better_batch-active_record 0.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 +7 -0
- data/lib/.DS_Store +0 -0
- data/lib/better_batch/.DS_Store +0 -0
- data/lib/better_batch/active_record/model.rb +13 -0
- data/lib/better_batch/active_record/query.rb +131 -0
- data/lib/better_batch/active_record/version.rb +7 -0
- data/lib/better_batch/active_record.rb +6 -0
- metadata +82 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: fc3cedf70ce459807c93814252ed8c4db04ccba0288e829b40f92d49df1efe21
|
4
|
+
data.tar.gz: 8062fff1d56372dd65eb20a4bd016022c8c81fc50363648a286a0485c0ad67bd
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 793b02a682e20a0ac01cde09d59a91d642b24bf0453eef62d51924111335d0e7f307526274cf434b3b8467934106a91b85357b9c23794a9378e7009a0eb6dfc5
|
7
|
+
data.tar.gz: 542b42bc0e4b7891936d97f0513f5b10ab0ea889d8e5d68c5454a52c140cf89b33e10a8c405f45bb5f1edc5ad6ac419c832cfafff806c4e8f330ff493b63ae38
|
data/lib/.DS_Store
ADDED
Binary file
|
Binary file
|
@@ -0,0 +1,131 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'better_batch/query'
|
4
|
+
|
5
|
+
module BetterBatch
|
6
|
+
module ActiveRecord
|
7
|
+
class Query
|
8
|
+
def initialize(model)
|
9
|
+
@model = model
|
10
|
+
end
|
11
|
+
|
12
|
+
def upsert(data, unique_by:, returning:)
|
13
|
+
query = build_query(data, unique_by:, returning:)
|
14
|
+
result = exec_query(:upsert, query, data)
|
15
|
+
case returning
|
16
|
+
when Symbol
|
17
|
+
result.rows.map(&:first)
|
18
|
+
when nil
|
19
|
+
nil
|
20
|
+
else
|
21
|
+
hash_rows(query.returning, result.rows)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def with_upserted_pk(data, unique_by:)
|
26
|
+
query = build_query(data, unique_by:, returning: primary_key)
|
27
|
+
data.zip(exec_query(:upsert, query, data).rows.map(&:first))
|
28
|
+
end
|
29
|
+
|
30
|
+
def set_upserted_pk(data, unique_by:)
|
31
|
+
with_upserted_pk(data, unique_by:).each do |row, pk|
|
32
|
+
row[primary_key] = pk
|
33
|
+
end
|
34
|
+
nil
|
35
|
+
end
|
36
|
+
|
37
|
+
def select(data, unique_by:, returning:)
|
38
|
+
query = build_query(data, unique_by:, returning:)
|
39
|
+
result = exec_query(:select, query, data)
|
40
|
+
case returning
|
41
|
+
when Symbol
|
42
|
+
result.rows.map(&:first)
|
43
|
+
when nil
|
44
|
+
nil
|
45
|
+
else
|
46
|
+
hash_rows(query.returning, result.rows)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def with_selected_pk(data, unique_by:)
|
51
|
+
query = build_query(data, unique_by:, returning: primary_key)
|
52
|
+
data.zip(exec_query(:select, query, data).rows.map(&:first))
|
53
|
+
end
|
54
|
+
|
55
|
+
def set_selected_pk(data, unique_by:)
|
56
|
+
with_upserted_pk(data, unique_by:).each do |row, pk|
|
57
|
+
row[primary_key] = pk
|
58
|
+
end
|
59
|
+
nil
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
attr_reader :model
|
65
|
+
|
66
|
+
def build_query(data, unique_by:, returning:)
|
67
|
+
array_data = data.to_a
|
68
|
+
unique_columns = Array(unique_by)
|
69
|
+
input_columns = array_data.first.keys
|
70
|
+
returning = Array(returning)
|
71
|
+
BetterBatch::Query.new(table_name:, primary_key:, input_columns:, column_types:, unique_columns:,
|
72
|
+
now_on_insert:, now_on_update:, returning:)
|
73
|
+
end
|
74
|
+
|
75
|
+
def exec_query(type, query, data)
|
76
|
+
sql = build_sql(type, query)
|
77
|
+
json_data = JSON.generate(data)
|
78
|
+
db_exec(sql, query, json_data)
|
79
|
+
end
|
80
|
+
|
81
|
+
def build_sql(type, query)
|
82
|
+
query.public_send(type)
|
83
|
+
rescue StandardError
|
84
|
+
raise query.inspect
|
85
|
+
end
|
86
|
+
|
87
|
+
def db_exec(sql, query, json_data)
|
88
|
+
model.connection.exec_query(sql, nil, [json_data])
|
89
|
+
rescue StandardError
|
90
|
+
raise [query.inspect, query.upsert_formatted].join("\n")
|
91
|
+
end
|
92
|
+
|
93
|
+
def table_name
|
94
|
+
@table_name ||= model.table_name
|
95
|
+
end
|
96
|
+
|
97
|
+
def primary_key
|
98
|
+
model.primary_key.to_sym
|
99
|
+
end
|
100
|
+
|
101
|
+
def column_types
|
102
|
+
@column_types ||= model.columns.to_h { |c| [c.name.to_sym, c.sql_type] }
|
103
|
+
end
|
104
|
+
|
105
|
+
def now_on_insert
|
106
|
+
[created_at_if_present, updated_at_if_present].compact
|
107
|
+
end
|
108
|
+
|
109
|
+
def now_on_update
|
110
|
+
updated_at_if_present
|
111
|
+
end
|
112
|
+
|
113
|
+
def created_at_if_present
|
114
|
+
:created_at if column_types.key?(:created_at)
|
115
|
+
end
|
116
|
+
|
117
|
+
def updated_at_if_present
|
118
|
+
:updated_at if column_types.key?(:updated_at)
|
119
|
+
end
|
120
|
+
|
121
|
+
def hash_rows(returning, rows)
|
122
|
+
# avoid building an entire new hash (which would rehash keys) for each row
|
123
|
+
# we only need to sub in the values
|
124
|
+
indexes = returning.each_with_index.to_h.freeze
|
125
|
+
rows.map do |row|
|
126
|
+
indexes.transform_values { |index| row[index] }
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
metadata
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: better_batch-active_record
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Tyler Hartland
|
8
|
+
bindir: exe
|
9
|
+
cert_chain: []
|
10
|
+
date: 2025-04-16 00:00:00.000000000 Z
|
11
|
+
dependencies:
|
12
|
+
- !ruby/object:Gem::Dependency
|
13
|
+
name: activerecord
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
15
|
+
requirements:
|
16
|
+
- - ">="
|
17
|
+
- !ruby/object:Gem::Version
|
18
|
+
version: '7'
|
19
|
+
- - "<"
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '9'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
version: '7'
|
29
|
+
- - "<"
|
30
|
+
- !ruby/object:Gem::Version
|
31
|
+
version: '9'
|
32
|
+
- !ruby/object:Gem::Dependency
|
33
|
+
name: better_batch
|
34
|
+
requirement: !ruby/object:Gem::Requirement
|
35
|
+
requirements:
|
36
|
+
- - "~>"
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: '1'
|
39
|
+
type: :runtime
|
40
|
+
prerelease: false
|
41
|
+
version_requirements: !ruby/object:Gem::Requirement
|
42
|
+
requirements:
|
43
|
+
- - "~>"
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '1'
|
46
|
+
email:
|
47
|
+
- tylerhartland7@gmail.com
|
48
|
+
executables: []
|
49
|
+
extensions: []
|
50
|
+
extra_rdoc_files: []
|
51
|
+
files:
|
52
|
+
- lib/.DS_Store
|
53
|
+
- lib/better_batch/.DS_Store
|
54
|
+
- lib/better_batch/active_record.rb
|
55
|
+
- lib/better_batch/active_record/model.rb
|
56
|
+
- lib/better_batch/active_record/query.rb
|
57
|
+
- lib/better_batch/active_record/version.rb
|
58
|
+
homepage: https://github.com/th7/better_batch-active_record
|
59
|
+
licenses:
|
60
|
+
- MIT
|
61
|
+
metadata:
|
62
|
+
allowed_push_host: https://rubygems.org
|
63
|
+
source_code_uri: https://github.com/th7/better_batch-active_record
|
64
|
+
rubygems_mfa_required: 'true'
|
65
|
+
rdoc_options: []
|
66
|
+
require_paths:
|
67
|
+
- lib
|
68
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
69
|
+
requirements:
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: 3.2.0
|
73
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
requirements: []
|
79
|
+
rubygems_version: 3.6.2
|
80
|
+
specification_version: 4
|
81
|
+
summary: Better batch operations.
|
82
|
+
test_files: []
|