persistent-cache 0.4.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 1c8b77545d0f4b605d15137012b0fcaf1f849032
4
+ data.tar.gz: e2258f5db2125f20ca38253e8f6fd51065783aca
5
+ SHA512:
6
+ metadata.gz: 6282dbd4b4916eedf1a97dbdb0d6f0a2c28422a7f6f0191c29e112b6a0b76e5daa42d22b2a0e8994b7eebce4333e877ec79fc8d8e927f9d9edd6985302ada000
7
+ data.tar.gz: 03eaed66ba58ca33230093b2b892be3f9bf889e354f610ebdd9e5a823f9fd816d1cb111c151e275101b45ba5dd680114100aed28f46a3e7350395f9ed581442a
@@ -0,0 +1 @@
1
+ persistent-cache
@@ -0,0 +1 @@
1
+ ruby-2.3.0
data/README.md CHANGED
@@ -6,7 +6,7 @@ Values in the cache have a default freshness period of 15465600 ms. This can be
6
6
 
7
7
  Note that when using a back-end that requires marshalling (e.g. sqlite) the string encoding for []= and [] needs to be the same (e.g. UTF-8, US-ASCII, etc.) If the coding does not match, [] will not be able to find the entry during lookup and will return nil. See the section on 'Encoding' below for more detail.
8
8
 
9
- This gem is sponsored by Hetzner (Pty) Ltd - http://hetzner.co.za
9
+ This gem was sponsored by Hetzner (Pty) Ltd - http://hetzner.co.za
10
10
 
11
11
  ## StorageSQLite
12
12
 
@@ -113,10 +113,10 @@ If you'd like persistent cache to rather store keys using an encoding of your pr
113
113
 
114
114
  Please send feedback and comments to the authors at:
115
115
 
116
- Wynand van Dyk <wynand.van.dyk@hetzner.co.za>
117
-
118
116
  Ernst van Graan <ernst.van.graan@hetzner.co.za>
119
117
 
118
+ Wynand van Dyk <wynand.van.dyk@hetzner.co.za>
119
+
120
120
  1. Fork it
121
121
  2. Create your feature branch (`git checkout -b my-new-feature`)
122
122
  3. Commit your changes (`git commit -am 'Added some feature'`)
@@ -1,8 +1,8 @@
1
1
  require "persistent-cache/version"
2
2
  require "sqlite3"
3
- require "persistent-cache/storage/storage_sq_lite"
4
- require "persistent-cache/storage/storage_directory"
5
- require "persistent-cache/storage/storage_ram"
3
+ require "persistent-cache/storage_sqlite"
4
+ require "persistent-cache/storage_directory"
5
+ require "persistent-cache/storage_ram"
6
6
 
7
7
  module Persistent
8
8
  class Cache
@@ -23,7 +23,7 @@ module Persistent
23
23
 
24
24
  @storage = StorageSQLite.new(storage_details) if storage == STORAGE_SQLITE
25
25
  @storage = StorageDirectory.new(storage_details) if storage == STORAGE_DIRECTORY
26
- @storage = StorageRAM.new if storage == STORAGE_RAM
26
+ @storage = StorageRAM.new(storage_details) if storage == STORAGE_RAM
27
27
  @fresh = fresh
28
28
  @storage_details = storage_details
29
29
 
@@ -1,5 +1,3 @@
1
1
  module Persistent
2
- class Cache
3
- VERSION = "0.4.1"
4
- end
2
+ VERSION = "1.0.0"
5
3
  end
@@ -1,9 +1,11 @@
1
1
  # -*- encoding: utf-8 -*-
2
- require File.expand_path('../lib/persistent-cache/version', __FILE__)
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'persistent-cache/version'
3
5
 
4
6
  Gem::Specification.new do |gem|
5
- gem.authors = ["Wynand van Dyk", "Ernst van Graan"]
6
- gem.email = ["wvd@hetzner.co.za", "ernst.van.graan@hetzner.co.za"]
7
+ gem.authors = ["Ernst van Graan", "Wynand van Dyk"]
8
+ gem.email = ["ernst.van.graan@hetzner.co.za", "wvd@hetzner.co.za"]
7
9
  gem.description = %q{Persistent Cache using a pluggable back-end (e.g. SQLite)}
8
10
  gem.summary = %q{Persistent Cache has a default freshness threshold of 179 days after which entries are no longer returned}
9
11
  gem.homepage = ""
@@ -13,11 +15,14 @@ Gem::Specification.new do |gem|
13
15
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
16
  gem.name = "persistent-cache"
15
17
  gem.require_paths = ["lib"]
16
- gem.version = Persistent::Cache::VERSION
18
+ gem.version = Persistent::VERSION
17
19
  gem.add_development_dependency 'rspec', '2.12.0'
18
20
  gem.add_development_dependency 'simplecov'
19
21
  gem.add_development_dependency 'simplecov-rcov'
20
- gem.add_development_dependency 'debugger'
21
- gem.add_dependency 'sqlite3', '1.3.10'
22
+ gem.add_development_dependency 'byebug'
22
23
  gem.add_dependency 'eh'
24
+ gem.add_dependency "persistent-cache-storage-api"
25
+ gem.add_dependency "persistent-cache-storage-sqlite"
26
+ gem.add_dependency "persistent-cache-storage-directory"
27
+ gem.add_dependency "persistent-cache-storage-ram"
23
28
  end
@@ -1,8 +1,5 @@
1
1
  require 'spec_helper'
2
2
 
3
- require "persistent-cache"
4
- require "persistent-cache/storage/storage_sq_lite"
5
-
6
3
  describe Persistent::Cache do
7
4
  before :each do
8
5
  @db_name = get_database_name
@@ -3,7 +3,11 @@ require 'rspec/mocks'
3
3
  require 'tempfile'
4
4
  require 'simplecov'
5
5
  require 'simplecov-rcov'
6
- require 'debugger'
6
+ require 'byebug'
7
+ require "persistent-cache"
8
+ require "persistent-cache/storage_sqlite"
9
+ require "persistent-cache/storage_directory"
10
+ require "persistent-cache/storage_ram"
7
11
 
8
12
  # This file was generated by the `rspec --init` command. Conventionally, all
9
13
  # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
@@ -1,6 +1,4 @@
1
1
  require 'spec_helper'
2
- require "persistent-cache/storage/storage_directory"
3
- require 'debugger'
4
2
 
5
3
  describe Persistent::StorageDirectory do
6
4
  before :each do
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
- require "persistent-cache/storage/storage_ram"
3
2
 
4
3
  describe Persistent::StorageRAM do
5
4
  before :each do
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
- require "persistent-cache/storage/storage_sq_lite"
3
2
 
4
3
  describe Persistent::StorageSQLite do
5
4
  before :each do
metadata CHANGED
@@ -1,21 +1,19 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: persistent-cache
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
5
- prerelease:
4
+ version: 1.0.0
6
5
  platform: ruby
7
6
  authors:
8
- - Wynand van Dyk
9
7
  - Ernst van Graan
8
+ - Wynand van Dyk
10
9
  autorequire:
11
10
  bindir: bin
12
11
  cert_chain: []
13
- date: 2015-08-28 00:00:00.000000000 Z
12
+ date: 2016-04-12 00:00:00.000000000 Z
14
13
  dependencies:
15
14
  - !ruby/object:Gem::Dependency
16
15
  name: rspec
17
16
  requirement: !ruby/object:Gem::Requirement
18
- none: false
19
17
  requirements:
20
18
  - - '='
21
19
  - !ruby/object:Gem::Version
@@ -23,7 +21,6 @@ dependencies:
23
21
  type: :development
24
22
  prerelease: false
25
23
  version_requirements: !ruby/object:Gem::Requirement
26
- none: false
27
24
  requirements:
28
25
  - - '='
29
26
  - !ruby/object:Gem::Version
@@ -31,102 +28,132 @@ dependencies:
31
28
  - !ruby/object:Gem::Dependency
32
29
  name: simplecov
33
30
  requirement: !ruby/object:Gem::Requirement
34
- none: false
35
31
  requirements:
36
- - - ! '>='
32
+ - - ">="
37
33
  - !ruby/object:Gem::Version
38
34
  version: '0'
39
35
  type: :development
40
36
  prerelease: false
41
37
  version_requirements: !ruby/object:Gem::Requirement
42
- none: false
43
38
  requirements:
44
- - - ! '>='
39
+ - - ">="
45
40
  - !ruby/object:Gem::Version
46
41
  version: '0'
47
42
  - !ruby/object:Gem::Dependency
48
43
  name: simplecov-rcov
49
44
  requirement: !ruby/object:Gem::Requirement
50
- none: false
51
45
  requirements:
52
- - - ! '>='
46
+ - - ">="
53
47
  - !ruby/object:Gem::Version
54
48
  version: '0'
55
49
  type: :development
56
50
  prerelease: false
57
51
  version_requirements: !ruby/object:Gem::Requirement
58
- none: false
59
52
  requirements:
60
- - - ! '>='
53
+ - - ">="
61
54
  - !ruby/object:Gem::Version
62
55
  version: '0'
63
56
  - !ruby/object:Gem::Dependency
64
- name: debugger
57
+ name: byebug
65
58
  requirement: !ruby/object:Gem::Requirement
66
- none: false
67
59
  requirements:
68
- - - ! '>='
60
+ - - ">="
69
61
  - !ruby/object:Gem::Version
70
62
  version: '0'
71
63
  type: :development
72
64
  prerelease: false
73
65
  version_requirements: !ruby/object:Gem::Requirement
74
- none: false
75
66
  requirements:
76
- - - ! '>='
67
+ - - ">="
77
68
  - !ruby/object:Gem::Version
78
69
  version: '0'
79
70
  - !ruby/object:Gem::Dependency
80
- name: sqlite3
71
+ name: eh
81
72
  requirement: !ruby/object:Gem::Requirement
82
- none: false
83
73
  requirements:
84
- - - '='
74
+ - - ">="
85
75
  - !ruby/object:Gem::Version
86
- version: 1.3.10
76
+ version: '0'
87
77
  type: :runtime
88
78
  prerelease: false
89
79
  version_requirements: !ruby/object:Gem::Requirement
90
- none: false
91
80
  requirements:
92
- - - '='
81
+ - - ">="
93
82
  - !ruby/object:Gem::Version
94
- version: 1.3.10
83
+ version: '0'
95
84
  - !ruby/object:Gem::Dependency
96
- name: eh
85
+ name: persistent-cache-storage-api
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ type: :runtime
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ - !ruby/object:Gem::Dependency
99
+ name: persistent-cache-storage-sqlite
97
100
  requirement: !ruby/object:Gem::Requirement
98
- none: false
99
101
  requirements:
100
- - - ! '>='
102
+ - - ">="
101
103
  - !ruby/object:Gem::Version
102
104
  version: '0'
103
105
  type: :runtime
104
106
  prerelease: false
105
107
  version_requirements: !ruby/object:Gem::Requirement
106
- none: false
107
108
  requirements:
108
- - - ! '>='
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ - !ruby/object:Gem::Dependency
113
+ name: persistent-cache-storage-directory
114
+ requirement: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ type: :runtime
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ - !ruby/object:Gem::Dependency
127
+ name: persistent-cache-storage-ram
128
+ requirement: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - ">="
131
+ - !ruby/object:Gem::Version
132
+ version: '0'
133
+ type: :runtime
134
+ prerelease: false
135
+ version_requirements: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - ">="
109
138
  - !ruby/object:Gem::Version
110
139
  version: '0'
111
140
  description: Persistent Cache using a pluggable back-end (e.g. SQLite)
112
141
  email:
113
- - wvd@hetzner.co.za
114
142
  - ernst.van.graan@hetzner.co.za
143
+ - wvd@hetzner.co.za
115
144
  executables: []
116
145
  extensions: []
117
146
  extra_rdoc_files: []
118
147
  files:
119
- - .gitignore
120
- - .rspec
121
- - .rvmrc
148
+ - ".gitignore"
149
+ - ".rspec"
150
+ - ".ruby-gemset"
151
+ - ".ruby-version"
122
152
  - Gemfile
123
153
  - LICENSE
124
154
  - README.md
125
155
  - Rakefile
126
156
  - lib/persistent-cache.rb
127
- - lib/persistent-cache/storage/storage_directory.rb
128
- - lib/persistent-cache/storage/storage_ram.rb
129
- - lib/persistent-cache/storage/storage_sq_lite.rb
130
157
  - lib/persistent-cache/version.rb
131
158
  - persistent-cache.gemspec
132
159
  - spec/persistent-cache_spec.rb
@@ -136,27 +163,26 @@ files:
136
163
  - spec/storage/storage_sqlite_spec.rb
137
164
  homepage: ''
138
165
  licenses: []
166
+ metadata: {}
139
167
  post_install_message:
140
168
  rdoc_options: []
141
169
  require_paths:
142
170
  - lib
143
171
  required_ruby_version: !ruby/object:Gem::Requirement
144
- none: false
145
172
  requirements:
146
- - - ! '>='
173
+ - - ">="
147
174
  - !ruby/object:Gem::Version
148
175
  version: '0'
149
176
  required_rubygems_version: !ruby/object:Gem::Requirement
150
- none: false
151
177
  requirements:
152
- - - ! '>='
178
+ - - ">="
153
179
  - !ruby/object:Gem::Version
154
180
  version: '0'
155
181
  requirements: []
156
182
  rubyforge_project:
157
- rubygems_version: 1.8.28
183
+ rubygems_version: 2.5.1
158
184
  signing_key:
159
- specification_version: 3
185
+ specification_version: 4
160
186
  summary: Persistent Cache has a default freshness threshold of 179 days after which
161
187
  entries are no longer returned
162
188
  test_files:
data/.rvmrc DELETED
@@ -1,48 +0,0 @@
1
- #!/usr/bin/env bash
2
-
3
- # This is an RVM Project .rvmrc file, used to automatically load the ruby
4
- # development environment upon cd'ing into the directory
5
-
6
- # First we specify our desired <ruby>[@<gemset>], the @gemset name is optional,
7
- # Only full ruby name is supported here, for short names use:
8
- # echo "rvm use 1.9.3" > .rvmrc
9
- environment_id="ruby-1.9.3-p194@persistent-hash"
10
-
11
- # Uncomment the following lines if you want to verify rvm version per project
12
- # rvmrc_rvm_version="1.14.3 (stable)" # 1.10.1 seams as a safe start
13
- # eval "$(echo ${rvm_version}.${rvmrc_rvm_version} | awk -F. '{print "[[ "$1*65536+$2*256+$3" -ge "$4*65536+$5*256+$6" ]]"}' )" || {
14
- # echo "This .rvmrc file requires at least RVM ${rvmrc_rvm_version}, aborting loading."
15
- # return 1
16
- # }
17
-
18
- # First we attempt to load the desired environment directly from the environment
19
- # file. This is very fast and efficient compared to running through the entire
20
- # CLI and selector. If you want feedback on which environment was used then
21
- # insert the word 'use' after --create as this triggers verbose mode.
22
- if [[ -d "${rvm_path:-$HOME/.rvm}/environments"
23
- && -s "${rvm_path:-$HOME/.rvm}/environments/$environment_id" ]]
24
- then
25
- \. "${rvm_path:-$HOME/.rvm}/environments/$environment_id"
26
- [[ -s "${rvm_path:-$HOME/.rvm}/hooks/after_use" ]] &&
27
- \. "${rvm_path:-$HOME/.rvm}/hooks/after_use" || true
28
- else
29
- # If the environment file has not yet been created, use the RVM CLI to select.
30
- rvm --create "$environment_id" || {
31
- echo "Failed to create RVM environment '${environment_id}'."
32
- return 1
33
- }
34
- fi
35
-
36
- # If you use bundler, this might be useful to you:
37
- # if [[ -s Gemfile ]] && {
38
- # ! builtin command -v bundle >/dev/null ||
39
- # builtin command -v bundle | GREP_OPTIONS= \grep $rvm_path/bin/bundle >/dev/null
40
- # }
41
- # then
42
- # printf "%b" "The rubygem 'bundler' is not installed. Installing it now.\n"
43
- # gem install bundler
44
- # fi
45
- # if [[ -s Gemfile ]] && builtin command -v bundle >/dev/null
46
- # then
47
- # bundle install | GREP_OPTIONS= \grep -vE '^Using|Your bundle is complete'
48
- # fi
@@ -1,170 +0,0 @@
1
- require 'fileutils'
2
- require 'tempfile'
3
- require 'pathname'
4
-
5
- module Persistent
6
- class StorageDirectory
7
- CACHE_FILE = "cache.gz" unless defined? CACHE_FILE; CACHE_FILE.freeze
8
-
9
- attr_accessor :storage_root
10
-
11
- def initialize(storage_details)
12
- raise ArgumentError.new("Storage details not provided") if storage_details.nil? or storage_details == ""
13
- @storage_root = storage_details
14
- connect_to_database
15
- end
16
-
17
- def connect_to_database
18
- FileUtils.makedirs([@storage_root]) if not File.directory?(@storage_root)
19
- end
20
-
21
- def save_key_value_pair(key, value, timestamp = nil)
22
- prepare_to_store_key_value(key, value, timestamp)
23
- store_key_value(key, value, get_time(timestamp)) if not value.nil?
24
- end
25
-
26
- def lookup_key(key)
27
- validate_key(key)
28
- return [] if not File.exists? compile_value_path(key)
29
- lookup_key_value_timestamp(key)
30
- end
31
-
32
- def delete_entry(key)
33
- validate_key(key)
34
- FileUtils.rm_rf(compile_key_path(key))
35
- end
36
-
37
- def size
38
- count = Dir::glob("#{@storage_root}/**/#{CACHE_FILE}").size
39
- end
40
-
41
- def keys
42
- return [] if size == 0
43
- list_keys_sorted
44
- end
45
-
46
- def clear
47
- keys.each do |key|
48
- delete_entry(key[0])
49
- end
50
- end
51
-
52
- def get_value_path(key)
53
- validate_key(key)
54
-
55
- return nil if not key_cached?(key)
56
-
57
- compile_value_path(key)
58
- end
59
-
60
- def get_value_path_even_when_not_cached(key)
61
- compile_value_path(key)
62
- end
63
-
64
- def key_cached?(key)
65
- # don't read the value here, as it may be very large - rather look whether the key is present
66
- File.exists? compile_key_path(key)
67
- end
68
-
69
- private
70
-
71
- def list_keys_sorted
72
- result = []
73
- append_keys(result).sort
74
- end
75
-
76
- def append_keys(result)
77
- get_key_directories.each do |dir|
78
- result << extract_key_from_directory(dir)
79
- end
80
- result
81
- end
82
-
83
- def get_key_directories
84
- subdirectories = Dir::glob("#{@storage_root}/**/")
85
- #exclude the storage root directory itself
86
- subdirectories[1..-1]
87
- end
88
-
89
- def extract_key_from_directory(dir)
90
- key = dir.match(/#{@storage_root}\/(\w+)\//)[1]
91
- [key]
92
- end
93
-
94
- def compile_key_path(key)
95
- "#{@storage_root}/#{key}"
96
- end
97
-
98
- def compile_value_path(key)
99
- "#{compile_key_path(key)}/#{CACHE_FILE}"
100
- end
101
-
102
- def validate_save_key_value_pair(key, value)
103
- validate_key(key)
104
- raise ArgumentError.new("Only string values allowed") if not value.is_a?(String)
105
- end
106
-
107
- def lookup_key_value_timestamp(key)
108
- result = [[],[]]
109
- data = File.read(compile_value_path(key))
110
- format_value_timestamp(result, data)
111
- end
112
-
113
- def format_value_timestamp(result, data)
114
- result[0][0] = data.lines.to_a[1..-1].join
115
- result[0][1] = data.lines.to_a[0..0].join.split("\n")[0]
116
- result
117
- end
118
-
119
- def validate_key(key)
120
- raise ArgumentError.new("Only string keys allowed") if not key.is_a?(String)
121
- root_path = Pathname.new(File.absolute_path(@storage_root))
122
- key_path = Pathname.new(File.absolute_path(compile_key_path(key)))
123
- relative = key_path.relative_path_from(root_path).to_s
124
- raise ArgumentError.new("key is outside of storage_root scope") if relative.start_with?("..")
125
- raise ArgumentError.new("key is the same as storage_root") if relative == "."
126
- end
127
-
128
- def empty_key_value(key)
129
- FileUtils.makedirs([compile_key_path(key)]) if not File.exists?(compile_key_path(key))
130
- FileUtils.rm_f(compile_value_path(key))
131
- end
132
-
133
- def get_time(timestamp)
134
- timestamp.nil? ? Time.now.to_s : timestamp.to_s
135
- end
136
-
137
- def prepare_to_store_key_value(key, value, timestamp)
138
- validate_save_key_value_pair(key, value)
139
- delete_entry(key)
140
- empty_key_value(key)
141
- end
142
-
143
- def store_key_value(key, value, timestamp)
144
- tempfile = Tempfile.new("store_key_value")
145
- store_value_timestamp_in_file(value, timestamp, tempfile)
146
- sync_cache_value(key, tempfile)
147
- end
148
-
149
- def sync_cache_value(key, tempfile)
150
- target = compile_value_path(key)
151
- FileUtils.rm_f(target)
152
- FileUtils.move(tempfile.path, target)
153
- end
154
-
155
- def store_value_timestamp_in_file(value, timestamp, tempfile)
156
- output = File.open(tempfile, 'a')
157
- write_value_timestamp(output, value, timestamp)
158
- output.close
159
- end
160
-
161
- def write_value_timestamp(output, value, timestamp)
162
- # Have to be explicit about writing to the file. 'puts' collapses newline at the end of the file and
163
- # so does not guarantee exact replication of 'value' on lookup
164
- output.write(timestamp)
165
- output.write("\n")
166
- output.write(value)
167
- output.flush
168
- end
169
- end
170
- end
@@ -1,51 +0,0 @@
1
- require "eh/eh"
2
-
3
- module Persistent
4
- class StorageRAM
5
- attr_accessor :storage
6
-
7
- def initialize()
8
- @storage = {}
9
- end
10
-
11
- def save_key_value_pair(serialized_key, serialized_value, timestamp = nil)
12
- delete_entry(serialized_key)
13
- time_entry = timestamp.nil? ? Time.now.to_s : timestamp.to_s
14
- EH::retry!(:args => [serialized_key, serialized_value, time_entry]) do
15
- @storage[serialized_key] = {:value => serialized_value, :timestamp => time_entry}
16
- end
17
- end
18
-
19
- def lookup_key(serialized_key)
20
- EH::retry!(:args => [serialized_key]) do
21
- return [] if @storage[serialized_key].nil?
22
- [@storage[serialized_key][:value], @storage[serialized_key][:timestamp]]
23
- end
24
- end
25
-
26
- def delete_entry(serialized_key)
27
- EH::retry!(:args => [serialized_key]) do
28
- @storage.delete(serialized_key)
29
- end
30
- end
31
-
32
- def size
33
- EH::retry!(:args => []) do
34
- @storage.size
35
- end
36
- end
37
-
38
- def keys
39
- EH::retry!(:args => []) do
40
- return [] if @storage.keys == []
41
- [@storage.keys]
42
- end
43
- end
44
-
45
- def clear
46
- EH::retry!(:args => []) do
47
- @storage.clear
48
- end
49
- end
50
- end
51
- end
@@ -1,97 +0,0 @@
1
- require "sqlite3"
2
- require "base64"
3
- require "eh/eh"
4
-
5
- module Persistent
6
- class StorageSQLite
7
- DB_TABLE = "key_value" unless defined? DB_TABLE; DB_TABLE.freeze
8
- DB_TIMEOUT = 30000 unless defined? DB_TIMEOUT; DB_TIMEOUT.freeze
9
-
10
- attr_accessor :storage_details
11
- attr_accessor :storage_handler
12
-
13
- def initialize(storage_details)
14
- raise ArgumentError.new("Storage details not provided") if storage_details.nil? or storage_details == ""
15
- @storage_details = storage_details
16
- @storage_handler = connect_to_database
17
- @storage_handler.busy_timeout = 30000
18
- end
19
-
20
- def save_key_value_pair(key, value, timestamp = nil)
21
- delete_entry(key)
22
- time_entry = timestamp.nil? ? Time.now.to_s : timestamp.to_s
23
- EH::retry!(:args => [serialize(key), serialize(value), time_entry]) do
24
- @storage_handler.execute("INSERT INTO #{DB_TABLE} (key, value, timestamp) VALUES(?, ?, ?)",serialize(key), serialize(value), time_entry)
25
- end
26
- end
27
-
28
- def lookup_key(key)
29
- EH::retry!(:args => [serialize(key)]) do
30
- result = @storage_handler.execute("SELECT value, timestamp FROM #{DB_TABLE} WHERE key=?", serialize(key))
31
- !result.nil? && !result.empty? ? [deserialize(result[0][0]), result[0][1]] : nil
32
- end
33
- end
34
-
35
- def delete_entry(key)
36
- EH::retry!(:args => [serialize(key)]) do
37
- @storage_handler.execute("DELETE FROM #{DB_TABLE} WHERE key=?", serialize(key))
38
- end
39
- end
40
-
41
- def size
42
- EH::retry!(:args => []) do
43
- @storage_handler.execute("SELECT value FROM #{DB_TABLE}").size
44
- end
45
- end
46
-
47
- def keys
48
- EH::retry!(:args => []) do
49
- @storage_handler.execute("SELECT key FROM #{DB_TABLE}").collect { |k| deserialize(k[0]) }
50
- end
51
- end
52
-
53
- def clear
54
- EH::retry!(:args => []) do
55
- @storage_handler.execute("DELETE FROM #{DB_TABLE}")
56
- end
57
- end
58
-
59
- private
60
-
61
- def serialize(data)
62
- Base64.encode64(Marshal.dump(data))
63
- end
64
-
65
- def deserialize(data)
66
- Marshal.load(Base64.decode64(data))
67
-
68
- rescue TypeError => ex
69
- Marshal.load(data)
70
- end
71
-
72
- def connect_to_database
73
- File.exists?(@storage_details) ? open_database : create_database
74
- end
75
-
76
- def open_database
77
- EH::retry!(:args => []) do
78
- SQLite3::Database.open(@storage_details)
79
- end
80
- end
81
-
82
- def create_database
83
- EH::retry!(:args => []) do
84
- @storage_handler = SQLite3::Database.new(@storage_details)
85
- create_table
86
- end
87
- @storage_handler
88
- end
89
-
90
- def create_table
91
- EH::retry!(:args => []) do
92
- @storage_handler.execute("CREATE TABLE #{DB_TABLE}(key TEXT PRIMARY KEY, value TEXT, timestamp TEXT)")
93
- end
94
- @storage_handler
95
- end
96
- end
97
- end