safe_migrations 1.0.2 → 1.0.3

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
  SHA256:
3
- metadata.gz: 49e3b2423b50c3452294c464d3e63097ffe05d4d7ff4e64720795f0e72dc1e6e
4
- data.tar.gz: 43d34ad4e0940dd00458d1945b17f45ece01a831fb53b844efa9f555d8b0f14d
3
+ metadata.gz: f119f92c66cd1a66e53b8fa3f23e1ebe816bb187100fa9c1f50e633042c038ad
4
+ data.tar.gz: 90d6339f1997bd3805fba30b7b252a437e000f00d81b86338276f30d38c5a6e8
5
5
  SHA512:
6
- metadata.gz: c4ab23f2761b651b001a13e05627c3f6ad830d727242a13f1c5baeda0e6c91080850151fe437eff71c652991cb51c1a82ff7edc2a66eef67dc3d6cba02d56e41
7
- data.tar.gz: 9b8e9aa4039ba456bb108ce9331b7343e07dac189ba6a26de45fe4e93caa4acfcafa7062d219249d07af2418e9070c07cf86dd6d7e713e0d023af5cb4b860479
6
+ metadata.gz: 0416fe1c97cddc47a4f5dff0f317395e1979e5e8b2bcf75c8474b98d746760ad15505d2087dcb518982a51b27809161182403ef0934c8163de9575555b2582fb
7
+ data.tar.gz: 5e95b1bc908f4e7c4b1bcbc01d066e55239c689262b8a2ab41efc654734cf4b4d1bef1119b1ba3e229778a1b82352abf25cc335353971c90f812b01d50549b70
@@ -0,0 +1,102 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [ main, master ]
6
+ pull_request:
7
+
8
+ jobs:
9
+ test:
10
+ runs-on: ubuntu-latest
11
+
12
+ strategy:
13
+ fail-fast: false
14
+ matrix:
15
+ ruby: [3.2]
16
+ rails: ["7.0", "7.1"]
17
+ db: [sqlite, postgres, mysql, mariadb]
18
+
19
+ services:
20
+ postgres:
21
+ image: postgres:15
22
+ ports: [5432:5432]
23
+ env:
24
+ POSTGRES_USER: postgres
25
+ POSTGRES_PASSWORD: postgres
26
+ options: >-
27
+ --health-cmd "pg_isready -U postgres"
28
+ --health-interval 5s
29
+ --health-timeout 5s
30
+ --health-retries 5
31
+
32
+ mysql:
33
+ image: mysql:8
34
+ ports: [3306:3306]
35
+ env:
36
+ MYSQL_ROOT_PASSWORD: root
37
+ MYSQL_DATABASE: safe_migrations_test
38
+ options: >-
39
+ --health-cmd="mysqladmin ping -h 127.0.0.1 -proot"
40
+ --health-interval=5s
41
+ --health-timeout=10s
42
+ --health-retries=5
43
+
44
+ mariadb:
45
+ image: mariadb:latest
46
+ ports: [3307:3306]
47
+ env:
48
+ MARIADB_ROOT_PASSWORD: root
49
+ MARIADB_DATABASE: safe_migrations_test
50
+ options: >-
51
+ --health-cmd="healthcheck.sh --connect"
52
+ --health-interval=5s
53
+ --health-timeout=10s
54
+ --health-retries=5
55
+
56
+ env:
57
+ RAILS_ENV: test
58
+ BUNDLE_JOBS: 4
59
+ BUNDLE_RETRY: 3
60
+ POSTGRES_USER: postgres
61
+ POSTGRES_PASSWORD: postgres
62
+ POSTGRES_DB: safe_migrations_test
63
+ MYSQL_ROOT_PASSWORD: root
64
+ MYSQL_DATABASE: safe_migrations_test
65
+
66
+ steps:
67
+ - name: Checkout repository
68
+ uses: actions/checkout@v4
69
+
70
+ - name: Set up Ruby
71
+ uses: ruby/setup-ruby@v1
72
+ with:
73
+ ruby-version: ${{ matrix.ruby }}
74
+ bundler-cache: true
75
+
76
+ - name: Install dependencies
77
+ run: |
78
+ gem install bundler
79
+ bundle add rails -v "~> ${{ matrix.rails }}" --skip-install
80
+ bundle install
81
+
82
+ - name: Prepare database
83
+ run: |
84
+ case ${{ matrix.db }} in
85
+ sqlite)
86
+ export DATABASE_URL="sqlite3::memory:"
87
+ ;;
88
+ postgres)
89
+ export DATABASE_URL="postgres://postgres:postgres@localhost:5432/safe_migrations_test"
90
+ ;;
91
+ mysql)
92
+ export DATABASE_URL="mysql2://root:root@127.0.0.1:3306/safe_migrations_test"
93
+ ;;
94
+ mariadb)
95
+ export DATABASE_URL="mysql2://root:root@127.0.0.1:3307/safe_migrations_test"
96
+ ;;
97
+ esac
98
+
99
+ echo "DATABASE_URL=$DATABASE_URL" >> $GITHUB_ENV
100
+
101
+ - name: Run specs
102
+ run: bundle exec rspec
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- safe_migrations (1.0.2)
4
+ safe_migrations (1.0.3)
5
5
  activerecord (>= 7.0)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -3,6 +3,7 @@
3
3
  G'day, mate! Welcome to **SafeMigrations**, a ripper of a gem that makes your Rails migrations as safe as a kangaroo in the outback. With `safe_` prefixed methods, this gem ensures your database schema changes are idempotent—no dramas if you run 'em twice. Built to play nice with Rails' `CommandRecorder`, it auto-reverses your migrations in the `change` method, so you can crack on with building your app without worrying about dodgy rollbacks.
4
4
 
5
5
  [![Gem Version](https://badge.fury.io/rb/safe_migrations.svg)](https://badge.fury.io/rb/safe_migrations)
6
+ [![CI](https://github.com/moskvin/safe_migrations/actions/workflows/ci.yml/badge.svg)](https://github.com/moskvin/safe_migrations/actions)
6
7
 
7
8
  ## Why SafeMigrations?
8
9
 
@@ -13,7 +14,7 @@ Tired of migrations chucking a wobbly when tables or columns already exist? Safe
13
14
 
14
15
  - **Idempotent Migrations**: `safe_create_table`, `safe_add_column`, `safe_add_index`, and more only run if needed.
15
16
  - **Auto-Reversal**: Integrates with Rails' `CommandRecorder` to invert `safe_` methods (e.g., `safe_create_table` → `safe_drop_table`) in `change` rollbacks.
16
- - **Rails 7.2+ Ready**: Built for ActiveRecord 7.2, with support for modern Ruby 3.2.
17
+ - **Rails 7.0+ Ready**: Built for ActiveRecord 7.0, with support for modern Ruby 3.2.
17
18
  - **Aussie Spirit**: Crafted with a bit of outback grit to keep your migrations smooth as a cold one on a summer arvo.
18
19
 
19
20
  ## Installation
@@ -18,6 +18,8 @@ module SafeMigrations
18
18
  safe_change_column_null
19
19
  safe_add_reference
20
20
  safe_remove_reference
21
+ safe_add_check_constraint
22
+ safe_remove_check_constraint
21
23
  ].freeze
22
24
 
23
25
  SAFE_REVERSIBLE_MAP = {
@@ -31,7 +33,9 @@ module SafeMigrations
31
33
  safe_add_column_and_index: :safe_remove_column_and_index,
32
34
  safe_remove_column_and_index: :safe_add_column_and_index,
33
35
  safe_change_column_null: :safe_change_column_null,
34
- safe_add_reference: :safe_remove_reference
36
+ safe_rename_column: :safe_rename_column,
37
+ safe_add_reference: :safe_remove_reference,
38
+ safe_add_check_constraint: :safe_remove_check_constraint
35
39
  }.freeze
36
40
 
37
41
  def self.apply
@@ -55,12 +59,10 @@ module SafeMigrations
55
59
  [:safe_rename_column, [table, new_col, old_col]]
56
60
  end
57
61
 
58
- # Special case for safe_change_column (needs type tracking)
59
- def invert_safe_change_column(args)
60
- table, column, type, options = args
61
- # If column existed, invert to original type (not tracked, so warn)
62
- # If column was added, invert to remove
63
- [:safe_remove_column, [table, column, type, options]]
62
+ # Special case for safe_change_column_null (needs invert value)
63
+ def invert_safe_change_column_null(args)
64
+ table, column, value = args
65
+ [:safe_change_column_null, [table, column, !value]]
64
66
  end
65
67
  end
66
68
  end
@@ -75,7 +75,25 @@ module SafeMigrations
75
75
  end
76
76
 
77
77
  def safe_remove_reference(table, ref_name, **)
78
- table_exists?(table) && column_exists?(table, "#{ref_name.to_s.singularize}_id") && remove_reference(table, ref_name, **options)
78
+ table_exists?(table) && column_exists?(table, "#{ref_name.to_s.singularize}_id") && remove_reference(table, ref_name, **)
79
+ end
80
+
81
+ def check_constraint_exists?(table_name, **options)
82
+ if !options.key?(:name) && !options.key?(:expression)
83
+ raise ArgumentError, 'At least one of :name or :expression must be supplied'
84
+ end
85
+
86
+ check_constraint_for(table_name, **options).present?
87
+ end
88
+
89
+ def safe_add_check_constraint(table, condition, name:, **)
90
+ return unless table_exists?(table)
91
+
92
+ check_constraint_exists?(table, name:) || add_check_constraint(table, condition, name:, **)
93
+ end
94
+
95
+ def safe_remove_check_constraint(table, condition, name:, **)
96
+ table_exists?(table) && check_constraint_exists?(table, name:) && remove_check_constraint(table, condition, name:, **)
79
97
  end
80
98
  end
81
99
  end
@@ -1,3 +1,3 @@
1
1
  module SafeMigrations
2
- VERSION = '1.0.2'.freeze
2
+ VERSION = '1.0.3'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: safe_migrations
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nikolay Moskvin
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-10-27 00:00:00.000000000 Z
11
+ date: 2025-10-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -90,6 +90,7 @@ executables: []
90
90
  extensions: []
91
91
  extra_rdoc_files: []
92
92
  files:
93
+ - ".github/workflows/ci.yml"
93
94
  - ".gitignore"
94
95
  - ".rspec"
95
96
  - ".rubocop.yml"