fork github.com/doug-martin

This commit is contained in:
2025-03-22 23:02:05 +08:00
commit f14642a736
131 changed files with 34555 additions and 0 deletions
+233
View File
@@ -0,0 +1,233 @@
package sqlgen_test
import (
"testing"
"git.fsdpf.net/go/db/v2/exp"
"git.fsdpf.net/go/db/v2/internal/errors"
"git.fsdpf.net/go/db/v2/internal/sb"
"git.fsdpf.net/go/db/v2/sqlgen"
"github.com/stretchr/testify/suite"
)
type (
deleteTestCase struct {
clause exp.DeleteClauses
sql string
isPrepared bool
args []interface{}
err string
}
deleteSQLGeneratorSuite struct {
baseSQLGeneratorSuite
}
)
func (dsgs *deleteSQLGeneratorSuite) assertCases(dsg sqlgen.DeleteSQLGenerator, testCases ...deleteTestCase) {
for _, tc := range testCases {
b := sb.NewSQLBuilder(tc.isPrepared)
dsg.Generate(b, tc.clause)
switch {
case len(tc.err) > 0:
dsgs.assertErrorSQL(b, tc.err)
case tc.isPrepared:
dsgs.assertPreparedSQL(b, tc.sql, tc.args)
default:
dsgs.assertNotPreparedSQL(b, tc.sql)
}
}
}
func (dsgs *deleteSQLGeneratorSuite) TestDialect() {
opts := sqlgen.DefaultDialectOptions()
d := sqlgen.NewDeleteSQLGenerator("test", opts)
dsgs.Equal("test", d.Dialect())
opts2 := sqlgen.DefaultDialectOptions()
d2 := sqlgen.NewDeleteSQLGenerator("test2", opts2)
dsgs.Equal("test2", d2.Dialect())
}
func (dsgs *deleteSQLGeneratorSuite) TestGenerate() {
dc := exp.NewDeleteClauses().
SetFrom(exp.NewIdentifierExpression("", "test", ""))
dsgs.assertCases(
sqlgen.NewDeleteSQLGenerator("test", sqlgen.DefaultDialectOptions()),
deleteTestCase{clause: dc, sql: `DELETE FROM "test"`},
deleteTestCase{clause: dc, sql: `DELETE FROM "test"`, isPrepared: true},
)
opts2 := sqlgen.DefaultDialectOptions()
opts2.DeleteClause = []byte("delete")
dsgs.assertCases(
sqlgen.NewDeleteSQLGenerator("test", opts2),
deleteTestCase{clause: dc, sql: `delete FROM "test"`},
deleteTestCase{clause: dc, sql: `delete FROM "test"`, isPrepared: true},
)
}
func (dsgs *deleteSQLGeneratorSuite) TestGenerate_withUnsupportedFragment() {
opts := sqlgen.DefaultDialectOptions()
opts.DeleteSQLOrder = []sqlgen.SQLFragmentType{sqlgen.InsertBeingSQLFragment}
dc := exp.NewDeleteClauses().
SetFrom(exp.NewIdentifierExpression("", "test", ""))
dsgs.assertCases(
sqlgen.NewDeleteSQLGenerator("test", opts),
deleteTestCase{clause: dc, err: `db: unsupported DELETE SQL fragment InsertBeingSQLFragment`},
deleteTestCase{clause: dc, err: `db: unsupported DELETE SQL fragment InsertBeingSQLFragment`, isPrepared: true},
)
}
func (dsgs *deleteSQLGeneratorSuite) TestGenerate_noFrom() {
dc := exp.NewDeleteClauses()
dsgs.assertCases(
sqlgen.NewDeleteSQLGenerator("test", sqlgen.DefaultDialectOptions()),
deleteTestCase{clause: dc, err: sqlgen.ErrNoSourceForDelete.Error()},
deleteTestCase{clause: dc, err: sqlgen.ErrNoSourceForDelete.Error(), isPrepared: true},
)
}
func (dsgs *deleteSQLGeneratorSuite) TestGenerate_withErroredBuilder() {
opts := sqlgen.DefaultDialectOptions()
d := sqlgen.NewDeleteSQLGenerator("test", opts)
dc := exp.NewDeleteClauses().SetFrom(exp.NewIdentifierExpression("", "test", ""))
b := sb.NewSQLBuilder(false).SetError(errors.New("expected error"))
d.Generate(b, dc)
dsgs.assertErrorSQL(b, "db: expected error")
b = sb.NewSQLBuilder(true).SetError(errors.New("expected error"))
d.Generate(b, dc)
dsgs.assertErrorSQL(b, "db: expected error")
}
func (dsgs *deleteSQLGeneratorSuite) TestGenerate_withCommonTables() {
opts := sqlgen.DefaultDialectOptions()
opts.WithFragment = []byte("with ")
opts.RecursiveFragment = []byte("recursive ")
tse := newTestAppendableExpression("select * from foo", emptyArgs, nil, nil)
dc := exp.NewDeleteClauses().SetFrom(exp.NewIdentifierExpression("", "test_cte", ""))
dcCte1 := dc.CommonTablesAppend(exp.NewCommonTableExpression(false, "test_cte", tse))
dcCte2 := dc.CommonTablesAppend(exp.NewCommonTableExpression(true, "test_cte", tse))
dsgs.assertCases(
sqlgen.NewDeleteSQLGenerator("test", opts),
deleteTestCase{clause: dcCte1, sql: `with test_cte AS (select * from foo) DELETE FROM "test_cte"`},
deleteTestCase{clause: dcCte1, sql: `with test_cte AS (select * from foo) DELETE FROM "test_cte"`, isPrepared: true},
deleteTestCase{clause: dcCte2, sql: `with recursive test_cte AS (select * from foo) DELETE FROM "test_cte"`},
deleteTestCase{clause: dcCte2, sql: `with recursive test_cte AS (select * from foo) DELETE FROM "test_cte"`, isPrepared: true},
)
opts.SupportsWithCTE = false
expectedErr := sqlgen.ErrCTENotSupported("test")
dsgs.assertCases(
sqlgen.NewDeleteSQLGenerator("test", opts),
deleteTestCase{clause: dcCte1, err: expectedErr.Error()},
deleteTestCase{clause: dcCte1, err: expectedErr.Error(), isPrepared: true},
deleteTestCase{clause: dcCte2, err: expectedErr.Error()},
deleteTestCase{clause: dcCte2, err: expectedErr.Error(), isPrepared: true},
)
opts.SupportsWithCTE = true
opts.SupportsWithCTERecursive = false
expectedErr = sqlgen.ErrRecursiveCTENotSupported("test")
dsgs.assertCases(
sqlgen.NewDeleteSQLGenerator("test", opts),
deleteTestCase{clause: dcCte1, sql: `with test_cte AS (select * from foo) DELETE FROM "test_cte"`},
deleteTestCase{clause: dcCte1, sql: `with test_cte AS (select * from foo) DELETE FROM "test_cte"`, isPrepared: true},
deleteTestCase{clause: dcCte2, err: expectedErr.Error()},
deleteTestCase{clause: dcCte2, err: expectedErr.Error(), isPrepared: true},
)
}
func (dsgs *deleteSQLGeneratorSuite) TestGenerate_withWhere() {
dc := exp.NewDeleteClauses().
SetFrom(exp.NewIdentifierExpression("", "test", "")).
WhereAppend(exp.NewLiteralExpression(`"a"=?`, 1))
dsgs.assertCases(
sqlgen.NewDeleteSQLGenerator("test", sqlgen.DefaultDialectOptions()),
deleteTestCase{clause: dc, sql: `DELETE FROM "test" WHERE "a"=1`},
deleteTestCase{clause: dc, sql: `DELETE FROM "test" WHERE "a"=?`, isPrepared: true, args: []interface{}{
int64(1),
}},
)
}
func (dsgs *deleteSQLGeneratorSuite) TestGenerate_withOrder() {
opts := sqlgen.DefaultDialectOptions()
opts.SupportsOrderByOnDelete = true
dc := exp.NewDeleteClauses().
SetFrom(exp.NewIdentifierExpression("", "test", "")).
SetOrder(exp.NewIdentifierExpression("", "", "c").Desc())
dsgs.assertCases(
sqlgen.NewDeleteSQLGenerator("test", opts),
deleteTestCase{clause: dc, sql: `DELETE FROM "test" ORDER BY "c" DESC`},
deleteTestCase{clause: dc, sql: `DELETE FROM "test" ORDER BY "c" DESC`, isPrepared: true},
)
opts.SupportsOrderByOnDelete = false
dsgs.assertCases(
sqlgen.NewDeleteSQLGenerator("test", opts),
deleteTestCase{clause: dc, sql: `DELETE FROM "test"`},
deleteTestCase{clause: dc, sql: `DELETE FROM "test"`, isPrepared: true},
)
}
func (dsgs *deleteSQLGeneratorSuite) TestGenerate_withLimit() {
opts := sqlgen.DefaultDialectOptions()
opts.SupportsLimitOnDelete = true
dc := exp.NewDeleteClauses().
SetFrom(exp.NewIdentifierExpression("", "test", "")).
SetLimit(1)
dsgs.assertCases(
sqlgen.NewDeleteSQLGenerator("test", opts),
deleteTestCase{clause: dc, sql: `DELETE FROM "test" LIMIT 1`},
deleteTestCase{clause: dc, sql: `DELETE FROM "test" LIMIT ?`, isPrepared: true, args: []interface{}{int64(1)}},
)
opts.SupportsLimitOnDelete = false
dsgs.assertCases(
sqlgen.NewDeleteSQLGenerator("test", opts),
deleteTestCase{clause: dc, sql: `DELETE FROM "test"`},
deleteTestCase{clause: dc, sql: `DELETE FROM "test"`, isPrepared: true},
)
}
func (dsgs *deleteSQLGeneratorSuite) TestGenerate_withReturning() {
opts := sqlgen.DefaultDialectOptions()
opts.SupportsReturn = true
dc := exp.NewDeleteClauses().
SetFrom(exp.NewIdentifierExpression("", "test", "")).
SetReturning(exp.NewColumnListExpression("a", "b"))
dsgs.assertCases(
sqlgen.NewDeleteSQLGenerator("test", opts),
deleteTestCase{clause: dc, sql: `DELETE FROM "test" RETURNING "a", "b"`},
deleteTestCase{clause: dc, sql: `DELETE FROM "test" RETURNING "a", "b"`, isPrepared: true},
)
opts.SupportsReturn = false
expectedErr := `db: dialect does not support RETURNING clause [dialect=test]`
dsgs.assertCases(
sqlgen.NewDeleteSQLGenerator("test", opts),
deleteTestCase{clause: dc, err: expectedErr},
deleteTestCase{clause: dc, err: expectedErr, isPrepared: true},
)
}
func TestDeleteSQLGenerator(t *testing.T) {
suite.Run(t, new(deleteSQLGeneratorSuite))
}