vitess.io/vitess@v0.16.2/go/vt/schemadiff/diff.go (about) 1 package schemadiff 2 3 import ( 4 "vitess.io/vitess/go/vt/sqlparser" 5 ) 6 7 // DDLActionStr returns the action implied by the given diff: CREATE", "DROP", "ALTER" or empty 8 func DDLActionStr(diff EntityDiff) (string, error) { 9 if diff == nil { 10 return "", nil 11 } 12 if ddl, ok := diff.Statement().(sqlparser.DDLStatement); ok { 13 return ddl.GetAction().ToString(), nil 14 } 15 return "", ErrUnexpectedDiffAction 16 } 17 18 // AllSubsequent returns a list of diffs starting the given diff and followed by all subsequent diffs, if any 19 func AllSubsequent(diff EntityDiff) (diffs []EntityDiff) { 20 for diff != nil && !diff.IsEmpty() { 21 diffs = append(diffs, diff) 22 diff = diff.SubsequentDiff() 23 } 24 return diffs 25 } 26 27 // DiffCreateTablesQueries compares two `CREATE TABLE ...` queries (in string form) and returns the diff from table1 to table2. 28 // Either or both of the queries can be empty. Based on this, the diff could be 29 // nil, CreateTable, DropTable or AlterTable 30 func DiffCreateTablesQueries(query1 string, query2 string, hints *DiffHints) (EntityDiff, error) { 31 var fromCreateTable *sqlparser.CreateTable 32 var ok bool 33 if query1 != "" { 34 stmt, err := sqlparser.ParseStrictDDL(query1) 35 if err != nil { 36 return nil, err 37 } 38 fromCreateTable, ok = stmt.(*sqlparser.CreateTable) 39 if !ok { 40 return nil, ErrExpectedCreateTable 41 } 42 } 43 var toCreateTable *sqlparser.CreateTable 44 if query2 != "" { 45 stmt, err := sqlparser.ParseStrictDDL(query2) 46 if err != nil { 47 return nil, err 48 } 49 toCreateTable, ok = stmt.(*sqlparser.CreateTable) 50 if !ok { 51 return nil, ErrExpectedCreateTable 52 } 53 } 54 return DiffTables(fromCreateTable, toCreateTable, hints) 55 } 56 57 // DiffTables compares two tables and returns the diff from table1 to table2. 58 // Either or both of the CreateTable statements can be nil. Based on this, the diff could be 59 // nil, CreateTable, DropTable or AlterTable 60 func DiffTables(create1 *sqlparser.CreateTable, create2 *sqlparser.CreateTable, hints *DiffHints) (EntityDiff, error) { 61 switch { 62 case create1 == nil && create2 == nil: 63 return nil, nil 64 case create1 == nil: 65 c2, err := NewCreateTableEntity(create2) 66 if err != nil { 67 return nil, err 68 } 69 return c2.Create(), nil 70 case create2 == nil: 71 c1, err := NewCreateTableEntity(create1) 72 if err != nil { 73 return nil, err 74 } 75 return c1.Drop(), nil 76 default: 77 c1, err := NewCreateTableEntity(create1) 78 if err != nil { 79 return nil, err 80 } 81 c2, err := NewCreateTableEntity(create2) 82 if err != nil { 83 return nil, err 84 } 85 return c1.Diff(c2, hints) 86 } 87 } 88 89 // DiffCreateViewsQueries compares two `CREATE TABLE ...` queries (in string form) and returns the diff from table1 to table2. 90 // Either or both of the queries can be empty. Based on this, the diff could be 91 // nil, CreateView, DropView or AlterView 92 func DiffCreateViewsQueries(query1 string, query2 string, hints *DiffHints) (EntityDiff, error) { 93 var fromCreateView *sqlparser.CreateView 94 var ok bool 95 if query1 != "" { 96 stmt, err := sqlparser.ParseStrictDDL(query1) 97 if err != nil { 98 return nil, err 99 } 100 fromCreateView, ok = stmt.(*sqlparser.CreateView) 101 if !ok { 102 return nil, ErrExpectedCreateView 103 } 104 } 105 var toCreateView *sqlparser.CreateView 106 if query2 != "" { 107 stmt, err := sqlparser.ParseStrictDDL(query2) 108 if err != nil { 109 return nil, err 110 } 111 toCreateView, ok = stmt.(*sqlparser.CreateView) 112 if !ok { 113 return nil, ErrExpectedCreateView 114 } 115 } 116 return DiffViews(fromCreateView, toCreateView, hints) 117 } 118 119 // DiffViews compares two views and returns the diff from view1 to view2 120 // Either or both of the CreateView statements can be nil. Based on this, the diff could be 121 // nil, CreateView, DropView or AlterView 122 func DiffViews(create1 *sqlparser.CreateView, create2 *sqlparser.CreateView, hints *DiffHints) (EntityDiff, error) { 123 switch { 124 case create1 == nil && create2 == nil: 125 return nil, nil 126 case create1 == nil: 127 c2, err := NewCreateViewEntity(create2) 128 if err != nil { 129 return nil, err 130 } 131 return c2.Create(), nil 132 case create2 == nil: 133 c1, err := NewCreateViewEntity(create1) 134 if err != nil { 135 return nil, err 136 } 137 return c1.Drop(), nil 138 default: 139 c1, err := NewCreateViewEntity(create1) 140 if err != nil { 141 return nil, err 142 } 143 c2, err := NewCreateViewEntity(create2) 144 if err != nil { 145 return nil, err 146 } 147 return c1.Diff(c2, hints) 148 } 149 } 150 151 // DiffSchemasSQL compares two schemas and returns the list of diffs that turn 152 // 1st schema into 2nd. Schemas are build from SQL, each of which can contain an arbitrary number of 153 // CREATE TABLE and CREATE VIEW statements. 154 func DiffSchemasSQL(sql1 string, sql2 string, hints *DiffHints) ([]EntityDiff, error) { 155 schema1, err := NewSchemaFromSQL(sql1) 156 if err != nil { 157 return nil, err 158 } 159 schema2, err := NewSchemaFromSQL(sql2) 160 if err != nil { 161 return nil, err 162 } 163 return schema1.Diff(schema2, hints) 164 } 165 166 // DiffSchemasSQL compares two schemas and returns the list of diffs that turn 167 // 1st schema into 2nd. Any of the schemas may be nil. 168 func DiffSchemas(schema1 *Schema, schema2 *Schema, hints *DiffHints) ([]EntityDiff, error) { 169 if schema1 == nil { 170 schema1 = newEmptySchema() 171 } 172 if schema2 == nil { 173 schema2 = newEmptySchema() 174 } 175 return schema1.Diff(schema2, hints) 176 }