Add support for CockorachDB.
This commit is contained in:
parent
3ff9241eea
commit
bc776f947b
33 changed files with 1040 additions and 1037 deletions
|
|
@ -2,6 +2,7 @@ package postgres
|
|||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"github.com/go-jet/jet/v2/internal/testutils"
|
||||
. "github.com/go-jet/jet/v2/postgres"
|
||||
model2 "github.com/go-jet/jet/v2/tests/.gentestdata/jetdb/dvds/model"
|
||||
|
|
@ -14,9 +15,7 @@ import (
|
|||
)
|
||||
|
||||
func TestUpdateValues(t *testing.T) {
|
||||
setupLinkTableForUpdateTest(t)
|
||||
|
||||
t.Run("deprecated version", func(t *testing.T) {
|
||||
t.Run("deprecated update", func(t *testing.T) {
|
||||
query := Link.
|
||||
UPDATE(Link.Name, Link.URL).
|
||||
SET("Bong", "http://bong.com").
|
||||
|
|
@ -25,31 +24,34 @@ func TestUpdateValues(t *testing.T) {
|
|||
testutils.AssertDebugStatementSql(t, query, `
|
||||
UPDATE test_sample.link
|
||||
SET (name, url) = ('Bong', 'http://bong.com')
|
||||
WHERE link.name = 'Bing';
|
||||
WHERE link.name = 'Bing'::text;
|
||||
`, "Bong", "http://bong.com", "Bing")
|
||||
|
||||
testutils.AssertExec(t, query, db, 1)
|
||||
requireLogged(t, query)
|
||||
testutils.ExecuteInTxAndRollback(t, db, func(tx *sql.Tx) {
|
||||
|
||||
links := []model.Link{}
|
||||
testutils.AssertExec(t, query, tx, 1)
|
||||
requireLogged(t, query)
|
||||
|
||||
selQuery := Link.
|
||||
SELECT(Link.AllColumns).
|
||||
WHERE(Link.Name.IN(String("Bong")))
|
||||
var links []model.Link
|
||||
|
||||
err := selQuery.Query(db, &links)
|
||||
selQuery := Link.
|
||||
SELECT(Link.AllColumns).
|
||||
WHERE(Link.Name.IN(String("Bong")))
|
||||
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, len(links), 1)
|
||||
testutils.AssertDeepEqual(t, links[0], model.Link{
|
||||
ID: 204,
|
||||
URL: "http://bong.com",
|
||||
Name: "Bong",
|
||||
err := selQuery.Query(tx, &links)
|
||||
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, len(links), 1)
|
||||
testutils.AssertDeepEqual(t, links[0], model.Link{
|
||||
ID: 204,
|
||||
URL: "http://bong.com",
|
||||
Name: "Bong",
|
||||
})
|
||||
requireLogged(t, selQuery)
|
||||
})
|
||||
requireLogged(t, selQuery)
|
||||
})
|
||||
|
||||
t.Run("new version", func(t *testing.T) {
|
||||
t.Run("new type safe update", func(t *testing.T) {
|
||||
stmt := Link.UPDATE().
|
||||
SET(
|
||||
Link.Name.SET(String("DuckDuckGo")),
|
||||
|
|
@ -59,18 +61,16 @@ WHERE link.name = 'Bing';
|
|||
|
||||
testutils.AssertDebugStatementSql(t, stmt, `
|
||||
UPDATE test_sample.link
|
||||
SET name = 'DuckDuckGo',
|
||||
url = 'www.duckduckgo.com'
|
||||
WHERE link.name = 'Yahoo';
|
||||
SET name = 'DuckDuckGo'::text,
|
||||
url = 'www.duckduckgo.com'::text
|
||||
WHERE link.name = 'Yahoo'::text;
|
||||
`)
|
||||
testutils.AssertExec(t, stmt, db, 1)
|
||||
testutils.AssertExecAndRollback(t, stmt, db, 1)
|
||||
requireLogged(t, stmt)
|
||||
})
|
||||
}
|
||||
|
||||
func TestUpdateWithSubQueries(t *testing.T) {
|
||||
setupLinkTableForUpdateTest(t)
|
||||
|
||||
t.Run("deprecated version", func(t *testing.T) {
|
||||
query := Link.
|
||||
UPDATE(Link.Name, Link.URL).
|
||||
|
|
@ -82,20 +82,19 @@ func TestUpdateWithSubQueries(t *testing.T) {
|
|||
).
|
||||
WHERE(Link.Name.EQ(String("Bing")))
|
||||
|
||||
expectedSQL := `
|
||||
testutils.AssertDebugStatementSql(t, query, `
|
||||
UPDATE test_sample.link
|
||||
SET (name, url) = ((
|
||||
SELECT 'Bong'
|
||||
SELECT 'Bong'::text
|
||||
), (
|
||||
SELECT link.url AS "link.url"
|
||||
FROM test_sample.link
|
||||
WHERE link.name = 'Bing'
|
||||
WHERE link.name = 'Bing'::text
|
||||
))
|
||||
WHERE link.name = 'Bing';
|
||||
`
|
||||
testutils.AssertDebugStatementSql(t, query, expectedSQL, "Bong", "Bing", "Bing")
|
||||
WHERE link.name = 'Bing'::text;
|
||||
`, "Bong", "Bing", "Bing")
|
||||
|
||||
AssertExec(t, query, 1)
|
||||
testutils.AssertExecAndRollback(t, query, db, 1)
|
||||
requireLogged(t, query)
|
||||
})
|
||||
|
||||
|
|
@ -113,50 +112,48 @@ WHERE link.name = 'Bing';
|
|||
|
||||
testutils.AssertStatementSql(t, query, `
|
||||
UPDATE test_sample.link
|
||||
SET name = $1,
|
||||
SET name = $1::text,
|
||||
url = (
|
||||
SELECT link.url AS "link.url"
|
||||
FROM test_sample.link
|
||||
WHERE link.name = $2
|
||||
WHERE link.name = $2::text
|
||||
)
|
||||
WHERE link.name = $3;
|
||||
WHERE link.name = $3::text;
|
||||
`, "Bong", "Bing", "Bing")
|
||||
_, err := query.Exec(db)
|
||||
require.NoError(t, err)
|
||||
testutils.AssertExecAndRollback(t, query, db)
|
||||
requireLogged(t, query)
|
||||
})
|
||||
}
|
||||
|
||||
func TestUpdateAndReturning(t *testing.T) {
|
||||
setupLinkTableForUpdateTest(t)
|
||||
|
||||
expectedSQL := `
|
||||
UPDATE test_sample.link
|
||||
SET (name, url) = ('DuckDuckGo', 'http://www.duckduckgo.com')
|
||||
WHERE link.name = 'Ask'
|
||||
RETURNING link.id AS "link.id",
|
||||
link.url AS "link.url",
|
||||
link.name AS "link.name",
|
||||
link.description AS "link.description";
|
||||
`
|
||||
|
||||
stmt := Link.
|
||||
UPDATE(Link.Name, Link.URL).
|
||||
SET("DuckDuckGo", "http://www.duckduckgo.com").
|
||||
WHERE(Link.Name.EQ(String("Ask"))).
|
||||
RETURNING(Link.AllColumns)
|
||||
|
||||
testutils.AssertDebugStatementSql(t, stmt, expectedSQL, "DuckDuckGo", "http://www.duckduckgo.com", "Ask")
|
||||
testutils.AssertDebugStatementSql(t, stmt, `
|
||||
UPDATE test_sample.link
|
||||
SET (name, url) = ('DuckDuckGo', 'http://www.duckduckgo.com')
|
||||
WHERE link.name = 'Ask'::text
|
||||
RETURNING link.id AS "link.id",
|
||||
link.url AS "link.url",
|
||||
link.name AS "link.name",
|
||||
link.description AS "link.description";
|
||||
`, "DuckDuckGo", "http://www.duckduckgo.com", "Ask")
|
||||
|
||||
links := []model.Link{}
|
||||
testutils.ExecuteInTxAndRollback(t, db, func(tx *sql.Tx) {
|
||||
links := []model.Link{}
|
||||
|
||||
err := stmt.Query(db, &links)
|
||||
err := stmt.Query(tx, &links)
|
||||
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, len(links), 2)
|
||||
require.Equal(t, links[0].Name, "DuckDuckGo")
|
||||
require.Equal(t, links[1].Name, "DuckDuckGo")
|
||||
requireLogged(t, stmt)
|
||||
})
|
||||
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, len(links), 2)
|
||||
require.Equal(t, links[0].Name, "DuckDuckGo")
|
||||
require.Equal(t, links[1].Name, "DuckDuckGo")
|
||||
requireLogged(t, stmt)
|
||||
}
|
||||
|
||||
func TestUpdateWithSelect(t *testing.T) {
|
||||
|
|
@ -170,7 +167,7 @@ func TestUpdateWithSelect(t *testing.T) {
|
|||
).
|
||||
WHERE(Link.ID.EQ(Int(0)))
|
||||
|
||||
expectedSQL := `
|
||||
testutils.AssertDebugStatementSql(t, stmt, `
|
||||
UPDATE test_sample.link
|
||||
SET (id, url, name, description) = (
|
||||
SELECT link.id AS "link.id",
|
||||
|
|
@ -181,10 +178,9 @@ SET (id, url, name, description) = (
|
|||
WHERE link.id = 0
|
||||
)
|
||||
WHERE link.id = 0;
|
||||
`
|
||||
testutils.AssertDebugStatementSql(t, stmt, expectedSQL, int64(0), int64(0))
|
||||
`, int64(0), int64(0))
|
||||
|
||||
AssertExec(t, stmt, 1)
|
||||
testutils.AssertExecAndRollback(t, stmt, db, 1)
|
||||
})
|
||||
|
||||
t.Run("new version", func(t *testing.T) {
|
||||
|
|
@ -210,12 +206,11 @@ SET (url, name, description) = (
|
|||
WHERE link.id = 0;
|
||||
`, int64(0), int64(0))
|
||||
|
||||
AssertExec(t, stmt, 1)
|
||||
testutils.AssertExecAndRollback(t, stmt, db, 1)
|
||||
})
|
||||
}
|
||||
|
||||
func TestUpdateWithInvalidSelect(t *testing.T) {
|
||||
|
||||
t.Run("deprecated version", func(t *testing.T) {
|
||||
stmt := Link.UPDATE(Link.AllColumns).
|
||||
SET(
|
||||
|
|
@ -236,7 +231,6 @@ SET (id, url, name, description) = (
|
|||
WHERE link.id = 0;
|
||||
`
|
||||
testutils.AssertDebugStatementSql(t, stmt, expectedSQL, int64(0), int64(0))
|
||||
|
||||
testutils.AssertExecErr(t, stmt, db, "pq: number of columns does not match number of values")
|
||||
})
|
||||
|
||||
|
|
@ -250,8 +244,6 @@ WHERE link.id = 0;
|
|||
}
|
||||
|
||||
func TestUpdateWithModelData(t *testing.T) {
|
||||
setupLinkTableForUpdateTest(t)
|
||||
|
||||
link := model.Link{
|
||||
ID: 201,
|
||||
URL: "http://www.duckduckgo.com",
|
||||
|
|
@ -261,24 +253,20 @@ func TestUpdateWithModelData(t *testing.T) {
|
|||
stmt := Link.
|
||||
UPDATE(Link.AllColumns).
|
||||
MODEL(link).
|
||||
WHERE(Link.ID.EQ(Int32(link.ID)))
|
||||
WHERE(Link.ID.EQ(Int64(link.ID)))
|
||||
|
||||
expectedSQL := `
|
||||
UPDATE test_sample.link
|
||||
SET (id, url, name, description) = (201, 'http://www.duckduckgo.com', 'DuckDuckGo', NULL)
|
||||
WHERE link.id = 201::integer;
|
||||
WHERE link.id = 201::bigint;
|
||||
`
|
||||
testutils.AssertDebugStatementSql(t, stmt, expectedSQL, int32(201), "http://www.duckduckgo.com", "DuckDuckGo", nil, int32(201))
|
||||
testutils.AssertDebugStatementSql(t, stmt, expectedSQL, int64(201), "http://www.duckduckgo.com", "DuckDuckGo", nil, int64(201))
|
||||
|
||||
_, err := stmt.Exec(db)
|
||||
require.NoError(t, err)
|
||||
testutils.AssertExecAndRollback(t, stmt, db, 1)
|
||||
requireQueryLogged(t, stmt, 1)
|
||||
}
|
||||
|
||||
func TestUpdateWithModelDataAndPredefinedColumnList(t *testing.T) {
|
||||
|
||||
setupLinkTableForUpdateTest(t)
|
||||
|
||||
link := model.Link{
|
||||
ID: 201,
|
||||
URL: "http://www.duckduckgo.com",
|
||||
|
|
@ -290,27 +278,24 @@ func TestUpdateWithModelDataAndPredefinedColumnList(t *testing.T) {
|
|||
stmt := Link.
|
||||
UPDATE(updateColumnList).
|
||||
MODEL(link).
|
||||
WHERE(Link.ID.EQ(Int32(link.ID)))
|
||||
WHERE(Link.ID.EQ(Int64(link.ID)))
|
||||
|
||||
var expectedSQL = `
|
||||
testutils.AssertDebugStatementSql(t, stmt, `
|
||||
UPDATE test_sample.link
|
||||
SET (description, name, url) = (NULL, 'DuckDuckGo', 'http://www.duckduckgo.com')
|
||||
WHERE link.id = 201::integer;
|
||||
`
|
||||
testutils.AssertDebugStatementSql(t, stmt, expectedSQL, nil, "DuckDuckGo", "http://www.duckduckgo.com", int32(201))
|
||||
WHERE link.id = 201::bigint;
|
||||
`,
|
||||
nil, "DuckDuckGo", "http://www.duckduckgo.com", int64(201))
|
||||
|
||||
AssertExec(t, stmt, 1)
|
||||
testutils.AssertExecAndRollback(t, stmt, db, 1)
|
||||
}
|
||||
|
||||
func TestUpdateWithInvalidModelData(t *testing.T) {
|
||||
defer func() {
|
||||
r := recover()
|
||||
|
||||
require.Equal(t, r, "missing struct field for column : id")
|
||||
}()
|
||||
|
||||
setupLinkTableForUpdateTest(t)
|
||||
|
||||
link := struct {
|
||||
Ident int
|
||||
URL string
|
||||
|
|
@ -323,24 +308,13 @@ func TestUpdateWithInvalidModelData(t *testing.T) {
|
|||
Name: "DuckDuckGo",
|
||||
}
|
||||
|
||||
stmt := Link.
|
||||
_ = Link.
|
||||
UPDATE(Link.AllColumns).
|
||||
MODEL(link).
|
||||
MODEL(link). // panics
|
||||
WHERE(Link.ID.EQ(Int(int64(link.Ident))))
|
||||
|
||||
var expectedSQL = `
|
||||
UPDATE test_sample.link
|
||||
SET (id, url, name, description, rel) = ('http://www.duckduckgo.com', 'DuckDuckGo', NULL, NULL)
|
||||
WHERE link.id = 201;
|
||||
`
|
||||
testutils.AssertDebugStatementSql(t, stmt, expectedSQL, "http://www.duckduckgo.com", "DuckDuckGo", nil, nil, int64(201))
|
||||
|
||||
testutils.AssertExecErr(t, stmt, db, "pq: number of columns does not match number of values")
|
||||
}
|
||||
|
||||
func TestUpdateQueryContext(t *testing.T) {
|
||||
setupLinkTableForUpdateTest(t)
|
||||
|
||||
updateStmt := Link.
|
||||
UPDATE(Link.Name, Link.URL).
|
||||
SET("Bong", "http://bong.com").
|
||||
|
|
@ -351,15 +325,15 @@ func TestUpdateQueryContext(t *testing.T) {
|
|||
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
|
||||
dest := []model.Link{}
|
||||
err := updateStmt.QueryContext(ctx, db, &dest)
|
||||
testutils.ExecuteInTxAndRollback(t, db, func(tx *sql.Tx) {
|
||||
dest := []model.Link{}
|
||||
err := updateStmt.QueryContext(ctx, tx, &dest)
|
||||
|
||||
require.Error(t, err, "context deadline exceeded")
|
||||
require.Error(t, err, "context deadline exceeded")
|
||||
})
|
||||
}
|
||||
|
||||
func TestUpdateExecContext(t *testing.T) {
|
||||
setupLinkTableForUpdateTest(t)
|
||||
|
||||
updateStmt := Link.
|
||||
UPDATE(Link.Name, Link.URL).
|
||||
SET("Bong", "http://bong.com").
|
||||
|
|
@ -370,15 +344,10 @@ func TestUpdateExecContext(t *testing.T) {
|
|||
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
|
||||
_, err := updateStmt.ExecContext(ctx, db)
|
||||
|
||||
require.Error(t, err, "context deadline exceeded")
|
||||
testutils.AssertExecContextErr(t, updateStmt, ctx, db, "context deadline exceeded")
|
||||
}
|
||||
|
||||
func TestUpdateFrom(t *testing.T) {
|
||||
tx := beginTx(t)
|
||||
defer tx.Rollback()
|
||||
|
||||
stmt := table.Rental.UPDATE().
|
||||
SET(
|
||||
table.Rental.RentalDate.SET(Timestamp(2020, 2, 2, 0, 0, 0)),
|
||||
|
|
@ -416,16 +385,17 @@ RETURNING rental.rental_id AS "rental.rental_id",
|
|||
store.address_id AS "store.address_id";
|
||||
`)
|
||||
|
||||
var dest []struct {
|
||||
Rental model2.Rental
|
||||
Store model2.Store
|
||||
}
|
||||
testutils.ExecuteInTxAndRollback(t, db, func(tx *sql.Tx) {
|
||||
var dest []struct {
|
||||
Rental model2.Rental
|
||||
Store model2.Store
|
||||
}
|
||||
|
||||
err := stmt.Query(tx, &dest)
|
||||
err := stmt.Query(tx, &dest)
|
||||
|
||||
require.NoError(t, err)
|
||||
require.Len(t, dest, 3)
|
||||
testutils.AssertJSON(t, dest[0], `
|
||||
require.NoError(t, err)
|
||||
require.Len(t, dest, 3)
|
||||
testutils.AssertJSON(t, dest[0], `
|
||||
{
|
||||
"Rental": {
|
||||
"RentalID": 4,
|
||||
|
|
@ -444,24 +414,5 @@ RETURNING rental.rental_id AS "rental.rental_id",
|
|||
}
|
||||
}
|
||||
`)
|
||||
}
|
||||
|
||||
func setupLinkTableForUpdateTest(t *testing.T) {
|
||||
|
||||
cleanUpLinkTable(t)
|
||||
|
||||
_, err := Link.INSERT(Link.ID, Link.URL, Link.Name, Link.Description).
|
||||
VALUES(200, "http://www.postgresqltutorial.com", "PostgreSQL Tutorial", DEFAULT).
|
||||
VALUES(201, "http://www.ask.com", "Ask", DEFAULT).
|
||||
VALUES(202, "http://www.ask.com", "Ask", DEFAULT).
|
||||
VALUES(203, "http://www.yahoo.com", "Yahoo", DEFAULT).
|
||||
VALUES(204, "http://www.bing.com", "Bing", DEFAULT).
|
||||
Exec(db)
|
||||
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func cleanUpLinkTable(t *testing.T) {
|
||||
_, err := Link.DELETE().WHERE(Link.ID.GT(Int(0))).Exec(db)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue