Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions cmd/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,16 @@ var (
if err != nil {
return err
}
ignoreCreateSchema, err := cmd.Flags().GetBool("ignore-create-schema")
if err != nil {
return err
}
ddlOption := &hammer.DDLOption{
IgnoreAlterDatabase: ignoreAlterDatabase,
IgnoreChangeStreams: ignoreChangeStreams,
IgnoreModels: ignoreModels,
IgnoreProtoBundles: ignoreProtoBundles,
IgnoreCreateSchema: ignoreCreateSchema,
}

if hammer.Scheme(databaseURI) != "spanner" {
Expand Down Expand Up @@ -95,6 +100,7 @@ func init() {
applyCmd.Flags().Bool("ignore-change-streams", false, "ignore change streams statements")
applyCmd.Flags().Bool("ignore-models", false, "ignore model statements")
applyCmd.Flags().Bool("ignore-proto-bundles", false, "ignore proto bundle statements")
applyCmd.Flags().Bool("ignore-create-schema", false, "ignore create schema statements")

rootCmd.AddCommand(applyCmd)
}
6 changes: 6 additions & 0 deletions cmd/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,16 @@ var (
if err != nil {
return err
}
ignoreCreateSchema, err := cmd.Flags().GetBool("ignore-create-schema")
if err != nil {
return err
}
ddlOption := &hammer.DDLOption{
IgnoreAlterDatabase: ignoreAlterDatabase,
IgnoreChangeStreams: ignoreChangeStreams,
IgnoreModels: ignoreModels,
IgnoreProtoBundles: ignoreProtoBundles,
IgnoreCreateSchema: ignoreCreateSchema,
}

if hammer.Scheme(databaseURI) != "spanner" {
Expand Down Expand Up @@ -81,6 +86,7 @@ func init() {
createCmd.Flags().Bool("ignore-change-streams", false, "ignore change streams statements")
createCmd.Flags().Bool("ignore-models", false, "ignore model statements")
createCmd.Flags().Bool("ignore-proto-bundles", false, "ignore proto bundle statements")
createCmd.Flags().Bool("ignore-create-schema", false, "ignore create schema statements")

rootCmd.AddCommand(createCmd)
}
6 changes: 6 additions & 0 deletions cmd/diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,16 @@ var (
if err != nil {
return err
}
ignoreCreateSchema, err := cmd.Flags().GetBool("ignore-create-schema")
if err != nil {
return err
}
ddlOption := &hammer.DDLOption{
IgnoreAlterDatabase: ignoreAlterDatabase,
IgnoreChangeStreams: ignoreChangeStreams,
IgnoreModels: ignoreModels,
IgnoreProtoBundles: ignoreProtoBundles,
IgnoreCreateSchema: ignoreCreateSchema,
}

source1, err := hammer.NewSource(ctx, sourceURI1)
Expand Down Expand Up @@ -94,6 +99,7 @@ func init() {
diffCmd.Flags().Bool("ignore-change-streams", false, "ignore change streams statements")
diffCmd.Flags().Bool("ignore-models", false, "ignore model statements")
diffCmd.Flags().Bool("ignore-proto-bundles", false, "ignore proto bundle statements")
diffCmd.Flags().Bool("ignore-create-schema", false, "ignore create schema statements")

rootCmd.AddCommand(diffCmd)
}
6 changes: 6 additions & 0 deletions cmd/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,16 @@ var (
if err != nil {
return err
}
ignoreCreateSchema, err := cmd.Flags().GetBool("ignore-create-schema")
if err != nil {
return err
}
ddlOption := &hammer.DDLOption{
IgnoreAlterDatabase: ignoreAlterDatabase,
IgnoreChangeStreams: ignoreChangeStreams,
IgnoreModels: ignoreModels,
IgnoreProtoBundles: ignoreProtoBundles,
IgnoreCreateSchema: ignoreCreateSchema,
}

source, err := hammer.NewSource(ctx, sourceURI)
Expand All @@ -74,6 +79,7 @@ func init() {
exportCmd.Flags().Bool("ignore-change-streams", false, "ignore change streams statements")
exportCmd.Flags().Bool("ignore-models", false, "ignore model statements")
exportCmd.Flags().Bool("ignore-proto-bundles", false, "ignore proto bundle statements")
exportCmd.Flags().Bool("ignore-create-schema", false, "ignore create schema statements")

rootCmd.AddCommand(exportCmd)
}
3 changes: 3 additions & 0 deletions internal/hammer/ddl.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ func ParseDDL(uri, schema string, option *DDLOption) (DDL, error) {
if _, ok := stmt.(*ast.CreateProtoBundle); ok && option.IgnoreProtoBundles {
continue
}
if _, ok := stmt.(*ast.CreateSchema); ok && option.IgnoreCreateSchema {
continue
}
list = append(list, stmt)
}
return DDL{List: list}, nil
Expand Down
17 changes: 17 additions & 0 deletions internal/hammer/ddl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,23 @@ OPTIONS (
want: `CREATE TABLE Users (
UserID STRING(10) NOT NULL,
Name STRING(10) NOT NULL
) PRIMARY KEY (UserID);`,
},
{
name: "Ignore create schema",
schema: `CREATE SCHEMA sch1;

CREATE TABLE Users (
UserID STRING(10) NOT NULL, -- comment
Name STRING(10) NOT NULL, -- comment
) PRIMARY KEY(UserID);
`,
option: &hammer.DDLOption{
IgnoreCreateSchema: true,
},
want: `CREATE TABLE Users (
UserID STRING(10) NOT NULL,
Name STRING(10) NOT NULL
) PRIMARY KEY (UserID);`,
},
}
Expand Down
35 changes: 34 additions & 1 deletion internal/hammer/diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ func Diff(ddl1, ddl2 DDL) (DDL, error) {

func NewDatabase(ddl DDL) (*Database, error) {
var (
schemas []*Schema
tables []*Table
changeStreams []*ChangeStream
views []*View
Expand All @@ -43,6 +44,8 @@ func NewDatabase(ddl DDL) (*Database, error) {
m := make(map[string]*Table)
for _, istmt := range ddl.List {
switch stmt := istmt.(type) {
case *ast.CreateSchema:
schemas = append(schemas, &Schema{CreateSchema: stmt})
case *ast.CreateTable:
t := &Table{CreateTable: stmt}
tables = append(tables, t)
Expand Down Expand Up @@ -105,10 +108,11 @@ func NewDatabase(ddl DDL) (*Database, error) {
}
}

return &Database{tables: tables, changeStreams: changeStreams, views: views, roles: roles, grants: grants, alterDatabaseOptions: alterDatabaseOptions, options: options}, nil
return &Database{schemas: schemas, tables: tables, changeStreams: changeStreams, views: views, roles: roles, grants: grants, alterDatabaseOptions: alterDatabaseOptions, options: options}, nil
}

type Database struct {
schemas []*Schema
tables []*Table
changeStreams []*ChangeStream
views []*View
Expand Down Expand Up @@ -211,6 +215,10 @@ type Table struct {
changeStreams []*ChangeStream
}

type Schema struct {
*ast.CreateSchema
}

type View struct {
*ast.CreateView
}
Expand Down Expand Up @@ -266,6 +274,13 @@ func (g *Generator) GenerateDDL() DDL {
// for alter database
ddl.AppendDDL(g.generateDDLForAlterDatabaseOptions())

// create schemas before any object that may be created inside them
for _, toSchema := range g.to.schemas {
if _, exists := g.findSchemaByName(g.from.schemas, identsToComparable(toSchema.Name)); !exists {
ddl.Append(toSchema)
}
}

// for alter table
var constraintTargets []*Table
for _, toTable := range g.to.tables {
Expand Down Expand Up @@ -404,6 +419,13 @@ func (g *Generator) GenerateDDL() DDL {
}
}

// drop schemas after every object inside them has been dropped
for _, fromSchema := range g.from.schemas {
if _, exists := g.findSchemaByName(g.to.schemas, identsToComparable(fromSchema.Name)); !exists {
ddl.Append(&ast.DropSchema{Name: fromSchema.Name})
}
}

return ddl
}

Expand Down Expand Up @@ -1514,6 +1536,17 @@ func (g *Generator) generateDDLForDropChangeStream(changeStream *ChangeStream) D
return ddl
}

func (g *Generator) findSchemaByName(schemas []*Schema, name string) (schema *Schema, exists bool) {
for _, s := range schemas {
if identsToComparable(s.Name) == name {
schema = s
exists = true
break
}
}
return
}

func (g *Generator) findViewByName(views []*View, name string) (view *View, exists bool) {
for _, v := range views {
if identsToComparable(v.Name.Idents...) == name {
Expand Down
107 changes: 107 additions & 0 deletions internal/hammer/diff_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2557,6 +2557,113 @@ AS SELECT * FROM t1;
`DROP ROLE role2`,
},
},
// === SCHEMA ===
{
name: "create schema",
from: ``,
to: `
CREATE SCHEMA sch1;
`,
expected: []string{
`CREATE SCHEMA sch1`,
},
},
{
name: "drop schema",
from: `
CREATE SCHEMA sch1;
CREATE SCHEMA sch2;
`,
to: `
CREATE SCHEMA sch1;
`,
expected: []string{
`DROP SCHEMA sch2`,
},
},
{
name: "schema unchanged is a no-op",
from: `
CREATE SCHEMA sch1;
`,
to: `
CREATE SCHEMA sch1;
`,
expected: nil,
},
{
name: "create schema before table in that schema",
from: ``,
to: `
CREATE SCHEMA sch1;
CREATE TABLE sch1.t1 (
t1_1 INT64 NOT NULL,
) PRIMARY KEY(t1_1);
`,
expected: []string{
`CREATE SCHEMA sch1`,
`
CREATE TABLE sch1.t1 (
t1_1 INT64 NOT NULL
) PRIMARY KEY (t1_1)`,
},
},
{
name: "drop schema after table in that schema",
from: `
CREATE SCHEMA sch1;
CREATE TABLE sch1.t1 (
t1_1 INT64 NOT NULL,
) PRIMARY KEY(t1_1);
`,
to: ``,
expected: []string{
`DROP TABLE sch1.t1`,
`DROP SCHEMA sch1`,
},
},
{
name: "create schema before schema-qualified table, index and view",
from: ``,
to: `
CREATE SCHEMA sch1;
CREATE TABLE sch1.t1 (
id INT64 NOT NULL,
name STRING(MAX),
) PRIMARY KEY(id);
CREATE INDEX idx1 ON sch1.t1(name);
CREATE VIEW sch1.v1 SQL SECURITY INVOKER AS SELECT id FROM sch1.t1;
`,
expected: []string{
`CREATE SCHEMA sch1`,
`
CREATE TABLE sch1.t1 (
id INT64 NOT NULL,
name STRING(MAX)
) PRIMARY KEY (id)`,
`CREATE INDEX idx1 ON sch1.t1(name)`,
`CREATE VIEW sch1.v1 SQL SECURITY INVOKER AS SELECT id FROM sch1.t1`,
},
},
{
name: "drop schema after its qualified table, index and view",
from: `
CREATE SCHEMA sch1;
CREATE TABLE sch1.t1 (
id INT64 NOT NULL,
name STRING(MAX),
) PRIMARY KEY(id);
CREATE INDEX idx1 ON sch1.t1(name);
CREATE VIEW sch1.v1 SQL SECURITY INVOKER AS SELECT id FROM sch1.t1;
`,
to: ``,
expected: []string{
`DROP INDEX idx1`,
`DROP TABLE sch1.t1`,
`DROP VIEW sch1.v1`,
`DROP SCHEMA sch1`,
},
},
// === GRANT / REVOKE ===
{
name: "grant role",
Expand Down
1 change: 1 addition & 0 deletions internal/hammer/source.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ type DDLOption struct {
IgnoreChangeStreams bool
IgnoreModels bool
IgnoreProtoBundles bool
IgnoreCreateSchema bool
}

func NewSource(ctx context.Context, uri string) (Source, error) {
Expand Down
Loading