drogus-mongo_mapper 0.6.10

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 (91) hide show
  1. data/.gitignore +10 -0
  2. data/LICENSE +20 -0
  3. data/README.rdoc +29 -0
  4. data/Rakefile +55 -0
  5. data/VERSION +1 -0
  6. data/bin/mmconsole +60 -0
  7. data/lib/mongo_mapper.rb +131 -0
  8. data/lib/mongo_mapper/document.rb +417 -0
  9. data/lib/mongo_mapper/embedded_document.rb +55 -0
  10. data/lib/mongo_mapper/finder_options.rb +127 -0
  11. data/lib/mongo_mapper/plugins.rb +30 -0
  12. data/lib/mongo_mapper/plugins/associations.rb +104 -0
  13. data/lib/mongo_mapper/plugins/associations/base.rb +121 -0
  14. data/lib/mongo_mapper/plugins/associations/belongs_to_polymorphic_proxy.rb +30 -0
  15. data/lib/mongo_mapper/plugins/associations/belongs_to_proxy.rb +25 -0
  16. data/lib/mongo_mapper/plugins/associations/collection.rb +21 -0
  17. data/lib/mongo_mapper/plugins/associations/embedded_collection.rb +50 -0
  18. data/lib/mongo_mapper/plugins/associations/in_array_proxy.rb +139 -0
  19. data/lib/mongo_mapper/plugins/associations/many_documents_as_proxy.rb +28 -0
  20. data/lib/mongo_mapper/plugins/associations/many_documents_proxy.rb +117 -0
  21. data/lib/mongo_mapper/plugins/associations/many_embedded_polymorphic_proxy.rb +31 -0
  22. data/lib/mongo_mapper/plugins/associations/many_embedded_proxy.rb +23 -0
  23. data/lib/mongo_mapper/plugins/associations/many_polymorphic_proxy.rb +13 -0
  24. data/lib/mongo_mapper/plugins/associations/one_proxy.rb +68 -0
  25. data/lib/mongo_mapper/plugins/associations/proxy.rb +118 -0
  26. data/lib/mongo_mapper/plugins/callbacks.rb +134 -0
  27. data/lib/mongo_mapper/plugins/clone.rb +13 -0
  28. data/lib/mongo_mapper/plugins/descendants.rb +16 -0
  29. data/lib/mongo_mapper/plugins/dirty.rb +119 -0
  30. data/lib/mongo_mapper/plugins/equality.rb +23 -0
  31. data/lib/mongo_mapper/plugins/identity_map.rb +122 -0
  32. data/lib/mongo_mapper/plugins/inspect.rb +14 -0
  33. data/lib/mongo_mapper/plugins/keys.rb +324 -0
  34. data/lib/mongo_mapper/plugins/logger.rb +17 -0
  35. data/lib/mongo_mapper/plugins/pagination.rb +85 -0
  36. data/lib/mongo_mapper/plugins/protected.rb +45 -0
  37. data/lib/mongo_mapper/plugins/rails.rb +45 -0
  38. data/lib/mongo_mapper/plugins/serialization.rb +105 -0
  39. data/lib/mongo_mapper/plugins/validations.rb +57 -0
  40. data/lib/mongo_mapper/support.rb +217 -0
  41. data/lib/mongo_mapper/support/descendant_appends.rb +46 -0
  42. data/lib/mongo_mapper/support/find.rb +77 -0
  43. data/mongo_mapper.gemspec +195 -0
  44. data/performance/read_write.rb +52 -0
  45. data/specs.watchr +51 -0
  46. data/test/NOTE_ON_TESTING +1 -0
  47. data/test/functional/associations/test_belongs_to_polymorphic_proxy.rb +63 -0
  48. data/test/functional/associations/test_belongs_to_proxy.rb +101 -0
  49. data/test/functional/associations/test_in_array_proxy.rb +309 -0
  50. data/test/functional/associations/test_many_documents_as_proxy.rb +229 -0
  51. data/test/functional/associations/test_many_documents_proxy.rb +431 -0
  52. data/test/functional/associations/test_many_embedded_polymorphic_proxy.rb +176 -0
  53. data/test/functional/associations/test_many_embedded_proxy.rb +256 -0
  54. data/test/functional/associations/test_many_polymorphic_proxy.rb +302 -0
  55. data/test/functional/associations/test_one_proxy.rb +161 -0
  56. data/test/functional/test_associations.rb +44 -0
  57. data/test/functional/test_binary.rb +27 -0
  58. data/test/functional/test_callbacks.rb +81 -0
  59. data/test/functional/test_dirty.rb +163 -0
  60. data/test/functional/test_document.rb +1264 -0
  61. data/test/functional/test_embedded_document.rb +125 -0
  62. data/test/functional/test_identity_map.rb +508 -0
  63. data/test/functional/test_logger.rb +20 -0
  64. data/test/functional/test_modifiers.rb +252 -0
  65. data/test/functional/test_pagination.rb +93 -0
  66. data/test/functional/test_protected.rb +155 -0
  67. data/test/functional/test_string_id_compatibility.rb +67 -0
  68. data/test/functional/test_validations.rb +329 -0
  69. data/test/models.rb +232 -0
  70. data/test/support/custom_matchers.rb +55 -0
  71. data/test/support/timing.rb +16 -0
  72. data/test/test_helper.rb +60 -0
  73. data/test/unit/associations/test_base.rb +207 -0
  74. data/test/unit/associations/test_proxy.rb +105 -0
  75. data/test/unit/serializers/test_json_serializer.rb +189 -0
  76. data/test/unit/test_descendant_appends.rb +71 -0
  77. data/test/unit/test_document.rb +231 -0
  78. data/test/unit/test_dynamic_finder.rb +123 -0
  79. data/test/unit/test_embedded_document.rb +663 -0
  80. data/test/unit/test_finder_options.rb +329 -0
  81. data/test/unit/test_keys.rb +169 -0
  82. data/test/unit/test_mongo_mapper.rb +65 -0
  83. data/test/unit/test_pagination.rb +127 -0
  84. data/test/unit/test_plugins.rb +50 -0
  85. data/test/unit/test_rails.rb +123 -0
  86. data/test/unit/test_rails_compatibility.rb +52 -0
  87. data/test/unit/test_serialization.rb +51 -0
  88. data/test/unit/test_support.rb +354 -0
  89. data/test/unit/test_time_zones.rb +39 -0
  90. data/test/unit/test_validations.rb +544 -0
  91. metadata +290 -0
@@ -0,0 +1,68 @@
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[foreign_key] = owner.id
41
+ doc.save if doc.new?
42
+ loaded
43
+ @target = doc
44
+ end
45
+ end
46
+
47
+ protected
48
+ def find_target
49
+ target_class.first(reflection.finder_options.merge(foreign_key => owner.id))
50
+ end
51
+
52
+ def instantiate_target(instantiator, attrs={})
53
+ @target = target_class.send(instantiator, attrs.update(foreign_key => owner.id))
54
+ loaded
55
+ @target
56
+ end
57
+
58
+ def target_class
59
+ @target_class ||= options[:class] || (options[:class_name] || reflection.name.to_s.camelize).constantize
60
+ end
61
+
62
+ def foreign_key
63
+ options[:foreign_key] || owner.class.name.foreign_key
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,118 @@
1
+ module MongoMapper
2
+ module Plugins
3
+ module Associations
4
+ class Proxy
5
+ alias :proxy_respond_to? :respond_to?
6
+ alias :proxy_extend :extend
7
+
8
+ instance_methods.each { |m| undef_method m unless m =~ /(^__|^nil\?$|^send$|proxy_|^object_id$)/ }
9
+
10
+ attr_reader :owner, :reflection, :target
11
+
12
+ alias :proxy_owner :owner
13
+ alias :proxy_target :target
14
+ alias :proxy_reflection :reflection
15
+
16
+ delegate :klass, :to => :proxy_reflection
17
+ delegate :options, :to => :proxy_reflection
18
+ delegate :collection, :to => :klass
19
+
20
+ def initialize(owner, reflection)
21
+ @owner, @reflection, @loaded = owner, reflection, false
22
+ Array(reflection.options[:extend]).each { |ext| proxy_extend(ext) }
23
+ reset
24
+ end
25
+
26
+ def inspect
27
+ load_target
28
+ target.inspect
29
+ end
30
+
31
+ def loaded?
32
+ @loaded
33
+ end
34
+
35
+ def loaded
36
+ @loaded = true
37
+ end
38
+
39
+ def nil?
40
+ load_target
41
+ target.nil?
42
+ end
43
+
44
+ def blank?
45
+ load_target
46
+ target.blank?
47
+ end
48
+
49
+ def present?
50
+ load_target
51
+ target.present?
52
+ end
53
+
54
+ def reload
55
+ reset
56
+ load_target
57
+ self unless target.nil?
58
+ end
59
+
60
+ def replace(v)
61
+ raise NotImplementedError
62
+ end
63
+
64
+ def reset
65
+ @loaded = false
66
+ @target = nil
67
+ end
68
+
69
+ def respond_to?(*args)
70
+ proxy_respond_to?(*args) || (load_target && target.respond_to?(*args))
71
+ end
72
+
73
+ def send(method, *args)
74
+ if proxy_respond_to?(method)
75
+ super
76
+ else
77
+ load_target
78
+ target.send(method, *args)
79
+ end
80
+ end
81
+
82
+ def ===(other)
83
+ load_target
84
+ other === target
85
+ end
86
+
87
+ protected
88
+ def method_missing(method, *args, &block)
89
+ if load_target
90
+ if block_given?
91
+ target.send(method, *args) { |*block_args| block.call(*block_args) }
92
+ else
93
+ target.send(method, *args)
94
+ end
95
+ end
96
+ end
97
+
98
+ def load_target
99
+ @target = find_target unless loaded?
100
+ loaded
101
+ @target
102
+ rescue MongoMapper::DocumentNotFound
103
+ reset
104
+ end
105
+
106
+ def find_target
107
+ raise NotImplementedError
108
+ end
109
+
110
+ def flatten_deeper(array)
111
+ array.collect do |element|
112
+ (element.respond_to?(:flatten) && !element.is_a?(Hash)) ? element.flatten : element
113
+ end.flatten
114
+ end
115
+ end
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,134 @@
1
+ module MongoMapper
2
+ module Plugins
3
+ if defined?(ActiveModel)
4
+ # Rails 3 stuff
5
+ module Callbacks
6
+ def self.configure(model)
7
+ model.class_eval do
8
+ extend ActiveModel::Callbacks
9
+ define_model_callbacks :create, :save, :update, :destroy, :validation,
10
+ :validation_on_create, :validation_on_update
11
+ end
12
+ end
13
+
14
+ module InstanceMethods
15
+ def valid?
16
+ action = new? ? 'create' : 'update'
17
+ result = nil
18
+
19
+ _run_validation_callbacks do
20
+ self.send("_run_validation_on_#{action}_callbacks") do
21
+ result = super
22
+ end
23
+ end
24
+
25
+ result
26
+ end
27
+
28
+ def destroy
29
+ result = nil
30
+
31
+ _run_destroy_callbacks do
32
+ result = super
33
+ end
34
+
35
+ result
36
+ end
37
+
38
+ private
39
+ def create_or_update(*args)
40
+ result = nil
41
+
42
+ _run_save_callbacks do
43
+ result = super
44
+ end
45
+
46
+ result
47
+ end
48
+
49
+ def create(*args)
50
+ result = nil
51
+
52
+ _run_create_callbacks do
53
+ result = super
54
+ end
55
+
56
+ result
57
+ end
58
+
59
+ def update(*args)
60
+ result = nil
61
+
62
+ _run_update_callbacks do
63
+ result = super
64
+ end
65
+
66
+ result
67
+ end
68
+ end
69
+ end
70
+ else
71
+ module Callbacks
72
+ def self.configure(model)
73
+ model.class_eval do
74
+ include ActiveSupport::Callbacks
75
+
76
+ define_callbacks(
77
+ :before_save, :after_save,
78
+ :before_create, :after_create,
79
+ :before_update, :after_update,
80
+ :before_validation, :after_validation,
81
+ :before_validation_on_create, :after_validation_on_create,
82
+ :before_validation_on_update, :after_validation_on_update,
83
+ :before_destroy, :after_destroy
84
+ )
85
+ end
86
+ end
87
+
88
+ module InstanceMethods
89
+ def valid?
90
+ action = new? ? 'create' : 'update'
91
+
92
+ run_callbacks(:before_validation)
93
+ run_callbacks("before_validation_on_#{action}".to_sym)
94
+ result = super
95
+ run_callbacks("after_validation_on_#{action}".to_sym)
96
+ run_callbacks(:after_validation)
97
+
98
+ result
99
+ end
100
+
101
+ def destroy
102
+ run_callbacks(:before_destroy)
103
+ result = super
104
+ run_callbacks(:after_destroy)
105
+ result
106
+ end
107
+
108
+ private
109
+ def create_or_update(*args)
110
+ run_callbacks(:before_save)
111
+ if result = super
112
+ run_callbacks(:after_save)
113
+ end
114
+ result
115
+ end
116
+
117
+ def create(*args)
118
+ run_callbacks(:before_create)
119
+ result = super
120
+ run_callbacks(:after_create)
121
+ result
122
+ end
123
+
124
+ def update(*args)
125
+ run_callbacks(:before_update)
126
+ result = super
127
+ run_callbacks(:after_update)
128
+ result
129
+ end
130
+ end
131
+ end
132
+ end
133
+ end
134
+ end
@@ -0,0 +1,13 @@
1
+ module MongoMapper
2
+ module Plugins
3
+ module Clone
4
+ module InstanceMethods
5
+ def clone
6
+ clone_attributes = self.attributes
7
+ clone_attributes.delete("_id")
8
+ self.class.new(clone_attributes)
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,16 @@
1
+ module MongoMapper
2
+ module Plugins
3
+ module Descendants
4
+ module ClassMethods
5
+ def inherited(descendant)
6
+ (@descendants ||= []) << descendant
7
+ super
8
+ end
9
+
10
+ def descendants
11
+ @descendants
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,119 @@
1
+ module MongoMapper
2
+ module Plugins
3
+ module Dirty
4
+ module InstanceMethods
5
+ def method_missing(method, *args, &block)
6
+ if method.to_s =~ /(_changed\?|_change|_will_change!|_was)$/
7
+ method_suffix = $1
8
+ key = method.to_s.gsub(method_suffix, '')
9
+
10
+ if key_names.include?(key)
11
+ case method_suffix
12
+ when '_changed?'
13
+ key_changed?(key)
14
+ when '_change'
15
+ key_change(key)
16
+ when '_will_change!'
17
+ key_will_change!(key)
18
+ when '_was'
19
+ key_was(key)
20
+ end
21
+ else
22
+ super
23
+ end
24
+ else
25
+ super
26
+ end
27
+ end
28
+
29
+ def changed?
30
+ !changed_keys.empty?
31
+ end
32
+
33
+ def changed
34
+ changed_keys.keys
35
+ end
36
+
37
+ def changes
38
+ changed.inject({}) { |h, key| h[key] = key_change(key); h }
39
+ end
40
+
41
+ def initialize(*args)
42
+ super
43
+ changed_keys.clear if args.first.blank? || !new?
44
+ end
45
+
46
+ def save(*args)
47
+ if status = super
48
+ changed_keys.clear
49
+ end
50
+ status
51
+ end
52
+
53
+ def save!(*args)
54
+ status = super
55
+ changed_keys.clear
56
+ status
57
+ end
58
+
59
+ def reload(*args)
60
+ document = super
61
+ changed_keys.clear
62
+ document
63
+ end
64
+
65
+ private
66
+ def clone_key_value(key)
67
+ value = read_key(key)
68
+ value.duplicable? ? value.clone : value
69
+ rescue TypeError, NoMethodError
70
+ value
71
+ end
72
+
73
+ def changed_keys
74
+ @changed_keys ||= {}
75
+ end
76
+
77
+ def key_changed?(key)
78
+ changed_keys.include?(key)
79
+ end
80
+
81
+ def key_change(key)
82
+ [changed_keys[key], __send__(key)] if key_changed?(key)
83
+ end
84
+
85
+ def key_was(key)
86
+ key_changed?(key) ? changed_keys[key] : __send__(key)
87
+ end
88
+
89
+ def key_will_change!(key)
90
+ changed_keys[key] = clone_key_value(key)
91
+ end
92
+
93
+ def write_key(key, value)
94
+ key = key.to_s
95
+
96
+ if changed_keys.include?(key)
97
+ old = changed_keys[key]
98
+ changed_keys.delete(key) unless value_changed?(key, old, value)
99
+ else
100
+ old = clone_key_value(key)
101
+ changed_keys[key] = old if value_changed?(key, old, value)
102
+ end
103
+
104
+ super(key, value)
105
+ end
106
+
107
+ def value_changed?(key_name, old, value)
108
+ key = keys[key_name]
109
+
110
+ if key.number? && value.blank?
111
+ value = nil
112
+ end
113
+
114
+ old != value
115
+ end
116
+ end
117
+ end
118
+ end
119
+ end