mongo_mapper_ign 0.7.4

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 (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,70 @@
1
+ module MongoMapper
2
+ module EmbeddedDocument
3
+ extend Support::DescendantAppends
4
+
5
+ def self.included(model)
6
+ model.class_eval do
7
+ include InstanceMethods
8
+ extend ClassMethods
9
+ extend Plugins
10
+
11
+ plugin Plugins::Associations
12
+ plugin Plugins::Clone
13
+ plugin Plugins::Descendants
14
+ plugin Plugins::Equality
15
+ plugin Plugins::Inspect
16
+ plugin Plugins::Keys
17
+ plugin Plugins::Logger
18
+ plugin Plugins::Persistence
19
+ plugin Plugins::Protected
20
+ plugin Plugins::Rails
21
+ plugin Plugins::Serialization
22
+ plugin Plugins::Validations
23
+ plugin Plugins::Callbacks
24
+
25
+ attr_reader :_root_document, :_parent_document
26
+ end
27
+
28
+ super
29
+ end
30
+
31
+ module ClassMethods
32
+ def embeddable?
33
+ true
34
+ end
35
+
36
+ def embedded_in(owner_name)
37
+ define_method(owner_name) { _parent_document }
38
+ end
39
+ end
40
+
41
+ module InstanceMethods
42
+ def destroyed?
43
+ !!_root_document.try(:destroyed?)
44
+ end
45
+
46
+ def new?
47
+ _root_document.try(:new?) || @new
48
+ end
49
+
50
+ def save(options={})
51
+ if result = _root_document.try(:save, options)
52
+ @new = false
53
+ end
54
+ result
55
+ end
56
+
57
+ def save!(options={})
58
+ if result = _root_document.try(:save!, options)
59
+ @new = false
60
+ end
61
+ result
62
+ end
63
+
64
+ def _parent_document=(value)
65
+ @_root_document = value._root_document
66
+ @_parent_document = value
67
+ end
68
+ end # InstanceMethods
69
+ end # EmbeddedDocument
70
+ end # MongoMapper
@@ -0,0 +1,35 @@
1
+ module MongoMapper
2
+ module Plugins
3
+ def plugins
4
+ @plugins ||= []
5
+ end
6
+
7
+ def plugin(mod)
8
+ extend mod::ClassMethods if mod.const_defined?(:ClassMethods)
9
+ include mod::InstanceMethods if mod.const_defined?(:InstanceMethods)
10
+ mod.configure(self) if mod.respond_to?(:configure)
11
+ plugins << mod
12
+ end
13
+
14
+ autoload :Callbacks, 'mongo_mapper/plugins/callbacks'
15
+ autoload :Clone, 'mongo_mapper/plugins/clone'
16
+ autoload :Descendants, 'mongo_mapper/plugins/descendants'
17
+ autoload :Dirty, 'mongo_mapper/plugins/dirty'
18
+ autoload :Equality, 'mongo_mapper/plugins/equality'
19
+ autoload :IdentityMap, 'mongo_mapper/plugins/identity_map'
20
+ autoload :Inspect, 'mongo_mapper/plugins/inspect'
21
+ autoload :Keys, 'mongo_mapper/plugins/keys'
22
+ autoload :Logger, 'mongo_mapper/plugins/logger'
23
+ autoload :Modifiers, 'mongo_mapper/plugins/modifiers'
24
+ autoload :Persistence, 'mongo_mapper/plugins/persistence'
25
+ autoload :Protected, 'mongo_mapper/plugins/protected'
26
+ autoload :Rails, 'mongo_mapper/plugins/rails'
27
+ autoload :Serialization, 'mongo_mapper/plugins/serialization'
28
+ autoload :Timestamps, 'mongo_mapper/plugins/timestamps'
29
+ autoload :Userstamps, 'mongo_mapper/plugins/userstamps'
30
+ autoload :Validations, 'mongo_mapper/plugins/validations'
31
+ end
32
+ end
33
+
34
+ require 'mongo_mapper/plugins/associations'
35
+ require 'mongo_mapper/plugins/pagination'
@@ -0,0 +1,114 @@
1
+ module MongoMapper
2
+ module Plugins
3
+ module Associations
4
+ module ClassMethods
5
+ def belongs_to(association_id, options={}, &extension)
6
+ create_association(:belongs_to, association_id, options, &extension)
7
+ end
8
+
9
+ def many(association_id, options={}, &extension)
10
+ create_association(:many, association_id, options, &extension)
11
+ end
12
+
13
+ def one(association_id, options={}, &extension)
14
+ create_association(:one, association_id, options, &extension)
15
+ end
16
+
17
+ def associations
18
+ @associations ||= HashWithIndifferentAccess.new
19
+ end
20
+
21
+ def associations=(hash)
22
+ @associations = hash
23
+ end
24
+
25
+ def inherited(subclass)
26
+ subclass.associations = associations.dup
27
+ super
28
+ end
29
+
30
+ private
31
+ def create_association(type, name, options, &extension)
32
+ association = Associations::Base.new(type, name, options, &extension)
33
+ associations[association.name] = association
34
+
35
+ define_method(association.name) do
36
+ get_proxy(association)
37
+ end
38
+
39
+ define_method("#{association.name}=") do |value|
40
+ get_proxy(association).replace(value)
41
+ value
42
+ end
43
+
44
+ if association.one? || association.belongs_to?
45
+ define_method("#{association.name}?") do
46
+ get_proxy(association).present?
47
+ end
48
+ end
49
+
50
+ if association.options[:dependent] && association.many? && !association.embeddable?
51
+ after_destroy do |doc|
52
+ case association.options[:dependent]
53
+ when :destroy
54
+ doc.get_proxy(association).destroy_all
55
+ when :delete_all
56
+ doc.get_proxy(association).delete_all
57
+ when :nullify
58
+ doc.get_proxy(association).nullify
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+
65
+ module InstanceMethods
66
+ def associations
67
+ self.class.associations
68
+ end
69
+
70
+ # @api private?
71
+ def embedded_associations
72
+ associations.select do |name, association|
73
+ association.embeddable?
74
+ end.map do |name, association|
75
+ association
76
+ end
77
+ end
78
+
79
+ def get_proxy(association)
80
+ unless proxy = self.instance_variable_get(association.ivar)
81
+ proxy = association.proxy_class.new(self, association)
82
+ self.instance_variable_set(association.ivar, proxy)
83
+ end
84
+
85
+ proxy
86
+ end
87
+
88
+ def save_to_collection(options = {})
89
+ super
90
+ associations.each do |association_name, association|
91
+ proxy = get_proxy(association)
92
+ proxy.save_to_collection(options) if proxy.proxy_respond_to?(:save_to_collection)
93
+ end
94
+ end
95
+ end
96
+
97
+ autoload :Base, 'mongo_mapper/plugins/associations/base'
98
+ autoload :Collection, 'mongo_mapper/plugins/associations/collection'
99
+ autoload :EmbeddedCollection, 'mongo_mapper/plugins/associations/embedded_collection'
100
+ autoload :ManyDocumentsProxy, 'mongo_mapper/plugins/associations/many_documents_proxy'
101
+ autoload :BelongsToProxy, 'mongo_mapper/plugins/associations/belongs_to_proxy'
102
+ autoload :BelongsToPolymorphicProxy, 'mongo_mapper/plugins/associations/belongs_to_polymorphic_proxy'
103
+ autoload :ManyPolymorphicProxy, 'mongo_mapper/plugins/associations/many_polymorphic_proxy'
104
+ autoload :ManyEmbeddedProxy, 'mongo_mapper/plugins/associations/many_embedded_proxy'
105
+ autoload :ManyEmbeddedPolymorphicProxy, 'mongo_mapper/plugins/associations/many_embedded_polymorphic_proxy'
106
+ autoload :ManyDocumentsAsProxy, 'mongo_mapper/plugins/associations/many_documents_as_proxy'
107
+ autoload :OneProxy, 'mongo_mapper/plugins/associations/one_proxy'
108
+ autoload :OneEmbeddedProxy, 'mongo_mapper/plugins/associations/one_embedded_proxy'
109
+ autoload :InArrayProxy, 'mongo_mapper/plugins/associations/in_array_proxy'
110
+ end
111
+ end
112
+ end
113
+
114
+ require 'mongo_mapper/plugins/associations/proxy'
@@ -0,0 +1,123 @@
1
+ module MongoMapper
2
+ module Plugins
3
+ module Associations
4
+ class Base
5
+ attr_reader :type, :name, :options, :query_options
6
+
7
+ # Options that should not be considered MongoDB query options/criteria
8
+ AssociationOptions = [:as, :class, :class_name, :dependent, :extend, :foreign_key, :in, :polymorphic]
9
+
10
+ def initialize(type, name, options={}, &extension)
11
+ @type, @name, @options, @query_options, @original_options = type, name, {}, {}, options
12
+ options.symbolize_keys!
13
+ options[:extend] = modularized_extensions(extension, options[:extend])
14
+ separate_options_and_conditions
15
+ end
16
+
17
+ def class_name
18
+ return @class_name if defined?(@class_name)
19
+
20
+ @class_name =
21
+ if cn = options[:class_name]
22
+ cn
23
+ elsif many?
24
+ name.to_s.singularize.camelize
25
+ else
26
+ name.to_s.camelize
27
+ end
28
+ end
29
+
30
+ def klass
31
+ @klass ||= options[:class] || class_name.constantize
32
+ end
33
+
34
+ def many?
35
+ @type == :many
36
+ end
37
+
38
+ def belongs_to?
39
+ @type == :belongs_to
40
+ end
41
+
42
+ def one?
43
+ @type == :one
44
+ end
45
+
46
+ def polymorphic?
47
+ !!@options[:polymorphic]
48
+ end
49
+
50
+ def as?
51
+ !!@options[:as]
52
+ end
53
+
54
+ def in_array?
55
+ !!@options[:in]
56
+ end
57
+
58
+ def embeddable?
59
+ (one? || many?) && klass.embeddable?
60
+ end
61
+
62
+ def type_key_name
63
+ many? ? '_type' : "#{as}_type"
64
+ end
65
+
66
+ def as
67
+ @options[:as] || self.name
68
+ end
69
+
70
+ def foreign_key
71
+ @options[:foreign_key] || "#{name}_id"
72
+ end
73
+
74
+ def ivar
75
+ @ivar ||= "@_#{name}"
76
+ end
77
+
78
+ # hate this, need to revisit
79
+ def proxy_class
80
+ return @proxy_class if defined?(@proxy_class)
81
+
82
+ @proxy_class =
83
+ if many?
84
+ if klass.embeddable?
85
+ polymorphic? ? ManyEmbeddedPolymorphicProxy : ManyEmbeddedProxy
86
+ else
87
+ if polymorphic?
88
+ ManyPolymorphicProxy
89
+ elsif as?
90
+ ManyDocumentsAsProxy
91
+ elsif in_array?
92
+ InArrayProxy
93
+ else
94
+ ManyDocumentsProxy
95
+ end
96
+ end
97
+ elsif one?
98
+ klass.embeddable? ? OneEmbeddedProxy : OneProxy
99
+ else
100
+ polymorphic? ? BelongsToPolymorphicProxy : BelongsToProxy
101
+ end
102
+ end
103
+
104
+ private
105
+ def separate_options_and_conditions
106
+ @original_options.each_pair do |key, value|
107
+ if AssociationOptions.include?(key)
108
+ @options[key] = value
109
+ else
110
+ @query_options[key] = value
111
+ end
112
+ end
113
+ end
114
+
115
+ def modularized_extensions(*extensions)
116
+ extensions.flatten.compact.map do |extension|
117
+ Proc === extension ? Module.new(&extension) : extension
118
+ end
119
+ end
120
+ end
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,30 @@
1
+ module MongoMapper
2
+ module Plugins
3
+ module Associations
4
+ class BelongsToPolymorphicProxy < Proxy
5
+ undef_method :object_id
6
+
7
+ def replace(doc)
8
+ if doc
9
+ doc.save if doc.new?
10
+ id, type = doc.id, doc.class.name
11
+ end
12
+
13
+ owner[association.foreign_key] = id
14
+ owner[association.type_key_name] = type
15
+ reset
16
+ end
17
+
18
+ protected
19
+ def find_target
20
+ return nil if association_class.nil? || owner[association.foreign_key].nil?
21
+ association_class.find_by_id(owner[association.foreign_key])
22
+ end
23
+
24
+ def association_class
25
+ proxy_owner[association.type_key_name] ? proxy_owner[association.type_key_name].constantize : nil
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,25 @@
1
+ module MongoMapper
2
+ module Plugins
3
+ module Associations
4
+ class BelongsToProxy < Proxy
5
+ undef_method :object_id
6
+
7
+ def replace(doc)
8
+ if doc
9
+ doc.save if doc.new?
10
+ id = doc.id
11
+ end
12
+
13
+ owner[association.foreign_key] = id
14
+ reset
15
+ end
16
+
17
+ protected
18
+ def find_target
19
+ return nil if owner[association.foreign_key].nil?
20
+ klass.find_by_id(owner[association.foreign_key])
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,21 @@
1
+ module MongoMapper
2
+ module Plugins
3
+ module Associations
4
+ class Collection < Proxy
5
+ def to_ary
6
+ load_target
7
+ if target.is_a?(Array)
8
+ target.to_ary
9
+ else
10
+ Array(target)
11
+ end
12
+ end
13
+
14
+ def reset
15
+ super
16
+ target = []
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,39 @@
1
+ module MongoMapper
2
+ module Plugins
3
+ module Associations
4
+ class EmbeddedCollection < Collection
5
+ def build(attributes={})
6
+ doc = klass.new(attributes)
7
+ assign_references(doc)
8
+ self << doc
9
+ doc
10
+ end
11
+
12
+ def find(id)
13
+ load_target
14
+ target.detect { |item| item.id.to_s == id || item.id == id }
15
+ end
16
+
17
+ def count
18
+ load_target
19
+ target.size
20
+ end
21
+
22
+ def <<(*docs)
23
+ load_target
24
+ docs.each do |doc|
25
+ assign_references(doc)
26
+ target << doc
27
+ end
28
+ end
29
+ alias_method :push, :<<
30
+ alias_method :concat, :<<
31
+
32
+ private
33
+ def assign_references(*docs)
34
+ docs.each { |doc| doc._parent_document = owner }
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end