|
| 1 | +package mysql |
| 2 | + |
| 3 | +import ( |
| 4 | + "database/sql" |
| 5 | + |
| 6 | + "fmt" |
| 7 | + "github.com/lopezator/migrator" |
| 8 | + "github.com/wework/grabbit/gbus/tx" |
| 9 | +) |
| 10 | + |
| 11 | +//SagaStoreTableMigration creates the service saga store table |
| 12 | +func SagaStoreTableMigration(svcName string) *migrator.Migration { |
| 13 | + tblName := tx.GetSagatableName(svcName) |
| 14 | + |
| 15 | + createTableQuery := `CREATE TABLE IF NOT EXISTS ` + tblName + ` ( |
| 16 | + rec_id INT PRIMARY KEY AUTO_INCREMENT, |
| 17 | + saga_id VARCHAR(255) UNIQUE NOT NULL, |
| 18 | + saga_type VARCHAR(255) NOT NULL, |
| 19 | + saga_data LONGBLOB NOT NULL, |
| 20 | + version integer NOT NULL DEFAULT 0, |
| 21 | + last_update timestamp DEFAULT NOW(), |
| 22 | + INDEX ` + tblName + `_sagatype_idx (saga_type))` |
| 23 | + |
| 24 | + return &migrator.Migration{ |
| 25 | + Name: "create saga store table", |
| 26 | + Func: func(tx *sql.Tx) error { |
| 27 | + if _, err := tx.Exec(createTableQuery); err != nil { |
| 28 | + return err |
| 29 | + } |
| 30 | + return nil |
| 31 | + }, |
| 32 | + } |
| 33 | +} |
| 34 | + |
| 35 | +//OutboxMigrations creates service outbox table |
| 36 | +func OutboxMigrations(svcName string) *migrator.Migration { |
| 37 | + |
| 38 | + query := `CREATE TABLE IF NOT EXISTS ` + getOutboxName(svcName) + ` ( |
| 39 | + rec_id int NOT NULL AUTO_INCREMENT, |
| 40 | + message_id varchar(50) NOT NULL UNIQUE, |
| 41 | + message_type varchar(50) NOT NULL, |
| 42 | + exchange varchar(50) NOT NULL, |
| 43 | + routing_key varchar(50) NOT NULL, |
| 44 | + publishing longblob NOT NULL, |
| 45 | + status int(11) NOT NULL, |
| 46 | + relay_id varchar(50) NULL, |
| 47 | + delivery_tag bigint(20) NOT NULL, |
| 48 | + delivery_attempts int NOT NULL DEFAULT 0, |
| 49 | + insert_date timestamp DEFAULT CURRENT_TIMESTAMP, |
| 50 | + PRIMARY KEY(rec_id), |
| 51 | + INDEX status_delivery (rec_id, status, delivery_attempts))` |
| 52 | + |
| 53 | + return &migrator.Migration{ |
| 54 | + Name: "create outbox table", |
| 55 | + Func: func(tx *sql.Tx) error { |
| 56 | + if _, err := tx.Exec(query); err != nil { |
| 57 | + return err |
| 58 | + } |
| 59 | + return nil |
| 60 | + }, |
| 61 | + } |
| 62 | +} |
| 63 | + |
| 64 | +//TimoutTableMigration creates the service timeout table, where timeouts are persisted |
| 65 | +func TimoutTableMigration(svcName string) *migrator.Migration { |
| 66 | + tblName := GetTimeoutsTableName(svcName) |
| 67 | + |
| 68 | + createTableQuery := `CREATE TABLE IF NOT EXISTS ` + tblName + ` ( |
| 69 | + rec_id INT PRIMARY KEY AUTO_INCREMENT, |
| 70 | + saga_id VARCHAR(255) UNIQUE NOT NULL, |
| 71 | + timeout DATETIME NOT NULL, |
| 72 | + INDEX (timeout), |
| 73 | + INDEX (saga_id) |
| 74 | + )` |
| 75 | + |
| 76 | + return &migrator.Migration{ |
| 77 | + Name: "create timeout table", |
| 78 | + Func: func(tx *sql.Tx) error { |
| 79 | + if _, err := tx.Exec(createTableQuery); err != nil { |
| 80 | + return err |
| 81 | + } |
| 82 | + return nil |
| 83 | + }, |
| 84 | + } |
| 85 | +} |
| 86 | + |
| 87 | +//EnsureSchema implements Grabbit's migrations strategy |
| 88 | +func EnsureSchema(db *sql.DB, svcName string) { |
| 89 | + migrationsTable := fmt.Sprintf("grabbitMigrations_%s", svcName) |
| 90 | + |
| 91 | + migrate, err := migrator.New(migrator.TableName(migrationsTable), migrator.Migrations( |
| 92 | + OutboxMigrations(svcName), |
| 93 | + SagaStoreTableMigration(svcName), |
| 94 | + TimoutTableMigration(svcName), |
| 95 | + )) |
| 96 | + if err != nil { |
| 97 | + panic(err) |
| 98 | + } |
| 99 | + err = migrate.Migrate(db) |
| 100 | + if err != nil { |
| 101 | + panic(err) |
| 102 | + } |
| 103 | +} |
0 commit comments