Add support for blob expressions.

This commit is contained in:
go-jet 2025-02-28 18:23:15 +01:00
parent 26e478dc7e
commit c94216ab0e
37 changed files with 1296 additions and 81 deletions

View file

@ -511,7 +511,8 @@ func TestStringOperators(t *testing.T) {
RTRIM(AllTypes.VarCharPtr),
CONCAT(String("string1"), Int(1), Float(11.12)),
CONCAT_WS(String("string1"), Int(1), Float(11.12)),
FORMAT(String("Hello %s, %1$s"), String("World")),
FORMAT(Int(11), Int(2)),
FORMAT(Int(11), Int(2), String("de_DE")),
LEFT(String("abcde"), Int(2)),
RIGHT(String("abcde"), Int(2)),
LENGTH(String("jose")),
@ -523,6 +524,12 @@ func TestStringOperators(t *testing.T) {
REVERSE(AllTypes.VarCharPtr),
SUBSTR(AllTypes.CharPtr, Int(3)),
SUBSTR(AllTypes.CharPtr, Int(3), Int(2)),
ELT(Int(2), AllTypes.CharPtr, AllTypes.Char, AllTypes.Text),
FIELD(AllTypes.Char, AllTypes.VarChar, AllTypes.Text),
FROM_BASE64(String("SGVsbG8gV29ybGQ=")),
TO_BASE64(String("Hello World")),
CHARSET(AllTypes.Char),
COLLATION(AllTypes.Text),
}
if !sourceIsMariaDB() {
@ -544,6 +551,71 @@ func TestStringOperators(t *testing.T) {
require.NoError(t, err)
}
func TestBlob(t *testing.T) {
var sampleBlob = Blob([]byte{11, 0, 22, 33, 44})
var textBlob = Blob([]byte("text blob"))
stmt := SELECT(
AllTypes.BlobPtr.EQ(sampleBlob),
AllTypes.BlobPtr.EQ(AllTypes.BlobPtr),
AllTypes.BlobPtr.NOT_EQ(sampleBlob),
AllTypes.BlobPtr.GT(textBlob),
AllTypes.BlobPtr.GT_EQ(AllTypes.BlobPtr),
AllTypes.BlobPtr.LT(AllTypes.BlobPtr),
AllTypes.BlobPtr.LT_EQ(sampleBlob),
AllTypes.BlobPtr.BETWEEN(Blob([]byte("min")), Blob([]byte("max"))),
AllTypes.BlobPtr.NOT_BETWEEN(AllTypes.BlobPtr, AllTypes.BlobPtr),
AllTypes.BlobPtr.CONCAT(textBlob),
AllTypes.BlobPtr.LIKE(AllTypes.BlobPtr),
AllTypes.BlobPtr.NOT_LIKE(sampleBlob),
BIT_LENGTH(textBlob),
LENGTH(sampleBlob),
CHAR_LENGTH(AllTypes.BlobPtr),
OCTET_LENGTH(textBlob),
CONCAT(sampleBlob, Int(1), Float(11.12)),
TO_BASE64(sampleBlob),
HEX(sampleBlob),
UNHEX(String("616B263A")),
SUBSTR(AllTypes.BlobPtr, Int(3)),
SUBSTR(AllTypes.BlobPtr, Int(3), Int(2)),
).FROM(
AllTypes,
)
testutils.AssertDebugStatementSql(t, stmt, `
SELECT all_types.blob_ptr = X'0b0016212c',
all_types.blob_ptr = all_types.blob_ptr,
all_types.blob_ptr != X'0b0016212c',
all_types.blob_ptr > X'7465787420626c6f62',
all_types.blob_ptr >= all_types.blob_ptr,
all_types.blob_ptr < all_types.blob_ptr,
all_types.blob_ptr <= X'0b0016212c',
all_types.blob_ptr BETWEEN X'6d696e' AND X'6d6178',
all_types.blob_ptr NOT BETWEEN all_types.blob_ptr AND all_types.blob_ptr,
CONCAT(all_types.blob_ptr, X'7465787420626c6f62'),
all_types.blob_ptr LIKE all_types.blob_ptr,
all_types.blob_ptr NOT LIKE X'0b0016212c',
BIT_LENGTH(X'7465787420626c6f62'),
LENGTH(X'0b0016212c'),
CHAR_LENGTH(all_types.blob_ptr),
OCTET_LENGTH(X'7465787420626c6f62'),
CONCAT(X'0b0016212c', 1, 11.12),
TO_BASE64(X'0b0016212c'),
HEX(X'0b0016212c'),
UNHEX('616B263A'),
SUBSTR(all_types.blob_ptr, 3),
SUBSTR(all_types.blob_ptr, 3, 2)
FROM test_sample.all_types;
`)
var dest []struct{}
err := stmt.Query(db, &dest)
require.NoError(t, err)
}
var timeT = time.Date(2009, 11, 17, 20, 34, 58, 651387237, time.UTC)
func TestTimeExpressions(t *testing.T) {

View file

@ -3,6 +3,7 @@ package mysql
import (
"os"
"os/exec"
"path/filepath"
"strconv"
"testing"
@ -606,3 +607,394 @@ func UseSchema(schema string) {
StaffList = StaffList.FromSchema(schema)
}
`
func TestGeneratedTestSampleDatabase(t *testing.T) {
enumDir := filepath.Join(testRoot, "/.gentestdata/mysql/test_sample/enum/")
modelDir := filepath.Join(testRoot, "/.gentestdata/mysql/test_sample/model/")
tableDir := filepath.Join(testRoot, "/.gentestdata/mysql/test_sample/table/")
viewDir := filepath.Join(testRoot, "/.gentestdata/mysql/test_sample/view/")
testutils.AssertFileNamesEqual(t, enumDir, "all_types_enum.go", "all_types_enum_ptr.go",
"all_types_view_enum.go", "all_types_view_enum_ptr.go")
testutils.AssertFileContent(t, enumDir+"/all_types_enum.go", allTypesEnum)
testutils.AssertFileNamesEqual(t, modelDir, "all_types.go", "all_types_enum.go", "all_types_enum_ptr.go",
"all_types_view.go", "all_types_view_enum.go", "all_types_view_enum_ptr.go", "link.go", "link2.go",
"floats.go", "user.go")
testutils.AssertFileContent(t, modelDir+"/all_types.go", allTypesModelContent)
testutils.AssertFileNamesEqual(t, tableDir, "all_types.go",
"link.go", "link2.go", "user.go", "floats.go", "table_use_schema.go")
testutils.AssertFileContent(t, tableDir+"/all_types.go", allTypesTableContent)
testutils.AssertFileNamesEqual(t, viewDir, "all_types_view.go", "view_use_schema.go")
}
var allTypesEnum = `
//
// Code generated by go-jet DO NOT EDIT.
//
// WARNING: Changes to this file may cause incorrect behavior
// and will be lost if the code is regenerated
//
package enum
import "github.com/go-jet/jet/v2/mysql"
var AllTypesEnum = &struct {
Value1 mysql.StringExpression
Value2 mysql.StringExpression
Value3 mysql.StringExpression
}{
Value1: mysql.NewEnumValue("value1"),
Value2: mysql.NewEnumValue("value2"),
Value3: mysql.NewEnumValue("value3"),
}
`
var allTypesModelContent = `
//
// Code generated by go-jet DO NOT EDIT.
//
// WARNING: Changes to this file may cause incorrect behavior
// and will be lost if the code is regenerated
//
package model
import (
"time"
)
type AllTypes struct {
Boolean bool
BooleanPtr *bool
TinyInt int8
UTinyInt uint8
SmallInt int16
USmallInt uint16
MediumInt int32
UMediumInt uint32
Integer int32
UInteger uint32
BigInt int64
UBigInt uint64
TinyIntPtr *int8
UTinyIntPtr *uint8
SmallIntPtr *int16
USmallIntPtr *uint16
MediumIntPtr *int32
UMediumIntPtr *uint32
IntegerPtr *int32
UIntegerPtr *uint32
BigIntPtr *int64
UBigIntPtr *uint64
Decimal float64
DecimalPtr *float64
Numeric float64
NumericPtr *float64
Float float64
FloatPtr *float64
Double float64
DoublePtr *float64
Real float64
RealPtr *float64
Bit string
BitPtr *string
Time time.Time
TimePtr *time.Time
Date time.Time
DatePtr *time.Time
DateTime time.Time
DateTimePtr *time.Time
Timestamp time.Time
TimestampPtr *time.Time
Year int16
YearPtr *int16
Char string
CharPtr *string
VarChar string
VarCharPtr *string
Binary []byte
BinaryPtr *[]byte
VarBinary []byte
VarBinaryPtr *[]byte
Blob []byte
BlobPtr *[]byte
Text string
TextPtr *string
Enum AllTypesEnum
EnumPtr *AllTypesEnumPtr
Set string
SetPtr *string
JSON string
JSONPtr *string
}
`
var allTypesTableContent = `
//
// Code generated by go-jet DO NOT EDIT.
//
// WARNING: Changes to this file may cause incorrect behavior
// and will be lost if the code is regenerated
//
package table
import (
"github.com/go-jet/jet/v2/mysql"
)
var AllTypes = newAllTypesTable("test_sample", "all_types", "")
type allTypesTable struct {
mysql.Table
// Columns
Boolean mysql.ColumnBool
BooleanPtr mysql.ColumnBool
TinyInt mysql.ColumnInteger
UTinyInt mysql.ColumnInteger
SmallInt mysql.ColumnInteger
USmallInt mysql.ColumnInteger
MediumInt mysql.ColumnInteger
UMediumInt mysql.ColumnInteger
Integer mysql.ColumnInteger
UInteger mysql.ColumnInteger
BigInt mysql.ColumnInteger
UBigInt mysql.ColumnInteger
TinyIntPtr mysql.ColumnInteger
UTinyIntPtr mysql.ColumnInteger
SmallIntPtr mysql.ColumnInteger
USmallIntPtr mysql.ColumnInteger
MediumIntPtr mysql.ColumnInteger
UMediumIntPtr mysql.ColumnInteger
IntegerPtr mysql.ColumnInteger
UIntegerPtr mysql.ColumnInteger
BigIntPtr mysql.ColumnInteger
UBigIntPtr mysql.ColumnInteger
Decimal mysql.ColumnFloat
DecimalPtr mysql.ColumnFloat
Numeric mysql.ColumnFloat
NumericPtr mysql.ColumnFloat
Float mysql.ColumnFloat
FloatPtr mysql.ColumnFloat
Double mysql.ColumnFloat
DoublePtr mysql.ColumnFloat
Real mysql.ColumnFloat
RealPtr mysql.ColumnFloat
Bit mysql.ColumnString
BitPtr mysql.ColumnString
Time mysql.ColumnTime
TimePtr mysql.ColumnTime
Date mysql.ColumnDate
DatePtr mysql.ColumnDate
DateTime mysql.ColumnTimestamp
DateTimePtr mysql.ColumnTimestamp
Timestamp mysql.ColumnTimestamp
TimestampPtr mysql.ColumnTimestamp
Year mysql.ColumnInteger
YearPtr mysql.ColumnInteger
Char mysql.ColumnString
CharPtr mysql.ColumnString
VarChar mysql.ColumnString
VarCharPtr mysql.ColumnString
Binary mysql.ColumnBlob
BinaryPtr mysql.ColumnBlob
VarBinary mysql.ColumnBlob
VarBinaryPtr mysql.ColumnBlob
Blob mysql.ColumnBlob
BlobPtr mysql.ColumnBlob
Text mysql.ColumnString
TextPtr mysql.ColumnString
Enum mysql.ColumnString
EnumPtr mysql.ColumnString
Set mysql.ColumnString
SetPtr mysql.ColumnString
JSON mysql.ColumnString
JSONPtr mysql.ColumnString
AllColumns mysql.ColumnList
MutableColumns mysql.ColumnList
DefaultColumns mysql.ColumnList
}
type AllTypesTable struct {
allTypesTable
NEW allTypesTable
}
// AS creates new AllTypesTable with assigned alias
func (a AllTypesTable) AS(alias string) *AllTypesTable {
return newAllTypesTable(a.SchemaName(), a.TableName(), alias)
}
// Schema creates new AllTypesTable with assigned schema name
func (a AllTypesTable) FromSchema(schemaName string) *AllTypesTable {
return newAllTypesTable(schemaName, a.TableName(), a.Alias())
}
// WithPrefix creates new AllTypesTable with assigned table prefix
func (a AllTypesTable) WithPrefix(prefix string) *AllTypesTable {
return newAllTypesTable(a.SchemaName(), prefix+a.TableName(), a.TableName())
}
// WithSuffix creates new AllTypesTable with assigned table suffix
func (a AllTypesTable) WithSuffix(suffix string) *AllTypesTable {
return newAllTypesTable(a.SchemaName(), a.TableName()+suffix, a.TableName())
}
func newAllTypesTable(schemaName, tableName, alias string) *AllTypesTable {
return &AllTypesTable{
allTypesTable: newAllTypesTableImpl(schemaName, tableName, alias),
NEW: newAllTypesTableImpl("", "new", ""),
}
}
func newAllTypesTableImpl(schemaName, tableName, alias string) allTypesTable {
var (
BooleanColumn = mysql.BoolColumn("boolean")
BooleanPtrColumn = mysql.BoolColumn("boolean_ptr")
TinyIntColumn = mysql.IntegerColumn("tiny_int")
UTinyIntColumn = mysql.IntegerColumn("u_tiny_int")
SmallIntColumn = mysql.IntegerColumn("small_int")
USmallIntColumn = mysql.IntegerColumn("u_small_int")
MediumIntColumn = mysql.IntegerColumn("medium_int")
UMediumIntColumn = mysql.IntegerColumn("u_medium_int")
IntegerColumn = mysql.IntegerColumn("integer")
UIntegerColumn = mysql.IntegerColumn("u_integer")
BigIntColumn = mysql.IntegerColumn("big_int")
UBigIntColumn = mysql.IntegerColumn("u_big_int")
TinyIntPtrColumn = mysql.IntegerColumn("tiny_int_ptr")
UTinyIntPtrColumn = mysql.IntegerColumn("u_tiny_int_ptr")
SmallIntPtrColumn = mysql.IntegerColumn("small_int_ptr")
USmallIntPtrColumn = mysql.IntegerColumn("u_small_int_ptr")
MediumIntPtrColumn = mysql.IntegerColumn("medium_int_ptr")
UMediumIntPtrColumn = mysql.IntegerColumn("u_medium_int_ptr")
IntegerPtrColumn = mysql.IntegerColumn("integer_ptr")
UIntegerPtrColumn = mysql.IntegerColumn("u_integer_ptr")
BigIntPtrColumn = mysql.IntegerColumn("big_int_ptr")
UBigIntPtrColumn = mysql.IntegerColumn("u_big_int_ptr")
DecimalColumn = mysql.FloatColumn("decimal")
DecimalPtrColumn = mysql.FloatColumn("decimal_ptr")
NumericColumn = mysql.FloatColumn("numeric")
NumericPtrColumn = mysql.FloatColumn("numeric_ptr")
FloatColumn = mysql.FloatColumn("float")
FloatPtrColumn = mysql.FloatColumn("float_ptr")
DoubleColumn = mysql.FloatColumn("double")
DoublePtrColumn = mysql.FloatColumn("double_ptr")
RealColumn = mysql.FloatColumn("real")
RealPtrColumn = mysql.FloatColumn("real_ptr")
BitColumn = mysql.StringColumn("bit")
BitPtrColumn = mysql.StringColumn("bit_ptr")
TimeColumn = mysql.TimeColumn("time")
TimePtrColumn = mysql.TimeColumn("time_ptr")
DateColumn = mysql.DateColumn("date")
DatePtrColumn = mysql.DateColumn("date_ptr")
DateTimeColumn = mysql.TimestampColumn("date_time")
DateTimePtrColumn = mysql.TimestampColumn("date_time_ptr")
TimestampColumn = mysql.TimestampColumn("timestamp")
TimestampPtrColumn = mysql.TimestampColumn("timestamp_ptr")
YearColumn = mysql.IntegerColumn("year")
YearPtrColumn = mysql.IntegerColumn("year_ptr")
CharColumn = mysql.StringColumn("char")
CharPtrColumn = mysql.StringColumn("char_ptr")
VarCharColumn = mysql.StringColumn("var_char")
VarCharPtrColumn = mysql.StringColumn("var_char_ptr")
BinaryColumn = mysql.BlobColumn("binary")
BinaryPtrColumn = mysql.BlobColumn("binary_ptr")
VarBinaryColumn = mysql.BlobColumn("var_binary")
VarBinaryPtrColumn = mysql.BlobColumn("var_binary_ptr")
BlobColumn = mysql.BlobColumn("blob")
BlobPtrColumn = mysql.BlobColumn("blob_ptr")
TextColumn = mysql.StringColumn("text")
TextPtrColumn = mysql.StringColumn("text_ptr")
EnumColumn = mysql.StringColumn("enum")
EnumPtrColumn = mysql.StringColumn("enum_ptr")
SetColumn = mysql.StringColumn("set")
SetPtrColumn = mysql.StringColumn("set_ptr")
JSONColumn = mysql.StringColumn("json")
JSONPtrColumn = mysql.StringColumn("json_ptr")
allColumns = mysql.ColumnList{BooleanColumn, BooleanPtrColumn, TinyIntColumn, UTinyIntColumn, SmallIntColumn, USmallIntColumn, MediumIntColumn, UMediumIntColumn, IntegerColumn, UIntegerColumn, BigIntColumn, UBigIntColumn, TinyIntPtrColumn, UTinyIntPtrColumn, SmallIntPtrColumn, USmallIntPtrColumn, MediumIntPtrColumn, UMediumIntPtrColumn, IntegerPtrColumn, UIntegerPtrColumn, BigIntPtrColumn, UBigIntPtrColumn, DecimalColumn, DecimalPtrColumn, NumericColumn, NumericPtrColumn, FloatColumn, FloatPtrColumn, DoubleColumn, DoublePtrColumn, RealColumn, RealPtrColumn, BitColumn, BitPtrColumn, TimeColumn, TimePtrColumn, DateColumn, DatePtrColumn, DateTimeColumn, DateTimePtrColumn, TimestampColumn, TimestampPtrColumn, YearColumn, YearPtrColumn, CharColumn, CharPtrColumn, VarCharColumn, VarCharPtrColumn, BinaryColumn, BinaryPtrColumn, VarBinaryColumn, VarBinaryPtrColumn, BlobColumn, BlobPtrColumn, TextColumn, TextPtrColumn, EnumColumn, EnumPtrColumn, SetColumn, SetPtrColumn, JSONColumn, JSONPtrColumn}
mutableColumns = mysql.ColumnList{BooleanColumn, BooleanPtrColumn, TinyIntColumn, UTinyIntColumn, SmallIntColumn, USmallIntColumn, MediumIntColumn, UMediumIntColumn, IntegerColumn, UIntegerColumn, BigIntColumn, UBigIntColumn, TinyIntPtrColumn, UTinyIntPtrColumn, SmallIntPtrColumn, USmallIntPtrColumn, MediumIntPtrColumn, UMediumIntPtrColumn, IntegerPtrColumn, UIntegerPtrColumn, BigIntPtrColumn, UBigIntPtrColumn, DecimalColumn, DecimalPtrColumn, NumericColumn, NumericPtrColumn, FloatColumn, FloatPtrColumn, DoubleColumn, DoublePtrColumn, RealColumn, RealPtrColumn, BitColumn, BitPtrColumn, TimeColumn, TimePtrColumn, DateColumn, DatePtrColumn, DateTimeColumn, DateTimePtrColumn, TimestampColumn, TimestampPtrColumn, YearColumn, YearPtrColumn, CharColumn, CharPtrColumn, VarCharColumn, VarCharPtrColumn, BinaryColumn, BinaryPtrColumn, VarBinaryColumn, VarBinaryPtrColumn, BlobColumn, BlobPtrColumn, TextColumn, TextPtrColumn, EnumColumn, EnumPtrColumn, SetColumn, SetPtrColumn, JSONColumn, JSONPtrColumn}
defaultColumns = mysql.ColumnList{BooleanColumn, TinyIntColumn, UTinyIntColumn, SmallIntColumn, USmallIntColumn, MediumIntColumn, UMediumIntColumn, IntegerColumn, UIntegerColumn, BigIntColumn, UBigIntColumn, DecimalColumn, NumericColumn, FloatColumn, DoubleColumn, RealColumn, BitColumn, TimeColumn, DateColumn, DateTimeColumn, TimestampColumn, YearColumn, CharColumn, VarCharColumn, BinaryColumn, VarBinaryColumn, EnumColumn, SetColumn}
)
return allTypesTable{
Table: mysql.NewTable(schemaName, tableName, alias, allColumns...),
//Columns
Boolean: BooleanColumn,
BooleanPtr: BooleanPtrColumn,
TinyInt: TinyIntColumn,
UTinyInt: UTinyIntColumn,
SmallInt: SmallIntColumn,
USmallInt: USmallIntColumn,
MediumInt: MediumIntColumn,
UMediumInt: UMediumIntColumn,
Integer: IntegerColumn,
UInteger: UIntegerColumn,
BigInt: BigIntColumn,
UBigInt: UBigIntColumn,
TinyIntPtr: TinyIntPtrColumn,
UTinyIntPtr: UTinyIntPtrColumn,
SmallIntPtr: SmallIntPtrColumn,
USmallIntPtr: USmallIntPtrColumn,
MediumIntPtr: MediumIntPtrColumn,
UMediumIntPtr: UMediumIntPtrColumn,
IntegerPtr: IntegerPtrColumn,
UIntegerPtr: UIntegerPtrColumn,
BigIntPtr: BigIntPtrColumn,
UBigIntPtr: UBigIntPtrColumn,
Decimal: DecimalColumn,
DecimalPtr: DecimalPtrColumn,
Numeric: NumericColumn,
NumericPtr: NumericPtrColumn,
Float: FloatColumn,
FloatPtr: FloatPtrColumn,
Double: DoubleColumn,
DoublePtr: DoublePtrColumn,
Real: RealColumn,
RealPtr: RealPtrColumn,
Bit: BitColumn,
BitPtr: BitPtrColumn,
Time: TimeColumn,
TimePtr: TimePtrColumn,
Date: DateColumn,
DatePtr: DatePtrColumn,
DateTime: DateTimeColumn,
DateTimePtr: DateTimePtrColumn,
Timestamp: TimestampColumn,
TimestampPtr: TimestampPtrColumn,
Year: YearColumn,
YearPtr: YearPtrColumn,
Char: CharColumn,
CharPtr: CharPtrColumn,
VarChar: VarCharColumn,
VarCharPtr: VarCharPtrColumn,
Binary: BinaryColumn,
BinaryPtr: BinaryPtrColumn,
VarBinary: VarBinaryColumn,
VarBinaryPtr: VarBinaryPtrColumn,
Blob: BlobColumn,
BlobPtr: BlobPtrColumn,
Text: TextColumn,
TextPtr: TextPtrColumn,
Enum: EnumColumn,
EnumPtr: EnumPtrColumn,
Set: SetColumn,
SetPtr: SetPtrColumn,
JSON: JSONColumn,
JSONPtr: JSONPtrColumn,
AllColumns: allColumns,
MutableColumns: mutableColumns,
DefaultColumns: defaultColumns,
}
}
`

View file

@ -8,6 +8,7 @@ import (
jetmysql "github.com/go-jet/jet/v2/mysql"
"github.com/go-jet/jet/v2/stmtcache"
"github.com/go-jet/jet/v2/tests/dbconfig"
"github.com/go-jet/jet/v2/tests/internal/utils/repo"
_ "github.com/go-sql-driver/mysql"
"github.com/stretchr/testify/require"
"runtime"
@ -21,12 +22,14 @@ var db *stmtcache.DB
var source string
var withStatementCaching bool
var testRoot string
const MariaDB = "MariaDB"
func init() {
source = os.Getenv("MY_SQL_SOURCE")
withStatementCaching = os.Getenv("JET_TESTS_WITH_STMT_CACHE") == "true"
testRoot = repo.GetTestsDirPath()
}
func sourceIsMariaDB() bool {