diff --git a/cmd/jet/main.go b/cmd/jet/main.go index e3335cf..5c43218 100644 --- a/cmd/jet/main.go +++ b/cmd/jet/main.go @@ -82,7 +82,8 @@ Usage: var err error switch strings.ToLower(strings.TrimSpace(source)) { - case strings.ToLower(postgres.Dialect.Name()): + case strings.ToLower(postgres.Dialect.Name()), + strings.ToLower(postgres.Dialect.PackageName()): genData := postgresgen.DBConnection{ Host: host, Port: port, @@ -104,7 +105,6 @@ Usage: Port: port, User: user, Password: password, - SslMode: sslmode, Params: params, DBName: dbName, } diff --git a/generator/internal/metadata/column_meta_data.go b/generator/internal/metadata/column_meta_data.go index 7bc169e..c1fdd10 100644 --- a/generator/internal/metadata/column_meta_data.go +++ b/generator/internal/metadata/column_meta_data.go @@ -20,6 +20,7 @@ type ColumnMetaData struct { GoModelType string } +// NewColumnMetaData create new column meta data that describes one column in SQL database func NewColumnMetaData(name string, isNullable bool, dataType string, enumName string, isUnsigned bool) ColumnMetaData { columnMetaData := ColumnMetaData{ Name: name, diff --git a/generator/internal/metadata/dialect_query_set.go b/generator/internal/metadata/dialect_query_set.go index 057be3e..6cc9834 100644 --- a/generator/internal/metadata/dialect_query_set.go +++ b/generator/internal/metadata/dialect_query_set.go @@ -2,9 +2,9 @@ package metadata import ( "database/sql" - "strings" ) +// DialectQuerySet is set of methods necessary to retrieve dialect meta data information type DialectQuerySet interface { ListOfTablesQuery() string PrimaryKeysQuery() string @@ -13,128 +13,3 @@ type DialectQuerySet interface { GetEnumsMetaData(db *sql.DB, schemaName string) ([]MetaData, error) } - -type PostgresQuerySet struct{} - -func (p *PostgresQuerySet) ListOfTablesQuery() string { - return ` -SELECT table_name -FROM information_schema.tables -where table_schema = $1 and table_type = 'BASE TABLE'; -` -} - -func (p *PostgresQuerySet) PrimaryKeysQuery() string { - return ` -SELECT c.column_name -FROM information_schema.key_column_usage AS c -LEFT JOIN information_schema.table_constraints AS t -ON t.constraint_name = c.constraint_name -WHERE t.table_schema = $1 AND t.table_name = $2 AND t.constraint_type = 'PRIMARY KEY'; -` -} - -func (p *PostgresQuerySet) ListOfColumnsQuery() string { - return ` -SELECT column_name, is_nullable, data_type, udt_name, FALSE -FROM information_schema.columns -where table_schema = $1 and table_name = $2 -order by ordinal_position;` -} - -func (p *PostgresQuerySet) ListOfEnumsQuery() string { - return ` -SELECT t.typname, - e.enumlabel -FROM pg_catalog.pg_type t - JOIN pg_catalog.pg_enum e on t.oid = e.enumtypid - JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace -WHERE n.nspname = $1 -ORDER BY n.nspname, t.typname, e.enumsortorder;` -} - -func (p *PostgresQuerySet) GetEnumsMetaData(db *sql.DB, schemaName string) ([]MetaData, error) { - return getEnumInfos(db, p, schemaName) -} - -// =======================================================================// - -type MySqlQuerySet struct{} - -func (m *MySqlQuerySet) ListOfTablesQuery() string { - return ` -SELECT table_name -FROM INFORMATION_SCHEMA.tables -WHERE table_schema = ? and table_type = 'BASE TABLE'; -` -} - -func (m *MySqlQuerySet) PrimaryKeysQuery() string { - return ` -SELECT k.column_name -FROM information_schema.table_constraints t -JOIN information_schema.key_column_usage k -USING(constraint_name,table_schema,table_name) -WHERE t.constraint_type='PRIMARY KEY' - AND t.table_schema= ? - AND t.table_name= ?; -` -} - -func (m *MySqlQuerySet) ListOfColumnsQuery() string { - return ` -SELECT COLUMN_NAME, - IS_NULLABLE, IF(COLUMN_TYPE = 'tinyint(1)', 'boolean', DATA_TYPE), - IF(DATA_TYPE = 'enum', CONCAT(TABLE_NAME, '_', COLUMN_NAME), ''), - COLUMN_TYPE LIKE '%unsigned%' -FROM information_schema.columns -WHERE table_schema = ? and table_name = ? -ORDER BY ordinal_position; -` -} - -func (m *MySqlQuerySet) ListOfEnumsQuery() string { - return ` -SELECT (CASE c.DATA_TYPE WHEN 'enum' then CONCAT(c.TABLE_NAME, '_', c.COLUMN_NAME) ELSE '' END ), SUBSTRING(c.COLUMN_TYPE,5) -FROM information_schema.columns as c - INNER JOIN information_schema.tables as t on (t.table_schema = c.table_schema AND t.table_name = c.table_name) -WHERE c.table_schema = ? AND DATA_TYPE = 'enum' AND t.TABLE_TYPE = 'BASE TABLE'; -` -} - -func (m *MySqlQuerySet) GetEnumsMetaData(db *sql.DB, schemaName string) ([]MetaData, error) { - - rows, err := db.Query(m.ListOfEnumsQuery(), schemaName) - - if err != nil { - return nil, err - } - defer rows.Close() - - ret := []MetaData{} - - for rows.Next() { - var enumName string - var enumValues string - err = rows.Scan(&enumName, &enumValues) - if err != nil { - return nil, err - } - - enumValues = strings.Replace(enumValues[1:len(enumValues)-1], "'", "", -1) - - ret = append(ret, EnumMetaData{ - name: enumName, - Values: strings.Split(enumValues, ","), - }) - } - - err = rows.Err() - - if err != nil { - return nil, err - } - - return ret, nil - -} diff --git a/generator/internal/metadata/enum_meta_data.go b/generator/internal/metadata/enum_meta_data.go index 806325f..8479c60 100644 --- a/generator/internal/metadata/enum_meta_data.go +++ b/generator/internal/metadata/enum_meta_data.go @@ -1,59 +1,12 @@ package metadata -import ( - "database/sql" -) - // EnumMetaData struct type EnumMetaData struct { - name string - Values []string + EnumName string + Values []string } // Name returns enum name func (e EnumMetaData) Name() string { - return e.name -} - -func getEnumInfos(db *sql.DB, querySet DialectQuerySet, schemaName string) ([]MetaData, error) { - - rows, err := db.Query(querySet.ListOfEnumsQuery(), schemaName) - - if err != nil { - return nil, err - } - defer rows.Close() - - enumsInfosMap := map[string][]string{} - for rows.Next() { - var enumName string - var enumValue string - err = rows.Scan(&enumName, &enumValue) - if err != nil { - return nil, err - } - - enumValues := enumsInfosMap[enumName] - - enumValues = append(enumValues, enumValue) - - enumsInfosMap[enumName] = enumValues - } - - err = rows.Err() - - if err != nil { - return nil, err - } - - ret := []MetaData{} - - for enumName, enumValues := range enumsInfosMap { - ret = append(ret, EnumMetaData{ - enumName, - enumValues, - }) - } - - return ret, nil + return e.EnumName } diff --git a/generator/internal/template/generate.go b/generator/internal/template/generate.go index bc853fe..a16c133 100644 --- a/generator/internal/template/generate.go +++ b/generator/internal/template/generate.go @@ -11,6 +11,7 @@ import ( "time" ) +// GenerateFiles generates Go files from tables and enums metadata func GenerateFiles(destDir string, tables, enums []metadata.MetaData, dialect jet.Dialect) error { if len(tables) == 0 && len(enums) == 0 { return nil diff --git a/generator/mysql/mysql_generator.go b/generator/mysql/mysql_generator.go index a893e3c..c8b01ee 100644 --- a/generator/mysql/mysql_generator.go +++ b/generator/mysql/mysql_generator.go @@ -10,12 +10,12 @@ import ( "path" ) +// DBConnection contains MySQL connection details type DBConnection struct { Host string Port int User string Password string - SslMode string Params string DBName string @@ -31,7 +31,7 @@ func Generate(destDir string, dbConn DBConnection) error { fmt.Println("Retrieving database information...") // No schemas in MySQL - dbInfo, err := metadata.GetSchemaInfo(db, dbConn.DBName, &metadata.MySqlQuerySet{}) + dbInfo, err := metadata.GetSchemaInfo(db, dbConn.DBName, &mySqlQuerySet{}) if err != nil { return err diff --git a/generator/mysql/query_set.go b/generator/mysql/query_set.go new file mode 100644 index 0000000..20a01ac --- /dev/null +++ b/generator/mysql/query_set.go @@ -0,0 +1,88 @@ +package mysql + +import ( + "database/sql" + "github.com/go-jet/jet/generator/internal/metadata" + "strings" +) + +// mySqlQuerySet is dialect query set for MySQL +type mySqlQuerySet struct{} + +func (m *mySqlQuerySet) ListOfTablesQuery() string { + return ` +SELECT table_name +FROM INFORMATION_SCHEMA.tables +WHERE table_schema = ? and table_type = 'BASE TABLE'; +` +} + +func (m *mySqlQuerySet) PrimaryKeysQuery() string { + return ` +SELECT k.column_name +FROM information_schema.table_constraints t +JOIN information_schema.key_column_usage k +USING(constraint_name,table_schema,table_name) +WHERE t.constraint_type='PRIMARY KEY' + AND t.table_schema= ? + AND t.table_name= ?; +` +} + +func (m *mySqlQuerySet) ListOfColumnsQuery() string { + return ` +SELECT COLUMN_NAME, + IS_NULLABLE, IF(COLUMN_TYPE = 'tinyint(1)', 'boolean', DATA_TYPE), + IF(DATA_TYPE = 'enum', CONCAT(TABLE_NAME, '_', COLUMN_NAME), ''), + COLUMN_TYPE LIKE '%unsigned%' +FROM information_schema.columns +WHERE table_schema = ? and table_name = ? +ORDER BY ordinal_position; +` +} + +func (m *mySqlQuerySet) ListOfEnumsQuery() string { + return ` +SELECT (CASE c.DATA_TYPE WHEN 'enum' then CONCAT(c.TABLE_NAME, '_', c.COLUMN_NAME) ELSE '' END ), SUBSTRING(c.COLUMN_TYPE,5) +FROM information_schema.columns as c + INNER JOIN information_schema.tables as t on (t.table_schema = c.table_schema AND t.table_name = c.table_name) +WHERE c.table_schema = ? AND DATA_TYPE = 'enum' AND t.TABLE_TYPE = 'BASE TABLE'; +` +} + +func (m *mySqlQuerySet) GetEnumsMetaData(db *sql.DB, schemaName string) ([]metadata.MetaData, error) { + + rows, err := db.Query(m.ListOfEnumsQuery(), schemaName) + + if err != nil { + return nil, err + } + defer rows.Close() + + ret := []metadata.MetaData{} + + for rows.Next() { + var enumName string + var enumValues string + err = rows.Scan(&enumName, &enumValues) + if err != nil { + return nil, err + } + + enumValues = strings.Replace(enumValues[1:len(enumValues)-1], "'", "", -1) + + ret = append(ret, metadata.EnumMetaData{ + EnumName: enumName, + Values: strings.Split(enumValues, ","), + }) + } + + err = rows.Err() + + if err != nil { + return nil, err + } + + return ret, nil + +} diff --git a/generator/postgres/postgres_generator.go b/generator/postgres/postgres_generator.go index c6d5173..ce2ea34 100644 --- a/generator/postgres/postgres_generator.go +++ b/generator/postgres/postgres_generator.go @@ -35,7 +35,7 @@ func Generate(destDir string, dbConn DBConnection) error { } fmt.Println("Retrieving schema information...") - schemaInfo, err := metadata.GetSchemaInfo(db, dbConn.SchemaName, &metadata.PostgresQuerySet{}) + schemaInfo, err := metadata.GetSchemaInfo(db, dbConn.SchemaName, &postgresQuerySet{}) if err != nil { return err diff --git a/generator/postgres/query_set.go b/generator/postgres/query_set.go new file mode 100644 index 0000000..a4f1fdd --- /dev/null +++ b/generator/postgres/query_set.go @@ -0,0 +1,88 @@ +package postgres + +import ( + "database/sql" + "github.com/go-jet/jet/generator/internal/metadata" +) + +// postgresQuerySet is dialect query set for PostgreSQL +type postgresQuerySet struct{} + +func (p *postgresQuerySet) ListOfTablesQuery() string { + return ` +SELECT table_name +FROM information_schema.tables +where table_schema = $1 and table_type = 'BASE TABLE'; +` +} + +func (p *postgresQuerySet) PrimaryKeysQuery() string { + return ` +SELECT c.column_name +FROM information_schema.key_column_usage AS c +LEFT JOIN information_schema.table_constraints AS t +ON t.constraint_name = c.constraint_name +WHERE t.table_schema = $1 AND t.table_name = $2 AND t.constraint_type = 'PRIMARY KEY'; +` +} + +func (p *postgresQuerySet) ListOfColumnsQuery() string { + return ` +SELECT column_name, is_nullable, data_type, udt_name, FALSE +FROM information_schema.columns +where table_schema = $1 and table_name = $2 +order by ordinal_position;` +} + +func (p *postgresQuerySet) ListOfEnumsQuery() string { + return ` +SELECT t.typname, + e.enumlabel +FROM pg_catalog.pg_type t + JOIN pg_catalog.pg_enum e on t.oid = e.enumtypid + JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace +WHERE n.nspname = $1 +ORDER BY n.nspname, t.typname, e.enumsortorder;` +} + +func (p *postgresQuerySet) GetEnumsMetaData(db *sql.DB, schemaName string) ([]metadata.MetaData, error) { + rows, err := db.Query(p.ListOfEnumsQuery(), schemaName) + + if err != nil { + return nil, err + } + defer rows.Close() + + enumsInfosMap := map[string][]string{} + for rows.Next() { + var enumName string + var enumValue string + err = rows.Scan(&enumName, &enumValue) + if err != nil { + return nil, err + } + + enumValues := enumsInfosMap[enumName] + + enumValues = append(enumValues, enumValue) + + enumsInfosMap[enumName] = enumValues + } + + err = rows.Err() + + if err != nil { + return nil, err + } + + ret := []metadata.MetaData{} + + for enumName, enumValues := range enumsInfosMap { + ret = append(ret, metadata.EnumMetaData{ + EnumName: enumName, + Values: enumValues, + }) + } + + return ret, nil +} diff --git a/internal/jet/alias.go b/internal/jet/alias.go index d9b33d7..a2b1ae3 100644 --- a/internal/jet/alias.go +++ b/internal/jet/alias.go @@ -20,7 +20,7 @@ func (a *alias) fromImpl(subQuery SelectTable) Projection { return &column } -func (a *alias) serializeForProjection(statement StatementType, out *SqlBuilder) { +func (a *alias) serializeForProjection(statement StatementType, out *SQLBuilder) { a.expression.serialize(statement, out) out.WriteString("AS") diff --git a/internal/jet/bool_expression.go b/internal/jet/bool_expression.go index 466f624..5bdda95 100644 --- a/internal/jet/bool_expression.go +++ b/internal/jet/bool_expression.go @@ -86,7 +86,7 @@ func (b *boolInterfaceImpl) IS_NOT_UNKNOWN() BoolExpression { //---------------------------------------------------// type binaryBoolExpression struct { - ExpressionInterfaceImpl + expressionInterfaceImpl boolInterfaceImpl binaryOpExpression @@ -96,7 +96,7 @@ func newBinaryBoolOperator(lhs, rhs Expression, operator string, additionalParam binaryBoolExpression := binaryBoolExpression{} binaryBoolExpression.binaryOpExpression = newBinaryExpression(lhs, rhs, operator, additionalParams...) - binaryBoolExpression.ExpressionInterfaceImpl.Parent = &binaryBoolExpression + binaryBoolExpression.expressionInterfaceImpl.Parent = &binaryBoolExpression binaryBoolExpression.boolInterfaceImpl.parent = &binaryBoolExpression return &binaryBoolExpression @@ -104,7 +104,7 @@ func newBinaryBoolOperator(lhs, rhs Expression, operator string, additionalParam //---------------------------------------------------// type prefixBoolExpression struct { - ExpressionInterfaceImpl + expressionInterfaceImpl boolInterfaceImpl prefixOpExpression @@ -114,7 +114,7 @@ func newPrefixBoolOperator(expression Expression, operator string) BoolExpressio exp := prefixBoolExpression{} exp.prefixOpExpression = newPrefixExpression(expression, operator) - exp.ExpressionInterfaceImpl.Parent = &exp + exp.expressionInterfaceImpl.Parent = &exp exp.boolInterfaceImpl.parent = &exp return &exp @@ -122,7 +122,7 @@ func newPrefixBoolOperator(expression Expression, operator string) BoolExpressio //---------------------------------------------------// type postfixBoolOpExpression struct { - ExpressionInterfaceImpl + expressionInterfaceImpl boolInterfaceImpl postfixOpExpression @@ -132,7 +132,7 @@ func newPostifxBoolExpression(expression Expression, operator string) BoolExpres exp := postfixBoolOpExpression{} exp.postfixOpExpression = newPostfixOpExpression(expression, operator) - exp.ExpressionInterfaceImpl.Parent = &exp + exp.expressionInterfaceImpl.Parent = &exp exp.boolInterfaceImpl.parent = &exp return &exp diff --git a/internal/jet/cast.go b/internal/jet/cast.go index bd0eb7c..84e1962 100644 --- a/internal/jet/cast.go +++ b/internal/jet/cast.go @@ -1,40 +1,42 @@ package jet +// Cast interface type Cast interface { AS(castType string) Expression } -type CastImpl struct { +type castImpl struct { expression Expression } +// NewCastImpl creates new generic cast func NewCastImpl(expression Expression) Cast { - castImpl := CastImpl{ + castImpl := castImpl{ expression: expression, } return &castImpl } -func (b *CastImpl) AS(castType string) Expression { +func (b *castImpl) AS(castType string) Expression { castExp := &castExpression{ expression: b.expression, cast: string(castType), } - castExp.ExpressionInterfaceImpl.Parent = castExp + castExp.expressionInterfaceImpl.Parent = castExp return castExp } type castExpression struct { - ExpressionInterfaceImpl + expressionInterfaceImpl expression Expression cast string } -func (b *castExpression) serialize(statement StatementType, out *SqlBuilder, options ...SerializeOption) { +func (b *castExpression) serialize(statement StatementType, out *SQLBuilder, options ...SerializeOption) { expression := b.expression castType := b.cast diff --git a/internal/jet/clause.go b/internal/jet/clause.go index cae71d3..5a3f1e9 100644 --- a/internal/jet/clause.go +++ b/internal/jet/clause.go @@ -4,16 +4,19 @@ import ( "github.com/go-jet/jet/internal/utils" ) +// Clause interface type Clause interface { - Serialize(statementType StatementType, out *SqlBuilder) + Serialize(statementType StatementType, out *SQLBuilder) } +// ClauseWithProjections interface type ClauseWithProjections interface { Clause projections() ProjectionList } +// ClauseSelect struct type ClauseSelect struct { Distinct bool Projections []Projection @@ -23,7 +26,8 @@ func (s *ClauseSelect) projections() ProjectionList { return s.Projections } -func (s *ClauseSelect) Serialize(statementType StatementType, out *SqlBuilder) { +// Serialize serializes clause into SQLBuilder +func (s *ClauseSelect) Serialize(statementType StatementType, out *SQLBuilder) { out.NewLine() out.WriteString("SELECT") @@ -38,11 +42,13 @@ func (s *ClauseSelect) Serialize(statementType StatementType, out *SqlBuilder) { out.WriteProjections(statementType, s.Projections) } +// ClauseFrom struct type ClauseFrom struct { Table Serializer } -func (f *ClauseFrom) Serialize(statementType StatementType, out *SqlBuilder) { +// Serialize serializes clause into SQLBuilder +func (f *ClauseFrom) Serialize(statementType StatementType, out *SQLBuilder) { if f.Table == nil { return } @@ -54,12 +60,14 @@ func (f *ClauseFrom) Serialize(statementType StatementType, out *SqlBuilder) { out.DecreaseIdent() } +// ClauseWhere struct type ClauseWhere struct { Condition BoolExpression Mandatory bool } -func (c *ClauseWhere) Serialize(statementType StatementType, out *SqlBuilder) { +// Serialize serializes clause into SQLBuilder +func (c *ClauseWhere) Serialize(statementType StatementType, out *SQLBuilder) { if c.Condition == nil { if c.Mandatory { panic("jet: WHERE clause not set") @@ -74,11 +82,13 @@ func (c *ClauseWhere) Serialize(statementType StatementType, out *SqlBuilder) { out.DecreaseIdent() } +// ClauseGroupBy struct type ClauseGroupBy struct { List []GroupByClause } -func (c *ClauseGroupBy) Serialize(statementType StatementType, out *SqlBuilder) { +// Serialize serializes clause into SQLBuilder +func (c *ClauseGroupBy) Serialize(statementType StatementType, out *SQLBuilder) { if len(c.List) == 0 { return } @@ -87,15 +97,29 @@ func (c *ClauseGroupBy) Serialize(statementType StatementType, out *SqlBuilder) out.WriteString("GROUP BY") out.IncreaseIdent() - serializeGroupByClauseList(statementType, c.List, out) + + for i, c := range c.List { + if i > 0 { + out.WriteString(", ") + } + + if c == nil { + panic("jet: nil clause in GROUP BY list") + } + + c.serializeForGroupBy(statementType, out) + } + out.DecreaseIdent() } +// ClauseHaving struct type ClauseHaving struct { Condition BoolExpression } -func (c *ClauseHaving) Serialize(statementType StatementType, out *SqlBuilder) { +// Serialize serializes clause into SQLBuilder +func (c *ClauseHaving) Serialize(statementType StatementType, out *SQLBuilder) { if c.Condition == nil { return } @@ -108,11 +132,13 @@ func (c *ClauseHaving) Serialize(statementType StatementType, out *SqlBuilder) { out.DecreaseIdent() } +// ClauseOrderBy struct type ClauseOrderBy struct { List []OrderByClause } -func (o *ClauseOrderBy) Serialize(statementType StatementType, out *SqlBuilder) { +// Serialize serializes clause into SQLBuilder +func (o *ClauseOrderBy) Serialize(statementType StatementType, out *SQLBuilder) { if o.List == nil { return } @@ -121,15 +147,25 @@ func (o *ClauseOrderBy) Serialize(statementType StatementType, out *SqlBuilder) out.WriteString("ORDER BY") out.IncreaseIdent() - serializeOrderByClauseList(statementType, o.List, out) + + for i, value := range o.List { + if i > 0 { + out.WriteString(", ") + } + + value.serializeForOrderBy(statementType, out) + } + out.DecreaseIdent() } +// ClauseLimit struct type ClauseLimit struct { Count int64 } -func (l *ClauseLimit) Serialize(statementType StatementType, out *SqlBuilder) { +// Serialize serializes clause into SQLBuilder +func (l *ClauseLimit) Serialize(statementType StatementType, out *SQLBuilder) { if l.Count >= 0 { out.NewLine() out.WriteString("LIMIT") @@ -137,11 +173,13 @@ func (l *ClauseLimit) Serialize(statementType StatementType, out *SqlBuilder) { } } +// ClauseOffset struct type ClauseOffset struct { Count int64 } -func (o *ClauseOffset) Serialize(statementType StatementType, out *SqlBuilder) { +// Serialize serializes clause into SQLBuilder +func (o *ClauseOffset) Serialize(statementType StatementType, out *SQLBuilder) { if o.Count >= 0 { out.NewLine() out.WriteString("OFFSET") @@ -149,11 +187,13 @@ func (o *ClauseOffset) Serialize(statementType StatementType, out *SqlBuilder) { } } +// ClauseFor struct type ClauseFor struct { Lock RowLock } -func (f *ClauseFor) Serialize(statementType StatementType, out *SqlBuilder) { +// Serialize serializes clause into SQLBuilder +func (f *ClauseFor) Serialize(statementType StatementType, out *SQLBuilder) { if f.Lock == nil { return } @@ -163,6 +203,7 @@ func (f *ClauseFor) Serialize(statementType StatementType, out *SqlBuilder) { f.Lock.serialize(statementType, out) } +// ClauseSetStmtOperator struct type ClauseSetStmtOperator struct { Operator string All bool @@ -179,7 +220,8 @@ func (s *ClauseSetStmtOperator) projections() ProjectionList { return nil } -func (s *ClauseSetStmtOperator) Serialize(statementType StatementType, out *SqlBuilder) { +// Serialize serializes clause into SQLBuilder +func (s *ClauseSetStmtOperator) Serialize(statementType StatementType, out *SQLBuilder) { if len(s.Selects) < 2 { panic("jet: UNION Statement must contain at least two SELECT statements") } @@ -207,11 +249,13 @@ func (s *ClauseSetStmtOperator) Serialize(statementType StatementType, out *SqlB s.Offset.Serialize(statementType, out) } +// ClauseUpdate struct type ClauseUpdate struct { Table SerializerTable } -func (u *ClauseUpdate) Serialize(statementType StatementType, out *SqlBuilder) { +// Serialize serializes clause into SQLBuilder +func (u *ClauseUpdate) Serialize(statementType StatementType, out *SQLBuilder) { out.NewLine() out.WriteString("UPDATE") @@ -222,12 +266,14 @@ func (u *ClauseUpdate) Serialize(statementType StatementType, out *SqlBuilder) { u.Table.serialize(statementType, out) } +// ClauseSet struct type ClauseSet struct { Columns []Column Values []Serializer } -func (s *ClauseSet) Serialize(statementType StatementType, out *SqlBuilder) { +// Serialize serializes clause into SQLBuilder +func (s *ClauseSet) Serialize(statementType StatementType, out *SQLBuilder) { out.NewLine() out.WriteString("SET") @@ -255,11 +301,13 @@ func (s *ClauseSet) Serialize(statementType StatementType, out *SqlBuilder) { out.DecreaseIdent(4) } +// ClauseInsert struct type ClauseInsert struct { Table SerializerTable Columns []Column } +// GetColumns gets list of columns for insert func (i *ClauseInsert) GetColumns() []Column { if len(i.Columns) > 0 { return i.Columns @@ -268,7 +316,8 @@ func (i *ClauseInsert) GetColumns() []Column { return i.Table.columns() } -func (i *ClauseInsert) Serialize(statementType StatementType, out *SqlBuilder) { +// Serialize serializes clause into SQLBuilder +func (i *ClauseInsert) Serialize(statementType StatementType, out *SQLBuilder) { out.NewLine() out.WriteString("INSERT INTO") @@ -287,12 +336,14 @@ func (i *ClauseInsert) Serialize(statementType StatementType, out *SqlBuilder) { } } +// ClauseValuesQuery struct type ClauseValuesQuery struct { ClauseValues ClauseQuery } -func (v *ClauseValuesQuery) Serialize(statementType StatementType, out *SqlBuilder) { +// Serialize serializes clause into SQLBuilder +func (v *ClauseValuesQuery) Serialize(statementType StatementType, out *SQLBuilder) { if len(v.Rows) == 0 && v.Query == nil { panic("jet: VALUES or QUERY has to be specified for INSERT statement") } @@ -305,11 +356,13 @@ func (v *ClauseValuesQuery) Serialize(statementType StatementType, out *SqlBuild v.ClauseQuery.Serialize(statementType, out) } +// ClauseValues struct type ClauseValues struct { Rows [][]Serializer } -func (v *ClauseValues) Serialize(statementType StatementType, out *SqlBuilder) { +// Serialize serializes clause into SQLBuilder +func (v *ClauseValues) Serialize(statementType StatementType, out *SQLBuilder) { if len(v.Rows) == 0 { return } @@ -332,11 +385,13 @@ func (v *ClauseValues) Serialize(statementType StatementType, out *SqlBuilder) { } } +// ClauseQuery struct type ClauseQuery struct { Query SerializerStatement } -func (v *ClauseQuery) Serialize(statementType StatementType, out *SqlBuilder) { +// Serialize serializes clause into SQLBuilder +func (v *ClauseQuery) Serialize(statementType StatementType, out *SQLBuilder) { if v.Query == nil { return } @@ -344,11 +399,13 @@ func (v *ClauseQuery) Serialize(statementType StatementType, out *SqlBuilder) { v.Query.serialize(statementType, out) } +// ClauseDelete struct type ClauseDelete struct { Table SerializerTable } -func (d *ClauseDelete) Serialize(statementType StatementType, out *SqlBuilder) { +// Serialize serializes clause into SQLBuilder +func (d *ClauseDelete) Serialize(statementType StatementType, out *SQLBuilder) { out.NewLine() out.WriteString("DELETE FROM") @@ -359,12 +416,14 @@ func (d *ClauseDelete) Serialize(statementType StatementType, out *SqlBuilder) { d.Table.serialize(statementType, out) } +// ClauseStatementBegin struct type ClauseStatementBegin struct { Name string Tables []SerializerTable } -func (d *ClauseStatementBegin) Serialize(statementType StatementType, out *SqlBuilder) { +// Serialize serializes clause into SQLBuilder +func (d *ClauseStatementBegin) Serialize(statementType StatementType, out *SQLBuilder) { out.NewLine() out.WriteString(d.Name) @@ -377,13 +436,15 @@ func (d *ClauseStatementBegin) Serialize(statementType StatementType, out *SqlBu } } +// ClauseOptional struct type ClauseOptional struct { Name string Show bool InNewLine bool } -func (d *ClauseOptional) Serialize(statementType StatementType, out *SqlBuilder) { +// Serialize serializes clause into SQLBuilder +func (d *ClauseOptional) Serialize(statementType StatementType, out *SQLBuilder) { if !d.Show { return } @@ -393,11 +454,13 @@ func (d *ClauseOptional) Serialize(statementType StatementType, out *SqlBuilder) out.WriteString(d.Name) } +// ClauseIn struct type ClauseIn struct { LockMode string } -func (i *ClauseIn) Serialize(statementType StatementType, out *SqlBuilder) { +// Serialize serializes clause into SQLBuilder +func (i *ClauseIn) Serialize(statementType StatementType, out *SQLBuilder) { if i.LockMode == "" { return } diff --git a/internal/jet/clause_test.go b/internal/jet/clause_test.go index 6722c10..14ced64 100644 --- a/internal/jet/clause_test.go +++ b/internal/jet/clause_test.go @@ -12,5 +12,5 @@ func TestClauseSelect_Serialize(t *testing.T) { }() selectClause := &ClauseSelect{} - selectClause.Serialize(SelectStatementType, &SqlBuilder{}) + selectClause.Serialize(SelectStatementType, &SQLBuilder{}) } diff --git a/internal/jet/column.go b/internal/jet/column.go index 8707247..6505bf4 100644 --- a/internal/jet/column.go +++ b/internal/jet/column.go @@ -12,6 +12,7 @@ type Column interface { defaultAlias() string } +// ColumnExpression interface type ColumnExpression interface { Column Expression @@ -19,7 +20,7 @@ type ColumnExpression interface { // The base type for real materialized columns. type columnImpl struct { - ExpressionInterfaceImpl + expressionInterfaceImpl name string tableName string @@ -33,7 +34,7 @@ func newColumn(name string, tableName string, parent ColumnExpression) columnImp tableName: tableName, } - bc.ExpressionInterfaceImpl.Parent = parent + bc.expressionInterfaceImpl.Parent = parent return bc } @@ -62,7 +63,7 @@ func (c *columnImpl) defaultAlias() string { return c.name } -func (c *columnImpl) serializeForOrderBy(statement StatementType, out *SqlBuilder) { +func (c *columnImpl) serializeForOrderBy(statement StatementType, out *SQLBuilder) { if statement == SetStatementType { // set Statement (UNION, EXCEPT ...) can reference only select projections in order by clause out.WriteAlias(c.defaultAlias()) //always quote @@ -73,14 +74,14 @@ func (c *columnImpl) serializeForOrderBy(statement StatementType, out *SqlBuilde c.serialize(statement, out) } -func (c columnImpl) serializeForProjection(statement StatementType, out *SqlBuilder) { +func (c columnImpl) serializeForProjection(statement StatementType, out *SQLBuilder) { c.serialize(statement, out) out.WriteString("AS") out.WriteAlias(c.defaultAlias()) } -func (c columnImpl) serialize(statement StatementType, out *SqlBuilder, options ...SerializeOption) { +func (c columnImpl) serialize(statement StatementType, out *SQLBuilder, options ...SerializeOption) { if c.subQuery != nil { out.WriteIdentifier(c.subQuery.Alias()) @@ -129,7 +130,7 @@ func (cl columnListImpl) fromImpl(subQuery SelectTable) Projection { return newProjectionList } -func (cl columnListImpl) serializeForProjection(statement StatementType, out *SqlBuilder) { +func (cl columnListImpl) serializeForProjection(statement StatementType, out *SQLBuilder) { projections := ColumnListToProjectionList(cl) SerializeProjectionList(statement, projections, out) diff --git a/internal/jet/column_test.go b/internal/jet/column_test.go index ca3f5f6..2159c68 100644 --- a/internal/jet/column_test.go +++ b/internal/jet/column_test.go @@ -4,7 +4,7 @@ import "testing" func TestColumn(t *testing.T) { column := newColumn("col", "", nil) - column.ExpressionInterfaceImpl.Parent = &column + column.expressionInterfaceImpl.Parent = &column assertClauseSerialize(t, column, "col") column.setTableName("table1") diff --git a/internal/jet/column_types_test.go b/internal/jet/column_types_test.go index 0c154ec..8c00d5b 100644 --- a/internal/jet/column_types_test.go +++ b/internal/jet/column_types_test.go @@ -4,7 +4,7 @@ import ( "testing" ) -var subQuery = &SelectTableImpl{ +var subQuery = &selectTableImpl{ alias: "sub_query", } diff --git a/internal/jet/dialect.go b/internal/jet/dialect.go index a0a9d37..e46000a 100644 --- a/internal/jet/dialect.go +++ b/internal/jet/dialect.go @@ -1,5 +1,6 @@ package jet +// Dialect interface type Dialect interface { Name() string PackageName() string @@ -10,10 +11,16 @@ type Dialect interface { ArgumentPlaceholder() QueryPlaceholderFunc } -type SerializeFunc func(statement StatementType, out *SqlBuilder, options ...SerializeOption) +// SerializeFunc func +type SerializeFunc func(statement StatementType, out *SQLBuilder, options ...SerializeOption) + +// SerializeOverride func type SerializeOverride func(expressions ...Expression) SerializeFunc + +// QueryPlaceholderFunc func type QueryPlaceholderFunc func(ord int) string +// DialectParams struct type DialectParams struct { Name string PackageName string @@ -24,6 +31,7 @@ type DialectParams struct { ArgumentPlaceholder QueryPlaceholderFunc } +// NewDialect creates new dialect with params func NewDialect(params DialectParams) Dialect { return &dialectImpl{ name: params.Name, diff --git a/internal/jet/enum_value.go b/internal/jet/enum_value.go index c1b2067..5bd609d 100644 --- a/internal/jet/enum_value.go +++ b/internal/jet/enum_value.go @@ -1,7 +1,7 @@ package jet type enumValue struct { - ExpressionInterfaceImpl + expressionInterfaceImpl stringInterfaceImpl name string @@ -11,12 +11,12 @@ type enumValue struct { func NewEnumValue(name string) StringExpression { enumValue := &enumValue{name: name} - enumValue.ExpressionInterfaceImpl.Parent = enumValue + enumValue.expressionInterfaceImpl.Parent = enumValue enumValue.stringInterfaceImpl.parent = enumValue return enumValue } -func (e enumValue) serialize(statement StatementType, out *SqlBuilder, options ...SerializeOption) { +func (e enumValue) serialize(statement StatementType, out *SQLBuilder, options ...SerializeOption) { out.insertConstantArgument(e.name) } diff --git a/internal/jet/expression.go b/internal/jet/expression.go index f303fee..4ded89f 100644 --- a/internal/jet/expression.go +++ b/internal/jet/expression.go @@ -27,51 +27,51 @@ type Expression interface { DESC() OrderByClause } -type ExpressionInterfaceImpl struct { +type expressionInterfaceImpl struct { Parent Expression } -func (e *ExpressionInterfaceImpl) fromImpl(subQuery SelectTable) Projection { +func (e *expressionInterfaceImpl) fromImpl(subQuery SelectTable) Projection { return e.Parent } -func (e *ExpressionInterfaceImpl) IS_NULL() BoolExpression { +func (e *expressionInterfaceImpl) IS_NULL() BoolExpression { return newPostifxBoolExpression(e.Parent, "IS NULL") } -func (e *ExpressionInterfaceImpl) IS_NOT_NULL() BoolExpression { +func (e *expressionInterfaceImpl) IS_NOT_NULL() BoolExpression { return newPostifxBoolExpression(e.Parent, "IS NOT NULL") } -func (e *ExpressionInterfaceImpl) IN(expressions ...Expression) BoolExpression { +func (e *expressionInterfaceImpl) IN(expressions ...Expression) BoolExpression { return newBinaryBoolOperator(e.Parent, WRAP(expressions...), "IN") } -func (e *ExpressionInterfaceImpl) NOT_IN(expressions ...Expression) BoolExpression { +func (e *expressionInterfaceImpl) NOT_IN(expressions ...Expression) BoolExpression { return newBinaryBoolOperator(e.Parent, WRAP(expressions...), "NOT IN") } -func (e *ExpressionInterfaceImpl) AS(alias string) Projection { +func (e *expressionInterfaceImpl) AS(alias string) Projection { return newAlias(e.Parent, alias) } -func (e *ExpressionInterfaceImpl) ASC() OrderByClause { +func (e *expressionInterfaceImpl) ASC() OrderByClause { return newOrderByClause(e.Parent, true) } -func (e *ExpressionInterfaceImpl) DESC() OrderByClause { +func (e *expressionInterfaceImpl) DESC() OrderByClause { return newOrderByClause(e.Parent, false) } -func (e *ExpressionInterfaceImpl) serializeForGroupBy(statement StatementType, out *SqlBuilder) { +func (e *expressionInterfaceImpl) serializeForGroupBy(statement StatementType, out *SQLBuilder) { e.Parent.serialize(statement, out, noWrap) } -func (e *ExpressionInterfaceImpl) serializeForProjection(statement StatementType, out *SqlBuilder) { +func (e *expressionInterfaceImpl) serializeForProjection(statement StatementType, out *SQLBuilder) { e.Parent.serialize(statement, out, noWrap) } -func (e *ExpressionInterfaceImpl) serializeForOrderBy(statement StatementType, out *SqlBuilder) { +func (e *expressionInterfaceImpl) serializeForOrderBy(statement StatementType, out *SQLBuilder) { e.Parent.serialize(statement, out, noWrap) } @@ -96,7 +96,7 @@ func newBinaryExpression(lhs, rhs Expression, operator string, additionalParam . return binaryExpression } -func (c *binaryOpExpression) serialize(statement StatementType, out *SqlBuilder, options ...SerializeOption) { +func (c *binaryOpExpression) serialize(statement StatementType, out *SQLBuilder, options ...SerializeOption) { if c.lhs == nil { panic("jet: lhs is nil for '" + c.operator + "' operator") } @@ -139,7 +139,7 @@ func newPrefixExpression(expression Expression, operator string) prefixOpExpress return prefixExpression } -func (p *prefixOpExpression) serialize(statement StatementType, out *SqlBuilder, options ...SerializeOption) { +func (p *prefixOpExpression) serialize(statement StatementType, out *SQLBuilder, options ...SerializeOption) { out.WriteString("(") out.WriteString(p.operator) @@ -167,7 +167,7 @@ func newPostfixOpExpression(expression Expression, operator string) postfixOpExp return postfixOpExpression } -func (p *postfixOpExpression) serialize(statement StatementType, out *SqlBuilder, options ...SerializeOption) { +func (p *postfixOpExpression) serialize(statement StatementType, out *SQLBuilder, options ...SerializeOption) { if p.expression == nil { panic("jet: nil prefix expression in postfix operator " + p.operator) } diff --git a/internal/jet/float_expression.go b/internal/jet/float_expression.go index bc69a62..c2ec535 100644 --- a/internal/jet/float_expression.go +++ b/internal/jet/float_expression.go @@ -86,7 +86,7 @@ func (n *floatInterfaceImpl) POW(expression NumericExpression) FloatExpression { //---------------------------------------------------// type binaryFloatExpression struct { - ExpressionInterfaceImpl + expressionInterfaceImpl floatInterfaceImpl binaryOpExpression @@ -97,7 +97,7 @@ func newBinaryFloatExpression(lhs, rhs Expression, operator string) FloatExpress floatExpression.binaryOpExpression = newBinaryExpression(lhs, rhs, operator) - floatExpression.ExpressionInterfaceImpl.Parent = &floatExpression + floatExpression.expressionInterfaceImpl.Parent = &floatExpression floatExpression.floatInterfaceImpl.parent = &floatExpression return &floatExpression diff --git a/internal/jet/func_expression.go b/internal/jet/func_expression.go index 3cab191..2489b85 100644 --- a/internal/jet/func_expression.go +++ b/internal/jet/func_expression.go @@ -482,7 +482,7 @@ func LEAST(value Expression, values ...Expression) Expression { //--------------------------------------------------------------------// type funcExpressionImpl struct { - ExpressionInterfaceImpl + expressionInterfaceImpl name string expressions []Expression @@ -496,15 +496,15 @@ func newFunc(name string, expressions []Expression, parent Expression) *funcExpr } if parent != nil { - funcExp.ExpressionInterfaceImpl.Parent = parent + funcExp.expressionInterfaceImpl.Parent = parent } else { - funcExp.ExpressionInterfaceImpl.Parent = funcExp + funcExp.expressionInterfaceImpl.Parent = funcExp } return funcExp } -func (f *funcExpressionImpl) serialize(statement StatementType, out *SqlBuilder, options ...SerializeOption) { +func (f *funcExpressionImpl) serialize(statement StatementType, out *SQLBuilder, options ...SerializeOption) { if serializeOverride := out.Dialect.FunctionSerializeOverride(f.name); serializeOverride != nil { serializeOverrideFunc := serializeOverride(f.expressions...) serializeOverrideFunc(statement, out, options...) @@ -545,6 +545,7 @@ type floatFunc struct { floatInterfaceImpl } +// NewFloatFunc creates new float function with name and expressions func NewFloatFunc(name string, expressions ...Expression) FloatExpression { floatFunc := &floatFunc{} @@ -629,6 +630,7 @@ type timestampFunc struct { timestampInterfaceImpl } +// NewTimestampFunc creates new timestamp function with name and expressions func NewTimestampFunc(name string, expressions ...Expression) *timestampFunc { timestampFunc := ×tampFunc{} diff --git a/internal/jet/group_by_clause.go b/internal/jet/group_by_clause.go index d010da9..65687c6 100644 --- a/internal/jet/group_by_clause.go +++ b/internal/jet/group_by_clause.go @@ -1,5 +1,6 @@ package jet +// GroupByClause interface type GroupByClause interface { - serializeForGroupBy(statement StatementType, out *SqlBuilder) + serializeForGroupBy(statement StatementType, out *SQLBuilder) } diff --git a/internal/jet/integer_expression.go b/internal/jet/integer_expression.go index 3394c16..74a3927 100644 --- a/internal/jet/integer_expression.go +++ b/internal/jet/integer_expression.go @@ -131,7 +131,7 @@ func (i *integerInterfaceImpl) BIT_SHIFT_RIGHT(intExpression IntegerExpression) //---------------------------------------------------// type binaryIntegerExpression struct { - ExpressionInterfaceImpl + expressionInterfaceImpl integerInterfaceImpl binaryOpExpression @@ -140,7 +140,7 @@ type binaryIntegerExpression struct { func newBinaryIntegerExpression(lhs, rhs IntegerExpression, operator string) IntegerExpression { integerExpression := binaryIntegerExpression{} - integerExpression.ExpressionInterfaceImpl.Parent = &integerExpression + integerExpression.expressionInterfaceImpl.Parent = &integerExpression integerExpression.integerInterfaceImpl.parent = &integerExpression integerExpression.binaryOpExpression = newBinaryExpression(lhs, rhs, operator) @@ -150,7 +150,7 @@ func newBinaryIntegerExpression(lhs, rhs IntegerExpression, operator string) Int //---------------------------------------------------// type prefixIntegerOpExpression struct { - ExpressionInterfaceImpl + expressionInterfaceImpl integerInterfaceImpl prefixOpExpression @@ -160,7 +160,7 @@ func newPrefixIntegerOperator(expression IntegerExpression, operator string) Int integerExpression := prefixIntegerOpExpression{} integerExpression.prefixOpExpression = newPrefixExpression(expression, operator) - integerExpression.ExpressionInterfaceImpl.Parent = &integerExpression + integerExpression.expressionInterfaceImpl.Parent = &integerExpression integerExpression.integerInterfaceImpl.parent = &integerExpression return &integerExpression @@ -168,7 +168,7 @@ func newPrefixIntegerOperator(expression IntegerExpression, operator string) Int //---------------------------------------------------// type prefixFloatOpExpression struct { - ExpressionInterfaceImpl + expressionInterfaceImpl floatInterfaceImpl prefixOpExpression @@ -178,7 +178,7 @@ func newPrefixFloatOperator(expression FloatExpression, operator string) FloatEx floatOpExpression := prefixFloatOpExpression{} floatOpExpression.prefixOpExpression = newPrefixExpression(expression, operator) - floatOpExpression.ExpressionInterfaceImpl.Parent = &floatOpExpression + floatOpExpression.expressionInterfaceImpl.Parent = &floatOpExpression floatOpExpression.floatInterfaceImpl.parent = &floatOpExpression return &floatOpExpression diff --git a/internal/jet/keyword.go b/internal/jet/keyword.go index b8f30cd..c903ad6 100644 --- a/internal/jet/keyword.go +++ b/internal/jet/keyword.go @@ -14,6 +14,6 @@ var ( type keywordClause string -func (k keywordClause) serialize(statement StatementType, out *SqlBuilder, options ...SerializeOption) { +func (k keywordClause) serialize(statement StatementType, out *SQLBuilder, options ...SerializeOption) { out.WriteString(string(k)) } diff --git a/internal/jet/literal_expression.go b/internal/jet/literal_expression.go index fc8117b..4851fa6 100644 --- a/internal/jet/literal_expression.go +++ b/internal/jet/literal_expression.go @@ -14,7 +14,7 @@ type LiteralExpression interface { } type literalExpressionImpl struct { - ExpressionInterfaceImpl + expressionInterfaceImpl value interface{} constant bool @@ -27,11 +27,12 @@ func literal(value interface{}, optionalConstant ...bool) *literalExpressionImpl exp.constant = optionalConstant[0] } - exp.ExpressionInterfaceImpl.Parent = &exp + exp.expressionInterfaceImpl.Parent = &exp return &exp } +// ConstLiteral is injected directly to SQL query, and does not appear in argument list. func ConstLiteral(value interface{}) *literalExpressionImpl { exp := literal(value) exp.constant = true @@ -39,7 +40,7 @@ func ConstLiteral(value interface{}) *literalExpressionImpl { return exp } -func (l *literalExpressionImpl) serialize(statement StatementType, out *SqlBuilder, options ...SerializeOption) { +func (l *literalExpressionImpl) serialize(statement StatementType, out *SQLBuilder, options ...SerializeOption) { if l.constant { out.insertConstantArgument(l.value) } else { @@ -272,46 +273,46 @@ func formatNanoseconds(nanoseconds ...time.Duration) string { //--------------------------------------------------// type nullLiteral struct { - ExpressionInterfaceImpl + expressionInterfaceImpl } func newNullLiteral() Expression { nullExpression := &nullLiteral{} - nullExpression.ExpressionInterfaceImpl.Parent = nullExpression + nullExpression.expressionInterfaceImpl.Parent = nullExpression return nullExpression } -func (n *nullLiteral) serialize(statement StatementType, out *SqlBuilder, options ...SerializeOption) { +func (n *nullLiteral) serialize(statement StatementType, out *SQLBuilder, options ...SerializeOption) { out.WriteString("NULL") } //--------------------------------------------------// type starLiteral struct { - ExpressionInterfaceImpl + expressionInterfaceImpl } func newStarLiteral() Expression { starExpression := &starLiteral{} - starExpression.ExpressionInterfaceImpl.Parent = starExpression + starExpression.expressionInterfaceImpl.Parent = starExpression return starExpression } -func (n *starLiteral) serialize(statement StatementType, out *SqlBuilder, options ...SerializeOption) { +func (n *starLiteral) serialize(statement StatementType, out *SQLBuilder, options ...SerializeOption) { out.WriteString("*") } //---------------------------------------------------// type wrap struct { - ExpressionInterfaceImpl + expressionInterfaceImpl expressions []Expression } -func (n *wrap) serialize(statement StatementType, out *SqlBuilder, options ...SerializeOption) { +func (n *wrap) serialize(statement StatementType, out *SQLBuilder, options ...SerializeOption) { out.WriteString("(") serializeExpressionList(statement, n.expressions, ", ", out) out.WriteString(")") @@ -320,7 +321,7 @@ func (n *wrap) serialize(statement StatementType, out *SqlBuilder, options ...Se // WRAP wraps list of expressions with brackets '(' and ')' func WRAP(expression ...Expression) Expression { wrap := &wrap{expressions: expression} - wrap.ExpressionInterfaceImpl.Parent = wrap + wrap.expressionInterfaceImpl.Parent = wrap return wrap } @@ -328,12 +329,12 @@ func WRAP(expression ...Expression) Expression { //---------------------------------------------------// type rawExpression struct { - ExpressionInterfaceImpl + expressionInterfaceImpl raw string } -func (n *rawExpression) serialize(statement StatementType, out *SqlBuilder, options ...SerializeOption) { +func (n *rawExpression) serialize(statement StatementType, out *SQLBuilder, options ...SerializeOption) { out.WriteString(n.raw) } @@ -341,7 +342,7 @@ func (n *rawExpression) serialize(statement StatementType, out *SqlBuilder, opti // For example: Raw("current_database()") func Raw(raw string) Expression { rawExp := &rawExpression{raw: raw} - rawExp.ExpressionInterfaceImpl.Parent = rawExp + rawExp.expressionInterfaceImpl.Parent = rawExp return rawExp } diff --git a/internal/jet/operators.go b/internal/jet/operators.go index 14dbd77..4a4a32d 100644 --- a/internal/jet/operators.go +++ b/internal/jet/operators.go @@ -1,5 +1,6 @@ package jet +// Operators const ( StringConcatOperator = "||" StringRegexpLikeOperator = "REGEXP" @@ -78,7 +79,7 @@ type CaseOperator interface { } type caseOperatorImpl struct { - ExpressionInterfaceImpl + expressionInterfaceImpl expression Expression when []Expression @@ -94,7 +95,7 @@ func CASE(expression ...Expression) CaseOperator { caseExp.expression = expression[0] } - caseExp.ExpressionInterfaceImpl.Parent = caseExp + caseExp.expressionInterfaceImpl.Parent = caseExp return caseExp } @@ -115,7 +116,7 @@ func (c *caseOperatorImpl) ELSE(els Expression) CaseOperator { return c } -func (c *caseOperatorImpl) serialize(statement StatementType, out *SqlBuilder, options ...SerializeOption) { +func (c *caseOperatorImpl) serialize(statement StatementType, out *SQLBuilder, options ...SerializeOption) { out.WriteString("(CASE") if c.expression != nil { diff --git a/internal/jet/order_by_clause.go b/internal/jet/order_by_clause.go index 42d12d4..55fb7d2 100644 --- a/internal/jet/order_by_clause.go +++ b/internal/jet/order_by_clause.go @@ -1,8 +1,8 @@ package jet -// OrderByClause +// OrderByClause interface type OrderByClause interface { - serializeForOrderBy(statement StatementType, out *SqlBuilder) + serializeForOrderBy(statement StatementType, out *SQLBuilder) } type orderByClauseImpl struct { @@ -10,7 +10,7 @@ type orderByClauseImpl struct { ascent bool } -func (o *orderByClauseImpl) serializeForOrderBy(statement StatementType, out *SqlBuilder) { +func (o *orderByClauseImpl) serializeForOrderBy(statement StatementType, out *SQLBuilder) { if o.expression == nil { panic("jet: nil expression in ORDER BY clause") } diff --git a/internal/jet/projection.go b/internal/jet/projection.go index 6ab4b09..b85702f 100644 --- a/internal/jet/projection.go +++ b/internal/jet/projection.go @@ -2,11 +2,12 @@ package jet // Projection is interface for all projection types. Types that can be part of, for instance SELECT clause. type Projection interface { - serializeForProjection(statement StatementType, out *SqlBuilder) + serializeForProjection(statement StatementType, out *SQLBuilder) fromImpl(subQuery SelectTable) Projection } -func SerializeForProjection(projection Projection, statementType StatementType, out *SqlBuilder) { +// SerializeForProjection is helper function for serializing projection outside of jet package +func SerializeForProjection(projection Projection, statementType StatementType, out *SQLBuilder) { projection.serializeForProjection(statementType, out) } @@ -23,6 +24,6 @@ func (cl ProjectionList) fromImpl(subQuery SelectTable) Projection { return newProjectionList } -func (cl ProjectionList) serializeForProjection(statement StatementType, out *SqlBuilder) { +func (cl ProjectionList) serializeForProjection(statement StatementType, out *SQLBuilder) { SerializeProjectionList(statement, cl, out) } diff --git a/internal/jet/select_lock.go b/internal/jet/select_lock.go index 48277d9..4694ee3 100644 --- a/internal/jet/select_lock.go +++ b/internal/jet/select_lock.go @@ -13,7 +13,8 @@ type selectLockImpl struct { noWait, skipLocked bool } -func NewSelectLock(name string) func() RowLock { +// NewRowLock creates new RowLock +func NewRowLock(name string) func() RowLock { return func() RowLock { return newSelectLock(name) } @@ -33,7 +34,7 @@ func (s *selectLockImpl) SKIP_LOCKED() RowLock { return s } -func (s *selectLockImpl) serialize(statement StatementType, out *SqlBuilder, options ...SerializeOption) { +func (s *selectLockImpl) serialize(statement StatementType, out *SQLBuilder, options ...SerializeOption) { out.WriteString(s.lockStrength) if s.noWait { diff --git a/internal/jet/select_table.go b/internal/jet/select_table.go index 6894bc0..9acd8a3 100644 --- a/internal/jet/select_table.go +++ b/internal/jet/select_table.go @@ -2,35 +2,37 @@ package jet // SelectTable is interface for SELECT sub-queries type SelectTable interface { + Serializer Alias() string AllColumns() ProjectionList } -type SelectTableImpl struct { +type selectTableImpl struct { selectStmt StatementWithProjections alias string projections ProjectionList } -func NewSelectTable(selectStmt StatementWithProjections, alias string) SelectTableImpl { - selectTable := SelectTableImpl{selectStmt: selectStmt, alias: alias} +// NewSelectTable func +func NewSelectTable(selectStmt StatementWithProjections, alias string) SelectTable { + selectTable := selectTableImpl{selectStmt: selectStmt, alias: alias} projectionList := selectStmt.projections().fromImpl(&selectTable) selectTable.projections = projectionList.(ProjectionList) - return selectTable + return &selectTable } -func (s *SelectTableImpl) Alias() string { +func (s *selectTableImpl) Alias() string { return s.alias } -func (s *SelectTableImpl) AllColumns() ProjectionList { +func (s *selectTableImpl) AllColumns() ProjectionList { return s.projections } -func (s *SelectTableImpl) serialize(statement StatementType, out *SqlBuilder, options ...SerializeOption) { +func (s *selectTableImpl) serialize(statement StatementType, out *SQLBuilder, options ...SerializeOption) { if s == nil { panic("jet: expression table is nil. ") } diff --git a/internal/jet/serializer.go b/internal/jet/serializer.go index b624f61..585d7db 100644 --- a/internal/jet/serializer.go +++ b/internal/jet/serializer.go @@ -1,13 +1,17 @@ package jet +// SerializeOption type type SerializeOption int +// Serialize options const ( noWrap SerializeOption = iota ) +// StatementType is type of the SQL statement type StatementType string +// Statement types const ( SelectStatementType StatementType = "SELECT" InsertStatementType StatementType = "INSERT" @@ -18,11 +22,13 @@ const ( UnLockStatementType StatementType = "UNLOCK" ) +// Serializer interface type Serializer interface { - serialize(statement StatementType, out *SqlBuilder, options ...SerializeOption) + serialize(statement StatementType, out *SQLBuilder, options ...SerializeOption) } -func Serialize(exp Serializer, statementType StatementType, out *SqlBuilder, options ...SerializeOption) { +// Serialize func +func Serialize(exp Serializer, statementType StatementType, out *SQLBuilder, options ...SerializeOption) { exp.serialize(statementType, out, options...) } diff --git a/internal/jet/sql_builder.go b/internal/jet/sql_builder.go index c021fd0..d16aec4 100644 --- a/internal/jet/sql_builder.go +++ b/internal/jet/sql_builder.go @@ -10,7 +10,8 @@ import ( "unicode" ) -type SqlBuilder struct { +// SQLBuilder generates output SQL +type SQLBuilder struct { Dialect Dialect Buff bytes.Buffer Args []interface{} @@ -23,7 +24,8 @@ type SqlBuilder struct { const defaultIdent = 5 -func (s *SqlBuilder) IncreaseIdent(ident ...int) { +// IncreaseIdent adds ident or defaultIdent number of spaces to each new line +func (s *SQLBuilder) IncreaseIdent(ident ...int) { if len(ident) > 0 { s.ident += ident[0] } else { @@ -31,7 +33,8 @@ func (s *SqlBuilder) IncreaseIdent(ident ...int) { } } -func (s *SqlBuilder) DecreaseIdent(ident ...int) { +// DecreaseIdent removes ident or defaultIdent number of spaces for each new line +func (s *SQLBuilder) DecreaseIdent(ident ...int) { toDecrease := defaultIdent if len(ident) > 0 { @@ -45,18 +48,20 @@ func (s *SqlBuilder) DecreaseIdent(ident ...int) { s.ident -= toDecrease } -func (s *SqlBuilder) WriteProjections(statement StatementType, projections []Projection) { +// WriteProjections func +func (s *SQLBuilder) WriteProjections(statement StatementType, projections []Projection) { s.IncreaseIdent() SerializeProjectionList(statement, projections, s) s.DecreaseIdent() } -func (s *SqlBuilder) NewLine() { +// NewLine adds new line to output SQL +func (s *SQLBuilder) NewLine() { s.write([]byte{'\n'}) s.write(bytes.Repeat([]byte{' '}, s.ident)) } -func (s *SqlBuilder) write(data []byte) { +func (s *SQLBuilder) write(data []byte) { if len(data) == 0 { return } @@ -77,16 +82,19 @@ func isPostSeparator(b byte) bool { return b == ' ' || b == '.' || b == ',' || b == ')' || b == '\n' || b == ':' } -func (s *SqlBuilder) WriteAlias(str string) { +// WriteAlias is used to add alias to output SQL +func (s *SQLBuilder) WriteAlias(str string) { aliasQuoteChar := string(s.Dialect.AliasQuoteChar()) s.WriteString(aliasQuoteChar + str + aliasQuoteChar) } -func (s *SqlBuilder) WriteString(str string) { +// WriteString writes sting to output SQL +func (s *SQLBuilder) WriteString(str string) { s.write([]byte(str)) } -func (s *SqlBuilder) WriteIdentifier(name string, alwaysQuote ...bool) { +// WriteIdentifier adds identifier to output SQL +func (s *SQLBuilder) WriteIdentifier(name string, alwaysQuote ...bool) { if shouldQuoteIdentifier(name) || len(alwaysQuote) > 0 { identQuoteChar := string(s.Dialect.IdentifierQuoteChar()) s.WriteString(identQuoteChar + name + identQuoteChar) @@ -95,19 +103,20 @@ func (s *SqlBuilder) WriteIdentifier(name string, alwaysQuote ...bool) { } } -func (s *SqlBuilder) WriteByte(b byte) { +// WriteByte writes byte to output SQL +func (s *SQLBuilder) WriteByte(b byte) { s.write([]byte{b}) } -func (s *SqlBuilder) finalize() (string, []interface{}) { +func (s *SQLBuilder) finalize() (string, []interface{}) { return s.Buff.String() + ";\n", s.Args } -func (s *SqlBuilder) insertConstantArgument(arg interface{}) { +func (s *SQLBuilder) insertConstantArgument(arg interface{}) { s.WriteString(argToString(arg)) } -func (s *SqlBuilder) insertParametrizedArgument(arg interface{}) { +func (s *SQLBuilder) insertParametrizedArgument(arg interface{}) { if s.debug { s.insertConstantArgument(arg) return @@ -139,7 +148,7 @@ func argToString(value interface{}) string { case int32: return strconv.FormatInt(int64(bindVal), 10) case int64: - return strconv.FormatInt(int64(bindVal), 10) + return strconv.FormatInt(bindVal, 10) case uint8: return strconv.FormatUint(uint64(bindVal), 10) diff --git a/internal/jet/statement.go b/internal/jet/statement.go index 23909c2..8a76738 100644 --- a/internal/jet/statement.go +++ b/internal/jet/statement.go @@ -27,30 +27,34 @@ type Statement interface { ExecContext(context context.Context, db execution.DB) (sql.Result, error) } +// SerializerStatement interface type SerializerStatement interface { Serializer Statement } +// StatementWithProjections interface type StatementWithProjections interface { Statement HasProjections Serializer } +// HasProjections interface type HasProjections interface { projections() ProjectionList } -type SerializerStatementInterfaceImpl struct { +// serializerStatementInterfaceImpl struct +type serializerStatementInterfaceImpl struct { dialect Dialect statementType StatementType parent SerializerStatement } -func (s *SerializerStatementInterfaceImpl) Sql() (query string, args []interface{}) { +func (s *serializerStatementInterfaceImpl) Sql() (query string, args []interface{}) { - queryData := &SqlBuilder{Dialect: s.dialect} + queryData := &SQLBuilder{Dialect: s.dialect} s.parent.serialize(s.statementType, queryData, noWrap) @@ -58,8 +62,8 @@ func (s *SerializerStatementInterfaceImpl) Sql() (query string, args []interface return } -func (s *SerializerStatementInterfaceImpl) DebugSql() (query string) { - sqlBuilder := &SqlBuilder{Dialect: s.dialect, debug: true} +func (s *serializerStatementInterfaceImpl) DebugSql() (query string) { + sqlBuilder := &SQLBuilder{Dialect: s.dialect, debug: true} s.parent.serialize(s.statementType, sqlBuilder, noWrap) @@ -67,41 +71,64 @@ func (s *SerializerStatementInterfaceImpl) DebugSql() (query string) { return } -func (s *SerializerStatementInterfaceImpl) Query(db execution.DB, destination interface{}) error { +func (s *serializerStatementInterfaceImpl) Query(db execution.DB, destination interface{}) error { query, args := s.Sql() return execution.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 execution.DB, destination interface{}) error { query, args := s.Sql() return execution.Query(context, db, query, args, destination) } -func (s *SerializerStatementInterfaceImpl) Exec(db execution.DB) (res sql.Result, err error) { +func (s *serializerStatementInterfaceImpl) Exec(db execution.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 execution.DB) (res sql.Result, err error) { query, args := s.Sql() return db.ExecContext(context, query, args...) } -type ExpressionStatementImpl struct { - ExpressionInterfaceImpl - StatementImpl +// ExpressionStatement interfacess +type ExpressionStatement interface { + Expression + Statement + HasProjections } -func (s *ExpressionStatementImpl) serializeForProjection(statement StatementType, out *SqlBuilder) { +// NewExpressionStatementImpl creates new expression statement +func NewExpressionStatementImpl(Dialect Dialect, statementType StatementType, parent ExpressionStatement, clauses ...Clause) ExpressionStatement { + return &expressionStatementImpl{ + expressionInterfaceImpl{Parent: parent}, + statementImpl{ + serializerStatementInterfaceImpl: serializerStatementInterfaceImpl{ + parent: parent, + dialect: Dialect, + statementType: statementType, + }, + Clauses: clauses, + }, + } +} + +type expressionStatementImpl struct { + expressionInterfaceImpl + statementImpl +} + +func (s *expressionStatementImpl) serializeForProjection(statement StatementType, out *SQLBuilder) { s.serialize(statement, out) } -func NewStatementImpl(Dialect Dialect, statementType StatementType, parent SerializerStatement, clauses ...Clause) StatementImpl { - return StatementImpl{ - SerializerStatementInterfaceImpl: SerializerStatementInterfaceImpl{ +// NewStatementImpl creates new statementImpl +func NewStatementImpl(Dialect Dialect, statementType StatementType, parent SerializerStatement, clauses ...Clause) SerializerStatement { + return &statementImpl{ + serializerStatementInterfaceImpl: serializerStatementInterfaceImpl{ parent: parent, dialect: Dialect, statementType: statementType, @@ -110,13 +137,13 @@ func NewStatementImpl(Dialect Dialect, statementType StatementType, parent Seria } } -type StatementImpl struct { - SerializerStatementInterfaceImpl +type statementImpl struct { + serializerStatementInterfaceImpl Clauses []Clause } -func (s *StatementImpl) projections() ProjectionList { +func (s *statementImpl) projections() ProjectionList { for _, clause := range s.Clauses { if selectClause, ok := clause.(ClauseWithProjections); ok { return selectClause.projections() @@ -126,7 +153,7 @@ func (s *StatementImpl) projections() ProjectionList { return nil } -func (s *StatementImpl) serialize(statement StatementType, out *SqlBuilder, options ...SerializeOption) { +func (s *statementImpl) serialize(statement StatementType, out *SQLBuilder, options ...SerializeOption) { if !contains(options, noWrap) { out.WriteString("(") diff --git a/internal/jet/string_expression.go b/internal/jet/string_expression.go index ef8d802..b0351ea 100644 --- a/internal/jet/string_expression.go +++ b/internal/jet/string_expression.go @@ -82,7 +82,7 @@ func (s *stringInterfaceImpl) NOT_REGEXP_LIKE(pattern StringExpression, caseSens //---------------------------------------------------// type binaryStringExpression struct { - ExpressionInterfaceImpl + expressionInterfaceImpl stringInterfaceImpl binaryOpExpression @@ -92,7 +92,7 @@ func newBinaryStringExpression(lhs, rhs Expression, operator string) StringExpre boolExpression := binaryStringExpression{} boolExpression.binaryOpExpression = newBinaryExpression(lhs, rhs, operator) - boolExpression.ExpressionInterfaceImpl.Parent = &boolExpression + boolExpression.expressionInterfaceImpl.Parent = &boolExpression boolExpression.stringInterfaceImpl.parent = &boolExpression return &boolExpression diff --git a/internal/jet/table.go b/internal/jet/table.go index 933db2f..bf8285f 100644 --- a/internal/jet/table.go +++ b/internal/jet/table.go @@ -4,11 +4,13 @@ import ( "github.com/go-jet/jet/internal/utils" ) +// SerializerTable interface type SerializerTable interface { Serializer Table } +// Table interface type Table interface { columns() []Column SchemaName() string @@ -17,9 +19,9 @@ type Table interface { } // NewTable creates new table with schema Name, table Name and list of columns -func NewTable(schemaName, name string, columns ...ColumnExpression) TableImpl { +func NewTable(schemaName, name string, columns ...ColumnExpression) SerializerTable { - t := TableImpl{ + t := tableImpl{ schemaName: schemaName, name: name, columnList: columns, @@ -29,17 +31,17 @@ func NewTable(schemaName, name string, columns ...ColumnExpression) TableImpl { c.setTableName(name) } - return t + return &t } -type TableImpl struct { +type tableImpl struct { schemaName string name string alias string columnList []ColumnExpression } -func (t *TableImpl) AS(alias string) { +func (t *tableImpl) AS(alias string) { t.alias = alias for _, c := range t.columnList { @@ -47,15 +49,15 @@ func (t *TableImpl) AS(alias string) { } } -func (t *TableImpl) SchemaName() string { +func (t *tableImpl) SchemaName() string { return t.schemaName } -func (t *TableImpl) TableName() string { +func (t *tableImpl) TableName() string { return t.name } -func (t *TableImpl) columns() []Column { +func (t *tableImpl) columns() []Column { ret := []Column{} for _, col := range t.columnList { @@ -65,7 +67,7 @@ func (t *TableImpl) columns() []Column { return ret } -func (t *TableImpl) serialize(statement StatementType, out *SqlBuilder, options ...SerializeOption) { +func (t *tableImpl) serialize(statement StatementType, out *SQLBuilder, options ...SerializeOption) { if t == nil { panic("jet: tableImpl is nil") } @@ -80,8 +82,10 @@ func (t *TableImpl) serialize(statement StatementType, out *SqlBuilder, options } } +// JoinType is type of table join type JoinType int +// Table join types const ( InnerJoin JoinType = iota LeftJoin @@ -91,37 +95,44 @@ const ( ) // Join expressions are pseudo readable tables. -type JoinTableImpl struct { +type joinTableImpl struct { lhs Serializer rhs Serializer joinType JoinType onCondition BoolExpression } -func NewJoinTableImpl(lhs Serializer, rhs Serializer, joinType JoinType, onCondition BoolExpression) JoinTableImpl { +// JoinTable interface +type JoinTable SerializerTable - joinTable := JoinTableImpl{ +// NewJoinTable creates new join table +func NewJoinTable(lhs Serializer, rhs Serializer, joinType JoinType, onCondition BoolExpression) JoinTable { + + joinTable := joinTableImpl{ lhs: lhs, rhs: rhs, joinType: joinType, onCondition: onCondition, } - return joinTable + return &joinTable } -func (t *JoinTableImpl) SchemaName() string { +func (t *joinTableImpl) SchemaName() string { if table, ok := t.lhs.(Table); ok { return table.SchemaName() } return "" } -func (t *JoinTableImpl) TableName() string { +func (t *joinTableImpl) TableName() string { return "" } -func (t *JoinTableImpl) Columns() []Column { +func (t *joinTableImpl) AS(alias string) { +} + +func (t *joinTableImpl) columns() []Column { var ret []Column if lhsTable, ok := t.lhs.(Table); ok { @@ -134,7 +145,7 @@ func (t *JoinTableImpl) Columns() []Column { return ret } -func (t *JoinTableImpl) serialize(statement StatementType, out *SqlBuilder, options ...SerializeOption) { +func (t *joinTableImpl) serialize(statement StatementType, out *SQLBuilder, options ...SerializeOption) { if t == nil { panic("jet: Join table is nil. ") } @@ -175,35 +186,3 @@ func (t *JoinTableImpl) serialize(statement StatementType, out *SqlBuilder, opti t.onCondition.serialize(statement, out) } } - -func UnwindColumns(column1 Column, columns ...Column) []Column { - columnList := []Column{} - - if val, ok := column1.(IColumnList); ok { - for _, col := range val.columns() { - columnList = append(columnList, col) - } - columnList = append(columnList, columns...) - } else { - columnList = append(columnList, column1) - columnList = append(columnList, columns...) - } - - return columnList -} - -func UnwidColumnList(columns []Column) []Column { - ret := []Column{} - - for _, col := range columns { - if columnList, ok := col.(IColumnList); ok { - for _, c := range columnList.columns() { - ret = append(ret, c) - } - } else { - ret = append(ret, col) - } - } - - return ret -} diff --git a/internal/jet/testutils.go b/internal/jet/testutils.go index f95ae76..3c0a969 100644 --- a/internal/jet/testutils.go +++ b/internal/jet/testutils.go @@ -6,7 +6,7 @@ import ( "testing" ) -var DefaultDialect = NewDialect(DialectParams{ // just for tests +var defaultDialect = NewDialect(DialectParams{ // just for tests AliasQuoteChar: '"', IdentifierQuoteChar: '"', ArgumentPlaceholder: func(ord int) string { @@ -47,7 +47,7 @@ var table3StrCol = StringColumn("col2") var table3 = NewTable("db", "table3", table3Col1, table3ColInt, table3StrCol) func assertClauseSerialize(t *testing.T, clause Serializer, query string, args ...interface{}) { - out := SqlBuilder{Dialect: DefaultDialect} + out := SQLBuilder{Dialect: defaultDialect} clause.serialize(SelectStatementType, &out) //fmt.Println(out.Buff.String()) @@ -62,12 +62,12 @@ func assertClauseSerializeErr(t *testing.T, clause Serializer, errString string) assert.Equal(t, r, errString) }() - out := SqlBuilder{Dialect: DefaultDialect} + out := SQLBuilder{Dialect: defaultDialect} clause.serialize(SelectStatementType, &out) } func assertClauseDebugSerialize(t *testing.T, clause Serializer, query string, args ...interface{}) { - out := SqlBuilder{Dialect: DefaultDialect, debug: true} + out := SQLBuilder{Dialect: defaultDialect, debug: true} clause.serialize(SelectStatementType, &out) //fmt.Println(out.Buff.String()) @@ -77,7 +77,7 @@ func assertClauseDebugSerialize(t *testing.T, clause Serializer, query string, a } func assertProjectionSerialize(t *testing.T, projection Projection, query string, args ...interface{}) { - out := SqlBuilder{Dialect: DefaultDialect} + out := SQLBuilder{Dialect: defaultDialect} projection.serializeForProjection(SelectStatementType, &out) assert.DeepEqual(t, out.Buff.String(), query) diff --git a/internal/jet/time_expression.go b/internal/jet/time_expression.go index 0fadfc5..779d37f 100644 --- a/internal/jet/time_expression.go +++ b/internal/jet/time_expression.go @@ -53,7 +53,7 @@ func (t *timeInterfaceImpl) GT_EQ(rhs TimeExpression) BoolExpression { //---------------------------------------------------// type prefixTimeExpression struct { - ExpressionInterfaceImpl + expressionInterfaceImpl timeInterfaceImpl prefixOpExpression @@ -63,7 +63,7 @@ type prefixTimeExpression struct { // timeExpr := prefixTimeExpression{} // timeExpr.prefixOpExpression = newPrefixExpression(expression, operator) // -// timeExpr.ExpressionInterfaceImpl.parent = &timeExpr +// timeExpr.expressionInterfaceImpl.parent = &timeExpr // timeExpr.timeInterfaceImpl.parent = &timeExpr // // return &timeExpr diff --git a/internal/jet/timestampz_expression.go b/internal/jet/timestampz_expression.go index 1d83523..4f3e6ec 100644 --- a/internal/jet/timestampz_expression.go +++ b/internal/jet/timestampz_expression.go @@ -54,22 +54,12 @@ func (t *timestampzInterfaceImpl) GT_EQ(rhs TimestampzExpression) BoolExpression //---------------------------------------------------// type prefixTimestampzOperator struct { - ExpressionInterfaceImpl + expressionInterfaceImpl timestampzInterfaceImpl prefixOpExpression } -func NewPrefixTimestampOperator(operator string, expression Expression) TimestampzExpression { - timeExpr := prefixTimestampzOperator{} - timeExpr.prefixOpExpression = newPrefixExpression(expression, operator) - - timeExpr.ExpressionInterfaceImpl.Parent = &timeExpr - timeExpr.timestampzInterfaceImpl.parent = &timeExpr - - return &timeExpr -} - //------------------------------------------------- type timestampzExpressionWrapper struct { diff --git a/internal/jet/timez_expression.go b/internal/jet/timez_expression.go index 0189d3d..36b5c8f 100644 --- a/internal/jet/timez_expression.go +++ b/internal/jet/timez_expression.go @@ -61,7 +61,7 @@ func (t *timezInterfaceImpl) GT_EQ(rhs TimezExpression) BoolExpression { //---------------------------------------------------// type prefixTimezExpression struct { - ExpressionInterfaceImpl + expressionInterfaceImpl timezInterfaceImpl prefixOpExpression @@ -71,7 +71,7 @@ type prefixTimezExpression struct { // timeExpr := prefixTimezExpression{} // timeExpr.prefixOpExpression = newPrefixExpression(expression, operator) // -// timeExpr.ExpressionInterfaceImpl.parent = &timeExpr +// timeExpr.expressionInterfaceImpl.parent = &timeExpr // timeExpr.timezInterfaceImpl.parent = &timeExpr // // return &timeExpr diff --git a/internal/jet/utils.go b/internal/jet/utils.go index 78dc013..266ce53 100644 --- a/internal/jet/utils.go +++ b/internal/jet/utils.go @@ -5,33 +5,8 @@ import ( "reflect" ) -func serializeOrderByClauseList(statement StatementType, orderByClauses []OrderByClause, out *SqlBuilder) { - - for i, value := range orderByClauses { - if i > 0 { - out.WriteString(", ") - } - - value.serializeForOrderBy(statement, out) - } -} - -func serializeGroupByClauseList(statement StatementType, clauses []GroupByClause, out *SqlBuilder) { - - for i, c := range clauses { - if i > 0 { - out.WriteString(", ") - } - - if c == nil { - panic("jet: nil clause") - } - - c.serializeForGroupBy(statement, out) - } -} - -func SerializeClauseList(statement StatementType, clauses []Serializer, out *SqlBuilder) { +// SerializeClauseList func +func SerializeClauseList(statement StatementType, clauses []Serializer, out *SQLBuilder) { for i, c := range clauses { if i > 0 { @@ -46,7 +21,7 @@ func SerializeClauseList(statement StatementType, clauses []Serializer, out *Sql } } -func serializeExpressionList(statement StatementType, expressions []Expression, separator string, out *SqlBuilder) { +func serializeExpressionList(statement StatementType, expressions []Expression, separator string, out *SQLBuilder) { for i, value := range expressions { if i > 0 { @@ -57,7 +32,8 @@ func serializeExpressionList(statement StatementType, expressions []Expression, } } -func SerializeProjectionList(statement StatementType, projections []Projection, out *SqlBuilder) { +// SerializeProjectionList func +func SerializeProjectionList(statement StatementType, projections []Projection, out *SQLBuilder) { for i, col := range projections { if i > 0 { out.WriteString(",") @@ -72,7 +48,8 @@ func SerializeProjectionList(statement StatementType, projections []Projection, } } -func SerializeColumnNames(columns []Column, out *SqlBuilder) { +// SerializeColumnNames func +func SerializeColumnNames(columns []Column, out *SQLBuilder) { for i, col := range columns { if i > 0 { out.WriteString(", ") @@ -86,6 +63,7 @@ func SerializeColumnNames(columns []Column, out *SqlBuilder) { } } +// ColumnListToProjectionList func func ColumnListToProjectionList(columns []ColumnExpression) []Projection { var ret []Projection @@ -104,6 +82,7 @@ func valueToClause(value interface{}) Serializer { return literal(value) } +// UnwindRowFromModel func func UnwindRowFromModel(columns []Column, data interface{}) []Serializer { structValue := reflect.Indirect(reflect.ValueOf(data)) @@ -135,6 +114,7 @@ func UnwindRowFromModel(columns []Column, data interface{}) []Serializer { return row } +// UnwindRowsFromModels func func UnwindRowsFromModels(columns []Column, data interface{}) [][]Serializer { sliceValue := reflect.Indirect(reflect.ValueOf(data)) utils.ValueMustBe(sliceValue, reflect.Slice, "jet: data has to be a slice.") @@ -150,6 +130,7 @@ func UnwindRowsFromModels(columns []Column, data interface{}) [][]Serializer { return rows } +// UnwindRowFromValues func func UnwindRowFromValues(value interface{}, values []interface{}) []Serializer { row := []Serializer{} @@ -161,3 +142,37 @@ func UnwindRowFromValues(value interface{}, values []interface{}) []Serializer { return row } + +// UnwindColumns func +func UnwindColumns(column1 Column, columns ...Column) []Column { + columnList := []Column{} + + if val, ok := column1.(IColumnList); ok { + for _, col := range val.columns() { + columnList = append(columnList, col) + } + columnList = append(columnList, columns...) + } else { + columnList = append(columnList, column1) + columnList = append(columnList, columns...) + } + + return columnList +} + +// UnwidColumnList func +func UnwidColumnList(columns []Column) []Column { + ret := []Column{} + + for _, col := range columns { + if columnList, ok := col.(IColumnList); ok { + for _, c := range columnList.columns() { + ret = append(ret, c) + } + } else { + ret = append(ret, col) + } + } + + return ret +} diff --git a/internal/testutils/test_utils.go b/internal/testutils/test_utils.go index 375785f..d5dbbd6 100644 --- a/internal/testutils/test_utils.go +++ b/internal/testutils/test_utils.go @@ -14,6 +14,7 @@ import ( "testing" ) +// 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) { res, err := stmt.Exec(db) @@ -26,6 +27,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) { _, err := stmt.Exec(db) @@ -37,11 +39,13 @@ func getFullPath(relativePath string) string { return filepath.Join(goPath, "src/github.com/go-jet/jet/tests", relativePath) } +// PrintJson print v as json func PrintJson(v interface{}) { jsonText, _ := json.MarshalIndent(v, "", "\t") fmt.Println(string(jsonText)) } +// AssertJSON check if data json output is the same as expectedJSON func AssertJSON(t *testing.T, data interface{}, expectedJSON string) { jsonData, err := json.MarshalIndent(data, "", "\t") assert.NilError(t, err) @@ -49,7 +53,8 @@ func AssertJSON(t *testing.T, data interface{}, expectedJSON string) { assert.Equal(t, "\n"+string(jsonData)+"\n", expectedJSON) } -func SaveJsonFile(v interface{}, testRelativePath string) { +// SaveJSONFile saves v as json at testRelativePath +func SaveJSONFile(v interface{}, testRelativePath string) { jsonText, _ := json.MarshalIndent(v, "", "\t") filePath := getFullPath(testRelativePath) @@ -60,6 +65,7 @@ func SaveJsonFile(v interface{}, testRelativePath string) { } } +// AssertJSONFile check if data json representation is the same as json at testRelativePath func AssertJSONFile(t *testing.T, data interface{}, testRelativePath string) { filePath := getFullPath(testRelativePath) @@ -77,6 +83,7 @@ func AssertJSONFile(t *testing.T, data interface{}, testRelativePath string) { //assert.DeepEqual(t, string(fileJSONData), string(jsonData)) } +// AssertStatementSql check if statement Sql() is the same as expectedQuery and expectedArgs func AssertStatementSql(t *testing.T, query jet.Statement, expectedQuery string, expectedArgs ...interface{}) { queryStr, args := query.Sql() assert.Equal(t, queryStr, expectedQuery) @@ -87,6 +94,7 @@ func AssertStatementSql(t *testing.T, query jet.Statement, expectedQuery string, assert.DeepEqual(t, args, expectedArgs) } +// AssertStatementSqlErr checks if statement Sql() panics with errorStr func AssertStatementSqlErr(t *testing.T, stmt jet.Statement, errorStr string) { defer func() { r := recover() @@ -96,6 +104,7 @@ func AssertStatementSqlErr(t *testing.T, stmt jet.Statement, errorStr string) { stmt.Sql() } +// AssertDebugStatementSql check if statement Sql() is the same as expectedQuery func AssertDebugStatementSql(t *testing.T, query jet.Statement, expectedQuery string, expectedArgs ...interface{}) { _, args := query.Sql() @@ -107,8 +116,9 @@ func AssertDebugStatementSql(t *testing.T, query jet.Statement, expectedQuery st assert.Equal(t, debuqSql, expectedQuery) } +// AssertClauseSerialize checks if clause serialize produces expected query and args func AssertClauseSerialize(t *testing.T, dialect jet.Dialect, clause jet.Serializer, query string, args ...interface{}) { - out := jet.SqlBuilder{Dialect: dialect} + out := jet.SQLBuilder{Dialect: dialect} jet.Serialize(clause, jet.SelectStatementType, &out) //fmt.Println(out.Buff.String()) @@ -120,24 +130,27 @@ func AssertClauseSerialize(t *testing.T, dialect jet.Dialect, clause jet.Seriali } } +// AssertClauseSerializeErr check if clause serialize panics with errString func AssertClauseSerializeErr(t *testing.T, dialect jet.Dialect, clause jet.Serializer, errString string) { defer func() { r := recover() assert.Equal(t, r, errString) }() - out := jet.SqlBuilder{Dialect: dialect} + out := jet.SQLBuilder{Dialect: dialect} jet.Serialize(clause, jet.SelectStatementType, &out) } +// AssertProjectionSerialize check if projection serialize produces expected query and args func AssertProjectionSerialize(t *testing.T, dialect jet.Dialect, projection jet.Projection, query string, args ...interface{}) { - out := jet.SqlBuilder{Dialect: dialect} + out := jet.SQLBuilder{Dialect: dialect} jet.SerializeForProjection(projection, jet.SelectStatementType, &out) assert.DeepEqual(t, out.Buff.String(), query) assert.DeepEqual(t, out.Args, args) } +// 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) { defer func() { r := recover() diff --git a/internal/testutils/time_utils.go b/internal/testutils/time_utils.go index 2f83231..8348a6c 100644 --- a/internal/testutils/time_utils.go +++ b/internal/testutils/time_utils.go @@ -5,6 +5,7 @@ import ( "time" ) +// Date creates time from t string func Date(t string) *time.Time { newTime, err := time.Parse("2006-01-02", t) @@ -15,6 +16,7 @@ func Date(t string) *time.Time { return &newTime } +// TimestampWithoutTimeZone creates time from t func TimestampWithoutTimeZone(t string, precision int) *time.Time { precisionStr := "" @@ -32,6 +34,7 @@ func TimestampWithoutTimeZone(t string, precision int) *time.Time { return &newTime } +// TimeWithoutTimeZone creates time from t func TimeWithoutTimeZone(t string) *time.Time { newTime, err := time.Parse("15:04:05", t) @@ -42,6 +45,7 @@ func TimeWithoutTimeZone(t string) *time.Time { return &newTime } +// TimeWithTimeZone creates time from t func TimeWithTimeZone(t string) *time.Time { newTimez, err := time.Parse("15:04:05 -0700", t) @@ -52,6 +56,7 @@ func TimeWithTimeZone(t string) *time.Time { return &newTimez } +// TimestampWithTimeZone creates time from t func TimestampWithTimeZone(t string, precision int) *time.Time { precisionStr := "" diff --git a/internal/utils/utils.go b/internal/utils/utils.go index 7305a3d..9694cbb 100644 --- a/internal/utils/utils.go +++ b/internal/utils/utils.go @@ -142,7 +142,7 @@ func FormatTimestamp(t time.Time) []byte { return b } -// IsNill check if v is nil +// IsNil check if v is nil func IsNil(v interface{}) bool { return v == nil || (reflect.ValueOf(v).Kind() == reflect.Ptr && reflect.ValueOf(v).IsNil()) } diff --git a/mysql/delete_statement.go b/mysql/delete_statement.go index cd0c2d1..4242813 100644 --- a/mysql/delete_statement.go +++ b/mysql/delete_statement.go @@ -12,7 +12,7 @@ type DeleteStatement interface { } type deleteStatementImpl struct { - jet.StatementImpl + jet.SerializerStatement Delete jet.ClauseStatementBegin Where jet.ClauseWhere @@ -22,7 +22,7 @@ type deleteStatementImpl struct { func newDeleteStatement(table Table) DeleteStatement { newDelete := &deleteStatementImpl{} - newDelete.StatementImpl = jet.NewStatementImpl(Dialect, jet.DeleteStatementType, newDelete, &newDelete.Delete, + newDelete.SerializerStatement = jet.NewStatementImpl(Dialect, jet.DeleteStatementType, newDelete, &newDelete.Delete, &newDelete.Where, &newDelete.OrderBy, &newDelete.Limit) newDelete.Delete.Name = "DELETE FROM" diff --git a/mysql/dialect.go b/mysql/dialect.go index 673b73d..d93081c 100644 --- a/mysql/dialect.go +++ b/mysql/dialect.go @@ -33,7 +33,7 @@ func newDialect() jet.Dialect { } func mysql_BIT_XOR(expressions ...jet.Expression) jet.SerializeFunc { - return func(statement jet.StatementType, out *jet.SqlBuilder, options ...jet.SerializeOption) { + return func(statement jet.StatementType, out *jet.SQLBuilder, options ...jet.SerializeOption) { if len(expressions) < 2 { panic("jet: invalid number of expressions for operator XOR") } @@ -50,7 +50,7 @@ func mysql_BIT_XOR(expressions ...jet.Expression) jet.SerializeFunc { } func mysql_CONCAT_operator(expressions ...jet.Expression) jet.SerializeFunc { - return func(statement jet.StatementType, out *jet.SqlBuilder, options ...jet.SerializeOption) { + return func(statement jet.StatementType, out *jet.SQLBuilder, options ...jet.SerializeOption) { if len(expressions) < 2 { panic("jet: invalid number of expressions for operator CONCAT") } @@ -67,7 +67,7 @@ func mysql_CONCAT_operator(expressions ...jet.Expression) jet.SerializeFunc { } func mysql_DIVISION(expressions ...jet.Expression) jet.SerializeFunc { - return func(statement jet.StatementType, out *jet.SqlBuilder, options ...jet.SerializeOption) { + return func(statement jet.StatementType, out *jet.SQLBuilder, options ...jet.SerializeOption) { if len(expressions) < 2 { panic("jet: invalid number of expressions for operator DIV") } @@ -91,7 +91,7 @@ func mysql_DIVISION(expressions ...jet.Expression) jet.SerializeFunc { } func mysql_IS_NOT_DISTINCT_FROM(expressions ...jet.Expression) jet.SerializeFunc { - return func(statement jet.StatementType, out *jet.SqlBuilder, options ...jet.SerializeOption) { + return func(statement jet.StatementType, out *jet.SQLBuilder, options ...jet.SerializeOption) { if len(expressions) < 2 { panic("jet: invalid number of expressions for operator") } @@ -103,7 +103,7 @@ func mysql_IS_NOT_DISTINCT_FROM(expressions ...jet.Expression) jet.SerializeFunc } func mysql_IS_DISTINCT_FROM(expressions ...jet.Expression) jet.SerializeFunc { - return func(statement jet.StatementType, out *jet.SqlBuilder, options ...jet.SerializeOption) { + return func(statement jet.StatementType, out *jet.SQLBuilder, options ...jet.SerializeOption) { out.WriteString("NOT(") mysql_IS_NOT_DISTINCT_FROM(expressions...)(statement, out, options...) out.WriteString(")") @@ -111,7 +111,7 @@ func mysql_IS_DISTINCT_FROM(expressions ...jet.Expression) jet.SerializeFunc { } func mysql_REGEXP_LIKE_operator(expressions ...jet.Expression) jet.SerializeFunc { - return func(statement jet.StatementType, out *jet.SqlBuilder, options ...jet.SerializeOption) { + return func(statement jet.StatementType, out *jet.SQLBuilder, options ...jet.SerializeOption) { if len(expressions) < 2 { panic("jet: invalid number of expressions for operator") } @@ -137,7 +137,7 @@ func mysql_REGEXP_LIKE_operator(expressions ...jet.Expression) jet.SerializeFunc } func mysql_NOT_REGEXP_LIKE_operator(expressions ...jet.Expression) jet.SerializeFunc { - return func(statement jet.StatementType, out *jet.SqlBuilder, options ...jet.SerializeOption) { + return func(statement jet.StatementType, out *jet.SQLBuilder, options ...jet.SerializeOption) { if len(expressions) < 2 { panic("jet: invalid number of expressions for operator") } diff --git a/mysql/insert_statement.go b/mysql/insert_statement.go index 8639eb7..a21089c 100644 --- a/mysql/insert_statement.go +++ b/mysql/insert_statement.go @@ -18,7 +18,7 @@ type InsertStatement interface { func newInsertStatement(table Table, columns []jet.Column) InsertStatement { newInsert := &insertStatementImpl{} - newInsert.StatementImpl = jet.NewStatementImpl(Dialect, jet.InsertStatementType, newInsert, + newInsert.SerializerStatement = jet.NewStatementImpl(Dialect, jet.InsertStatementType, newInsert, &newInsert.Insert, &newInsert.ValuesQuery) newInsert.Insert.Table = table @@ -28,7 +28,7 @@ func newInsertStatement(table Table, columns []jet.Column) InsertStatement { } type insertStatementImpl struct { - jet.StatementImpl + jet.SerializerStatement Insert jet.ClauseInsert ValuesQuery jet.ClauseValuesQuery diff --git a/mysql/lock_statement.go b/mysql/lock_statement.go index ee2f9d6..20ce76b 100644 --- a/mysql/lock_statement.go +++ b/mysql/lock_statement.go @@ -17,13 +17,13 @@ func LOCK(tables ...jet.SerializerTable) LockStatement { Write: jet.ClauseOptional{Name: "WRITE"}, } - newLock.StatementImpl = jet.NewStatementImpl(Dialect, jet.LockStatementType, newLock, &newLock.Lock, &newLock.Read, &newLock.Write) + newLock.SerializerStatement = jet.NewStatementImpl(Dialect, jet.LockStatementType, newLock, &newLock.Lock, &newLock.Read, &newLock.Write) return newLock } type lockStatementImpl struct { - jet.StatementImpl + jet.SerializerStatement Lock jet.ClauseStatementBegin Read jet.ClauseOptional @@ -46,12 +46,12 @@ func UNLOCK_TABLES() Statement { Unlock: jet.ClauseStatementBegin{Name: "UNLOCK TABLES"}, } - newUnlock.StatementImpl = jet.NewStatementImpl(Dialect, jet.UnLockStatementType, newUnlock, &newUnlock.Unlock) + newUnlock.SerializerStatement = jet.NewStatementImpl(Dialect, jet.UnLockStatementType, newUnlock, &newUnlock.Unlock) return newUnlock } type unlockStatementImpl struct { - jet.StatementImpl + jet.SerializerStatement Unlock jet.ClauseStatementBegin } diff --git a/mysql/select_statement.go b/mysql/select_statement.go index a6bd9e9..5622f3e 100644 --- a/mysql/select_statement.go +++ b/mysql/select_statement.go @@ -7,8 +7,8 @@ type RowLock = jet.RowLock // Row lock types var ( - UPDATE = jet.NewSelectLock("UPDATE") - SHARE = jet.NewSelectLock("SHARE") + UPDATE = jet.NewRowLock("UPDATE") + SHARE = jet.NewRowLock("SHARE") ) // SelectStatement is interface for MySQL SELECT statement @@ -41,12 +41,10 @@ func SELECT(projection Projection, projections ...Projection) SelectStatement { func newSelectStatement(table ReadableTable, projections []Projection) SelectStatement { newSelect := &selectStatementImpl{} - newSelect.ExpressionStatementImpl.StatementImpl = jet.NewStatementImpl(Dialect, jet.SelectStatementType, newSelect, &newSelect.Select, + newSelect.ExpressionStatement = jet.NewExpressionStatementImpl(Dialect, jet.SelectStatementType, newSelect, &newSelect.Select, &newSelect.From, &newSelect.Where, &newSelect.GroupBy, &newSelect.Having, &newSelect.OrderBy, &newSelect.Limit, &newSelect.Offset, &newSelect.For, &newSelect.ShareLock) - newSelect.ExpressionStatementImpl.ExpressionInterfaceImpl.Parent = newSelect - newSelect.Select.Projections = toJetProjectionList(projections) newSelect.From.Table = table newSelect.Limit.Count = -1 @@ -60,7 +58,7 @@ func newSelectStatement(table ReadableTable, projections []Projection) SelectSta } type selectStatementImpl struct { - jet.ExpressionStatementImpl + jet.ExpressionStatement setOperatorsImpl Select jet.ClauseSelect diff --git a/mysql/select_table.go b/mysql/select_table.go index 300c7a1..1ac02a8 100644 --- a/mysql/select_table.go +++ b/mysql/select_table.go @@ -4,18 +4,18 @@ import "github.com/go-jet/jet/internal/jet" // SelectTable is interface for MySQL sub-queries type SelectTable interface { - ReadableTable + readableTable jet.SelectTable } type selectTableImpl struct { - jet.SelectTableImpl + jet.SelectTable readableTableInterfaceImpl } func newSelectTable(selectStmt jet.StatementWithProjections, alias string) SelectTable { subQuery := &selectTableImpl{ - SelectTableImpl: jet.NewSelectTable(selectStmt, alias), + SelectTable: jet.NewSelectTable(selectStmt, alias), } subQuery.readableTableInterfaceImpl.parent = subQuery diff --git a/mysql/set_statement.go b/mysql/set_statement.go index 92f622e..ba14ece 100644 --- a/mysql/set_statement.go +++ b/mysql/set_statement.go @@ -47,7 +47,7 @@ func (s *setOperatorsImpl) UNION_ALL(rhs SelectStatement) setStatement { } type setStatementImpl struct { - jet.ExpressionStatementImpl + jet.ExpressionStatement setOperatorsImpl @@ -56,9 +56,8 @@ type setStatementImpl struct { func newSetStatementImpl(operator string, all bool, selects []jet.StatementWithProjections) setStatement { newSetStatement := &setStatementImpl{} - newSetStatement.ExpressionStatementImpl.StatementImpl = jet.NewStatementImpl(Dialect, jet.SetStatementType, newSetStatement, + newSetStatement.ExpressionStatement = jet.NewExpressionStatementImpl(Dialect, jet.SetStatementType, newSetStatement, &newSetStatement.setOperator) - newSetStatement.ExpressionStatementImpl.ExpressionInterfaceImpl.Parent = newSetStatement newSetStatement.setOperator.Operator = operator newSetStatement.setOperator.All = all @@ -68,8 +67,6 @@ func newSetStatementImpl(operator string, all bool, selects []jet.StatementWithP newSetStatement.setOperatorsImpl.parent = newSetStatement - newSetStatement.Clauses = []jet.Clause{&newSetStatement.setOperator} - return newSetStatement } diff --git a/mysql/table.go b/mysql/table.go index 5b30080..a4cf042 100644 --- a/mysql/table.go +++ b/mysql/table.go @@ -79,7 +79,7 @@ func (r *readableTableInterfaceImpl) CROSS_JOIN(table ReadableTable) joinSelectU // NewTable creates new table with schema Name, table Name and list of columns func NewTable(schemaName, name string, columns ...jet.ColumnExpression) Table { t := &tableImpl{ - TableImpl: jet.NewTable(schemaName, name, columns...), + SerializerTable: jet.NewTable(schemaName, name, columns...), } t.readableTableInterfaceImpl.parent = t @@ -89,7 +89,7 @@ func NewTable(schemaName, name string, columns ...jet.ColumnExpression) Table { } type tableImpl struct { - jet.TableImpl + jet.SerializerTable readableTableInterfaceImpl parent Table } @@ -110,14 +110,14 @@ func (t *tableImpl) LOCK() LockStatement { return LOCK(t.parent) } -type joinTable2 struct { +type joinTable struct { tableImpl - jet.JoinTableImpl + jet.JoinTable } func newJoinTable(lhs jet.Serializer, rhs jet.Serializer, joinType jet.JoinType, onCondition BoolExpression) Table { - newJoinTable := &joinTable2{ - JoinTableImpl: jet.NewJoinTableImpl(lhs, rhs, joinType, onCondition), + newJoinTable := &joinTable{ + JoinTable: jet.NewJoinTable(lhs, rhs, joinType, onCondition), } newJoinTable.readableTableInterfaceImpl.parent = newJoinTable diff --git a/mysql/update_statement.go b/mysql/update_statement.go index 35db0e8..ce4498f 100644 --- a/mysql/update_statement.go +++ b/mysql/update_statement.go @@ -13,7 +13,7 @@ type UpdateStatement interface { } type updateStatementImpl struct { - jet.StatementImpl + jet.SerializerStatement Update jet.ClauseUpdate Set jet.ClauseSet @@ -22,7 +22,7 @@ type updateStatementImpl struct { func newUpdateStatement(table Table, columns []jet.Column) UpdateStatement { update := &updateStatementImpl{} - update.StatementImpl = jet.NewStatementImpl(Dialect, jet.UpdateStatementType, update, &update.Update, + update.SerializerStatement = jet.NewStatementImpl(Dialect, jet.UpdateStatementType, update, &update.Update, &update.Set, &update.Where) update.Update.Table = table diff --git a/postgres/clauses.go b/postgres/clauses.go index f3cf9bd..a882b64 100644 --- a/postgres/clauses.go +++ b/postgres/clauses.go @@ -8,7 +8,7 @@ type clauseReturning struct { Projections []jet.Projection } -func (r *clauseReturning) Serialize(statementType jet.StatementType, out *jet.SqlBuilder) { +func (r *clauseReturning) Serialize(statementType jet.StatementType, out *jet.SQLBuilder) { if len(r.Projections) == 0 { return } diff --git a/postgres/delete_statement.go b/postgres/delete_statement.go index 7f636ce..b39b7c1 100644 --- a/postgres/delete_statement.go +++ b/postgres/delete_statement.go @@ -12,7 +12,7 @@ type DeleteStatement interface { } type deleteStatementImpl struct { - jet.StatementImpl + jet.SerializerStatement Delete jet.ClauseStatementBegin Where jet.ClauseWhere @@ -21,7 +21,7 @@ type deleteStatementImpl struct { func newDeleteStatement(table WritableTable) DeleteStatement { newDelete := &deleteStatementImpl{} - newDelete.StatementImpl = jet.NewStatementImpl(Dialect, jet.DeleteStatementType, newDelete, &newDelete.Delete, + newDelete.SerializerStatement = jet.NewStatementImpl(Dialect, jet.DeleteStatementType, newDelete, &newDelete.Delete, &newDelete.Where, &newDelete.Returning) newDelete.Delete.Name = "DELETE FROM" diff --git a/postgres/dialect.go b/postgres/dialect.go index 0ba8c2c..0fbfd9e 100644 --- a/postgres/dialect.go +++ b/postgres/dialect.go @@ -30,7 +30,7 @@ func newDialect() jet.Dialect { } func postgresCAST(expressions ...jet.Expression) jet.SerializeFunc { - return func(statement jet.StatementType, out *jet.SqlBuilder, options ...jet.SerializeOption) { + return func(statement jet.StatementType, out *jet.SQLBuilder, options ...jet.SerializeOption) { if len(expressions) < 2 { panic("jet: invalid number of expressions for operator") } @@ -55,7 +55,7 @@ func postgresCAST(expressions ...jet.Expression) jet.SerializeFunc { } func postgres_REGEXP_LIKE_operator(expressions ...jet.Expression) jet.SerializeFunc { - return func(statement jet.StatementType, out *jet.SqlBuilder, options ...jet.SerializeOption) { + return func(statement jet.StatementType, out *jet.SQLBuilder, options ...jet.SerializeOption) { if len(expressions) < 2 { panic("jet: invalid number of expressions for operator") } @@ -81,7 +81,7 @@ func postgres_REGEXP_LIKE_operator(expressions ...jet.Expression) jet.SerializeF } func postgres_NOT_REGEXP_LIKE_operator(expressions ...jet.Expression) jet.SerializeFunc { - return func(statement jet.StatementType, out *jet.SqlBuilder, options ...jet.SerializeOption) { + return func(statement jet.StatementType, out *jet.SQLBuilder, options ...jet.SerializeOption) { if len(expressions) < 2 { panic("jet: invalid number of expressions for operator") } diff --git a/postgres/insert_statement.go b/postgres/insert_statement.go index f75dbea..a9dee25 100644 --- a/postgres/insert_statement.go +++ b/postgres/insert_statement.go @@ -21,7 +21,7 @@ type InsertStatement interface { func newInsertStatement(table WritableTable, columns []jet.Column) InsertStatement { newInsert := &insertStatementImpl{} - newInsert.StatementImpl = jet.NewStatementImpl(Dialect, jet.InsertStatementType, newInsert, + newInsert.SerializerStatement = jet.NewStatementImpl(Dialect, jet.InsertStatementType, newInsert, &newInsert.Insert, &newInsert.ValuesQuery, &newInsert.Returning) newInsert.Insert.Table = table @@ -31,7 +31,7 @@ func newInsertStatement(table WritableTable, columns []jet.Column) InsertStateme } type insertStatementImpl struct { - jet.StatementImpl + jet.SerializerStatement Insert jet.ClauseInsert ValuesQuery jet.ClauseValuesQuery diff --git a/postgres/lock_statement.go b/postgres/lock_statement.go index 87cad6e..3473427 100644 --- a/postgres/lock_statement.go +++ b/postgres/lock_statement.go @@ -28,7 +28,7 @@ type LockStatement interface { // LOCK creates LockStatement from list of tables func LOCK(tables ...jet.SerializerTable) LockStatement { newLock := &lockStatementImpl{} - newLock.StatementImpl = jet.NewStatementImpl(Dialect, jet.LockStatementType, newLock, + newLock.SerializerStatement = jet.NewStatementImpl(Dialect, jet.LockStatementType, newLock, &newLock.StatementBegin, &newLock.In, &newLock.NoWait) newLock.StatementBegin.Name = "LOCK TABLE" @@ -38,7 +38,7 @@ func LOCK(tables ...jet.SerializerTable) LockStatement { } type lockStatementImpl struct { - jet.StatementImpl + jet.SerializerStatement StatementBegin jet.ClauseStatementBegin In jet.ClauseIn diff --git a/postgres/select_statement.go b/postgres/select_statement.go index e922550..34225e6 100644 --- a/postgres/select_statement.go +++ b/postgres/select_statement.go @@ -7,10 +7,10 @@ type RowLock = jet.RowLock // Row lock types var ( - UPDATE = jet.NewSelectLock("UPDATE") - NO_KEY_UPDATE = jet.NewSelectLock("NO KEY UPDATE") - SHARE = jet.NewSelectLock("SHARE") - KEY_SHARE = jet.NewSelectLock("KEY SHARE") + UPDATE = jet.NewRowLock("UPDATE") + NO_KEY_UPDATE = jet.NewRowLock("NO KEY UPDATE") + SHARE = jet.NewRowLock("SHARE") + KEY_SHARE = jet.NewRowLock("KEY SHARE") ) // SelectStatement is interface for PostgreSQL SELECT statement @@ -46,11 +46,15 @@ func SELECT(projection Projection, projections ...Projection) SelectStatement { func newSelectStatement(table ReadableTable, projections []Projection) SelectStatement { newSelect := &selectStatementImpl{} - newSelect.ExpressionStatementImpl.StatementImpl = jet.NewStatementImpl(Dialect, jet.SelectStatementType, newSelect, &newSelect.Select, + newSelect.ExpressionStatement = jet.NewExpressionStatementImpl(Dialect, jet.SelectStatementType, newSelect, &newSelect.Select, &newSelect.From, &newSelect.Where, &newSelect.GroupBy, &newSelect.Having, &newSelect.OrderBy, &newSelect.Limit, &newSelect.Offset, &newSelect.For) - newSelect.ExpressionStatementImpl.ExpressionInterfaceImpl.Parent = newSelect + // statementImpl = jet.NewStatementImpl(Dialect, jet.SelectStatementType, newSelect, &newSelect.Select, + // &newSelect.From, &newSelect.Where, &newSelect.GroupBy, &newSelect.Having, &newSelect.OrderBy, + // &newSelect.Limit, &newSelect.Offset, &newSelect.For) + // + //newSelect.expressionStatementImpl.expressionInterfaceImpl.Parent = newSelect newSelect.Select.Projections = toJetProjectionList(projections) newSelect.From.Table = table @@ -63,7 +67,7 @@ func newSelectStatement(table ReadableTable, projections []Projection) SelectSta } type selectStatementImpl struct { - jet.ExpressionStatementImpl + jet.ExpressionStatement setOperatorsImpl Select jet.ClauseSelect diff --git a/postgres/select_table.go b/postgres/select_table.go index 5b6ebb8..8dea4cc 100644 --- a/postgres/select_table.go +++ b/postgres/select_table.go @@ -4,18 +4,18 @@ import "github.com/go-jet/jet/internal/jet" // SelectTable is interface for MySQL sub-queries type SelectTable interface { - ReadableTable + readableTable jet.SelectTable } type selectTableImpl struct { - jet.SelectTableImpl + jet.SelectTable readableTableInterfaceImpl } func newSelectTable(selectStmt jet.StatementWithProjections, alias string) SelectTable { subQuery := &selectTableImpl{ - SelectTableImpl: jet.NewSelectTable(selectStmt, alias), + SelectTable: jet.NewSelectTable(selectStmt, alias), } subQuery.readableTableInterfaceImpl.parent = subQuery diff --git a/postgres/set_statement.go b/postgres/set_statement.go index 2dc9330..cc6d1fe 100644 --- a/postgres/set_statement.go +++ b/postgres/set_statement.go @@ -91,7 +91,7 @@ func (s *setOperatorsImpl) EXCEPT_ALL(rhs SelectStatement) setStatement { } type setStatementImpl struct { - jet.ExpressionStatementImpl + jet.ExpressionStatement setOperatorsImpl @@ -100,9 +100,8 @@ type setStatementImpl struct { func newSetStatementImpl(operator string, all bool, selects []jet.StatementWithProjections) setStatement { newSetStatement := &setStatementImpl{} - newSetStatement.ExpressionStatementImpl.StatementImpl = jet.NewStatementImpl(Dialect, jet.SetStatementType, newSetStatement, + newSetStatement.ExpressionStatement = jet.NewExpressionStatementImpl(Dialect, jet.SetStatementType, newSetStatement, &newSetStatement.setOperator) - newSetStatement.ExpressionStatementImpl.ExpressionInterfaceImpl.Parent = newSetStatement newSetStatement.setOperator.Operator = operator newSetStatement.setOperator.All = all @@ -112,8 +111,6 @@ func newSetStatementImpl(operator string, all bool, selects []jet.StatementWithP newSetStatement.setOperatorsImpl.parent = newSetStatement - newSetStatement.Clauses = []jet.Clause{&newSetStatement.setOperator} - return newSetStatement } diff --git a/postgres/table.go b/postgres/table.go index 2a4cc83..bc2f5c2 100644 --- a/postgres/table.go +++ b/postgres/table.go @@ -101,18 +101,18 @@ func (w *writableTableInterfaceImpl) LOCK() LockStatement { return LOCK(w.parent) } -type table2Impl struct { +type tableImpl struct { readableTableInterfaceImpl writableTableInterfaceImpl - jet.TableImpl + jet.SerializerTable } // NewTable creates new table with schema Name, table Name and list of columns func NewTable(schemaName, name string, columns ...jet.ColumnExpression) Table { - t := &table2Impl{ - TableImpl: jet.NewTable(schemaName, name, columns...), + t := &tableImpl{ + SerializerTable: jet.NewTable(schemaName, name, columns...), } t.readableTableInterfaceImpl.parent = t @@ -121,14 +121,14 @@ func NewTable(schemaName, name string, columns ...jet.ColumnExpression) Table { return t } -type joinTable2 struct { +type joinTable struct { readableTableInterfaceImpl - jet.JoinTableImpl + jet.JoinTable } func newJoinTable(lhs jet.Serializer, rhs jet.Serializer, joinType jet.JoinType, onCondition BoolExpression) ReadableTable { - newJoinTable := &joinTable2{ - JoinTableImpl: jet.NewJoinTableImpl(lhs, rhs, joinType, onCondition), + newJoinTable := &joinTable{ + JoinTable: jet.NewJoinTable(lhs, rhs, joinType, onCondition), } newJoinTable.readableTableInterfaceImpl.parent = newJoinTable diff --git a/postgres/update_statement.go b/postgres/update_statement.go index 4fff979..6d54eb5 100644 --- a/postgres/update_statement.go +++ b/postgres/update_statement.go @@ -16,7 +16,7 @@ type UpdateStatement interface { } type updateStatementImpl struct { - jet.StatementImpl + jet.SerializerStatement Update jet.ClauseUpdate Set clauseSet @@ -26,7 +26,7 @@ type updateStatementImpl struct { func newUpdateStatement(table WritableTable, columns []jet.Column) UpdateStatement { update := &updateStatementImpl{} - update.StatementImpl = jet.NewStatementImpl(Dialect, jet.UpdateStatementType, update, &update.Update, + update.SerializerStatement = jet.NewStatementImpl(Dialect, jet.UpdateStatementType, update, &update.Update, &update.Set, &update.Where, &update.Returning) update.Update.Table = table @@ -61,7 +61,7 @@ type clauseSet struct { Values []jet.Serializer } -func (s *clauseSet) Serialize(statementType jet.StatementType, out *jet.SqlBuilder) { +func (s *clauseSet) Serialize(statementType jet.StatementType, out *jet.SQLBuilder) { out.NewLine() out.WriteString("SET") diff --git a/tests/dbconfig/dbconfig.go b/tests/dbconfig/dbconfig.go index 6ff4195..cf48420 100644 --- a/tests/dbconfig/dbconfig.go +++ b/tests/dbconfig/dbconfig.go @@ -22,4 +22,5 @@ const ( MySQLPassword = "jet" ) +// MySQLConnectionString is MySQL driver connection string to test database var MySQLConnectionString = fmt.Sprintf("%s:%s@tcp(%s:%d)/", MySQLUser, MySQLPassword, MySqLHost, MySQLPort)