webdack-uuid_migration 1.0.1 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6368bae7ea813a00d4a532174f0f1ebd704b2cef
4
- data.tar.gz: d9e59fe6d56546514c5eca167ef2e8b53bd6b622
3
+ metadata.gz: 7e73ae10fca41d84505cb6f9237f9b45f2da850c
4
+ data.tar.gz: 5abb88d0a9bc06de553e2e7b1e6fcae13fc85d88
5
5
  SHA512:
6
- metadata.gz: 4840bb9c3a7da55bc2c9fe9b0712163181a86f9060f2aeba6eefeb2c862621953b8fd53e97d13b433d7260a96af9a0a5addabbba88a0f2c201766c6f3d61fd3b
7
- data.tar.gz: 64dd4f6a8271522d79870c6628c524c5258ebc45937e66c91afe5ed41ca8d17a316ff30a661c96e6b70bf854131f01fa8ad8d2228530b4748caf85cd90727b7b
6
+ metadata.gz: d3005d3ba1bde0da93c33714b05cc7d831ede40dc91a977c836442c5b7be10f0a08e2d7a58fcf878e21fb1fafef26cc9b8d86ece4978270b1c49034a3824e8a9
7
+ data.tar.gz: 1631e47e420df4926c7ce6ab4775925cf7a3f53389c7369a4d473cda7e63febdb0fb6782995da3ff786b4947ed0092123835b5d1851309c7f46e2a52ec1d531a
data/.travis.yml ADDED
@@ -0,0 +1,15 @@
1
+ rvm:
2
+ - 1.9.3
3
+ - 2.0.0
4
+ - 2.1.1
5
+ - 2.2.0
6
+ - 2.3.1
7
+ - rbx-2
8
+ - jruby
9
+ - ruby-head
10
+
11
+ script: bundle exec rspec spec
12
+
13
+ matrix:
14
+ allow_failures:
15
+ - rvm: jruby
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # Webdack::UuidMigration
2
2
 
3
+ [![Build Status](https://travis-ci.org/kreatio-sw/webdack-uuid_migration.svg?branch=master)](https://travis-ci.org/kreatio-sw/webdack-uuid_migration)
4
+
3
5
  Helper methods to migrate Integer columns to UUID columns during migrations in PostgreSQL.
4
6
  It supports migrating primary key columns as well.
5
7
 
@@ -60,6 +62,39 @@ retrieve old id in future.
60
62
  See {Webdack::UUIDMigration::Helpers} for more details. {Webdack::UUIDMigration::Helpers} is mixed
61
63
  into {ActiveRecord::Migration}, so that all methods can directly be used within migrations.
62
64
 
65
+ ### Schema with Foreign Key References
66
+
67
+ Please see [https://github.com/kreatio-sw/webdack-uuid_migration/issues/4]
68
+
69
+ To update a primary key and all columns referencing it please use
70
+ {Webdack::UUIDMigration::Helpers#primary_key_and_all_references_to_uuid}. For example:
71
+
72
+ ```
73
+ class MigrateWithFk < ActiveRecord::Migration
74
+ def change
75
+ reversible do |dir|
76
+ dir.up do
77
+ enable_extension 'uuid-ossp'
78
+
79
+ primary_key_and_all_references_to_uuid :cities
80
+ end
81
+
82
+ dir.down do
83
+ raise ActiveRecord::IrreversibleMigration
84
+ end
85
+ end
86
+ end
87
+ end
88
+ ```
89
+
90
+ Internally it will query the database to find all tables & columns referring to this primary key as foreign keys
91
+ and do the following:
92
+
93
+ - Drop all foreign key constraints referring to this primary key
94
+ - Convert the primary key to UUID
95
+ - Convert all referring columns to UUID
96
+ - Restore all foreign keys
97
+
63
98
  ### Polymorphic references
64
99
 
65
100
  Migrating Polymorphic references may get tricky if not all the participating entities are getting migrated to
@@ -93,10 +128,10 @@ Example:
93
128
 
94
129
  ## Compatibility
95
130
 
96
- Works only with Rails 4. It uses Rails4's out-of-the-box UUID support for PostgreSQL. Works with Ruby 1.9.3,
131
+ Works only with Rails 4 & Rails 5. It uses Rails4's out-of-the-box UUID support for PostgreSQL. Works with Ruby 1.9.3,
97
132
  2.0.0, 2.1.1, and 2.3.0.
98
133
 
99
- Tested with Rails 5.0.0.beta1.
134
+ Tested with Rails 5.0.0.
100
135
 
101
136
  To run the test suite:
102
137
 
@@ -1,6 +1,10 @@
1
+ require_relative 'schema_helpers'
2
+
1
3
  module Webdack
2
4
  module UUIDMigration
3
5
  module Helpers
6
+ include SchemaHelpers
7
+
4
8
 
5
9
  # Converts primary key from Serial Integer to UUID, migrates all data by left padding with 0's
6
10
  # sets uuid_generate_v4() as default for the column
@@ -72,6 +76,32 @@ module Webdack
72
76
  }
73
77
  end
74
78
 
79
+ # Convert primary key of a table and all referring columns to UUID. Useful if migrations were generated
80
+ # with newer version of Rails that automatically creates foreign key constraints in the database.
81
+ #
82
+ # Internally it will query the database to find all tables & columns referring to this primary key as foreign keys
83
+ # and do the following:
84
+ #
85
+ # - Drop all foreign key constraints referring to this primary key
86
+ # - Convert the primary key to UUID
87
+ # - Convert all referring columns to UUID
88
+ # - Restore all foreign keys
89
+ #
90
+ # @param table[Symbol]
91
+ def primary_key_and_all_references_to_uuid(table)
92
+ fk_specs = foreign_keys_into(:cities)
93
+
94
+ drop_foreign_keys(fk_specs)
95
+
96
+ primary_key_to_uuid(table)
97
+
98
+ fk_specs.each do |fk_spec|
99
+ columns_to_uuid fk_spec[:from_table], fk_spec[:column]
100
+ end
101
+
102
+ create_foreign_keys(fk_specs.deep_dup)
103
+ end
104
+
75
105
  private
76
106
  # Prepare a fragment that can be used in SQL statements that converts teh data value
77
107
  # from integer, string, or UUID to valid UUID string as per Postgres guidelines
@@ -0,0 +1,55 @@
1
+ module Webdack
2
+ module UUIDMigration
3
+ module SchemaHelpers
4
+ def foreign_keys_into(to_table_name)
5
+ to_primary_key = primary_key(to_table_name)
6
+
7
+
8
+ fk_info = select_all <<-SQL.strip_heredoc
9
+ SELECT t2.oid::regclass::text AS to_table, a2.attname AS primary_key, t1.relname as from_table, a1.attname AS column, c.conname AS name, c.confupdtype AS on_update, c.confdeltype AS on_delete FROM pg_constraint c
10
+ JOIN pg_class t1 ON c.conrelid = t1.oid
11
+ JOIN pg_class t2 ON c.confrelid = t2.oid
12
+ JOIN pg_attribute a1 ON a1.attnum = c.conkey[1] AND a1.attrelid = t1.oid
13
+ JOIN pg_attribute a2 ON a2.attnum = c.confkey[1] AND a2.attrelid = t2.oid
14
+ JOIN pg_namespace t3 ON c.connamespace = t3.oid
15
+ WHERE c.contype = 'f'
16
+ AND t2.oid::regclass::text = #{quote(to_table_name)}
17
+ AND a2.attname = #{quote(to_primary_key)}
18
+ ORDER BY t1.relname, a1.attname
19
+ SQL
20
+
21
+ fk_info.map do |row|
22
+ options = {
23
+ to_table: row['to_table'],
24
+ primary_key: row['primary_key'],
25
+ from_table: row['from_table'],
26
+ column: row['column'],
27
+ name: row['name']
28
+ }
29
+
30
+ options[:on_delete] = extract_foreign_key_action(row['on_delete'])
31
+ options[:on_update] = extract_foreign_key_action(row['on_update'])
32
+
33
+ options
34
+ end
35
+ end
36
+
37
+ def drop_foreign_keys(foreign_keys)
38
+ foreign_keys.each do |fk_key_spec|
39
+ foreign_key_spec = fk_key_spec.dup
40
+ from_table = foreign_key_spec.delete(:from_table)
41
+ remove_foreign_key from_table, name: foreign_key_spec[:name]
42
+ end
43
+ end
44
+
45
+ def create_foreign_keys(foreign_keys)
46
+ foreign_keys.each do |fk_key_spec|
47
+ foreign_key_spec = fk_key_spec.dup
48
+ from_table = foreign_key_spec.delete(:from_table)
49
+ to_table = foreign_key_spec.delete(:to_table)
50
+ add_foreign_key from_table, to_table, foreign_key_spec
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -2,6 +2,6 @@
2
2
  module Webdack
3
3
  #
4
4
  module UUIDMigration
5
- VERSION = "1.0.1"
5
+ VERSION = "1.0.2"
6
6
  end
7
7
  end
@@ -0,0 +1,68 @@
1
+ require_relative 'spec_helper'
2
+
3
+ ActiveRecord::ConnectionAdapters::AbstractAdapter.class_eval do
4
+ include Webdack::UUIDMigration::SchemaHelpers
5
+ end
6
+
7
+ describe Webdack::UUIDMigration::SchemaHelpers do
8
+ def initial_setup
9
+ init_database
10
+ create_initial_schema
11
+
12
+ # Create 2 more tables similar to the way new version of Rails will do
13
+ create_tables_with_fk
14
+ end
15
+
16
+ before(:each) do
17
+ initial_setup
18
+
19
+ @connection = ActiveRecord::Base.connection
20
+
21
+ # Create one more foreign key constraints
22
+ @connection.add_foreign_key :students, :cities
23
+ end
24
+
25
+ it 'should get all foreign keys into a table' do
26
+ foreign_keys_into = @connection.foreign_keys_into(:cities)
27
+
28
+ expect(foreign_keys_into).to eq([{:to_table => "cities",
29
+ :primary_key => "id",
30
+ :from_table => "dummy01",
31
+ :column => "city_id",
32
+ :name => "fk_rails_d0b87897d5",
33
+ :on_delete => :nullify,
34
+ :on_update => :cascade},
35
+ {:to_table => "cities",
36
+ :primary_key => "id",
37
+ :from_table => "dummy02",
38
+ :column => "city_id",
39
+ :name => "fk_rails_bc0a81611b",
40
+ :on_delete => :restrict,
41
+ :on_update => :restrict},
42
+ {:to_table => "cities",
43
+ :primary_key => "id",
44
+ :from_table => "students",
45
+ :column => "city_id",
46
+ :name => "fk_rails_c4b8171c0a",
47
+ :on_delete => nil,
48
+ :on_update => nil}])
49
+ end
50
+
51
+ it 'should drop all foreign keys into a table' do
52
+ fk_specs = @connection.foreign_keys_into(:cities)
53
+
54
+ @connection.drop_foreign_keys(fk_specs)
55
+
56
+ expect(@connection.foreign_keys_into(:cities)).to eq([])
57
+ end
58
+
59
+ it 'should drop all recreate all foreign keys into a table' do
60
+ fk_specs = @connection.foreign_keys_into(:cities)
61
+
62
+ @connection.drop_foreign_keys(fk_specs)
63
+ @connection.create_foreign_keys(fk_specs)
64
+
65
+ expect(@connection.foreign_keys_into(:cities)).to eq(fk_specs)
66
+ end
67
+
68
+ end
@@ -38,3 +38,17 @@ def create_initial_schema
38
38
 
39
39
  end
40
40
  end
41
+
42
+ def create_tables_with_fk
43
+ connection = ActiveRecord::Base.connection
44
+
45
+ connection.create_table "dummy01", force: true do |t|
46
+ t.string "name"
47
+ t.references "city", index: true, foreign_key: {on_update: :cascade, on_delete: :nullify}
48
+ end
49
+
50
+ connection.create_table "dummy02", force: true do |t|
51
+ t.string "name"
52
+ t.references "city", index: true, foreign_key: {on_update: :restrict, on_delete: :restrict}
53
+ end
54
+ end
@@ -2,11 +2,9 @@
2
2
 
3
3
  PG_SPEC = {
4
4
  :adapter => 'postgresql',
5
- :host => 'localhost',
6
5
  :database => 'webdack_uuid_migration_helper_test',
7
- :username => 'kdeepak',
8
- :encoding => 'utf8',
9
- :password => 'kreatio'
6
+ :username => 'postgres',
7
+ :encoding => 'utf8'
10
8
  }
11
9
 
12
10
  def init_database
@@ -38,6 +38,22 @@ class MigrateAllOneGo < ActiveRecord::Migration
38
38
  end
39
39
  end
40
40
 
41
+ class MigrateWithFk < ActiveRecord::Migration
42
+ def change
43
+ reversible do |dir|
44
+ dir.up do
45
+ enable_extension 'uuid-ossp'
46
+
47
+ primary_key_and_all_references_to_uuid :cities
48
+ end
49
+
50
+ dir.down do
51
+ raise ActiveRecord::IrreversibleMigration
52
+ end
53
+ end
54
+ end
55
+ end
56
+
41
57
  class MigrateStep01 < ActiveRecord::Migration
42
58
  def change
43
59
  reversible do |dir|
@@ -154,6 +170,21 @@ describe Webdack::UUIDMigration::Helpers do
154
170
  }
155
171
  end
156
172
 
173
+ it 'should migrate a primary key and all columns referencing it using foreign keys' do
174
+ # Create 2 more tables similar to the way new version of Rails will do
175
+ create_tables_with_fk
176
+
177
+ # Add Foreign key for this reference as well
178
+ ActiveRecord::Base.connection.add_foreign_key :students, :cities
179
+
180
+ expect {
181
+ MigrateWithFk.migrate(:up)
182
+ reset_columns_data
183
+ }.to_not change {
184
+ key_relationships
185
+ }
186
+ end
187
+
157
188
  it 'should handle nulls' do
158
189
  Student.create(name: 'Student without city or institution')
159
190
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: webdack-uuid_migration
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Deepak Kumar
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-12-27 00:00:00.000000000 Z
11
+ date: 2016-08-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -117,13 +117,16 @@ extensions: []
117
117
  extra_rdoc_files: []
118
118
  files:
119
119
  - ".gitignore"
120
+ - ".travis.yml"
120
121
  - Gemfile
121
122
  - LICENSE.txt
122
123
  - README.md
123
124
  - Rakefile
124
125
  - lib/webdack/uuid_migration.rb
125
126
  - lib/webdack/uuid_migration/helpers.rb
127
+ - lib/webdack/uuid_migration/schema_helpers.rb
126
128
  - lib/webdack/uuid_migration/version.rb
129
+ - spec/schema_helper_spec.rb
127
130
  - spec/spec_helper.rb
128
131
  - spec/support/initial_data.rb
129
132
  - spec/support/initial_schema.rb
@@ -160,6 +163,7 @@ signing_key:
160
163
  specification_version: 4
161
164
  summary: Useful helpers to migrate Integer id columns to UUID in PostgreSql.
162
165
  test_files:
166
+ - spec/schema_helper_spec.rb
163
167
  - spec/spec_helper.rb
164
168
  - spec/support/initial_data.rb
165
169
  - spec/support/initial_schema.rb
@@ -170,4 +174,3 @@ test_files:
170
174
  - spec/support/pg_database_helper.rb
171
175
  - spec/uuid_custom_pk_spec.rb
172
176
  - spec/uuid_migrate_helper_spec.rb
173
- has_rdoc: yard