rediline 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -1
- data/Gemfile +6 -2
- data/Gemfile.lock +2 -2
- data/README.md +24 -2
- data/Rakefile +6 -1
- data/VERSION +1 -1
- data/lib/rediline/entry.rb +14 -4
- data/lib/rediline/object.rb +2 -2
- data/lib/rediline/timeline/user.rb +19 -1
- data/lib/rediline/user.rb +5 -0
- data/rediline.gemspec +5 -5
- data/spec/entry_spec.rb +27 -0
- data/spec/support/timeline.rb +5 -0
- data/spec/support/user.rb +14 -0
- data/spec/timeline/user_spec.rb +48 -0
- metadata +7 -9
data/.gitignore
CHANGED
data/Gemfile
CHANGED
@@ -4,8 +4,12 @@ gem "redis", '2.0.7'
|
|
4
4
|
gem "redis-namespace", '0.10.0'
|
5
5
|
gem "json"
|
6
6
|
gem "i18n"
|
7
|
-
|
8
|
-
|
7
|
+
|
8
|
+
#
|
9
|
+
# About the version required there, please see the "compatibility" section in the README
|
10
|
+
#
|
11
|
+
gem "activesupport", ">= 2"
|
12
|
+
gem "activemodel", "~> 3.0"
|
9
13
|
|
10
14
|
group :development do
|
11
15
|
gem "jeweler"
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -3,6 +3,28 @@
|
|
3
3
|
|
4
4
|
Rediline is a ruby library which intends to allow you to create timelines for your users in ruby.
|
5
5
|
|
6
|
+
## Compatibility
|
7
|
+
|
8
|
+
Rediling has been built with the idea to make it compatible with any other ORM possible.
|
9
|
+
Whether your users and objects are in SQL, MongoDB, CouchDB or anything else, you should be able to use it.
|
10
|
+
|
11
|
+
There are several requirements though.
|
12
|
+
|
13
|
+
* The ORM should provide an ActiveModel::Calbacks similar API (most ORM depends of it anyway)
|
14
|
+
* The ORM should provide a #find method to query the objects (if it does not, you can use [complex queries](http://github.com/dmathieu/rediline/wiki/Complex-queries-to-get-an-object) though).
|
15
|
+
|
16
|
+
You should also be able to use Rediling in a non-rails application. Sinatra for example.
|
17
|
+
There are be dependencies to ActiveSupport and ActiveModel though.
|
18
|
+
|
19
|
+
### Rails 2 and Rails 3
|
20
|
+
|
21
|
+
As we're using ActiveSupport (mainly for #constantize), there were some problems with the version of the gem we're using.
|
22
|
+
|
23
|
+
Currently, ActiveSupport is required on a very permissive way (>= 2). That's intended to allow you to run rediline on a Rails2 application.
|
24
|
+
|
25
|
+
Moreover, we're using ActiveModel for the callbacks. And it requires ActiveSupport 3.0.
|
26
|
+
So for now, there's no dependency to ActiveModel. But you must know that you need your models to behave correctly with it in order to have rediline to work.
|
27
|
+
|
6
28
|
## Installation
|
7
29
|
|
8
30
|
Add the following to your Gemfile :
|
@@ -49,7 +71,7 @@ And a "public" one, which will contain all the actions made by this user's frien
|
|
49
71
|
|
50
72
|
You can retrieve a list's actions with the each method.
|
51
73
|
|
52
|
-
User.first.timeline.each(:egocentric) do |action|
|
74
|
+
User.first.timeline.limit(10).each(:egocentric) do |action|
|
53
75
|
p action.inspect
|
54
76
|
end
|
55
77
|
|
@@ -92,7 +114,7 @@ Rediline has a redis setter which can be given a string or a Redis object.
|
|
92
114
|
This means if you're already using Redis in your app, Rediline can re-use the existing connection.
|
93
115
|
|
94
116
|
String: `Rediline.redis = 'localhost:6379'`
|
95
|
-
Redis: `
|
117
|
+
Redis: `Rediline.redis = $redis`
|
96
118
|
|
97
119
|
In a rails app, I have an initializer in `config/initializers/rediline.rb` where I load `config/rediline.yml` and set the redis information appropriately.
|
98
120
|
|
data/Rakefile
CHANGED
@@ -27,7 +27,12 @@ begin
|
|
27
27
|
gemspec.add_dependency "redis-namespace", '0.10.0'
|
28
28
|
gemspec.add_dependency "json"
|
29
29
|
gemspec.add_dependency "i18n"
|
30
|
-
|
30
|
+
|
31
|
+
#
|
32
|
+
# About the version required there, please see the "compatibility" section in the README
|
33
|
+
#
|
34
|
+
gemspec.add_dependency "activesupport", ">= 2"
|
35
|
+
#gemspec.add_dependency "activemodel", "~> 3.0"
|
31
36
|
end
|
32
37
|
rescue LoadError
|
33
38
|
puts "Jeweler not available. Install it with: gem install jeweler"
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.2
|
data/lib/rediline/entry.rb
CHANGED
@@ -4,10 +4,10 @@ require 'active_support/core_ext'
|
|
4
4
|
module Rediline
|
5
5
|
|
6
6
|
class Entry
|
7
|
-
attr_reader :content
|
7
|
+
attr_reader :content, :queries
|
8
8
|
|
9
|
-
def initialize(content)
|
10
|
-
@content = parse(content)
|
9
|
+
def initialize(content, queries={})
|
10
|
+
@content, @queries = parse(content), queries
|
11
11
|
@objects = {}
|
12
12
|
end
|
13
13
|
|
@@ -18,7 +18,7 @@ module Rediline
|
|
18
18
|
def method_missing(name, *args)
|
19
19
|
return content[name] if content.include?(name)
|
20
20
|
if content.include?(:"#{name}_object") && content.include?(:"#{name}_object")
|
21
|
-
return @objects[name] ||=
|
21
|
+
return @objects[name] ||= find_query(name, content[:"#{name}_id"])
|
22
22
|
end
|
23
23
|
super
|
24
24
|
end
|
@@ -33,12 +33,14 @@ module Rediline
|
|
33
33
|
def parse(string)
|
34
34
|
if string.is_a?(String)
|
35
35
|
string = JSON.parse(string).symbolize_keys
|
36
|
+
string.delete :queries
|
36
37
|
|
37
38
|
[:user_id, :user_object, :object_id, :object_object, :verb].each do |f|
|
38
39
|
raise "invalid content : missing field #{f}" if string[f].nil?
|
39
40
|
end
|
40
41
|
else
|
41
42
|
string.symbolize_keys!
|
43
|
+
string.delete :queries
|
42
44
|
|
43
45
|
[:user, :object, :verb].each do |f|
|
44
46
|
raise "invalid content : missing field #{f}" if string[f].nil?
|
@@ -61,5 +63,13 @@ module Rediline
|
|
61
63
|
end
|
62
64
|
string
|
63
65
|
end
|
66
|
+
|
67
|
+
def find_query(name, id)
|
68
|
+
if queries.nil? or queries[name].nil?
|
69
|
+
return content[:"#{name}_object"].constantize.find(id)
|
70
|
+
else
|
71
|
+
return queries[name].call(self, id)
|
72
|
+
end
|
73
|
+
end
|
64
74
|
end
|
65
75
|
end
|
data/lib/rediline/object.rb
CHANGED
@@ -26,7 +26,7 @@ module Rediline
|
|
26
26
|
|
27
27
|
define_method "rediline_#{callback}" do
|
28
28
|
if attrs.frozen?
|
29
|
-
entry = Rediline::Entry.new(attrs.dup)
|
29
|
+
entry = Rediline::Entry.new(attrs.dup, attrs[:queries])
|
30
30
|
else
|
31
31
|
attrs[:object] = self
|
32
32
|
case attrs[:user]
|
@@ -38,7 +38,7 @@ module Rediline
|
|
38
38
|
attrs[:user] = send(:user)
|
39
39
|
end
|
40
40
|
attrs.freeze
|
41
|
-
entry = Rediline::Entry.new(attrs.dup)
|
41
|
+
entry = Rediline::Entry.new(attrs.dup, attrs[:queries])
|
42
42
|
end
|
43
43
|
|
44
44
|
entry.user.send(field_name).lists.each_pair do |k, v|
|
@@ -6,16 +6,24 @@ module Rediline
|
|
6
6
|
def initialize(field_name, user, block)
|
7
7
|
@field_name, @user, @block = field_name, user
|
8
8
|
@lists = {}
|
9
|
+
@limit, @start_at = 10, 0
|
9
10
|
instance_eval(&block)
|
10
11
|
end
|
11
12
|
|
12
13
|
def each(type)
|
13
14
|
raise "you must provide a block" unless block_given?
|
14
|
-
(
|
15
|
+
(@start_at..@limit).each do |i|
|
15
16
|
data = Rediline.redis.lindex(key(type), i)
|
17
|
+
next if data.nil?
|
16
18
|
yield Rediline::Entry.new(data)
|
17
19
|
end
|
18
20
|
end
|
21
|
+
|
22
|
+
def destroy
|
23
|
+
lists.each do |l|
|
24
|
+
Rediline.redis.del key(l)
|
25
|
+
end
|
26
|
+
end
|
19
27
|
|
20
28
|
def to_a(type)
|
21
29
|
result = Array.new
|
@@ -33,6 +41,16 @@ module Rediline
|
|
33
41
|
@lists[name] = instance_eval(&block)
|
34
42
|
end
|
35
43
|
|
44
|
+
def limit(count)
|
45
|
+
@limit = count
|
46
|
+
self
|
47
|
+
end
|
48
|
+
|
49
|
+
def start_at(count)
|
50
|
+
@start_at = count
|
51
|
+
self
|
52
|
+
end
|
53
|
+
|
36
54
|
private
|
37
55
|
def key(type)
|
38
56
|
"#{field_name.to_s}:#{@user.class.to_s}.#{@user.id.to_s}:#{type}"
|
data/lib/rediline/user.rb
CHANGED
data/rediline.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{rediline}
|
8
|
-
s.version = "0.0.
|
8
|
+
s.version = "0.0.2"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Damien MATHIEU"]
|
12
|
-
s.date = %q{2010-09-
|
12
|
+
s.date = %q{2010-09-29}
|
13
13
|
s.description = %q{Timeline library}
|
14
14
|
s.email = %q{42@dmathieu.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -70,20 +70,20 @@ Gem::Specification.new do |s|
|
|
70
70
|
s.add_runtime_dependency(%q<redis-namespace>, ["= 0.10.0"])
|
71
71
|
s.add_runtime_dependency(%q<json>, [">= 0"])
|
72
72
|
s.add_runtime_dependency(%q<i18n>, [">= 0"])
|
73
|
-
s.add_runtime_dependency(%q<activesupport>, ["
|
73
|
+
s.add_runtime_dependency(%q<activesupport>, [">= 2"])
|
74
74
|
else
|
75
75
|
s.add_dependency(%q<redis>, ["= 2.0.7"])
|
76
76
|
s.add_dependency(%q<redis-namespace>, ["= 0.10.0"])
|
77
77
|
s.add_dependency(%q<json>, [">= 0"])
|
78
78
|
s.add_dependency(%q<i18n>, [">= 0"])
|
79
|
-
s.add_dependency(%q<activesupport>, ["
|
79
|
+
s.add_dependency(%q<activesupport>, [">= 2"])
|
80
80
|
end
|
81
81
|
else
|
82
82
|
s.add_dependency(%q<redis>, ["= 2.0.7"])
|
83
83
|
s.add_dependency(%q<redis-namespace>, ["= 0.10.0"])
|
84
84
|
s.add_dependency(%q<json>, [">= 0"])
|
85
85
|
s.add_dependency(%q<i18n>, [">= 0"])
|
86
|
-
s.add_dependency(%q<activesupport>, ["
|
86
|
+
s.add_dependency(%q<activesupport>, [">= 2"])
|
87
87
|
end
|
88
88
|
end
|
89
89
|
|
data/spec/entry_spec.rb
CHANGED
@@ -37,6 +37,13 @@ describe Rediline::Entry do
|
|
37
37
|
entry.content[o].should be_nil
|
38
38
|
end
|
39
39
|
end
|
40
|
+
|
41
|
+
it 'should not store the queries parameter' do
|
42
|
+
c = valid_json
|
43
|
+
c[:queries] = {}
|
44
|
+
entry = Rediline::Entry.new c.to_json
|
45
|
+
entry.content[:queries].should be_nil
|
46
|
+
end
|
40
47
|
end
|
41
48
|
|
42
49
|
describe 'when initializing with a hash' do
|
@@ -76,6 +83,13 @@ describe Rediline::Entry do
|
|
76
83
|
entry = Rediline::Entry.new c
|
77
84
|
entry.second_object.should eql(42)
|
78
85
|
end
|
86
|
+
|
87
|
+
it 'should not store the queries parameter' do
|
88
|
+
c = valid_hash
|
89
|
+
c[:queries] = {}
|
90
|
+
entry = Rediline::Entry.new c
|
91
|
+
entry.content[:queries].should be_nil
|
92
|
+
end
|
79
93
|
end
|
80
94
|
|
81
95
|
describe 'creation date' do
|
@@ -107,6 +121,19 @@ describe Rediline::Entry do
|
|
107
121
|
end
|
108
122
|
end
|
109
123
|
|
124
|
+
describe 'queries' do
|
125
|
+
it 'should allow us to instantiate with a queries object' do
|
126
|
+
lambda do
|
127
|
+
Rediline::Entry.new valid_hash, { :object => lambda {|o, id| o.object.find(id) }}
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
it 'should execute the specified query' do
|
132
|
+
entry = Rediline::Entry.new valid_hash, { :object => lambda {|o, id| TestingTimelineObject.new(7) }}
|
133
|
+
entry.object.id.should eql(7)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
110
137
|
def valid_hash
|
111
138
|
{
|
112
139
|
:object => TestingTimelineObject.new(42),
|
data/spec/support/timeline.rb
CHANGED
@@ -10,6 +10,11 @@ class TestingTimelineObject
|
|
10
10
|
rediline :timeline,
|
11
11
|
:user => lambda {|o| o.user },
|
12
12
|
:verb => :destroyed,
|
13
|
+
:queries => {
|
14
|
+
:object => lambda {|o, id|
|
15
|
+
TestingTimelineObject.new(id+1)
|
16
|
+
}
|
17
|
+
},
|
13
18
|
:when => :before_destroy
|
14
19
|
|
15
20
|
attr_reader :id, :user
|
data/spec/support/user.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
class User
|
2
|
+
extend ActiveModel::Callbacks
|
3
|
+
define_model_callbacks :create, :destroy
|
2
4
|
include Rediline::User
|
5
|
+
|
3
6
|
rediline :timeline do
|
4
7
|
list :egocentric do
|
5
8
|
[user]
|
@@ -17,4 +20,15 @@ class User
|
|
17
20
|
def self.find(id)
|
18
21
|
self.new(id)
|
19
22
|
end
|
23
|
+
|
24
|
+
def create
|
25
|
+
_run_create_callbacks do
|
26
|
+
# Your create action methods here
|
27
|
+
end
|
28
|
+
end
|
29
|
+
def destroy
|
30
|
+
_run_destroy_callbacks do
|
31
|
+
# Your destroy action methods here
|
32
|
+
end
|
33
|
+
end
|
20
34
|
end
|
data/spec/timeline/user_spec.rb
CHANGED
@@ -37,6 +37,12 @@ describe Rediline::Timeline::User do
|
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
40
|
+
it 'should not fail if there are not enough entries' do
|
41
|
+
@timeline.limit(@timeline.count(:egocentric) + 1).each(:egocentric) do |entry|
|
42
|
+
entry.should be_kind_of(Rediline::Entry)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
40
46
|
[:object, :user].each do |o|
|
41
47
|
it "should not have any #{o} in it\'s values" do
|
42
48
|
@timeline.each(:egocentric) do |entry|
|
@@ -46,6 +52,18 @@ describe Rediline::Timeline::User do
|
|
46
52
|
end
|
47
53
|
end
|
48
54
|
|
55
|
+
describe 'destroy' do
|
56
|
+
it 'should destroy all the user\'s lists keys' do
|
57
|
+
Rediline.redis.expects(:del).twice
|
58
|
+
@timeline.destroy
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'should destroy the timelines when destroying the user' do
|
62
|
+
Rediline.redis.expects(:del).twice
|
63
|
+
User.new(1).destroy
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
49
67
|
describe 'to_a' do
|
50
68
|
it 'should return an array' do
|
51
69
|
@timeline.to_a(:egocentric).should be_kind_of(Array)
|
@@ -68,4 +86,34 @@ describe Rediline::Timeline::User do
|
|
68
86
|
@timeline.send(:key, :egocentric).should eql('timeline:User.1:egocentric')
|
69
87
|
end
|
70
88
|
end
|
89
|
+
|
90
|
+
describe 'limit' do
|
91
|
+
it 'should default the limit to 10' do
|
92
|
+
@timeline.instance_eval('@limit').should eql(10)
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'should redefine the limit' do
|
96
|
+
@timeline.limit(20)
|
97
|
+
@timeline.instance_eval('@limit').should eql(20)
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'should return self' do
|
101
|
+
@timeline.limit(30).should eql(@timeline)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
describe 'start_at' do
|
106
|
+
it 'should default the start_at to 0' do
|
107
|
+
@timeline.instance_eval('@start_at').should eql(0)
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'should redefine the start_at' do
|
111
|
+
@timeline.start_at(20)
|
112
|
+
@timeline.instance_eval('@start_at').should eql(20)
|
113
|
+
end
|
114
|
+
|
115
|
+
it 'should return self' do
|
116
|
+
@timeline.start_at(30).should eql(@timeline)
|
117
|
+
end
|
118
|
+
end
|
71
119
|
end
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: 0.0.
|
8
|
+
- 2
|
9
|
+
version: 0.0.2
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Damien MATHIEU
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-09-
|
17
|
+
date: 2010-09-29 00:00:00 +02:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -78,13 +78,11 @@ dependencies:
|
|
78
78
|
requirement: &id005 !ruby/object:Gem::Requirement
|
79
79
|
none: false
|
80
80
|
requirements:
|
81
|
-
- - "
|
81
|
+
- - ">="
|
82
82
|
- !ruby/object:Gem::Version
|
83
83
|
segments:
|
84
|
-
-
|
85
|
-
|
86
|
-
- 0
|
87
|
-
version: 3.0.0
|
84
|
+
- 2
|
85
|
+
version: "2"
|
88
86
|
type: :runtime
|
89
87
|
prerelease: false
|
90
88
|
version_requirements: *id005
|
@@ -137,7 +135,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
137
135
|
requirements:
|
138
136
|
- - ">="
|
139
137
|
- !ruby/object:Gem::Version
|
140
|
-
hash:
|
138
|
+
hash: 355954079675066628
|
141
139
|
segments:
|
142
140
|
- 0
|
143
141
|
version: "0"
|