better_batch-active_record 1.0.3 → 1.1.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 +4 -4
- data/lib/better_batch/active_record/interface.rb +101 -0
- data/lib/better_batch/active_record/model.rb +2 -2
- data/lib/better_batch/active_record/query.rb +3 -87
- data/lib/better_batch/active_record/transform.rb +50 -0
- data/lib/better_batch/active_record/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a12d961c7d5053c050e5ddb15db2a538c1ac45d60b95a4e30fcc3cfd4350b0e3
|
4
|
+
data.tar.gz: a3bb810a265d30d681a51bf01b5c774aa66fb805a318f8cbcad57109eb1c1ad9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 48766522a43487d0be9514d148ad431408ef219333dd4a3ee69de8f4a902e77989cbe7785152d6ae5ee1a11d94eed1750085e3513baf4a05094a5cd54d4c272b
|
7
|
+
data.tar.gz: ed282d59658f40fb23aa6dfbe0a2212aeb854e8001778879e2b8c4daa5f05cb33582d132532dd659f5b677c4a865544139b3c3a3f4cd3f7828b4ba00e7e830b9
|
@@ -0,0 +1,101 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'better_batch/query'
|
4
|
+
require 'better_batch/active_record/query'
|
5
|
+
require 'better_batch/active_record/transform'
|
6
|
+
|
7
|
+
module BetterBatch
|
8
|
+
module ActiveRecord
|
9
|
+
class Interface
|
10
|
+
def initialize(model)
|
11
|
+
@builder = Query.new(model)
|
12
|
+
@model = model
|
13
|
+
end
|
14
|
+
|
15
|
+
def upsert(data, unique_by:, except: nil, returning: nil)
|
16
|
+
upsert_data = Transform.slice_upsert(data, except:)
|
17
|
+
query = builder.build(upsert_data, unique_by:, returning:)
|
18
|
+
result = exec_query(:upsert, query, upsert_data)
|
19
|
+
Transform.build_return(returning, result.rows, query)
|
20
|
+
end
|
21
|
+
|
22
|
+
def with_upserted_pk(data, unique_by:, except: nil, &)
|
23
|
+
upserted = upsert(data, unique_by:, except:, returning: primary_key)
|
24
|
+
if block_given?
|
25
|
+
data.zip(upserted, &)
|
26
|
+
else
|
27
|
+
data.zip(upserted)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def set_upserted_pk(data, unique_by:, except: nil)
|
32
|
+
if block_given?
|
33
|
+
with_upserted_pk(data, unique_by:, except:) do |row, pk|
|
34
|
+
row[primary_key] = pk
|
35
|
+
yield row
|
36
|
+
end
|
37
|
+
else
|
38
|
+
set_upserted_pk_map(data, unique_by:, except:)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def select(data, unique_by:, returning:)
|
43
|
+
Transform.assert_inputs_ok!(data, unique_by:)
|
44
|
+
select_data = data.map { |datum| datum.slice(*unique_by) }
|
45
|
+
query = builder.build(select_data, unique_by:, returning:)
|
46
|
+
result = exec_query(:select, query, select_data)
|
47
|
+
Transform.build_return(returning, result.rows, query)
|
48
|
+
end
|
49
|
+
|
50
|
+
def with_selected_pk(data, unique_by:, &)
|
51
|
+
selected = select(data, unique_by:, returning: primary_key)
|
52
|
+
if block_given?
|
53
|
+
data.zip(selected, &)
|
54
|
+
else
|
55
|
+
data.zip(selected)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def set_selected_pk(data, unique_by:)
|
60
|
+
if block_given?
|
61
|
+
with_selected_pk(data, unique_by:) do |row, pk|
|
62
|
+
row[primary_key] = pk
|
63
|
+
yield row
|
64
|
+
end
|
65
|
+
else
|
66
|
+
set_selected_pk_map(data, unique_by:)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
attr_reader :model, :builder
|
73
|
+
|
74
|
+
def set_upserted_pk_map(data, unique_by:, except: nil)
|
75
|
+
with_upserted_pk(data, unique_by:, except:).map do |row, pk|
|
76
|
+
row[primary_key] = pk
|
77
|
+
row
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def set_selected_pk_map(data, unique_by:)
|
82
|
+
with_selected_pk(data, unique_by:).map do |row, pk|
|
83
|
+
row[primary_key] = pk
|
84
|
+
row
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def exec_query(type, query, data)
|
89
|
+
db_exec(query.public_send(type), JSON.generate(data))
|
90
|
+
end
|
91
|
+
|
92
|
+
def db_exec(sql, json_data)
|
93
|
+
model.connection.exec_query(sql, nil, [json_data])
|
94
|
+
end
|
95
|
+
|
96
|
+
def primary_key
|
97
|
+
model.primary_key.to_sym
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -1,12 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'better_batch/active_record/
|
3
|
+
require 'better_batch/active_record/interface'
|
4
4
|
|
5
5
|
module BetterBatch
|
6
6
|
module ActiveRecord
|
7
7
|
module Model
|
8
8
|
def better_batch
|
9
|
-
|
9
|
+
Interface.new(self)
|
10
10
|
end
|
11
11
|
end
|
12
12
|
end
|
@@ -9,90 +9,15 @@ module BetterBatch
|
|
9
9
|
@model = model
|
10
10
|
end
|
11
11
|
|
12
|
-
def
|
13
|
-
upsert_data = slice_upsert(data, except:)
|
14
|
-
query = build_query(upsert_data, unique_by:, returning:)
|
15
|
-
result = exec_query(:upsert, query, upsert_data)
|
16
|
-
build_return(returning, result.rows, query)
|
17
|
-
end
|
18
|
-
|
19
|
-
def with_upserted_pk(data, unique_by:, except: nil)
|
20
|
-
upserted = upsert(data, unique_by:, except:, returning: primary_key)
|
21
|
-
data.zip(upserted)
|
22
|
-
end
|
23
|
-
|
24
|
-
def set_upserted_pk(data, unique_by:, except: nil)
|
25
|
-
with_upserted_pk(data, unique_by:, except:).each do |row, pk|
|
26
|
-
row[primary_key] = pk
|
27
|
-
end
|
28
|
-
nil
|
29
|
-
end
|
30
|
-
|
31
|
-
def select(data, unique_by:, returning:)
|
32
|
-
assert_inputs_ok!(data, unique_by:)
|
33
|
-
select_data = data.map { |datum| datum.slice(*unique_by) }
|
34
|
-
query = build_query(select_data, unique_by:, returning:)
|
35
|
-
result = exec_query(:select, query, select_data)
|
36
|
-
build_return(returning, result.rows, query)
|
37
|
-
end
|
38
|
-
|
39
|
-
def build_return(returning, rows, query)
|
40
|
-
case returning
|
41
|
-
when Symbol
|
42
|
-
rows.map(&:first)
|
43
|
-
when nil, []
|
44
|
-
nil
|
45
|
-
else
|
46
|
-
hash_rows(query.returning, rows)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
def with_selected_pk(data, unique_by:)
|
51
|
-
data.zip(select(data, unique_by:, returning: primary_key))
|
52
|
-
end
|
53
|
-
|
54
|
-
def set_selected_pk(data, unique_by:)
|
55
|
-
with_upserted_pk(data, unique_by:).each do |row, pk|
|
56
|
-
row[primary_key] = pk
|
57
|
-
end
|
58
|
-
nil
|
59
|
-
end
|
60
|
-
|
61
|
-
private
|
62
|
-
|
63
|
-
attr_reader :model
|
64
|
-
|
65
|
-
def slice_upsert(data, except:)
|
66
|
-
case except
|
67
|
-
when nil, []
|
68
|
-
data
|
69
|
-
else
|
70
|
-
data.map { |datum| datum.except(*except) }
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
def assert_inputs_ok!(data, unique_by:)
|
75
|
-
data_keys = data.first.keys
|
76
|
-
missing = Array(unique_by) - data_keys
|
77
|
-
return if missing.empty?
|
78
|
-
|
79
|
-
msg = "All unique_by columns must be in the given data, but #{missing.inspect} was missing from #{data_keys}."
|
80
|
-
raise Error, msg
|
81
|
-
end
|
82
|
-
|
83
|
-
def build_query(data, unique_by:, returning:)
|
12
|
+
def build(data, unique_by:, returning:)
|
84
13
|
BetterBatch::Query.new(table_name:, primary_key:, input_columns: data.first.keys,
|
85
14
|
column_types:, unique_columns: unique_by, now_on_insert:,
|
86
15
|
now_on_update:, returning:)
|
87
16
|
end
|
88
17
|
|
89
|
-
|
90
|
-
db_exec(query.public_send(type), JSON.generate(data))
|
91
|
-
end
|
18
|
+
private
|
92
19
|
|
93
|
-
|
94
|
-
model.connection.exec_query(sql, nil, [json_data])
|
95
|
-
end
|
20
|
+
attr_reader :model
|
96
21
|
|
97
22
|
def table_name
|
98
23
|
@table_name ||= model.table_name
|
@@ -121,15 +46,6 @@ module BetterBatch
|
|
121
46
|
def updated_at_if_present
|
122
47
|
:updated_at if column_types.key?(:updated_at)
|
123
48
|
end
|
124
|
-
|
125
|
-
def hash_rows(returning, rows)
|
126
|
-
# avoid building an entire new hash (which would rehash keys) for each row
|
127
|
-
# we only need to sub in the values
|
128
|
-
indexes = returning.each_with_index.to_h.freeze
|
129
|
-
rows.map do |row|
|
130
|
-
indexes.transform_values { |index| row[index] }
|
131
|
-
end
|
132
|
-
end
|
133
49
|
end
|
134
50
|
end
|
135
51
|
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'better_batch/query'
|
4
|
+
require 'better_batch/active_record/query'
|
5
|
+
|
6
|
+
module BetterBatch
|
7
|
+
module ActiveRecord
|
8
|
+
module Transform
|
9
|
+
class << self
|
10
|
+
def assert_inputs_ok!(data, unique_by:)
|
11
|
+
data_keys = data.first.keys
|
12
|
+
missing = Array(unique_by) - data_keys
|
13
|
+
return if missing.empty?
|
14
|
+
|
15
|
+
msg = "All unique_by columns must be in the given data, but #{missing.inspect} was missing from #{data_keys}."
|
16
|
+
raise Error, msg
|
17
|
+
end
|
18
|
+
|
19
|
+
def slice_upsert(data, except:)
|
20
|
+
case except
|
21
|
+
when nil, []
|
22
|
+
data
|
23
|
+
else
|
24
|
+
data.map { |datum| datum.except(*except) }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def build_return(returning, rows, query)
|
29
|
+
case returning
|
30
|
+
when Symbol
|
31
|
+
rows.map(&:first)
|
32
|
+
when nil, []
|
33
|
+
nil
|
34
|
+
else
|
35
|
+
hash_rows(query.returning, rows)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def hash_rows(returning, rows)
|
40
|
+
# avoid building an entire new hash (which would rehash keys) for each row
|
41
|
+
# we only need to sub in the values
|
42
|
+
indexes = returning.each_with_index.to_h.freeze
|
43
|
+
rows.map do |row|
|
44
|
+
indexes.transform_values { |index| row[index] }
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: better_batch-active_record
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tyler Hartland
|
8
8
|
bindir: exe
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-04-
|
10
|
+
date: 2025-04-18 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: activerecord
|
@@ -53,8 +53,10 @@ files:
|
|
53
53
|
- lib/better_batch/.DS_Store
|
54
54
|
- lib/better_batch/active_record.rb
|
55
55
|
- lib/better_batch/active_record/error.rb
|
56
|
+
- lib/better_batch/active_record/interface.rb
|
56
57
|
- lib/better_batch/active_record/model.rb
|
57
58
|
- lib/better_batch/active_record/query.rb
|
59
|
+
- lib/better_batch/active_record/transform.rb
|
58
60
|
- lib/better_batch/active_record/version.rb
|
59
61
|
homepage: https://github.com/th7/better_batch-active_record
|
60
62
|
licenses:
|