Rename of types and errors.

This commit is contained in:
go-jet 2019-07-08 13:00:44 +02:00
parent 18bbf1b5fb
commit 63f2d04651
30 changed files with 142 additions and 238 deletions

View file

@ -247,7 +247,7 @@ jsonText, _ := json.MarshalIndent(dest, "", "\t")
fmt.Println(string(jsonText))
```
```json
```js
[
{
"ActorID": 1,
@ -319,7 +319,8 @@ fmt.Println(string(jsonText))
}
]
},
...(125 more items)
//...(125 more items)
]
```
What if we also want to have list of films per category and actors per category, where films are longer than 180 minutes, film language is 'English'
@ -340,7 +341,7 @@ handleError(err)
<details>
<summary>Click to see dest2 json</summary>
```json
```js
[
{
"CategoryID": 8,
@ -423,7 +424,8 @@ handleError(err)
}
]
},
...
//...
]
```
</details>

View file

@ -5,7 +5,7 @@ import (
)
func TestBoolExpressionEQ(t *testing.T) {
assertClauseSerializeErr(t, table1ColBool.EQ(nil), "nil rhs")
assertClauseSerializeErr(t, table1ColBool.EQ(nil), "jet: nil rhs")
assertClauseSerialize(t, table1ColBool.EQ(table2ColBool), "(table1.col_bool = table2.col_bool)")
assertClauseSerialize(t, table1ColBool.EQ(Bool(true)), "(table1.col_bool = $1)", true)
}

View file

@ -39,13 +39,13 @@ func (d *deleteStatementImpl) RETURNING(projections ...projection) DeleteStateme
func (d *deleteStatementImpl) serializeImpl(out *sqlBuilder) error {
if d == nil {
return errors.New("delete statement is nil")
return errors.New("jet: delete statement is nil")
}
out.newLine()
out.writeString("DELETE FROM")
if d.table == nil {
return errors.New("nil tableName")
return errors.New("jet: nil tableName")
}
if err := d.table.serialize(delete_statement, out); err != nil {
@ -53,7 +53,7 @@ func (d *deleteStatementImpl) serializeImpl(out *sqlBuilder) error {
}
if d.where == nil {
return errors.New("deleting without a WHERE clause")
return errors.New("jet: deleting without a WHERE clause")
}
if err := out.writeWhere(delete_statement, d.where); err != nil {

View file

@ -5,8 +5,8 @@ import (
)
func TestDeleteUnconditionally(t *testing.T) {
assertStatementErr(t, table1.DELETE(), `deleting without a WHERE clause`)
assertStatementErr(t, table1.DELETE().WHERE(nil), `deleting without a WHERE clause`)
assertStatementErr(t, table1.DELETE(), `jet: deleting without a WHERE clause`)
assertStatementErr(t, table1.DELETE().WHERE(nil), `jet: deleting without a WHERE clause`)
}
func TestDeleteWithWhere(t *testing.T) {

View file

@ -17,12 +17,12 @@ import (
func Query(db DB, context context.Context, query string, args []interface{}, destinationPtr interface{}) error {
if destinationPtr == nil {
return errors.New("Destination is nil. ")
return errors.New("jet: Destination is nil.")
}
destinationPtrType := reflect.TypeOf(destinationPtr)
if destinationPtrType.Kind() != reflect.Ptr {
return errors.New("Destination has to be a pointer to slice or pointer to struct. ")
return errors.New("jet: Destination has to be a pointer to slice or pointer to struct")
}
if destinationPtrType.Elem().Kind() == reflect.Slice {
@ -51,22 +51,22 @@ func Query(db DB, context context.Context, query string, args []interface{}, des
}
return nil
} else {
return errors.New("Unsupported destination type. ")
return errors.New("jet: unsupported destination type")
}
}
func queryToSlice(db DB, ctx context.Context, query string, args []interface{}, slicePtr interface{}) error {
if db == nil {
return errors.New("db is nil")
return errors.New("jet: db is nil")
}
if slicePtr == nil {
return errors.New("Destination is nil. ")
return errors.New("jet: Destination is nil. ")
}
destinationType := reflect.TypeOf(slicePtr)
if destinationType.Kind() != reflect.Ptr && destinationType.Elem().Kind() != reflect.Slice {
return errors.New("Destination has to be a pointer to slice. ")
return errors.New("jet: Destination has to be a pointer to slice. ")
}
if ctx == nil {
@ -157,7 +157,7 @@ func mapRowToSlice(scanContext *scanContext, groupKey string, slicePtrValue refl
}
if sliceElemType.Kind() != reflect.Struct {
return false, errors.New("Unsupported dest type: " + structField.Name + " " + structField.Type.String())
return false, errors.New("jet: Unsupported dest type: " + structField.Name + " " + structField.Type.String())
}
structGroupKey := scanContext.getGroupKey(sliceElemType, structField)
@ -229,7 +229,7 @@ func appendElemToSlice(slicePtrValue reflect.Value, objPtrValue reflect.Value) e
}
if !newElemValue.Type().AssignableTo(sliceElemType) {
return fmt.Errorf("Scan: can't append %s to %s slice ", newElemValue.Type().String(), sliceValue.Type().String())
return fmt.Errorf("jet: can't append %s to %s slice ", newElemValue.Type().String(), sliceValue.Type().String())
}
sliceValue.Set(reflect.Append(sliceValue, newElemValue))
@ -247,7 +247,7 @@ func newElemPtrValueForSlice(slicePtrValue reflect.Value) reflect.Value {
func mapRowToDestinationPtr(scanContext *scanContext, groupKey string, destPtrValue reflect.Value, structField *reflect.StructField) (updated bool, err error) {
if destPtrValue.Kind() != reflect.Ptr {
return false, errors.New("Internal error. ")
return false, errors.New("jet: Internal error. ")
}
destValueKind := destPtrValue.Elem().Kind()
@ -257,7 +257,7 @@ func mapRowToDestinationPtr(scanContext *scanContext, groupKey string, destPtrVa
} else if destValueKind == reflect.Slice {
return mapRowToSlice(scanContext, groupKey, destPtrValue, structField)
} else {
return false, errors.New("Unsupported dest type: " + structField.Name + " " + structField.Type.String())
return false, errors.New("jet: Unsupported dest type: " + structField.Name + " " + structField.Type.String())
}
}
@ -274,7 +274,7 @@ func mapRowToDestinationValue(scanContext *scanContext, groupKey string, dest re
destPtrValue = dest
}
} else {
return false, errors.New("Internal error. ")
return false, errors.New("jet: Internal error. ")
}
updated, err = mapRowToDestinationPtr(scanContext, groupKey, destPtrValue, structField)
@ -337,7 +337,7 @@ func mapRowToStruct(scanContext *scanContext, groupKey string, structPtrValue re
err = setReflectValue(reflect.ValueOf(cellValue), fieldValue)
if err != nil {
err = fmt.Errorf("Scan: %s, at struct field: %s %s of type %s. ", err.Error(), field.Name, field.Type.String(), structType.String())
err = fmt.Errorf("%s, at struct field: %s %s of type %s. ", err.Error(), field.Name, field.Type.String(), structType.String())
return
}
}
@ -456,7 +456,7 @@ func setReflectValue(source, destination reflect.Value) error {
}
if !sourceElem.Type().AssignableTo(destination.Type()) {
return errors.New("can't set " + sourceElem.Type().String() + " to " + destination.Type().String())
return errors.New("jet: can't set " + sourceElem.Type().String() + " to " + destination.Type().String())
}
destination.Set(sourceElem)

View file

@ -96,13 +96,13 @@ func newBinaryExpression(lhs, rhs Expression, operator string) binaryOpExpressio
func (c *binaryOpExpression) serialize(statement statementType, out *sqlBuilder, options ...serializeOption) error {
if c == nil {
return errors.New("binary Expression is nil")
return errors.New("jet: binary Expression is nil")
}
if c.lhs == nil {
return errors.New("nil lhs")
return errors.New("jet: nil lhs")
}
if c.rhs == nil {
return errors.New("nil rhs")
return errors.New("jet: nil rhs")
}
wrap := !contains(options, noWrap)
@ -145,13 +145,13 @@ func newPrefixExpression(expression Expression, operator string) prefixOpExpress
func (p *prefixOpExpression) serialize(statement statementType, out *sqlBuilder, options ...serializeOption) error {
if p == nil {
return errors.New("Prefix Expression is nil.")
return errors.New("jet: Prefix Expression is nil.")
}
out.writeString(p.operator + " ")
if p.expression == nil {
return errors.New("nil prefix Expression.")
return errors.New("jet: nil prefix Expression.")
}
if err := p.expression.serialize(statement, out); err != nil {
return err
@ -177,11 +177,11 @@ func newPostfixOpExpression(expression Expression, operator string) postfixOpExp
func (p *postfixOpExpression) serialize(statement statementType, out *sqlBuilder, options ...serializeOption) error {
if p == nil {
return errors.New("Postifx operator Expression is nil.")
return errors.New("jet: Postifx operator Expression is nil.")
}
if p.expression == nil {
return errors.New("nil prefix Expression.")
return errors.New("jet: nil prefix Expression.")
}
if err := p.expression.serialize(statement, out); err != nil {
return err

View file

@ -1,51 +0,0 @@
package jet
import (
"strconv"
"time"
)
type intervalExpression struct {
expressionInterfaceImpl
duration time.Duration
}
const intervalSep = ":"
func (c *intervalExpression) serialize(statement statementType, out *sqlBuilder, options ...serializeOption) error {
out.writeString("INTERVAL '")
duration := c.duration
if duration < 0 {
duration = -duration
out.writeString("-")
}
hours := duration / time.Hour
minutes := (duration % time.Hour) / time.Minute
sec := (duration % time.Minute) / time.Second
msec := (duration % time.Second) / time.Microsecond
out.writeString(strconv.FormatInt(int64(hours), 10))
out.writeString(intervalSep)
out.writeString(strconv.FormatInt(int64(minutes), 10))
out.writeString(intervalSep)
out.writeString(strconv.FormatInt(int64(sec), 10))
out.writeString(intervalSep)
out.writeString(strconv.FormatInt(int64(msec), 10))
out.writeString("' HOUR_MICROSECOND")
return nil
}
//// Interval returns a representation of duration
//func Interval(duration time.Duration) expressions {
// intervalExp := &intervalExpression{
// duration: duration,
// }
//
// intervalExp.expressionInterfaceImpl.parent = intervalExp
//
// return intervalExp
//}

View file

@ -1,76 +0,0 @@
// +build disabled
package jet
import (
"bytes"
"time"
gc "gopkg.in/check.v1"
)
func (s *ExprSuite) TestInterval(c *gc.C) {
testTable := []struct {
interval time.Duration
expected string
expectedErr error
}{
{
interval: 50 * time.Microsecond,
expected: "INTERVAL '0:0:0:50' HOUR_MICROSECOND",
},
{
interval: -50 * time.Microsecond,
expected: "INTERVAL '-0:0:0:50' HOUR_MICROSECOND",
},
{
interval: 50*time.Microsecond + 50*time.Second,
expected: "INTERVAL '0:0:50:50' HOUR_MICROSECOND",
},
{
interval: 50*time.Microsecond +
50*time.Second +
50*time.Minute,
expected: "INTERVAL '0:50:50:50' HOUR_MICROSECOND",
},
{
interval: 50*time.Microsecond +
50*time.Second +
50*time.Minute +
50*time.Hour,
expected: "INTERVAL '50:50:50:50' HOUR_MICROSECOND",
},
{
interval: 50 * time.Hour,
expected: "INTERVAL '50:0:0:0' HOUR_MICROSECOND",
},
{
interval: 50*time.Hour + 50*time.Minute,
expected: "INTERVAL '50:50:0:0' HOUR_MICROSECOND",
},
{
interval: 50*time.Hour + 50*time.Minute + 50*time.Second,
expected: "INTERVAL '50:50:50:0' HOUR_MICROSECOND",
},
{
interval: 0,
expected: "INTERVAL '0:0:0:0' HOUR_MICROSECOND",
},
{
interval: 50 * time.Nanosecond,
expected: "INTERVAL '0:0:0:0' HOUR_MICROSECOND",
},
}
buf := &bytes.Buffer{}
for i, tt := range testTable {
buf.Reset()
err := Interval(tt.interval).Serialize(buf)
c.Assert(err, gc.Equals, tt.expectedErr,
gc.Commentf("experiment #%d", i))
if err == nil {
c.Assert(buf.String(), gc.Equals, tt.expected,
gc.Commentf("experiment #%d", i))
}
}
}

View file

@ -46,7 +46,7 @@ func (e *expressionTableImpl) AllColumns() ProjectionList {
func (e *expressionTableImpl) serialize(statement statementType, out *sqlBuilder, options ...serializeOption) error {
if e == nil {
return errors.New("Expression table is nil. ")
return errors.New("jet: Expression table is nil. ")
}
err := e.expression.serialize(statement, out)

View file

@ -7,7 +7,7 @@ import (
func TestExpressionIS_NULL(t *testing.T) {
assertClauseSerialize(t, table2Col3.IS_NULL(), "table2.col3 IS NULL")
assertClauseSerialize(t, table2Col3.ADD(table2Col3).IS_NULL(), "(table2.col3 + table2.col3) IS NULL")
assertClauseSerializeErr(t, table2Col3.ADD(nil), "nil rhs")
assertClauseSerializeErr(t, table2Col3.ADD(nil), "jet: nil rhs")
}
func TestExpressionIS_NOT_NULL(t *testing.T) {

View file

@ -27,7 +27,7 @@ func newFunc(name string, expressions []Expression, parent Expression) *funcExpr
func (f *funcExpressionImpl) serialize(statement statementType, out *sqlBuilder, options ...serializeOption) error {
if f == nil {
return errors.New("Function expressions is nil. ")
return errors.New("jet: Function expressions is nil. ")
}
addBrackets := !f.noBrackets || len(f.expressions) > 0

View file

@ -103,7 +103,7 @@ const (
func (e *{{ToGoIdentifier $.Name}}) Scan(value interface{}) error {
if v, ok := value.(string); !ok {
return errors.New("Invalid data for {{ToGoIdentifier $.Name}} enum")
return errors.New("jet: Invalid data for {{ToGoIdentifier $.Name}} enum")
} else {
switch string(v) {
{{- range $index, $element := .Values}}
@ -111,7 +111,7 @@ func (e *{{ToGoIdentifier $.Name}}) Scan(value interface{}) error {
*e = {{ToGoIdentifier $.Name}}_{{ToGoIdentifier $element}}
{{- end}}
default:
return errors.New("Inavlid data " + string(v) + "for {{ToGoIdentifier $.Name}} enum")
return errors.New("jet: Inavlid data " + string(v) + "for {{ToGoIdentifier $.Name}} enum")
}
return nil

View file

@ -82,7 +82,7 @@ func (i *insertStatementImpl) Sql() (sql string, args []interface{}, err error)
queryData.writeString("INSERT INTO")
if isNil(i.table) {
return "", nil, errors.New("table is nil")
return "", nil, errors.New("jet: table is nil")
}
err = i.table.serialize(insert_statement, queryData)
@ -104,11 +104,11 @@ func (i *insertStatementImpl) Sql() (sql string, args []interface{}, err error)
}
if len(i.rows) == 0 && i.query == nil {
return "", nil, errors.New("no row values or query specified")
return "", nil, errors.New("jet: no row values or query specified")
}
if len(i.rows) > 0 && i.query != nil {
return "", nil, errors.New("only row values or query has to be specified")
return "", nil, errors.New("jet: only row values or query has to be specified")
}
if len(i.rows) > 0 {

View file

@ -7,8 +7,8 @@ import (
)
func TestInvalidInsert(t *testing.T) {
assertStatementErr(t, table1.INSERT(table1Col1), "no row values or query specified")
assertStatementErr(t, table1.INSERT(nil).VALUES(1), "nil column in columns list")
assertStatementErr(t, table1.INSERT(table1Col1), "jet: no row values or query specified")
assertStatementErr(t, table1.INSERT(nil).VALUES(1), "jet: nil column in columns list")
}
func TestInsertNilValue(t *testing.T) {

View file

@ -55,11 +55,11 @@ func (l *lockStatementImpl) DebugSql() (query string, err error) {
func (l *lockStatementImpl) Sql() (query string, args []interface{}, err error) {
if l == nil {
return "", nil, errors.New("nil Statement.")
return "", nil, errors.New("jet: nil Statement.")
}
if len(l.tables) == 0 {
return "", nil, errors.New("There is no table selected to be locked. ")
return "", nil, errors.New("jet: There is no table selected to be locked. ")
}
out := &sqlBuilder{}

View file

@ -102,7 +102,7 @@ func (c *caseOperatorImpl) ELSE(els Expression) CaseOperatorExpression {
func (c *caseOperatorImpl) serialize(statement statementType, out *sqlBuilder, options ...serializeOption) error {
if c == nil {
return errors.New("Case Expression is nil. ")
return errors.New("jet: Case Expression is nil. ")
}
out.writeString("(CASE")
@ -116,11 +116,11 @@ func (c *caseOperatorImpl) serialize(statement statementType, out *sqlBuilder, o
}
if len(c.when) == 0 || len(c.then) == 0 {
return errors.New("Invalid case Statement. There should be at least one when/then Expression pair. ")
return errors.New("jet: Invalid case Statement. There should be at least one when/then Expression pair. ")
}
if len(c.when) != len(c.then) {
return errors.New("When and then Expression count mismatch. ")
return errors.New("jet: When and then Expression count mismatch. ")
}
for i, when := range c.when {

View file

@ -13,7 +13,7 @@ type orderByClauseImpl struct {
func (o *orderByClauseImpl) serializeForOrderBy(statement statementType, out *sqlBuilder) error {
if o.expression == nil {
return errors.New("nil orderBy by clause.")
return errors.New("jet: nil orderBy by clause.")
}
if err := o.expression.serializeForOrderBy(statement, out); err != nil {

View file

@ -155,7 +155,7 @@ func (s *selectStatementImpl) projections() []projection {
func (s *selectStatementImpl) serialize(statement statementType, out *sqlBuilder, options ...serializeOption) error {
if s == nil {
return errors.New("Select expression is nil. ")
return errors.New("jet: Select expression is nil. ")
}
out.writeString("(")
@ -175,7 +175,7 @@ func (s *selectStatementImpl) serialize(statement statementType, out *sqlBuilder
func (s *selectStatementImpl) serializeImpl(out *sqlBuilder) error {
if s == nil {
return errors.New("Select expression is nil. ")
return errors.New("jet: Select expression is nil. ")
}
out.newLine()
@ -186,7 +186,7 @@ func (s *selectStatementImpl) serializeImpl(out *sqlBuilder) error {
}
if len(s.projectionList) == 0 {
return errors.New("no column selected for projection")
return errors.New("jet: no column selected for projection")
}
err := out.writeProjections(select_statement, s.projectionList)

View file

@ -3,7 +3,7 @@ package jet
import "testing"
func TestInvalidSelect(t *testing.T) {
assertStatementErr(t, SELECT(nil), "projection is nil")
assertStatementErr(t, SELECT(nil), "jet: projection is nil")
}
func TestSelectColumnList(t *testing.T) {

View file

@ -71,7 +71,7 @@ func (s *setStatementImpl) projections() []projection {
func (s *setStatementImpl) serialize(statement statementType, out *sqlBuilder, options ...serializeOption) error {
if s == nil {
return errors.New("Set expression is nil. ")
return errors.New("jet: Set expression is nil. ")
}
wrap := s.orderBy != nil || s.limit >= 0 || s.offset >= 0
@ -98,11 +98,11 @@ func (s *setStatementImpl) serialize(statement statementType, out *sqlBuilder, o
func (s *setStatementImpl) serializeImpl(out *sqlBuilder) error {
if s == nil {
return errors.New("Set expression is nil. ")
return errors.New("jet: Set expression is nil. ")
}
if len(s.selects) < 2 {
return errors.New("UNION Statement must have at least two SELECT statements.")
return errors.New("jet: UNION Statement must have at least two SELECT statements.")
}
out.newLine()
@ -121,7 +121,7 @@ func (s *setStatementImpl) serializeImpl(out *sqlBuilder) error {
}
if selectStmt == nil {
return errors.New("select statement is nil")
return errors.New("jet: select statement is nil")
}
err := selectStmt.serialize(set_statement, out)

View file

@ -37,7 +37,7 @@ func TestUnionNilSelect(t *testing.T) {
SELECT(table1Col1).
UNION(nil)
assertStatementErr(t, unionStmt, "select statement is nil")
assertStatementErr(t, unionStmt, "jet: select statement is nil")
}
func TestUnionThreeSelect1(t *testing.T) {

View file

@ -170,7 +170,7 @@ func (t *tableImpl) columns() []column {
func (t *tableImpl) serialize(statement statementType, out *sqlBuilder, options ...serializeOption) error {
if t == nil {
return errors.New("tableImpl is nil. ")
return errors.New("jet: tableImpl is nil. ")
}
out.writeIdentifier(t.schemaName)
@ -237,11 +237,11 @@ func (t *joinTable) columns() []column {
func (t *joinTable) serialize(statement statementType, out *sqlBuilder, options ...serializeOption) (err error) {
if t == nil {
return errors.New("Join table is nil. ")
return errors.New("jet: Join table is nil. ")
}
if isNil(t.lhs) {
return errors.New("left hand side of join operation is nil table")
return errors.New("jet: left hand side of join operation is nil table")
}
if err = t.lhs.serialize(statement, out); err != nil {
@ -264,7 +264,7 @@ func (t *joinTable) serialize(statement statementType, out *sqlBuilder, options
}
if isNil(t.rhs) {
return errors.New("right hand side of join operation is nil table")
return errors.New("jet: right hand side of join operation is nil table")
}
if err = t.rhs.serialize(statement, out); err != nil {
@ -272,7 +272,7 @@ func (t *joinTable) serialize(statement statementType, out *sqlBuilder, options
}
if t.onCondition == nil && t.join_type != crossJoin {
return errors.New("join condition is nil")
return errors.New("jet: join condition is nil")
}
if t.onCondition != nil {

View file

@ -6,9 +6,9 @@ import (
func TestJoinNilInputs(t *testing.T) {
assertClauseSerializeErr(t, table2.INNER_JOIN(nil, table1ColBool.EQ(table2ColBool)),
"right hand side of join operation is nil table")
"jet: right hand side of join operation is nil table")
assertClauseSerializeErr(t, table2.INNER_JOIN(table1, nil),
"join condition is nil")
"jet: join condition is nil")
}
func TestINNER_JOIN(t *testing.T) {

View file

@ -21,31 +21,31 @@ func TestScanToInvalidDestination(t *testing.T) {
t.Run("nil dest", func(t *testing.T) {
err := query.Query(db, nil)
assert.Error(t, err, "Destination is nil. ")
assert.Error(t, err, "jet: Destination is nil.")
})
t.Run("struct dest", func(t *testing.T) {
err := query.Query(db, struct{}{})
assert.Error(t, err, "Destination has to be a pointer to slice or pointer to struct. ")
assert.Error(t, err, "jet: Destination has to be a pointer to slice or pointer to struct")
})
t.Run("slice dest", func(t *testing.T) {
err := query.Query(db, []struct{}{})
assert.Error(t, err, "Destination has to be a pointer to slice or pointer to struct. ")
assert.Error(t, err, "jet: Destination has to be a pointer to slice or pointer to struct")
})
t.Run("slice of pointers to pointer dest", func(t *testing.T) {
err := query.Query(db, []**struct{}{})
assert.Error(t, err, "Destination has to be a pointer to slice or pointer to struct. ")
assert.Error(t, err, "jet: Destination has to be a pointer to slice or pointer to struct")
})
t.Run("map dest", func(t *testing.T) {
err := query.Query(db, []map[string]string{})
assert.Error(t, err, "Destination has to be a pointer to slice or pointer to struct. ")
assert.Error(t, err, "jet: Destination has to be a pointer to slice or pointer to struct")
})
}
@ -129,7 +129,7 @@ func TestScanToStruct(t *testing.T) {
err := query.Query(db, &dest)
assert.Error(t, err, "Unsupported dest type: Inventory **model.Inventory")
assert.Error(t, err, "jet: Unsupported dest type: Inventory **model.Inventory")
})
t.Run("invalid dest 2", func(t *testing.T) {
@ -139,7 +139,7 @@ func TestScanToStruct(t *testing.T) {
err := query.Query(db, &dest)
assert.Error(t, err, "Unsupported dest type: Inventory ***model.Inventory")
assert.Error(t, err, "jet: Unsupported dest type: Inventory ***model.Inventory")
})
t.Run("custom struct", func(t *testing.T) {
@ -170,7 +170,7 @@ func TestScanToStruct(t *testing.T) {
err := query.Query(db, &dest)
assert.Error(t, err, `Scan: can't set int32 to int, at struct field: InventoryID int of type tests.Inventory. `)
assert.Error(t, err, `jet: can't set int32 to int, at struct field: InventoryID int of type tests.Inventory. `)
fmt.Println(err)
})
@ -431,7 +431,7 @@ func TestScanToSlice(t *testing.T) {
var dest []int
err := query.Query(db, &dest)
assert.Error(t, err, `Scan: can't append int32 to []int slice `)
assert.Error(t, err, `jet: can't append int32 to []int slice `)
})
})
@ -678,7 +678,7 @@ func TestScanToSlice(t *testing.T) {
err := query.Query(db, &dest)
assert.Error(t, err, "Unsupported dest type: Cities []**struct { *model.City }")
assert.Error(t, err, "jet: Unsupported dest type: Cities []**struct { *model.City }")
})
}

View file

@ -861,14 +861,14 @@ FROM dvds.film
WHERE film.rental_rate = (
SELECT MAX(film.rental_rate)
FROM dvds.film
)::double precision
)
ORDER BY film.film_id ASC;
`
maxFilmRentalRate := CAST(
maxFilmRentalRate := FloatExp(
Film.
SELECT(MAXf(Film.RentalRate)),
).AS_DOUBLE()
)
query := Film.
SELECT(Film.AllColumns).

View file

@ -62,7 +62,7 @@ func (u *updateStatementImpl) Sql() (sql string, args []interface{}, err error)
out.writeString("UPDATE")
if isNil(u.table) {
return "", nil, errors.New("table to update is nil")
return "", nil, errors.New("jet: table to update is nil")
}
if err = u.table.serialize(update_statement, out); err != nil {
@ -70,11 +70,11 @@ func (u *updateStatementImpl) Sql() (sql string, args []interface{}, err error)
}
if len(u.columns) == 0 {
return "", nil, errors.New("no columns selected")
return "", nil, errors.New("jet: no columns selected")
}
if len(u.row) == 0 {
return "", nil, errors.New("no values to updated")
return "", nil, errors.New("jet: no values to updated")
}
out.newLine()
@ -111,7 +111,7 @@ func (u *updateStatementImpl) Sql() (sql string, args []interface{}, err error)
}
if u.where == nil {
return "", nil, errors.New("WHERE clause not set")
return "", nil, errors.New("jet: WHERE clause not set")
}
if err = out.writeWhere(update_statement, u.where); err != nil {

View file

@ -71,6 +71,6 @@ RETURNING table1.col1 AS "table1.col1";
}
func TestInvalidInputs(t *testing.T) {
assertStatementErr(t, table1.UPDATE(table1ColInt).SET(1, 2), "WHERE clause not set")
assertStatementErr(t, table1.UPDATE(nil).SET(1, 2), "nil column in columns list")
assertStatementErr(t, table1.UPDATE(table1ColInt).SET(1, 2), "jet: WHERE clause not set")
assertStatementErr(t, table1.UPDATE(nil).SET(1, 2), "jet: nil column in columns list")
}

View file

@ -32,7 +32,7 @@ func serializeGroupByClauseList(statement statementType, clauses []groupByClause
}
if c == nil {
return errors.New("nil clause.")
return errors.New("jet: nil clause.")
}
if err = c.serializeForGroupBy(statement, out); err != nil {
@ -51,7 +51,7 @@ func serializeClauseList(statement statementType, clauses []clause, out *sqlBuil
}
if c == nil {
return errors.New("nil clause.")
return errors.New("jet: nil clause.")
}
if err = c.serialize(statement, out); err != nil {
@ -87,7 +87,7 @@ func serializeProjectionList(statement statementType, projections []projection,
}
if col == nil {
return errors.New("projection is nil")
return errors.New("jet: projection is nil")
}
if err := col.serializeForProjection(statement, out); err != nil {
@ -105,7 +105,7 @@ func serializeColumnNames(columns []column, out *sqlBuilder) error {
}
if col == nil {
return errors.New("nil column in columns list")
return errors.New("jet: nil column in columns list")
}
out.writeString(col.Name())

View file

@ -13,7 +13,7 @@ Jet sql builder supports following expression types:
_This list might be extended with feature Jet releases._
### Literal type
### Literal Types
For every expression type there is a method to create one expression literal type .
Literal type examples:
@ -32,7 +32,7 @@ jet.NULL
jet.STAR (alias for *)
```
### Column types
### Column Types
Every sql builder table column belongs to one expression type. There are following column types:
```
jet.ColumnBool
@ -62,7 +62,7 @@ jet.Int(11).LIKE(jet.Float(22.2)) // integer expressions doesn't have LIKE
```
## Comparision operators
## Comparision Operators
Jet supports following comparison operators for all expression types:
@ -80,7 +80,7 @@ Jet supports following comparison operators for all expression types:
*Left-hand side and right-hand side of operators have to be of the same type*
## Arithmetic operators
## Arithmetic Operators
Following arithmetic operators are supported for integer and float expressions.
If the first argument is float expression, second argument can be integer or float expression.
@ -96,7 +96,7 @@ If the first argument is integer expression second argument can only be integer
| POW | jet.Float(10.01).POW(table.Film.Length) | 10.01 ^ film.length |
## Bit operators
## Bit Operators
Following operators are only available on integer expressions:
@ -110,7 +110,7 @@ Following operators are only available on integer expressions:
| BIT_SHIFT_RIGHT | jet.Int(11).BIT_SHIFT_RIGHT(table.Film.Length) | 11 >> film.length |
## Logical operators
## Logical Operators
Following operators are only available on boolean expressions:
@ -124,7 +124,7 @@ Following operators are only available on boolean expressions:
| IS_NOT_UNKNOWN | table.Staff.Active.IS_NOT_UNKNOWN() | staff.active IS NOT UNKNOWN |
## String operators
## String Operators
Following operators are only available on string expressions:
@ -137,27 +137,56 @@ Following operators are only available on string expressions:
| NOT_SIMILAR_TO | table.Film.Name.NOT_SIMILAR_TO(String("%Wind%")) | staff.active NOT SIMILAR TO %Wind% |
## SQL Cast operators
## SQL Cast Operators
Cast operators allow expressions to be casted to some other database type.
SQL builder expression type changes accordingly to database type.
| Method | Example | Generated sql |
| ------------------------------ | -------------------------------------------|---------------------------- |
| TO_BOOL | table.Film.Description.TO_BOOL() | film.description::boolean |
| TO_SMALLINT | table.Film.Description.TO_SMALLINT() | film.description::smallint |
| TO_INTEGER | table.Film.Description.TO_INTEGER() | film.description::integer |
| TO_BIGINT | table.Film.Description.TO_BIGINT() | film.description::bigint |
| TO_NUMERIC | table.Film.Description.TO_NUMERIC(10, 6) | film.description::numeric(10,6) |
| TO_REAL | table.Film.Description.TO_REAL() | film.description::real |
| TO_DOUBLE | table.Film.Description.TO_DOUBLE() | film.description::double |
| TO_TEXT | table.Film.Description.TO_TEXT() | film.description::text |
| TO_DATE | table.Film.Description.TO_DATE() | film.description::date |
| TO_TIME | table.Film.Description.TO_TIME() | film.description::time |
| TO_TIMEZ | table.Film.Description.TO_TIMEZ() | film.description::timez |
| TO_TIMESTAMP | table.Film.Description.TO_TIMESTAMP() | film.description::timestamp |
| TO_TIMESTAMPZ | table.Film.Description.TO_TIMESTAMPZ() | film.description::timestampz |
| ------------------------------ | ----------------------------------------------- | --------------------------------------------- |
| CAST(exp).AS_BOOL() | CAST(table.Film.Description).AS_BOOL() | film.description::boolean |
| CAST(exp).AS_SMALLINT() | CAST(table.Film.Description).AS_SMALLINT() | film.description::smallint |
| CAST(exp).AS_INTEGER() | CAST(table.Film.Description).AS_INTEGER() | film.description::integer |
| CAST(exp).AS_BIGINT() | CAST(table.Film.Description).AS_BIGINT() | film.description::bigint |
| CAST(exp).AS_NUMERIC() | CAST(table.Film.Description).AS_NUMERIC(10, 6) | film.description::numeric(10,6) |
| CAST(exp).AS_REAL() | CAST(table.Film.Description).AS_REAL() | film.description::real |
| CAST(exp).AS_DOUBLE() | CAST(table.Film.Description).AS_DOUBLE() | film.description::double |
| CAST(exp).AS_TEXT() | CAST(table.Film.Description).AS_TEXT() | film.description::text |
| CAST(exp).AS_DATE() | CAST(table.Film.Description).AS_DATE() | film.description::date |
| CAST(exp).AS_TIME() | CAST(table.Film.Description).AS_TIME() | film.description::time without time zone |
| CAST(exp).AS_TIMEZ() | CAST(table.Film.Description).AS_TIMEZ() | film.description::time with time zone |
| CAST(exp).AS_TIMESTAMP() | CAST(table.Film.Description).AS_TIMESTAMP() | film.description::timestamp without time zone |
| CAST(exp).AS_TIMESTAMPZ() | CAST(table.Film.Description).AS_TIMESTAMPZ() | film.description::timestamp with time zone |
## SQL builder cast
## SQL Builder Cast Wrapper
TODO:
For some expressions sql builder can't deduce expression type directly. For instance scalar sub-query:
```
( SELECT(MAXf(Film.RentalRate)).
FROM(Film) ).LT(Float(11.1))
```
This expression would not compile, because sub-query, although calculates one scalar float value, it is not a float expression.
To fix this sub-query can be cast to some float type, or just wrapped as float expression:
```
FloatExp( SELECT(MAXf(Film.RentalRate)).
FROM(Film) ).LT(Float(11.1))
```
There are wrappers for all supported types:
```
- BoolExp(exp)
- IntExp(exp)
- FloatExp(exp)
- StringExp(exp)
- DateExp(exp)
- TimeExp(exp)
- TimezExp(exp)
- TimestampExp(exp)
- TimestampzExp(exp)
```
**Cast wrapper does NOT inject cast operator to generated SQL.**
## RAW Operator
There is a RAW operator expression, that accepts raw sql as a string. It can be used for any unsupported functions, operators or expressions.
For example:
```RAW("current_database()")``` _can be cast or wrapped, as needed._

View file

@ -113,7 +113,7 @@ const (
func (e *MpaaRating) Scan(value interface{}) error {
if v, ok := value.(string); !ok {
return errors.New("Invalid data for MpaaRating enum")
return errors.New("jet: Invalid data for MpaaRating enum")
} else {
switch string(v) {
case "G":