From c9b01eeb67c70d2a1be031aa145c2c1acf020cf6 Mon Sep 17 00:00:00 2001 From: Reinaldy Rafli Date: Sun, 25 Jul 2021 01:35:12 +0700 Subject: [PATCH] feat: truncate rename and drop --- bob.go | 32 +++++++++++++++++++++++++++++ drop.go | 53 ++++++++++++++++++++++++++++++++++++++++++++++++ drop_test.go | 40 ++++++++++++++++++++++++++++++++++++ rename.go | 43 +++++++++++++++++++++++++++++++++++++++ rename_test.go | 28 +++++++++++++++++++++++++ truncate.go | 37 +++++++++++++++++++++++++++++++++ truncate_test.go | 28 +++++++++++++++++++++++++ 7 files changed, 261 insertions(+) create mode 100644 drop.go create mode 100644 drop_test.go create mode 100644 rename.go create mode 100644 rename_test.go create mode 100644 truncate.go create mode 100644 truncate_test.go diff --git a/bob.go b/bob.go index c25e097..47d30f4 100644 --- a/bob.go +++ b/bob.go @@ -36,6 +36,22 @@ func (b BobBuilderType) HasColumn(column string) HasBuilder { return HasBuilder(b).HasColumn(column) } +func (b BobBuilderType) DropTable(table string) DropBuilder { + return DropBuilder(b).DropTable(table) +} + +func (b BobBuilderType) DropTableIfExists(table string) DropBuilder { + return DropBuilder(b).DropTable(table).IfExists() +} + +func (b BobBuilderType) RenameTable(from, to string) RenameBuilder { + return RenameBuilder(b).From(from).To(to) +} + +func (b BobBuilderType) Truncate(table string) TruncateBuilder { + return TruncateBuilder(b).Truncate(table) +} + // BobStmtBuilder is the parent builder for BobBuilderType var BobStmtBuilder = BobBuilderType(builder.EmptyBuilder) @@ -58,3 +74,19 @@ func HasTable(table string) HasBuilder { func HasColumn(col string) HasBuilder { return BobStmtBuilder.HasColumn(col) } + +func DropTable(table string) DropBuilder { + return BobStmtBuilder.DropTable(table) +} + +func DropTableIfExists(table string) DropBuilder { + return BobStmtBuilder.DropTableIfExists(table) +} + +func RenameTable(from, to string) RenameBuilder { + return BobStmtBuilder.RenameTable(from, to) +} + +func Truncate(table string) TruncateBuilder { + return BobStmtBuilder.Truncate(table) +} \ No newline at end of file diff --git a/drop.go b/drop.go new file mode 100644 index 0000000..2311c71 --- /dev/null +++ b/drop.go @@ -0,0 +1,53 @@ +package bob + +import ( + "bytes" + "errors" + + "github.com/lann/builder" +) + +type DropBuilder builder.Builder + +type dropData struct { + TableName string + IfExists bool +} + +func init() { + builder.Register(DropBuilder{}, dropData{}) +} + +// DropTable sets which table to be dropped +func (b DropBuilder) DropTable(name string) DropBuilder { + return builder.Set(b, "TableName", name).(DropBuilder) +} + +func (b DropBuilder) IfExists() DropBuilder { + return builder.Set(b, "IfExists", 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) + return data.ToSql() +} + +// ToSql returns 3 variables filled out with the correct values based on bindings, etc. +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{} + + sql.WriteString("DROP TABLE ") + + if d.IfExists { + sql.WriteString("IF EXISTS ") + } + + sql.WriteString("\""+d.TableName+"\";") + + sqlStr = sql.String() + return +} \ No newline at end of file diff --git a/drop_test.go b/drop_test.go new file mode 100644 index 0000000..d4c7bdd --- /dev/null +++ b/drop_test.go @@ -0,0 +1,40 @@ +package bob_test + +import ( + "testing" + + "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) + } + + 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) + } + }) +} \ No newline at end of file diff --git a/rename.go b/rename.go new file mode 100644 index 0000000..1cb4c80 --- /dev/null +++ b/rename.go @@ -0,0 +1,43 @@ +package bob + +import ( + "errors" + + "github.com/lann/builder" +) + +type RenameBuilder builder.Builder + +type renameData struct { + From string + To string +} + +func init() { + builder.Register(RenameBuilder{}, renameData{}) +} + +// From sets existing table name +func (b RenameBuilder) From(name string) RenameBuilder { + return builder.Set(b, "From", name).(RenameBuilder) +} + +// To sets desired table name +func (b RenameBuilder) To(name string) RenameBuilder { + return builder.Set(b, "To", name).(RenameBuilder) +} + +// ToSql returns 3 variables filled out with the correct values based on bindings, etc. +func (b RenameBuilder) ToSql() (string, []interface{}, error) { + data := builder.GetStruct(b).(renameData) + return data.ToSql() +} + +// ToSql returns 3 variables filled out with the correct values based on bindings, etc. +func (d *renameData) ToSql() (sqlStr string, args []interface{}, err error) { + if len(d.From) == 0 || d.From == "" || len(d.To) == 0 || d.To == "" { + err = errors.New("rename statement must specify a table") + } + sqlStr = "RENAME TABLE \""+d.From+"\" TO \""+d.To+"\";" + return +} \ No newline at end of file diff --git a/rename_test.go b/rename_test.go new file mode 100644 index 0000000..05a2492 --- /dev/null +++ b/rename_test.go @@ -0,0 +1,28 @@ +package bob_test + +import ( + "testing" + + "github.com/aldy505/bob" +) + +func TestRename(t *testing.T) { + t.Run("should be able to create rename query", func (t *testing.T) { + sql, _, err := bob.RenameTable("users", "teachers").ToSql() + if err != nil { + t.Error(err) + } + + result := "RENAME TABLE \"users\" TO \"teachers\";" + 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.RenameTable("", "").ToSql() + if err == nil && err.Error() != "rename statement must specify a table" { + t.Error(err) + } + }) +} \ No newline at end of file diff --git a/truncate.go b/truncate.go new file mode 100644 index 0000000..95c39c2 --- /dev/null +++ b/truncate.go @@ -0,0 +1,37 @@ +package bob + +import ( + "errors" + + "github.com/lann/builder" +) + +type TruncateBuilder builder.Builder + +type truncateData struct { + TableName string +} + +func init() { + builder.Register(TruncateBuilder{}, truncateData{}) +} + +// Truncate sets which table to be dropped +func (b TruncateBuilder) Truncate(name string) TruncateBuilder { + return builder.Set(b, "TableName", name).(TruncateBuilder) +} + +// ToSql returns 3 variables filled out with the correct values based on bindings, etc. +func (b TruncateBuilder) ToSql() (string, []interface{}, error) { + data := builder.GetStruct(b).(truncateData) + return data.ToSql() +} + +// ToSql returns 3 variables filled out with the correct values based on bindings, etc. +func (d *truncateData) ToSql() (sqlStr string, args []interface{}, err error) { + if len(d.TableName) == 0 || d.TableName == "" { + err = errors.New("truncate statement must specify a table") + } + sqlStr = "TRUNCATE \""+d.TableName+"\";" + return +} \ No newline at end of file diff --git a/truncate_test.go b/truncate_test.go new file mode 100644 index 0000000..535bc5d --- /dev/null +++ b/truncate_test.go @@ -0,0 +1,28 @@ +package bob_test + +import ( + "testing" + + "github.com/aldy505/bob" +) + +func TestTruncate(t *testing.T) { + t.Run("should be able to create truncate query", func (t *testing.T) { + sql, _, err := bob.Truncate("users").ToSql() + if err != nil { + t.Error(err) + } + + result := "TRUNCATE \"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.Truncate("").ToSql() + if err == nil && err.Error() != "TRUNCATE statement must specify a table" { + t.Error(err) + } + }) +} \ No newline at end of file