ign-mongo_mapper 0.8.6.1

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 (147) hide show
  1. data/LICENSE +20 -0
  2. data/README.rdoc +33 -0
  3. data/UPGRADES +7 -0
  4. data/bin/mmconsole +60 -0
  5. data/examples/attr_accessible.rb +22 -0
  6. data/examples/attr_protected.rb +22 -0
  7. data/examples/cache_key.rb +24 -0
  8. data/examples/custom_types.rb +24 -0
  9. data/examples/identity_map.rb +33 -0
  10. data/examples/identity_map/automatic.rb +8 -0
  11. data/examples/keys.rb +40 -0
  12. data/examples/modifiers/set.rb +25 -0
  13. data/examples/plugins.rb +41 -0
  14. data/examples/querying.rb +35 -0
  15. data/examples/safe.rb +43 -0
  16. data/examples/scopes.rb +52 -0
  17. data/examples/validating/embedded_docs.rb +29 -0
  18. data/lib/mongo_mapper.rb +83 -0
  19. data/lib/mongo_mapper/connection.rb +83 -0
  20. data/lib/mongo_mapper/document.rb +41 -0
  21. data/lib/mongo_mapper/embedded_document.rb +31 -0
  22. data/lib/mongo_mapper/exceptions.rb +27 -0
  23. data/lib/mongo_mapper/extensions/array.rb +19 -0
  24. data/lib/mongo_mapper/extensions/binary.rb +22 -0
  25. data/lib/mongo_mapper/extensions/boolean.rb +44 -0
  26. data/lib/mongo_mapper/extensions/date.rb +25 -0
  27. data/lib/mongo_mapper/extensions/float.rb +14 -0
  28. data/lib/mongo_mapper/extensions/hash.rb +14 -0
  29. data/lib/mongo_mapper/extensions/integer.rb +19 -0
  30. data/lib/mongo_mapper/extensions/kernel.rb +9 -0
  31. data/lib/mongo_mapper/extensions/nil_class.rb +18 -0
  32. data/lib/mongo_mapper/extensions/object.rb +27 -0
  33. data/lib/mongo_mapper/extensions/object_id.rb +30 -0
  34. data/lib/mongo_mapper/extensions/set.rb +20 -0
  35. data/lib/mongo_mapper/extensions/string.rb +18 -0
  36. data/lib/mongo_mapper/extensions/time.rb +29 -0
  37. data/lib/mongo_mapper/middleware/identity_map.rb +16 -0
  38. data/lib/mongo_mapper/plugins.rb +15 -0
  39. data/lib/mongo_mapper/plugins/accessible.rb +44 -0
  40. data/lib/mongo_mapper/plugins/associations.rb +134 -0
  41. data/lib/mongo_mapper/plugins/associations/base.rb +124 -0
  42. data/lib/mongo_mapper/plugins/associations/belongs_to_polymorphic_proxy.rb +29 -0
  43. data/lib/mongo_mapper/plugins/associations/belongs_to_proxy.rb +24 -0
  44. data/lib/mongo_mapper/plugins/associations/collection.rb +27 -0
  45. data/lib/mongo_mapper/plugins/associations/embedded_collection.rb +40 -0
  46. data/lib/mongo_mapper/plugins/associations/in_array_proxy.rb +151 -0
  47. data/lib/mongo_mapper/plugins/associations/many_documents_as_proxy.rb +28 -0
  48. data/lib/mongo_mapper/plugins/associations/many_documents_proxy.rb +109 -0
  49. data/lib/mongo_mapper/plugins/associations/many_embedded_polymorphic_proxy.rb +32 -0
  50. data/lib/mongo_mapper/plugins/associations/many_embedded_proxy.rb +24 -0
  51. data/lib/mongo_mapper/plugins/associations/many_polymorphic_proxy.rb +14 -0
  52. data/lib/mongo_mapper/plugins/associations/one_embedded_proxy.rb +41 -0
  53. data/lib/mongo_mapper/plugins/associations/one_proxy.rb +68 -0
  54. data/lib/mongo_mapper/plugins/associations/proxy.rb +139 -0
  55. data/lib/mongo_mapper/plugins/caching.rb +21 -0
  56. data/lib/mongo_mapper/plugins/callbacks.rb +243 -0
  57. data/lib/mongo_mapper/plugins/clone.rb +22 -0
  58. data/lib/mongo_mapper/plugins/descendants.rb +17 -0
  59. data/lib/mongo_mapper/plugins/dirty.rb +124 -0
  60. data/lib/mongo_mapper/plugins/document.rb +41 -0
  61. data/lib/mongo_mapper/plugins/dynamic_querying.rb +43 -0
  62. data/lib/mongo_mapper/plugins/dynamic_querying/dynamic_finder.rb +44 -0
  63. data/lib/mongo_mapper/plugins/embedded_document.rb +48 -0
  64. data/lib/mongo_mapper/plugins/equality.rb +17 -0
  65. data/lib/mongo_mapper/plugins/identity_map.rb +128 -0
  66. data/lib/mongo_mapper/plugins/indexes.rb +12 -0
  67. data/lib/mongo_mapper/plugins/inspect.rb +15 -0
  68. data/lib/mongo_mapper/plugins/keys.rb +311 -0
  69. data/lib/mongo_mapper/plugins/keys/key.rb +65 -0
  70. data/lib/mongo_mapper/plugins/logger.rb +18 -0
  71. data/lib/mongo_mapper/plugins/modifiers.rb +112 -0
  72. data/lib/mongo_mapper/plugins/pagination.rb +14 -0
  73. data/lib/mongo_mapper/plugins/persistence.rb +69 -0
  74. data/lib/mongo_mapper/plugins/protected.rb +53 -0
  75. data/lib/mongo_mapper/plugins/querying.rb +176 -0
  76. data/lib/mongo_mapper/plugins/querying/decorator.rb +46 -0
  77. data/lib/mongo_mapper/plugins/querying/plucky_methods.rb +15 -0
  78. data/lib/mongo_mapper/plugins/rails.rb +58 -0
  79. data/lib/mongo_mapper/plugins/safe.rb +28 -0
  80. data/lib/mongo_mapper/plugins/sci.rb +32 -0
  81. data/lib/mongo_mapper/plugins/scopes.rb +21 -0
  82. data/lib/mongo_mapper/plugins/serialization.rb +76 -0
  83. data/lib/mongo_mapper/plugins/timestamps.rb +22 -0
  84. data/lib/mongo_mapper/plugins/userstamps.rb +15 -0
  85. data/lib/mongo_mapper/plugins/validations.rb +50 -0
  86. data/lib/mongo_mapper/support/descendant_appends.rb +45 -0
  87. data/lib/mongo_mapper/version.rb +4 -0
  88. data/rails/init.rb +15 -0
  89. data/test/_NOTE_ON_TESTING +1 -0
  90. data/test/functional/associations/test_belongs_to_polymorphic_proxy.rb +64 -0
  91. data/test/functional/associations/test_belongs_to_proxy.rb +117 -0
  92. data/test/functional/associations/test_in_array_proxy.rb +349 -0
  93. data/test/functional/associations/test_many_documents_as_proxy.rb +229 -0
  94. data/test/functional/associations/test_many_documents_proxy.rb +615 -0
  95. data/test/functional/associations/test_many_embedded_polymorphic_proxy.rb +176 -0
  96. data/test/functional/associations/test_many_embedded_proxy.rb +256 -0
  97. data/test/functional/associations/test_many_polymorphic_proxy.rb +303 -0
  98. data/test/functional/associations/test_one_embedded_proxy.rb +100 -0
  99. data/test/functional/associations/test_one_proxy.rb +206 -0
  100. data/test/functional/test_accessible.rb +168 -0
  101. data/test/functional/test_associations.rb +46 -0
  102. data/test/functional/test_binary.rb +27 -0
  103. data/test/functional/test_caching.rb +76 -0
  104. data/test/functional/test_callbacks.rb +151 -0
  105. data/test/functional/test_dirty.rb +163 -0
  106. data/test/functional/test_document.rb +272 -0
  107. data/test/functional/test_dynamic_querying.rb +75 -0
  108. data/test/functional/test_embedded_document.rb +210 -0
  109. data/test/functional/test_identity_map.rb +513 -0
  110. data/test/functional/test_indexes.rb +42 -0
  111. data/test/functional/test_logger.rb +20 -0
  112. data/test/functional/test_modifiers.rb +416 -0
  113. data/test/functional/test_pagination.rb +91 -0
  114. data/test/functional/test_protected.rb +175 -0
  115. data/test/functional/test_querying.rb +873 -0
  116. data/test/functional/test_safe.rb +76 -0
  117. data/test/functional/test_sci.rb +230 -0
  118. data/test/functional/test_scopes.rb +171 -0
  119. data/test/functional/test_string_id_compatibility.rb +67 -0
  120. data/test/functional/test_timestamps.rb +62 -0
  121. data/test/functional/test_userstamps.rb +27 -0
  122. data/test/functional/test_validations.rb +342 -0
  123. data/test/models.rb +233 -0
  124. data/test/test_active_model_lint.rb +13 -0
  125. data/test/test_helper.rb +102 -0
  126. data/test/unit/associations/test_base.rb +212 -0
  127. data/test/unit/associations/test_proxy.rb +105 -0
  128. data/test/unit/serializers/test_json_serializer.rb +217 -0
  129. data/test/unit/test_clone.rb +69 -0
  130. data/test/unit/test_descendant_appends.rb +71 -0
  131. data/test/unit/test_document.rb +208 -0
  132. data/test/unit/test_dynamic_finder.rb +125 -0
  133. data/test/unit/test_embedded_document.rb +639 -0
  134. data/test/unit/test_extensions.rb +376 -0
  135. data/test/unit/test_identity_map_middleware.rb +34 -0
  136. data/test/unit/test_inspect.rb +22 -0
  137. data/test/unit/test_key.rb +205 -0
  138. data/test/unit/test_keys.rb +89 -0
  139. data/test/unit/test_mongo_mapper.rb +110 -0
  140. data/test/unit/test_pagination.rb +11 -0
  141. data/test/unit/test_plugins.rb +50 -0
  142. data/test/unit/test_rails.rb +181 -0
  143. data/test/unit/test_rails_compatibility.rb +52 -0
  144. data/test/unit/test_serialization.rb +51 -0
  145. data/test/unit/test_time_zones.rb +39 -0
  146. data/test/unit/test_validations.rb +564 -0
  147. metadata +385 -0
@@ -0,0 +1,14 @@
1
+ # encoding: UTF-8
2
+ module MongoMapper
3
+ module Plugins
4
+ module Pagination
5
+ module ClassMethods
6
+ def per_page; 25 end
7
+
8
+ def paginate(opts={})
9
+ query.paginate({:per_page => per_page}.merge(opts))
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,69 @@
1
+ # encoding: UTF-8
2
+ module MongoMapper
3
+ module Plugins
4
+ module Persistence
5
+ module ClassMethods
6
+ def connection(mongo_connection=nil)
7
+ assert_supported
8
+ if mongo_connection.nil?
9
+ @connection ||= MongoMapper.connection
10
+ else
11
+ @connection = mongo_connection
12
+ end
13
+ @connection
14
+ end
15
+
16
+ def set_database_name(name)
17
+ assert_supported
18
+ @database_name = name
19
+ end
20
+
21
+ def database_name
22
+ assert_supported
23
+ @database_name
24
+ end
25
+
26
+ def database
27
+ assert_supported
28
+ if database_name.nil?
29
+ MongoMapper.database
30
+ else
31
+ connection.db(database_name)
32
+ end
33
+ end
34
+
35
+ def set_collection_name(name)
36
+ assert_supported
37
+ @collection_name = name
38
+ end
39
+
40
+ def collection_name
41
+ assert_supported
42
+ @collection_name ||= self.to_s.tableize.gsub(/\//, '.')
43
+ end
44
+
45
+ def collection
46
+ assert_supported
47
+ database.collection(collection_name)
48
+ end
49
+
50
+ private
51
+ def assert_supported
52
+ if embeddable?
53
+ raise NotSupported.new('This is not supported for embeddable documents at this time.')
54
+ end
55
+ end
56
+ end
57
+
58
+ module InstanceMethods
59
+ def collection
60
+ _root_document.class.collection
61
+ end
62
+
63
+ def database
64
+ _root_document.class.database
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,53 @@
1
+ # encoding: UTF-8
2
+ require 'set'
3
+
4
+ module MongoMapper
5
+ module Plugins
6
+ module Protected
7
+ module ClassMethods
8
+ def attr_protected(*attrs)
9
+ raise AccessibleOrProtected.new(name) if try(:accessible_attributes?)
10
+ self.write_inheritable_attribute(:attr_protected, Set.new(attrs) + (protected_attributes || []))
11
+ end
12
+
13
+ def protected_attributes
14
+ self.read_inheritable_attribute(:attr_protected)
15
+ end
16
+
17
+ def protected_attributes?
18
+ !protected_attributes.nil?
19
+ end
20
+
21
+ def key(*args)
22
+ key = super
23
+ attr_protected key.name.to_sym if key.options[:protected]
24
+ key
25
+ end
26
+ end
27
+
28
+ module InstanceMethods
29
+ def assign(attrs={})
30
+ super(filter_protected_attrs(attrs))
31
+ end
32
+
33
+ def update_attributes(attrs={})
34
+ super(filter_protected_attrs(attrs))
35
+ end
36
+
37
+ def update_attributes!(attrs={})
38
+ super(filter_protected_attrs(attrs))
39
+ end
40
+
41
+ def protected_attributes
42
+ self.class.protected_attributes
43
+ end
44
+
45
+ protected
46
+ def filter_protected_attrs(attrs)
47
+ return attrs if protected_attributes.blank? || attrs.blank?
48
+ attrs.dup.delete_if { |key, val| protected_attributes.include?(key.to_sym) }
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,176 @@
1
+ # encoding: UTF-8
2
+ require 'mongo_mapper/plugins/querying/decorator'
3
+ require 'mongo_mapper/plugins/querying/plucky_methods'
4
+
5
+ module MongoMapper
6
+ module Plugins
7
+ module Querying
8
+ module ClassMethods
9
+ include PluckyMethods
10
+
11
+ def find_each(opts={})
12
+ super(opts).each { |doc| yield load(doc) }
13
+ end
14
+
15
+ def find_by_id(id)
16
+ find_one(:_id => id)
17
+ end
18
+
19
+ def first_or_create(args)
20
+ first(args) || create(args.reject { |key, value| !key?(key) })
21
+ end
22
+
23
+ def first_or_new(args)
24
+ first(args) || new(args.reject { |key, value| !key?(key) })
25
+ end
26
+
27
+ def create(*docs)
28
+ initialize_each(*docs) { |doc| doc.save }
29
+ end
30
+
31
+ def create!(*docs)
32
+ initialize_each(*docs) { |doc| doc.save! }
33
+ end
34
+
35
+ def update(*args)
36
+ if args.length == 1
37
+ update_multiple(args[0])
38
+ else
39
+ id, attributes = args
40
+ update_single(id, attributes)
41
+ end
42
+ end
43
+
44
+ def delete(*ids)
45
+ query(:_id => ids.flatten).remove
46
+ end
47
+
48
+ def delete_all(options={})
49
+ query(options).remove
50
+ end
51
+
52
+ def destroy(*ids)
53
+ find_some!(ids.flatten).each(&:destroy)
54
+ end
55
+
56
+ def destroy_all(options={})
57
+ find_each(options) { |document| document.destroy }
58
+ end
59
+
60
+ # @api private for now
61
+ def query(options={})
62
+ Plucky::Query.new(collection).tap do |query|
63
+ query.extend(Decorator)
64
+ query.object_ids(object_id_keys)
65
+ query.update(options)
66
+ query.model(self)
67
+ end
68
+ end
69
+
70
+ # @api private for now
71
+ def criteria_hash(criteria={})
72
+ Plucky::CriteriaHash.new(criteria, :object_ids => object_id_keys)
73
+ end
74
+
75
+ private
76
+ def find_some(ids, options={})
77
+ query = query(options).update(:_id => ids.flatten.compact.uniq)
78
+ find_many(query.to_hash).compact
79
+ end
80
+
81
+ def find_some!(ids, options={})
82
+ ids = ids.flatten.compact.uniq
83
+ docs = find_some(ids, options)
84
+
85
+ if ids.size != docs.size
86
+ raise DocumentNotFound, "Couldn't find all of the ids (#{ids.to_sentence}). Found #{docs.size}, but was expecting #{ids.size}"
87
+ end
88
+
89
+ docs
90
+ end
91
+
92
+ # All query methods that load documents pass through find_one or find_many
93
+ def find_one(options={})
94
+ query(options).first
95
+ end
96
+
97
+ # All query methods that load documents pass through find_one or find_many
98
+ def find_many(options)
99
+ query(options).all
100
+ end
101
+
102
+ def initialize_each(*docs)
103
+ instances = []
104
+ docs = [{}] if docs.blank?
105
+ docs.flatten.each do |attrs|
106
+ doc = new(attrs)
107
+ yield(doc)
108
+ instances << doc
109
+ end
110
+ instances.size == 1 ? instances[0] : instances
111
+ end
112
+
113
+ def update_single(id, attrs)
114
+ if id.blank? || attrs.blank? || !attrs.is_a?(Hash)
115
+ raise ArgumentError, "Updating a single document requires an id and a hash of attributes"
116
+ end
117
+
118
+ find(id).tap do |doc|
119
+ doc.update_attributes(attrs)
120
+ end
121
+ end
122
+
123
+ def update_multiple(docs)
124
+ unless docs.is_a?(Hash)
125
+ raise ArgumentError, "Updating multiple documents takes 1 argument and it must be hash"
126
+ end
127
+
128
+ instances = []
129
+ docs.each_pair { |id, attrs| instances << update(id, attrs) }
130
+ instances
131
+ end
132
+ end
133
+
134
+ module InstanceMethods
135
+ def save(options={})
136
+ options.assert_valid_keys(:validate, :safe)
137
+ options.reverse_merge!(:validate => true)
138
+ !options[:validate] || valid? ? create_or_update(options) : false
139
+ end
140
+
141
+ def save!(options={})
142
+ options.assert_valid_keys(:safe)
143
+ save(options) || raise(DocumentNotValid.new(self))
144
+ end
145
+
146
+ def destroy
147
+ delete
148
+ end
149
+
150
+ def delete
151
+ @_destroyed = true
152
+ self.class.delete(id) unless new?
153
+ end
154
+
155
+ private
156
+ def create_or_update(options={})
157
+ result = new? ? create(options) : update(options)
158
+ result != false
159
+ end
160
+
161
+ def create(options={})
162
+ save_to_collection(options)
163
+ end
164
+
165
+ def update(options={})
166
+ save_to_collection(options)
167
+ end
168
+
169
+ def save_to_collection(options={})
170
+ @_new = false
171
+ collection.save(to_mongo, :safe => options[:safe])
172
+ end
173
+ end
174
+ end
175
+ end
176
+ end
@@ -0,0 +1,46 @@
1
+ # encoding: UTF-8
2
+ module MongoMapper
3
+ module Plugins
4
+ module Querying
5
+ module Decorator
6
+ include DynamicQuerying::ClassMethods
7
+
8
+ def model(model=nil)
9
+ return @model if model.nil?
10
+ @model = model
11
+ self
12
+ end
13
+
14
+ def find!(*ids)
15
+ raise DocumentNotFound, "Couldn't find without an ID" if ids.size == 0
16
+
17
+ find(*ids).tap do |result|
18
+ if result.nil? || ids.size != Array(result).size
19
+ raise DocumentNotFound, "Couldn't find all of the ids (#{ids.join(',')}). Found #{Array(result).size}, but was expecting #{ids.size}"
20
+ end
21
+ end
22
+ end
23
+
24
+ def all(opts={})
25
+ super.map { |doc| model.load(doc) }
26
+ end
27
+
28
+ def first(opts={})
29
+ model.load(super)
30
+ end
31
+
32
+ def last(opts={})
33
+ model.load(super)
34
+ end
35
+
36
+ private
37
+ def method_missing(method, *args, &block)
38
+ return super unless model.respond_to?(method)
39
+ result = model.send(method, *args, &block)
40
+ return super unless result.is_a?(Plucky::Query)
41
+ merge(result)
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,15 @@
1
+ # encoding: UTF-8
2
+ require 'forwardable'
3
+
4
+ module MongoMapper
5
+ module Plugins
6
+ module Querying
7
+ module PluckyMethods
8
+ extend Forwardable
9
+ def_delegators :query, :where, :fields, :limit, :skip, :sort,
10
+ :count, :last, :first, :all, :paginate,
11
+ :find, :find!, :exists?, :exist?, :find_each
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,58 @@
1
+ # encoding: UTF-8
2
+ module MongoMapper
3
+ module Plugins
4
+ module Rails
5
+ def self.configure(model)
6
+ model.extend ActiveModel::Naming if defined?(ActiveModel)
7
+ end
8
+
9
+ module InstanceMethods
10
+ def to_param
11
+ id.to_s if persisted?
12
+ end
13
+
14
+ def to_model
15
+ self
16
+ end
17
+
18
+ def to_key
19
+ [id] if persisted?
20
+ end
21
+
22
+ def new_record?
23
+ new?
24
+ end
25
+
26
+ def read_attribute(name)
27
+ self[name]
28
+ end
29
+
30
+ def read_attribute_before_typecast(name)
31
+ read_key_before_typecast(name)
32
+ end
33
+
34
+ def write_attribute(name, value)
35
+ self[name] = value
36
+ end
37
+ end
38
+
39
+ module ClassMethods
40
+ def has_one(*args)
41
+ one(*args)
42
+ end
43
+
44
+ def has_many(*args)
45
+ many(*args)
46
+ end
47
+
48
+ def column_names
49
+ keys.keys
50
+ end
51
+
52
+ def human_name
53
+ self.name.demodulize.titleize
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,28 @@
1
+ # encoding: UTF-8
2
+ module MongoMapper
3
+ module Plugins
4
+ module Safe
5
+ module ClassMethods
6
+ def inherited(subclass)
7
+ super
8
+ subclass.safe if safe?
9
+ end
10
+
11
+ def safe
12
+ @safe = true
13
+ end
14
+
15
+ def safe?
16
+ @safe == true
17
+ end
18
+ end
19
+
20
+ module InstanceMethods
21
+ def save_to_collection(options={})
22
+ options[:safe] = self.class.safe? unless options.key?(:safe)
23
+ super
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end