strong_migrations 0.7.9 → 1.4.4

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
  SHA256:
3
- metadata.gz: c2fb3fbcc5caf98759ebe2ef05a4ef011eca91924e479647d36e2b261baf2c8e
4
- data.tar.gz: '0118bd4e05814f2d531a659a724237080763843bd6cb3ff0b880447348004585'
3
+ metadata.gz: 7444023bd5f0829a289ebc9d222a28f041a4e3789224438f9fd6bffa01fa6668
4
+ data.tar.gz: feb5010616cc8ef6cf36088be7a67bb0d74272cde79d0e9a0a442272bfa92d99
5
5
  SHA512:
6
- metadata.gz: 7a04ea74876b44c645c9cba04c2f7b4932fcc0637eedd78b544dadf40272c84fb0461420e66c49c991c214f5d36b53acbface0347af25cb65c1e9c1251375886
7
- data.tar.gz: 8e97437c5eae3b3aa6508e08c21aa8caf648a03989e621d37c165d1a2412a3cc67784d0923d47e7f814475bb000c6e68e93bf5ce6ef5dbd83f03fc399bb85b4c
6
+ metadata.gz: '0599a3fef628ec724471ef53b7ad7358831e6b638bdd0ca3b7cb79c1b416da6c044793ecca5475f5e602e8a7d1235ced3ff3fda526f31b9c4a56990c8531f9b4'
7
+ data.tar.gz: 6aac91ecb348c6a04c25511adf7df5d3e97823f6b9acdfbfd86bac50c4f5856f15fdcc271f00d0fc6f1e5d2cfdbaf3da5e056b1476aaf9b224e7df89b9737e01
data/CHANGELOG.md CHANGED
@@ -1,3 +1,83 @@
1
+ ## 1.4.4 (2023-03-08)
2
+
3
+ - Fixed `add_foreign_key` with `name` and `column` options with `safe_by_default`
4
+
5
+ ## 1.4.3 (2023-02-19)
6
+
7
+ - Fixed check for `change_column` to account for charset with MySQL and MariaDB
8
+
9
+ ## 1.4.2 (2023-01-29)
10
+
11
+ - Added `alphabetize_schema` option
12
+
13
+ ## 1.4.1 (2023-01-05)
14
+
15
+ - Added support for multiple databases to `target_version`
16
+
17
+ ## 1.4.0 (2022-10-31)
18
+
19
+ - Added check for `add_exclusion_constraint`
20
+ - Added support for `RACK_ENV`
21
+ - Fixed error when `Rails` defined without `Rails.env`
22
+ - Fixed error with `change_column_null` when table does not exist
23
+
24
+ ## 1.3.2 (2022-10-09)
25
+
26
+ - Improved error message for `add_column` with `default: nil` with Postgres 10
27
+
28
+ ## 1.3.1 (2022-09-21)
29
+
30
+ - Fixed check for `add_column` with `default: nil` with Postgres 10
31
+
32
+ ## 1.3.0 (2022-08-30)
33
+
34
+ - Added check for `add_column` with `uuid` type and volatile default value
35
+
36
+ ## 1.2.0 (2022-06-10)
37
+
38
+ - Added check for index corruption with Postgres 14.0 to 14.3
39
+
40
+ ## 1.1.0 (2022-06-08)
41
+
42
+ - Added check for `force` option with `create_join_table`
43
+ - Improved errors for extra arguments
44
+ - Fixed ignoring extra arguments with `safe_by_default`
45
+ - Fixed missing options with `remove_index` and `safe_by_default`
46
+
47
+ ## 1.0.0 (2022-03-21)
48
+
49
+ New safe operations with MySQL and MariaDB
50
+
51
+ - Setting `NOT NULL` on an existing column with strict mode enabled
52
+
53
+ New safe operations with Postgres
54
+
55
+ - Changing between `text` and `citext` when not indexed
56
+ - Changing a `string` column to a `citext` column when not indexed
57
+ - Changing a `citext` column to a `string` column with no `:limit` when not indexed
58
+ - Changing a `cidr` column to an `inet` column
59
+ - Increasing `:precision` of an `interval` or `time` column
60
+
61
+ New unsafe operations with Postgres
62
+
63
+ - Adding a column with a callable default value
64
+ - Decreasing `:precision` of a `datetime` column
65
+ - Decreasing `:limit` of a `timestamptz` column
66
+ - Passing a default value to `change_column_null`
67
+
68
+ Other
69
+
70
+ - Added experimental support for lock timeout retries
71
+ - Added `target_sql_mode` option
72
+ - Added error for `change_column_null` with default value with `safe_by_default` option
73
+ - Fixed instructions for `remove_columns` with options
74
+ - Dropped support for Postgres < 10, MySQL < 5.7, and MariaDB < 10.2
75
+
76
+ ## 0.8.0 (2022-02-09)
77
+
78
+ - Fixed error with versioned schema with Active Record 7.0.2+
79
+ - Dropped support for Ruby < 2.6 and Active Record < 5.2
80
+
1
81
  ## 0.7.9 (2021-12-15)
2
82
 
3
83
  - Fixed error with multiple databases with Active Record 7
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2013 Bob Remeika and David Waller, 2015-2021 Andrew Kane
1
+ Copyright (c) 2013 Bob Remeika and David Waller, 2015-2022 Andrew Kane
2
2
 
3
3
  MIT License
4
4
 
data/README.md CHANGED
@@ -4,7 +4,7 @@ Catch unsafe migrations in development
4
4
 
5
5
  &nbsp;&nbsp;✓&nbsp;&nbsp;Detects potentially dangerous operations<br />&nbsp;&nbsp;✓&nbsp;&nbsp;Prevents them from running by default<br />&nbsp;&nbsp;✓&nbsp;&nbsp;Provides instructions on safer ways to do what you want
6
6
 
7
- Supports for PostgreSQL, MySQL, and MariaDB
7
+ Supports PostgreSQL, MySQL, and MariaDB
8
8
 
9
9
  :tangerine: Battle-tested at [Instacart](https://www.instacart.com/opensource)
10
10
 
@@ -15,7 +15,7 @@ Supports for PostgreSQL, MySQL, and MariaDB
15
15
  Add this line to your application’s Gemfile:
16
16
 
17
17
  ```ruby
18
- gem 'strong_migrations'
18
+ gem "strong_migrations"
19
19
  ```
20
20
 
21
21
  And run:
@@ -67,7 +67,6 @@ Potentially dangerous operations:
67
67
  - [renaming a table](#renaming-a-table)
68
68
  - [creating a table with the force option](#creating-a-table-with-the-force-option)
69
69
  - [adding a check constraint](#adding-a-check-constraint)
70
- - [setting NOT NULL on an existing column](#setting-not-null-on-an-existing-column)
71
70
  - [executing SQL directly](#executing-SQL-directly)
72
71
 
73
72
  Postgres-specific checks:
@@ -75,7 +74,9 @@ Postgres-specific checks:
75
74
  - [adding an index non-concurrently](#adding-an-index-non-concurrently)
76
75
  - [adding a reference](#adding-a-reference)
77
76
  - [adding a foreign key](#adding-a-foreign-key)
77
+ - [adding an exclusion constraint](#adding-an-exclusion-constraint)
78
78
  - [adding a json column](#adding-a-json-column)
79
+ - [setting NOT NULL on an existing column](#setting-not-null-on-an-existing-column)
79
80
 
80
81
  Best practices:
81
82
 
@@ -107,7 +108,7 @@ end
107
108
  end
108
109
  ```
109
110
 
110
- 2. Deploy code
111
+ 2. Deploy the code
111
112
  3. Write a migration to remove the column (wrap in `safety_assured` block)
112
113
 
113
114
  ```ruby
@@ -118,7 +119,8 @@ end
118
119
  end
119
120
  ```
120
121
 
121
- 4. Deploy and run migration
122
+ 4. Deploy and run the migration
123
+ 5. Remove the line added in step 1
122
124
 
123
125
  ### Adding a column with a default value
124
126
 
@@ -134,7 +136,7 @@ class AddSomeColumnToUsers < ActiveRecord::Migration[7.0]
134
136
  end
135
137
  ```
136
138
 
137
- In Postgres 11+, MySQL 8.0.12+, and MariaDB 10.3.2+, this no longer requires a table rewrite and is safe.
139
+ In Postgres 11+, MySQL 8.0.12+, and MariaDB 10.3.2+, this no longer requires a table rewrite and is safe (except for volatile functions like `gen_random_uuid()`).
138
140
 
139
141
  #### Good
140
142
 
@@ -203,19 +205,26 @@ class ChangeSomeColumnType < ActiveRecord::Migration[7.0]
203
205
  end
204
206
  ```
205
207
 
206
- A few changes don’t require a table rewrite (and are safe) in Postgres:
208
+ Some changes don’t require a table rewrite and are safe in Postgres:
207
209
 
208
- - Increasing the length limit of a `varchar` column (or removing the limit)
209
- - Changing a `varchar` column to a `text` column
210
- - Changing a `text` column to a `varchar` column with no length limit
211
- - Increasing the precision of a `decimal` or `numeric` column
212
- - Making a `decimal` or `numeric` column unconstrained
213
- - Changing between `timestamp` and `timestamptz` columns when session time zone is UTC in Postgres 12+
210
+ Type | Safe Changes
211
+ --- | ---
212
+ `cidr` | Changing to `inet`
213
+ `citext` | Changing to `text` if not indexed, changing to `string` with no `:limit` if not indexed
214
+ `datetime` | Increasing or removing `:precision`, changing to `timestamptz` when session time zone is UTC in Postgres 12+
215
+ `decimal` | Increasing `:precision` at same `:scale`, removing `:precision` and `:scale`
216
+ `interval` | Increasing or removing `:precision`
217
+ `numeric` | Increasing `:precision` at same `:scale`, removing `:precision` and `:scale`
218
+ `string` | Increasing or removing `:limit`, changing to `text`, changing `citext` if not indexed
219
+ `text` | Changing to `string` with no `:limit`, changing to `citext` if not indexed
220
+ `time` | Increasing or removing `:precision`
221
+ `timestamptz` | Increasing or removing `:limit`, changing to `datetime` when session time zone is UTC in Postgres 12+
214
222
 
215
- And a few in MySQL and MariaDB:
223
+ And some in MySQL and MariaDB:
216
224
 
217
- - Increasing the length limit of a `varchar` column from under 255 up to 255
218
- - Increasing the length limit of a `varchar` column from over 255 to the max limit
225
+ Type | Safe Changes
226
+ --- | ---
227
+ `string` | Increasing `:limit` from under 63 up to 63, increasing `:limit` from over 63 to the max (the threshold can be different if using an encoding other than `utf8mb4` - for instance, it’s 85 for `utf8mb3` and 255 for `latin1`)
219
228
 
220
229
  #### Good
221
230
 
@@ -352,86 +361,6 @@ end
352
361
 
353
362
  [Let us know](https://github.com/ankane/strong_migrations/issues/new) if you have a safe way to do this (check constraints can be added with `NOT ENFORCED`, but enforcing blocks writes).
354
363
 
355
- ### Setting NOT NULL on an existing column
356
-
357
- :turtle: Safe by default available
358
-
359
- #### Bad
360
-
361
- Setting `NOT NULL` on an existing column blocks reads and writes while every row is checked.
362
-
363
- ```ruby
364
- class SetSomeColumnNotNull < ActiveRecord::Migration[7.0]
365
- def change
366
- change_column_null :users, :some_column, false
367
- end
368
- end
369
- ```
370
-
371
- #### Good - Postgres
372
-
373
- Instead, add a check constraint.
374
-
375
- For Rails 6.1, use:
376
-
377
- ```ruby
378
- class SetSomeColumnNotNull < ActiveRecord::Migration[7.0]
379
- def change
380
- add_check_constraint :users, "some_column IS NOT NULL", name: "users_some_column_null", validate: false
381
- end
382
- end
383
- ```
384
-
385
- For Rails < 6.1, use:
386
-
387
- ```ruby
388
- class SetSomeColumnNotNull < ActiveRecord::Migration[6.0]
389
- def change
390
- safety_assured do
391
- execute 'ALTER TABLE "users" ADD CONSTRAINT "users_some_column_null" CHECK ("some_column" IS NOT NULL) NOT VALID'
392
- end
393
- end
394
- end
395
- ```
396
-
397
- Then validate it in a separate migration. A `NOT NULL` check constraint is [functionally equivalent](https://medium.com/doctolib/adding-a-not-null-constraint-on-pg-faster-with-minimal-locking-38b2c00c4d1c) to setting `NOT NULL` on the column (but it won’t show up in `schema.rb` in Rails < 6.1). In Postgres 12+, once the check constraint is validated, you can safely set `NOT NULL` on the column and drop the check constraint.
398
-
399
- For Rails 6.1, use:
400
-
401
- ```ruby
402
- class ValidateSomeColumnNotNull < ActiveRecord::Migration[7.0]
403
- def change
404
- validate_check_constraint :users, name: "users_some_column_null"
405
-
406
- # in Postgres 12+, you can then safely set NOT NULL on the column
407
- change_column_null :users, :some_column, false
408
- remove_check_constraint :users, name: "users_some_column_null"
409
- end
410
- end
411
- ```
412
-
413
- For Rails < 6.1, use:
414
-
415
- ```ruby
416
- class ValidateSomeColumnNotNull < ActiveRecord::Migration[6.0]
417
- def change
418
- safety_assured do
419
- execute 'ALTER TABLE "users" VALIDATE CONSTRAINT "users_some_column_null"'
420
- end
421
-
422
- # in Postgres 12+, you can then safely set NOT NULL on the column
423
- change_column_null :users, :some_column, false
424
- safety_assured do
425
- execute 'ALTER TABLE "users" DROP CONSTRAINT "users_some_column_null"'
426
- end
427
- end
428
- end
429
- ```
430
-
431
- #### Good - MySQL and MariaDB
432
-
433
- [Let us know](https://github.com/ankane/strong_migrations/issues/new) if you have a safe way to do this.
434
-
435
364
  ### Executing SQL directly
436
365
 
437
366
  Strong Migrations can’t ensure safety for raw SQL statements. Make really sure that what you’re doing is safe, then use:
@@ -540,9 +469,7 @@ end
540
469
 
541
470
  #### Good
542
471
 
543
- Add the foreign key without validating existing rows, then validate them in a separate migration.
544
-
545
- For Rails 5.2+, use:
472
+ Add the foreign key without validating existing rows:
546
473
 
547
474
  ```ruby
548
475
  class AddForeignKeyOnUsers < ActiveRecord::Migration[7.0]
@@ -552,7 +479,7 @@ class AddForeignKeyOnUsers < ActiveRecord::Migration[7.0]
552
479
  end
553
480
  ```
554
481
 
555
- Then:
482
+ Then validate them in a separate migration.
556
483
 
557
484
  ```ruby
558
485
  class ValidateForeignKeyOnUsers < ActiveRecord::Migration[7.0]
@@ -562,30 +489,24 @@ class ValidateForeignKeyOnUsers < ActiveRecord::Migration[7.0]
562
489
  end
563
490
  ```
564
491
 
565
- For Rails < 5.2, use:
492
+ ### Adding an exclusion constraint
566
493
 
567
- ```ruby
568
- class AddForeignKeyOnUsers < ActiveRecord::Migration[5.1]
569
- def change
570
- safety_assured do
571
- execute 'ALTER TABLE "users" ADD CONSTRAINT "fk_rails_c1e9b98e31" FOREIGN KEY ("order_id") REFERENCES "orders" ("id") NOT VALID'
572
- end
573
- end
574
- end
575
- ```
494
+ #### Bad
576
495
 
577
- Then:
496
+ In Postgres, adding an exclusion constraint blocks reads and writes while every row is checked.
578
497
 
579
498
  ```ruby
580
- class ValidateForeignKeyOnUsers < ActiveRecord::Migration[5.1]
499
+ class AddExclusionContraint < ActiveRecord::Migration[7.1]
581
500
  def change
582
- safety_assured do
583
- execute 'ALTER TABLE "users" VALIDATE CONSTRAINT "fk_rails_c1e9b98e31"'
584
- end
501
+ add_exclusion_constraint :users, "number WITH =", using: :gist
585
502
  end
586
503
  end
587
504
  ```
588
505
 
506
+ #### Good
507
+
508
+ [Let us know](https://github.com/ankane/strong_migrations/issues/new) if you have a safe way to do this (exclusion constraints cannot be marked `NOT VALID`).
509
+
589
510
  ### Adding a json column
590
511
 
591
512
  #### Bad
@@ -612,6 +533,82 @@ class AddPropertiesToUsers < ActiveRecord::Migration[7.0]
612
533
  end
613
534
  ```
614
535
 
536
+ ### Setting NOT NULL on an existing column
537
+
538
+ :turtle: Safe by default available
539
+
540
+ #### Bad
541
+
542
+ In Postgres, setting `NOT NULL` on an existing column blocks reads and writes while every row is checked.
543
+
544
+ ```ruby
545
+ class SetSomeColumnNotNull < ActiveRecord::Migration[7.0]
546
+ def change
547
+ change_column_null :users, :some_column, false
548
+ end
549
+ end
550
+ ```
551
+
552
+ #### Good
553
+
554
+ Instead, add a check constraint.
555
+
556
+ For Rails 6.1, use:
557
+
558
+ ```ruby
559
+ class SetSomeColumnNotNull < ActiveRecord::Migration[7.0]
560
+ def change
561
+ add_check_constraint :users, "some_column IS NOT NULL", name: "users_some_column_null", validate: false
562
+ end
563
+ end
564
+ ```
565
+
566
+ For Rails < 6.1, use:
567
+
568
+ ```ruby
569
+ class SetSomeColumnNotNull < ActiveRecord::Migration[6.0]
570
+ def change
571
+ safety_assured do
572
+ execute 'ALTER TABLE "users" ADD CONSTRAINT "users_some_column_null" CHECK ("some_column" IS NOT NULL) NOT VALID'
573
+ end
574
+ end
575
+ end
576
+ ```
577
+
578
+ Then validate it in a separate migration. A `NOT NULL` check constraint is [functionally equivalent](https://medium.com/doctolib/adding-a-not-null-constraint-on-pg-faster-with-minimal-locking-38b2c00c4d1c) to setting `NOT NULL` on the column (but it won’t show up in `schema.rb` in Rails < 6.1). In Postgres 12+, once the check constraint is validated, you can safely set `NOT NULL` on the column and drop the check constraint.
579
+
580
+ For Rails 6.1, use:
581
+
582
+ ```ruby
583
+ class ValidateSomeColumnNotNull < ActiveRecord::Migration[7.0]
584
+ def change
585
+ validate_check_constraint :users, name: "users_some_column_null"
586
+
587
+ # in Postgres 12+, you can then safely set NOT NULL on the column
588
+ change_column_null :users, :some_column, false
589
+ remove_check_constraint :users, name: "users_some_column_null"
590
+ end
591
+ end
592
+ ```
593
+
594
+ For Rails < 6.1, use:
595
+
596
+ ```ruby
597
+ class ValidateSomeColumnNotNull < ActiveRecord::Migration[6.0]
598
+ def change
599
+ safety_assured do
600
+ execute 'ALTER TABLE "users" VALIDATE CONSTRAINT "users_some_column_null"'
601
+ end
602
+
603
+ # in Postgres 12+, you can then safely set NOT NULL on the column
604
+ change_column_null :users, :some_column, false
605
+ safety_assured do
606
+ execute 'ALTER TABLE "users" DROP CONSTRAINT "users_some_column_null"'
607
+ end
608
+ end
609
+ end
610
+ ```
611
+
615
612
  ### Keeping non-unique indexes to three columns or less
616
613
 
617
614
  #### Bad
@@ -703,7 +700,7 @@ Disable specific checks with:
703
700
  StrongMigrations.disable_check(:add_index)
704
701
  ```
705
702
 
706
- Check the [source code](https://github.com/ankane/strong_migrations/blob/master/lib/strong_migrations.rb) for the list of keys.
703
+ Check the [source code](https://github.com/ankane/strong_migrations/blob/master/lib/strong_migrations/error_messages.rb) for the list of keys.
707
704
 
708
705
  ## Down Migrations / Rollbacks
709
706
 
@@ -721,7 +718,7 @@ To customize specific messages, create an initializer with:
721
718
  StrongMigrations.error_messages[:add_column_default] = "Your custom instructions"
722
719
  ```
723
720
 
724
- Check the [source code](https://github.com/ankane/strong_migrations/blob/master/lib/strong_migrations.rb) for the list of keys.
721
+ Check the [source code](https://github.com/ankane/strong_migrations/blob/master/lib/strong_migrations/error_messages.rb) for the list of keys.
725
722
 
726
723
  ## Migration Timeouts
727
724
 
@@ -743,6 +740,25 @@ ALTER ROLE myuser SET statement_timeout = '1h';
743
740
 
744
741
  Note: If you use PgBouncer in transaction mode, you must set timeouts on the database user.
745
742
 
743
+ ## Lock Timeout Retries [experimental]
744
+
745
+ There’s the option to automatically retry statements when the lock timeout is reached. Here’s how it works:
746
+
747
+ - If a lock timeout happens outside a transaction, the statement is retried
748
+ - If it happens inside the DDL transaction, the entire migration is retried (only applicable to Postgres)
749
+
750
+ Add to `config/initializers/strong_migrations.rb`:
751
+
752
+ ```ruby
753
+ StrongMigrations.lock_timeout_retries = 3
754
+ ```
755
+
756
+ Set the delay between retries with:
757
+
758
+ ```ruby
759
+ StrongMigrations.lock_timeout_retry_delay = 10.seconds
760
+ ```
761
+
746
762
  ## App Timeouts
747
763
 
748
764
  We recommend adding timeouts to `config/database.yml` to prevent connections from hanging and individual queries from taking up too many resources in controllers, jobs, the Rails console, and other places.
@@ -808,6 +824,12 @@ The major version works well for Postgres, while the full version is recommended
808
824
 
809
825
  For safety, this option only affects development and test environments. In other environments, the actual server version is always used.
810
826
 
827
+ If your app has multiple databases with different versions, with Rails 6.1+, you can use:
828
+
829
+ ```ruby
830
+ StrongMigrations.target_version = {primary: 13, catalog: 15}
831
+ ```
832
+
811
833
  ## Analyze Tables
812
834
 
813
835
  Analyze tables automatically (to update planner statistics) after an index is added. Create an initializer with:
@@ -818,23 +840,18 @@ StrongMigrations.auto_analyze = true
818
840
 
819
841
  ## Faster Migrations
820
842
 
821
- Only dump the schema when adding a new migration. If you use Git, add to the end of your `Rakefile`:
843
+ Only dump the schema when adding a new migration. If you use Git, add to `config/environments/development.rb`:
822
844
 
823
845
  ```rb
824
- task :faster_migrations do
825
- ActiveRecord::Base.dump_schema_after_migration = Rails.env.development? &&
826
- `git status db/migrate/ --porcelain`.present?
827
- end
828
-
829
- task "db:migrate": "faster_migrations"
846
+ config.active_record.dump_schema_after_migration = `git status db/migrate/ --porcelain`.present?
830
847
  ```
831
848
 
832
849
  ## Schema Sanity
833
850
 
834
- Columns can flip order in `db/schema.rb` when you have multiple developers. One way to prevent this is to [alphabetize them](https://www.pgrs.net/2008/03/12/alphabetize-schema-rb-columns/). Add to the end of your `Rakefile`:
851
+ Columns can flip order in `db/schema.rb` when you have multiple developers. One way to prevent this is to [alphabetize them](https://www.pgrs.net/2008/03/12/alphabetize-schema-rb-columns/). Add to `config/initializers/strong_migrations.rb`:
835
852
 
836
853
  ```ruby
837
- task "db:schema:dump": "strong_migrations:alphabetize_columns"
854
+ StrongMigrations.alphabetize_schema = true
838
855
  ```
839
856
 
840
857
  ## Permissions
@@ -0,0 +1,77 @@
1
+ module StrongMigrations
2
+ module Adapters
3
+ class AbstractAdapter
4
+ def initialize(checker)
5
+ @checker = checker
6
+ end
7
+
8
+ def name
9
+ "Unknown"
10
+ end
11
+
12
+ def min_version
13
+ end
14
+
15
+ def set_statement_timeout(timeout)
16
+ raise StrongMigrations::Error, "Statement timeout not supported for this database"
17
+ end
18
+
19
+ def set_lock_timeout(timeout)
20
+ raise StrongMigrations::Error, "Lock timeout not supported for this database"
21
+ end
22
+
23
+ def check_lock_timeout(limit)
24
+ # do nothing
25
+ end
26
+
27
+ def add_column_default_safe?
28
+ false
29
+ end
30
+
31
+ def change_type_safe?(table, column, type, options, existing_column, existing_type)
32
+ false
33
+ end
34
+
35
+ def rewrite_blocks
36
+ "reads and writes"
37
+ end
38
+
39
+ private
40
+
41
+ def connection
42
+ @checker.send(:connection)
43
+ end
44
+
45
+ def select_all(statement)
46
+ connection.select_all(statement)
47
+ end
48
+
49
+ def target_version(target_version)
50
+ target_version ||= StrongMigrations.target_version
51
+ version =
52
+ if target_version && StrongMigrations.developer_env?
53
+ if target_version.is_a?(Hash)
54
+ # Active Record 6.0 supports multiple databases
55
+ # but connection.pool.spec.name always returns "primary"
56
+ # in migrations with rails db:migrate
57
+ if ActiveRecord::VERSION::STRING.to_f < 6.1
58
+ # error class is not shown in db:migrate output so ensure message is descriptive
59
+ raise StrongMigrations::Error, "StrongMigrations.target_version does not support multiple databases for Active Record < 6.1"
60
+ end
61
+
62
+ db_config_name = connection.pool.db_config.name
63
+ target_version.stringify_keys.fetch(db_config_name) do
64
+ # error class is not shown in db:migrate output so ensure message is descriptive
65
+ raise StrongMigrations::Error, "StrongMigrations.target_version is not configured for :#{db_config_name} database"
66
+ end.to_s
67
+ else
68
+ target_version.to_s
69
+ end
70
+ else
71
+ yield
72
+ end
73
+ Gem::Version.new(version)
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,32 @@
1
+ module StrongMigrations
2
+ module Adapters
3
+ class MariaDBAdapter < MySQLAdapter
4
+ def name
5
+ "MariaDB"
6
+ end
7
+
8
+ def min_version
9
+ "10.2"
10
+ end
11
+
12
+ def server_version
13
+ @server_version ||= begin
14
+ target_version(StrongMigrations.target_mariadb_version) do
15
+ select_all("SELECT VERSION()").first["VERSION()"].split("-").first
16
+ end
17
+ end
18
+ end
19
+
20
+ def set_statement_timeout(timeout)
21
+ # fix deprecation warning with Active Record 7.1
22
+ timeout = timeout.value if timeout.is_a?(ActiveSupport::Duration)
23
+
24
+ select_all("SET max_statement_time = #{connection.quote(timeout)}")
25
+ end
26
+
27
+ def add_column_default_safe?
28
+ server_version >= Gem::Version.new("10.3.2")
29
+ end
30
+ end
31
+ end
32
+ end