mince_mongo_db 1.0.0.pre.1

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.
@@ -0,0 +1,45 @@
1
+ module Mince # :nodoc:
2
+ module MongoDb # :nodoc:
3
+ require 'singleton'
4
+
5
+ # = Config
6
+ #
7
+ # Config specifies the configuration settings
8
+ #
9
+ # @author Matt Simpson
10
+ class Config
11
+ include Singleton
12
+
13
+ # Returns the primary key identifier for records. This is necessary because not all databases use the same
14
+ # primary key.
15
+ #
16
+ # @return [Symbol] the name of the primary key field.
17
+ def self.primary_key
18
+ instance.primary_key
19
+ end
20
+
21
+ def self.database_name
22
+ instance.database_name
23
+ end
24
+
25
+ def self.database_name=(val)
26
+ instance.database_name = val
27
+ end
28
+
29
+ def self.test_env_number
30
+ ENV['TEST_ENV_NUMBER']
31
+ end
32
+
33
+ attr_accessor :primary_key, :database_name
34
+
35
+ def initialize
36
+ self.primary_key = :_id
37
+ self.database_name = 'mince'
38
+ end
39
+
40
+ def database_name=(name)
41
+ @database_name = [name, self.class.test_env_number].compact.join("-")
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,34 @@
1
+ module Mince
2
+ module MongoDb
3
+ require_relative 'config'
4
+ require 'mongo'
5
+ require 'singleton'
6
+
7
+ class Connection
8
+ include Singleton
9
+
10
+ attr_accessor :connection, :db
11
+
12
+ def self.connection
13
+ instance.connection
14
+ end
15
+
16
+ def self.db
17
+ instance.db
18
+ end
19
+
20
+ def initialize
21
+ self.connection = Mongo::Connection.new
22
+ end
23
+
24
+ def connection=(con)
25
+ @connection = con
26
+ self.db = connection.db(database_name)
27
+ end
28
+
29
+ def database_name
30
+ Config.database_name
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,28 @@
1
+ module Mince
2
+ module MongoDb
3
+ require 'singleton'
4
+ require_relative 'connection'
5
+
6
+ class DataStore
7
+ include Singleton
8
+
9
+ def self.collection(collection_name)
10
+ instance.collection(collection_name)
11
+ end
12
+
13
+ def self.db
14
+ instance.db
15
+ end
16
+
17
+ def collection(collection_name)
18
+ db.collection(collection_name)
19
+ end
20
+
21
+ attr_accessor :db
22
+
23
+ def initialize
24
+ self.db = Mince::MongoDb::Connection.db
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,114 @@
1
+ module Mince
2
+ module MongoDb
3
+ module Interface
4
+ require_relative 'data_store'
5
+ require_relative 'config'
6
+
7
+ def self.generate_unique_id(*args)
8
+ BSON::ObjectId.new.to_s
9
+ end
10
+
11
+ def self.primary_key
12
+ Config.primary_key
13
+ end
14
+
15
+ def self.delete_field(collection_name, key)
16
+ collection(collection_name).update({}, {"$unset" => { key => 1 } }, multi: true)
17
+ end
18
+
19
+ def self.delete_by_params(collection_name, params)
20
+ collection(collection_name).remove(params)
21
+ end
22
+
23
+ def self.add(collection_name, hash)
24
+ collection(collection_name).insert(hash)
25
+ end
26
+
27
+ def self.replace(collection_name, hash)
28
+ collection(collection_name).update({primary_key => hash[primary_key]}, hash)
29
+ end
30
+
31
+ def self.update_field_with_value(collection_name, primary_key_value, field_name, new_value)
32
+ collection(collection_name).update({primary_key => primary_key_value}, {'$set' => { field_name => new_value } })
33
+ end
34
+
35
+ def self.increment_field_by_amount(collection_name, primary_key_value, field_name, amount)
36
+ collection(collection_name).update({primary_key => primary_key_value}, {'$inc' => { field_name => amount } })
37
+ end
38
+
39
+ def self.get_all_for_key_with_value(collection_name, key, value)
40
+ get_by_params(collection_name, key.to_s => value)
41
+ end
42
+
43
+ def self.get_for_key_with_value(collection_name, key, value)
44
+ get_all_for_key_with_value(collection_name, key, value).first
45
+ end
46
+
47
+ def self.get_by_params(collection_name, hash)
48
+ collection(collection_name).find(hash)
49
+ end
50
+
51
+ def self.find_all(collection_name)
52
+ collection(collection_name).find
53
+ end
54
+
55
+ def self.find(collection_name, key, value)
56
+ collection(collection_name).find_one({key.to_s => value})
57
+ end
58
+
59
+ def self.push_to_array(collection_name, identifying_key, identifying_value, array_key, value_to_push)
60
+ collection(collection_name).update({identifying_key.to_s => identifying_value}, {'$push' => {array_key.to_s => value_to_push}})
61
+ end
62
+
63
+ def self.remove_from_array(collection_name, identifying_key, identifying_value, array_key, value_to_remove)
64
+ collection(collection_name).update({identifying_key.to_s => identifying_value}, {'$pull' => {array_key.to_s => value_to_remove}})
65
+ end
66
+
67
+ def self.containing_any(collection_name, key, values)
68
+ collection(collection_name).find({key.to_s => {"$in" => values}})
69
+ end
70
+
71
+ def self.array_contains(collection_name, key, value)
72
+ collection(collection_name).find(key.to_s => value)
73
+ end
74
+
75
+ def self.clear
76
+ db.collection_names.each do |collection_name|
77
+ db.drop_collection collection_name unless collection_name.include?('system')
78
+ end
79
+ end
80
+
81
+ def self.delete_collection(collection_name)
82
+ collection(collection_name).drop
83
+ end
84
+
85
+ def self.insert(collection_name, data)
86
+ data.each do |datum|
87
+ add collection_name, datum
88
+ end
89
+ end
90
+
91
+ def self.set_data(data)
92
+ clear
93
+
94
+ data.each do |key, value|
95
+ insert key, value
96
+ end
97
+ end
98
+
99
+ def self.data
100
+ db.collection_names.map do |collection_name|
101
+ find_all collection_name
102
+ end
103
+ end
104
+
105
+ def self.collection(collection_name)
106
+ DataStore.collection(collection_name)
107
+ end
108
+
109
+ def self.db
110
+ DataStore.db
111
+ end
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,21 @@
1
+ module Mince
2
+ module MongoDb
3
+ module Version
4
+ def self.major
5
+ 1
6
+ end
7
+
8
+ def self.minor
9
+ 0
10
+ end
11
+
12
+ def self.patch
13
+ "0.pre.1"
14
+ end
15
+ end
16
+
17
+ def self.version
18
+ [Version.major, Version.minor, Version.patch].join(".")
19
+ end
20
+ end
21
+ end
data/lib/mongo_db.rb ADDED
@@ -0,0 +1,9 @@
1
+ module Mince
2
+ module MongoDb
3
+ require_relative 'mongo_db/config'
4
+ require_relative 'mongo_db/connection'
5
+ require_relative 'mongo_db/version'
6
+ require_relative 'mongo_db/data_store'
7
+ require_relative 'mongo_db/interface'
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ require_relative '../../lib/mongo_db'
2
+ require 'mince/shared_examples/interface_example'
3
+
4
+ describe 'Mince Interface with MongoDb' do
5
+ before do
6
+ Mince::Config.interface = Mince::MongoDb::Interface
7
+ end
8
+
9
+ it_behaves_like 'a mince interface'
10
+ end
11
+
@@ -0,0 +1,40 @@
1
+ require_relative '../../../lib/mongo_db/config'
2
+
3
+ describe Mince::MongoDb::Config do
4
+ it 'contains the primary key to used by the db interface' do
5
+ described_class.primary_key.should == :_id
6
+ end
7
+
8
+ describe 'the database name' do
9
+ subject { described_class.database_name }
10
+
11
+ it 'by default is "mince"' do
12
+ subject.should == 'mince'
13
+ end
14
+
15
+ it 'can be explicitly defined' do
16
+ described_class.database_name = 'custom_db_name'
17
+
18
+ subject.should == 'custom_db_name'
19
+
20
+ # Change name back because it is a singleton object
21
+ described_class.database_name = 'mince'
22
+ end
23
+
24
+ context 'when running parallel tests' do
25
+ before do
26
+ # Stubbing described_class because the method gets value from an environment
27
+ # variable, which is dangerous to change inside of a test and dangerous to
28
+ # stub
29
+ described_class.stub(:test_env_number => '1')
30
+
31
+ # Change name so that the test number is appended
32
+ described_class.database_name = 'mince'
33
+ end
34
+
35
+ it 'appends the test number to the db name' do
36
+ subject.should == 'mince-1'
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,18 @@
1
+ require_relative '../../../lib/mongo_db/connection'
2
+
3
+ describe Mince::MongoDb::Connection do
4
+ subject { described_class.instance }
5
+
6
+ let(:mongo_connection) { mock 'a mongo connection object', :db => db }
7
+ let(:db) { mock 'db'}
8
+ let(:database_name) { mock }
9
+
10
+ before do
11
+ Mince::MongoDb::Config.stub(database_name: database_name)
12
+ subject.connection = mongo_connection
13
+ end
14
+
15
+ it 'is a mongo connection' do
16
+ subject.connection.should == mongo_connection
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ require_relative '../../../lib/mongo_db/data_store'
2
+
3
+ describe Mince::MongoDb::DataStore do
4
+ let(:db) { mock }
5
+ let(:collection) { mock }
6
+ let(:collection_name) { mock }
7
+
8
+ before do
9
+ described_class.instance.db = db
10
+ end
11
+
12
+ it 'can return a specific collection and provides access to the db' do
13
+ db.stub(:collection).with(collection_name).and_return(collection)
14
+
15
+ described_class.collection(collection_name).should == collection
16
+ described_class.db.should == db
17
+ end
18
+ end
@@ -0,0 +1,146 @@
1
+ require_relative '../../../lib/mongo_db/interface'
2
+
3
+ describe Mince::MongoDb::Interface do
4
+
5
+ let(:interface) { described_class }
6
+ let(:primary_key) { Mince::MongoDb::Config.primary_key }
7
+
8
+ let(:db) { mock 'mongo database' }
9
+ let(:mongo_data_store_connection) { mock 'mongo_data_store_connection', :db => db}
10
+ let(:collection) { mock 'some collection'}
11
+ let(:collection_name) { 'some_collection_name'}
12
+ let(:primary_key) { mock 'primary key'}
13
+ let(:mock_id) { mock 'id' }
14
+ let(:data) { { primary_key => mock_id}}
15
+ let(:return_data) { mock 'return data' }
16
+
17
+ before do
18
+ Mince::MongoDb::DataStore.stub(:db).and_return(db)
19
+ Mince::MongoDb::DataStore.stub(:collection).with(collection_name).and_return(collection)
20
+ Mince::MongoDb::Config.stub(primary_key: primary_key)
21
+ end
22
+
23
+ it 'uses the correct collection' do
24
+ interface.collection(collection_name).should == collection
25
+ end
26
+
27
+ it 'can delete a field' do
28
+ field = mock 'field to delete'
29
+ collection.should_receive(:update).with({}, {'$unset' => { field => 1 } }, multi: true)
30
+
31
+ interface.delete_field(collection_name, field)
32
+ end
33
+
34
+ it 'can delete all records the match a given set of params' do
35
+ params = mock 'params to condition the deleted records to'
36
+ collection.should_receive(:remove).with(params)
37
+
38
+ interface.delete_by_params(collection_name, params)
39
+ end
40
+
41
+ it 'can delete a collection' do
42
+ collection.should_receive(:drop)
43
+
44
+ interface.delete_collection(collection_name)
45
+ end
46
+
47
+ describe "Generating a primary key" do
48
+ let(:unique_id) { mock 'id' }
49
+ it 'should create a reasonably unique id' do
50
+ BSON::ObjectId.should_receive(:new).and_return(unique_id)
51
+
52
+ described_class.generate_unique_id('something').should == unique_id.to_s
53
+ end
54
+ end
55
+
56
+ it 'can write to the collection' do
57
+ collection.should_receive(:insert).with(data).and_return(return_data)
58
+
59
+ interface.add(collection_name, data).should == return_data
60
+ end
61
+
62
+ it 'can update a field with a specific value' do
63
+ key = mock 'key'
64
+ value = mock 'value'
65
+ id = mock 'id'
66
+ collection.should_receive(:update).with({ primary_key => id }, { '$set' => { key => value } })
67
+
68
+ interface.update_field_with_value collection_name, id, key, value
69
+ end
70
+
71
+ it 'can increment a field by a specific amount' do
72
+ key = mock 'key'
73
+ amount = mock 'amount to increment the field by'
74
+ id = mock 'id'
75
+ collection.should_receive(:update).with({ primary_key => id }, { '$inc' => { key => amount } })
76
+
77
+ interface.increment_field_by_amount collection_name, id, key, amount
78
+ end
79
+
80
+ it 'can read from the collection' do
81
+ collection.should_receive(:find).and_return(return_data)
82
+
83
+ interface.find_all(collection_name).should == return_data
84
+ end
85
+
86
+ it 'can replace a record' do
87
+ collection.should_receive(:update).with({primary_key => data[primary_key]}, data)
88
+
89
+ interface.replace(collection_name, data)
90
+ end
91
+
92
+ it 'can get one document' do
93
+ field = "stuff"
94
+ value = "more stuff"
95
+
96
+ collection.should_receive(:find_one).with(field => value).and_return(return_data)
97
+
98
+ interface.find(collection_name, field, value).should == return_data
99
+ end
100
+
101
+ it 'can clear the data store' do
102
+ collection_names = %w(collection_1 collection_2 system_profiles)
103
+ db.stub(:collection_names => collection_names)
104
+
105
+ db.should_receive(:drop_collection).with('collection_1')
106
+ db.should_receive(:drop_collection).with('collection_2')
107
+
108
+ interface.clear
109
+ end
110
+
111
+ it 'can get all records of a specific key value' do
112
+ collection.should_receive(:find).with({"key" => "value"}).and_return(return_data)
113
+
114
+ interface.get_all_for_key_with_value(collection_name, "key", "value").should == return_data
115
+ end
116
+
117
+ it 'can get a record of a specific key value' do
118
+ collection.should_receive(:find).with({"key" => "value"}).and_return([return_data])
119
+
120
+ interface.get_for_key_with_value(collection_name, "key", "value").should == return_data
121
+ end
122
+
123
+ it 'can get all records where a value includes any of a set of values' do
124
+ collection.should_receive(:find).with({"key1" => { "$in" => [1,2,4]} }).and_return(return_data)
125
+
126
+ interface.containing_any(collection_name, "key1", [1,2,4]).should == return_data
127
+ end
128
+
129
+ it 'can get all records where the array includes a value' do
130
+ collection.should_receive(:find).with({"key" => "value"}).and_return(return_data)
131
+
132
+ interface.array_contains(collection_name, "key", "value").should == return_data
133
+ end
134
+
135
+ it 'can push a value to an array for a specific record' do
136
+ collection.should_receive(:update).with({"key" => "value"}, { '$push' => { "array_key" => "value_to_push"}}).and_return(return_data)
137
+
138
+ interface.push_to_array(collection_name, :key, "value", :array_key, "value_to_push").should == return_data
139
+ end
140
+
141
+ it 'can remove a value from an array for a specific record' do
142
+ collection.should_receive(:update).with({"key" => "value"}, { '$pull' => { "array_key" => "value_to_remove"}}).and_return(return_data)
143
+
144
+ interface.remove_from_array(collection_name, :key, "value", :array_key, "value_to_remove").should == return_data
145
+ end
146
+ end
metadata ADDED
@@ -0,0 +1,244 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mince_mongo_db
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0.pre.1
5
+ prerelease: 6
6
+ platform: ruby
7
+ authors:
8
+ - Matt Simpson
9
+ - Jason Mayer
10
+ - Asynchrony
11
+ autorequire:
12
+ bindir: bin
13
+ cert_chain: []
14
+ date: 2012-11-01 00:00:00.000000000 Z
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: mongo
18
+ requirement: !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ~>
22
+ - !ruby/object:Gem::Version
23
+ version: 1.5.2
24
+ type: :runtime
25
+ prerelease: false
26
+ version_requirements: !ruby/object:Gem::Requirement
27
+ none: false
28
+ requirements:
29
+ - - ~>
30
+ - !ruby/object:Gem::Version
31
+ version: 1.5.2
32
+ - !ruby/object:Gem::Dependency
33
+ name: bson_ext
34
+ requirement: !ruby/object:Gem::Requirement
35
+ none: false
36
+ requirements:
37
+ - - ~>
38
+ - !ruby/object:Gem::Version
39
+ version: 1.5.2
40
+ type: :runtime
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ none: false
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: 1.5.2
48
+ - !ruby/object:Gem::Dependency
49
+ name: activesupport
50
+ requirement: !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ~>
54
+ - !ruby/object:Gem::Version
55
+ version: '3.0'
56
+ type: :runtime
57
+ prerelease: false
58
+ version_requirements: !ruby/object:Gem::Requirement
59
+ none: false
60
+ requirements:
61
+ - - ~>
62
+ - !ruby/object:Gem::Version
63
+ version: '3.0'
64
+ - !ruby/object:Gem::Dependency
65
+ name: rake
66
+ requirement: !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ~>
70
+ - !ruby/object:Gem::Version
71
+ version: '0.9'
72
+ type: :development
73
+ prerelease: false
74
+ version_requirements: !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ~>
78
+ - !ruby/object:Gem::Version
79
+ version: '0.9'
80
+ - !ruby/object:Gem::Dependency
81
+ name: rspec
82
+ requirement: !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ~>
86
+ - !ruby/object:Gem::Version
87
+ version: '2.0'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: !ruby/object:Gem::Requirement
91
+ none: false
92
+ requirements:
93
+ - - ~>
94
+ - !ruby/object:Gem::Version
95
+ version: '2.0'
96
+ - !ruby/object:Gem::Dependency
97
+ name: guard-rspec
98
+ requirement: !ruby/object:Gem::Requirement
99
+ none: false
100
+ requirements:
101
+ - - ~>
102
+ - !ruby/object:Gem::Version
103
+ version: '0.6'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ none: false
108
+ requirements:
109
+ - - ~>
110
+ - !ruby/object:Gem::Version
111
+ version: '0.6'
112
+ - !ruby/object:Gem::Dependency
113
+ name: yard
114
+ requirement: !ruby/object:Gem::Requirement
115
+ none: false
116
+ requirements:
117
+ - - ~>
118
+ - !ruby/object:Gem::Version
119
+ version: '0.7'
120
+ type: :development
121
+ prerelease: false
122
+ version_requirements: !ruby/object:Gem::Requirement
123
+ none: false
124
+ requirements:
125
+ - - ~>
126
+ - !ruby/object:Gem::Version
127
+ version: '0.7'
128
+ - !ruby/object:Gem::Dependency
129
+ name: redcarpet
130
+ requirement: !ruby/object:Gem::Requirement
131
+ none: false
132
+ requirements:
133
+ - - ~>
134
+ - !ruby/object:Gem::Version
135
+ version: '2.1'
136
+ type: :development
137
+ prerelease: false
138
+ version_requirements: !ruby/object:Gem::Requirement
139
+ none: false
140
+ requirements:
141
+ - - ~>
142
+ - !ruby/object:Gem::Version
143
+ version: '2.1'
144
+ - !ruby/object:Gem::Dependency
145
+ name: debugger
146
+ requirement: !ruby/object:Gem::Requirement
147
+ none: false
148
+ requirements:
149
+ - - ~>
150
+ - !ruby/object:Gem::Version
151
+ version: '1.2'
152
+ type: :development
153
+ prerelease: false
154
+ version_requirements: !ruby/object:Gem::Requirement
155
+ none: false
156
+ requirements:
157
+ - - ~>
158
+ - !ruby/object:Gem::Version
159
+ version: '1.2'
160
+ - !ruby/object:Gem::Dependency
161
+ name: mince
162
+ requirement: !ruby/object:Gem::Requirement
163
+ none: false
164
+ requirements:
165
+ - - '='
166
+ - !ruby/object:Gem::Version
167
+ version: 2.0.0.pre.2
168
+ type: :development
169
+ prerelease: false
170
+ version_requirements: !ruby/object:Gem::Requirement
171
+ none: false
172
+ requirements:
173
+ - - '='
174
+ - !ruby/object:Gem::Version
175
+ version: 2.0.0.pre.2
176
+ - !ruby/object:Gem::Dependency
177
+ name: rb-fsevent
178
+ requirement: !ruby/object:Gem::Requirement
179
+ none: false
180
+ requirements:
181
+ - - ~>
182
+ - !ruby/object:Gem::Version
183
+ version: 0.9.0
184
+ type: :development
185
+ prerelease: false
186
+ version_requirements: !ruby/object:Gem::Requirement
187
+ none: false
188
+ requirements:
189
+ - - ~>
190
+ - !ruby/object:Gem::Version
191
+ version: 0.9.0
192
+ description: Mince interface library to provide a lightweight MongoDB ORM for Ruby.
193
+ email:
194
+ - matt@railsgrammer.com
195
+ - jason.mayer@gmail.com
196
+ executables: []
197
+ extensions: []
198
+ extra_rdoc_files: []
199
+ files:
200
+ - lib/mongo_db.rb
201
+ - lib/mongo_db/config.rb
202
+ - lib/mongo_db/connection.rb
203
+ - lib/mongo_db/data_store.rb
204
+ - lib/mongo_db/interface.rb
205
+ - lib/mongo_db/version.rb
206
+ - spec/integration/mince_interface_spec.rb
207
+ - spec/units/mongo_db/config_spec.rb
208
+ - spec/units/mongo_db/connection_spec.rb
209
+ - spec/units/mongo_db/data_store_spec.rb
210
+ - spec/units/mongo_db/interface_spec.rb
211
+ homepage: https://github.com/coffeencoke/mince_mongo_db
212
+ licenses: []
213
+ post_install_message:
214
+ rdoc_options: []
215
+ require_paths:
216
+ - lib
217
+ required_ruby_version: !ruby/object:Gem::Requirement
218
+ none: false
219
+ requirements:
220
+ - - ! '>='
221
+ - !ruby/object:Gem::Version
222
+ version: '0'
223
+ segments:
224
+ - 0
225
+ hash: 682498058529759032
226
+ required_rubygems_version: !ruby/object:Gem::Requirement
227
+ none: false
228
+ requirements:
229
+ - - ! '>'
230
+ - !ruby/object:Gem::Version
231
+ version: 1.3.1
232
+ requirements: []
233
+ rubyforge_project: mince_mongo_db
234
+ rubygems_version: 1.8.24
235
+ signing_key:
236
+ specification_version: 3
237
+ summary: Lightweight MongoDB ORM for Ruby.
238
+ test_files:
239
+ - spec/integration/mince_interface_spec.rb
240
+ - spec/units/mongo_db/config_spec.rb
241
+ - spec/units/mongo_db/connection_spec.rb
242
+ - spec/units/mongo_db/data_store_spec.rb
243
+ - spec/units/mongo_db/interface_spec.rb
244
+ has_rdoc: