active_repository 0.2.7 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 605ad373409e52ed436bd85e89904760fe97e049
4
+ data.tar.gz: 39716333dfbdaa9d447bb8be5f384148d8815b4d
5
+ SHA512:
6
+ metadata.gz: 2841548917d159c2ac40c46fc2aaea7d724cd3479a4842b6e71ce53b7ed076e3781539a5a2e54391b83cc9bae310267450ac179b9340057a767de655944e7b14
7
+ data.tar.gz: cd3890fb5aa63a1cbcd90c533121710eb2b68a9839b92dcbdd0b4db0d267d7c0dce11e2e6eb625b6193faf50e64c03bb6213deac7c924fff2175cd4d8cac9381
@@ -24,16 +24,18 @@ Gem::Specification.new do |gem|
24
24
  "Gemfile",
25
25
  "spec/active_repository/base_spec.rb",
26
26
  "spec/active_repository/associations_spec.rb",
27
+ "spec/active_repository/result_set_spec.rb",
27
28
  "spec/support/shared_examples.rb",
28
29
  "spec/spec_helper.rb"
29
30
  ]
30
31
 
31
- gem.add_runtime_dependency(%q<active_hash>, [">= 0.9.12"])
32
- gem.add_runtime_dependency(%q<activemodel>, [">= 3.2.6"])
33
- gem.add_runtime_dependency(%q<sql_query_executor>, [">= 0.0.1"])
32
+ gem.add_runtime_dependency(%q<active_hash>, [">= 1.2.3"])
33
+ gem.add_runtime_dependency(%q<activemodel>, [">= 3.2"])
34
+ gem.add_runtime_dependency(%q<sql_query_executor>, [">= 0.3.1"])
35
+ gem.add_development_dependency(%q<pry>)
34
36
  gem.add_development_dependency(%q<rspec>, [">= 2.2.0"])
35
- gem.add_development_dependency(%q<activerecord>, [">= 3.2.6"])
36
- gem.add_development_dependency(%q<mongoid>, [">= 3.0.11"])
37
+ gem.add_development_dependency(%q<activerecord>, [">= 3.2"])
38
+ gem.add_development_dependency(%q<mongoid>, [">= 3.1"])
37
39
  gem.add_development_dependency('rake', [">= 10.0.0"])
38
40
  gem.add_development_dependency('coveralls')
39
41
  gem.add_development_dependency(%q<sqlite3>) unless RUBY_PLATFORM == 'java'
@@ -5,7 +5,7 @@ class DefaultAdapter
5
5
  end
6
6
 
7
7
  def delete(klass, id)
8
- object = klass.get_model_class.find_by_id(id)
8
+ object = klass.get_model_class.where(id: id).first
9
9
  object.delete if object
10
10
  end
11
11
 
@@ -18,6 +18,8 @@ class DefaultAdapter
18
18
  end
19
19
 
20
20
  def find(klass, id)
21
+ id = normalize_id(id) if id
22
+
21
23
  klass.get_model_class.find(id)
22
24
  end
23
25
 
@@ -49,9 +51,21 @@ class DefaultAdapter
49
51
  [ret, object]
50
52
  end
51
53
 
52
- def where(klass, args)
53
- # raise args.inspect
54
- klass.get_model_class.where(args)
54
+ def where(klass, query)
55
+ klass.get_model_class.where(query.to_sql)
56
+ end
57
+
58
+ private
59
+ def normalize_id(args)
60
+ return args if args.is_a?(Array)
61
+
62
+ id = (args.is_a?(Hash) ? args[:id] : args)
63
+
64
+ convertable?(id) ? id.to_i : id
65
+ end
66
+
67
+ def convertable?(id)
68
+ id.respond_to?(:to_i) && id.to_s == id.to_i.to_s
55
69
  end
56
70
  end
57
71
  end
@@ -46,8 +46,8 @@ class MongoidAdapter < DefaultAdapter
46
46
  # [ret, object]
47
47
  # end
48
48
 
49
- # def where(klass, args)
50
- # klass.where(args)
51
- # end
49
+ def where(klass, query)
50
+ klass.get_model_class.where(query.selector)
51
+ end
52
52
  end
53
53
  end
@@ -1,4 +1,3 @@
1
- require 'active_repository/adapters/active_hash_adapter'
2
1
  require 'active_repository/adapters/default_adapter'
3
2
  require 'active_repository/adapters/mongoid_adapter'
4
3
 
@@ -8,10 +7,6 @@ class PersistenceAdapter
8
7
  modules = klass.get_model_class.included_modules.map(&:to_s)
9
8
  if modules.include?("Mongoid::Document")
10
9
  MongoidAdapter
11
- elsif modules.map(&:to_s).include?("DataMapper::Resource")
12
- DataMapperAdapter
13
- # elsif modules.map(&:to_s).include?("MongoMapper::Document")
14
- # MongoMapperAdapter
15
10
  else
16
11
  DefaultAdapter
17
12
  end
@@ -1,42 +1,14 @@
1
- # Defines the relations between ActiveRepository objects and/or ActiveRecord Models.
1
+ # Defines the relations between ActiveRepository objects.
2
2
  #
3
3
  # Author:: Caio Torres (mailto:efreesen@gmail.com)
4
4
  # License:: GPL
5
5
 
6
6
  module ActiveRepository
7
7
  module Associations
8
- #:nodoc:
9
- module ActiveRecordExtensions
10
- # Defines belongs to type relation between ActiveRepository objects and ActivRecord Models.
11
- def belongs_to_active_repository(association_id, options = {})
12
- options = {
13
- class_name: association_id.to_s.classify,
14
- foreign_key: association_id.to_s.foreign_key
15
- }.merge(options)
16
-
17
- define_method(association_id) do
18
- options[:class_name].constantize.find_by_id(send(options[:foreign_key]))
19
- end
20
-
21
- define_method("#{association_id}=") do |new_value|
22
- send "#{options[:foreign_key]}=", new_value ? new_value.id : nil
23
- end
24
-
25
- create_reflection(
26
- :belongs_to,
27
- association_id.to_sym,
28
- options,
29
- options[:class_name].constantize
30
- )
31
- end
32
- end
33
-
34
- #:nodoc:
35
8
  def self.included(base)
36
9
  base.extend Methods
37
10
  end
38
11
 
39
- #:nodoc:
40
12
  module Methods
41
13
  # Defines "has many" type relation between ActiveRepository objects
42
14
  def has_many(association_id, options = {})
@@ -49,11 +21,7 @@ module ActiveRepository
49
21
  klass = options[:class_name].constantize
50
22
  objects = []
51
23
 
52
- if klass.respond_to?(:scoped)
53
- objects = klass.scoped(:conditions => {options[:foreign_key] => id})
54
- else
55
- objects = klass.send("find_all_by_#{options[:foreign_key]}", id)
56
- end
24
+ klass.where(options[:foreign_key] => id)
57
25
  end
58
26
  end
59
27
 
@@ -67,11 +35,11 @@ module ActiveRepository
67
35
 
68
36
  scope = options[:class_name].constantize
69
37
 
70
- if scope.respond_to?(:scoped) && options[:conditions]
71
- scope = scope.scoped(:conditions => options[:conditions])
72
- end
73
-
74
- scope.send("find_by_#{options[:foreign_key]}", id)
38
+ scope = scope.where(options[:conditions]) if options[:conditions]
39
+
40
+ send_params = scope.respond_to?(:find_by) ? ["find_by", id: id] : ["find_by_id", id]
41
+
42
+ scope.send(*send_params)
75
43
  end
76
44
  end
77
45
 
@@ -89,7 +57,7 @@ module ActiveRepository
89
57
  id = send(options[:foreign_key])
90
58
 
91
59
  if id.present?
92
- object = klass.find_by_id(id)
60
+ object = klass.respond_to?(:find_by) ? klass.find_by(id: id) : klass.find_by_id(id)
93
61
  else
94
62
  nil
95
63
  end
@@ -5,6 +5,7 @@ require 'sql_query_executor'
5
5
  require 'active_repository/finders'
6
6
  require 'active_repository/writers'
7
7
  require 'active_repository/adapters/persistence_adapter'
8
+ require 'active_repository/result_set'
8
9
 
9
10
  begin
10
11
  klass = Module.const_get(Mongoid::Document)
@@ -84,7 +85,7 @@ module ActiveRepository
84
85
 
85
86
  # Checks the existence of a persisted object with the specified id
86
87
  def self.exists?(id)
87
- repository? ? find_by_id(id).present? : PersistenceAdapter.exists?(self, id)
88
+ repository? ? find_by(id: id).present? : PersistenceAdapter.exists?(self, id)
88
89
  end
89
90
 
90
91
  # Returns the Class responsible for persisting the objects
@@ -93,12 +94,29 @@ module ActiveRepository
93
94
  save_in_memory? ? self : self.model_class
94
95
  end
95
96
 
97
+ # Searches all objects that matches #field_name field with the #args value(s)
98
+ def self.find_by(args)
99
+ raise ArgumentError("Argument must be a Hash") unless args.is_a?(Hash)
100
+
101
+ objects = where(args)
102
+
103
+ objects.first
104
+ end
105
+
106
+ # Searches all objects that matches #field_name field with the #args value(s)
107
+ def self.find_by!(args)
108
+ object = find_by(args)
109
+
110
+ raise ActiveHash::RecordNotFound unless object
111
+ object
112
+ end
113
+
96
114
  # Converts Persisted object(s) to it's ActiveRepository counterpart
97
115
  def self.serialize!(other)
98
116
  case other.class.to_s
99
117
  when "Hash", "ActiveSupport::HashWithIndifferentAccess" then self.new.serialize!(other)
100
118
  when "Array" then other.map { |o| serialize!(o.attributes) }
101
- when "Moped::BSON::Document" then self.new.serialize!(other)
119
+ when "Moped::BSON::Document", "BSON::Document" then self.new.serialize!(other)
102
120
  else self.new.serialize!(other.attributes)
103
121
  end
104
122
  end
@@ -113,11 +131,6 @@ module ActiveRepository
113
131
  self.model_class = value if model_class.nil?
114
132
 
115
133
  self.set_save_in_memory(repository?)
116
-
117
- field_names.each do |field_name|
118
- define_custom_find_by_field(field_name)
119
- define_custom_find_all_by_field(field_name)
120
- end
121
134
  end
122
135
 
123
136
  # Sets the class attribute save_in_memory, set it to true to ignore model_class attribute
@@ -134,19 +147,25 @@ module ActiveRepository
134
147
  # * RelatedClass.where(:name => "Peter")
135
148
  # * RelatedClass.where("name = 'Peter'")
136
149
  def self.where(*args)
137
- raise ArgumentError.new("wrong number of arguments (0 for 1)") if args.empty?
150
+ raise ArgumentError.new("must pass at least one argument") if args.empty?
138
151
 
139
- if repository?
140
- args = args.first if args.try(:first).is_a?(Array)
141
- query_executor = SqlQueryExecutor::Base.new(all)
142
- query_executor.where(args)
143
- else
144
- objects = PersistenceAdapter.where(self, sanitize_args(args)).map do |object|
145
- self.serialize!(object.attributes)
146
- end
152
+ result_set = ActiveRepository::ResultSet.new(self)
147
153
 
148
- objects
149
- end
154
+ # binding.pry
155
+
156
+ result_set.where(args)
157
+
158
+ # if repository?
159
+ # args = args.first if args.respond_to?(:size) && args.size == 1
160
+ # query_executor = SqlQueryExecutor::Base.new(all)
161
+ # query_executor.where(args)
162
+ # else
163
+ # objects = PersistenceAdapter.where(self, sanitize_args(args)).map do |object|
164
+ # self.serialize!(object.attributes)
165
+ # end
166
+
167
+ # objects
168
+ # end
150
169
  end
151
170
 
152
171
  def get_model_class
@@ -163,14 +182,16 @@ module ActiveRepository
163
182
 
164
183
  # Gathers the persisted object from database and updates self with it's attributes.
165
184
  def reload
166
- object = self.id.present? ? get_model_class.find(self.id) : self
185
+ object = self.id.present? ?
186
+ get_model_class.where(id: self.id).first_or_initialize :
187
+ self
167
188
 
168
189
  serialize! object.attributes
169
190
  end
170
191
 
171
192
  def save(force=false)
172
193
  if self.class == get_model_class
173
- object = get_model_class.find(self.id)
194
+ object = get_model_class.where(id: self.id).first_or_initialize
174
195
 
175
196
  if force || self.id.nil?
176
197
  self.id = nil if self.id.nil?
@@ -221,29 +242,10 @@ module ActiveRepository
221
242
  end
222
243
 
223
244
  private
224
-
225
- # Checks if model_class is a Mongoid model
226
- def self.mongoid?
227
- get_model_class.included_modules.include?(Mongoid::Document)
228
- end
229
-
230
245
  def self.repository?
231
246
  self == get_model_class
232
247
  end
233
248
 
234
- def self.sanitize_args(args)
235
- args.first.is_a?(Hash) ? args.first : (args.first.is_a?(Array) ? args.first : args)
236
- end
237
-
238
- def repository?
239
- self.class.repository?
240
- end
241
-
242
- # Checks if model_class is a Mongoid model
243
- def mongoid?
244
- self.class.mongoid?
245
- end
246
-
247
249
  # Updates created_at and updated_at
248
250
  def set_timestamps
249
251
  if self.errors.empty?
@@ -1,43 +1,13 @@
1
1
  # Module containing methods responsible for searching ActiveRepository objects
2
2
  module ActiveRepository #:nodoc:
3
3
  module Finders #:nodoc:
4
- # Defines fiend_by_field methods for the Class
5
- def define_custom_find_by_field(field_name)
6
- method_name = :"find_by_#{field_name}"
7
- the_meta_class.instance_eval do
8
- define_method(method_name) do |*args|
9
- object = nil
10
-
11
- object = self.where(field_name.to_sym => args).first
12
-
13
- object.nil? ? nil : serialize!(object.attributes)
14
- end
15
- end
16
- end
17
-
18
- # Defines fiend_all_by_field methods for the Class
19
- def define_custom_find_all_by_field(field_name)
20
- method_name = :"find_all_by_#{field_name}"
21
- the_meta_class.instance_eval do
22
- define_method(method_name) do |*args|
23
- objects = []
24
-
25
- objects = self.find_all_by_field(field_name.to_sym, args)
26
-
27
- objects.empty? ? [] : objects.map{ |object| serialize!(object.attributes) }
28
- end
29
- end
30
- end
31
-
32
4
  # Searches for a object containing the id in #id
33
5
  def find(id)
34
6
  begin
35
7
  if repository?
36
8
  super(id)
37
9
  else
38
- object = (id == :all) ? all : PersistenceAdapter.find(self, id)
39
-
40
- serialize!(object)
10
+ serialize!(PersistenceAdapter.find(self, id))
41
11
  end
42
12
  rescue Exception => e
43
13
  message = "Couldn't find #{self} with ID=#{id}"
@@ -47,51 +17,6 @@ module ActiveRepository #:nodoc:
47
17
  end
48
18
  end
49
19
 
50
- # Searches all objects that matches #field_name field with the #args value(s)
51
- def find_all_by_field(field_name, args)
52
- objects = []
53
-
54
- # raise "field: #{field_name}; values: #{args.first.inspect}; all: #{get_model_class.all.inspect}"
55
-
56
- if repository?
57
- objects = self.where(field_name.to_sym => args.first)
58
- else
59
- objects = PersistenceAdapter.where(self, field_name.to_sym => args.first)
60
- # if mongoid?
61
- # objects = get_model_class.where(field_name.to_sym => args.first)
62
- # else
63
- # method_name = :"find_all_by_#{field_name}"
64
- # objects = get_model_class.send(method_name, args)
65
- # end
66
- end
67
-
68
- objects
69
- end
70
-
71
- # Searches first object that matches #field_name field with the #args value(s)
72
- # def find_by_field(field_name, args)
73
- # self.find_all_by_field(field_name, args).first.dup
74
- # end
75
-
76
- # Searches for an object that has id with #id value, if none is found returns nil
77
- def find_by_id(id)
78
- if repository?
79
- object = super(id)
80
-
81
- object.nil? ? nil : object.dup
82
- else
83
- object = PersistenceAdapter.where(self, :id => id).first
84
-
85
- # if mongoid?
86
- # object = get_model_class.where(:id => id).entries.first
87
- # else
88
- # object = get_model_class.find_by_id(id)
89
- # end
90
-
91
- object.nil? ? nil : serialize!(object.attributes)
92
- end
93
- end
94
-
95
20
  # Returns first persisted object
96
21
  def first
97
22
  repository? ? super : get(:first)
@@ -0,0 +1,76 @@
1
+ class ActiveRepository::ResultSet
2
+ def initialize(klass, query={}, attributes={})
3
+ @klass = klass
4
+ convert_query(query)
5
+ @attributes = query.is_a?(Hash) ? attributes.merge(query) : attributes
6
+ end
7
+
8
+ def all
9
+ @query ? get_result(@query) : @klass.all
10
+ end
11
+
12
+ def count
13
+ all.size
14
+ end
15
+
16
+ def first
17
+ @query ? all.first : @klass.all.first
18
+ end
19
+
20
+ def first_or_initialize
21
+ object = all.first
22
+
23
+ object ? object : @klass.new(@attributes)
24
+ end
25
+
26
+ def first_or_create
27
+ object = first_or_initialize
28
+
29
+ object.new_record? ? object.save : object
30
+
31
+ object.reload
32
+ end
33
+
34
+ def last
35
+ @query ? all.last : @klass.all.last
36
+ end
37
+
38
+ def where(query)
39
+ @attributes = @attributes.merge(query) if query.is_a?(Hash)
40
+ query = join_query(query, 'and')
41
+
42
+ ActiveRepository::ResultSet.new(@klass, query, @attributes)
43
+ end
44
+ alias_method :and, :where
45
+
46
+ def or(query)
47
+ query = join_query(query, 'or')
48
+
49
+ ActiveRepository::ResultSet.new(@klass, query, @attributes)
50
+ end
51
+
52
+ private
53
+ def convert_query(query)
54
+ @query = SqlQueryExecutor::Query::QueryNormalizer.clean_query(query)
55
+ end
56
+
57
+ def get_result(args)
58
+ if @klass.repository?
59
+ args = args.first if args.is_a?(Array) && args.size == 1
60
+ query_executor = SqlQueryExecutor::Base.new(@klass.all, args)
61
+ query_executor.execute!
62
+ else
63
+ query = SqlQueryExecutor::Base.new([], args)
64
+ objects = PersistenceAdapter.where(@klass, query).map do |object|
65
+ @klass.serialize!(object.attributes)
66
+ end
67
+
68
+ objects
69
+ end
70
+ end
71
+
72
+ def join_query(query, separator)
73
+ query = SqlQueryExecutor::Query::QueryNormalizer.clean_query(query)
74
+ query.blank? ? @query : (@query.blank? ? query : "(#{@query}) #{separator} (#{query})")
75
+ end
76
+ end
@@ -1,3 +1,3 @@
1
1
  module ActiveRepository
2
- VERSION = "0.2.7"
2
+ VERSION = "0.3.0"
3
3
  end
@@ -40,32 +40,17 @@ module ActiveHash
40
40
  end
41
41
  end
42
42
 
43
- def self.where(query)
44
- if query.is_a?(String)
45
- return ActiveHash::SQLQueryExecutor.execute(self, query)
46
- else
47
- (@records || []).select do |record|
48
- query.all? { |col, match| record[col] == match }
49
- end
50
- end
51
- end
52
-
53
43
  def self.validate_unique_id(record)
54
44
  raise IdError.new("Duplicate Id found for record #{record.attributes}") if record_index.has_key?(record.id.to_s)
55
45
  end
56
46
 
57
- def update_attribute(key, value)
58
- self.send("#{key}=", value)
59
- self.save(:validate => false)
60
- end
61
-
62
47
  def readonly?
63
48
  false
64
49
  end
65
50
 
66
51
  def save(*args)
67
52
  if self.valid?
68
- record = self.class.find_by_id(self.id)
53
+ record = self.class.find_by(id: self.id)
69
54
 
70
55
  self.class.insert(self) if record.nil? && record != self
71
56
 
@@ -77,11 +62,11 @@ module ActiveHash
77
62
  end
78
63
 
79
64
  def delete
80
- record = self.class.find_by_id(self.id)
65
+ record = self.class.find_by(id: self.id)
81
66
 
82
67
  self.class.remove(self)
83
68
 
84
- self.class.find_by_id(self.id).nil?
69
+ self.class.find_by(id: self.id).nil?
85
70
  end
86
71
 
87
72
  def to_param
@@ -89,7 +74,7 @@ module ActiveHash
89
74
  end
90
75
 
91
76
  def persisted?
92
- other = self.class.find_by_id(id)
77
+ other = self.class.find_by(id: id)
93
78
  other.present?
94
79
  end
95
80
 
@@ -23,25 +23,6 @@ module ActiveRepository
23
23
  new_object
24
24
  end
25
25
 
26
- # Searches for an object that matches the attributes on the parameter, if none is found
27
- # it creates one with the defined attributes.
28
- def find_or_create(attributes)
29
- object = where(attributes).first
30
-
31
- object.nil? ? create(attributes) : object
32
- end
33
-
34
- def find_or_initialize(attributes)
35
- attributes = attributes.symbolize_keys if attributes.respond_to?(:symbolize_keys)
36
- object = where(attributes).first || self.new(attributes)
37
-
38
- attributes.each do |key, value|
39
- object.send("#{key}=", value)
40
- end
41
-
42
- serialize!(object.attributes)
43
- end
44
-
45
26
  #:nodoc:
46
27
  module InstanceMethods
47
28
  # Assigns new_attributes parameter to the attributes in self.
@@ -67,7 +48,7 @@ module ActiveRepository
67
48
  key = key.to_sym
68
49
 
69
50
  if self.class == get_model_class
70
- object = self.class.find_or_initialize(:id => self.id)
51
+ object = self.class.where(:id => self.id).first_or_initialize
71
52
 
72
53
  self.send("#{key}=", value)
73
54