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()
|
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
|
// HasTable checks if a table exists with HasBuilder interface
|
||||||
func (b BobBuilderType) HasTable(table string) HasBuilder {
|
func (b BobBuilderType) HasTable(table string) HasBuilder {
|
||||||
return HasBuilder(b).HasTable(table)
|
return HasBuilder(b).HasTable(table)
|
||||||
|
@ -172,3 +182,13 @@ func Truncate(table string) TruncateBuilder {
|
||||||
func Upsert(table string, dialect int) UpsertBuilder {
|
func Upsert(table string, dialect int) UpsertBuilder {
|
||||||
return BobStmtBuilder.Upsert(table, dialect)
|
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