blendris 0.0.4 → 0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +55 -24
- data/Rakefile +1 -1
- data/blendris.gemspec +2 -2
- data/lib/blendris/accessor.rb +13 -0
- data/lib/blendris/integer.rb +8 -0
- data/lib/blendris/model.rb +1 -0
- data/lib/blendris/node.rb +6 -0
- data/lib/blendris/reference_set.rb +10 -3
- data/lib/blendris/set.rb +26 -0
- data/lib/blendris/utils.rb +2 -0
- data/spec/model_spec.rb +5 -0
- data/spec/redis-tools_spec.rb +12 -0
- data/spec/set_spec.rb +46 -0
- metadata +2 -2
data/README.markdown
CHANGED
@@ -16,11 +16,16 @@ BLENDRIS IS IN VERY EARLY ALPHA!!!
|
|
16
16
|
|
17
17
|
PLEASE DON'T USE IT FOR ANYTHING IMPORTANT YET!!!
|
18
18
|
|
19
|
+
Blendris provides a way to create an object hierarchy within Redis,
|
20
|
+
a key-value database. It provides very little in the way of indexing
|
21
|
+
or querying that data. It is up to the user to maintain objects
|
22
|
+
representing the query in which they are interested.
|
23
|
+
|
19
24
|
|
20
25
|
|
21
26
|
# REQUIREMENTS #
|
22
27
|
|
23
|
-
Blendris uses the redis
|
28
|
+
Blendris uses the [redis](http://gemcutter.org/gems/redis) gem.
|
24
29
|
|
25
30
|
|
26
31
|
|
@@ -32,38 +37,64 @@ gem install blendris
|
|
32
37
|
|
33
38
|
# EXAMPLES #
|
34
39
|
|
35
|
-
|
36
|
-
|
40
|
+
Let's say we want to maintain a list of employers and employees.
|
41
|
+
|
42
|
+
class Employer < Blendris::Model
|
43
|
+
key "employer", :name
|
37
44
|
|
38
|
-
|
39
|
-
|
45
|
+
string :name
|
46
|
+
string :address
|
40
47
|
|
41
|
-
|
42
|
-
string :url
|
43
|
-
set :paths
|
48
|
+
refs :employees, :class => "Employee", :reverse => :employer
|
44
49
|
end
|
45
50
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
51
|
+
class Employee < Blendris::Model
|
52
|
+
key "employee", :name
|
53
|
+
|
54
|
+
string :name
|
55
|
+
string :address
|
56
|
+
set :family_members
|
50
57
|
|
51
|
-
|
58
|
+
ref :employer, :class => "Employer", :reverse => :employees
|
59
|
+
end
|
52
60
|
|
53
|
-
|
54
|
-
website:One_Fake_Website:name => "One Fake Website"
|
55
|
-
website:One_Fake_Website:url => "http://fakewebsite.com"
|
56
|
-
website:One_Fake_Website:paths => [ "/blog/index", "/admin/index" ]
|
61
|
+
### key ###
|
57
62
|
|
58
|
-
|
63
|
+
Key sets the base key for this object. In the case of the employer
|
64
|
+
"37 Signals" it would create a key "employer:37_Signals" and set its value
|
65
|
+
to "Employer". In the key, strings are interpreted as literals and
|
66
|
+
symbols are interpreted as pointers to that data field.
|
59
67
|
|
60
|
-
|
61
|
-
|
62
|
-
|
68
|
+
* Note that spaces are converted to underscores, as spaces are not
|
69
|
+
allowed in Redis keys. This could cause problems in some data sets.
|
70
|
+
* Also note that the value assigned to the base key is the class name of
|
71
|
+
the model being used.
|
72
|
+
* Only strings and integers should be used as key values.
|
73
|
+
|
74
|
+
### string ###
|
75
|
+
|
76
|
+
String creates a string key named for the first parameter given to it.
|
77
|
+
This means that it would generate a key "employer:37_Signals:name" with
|
78
|
+
a value of "37 Signals".
|
79
|
+
|
80
|
+
### refs ###
|
81
|
+
|
82
|
+
Refs maintains a set of references to other objects.
|
83
|
+
|
84
|
+
* *:class* will limit objects in this reference set to the given class.
|
85
|
+
If a string is specified as a class, it will be constantized before
|
86
|
+
comparing.
|
87
|
+
* *reverse* will cause the given field to be updated on the object when
|
88
|
+
it is added to or removed from this set.
|
89
|
+
|
90
|
+
### new vs create ###
|
91
|
+
|
92
|
+
Calling the *create* method will build a new object, generating a new base
|
93
|
+
key based upon the parameters. The parameter list should be the same as
|
94
|
+
the list of symbols in your *key* field.
|
63
95
|
|
64
|
-
|
65
|
-
|
66
|
-
from this site's list.
|
96
|
+
Calling the *new* method will instantiate an existing object using the
|
97
|
+
given *key* as the base key.
|
67
98
|
|
68
99
|
|
69
100
|
|
data/Rakefile
CHANGED
data/blendris.gemspec
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{blendris}
|
5
|
-
s.version = "0.
|
5
|
+
s.version = "0.5"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Alex McHale"]
|
9
|
-
s.date = %q{2010-02-
|
9
|
+
s.date = %q{2010-02-21}
|
10
10
|
s.description = %q{A redis library for Ruby}
|
11
11
|
s.email = %q{alexmchale@gmail.com}
|
12
12
|
s.extra_rdoc_files = ["README.markdown", "lib/blendris.rb", "lib/blendris/accessor.rb", "lib/blendris/errors.rb", "lib/blendris/integer.rb", "lib/blendris/list.rb", "lib/blendris/model.rb", "lib/blendris/node.rb", "lib/blendris/reference.rb", "lib/blendris/reference_base.rb", "lib/blendris/reference_set.rb", "lib/blendris/set.rb", "lib/blendris/string.rb", "lib/blendris/types.rb", "lib/blendris/utils.rb", "tasks/rspec.rake"]
|
data/lib/blendris/accessor.rb
CHANGED
@@ -52,6 +52,19 @@ module Blendris
|
|
52
52
|
redis.flushdb
|
53
53
|
end
|
54
54
|
|
55
|
+
# Build a new temporary set with the given contents, yielding it to
|
56
|
+
# the passed block. After the block exits, destroy the temporary set.
|
57
|
+
def in_temporary_set(*contents)
|
58
|
+
index = RedisInteger.new("blendris:temporary:index").increment
|
59
|
+
|
60
|
+
temporary_set = RedisSet.new("blendris:temporary:set:#{index}")
|
61
|
+
temporary_set << contents
|
62
|
+
yield temporary_set
|
63
|
+
temporary_set.clear
|
64
|
+
|
65
|
+
self
|
66
|
+
end
|
67
|
+
|
55
68
|
end
|
56
69
|
|
57
70
|
end
|
data/lib/blendris/integer.rb
CHANGED
data/lib/blendris/model.rb
CHANGED
data/lib/blendris/node.rb
CHANGED
@@ -12,8 +12,16 @@ module Blendris
|
|
12
12
|
@refs ||= RedisSet.new(@key)
|
13
13
|
end
|
14
14
|
|
15
|
-
# TODO set should be a real set, while << appends
|
16
15
|
def set(*objs)
|
16
|
+
refkeys = objs.flatten.compact.map {|o| o.key}
|
17
|
+
self.refs.set refkeys
|
18
|
+
|
19
|
+
self
|
20
|
+
ensure
|
21
|
+
notify_changed
|
22
|
+
end
|
23
|
+
|
24
|
+
def <<(*objs)
|
17
25
|
objs.flatten!
|
18
26
|
objs.compact!
|
19
27
|
|
@@ -28,7 +36,6 @@ module Blendris
|
|
28
36
|
|
29
37
|
self
|
30
38
|
end
|
31
|
-
alias :<< :set
|
32
39
|
|
33
40
|
def delete(obj)
|
34
41
|
if refkey = self.class.cast_to_redis(obj, @options)
|
@@ -56,7 +63,7 @@ module Blendris
|
|
56
63
|
end
|
57
64
|
|
58
65
|
def assign_ref(*values)
|
59
|
-
self
|
66
|
+
self << values
|
60
67
|
end
|
61
68
|
|
62
69
|
def remove_ref(value)
|
data/lib/blendris/set.rb
CHANGED
@@ -21,6 +21,18 @@ module Blendris
|
|
21
21
|
self
|
22
22
|
end
|
23
23
|
|
24
|
+
def set(*values)
|
25
|
+
self.clear
|
26
|
+
|
27
|
+
values.flatten.compact.each do |v|
|
28
|
+
redis.sadd key, v
|
29
|
+
end
|
30
|
+
|
31
|
+
self
|
32
|
+
ensure
|
33
|
+
notify_changed
|
34
|
+
end
|
35
|
+
|
24
36
|
def <<(value)
|
25
37
|
[ value ].flatten.compact.each do |v|
|
26
38
|
redis.sadd key, v
|
@@ -41,6 +53,20 @@ module Blendris
|
|
41
53
|
notify_changed
|
42
54
|
end
|
43
55
|
|
56
|
+
# Set this set's members to the intersection of this set and the given set.
|
57
|
+
def intersect!(other)
|
58
|
+
redis.sinterstore key, key, other.key
|
59
|
+
ensure
|
60
|
+
notify_changed
|
61
|
+
end
|
62
|
+
|
63
|
+
# Set this set's members to the union of this set and the given set.
|
64
|
+
def union!(other)
|
65
|
+
redis.sunionstore key, key, other.key
|
66
|
+
ensure
|
67
|
+
notify_changed
|
68
|
+
end
|
69
|
+
|
44
70
|
end
|
45
71
|
|
46
72
|
end
|
data/lib/blendris/utils.rb
CHANGED
data/spec/model_spec.rb
CHANGED
@@ -35,6 +35,11 @@ describe Model do
|
|
35
35
|
@fruit.foods.should be_include(@lemon)
|
36
36
|
@fruit.foods.should be_include(Food.new("food:lemon"))
|
37
37
|
@fruit.foods.should_not be_include(@steak)
|
38
|
+
|
39
|
+
@fruit.foods = @onion
|
40
|
+
|
41
|
+
@fruit.foods.count.should == 1
|
42
|
+
@fruit.foods.first.should == @onion
|
38
43
|
end
|
39
44
|
|
40
45
|
it "should not allow you to instantiate with a key that doesnt match its class" do
|
data/spec/redis-tools_spec.rb
CHANGED
@@ -14,4 +14,16 @@ describe "redis connection accessor" do
|
|
14
14
|
redis.del(testkey).should == false
|
15
15
|
end
|
16
16
|
|
17
|
+
it "should allow for keys to be renamed" do
|
18
|
+
s = RedisString.new("string1")
|
19
|
+
s.set "hobo"
|
20
|
+
|
21
|
+
s.rename "string2"
|
22
|
+
s.key.should == "string2"
|
23
|
+
s.get.should == "hobo"
|
24
|
+
|
25
|
+
RedisString.new("string1").get.should be_nil
|
26
|
+
RedisString.new("string2").get.should == "hobo"
|
27
|
+
end
|
28
|
+
|
17
29
|
end
|
data/spec/set_spec.rb
CHANGED
@@ -17,4 +17,50 @@ describe "redis sets" do
|
|
17
17
|
@onion.qualities.to_a.sort.should == %w( delicious white )
|
18
18
|
end
|
19
19
|
|
20
|
+
it "should allow for temporary sets" do
|
21
|
+
extend RedisAccessor
|
22
|
+
|
23
|
+
redis.keys("blendris:temporary:set:*").count.should == 0
|
24
|
+
|
25
|
+
in_temporary_set do |set|
|
26
|
+
redis.keys("blendris:temporary:set:*").count.should == 0
|
27
|
+
set.count.should == 0
|
28
|
+
end
|
29
|
+
|
30
|
+
redis.keys("blendris:temporary:set:*").count.should == 0
|
31
|
+
|
32
|
+
in_temporary_set(1, 2, 3) do |set|
|
33
|
+
redis.keys("blendris:temporary:set:*").count.should == 1
|
34
|
+
set.count.should == 3
|
35
|
+
end
|
36
|
+
|
37
|
+
redis.keys("blendris:temporary:set:*").count.should == 0
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should do intersections properly" do
|
41
|
+
s1 = RedisSet.new("set1")
|
42
|
+
s2 = RedisSet.new("set2")
|
43
|
+
|
44
|
+
s1 << [ 1, 2, 3 ]
|
45
|
+
s2 << [ 1, 4, 5 ]
|
46
|
+
|
47
|
+
s1.intersect!(s2).should == 1
|
48
|
+
|
49
|
+
s1.sort.should == %w( 1 )
|
50
|
+
s2.sort.should == %w( 1 4 5 )
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should be able to union two sets" do
|
54
|
+
s1 = RedisSet.new("set1")
|
55
|
+
s2 = RedisSet.new("set2")
|
56
|
+
|
57
|
+
s1 << %w( 1 4 5 )
|
58
|
+
s2 << %w( 1 2 3 )
|
59
|
+
|
60
|
+
s1.union!(s2).should == 5
|
61
|
+
|
62
|
+
s1.sort.should == %w( 1 2 3 4 5 )
|
63
|
+
s2.sort.should == %w( 1 2 3 )
|
64
|
+
end
|
65
|
+
|
20
66
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: blendris
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: "0.5"
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alex McHale
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-02-
|
12
|
+
date: 2010-02-21 00:00:00 -06:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|