mirror of
https://github.com/astaxie/beego.git
synced 2024-12-23 08:50:50 +00:00
172 lines
3.9 KiB
Go
172 lines
3.9 KiB
Go
// Copyright 2014 beego Author. All Rights Reserved.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package orm
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
type dbIndex struct {
|
|
Table string
|
|
Name string
|
|
SQL string
|
|
}
|
|
|
|
// get database column type string.
|
|
func getColumnTyp(al *alias, fi *fieldInfo) (col string) {
|
|
T := al.DbBaser.DbTypes()
|
|
fieldType := fi.fieldType
|
|
fieldSize := fi.size
|
|
|
|
checkColumn:
|
|
switch fieldType {
|
|
case TypeBooleanField:
|
|
col = T["bool"]
|
|
case TypeVarCharField:
|
|
if al.Driver == DRPostgres && fi.toText {
|
|
col = T["string-text"]
|
|
} else {
|
|
col = fmt.Sprintf(T["string"], fieldSize)
|
|
}
|
|
case TypeCharField:
|
|
col = fmt.Sprintf(T["string-char"], fieldSize)
|
|
case TypeTextField:
|
|
col = T["string-text"]
|
|
case TypeTimeField:
|
|
col = T["time.Time-clock"]
|
|
case TypeDateField:
|
|
col = T["time.Time-date"]
|
|
case TypeDateTimeField:
|
|
// the precision of sqlite is not implemented
|
|
if al.Driver == 2 || fi.timePrecision == nil {
|
|
col = T["time.Time"]
|
|
} else {
|
|
s := T["time.Time-precision"]
|
|
col = fmt.Sprintf(s, *fi.timePrecision)
|
|
}
|
|
|
|
case TypeBitField:
|
|
col = T["int8"]
|
|
case TypeSmallIntegerField:
|
|
col = T["int16"]
|
|
case TypeIntegerField:
|
|
col = T["int32"]
|
|
case TypeBigIntegerField:
|
|
if al.Driver == DRSqlite {
|
|
fieldType = TypeIntegerField
|
|
goto checkColumn
|
|
}
|
|
col = T["int64"]
|
|
case TypePositiveBitField:
|
|
col = T["uint8"]
|
|
case TypePositiveSmallIntegerField:
|
|
col = T["uint16"]
|
|
case TypePositiveIntegerField:
|
|
col = T["uint32"]
|
|
case TypePositiveBigIntegerField:
|
|
col = T["uint64"]
|
|
case TypeFloatField:
|
|
col = T["float64"]
|
|
case TypeDecimalField:
|
|
s := T["float64-decimal"]
|
|
if !strings.Contains(s, "%d") {
|
|
col = s
|
|
} else {
|
|
col = fmt.Sprintf(s, fi.digits, fi.decimals)
|
|
}
|
|
case TypeJSONField:
|
|
if al.Driver != DRPostgres {
|
|
fieldType = TypeVarCharField
|
|
goto checkColumn
|
|
}
|
|
col = T["json"]
|
|
case TypeJsonbField:
|
|
if al.Driver != DRPostgres {
|
|
fieldType = TypeVarCharField
|
|
goto checkColumn
|
|
}
|
|
col = T["jsonb"]
|
|
case RelForeignKey, RelOneToOne:
|
|
fieldType = fi.relModelInfo.fields.pk.fieldType
|
|
fieldSize = fi.relModelInfo.fields.pk.size
|
|
goto checkColumn
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
// create alter sql string.
|
|
func getColumnAddQuery(al *alias, fi *fieldInfo) string {
|
|
Q := al.DbBaser.TableQuote()
|
|
typ := getColumnTyp(al, fi)
|
|
|
|
if !fi.null {
|
|
typ += " " + "NOT NULL"
|
|
}
|
|
|
|
return fmt.Sprintf("ALTER TABLE %s%s%s ADD COLUMN %s%s%s %s %s",
|
|
Q, fi.mi.table, Q,
|
|
Q, fi.column, Q,
|
|
typ, getColumnDefault(fi),
|
|
)
|
|
}
|
|
|
|
// Get string value for the attribute "DEFAULT" for the CREATE, ALTER commands
|
|
func getColumnDefault(fi *fieldInfo) string {
|
|
var (
|
|
v, t, d string
|
|
)
|
|
|
|
// Skip default attribute if field is in relations
|
|
if fi.rel || fi.reverse {
|
|
return v
|
|
}
|
|
|
|
t = " DEFAULT '%s' "
|
|
|
|
// These defaults will be useful if there no config value orm:"default" and NOT NULL is on
|
|
switch fi.fieldType {
|
|
case TypeTimeField, TypeDateField, TypeDateTimeField, TypeTextField:
|
|
return v
|
|
|
|
case TypeBitField, TypeSmallIntegerField, TypeIntegerField,
|
|
TypeBigIntegerField, TypePositiveBitField, TypePositiveSmallIntegerField,
|
|
TypePositiveIntegerField, TypePositiveBigIntegerField, TypeFloatField,
|
|
TypeDecimalField:
|
|
t = " DEFAULT %s "
|
|
d = "0"
|
|
case TypeBooleanField:
|
|
t = " DEFAULT %s "
|
|
d = "FALSE"
|
|
case TypeJSONField, TypeJsonbField:
|
|
d = "{}"
|
|
}
|
|
|
|
if fi.colDefault {
|
|
if !fi.initial.Exist() {
|
|
v = fmt.Sprintf(t, "")
|
|
} else {
|
|
v = fmt.Sprintf(t, fi.initial.String())
|
|
}
|
|
} else {
|
|
if !fi.null {
|
|
v = fmt.Sprintf(t, d)
|
|
}
|
|
}
|
|
|
|
return v
|
|
}
|