chrono_model 1.0.1 → 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 +5 -5
- data/.travis.yml +19 -14
- data/README.md +49 -25
- data/lib/chrono_model.rb +37 -3
- data/lib/chrono_model/adapter.rb +91 -874
- data/lib/chrono_model/adapter/ddl.rb +225 -0
- data/lib/chrono_model/adapter/indexes.rb +194 -0
- data/lib/chrono_model/adapter/migrations.rb +282 -0
- data/lib/chrono_model/adapter/tsrange.rb +57 -0
- data/lib/chrono_model/adapter/upgrade.rb +120 -0
- data/lib/chrono_model/conversions.rb +20 -0
- data/lib/chrono_model/json.rb +28 -0
- data/lib/chrono_model/patches.rb +8 -232
- data/lib/chrono_model/patches/as_of_time_holder.rb +23 -0
- data/lib/chrono_model/patches/as_of_time_relation.rb +19 -0
- data/lib/chrono_model/patches/association.rb +52 -0
- data/lib/chrono_model/patches/db_console.rb +11 -0
- data/lib/chrono_model/patches/join_node.rb +32 -0
- data/lib/chrono_model/patches/preloader.rb +68 -0
- data/lib/chrono_model/patches/relation.rb +58 -0
- data/lib/chrono_model/time_gate.rb +5 -5
- data/lib/chrono_model/time_machine.rb +47 -427
- data/lib/chrono_model/time_machine/history_model.rb +196 -0
- data/lib/chrono_model/time_machine/time_query.rb +86 -0
- data/lib/chrono_model/time_machine/timeline.rb +94 -0
- data/lib/chrono_model/utilities.rb +27 -0
- data/lib/chrono_model/version.rb +1 -1
- data/spec/aruba/dbconsole_spec.rb +25 -0
- data/spec/chrono_model/adapter/counter_cache_race_spec.rb +46 -0
- data/spec/{adapter_spec.rb → chrono_model/adapter_spec.rb} +124 -5
- data/spec/{utils_spec.rb → chrono_model/conversions_spec.rb} +0 -0
- data/spec/{json_ops_spec.rb → chrono_model/json_ops_spec.rb} +11 -0
- data/spec/{time_machine_spec.rb → chrono_model/time_machine_spec.rb} +15 -5
- data/spec/{time_query_spec.rb → chrono_model/time_query_spec.rb} +0 -0
- data/spec/config.travis.yml +1 -0
- data/spec/config.yml.example +1 -0
- metadata +35 -14
- data/lib/chrono_model/utils.rb +0 -117
@@ -78,6 +78,33 @@ describe ChronoModel::Adapter do
|
|
78
78
|
native
|
79
79
|
end
|
80
80
|
|
81
|
+
describe '.is_chrono?' do
|
82
|
+
with_temporal_table do
|
83
|
+
it { expect(adapter.is_chrono?(table)).to be(true) }
|
84
|
+
end
|
85
|
+
|
86
|
+
with_plain_table do
|
87
|
+
it { expect(adapter.is_chrono?(table)).to be(false) }
|
88
|
+
end
|
89
|
+
|
90
|
+
context 'when schemas are not there yet' do
|
91
|
+
before(:all) do
|
92
|
+
adapter.execute 'BEGIN'
|
93
|
+
adapter.execute 'DROP SCHEMA temporal CASCADE'
|
94
|
+
adapter.execute 'DROP SCHEMA history CASCADE'
|
95
|
+
adapter.execute 'CREATE TABLE test_table (id integer)'
|
96
|
+
end
|
97
|
+
|
98
|
+
after(:all) do
|
99
|
+
adapter.execute 'ROLLBACK'
|
100
|
+
end
|
101
|
+
|
102
|
+
it { expect { adapter.is_chrono?(table) }.to_not raise_error }
|
103
|
+
|
104
|
+
it { expect(adapter.is_chrono?(table)).to be(false) }
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
81
108
|
describe '.create_table' do
|
82
109
|
with_temporal_table do
|
83
110
|
it_should_behave_like 'temporal table'
|
@@ -395,11 +422,15 @@ describe ChronoModel::Adapter do
|
|
395
422
|
|
396
423
|
describe '.on_schema' do
|
397
424
|
before(:all) do
|
425
|
+
adapter.execute 'BEGIN'
|
398
426
|
5.times {|i| adapter.execute "CREATE SCHEMA test_#{i}"}
|
399
427
|
end
|
400
428
|
|
401
|
-
|
429
|
+
after(:all) do
|
430
|
+
adapter.execute 'ROLLBACK'
|
431
|
+
end
|
402
432
|
|
433
|
+
context 'by default' do
|
403
434
|
it 'saves the schema at each recursion' do
|
404
435
|
is_expected.to be_in_schema(:default)
|
405
436
|
|
@@ -415,15 +446,37 @@ describe ChronoModel::Adapter do
|
|
415
446
|
is_expected.to be_in_schema(:default)
|
416
447
|
end
|
417
448
|
|
449
|
+
context 'when errors occur' do
|
450
|
+
subject do
|
451
|
+
adapter.on_schema('test_1') do
|
452
|
+
|
453
|
+
adapter.on_schema('test_2') do
|
454
|
+
adapter.execute 'BEGIN'
|
455
|
+
adapter.execute 'ERRORING ON PURPOSE'
|
456
|
+
end
|
457
|
+
|
458
|
+
end
|
459
|
+
end
|
460
|
+
|
461
|
+
it {
|
462
|
+
expect { subject }.
|
463
|
+
to raise_error(/current transaction is aborted/).
|
464
|
+
and change { adapter.instance_variable_get(:@schema_search_path) }
|
465
|
+
}
|
466
|
+
|
467
|
+
after do
|
468
|
+
adapter.execute 'ROLLBACK'
|
469
|
+
end
|
470
|
+
end
|
418
471
|
end
|
419
472
|
|
420
|
-
context '
|
473
|
+
context 'with recurse: :ignore' do
|
421
474
|
it 'ignores recursive calls' do
|
422
475
|
is_expected.to be_in_schema(:default)
|
423
476
|
|
424
|
-
adapter.on_schema('test_1',
|
425
|
-
adapter.on_schema('test_2',
|
426
|
-
adapter.on_schema('test_3',
|
477
|
+
adapter.on_schema('test_1', recurse: :ignore) { is_expected.to be_in_schema('test_1')
|
478
|
+
adapter.on_schema('test_2', recurse: :ignore) { is_expected.to be_in_schema('test_1')
|
479
|
+
adapter.on_schema('test_3', recurse: :ignore) { is_expected.to be_in_schema('test_1')
|
427
480
|
} } }
|
428
481
|
|
429
482
|
is_expected.to be_in_schema(:default)
|
@@ -431,6 +484,72 @@ describe ChronoModel::Adapter do
|
|
431
484
|
end
|
432
485
|
end
|
433
486
|
|
487
|
+
context 'migration extensions' do
|
488
|
+
before :all do
|
489
|
+
adapter.create_table :meetings do |t|
|
490
|
+
t.string :name
|
491
|
+
t.tsrange :interval
|
492
|
+
end
|
493
|
+
end
|
494
|
+
|
495
|
+
after :all do
|
496
|
+
adapter.drop_table :meetings
|
497
|
+
end
|
498
|
+
|
499
|
+
describe '.add_temporal_indexes' do
|
500
|
+
before do
|
501
|
+
adapter.add_temporal_indexes :meetings, :interval
|
502
|
+
end
|
503
|
+
|
504
|
+
it { expect(adapter.indexes(:meetings).map(&:name)).to eq [
|
505
|
+
'index_meetings_temporal_on_interval',
|
506
|
+
'index_meetings_temporal_on_lower_interval',
|
507
|
+
'index_meetings_temporal_on_upper_interval'
|
508
|
+
] }
|
509
|
+
|
510
|
+
after do
|
511
|
+
adapter.remove_temporal_indexes :meetings, :interval
|
512
|
+
end
|
513
|
+
end
|
514
|
+
|
515
|
+
describe '.remove_temporal_indexes' do
|
516
|
+
before :all do
|
517
|
+
adapter.add_temporal_indexes :meetings, :interval
|
518
|
+
end
|
519
|
+
|
520
|
+
before do
|
521
|
+
adapter.remove_temporal_indexes :meetings, :interval
|
522
|
+
end
|
523
|
+
|
524
|
+
it { expect(adapter.indexes(:meetings)).to be_empty }
|
525
|
+
end
|
526
|
+
|
527
|
+
describe '.add_timeline_consistency_constraint' do
|
528
|
+
before do
|
529
|
+
adapter.add_timeline_consistency_constraint(:meetings, :interval)
|
530
|
+
end
|
531
|
+
|
532
|
+
it { expect(adapter.indexes(:meetings).map(&:name)).to eq [
|
533
|
+
'meetings_timeline_consistency'
|
534
|
+
] }
|
535
|
+
|
536
|
+
after do
|
537
|
+
adapter.remove_timeline_consistency_constraint(:meetings)
|
538
|
+
end
|
539
|
+
end
|
540
|
+
|
541
|
+
describe '.remove_timeline_consistency_constraint' do
|
542
|
+
before :all do
|
543
|
+
adapter.add_timeline_consistency_constraint :meetings, :interval
|
544
|
+
end
|
545
|
+
|
546
|
+
before do
|
547
|
+
adapter.remove_timeline_consistency_constraint(:meetings)
|
548
|
+
end
|
549
|
+
|
550
|
+
it { expect(adapter.indexes(:meetings)).to be_empty }
|
551
|
+
end
|
552
|
+
end
|
434
553
|
|
435
554
|
let(:current) { [ChronoModel::Adapter::TEMPORAL_SCHEMA, table].join('.') }
|
436
555
|
let(:history) { [ChronoModel::Adapter::HISTORY_SCHEMA, table].join('.') }
|
File without changes
|
@@ -1,6 +1,14 @@
|
|
1
|
+
##########################################################
|
2
|
+
### DEPRECATED: JSON operators are an hack and there is no
|
3
|
+
### reason not to use jsonb other than migrating your data
|
4
|
+
##########################################################
|
5
|
+
if ENV['HAVE_PLPYTHON'] == '1'
|
6
|
+
|
1
7
|
require 'spec_helper'
|
2
8
|
require 'support/helpers'
|
3
9
|
|
10
|
+
require 'chrono_model/json'
|
11
|
+
|
4
12
|
describe 'JSON equality operator' do
|
5
13
|
include ChronoTest::Helpers::Adapter
|
6
14
|
|
@@ -46,3 +54,6 @@ describe 'JSON equality operator' do
|
|
46
54
|
end
|
47
55
|
|
48
56
|
end
|
57
|
+
|
58
|
+
|
59
|
+
end
|
@@ -82,14 +82,16 @@ describe ChronoModel::TimeMachine do
|
|
82
82
|
it { is_expected.to include(Publication) }
|
83
83
|
end
|
84
84
|
|
85
|
-
describe '.
|
86
|
-
subject { ChronoModel
|
85
|
+
describe '.history_models' do
|
86
|
+
subject { ChronoModel.history_models }
|
87
87
|
|
88
88
|
it { is_expected.to eq(
|
89
|
+
'articles' => Article::History,
|
89
90
|
'foos' => Foo::History,
|
90
91
|
'defoos' => Defoo::History,
|
91
92
|
'bars' => Bar::History,
|
92
93
|
'elements' => Element::History,
|
94
|
+
'sections' => Section::History,
|
93
95
|
'sub_bars' => SubBar::History,
|
94
96
|
) }
|
95
97
|
end
|
@@ -210,9 +212,17 @@ describe ChronoModel::TimeMachine do
|
|
210
212
|
it { expect(Bar.as_of(bar.ts[2]).includes(foo: :sub_bars).first.foo.name).to eq 'new foo' }
|
211
213
|
it { expect(Bar.as_of(bar.ts[3]).includes(foo: :sub_bars).first.foo.name).to eq 'new foo' }
|
212
214
|
|
213
|
-
it { expect(Foo.as_of(foo.ts[0]).includes(bars
|
214
|
-
it { expect(Foo.as_of(foo.ts[1]).includes(bars
|
215
|
-
it { expect(Foo.as_of(foo.ts[2]).includes(bars
|
215
|
+
it { expect(Foo.as_of(foo.ts[0]).includes(:bars, :sub_bars).first.sub_bars.count).to eq 0 }
|
216
|
+
it { expect(Foo.as_of(foo.ts[1]).includes(:bars, :sub_bars).first.sub_bars.count).to eq 0 }
|
217
|
+
it { expect(Foo.as_of(foo.ts[2]).includes(:bars, :sub_bars).first.sub_bars.count).to eq 1 }
|
218
|
+
|
219
|
+
it { expect(Foo.as_of(foo.ts[0]).includes(:bars, :sub_bars).first.sub_bars.first).to be nil }
|
220
|
+
it { expect(Foo.as_of(foo.ts[1]).includes(:bars, :sub_bars).first.sub_bars.first).to be nil }
|
221
|
+
|
222
|
+
it { expect(Foo.as_of(subbar.ts[0]).includes(:bars, :sub_bars).first.sub_bars.first.name).to eq 'sub-bar' }
|
223
|
+
it { expect(Foo.as_of(subbar.ts[1]).includes(:bars, :sub_bars).first.sub_bars.first.name).to eq 'bar sub-bar' }
|
224
|
+
it { expect(Foo.as_of(subbar.ts[2]).includes(:bars, :sub_bars).first.sub_bars.first.name).to eq 'sub-bar sub-bar' }
|
225
|
+
it { expect(Foo.as_of(subbar.ts[3]).includes(:bars, :sub_bars).first.sub_bars.first.name).to eq 'new sub-bar' }
|
216
226
|
end
|
217
227
|
|
218
228
|
it 'doesn\'t raise RecordNotFound when no history records are found' do
|
File without changes
|
data/spec/config.travis.yml
CHANGED
data/spec/config.yml.example
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: chrono_model
|
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
|
- Marcello Barnaba
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2019-04-
|
12
|
+
date: 2019-04-08 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activerecord
|
@@ -218,13 +218,30 @@ files:
|
|
218
218
|
- lib/active_record/tasks/chronomodel_database_tasks.rb
|
219
219
|
- lib/chrono_model.rb
|
220
220
|
- lib/chrono_model/adapter.rb
|
221
|
+
- lib/chrono_model/adapter/ddl.rb
|
222
|
+
- lib/chrono_model/adapter/indexes.rb
|
223
|
+
- lib/chrono_model/adapter/migrations.rb
|
224
|
+
- lib/chrono_model/adapter/tsrange.rb
|
225
|
+
- lib/chrono_model/adapter/upgrade.rb
|
226
|
+
- lib/chrono_model/conversions.rb
|
227
|
+
- lib/chrono_model/json.rb
|
221
228
|
- lib/chrono_model/patches.rb
|
229
|
+
- lib/chrono_model/patches/as_of_time_holder.rb
|
230
|
+
- lib/chrono_model/patches/as_of_time_relation.rb
|
231
|
+
- lib/chrono_model/patches/association.rb
|
232
|
+
- lib/chrono_model/patches/db_console.rb
|
233
|
+
- lib/chrono_model/patches/join_node.rb
|
234
|
+
- lib/chrono_model/patches/preloader.rb
|
235
|
+
- lib/chrono_model/patches/relation.rb
|
222
236
|
- lib/chrono_model/railtie.rb
|
223
237
|
- lib/chrono_model/time_gate.rb
|
224
238
|
- lib/chrono_model/time_machine.rb
|
225
|
-
- lib/chrono_model/
|
239
|
+
- lib/chrono_model/time_machine/history_model.rb
|
240
|
+
- lib/chrono_model/time_machine/time_query.rb
|
241
|
+
- lib/chrono_model/time_machine/timeline.rb
|
242
|
+
- lib/chrono_model/utilities.rb
|
226
243
|
- lib/chrono_model/version.rb
|
227
|
-
- spec/
|
244
|
+
- spec/aruba/dbconsole_spec.rb
|
228
245
|
- spec/aruba/fixtures/database_with_default_username_and_password.yml
|
229
246
|
- spec/aruba/fixtures/database_without_username_and_password.yml
|
230
247
|
- spec/aruba/fixtures/empty_structure.sql
|
@@ -235,9 +252,14 @@ files:
|
|
235
252
|
- spec/aruba/fixtures/railsapp/config/environments/development.rb
|
236
253
|
- spec/aruba/migrations_spec.rb
|
237
254
|
- spec/aruba/rake_task_spec.rb
|
255
|
+
- spec/chrono_model/adapter/counter_cache_race_spec.rb
|
256
|
+
- spec/chrono_model/adapter_spec.rb
|
257
|
+
- spec/chrono_model/conversions_spec.rb
|
258
|
+
- spec/chrono_model/json_ops_spec.rb
|
259
|
+
- spec/chrono_model/time_machine_spec.rb
|
260
|
+
- spec/chrono_model/time_query_spec.rb
|
238
261
|
- spec/config.travis.yml
|
239
262
|
- spec/config.yml.example
|
240
|
-
- spec/json_ops_spec.rb
|
241
263
|
- spec/spec_helper.rb
|
242
264
|
- spec/support/aruba.rb
|
243
265
|
- spec/support/connection.rb
|
@@ -248,9 +270,6 @@ files:
|
|
248
270
|
- spec/support/matchers/index.rb
|
249
271
|
- spec/support/matchers/schema.rb
|
250
272
|
- spec/support/matchers/table.rb
|
251
|
-
- spec/time_machine_spec.rb
|
252
|
-
- spec/time_query_spec.rb
|
253
|
-
- spec/utils_spec.rb
|
254
273
|
- sql/json_ops.sql
|
255
274
|
- sql/uninstall-json_ops.sql
|
256
275
|
homepage: https://github.com/ifad/chronomodel
|
@@ -272,12 +291,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
272
291
|
version: '0'
|
273
292
|
requirements: []
|
274
293
|
rubyforge_project:
|
275
|
-
rubygems_version: 2.
|
294
|
+
rubygems_version: 2.7.6.2
|
276
295
|
signing_key:
|
277
296
|
specification_version: 4
|
278
297
|
summary: Temporal extensions (SCD Type II) for Active Record
|
279
298
|
test_files:
|
280
|
-
- spec/
|
299
|
+
- spec/aruba/dbconsole_spec.rb
|
281
300
|
- spec/aruba/fixtures/database_with_default_username_and_password.yml
|
282
301
|
- spec/aruba/fixtures/database_without_username_and_password.yml
|
283
302
|
- spec/aruba/fixtures/empty_structure.sql
|
@@ -288,9 +307,14 @@ test_files:
|
|
288
307
|
- spec/aruba/fixtures/railsapp/config/environments/development.rb
|
289
308
|
- spec/aruba/migrations_spec.rb
|
290
309
|
- spec/aruba/rake_task_spec.rb
|
310
|
+
- spec/chrono_model/adapter/counter_cache_race_spec.rb
|
311
|
+
- spec/chrono_model/adapter_spec.rb
|
312
|
+
- spec/chrono_model/conversions_spec.rb
|
313
|
+
- spec/chrono_model/json_ops_spec.rb
|
314
|
+
- spec/chrono_model/time_machine_spec.rb
|
315
|
+
- spec/chrono_model/time_query_spec.rb
|
291
316
|
- spec/config.travis.yml
|
292
317
|
- spec/config.yml.example
|
293
|
-
- spec/json_ops_spec.rb
|
294
318
|
- spec/spec_helper.rb
|
295
319
|
- spec/support/aruba.rb
|
296
320
|
- spec/support/connection.rb
|
@@ -301,6 +325,3 @@ test_files:
|
|
301
325
|
- spec/support/matchers/index.rb
|
302
326
|
- spec/support/matchers/schema.rb
|
303
327
|
- spec/support/matchers/table.rb
|
304
|
-
- spec/time_machine_spec.rb
|
305
|
-
- spec/time_query_spec.rb
|
306
|
-
- spec/utils_spec.rb
|
data/lib/chrono_model/utils.rb
DELETED
@@ -1,117 +0,0 @@
|
|
1
|
-
module ChronoModel
|
2
|
-
|
3
|
-
module Conversions
|
4
|
-
extend self
|
5
|
-
|
6
|
-
ISO_DATETIME = /\A(\d{4})-(\d\d)-(\d\d) (\d\d):(\d\d):(\d\d)(?:\.(\d+))?\z/
|
7
|
-
|
8
|
-
def string_to_utc_time(string)
|
9
|
-
if string =~ ISO_DATETIME
|
10
|
-
usec = $7.nil? ? '000000' : $7.ljust(6, '0') # .1 is .100000, not .000001
|
11
|
-
Time.utc $1.to_i, $2.to_i, $3.to_i, $4.to_i, $5.to_i, $6.to_i, usec.to_i
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
def time_to_utc_string(time)
|
16
|
-
[time.to_s(:db), sprintf('%06d', time.usec)].join '.'
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
module Json
|
21
|
-
extend self
|
22
|
-
|
23
|
-
def create
|
24
|
-
adapter.execute 'CREATE OR REPLACE LANGUAGE plpythonu'
|
25
|
-
adapter.execute File.read(sql 'json_ops.sql')
|
26
|
-
end
|
27
|
-
|
28
|
-
def drop
|
29
|
-
adapter.execute File.read(sql 'uninstall-json_ops.sql')
|
30
|
-
adapter.execute 'DROP LANGUAGE IF EXISTS plpythonu'
|
31
|
-
end
|
32
|
-
|
33
|
-
private
|
34
|
-
def sql(file)
|
35
|
-
File.dirname(__FILE__) + '/../../sql/' + file
|
36
|
-
end
|
37
|
-
|
38
|
-
def adapter
|
39
|
-
ActiveRecord::Base.connection
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
module Utilities
|
44
|
-
# Amends the given history item setting a different period.
|
45
|
-
# Useful when migrating from legacy systems.
|
46
|
-
#
|
47
|
-
def amend_period!(hid, from, to)
|
48
|
-
unless [from, to].any? {|ts| ts.respond_to?(:zone) && ts.zone == 'UTC'}
|
49
|
-
raise 'Can amend history only with UTC timestamps'
|
50
|
-
end
|
51
|
-
|
52
|
-
connection.execute %[
|
53
|
-
UPDATE #{quoted_table_name}
|
54
|
-
SET "validity" = tsrange(#{connection.quote(from)}, #{connection.quote(to)}),
|
55
|
-
"recorded_at" = #{connection.quote(from)}
|
56
|
-
WHERE "hid" = #{hid.to_i}
|
57
|
-
]
|
58
|
-
end
|
59
|
-
|
60
|
-
# Returns true if this model is backed by a temporal table,
|
61
|
-
# false otherwise.
|
62
|
-
#
|
63
|
-
def chrono?
|
64
|
-
connection.is_chrono?(table_name)
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
ActiveRecord::Base.extend Utilities
|
69
|
-
|
70
|
-
module Migrate
|
71
|
-
extend self
|
72
|
-
|
73
|
-
def upgrade_indexes!(base = ActiveRecord::Base)
|
74
|
-
use base
|
75
|
-
|
76
|
-
db.on_schema(Adapter::HISTORY_SCHEMA) do
|
77
|
-
db.tables.each do |table|
|
78
|
-
if db.is_chrono?(table)
|
79
|
-
upgrade_indexes_for(table)
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
private
|
86
|
-
attr_reader :db
|
87
|
-
|
88
|
-
def use(ar)
|
89
|
-
@db = ar.connection
|
90
|
-
end
|
91
|
-
|
92
|
-
def upgrade_indexes_for(table_name)
|
93
|
-
upgradeable =
|
94
|
-
%r{_snapshot$|_valid_(?:from|to)$|_recorded_at$|_instance_(?:update|history)$}
|
95
|
-
|
96
|
-
indexes_sql = %[
|
97
|
-
SELECT DISTINCT i.relname
|
98
|
-
FROM pg_class t
|
99
|
-
INNER JOIN pg_index d ON t.oid = d.indrelid
|
100
|
-
INNER JOIN pg_class i ON d.indexrelid = i.oid
|
101
|
-
WHERE i.relkind = 'i'
|
102
|
-
AND d.indisprimary = 'f'
|
103
|
-
AND t.relname = '#{table_name}'
|
104
|
-
AND i.relnamespace IN (SELECT oid FROM pg_namespace WHERE nspname = ANY(current_schemas(false)) )
|
105
|
-
]
|
106
|
-
|
107
|
-
db.select_values(indexes_sql).each do |idx|
|
108
|
-
if idx =~ upgradeable
|
109
|
-
db.execute "DROP INDEX #{idx}"
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
|
-
db.send(:chrono_create_history_indexes_for, table_name)
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
117
|
-
end
|