dm-mongo-adapter 0.2.0.pre3 → 0.6.0

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.
Files changed (64) hide show
  1. data/Gemfile +27 -0
  2. data/README.rdoc +16 -35
  3. data/Rakefile +6 -16
  4. data/VERSION.yml +2 -2
  5. data/dm-mongo-adapter.gemspec +100 -121
  6. data/lib/mongo_adapter.rb +19 -62
  7. data/lib/mongo_adapter/adapter.rb +49 -36
  8. data/lib/mongo_adapter/conditions.rb +0 -5
  9. data/lib/mongo_adapter/migrations.rb +17 -23
  10. data/lib/mongo_adapter/model.rb +3 -74
  11. data/lib/mongo_adapter/modifier.rb +1 -1
  12. data/lib/mongo_adapter/property/array.rb +10 -0
  13. data/lib/mongo_adapter/property/db_ref.rb +17 -0
  14. data/lib/mongo_adapter/property/hash.rb +27 -0
  15. data/lib/mongo_adapter/property/object_id.rb +47 -0
  16. data/lib/mongo_adapter/query.rb +42 -45
  17. data/lib/mongo_adapter/rails/storage.rb +15 -0
  18. data/lib/mongo_adapter/resource.rb +0 -130
  19. data/lib/mongo_adapter/support/class.rb +11 -0
  20. data/lib/mongo_adapter/support/date.rb +11 -0
  21. data/lib/mongo_adapter/support/date_time.rb +12 -0
  22. data/lib/mongo_adapter/support/object.rb +9 -0
  23. data/spec/legacy/adapter_spec.rb +9 -6
  24. data/spec/legacy/associations_spec.rb +37 -29
  25. data/spec/legacy/property_spec.rb +4 -3
  26. data/spec/legacy/sti_spec.rb +1 -2
  27. data/spec/lib/cleanup_models.rb +0 -1
  28. data/spec/public/aggregates_spec.rb +171 -0
  29. data/spec/public/model_spec.rb +8 -22
  30. data/spec/public/modifier_spec.rb +109 -0
  31. data/spec/public/properties/db_ref_spec.rb +17 -0
  32. data/spec/public/properties/object_id_spec.rb +15 -0
  33. data/spec/public/resource_spec.rb +2 -383
  34. data/spec/public/shared/object_id_shared_spec.rb +16 -39
  35. data/spec/spec_helper.rb +0 -4
  36. metadata +87 -117
  37. data/.gitignore +0 -9
  38. data/lib/mongo_adapter/embedded_model.rb +0 -187
  39. data/lib/mongo_adapter/embedded_resource.rb +0 -134
  40. data/lib/mongo_adapter/embedments/one_to_many.rb +0 -144
  41. data/lib/mongo_adapter/embedments/one_to_one.rb +0 -57
  42. data/lib/mongo_adapter/embedments/relationship.rb +0 -258
  43. data/lib/mongo_adapter/model/embedment.rb +0 -215
  44. data/lib/mongo_adapter/types/date.rb +0 -24
  45. data/lib/mongo_adapter/types/date_time.rb +0 -28
  46. data/lib/mongo_adapter/types/db_ref.rb +0 -65
  47. data/lib/mongo_adapter/types/discriminator.rb +0 -32
  48. data/lib/mongo_adapter/types/object_id.rb +0 -72
  49. data/lib/mongo_adapter/types/objects.rb +0 -31
  50. data/spec/legacy/embedded_resource_spec.rb +0 -157
  51. data/spec/legacy/embedments_spec.rb +0 -177
  52. data/spec/legacy/modifier_spec.rb +0 -81
  53. data/spec/public/embedded_collection_spec.rb +0 -61
  54. data/spec/public/embedded_resource_spec.rb +0 -220
  55. data/spec/public/model/embedment_spec.rb +0 -186
  56. data/spec/public/shared/model_embedments_spec.rb +0 -338
  57. data/spec/public/types/df_ref_spec.rb +0 -6
  58. data/spec/public/types/discriminator_spec.rb +0 -118
  59. data/spec/public/types/embedded_array_spec.rb +0 -55
  60. data/spec/public/types/embedded_hash_spec.rb +0 -83
  61. data/spec/public/types/object_id_spec.rb +0 -6
  62. data/spec/semipublic/embedded_model_spec.rb +0 -43
  63. data/spec/semipublic/model/embedment_spec.rb +0 -42
  64. data/spec/semipublic/resource_spec.rb +0 -70
@@ -1,215 +0,0 @@
1
- module DataMapper
2
- module Mongo
3
- module Model
4
- # Embedment extends Mongo-based resources to allow resources to be
5
- # embedded within a document, while providing relationship-like `has 1`
6
- # and `has n` functionality.
7
- #
8
- # @example
9
- # class User
10
- # include DataMapper::Mongo::Resource
11
- #
12
- # property :id, ObjectID
13
- # property :name, String
14
- #
15
- # embeds n, :addresses, :model => Address
16
- # end
17
- #
18
- # class Address
19
- # include DataMapper::Mongo::EmbeddedResource
20
- #
21
- # property :street, String
22
- # property :post_code, String
23
- # end
24
- #
25
- module Embedment
26
- extend Chainable
27
-
28
- # Options which cannot be used on Embedments.
29
- ILLEGAL_OPTS = [:through, :remote_name, :via, :inverse, :parent_key]
30
-
31
- # @api private
32
- def self.extended(model)
33
- model.instance_variable_set(:@embedments, {})
34
- end
35
-
36
- chainable do
37
- # @api private
38
- def inherited(model)
39
- model.instance_variable_set(:@embedments, {})
40
-
41
- @embedments.each { |name, embedment| model.embedments[name] ||= embedment }
42
-
43
- super
44
- end
45
- end
46
-
47
- chainable do
48
- # @api public
49
- def method_missing(method, *args, &block)
50
- if respond_to?(:embedments) && embedment = embedments[method]
51
- return embedment
52
- end
53
-
54
- super
55
- end
56
- end
57
-
58
- # Returns the embedments on this model
59
- #
60
- # @return [Hash]
61
- # Embedments on this model, where each hash key is the embedment
62
- # name, and each value is the Embedments::Relationship instance.
63
- #
64
- # @api semipublic
65
- def embedments
66
- @embedments ||= {}
67
- end
68
-
69
- # A short-hand, clear syntax for defining one-to-one and one-to-many
70
- # embedments -- where an embedded resource is held within the parent
71
- # document in the database.
72
- #
73
- # @example
74
- # embed 1, :friend # one friend
75
- # embed n, :friends # many friends
76
- # embed 1..3, :friends # many friends (at least 1, at most 3)
77
- # embed 3, :friends # many friends (exactly 3)
78
- # embed 1, :friend, 'User' # one friend with the class User
79
- #
80
- # @param cardinality [Integer, Range, Infinity]
81
- # Cardinality that defines the embedment type and constraints
82
- # @param name [Symbol]
83
- # The name that the embedment will be referenced by
84
- # @param model [Model, #to_str]
85
- # The target model of the embedment
86
- # @param opts [Hash]
87
- # An options hash
88
- #
89
- # @option :model[Model, String] The name of the class to associate
90
- # with, if omitted then the model class name is assumed to match the
91
- # (optional) third parameter, or the embedment name.
92
- #
93
- # @return [Embedment::Relationship]
94
- # The embedment that was created to reflect either a one-to-one or
95
- # one-to-many embedment.
96
- #
97
- # @raise [ArgumentError]
98
- # If the cardinality was not understood. Should be a Integer, Range
99
- # or Infinity(n)
100
- #
101
- # @api public
102
- def embeds(cardinality, name, *args)
103
- assert_kind_of 'cardinality', cardinality, Integer, Range, Infinity.class
104
- assert_kind_of 'name', name, Symbol
105
-
106
- model = extract_model(args)
107
- options = extract_options(args)
108
-
109
- min, max = extract_min_max(cardinality)
110
- options.update(:min => min, :max => max)
111
-
112
- assert_valid_options(options)
113
-
114
- if options.key?(:model) && model
115
- raise ArgumentError, 'should not specify options[:model] if passing the model in the third argument'
116
- end
117
-
118
- model ||= options.delete(:model)
119
-
120
- klass = if max > 1
121
- Embedments::OneToMany::Relationship
122
- else
123
- Embedments::OneToOne::Relationship
124
- end
125
-
126
- embedment = embedments[name] = klass.new(name, model, self, options)
127
-
128
- descendants.each do |descendant|
129
- descendant.embedments[name] ||= embedment
130
- end
131
-
132
- create_embedment_reader(embedment)
133
- create_embedment_writer(embedment)
134
-
135
- embedment
136
- end
137
-
138
- # @todo Investigate as a candidate for removal.
139
- # Added 26ae98e1 as an equivelent of belongs_to but _probably_ isn't
140
- # of much use in embedded resources (since it would be perfectly
141
- # acceptable for an embedment to be used in multiple models). My
142
- # opinion is that embedments should always be declared from the
143
- # parent side (DM::M::Resource), rather the child side
144
- # (DM::M::EmbeddedResource).
145
- #
146
- # ~antw
147
- #
148
- # @api public
149
- def embedded_in(name, *args)
150
- return NotImplementedError
151
- end
152
-
153
- def assert_valid_options(options)
154
- ILLEGAL_OPTS.each do |option|
155
- raise ArgumentError, "+options[:#{option}]+ should not be " \
156
- "specified on a relationship" if options.key?(option)
157
- end
158
-
159
- super
160
- end
161
-
162
- # Dynamically defines a reader method
163
- #
164
- # Creates a public method matching the name of the embedment which can
165
- # be used to access the embedded resource(s).
166
- #
167
- # @param [Embedment::Relationship] embedment
168
- # The embedment for which a reader should be created
169
- #
170
- # @api private
171
- def create_embedment_reader(embedment)
172
- name = embedment.name
173
- reader_name = name.to_s
174
-
175
- return if resource_method_defined?(reader_name)
176
-
177
- reader_visibility = embedment.reader_visibility
178
-
179
- class_eval <<-RUBY, __FILE__, __LINE__ + 1
180
- #{reader_visibility} # public
181
- def #{reader_name}(query = nil) # def author(query = nil)
182
- embedments[#{name.inspect}].get(self, query) # embedment[:author].get(self, query)
183
- end # end
184
- RUBY
185
- end
186
-
187
- # Dynamically defines a writer method
188
- #
189
- # Creates a public method matching the name of the embedment which can
190
- # be used to set the embedded resource(s).
191
- #
192
- # @param [Embedment::Relationship] embedment
193
- # The embedment for which a writer should be created
194
- #
195
- # @api private
196
- def create_embedment_writer(embedment)
197
- name = embedment.name
198
- writer_name = "#{name}="
199
-
200
- return if resource_method_defined?(writer_name)
201
-
202
- writer_visibility = embedment.writer_visibility
203
-
204
- class_eval <<-RUBY, __FILE__, __LINE__ + 1
205
- #{writer_visibility} # public
206
- def #{writer_name}(target) # def author=(target)
207
- embedments[#{name.inspect}].set(self, target) # embedment[:author].set(self, target)
208
- end # end
209
- RUBY
210
- end
211
- end
212
-
213
- end # Model
214
- end # Mongo
215
- end # DataMapper
@@ -1,24 +0,0 @@
1
- module DataMapper
2
- module Mongo
3
- module Types
4
- class Date < DataMapper::Type
5
- primitive ::Time
6
-
7
- def self.load(value, property)
8
- self.typecast(value, property)
9
- end
10
-
11
- def self.typecast(value, property)
12
- case value
13
- when ::Date
14
- Time.utc(value.year, value.month, value.day)
15
- when ::Time
16
- ::Date.new(value.year, value.month, value.day)
17
- when NilClass, Range
18
- value
19
- end
20
- end
21
- end
22
- end # Types
23
- end # Mongo
24
- end # DataMapper
@@ -1,28 +0,0 @@
1
- module DataMapper
2
- module Mongo
3
- module Types
4
- class DateTime < DataMapper::Type
5
- primitive Time
6
-
7
- def self.load(value, property)
8
- self.typecast(value, property)
9
- end
10
-
11
- def self.dump(value, property)
12
- self.typecast(value, property)
13
- end
14
-
15
- def self.typecast(value, property)
16
- case value
17
- when Time
18
- value.to_datetime
19
- when ::DateTime
20
- value.to_time.utc
21
- when NilClass, Range
22
- value
23
- end
24
- end
25
- end
26
- end # Types
27
- end # Mongo
28
- end # DataMapper
@@ -1,65 +0,0 @@
1
- module DataMapper
2
- module Mongo
3
- module Types
4
- # Database references are references from one document (object) to
5
- # another within a database. A database reference is a standard embedded
6
- # object: this is a MongoDB convention, not a special type.
7
- #
8
- # The DBRef is made available via your model as a String.
9
- #
10
- # @see http://www.mongodb.org/display/DOCS/DB+Ref
11
- #
12
- # @api public
13
- class DBRef < DataMapper::Type
14
- primitive ::Object
15
-
16
- # Returns the DBRef as a string; suitable for use in a Resource
17
- #
18
- # @return [String]
19
- #
20
- # @api public
21
- def self.load(value, property)
22
- typecast(value, property)
23
- end
24
-
25
- # Returns the DBRef as a Mongo ObjectID; suitable to be passed to the
26
- # Mongo library
27
- #
28
- # @return [Mongo::ObjectID] The dumped ID.
29
- #
30
- # @api public
31
- def self.dump(value, property)
32
- case value
33
- when NilClass
34
- nil
35
- when String
36
- ::Mongo::ObjectID.from_string(value)
37
- when ::Mongo::ObjectID
38
- value
39
- else
40
- raise ArgumentError.new('+value+ must be nil, String, ObjectID')
41
- end
42
- end
43
-
44
- # Returns the DBRef as a string
45
- #
46
- # @return [String]
47
- #
48
- # @api semipublic
49
- def self.typecast(value, property)
50
- case value
51
- when NilClass
52
- nil
53
- when String
54
- value
55
- when ::Mongo::ObjectID
56
- value.to_s
57
- else
58
- raise ArgumentError.new('+value+ must be nil, String, ObjectID')
59
- end
60
- end
61
-
62
- end # DBRef
63
- end # Types
64
- end # Mongo
65
- end # DataMapper
@@ -1,32 +0,0 @@
1
- module DataMapper
2
- module Mongo
3
- module Types
4
- class Discriminator < DataMapper::Types::Discriminator
5
- primitive String
6
- default lambda { |resource, property| resource.model.to_s }
7
-
8
- def self.load(value, property)
9
- typecast(value, property)
10
- end
11
-
12
- def self.dump(value, property)
13
- value.name
14
- end
15
-
16
- def self.typecast(value, property)
17
- if value
18
- if value.is_a?(String)
19
- Extlib::Inflection.constantize(value)
20
- else
21
- value
22
- end
23
- end
24
- end
25
-
26
- def self.==(other)
27
- other == DataMapper::Types::Discriminator || super
28
- end
29
- end
30
- end
31
- end
32
- end
@@ -1,72 +0,0 @@
1
- module DataMapper
2
- module Mongo
3
- module Types
4
- # Each object (document) stored in Mongo DB has an _id field as its
5
- # first attribute. This is an object id. It must be unique for each
6
- # member of a collection (this is enforced if the collection has an _id
7
- # index, which is the case by default).
8
- #
9
- # The database will assign an _id if an object being inserted into a
10
- # collection does not have one.
11
- #
12
- # The _id may be of any type as long as it is a unique value.
13
- #
14
- # @see http://www.mongodb.org/display/DOCS/Object+IDs
15
- #
16
- # @api public
17
- class ObjectID < DataMapper::Type
18
- primitive ::Object
19
- key true
20
- field "_id"
21
- required false
22
-
23
- # Returns the ObjectID as a string; suitable for use in a Resource
24
- #
25
- # @return [String]
26
- #
27
- # @api public
28
- def self.load(value, property)
29
- typecast(value, property)
30
- end
31
-
32
- # Returns the ObjectID as a Mongo::ObjectID; suitable to be passed to
33
- # the Mongo library
34
- #
35
- # @return [Mongo::ObjectID] The dumped ID.
36
- #
37
- # @api public
38
- def self.dump(value, property)
39
- case value
40
- when NilClass
41
- nil
42
- when String
43
- ::Mongo::ObjectID.from_string(value)
44
- when ::Mongo::ObjectID
45
- value
46
- else
47
- raise ArgumentError.new('+value+ must be nil, String or ObjectID')
48
- end
49
- end
50
-
51
- # Returns the ObjectID as a string
52
- #
53
- # @return [String]
54
- #
55
- # @api semipublic
56
- def self.typecast(value, property)
57
- case value
58
- when NilClass
59
- nil
60
- when String
61
- value
62
- when ::Mongo::ObjectID
63
- value.to_s
64
- else
65
- raise ArgumentError.new('+value+ must be nil, String or ObjectID')
66
- end
67
- end
68
-
69
- end # ObjectID
70
- end # Types
71
- end # Mongo
72
- end # DataMapper
@@ -1,31 +0,0 @@
1
- module DataMapper
2
- module Mongo
3
- module Types
4
- class EmbeddedArray < DataMapper::Type
5
- primitive Object
6
- end
7
-
8
- class EmbeddedHash < DataMapper::Type
9
- primitive Object
10
-
11
- # @api public
12
- def self.load(value, property)
13
- typecast(value, property)
14
- end
15
-
16
- # @api semipublic
17
- def self.typecast(value, property)
18
- case value
19
- when NilClass
20
- nil
21
- when Hash
22
- value.to_mash.symbolize_keys
23
- when Array
24
- value.empty? ? Mash.new : [value].to_mash.symbolize_keys
25
- end
26
- end
27
- end #EmbeddedHash
28
-
29
- end # Types
30
- end # Mongo
31
- end # DataMapper