mirror of
https://github.com/ent/ent.git
synced 2026-05-24 09:31:56 +03:00
dialect/sql/schema: support providing alternate schema for postgres (#1172)
This commit is contained in:
@@ -17,6 +17,7 @@ import (
|
||||
// Postgres is a postgres migration driver.
|
||||
type Postgres struct {
|
||||
dialect.Driver
|
||||
schema string
|
||||
version string
|
||||
}
|
||||
|
||||
@@ -53,7 +54,7 @@ func (d *Postgres) tableExist(ctx context.Context, tx dialect.Tx, name string) (
|
||||
query, args := sql.Dialect(dialect.Postgres).
|
||||
Select(sql.Count("*")).From(sql.Table("tables").Schema("information_schema")).
|
||||
Where(sql.And(
|
||||
sql.EQ("table_schema", sql.Raw("CURRENT_SCHEMA()")),
|
||||
sql.EQ("table_schema", d.tableSchema()),
|
||||
sql.EQ("table_name", name),
|
||||
)).Query()
|
||||
return exist(ctx, tx, query, args...)
|
||||
@@ -64,7 +65,7 @@ func (d *Postgres) fkExist(ctx context.Context, tx dialect.Tx, name string) (boo
|
||||
query, args := sql.Dialect(dialect.Postgres).
|
||||
Select(sql.Count("*")).From(sql.Table("table_constraints").Schema("information_schema")).
|
||||
Where(sql.And(
|
||||
sql.EQ("table_schema", sql.Raw("CURRENT_SCHEMA()")),
|
||||
sql.EQ("table_schema", d.tableSchema()),
|
||||
sql.EQ("constraint_type", "FOREIGN KEY"),
|
||||
sql.EQ("constraint_name", name),
|
||||
)).Query()
|
||||
@@ -90,7 +91,7 @@ func (d *Postgres) table(ctx context.Context, tx dialect.Tx, name string) (*Tabl
|
||||
Select("column_name", "data_type", "is_nullable", "column_default", "udt_name").
|
||||
From(sql.Table("columns").Schema("information_schema")).
|
||||
Where(sql.And(
|
||||
sql.EQ("table_schema", sql.Raw("CURRENT_SCHEMA()")),
|
||||
sql.EQ("table_schema", d.tableSchema()),
|
||||
sql.EQ("table_name", name),
|
||||
)).Query()
|
||||
if err := tx.Query(ctx, query, args, rows); err != nil {
|
||||
@@ -165,14 +166,21 @@ WHERE t.oid = idx.indrelid
|
||||
AND a.attrelid = t.oid
|
||||
AND a.attnum = ANY(idx.indkey)
|
||||
AND t.relkind = 'r'
|
||||
AND n.nspname = CURRENT_SCHEMA()
|
||||
AND n.nspname = %s
|
||||
AND t.relname = '%s'
|
||||
ORDER BY index_name, seq_in_index;
|
||||
`
|
||||
|
||||
// indexesQuery returns the query (and its placeholders) for getting table indexes.
|
||||
func (d *Postgres) indexesQuery(table string) (string, []interface{}) {
|
||||
expr, args := d.tableSchema().Query()
|
||||
return fmt.Sprintf(indexesQuery, expr, table), args
|
||||
}
|
||||
|
||||
func (d *Postgres) indexes(ctx context.Context, tx dialect.Tx, table string) (Indexes, error) {
|
||||
rows := &sql.Rows{}
|
||||
if err := tx.Query(ctx, fmt.Sprintf(indexesQuery, table), []interface{}{}, rows); err != nil {
|
||||
query, args := d.indexesQuery(table)
|
||||
if err := tx.Query(ctx, query, args, rows); err != nil {
|
||||
return nil, fmt.Errorf("querying indexes for table %s: %v", table, err)
|
||||
}
|
||||
defer rows.Close()
|
||||
@@ -397,7 +405,7 @@ func (d *Postgres) dropIndex(ctx context.Context, tx dialect.Tx, idx *Index, tab
|
||||
query, args := sql.Dialect(dialect.Postgres).
|
||||
Select(sql.Count("*")).From(sql.Table("table_constraints").Schema("information_schema")).
|
||||
Where(sql.And(
|
||||
sql.EQ("table_schema", sql.Raw("CURRENT_SCHEMA()")),
|
||||
sql.EQ("table_schema", d.tableSchema()),
|
||||
sql.EQ("constraint_type", "UNIQUE"),
|
||||
sql.EQ("constraint_name", name),
|
||||
)).
|
||||
@@ -438,7 +446,10 @@ func (d *Postgres) renameIndex(t *Table, old, new *Index) sql.Querier {
|
||||
|
||||
// tableSchema returns the query for getting the table schema.
|
||||
func (d *Postgres) tableSchema() sql.Querier {
|
||||
return sql.Raw("(CURRENT_SCHEMA())")
|
||||
if d.schema != "" {
|
||||
return sql.Expr("?", d.schema)
|
||||
}
|
||||
return sql.Raw("CURRENT_SCHEMA()")
|
||||
}
|
||||
|
||||
// alterColumns returns the queries for applying the columns change-set.
|
||||
|
||||
@@ -196,7 +196,7 @@ func TestPostgres_Create(t *testing.T) {
|
||||
WithArgs("users").
|
||||
WillReturnRows(sqlmock.NewRows([]string{"column_name", "data_type", "is_nullable", "column_default", "udt_name"}).
|
||||
AddRow("id", "bigint", "NO", "nextval('users_colname_seq'::regclass)", "int4"))
|
||||
mock.ExpectQuery(escape(fmt.Sprintf(indexesQuery, "users"))).
|
||||
mock.ExpectQuery(escape(fmt.Sprintf(indexesQuery, "CURRENT_SCHEMA()", "users"))).
|
||||
WillReturnRows(sqlmock.NewRows([]string{"index_name", "column_name", "primary", "unique", "seq_in_index"}).
|
||||
AddRow("users_pkey", "id", "t", "t", 0))
|
||||
mock.ExpectCommit()
|
||||
@@ -224,7 +224,7 @@ func TestPostgres_Create(t *testing.T) {
|
||||
WillReturnRows(sqlmock.NewRows([]string{"column_name", "data_type", "is_nullable", "column_default", "udt_name"}).
|
||||
AddRow("id", "bigint", "NO", "nextval('users_colname_seq'::regclass)", "NULL").
|
||||
AddRow("custom", "USER-DEFINED", "NO", "NULL", "customtype"))
|
||||
mock.ExpectQuery(escape(fmt.Sprintf(indexesQuery, "users"))).
|
||||
mock.ExpectQuery(escape(fmt.Sprintf(indexesQuery, "CURRENT_SCHEMA()", "users"))).
|
||||
WillReturnRows(sqlmock.NewRows([]string{"index_name", "column_name", "primary", "unique", "seq_in_index"}).
|
||||
AddRow("users_pkey", "id", "t", "t", 0))
|
||||
mock.ExpectCommit()
|
||||
@@ -271,7 +271,7 @@ func TestPostgres_Create(t *testing.T) {
|
||||
AddRow("inet", "inet", "YES", "NULL", "inet").
|
||||
AddRow("macaddr", "macaddr", "YES", "NULL", "macaddr").
|
||||
AddRow("macaddr8", "macaddr8", "YES", "NULL", "macaddr8"))
|
||||
mock.ExpectQuery(escape(fmt.Sprintf(indexesQuery, "users"))).
|
||||
mock.ExpectQuery(escape(fmt.Sprintf(indexesQuery, "CURRENT_SCHEMA()", "users"))).
|
||||
WillReturnRows(sqlmock.NewRows([]string{"index_name", "column_name", "primary", "unique", "seq_in_index"}).
|
||||
AddRow("users_pkey", "id", "t", "t", 0))
|
||||
mock.ExpectExec(escape(`ALTER TABLE "users" ADD COLUMN "age" bigint NOT NULL, ALTER COLUMN "updated_at" TYPE timestamp with time zone, ALTER COLUMN "updated_at" DROP NOT NULL, ALTER COLUMN "deleted_at" TYPE timestamp with time zone, ALTER COLUMN "deleted_at" DROP NOT NULL`)).
|
||||
@@ -304,7 +304,7 @@ func TestPostgres_Create(t *testing.T) {
|
||||
AddRow("id", "bigint", "NO", "NULL", "int8").
|
||||
AddRow("name", "character", "YES", "NULL", "bpchar").
|
||||
AddRow("doc", "jsonb", "YES", "NULL", "jsonb"))
|
||||
mock.ExpectQuery(escape(fmt.Sprintf(indexesQuery, "users"))).
|
||||
mock.ExpectQuery(escape(fmt.Sprintf(indexesQuery, "CURRENT_SCHEMA()", "users"))).
|
||||
WillReturnRows(sqlmock.NewRows([]string{"index_name", "column_name", "primary", "unique", "seq_in_index"}).
|
||||
AddRow("users_pkey", "id", "t", "t", 0))
|
||||
mock.ExpectExec(escape(`ALTER TABLE "users" ADD COLUMN "age" bigint NOT NULL DEFAULT 10`)).
|
||||
@@ -338,7 +338,7 @@ func TestPostgres_Create(t *testing.T) {
|
||||
AddRow("id", "bigint", "NO", "NULL", "int8").
|
||||
AddRow("name", "character", "YES", "NULL", "bpchar").
|
||||
AddRow("doc", "jsonb", "YES", "NULL", "jsonb"))
|
||||
mock.ExpectQuery(escape(fmt.Sprintf(indexesQuery, "users"))).
|
||||
mock.ExpectQuery(escape(fmt.Sprintf(indexesQuery, "CURRENT_SCHEMA()", "users"))).
|
||||
WillReturnRows(sqlmock.NewRows([]string{"index_name", "column_name", "primary", "unique", "seq_in_index"}).
|
||||
AddRow("users_pkey", "id", "t", "t", 0))
|
||||
mock.ExpectExec(escape(`ALTER TABLE "users" ADD COLUMN "blob" bytea NOT NULL, ADD COLUMN "longblob" bytea NOT NULL`)).
|
||||
@@ -369,7 +369,7 @@ func TestPostgres_Create(t *testing.T) {
|
||||
WillReturnRows(sqlmock.NewRows([]string{"column_name", "data_type", "is_nullable", "column_default", "udt_name"}).
|
||||
AddRow("id", "bigint", "NO", "NULL", "int8").
|
||||
AddRow("name", "character", "YES", "NULL", "bpchar"))
|
||||
mock.ExpectQuery(escape(fmt.Sprintf(indexesQuery, "users"))).
|
||||
mock.ExpectQuery(escape(fmt.Sprintf(indexesQuery, "CURRENT_SCHEMA()", "users"))).
|
||||
WillReturnRows(sqlmock.NewRows([]string{"index_name", "column_name", "primary", "unique", "seq_in_index"}).
|
||||
AddRow("users_pkey", "id", "t", "t", 0))
|
||||
mock.ExpectExec(escape(`ALTER TABLE "users" ADD COLUMN "age" double precision NOT NULL DEFAULT 10.1`)).
|
||||
@@ -400,7 +400,7 @@ func TestPostgres_Create(t *testing.T) {
|
||||
WillReturnRows(sqlmock.NewRows([]string{"column_name", "data_type", "is_nullable", "column_default", "udt_name"}).
|
||||
AddRow("id", "bigint", "NO", "NULL", "int8").
|
||||
AddRow("name", "character", "YES", "NULL", "bpchar"))
|
||||
mock.ExpectQuery(escape(fmt.Sprintf(indexesQuery, "users"))).
|
||||
mock.ExpectQuery(escape(fmt.Sprintf(indexesQuery, "CURRENT_SCHEMA()", "users"))).
|
||||
WillReturnRows(sqlmock.NewRows([]string{"index_name", "column_name", "primary", "unique", "seq_in_index"}).
|
||||
AddRow("users_pkey", "id", "t", "t", 0))
|
||||
mock.ExpectExec(escape(`ALTER TABLE "users" ADD COLUMN "age" boolean NOT NULL DEFAULT true`)).
|
||||
@@ -431,7 +431,7 @@ func TestPostgres_Create(t *testing.T) {
|
||||
WillReturnRows(sqlmock.NewRows([]string{"column_name", "data_type", "is_nullable", "column_default", "udt_name"}).
|
||||
AddRow("id", "bigint", "NO", "NULL", "int8").
|
||||
AddRow("name", "character", "YES", "NULL", "bpchar"))
|
||||
mock.ExpectQuery(escape(fmt.Sprintf(indexesQuery, "users"))).
|
||||
mock.ExpectQuery(escape(fmt.Sprintf(indexesQuery, "CURRENT_SCHEMA()", "users"))).
|
||||
WillReturnRows(sqlmock.NewRows([]string{"index_name", "column_name", "primary", "unique", "seq_in_index"}).
|
||||
AddRow("users_pkey", "id", "t", "t", 0))
|
||||
mock.ExpectExec(escape(`ALTER TABLE "users" ADD COLUMN "nick" varchar NOT NULL DEFAULT 'unknown'`)).
|
||||
@@ -461,7 +461,7 @@ func TestPostgres_Create(t *testing.T) {
|
||||
WillReturnRows(sqlmock.NewRows([]string{"column_name", "data_type", "is_nullable", "column_default", "udt_name"}).
|
||||
AddRow("id", "bigint", "NO", "NULL", "int8").
|
||||
AddRow("name", "character", "YES", "NULL", "bpchar"))
|
||||
mock.ExpectQuery(escape(fmt.Sprintf(indexesQuery, "users"))).
|
||||
mock.ExpectQuery(escape(fmt.Sprintf(indexesQuery, "CURRENT_SCHEMA()", "users"))).
|
||||
WillReturnRows(sqlmock.NewRows([]string{"index_name", "column_name", "primary", "unique", "seq_in_index"}).
|
||||
AddRow("users_pkey", "id", "t", "t", 0))
|
||||
mock.ExpectExec(escape(`ALTER TABLE "users" DROP COLUMN "name"`)).
|
||||
@@ -491,7 +491,7 @@ func TestPostgres_Create(t *testing.T) {
|
||||
WillReturnRows(sqlmock.NewRows([]string{"column_name", "data_type", "is_nullable", "column_default", "udt_name"}).
|
||||
AddRow("id", "bigint", "NO", "NULL", "int8").
|
||||
AddRow("name", "character", "NO", "NULL", "bpchar"))
|
||||
mock.ExpectQuery(escape(fmt.Sprintf(indexesQuery, "users"))).
|
||||
mock.ExpectQuery(escape(fmt.Sprintf(indexesQuery, "CURRENT_SCHEMA()", "users"))).
|
||||
WillReturnRows(sqlmock.NewRows([]string{"index_name", "column_name", "primary", "unique", "seq_in_index"}).
|
||||
AddRow("users_pkey", "id", "t", "t", 0))
|
||||
mock.ExpectExec(escape(`ALTER TABLE "users" ALTER COLUMN "name" TYPE varchar, ALTER COLUMN "name" DROP NOT NULL`)).
|
||||
@@ -521,7 +521,7 @@ func TestPostgres_Create(t *testing.T) {
|
||||
WillReturnRows(sqlmock.NewRows([]string{"column_name", "data_type", "is_nullable", "column_default", "udt_name"}).
|
||||
AddRow("id", "bigint", "NO", "NULL", "int8").
|
||||
AddRow("age", "bigint", "NO", "NULL", "int8"))
|
||||
mock.ExpectQuery(escape(fmt.Sprintf(indexesQuery, "users"))).
|
||||
mock.ExpectQuery(escape(fmt.Sprintf(indexesQuery, "CURRENT_SCHEMA()", "users"))).
|
||||
WillReturnRows(sqlmock.NewRows([]string{"index_name", "column_name", "primary", "unique", "seq_in_index"}).
|
||||
AddRow("users_pkey", "id", "t", "t", 0))
|
||||
mock.ExpectExec(escape(`CREATE UNIQUE INDEX "users_age" ON "users"("age")`)).
|
||||
@@ -551,7 +551,7 @@ func TestPostgres_Create(t *testing.T) {
|
||||
WillReturnRows(sqlmock.NewRows([]string{"column_name", "data_type", "is_nullable", "column_default", "udt_name"}).
|
||||
AddRow("id", "bigint", "NO", "NULL", "int8").
|
||||
AddRow("age", "bigint", "NO", "NULL", "int8"))
|
||||
mock.ExpectQuery(escape(fmt.Sprintf(indexesQuery, "users"))).
|
||||
mock.ExpectQuery(escape(fmt.Sprintf(indexesQuery, "CURRENT_SCHEMA()", "users"))).
|
||||
WillReturnRows(sqlmock.NewRows([]string{"index_name", "column_name", "primary", "unique", "seq_in_index"}).
|
||||
AddRow("users_pkey", "id", "t", "t", 0).
|
||||
AddRow("users_age_key", "age", "f", "t", 0))
|
||||
@@ -581,7 +581,7 @@ func TestPostgres_Create(t *testing.T) {
|
||||
WillReturnRows(sqlmock.NewRows([]string{"column_name", "data_type", "is_nullable", "column_default", "udt_name"}).
|
||||
AddRow("id", "bigint", "NO", "NULL", "int8").
|
||||
AddRow("age", "bigint", "NO", "NULL", "int8"))
|
||||
mock.ExpectQuery(escape(fmt.Sprintf(indexesQuery, "users"))).
|
||||
mock.ExpectQuery(escape(fmt.Sprintf(indexesQuery, "CURRENT_SCHEMA()", "users"))).
|
||||
WillReturnRows(sqlmock.NewRows([]string{"index_name", "column_name", "primary", "unique", "seq_in_index"}).
|
||||
AddRow("users_pkey", "id", "t", "t", 0).
|
||||
AddRow("users_age_key", "age", "f", "t", 0))
|
||||
@@ -636,7 +636,7 @@ func TestPostgres_Create(t *testing.T) {
|
||||
AddRow("id", "bigint", "NO", "NULL", "int8").
|
||||
AddRow("age", "bigint", "NO", "NULL", "int8").
|
||||
AddRow("score", "bigint", "NO", "NULL", "int8"))
|
||||
mock.ExpectQuery(escape(fmt.Sprintf(indexesQuery, "users"))).
|
||||
mock.ExpectQuery(escape(fmt.Sprintf(indexesQuery, "CURRENT_SCHEMA()", "users"))).
|
||||
WillReturnRows(sqlmock.NewRows([]string{"index_name", "column_name", "primary", "unique", "seq_in_index"}).
|
||||
AddRow("users_pkey", "id", "t", "t", 0).
|
||||
AddRow("user_score", "score", "f", "f", 0))
|
||||
@@ -656,7 +656,7 @@ func TestPostgres_Create(t *testing.T) {
|
||||
WillReturnRows(sqlmock.NewRows([]string{"column_name", "data_type", "is_nullable", "column_default", "udt_name"}).
|
||||
AddRow("id", "bigint", "NO", "NULL", "int8").
|
||||
AddRow("score", "bigint", "NO", "NULL", "int8"))
|
||||
mock.ExpectQuery(escape(fmt.Sprintf(indexesQuery, "equipment"))).
|
||||
mock.ExpectQuery(escape(fmt.Sprintf(indexesQuery, "CURRENT_SCHEMA()", "equipment"))).
|
||||
WillReturnRows(sqlmock.NewRows([]string{"index_name", "column_name", "primary", "unique", "seq_in_index"}).
|
||||
AddRow("users_pkey", "id", "t", "t", 0).
|
||||
AddRow("equipment_score", "score", "f", "f", 0))
|
||||
@@ -697,7 +697,7 @@ func TestPostgres_Create(t *testing.T) {
|
||||
WillReturnRows(sqlmock.NewRows([]string{"column_name", "data_type", "is_nullable", "column_default", "udt_name"}).
|
||||
AddRow("id", "bigint", "YES", "NULL", "int8").
|
||||
AddRow("name", "character", "YES", "NULL", "bpchar"))
|
||||
mock.ExpectQuery(escape(fmt.Sprintf(indexesQuery, "users"))).
|
||||
mock.ExpectQuery(escape(fmt.Sprintf(indexesQuery, "CURRENT_SCHEMA()", "users"))).
|
||||
WillReturnRows(sqlmock.NewRows([]string{"index_name", "column_name", "primary", "unique", "seq_in_index"}).
|
||||
AddRow("users_pkey", "id", "t", "t", 0))
|
||||
mock.ExpectExec(escape(`ALTER TABLE "users" ADD COLUMN "spouse_id" bigint NULL`)).
|
||||
@@ -762,7 +762,7 @@ func TestPostgres_Create(t *testing.T) {
|
||||
WithArgs("users").
|
||||
WillReturnRows(sqlmock.NewRows([]string{"column_name", "data_type", "is_nullable", "column_default", "udt_name"}).
|
||||
AddRow("id", "bigint", "YES", "NULL", "int8"))
|
||||
mock.ExpectQuery(escape(fmt.Sprintf(indexesQuery, "users"))).
|
||||
mock.ExpectQuery(escape(fmt.Sprintf(indexesQuery, "CURRENT_SCHEMA()", "users"))).
|
||||
WillReturnRows(sqlmock.NewRows([]string{"index_name", "column_name", "primary", "unique", "seq_in_index"}).
|
||||
AddRow("users_pkey", "id", "t", "t", 0))
|
||||
// query groups table.
|
||||
|
||||
Reference in New Issue
Block a user