sliding_partition 0.3.0 → 0.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 60a930fe3a691eb3e9ddd4dd74d6719a264232d5
4
- data.tar.gz: 576af132477c22d38afc7948df0d170a0c95a36a
3
+ metadata.gz: 2bf2b1b4f2a76d444d0238530ae8eb2be574c566
4
+ data.tar.gz: 97ae79b822ca5e4212d53e18e90976d78029e1aa
5
5
  SHA512:
6
- metadata.gz: 7f98cde8a0c07ba0e749e6449f11cd460a752e9ff0ea77f5fdfe39f8446ad601eadabf3408388111b0cc3db153a968cad9224071cac5e2766df6575c9dfb3f53
7
- data.tar.gz: 03e0310746fcdcd74807f6fbaad099d9f8f66c50dfafde2d92f1f5fa84a499cb218b749556bea666f395b4fff65e91c7233e59ffdda17bd521c2af8777c49ddb
6
+ metadata.gz: 6c076eee13cd511d8f74788e7462cf05ef7835ad92d943d0252d7ddb4b2d09f1cf8d3e63e118f958fa76461ed4e883873a2e56416d8e64b18fe52186e1bcf224
7
+ data.tar.gz: 250ce476eed36ef530ef28ed3af7d0084ef3c2c95acfce42d7a87647caf8b623fb98ee2c7a238d668abf78fd936ea4687a1846340388b06372167559d77eb0c1
@@ -23,6 +23,10 @@ module SlidingPartition
23
23
  parititions.values.each { |p| p.migrate! }
24
24
  end
25
25
 
26
+ def self.final_copy!
27
+ parititions.values.each { |p| p.final_copy! }
28
+ end
29
+
26
30
  def self.parititions
27
31
  @@parititions ||= {}
28
32
  end
@@ -23,14 +23,18 @@ module SlidingPartition
23
23
  PartitionDDLChanger.new(self, at).rotate!
24
24
  end
25
25
 
26
- def migrate!(at: Time.now)
27
- PartitionDDLChanger.new(self, at).migrate!
26
+ def migrate!(at: Time.now, quiet: false)
27
+ PartitionDDLChanger.new(self, at, quiet: quiet).migrate!
28
28
  end
29
29
 
30
30
  def partitions(at: Time.now)
31
31
  TableCollection.new(definition: self, at_time: at)
32
32
  end
33
33
 
34
+ def final_copy!(at: Time.now, quiet: false)
35
+ PartitionDDLChanger.new(self, at, quiet: quiet).migrate!
36
+ end
37
+
34
38
  def inherited_table_name
35
39
  @inherited_table_name ||= model.table_name
36
40
  end
@@ -12,7 +12,7 @@ module SlidingPartition
12
12
  end
13
13
 
14
14
  def self.version
15
- "0.3.0"
15
+ "0.5.0"
16
16
  end
17
17
 
18
18
  def self.version_label
@@ -1,23 +1,27 @@
1
+ require "sliding_partition/util"
1
2
 
2
3
  module SlidingPartition
3
4
  class PartitionDDLChanger
4
5
  extend Forwardable
5
6
 
7
+ include SlidingPartition::Util
8
+
6
9
  attr_reader :definition, :time, :partitions
7
10
 
8
11
  delegate %i[ inherited_table_name time_column suffix
9
12
  partition_interval retention_interval ] => :definition
10
13
 
11
- def initialize(definition, time)
14
+ def initialize(definition, time, quiet: false)
12
15
  @definition, @time = definition, time
13
16
  @partitions = @definition.partitions(at: time)
17
+ @quiet = quiet
14
18
  end
15
19
 
16
20
  def setup!
17
21
  connection.transaction do
18
- create_tables!
19
- update_trigger_function!
20
- create_trigger!
22
+ say_with_time("Creating tables") { create_tables! }
23
+ say_with_time("Updating trigger function") { update_trigger_function! }
24
+ say_with_time("Creating trigger") { create_trigger! }
21
25
  end
22
26
  end
23
27
 
@@ -31,14 +35,21 @@ module SlidingPartition
31
35
 
32
36
  def migrate!
33
37
  connection.transaction do
34
- clone_new_table!
35
- update_trigger_function!
36
- swap_tables!
37
- setup!
38
- migrate_data!(from: retired_table, to: parent_table)
38
+ say_with_time("Cloning table") { clone_new_table! }
39
+ say_with_time("Creating #{partitions.tables.size} partition tables") { create_tables! }
40
+ say_with_time("Migrating data") { migrate_data!(from: parent_table, to: new_table) }
41
+ say_with_time("Swapping retired & new tables") { swap_tables! }
39
42
  end
40
43
  end
41
44
 
45
+ def final_copy!
46
+ connection.execute(<<-SQL)
47
+ INSERT INTO #{parent_table} (
48
+ SELECT * FROM #{retired_table} WHERE id NOT IN (SELECT id FROM #{parent_table})
49
+ )
50
+ SQL
51
+ end
52
+
42
53
  def create_tables!
43
54
  partitions.each do |partition|
44
55
  create_partition_table(partition) unless partition_table_exists?(partition)
@@ -64,19 +75,14 @@ module SlidingPartition
64
75
  ALTER TABLE #{parent_table} RENAME TO #{retired_table};
65
76
  ALTER TABLE #{new_table} RENAME TO #{parent_table};
66
77
  SQL
78
+ update_trigger_function!
67
79
  create_trigger!
68
80
  end
69
81
 
70
82
  def migrate_data!(from:, to:)
71
- partitions.each do |partition|
72
- connection.execute <<-SQL
73
- INSERT INTO #{to} (
74
- SELECT * FROM #{from}
75
- WHERE #{time_column} >= TIMESTAMP '#{partition.timestamp_floor.to_s(:db)}'
76
- AND #{time_column} < TIMESTAMP '#{partition.timestamp_ceiling.to_s(:db)}'
77
- );
78
- SQL
79
- end
83
+ connection.execute <<-SQL
84
+ INSERT INTO #{to} ( SELECT * FROM #{from} )
85
+ SQL
80
86
  end
81
87
 
82
88
  protected
@@ -16,10 +16,10 @@ module SlidingPartition
16
16
  end
17
17
 
18
18
  def tables
19
- first_ts = time - retention_interval
20
- last_ts = time + partition_interval
21
- (first_ts.to_i...last_ts.to_i).step(partition_interval).map do |partition_time|
22
- PartitionTable.new(for_time: Time.at(partition_time), definition: definition)
19
+ @tables ||= begin
20
+ (first_timestamp.to_i...last_timestamp.to_i).step(partition_interval).map do |partition_time|
21
+ PartitionTable.new(for_time: Time.at(partition_time), definition: definition)
22
+ end
23
23
  end
24
24
  end
25
25
 
@@ -27,9 +27,24 @@ module SlidingPartition
27
27
  tables.each(&block)
28
28
  end
29
29
 
30
+ def first_timestamp
31
+ @first_timestamp ||= if retention_interval == :forever
32
+ earliest_record_timestamp
33
+ else
34
+ time - retention_interval
35
+ end
36
+ end
37
+
38
+ def last_timestamp
39
+ time + partition_interval
40
+ end
41
+
30
42
  def first_partition_timestamp
31
43
  tables.first.timestamp_floor
32
44
  end
33
45
 
46
+ def earliest_record_timestamp
47
+ definition.model.order("#{time_column} ASC").limit(1).first[time_column]
48
+ end
34
49
  end
35
50
  end
@@ -0,0 +1,18 @@
1
+
2
+ module SlidingPartition
3
+ module Util
4
+
5
+ def say_with_time(message)
6
+ say(message)
7
+ result = nil
8
+ time = Benchmark.measure { yield }
9
+ say "%.4fs" % time.real, :subitem
10
+ result
11
+ end
12
+
13
+ def say(message, subitem=false)
14
+ puts "#{subitem ? " ->" : "--"} #{message}" unless @quiet
15
+ end
16
+
17
+ end
18
+ end
@@ -12,4 +12,9 @@ namespace :partition do
12
12
  task :migrate => :environment do
13
13
  SlidingPartition.migrate!
14
14
  end
15
+
16
+ desc "Copy missing data"
17
+ task :final_copy => :environment do
18
+ SlidingPartition.final_copy!
19
+ end
15
20
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sliding_partition
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paul Sadauskas
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-03-23 00:00:00.000000000 Z
11
+ date: 2017-04-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -259,6 +259,7 @@ files:
259
259
  - lib/sliding_partition/partition_table.rb
260
260
  - lib/sliding_partition/railtie.rb
261
261
  - lib/sliding_partition/table_collection.rb
262
+ - lib/sliding_partition/util.rb
262
263
  - lib/tasks/sliding_partition_tasks.rake
263
264
  homepage: https://github.com/paul/sliding_partition
264
265
  licenses: