simple_store 0.0.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.
- data/.gitignore +17 -0
- data/.rspec +2 -0
- data/Gemfile +7 -0
- data/LICENSE.txt +22 -0
- data/README.md +83 -0
- data/Rakefile +1 -0
- data/lib/simple_store.rb +7 -0
- data/lib/simple_store/disk.rb +36 -0
- data/lib/simple_store/memory.rb +41 -0
- data/lib/simple_store/version.rb +3 -0
- data/simple_store.gemspec +21 -0
- data/spec/file_store_spec.rb +44 -0
- data/spec/memory_store_spec.rb +39 -0
- data/spec/spec_helper.rb +14 -0
- data/spec/table_spec.rb +49 -0
- metadata +81 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Kris Leech
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
# SimpleStore
|
2
|
+
|
3
|
+
Store buckets of keyed hashes in memory or to disk, useful for testing without a real database.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'simple_store'
|
10
|
+
|
11
|
+
## Usage
|
12
|
+
|
13
|
+
### Memory Store
|
14
|
+
|
15
|
+
person = { :id => 1, :first_name => 'Kris', :last_name => 'Leech' }
|
16
|
+
store = SimpleStore::Memory.new(:people)
|
17
|
+
store.put(person)
|
18
|
+
|
19
|
+
# some moments later...
|
20
|
+
|
21
|
+
store.get(1) # => { ... }
|
22
|
+
|
23
|
+
### Disk Store
|
24
|
+
|
25
|
+
person = { :id => 1, :first_name => 'Kris', :last_name => 'Leech' }
|
26
|
+
store = SimpleStore::Disk.new(:people)
|
27
|
+
store.put(person)
|
28
|
+
|
29
|
+
# some days later...
|
30
|
+
|
31
|
+
store = SimpleStore::Disk.new(:people)
|
32
|
+
store.get(1) # => { ... }
|
33
|
+
|
34
|
+
### Example
|
35
|
+
|
36
|
+
require 'virtus'
|
37
|
+
require 'guid'
|
38
|
+
|
39
|
+
class Person
|
40
|
+
include Virtus
|
41
|
+
|
42
|
+
attribute :id, String, :default => Guid.new.to_s
|
43
|
+
attribute :first_name
|
44
|
+
attribute :last_name
|
45
|
+
|
46
|
+
def ==(person)
|
47
|
+
id == person.id
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
class PeopleTable < SimpleStore::Disk
|
52
|
+
def initialize
|
53
|
+
super(:people)
|
54
|
+
end
|
55
|
+
|
56
|
+
def put(person)
|
57
|
+
super(person.attributes)
|
58
|
+
end
|
59
|
+
|
60
|
+
def get(id)
|
61
|
+
Person.new(super(id))
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe 'storing a domain object to disk' do
|
66
|
+
it 'domain objects can be stored and retrieved from the store' do
|
67
|
+
person = Person.new
|
68
|
+
person.first_name = 'Kris'
|
69
|
+
person.last_name = 'Leech'
|
70
|
+
|
71
|
+
table = PeopleTable.new
|
72
|
+
table.put person
|
73
|
+
table.get(person.id).should == person
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
## Contributing
|
78
|
+
|
79
|
+
1. Fork it
|
80
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
81
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
82
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
83
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/lib/simple_store.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
module SimpleStore
|
2
|
+
class Disk < Memory
|
3
|
+
def put(attributes)
|
4
|
+
super(attributes)
|
5
|
+
write_data
|
6
|
+
end
|
7
|
+
|
8
|
+
def get(key)
|
9
|
+
load_data
|
10
|
+
super(key)
|
11
|
+
end
|
12
|
+
|
13
|
+
def destroy_all
|
14
|
+
super
|
15
|
+
write_data
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def write_data
|
21
|
+
serialized_data = YAML.dump(data[bucket])
|
22
|
+
File.open(filename, 'w') do |file|
|
23
|
+
file.write(serialized_data)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def load_data
|
28
|
+
deserialized_data = YAML.load(File.read(filename))
|
29
|
+
data[bucket] = deserialized_data
|
30
|
+
end
|
31
|
+
|
32
|
+
def filename
|
33
|
+
'/tmp/simple_store.yml'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module SimpleStore
|
2
|
+
class Memory
|
3
|
+
attr_reader :bucket
|
4
|
+
|
5
|
+
def initialize(bucket)
|
6
|
+
@bucket = bucket
|
7
|
+
data[bucket] ||= {}
|
8
|
+
end
|
9
|
+
|
10
|
+
def put(attributes)
|
11
|
+
key = find_key(attributes)
|
12
|
+
data[bucket][key] = attributes
|
13
|
+
end
|
14
|
+
|
15
|
+
def get(key)
|
16
|
+
data[bucket].fetch(key) { raise SimpleStore::RecordNotFound, "Record not found with key #{key}"}
|
17
|
+
end
|
18
|
+
|
19
|
+
def destroy_all
|
20
|
+
data[bucket] = {}
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_s
|
24
|
+
data.inspect
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def find_key(attributes)
|
30
|
+
[:id, :key].each do |key|
|
31
|
+
return attributes[key] if !attributes[key].nil?
|
32
|
+
end
|
33
|
+
raise 'No key found in attributes'
|
34
|
+
end
|
35
|
+
|
36
|
+
def data
|
37
|
+
@data ||= {}
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'simple_store/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "simple_store"
|
8
|
+
gem.version = SimpleStore::VERSION
|
9
|
+
gem.authors = ["Kris Leech"]
|
10
|
+
gem.email = ["kris.leech@gmail.com"]
|
11
|
+
gem.description = %q{Store buckets of keyed hashes in memory or to disk, useful for testing without a real database}
|
12
|
+
gem.summary = %q{Store buckets of keyed hashes in memory or to disk}
|
13
|
+
gem.homepage = ""
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ["lib"]
|
19
|
+
|
20
|
+
gem.add_development_dependency 'rspec'
|
21
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe SimpleStore::Disk do
|
4
|
+
let(:store) { SimpleStore::Disk.new(:people) }
|
5
|
+
|
6
|
+
before(:each) do
|
7
|
+
store.destroy_all
|
8
|
+
end
|
9
|
+
|
10
|
+
it '#put stores keyed hashes' do
|
11
|
+
person_attributes = { :id => 1, :first_name => 'Kris', :last_name => 'Leech' }
|
12
|
+
store.put person_attributes
|
13
|
+
store.get(1).should == person_attributes
|
14
|
+
end
|
15
|
+
|
16
|
+
it '#get raise RecordNotFound for missing keys' do
|
17
|
+
expect { store.get(1) }.to raise_error SimpleStore::RecordNotFound
|
18
|
+
end
|
19
|
+
|
20
|
+
it '#put persists data across store instances' do
|
21
|
+
person_attributes = { :id => 1, :first_name => 'Kris', :last_name => 'Leech' }
|
22
|
+
store.put person_attributes
|
23
|
+
|
24
|
+
new_store = SimpleStore::Disk.new(:people)
|
25
|
+
expect { new_store.get(1) }.not_to raise_error SimpleStore::RecordNotFound
|
26
|
+
end
|
27
|
+
|
28
|
+
it '#destroy_all removes all records' do
|
29
|
+
store = SimpleStore::Disk.new(:people)
|
30
|
+
first_person_attributes = { :id => 1, :first_name => 'Kris', :last_name => 'Leech' }
|
31
|
+
second_person_attributes = { :id => 2, :first_name => 'Kris', :last_name => 'Leech' }
|
32
|
+
store.put first_person_attributes
|
33
|
+
store.put second_person_attributes
|
34
|
+
store.destroy_all
|
35
|
+
expect { store.get(1) }.to raise_error SimpleStore::RecordNotFound
|
36
|
+
expect { store.get(2) }.to raise_error SimpleStore::RecordNotFound
|
37
|
+
end
|
38
|
+
|
39
|
+
it '#put stores nested hashes' do
|
40
|
+
record = { :id => 1, :name => 'Foobar', :chapters => [ 1,2,3 ], :sections => [{ :name => '1', :color => :red }, { :name => '2', :color => :green } ] }
|
41
|
+
store.put record
|
42
|
+
store.get(1).should == record
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe SimpleStore::Memory do
|
4
|
+
let(:store) { SimpleStore::Memory.new(:people) }
|
5
|
+
|
6
|
+
it '#put stores keyed hashes' do
|
7
|
+
person_attributes = { :id => 1, :first_name => 'Kris', :last_name => 'Leech' }
|
8
|
+
store.put person_attributes
|
9
|
+
store.get(1).should == person_attributes
|
10
|
+
end
|
11
|
+
|
12
|
+
it '#get raise RecordNotFound for missing keys' do
|
13
|
+
expect { store.get(1) }.to raise_error SimpleStore::RecordNotFound
|
14
|
+
end
|
15
|
+
|
16
|
+
it '#put does not persist across instances' do
|
17
|
+
person_attributes = { :id => 1, :first_name => 'Kris', :last_name => 'Leech' }
|
18
|
+
store.put person_attributes
|
19
|
+
|
20
|
+
new_store = SimpleStore::Memory.new(:people)
|
21
|
+
expect { new_store.get(1) }.to raise_error SimpleStore::RecordNotFound
|
22
|
+
end
|
23
|
+
|
24
|
+
it '#destroy_all removes all records' do
|
25
|
+
first_person_attributes = { :id => 1, :first_name => 'Kris', :last_name => 'Leech' }
|
26
|
+
second_person_attributes = { :id => 2, :first_name => 'Kris', :last_name => 'Leech' }
|
27
|
+
store.put first_person_attributes
|
28
|
+
store.put second_person_attributes
|
29
|
+
store.destroy_all
|
30
|
+
expect { store.get(1) }.to raise_error SimpleStore::RecordNotFound
|
31
|
+
expect { store.get(2) }.to raise_error SimpleStore::RecordNotFound
|
32
|
+
end
|
33
|
+
|
34
|
+
it '#put stores nested hashes' do
|
35
|
+
record = { :id => 1, :name => 'Foobar', :chapters => [ 1,2,3 ], :sections => [{ :name => '1', :color => :red }, { :name => '2', :color => :green } ] }
|
36
|
+
store.put record
|
37
|
+
store.get(1).should == record
|
38
|
+
end
|
39
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require_relative '../lib/simple_store'
|
2
|
+
|
3
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
4
|
+
RSpec.configure do |config|
|
5
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
6
|
+
config.run_all_when_everything_filtered = true
|
7
|
+
config.filter_run :focus
|
8
|
+
|
9
|
+
# Run specs in random order to surface order dependencies. If you find an
|
10
|
+
# order dependency and want to debug it, you can fix the order by providing
|
11
|
+
# the seed, which is printed after each run.
|
12
|
+
# --seed 1234
|
13
|
+
config.order = 'random'
|
14
|
+
end
|
data/spec/table_spec.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'virtus'
|
3
|
+
require 'guid'
|
4
|
+
require 'rubygems'
|
5
|
+
|
6
|
+
class Person
|
7
|
+
include Virtus
|
8
|
+
|
9
|
+
attribute :id, String, :default => Guid.new.to_s
|
10
|
+
attribute :first_name
|
11
|
+
attribute :last_name
|
12
|
+
|
13
|
+
def full_name
|
14
|
+
[first_name, last_name].join(' ')
|
15
|
+
end
|
16
|
+
|
17
|
+
def ==(person)
|
18
|
+
id == person.id
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class PeopleTable < SimpleStore::Disk
|
23
|
+
def initialize
|
24
|
+
super(:people)
|
25
|
+
end
|
26
|
+
|
27
|
+
def put(person)
|
28
|
+
super(person.attributes)
|
29
|
+
end
|
30
|
+
|
31
|
+
def get(id)
|
32
|
+
Person.new(super(id))
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe 'using as super class for a table' do
|
37
|
+
it 'works' do
|
38
|
+
person = Person.new
|
39
|
+
person.first_name = 'Kris'
|
40
|
+
person.last_name = 'Leech'
|
41
|
+
table = PeopleTable.new
|
42
|
+
table.put person
|
43
|
+
table.get(person.id).should == person
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
|
metadata
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: simple_store
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Kris Leech
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-12-01 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rspec
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
description: Store buckets of keyed hashes in memory or to disk, useful for testing
|
31
|
+
without a real database
|
32
|
+
email:
|
33
|
+
- kris.leech@gmail.com
|
34
|
+
executables: []
|
35
|
+
extensions: []
|
36
|
+
extra_rdoc_files: []
|
37
|
+
files:
|
38
|
+
- .gitignore
|
39
|
+
- .rspec
|
40
|
+
- Gemfile
|
41
|
+
- LICENSE.txt
|
42
|
+
- README.md
|
43
|
+
- Rakefile
|
44
|
+
- lib/simple_store.rb
|
45
|
+
- lib/simple_store/disk.rb
|
46
|
+
- lib/simple_store/memory.rb
|
47
|
+
- lib/simple_store/version.rb
|
48
|
+
- simple_store.gemspec
|
49
|
+
- spec/file_store_spec.rb
|
50
|
+
- spec/memory_store_spec.rb
|
51
|
+
- spec/spec_helper.rb
|
52
|
+
- spec/table_spec.rb
|
53
|
+
homepage: ''
|
54
|
+
licenses: []
|
55
|
+
post_install_message:
|
56
|
+
rdoc_options: []
|
57
|
+
require_paths:
|
58
|
+
- lib
|
59
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
60
|
+
none: false
|
61
|
+
requirements:
|
62
|
+
- - ! '>='
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: '0'
|
65
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
66
|
+
none: false
|
67
|
+
requirements:
|
68
|
+
- - ! '>='
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: '0'
|
71
|
+
requirements: []
|
72
|
+
rubyforge_project:
|
73
|
+
rubygems_version: 1.8.23
|
74
|
+
signing_key:
|
75
|
+
specification_version: 3
|
76
|
+
summary: Store buckets of keyed hashes in memory or to disk
|
77
|
+
test_files:
|
78
|
+
- spec/file_store_spec.rb
|
79
|
+
- spec/memory_store_spec.rb
|
80
|
+
- spec/spec_helper.rb
|
81
|
+
- spec/table_spec.rb
|