switchman 2.0.7 → 2.0.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/switchman/active_record/postgresql_adapter.rb +137 -108
- data/lib/switchman/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 697ce16e90d84de2535fdbf6dacc40640323dddffa4becb4a3d5e8c3b4d1a67f
|
4
|
+
data.tar.gz: b94f2c678d8dd4d03c7dd089c441ced5a75923778c972a86a7cc3f20c126bc97
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 82dff35e613f3f9147e7575f1865402df57375dd8f8396ae6f61ad86cf82ec401098b4210eecabb8596c9d7dbba3a3a3ba87c030d7b17b74aae1605cfc3efac9
|
7
|
+
data.tar.gz: 8678d9c29a485baf8bc483d3c6717d4e2c88d2de14e51e4356a656b579bd0c65579274e0afd70a94d2fb1bc8c617b44a47d73bb04cd8a0b41f1ad2a378ff7e38
|
@@ -40,14 +40,6 @@ module Switchman
|
|
40
40
|
select_values("SELECT * FROM unnest(current_schemas(false))")
|
41
41
|
end
|
42
42
|
|
43
|
-
def tables(name = nil)
|
44
|
-
query(<<-SQL, 'SCHEMA').map { |row| row[0] }
|
45
|
-
SELECT tablename
|
46
|
-
FROM pg_tables
|
47
|
-
WHERE schemaname = '#{shard.name}'
|
48
|
-
SQL
|
49
|
-
end
|
50
|
-
|
51
43
|
def extract_schema_qualified_name(string)
|
52
44
|
name = ::ActiveRecord::ConnectionAdapters::PostgreSQL::Utils.extract_schema_qualified_name(string.to_s)
|
53
45
|
if string && !name.schema
|
@@ -56,80 +48,155 @@ module Switchman
|
|
56
48
|
[name.schema, name.identifier]
|
57
49
|
end
|
58
50
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
51
|
+
# significant change: use the shard name if no explicit schema
|
52
|
+
def quoted_scope(name = nil, type: nil)
|
53
|
+
schema, name = extract_schema_qualified_name(name)
|
54
|
+
type = \
|
55
|
+
case type
|
56
|
+
when "BASE TABLE"
|
57
|
+
"'r','p'"
|
58
|
+
when "VIEW"
|
59
|
+
"'v','m'"
|
60
|
+
when "FOREIGN TABLE"
|
61
|
+
"'f'"
|
62
|
+
end
|
63
|
+
scope = {}
|
64
|
+
scope[:schema] = quote(schema || shard.name)
|
65
|
+
scope[:name] = quote(name) if name
|
66
|
+
scope[:type] = type if type
|
67
|
+
scope
|
74
68
|
end
|
75
69
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
WHERE i.relkind = 'i'
|
83
|
-
AND d.indisprimary = 'f'
|
84
|
-
AND t.relname = '#{table_name}'
|
85
|
-
AND i.relnamespace IN (SELECT oid FROM pg_namespace WHERE nspname = '#{shard.name}' )
|
86
|
-
ORDER BY i.relname
|
87
|
-
SQL
|
88
|
-
|
89
|
-
|
90
|
-
result.map do |row|
|
91
|
-
index_name = row[0]
|
92
|
-
unique = row[1] == true || row[1] == 't'
|
93
|
-
indkey = row[2].split(" ")
|
94
|
-
inddef = row[3]
|
95
|
-
oid = row[4]
|
96
|
-
|
97
|
-
columns = Hash[query(<<-SQL, "SCHEMA")]
|
98
|
-
SELECT a.attnum, a.attname
|
99
|
-
FROM pg_attribute a
|
100
|
-
WHERE a.attrelid = #{oid}
|
101
|
-
AND a.attnum IN (#{indkey.join(",")})
|
70
|
+
if ::Rails.version < '6.0'
|
71
|
+
def tables(name = nil)
|
72
|
+
query(<<-SQL, 'SCHEMA').map { |row| row[0] }
|
73
|
+
SELECT tablename
|
74
|
+
FROM pg_tables
|
75
|
+
WHERE schemaname = '#{shard.name}'
|
102
76
|
SQL
|
77
|
+
end
|
103
78
|
|
104
|
-
|
105
|
-
|
106
|
-
unless
|
107
|
-
|
108
|
-
|
109
|
-
orders = desc_order_columns.any? ? Hash[desc_order_columns.map {|order_column| [order_column, :desc]}] : {}
|
110
|
-
where = inddef.scan(/WHERE (.+)$/).flatten[0]
|
111
|
-
using = inddef.scan(/USING (.+?) /).flatten[0].to_sym
|
112
|
-
|
113
|
-
if ::Rails.version >= "5.2"
|
114
|
-
::ActiveRecord::ConnectionAdapters::IndexDefinition.new(table_name, index_name, unique, column_names, orders: orders, where: where, using: using)
|
115
|
-
else
|
116
|
-
::ActiveRecord::ConnectionAdapters::IndexDefinition.new(table_name, index_name, unique, column_names, [], orders, where, nil, using)
|
117
|
-
end
|
79
|
+
def view_exists?(name)
|
80
|
+
name = ::ActiveRecord::ConnectionAdapters::PostgreSQL::Utils.extract_schema_qualified_name(name.to_s)
|
81
|
+
return false unless name.identifier
|
82
|
+
if !name.schema
|
83
|
+
name.instance_variable_set(:@schema, shard.name)
|
118
84
|
end
|
119
|
-
end.compact
|
120
|
-
end
|
121
85
|
|
122
|
-
|
123
|
-
|
124
|
-
|
86
|
+
select_values(<<-SQL, 'SCHEMA').any?
|
87
|
+
SELECT c.relname
|
88
|
+
FROM pg_class c
|
89
|
+
LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
|
90
|
+
WHERE c.relkind IN ('v','m') -- (v)iew, (m)aterialized view
|
91
|
+
AND c.relname = '#{name.identifier}'
|
92
|
+
AND n.nspname = '#{shard.name}'
|
93
|
+
SQL
|
94
|
+
end
|
95
|
+
|
96
|
+
def indexes(table_name)
|
97
|
+
result = query(<<-SQL, 'SCHEMA')
|
98
|
+
SELECT distinct i.relname, d.indisunique, d.indkey, pg_get_indexdef(d.indexrelid), t.oid
|
125
99
|
FROM pg_class t
|
126
100
|
INNER JOIN pg_index d ON t.oid = d.indrelid
|
127
101
|
INNER JOIN pg_class i ON d.indexrelid = i.oid
|
128
102
|
WHERE i.relkind = 'i'
|
129
|
-
AND
|
103
|
+
AND d.indisprimary = 'f'
|
130
104
|
AND t.relname = '#{table_name}'
|
131
105
|
AND i.relnamespace IN (SELECT oid FROM pg_namespace WHERE nspname = '#{shard.name}' )
|
132
|
-
|
106
|
+
ORDER BY i.relname
|
107
|
+
SQL
|
108
|
+
|
109
|
+
|
110
|
+
result.map do |row|
|
111
|
+
index_name = row[0]
|
112
|
+
unique = row[1] == true || row[1] == 't'
|
113
|
+
indkey = row[2].split(" ")
|
114
|
+
inddef = row[3]
|
115
|
+
oid = row[4]
|
116
|
+
|
117
|
+
columns = Hash[query(<<-SQL, "SCHEMA")]
|
118
|
+
SELECT a.attnum, a.attname
|
119
|
+
FROM pg_attribute a
|
120
|
+
WHERE a.attrelid = #{oid}
|
121
|
+
AND a.attnum IN (#{indkey.join(",")})
|
122
|
+
SQL
|
123
|
+
|
124
|
+
column_names = columns.stringify_keys.values_at(*indkey).compact
|
125
|
+
|
126
|
+
unless column_names.empty?
|
127
|
+
# add info on sort order for columns (only desc order is explicitly specified, asc is the default)
|
128
|
+
desc_order_columns = inddef.scan(/(\w+) DESC/).flatten
|
129
|
+
orders = desc_order_columns.any? ? Hash[desc_order_columns.map {|order_column| [order_column, :desc]}] : {}
|
130
|
+
where = inddef.scan(/WHERE (.+)$/).flatten[0]
|
131
|
+
using = inddef.scan(/USING (.+?) /).flatten[0].to_sym
|
132
|
+
|
133
|
+
if ::Rails.version >= "5.2"
|
134
|
+
::ActiveRecord::ConnectionAdapters::IndexDefinition.new(table_name, index_name, unique, column_names, orders: orders, where: where, using: using)
|
135
|
+
else
|
136
|
+
::ActiveRecord::ConnectionAdapters::IndexDefinition.new(table_name, index_name, unique, column_names, [], orders, where, nil, using)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end.compact
|
140
|
+
end
|
141
|
+
|
142
|
+
def index_name_exists?(table_name, index_name, _default = nil)
|
143
|
+
exec_query(<<-SQL, 'SCHEMA').rows.first[0].to_i > 0
|
144
|
+
SELECT COUNT(*)
|
145
|
+
FROM pg_class t
|
146
|
+
INNER JOIN pg_index d ON t.oid = d.indrelid
|
147
|
+
INNER JOIN pg_class i ON d.indexrelid = i.oid
|
148
|
+
WHERE i.relkind = 'i'
|
149
|
+
AND i.relname = '#{index_name}'
|
150
|
+
AND t.relname = '#{table_name}'
|
151
|
+
AND i.relnamespace IN (SELECT oid FROM pg_namespace WHERE nspname = '#{shard.name}' )
|
152
|
+
SQL
|
153
|
+
end
|
154
|
+
|
155
|
+
def foreign_keys(table_name)
|
156
|
+
# mostly copy-pasted from AR - only change is to the nspname condition for qualified names support
|
157
|
+
fk_info = select_all <<-SQL.strip_heredoc
|
158
|
+
SELECT t2.oid::regclass::text AS to_table, a1.attname AS column, a2.attname AS primary_key, c.conname AS name, c.confupdtype AS on_update, c.confdeltype AS on_delete
|
159
|
+
FROM pg_constraint c
|
160
|
+
JOIN pg_class t1 ON c.conrelid = t1.oid
|
161
|
+
JOIN pg_class t2 ON c.confrelid = t2.oid
|
162
|
+
JOIN pg_attribute a1 ON a1.attnum = c.conkey[1] AND a1.attrelid = t1.oid
|
163
|
+
JOIN pg_attribute a2 ON a2.attnum = c.confkey[1] AND a2.attrelid = t2.oid
|
164
|
+
JOIN pg_namespace t3 ON c.connamespace = t3.oid
|
165
|
+
WHERE c.contype = 'f'
|
166
|
+
AND t1.relname = #{quote(table_name)}
|
167
|
+
AND t3.nspname = '#{shard.name}'
|
168
|
+
ORDER BY c.conname
|
169
|
+
SQL
|
170
|
+
|
171
|
+
fk_info.map do |row|
|
172
|
+
options = {
|
173
|
+
column: row['column'],
|
174
|
+
name: row['name'],
|
175
|
+
primary_key: row['primary_key']
|
176
|
+
}
|
177
|
+
|
178
|
+
options[:on_delete] = extract_foreign_key_action(row['on_delete'])
|
179
|
+
options[:on_update] = extract_foreign_key_action(row['on_update'])
|
180
|
+
|
181
|
+
# strip the schema name from to_table if it matches
|
182
|
+
to_table = row['to_table']
|
183
|
+
to_table_qualified_name = ::ActiveRecord::ConnectionAdapters::PostgreSQL::Utils.extract_schema_qualified_name(to_table)
|
184
|
+
if to_table_qualified_name.schema == shard.name
|
185
|
+
to_table = to_table_qualified_name.identifier
|
186
|
+
end
|
187
|
+
|
188
|
+
::ActiveRecord::ConnectionAdapters::ForeignKeyDefinition.new(table_name, to_table, options)
|
189
|
+
end
|
190
|
+
end
|
191
|
+
else
|
192
|
+
def foreign_keys(table_name)
|
193
|
+
super.each do |fk|
|
194
|
+
to_table_qualified_name = ::ActiveRecord::ConnectionAdapters::PostgreSQL::Utils.extract_schema_qualified_name(fk.to_table)
|
195
|
+
if to_table_qualified_name.schema == shard.name
|
196
|
+
fk.to_table = to_table_qualified_name.identifier
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
133
200
|
end
|
134
201
|
|
135
202
|
def quote_local_table_name(name)
|
@@ -156,44 +223,6 @@ module Switchman
|
|
156
223
|
@use_local_table_name = old_value
|
157
224
|
end
|
158
225
|
|
159
|
-
def foreign_keys(table_name)
|
160
|
-
|
161
|
-
# mostly copy-pasted from AR - only change is to the nspname condition for qualified names support
|
162
|
-
fk_info = select_all <<-SQL.strip_heredoc
|
163
|
-
SELECT t2.oid::regclass::text AS to_table, a1.attname AS column, a2.attname AS primary_key, c.conname AS name, c.confupdtype AS on_update, c.confdeltype AS on_delete
|
164
|
-
FROM pg_constraint c
|
165
|
-
JOIN pg_class t1 ON c.conrelid = t1.oid
|
166
|
-
JOIN pg_class t2 ON c.confrelid = t2.oid
|
167
|
-
JOIN pg_attribute a1 ON a1.attnum = c.conkey[1] AND a1.attrelid = t1.oid
|
168
|
-
JOIN pg_attribute a2 ON a2.attnum = c.confkey[1] AND a2.attrelid = t2.oid
|
169
|
-
JOIN pg_namespace t3 ON c.connamespace = t3.oid
|
170
|
-
WHERE c.contype = 'f'
|
171
|
-
AND t1.relname = #{quote(table_name)}
|
172
|
-
AND t3.nspname = '#{shard.name}'
|
173
|
-
ORDER BY c.conname
|
174
|
-
SQL
|
175
|
-
|
176
|
-
fk_info.map do |row|
|
177
|
-
options = {
|
178
|
-
column: row['column'],
|
179
|
-
name: row['name'],
|
180
|
-
primary_key: row['primary_key']
|
181
|
-
}
|
182
|
-
|
183
|
-
options[:on_delete] = extract_foreign_key_action(row['on_delete'])
|
184
|
-
options[:on_update] = extract_foreign_key_action(row['on_update'])
|
185
|
-
|
186
|
-
# strip the schema name from to_table if it matches
|
187
|
-
to_table = row['to_table']
|
188
|
-
to_table_qualified_name = ::ActiveRecord::ConnectionAdapters::PostgreSQL::Utils.extract_schema_qualified_name(to_table)
|
189
|
-
if to_table_qualified_name.schema == shard.name
|
190
|
-
to_table = to_table_qualified_name.identifier
|
191
|
-
end
|
192
|
-
|
193
|
-
::ActiveRecord::ConnectionAdapters::ForeignKeyDefinition.new(table_name, to_table, options)
|
194
|
-
end
|
195
|
-
end
|
196
|
-
|
197
226
|
def add_index_options(_table_name, _column_name, **)
|
198
227
|
index_name, index_type, index_columns, index_options, algorithm, using = super
|
199
228
|
algorithm = nil if DatabaseServer.creating_new_shard && algorithm == "CONCURRENTLY"
|
data/lib/switchman/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: switchman
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Cody Cutrer
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2021-
|
13
|
+
date: 2021-04-01 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: railties
|