Merge pull request #14 from go-jet/develop

Merge develop to master
This commit is contained in:
go-jet 2019-09-27 13:27:36 +02:00 committed by GitHub
commit 4db3f422f7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
46 changed files with 331 additions and 234 deletions

View file

@ -76,7 +76,7 @@ jobs:
- run:
name: Install MySQL CLI;
command: |
sudo apt-get install default-mysql-client
sudo apt-get update && sudo apt-get install default-mysql-client
- run:
name: Create MySQL user and databases
@ -151,7 +151,7 @@ jobs:
- run:
name: Install MySQL CLI;
command: |
sudo apt-get install default-mysql-client
sudo apt-get update && sudo apt-get install default-mysql-client
- run:
name: Init MariaDB database

View file

@ -564,7 +564,10 @@ To run the tests, additional dependencies are required:
## Versioning
[SemVer](http://semver.org/) is used for versioning. For the versions available, see the [releases](https://github.com/go-jet/jet/releases).
[SemVer](http://semver.org/) is used for versioning. For the versions available, take a look at the [releases](https://github.com/go-jet/jet/releases).
For now there is no guarantee that public API will remain backward compatible. Please read new release drafts to get acquaint how to handle possible build breakable API changes.
## License

View file

@ -1,6 +1,6 @@
//
// Code generated by go-jet DO NOT EDIT.
// Generated at Thursday, 08-Aug-19 16:59:58 CEST
// Generated at Thursday, 26-Sep-19 12:02:13 CEST
//
// WARNING: Changes to this file may cause incorrect behavior
// and will be lost if the code is regenerated

View file

@ -1,6 +1,6 @@
//
// Code generated by go-jet DO NOT EDIT.
// Generated at Thursday, 08-Aug-19 16:59:58 CEST
// Generated at Thursday, 26-Sep-19 12:02:13 CEST
//
// WARNING: Changes to this file may cause incorrect behavior
// and will be lost if the code is regenerated

View file

@ -1,6 +1,6 @@
//
// Code generated by go-jet DO NOT EDIT.
// Generated at Thursday, 08-Aug-19 16:59:58 CEST
// Generated at Thursday, 26-Sep-19 12:02:13 CEST
//
// WARNING: Changes to this file may cause incorrect behavior
// and will be lost if the code is regenerated

View file

@ -1,6 +1,6 @@
//
// Code generated by go-jet DO NOT EDIT.
// Generated at Thursday, 08-Aug-19 16:59:58 CEST
// Generated at Thursday, 26-Sep-19 12:02:13 CEST
//
// WARNING: Changes to this file may cause incorrect behavior
// and will be lost if the code is regenerated

View file

@ -1,6 +1,6 @@
//
// Code generated by go-jet DO NOT EDIT.
// Generated at Thursday, 08-Aug-19 16:59:58 CEST
// Generated at Thursday, 26-Sep-19 12:02:13 CEST
//
// WARNING: Changes to this file may cause incorrect behavior
// and will be lost if the code is regenerated

View file

@ -1,6 +1,6 @@
//
// Code generated by go-jet DO NOT EDIT.
// Generated at Thursday, 08-Aug-19 16:59:58 CEST
// Generated at Thursday, 26-Sep-19 12:02:13 CEST
//
// WARNING: Changes to this file may cause incorrect behavior
// and will be lost if the code is regenerated

View file

@ -1,6 +1,6 @@
//
// Code generated by go-jet DO NOT EDIT.
// Generated at Thursday, 08-Aug-19 16:59:58 CEST
// Generated at Thursday, 26-Sep-19 12:02:13 CEST
//
// WARNING: Changes to this file may cause incorrect behavior
// and will be lost if the code is regenerated

View file

@ -1,6 +1,6 @@
//
// Code generated by go-jet DO NOT EDIT.
// Generated at Thursday, 08-Aug-19 16:59:58 CEST
// Generated at Thursday, 26-Sep-19 12:02:13 CEST
//
// WARNING: Changes to this file may cause incorrect behavior
// and will be lost if the code is regenerated

View file

@ -1,6 +1,6 @@
//
// Code generated by go-jet DO NOT EDIT.
// Generated at Thursday, 08-Aug-19 16:59:58 CEST
// Generated at Thursday, 26-Sep-19 12:02:13 CEST
//
// WARNING: Changes to this file may cause incorrect behavior
// and will be lost if the code is regenerated
@ -23,8 +23,8 @@ type ActorTable struct {
LastName postgres.ColumnString
LastUpdate postgres.ColumnTimestamp
AllColumns postgres.IColumnList
MutableColumns postgres.IColumnList
AllColumns postgres.ColumnList
MutableColumns postgres.ColumnList
}
// creates new ActorTable with assigned alias
@ -53,7 +53,7 @@ func newActorTable() *ActorTable {
LastName: LastNameColumn,
LastUpdate: LastUpdateColumn,
AllColumns: postgres.ColumnList(ActorIDColumn, FirstNameColumn, LastNameColumn, LastUpdateColumn),
MutableColumns: postgres.ColumnList(FirstNameColumn, LastNameColumn, LastUpdateColumn),
AllColumns: postgres.ColumnList{ActorIDColumn, FirstNameColumn, LastNameColumn, LastUpdateColumn},
MutableColumns: postgres.ColumnList{FirstNameColumn, LastNameColumn, LastUpdateColumn},
}
}

View file

@ -1,6 +1,6 @@
//
// Code generated by go-jet DO NOT EDIT.
// Generated at Thursday, 08-Aug-19 16:59:58 CEST
// Generated at Thursday, 26-Sep-19 12:02:13 CEST
//
// WARNING: Changes to this file may cause incorrect behavior
// and will be lost if the code is regenerated
@ -22,8 +22,8 @@ type CategoryTable struct {
Name postgres.ColumnString
LastUpdate postgres.ColumnTimestamp
AllColumns postgres.IColumnList
MutableColumns postgres.IColumnList
AllColumns postgres.ColumnList
MutableColumns postgres.ColumnList
}
// creates new CategoryTable with assigned alias
@ -50,7 +50,7 @@ func newCategoryTable() *CategoryTable {
Name: NameColumn,
LastUpdate: LastUpdateColumn,
AllColumns: postgres.ColumnList(CategoryIDColumn, NameColumn, LastUpdateColumn),
MutableColumns: postgres.ColumnList(NameColumn, LastUpdateColumn),
AllColumns: postgres.ColumnList{CategoryIDColumn, NameColumn, LastUpdateColumn},
MutableColumns: postgres.ColumnList{NameColumn, LastUpdateColumn},
}
}

View file

@ -1,6 +1,6 @@
//
// Code generated by go-jet DO NOT EDIT.
// Generated at Thursday, 08-Aug-19 16:59:58 CEST
// Generated at Thursday, 26-Sep-19 12:02:13 CEST
//
// WARNING: Changes to this file may cause incorrect behavior
// and will be lost if the code is regenerated
@ -32,8 +32,8 @@ type FilmTable struct {
SpecialFeatures postgres.ColumnString
Fulltext postgres.ColumnString
AllColumns postgres.IColumnList
MutableColumns postgres.IColumnList
AllColumns postgres.ColumnList
MutableColumns postgres.ColumnList
}
// creates new FilmTable with assigned alias
@ -80,7 +80,7 @@ func newFilmTable() *FilmTable {
SpecialFeatures: SpecialFeaturesColumn,
Fulltext: FulltextColumn,
AllColumns: postgres.ColumnList(FilmIDColumn, TitleColumn, DescriptionColumn, ReleaseYearColumn, LanguageIDColumn, RentalDurationColumn, RentalRateColumn, LengthColumn, ReplacementCostColumn, RatingColumn, LastUpdateColumn, SpecialFeaturesColumn, FulltextColumn),
MutableColumns: postgres.ColumnList(TitleColumn, DescriptionColumn, ReleaseYearColumn, LanguageIDColumn, RentalDurationColumn, RentalRateColumn, LengthColumn, ReplacementCostColumn, RatingColumn, LastUpdateColumn, SpecialFeaturesColumn, FulltextColumn),
AllColumns: postgres.ColumnList{FilmIDColumn, TitleColumn, DescriptionColumn, ReleaseYearColumn, LanguageIDColumn, RentalDurationColumn, RentalRateColumn, LengthColumn, ReplacementCostColumn, RatingColumn, LastUpdateColumn, SpecialFeaturesColumn, FulltextColumn},
MutableColumns: postgres.ColumnList{TitleColumn, DescriptionColumn, ReleaseYearColumn, LanguageIDColumn, RentalDurationColumn, RentalRateColumn, LengthColumn, ReplacementCostColumn, RatingColumn, LastUpdateColumn, SpecialFeaturesColumn, FulltextColumn},
}
}

View file

@ -1,6 +1,6 @@
//
// Code generated by go-jet DO NOT EDIT.
// Generated at Thursday, 08-Aug-19 16:59:58 CEST
// Generated at Thursday, 26-Sep-19 12:02:13 CEST
//
// WARNING: Changes to this file may cause incorrect behavior
// and will be lost if the code is regenerated
@ -22,8 +22,8 @@ type FilmActorTable struct {
FilmID postgres.ColumnInteger
LastUpdate postgres.ColumnTimestamp
AllColumns postgres.IColumnList
MutableColumns postgres.IColumnList
AllColumns postgres.ColumnList
MutableColumns postgres.ColumnList
}
// creates new FilmActorTable with assigned alias
@ -50,7 +50,7 @@ func newFilmActorTable() *FilmActorTable {
FilmID: FilmIDColumn,
LastUpdate: LastUpdateColumn,
AllColumns: postgres.ColumnList(ActorIDColumn, FilmIDColumn, LastUpdateColumn),
MutableColumns: postgres.ColumnList(LastUpdateColumn),
AllColumns: postgres.ColumnList{ActorIDColumn, FilmIDColumn, LastUpdateColumn},
MutableColumns: postgres.ColumnList{LastUpdateColumn},
}
}

View file

@ -1,6 +1,6 @@
//
// Code generated by go-jet DO NOT EDIT.
// Generated at Thursday, 08-Aug-19 16:59:58 CEST
// Generated at Thursday, 26-Sep-19 12:02:13 CEST
//
// WARNING: Changes to this file may cause incorrect behavior
// and will be lost if the code is regenerated
@ -22,8 +22,8 @@ type FilmCategoryTable struct {
CategoryID postgres.ColumnInteger
LastUpdate postgres.ColumnTimestamp
AllColumns postgres.IColumnList
MutableColumns postgres.IColumnList
AllColumns postgres.ColumnList
MutableColumns postgres.ColumnList
}
// creates new FilmCategoryTable with assigned alias
@ -50,7 +50,7 @@ func newFilmCategoryTable() *FilmCategoryTable {
CategoryID: CategoryIDColumn,
LastUpdate: LastUpdateColumn,
AllColumns: postgres.ColumnList(FilmIDColumn, CategoryIDColumn, LastUpdateColumn),
MutableColumns: postgres.ColumnList(LastUpdateColumn),
AllColumns: postgres.ColumnList{FilmIDColumn, CategoryIDColumn, LastUpdateColumn},
MutableColumns: postgres.ColumnList{LastUpdateColumn},
}
}

View file

@ -1,6 +1,6 @@
//
// Code generated by go-jet DO NOT EDIT.
// Generated at Thursday, 08-Aug-19 16:59:58 CEST
// Generated at Thursday, 26-Sep-19 12:02:13 CEST
//
// WARNING: Changes to this file may cause incorrect behavior
// and will be lost if the code is regenerated
@ -22,8 +22,8 @@ type LanguageTable struct {
Name postgres.ColumnString
LastUpdate postgres.ColumnTimestamp
AllColumns postgres.IColumnList
MutableColumns postgres.IColumnList
AllColumns postgres.ColumnList
MutableColumns postgres.ColumnList
}
// creates new LanguageTable with assigned alias
@ -50,7 +50,7 @@ func newLanguageTable() *LanguageTable {
Name: NameColumn,
LastUpdate: LastUpdateColumn,
AllColumns: postgres.ColumnList(LanguageIDColumn, NameColumn, LastUpdateColumn),
MutableColumns: postgres.ColumnList(NameColumn, LastUpdateColumn),
AllColumns: postgres.ColumnList{LanguageIDColumn, NameColumn, LastUpdateColumn},
MutableColumns: postgres.ColumnList{NameColumn, LastUpdateColumn},
}
}

View file

@ -0,0 +1,59 @@
//
// Code generated by go-jet DO NOT EDIT.
// Generated at Thursday, 26-Sep-19 12:02:13 CEST
//
// WARNING: Changes to this file may cause incorrect behavior
// and will be lost if the code is regenerated
//
package view
import (
"github.com/go-jet/jet/postgres"
)
var ActorInfo = newActorInfoTable()
type ActorInfoTable struct {
postgres.Table
//Columns
ActorID postgres.ColumnInteger
FirstName postgres.ColumnString
LastName postgres.ColumnString
FilmInfo postgres.ColumnString
AllColumns postgres.ColumnList
MutableColumns postgres.ColumnList
}
// creates new ActorInfoTable with assigned alias
func (a *ActorInfoTable) AS(alias string) *ActorInfoTable {
aliasTable := newActorInfoTable()
aliasTable.Table.AS(alias)
return aliasTable
}
func newActorInfoTable() *ActorInfoTable {
var (
ActorIDColumn = postgres.IntegerColumn("actor_id")
FirstNameColumn = postgres.StringColumn("first_name")
LastNameColumn = postgres.StringColumn("last_name")
FilmInfoColumn = postgres.StringColumn("film_info")
)
return &ActorInfoTable{
Table: postgres.NewTable("dvds", "actor_info", ActorIDColumn, FirstNameColumn, LastNameColumn, FilmInfoColumn),
//Columns
ActorID: ActorIDColumn,
FirstName: FirstNameColumn,
LastName: LastNameColumn,
FilmInfo: FilmInfoColumn,
AllColumns: postgres.ColumnList{ActorIDColumn, FirstNameColumn, LastNameColumn, FilmInfoColumn},
MutableColumns: postgres.ColumnList{ActorIDColumn, FirstNameColumn, LastNameColumn, FilmInfoColumn},
}
}

View file

@ -0,0 +1,74 @@
//
// Code generated by go-jet DO NOT EDIT.
// Generated at Thursday, 26-Sep-19 12:02:13 CEST
//
// WARNING: Changes to this file may cause incorrect behavior
// and will be lost if the code is regenerated
//
package view
import (
"github.com/go-jet/jet/postgres"
)
var CustomerList = newCustomerListTable()
type CustomerListTable struct {
postgres.Table
//Columns
ID postgres.ColumnInteger
Name postgres.ColumnString
Address postgres.ColumnString
ZipCode postgres.ColumnString
Phone postgres.ColumnString
City postgres.ColumnString
Country postgres.ColumnString
Notes postgres.ColumnString
Sid postgres.ColumnInteger
AllColumns postgres.ColumnList
MutableColumns postgres.ColumnList
}
// creates new CustomerListTable with assigned alias
func (a *CustomerListTable) AS(alias string) *CustomerListTable {
aliasTable := newCustomerListTable()
aliasTable.Table.AS(alias)
return aliasTable
}
func newCustomerListTable() *CustomerListTable {
var (
IDColumn = postgres.IntegerColumn("id")
NameColumn = postgres.StringColumn("name")
AddressColumn = postgres.StringColumn("address")
ZipCodeColumn = postgres.StringColumn("zip code")
PhoneColumn = postgres.StringColumn("phone")
CityColumn = postgres.StringColumn("city")
CountryColumn = postgres.StringColumn("country")
NotesColumn = postgres.StringColumn("notes")
SidColumn = postgres.IntegerColumn("sid")
)
return &CustomerListTable{
Table: postgres.NewTable("dvds", "customer_list", IDColumn, NameColumn, AddressColumn, ZipCodeColumn, PhoneColumn, CityColumn, CountryColumn, NotesColumn, SidColumn),
//Columns
ID: IDColumn,
Name: NameColumn,
Address: AddressColumn,
ZipCode: ZipCodeColumn,
Phone: PhoneColumn,
City: CityColumn,
Country: CountryColumn,
Notes: NotesColumn,
Sid: SidColumn,
AllColumns: postgres.ColumnList{IDColumn, NameColumn, AddressColumn, ZipCodeColumn, PhoneColumn, CityColumn, CountryColumn, NotesColumn, SidColumn},
MutableColumns: postgres.ColumnList{IDColumn, NameColumn, AddressColumn, ZipCodeColumn, PhoneColumn, CityColumn, CountryColumn, NotesColumn, SidColumn},
}
}

View file

@ -34,8 +34,8 @@ type {{.GoStructName}} struct {
{{ToGoIdentifier .Name}} {{dialect.PackageName}}.Column{{.SqlBuilderColumnType}}
{{- end}}
AllColumns {{dialect.PackageName}}.IColumnList
MutableColumns {{dialect.PackageName}}.IColumnList
AllColumns {{dialect.PackageName}}.ColumnList
MutableColumns {{dialect.PackageName}}.ColumnList
}
// creates new {{.GoStructName}} with assigned alias
@ -62,8 +62,8 @@ func new{{.GoStructName}}() *{{.GoStructName}} {
{{ToGoIdentifier .Name}}: {{ToGoIdentifier .Name}}Column,
{{- end}}
AllColumns: {{dialect.PackageName}}.ColumnList( {{template "column-list" .Columns}} ),
MutableColumns: {{dialect.PackageName}}.ColumnList( {{template "column-list" .MutableColumns}} ),
AllColumns: {{dialect.PackageName}}.ColumnList{ {{template "column-list" .Columns}} },
MutableColumns: {{dialect.PackageName}}.ColumnList{ {{template "column-list" .MutableColumns}} },
}
}

View file

@ -99,28 +99,10 @@ func (c columnImpl) serialize(statement StatementType, out *SQLBuilder, options
//------------------------------------------------------//
// IColumnList is used to store list of columns for later reuse as single projection or
// column list for UPDATE and INSERT statement.
type IColumnList interface {
Projection
Column
// ColumnList is a helper type to support list of columns as single projection
type ColumnList []ColumnExpression
columns() []ColumnExpression
}
// ColumnList function returns list of columns that be used as projection or column list for UPDATE and INSERT statement.
func ColumnList(columns ...ColumnExpression) IColumnList {
return columnListImpl(columns)
}
// ColumnList is redefined type to support list of columns as single Projection
type columnListImpl []ColumnExpression
func (cl columnListImpl) columns() []ColumnExpression {
return cl
}
func (cl columnListImpl) fromImpl(subQuery SelectTable) Projection {
func (cl ColumnList) fromImpl(subQuery SelectTable) Projection {
newProjectionList := ProjectionList{}
for _, column := range cl {
@ -130,7 +112,7 @@ func (cl columnListImpl) fromImpl(subQuery SelectTable) Projection {
return newProjectionList
}
func (cl columnListImpl) serializeForProjection(statement StatementType, out *SQLBuilder) {
func (cl ColumnList) serializeForProjection(statement StatementType, out *SQLBuilder) {
projections := ColumnListToProjectionList(cl)
SerializeProjectionList(statement, projections, out)
@ -139,10 +121,10 @@ func (cl columnListImpl) serializeForProjection(statement StatementType, out *SQ
// dummy column interface implementation
// Name is placeholder for ColumnList to implement Column interface
func (cl columnListImpl) Name() string { return "" }
func (cl ColumnList) Name() string { return "" }
// TableName is placeholder for ColumnList to implement Column interface
func (cl columnListImpl) TableName() string { return "" }
func (cl columnListImpl) setTableName(name string) {}
func (cl columnListImpl) setSubQuery(subQuery SelectTable) {}
func (cl columnListImpl) defaultAlias() string { return "" }
func (cl ColumnList) TableName() string { return "" }
func (cl ColumnList) setTableName(name string) {}
func (cl ColumnList) setSubQuery(subQuery SelectTable) {}
func (cl ColumnList) defaultAlias() string { return "" }

View file

@ -3,7 +3,7 @@ package jet
import (
"context"
"database/sql"
"github.com/go-jet/jet/execution"
"github.com/go-jet/jet/qrm"
)
//Statement is common interface for all statements(SELECT, INSERT, UPDATE, DELETE, LOCK)
@ -16,15 +16,15 @@ type Statement interface {
// Query executes statement over database connection db and stores row result in destination.
// Destination can be arbitrary structure
Query(db execution.DB, destination interface{}) error
Query(db qrm.DB, destination interface{}) error
// QueryContext executes statement with a context over database connection db and stores row result in destination.
// Destination can be of arbitrary structure
QueryContext(context context.Context, db execution.DB, destination interface{}) error
QueryContext(context context.Context, db qrm.DB, destination interface{}) error
//Exec executes statement over db connection without returning any rows.
Exec(db execution.DB) (sql.Result, error)
Exec(db qrm.DB) (sql.Result, error)
//Exec executes statement with context over db connection without returning any rows.
ExecContext(context context.Context, db execution.DB) (sql.Result, error)
ExecContext(context context.Context, db qrm.DB) (sql.Result, error)
}
// SerializerStatement interface
@ -71,24 +71,24 @@ func (s *serializerStatementInterfaceImpl) DebugSql() (query string) {
return
}
func (s *serializerStatementInterfaceImpl) Query(db execution.DB, destination interface{}) error {
func (s *serializerStatementInterfaceImpl) Query(db qrm.DB, destination interface{}) error {
query, args := s.Sql()
return execution.Query(context.Background(), db, query, args, destination)
return qrm.Query(context.Background(), db, query, args, destination)
}
func (s *serializerStatementInterfaceImpl) QueryContext(context context.Context, db execution.DB, destination interface{}) error {
func (s *serializerStatementInterfaceImpl) QueryContext(context context.Context, db qrm.DB, destination interface{}) error {
query, args := s.Sql()
return execution.Query(context, db, query, args, destination)
return qrm.Query(context, db, query, args, destination)
}
func (s *serializerStatementInterfaceImpl) Exec(db execution.DB) (res sql.Result, err error) {
func (s *serializerStatementInterfaceImpl) Exec(db qrm.DB) (res sql.Result, err error) {
query, args := s.Sql()
return db.Exec(query, args...)
}
func (s *serializerStatementInterfaceImpl) ExecContext(context context.Context, db execution.DB) (res sql.Result, err error) {
func (s *serializerStatementInterfaceImpl) ExecContext(context context.Context, db qrm.DB) (res sql.Result, err error) {
query, args := s.Sql()
return db.ExecContext(context, query, args...)

View file

@ -147,8 +147,8 @@ func UnwindRowFromValues(value interface{}, values []interface{}) []Serializer {
func UnwindColumns(column1 Column, columns ...Column) []Column {
columnList := []Column{}
if val, ok := column1.(IColumnList); ok {
for _, col := range val.columns() {
if val, ok := column1.(ColumnList); ok {
for _, col := range val {
columnList = append(columnList, col)
}
columnList = append(columnList, columns...)
@ -165,8 +165,8 @@ func UnwidColumnList(columns []Column) []Column {
ret := []Column{}
for _, col := range columns {
if columnList, ok := col.(IColumnList); ok {
for _, c := range columnList.columns() {
if columnList, ok := col.(ColumnList); ok {
for _, c := range columnList {
ret = append(ret, c)
}
} else {

View file

@ -4,9 +4,9 @@ import (
"bytes"
"encoding/json"
"fmt"
"github.com/go-jet/jet/execution"
"github.com/go-jet/jet/internal/jet"
"github.com/go-jet/jet/internal/utils"
"github.com/go-jet/jet/qrm"
"gotest.tools/assert"
"io/ioutil"
"os"
@ -16,7 +16,7 @@ import (
)
// AssertExec assert statement execution for successful execution and number of rows affected
func AssertExec(t *testing.T, stmt jet.Statement, db execution.DB, rowsAffected ...int64) {
func AssertExec(t *testing.T, stmt jet.Statement, db qrm.DB, rowsAffected ...int64) {
res, err := stmt.Exec(db)
assert.NilError(t, err)
@ -29,7 +29,7 @@ func AssertExec(t *testing.T, stmt jet.Statement, db execution.DB, rowsAffected
}
// AssertExecErr assert statement execution for failed execution with error string errorStr
func AssertExecErr(t *testing.T, stmt jet.Statement, db execution.DB, errorStr string) {
func AssertExecErr(t *testing.T, stmt jet.Statement, db qrm.DB, errorStr string) {
_, err := stmt.Exec(db)
assert.Error(t, err, errorStr)
@ -150,7 +150,7 @@ func AssertProjectionSerialize(t *testing.T, dialect jet.Dialect, projection jet
}
// AssertQueryPanicErr check if statement Query execution panics with error errString
func AssertQueryPanicErr(t *testing.T, stmt jet.Statement, db execution.DB, dest interface{}, errString string) {
func AssertQueryPanicErr(t *testing.T, stmt jet.Statement, db qrm.DB, dest interface{}, errString string) {
defer func() {
r := recover()
assert.Equal(t, r, errString)

View file

@ -164,3 +164,13 @@ func ErrorCatch(err *error) {
*err = fmt.Errorf("%v", recovered)
}
}
func StringSliceContains(strings []string, contains string) bool {
for _, str := range strings {
if str == contains {
return true
}
}
return false
}

View file

@ -3,59 +3,56 @@ package mysql
import "github.com/go-jet/jet/internal/jet"
// Column is common column interface for all types of columns.
type Column jet.ColumnExpression
// IColumnList is used to store list of columns for later reuse as projection or column list for UPDATE and INSERT statement.
type IColumnList jet.IColumnList
type Column = jet.ColumnExpression
// ColumnList function returns list of columns that be used as projection or column list for UPDATE and INSERT statement.
var ColumnList = jet.ColumnList
type ColumnList = jet.ColumnList
// ColumnBool is interface for SQL boolean columns.
type ColumnBool jet.ColumnBool
type ColumnBool = jet.ColumnBool
// BoolColumn creates named bool column.
var BoolColumn = jet.BoolColumn
// ColumnString is interface for SQL text, character, character varying
// bytea, uuid columns and enums types.
type ColumnString jet.ColumnString
type ColumnString = jet.ColumnString
// StringColumn creates named string column.
var StringColumn = jet.StringColumn
// ColumnInteger is interface for SQL smallint, integer, bigint columns.
type ColumnInteger jet.ColumnInteger
type ColumnInteger = jet.ColumnInteger
// IntegerColumn creates named integer column.
var IntegerColumn = jet.IntegerColumn
// ColumnFloat is interface for SQL real, numeric, decimal or double precision column.
type ColumnFloat jet.ColumnFloat
type ColumnFloat = jet.ColumnFloat
// FloatColumn creates named float column.
var FloatColumn = jet.FloatColumn
// ColumnTime is interface for SQL time column.
type ColumnTime jet.ColumnTime
type ColumnTime = jet.ColumnTime
// TimeColumn creates named time column
var TimeColumn = jet.TimeColumn
// ColumnDate is interface of SQL date columns.
type ColumnDate jet.ColumnDate
type ColumnDate = jet.ColumnDate
// DateColumn creates named date column.
var DateColumn = jet.DateColumn
// ColumnDateTime is interface of SQL timestamp columns.
type ColumnDateTime jet.ColumnTimestamp
type ColumnDateTime = jet.ColumnTimestamp
// DateTimeColumn creates named timestamp column
var DateTimeColumn = jet.TimestampColumn
// ColumnTimestamp is interface of SQL timestamp columns.
type ColumnTimestamp jet.ColumnTimestamp
type ColumnTimestamp = jet.ColumnTimestamp
// TimestampColumn creates named timestamp column
var TimestampColumn = jet.TimestampColumn

View file

@ -4,31 +4,31 @@ import "github.com/go-jet/jet/internal/jet"
// Expression is common interface for all expressions.
// Can be Bool, Int, Float, String, Date, Time, Timez, Timestamp or Timestampz expressions.
type Expression jet.Expression
type Expression = jet.Expression
// BoolExpression interface
type BoolExpression jet.BoolExpression
type BoolExpression = jet.BoolExpression
// StringExpression interface
type StringExpression jet.StringExpression
type StringExpression = jet.StringExpression
// IntegerExpression interface
type IntegerExpression jet.IntegerExpression
type IntegerExpression = jet.IntegerExpression
// FloatExpression interface
type FloatExpression jet.FloatExpression
type FloatExpression = jet.FloatExpression
// TimeExpression interface
type TimeExpression jet.TimeExpression
type TimeExpression = jet.TimeExpression
// DateExpression interface
type DateExpression jet.DateExpression
type DateExpression = jet.DateExpression
// DateTimeExpression interface
type DateTimeExpression jet.TimestampExpression
type DateTimeExpression = jet.TimestampExpression
// TimestampExpression interface
type TimestampExpression jet.TimestampExpression
type TimestampExpression = jet.TimestampExpression
// BoolExp is bool expression wrapper around arbitrary expression.
// Allows go compiler to see any expression as bool expression.

View file

@ -26,7 +26,9 @@ INSERT INTO db.table1 (col1) VALUES
}
func TestInsertWithColumnList(t *testing.T) {
columnList := ColumnList(table3ColInt, table3StrCol)
columnList := ColumnList{table3ColInt}
columnList = append(columnList, table3StrCol)
assertStatementSql(t, table3.INSERT(columnList).VALUES(1, 3), `
INSERT INTO db.table3 (col_int, col2) VALUES

View file

@ -69,7 +69,7 @@ func newSelectStatement(table ReadableTable, projections []Projection) SelectSta
&newSelect.From, &newSelect.Where, &newSelect.GroupBy, &newSelect.Having, &newSelect.Window, &newSelect.OrderBy,
&newSelect.Limit, &newSelect.Offset, &newSelect.For, &newSelect.ShareLock)
newSelect.Select.Projections = toJetProjectionList(projections)
newSelect.Select.Projections = projections
newSelect.From.Table = table
newSelect.Limit.Count = -1
newSelect.Offset.Count = -1

View file

@ -10,7 +10,7 @@ func TestInvalidSelect(t *testing.T) {
}
func TestSelectColumnList(t *testing.T) {
columnList := ColumnList(table2ColInt, table2ColFloat, table3ColInt)
columnList := ColumnList{table2ColInt, table2ColFloat, table3ColInt}
assertStatementSql(t, SELECT(columnList).FROM(table2), `
SELECT table2.col_int AS "table2.col_int",

View file

@ -3,17 +3,7 @@ package mysql
import "github.com/go-jet/jet/internal/jet"
// Statement is common interface for all statements(SELECT, INSERT, UPDATE, DELETE, LOCK)
type Statement jet.Statement
type Statement = jet.Statement
// Projection is interface for all projection types. Types that can be part of, for instance SELECT clause.
type Projection jet.Projection
func toJetProjectionList(projections []Projection) []jet.Projection {
ret := []jet.Projection{}
for _, projection := range projections {
ret = append(ret, projection)
}
return ret
}
type Projection = jet.Projection

View file

@ -3,66 +3,62 @@ package postgres
import "github.com/go-jet/jet/internal/jet"
// Column is common column interface for all types of columns.
type Column jet.ColumnExpression
// IColumnList is used to store list of columns for later reuse as single projection or
// column list for UPDATE and INSERT statement.
type IColumnList jet.IColumnList
type Column = jet.ColumnExpression
// ColumnList function returns list of columns that be used as projection or column list for UPDATE and INSERT statement.
var ColumnList = jet.ColumnList
type ColumnList = jet.ColumnList
// ColumnBool is interface for SQL boolean columns.
type ColumnBool jet.ColumnBool
type ColumnBool = jet.ColumnBool
// BoolColumn creates named bool column.
var BoolColumn = jet.BoolColumn
// ColumnString is interface for SQL text, character, character varying
// bytea, uuid columns and enums types.
type ColumnString jet.ColumnString
type ColumnString = jet.ColumnString
// StringColumn creates named string column.
var StringColumn = jet.StringColumn
// ColumnInteger is interface for SQL smallint, integer, bigint columns.
type ColumnInteger jet.ColumnInteger
type ColumnInteger = jet.ColumnInteger
// IntegerColumn creates named integer column.
var IntegerColumn = jet.IntegerColumn
// ColumnFloat is interface for SQL real, numeric, decimal or double precision column.
type ColumnFloat jet.ColumnFloat
type ColumnFloat = jet.ColumnFloat
// FloatColumn creates named float column.
var FloatColumn = jet.FloatColumn
// ColumnDate is interface of SQL date columns.
type ColumnDate jet.ColumnDate
type ColumnDate = jet.ColumnDate
// DateColumn creates named date column.
var DateColumn = jet.DateColumn
// ColumnTime is interface for SQL time column.
type ColumnTime jet.ColumnTime
type ColumnTime = jet.ColumnTime
// TimeColumn creates named time column
var TimeColumn = jet.TimeColumn
// ColumnTimez is interface of SQL time with time zone columns.
type ColumnTimez jet.ColumnTimez
type ColumnTimez = jet.ColumnTimez
// TimezColumn creates named time with time zone column.
var TimezColumn = jet.TimezColumn
// ColumnTimestamp is interface of SQL timestamp columns.
type ColumnTimestamp jet.ColumnTimestamp
type ColumnTimestamp = jet.ColumnTimestamp
// TimestampColumn creates named timestamp column
var TimestampColumn = jet.TimestampColumn
// ColumnTimestampz is interface of SQL timestamp with timezone columns.
type ColumnTimestampz jet.ColumnTimestampz
type ColumnTimestampz = jet.ColumnTimestampz
// TimestampzColumn creates named timestamp with time zone column.
var TimestampzColumn = jet.TimestampzColumn

View file

@ -4,34 +4,34 @@ import "github.com/go-jet/jet/internal/jet"
// Expression is common interface for all expressions.
// Can be Bool, Int, Float, String, Date, Time, Timez, Timestamp or Timestampz expressions.
type Expression jet.Expression
type Expression = jet.Expression
// BoolExpression interface
type BoolExpression jet.BoolExpression
type BoolExpression = jet.BoolExpression
// StringExpression interface
type StringExpression jet.StringExpression
type StringExpression = jet.StringExpression
// IntegerExpression interface
type IntegerExpression jet.IntegerExpression
type IntegerExpression = jet.IntegerExpression
//FloatExpression is interface
type FloatExpression jet.FloatExpression
type FloatExpression = jet.FloatExpression
// TimeExpression interface
type TimeExpression jet.TimeExpression
type TimeExpression = jet.TimeExpression
// TimezExpression interface for 'time with time zone' types
type TimezExpression jet.TimezExpression
type TimezExpression = jet.TimezExpression
// DateExpression is interface for date types
type DateExpression jet.DateExpression
type DateExpression = jet.DateExpression
// TimestampExpression interface
type TimestampExpression jet.TimestampExpression
type TimestampExpression = jet.TimestampExpression
// TimestampzExpression interface
type TimestampzExpression jet.TimestampzExpression
type TimestampzExpression = jet.TimestampzExpression
// BoolExp is bool expression wrapper around arbitrary expression.
// Allows go compiler to see any expression as bool expression.

View file

@ -26,7 +26,7 @@ INSERT INTO db.table1 (col1) VALUES
}
func TestInsertWithColumnList(t *testing.T) {
columnList := ColumnList(table3ColInt, table3StrCol)
columnList := ColumnList{table3ColInt, table3StrCol}
assertStatementSql(t, table3.INSERT(columnList).VALUES(1, 3), `
INSERT INTO db.table3 (col_int, col2) VALUES

View file

@ -75,7 +75,7 @@ func newSelectStatement(table ReadableTable, projections []Projection) SelectSta
&newSelect.From, &newSelect.Where, &newSelect.GroupBy, &newSelect.Having, &newSelect.Window, &newSelect.OrderBy,
&newSelect.Limit, &newSelect.Offset, &newSelect.For)
newSelect.Select.Projections = toJetProjectionList(projections)
newSelect.Select.Projections = projections
newSelect.From.Table = table
newSelect.Limit.Count = -1
newSelect.Offset.Count = -1

View file

@ -9,7 +9,7 @@ func TestInvalidSelect(t *testing.T) {
}
func TestSelectColumnList(t *testing.T) {
columnList := ColumnList(table2ColInt, table2ColFloat, table3ColInt)
columnList := ColumnList{table2ColInt, table2ColFloat, table3ColInt}
assertStatementSql(t, SELECT(columnList).FROM(table2), `
SELECT table2.col_int AS "table2.col_int",

View file

@ -3,17 +3,7 @@ package postgres
import "github.com/go-jet/jet/internal/jet"
// Statement is common interface for all statements(SELECT, INSERT, UPDATE, DELETE, LOCK)
type Statement jet.Statement
type Statement = jet.Statement
// Projection is interface for all projection types. Types that can be part of, for instance SELECT clause.
type Projection jet.Projection
func toJetProjectionList(projections []Projection) []jet.Projection {
ret := []jet.Projection{}
for _, projection := range projections {
ret = append(ret, projection)
}
return ret
}
type Projection = jet.Projection

View file

@ -1,4 +1,4 @@
package execution
package qrm
import (
"context"

View file

@ -1,12 +1,12 @@
package execution
package qrm
import (
"context"
"database/sql"
"database/sql/driver"
"fmt"
"github.com/go-jet/jet/execution/internal"
"github.com/go-jet/jet/internal/utils"
"github.com/go-jet/jet/qrm/internal"
"github.com/google/uuid"
"reflect"
"strconv"
@ -14,23 +14,24 @@ import (
"time"
)
// Query executes query with arguments over database connection with context and stores result into destination.
// Query executes Query Result Mapping (QRM) of `query` with list of parametrized arguments `arg` over database connection `db`
// using context `ctx` into destination `destPtr`.
// Destination can be either pointer to struct or pointer to slice of structs.
func Query(context context.Context, db DB, query string, args []interface{}, destinationPtr interface{}) error {
func Query(ctx context.Context, db DB, query string, args []interface{}, destPtr interface{}) error {
utils.MustBeInitializedPtr(db, "jet: db is nil")
utils.MustBeInitializedPtr(destinationPtr, "jet: destination is nil")
utils.MustBe(destinationPtr, reflect.Ptr, "jet: destination has to be a pointer to slice or pointer to struct")
utils.MustBeInitializedPtr(destPtr, "jet: destination is nil")
utils.MustBe(destPtr, reflect.Ptr, "jet: destination has to be a pointer to slice or pointer to struct")
destinationPtrType := reflect.TypeOf(destinationPtr)
destinationPtrType := reflect.TypeOf(destPtr)
if destinationPtrType.Elem().Kind() == reflect.Slice {
return queryToSlice(context, db, query, args, destinationPtr)
return queryToSlice(ctx, db, query, args, destPtr)
} else if destinationPtrType.Elem().Kind() == reflect.Struct {
tempSlicePtrValue := reflect.New(reflect.SliceOf(destinationPtrType))
tempSliceValue := tempSlicePtrValue.Elem()
err := queryToSlice(context, db, query, args, tempSlicePtrValue.Interface())
err := queryToSlice(ctx, db, query, args, tempSlicePtrValue.Interface())
if err != nil {
return err
@ -40,7 +41,7 @@ func Query(context context.Context, db DB, query string, args []interface{}, des
return nil
}
structValue := reflect.ValueOf(destinationPtr).Elem()
structValue := reflect.ValueOf(destPtr).Elem()
firstTempStruct := tempSliceValue.Index(0).Elem()
if structValue.Type().AssignableTo(firstTempStruct.Type()) {
@ -748,30 +749,29 @@ func (s *scanContext) constructGroupKey(groupKeyInfo groupKeyInfo) string {
}
func (s *scanContext) getGroupKeyInfo(structType reflect.Type, parentField *reflect.StructField) groupKeyInfo {
typeName := getTypeName(structType, parentField)
ret := groupKeyInfo{typeName: structType.Name()}
typeName := getTypeName(structType, parentField)
primaryKeyOverwrites := parentFieldPrimaryKeyOverwrite(parentField)
for i := 0; i < structType.NumField(); i++ {
field := structType.Field(i)
newTypeName, fieldName := getTypeAndFieldName(typeName, field)
fieldType := indirectType(field.Type)
if !isSimpleModelType(field.Type) {
var structType reflect.Type
if field.Type.Kind() == reflect.Struct {
structType = field.Type
} else if field.Type.Kind() == reflect.Ptr && field.Type.Elem().Kind() == reflect.Struct {
structType = field.Type.Elem()
} else {
if !isSimpleModelType(fieldType) {
if fieldType.Kind() != reflect.Struct {
continue
}
subType := s.getGroupKeyInfo(structType, &field)
subType := s.getGroupKeyInfo(fieldType, &field)
if len(subType.indexes) != 0 || len(subType.subTypes) != 0 {
ret.subTypes = append(ret.subTypes, subType)
}
} else if isPrimaryKey(field, parentField) {
} else {
if isPrimaryKey(field, primaryKeyOverwrites) {
newTypeName, fieldName := getTypeAndFieldName(typeName, field)
index := s.typeToColumnIndex(newTypeName, fieldName)
if index < 0 {
@ -781,6 +781,7 @@ func (s *scanContext) getGroupKeyInfo(structType reflect.Type, parentField *refl
ret.indexes = append(ret.indexes, index)
}
}
}
return ret
}
@ -835,10 +836,9 @@ func (s *scanContext) rowElemValuePtr(index int) reflect.Value {
return newElem
}
func isPrimaryKey(field reflect.StructField, parentField *reflect.StructField) bool {
if hasOverwrite, isPrimaryKey := primaryKeyOvewrite(field.Name, parentField); hasOverwrite {
return isPrimaryKey
func isPrimaryKey(field reflect.StructField, primaryKeyOverwrites []string) bool {
if len(primaryKeyOverwrites) > 0 {
return utils.StringSliceContains(primaryKeyOverwrites, field.Name)
}
sqlTag := field.Tag.Get("sql")
@ -846,32 +846,24 @@ func isPrimaryKey(field reflect.StructField, parentField *reflect.StructField) b
return sqlTag == "primary_key"
}
func primaryKeyOvewrite(columnName string, parentField *reflect.StructField) (hasOverwrite, primaryKey bool) {
func parentFieldPrimaryKeyOverwrite(parentField *reflect.StructField) []string {
if parentField == nil {
return
return nil
}
sqlTag := parentField.Tag.Get("sql")
if !strings.HasPrefix(sqlTag, "primary_key") {
return
return nil
}
parts := strings.Split(sqlTag, "=")
if len(parts) < 2 {
return
return nil
}
primaryKeyColumns := strings.Split(parts[1], ",")
for _, primaryKeyCol := range primaryKeyColumns {
if toCommonIdentifier(columnName) == toCommonIdentifier(primaryKeyCol) {
return true, true
}
}
return true, false
return strings.Split(parts[1], ",")
}
func indirectType(reflectType reflect.Type) reflect.Type {

View file

@ -137,8 +137,8 @@ type ActorTable struct {
LastName mysql.ColumnString
LastUpdate mysql.ColumnTimestamp
AllColumns mysql.IColumnList
MutableColumns mysql.IColumnList
AllColumns mysql.ColumnList
MutableColumns mysql.ColumnList
}
// creates new ActorTable with assigned alias
@ -167,8 +167,8 @@ func newActorTable() *ActorTable {
LastName: LastNameColumn,
LastUpdate: LastUpdateColumn,
AllColumns: mysql.ColumnList(ActorIDColumn, FirstNameColumn, LastNameColumn, LastUpdateColumn),
MutableColumns: mysql.ColumnList(FirstNameColumn, LastNameColumn, LastUpdateColumn),
AllColumns: mysql.ColumnList{ActorIDColumn, FirstNameColumn, LastNameColumn, LastUpdateColumn},
MutableColumns: mysql.ColumnList{FirstNameColumn, LastNameColumn, LastUpdateColumn},
}
}
`
@ -206,8 +206,8 @@ type ActorInfoTable struct {
LastName mysql.ColumnString
FilmInfo mysql.ColumnString
AllColumns mysql.IColumnList
MutableColumns mysql.IColumnList
AllColumns mysql.ColumnList
MutableColumns mysql.ColumnList
}
// creates new ActorInfoTable with assigned alias
@ -236,8 +236,8 @@ func newActorInfoTable() *ActorInfoTable {
LastName: LastNameColumn,
FilmInfo: FilmInfoColumn,
AllColumns: mysql.ColumnList(ActorIDColumn, FirstNameColumn, LastNameColumn, FilmInfoColumn),
MutableColumns: mysql.ColumnList(ActorIDColumn, FirstNameColumn, LastNameColumn, FilmInfoColumn),
AllColumns: mysql.ColumnList{ActorIDColumn, FirstNameColumn, LastNameColumn, FilmInfoColumn},
MutableColumns: mysql.ColumnList{ActorIDColumn, FirstNameColumn, LastNameColumn, FilmInfoColumn},
}
}
`

View file

@ -118,7 +118,7 @@ func TestUpdateWithModelDataAndPredefinedColumnList(t *testing.T) {
Name: "DuckDuckGo",
}
updateColumnList := ColumnList(Link.Description, Link.Name, Link.URL)
updateColumnList := ColumnList{Link.Description, Link.Name, Link.URL}
stmt := Link.
UPDATE(updateColumnList).

View file

@ -85,9 +85,11 @@ func TestDeleteQueryContext(t *testing.T) {
func TestDeleteExecContext(t *testing.T) {
initForDeleteTest(t)
list := []Expression{String("Gmail"), String("Outlook")}
deleteStmt := Link.
DELETE().
WHERE(Link.Name.IN(String("Gmail"), String("Outlook")))
WHERE(Link.Name.IN(list...))
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Microsecond)
defer cancel()

View file

@ -171,8 +171,8 @@ type ActorTable struct {
LastName postgres.ColumnString
LastUpdate postgres.ColumnTimestamp
AllColumns postgres.IColumnList
MutableColumns postgres.IColumnList
AllColumns postgres.ColumnList
MutableColumns postgres.ColumnList
}
// creates new ActorTable with assigned alias
@ -201,8 +201,8 @@ func newActorTable() *ActorTable {
LastName: LastNameColumn,
LastUpdate: LastUpdateColumn,
AllColumns: postgres.ColumnList(ActorIDColumn, FirstNameColumn, LastNameColumn, LastUpdateColumn),
MutableColumns: postgres.ColumnList(FirstNameColumn, LastNameColumn, LastUpdateColumn),
AllColumns: postgres.ColumnList{ActorIDColumn, FirstNameColumn, LastNameColumn, LastUpdateColumn},
MutableColumns: postgres.ColumnList{FirstNameColumn, LastNameColumn, LastUpdateColumn},
}
}
`
@ -240,8 +240,8 @@ type ActorInfoTable struct {
LastName postgres.ColumnString
FilmInfo postgres.ColumnString
AllColumns postgres.IColumnList
MutableColumns postgres.IColumnList
AllColumns postgres.ColumnList
MutableColumns postgres.ColumnList
}
// creates new ActorInfoTable with assigned alias
@ -270,8 +270,8 @@ func newActorInfoTable() *ActorInfoTable {
LastName: LastNameColumn,
FilmInfo: FilmInfoColumn,
AllColumns: postgres.ColumnList(ActorIDColumn, FirstNameColumn, LastNameColumn, FilmInfoColumn),
MutableColumns: postgres.ColumnList(ActorIDColumn, FirstNameColumn, LastNameColumn, FilmInfoColumn),
AllColumns: postgres.ColumnList{ActorIDColumn, FirstNameColumn, LastNameColumn, FilmInfoColumn},
MutableColumns: postgres.ColumnList{ActorIDColumn, FirstNameColumn, LastNameColumn, FilmInfoColumn},
}
}
`

View file

@ -2,9 +2,9 @@ package postgres
import (
"fmt"
"github.com/go-jet/jet/execution"
"github.com/go-jet/jet/internal/testutils"
. "github.com/go-jet/jet/postgres"
"github.com/go-jet/jet/qrm"
"github.com/go-jet/jet/tests/.gentestdata/jetdb/dvds/model"
. "github.com/go-jet/jet/tests/.gentestdata/jetdb/dvds/table"
"github.com/google/uuid"
@ -57,7 +57,7 @@ func TestScanToValidDestination(t *testing.T) {
t.Run("global query function scan", func(t *testing.T) {
queryStr, args := query.Sql()
err := execution.Query(nil, db, queryStr, args, &struct{}{})
err := qrm.Query(nil, db, queryStr, args, &struct{}{})
assert.NilError(t, err)
})

View file

@ -191,7 +191,7 @@ func TestUpdateWithModelDataAndPredefinedColumnList(t *testing.T) {
Name: "DuckDuckGo",
}
updateColumnList := ColumnList(Link.Description, Link.Name, Link.URL)
updateColumnList := ColumnList{Link.Description, Link.Name, Link.URL}
stmt := Link.
UPDATE(updateColumnList).