mongo_odm 0.1.9 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -1,16 +1,16 @@
1
1
  # Use `bundle install` in order to install these gems
2
2
  source 'http://rubygems.org'
3
3
 
4
- gem "activesupport", "3.0.0.beta3"
5
- gem "activemodel", "3.0.0.beta3"
6
- gem "mongo", "~>1.0.2"
7
- gem "bson_ext", "~>1.0.1"
8
- gem "tzinfo", "~>0.3.22"
4
+ gem "activesupport", "~>3.0.0.rc2"
5
+ gem "activemodel", "~>3.0.0.rc2"
6
+ gem "mongo", "~>1.0.8"
7
+ gem "bson_ext", "~>1.0.5"
8
+ gem "tzinfo", "~>0.3.23"
9
9
 
10
10
  group :development do
11
- gem 'jeweler', '1.4.0'
12
- gem 'yard', '0.5.6'
13
- gem 'rcov', '0.9.8'
14
- gem 'rspec', '2.0.0.beta.12'
15
- gem 'watchr', '~>0.6'
11
+ gem 'jeweler', '~>1.4.0'
12
+ gem 'yard', '~>0.5.8'
13
+ gem 'rcov', '~>0.9.8'
14
+ gem 'rspec', '~>2.0.0.beta.20'
15
+ gem 'watchr', '~>0.7'
16
16
  end
data/Gemfile.lock ADDED
@@ -0,0 +1,51 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ activemodel (3.0.0.rc2)
5
+ activesupport (= 3.0.0.rc2)
6
+ builder (~> 2.1.2)
7
+ i18n (~> 0.4.1)
8
+ activesupport (3.0.0.rc2)
9
+ bson (1.0.6)
10
+ bson_ext (1.0.6)
11
+ builder (2.1.2)
12
+ diff-lcs (1.1.2)
13
+ gemcutter (0.6.1)
14
+ git (1.2.5)
15
+ i18n (0.4.1)
16
+ jeweler (1.4.0)
17
+ gemcutter (>= 0.1.0)
18
+ git (>= 1.2.5)
19
+ rubyforge (>= 2.0.0)
20
+ json_pure (1.4.6)
21
+ mongo (1.0.8)
22
+ bson (>= 1.0.5)
23
+ rcov (0.9.8)
24
+ rspec (2.0.0.beta.20)
25
+ rspec-core (= 2.0.0.beta.20)
26
+ rspec-expectations (= 2.0.0.beta.20)
27
+ rspec-mocks (= 2.0.0.beta.20)
28
+ rspec-core (2.0.0.beta.20)
29
+ rspec-expectations (2.0.0.beta.20)
30
+ diff-lcs (>= 1.1.2)
31
+ rspec-mocks (2.0.0.beta.20)
32
+ rubyforge (2.0.4)
33
+ json_pure (>= 1.1.7)
34
+ tzinfo (0.3.23)
35
+ watchr (0.7)
36
+ yard (0.5.8)
37
+
38
+ PLATFORMS
39
+ ruby
40
+
41
+ DEPENDENCIES
42
+ activemodel (~> 3.0.0.rc2)
43
+ activesupport (~> 3.0.0.rc2)
44
+ bson_ext (~> 1.0.5)
45
+ jeweler (~> 1.4.0)
46
+ mongo (~> 1.0.8)
47
+ rcov (~> 0.9.8)
48
+ rspec (~> 2.0.0.beta.20)
49
+ tzinfo (~> 0.3.23)
50
+ watchr (~> 0.7)
51
+ yard (~> 0.5.8)
data/README.rdoc CHANGED
@@ -4,14 +4,19 @@ Flexible persistence module for any Ruby class to MongoDB.
4
4
 
5
5
  = Why another ODM for MongoDB?
6
6
 
7
- MongoMapper, Mongoid, and others, are amazing projects. But I still think it's too much for an ODM for MongoDB.
8
- The Mongo Ruby driver allows you to query the database with a nice interface, the only required thing is a way to instanciate
9
- the results as objects of predefined classes, so you can encapsulate all the logic under a particular class and don't have to
10
- worry about type conversions.
11
-
7
+ * Fully compatible with Rails 3
8
+ * Use the Mongo ruby driver when possible (query syntax, cursors, indexes management...)
9
+ * Allow lazy loading of collections and queries nesting (concatenation of 'find' calls) to emulate ActiveRecord 3
10
+ * No association methods (for now): Just declare your own methods on models to fetch the related items
11
+ * Give support for dirty objects, validations, etc. through ActiveModel 3
12
+ * Automanage type conversions and default values
13
+ * Keep it as simple as possible
14
+
15
+ Other Mongo ODMs don't require to explicitly define the possible schema of a model. I think this is necessary to help with type conversions (instanciate the right class for each attribute, and convert them to a Mongo compatible type when persisted). But it's also possible to fill attributes with valid Mongo values without defining them as fields, and only the attributes whose values are different than the default values are stored as part of the document when saved.
16
+
12
17
  = Basics
13
18
 
14
- A piece of code is better than a hundred words:
19
+ A piece of code is better than a hundred of words:
15
20
 
16
21
  class Shape
17
22
  include MongoODM::Document
@@ -32,8 +37,7 @@ A piece of code is better than a hundred words:
32
37
  # "name" : "Point"
33
38
  # }
34
39
 
35
- class Circle < Shape
36
- set_collection :shapes # Because we don't want them to be saved on a separated collection
40
+ class Circle < Shape # This items are stored on the 'shapes' collection
37
41
  field :radius, Float, :default => 1.0
38
42
  end
39
43
 
@@ -194,10 +198,10 @@ To reference the associated objects instead of embed them, for now you need to d
194
198
 
195
199
  class Flag
196
200
  include MongoODM::Document
197
- field :colors, Array
201
+ field :colors_ids, Array
198
202
 
199
203
  def colors
200
- Color.find(:_id => {'$in' => read_attribute(:colors)})
204
+ Color.find(:_id => {'$in' => colors_ids})
201
205
  end
202
206
  end
203
207
 
@@ -209,18 +213,18 @@ To reference the associated objects instead of embed them, for now you need to d
209
213
  Color.new(:name => "red").save
210
214
  Color.new(:name => "green").save
211
215
 
212
- flag = Flag.new(:colors => [ Color.find_one(:name => "red").id, Color.find_one(:name => "green").id ])
216
+ flag = Flag.new(:colors_ids => [ Color.find_one(:name => "red").id, Color.find_one(:name => "green").id ])
213
217
  flag.save
214
218
 
215
219
  # Saves:
216
- # { "_id" : ObjectId("4be96c15715dd2c4be000003"),
217
- # "_class" : "Flag",
218
- # "colors" : [ ObjectId("4be96bfe715dd2c4be000001"), ObjectId("4be96c08715dd2c4be000002") ]
220
+ # { "_id" : ObjectId("4be96c15715dd2c4be000003"),
221
+ # "_class" : "Flag",
222
+ # "colors_ids" : [ ObjectId("4be96bfe715dd2c4be000001"), ObjectId("4be96c08715dd2c4be000002") ]
219
223
  # }
220
224
 
221
225
  flag.colors
222
226
 
223
- # Returns a cursor
227
+ # Returns a criteria object that wraps a cursor
224
228
 
225
229
  flag.colors.to_a
226
230
 
@@ -248,4 +252,10 @@ All the dirty object methods defined in ActiveModel::Dirty are included
248
252
 
249
253
  = Copyright
250
254
 
251
- Copyright © 2010 Carlos Paramio. See LICENSE for details.
255
+ Copyright © 2010 Carlos Paramio. See LICENSE for details.
256
+
257
+ = Credits
258
+
259
+ Carlos Paramio
260
+
261
+ http://h1labs.com
data/Rakefile CHANGED
@@ -15,7 +15,7 @@ if Gem.available? 'jeweler'
15
15
  gemspec.authors = ["Carlos Paramio"]
16
16
  gemspec.files = FileList["[A-Z]*", "{lib,spec}/**/*"]
17
17
  gemspec.version = MongoODM::VERSION
18
- bundle = Bundler::Definition.from_gemfile('Gemfile')
18
+ bundle = Bundler.definition
19
19
  bundle.dependencies.each do |dependency|
20
20
  if dependency.groups.include?(:default)
21
21
  gemspec.add_dependency(dependency.name, dependency.requirement.to_s)
data/lib/mongo_odm.rb CHANGED
@@ -8,7 +8,6 @@ require 'active_model'
8
8
  module MongoODM
9
9
 
10
10
  extend ActiveSupport::Autoload
11
- include ActiveSupport::Configurable
12
11
 
13
12
  autoload :VERSION
14
13
  autoload :Criteria
@@ -29,9 +28,13 @@ module MongoODM
29
28
  connection.db(config[:database] || 'test')
30
29
  end
31
30
 
31
+ def self.config
32
+ @_config ||= {}
33
+ end
34
+
32
35
  def self.config=(value)
33
36
  self.connection = nil
34
- super
37
+ @_config = value
35
38
  end
36
39
 
37
40
  def self.instanciate(value)
@@ -14,24 +14,11 @@ require 'active_support/core_ext/time/conversions'
14
14
  # * An attribute of the same class is sent to the Mongo driver
15
15
 
16
16
  # @private
17
- class Mongo::ObjectID
17
+ class BSON::ObjectId
18
18
  def self.type_cast(value)
19
19
  return nil if value.nil?
20
- return value if value.is_a?(Mongo::ObjectID)
21
- value.to_s
22
- end
23
-
24
- def to_mongo
25
- self
26
- end
27
- end
28
-
29
- # @private
30
- class BSON::ObjectID
31
- def self.type_cast(value)
32
- return nil if value.nil?
33
- return value if value.is_a?(BSON::ObjectID)
34
- value.to_s
20
+ return value if value.is_a?(BSON::ObjectId)
21
+ BSON::ObjectId(value)
35
22
  end
36
23
 
37
24
  def to_mongo
@@ -66,8 +53,12 @@ end
66
53
  # @private
67
54
  class Symbol
68
55
  def self.type_cast(value)
69
- return nil if value.nil?
70
- value.to_s.intern
56
+ case value
57
+ when nil then nil
58
+ when Symbol then value
59
+ when String then value.intern
60
+ else value.inspect.intern
61
+ end
71
62
  end
72
63
 
73
64
  def to_mongo
@@ -114,8 +105,11 @@ end
114
105
  # @private
115
106
  class String
116
107
  def self.type_cast(value)
117
- return nil if value.nil?
118
- value.to_s
108
+ case value
109
+ when nil then nil
110
+ when String, Symbol then value.to_s
111
+ else value.inspect
112
+ end
119
113
  end
120
114
 
121
115
  def to_mongo
@@ -39,7 +39,7 @@ module MongoODM
39
39
 
40
40
  def reload_with_dirty(*args)
41
41
  reload_without_dirty(*args).tap do
42
- previously_changed_attributes.clear
42
+ @previously_changed = nil
43
43
  changed_attributes.clear
44
44
  end
45
45
  end
@@ -19,7 +19,7 @@ module MongoODM
19
19
  end
20
20
 
21
21
  def inspect
22
- "#<#{self.class.name} #{attributes.except(*private_attribute_names).keys.map{|k| inspect_attribute(k)}.join(", ")}>"
22
+ "#<#{self.class.name} #{attributes.except(*private_attribute_names).keys.sort.map{|k| inspect_attribute(k)}.join(", ")}>"
23
23
  end
24
24
  end
25
25
 
@@ -23,7 +23,7 @@ module MongoODM
23
23
 
24
24
  # Save a document to its collection.
25
25
  #
26
- # @return [ObjectID] the _id of the saved document.
26
+ # @return [ObjectId] the _id of the saved document.
27
27
  #
28
28
  # @option opts [Boolean] :safe (+false+)
29
29
  # If true, check that the save succeeded. OperationFailure
@@ -48,7 +48,7 @@ module MongoODM
48
48
  end
49
49
 
50
50
  def to_mongo
51
- attributes.inject({}.with_indifferent_access) do |attrs, (key, value)|
51
+ attributes.inject({}) do |attrs, (key, value)|
52
52
  attrs[key] = value.to_mongo unless value.nil? # self.class.fields[key].default == value
53
53
  attrs
54
54
  end
@@ -1,7 +1,7 @@
1
1
  # encoding: utf-8
2
2
  module MongoODM
3
3
  VERSION_MAJOR = "0"
4
- VERSION_MINOR = "1"
5
- VERSION_BUILD = "9"
4
+ VERSION_MINOR = "2"
5
+ VERSION_BUILD = "0"
6
6
  VERSION = "#{VERSION_MAJOR}.#{VERSION_MINOR}.#{VERSION_BUILD}"
7
7
  end
@@ -3,6 +3,10 @@ require "spec_helper"
3
3
 
4
4
  describe "Conversions" do
5
5
 
6
+ before do
7
+ Time.zone = 'UTC'
8
+ end
9
+
6
10
  describe Array do
7
11
 
8
12
  describe ".type_cast" do
@@ -74,6 +78,8 @@ describe "Conversions" do
74
78
 
75
79
  it "tries to convert any other value to a symbol" do
76
80
  Symbol.type_cast("test").should == :test
81
+ Symbol.type_cast(1).should == :"1"
82
+ Symbol.type_cast(3.14).should == :"3.14"
77
83
  Symbol.type_cast([1, 2]).should == :"[1, 2]"
78
84
  Symbol.type_cast({:a => 1, :b => 2}).should == :"{:a=>1, :b=>2}"
79
85
  end
@@ -199,13 +205,13 @@ describe "Conversions" do
199
205
  describe Date do
200
206
 
201
207
  describe ".type_cast" do
202
-
208
+
203
209
  it "returns nil when called with nil" do
204
210
  Date.type_cast(nil).should == nil
205
211
  end
206
212
 
207
213
  it "tries to convert any other value to a date" do
208
- Date.type_cast("1/2/1980").should == Date.new(1980, 2, 1)
214
+ Date.type_cast("2/1/1980").should == Date.new(1980, 1, 2)
209
215
  end
210
216
 
211
217
  end
@@ -229,8 +235,8 @@ describe "Conversions" do
229
235
  DateTime.type_cast(nil).should == nil
230
236
  end
231
237
 
232
- it "tries to convert any other value to a date" do
233
- DateTime.type_cast("1/2/1980 11:30").should == DateTime.new(1980, 2, 1, 11, 30)
238
+ it "tries to convert any other value to a datetime" do
239
+ DateTime.type_cast("2/1/1980 11:30").should == DateTime.new(1980, 1, 2, 11, 30)
234
240
  end
235
241
 
236
242
  end
@@ -306,8 +312,8 @@ describe "Conversions" do
306
312
  Time.type_cast(nil).should == nil
307
313
  end
308
314
 
309
- it "tries to convert any other value to a date" do
310
- Time.type_cast("1/2/1980 11:30").should == Time.utc(1980, 2, 1, 11, 30)
315
+ it "tries to convert any other value to a timestamp" do
316
+ Time.type_cast("2/1/1980 11:30").should == Time.utc(1980, 1, 2, 11, 30)
311
317
  end
312
318
 
313
319
  end
@@ -19,7 +19,7 @@ describe MongoODM::Document::Inspect do
19
19
  describe "#inspect" do
20
20
  it "returns a string with the name of the class that includes the MongoODM::Document module and a list of its attributes with values" do
21
21
  circle = Circle.new(:x => 10, :y => 12.5, :radius => 1.2)
22
- circle.inspect.should == "#<Circle x: 10.0, y: 12.5, color: nil, radius: 1.2>"
22
+ circle.inspect.should == "#<Circle color: nil, radius: 1.2, x: 10.0, y: 12.5>"
23
23
  end
24
24
  end
25
25
 
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 1
8
- - 9
9
- version: 0.1.9
7
+ - 2
8
+ - 0
9
+ version: 0.2.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Carlos Paramio
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-06-17 00:00:00 +02:00
17
+ date: 2010-08-29 00:00:00 +02:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -22,14 +22,14 @@ dependencies:
22
22
  requirement: &id001 !ruby/object:Gem::Requirement
23
23
  none: false
24
24
  requirements:
25
- - - "="
25
+ - - ~>
26
26
  - !ruby/object:Gem::Version
27
27
  segments:
28
28
  - 3
29
29
  - 0
30
30
  - 0
31
- - beta3
32
- version: 3.0.0.beta3
31
+ - rc2
32
+ version: 3.0.0.rc2
33
33
  type: :runtime
34
34
  prerelease: false
35
35
  version_requirements: *id001
@@ -38,14 +38,14 @@ dependencies:
38
38
  requirement: &id002 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
- - - "="
41
+ - - ~>
42
42
  - !ruby/object:Gem::Version
43
43
  segments:
44
44
  - 3
45
45
  - 0
46
46
  - 0
47
- - beta3
48
- version: 3.0.0.beta3
47
+ - rc2
48
+ version: 3.0.0.rc2
49
49
  type: :runtime
50
50
  prerelease: false
51
51
  version_requirements: *id002
@@ -59,8 +59,8 @@ dependencies:
59
59
  segments:
60
60
  - 1
61
61
  - 0
62
- - 2
63
- version: 1.0.2
62
+ - 8
63
+ version: 1.0.8
64
64
  type: :runtime
65
65
  prerelease: false
66
66
  version_requirements: *id003
@@ -74,8 +74,8 @@ dependencies:
74
74
  segments:
75
75
  - 1
76
76
  - 0
77
- - 1
78
- version: 1.0.1
77
+ - 5
78
+ version: 1.0.5
79
79
  type: :runtime
80
80
  prerelease: false
81
81
  version_requirements: *id004
@@ -89,8 +89,8 @@ dependencies:
89
89
  segments:
90
90
  - 0
91
91
  - 3
92
- - 22
93
- version: 0.3.22
92
+ - 23
93
+ version: 0.3.23
94
94
  type: :runtime
95
95
  prerelease: false
96
96
  version_requirements: *id005
@@ -99,7 +99,7 @@ dependencies:
99
99
  requirement: &id006 !ruby/object:Gem::Requirement
100
100
  none: false
101
101
  requirements:
102
- - - "="
102
+ - - ~>
103
103
  - !ruby/object:Gem::Version
104
104
  segments:
105
105
  - 1
@@ -114,13 +114,13 @@ dependencies:
114
114
  requirement: &id007 !ruby/object:Gem::Requirement
115
115
  none: false
116
116
  requirements:
117
- - - "="
117
+ - - ~>
118
118
  - !ruby/object:Gem::Version
119
119
  segments:
120
120
  - 0
121
121
  - 5
122
- - 6
123
- version: 0.5.6
122
+ - 8
123
+ version: 0.5.8
124
124
  type: :development
125
125
  prerelease: false
126
126
  version_requirements: *id007
@@ -129,7 +129,7 @@ dependencies:
129
129
  requirement: &id008 !ruby/object:Gem::Requirement
130
130
  none: false
131
131
  requirements:
132
- - - "="
132
+ - - ~>
133
133
  - !ruby/object:Gem::Version
134
134
  segments:
135
135
  - 0
@@ -144,15 +144,15 @@ dependencies:
144
144
  requirement: &id009 !ruby/object:Gem::Requirement
145
145
  none: false
146
146
  requirements:
147
- - - "="
147
+ - - ~>
148
148
  - !ruby/object:Gem::Version
149
149
  segments:
150
150
  - 2
151
151
  - 0
152
152
  - 0
153
153
  - beta
154
- - 12
155
- version: 2.0.0.beta.12
154
+ - 20
155
+ version: 2.0.0.beta.20
156
156
  type: :development
157
157
  prerelease: false
158
158
  version_requirements: *id009
@@ -165,8 +165,8 @@ dependencies:
165
165
  - !ruby/object:Gem::Version
166
166
  segments:
167
167
  - 0
168
- - 6
169
- version: "0.6"
168
+ - 7
169
+ version: "0.7"
170
170
  type: :development
171
171
  prerelease: false
172
172
  version_requirements: *id010
@@ -181,6 +181,7 @@ extra_rdoc_files:
181
181
  - README.rdoc
182
182
  files:
183
183
  - Gemfile
184
+ - Gemfile.lock
184
185
  - LICENSE
185
186
  - README.rdoc
186
187
  - Rakefile