909 lines
48 KiB
Go
909 lines
48 KiB
Go
|
|
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/qrm"
|
||
|
|
"github.com/go-jet/jet/v2/tests/.gentestdata/jetdb/dvds/view"
|
||
|
|
"github.com/stretchr/testify/require"
|
||
|
|
"testing"
|
||
|
|
"time"
|
||
|
|
|
||
|
|
. "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"
|
||
|
|
)
|
||
|
|
|
||
|
|
var ctx = context.Background()
|
||
|
|
|
||
|
|
func TestSelectJsonObject(t *testing.T) {
|
||
|
|
stmt := SELECT_JSON_OBJ(Actor.AllColumns).
|
||
|
|
FROM(Actor).
|
||
|
|
WHERE(Actor.ActorID.EQ(Int32(2)))
|
||
|
|
|
||
|
|
testutils.AssertStatementSql(t, stmt, `
|
||
|
|
SELECT row_to_json(records) AS "json"
|
||
|
|
FROM (
|
||
|
|
SELECT actor.actor_id AS "actorID",
|
||
|
|
actor.first_name AS "firstName",
|
||
|
|
actor.last_name AS "lastName",
|
||
|
|
actor.last_update AS "lastUpdate"
|
||
|
|
FROM dvds.actor
|
||
|
|
WHERE actor.actor_id = $1::integer
|
||
|
|
) AS records;
|
||
|
|
`, int32(2))
|
||
|
|
|
||
|
|
var dest model.Actor
|
||
|
|
|
||
|
|
err := stmt.QueryJSON(ctx, db, &dest)
|
||
|
|
require.NoError(t, err)
|
||
|
|
testutils.AssertDeepEqual(t, dest, actor2)
|
||
|
|
requireLogged(t, stmt)
|
||
|
|
|
||
|
|
t.Run("scan to map", func(t *testing.T) {
|
||
|
|
var dest2 map[string]interface{}
|
||
|
|
|
||
|
|
err = stmt.QueryJSON(ctx, db, &dest2)
|
||
|
|
require.NoError(t, err)
|
||
|
|
testutils.PrintJson(dest2)
|
||
|
|
testutils.AssertDeepEqual(t, dest2, map[string]interface{}{
|
||
|
|
"actorID": float64(2),
|
||
|
|
"firstName": "Nick",
|
||
|
|
"lastName": "Wahlberg",
|
||
|
|
"lastUpdate": "2013-05-26T14:47:57.62",
|
||
|
|
})
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestSelectJsonArr(t *testing.T) {
|
||
|
|
stmt := SELECT_JSON_ARR(
|
||
|
|
Rental.StaffID,
|
||
|
|
Rental.CustomerID,
|
||
|
|
Rental.RentalID,
|
||
|
|
).DISTINCT(
|
||
|
|
Rental.StaffID,
|
||
|
|
Rental.CustomerID,
|
||
|
|
).FROM(
|
||
|
|
Rental,
|
||
|
|
).WHERE(
|
||
|
|
Rental.CustomerID.LT(Int(2)),
|
||
|
|
).ORDER_BY(
|
||
|
|
Rental.StaffID.ASC(),
|
||
|
|
Rental.CustomerID.ASC(),
|
||
|
|
Rental.RentalID.ASC(),
|
||
|
|
)
|
||
|
|
|
||
|
|
testutils.AssertStatementSql(t, stmt, `
|
||
|
|
SELECT json_agg(row_to_json(records)) AS "json"
|
||
|
|
FROM (
|
||
|
|
SELECT DISTINCT ON (rental.staff_id, rental.customer_id) rental.staff_id AS "staffID",
|
||
|
|
rental.customer_id AS "customerID",
|
||
|
|
rental.rental_id AS "rentalID"
|
||
|
|
FROM dvds.rental
|
||
|
|
WHERE rental.customer_id < $1
|
||
|
|
ORDER BY rental.staff_id ASC, rental.customer_id ASC, rental.rental_id ASC
|
||
|
|
) AS records;
|
||
|
|
`, int64(2))
|
||
|
|
|
||
|
|
var dest []model.Rental
|
||
|
|
|
||
|
|
err := stmt.QueryJSON(ctx, db, &dest)
|
||
|
|
require.NoError(t, err)
|
||
|
|
testutils.AssertJSON(t, dest, `
|
||
|
|
[
|
||
|
|
{
|
||
|
|
"RentalID": 573,
|
||
|
|
"RentalDate": "0001-01-01T00:00:00Z",
|
||
|
|
"InventoryID": 0,
|
||
|
|
"CustomerID": 1,
|
||
|
|
"ReturnDate": null,
|
||
|
|
"StaffID": 1,
|
||
|
|
"LastUpdate": "0001-01-01T00:00:00Z"
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"RentalID": 76,
|
||
|
|
"RentalDate": "0001-01-01T00:00:00Z",
|
||
|
|
"InventoryID": 0,
|
||
|
|
"CustomerID": 1,
|
||
|
|
"ReturnDate": null,
|
||
|
|
"StaffID": 2,
|
||
|
|
"LastUpdate": "0001-01-01T00:00:00Z"
|
||
|
|
}
|
||
|
|
]
|
||
|
|
`)
|
||
|
|
t.Run("scan to array map", func(t *testing.T) {
|
||
|
|
var dest2 []map[string]interface{}
|
||
|
|
|
||
|
|
err := stmt.QueryJSON(ctx, db, &dest2)
|
||
|
|
require.NoError(t, err)
|
||
|
|
testutils.AssertDeepEqual(t, dest2, []map[string]interface{}{
|
||
|
|
{
|
||
|
|
"rentalID": 573.,
|
||
|
|
"customerID": 1.,
|
||
|
|
"staffID": 1.,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"rentalID": 76.,
|
||
|
|
"customerID": 1.,
|
||
|
|
"staffID": 2.,
|
||
|
|
},
|
||
|
|
})
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestSelectJsonArr_NestedArr(t *testing.T) {
|
||
|
|
|
||
|
|
stmt := SELECT_JSON_ARR(
|
||
|
|
Customer.AllColumns,
|
||
|
|
|
||
|
|
SELECT_JSON_ARR(Rental.AllColumns).
|
||
|
|
FROM(Rental).
|
||
|
|
WHERE(Rental.CustomerID.EQ(Customer.CustomerID)).
|
||
|
|
ORDER_BY(Rental.RentalID).
|
||
|
|
OFFSET_e(Int(1)).LIMIT(3).AS("Rentals"),
|
||
|
|
).FROM(
|
||
|
|
Customer,
|
||
|
|
).ORDER_BY(
|
||
|
|
Customer.CustomerID,
|
||
|
|
).LIMIT(2).OFFSET(1)
|
||
|
|
|
||
|
|
testutils.AssertStatementSql(t, stmt, `
|
||
|
|
SELECT json_agg(row_to_json(records)) AS "json"
|
||
|
|
FROM (
|
||
|
|
SELECT customer.customer_id AS "customerID",
|
||
|
|
customer.store_id AS "storeID",
|
||
|
|
customer.first_name AS "firstName",
|
||
|
|
customer.last_name AS "lastName",
|
||
|
|
customer.email AS "email",
|
||
|
|
customer.address_id AS "addressID",
|
||
|
|
customer.activebool AS "activebool",
|
||
|
|
customer.create_date AS "createDate",
|
||
|
|
customer.last_update AS "lastUpdate",
|
||
|
|
customer.active AS "active",
|
||
|
|
(
|
||
|
|
SELECT json_agg(row_to_json(rentals_records)) AS "rentals_json"
|
||
|
|
FROM (
|
||
|
|
SELECT rental.rental_id AS "rentalID",
|
||
|
|
rental.rental_date AS "rentalDate",
|
||
|
|
rental.inventory_id AS "inventoryID",
|
||
|
|
rental.customer_id AS "customerID",
|
||
|
|
rental.return_date AS "returnDate",
|
||
|
|
rental.staff_id AS "staffID",
|
||
|
|
rental.last_update AS "lastUpdate"
|
||
|
|
FROM dvds.rental
|
||
|
|
WHERE rental.customer_id = customer.customer_id
|
||
|
|
ORDER BY rental.rental_id
|
||
|
|
LIMIT $1
|
||
|
|
OFFSET $2
|
||
|
|
) AS rentals_records
|
||
|
|
) AS "Rentals"
|
||
|
|
FROM dvds.customer
|
||
|
|
ORDER BY customer.customer_id
|
||
|
|
LIMIT $3
|
||
|
|
OFFSET $4
|
||
|
|
) AS records;
|
||
|
|
`)
|
||
|
|
|
||
|
|
var dest []struct {
|
||
|
|
model.Customer
|
||
|
|
|
||
|
|
Rentals []model.Rental
|
||
|
|
}
|
||
|
|
|
||
|
|
err := stmt.QueryJSON(ctx, db, &dest)
|
||
|
|
require.NoError(t, err)
|
||
|
|
|
||
|
|
t.Run("partial select json", func(t *testing.T) {
|
||
|
|
|
||
|
|
stmt := SELECT(
|
||
|
|
Customer.AllColumns,
|
||
|
|
|
||
|
|
SELECT_JSON_ARR(Rental.AllColumns).
|
||
|
|
FROM(Rental).
|
||
|
|
WHERE(Rental.CustomerID.EQ(Customer.CustomerID)).
|
||
|
|
ORDER_BY(Rental.RentalID).
|
||
|
|
OFFSET_e(Int(1)).LIMIT(3).AS("Rentals"),
|
||
|
|
).FROM(
|
||
|
|
Customer,
|
||
|
|
).ORDER_BY(
|
||
|
|
Customer.CustomerID,
|
||
|
|
).OFFSET(1).LIMIT(2)
|
||
|
|
|
||
|
|
testutils.AssertStatementSql(t, stmt, `
|
||
|
|
SELECT customer.customer_id AS "customer.customer_id",
|
||
|
|
customer.store_id AS "customer.store_id",
|
||
|
|
customer.first_name AS "customer.first_name",
|
||
|
|
customer.last_name AS "customer.last_name",
|
||
|
|
customer.email AS "customer.email",
|
||
|
|
customer.address_id AS "customer.address_id",
|
||
|
|
customer.activebool AS "customer.activebool",
|
||
|
|
customer.create_date AS "customer.create_date",
|
||
|
|
customer.last_update AS "customer.last_update",
|
||
|
|
customer.active AS "customer.active",
|
||
|
|
(
|
||
|
|
SELECT json_agg(row_to_json(rentals_records)) AS "rentals_json"
|
||
|
|
FROM (
|
||
|
|
SELECT rental.rental_id AS "rentalID",
|
||
|
|
rental.rental_date AS "rentalDate",
|
||
|
|
rental.inventory_id AS "inventoryID",
|
||
|
|
rental.customer_id AS "customerID",
|
||
|
|
rental.return_date AS "returnDate",
|
||
|
|
rental.staff_id AS "staffID",
|
||
|
|
rental.last_update AS "lastUpdate"
|
||
|
|
FROM dvds.rental
|
||
|
|
WHERE rental.customer_id = customer.customer_id
|
||
|
|
ORDER BY rental.rental_id
|
||
|
|
LIMIT $1
|
||
|
|
OFFSET $2
|
||
|
|
) AS rentals_records
|
||
|
|
) AS "Rentals"
|
||
|
|
FROM dvds.customer
|
||
|
|
ORDER BY customer.customer_id
|
||
|
|
LIMIT $3
|
||
|
|
OFFSET $4;
|
||
|
|
`)
|
||
|
|
|
||
|
|
var dest2 []struct {
|
||
|
|
model.Customer
|
||
|
|
|
||
|
|
Rentals []model.Rental `json_column:"Rentals"`
|
||
|
|
}
|
||
|
|
|
||
|
|
err := stmt.Query(db, &dest2)
|
||
|
|
require.NoError(t, err)
|
||
|
|
testutils.AssertJsonEqual(t, dest, dest2)
|
||
|
|
|
||
|
|
var dest3 []struct {
|
||
|
|
model.Customer
|
||
|
|
|
||
|
|
Rentals *[]model.Rental `json_column:"rentals"`
|
||
|
|
}
|
||
|
|
|
||
|
|
err = stmt.Query(db, &dest3)
|
||
|
|
require.NoError(t, err)
|
||
|
|
testutils.AssertJsonEqual(t, dest, dest3)
|
||
|
|
|
||
|
|
var dest4 []struct {
|
||
|
|
model.Customer
|
||
|
|
|
||
|
|
Rentals []*model.Rental `json_column:"rentals"`
|
||
|
|
}
|
||
|
|
|
||
|
|
err = stmt.Query(db, &dest4)
|
||
|
|
require.NoError(t, err)
|
||
|
|
testutils.AssertJsonEqual(t, dest, dest4)
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestSelectJson_GroupByHaving(t *testing.T) {
|
||
|
|
stmt := SELECT_JSON_ARR(
|
||
|
|
Customer.AllColumns,
|
||
|
|
|
||
|
|
SELECT_JSON_OBJ(
|
||
|
|
SUM(Payment.Amount).AS("sum"),
|
||
|
|
AVG(Payment.Amount).AS("avg"),
|
||
|
|
MAX(Payment.PaymentDate).AS("max_date"),
|
||
|
|
MAX(Payment.Amount).AS("max"),
|
||
|
|
MIN(Payment.PaymentDate).AS("min_date"),
|
||
|
|
MIN(Payment.Amount).AS("min"),
|
||
|
|
COUNT(Payment.Amount).AS("count"),
|
||
|
|
).AS("amount"),
|
||
|
|
).FROM(
|
||
|
|
Payment.
|
||
|
|
INNER_JOIN(Customer, Customer.CustomerID.EQ(Payment.CustomerID)),
|
||
|
|
).GROUP_BY(
|
||
|
|
Customer.CustomerID,
|
||
|
|
).HAVING(
|
||
|
|
SUMf(Payment.Amount).GT(Real(125)),
|
||
|
|
).ORDER_BY(
|
||
|
|
Customer.CustomerID, SUM(Payment.Amount).ASC(),
|
||
|
|
)
|
||
|
|
|
||
|
|
testutils.AssertDebugStatementSql(t, stmt, `
|
||
|
|
SELECT json_agg(row_to_json(records)) AS "json"
|
||
|
|
FROM (
|
||
|
|
SELECT customer.customer_id AS "customerID",
|
||
|
|
customer.store_id AS "storeID",
|
||
|
|
customer.first_name AS "firstName",
|
||
|
|
customer.last_name AS "lastName",
|
||
|
|
customer.email AS "email",
|
||
|
|
customer.address_id AS "addressID",
|
||
|
|
customer.activebool AS "activebool",
|
||
|
|
customer.create_date AS "createDate",
|
||
|
|
customer.last_update AS "lastUpdate",
|
||
|
|
customer.active AS "active",
|
||
|
|
(
|
||
|
|
SELECT row_to_json(amount_records) AS "amount_json"
|
||
|
|
FROM (
|
||
|
|
SELECT SUM(payment.amount) AS "sum",
|
||
|
|
AVG(payment.amount) AS "avg",
|
||
|
|
MAX(payment.payment_date) AS "max_date",
|
||
|
|
MAX(payment.amount) AS "max",
|
||
|
|
MIN(payment.payment_date) AS "min_date",
|
||
|
|
MIN(payment.amount) AS "min",
|
||
|
|
COUNT(payment.amount) AS "count"
|
||
|
|
) AS amount_records
|
||
|
|
) AS "amount"
|
||
|
|
FROM dvds.payment
|
||
|
|
INNER JOIN dvds.customer ON (customer.customer_id = payment.customer_id)
|
||
|
|
GROUP BY customer.customer_id
|
||
|
|
HAVING SUM(payment.amount) > 125::real
|
||
|
|
ORDER BY customer.customer_id, SUM(payment.amount) ASC
|
||
|
|
) AS records;
|
||
|
|
`)
|
||
|
|
|
||
|
|
var dest []struct {
|
||
|
|
model.Customer
|
||
|
|
|
||
|
|
Amount struct {
|
||
|
|
Sum float64
|
||
|
|
Avg float64
|
||
|
|
Max float64
|
||
|
|
Min float64
|
||
|
|
Count int64
|
||
|
|
} `alias:"amount"`
|
||
|
|
}
|
||
|
|
|
||
|
|
err := stmt.QueryJSON(ctx, db, &dest)
|
||
|
|
require.NoError(t, err)
|
||
|
|
|
||
|
|
if sourceIsCockroachDB() {
|
||
|
|
return // small precision difference in result
|
||
|
|
}
|
||
|
|
|
||
|
|
testutils.AssertJSONFile(t, dest, "./testdata/results/postgres/customer_payment_sum.json")
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestSelectQuickStartJSON(t *testing.T) {
|
||
|
|
|
||
|
|
stmt := SELECT_JSON_ARR(
|
||
|
|
Actor.ActorID, Actor.FirstName, Actor.LastName, Actor.LastUpdate,
|
||
|
|
|
||
|
|
SELECT_JSON_ARR(
|
||
|
|
Film.AllColumns.Except(Film.SpecialFeatures),
|
||
|
|
CAST(Film.SpecialFeatures).AS_TEXT().AS("SpecialFeatures"),
|
||
|
|
|
||
|
|
SELECT_JSON_OBJ(
|
||
|
|
Language.AllColumns,
|
||
|
|
).FROM(
|
||
|
|
Language,
|
||
|
|
).WHERE(
|
||
|
|
Language.LanguageID.EQ(Film.LanguageID).AND(
|
||
|
|
Language.Name.EQ(Char(20)("English")),
|
||
|
|
),
|
||
|
|
).AS("Language"),
|
||
|
|
|
||
|
|
SELECT_JSON_ARR(
|
||
|
|
Category.AllColumns,
|
||
|
|
).FROM(
|
||
|
|
Category.
|
||
|
|
INNER_JOIN(FilmCategory, FilmCategory.CategoryID.EQ(Category.CategoryID)),
|
||
|
|
).WHERE(
|
||
|
|
FilmCategory.FilmID.EQ(Film.FilmID).AND(
|
||
|
|
Category.Name.NOT_EQ(Text("Action")),
|
||
|
|
),
|
||
|
|
).AS("Categories"),
|
||
|
|
).FROM(
|
||
|
|
Film.
|
||
|
|
INNER_JOIN(FilmActor, FilmActor.FilmID.EQ(Film.FilmID)),
|
||
|
|
).WHERE(
|
||
|
|
FilmActor.ActorID.EQ(Actor.ActorID).AND(Film.Length.GT(Int32(180))),
|
||
|
|
).ORDER_BY(
|
||
|
|
Film.FilmID.ASC(),
|
||
|
|
).AS("Films"),
|
||
|
|
).FROM(
|
||
|
|
Actor,
|
||
|
|
).ORDER_BY(
|
||
|
|
Actor.ActorID.ASC(),
|
||
|
|
)
|
||
|
|
|
||
|
|
testutils.AssertDebugStatementSql(t, stmt, `
|
||
|
|
SELECT json_agg(row_to_json(records)) AS "json"
|
||
|
|
FROM (
|
||
|
|
SELECT actor.actor_id AS "actorID",
|
||
|
|
actor.first_name AS "firstName",
|
||
|
|
actor.last_name AS "lastName",
|
||
|
|
actor.last_update AS "lastUpdate",
|
||
|
|
(
|
||
|
|
SELECT json_agg(row_to_json(films_records)) AS "films_json"
|
||
|
|
FROM (
|
||
|
|
SELECT film.film_id AS "filmID",
|
||
|
|
film.title AS "title",
|
||
|
|
film.description AS "description",
|
||
|
|
film.release_year AS "releaseYear",
|
||
|
|
film.language_id AS "languageID",
|
||
|
|
film.rental_duration AS "rentalDuration",
|
||
|
|
film.rental_rate AS "rentalRate",
|
||
|
|
film.length AS "length",
|
||
|
|
film.replacement_cost AS "replacementCost",
|
||
|
|
film.rating AS "rating",
|
||
|
|
film.last_update AS "lastUpdate",
|
||
|
|
film.fulltext AS "fulltext",
|
||
|
|
film.special_features::text AS "SpecialFeatures",
|
||
|
|
(
|
||
|
|
SELECT row_to_json(language_records) AS "language_json"
|
||
|
|
FROM (
|
||
|
|
SELECT language.language_id AS "languageID",
|
||
|
|
language.name AS "name",
|
||
|
|
language.last_update AS "lastUpdate"
|
||
|
|
FROM dvds.language
|
||
|
|
WHERE (language.language_id = film.language_id) AND (language.name = 'English'::char(20))
|
||
|
|
) AS language_records
|
||
|
|
) AS "Language",
|
||
|
|
(
|
||
|
|
SELECT json_agg(row_to_json(categories_records)) AS "categories_json"
|
||
|
|
FROM (
|
||
|
|
SELECT category.category_id AS "categoryID",
|
||
|
|
category.name AS "name",
|
||
|
|
category.last_update AS "lastUpdate"
|
||
|
|
FROM dvds.category
|
||
|
|
INNER JOIN dvds.film_category ON (film_category.category_id = category.category_id)
|
||
|
|
WHERE (film_category.film_id = film.film_id) AND (category.name != 'Action'::text)
|
||
|
|
) AS categories_records
|
||
|
|
) AS "Categories"
|
||
|
|
FROM dvds.film
|
||
|
|
INNER JOIN dvds.film_actor ON (film_actor.film_id = film.film_id)
|
||
|
|
WHERE (film_actor.actor_id = actor.actor_id) AND (film.length > 180::integer)
|
||
|
|
ORDER BY film.film_id ASC
|
||
|
|
) AS films_records
|
||
|
|
) AS "Films"
|
||
|
|
FROM dvds.actor
|
||
|
|
ORDER BY actor.actor_id ASC
|
||
|
|
) AS records;
|
||
|
|
`)
|
||
|
|
|
||
|
|
var dest []struct {
|
||
|
|
model.Actor
|
||
|
|
|
||
|
|
Films []struct {
|
||
|
|
model.Film
|
||
|
|
|
||
|
|
Language model.Language
|
||
|
|
Categories []model.Category
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
err := stmt.QueryJSON(ctx, db, &dest)
|
||
|
|
require.NoError(t, err)
|
||
|
|
require.Len(t, dest, 200)
|
||
|
|
|
||
|
|
if sourceIsCockroachDB() {
|
||
|
|
return // char[n] columns whitespaces are trimmed when returned as json in cockroachdb
|
||
|
|
}
|
||
|
|
|
||
|
|
//testutils.SaveJSONFile(dest, "./testdata/results/postgres/quick-start-json-dest2.json")
|
||
|
|
//testutils.AssertJSONFile(t, dest, "./testdata/results/postgres/quick-start-json-dest.json")
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestSelectJsonInReturning(t *testing.T) {
|
||
|
|
|
||
|
|
stmt := Rental.
|
||
|
|
UPDATE(Rental.ReturnDate).
|
||
|
|
MODEL(model.Rental{
|
||
|
|
ReturnDate: ptr.Of(time.Date(2010, 2, 4, 5, 6, 7, 8, time.UTC)),
|
||
|
|
}).
|
||
|
|
WHERE(
|
||
|
|
Rental.RentalID.EQ(Int(11496)),
|
||
|
|
).
|
||
|
|
RETURNING(
|
||
|
|
Rental.AllColumns.Except(Rental.LastUpdate),
|
||
|
|
|
||
|
|
SELECT_JSON_OBJ(
|
||
|
|
Customer.AllColumns,
|
||
|
|
).FROM(
|
||
|
|
Customer,
|
||
|
|
).WHERE(
|
||
|
|
Customer.CustomerID.EQ(Rental.CustomerID),
|
||
|
|
).AS("Customer"),
|
||
|
|
)
|
||
|
|
|
||
|
|
testutils.AssertStatementSql(t, stmt, `
|
||
|
|
UPDATE dvds.rental
|
||
|
|
SET return_date = $1
|
||
|
|
WHERE rental.rental_id = $2
|
||
|
|
RETURNING rental.rental_id AS "rental.rental_id",
|
||
|
|
rental.rental_date AS "rental.rental_date",
|
||
|
|
rental.inventory_id AS "rental.inventory_id",
|
||
|
|
rental.customer_id AS "rental.customer_id",
|
||
|
|
rental.return_date AS "rental.return_date",
|
||
|
|
rental.staff_id AS "rental.staff_id",
|
||
|
|
(
|
||
|
|
SELECT row_to_json(customer_records) AS "customer_json"
|
||
|
|
FROM (
|
||
|
|
SELECT customer.customer_id AS "customerID",
|
||
|
|
customer.store_id AS "storeID",
|
||
|
|
customer.first_name AS "firstName",
|
||
|
|
customer.last_name AS "lastName",
|
||
|
|
customer.email AS "email",
|
||
|
|
customer.address_id AS "addressID",
|
||
|
|
customer.activebool AS "activebool",
|
||
|
|
customer.create_date AS "createDate",
|
||
|
|
customer.last_update AS "lastUpdate",
|
||
|
|
customer.active AS "active"
|
||
|
|
FROM dvds.customer
|
||
|
|
WHERE customer.customer_id = rental.customer_id
|
||
|
|
) AS customer_records
|
||
|
|
) AS "Customer";
|
||
|
|
`)
|
||
|
|
|
||
|
|
testutils.ExecuteInTxAndRollback(t, db, func(tx qrm.DB) {
|
||
|
|
var dest struct {
|
||
|
|
model.Rental
|
||
|
|
|
||
|
|
Customer model.Customer `json_column:"Customer"`
|
||
|
|
}
|
||
|
|
|
||
|
|
err := stmt.Query(tx, &dest)
|
||
|
|
require.NoError(t, err)
|
||
|
|
testutils.AssertJSON(t, dest, `
|
||
|
|
{
|
||
|
|
"RentalID": 11496,
|
||
|
|
"RentalDate": "2006-02-14T15:16:03Z",
|
||
|
|
"InventoryID": 2047,
|
||
|
|
"CustomerID": 155,
|
||
|
|
"ReturnDate": "2010-02-04T05:06:07Z",
|
||
|
|
"StaffID": 1,
|
||
|
|
"LastUpdate": "0001-01-01T00:00:00Z",
|
||
|
|
"Customer": {
|
||
|
|
"CustomerID": 155,
|
||
|
|
"StoreID": 1,
|
||
|
|
"FirstName": "Gail",
|
||
|
|
"LastName": "Knight",
|
||
|
|
"Email": "gail.knight@sakilacustomer.org",
|
||
|
|
"AddressID": 159,
|
||
|
|
"Activebool": true,
|
||
|
|
"CreateDate": "2006-02-14T00:00:00Z",
|
||
|
|
"LastUpdate": "2013-05-26T14:49:45.738Z",
|
||
|
|
"Active": 1
|
||
|
|
}
|
||
|
|
}
|
||
|
|
`)
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestSelectJson_FetchFirst(t *testing.T) {
|
||
|
|
stmt := SELECT_JSON_ARR(Actor.AllColumns).
|
||
|
|
FROM(Actor).
|
||
|
|
ORDER_BY(Actor.ActorID).
|
||
|
|
OFFSET(2).
|
||
|
|
FETCH_FIRST(Int(3)).ROWS_ONLY()
|
||
|
|
|
||
|
|
testutils.AssertDebugStatementSql(t, stmt, `
|
||
|
|
SELECT json_agg(row_to_json(records)) AS "json"
|
||
|
|
FROM (
|
||
|
|
SELECT actor.actor_id AS "actorID",
|
||
|
|
actor.first_name AS "firstName",
|
||
|
|
actor.last_name AS "lastName",
|
||
|
|
actor.last_update AS "lastUpdate"
|
||
|
|
FROM dvds.actor
|
||
|
|
ORDER BY actor.actor_id
|
||
|
|
OFFSET 2
|
||
|
|
FETCH FIRST 3 ROWS ONLY
|
||
|
|
) AS records;
|
||
|
|
`)
|
||
|
|
|
||
|
|
var dest []model.Actor
|
||
|
|
|
||
|
|
err := stmt.QueryJSON(ctx, db, &dest)
|
||
|
|
require.NoError(t, err)
|
||
|
|
testutils.AssertJSON(t, dest, `
|
||
|
|
[
|
||
|
|
{
|
||
|
|
"ActorID": 3,
|
||
|
|
"FirstName": "Ed",
|
||
|
|
"LastName": "Chase",
|
||
|
|
"LastUpdate": "2013-05-26T14:47:57.62Z"
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"ActorID": 4,
|
||
|
|
"FirstName": "Jennifer",
|
||
|
|
"LastName": "Davis",
|
||
|
|
"LastUpdate": "2013-05-26T14:47:57.62Z"
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"ActorID": 5,
|
||
|
|
"FirstName": "Johnny",
|
||
|
|
"LastName": "Lollobrigida",
|
||
|
|
"LastUpdate": "2013-05-26T14:47:57.62Z"
|
||
|
|
}
|
||
|
|
]
|
||
|
|
`)
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestSelectJson_RowLock(t *testing.T) {
|
||
|
|
|
||
|
|
stmt := SELECT_JSON_OBJ(Actor.AllColumns).
|
||
|
|
FROM(Actor).
|
||
|
|
WHERE(Actor.ActorID.EQ(Int(200))).
|
||
|
|
FOR(UPDATE().NOWAIT())
|
||
|
|
|
||
|
|
testutils.AssertDebugStatementSql(t, stmt, `
|
||
|
|
SELECT row_to_json(records) AS "json"
|
||
|
|
FROM (
|
||
|
|
SELECT actor.actor_id AS "actorID",
|
||
|
|
actor.first_name AS "firstName",
|
||
|
|
actor.last_name AS "lastName",
|
||
|
|
actor.last_update AS "lastUpdate"
|
||
|
|
FROM dvds.actor
|
||
|
|
WHERE actor.actor_id = 200
|
||
|
|
FOR UPDATE NOWAIT
|
||
|
|
) AS records;
|
||
|
|
`)
|
||
|
|
|
||
|
|
testutils.ExecuteInTxAndRollback(t, db, func(tx qrm.DB) {
|
||
|
|
var dest model.Actor
|
||
|
|
|
||
|
|
err := stmt.QueryJSON(ctx, tx, &dest)
|
||
|
|
require.NoError(t, err)
|
||
|
|
testutils.AssertJSON(t, dest, `
|
||
|
|
{
|
||
|
|
"ActorID": 200,
|
||
|
|
"FirstName": "Thora",
|
||
|
|
"LastName": "Temple",
|
||
|
|
"LastUpdate": "2013-05-26T14:47:57.62Z"
|
||
|
|
}
|
||
|
|
`)
|
||
|
|
})
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestSelectJson_UNION(t *testing.T) {
|
||
|
|
|
||
|
|
stmt := UNION_ALL(
|
||
|
|
SELECT_JSON_OBJ(Actor.AllColumns).
|
||
|
|
FROM(Actor).
|
||
|
|
WHERE(Actor.ActorID.EQ(Int(20))),
|
||
|
|
|
||
|
|
SELECT_JSON_OBJ(Actor.AllColumns).
|
||
|
|
FROM(Actor).
|
||
|
|
WHERE(Actor.ActorID.EQ(Int(21))),
|
||
|
|
)
|
||
|
|
|
||
|
|
testutils.AssertDebugStatementSql(t, stmt, `
|
||
|
|
(
|
||
|
|
SELECT row_to_json(records) AS "json"
|
||
|
|
FROM (
|
||
|
|
SELECT actor.actor_id AS "actorID",
|
||
|
|
actor.first_name AS "firstName",
|
||
|
|
actor.last_name AS "lastName",
|
||
|
|
actor.last_update AS "lastUpdate"
|
||
|
|
FROM dvds.actor
|
||
|
|
WHERE actor.actor_id = 20
|
||
|
|
) AS records
|
||
|
|
)
|
||
|
|
UNION ALL
|
||
|
|
(
|
||
|
|
SELECT row_to_json(records) AS "json"
|
||
|
|
FROM (
|
||
|
|
SELECT actor.actor_id AS "actorID",
|
||
|
|
actor.first_name AS "firstName",
|
||
|
|
actor.last_name AS "lastName",
|
||
|
|
actor.last_update AS "lastUpdate"
|
||
|
|
FROM dvds.actor
|
||
|
|
WHERE actor.actor_id = 21
|
||
|
|
) AS records
|
||
|
|
);
|
||
|
|
`)
|
||
|
|
|
||
|
|
var dest []struct {
|
||
|
|
model.Actor `json_column:"json"`
|
||
|
|
}
|
||
|
|
|
||
|
|
err := stmt.Query(db, &dest)
|
||
|
|
require.NoError(t, err)
|
||
|
|
testutils.AssertJSON(t, dest, `
|
||
|
|
[
|
||
|
|
{
|
||
|
|
"ActorID": 20,
|
||
|
|
"FirstName": "Lucille",
|
||
|
|
"LastName": "Tracy",
|
||
|
|
"LastUpdate": "2013-05-26T14:47:57.62Z"
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"ActorID": 21,
|
||
|
|
"FirstName": "Kirsten",
|
||
|
|
"LastName": "Paltrow",
|
||
|
|
"LastUpdate": "2013-05-26T14:47:57.62Z"
|
||
|
|
}
|
||
|
|
]
|
||
|
|
`)
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestSelectJson_Window(t *testing.T) {
|
||
|
|
stmt := SELECT_JSON_ARR(
|
||
|
|
AVG(Payment.Amount).OVER().AS("avgOver"),
|
||
|
|
AVG(Payment.Amount).OVER(Window("w1")).AS("avgOverW1"),
|
||
|
|
AVG(Payment.Amount).OVER(
|
||
|
|
Window("w2").
|
||
|
|
ORDER_BY(Payment.CustomerID).
|
||
|
|
RANGE(PRECEDING(UNBOUNDED), FOLLOWING(UNBOUNDED)),
|
||
|
|
).AS("avgOverW2"),
|
||
|
|
AVG(Payment.Amount).OVER(Window("w3").RANGE(PRECEDING(UNBOUNDED), FOLLOWING(UNBOUNDED))).AS("avgOverW3"),
|
||
|
|
).FROM(
|
||
|
|
Payment,
|
||
|
|
).WINDOW("w1").AS(PARTITION_BY(Payment.PaymentDate)).
|
||
|
|
WINDOW("w2").AS(Window("w1")).
|
||
|
|
WINDOW("w3").AS(Window("w2").ORDER_BY(Payment.CustomerID)).
|
||
|
|
ORDER_BY(Payment.CustomerID).
|
||
|
|
LIMIT(4)
|
||
|
|
|
||
|
|
testutils.AssertDebugStatementSql(t, stmt, `
|
||
|
|
SELECT json_agg(row_to_json(records)) AS "json"
|
||
|
|
FROM (
|
||
|
|
SELECT AVG(payment.amount) OVER () AS "avgOver",
|
||
|
|
AVG(payment.amount) OVER (w1) AS "avgOverW1",
|
||
|
|
AVG(payment.amount) OVER (w2 ORDER BY payment.customer_id RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS "avgOverW2",
|
||
|
|
AVG(payment.amount) OVER (w3 RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS "avgOverW3"
|
||
|
|
FROM dvds.payment
|
||
|
|
WINDOW w1 AS (PARTITION BY payment.payment_date), w2 AS (w1), w3 AS (w2 ORDER BY payment.customer_id)
|
||
|
|
ORDER BY payment.customer_id
|
||
|
|
LIMIT 4
|
||
|
|
) AS records;
|
||
|
|
`)
|
||
|
|
|
||
|
|
var dest []struct {
|
||
|
|
AvgOver float64
|
||
|
|
AvgOverW1 float64
|
||
|
|
AvgOverW2 float64
|
||
|
|
AvgOverW3 float64
|
||
|
|
}
|
||
|
|
|
||
|
|
err := stmt.QueryJSON(ctx, db, &dest)
|
||
|
|
require.NoError(t, err)
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestSelectJson_QueryWithoutUnMarshaling(t *testing.T) {
|
||
|
|
stmt := SELECT_JSON_ARR(
|
||
|
|
view.CustomerList.AllColumns,
|
||
|
|
|
||
|
|
SELECT_JSON_ARR(Rental.AllColumns).
|
||
|
|
FROM(Rental).
|
||
|
|
WHERE(view.CustomerList.ID.EQ(Rental.CustomerID)).
|
||
|
|
ORDER_BY(Rental.CustomerID).
|
||
|
|
AS("Rentals"),
|
||
|
|
).FROM(
|
||
|
|
view.CustomerList,
|
||
|
|
).WHERE(
|
||
|
|
view.CustomerList.ID.LT_EQ(Int(2)),
|
||
|
|
).ORDER_BY(
|
||
|
|
view.CustomerList.ID,
|
||
|
|
)
|
||
|
|
|
||
|
|
//fmt.Println(stmt.DebugSql())
|
||
|
|
|
||
|
|
testutils.AssertDebugStatementSql(t, stmt, `
|
||
|
|
SELECT json_agg(row_to_json(records)) AS "json"
|
||
|
|
FROM (
|
||
|
|
SELECT customer_list.id AS "id",
|
||
|
|
customer_list.name AS "name",
|
||
|
|
customer_list.address AS "address",
|
||
|
|
customer_list."zip code" AS "zip code",
|
||
|
|
customer_list.phone AS "phone",
|
||
|
|
customer_list.city AS "city",
|
||
|
|
customer_list.country AS "country",
|
||
|
|
customer_list.notes AS "notes",
|
||
|
|
customer_list.sid AS "sid",
|
||
|
|
(
|
||
|
|
SELECT json_agg(row_to_json(rentals_records)) AS "rentals_json"
|
||
|
|
FROM (
|
||
|
|
SELECT rental.rental_id AS "rentalID",
|
||
|
|
rental.rental_date AS "rentalDate",
|
||
|
|
rental.inventory_id AS "inventoryID",
|
||
|
|
rental.customer_id AS "customerID",
|
||
|
|
rental.return_date AS "returnDate",
|
||
|
|
rental.staff_id AS "staffID",
|
||
|
|
rental.last_update AS "lastUpdate"
|
||
|
|
FROM dvds.rental
|
||
|
|
WHERE customer_list.id = rental.customer_id
|
||
|
|
ORDER BY rental.customer_id
|
||
|
|
) AS rentals_records
|
||
|
|
) AS "Rentals"
|
||
|
|
FROM dvds.customer_list
|
||
|
|
WHERE customer_list.id <= 2
|
||
|
|
ORDER BY customer_list.id
|
||
|
|
) AS records;
|
||
|
|
`)
|
||
|
|
|
||
|
|
var dest struct {
|
||
|
|
Json []byte
|
||
|
|
}
|
||
|
|
|
||
|
|
err := stmt.Query(db, &dest)
|
||
|
|
require.NoError(t, err)
|
||
|
|
|
||
|
|
if sourceIsCockroachDB() {
|
||
|
|
require.Equal(t, string(dest.Json), `[{"Rentals": [{"customerID": 1, "inventoryID": 3021, "lastUpdate": "2006-02-16T02:30:53", "rentalDate": "2005-05-25T11:30:37", "rentalID": 76, "returnDate": "2005-06-03T12:00:37", "staffID": 2}, {"customerID": 1, "inventoryID": 4020, "lastUpdate": "2006-02-16T02:30:53", "rentalDate": "2005-05-28T10:35:23", "rentalID": 573, "returnDate": "2005-06-03T06:32:23", "staffID": 1}, {"customerID": 1, "inventoryID": 2785, "lastUpdate": "2006-02-16T02:30:53", "rentalDate": "2005-06-15T00:54:12", "rentalID": 1185, "returnDate": "2005-06-23T02:42:12", "staffID": 2}, {"customerID": 1, "inventoryID": 1021, "lastUpdate": "2006-02-16T02:30:53", "rentalDate": "2005-06-15T18:02:53", "rentalID": 1422, "returnDate": "2005-06-19T15:54:53", "staffID": 2}, {"customerID": 1, "inventoryID": 1407, "lastUpdate": "2006-02-16T02:30:53", "rentalDate": "2005-06-15T21:08:46", "rentalID": 1476, "returnDate": "2005-06-25T02:26:46", "staffID": 1}, {"customerID": 1, "inventoryID": 726, "lastUpdate": "2006-02-16T02:30:53", "rentalDate": "2005-06-16T15:18:57", "rentalID": 1725, "returnDate": "2005-06-17T21:05:57", "staffID": 1}, {"customerID": 1, "inventoryID": 197, "lastUpdate": "2006-02-16T02:30:53", "rentalDate": "2005-06-18T08:41:48", "rentalID": 2308, "returnDate": "2005-06-22T03:36:48", "staffID": 2}, {"customerID": 1, "inventoryID": 3497, "lastUpdate": "2006-02-16T02:30:53", "rentalDate": "2005-06-18T13:33:59", "rentalID": 2363, "returnDate": "2005-06-19T17:40:59", "staffID": 1}, {"customerID": 1, "inventoryID": 4566, "lastUpdate": "2006-02-16T02:30:53", "rentalDate": "2005-06-21T06:24:45", "rentalID": 3284, "returnDate": "2005-06-28T03:28:45", "staffID": 1}, {"customerID": 1, "inventoryID": 1443, "lastUpdate": "2006-02-16T02:30:53", "rentalDate": "2005-07-08T03:17:05", "rentalID": 4526, "returnDate": "2005-07-14T01:19:05", "staffID": 2}, {"customerID": 1, "inventoryID": 3486, "lastUpdate": "2006-02-16T02:30:53", "rentalDate": "2005-07-08T07:33:56", "rentalID": 4611, "returnDate": "2005-07-12T13:25:56", "staffID": 2}, {"customerID": 1, "inventoryID": 3726, "lastUpdate": "2006-02-16T02:30:53", "rentalDate": "2005-07-09T13:24:07", "rentalID": 5244, "returnDate": "2005-07-14T14:01:07", "staffID": 2}, {"customerID": 1, "inventoryID": 797, "lastUpdate": "2006-02-16T02:30:53", "rentalDate": "2005-07-09T16:38:01", "rentalID": 5326, "returnDate": "2005-07-13T18:02:01", "staffID": 1}, {"customerID": 1, "inventoryID": 1330, "lastUpdate": "2006-02-16T02:30:53", "rentalDate": "2005-07-11T10:13:46", "rentalID": 6163, "returnDate": "2005-07-19T13:15:46", "staffID": 2}, {"customerID": 1, "inventoryID": 2465, "lastUpdate": "2006-02-16T02:30:53", "rentalDate": "2005-07-27T11:31:22", "rentalID": 7273, "returnDate": "2005-07-31T06:50:22", "staffID": 1}, {"customerID": 1, "inventoryID": 1092, "lastUpdate": "2006-02-16T02:30:53", "rentalDate": "2005-07-28T09:04:45", "rentalID": 7841, "returnDate": "2005-07-30T12:37:45", "staffID": 2}, {"customerID": 1, "inventoryID": 4268, "lastUpdate": "2006-02-16T02:30:53", "rentalDate": "2005-07-28T16:18:23", "rentalID": 8033, "returnDate": "2005-07-30T17:56:23", "staffID": 1}, {"customerID": 1, "inventoryID": 1558, "lastUpdate": "2006-02-16T02:30:53", "rentalDate": "2005-07-28T17:33:39", "rentalID": 8074, "returnDate": "2005-07-29T20:17:39", "staffID": 1}, {"customerID": 1, "inventoryID": 4497, "lastUpdate": "2006-02-16T02:30:53", "rentalDate": "2005-07-28T19:20:07", "rentalID": 8116, "returnDate": "2005-07-29T22:54:07", "staffID": 1}, {"customerID": 1, "inventoryID": 108, "lastUpdate": "2006-02-16T02:30:53", "rentalDate": "2005-07-29T03:58:49", "rentalID": 8326, "returnDate": "2005-08-01T05:16:49", "staffID": 2}, {"customerID": 1, "inventoryID": 2219, "lastUpdate": "2006-02-16T02:30:53", "rentalDate": "2005-07-31T02:42:18", "rentalID": 9571, "returnDate": "2005-08-02T23:26:18", "staffID": 2}, {"customerID": 1, "inventoryID": 14, "lastUpdate": "2006-02-16T02:30:53", "rentalDate": "2005-08-01T08:51:04", "rentalID": 10437, "returnDate": "2005-08-10T12:12:04", "staffID": 1}, {"customerID": 1, "inven
|
||
|
|
} else {
|
||
|
|
require.Equal(t, string(dest.Json), `[{"id":1,"name":"Mary Smith","address":"1913 Hanoi Way","zip code":"35200","phone":"28303384290","city":"Sasebo","country":"Japan","notes":"active","sid":1,"Rentals":[{"rentalID":76,"rentalDate":"2005-05-25T11:30:37","inventoryID":3021,"customerID":1,"returnDate":"2005-06-03T12:00:37","staffID":2,"lastUpdate":"2006-02-16T02:30:53"}, {"rentalID":573,"rentalDate":"2005-05-28T10:35:23","inventoryID":4020,"customerID":1,"returnDate":"2005-06-03T06:32:23","staffID":1,"lastUpdate":"2006-02-16T02:30:53"}, {"rentalID":1185,"rentalDate":"2005-06-15T00:54:12","inventoryID":2785,"customerID":1,"returnDate":"2005-06-23T02:42:12","staffID":2,"lastUpdate":"2006-02-16T02:30:53"}, {"rentalID":1422,"rentalDate":"2005-06-15T18:02:53","inventoryID":1021,"customerID":1,"returnDate":"2005-06-19T15:54:53","staffID":2,"lastUpdate":"2006-02-16T02:30:53"}, {"rentalID":1476,"rentalDate":"2005-06-15T21:08:46","inventoryID":1407,"customerID":1,"returnDate":"2005-06-25T02:26:46","staffID":1,"lastUpdate":"2006-02-16T02:30:53"}, {"rentalID":1725,"rentalDate":"2005-06-16T15:18:57","inventoryID":726,"customerID":1,"returnDate":"2005-06-17T21:05:57","staffID":1,"lastUpdate":"2006-02-16T02:30:53"}, {"rentalID":2308,"rentalDate":"2005-06-18T08:41:48","inventoryID":197,"customerID":1,"returnDate":"2005-06-22T03:36:48","staffID":2,"lastUpdate":"2006-02-16T02:30:53"}, {"rentalID":2363,"rentalDate":"2005-06-18T13:33:59","inventoryID":3497,"customerID":1,"returnDate":"2005-06-19T17:40:59","staffID":1,"lastUpdate":"2006-02-16T02:30:53"}, {"rentalID":3284,"rentalDate":"2005-06-21T06:24:45","inventoryID":4566,"customerID":1,"returnDate":"2005-06-28T03:28:45","staffID":1,"lastUpdate":"2006-02-16T02:30:53"}, {"rentalID":4526,"rentalDate":"2005-07-08T03:17:05","inventoryID":1443,"customerID":1,"returnDate":"2005-07-14T01:19:05","staffID":2,"lastUpdate":"2006-02-16T02:30:53"}, {"rentalID":4611,"rentalDate":"2005-07-08T07:33:56","inventoryID":3486,"customerID":1,"returnDate":"2005-07-12T13:25:56","staffID":2,"lastUpdate":"2006-02-16T02:30:53"}, {"rentalID":5244,"rentalDate":"2005-07-09T13:24:07","inventoryID":3726,"customerID":1,"returnDate":"2005-07-14T14:01:07","staffID":2,"lastUpdate":"2006-02-16T02:30:53"}, {"rentalID":5326,"rentalDate":"2005-07-09T16:38:01","inventoryID":797,"customerID":1,"returnDate":"2005-07-13T18:02:01","staffID":1,"lastUpdate":"2006-02-16T02:30:53"}, {"rentalID":6163,"rentalDate":"2005-07-11T10:13:46","inventoryID":1330,"customerID":1,"returnDate":"2005-07-19T13:15:46","staffID":2,"lastUpdate":"2006-02-16T02:30:53"}, {"rentalID":7273,"rentalDate":"2005-07-27T11:31:22","inventoryID":2465,"customerID":1,"returnDate":"2005-07-31T06:50:22","staffID":1,"lastUpdate":"2006-02-16T02:30:53"}, {"rentalID":7841,"rentalDate":"2005-07-28T09:04:45","inventoryID":1092,"customerID":1,"returnDate":"2005-07-30T12:37:45","staffID":2,"lastUpdate":"2006-02-16T02:30:53"}, {"rentalID":8033,"rentalDate":"2005-07-28T16:18:23","inventoryID":4268,"customerID":1,"returnDate":"2005-07-30T17:56:23","staffID":1,"lastUpdate":"2006-02-16T02:30:53"}, {"rentalID":8074,"rentalDate":"2005-07-28T17:33:39","inventoryID":1558,"customerID":1,"returnDate":"2005-07-29T20:17:39","staffID":1,"lastUpdate":"2006-02-16T02:30:53"}, {"rentalID":8116,"rentalDate":"2005-07-28T19:20:07","inventoryID":4497,"customerID":1,"returnDate":"2005-07-29T22:54:07","staffID":1,"lastUpdate":"2006-02-16T02:30:53"}, {"rentalID":8326,"rentalDate":"2005-07-29T03:58:49","inventoryID":108,"customerID":1,"returnDate":"2005-08-01T05:16:49","staffID":2,"lastUpdate":"2006-02-16T02:30:53"}, {"rentalID":9571,"rentalDate":"2005-07-31T02:42:18","inventoryID":2219,"customerID":1,"returnDate":"2005-08-02T23:26:18","staffID":2,"lastUpdate":"2006-02-16T02:30:53"}, {"rentalID":10437,"rentalDate":"2005-08-01T08:51:04","inventoryID":14,"customerID":1,"returnDate":"2005-08-10T12:12:04","staffID":1,"lastUpdate":"2006-02-16T02:30:53"}, {"rentalID":11299,"rentalDate":"2005-08-02T15:36:52","inventoryID":3232,"customerID":1,"returnDate":"2005-08-10T16:40:52","staffID":2,"lastUpdate":"2006-02-1
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestSelectJsonObject_EmptyResult(t *testing.T) {
|
||
|
|
t.Run("json obj", func(t *testing.T) {
|
||
|
|
stmt := SELECT_JSON_OBJ(Actor.AllColumns).
|
||
|
|
FROM(Actor).
|
||
|
|
WHERE(Actor.FirstName.EQ(Text("Kowalski")))
|
||
|
|
|
||
|
|
var dest model.Actor
|
||
|
|
|
||
|
|
err := stmt.QueryJSON(ctx, db, &dest)
|
||
|
|
require.ErrorIs(t, err, qrm.ErrNoRows)
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("json arr", func(t *testing.T) {
|
||
|
|
stmt := SELECT_JSON_ARR(Actor.AllColumns).
|
||
|
|
FROM(Actor).
|
||
|
|
WHERE(Actor.FirstName.EQ(Text("Kowalski")))
|
||
|
|
|
||
|
|
var dest []model.Actor
|
||
|
|
|
||
|
|
err := stmt.QueryJSON(ctx, db, &dest)
|
||
|
|
require.NoError(t, err)
|
||
|
|
require.Empty(t, dest)
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestSelectJson_InvalidDestination(t *testing.T) {
|
||
|
|
t.Run("json obj", func(t *testing.T) {
|
||
|
|
stmt := SELECT_JSON_OBJ(Actor.AllColumns).
|
||
|
|
FROM(Actor)
|
||
|
|
|
||
|
|
testutils.AssertQueryJsonPanicErr(t, stmt, db, &[]model.Actor{}, "jet: destination has to be a pointer to struct or pointer to map[string]any")
|
||
|
|
testutils.AssertQueryJsonPanicErr(t, stmt, db, model.Actor{}, "jet: destination has to be a pointer to struct or pointer to map[string]any")
|
||
|
|
testutils.AssertQueryJsonPanicErr(t, stmt, nil, &model.Actor{}, "jet: db is nil")
|
||
|
|
testutils.AssertQueryJsonPanicErr(t, stmt, db, nil, "jet: destination is nil")
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("json arr", func(t *testing.T) {
|
||
|
|
stmt := SELECT_JSON_ARR(Actor.AllColumns).
|
||
|
|
FROM(Actor)
|
||
|
|
|
||
|
|
testutils.AssertQueryJsonPanicErr(t, stmt, db, &model.Actor{}, "jet: destination has to be a pointer to slice of struct or pointer to []map[string]any")
|
||
|
|
testutils.AssertQueryJsonPanicErr(t, stmt, db, []model.Actor{}, "jet: destination has to be a pointer to slice of struct or pointer to []map[string]any")
|
||
|
|
testutils.AssertQueryJsonPanicErr(t, stmt, nil, &[]model.Actor{}, "jet: db is nil")
|
||
|
|
testutils.AssertQueryJsonPanicErr(t, stmt, db, nil, "jet: destination is nil")
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestSelectJson_ProjectionNotAliased(t *testing.T) {
|
||
|
|
t.Run("statement not aliased", func(t *testing.T) {
|
||
|
|
testutils.AssertPanicErr(t, func() {
|
||
|
|
stmt := SELECT_JSON_ARR(
|
||
|
|
Customer.AllColumns,
|
||
|
|
|
||
|
|
SELECT_JSON_ARR(Rental.AllColumns).
|
||
|
|
FROM(Rental).
|
||
|
|
WHERE(Rental.CustomerID.EQ(Customer.CustomerID)),
|
||
|
|
).FROM(Customer)
|
||
|
|
|
||
|
|
stmt.DebugSql()
|
||
|
|
|
||
|
|
}, "jet: SELECT JSON statements need to be aliased when used as a projection.")
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("expression not aliased", func(t *testing.T) {
|
||
|
|
testutils.AssertPanicErr(t, func() {
|
||
|
|
stmt := SELECT_JSON_ARR(
|
||
|
|
Int(2).ADD(Customer.CustomerID),
|
||
|
|
).FROM(Customer)
|
||
|
|
|
||
|
|
stmt.DebugSql()
|
||
|
|
|
||
|
|
}, "jet: expression need to be aliased when used as SELECT JSON projection.")
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestSelectJson_MoreThenOneRowErr(t *testing.T) {
|
||
|
|
actors := SELECT_JSON_ARR(Actor.AllColumns).
|
||
|
|
FROM(Actor).
|
||
|
|
WHERE(Actor.ActorID.BETWEEN(Int(20), Int(30)))
|
||
|
|
|
||
|
|
stmt := UNION_ALL(actors, actors)
|
||
|
|
|
||
|
|
var dest []model.Actor
|
||
|
|
|
||
|
|
err := stmt.QueryJSON(ctx, db, &dest)
|
||
|
|
require.ErrorContains(t, err, "jet: query returned more then one row")
|
||
|
|
}
|