Commit 055d01da authored by Amos Wenger's avatar Amos Wenger

Take care of last few TODOs/FIXMEs

parent e8488ebd
Pipeline #10424 failed with stage
in 17 seconds
......@@ -176,4 +176,24 @@ func Test_ManyToManyThorough(t *testing.T) {
assertCount(&Piece{}, 1)
assertCount(&Author{}, len(originalAuthors)+1)
assertCount(&PieceAuthor{}, len(p.Authors))
// now let's try to break SQLite's max variables limit
for i := 0; i < 1200; i++ {
p.Authors = append(p.Authors, &Author{
ID: int64(i + 4000),
})
}
ordie(c.SaveOne(conn, p))
assertCount(&Piece{}, 1)
assertCount(&Author{}, len(originalAuthors)+1+1200)
assertCount(&PieceAuthor{}, len(p.Authors))
p.Authors = nil
ordie(c.SaveOne(conn, p))
assertCount(&Piece{}, 1)
assertCount(&Author{}, len(originalAuthors)+1+1200)
assertCount(&PieceAuthor{}, 0)
}
......@@ -46,7 +46,7 @@ func (c *Context) fetchPagedByPK(conn *sqlite.Conn, PKDBName string, keys []inte
return result, nil
}
func (c *Context) deletePagedByPK(conn *sqlite.Conn, TableName string, PKDBName string, keys []interface{}) error {
func (c *Context) deletePagedByPK(conn *sqlite.Conn, TableName string, PKDBName string, keys []interface{}, userCond builder.Cond) error {
remainingItems := keys
for len(remainingItems) > 0 {
......@@ -57,7 +57,7 @@ func (c *Context) deletePagedByPK(conn *sqlite.Conn, TableName string, PKDBName
pageSize = len(remainingItems)
}
cond := builder.In(PKDBName, remainingItems[:pageSize]...)
cond := builder.And(userCond, builder.In(PKDBName, remainingItems[:pageSize]...))
query := builder.Delete(cond).From(TableName)
err := c.Exec(conn, query, nil)
......
......@@ -163,12 +163,18 @@ func (c *Context) SaveNoTransaction(conn *sqlite.Conn, params *SaveParams) error
if v.Kind() == reflect.Slice {
cull := false
if vri.Relationship != nil && vri.Relationship.Kind == "has_many" {
cull = true
for _, dc := range params.DontCull {
if reflect.TypeOf(dc).Elem() == vri.ModelStruct.ModelType {
cull = false
if vri.Relationship != nil {
switch vri.Relationship.Kind {
case "has_many":
cull = true
for _, dc := range params.DontCull {
if reflect.TypeOf(dc).Elem() == vri.ModelStruct.ModelType {
cull = false
}
}
case "many_to_many":
// culling is done later, but let's record the ManyToMany now
vri.ManyToMany.Mark(p)
}
}
......@@ -231,7 +237,7 @@ func (c *Context) SaveNoTransaction(conn *sqlite.Conn, params *SaveParams) error
}
if len(vpksToDelete) > 0 {
err := c.deletePagedByPK(conn, vri.ModelStruct.TableName, valuePF.DBName, vpksToDelete)
err := c.deletePagedByPK(conn, vri.ModelStruct.TableName, valuePF.DBName, vpksToDelete, builder.NewCond())
if err != nil {
return err
}
......
......@@ -82,11 +82,7 @@ func (c *Context) saveJoins(params *SaveParams, conn *sqlite.Conn, mtm *ManyToMa
// Not deleting extra join records, as requested
} else {
if len(deletes) > 0 {
// FIXME: this needs to be paginated to avoid hitting SQLite max variables
err := c.Exec(conn, builder.Delete(
builder.Eq{mtm.SourceDBName: sourceKey},
builder.In(mtm.DestinDBName, deletes...),
).From(mtm.Scope.TableName()), nil)
err := c.deletePagedByPK(conn, mtm.JoinTable, mtm.DestinDBName, deletes, builder.Eq{mtm.SourceDBName: sourceKey})
if err != nil {
return errors.Wrap(err, "deleting extraneous relations")
}
......
......@@ -69,6 +69,11 @@ func (c *Context) NewManyToMany(JoinTable string, SourceForeignKeys, Destination
return mtm, nil
}
func (mtm *ManyToMany) Mark(Source reflect.Value) {
sourceKey := Source.Elem().FieldByName(mtm.SourceAssocName).Interface()
mtm.Values[sourceKey] = make([]JoinRec, 0)
}
func (mtm *ManyToMany) Add(Source reflect.Value, Destin reflect.Value) {
sourceKey := Source.Elem().FieldByName(mtm.SourceAssocName).Interface()
destinKey := Destin.Elem().FieldByName(mtm.DestinAssocName).Interface()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment