obstore 0.0.1 → 0.1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 189bceb51e975e4cee66730f5eda40d6d2e5f70a
4
- data.tar.gz: 6064191922ce26a55d7b2cb386e37ee066e31ac2
3
+ metadata.gz: 53360071404e5f944d1f8be3c691864a51dd11cc
4
+ data.tar.gz: a6985c19eb52cb2b6382528e314fb7ab9df7f3e0
5
5
  SHA512:
6
- metadata.gz: 2bfaf6545bec341b3d79bf94592dd94ad275e1d0e2e53e533a827c7bff55fe14f4db796f0040e4b0ac636744ec73f10002d8c82b6f09a5807322bee586cf8787
7
- data.tar.gz: ecf26c593a83171c30090ab75c8c846942b87b6181083bbcaf3decec610b272bf80b27cf1657ef8aa53b0306034067a8f53a4c14dfabc2387b80b034aebdf51c
6
+ metadata.gz: f52c3580b81d6cb080ed5db56c8ff77ccf55280ea7150625936e08458c71fb35ed8eccff20b24a2bb4182c4697a57ffa0b24cc98c189a69f7ac99e7626be29d6
7
+ data.tar.gz: 7369a978a06b5c84b7bd1e0c54428889ebb1affb423479778bf15474a0ad7bf41714e7cb34d21f18acae4dfac001e9676c3145d744377727d0ebbf400c80e3ea
@@ -11,21 +11,21 @@ require 'obstore/data'
11
11
  module ObStore
12
12
  class FileStore
13
13
 
14
- attr_accessor :store
14
+ attr_accessor :_store
15
15
 
16
16
  def initialize(opts={})
17
17
  opts[:database] ||= "./tmp/obstore.db"
18
18
  opts[:threadsafe] ||= true
19
19
  opts[:atomic_writes] ||= false
20
- @store = PStore.new(opts[:database], opts[:threadsafe])
21
- @store.ultra_safe = opts[:atomic_writes]
20
+ @_store = PStore.new(opts[:database], opts[:threadsafe])
21
+ @_store.ultra_safe = opts[:atomic_writes]
22
22
  end
23
23
 
24
24
  # removes stale records from the pstore db
25
25
  def compact!
26
26
  keys = []
27
- @store.transaction do
28
- keys = @store.roots
27
+ @_store.transaction do
28
+ keys = @_store.roots
29
29
  end
30
30
  keys.each do |key|
31
31
  fetch_data_by_key key.to_sym # just fetching the stale items deletes them
@@ -33,6 +33,44 @@ module ObStore
33
33
  return true
34
34
  end
35
35
 
36
+ # stores data to pstore db
37
+ def store(key, value, opts={})
38
+ if key.class != Symbol
39
+ raise TypeError "key must be of type symbol"
40
+ end
41
+ store_data_by_key key, value, opts
42
+ end
43
+
44
+ # fetches saved object for the given key
45
+ def fetch(key)
46
+ if key.class != Symbol
47
+ raise TypeError "key must be of type symbol"
48
+ end
49
+ data = fetch_data_by_key(key)
50
+ if data.nil?
51
+ return nil
52
+ else
53
+ return data.fetch
54
+ end
55
+ end
56
+
57
+ # lists all the keys that are currently in the DBs
58
+ def keys
59
+ @_store.transaction do
60
+ @_store.roots
61
+ end
62
+ end
63
+
64
+ # returns boolean if atomic writes is active
65
+ def atomic_writes
66
+ @_store.ultra_safe
67
+ end
68
+
69
+ # sets atomic writes
70
+ def atomic_writes=(bool)
71
+ @_store.ultra_safe = bool
72
+ end
73
+
36
74
  private
37
75
 
38
76
  # marshals the data object to a string
@@ -42,11 +80,14 @@ module ObStore
42
80
 
43
81
  # un-marshals the passed string into an object
44
82
  def unmarshal(str)
83
+ if str.nil?
84
+ return nil
85
+ end
45
86
  YAML.load str
46
87
  end
47
88
 
48
- # method used by method_missing to store data
49
- def store_data_by_key(key, args)
89
+ # internal method used for storing data by key
90
+ def store_data_by_key(key, *args)
50
91
  options = {}
51
92
  if args.class == Array
52
93
  value = args.shift
@@ -54,24 +95,38 @@ module ObStore
54
95
  else
55
96
  value = args
56
97
  end
57
- @store.transaction do
58
- if value.nil?
59
- @store.delete key.to_sym
98
+ @_store.transaction do
99
+ if value.class == ObStore::Data
100
+ @_store[key.to_sym] = marshal value
101
+ elsif value.nil?
102
+ @_store.delete key.to_sym
60
103
  else
61
- @store[key.to_sym] = marshal ObStore::Data.new(value, options)
104
+ @_store[key.to_sym] = marshal ObStore::Data.new(value, options)
62
105
  end
63
- @store.commit
106
+ @_store.commit
64
107
  end
65
108
  end
66
109
 
110
+ def store_obj_by_key(key, args)
111
+ if args.class != ObStore::Data
112
+ unless args.class == NilClass
113
+ raise TypeError "data must be of type ObStore::Data"
114
+ end
115
+ end
116
+ store_data_by_key key, args
117
+ end
118
+
67
119
  # method used by method_missing to fetch data
68
120
  def fetch_data_by_key(key)
69
- @store.transaction do
70
- data = unmarshal(@store[key.to_sym])
121
+ @_store.transaction do
122
+ data = unmarshal(@_store[key.to_sym])
123
+ if data.nil?
124
+ return data
125
+ end
71
126
  if data.stale?
72
127
  data = nil
73
- @store.delete key.to_sym
74
- @store.commit
128
+ @_store.delete key.to_sym
129
+ @_store.commit
75
130
  end
76
131
  return data
77
132
  end
@@ -79,7 +134,7 @@ module ObStore
79
134
 
80
135
  def method_missing(meth, *args, &block)
81
136
  if meth.to_s =~ /^(.+)=$/
82
- store_data_by_key($1, *args)
137
+ store_obj_by_key($1, *args)
83
138
  elsif meth.to_s =~ /^(.+)$/
84
139
  fetch_data_by_key($1)
85
140
  else
@@ -5,5 +5,5 @@
5
5
  # License:: MIT
6
6
 
7
7
  module ObStore
8
- VERSION = "0.0.1"
8
+ VERSION = "0.1.1"
9
9
  end
@@ -0,0 +1,4 @@
1
+ # used for testing custom object storage and retrieval
2
+ class DummyObject
3
+ attr_accessor :data
4
+ end
@@ -1,100 +1,191 @@
1
1
  require 'obstore/filestore'
2
+ require './spec/dummy_object'
2
3
 
3
4
  describe ObStore::FileStore do
4
5
  before(:all) do
5
6
  begin
6
7
  Dir.mkdir './tmp'
7
8
  rescue
9
+ # ignored
8
10
  end
9
11
  end
10
12
 
11
13
  after(:all) do
12
14
  begin
13
15
  File.delete('./tmp/obstore.db')
16
+ File.delete('./tmp/keytest.db')
14
17
  rescue
18
+ # ignored
15
19
  end
16
20
  end
17
21
 
18
22
  describe "#initialize(options)" do
19
23
  it 'initializes a storage object' do
20
24
  s = ObStore::FileStore.new
21
- expect(s.store.path).to eq("./tmp/obstore.db")
22
- expect(s.store.ultra_safe).to eq(false)
25
+ expect(s._store.path).to eq("./tmp/obstore.db")
26
+ expect(s._store.ultra_safe).to eq(false)
23
27
  end
24
28
  it 'sets pstore to be ultra_safe when setting atomic_writes' do
25
29
  s = ObStore::FileStore.new(:atomic_writes=>true)
26
- expect(s.store.ultra_safe).to eq(true)
30
+ expect(s._store.ultra_safe).to eq(true)
31
+ end
32
+
33
+ it 'allows you to set atomic_writes after you create the object' do
34
+ s = ObStore::FileStore.new
35
+ expect(s._store.ultra_safe).to eq(false)
36
+ s.atomic_writes = true
37
+ expect(s._store.ultra_safe).to eq(true)
27
38
  end
28
39
  end
29
40
 
30
- describe "#data=(foo)" do
41
+ describe "#atomic_writes" do
42
+ it 'returns the ultra_safe status of the internal pstore' do
43
+ s = ObStore::FileStore.new
44
+ expect(s.atomic_writes).to eq(s._store.ultra_safe)
45
+ end
46
+
47
+ it 'allows you to set the ultra_safe status of the internal pstore' do
48
+ s = ObStore::FileStore.new
49
+ expect(s._store.ultra_safe).to eq(false)
50
+ s.atomic_writes = true
51
+ expect(s._store.ultra_safe).to eq(true)
52
+ end
53
+ end
54
+
55
+ describe "#store" do
31
56
  before(:each) do
32
- @s = ObStore::FileStore.new
57
+ @obstore = ObStore::FileStore.new
33
58
  end
34
59
 
35
- it 'allows you to set values for keys using the dot operator' do
36
- @s.data = "foo"
37
- expect(@s.data.fetch).to eq("foo")
60
+ it 'allows you to store an object to the pstore db' do
61
+ @obstore.store :data, "some data"
62
+ expect(@obstore.fetch :data).to eq("some data")
38
63
  end
39
64
 
40
- it 'allows you to set expiry for the value' do
41
- @s.data = Hash.new, {:expiry=>300}
42
- expect(@s.data.expiry).to eq(300)
65
+ it 'throws a type error if the key is not a symbol' do
66
+ expect{@obstore.store "data", "something"}.to raise_error(TypeError)
43
67
  end
44
68
 
45
- it 'allows you to pass a metadata hash' do
46
- @s.data = {:foo=>"bar"}, {:metadata=>{:baz=>"foo"}}
47
- expect(@s.data.baz).to eq("foo")
69
+ it 'handles any object' do
70
+ ob = DummyObject.new
71
+ ob.data = "foo"
72
+ @obstore.store :dummy, ob
73
+ expect(@obstore.fetch(:dummy).class).to eq(DummyObject)
74
+ expect(@obstore.fetch(:dummy).data).to eq("foo")
48
75
  end
49
76
 
50
- it 'allows you to set expiry and metadata' do
51
- @s.data = {:foo=>"bar"}, {:expiry=>600, :metadata=>{:baz=>"foo"}}
52
- expect(@s.data.expiry).to eq(600)
53
- expect(@s.data.baz).to eq("foo")
77
+ it 'handles persisting data changes to an object' do
78
+ ob = DummyObject.new
79
+ ob.data = "foo"
80
+ @obstore.store :dummy, ob
81
+ expect(@obstore.fetch(:dummy).class).to eq(DummyObject)
82
+ expect(@obstore.fetch(:dummy).data).to eq("foo")
83
+ ob.data = "bar"
84
+ @obstore.store :dummy, ob
85
+ expect(@obstore.fetch(:dummy).data).to eq("bar")
54
86
  end
55
87
 
56
- it 'returns nil if the data has expired' do
57
- @s.data = {:foo=>"bar"}, {:expiry=>-3}
58
- expect(@s.data).to eq(nil)
88
+ it 'handles setting expiry' do
89
+ @obstore.store :data, "foo", {:expiry=>300}
90
+ expect(@obstore.data.expiry).to eq(300)
59
91
  end
92
+ end
60
93
 
61
- it 'removes the data from the file if the data is stale' do
62
- @s.data = {:foo=>"bar"}, {:expiry=>-3}
63
- expect(@s.data).to eq(nil)
64
- @s.store.transaction do
65
- expect(@s.store.root?(:data)).to eq(false)
66
- end
94
+ describe '#fetch(key)' do
95
+ before(:each) do
96
+ @obstore = ObStore::FileStore.new
67
97
  end
68
98
 
69
- it 'removes the object from the store when you nil it out' do
70
- @s.data = "foo"
71
- expect(@s.data.fetch).to eq("foo")
72
- @s.data = nil
73
- @s.store.transaction do
74
- expect(@s.store.root?(:data)).to eq(false)
75
- end
99
+ it 'fetches the tracked object for the key' do
100
+ @obstore.store :data, "foo"
101
+ expect(@obstore.fetch :data).to eq("foo")
102
+ end
103
+
104
+ it 'fetches the actual tracked object instance' do
105
+ ob = DummyObject.new
106
+ ob.data = "bar"
107
+ @obstore.store :dummy, ob
108
+ expect(@obstore.fetch(:dummy).class).to eq(DummyObject)
109
+ expect(@obstore.fetch(:dummy).data).to eq("bar")
110
+ end
111
+ end
112
+
113
+ describe '#keys' do
114
+ it 'returns all the keys we have saved' do
115
+ @obstore = ObStore::FileStore.new(:database=>'./tmp/keytest.db')
116
+ expect(@obstore.keys).to eq([])
117
+ @obstore.store(:data, "foo")
118
+ expect(@obstore.keys.include?(:data)).to eq(true)
76
119
  end
77
120
  end
78
121
 
122
+ describe '#data' do
123
+ before(:each) do
124
+ @obstore = ObStore::FileStore.new
125
+ end
126
+
127
+ it 'fetches the ObStore::Data object' do
128
+ @obstore.store :data, "foo"
129
+ expect(@obstore.data.class).to eq(ObStore::Data)
130
+ end
131
+
132
+ it 'allows me to pass in an ObStore::Data object directly to be saved' do
133
+ @obstore.data = ObStore::Data.new("foo")
134
+ expect(@obstore.data.fetch).to eq("foo")
135
+ end
136
+
137
+ it 'allows me to nil a key out directly' do
138
+ @obstore.data = ObStore::Data.new("foo")
139
+ expect(@obstore.data.fetch).to eq("foo")
140
+ @obstore.data = nil
141
+ expect(@obstore.fetch :data).to eq(nil)
142
+ end
143
+
144
+ it 'throws a TypeError if passed anything other than ObStore::Data object' do
145
+ expect{@obstore.data = "foo"}.to raise_error(TypeError)
146
+ end
147
+
148
+ # TODO: persist metadata changes on update
149
+ #it 'persists metadata changes on update' do
150
+ # @obstore.store :data, {:foo=>"bar"}, {:expiry=>400, :metadata=>{:foo=>"bar"}}
151
+ # expect(@obstore.data.foo).to eq("bar")
152
+ # @obstore.data.foo = "baz"
153
+ # expect(@obstore.data.foo).to eq("baz")
154
+ # @obstore.data.expiry = 500
155
+ # expect(@obstore.data.expiry).to eq(500)
156
+ #end
157
+ end
158
+
79
159
  describe "#compact!" do
80
160
  before(:each) do
81
- @s = ObStore::FileStore.new
82
- @s.data = {:foo=>"bar"}, {:expiry=>-3}
83
- @s.more_data = {:foo=>"bar"}, {:expiry=>-3}
84
- @s.keep = {:foo=>"bar"}, {:expiry=>300}
85
- @s.never = {:foo=>"bar"}
161
+ begin
162
+ File.delete('./tmp/obstore.db')
163
+ File.delete('./tmp/keytest.db')
164
+ rescue
165
+ # ignored
166
+ end
167
+ begin
168
+ Dir.mkdir './tmp'
169
+ rescue
170
+ # ignored
171
+ end
172
+ @obstore = ObStore::FileStore.new
173
+ @obstore.store :data, {:foo=>"bar"}, {:expiry=>-3}
174
+ @obstore.store :more_data, {:foo=>"bar"}, {:expiry=>-3}
175
+ @obstore.store :keep, {:foo=>"bar"}, {:expiry=>300}
176
+ @obstore.store :never, {:foo=>"bar"}
86
177
  end
87
178
 
88
179
  it 'removes all expired records from the file' do
89
- @s.store.transaction do
90
- expect(@s.store.roots.length).to eq(4)
180
+ @obstore._store.transaction do
181
+ expect(@obstore._store.roots.length).to eq(4)
91
182
  end
92
- @s.compact!
93
- @s.store.transaction do
94
- expect(@s.store.roots.length).to eq(2)
95
- expect(@s.store.root?(:keep)).to eq(true)
96
- expect(@s.store.root?(:never)).to eq(true)
97
- expect(@s.store.root?(:data)).to eq(false)
183
+ @obstore.compact!
184
+ @obstore._store.transaction do
185
+ expect(@obstore._store.roots.length).to eq(2)
186
+ expect(@obstore._store.root?(:keep)).to eq(true)
187
+ expect(@obstore._store.root?(:never)).to eq(true)
188
+ expect(@obstore._store.root?(:data)).to eq(false)
98
189
  end
99
190
  end
100
191
 
metadata CHANGED
@@ -1,27 +1,27 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: obstore
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Heijmans
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-06-29 00:00:00.000000000 Z
11
+ date: 2014-07-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ~>
18
18
  - !ruby/object:Gem::Version
19
19
  version: '3.0'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ~>
25
25
  - !ruby/object:Gem::Version
26
26
  version: '3.0'
27
27
  description: ObStore allows you to save any object to a file along with metadata about
@@ -37,6 +37,7 @@ files:
37
37
  - lib/obstore/filestore.rb
38
38
  - lib/obstore/lockable.rb
39
39
  - lib/obstore/version.rb
40
+ - spec/dummy_object.rb
40
41
  - spec/lib/data_spec.rb
41
42
  - spec/lib/filestore_spec.rb
42
43
  - spec/lib/version_spec.rb
@@ -51,12 +52,12 @@ require_paths:
51
52
  - lib
52
53
  required_ruby_version: !ruby/object:Gem::Requirement
53
54
  requirements:
54
- - - ">="
55
+ - - '>='
55
56
  - !ruby/object:Gem::Version
56
57
  version: '0'
57
58
  required_rubygems_version: !ruby/object:Gem::Requirement
58
59
  requirements:
59
- - - ">="
60
+ - - '>='
60
61
  - !ruby/object:Gem::Version
61
62
  version: '0'
62
63
  requirements: []
@@ -66,6 +67,7 @@ signing_key:
66
67
  specification_version: 4
67
68
  summary: ObStore is a smart persistent Object store.
68
69
  test_files:
70
+ - spec/dummy_object.rb
69
71
  - spec/lib/data_spec.rb
70
72
  - spec/lib/filestore_spec.rb
71
73
  - spec/lib/version_spec.rb