Module: Switchman::ActiveRecord::PostgreSQLAdapter

Defined in:
lib/switchman/active_record/postgresql_adapter.rb

Instance Method Summary collapse

Instance Method Details

#add_index_options(_table_name, _column_name) ⇒ Object



103
104
105
106
107
# File 'lib/switchman/active_record/postgresql_adapter.rb', line 103

def add_index_options(_table_name, _column_name, **)
  index, algorithm, if_not_exists = super
  algorithm = nil if DatabaseServer.creating_new_shard && algorithm == "CONCURRENTLY"
  [index, algorithm, if_not_exists]
end

#columnsObject



131
132
133
# File 'lib/switchman/active_record/postgresql_adapter.rb', line 131

def columns(*)
  with_local_table_name(false) { super }
end

#create_database(name, options = {}) ⇒ Object

copy/paste; use quote_local_table_name



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/switchman/active_record/postgresql_adapter.rb', line 7

def create_database(name, options = {})
  options = { encoding: "utf8" }.merge!(options.symbolize_keys)

  option_string = options.sum("") do |key, value|
    case key
    when :owner
      " OWNER = \"#{value}\""
    when :template
      " TEMPLATE = \"#{value}\""
    when :encoding
      " ENCODING = '#{value}'"
    when :collation
      " LC_COLLATE = '#{value}'"
    when :ctype
      " LC_CTYPE = '#{value}'"
    when :tablespace
      " TABLESPACE = \"#{value}\""
    when :connection_limit
      " CONNECTION LIMIT = #{value}"
    else
      ""
    end
  end

  execute "CREATE DATABASE #{quote_local_table_name(name)}#{option_string}"
end

#current_schemasObject



39
40
41
# File 'lib/switchman/active_record/postgresql_adapter.rb', line 39

def current_schemas
  select_values("SELECT * FROM unnest(current_schemas(false))")
end

#drop_database(name) ⇒ Object

copy/paste; use quote_local_table_name



35
36
37
# File 'lib/switchman/active_record/postgresql_adapter.rb', line 35

def drop_database(name) # :nodoc:
  execute "DROP DATABASE IF EXISTS #{quote_local_table_name(name)}"
end

#extract_schema_qualified_name(string) ⇒ Object



43
44
45
46
47
# File 'lib/switchman/active_record/postgresql_adapter.rb', line 43

def extract_schema_qualified_name(string)
  name = ::ActiveRecord::ConnectionAdapters::PostgreSQL::Utils.extract_schema_qualified_name(string.to_s)
  name.instance_variable_set(:@schema, shard.name) if string && !name.schema
  [name.schema, name.identifier]
end

#foreign_keys(table_name) ⇒ Object



68
69
70
71
72
73
74
# File 'lib/switchman/active_record/postgresql_adapter.rb', line 68

def foreign_keys(table_name)
  super.each do |fk|
    to_table_qualified_name =
      ::ActiveRecord::ConnectionAdapters::PostgreSQL::Utils.extract_schema_qualified_name(fk.to_table)
    fk.to_table = to_table_qualified_name.identifier if to_table_qualified_name.schema == shard.name
  end
end

#quote_local_table_name(name) ⇒ Object



76
77
78
79
80
81
# File 'lib/switchman/active_record/postgresql_adapter.rb', line 76

def quote_local_table_name(name)
  # postgres quotes tables and columns the same; just pass through
  # (differs from quote_table_name_with_shard below by no logic to
  # explicitly qualify the table)
  quote_column_name(name)
end

#quote_table_name(name) ⇒ Object



83
84
85
86
87
88
89
# File 'lib/switchman/active_record/postgresql_adapter.rb', line 83

def quote_table_name(name)
  return quote_local_table_name(name) if @use_local_table_name

  name = ::ActiveRecord::ConnectionAdapters::PostgreSQL::Utils.extract_schema_qualified_name(name.to_s)
  name.instance_variable_set(:@schema, shard.name) unless name.schema
  name.quoted
end

#quoted_scope(name = nil, type: nil) ⇒ Object

significant change: use the shard name if no explicit schema



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/switchman/active_record/postgresql_adapter.rb', line 50

def quoted_scope(name = nil, type: nil)
  schema, name = extract_schema_qualified_name(name)
  type =
    case type # rubocop:disable Style/HashLikeCase
    when "BASE TABLE"
      "'r','p'"
    when "VIEW"
      "'v','m'"
    when "FOREIGN TABLE"
      "'f'"
    end
  scope = {}
  scope[:schema] = quote(schema || shard.name)
  scope[:name] = quote(name) if name
  scope[:type] = type if type
  scope
end

#rename_index(table_name, old_name, new_name) ⇒ Object



125
126
127
128
129
# File 'lib/switchman/active_record/postgresql_adapter.rb', line 125

def rename_index(table_name, old_name, new_name)
  validate_index_length!(table_name, new_name)

  execute "ALTER INDEX #{quote_table_name(old_name)} RENAME TO #{quote_local_table_name(new_name)}"
end

#rename_table(table_name, new_name) ⇒ Object



109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/switchman/active_record/postgresql_adapter.rb', line 109

def rename_table(table_name, new_name)
  clear_cache!
  execute "ALTER TABLE #{quote_table_name(table_name)} RENAME TO #{quote_local_table_name(new_name)}"
  pk, seq = pk_and_sequence_for(new_name)
  if pk
    idx = "#{table_name}_pkey"
    new_idx = "#{new_name}_pkey"
    execute "ALTER INDEX #{quote_table_name(idx)} RENAME TO #{quote_local_table_name(new_idx)}"
    if seq && seq.identifier == "#{table_name}_#{pk}_seq"
      new_seq = "#{new_name}_#{pk}_seq"
      execute "ALTER TABLE #{seq.quoted} RENAME TO #{quote_local_table_name(new_seq)}"
    end
  end
  rename_table_indexes(table_name, new_name)
end

#with_global_table_name(&block) ⇒ Object



91
92
93
# File 'lib/switchman/active_record/postgresql_adapter.rb', line 91

def with_global_table_name(&block)
  with_local_table_name(false, &block)
end

#with_local_table_name(enable = true) ⇒ Object

rubocop:disable Style/OptionalBooleanParameter



95
96
97
98
99
100
101
# File 'lib/switchman/active_record/postgresql_adapter.rb', line 95

def with_local_table_name(enable = true) # rubocop:disable Style/OptionalBooleanParameter
  old_value = @use_local_table_name
  @use_local_table_name = enable
  yield
ensure
  @use_local_table_name = old_value
end