70 lines
2.7 KiB
Go
70 lines
2.7 KiB
Go
package migration
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
)
|
|
|
|
func applyUserEmailAddressSchema(ctx context.Context, exec executor, dialect Dialect) error {
|
|
columns := []struct {
|
|
name string
|
|
definition map[Dialect]string
|
|
}{
|
|
{name: "address", definition: map[Dialect]string{
|
|
DialectSQLite: `TEXT NULL`,
|
|
DialectMySQL: `VARCHAR(254) NULL`,
|
|
DialectPostgres: `VARCHAR(254) NULL`,
|
|
}},
|
|
{name: "address_canonical", definition: map[Dialect]string{
|
|
DialectSQLite: `TEXT NULL`,
|
|
DialectMySQL: `VARCHAR(254) NULL`,
|
|
DialectPostgres: `VARCHAR(254) NULL`,
|
|
}},
|
|
{name: "is_primary", definition: map[Dialect]string{
|
|
DialectSQLite: `INTEGER NOT NULL DEFAULT 0`,
|
|
DialectMySQL: `TINYINT NOT NULL DEFAULT 0`,
|
|
DialectPostgres: `SMALLINT NOT NULL DEFAULT 0`,
|
|
}},
|
|
{name: "verified_at", definition: map[Dialect]string{
|
|
DialectSQLite: `DATETIME NULL`,
|
|
DialectMySQL: `DATETIME(6) NULL`,
|
|
DialectPostgres: `TIMESTAMPTZ NULL`,
|
|
}},
|
|
{name: "created_at", definition: map[Dialect]string{
|
|
DialectSQLite: `DATETIME NULL`,
|
|
DialectMySQL: `DATETIME(6) NULL`,
|
|
DialectPostgres: `TIMESTAMPTZ NULL`,
|
|
}},
|
|
{name: "updated_at", definition: map[Dialect]string{
|
|
DialectSQLite: `DATETIME NULL`,
|
|
DialectMySQL: `DATETIME(6) NULL`,
|
|
DialectPostgres: `TIMESTAMPTZ NULL`,
|
|
}},
|
|
}
|
|
for _, column := range columns {
|
|
if err := ensureColumn(ctx, exec, dialect, "user_email", column.name, column.definition[dialect]); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
var conflicts int
|
|
conflictQuery := `SELECT COUNT(*) FROM (SELECT "address_canonical" FROM "user_email" WHERE "address_canonical" IS NOT NULL AND TRIM("address_canonical") <> '' GROUP BY "address_canonical" HAVING COUNT(*) > 1) AS conflicts`
|
|
if dialect == DialectMySQL {
|
|
conflictQuery = "SELECT COUNT(*) FROM (SELECT `address_canonical` FROM `user_email` WHERE `address_canonical` IS NOT NULL AND TRIM(`address_canonical`) <> '' GROUP BY `address_canonical` HAVING COUNT(*) > 1) AS conflicts"
|
|
}
|
|
if dialect == DialectPostgres {
|
|
conflictQuery = `SELECT COUNT(*) FROM (SELECT "address_canonical" FROM "user_email" WHERE "address_canonical" IS NOT NULL AND BTRIM("address_canonical") <> '' GROUP BY "address_canonical" HAVING COUNT(*) > 1) AS conflicts`
|
|
}
|
|
if err := exec.QueryRowContext(ctx, conflictQuery).Scan(&conflicts); err != nil {
|
|
return fmt.Errorf("check user email address conflicts: %w", err)
|
|
}
|
|
if conflicts > 0 {
|
|
return fmt.Errorf("user email address conflict count: %d", conflicts)
|
|
}
|
|
|
|
if err := ensureIndex(ctx, exec, dialect, "user_email", "uq_user_email_address_canonical", true, []string{"address_canonical"}); err != nil {
|
|
return err
|
|
}
|
|
return ensureIndex(ctx, exec, dialect, "user_email", "idx_user_email_user_primary", false, []string{"user_id", "is_primary"})
|
|
}
|