postgresql_adapter_extensions 0.1.0 → 1.1.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.
- checksums.yaml +4 -4
- data/.github/workflows/docs.yml +31 -0
- data/.github/workflows/main.yml +3 -2
- data/CHANGELOG.md +34 -0
- data/Gemfile.lock +1 -1
- data/README.md +190 -0
- data/bin/setup_postgresql.sh +41 -0
- data/lib/postgresql_adapter_extensions/base.rb +13 -1
- data/lib/postgresql_adapter_extensions/command_recorder.rb +121 -0
- data/lib/postgresql_adapter_extensions/sequence_methods.rb +179 -0
- data/lib/postgresql_adapter_extensions/version.rb +1 -1
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: db065d0487684a0647e17b2db8e5ef1f2131a6b15a7b0316d1fcd9856e46c07a
|
4
|
+
data.tar.gz: bd6cb683c11d9e27c1225d5c29e638adf6f14b96b1f7c3bf1803d96944383478
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 986daa750a1e762d710dbda29ba587ea8c76a8894f2c7ff346b2d64dc974e4c3fe54098e9549646d584c8b8c9efb5ebe00e0581a3d00c76dc3be253e7d5af9c5
|
7
|
+
data.tar.gz: 8dc3a0571ff79ce9dd058ab3c22e0876c07cd748ddc0b4c42b5f642e51869aaddc353b144be5f1feff165cbe967bacaf08f0e70dbe0828fba8ffe8fa5703c5fc
|
@@ -0,0 +1,31 @@
|
|
1
|
+
name: Publish Documentation to GitHub Pages
|
2
|
+
on:
|
3
|
+
push:
|
4
|
+
branches:
|
5
|
+
- main
|
6
|
+
jobs:
|
7
|
+
build:
|
8
|
+
name: Publish Documentation to GitHub Pages ${{ matrix.ruby }}
|
9
|
+
runs-on: ubuntu-latest
|
10
|
+
permissions:
|
11
|
+
contents: write
|
12
|
+
strategy:
|
13
|
+
matrix:
|
14
|
+
ruby:
|
15
|
+
- "3.3.7"
|
16
|
+
steps:
|
17
|
+
- name: Checkout Repository
|
18
|
+
uses: actions/checkout@v3
|
19
|
+
- name: Set Up Ruby
|
20
|
+
uses: ruby/setup-ruby@v1
|
21
|
+
with:
|
22
|
+
ruby-version: ${{ matrix.ruby }}
|
23
|
+
- name: Install Dependencies
|
24
|
+
run: gem install yard
|
25
|
+
- name: Generate Documentation
|
26
|
+
run: yardoc
|
27
|
+
- name: Deploy to GitHub Pages
|
28
|
+
uses: peaceiris/actions-gh-pages@v4.0.0
|
29
|
+
with:
|
30
|
+
github_token: ${{ secrets.GITHUB_TOKEN }}
|
31
|
+
publish_dir: ./doc
|
data/.github/workflows/main.yml
CHANGED
@@ -9,8 +9,6 @@ jobs:
|
|
9
9
|
name: Ruby ${{ matrix.ruby }}
|
10
10
|
env:
|
11
11
|
RAILS_ENV: test
|
12
|
-
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
|
13
|
-
DATABASE_URL: "postgres://rails:password@localhost:5432/rails_test"
|
14
12
|
strategy:
|
15
13
|
matrix:
|
16
14
|
ruby:
|
@@ -24,6 +22,7 @@ jobs:
|
|
24
22
|
POSTGRES_DB: rails_test
|
25
23
|
POSTGRES_USER: rails
|
26
24
|
POSTGRES_PASSWORD: password
|
25
|
+
DATABASE_URL: "postgres://rails:password@localhost:5432/rails_test"
|
27
26
|
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
|
28
27
|
steps:
|
29
28
|
- name: Checkout code
|
@@ -40,3 +39,5 @@ jobs:
|
|
40
39
|
run: bundle exec rake
|
41
40
|
- name: Publish code coverage
|
42
41
|
uses: paambaati/codeclimate-action@v9.0.0
|
42
|
+
env:
|
43
|
+
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,37 @@
|
|
1
|
+
## [1.1.0](https://github.com/shivam091/postgresql_adapter_extensions/compare/v1.0.0...v1.1.0) - 2025-03-21
|
2
|
+
|
3
|
+
### What's new
|
4
|
+
- Extended `ActiveRecord::Migration::CommandRecorder` to support PostgreSQL sequence-related commands.
|
5
|
+
- Added `create_sequence` method to record sequence creation in migrations.
|
6
|
+
- Added `alter_sequence` method to record sequence alterations (irreversible).
|
7
|
+
- Added `drop_sequence` method to record sequence deletions (irreversible).
|
8
|
+
- Implemented `invert_create_sequence` to allow rollback by dropping the sequence.
|
9
|
+
- Implemented `invert_alter_sequence` and `invert_drop_sequence` to raise `ActiveRecord::IrreversibleMigration`.
|
10
|
+
|
11
|
+
### Notes
|
12
|
+
- `create_sequence` can be reversed by dropping the sequence.
|
13
|
+
- `alter_sequence` and `drop_sequence` are irreversible operations.
|
14
|
+
|
15
|
+
----------
|
16
|
+
|
17
|
+
## [1.0.0](https://github.com/shivam091/postgresql_adapter_extensions/compare/v0.1.0...v1.0.0) - 2025-03-12
|
18
|
+
|
19
|
+
### What's new
|
20
|
+
|
21
|
+
- Added `create_sequence` method
|
22
|
+
|
23
|
+
Allows creating PostgreSQL sequences with customizable options such as start value, increment step, min/max values, caching, cycling, and ownership.
|
24
|
+
|
25
|
+
- Added `alter_sequence` method
|
26
|
+
|
27
|
+
Enables modifying existing PostgreSQL sequences, supporting changes to increment steps, restart values, min/max limits, caching, cycling behavior, and ownership.
|
28
|
+
|
29
|
+
- Added `drop_sequence` method
|
30
|
+
|
31
|
+
Provides functionality to remove a PostgreSQL sequence with optional IF EXISTS and CASCADE/RESTRICT behaviors to manage dependencies.
|
32
|
+
|
33
|
+
----------
|
34
|
+
|
1
35
|
## 0.1.0 - 2025-03-11
|
2
36
|
|
3
37
|
### Initial release
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,30 @@
|
|
1
1
|
# PostgreSQLAdapterExtensions
|
2
|
+
|
3
|
+
PostgreSQL Adapter Extensions for ActiveRecord.
|
4
|
+
|
5
|
+
`postgresql_adapter_extensions` is a Ruby gem that extends the `ActiveRecord::ConnectionAdapters::PostgreSQLAdapter`
|
6
|
+
to add additional sequence-related methods for managing PostgreSQL sequences in a Rails application.
|
7
|
+
|
8
|
+
[](https://github.com/shivam091/postgresql_adapter_extensions/actions/workflows/main.yml)
|
9
|
+
[](https://badge.fury.io/rb/postgresql_adapter_extensions)
|
10
|
+
[](http://rubygems.org/gems/postgresql_adapter_extensions)
|
11
|
+
[](https://codeclimate.com/github/shivam091/postgresql_adapter_extensions/maintainability)
|
12
|
+
[](https://codeclimate.com/github/shivam091/postgresql_adapter_extensions/test_coverage)
|
13
|
+
[](https://github.com/shivam091/postgresql_adapter_extensions/blob/main/LICENSE.md)
|
14
|
+
|
15
|
+
[Harshal V. Ladhe, Master of Computer Science.](https://shivam091.github.io)
|
16
|
+
|
17
|
+
## Introduction
|
18
|
+
|
19
|
+
This gem provides easy-to-use methods to create, alter, and drop sequences, which can be useful for handling
|
20
|
+
auto-incrementing IDs and other sequence-based logic in your database.
|
21
|
+
|
22
|
+
## Minimum Requirements
|
23
|
+
|
24
|
+
* Ruby 3.3+ ([Download Ruby](https://www.ruby-lang.org/en/downloads/branches/))
|
25
|
+
* Rails 8.0.0+ ([RubyGems - Rails Versions](https://rubygems.org/gems/rails/versions))
|
26
|
+
* ActiveRecord 8.0.0+ (comes with Rails)
|
27
|
+
|
2
28
|
## Installation
|
3
29
|
|
4
30
|
To use `postgresql_adapter_extensions` in your Rails application, add the following line to your Gemfile:
|
@@ -15,6 +41,170 @@ Or otherwise simply install it yourself as:
|
|
15
41
|
|
16
42
|
`$ gem install postgresql_adapter_extensions`
|
17
43
|
|
44
|
+
## Usage
|
45
|
+
|
46
|
+
### create_sequence
|
47
|
+
|
48
|
+
The `create_sequence` method allows you to create a new sequence in your PostgreSQL database with customizable options. A sequence is typically used to auto-generate unique values for primary keys or other incrementing columns.
|
49
|
+
|
50
|
+
```ruby
|
51
|
+
create_sequence(name, options = {})
|
52
|
+
```
|
53
|
+
|
54
|
+
**Create a sequence with default options:**
|
55
|
+
|
56
|
+
```ruby
|
57
|
+
create_sequence(:order_id_seq)
|
58
|
+
```
|
59
|
+
|
60
|
+
**Create a sequence starting from 1000 with an increment of 5:**
|
61
|
+
|
62
|
+
```ruby
|
63
|
+
create_sequence(:order_id_seq, start: 1000, increment_by: 5)
|
64
|
+
```
|
65
|
+
|
66
|
+
**Create a cyclic sequence with a maximum value of 5000:**
|
67
|
+
|
68
|
+
```ruby
|
69
|
+
create_sequence(:order_id_seq, cycle: true, maxvalue: 5000)
|
70
|
+
```
|
71
|
+
|
72
|
+
**Create a sequence owned by a specific table and column:**
|
73
|
+
|
74
|
+
```ruby
|
75
|
+
create_sequence(:order_id_seq, owned_by: "orders.id")
|
76
|
+
```
|
77
|
+
|
78
|
+
### alter_sequence
|
79
|
+
|
80
|
+
The `alter_sequence` method allows you to modify an existing sequence in your PostgreSQL database.
|
81
|
+
You can change various attributes of the sequence, such as its increment, start value, maximum value,
|
82
|
+
cycle behavior, and ownership.
|
83
|
+
|
84
|
+
```ruby
|
85
|
+
alter_sequence(name, options = {})
|
86
|
+
```
|
87
|
+
|
88
|
+
**Modify the increment value of a sequence:**
|
89
|
+
|
90
|
+
```ruby
|
91
|
+
alter_sequence(:order_id_seq, increment_by: 10)
|
92
|
+
```
|
93
|
+
|
94
|
+
**Restart a sequence at a specific value:**
|
95
|
+
|
96
|
+
```ruby
|
97
|
+
alter_sequence(:order_id_seq, restart_with: 2000)
|
98
|
+
```
|
99
|
+
|
100
|
+
**Set a minimum and maximum value for a sequence:**
|
101
|
+
|
102
|
+
```ruby
|
103
|
+
alter_sequence(:order_id_seq, minvalue: 500, maxvalue: 10000)
|
104
|
+
```
|
105
|
+
|
106
|
+
**Make a sequence cycle when it reaches the maximum value:**
|
107
|
+
|
108
|
+
```ruby
|
109
|
+
alter_sequence(:order_id_seq, cycle: true)
|
110
|
+
```
|
111
|
+
|
112
|
+
**Remove the cycle behavior from a sequence:**
|
113
|
+
|
114
|
+
```ruby
|
115
|
+
alter_sequence(:order_id_seq, cycle: false)
|
116
|
+
```
|
117
|
+
|
118
|
+
**Change the owner of a sequence to a specific table column:**
|
119
|
+
|
120
|
+
```ruby
|
121
|
+
alter_sequence(:order_id_seq, owned_by: "orders.id")
|
122
|
+
```
|
123
|
+
|
124
|
+
This method provides flexibility in managing sequences dynamically in your Rails application,
|
125
|
+
ensuring that sequence-related database behavior can be modified as needed.
|
126
|
+
|
127
|
+
### drop_sequence
|
128
|
+
|
129
|
+
The `drop_sequence` method allows you to drop an existing sequence from your PostgreSQL database, with options to control its behavior.
|
130
|
+
|
131
|
+
```ruby
|
132
|
+
drop_sequence(name, options = {})
|
133
|
+
```
|
134
|
+
|
135
|
+
**Drop a sequence without additional options:**
|
136
|
+
|
137
|
+
```ruby
|
138
|
+
drop_sequence(:order_id_seq)
|
139
|
+
```
|
140
|
+
|
141
|
+
**Drop a sequence if it exists:**
|
142
|
+
|
143
|
+
```ruby
|
144
|
+
drop_sequence(:order_id_seq, if_exists: true)
|
145
|
+
```
|
146
|
+
|
147
|
+
**Drop a sequence and all dependent objects:**
|
148
|
+
|
149
|
+
```ruby
|
150
|
+
drop_sequence(:order_id_seq, drop_behavior: :cascade)
|
151
|
+
```
|
152
|
+
|
153
|
+
**Drop a sequence but prevent deletion if dependencies exist:**
|
154
|
+
|
155
|
+
```ruby
|
156
|
+
drop_sequence(:order_id_seq, drop_behavior: :restrict)
|
157
|
+
```
|
158
|
+
|
159
|
+
## PostgreSQL Setup for Contributors
|
160
|
+
|
161
|
+
If you're contributing to this gem and need to set up PostgreSQL for local development or testing,
|
162
|
+
you can use the provided setup script. This script will help you create the necessary PostgreSQL
|
163
|
+
user and database for testing.
|
164
|
+
|
165
|
+
### Running the Setup Script
|
166
|
+
|
167
|
+
1. **Clone the repository** and navigate to the root directory of the gem.
|
168
|
+
2. Make sure you have PostgreSQL installed and running on your machine.
|
169
|
+
3. Run the script using the following command:
|
170
|
+
|
171
|
+
`$ ./bin/setup_postgresql.sh`
|
172
|
+
|
173
|
+
By default, the script will use the following values unless environment variables are set:
|
174
|
+
|
175
|
+
1. Database Name: `rails_test`
|
176
|
+
2. Username: `rails`
|
177
|
+
3. Password: `password`
|
178
|
+
|
179
|
+
4. If you want to override these defaults, set the environment variables before running the script:
|
180
|
+
|
181
|
+
`$ POSTGRES_DB=rails_test POSTGRES_USER=rails POSTGRES_PASSWORD=password ./bin/setup_postgresql.sh`
|
182
|
+
|
183
|
+
5. The script will:
|
184
|
+
|
185
|
+
- Check if the specified PostgreSQL user exists, creating it if necessary.
|
186
|
+
- Check if the specified database exists, creating it if necessary.
|
187
|
+
- Grant the required privileges to the user for the database.
|
188
|
+
|
189
|
+
***Note: This script is only required if you're contributing to the development of the gem or testing locally. It is not required for end users of the gem.***
|
190
|
+
|
191
|
+
## Tests
|
192
|
+
|
193
|
+
The gem includes RSpec tests to verify that the sequence methods behave as expected.
|
194
|
+
|
195
|
+
### Running the Tests
|
196
|
+
|
197
|
+
To run the tests, you need to install the required dependencies first:
|
198
|
+
|
199
|
+
`$ bundle install`
|
200
|
+
|
201
|
+
Then, run the tests with:
|
202
|
+
|
203
|
+
`$ bundle exec rspec`
|
204
|
+
|
205
|
+
The tests are located in the `spec/` directory and verify the behavior of `create_sequence`,
|
206
|
+
`alter_sequence`, and `drop_sequence` methods.
|
207
|
+
|
18
208
|
## Contributing
|
19
209
|
|
20
210
|
Contributions to this project are welcomed! To contribute:
|
@@ -0,0 +1,41 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
# Exit immediately if any command fails
|
4
|
+
set -e
|
5
|
+
|
6
|
+
echo "🔧 Setting up PostgreSQL for testing..."
|
7
|
+
|
8
|
+
# Read input from ENV variables or use default one
|
9
|
+
POSTGRES_DB=${POSTGRES_DB:-"rails_test"}
|
10
|
+
POSTGRES_USER=${POSTGRES_USER:-"rails"}
|
11
|
+
POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-"password"}
|
12
|
+
|
13
|
+
# Check if the user exists, create if not
|
14
|
+
echo "👤 Checking if user '$POSTGRES_USER' exists..."
|
15
|
+
USER_EXISTS=$(sudo -u postgres psql -tAc "SELECT 1 FROM pg_roles WHERE rolname='$POSTGRES_USER'")
|
16
|
+
|
17
|
+
if [[ "$USER_EXISTS" != "1" ]]; then
|
18
|
+
echo "👤 Creating user '$POSTGRES_USER'..."
|
19
|
+
sudo -u postgres psql -c "CREATE USER $POSTGRES_USER WITH SUPERUSER;"
|
20
|
+
echo "🔑 Setting password for user '$POSTGRES_USER'..."
|
21
|
+
sudo -u postgres psql -c "ALTER USER $POSTGRES_USER WITH PASSWORD '$POSTGRES_PASSWORD';"
|
22
|
+
else
|
23
|
+
echo "✅ User '$POSTGRES_USER' already exists."
|
24
|
+
fi
|
25
|
+
|
26
|
+
# Check if the database exists, create if not
|
27
|
+
echo "📦 Checking if database '$POSTGRES_DB' exists..."
|
28
|
+
DB_EXISTS=$(sudo -u postgres psql -tAc "SELECT 1 FROM pg_database WHERE datname='$POSTGRES_DB'")
|
29
|
+
|
30
|
+
if [[ "$DB_EXISTS" != "1" ]]; then
|
31
|
+
echo "📦 Creating database '$POSTGRES_DB'..."
|
32
|
+
sudo -u postgres psql -c "CREATE DATABASE $POSTGRES_DB OWNER $POSTGRES_USER;"
|
33
|
+
else
|
34
|
+
echo "✅ Database '$POSTGRES_DB' already exists."
|
35
|
+
fi
|
36
|
+
|
37
|
+
# Grant privileges to the user on the database
|
38
|
+
echo "🔑 Granting privileges to '$POSTGRES_USER' on '$POSTGRES_DB'..."
|
39
|
+
sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE $POSTGRES_DB TO $POSTGRES_USER;"
|
40
|
+
|
41
|
+
echo "✅ PostgreSQL setup complete!"
|
@@ -5,11 +5,23 @@
|
|
5
5
|
require "active_record"
|
6
6
|
require "active_record/connection_adapters/postgresql_adapter"
|
7
7
|
|
8
|
-
|
8
|
+
require "postgresql_adapter_extensions/command_recorder"
|
9
|
+
require "postgresql_adapter_extensions/sequence_methods"
|
9
10
|
|
11
|
+
module PostgreSQLAdapterExtensions
|
12
|
+
##
|
10
13
|
# This is the base class for custom errors in the +PostgreSQLAdapterExtensions+ module.
|
11
14
|
#
|
12
15
|
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
13
16
|
# @since 0.1.0
|
17
|
+
#
|
14
18
|
class BaseError < StandardError; end
|
19
|
+
|
20
|
+
if defined?(ActiveRecord::ConnectionAdapters::PostgreSQLAdapter)
|
21
|
+
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.include(SequenceMethods)
|
22
|
+
end
|
23
|
+
|
24
|
+
if defined?(ActiveRecord::Migration::CommandRecorder)
|
25
|
+
ActiveRecord::Migration::CommandRecorder.include(CommandRecorder)
|
26
|
+
end
|
15
27
|
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
# -*- frozen_string_literal: true -*-
|
3
|
+
# -*- warn_indent: true -*-
|
4
|
+
|
5
|
+
module PostgreSQLAdapterExtensions
|
6
|
+
##
|
7
|
+
# Module that extends ActiveRecord's CommandRecorder to handle sequence-related commands.
|
8
|
+
#
|
9
|
+
# This module is designed to work with reversible migrations in ActiveRecord, specifically to manage PostgreSQL sequence operations.
|
10
|
+
# The methods capture forward migration commands for sequences and generate their inverse using simple metaprogramming.
|
11
|
+
#
|
12
|
+
# @example
|
13
|
+
# class AddSomeSequence < ActiveRecord::Migration[6.0]
|
14
|
+
# def change
|
15
|
+
# create_sequence :some_sequence
|
16
|
+
# end
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# This will create a sequence, and during rollback, it will drop the sequence.
|
20
|
+
#
|
21
|
+
# @see ActiveRecord::Migration::CommandRecorder
|
22
|
+
#
|
23
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
24
|
+
# @since 1.0.0
|
25
|
+
#
|
26
|
+
module CommandRecorder
|
27
|
+
##
|
28
|
+
# Records the creation of a PostgreSQL sequence during a migration.
|
29
|
+
#
|
30
|
+
# This method is invoked when creating a sequence in the database. The corresponding
|
31
|
+
# inverse operation will be to drop the sequence during rollback.
|
32
|
+
#
|
33
|
+
# @param args [Array] Arguments required to create the sequence (usually the sequence name).
|
34
|
+
# @param block [Proc] An optional block passed to the command.
|
35
|
+
# @return [void]
|
36
|
+
#
|
37
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
38
|
+
# @since 1.0.0
|
39
|
+
#
|
40
|
+
def create_sequence(*args, &block)
|
41
|
+
record(:create_sequence, args, &block)
|
42
|
+
end
|
43
|
+
|
44
|
+
##
|
45
|
+
# Records the alteration of a PostgreSQL sequence during a migration.
|
46
|
+
#
|
47
|
+
# This method is invoked when altering a sequence in the database.
|
48
|
+
# The corresponding inverse operation is not possible, so it will raise an error during rollback.
|
49
|
+
#
|
50
|
+
# @param args [Array] Arguments required to alter the sequence.
|
51
|
+
# @param block [Proc] An optional block passed to the command.
|
52
|
+
# @raise [ActiveRecord::IrreversibleMigration] When attempting to rollback an altered sequence.
|
53
|
+
# @return [void]
|
54
|
+
#
|
55
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
56
|
+
# @since 1.0.0
|
57
|
+
#
|
58
|
+
def alter_sequence(*args, &block)
|
59
|
+
record(:alter_sequence, args, &block)
|
60
|
+
end
|
61
|
+
|
62
|
+
##
|
63
|
+
# Records the dropping of a PostgreSQL sequence during a migration.
|
64
|
+
#
|
65
|
+
# This method is invoked when dropping a sequence from the database.
|
66
|
+
# The corresponding inverse operation is not possible, so it will raise an error during rollback.
|
67
|
+
#
|
68
|
+
# @param args [Array] Arguments required to drop the sequence (usually the sequence name).
|
69
|
+
# @param block [Proc] An optional block passed to the command.
|
70
|
+
# @raise [ActiveRecord::IrreversibleMigration] When attempting to rollback a dropped sequence.
|
71
|
+
# @return [void]
|
72
|
+
#
|
73
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
74
|
+
# @since 1.0.0
|
75
|
+
#
|
76
|
+
def drop_sequence(*args, &block)
|
77
|
+
record(:drop_sequence, args, &block)
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
##
|
83
|
+
# Generates the inverse command for creating a sequence, which is to drop the sequence.
|
84
|
+
#
|
85
|
+
# @param args [Array] Arguments passed to the create_sequence method (sequence name).
|
86
|
+
# @return [Array] An array with the inverse command `:drop_sequence` and its arguments.
|
87
|
+
#
|
88
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
89
|
+
# @since 1.0.0
|
90
|
+
#
|
91
|
+
def invert_create_sequence(args)
|
92
|
+
[:drop_sequence, args]
|
93
|
+
end
|
94
|
+
|
95
|
+
##
|
96
|
+
# Generates the inverse command for altering a sequence, which is not possible.
|
97
|
+
#
|
98
|
+
# @param args [Array] Arguments passed to the alter_sequence method.
|
99
|
+
# @raise [ActiveRecord::IrreversibleMigration] This operation cannot be reversed.
|
100
|
+
#
|
101
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
102
|
+
# @since 1.0.0
|
103
|
+
#
|
104
|
+
def invert_alter_sequence(args)
|
105
|
+
raise ActiveRecord::IrreversibleMigration, "Alter sequence is irreversible."
|
106
|
+
end
|
107
|
+
|
108
|
+
##
|
109
|
+
# Generates the inverse command for dropping a sequence, which is not possible.
|
110
|
+
#
|
111
|
+
# @param args [Array] Arguments passed to the drop_sequence method (sequence name).
|
112
|
+
# @raise [ActiveRecord::IrreversibleMigration] This operation cannot be reversed.
|
113
|
+
#
|
114
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
115
|
+
# @since 1.0.0
|
116
|
+
#
|
117
|
+
def invert_drop_sequence(args)
|
118
|
+
raise ActiveRecord::IrreversibleMigration, "Drop sequence is irreversible."
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,179 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
# -*- frozen_string_literal: true -*-
|
3
|
+
# -*- warn_indent: true -*-
|
4
|
+
|
5
|
+
module PostgreSQLAdapterExtensions
|
6
|
+
##
|
7
|
+
# This module provides methods for managing PostgreSQL sequences, including
|
8
|
+
# creating, altering, and dropping sequences with various customization options.
|
9
|
+
#
|
10
|
+
# @note This module is designed for PostgreSQL databases and may not be compatible with other database systems.
|
11
|
+
#
|
12
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
13
|
+
# @since 1.0.0
|
14
|
+
#
|
15
|
+
module SequenceMethods
|
16
|
+
##
|
17
|
+
# Creates a new sequence in the PostgreSQL database with customizable options.
|
18
|
+
#
|
19
|
+
# @param name [String, Symbol] The name of the sequence to create.
|
20
|
+
# @param options [Hash] Additional options to configure the sequence.
|
21
|
+
# @option options [Boolean] :if_not_exists (false) Includes +IF NOT EXISTS+ to avoid errors if the sequence exists.
|
22
|
+
# @option options [String, nil] :data_type (nil) Sets the sequence's data type (e.g., +BIGINT+, +SMALLINT+).
|
23
|
+
# @option options [Integer] :start (1) The starting value of the sequence.
|
24
|
+
# @option options [Integer] :increment_by (1) The increment step for each sequence value.
|
25
|
+
# @option options [Integer, nil] :minvalue (1) The minimum value the sequence can generate. Uses +NO MINVALUE+ if nil.
|
26
|
+
# @option options [Integer, nil] :maxvalue (nil) The maximum value the sequence can generate. Uses +NO MAXVALUE+ if nil.
|
27
|
+
# @option options [Integer] :cache (1) The number of sequence values to cache for performance.
|
28
|
+
# @option options [Boolean] :cycle (false) Whether the sequence should cycle back to the start after reaching the max value.
|
29
|
+
# @option options [String, nil] :owned_by (nil) The table and column name that owns this sequence.
|
30
|
+
#
|
31
|
+
# @example Create a sequence with default options
|
32
|
+
# create_sequence(:order_id_seq)
|
33
|
+
#
|
34
|
+
# @example Create a sequence starting from 1000 with an increment of 5
|
35
|
+
# create_sequence(:order_id_seq, start: 1000, increment_by: 5)
|
36
|
+
#
|
37
|
+
# @example Create a cyclic sequence with a maximum value of 5000
|
38
|
+
# create_sequence(:order_id_seq, cycle: true, maxvalue: 5000)
|
39
|
+
#
|
40
|
+
# @example Create a sequence owned by a specific table column
|
41
|
+
# create_sequence(:order_id_seq, owned_by: "orders.id")
|
42
|
+
#
|
43
|
+
# @return [void]
|
44
|
+
#
|
45
|
+
# @note Uses `CREATE SEQUENCE` SQL statement with PostgreSQL-specific options.
|
46
|
+
#
|
47
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
48
|
+
# @since 1.0.0
|
49
|
+
#
|
50
|
+
def create_sequence(name, options = {})
|
51
|
+
options = options.reverse_merge(
|
52
|
+
start: 1,
|
53
|
+
increment_by: 1,
|
54
|
+
minvalue: 1,
|
55
|
+
cache: 1,
|
56
|
+
cycle: false,
|
57
|
+
if_not_exists: false
|
58
|
+
)
|
59
|
+
|
60
|
+
sql = +"CREATE SEQUENCE"
|
61
|
+
sql << " IF NOT EXISTS" if options[:if_not_exists]
|
62
|
+
sql << " #{quote_table_name(name)}"
|
63
|
+
|
64
|
+
sql << " AS #{options[:data_type]}" if options[:data_type]
|
65
|
+
sql << " INCREMENT BY #{options[:increment_by]}" if options[:increment_by]
|
66
|
+
sql << (options[:minvalue] ? " MINVALUE #{options[:minvalue]}" : " NO MINVALUE")
|
67
|
+
sql << (options[:maxvalue] ? " MAXVALUE #{options[:maxvalue]}" : " NO MAXVALUE")
|
68
|
+
sql << " START WITH #{options[:start]}" if options[:start]
|
69
|
+
sql << " CACHE #{options[:cache]}" if options[:cache]
|
70
|
+
sql << " #{options[:cycle] ? 'CYCLE' : 'NO CYCLE'}"
|
71
|
+
sql << " OWNED BY #{options[:owned_by]}" if options[:owned_by]
|
72
|
+
|
73
|
+
execute(sql).tap { reload_type_map }
|
74
|
+
end
|
75
|
+
|
76
|
+
##
|
77
|
+
# Alters an existing PostgreSQL sequence with the given options.
|
78
|
+
#
|
79
|
+
# @param name [String, Symbol] The name of the sequence to alter.
|
80
|
+
# @param options [Hash] A hash of options to modify the sequence behavior.
|
81
|
+
# @option options [Boolean] :if_exists Includes +IF EXISTS+ to avoid errors if the sequence does not exist.
|
82
|
+
# @option options [String, nil] :data_type Sets the sequence's data type (e.g., +BIGINT+, +SMALLINT+).
|
83
|
+
# @option options [Integer] :increment_by Sets the increment step for the sequence.
|
84
|
+
# @option options [Integer, nil] :minvalue Sets the minimum value for the sequence. Uses +NO MINVALUE+ if nil.
|
85
|
+
# @option options [Integer, nil] :maxvalue Sets the maximum value for the sequence. Uses +NO MAXVALUE+ if nil.
|
86
|
+
# @option options [Integer] :start Sets the starting value of the sequence.
|
87
|
+
# @option options [Integer, nil] :restart Restarts the sequence. Uses +RESTART+ if nil, +RESTART WITH value+ if provided.
|
88
|
+
# @option options [Integer] :cache Sets the number of sequence values to cache for performance.
|
89
|
+
# @option options [Boolean] :cycle Enables (+CYCLE+) or disables (+NO CYCLE+) sequence cycling.
|
90
|
+
# @option options [String, nil] :owned_by Associates the sequence with a table column. Uses +OWNED BY NONE+ if nil.
|
91
|
+
#
|
92
|
+
# @example Modify the increment value of a sequence
|
93
|
+
# alter_sequence(:order_id_seq, increment_by: 10)
|
94
|
+
#
|
95
|
+
# @example Restart a sequence at a specific value
|
96
|
+
# alter_sequence(:order_id_seq, restart_with: 2000)
|
97
|
+
#
|
98
|
+
# @example Set a minimum and maximum value for a sequence
|
99
|
+
# alter_sequence(:order_id_seq, minvalue: 500, maxvalue: 10000)
|
100
|
+
#
|
101
|
+
# @example Make a sequence cycle when it reaches the maximum value
|
102
|
+
# alter_sequence(:order_id_seq, cycle: true)
|
103
|
+
#
|
104
|
+
# @example Remove the cycle behavior from a sequence
|
105
|
+
# alter_sequence(:order_id_seq, cycle: false)
|
106
|
+
#
|
107
|
+
# @example Change the owner of a sequence to a specific table column
|
108
|
+
# alter_sequence(:order_id_seq, owned_by: "orders.id")
|
109
|
+
#
|
110
|
+
# @return [void] Executes the SQL statement to alter the sequence.
|
111
|
+
#
|
112
|
+
# @note Uses `ALTER SEQUENCE` SQL statement with PostgreSQL-specific options.
|
113
|
+
#
|
114
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
115
|
+
# @since 1.0.0
|
116
|
+
#
|
117
|
+
def alter_sequence(name, options = {})
|
118
|
+
sql = +"ALTER SEQUENCE"
|
119
|
+
sql << " IF EXISTS" if options[:if_exists]
|
120
|
+
sql << " #{quote_table_name(name)}"
|
121
|
+
|
122
|
+
sql << " AS #{options[:data_type]}" if options[:data_type]
|
123
|
+
sql << " INCREMENT BY #{options[:increment_by]}" if options[:increment_by]
|
124
|
+
sql << (options[:minvalue] ? " MINVALUE #{options[:minvalue]}" : " NO MINVALUE")
|
125
|
+
sql << (options[:maxvalue] ? " MAXVALUE #{options[:maxvalue]}" : " NO MAXVALUE")
|
126
|
+
sql << " START WITH #{options[:start]}" if options[:start]
|
127
|
+
sql << " RESTART" if options[:restart].nil? && options.key?(:restart)
|
128
|
+
sql << " RESTART WITH #{options[:restart]}" if options[:restart]
|
129
|
+
sql << " CACHE #{options[:cache]}" if options[:cache]
|
130
|
+
sql << " #{options[:cycle] ? 'CYCLE' : 'NO CYCLE'}"
|
131
|
+
sql << (options[:owned_by] ? " OWNED BY #{options[:owned_by]}" : " OWNED BY NONE")
|
132
|
+
|
133
|
+
execute(sql).tap { reload_type_map }
|
134
|
+
end
|
135
|
+
|
136
|
+
##
|
137
|
+
# Drops an existing sequence from the PostgreSQL database with optional conditions.
|
138
|
+
#
|
139
|
+
# @param name [String, Symbol] The name of the sequence to drop.
|
140
|
+
# @param options [Hash] Additional options to modify the behavior of the drop operation.
|
141
|
+
# @option options [Boolean] :if_exists (false) Adds +IF EXISTS+ to avoid errors if the sequence does not exist.
|
142
|
+
# @option options [Symbol] :drop_behavior (nil) Determines whether dependent objects are also dropped.
|
143
|
+
# - Accepts +:cascade+ to drop dependent objects.
|
144
|
+
# - Accepts +:restrict+ to prevent dropping if dependencies exist.
|
145
|
+
#
|
146
|
+
# @example Drop a sequence without additional options
|
147
|
+
# drop_sequence(:order_id_seq)
|
148
|
+
#
|
149
|
+
# @example Drop a sequence if it exists
|
150
|
+
# drop_sequence(:order_id_seq, if_exists: true)
|
151
|
+
#
|
152
|
+
# @example Drop a sequence and all dependent objects
|
153
|
+
# drop_sequence(:order_id_seq, drop_behavior: :cascade)
|
154
|
+
#
|
155
|
+
# @example Drop a sequence but prevent deletion if dependencies exist
|
156
|
+
# drop_sequence(:order_id_seq, drop_behavior: :restrict)
|
157
|
+
#
|
158
|
+
# @return [void]
|
159
|
+
#
|
160
|
+
# @note Uses `DROP SEQUENCE` SQL statement with PostgreSQL-specific options.
|
161
|
+
#
|
162
|
+
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
|
163
|
+
# @since 1.0.0
|
164
|
+
#
|
165
|
+
def drop_sequence(name, options = {})
|
166
|
+
options = options.reverse_merge(
|
167
|
+
if_exists: false
|
168
|
+
)
|
169
|
+
|
170
|
+
sql = +"DROP SEQUENCE"
|
171
|
+
sql << " IF EXISTS" if options[:if_exists]
|
172
|
+
sql << " #{quote_table_name(name)}"
|
173
|
+
|
174
|
+
sql << " #{options[:drop_behavior].to_s.upcase}" if options[:drop_behavior].in?([:cascade, :restrict])
|
175
|
+
|
176
|
+
execute(sql).tap { reload_type_map }
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: postgresql_adapter_extensions
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Harshal LADHE
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-03-
|
11
|
+
date: 2025-03-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -108,6 +108,7 @@ executables: []
|
|
108
108
|
extensions: []
|
109
109
|
extra_rdoc_files: []
|
110
110
|
files:
|
111
|
+
- ".github/workflows/docs.yml"
|
111
112
|
- ".github/workflows/main.yml"
|
112
113
|
- ".gitignore"
|
113
114
|
- ".rspec"
|
@@ -117,8 +118,11 @@ files:
|
|
117
118
|
- LICENSE.txt
|
118
119
|
- README.md
|
119
120
|
- Rakefile
|
121
|
+
- bin/setup_postgresql.sh
|
120
122
|
- lib/postgresql_adapter_extensions.rb
|
121
123
|
- lib/postgresql_adapter_extensions/base.rb
|
124
|
+
- lib/postgresql_adapter_extensions/command_recorder.rb
|
125
|
+
- lib/postgresql_adapter_extensions/sequence_methods.rb
|
122
126
|
- lib/postgresql_adapter_extensions/version.rb
|
123
127
|
- postgresql_adapter_extensions.gemspec
|
124
128
|
homepage: https://github.com/shivam091/postgresql_adapter_extensions
|