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,17 @@
1
+ module MongoMapper
2
+ module Plugins
3
+ module Logger
4
+ module ClassMethods
5
+ def logger
6
+ MongoMapper.logger
7
+ end
8
+ end
9
+
10
+ module InstanceMethods
11
+ def logger
12
+ self.class.logger
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,107 @@
1
+ module MongoMapper
2
+ module Plugins
3
+ module Modifiers
4
+ module ClassMethods
5
+ def increment(*args)
6
+ modifier_update('$inc', args)
7
+ end
8
+
9
+ def decrement(*args)
10
+ criteria, keys = criteria_and_keys_from_args(args)
11
+ values, to_decrement = keys.values, {}
12
+ keys.keys.each_with_index { |k, i| to_decrement[k] = -values[i].abs }
13
+ collection.update(criteria, {'$inc' => to_decrement}, :multi => true)
14
+ end
15
+
16
+ def set(*args)
17
+ modifier_update('$set', args)
18
+ end
19
+
20
+ def unset(*args)
21
+ if args[0].is_a?(Hash)
22
+ criteria, keys = args.shift, args
23
+ else
24
+ keys, ids = args.partition { |arg| arg.is_a?(Symbol) }
25
+ criteria = {:id => ids}
26
+ end
27
+
28
+ criteria = to_criteria(criteria)
29
+ modifiers = keys.inject({}) { |hash, key| hash[key] = 1; hash }
30
+ collection.update(criteria, {'$unset' => modifiers}, :multi => true)
31
+ end
32
+
33
+ def push(*args)
34
+ modifier_update('$push', args)
35
+ end
36
+
37
+ def push_all(*args)
38
+ modifier_update('$pushAll', args)
39
+ end
40
+
41
+ def add_to_set(*args)
42
+ modifier_update('$addToSet', args)
43
+ end
44
+ alias push_uniq add_to_set
45
+
46
+ def pull(*args)
47
+ modifier_update('$pull', args)
48
+ end
49
+
50
+ def pull_all(*args)
51
+ modifier_update('$pullAll', args)
52
+ end
53
+
54
+ def pop(*args)
55
+ modifier_update('$pop', args)
56
+ end
57
+
58
+ private
59
+ def modifier_update(modifier, args)
60
+ criteria, keys = criteria_and_keys_from_args(args)
61
+ collection.update(criteria, {modifier => keys}, :multi => true)
62
+ end
63
+
64
+ def criteria_and_keys_from_args(args)
65
+ keys = args.pop
66
+ criteria = args[0].is_a?(Hash) ? args[0] : {:id => args}
67
+ [to_criteria(criteria), keys]
68
+ end
69
+ end
70
+
71
+ module InstanceMethods
72
+ def unset(*keys)
73
+ self.class.unset(id, *keys)
74
+ end
75
+
76
+ def increment(hash)
77
+ self.class.increment(id, hash)
78
+ end
79
+
80
+ def decrement(hash)
81
+ self.class.decrement(id, hash)
82
+ end
83
+
84
+ def set(hash)
85
+ self.class.set(id, hash)
86
+ end
87
+
88
+ def push(hash)
89
+ self.class.push(id, hash)
90
+ end
91
+
92
+ def pull(hash)
93
+ self.class.pull(id, hash)
94
+ end
95
+
96
+ def add_to_set(hash)
97
+ self.class.push_uniq(id, hash)
98
+ end
99
+ alias push_uniq add_to_set
100
+
101
+ def pop(hash)
102
+ self.class.pop(id, hash)
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,24 @@
1
+ module MongoMapper
2
+ module Plugins
3
+ module Pagination
4
+ module ClassMethods
5
+ def per_page
6
+ 25
7
+ end
8
+
9
+ def paginate(options)
10
+ per_page = options.delete(:per_page) || self.per_page
11
+ page = options.delete(:page)
12
+ total_entries = count(options)
13
+ pagination = Pagination::Proxy.new(total_entries, page, per_page)
14
+
15
+ options.update(:limit => pagination.limit, :skip => pagination.skip)
16
+ pagination.subject = find_many(options)
17
+ pagination
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+
24
+ require 'mongo_mapper/plugins/pagination/proxy'
@@ -0,0 +1,72 @@
1
+ module MongoMapper
2
+ module Plugins
3
+ module Pagination
4
+ class Proxy
5
+ instance_methods.each { |m| undef_method m unless m =~ /(^__|^nil\?$|^send$|respond_to\?|proxy_|^object_id$)/ }
6
+
7
+ attr_accessor :subject
8
+ attr_reader :total_entries, :per_page, :current_page
9
+ alias limit per_page
10
+
11
+ def initialize(total_entries, current_page, per_page=nil)
12
+ @total_entries = total_entries.to_i
13
+ self.per_page = per_page
14
+ self.current_page = current_page
15
+ end
16
+
17
+ def total_pages
18
+ (total_entries / per_page.to_f).ceil
19
+ end
20
+
21
+ def out_of_bounds?
22
+ current_page > total_pages
23
+ end
24
+
25
+ def previous_page
26
+ current_page > 1 ? (current_page - 1) : nil
27
+ end
28
+
29
+ def next_page
30
+ current_page < total_pages ? (current_page + 1) : nil
31
+ end
32
+
33
+ def skip
34
+ (current_page - 1) * per_page
35
+ end
36
+ alias offset skip # for will paginate support
37
+
38
+ def send(method, *args, &block)
39
+ if respond_to?(method)
40
+ super
41
+ else
42
+ subject.send(method, *args, &block)
43
+ end
44
+ end
45
+
46
+ def ===(other)
47
+ other === subject
48
+ end
49
+
50
+ def method_missing(name, *args, &block)
51
+ @subject.send(name, *args, &block)
52
+ end
53
+
54
+ def respond_to?(name, *args, &block)
55
+ super || @subject.respond_to?(name, *args, &block)
56
+ end
57
+
58
+ private
59
+ def per_page=(value)
60
+ value = 25 if value.blank?
61
+ @per_page = value.to_i
62
+ end
63
+
64
+ def current_page=(value)
65
+ value = value.to_i
66
+ value = 1 if value < 1
67
+ @current_page = value
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,68 @@
1
+ module MongoMapper
2
+ module Plugins
3
+ module Persistence
4
+ module ClassMethods
5
+ class Unsupported < MongoMapperError; end
6
+
7
+ def connection(mongo_connection=nil)
8
+ not_supported_by_embedded
9
+ if mongo_connection.nil?
10
+ @connection ||= MongoMapper.connection
11
+ else
12
+ @connection = mongo_connection
13
+ end
14
+ @connection
15
+ end
16
+
17
+ def set_database_name(name)
18
+ not_supported_by_embedded
19
+ @database_name = name
20
+ end
21
+
22
+ def database_name
23
+ not_supported_by_embedded
24
+ @database_name
25
+ end
26
+
27
+ def database
28
+ not_supported_by_embedded
29
+ if database_name.nil?
30
+ MongoMapper.database
31
+ else
32
+ connection.db(database_name)
33
+ end
34
+ end
35
+
36
+ def set_collection_name(name)
37
+ not_supported_by_embedded
38
+ @collection_name = name
39
+ end
40
+
41
+ def collection_name
42
+ not_supported_by_embedded
43
+ @collection_name ||= self.to_s.tableize.gsub(/\//, '.')
44
+ end
45
+
46
+ def collection
47
+ not_supported_by_embedded
48
+ database.collection(collection_name)
49
+ end
50
+
51
+ private
52
+ def not_supported_by_embedded
53
+ raise Unsupported.new('This is not supported for embeddable documents at this time.') if embeddable?
54
+ end
55
+ end
56
+
57
+ module InstanceMethods
58
+ def collection
59
+ _root_document.class.collection
60
+ end
61
+
62
+ def database
63
+ _root_document.class.database
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,45 @@
1
+ module MongoMapper
2
+ module Plugins
3
+ module Protected
4
+ module ClassMethods
5
+ def attr_protected(*attrs)
6
+ self.write_inheritable_attribute(:attr_protected, Set.new(attrs) + (protected_attributes || []))
7
+ end
8
+
9
+ def protected_attributes
10
+ self.read_inheritable_attribute(:attr_protected)
11
+ end
12
+
13
+ def key(*args)
14
+ key = super
15
+ attr_protected key.name.to_sym if key.options[:protected]
16
+ key
17
+ end
18
+ end
19
+
20
+ module InstanceMethods
21
+ def assign(attrs={})
22
+ super(filter_protected_attrs(attrs))
23
+ end
24
+
25
+ def update_attributes(attrs={})
26
+ super(filter_protected_attrs(attrs))
27
+ end
28
+
29
+ def update_attributes!(attrs={})
30
+ super(filter_protected_attrs(attrs))
31
+ end
32
+
33
+ def protected_attributes
34
+ self.class.protected_attributes
35
+ end
36
+
37
+ protected
38
+ def filter_protected_attrs(attrs)
39
+ return attrs if protected_attributes.blank? || attrs.blank?
40
+ attrs.dup.delete_if { |key, val| protected_attributes.include?(key.to_sym) }
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,57 @@
1
+ module MongoMapper
2
+ module Plugins
3
+ module Rails
4
+ def self.configure(model)
5
+ model.extend ActiveModel::Naming if defined?(ActiveModel)
6
+ end
7
+
8
+ module InstanceMethods
9
+ def to_param
10
+ id.to_s if persisted?
11
+ end
12
+
13
+ def to_model
14
+ self
15
+ end
16
+
17
+ def to_key
18
+ [id] if persisted?
19
+ end
20
+
21
+ def new_record?
22
+ new?
23
+ end
24
+
25
+ def read_attribute(name)
26
+ self[name]
27
+ end
28
+
29
+ def read_attribute_before_typecast(name)
30
+ read_key_before_typecast(name)
31
+ end
32
+
33
+ def write_attribute(name, value)
34
+ self[name] = value
35
+ end
36
+ end
37
+
38
+ module ClassMethods
39
+ def has_one(*args)
40
+ one(*args)
41
+ end
42
+
43
+ def has_many(*args)
44
+ many(*args)
45
+ end
46
+
47
+ def column_names
48
+ keys.keys
49
+ end
50
+
51
+ def human_name
52
+ self.name.demodulize.titleize
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,91 @@
1
+ require 'active_support/json'
2
+
3
+ module MongoMapper
4
+ module Plugins
5
+ module Serialization
6
+ def self.configure(model)
7
+ model.class_eval { cattr_accessor :include_root_in_json, :instance_writer => true }
8
+ end
9
+
10
+ module InstanceMethods
11
+ def to_xml(options = {}, &block)
12
+ options[:dasherize] = false unless options.has_key?(:dasherize)
13
+ serializer = Serialization::XmlSerializer.new(self, options)
14
+ block_given? ? serializer.to_s(&block) : serializer.to_s
15
+ end
16
+
17
+ def as_json options={}
18
+ options ||= {}
19
+ unless options[:only]
20
+ methods = [options.delete(:methods)].flatten.compact
21
+ methods << :id
22
+ options[:methods] = methods.uniq
23
+ end
24
+
25
+ except = [options.delete(:except)].flatten.compact
26
+ except << :_id
27
+ options[:except] = except
28
+
29
+ # Direct rip from Rails 3 ActiveModel Serialization (#serializable_hash)
30
+ hash = begin
31
+ options[:only] = Array.wrap(options[:only]).map { |n| n.to_s }
32
+ options[:except] = Array.wrap(options[:except]).map { |n| n.to_s }
33
+
34
+ attribute_names = attributes.keys.sort
35
+ if options[:only].any?
36
+ attribute_names &= options[:only]
37
+ elsif options[:except].any?
38
+ attribute_names -= options[:except]
39
+ end
40
+
41
+ method_names = Array.wrap(options[:methods]).inject([]) do |methods, name|
42
+ methods << name if respond_to?(name.to_s)
43
+ methods
44
+ end
45
+
46
+ (attribute_names + method_names).inject({}) { |hash, name|
47
+ hash[name] = send(name)
48
+ hash
49
+ }
50
+ end
51
+ # End rip
52
+
53
+ options.delete(:only) if options[:only].nil? or options[:only].empty?
54
+
55
+ hash.each do |key, value|
56
+ if value.is_a?(Array)
57
+ hash[key] = value.map do |item|
58
+ item.respond_to?(:as_json) ? item.as_json(options) : item
59
+ end
60
+ elsif value.is_a? BSON::ObjectID
61
+ hash[key] = value.to_s
62
+ elsif value.respond_to?(:as_json)
63
+ hash[key] = value.as_json(options)
64
+ end
65
+ end
66
+
67
+ # Replicate Rails 3 naming - and also bin anytihng after : for use in our dynamic classes from unit tests
68
+ hash = { ActiveSupport::Inflector.underscore(ActiveSupport::Inflector.demodulize(self)).gsub(/:.*/,'') => hash } if include_root_in_json
69
+ hash
70
+ end
71
+ end
72
+
73
+ module ClassMethods
74
+ def from_json(json)
75
+ self.new(ActiveSupport::JSON.decode(json))
76
+ end
77
+
78
+ def from_xml(xml)
79
+ # instance = self.new
80
+ # instance.attributes = self.new
81
+ # instance
82
+ instance.attributes = self.new(Hash.from_xml(xml).values.first)
83
+ end
84
+ end
85
+
86
+ end
87
+ end
88
+ end
89
+
90
+ require 'mongo_mapper/plugins/serialization/xml_serializer'
91
+ require 'mongo_mapper/plugins/serialization/array'