Class: Code0::ZeroTrack::Database::Partitioning::TimePartition

Inherits:
Object
  • Object
show all
Includes:
Comparable
Defined in:
lib/code0/zero_track/database/partitioning/time_partition.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(model, from, to, partition_name:) ⇒ TimePartition

Returns a new instance of TimePartition.



25
26
27
28
29
30
# File 'lib/code0/zero_track/database/partitioning/time_partition.rb', line 25

def initialize(model, from, to, partition_name:)
  @model = model
  @from = date_or_nil(from)
  @to = date_or_nil(to)
  @partition_name = partition_name
end

Instance Attribute Details

#fromObject (readonly)

Returns the value of attribute from.



23
24
25
# File 'lib/code0/zero_track/database/partitioning/time_partition.rb', line 23

def from
  @from
end

#modelObject (readonly)

Returns the value of attribute model.



23
24
25
# File 'lib/code0/zero_track/database/partitioning/time_partition.rb', line 23

def model
  @model
end

#partition_nameObject (readonly)

Returns the value of attribute partition_name.



23
24
25
# File 'lib/code0/zero_track/database/partitioning/time_partition.rb', line 23

def partition_name
  @partition_name
end

#toObject (readonly)

Returns the value of attribute to.



23
24
25
# File 'lib/code0/zero_track/database/partitioning/time_partition.rb', line 23

def to
  @to
end

Class Method Details

.from_sql(table, partition_name, definition) ⇒ Object

Raises:

  • (ArgumentError)


10
11
12
13
14
15
16
17
18
19
20
21
# File 'lib/code0/zero_track/database/partitioning/time_partition.rb', line 10

def self.from_sql(table, partition_name, definition)
  matches = definition.match(/FOR VALUES FROM \('?(?<from>[^)']+)'?\) TO \('?(?<to>[^)']+)'?\)/)

  raise ArgumentError, "Unknown partition definition: #{definition}" unless matches

  raise NotImplementedError, 'MAXVALUE as upper bound is not supported' if matches[:to] == 'MAXVALUE'

  from = matches[:from] == 'MINVALUE' ? nil : matches[:from]
  to = matches[:to]

  new(table, from, to, partition_name: partition_name)
end

Instance Method Details

#<=>(other) ⇒ Object



41
42
43
44
45
# File 'lib/code0/zero_track/database/partitioning/time_partition.rb', line 41

def <=>(other)
  return if model != other.model

  partition_name <=> other.partition_name
end

#==(other) ⇒ Object Also known as: eql?



32
33
34
# File 'lib/code0/zero_track/database/partitioning/time_partition.rb', line 32

def ==(other)
  model == other.model && partition_name == other.partition_name && from == other.from && to == other.to
end

#fully_qualified_partition(connection) ⇒ Object



72
73
74
75
76
77
78
79
80
# File 'lib/code0/zero_track/database/partitioning/time_partition.rb', line 72

def fully_qualified_partition(connection)
  format(
    '%<schema>s.%<partition>s',
    schema: connection.quote_table_name(
      Rails.application.config.zero_track.db_partitioning.dynamic_partition_schema
    ),
    partition: connection.quote_table_name(partition_name)
  )
end

#hashObject



37
38
39
# File 'lib/code0/zero_track/database/partitioning/time_partition.rb', line 37

def hash
  [model, partition_name, from, to].hash
end

#to_attach_sql(connection) ⇒ Object



54
55
56
57
58
59
60
61
62
63
# File 'lib/code0/zero_track/database/partitioning/time_partition.rb', line 54

def to_attach_sql(connection)
  from_sql = from ? connection.quote(from.to_date.iso8601) : 'MINVALUE'
  to_sql = connection.quote(to.to_date.iso8601)

  <<~SQL.squish
    ALTER TABLE #{connection.quote_table_name(model.table_name)}
    ATTACH PARTITION #{fully_qualified_partition(connection)}
    FOR VALUES FROM (#{from_sql}) TO (#{to_sql})
  SQL
end

#to_create_sql(connection) ⇒ Object



47
48
49
50
51
52
# File 'lib/code0/zero_track/database/partitioning/time_partition.rb', line 47

def to_create_sql(connection)
  <<~SQL.squish
    CREATE TABLE IF NOT EXISTS #{fully_qualified_partition(connection)}
    (LIKE #{connection.quote_table_name(model.table_name)} INCLUDING ALL)
  SQL
end

#to_detach_sql(connection) ⇒ Object



65
66
67
68
69
70
# File 'lib/code0/zero_track/database/partitioning/time_partition.rb', line 65

def to_detach_sql(connection)
  <<~SQL.squish
    ALTER TABLE #{connection.quote_table_name(model.table_name)}
    DETACH PARTITION #{fully_qualified_partition(connection)}
  SQL
end