// upsert insert a record or update it if given primary key exists. // Limitation: The current implementation does not handle confilicts between // transactions. So there must be an external lock to make sure there is only // one transaction at the same time. func upsert(tx execer, s interface{}) error { var r *sc.Record switch s.(type) { case *sc.Record: r = s.(*sc.Record) default: r = sc.NewRecord(s) } // ignore nil record if r == nil { return nil } q := insertIgnoreQuery(r) result, err := q.Do(tx) if err != nil { return fmt.Errorf("%v -> %v", err, q) } n, err := result.RowsAffected() if err != nil { return err } if n == 0 { q := updateQuery(r) result, err := q.Do(tx) if err != nil { return err } n, err := result.RowsAffected() if err != nil { return err } if n == 0 { return fmt.Errorf("failed to update row: %v", q) } } return nil }
func TestSqlstore(t *testing.T) { type StructType struct { ID int `sql:"pk"` IDOther int `sql:"pk"` SVal string IVal int PVal *int } s := &StructType{ID: 1, IDOther: 2, SVal: "S", IVal: 9} r := schema.NewRecord(s) //.SetKey("Id", "IdOther") fmt.Println(r) for _, f := range r.Fields { fmt.Println(f) } fmt.Println(insertIgnoreQuery(r)) fmt.Println(updateQuery(r)) fmt.Println(deleteQuery(r)) }
// delete deletes a record of a given primary key. func deleteRecord(tx execer, s interface{}) error { var r *sc.Record switch s.(type) { case *sc.Record: r = s.(*sc.Record) default: r = sc.NewRecord(s) } // ignore nil record if r == nil { return nil } q := deleteQuery(r) _, err := q.Do(tx) if err != nil { return fmt.Errorf("%v -> %v", err, q) } return nil }