Commit ebf651fe authored by Amos Wenger's avatar Amos Wenger

Fix some tests + better error wrapping

parent a03f88d2
Pipeline #11011 failed with stage
in 20 seconds
......@@ -2,6 +2,7 @@ package hades_test
import (
"context"
"fmt"
"testing"
"time"
......@@ -269,6 +270,6 @@ func Test_AutoMigrateSquash(t *testing.T) {
func ordie(err error) {
if err != nil {
panic(err)
panic(fmt.Sprintf("%+v", err))
}
}
......@@ -88,13 +88,7 @@ func Test_BelongsTo(t *testing.T) {
}
wtest.Must(t, c.Save(conn, joke))
c.Preload(conn, &hades.PreloadParams{
Record: joke,
Fields: []hades.PreloadField{
{Name: "Human"},
{Name: "Human.Fate"},
},
})
c.Preload(conn, joke, hades.Assoc("Human", hades.Assoc("Fate")))
assert.NotNil(t, joke.Human)
assert.NotNil(t, joke.Human.Fate)
assert.EqualValues(t, "Space rodeo", joke.Human.Fate.Desc)
......
......@@ -121,7 +121,7 @@ func iseq(sf *StructField, v1f reflect.Value, v2f reflect.Value) (bool, error) {
func (cf ChangedFields) ToEq() builder.Eq {
eq := make(builder.Eq)
for sf, v := range cf {
eq[sf.DBName] = DBValue(v)
eq[EscapeIdentifier(sf.DBName)] = DBValue(v)
}
return eq
}
package hades
import (
"fmt"
"reflect"
"github.com/pkg/errors"
......@@ -44,7 +43,7 @@ func (field *Field) Set(value interface{}) (err error) {
if reflectValue.Type().ConvertibleTo(fieldValue.Type()) {
fieldValue.Set(reflectValue.Convert(fieldValue.Type()))
} else {
err = fmt.Errorf("could not convert argument of field %s from %s to %s", field.Name, reflectValue.Type(), fieldValue.Type())
err = errors.Errorf("could not convert argument of field %s from %s to %s", field.Name, reflectValue.Type(), fieldValue.Type())
}
}
} else {
......
......@@ -32,8 +32,7 @@ func withContext(t *testing.T, models []interface{}, f WithContextFunc) {
wtest.Must(t, err)
c.Log = true
// wtest.Must(t, c.AutoMigrate(conn))
c.AutoMigrate(conn)
wtest.Must(t, c.AutoMigrate(conn))
f(conn, c)
}
......@@ -67,40 +67,35 @@ func Test_HasMany(t *testing.T) {
},
}
programmers := []*Programmer{p1, p2}
wtest.Must(t, c.Save(conn, &hades.SaveParams{Record: programmers}))
wtest.Must(t, c.Save(conn, programmers, hades.Assoc("Qualities")))
assertCount(&Programmer{}, 2)
assertCount(&Quality{}, 5)
p1bis := &Programmer{ID: 3}
wtest.Must(t, c.Preload(conn, p1bis, hades.Field("Qualities")))
wtest.Must(t, c.Preload(conn, p1bis, hades.Assoc("Qualities")))
assert.EqualValues(t, 3, len(p1bis.Qualities), "preload has_many")
wtest.Must(t, c.Preload(conn, p1bis, hades.Field("Qualities")))
wtest.Must(t, c.Preload(conn, p1bis, hades.Assoc("Qualities")))
assert.EqualValues(t, 3, len(p1bis.Qualities), "preload replaces, doesn't append")
pp.Fields[0] = hades.PreloadField{
Name: "Qualities",
Search: hades.Search().OrderBy("id asc"),
}
wtest.Must(t, c.Preload(conn, pp))
wtest.Must(t, c.Preload(conn, p1bis,
hades.AssocWithSearch("Qualities", hades.Search().OrderBy("id ASC"))),
)
assert.EqualValues(t, "Inspiration", p1bis.Qualities[0].Label, "orders by (asc)")
pp.Fields[0] = hades.PreloadField{
Name: "Qualities",
Search: hades.Search().OrderBy("id desc"),
}
wtest.Must(t, c.Preload(conn, pp))
wtest.Must(t, c.Preload(conn, p1bis,
hades.AssocWithSearch("Qualities", hades.Search().OrderBy("id DESC"))),
)
assert.EqualValues(t, "Inspiration again", p1bis.Qualities[0].Label, "orders by (desc)")
// no fields
assert.Error(t, c.Preload(conn, &hades.PreloadParams{Record: p1bis}))
assert.Error(t, c.Preload(conn, p1bis))
// not a model
assert.Error(t, c.Preload(conn, &hades.PreloadParams{Record: 42, Fields: pp.Fields}))
assert.Error(t, c.Preload(conn, 42, hades.Assoc("Qualities")))
// non-existent relation
assert.Error(t, c.Preload(conn, &hades.PreloadParams{Record: p1bis, Fields: []hades.PreloadField{{Name: "Woops"}}}))
assert.Error(t, c.Preload(conn, 42, hades.Assoc("Woops")))
})
}
......@@ -149,10 +144,7 @@ func Test_HasManyThorough(t *testing.T) {
t.Logf("...snip tons of INSERT...")
c.Log = false
ordie(c.Save(conn, &hades.SaveParams{
Record: car,
Assocs: []string{"Traits"},
}))
ordie(c.Save(conn, car, hades.Assoc("Traits")))
c.Log = true
numTraits := len(car.Traits)
......@@ -163,20 +155,13 @@ func Test_HasManyThorough(t *testing.T) {
car.Traits = nil
ordie(c.Save(conn, &hades.SaveParams{
Record: car,
Assocs: []string{"Traits"},
DontCull: []interface{}{&Trait{}},
}))
ordie(c.Save(conn, car, hades.Assoc("Traits")))
traitCount, err = c.Count(conn, &Trait{}, builder.NewCond())
ordie(err)
assert.EqualValues(t, numTraits, traitCount, "traits should still exist after partial-join save")
ordie(c.Save(conn, &hades.SaveParams{
Record: car,
Assocs: []string{"Traits"},
}))
ordie(c.Save(conn, car, hades.AssocReplace("Traits")))
traitCount, err = c.Count(conn, &Trait{}, builder.NewCond())
ordie(err)
......
......@@ -51,12 +51,12 @@ func Test_HasOne(t *testing.T) {
assert.EqualValues(t, expectedCount, count)
}
wtest.Must(t, c.Save(conn, &hades.SaveParams{Record: country, Assocs: []string{"Specialty"}}))
wtest.Must(t, c.Save(conn, country, hades.OmitRoot(), hades.Assoc("Specialty", hades.Assoc("Drawback"))))
assertCount(&Country{}, 0)
assertCount(&Specialty{}, 1)
assertCount(&Drawback{}, 1)
wtest.Must(t, c.Save(conn, &hades.SaveParams{Record: country}))
wtest.Must(t, c.Save(conn, country, hades.Assoc("Specialty", hades.Assoc("Drawback"))))
assertCount(&Country{}, 1)
assertCount(&Specialty{}, 1)
assertCount(&Drawback{}, 1)
......@@ -70,12 +70,8 @@ func Test_HasOne(t *testing.T) {
countries = append(countries, country)
}
wtest.Must(t, c.Preload(conn, &hades.PreloadParams{
Record: countries,
Fields: []hades.PreloadField{
{Name: "Specialty"},
{Name: "Specialty.Drawback"},
},
}))
wtest.Must(t, c.Preload(conn, countries,
hades.Assoc("Specialty",
hades.Assoc("Drawback"))))
})
}
......@@ -32,7 +32,7 @@ func (scope *Scope) ToEq(rec reflect.Value) builder.Eq {
if !sf.IsNormal {
return
}
eq[sf.DBName] = DBValue(field.Interface())
eq[EscapeIdentifier(sf.DBName)] = DBValue(field.Interface())
}
for _, sf := range scope.GetModelStruct().StructFields {
......
......@@ -39,9 +39,7 @@ func Test_ManyToMany(t *testing.T) {
},
}
t.Logf("saving just fr")
wtest.Must(t, c.Save(conn, &hades.SaveParams{
Record: fr,
}))
wtest.Must(t, c.Save(conn, fr, hades.Assoc("Words")))
assertCount := func(model interface{}, expectedCount int64) {
t.Helper()
......@@ -62,10 +60,7 @@ func Test_ManyToMany(t *testing.T) {
},
}
t.Logf("saving fr+en")
wtest.Must(t, c.Save(conn, &hades.SaveParams{
Record: []*Language{fr, en},
}))
wtest.Must(t, c.Save(conn, []*Language{fr, en}, hades.Assoc("Words")))
assertCount(&Language{}, 2)
assertCount(&Word{}, 2)
assertCount(&LanguageWord{}, 4)
......@@ -75,19 +70,14 @@ func Test_ManyToMany(t *testing.T) {
{ID: "Wreck"},
{ID: "Nervous"},
}
wtest.Must(t, c.Save(conn, &hades.SaveParams{
Record: []*Language{en},
DontCull: []interface{}{&LanguageWord{}},
}))
wtest.Must(t, c.Save(conn, []*Language{en}, hades.Assoc("Words")))
assertCount(&Language{}, 2)
assertCount(&Word{}, 4)
assertCount(&LanguageWord{}, 6)
t.Logf("replacing all english words")
wtest.Must(t, c.Save(conn, &hades.SaveParams{
Record: []*Language{en},
}))
wtest.Must(t, c.Save(conn, []*Language{en}, hades.AssocReplace("Words")))
assertCount(&Language{}, 2)
assertCount(&Word{}, 4)
......@@ -95,10 +85,7 @@ func Test_ManyToMany(t *testing.T) {
t.Logf("adding commentary")
en.Words[0].Comment = "punk band reference"
wtest.Must(t, c.Save(conn, &hades.SaveParams{
Record: []*Language{en},
}))
wtest.Must(t, c.Save(conn, []*Language{en}, hades.Assoc("Words")))
assertCount(&Language{}, 2)
assertCount(&Word{}, 4)
assertCount(&LanguageWord{}, 4)
......@@ -115,12 +102,7 @@ func Test_ManyToMany(t *testing.T) {
{ID: fr.ID},
{ID: en.ID},
}
err := c.Preload(conn, &hades.PreloadParams{
Record: langs,
Fields: []hades.PreloadField{
{Name: "Words"},
},
})
err := c.Preload(conn, langs, hades.Assoc("Words"))
// many_to_many preload is not implemented
assert.Error(t, err)
})
......@@ -179,9 +161,29 @@ func Test_ManyToManyRevenge(t *testing.T) {
}
}
p := makeProfile()
c.Save(conn, &hades.SaveParams{
Record: p,
})
wtest.Must(t, c.Save(conn, p,
hades.Assoc("ProfileGames",
hades.Assoc("Game"),
),
))
var names []struct {
Name string
}
wtest.Must(t, c.ExecWithSearch(conn,
builder.Select("games.title").
From("games").
LeftJoin("profile_games", builder.Expr("profile_games.game_id = games.id")),
hades.Search().OrderBy("profile_games.\"order\" ASC"),
c.IntoRowsScanner(&names),
))
assert.EqualValues(t, []struct {
Name string
}{
{"First offensive"},
{"Seconds until midnight"},
{"Three was company"},
}, names)
})
}
......@@ -237,7 +239,7 @@ func Test_ManyToManyThorough(t *testing.T) {
{
beforeSaveQueryCount := c.QueryCount
ordie(c.Save(conn, p))
ordie(c.Save(conn, p, hades.Assoc("Authors")))
pieceSelect := 1
pieceInsert := 1
......@@ -271,7 +273,7 @@ func Test_ManyToManyThorough(t *testing.T) {
{
beforeSaveQueryCount := c.QueryCount
ordie(c.Save(conn, p))
ordie(c.Save(conn, p, hades.AssocReplace("Authors")))
pieceSelect := 1
......@@ -297,7 +299,7 @@ func Test_ManyToManyThorough(t *testing.T) {
{
beforeSaveQueryCount := c.QueryCount
ordie(c.Save(conn, p))
ordie(c.Save(conn, p, hades.AssocReplace("Authors")))
pieceSelect := 1
......@@ -328,7 +330,7 @@ func Test_ManyToManyThorough(t *testing.T) {
{
beforeSaveQueryCount := c.QueryCount
ordie(c.Save(conn, p))
ordie(c.Save(conn, p, hades.AssocReplace("Authors")))
pieceSelect := 1
......@@ -365,7 +367,7 @@ func Test_ManyToManyThorough(t *testing.T) {
assertCount(&PieceAuthor{}, len(p.Authors))
p.Authors = nil
ordie(c.Save(conn, p))
ordie(c.Save(conn, p, hades.AssocReplace("Authors")))
assertCount(&Piece{}, 1)
assertCount(&Author{}, len(originalAuthors)+1+1200)
......
......@@ -31,11 +31,11 @@ func (c *Context) fetchPagedByPK(conn *sqlite.Conn, PKDBName string, keys []inte
}
pageAddr := reflect.New(sliceType)
cond := builder.In(PKDBName, remainingItems[:pageSize]...)
cond := builder.In(EscapeIdentifier(PKDBName), remainingItems[:pageSize]...)
err := c.Select(conn, pageAddr.Interface(), cond, search)
if err != nil {
return result, errors.Wrap(err, "performing page fetch")
return result, errors.WithMessage(err, "performing page fetch")
}
appended := reflect.AppendSlice(resultVal, pageAddr.Elem())
......
......@@ -14,6 +14,10 @@ func (c *Context) Preload(conn *sqlite.Conn, rec interface{}, opts ...PreloadPar
o.ApplyToPreloadParams(params)
}
if len(params.assocs) == 0 {
return errors.Errorf("Cannot preload 0 assocs")
}
val := reflect.ValueOf(rec)
valtyp := val.Type()
if valtyp.Kind() == reflect.Slice {
......@@ -23,7 +27,7 @@ func (c *Context) Preload(conn *sqlite.Conn, rec interface{}, opts ...PreloadPar
valtyp = valtyp.Elem()
}
if valtyp.Kind() != reflect.Ptr {
return fmt.Errorf("Preload expects a []*Model or *Model, but it was passed a %v instead", val.Type())
return errors.Errorf("Preload expects a []*Model or *Model, but it was passed a %v instead", val.Type())
}
riMap := make(RecordInfoMap)
......@@ -34,7 +38,7 @@ func (c *Context) Preload(conn *sqlite.Conn, rec interface{}, opts ...PreloadPar
}
rootInfo, err := c.WalkType(riMap, rootField, valtyp)
if err != nil {
return errors.Wrap(err, "waking type tree")
return errors.WithMessage(err, "waking type tree")
}
var walk func(p reflect.Value, pri *RecordInfo) error
......@@ -44,7 +48,7 @@ func (c *Context) Preload(conn *sqlite.Conn, rec interface{}, opts ...PreloadPar
ptyp = ptyp.Elem()
}
if ptyp.Kind() != reflect.Ptr {
return fmt.Errorf("walk expects a []*Model or *Model, but it was passed a %v instead", p.Type())
return errors.Errorf("walk expects a []*Model or *Model, but it was passed a %v instead", p.Type())
}
for _, cri := range pri.Children {
......@@ -68,7 +72,7 @@ func (c *Context) Preload(conn *sqlite.Conn, rec interface{}, opts ...PreloadPar
var err error
freshAddr, err = c.fetchPagedByPK(conn, cri.Relationship.ForeignDBNames[0], keys, reflect.SliceOf(cri.Type), cri.Field.Search())
if err != nil {
return errors.Wrap(err, "fetching has_many records (paginated)")
return errors.WithMessage(err, "fetching has_many records (paginated)")
}
pByFK := make(map[interface{}]reflect.Value)
......@@ -101,7 +105,7 @@ func (c *Context) Preload(conn *sqlite.Conn, rec interface{}, opts ...PreloadPar
var err error
freshAddr, err = c.fetchPagedByPK(conn, cri.Relationship.ForeignDBNames[0], keys, reflect.SliceOf(cri.Type), cri.Field.Search())
if err != nil {
return errors.Wrap(err, "fetching has_one records (paginated)")
return errors.WithMessage(err, "fetching has_one records (paginated)")
}
fresh := freshAddr.Elem()
......@@ -129,7 +133,7 @@ func (c *Context) Preload(conn *sqlite.Conn, rec interface{}, opts ...PreloadPar
var err error
freshAddr, err = c.fetchPagedByPK(conn, cri.Relationship.AssociationForeignDBNames[0], keys, reflect.SliceOf(cri.Type), cri.Field.Search())
if err != nil {
return errors.Wrap(err, "fetching belongs_to records (paginated)")
return errors.WithMessage(err, "fetching belongs_to records (paginated)")
}
fresh := freshAddr.Elem()
......@@ -148,7 +152,7 @@ func (c *Context) Preload(conn *sqlite.Conn, rec interface{}, opts ...PreloadPar
}
}
default:
return fmt.Errorf("Preload doesn't know how to handle %s relationships", cri.Relationship.Kind)
return errors.Errorf("Preload doesn't know how to handle %s relationships", cri.Relationship.Kind)
}
fresh := freshAddr.Elem()
......
......@@ -24,20 +24,10 @@ func Test_PreloadEdgeCases(t *testing.T) {
withContext(t, models, func(conn *sqlite.Conn, c *hades.Context) {
// non-existent Bar
f := &Foo{ID: 1, BarID: 999}
wtest.Must(t, c.Preload(conn, &hades.PreloadParams{
Record: f,
Fields: []hades.PreloadField{
{Name: "Bar"},
},
}))
wtest.Must(t, c.Preload(conn, f, hades.Assoc("Bar")))
// empty slice
var foos []*Foo
wtest.Must(t, c.Preload(conn, &hades.PreloadParams{
Record: foos,
Fields: []hades.PreloadField{
{Name: "Bar"},
},
}))
wtest.Must(t, c.Preload(conn, foos, hades.Assoc("Bar")))
})
}
package hades
import (
"fmt"
"log"
"reflect"
"strings"
......@@ -33,7 +31,7 @@ func (c *Context) SaveNoTransaction(conn *sqlite.Conn, rec interface{}, opts ...
valtyp = valtyp.Elem()
}
if valtyp.Kind() != reflect.Ptr {
return fmt.Errorf("Save expects a []*Model or a *Model, but it was passed a %v instead", val.Type())
return errors.Errorf("Save expects a []*Model or a *Model, but it was passed a %v instead", val.Type())
}
riMap := make(RecordInfoMap)
......@@ -44,7 +42,7 @@ func (c *Context) SaveNoTransaction(conn *sqlite.Conn, rec interface{}, opts ...
}
rootRecordInfo, err := c.WalkType(riMap, rootField, valtyp)
if err != nil {
return errors.Wrap(err, "walking records to be saved")
return errors.WithMessage(err, "walking records to be saved")
}
entities := make(AllEntities)
......@@ -63,7 +61,7 @@ func (c *Context) SaveNoTransaction(conn *sqlite.Conn, rec interface{}, opts ...
switch vri.Relationship.Kind {
case "has_many", "has_one":
if len(pri.ModelStruct.PrimaryFields) != 1 {
return fmt.Errorf("Since %v %s %v, we expected one primary key in %v, but found %d",
return errors.Errorf("Since %v %s %v, we expected one primary key in %v, but found %d",
p.Type(),
vri.Relationship.Kind,
v.Type(),
......@@ -73,7 +71,7 @@ func (c *Context) SaveNoTransaction(conn *sqlite.Conn, rec interface{}, opts ...
}
pkField := p.Elem().FieldByName(pri.ModelStruct.PrimaryFields[0].Name)
if len(vri.Relationship.ForeignFieldNames) != 1 {
return fmt.Errorf("Since %v %s %v, we expected one foreign field in %v, but found %d",
return errors.Errorf("Since %v %s %v, we expected one foreign field in %v, but found %d",
p.Type(),
vri.Relationship.Kind,
v.Type(),
......@@ -85,7 +83,7 @@ func (c *Context) SaveNoTransaction(conn *sqlite.Conn, rec interface{}, opts ...
fkField.Set(pkField)
case "belongs_to":
if len(vri.ModelStruct.PrimaryFields) != 1 {
return fmt.Errorf("Since %v %s %v, we expected one primary key in %v, but found %d",
return errors.Errorf("Since %v %s %v, we expected one primary key in %v, but found %d",
p.Type(),
vri.Relationship.Kind,
v.Type(),
......@@ -96,7 +94,7 @@ func (c *Context) SaveNoTransaction(conn *sqlite.Conn, rec interface{}, opts ...
pkField := v.Elem().FieldByName(vri.ModelStruct.PrimaryFields[0].Name)
if len(vri.Relationship.ForeignFieldNames) != 1 {
return fmt.Errorf("Since %v %s %v, we expected one foreign field in %v, but found %d",
return errors.Errorf("Since %v %s %v, we expected one foreign field in %v, but found %d",
p.Type(),
vri.Relationship.Kind,
v.Type(),
......@@ -114,17 +112,17 @@ func (c *Context) SaveNoTransaction(conn *sqlite.Conn, rec interface{}, opts ...
numVisited++
err := addEntity(v)
if err != nil {
return errors.Wrap(err, "adding entity")
return errors.WithMessage(err, "adding entity")
}
}
if v.Kind() != reflect.Ptr {
return fmt.Errorf("expected a pointer, but got with %v", v)
return errors.Errorf("expected a pointer, but got with %v", v)
}
vs := v.Elem()
if vs.Kind() != reflect.Struct {
return fmt.Errorf("expected a struct, but got with %v", v)
return errors.Errorf("expected a struct, but got with %v", v)
}
for _, childRi := range vri.Children {
......@@ -141,7 +139,7 @@ func (c *Context) SaveNoTransaction(conn *sqlite.Conn, rec interface{}, opts ...
persistChildren := true
err := walk(v, vri, child, childRi, persistChildren)
if err != nil {
return errors.Wrap(err, "walking child entities to be saved")
return errors.WithMessage(err, "walking child entities to be saved")
}
}
return nil
......@@ -152,11 +150,14 @@ func (c *Context) SaveNoTransaction(conn *sqlite.Conn, rec interface{}, opts ...
for i := 0; i < v.Len(); i++ {
err := visit(p, pri, v.Index(i), vri, persist)
if err != nil {
return errors.Wrap(err, "walking slice of children")
return errors.WithMessage(err, "walking slice of children")
}
}
if vri.Field.Mode() == AssocModeReplace {
if vri.Relationship != nil &&
vri.Relationship.Kind == "has_many" &&
vri.Field.Mode() == AssocModeReplace {
var oldValuePKs []string
rel := vri.Relationship
......@@ -166,10 +167,6 @@ func (c *Context) SaveNoTransaction(conn *sqlite.Conn, rec interface{}, opts ...
}
parentPK := parentPF.Field
log.Printf("%v has_many %v:", pri.Type, vri.Type)
log.Printf("AssociationForeignDBNames: %v", vri.Relationship.AssociationForeignDBNames)
log.Printf(" ForeignDBNames: %v", vri.Relationship.ForeignDBNames)
if len(vri.ModelStruct.PrimaryFields) != 1 {
var pfNames []string
for _, pf := range vri.ModelStruct.PrimaryFields {
......@@ -227,7 +224,7 @@ func (c *Context) SaveNoTransaction(conn *sqlite.Conn, rec interface{}, opts ...
} else {
err := visit(p, pri, v, vri, persist)
if err != nil {
return errors.Wrap(err, "walking single child")
return errors.WithMessage(err, "walking single child")
}
}
return nil
......@@ -235,14 +232,14 @@ func (c *Context) SaveNoTransaction(conn *sqlite.Conn, rec interface{}, opts ...
err = walk(reflect.Zero(reflect.TypeOf(0)), nil, val, rootRecordInfo, !params.omitRoot)
if err != nil {
return errors.Wrap(err, "walking all records to be persisted")
return errors.WithMessage(err, "walking all records to be persisted")
}
for typ, m := range entities {
ri := riMap[typ]
err := c.saveRows(conn, ri.Field.Mode(), m)
if err != nil {
return errors.Wrap(err, "saving rows")
return errors.WithMessage(err, "saving rows")
}
}
......@@ -250,7 +247,7 @@ func (c *Context) SaveNoTransaction(conn *sqlite.Conn, rec interface{}, opts ...
if ri.ManyToMany != nil {
err := c.saveJoins(conn, ri.Field.Mode(), ri.ManyToMany)
if err != nil {
return errors.Wrap(err, "saving joins")
return errors.WithMessage(err, "saving joins")
}
}
}
......
......@@ -20,7 +20,7 @@ func (c *Context) saveJoins(conn *sqlite.Conn, mode AssocMode, mtm *ManyToMany)
err := c.Select(conn, cacheAddr.Interface(), builder.Eq{mtm.SourceDBName: sourceKey}, nil)
if err != nil {
return errors.Wrap(err, "fetching cached records to compare later")
return errors.WithMessage(err, "fetching cached records to compare later")
}
cache := cacheAddr.Elem()
......@@ -52,7 +52,7 @@ func (c *Context) saveJoins(conn *sqlite.Conn, mode AssocMode, mtm *ManyToMany)
cf, err := DiffRecord(ifrec, icrec, mtm.Scope)
if err != nil {
return errors.Wrap(err, "diffing database records")
return errors.WithMessage(err, "diffing database records")
}
if cf != nil {
......@@ -73,7 +73,7 @@ func (c *Context) saveJoins(conn *sqlite.Conn, mode AssocMode, mtm *ManyToMany)
if mode == AssocModeReplace && len(deletes) > 0 {
err := c.deletePagedByPK(conn, mtm.JoinTable, mtm.DestinDBName, deletes, builder.Eq{mtm.SourceDBName: sourceKey})
if err != nil {
return errors.Wrap(err, "deleting extraneous relations")
return errors.WithMessage(err, "deleting extraneous relations")
}
}
......@@ -83,7 +83,7 @@ func (c *Context) saveJoins(conn *sqlite.Conn, mode AssocMode, mtm *ManyToMany)
if rec.IsValid() {
err := c.Insert(conn, mtm.Scope, rec)
if err != nil {
return errors.Wrap(err, "creating new relation records")
return errors.WithMessage(err, "creating new relation records")
}
} else {
// if not passed an explicit record, make it ourselves
......@@ -105,7 +105,7 @@ func (c *Context) saveJoins(conn *sqlite.Conn, mode AssocMode, mtm *ManyToMany)
query := builder.Update(cf.ToEq()).Into(mtm.Scope.TableName()).Where(builder.Eq{mtm.SourceDBName: sourceKey, mtm.DestinDBName: destinKey})
err := c.Exec(conn, query, nil)
if err != nil {
return errors.Wrap(err, "updating related records")
return errors.WithMessage(err, "updating related records")
}
}
}
......
package hades
import (
"fmt"
"math"
"reflect"
"strings"
......@@ -40,7 +39,7 @@ func (c *Context) saveRows(conn *sqlite.Conn, mode AssocMode, inputIface interfa
// this will happen for associations
if len(primaryFields) != 1 {
if len(primaryFields) != 2 {
return fmt.Errorf("Have %d primary keys for %s, don't know what to do", len(primaryFields), modelName)
return errors.Errorf("Have %d primary keys for %s, don't know what to do", len(primaryFields), modelName)
}
recordsGroupedByPrimaryField := make(map[*Field]map[interface{}][]reflect.Value)
......@@ -69,7 +68,7 @@ func (c *Context) saveRows(conn *sqlite.Conn, mode AssocMode, inputIface interfa
}
if bestSourcePrimaryField == nil {
return fmt.Errorf("Have %d primary keys for %s, don't know what to do", len(primaryFields), modelName)
return errors.Errorf("Have %d primary keys for %s, don't know what to do", len(primaryFields), modelName)
}
var bestDestinPrimaryField *Field
......@@ -85,28 +84,28 @@ func (c *Context) saveRows(conn *sqlite.Conn, mode AssocMode, inputIface interfa
sourceRelField, ok := scope.FieldByName(strings.TrimSuffix(bestSourcePrimaryField.Name, "ID"))
if !ok {
return fmt.Errorf("Could not find assoc for %s.%s", modelName, bestSourcePrimaryField.Name)
return errors.Errorf("Could not find assoc for %s.%s", modelName, bestSourcePrimaryField.Name)
}
destinRelField, ok := scope.FieldByName(strings.TrimSuffix(bestDestinPrimaryField.Name, "ID"))
if !ok {
return fmt.Errorf("Could not find assoc for %s.%s", modelName, bestDestinPrimaryField.Name)
return errors.Errorf("Could not find assoc for %s.%s", modelName, bestDestinPrimaryField.Name)
}
sourceScope := c.ScopeMap.ByType(sourceRelField.Struct.Type)
if sourceScope == nil {
return fmt.Errorf("Could not find scope for assoc for %s.%s", modelName, bestSourcePrimaryField.Name)
return errors.Errorf("Could not find scope for assoc for %s.%s", modelName, bestSourcePrimaryField.Name)
}
destinScope := c.ScopeMap.ByType(destinRelField.Struct.Type)
if destinScope == nil {
return fmt.Errorf("Could not find scope for assoc for %s.%s", modelName, bestSourcePrimaryField.Name)
return errors.Errorf("Could not find scope for assoc for %s.%s", modelName, bestSourcePrimaryField.Name)
}
if len(sourceScope.PrimaryFields()) != 1 {
return fmt.Errorf("Expected Source model %s to have 1 primary field, but it has %d",
return errors.Errorf("Expected Source model %s to have 1 primary field, but it has %d",
sourceScope.GetModelStruct().ModelType, len(sourceScope.PrimaryFields()))
}
if len(destinScope.PrimaryFields()) != 1 {
return fmt.Errorf("Expected Destin model %s to have 1 primary field, but it has %d",
return errors.Errorf("Expected Destin model %s to have 1 primary field, but it has %d",
destinScope.GetModelStruct().ModelType, len(destinScope.PrimaryFields()))
}