Module: TemporalTables::TemporalAdapter

Defined in:
lib/temporal_tables/temporal_adapter.rb

Instance Method Summary collapse

Instance Method Details

#add_column(table_name, column_name, type, options = {}) ⇒ Object



73
74
75
76
77
78
79
80
# File 'lib/temporal_tables/temporal_adapter.rb', line 73

def add_column(table_name, column_name, type, options = {})
  super table_name, column_name, type, options

  if table_exists?(temporal_name(table_name))
    super temporal_name(table_name), column_name, type, options
    create_temporal_triggers table_name
  end
end

#add_index(table_name, column_name, options = {}) ⇒ Object



109
110
111
112
113
114
115
116
117
118
# File 'lib/temporal_tables/temporal_adapter.rb', line 109

def add_index(table_name, column_name, options = {})
  super table_name, column_name, options

  if table_exists?(temporal_name(table_name))
    column_names = Array.wrap(column_name)
    idx_name = temporal_index_name(options[:name] || index_name(table_name, :column => column_names))

    super temporal_name(table_name), column_name, options.except(:unique).merge(name: idx_name)
  end
end

#add_temporal_table(table_name, options = {}) ⇒ Object



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/temporal_tables/temporal_adapter.rb', line 23

def add_temporal_table(table_name, options = {})
  create_table temporal_name(table_name), options.merge(id: false, primary_key: "history_id", temporal_bypass: true) do |t|
    t.integer   :id
    t.datetime :eff_from, :null => false, limit: 6
    t.datetime :eff_to,   :null => false, limit: 6, :default => "9999-12-31"

    for c in columns(table_name)
      t.send c.type, c.name, :limit => c.limit
    end
  end

  if TemporalTables.add_updated_by_field && !column_exists?(table_name, :updated_by)
    change_table table_name do |t|
      t.column :updated_by, TemporalTables.updated_by_type
    end
  end

  add_index temporal_name(table_name), [:id, :eff_to]
  create_temporal_triggers table_name
  create_temporal_indexes table_name
end

#change_column(table_name, column_name, type, options = {}) ⇒ Object



91
92
93
94
95
96
97
98
# File 'lib/temporal_tables/temporal_adapter.rb', line 91

def change_column(table_name, column_name, type, options = {})
  super table_name, column_name, type, options

  if table_exists?(temporal_name(table_name))
    super temporal_name(table_name), column_name, type, options
    # Don't need to update triggers here...
  end
end

#create_table(table_name, options = {}, &block) ⇒ Object



3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# File 'lib/temporal_tables/temporal_adapter.rb', line 3

def create_table(table_name, options = {}, &block)
  if options[:temporal_bypass]
    super table_name, options, &block
  else
    skip_table = TemporalTables.skipped_temporal_tables.include?(table_name.to_sym) || table_name.to_s =~ /_h$/

    super table_name, options do |t|
      block.call t

      if TemporalTables.add_updated_by_field && !skip_table
        t.column :updated_by, TemporalTables.updated_by_type
      end
    end

    if options[:temporal] || (TemporalTables.create_by_default && !skip_table)
      add_temporal_table table_name, options
    end
  end
end

#create_temporal_indexes(table_name) ⇒ Object



130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/temporal_tables/temporal_adapter.rb', line 130

def create_temporal_indexes(table_name)
  indexes = ActiveRecord::Base.connection.indexes(table_name)

  indexes.each do |index|
    index_name = temporal_index_name(index.name)

    unless temporal_index_exists?(table_name, index_name)
      add_index(
        temporal_name(table_name),
        index.columns, {
          # exclude unique constraints for temporal tables
          :name   => index_name,
          :length => index.lengths,
          :order  => index.orders
      })
    end
  end
end

#create_temporal_triggers(table_name) ⇒ Object

Raises:

  • (NotImplementedError)


153
154
155
# File 'lib/temporal_tables/temporal_adapter.rb', line 153

def create_temporal_triggers(table_name)
  raise NotImplementedError, "create_temporal_triggers is not implemented"
end

#drop_table(table_name, options = {}) ⇒ Object



52
53
54
55
56
57
58
# File 'lib/temporal_tables/temporal_adapter.rb', line 52

def drop_table(table_name, options = {})
  super table_name, options

  if table_exists?(temporal_name(table_name))
    super temporal_name(table_name), options
  end
end

#drop_temporal_triggers(table_name) ⇒ Object

Raises:

  • (NotImplementedError)


157
158
159
# File 'lib/temporal_tables/temporal_adapter.rb', line 157

def drop_temporal_triggers(table_name)
  raise NotImplementedError, "drop_temporal_triggers is not implemented"
end

#remove_column(table_name, *column_names) ⇒ Object



82
83
84
85
86
87
88
89
# File 'lib/temporal_tables/temporal_adapter.rb', line 82

def remove_column(table_name, *column_names)
  super table_name, *column_names

  if table_exists?(temporal_name(table_name))
    super temporal_name(table_name), *column_names
    create_temporal_triggers table_name
  end
end

#remove_index(table_name, options = {}) ⇒ Object



120
121
122
123
124
125
126
127
128
# File 'lib/temporal_tables/temporal_adapter.rb', line 120

def remove_index(table_name, options = {})
  super table_name, options

  if table_exists?(temporal_name(table_name))
    idx_name = temporal_index_name(index_name(table_name, options))

    super temporal_name(table_name), :name => idx_name
  end
end

#remove_temporal_table(table_name) ⇒ Object



45
46
47
48
49
50
# File 'lib/temporal_tables/temporal_adapter.rb', line 45

def remove_temporal_table(table_name)
  if table_exists?(temporal_name(table_name))
    drop_temporal_triggers table_name
    drop_table_without_temporal temporal_name(table_name)
  end
end

#rename_column(table_name, column_name, new_column_name) ⇒ Object



100
101
102
103
104
105
106
107
# File 'lib/temporal_tables/temporal_adapter.rb', line 100

def rename_column(table_name, column_name, new_column_name)
  super table_name, column_name, new_column_name

  if table_exists?(temporal_name(table_name))
    super temporal_name(table_name), column_name, new_column_name
    create_temporal_triggers table_name
  end
end

#rename_table(name, new_name) ⇒ Object



60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/temporal_tables/temporal_adapter.rb', line 60

def rename_table(name, new_name)
  if table_exists?(temporal_name(name))
    drop_temporal_triggers name
  end

  super name, new_name

  if table_exists?(temporal_name(name))
    super temporal_name(name), temporal_name(new_name)
    create_temporal_triggers new_name
  end
end

#temporal_index_exists?(table_name, index_name) ⇒ Boolean

Returns:

  • (Boolean)


166
167
168
169
170
171
172
173
174
# File 'lib/temporal_tables/temporal_adapter.rb', line 166

def temporal_index_exists?(table_name, index_name)
  raise "Rails version not supported" unless Rails::VERSION::MAJOR == 5
  case Rails::VERSION::MINOR
  when 0
    index_name_exists?(temporal_name(table_name), index_name, false)
  else
    index_name_exists?(temporal_name(table_name), index_name)
  end
end

#temporal_index_name(index_name) ⇒ Object

It’s important not to increase the length of the returned string.



162
163
164
# File 'lib/temporal_tables/temporal_adapter.rb', line 162

def temporal_index_name(index_name)
  index_name.to_s.sub(/^index/, "ind_h").sub(/_ix(\d+)$/, '_hi\1')
end

#temporal_name(table_name) ⇒ Object



149
150
151
# File 'lib/temporal_tables/temporal_adapter.rb', line 149

def temporal_name(table_name)
  "#{table_name}_h"
end