redismapper 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Manifest +8 -0
- data/README.rdoc +0 -0
- data/Rakefile +14 -0
- data/examples/basic.rb +7 -0
- data/init.rb +1 -0
- data/lib/redismapper.rb +143 -0
- data/redismapper.gemspec +33 -0
- data/spec/redismapper_spec.rb +99 -0
- data/spec/spec_helper.rb +1 -0
- metadata +78 -0
data/Manifest
ADDED
data/README.rdoc
ADDED
File without changes
|
data/Rakefile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'echoe'
|
4
|
+
|
5
|
+
Echoe.new('redismapper', '0.0.1') do |p|
|
6
|
+
p.description = "Basic ORM for Redis key/value store"
|
7
|
+
p.url = "http://github.com/makevoid/redismapper"
|
8
|
+
p.author = "Francesco Canessa"
|
9
|
+
p.email = "makevoid@gmail.com"
|
10
|
+
p.ignore_pattern = ["tmp/*", "dump.rdb"]
|
11
|
+
p.development_dependencies = ["rspec"]
|
12
|
+
end
|
13
|
+
|
14
|
+
Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each { |ext| load ext }
|
data/examples/basic.rb
ADDED
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'redismapper'
|
data/lib/redismapper.rb
ADDED
@@ -0,0 +1,143 @@
|
|
1
|
+
class RedisMapper
|
2
|
+
require 'rubygems'
|
3
|
+
require 'redis'
|
4
|
+
|
5
|
+
WARNINGS = true # set false to speed up
|
6
|
+
|
7
|
+
def self.setup(db)
|
8
|
+
@@r = db
|
9
|
+
end
|
10
|
+
|
11
|
+
|
12
|
+
|
13
|
+
def initialize(hash)
|
14
|
+
hash.map do |key, value|
|
15
|
+
instance_variable_set("@#{key}", value)
|
16
|
+
self.class.send(:define_method, key){ instance_variable_get("@#{key}") }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.inherited(sub)
|
21
|
+
sub.instance_variable_set("@model", sub.name.downcase)
|
22
|
+
end
|
23
|
+
|
24
|
+
def id
|
25
|
+
@id
|
26
|
+
end
|
27
|
+
|
28
|
+
# internals
|
29
|
+
|
30
|
+
def self.property(name, options={})
|
31
|
+
@properties = [] if @properties.nil?
|
32
|
+
@properties << [name, options]
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.properties
|
36
|
+
@properties
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.db
|
40
|
+
@@r
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.count
|
44
|
+
@@r["globals:next_#{@model}_id"].to_i
|
45
|
+
end
|
46
|
+
|
47
|
+
# actions
|
48
|
+
|
49
|
+
# GET /resources
|
50
|
+
def self.all(props={})
|
51
|
+
resources = []
|
52
|
+
max = set_all_max(props)
|
53
|
+
(1..max).map do |obj_id|
|
54
|
+
resources << get_resource(obj_id, props[:select])
|
55
|
+
end
|
56
|
+
resources
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.set_all_max(props)
|
60
|
+
if props.keys.include?(:limit)
|
61
|
+
props[:limit]
|
62
|
+
else
|
63
|
+
@@r["globals:next_#{@model}_id"].to_i
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
def self.get_resource(obj_id, select=nil)
|
69
|
+
hash = {}
|
70
|
+
@properties.map do |prop, opts|
|
71
|
+
sel = select.nil? ? true : [select].flatten.include?(prop.to_sym)
|
72
|
+
hash[prop] = @@r["#{@model}_id:#{obj_id}:#{prop}"] if sel
|
73
|
+
end
|
74
|
+
new(hash.merge(:id => obj_id.to_i))
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
def self.find(obj_id)
|
79
|
+
get_resource obj_id
|
80
|
+
end
|
81
|
+
|
82
|
+
def self.first(hash={})
|
83
|
+
# first_warning(hash) if WARNINGS
|
84
|
+
obj_id = get_id(hash)
|
85
|
+
get_resource obj_id
|
86
|
+
end
|
87
|
+
|
88
|
+
def self.first_warning(hash)
|
89
|
+
raise "no index property '#{hash.keys.first}' for model '#{@model}'" unless @properties.flatten.include? hash.keys.first
|
90
|
+
end
|
91
|
+
|
92
|
+
def self.get_id(hash)
|
93
|
+
hash.map do |key, value|
|
94
|
+
@@r["#{@model}_#{key}:#{value}:id"]
|
95
|
+
end.uniq.first
|
96
|
+
end
|
97
|
+
|
98
|
+
# no sort
|
99
|
+
def self.sort()
|
100
|
+
gets = []
|
101
|
+
@properties.map do |prop|
|
102
|
+
gets << "#{@model}_id:*:#{prop}"
|
103
|
+
end
|
104
|
+
@@r.sort("globals:next_#{@model}_id", :get => gets,
|
105
|
+
:limit => [0, 100],
|
106
|
+
:order => 'asc')
|
107
|
+
end
|
108
|
+
|
109
|
+
# POST /resources
|
110
|
+
def self.create(hash)
|
111
|
+
obj_id = @@r.incr "globals:next_#{@model}_id"
|
112
|
+
@@r["#{@model}_id:#{obj_id}:id"] = obj_id
|
113
|
+
@properties.map do |prop, opts|
|
114
|
+
value = hash[prop]
|
115
|
+
# puts "[#{@model}_id:#{obj_id}:#{prop}] = #{hash[prop]}"
|
116
|
+
@@r["#{@model}_id:#{obj_id}:#{prop}"] = value unless value.nil?
|
117
|
+
@@r["#{@model}_#{prop}:#{value}:id"] = obj_id if opts[:index] # CHANGES: sanitize on hash[prop]
|
118
|
+
end
|
119
|
+
new(hash.merge(:id => obj_id))
|
120
|
+
end
|
121
|
+
|
122
|
+
# classes
|
123
|
+
class Resource
|
124
|
+
# what about moving resource inside is class and make it a loadable module?? (yea like DM's)
|
125
|
+
end
|
126
|
+
|
127
|
+
def to_hash
|
128
|
+
h = {}
|
129
|
+
eval(self.class.name).properties.map do |prop, opts|
|
130
|
+
h[prop] = instance_variable_get("@#{prop}")
|
131
|
+
end
|
132
|
+
h
|
133
|
+
end
|
134
|
+
|
135
|
+
|
136
|
+
# UTILS
|
137
|
+
protected
|
138
|
+
def self.delete_db
|
139
|
+
@@r.keys('*').map{ |k| @@r.del k }
|
140
|
+
end
|
141
|
+
|
142
|
+
|
143
|
+
end
|
data/redismapper.gemspec
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{redismapper}
|
5
|
+
s.version = "0.0.1"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Francesco Canessa"]
|
9
|
+
s.date = %q{2009-11-06}
|
10
|
+
s.description = %q{Basic ORM for Redis key/value store}
|
11
|
+
s.email = %q{makevoid@gmail.com}
|
12
|
+
s.extra_rdoc_files = ["README.rdoc", "lib/redismapper.rb"]
|
13
|
+
s.files = ["Manifest", "README.rdoc", "Rakefile", "examples/basic.rb", "init.rb", "lib/redismapper.rb", "spec/redismapper_spec.rb", "spec/spec_helper.rb", "redismapper.gemspec"]
|
14
|
+
s.homepage = %q{http://github.com/makevoid/redismapper}
|
15
|
+
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Redismapper", "--main", "README.rdoc"]
|
16
|
+
s.require_paths = ["lib"]
|
17
|
+
s.rubyforge_project = %q{redismapper}
|
18
|
+
s.rubygems_version = %q{1.3.5}
|
19
|
+
s.summary = %q{Basic ORM for Redis key/value store}
|
20
|
+
|
21
|
+
if s.respond_to? :specification_version then
|
22
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
23
|
+
s.specification_version = 3
|
24
|
+
|
25
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
26
|
+
s.add_development_dependency(%q<rspec>, [">= 0"])
|
27
|
+
else
|
28
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
29
|
+
end
|
30
|
+
else
|
31
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe RedisMapper do
|
4
|
+
|
5
|
+
it "should setup db connection" do
|
6
|
+
RedisMapper.setup(Redis.new :db => 4).should be_a(Redis)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should delete all keys" do
|
10
|
+
RedisMapper.delete_db
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should create a resource" do
|
14
|
+
class Resource < RedisMapper
|
15
|
+
property :name
|
16
|
+
end
|
17
|
+
|
18
|
+
r = Resource.create(:name => "hola")
|
19
|
+
r.should be_a(Resource)
|
20
|
+
r.name.should == "hola"
|
21
|
+
end
|
22
|
+
|
23
|
+
# it "should make a sort" do
|
24
|
+
# class Resource < RedisMapper
|
25
|
+
# property :name
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# Resource.create(:name => "yo")
|
29
|
+
# Resource.create(:name => "uhm")
|
30
|
+
# Resource.create(:name => "argh")
|
31
|
+
# Resource.create(:name => "yaaa")
|
32
|
+
# Resource.sort
|
33
|
+
# end
|
34
|
+
|
35
|
+
it "should find by property" do
|
36
|
+
class Resource < RedisMapper
|
37
|
+
property :name, :index => true
|
38
|
+
end
|
39
|
+
|
40
|
+
r = Resource.create(:name => "abdullah")
|
41
|
+
Resource.first(:name => "abdullah").id.should == r.id
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should find by relation" do
|
45
|
+
class Father < RedisMapper
|
46
|
+
property :name
|
47
|
+
end
|
48
|
+
|
49
|
+
class Child < RedisMapper
|
50
|
+
property :name
|
51
|
+
property :father_id
|
52
|
+
end
|
53
|
+
|
54
|
+
f = Father.create(:name => "foo")
|
55
|
+
c = Child.create(:name => "bar", :father_id => f.id)
|
56
|
+
puts "TODO: relation!!"
|
57
|
+
end
|
58
|
+
|
59
|
+
# GET all
|
60
|
+
it "should get all resources selecting by an attribute" do
|
61
|
+
class Resource < RedisMapper
|
62
|
+
property :name
|
63
|
+
property :description
|
64
|
+
end
|
65
|
+
|
66
|
+
RedisMapper.delete_db
|
67
|
+
r = Resource.create(:name => "ahmed", :description => "test")
|
68
|
+
r = Resource.create(:name => "the_terrorist", :description => "test")
|
69
|
+
r = Resource.create(:name => "abdul", :description => "test")
|
70
|
+
|
71
|
+
Resource.count.should == 3
|
72
|
+
Resource.all(:select => :name).map{ |r| r.name }.compact.size.should == 3
|
73
|
+
Resource.all(:select => :name).map{ |r| r.description }.compact.should == []
|
74
|
+
end
|
75
|
+
|
76
|
+
# GET one
|
77
|
+
it "should list all attributes and values of a resource in a hash" do
|
78
|
+
class Arab < RedisMapper
|
79
|
+
property :name
|
80
|
+
property :description
|
81
|
+
end
|
82
|
+
|
83
|
+
RedisMapper.delete_db
|
84
|
+
attrs = {:name => "ahmed", :description => "test"}
|
85
|
+
r = Arab.create(attrs)
|
86
|
+
r.to_hash.should == attrs
|
87
|
+
end
|
88
|
+
|
89
|
+
# GET one [exception]
|
90
|
+
it "should return nil if a record is not found" do
|
91
|
+
class Tao < RedisMapper
|
92
|
+
property :balance
|
93
|
+
end
|
94
|
+
|
95
|
+
Tao.find(1).should be_nil
|
96
|
+
end
|
97
|
+
|
98
|
+
|
99
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../lib/redismapper')
|
metadata
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: redismapper
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Francesco Canessa
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-11-06 00:00:00 +01:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rspec
|
17
|
+
type: :development
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
25
|
+
description: Basic ORM for Redis key/value store
|
26
|
+
email: makevoid@gmail.com
|
27
|
+
executables: []
|
28
|
+
|
29
|
+
extensions: []
|
30
|
+
|
31
|
+
extra_rdoc_files:
|
32
|
+
- README.rdoc
|
33
|
+
- lib/redismapper.rb
|
34
|
+
files:
|
35
|
+
- Manifest
|
36
|
+
- README.rdoc
|
37
|
+
- Rakefile
|
38
|
+
- examples/basic.rb
|
39
|
+
- init.rb
|
40
|
+
- lib/redismapper.rb
|
41
|
+
- spec/redismapper_spec.rb
|
42
|
+
- spec/spec_helper.rb
|
43
|
+
- redismapper.gemspec
|
44
|
+
has_rdoc: true
|
45
|
+
homepage: http://github.com/makevoid/redismapper
|
46
|
+
licenses: []
|
47
|
+
|
48
|
+
post_install_message:
|
49
|
+
rdoc_options:
|
50
|
+
- --line-numbers
|
51
|
+
- --inline-source
|
52
|
+
- --title
|
53
|
+
- Redismapper
|
54
|
+
- --main
|
55
|
+
- README.rdoc
|
56
|
+
require_paths:
|
57
|
+
- lib
|
58
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: "0"
|
63
|
+
version:
|
64
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: "1.2"
|
69
|
+
version:
|
70
|
+
requirements: []
|
71
|
+
|
72
|
+
rubyforge_project: redismapper
|
73
|
+
rubygems_version: 1.3.5
|
74
|
+
signing_key:
|
75
|
+
specification_version: 3
|
76
|
+
summary: Basic ORM for Redis key/value store
|
77
|
+
test_files: []
|
78
|
+
|