// Persist persists an object in DB. // // If `object.IsNew()` equals true object will be inserted. // Otherwise, it will found using `object.GetId()` and updated. func (em EntityManager) Persist(object entities.Entity) (err error) { if object.IsNew() { _, err = em.driver.Insert(object) } else { err = em.driver.Update(object) } return }
// Insert inserts the entity to a DB func (d *Driver) Insert(object entities.Entity) (id int64, err error) { value, tableName, err := getTypeData(object) if err != nil { return 0, err } fieldsCount := value.NumField() var fieldNames []string var fieldValues []string for i := 0; i < fieldsCount; i++ { field := value.Field(i) tag := field.Tag.Get("db") if tag == "" { continue } fieldNames = append(fieldNames, tag) fieldValues = append(fieldValues, ":"+tag) } query := "INSERT INTO " + tableName + " (" + strings.Join(fieldNames, ", ") + ") VALUES (" + strings.Join(fieldValues, ", ") + ");" var result sql.Result switch object := object.(type) { case *entities.AuthorizedTransaction: result, err = d.database.NamedExec(query, object) case *entities.AllowedFi: result, err = d.database.NamedExec(query, object) case *entities.AllowedUser: result, err = d.database.NamedExec(query, object) case *entities.SentTransaction: result, err = d.database.NamedExec(query, object) case *entities.ReceivedPayment: result, err = d.database.NamedExec(query, object) } if err != nil { return } id, err = result.LastInsertId() if id == 0 { // Not autoincrement if object.GetID() == nil { return 0, fmt.Errorf("Not autoincrement but ID nil") } id = *object.GetID() } if err == nil { object.SetID(id) object.SetExists() } return }
// GetOne returns a single entity based on a seach conditions func (d *Driver) GetOne(object entities.Entity, where string, params ...interface{}) (entities.Entity, error) { _, tableName, err := getTypeData(object) if err != nil { return nil, err } err = d.database.Get(object, "SELECT * FROM "+tableName+" WHERE "+where+" LIMIT 1;", params...) if err != nil { if err.Error() == "sql: no rows in result set" { return nil, nil } return nil, err } object.SetExists() // Mark this entity as existing return object, err }
// Insert inserts the entity to a DB func (d *Driver) Insert(object entities.Entity) (id int64, err error) { value, tableName, err := getTypeData(object) if err != nil { return 0, err } fieldsCount := value.NumField() var fieldNames []string var fieldValues []string for i := 0; i < fieldsCount; i++ { field := value.Field(i) tag := field.Tag.Get("db") if tag == "" { continue } if tag == "id" && object.GetID() == nil { // To handle error: // null value in column "id" violates not-null constraint continue } fieldNames = append(fieldNames, tag) fieldValues = append(fieldValues, ":"+tag) } query := "INSERT INTO " + tableName + " (" + strings.Join(fieldNames, ", ") + ") VALUES (" + strings.Join(fieldValues, ", ") + ") RETURNING id;" // TODO cache prepared statement stmt, err := d.database.PrepareNamed(query) if err != nil { return } switch object := object.(type) { case *entities.AuthorizedTransaction: err = stmt.Get(&id, object) case *entities.SentTransaction: err = stmt.Get(&id, object) case *entities.ReceivedPayment: err = stmt.Get(&id, object) } if err != nil { return } if id == 0 { // Not autoincrement if object.GetID() == nil { return 0, fmt.Errorf("Not autoincrement but ID nil") } id = *object.GetID() } if err == nil { object.SetID(id) object.SetExists() } return }