mongo_mapper_ign 0.7.7 → 0.7.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. data/LICENSE +20 -20
  2. data/README.rdoc +34 -34
  3. data/bin/mmconsole +60 -60
  4. data/lib/mongo_mapper.rb +123 -123
  5. data/lib/mongo_mapper/document.rb +292 -292
  6. data/lib/mongo_mapper/embedded_document.rb +71 -71
  7. data/lib/mongo_mapper/plugins.rb +36 -36
  8. data/lib/mongo_mapper/plugins/associations.rb +115 -115
  9. data/lib/mongo_mapper/plugins/associations/base.rb +124 -124
  10. data/lib/mongo_mapper/plugins/associations/belongs_to_polymorphic_proxy.rb +31 -31
  11. data/lib/mongo_mapper/plugins/associations/belongs_to_proxy.rb +26 -26
  12. data/lib/mongo_mapper/plugins/associations/collection.rb +21 -21
  13. data/lib/mongo_mapper/plugins/associations/embedded_collection.rb +39 -39
  14. data/lib/mongo_mapper/plugins/associations/in_array_proxy.rb +160 -144
  15. data/lib/mongo_mapper/plugins/associations/many_documents_as_proxy.rb +29 -29
  16. data/lib/mongo_mapper/plugins/associations/many_documents_proxy.rb +130 -130
  17. data/lib/mongo_mapper/plugins/associations/many_embedded_polymorphic_proxy.rb +32 -32
  18. data/lib/mongo_mapper/plugins/associations/many_embedded_proxy.rb +24 -24
  19. data/lib/mongo_mapper/plugins/associations/many_polymorphic_proxy.rb +14 -14
  20. data/lib/mongo_mapper/plugins/associations/one_embedded_proxy.rb +42 -42
  21. data/lib/mongo_mapper/plugins/associations/one_proxy.rb +70 -70
  22. data/lib/mongo_mapper/plugins/associations/proxy.rb +125 -125
  23. data/lib/mongo_mapper/plugins/callbacks.rb +241 -241
  24. data/lib/mongo_mapper/plugins/clone.rb +13 -13
  25. data/lib/mongo_mapper/plugins/descendants.rb +16 -16
  26. data/lib/mongo_mapper/plugins/dirty.rb +119 -119
  27. data/lib/mongo_mapper/plugins/equality.rb +23 -23
  28. data/lib/mongo_mapper/plugins/identity_map.rb +123 -123
  29. data/lib/mongo_mapper/plugins/inspect.rb +14 -14
  30. data/lib/mongo_mapper/plugins/keys.rb +322 -322
  31. data/lib/mongo_mapper/plugins/keys/key.rb +53 -53
  32. data/lib/mongo_mapper/plugins/logger.rb +17 -17
  33. data/lib/mongo_mapper/plugins/modifiers.rb +111 -111
  34. data/lib/mongo_mapper/plugins/pagination.rb +24 -24
  35. data/lib/mongo_mapper/plugins/pagination/proxy.rb +72 -72
  36. data/lib/mongo_mapper/plugins/persistence.rb +96 -96
  37. data/lib/mongo_mapper/plugins/protected.rb +46 -46
  38. data/lib/mongo_mapper/plugins/rails.rb +57 -57
  39. data/lib/mongo_mapper/plugins/serialization.rb +92 -92
  40. data/lib/mongo_mapper/plugins/serialization/array.rb +56 -56
  41. data/lib/mongo_mapper/plugins/serialization/xml_serializer.rb +239 -239
  42. data/lib/mongo_mapper/plugins/timestamps.rb +21 -21
  43. data/lib/mongo_mapper/plugins/userstamps.rb +14 -14
  44. data/lib/mongo_mapper/plugins/validations.rb +46 -46
  45. data/lib/mongo_mapper/query.rb +28 -28
  46. data/lib/mongo_mapper/support.rb +197 -197
  47. data/lib/mongo_mapper/support/descendant_appends.rb +46 -46
  48. data/lib/mongo_mapper/support/find.rb +77 -77
  49. data/lib/mongo_mapper/version.rb +3 -3
  50. metadata +4 -25
@@ -1,56 +1,56 @@
1
- # Credit: http://github.com/tsxn26/array-xml_serialization
2
-
3
- # Extends the XML serialization support in activesupport to allow for
4
- # arrays containing strings, symbols, and integers.
5
-
6
- # Forces elements in arrays to be output using to_xml on each element if the
7
- # element responds to to_xml. If an element does not respond to to_xml then a
8
- # nested XML tag is created with the element's to_s value and the singlarized name
9
- # of the array as the tag name.
10
-
11
- require 'rubygems'
12
- require 'activesupport'
13
- require 'builder'
14
-
15
- class Array
16
- def to_xml(options = {})
17
- #raise "Not all elements respond to to_xml" unless all? { |e| e.respond_to? :to_xml }
18
- require 'builder' unless defined?(Builder)
19
-
20
- options = options.dup
21
- options[:root] ||= all? { |e| e.is_a?(first.class) && first.class.to_s != "Hash" } ? first.class.to_s.underscore.pluralize : "records"
22
- options[:children] ||= options[:root].singularize
23
- options[:indent] ||= 2
24
- options[:builder] ||= Builder::XmlMarkup.new(:indent => options[:indent])
25
-
26
- root = options.delete(:root).to_s
27
- children = options.delete(:children)
28
-
29
- if !options.has_key?(:dasherize) || options[:dasherize]
30
- root = root.dasherize
31
- end
32
-
33
- options[:builder].instruct! unless options.delete(:skip_instruct)
34
-
35
- opts = options.merge({ :root => children })
36
-
37
- root = root.pluralize
38
-
39
- xml = options[:builder]
40
- if empty?
41
- xml.tag!(root, options[:skip_types] ? {} : {:type => "array"})
42
- else
43
- xml.tag!(root, options[:skip_types] ? {} : {:type => "array"}) do
44
- yield xml if block_given?
45
- each do |e|
46
- if e.respond_to? :to_xml
47
- e.to_xml(opts.merge({ :skip_instruct => true }))
48
- else
49
- xml.tag!(root.singularize, e.to_s)
50
- end
51
- end
52
- end
53
- end
54
- end
55
- end
56
-
1
+ # Credit: http://github.com/tsxn26/array-xml_serialization
2
+
3
+ # Extends the XML serialization support in activesupport to allow for
4
+ # arrays containing strings, symbols, and integers.
5
+
6
+ # Forces elements in arrays to be output using to_xml on each element if the
7
+ # element responds to to_xml. If an element does not respond to to_xml then a
8
+ # nested XML tag is created with the element's to_s value and the singlarized name
9
+ # of the array as the tag name.
10
+
11
+ require 'rubygems'
12
+ require 'activesupport'
13
+ require 'builder'
14
+
15
+ class Array
16
+ def to_xml(options = {})
17
+ #raise "Not all elements respond to to_xml" unless all? { |e| e.respond_to? :to_xml }
18
+ require 'builder' unless defined?(Builder)
19
+
20
+ options = options.dup
21
+ options[:root] ||= all? { |e| e.is_a?(first.class) && first.class.to_s != "Hash" } ? first.class.to_s.underscore.pluralize : "records"
22
+ options[:children] ||= options[:root].singularize
23
+ options[:indent] ||= 2
24
+ options[:builder] ||= Builder::XmlMarkup.new(:indent => options[:indent])
25
+
26
+ root = options.delete(:root).to_s
27
+ children = options.delete(:children)
28
+
29
+ if !options.has_key?(:dasherize) || options[:dasherize]
30
+ root = root.dasherize
31
+ end
32
+
33
+ options[:builder].instruct! unless options.delete(:skip_instruct)
34
+
35
+ opts = options.merge({ :root => children })
36
+
37
+ root = root.pluralize
38
+
39
+ xml = options[:builder]
40
+ if empty?
41
+ xml.tag!(root, options[:skip_types] ? {} : {:type => "array"})
42
+ else
43
+ xml.tag!(root, options[:skip_types] ? {} : {:type => "array"}) do
44
+ yield xml if block_given?
45
+ each do |e|
46
+ if e.respond_to? :to_xml
47
+ e.to_xml(opts.merge({ :skip_instruct => true }))
48
+ else
49
+ xml.tag!(root.singularize, e.to_s)
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+
@@ -1,240 +1,240 @@
1
- module MongoMapper
2
- module Plugins
3
- module Serialization
4
-
5
- class XmlSerializer #:nodoc:
6
- attr_reader :options
7
-
8
- def initialize(record, options = {})
9
- @record, @options = record, options.dup
10
- end
11
-
12
- def builder
13
- @builder ||= begin
14
- options[:indent] ||= 2
15
- builder = options[:builder] ||= Builder::XmlMarkup.new(:indent => options[:indent])
16
-
17
- unless options[:skip_instruct]
18
- builder.instruct!
19
- options[:skip_instruct] = true
20
- end
21
-
22
- builder
23
- end
24
- end
25
-
26
- def root
27
- root = (options[:root] || @record.class.to_s.underscore).to_s
28
- dasherize? ? root.dasherize : root
29
- end
30
-
31
- def dasherize?
32
- !options.has_key?(:dasherize) || options[:dasherize]
33
- end
34
-
35
-
36
- # To replicate the behavior in ActiveRecord#attributes,
37
- # :except takes precedence over :only. If :only is not set
38
- # for a N level model but is set for the N+1 level models,
39
- # then because :except is set to a default value, the second
40
- # level model can have both :except and :only set. So if
41
- # :only is set, always delete :except.
42
- def serializable_attributes
43
- #attribute_names = @record.attributes.keys # This includes all attributes including associations
44
- attribute_names = @record.class.keys.keys # This includes just keys
45
- idex = attribute_names.index("_id")
46
- attribute_names[idex] = "id" if idex
47
-
48
- if options[:only]
49
- options.delete(:except)
50
- attribute_names = attribute_names & Array(options[:only]).collect { |n| n.to_s }
51
- else
52
- options[:except] = Array(options[:except])
53
- attribute_names = attribute_names - options[:except].collect { |n| n.to_s }
54
- end
55
-
56
- attribute_names.collect { |name| Attribute.new(name, @record) }
57
- end
58
-
59
- def serializable_method_attributes
60
- Array(options[:methods]).collect { |name| MethodAttribute.new(name.to_s, @record) }
61
- end
62
-
63
- def add_attributes
64
- (serializable_attributes + serializable_method_attributes).each do |attribute|
65
- add_tag(attribute)
66
- end
67
- end
68
-
69
- def add_includes
70
- if include_associations = options.delete(:include)
71
- root_only_or_except = { :except => options[:except],
72
- :only => options[:only] }
73
-
74
- include_has_options = include_associations.is_a?(Hash)
75
-
76
- for association in include_has_options ? include_associations.keys : Array(include_associations)
77
- association_options = include_has_options ? include_associations[association] : root_only_or_except
78
-
79
- opts = options.merge(association_options)
80
-
81
- case @record.class.associations[association].type
82
- when :many, :has_and_belongs_to_many
83
- records = @record.send(association).to_a
84
- unless records.empty?
85
- tag = association.to_s
86
- tag = tag.dasherize if dasherize?
87
-
88
- builder.tag!(tag) do
89
- records.each { |r| r.to_xml(opts.merge(:root=>r.class.to_s.underscore)) }
90
- end
91
- end
92
- when :has_one, :belongs_to
93
- if record = @record.send(association)
94
- record.to_xml(opts.merge(:root => association))
95
- end
96
- end
97
- end
98
-
99
- options[:include] = include_associations
100
- end
101
- end
102
-
103
- def add_procs
104
- if procs = options.delete(:procs)
105
- [ *procs ].each do |proc|
106
- proc.call(options)
107
- end
108
- end
109
- end
110
-
111
-
112
- def add_tag(attribute)
113
- if attribute.type == :array
114
- builder.tag!(
115
- dasherize? ? attribute.name.dasherize.pluralize : attribute.name.pluralize,
116
- attribute.decorations(!options[:skip_types])
117
- ) do |x|
118
- attribute.value.each do |val|
119
- if val.respond_to? :to_xml
120
- x << val.to_xml(:skip_instruct => true, :root => attribute.name.dasherize.singularize)
121
- else
122
- x.tag!(
123
- dasherize? ? attribute.name.dasherize.singularize : attribute.name.singularize,
124
- val.to_s
125
- )
126
- end
127
- end
128
- end
129
- else
130
- builder.tag!(
131
- dasherize? ? attribute.name.dasherize : attribute.name,
132
- attribute.value.to_s,
133
- attribute.decorations(!options[:skip_types])
134
- )
135
- end
136
- end
137
-
138
- def serialize
139
- args = [root]
140
- if options[:namespace]
141
- args << {:xmlns=>options[:namespace]}
142
- end
143
-
144
- builder.tag!(*args) do
145
- add_attributes
146
- add_includes
147
- add_procs
148
- yield builder if block_given?
149
- end
150
- end
151
-
152
- alias_method :to_s, :serialize
153
-
154
- class Attribute #:nodoc:
155
- attr_reader :name, :value, :type
156
-
157
- def initialize(name, record)
158
- @name, @record = name, record
159
-
160
- @type = compute_type
161
- @value = compute_value
162
- end
163
-
164
- # There is a significant speed improvement if the value
165
- # does not need to be escaped, as #tag! escapes all values
166
- # to ensure that valid XML is generated. For known binary
167
- # values, it is at least an order of magnitude faster to
168
- # Base64 encode binary values and directly put them in the
169
- # output XML than to pass the original value or the Base64
170
- # encoded value to the #tag! method. It definitely makes
171
- # no sense to Base64 encode the value and then give it to
172
- # #tag!, since that just adds additional overhead.
173
- def needs_encoding?
174
- ![ :binary, :date, :datetime, :boolean, :float, :integer ].include?(type)
175
- end
176
-
177
- def decorations(include_types = true)
178
- decorations = {}
179
-
180
- if type == :binary
181
- decorations[:encoding] = 'base64'
182
- end
183
-
184
- if include_types && type != :string
185
- decorations[:type] = type
186
- end
187
-
188
- decorations
189
- end
190
-
191
- protected
192
- def compute_type
193
- if name == "id"
194
- return :object_id
195
- end
196
-
197
- #type = @record.class.serialized_attributes.has_key?(name) ? :yaml : @record.class.columns_hash[name].type
198
- v = @record.class.keys[name]
199
- #puts "Value type is........... #{v.type.to_s} #{v.type.to_s.blank?}"
200
-
201
- #type = @record.send(name).class
202
-
203
- type = v.nil? ? :yaml : (v.type.to_s.blank? ? :key : v.type.to_s.underscore.to_sym)
204
-
205
- case type
206
- when :text
207
- :string
208
- when :time
209
- :datetime
210
- # when :array
211
- # :yaml
212
- else
213
- type
214
- end
215
- end
216
-
217
- def compute_value
218
- n = name == "id" ? "_id" : name
219
-
220
- value = @record.send(n)
221
-
222
- if formatter = Hash::XML_FORMATTING[type.to_s]
223
- value ? formatter.call(value) : nil
224
- else
225
- value
226
- end
227
- end
228
- end
229
-
230
- class MethodAttribute < Attribute #:nodoc:
231
- protected
232
- def compute_type
233
- Hash::XML_TYPE_NAMES[@record.send(name).class.name] || :string
234
- end
235
- end
236
- end
237
-
238
- end
239
- end
1
+ module MongoMapper
2
+ module Plugins
3
+ module Serialization
4
+
5
+ class XmlSerializer #:nodoc:
6
+ attr_reader :options
7
+
8
+ def initialize(record, options = {})
9
+ @record, @options = record, options.dup
10
+ end
11
+
12
+ def builder
13
+ @builder ||= begin
14
+ options[:indent] ||= 2
15
+ builder = options[:builder] ||= Builder::XmlMarkup.new(:indent => options[:indent])
16
+
17
+ unless options[:skip_instruct]
18
+ builder.instruct!
19
+ options[:skip_instruct] = true
20
+ end
21
+
22
+ builder
23
+ end
24
+ end
25
+
26
+ def root
27
+ root = (options[:root] || @record.class.to_s.underscore).to_s
28
+ dasherize? ? root.dasherize : root
29
+ end
30
+
31
+ def dasherize?
32
+ !options.has_key?(:dasherize) || options[:dasherize]
33
+ end
34
+
35
+
36
+ # To replicate the behavior in ActiveRecord#attributes,
37
+ # :except takes precedence over :only. If :only is not set
38
+ # for a N level model but is set for the N+1 level models,
39
+ # then because :except is set to a default value, the second
40
+ # level model can have both :except and :only set. So if
41
+ # :only is set, always delete :except.
42
+ def serializable_attributes
43
+ #attribute_names = @record.attributes.keys # This includes all attributes including associations
44
+ attribute_names = @record.class.keys.keys # This includes just keys
45
+ idex = attribute_names.index("_id")
46
+ attribute_names[idex] = "id" if idex
47
+
48
+ if options[:only]
49
+ options.delete(:except)
50
+ attribute_names = attribute_names & Array(options[:only]).collect { |n| n.to_s }
51
+ else
52
+ options[:except] = Array(options[:except])
53
+ attribute_names = attribute_names - options[:except].collect { |n| n.to_s }
54
+ end
55
+
56
+ attribute_names.collect { |name| Attribute.new(name, @record) }
57
+ end
58
+
59
+ def serializable_method_attributes
60
+ Array(options[:methods]).collect { |name| MethodAttribute.new(name.to_s, @record) }
61
+ end
62
+
63
+ def add_attributes
64
+ (serializable_attributes + serializable_method_attributes).each do |attribute|
65
+ add_tag(attribute)
66
+ end
67
+ end
68
+
69
+ def add_includes
70
+ if include_associations = options.delete(:include)
71
+ root_only_or_except = { :except => options[:except],
72
+ :only => options[:only] }
73
+
74
+ include_has_options = include_associations.is_a?(Hash)
75
+
76
+ for association in include_has_options ? include_associations.keys : Array(include_associations)
77
+ association_options = include_has_options ? include_associations[association] : root_only_or_except
78
+
79
+ opts = options.merge(association_options)
80
+
81
+ case @record.class.associations[association].type
82
+ when :many, :has_and_belongs_to_many
83
+ records = @record.send(association).to_a
84
+ unless records.empty?
85
+ tag = association.to_s
86
+ tag = tag.dasherize if dasherize?
87
+
88
+ builder.tag!(tag) do
89
+ records.each { |r| r.to_xml(opts.merge(:root=>r.class.to_s.underscore)) }
90
+ end
91
+ end
92
+ when :has_one, :belongs_to
93
+ if record = @record.send(association)
94
+ record.to_xml(opts.merge(:root => association))
95
+ end
96
+ end
97
+ end
98
+
99
+ options[:include] = include_associations
100
+ end
101
+ end
102
+
103
+ def add_procs
104
+ if procs = options.delete(:procs)
105
+ [ *procs ].each do |proc|
106
+ proc.call(options)
107
+ end
108
+ end
109
+ end
110
+
111
+
112
+ def add_tag(attribute)
113
+ if attribute.type == :array
114
+ builder.tag!(
115
+ dasherize? ? attribute.name.dasherize.pluralize : attribute.name.pluralize,
116
+ attribute.decorations(!options[:skip_types])
117
+ ) do |x|
118
+ attribute.value.each do |val|
119
+ if val.respond_to? :to_xml
120
+ x << val.to_xml(:skip_instruct => true, :root => attribute.name.dasherize.singularize)
121
+ else
122
+ x.tag!(
123
+ dasherize? ? attribute.name.dasherize.singularize : attribute.name.singularize,
124
+ val.to_s
125
+ )
126
+ end
127
+ end
128
+ end
129
+ else
130
+ builder.tag!(
131
+ dasherize? ? attribute.name.dasherize : attribute.name,
132
+ attribute.value.to_s,
133
+ attribute.decorations(!options[:skip_types])
134
+ )
135
+ end
136
+ end
137
+
138
+ def serialize
139
+ args = [root]
140
+ if options[:namespace]
141
+ args << {:xmlns=>options[:namespace]}
142
+ end
143
+
144
+ builder.tag!(*args) do
145
+ add_attributes
146
+ add_includes
147
+ add_procs
148
+ yield builder if block_given?
149
+ end
150
+ end
151
+
152
+ alias_method :to_s, :serialize
153
+
154
+ class Attribute #:nodoc:
155
+ attr_reader :name, :value, :type
156
+
157
+ def initialize(name, record)
158
+ @name, @record = name, record
159
+
160
+ @type = compute_type
161
+ @value = compute_value
162
+ end
163
+
164
+ # There is a significant speed improvement if the value
165
+ # does not need to be escaped, as #tag! escapes all values
166
+ # to ensure that valid XML is generated. For known binary
167
+ # values, it is at least an order of magnitude faster to
168
+ # Base64 encode binary values and directly put them in the
169
+ # output XML than to pass the original value or the Base64
170
+ # encoded value to the #tag! method. It definitely makes
171
+ # no sense to Base64 encode the value and then give it to
172
+ # #tag!, since that just adds additional overhead.
173
+ def needs_encoding?
174
+ ![ :binary, :date, :datetime, :boolean, :float, :integer ].include?(type)
175
+ end
176
+
177
+ def decorations(include_types = true)
178
+ decorations = {}
179
+
180
+ if type == :binary
181
+ decorations[:encoding] = 'base64'
182
+ end
183
+
184
+ if include_types && type != :string
185
+ decorations[:type] = type
186
+ end
187
+
188
+ decorations
189
+ end
190
+
191
+ protected
192
+ def compute_type
193
+ if name == "id"
194
+ return :object_id
195
+ end
196
+
197
+ #type = @record.class.serialized_attributes.has_key?(name) ? :yaml : @record.class.columns_hash[name].type
198
+ v = @record.class.keys[name]
199
+ #puts "Value type is........... #{v.type.to_s} #{v.type.to_s.blank?}"
200
+
201
+ #type = @record.send(name).class
202
+
203
+ type = v.nil? ? :yaml : (v.type.to_s.blank? ? :key : v.type.to_s.underscore.to_sym)
204
+
205
+ case type
206
+ when :text
207
+ :string
208
+ when :time
209
+ :datetime
210
+ # when :array
211
+ # :yaml
212
+ else
213
+ type
214
+ end
215
+ end
216
+
217
+ def compute_value
218
+ n = name == "id" ? "_id" : name
219
+
220
+ value = @record.send(n)
221
+
222
+ if formatter = Hash::XML_FORMATTING[type.to_s]
223
+ value ? formatter.call(value) : nil
224
+ else
225
+ value
226
+ end
227
+ end
228
+ end
229
+
230
+ class MethodAttribute < Attribute #:nodoc:
231
+ protected
232
+ def compute_type
233
+ Hash::XML_TYPE_NAMES[@record.send(name).class.name] || :string
234
+ end
235
+ end
236
+ end
237
+
238
+ end
239
+ end
240
240
  end