webdack-uuid_migration 1.0.1 → 1.0.2

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 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