feat: drop cascade & restrict

This commit is contained in:
Reinaldy Rafli 2021-11-05 12:06:47 +07:00
parent efa752f2ab
commit 8a461fef1a
No known key found for this signature in database
GPG Key ID: CFDB9400255D8CB6
10 changed files with 134 additions and 77 deletions

View File

@ -9,7 +9,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
go-version: [1.15.x, 1.16.x]
go-version: [1.16.x, 1.17.x]
steps:
- name: Checkout code
uses: actions/checkout@v2

View File

@ -14,7 +14,7 @@ jobs:
- name: Install Go
uses: actions/setup-go@v2
with:
go-version: 1.16.x
go-version: 1.17.x
- name: Run coverage
run: go test -v -race -coverprofile=coverage.out -covermode=atomic -failfast

View File

@ -89,11 +89,28 @@ func main() {
if err != nil {
log.Fatal(err)
}
// sql = "DROP TABLE users;"
sql, _, err = bob.DropTableIfExists("users").ToSql()
if err != nil {
log.Fatal(err)
}
// sql = "DROP TABLE IF EXISTS users;"
sql, _, err = bob.DropTable("users").Cascade().ToSql()
if err != nil {
log.Fatal(err)
}
// sql = "DROP TABLE users CASCADE;"
sql, _, err = bob.DropTable("users").Restrict().ToSql()
if err != nil {
log.Fatal(err)
}
// sql = "DROP TABLE users RESTRICT;"
}
```
You could also do `bob.DropTableIfExists("users")` to output a `DROP TABLE IF EXISTS "users"` query.
### Truncate table
```go

24
drop.go
View File

@ -1,8 +1,8 @@
package bob
import (
"bytes"
"errors"
"strings"
"github.com/lann/builder"
)
@ -12,6 +12,8 @@ type DropBuilder builder.Builder
type dropData struct {
TableName string
IfExists bool
Cascade bool
Restrict bool
}
func init() {
@ -27,6 +29,14 @@ func (b DropBuilder) ifExists() DropBuilder {
return builder.Set(b, "IfExists", true).(DropBuilder)
}
func (b DropBuilder) Cascade() DropBuilder {
return builder.Set(b, "Cascade", true).(DropBuilder)
}
func (b DropBuilder) Restrict() DropBuilder {
return builder.Set(b, "Restrict", true).(DropBuilder)
}
// ToSql returns 3 variables filled out with the correct values based on bindings, etc.
func (b DropBuilder) ToSql() (string, []interface{}, error) {
data := builder.GetStruct(b).(dropData)
@ -38,7 +48,7 @@ func (d *dropData) ToSql() (sqlStr string, args []interface{}, err error) {
if len(d.TableName) == 0 || d.TableName == "" {
err = errors.New("drop statement must specify a table")
}
sql := &bytes.Buffer{}
var sql strings.Builder
sql.WriteString("DROP TABLE ")
@ -46,7 +56,15 @@ func (d *dropData) ToSql() (sqlStr string, args []interface{}, err error) {
sql.WriteString("IF EXISTS ")
}
sql.WriteString("\"" + d.TableName + "\";")
sql.WriteString("\"" + d.TableName + "\"")
if d.Cascade {
sql.WriteString(" CASCADE")
} else if d.Restrict {
sql.WriteString(" RESTRICT")
}
sql.WriteString(";")
sqlStr = sql.String()
return

View File

@ -6,35 +6,57 @@ import (
"github.com/aldy505/bob"
)
func TestDrop(t *testing.T) {
t.Run("should be able to create regular drop query", func(t *testing.T) {
sql, _, err := bob.DropTable("users").ToSql()
if err != nil {
t.Error(err)
}
func TestDrop_Regular(t *testing.T) {
sql, _, err := bob.DropTable("users").ToSql()
if err != nil {
t.Error(err)
}
result := "DROP TABLE \"users\";"
if sql != result {
t.Error("sql is not the same as result: ", sql)
}
})
t.Run("should be able to create drop if exists query", func(t *testing.T) {
sql, _, err := bob.DropTableIfExists("users").ToSql()
if err != nil {
t.Error(err)
}
result := "DROP TABLE IF EXISTS \"users\";"
if sql != result {
t.Error("sql is not the same as result: ", sql)
}
})
t.Run("should expect an error for no table name", func(t *testing.T) {
_, _, err := bob.DropTableIfExists("").ToSql()
if err == nil && err.Error() != "drop statement must specify a table" {
t.Error(err)
}
})
result := "DROP TABLE \"users\";"
if sql != result {
t.Error("sql is not the same as result: ", sql)
}
}
func TestDrop_IfExists(t *testing.T) {
sql, _, err := bob.DropTableIfExists("users").ToSql()
if err != nil {
t.Error(err)
}
result := "DROP TABLE IF EXISTS \"users\";"
if sql != result {
t.Error("sql is not the same as result: ", sql)
}
}
func TestDrop_Cascade(t *testing.T) {
sql, _, err := bob.DropTable("users").Cascade().ToSql()
if err != nil {
t.Error(err)
}
result := "DROP TABLE \"users\" CASCADE;"
if sql != result {
t.Error("sql is not the same as result: ", sql)
}
}
func TestDrop_Restrict(t *testing.T) {
sql, _, err := bob.DropTable("users").Restrict().ToSql()
if err != nil {
t.Error(err)
}
result := "DROP TABLE \"users\" RESTRICT;"
if sql != result {
t.Error("sql is not the same as result: ", sql)
}
}
func TestDrop_ErrNoTable(t *testing.T) {
_, _, err := bob.DropTableIfExists("").ToSql()
if err == nil && err.Error() != "drop statement must specify a table" {
t.Error(err)
}
}

2
go.mod
View File

@ -1,6 +1,6 @@
module github.com/aldy505/bob
go 1.16
go 1.17
require (
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0

9
has.go
View File

@ -4,7 +4,6 @@ import (
"bytes"
"errors"
"github.com/aldy505/bob/util"
"github.com/lann/builder"
)
@ -21,12 +20,14 @@ func init() {
builder.Register(HasBuilder{}, hasData{})
}
// HasTable checks for a table's existence by tableName, resolving with a boolean to signal if the table exists.
// HasTable checks for a table's existence by tableName,
// resolving with a boolean to signal if the table exists.
func (h HasBuilder) HasTable(table string) HasBuilder {
return builder.Set(h, "Name", table).(HasBuilder)
}
// HasColumn checks if a column exists in the current table, resolves the promise with a boolean, true if the column exists, false otherwise.
// HasColumn checks if a column exists in the current table,
// resolves the promise with a boolean, true if the column exists, false otherwise.
func (h HasBuilder) HasColumn(column string) HasBuilder {
return builder.Set(h, "Column", column).(HasBuilder)
}
@ -69,6 +70,6 @@ func (d *hasData) ToSql() (sqlStr string, args []interface{}, err error) {
}
sqlStr = ReplacePlaceholder(sql.String(), d.Placeholder)
args = util.CreateArgs(d.Name, d.Column, d.Schema)
args = createArgs(d.Name, d.Column, d.Schema)
return
}

34
internal.go Normal file
View File

@ -0,0 +1,34 @@
package bob
// createArgs should create an argument []interface{} for SQL query
// I'm using the idiot approach for creating args
func createArgs(keys ...interface{}) []interface{} {
var args []interface{}
for _, v := range keys {
if v == "" {
continue
}
args = append(args, v)
}
return args
}
// isIn checks if an array have a value
func isIn(arr []string, value string) bool {
for _, item := range arr {
if item == value {
return true
}
}
return false
}
// findPosition search for value position on an array
func findPosition(arr []string, value string) int {
for i, item := range arr {
if item == value {
return i
}
}
return -1
}

View File

@ -1,14 +0,0 @@
package util
// createArgs should create an argument []interface{} for SQL query
// I'm using the idiot approach for creating args
func CreateArgs(keys ...interface{}) []interface{} {
var args []interface{}
for _, v := range keys {
if v == "" {
continue
}
args = append(args, v)
}
return args
}

View File

@ -1,21 +0,0 @@
package util
// IsIn checks if an array have a value
func IsIn(arr []string, value string) bool {
for _, item := range arr {
if item == value {
return true
}
}
return false
}
// FindPosition search for value position on an array
func FindPosition(arr []string, value string) int {
for i, item := range arr {
if item == value {
return i
}
}
return -1
}