Skip to content

Commit

Permalink
Adding create_sequence and drop_sequence migration helpers. Fixes #910 (
Browse files Browse the repository at this point in the history
  • Loading branch information
jwoertink authored Mar 9, 2024
1 parent 8f39cc4 commit 0366d79
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 0 deletions.
14 changes: 14 additions & 0 deletions spec/avram/migrator/create_sequence_statement_spec.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
require "../../spec_helper"

describe Avram::Migrator::CreateSequenceStatement do
it "generates correct CREATE SEQUENCE sql" do
statement = Avram::Migrator::CreateSequenceStatement.new(:accounts_number).build
statement.should eq "CREATE SEQUENCE accounts_number_seq OWNED BY NONE;"

statement = Avram::Migrator::CreateSequenceStatement.new(:accounts_number, if_not_exists: true).build
statement.should eq "CREATE SEQUENCE IF NOT EXISTS accounts_number_seq OWNED BY NONE;"

statement = Avram::Migrator::CreateSequenceStatement.new(:accounts_number, owned_by: "accounts.number").build
statement.should eq "CREATE SEQUENCE accounts_number_seq OWNED BY accounts.number;"
end
end
8 changes: 8 additions & 0 deletions spec/avram/migrator/drop_sequence_statement_spec.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
require "../../spec_helper"

describe Avram::Migrator::DropSequenceStatement do
it "generates correct DROP SEQUENCE sql" do
statement = Avram::Migrator::DropSequenceStatement.new(:accounts_number).build
statement.should eq "DROP SEQUENCE IF EXISTS accounts_number_seq;"
end
end
23 changes: 23 additions & 0 deletions spec/avram/migrator/migration_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,16 @@ class MigrationCreateTableIfNotExists::V995 < Avram::Migrator::Migration::V1
end
end

class MigrationCreateAndDropSequences::V994 < Avram::Migrator::Migration::V1
def migrate
create_sequence(:accounts, :number)
end

def rollback
drop_sequence(:accounts, :number)
end
end

describe Avram::Migrator::Migration::V1 do
it "executes statements in a transaction" do
expect_raises Avram::FailedMigration do
Expand Down Expand Up @@ -140,6 +150,19 @@ describe Avram::Migrator::Migration::V1 do
sql.should contain "ALTER TABLE IF EXISTS fake_things"
end
end

describe "sequences" do
it "creates the sequences" do
migration = MigrationCreateAndDropSequences::V994.new
migration.migrate
sql = migration.prepared_statements.join("\n")
sql.should contain "CREATE SEQUENCE IF NOT EXISTS accounts_number_seq OWNED BY accounts.number"

migration.rollback
sql = migration.prepared_statements.join("\n")
sql.should contain "DROP SEQUENCE IF EXISTS accounts_number_seq"
end
end
end

private def get_column_names(table_name)
Expand Down
26 changes: 26 additions & 0 deletions src/avram/migrator/create_sequence_statement.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Builds an SQL statement for creating a sequence using the given name appending "_seq".
# Additional options may be provided for extra customization.
#
# ### Usage
#
# ```
# CreateSequenceStatement.new(:accounts_number, if_not_exists: true, owned_by: "accounts.number").build
# # => "CREATE SEQUENCE accounts_number_seq;"
# ```
class Avram::Migrator::CreateSequenceStatement
private getter? if_not_exists : Bool = false

def initialize(@name : String | Symbol, *, @if_not_exists : Bool = false, @owned_by : String = "NONE")
end

def build
name = "#{@name}_seq"

String.build do |io|
io << "CREATE SEQUENCE "
io << "IF NOT EXISTS " if if_not_exists?
io << name
io << " OWNED BY #{@owned_by};"
end
end
end
22 changes: 22 additions & 0 deletions src/avram/migrator/drop_sequence_statement.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Builds an SQL statement for dropping a sequence using the given name.
#
# ### Usage
#
# ```
# DropSequenceStatement.new(:accounts_number, if_not_exists: true, owned_by: "accounts.number").build
# # => "CREATE SEQUENCE accounts_number_seq;"
# ```
class Avram::Migrator::DropSequenceStatement
def initialize(@name : String | Symbol)
end

def build
name = "#{@name}_seq"

String.build do |io|
io << "DROP SEQUENCE IF EXISTS "
io << name
io << ';'
end
end
end
11 changes: 11 additions & 0 deletions src/avram/migrator/statement_helpers.cr
Original file line number Diff line number Diff line change
Expand Up @@ -93,4 +93,15 @@ module Avram::Migrator::StatementHelpers
def drop_trigger(table_name : TableName, name : String)
prepared_statements << Avram::Migrator::DropTriggerStatement.new(table_name, name).build
end

def create_sequence(table : TableName, column : Symbol)
sequence_name = "#{table}_#{column}"
owned_by = "#{table}.#{column}"
prepared_statements << Avram::Migrator::CreateSequenceStatement.new(sequence_name, if_not_exists: true, owned_by: owned_by).build
end

def drop_sequence(table : TableName, column : Symbol)
sequence_name = "#{table}_#{column}"
prepared_statements << Avram::Migrator::DropSequenceStatement.new(sequence_name).build
end
end

0 comments on commit 0366d79

Please sign in to comment.