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 CHANGED
@@ -1,3 +1,3 @@
1
1
  .DS_Store
2
2
  .bundle/
3
-
3
+ pkg/*
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
- gem "activesupport", "~> 3.0.0"
8
- gem "activemodel", '~> 3.0.0'
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"
@@ -50,8 +50,8 @@ PLATFORMS
50
50
  ruby
51
51
 
52
52
  DEPENDENCIES
53
- activemodel (~> 3.0.0)
54
- activesupport (~> 3.0.0)
53
+ activemodel (~> 3.0)
54
+ activesupport (>= 2)
55
55
  i18n
56
56
  jeweler
57
57
  json
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: `Resque.redis = $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
- gemspec.add_dependency "activesupport", "3.0.0"
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
1
+ 0.0.2
@@ -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] ||= content[:"#{name}_object"].constantize.find(content[:"#{name}_id"])
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
@@ -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
- (0..count(type)-1).each do |i|
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}"
@@ -9,6 +9,11 @@ module Rediline
9
9
  define_method field_name.to_sym do
10
10
  Rediline::Timeline::User.new(field_name.to_sym, self, block)
11
11
  end
12
+
13
+ private
14
+ define_method "delete_rediline_#{field_name}" do
15
+ send(field_name).destroy
16
+ end
12
17
  end
13
18
  end
14
19
  end
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{rediline}
8
- s.version = "0.0.1"
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-23}
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>, ["= 3.0.0"])
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>, ["= 3.0.0"])
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>, ["= 3.0.0"])
86
+ s.add_dependency(%q<activesupport>, [">= 2"])
87
87
  end
88
88
  end
89
89
 
@@ -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),
@@ -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
@@ -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
@@ -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
- - 1
9
- version: 0.0.1
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-23 00:00:00 +02:00
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
- - 3
85
- - 0
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: 1586793397385962776
138
+ hash: 355954079675066628
141
139
  segments:
142
140
  - 0
143
141
  version: "0"