-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
25 changed files
with
1,280 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
|
||
# Created by https://www.toptal.com/developers/gitignore/api/go,vscode | ||
# Edit at https://www.toptal.com/developers/gitignore?templates=go,vscode | ||
|
||
### Go ### | ||
# Binaries for programs and plugins | ||
*.exe | ||
*.exe~ | ||
*.dll | ||
*.so | ||
*.dylib | ||
|
||
# Test binary, built with `go test -c` | ||
*.test | ||
|
||
# Output of the go coverage tool, specifically when used with LiteIDE | ||
*.out | ||
|
||
# Dependency directories (remove the comment below to include it) | ||
# vendor/ | ||
|
||
### Go Patch ### | ||
/vendor/ | ||
/Godeps/ | ||
|
||
### vscode ### | ||
.vscode/* | ||
!.vscode/settings.json | ||
!.vscode/tasks.json | ||
!.vscode/launch.json | ||
!.vscode/extensions.json | ||
*.code-workspace | ||
|
||
# End of https://www.toptal.com/developers/gitignore/api/go,vscode | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
module github.com/itagile/go-sqlb | ||
|
||
go 1.16 | ||
|
||
require github.com/stretchr/testify v1.7.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= | ||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | ||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | ||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= | ||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= | ||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= | ||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= | ||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
package sqlb | ||
|
||
import ( | ||
"strings" | ||
) | ||
|
||
// DeleteBuilder generates simple UPDATE from values | ||
type DeleteBuilder interface { | ||
Setter | ||
SQLBuilder | ||
} | ||
|
||
type deleteBuilderData struct { | ||
engine Engine | ||
table string | ||
where *predicateData | ||
} | ||
|
||
// NewDeleteBuilder constructs an DeleteBuilder with the provided ParameterPlaceholder | ||
func NewDeleteBuilder(engine Engine, table string) *deleteBuilderData { | ||
return &deleteBuilderData{ | ||
engine: engine, | ||
table: table, | ||
} | ||
} | ||
|
||
// Where for simple where condition initialization with AND operator | ||
func (d *deleteBuilderData) Where(conditions ...Condition) *predicateData { | ||
d.where = NewAnd(conditions...) | ||
return d.where | ||
} | ||
|
||
// Where for simple where condition initialization with OR operator | ||
func (d *deleteBuilderData) WhereOr(conditions ...Condition) *predicateData { | ||
d.where = NewOr(conditions...) | ||
return d.where | ||
} | ||
|
||
// Build the UPDATE command | ||
func (d *deleteBuilderData) Build() (query string, args []interface{}) { | ||
if d.table == "" { | ||
return "", nil | ||
} | ||
var sb strings.Builder | ||
sb.WriteString("DELETE FROM ") | ||
sb.WriteString(d.table) | ||
args = d.addWhere(&sb, args) | ||
return sb.String(), args | ||
} | ||
|
||
// addWhere appends WHERE clause | ||
func (d *deleteBuilderData) addWhere(sb *strings.Builder, args []interface{}) []interface{} { | ||
queryWhere, argsWhere := d.where.Build(d.engine) | ||
if len(queryWhere) > 0 { | ||
sb.WriteString("\nWHERE ") | ||
sb.WriteString(queryWhere) | ||
args = append(args, argsWhere...) | ||
} | ||
return args | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package sqlb_test | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/itagile/go-sqlb/sqlb" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestNewDeleteBuilderWithoutWhere(t *testing.T) { | ||
expected := "DELETE FROM schema.myTable" | ||
del := sqlb.NewDeleteBuilder(sqlb.DefaultEngine(), "schema.myTable") | ||
query, args := del.Build() | ||
require.Equal(t, expected, query) | ||
require.Empty(t, args) | ||
} | ||
|
||
func TestNewDeleteBuilderWithWhere(t *testing.T) { | ||
expected := `DELETE FROM schema.myTable | ||
WHERE ID = ?` | ||
del := sqlb.NewDeleteBuilder(sqlb.DefaultEngine(), "schema.myTable") | ||
del.Where(sqlb.Expr("ID").Eq(1)) | ||
query, args := del.Build() | ||
require.Equal(t, expected, query) | ||
require.Equal(t, []interface{}{1}, args) | ||
} | ||
|
||
func TestNewDeleteBuilderWithWhereOr(t *testing.T) { | ||
expected := `DELETE FROM schema.myTable | ||
WHERE Col3 LIKE ? OR Col4 = ?` | ||
del := sqlb.NewDeleteBuilder(sqlb.DefaultEngine(), "schema.myTable") | ||
del.WhereOr(sqlb.Expr("Col3").Like("like1"), sqlb.Expr("Col4").Eq(2)) | ||
query, args := del.Build() | ||
require.Equal(t, expected, query) | ||
require.Equal(t, []interface{}{"like1", 2}, args) | ||
} | ||
|
||
func TestEmptyDeleteBuilderWhenNoTableName(t *testing.T) { | ||
expected := "" | ||
ins := sqlb.NewDeleteBuilder(sqlb.DefaultEngine(), "") | ||
query, args := ins.Build() | ||
require.Equal(t, expected, query) | ||
require.Nil(t, args) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package sqlb | ||
|
||
import ( | ||
"fmt" | ||
"strings" | ||
) | ||
|
||
type Engine interface { | ||
ParameterPlaceholder | ||
ILike(expression string, like string) (query string, arg string) | ||
} | ||
|
||
type defaultEngine struct { | ||
ParameterPlaceholder | ||
} | ||
|
||
func DefaultEngine() *defaultEngine { | ||
return &defaultEngine{ | ||
ParameterPlaceholder: QuestionPlaceholderData, | ||
} | ||
} | ||
|
||
func (e *defaultEngine) ILike(expression string, like string) (query string, arg string) { | ||
if expression == "" { | ||
return "", "" | ||
} | ||
return fmt.Sprintf("UPPER(%s) LIKE %s", expression, e.Placeholder()), strings.ToUpper(like) | ||
} | ||
|
||
type postgreSQLEngine defaultEngine | ||
|
||
func PostgreSQLEngine() *postgreSQLEngine { | ||
return &postgreSQLEngine{ | ||
ParameterPlaceholder: NewDollarPlaceholder(), | ||
} | ||
} | ||
|
||
func (e *postgreSQLEngine) ILike(expression string, like string) (query string, arg string) { | ||
if expression == "" { | ||
return "", "" | ||
} | ||
return fmt.Sprintf("%s ILIKE %s", expression, e.Placeholder()), like | ||
} | ||
|
||
func ORACLEEngine() *defaultEngine { | ||
return &defaultEngine{ | ||
ParameterPlaceholder: NewColonPlaceholder(), | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package sqlb_test | ||
|
||
import ( | ||
"strings" | ||
"testing" | ||
|
||
"github.com/itagile/go-sqlb/sqlb" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestDefaultEngineILike(t *testing.T) { | ||
expected := "UPPER(Col1) LIKE ?" | ||
engine := sqlb.DefaultEngine() | ||
query, arg := engine.ILike("Col1", likeTest) | ||
require.Equal(t, expected, query) | ||
require.Equal(t, strings.ToUpper(likeTest), arg) | ||
} | ||
|
||
func TestDefaultEngineILikeEmptyExpression(t *testing.T) { | ||
expected := "" | ||
engine := sqlb.DefaultEngine() | ||
query, arg := engine.ILike("", likeTest) | ||
require.Equal(t, expected, query) | ||
require.Equal(t, expected, arg) | ||
} | ||
|
||
func TestPostgreSQLEngineILike(t *testing.T) { | ||
expected := "Col1 ILIKE $1" | ||
engine := sqlb.PostgreSQLEngine() | ||
query, arg := engine.ILike("Col1", likeTest) | ||
require.Equal(t, expected, query) | ||
require.Equal(t, likeTest, arg) | ||
} | ||
|
||
func TestPostgreSQLEngineILikeEmptyExpression(t *testing.T) { | ||
expected := "" | ||
engine := sqlb.PostgreSQLEngine() | ||
query, arg := engine.ILike("", likeTest) | ||
require.Equal(t, expected, query) | ||
require.Equal(t, expected, arg) | ||
} | ||
|
||
func TestORACLEEngineILike(t *testing.T) { | ||
expected := "UPPER(Col1) LIKE :v1" | ||
engine := sqlb.ORACLEEngine() | ||
query, arg := engine.ILike("Col1", likeTest) | ||
require.Equal(t, expected, query) | ||
require.Equal(t, strings.ToUpper(likeTest), arg) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package sqlb | ||
|
||
import "strings" | ||
|
||
type expressionData []string | ||
|
||
func Expr(expressions ...string) expressionData { | ||
return expressions | ||
} | ||
|
||
type ExpressionBuilder func(engine Engine, expression string, sb *strings.Builder) []interface{} | ||
|
||
func (e expressionData) Build(engine Engine) (query string, args []interface{}) { | ||
return BuildExpression(e, engine, func(engine Engine, expression string, sb *strings.Builder) []interface{} { | ||
sb.WriteString(expression) | ||
return nil | ||
}) | ||
} | ||
|
||
func BuildExpression(e expressionData, engine Engine, handler ExpressionBuilder) (query string, args []interface{}) { | ||
var sb strings.Builder | ||
args = make([]interface{}, 0, len(e)) | ||
enclose := false | ||
for _, expression := range e { | ||
if expression != "" { | ||
if sb.Len() > 0 { | ||
sb.WriteString(" OR ") | ||
enclose = true | ||
} | ||
argsHandler := handler(engine, expression, &sb) | ||
args = append(args, argsHandler...) | ||
} | ||
} | ||
query = sb.String() | ||
if enclose { | ||
query = "(" + query + ")" | ||
} | ||
return query, args | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package sqlb | ||
|
||
import "strings" | ||
|
||
type expresisonEqData struct { | ||
expressionData | ||
value interface{} | ||
} | ||
|
||
func (e expresisonEqData) Build(engine Engine) (query string, args []interface{}) { | ||
return BuildExpression(e.expressionData, engine, e.buildHandler) | ||
} | ||
|
||
func (e expresisonEqData) buildHandler(engine Engine, expression string, sb *strings.Builder) (args []interface{}) { | ||
sb.WriteString(expression) | ||
if e.value == nil { | ||
sb.WriteString(" IS NULL") | ||
} else { | ||
sb.WriteString(" = ") | ||
sb.WriteString(engine.Placeholder()) | ||
args = append(args, e.value) | ||
} | ||
return args | ||
} | ||
|
||
func (e expressionData) Eq(value interface{}) Condition { | ||
return &expresisonEqData{ | ||
expressionData: e, | ||
value: value, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package sqlb_test | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/itagile/go-sqlb/sqlb" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestSingleEq(t *testing.T) { | ||
expected := "Col1 = ?" | ||
expr := sqlb.Expr("Col1").Eq(1) | ||
query, args := expr.Build(sqlb.DefaultEngine()) | ||
require.Equal(t, expected, query) | ||
require.Equal(t, []interface{}{1}, args) | ||
} | ||
|
||
func TestMultipleEq(t *testing.T) { | ||
expected := "(Col1 = ? OR Col2 = ?)" | ||
expr := sqlb.Expr("Col1", "Col2").Eq(1) | ||
query, args := expr.Build(sqlb.DefaultEngine()) | ||
require.Equal(t, expected, query) | ||
require.Equal(t, []interface{}{1, 1}, args) | ||
} | ||
|
||
func TestSingleEqIsNull(t *testing.T) { | ||
expected := "Col1 IS NULL" | ||
expr := sqlb.Expr("Col1").Eq(nil) | ||
query, args := expr.Build(sqlb.DefaultEngine()) | ||
require.Equal(t, expected, query) | ||
require.Empty(t, args) | ||
} | ||
|
||
func TestMultipleEqIsNull(t *testing.T) { | ||
expected := "(Col1 IS NULL OR Col2 IS NULL)" | ||
expr := sqlb.Expr("Col1", "Col2").Eq(nil) | ||
query, args := expr.Build(sqlb.DefaultEngine()) | ||
require.Equal(t, expected, query) | ||
require.Empty(t, args) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package sqlb | ||
|
||
import "strings" | ||
|
||
type expresisonILikeData struct { | ||
expressionData | ||
like string | ||
} | ||
|
||
func (e expresisonILikeData) Build(engine Engine) (query string, args []interface{}) { | ||
return BuildExpression(e.expressionData, engine, e.buildHandler) | ||
} | ||
|
||
func (e expresisonILikeData) buildHandler(engine Engine, expression string, sb *strings.Builder) (args []interface{}) { | ||
query, arg := engine.ILike(expression, e.like) | ||
sb.WriteString(query) | ||
args = append(args, arg) | ||
return args | ||
} | ||
|
||
func (e expressionData) ILike(like string) Condition { | ||
return &expresisonILikeData{ | ||
expressionData: e, | ||
like: like, | ||
} | ||
} |
Oops, something went wrong.