diff --git a/Makefile b/Makefile index fcd3320..8a87ac5 100644 --- a/Makefile +++ b/Makefile @@ -18,6 +18,7 @@ test_all: test_postgres test_mysql test_mssql .PHONY: test_postgres test_postgres: @TYPE=postgres go test -cover -coverprofile postgres.out -coverpkg ./... ./internal/tests -v + @TYPE=postgresX go test -cover -coverprofile postgresX.out -coverpkg ./... ./internal/tests -v .PHONY: test_mysql test_mysql: diff --git a/delete.go b/delete.go index f9a1d2b..97a0bbc 100644 --- a/delete.go +++ b/delete.go @@ -1,10 +1,5 @@ package qb -import ( - "reflect" - "strings" -) - // DeleteBuilder builds a DELETE query type DeleteBuilder struct { table *Table @@ -15,8 +10,8 @@ type DeleteBuilder struct { // func (q DeleteBuilder) SQL(b SQLBuilder) (string, []interface{}) { - drvPath := reflect.TypeOf(b.Context.Driver).PkgPath() - if strings.HasSuffix(drvPath, `myqb`) || strings.HasSuffix(drvPath, `msqb`) { + dbtype := b.Context.Driver.DBType() + if dbtype == DriverMysql || dbtype == DriverMssql { b.w.WriteLine(`DELETE ` + q.table.aliasString()) b.w.WriteLine(`FROM ` + b.SourceToSQL(q.table)) } else { diff --git a/driver/autoqb/main.go b/driver/autoqb/main.go index a60c346..c2d35e7 100644 --- a/driver/autoqb/main.go +++ b/driver/autoqb/main.go @@ -2,34 +2,62 @@ package autoqb // import "git.ultraware.nl/Ultraware/qb/v2/driver/autoqb" import ( "database/sql" - "reflect" - "strings" "git.ultraware.nl/Ultraware/qb/v2/driver/msqb" "git.ultraware.nl/Ultraware/qb/v2/driver/myqb" "git.ultraware.nl/Ultraware/qb/v2/driver/pgqb" "git.ultraware.nl/Ultraware/qb/v2/qbdb" + denisenkom "github.com/denisenkom/go-mssqldb" // database driver for Microsoft MSSQL + "github.com/go-sql-driver/mysql" // database driver for MySQL + "github.com/jackc/pgx/stdlib" // database driver for PostgreSQL + "github.com/lib/pq" // database driver for PostgreSQL + mssqldb "github.com/microsoft/go-mssqldb" // database driver for Microsoft MSSQL + "github.com/ziutek/mymysql/godrv" // database driver for MySQL ) // New automatically selects a qb driver func New(db *sql.DB) qbdb.DB { - switch getPkgName(db) { - case `github.com/lib/pq`, `github.com/jackc/pgx/stdlib`: + switch { + case IsPostgres(db): return pgqb.New(db) - case `github.com/go-sql-driver/mysql`, `github.com/ziutek/mymysql/godrv`: + case IsMysql(db): return myqb.New(db) - case `github.com/denisenkom/go-mssqldb`, `github.com/microsoft/go-mssqldb`: + case IsMssql(db): return msqb.New(db) } panic(`Unknown database driver`) } -func getPkgName(db *sql.DB) string { - t := reflect.TypeOf(db.Driver()) - if t.Kind() == reflect.Ptr { - t = t.Elem() +func IsPostgres(db *sql.DB) bool { + driver := db.Driver() + + if _, ok := driver.(*stdlib.Driver); ok { + return true + + } + + _, ok := driver.(*pq.Driver) + return ok +} + +func IsMysql(db *sql.DB) bool { + driver := db.Driver() + + if _, ok := driver.(*mysql.MySQLDriver); ok { + return true } - path := t.PkgPath() - parts := strings.Split(path, `/vendor/`) - return parts[len(parts)-1] + + _, ok := driver.(*godrv.Driver) + return ok +} + +func IsMssql(db *sql.DB) bool { + driver := db.Driver() + + if _, ok := driver.(*mssqldb.Driver); ok { + return true + } + + _, ok := driver.(*denisenkom.Driver) + return ok } diff --git a/driver/msqb/main.go b/driver/msqb/main.go index 8dfb0d4..54909e5 100644 --- a/driver/msqb/main.go +++ b/driver/msqb/main.go @@ -19,6 +19,10 @@ func New(db *sql.DB) qbdb.DB { return qbdb.New(Driver{}, db) } +func (d Driver) DBType() qb.DBType { + return qb.DriverMssql +} + // ValueString returns a the SQL for a parameter value func (d Driver) ValueString(i int) string { return `@p` + strconv.Itoa(i) diff --git a/driver/myqb/main.go b/driver/myqb/main.go index d8ff941..cad65ec 100644 --- a/driver/myqb/main.go +++ b/driver/myqb/main.go @@ -20,6 +20,10 @@ func New(db *sql.DB) qbdb.DB { return qbdb.New(Driver{}, db) } +func (d Driver) DBType() qb.DBType { + return qb.DriverMysql +} + // ValueString returns a the SQL for a parameter value func (d Driver) ValueString(_ int) string { return `?` diff --git a/driver/pgqb/main.go b/driver/pgqb/main.go index a00c689..2ea048f 100644 --- a/driver/pgqb/main.go +++ b/driver/pgqb/main.go @@ -21,6 +21,10 @@ func New(db *sql.DB) qbdb.DB { return qbdb.New(Driver{}, db) } +func (d Driver) DBType() qb.DBType { + return qb.DriverPostgres +} + // ValueString returns a the SQL for a parameter value func (d Driver) ValueString(c int) string { return `$` + strconv.Itoa(c) diff --git a/go.mod b/go.mod index da7be89..04934de 100644 --- a/go.mod +++ b/go.mod @@ -4,17 +4,30 @@ go 1.23.0 require ( git.fuyu.moe/Fuyu/assert v0.2.1 + github.com/denisenkom/go-mssqldb v0.12.3 github.com/go-sql-driver/mysql v1.9.3 + github.com/jackc/pgx v3.6.2+incompatible + github.com/jackc/pgx/v5 v5.7.5 github.com/lib/pq v1.10.9 github.com/microsoft/go-mssqldb v1.8.2 + github.com/ziutek/mymysql v1.5.4 ) require ( filippo.io/edwards25519 v1.1.0 // indirect + github.com/cockroachdb/apd v1.1.0 // indirect + github.com/gofrs/uuid v4.4.0+incompatible // indirect github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect github.com/golang-sql/sqlexp v0.1.0 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/uuid v1.6.0 // indirect - golang.org/x/crypto v0.36.0 // indirect - golang.org/x/text v0.23.0 // indirect + github.com/jackc/fake v0.0.0-20150926172116-812a484cc733 // indirect + github.com/jackc/pgpassfile v1.0.0 // indirect + github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect + github.com/jackc/puddle/v2 v2.2.2 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/shopspring/decimal v1.4.0 // indirect + golang.org/x/crypto v0.37.0 // indirect + golang.org/x/sync v0.13.0 // indirect + golang.org/x/text v0.24.0 // indirect ) diff --git a/go.sum b/go.sum index db124c7..50cce7d 100644 --- a/go.sum +++ b/go.sum @@ -2,10 +2,13 @@ filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= git.fuyu.moe/Fuyu/assert v0.2.1 h1:F8faRzPp0AhzGDYzv0S6eehbRTb72dc0V2ZMMo39ryo= git.fuyu.moe/Fuyu/assert v0.2.1/go.mod h1:Q/wfl8GbNF2ZRkaVOd4zcxr+1MTQ3UZLywWwaxxBzkk= +github.com/Azure/azure-sdk-for-go/sdk/azcore v0.19.0/go.mod h1:h6H6c8enJmmocHUbLiiGY6sx7f9i+X3m1CHdd5c6Rdw= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1 h1:E+OJmp2tPvt1W+amx48v1eqbjDYsgN+RzP4q16yV5eM= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1/go.mod h1:a6xsAQUZg+VsS3TJ05SRp524Hs4pZ/AeFSr5ENf0Yjo= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v0.11.0/go.mod h1:HcM1YX14R7CJcghJGOYCgdezslRSVzqwLf/q+4Y2r/0= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.6.0 h1:U2rTu3Ef+7w9FHKIAXM6ZyqF3UOWJZ12zIm8zECAFfg= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.6.0/go.mod h1:9kIvujWAA58nmPmWB1m23fyWic1kYZMxD9CxaWn4Qpg= +github.com/Azure/azure-sdk-for-go/sdk/internal v0.7.0/go.mod h1:yqy467j36fJxcRV2TzfVZ1pCb5vxm4BtZPUdYWe/Xo8= github.com/Azure/azure-sdk-for-go/sdk/internal v1.8.0 h1:jBQA3cKT4L2rWMpgE7Yt3Hwh2aUj8KXjIGLxjHeYNNo= github.com/Azure/azure-sdk-for-go/sdk/internal v1.8.0/go.mod h1:4OG6tQ9EOP/MT0NMjDlRzWoVFxfu9rN9B2X+tlSVktg= github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.0.1 h1:MyVTgWR8qd/Jw1Le0NZebGBUCLbtak3bJ3z1OlqZBpw= @@ -14,12 +17,21 @@ github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.0.0 h1:D3occ github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.0.0/go.mod h1:bTSOgj05NGRuHHhQwAdPnYr9TOdNmKlZTgGLL6nyAdI= github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 h1:XHOnouVk1mxXfQidrMEnLlPk9UMeRtyBTnEFtxkV0kU= github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= +github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= +github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/denisenkom/go-mssqldb v0.12.3 h1:pBSGx9Tq67pBOTLmxNuirNTeB8Vjmf886Kx+8Y+8shw= +github.com/denisenkom/go-mssqldb v0.12.3/go.mod h1:k0mtMFOnU+AihqFxPMiF05rtiDrorD1Vrm1KEz5hxDo= +github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= github.com/go-sql-driver/mysql v1.9.3 h1:U/N249h2WzJ3Ukj8SowVFjdtZKfu9vlLZxjPXV1aweo= github.com/go-sql-driver/mysql v1.9.3/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU= +github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA= +github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8= github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= +github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA= github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A= @@ -29,26 +41,71 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/jackc/fake v0.0.0-20150926172116-812a484cc733 h1:vr3AYkKovP8uR8AvSGGUK1IDqRa5lAAvEkZG1LKaCRc= +github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ= +github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= +github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= +github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo= +github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= +github.com/jackc/pgx v3.6.2+incompatible h1:2zP5OD7kiyR3xzRYMhOcXVvkDZsImVXfj+yIyTQf3/o= +github.com/jackc/pgx v3.6.2+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I= +github.com/jackc/pgx/v5 v5.7.5 h1:JHGfMnQY+IEtGM63d+NGMjoRpysB2JBwDr5fsngwmJs= +github.com/jackc/pgx/v5 v5.7.5/go.mod h1:aruU7o91Tc2q2cFp5h4uP3f6ztExVpyVv88Xl/8Vl8M= +github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo= +github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/microsoft/go-mssqldb v1.8.2 h1:236sewazvC8FvG6Dr3bszrVhMkAl4KYImryLkRMCd0I= github.com/microsoft/go-mssqldb v1.8.2/go.mod h1:vp38dT33FGfVotRiTmDo3bFyaHq+p3LektQrjTULowo= +github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8= +github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 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/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= +github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= -golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= +github.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs= +github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE= +golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= -golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= -golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= -golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= +golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610= +golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= +golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +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.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= +golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.8/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/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/tests/db_test.go b/internal/tests/db_test.go index 85a74e6..8dff99e 100644 --- a/internal/tests/db_test.go +++ b/internal/tests/db_test.go @@ -4,9 +4,7 @@ import ( "database/sql" "strings" - _ "github.com/go-sql-driver/mysql" // database driver - _ "github.com/lib/pq" // database driver - _ "github.com/microsoft/go-mssqldb" // database driver for Microsoft MSSQL + "git.ultraware.nl/Ultraware/qb/v2/driver/autoqb" ) func initDatabase(driverName, connectionString string) *sql.DB { @@ -17,10 +15,11 @@ func initDatabase(driverName, connectionString string) *sql.DB { dropQuery := `DROP TABLE IF EXISTS one, "two $#!", three` sql := createSQL - if driverName != `postgres` { + + switch { + case autoqb.IsPostgres(db): sql = strings.ReplaceAll(sql, `timestamp`, `datetime`) - } - if driverName == `mysql` { + case autoqb.IsMysql(db): sql = strings.ReplaceAll(sql, `"`, "`") dropQuery = strings.ReplaceAll(dropQuery, `"`, "`") } @@ -42,6 +41,10 @@ func initPostgres() *sql.DB { return initDatabase(`postgres`, getPostgresDBString()) } +func initPostgresX() *sql.DB { + return initDatabase(`pgx`, getPostgresDBString()) +} + func initMysql() *sql.DB { return initDatabase(`mysql`, getMysqlDBString()) } diff --git a/internal/tests/tests_test.go b/internal/tests/tests_test.go index 620b480..7fad87f 100644 --- a/internal/tests/tests_test.go +++ b/internal/tests/tests_test.go @@ -4,7 +4,6 @@ import ( "database/sql" "fmt" "os" - "reflect" "testing" "time" @@ -20,7 +19,7 @@ import ( var ( db qbdb.DB - driver string + driver qb.DBType ) func TestEndToEnd(t *testing.T) { @@ -32,6 +31,8 @@ func TestEndToEnd(t *testing.T) { switch os.Getenv(`TYPE`) { case `postgres`: db = initPostgres() + case `postgresX`: + db = initPostgresX() case `mysql`: db = initMysql() case `mssql`: @@ -46,7 +47,7 @@ func TestEndToEnd(t *testing.T) { func startTests(t *testing.T, d *sql.DB) { db = autoqb.New(d) - driver = reflect.TypeOf(db.Driver()).String() + driver = db.Driver().DBType() if testing.Verbose() { db.SetDebug(true) @@ -64,7 +65,7 @@ func startTests(t *testing.T, d *sql.DB) { } func runTests(t *testing.T) { - if driver == `msqb.Driver` { + if driver == qb.DriverMssql { testUpsertSeparate(t) testInsert(t) testUpsertSeparate(t) @@ -73,11 +74,11 @@ func runTests(t *testing.T) { testInsert(t) testUpsert(t) } - if driver == `pgqb.Driver` { + if driver == qb.DriverPostgres { testIgnoreConflicts(t) } - if driver == `myqb.Driver` { + if driver == qb.DriverMysql { testUpdate(t) } else { testUpdateReturning(t) @@ -93,14 +94,14 @@ func runTests(t *testing.T) { testExists(t) testPrepare(t) testSubQuery(t) - if driver == `pgqb.Driver` { + if driver == qb.DriverPostgres { testInnerJoinLateral(t) testLateralJoinAlias(t) } testCTE(t) testUnionAll(t) - if driver == `myqb.Driver` { + if driver == qb.DriverMysql { testDelete(t) } else { testDeleteReturning(t) diff --git a/qbdb/driver.go b/qbdb/driver.go index d141206..2a6c308 100644 --- a/qbdb/driver.go +++ b/qbdb/driver.go @@ -9,6 +9,10 @@ import ( // Driver is a default driver used for tests type Driver struct{} +func (d Driver) DBType() qb.DBType { + return qb.DriverPostgres +} + // ValueString returns the placeholder for prepare values func (d Driver) ValueString(_ int) string { return `@@` diff --git a/types.go b/types.go index 55603da..5a2c7f7 100644 --- a/types.go +++ b/types.go @@ -5,7 +5,18 @@ import ( "strings" ) -// Driver implements databse-specific features +type DBType int + +const ( + // DriverPostgres is the PostgreSQL driver + DriverPostgres DBType = iota + // DriverMysql is the MySQL driver + DriverMysql + // DriverMssql is the Microsoft SQL Server driver + DriverMssql +) + +// Driver implements database-specific features type Driver interface { ValueString(int) string BoolString(bool) string @@ -17,6 +28,8 @@ type Driver interface { LateralJoin(*Context, *SubQuery) string TypeName(DataType) string Override() OverrideMap + + DBType() DBType } // Query generates SQL diff --git a/update.go b/update.go index 0e2a934..f214192 100644 --- a/update.go +++ b/update.go @@ -2,7 +2,6 @@ package qb import ( "reflect" - "strings" ) type set struct { @@ -43,7 +42,7 @@ func (q *UpdateBuilder) Where(c ...Condition) *UpdateBuilder { // SQL returns a query string and a list of values func (q *UpdateBuilder) SQL(b SQLBuilder) (string, []interface{}) { - if reflect.TypeOf(b.Context.alias) != reflect.TypeOf(NoAlias()) && strings.HasSuffix(reflect.TypeOf(b.Context.Driver).PkgPath(), `msqb`) { + if reflect.TypeOf(b.Context.alias) != reflect.TypeOf(NoAlias()) && b.Context.Driver.DBType() == DriverMssql { b.w.WriteLine(`UPDATE ` + q.t.aliasString()) b.Set(q.set) b.w.WriteLine(`FROM ` + b.SourceToSQL(q.t))