// releasesCreate creates a new Release and inserts it into the database. func releasesCreate(db *gorm.DB, release *Release) (*Release, error) { t := db.Begin() // Get the last release version for this app. v, err := releasesLastVersion(t, release.App.ID) if err != nil { t.Rollback() return release, err } // Increment the release version. release.Version = v + 1 if err := t.Create(release).Error; err != nil { t.Rollback() return release, err } if err := t.Commit().Error; err != nil { t.Rollback() return release, err } return release, nil }
// DeleteCreatedEntities records all created entities on the gorm.DB connection // and returns a function which can be called on defer to delete created // entities in reverse order on function exit. // // In addition to that, the WIT cache is cleared as well in order to respect any // deletions made to the db. // // Usage: // // func TestDatabaseActions(t *testing.T) { // // // setup database connection // db := .... // // setup auto clean up of created entities // defer DeleteCreatedEntities(db)() // // repo := NewRepo(db) // repo.Create(X) // repo.Create(X) // repo.Create(X) // } // // Output: // // 2017/01/31 12:08:08 Deleting from x 6d143405-1232-40de-bc73-835b543cd972 // 2017/01/31 12:08:08 Deleting from x 0685068d-4934-4d9a-bac2-91eebbca9575 // 2017/01/31 12:08:08 Deleting from x 2d20944e-7952-40c1-bd15-f3fa1a70026d func DeleteCreatedEntities(db *gorm.DB) func() { hookName := "mighti:record" type entity struct { table string keyname string key interface{} } var entires []entity db.Callback().Create().After("gorm:create").Register(hookName, func(scope *gorm.Scope) { entires = append(entires, entity{table: scope.TableName(), keyname: scope.PrimaryKey(), key: scope.PrimaryKeyValue()}) }) return func() { defer db.Callback().Create().Remove(hookName) tx := db.Begin() for i := len(entires) - 1; i >= 0; i-- { entry := entires[i] log.Debug(nil, map[string]interface{}{ "pkg": "cleaner", "table": entry.table, "key": entry.key, }, "Deleting entities from %s with key %s", entry.table, entry.key) tx.Table(entry.table).Where(entry.keyname+" = ?", entry.key).Delete("") } // Delete the work item cache as well // NOTE: Feel free to add more cache freeing calls here as needed. workitem.ClearGlobalWorkItemTypeCache() tx.Commit() } }
// add to a identities soul amount func AddToSoulByObjectID(db *gorm.DB, id string, incrVal float64) (Identity, error) { identity := Identity{} tx := db.Begin() err := tx.Exec(`set transaction isolation level repeatable read`).Error if err != nil { tx.Rollback() return identity, err } // get identity if err = tx.Where(&Identity{ObjectID: id}).First(&identity).Error; err != nil { tx.Rollback() return identity, err } // add to identities soul amount identity.SoulBalance = identity.SoulBalance + incrVal // update identity tx.Save(&identity) tx.Commit() return identity, nil }
//Transfer funds between two accounts and adds an entry to the transfer history func transferFunds(db *gorm.DB, fromID, toID int, amount float64) error { if fromID == toID { return errors.New("Can't transfer from one account to itself") } transact := db.Begin() defer transact.Commit() fromAcc, err := findAccount(transact, &account{ID: fromID}) if err != nil { return err } toAcc, err := findAccount(transact, &account{ID: toID}) if err != nil { return err } if amount > fromAcc.Funds { return errors.New("Cannot transfer more than you've got") } if 1 > amount { return errors.New("You have to transfer more than 0 funds") } fromAcc.Funds -= amount toAcc.Funds += amount transact.Save(fromAcc) transact.Save(toAcc) t := &transfer{FromID: fromID, ToID: toID, Amount: amount} transact.Create(t) return nil }
func lockedMethod(db *gorm.DB, num int, done chan bool) { for i := 0; i < num; i++ { var tt TestTable tx := db.Begin() panicOnError(tx.Raw("SELECT * FROM test_table WHERE id = 1 LIMIT 1 FOR UPDATE").Scan(&tt).Error) tt.Counter -= 1 panicOnError(tx.Save(&tt).Error) panicOnError(tx.Commit().Error) } done <- true }
func transactionMethod(db *gorm.DB, num int, done chan bool) { for i := 0; i < num; i++ { var tt TestTable tx := db.Begin() panicOnError(tx.First(&tt, 1).Error) tt.Counter -= 1 panicOnError(tx.Save(&tt).Error) panicOnError(tx.Commit().Error) } done <- true }
func getSequence(db gorm.DB) (uint64, error) { tx := db.Begin() if err := tx.Model(&Seq{}).Update("id", gorm.Expr("LAST_INSERT_ID(id + 1)")).Error; err != nil { return 0, err } var id uint64 r := tx.Raw("SELECT LAST_INSERT_ID()").Row() r.Scan(&id) return id, nil }
func beginTx(db *gorm.DB) func() { tx := db.Begin() tx.LogMode(true) return func() { if err := recover(); err != nil { tx.Rollback() panic(err) } else { tx.Commit() } } }
// Transactional executes the given function in a transaction. If todo returns an error, the transaction is rolled back func Transactional(db *gorm.DB, todo func(tx *gorm.DB) error) error { var tx *gorm.DB tx = db.Begin() if tx.Error != nil { return tx.Error } if err := todo(tx); err != nil { tx.Rollback() return errs.WithStack(err) } tx.Commit() return tx.Error }
//Deposits funds for a certain account and adds to the deposit transactional history func depositFunds(db *gorm.DB, accountID int, amount float64) error { transact := db.Begin() acc, err := findAccount(transact, &account{ID: accountID}) if err != nil { return err } if amount < 0 { return errors.New("Can't deposite negative amounts") } defer transact.Commit() acc.Funds += amount transact.Save(acc) dep := &deposit{AccountID: acc.ID, Amount: amount} transact.Create(dep) return nil }
//Withdraws funds for a certain account and adds to the withdrawal transactional history func withdrawFunds(db *gorm.DB, accountID int, amount float64) error { transact := db.Begin() defer transact.Commit() acc, err := findAccount(transact, &account{ID: accountID}) if err != nil { return err } if amount < 0 { return errors.New("Can't withdraw negative amounts") } if acc.Funds < amount { return errors.New("Can't withdraw more money than you've got") } acc.Funds -= amount transact.Save(acc) w := &withdrawal{AccountID: accountID, Amount: amount} transact.Create(w) return nil }
serviceManager.LoadConfig("config_test.json") serviceMode := serviceManager.ViperConfig.GetString("service.mode") dbDetail := serviceManager.ViperConfig.GetStringMapString(fmt.Sprintf("service.datastore.%s", serviceMode)) db, err := serviceManager.InitDB(dbDetail) dbConn = &db utility = Utility{dbConn} if err != nil { Panic() } }) Describe("Save Country and other releated data", func() { Context("Save Country", func() { It("Return country id", func() { tx := dbConn.Begin() if err := tx.Create(&country).Error; err != nil { tx.Rollback() } tx.Commit() tx.Close() Expect(country.ID).To(BeNumerically(">", 0)) }) It("Return country id", func() { tx := dbConn.Begin() if err := tx.Create(&ngnCountry).Error; err != nil { tx.Rollback() } tx.Commit() tx.Close() Expect(ngnCountry.ID).To(BeNumerically(">", 0))