package bun

import (
	
	
	
	

	
	
	
	
)

type CreateTableQuery struct {
	baseQuery

	temp        bool
	ifNotExists bool
	varchar     int

	fks         []schema.QueryWithArgs
	partitionBy schema.QueryWithArgs
	tablespace  schema.QueryWithArgs
}

func ( *DB) *CreateTableQuery {
	 := &CreateTableQuery{
		baseQuery: baseQuery{
			db:   ,
			conn: .DB,
		},
	}
	return 
}

func ( *CreateTableQuery) ( IConn) *CreateTableQuery {
	.setConn()
	return 
}

func ( *CreateTableQuery) ( interface{}) *CreateTableQuery {
	.setTableModel()
	return 
}

//------------------------------------------------------------------------------

func ( *CreateTableQuery) ( ...string) *CreateTableQuery {
	for ,  := range  {
		.addTable(schema.UnsafeIdent())
	}
	return 
}

func ( *CreateTableQuery) ( string,  ...interface{}) *CreateTableQuery {
	.addTable(schema.SafeQuery(, ))
	return 
}

func ( *CreateTableQuery) ( string,  ...interface{}) *CreateTableQuery {
	.modelTable = schema.SafeQuery(, )
	return 
}

//------------------------------------------------------------------------------

func ( *CreateTableQuery) () *CreateTableQuery {
	.temp = true
	return 
}

func ( *CreateTableQuery) () *CreateTableQuery {
	.ifNotExists = true
	return 
}

func ( *CreateTableQuery) ( int) *CreateTableQuery {
	.varchar = 
	return 
}

func ( *CreateTableQuery) ( string,  ...interface{}) *CreateTableQuery {
	.fks = append(.fks, schema.SafeQuery(, ))
	return 
}

func ( *CreateTableQuery) () string {
	return "CREATE TABLE"
}

func ( *CreateTableQuery) ( schema.Formatter,  []byte) ( []byte,  error) {
	if .err != nil {
		return nil, .err
	}
	if .table == nil {
		return nil, errNilModel
	}

	 = append(, "CREATE "...)
	if .temp {
		 = append(, "TEMP "...)
	}
	 = append(, "TABLE "...)
	if .ifNotExists {
		 = append(, "IF NOT EXISTS "...)
	}
	,  = .appendFirstTable(, )
	if  != nil {
		return nil, 
	}

	 = append(, " ("...)

	for ,  := range .table.Fields {
		if  > 0 {
			 = append(, ", "...)
		}

		 = append(, .SQLName...)
		 = append(, " "...)
		 = .appendSQLType(, )
		if .NotNull {
			 = append(, " NOT NULL"...)
		}
		if .db.features.Has(feature.AutoIncrement) && .AutoIncrement {
			 = append(, " AUTO_INCREMENT"...)
		}
		if .SQLDefault != "" {
			 = append(, " DEFAULT "...)
			 = append(, .SQLDefault...)
		}
	}

	 = .appendPKConstraint(, .table.PKs)
	 = .appendUniqueConstraints(, )
	,  = .appenFKConstraints(, )
	if  != nil {
		return nil, 
	}

	 = append(, ")"...)

	if !.partitionBy.IsZero() {
		 = append(, " PARTITION BY "...)
		,  = .partitionBy.AppendQuery(, )
		if  != nil {
			return nil, 
		}
	}

	if !.tablespace.IsZero() {
		 = append(, " TABLESPACE "...)
		,  = .tablespace.AppendQuery(, )
		if  != nil {
			return nil, 
		}
	}

	return , nil
}

func ( *CreateTableQuery) ( []byte,  *schema.Field) []byte {
	if .CreateTableSQLType != .DiscoveredSQLType {
		return append(, .CreateTableSQLType...)
	}

	if .varchar > 0 &&
		.CreateTableSQLType == sqltype.VarChar {
		 = append(, "varchar("...)
		 = strconv.AppendInt(, int64(.varchar), 10)
		 = append(, ")"...)
		return 
	}

	return append(, .CreateTableSQLType...)
}

func ( *CreateTableQuery) ( schema.Formatter,  []byte) []byte {
	 := .table.Unique

	 := make([]string, 0, len())
	for  := range  {
		 = append(, )
	}
	sort.Strings()

	for ,  := range  {
		if  == "" {
			for ,  := range [] {
				 = .appendUniqueConstraint(, , , )
			}
			continue
		}
		 = .appendUniqueConstraint(, , , []...)
	}

	return 
}

func ( *CreateTableQuery) (
	 schema.Formatter,  []byte,  string,  ...*schema.Field,
) []byte {
	if  != "" {
		 = append(, ", CONSTRAINT "...)
		 = .AppendIdent(, )
	} else {
		 = append(, ","...)
	}
	 = append(, " UNIQUE ("...)
	 = appendColumns(, "", )
	 = append(, ")"...)
	return 
}

func ( *CreateTableQuery) (
	 schema.Formatter,  []byte,
) ( []byte,  error) {
	for ,  := range .fks {
		 = append(, ", FOREIGN KEY "...)
		,  = .AppendQuery(, )
		if  != nil {
			return nil, 
		}
	}
	return , nil
}

func ( *CreateTableQuery) ( []byte,  []*schema.Field) []byte {
	if len() == 0 {
		return 
	}

	 = append(, ", PRIMARY KEY ("...)
	 = appendColumns(, "", )
	 = append(, ")"...)
	return 
}

//------------------------------------------------------------------------------

func ( *CreateTableQuery) ( context.Context,  ...interface{}) (sql.Result, error) {
	if  := .beforeCreateTableHook();  != nil {
		return nil, 
	}

	,  := .AppendQuery(.db.fmter, .db.makeQueryBytes())
	if  != nil {
		return nil, 
	}

	 := internal.String()

	,  := .exec(, , )
	if  != nil {
		return nil, 
	}

	if .table != nil {
		if  := .afterCreateTableHook();  != nil {
			return nil, 
		}
	}

	return , nil
}

func ( *CreateTableQuery) ( context.Context) error {
	if ,  := .table.ZeroIface.(BeforeCreateTableHook);  {
		if  := .BeforeCreateTable(, );  != nil {
			return 
		}
	}
	return nil
}

func ( *CreateTableQuery) ( context.Context) error {
	if ,  := .table.ZeroIface.(AfterCreateTableHook);  {
		if  := .AfterCreateTable(, );  != nil {
			return 
		}
	}
	return nil
}