Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions delete_sql.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
// DeleteSQL builder.
type DeleteSQL struct {
fieldSQL FieldSQL
querySQL QuerySQL
filterSQL FilterSQL
}

Expand All @@ -19,7 +20,7 @@ func (ds DeleteSQL) Build(table string, filter rel.FilterQuery) (string, []inter

if !filter.None() {
buffer.WriteString(" WHERE ")
ds.filterSQL.Write(&buffer, filter)
ds.filterSQL.Write(&buffer, filter, ds.querySQL)
}

buffer.WriteString(";")
Expand All @@ -28,9 +29,10 @@ func (ds DeleteSQL) Build(table string, filter rel.FilterQuery) (string, []inter
}

// NewDeleteSQL builder.
func NewDeleteSQL(fieldSQL FieldSQL, filterSQL FilterSQL) DeleteSQL {
func NewDeleteSQL(fieldSQL FieldSQL, querySQL QuerySQL, filterSQL FilterSQL) DeleteSQL {
return DeleteSQL{
fieldSQL: fieldSQL,
querySQL: querySQL,
filterSQL: filterSQL,
}
}
55 changes: 42 additions & 13 deletions filter_sql.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,22 @@ type FilterSQL struct {
}

// Write SQL to buffer.
func (fs FilterSQL) Write(buffer *buffer, filter rel.FilterQuery) {
func (fs FilterSQL) Write(buffer *buffer, filter rel.FilterQuery, qs QuerySQL) {
switch filter.Type {
case rel.FilterAndOp:
fs.BuildLogical(buffer, "AND", filter.Inner)
fs.BuildLogical(buffer, "AND", filter.Inner, qs)
case rel.FilterOrOp:
fs.BuildLogical(buffer, "OR", filter.Inner)
fs.BuildLogical(buffer, "OR", filter.Inner, qs)
case rel.FilterNotOp:
buffer.WriteString("NOT ")
fs.BuildLogical(buffer, "AND", filter.Inner)
fs.BuildLogical(buffer, "AND", filter.Inner, qs)
case rel.FilterEqOp,
rel.FilterNeOp,
rel.FilterLtOp,
rel.FilterLteOp,
rel.FilterGtOp,
rel.FilterGteOp:
fs.BuildComparison(buffer, filter)
fs.BuildComparison(buffer, filter, qs)
case rel.FilterNilOp:
buffer.WriteString(fs.fieldSQL.Build(filter.Field))
buffer.WriteString(" IS NULL")
Expand All @@ -34,7 +34,7 @@ func (fs FilterSQL) Write(buffer *buffer, filter rel.FilterQuery) {
buffer.WriteString(" IS NOT NULL")
case rel.FilterInOp,
rel.FilterNinOp:
fs.BuildInclusion(buffer, filter)
fs.BuildInclusion(buffer, filter, qs)
case rel.FilterLikeOp:
buffer.WriteString(fs.fieldSQL.Build(filter.Field))
buffer.WriteString(" LIKE ")
Expand All @@ -50,7 +50,7 @@ func (fs FilterSQL) Write(buffer *buffer, filter rel.FilterQuery) {
}

// BuildLogical SQL to buffer.
func (fs FilterSQL) BuildLogical(buffer *buffer, op string, inner []rel.FilterQuery) {
func (fs FilterSQL) BuildLogical(buffer *buffer, op string, inner []rel.FilterQuery, qs QuerySQL) {
var (
length = len(inner)
)
Expand All @@ -60,7 +60,7 @@ func (fs FilterSQL) BuildLogical(buffer *buffer, op string, inner []rel.FilterQu
}

for i, c := range inner {
fs.Write(buffer, c)
fs.Write(buffer, c, qs)

if i < length-1 {
buffer.WriteByte(' ')
Expand All @@ -75,7 +75,7 @@ func (fs FilterSQL) BuildLogical(buffer *buffer, op string, inner []rel.FilterQu
}

// BuildComparison SQL to buffer.
func (fs FilterSQL) BuildComparison(buffer *buffer, filter rel.FilterQuery) {
func (fs FilterSQL) BuildComparison(buffer *buffer, filter rel.FilterQuery, qs QuerySQL) {
buffer.WriteString(fs.fieldSQL.Build(filter.Field))

switch filter.Type {
Expand All @@ -93,23 +93,45 @@ func (fs FilterSQL) BuildComparison(buffer *buffer, filter rel.FilterQuery) {
buffer.WriteString(">=")
}

buffer.WriteValue(filter.Value)
switch v := filter.Value.(type) {
case rel.SubQuery:
// For warped sub-queries
fs.buildSubQuery(buffer, v, qs)
case rel.Query:
// For sub-queries without warp
fs.buildSubQuery(buffer, rel.SubQuery{Query: v}, qs)
default:
// For simple values
buffer.WriteValue(filter.Value)
}
}

// BuildInclusion SQL to buffer.
func (fs FilterSQL) BuildInclusion(buffer *buffer, filter rel.FilterQuery) {
func (fs FilterSQL) BuildInclusion(buffer *buffer, filter rel.FilterQuery, qs QuerySQL) {
var (
values = filter.Value.([]interface{})
)

buffer.WriteString(fs.fieldSQL.Build(filter.Field))

if filter.Type == rel.FilterInOp {
buffer.WriteString(" IN (")
buffer.WriteString(" IN ")
} else {
buffer.WriteString(" NOT IN (")
buffer.WriteString(" NOT IN ")
}

fs.buildInclusionValues(buffer, values, qs)
}

func (fs *FilterSQL) buildInclusionValues(buffer *buffer, values []interface{}, qs QuerySQL) {
if len(values) == 1 {
if value, ok := values[0].(rel.Query); ok {
fs.buildSubQuery(buffer, rel.SubQuery{Query: value}, qs)
return
}
}

buffer.WriteByte('(')
for i := 0; i < len(values); i++ {
if i > 0 {
buffer.WriteByte(',')
Expand All @@ -119,6 +141,13 @@ func (fs FilterSQL) BuildInclusion(buffer *buffer, filter rel.FilterQuery) {
buffer.WriteByte(')')
}

func (fs FilterSQL) buildSubQuery(buffer *buffer, sub rel.SubQuery, qs QuerySQL) {
buffer.WriteString(sub.Prefix)
buffer.WriteByte('(')
qs.Write(buffer, sub.Query)
buffer.WriteByte(')')
}

// NewFilterSQL builder.
func NewFilterSQL(fieldSQL FieldSQL) FilterSQL {
return FilterSQL{
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ go 1.16

require (
github.com/denisenkom/go-mssqldb v0.9.0
github.com/go-rel/rel v0.12.0
github.com/go-rel/rel v0.12.1-0.20210401230812-23ab585f43ad
github.com/stretchr/objx v0.3.0 // indirect
github.com/stretchr/testify v1.7.0
)
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ github.com/denisenkom/go-mssqldb v0.9.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27N
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/go-rel/rel v0.12.0 h1:C3r8YSwjqcXFtdANY8eB9nkMD0cfwThqnQdesmVt5s8=
github.com/go-rel/rel v0.12.0/go.mod h1:XgnuQgSs6iSOQaZ+fp+uz4GdYsdyKcnAKkc0WhkXVJI=
github.com/go-rel/rel v0.12.1-0.20210401230812-23ab585f43ad h1:GWwTNkaLp5g1284FgZxf7CvktOjLIsx/l79F3WZbgoc=
github.com/go-rel/rel v0.12.1-0.20210401230812-23ab585f43ad/go.mod h1:XgnuQgSs6iSOQaZ+fp+uz4GdYsdyKcnAKkc0WhkXVJI=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY=
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
Expand Down
6 changes: 2 additions & 4 deletions mssql.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ func new(db *db.DB, tx *db.Tx, savepoint int) rel.Adapter {
applyAdapter = NewApplyAdapter(execAdapter, NewApplyTableSQL(fieldSQL, mapColumn), NewApplyIndexSQL(fieldSQL))
insertAdapter = NewInsertAdapter(connectionAdapter, NewInsertSQL(fieldSQL))
insertAllAdapter = NewInsertAllAdapter(connectionAdapter, NewInsertAllSQL(fieldSQL))
updateAdapter = NewUpdateAdapter(execAdapter, NewUpdateSQL(fieldSQL, filterSQL))
deleteAdapter = NewDeleteAdapter(execAdapter, NewDeleteSQL(fieldSQL, filterSQL))
updateAdapter = NewUpdateAdapter(execAdapter, NewUpdateSQL(fieldSQL, querySQL, filterSQL))
deleteAdapter = NewDeleteAdapter(execAdapter, NewDeleteSQL(fieldSQL, querySQL, filterSQL))
)

return Adapter{
Expand Down Expand Up @@ -151,8 +151,6 @@ func mapColumn(column *rel.Column) (string, int, int) {
case rel.Time:
typ = "TIME"
timeLayout = "15:04:05"
case rel.Timestamp:
typ = "TIMESTAMP"
default:
typ = string(column.Type)
}
Expand Down
1 change: 1 addition & 0 deletions mssql_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ func TestAdapter_specs(t *testing.T) {
// Query Specs
specs.Query(t, repo)
specs.QueryJoin(t, repo)
specs.QueryWhereSubQuery(t, repo)
specs.QueryNotFound(t, repo)

// Preload specs
Expand Down
26 changes: 16 additions & 10 deletions query_sql.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,27 @@ type QuerySQL struct {

// Build SQL string and it arguments.
func (qs QuerySQL) Build(query rel.Query) (string, []interface{}) {
var buffer buffer
qs.Write(&buffer, query)
buffer.WriteString(";")

return buffer.String(), buffer.Arguments()
}

// Write SQL to buffer.
func (qs QuerySQL) Write(buffer *buffer, query rel.Query) {
if query.SQLQuery.Statement != "" {
return query.SQLQuery.Statement, query.SQLQuery.Values
buffer.WriteString(query.SQLQuery.Statement)
buffer.AddArguments(query.SQLQuery.Values...)
return
}

if len(query.SortQuery) == 0 && query.OffsetQuery > 0 && query.LimitQuery > 0 {
query = query.Sort("^1")
}

var buffer buffer
qs.BuildSelect(&buffer, query.SelectQuery, query.LimitQuery, query.OffsetQuery)
qs.BuildQuery(&buffer, query)

return buffer.String(), buffer.Arguments()
qs.BuildSelect(buffer, query.SelectQuery, query.LimitQuery, query.OffsetQuery)
qs.BuildQuery(buffer, query)
}

// BuildSelect SQL to buffer.
Expand Down Expand Up @@ -77,8 +85,6 @@ func (qs QuerySQL) BuildQuery(buffer *buffer, query rel.Query) {
buffer.WriteByte(' ')
buffer.WriteString(string(query.LockQuery))
}

buffer.WriteString(";")
}

// BuildFrom SQL to buffer.
Expand Down Expand Up @@ -128,7 +134,7 @@ func (qs QuerySQL) BuildWhere(buffer *buffer, filter rel.FilterQuery) {
}

buffer.WriteString(" WHERE ")
qs.filterSQL.Write(buffer, filter)
qs.filterSQL.Write(buffer, filter, qs)
}

// BuildGroupBy SQL to buffer.
Expand All @@ -152,7 +158,7 @@ func (qs QuerySQL) BuildHaving(buffer *buffer, filter rel.FilterQuery) {
}

buffer.WriteString(" HAVING ")
qs.filterSQL.Write(buffer, filter)
qs.filterSQL.Write(buffer, filter, qs)
}

// BuildOrderBy SQL to buffer.
Expand Down
6 changes: 4 additions & 2 deletions update_sql.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
// UpdateSQL builder.
type UpdateSQL struct {
fieldSQL FieldSQL
querySQL QuerySQL
filterSQL FilterSQL
}

Expand Down Expand Up @@ -50,7 +51,7 @@ func (us UpdateSQL) Build(table string, primaryField string, mutates map[string]

if !filter.None() {
buffer.WriteString(" WHERE ")
us.filterSQL.Write(&buffer, filter)
us.filterSQL.Write(&buffer, filter, us.querySQL)
}

buffer.WriteString(";")
Expand All @@ -59,9 +60,10 @@ func (us UpdateSQL) Build(table string, primaryField string, mutates map[string]
}

// NewUpdateSQL builder.
func NewUpdateSQL(fieldSQL FieldSQL, filterSQL FilterSQL) UpdateSQL {
func NewUpdateSQL(fieldSQL FieldSQL, querySQL QuerySQL, filterSQL FilterSQL) UpdateSQL {
return UpdateSQL{
fieldSQL: fieldSQL,
querySQL: querySQL,
filterSQL: filterSQL,
}
}