hashy_db 1.1.0 → 2.0.0.pre

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,18 @@
1
+ module Mince
2
+ module HashyDb # :nodoc:
3
+ # = HashyDb Config
4
+ #
5
+ # HashyDb Config specifies the configuration settings for HashyDb
6
+ #
7
+ # @author Matt Simpson
8
+ module Config
9
+ # Returns the primary key identifier for records. This is necessary because not all databases use the same
10
+ # primary key.
11
+ #
12
+ # @return [Symbol] the name of the primary key field.
13
+ def self.primary_key
14
+ :id
15
+ end
16
+ end
17
+ end
18
+ end
@@ -1,123 +1,55 @@
1
- # SRP: Model with implementation on how to store each collection in a data store
2
- require 'singleton'
3
- require 'active_support/core_ext/module/delegation'
4
- require 'digest'
5
-
6
- module HashyDb
7
- class DataStore
8
- include Singleton
9
-
10
- def self.primary_key_identifier
11
- :id
12
- end
13
-
14
- def self.generate_unique_id(salt)
15
- Digest::SHA256.hexdigest("#{Time.current.utc}#{salt}")[0..6]
16
- end
17
-
18
- def delete_field(collection_name, field)
19
- find_all(collection_name).each do |row|
20
- row.delete(field)
1
+ module Mince
2
+ module HashyDb # :nodoc:
3
+ require 'singleton'
4
+
5
+ # = HashyDb Data Store
6
+ #
7
+ # HashyDb Data Store stores and retrieves data from a ruby in-memory hash.
8
+ #
9
+ # Using this library offers more extensibility and growth for your application. If at any point in time
10
+ # you want to support a different database for all, or even one, of your classes, you only need to implement
11
+ # the few methods defined in this class.
12
+ #
13
+ # HashyDb Data Store is a singleton object that provides class level interface to the singleton instance.
14
+ #
15
+ # Mince::HashyDb::DataStore.instance # => Mince::HashyDb::DataStore object
16
+ # Mince::HashyDb::DataStore.data # => returns all data stored in the HashyDb database
17
+ # Mince::HashyDb::DataStore.collection(:some_collection) # => returns all data stored in a specific collection in the HashyDb database
18
+ #
19
+ # @author Matt Simpson
20
+ class DataStore
21
+ include Singleton
22
+
23
+ # Sets the entire data store, for all collections
24
+ #
25
+ # @param [Hash] hash the hash to replace the entire data store with
26
+ def self.set_data(hash)
27
+ instance.data = hash
21
28
  end
22
- end
23
-
24
- def add(collection_name, hash)
25
- find_all(collection_name) << hash
26
- end
27
-
28
- def replace(collection_name, hash)
29
- collection = find_all(collection_name)
30
- index = collection.index{ |object| object[:id] == hash[:id] }
31
- collection[index] = hash
32
- end
33
29
 
34
- def delete_by_params(collection_name, params)
35
- find_all(collection_name).reject! do |record|
36
- params.all?{|k,v| record[k] == v }
30
+ # Class level access to the in-memory data store
31
+ #
32
+ # @return [Hash] all collections along with the contents of each collection
33
+ def self.data
34
+ instance.data
37
35
  end
38
- end
39
-
40
- def update_field_with_value(collection_name, primary_key_value, field_name, new_value)
41
- find(collection_name, :id, primary_key_value)[field_name] = new_value
42
- end
43
36
 
44
- def increment_field_by_amount(collection_name, primary_key_value, field_name, amount)
45
- find(collection_name, :id, primary_key_value)[field_name] += amount
46
- end
47
-
48
- def get_all_for_key_with_value(collection_name, key, value)
49
- find_all(collection_name).select { |a| a[key] == value }
50
- end
51
-
52
- def get_for_key_with_value(collection_name, key, value)
53
- get_all_for_key_with_value(collection_name, key, value)[0]
54
- end
55
-
56
- def get_by_params(collection_name, hash)
57
- find_all(collection_name).select do |record|
58
- hash.all?{|k,v| record[k] == v }
37
+ # The collection in the data store
38
+ #
39
+ # @param [Symbol] collection_name the name of the collection
40
+ # @return [Array] all records in the collection, defaults to an empty array
41
+ def self.collection(collection_name)
42
+ data[collection_name] ||= []
59
43
  end
60
- end
61
44
 
62
- def find_all(collection_name)
63
- data_store[collection_name] ||= []
64
- end
45
+ # The attribute containing the data
46
+ #
47
+ # @return [Hash] all collections along with the contents of each collection, defaults to an empty hash
48
+ attr_accessor :data
65
49
 
66
- def find(collection_name, key, value)
67
- find_all(collection_name).find { |x| x[key] == value }
68
- end
69
-
70
- def push_to_array(collection_name, identifying_key, identifying_value, array_key, value_to_push)
71
- record = find(collection_name, identifying_key, identifying_value)
72
- if (record[array_key])
73
- record[array_key] << value_to_push
74
- else
75
- record[array_key] = [value_to_push]
50
+ def initialize
51
+ @data = {}
76
52
  end
77
- record[array_key].uniq!
78
- end
79
-
80
- def remove_from_array(collection_name, identifying_key, identifying_value, array_key, value_to_pop)
81
- record = find(collection_name, identifying_key, identifying_value)
82
- record[array_key].reject! { |x| x == value_to_pop }
83
- end
84
-
85
- def containing_any(collection_name, key, values)
86
- find_all(collection_name).select do |x|
87
- if x[key].is_a?(Array)
88
- (x[key] & values).any?
89
- else
90
- values.include?(x[key])
91
- end
92
- end
93
- end
94
-
95
- def array_contains(collection_name, key, value)
96
- find_all(collection_name).select do |x|
97
- x[key] && x[key].include?(value)
98
- end
99
- end
100
-
101
- def delete_collection(collection_name)
102
- data_store.delete(collection_name)
103
- end
104
-
105
- def clear
106
- data_store.clear
107
- end
108
-
109
- def insert(collection_name, data)
110
- data_store[collection_name] = data
111
- end
112
-
113
- def set_data_store(hash)
114
- @data_store = hash
115
- end
116
-
117
- private
118
-
119
- def data_store
120
- @data_store ||= ::DB_HASH
121
53
  end
122
54
  end
123
55
  end
@@ -0,0 +1,237 @@
1
+ module Mince
2
+ module HashyDb # :nodoc:
3
+ require 'digest'
4
+ require_relative 'data_store'
5
+ require_relative 'config'
6
+
7
+ # = HashyDb Data Store
8
+ #
9
+ # HashyDb Data Store stores and retrieves data from a ruby in-memory hash.
10
+ #
11
+ # Using this library offers more extensibility and growth for your application. If at any point in time
12
+ # you want to support a different database for all, or even one, of your classes, you only need to implement
13
+ # the few methods defined in this class.
14
+ #
15
+ # HashyDb::DataStore.add 'fruits', id: '1', name: 'Shnawzberry', color: 'redish', quantity: '20'
16
+ # HashyDb::DataStore.get_for_key_with_value 'fruits', :color, 'redish'
17
+ #
18
+ # @author Matt Simpson
19
+ module Interface
20
+
21
+ # Generates a unique ID for a database record
22
+ #
23
+ # @note This is necessary because different databases use different types of primary key values. Thus, each mince
24
+ # implementation must define how to generate a unique id.
25
+ #
26
+ # @param [#to_s] salt any object that responds to #to_s
27
+ # @return [String] A unique id based on the salt and the current time
28
+ def self.generate_unique_id(salt)
29
+ Digest::SHA256.hexdigest("#{Time.now}#{salt}")[0..6]
30
+ end
31
+
32
+ def self.primary_key
33
+ Config.primary_key
34
+ end
35
+
36
+ # Deletes a field from all records in the given collection
37
+ #
38
+ # @param [Symbol] collection_name the name of the collection
39
+ # @param [symbol] field the name of the field to delete
40
+ def self.delete_field(collection_name, field)
41
+ find_all(collection_name).each do |row|
42
+ row.delete(field)
43
+ end
44
+ end
45
+
46
+ # Inserts one record into a collection.
47
+ #
48
+ # @param [Symbol] collection_name the name of the collection
49
+ # @param [Hash] hash a hash of data to be added to the collection
50
+ def self.add(collection_name, hash)
51
+ find_all(collection_name) << hash
52
+ end
53
+
54
+ # Replaces a record in the collection based on the primary key's value. The hash must contain a key, defined
55
+ # by the +primary_key_identifier+ method, with a value. If a record in the data store is found with that key and
56
+ # value, the entire record will be replaced with the given hash.
57
+ #
58
+ # @param [Symbol] collection_name the name of the collection
59
+ # @param [Hash] hash a hash to replace the record in the collection with
60
+ def self.replace(collection_name, hash)
61
+ collection = find_all(collection_name)
62
+ index = collection.index{ |object| object[primary_key] == hash[primary_key] }
63
+ collection[index] = hash
64
+ end
65
+
66
+ # Deletes a record that matches the given criteria from the data store.
67
+ def self.delete_by_params(collection_name, params)
68
+ find_all(collection_name).reject! do |record|
69
+ params.all?{|k,v| record[k] == v }
70
+ end
71
+ end
72
+
73
+ # Updates the field with a value for the record for the given id.
74
+ #
75
+ # @param [Symbol] collection_name the name of the collection
76
+ # @param [String] primary_key_value the id of the record
77
+ # @param [Symbol] field_name the name of the field to update
78
+ # @param [String] field_value the value to update the field to
79
+ # @return [void] no specific return value
80
+ def self.update_field_with_value(collection_name, primary_key_value, field_name, new_value)
81
+ find(collection_name, primary_key, primary_key_value)[field_name] = new_value
82
+ end
83
+
84
+ # Increments or decrements the field by the given amount for the record for the given id.
85
+ #
86
+ # @param [Symbol] collection_name the name of the collection
87
+ # @param [String] primary_key_value the id of the record
88
+ # @param [Symbol] field_name the name of the field to update
89
+ # @param [String] amount the amount to increment or decrement the field by
90
+ # @return [void] no specific return value
91
+ def self.increment_field_by_amount(collection_name, primary_key_value, field_name, amount)
92
+ find(collection_name, primary_key, primary_key_value)[field_name] += amount
93
+ end
94
+
95
+ # Gets all records that have the value for a given key.
96
+ #
97
+ # @param [Symbol] collection_name the name of the collection
98
+ # @param [String] key the key, or field, to get a record for
99
+ # @param [*] value the value to get a record for
100
+ # @return [Array] an array of records that match the key and value
101
+ def self.get_all_for_key_with_value(collection_name, key, value)
102
+ find_all(collection_name).select { |a| a[key] == value }
103
+ end
104
+
105
+ # Gets the first record that has the value for a given key.
106
+ #
107
+ # @param [Symbol] collection_name the name of the collection
108
+ # @param [String] key the key to find a record by
109
+ # @param [String] value the value to find a record by
110
+ # @return [Hash] a hash for the record found by the key and value in the collection
111
+ def self.get_for_key_with_value(collection_name, key, value)
112
+ self.get_all_for_key_with_value(collection_name, key, value)[0]
113
+ end
114
+
115
+ # Gets all records that have all of the keys and values in the given hash.
116
+ #
117
+ # @param [Symbol] collection_name the name of the collection
118
+ # @param [Hash] hash a hash to get a record for
119
+ # @return [Array] an array of all records matching the given hash for the collection
120
+ def self.get_by_params(collection_name, hash)
121
+ self.find_all(collection_name).select do |record|
122
+ hash.all?{|k,v| record[k] == v }
123
+ end
124
+ end
125
+
126
+ # Gets all records for a collection
127
+ #
128
+ # @param [Symbol] collection_name the name of the collection
129
+ # @return [Array] all records for the given collection name
130
+ def self.find_all(collection_name)
131
+ DataStore.collection(collection_name)
132
+ end
133
+
134
+ # Gets a record matching a key and value
135
+ #
136
+ # @param [Symbol] collection_name the name of the collection
137
+ # @param [String] key the key to find a record by
138
+ # @param [*] value a value the find a record by
139
+ # @return [Hash] a record that matches the given key and value
140
+ def self.find(collection_name, key, value)
141
+ find_all(collection_name).find { |x| x[key] == value }
142
+ end
143
+
144
+ # Pushes a value to a record's key that is an array
145
+ #
146
+ # @param [Symbol] collection_name the name of the collection
147
+ # @param [String] identifying_key the field used to find the record
148
+ # @param [*] identifying_value the value used to find the record
149
+ # @param [String] array_key the field to push an array to
150
+ # @param [*] value_to_push the value to push to the array
151
+ def self.push_to_array(collection_name, identifying_key, identifying_value, array_key, value_to_push)
152
+ record = find(collection_name, identifying_key, identifying_value)
153
+ if (record[array_key])
154
+ record[array_key] << value_to_push
155
+ else
156
+ record[array_key] = [value_to_push]
157
+ end
158
+ record[array_key].uniq!
159
+ end
160
+
161
+ # Removes a value from a record's key that is an array
162
+ #
163
+ # @param [Symbol] collection_name the name of the collection
164
+ # @param [String] identifying_key the field used to find the record
165
+ # @param [*] identifying_value the value used to find the record
166
+ # @param [String] array_key the field to push an array from
167
+ # @param [*] value_to_remove the value to remove from the array
168
+ def self.remove_from_array(collection_name, identifying_key, identifying_value, array_key, value_to_pop)
169
+ record = find(collection_name, identifying_key, identifying_value)
170
+ record[array_key].reject! { |x| x == value_to_pop }
171
+ end
172
+
173
+ # Returns all records where the given key contains any of the values provided
174
+ #
175
+ # @param [Symbol] collection_name the name of the collection
176
+ # @param [String] key the key to find the record by
177
+ # @param [Array] values an array of values that the record could contain
178
+ # @return [Array] all records that contain any of the values given
179
+ def self.containing_any(collection_name, key, values)
180
+ find_all(collection_name).select do |x|
181
+ if x[key].is_a?(Array)
182
+ (x[key] & values).any?
183
+ else
184
+ values.include?(x[key])
185
+ end
186
+ end
187
+ end
188
+
189
+ # Returns all records where the given key contains the given value
190
+ #
191
+ # @param [Symbol] collection_name the name of the collection
192
+ # @param [String] key the key to find records by
193
+ # @param [*] value the value to find a record by
194
+ # @return [Array] all records where the key contains the given value
195
+ def self.array_contains(collection_name, key, value)
196
+ find_all(collection_name).select do |x|
197
+ x[key] && x[key].include?(value)
198
+ end
199
+ end
200
+
201
+ # Replaces the entire collection with the given data
202
+ #
203
+ # @param [Symbol] collection_name the name of the collection
204
+ # @param [Array] data an array of data hashes to replace and insert into the collection
205
+ def self.insert(collection_name, data_to_insert)
206
+ data[collection_name] = data_to_insert
207
+ end
208
+
209
+ # Deletes an entire collection
210
+ #
211
+ # @param [Symbol] collection_name the collection to delete from the database
212
+ # @return [Array] the records in the collection being deleted
213
+ def self.delete_collection(collection_name)
214
+ data.delete(collection_name)
215
+ end
216
+
217
+ # Clears the data store.
218
+ #
219
+ # Mainly used for rolling back the data store for tests.
220
+ #
221
+ # @return [Hash] the data store
222
+ def self.clear
223
+ data.clear
224
+ end
225
+
226
+ # Alias to Mince::HashyDb::DataStore.data=
227
+ def self.set_data(hash)
228
+ DataStore.set_data hash
229
+ end
230
+
231
+ # Alias to Mince::HashyDb::DataStore.data
232
+ def self.data
233
+ DataStore.data
234
+ end
235
+ end
236
+ end
237
+ end
@@ -1,3 +1,35 @@
1
- module HashyDb
2
- VERSION = '1.1.0'
1
+ module HashyDb # :nodoc:
2
+ # = HashyDb Version
3
+ #
4
+ # HashyDb Version specifies the version of this library
5
+ #
6
+ # Use these versions to negotiate with for compatibility
7
+ #
8
+ # Major version releases indicates a major enhancement, breaks backward compatibility
9
+ # Minor version release indicates an addition, enhancement or bug fix which is not an immediate need, does not break backward compatibility
10
+ # Patch version release indicates a bug fix or patch that is an emergency, does not break backward compatibility
11
+ #
12
+ # @author Matt Simpson
13
+ module Version
14
+
15
+ # Provides the major level version of the library
16
+ def self.major
17
+ 2
18
+ end
19
+
20
+ # Provides the minor level version of the library
21
+ def self.minor
22
+ 0
23
+ end
24
+
25
+ # Provides the patch level version of the library
26
+ def self.patch
27
+ '0.pre'
28
+ end
29
+ end
30
+
31
+ # Provides the full version of the library
32
+ def self.version
33
+ [Version.major, Version.minor, Version.patch].join(".")
34
+ end
3
35
  end
data/lib/hashy_db.rb CHANGED
@@ -1 +1,4 @@
1
- require 'hashy_db/data_store'
1
+ require_relative 'hashy_db/version'
2
+ require_relative 'hashy_db/config'
3
+ require_relative 'hashy_db/data_store'
4
+ require_relative 'hashy_db/interface'
@@ -0,0 +1,14 @@
1
+ require_relative '../../lib/hashy_db'
2
+ require 'mince/shared_examples/interface_example'
3
+
4
+ describe 'Mince Interface with HashyDb' do
5
+ before do
6
+ Mince::Config.interface = Mince::HashyDb::Interface
7
+ end
8
+
9
+ after do
10
+ Mince::HashyDb::Interface.clear
11
+ end
12
+
13
+ it_behaves_like 'a mince interface'
14
+ end
@@ -0,0 +1,7 @@
1
+ require_relative '../../../lib/hashy_db/config'
2
+
3
+ describe Mince::HashyDb::Config do
4
+ it 'it knows what to use for the primary key of each record' do
5
+ described_class.primary_key.should == :id
6
+ end
7
+ end
@@ -0,0 +1,21 @@
1
+ require_relative '../../../lib/hashy_db/data_store'
2
+
3
+ describe Mince::HashyDb::DataStore do
4
+ it 'has no data by default' do
5
+ described_class.data.should == {}
6
+ end
7
+
8
+ it 'can add data' do
9
+ data = mock
10
+ described_class.set_data(data)
11
+
12
+ described_class.data.should == data
13
+ end
14
+
15
+ it 'can return a collection' do
16
+ data = mock
17
+ described_class.set_data({ some_collection: data })
18
+
19
+ described_class.collection(:some_collection).should == data
20
+ end
21
+ end
@@ -0,0 +1,8 @@
1
+ require_relative '../../../lib/hashy_db/interface'
2
+
3
+ describe Mince::HashyDb::Interface do
4
+ # due to the low level behavior of this class, it is tested at the integration level
5
+ # at spec/integration/mince_interface_spec.rb
6
+ #
7
+ # Feel free to provide a better implementation of this.
8
+ end
metadata CHANGED
@@ -1,67 +1,134 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hashy_db
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
5
- prerelease:
4
+ version: 2.0.0.pre
5
+ prerelease: 6
6
6
  platform: ruby
7
7
  authors:
8
8
  - Matt Simpson
9
9
  - Jason Mayer
10
- - Asynchrony Solutions
10
+ - Asynchrony
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2012-08-08 00:00:00.000000000 Z
14
+ date: 2012-10-02 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
- name: activesupport
17
+ name: rake
18
18
  requirement: !ruby/object:Gem::Requirement
19
19
  none: false
20
20
  requirements:
21
21
  - - ~>
22
22
  - !ruby/object:Gem::Version
23
- version: '3.1'
24
- type: :runtime
23
+ version: '0.9'
24
+ type: :development
25
25
  prerelease: false
26
26
  version_requirements: !ruby/object:Gem::Requirement
27
27
  none: false
28
28
  requirements:
29
29
  - - ~>
30
30
  - !ruby/object:Gem::Version
31
- version: '3.1'
31
+ version: '0.9'
32
32
  - !ruby/object:Gem::Dependency
33
- name: rake
33
+ name: rspec
34
34
  requirement: !ruby/object:Gem::Requirement
35
35
  none: false
36
36
  requirements:
37
- - - ! '>='
37
+ - - ~>
38
38
  - !ruby/object:Gem::Version
39
- version: '0'
39
+ version: '2.0'
40
40
  type: :development
41
41
  prerelease: false
42
42
  version_requirements: !ruby/object:Gem::Requirement
43
43
  none: false
44
44
  requirements:
45
- - - ! '>='
45
+ - - ~>
46
46
  - !ruby/object:Gem::Version
47
- version: '0'
47
+ version: '2.0'
48
48
  - !ruby/object:Gem::Dependency
49
- name: rspec
49
+ name: guard-rspec
50
50
  requirement: !ruby/object:Gem::Requirement
51
51
  none: false
52
52
  requirements:
53
- - - ! '>='
53
+ - - ~>
54
54
  - !ruby/object:Gem::Version
55
- version: '0'
55
+ version: '0.6'
56
56
  type: :development
57
57
  prerelease: false
58
58
  version_requirements: !ruby/object:Gem::Requirement
59
59
  none: false
60
60
  requirements:
61
- - - ! '>='
61
+ - - ~>
62
+ - !ruby/object:Gem::Version
63
+ version: '0.6'
64
+ - !ruby/object:Gem::Dependency
65
+ name: yard
66
+ requirement: !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ~>
62
70
  - !ruby/object:Gem::Version
63
- version: '0'
64
- description: Provides an interface to store and retrieve data in a Hash.
71
+ version: '0.7'
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.7'
80
+ - !ruby/object:Gem::Dependency
81
+ name: redcarpet
82
+ requirement: !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ~>
86
+ - !ruby/object:Gem::Version
87
+ version: '2.1'
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.1'
96
+ - !ruby/object:Gem::Dependency
97
+ name: debugger
98
+ requirement: !ruby/object:Gem::Requirement
99
+ none: false
100
+ requirements:
101
+ - - ~>
102
+ - !ruby/object:Gem::Version
103
+ version: '1.2'
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: '1.2'
112
+ - !ruby/object:Gem::Dependency
113
+ name: mince
114
+ requirement: !ruby/object:Gem::Requirement
115
+ none: false
116
+ requirements:
117
+ - - '='
118
+ - !ruby/object:Gem::Version
119
+ version: 2.0.0.pre
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: 2.0.0.pre
128
+ description: Library to interact with in-memory hash database collections. Offers
129
+ very little technical dependencies. In order to develop or run the tests for your
130
+ application you just need ruby installed, run bundle install and you're good to
131
+ go. No need to install and start your database, migrate, etc.
65
132
  email:
66
133
  - matt@railsgrammer.com
67
134
  - jason.mayer@gmail.com
@@ -69,18 +136,15 @@ executables: []
69
136
  extensions: []
70
137
  extra_rdoc_files: []
71
138
  files:
72
- - .gitignore
73
- - .rspec
74
- - .rvmrc
75
- - Gemfile
76
- - LICENSE.txt
77
- - README.md
78
- - Rakefile
79
- - hashy_db.gemspec
80
139
  - lib/hashy_db.rb
81
140
  - lib/hashy_db/data_store.rb
82
141
  - lib/hashy_db/version.rb
83
- - spec/lib/data_store_spec.rb
142
+ - lib/hashy_db/config.rb
143
+ - lib/hashy_db/interface.rb
144
+ - spec/integration/mince_interface_spec.rb
145
+ - spec/units/hashy_db/config_spec.rb
146
+ - spec/units/hashy_db/data_store_spec.rb
147
+ - spec/units/hashy_db/interface_spec.rb
84
148
  homepage: https://github.com/asynchrony/hashy_db
85
149
  licenses: []
86
150
  post_install_message:
@@ -96,15 +160,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
96
160
  required_rubygems_version: !ruby/object:Gem::Requirement
97
161
  none: false
98
162
  requirements:
99
- - - ! '>='
163
+ - - ! '>'
100
164
  - !ruby/object:Gem::Version
101
- version: '0'
165
+ version: 1.3.1
102
166
  requirements: []
103
167
  rubyforge_project: hashy_db
104
168
  rubygems_version: 1.8.24
105
169
  signing_key:
106
170
  specification_version: 3
107
- summary: Provides an interface to store and retrieve data in a Hash.
171
+ summary: Library to interact with in-memory hash database collections
108
172
  test_files:
109
- - spec/lib/data_store_spec.rb
173
+ - spec/integration/mince_interface_spec.rb
174
+ - spec/units/hashy_db/config_spec.rb
175
+ - spec/units/hashy_db/data_store_spec.rb
176
+ - spec/units/hashy_db/interface_spec.rb
110
177
  has_rdoc:
data/.gitignore DELETED
@@ -1,8 +0,0 @@
1
- .idea
2
- *.gem
3
- .bundle
4
- Gemfile.lock
5
- pkg/*
6
- .yardoc
7
- doc
8
-
data/.rspec DELETED
@@ -1,2 +0,0 @@
1
- --colour
2
- --format nested
data/.rvmrc DELETED
@@ -1 +0,0 @@
1
- rvm use 1.9.3
data/Gemfile DELETED
@@ -1,3 +0,0 @@
1
- source :rubygems
2
-
3
- gemspec
data/LICENSE.txt DELETED
@@ -1,20 +0,0 @@
1
- Copyright (c) 2012 Matt Simpson and Jason Mayer
2
-
3
- Permission is hereby granted, free of charge, to any person obtaining
4
- a copy of this software and associated documentation files (the
5
- "Software"), to deal in the Software without restriction, including
6
- without limitation the rights to use, copy, modify, merge, publish,
7
- distribute, sublicense, and/or sell copies of the Software, and to
8
- permit persons to whom the Software is furnished to do so, subject to
9
- the following conditions:
10
-
11
- The above copyright notice and this permission notice shall be
12
- included in all copies or substantial portions of the Software.
13
-
14
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md DELETED
@@ -1,65 +0,0 @@
1
- # What is hashy db?
2
-
3
- Light weight ORM to persist data to a hash.
4
-
5
- Provides an interface for storing and retreiving information to a Hash.
6
-
7
- The motivation behind this is so you can clone the repository down, have ruby installed, run bundle install and be able to run your tests and develop without being dependent on any other setup.
8
-
9
- [@github](https://github.com/asynchrony/HashyDB)
10
- [@rubygems](https://rubygems.org/gems/hashy_db)
11
-
12
- # How to use
13
-
14
- view the [example mince rails app](https://github.com/coffeencoke/mince_rails_example) to see how to use this.
15
-
16
- Basic usage is to create a constant called DB_HASH and set it to an empty hash in an initializer file, or whenever your application gets loaded (if you're not running rails).
17
-
18
- <pre>
19
- # initializers/datastore.rb
20
- ::DB_HASH = {}
21
- </pre>
22
-
23
- From there you can use Hashy Db to add and retrieve data.
24
-
25
- <pre>
26
- # Add a book to the books collection
27
- HashyDb::DataStore.add 'books', title: 'The World In Photographs', publisher: 'National Geographic'
28
-
29
- # Retrieve all records from the books collection
30
- HashyDb::DataStore.find_all 'books'
31
-
32
- # Update a field with a value for a specific record
33
- HashyDb::DataStore.update_field_with_value 'books', 'primary_id_123', :field_name, 'value to update with'
34
-
35
- # Replace a specific book
36
- HashyDb::DataStore.replace 'books', id: 1, title: 'A World In Photographs', publisher: 'National Geographic'
37
- </pre>
38
-
39
- View the [data_store.rb](https://github.com/asynchrony/hashy_db/blob/master/lib/hashy_db/data_store.rb) file for all methods available.
40
-
41
- Use with [mince data model](https://github.com/asynchrony/mince_data_model) to make it easy to change from one data storage to another, like [Mince](https://github.com/asynchrony/mince), a MongoDB implementation.
42
-
43
-
44
- # Why would you want this?
45
-
46
- - To defer choosing your database until you know most about your application.
47
- - Provides assitance in designing a database agnostic architecture.
48
- - Offers very little technical dependencies. In order to develop or run the tests for your application you just need ruby installed, run bundle install and you're good to go. No need to install and start your database, migrate, etc.
49
-
50
- The hash can be loaded in memory and be used as your data store.
51
-
52
- # Contribute
53
-
54
- - fork into a topic branch, write specs, make a pull request.
55
-
56
- # Owners
57
-
58
- Matt Simpson - [@railsgrammer](https://twitter.com/railsgrammer)
59
-
60
- Jason Mayer - [@farkerhaiku](https://twitter.com/farkerhaiku)
61
-
62
- # Contributors
63
-
64
- David Czarnecki - [@czarneckid](https://twitter.com/czarneckid)
65
- Amos King - [@adkron](https://twitter.com/adkron)
data/Rakefile DELETED
@@ -1,11 +0,0 @@
1
- require 'bundler/gem_tasks'
2
- require 'rake'
3
- require 'rspec/core/rake_task'
4
-
5
- RSpec::Core::RakeTask.new(:spec) do |spec|
6
- spec.pattern = 'spec/**/*_spec.rb'
7
- spec.rspec_opts = ['--backtrace']
8
- # spec.ruby_opts = ['-w']
9
- end
10
-
11
- task :default => :spec
data/hashy_db.gemspec DELETED
@@ -1,25 +0,0 @@
1
- # -*- encoding: utf-8 -*-
2
- $:.push File.expand_path("../lib", __FILE__)
3
- require 'hashy_db/version'
4
-
5
- Gem::Specification.new do |s|
6
- s.name = "hashy_db"
7
- s.version = HashyDb::VERSION
8
- s.authors = ["Matt Simpson", "Jason Mayer", "Asynchrony Solutions"]
9
- s.email = ["matt@railsgrammer.com", "jason.mayer@gmail.com"]
10
- s.homepage = "https://github.com/asynchrony/hashy_db"
11
- s.summary = %q{Provides an interface to store and retrieve data in a Hash.}
12
- s.description = %q{Provides an interface to store and retrieve data in a Hash.}
13
-
14
- s.rubyforge_project = "hashy_db"
15
-
16
- s.files = `git ls-files`.split("\n")
17
- s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
- s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
- s.require_paths = ["lib"]
20
-
21
- s.add_dependency('activesupport', '~> 3.1')
22
-
23
- s.add_development_dependency('rake')
24
- s.add_development_dependency('rspec')
25
- end
@@ -1,137 +0,0 @@
1
- require_relative '../../lib/hashy_db/data_store'
2
-
3
- describe HashyDb::DataStore do
4
- subject { HashyDb::DataStore.instance }
5
-
6
- let(:data1) { {id: 1, field_1: 'value 1', field_2: 3, field_3: [1, 2, 3], shared_between_1_and_2: 'awesome_value', :some_array => [1, 2, 3, 4]} }
7
- let(:data2) { {id: 2, field_1: 'value 1.2', field_2: 6, shared_between_1_and_2: 'awesome_value', :some_array => [4, 5, 6]} }
8
- let(:data3) { {id: 3, field_1: 'value 3', field_2: 9, shared_between_1_and_2: 'not the same as 1 and 2', :some_array => [1, 7]} }
9
-
10
- before do
11
- subject.set_data_store({})
12
-
13
- subject.insert(:some_collection, [data1, data2, data3])
14
- end
15
-
16
- it 'has a primary key identifier' do
17
- described_class.primary_key_identifier.should == :id
18
- end
19
-
20
- describe "Generating a primary key" do
21
- let(:data_model_id) { full_data_model_id[0..6] }
22
- let(:full_data_model_id) { '1234567891423456789' }
23
- let(:utc) { mock 'utc'}
24
- let(:time) { mock 'time', :utc => utc}
25
- let(:salt) { mock 'salt to ensure uniqeness' }
26
-
27
- before do
28
- Digest::SHA256.stub(:hexdigest => full_data_model_id)
29
- Time.stub(:current => time)
30
- end
31
-
32
- it 'should create a reasonably unique id' do
33
- Digest::SHA256.should_receive(:hexdigest).with("#{utc}#{salt}").and_return(full_data_model_id)
34
-
35
- described_class.generate_unique_id(salt).should == data_model_id
36
- end
37
- end
38
-
39
- it 'can delete a field' do
40
- subject.delete_field(:some_collection, :field_1)
41
-
42
- subject.find_all(:some_collection).each do |row|
43
- row.has_key?(:field_1).should be_false
44
- end
45
- end
46
-
47
- it 'can delete a collection' do
48
- subject.delete_collection(:some_collection)
49
-
50
- subject.find_all(:some_collection).should == []
51
- end
52
-
53
- it 'can delete records that match a given set of fields' do
54
- params = { id: 1, field_1: 'value 1' }
55
-
56
- subject.delete_by_params(:some_collection, params)
57
-
58
- subject.find_all(:some_collection).should == [data2, data3]
59
- end
60
-
61
- it 'can write and read data to and from a collection' do
62
- data4 = {id: 3, field_1: 'value 3', field_2: 9, shared_between_1_and_2: 'not the same as 1 and 2', :some_array => [1, 7]}
63
-
64
- subject.add(:some_collection, data4)
65
- subject.find_all(:some_collection).should == [data1, data2, data3, data4]
66
- end
67
-
68
- it 'can replace a record' do
69
- data2[:field_1] = 'value modified'
70
- subject.replace(:some_collection, data2)
71
-
72
- subject.find(:some_collection, :id, 2)[:field_1].should == 'value modified'
73
- end
74
-
75
- it 'can update a field with a value on a specific record' do
76
- subject.update_field_with_value(:some_collection, 3, :field_2, '10')
77
-
78
- subject.find(:some_collection, :id, 3)[:field_2].should == '10'
79
- end
80
-
81
- it 'can increment a field with a given amount for a specific field' do
82
- subject.increment_field_by_amount(:some_collection, 1, :field_2, 3)
83
-
84
- subject.find(:some_collection, :id, 1)[:field_2].should == 6
85
- end
86
-
87
- it 'can get one document' do
88
- subject.find(:some_collection, :field_1, 'value 1').should == data1
89
- subject.find(:some_collection, :field_2, 6).should == data2
90
- end
91
-
92
- it 'can clear the data store' do
93
- subject.clear
94
-
95
- subject.find_all(:some_collection).should == []
96
- end
97
-
98
- it 'can get all records of a specific key value' do
99
- subject.get_all_for_key_with_value(:some_collection, :shared_between_1_and_2, 'awesome_value').should == [data1, data2]
100
- end
101
-
102
- it 'can get all records where a value includes any of a set of values' do
103
- subject.containing_any(:some_collection, :some_array, []).should == []
104
- subject.containing_any(:some_collection, :some_array, [7, 2, 3]).should == [data1, data3]
105
- subject.containing_any(:some_collection, :id, [1, 2, 5]).should == [data1, data2]
106
- end
107
-
108
- it 'can get all records where the array includes a value' do
109
- subject.array_contains(:some_collection, :some_array, 1).should == [data1, data3]
110
- subject.array_contains(:some_collection, :some_array_2, 1).should == []
111
- end
112
-
113
- it 'can push a value to an array for a specific record' do
114
- subject.push_to_array(:some_collection, :id, 1, :field_3, 'add to existing array')
115
- subject.push_to_array(:some_collection, :id, 1, :new_field, 'add to new array')
116
-
117
- subject.find(:some_collection, :id, 1)[:field_3].should include('add to existing array')
118
- subject.find(:some_collection, :id, 1)[:new_field].should == ['add to new array']
119
- end
120
-
121
- it 'can remove a value from an array for a specific record' do
122
- subject.remove_from_array(:some_collection, :id, 1, :field_3, 2)
123
-
124
- subject.find(:some_collection, :id, 1)[:field_3].should_not include(2)
125
- end
126
-
127
- it 'can get all records that match a given set of keys and values' do
128
- records = subject.get_by_params(:some_collection, field_1: 'value 1', shared_between_1_and_2: 'awesome_value')
129
- records.size.should be(1)
130
- records.first[:id].should == 1
131
- subject.find_all(:some_collection).size.should == 3
132
- end
133
-
134
- it 'can get a record for a specific key and value' do
135
- subject.get_for_key_with_value(:some_collection, :field_1, 'value 1').should == data1
136
- end
137
- end