github-ds 0.2.10 → 0.5.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 +5 -5
- data/.travis.yml +5 -6
- data/Gemfile +10 -4
- data/README.md +10 -0
- data/github-ds.gemspec +3 -1
- 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 -18
- data/lib/github/kv/config.rb +13 -0
- data/lib/github/sql.rb +3 -3
- metadata +37 -9
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 4b95473248771ff3545335efd43524ac0cabeb2f2ec8ec838f7f7537149e9c5e
|
|
4
|
+
data.tar.gz: dbf07fa010c19fde19540f22f54e0f6f5fec6d4861b31cac059f92c081f7d9bd
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 433f178728cbc1c7748e3b0b7985781bb8d39aabb338169cbc08eb6a954a914a80796b6bcbeda711d1a1de8c0bb87809102b7022c07e2ba97f381bafcdf0c450
|
|
7
|
+
data.tar.gz: 47586ed750c3af0cbbf0dc34820c99da0c9c69f81946a4f505ba9100c9368ab16e094e0483c7cf37692ad4c0db317b1c0b499c34c5e536e9fb62a1f3e1e4fd1f
|
data/.travis.yml
CHANGED
|
@@ -3,13 +3,12 @@ before_install:
|
|
|
3
3
|
- gem uninstall -v '>= 2' -i $(rvm gemdir)@global -ax bundler || true
|
|
4
4
|
- gem install bundler -v '<2'
|
|
5
5
|
rvm:
|
|
6
|
-
- 2.3
|
|
7
|
-
- 2.4
|
|
8
6
|
- 2.5
|
|
7
|
+
- 2.6
|
|
8
|
+
- 2.7
|
|
9
9
|
script: bundle exec rake
|
|
10
10
|
env:
|
|
11
|
-
- RAILS_VERSION=6.0.
|
|
11
|
+
- RAILS_VERSION=6.0.3.5
|
|
12
12
|
- RAILS_VERSION=5.2.0
|
|
13
|
-
|
|
14
|
-
-
|
|
15
|
-
- RAILS_VERSION=4.2.10
|
|
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'
|
|
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
|
|
@@ -86,6 +94,8 @@ pp kv.mdel(["foo", "bar"])
|
|
|
86
94
|
# nil
|
|
87
95
|
```
|
|
88
96
|
|
|
97
|
+
Note that due to MySQL's default collation, KV keys are case-insensitive.
|
|
98
|
+
|
|
89
99
|
### GitHub::SQL
|
|
90
100
|
|
|
91
101
|
```ruby
|
data/github-ds.gemspec
CHANGED
|
@@ -33,10 +33,12 @@ Gem::Specification.new do |spec|
|
|
|
33
33
|
spec.add_dependency "activerecord", ">= 3.2"
|
|
34
34
|
|
|
35
35
|
spec.add_development_dependency "bundler", ">= 1.14"
|
|
36
|
-
spec.add_development_dependency "rake", "~>
|
|
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,11 +125,12 @@ 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
|
-
keys.
|
|
132
|
+
kvs.keys.each { |key| kvs[key.downcase] = kvs[key] }
|
|
133
|
+
keys.map { |key| kvs[key.downcase] }
|
|
101
134
|
}
|
|
102
135
|
end
|
|
103
136
|
|
|
@@ -137,12 +170,12 @@ module GitHub
|
|
|
137
170
|
|
|
138
171
|
rows = kvs.map { |key, value|
|
|
139
172
|
value = value.is_a?(GitHub::SQL::Literal) ? value : GitHub::SQL::BINARY(value)
|
|
140
|
-
[key, value,
|
|
173
|
+
[key, value, now, now, expires || GitHub::SQL::NULL]
|
|
141
174
|
}
|
|
142
175
|
|
|
143
176
|
encapsulate_error do
|
|
144
177
|
GitHub::SQL.run(<<-SQL, :rows => GitHub::SQL::ROWS(rows), :connection => connection)
|
|
145
|
-
INSERT INTO
|
|
178
|
+
INSERT INTO #{@table_name} (`key`, value, created_at, updated_at, expires_at)
|
|
146
179
|
VALUES :rows
|
|
147
180
|
ON DUPLICATE KEY UPDATE
|
|
148
181
|
value = VALUES(value),
|
|
@@ -186,8 +219,8 @@ module GitHub
|
|
|
186
219
|
validate_key_array(keys)
|
|
187
220
|
|
|
188
221
|
Result.new {
|
|
189
|
-
existing_keys = GitHub::SQL.values(<<-SQL, :keys => keys, :connection => connection).to_set
|
|
190
|
-
SELECT `key` FROM
|
|
222
|
+
existing_keys = GitHub::SQL.values(<<-SQL, :keys => keys, :now => now, :connection => connection).to_set
|
|
223
|
+
SELECT `key` FROM #{@table_name} WHERE `key` IN :keys AND (`expires_at` IS NULL OR `expires_at` > :now)
|
|
191
224
|
SQL
|
|
192
225
|
|
|
193
226
|
keys.map { |key| existing_keys.include?(key) }
|
|
@@ -222,20 +255,116 @@ module GitHub
|
|
|
222
255
|
# achieve the same thing with the right INSERT ... ON DUPLICATE KEY UPDATE
|
|
223
256
|
# query, but then we would not be able to rely on affected_rows
|
|
224
257
|
|
|
225
|
-
GitHub::SQL.run(<<-SQL, :key => key, :connection => connection)
|
|
226
|
-
DELETE FROM
|
|
258
|
+
GitHub::SQL.run(<<-SQL, :key => key, :now => now, :connection => connection)
|
|
259
|
+
DELETE FROM #{@table_name} WHERE `key` = :key AND expires_at <= :now
|
|
227
260
|
SQL
|
|
228
261
|
|
|
229
262
|
value = value.is_a?(GitHub::SQL::Literal) ? value : GitHub::SQL::BINARY(value)
|
|
230
|
-
sql = GitHub::SQL.run(<<-SQL, :key => key, :value => value, :expires => expires || GitHub::SQL::NULL, :connection => connection)
|
|
231
|
-
INSERT IGNORE INTO
|
|
232
|
-
VALUES (:key, :value,
|
|
263
|
+
sql = GitHub::SQL.run(<<-SQL, :key => key, :value => value, :now => now, :expires => expires || GitHub::SQL::NULL, :connection => connection)
|
|
264
|
+
INSERT IGNORE INTO #{@table_name} (`key`, value, created_at, updated_at, expires_at)
|
|
265
|
+
VALUES (:key, :value, :now, :now, :expires)
|
|
233
266
|
SQL
|
|
234
267
|
|
|
235
268
|
sql.affected_rows > 0
|
|
236
269
|
}
|
|
237
270
|
end
|
|
238
271
|
|
|
272
|
+
# increment :: String, Integer, expires: Time? -> Integer
|
|
273
|
+
#
|
|
274
|
+
# Increment the key's value by an amount.
|
|
275
|
+
#
|
|
276
|
+
# key - The key to increment.
|
|
277
|
+
# amount - The amount to increment the key's value by.
|
|
278
|
+
# The user can increment by both positive and
|
|
279
|
+
# negative values
|
|
280
|
+
# expires - When the key should expire.
|
|
281
|
+
# touch_on_insert - Only when expires is specified. When true
|
|
282
|
+
# the expires value is only touched upon
|
|
283
|
+
# inserts. Otherwise the record is always
|
|
284
|
+
# touched.
|
|
285
|
+
#
|
|
286
|
+
# Returns the key's value after incrementing.
|
|
287
|
+
def increment(key, amount: 1, expires: nil, touch_on_insert: false)
|
|
288
|
+
validate_key(key)
|
|
289
|
+
validate_amount(amount) if amount
|
|
290
|
+
validate_expires(expires) if expires
|
|
291
|
+
validate_touch(touch_on_insert, expires)
|
|
292
|
+
|
|
293
|
+
expires ||= GitHub::SQL::NULL
|
|
294
|
+
|
|
295
|
+
# This query uses a few MySQL "hacks" to ensure that the incrementing
|
|
296
|
+
# is done atomically and the value is returned. The first trick is done
|
|
297
|
+
# using the `LAST_INSERT_ID` function. This allows us to manually set
|
|
298
|
+
# the LAST_INSERT_ID returned by the query. Here we are able to set it
|
|
299
|
+
# to the new value when an increment takes place, essentially allowing us
|
|
300
|
+
# to do: `UPDATE...;SELECT value from key_value where key=:key` in a
|
|
301
|
+
# single step.
|
|
302
|
+
#
|
|
303
|
+
# However the `LAST_INSERT_ID` trick is only used when the value is
|
|
304
|
+
# updated. Upon a fresh insert we know the amount is going to be set
|
|
305
|
+
# to the amount specified.
|
|
306
|
+
#
|
|
307
|
+
# Lastly we only do these tricks when the value at the key is an integer.
|
|
308
|
+
# If the value is not an integer the update ensures the values remain the
|
|
309
|
+
# same and we raise an error.
|
|
310
|
+
encapsulate_error {
|
|
311
|
+
sql = GitHub::SQL.run(<<-SQL, key: key, amount: amount, now: now, expires: expires, touch: !touch_on_insert, connection: connection)
|
|
312
|
+
INSERT INTO #{@table_name} (`key`, `value`, `created_at`, `updated_at`, `expires_at`)
|
|
313
|
+
VALUES(:key, :amount, :now, :now, :expires)
|
|
314
|
+
ON DUPLICATE KEY UPDATE
|
|
315
|
+
`value`=IF(
|
|
316
|
+
concat('',`value`*1) = `value`,
|
|
317
|
+
LAST_INSERT_ID(IF(
|
|
318
|
+
`expires_at` IS NULL OR `expires_at`>=:now,
|
|
319
|
+
`value`+:amount,
|
|
320
|
+
:amount
|
|
321
|
+
)),
|
|
322
|
+
`value`
|
|
323
|
+
),
|
|
324
|
+
`updated_at`=IF(
|
|
325
|
+
concat('',`value`*1) = `value`,
|
|
326
|
+
:now,
|
|
327
|
+
`updated_at`
|
|
328
|
+
),
|
|
329
|
+
`expires_at`=IF(
|
|
330
|
+
concat('',`value`*1) = `value`,
|
|
331
|
+
IF(
|
|
332
|
+
:touch OR (`expires_at` IS NULL OR `expires_at`<:now),
|
|
333
|
+
:expires,
|
|
334
|
+
`expires_at`
|
|
335
|
+
),
|
|
336
|
+
`expires_at`
|
|
337
|
+
)
|
|
338
|
+
SQL
|
|
339
|
+
|
|
340
|
+
# The ordering of these statements is extremely important if we are to
|
|
341
|
+
# support incrementing a negative amount. The checks occur in this order:
|
|
342
|
+
# 1. Check if an update with new values occurred? If so return the result
|
|
343
|
+
# This could potentially result in `sql.last_insert_id` with a value
|
|
344
|
+
# of 0, thus it must be before the second check.
|
|
345
|
+
# 2. Check if an update took place but nothing changed (I.E. no new value
|
|
346
|
+
# was set)
|
|
347
|
+
# 3. Check if an insert took place.
|
|
348
|
+
#
|
|
349
|
+
# See https://dev.mysql.com/doc/refman/8.0/en/insert-on-duplicate.html for
|
|
350
|
+
# more information (NOTE: CLIENT_FOUND_ROWS is set)
|
|
351
|
+
if sql.affected_rows == 2
|
|
352
|
+
# An update took place in which data changed. We use a hack to set
|
|
353
|
+
# the last insert ID to be the new value.
|
|
354
|
+
sql.last_insert_id
|
|
355
|
+
elsif sql.affected_rows == 0 || (sql.affected_rows == 1 && sql.last_insert_id == 0)
|
|
356
|
+
# No insert took place nor did any update occur. This means that
|
|
357
|
+
# the value was not an integer thus not incremented.
|
|
358
|
+
raise InvalidValueError
|
|
359
|
+
elsif sql.affected_rows == 1
|
|
360
|
+
# If the number of affected_rows is 1 then a new value was inserted
|
|
361
|
+
# thus we can just return the amount given to us since that is the
|
|
362
|
+
# value at the key
|
|
363
|
+
amount
|
|
364
|
+
end
|
|
365
|
+
}
|
|
366
|
+
end
|
|
367
|
+
|
|
239
368
|
# del :: String -> nil
|
|
240
369
|
#
|
|
241
370
|
# Deletes the specified key. Returns nil. Raises on error.
|
|
@@ -265,7 +394,7 @@ module GitHub
|
|
|
265
394
|
|
|
266
395
|
encapsulate_error do
|
|
267
396
|
GitHub::SQL.run(<<-SQL, :keys => keys, :connection => connection)
|
|
268
|
-
DELETE FROM
|
|
397
|
+
DELETE FROM #{@table_name} WHERE `key` IN :keys
|
|
269
398
|
SQL
|
|
270
399
|
end
|
|
271
400
|
|
|
@@ -288,14 +417,40 @@ module GitHub
|
|
|
288
417
|
validate_key(key)
|
|
289
418
|
|
|
290
419
|
Result.new {
|
|
291
|
-
GitHub::SQL.value(<<-SQL, :key => key, :connection => connection)
|
|
292
|
-
SELECT expires_at FROM
|
|
293
|
-
WHERE `key` = :key AND (expires_at IS NULL OR expires_at >
|
|
420
|
+
GitHub::SQL.value(<<-SQL, :key => key, :now => now, :connection => connection)
|
|
421
|
+
SELECT expires_at FROM #{@table_name}
|
|
422
|
+
WHERE `key` = :key AND (expires_at IS NULL OR expires_at > :now)
|
|
294
423
|
SQL
|
|
295
424
|
}
|
|
296
425
|
end
|
|
297
426
|
|
|
427
|
+
# mttl :: [String] -> Result<[Time | nil]>
|
|
428
|
+
#
|
|
429
|
+
# Returns the expires_at time for the specified key or nil.
|
|
430
|
+
#
|
|
431
|
+
# Example:
|
|
432
|
+
#
|
|
433
|
+
# kv.mttl(["foo", "octocat"])
|
|
434
|
+
# # => #<Result value: [2018-04-23 11:34:54 +0200, nil]>
|
|
435
|
+
#
|
|
436
|
+
def mttl(keys)
|
|
437
|
+
validate_key_array(keys)
|
|
438
|
+
|
|
439
|
+
Result.new {
|
|
440
|
+
kvs = GitHub::SQL.results(<<-SQL, :keys => keys, :now => now, :connection => connection).to_h
|
|
441
|
+
SELECT `key`, expires_at FROM #{@table_name}
|
|
442
|
+
WHERE `key` in :keys AND (expires_at IS NULL OR expires_at > :now)
|
|
443
|
+
SQL
|
|
444
|
+
|
|
445
|
+
keys.map { |key| kvs[key] }
|
|
446
|
+
}
|
|
447
|
+
end
|
|
448
|
+
|
|
298
449
|
private
|
|
450
|
+
def now
|
|
451
|
+
use_local_time ? Time.now : GitHub::SQL::NOW
|
|
452
|
+
end
|
|
453
|
+
|
|
299
454
|
def validate_key(key, error_message: nil)
|
|
300
455
|
unless key.is_a?(String)
|
|
301
456
|
raise TypeError, error_message || "key must be a String in #{self.class.name}, but was #{key.class}"
|
|
@@ -349,6 +504,19 @@ module GitHub
|
|
|
349
504
|
end
|
|
350
505
|
end
|
|
351
506
|
|
|
507
|
+
def validate_amount(amount)
|
|
508
|
+
raise ArgumentError.new("The amount specified must be an integer") unless amount.is_a? Integer
|
|
509
|
+
raise ArgumentError.new("The amount specified cannot be 0") if amount == 0
|
|
510
|
+
end
|
|
511
|
+
|
|
512
|
+
def validate_touch(touch, expires)
|
|
513
|
+
raise ArgumentError.new("touch_on_insert must be a boolean value") unless [true, false].include?(touch)
|
|
514
|
+
|
|
515
|
+
if touch && expires.nil?
|
|
516
|
+
raise ArgumentError.new("Please specify an expires value if you wish to touch on insert")
|
|
517
|
+
end
|
|
518
|
+
end
|
|
519
|
+
|
|
352
520
|
def validate_expires(expires)
|
|
353
521
|
unless expires.respond_to?(:to_time)
|
|
354
522
|
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.2
|
|
4
|
+
version: 0.5.2
|
|
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: 2021-04-07 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: activerecord
|
|
@@ -45,14 +45,14 @@ dependencies:
|
|
|
45
45
|
requirements:
|
|
46
46
|
- - "~>"
|
|
47
47
|
- !ruby/object:Gem::Version
|
|
48
|
-
version: '
|
|
48
|
+
version: '12.0'
|
|
49
49
|
type: :development
|
|
50
50
|
prerelease: false
|
|
51
51
|
version_requirements: !ruby/object:Gem::Requirement
|
|
52
52
|
requirements:
|
|
53
53
|
- - "~>"
|
|
54
54
|
- !ruby/object:Gem::Version
|
|
55
|
-
version: '
|
|
55
|
+
version: '12.0'
|
|
56
56
|
- !ruby/object:Gem::Dependency
|
|
57
57
|
name: minitest
|
|
58
58
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -123,6 +123,34 @@ dependencies:
|
|
|
123
123
|
- - "~>"
|
|
124
124
|
- !ruby/object:Gem::Version
|
|
125
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
|
|
126
154
|
description: A collection of libraries for working with SQL on top of ActiveRecord's
|
|
127
155
|
connection.
|
|
128
156
|
email:
|
|
@@ -155,6 +183,7 @@ files:
|
|
|
155
183
|
- lib/github/ds.rb
|
|
156
184
|
- lib/github/ds/version.rb
|
|
157
185
|
- lib/github/kv.rb
|
|
186
|
+
- lib/github/kv/config.rb
|
|
158
187
|
- lib/github/result.rb
|
|
159
188
|
- lib/github/sql.rb
|
|
160
189
|
- lib/github/sql/errors.rb
|
|
@@ -170,7 +199,7 @@ licenses:
|
|
|
170
199
|
- MIT
|
|
171
200
|
metadata:
|
|
172
201
|
allowed_push_host: https://rubygems.org
|
|
173
|
-
post_install_message:
|
|
202
|
+
post_install_message:
|
|
174
203
|
rdoc_options: []
|
|
175
204
|
require_paths:
|
|
176
205
|
- lib
|
|
@@ -185,9 +214,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
185
214
|
- !ruby/object:Gem::Version
|
|
186
215
|
version: '0'
|
|
187
216
|
requirements: []
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
signing_key:
|
|
217
|
+
rubygems_version: 3.1.4
|
|
218
|
+
signing_key:
|
|
191
219
|
specification_version: 4
|
|
192
220
|
summary: A collection of libraries for working with SQL on top of ActiveRecord's connection.
|
|
193
221
|
test_files: []
|