2019-07-30 11:45:10 +02:00
|
|
|
package postgres
|
2019-04-04 13:07:21 +02:00
|
|
|
|
|
|
|
|
import (
|
2025-01-13 10:58:48 +03:00
|
|
|
"testing"
|
|
|
|
|
|
2024-10-06 09:04:10 -04:00
|
|
|
"github.com/go-jet/jet/v2/internal/utils/ptr"
|
2024-10-19 14:06:12 +02:00
|
|
|
"github.com/go-jet/jet/v2/qrm"
|
2022-05-05 13:01:42 +02:00
|
|
|
"github.com/google/uuid"
|
2020-11-14 12:14:08 +01:00
|
|
|
|
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
|
|
2020-06-27 18:48:19 +02:00
|
|
|
"github.com/go-jet/jet/v2/internal/testutils"
|
|
|
|
|
. "github.com/go-jet/jet/v2/postgres"
|
|
|
|
|
"github.com/go-jet/jet/v2/tests/.gentestdata/jetdb/test_sample/model"
|
|
|
|
|
. "github.com/go-jet/jet/v2/tests/.gentestdata/jetdb/test_sample/table"
|
2020-11-14 12:14:08 +01:00
|
|
|
|
2020-11-19 14:02:41 -05:00
|
|
|
"github.com/shopspring/decimal"
|
2019-04-04 13:07:21 +02:00
|
|
|
)
|
|
|
|
|
|
2020-11-14 12:14:08 +01:00
|
|
|
func TestExactDecimals(t *testing.T) {
|
2021-05-09 16:37:16 +02:00
|
|
|
|
|
|
|
|
type floats struct {
|
|
|
|
|
model.Floats
|
|
|
|
|
Numeric decimal.Decimal
|
|
|
|
|
NumericPtr decimal.Decimal
|
|
|
|
|
Decimal decimal.Decimal
|
|
|
|
|
DecimalPtr decimal.Decimal
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-19 14:02:41 -05:00
|
|
|
t.Run("should query decimal", func(t *testing.T) {
|
|
|
|
|
query := SELECT(
|
2021-05-09 16:37:16 +02:00
|
|
|
Floats.AllColumns,
|
2020-11-19 14:02:41 -05:00
|
|
|
).FROM(
|
2021-05-09 16:37:16 +02:00
|
|
|
Floats,
|
|
|
|
|
).WHERE(Floats.Decimal.EQ(Decimal("1.11111111111111111111")))
|
2020-11-14 12:14:08 +01:00
|
|
|
|
2021-05-09 16:37:16 +02:00
|
|
|
var result floats
|
2020-11-19 14:02:41 -05:00
|
|
|
|
|
|
|
|
err := query.Query(db, &result)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
2021-05-09 16:37:16 +02:00
|
|
|
require.Equal(t, "1.11111111111111111111", result.Decimal.String())
|
|
|
|
|
require.Equal(t, "0", result.DecimalPtr.String()) // NULL
|
|
|
|
|
require.Equal(t, "2.22222222222222222222", result.Numeric.String())
|
|
|
|
|
require.Equal(t, "0", result.NumericPtr.String()) // NULL
|
|
|
|
|
|
|
|
|
|
require.Equal(t, 1.1111111111111112, result.Floats.Decimal) // precision loss
|
|
|
|
|
require.Equal(t, (*float64)(nil), result.Floats.DecimalPtr)
|
|
|
|
|
require.Equal(t, 2.2222222222222223, result.Floats.Numeric) // precision loss
|
|
|
|
|
require.Equal(t, (*float64)(nil), result.Floats.NumericPtr)
|
|
|
|
|
|
|
|
|
|
// floating point
|
|
|
|
|
require.Equal(t, float32(3.3333333), result.Floats.Real) // precision loss
|
|
|
|
|
require.Equal(t, (*float32)(nil), result.Floats.RealPtr)
|
|
|
|
|
require.Equal(t, 4.444444444444445, result.Floats.Double) // precision loss
|
|
|
|
|
require.Equal(t, (*float64)(nil), result.Floats.DoublePtr)
|
2020-11-19 14:02:41 -05:00
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("should insert decimal", func(t *testing.T) {
|
2021-05-09 16:37:16 +02:00
|
|
|
|
|
|
|
|
insertQuery := Floats.INSERT(
|
2022-05-05 13:01:42 +02:00
|
|
|
Floats.MutableColumns,
|
2021-05-09 16:37:16 +02:00
|
|
|
).MODEL(
|
|
|
|
|
floats{
|
|
|
|
|
Floats: model.Floats{
|
|
|
|
|
// overwritten by wrapped(floats) scope
|
|
|
|
|
Numeric: 0.1,
|
2024-10-06 09:04:10 -04:00
|
|
|
NumericPtr: ptr.Of(0.1),
|
2021-05-09 16:37:16 +02:00
|
|
|
Decimal: 0.1,
|
2024-10-06 09:04:10 -04:00
|
|
|
DecimalPtr: ptr.Of(0.1),
|
2021-05-09 16:37:16 +02:00
|
|
|
|
|
|
|
|
// not overwritten
|
|
|
|
|
Real: 0.4,
|
2024-10-06 09:04:10 -04:00
|
|
|
RealPtr: ptr.Of(float32(0.44)),
|
2021-05-09 16:37:16 +02:00
|
|
|
Double: 0.3,
|
2024-10-06 09:04:10 -04:00
|
|
|
DoublePtr: ptr.Of(0.33),
|
2021-05-09 16:37:16 +02:00
|
|
|
},
|
|
|
|
|
Numeric: decimal.RequireFromString("0.1234567890123456789"),
|
|
|
|
|
NumericPtr: decimal.RequireFromString("1.1111111111111111111"),
|
|
|
|
|
Decimal: decimal.RequireFromString("2.2222222222222222222"),
|
|
|
|
|
DecimalPtr: decimal.RequireFromString("3.3333333333333333333"),
|
|
|
|
|
},
|
|
|
|
|
).RETURNING(
|
2022-05-05 13:01:42 +02:00
|
|
|
Floats.MutableColumns,
|
2021-05-09 16:37:16 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
testutils.AssertDebugStatementSql(t, insertQuery, `
|
|
|
|
|
INSERT INTO test_sample.floats (decimal_ptr, decimal, numeric_ptr, numeric, real_ptr, real, double_ptr, double)
|
|
|
|
|
VALUES ('3.3333333333333333333', '2.2222222222222222222', '1.1111111111111111111', '0.1234567890123456789', 0.4399999976158142, 0.4000000059604645, 0.33, 0.3)
|
|
|
|
|
RETURNING floats.decimal_ptr AS "floats.decimal_ptr",
|
|
|
|
|
floats.decimal AS "floats.decimal",
|
|
|
|
|
floats.numeric_ptr AS "floats.numeric_ptr",
|
|
|
|
|
floats.numeric AS "floats.numeric",
|
|
|
|
|
floats.real_ptr AS "floats.real_ptr",
|
|
|
|
|
floats.real AS "floats.real",
|
|
|
|
|
floats.double_ptr AS "floats.double_ptr",
|
|
|
|
|
floats.double AS "floats.double";
|
|
|
|
|
`)
|
|
|
|
|
|
|
|
|
|
var result floats
|
2020-11-19 14:02:41 -05:00
|
|
|
err := insertQuery.Query(db, &result)
|
|
|
|
|
require.NoError(t, err)
|
2020-11-14 12:14:08 +01:00
|
|
|
|
2021-05-09 16:37:16 +02:00
|
|
|
// exact decimal
|
|
|
|
|
require.Equal(t, "0.1234567890123456789", result.Numeric.String())
|
|
|
|
|
require.Equal(t, "1.1111111111111111111", result.NumericPtr.String())
|
|
|
|
|
require.Equal(t, "2.2222222222222222222", result.Decimal.String())
|
|
|
|
|
require.Equal(t, "3.3333333333333333333", result.DecimalPtr.String())
|
|
|
|
|
|
|
|
|
|
// precision loss
|
|
|
|
|
require.Equal(t, 0.12345678901234568, result.Floats.Numeric)
|
|
|
|
|
require.Equal(t, 1.1111111111111112, *result.Floats.NumericPtr)
|
|
|
|
|
require.Equal(t, 2.2222222222222223, result.Floats.Decimal)
|
|
|
|
|
require.Equal(t, 3.3333333333333335, *result.Floats.DecimalPtr)
|
|
|
|
|
|
|
|
|
|
// floating points numbers
|
|
|
|
|
require.Equal(t, float32(0.4), result.Floats.Real)
|
|
|
|
|
require.Equal(t, float32(0.44), *result.Floats.RealPtr)
|
|
|
|
|
require.Equal(t, 0.3, result.Floats.Double)
|
|
|
|
|
require.Equal(t, 0.33, *result.Floats.DoublePtr)
|
2020-11-19 14:02:41 -05:00
|
|
|
})
|
2020-11-14 12:14:08 +01:00
|
|
|
}
|
|
|
|
|
|
2019-10-17 13:27:18 -04:00
|
|
|
func TestUUIDComplex(t *testing.T) {
|
2024-02-01 15:20:49 +01:00
|
|
|
query := SELECT(
|
|
|
|
|
Person.AllColumns,
|
|
|
|
|
PersonPhone.AllColumns,
|
|
|
|
|
).FROM(
|
|
|
|
|
Person.INNER_JOIN(PersonPhone, PersonPhone.PersonID.EQ(Person.PersonID)),
|
|
|
|
|
).ORDER_BY(
|
|
|
|
|
Person.PersonID.ASC(),
|
|
|
|
|
PersonPhone.PhoneID.ASC(),
|
|
|
|
|
)
|
2019-10-17 13:27:18 -04:00
|
|
|
|
|
|
|
|
t.Run("slice of structs", func(t *testing.T) {
|
|
|
|
|
|
|
|
|
|
var dest []struct {
|
|
|
|
|
model.Person
|
|
|
|
|
Phones []struct {
|
|
|
|
|
model.PersonPhone
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err := query.Query(db, &dest)
|
|
|
|
|
|
2020-05-09 11:00:22 +02:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Equal(t, len(dest), 2)
|
2019-10-17 13:27:18 -04:00
|
|
|
testutils.AssertJSON(t, dest, `
|
|
|
|
|
[
|
|
|
|
|
{
|
|
|
|
|
"PersonID": "b68dbff4-a87d-11e9-a7f2-98ded00c39c6",
|
|
|
|
|
"FirstName": "Sad",
|
|
|
|
|
"LastName": "John",
|
|
|
|
|
"Mood": "sad",
|
|
|
|
|
"Phones": [
|
|
|
|
|
{
|
|
|
|
|
"PhoneID": "02b61cc4-d500-4847-bd36-111eccbc7a51",
|
|
|
|
|
"PhoneNumber": "212-555-1211",
|
|
|
|
|
"PersonID": "b68dbff4-a87d-11e9-a7f2-98ded00c39c6"
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"PersonID": "b68dbff6-a87d-11e9-a7f2-98ded00c39c8",
|
|
|
|
|
"FirstName": "Ok",
|
|
|
|
|
"LastName": "John",
|
|
|
|
|
"Mood": "ok",
|
|
|
|
|
"Phones": [
|
|
|
|
|
{
|
|
|
|
|
"PhoneID": "02b61cc4-d500-4847-bd36-111eccbc7a52",
|
|
|
|
|
"PhoneNumber": "212-555-1212",
|
|
|
|
|
"PersonID": "b68dbff6-a87d-11e9-a7f2-98ded00c39c8"
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"PhoneID": "02b61cc4-d500-4847-bd36-111eccbc7a53",
|
|
|
|
|
"PhoneNumber": "212-555-1213",
|
|
|
|
|
"PersonID": "b68dbff6-a87d-11e9-a7f2-98ded00c39c8"
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
`)
|
|
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("single struct", func(t *testing.T) {
|
2022-05-05 13:01:42 +02:00
|
|
|
uuid, err := uuid.Parse("b68dbff6-a87d-11e9-a7f2-98ded00c39c8")
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
singleQuery := query.WHERE(Person.PersonID.EQ(UUID(uuid)))
|
2019-10-17 13:27:18 -04:00
|
|
|
|
|
|
|
|
var dest struct {
|
|
|
|
|
model.Person
|
|
|
|
|
Phones []struct {
|
|
|
|
|
model.PersonPhone
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-05-05 13:01:42 +02:00
|
|
|
err = singleQuery.Query(db, &dest)
|
2020-05-09 11:00:22 +02:00
|
|
|
require.NoError(t, err)
|
2019-10-17 13:27:18 -04:00
|
|
|
|
|
|
|
|
testutils.AssertJSON(t, dest, `
|
|
|
|
|
{
|
|
|
|
|
"PersonID": "b68dbff6-a87d-11e9-a7f2-98ded00c39c8",
|
|
|
|
|
"FirstName": "Ok",
|
|
|
|
|
"LastName": "John",
|
|
|
|
|
"Mood": "ok",
|
|
|
|
|
"Phones": [
|
|
|
|
|
{
|
|
|
|
|
"PhoneID": "02b61cc4-d500-4847-bd36-111eccbc7a52",
|
|
|
|
|
"PhoneNumber": "212-555-1212",
|
|
|
|
|
"PersonID": "b68dbff6-a87d-11e9-a7f2-98ded00c39c8"
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"PhoneID": "02b61cc4-d500-4847-bd36-111eccbc7a53",
|
|
|
|
|
"PhoneNumber": "212-555-1213",
|
|
|
|
|
"PersonID": "b68dbff6-a87d-11e9-a7f2-98ded00c39c8"
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
`)
|
2020-05-10 11:41:07 +02:00
|
|
|
requireLogged(t, query)
|
2019-10-17 13:27:18 -04:00
|
|
|
})
|
|
|
|
|
|
2025-02-21 19:55:01 +01:00
|
|
|
var expectedSliceOfStructsLeftJoin = `
|
2019-10-17 13:27:18 -04:00
|
|
|
[
|
|
|
|
|
{
|
|
|
|
|
"PersonID": "b68dbff4-a87d-11e9-a7f2-98ded00c39c6",
|
|
|
|
|
"FirstName": "Sad",
|
|
|
|
|
"LastName": "John",
|
|
|
|
|
"Mood": "sad",
|
|
|
|
|
"Phones": [
|
|
|
|
|
{
|
|
|
|
|
"PhoneID": "02b61cc4-d500-4847-bd36-111eccbc7a51",
|
|
|
|
|
"PhoneNumber": "212-555-1211",
|
|
|
|
|
"PersonID": "b68dbff4-a87d-11e9-a7f2-98ded00c39c6"
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"PersonID": "b68dbff5-a87d-11e9-a7f2-98ded00c39c7",
|
|
|
|
|
"FirstName": "Ok",
|
|
|
|
|
"LastName": "John",
|
|
|
|
|
"Mood": "ok",
|
|
|
|
|
"Phones": null
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"PersonID": "b68dbff6-a87d-11e9-a7f2-98ded00c39c8",
|
|
|
|
|
"FirstName": "Ok",
|
|
|
|
|
"LastName": "John",
|
|
|
|
|
"Mood": "ok",
|
|
|
|
|
"Phones": [
|
|
|
|
|
{
|
|
|
|
|
"PhoneID": "02b61cc4-d500-4847-bd36-111eccbc7a52",
|
|
|
|
|
"PhoneNumber": "212-555-1212",
|
|
|
|
|
"PersonID": "b68dbff6-a87d-11e9-a7f2-98ded00c39c8"
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"PhoneID": "02b61cc4-d500-4847-bd36-111eccbc7a53",
|
|
|
|
|
"PhoneNumber": "212-555-1213",
|
|
|
|
|
"PersonID": "b68dbff6-a87d-11e9-a7f2-98ded00c39c8"
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
]
|
2025-02-21 19:55:01 +01:00
|
|
|
`
|
|
|
|
|
|
|
|
|
|
t.Run("slice of structs left join", func(t *testing.T) {
|
|
|
|
|
leftQuery := Person.LEFT_JOIN(PersonPhone, PersonPhone.PersonID.EQ(Person.PersonID)).
|
|
|
|
|
SELECT(Person.AllColumns, PersonPhone.AllColumns).
|
|
|
|
|
ORDER_BY(Person.PersonID.ASC(), PersonPhone.PhoneID.ASC())
|
|
|
|
|
var dest []struct {
|
|
|
|
|
model.Person
|
|
|
|
|
Phones []struct {
|
|
|
|
|
model.PersonPhone
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
err := leftQuery.Query(db, &dest)
|
|
|
|
|
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
testutils.AssertJSON(t, dest, expectedSliceOfStructsLeftJoin)
|
2020-05-10 11:41:07 +02:00
|
|
|
requireLogged(t, leftQuery)
|
2019-10-17 13:27:18 -04:00
|
|
|
})
|
|
|
|
|
|
2025-02-21 19:55:01 +01:00
|
|
|
t.Run("select json", func(t *testing.T) {
|
|
|
|
|
jsonQuery := SELECT_JSON_ARR(
|
|
|
|
|
Person.AllColumns,
|
|
|
|
|
SELECT_JSON_ARR(PersonPhone.AllColumns).
|
|
|
|
|
FROM(PersonPhone).
|
|
|
|
|
WHERE(PersonPhone.PersonID.EQ(Person.PersonID)).
|
|
|
|
|
ORDER_BY(PersonPhone.PhoneID).AS("Phones"),
|
|
|
|
|
).FROM(
|
|
|
|
|
Person,
|
|
|
|
|
).ORDER_BY(
|
|
|
|
|
Person.PersonID.ASC(),
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
var dest []struct {
|
|
|
|
|
model.Person
|
|
|
|
|
Phones []struct {
|
|
|
|
|
model.PersonPhone
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-09 17:46:34 +01:00
|
|
|
err := jsonQuery.QueryContext(ctx, db, &dest)
|
2025-02-21 19:55:01 +01:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
testutils.AssertJSON(t, dest, expectedSliceOfStructsLeftJoin)
|
|
|
|
|
})
|
|
|
|
|
|
2019-10-17 13:27:18 -04:00
|
|
|
}
|
2019-04-04 13:07:21 +02:00
|
|
|
func TestEnumType(t *testing.T) {
|
2019-06-26 10:30:31 +02:00
|
|
|
query := Person.
|
|
|
|
|
SELECT(Person.AllColumns)
|
2019-04-04 13:07:21 +02:00
|
|
|
|
2019-07-30 11:18:12 +02:00
|
|
|
testutils.AssertDebugStatementSql(t, query, `
|
2019-07-17 13:22:14 +02:00
|
|
|
SELECT person.person_id AS "person.person_id",
|
|
|
|
|
person.first_name AS "person.first_name",
|
|
|
|
|
person.last_name AS "person.last_name",
|
|
|
|
|
person."Mood" AS "person.Mood"
|
|
|
|
|
FROM test_sample.person;
|
|
|
|
|
`)
|
2019-04-04 13:07:21 +02:00
|
|
|
|
2022-05-05 13:01:42 +02:00
|
|
|
var result []model.Person
|
2019-04-04 13:07:21 +02:00
|
|
|
|
2019-07-17 13:22:14 +02:00
|
|
|
err := query.Query(db, &result)
|
2019-04-04 13:07:21 +02:00
|
|
|
|
2020-05-09 11:00:22 +02:00
|
|
|
require.NoError(t, err)
|
2019-08-06 11:41:45 +02:00
|
|
|
testutils.AssertJSON(t, result, `
|
2019-07-17 13:22:14 +02:00
|
|
|
[
|
|
|
|
|
{
|
|
|
|
|
"PersonID": "b68dbff4-a87d-11e9-a7f2-98ded00c39c6",
|
|
|
|
|
"FirstName": "Sad",
|
|
|
|
|
"LastName": "John",
|
|
|
|
|
"Mood": "sad"
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"PersonID": "b68dbff5-a87d-11e9-a7f2-98ded00c39c7",
|
|
|
|
|
"FirstName": "Ok",
|
|
|
|
|
"LastName": "John",
|
|
|
|
|
"Mood": "ok"
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"PersonID": "b68dbff6-a87d-11e9-a7f2-98ded00c39c8",
|
|
|
|
|
"FirstName": "Ok",
|
|
|
|
|
"LastName": "John",
|
|
|
|
|
"Mood": "ok"
|
2019-04-04 13:07:21 +02:00
|
|
|
}
|
2019-07-17 13:22:14 +02:00
|
|
|
]
|
2019-08-06 11:41:45 +02:00
|
|
|
`)
|
2019-04-04 13:07:21 +02:00
|
|
|
}
|
2019-06-26 10:30:31 +02:00
|
|
|
|
2022-05-05 13:01:42 +02:00
|
|
|
func TestSelectSelfJoin1(t *testing.T) {
|
2019-06-26 10:30:31 +02:00
|
|
|
|
2020-04-12 18:53:57 +02:00
|
|
|
// clean up
|
|
|
|
|
_, err := Employee.DELETE().WHERE(Employee.EmployeeID.GT(Int(100))).Exec(db)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
2019-07-18 17:43:11 +02:00
|
|
|
var expectedSQL = `
|
2019-06-26 10:30:31 +02:00
|
|
|
SELECT 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",
|
2024-10-07 15:02:12 -04:00
|
|
|
employee.pto_accrual AS "employee.pto_accrual",
|
2019-06-26 10:30:31 +02:00
|
|
|
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",
|
2024-10-07 15:02:12 -04:00
|
|
|
manager.manager_id AS "manager.manager_id",
|
|
|
|
|
manager.pto_accrual AS "manager.pto_accrual"
|
2019-06-26 10:30:31 +02:00
|
|
|
FROM test_sample.employee
|
|
|
|
|
LEFT JOIN test_sample.employee AS manager ON (manager.employee_id = employee.manager_id)
|
|
|
|
|
ORDER BY employee.employee_id;
|
|
|
|
|
`
|
|
|
|
|
|
|
|
|
|
manager := Employee.AS("manager")
|
|
|
|
|
query := Employee.
|
|
|
|
|
LEFT_JOIN(manager, manager.EmployeeID.EQ(Employee.ManagerID)).
|
|
|
|
|
SELECT(
|
|
|
|
|
Employee.AllColumns,
|
|
|
|
|
manager.AllColumns,
|
|
|
|
|
).
|
|
|
|
|
ORDER_BY(Employee.EmployeeID)
|
|
|
|
|
|
2019-07-30 11:18:12 +02:00
|
|
|
testutils.AssertDebugStatementSql(t, query, expectedSQL)
|
2019-06-26 10:30:31 +02:00
|
|
|
|
|
|
|
|
type Manager model.Employee
|
|
|
|
|
|
|
|
|
|
var dest []struct {
|
|
|
|
|
model.Employee
|
|
|
|
|
|
|
|
|
|
Manager *Manager
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-12 18:53:57 +02:00
|
|
|
err = query.Query(db, &dest)
|
2019-06-26 10:30:31 +02:00
|
|
|
|
2020-05-09 11:00:22 +02:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Equal(t, len(dest), 8)
|
2020-02-11 10:25:13 +01:00
|
|
|
testutils.AssertDeepEqual(t, dest[0].Employee, model.Employee{
|
2019-06-26 10:30:31 +02:00
|
|
|
EmployeeID: 1,
|
|
|
|
|
FirstName: "Windy",
|
|
|
|
|
LastName: "Hays",
|
2019-07-31 18:43:54 +02:00
|
|
|
EmploymentDate: testutils.TimestampWithTimeZone("1999-01-08 04:05:06.1 +0100 CET", 1),
|
2019-06-26 10:30:31 +02:00
|
|
|
ManagerID: nil,
|
2024-10-07 15:02:12 -04:00
|
|
|
PtoAccrual: ptr.Of("22:00:00"),
|
2019-06-26 10:30:31 +02:00
|
|
|
})
|
|
|
|
|
|
2020-05-09 11:00:22 +02:00
|
|
|
require.True(t, dest[0].Manager == nil)
|
2019-06-26 10:30:31 +02:00
|
|
|
|
2020-02-11 10:25:13 +01:00
|
|
|
testutils.AssertDeepEqual(t, dest[7].Employee, model.Employee{
|
2019-06-26 10:30:31 +02:00
|
|
|
EmployeeID: 8,
|
|
|
|
|
FirstName: "Salley",
|
|
|
|
|
LastName: "Lester",
|
2019-07-31 18:43:54 +02:00
|
|
|
EmploymentDate: testutils.TimestampWithTimeZone("1999-01-08 04:05:06 +0100 CET", 1),
|
2024-10-06 09:04:10 -04:00
|
|
|
ManagerID: ptr.Of(int32(3)),
|
2019-06-26 10:30:31 +02:00
|
|
|
})
|
|
|
|
|
}
|
2019-07-03 16:27:14 +02:00
|
|
|
|
|
|
|
|
func TestWierdNamesTable(t *testing.T) {
|
2022-05-05 13:01:42 +02:00
|
|
|
stmt := WeirdNamesTable.SELECT(WeirdNamesTable.MutableColumns)
|
2019-07-03 16:27:14 +02:00
|
|
|
|
2019-07-30 11:18:12 +02:00
|
|
|
testutils.AssertDebugStatementSql(t, stmt, `
|
2019-07-13 13:17:28 +02:00
|
|
|
SELECT "WEIRD NAMES TABLE".weird_column_name1 AS "WEIRD NAMES TABLE.weird_column_name1",
|
|
|
|
|
"WEIRD NAMES TABLE"."Weird_Column_Name2" AS "WEIRD NAMES TABLE.Weird_Column_Name2",
|
|
|
|
|
"WEIRD NAMES TABLE"."wEiRd_cOluMn_nAmE3" AS "WEIRD NAMES TABLE.wEiRd_cOluMn_nAmE3",
|
|
|
|
|
"WEIRD NAMES TABLE"."WeIrd_CoLuMN_Name4" AS "WEIRD NAMES TABLE.WeIrd_CoLuMN_Name4",
|
|
|
|
|
"WEIRD NAMES TABLE"."WEIRD_COLUMN_NAME5" AS "WEIRD NAMES TABLE.WEIRD_COLUMN_NAME5",
|
|
|
|
|
"WEIRD NAMES TABLE"."WeirdColumnName6" AS "WEIRD NAMES TABLE.WeirdColumnName6",
|
|
|
|
|
"WEIRD NAMES TABLE"."weirdColumnName7" AS "WEIRD NAMES TABLE.weirdColumnName7",
|
|
|
|
|
"WEIRD NAMES TABLE".weirdcolumnname8 AS "WEIRD NAMES TABLE.weirdcolumnname8",
|
|
|
|
|
"WEIRD NAMES TABLE"."weird col name9" AS "WEIRD NAMES TABLE.weird col name9",
|
|
|
|
|
"WEIRD NAMES TABLE"."wEiRd cOlu nAmE10" AS "WEIRD NAMES TABLE.wEiRd cOlu nAmE10",
|
|
|
|
|
"WEIRD NAMES TABLE"."WEIRD COLU NAME11" AS "WEIRD NAMES TABLE.WEIRD COLU NAME11",
|
|
|
|
|
"WEIRD NAMES TABLE"."Weird Colu Name12" AS "WEIRD NAMES TABLE.Weird Colu Name12",
|
|
|
|
|
"WEIRD NAMES TABLE"."weird-col-name13" AS "WEIRD NAMES TABLE.weird-col-name13",
|
|
|
|
|
"WEIRD NAMES TABLE"."wEiRd-cOlu-nAmE14" AS "WEIRD NAMES TABLE.wEiRd-cOlu-nAmE14",
|
|
|
|
|
"WEIRD NAMES TABLE"."WEIRD-COLU-NAME15" AS "WEIRD NAMES TABLE.WEIRD-COLU-NAME15",
|
|
|
|
|
"WEIRD NAMES TABLE"."Weird-Colu-Name16" AS "WEIRD NAMES TABLE.Weird-Colu-Name16"
|
|
|
|
|
FROM test_sample."WEIRD NAMES TABLE";
|
|
|
|
|
`)
|
2019-07-03 16:27:14 +02:00
|
|
|
|
2022-05-05 13:01:42 +02:00
|
|
|
var dest []model.WeirdNamesTable
|
2019-07-03 16:27:14 +02:00
|
|
|
|
|
|
|
|
err := stmt.Query(db, &dest)
|
|
|
|
|
|
2020-05-09 11:00:22 +02:00
|
|
|
require.NoError(t, err)
|
2019-07-03 16:27:14 +02:00
|
|
|
|
2020-05-09 11:00:22 +02:00
|
|
|
require.Equal(t, len(dest), 1)
|
2020-02-11 10:25:13 +01:00
|
|
|
testutils.AssertDeepEqual(t, dest[0], model.WeirdNamesTable{
|
2019-07-03 16:27:14 +02:00
|
|
|
WeirdColumnName1: "Doe",
|
|
|
|
|
WeirdColumnName2: "Doe",
|
|
|
|
|
WeirdColumnName3: "Doe",
|
|
|
|
|
WeirdColumnName4: "Doe",
|
|
|
|
|
WeirdColumnName5: "Doe",
|
|
|
|
|
WeirdColumnName6: "Doe",
|
|
|
|
|
WeirdColumnName7: "Doe",
|
2024-10-06 09:04:10 -04:00
|
|
|
Weirdcolumnname8: ptr.Of("Doe"),
|
2019-07-03 16:27:14 +02:00
|
|
|
WeirdColName9: "Doe",
|
|
|
|
|
WeirdColuName10: "Doe",
|
|
|
|
|
WeirdColuName11: "Doe",
|
|
|
|
|
WeirdColuName12: "Doe",
|
|
|
|
|
WeirdColName13: "Doe",
|
|
|
|
|
WeirdColuName14: "Doe",
|
|
|
|
|
WeirdColuName15: "Doe",
|
|
|
|
|
WeirdColuName16: "Doe",
|
|
|
|
|
})
|
|
|
|
|
}
|
2020-02-16 10:25:21 +01:00
|
|
|
|
|
|
|
|
func TestReserwedWordEscape(t *testing.T) {
|
2022-05-05 13:01:42 +02:00
|
|
|
stmt := SELECT(User.MutableColumns).
|
2020-02-16 10:25:21 +01:00
|
|
|
FROM(User)
|
|
|
|
|
|
|
|
|
|
//fmt.Println(stmt.DebugSql())
|
|
|
|
|
|
|
|
|
|
testutils.AssertDebugStatementSql(t, stmt, `
|
|
|
|
|
SELECT "User"."column" AS "User.column",
|
|
|
|
|
"User"."check" AS "User.check",
|
|
|
|
|
"User".ceil AS "User.ceil",
|
|
|
|
|
"User".commit AS "User.commit",
|
|
|
|
|
"User"."create" AS "User.create",
|
|
|
|
|
"User"."default" AS "User.default",
|
|
|
|
|
"User"."desc" AS "User.desc",
|
|
|
|
|
"User".empty AS "User.empty",
|
|
|
|
|
"User".float AS "User.float",
|
2025-01-13 10:58:48 +03:00
|
|
|
"User"."join" AS "User.join",
|
|
|
|
|
"User"."like" AS "User.like",
|
2020-02-16 10:25:21 +01:00
|
|
|
"User".max AS "User.max",
|
|
|
|
|
"User".rank AS "User.rank"
|
|
|
|
|
FROM test_sample."User";
|
|
|
|
|
`)
|
|
|
|
|
|
|
|
|
|
var dest []model.User
|
|
|
|
|
|
|
|
|
|
err := stmt.Query(db, &dest)
|
2020-05-09 11:00:22 +02:00
|
|
|
require.NoError(t, err)
|
2020-02-16 10:25:21 +01:00
|
|
|
|
2021-03-21 17:17:44 +01:00
|
|
|
//testutils.PrintJson(dest)
|
2020-02-16 10:25:21 +01:00
|
|
|
|
|
|
|
|
testutils.AssertJSON(t, dest, `
|
|
|
|
|
[
|
|
|
|
|
{
|
2022-05-05 13:01:42 +02:00
|
|
|
"ID": 0,
|
2020-02-16 10:25:21 +01:00
|
|
|
"Column": "Column",
|
|
|
|
|
"Check": "CHECK",
|
|
|
|
|
"Ceil": "CEIL",
|
|
|
|
|
"Commit": "COMMIT",
|
|
|
|
|
"Create": "CREATE",
|
|
|
|
|
"Default": "DEFAULT",
|
|
|
|
|
"Desc": "DESC",
|
|
|
|
|
"Empty": "EMPTY",
|
|
|
|
|
"Float": "FLOAT",
|
|
|
|
|
"Join": "JOIN",
|
|
|
|
|
"Like": "LIKE",
|
|
|
|
|
"Max": "MAX",
|
|
|
|
|
"Rank": "RANK"
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
`)
|
|
|
|
|
}
|
2023-01-30 14:53:16 -05:00
|
|
|
|
|
|
|
|
func TestMutableColumnsExcludeGeneratedColumn(t *testing.T) {
|
|
|
|
|
|
|
|
|
|
t.Run("should not have the generated column in mutableColumns", func(t *testing.T) {
|
|
|
|
|
require.Equal(t, 2, len(People.MutableColumns))
|
|
|
|
|
require.Equal(t, People.PeopleName, People.MutableColumns[0])
|
|
|
|
|
require.Equal(t, People.PeopleHeightCm, People.MutableColumns[1])
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("should query with all columns", func(t *testing.T) {
|
|
|
|
|
query := SELECT(
|
|
|
|
|
People.AllColumns,
|
|
|
|
|
).FROM(
|
|
|
|
|
People,
|
|
|
|
|
).WHERE(
|
|
|
|
|
People.PeopleID.EQ(Int(3)),
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
var result model.People
|
|
|
|
|
|
|
|
|
|
err := query.Query(db, &result)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
|
|
require.Equal(t, "Carla", result.PeopleName)
|
|
|
|
|
require.Equal(t, 155., *result.PeopleHeightCm)
|
|
|
|
|
require.InEpsilon(t, 61.02, *result.PeopleHeightIn, 1e-3)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("should insert without generated columns", func(t *testing.T) {
|
2024-03-07 18:01:31 +01:00
|
|
|
testutils.ExecuteInTxAndRollback(t, db, func(tx qrm.DB) {
|
2023-04-06 11:26:09 +02:00
|
|
|
insertQuery := People.INSERT(
|
|
|
|
|
People.MutableColumns,
|
|
|
|
|
).MODEL(
|
|
|
|
|
model.People{
|
|
|
|
|
PeopleName: "Dario",
|
2024-10-06 09:04:10 -04:00
|
|
|
PeopleHeightCm: ptr.Of(120.0),
|
2023-04-06 11:26:09 +02:00
|
|
|
},
|
|
|
|
|
).RETURNING(
|
|
|
|
|
People.MutableColumns,
|
|
|
|
|
)
|
2023-01-30 14:53:16 -05:00
|
|
|
|
2023-04-06 11:26:09 +02:00
|
|
|
testutils.AssertDebugStatementSql(t, insertQuery, `
|
2023-01-30 14:53:16 -05:00
|
|
|
INSERT INTO test_sample.people (people_name, people_height_cm)
|
|
|
|
|
VALUES ('Dario', 120)
|
|
|
|
|
RETURNING people.people_name AS "people.people_name",
|
|
|
|
|
people.people_height_cm AS "people.people_height_cm";
|
|
|
|
|
`)
|
2023-04-06 11:26:09 +02:00
|
|
|
var result model.People
|
|
|
|
|
err := insertQuery.Query(tx, &result)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
|
|
require.Equal(t, "Dario", result.PeopleName)
|
|
|
|
|
require.Equal(t, 120., *result.PeopleHeightCm)
|
|
|
|
|
|
|
|
|
|
query := SELECT(
|
|
|
|
|
People.AllColumns,
|
|
|
|
|
).FROM(
|
|
|
|
|
People,
|
|
|
|
|
).ORDER_BY(
|
|
|
|
|
People.PeopleID.DESC(),
|
|
|
|
|
).LIMIT(1)
|
|
|
|
|
|
|
|
|
|
result = model.People{}
|
|
|
|
|
|
|
|
|
|
err = query.Query(tx, &result)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
|
|
require.Equal(t, "Dario", result.PeopleName)
|
|
|
|
|
require.Equal(t, 120., *result.PeopleHeightCm)
|
|
|
|
|
require.InEpsilon(t, 47.24, *result.PeopleHeightIn, 1e-3)
|
|
|
|
|
})
|
2023-01-30 14:53:16 -05:00
|
|
|
})
|
|
|
|
|
}
|