add tests for map

Signed-off-by: Andrew Thornton <art27@cantab.net>
This commit is contained in:
Andrew Thornton 2023-03-15 12:26:47 +00:00
parent 625167ded5
commit 2715e0de59
No known key found for this signature in database
GPG Key ID: 3CDE74631F13A748
3 changed files with 164 additions and 8 deletions

View File

@ -461,7 +461,7 @@ func TestUpsert(t *testing.T) {
assert.Equal(t, int64(1), n)
// Update default
n, err = testEngine.Upsert(&NoAutoIncrementPrimaryKey{NotUnique: "notunique"})
n, err = testEngine.Upsert([]*NoAutoIncrementPrimaryKey{{NotUnique: "notunique"}})
assert.NoError(t, err)
assert.Equal(t, int64(1), n)
@ -471,7 +471,7 @@ func TestUpsert(t *testing.T) {
assert.Equal(t, int64(1), n)
// Insert with 2
n, err = testEngine.Upsert(&NoAutoIncrementPrimaryKey{Name: "two", Number: 2})
n, err = testEngine.Upsert([]*NoAutoIncrementPrimaryKey{{Name: "two", Number: 2}})
assert.NoError(t, err)
assert.Equal(t, int64(1), n)
@ -479,5 +479,154 @@ func TestUpsert(t *testing.T) {
n, err = testEngine.Upsert(&NoAutoIncrementPrimaryKey{Name: "one", Number: 1, NotUnique: "updated"})
assert.NoError(t, err)
assert.Equal(t, int64(1), n)
// Upsert multiple with 2
n, err = testEngine.Upsert([]*NoAutoIncrementPrimaryKey{{Name: "one", Number: 1, NotUnique: "updatedagain"}, {Name: "three", Number: 3}})
assert.NoError(t, err)
assert.Equal(t, int64(2), n)
})
}
func TestInsertOnConflictDoNothingMap(t *testing.T) {
type MultiUniqueMap struct {
ID int64 `xorm:"pk autoincr"`
NotUnique string
Data1 string `xorm:"UNIQUE(s) NOT NULL"`
Data2 string `xorm:"UNIQUE(s) NOT NULL"`
}
assert.NoError(t, testEngine.Sync2(&MultiUniqueMap{}))
_, _ = testEngine.Exec("DELETE FROM multi_unique_map")
n, err := testEngine.Table(&MultiUniqueMap{}).InsertOnConflictDoNothing(map[string]interface{}{
"not_unique": "",
"data1": "",
"data2": "",
})
assert.NoError(t, err)
assert.Equal(t, int64(1), n)
n, err = testEngine.Table(&MultiUniqueMap{}).InsertOnConflictDoNothing(map[string]interface{}{
"not_unique": "",
"data1": "second",
"data2": "",
})
assert.NoError(t, err)
assert.Equal(t, int64(1), n)
n, err = testEngine.Table(&MultiUniqueMap{}).InsertOnConflictDoNothing(map[string]interface{}{
"not_unique": "",
"data1": "",
"data2": "",
})
assert.NoError(t, err)
assert.Equal(t, int64(0), n)
n, err = testEngine.Table(&MultiUniqueMap{}).InsertOnConflictDoNothing(map[string]interface{}{
"not_unique": "",
"data1": "",
"data2": "third",
})
assert.NoError(t, err)
assert.Equal(t, int64(1), n)
n, err = testEngine.Table(&MultiUniqueMap{}).InsertOnConflictDoNothing(map[string]interface{}{
"not_unique": "",
"data1": "",
"data2": "third",
})
assert.NoError(t, err)
assert.Equal(t, int64(0), n)
}
func TestUpsertMap(t *testing.T) {
type MultiUniqueMap struct {
ID int64 `xorm:"pk autoincr"`
NotUnique string
Data1 string `xorm:"UNIQUE(s) NOT NULL"`
Data2 string `xorm:"UNIQUE(s) NOT NULL"`
}
assert.NoError(t, testEngine.Sync2(&MultiUniqueMap{}))
_, _ = testEngine.Exec("DELETE FROM multi_unique_map")
n, err := testEngine.Table(&MultiUniqueMap{}).Upsert(map[string]interface{}{
"not_unique": "",
"data1": "",
"data2": "",
})
assert.NoError(t, err)
assert.Equal(t, int64(1), n)
testCase := &MultiUniqueMap{}
has, err := testEngine.Get(testCase)
assert.NoError(t, err)
assert.True(t, has)
n, err = testEngine.Table(&MultiUniqueMap{}).Upsert(map[string]interface{}{
"not_unique": "",
"data1": "second",
"data2": "",
})
assert.NoError(t, err)
assert.Equal(t, int64(1), n)
testCase = &MultiUniqueMap{
Data1: "second",
}
has, err = testEngine.Get(testCase)
assert.NoError(t, err)
assert.True(t, has)
n, err = testEngine.Table(&MultiUniqueMap{}).Upsert(map[string]interface{}{
"not_unique": "updated",
"data1": "",
"data2": "",
})
assert.NoError(t, err)
assert.Equal(t, int64(1), n)
testCase = &MultiUniqueMap{
Data1: "",
}
has, err = testEngine.Get(testCase)
assert.NoError(t, err)
assert.True(t, has)
assert.Equal(t, "updated", testCase.NotUnique)
n, err = testEngine.Table(&MultiUniqueMap{}).Upsert(map[string]interface{}{
"not_unique": "",
"data1": "",
"data2": "third",
})
assert.NoError(t, err)
assert.Equal(t, int64(1), n)
testCase = &MultiUniqueMap{
Data2: "third",
}
has, err = testEngine.Get(testCase)
assert.NoError(t, err)
assert.True(t, has)
assert.Equal(t, "", testCase.NotUnique)
n, err = testEngine.Table(&MultiUniqueMap{}).Upsert(map[string]interface{}{
"not_unique": "updated",
"data1": "",
"data2": "third",
})
assert.NoError(t, err)
assert.Equal(t, int64(1), n)
testCase = &MultiUniqueMap{
Data2: "third",
}
has, err = testEngine.Get(testCase)
assert.NoError(t, err)
assert.True(t, has)
assert.Equal(t, "updated", testCase.NotUnique)
testCase = &MultiUniqueMap{
Data1: "second",
}
has, err = testEngine.Get(testCase)
assert.NoError(t, err)
assert.True(t, has)
assert.Equal(t, "", testCase.NotUnique)
}

View File

@ -98,12 +98,14 @@ func (statement *Statement) GenUpsertSQL(doUpdate bool, addOuput bool, columns [
return "", nil, fmt.Errorf("unimplemented") // FIXME: UPSERT
}
if len(table.AutoIncrement) > 0 &&
(statement.dialect.URI().DBType == schemas.POSTGRES ||
statement.dialect.URI().DBType == schemas.SQLITE) {
write(" RETURNING ")
if err := statement.dialect.Quoter().QuoteTo(buf.Builder, table.AutoIncrement); err != nil {
return "", nil, err
if addOuput {
if len(table.AutoIncrement) > 0 &&
(statement.dialect.URI().DBType == schemas.POSTGRES ||
statement.dialect.URI().DBType == schemas.SQLITE) {
write(" RETURNING ")
if err := statement.dialect.Quoter().QuoteTo(buf.Builder, table.AutoIncrement); err != nil {
return "", nil, err
}
}
}

View File

@ -31,6 +31,8 @@ func (session *Session) upsert(doUpdate bool, beans ...interface{}) (int64, erro
session.autoResetStatement = true
session.resetStatement()
}()
fmt.Println(session.statement.TableName())
for _, bean := range beans {
var cnt int64
var err error
@ -116,6 +118,9 @@ func (session *Session) upsertMap(doUpdate bool, columns []string, args []interf
if len(tableName) == 0 {
return 0, ErrTableNotFound
}
if session.statement.RefTable == nil {
return 0, ErrTableNotFound
}
uniqueColValMap, uniqueConstraints, err := session.getUniqueColumns(doUpdate, columns, args)
if err != nil {