Change structure aliasing order.
This commit is contained in:
parent
8be33b8774
commit
b7ba58200e
9 changed files with 402 additions and 406 deletions
22
README.md
22
README.md
|
|
@ -214,7 +214,7 @@ var dest []struct {
|
|||
Films []struct {
|
||||
model.Film
|
||||
Language model.Language
|
||||
Category []model.Category
|
||||
Categories []model.Category
|
||||
}
|
||||
}
|
||||
```
|
||||
|
|
@ -263,7 +263,7 @@ fmt.Println(string(jsonText))
|
|||
"Name": "English ",
|
||||
"LastUpdate": "2006-02-15T10:02:19Z"
|
||||
},
|
||||
"Category": [
|
||||
"Categories": [
|
||||
{
|
||||
"CategoryID": 8,
|
||||
"Name": "Family",
|
||||
|
|
@ -298,7 +298,7 @@ fmt.Println(string(jsonText))
|
|||
"Name": "English ",
|
||||
"LastUpdate": "2006-02-15T10:02:19Z"
|
||||
},
|
||||
"Category": [
|
||||
"Categories": [
|
||||
{
|
||||
"CategoryID": 6,
|
||||
"Name": "Documentary",
|
||||
|
|
@ -319,8 +319,8 @@ In that case we can reuse above statement `stmt`, and just change our destinatio
|
|||
var dest2 []struct {
|
||||
model.Category
|
||||
|
||||
Film []model.Film
|
||||
Actor []model.Actor
|
||||
Films []model.Film
|
||||
Actors []model.Actor
|
||||
}
|
||||
|
||||
err = stmt.Query(db, &dest2)
|
||||
|
|
@ -335,7 +335,7 @@ handleError(err)
|
|||
"CategoryID": 8,
|
||||
"Name": "Family",
|
||||
"LastUpdate": "2006-02-15T09:46:27Z",
|
||||
"Film": [
|
||||
"Films": [
|
||||
{
|
||||
"FilmID": 499,
|
||||
"Title": "King Evolution",
|
||||
|
|
@ -367,7 +367,7 @@ handleError(err)
|
|||
"Fulltext": "'bake':1 'cleopatra':2 'drama':5 'forens':8 'husband':12 'monasteri':20 'must':14 'overcom':15 'psychologist':9 'stun':4 'waitress':17"
|
||||
}
|
||||
],
|
||||
"Actor": [
|
||||
"Actors": [
|
||||
{
|
||||
"ActorID": 1,
|
||||
"FirstName": "Penelope",
|
||||
|
|
@ -418,6 +418,14 @@ handleError(err)
|
|||
|
||||
Complete code example can be found at [./examples/quick-start/quick-start.go](./examples/quick-start/quick-start.go)
|
||||
|
||||
|
||||
This example represent probably the most common use case, but Jet offers much more. Like subqueries, INSERT, UPDATE, DELETE, LOCK statements and much more.
|
||||
Detail info can be found at project wiki page.
|
||||
|
||||
# Benefits
|
||||
|
||||
TODO:
|
||||
|
||||
# Contributing
|
||||
|
||||
# Versioning
|
||||
|
|
|
|||
|
|
@ -57,8 +57,8 @@ func main() {
|
|||
model.Actor
|
||||
Films []struct {
|
||||
model.Film
|
||||
Language model.Language
|
||||
Category []model.Category
|
||||
Language model.Language
|
||||
Categories []model.Category
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -72,8 +72,8 @@ func main() {
|
|||
var dest2 []struct {
|
||||
model.Category
|
||||
|
||||
Film []model.Film
|
||||
Actor []model.Actor
|
||||
Films []model.Film
|
||||
Actors []model.Actor
|
||||
}
|
||||
|
||||
err = stmt.Query(db, &dest2)
|
||||
|
|
|
|||
|
|
@ -139,7 +139,7 @@ func mapRowToSlice(scanContext *scanContext, groupKey string, slicePtrValue refl
|
|||
if isGoBaseType(sliceElemType) {
|
||||
index := 0
|
||||
if structField != nil {
|
||||
tableName, columnName := getRefTableNameFrom(structField)
|
||||
tableName, columnName := getRefAlias(structField)
|
||||
index = scanContext.columnIndex(tableName, columnName)
|
||||
|
||||
if index < 0 {
|
||||
|
|
@ -297,7 +297,7 @@ func mapRowToStruct(scanContext *scanContext, groupKey string, structPtrValue re
|
|||
structType := structPtrValue.Type().Elem()
|
||||
structValue := structPtrValue.Elem()
|
||||
|
||||
tableName, _ := getRefTableNameFrom(structField)
|
||||
tableName, _ := getRefAlias(structField)
|
||||
|
||||
if tableName == "" {
|
||||
tableName = structType.Name()
|
||||
|
|
@ -365,30 +365,26 @@ func mapRowToStruct(scanContext *scanContext, groupKey string, structPtrValue re
|
|||
return
|
||||
}
|
||||
|
||||
func getRefTableNameFrom(structField *reflect.StructField) (table, column string) {
|
||||
func getRefAlias(structField *reflect.StructField) (table, column string) {
|
||||
if structField == nil {
|
||||
return
|
||||
}
|
||||
|
||||
sqlTag := structField.Tag.Get("sql")
|
||||
aliasTag := structField.Tag.Get("alias")
|
||||
|
||||
if sqlTag != "" {
|
||||
tagInfo := tagInfo(sqlTag)
|
||||
|
||||
return tagInfo.table, tagInfo.column
|
||||
if aliasTag == "" {
|
||||
return
|
||||
}
|
||||
|
||||
if !structField.Anonymous {
|
||||
return structField.Name, ""
|
||||
aliasParts := strings.Split(aliasTag, ".")
|
||||
|
||||
table = aliasParts[0]
|
||||
|
||||
if len(aliasParts) > 1 {
|
||||
column = aliasParts[1]
|
||||
}
|
||||
|
||||
fieldType := indirectType(structField.Type)
|
||||
|
||||
if fieldType.Kind() == reflect.Slice {
|
||||
fieldType = fieldType.Elem()
|
||||
}
|
||||
|
||||
return fieldType.Name(), ""
|
||||
return
|
||||
}
|
||||
|
||||
func initializeValueIfNilPtr(value reflect.Value) {
|
||||
|
|
@ -612,7 +608,7 @@ func (s *scanContext) constructGroupKey(groupKeyInfo groupKeyInfo) string {
|
|||
}
|
||||
|
||||
func (s *scanContext) getGroupKeyInfo(structType reflect.Type, structField *reflect.StructField) groupKeyInfo {
|
||||
tableName, _ := getRefTableNameFrom(structField)
|
||||
tableName, _ := getRefAlias(structField)
|
||||
|
||||
if tableName == "" {
|
||||
tableName = structType.Name()
|
||||
|
|
@ -638,7 +634,7 @@ func (s *scanContext) getGroupKeyInfo(structType reflect.Type, structField *refl
|
|||
if len(subType.indexes) != 0 || len(subType.subTypes) != 0 {
|
||||
ret.subTypes = append(ret.subTypes, subType)
|
||||
}
|
||||
} else if tagInfo(field.Tag.Get("sql")).isPrimaryKey {
|
||||
} else if isPrimaryKey(field) {
|
||||
index := s.columnIndex(tableName, field.Name)
|
||||
|
||||
if index < 0 {
|
||||
|
|
@ -741,35 +737,11 @@ func (s *scanContext) rowElemValuePtr(index int) reflect.Value {
|
|||
return newElem
|
||||
}
|
||||
|
||||
type sqlTagInfo struct {
|
||||
isPrimaryKey bool
|
||||
table string
|
||||
column string
|
||||
}
|
||||
func isPrimaryKey(field reflect.StructField) bool {
|
||||
|
||||
func tagInfo(tag string) sqlTagInfo {
|
||||
sqlTags := strings.Split(tag, ",")
|
||||
tagMap := map[string]string{}
|
||||
sqlTag := field.Tag.Get("sql")
|
||||
|
||||
for _, tag := range sqlTags {
|
||||
tagParts := strings.Split(tag, ":")
|
||||
|
||||
tagKey := tagParts[0]
|
||||
tagValue := ""
|
||||
if len(tagParts) > 1 {
|
||||
tagValue = tagParts[1]
|
||||
}
|
||||
|
||||
tagMap[tagKey] = tagValue
|
||||
}
|
||||
|
||||
_, isPrimaryKey := tagMap["primary_key"]
|
||||
|
||||
return sqlTagInfo{
|
||||
isPrimaryKey: isPrimaryKey,
|
||||
table: tagMap["table"],
|
||||
column: tagMap["column"],
|
||||
}
|
||||
return sqlTag == "primary_key"
|
||||
}
|
||||
|
||||
func indirectType(reflectType reflect.Type) reflect.Type {
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ func TestJoinEverything(t *testing.T) {
|
|||
Genre model.Genre // track genre
|
||||
MediaType model.MediaType // track media type
|
||||
|
||||
Playlists []model.Playlist `sql:"table:Playlist"` // list of playlist where track is used
|
||||
Playlists []model.Playlist // list of playlist where track is used
|
||||
|
||||
Invoices []struct { // list of invoices where track occurs
|
||||
model.Invoice
|
||||
|
|
@ -94,7 +94,7 @@ func TestJoinEverything(t *testing.T) {
|
|||
Employee *struct { // employee data for customer if exists
|
||||
model.Employee
|
||||
|
||||
Manager *model.Employee
|
||||
Manager *model.Employee `alias:"Manager"`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,15 +5,15 @@ import (
|
|||
"github.com/davecgh/go-spew/spew"
|
||||
. "github.com/go-jet/jet"
|
||||
"github.com/go-jet/jet/tests/.gentestdata/jetdb/test_sample/model"
|
||||
"github.com/go-jet/jet/tests/.gentestdata/jetdb/test_sample/table"
|
||||
. "github.com/go-jet/jet/tests/.gentestdata/jetdb/test_sample/table"
|
||||
"gotest.tools/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestUUIDType(t *testing.T) {
|
||||
query := table.AllTypes.
|
||||
SELECT(table.AllTypes.AllColumns).
|
||||
WHERE(table.AllTypes.UUID.EQ(String("a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11")))
|
||||
query := AllTypes.
|
||||
SELECT(AllTypes.AllColumns).
|
||||
WHERE(AllTypes.UUID.EQ(String("a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11")))
|
||||
|
||||
queryStr, args, err := query.Sql()
|
||||
|
||||
|
|
@ -28,8 +28,8 @@ func TestUUIDType(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestEnumType(t *testing.T) {
|
||||
query := table.Person.
|
||||
SELECT(table.Person.AllColumns)
|
||||
query := Person.
|
||||
SELECT(Person.AllColumns)
|
||||
|
||||
queryStr, args, err := query.Sql()
|
||||
|
||||
|
|
@ -56,3 +56,63 @@ func TestEnumType(t *testing.T) {
|
|||
|
||||
spew.Dump(result2)
|
||||
}
|
||||
|
||||
func TestSelecSelfJoin1(t *testing.T) {
|
||||
|
||||
var expectedSql = `
|
||||
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",
|
||||
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"
|
||||
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)
|
||||
|
||||
assertStatementSql(t, query, expectedSql)
|
||||
|
||||
type Manager model.Employee
|
||||
|
||||
var dest []struct {
|
||||
model.Employee
|
||||
|
||||
Manager *Manager
|
||||
}
|
||||
|
||||
err := query.Query(db, &dest)
|
||||
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, len(dest), 8)
|
||||
assert.DeepEqual(t, dest[0].Employee, model.Employee{
|
||||
EmployeeID: 1,
|
||||
FirstName: "Windy",
|
||||
LastName: "Hays",
|
||||
EmploymentDate: timestampWithTimeZone("1999-01-08 04:05:06.1 +0100 CET", 1),
|
||||
ManagerID: nil,
|
||||
})
|
||||
|
||||
assert.Assert(t, dest[0].Manager == nil)
|
||||
|
||||
assert.DeepEqual(t, dest[7].Employee, model.Employee{
|
||||
EmployeeID: 8,
|
||||
FirstName: "Salley",
|
||||
LastName: "Lester",
|
||||
EmploymentDate: timestampWithTimeZone("1999-01-08 04:05:06 +0100 CET", 1),
|
||||
ManagerID: int32Ptr(3),
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -144,7 +144,7 @@ func TestScanToStruct(t *testing.T) {
|
|||
|
||||
t.Run("custom struct", func(t *testing.T) {
|
||||
type Inventory struct {
|
||||
InventoryID *int32 `sql:"unique"`
|
||||
InventoryID *int32 `sql:"primary_key"`
|
||||
FilmID int16
|
||||
StoreID *int16
|
||||
}
|
||||
|
|
@ -373,8 +373,8 @@ func TestScanToNestedStruct(t *testing.T) {
|
|||
model.Film
|
||||
|
||||
Language model.Language
|
||||
Language2 *model.Language
|
||||
Language3 *Language3 `sql:"table:language"`
|
||||
Language2 *model.Language `alias:"Language.*"`
|
||||
Language3 *Language3 `alias:"language"`
|
||||
Lang struct {
|
||||
model.Language
|
||||
}
|
||||
|
|
@ -394,7 +394,7 @@ func TestScanToNestedStruct(t *testing.T) {
|
|||
assert.DeepEqual(t, dest.Film.Language, language1)
|
||||
assert.DeepEqual(t, dest.Film.Lang.Language, language1)
|
||||
assert.DeepEqual(t, dest.Film.Lang2.Language, language1)
|
||||
assert.DeepEqual(t, dest.Film.Language2, (*model.Language)(nil))
|
||||
assert.DeepEqual(t, dest.Film.Language2, &language1)
|
||||
assert.DeepEqual(t, model.Language(*dest.Film.Language3), language1)
|
||||
})
|
||||
}
|
||||
|
|
@ -439,14 +439,18 @@ func TestScanToSlice(t *testing.T) {
|
|||
query := Inventory.
|
||||
INNER_JOIN(Film, Inventory.FilmID.EQ(Film.FilmID)).
|
||||
INNER_JOIN(Store, Inventory.StoreID.EQ(Store.StoreID)).
|
||||
SELECT(Inventory.AllColumns, Film.AllColumns, Store.AllColumns).
|
||||
SELECT(
|
||||
Inventory.AllColumns,
|
||||
Film.AllColumns,
|
||||
Store.AllColumns,
|
||||
).
|
||||
ORDER_BY(Inventory.InventoryID).
|
||||
LIMIT(10)
|
||||
|
||||
t.Run("struct with slice of ints", func(t *testing.T) {
|
||||
var dest struct {
|
||||
model.Film
|
||||
IDs []int32 `sql:"table:inventory,column:inventory_id"`
|
||||
IDs []int32 `alias:"inventory.inventory_id"`
|
||||
}
|
||||
|
||||
err := query.Query(db, &dest)
|
||||
|
|
@ -463,7 +467,7 @@ func TestScanToSlice(t *testing.T) {
|
|||
t.Run("slice of structs with slice of ints", func(t *testing.T) {
|
||||
var dest []struct {
|
||||
model.Film
|
||||
IDs []int32 `sql:"table:inventory,column:inventory_id"`
|
||||
IDs []int32 `alias:"Inventory.inventory_id"`
|
||||
}
|
||||
|
||||
err := query.Query(db, &dest)
|
||||
|
|
@ -479,7 +483,7 @@ func TestScanToSlice(t *testing.T) {
|
|||
t.Run("slice of structs with slice of pointer to ints", func(t *testing.T) {
|
||||
var dest []struct {
|
||||
model.Film
|
||||
IDs []*int32 `sql:"table:inventory,column:inventory_id"`
|
||||
IDs []*int32 `alias:"inventory.InventoryId"`
|
||||
}
|
||||
|
||||
err := query.Query(db, &dest)
|
||||
|
|
|
|||
|
|
@ -7,8 +7,6 @@ import (
|
|||
"github.com/go-jet/jet/tests/.gentestdata/jetdb/dvds/enum"
|
||||
"github.com/go-jet/jet/tests/.gentestdata/jetdb/dvds/model"
|
||||
. "github.com/go-jet/jet/tests/.gentestdata/jetdb/dvds/table"
|
||||
model2 "github.com/go-jet/jet/tests/.gentestdata/jetdb/test_sample/model"
|
||||
. "github.com/go-jet/jet/tests/.gentestdata/jetdb/test_sample/table"
|
||||
"gotest.tools/assert"
|
||||
"testing"
|
||||
)
|
||||
|
|
@ -490,61 +488,6 @@ LIMIT 1000;
|
|||
assert.NilError(t, err)
|
||||
}
|
||||
|
||||
func TestSelecSelfJoin1(t *testing.T) {
|
||||
|
||||
var expectedSql = `
|
||||
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",
|
||||
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"
|
||||
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)
|
||||
|
||||
assertStatementSql(t, query, expectedSql)
|
||||
|
||||
var dest []struct {
|
||||
model2.Employee
|
||||
|
||||
Manager *model2.Employee
|
||||
}
|
||||
|
||||
err := query.Query(db, &dest)
|
||||
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, len(dest), 8)
|
||||
assert.DeepEqual(t, dest[0].Employee, model2.Employee{
|
||||
EmployeeID: 1,
|
||||
FirstName: "Windy",
|
||||
LastName: "Hays",
|
||||
EmploymentDate: timestampWithTimeZone("1999-01-08 04:05:06.1 +0100 CET", 1),
|
||||
ManagerID: nil,
|
||||
})
|
||||
|
||||
assert.Assert(t, dest[0].Manager == nil)
|
||||
|
||||
assert.DeepEqual(t, dest[7].Employee, model2.Employee{
|
||||
EmployeeID: 8,
|
||||
FirstName: "Salley",
|
||||
LastName: "Lester",
|
||||
EmploymentDate: timestampWithTimeZone("1999-01-08 04:05:06 +0100 CET", 1),
|
||||
ManagerID: int32Ptr(3),
|
||||
})
|
||||
}
|
||||
|
||||
func TestSelectSelfJoin(t *testing.T) {
|
||||
expectedSql := `
|
||||
SELECT f1.film_id AS "f1.film_id",
|
||||
|
|
@ -647,63 +590,6 @@ LIMIT 1000;
|
|||
assert.DeepEqual(t, films[0], thesameLengthFilms{"Alien Center", "Iron Moon", 46})
|
||||
}
|
||||
|
||||
//
|
||||
//type Manager staff
|
||||
//
|
||||
//type staff struct {
|
||||
// StaffID int32 `sql:"unique"`
|
||||
// FirstName string
|
||||
// LastName string
|
||||
// //Address *model.Address
|
||||
// //Email *string
|
||||
// //StoreID int16
|
||||
// //Active bool
|
||||
// //Username string
|
||||
// //Password *string
|
||||
// //LastUpdate time.Time
|
||||
// *Manager //`sqlbuilder:"manager"`
|
||||
//}
|
||||
//
|
||||
//func TestSelectSelfReferenceType(t *testing.T) {
|
||||
//
|
||||
// expectedSql := `
|
||||
//SELECT DISTINCT staff.staff_id AS "staff.staff_id",
|
||||
// staff.first_name AS "staff.first_name",
|
||||
// staff.last_name AS "staff.last_name",
|
||||
// address.address_id AS "address.address_id",
|
||||
// address.address AS "address.address",
|
||||
// address.address2 AS "address.address2",
|
||||
// address.district AS "address.district",
|
||||
// address.city_id AS "address.city_id",
|
||||
// address.postal_code AS "address.postal_code",
|
||||
// address.phone AS "address.phone",
|
||||
// address.last_update AS "address.last_update",
|
||||
// manager.staff_id AS "manager.staff_id",
|
||||
// manager.first_name AS "manager.first_name"
|
||||
//FROM dvds.staff
|
||||
// JOIN dvds.address ON staff.address_id = address.address_id
|
||||
// JOIN dvds.staff AS manager ON staff.staff_id = manager.staff_id;
|
||||
//`
|
||||
// manager := Staff.AS("manager")
|
||||
//
|
||||
// query := Staff.
|
||||
// innerJoin(Address, Staff.AddressID.EQ(Address.AddressID)).
|
||||
// innerJoin(manager, Staff.StaffID.EQ(manager.StaffID)).
|
||||
// SELECT(Staff.StaffID, Staff.FirstName, Staff.LastName, Address.AllColumns, manager.StaffID, manager.FirstName).
|
||||
// DISTINCT()
|
||||
//
|
||||
// assertStatementSql(t, query, expectedSql)
|
||||
//
|
||||
// staffs := []staff{}
|
||||
//
|
||||
// err := query.Query(db, &staffs)
|
||||
//
|
||||
// assert.NilError(t, err)
|
||||
//
|
||||
// fmt.Println(query.DebugSql())
|
||||
// //spew.Dump(staffs)
|
||||
//}
|
||||
|
||||
func TestSubQuery(t *testing.T) {
|
||||
expectedQuery := `
|
||||
SELECT actor.actor_id AS "actor.actor_id",
|
||||
|
|
@ -1219,7 +1105,7 @@ FOR`
|
|||
}
|
||||
}
|
||||
|
||||
func TestForQuickStart(t *testing.T) {
|
||||
func TestQuickStart(t *testing.T) {
|
||||
|
||||
var expectedSql = `
|
||||
SELECT actor.actor_id AS "actor.actor_id",
|
||||
|
|
@ -1286,24 +1172,90 @@ ORDER BY actor.actor_id ASC, film.film_id ASC;
|
|||
|
||||
Language model.Language
|
||||
|
||||
Category []model.Category
|
||||
Categories []model.Category
|
||||
}
|
||||
}
|
||||
|
||||
err := stmt.Query(db, &dest)
|
||||
assert.NilError(t, err)
|
||||
|
||||
//jsonSave("./testdata/quick-start-dest.json", dest)
|
||||
assertJson(t, "./testdata/quick-start-dest.json", dest)
|
||||
|
||||
var dest2 []struct {
|
||||
model.Category
|
||||
|
||||
Film []model.Film
|
||||
Actor []model.Actor
|
||||
Films []model.Film
|
||||
Actors []model.Actor
|
||||
}
|
||||
|
||||
err = stmt.Query(db, &dest2)
|
||||
assert.NilError(t, err)
|
||||
|
||||
//jsonSave("./testdata/quick-start-dest2.json", dest2)
|
||||
assertJson(t, "./testdata/quick-start-dest2.json", dest2)
|
||||
}
|
||||
|
||||
func TestQuickStartWithSubQueries(t *testing.T) {
|
||||
filmLogerThan180 := Film.
|
||||
SELECT(Film.AllColumns).
|
||||
WHERE(Film.Length.GT(Int(180))).
|
||||
AsTable("films")
|
||||
|
||||
filmId := Film.FilmID.From(filmLogerThan180)
|
||||
filmLanguageId := Film.LanguageID.From(filmLogerThan180)
|
||||
|
||||
categoriesNotAction := Category.
|
||||
SELECT(Category.AllColumns).
|
||||
WHERE(Category.Name.NOT_EQ(String("Action"))).
|
||||
AsTable("categories")
|
||||
|
||||
categoryId := Category.CategoryID.From(categoriesNotAction)
|
||||
|
||||
stmt := Actor.
|
||||
INNER_JOIN(FilmActor, Actor.ActorID.EQ(FilmActor.ActorID)).
|
||||
INNER_JOIN(filmLogerThan180, filmId.EQ(FilmActor.FilmID)).
|
||||
INNER_JOIN(Language, Language.LanguageID.EQ(filmLanguageId)).
|
||||
INNER_JOIN(FilmCategory, FilmCategory.FilmID.EQ(filmId)).
|
||||
INNER_JOIN(categoriesNotAction, categoryId.EQ(FilmCategory.CategoryID)).
|
||||
SELECT(
|
||||
Actor.AllColumns,
|
||||
filmLogerThan180.AllColumns(),
|
||||
Language.AllColumns,
|
||||
categoriesNotAction.AllColumns(),
|
||||
).ORDER_BY(
|
||||
Actor.ActorID.ASC(),
|
||||
filmId.ASC(),
|
||||
)
|
||||
|
||||
var dest []struct {
|
||||
model.Actor
|
||||
|
||||
Films []struct {
|
||||
model.Film
|
||||
|
||||
Language model.Language
|
||||
|
||||
Categories []model.Category
|
||||
}
|
||||
}
|
||||
|
||||
err := stmt.Query(db, &dest)
|
||||
assert.NilError(t, err)
|
||||
|
||||
//jsonSave("./testdata/quick-start-dest.json", dest)
|
||||
assertJson(t, "./testdata/quick-start-dest.json", dest)
|
||||
|
||||
var dest2 []struct {
|
||||
model.Category
|
||||
|
||||
Films []model.Film
|
||||
Actors []model.Actor
|
||||
}
|
||||
|
||||
err = stmt.Query(db, &dest2)
|
||||
assert.NilError(t, err)
|
||||
|
||||
//jsonSave("./testdata/quick-start-dest2.json", dest2)
|
||||
assertJson(t, "./testdata/quick-start-dest2.json", dest2)
|
||||
}
|
||||
|
|
|
|||
374
tests/testdata/quick-start-dest.json
vendored
374
tests/testdata/quick-start-dest.json
vendored
File diff suppressed because it is too large
Load diff
56
tests/testdata/quick-start-dest2.json
vendored
56
tests/testdata/quick-start-dest2.json
vendored
|
|
@ -3,7 +3,7 @@
|
|||
"CategoryID": 8,
|
||||
"Name": "Family",
|
||||
"LastUpdate": "2006-02-15T09:46:27Z",
|
||||
"Film": [
|
||||
"Films": [
|
||||
{
|
||||
"FilmID": 499,
|
||||
"Title": "King Evolution",
|
||||
|
|
@ -35,7 +35,7 @@
|
|||
"Fulltext": "'bake':1 'cleopatra':2 'drama':5 'forens':8 'husband':12 'monasteri':20 'must':14 'overcom':15 'psychologist':9 'stun':4 'waitress':17"
|
||||
}
|
||||
],
|
||||
"Actor": [
|
||||
"Actors": [
|
||||
{
|
||||
"ActorID": 1,
|
||||
"FirstName": "Penelope",
|
||||
|
|
@ -84,7 +84,7 @@
|
|||
"CategoryID": 6,
|
||||
"Name": "Documentary",
|
||||
"LastUpdate": "2006-02-15T09:46:27Z",
|
||||
"Film": [
|
||||
"Films": [
|
||||
{
|
||||
"FilmID": 996,
|
||||
"Title": "Young Language",
|
||||
|
|
@ -116,7 +116,7 @@
|
|||
"Fulltext": "'ancient':20 'awe':5 'awe-inspir':4 'confront':16 'epistl':7 'feminist':13 'inspir':6 'japan':21 'must':15 'pioneer':18 'teacher':10 'turn':2 'wife':1"
|
||||
}
|
||||
],
|
||||
"Actor": [
|
||||
"Actors": [
|
||||
{
|
||||
"ActorID": 3,
|
||||
"FirstName": "Ed",
|
||||
|
|
@ -189,7 +189,7 @@
|
|||
"CategoryID": 12,
|
||||
"Name": "Music",
|
||||
"LastUpdate": "2006-02-15T09:46:27Z",
|
||||
"Film": [
|
||||
"Films": [
|
||||
{
|
||||
"FilmID": 721,
|
||||
"Title": "Reds Pocus",
|
||||
|
|
@ -236,7 +236,7 @@
|
|||
"Fulltext": "'car':8 'confront':14 'duck':2 'fate':4 'monasteri':19 'must':13 'reflect':5 'scalawag':1 'teacher':11 'waitress':16"
|
||||
}
|
||||
],
|
||||
"Actor": [
|
||||
"Actors": [
|
||||
{
|
||||
"ActorID": 4,
|
||||
"FirstName": "Jennifer",
|
||||
|
|
@ -339,7 +339,7 @@
|
|||
"CategoryID": 13,
|
||||
"Name": "New",
|
||||
"LastUpdate": "2006-02-15T09:46:27Z",
|
||||
"Film": [
|
||||
"Films": [
|
||||
{
|
||||
"FilmID": 340,
|
||||
"Title": "Frontier Cabin",
|
||||
|
|
@ -386,7 +386,7 @@
|
|||
"Fulltext": "'abandon':19 'boat':8,16 'documentari':5 'fun':20 'hous':21 'man':11 'meet':14 'must':13 'runaway':1 'tenenbaum':2 'thought':4"
|
||||
}
|
||||
],
|
||||
"Actor": [
|
||||
"Actors": [
|
||||
{
|
||||
"ActorID": 5,
|
||||
"FirstName": "Johnny",
|
||||
|
|
@ -471,7 +471,7 @@
|
|||
"CategoryID": 11,
|
||||
"Name": "Horror",
|
||||
"LastUpdate": "2006-02-15T09:46:27Z",
|
||||
"Film": [
|
||||
"Films": [
|
||||
{
|
||||
"FilmID": 535,
|
||||
"Title": "Love Suicides",
|
||||
|
|
@ -503,7 +503,7 @@
|
|||
"Fulltext": "'analyz':1 'chef':12 'desert':21 'display':5 'explor':8 'feminist':17 'hoosier':2 'must':14 'overcom':15 'pastri':11 'sahara':20 'thought':4"
|
||||
}
|
||||
],
|
||||
"Actor": [
|
||||
"Actors": [
|
||||
{
|
||||
"ActorID": 5,
|
||||
"FirstName": "Johnny",
|
||||
|
|
@ -552,7 +552,7 @@
|
|||
"CategoryID": 14,
|
||||
"Name": "Sci-Fi",
|
||||
"LastUpdate": "2006-02-15T09:46:27Z",
|
||||
"Film": [
|
||||
"Films": [
|
||||
{
|
||||
"FilmID": 817,
|
||||
"Title": "Soldiers Evolution",
|
||||
|
|
@ -569,7 +569,7 @@
|
|||
"Fulltext": "'confront':15 'evolut':2 'first':20 'lacklustur':4 'man':21 'must':14 'panorama':5 'pioneer':12 'shark':9 'soldier':1 'space':22 'station':23 'student':17"
|
||||
}
|
||||
],
|
||||
"Actor": [
|
||||
"Actors": [
|
||||
{
|
||||
"ActorID": 5,
|
||||
"FirstName": "Johnny",
|
||||
|
|
@ -630,7 +630,7 @@
|
|||
"CategoryID": 15,
|
||||
"Name": "Sports",
|
||||
"LastUpdate": "2006-02-15T09:46:27Z",
|
||||
"Film": [
|
||||
"Films": [
|
||||
{
|
||||
"FilmID": 841,
|
||||
"Title": "Star Operation",
|
||||
|
|
@ -677,7 +677,7 @@
|
|||
"Fulltext": "'ancient':19 'china':20 'control':2 'documentari':5 'face':14 'feminist':11 'husband':8 'mad':16 'must':13 'scientist':17 'smoochi':1 'thrill':4"
|
||||
}
|
||||
],
|
||||
"Actor": [
|
||||
"Actors": [
|
||||
{
|
||||
"ActorID": 5,
|
||||
"FirstName": "Johnny",
|
||||
|
|
@ -774,7 +774,7 @@
|
|||
"CategoryID": 2,
|
||||
"Name": "Animation",
|
||||
"LastUpdate": "2006-02-15T09:46:27Z",
|
||||
"Film": [
|
||||
"Films": [
|
||||
{
|
||||
"FilmID": 510,
|
||||
"Title": "Lawless Vision",
|
||||
|
|
@ -851,7 +851,7 @@
|
|||
"Fulltext": "'ancient':18 'battl':14 'boat':11 'china':19 'drama':5 'feminist':16 'must':13 'pond':1 'seattl':2 'stun':4 'teacher':8"
|
||||
}
|
||||
],
|
||||
"Actor": [
|
||||
"Actors": [
|
||||
{
|
||||
"ActorID": 9,
|
||||
"FirstName": "Joe",
|
||||
|
|
@ -996,7 +996,7 @@
|
|||
"CategoryID": 10,
|
||||
"Name": "Games",
|
||||
"LastUpdate": "2006-02-15T09:46:27Z",
|
||||
"Film": [
|
||||
"Films": [
|
||||
{
|
||||
"FilmID": 597,
|
||||
"Title": "Moonwalker Fool",
|
||||
|
|
@ -1058,7 +1058,7 @@
|
|||
"Fulltext": "'battl':15 'california':19 'chicago':1 'cow':9 'fate':4 'mad':8 'must':14 'north':2 'student':17 'waitress':12 'yarn':5"
|
||||
}
|
||||
],
|
||||
"Actor": [
|
||||
"Actors": [
|
||||
{
|
||||
"ActorID": 11,
|
||||
"FirstName": "Zero",
|
||||
|
|
@ -1209,7 +1209,7 @@
|
|||
"CategoryID": 5,
|
||||
"Name": "Comedy",
|
||||
"LastUpdate": "2006-02-15T09:46:27Z",
|
||||
"Film": [
|
||||
"Films": [
|
||||
{
|
||||
"FilmID": 182,
|
||||
"Title": "Control Anthem",
|
||||
|
|
@ -1256,7 +1256,7 @@
|
|||
"Fulltext": "'ancient':21 'car':10 'fast':5 'fast-pac':4 'japan':22 'kill':17 'mad':13 'must':16 'pace':6 'scientist':14 'searcher':1 'tale':7 'wait':2 'woman':19"
|
||||
}
|
||||
],
|
||||
"Actor": [
|
||||
"Actors": [
|
||||
{
|
||||
"ActorID": 19,
|
||||
"FirstName": "Bob",
|
||||
|
|
@ -1317,7 +1317,7 @@
|
|||
"CategoryID": 7,
|
||||
"Name": "Drama",
|
||||
"LastUpdate": "2006-02-15T09:46:27Z",
|
||||
"Film": [
|
||||
"Films": [
|
||||
{
|
||||
"FilmID": 473,
|
||||
"Title": "Jacket Frisco",
|
||||
|
|
@ -1334,7 +1334,7 @@
|
|||
"Fulltext": "'baloon':20 'chef':17 'conquer':14 'frisco':2 'husband':11 'insight':4 'jacket':1 'must':13 'pastri':16 'reflect':5 'woman':8"
|
||||
}
|
||||
],
|
||||
"Actor": [
|
||||
"Actors": [
|
||||
{
|
||||
"ActorID": 19,
|
||||
"FirstName": "Bob",
|
||||
|
|
@ -1401,7 +1401,7 @@
|
|||
"CategoryID": 9,
|
||||
"Name": "Foreign",
|
||||
"LastUpdate": "2006-02-15T09:46:27Z",
|
||||
"Film": [
|
||||
"Films": [
|
||||
{
|
||||
"FilmID": 435,
|
||||
"Title": "Hotel Happiness",
|
||||
|
|
@ -1478,7 +1478,7 @@
|
|||
"Fulltext": "'ancient':22 'break':2 'charact':7 'chef':20 'crystal':1 'explor':14 'face':17 'fast':5 'fast-pac':4 'feminist':11 'japan':23 'must':16 'pace':6 'pastri':19 'studi':8"
|
||||
}
|
||||
],
|
||||
"Actor": [
|
||||
"Actors": [
|
||||
{
|
||||
"ActorID": 23,
|
||||
"FirstName": "Sandra",
|
||||
|
|
@ -1617,7 +1617,7 @@
|
|||
"CategoryID": 4,
|
||||
"Name": "Classics",
|
||||
"LastUpdate": "2006-02-15T09:46:27Z",
|
||||
"Film": [
|
||||
"Films": [
|
||||
{
|
||||
"FilmID": 180,
|
||||
"Title": "Conspiracy Spirit",
|
||||
|
|
@ -1634,7 +1634,7 @@
|
|||
"Fulltext": "'abandon':21 'awe':5 'awe-inspir':4 'conquer':16 'conspiraci':1 'crocodil':18 'frisbe':13 'inspir':6 'mine':22 'must':15 'shaft':23 'spirit':2 'stori':7 'student':10"
|
||||
}
|
||||
],
|
||||
"Actor": [
|
||||
"Actors": [
|
||||
{
|
||||
"ActorID": 43,
|
||||
"FirstName": "Kirk",
|
||||
|
|
@ -1665,7 +1665,7 @@
|
|||
"CategoryID": 16,
|
||||
"Name": "Travel",
|
||||
"LastUpdate": "2006-02-15T09:46:27Z",
|
||||
"Film": [
|
||||
"Films": [
|
||||
{
|
||||
"FilmID": 609,
|
||||
"Title": "Muscle Bright",
|
||||
|
|
@ -1697,7 +1697,7 @@
|
|||
"Fulltext": "'baloon':21 'brotherhood':2 'chase':15 'epistl':5 'forens':17 'hunter':12 'must':14 'psychologist':18 'sumo':8 'sweet':1 'unbeliev':4 'wrestler':9"
|
||||
}
|
||||
],
|
||||
"Actor": [
|
||||
"Actors": [
|
||||
{
|
||||
"ActorID": 72,
|
||||
"FirstName": "Sean",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue