bob/create_table.go

239 lines
6.5 KiB
Go

package bob
import (
"errors"
"strings"
"github.com/lann/builder"
)
type CreateBuilder builder.Builder
type createData struct {
TableName string
IfNotExists bool
Schema string
Columns []ColumnDef
}
type ColumnDef struct {
Name string
Type string
Extras []string
}
func init() {
builder.Register(CreateBuilder{}, createData{})
}
// name sets the table name
func (b CreateBuilder) name(name string) CreateBuilder {
return builder.Set(b, "TableName", name).(CreateBuilder)
}
// ifNotExists adds IF NOT EXISTS to the query
func (b CreateBuilder) ifNotExists() CreateBuilder {
return builder.Set(b, "IfNotExists", true).(CreateBuilder)
}
// WithSchema specifies the schema to be used when using the schema-building commands.
func (b CreateBuilder) WithSchema(name string) CreateBuilder {
return builder.Set(b, "Schema", name).(CreateBuilder)
}
// StringColumn creates a column with VARCHAR(255) data type.
// For SQLite please refer to TextColumn.
func (b CreateBuilder) StringColumn(name string, extras ...string) CreateBuilder {
return builder.Append(b, "Columns", ColumnDef{
Name: name,
Type: "VARCHAR(255)",
Extras: extras,
}).(CreateBuilder)
}
// TextColumn creates a column with TEXT data type
func (b CreateBuilder) TextColumn(name string, extras ...string) CreateBuilder {
return builder.Append(b, "Columns", ColumnDef{
Name: name,
Type: "TEXT",
Extras: extras,
}).(CreateBuilder)
}
// UUIDColumn only available for PostgreSQL
func (b CreateBuilder) UUIDColumn(name string, extras ...string) CreateBuilder {
return builder.Append(b, "Columns", ColumnDef{
Name: name,
Type: "UUID",
Extras: extras,
}).(CreateBuilder)
}
// BooleanColumn only available for PostgreSQL
func (b CreateBuilder) BooleanColumn(name string, extras ...string) CreateBuilder {
return builder.Append(b, "Columns", ColumnDef{
Name: name,
Type: "BOOLEAN",
Extras: extras,
}).(CreateBuilder)
}
// IntegerColumn only available for PostgreSQL and SQLite.
// For MySQL and MSSQL, please refer to IntColumn,
func (b CreateBuilder) IntegerColumn(name string, extras ...string) CreateBuilder {
return builder.Append(b, "Columns", ColumnDef{
Name: name,
Type: "INTEGER",
Extras: extras,
}).(CreateBuilder)
}
// IntColumn only available for MySQL and MSSQL.
// For PostgreSQL and SQLite please refer to IntegerColumn.
func (b CreateBuilder) IntColumn(name string, extras ...string) CreateBuilder {
return builder.Append(b, "Columns", ColumnDef{
Name: name,
Type: "INT",
Extras: extras,
}).(CreateBuilder)
}
// RealColumn only available for MSSQL, PostgreSQL, and SQLite.
// For MySQL, please refer to FloatColumn, or create your own with AddColumn() with Type: "DOUBLE".
func (b CreateBuilder) RealColumn(name string, extras ...string) CreateBuilder {
return builder.Append(b, "Columns", ColumnDef{
Name: name,
Type: "REAL",
Extras: extras,
}).(CreateBuilder)
}
// FloatColumn only available for MySQL and MSSQL.
// For PostgreSQL and SQLite, please refer to RealColumn.
func (b CreateBuilder) FloatColumn(name string, extras ...string) CreateBuilder {
return builder.Append(b, "Columns", ColumnDef{
Name: name,
Type: "FLOAT",
Extras: extras,
}).(CreateBuilder)
}
func (b CreateBuilder) DateTimeColumn(name string, extras ...string) CreateBuilder {
return builder.Append(b, "Columns", ColumnDef{
Name: name,
Type: "DATETIME",
Extras: extras,
}).(CreateBuilder)
}
func (b CreateBuilder) TimeStampColumn(name string, extras ...string) CreateBuilder {
return builder.Append(b, "Columns", ColumnDef{
Name: name,
Type: "TIMESTAMP",
Extras: extras,
}).(CreateBuilder)
}
func (b CreateBuilder) TimeColumn(name string, extras ...string) CreateBuilder {
return builder.Append(b, "Columns", ColumnDef{
Name: name,
Type: "TIME",
Extras: extras,
}).(CreateBuilder)
}
func (b CreateBuilder) DateColumn(name string, extras ...string) CreateBuilder {
return builder.Append(b, "Columns", ColumnDef{
Name: name,
Type: "DATE",
Extras: extras,
}).(CreateBuilder)
}
// JSONColumn only available for MySQL and PostgreSQL.
// For MSSQL please use AddColumn(bob.ColumnDef{Name: "name", Type: "NVARCHAR(1000)"}).
// Not supported for SQLite.
func (b CreateBuilder) JSONColumn(name string, extras ...string) CreateBuilder {
return builder.Append(b, "Columns", ColumnDef{
Name: name,
Type: "JSON",
Extras: extras,
}).(CreateBuilder)
}
// JSONBColumn only available for PostgreSQL.
// For MySQL please refer to JSONColumn.
func (b CreateBuilder) JSONBColumn(name string, extras ...string) CreateBuilder {
return builder.Append(b, "Columns", ColumnDef{
Name: name,
Type: "JSONB",
Extras: extras,
}).(CreateBuilder)
}
// BlobColumn only available for MySQL and SQLite.
// For PostgreSQL and MSSQL, please use AddColumn(bob.ColumnDef{Name: "name", Type: "BYTEA"}).
func (b CreateBuilder) BlobColumn(name string, extras ...string) CreateBuilder {
return builder.Append(b, "Columns", ColumnDef{
Name: name,
Type: "BLOB",
Extras: extras,
}).(CreateBuilder)
}
// AddColumn sets custom columns
func (b CreateBuilder) AddColumn(column ColumnDef) CreateBuilder {
return builder.Append(b, "Columns", column).(CreateBuilder)
}
// ToSql returns 3 variables filled out with the correct values based on bindings, etc.
func (b CreateBuilder) ToSql() (string, []interface{}, error) {
data := builder.GetStruct(b).(createData)
return data.ToSql()
}
// ToSql returns 3 variables filled out with the correct values based on bindings, etc.
func (d *createData) ToSql() (sqlStr string, args []interface{}, err error) {
if len(d.TableName) == 0 || d.TableName == "" {
err = errors.New("create statements must specify a table")
return
}
if len(d.Columns) == 0 {
err = errors.New("a table should at least have one column")
return
}
var sql strings.Builder
sql.WriteString("CREATE TABLE ")
if d.IfNotExists {
sql.WriteString("IF NOT EXISTS ")
}
if d.Schema != "" {
sql.WriteString("\"" + d.Schema + "\".")
}
sql.WriteString("\"" + d.TableName + "\"")
sql.WriteString(" ")
var columnTypes []string
for i := 0; i < len(d.Columns); i++ {
var column []string
column = append(column, "\""+d.Columns[i].Name+"\" "+d.Columns[i].Type)
if len(d.Columns[i].Extras) > 0 {
column = append(column, strings.Join(d.Columns[i].Extras, " "))
}
columnTypes = append(columnTypes, strings.Join(column, " "))
}
sql.WriteString("(")
sql.WriteString(strings.Join(columnTypes, ", "))
sql.WriteString(");")
sqlStr = sql.String()
return
}