sliding_partition 0.3.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
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: