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.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/tasks/db.rb +76 -2
  3. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 968ab94490eb008b3eedcd6b83ad0042cc4812f5
4
- data.tar.gz: 5c41d69b55474bb81f0fb7829d6fd5604d5bb193
3
+ metadata.gz: df4390a732399e47e5810e40f119ffc1dfaf48b2
4
+ data.tar.gz: 9d90300f7b49ad447022b53320b3d88b14b39bbc
5
5
  SHA512:
6
- metadata.gz: 059920a90809c21cf69c76183c433649f12a8425069ff1ad428858176fe693c3e6a43e019fd8dbb168492aad499f89771bfcd22ca7e707bb5050b788ec8f81ee
7
- data.tar.gz: 1f9adcf24f2c40df0f427651c5f1e05db406863b89251ce74eb4394af8bbf4d8ea08acfd7b228a5a4e35029065404b0cc64535ae1472af13cab106a3fcd69222
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
- results.each do |row|
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.2.2
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-03 00:00:00.000000000 Z
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.