github.com/supabase/cli@v1.168.1/internal/migration/history/history.go (about)

     1  package history
     2  
     3  import (
     4  	"context"
     5  
     6  	"github.com/go-errors/errors"
     7  	"github.com/jackc/pgconn"
     8  	"github.com/jackc/pgx/v4"
     9  	"github.com/supabase/cli/internal/utils/pgxv5"
    10  )
    11  
    12  const (
    13  	SET_LOCK_TIMEOUT         = "SET LOCAL lock_timeout = '4s'"
    14  	CREATE_VERSION_SCHEMA    = "CREATE SCHEMA IF NOT EXISTS supabase_migrations"
    15  	CREATE_VERSION_TABLE     = "CREATE TABLE IF NOT EXISTS supabase_migrations.schema_migrations (version text NOT NULL PRIMARY KEY)"
    16  	ADD_STATEMENTS_COLUMN    = "ALTER TABLE supabase_migrations.schema_migrations ADD COLUMN IF NOT EXISTS statements text[]"
    17  	ADD_NAME_COLUMN          = "ALTER TABLE supabase_migrations.schema_migrations ADD COLUMN IF NOT EXISTS name text"
    18  	INSERT_MIGRATION_VERSION = "INSERT INTO supabase_migrations.schema_migrations(version, name, statements) VALUES($1, $2, $3)"
    19  	DELETE_MIGRATION_VERSION = "DELETE FROM supabase_migrations.schema_migrations WHERE version = ANY($1)"
    20  	DELETE_MIGRATION_BEFORE  = "DELETE FROM supabase_migrations.schema_migrations WHERE version <= $1"
    21  	TRUNCATE_VERSION_TABLE   = "TRUNCATE supabase_migrations.schema_migrations"
    22  	SELECT_VERSION_TABLE     = "SELECT * FROM supabase_migrations.schema_migrations"
    23  )
    24  
    25  type SchemaMigration struct {
    26  	Version    string
    27  	Name       string
    28  	Statements []string
    29  }
    30  
    31  func CreateMigrationTable(ctx context.Context, conn *pgx.Conn) error {
    32  	// This must be run without prepared statements because each statement in the batch depends on
    33  	// the previous schema change. The lock timeout will be reset when implicit transaction ends.
    34  	batch := pgconn.Batch{}
    35  	batch.ExecParams(SET_LOCK_TIMEOUT, nil, nil, nil, nil)
    36  	batch.ExecParams(CREATE_VERSION_SCHEMA, nil, nil, nil, nil)
    37  	batch.ExecParams(CREATE_VERSION_TABLE, nil, nil, nil, nil)
    38  	batch.ExecParams(ADD_STATEMENTS_COLUMN, nil, nil, nil, nil)
    39  	batch.ExecParams(ADD_NAME_COLUMN, nil, nil, nil, nil)
    40  	if _, err := conn.PgConn().ExecBatch(ctx, &batch).ReadAll(); err != nil {
    41  		return errors.Errorf("failed to create migration table: %w", err)
    42  	}
    43  	return nil
    44  }
    45  
    46  func ReadMigrationTable(ctx context.Context, conn *pgx.Conn) ([]SchemaMigration, error) {
    47  	rows, err := conn.Query(ctx, SELECT_VERSION_TABLE)
    48  	if err != nil {
    49  		return nil, errors.Errorf("failed to read migration table: %w", err)
    50  	}
    51  	return pgxv5.CollectRows[SchemaMigration](rows)
    52  }