mongo_mapper_ign 0.7.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (105) hide show
  1. data/.gitignore +10 -0
  2. data/LICENSE +20 -0
  3. data/README.rdoc +35 -0
  4. data/Rakefile +37 -0
  5. data/bin/mmconsole +60 -0
  6. data/lib/mongo_mapper.rb +116 -0
  7. data/lib/mongo_mapper/document.rb +313 -0
  8. data/lib/mongo_mapper/embedded_document.rb +70 -0
  9. data/lib/mongo_mapper/plugins.rb +35 -0
  10. data/lib/mongo_mapper/plugins/associations.rb +114 -0
  11. data/lib/mongo_mapper/plugins/associations/base.rb +123 -0
  12. data/lib/mongo_mapper/plugins/associations/belongs_to_polymorphic_proxy.rb +30 -0
  13. data/lib/mongo_mapper/plugins/associations/belongs_to_proxy.rb +25 -0
  14. data/lib/mongo_mapper/plugins/associations/collection.rb +21 -0
  15. data/lib/mongo_mapper/plugins/associations/embedded_collection.rb +39 -0
  16. data/lib/mongo_mapper/plugins/associations/in_array_proxy.rb +144 -0
  17. data/lib/mongo_mapper/plugins/associations/many_documents_as_proxy.rb +28 -0
  18. data/lib/mongo_mapper/plugins/associations/many_documents_proxy.rb +129 -0
  19. data/lib/mongo_mapper/plugins/associations/many_embedded_polymorphic_proxy.rb +31 -0
  20. data/lib/mongo_mapper/plugins/associations/many_embedded_proxy.rb +23 -0
  21. data/lib/mongo_mapper/plugins/associations/many_polymorphic_proxy.rb +13 -0
  22. data/lib/mongo_mapper/plugins/associations/one_embedded_proxy.rb +41 -0
  23. data/lib/mongo_mapper/plugins/associations/one_proxy.rb +69 -0
  24. data/lib/mongo_mapper/plugins/associations/proxy.rb +124 -0
  25. data/lib/mongo_mapper/plugins/callbacks.rb +240 -0
  26. data/lib/mongo_mapper/plugins/clone.rb +13 -0
  27. data/lib/mongo_mapper/plugins/descendants.rb +16 -0
  28. data/lib/mongo_mapper/plugins/dirty.rb +119 -0
  29. data/lib/mongo_mapper/plugins/equality.rb +23 -0
  30. data/lib/mongo_mapper/plugins/identity_map.rb +122 -0
  31. data/lib/mongo_mapper/plugins/inspect.rb +14 -0
  32. data/lib/mongo_mapper/plugins/keys.rb +345 -0
  33. data/lib/mongo_mapper/plugins/logger.rb +17 -0
  34. data/lib/mongo_mapper/plugins/modifiers.rb +107 -0
  35. data/lib/mongo_mapper/plugins/pagination.rb +24 -0
  36. data/lib/mongo_mapper/plugins/pagination/proxy.rb +72 -0
  37. data/lib/mongo_mapper/plugins/persistence.rb +68 -0
  38. data/lib/mongo_mapper/plugins/protected.rb +45 -0
  39. data/lib/mongo_mapper/plugins/rails.rb +57 -0
  40. data/lib/mongo_mapper/plugins/serialization.rb +91 -0
  41. data/lib/mongo_mapper/plugins/serialization/array.rb +56 -0
  42. data/lib/mongo_mapper/plugins/serialization/xml_serializer.rb +240 -0
  43. data/lib/mongo_mapper/plugins/timestamps.rb +21 -0
  44. data/lib/mongo_mapper/plugins/userstamps.rb +14 -0
  45. data/lib/mongo_mapper/plugins/validations.rb +46 -0
  46. data/lib/mongo_mapper/query.rb +143 -0
  47. data/lib/mongo_mapper/support.rb +218 -0
  48. data/lib/mongo_mapper/support/descendant_appends.rb +46 -0
  49. data/lib/mongo_mapper/support/find.rb +77 -0
  50. data/lib/mongo_mapper/version.rb +3 -0
  51. data/mongo_mapper.gemspec +214 -0
  52. data/mongo_mapper_ign.gemspec +217 -0
  53. data/performance/read_write.rb +52 -0
  54. data/specs.watchr +51 -0
  55. data/test/NOTE_ON_TESTING +1 -0
  56. data/test/active_model_lint_test.rb +13 -0
  57. data/test/functional/associations/test_belongs_to_polymorphic_proxy.rb +63 -0
  58. data/test/functional/associations/test_belongs_to_proxy.rb +101 -0
  59. data/test/functional/associations/test_in_array_proxy.rb +325 -0
  60. data/test/functional/associations/test_many_documents_as_proxy.rb +229 -0
  61. data/test/functional/associations/test_many_documents_proxy.rb +536 -0
  62. data/test/functional/associations/test_many_embedded_polymorphic_proxy.rb +176 -0
  63. data/test/functional/associations/test_many_embedded_proxy.rb +256 -0
  64. data/test/functional/associations/test_many_polymorphic_proxy.rb +302 -0
  65. data/test/functional/associations/test_one_embedded_proxy.rb +68 -0
  66. data/test/functional/associations/test_one_proxy.rb +196 -0
  67. data/test/functional/test_associations.rb +44 -0
  68. data/test/functional/test_binary.rb +27 -0
  69. data/test/functional/test_callbacks.rb +151 -0
  70. data/test/functional/test_dirty.rb +163 -0
  71. data/test/functional/test_document.rb +1219 -0
  72. data/test/functional/test_embedded_document.rb +210 -0
  73. data/test/functional/test_identity_map.rb +507 -0
  74. data/test/functional/test_indexing.rb +44 -0
  75. data/test/functional/test_logger.rb +20 -0
  76. data/test/functional/test_modifiers.rb +394 -0
  77. data/test/functional/test_pagination.rb +93 -0
  78. data/test/functional/test_protected.rb +163 -0
  79. data/test/functional/test_string_id_compatibility.rb +67 -0
  80. data/test/functional/test_timestamps.rb +64 -0
  81. data/test/functional/test_userstamps.rb +28 -0
  82. data/test/functional/test_validations.rb +342 -0
  83. data/test/models.rb +227 -0
  84. data/test/support/custom_matchers.rb +37 -0
  85. data/test/support/timing.rb +16 -0
  86. data/test/test_helper.rb +64 -0
  87. data/test/unit/associations/test_base.rb +212 -0
  88. data/test/unit/associations/test_proxy.rb +105 -0
  89. data/test/unit/serializers/test_json_serializer.rb +202 -0
  90. data/test/unit/test_descendant_appends.rb +71 -0
  91. data/test/unit/test_document.rb +225 -0
  92. data/test/unit/test_dynamic_finder.rb +123 -0
  93. data/test/unit/test_embedded_document.rb +657 -0
  94. data/test/unit/test_keys.rb +185 -0
  95. data/test/unit/test_mongo_mapper.rb +118 -0
  96. data/test/unit/test_pagination.rb +160 -0
  97. data/test/unit/test_plugins.rb +50 -0
  98. data/test/unit/test_query.rb +374 -0
  99. data/test/unit/test_rails.rb +181 -0
  100. data/test/unit/test_rails_compatibility.rb +52 -0
  101. data/test/unit/test_serialization.rb +51 -0
  102. data/test/unit/test_support.rb +382 -0
  103. data/test/unit/test_time_zones.rb +39 -0
  104. data/test/unit/test_validations.rb +544 -0
  105. metadata +327 -0
@@ -0,0 +1,144 @@
1
+ module MongoMapper
2
+ module Plugins
3
+ module Associations
4
+ class InArrayProxy < Collection
5
+ include Support::Find
6
+
7
+ def find(*args)
8
+ options = args.extract_options!
9
+
10
+ case args.first
11
+ when :first
12
+ first(options)
13
+ when :last
14
+ last(options)
15
+ when :all
16
+ all(options)
17
+ else
18
+ klass.find(*scoped_ids(args) << scoped_options(options))
19
+ end
20
+ end
21
+
22
+ def find!(*args)
23
+ options = args.extract_options!
24
+
25
+ case args.first
26
+ when :first
27
+ first(options)
28
+ when :last
29
+ last(options)
30
+ when :all
31
+ all(options)
32
+ else
33
+ klass.find!(*scoped_ids(args) << scoped_options(options))
34
+ end
35
+ end
36
+
37
+ def paginate(options)
38
+ klass.paginate(scoped_options(options))
39
+ end
40
+
41
+ def all(options={})
42
+ klass.all(scoped_options(options))
43
+ end
44
+
45
+ def first(options={})
46
+ klass.first(scoped_options(options))
47
+ end
48
+
49
+ def last(options={})
50
+ klass.last(scoped_options(options))
51
+ end
52
+
53
+ def count(options={})
54
+ options.blank? ? ids.size : klass.count(scoped_options(options))
55
+ end
56
+
57
+ def destroy_all(options={})
58
+ all(options).each do |doc|
59
+ ids.delete(doc.id)
60
+ doc.destroy
61
+ end
62
+ reset
63
+ end
64
+
65
+ def delete_all(options={})
66
+ docs = all(options.merge(:select => ['_id']))
67
+ docs.each { |doc| ids.delete(doc.id) }
68
+ klass.delete(docs.map(&:id))
69
+ reset
70
+ end
71
+
72
+ def nullify
73
+ replace([])
74
+ reset
75
+ end
76
+
77
+ def create(attrs={})
78
+ doc = klass.create(attrs)
79
+ unless doc.new?
80
+ ids << doc.id
81
+ owner.save
82
+ reset
83
+ end
84
+ doc
85
+ end
86
+
87
+ def create!(attrs={})
88
+ doc = klass.create!(attrs)
89
+ unless doc.new?
90
+ ids << doc.id
91
+ owner.save
92
+ reset
93
+ end
94
+ doc
95
+ end
96
+
97
+ def <<(*docs)
98
+ flatten_deeper(docs).each do |doc|
99
+ doc.save if doc.new?
100
+ unless ids.include?(doc.id)
101
+ ids << doc.id
102
+ end
103
+ end
104
+ reset
105
+ end
106
+ alias_method :push, :<<
107
+ alias_method :concat, :<<
108
+
109
+ def replace(docs)
110
+ doc_ids = docs.map do |doc|
111
+ doc.save if doc.new?
112
+ doc.id
113
+ end
114
+ ids.replace(doc_ids.uniq)
115
+ reset
116
+ end
117
+
118
+ private
119
+ def scoped_conditions
120
+ {:_id => ids}
121
+ end
122
+
123
+ def scoped_options(options)
124
+ association.query_options.merge(options).merge(scoped_conditions)
125
+ end
126
+
127
+ def scoped_ids(args)
128
+ args.flatten.select do |id|
129
+ id = ObjectId.to_mongo(id) if klass.using_object_id?
130
+ ids.include?(id)
131
+ end
132
+ end
133
+
134
+ def find_target
135
+ ids.blank? ? [] : all
136
+ end
137
+
138
+ def ids
139
+ owner[options[:in]]
140
+ end
141
+ end
142
+ end
143
+ end
144
+ end
@@ -0,0 +1,28 @@
1
+ module MongoMapper
2
+ module Plugins
3
+ module Associations
4
+ class ManyDocumentsAsProxy < ManyDocumentsProxy
5
+ protected
6
+ def scoped_conditions
7
+ {type_key_name => owner.class.name, id_key_name => owner.id}
8
+ end
9
+
10
+ def apply_scope(doc)
11
+ ensure_owner_saved
12
+ doc[type_key_name] = owner.class.name
13
+ doc[id_key_name] = owner.id
14
+ doc
15
+ end
16
+
17
+ private
18
+ def type_key_name
19
+ "#{options[:as]}_type"
20
+ end
21
+
22
+ def id_key_name
23
+ "#{options[:as]}_id"
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,129 @@
1
+ module MongoMapper
2
+ module Plugins
3
+ module Associations
4
+ class ManyDocumentsProxy < Collection
5
+ include Support::Find
6
+
7
+ def find(*args)
8
+ options = args.extract_options!
9
+ klass.find(*args << scoped_options(options))
10
+ end
11
+
12
+ def find!(*args)
13
+ options = args.extract_options!
14
+ klass.find!(*args << scoped_options(options))
15
+ end
16
+
17
+ def paginate(options)
18
+ klass.paginate(scoped_options(options))
19
+ end
20
+
21
+ def all(options={})
22
+ klass.all(scoped_options(options))
23
+ end
24
+
25
+ def first(options={})
26
+ klass.first(scoped_options(options))
27
+ end
28
+
29
+ def last(options={})
30
+ klass.last(scoped_options(options))
31
+ end
32
+
33
+ def count(options={})
34
+ klass.count(scoped_options(options))
35
+ end
36
+
37
+ def replace(docs)
38
+ load_target
39
+ target.map(&:destroy)
40
+ docs.each { |doc| prepare(doc).save }
41
+ reset
42
+ end
43
+
44
+ def <<(*docs)
45
+ ensure_owner_saved
46
+ flatten_deeper(docs).each { |doc| prepare(doc).save }
47
+ reset
48
+ end
49
+ alias_method :push, :<<
50
+ alias_method :concat, :<<
51
+
52
+ def build(attrs={})
53
+ doc = klass.new(attrs)
54
+ apply_scope(doc)
55
+ @target ||= [] unless loaded?
56
+ @target << doc
57
+ doc
58
+ end
59
+
60
+ def create(attrs={})
61
+ doc = klass.new(attrs)
62
+ apply_scope(doc).save
63
+ reset
64
+ doc
65
+ end
66
+
67
+ def create!(attrs={})
68
+ doc = klass.new(attrs)
69
+ apply_scope(doc).save!
70
+ reset
71
+ doc
72
+ end
73
+
74
+ def destroy_all(options={})
75
+ all(options).map(&:destroy)
76
+ reset
77
+ end
78
+
79
+ def delete_all(options={})
80
+ klass.delete_all(options.merge(scoped_conditions))
81
+ reset
82
+ end
83
+
84
+ def nullify
85
+ criteria = Query.new(klass, scoped_conditions).criteria
86
+ all(criteria).each do |doc|
87
+ doc.update_attributes(self.foreign_key => nil)
88
+ end
89
+ reset
90
+ end
91
+
92
+ def save_to_collection(options = {})
93
+ @target.each { |doc| doc.save(options) } if @target
94
+ end
95
+
96
+ protected
97
+ def scoped_conditions
98
+ {self.foreign_key => owner.id}
99
+ end
100
+
101
+ def scoped_options(options)
102
+ association.query_options.merge(options).merge(scoped_conditions)
103
+ end
104
+
105
+ def find_target
106
+ all
107
+ end
108
+
109
+ def ensure_owner_saved
110
+ owner.save if owner.new?
111
+ end
112
+
113
+ def prepare(doc)
114
+ klass === doc ? apply_scope(doc) : build(doc)
115
+ end
116
+
117
+ def apply_scope(doc)
118
+ ensure_owner_saved
119
+ doc[foreign_key] = owner.id
120
+ doc
121
+ end
122
+
123
+ def foreign_key
124
+ options[:foreign_key] || owner.class.name.to_s.underscore.gsub("/", "_") + "_id"
125
+ end
126
+ end
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,31 @@
1
+ module MongoMapper
2
+ module Plugins
3
+ module Associations
4
+ class ManyEmbeddedPolymorphicProxy < EmbeddedCollection
5
+ def replace(values)
6
+ @_values = values.map do |v|
7
+ v.respond_to?(:attributes) ? v.attributes.merge(association.type_key_name => v.class.name) : v
8
+ end
9
+ reset
10
+ end
11
+
12
+ protected
13
+ def find_target
14
+ (@_values || []).map do |hash|
15
+ child = polymorphic_class(hash).load(hash)
16
+ assign_references(child)
17
+ child
18
+ end
19
+ end
20
+
21
+ def polymorphic_class(doc)
22
+ if class_name = doc[association.type_key_name]
23
+ class_name.constantize
24
+ else
25
+ klass
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,23 @@
1
+ module MongoMapper
2
+ module Plugins
3
+ module Associations
4
+ class ManyEmbeddedProxy < EmbeddedCollection
5
+ def replace(values)
6
+ @_values = values.map do |v|
7
+ v.respond_to?(:attributes) ? v.attributes : v
8
+ end
9
+ reset
10
+ end
11
+
12
+ private
13
+ def find_target
14
+ (@_values || []).map do |attrs|
15
+ klass.load(attrs).tap do |child|
16
+ assign_references(child)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,13 @@
1
+ module MongoMapper
2
+ module Plugins
3
+ module Associations
4
+ class ManyPolymorphicProxy < ManyDocumentsProxy
5
+ private
6
+ def apply_scope(doc)
7
+ doc[association.type_key_name] = doc.class.name
8
+ super
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,41 @@
1
+ module MongoMapper
2
+ module Plugins
3
+ module Associations
4
+ class OneEmbeddedProxy < Proxy
5
+ undef_method :object_id
6
+
7
+ def build(attributes={})
8
+ @target = klass.new(attributes)
9
+ assign_references(@target)
10
+ loaded
11
+ @target
12
+ end
13
+
14
+ def replace(doc)
15
+ if doc.respond_to?(:attributes)
16
+ @target = klass.load(doc.attributes)
17
+ else
18
+ @target = klass.load(doc)
19
+ end
20
+ assign_references(@target)
21
+ loaded
22
+ @target
23
+ end
24
+
25
+ protected
26
+
27
+ def find_target
28
+ if @value
29
+ klass.load(@value).tap do |child|
30
+ assign_references(child)
31
+ end
32
+ end
33
+ end
34
+
35
+ def assign_references(doc)
36
+ doc._parent_document = owner
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,69 @@
1
+ module MongoMapper
2
+ module Plugins
3
+ module Associations
4
+ class OneProxy < Proxy
5
+ undef_method :object_id
6
+
7
+ def build(attrs={})
8
+ instantiate_target(:new, attrs)
9
+ end
10
+
11
+ def create(attrs={})
12
+ instantiate_target(:create, attrs)
13
+ end
14
+
15
+ def create!(attrs={})
16
+ instantiate_target(:create!, attrs)
17
+ end
18
+
19
+ def replace(doc)
20
+ load_target
21
+
22
+ if !target.nil? && target != doc
23
+ if options[:dependent] && !target.new?
24
+ case options[:dependent]
25
+ when :delete
26
+ target.delete
27
+ when :destroy
28
+ target.destroy
29
+ when :nullify
30
+ target[foreign_key] = nil
31
+ target.save
32
+ end
33
+ end
34
+ end
35
+
36
+ reset
37
+
38
+ unless doc.nil?
39
+ owner.save if owner.new?
40
+ doc = klass.new(doc) unless klass === doc
41
+ doc[foreign_key] = owner.id
42
+ doc.save if doc.new?
43
+ loaded
44
+ @target = doc
45
+ end
46
+ end
47
+
48
+ protected
49
+ def find_target
50
+ target_class.first(association.query_options.merge(foreign_key => owner.id))
51
+ end
52
+
53
+ def instantiate_target(instantiator, attrs={})
54
+ @target = target_class.send(instantiator, attrs.update(foreign_key => owner.id))
55
+ loaded
56
+ @target
57
+ end
58
+
59
+ def target_class
60
+ @target_class ||= options[:class] || (options[:class_name] || association.name.to_s.camelize).constantize
61
+ end
62
+
63
+ def foreign_key
64
+ options[:foreign_key] || owner.class.name.foreign_key
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end