umbrellio-utils 1.1.0 → 1.2.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 69008a465e6cb9232b9e2ae595e519b04358ca1b6c39a140cb63e3f2c94b4d07
4
- data.tar.gz: aff52ed04ae02ff06788f5d7cf990e9d55043411f59ed8e45866c4234b968225
3
+ metadata.gz: aaa7935344d41de32a9d61527b1c7b167d64715207422fc23f83d790950e5951
4
+ data.tar.gz: f9d7707ff893d916462b7e584a08ad8171036825eecacc201eecc09b17fc041f
5
5
  SHA512:
6
- metadata.gz: 3f832a358b8517c3a9679a777eafd8488047488f8df5d451f395b0704213b994b1354d24346204e1bb63ff9e1e5eb135dc933905c53c12e18a2e6eda9ee81912
7
- data.tar.gz: a89452771f674065a78c1a64cb41466938bb2e42e681d5fa1a3c8f4c786be608f4ed6afb56ecd2f84de343a95036d673cde68352bf8225d3dee807a81d47e019
6
+ metadata.gz: 319224d118b8c1197b9d93855aa83dcb8dbe80b33fb9395d8782e24cbdd4e303ce7bea798f33b4940febfa268d4f457dae0aac55d14e43e5933fd60d9d038362
7
+ data.tar.gz: fb536f209a2190fc064db5b0f3a73b01b9286deceab3b7ee83e7f88cbb0023203737b29444baf218b42402dd5e0ad2f2a0bc60edf92bbf0cfbceb1352c5c0f84
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- umbrellio-utils (1.1.0)
4
+ umbrellio-utils (1.2.1)
5
5
  memery (~> 1)
6
6
 
7
7
  GEM
@@ -5,6 +5,7 @@ module UmbrellioUtils
5
5
  extend self
6
6
 
7
7
  HandledConstaintError = Class.new(StandardError)
8
+ InvalidPkError = Class.new(StandardError)
8
9
 
9
10
  def handle_constraint_error(constraint_name, &block)
10
11
  DB.transaction(savepoint: true, &block)
@@ -22,15 +23,16 @@ module UmbrellioUtils
22
23
  end
23
24
 
24
25
  def each_record(dataset, **options, &block)
25
- primary_key = primary_key_from(**options)
26
+ primary_key = primary_key_from(dataset, **options)
26
27
 
27
28
  with_temp_table(dataset, **options) do |ids|
28
- dataset.model.where(primary_key => ids).reverse(primary_key).each(&block)
29
+ rows = ids.map { |id| row(id.is_a?(Hash) ? id.values : [id]) }
30
+ dataset.model.where(row(primary_key) => rows).reverse(row(primary_key)).each(&block)
29
31
  end
30
32
  end
31
33
 
32
34
  def with_temp_table(dataset, page_size: 1_000, sleep: nil, **options)
33
- primary_key = primary_key_from(**options)
35
+ primary_key = primary_key_from(dataset, **options)
34
36
  sleep_interval = sleep_interval_from(sleep)
35
37
 
36
38
  temp_table_name = create_temp_table(dataset, primary_key: primary_key)
@@ -39,11 +41,7 @@ module UmbrellioUtils
39
41
 
40
42
  loop do
41
43
  DB.transaction do
42
- pk_expr = DB[temp_table_name].select(primary_key).reverse(primary_key).limit(page_size)
43
-
44
- deleted_items = DB[temp_table_name].where(primary_key => pk_expr).returning.delete
45
- pk_set = deleted_items.map { |item| item[primary_key] }
46
-
44
+ pk_set = pop_next_pk_batch(temp_table_name, primary_key, page_size)
47
45
  yield(pk_set) if pk_set.any?
48
46
  end
49
47
 
@@ -61,18 +59,22 @@ module UmbrellioUtils
61
59
  Lamian.logger.send(:logdevs).each { |x| x.truncate(0) && x.rewind }
62
60
  end
63
61
 
64
- def create_temp_table(dataset, primary_key:)
65
- model = dataset.model
62
+ def create_temp_table(dataset, **options)
66
63
  time = Time.current
64
+ model = dataset.model
67
65
  temp_table_name = "temp_#{model.table_name}_#{time.to_i}_#{time.nsec}".to_sym
68
- type = model.db_schema[primary_key][:db_type]
66
+ primary_key = primary_key_from(dataset, **options)
69
67
 
70
- DB.drop_table?(temp_table_name)
71
68
  DB.create_table(temp_table_name, unlogged: true) do
72
- column primary_key, type, primary_key: true
69
+ primary_key.each do |field|
70
+ type = model.db_schema[field][:db_type]
71
+ column field, type
72
+ end
73
+
74
+ primary_key primary_key
73
75
  end
74
76
 
75
- insert_ds = dataset.select(Sequel[model.table_name][primary_key])
77
+ insert_ds = dataset.select(*qualified_pk(model.table_name, primary_key))
76
78
  DB[temp_table_name].disable_insert_returning.insert(insert_ds)
77
79
 
78
80
  temp_table_name
@@ -80,8 +82,22 @@ module UmbrellioUtils
80
82
 
81
83
  private
82
84
 
83
- def primary_key_from(**options)
84
- options.fetch(:primary_key, :id)
85
+ def row(values)
86
+ Sequel.function(:row, *values)
87
+ end
88
+
89
+ def extract_primary_key(dataset)
90
+ dataset.db.schema(dataset.first_source).select { |x| x[1][:primary_key] }.map(&:first)
91
+ end
92
+
93
+ def primary_key_from(dataset, **options)
94
+ Array(options[:primary_key] || extract_primary_key(dataset)).tap do |primary_key|
95
+ raise InvalidPkError if primary_key.empty?
96
+ end
97
+ end
98
+
99
+ def qualified_pk(table_name, primary_key)
100
+ primary_key.map { |f| Sequel[table_name][f] }
85
101
  end
86
102
 
87
103
  def sleep_interval_from(sleep)
@@ -94,5 +110,15 @@ module UmbrellioUtils
94
110
  defined?(Rails) && Rails.env.production? ? 1 : 0
95
111
  end
96
112
  end
113
+
114
+ def pop_next_pk_batch(temp_table_name, primary_key, batch_size)
115
+ row = row(primary_key)
116
+ pk_expr = DB[temp_table_name].select(*primary_key).reverse(row).limit(batch_size)
117
+ deleted_items = DB[temp_table_name].where(row => pk_expr).returning.delete
118
+ deleted_items.map do |item|
119
+ next item if primary_key.size > 1
120
+ item[primary_key.first]
121
+ end
122
+ end
97
123
  end
98
124
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module UmbrellioUtils
4
- VERSION = "1.1.0"
4
+ VERSION = "1.2.1"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: umbrellio-utils
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Team Umbrellio
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-05-02 00:00:00.000000000 Z
11
+ date: 2024-05-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: memery