moneta 1.4.1 → 1.5.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +425 -0
- data/CHANGES +17 -0
- data/CONTRIBUTORS +2 -0
- data/Gemfile +161 -60
- data/README.md +21 -17
- data/lib/moneta/adapter.rb +52 -0
- data/lib/moneta/adapters/activerecord.rb +77 -68
- data/lib/moneta/adapters/activesupportcache.rb +22 -31
- data/lib/moneta/adapters/cassandra.rb +114 -116
- data/lib/moneta/adapters/client.rb +17 -18
- data/lib/moneta/adapters/couch.rb +31 -26
- data/lib/moneta/adapters/datamapper.rb +9 -5
- data/lib/moneta/adapters/daybreak.rb +15 -21
- data/lib/moneta/adapters/dbm.rb +6 -12
- data/lib/moneta/adapters/file.rb +21 -13
- data/lib/moneta/adapters/fog.rb +5 -6
- data/lib/moneta/adapters/gdbm.rb +6 -12
- data/lib/moneta/adapters/hbase.rb +10 -12
- data/lib/moneta/adapters/kyotocabinet.rb +22 -27
- data/lib/moneta/adapters/leveldb.rb +14 -20
- data/lib/moneta/adapters/lmdb.rb +19 -22
- data/lib/moneta/adapters/localmemcache.rb +7 -13
- data/lib/moneta/adapters/lruhash.rb +20 -20
- data/lib/moneta/adapters/memcached/dalli.rb +25 -33
- data/lib/moneta/adapters/memcached/native.rb +14 -20
- data/lib/moneta/adapters/memory.rb +5 -7
- data/lib/moneta/adapters/mongo.rb +53 -52
- data/lib/moneta/adapters/pstore.rb +21 -27
- data/lib/moneta/adapters/redis.rb +42 -37
- data/lib/moneta/adapters/restclient.rb +17 -25
- data/lib/moneta/adapters/riak.rb +8 -9
- data/lib/moneta/adapters/sdbm.rb +6 -12
- data/lib/moneta/adapters/sequel/mysql.rb +8 -8
- data/lib/moneta/adapters/sequel/postgres.rb +17 -17
- data/lib/moneta/adapters/sequel/postgres_hstore.rb +47 -47
- data/lib/moneta/adapters/sequel/sqlite.rb +9 -9
- data/lib/moneta/adapters/sequel.rb +56 -65
- data/lib/moneta/adapters/sqlite.rb +37 -35
- data/lib/moneta/adapters/tdb.rb +8 -14
- data/lib/moneta/adapters/tokyocabinet.rb +19 -17
- data/lib/moneta/adapters/tokyotyrant.rb +29 -30
- data/lib/moneta/adapters/yaml.rb +1 -5
- data/lib/moneta/config.rb +101 -0
- data/lib/moneta/expires.rb +0 -1
- data/lib/moneta/expires_support.rb +3 -4
- data/lib/moneta/pool.rb +27 -7
- data/lib/moneta/proxy.rb +29 -0
- data/lib/moneta/server.rb +21 -14
- data/lib/moneta/version.rb +1 -1
- data/lib/moneta/wrapper.rb +5 -0
- data/lib/moneta.rb +2 -0
- data/moneta.gemspec +1 -0
- data/spec/active_support/cache_moneta_store_spec.rb +13 -13
- data/spec/features/null.rb +28 -28
- data/spec/features/persist.rb +3 -3
- data/spec/features/returndifferent.rb +4 -4
- data/spec/features/returnsame.rb +4 -4
- data/spec/features/store.rb +104 -104
- data/spec/helper.rb +15 -4
- data/spec/moneta/adapters/activerecord/adapter_activerecord_existing_connection_spec.rb +3 -1
- data/spec/moneta/adapters/activerecord/adapter_activerecord_spec.rb +15 -7
- data/spec/moneta/adapters/activerecord/standard_activerecord_spec.rb +5 -2
- data/spec/moneta/adapters/activerecord/standard_activerecord_with_expires_spec.rb +5 -2
- data/spec/moneta/adapters/activesupportcache/adapter_activesupportcache_spec.rb +3 -3
- data/spec/moneta/adapters/activesupportcache/adapter_activesupportcache_with_default_expires_spec.rb +2 -2
- data/spec/moneta/adapters/cassandra/adapter_cassandra_spec.rb +1 -1
- data/spec/moneta/adapters/cassandra/adapter_cassandra_with_default_expires_spec.rb +1 -1
- data/spec/moneta/adapters/cassandra/standard_cassandra_spec.rb +1 -1
- data/spec/moneta/adapters/client/client_helper.rb +4 -3
- data/spec/moneta/adapters/datamapper/adapter_datamapper_spec.rb +25 -8
- data/spec/moneta/adapters/datamapper/standard_datamapper_spec.rb +2 -2
- data/spec/moneta/adapters/datamapper/standard_datamapper_with_expires_spec.rb +2 -2
- data/spec/moneta/adapters/datamapper/standard_datamapper_with_repository_spec.rb +2 -2
- data/spec/moneta/adapters/faraday_helper.rb +3 -2
- data/spec/moneta/adapters/lruhash/adapter_lruhash_spec.rb +10 -6
- data/spec/moneta/adapters/memcached/dalli/adapter_memcached_dalli_spec.rb +13 -3
- data/spec/moneta/adapters/memcached/native/adapter_memcached_native_spec.rb +13 -3
- data/spec/moneta/adapters/mongo/adapter_mongo_spec.rb +2 -2
- data/spec/moneta/adapters/mongo/adapter_mongo_with_default_expires_spec.rb +1 -1
- data/spec/moneta/adapters/redis/adapter_redis_spec.rb +13 -3
- data/spec/moneta/adapters/redis/standard_redis_spec.rb +8 -1
- data/spec/moneta/adapters/sequel/adapter_sequel_spec.rb +4 -4
- data/spec/moneta/adapters/sequel/helper.rb +10 -5
- data/spec/moneta/adapters/sequel/standard_sequel_spec.rb +1 -1
- data/spec/moneta/adapters/sequel/standard_sequel_with_expires_spec.rb +1 -1
- data/spec/moneta/adapters/sqlite/adapter_sqlite_spec.rb +1 -1
- data/spec/moneta/adapters/sqlite/standard_sqlite_spec.rb +1 -1
- data/spec/moneta/adapters/sqlite/standard_sqlite_with_expires_spec.rb +1 -1
- data/spec/moneta/config_spec.rb +219 -0
- data/spec/moneta/proxies/enumerable/enumerable_spec.rb +2 -2
- data/spec/moneta/proxies/pool/pool_spec.rb +31 -3
- data/spec/moneta/proxies/transformer/transformer_bson_spec.rb +3 -1
- data/spec/moneta/proxies/transformer/transformer_marshal_escape_spec.rb +2 -0
- data/spec/rack/session_moneta_spec.rb +44 -25
- data/spec/restserver.rb +3 -14
- metadata +25 -15
- data/.travis.yml +0 -146
- data/spec/moneta/adapters/memcached/dalli/adapter_memcached_dalli_with_default_expires_spec.rb +0 -15
- data/spec/moneta/adapters/memcached/native/adapter_memcached_native_with_default_expires_spec.rb +0 -15
- data/spec/moneta/adapters/redis/adapter_redis_with_default_expires_spec.rb +0 -10
- data/spec/moneta/proxies/proxy/proxy_redis_spec.rb +0 -13
@@ -12,7 +12,7 @@ module Moneta
|
|
12
12
|
|
13
13
|
def key?(key, options = {})
|
14
14
|
if @key
|
15
|
-
row = @key.call(row:
|
15
|
+
row = @key.call(row: config.hstore, key: key) || false
|
16
16
|
row && row[:present]
|
17
17
|
else
|
18
18
|
@key_pl.get(key)
|
@@ -22,13 +22,13 @@ module Moneta
|
|
22
22
|
def store(key, value, options = {})
|
23
23
|
@backend.transaction do
|
24
24
|
create_row
|
25
|
-
@store.call(row:
|
25
|
+
@store.call(row: config.hstore, pair: ::Sequel.hstore(key => value))
|
26
26
|
end
|
27
27
|
value
|
28
28
|
end
|
29
29
|
|
30
30
|
def load(key, options = {})
|
31
|
-
if row = @load.call(row:
|
31
|
+
if row = @load.call(row: config.hstore, key: key)
|
32
32
|
row[:value]
|
33
33
|
end
|
34
34
|
end
|
@@ -36,7 +36,7 @@ module Moneta
|
|
36
36
|
def delete(key, options = {})
|
37
37
|
@backend.transaction do
|
38
38
|
value = load(key, options)
|
39
|
-
@delete.call(row:
|
39
|
+
@delete.call(row: config.hstore, key: key)
|
40
40
|
value
|
41
41
|
end
|
42
42
|
end
|
@@ -44,7 +44,7 @@ module Moneta
|
|
44
44
|
def increment(key, amount = 1, options = {})
|
45
45
|
@backend.transaction do
|
46
46
|
create_row
|
47
|
-
if row = @increment.call(row:
|
47
|
+
if row = @increment.call(row: config.hstore, key: key, amount: amount).first
|
48
48
|
row[:value].to_i
|
49
49
|
end
|
50
50
|
end
|
@@ -55,23 +55,23 @@ module Moneta
|
|
55
55
|
create_row
|
56
56
|
1 ==
|
57
57
|
if @create
|
58
|
-
@create.call(row:
|
58
|
+
@create.call(row: config.hstore, key: key, pair: ::Sequel.hstore(key => value))
|
59
59
|
else
|
60
60
|
@table
|
61
|
-
.where(key_column =>
|
62
|
-
.exclude(::Sequel[value_column].hstore.key?(key))
|
63
|
-
.update(value_column => ::Sequel[value_column].hstore.merge(key => value))
|
61
|
+
.where(config.key_column => config.hstore)
|
62
|
+
.exclude(::Sequel[config.value_column].hstore.key?(key))
|
63
|
+
.update(config.value_column => ::Sequel[config.value_column].hstore.merge(key => value))
|
64
64
|
end
|
65
65
|
end
|
66
66
|
end
|
67
67
|
|
68
68
|
def clear(options = {})
|
69
|
-
@clear.call(row:
|
69
|
+
@clear.call(row: config.hstore)
|
70
70
|
self
|
71
71
|
end
|
72
72
|
|
73
73
|
def values_at(*keys, **options)
|
74
|
-
if row = @values_at.call(row:
|
74
|
+
if row = @values_at.call(row: config.hstore, keys: ::Sequel.pg_array(keys))
|
75
75
|
row[:values].to_a
|
76
76
|
else
|
77
77
|
[]
|
@@ -79,7 +79,7 @@ module Moneta
|
|
79
79
|
end
|
80
80
|
|
81
81
|
def slice(*keys, **options)
|
82
|
-
if row = @slice.call(row:
|
82
|
+
if row = @slice.call(row: config.hstore, keys: ::Sequel.pg_array(keys))
|
83
83
|
row[:pairs].to_h
|
84
84
|
else
|
85
85
|
[]
|
@@ -91,24 +91,24 @@ module Moneta
|
|
91
91
|
create_row
|
92
92
|
pairs = yield_merge_pairs(pairs, &block) if block_given?
|
93
93
|
hash = Hash === pairs ? pairs : Hash[pairs.to_a]
|
94
|
-
@store.call(row:
|
94
|
+
@store.call(row: config.hstore, pair: ::Sequel.hstore(hash))
|
95
95
|
end
|
96
96
|
|
97
97
|
self
|
98
98
|
end
|
99
99
|
|
100
100
|
def each_key
|
101
|
-
return enum_for(:each_key) { @size.call(row:
|
101
|
+
return enum_for(:each_key) { @size.call(row: config.hstore)[:size] } unless block_given?
|
102
102
|
|
103
103
|
ds =
|
104
|
-
if
|
105
|
-
@table.server(
|
104
|
+
if config.each_key_server
|
105
|
+
@table.server(config.each_key_server)
|
106
106
|
else
|
107
107
|
@table
|
108
108
|
end
|
109
109
|
ds = ds.order(:skeys) unless @table.respond_to?(:use_cursor)
|
110
|
-
ds.where(key_column =>
|
111
|
-
.select(::Sequel[value_column].hstore.skeys)
|
110
|
+
ds.where(config.key_column => config.hstore)
|
111
|
+
.select(::Sequel[config.value_column].hstore.skeys)
|
112
112
|
.paged_each do |row|
|
113
113
|
yield row[:skeys]
|
114
114
|
end
|
@@ -118,14 +118,14 @@ module Moneta
|
|
118
118
|
protected
|
119
119
|
|
120
120
|
def create_row
|
121
|
-
@create_row.call(row:
|
121
|
+
@create_row.call(row: config.hstore)
|
122
122
|
end
|
123
123
|
|
124
124
|
def create_table
|
125
|
-
key_column =
|
126
|
-
value_column =
|
125
|
+
key_column = config.key_column
|
126
|
+
value_column = config.value_column
|
127
127
|
|
128
|
-
@backend.create_table?(
|
128
|
+
@backend.create_table?(config.table) do
|
129
129
|
column key_column, String, null: false, primary_key: true
|
130
130
|
column value_column, :hstore
|
131
131
|
index value_column, type: :gin
|
@@ -134,7 +134,7 @@ module Moneta
|
|
134
134
|
|
135
135
|
def slice_for_update(pairs)
|
136
136
|
keys = pairs.map { |k, _| k }.to_a
|
137
|
-
if row = @slice_for_update.call(row:
|
137
|
+
if row = @slice_for_update.call(row: config.hstore, keys: ::Sequel.pg_array(keys))
|
138
138
|
row[:pairs].to_h
|
139
139
|
else
|
140
140
|
{}
|
@@ -152,53 +152,53 @@ module Moneta
|
|
152
152
|
def prepare_create_row
|
153
153
|
@create_row = @table
|
154
154
|
.insert_ignore
|
155
|
-
.prepare(:insert, statement_id(:hstore_create_row), key_column => :$row, value_column => '')
|
155
|
+
.prepare(:insert, statement_id(:hstore_create_row), config.key_column => :$row, config.value_column => '')
|
156
156
|
end
|
157
157
|
|
158
158
|
def prepare_clear
|
159
|
-
@clear = @table.where(key_column => :$row).prepare(:update, statement_id(:hstore_clear), value_column => '')
|
159
|
+
@clear = @table.where(config.key_column => :$row).prepare(:update, statement_id(:hstore_clear), config.value_column => '')
|
160
160
|
end
|
161
161
|
|
162
162
|
def prepare_key
|
163
163
|
if defined?(JRUBY_VERSION)
|
164
164
|
@key_pl = ::Sequel::Dataset::PlaceholderLiteralizer.loader(@table) do |pl, ds|
|
165
|
-
ds.where(key_column =>
|
165
|
+
ds.where(config.key_column => config.hstore).select(::Sequel[config.value_column].hstore.key?(pl.arg))
|
166
166
|
end
|
167
167
|
else
|
168
|
-
@key = @table.where(key_column => :$row)
|
169
|
-
.select(::Sequel[value_column].hstore.key?(:$key).as(:present))
|
168
|
+
@key = @table.where(config.key_column => :$row)
|
169
|
+
.select(::Sequel[config.value_column].hstore.key?(:$key).as(:present))
|
170
170
|
.prepare(:first, statement_id(:hstore_key))
|
171
171
|
end
|
172
172
|
end
|
173
173
|
|
174
174
|
def prepare_store
|
175
175
|
@store = @table
|
176
|
-
.where(key_column => :$row)
|
177
|
-
.prepare(:update, statement_id(:hstore_store), value_column => ::Sequel[value_column].hstore.merge(:$pair))
|
176
|
+
.where(config.key_column => :$row)
|
177
|
+
.prepare(:update, statement_id(:hstore_store), config.value_column => ::Sequel[config.value_column].hstore.merge(:$pair))
|
178
178
|
end
|
179
179
|
|
180
180
|
def prepare_increment
|
181
181
|
pair = ::Sequel[:hstore]
|
182
182
|
.function(:$key, (
|
183
|
-
::Sequel[:coalesce].function(::Sequel[value_column].hstore[:$key].cast(Integer), 0) +
|
183
|
+
::Sequel[:coalesce].function(::Sequel[config.value_column].hstore[:$key].cast(Integer), 0) +
|
184
184
|
:$amount
|
185
185
|
).cast(String))
|
186
186
|
|
187
187
|
@increment = @table
|
188
|
-
.returning(::Sequel[value_column].hstore[:$key].as(:value))
|
189
|
-
.where(key_column => :$row)
|
190
|
-
.prepare(:update, statement_id(:hstore_increment), value_column => ::Sequel.join([value_column, pair]))
|
188
|
+
.returning(::Sequel[config.value_column].hstore[:$key].as(:value))
|
189
|
+
.where(config.key_column => :$row)
|
190
|
+
.prepare(:update, statement_id(:hstore_increment), config.value_column => ::Sequel.join([config.value_column, pair]))
|
191
191
|
end
|
192
192
|
|
193
193
|
def prepare_load
|
194
|
-
@load = @table.where(key_column => :$row)
|
195
|
-
.select(::Sequel[value_column].hstore[:$key].as(:value))
|
194
|
+
@load = @table.where(config.key_column => :$row)
|
195
|
+
.select(::Sequel[config.value_column].hstore[:$key].as(:value))
|
196
196
|
.prepare(:first, statement_id(:hstore_load))
|
197
197
|
end
|
198
198
|
|
199
199
|
def prepare_delete
|
200
|
-
@delete = @table.where(key_column => :$row)
|
201
|
-
.prepare(:update, statement_id(:hstore_delete), value_column => ::Sequel[value_column].hstore.delete(:$key))
|
200
|
+
@delete = @table.where(config.key_column => :$row)
|
201
|
+
.prepare(:update, statement_id(:hstore_delete), config.value_column => ::Sequel[config.value_column].hstore.delete(:$key))
|
202
202
|
end
|
203
203
|
|
204
204
|
def prepare_create
|
@@ -207,30 +207,30 @@ module Moneta
|
|
207
207
|
# https://stackoverflow.com/questions/11940401/escaping-hstore-contains-operators-in-a-jdbc-prepared-statement
|
208
208
|
return if defined?(JRUBY_VERSION)
|
209
209
|
@create = @table
|
210
|
-
.where(key_column => :$row)
|
211
|
-
.exclude(::Sequel[value_column].hstore.key?(:$key))
|
212
|
-
.prepare(:update, statement_id(:hstore_create), value_column => ::Sequel[value_column].hstore.merge(:$pair))
|
210
|
+
.where(config.key_column => :$row)
|
211
|
+
.exclude(::Sequel[config.value_column].hstore.key?(:$key))
|
212
|
+
.prepare(:update, statement_id(:hstore_create), config.value_column => ::Sequel[config.value_column].hstore.merge(:$pair))
|
213
213
|
end
|
214
214
|
|
215
215
|
def prepare_values_at
|
216
216
|
@values_at = @table
|
217
|
-
.where(key_column => :$row)
|
218
|
-
.select(::Sequel[value_column].hstore[::Sequel.cast(:$keys, :"text[]")].as(:values))
|
217
|
+
.where(config.key_column => :$row)
|
218
|
+
.select(::Sequel[config.value_column].hstore[::Sequel.cast(:$keys, :"text[]")].as(:values))
|
219
219
|
.prepare(:first, statement_id(:hstore_values_at))
|
220
220
|
end
|
221
221
|
|
222
222
|
def prepare_slice
|
223
223
|
slice = @table
|
224
|
-
.where(key_column => :$row)
|
225
|
-
.select(::Sequel[value_column].hstore.slice(:$keys).as(:pairs))
|
224
|
+
.where(config.key_column => :$row)
|
225
|
+
.select(::Sequel[config.value_column].hstore.slice(:$keys).as(:pairs))
|
226
226
|
@slice = slice.prepare(:first, statement_id(:hstore_slice))
|
227
227
|
@slice_for_update = slice.for_update.prepare(:first, statement_id(:hstore_slice_for_update))
|
228
228
|
end
|
229
229
|
|
230
230
|
def prepare_size
|
231
231
|
@size = @backend
|
232
|
-
.from(@table.where(key_column => :$row)
|
233
|
-
|
232
|
+
.from(@table.where(config.key_column => :$row)
|
233
|
+
.select(::Sequel[config.value_column].hstore.each))
|
234
234
|
.select { count.function.*.as(:size) }
|
235
235
|
.prepare(:first, statement_id(:hstore_size))
|
236
236
|
end
|
@@ -10,7 +10,7 @@ module Moneta
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def store(key, value, options = {})
|
13
|
-
@table.insert_conflict(:replace).insert(key_column => key, value_column => blob(value))
|
13
|
+
@table.insert_conflict(:replace).insert(config.key_column => key, config.value_column => blob(value))
|
14
14
|
value
|
15
15
|
end
|
16
16
|
|
@@ -25,7 +25,7 @@ module Moneta
|
|
25
25
|
def merge!(pairs, options = {}, &block)
|
26
26
|
@backend.transaction do
|
27
27
|
pairs = yield_merge_pairs(pairs, &block) if block_given?
|
28
|
-
@table.insert_conflict(:replace).import([key_column, value_column], blob_pairs(pairs).to_a)
|
28
|
+
@table.insert_conflict(:replace).import([config.key_column, config.value_column], blob_pairs(pairs).to_a)
|
29
29
|
end
|
30
30
|
|
31
31
|
self
|
@@ -36,20 +36,20 @@ module Moneta
|
|
36
36
|
def prepare_store
|
37
37
|
@store = @table
|
38
38
|
.insert_conflict(:replace)
|
39
|
-
.prepare(:insert, statement_id(:store), key_column => :$key, value_column => :$value)
|
39
|
+
.prepare(:insert, statement_id(:store), config.key_column => :$key, config.value_column => :$value)
|
40
40
|
end
|
41
41
|
|
42
42
|
def prepare_increment
|
43
43
|
return super unless @can_upsert
|
44
|
-
update_expr = (::Sequel[value_column].cast(Integer) + :$amount).cast(:blob)
|
44
|
+
update_expr = (::Sequel[config.value_column].cast(Integer) + :$amount).cast(:blob)
|
45
45
|
@increment = @table
|
46
46
|
.insert_conflict(
|
47
|
-
target: key_column,
|
48
|
-
update: { value_column => update_expr },
|
49
|
-
update_where: ::Sequel.|({ value_column => blob("0") },
|
50
|
-
{ ::Sequel.~(::Sequel[value_column].cast(Integer)) => 0 })
|
47
|
+
target: config.key_column,
|
48
|
+
update: { config.value_column => update_expr },
|
49
|
+
update_where: ::Sequel.|({ config.value_column => blob("0") },
|
50
|
+
{ ::Sequel.~(::Sequel[config.value_column].cast(Integer)) => 0 })
|
51
51
|
)
|
52
|
-
.prepare(:insert, statement_id(:increment), key_column => :$key, value_column => :$value)
|
52
|
+
.prepare(:insert, statement_id(:increment), config.key_column => :$key, config.value_column => :$value)
|
53
53
|
end
|
54
54
|
end
|
55
55
|
end
|
@@ -4,16 +4,31 @@ module Moneta
|
|
4
4
|
module Adapters
|
5
5
|
# Sequel backend
|
6
6
|
# @api public
|
7
|
-
class Sequel
|
8
|
-
include Defaults
|
9
|
-
|
7
|
+
class Sequel < Adapter
|
10
8
|
autoload :MySQL, 'moneta/adapters/sequel/mysql'
|
11
9
|
autoload :Postgres, 'moneta/adapters/sequel/postgres'
|
12
10
|
autoload :PostgresHStore, 'moneta/adapters/sequel/postgres_hstore'
|
13
11
|
autoload :SQLite, 'moneta/adapters/sequel/sqlite'
|
14
12
|
|
15
13
|
supports :create, :increment, :each_key
|
16
|
-
|
14
|
+
|
15
|
+
config :table, default: :moneta, coerce: :to_sym
|
16
|
+
config :optimize, default: true
|
17
|
+
config :create_table, default: true
|
18
|
+
config :key_column, default: :k
|
19
|
+
config :value_column, default: :v
|
20
|
+
config :hstore, coerce: :to_s
|
21
|
+
config :each_key_server
|
22
|
+
|
23
|
+
backend do |db:, extensions: [], connection_validation_timeout: nil, **options|
|
24
|
+
::Sequel.connect(db, options).tap do |backend|
|
25
|
+
extensions.map(&:to_sym).each(&backend.method(:extension))
|
26
|
+
|
27
|
+
if connection_validation_timeout
|
28
|
+
backend.pool.connection_validation_timeout = connection_validation_timeout
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
17
32
|
|
18
33
|
# @param [Hash] options
|
19
34
|
# @option options [String] :db Sequel database
|
@@ -22,7 +37,7 @@ module Moneta
|
|
22
37
|
# @option options [Integer] :connection_validation_timeout (nil) Sequel connection_validation_timeout
|
23
38
|
# @option options [Sequel::Database] :backend Use existing backend instance
|
24
39
|
# @option options [Boolean] :optimize (true) Set to false to prevent database-specific optimisations
|
25
|
-
# @option options [Proc, Boolean] :create_table Provide a Proc for creating the table, or
|
40
|
+
# @option options [Proc, Boolean] :create_table (true) Provide a Proc for creating the table, or
|
26
41
|
# set to false to disable table creation all together. If a Proc is given, it will be
|
27
42
|
# called regardless of whether the table exists already.
|
28
43
|
# @option options [Symbol] :key_column (:k) The name of the key column
|
@@ -37,32 +52,21 @@ module Moneta
|
|
37
52
|
# in conjunction with Sequel's `:servers` option
|
38
53
|
# @option options All other options passed to `Sequel#connect`
|
39
54
|
def initialize(options = {})
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
@backend = options.delete(:backend) ||
|
44
|
-
connect(extensions: extensions, connection_validation_timeout: connection_validation_timeout, **options)
|
45
|
-
|
46
|
-
if hstore = options.delete(:hstore)
|
47
|
-
@row = hstore.to_s
|
55
|
+
super
|
56
|
+
|
57
|
+
if config.hstore
|
48
58
|
extend Sequel::PostgresHStore
|
49
|
-
elsif optimize
|
59
|
+
elsif config.optimize
|
50
60
|
add_optimizations
|
51
61
|
end
|
52
62
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
@each_key_server = options.delete(:each_key_server)
|
57
|
-
|
58
|
-
create_proc = options.delete(:create_table)
|
59
|
-
if create_proc == nil
|
63
|
+
if config.create_table.respond_to?(:call)
|
64
|
+
config.create_table.call(backend)
|
65
|
+
elsif config.create_table
|
60
66
|
create_table
|
61
|
-
elsif create_proc
|
62
|
-
create_proc.call(@backend)
|
63
67
|
end
|
64
68
|
|
65
|
-
@table =
|
69
|
+
@table = backend[config.table]
|
66
70
|
prepare_statements
|
67
71
|
end
|
68
72
|
|
@@ -74,7 +78,7 @@ module Moneta
|
|
74
78
|
# (see Proxy#load)
|
75
79
|
def load(key, options = {})
|
76
80
|
if row = @load.call(key: key)
|
77
|
-
row[value_column]
|
81
|
+
row[config.value_column]
|
78
82
|
end
|
79
83
|
end
|
80
84
|
|
@@ -100,9 +104,9 @@ module Moneta
|
|
100
104
|
|
101
105
|
# (see Proxy#increment)
|
102
106
|
def increment(key, amount = 1, options = {})
|
103
|
-
|
107
|
+
backend.transaction do
|
104
108
|
if existing = @load_for_update.call(key: key)
|
105
|
-
existing_value = existing[value_column]
|
109
|
+
existing_value = existing[config.value_column]
|
106
110
|
amount += Integer(existing_value)
|
107
111
|
raise IncrementError, "no update" unless @increment_update.call(
|
108
112
|
key: key,
|
@@ -135,13 +139,13 @@ module Moneta
|
|
135
139
|
|
136
140
|
# (see Proxy#close)
|
137
141
|
def close
|
138
|
-
|
142
|
+
backend.disconnect
|
139
143
|
nil
|
140
144
|
end
|
141
145
|
|
142
146
|
# (see Proxy#slice)
|
143
147
|
def slice(*keys, **options)
|
144
|
-
@slice.all(keys).map! { |row| [row[key_column], row[value_column]] }
|
148
|
+
@slice.all(keys).map! { |row| [row[config.key_column], row[config.value_column]] }
|
145
149
|
end
|
146
150
|
|
147
151
|
# (see Proxy#values_at)
|
@@ -165,10 +169,10 @@ module Moneta
|
|
165
169
|
|
166
170
|
# (see Proxy#merge!)
|
167
171
|
def merge!(pairs, options = {})
|
168
|
-
|
172
|
+
backend.transaction do
|
169
173
|
existing = Hash[slice_for_update(pairs)]
|
170
174
|
update_pairs, insert_pairs = pairs.partition { |k, _| existing.key?(k) }
|
171
|
-
@table.import([key_column, value_column], blob_pairs(insert_pairs))
|
175
|
+
@table.import([config.key_column, config.value_column], blob_pairs(insert_pairs))
|
172
176
|
|
173
177
|
if block_given?
|
174
178
|
update_pairs.map! do |key, new_value|
|
@@ -187,8 +191,10 @@ module Moneta
|
|
187
191
|
# (see Proxy#each_key)
|
188
192
|
def each_key
|
189
193
|
return enum_for(:each_key) { @table.count } unless block_given?
|
190
|
-
|
191
|
-
|
194
|
+
|
195
|
+
key_column = config.key_column
|
196
|
+
if config.each_key_server
|
197
|
+
@table.server(config.each_key_server).order(key_column).select(key_column).paged_each do |row|
|
192
198
|
yield row[key_column]
|
193
199
|
end
|
194
200
|
else
|
@@ -201,21 +207,6 @@ module Moneta
|
|
201
207
|
|
202
208
|
protected
|
203
209
|
|
204
|
-
# @api private
|
205
|
-
def connect(db:, extensions: nil, connection_validation_timeout: nil, **options)
|
206
|
-
other_cols = [:table, :create_table, :key_column, :value_column, :hstore]
|
207
|
-
::Sequel.connect(db, options.reject { |k,| other_cols.member?(k) }).tap do |backend|
|
208
|
-
if extensions
|
209
|
-
raise ArgumentError, 'Option :extensions must be an Array' unless extensions.is_a?(Array)
|
210
|
-
extensions.map(&:to_sym).each(&backend.method(:extension))
|
211
|
-
end
|
212
|
-
|
213
|
-
if connection_validation_timeout
|
214
|
-
backend.pool.connection_validation_timeout = connection_validation_timeout
|
215
|
-
end
|
216
|
-
end
|
217
|
-
end
|
218
|
-
|
219
210
|
# @api private
|
220
211
|
def add_optimizations
|
221
212
|
case backend.database_type
|
@@ -243,9 +234,9 @@ module Moneta
|
|
243
234
|
end
|
244
235
|
|
245
236
|
def create_table
|
246
|
-
key_column =
|
247
|
-
value_column =
|
248
|
-
|
237
|
+
key_column = config.key_column
|
238
|
+
value_column = config.value_column
|
239
|
+
backend.create_table?(config.table) do
|
249
240
|
String key_column, null: false, primary_key: true
|
250
241
|
File value_column
|
251
242
|
end
|
@@ -253,7 +244,7 @@ module Moneta
|
|
253
244
|
|
254
245
|
def slice_for_update(pairs)
|
255
246
|
@slice_for_update.all(pairs.map { |k, _| k }.to_a).map! do |row|
|
256
|
-
[row[key_column], row[value_column]]
|
247
|
+
[row[config.key_column], row[config.value_column]]
|
257
248
|
end
|
258
249
|
end
|
259
250
|
|
@@ -266,7 +257,7 @@ module Moneta
|
|
266
257
|
end
|
267
258
|
|
268
259
|
def statement_id(id)
|
269
|
-
"moneta_#{
|
260
|
+
"moneta_#{config.table}_#{id}".to_sym
|
270
261
|
end
|
271
262
|
|
272
263
|
def prepare_statements
|
@@ -281,49 +272,49 @@ module Moneta
|
|
281
272
|
|
282
273
|
def prepare_key
|
283
274
|
@key = @table
|
284
|
-
.where(key_column => :$key).select(1)
|
275
|
+
.where(config.key_column => :$key).select(1)
|
285
276
|
.prepare(:first, statement_id(:key))
|
286
277
|
end
|
287
278
|
|
288
279
|
def prepare_load
|
289
280
|
@load = @table
|
290
|
-
.where(key_column => :$key).select(value_column)
|
281
|
+
.where(config.key_column => :$key).select(config.value_column)
|
291
282
|
.prepare(:first, statement_id(:load))
|
292
283
|
end
|
293
284
|
|
294
285
|
def prepare_store
|
295
286
|
@store_update = @table
|
296
|
-
.where(key_column => :$key)
|
297
|
-
.prepare(:update, statement_id(:store_update), value_column => :$value)
|
287
|
+
.where(config.key_column => :$key)
|
288
|
+
.prepare(:update, statement_id(:store_update), config.value_column => :$value)
|
298
289
|
end
|
299
290
|
|
300
291
|
def prepare_create
|
301
292
|
@create = @table
|
302
|
-
.prepare(:insert, statement_id(:create), key_column => :$key, value_column => :$value)
|
293
|
+
.prepare(:insert, statement_id(:create), config.key_column => :$key, config.value_column => :$value)
|
303
294
|
end
|
304
295
|
|
305
296
|
def prepare_increment
|
306
297
|
@load_for_update = @table
|
307
|
-
.where(key_column => :$key).for_update
|
308
|
-
.select(value_column)
|
298
|
+
.where(config.key_column => :$key).for_update
|
299
|
+
.select(config.value_column)
|
309
300
|
.prepare(:first, statement_id(:load_for_update))
|
310
301
|
@increment_update ||= @table
|
311
|
-
.where(key_column => :$key, value_column => :$value)
|
312
|
-
.prepare(:update, statement_id(:increment_update), value_column => :$new_value)
|
302
|
+
.where(config.key_column => :$key, config.value_column => :$value)
|
303
|
+
.prepare(:update, statement_id(:increment_update), config.value_column => :$new_value)
|
313
304
|
end
|
314
305
|
|
315
306
|
def prepare_delete
|
316
|
-
@delete = @table.where(key_column => :$key)
|
307
|
+
@delete = @table.where(config.key_column => :$key)
|
317
308
|
.prepare(:delete, statement_id(:delete))
|
318
309
|
end
|
319
310
|
|
320
311
|
def prepare_slice
|
321
312
|
@slice_for_update = ::Sequel::Dataset::PlaceholderLiteralizer.loader(@table) do |pl, ds|
|
322
|
-
ds.filter(key_column => pl.arg).select(key_column, value_column).for_update
|
313
|
+
ds.filter(config.key_column => pl.arg).select(config.key_column, config.value_column).for_update
|
323
314
|
end
|
324
315
|
|
325
316
|
@slice = ::Sequel::Dataset::PlaceholderLiteralizer.loader(@table) do |pl, ds|
|
326
|
-
ds.filter(key_column => pl.arg).select(key_column, value_column)
|
317
|
+
ds.filter(config.key_column => pl.arg).select(config.key_column, config.value_column)
|
327
318
|
end
|
328
319
|
end
|
329
320
|
|