From 9dafb36a4455445589e915441625764473717450 Mon Sep 17 00:00:00 2001 From: Andrew Thornton Date: Mon, 13 Mar 2023 06:44:23 +0000 Subject: [PATCH] no returning on sqlite Signed-off-by: Andrew Thornton --- integrations/session_insert_test.go | 225 ---------------------------- internal/statements/upsert.go | 4 +- 2 files changed, 2 insertions(+), 227 deletions(-) diff --git a/integrations/session_insert_test.go b/integrations/session_insert_test.go index 40b52806..4759b4aa 100644 --- a/integrations/session_insert_test.go +++ b/integrations/session_insert_test.go @@ -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, - 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, - n, err = testEngine.InsertOnConflictDoNothing(&MultiMultiUnique{Data2: "test2", Data0: "t1"}) - assert.NoError(t, err) - assert.Equal(t, int64(0), n) - - // Insert with value for t2, - 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, - 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, - n, err = testEngine.InsertOnConflictDoNothing(&MultiMultiUnique{Data1: "test", Data0: "t2"}) - assert.NoError(t, err) - assert.Equal(t, int64(0), n) - - // Insert with value for t3, - 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, - 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()) diff --git a/internal/statements/upsert.go b/internal/statements/upsert.go index 01d7fe52..dd2d77b9 100644 --- a/internal/statements/upsert.go +++ b/internal/statements/upsert.go @@ -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 }