github.com/wawandco/oxplugins@v0.7.11/tools/liquibase/migration.go (about) 1 package liquibase 2 3 import ( 4 "context" 5 "errors" 6 "fmt" 7 "time" 8 9 "github.com/jackc/pgx/v4" 10 ) 11 12 // Migration xml with liquibase format. A migration may be composed 13 // of multiple changesets. 14 type Migration struct { 15 ChangeSets []ChangeSet `xml:"changeSet"` 16 } 17 18 // ChangeSet with SQL and Rollback instructions. 19 type ChangeSet struct { 20 ID string `xml:"id,attr"` 21 Author string `xml:"author,attr"` 22 SQL string `xml:"sql"` 23 RollbackSQL string `xml:"rollback"` 24 } 25 26 // Execute a changeset takes the SQL part of the changeset and runs it. 27 func (cs ChangeSet) Execute(conn *pgx.Conn, file string) error { 28 var err error 29 ctx := context.Background() 30 31 row := conn.QueryRow(context.Background(), `SELECT orderexecuted FROM databasechangelog ORDER BY dateexecuted desc`) 32 var order int 33 if err = row.Scan(&order); err != nil && !errors.Is(err, pgx.ErrNoRows) { 34 return err 35 } 36 37 var count int 38 row = conn.QueryRow(ctx, `SELECT count(*) FROM databasechangelog WHERE id = $1`, cs.ID) 39 if err = row.Scan(&count); err == nil && count > 0 { 40 return nil 41 } 42 43 if err != nil { 44 return err 45 } 46 47 tx, err := conn.BeginTx(ctx, pgx.TxOptions{}) 48 if err != nil { 49 return err 50 } 51 52 _, err = tx.Exec(ctx, cs.SQL) 53 if err != nil { 54 return err 55 } 56 57 insertStmt := ` 58 INSERT 59 INTO databasechangelog (id, author, filename, dateexecuted, orderexecuted,exectype) 60 VALUES ($1, $2, $3, $4, $5, $6); 61 ` 62 63 _, err = tx.Exec(ctx, insertStmt, cs.ID, cs.Author, file, time.Now(), order+1, "EXECUTED") 64 if err != nil { 65 return err 66 } 67 68 err = tx.Commit(ctx) 69 if err != nil { 70 return err 71 } 72 73 fmt.Printf("[info] Executed `%v`.\n", cs.ID) 74 order++ 75 76 return nil 77 } 78 79 // Rollback the changeset runs the Rollback section of the 80 // changeset. 81 func (cs ChangeSet) Rollback(conn *pgx.Conn) error { 82 tx, err := conn.BeginTx(context.Background(), pgx.TxOptions{}) 83 if err != nil { 84 return err 85 } 86 87 fmt.Printf("[info] Rolling back %v. \n", cs.ID) 88 _, err = tx.Exec(context.Background(), cs.RollbackSQL) 89 if err != nil { 90 return err 91 } 92 93 _, err = tx.Exec(context.Background(), `DELETE FROM databasechangelog WHERE id = $1`, cs.ID) 94 if err != nil { 95 return err 96 } 97 98 return tx.Commit(context.Background()) 99 }