Merge remote-tracking branch 'upstream/master' into stmt-cache2
# Conflicts: # tests/postgres/alltypes_test.go # tests/postgres/northwind_test.go # tests/postgres/sample_test.go # tests/postgres/update_test.go # tests/sqlite/insert_test.go # tests/sqlite/main_test.go # tests/sqlite/sample_test.go # tests/sqlite/update_test.go
This commit is contained in:
commit
4bb9775134
97 changed files with 2306 additions and 537 deletions
|
|
@ -1,6 +1,10 @@
|
|||
package postgres
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"github.com/go-jet/jet/v2/internal/utils/ptr"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/go-jet/jet/v2/qrm"
|
||||
"testing"
|
||||
"time"
|
||||
|
|
@ -344,24 +348,22 @@ func TestExpressionOperators(t *testing.T) {
|
|||
AllTypes.SmallIntPtr.NOT_IN(AllTypes.SELECT(AllTypes.Integer)).AS("result.not_in_select"),
|
||||
).LIMIT(2)
|
||||
|
||||
//fmt.Println(query.Sql())
|
||||
|
||||
testutils.AssertStatementSql(t, query, `
|
||||
SELECT all_types.integer IS NULL AS "result.is_null",
|
||||
all_types.date_ptr IS NOT NULL AS "result.is_not_null",
|
||||
(all_types.small_int_ptr IN ($1::smallint, $2::smallint)) AS "result.in",
|
||||
(all_types.small_int_ptr IN (
|
||||
(all_types.small_int_ptr IN ((
|
||||
SELECT all_types.integer AS "all_types.integer"
|
||||
FROM test_sample.all_types
|
||||
)) AS "result.in_select",
|
||||
))) AS "result.in_select",
|
||||
(CURRENT_USER) AS "result.raw",
|
||||
($3 + COALESCE(all_types.small_int_ptr, 0) + $4) AS "result.raw_arg",
|
||||
($5 + all_types.integer + $6 + $5 + $7 + $8) AS "result.raw_arg2",
|
||||
(all_types.small_int_ptr NOT IN ($9, $10::smallint, NULL)) AS "result.not_in",
|
||||
(all_types.small_int_ptr NOT IN (
|
||||
(all_types.small_int_ptr NOT IN ((
|
||||
SELECT all_types.integer AS "all_types.integer"
|
||||
FROM test_sample.all_types
|
||||
)) AS "result.not_in_select"
|
||||
))) AS "result.not_in_select"
|
||||
FROM test_sample.all_types
|
||||
LIMIT $11;
|
||||
`, int8(11), int8(22), 78, 56, 11, 22, 33, 44, int64(11), int16(22), int64(2))
|
||||
|
|
@ -373,9 +375,6 @@ LIMIT $11;
|
|||
err := query.Query(db, &dest)
|
||||
|
||||
require.NoError(t, err)
|
||||
|
||||
//testutils.PrintJson(dest)
|
||||
|
||||
testutils.AssertJSON(t, dest, `
|
||||
[
|
||||
{
|
||||
|
|
@ -930,6 +929,68 @@ func TestTimeExpression(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestIntervalSetFunctionality(t *testing.T) {
|
||||
|
||||
t.Run("updateQueryIntervalTest", func(t *testing.T) {
|
||||
|
||||
expectedQuery := `
|
||||
UPDATE test_sample.employee
|
||||
SET pto_accrual = INTERVAL '3 HOUR'
|
||||
WHERE employee.employee_id = $1
|
||||
RETURNING employee.employee_id AS "employee.employee_id",
|
||||
employee.first_name AS "employee.first_name",
|
||||
employee.last_name AS "employee.last_name",
|
||||
employee.employment_date AS "employee.employment_date",
|
||||
employee.manager_id AS "employee.manager_id",
|
||||
employee.pto_accrual AS "employee.pto_accrual";
|
||||
`
|
||||
testutils.ExecuteInTxAndRollback(t, db, func(tx *sql.Tx) {
|
||||
var windy model.Employee
|
||||
windy.PtoAccrual = ptr.Of("3h")
|
||||
stmt := Employee.UPDATE(Employee.PtoAccrual).SET(
|
||||
Employee.PtoAccrual.SET(INTERVAL(3, HOUR)),
|
||||
).WHERE(Employee.EmployeeID.EQ(Int(1))).RETURNING(Employee.AllColumns)
|
||||
|
||||
testutils.AssertStatementSql(t, stmt, expectedQuery)
|
||||
err := stmt.Query(tx, &windy)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, *windy.PtoAccrual, "03:00:00")
|
||||
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("upsertQueryIntervalTest", func(t *testing.T) {
|
||||
expectedQuery := `
|
||||
INSERT INTO test_sample.employee (employee_id, first_name, last_name, employment_date, manager_id, pto_accrual)
|
||||
VALUES ($1, $2, $3, $4, $5, $6)
|
||||
ON CONFLICT (employee_id) DO UPDATE
|
||||
SET pto_accrual = excluded.pto_accrual
|
||||
RETURNING employee.employee_id AS "employee.employee_id",
|
||||
employee.first_name AS "employee.first_name",
|
||||
employee.last_name AS "employee.last_name",
|
||||
employee.employment_date AS "employee.employment_date",
|
||||
employee.manager_id AS "employee.manager_id",
|
||||
employee.pto_accrual AS "employee.pto_accrual";
|
||||
`
|
||||
testutils.ExecuteInTxAndRollback(t, db, func(tx *sql.Tx) {
|
||||
var employee model.Employee
|
||||
employee.PtoAccrual = ptr.Of("5h")
|
||||
stmt := Employee.INSERT(Employee.AllColumns).
|
||||
MODEL(employee).
|
||||
ON_CONFLICT(Employee.EmployeeID).
|
||||
DO_UPDATE(SET(
|
||||
Employee.PtoAccrual.SET(Employee.EXCLUDED.PtoAccrual),
|
||||
)).RETURNING(Employee.AllColumns)
|
||||
|
||||
testutils.AssertStatementSql(t, stmt, expectedQuery)
|
||||
err := stmt.Query(tx, &employee)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, *employee.PtoAccrual, "05:00:00")
|
||||
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestInterval(t *testing.T) {
|
||||
skipForCockroachDB(t)
|
||||
|
||||
|
|
@ -1046,6 +1107,46 @@ FROM test_sample.all_types;
|
|||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestRowExpression(t *testing.T) {
|
||||
now := time.Now()
|
||||
nowAddHour := time.Now().Add(time.Hour)
|
||||
|
||||
stmt := SELECT(
|
||||
ROW(Int32(1), Float32(11.22), String("john")).AS("row"),
|
||||
WRAP(Int64(1), Float64(11.22), String("john")).AS("wrap"),
|
||||
|
||||
ROW(Bool(false), DateT(now)).EQ(ROW(Bool(true), DateT(now))),
|
||||
WRAP(Bool(false), DateT(now)).NOT_EQ(WRAP(Bool(true), DateT(now))),
|
||||
|
||||
ROW(TimeT(nowAddHour)).IS_DISTINCT_FROM(RowExp(Raw("row(NOW()::time)"))),
|
||||
ROW().IS_NOT_DISTINCT_FROM(ROW()),
|
||||
|
||||
ROW(TimestampT(now), TimestampzT(nowAddHour)).GT(WRAP(TimestampT(now), TimestampzT(now))),
|
||||
ROW(TimestampzT(nowAddHour)).GT_EQ(ROW(TimestampzT(now))),
|
||||
WRAP(TimestampT(now), TimestampzT(nowAddHour)).LT(ROW(TimestampT(now), TimestampzT(now))),
|
||||
ROW(TimestampzT(nowAddHour)).LT_EQ(ROW(TimestampzT(now))),
|
||||
)
|
||||
|
||||
//fmt.Println(stmt.Sql())
|
||||
//fmt.Println(stmt.DebugSql())
|
||||
|
||||
testutils.AssertStatementSql(t, stmt, `
|
||||
SELECT ROW($1::integer, $2::real, $3::text) AS "row",
|
||||
($4::bigint, $5::double precision, $6::text) AS "wrap",
|
||||
ROW($7::boolean, $8::date) = ROW($9::boolean, $10::date),
|
||||
($11::boolean, $12::date) != ($13::boolean, $14::date),
|
||||
ROW($15::time without time zone) IS DISTINCT FROM (row(NOW()::time)),
|
||||
ROW() IS NOT DISTINCT FROM ROW(),
|
||||
ROW($16::timestamp without time zone, $17::timestamp with time zone) > ($18::timestamp without time zone, $19::timestamp with time zone),
|
||||
ROW($20::timestamp with time zone) >= ROW($21::timestamp with time zone),
|
||||
($22::timestamp without time zone, $23::timestamp with time zone) < ROW($24::timestamp without time zone, $25::timestamp with time zone),
|
||||
ROW($26::timestamp with time zone) <= ROW($27::timestamp with time zone);
|
||||
`)
|
||||
|
||||
err := stmt.Query(db, &struct{}{})
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestSubQueryColumnReference(t *testing.T) {
|
||||
type expected struct {
|
||||
sql string
|
||||
|
|
@ -1305,32 +1406,32 @@ RETURNING all_types.json AS "all_types.json";
|
|||
var moodSad = model.Mood_Sad
|
||||
|
||||
var allTypesRow0 = model.AllTypes{
|
||||
SmallIntPtr: testutils.Int16Ptr(14),
|
||||
SmallIntPtr: ptr.Of(int16(14)),
|
||||
SmallInt: 14,
|
||||
IntegerPtr: testutils.Int32Ptr(300),
|
||||
IntegerPtr: ptr.Of(int32(300)),
|
||||
Integer: 300,
|
||||
BigIntPtr: testutils.Int64Ptr(50000),
|
||||
BigIntPtr: ptr.Of(int64(50000)),
|
||||
BigInt: 5000,
|
||||
DecimalPtr: testutils.Float64Ptr(1.11),
|
||||
DecimalPtr: ptr.Of(1.11),
|
||||
Decimal: 1.11,
|
||||
NumericPtr: testutils.Float64Ptr(2.22),
|
||||
NumericPtr: ptr.Of(2.22),
|
||||
Numeric: 2.22,
|
||||
RealPtr: testutils.Float32Ptr(5.55),
|
||||
RealPtr: ptr.Of(float32(5.55)),
|
||||
Real: 5.55,
|
||||
DoublePrecisionPtr: testutils.Float64Ptr(11111111.22),
|
||||
DoublePrecisionPtr: ptr.Of(11111111.22),
|
||||
DoublePrecision: 11111111.22,
|
||||
Smallserial: 1,
|
||||
Serial: 1,
|
||||
Bigserial: 1,
|
||||
//MoneyPtr: nil,
|
||||
//Money:
|
||||
VarCharPtr: testutils.StringPtr("ABBA"),
|
||||
VarCharPtr: ptr.Of("ABBA"),
|
||||
VarChar: "ABBA",
|
||||
CharPtr: testutils.StringPtr("JOHN "),
|
||||
CharPtr: ptr.Of("JOHN "),
|
||||
Char: "JOHN ",
|
||||
TextPtr: testutils.StringPtr("Some text"),
|
||||
TextPtr: ptr.Of("Some text"),
|
||||
Text: "Some text",
|
||||
ByteaPtr: testutils.ByteArrayPtr([]byte("bytea")),
|
||||
ByteaPtr: ptr.Of([]byte("bytea")),
|
||||
Bytea: []byte("bytea"),
|
||||
TimestampzPtr: testutils.TimestampWithTimeZone("1999-01-08 13:05:06 +0100 CET", 0),
|
||||
Timestampz: *testutils.TimestampWithTimeZone("1999-01-08 13:05:06 +0100 CET", 0),
|
||||
|
|
@ -1342,31 +1443,31 @@ var allTypesRow0 = model.AllTypes{
|
|||
Timez: *testutils.TimeWithTimeZone("04:05:06 -0800"),
|
||||
TimePtr: testutils.TimeWithoutTimeZone("04:05:06"),
|
||||
Time: *testutils.TimeWithoutTimeZone("04:05:06"),
|
||||
IntervalPtr: testutils.StringPtr("3 days 04:05:06"),
|
||||
IntervalPtr: ptr.Of("3 days 04:05:06"),
|
||||
Interval: "3 days 04:05:06",
|
||||
BooleanPtr: testutils.BoolPtr(true),
|
||||
BooleanPtr: ptr.Of(true),
|
||||
Boolean: false,
|
||||
PointPtr: testutils.StringPtr("(2,3)"),
|
||||
BitPtr: testutils.StringPtr("101"),
|
||||
PointPtr: ptr.Of("(2,3)"),
|
||||
BitPtr: ptr.Of("101"),
|
||||
Bit: "101",
|
||||
BitVaryingPtr: testutils.StringPtr("101111"),
|
||||
BitVaryingPtr: ptr.Of("101111"),
|
||||
BitVarying: "101111",
|
||||
TsvectorPtr: testutils.StringPtr("'supernova':1"),
|
||||
TsvectorPtr: ptr.Of("'supernova':1"),
|
||||
Tsvector: "'supernova':1",
|
||||
UUIDPtr: testutils.UUIDPtr("a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11"),
|
||||
UUID: uuid.MustParse("a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11"),
|
||||
XMLPtr: testutils.StringPtr("<Sub>abc</Sub>"),
|
||||
XMLPtr: ptr.Of("<Sub>abc</Sub>"),
|
||||
XML: "<Sub>abc</Sub>",
|
||||
JSONPtr: testutils.StringPtr(`{"a": 1, "b": 3}`),
|
||||
JSONPtr: ptr.Of(`{"a": 1, "b": 3}`),
|
||||
JSON: `{"a": 1, "b": 3}`,
|
||||
JsonbPtr: testutils.StringPtr(`{"a": 1, "b": 3}`),
|
||||
JsonbPtr: ptr.Of(`{"a": 1, "b": 3}`),
|
||||
Jsonb: `{"a": 1, "b": 3}`,
|
||||
IntegerArrayPtr: testutils.StringPtr("{1,2,3}"),
|
||||
IntegerArrayPtr: ptr.Of("{1,2,3}"),
|
||||
IntegerArray: "{1,2,3}",
|
||||
TextArrayPtr: testutils.StringPtr("{breakfast,consulting}"),
|
||||
TextArrayPtr: ptr.Of("{breakfast,consulting}"),
|
||||
TextArray: "{breakfast,consulting}",
|
||||
JsonbArray: `{"{\"a\": 1, \"b\": 2}","{\"a\": 3, \"b\": 4}"}`,
|
||||
TextMultiDimArrayPtr: testutils.StringPtr("{{meeting,lunch},{training,presentation}}"),
|
||||
TextMultiDimArrayPtr: ptr.Of("{{meeting,lunch},{training,presentation}}"),
|
||||
TextMultiDimArray: "{{meeting,lunch},{training,presentation}}",
|
||||
MoodPtr: &moodSad,
|
||||
Mood: model.Mood_Happy,
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package postgres
|
|||
import (
|
||||
"context"
|
||||
"github.com/go-jet/jet/v2/internal/testutils"
|
||||
"github.com/go-jet/jet/v2/internal/utils/ptr"
|
||||
. "github.com/go-jet/jet/v2/postgres"
|
||||
"github.com/go-jet/jet/v2/tests/.gentestdata/jetdb/chinook/model"
|
||||
. "github.com/go-jet/jet/v2/tests/.gentestdata/jetdb/chinook/table"
|
||||
|
|
@ -455,7 +456,7 @@ FROM (
|
|||
require.Len(t, dest, 275)
|
||||
require.Equal(t, dest[0].Artist1.Artist, model.Artist{
|
||||
ArtistId: 1,
|
||||
Name: testutils.StringPtr("AC/DC"),
|
||||
Name: ptr.Of("AC/DC"),
|
||||
})
|
||||
require.Equal(t, dest[0].Artist1.CustomColumn1, "custom_column_1")
|
||||
require.Equal(t, dest[0].Artist1.CustomColumn2, "custom_column_2")
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@ package postgres
|
|||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"path"
|
||||
"testing"
|
||||
|
||||
"github.com/go-jet/jet/v2/generator/metadata"
|
||||
"github.com/go-jet/jet/v2/generator/postgres"
|
||||
"github.com/go-jet/jet/v2/generator/template"
|
||||
|
|
@ -13,8 +16,6 @@ import (
|
|||
"github.com/go-jet/jet/v2/tests/dbconfig"
|
||||
file2 "github.com/go-jet/jet/v2/tests/internal/utils/file"
|
||||
"github.com/stretchr/testify/require"
|
||||
"path"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const tempTestDir = "./.tempTestDir"
|
||||
|
|
@ -170,6 +171,7 @@ func TestGeneratorTemplate_Model_RenameFilesAndTypes(t *testing.T) {
|
|||
|
||||
mpaaRating := file2.Exists(t, defaultModelPath, "mpaa_rating_enum.go")
|
||||
require.Contains(t, mpaaRating, "type MpaaRatingEnum string")
|
||||
require.Contains(t, mpaaRating, "MpaaRatingEnumAllValues")
|
||||
}
|
||||
|
||||
func TestGeneratorTemplate_Model_SkipTableAndEnum(t *testing.T) {
|
||||
|
|
@ -267,7 +269,6 @@ func UseSchema(schema string) {
|
|||
FilmList = FilmList.FromSchema(schema)
|
||||
}
|
||||
`)
|
||||
|
||||
}
|
||||
|
||||
func TestGeneratorTemplate_SQLBuilder_ChangeTypeAndFileName(t *testing.T) {
|
||||
|
|
@ -365,7 +366,6 @@ func TestGeneratorTemplate_SQLBuilder_DefaultAlias(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGeneratorTemplate_Model_AddTags(t *testing.T) {
|
||||
|
||||
err := postgres.Generate(
|
||||
tempTestDir,
|
||||
dbConnection,
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ package postgres
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/go-jet/jet/v2/tests/internal/utils/file"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
|
|
@ -12,11 +11,14 @@ import (
|
|||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/go-jet/jet/v2/generator/metadata"
|
||||
"github.com/go-jet/jet/v2/generator/postgres"
|
||||
"github.com/go-jet/jet/v2/generator/template"
|
||||
"github.com/go-jet/jet/v2/internal/testutils"
|
||||
"github.com/go-jet/jet/v2/tests/dbconfig"
|
||||
|
||||
postgres2 "github.com/go-jet/jet/v2/postgres"
|
||||
"github.com/go-jet/jet/v2/tests/.gentestdata/jetdb/dvds/model"
|
||||
"github.com/go-jet/jet/v2/tests/dbconfig"
|
||||
"github.com/go-jet/jet/v2/tests/internal/utils/file"
|
||||
)
|
||||
|
||||
func dsn(host string, port int, dbName, user, password string) string {
|
||||
|
|
@ -208,6 +210,45 @@ func TestGenerator(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestGenerator_TableMetadata(t *testing.T) {
|
||||
var schema metadata.Schema
|
||||
err := postgres.GenerateDSN(defaultDSN(), "dvds", genTestDir2,
|
||||
template.Default(postgres2.Dialect).UseSchema(func(m metadata.Schema) template.Schema {
|
||||
schema = m
|
||||
return template.DefaultSchema(m)
|
||||
}))
|
||||
require.NoError(t, err)
|
||||
|
||||
// Spot check the actor table and assert that the emitted
|
||||
// properties are as expected.
|
||||
var got metadata.Table
|
||||
var specialFeatures metadata.Column
|
||||
for _, table := range schema.TablesMetaData {
|
||||
if table.Name == "actor" {
|
||||
got = table
|
||||
}
|
||||
if table.Name == "film" {
|
||||
for _, column := range table.Columns {
|
||||
if column.Name == "special_features" {
|
||||
specialFeatures = column
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
want := metadata.Table{
|
||||
Name: "actor",
|
||||
Columns: []metadata.Column{
|
||||
{Name: "actor_id", IsPrimaryKey: true, IsNullable: false, IsGenerated: false, HasDefault: true, DataType: metadata.DataType{Name: "int4", Kind: "base", IsUnsigned: false}, Comment: ""},
|
||||
{Name: "first_name", IsPrimaryKey: false, IsNullable: false, IsGenerated: false, HasDefault: false, DataType: metadata.DataType{Name: "varchar", Kind: "base", IsUnsigned: false}, Comment: ""},
|
||||
{Name: "last_name", IsPrimaryKey: false, IsNullable: false, IsGenerated: false, HasDefault: false, DataType: metadata.DataType{Name: "varchar", Kind: "base", IsUnsigned: false}, Comment: ""},
|
||||
{Name: "last_update", IsPrimaryKey: false, IsNullable: false, IsGenerated: false, HasDefault: false, DataType: metadata.DataType{Name: "timestamp", Kind: "base", IsUnsigned: false}, Comment: ""},
|
||||
},
|
||||
}
|
||||
require.Equal(t, want, got)
|
||||
require.Equal(t, metadata.ArrayType, specialFeatures.DataType.Kind)
|
||||
}
|
||||
|
||||
func TestGeneratorSpecialCharacters(t *testing.T) {
|
||||
t.SkipNow()
|
||||
err := postgres.Generate(genTestDir2, postgres.DBConnection{
|
||||
|
|
@ -563,6 +604,7 @@ func TestGeneratedAllTypesSQLBuilderFiles(t *testing.T) {
|
|||
"mood.go", "person.go", "person_phone.go", "weird_names_table.go", "level.go", "user.go", "floats.go", "people.go",
|
||||
"components.go", "vulnerabilities.go", "all_types_materialized_view.go", "sample_ranges.go")
|
||||
testutils.AssertFileContent(t, modelDir+"/all_types.go", allTypesModelContent)
|
||||
testutils.AssertFileContent(t, modelDir+"/link.go", linkModelContent)
|
||||
|
||||
testutils.AssertFileNamesEqual(t, tableDir, "all_types.go", "employee.go", "link.go",
|
||||
"person.go", "person_phone.go", "weird_names_table.go", "user.go", "floats.go", "people.go", "table_use_schema.go",
|
||||
|
|
@ -570,6 +612,8 @@ func TestGeneratedAllTypesSQLBuilderFiles(t *testing.T) {
|
|||
testutils.AssertFileContent(t, tableDir+"/all_types.go", allTypesTableContent)
|
||||
testutils.AssertFileContent(t, tableDir+"/sample_ranges.go", sampleRangeTableContent)
|
||||
|
||||
testutils.AssertFileContent(t, tableDir+"/link.go", linkTableContent)
|
||||
|
||||
testutils.AssertFileNamesEqual(t, viewDir, "all_types_materialized_view.go", "all_types_view.go",
|
||||
"view_use_schema.go")
|
||||
}
|
||||
|
|
@ -609,6 +653,7 @@ package enum
|
|||
|
||||
import "github.com/go-jet/jet/v2/postgres"
|
||||
|
||||
// Level enum
|
||||
var Level = &struct {
|
||||
Level1 postgres.StringExpression
|
||||
Level2 postgres.StringExpression
|
||||
|
|
@ -706,6 +751,25 @@ type AllTypes struct {
|
|||
}
|
||||
`
|
||||
|
||||
var linkModelContent = `
|
||||
//
|
||||
// Code generated by go-jet DO NOT EDIT.
|
||||
//
|
||||
// WARNING: Changes to this file may cause incorrect behavior
|
||||
// and will be lost if the code is regenerated
|
||||
//
|
||||
|
||||
package model
|
||||
|
||||
// Link table
|
||||
type Link struct {
|
||||
ID int64 ` + "`sql:\"primary_key\"`" + ` // this is link id
|
||||
URL string // link url
|
||||
Name string // Unicode characters comment ₲鬼佬℧⇄↻
|
||||
Description *string // '"Z\%_
|
||||
}
|
||||
`
|
||||
|
||||
var allTypesTableContent = `
|
||||
//
|
||||
// Code generated by go-jet DO NOT EDIT.
|
||||
|
|
@ -1062,3 +1126,91 @@ func newSampleRangesTableImpl(schemaName, tableName, alias string) sampleRangesT
|
|||
}
|
||||
}
|
||||
`
|
||||
|
||||
var linkTableContent = `
|
||||
//
|
||||
// Code generated by go-jet DO NOT EDIT.
|
||||
//
|
||||
// WARNING: Changes to this file may cause incorrect behavior
|
||||
// and will be lost if the code is regenerated
|
||||
//
|
||||
|
||||
package table
|
||||
|
||||
import (
|
||||
"github.com/go-jet/jet/v2/postgres"
|
||||
)
|
||||
|
||||
var Link = newLinkTable("test_sample", "link", "")
|
||||
|
||||
// Link table
|
||||
type linkTable struct {
|
||||
postgres.Table
|
||||
|
||||
// Columns
|
||||
ID postgres.ColumnInteger // this is link id
|
||||
URL postgres.ColumnString // link url
|
||||
Name postgres.ColumnString // Unicode characters comment ₲鬼佬℧⇄↻
|
||||
Description postgres.ColumnString // '"Z\%_
|
||||
|
||||
AllColumns postgres.ColumnList
|
||||
MutableColumns postgres.ColumnList
|
||||
}
|
||||
|
||||
type LinkTable struct {
|
||||
linkTable
|
||||
|
||||
EXCLUDED linkTable
|
||||
}
|
||||
|
||||
// AS creates new LinkTable with assigned alias
|
||||
func (a LinkTable) AS(alias string) *LinkTable {
|
||||
return newLinkTable(a.SchemaName(), a.TableName(), alias)
|
||||
}
|
||||
|
||||
// Schema creates new LinkTable with assigned schema name
|
||||
func (a LinkTable) FromSchema(schemaName string) *LinkTable {
|
||||
return newLinkTable(schemaName, a.TableName(), a.Alias())
|
||||
}
|
||||
|
||||
// WithPrefix creates new LinkTable with assigned table prefix
|
||||
func (a LinkTable) WithPrefix(prefix string) *LinkTable {
|
||||
return newLinkTable(a.SchemaName(), prefix+a.TableName(), a.TableName())
|
||||
}
|
||||
|
||||
// WithSuffix creates new LinkTable with assigned table suffix
|
||||
func (a LinkTable) WithSuffix(suffix string) *LinkTable {
|
||||
return newLinkTable(a.SchemaName(), a.TableName()+suffix, a.TableName())
|
||||
}
|
||||
|
||||
func newLinkTable(schemaName, tableName, alias string) *LinkTable {
|
||||
return &LinkTable{
|
||||
linkTable: newLinkTableImpl(schemaName, tableName, alias),
|
||||
EXCLUDED: newLinkTableImpl("", "excluded", ""),
|
||||
}
|
||||
}
|
||||
|
||||
func newLinkTableImpl(schemaName, tableName, alias string) linkTable {
|
||||
var (
|
||||
IDColumn = postgres.IntegerColumn("id")
|
||||
URLColumn = postgres.StringColumn("url")
|
||||
NameColumn = postgres.StringColumn("name")
|
||||
DescriptionColumn = postgres.StringColumn("description")
|
||||
allColumns = postgres.ColumnList{IDColumn, URLColumn, NameColumn, DescriptionColumn}
|
||||
mutableColumns = postgres.ColumnList{URLColumn, NameColumn, DescriptionColumn}
|
||||
)
|
||||
|
||||
return linkTable{
|
||||
Table: postgres.NewTable(schemaName, tableName, alias, allColumns...),
|
||||
|
||||
//Columns
|
||||
ID: IDColumn,
|
||||
URL: URLColumn,
|
||||
Name: NameColumn,
|
||||
Description: DescriptionColumn,
|
||||
|
||||
AllColumns: allColumns,
|
||||
MutableColumns: mutableColumns,
|
||||
}
|
||||
}
|
||||
`
|
||||
|
|
|
|||
|
|
@ -93,9 +93,9 @@ func TestInsertOnConflict(t *testing.T) {
|
|||
ON_CONFLICT().DO_NOTHING()
|
||||
|
||||
testutils.AssertStatementSql(t, stmt, `
|
||||
INSERT INTO test_sample.employee (employee_id, first_name, last_name, employment_date, manager_id)
|
||||
VALUES ($1, $2, $3, $4, $5),
|
||||
($6, $7, $8, $9, $10)
|
||||
INSERT INTO test_sample.employee (employee_id, first_name, last_name, employment_date, manager_id, pto_accrual)
|
||||
VALUES ($1, $2, $3, $4, $5, $6),
|
||||
($7, $8, $9, $10, $11, $12)
|
||||
ON CONFLICT DO NOTHING;
|
||||
`)
|
||||
testutils.AssertExecAndRollback(t, stmt, db, 1)
|
||||
|
|
@ -111,9 +111,9 @@ ON CONFLICT DO NOTHING;
|
|||
ON_CONFLICT(Employee.EmployeeID).DO_NOTHING()
|
||||
|
||||
testutils.AssertStatementSql(t, stmt, `
|
||||
INSERT INTO test_sample.employee (employee_id, first_name, last_name, employment_date, manager_id)
|
||||
VALUES ($1, $2, $3, $4, $5),
|
||||
($6, $7, $8, $9, $10)
|
||||
INSERT INTO test_sample.employee (employee_id, first_name, last_name, employment_date, manager_id, pto_accrual)
|
||||
VALUES ($1, $2, $3, $4, $5, $6),
|
||||
($7, $8, $9, $10, $11, $12)
|
||||
ON CONFLICT (employee_id) DO NOTHING;
|
||||
`)
|
||||
testutils.AssertExecAndRollback(t, stmt, db, 1)
|
||||
|
|
@ -130,9 +130,9 @@ ON CONFLICT (employee_id) DO NOTHING;
|
|||
ON_CONFLICT().ON_CONSTRAINT("employee_pkey").DO_NOTHING()
|
||||
|
||||
testutils.AssertStatementSql(t, stmt, `
|
||||
INSERT INTO test_sample.employee (employee_id, first_name, last_name, employment_date, manager_id)
|
||||
VALUES ($1, $2, $3, $4, $5),
|
||||
($6, $7, $8, $9, $10)
|
||||
INSERT INTO test_sample.employee (employee_id, first_name, last_name, employment_date, manager_id, pto_accrual)
|
||||
VALUES ($1, $2, $3, $4, $5, $6),
|
||||
($7, $8, $9, $10, $11, $12)
|
||||
ON CONFLICT ON CONSTRAINT employee_pkey DO NOTHING;
|
||||
`)
|
||||
testutils.AssertExecAndRollback(t, stmt, db, 1)
|
||||
|
|
@ -234,8 +234,8 @@ ON CONFLICT (id) WHERE (id * 2) > 10 DO UPDATE
|
|||
ON_CONFLICT().DO_UPDATE(nil)
|
||||
|
||||
testutils.AssertStatementSql(t, stmt, `
|
||||
INSERT INTO test_sample.employee (employee_id, first_name, last_name, employment_date, manager_id)
|
||||
VALUES ($1, $2, $3, $4, $5);
|
||||
INSERT INTO test_sample.employee (employee_id, first_name, last_name, employment_date, manager_id, pto_accrual)
|
||||
VALUES ($1, $2, $3, $4, $5, $6);
|
||||
`)
|
||||
testutils.AssertExecAndRollback(t, stmt, db, 1)
|
||||
requireLogged(t, stmt)
|
||||
|
|
|
|||
|
|
@ -5,13 +5,10 @@ import (
|
|||
"database/sql"
|
||||
"fmt"
|
||||
"github.com/go-jet/jet/v2/tests/internal/utils/repo"
|
||||
"math/rand"
|
||||
"github.com/jackc/pgx/v4/stdlib"
|
||||
"os"
|
||||
"runtime"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/jackc/pgx/v4/stdlib"
|
||||
|
||||
"github.com/go-jet/jet/v2/postgres"
|
||||
"github.com/go-jet/jet/v2/tests/dbconfig"
|
||||
|
|
@ -44,7 +41,6 @@ func skipForCockroachDB(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
rand.Seed(time.Now().Unix())
|
||||
defer profile.Start().Stop()
|
||||
|
||||
setTestRoot()
|
||||
|
|
|
|||
|
|
@ -11,34 +11,31 @@ import (
|
|||
|
||||
func TestNorthwindJoinEverything(t *testing.T) {
|
||||
|
||||
stmt := SELECT(
|
||||
Customers.AllColumns,
|
||||
CustomerDemographics.AllColumns,
|
||||
Orders.AllColumns,
|
||||
Shippers.AllColumns,
|
||||
OrderDetails.AllColumns,
|
||||
Products.AllColumns,
|
||||
Categories.AllColumns,
|
||||
Suppliers.AllColumns,
|
||||
).FROM(
|
||||
Customers.
|
||||
LEFT_JOIN(CustomerCustomerDemo, Customers.CustomerID.EQ(CustomerCustomerDemo.CustomerID)).
|
||||
LEFT_JOIN(CustomerDemographics, CustomerCustomerDemo.CustomerTypeID.EQ(CustomerDemographics.CustomerTypeID)).
|
||||
LEFT_JOIN(Orders, Orders.CustomerID.EQ(Customers.CustomerID)).
|
||||
LEFT_JOIN(Shippers, Orders.ShipVia.EQ(Shippers.ShipperID)).
|
||||
LEFT_JOIN(OrderDetails, Orders.OrderID.EQ(OrderDetails.OrderID)).
|
||||
LEFT_JOIN(Products, OrderDetails.ProductID.EQ(Products.ProductID)).
|
||||
LEFT_JOIN(Categories, Products.CategoryID.EQ(Categories.CategoryID)).
|
||||
LEFT_JOIN(Suppliers, Products.SupplierID.EQ(Suppliers.SupplierID)).
|
||||
LEFT_JOIN(Employees, Orders.EmployeeID.EQ(Employees.EmployeeID)).
|
||||
LEFT_JOIN(EmployeeTerritories, EmployeeTerritories.EmployeeID.EQ(Employees.EmployeeID)).
|
||||
LEFT_JOIN(Territories, EmployeeTerritories.TerritoryID.EQ(Territories.TerritoryID)).
|
||||
LEFT_JOIN(Region, Territories.RegionID.EQ(Region.RegionID)),
|
||||
).ORDER_BY(
|
||||
Customers.CustomerID,
|
||||
Orders.OrderID,
|
||||
Products.ProductID,
|
||||
)
|
||||
stmt :=
|
||||
SELECT(
|
||||
Customers.AllColumns,
|
||||
CustomerDemographics.AllColumns,
|
||||
Orders.AllColumns,
|
||||
Shippers.AllColumns,
|
||||
OrderDetails.AllColumns,
|
||||
Products.AllColumns,
|
||||
Categories.AllColumns,
|
||||
Suppliers.AllColumns,
|
||||
).FROM(
|
||||
Customers.
|
||||
LEFT_JOIN(CustomerCustomerDemo, Customers.CustomerID.EQ(CustomerCustomerDemo.CustomerID)).
|
||||
LEFT_JOIN(CustomerDemographics, CustomerCustomerDemo.CustomerTypeID.EQ(CustomerDemographics.CustomerTypeID)).
|
||||
LEFT_JOIN(Orders, Orders.CustomerID.EQ(Customers.CustomerID)).
|
||||
LEFT_JOIN(Shippers, Orders.ShipVia.EQ(Shippers.ShipperID)).
|
||||
LEFT_JOIN(OrderDetails, Orders.OrderID.EQ(OrderDetails.OrderID)).
|
||||
LEFT_JOIN(Products, OrderDetails.ProductID.EQ(Products.ProductID)).
|
||||
LEFT_JOIN(Categories, Products.CategoryID.EQ(Categories.CategoryID)).
|
||||
LEFT_JOIN(Suppliers, Products.SupplierID.EQ(Suppliers.SupplierID)).
|
||||
LEFT_JOIN(Employees, Orders.EmployeeID.EQ(Employees.EmployeeID)).
|
||||
LEFT_JOIN(EmployeeTerritories, EmployeeTerritories.EmployeeID.EQ(Employees.EmployeeID)).
|
||||
LEFT_JOIN(Territories, EmployeeTerritories.TerritoryID.EQ(Territories.TerritoryID)).
|
||||
LEFT_JOIN(Region, Territories.RegionID.EQ(Region.RegionID)),
|
||||
).ORDER_BY(Customers.CustomerID, Orders.OrderID, Products.ProductID)
|
||||
|
||||
var dest []struct {
|
||||
model.Customers
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package postgres
|
|||
|
||||
import (
|
||||
"github.com/go-jet/jet/v2/qrm"
|
||||
"github.com/go-jet/jet/v2/internal/utils/ptr"
|
||||
"github.com/google/uuid"
|
||||
"testing"
|
||||
|
||||
|
|
@ -63,15 +64,15 @@ func TestExactDecimals(t *testing.T) {
|
|||
Floats: model.Floats{
|
||||
// overwritten by wrapped(floats) scope
|
||||
Numeric: 0.1,
|
||||
NumericPtr: testutils.Float64Ptr(0.1),
|
||||
NumericPtr: ptr.Of(0.1),
|
||||
Decimal: 0.1,
|
||||
DecimalPtr: testutils.Float64Ptr(0.1),
|
||||
DecimalPtr: ptr.Of(0.1),
|
||||
|
||||
// not overwritten
|
||||
Real: 0.4,
|
||||
RealPtr: testutils.Float32Ptr(0.44),
|
||||
RealPtr: ptr.Of(float32(0.44)),
|
||||
Double: 0.3,
|
||||
DoublePtr: testutils.Float64Ptr(0.33),
|
||||
DoublePtr: ptr.Of(0.33),
|
||||
},
|
||||
Numeric: decimal.RequireFromString("0.1234567890123456789"),
|
||||
NumericPtr: decimal.RequireFromString("1.1111111111111111111"),
|
||||
|
|
@ -330,11 +331,13 @@ SELECT employee.employee_id AS "employee.employee_id",
|
|||
employee.last_name AS "employee.last_name",
|
||||
employee.employment_date AS "employee.employment_date",
|
||||
employee.manager_id AS "employee.manager_id",
|
||||
employee.pto_accrual AS "employee.pto_accrual",
|
||||
manager.employee_id AS "manager.employee_id",
|
||||
manager.first_name AS "manager.first_name",
|
||||
manager.last_name AS "manager.last_name",
|
||||
manager.employment_date AS "manager.employment_date",
|
||||
manager.manager_id AS "manager.manager_id"
|
||||
manager.manager_id AS "manager.manager_id",
|
||||
manager.pto_accrual AS "manager.pto_accrual"
|
||||
FROM test_sample.employee
|
||||
LEFT JOIN test_sample.employee AS manager ON (manager.employee_id = employee.manager_id)
|
||||
ORDER BY employee.employee_id;
|
||||
|
|
@ -369,6 +372,7 @@ ORDER BY employee.employee_id;
|
|||
LastName: "Hays",
|
||||
EmploymentDate: testutils.TimestampWithTimeZone("1999-01-08 04:05:06.1 +0100 CET", 1),
|
||||
ManagerID: nil,
|
||||
PtoAccrual: ptr.Of("22:00:00"),
|
||||
})
|
||||
|
||||
require.True(t, dest[0].Manager == nil)
|
||||
|
|
@ -378,7 +382,7 @@ ORDER BY employee.employee_id;
|
|||
FirstName: "Salley",
|
||||
LastName: "Lester",
|
||||
EmploymentDate: testutils.TimestampWithTimeZone("1999-01-08 04:05:06 +0100 CET", 1),
|
||||
ManagerID: testutils.Int32Ptr(3),
|
||||
ManagerID: ptr.Of(int32(3)),
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -420,7 +424,7 @@ FROM test_sample."WEIRD NAMES TABLE";
|
|||
WeirdColumnName5: "Doe",
|
||||
WeirdColumnName6: "Doe",
|
||||
WeirdColumnName7: "Doe",
|
||||
Weirdcolumnname8: testutils.StringPtr("Doe"),
|
||||
Weirdcolumnname8: ptr.Of("Doe"),
|
||||
WeirdColName9: "Doe",
|
||||
WeirdColuName10: "Doe",
|
||||
WeirdColuName11: "Doe",
|
||||
|
|
@ -518,7 +522,7 @@ func TestMutableColumnsExcludeGeneratedColumn(t *testing.T) {
|
|||
).MODEL(
|
||||
model.People{
|
||||
PeopleName: "Dario",
|
||||
PeopleHeightCm: testutils.Float64Ptr(120),
|
||||
PeopleHeightCm: ptr.Of(120.0),
|
||||
},
|
||||
).RETURNING(
|
||||
People.MutableColumns,
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package postgres
|
|||
|
||||
import (
|
||||
"context"
|
||||
"github.com/go-jet/jet/v2/internal/utils/ptr"
|
||||
"github.com/volatiletech/null/v8"
|
||||
"testing"
|
||||
"time"
|
||||
|
|
@ -93,7 +94,7 @@ func TestScanToValidDestination(t *testing.T) {
|
|||
|
||||
err := oneInventoryQuery.Query(db, &dest)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, dest[0], testutils.Int32Ptr(1))
|
||||
require.Equal(t, dest[0], ptr.Of(int32(1)))
|
||||
})
|
||||
|
||||
t.Run("NULL to integer", func(t *testing.T) {
|
||||
|
|
@ -530,10 +531,10 @@ func TestScanToSlice(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
require.Equal(t, len(dest), 2)
|
||||
testutils.AssertDeepEqual(t, dest[0].Film, film1)
|
||||
testutils.AssertDeepEqual(t, dest[0].IDs, []*int32{testutils.Int32Ptr(1), testutils.Int32Ptr(2), testutils.Int32Ptr(3), testutils.Int32Ptr(4),
|
||||
testutils.Int32Ptr(5), testutils.Int32Ptr(6), testutils.Int32Ptr(7), testutils.Int32Ptr(8)})
|
||||
testutils.AssertDeepEqual(t, dest[0].IDs, []*int32{ptr.Of(int32(1)), ptr.Of(int32(2)), ptr.Of(int32(3)), ptr.Of(int32(4)),
|
||||
ptr.Of(int32(5)), ptr.Of(int32(6)), ptr.Of(int32(7)), ptr.Of(int32(8))})
|
||||
testutils.AssertDeepEqual(t, dest[1].Film, film2)
|
||||
testutils.AssertDeepEqual(t, dest[1].IDs, []*int32{testutils.Int32Ptr(9), testutils.Int32Ptr(10)})
|
||||
testutils.AssertDeepEqual(t, dest[1].IDs, []*int32{ptr.Of(int32(9)), ptr.Of(int32(10))})
|
||||
})
|
||||
|
||||
t.Run("complex struct 1", func(t *testing.T) {
|
||||
|
|
@ -1076,10 +1077,10 @@ VALUES (1234, 0, 'Joe', '', NULL, 1, TRUE, '2020-02-02 10:00:00Z', NULL, 1);
|
|||
var address256 = model.Address{
|
||||
AddressID: 256,
|
||||
Address: "1497 Yuzhou Drive",
|
||||
Address2: testutils.StringPtr(""),
|
||||
Address2: ptr.Of(""),
|
||||
District: "England",
|
||||
CityID: 312,
|
||||
PostalCode: testutils.StringPtr("3433"),
|
||||
PostalCode: ptr.Of("3433"),
|
||||
Phone: "246810237916",
|
||||
LastUpdate: *testutils.TimestampWithoutTimeZone("2006-02-15 09:45:30", 0),
|
||||
}
|
||||
|
|
@ -1087,10 +1088,10 @@ var address256 = model.Address{
|
|||
var addres517 = model.Address{
|
||||
AddressID: 517,
|
||||
Address: "548 Uruapan Street",
|
||||
Address2: testutils.StringPtr(""),
|
||||
Address2: ptr.Of(""),
|
||||
District: "Ontario",
|
||||
CityID: 312,
|
||||
PostalCode: testutils.StringPtr("35653"),
|
||||
PostalCode: ptr.Of("35653"),
|
||||
Phone: "879347453467",
|
||||
LastUpdate: *testutils.TimestampWithoutTimeZone("2006-02-15 09:45:30", 0),
|
||||
}
|
||||
|
|
@ -1100,12 +1101,12 @@ var customer256 = model.Customer{
|
|||
StoreID: 2,
|
||||
FirstName: "Mattie",
|
||||
LastName: "Hoffman",
|
||||
Email: testutils.StringPtr("mattie.hoffman@sakilacustomer.org"),
|
||||
Email: ptr.Of("mattie.hoffman@sakilacustomer.org"),
|
||||
AddressID: 256,
|
||||
Activebool: true,
|
||||
CreateDate: *testutils.TimestampWithoutTimeZone("2006-02-14 00:00:00", 0),
|
||||
LastUpdate: testutils.TimestampWithoutTimeZone("2013-05-26 14:49:45.738", 0),
|
||||
Active: testutils.Int32Ptr(1),
|
||||
Active: ptr.Of(int32(1)),
|
||||
}
|
||||
|
||||
var customer512 = model.Customer{
|
||||
|
|
@ -1113,12 +1114,12 @@ var customer512 = model.Customer{
|
|||
StoreID: 1,
|
||||
FirstName: "Cecil",
|
||||
LastName: "Vines",
|
||||
Email: testutils.StringPtr("cecil.vines@sakilacustomer.org"),
|
||||
Email: ptr.Of("cecil.vines@sakilacustomer.org"),
|
||||
AddressID: 517,
|
||||
Activebool: true,
|
||||
CreateDate: *testutils.TimestampWithoutTimeZone("2006-02-14 00:00:00", 0),
|
||||
LastUpdate: testutils.TimestampWithoutTimeZone("2013-05-26 14:49:45.738", 0),
|
||||
Active: testutils.Int32Ptr(1),
|
||||
Active: ptr.Of(int32(1)),
|
||||
}
|
||||
|
||||
var countryUk = model.Country{
|
||||
|
|
@ -1151,32 +1152,32 @@ var inventory2 = model.Inventory{
|
|||
var film1 = model.Film{
|
||||
FilmID: 1,
|
||||
Title: "Academy Dinosaur",
|
||||
Description: testutils.StringPtr("A Epic Drama of a Feminist And a Mad Scientist who must Battle a Teacher in The Canadian Rockies"),
|
||||
ReleaseYear: testutils.Int32Ptr(2006),
|
||||
Description: ptr.Of("A Epic Drama of a Feminist And a Mad Scientist who must Battle a Teacher in The Canadian Rockies"),
|
||||
ReleaseYear: ptr.Of(int32(2006)),
|
||||
LanguageID: 1,
|
||||
RentalDuration: 6,
|
||||
RentalRate: 0.99,
|
||||
Length: testutils.Int16Ptr(86),
|
||||
Length: ptr.Of(int16(86)),
|
||||
ReplacementCost: 20.99,
|
||||
Rating: &pgRating,
|
||||
LastUpdate: *testutils.TimestampWithoutTimeZone("2013-05-26 14:50:58.951", 3),
|
||||
SpecialFeatures: testutils.StringPtr("{\"Deleted Scenes\",\"Behind the Scenes\"}"),
|
||||
SpecialFeatures: ptr.Of("{\"Deleted Scenes\",\"Behind the Scenes\"}"),
|
||||
Fulltext: "'academi':1 'battl':15 'canadian':20 'dinosaur':2 'drama':5 'epic':4 'feminist':8 'mad':11 'must':14 'rocki':21 'scientist':12 'teacher':17",
|
||||
}
|
||||
|
||||
var film2 = model.Film{
|
||||
FilmID: 2,
|
||||
Title: "Ace Goldfinger",
|
||||
Description: testutils.StringPtr("A Astounding Epistle of a Database Administrator And a Explorer who must Find a Car in Ancient China"),
|
||||
ReleaseYear: testutils.Int32Ptr(2006),
|
||||
Description: ptr.Of("A Astounding Epistle of a Database Administrator And a Explorer who must Find a Car in Ancient China"),
|
||||
ReleaseYear: ptr.Of(int32(2006)),
|
||||
LanguageID: 1,
|
||||
RentalDuration: 3,
|
||||
RentalRate: 4.99,
|
||||
Length: testutils.Int16Ptr(48),
|
||||
Length: ptr.Of(int16(48)),
|
||||
ReplacementCost: 12.99,
|
||||
Rating: &gRating,
|
||||
LastUpdate: *testutils.TimestampWithoutTimeZone("2013-05-26 14:50:58.951", 3),
|
||||
SpecialFeatures: testutils.StringPtr(`{Trailers,"Deleted Scenes"}`),
|
||||
SpecialFeatures: ptr.Of(`{Trailers,"Deleted Scenes"}`),
|
||||
Fulltext: `'ace':1 'administr':9 'ancient':19 'astound':4 'car':17 'china':20 'databas':8 'epistl':5 'explor':12 'find':15 'goldfing':2 'must':14`,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package postgres
|
|||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"github.com/go-jet/jet/v2/internal/utils/ptr"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
|
|
@ -1828,16 +1829,16 @@ ORDER BY film.film_id ASC;
|
|||
testutils.AssertDeepEqual(t, maxRentalRateFilms[0], model.Film{
|
||||
FilmID: 2,
|
||||
Title: "Ace Goldfinger",
|
||||
Description: testutils.StringPtr("A Astounding Epistle of a Database Administrator And a Explorer who must Find a Car in Ancient China"),
|
||||
ReleaseYear: testutils.Int32Ptr(2006),
|
||||
Description: ptr.Of("A Astounding Epistle of a Database Administrator And a Explorer who must Find a Car in Ancient China"),
|
||||
ReleaseYear: ptr.Of(int32(2006)),
|
||||
LanguageID: 1,
|
||||
RentalRate: 4.99,
|
||||
Length: testutils.Int16Ptr(48),
|
||||
Length: ptr.Of(int16(48)),
|
||||
ReplacementCost: 12.99,
|
||||
Rating: &gRating,
|
||||
RentalDuration: 3,
|
||||
LastUpdate: *testutils.TimestampWithoutTimeZone("2013-05-26 14:50:58.951", 3),
|
||||
SpecialFeatures: testutils.StringPtr("{Trailers,\"Deleted Scenes\"}"),
|
||||
SpecialFeatures: ptr.Of("{Trailers,\"Deleted Scenes\"}"),
|
||||
Fulltext: "'ace':1 'administr':9 'ancient':19 'astound':4 'car':17 'china':20 'databas':8 'epistl':5 'explor':12 'find':15 'goldfing':2 'must':14",
|
||||
})
|
||||
}
|
||||
|
|
@ -2286,11 +2287,11 @@ ORDER BY customer_payment_sum.amount_sum ASC;
|
|||
FirstName: "Brian",
|
||||
LastName: "Wyman",
|
||||
AddressID: 323,
|
||||
Email: testutils.StringPtr("brian.wyman@sakilacustomer.org"),
|
||||
Email: ptr.Of("brian.wyman@sakilacustomer.org"),
|
||||
Activebool: true,
|
||||
CreateDate: *testutils.TimestampWithoutTimeZone("2006-02-14 00:00:00", 0),
|
||||
LastUpdate: testutils.TimestampWithoutTimeZone("2013-05-26 14:49:45.738", 3),
|
||||
Active: testutils.Int32Ptr(1),
|
||||
Active: ptr.Of(int32(1)),
|
||||
})
|
||||
|
||||
require.Equal(t, customersWithAmounts[0].AmountSum, 27.93)
|
||||
|
|
@ -3110,8 +3111,8 @@ func TestSelectDynamicCondition(t *testing.T) {
|
|||
Active *bool
|
||||
}
|
||||
|
||||
request.CustomerID = testutils.Int64Ptr(1)
|
||||
request.Active = testutils.BoolPtr(true)
|
||||
request.CustomerID = ptr.Of(int64(1))
|
||||
request.Active = ptr.Of(true)
|
||||
|
||||
// ...
|
||||
|
||||
|
|
@ -3871,12 +3872,12 @@ var customer0 = model.Customer{
|
|||
StoreID: 1,
|
||||
FirstName: "Mary",
|
||||
LastName: "Smith",
|
||||
Email: testutils.StringPtr("mary.smith@sakilacustomer.org"),
|
||||
Email: ptr.Of("mary.smith@sakilacustomer.org"),
|
||||
AddressID: 5,
|
||||
Activebool: true,
|
||||
CreateDate: *testutils.TimestampWithoutTimeZone("2006-02-14 00:00:00", 0),
|
||||
LastUpdate: testutils.TimestampWithoutTimeZone("2013-05-26 14:49:45.738", 3),
|
||||
Active: testutils.Int32Ptr(1),
|
||||
Active: ptr.Of(int32(1)),
|
||||
}
|
||||
|
||||
var customer1 = model.Customer{
|
||||
|
|
@ -3884,12 +3885,12 @@ var customer1 = model.Customer{
|
|||
StoreID: 1,
|
||||
FirstName: "Patricia",
|
||||
LastName: "Johnson",
|
||||
Email: testutils.StringPtr("patricia.johnson@sakilacustomer.org"),
|
||||
Email: ptr.Of("patricia.johnson@sakilacustomer.org"),
|
||||
AddressID: 6,
|
||||
Activebool: true,
|
||||
CreateDate: *testutils.TimestampWithoutTimeZone("2006-02-14 00:00:00", 0),
|
||||
LastUpdate: testutils.TimestampWithoutTimeZone("2013-05-26 14:49:45.738", 3),
|
||||
Active: testutils.Int32Ptr(1),
|
||||
Active: ptr.Of(int32(1)),
|
||||
}
|
||||
|
||||
var lastCustomer = model.Customer{
|
||||
|
|
@ -3897,10 +3898,10 @@ var lastCustomer = model.Customer{
|
|||
StoreID: 2,
|
||||
FirstName: "Austin",
|
||||
LastName: "Cintron",
|
||||
Email: testutils.StringPtr("austin.cintron@sakilacustomer.org"),
|
||||
Email: ptr.Of("austin.cintron@sakilacustomer.org"),
|
||||
AddressID: 605,
|
||||
Activebool: true,
|
||||
CreateDate: *testutils.TimestampWithoutTimeZone("2006-02-14 00:00:00", 0),
|
||||
LastUpdate: testutils.TimestampWithoutTimeZone("2013-05-26 14:49:45.738", 3),
|
||||
Active: testutils.Int32Ptr(1),
|
||||
Active: ptr.Of(int32(1)),
|
||||
}
|
||||
|
|
|
|||
284
tests/postgres/values_test.go
Normal file
284
tests/postgres/values_test.go
Normal file
|
|
@ -0,0 +1,284 @@
|
|||
package postgres
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"github.com/go-jet/jet/v2/internal/testutils"
|
||||
. "github.com/go-jet/jet/v2/postgres"
|
||||
"github.com/go-jet/jet/v2/tests/.gentestdata/jetdb/dvds/model"
|
||||
. "github.com/go-jet/jet/v2/tests/.gentestdata/jetdb/dvds/table"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestVALUES(t *testing.T) {
|
||||
|
||||
values := VALUES(
|
||||
WRAP(Int32(1), Int32(2), Float32(4.666), Bool(false), String("txt")),
|
||||
WRAP(Int32(11).ADD(Int32(2)), Int32(22), Float32(33.222), Bool(true), String("png")),
|
||||
WRAP(Int32(11), Int32(22), Float32(33.222), Bool(true), NULL),
|
||||
).AS("values_table")
|
||||
|
||||
stmt := SELECT(
|
||||
values.AllColumns(),
|
||||
).FROM(
|
||||
values,
|
||||
)
|
||||
|
||||
testutils.AssertStatementSql(t, stmt, `
|
||||
SELECT values_table.column1 AS "column1",
|
||||
values_table.column2 AS "column2",
|
||||
values_table.column3 AS "column3",
|
||||
values_table.column4 AS "column4",
|
||||
values_table.column5 AS "column5"
|
||||
FROM (
|
||||
VALUES ($1::integer, $2::integer, $3::real, $4::boolean, $5::text),
|
||||
($6::integer + $7::integer, $8::integer, $9::real, $10::boolean, $11::text),
|
||||
($12::integer, $13::integer, $14::real, $15::boolean, NULL)
|
||||
) AS values_table;
|
||||
`)
|
||||
|
||||
var dest []struct {
|
||||
Column1 int
|
||||
Column2 int
|
||||
Column3 float32
|
||||
Column4 bool
|
||||
Column5 *string
|
||||
}
|
||||
|
||||
err := stmt.Query(db, &dest)
|
||||
|
||||
require.NoError(t, err)
|
||||
testutils.AssertJSON(t, dest, `
|
||||
[
|
||||
{
|
||||
"Column1": 1,
|
||||
"Column2": 2,
|
||||
"Column3": 4.666,
|
||||
"Column4": false,
|
||||
"Column5": "txt"
|
||||
},
|
||||
{
|
||||
"Column1": 13,
|
||||
"Column2": 22,
|
||||
"Column3": 33.222,
|
||||
"Column4": true,
|
||||
"Column5": "png"
|
||||
},
|
||||
{
|
||||
"Column1": 11,
|
||||
"Column2": 22,
|
||||
"Column3": 33.222,
|
||||
"Column4": true,
|
||||
"Column5": null
|
||||
}
|
||||
]
|
||||
`)
|
||||
}
|
||||
|
||||
func TestVALUES_Join(t *testing.T) {
|
||||
|
||||
title := StringColumn("title")
|
||||
releaseYear := IntegerColumn("ReleaseYear")
|
||||
rentalRate := FloatColumn("rental_rate")
|
||||
|
||||
lastUpdate := Timestamp(2007, time.February, 11, 12, 0, 0)
|
||||
|
||||
filmValues := VALUES(
|
||||
WRAP(String("Chamber Italian"), Int64(117), Int32(2005), Float32(5.82), lastUpdate),
|
||||
WRAP(String("Grosse Wonderful"), Int64(49), Int32(2004), Float32(6.242), lastUpdate.ADD(INTERVAL(1, HOUR))),
|
||||
WRAP(String("Airport Pollock"), Int64(54), Int32(2001), Float32(7.22), NULL),
|
||||
WRAP(String("Bright Encounters"), Int64(73), Int32(2002), Float32(8.25), NULL),
|
||||
WRAP(String("Academy Dinosaur"), Int64(83), Int32(2010), Float32(9.22), lastUpdate.SUB(INTERVAL(2, MINUTE))),
|
||||
).AS("film_values",
|
||||
title, IntegerColumn("length"), releaseYear, rentalRate, TimestampColumn("update_date"))
|
||||
|
||||
stmt := SELECT(
|
||||
Film.AllColumns,
|
||||
filmValues.AllColumns(),
|
||||
).FROM(
|
||||
Film.
|
||||
INNER_JOIN(filmValues, title.EQ(Film.Title)),
|
||||
).WHERE(AND(
|
||||
Film.ReleaseYear.GT(releaseYear),
|
||||
Film.RentalRate.LT(rentalRate),
|
||||
)).ORDER_BY(
|
||||
title,
|
||||
)
|
||||
|
||||
testutils.AssertDebugStatementSql(t, stmt, `
|
||||
SELECT film.film_id AS "film.film_id",
|
||||
film.title AS "film.title",
|
||||
film.description AS "film.description",
|
||||
film.release_year AS "film.release_year",
|
||||
film.language_id AS "film.language_id",
|
||||
film.rental_duration AS "film.rental_duration",
|
||||
film.rental_rate AS "film.rental_rate",
|
||||
film.length AS "film.length",
|
||||
film.replacement_cost AS "film.replacement_cost",
|
||||
film.rating AS "film.rating",
|
||||
film.last_update AS "film.last_update",
|
||||
film.special_features AS "film.special_features",
|
||||
film.fulltext AS "film.fulltext",
|
||||
film_values.title AS "title",
|
||||
film_values.length AS "length",
|
||||
film_values."ReleaseYear" AS "ReleaseYear",
|
||||
film_values.rental_rate AS "rental_rate",
|
||||
film_values.update_date AS "update_date"
|
||||
FROM dvds.film
|
||||
INNER JOIN (
|
||||
VALUES ('Chamber Italian'::text, 117::bigint, 2005::integer, 5.820000171661377::real, '2007-02-11 12:00:00'::timestamp without time zone),
|
||||
('Grosse Wonderful'::text, 49::bigint, 2004::integer, 6.242000102996826::real, '2007-02-11 12:00:00'::timestamp without time zone + INTERVAL '1 HOUR'),
|
||||
('Airport Pollock'::text, 54::bigint, 2001::integer, 7.21999979019165::real, NULL),
|
||||
('Bright Encounters'::text, 73::bigint, 2002::integer, 8.25::real, NULL),
|
||||
('Academy Dinosaur'::text, 83::bigint, 2010::integer, 9.220000267028809::real, '2007-02-11 12:00:00'::timestamp without time zone - INTERVAL '2 MINUTE')
|
||||
) AS film_values (title, length, "ReleaseYear", rental_rate, update_date) ON (film_values.title = film.title)
|
||||
WHERE (
|
||||
(film.release_year > film_values."ReleaseYear")
|
||||
AND (film.rental_rate < film_values.rental_rate)
|
||||
)
|
||||
ORDER BY film_values.title;
|
||||
`)
|
||||
|
||||
//fmt.Println(stmt.DebugSql())
|
||||
|
||||
var dest []struct {
|
||||
Film model.Film
|
||||
|
||||
Title string
|
||||
Length int
|
||||
ReleaseYear int
|
||||
RentalRate float32
|
||||
UpdateDate *time.Time
|
||||
}
|
||||
|
||||
err := stmt.Query(db, &dest)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Len(t, dest, 4)
|
||||
testutils.AssertJSON(t, dest[0:2], `
|
||||
[
|
||||
{
|
||||
"Film": {
|
||||
"FilmID": 8,
|
||||
"Title": "Airport Pollock",
|
||||
"Description": "A Epic Tale of a Moose And a Girl who must Confront a Monkey in Ancient India",
|
||||
"ReleaseYear": 2006,
|
||||
"LanguageID": 1,
|
||||
"RentalDuration": 6,
|
||||
"RentalRate": 4.99,
|
||||
"Length": 54,
|
||||
"ReplacementCost": 15.99,
|
||||
"Rating": "R",
|
||||
"LastUpdate": "2013-05-26T14:50:58.951Z",
|
||||
"SpecialFeatures": "{Trailers}",
|
||||
"Fulltext": "'airport':1 'ancient':18 'confront':14 'epic':4 'girl':11 'india':19 'monkey':16 'moos':8 'must':13 'pollock':2 'tale':5"
|
||||
},
|
||||
"Title": "Airport Pollock",
|
||||
"Length": 54,
|
||||
"ReleaseYear": 2001,
|
||||
"RentalRate": 7.22,
|
||||
"UpdateDate": null
|
||||
},
|
||||
{
|
||||
"Film": {
|
||||
"FilmID": 98,
|
||||
"Title": "Bright Encounters",
|
||||
"Description": "A Fateful Yarn of a Lumberjack And a Feminist who must Conquer a Student in A Jet Boat",
|
||||
"ReleaseYear": 2006,
|
||||
"LanguageID": 1,
|
||||
"RentalDuration": 4,
|
||||
"RentalRate": 4.99,
|
||||
"Length": 73,
|
||||
"ReplacementCost": 12.99,
|
||||
"Rating": "PG-13",
|
||||
"LastUpdate": "2013-05-26T14:50:58.951Z",
|
||||
"SpecialFeatures": "{Trailers}",
|
||||
"Fulltext": "'boat':20 'bright':1 'conquer':14 'encount':2 'fate':4 'feminist':11 'jet':19 'lumberjack':8 'must':13 'student':16 'yarn':5"
|
||||
},
|
||||
"Title": "Bright Encounters",
|
||||
"Length": 73,
|
||||
"ReleaseYear": 2002,
|
||||
"RentalRate": 8.25,
|
||||
"UpdateDate": null
|
||||
}
|
||||
]
|
||||
`)
|
||||
}
|
||||
|
||||
func TestVALUES_CTE_Update(t *testing.T) {
|
||||
|
||||
paymentID := IntegerColumn("payment_ID")
|
||||
increase := FloatColumn("increase")
|
||||
paymentsToUpdate := CTE("values_cte", paymentID, increase)
|
||||
|
||||
stmt := WITH(
|
||||
paymentsToUpdate.AS(
|
||||
VALUES(
|
||||
WRAP(Int32(20564), Float32(1.21)),
|
||||
WRAP(Int32(20567), Float32(1.02)),
|
||||
WRAP(Int32(20570), Float32(1.34)),
|
||||
WRAP(Int32(20573), Float32(1.72)),
|
||||
),
|
||||
),
|
||||
)(
|
||||
Payment.UPDATE().
|
||||
SET(
|
||||
Payment.Amount.SET(Payment.Amount.MUL(CAST(increase).AS_DECIMAL())),
|
||||
).
|
||||
FROM(paymentsToUpdate).
|
||||
WHERE(Payment.PaymentID.EQ(paymentID)).
|
||||
RETURNING(Payment.AllColumns),
|
||||
)
|
||||
|
||||
testutils.AssertDebugStatementSql(t, stmt, `
|
||||
WITH values_cte ("payment_ID", increase) AS (
|
||||
VALUES (20564::integer, 1.2100000381469727::real),
|
||||
(20567::integer, 1.0199999809265137::real),
|
||||
(20570::integer, 1.340000033378601::real),
|
||||
(20573::integer, 1.7200000286102295::real)
|
||||
)
|
||||
UPDATE dvds.payment
|
||||
SET amount = (payment.amount * values_cte.increase::decimal)
|
||||
FROM values_cte
|
||||
WHERE payment.payment_id = values_cte."payment_ID"
|
||||
RETURNING payment.payment_id AS "payment.payment_id",
|
||||
payment.customer_id AS "payment.customer_id",
|
||||
payment.staff_id AS "payment.staff_id",
|
||||
payment.rental_id AS "payment.rental_id",
|
||||
payment.amount AS "payment.amount",
|
||||
payment.payment_date AS "payment.payment_date";
|
||||
`)
|
||||
|
||||
testutils.ExecuteInTxAndRollback(t, db, func(tx *sql.Tx) {
|
||||
|
||||
var payments []model.Payment
|
||||
|
||||
err := stmt.Query(tx, &payments)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Len(t, payments, 4)
|
||||
testutils.AssertJSON(t, payments[0:2], `
|
||||
[
|
||||
{
|
||||
"PaymentID": 20564,
|
||||
"CustomerID": 379,
|
||||
"StaffID": 2,
|
||||
"RentalID": 11457,
|
||||
"Amount": 4.83,
|
||||
"PaymentDate": "2007-03-02T19:42:42.996577Z"
|
||||
},
|
||||
{
|
||||
"PaymentID": 20567,
|
||||
"CustomerID": 379,
|
||||
"StaffID": 2,
|
||||
"RentalID": 13397,
|
||||
"Amount": 8.15,
|
||||
"PaymentDate": "2007-03-19T20:35:01.996577Z"
|
||||
}
|
||||
]
|
||||
`)
|
||||
})
|
||||
|
||||
}
|
||||
|
|
@ -83,10 +83,10 @@ SELECT orders.ship_region AS "orders.ship_region",
|
|||
SUM(order_details.quantity) AS "product_sales"
|
||||
FROM northwind.orders
|
||||
INNER JOIN northwind.order_details ON (orders.order_id = order_details.order_id)
|
||||
WHERE orders.ship_region IN (
|
||||
WHERE orders.ship_region IN ((
|
||||
SELECT top_region."orders.ship_region" AS "orders.ship_region"
|
||||
FROM top_region
|
||||
)
|
||||
))
|
||||
GROUP BY orders.ship_region, order_details.product_id
|
||||
ORDER BY SUM(order_details.quantity) DESC;
|
||||
`)
|
||||
|
|
@ -157,19 +157,19 @@ func TestWithStatementDeleteAndInsert(t *testing.T) {
|
|||
testutils.AssertStatementSql(t, stmt, `
|
||||
WITH remove_discontinued_orders AS (
|
||||
DELETE FROM northwind.order_details
|
||||
WHERE order_details.product_id IN (
|
||||
WHERE order_details.product_id IN ((
|
||||
SELECT products.product_id AS "products.product_id"
|
||||
FROM northwind.products
|
||||
WHERE products.discontinued = $1
|
||||
)
|
||||
))
|
||||
RETURNING order_details.product_id AS "order_details.product_id"
|
||||
),update_discontinued_price AS (
|
||||
UPDATE northwind.products
|
||||
SET unit_price = $2
|
||||
WHERE products.product_id IN (
|
||||
WHERE products.product_id IN ((
|
||||
SELECT remove_discontinued_orders."order_details.product_id" AS "order_details.product_id"
|
||||
FROM remove_discontinued_orders
|
||||
)
|
||||
))
|
||||
RETURNING products.product_id AS "products.product_id",
|
||||
products.product_name AS "products.product_name",
|
||||
products.supplier_id AS "products.supplier_id",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue