mirror of https://github.com/aldy505/bob.git
feat: create index method
This commit is contained in:
parent
8163afaf1b
commit
070280bdf7
20
bob.go
20
bob.go
|
@ -40,6 +40,16 @@ func (b BobBuilderType) CreateTableIfNotExists(table string) CreateBuilder {
|
|||
return CreateBuilder(b).name(table).ifNotExists()
|
||||
}
|
||||
|
||||
// CreateIndex creates an index with CreateIndexBuilder interface.
|
||||
func (b BobBuilderType) CreateIndex(name string) IndexBuilder {
|
||||
return IndexBuilder(b).name(name)
|
||||
}
|
||||
|
||||
// CreateIndexIfNotExists creates an index with CreateIndexBuilder interface, if the index doesn't exists.
|
||||
func (b BobBuilderType) CreateIndexIfNotExists(name string) IndexBuilder {
|
||||
return IndexBuilder(b).name(name).ifNotExists()
|
||||
}
|
||||
|
||||
// HasTable checks if a table exists with HasBuilder interface
|
||||
func (b BobBuilderType) HasTable(table string) HasBuilder {
|
||||
return HasBuilder(b).HasTable(table)
|
||||
|
@ -172,3 +182,13 @@ func Truncate(table string) TruncateBuilder {
|
|||
func Upsert(table string, dialect int) UpsertBuilder {
|
||||
return BobStmtBuilder.Upsert(table, dialect)
|
||||
}
|
||||
|
||||
// CreateIndex creates an index with CreateIndexBuilder interface.
|
||||
func CreateIndex(name string) IndexBuilder {
|
||||
return BobStmtBuilder.CreateIndex(name)
|
||||
}
|
||||
|
||||
// CreateIndexIfNotExists creates an index with CreateIndexBuilder interface, if the index doesn't exists.
|
||||
func CreateIndexIfNotExists(name string) IndexBuilder {
|
||||
return BobStmtBuilder.CreateIndexIfNotExists(name)
|
||||
}
|
|
@ -0,0 +1,127 @@
|
|||
package bob
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"github.com/lann/builder"
|
||||
)
|
||||
|
||||
type IndexBuilder builder.Builder
|
||||
|
||||
type indexData struct {
|
||||
Unique bool
|
||||
Spatial bool
|
||||
Fulltext bool
|
||||
Name string
|
||||
TableName string
|
||||
Columns []IndexColumn
|
||||
IfNotExists bool
|
||||
}
|
||||
|
||||
type IndexColumn struct {
|
||||
Name string
|
||||
Extras []string
|
||||
Collate string
|
||||
}
|
||||
|
||||
func init() {
|
||||
builder.Register(IndexBuilder{}, indexData{})
|
||||
}
|
||||
|
||||
func (i IndexBuilder) Unique() IndexBuilder {
|
||||
return builder.Set(i, "Unique", true).(IndexBuilder)
|
||||
}
|
||||
|
||||
func (i IndexBuilder) Spatial() IndexBuilder {
|
||||
return builder.Set(i, "Spatial", true).(IndexBuilder)
|
||||
}
|
||||
|
||||
func (i IndexBuilder) Fulltext() IndexBuilder {
|
||||
return builder.Set(i, "Fulltext", true).(IndexBuilder)
|
||||
}
|
||||
|
||||
func (i IndexBuilder) name(name string) IndexBuilder {
|
||||
return builder.Set(i, "Name", name).(IndexBuilder)
|
||||
}
|
||||
|
||||
func (i IndexBuilder) ifNotExists() IndexBuilder {
|
||||
return builder.Set(i, "IfNotExists", true).(IndexBuilder)
|
||||
}
|
||||
|
||||
func (i IndexBuilder) On(table string) IndexBuilder {
|
||||
return builder.Set(i, "TableName", table).(IndexBuilder)
|
||||
}
|
||||
|
||||
func (i IndexBuilder) Columns(column IndexColumn) IndexBuilder {
|
||||
return builder.Append(i, "Columns", column).(IndexBuilder)
|
||||
}
|
||||
|
||||
func (i IndexBuilder) ToSql() (string, []interface{}, error) {
|
||||
data := builder.GetStruct(i).(indexData)
|
||||
return data.ToSql()
|
||||
}
|
||||
|
||||
func (i *indexData) ToSql() (sqlStr string, args []interface{}, err error) {
|
||||
if i.Name == "" {
|
||||
err = errors.New("index name is required on create index statement")
|
||||
return
|
||||
}
|
||||
if i.TableName == "" {
|
||||
err = errors.New("a table name must be specified on create index statement")
|
||||
return
|
||||
}
|
||||
|
||||
if len(i.Columns) == 0 {
|
||||
err = errors.New("should at least specify one column for create index statement")
|
||||
return
|
||||
}
|
||||
|
||||
var sql strings.Builder
|
||||
|
||||
sql.WriteString("CREATE ")
|
||||
|
||||
if i.Unique {
|
||||
sql.WriteString("UNIQUE ")
|
||||
}
|
||||
|
||||
if i.Fulltext {
|
||||
sql.WriteString("FULLTEXT ")
|
||||
}
|
||||
|
||||
if i.Spatial {
|
||||
sql.WriteString("SPATIAL ")
|
||||
}
|
||||
|
||||
sql.WriteString("INDEX ")
|
||||
|
||||
if i.IfNotExists {
|
||||
sql.WriteString("IF NOT EXISTS ")
|
||||
}
|
||||
|
||||
sql.WriteString(i.Name + " ")
|
||||
|
||||
sql.WriteString("ON ")
|
||||
|
||||
sql.WriteString(i.TableName + " ")
|
||||
|
||||
var columns []string
|
||||
for _, column := range i.Columns {
|
||||
var colBuilder strings.Builder
|
||||
colBuilder.WriteString(column.Name)
|
||||
if column.Collate != "" {
|
||||
colBuilder.WriteString(" COLLATE " + column.Collate)
|
||||
}
|
||||
if len(column.Extras) > 0 {
|
||||
colBuilder.WriteString(" " + strings.Join(column.Extras, " "))
|
||||
}
|
||||
columns = append(columns, colBuilder.String())
|
||||
}
|
||||
|
||||
sql.WriteString("(")
|
||||
sql.WriteString(strings.Join(columns, ", "))
|
||||
sql.WriteString(");")
|
||||
|
||||
sqlStr = sql.String()
|
||||
return
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
package bob_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/aldy505/bob"
|
||||
)
|
||||
|
||||
func TestCreateIndex(t *testing.T) {
|
||||
sql, _, err := bob.
|
||||
CreateIndexIfNotExists("email_idx").
|
||||
On("users").
|
||||
Unique().
|
||||
Spatial().
|
||||
Fulltext().
|
||||
Columns(bob.IndexColumn{Name: "email"}).
|
||||
ToSql()
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
|
||||
result := "CREATE UNIQUE FULLTEXT SPATIAL INDEX IF NOT EXISTS email_idx ON users (email);"
|
||||
if sql != result {
|
||||
t.Fatal("sql is not equal to result:", sql)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateIndex_Simple(t *testing.T) {
|
||||
sql, _, err := bob.
|
||||
CreateIndex("idx_email").
|
||||
On("users").
|
||||
Columns(bob.IndexColumn{Name: "email", Collate: "DEFAULT", Extras: []string{"ASC"}}).
|
||||
Columns(bob.IndexColumn{Name: "name", Extras: []string{"DESC"}}).
|
||||
ToSql()
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
|
||||
result := "CREATE INDEX idx_email ON users (email COLLATE DEFAULT ASC, name DESC);"
|
||||
if sql != result {
|
||||
t.Fatal("sql is not equal to result:", sql)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateIndex_Error(t *testing.T) {
|
||||
t.Run("without index", func(t *testing.T) {
|
||||
_, _, err := bob.
|
||||
CreateIndex("").
|
||||
On("users").
|
||||
Columns(bob.IndexColumn{Name: "email", Collate: "DEFAULT", Extras: []string{"ASC"}}).
|
||||
Columns(bob.IndexColumn{Name: "name", Extras: []string{"DESC"}}).
|
||||
ToSql()
|
||||
if err == nil {
|
||||
t.Fatal("error is nil")
|
||||
}
|
||||
|
||||
if err.Error() != "index name is required on create index statement" {
|
||||
t.Fatal("error is not equal to result:", err.Error())
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("without table name", func(t *testing.T) {
|
||||
_, _, err := bob.
|
||||
CreateIndex("name").
|
||||
On("").
|
||||
Columns(bob.IndexColumn{Name: "email", Collate: "DEFAULT", Extras: []string{"ASC"}}).
|
||||
Columns(bob.IndexColumn{Name: "name", Extras: []string{"DESC"}}).
|
||||
ToSql()
|
||||
if err == nil {
|
||||
t.Fatal("error is nil")
|
||||
}
|
||||
|
||||
if err.Error() != "a table name must be specified on create index statement" {
|
||||
t.Fatal("error is not equal to result:", err.Error())
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("without columns", func(t *testing.T) {
|
||||
_, _, err := bob.
|
||||
CreateIndex("name").
|
||||
On("users").
|
||||
ToSql()
|
||||
if err == nil {
|
||||
t.Fatal("error is nil")
|
||||
}
|
||||
|
||||
if err.Error() != "should at least specify one column for create index statement" {
|
||||
t.Fatal("error is not equal to result:", err.Error())
|
||||
}
|
||||
})
|
||||
}
|
Loading…
Reference in New Issue