mongomatic 0.5.3 → 0.5.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -81,13 +81,22 @@ module Mongomatic
81
81
 
82
82
  attr_accessor :removed, :is_new, :errors
83
83
 
84
- def initialize(doc={}, is_new=true)
85
- @doc = doc.stringify_keys
84
+ def initialize(doc_hash=Mongomatic::MHash.new, is_new=true)
85
+ self.doc = doc_hash
86
86
  self.removed = false
87
87
  self.is_new = is_new
88
88
  self.errors = Mongomatic::Errors.new
89
89
  end
90
90
 
91
+ def doc=(hash)
92
+ hash = Mongomatic::MHash.new(hash) unless hash.is_a?(Mongomatic::MHash)
93
+ @doc = hash
94
+ end
95
+
96
+ def doc
97
+ @doc
98
+ end
99
+
91
100
  # Override this with your own validate() method for validations.
92
101
  # Simply push your errors into the self.errors property and
93
102
  # if self.errors remains empty your document will be valid.
@@ -121,6 +130,17 @@ module Mongomatic
121
130
  @doc[k.to_s] = v
122
131
  end
123
132
 
133
+ # Returns true if document contains key
134
+ def has_key?(key)
135
+ field, hash = hash_for_field(key.to_s, true)
136
+ hash.has_key?(field)
137
+ end
138
+
139
+ def value_for_key(key)
140
+ field, hash = hash_for_field(key.to_s, true)
141
+ hash[field]
142
+ end
143
+
124
144
  # Fetch a field (just like a hash):
125
145
  # mydoc["name"]
126
146
  # => "Ben"
@@ -147,7 +167,7 @@ module Mongomatic
147
167
  # Reload the document from the database
148
168
  def reload
149
169
  if obj = self.class.find({"_id" => @doc["_id"]}).next_document
150
- @doc = obj.doc; true
170
+ self.doc = obj.doc; true
151
171
  end
152
172
  end
153
173
 
@@ -219,6 +239,19 @@ module Mongomatic
219
239
 
220
240
  protected
221
241
 
242
+ def hash_for_field(field, break_if_dne=false)
243
+ parts = field.split(".")
244
+ curr_hash = self.doc
245
+ return [parts[0], curr_hash] if parts.size == 1
246
+ field = parts.pop # last one is the field
247
+ parts.each_with_index do |part, i|
248
+ return [part, curr_hash] if break_if_dne && !curr_hash.has_key?(part)
249
+ curr_hash[part] ||= {}
250
+ return [field, curr_hash[part]] if parts.size == i+1
251
+ curr_hash = curr_hash[part]
252
+ end
253
+ end
254
+
222
255
  def do_callback(meth)
223
256
  begin
224
257
  send(meth)
@@ -226,13 +259,5 @@ module Mongomatic
226
259
  false
227
260
  end
228
261
  end
229
-
230
- def doc
231
- @doc
232
- end
233
-
234
- def doc=(v)
235
- @doc = v
236
- end
237
262
  end
238
263
  end
@@ -0,0 +1,4 @@
1
+ module Mongomatic
2
+ class MHash < HashWithIndifferentAccess
3
+ end
4
+ end
@@ -4,19 +4,6 @@ module Mongomatic
4
4
 
5
5
  class UnexpectedFieldType < RuntimeError; end
6
6
 
7
- def hash_for_field(field)
8
- parts = field.split(".")
9
- return [parts[0], self.doc] if parts.size == 1
10
- field = parts.pop # last one is the field
11
- curr_hash = self.doc
12
- parts.each_with_index do |part, i|
13
- curr_hash[part] ||= {}
14
- return [field, curr_hash[part]] if parts.size == i+1
15
- curr_hash = curr_hash[part]
16
- end
17
- end
18
- private :hash_for_field
19
-
20
7
  # MongoDB equivalent: { $push : { field : value } }<br/>
21
8
  # Appends value to field, if field is an existing array, otherwise sets field to the array [value]
22
9
  # if field is not present. If field is present but is not an array, error is returned.
data/lib/mongomatic.rb CHANGED
@@ -29,6 +29,7 @@ module Mongomatic
29
29
  end
30
30
  end
31
31
 
32
+ require "#{File.dirname(__FILE__)}/mongomatic/m_hash"
32
33
  require "#{File.dirname(__FILE__)}/mongomatic/cursor"
33
34
  require "#{File.dirname(__FILE__)}/mongomatic/modifiers"
34
35
  require "#{File.dirname(__FILE__)}/mongomatic/errors"
@@ -1,6 +1,23 @@
1
1
  require 'helper'
2
2
 
3
3
  class TestMongomatic < Test::Unit::TestCase
4
+ should "treat all keys as strings" do
5
+ Person.collection.drop
6
+ p1 = Person.new(:name => "Jordan")
7
+ p1[:address] = { :city => "San Francisco" }
8
+ assert_equal "Jordan", p1["name"]
9
+ assert_equal "Jordan", p1[:name]
10
+ assert_equal "San Francisco", p1["address"]["city"]
11
+ assert_equal "San Francisco", p1[:address][:city]
12
+ p1.insert
13
+
14
+ p1 = Person.find_one(:name => "Jordan")
15
+ assert_equal "Jordan", p1["name"]
16
+ assert_equal "Jordan", p1[:name]
17
+ assert_equal "San Francisco", p1["address"]["city"]
18
+ assert_equal "San Francisco", p1[:address][:city]
19
+ end
20
+
4
21
  should "find one with a query" do
5
22
  Person.collection.drop
6
23
  p1 = Person.new(:name => "Jordan")
@@ -549,4 +566,40 @@ class TestMongomatic < Test::Unit::TestCase
549
566
  p.valid?
550
567
  assert_equal 'Hair color must exist', p.errors.on(:hair_color)
551
568
  end
569
+
570
+ should "be able to use has_key?" do
571
+ p = Person.new
572
+
573
+ assert !p.has_key?(:name)
574
+
575
+ p['name'] = 'Jordan'
576
+
577
+ assert p.has_key?(:name)
578
+ assert p.has_key?('name')
579
+ end
580
+
581
+ should "be able to reach into keys with has_key?" do
582
+ p = Person.new(:employer => {:name => 'Meta+Level Games',
583
+ :function => 'Makes things with code',
584
+ :something_else => {
585
+ :with_a_key => 'And Value'}
586
+ })
587
+
588
+ assert !p.has_key?('employer.started_at')
589
+ assert p.has_key?('employer.name')
590
+ assert !p.has_key?('non.existent')
591
+ assert !p.has_key?('employer.something_else.not_here')
592
+ assert p.has_key?('employer.something_else.with_a_key')
593
+ end
594
+
595
+ should "be able to get the value for a key in an embedded doc" do
596
+ p = Person.new(:employer => {:name => 'Meta+Level Games',
597
+ :function => 'Makes things with code',
598
+ :something_else => {
599
+ :with_a_key => 'And Value'}
600
+ })
601
+ assert_equal "And Value", p.value_for_key("employer.something_else.with_a_key")
602
+ assert_equal "Meta+Level Games", p.value_for_key("employer.name")
603
+ assert_nil p.value_for_key("some_key.that_does_not.exist")
604
+ end
552
605
  end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 5
8
- - 3
9
- version: 0.5.3
8
+ - 4
9
+ version: 0.5.4
10
10
  platform: ruby
11
11
  authors:
12
12
  - Ben Myles
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-09-08 00:00:00 -07:00
17
+ date: 2010-09-10 00:00:00 -07:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -97,6 +97,7 @@ files:
97
97
  - lib/mongomatic/expectations/match.rb
98
98
  - lib/mongomatic/expectations/of_length.rb
99
99
  - lib/mongomatic/expectations/present.rb
100
+ - lib/mongomatic/m_hash.rb
100
101
  - lib/mongomatic/modifiers.rb
101
102
  - LICENSE
102
103
  - README.rdoc