//InTransaction executes function in the db transaction and set it to the context func InTransaction(context middleware.Context, dataStore db.DB, level transaction.Type, f func() error) error { if context["transaction"] != nil { return fmt.Errorf("cannot create nested transaction") } aTransaction, err := dataStore.Begin() if err != nil { return fmt.Errorf("cannot create transaction: %v", err) } defer aTransaction.Close() err = aTransaction.SetIsolationLevel(level) if err != nil { return fmt.Errorf("error when setting isolation level '%s': %s", level, err) } context["transaction"] = aTransaction err = f() if err != nil { return err } err = aTransaction.Commit() if err != nil { return fmt.Errorf("commit error : %s", err) } delete(context, "transaction") return nil }
// DeleteResource deletes the resource specified by the schema and ID func DeleteResource(context middleware.Context, dataStore db.DB, resourceSchema *schema.Schema, resourceID string, ) error { context["id"] = resourceID environmentManager := extension.GetManager() environment, ok := environmentManager.GetEnvironment(resourceSchema.ID) if !ok { return fmt.Errorf("No environment for schema") } auth := context["auth"].(schema.Authorization) policy, err := loadPolicy(context, "delete", strings.Replace(resourceSchema.GetSingleURL(), ":id", resourceID, 1), auth) if err != nil { return err } context["policy"] = policy preTransaction, err := dataStore.Begin() if err != nil { return fmt.Errorf("cannot create transaction: %v", err) } tenantIDs := policy.GetTenantIDFilter(schema.ActionDelete, auth.TenantID()) filter := transaction.IDFilter(resourceID) if tenantIDs != nil { filter["tenant_id"] = tenantIDs } resource, fetchErr := preTransaction.Fetch(resourceSchema, filter) preTransaction.Close() if resource != nil { context["resource"] = resource.Data() } if err := extension.HandleEvent(context, environment, "pre_delete"); err != nil { return err } if fetchErr != nil { return ResourceError{err, "", NotFound} } if err := InTransaction( context, dataStore, transaction.GetIsolationLevel(resourceSchema, schema.ActionDelete), func() error { return DeleteResourceInTransaction(context, resourceSchema, resourceID) }, ); err != nil { return err } if err := extension.HandleEvent(context, environment, "post_delete"); err != nil { return err } return nil }
//InTransaction executes function in the db transaction and set it to the context func InTransaction(context middleware.Context, dataStore db.DB, f func() error) error { if context["transaction"] != nil { return fmt.Errorf("cannot create nested transaction") } aTransaction, err := dataStore.Begin() if err != nil { return fmt.Errorf("cannot create transaction: %v", err) } defer aTransaction.Close() context["transaction"] = aTransaction err = f() if err != nil { return err } err = aTransaction.Commit() if err != nil { return fmt.Errorf("commit error : %s", err) } delete(context, "transaction") return nil }
// CreateOrUpdateResource updates resource if it existed and otherwise creates it and returns true. func CreateOrUpdateResource( context middleware.Context, dataStore db.DB, identityService middleware.IdentityService, resourceSchema *schema.Schema, resourceID string, dataMap map[string]interface{}, ) (bool, error) { auth := context["auth"].(schema.Authorization) //LoadPolicy policy, err := loadPolicy(context, "update", strings.Replace(resourceSchema.GetSingleURL(), ":id", resourceID, 1), auth) if err != nil { return false, err } preTransaction, err := dataStore.Begin() if err != nil { return false, fmt.Errorf("cannot create transaction: %v", err) } tenantIDs := policy.GetTenantIDFilter(schema.ActionUpdate, auth.TenantID()) filter := transaction.IDFilter(resourceID) if tenantIDs != nil { filter["tenant_id"] = tenantIDs } _, fetchErr := preTransaction.Fetch(resourceSchema, filter) preTransaction.Close() if fetchErr != nil { dataMap["id"] = resourceID if err := CreateResource(context, dataStore, identityService, resourceSchema, dataMap); err != nil { return false, err } return true, err } return false, UpdateResource(context, dataStore, identityService, resourceSchema, resourceID, dataMap) }
networkResource *schema.Resource wrappedTestDB db.DB possibleEvent gohan_sync.Event ) BeforeEach(func() { manager := schema.GetManager() var ok bool networkSchema, ok = manager.Schema("network") Expect(ok).To(BeTrue()) network := getNetwork("Red", "red") var err error networkResource, err = manager.LoadResource("network", network) Expect(err).ToNot(HaveOccurred()) wrappedTestDB = &srv.DbSyncWrapper{DB: testDB} tx, err := wrappedTestDB.Begin() defer tx.Close() Expect(err).ToNot(HaveOccurred()) Expect(tx.Create(networkResource)).To(Succeed()) Expect(tx.Commit()).To(Succeed()) }) Describe("Updating state", func() { Context("Invoked correctly", func() { It("Should work", func() { possibleEvent = gohan_sync.Event{ Action: "this is ignored here", Data: map[string]interface{}{ "version": float64(1), "error": "", "state": "Ni malvarmetas",
"description": "red server", "cidr": "10.0.0.0/24"} serverResource, err = manager.LoadResource("server", server) Expect(err).ToNot(HaveOccurred()) }) JustBeforeEach(func() { os.Remove(conn) dataStore, err = db.ConnectDB(dbType, conn, db.DefaultMaxOpenConn) Expect(err).ToNot(HaveOccurred()) for _, s := range manager.Schemas() { Expect(dataStore.RegisterTable(s, false)).To(Succeed()) } tx, err = dataStore.Begin() Expect(err).ToNot(HaveOccurred()) }) AfterEach(func() { tx.Close() }) Describe("Using sql", func() { BeforeEach(func() { if os.Getenv("MYSQL_TEST") == "true" { conn = "root@/gohan_test" dbType = "mysql" } else { conn = "./test.db" dbType = "sqlite3"
//DBBegin starts transaction func DBBegin(connection db.DB) (transaction.Transaction, error) { return connection.Begin() }