persistent-cache 0.1.3 → 0.1.6
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/lib/persistent-cache.rb +19 -21
- data/lib/persistent-cache/storage/storage_directory.rb +1 -1
- data/lib/persistent-cache/storage/storage_sq_lite.rb +13 -12
- data/lib/persistent-cache/version.rb +1 -1
- data/spec/persistent-cache_spec.rb +14 -12
- data/spec/storage/storage_sqlite_spec.rb +29 -30
- metadata +3 -4
- data/multidb +0 -0
data/lib/persistent-cache.rb
CHANGED
|
@@ -31,27 +31,27 @@ module Persistent
|
|
|
31
31
|
|
|
32
32
|
def set(key, value, timestamp)
|
|
33
33
|
if value.nil?
|
|
34
|
-
delete_entry(
|
|
34
|
+
delete_entry(key)
|
|
35
35
|
else
|
|
36
|
-
save_key_value_pair(
|
|
36
|
+
save_key_value_pair(key, value, timestamp)
|
|
37
37
|
end
|
|
38
38
|
end
|
|
39
39
|
|
|
40
40
|
def []=(key, value)
|
|
41
41
|
if value.nil?
|
|
42
|
-
delete_entry(
|
|
42
|
+
delete_entry(key)
|
|
43
43
|
else
|
|
44
|
-
save_key_value_pair(
|
|
44
|
+
save_key_value_pair(key, value)
|
|
45
45
|
end
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
def [](key)
|
|
49
|
-
lookup_key(
|
|
49
|
+
lookup_key(key)
|
|
50
50
|
end
|
|
51
51
|
|
|
52
52
|
def each(&block)
|
|
53
53
|
keys.each do |key|
|
|
54
|
-
yield key, lookup_key(
|
|
54
|
+
yield key, lookup_key(key)
|
|
55
55
|
end
|
|
56
56
|
end
|
|
57
57
|
|
|
@@ -60,9 +60,7 @@ module Persistent
|
|
|
60
60
|
end
|
|
61
61
|
|
|
62
62
|
def keys
|
|
63
|
-
@storage.keys
|
|
64
|
-
Marshal.load(key[0])
|
|
65
|
-
}
|
|
63
|
+
@storage.keys
|
|
66
64
|
end
|
|
67
65
|
|
|
68
66
|
def clear
|
|
@@ -71,32 +69,32 @@ module Persistent
|
|
|
71
69
|
|
|
72
70
|
private
|
|
73
71
|
|
|
74
|
-
def save_key_value_pair(
|
|
75
|
-
delete_entry(
|
|
76
|
-
@storage.save_key_value_pair(
|
|
72
|
+
def save_key_value_pair(key, value, timestamp = nil)
|
|
73
|
+
@storage.delete_entry(key)
|
|
74
|
+
@storage.save_key_value_pair(key, value, timestamp)
|
|
77
75
|
end
|
|
78
76
|
|
|
79
|
-
def lookup_key(
|
|
80
|
-
result = @storage.lookup_key(
|
|
77
|
+
def lookup_key(key)
|
|
78
|
+
result = @storage.lookup_key(key)
|
|
81
79
|
return nil if nil_result?(result)
|
|
82
|
-
return nil if stale_entry?(
|
|
80
|
+
return nil if stale_entry?(key, result)
|
|
83
81
|
|
|
84
|
-
return
|
|
82
|
+
return result[0]
|
|
85
83
|
end
|
|
86
84
|
|
|
87
|
-
def stale_entry?(
|
|
85
|
+
def stale_entry?(key, result)
|
|
88
86
|
return false if @fresh.nil?
|
|
89
87
|
|
|
90
|
-
timestamp = Time.parse(result[
|
|
88
|
+
timestamp = Time.parse(result[1])
|
|
91
89
|
if ((Time.now - timestamp) > FRESH)
|
|
92
|
-
delete_entry(
|
|
90
|
+
delete_entry(key)
|
|
93
91
|
return true
|
|
94
92
|
end
|
|
95
93
|
return false
|
|
96
94
|
end
|
|
97
95
|
|
|
98
|
-
def delete_entry(
|
|
99
|
-
@storage.delete_entry(
|
|
96
|
+
def delete_entry(key)
|
|
97
|
+
@storage.delete_entry(key)
|
|
100
98
|
end
|
|
101
99
|
|
|
102
100
|
def nil_result?(result)
|
|
@@ -16,23 +16,24 @@ module Persistent
|
|
|
16
16
|
@storage_handler.busy_timeout = 30000
|
|
17
17
|
end
|
|
18
18
|
|
|
19
|
-
def save_key_value_pair(
|
|
20
|
-
delete_entry(
|
|
19
|
+
def save_key_value_pair(key, value, timestamp = nil)
|
|
20
|
+
delete_entry(key)
|
|
21
21
|
time_entry = timestamp.nil? ? Time.now.to_s : timestamp.to_s
|
|
22
|
-
EH::retry!(:args => [
|
|
23
|
-
@storage_handler.execute("INSERT INTO #{DB_TABLE} (key, value, timestamp) VALUES(?, ?, ?)",
|
|
22
|
+
EH::retry!(:args => [Marshal.dump(key), Marshal.dump(value), time_entry]) do
|
|
23
|
+
@storage_handler.execute("INSERT INTO #{DB_TABLE} (key, value, timestamp) VALUES(?, ?, ?)",Marshal.dump(key), Marshal.dump(value), time_entry)
|
|
24
24
|
end
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
-
def lookup_key(
|
|
28
|
-
EH::retry!(:args => [
|
|
29
|
-
@storage_handler.execute("SELECT value, timestamp FROM #{DB_TABLE} WHERE key=?",
|
|
27
|
+
def lookup_key(key)
|
|
28
|
+
EH::retry!(:args => [Marshal.dump(key)]) do
|
|
29
|
+
result = @storage_handler.execute("SELECT value, timestamp FROM #{DB_TABLE} WHERE key=?", Marshal.dump(key))
|
|
30
|
+
!result.nil? && !result.empty? ? [Marshal.load(result[0][0]), result[0][1]] : nil
|
|
30
31
|
end
|
|
31
32
|
end
|
|
32
33
|
|
|
33
|
-
def delete_entry(
|
|
34
|
-
EH::retry!(:args => [
|
|
35
|
-
@storage_handler.execute("DELETE FROM #{DB_TABLE} WHERE key=?",
|
|
34
|
+
def delete_entry(key)
|
|
35
|
+
EH::retry!(:args => [Marshal.dump(key)]) do
|
|
36
|
+
@storage_handler.execute("DELETE FROM #{DB_TABLE} WHERE key=?", Marshal.dump(key))
|
|
36
37
|
end
|
|
37
38
|
end
|
|
38
39
|
|
|
@@ -44,7 +45,7 @@ module Persistent
|
|
|
44
45
|
|
|
45
46
|
def keys
|
|
46
47
|
EH::retry!(:args => []) do
|
|
47
|
-
@storage_handler.execute("SELECT key FROM #{DB_TABLE}")
|
|
48
|
+
@storage_handler.execute("SELECT key FROM #{DB_TABLE}").collect { |k| Marshal.load(k[0]) }
|
|
48
49
|
end
|
|
49
50
|
end
|
|
50
51
|
|
|
@@ -81,4 +82,4 @@ module Persistent
|
|
|
81
82
|
@storage_handler
|
|
82
83
|
end
|
|
83
84
|
end
|
|
84
|
-
end
|
|
85
|
+
end
|
|
@@ -51,21 +51,21 @@ describe Persistent::Cache do
|
|
|
51
51
|
it "should ask the storage handler to first delete, then save the key/value pair" do
|
|
52
52
|
Persistent::StorageSQLite.should_receive(:new).and_return @mock_storage
|
|
53
53
|
@mock_storage.should_receive(:delete_entry)
|
|
54
|
-
@mock_storage.should_receive(:save_key_value_pair).with(
|
|
54
|
+
@mock_storage.should_receive(:save_key_value_pair).with(@test_key, @test_value, nil)
|
|
55
55
|
@pcache = Persistent::Cache.new(@db_name)
|
|
56
56
|
@pcache[@test_key] = @test_value
|
|
57
57
|
end
|
|
58
58
|
|
|
59
59
|
it "should ask the storage handler to delete if the value is nil using []" do
|
|
60
60
|
Persistent::StorageSQLite.should_receive(:new).and_return @mock_storage
|
|
61
|
-
@mock_storage.should_receive(:delete_entry).with(
|
|
61
|
+
@mock_storage.should_receive(:delete_entry).with(@test_key)
|
|
62
62
|
@pcache = Persistent::Cache.new(@db_name)
|
|
63
63
|
@pcache[@test_key] = nil
|
|
64
64
|
end
|
|
65
65
|
|
|
66
66
|
it "should ask the storage handler to delete if the value is nil using set()" do
|
|
67
67
|
Persistent::StorageSQLite.should_receive(:new).and_return @mock_storage
|
|
68
|
-
@mock_storage.should_receive(:delete_entry).with(
|
|
68
|
+
@mock_storage.should_receive(:delete_entry).with(@test_key)
|
|
69
69
|
@pcache = Persistent::Cache.new(@db_name)
|
|
70
70
|
@pcache.set(@test_key, nil, Time.now)
|
|
71
71
|
end
|
|
@@ -73,7 +73,7 @@ describe Persistent::Cache do
|
|
|
73
73
|
it "should serialize the key and value for persistence" do
|
|
74
74
|
Persistent::StorageSQLite.should_receive(:new).and_return @mock_storage
|
|
75
75
|
@mock_storage.should_receive(:delete_entry)
|
|
76
|
-
@mock_storage.should_receive(:save_key_value_pair).with(
|
|
76
|
+
@mock_storage.should_receive(:save_key_value_pair).with(@test_key, @test_value, nil)
|
|
77
77
|
@pcache = Persistent::Cache.new(@db_name)
|
|
78
78
|
@pcache[@test_key] = @test_value
|
|
79
79
|
end
|
|
@@ -82,7 +82,7 @@ describe Persistent::Cache do
|
|
|
82
82
|
Persistent::StorageSQLite.should_receive(:new).and_return @mock_storage
|
|
83
83
|
@mock_storage.should_receive(:delete_entry)
|
|
84
84
|
timestamp = Time.now - 100
|
|
85
|
-
@mock_storage.should_receive(:save_key_value_pair).with(
|
|
85
|
+
@mock_storage.should_receive(:save_key_value_pair).with(@test_key, @test_value, timestamp)
|
|
86
86
|
@pcache = Persistent::Cache.new(@db_name)
|
|
87
87
|
@pcache.set(@test_key, @test_value, timestamp)
|
|
88
88
|
end
|
|
@@ -91,8 +91,8 @@ describe Persistent::Cache do
|
|
|
91
91
|
context "When looking up a value given its key" do
|
|
92
92
|
it "should retrieve the value from storage using lookup_key and deserialize the value" do
|
|
93
93
|
@mock_storage.should_receive(:delete_entry)
|
|
94
|
-
@mock_storage.should_receive(:save_key_value_pair).with(
|
|
95
|
-
@mock_storage.should_receive(:lookup_key).with(
|
|
94
|
+
@mock_storage.should_receive(:save_key_value_pair).with(@test_key, @test_value, nil)
|
|
95
|
+
@mock_storage.should_receive(:lookup_key).with(@test_key).and_return([@test_value, Time.now.to_s])
|
|
96
96
|
Persistent::StorageSQLite.should_receive(:new).and_return @mock_storage
|
|
97
97
|
@pcache = Persistent::Cache.new(@db_name)
|
|
98
98
|
@pcache[@test_key] = @test_value
|
|
@@ -102,7 +102,7 @@ describe Persistent::Cache do
|
|
|
102
102
|
|
|
103
103
|
it "should return nil if a value exists but it not fresh" do
|
|
104
104
|
@mock_storage.should_receive(:delete_entry)
|
|
105
|
-
@mock_storage.should_receive(:lookup_key).with(
|
|
105
|
+
@mock_storage.should_receive(:lookup_key).with(@test_key).and_return([@test_value, (Time.now - Persistent::Cache::FRESH).to_s])
|
|
106
106
|
Persistent::StorageSQLite.should_receive(:new).and_return @mock_storage
|
|
107
107
|
|
|
108
108
|
@pcache = Persistent::Cache.new(@db_name)
|
|
@@ -111,7 +111,7 @@ describe Persistent::Cache do
|
|
|
111
111
|
|
|
112
112
|
it "should remove from the cache an entry it encounters that is not fresh" do
|
|
113
113
|
@mock_storage.should_receive(:delete_entry)
|
|
114
|
-
@mock_storage.should_receive(:lookup_key).with(
|
|
114
|
+
@mock_storage.should_receive(:lookup_key).with(@test_key).and_return([@test_value, (Time.now - Persistent::Cache::FRESH).to_s])
|
|
115
115
|
Persistent::StorageSQLite.should_receive(:new).and_return @mock_storage
|
|
116
116
|
|
|
117
117
|
@pcache = Persistent::Cache.new(@db_name)
|
|
@@ -127,7 +127,7 @@ describe Persistent::Cache do
|
|
|
127
127
|
it "should serialize the key for lookup" do
|
|
128
128
|
@pcache = Persistent::Cache.new(@db_name)
|
|
129
129
|
@pcache["testkey"] = "testvalue"
|
|
130
|
-
@pcache.should_receive(:lookup_key).with(
|
|
130
|
+
@pcache.should_receive(:lookup_key).with("testkey")
|
|
131
131
|
@pcache["testkey"]
|
|
132
132
|
end
|
|
133
133
|
end
|
|
@@ -159,7 +159,7 @@ describe Persistent::Cache do
|
|
|
159
159
|
end
|
|
160
160
|
|
|
161
161
|
it "should be able to handle multiple accesses to the same db" do
|
|
162
|
-
|
|
162
|
+
pending "find a better way to test this, currently you need to spawn multiple rspecs running this test to hit the error if the busy_timeout is not specified"
|
|
163
163
|
pcache = Persistent::Cache.new("multidb")
|
|
164
164
|
pcache["multi_test"] = 0
|
|
165
165
|
|
|
@@ -167,7 +167,9 @@ describe Persistent::Cache do
|
|
|
167
167
|
100.times do |i|
|
|
168
168
|
threads << Thread.new do
|
|
169
169
|
Thread.current['pcache'] = Persistent::Cache.new("multidb")
|
|
170
|
-
|
|
170
|
+
if (!Thread.current['pcache'].nil? && !Thread.current['pcache']["multi_test"].nil?)
|
|
171
|
+
Thread.current['pcache']["multi_test"] += 1
|
|
172
|
+
end
|
|
171
173
|
end
|
|
172
174
|
end
|
|
173
175
|
threads.each { |t| t.join }
|
|
@@ -61,7 +61,7 @@ describe Persistent::StorageSQLite do
|
|
|
61
61
|
context "when asked to store a key value pair" do
|
|
62
62
|
it "should store the key/value pair in the db, with the current time as timestamp" do
|
|
63
63
|
start_time = Time.now - 1
|
|
64
|
-
@iut.save_key_value_pair(
|
|
64
|
+
@iut.save_key_value_pair(@test_key, @test_value)
|
|
65
65
|
handle = SQLite3::Database.open(@db_name)
|
|
66
66
|
result = handle.execute "select value, timestamp from #{Persistent::StorageSQLite::DB_TABLE} where key=?", Marshal.dump(@test_key)
|
|
67
67
|
result.nil?.should == false
|
|
@@ -73,7 +73,7 @@ describe Persistent::StorageSQLite do
|
|
|
73
73
|
|
|
74
74
|
it "should store the key/value pair in the db, with a timestamp specified" do
|
|
75
75
|
test_time = (Time.now - 2500)
|
|
76
|
-
@iut.save_key_value_pair(
|
|
76
|
+
@iut.save_key_value_pair(@test_key, @test_value, test_time)
|
|
77
77
|
handle = SQLite3::Database.open(@db_name)
|
|
78
78
|
result = handle.execute "select value, timestamp from #{Persistent::StorageSQLite::DB_TABLE} where key=?", Marshal.dump(@test_key)
|
|
79
79
|
result.nil?.should == false
|
|
@@ -84,8 +84,8 @@ describe Persistent::StorageSQLite do
|
|
|
84
84
|
end
|
|
85
85
|
|
|
86
86
|
it "should overwrite the existing key/value pair if they already exist" do
|
|
87
|
-
@iut.save_key_value_pair(
|
|
88
|
-
@iut.save_key_value_pair(
|
|
87
|
+
@iut.save_key_value_pair(@test_key, @test_value)
|
|
88
|
+
@iut.save_key_value_pair(@test_key, "testvalue2")
|
|
89
89
|
handle = SQLite3::Database.open(@db_name)
|
|
90
90
|
result = handle.execute "select value from #{Persistent::StorageSQLite::DB_TABLE} where key=?", Marshal.dump(@test_key)
|
|
91
91
|
result.nil?.should == false
|
|
@@ -97,24 +97,23 @@ describe Persistent::StorageSQLite do
|
|
|
97
97
|
|
|
98
98
|
context "When looking up a value given its key" do
|
|
99
99
|
it "should retrieve the value from the database" do
|
|
100
|
-
@iut.save_key_value_pair(
|
|
101
|
-
result = @iut.lookup_key(
|
|
102
|
-
result[0]
|
|
100
|
+
@iut.save_key_value_pair(@test_key, @test_value)
|
|
101
|
+
result = @iut.lookup_key(@test_key)
|
|
102
|
+
result[0].should == @test_value
|
|
103
103
|
end
|
|
104
104
|
|
|
105
105
|
it "should retrieve the timestamp when the value was stored from the database" do
|
|
106
106
|
now = Time.now.to_s
|
|
107
|
-
@iut.save_key_value_pair(
|
|
107
|
+
@iut.save_key_value_pair(@test_key, @test_value)
|
|
108
108
|
sleep 1
|
|
109
|
-
result = @iut.lookup_key(
|
|
110
|
-
result[
|
|
109
|
+
result = @iut.lookup_key(@test_key)
|
|
110
|
+
result[1].should == now
|
|
111
111
|
end
|
|
112
112
|
|
|
113
113
|
it "should return an empty array if a key is not in the database" do
|
|
114
|
-
@iut.delete_entry(
|
|
115
|
-
result = @iut.lookup_key(
|
|
116
|
-
result.should ==
|
|
117
|
-
result[0].should == nil
|
|
114
|
+
@iut.delete_entry(@test_key)
|
|
115
|
+
result = @iut.lookup_key(@test_key)
|
|
116
|
+
result.should == nil
|
|
118
117
|
end
|
|
119
118
|
end
|
|
120
119
|
|
|
@@ -124,12 +123,12 @@ describe Persistent::StorageSQLite do
|
|
|
124
123
|
end
|
|
125
124
|
|
|
126
125
|
it "should delete the entry if it is present" do
|
|
127
|
-
@iut.save_key_value_pair(
|
|
128
|
-
result = @iut.lookup_key(
|
|
129
|
-
result[0]
|
|
130
|
-
@iut.delete_entry(
|
|
131
|
-
result = @iut.lookup_key(
|
|
132
|
-
result.should ==
|
|
126
|
+
@iut.save_key_value_pair(@test_key, @test_value)
|
|
127
|
+
result = @iut.lookup_key(@test_key)
|
|
128
|
+
result[0].should == @test_value
|
|
129
|
+
@iut.delete_entry(@test_key)
|
|
130
|
+
result = @iut.lookup_key(@test_key)
|
|
131
|
+
result.should == nil
|
|
133
132
|
end
|
|
134
133
|
end
|
|
135
134
|
|
|
@@ -152,17 +151,17 @@ describe Persistent::StorageSQLite do
|
|
|
152
151
|
it "should return the keys in the database" do
|
|
153
152
|
populate_database(@iut)
|
|
154
153
|
keys = @iut.keys.flatten
|
|
155
|
-
keys.include?(
|
|
156
|
-
keys.include?(
|
|
157
|
-
keys.include?(
|
|
154
|
+
keys.include?("one").should == true
|
|
155
|
+
keys.include?("two").should == true
|
|
156
|
+
keys.include?("three").should == true
|
|
158
157
|
@iut.size.should == 3
|
|
159
158
|
end
|
|
160
159
|
|
|
161
|
-
it "should return the keys in an array
|
|
160
|
+
it "should return the keys in an array" do
|
|
162
161
|
populate_database(@iut)
|
|
163
162
|
found = false
|
|
164
|
-
test =
|
|
165
|
-
found = true if (@iut.keys
|
|
163
|
+
test = "one"
|
|
164
|
+
found = true if (@iut.keys.include?(test))
|
|
166
165
|
found.should == true
|
|
167
166
|
end
|
|
168
167
|
end
|
|
@@ -182,12 +181,12 @@ describe Persistent::StorageSQLite do
|
|
|
182
181
|
end
|
|
183
182
|
|
|
184
183
|
def populate_database(iut)
|
|
185
|
-
iut.save_key_value_pair(
|
|
186
|
-
iut.save_key_value_pair(
|
|
187
|
-
iut.save_key_value_pair(
|
|
184
|
+
iut.save_key_value_pair("one", "one")
|
|
185
|
+
iut.save_key_value_pair("two", "two")
|
|
186
|
+
iut.save_key_value_pair("three", "three")
|
|
188
187
|
end
|
|
189
188
|
|
|
190
189
|
def delete_database
|
|
191
190
|
FileUtils.rm_f(@db_name)
|
|
192
191
|
end
|
|
193
|
-
end
|
|
192
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: persistent-cache
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.6
|
|
5
5
|
prerelease:
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
@@ -10,7 +10,7 @@ authors:
|
|
|
10
10
|
autorequire:
|
|
11
11
|
bindir: bin
|
|
12
12
|
cert_chain: []
|
|
13
|
-
date: 2013-
|
|
13
|
+
date: 2013-11-29 00:00:00.000000000 Z
|
|
14
14
|
dependencies:
|
|
15
15
|
- !ruby/object:Gem::Dependency
|
|
16
16
|
name: rspec
|
|
@@ -112,7 +112,6 @@ files:
|
|
|
112
112
|
- lib/persistent-cache/storage/storage_ram.rb
|
|
113
113
|
- lib/persistent-cache/storage/storage_sq_lite.rb
|
|
114
114
|
- lib/persistent-cache/version.rb
|
|
115
|
-
- multidb
|
|
116
115
|
- persistent-cache.gemspec
|
|
117
116
|
- spec/persistent-cache_spec.rb
|
|
118
117
|
- spec/spec_helper.rb
|
|
@@ -139,7 +138,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
139
138
|
version: '0'
|
|
140
139
|
requirements: []
|
|
141
140
|
rubyforge_project:
|
|
142
|
-
rubygems_version: 1.8.
|
|
141
|
+
rubygems_version: 1.8.28
|
|
143
142
|
signing_key:
|
|
144
143
|
specification_version: 3
|
|
145
144
|
summary: Persistent Cache has a default freshness threshold of 179 days after which
|
data/multidb
DELETED
|
Binary file
|