From 0f2ce0a685df03114e84e23b15955c883c9295ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Garcia?= Date: Tue, 20 Dec 2022 23:07:39 -0300 Subject: [PATCH 1/4] Minor refactor: remove the DB.driver field --- ksql.go | 4 +--- ksql_test.go | 1 - test_adapters.go | 1 - 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/ksql.go b/ksql.go index 3249759..6e2196b 100644 --- a/ksql.go +++ b/ksql.go @@ -30,7 +30,6 @@ func initializeQueryCache() map[string]*sync.Map { // interfacing with the "database/sql" package implementing // the KSQL interface `ksql.Provider`. type DB struct { - driver string dialect Dialect db DBAdapter } @@ -133,7 +132,6 @@ func NewWithAdapter( return DB{ dialect: dialect, - driver: dialectName, db: db, }, nil } @@ -463,7 +461,7 @@ func (c DB) Insert( default: // Unsupported drivers should be detected on the New() function, // So we don't expect the code to ever get into this default case. - err = fmt.Errorf("code error: unsupported driver `%s`", c.driver) + err = fmt.Errorf("code error: unsupported driver `%s`", c.dialect.DriverName()) } return err diff --git a/ksql_test.go b/ksql_test.go index a7c09d9..decaf72 100644 --- a/ksql_test.go +++ b/ksql_test.go @@ -27,7 +27,6 @@ func TestNewAdapterWith(t *testing.T) { tt.AssertNoErr(t, err) tt.AssertEqual(t, db.dialect, supportedDialects[dialectName]) - tt.AssertEqual(t, db.driver, dialectName) } }) diff --git a/test_adapters.go b/test_adapters.go index 1632d0d..38956a6 100644 --- a/test_adapters.go +++ b/test_adapters.go @@ -3577,7 +3577,6 @@ func createTables(driver string, connStr string) error { func newTestDB(db DBAdapter, driver string) DB { return DB{ - driver: driver, dialect: supportedDialects[driver], db: db, } From 24599e6644d533d042a4c86a8ae3e749bbb1e970 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Garcia?= Date: Wed, 21 Dec 2022 21:23:54 -0300 Subject: [PATCH 2/4] Improve NewWithAdapter to expect a dialect instead of a driver name --- Makefile | 6 +- adapters/kmysql/go.mod | 3 + adapters/kmysql/go.sum | 8 +- adapters/kmysql/kmysql.go | 5 +- adapters/kmysql/kmysql_test.go | 3 +- adapters/kpgx/go.mod | 6 + adapters/kpgx/go.sum | 16 +- adapters/kpgx/kpgx.go | 5 +- adapters/kpgx/kpgx_test.go | 3 +- adapters/ksqlite3/go.mod | 2 + adapters/ksqlite3/go.sum | 11 +- adapters/ksqlite3/ksqlite3.go | 5 +- adapters/ksqlite3/ksqlite3_test.go | 3 +- adapters/ksqlserver/go.mod | 5 + adapters/ksqlserver/go.sum | 21 +- adapters/ksqlserver/ksqlserver.go | 5 +- adapters/ksqlserver/ksqlserver_test.go | 3 +- benchmarks/benchmarks_test.go | 5 +- benchmarks/go.mod | 2 + benchmarks/go.sum | 22 +- contracts.go | 8 +- dialect.go | 115 ------- dialect_test.go | 24 -- examples/go.sum | 9 +- go.mod | 5 +- go.sum | 13 +- internal/kbuilder/insert.go | 10 +- internal/kbuilder/kbuilder.go | 16 +- internal/kbuilder/query.go | 14 +- ksql.go | 44 +-- ksql_test.go | 13 +- sqldialect/dialect.go | 104 ++++++ test_adapters.go | 433 ++++++++++++------------- 33 files changed, 487 insertions(+), 460 deletions(-) delete mode 100644 dialect.go delete mode 100644 dialect_test.go create mode 100644 sqldialect/dialect.go diff --git a/Makefile b/Makefile index ccfcac6..005abe6 100644 --- a/Makefile +++ b/Makefile @@ -48,7 +48,11 @@ gen: mock mock: setup $(GOBIN)/mockgen -package=exampleservice -source=contracts.go -destination=examples/example_service/mocks.go -setup: $(GOBIN)/richgo $(GOBIN)/staticcheck $(GOBIN)/mockgen +setup: $(GOBIN)/richgo $(GOBIN)/staticcheck $(GOBIN)/mockgen go.work + +go.work: + go work init + go work use -r . $(GOBIN)/richgo: go install github.com/kyoh86/richgo@latest diff --git a/adapters/kmysql/go.mod b/adapters/kmysql/go.mod index 3c58adb..1e85c57 100644 --- a/adapters/kmysql/go.mod +++ b/adapters/kmysql/go.mod @@ -10,13 +10,16 @@ require ( github.com/containerd/continuity v0.2.2 // indirect github.com/docker/go-connections v0.4.0 // indirect github.com/go-sql-driver/mysql v1.6.0 + github.com/google/go-cmp v0.5.6 // indirect github.com/gotestyourself/gotestyourself v2.2.0+incompatible // indirect github.com/lib/pq v1.10.4 // indirect github.com/opencontainers/image-spec v1.0.2 // indirect github.com/opencontainers/runc v1.1.0 // indirect github.com/ory/dockertest v3.3.5+incompatible + github.com/stretchr/testify v1.8.0 // indirect github.com/vingarcia/ksql v1.6.0 golang.org/x/net v0.0.0-20220225172249-27dd8689420f // indirect golang.org/x/sys v0.0.0-20220315194320-039c03cc5b86 // indirect + gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect gotest.tools v2.2.0+incompatible // indirect ) diff --git a/adapters/kmysql/go.sum b/adapters/kmysql/go.sum index 8e95edc..8588bbe 100644 --- a/adapters/kmysql/go.sum +++ b/adapters/kmysql/go.sum @@ -65,8 +65,8 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gotestyourself/gotestyourself v2.2.0+incompatible h1:AQwinXlbQR2HvPjQZOmDhRqsv5mZf+Jb1RnSLxcqZcI= github.com/gotestyourself/gotestyourself v2.2.0+incompatible/go.mod h1:zZKM6oeNM8k+FRljX1mnzVYeS8wiGgQyvST1/GafPbY= @@ -141,8 +141,8 @@ github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/y github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= @@ -214,14 +214,14 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/adapters/kmysql/kmysql.go b/adapters/kmysql/kmysql.go index 8241d19..cc23e91 100644 --- a/adapters/kmysql/kmysql.go +++ b/adapters/kmysql/kmysql.go @@ -5,6 +5,7 @@ import ( "database/sql" "github.com/vingarcia/ksql" + "github.com/vingarcia/ksql/sqldialect" // This is imported here so the user don't // have to worry about it when he uses it. @@ -13,7 +14,7 @@ import ( // NewFromSQLDB builds a ksql.DB from a *sql.DB instance func NewFromSQLDB(db *sql.DB) (ksql.DB, error) { - return ksql.NewWithAdapter(NewSQLAdapter(db), "mysql") + return ksql.NewWithAdapter(NewSQLAdapter(db), sqldialect.MysqlDialect{}) } // New instantiates a new KSQL client using the "mysql" driver @@ -34,5 +35,5 @@ func New( db.SetMaxOpenConns(config.MaxOpenConns) - return ksql.NewWithAdapter(NewSQLAdapter(db), "mysql") + return ksql.NewWithAdapter(NewSQLAdapter(db), sqldialect.MysqlDialect{}) } diff --git a/adapters/kmysql/kmysql_test.go b/adapters/kmysql/kmysql_test.go index 6433cad..94a9e4d 100644 --- a/adapters/kmysql/kmysql_test.go +++ b/adapters/kmysql/kmysql_test.go @@ -11,13 +11,14 @@ import ( "github.com/ory/dockertest" "github.com/ory/dockertest/docker" "github.com/vingarcia/ksql" + "github.com/vingarcia/ksql/sqldialect" ) func TestAdapter(t *testing.T) { mysqlURL, closeMySQL := startMySQLDB("ksql") defer closeMySQL() - ksql.RunTestsForAdapter(t, "kmysql", "mysql", mysqlURL, func(t *testing.T) (ksql.DBAdapter, io.Closer) { + ksql.RunTestsForAdapter(t, "kmysql", sqldialect.MysqlDialect{}, mysqlURL, func(t *testing.T) (ksql.DBAdapter, io.Closer) { db, err := sql.Open("mysql", mysqlURL) if err != nil { t.Fatal(err.Error()) diff --git a/adapters/kpgx/go.mod b/adapters/kpgx/go.mod index 8253e7a..83b037d 100644 --- a/adapters/kpgx/go.mod +++ b/adapters/kpgx/go.mod @@ -9,6 +9,7 @@ require ( github.com/cenkalti/backoff v2.2.1+incompatible // indirect github.com/containerd/continuity v0.2.2 // indirect github.com/docker/go-connections v0.4.0 // indirect + github.com/google/go-cmp v0.5.6 // indirect github.com/gotestyourself/gotestyourself v2.2.0+incompatible // indirect github.com/jackc/pgconn v1.10.0 github.com/jackc/pgx/v4 v4.13.0 @@ -16,6 +17,11 @@ require ( github.com/opencontainers/image-spec v1.0.2 // indirect github.com/opencontainers/runc v1.1.0 // indirect github.com/ory/dockertest v3.3.5+incompatible + github.com/stretchr/testify v1.8.0 // indirect github.com/vingarcia/ksql v1.6.0 + golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect + golang.org/x/net v0.0.0-20220225172249-27dd8689420f // indirect + golang.org/x/sys v0.0.0-20220315194320-039c03cc5b86 // indirect + gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect gotest.tools v2.2.0+incompatible // indirect ) diff --git a/adapters/kpgx/go.sum b/adapters/kpgx/go.sum index ca371fe..9aa4157 100644 --- a/adapters/kpgx/go.sum +++ b/adapters/kpgx/go.sum @@ -73,8 +73,8 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gotestyourself/gotestyourself v2.2.0+incompatible h1:AQwinXlbQR2HvPjQZOmDhRqsv5mZf+Jb1RnSLxcqZcI= @@ -224,8 +224,8 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= @@ -259,8 +259,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 h1:/UOmuWzQfxxo9UtlXMwuQU8CMgg1eZXqTRwkSQJWKOI= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= @@ -275,8 +275,8 @@ golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -305,16 +305,16 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c h1:DHcbWVXeY+0Y8HHKR+rbLwnoh2F4tNCY7rTiHJ30RmA= golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220315194320-039c03cc5b86 h1:A9i04dxx7Cribqbs8jf3FQLogkL/CV2YN7hj9KWJCkc= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -341,16 +341,16 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/adapters/kpgx/kpgx.go b/adapters/kpgx/kpgx.go index 7ab6a4f..71a6ea8 100644 --- a/adapters/kpgx/kpgx.go +++ b/adapters/kpgx/kpgx.go @@ -5,6 +5,7 @@ import ( "github.com/jackc/pgx/v4/pgxpool" "github.com/vingarcia/ksql" + "github.com/vingarcia/ksql/sqldialect" // This is imported here so the user don't // have to worry about it when he uses it. @@ -13,7 +14,7 @@ import ( // NewFromPgxPool builds a ksql.DB from a *pgxpool.Pool instance func NewFromPgxPool(pool *pgxpool.Pool) (db ksql.DB, err error) { - return ksql.NewWithAdapter(NewPGXAdapter(pool), "postgres") + return ksql.NewWithAdapter(NewPGXAdapter(pool), sqldialect.PostgresDialect{}) } // New instantiates a new ksql.Client using pgx as the backend driver @@ -39,6 +40,6 @@ func New( return ksql.DB{}, err } - db, err = ksql.NewWithAdapter(NewPGXAdapter(pool), "postgres") + db, err = ksql.NewWithAdapter(NewPGXAdapter(pool), sqldialect.PostgresDialect{}) return db, err } diff --git a/adapters/kpgx/kpgx_test.go b/adapters/kpgx/kpgx_test.go index d6d98ca..a0a2a64 100644 --- a/adapters/kpgx/kpgx_test.go +++ b/adapters/kpgx/kpgx_test.go @@ -13,13 +13,14 @@ import ( "github.com/ory/dockertest" "github.com/ory/dockertest/docker" "github.com/vingarcia/ksql" + "github.com/vingarcia/ksql/sqldialect" ) func TestAdapter(t *testing.T) { postgresURL, closePostgres := startPostgresDB("ksql") defer closePostgres() - ksql.RunTestsForAdapter(t, "kpgx", "postgres", postgresURL, func(t *testing.T) (ksql.DBAdapter, io.Closer) { + ksql.RunTestsForAdapter(t, "kpgx", sqldialect.PostgresDialect{}, postgresURL, func(t *testing.T) (ksql.DBAdapter, io.Closer) { pool, err := pgxpool.Connect(context.TODO(), postgresURL) if err != nil { t.Fatal(err.Error()) diff --git a/adapters/ksqlite3/go.mod b/adapters/ksqlite3/go.mod index 86aad59..4bdc889 100644 --- a/adapters/ksqlite3/go.mod +++ b/adapters/ksqlite3/go.mod @@ -4,5 +4,7 @@ go 1.14 require ( github.com/mattn/go-sqlite3 v1.14.12 + github.com/stretchr/testify v1.8.0 // indirect github.com/vingarcia/ksql v1.6.0 + gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect ) diff --git a/adapters/ksqlite3/go.sum b/adapters/ksqlite3/go.sum index 160220e..dfcb73f 100644 --- a/adapters/ksqlite3/go.sum +++ b/adapters/ksqlite3/go.sum @@ -11,12 +11,17 @@ github.com/mattn/go-sqlite3 v1.14.12/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/vingarcia/ksql v1.6.0 h1:YRAwLE/AvptLKO8C5Kq+hsh1gP2MtbJqbDIP/tu18mg= github.com/vingarcia/ksql v1.6.0/go.mod h1:4nOL38WsU6h25rbYyfkVbvzcly1RSBzJ9Oc5wgGMixU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/adapters/ksqlite3/ksqlite3.go b/adapters/ksqlite3/ksqlite3.go index 4850654..c12a811 100644 --- a/adapters/ksqlite3/ksqlite3.go +++ b/adapters/ksqlite3/ksqlite3.go @@ -5,6 +5,7 @@ import ( "database/sql" "github.com/vingarcia/ksql" + "github.com/vingarcia/ksql/sqldialect" // This is imported here so the user don't // have to worry about it when he uses it. @@ -13,7 +14,7 @@ import ( // NewFromSQLDB builds a ksql.DB from a *sql.DB instance func NewFromSQLDB(db *sql.DB) (ksql.DB, error) { - return ksql.NewWithAdapter(NewSQLAdapter(db), "sqlite3") + return ksql.NewWithAdapter(NewSQLAdapter(db), sqldialect.Sqlite3Dialect{}) } // New instantiates a new KSQL client using the "sqlite3" driver @@ -34,5 +35,5 @@ func New( db.SetMaxOpenConns(config.MaxOpenConns) - return ksql.NewWithAdapter(NewSQLAdapter(db), "sqlite3") + return ksql.NewWithAdapter(NewSQLAdapter(db), sqldialect.Sqlite3Dialect{}) } diff --git a/adapters/ksqlite3/ksqlite3_test.go b/adapters/ksqlite3/ksqlite3_test.go index aba43a0..0ecae2c 100644 --- a/adapters/ksqlite3/ksqlite3_test.go +++ b/adapters/ksqlite3/ksqlite3_test.go @@ -6,10 +6,11 @@ import ( "testing" "github.com/vingarcia/ksql" + "github.com/vingarcia/ksql/sqldialect" ) func TestAdapter(t *testing.T) { - ksql.RunTestsForAdapter(t, "ksqlite", "sqlite3", "/tmp/ksql.db", func(t *testing.T) (ksql.DBAdapter, io.Closer) { + ksql.RunTestsForAdapter(t, "ksqlite", sqldialect.Sqlite3Dialect{}, "/tmp/ksql.db", func(t *testing.T) (ksql.DBAdapter, io.Closer) { db, err := sql.Open("sqlite3", "/tmp/ksql.db") if err != nil { t.Fatal(err.Error()) diff --git a/adapters/ksqlserver/go.mod b/adapters/ksqlserver/go.mod index 91ec3d6..69ffa32 100644 --- a/adapters/ksqlserver/go.mod +++ b/adapters/ksqlserver/go.mod @@ -10,12 +10,17 @@ require ( github.com/containerd/continuity v0.2.2 // indirect github.com/denisenkom/go-mssqldb v0.10.0 github.com/docker/go-connections v0.4.0 // indirect + github.com/google/go-cmp v0.5.6 // indirect github.com/gotestyourself/gotestyourself v2.2.0+incompatible // indirect github.com/lib/pq v1.10.4 // indirect github.com/opencontainers/image-spec v1.0.2 // indirect github.com/opencontainers/runc v1.1.0 // indirect github.com/ory/dockertest v3.3.5+incompatible + github.com/stretchr/testify v1.8.0 // indirect github.com/vingarcia/ksql v1.6.0 + golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect golang.org/x/net v0.0.0-20220225172249-27dd8689420f // indirect + golang.org/x/sys v0.0.0-20220315194320-039c03cc5b86 // indirect + gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect gotest.tools v2.2.0+incompatible // indirect ) diff --git a/adapters/ksqlserver/go.sum b/adapters/ksqlserver/go.sum index 1a1789e..0147f63 100644 --- a/adapters/ksqlserver/go.sum +++ b/adapters/ksqlserver/go.sum @@ -67,8 +67,9 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gotestyourself/gotestyourself v2.2.0+incompatible h1:AQwinXlbQR2HvPjQZOmDhRqsv5mZf+Jb1RnSLxcqZcI= github.com/gotestyourself/gotestyourself v2.2.0+incompatible/go.mod h1:zZKM6oeNM8k+FRljX1mnzVYeS8wiGgQyvST1/GafPbY= @@ -142,9 +143,12 @@ github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= @@ -162,8 +166,9 @@ go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/ go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c h1:Vj5n4GlwjmQteupaxJ9+0FNOmBrHfq7vN4btdGoDZgI= golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -172,6 +177,7 @@ golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -195,8 +201,9 @@ golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220315194320-039c03cc5b86 h1:A9i04dxx7Cribqbs8jf3FQLogkL/CV2YN7hj9KWJCkc= +golang.org/x/sys v0.0.0-20220315194320-039c03cc5b86/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -217,14 +224,16 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/adapters/ksqlserver/ksqlserver.go b/adapters/ksqlserver/ksqlserver.go index 94dd775..751fb6d 100644 --- a/adapters/ksqlserver/ksqlserver.go +++ b/adapters/ksqlserver/ksqlserver.go @@ -5,6 +5,7 @@ import ( "database/sql" "github.com/vingarcia/ksql" + "github.com/vingarcia/ksql/sqldialect" // This is imported here so the user don't // have to worry about it when he uses it. @@ -13,7 +14,7 @@ import ( // NewFromSQLDB builds a ksql.DB from a *sql.DB instance func NewFromSQLDB(db *sql.DB) (ksql.DB, error) { - return ksql.NewWithAdapter(NewSQLAdapter(db), "sqlserver") + return ksql.NewWithAdapter(NewSQLAdapter(db), sqldialect.SqlserverDialect{}) } // New instantiates a new KSQL client using the "sqlserver" driver @@ -34,5 +35,5 @@ func New( db.SetMaxOpenConns(config.MaxOpenConns) - return ksql.NewWithAdapter(NewSQLAdapter(db), "sqlserver") + return ksql.NewWithAdapter(NewSQLAdapter(db), sqldialect.SqlserverDialect{}) } diff --git a/adapters/ksqlserver/ksqlserver_test.go b/adapters/ksqlserver/ksqlserver_test.go index bea1c25..54afb74 100644 --- a/adapters/ksqlserver/ksqlserver_test.go +++ b/adapters/ksqlserver/ksqlserver_test.go @@ -11,13 +11,14 @@ import ( "github.com/ory/dockertest" "github.com/ory/dockertest/docker" "github.com/vingarcia/ksql" + "github.com/vingarcia/ksql/sqldialect" ) func TestAdapter(t *testing.T) { sqlServerURL, closeSQLServer := startSQLServerDB("ksql") defer closeSQLServer() - ksql.RunTestsForAdapter(t, "ksqlserver", "sqlserver", sqlServerURL, func(t *testing.T) (ksql.DBAdapter, io.Closer) { + ksql.RunTestsForAdapter(t, "ksqlserver", sqldialect.SqlserverDialect{}, sqlServerURL, func(t *testing.T) (ksql.DBAdapter, io.Closer) { db, err := sql.Open("sqlserver", sqlServerURL) if err != nil { t.Fatal(err.Error()) diff --git a/benchmarks/benchmarks_test.go b/benchmarks/benchmarks_test.go index 8b15f51..a77b590 100644 --- a/benchmarks/benchmarks_test.go +++ b/benchmarks/benchmarks_test.go @@ -16,6 +16,7 @@ import ( "github.com/vingarcia/ksql/adapters/kpgx" "github.com/vingarcia/ksql/benchmarks/sqlboilergen" "github.com/vingarcia/ksql/benchmarks/sqlcgen" + "github.com/vingarcia/ksql/sqldialect" "github.com/volatiletech/sqlboiler/v4/boil" "github.com/volatiletech/sqlboiler/v4/queries/qm" "gorm.io/driver/postgres" @@ -42,7 +43,7 @@ func BenchmarkInsert(b *testing.B) { b.Fatalf("error connecting to database: %s", err) } db.SetMaxOpenConns(1) - ksqlDB, err := ksql.NewWithAdapter(NewSQLAdapter(db), driver) + ksqlDB, err := ksql.NewWithAdapter(NewSQLAdapter(db), sqldialect.PostgresDialect{}) if err != nil { b.Fatalf("error creating ksql client: %s", err) } @@ -425,7 +426,7 @@ func BenchmarkQuery(b *testing.B) { b.Fatalf("error connecting to database: %s", err) } db.SetMaxOpenConns(1) - ksqlDB, err := ksql.NewWithAdapter(NewSQLAdapter(db), driver) + ksqlDB, err := ksql.NewWithAdapter(NewSQLAdapter(db), sqldialect.PostgresDialect{}) if err != nil { b.Fatalf("error creating ksql client: %s", err) } diff --git a/benchmarks/go.mod b/benchmarks/go.mod index 70ce09e..b48a54c 100644 --- a/benchmarks/go.mod +++ b/benchmarks/go.mod @@ -4,9 +4,11 @@ go 1.16 require ( github.com/friendsofgo/errors v0.9.2 + github.com/go-sql-driver/mysql v1.6.0 // indirect github.com/jackc/pgx/v4 v4.13.0 github.com/jmoiron/sqlx v1.3.4 github.com/lib/pq v1.10.4 + github.com/mattn/go-sqlite3 v1.14.12 // indirect github.com/vingarcia/ksql v1.6.0 github.com/vingarcia/ksql/adapters/kpgx v0.0.0-00010101000000-000000000000 github.com/volatiletech/sqlboiler/v4 v4.12.0 diff --git a/benchmarks/go.sum b/benchmarks/go.sum index 635771a..ea726d1 100644 --- a/benchmarks/go.sum +++ b/benchmarks/go.sum @@ -141,8 +141,9 @@ github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vb github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= +github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= @@ -362,8 +363,9 @@ github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcME github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= -github.com/mattn/go-sqlite3 v1.14.10 h1:MLn+5bFRlWMGoSRmJour3CL1w/qL96mvipqpwQW/Sfk= github.com/mattn/go-sqlite3 v1.14.10/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= +github.com/mattn/go-sqlite3 v1.14.12 h1:TJ1bhYJPV44phC+IMu1u2K/i5RriLTPe+yc68XDJ1Z0= +github.com/mattn/go-sqlite3 v1.14.12/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= @@ -465,13 +467,16 @@ github.com/spf13/viper v1.9.0/go.mod h1:+i6ajR7OX2XaiBkrcZJFK21htRk7eDeLg7+O6bhU github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= @@ -620,8 +625,9 @@ golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420 h1:a8jGStKg0XqKDlKqjLrXn0ioF5MH36pT7Z0BRTqLhbk= golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -720,10 +726,13 @@ golang.org/x/sys v0.0.0-20210902050250-f475640dd07b/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c h1:DHcbWVXeY+0Y8HHKR+rbLwnoh2F4tNCY7rTiHJ30RmA= golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220315194320-039c03cc5b86 h1:A9i04dxx7Cribqbs8jf3FQLogkL/CV2YN7hj9KWJCkc= +golang.org/x/sys v0.0.0-20220315194320-039c03cc5b86/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -953,8 +962,9 @@ gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gorm.io/driver/postgres v1.2.2 h1:Ka9W6feOU+rPM9m007eYLMD4QoZuYGBnQ3Jp0faGSwg= gorm.io/driver/postgres v1.2.2/go.mod h1:Ik3tK+a3FMp8ORZl29v4b3M0RsgXsaeMXh9s9eVMXco= gorm.io/gorm v1.22.2/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0= diff --git a/contracts.go b/contracts.go index 6732ebd..f1557f2 100644 --- a/contracts.go +++ b/contracts.go @@ -4,6 +4,8 @@ import ( "context" "database/sql" "fmt" + + "github.com/vingarcia/ksql/sqldialect" ) // ErrRecordNotFound informs that a given query failed because the record was not found. @@ -101,14 +103,14 @@ func (t Table) validate() error { return nil } -func (t Table) insertMethodFor(dialect Dialect) insertMethod { +func (t Table) insertMethodFor(dialect sqldialect.Provider) sqldialect.InsertMethod { if len(t.idColumns) == 1 { return dialect.InsertMethod() } insertMethod := dialect.InsertMethod() - if insertMethod == insertWithLastInsertID { - return insertWithNoIDRetrieval + if insertMethod == sqldialect.InsertWithLastInsertID { + return sqldialect.InsertWithNoIDRetrieval } return insertMethod diff --git a/dialect.go b/dialect.go deleted file mode 100644 index 8a5711c..0000000 --- a/dialect.go +++ /dev/null @@ -1,115 +0,0 @@ -package ksql - -import ( - "fmt" - "strconv" -) - -type insertMethod int - -const ( - insertWithReturning insertMethod = iota - insertWithOutput - insertWithLastInsertID - insertWithNoIDRetrieval -) - -var supportedDialects = map[string]Dialect{ - "postgres": &postgresDialect{}, - "sqlite3": &sqlite3Dialect{}, - "mysql": &mysqlDialect{}, - "sqlserver": &sqlserverDialect{}, -} - -// Dialect is used to represent the different ways -// of writing SQL queries used by each SQL driver. -type Dialect interface { - InsertMethod() insertMethod - Escape(str string) string - Placeholder(idx int) string - DriverName() string -} - -type postgresDialect struct{} - -func (postgresDialect) DriverName() string { - return "postgres" -} - -func (postgresDialect) InsertMethod() insertMethod { - return insertWithReturning -} - -func (postgresDialect) Escape(str string) string { - return `"` + str + `"` -} - -func (postgresDialect) Placeholder(idx int) string { - return "$" + strconv.Itoa(idx+1) -} - -type sqlite3Dialect struct{} - -func (sqlite3Dialect) DriverName() string { - return "sqlite3" -} - -func (sqlite3Dialect) InsertMethod() insertMethod { - return insertWithLastInsertID -} - -func (sqlite3Dialect) Escape(str string) string { - return "`" + str + "`" -} - -func (sqlite3Dialect) Placeholder(idx int) string { - return "?" -} - -// GetDriverDialect instantiantes the dialect for the -// provided driver string, if the drive is not supported -// it returns an error -func GetDriverDialect(driver string) (Dialect, error) { - dialect, found := supportedDialects[driver] - if !found { - return nil, fmt.Errorf("unsupported driver `%s`", driver) - } - - return dialect, nil -} - -type mysqlDialect struct{} - -func (mysqlDialect) DriverName() string { - return "mysql" -} - -func (mysqlDialect) InsertMethod() insertMethod { - return insertWithLastInsertID -} - -func (mysqlDialect) Escape(str string) string { - return "`" + str + "`" -} - -func (mysqlDialect) Placeholder(idx int) string { - return "?" -} - -type sqlserverDialect struct{} - -func (sqlserverDialect) DriverName() string { - return "sqlserver" -} - -func (sqlserverDialect) InsertMethod() insertMethod { - return insertWithOutput -} - -func (sqlserverDialect) Escape(str string) string { - return `[` + str + `]` -} - -func (sqlserverDialect) Placeholder(idx int) string { - return "@p" + strconv.Itoa(idx+1) -} diff --git a/dialect_test.go b/dialect_test.go deleted file mode 100644 index bad5471..0000000 --- a/dialect_test.go +++ /dev/null @@ -1,24 +0,0 @@ -package ksql - -import ( - "testing" - - tt "github.com/vingarcia/ksql/internal/testtools" -) - -func TestGetDriverDialect(t *testing.T) { - t.Run("should work for all registered drivers", func(t *testing.T) { - for drivername, expectedDialect := range supportedDialects { - t.Run(drivername, func(t *testing.T) { - dialect, err := GetDriverDialect(drivername) - tt.AssertNoErr(t, err) - tt.AssertEqual(t, dialect, expectedDialect) - }) - } - }) - - t.Run("should report error if no driver is found", func(t *testing.T) { - _, err := GetDriverDialect("non-existing-driver") - tt.AssertErrContains(t, err, "unsupported driver", "non-existing-driver") - }) -} diff --git a/examples/go.sum b/examples/go.sum index 98a15fb..7494cfe 100644 --- a/examples/go.sum +++ b/examples/go.sum @@ -81,8 +81,9 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gotestyourself/gotestyourself v2.2.0+incompatible h1:AQwinXlbQR2HvPjQZOmDhRqsv5mZf+Jb1RnSLxcqZcI= @@ -272,8 +273,9 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 h1:/UOmuWzQfxxo9UtlXMwuQU8CMgg1eZXqTRwkSQJWKOI= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= @@ -366,8 +368,9 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= diff --git a/go.mod b/go.mod index 8e28016..e160b47 100644 --- a/go.mod +++ b/go.mod @@ -3,8 +3,7 @@ module github.com/vingarcia/ksql go 1.14 require ( - github.com/davecgh/go-spew v1.1.1 // indirect github.com/kr/pretty v0.2.1 // indirect - github.com/stretchr/testify v1.7.0 - gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect + github.com/stretchr/testify v1.8.0 + gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect ) diff --git a/go.sum b/go.sum index 7413aff..8dbdc6e 100644 --- a/go.sum +++ b/go.sum @@ -9,10 +9,13 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/internal/kbuilder/insert.go b/internal/kbuilder/insert.go index eb34300..8b967fd 100644 --- a/internal/kbuilder/insert.go +++ b/internal/kbuilder/insert.go @@ -5,8 +5,8 @@ import ( "reflect" "strings" - "github.com/vingarcia/ksql" "github.com/vingarcia/ksql/internal/structs" + "github.com/vingarcia/ksql/sqldialect" ) // Insert is the struct template for building INSERT queries @@ -22,16 +22,16 @@ type Insert struct { // Build is a utility function for finding the dialect based on the driver and // then calling BuildQuery(dialect) func (i Insert) Build(driver string) (sqlQuery string, params []interface{}, _ error) { - dialect, err := ksql.GetDriverDialect(driver) - if err != nil { - return "", nil, err + dialect, ok := sqldialect.SupportedDialects[driver] + if !ok { + return "", nil, fmt.Errorf("unsupported driver `%s`", driver) } return i.BuildQuery(dialect) } // BuildQuery implements the queryBuilder interface -func (i Insert) BuildQuery(dialect ksql.Dialect) (sqlQuery string, params []interface{}, _ error) { +func (i Insert) BuildQuery(dialect sqldialect.Provider) (sqlQuery string, params []interface{}, _ error) { var b strings.Builder b.WriteString("INSERT INTO " + dialect.Escape(i.Into)) diff --git a/internal/kbuilder/kbuilder.go b/internal/kbuilder/kbuilder.go index 0cf84de..a9663ac 100644 --- a/internal/kbuilder/kbuilder.go +++ b/internal/kbuilder/kbuilder.go @@ -1,7 +1,9 @@ package kbuilder import ( - "github.com/vingarcia/ksql" + "fmt" + + "github.com/vingarcia/ksql/sqldialect" ) // Builder is the basic container for injecting @@ -11,19 +13,23 @@ import ( // directly without this builder, but we kept it // here for convenience. type Builder struct { - dialect ksql.Dialect + dialect sqldialect.Provider } type queryBuilder interface { - BuildQuery(dialect ksql.Dialect) (sqlQuery string, params []interface{}, _ error) + BuildQuery(dialect sqldialect.Provider) (sqlQuery string, params []interface{}, _ error) } // New creates a new Builder container. func New(driver string) (Builder, error) { - dialect, err := ksql.GetDriverDialect(driver) + dialect, ok := sqldialect.SupportedDialects[driver] + if !ok { + return Builder{}, fmt.Errorf("unsupported driver `%s`", driver) + } + return Builder{ dialect: dialect, - }, err + }, nil } // Build receives a query builder struct, injects it with the configurations diff --git a/internal/kbuilder/query.go b/internal/kbuilder/query.go index a36ab26..55e7d4d 100644 --- a/internal/kbuilder/query.go +++ b/internal/kbuilder/query.go @@ -7,8 +7,8 @@ import ( "strings" "sync" - "github.com/vingarcia/ksql" "github.com/vingarcia/ksql/internal/structs" + "github.com/vingarcia/ksql/sqldialect" ) // Query is is the struct template for building SELECT queries. @@ -33,16 +33,16 @@ type Query struct { // Build is a utility function for finding the dialect based on the driver and // then calling BuildQuery(dialect) func (q Query) Build(driver string) (sqlQuery string, params []interface{}, _ error) { - dialect, err := ksql.GetDriverDialect(driver) - if err != nil { - return "", nil, err + dialect, ok := sqldialect.SupportedDialects[driver] + if !ok { + return "", nil, fmt.Errorf("unsupported driver `%s`", driver) } return q.BuildQuery(dialect) } // BuildQuery implements the queryBuilder interface -func (q Query) BuildQuery(dialect ksql.Dialect) (sqlQuery string, params []interface{}, _ error) { +func (q Query) BuildQuery(dialect sqldialect.Provider) (sqlQuery string, params []interface{}, _ error) { var b strings.Builder switch v := q.Select.(type) { @@ -106,7 +106,7 @@ type WhereQuery struct { // in a dynamic way. type WhereQueries []WhereQuery -func (w WhereQueries) build(dialect ksql.Dialect) (query string, params []interface{}) { +func (w WhereQueries) build(dialect sqldialect.Provider) (query string, params []interface{}) { var conds []string for _, whereQuery := range w { var placeholders []interface{} @@ -190,7 +190,7 @@ func OrderBy(fields string) OrderByQuery { var cachedSelectQueries = &sync.Map{} // Builds the select query using cached info so that its efficient -func buildSelectQuery(obj interface{}, dialect ksql.Dialect) (string, error) { +func buildSelectQuery(obj interface{}, dialect sqldialect.Provider) (string, error) { t := reflect.TypeOf(obj) if t.Kind() == reflect.Ptr { t = t.Elem() diff --git a/ksql.go b/ksql.go index 6e2196b..5972ed5 100644 --- a/ksql.go +++ b/ksql.go @@ -13,13 +13,14 @@ import ( "github.com/vingarcia/ksql/internal/modifiers" "github.com/vingarcia/ksql/internal/structs" "github.com/vingarcia/ksql/ksqlmodifiers" + "github.com/vingarcia/ksql/sqldialect" ) var selectQueryCache = initializeQueryCache() func initializeQueryCache() map[string]*sync.Map { cache := map[string]*sync.Map{} - for dname := range supportedDialects { + for dname := range sqldialect.SupportedDialects { cache[dname] = &sync.Map{} } @@ -30,7 +31,7 @@ func initializeQueryCache() map[string]*sync.Map { // interfacing with the "database/sql" package implementing // the KSQL interface `ksql.Provider`. type DB struct { - dialect Dialect + dialect sqldialect.Provider db DBAdapter } @@ -122,17 +123,16 @@ func (c *Config) SetDefaultValues() { // NewWithAdapter allows the user to insert a custom implementation // of the DBAdapter interface func NewWithAdapter( - db DBAdapter, - dialectName string, + adapter DBAdapter, + dialect sqldialect.Provider, ) (DB, error) { - dialect := supportedDialects[dialectName] if dialect == nil { - return DB{}, fmt.Errorf("unsupported driver `%s`", dialectName) + return DB{}, fmt.Errorf("expected a valid sqldialect.Provider as argument but got `nil`") } return DB{ dialect: dialect, - db: db, + db: adapter, }, nil } @@ -452,11 +452,11 @@ func (c DB) Insert( } switch table.insertMethodFor(c.dialect) { - case insertWithReturning, insertWithOutput: + case sqldialect.InsertWithReturning, sqldialect.InsertWithOutput: err = c.insertReturningIDs(ctx, query, params, scanValues, table.idColumns) - case insertWithLastInsertID: + case sqldialect.InsertWithLastInsertID: err = c.insertWithLastInsertID(ctx, t, v, info, record, query, params, table.idColumns[0]) - case insertWithNoIDRetrieval: + case sqldialect.InsertWithNoIDRetrieval: err = c.insertWithNoIDRetrieval(ctx, query, params) default: // Unsupported drivers should be detected on the New() function, @@ -714,7 +714,7 @@ func (c DB) Patch( func buildInsertQuery( ctx context.Context, - dialect Dialect, + dialect sqldialect.Provider, table Table, t reflect.Type, v reflect.Value, @@ -777,7 +777,7 @@ func buildInsertQuery( var returningQuery, outputQuery string switch dialect.InsertMethod() { - case insertWithReturning: + case sqldialect.InsertWithReturning: escapedIDNames := []string{} for _, id := range table.idColumns { escapedIDNames = append(escapedIDNames, dialect.Escape(id)) @@ -790,7 +790,7 @@ func buildInsertQuery( v.Elem().Field(info.ByName(id).Index).Addr().Interface(), ) } - case insertWithOutput: + case sqldialect.InsertWithOutput: escapedIDNames := []string{} for _, id := range table.idColumns { escapedIDNames = append(escapedIDNames, "INSERTED."+dialect.Escape(id)) @@ -831,7 +831,7 @@ func buildInsertQuery( func buildUpdateQuery( ctx context.Context, - dialect Dialect, + dialect sqldialect.Provider, tableName string, info structs.StructInfo, recordMap map[string]interface{}, @@ -998,7 +998,7 @@ func (nopScanner) Scan(value interface{}) error { return nil } -func scanRows(ctx context.Context, dialect Dialect, rows Rows, record interface{}) error { +func scanRows(ctx context.Context, dialect sqldialect.Provider, rows Rows, record interface{}) error { v := reflect.ValueOf(record) t := v.Type() return scanRowsFromType(ctx, dialect, rows, record, t, v) @@ -1006,7 +1006,7 @@ func scanRows(ctx context.Context, dialect Dialect, rows Rows, record interface{ func scanRowsFromType( ctx context.Context, - dialect Dialect, + dialect sqldialect.Provider, rows Rows, record interface{}, t reflect.Type, @@ -1063,7 +1063,7 @@ func scanRowsFromType( func getScanArgsForNestedStructs( ctx context.Context, - dialect Dialect, + dialect sqldialect.Provider, rows Rows, t reflect.Type, v reflect.Value, @@ -1112,7 +1112,7 @@ func getScanArgsForNestedStructs( func getScanArgsFromNames( ctx context.Context, - dialect Dialect, + dialect sqldialect.Provider, names []string, v reflect.Value, info structs.StructInfo, @@ -1146,7 +1146,7 @@ func getScanArgsFromNames( } func buildDeleteQuery( - dialect Dialect, + dialect sqldialect.Provider, table Table, idMap map[string]interface{}, ) (query string, params []interface{}) { @@ -1182,7 +1182,7 @@ func getFirstToken(s string) string { } func buildSelectQuery( - dialect Dialect, + dialect sqldialect.Provider, structType reflect.Type, info structs.StructInfo, selectQueryCache *sync.Map, @@ -1209,7 +1209,7 @@ func buildSelectQuery( } func buildSelectQueryForPlainStructs( - dialect Dialect, + dialect sqldialect.Provider, structType reflect.Type, info structs.StructInfo, ) string { @@ -1227,7 +1227,7 @@ func buildSelectQueryForPlainStructs( } func buildSelectQueryForNestedStructs( - dialect Dialect, + dialect sqldialect.Provider, structType reflect.Type, info structs.StructInfo, ) (string, error) { diff --git a/ksql_test.go b/ksql_test.go index decaf72..17f9409 100644 --- a/ksql_test.go +++ b/ksql_test.go @@ -6,6 +6,7 @@ import ( "testing" tt "github.com/vingarcia/ksql/internal/testtools" + "github.com/vingarcia/ksql/sqldialect" ) func TestConfigSetDefaultValues(t *testing.T) { @@ -19,24 +20,24 @@ func TestConfigSetDefaultValues(t *testing.T) { func TestNewAdapterWith(t *testing.T) { t.Run("should build new instances correctly", func(t *testing.T) { - for dialectName := range supportedDialects { + for _, dialect := range sqldialect.SupportedDialects { db, err := NewWithAdapter( DBAdapter(nil), - dialectName, + dialect, ) tt.AssertNoErr(t, err) - tt.AssertEqual(t, db.dialect, supportedDialects[dialectName]) + tt.AssertEqual(t, db.dialect, dialect) } }) - t.Run("should report invalid dialectNames correctly", func(t *testing.T) { + t.Run("should report invalid dialects correctly", func(t *testing.T) { _, err := NewWithAdapter( DBAdapter(nil), - "fake-dialect-name", + nil, ) - tt.AssertNotEqual(t, err, nil) + tt.AssertErrContains(t, err, "expected a valid", "Provider", "nil") }) } diff --git a/sqldialect/dialect.go b/sqldialect/dialect.go new file mode 100644 index 0000000..dfea76e --- /dev/null +++ b/sqldialect/dialect.go @@ -0,0 +1,104 @@ +package sqldialect + +import ( + "strconv" +) + +type InsertMethod int + +const ( + InsertWithReturning InsertMethod = iota + InsertWithOutput + InsertWithLastInsertID + InsertWithNoIDRetrieval +) + +var SupportedDialects = map[string]Provider{ + "postgres": &PostgresDialect{}, + "sqlite3": &Sqlite3Dialect{}, + "mysql": &MysqlDialect{}, + "sqlserver": &SqlserverDialect{}, +} + +// Provider or dialect.Provider represents one particular +// way of writing SQL queries. +// +// Different DBAdapters will use require different dialects to work. +type Provider interface { + InsertMethod() InsertMethod + Escape(str string) string + Placeholder(idx int) string + DriverName() string +} + +type PostgresDialect struct{} + +func (PostgresDialect) DriverName() string { + return "postgres" +} + +func (PostgresDialect) InsertMethod() InsertMethod { + return InsertWithReturning +} + +func (PostgresDialect) Escape(str string) string { + return `"` + str + `"` +} + +func (PostgresDialect) Placeholder(idx int) string { + return "$" + strconv.Itoa(idx+1) +} + +type Sqlite3Dialect struct{} + +func (Sqlite3Dialect) DriverName() string { + return "sqlite3" +} + +func (Sqlite3Dialect) InsertMethod() InsertMethod { + return InsertWithLastInsertID +} + +func (Sqlite3Dialect) Escape(str string) string { + return "`" + str + "`" +} + +func (Sqlite3Dialect) Placeholder(idx int) string { + return "?" +} + +type MysqlDialect struct{} + +func (MysqlDialect) DriverName() string { + return "mysql" +} + +func (MysqlDialect) InsertMethod() InsertMethod { + return InsertWithLastInsertID +} + +func (MysqlDialect) Escape(str string) string { + return "`" + str + "`" +} + +func (MysqlDialect) Placeholder(idx int) string { + return "?" +} + +type SqlserverDialect struct{} + +func (SqlserverDialect) DriverName() string { + return "sqlserver" +} + +func (SqlserverDialect) InsertMethod() InsertMethod { + return InsertWithOutput +} + +func (SqlserverDialect) Escape(str string) string { + return `[` + str + `]` +} + +func (SqlserverDialect) Placeholder(idx int) string { + return "@p" + strconv.Itoa(idx+1) +} diff --git a/test_adapters.go b/test_adapters.go index 38956a6..1033dfe 100644 --- a/test_adapters.go +++ b/test_adapters.go @@ -17,6 +17,7 @@ import ( tt "github.com/vingarcia/ksql/internal/testtools" "github.com/vingarcia/ksql/ksqlmodifiers" "github.com/vingarcia/ksql/nullable" + "github.com/vingarcia/ksql/sqldialect" ) var usersTable = NewTable("users") @@ -67,28 +68,28 @@ type userPermission struct { func RunTestsForAdapter( t *testing.T, adapterName string, - driver string, + dialect sqldialect.Provider, connStr string, newDBAdapter func(t *testing.T) (DBAdapter, io.Closer), ) { - t.Run(adapterName+"."+driver, func(t *testing.T) { - QueryTest(t, driver, connStr, newDBAdapter) - QueryOneTest(t, driver, connStr, newDBAdapter) - InsertTest(t, driver, connStr, newDBAdapter) - DeleteTest(t, driver, connStr, newDBAdapter) - PatchTest(t, driver, connStr, newDBAdapter) - QueryChunksTest(t, driver, connStr, newDBAdapter) - TransactionTest(t, driver, connStr, newDBAdapter) - ModifiersTest(t, driver, connStr, newDBAdapter) - ScanRowsTest(t, driver, connStr, newDBAdapter) + t.Run(adapterName+"."+dialect.DriverName(), func(t *testing.T) { + QueryTest(t, dialect, connStr, newDBAdapter) + QueryOneTest(t, dialect, connStr, newDBAdapter) + InsertTest(t, dialect, connStr, newDBAdapter) + DeleteTest(t, dialect, connStr, newDBAdapter) + PatchTest(t, dialect, connStr, newDBAdapter) + QueryChunksTest(t, dialect, connStr, newDBAdapter) + TransactionTest(t, dialect, connStr, newDBAdapter) + ModifiersTest(t, dialect, connStr, newDBAdapter) + ScanRowsTest(t, dialect, connStr, newDBAdapter) }) } // QueryTest runs all tests for making sure the Query function is -// working for a given adapter and driver. +// working for a given adapter and dialect. func QueryTest( t *testing.T, - driver string, + dialect sqldialect.Provider, connStr string, newDBAdapter func(t *testing.T) (DBAdapter, io.Closer), ) { @@ -111,7 +112,7 @@ func QueryTest( for _, variation := range variations { t.Run(variation.desc, func(t *testing.T) { t.Run("using slice of structs", func(t *testing.T) { - err := createTables(driver, connStr) + err := createTables(dialect, connStr) if err != nil { t.Fatal("could not create test table!, reason:", err.Error()) } @@ -120,7 +121,7 @@ func QueryTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) var users []user err := c.Query(ctx, &users, variation.queryPrefix+`FROM users WHERE id=1;`) tt.AssertNoErr(t, err) @@ -139,7 +140,7 @@ func QueryTest( _, err := db.ExecContext(ctx, `INSERT INTO users (name, age, address) VALUES ('Bia', 0, '{"country":"BR"}')`) tt.AssertNoErr(t, err) - c := newTestDB(db, driver) + c := newTestDB(db, dialect) var users []user err = c.Query(ctx, &users, variation.queryPrefix+`FROM users WHERE name=`+c.dialect.Placeholder(0), "Bia") @@ -160,7 +161,7 @@ func QueryTest( _, err = db.ExecContext(ctx, `INSERT INTO users (name, age, address) VALUES ('Bia Garcia', 0, '{"country":"BR"}')`) tt.AssertNoErr(t, err) - c := newTestDB(db, driver) + c := newTestDB(db, dialect) var users []user err = c.Query(ctx, &users, variation.queryPrefix+`FROM users WHERE name like `+c.dialect.Placeholder(0), "% Garcia") @@ -188,13 +189,13 @@ func QueryTest( _, err := db.ExecContext(ctx, `INSERT INTO users (name, age, address) VALUES ('João Ribeiro', 0, '{"country":"US"}')`) tt.AssertNoErr(t, err) var joao user - getUserByName(db, driver, &joao, "João Ribeiro") + getUserByName(db, dialect, &joao, "João Ribeiro") tt.AssertNoErr(t, err) _, err = db.ExecContext(ctx, `INSERT INTO users (name, age, address) VALUES ('Bia Ribeiro', 0, '{"country":"BR"}')`) tt.AssertNoErr(t, err) var bia user - getUserByName(db, driver, &bia, "Bia Ribeiro") + getUserByName(db, dialect, &bia, "Bia Ribeiro") _, err = db.ExecContext(ctx, fmt.Sprint(`INSERT INTO posts (user_id, title) VALUES (`, bia.ID, `, 'Bia Post1')`)) tt.AssertNoErr(t, err) @@ -204,7 +205,7 @@ func QueryTest( tt.AssertNoErr(t, err) ctx := context.Background() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) var rows []struct { User user `tablename:"u"` Post post `tablename:"p"` @@ -241,7 +242,7 @@ func QueryTest( }) t.Run("using slice of pointers to structs", func(t *testing.T) { - err := createTables(driver, connStr) + err := createTables(dialect, connStr) if err != nil { t.Fatal("could not create test table!, reason:", err.Error()) } @@ -250,7 +251,7 @@ func QueryTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) var users []*user err := c.Query(ctx, &users, variation.queryPrefix+`FROM users WHERE id=1;`) tt.AssertNoErr(t, err) @@ -269,7 +270,7 @@ func QueryTest( _, err := db.ExecContext(ctx, `INSERT INTO users (name, age, address) VALUES ('Bia', 0, '{"country":"BR"}')`) tt.AssertNoErr(t, err) - c := newTestDB(db, driver) + c := newTestDB(db, dialect) var users []*user err = c.Query(ctx, &users, variation.queryPrefix+`FROM users WHERE name=`+c.dialect.Placeholder(0), "Bia") @@ -290,7 +291,7 @@ func QueryTest( _, err = db.ExecContext(ctx, `INSERT INTO users (name, age, address) VALUES ('Bia Garcia', 0, '{"country":"BR"}')`) tt.AssertNoErr(t, err) - c := newTestDB(db, driver) + c := newTestDB(db, dialect) var users []*user err = c.Query(ctx, &users, variation.queryPrefix+`FROM users WHERE name like `+c.dialect.Placeholder(0), "% Garcia") @@ -318,12 +319,12 @@ func QueryTest( _, err := db.ExecContext(ctx, `INSERT INTO users (name, age, address) VALUES ('João Ribeiro', 0, '{"country":"US"}')`) tt.AssertNoErr(t, err) var joao user - getUserByName(db, driver, &joao, "João Ribeiro") + getUserByName(db, dialect, &joao, "João Ribeiro") _, err = db.ExecContext(ctx, `INSERT INTO users (name, age, address) VALUES ('Bia Ribeiro', 0, '{"country":"BR"}')`) tt.AssertNoErr(t, err) var bia user - getUserByName(db, driver, &bia, "Bia Ribeiro") + getUserByName(db, dialect, &bia, "Bia Ribeiro") _, err = db.ExecContext(ctx, fmt.Sprint(`INSERT INTO posts (user_id, title) VALUES (`, bia.ID, `, 'Bia Post1')`)) tt.AssertNoErr(t, err) @@ -332,7 +333,7 @@ func QueryTest( _, err = db.ExecContext(ctx, fmt.Sprint(`INSERT INTO posts (user_id, title) VALUES (`, joao.ID, `, 'João Post1')`)) tt.AssertNoErr(t, err) - c := newTestDB(db, driver) + c := newTestDB(db, dialect) var rows []*struct { User user `tablename:"u"` Post post `tablename:"p"` @@ -363,7 +364,7 @@ func QueryTest( } t.Run("testing error cases", func(t *testing.T) { - err := createTables(driver, connStr) + err := createTables(dialect, connStr) if err != nil { t.Fatal("could not create test table!, reason:", err.Error()) } @@ -378,7 +379,7 @@ func QueryTest( _, err = db.ExecContext(ctx, `INSERT INTO users (name, age) VALUES ('Caio Sá', 0)`) tt.AssertNoErr(t, err) - c := newTestDB(db, driver) + c := newTestDB(db, dialect) err = c.Query(ctx, &user{}, `SELECT * FROM users WHERE name like `+c.dialect.Placeholder(0), "% Sá") tt.AssertErrContains(t, err, "expected", "to be a slice", "user") @@ -397,7 +398,7 @@ func QueryTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) var users []user err := c.Query(ctx, &users, `SELECT * FROM not a valid query`) tt.AssertErrContains(t, err, "error running query") @@ -407,7 +408,7 @@ func QueryTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) // Provoque an error by sending an invalid struct: var users []struct { @@ -423,7 +424,7 @@ func QueryTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) var rows []struct { User user `tablename:"users"` Post post `tablename:"posts"` @@ -437,7 +438,7 @@ func QueryTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) var rows []struct { Foo int `tablename:"foo"` } @@ -454,7 +455,7 @@ func QueryTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) var rows []struct { Foo *user `tablename:"foo"` } @@ -472,7 +473,7 @@ func QueryTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) var rows []struct { User user `tablename:"users"` Post struct { @@ -499,7 +500,7 @@ func QueryTest( }, } - c := newTestDB(db, driver) + c := newTestDB(db, dialect) var users []user err := c.Query(ctx, &users, `SELECT * FROM users`) @@ -524,7 +525,7 @@ func QueryTest( }, } - c := newTestDB(db, driver) + c := newTestDB(db, dialect) var users []user err := c.Query(ctx, &users, `SELECT * FROM users`) @@ -549,7 +550,7 @@ func QueryTest( }, } - c := newTestDB(db, driver) + c := newTestDB(db, dialect) var users []user err := c.Query(ctx, &users, `SELECT * FROM users`) @@ -563,7 +564,7 @@ func QueryTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) var users []user err := c.Query(ctx, &users, `SELECT * FROM users`) @@ -575,10 +576,10 @@ func QueryTest( } // QueryOneTest runs all tests for making sure the QueryOne function is -// working for a given adapter and driver. +// working for a given adapter and dialect. func QueryOneTest( t *testing.T, - driver string, + dialect sqldialect.Provider, connStr string, newDBAdapter func(t *testing.T) (DBAdapter, io.Closer), ) { @@ -599,7 +600,7 @@ func QueryOneTest( }, } for _, variation := range variations { - err := createTables(driver, connStr) + err := createTables(dialect, connStr) if err != nil { t.Fatal("could not create test table!, reason:", err.Error()) } @@ -609,7 +610,7 @@ func QueryOneTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) u := user{} err := c.QueryOne(ctx, &u, variation.queryPrefix+`FROM users WHERE id=1;`) tt.AssertEqual(t, err, ErrRecordNotFound) @@ -622,7 +623,7 @@ func QueryOneTest( _, err := db.ExecContext(ctx, `INSERT INTO users (name, age, address) VALUES ('Bia', 0, '{"country":"BR"}')`) tt.AssertNoErr(t, err) - c := newTestDB(db, driver) + c := newTestDB(db, dialect) u := user{} err = c.QueryOne(ctx, &u, variation.queryPrefix+`FROM users WHERE name=`+c.dialect.Placeholder(0), "Bia") @@ -644,7 +645,7 @@ func QueryOneTest( _, err = db.ExecContext(ctx, `INSERT INTO users (name, age, address) VALUES ('Caio Sá', 0, '{"country":"BR"}')`) tt.AssertNoErr(t, err) - c := newTestDB(db, driver) + c := newTestDB(db, dialect) var u user err = c.QueryOne(ctx, &u, variation.queryPrefix+`FROM users WHERE name like `+c.dialect.Placeholder(0)+` ORDER BY id ASC`, "% Sá") @@ -668,12 +669,12 @@ func QueryOneTest( _, err := db.ExecContext(ctx, `INSERT INTO users (name, age, address) VALUES ('João Ribeiro', 0, '{"country":"US"}')`) tt.AssertNoErr(t, err) var joao user - getUserByName(db, driver, &joao, "João Ribeiro") + getUserByName(db, dialect, &joao, "João Ribeiro") _, err = db.ExecContext(ctx, fmt.Sprint(`INSERT INTO posts (user_id, title) VALUES (`, joao.ID, `, 'João Post1')`)) tt.AssertNoErr(t, err) - c := newTestDB(db, driver) + c := newTestDB(db, dialect) var row struct { User user `tablename:"u"` Post post `tablename:"p"` @@ -697,7 +698,7 @@ func QueryOneTest( _, err := db.ExecContext(ctx, `INSERT INTO users (name, age, address) VALUES ('Count Olivia', 0, '{"country":"US"}')`) tt.AssertNoErr(t, err) - c := newTestDB(db, driver) + c := newTestDB(db, dialect) var row struct { Count int `ksql:"myCount"` @@ -719,7 +720,7 @@ func QueryOneTest( _, err = db.ExecContext(ctx, `INSERT INTO users (name, age, address) VALUES ('Caio Sá', 0, '{"country":"BR"}')`) tt.AssertNoErr(t, err) - c := newTestDB(db, driver) + c := newTestDB(db, dialect) err = c.QueryOne(ctx, &[]user{}, `SELECT * FROM users WHERE name like `+c.dialect.Placeholder(0), "% Sá") tt.AssertErrContains(t, err, "pointer to struct") @@ -732,7 +733,7 @@ func QueryOneTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) var u *user err := c.QueryOne(ctx, u, `SELECT * FROM users`) tt.AssertErrContains(t, err, "expected a valid pointer", "received a nil pointer") @@ -742,7 +743,7 @@ func QueryOneTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) var u user err := c.QueryOne(ctx, &u, `SELECT * FROM not a valid query`) tt.AssertErrContains(t, err, "error running query") @@ -752,7 +753,7 @@ func QueryOneTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) var row struct { User user `tablename:"users"` Post post `tablename:"posts"` @@ -768,7 +769,7 @@ func QueryOneTest( _, err := db.ExecContext(ctx, `INSERT INTO users (name, age, address) VALUES ('Olivia', 0, '{"country":"US"}')`) tt.AssertNoErr(t, err) - c := newTestDB(db, driver) + c := newTestDB(db, dialect) var row struct { count int `ksql:"my_count"` @@ -784,7 +785,7 @@ func QueryOneTest( ctx, cancel := context.WithCancel(ctx) cancel() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) var u user err := c.QueryOne(ctx, &u, `SELECT * FROM users LIMIT 1`) @@ -794,10 +795,10 @@ func QueryOneTest( } // InsertTest runs all tests for making sure the Insert function is -// working for a given adapter and driver. +// working for a given adapter and dialect. func InsertTest( t *testing.T, - driver string, + dialect sqldialect.Provider, connStr string, newDBAdapter func(t *testing.T) (DBAdapter, io.Closer), ) { @@ -806,7 +807,7 @@ func InsertTest( t.Run("Insert", func(t *testing.T) { t.Run("success cases", func(t *testing.T) { t.Run("single primary key tables", func(t *testing.T) { - err := createTables(driver, connStr) + err := createTables(dialect, connStr) if err != nil { t.Fatal("could not create test table!, reason:", err.Error()) } @@ -815,7 +816,7 @@ func InsertTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) u := user{ Name: "Fernanda", @@ -837,7 +838,7 @@ func InsertTest( }) t.Run("should insert ignoring the ID with multiple ids", func(t *testing.T) { - if supportedDialects[driver].InsertMethod() != insertWithLastInsertID { + if dialect.InsertMethod() != sqldialect.InsertWithLastInsertID { return } @@ -847,7 +848,7 @@ func InsertTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) u := user{ Name: "No ID returned", @@ -863,7 +864,7 @@ func InsertTest( tt.AssertEqual(t, u.ID, uint(0)) result := user{} - err = getUserByName(c.db, driver, &result, "No ID returned") + err = getUserByName(c.db, dialect, &result, "No ID returned") tt.AssertNoErr(t, err) tt.AssertEqual(t, result.Age, u.Age) @@ -874,7 +875,7 @@ func InsertTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) err = c.Insert(ctx, usersTable, &struct { ID int `ksql:"id"` Name string `ksql:"name"` @@ -887,7 +888,7 @@ func InsertTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) usersByName := NewTable("users", "name") @@ -898,7 +899,7 @@ func InsertTest( tt.AssertNoErr(t, err) var inserted user - err := getUserByName(db, driver, &inserted, "Preset Name") + err := getUserByName(db, dialect, &inserted, "Preset Name") tt.AssertNoErr(t, err) tt.AssertEqual(t, inserted.Age, 5455) }) @@ -907,7 +908,7 @@ func InsertTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) type tsUser struct { ID uint `ksql:"id"` @@ -931,7 +932,7 @@ func InsertTest( }) t.Run("composite key tables", func(t *testing.T) { - err := createTables(driver, connStr) + err := createTables(dialect, connStr) if err != nil { t.Fatal("could not create test table!, reason:", err.Error()) } @@ -940,7 +941,7 @@ func InsertTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) table := NewTable("user_permissions", "id", "user_id", "perm_id") err = c.Insert(ctx, table, &userPermission{ @@ -949,7 +950,7 @@ func InsertTest( }) tt.AssertNoErr(t, err) - userPerms, err := getUserPermissionsByUser(db, driver, 1) + userPerms, err := getUserPermissionsByUser(db, dialect, 1) tt.AssertNoErr(t, err) tt.AssertEqual(t, len(userPerms), 1) tt.AssertEqual(t, userPerms[0].UserID, 1) @@ -960,7 +961,7 @@ func InsertTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) // Table defined with 3 values, but we'll provide only 2, // the third will be generated for the purposes of this test: @@ -972,18 +973,18 @@ func InsertTest( err = c.Insert(ctx, table, &permission) tt.AssertNoErr(t, err) - userPerms, err := getUserPermissionsByUser(db, driver, 2) + userPerms, err := getUserPermissionsByUser(db, dialect, 2) tt.AssertNoErr(t, err) // Should retrieve the generated ID from the database, // only if the database supports returning multiple values: switch c.dialect.InsertMethod() { - case insertWithNoIDRetrieval, insertWithLastInsertID: + case sqldialect.InsertWithNoIDRetrieval, sqldialect.InsertWithLastInsertID: tt.AssertEqual(t, permission.ID, 0) tt.AssertEqual(t, len(userPerms), 1) tt.AssertEqual(t, userPerms[0].UserID, 2) tt.AssertEqual(t, userPerms[0].PermID, 42) - case insertWithReturning, insertWithOutput: + case sqldialect.InsertWithReturning, sqldialect.InsertWithOutput: tt.AssertNotEqual(t, permission.ID, 0) tt.AssertEqual(t, len(userPerms), 1) tt.AssertEqual(t, userPerms[0].ID, permission.ID) @@ -996,7 +997,7 @@ func InsertTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) // Table defined with 3 values, but we'll provide only 2, // the third will be generated for the purposes of this test: @@ -1028,11 +1029,11 @@ func InsertTest( // Should retrieve the generated ID from the database, // only if the database supports returning multiple values: switch c.dialect.InsertMethod() { - case insertWithNoIDRetrieval, insertWithLastInsertID: + case sqldialect.InsertWithNoIDRetrieval, sqldialect.InsertWithLastInsertID: tt.AssertEqual(t, permission.ID, uint(0)) tt.AssertEqual(t, untaggedPerm.UserID, 3) tt.AssertEqual(t, untaggedPerm.PermID, 43) - case insertWithReturning, insertWithOutput: + case sqldialect.InsertWithReturning, sqldialect.InsertWithOutput: tt.AssertEqual(t, untaggedPerm.ID, permission.ID) tt.AssertEqual(t, untaggedPerm.UserID, 3) tt.AssertEqual(t, untaggedPerm.PermID, 43) @@ -1042,7 +1043,7 @@ func InsertTest( }) t.Run("testing error cases", func(t *testing.T) { - err := createTables(driver, connStr) + err := createTables(dialect, connStr) if err != nil { t.Fatal("could not create test table!, reason:", err.Error()) } @@ -1051,7 +1052,7 @@ func InsertTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) err = c.Insert(ctx, usersTable, "foo") tt.AssertNotEqual(t, err, nil) @@ -1077,11 +1078,11 @@ func InsertTest( tt.AssertNotEqual(t, err, nil) }) - t.Run("should report error if for some reason the insertMethod is invalid", func(t *testing.T) { + t.Run("should report error if for some reason the InsertMethod is invalid", func(t *testing.T) { db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) // This is an invalid value: c.dialect = brokenDialect{} @@ -1094,7 +1095,7 @@ func InsertTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) var u *user err := c.Insert(ctx, usersTable, u) @@ -1105,7 +1106,7 @@ func InsertTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) err := c.Insert(ctx, NewTable("users", ""), &user{Name: "fake-name"}) tt.AssertErrContains(t, err, "ksql.Table", "ID", "empty string") @@ -1115,7 +1116,7 @@ func InsertTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) err := c.Insert(ctx, NewTable("", "id"), &user{Name: "fake-name"}) tt.AssertErrContains(t, err, "ksql.Table", "table name", "empty string") @@ -1125,7 +1126,7 @@ func InsertTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) err = c.Insert(ctx, usersTable, &struct { ID string `ksql:"id"` @@ -1140,7 +1141,7 @@ func InsertTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) brokenTable := NewTable("users", "non_existing_id") @@ -1155,7 +1156,7 @@ func InsertTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) err = c.Insert(ctx, usersTable, &struct { Age int `ksql:"age"` @@ -1164,7 +1165,7 @@ func InsertTest( tt.AssertNoErr(t, err) var u user - err = getUserByName(db, driver, &u, "Inserted With no ID") + err = getUserByName(db, dialect, &u, "Inserted With no ID") tt.AssertNoErr(t, err) tt.AssertNotEqual(t, u.ID, uint(0)) tt.AssertEqual(t, u.Age, 42) @@ -1177,7 +1178,7 @@ func InsertTest( ctx, cancel := context.WithCancel(ctx) cancel() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) err = c.Insert(ctx, usersTable, &user{Age: 42, Name: "FakeUserName"}) @@ -1189,8 +1190,8 @@ func InsertTest( type brokenDialect struct{} -func (brokenDialect) InsertMethod() insertMethod { - return insertMethod(42) +func (brokenDialect) InsertMethod() sqldialect.InsertMethod { + return sqldialect.InsertMethod(42) } func (brokenDialect) Escape(str string) string { @@ -1206,17 +1207,17 @@ func (brokenDialect) DriverName() string { } // DeleteTest runs all tests for making sure the Delete function is -// working for a given adapter and driver. +// working for a given adapter and dialect. func DeleteTest( t *testing.T, - driver string, + dialect sqldialect.Provider, connStr string, newDBAdapter func(t *testing.T) (DBAdapter, io.Closer), ) { ctx := context.Background() t.Run("Delete", func(t *testing.T) { - err := createTables(driver, connStr) + err := createTables(dialect, connStr) if err != nil { t.Fatal("could not create test table!, reason:", err.Error()) } @@ -1251,7 +1252,7 @@ func DeleteTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) u1 := user{ Name: "Fernanda", @@ -1301,7 +1302,7 @@ func DeleteTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) // This permission should not be deleted, we'll use the id to check it: p0 := userPermission{ @@ -1325,7 +1326,7 @@ func DeleteTest( err = c.Delete(ctx, userPermissionsTable, p1) tt.AssertNoErr(t, err) - userPerms, err := getUserPermissionsByUser(db, driver, 1) + userPerms, err := getUserPermissionsByUser(db, dialect, 1) tt.AssertNoErr(t, err) tt.AssertEqual(t, len(userPerms), 1) tt.AssertEqual(t, userPerms[0].UserID, 1) @@ -1336,7 +1337,7 @@ func DeleteTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) // This permission should not be deleted, we'll use the id to check it: p0 := userPermission{ @@ -1363,7 +1364,7 @@ func DeleteTest( }) tt.AssertNoErr(t, err) - userPerms, err := getUserPermissionsByUser(db, driver, 2) + userPerms, err := getUserPermissionsByUser(db, dialect, 2) tt.AssertNoErr(t, err) tt.AssertEqual(t, len(userPerms), 1) tt.AssertEqual(t, userPerms[0].UserID, 2) @@ -1375,7 +1376,7 @@ func DeleteTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) err = c.Delete(ctx, usersTable, 4200) tt.AssertEqual(t, err, ErrRecordNotFound) @@ -1385,7 +1386,7 @@ func DeleteTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) var u *user err := c.Delete(ctx, usersTable, u) @@ -1398,7 +1399,7 @@ func DeleteTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) err := c.Delete(ctx, NewTable("users", "id"), &struct { // Missing ID @@ -1411,7 +1412,7 @@ func DeleteTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) err := c.Delete(ctx, NewTable("users", "id"), &struct { // Null ID @@ -1425,7 +1426,7 @@ func DeleteTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) err := c.Delete(ctx, NewTable("users", "id"), &struct { // Uninitialized ID @@ -1441,7 +1442,7 @@ func DeleteTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) err := c.Delete(ctx, userPermissionsTable, &struct { // Missing PermID @@ -1458,7 +1459,7 @@ func DeleteTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) err := c.Delete(ctx, userPermissionsTable, map[string]interface{}{ // Missing PermID @@ -1472,7 +1473,7 @@ func DeleteTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) err := c.Delete(ctx, userPermissionsTable, &struct { UserID int `ksql:"user_id"` @@ -1491,7 +1492,7 @@ func DeleteTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) err := c.Delete(ctx, userPermissionsTable, map[string]interface{}{ // Null Perm ID @@ -1506,7 +1507,7 @@ func DeleteTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) err := c.Delete(ctx, userPermissionsTable, &struct { UserID int `ksql:"user_id"` @@ -1525,7 +1526,7 @@ func DeleteTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) err := c.Delete(ctx, userPermissionsTable, map[string]interface{}{ // Zero Perm ID @@ -1542,7 +1543,7 @@ func DeleteTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) err := c.Delete(ctx, NewTable("users", ""), &user{ID: 42, Name: "fake-name"}) tt.AssertErrContains(t, err, "ksql.Table", "ID", "empty string") @@ -1552,7 +1553,7 @@ func DeleteTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) err := c.Delete(ctx, NewTable("", "id"), &user{Name: "fake-name"}) tt.AssertErrContains(t, err, "ksql.Table", "table name", "empty string") @@ -1565,7 +1566,7 @@ func DeleteTest( ctx, cancel := context.WithCancel(ctx) cancel() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) err := c.Delete(ctx, usersTable, &user{ID: 42, Name: "fake-name"}) tt.AssertEqual(t, errors.Is(err, context.Canceled), true) @@ -1574,17 +1575,17 @@ func DeleteTest( } // PatchTest runs all tests for making sure the Patch function is -// working for a given adapter and driver. +// working for a given adapter and dialect. func PatchTest( t *testing.T, - driver string, + dialect sqldialect.Provider, connStr string, newDBAdapter func(t *testing.T) (DBAdapter, io.Closer), ) { ctx := context.Background() t.Run("Patch", func(t *testing.T) { - err := createTables(driver, connStr) + err := createTables(dialect, connStr) if err != nil { t.Fatal("could not create test table!, reason:", err.Error()) } @@ -1593,7 +1594,7 @@ func PatchTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) u := user{ Name: "Letícia", @@ -1601,7 +1602,7 @@ func PatchTest( _, err := db.ExecContext(ctx, `INSERT INTO users (name, age) VALUES ('Letícia', 0)`) tt.AssertNoErr(t, err) - err = getUserByName(db, driver, &u, "Letícia") + err = getUserByName(db, dialect, &u, "Letícia") tt.AssertNoErr(t, err) tt.AssertNotEqual(t, u.ID, uint(0)) @@ -1621,7 +1622,7 @@ func PatchTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) u := user{ Name: "Letícia", @@ -1629,7 +1630,7 @@ func PatchTest( _, err := db.ExecContext(ctx, `INSERT INTO users (name, age) VALUES ('Letícia', 0)`) tt.AssertNoErr(t, err) - err = getUserByName(db, driver, &u, "Letícia") + err = getUserByName(db, dialect, &u, "Letícia") tt.AssertNoErr(t, err) tt.AssertNotEqual(t, u.ID, uint(0)) @@ -1649,7 +1650,7 @@ func PatchTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) err = createUserPermission(db, c.dialect, userPermission{ UserID: 42, @@ -1685,7 +1686,7 @@ func PatchTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) type partialUser struct { ID uint `ksql:"id"` @@ -1697,7 +1698,7 @@ func PatchTest( tt.AssertNoErr(t, err) var u user - err = getUserByName(db, driver, &u, "Letícia") + err = getUserByName(db, dialect, &u, "Letícia") tt.AssertNoErr(t, err) tt.AssertNotEqual(t, u.ID, uint(0)) @@ -1721,7 +1722,7 @@ func PatchTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) type partialUser struct { ID uint `ksql:"id"` @@ -1733,7 +1734,7 @@ func PatchTest( tt.AssertNoErr(t, err) var u user - err = getUserByName(db, driver, &u, "Letícia") + err = getUserByName(db, dialect, &u, "Letícia") tt.AssertNoErr(t, err) tt.AssertNotEqual(t, u.ID, uint(0)) @@ -1757,7 +1758,7 @@ func PatchTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) err = c.Update(ctx, usersTable, user{ ID: 4200, @@ -1770,7 +1771,7 @@ func PatchTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) err = c.Update(ctx, NewTable("non_existing_table"), user{ ID: 1, @@ -1783,7 +1784,7 @@ func PatchTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) var u *user err := c.Update(ctx, usersTable, u) @@ -1794,7 +1795,7 @@ func PatchTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) err = c.Update(ctx, usersTable, struct { ID uint `ksql:"id"` // ID fields are not updated @@ -1812,7 +1813,7 @@ func PatchTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) err := c.Update(ctx, usersTable, &user{ // Missing ID @@ -1825,7 +1826,7 @@ func PatchTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) err := c.Update(ctx, NewTable("user_permissions", "id", "user_id", "perm_id"), &userPermission{ ID: 1, @@ -1843,7 +1844,7 @@ func PatchTest( ctx, cancel := context.WithCancel(ctx) cancel() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) err = c.Update(ctx, usersTable, user{ ID: 1, @@ -1855,10 +1856,10 @@ func PatchTest( } // QueryChunksTest runs all tests for making sure the QueryChunks function is -// working for a given adapter and driver. +// working for a given adapter and dialect. func QueryChunksTest( t *testing.T, - driver string, + dialect sqldialect.Provider, connStr string, newDBAdapter func(t *testing.T) (DBAdapter, io.Closer), ) { @@ -1881,7 +1882,7 @@ func QueryChunksTest( for _, variation := range variations { t.Run(variation.desc, func(t *testing.T) { t.Run("should query a single row correctly", func(t *testing.T) { - err := createTables(driver, connStr) + err := createTables(dialect, connStr) if err != nil { t.Fatal("could not create test table!, reason:", err.Error()) } @@ -1889,7 +1890,7 @@ func QueryChunksTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) _ = c.Insert(ctx, usersTable, &user{ Name: "User1", @@ -1920,7 +1921,7 @@ func QueryChunksTest( }) t.Run("should query one chunk correctly", func(t *testing.T) { - err := createTables(driver, connStr) + err := createTables(dialect, connStr) if err != nil { t.Fatal("could not create test table!, reason:", err.Error()) } @@ -1928,7 +1929,7 @@ func QueryChunksTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) _ = c.Insert(ctx, usersTable, &user{Name: "User1", Address: address{Country: "US"}}) _ = c.Insert(ctx, usersTable, &user{Name: "User2", Address: address{Country: "BR"}}) @@ -1961,7 +1962,7 @@ func QueryChunksTest( }) t.Run("should query chunks of 1 correctly", func(t *testing.T) { - err := createTables(driver, connStr) + err := createTables(dialect, connStr) if err != nil { t.Fatal("could not create test table!, reason:", err.Error()) } @@ -1969,7 +1970,7 @@ func QueryChunksTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) _ = c.Insert(ctx, usersTable, &user{Name: "User1", Address: address{Country: "US"}}) _ = c.Insert(ctx, usersTable, &user{Name: "User2", Address: address{Country: "BR"}}) @@ -2002,7 +2003,7 @@ func QueryChunksTest( }) t.Run("should load partially filled chunks correctly", func(t *testing.T) { - err := createTables(driver, connStr) + err := createTables(dialect, connStr) if err != nil { t.Fatal("could not create test table!, reason:", err.Error()) } @@ -2010,7 +2011,7 @@ func QueryChunksTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) _ = c.Insert(ctx, usersTable, &user{Name: "User1"}) _ = c.Insert(ctx, usersTable, &user{Name: "User2"}) @@ -2060,7 +2061,7 @@ func QueryChunksTest( Age: 20, } - c := newTestDB(db, driver) + c := newTestDB(db, dialect) _ = c.Insert(ctx, usersTable, &joao) _ = c.Insert(ctx, usersTable, &thatiana) @@ -2113,7 +2114,7 @@ func QueryChunksTest( }) t.Run("should abort the first iteration when the callback returns an ErrAbortIteration", func(t *testing.T) { - err := createTables(driver, connStr) + err := createTables(dialect, connStr) if err != nil { t.Fatal("could not create test table!, reason:", err.Error()) } @@ -2121,7 +2122,7 @@ func QueryChunksTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) _ = c.Insert(ctx, usersTable, &user{Name: "User1"}) _ = c.Insert(ctx, usersTable, &user{Name: "User2"}) @@ -2151,7 +2152,7 @@ func QueryChunksTest( }) t.Run("should abort the last iteration when the callback returns an ErrAbortIteration", func(t *testing.T) { - err := createTables(driver, connStr) + err := createTables(dialect, connStr) if err != nil { t.Fatal("could not create test table!, reason:", err.Error()) } @@ -2159,7 +2160,7 @@ func QueryChunksTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) _ = c.Insert(ctx, usersTable, &user{Name: "User1"}) _ = c.Insert(ctx, usersTable, &user{Name: "User2"}) @@ -2193,7 +2194,7 @@ func QueryChunksTest( }) t.Run("should return error if the callback returns an error in the first iteration", func(t *testing.T) { - err := createTables(driver, connStr) + err := createTables(dialect, connStr) if err != nil { t.Fatal("could not create test table!, reason:", err.Error()) } @@ -2201,7 +2202,7 @@ func QueryChunksTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) _ = c.Insert(ctx, usersTable, &user{Name: "User1"}) _ = c.Insert(ctx, usersTable, &user{Name: "User2"}) @@ -2231,7 +2232,7 @@ func QueryChunksTest( }) t.Run("should return error if the callback returns an error in the last iteration", func(t *testing.T) { - err := createTables(driver, connStr) + err := createTables(dialect, connStr) if err != nil { t.Fatal("could not create test table!, reason:", err.Error()) } @@ -2239,7 +2240,7 @@ func QueryChunksTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) _ = c.Insert(ctx, usersTable, &user{Name: "User1"}) _ = c.Insert(ctx, usersTable, &user{Name: "User2"}) @@ -2276,7 +2277,7 @@ func QueryChunksTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) funcs := []interface{}{ nil, @@ -2319,7 +2320,7 @@ func QueryChunksTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) err := c.QueryChunks(ctx, ChunkParser{ Query: `SELECT * FROM not a valid query`, Params: []interface{}{}, @@ -2336,7 +2337,7 @@ func QueryChunksTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) err := c.QueryChunks(ctx, ChunkParser{ Query: `SELECT * FROM users u JOIN posts p ON u.id = p.user_id`, @@ -2364,7 +2365,7 @@ func QueryChunksTest( ctx, cancel := context.WithCancel(ctx) cancel() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) err := c.QueryChunks(ctx, ChunkParser{ Query: `SELECT * FROM users u JOIN posts p ON u.id = p.user_id`, @@ -2382,10 +2383,10 @@ func QueryChunksTest( } // TransactionTest runs all tests for making sure the Transaction function is -// working for a given adapter and driver. +// working for a given adapter and dialect. func TransactionTest( t *testing.T, - driver string, + dialect sqldialect.Provider, connStr string, newDBAdapter func(t *testing.T) (DBAdapter, io.Closer), ) { @@ -2393,7 +2394,7 @@ func TransactionTest( t.Run("Transaction", func(t *testing.T) { t.Run("should query a single row correctly", func(t *testing.T) { - err := createTables(driver, connStr) + err := createTables(dialect, connStr) if err != nil { t.Fatal("could not create test table!, reason:", err.Error()) } @@ -2401,7 +2402,7 @@ func TransactionTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) _ = c.Insert(ctx, usersTable, &user{Name: "User1"}) _ = c.Insert(ctx, usersTable, &user{Name: "User2"}) @@ -2419,7 +2420,7 @@ func TransactionTest( }) t.Run("should work normally in nested transactions", func(t *testing.T) { - err := createTables(driver, connStr) + err := createTables(dialect, connStr) if err != nil { t.Fatal("could not create test table!, reason:", err.Error()) } @@ -2427,7 +2428,7 @@ func TransactionTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) u := user{ Name: "User1", @@ -2455,7 +2456,7 @@ func TransactionTest( }) t.Run("should rollback when there are errors", func(t *testing.T) { - err := createTables(driver, connStr) + err := createTables(dialect, connStr) if err != nil { t.Fatal("could not create test table!, reason:", err.Error()) } @@ -2463,7 +2464,7 @@ func TransactionTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) u1 := user{Name: "User1", Age: 42} u2 := user{Name: "User2", Age: 42} @@ -2491,7 +2492,7 @@ func TransactionTest( }) t.Run("should rollback when the fn call panics", func(t *testing.T) { - err := createTables(driver, connStr) + err := createTables(dialect, connStr) if err != nil { t.Fatal("could not create test table!, reason:", err.Error()) } @@ -2499,7 +2500,7 @@ func TransactionTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) u1 := user{Name: "User1", Age: 42} u2 := user{Name: "User2", Age: 42} @@ -2528,7 +2529,7 @@ func TransactionTest( }) t.Run("should handle rollback errors when the fn call panics", func(t *testing.T) { - err := createTables(driver, connStr) + err := createTables(dialect, connStr) if err != nil { t.Fatal("could not create test table!, reason:", err.Error()) } @@ -2536,7 +2537,7 @@ func TransactionTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) cMock := mockTxBeginner{ DBAdapter: c.db, @@ -2562,7 +2563,7 @@ func TransactionTest( }) t.Run("should handle rollback errors when fn returns an error", func(t *testing.T) { - err := createTables(driver, connStr) + err := createTables(dialect, connStr) if err != nil { t.Fatal("could not create test table!, reason:", err.Error()) } @@ -2570,7 +2571,7 @@ func TransactionTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) cMock := mockTxBeginner{ DBAdapter: c.db, @@ -2595,7 +2596,7 @@ func TransactionTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) cMock := mockTxBeginner{ DBAdapter: c.db, @@ -2612,7 +2613,7 @@ func TransactionTest( }) t.Run("should report error if DBAdapter can't create transactions", func(t *testing.T) { - err := createTables(driver, connStr) + err := createTables(dialect, connStr) if err != nil { t.Fatal("could not create test table!, reason:", err.Error()) } @@ -2620,7 +2621,7 @@ func TransactionTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) c.db = mockDBAdapter{} @@ -2637,7 +2638,7 @@ func TransactionTest( ctx, cancel := context.WithCancel(ctx) cancel() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) err := c.Transaction(ctx, func(db Provider) error { return nil @@ -2649,14 +2650,14 @@ func TransactionTest( func ModifiersTest( t *testing.T, - driver string, + dialect sqldialect.Provider, connStr string, newDBAdapter func(t *testing.T) (DBAdapter, io.Closer), ) { ctx := context.Background() t.Run("Modifiers", func(t *testing.T) { - err := createTables(driver, connStr) + err := createTables(dialect, connStr) if err != nil { t.Fatal("could not create test table!, reason:", err.Error()) } @@ -2666,7 +2667,7 @@ func ModifiersTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) type tsUser struct { ID uint `ksql:"id"` @@ -2699,7 +2700,7 @@ func ModifiersTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) type userWithNoTags struct { ID uint `ksql:"id"` @@ -2743,7 +2744,7 @@ func ModifiersTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) type userWithNoTags struct { ID uint `ksql:"id"` @@ -2777,7 +2778,7 @@ func ModifiersTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) type tsUser struct { ID uint `ksql:"id"` @@ -2810,7 +2811,7 @@ func ModifiersTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) type userWithNoTags struct { ID uint `ksql:"id"` @@ -2850,7 +2851,7 @@ func ModifiersTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) type userWithNoTags struct { ID uint `ksql:"id"` @@ -2884,7 +2885,7 @@ func ModifiersTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) type tsUser struct { ID uint `ksql:"id"` @@ -2914,7 +2915,7 @@ func ModifiersTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) type userWithNoTags struct { ID uint `ksql:"id"` @@ -2953,7 +2954,7 @@ func ModifiersTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) type userWithNoTags struct { ID uint `ksql:"id"` @@ -2982,7 +2983,7 @@ func ModifiersTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) type tsUser struct { ID uint `ksql:"id"` @@ -3008,7 +3009,7 @@ func ModifiersTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) type userWithNoTags struct { ID uint `ksql:"id"` @@ -3047,7 +3048,7 @@ func ModifiersTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) type userWithNoTags struct { ID uint `ksql:"id"` @@ -3076,7 +3077,7 @@ func ModifiersTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) // The default value of the column "nullable_field" // is the string: "not_null". @@ -3118,7 +3119,7 @@ func ModifiersTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) type userWithNoTags struct { ID uint `ksql:"id"` @@ -3157,7 +3158,7 @@ func ModifiersTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) type userWithNoTags struct { ID uint `ksql:"id"` @@ -3184,7 +3185,7 @@ func ModifiersTest( db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) type user struct { ID uint `ksql:"id"` @@ -3219,10 +3220,10 @@ func ModifiersTest( } // ScanRowsTest runs all tests for making sure the ScanRows feature is -// working for a given adapter and driver. +// working for a given adapter and dialect. func ScanRowsTest( t *testing.T, - driver string, + dialect sqldialect.Provider, connStr string, newDBAdapter func(t *testing.T) (DBAdapter, io.Closer), ) { @@ -3230,15 +3231,14 @@ func ScanRowsTest( t.Run("ScanRows", func(t *testing.T) { t.Run("should scan users correctly", func(t *testing.T) { - err := createTables(driver, connStr) + err := createTables(dialect, connStr) if err != nil { t.Fatal("could not create test table!, reason:", err.Error()) } - dialect := supportedDialects[driver] db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) _ = c.Insert(ctx, usersTable, &user{Name: "User1", Age: 22}) _ = c.Insert(ctx, usersTable, &user{Name: "User2", Age: 14}) _ = c.Insert(ctx, usersTable, &user{Name: "User3", Age: 43}) @@ -3258,13 +3258,12 @@ func ScanRowsTest( }) t.Run("should ignore extra columns from query", func(t *testing.T) { - err := createTables(driver, connStr) + err := createTables(dialect, connStr) tt.AssertNoErr(t, err) - dialect := supportedDialects[driver] db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) _ = c.Insert(ctx, usersTable, &user{Name: "User1", Age: 22}) rows, err := db.QueryContext(ctx, "SELECT * FROM users WHERE name='User1'") @@ -3355,13 +3354,12 @@ func ScanRowsTest( for _, test := range tests { t.Run(test.desc, func(t *testing.T) { - err := createTables(driver, connStr) + err := createTables(dialect, connStr) tt.AssertNoErr(t, err) - dialect := supportedDialects[driver] db, closer := newDBAdapter(t) defer closer.Close() - c := newTestDB(db, driver) + c := newTestDB(db, dialect) u := user{Name: "User22", Age: 22} _ = c.Insert(ctx, usersTable, &u) @@ -3382,12 +3380,11 @@ func ScanRowsTest( }) t.Run("should report error for closed rows", func(t *testing.T) { - err := createTables(driver, connStr) + err := createTables(dialect, connStr) if err != nil { t.Fatal("could not create test table!, reason:", err.Error()) } - dialect := supportedDialects[driver] db, closer := newDBAdapter(t) defer closer.Close() @@ -3402,12 +3399,11 @@ func ScanRowsTest( }) t.Run("should report if record is not a pointer", func(t *testing.T) { - err := createTables(driver, connStr) + err := createTables(dialect, connStr) if err != nil { t.Fatal("could not create test table!, reason:", err.Error()) } - dialect := supportedDialects[driver] db, closer := newDBAdapter(t) defer closer.Close() @@ -3421,12 +3417,11 @@ func ScanRowsTest( }) t.Run("should report if record is not a pointer to struct", func(t *testing.T) { - err := createTables(driver, connStr) + err := createTables(dialect, connStr) if err != nil { t.Fatal("could not create test table!, reason:", err.Error()) } - dialect := supportedDialects[driver] db, closer := newDBAdapter(t) defer closer.Close() @@ -3441,9 +3436,11 @@ func ScanRowsTest( }) } -func createTables(driver string, connStr string) error { +func createTables(dialect sqldialect.Provider, connStr string) error { + driver := dialect.DriverName() + if connStr == "" { - return fmt.Errorf("unsupported driver: '%s'", driver) + return fmt.Errorf("unsupported dialect: '%s'", dialect) } db, err := sql.Open(driver, connStr) @@ -3575,9 +3572,9 @@ func createTables(driver string, connStr string) error { return nil } -func newTestDB(db DBAdapter, driver string) DB { +func newTestDB(db DBAdapter, dialect sqldialect.Provider) DB { return DB{ - dialect: supportedDialects[driver], + dialect: dialect, db: db, } } @@ -3588,7 +3585,7 @@ func shiftErrSlice(errs *[]error) error { return err } -func getUserByID(db DBAdapter, dialect Dialect, result *user, id uint) error { +func getUserByID(db DBAdapter, dialect sqldialect.Provider, result *user, id uint) error { rows, err := db.QueryContext(context.TODO(), `SELECT id, name, age, address FROM users WHERE id=`+dialect.Placeholder(0), id) if err != nil { return err @@ -3624,9 +3621,7 @@ func getUserByID(db DBAdapter, dialect Dialect, result *user, id uint) error { return nil } -func getUserByName(db DBAdapter, driver string, result *user, name string) error { - dialect := supportedDialects[driver] - +func getUserByName(db DBAdapter, dialect sqldialect.Provider, result *user, name string) error { rows, err := db.QueryContext(context.TODO(), `SELECT id, name, age, address FROM users WHERE name=`+dialect.Placeholder(0), name) if err != nil { return err @@ -3653,7 +3648,7 @@ func getUserByName(db DBAdapter, driver string, result *user, name string) error return json.Unmarshal(rawAddr, &result.Address) } -func createUserPermission(db DBAdapter, dialect Dialect, userPerm userPermission) error { +func createUserPermission(db DBAdapter, dialect sqldialect.Provider, userPerm userPermission) error { _, err := db.ExecContext(context.TODO(), `INSERT INTO user_permissions (user_id, perm_id, type) VALUES (`+dialect.Placeholder(0)+`, `+dialect.Placeholder(1)+`, `+dialect.Placeholder(2)+`)`, @@ -3663,7 +3658,7 @@ func createUserPermission(db DBAdapter, dialect Dialect, userPerm userPermission return err } -func getUserPermissionBySecondaryKeys(db DBAdapter, dialect Dialect, userID int, permID int) (userPermission, error) { +func getUserPermissionBySecondaryKeys(db DBAdapter, dialect sqldialect.Provider, userID int, permID int) (userPermission, error) { rows, err := db.QueryContext(context.TODO(), `SELECT id, user_id, perm_id, type FROM user_permissions WHERE user_id=`+dialect.Placeholder(0)+` AND perm_id=`+dialect.Placeholder(1), userID, permID, @@ -3689,9 +3684,7 @@ func getUserPermissionBySecondaryKeys(db DBAdapter, dialect Dialect, userID int, return result, nil } -func getUserPermissionsByUser(db DBAdapter, driver string, userID int) (results []userPermission, _ error) { - dialect := supportedDialects[driver] - +func getUserPermissionsByUser(db DBAdapter, dialect sqldialect.Provider, userID int) (results []userPermission, _ error) { rows, err := db.QueryContext(context.TODO(), `SELECT id, user_id, perm_id FROM user_permissions WHERE user_id=`+dialect.Placeholder(0), userID, @@ -3717,7 +3710,7 @@ func getUserPermissionsByUser(db DBAdapter, driver string, userID int) (results } func mustBuildSelectQuery(t *testing.T, - dialect Dialect, + dialect sqldialect.Provider, record interface{}, query string, ) string { From ddd9a4dec50aa71319be216ac301a042bc25e819 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Garcia?= Date: Wed, 21 Dec 2022 21:25:25 -0300 Subject: [PATCH 3/4] Remove completed task from README TODO list --- README.md | 1 - readme.template.md | 1 - 2 files changed, 2 deletions(-) diff --git a/README.md b/README.md index 0173252..1a6401c 100644 --- a/README.md +++ b/README.md @@ -460,7 +460,6 @@ is configured to kill the containers after 20 seconds. ## TODO List - Update `ksqltest.FillStructWith` to work with `ksql:"..,json"` tagged attributes -- Create a way for users to submit user defined dialects - Improve error messages (ongoing) ## Optimization Oportunities diff --git a/readme.template.md b/readme.template.md index 1ddd83d..247a8c3 100644 --- a/readme.template.md +++ b/readme.template.md @@ -227,7 +227,6 @@ is configured to kill the containers after 20 seconds. ## TODO List - Update `ksqltest.FillStructWith` to work with `ksql:"..,json"` tagged attributes -- Create a way for users to submit user defined dialects - Improve error messages (ongoing) ## Optimization Oportunities From f183327eec724616c80fe23de426feeb9d9fc571 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Garcia?= Date: Wed, 21 Dec 2022 22:15:30 -0300 Subject: [PATCH 4/4] Fix minor mistake on tests --- test_adapters.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_adapters.go b/test_adapters.go index 1033dfe..bc6f5a5 100644 --- a/test_adapters.go +++ b/test_adapters.go @@ -3440,7 +3440,7 @@ func createTables(dialect sqldialect.Provider, connStr string) error { driver := dialect.DriverName() if connStr == "" { - return fmt.Errorf("unsupported dialect: '%s'", dialect) + return fmt.Errorf("unsupported dialect: '%s'", driver) } db, err := sql.Open(driver, connStr)