no returning on sqlite

Signed-off-by: Andrew Thornton <art27@cantab.net>
This commit is contained in:
Andrew Thornton 2023-03-13 06:44:23 +00:00
parent c55adf1c26
commit 9dafb36a44
No known key found for this signature in database
GPG Key ID: 3CDE74631F13A748
2 changed files with 2 additions and 227 deletions

View File

@ -16,231 +16,6 @@ import (
"github.com/stretchr/testify/assert"
)
func TestInsertOnConflictDoNothing(t *testing.T) {
assert.NoError(t, PrepareEngine())
t.Run("NoUnique", func(t *testing.T) {
// InsertOnConflictDoNothing does not work if there is no unique constraint
type NoUniques struct {
ID int64 `xorm:"pk autoincr"`
Data string
}
assert.NoError(t, testEngine.Sync(new(NoUniques)))
toInsert := &NoUniques{Data: "shouldErr"}
n, err := testEngine.InsertOnConflictDoNothing(toInsert)
assert.Error(t, err)
assert.Equal(t, int64(0), n)
assert.Equal(t, int64(0), toInsert.ID)
toInsert = &NoUniques{Data: ""}
n, err = testEngine.InsertOnConflictDoNothing(toInsert)
assert.Error(t, err)
assert.Equal(t, int64(0), n)
assert.Equal(t, int64(0), toInsert.ID)
})
t.Run("OneUnique", func(t *testing.T) {
type OneUnique struct {
ID int64 `xorm:"pk autoincr"`
Data string `xorm:"UNIQUE NOT NULL"`
}
assert.NoError(t, testEngine.Sync2(&OneUnique{}))
_, _ = testEngine.Exec("DELETE FROM one_unique")
// Insert with the default value for the unique field
toInsert := &OneUnique{}
n, err := testEngine.InsertOnConflictDoNothing(toInsert)
assert.NoError(t, err)
assert.Equal(t, int64(1), n)
assert.NotEqual(t, int64(0), toInsert.ID)
// but not twice
toInsert = &OneUnique{}
n, err = testEngine.InsertOnConflictDoNothing(toInsert)
assert.NoError(t, err)
assert.Equal(t, int64(0), n)
assert.Equal(t, int64(0), toInsert.ID)
// Successfully insert test
toInsert = &OneUnique{Data: "test"}
n, err = testEngine.InsertOnConflictDoNothing(toInsert)
assert.NoError(t, err)
assert.Equal(t, int64(1), n)
assert.NotEqual(t, int64(0), toInsert.ID)
// Successfully insert test2
toInsert = &OneUnique{Data: "test2"}
n, err = testEngine.InsertOnConflictDoNothing(toInsert)
assert.NoError(t, err)
assert.Equal(t, int64(1), n)
assert.NotEqual(t, int64(0), toInsert.ID)
// Successfully don't reinsert test
toInsert = &OneUnique{Data: "test"}
n, err = testEngine.InsertOnConflictDoNothing(toInsert)
assert.NoError(t, err)
assert.Equal(t, int64(0), n)
assert.Equal(t, int64(0), toInsert.ID)
})
t.Run("MultiUnique", func(t *testing.T) {
type MultiUnique 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(&MultiUnique{}))
_, _ = testEngine.Exec("DELETE FROM multi_unique")
// Insert with default values
toInsert := &MultiUnique{}
n, err := testEngine.InsertOnConflictDoNothing(toInsert)
assert.NoError(t, err)
assert.Equal(t, int64(1), n)
assert.NotEqual(t, int64(0), toInsert.ID)
// successfully insert test, t1
toInsert = &MultiUnique{Data1: "test", NotUnique: "t1"}
n, err = testEngine.InsertOnConflictDoNothing(toInsert)
assert.NoError(t, err)
assert.Equal(t, int64(1), n)
assert.NotEqual(t, int64(0), toInsert.ID)
// successfully insert test2, t1
toInsert = &MultiUnique{Data1: "test2", NotUnique: "t1"}
n, err = testEngine.InsertOnConflictDoNothing(toInsert)
assert.NoError(t, err)
assert.Equal(t, int64(1), n)
assert.NotEqual(t, int64(0), toInsert.ID)
// successfully don't insert test2, t2
toInsert = &MultiUnique{Data1: "test2", NotUnique: "t2"}
n, err = testEngine.InsertOnConflictDoNothing(toInsert)
assert.NoError(t, err)
assert.Equal(t, int64(0), n)
assert.Equal(t, int64(0), toInsert.ID)
// successfully don't insert test, t2
toInsert = &MultiUnique{Data1: "test", NotUnique: "t2"}
n, err = testEngine.InsertOnConflictDoNothing(toInsert)
assert.NoError(t, err)
assert.Equal(t, int64(0), n)
assert.Equal(t, int64(0), toInsert.ID)
// successfully insert test/test2, t2
toInsert = &MultiUnique{Data1: "test", Data2: "test2", NotUnique: "t1"}
n, err = testEngine.InsertOnConflictDoNothing(toInsert)
assert.NoError(t, err)
assert.Equal(t, int64(1), n)
assert.NotEqual(t, int64(0), toInsert.ID)
// successfully don't insert test/test2, t2
toInsert = &MultiUnique{Data1: "test", Data2: "test2", NotUnique: "t2"}
n, err = testEngine.InsertOnConflictDoNothing(toInsert)
assert.NoError(t, err)
assert.Equal(t, int64(0), n)
assert.Equal(t, int64(0), toInsert.ID)
})
t.Run("MultiMultiUnique", func(t *testing.T) {
type MultiMultiUnique struct {
ID int64 `xorm:"pk autoincr"`
Data0 string `xorm:"UNIQUE NOT NULL"`
Data1 string `xorm:"UNIQUE(s) NOT NULL"`
Data2 string `xorm:"UNIQUE(s) NOT NULL"`
}
assert.NoError(t, testEngine.Sync2(&MultiMultiUnique{}))
_, _ = testEngine.Exec("DELETE FROM multi_multi_unique")
// Insert with default values
n, err := testEngine.InsertOnConflictDoNothing(&MultiMultiUnique{})
assert.NoError(t, err)
assert.Equal(t, int64(1), n)
// Insert with value for t1, <test, "">
n, err = testEngine.InsertOnConflictDoNothing(&MultiMultiUnique{Data1: "test", Data0: "t1"})
assert.NoError(t, err)
assert.Equal(t, int64(1), n)
// Fail insert with value for t1, <test2, "">
n, err = testEngine.InsertOnConflictDoNothing(&MultiMultiUnique{Data2: "test2", Data0: "t1"})
assert.NoError(t, err)
assert.Equal(t, int64(0), n)
// Insert with value for t2, <test2, "">
n, err = testEngine.InsertOnConflictDoNothing(&MultiMultiUnique{Data2: "test2", Data0: "t2"})
assert.NoError(t, err)
assert.Equal(t, int64(1), n)
// Fail insert with value for t2, <test2, "">
n, err = testEngine.InsertOnConflictDoNothing(&MultiMultiUnique{Data2: "test2", Data0: "t2"})
assert.NoError(t, err)
assert.Equal(t, int64(0), n)
// Fail insert with value for t2, <test, "">
n, err = testEngine.InsertOnConflictDoNothing(&MultiMultiUnique{Data1: "test", Data0: "t2"})
assert.NoError(t, err)
assert.Equal(t, int64(0), n)
// Insert with value for t3, <test, test2>
n, err = testEngine.InsertOnConflictDoNothing(&MultiMultiUnique{Data1: "test", Data2: "test2", Data0: "t3"})
assert.NoError(t, err)
assert.Equal(t, int64(1), n)
// fail insert with value for t2, <test, test2>
n, err = testEngine.InsertOnConflictDoNothing(&MultiMultiUnique{Data1: "test", Data2: "test2", Data0: "t2"})
assert.NoError(t, err)
assert.Equal(t, int64(0), n)
})
t.Run("NoPK", func(t *testing.T) {
type NoPrimaryKey struct {
NotID int64
Uniqued string `xorm:"UNIQUE"`
}
assert.NoError(t, testEngine.Sync2(&NoPrimaryKey{}))
_, _ = testEngine.Exec("DELETE FROM no_primary_unique")
empty := &NoPrimaryKey{}
// Insert default
n, err := testEngine.InsertOnConflictDoNothing(empty)
assert.NoError(t, err)
assert.Equal(t, int64(1), n)
// Insert with 1
n, err = testEngine.InsertOnConflictDoNothing(&NoPrimaryKey{Uniqued: "1"})
assert.NoError(t, err)
assert.Equal(t, int64(1), n)
// Fail reinsert default
n, err = testEngine.InsertOnConflictDoNothing(&NoPrimaryKey{NotID: 1})
assert.NoError(t, err)
assert.Equal(t, int64(0), n)
// Fail reinsert default
n, err = testEngine.InsertOnConflictDoNothing(&NoPrimaryKey{NotID: 2})
assert.NoError(t, err)
assert.Equal(t, int64(0), n)
// Insert with 2
n, err = testEngine.InsertOnConflictDoNothing(&NoPrimaryKey{NotID: 2, Uniqued: "2"})
assert.NoError(t, err)
assert.Equal(t, int64(1), n)
// Fail reinsert with 2
n, err = testEngine.InsertOnConflictDoNothing(&NoPrimaryKey{NotID: 1, Uniqued: "2"})
assert.NoError(t, err)
assert.Equal(t, int64(0), n)
})
}
func TestInsertOne(t *testing.T) {
assert.NoError(t, PrepareEngine())

View File

@ -82,7 +82,7 @@ func (statement *Statement) GenUpsertSQL(doUpdate bool, columns []string, args [
return "", nil, fmt.Errorf("unimplemented") // FIXME: UPSERT
}
if len(table.AutoIncrement) > 0 && (statement.dialect.URI().DBType == schemas.POSTGRES || statement.dialect.URI().DBType == schemas.SQLITE) {
if len(table.AutoIncrement) > 0 && statement.dialect.URI().DBType == schemas.POSTGRES {
write(" RETURNING ")
if err := statement.dialect.Quoter().QuoteTo(buf.Builder, table.AutoIncrement); err != nil {
return "", nil, err
@ -240,7 +240,7 @@ func (statement *Statement) GenUpsertMapSQL(doUpdate bool, columns []string, arg
return "", nil, fmt.Errorf("unimplemented") // FIXME: UPSERT
}
if len(table.AutoIncrement) > 0 && (statement.dialect.URI().DBType == schemas.POSTGRES || statement.dialect.URI().DBType == schemas.SQLITE) {
if len(table.AutoIncrement) > 0 && statement.dialect.URI().DBType == schemas.POSTGRES {
if _, err := buf.WriteString(" RETURNING "); err != nil {
return "", nil, err
}