db-evolve 0.2.2 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/tasks/db.rb +76 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: df4390a732399e47e5810e40f119ffc1dfaf48b2
|
4
|
+
data.tar.gz: 9d90300f7b49ad447022b53320b3d88b14b39bbc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c433eed0a2d0df2b78438ef62ec61b91c0d303aff4ccb26b3399f96f64311296f424990d7701753ae7dcc9c27a4cb1cb4a573dd5c26c73783261cd97efc4c5d6
|
7
|
+
data.tar.gz: 653cf0759eeae31361ab782e8b2660de2cdd2c18177f3d52222945a7ac7705916e18ef527463ff619a1efa067cebca4c3adc8bd683386af3424eea7d250e5e63
|
data/lib/tasks/db.rb
CHANGED
@@ -105,6 +105,8 @@ def do_evolve(noop, yes, nowait)
|
|
105
105
|
|
106
106
|
to_run += calc_index_changes(existing_indexes, $schema_indexes, renames, rename_cols_by_table)
|
107
107
|
|
108
|
+
to_run += calc_fk_changes($foreign_keys, Set.new($schema_tables.keys) + Set.new(existing_tables.keys))
|
109
|
+
|
108
110
|
to_run += calc_perms_changes($schema_tables, noop) unless $check_perms_for.empty?
|
109
111
|
|
110
112
|
to_run += sql_drops(deletes)
|
@@ -199,6 +201,55 @@ def calc_index_changes(existing_indexes, schema_indexes, table_renames, rename_c
|
|
199
201
|
return to_run
|
200
202
|
end
|
201
203
|
|
204
|
+
def calc_fk_changes(foreign_keys, tables)
|
205
|
+
existing_foreign_keys = []
|
206
|
+
unless tables.empty?
|
207
|
+
tables_sql = (tables.map {|tn| ActiveRecord::Base.sanitize(tn)}).join(',')
|
208
|
+
sql = %{
|
209
|
+
SELECT
|
210
|
+
tc.constraint_name, tc.table_name, kcu.column_name,
|
211
|
+
ccu.table_name AS foreign_table_name,
|
212
|
+
ccu.column_name AS foreign_column_name
|
213
|
+
FROM
|
214
|
+
information_schema.table_constraints AS tc
|
215
|
+
JOIN information_schema.key_column_usage AS kcu
|
216
|
+
ON tc.constraint_name = kcu.constraint_name
|
217
|
+
JOIN information_schema.constraint_column_usage AS ccu
|
218
|
+
ON ccu.constraint_name = tc.constraint_name
|
219
|
+
WHERE constraint_type = 'FOREIGN KEY'
|
220
|
+
AND tc.table_name in (#{tables_sql});
|
221
|
+
}
|
222
|
+
build_pg_connection.exec(sql).each do |row|
|
223
|
+
existing_foreign_keys << HashWithIndifferentAccess.new({
|
224
|
+
:from_table => row['table_name'],
|
225
|
+
:to_table => row['foreign_table_name'],
|
226
|
+
:column => row['column_name'],
|
227
|
+
:primary_key => row['foreign_column_name'],
|
228
|
+
:name => row['constraint_name'],
|
229
|
+
})
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
existing_foreign_keys = Set.new existing_foreign_keys
|
234
|
+
foreign_keys = Set.new foreign_keys
|
235
|
+
add_fks = foreign_keys - existing_foreign_keys
|
236
|
+
delete_fks = existing_foreign_keys - foreign_keys
|
237
|
+
|
238
|
+
to_run = []
|
239
|
+
delete_fks.each do |fk|
|
240
|
+
to_run << "ALTER TABLE #{escape_table(fk[:from_table])} DROP CONSTRAINT IF EXISTS #{escape_table(fk[:name])}"
|
241
|
+
end
|
242
|
+
add_fks.each do |fk|
|
243
|
+
to_run << "ALTER TABLE #{escape_table(fk[:from_table])} ADD CONSTRAINT #{escape_table(fk[:name])} FOREIGN KEY (#{escape_table(fk[:column])}) REFERENCES #{escape_table(fk[:to_table])} (#{escape_table(fk[:primary_key])}) MATCH FULL"
|
244
|
+
end
|
245
|
+
|
246
|
+
if !to_run.empty?
|
247
|
+
to_run.unshift("\n-- update foreign keys")
|
248
|
+
end
|
249
|
+
|
250
|
+
return to_run
|
251
|
+
end
|
252
|
+
|
202
253
|
def calc_perms_changes schema_tables, noop
|
203
254
|
users = ($check_perms_for.map { |user| ActiveRecord::Base::sanitize(user) }).join ","
|
204
255
|
database = ActiveRecord::Base.connection_config[:database]
|
@@ -209,9 +260,8 @@ def calc_perms_changes schema_tables, noop
|
|
209
260
|
and grantee in (#{users})
|
210
261
|
and table_schema='public';
|
211
262
|
}
|
212
|
-
results = build_pg_connection.exec(sql)
|
213
263
|
existing_perms = Hash.new { |h, k| h[k] = Hash.new { |h, k| h[k] = Set.new } }
|
214
|
-
|
264
|
+
build_pg_connection.exec(sql).each do |row|
|
215
265
|
existing_perms[row['grantee']][row['table_name']].add(row['privilege_type'])
|
216
266
|
end
|
217
267
|
to_run = []
|
@@ -294,6 +344,14 @@ class Table
|
|
294
344
|
c.akas = [aka]
|
295
345
|
end
|
296
346
|
end
|
347
|
+
fk = c.opts.delete(:fk)
|
348
|
+
if fk.present?
|
349
|
+
if fk.respond_to?('each')
|
350
|
+
add_foreign_key self.name, fk[0], column: c.name, primary_key: fk[1]
|
351
|
+
else
|
352
|
+
add_foreign_key self.name, fk, column: c.name
|
353
|
+
end
|
354
|
+
end
|
297
355
|
else
|
298
356
|
c.opts = {}
|
299
357
|
end
|
@@ -355,6 +413,21 @@ def add_index(table, columns, opts)
|
|
355
413
|
$schema_indexes.append(opts)
|
356
414
|
end
|
357
415
|
|
416
|
+
$foreign_keys = []
|
417
|
+
|
418
|
+
def add_foreign_key(from_table, to_table, opts={})
|
419
|
+
opts = HashWithIndifferentAccess.new opts
|
420
|
+
opts[:from_table] = from_table.to_s
|
421
|
+
opts[:to_table] = to_table.to_s
|
422
|
+
opts[:column] = to_table.to_s.singularize + "_id" unless opts[:column].present?
|
423
|
+
opts[:primary_key] = "id" unless opts[:primary_key].present?
|
424
|
+
opts[:name] = "fk #{from_table.to_s.parameterize}.#{opts[:column].to_s.parameterize} to #{to_table.to_s.parameterize}.#{opts[:primary_key].to_s.parameterize}" unless opts[:name].present?
|
425
|
+
opts[:column] = opts[:column].to_s
|
426
|
+
opts[:primary_key] = opts[:primary_key].to_s
|
427
|
+
opts[:name] = opts[:name].to_s
|
428
|
+
$foreign_keys.append(opts)
|
429
|
+
end
|
430
|
+
|
358
431
|
$allowed_perms = Set.new ["INSERT", "SELECT", "UPDATE", "DELETE", "TRUNCATE", "REFERENCES", "TRIGGER"]
|
359
432
|
$default_perms_for = Hash.new { |h, k| h[k] = Set.new }
|
360
433
|
|
@@ -414,6 +487,7 @@ def calc_table_changes(existing_tables, schema_tables, akas_tables)
|
|
414
487
|
end
|
415
488
|
|
416
489
|
def escape_table(k)
|
490
|
+
k = k.to_s if k.is_a? Symbol
|
417
491
|
return PG::Connection.quote_ident k
|
418
492
|
end
|
419
493
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: db-evolve
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Derek Anderson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-03-
|
11
|
+
date: 2016-03-04 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: A diff/patch-esque tool to replace schema migrations in Ruby. See https://github.com/keredson/ruby-db-evolve
|
14
14
|
for details.
|