rediline 0.0.1 → 0.0.2
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/.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"
|