mongo_mapper-unstable 2010.1.6 → 2010.1.12

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 (86) hide show
  1. data/VERSION +1 -1
  2. data/lib/mongo_mapper/descendant_appends.rb +44 -0
  3. data/lib/mongo_mapper/document.rb +54 -98
  4. data/lib/mongo_mapper/embedded_document.rb +28 -348
  5. data/lib/mongo_mapper/finder_options.rb +15 -33
  6. data/lib/mongo_mapper/plugins/associations/base.rb +121 -0
  7. data/lib/mongo_mapper/plugins/associations/belongs_to_polymorphic_proxy.rb +28 -0
  8. data/lib/mongo_mapper/plugins/associations/belongs_to_proxy.rb +23 -0
  9. data/lib/mongo_mapper/plugins/associations/collection.rb +21 -0
  10. data/lib/mongo_mapper/plugins/associations/embedded_collection.rb +49 -0
  11. data/lib/mongo_mapper/plugins/associations/in_array_proxy.rb +139 -0
  12. data/lib/mongo_mapper/plugins/associations/many_documents_as_proxy.rb +28 -0
  13. data/lib/mongo_mapper/plugins/associations/many_documents_proxy.rb +117 -0
  14. data/lib/mongo_mapper/plugins/associations/many_embedded_polymorphic_proxy.rb +31 -0
  15. data/lib/mongo_mapper/plugins/associations/many_embedded_proxy.rb +23 -0
  16. data/lib/mongo_mapper/plugins/associations/many_polymorphic_proxy.rb +13 -0
  17. data/lib/mongo_mapper/plugins/associations/one_proxy.rb +66 -0
  18. data/lib/mongo_mapper/plugins/associations/proxy.rb +118 -0
  19. data/lib/mongo_mapper/plugins/associations.rb +104 -0
  20. data/lib/mongo_mapper/plugins/callbacks.rb +65 -0
  21. data/lib/mongo_mapper/plugins/clone.rb +13 -0
  22. data/lib/mongo_mapper/plugins/descendants.rb +16 -0
  23. data/lib/mongo_mapper/plugins/dirty.rb +119 -0
  24. data/lib/mongo_mapper/plugins/equality.rb +11 -0
  25. data/lib/mongo_mapper/plugins/identity_map.rb +66 -0
  26. data/lib/mongo_mapper/plugins/inspect.rb +14 -0
  27. data/lib/mongo_mapper/plugins/keys.rb +295 -0
  28. data/lib/mongo_mapper/plugins/logger.rb +17 -0
  29. data/lib/mongo_mapper/plugins/pagination.rb +85 -0
  30. data/lib/mongo_mapper/plugins/rails.rb +45 -0
  31. data/lib/mongo_mapper/plugins/serialization.rb +109 -0
  32. data/lib/mongo_mapper/plugins/validations.rb +48 -0
  33. data/lib/mongo_mapper/plugins.rb +19 -0
  34. data/lib/mongo_mapper/support.rb +36 -15
  35. data/lib/mongo_mapper.rb +23 -22
  36. data/performance/read_write.rb +52 -0
  37. data/specs.watchr +23 -2
  38. data/test/functional/associations/test_belongs_to_proxy.rb +1 -1
  39. data/test/functional/associations/test_many_embedded_polymorphic_proxy.rb +58 -39
  40. data/test/functional/associations/test_many_embedded_proxy.rb +103 -69
  41. data/test/functional/test_dirty.rb +1 -1
  42. data/test/functional/test_document.rb +25 -25
  43. data/test/functional/test_embedded_document.rb +66 -63
  44. data/test/functional/test_identity_map.rb +233 -0
  45. data/test/functional/test_modifiers.rb +14 -0
  46. data/test/functional/test_string_id_compatibility.rb +4 -4
  47. data/test/functional/test_validations.rb +13 -0
  48. data/test/models.rb +0 -39
  49. data/test/test_helper.rb +8 -2
  50. data/test/unit/associations/test_base.rb +1 -1
  51. data/test/unit/associations/test_proxy.rb +3 -3
  52. data/test/unit/test_descendant_appends.rb +71 -0
  53. data/test/unit/test_document.rb +35 -46
  54. data/test/unit/test_embedded_document.rb +218 -271
  55. data/test/unit/{test_key.rb → test_keys.rb} +0 -0
  56. data/test/unit/test_pagination.rb +10 -2
  57. data/test/unit/test_plugins.rb +42 -0
  58. data/test/unit/test_rails.rb +123 -0
  59. data/test/unit/{test_serializations.rb → test_serialization.rb} +0 -0
  60. data/test/unit/test_support.rb +10 -6
  61. data/test/unit/test_time_zones.rb +2 -2
  62. metadata +44 -31
  63. data/lib/mongo_mapper/associations/base.rb +0 -119
  64. data/lib/mongo_mapper/associations/belongs_to_polymorphic_proxy.rb +0 -26
  65. data/lib/mongo_mapper/associations/belongs_to_proxy.rb +0 -21
  66. data/lib/mongo_mapper/associations/collection.rb +0 -19
  67. data/lib/mongo_mapper/associations/in_array_proxy.rb +0 -137
  68. data/lib/mongo_mapper/associations/many_documents_as_proxy.rb +0 -26
  69. data/lib/mongo_mapper/associations/many_documents_proxy.rb +0 -115
  70. data/lib/mongo_mapper/associations/many_embedded_polymorphic_proxy.rb +0 -31
  71. data/lib/mongo_mapper/associations/many_embedded_proxy.rb +0 -54
  72. data/lib/mongo_mapper/associations/many_polymorphic_proxy.rb +0 -11
  73. data/lib/mongo_mapper/associations/one_proxy.rb +0 -64
  74. data/lib/mongo_mapper/associations/proxy.rb +0 -116
  75. data/lib/mongo_mapper/associations.rb +0 -78
  76. data/lib/mongo_mapper/callbacks.rb +0 -61
  77. data/lib/mongo_mapper/dirty.rb +0 -117
  78. data/lib/mongo_mapper/key.rb +0 -36
  79. data/lib/mongo_mapper/mongo_mapper.rb +0 -125
  80. data/lib/mongo_mapper/pagination.rb +0 -66
  81. data/lib/mongo_mapper/rails_compatibility/document.rb +0 -15
  82. data/lib/mongo_mapper/rails_compatibility/embedded_document.rb +0 -28
  83. data/lib/mongo_mapper/serialization.rb +0 -54
  84. data/lib/mongo_mapper/serializers/json_serializer.rb +0 -48
  85. data/lib/mongo_mapper/validations.rb +0 -39
  86. data/test/functional/test_rails_compatibility.rb +0 -25
@@ -1,117 +0,0 @@
1
- module MongoMapper
2
- module Dirty
3
- DIRTY_SUFFIXES = ['_changed?', '_change', '_will_change!', '_was']
4
-
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, attribute| h[attribute] = key_change(attribute); h }
39
- end
40
-
41
- def initialize(attrs={})
42
- super(attrs)
43
- changed_keys.clear unless 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
- record = super
61
- changed_keys.clear
62
- record
63
- end
64
-
65
- private
66
- def clone_key_value(attribute_name)
67
- value = send(:read_attribute, attribute_name)
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?(attribute)
78
- changed_keys.include?(attribute)
79
- end
80
-
81
- def key_change(attribute)
82
- [changed_keys[attribute], __send__(attribute)] if key_changed?(attribute)
83
- end
84
-
85
- def key_was(attribute)
86
- key_changed?(attribute) ? changed_keys[attribute] : __send__(attribute)
87
- end
88
-
89
- def key_will_change!(attribute)
90
- changed_keys[attribute] = clone_key_value(attribute)
91
- end
92
-
93
- def write_attribute(attribute, value)
94
- attribute = attribute.to_s
95
-
96
- if changed_keys.include?(attribute)
97
- old = changed_keys[attribute]
98
- changed_keys.delete(attribute) unless value_changed?(attribute, old, value)
99
- else
100
- old = clone_key_value(attribute)
101
- changed_keys[attribute] = old if value_changed?(attribute, old, value)
102
- end
103
-
104
- super(attribute, 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
@@ -1,36 +0,0 @@
1
- module MongoMapper
2
- class Key
3
- attr_accessor :name, :type, :options, :default_value
4
-
5
- def initialize(*args)
6
- options = args.extract_options!
7
- @name, @type = args.shift.to_s, args.shift
8
- self.options = (options || {}).symbolize_keys
9
- self.default_value = self.options.delete(:default)
10
- end
11
-
12
- def ==(other)
13
- @name == other.name && @type == other.type
14
- end
15
-
16
- def set(value)
17
- type.to_mongo(value)
18
- end
19
-
20
- def embeddable?
21
- type.respond_to?(:embeddable?) && type.embeddable? ? true : false
22
- end
23
-
24
- def number?
25
- [Integer, Float].include?(type)
26
- end
27
-
28
- def get(value)
29
- if value.nil? && !default_value.nil?
30
- return default_value
31
- end
32
-
33
- type.from_mongo(value)
34
- end
35
- end
36
- end
@@ -1,125 +0,0 @@
1
- # if Gem is defined i'll assume you are using rubygems and lock specific versions
2
- # call me crazy but a plain old require will just get the latest version you have installed
3
- # so i want to make sure that if you are using gems you do in fact have the correct versions
4
- # if there is a better way to do this, please enlighten me!
5
- if self.class.const_defined?(:Gem)
6
- gem 'activesupport', '>= 2.3'
7
- gem 'mongo', '0.18.2'
8
- gem 'jnunemaker-validatable', '1.8.1'
9
- end
10
-
11
- require 'active_support'
12
- require 'mongo'
13
- require 'validatable'
14
-
15
- module MongoMapper
16
- # generic MM error
17
- class MongoMapperError < StandardError; end
18
-
19
- # raised when key expected to exist but not found
20
- class KeyNotFound < MongoMapperError; end
21
-
22
- # raised when document expected but not found
23
- class DocumentNotFound < MongoMapperError; end
24
-
25
- # raised when document not valid and using !
26
- class DocumentNotValid < MongoMapperError
27
- def initialize(document)
28
- super("Validation failed: #{document.errors.full_messages.join(", ")}")
29
- end
30
- end
31
-
32
- # @api public
33
- def self.connection
34
- @@connection ||= Mongo::Connection.new
35
- end
36
-
37
- # @api public
38
- def self.connection=(new_connection)
39
- @@connection = new_connection
40
- end
41
-
42
- # @api public
43
- def self.logger
44
- connection.logger
45
- end
46
-
47
- # @api public
48
- def self.database=(name)
49
- @@database = nil
50
- @@database_name = name
51
- end
52
-
53
- # @api public
54
- def self.database
55
- if @@database_name.blank?
56
- raise 'You forgot to set the default database name: MongoMapper.database = "foobar"'
57
- end
58
-
59
- @@database ||= MongoMapper.connection.db(@@database_name)
60
- end
61
-
62
- # @api private
63
- def self.ensured_indexes
64
- @@ensured_indexes ||= []
65
- end
66
-
67
- # @api private
68
- def self.ensured_indexes=(value)
69
- @@ensured_indexes = value
70
- end
71
-
72
- # @api private
73
- def self.ensure_index(klass, keys, options={})
74
- ensured_indexes << {:klass => klass, :keys => keys, :options => options}
75
- end
76
-
77
- # @api public
78
- def self.ensure_indexes!
79
- ensured_indexes.each do |index|
80
- unique = index[:options].delete(:unique)
81
- index[:klass].collection.create_index(index[:keys], unique)
82
- end
83
- end
84
-
85
- # @api private
86
- def self.use_time_zone?
87
- Time.respond_to?(:zone) && Time.zone ? true : false
88
- end
89
-
90
- # @api private
91
- def self.time_class
92
- use_time_zone? ? Time.zone : Time
93
- end
94
-
95
- # @api private
96
- def self.normalize_object_id(value)
97
- value.is_a?(String) ? Mongo::ObjectID.from_string(value) : value
98
- end
99
- end
100
-
101
- require 'mongo_mapper/support'
102
- require 'mongo_mapper/callbacks'
103
- require 'mongo_mapper/finder_options'
104
- require 'mongo_mapper/dirty'
105
- require 'mongo_mapper/dynamic_finder'
106
- require 'mongo_mapper/key'
107
- require 'mongo_mapper/pagination'
108
- require 'mongo_mapper/serialization'
109
- require 'mongo_mapper/validations'
110
- require 'mongo_mapper/rails_compatibility/document'
111
- require 'mongo_mapper/rails_compatibility/embedded_document'
112
- require 'mongo_mapper/embedded_document'
113
- require 'mongo_mapper/document'
114
- require 'mongo_mapper/associations'
115
- require 'mongo_mapper/associations/base'
116
- require 'mongo_mapper/associations/proxy'
117
- require 'mongo_mapper/associations/collection'
118
- require 'mongo_mapper/associations/many_documents_proxy'
119
- require 'mongo_mapper/associations/belongs_to_proxy'
120
- require 'mongo_mapper/associations/belongs_to_polymorphic_proxy'
121
- require 'mongo_mapper/associations/many_polymorphic_proxy'
122
- require 'mongo_mapper/associations/many_embedded_proxy'
123
- require 'mongo_mapper/associations/many_embedded_polymorphic_proxy'
124
- require 'mongo_mapper/associations/many_documents_as_proxy'
125
- require 'mongo_mapper/associations/one_proxy'
@@ -1,66 +0,0 @@
1
- module MongoMapper
2
- module Pagination
3
- class PaginationProxy
4
- instance_methods.each { |m| undef_method m unless m =~ /(^__|^nil\?$|^send$|proxy_|^object_id$)/ }
5
-
6
- attr_accessor :subject
7
- attr_reader :total_entries, :per_page, :current_page
8
- alias limit per_page
9
-
10
- def initialize(total_entries, current_page, per_page=nil)
11
- @total_entries = total_entries.to_i
12
- self.per_page = per_page
13
- self.current_page = current_page
14
- end
15
-
16
- def total_pages
17
- (total_entries / per_page.to_f).ceil
18
- end
19
-
20
- def out_of_bounds?
21
- current_page > total_pages
22
- end
23
-
24
- def previous_page
25
- current_page > 1 ? (current_page - 1) : nil
26
- end
27
-
28
- def next_page
29
- current_page < total_pages ? (current_page + 1) : nil
30
- end
31
-
32
- def skip
33
- (current_page - 1) * per_page
34
- end
35
- alias offset skip # for will paginate support
36
-
37
- def send(method, *args, &block)
38
- if respond_to?(method)
39
- super
40
- else
41
- subject.send(method, *args, &block)
42
- end
43
- end
44
-
45
- def ===(other)
46
- other === subject
47
- end
48
-
49
- def method_missing(name, *args, &block)
50
- @subject.send(name, *args, &block)
51
- end
52
-
53
- private
54
- def per_page=(value)
55
- value = 25 if value.blank?
56
- @per_page = value.to_i
57
- end
58
-
59
- def current_page=(value)
60
- value = value.to_i
61
- value = 1 if value < 1
62
- @current_page = value
63
- end
64
- end
65
- end
66
- end
@@ -1,15 +0,0 @@
1
- module MongoMapper
2
- module RailsCompatibility
3
- module Document
4
- def self.included(model)
5
- model.class_eval do
6
- alias_method :new_record?, :new?
7
-
8
- def human_name
9
- self.name.demodulize.titleize
10
- end
11
- end
12
- end
13
- end
14
- end
15
- end
@@ -1,28 +0,0 @@
1
- module MongoMapper
2
- module RailsCompatibility
3
- module EmbeddedDocument
4
- def self.included(model)
5
- model.class_eval do
6
- extend ClassMethods
7
-
8
- alias_method :new_record?, :new?
9
- end
10
-
11
- class << model
12
- alias has_many many
13
- alias has_one one
14
- end
15
- end
16
-
17
- module ClassMethods
18
- def column_names
19
- keys.keys
20
- end
21
-
22
- def human_name
23
- self.name.demodulize.titleize
24
- end
25
- end
26
- end
27
- end
28
- end
@@ -1,54 +0,0 @@
1
- require 'active_support/json'
2
-
3
- module MongoMapper
4
- module Serialization
5
- class Serializer
6
- attr_reader :options
7
-
8
- def initialize(record, options={})
9
- @record, @options = record, options.dup
10
- end
11
-
12
- def serializable_key_names
13
- key_names = @record.attributes.keys
14
-
15
- if options[:only]
16
- options.delete(:except)
17
- key_names = key_names & Array(options[:only]).collect { |n| n.to_s }
18
- else
19
- options[:except] = Array(options[:except])
20
- key_names = key_names - options[:except].collect { |n| n.to_s }
21
- end
22
-
23
- key_names
24
- end
25
-
26
- def serializable_method_names
27
- Array(options[:methods]).inject([]) do |method_attributes, name|
28
- method_attributes << name if @record.respond_to?(name.to_s)
29
- method_attributes
30
- end
31
- end
32
-
33
- def serializable_names
34
- serializable_key_names + serializable_method_names
35
- end
36
-
37
- def serializable_record
38
- returning(serializable_record = {}) do
39
- serializable_names.each { |name| serializable_record[name] = @record.send(name) }
40
- end
41
- end
42
-
43
- def serialize
44
- # overwrite to implement
45
- end
46
-
47
- def to_s(&block)
48
- serialize(&block)
49
- end
50
- end
51
- end
52
- end
53
-
54
- require 'mongo_mapper/serializers/json_serializer'
@@ -1,48 +0,0 @@
1
- module MongoMapper
2
- module Serialization
3
- def self.included(base)
4
- base.cattr_accessor :include_root_in_json, :instance_writer => false
5
- base.extend ClassMethods
6
- end
7
-
8
- def to_json(options={})
9
- apply_to_json_defaults(options)
10
-
11
- if include_root_in_json
12
- "{#{self.class.json_class_name}: #{JsonSerializer.new(self, options).to_s}}"
13
- else
14
- JsonSerializer.new(self, options).to_s
15
- end
16
- end
17
-
18
- def from_json(json)
19
- self.attributes = ActiveSupport::JSON.decode(json)
20
- self
21
- end
22
-
23
- class JsonSerializer < MongoMapper::Serialization::Serializer
24
- def serialize
25
- serializable_record.to_json
26
- end
27
- end
28
-
29
- module ClassMethods
30
- def json_class_name
31
- @json_class_name ||= name.demodulize.underscore.inspect
32
- end
33
- end
34
-
35
- private
36
- def apply_to_json_defaults(options)
37
- unless options[:only]
38
- methods = [options.delete(:methods)].flatten.compact
39
- methods << :id
40
- options[:methods] = methods.uniq
41
- end
42
-
43
- except = [options.delete(:except)].flatten.compact
44
- except << :_id
45
- options[:except] = except
46
- end
47
- end
48
- end
@@ -1,39 +0,0 @@
1
- module MongoMapper
2
- module Validations
3
- module Macros
4
- def validates_uniqueness_of(*args)
5
- add_validations(args, MongoMapper::Validations::ValidatesUniquenessOf)
6
- end
7
- end
8
-
9
- class ValidatesUniquenessOf < Validatable::ValidationBase
10
- option :scope, :case_sensitive
11
- default :case_sensitive => true
12
-
13
- def valid?(instance)
14
- value = instance[attribute]
15
- return true if allow_blank && value.blank?
16
- base_conditions = case_sensitive ? {self.attribute => value} : {}
17
- doc = instance.class.first(base_conditions.merge(scope_conditions(instance)).merge(where_conditions(instance)))
18
- doc.nil? || instance._id == doc._id
19
- end
20
-
21
- def message(instance)
22
- super || "has already been taken"
23
- end
24
-
25
- def scope_conditions(instance)
26
- return {} unless scope
27
- Array(scope).inject({}) do |conditions, key|
28
- conditions.merge(key => instance[key])
29
- end
30
- end
31
-
32
- def where_conditions(instance)
33
- conditions = {}
34
- conditions[attribute] = /#{instance[attribute].to_s}/i unless case_sensitive
35
- conditions
36
- end
37
- end
38
- end
39
- end
@@ -1,25 +0,0 @@
1
- require 'test_helper'
2
-
3
- class TestRailsCompatibility < Test::Unit::TestCase
4
- class Item
5
- include MongoMapper::EmbeddedDocument
6
- key :for_all, String
7
- end
8
-
9
- class Order
10
- include MongoMapper::Document
11
- many :items, :class_name => 'TestRailsCompatibility::Item'
12
- key :order_only, String
13
- end
14
-
15
- context "Document" do
16
- setup do
17
- Order.collection.remove
18
- end
19
-
20
- should "alias new to new_record?" do
21
- instance = Order.new
22
- instance.new_record?.should == instance.new?
23
- end
24
- end
25
- end