Files
sqlbuilder/createtable.go
T

184 lines
4.9 KiB
Go

// Copyright 2018 Huan Du. All rights reserved.
// Licensed under the MIT license that can be found in the LICENSE file.
package sqlbuilder
import (
"strings"
"github.com/huandu/go-clone"
)
const (
createTableMarkerInit injectionMarker = iota
createTableMarkerAfterCreate
createTableMarkerAfterDefine
createTableMarkerAfterOption
)
// NewCreateTableBuilder creates a new CREATE TABLE builder.
func NewCreateTableBuilder() *CreateTableBuilder {
return DefaultFlavor.NewCreateTableBuilder()
}
func newCreateTableBuilder() *CreateTableBuilder {
args := &Args{}
return &CreateTableBuilder{
verb: "CREATE TABLE",
args: args,
injection: newInjection(),
marker: createTableMarkerInit,
}
}
// Clone returns a deep copy of CreateTableBuilder.
// It's useful when you want to create a base builder and clone it to build similar queries.
func (ctb *CreateTableBuilder) Clone() *CreateTableBuilder {
return clone.Clone(ctb).(*CreateTableBuilder)
}
// CreateTableBuilder is a builder to build CREATE TABLE.
type CreateTableBuilder struct {
verb string
ifNotExists bool
table string
defs [][]string
options [][]string
args *Args
injection *injection
marker injectionMarker
}
var _ Builder = new(CreateTableBuilder)
// CreateTable sets the table name in CREATE TABLE.
func CreateTable(table string) *CreateTableBuilder {
return DefaultFlavor.NewCreateTableBuilder().CreateTable(table)
}
// CreateTable sets the table name in CREATE TABLE.
func (ctb *CreateTableBuilder) CreateTable(table string) *CreateTableBuilder {
ctb.table = Escape(table)
ctb.marker = createTableMarkerAfterCreate
return ctb
}
// CreateTempTable sets the table name and changes the verb of ctb to CREATE TEMPORARY TABLE.
func (ctb *CreateTableBuilder) CreateTempTable(table string) *CreateTableBuilder {
ctb.verb = "CREATE TEMPORARY TABLE"
ctb.table = Escape(table)
ctb.marker = createTableMarkerAfterCreate
return ctb
}
// IfNotExists adds IF NOT EXISTS before table name in CREATE TABLE.
func (ctb *CreateTableBuilder) IfNotExists() *CreateTableBuilder {
ctb.ifNotExists = true
return ctb
}
// Define adds definition of a column or index in CREATE TABLE.
func (ctb *CreateTableBuilder) Define(def ...string) *CreateTableBuilder {
ctb.defs = append(ctb.defs, def)
ctb.marker = createTableMarkerAfterDefine
return ctb
}
// Option adds a table option in CREATE TABLE.
func (ctb *CreateTableBuilder) Option(opt ...string) *CreateTableBuilder {
ctb.options = append(ctb.options, opt)
ctb.marker = createTableMarkerAfterOption
return ctb
}
// NumDefine returns the number of definitions in CREATE TABLE.
func (ctb *CreateTableBuilder) NumDefine() int {
return len(ctb.defs)
}
// String returns the compiled INSERT string.
func (ctb *CreateTableBuilder) String() string {
s, _ := ctb.Build()
return s
}
// Build returns compiled CREATE TABLE string and args.
// They can be used in `DB#Query` of package `database/sql` directly.
func (ctb *CreateTableBuilder) Build() (sql string, args []interface{}) {
return ctb.BuildWithFlavor(ctb.args.Flavor)
}
// BuildWithFlavor returns compiled CREATE TABLE string and args with flavor and initial args.
// They can be used in `DB#Query` of package `database/sql` directly.
func (ctb *CreateTableBuilder) BuildWithFlavor(flavor Flavor, initialArg ...interface{}) (sql string, args []interface{}) {
buf := newStringBuilder()
ctb.injection.WriteTo(buf, createTableMarkerInit)
if len(ctb.verb) > 0 {
buf.WriteLeadingString(ctb.verb)
}
if ctb.ifNotExists {
buf.WriteLeadingString("IF NOT EXISTS")
}
if len(ctb.table) > 0 {
buf.WriteLeadingString(ctb.table)
}
ctb.injection.WriteTo(buf, createTableMarkerAfterCreate)
if len(ctb.defs) > 0 {
buf.WriteLeadingString("(")
defs := make([]string, 0, len(ctb.defs))
for _, def := range ctb.defs {
defs = append(defs, strings.Join(def, " "))
}
buf.WriteStrings(defs, ", ")
buf.WriteRune(')')
ctb.injection.WriteTo(buf, createTableMarkerAfterDefine)
}
if len(ctb.options) > 0 {
opts := make([]string, 0, len(ctb.options))
for _, opt := range ctb.options {
opts = append(opts, strings.Join(opt, " "))
}
buf.WriteLeadingString(strings.Join(opts, ", "))
ctb.injection.WriteTo(buf, createTableMarkerAfterOption)
}
return ctb.args.CompileWithFlavor(buf.String(), flavor, initialArg...)
}
// SetFlavor sets the flavor of compiled sql.
func (ctb *CreateTableBuilder) SetFlavor(flavor Flavor) (old Flavor) {
old = ctb.args.Flavor
ctb.args.Flavor = flavor
return
}
// Flavor returns flavor of builder
func (ctb *CreateTableBuilder) Flavor() Flavor {
return ctb.args.Flavor
}
// Var returns a placeholder for value.
func (ctb *CreateTableBuilder) Var(arg interface{}) string {
return ctb.args.Add(arg)
}
// SQL adds an arbitrary sql to current position.
func (ctb *CreateTableBuilder) SQL(sql string) *CreateTableBuilder {
ctb.injection.SQL(ctb.marker, sql)
return ctb
}