expires 0.0.1 → 0.0.2
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 +4 -4
- data/expires.gemspec +3 -3
- data/lib/expires/version.rb +1 -1
- data/lib/expires.rb +141 -14
- data/spec/expires_spec.rb +0 -21
- metadata +17 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 56e31be07a9e1e953a4b0ad9d2e6d0b412c53cf7
|
4
|
+
data.tar.gz: e6719430566a092eead55ce856d514f090da2308
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4fded42175255292c7d97e954813e8e88381c1caf3b295fb326646df06599c52546ed31730cfab339eda524b4412a974bfba9d4fe187adc721525da0f7352c72
|
7
|
+
data.tar.gz: e47cdeb20c79b66c30eaaa4b11dbc78a444363dbe82211fd187774cd8364bca08187279a131944ef06fb802ca48103962ff33e0f2d59c5950fa6621e39974f6a
|
data/expires.gemspec
CHANGED
@@ -18,10 +18,10 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
+
spec.add_dependency 'color_print'
|
22
|
+
spec.add_dependency 'sqlite3'
|
23
|
+
|
21
24
|
spec.add_development_dependency "bundler", "~> 1.6"
|
22
25
|
spec.add_development_dependency "rake"
|
23
26
|
spec.add_development_dependency "rspec"
|
24
|
-
spec.add_development_dependency "color_print"
|
25
|
-
spec.add_development_dependency "sqlite3"
|
26
|
-
|
27
27
|
end
|
data/lib/expires/version.rb
CHANGED
data/lib/expires.rb
CHANGED
@@ -1,8 +1,13 @@
|
|
1
1
|
require "expires/version"
|
2
2
|
require 'sqlite3'
|
3
|
+
require 'json'
|
4
|
+
require 'pry'
|
3
5
|
|
4
6
|
class Expires
|
5
7
|
class DummyIO;def puts str;end;end
|
8
|
+
|
9
|
+
KEYS = %w[key value created_at updated_at expire on_expire remind]
|
10
|
+
SCHEMA = %Q(create table NAMESPACE (key TEXT PRIMARY KEY, value TEXT, created_at INTEGER, updated_at INTEGER, expire INTEGER, on_expire TEXT, remind TEXT);)
|
6
11
|
|
7
12
|
@@dbs = Hash.new #namespace: instance
|
8
13
|
@@database = 'expires.sqlite3'
|
@@ -28,6 +33,7 @@ class Expires
|
|
28
33
|
@expire = expire
|
29
34
|
@hotload = hotload
|
30
35
|
@body = Hash.new
|
36
|
+
@remind = Hash.new
|
31
37
|
|
32
38
|
connect(namespace)
|
33
39
|
sync if @hotload
|
@@ -42,9 +48,13 @@ class Expires
|
|
42
48
|
@synced = true
|
43
49
|
end
|
44
50
|
|
51
|
+
def schema namespace
|
52
|
+
return SCHEMA.gsub("NAMESPACE",namespace)
|
53
|
+
end
|
54
|
+
|
45
55
|
def create(namespace)
|
46
56
|
begin
|
47
|
-
@@db.execute(sql =
|
57
|
+
@@db.execute(sql = schema(namespace))
|
48
58
|
@@io.puts sql
|
49
59
|
rescue SQLite3::SQLException => e
|
50
60
|
raise e unless e.message =~ /table .* already exists/
|
@@ -53,9 +63,26 @@ class Expires
|
|
53
63
|
end
|
54
64
|
|
55
65
|
def kill_expired
|
66
|
+
@killing = true
|
56
67
|
now = Time.new.to_i
|
68
|
+
expires = @@db.execute(sql = "select on_expire, key, value from #{@namespace} where (updated_at+expire) < #{now};")
|
69
|
+
expires.each do |values|
|
70
|
+
if values[0]
|
71
|
+
begin
|
72
|
+
@key = values[1]
|
73
|
+
@value = values[2]
|
74
|
+
flash(@key)
|
75
|
+
eval values[0].gsub("$n","\n")
|
76
|
+
rescue =>e
|
77
|
+
STDERR.puts e
|
78
|
+
STDERR.puts e.backtrace
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
57
83
|
@@db.execute(sql = "delete from #{@namespace} where (updated_at+expire) < #{now};")
|
58
84
|
@@io.puts sql
|
85
|
+
@killing = nil
|
59
86
|
end
|
60
87
|
|
61
88
|
def connect(namespace)
|
@@ -75,10 +102,9 @@ class Expires
|
|
75
102
|
end
|
76
103
|
end
|
77
104
|
|
78
|
-
def set key, value
|
105
|
+
def set key, value, expire = @expire
|
79
106
|
@body[key] = value
|
80
|
-
|
81
|
-
record = @@db.execute("select created_at from #{@namespace} where key = '#{key}' limit 1;").first
|
107
|
+
record = select(key, :created_at)
|
82
108
|
|
83
109
|
if record
|
84
110
|
created_at = record[0]
|
@@ -86,25 +112,126 @@ class Expires
|
|
86
112
|
else
|
87
113
|
updated_at = created_at = Time.new.to_i
|
88
114
|
end
|
89
|
-
|
90
|
-
@@db.execute(sql="insert or replace into #{@namespace} (key,value,created_at,updated_at,expire)
|
115
|
+
|
116
|
+
@@db.execute(sql="insert or replace into #{@namespace} (key,value,created_at,updated_at,expire)"+
|
117
|
+
" values ('#{key}','#{value}','#{created_at}','#{updated_at}','#{expire}'#{});")
|
91
118
|
@@io.puts sql
|
92
119
|
#TODO: syncedで状態管理
|
93
120
|
end
|
94
121
|
|
95
|
-
def [](key)
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
122
|
+
def []=(key,value)
|
123
|
+
set(key,value)
|
124
|
+
end
|
125
|
+
|
126
|
+
def clean
|
127
|
+
@@db.execute("delete from #{@namespace};")
|
128
|
+
@@db.execute("VACUUM;")
|
129
|
+
end
|
130
|
+
|
131
|
+
def remind key, hash
|
132
|
+
raise "Remind your value as Hash." unless hash.is_a?(Hash)
|
133
|
+
update key, :remind, JSON.generate(hash) if get key
|
134
|
+
@remind[key.to_sym] = hash
|
135
|
+
end
|
136
|
+
|
137
|
+
def forget key
|
138
|
+
raise "Remind your value as Hash." unless hash.is_a?(Hash)
|
139
|
+
update key, :remind, "{}" if get key
|
140
|
+
@remind[key.to_sym] = {}
|
141
|
+
end
|
142
|
+
|
143
|
+
def flash key
|
144
|
+
if value = select(key, :remind)
|
145
|
+
begin
|
146
|
+
@remind = JSON.parse value.first
|
147
|
+
rescue
|
148
|
+
STDERR.puts "Invalid JSON value."
|
149
|
+
end
|
101
150
|
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def select key, *columns
|
154
|
+
kill_expired unless @killing
|
155
|
+
return @body[key.to_sym] = @@db.execute("select #{columns.join(", ")} from #{@namespace} where key = '#{key}' limit 1;").first
|
156
|
+
end
|
157
|
+
|
158
|
+
def get key
|
159
|
+
return select(key, :value).first
|
102
160
|
rescue => e
|
103
161
|
return nil
|
104
162
|
end
|
105
163
|
|
106
|
-
def []
|
107
|
-
|
164
|
+
def [](key)
|
165
|
+
get key
|
166
|
+
end
|
167
|
+
|
168
|
+
def update key, column, value
|
169
|
+
sql = Expires.escape_sqlite3("update :_namespace_ set #{column} = (:#{column}) where key = (:key);",
|
170
|
+
column=>value,
|
171
|
+
:key=>key,
|
172
|
+
:_namespace_=>@namespace)
|
173
|
+
@@db.execute(sql)
|
174
|
+
sql
|
175
|
+
end
|
176
|
+
|
177
|
+
def updates key, hash
|
178
|
+
sql = "update :_namespace_ set "
|
179
|
+
first = true
|
180
|
+
hash.each do |k, v|
|
181
|
+
if first
|
182
|
+
first = false
|
183
|
+
else
|
184
|
+
sql << ','
|
185
|
+
end
|
186
|
+
sql << "#{k} = :#{k} "
|
187
|
+
end
|
188
|
+
sql << "where key = (:key);"
|
189
|
+
|
190
|
+
sql = Expires.escape_sqlite3(sql,
|
191
|
+
:key=>key,
|
192
|
+
:_namespace_=>@namespace,
|
193
|
+
**hash)
|
194
|
+
@@db.execute(sql)
|
195
|
+
sql
|
196
|
+
end
|
197
|
+
|
198
|
+
def closer key, procedure=nil, remind: nil, &block
|
199
|
+
if block_given?
|
200
|
+
obj = Object.new
|
201
|
+
obj.define_singleton_method(:_, &block)
|
202
|
+
procedure = obj.method(:_).to_proc
|
203
|
+
end
|
204
|
+
|
205
|
+
source = Expires.get_source_str(procedure.source).gsub(/\n/,"$n")
|
206
|
+
if get key
|
207
|
+
sql = updates key, {:on_expire=>source.to_s, :remind=>JSON.generate(remind)}
|
208
|
+
else
|
209
|
+
#procedure.call
|
210
|
+
return
|
211
|
+
end
|
212
|
+
|
213
|
+
kill_expired
|
214
|
+
@@io.puts sql
|
215
|
+
end
|
216
|
+
|
217
|
+
def self.get_source_str source
|
218
|
+
source.gsub!(/\n/,"$n")
|
219
|
+
source.gsub!(/\A.*?(-> +\(.*\)|lambda) +?(do|\{)( +)?(\|.*?\|)?/, "")
|
220
|
+
source.gsub!(/\A.*?closer.*?(do|\{)( +)?(\|.*?\|)?/, "")
|
221
|
+
source.reverse!
|
222
|
+
source.gsub!(/\A(.*?)(dne|\})/, "")
|
223
|
+
source.reverse!
|
224
|
+
source.gsub!("$n","\n")
|
225
|
+
return source
|
226
|
+
end
|
227
|
+
|
228
|
+
def self.escape_sqlite3(string, **hash)
|
229
|
+
hash.each do |key, value|
|
230
|
+
value.gsub!(/'/,"''") if value.is_a?(String)
|
231
|
+
value = "null" if value.nil?
|
232
|
+
string.gsub!(":#{key}", "'#{value}'")
|
233
|
+
end
|
234
|
+
return string
|
108
235
|
end
|
109
236
|
end
|
110
237
|
|
data/spec/expires_spec.rb
CHANGED
@@ -30,29 +30,8 @@ describe Expires do
|
|
30
30
|
expect(expires["b"]).to eq 'b'
|
31
31
|
end
|
32
32
|
end
|
33
|
-
|
34
|
-
describe "when hotload is false" do
|
35
|
-
expires = Expires.new(namespace: "on_initialize_when_hotload_is_false")
|
36
|
-
expires["a"] = :a
|
37
|
-
expires["b"] = :b
|
38
|
-
expires.disconnect
|
39
|
-
|
40
|
-
expires = Expires.new(namespace: "on_initialize_when_hotload_is_false", hotload: false)
|
41
|
-
it "have to loaded 'a' as nil" do
|
42
|
-
expect(expires["a"]).to eq nil
|
43
|
-
end
|
44
|
-
|
45
|
-
it "have to loaded 'b' as nil" do
|
46
|
-
expect(expires["b"]).to eq nil
|
47
|
-
end
|
48
|
-
end
|
49
33
|
end
|
50
34
|
|
51
|
-
context "when not connected" do
|
52
|
-
end
|
53
|
-
|
54
|
-
context "when connected" do
|
55
|
-
end
|
56
35
|
|
57
36
|
|
58
37
|
|
metadata
CHANGED
@@ -1,37 +1,37 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: expires
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tatumaki
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-10-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: color_print
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
20
|
-
type: :
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: sqlite3
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0'
|
34
|
-
type: :
|
34
|
+
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
@@ -39,21 +39,21 @@ dependencies:
|
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: bundler
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - "
|
45
|
+
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '1.6'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - "
|
52
|
+
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
54
|
+
version: '1.6'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: rake
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - ">="
|
@@ -67,7 +67,7 @@ dependencies:
|
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: rspec
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - ">="
|