github-ds 0.2.9 → 0.5.0
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 +5 -5
- data/.travis.yml +9 -6
- data/Gemfile +10 -4
- data/README.md +8 -0
- data/github-ds.gemspec +5 -3
- data/lib/generators/github/ds/active_record_generator.rb +9 -1
- data/lib/generators/github/ds/templates/migration.rb +5 -5
- data/lib/github/ds/version.rb +1 -1
- data/lib/github/kv.rb +186 -17
- data/lib/github/kv/config.rb +13 -0
- data/lib/github/sql.rb +3 -3
- metadata +39 -17
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 88208f2b8cc24184dce9a984af467c44d9560196e9832d637ee99aac34082da8
|
|
4
|
+
data.tar.gz: 70f8c5e30c4b237e33e0d96ff747c4719bcf300f5a67472fe7d347e6779ff0f7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5afcb251c8dcbb250db23eb758f67a38baa8933fcf6325f2c9a419ae1dcee5455d7571a0eb0cfed0b401134225e482c74cab421b0bd116931996b5b954710c78
|
|
7
|
+
data.tar.gz: bda6aa58192ec5d29d3a909f1d14d939fcb4b069019c7d617ede8f3e580eceedaddb180cf2c266cf9e8d21e262d7752d3d04d20ecfe1e5491cf75f544a611395
|
data/.travis.yml
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
language: ruby
|
|
2
|
+
before_install:
|
|
3
|
+
- gem uninstall -v '>= 2' -i $(rvm gemdir)@global -ax bundler || true
|
|
4
|
+
- gem install bundler -v '<2'
|
|
2
5
|
rvm:
|
|
3
|
-
- 2.2
|
|
4
|
-
- 2.3
|
|
5
|
-
- 2.4
|
|
6
6
|
- 2.5
|
|
7
|
+
- 2.6
|
|
8
|
+
- 2.7
|
|
7
9
|
script: bundle exec rake
|
|
8
10
|
env:
|
|
9
|
-
- RAILS_VERSION=
|
|
10
|
-
- RAILS_VERSION=5.0
|
|
11
|
-
|
|
11
|
+
- RAILS_VERSION=6.0.3.1
|
|
12
|
+
- RAILS_VERSION=5.2.0
|
|
13
|
+
services:
|
|
14
|
+
- mysql
|
data/Gemfile
CHANGED
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
source "https://rubygems.org"
|
|
2
2
|
gemspec
|
|
3
3
|
|
|
4
|
-
DEFAULT_RAILS_VERSION = '
|
|
4
|
+
DEFAULT_RAILS_VERSION = '6.0.3'
|
|
5
|
+
ENV['RAILS_VERSION'] ||= DEFAULT_RAILS_VERSION
|
|
5
6
|
|
|
6
|
-
if ENV['RAILS_VERSION']
|
|
7
|
+
if ENV['RAILS_VERSION'] == '4.2.10'
|
|
7
8
|
gem 'mysql2', '~> 0.3.18'
|
|
8
9
|
else
|
|
9
10
|
gem "mysql2"
|
|
10
11
|
end
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
|
|
13
|
+
if ENV['RAILS_VERSION'] == 'master'
|
|
14
|
+
gem "activerecord", git: "https://github.com/rails/rails"
|
|
15
|
+
else
|
|
16
|
+
gem "rails", "~> #{ENV['RAILS_VERSION'] || DEFAULT_RAILS_VERSION}"
|
|
17
|
+
gem "activerecord", "~> #{ENV['RAILS_VERSION'] || DEFAULT_RAILS_VERSION}"
|
|
18
|
+
end
|
data/README.md
CHANGED
|
@@ -37,6 +37,14 @@ rails generate github:ds:active_record
|
|
|
37
37
|
rails db:migrate
|
|
38
38
|
```
|
|
39
39
|
|
|
40
|
+
If you need to change the name of the table used for storing the key-values, you can configure your table name as such, before running the migration:
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
GitHub::KV.configure do |config|
|
|
44
|
+
config.table_name = "new_key_values_table"
|
|
45
|
+
end
|
|
46
|
+
```
|
|
47
|
+
|
|
40
48
|
Once you have created and executed the migration, KV can do neat things like this:
|
|
41
49
|
|
|
42
50
|
```ruby
|
data/github-ds.gemspec
CHANGED
|
@@ -30,13 +30,15 @@ Gem::Specification.new do |spec|
|
|
|
30
30
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
31
31
|
spec.require_paths = ["lib"]
|
|
32
32
|
|
|
33
|
-
spec.add_dependency "activerecord", ">= 3.2"
|
|
33
|
+
spec.add_dependency "activerecord", ">= 3.2"
|
|
34
34
|
|
|
35
|
-
spec.add_development_dependency "bundler", "
|
|
36
|
-
spec.add_development_dependency "rake", "~>
|
|
35
|
+
spec.add_development_dependency "bundler", ">= 1.14"
|
|
36
|
+
spec.add_development_dependency "rake", "~> 12.0"
|
|
37
37
|
spec.add_development_dependency "minitest", "~> 5.0"
|
|
38
38
|
spec.add_development_dependency "timecop", "~> 0.8.1"
|
|
39
39
|
spec.add_development_dependency "activesupport"
|
|
40
40
|
spec.add_development_dependency "mysql2"
|
|
41
41
|
spec.add_development_dependency "mocha", "~> 1.2.1"
|
|
42
|
+
spec.add_development_dependency "minitest-focus", "~> 1.1.2"
|
|
43
|
+
spec.add_development_dependency "pry", "~> 0.12.2"
|
|
42
44
|
end
|
|
@@ -18,7 +18,7 @@ module Github
|
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
def self.migration_version
|
|
21
|
-
if Rails.
|
|
21
|
+
if Rails::VERSION::MAJOR.to_i >= 5
|
|
22
22
|
"[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]"
|
|
23
23
|
end
|
|
24
24
|
end
|
|
@@ -26,6 +26,14 @@ module Github
|
|
|
26
26
|
def migration_version
|
|
27
27
|
self.class.migration_version
|
|
28
28
|
end
|
|
29
|
+
|
|
30
|
+
def self.table_name
|
|
31
|
+
":#{GitHub::KV.config.table_name}"
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def table_name
|
|
35
|
+
self.class.table_name
|
|
36
|
+
end
|
|
29
37
|
end
|
|
30
38
|
end
|
|
31
39
|
end
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
class CreateKeyValuesTable < ActiveRecord::Migration<%= migration_version %>
|
|
2
2
|
def self.up
|
|
3
|
-
create_table
|
|
3
|
+
create_table <%= table_name %> do |t|
|
|
4
4
|
t.string :key, :null => false
|
|
5
5
|
t.binary :value, :null => false
|
|
6
6
|
t.datetime :expires_at, :null => true
|
|
7
7
|
t.timestamps :null => false
|
|
8
8
|
end
|
|
9
9
|
|
|
10
|
-
add_index
|
|
11
|
-
add_index
|
|
10
|
+
add_index <%= table_name %>, :key, :unique => true
|
|
11
|
+
add_index <%= table_name %>, :expires_at
|
|
12
12
|
|
|
13
|
-
change_column
|
|
13
|
+
change_column <%= table_name %>, :id, "bigint(20) NOT NULL AUTO_INCREMENT"
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
def self.down
|
|
17
|
-
drop_table
|
|
17
|
+
drop_table <%= table_name %>
|
|
18
18
|
end
|
|
19
19
|
end
|
data/lib/github/ds/version.rb
CHANGED
data/lib/github/kv.rb
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
require_relative "kv/config"
|
|
1
2
|
require_relative "result"
|
|
2
3
|
require_relative "sql"
|
|
3
4
|
|
|
@@ -48,11 +49,42 @@ module GitHub
|
|
|
48
49
|
KeyLengthError = Class.new(StandardError)
|
|
49
50
|
ValueLengthError = Class.new(StandardError)
|
|
50
51
|
UnavailableError = Class.new(StandardError)
|
|
52
|
+
InvalidValueError = Class.new(StandardError)
|
|
51
53
|
|
|
52
54
|
class MissingConnectionError < StandardError; end
|
|
53
55
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
+
attr_accessor :use_local_time
|
|
57
|
+
attr_writer :config
|
|
58
|
+
|
|
59
|
+
def self.config
|
|
60
|
+
@config ||= Config.new
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def self.reset
|
|
64
|
+
@config = Config.new
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def self.configure
|
|
68
|
+
yield(config)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# initialize :: [Exception], Boolean, Proc -> nil
|
|
72
|
+
#
|
|
73
|
+
# Initialize a new KV instance.
|
|
74
|
+
#
|
|
75
|
+
# encapsulated_errors - An Array of Exception subclasses that, when raised,
|
|
76
|
+
# will be replaced with UnavailableError.
|
|
77
|
+
# use_local_time: - Whether to use Ruby's `Time.now` instaed of MySQL's
|
|
78
|
+
# `NOW()` function. This is mostly useful in testing
|
|
79
|
+
# where time needs to be modified (eg. Timecop).
|
|
80
|
+
# Default false.
|
|
81
|
+
# &conn_block - A block to call to open a new database connection.
|
|
82
|
+
#
|
|
83
|
+
# Returns nothing.
|
|
84
|
+
def initialize(config: GitHub::KV.config, &conn_block)
|
|
85
|
+
@encapsulated_errors = config.encapsulated_errors
|
|
86
|
+
@use_local_time = config.use_local_time
|
|
87
|
+
@table_name = config.table_name
|
|
56
88
|
@conn_block = conn_block
|
|
57
89
|
end
|
|
58
90
|
|
|
@@ -93,8 +125,8 @@ module GitHub
|
|
|
93
125
|
validate_key_array(keys)
|
|
94
126
|
|
|
95
127
|
Result.new {
|
|
96
|
-
kvs = GitHub::SQL.results(<<-SQL, :keys => keys, :connection => connection).to_h
|
|
97
|
-
SELECT `key`, value FROM
|
|
128
|
+
kvs = GitHub::SQL.results(<<-SQL, :keys => keys, :now => now, :connection => connection).to_h
|
|
129
|
+
SELECT `key`, value FROM #{@table_name} WHERE `key` IN :keys AND (`expires_at` IS NULL OR `expires_at` > :now)
|
|
98
130
|
SQL
|
|
99
131
|
|
|
100
132
|
keys.map { |key| kvs[key] }
|
|
@@ -136,12 +168,13 @@ module GitHub
|
|
|
136
168
|
validate_expires(expires) if expires
|
|
137
169
|
|
|
138
170
|
rows = kvs.map { |key, value|
|
|
139
|
-
|
|
171
|
+
value = value.is_a?(GitHub::SQL::Literal) ? value : GitHub::SQL::BINARY(value)
|
|
172
|
+
[key, value, now, now, expires || GitHub::SQL::NULL]
|
|
140
173
|
}
|
|
141
174
|
|
|
142
175
|
encapsulate_error do
|
|
143
176
|
GitHub::SQL.run(<<-SQL, :rows => GitHub::SQL::ROWS(rows), :connection => connection)
|
|
144
|
-
INSERT INTO
|
|
177
|
+
INSERT INTO #{@table_name} (`key`, value, created_at, updated_at, expires_at)
|
|
145
178
|
VALUES :rows
|
|
146
179
|
ON DUPLICATE KEY UPDATE
|
|
147
180
|
value = VALUES(value),
|
|
@@ -185,8 +218,8 @@ module GitHub
|
|
|
185
218
|
validate_key_array(keys)
|
|
186
219
|
|
|
187
220
|
Result.new {
|
|
188
|
-
existing_keys = GitHub::SQL.values(<<-SQL, :keys => keys, :connection => connection).to_set
|
|
189
|
-
SELECT `key` FROM
|
|
221
|
+
existing_keys = GitHub::SQL.values(<<-SQL, :keys => keys, :now => now, :connection => connection).to_set
|
|
222
|
+
SELECT `key` FROM #{@table_name} WHERE `key` IN :keys AND (`expires_at` IS NULL OR `expires_at` > :now)
|
|
190
223
|
SQL
|
|
191
224
|
|
|
192
225
|
keys.map { |key| existing_keys.include?(key) }
|
|
@@ -221,19 +254,116 @@ module GitHub
|
|
|
221
254
|
# achieve the same thing with the right INSERT ... ON DUPLICATE KEY UPDATE
|
|
222
255
|
# query, but then we would not be able to rely on affected_rows
|
|
223
256
|
|
|
224
|
-
GitHub::SQL.run(<<-SQL, :key => key, :connection => connection)
|
|
225
|
-
DELETE FROM
|
|
257
|
+
GitHub::SQL.run(<<-SQL, :key => key, :now => now, :connection => connection)
|
|
258
|
+
DELETE FROM #{@table_name} WHERE `key` = :key AND expires_at <= :now
|
|
226
259
|
SQL
|
|
227
260
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
261
|
+
value = value.is_a?(GitHub::SQL::Literal) ? value : GitHub::SQL::BINARY(value)
|
|
262
|
+
sql = GitHub::SQL.run(<<-SQL, :key => key, :value => value, :now => now, :expires => expires || GitHub::SQL::NULL, :connection => connection)
|
|
263
|
+
INSERT IGNORE INTO #{@table_name} (`key`, value, created_at, updated_at, expires_at)
|
|
264
|
+
VALUES (:key, :value, :now, :now, :expires)
|
|
231
265
|
SQL
|
|
232
266
|
|
|
233
267
|
sql.affected_rows > 0
|
|
234
268
|
}
|
|
235
269
|
end
|
|
236
270
|
|
|
271
|
+
# increment :: String, Integer, expires: Time? -> Integer
|
|
272
|
+
#
|
|
273
|
+
# Increment the key's value by an amount.
|
|
274
|
+
#
|
|
275
|
+
# key - The key to increment.
|
|
276
|
+
# amount - The amount to increment the key's value by.
|
|
277
|
+
# The user can increment by both positive and
|
|
278
|
+
# negative values
|
|
279
|
+
# expires - When the key should expire.
|
|
280
|
+
# touch_on_insert - Only when expires is specified. When true
|
|
281
|
+
# the expires value is only touched upon
|
|
282
|
+
# inserts. Otherwise the record is always
|
|
283
|
+
# touched.
|
|
284
|
+
#
|
|
285
|
+
# Returns the key's value after incrementing.
|
|
286
|
+
def increment(key, amount: 1, expires: nil, touch_on_insert: false)
|
|
287
|
+
validate_key(key)
|
|
288
|
+
validate_amount(amount) if amount
|
|
289
|
+
validate_expires(expires) if expires
|
|
290
|
+
validate_touch(touch_on_insert, expires)
|
|
291
|
+
|
|
292
|
+
expires ||= GitHub::SQL::NULL
|
|
293
|
+
|
|
294
|
+
# This query uses a few MySQL "hacks" to ensure that the incrementing
|
|
295
|
+
# is done atomically and the value is returned. The first trick is done
|
|
296
|
+
# using the `LAST_INSERT_ID` function. This allows us to manually set
|
|
297
|
+
# the LAST_INSERT_ID returned by the query. Here we are able to set it
|
|
298
|
+
# to the new value when an increment takes place, essentially allowing us
|
|
299
|
+
# to do: `UPDATE...;SELECT value from key_value where key=:key` in a
|
|
300
|
+
# single step.
|
|
301
|
+
#
|
|
302
|
+
# However the `LAST_INSERT_ID` trick is only used when the value is
|
|
303
|
+
# updated. Upon a fresh insert we know the amount is going to be set
|
|
304
|
+
# to the amount specified.
|
|
305
|
+
#
|
|
306
|
+
# Lastly we only do these tricks when the value at the key is an integer.
|
|
307
|
+
# If the value is not an integer the update ensures the values remain the
|
|
308
|
+
# same and we raise an error.
|
|
309
|
+
encapsulate_error {
|
|
310
|
+
sql = GitHub::SQL.run(<<-SQL, key: key, amount: amount, now: now, expires: expires, touch: !touch_on_insert, connection: connection)
|
|
311
|
+
INSERT INTO #{@table_name} (`key`, `value`, `created_at`, `updated_at`, `expires_at`)
|
|
312
|
+
VALUES(:key, :amount, :now, :now, :expires)
|
|
313
|
+
ON DUPLICATE KEY UPDATE
|
|
314
|
+
`value`=IF(
|
|
315
|
+
concat('',`value`*1) = `value`,
|
|
316
|
+
LAST_INSERT_ID(IF(
|
|
317
|
+
`expires_at` IS NULL OR `expires_at`>=:now,
|
|
318
|
+
`value`+:amount,
|
|
319
|
+
:amount
|
|
320
|
+
)),
|
|
321
|
+
`value`
|
|
322
|
+
),
|
|
323
|
+
`updated_at`=IF(
|
|
324
|
+
concat('',`value`*1) = `value`,
|
|
325
|
+
:now,
|
|
326
|
+
`updated_at`
|
|
327
|
+
),
|
|
328
|
+
`expires_at`=IF(
|
|
329
|
+
concat('',`value`*1) = `value`,
|
|
330
|
+
IF(
|
|
331
|
+
:touch,
|
|
332
|
+
:expires,
|
|
333
|
+
`expires_at`
|
|
334
|
+
),
|
|
335
|
+
`expires_at`
|
|
336
|
+
)
|
|
337
|
+
SQL
|
|
338
|
+
|
|
339
|
+
# The ordering of these statements is extremely important if we are to
|
|
340
|
+
# support incrementing a negative amount. The checks occur in this order:
|
|
341
|
+
# 1. Check if an update with new values occurred? If so return the result
|
|
342
|
+
# This could potentially result in `sql.last_insert_id` with a value
|
|
343
|
+
# of 0, thus it must be before the second check.
|
|
344
|
+
# 2. Check if an update took place but nothing changed (I.E. no new value
|
|
345
|
+
# was set)
|
|
346
|
+
# 3. Check if an insert took place.
|
|
347
|
+
#
|
|
348
|
+
# See https://dev.mysql.com/doc/refman/8.0/en/insert-on-duplicate.html for
|
|
349
|
+
# more information (NOTE: CLIENT_FOUND_ROWS is set)
|
|
350
|
+
if sql.affected_rows == 2
|
|
351
|
+
# An update took place in which data changed. We use a hack to set
|
|
352
|
+
# the last insert ID to be the new value.
|
|
353
|
+
sql.last_insert_id
|
|
354
|
+
elsif sql.affected_rows == 0 || (sql.affected_rows == 1 && sql.last_insert_id == 0)
|
|
355
|
+
# No insert took place nor did any update occur. This means that
|
|
356
|
+
# the value was not an integer thus not incremented.
|
|
357
|
+
raise InvalidValueError
|
|
358
|
+
elsif sql.affected_rows == 1
|
|
359
|
+
# If the number of affected_rows is 1 then a new value was inserted
|
|
360
|
+
# thus we can just return the amount given to us since that is the
|
|
361
|
+
# value at the key
|
|
362
|
+
amount
|
|
363
|
+
end
|
|
364
|
+
}
|
|
365
|
+
end
|
|
366
|
+
|
|
237
367
|
# del :: String -> nil
|
|
238
368
|
#
|
|
239
369
|
# Deletes the specified key. Returns nil. Raises on error.
|
|
@@ -263,7 +393,7 @@ module GitHub
|
|
|
263
393
|
|
|
264
394
|
encapsulate_error do
|
|
265
395
|
GitHub::SQL.run(<<-SQL, :keys => keys, :connection => connection)
|
|
266
|
-
DELETE FROM
|
|
396
|
+
DELETE FROM #{@table_name} WHERE `key` IN :keys
|
|
267
397
|
SQL
|
|
268
398
|
end
|
|
269
399
|
|
|
@@ -286,14 +416,40 @@ module GitHub
|
|
|
286
416
|
validate_key(key)
|
|
287
417
|
|
|
288
418
|
Result.new {
|
|
289
|
-
GitHub::SQL.value(<<-SQL, :key => key, :connection => connection)
|
|
290
|
-
SELECT expires_at FROM
|
|
291
|
-
WHERE `key` = :key AND (expires_at IS NULL OR expires_at >
|
|
419
|
+
GitHub::SQL.value(<<-SQL, :key => key, :now => now, :connection => connection)
|
|
420
|
+
SELECT expires_at FROM #{@table_name}
|
|
421
|
+
WHERE `key` = :key AND (expires_at IS NULL OR expires_at > :now)
|
|
292
422
|
SQL
|
|
293
423
|
}
|
|
294
424
|
end
|
|
295
425
|
|
|
426
|
+
# mttl :: [String] -> Result<[Time | nil]>
|
|
427
|
+
#
|
|
428
|
+
# Returns the expires_at time for the specified key or nil.
|
|
429
|
+
#
|
|
430
|
+
# Example:
|
|
431
|
+
#
|
|
432
|
+
# kv.mttl(["foo", "octocat"])
|
|
433
|
+
# # => #<Result value: [2018-04-23 11:34:54 +0200, nil]>
|
|
434
|
+
#
|
|
435
|
+
def mttl(keys)
|
|
436
|
+
validate_key_array(keys)
|
|
437
|
+
|
|
438
|
+
Result.new {
|
|
439
|
+
kvs = GitHub::SQL.results(<<-SQL, :keys => keys, :now => now, :connection => connection).to_h
|
|
440
|
+
SELECT `key`, expires_at FROM #{@table_name}
|
|
441
|
+
WHERE `key` in :keys AND (expires_at IS NULL OR expires_at > :now)
|
|
442
|
+
SQL
|
|
443
|
+
|
|
444
|
+
keys.map { |key| kvs[key] }
|
|
445
|
+
}
|
|
446
|
+
end
|
|
447
|
+
|
|
296
448
|
private
|
|
449
|
+
def now
|
|
450
|
+
use_local_time ? Time.now : GitHub::SQL::NOW
|
|
451
|
+
end
|
|
452
|
+
|
|
297
453
|
def validate_key(key, error_message: nil)
|
|
298
454
|
unless key.is_a?(String)
|
|
299
455
|
raise TypeError, error_message || "key must be a String in #{self.class.name}, but was #{key.class}"
|
|
@@ -347,6 +503,19 @@ module GitHub
|
|
|
347
503
|
end
|
|
348
504
|
end
|
|
349
505
|
|
|
506
|
+
def validate_amount(amount)
|
|
507
|
+
raise ArgumentError.new("The amount specified must be an integer") unless amount.is_a? Integer
|
|
508
|
+
raise ArgumentError.new("The amount specified cannot be 0") if amount == 0
|
|
509
|
+
end
|
|
510
|
+
|
|
511
|
+
def validate_touch(touch, expires)
|
|
512
|
+
raise ArgumentError.new("touch_on_insert must be a boolean value") unless [true, false].include?(touch)
|
|
513
|
+
|
|
514
|
+
if touch && expires.nil?
|
|
515
|
+
raise ArgumentError.new("Please specify an expires value if you wish to touch on insert")
|
|
516
|
+
end
|
|
517
|
+
end
|
|
518
|
+
|
|
350
519
|
def validate_expires(expires)
|
|
351
520
|
unless expires.respond_to?(:to_time)
|
|
352
521
|
raise TypeError, "expires must be a time of some sort (Time, DateTime, ActiveSupport::TimeWithZone, etc.), but was #{expires.class}"
|
data/lib/github/sql.rb
CHANGED
|
@@ -43,7 +43,7 @@ module GitHub
|
|
|
43
43
|
# GitHub::SQL#initialize or overriding connection then you'll need to use
|
|
44
44
|
# the instance version.
|
|
45
45
|
def self.transaction(options = {}, &block)
|
|
46
|
-
ActiveRecord::Base.connection.transaction(options, &block)
|
|
46
|
+
ActiveRecord::Base.connection.transaction(**options, &block)
|
|
47
47
|
end
|
|
48
48
|
|
|
49
49
|
# Public: Instantiate a literal SQL value.
|
|
@@ -213,7 +213,7 @@ module GitHub
|
|
|
213
213
|
# Use select_all to retrieve hashes for each row instead of arrays of values.
|
|
214
214
|
@models = connection.
|
|
215
215
|
select_all(query, "#{klass.name} Load via #{self.class.name}").
|
|
216
|
-
|
|
216
|
+
map { |record| klass.send :instantiate, record }
|
|
217
217
|
|
|
218
218
|
retrieve_found_row_count
|
|
219
219
|
freeze
|
|
@@ -299,7 +299,7 @@ module GitHub
|
|
|
299
299
|
|
|
300
300
|
# Public: Run inside a transaction for the connection.
|
|
301
301
|
def transaction(options = {}, &block)
|
|
302
|
-
connection.transaction(options, &block)
|
|
302
|
+
connection.transaction(**options, &block)
|
|
303
303
|
end
|
|
304
304
|
|
|
305
305
|
# Internal: The object we use to execute SQL and retrieve results. Defaults
|
metadata
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: github-ds
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.5.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- GitHub Open Source
|
|
8
8
|
- John Nunemaker
|
|
9
|
-
autorequire:
|
|
9
|
+
autorequire:
|
|
10
10
|
bindir: exe
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date:
|
|
12
|
+
date: 2020-06-16 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: activerecord
|
|
@@ -18,9 +18,6 @@ dependencies:
|
|
|
18
18
|
- - ">="
|
|
19
19
|
- !ruby/object:Gem::Version
|
|
20
20
|
version: '3.2'
|
|
21
|
-
- - "<"
|
|
22
|
-
- !ruby/object:Gem::Version
|
|
23
|
-
version: '6.0'
|
|
24
21
|
type: :runtime
|
|
25
22
|
prerelease: false
|
|
26
23
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -28,21 +25,18 @@ dependencies:
|
|
|
28
25
|
- - ">="
|
|
29
26
|
- !ruby/object:Gem::Version
|
|
30
27
|
version: '3.2'
|
|
31
|
-
- - "<"
|
|
32
|
-
- !ruby/object:Gem::Version
|
|
33
|
-
version: '6.0'
|
|
34
28
|
- !ruby/object:Gem::Dependency
|
|
35
29
|
name: bundler
|
|
36
30
|
requirement: !ruby/object:Gem::Requirement
|
|
37
31
|
requirements:
|
|
38
|
-
- - "
|
|
32
|
+
- - ">="
|
|
39
33
|
- !ruby/object:Gem::Version
|
|
40
34
|
version: '1.14'
|
|
41
35
|
type: :development
|
|
42
36
|
prerelease: false
|
|
43
37
|
version_requirements: !ruby/object:Gem::Requirement
|
|
44
38
|
requirements:
|
|
45
|
-
- - "
|
|
39
|
+
- - ">="
|
|
46
40
|
- !ruby/object:Gem::Version
|
|
47
41
|
version: '1.14'
|
|
48
42
|
- !ruby/object:Gem::Dependency
|
|
@@ -51,14 +45,14 @@ dependencies:
|
|
|
51
45
|
requirements:
|
|
52
46
|
- - "~>"
|
|
53
47
|
- !ruby/object:Gem::Version
|
|
54
|
-
version: '
|
|
48
|
+
version: '12.0'
|
|
55
49
|
type: :development
|
|
56
50
|
prerelease: false
|
|
57
51
|
version_requirements: !ruby/object:Gem::Requirement
|
|
58
52
|
requirements:
|
|
59
53
|
- - "~>"
|
|
60
54
|
- !ruby/object:Gem::Version
|
|
61
|
-
version: '
|
|
55
|
+
version: '12.0'
|
|
62
56
|
- !ruby/object:Gem::Dependency
|
|
63
57
|
name: minitest
|
|
64
58
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -129,6 +123,34 @@ dependencies:
|
|
|
129
123
|
- - "~>"
|
|
130
124
|
- !ruby/object:Gem::Version
|
|
131
125
|
version: 1.2.1
|
|
126
|
+
- !ruby/object:Gem::Dependency
|
|
127
|
+
name: minitest-focus
|
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
|
129
|
+
requirements:
|
|
130
|
+
- - "~>"
|
|
131
|
+
- !ruby/object:Gem::Version
|
|
132
|
+
version: 1.1.2
|
|
133
|
+
type: :development
|
|
134
|
+
prerelease: false
|
|
135
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
136
|
+
requirements:
|
|
137
|
+
- - "~>"
|
|
138
|
+
- !ruby/object:Gem::Version
|
|
139
|
+
version: 1.1.2
|
|
140
|
+
- !ruby/object:Gem::Dependency
|
|
141
|
+
name: pry
|
|
142
|
+
requirement: !ruby/object:Gem::Requirement
|
|
143
|
+
requirements:
|
|
144
|
+
- - "~>"
|
|
145
|
+
- !ruby/object:Gem::Version
|
|
146
|
+
version: 0.12.2
|
|
147
|
+
type: :development
|
|
148
|
+
prerelease: false
|
|
149
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
150
|
+
requirements:
|
|
151
|
+
- - "~>"
|
|
152
|
+
- !ruby/object:Gem::Version
|
|
153
|
+
version: 0.12.2
|
|
132
154
|
description: A collection of libraries for working with SQL on top of ActiveRecord's
|
|
133
155
|
connection.
|
|
134
156
|
email:
|
|
@@ -161,6 +183,7 @@ files:
|
|
|
161
183
|
- lib/github/ds.rb
|
|
162
184
|
- lib/github/ds/version.rb
|
|
163
185
|
- lib/github/kv.rb
|
|
186
|
+
- lib/github/kv/config.rb
|
|
164
187
|
- lib/github/result.rb
|
|
165
188
|
- lib/github/sql.rb
|
|
166
189
|
- lib/github/sql/errors.rb
|
|
@@ -176,7 +199,7 @@ licenses:
|
|
|
176
199
|
- MIT
|
|
177
200
|
metadata:
|
|
178
201
|
allowed_push_host: https://rubygems.org
|
|
179
|
-
post_install_message:
|
|
202
|
+
post_install_message:
|
|
180
203
|
rdoc_options: []
|
|
181
204
|
require_paths:
|
|
182
205
|
- lib
|
|
@@ -191,9 +214,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
191
214
|
- !ruby/object:Gem::Version
|
|
192
215
|
version: '0'
|
|
193
216
|
requirements: []
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
signing_key:
|
|
217
|
+
rubygems_version: 3.1.2
|
|
218
|
+
signing_key:
|
|
197
219
|
specification_version: 4
|
|
198
220
|
summary: A collection of libraries for working with SQL on top of ActiveRecord's connection.
|
|
199
221
|
test_files: []
|