mongo_hash 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/mongo_hash.rb +175 -0
- metadata +57 -0
data/lib/mongo_hash.rb
ADDED
@@ -0,0 +1,175 @@
|
|
1
|
+
class MongoHash < Hash
|
2
|
+
attr_accessor :collection
|
3
|
+
attr_accessor :new_record
|
4
|
+
attr_accessor :subkey
|
5
|
+
attr_accessor :_id
|
6
|
+
attr_accessor :query_hash
|
7
|
+
attr_accessor :fields
|
8
|
+
attr_accessor :dirty_keys
|
9
|
+
attr_accessor :delete_keys
|
10
|
+
|
11
|
+
|
12
|
+
### figure out how to make this one method
|
13
|
+
def get_options_specifier(subkey)
|
14
|
+
if subkey == ""
|
15
|
+
{}
|
16
|
+
else
|
17
|
+
{:fields => {'_id' => 1, subkey => 1}}
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.get_options_specifier(subkey)
|
22
|
+
if subkey == ""
|
23
|
+
{}
|
24
|
+
else
|
25
|
+
{:fields => {'_id' => 1, subkey => 1}}
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# Main find method to use for searching the mongo collection for a matching object
|
30
|
+
#
|
31
|
+
# @param [Mongo::Collection] the mongo collection object
|
32
|
+
# @param [Hash] the query specifier, in standard mongodb syntax, optional
|
33
|
+
# @param [String] the subkey attribute to base the return on, optional
|
34
|
+
# @return [Array] the list of matching MongoHash objects from the collection
|
35
|
+
|
36
|
+
def self.find(collection, query = {}, subkey = "")
|
37
|
+
options_specifier = get_options_specifier(subkey)
|
38
|
+
records = collection.find(query, options_specifier)
|
39
|
+
return [] if records.nil? or records == [] or records.count == 0
|
40
|
+
mhs = []
|
41
|
+
records.each{|record|
|
42
|
+
mhs << self.new(collection, record['_id'], record, subkey)
|
43
|
+
}
|
44
|
+
mhs
|
45
|
+
end
|
46
|
+
|
47
|
+
# Finds matching objects, or creates a blank one if not
|
48
|
+
#
|
49
|
+
# @todo Infer default values from the query specifier
|
50
|
+
# @param [Mongo::Collection] the mongo collection object
|
51
|
+
# @param [Hash] the query specifier, in standard mongodb syntax, optional
|
52
|
+
# @param [String] the subkey attribute to base the return on, optional
|
53
|
+
# @return [Array] the list of matching MongoHash objects from the collection, or an array with a blank MongoHash object if none found
|
54
|
+
|
55
|
+
def self.find_or_create(collection, query = {}, subkey = "")
|
56
|
+
result = self.find(collection, query, subkey)
|
57
|
+
if result == []
|
58
|
+
result = [self.new(collection)]
|
59
|
+
else
|
60
|
+
result
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# MongoHash.new creates a new blank object tied to the specified collection or retrieves a specific object
|
65
|
+
#
|
66
|
+
# @param [Mongo::Collection] the mongo collection object
|
67
|
+
# @param [Object] the _id to query the collection for, optional
|
68
|
+
# @param [Hash] the default value to prepopulate into the returned object, optional
|
69
|
+
# @param [String] the subkey attribute to base the return on, optional
|
70
|
+
# @return [MongoHash] a single MongoHash object tied to the specified collection
|
71
|
+
|
72
|
+
def initialize(collection, _id = nil, default = {}, subkey = "")
|
73
|
+
@subkey = subkey
|
74
|
+
@collection = collection
|
75
|
+
if _id.nil?
|
76
|
+
@new_record = true
|
77
|
+
else
|
78
|
+
@_id = _id
|
79
|
+
@new_record = false
|
80
|
+
end
|
81
|
+
@dirty_keys = []
|
82
|
+
@delete_keys = []
|
83
|
+
# super() {|h, k| h[k] = Hash.new()}
|
84
|
+
super()
|
85
|
+
if default == {}
|
86
|
+
# puts default.inspect
|
87
|
+
# puts _id
|
88
|
+
unless @new_record
|
89
|
+
options_specifier = self.get_options_specifier(subkey)
|
90
|
+
default = collection.find({'_id' => _id}, options_specifier).first
|
91
|
+
end
|
92
|
+
end
|
93
|
+
default.delete('_id')
|
94
|
+
default.delete(:_id)
|
95
|
+
default.each{|k,v|
|
96
|
+
# puts [k,v].inspect
|
97
|
+
self[k] = v
|
98
|
+
} unless default.nil? or default.keys.length == 0
|
99
|
+
@dirty_keys = []
|
100
|
+
@delete_keys = []
|
101
|
+
end
|
102
|
+
|
103
|
+
# Overrides key assignment with mongohash metadata
|
104
|
+
|
105
|
+
def []=(key,value)
|
106
|
+
@dirty_keys << key
|
107
|
+
@delete_keys -= [key]
|
108
|
+
super
|
109
|
+
end
|
110
|
+
|
111
|
+
# Overrides delete assignment with mongohash metadata
|
112
|
+
|
113
|
+
def delete(key, mark = true)
|
114
|
+
if mark == true
|
115
|
+
@delete_keys << key
|
116
|
+
end
|
117
|
+
super(key)
|
118
|
+
end
|
119
|
+
|
120
|
+
# Removes the tied object from the mongo collection
|
121
|
+
|
122
|
+
def destroy()
|
123
|
+
unless @new_record == true
|
124
|
+
retval = @collection.remove({'_id' => self._id}, :safe => true)
|
125
|
+
@new_record = true
|
126
|
+
self._id = nil
|
127
|
+
## maybe some other things
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
# Persists the tied object to the mongo collection
|
132
|
+
# if a new record, assigns self._id after success
|
133
|
+
# if no keys have been modified, returns immediately
|
134
|
+
# attempts to be smart about updating individual keys instead of overwriting entire record
|
135
|
+
|
136
|
+
def save()
|
137
|
+
@dirty_keys.uniq!
|
138
|
+
@delete_keys.uniq!
|
139
|
+
if @subkey == ""
|
140
|
+
return nil if @dirty_keys.length == 0 and @delete_keys.length == 0
|
141
|
+
end
|
142
|
+
|
143
|
+
if @new_record == true
|
144
|
+
self['created_at'] = Time.now.to_i
|
145
|
+
id = @collection.insert(self, :safe => true)
|
146
|
+
self._id = id
|
147
|
+
self.delete(:_id, false)
|
148
|
+
@new_record = false
|
149
|
+
else
|
150
|
+
self['updated_at'] = Time.now.to_i
|
151
|
+
|
152
|
+
## @todo: what if the object with that key doesn't exist in the db when it's saved?
|
153
|
+
|
154
|
+
if @subkey == ""
|
155
|
+
if (@dirty_keys.length + @delete_keys.length) < self.keys.length / 2
|
156
|
+
update_hash = {}
|
157
|
+
@dirty_keys.map{|key| update_hash[key] = self[key]}
|
158
|
+
delete_hash = {}
|
159
|
+
@delete_keys.map{|key| delete_hash[key] = 1}
|
160
|
+
@collection.update({'_id' => self._id}, {'$unset' => delete_hash, '$set' => update_hash }, :safe => true)
|
161
|
+
|
162
|
+
retval = true
|
163
|
+
else
|
164
|
+
retval = @collection.update({'_id' => self._id}, self, :safe => true)
|
165
|
+
end
|
166
|
+
else
|
167
|
+
retval = @collection.update({'_id' => self._id}, {'$set' => {@subkey => self[@subkey]} }, :safe => true)
|
168
|
+
end
|
169
|
+
end
|
170
|
+
@delete_keys = []
|
171
|
+
@dirty_keys = []
|
172
|
+
retval
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
metadata
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mongo_hash
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Adam Fields
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-11-11 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: mongo
|
16
|
+
requirement: &70199814585480 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70199814585480
|
25
|
+
description: A simple front-end for mongodb persistence for ruby hashes
|
26
|
+
email: adam@morningside-analytics.com
|
27
|
+
executables: []
|
28
|
+
extensions: []
|
29
|
+
extra_rdoc_files: []
|
30
|
+
files:
|
31
|
+
- lib/mongo_hash.rb
|
32
|
+
homepage: http://rubygems.org/gems/mongo_hash
|
33
|
+
licenses: []
|
34
|
+
post_install_message:
|
35
|
+
rdoc_options: []
|
36
|
+
require_paths:
|
37
|
+
- lib
|
38
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
45
|
+
none: false
|
46
|
+
requirements:
|
47
|
+
- - ! '>='
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '0'
|
50
|
+
requirements:
|
51
|
+
- Mongo Gem
|
52
|
+
rubyforge_project:
|
53
|
+
rubygems_version: 1.8.15
|
54
|
+
signing_key:
|
55
|
+
specification_version: 3
|
56
|
+
summary: MongoHash
|
57
|
+
test_files: []
|