mirror of
https://github.com/go-gitea/gitea
synced 2025-07-23 02:38:35 +00:00
Upgrade xorm to v1.0.0 (#10646)
* Upgrade xorm to v1.0.0 * small nit * Fix tests * Update xorm * Update xorm * fix go.sum * fix test * Fix bug when dump * Fix bug * update xorm to latest * Fix migration test * update xorm to latest * Fix import order * Use xorm tag
This commit is contained in:
117
vendor/xorm.io/xorm/schemas/column.go
generated
vendored
Normal file
117
vendor/xorm.io/xorm/schemas/column.go
generated
vendored
Normal file
@@ -0,0 +1,117 @@
|
||||
// Copyright 2019 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package schemas
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
TWOSIDES = iota + 1
|
||||
ONLYTODB
|
||||
ONLYFROMDB
|
||||
)
|
||||
|
||||
// Column defines database column
|
||||
type Column struct {
|
||||
Name string
|
||||
TableName string
|
||||
FieldName string // Avaiable only when parsed from a struct
|
||||
SQLType SQLType
|
||||
IsJSON bool
|
||||
Length int
|
||||
Length2 int
|
||||
Nullable bool
|
||||
Default string
|
||||
Indexes map[string]int
|
||||
IsPrimaryKey bool
|
||||
IsAutoIncrement bool
|
||||
MapType int
|
||||
IsCreated bool
|
||||
IsUpdated bool
|
||||
IsDeleted bool
|
||||
IsCascade bool
|
||||
IsVersion bool
|
||||
DefaultIsEmpty bool // false means column has no default set, but not default value is empty
|
||||
EnumOptions map[string]int
|
||||
SetOptions map[string]int
|
||||
DisableTimeZone bool
|
||||
TimeZone *time.Location // column specified time zone
|
||||
Comment string
|
||||
}
|
||||
|
||||
// NewColumn creates a new column
|
||||
func NewColumn(name, fieldName string, sqlType SQLType, len1, len2 int, nullable bool) *Column {
|
||||
return &Column{
|
||||
Name: name,
|
||||
TableName: "",
|
||||
FieldName: fieldName,
|
||||
SQLType: sqlType,
|
||||
Length: len1,
|
||||
Length2: len2,
|
||||
Nullable: nullable,
|
||||
Default: "",
|
||||
Indexes: make(map[string]int),
|
||||
IsPrimaryKey: false,
|
||||
IsAutoIncrement: false,
|
||||
MapType: TWOSIDES,
|
||||
IsCreated: false,
|
||||
IsUpdated: false,
|
||||
IsDeleted: false,
|
||||
IsCascade: false,
|
||||
IsVersion: false,
|
||||
DefaultIsEmpty: true, // default should be no default
|
||||
EnumOptions: make(map[string]int),
|
||||
Comment: "",
|
||||
}
|
||||
}
|
||||
|
||||
// ValueOf returns column's filed of struct's value
|
||||
func (col *Column) ValueOf(bean interface{}) (*reflect.Value, error) {
|
||||
dataStruct := reflect.Indirect(reflect.ValueOf(bean))
|
||||
return col.ValueOfV(&dataStruct)
|
||||
}
|
||||
|
||||
// ValueOfV returns column's filed of struct's value accept reflevt value
|
||||
func (col *Column) ValueOfV(dataStruct *reflect.Value) (*reflect.Value, error) {
|
||||
var fieldValue reflect.Value
|
||||
fieldPath := strings.Split(col.FieldName, ".")
|
||||
|
||||
if dataStruct.Type().Kind() == reflect.Map {
|
||||
keyValue := reflect.ValueOf(fieldPath[len(fieldPath)-1])
|
||||
fieldValue = dataStruct.MapIndex(keyValue)
|
||||
return &fieldValue, nil
|
||||
} else if dataStruct.Type().Kind() == reflect.Interface {
|
||||
structValue := reflect.ValueOf(dataStruct.Interface())
|
||||
dataStruct = &structValue
|
||||
}
|
||||
|
||||
level := len(fieldPath)
|
||||
fieldValue = dataStruct.FieldByName(fieldPath[0])
|
||||
for i := 0; i < level-1; i++ {
|
||||
if !fieldValue.IsValid() {
|
||||
break
|
||||
}
|
||||
if fieldValue.Kind() == reflect.Struct {
|
||||
fieldValue = fieldValue.FieldByName(fieldPath[i+1])
|
||||
} else if fieldValue.Kind() == reflect.Ptr {
|
||||
if fieldValue.IsNil() {
|
||||
fieldValue.Set(reflect.New(fieldValue.Type().Elem()))
|
||||
}
|
||||
fieldValue = fieldValue.Elem().FieldByName(fieldPath[i+1])
|
||||
} else {
|
||||
return nil, fmt.Errorf("field %v is not valid", col.FieldName)
|
||||
}
|
||||
}
|
||||
|
||||
if !fieldValue.IsValid() {
|
||||
return nil, fmt.Errorf("field %v is not valid", col.FieldName)
|
||||
}
|
||||
|
||||
return &fieldValue, nil
|
||||
}
|
72
vendor/xorm.io/xorm/schemas/index.go
generated
vendored
Normal file
72
vendor/xorm.io/xorm/schemas/index.go
generated
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
// Copyright 2019 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package schemas
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// enumerate all index types
|
||||
const (
|
||||
IndexType = iota + 1
|
||||
UniqueType
|
||||
)
|
||||
|
||||
// Index represents a database index
|
||||
type Index struct {
|
||||
IsRegular bool
|
||||
Name string
|
||||
Type int
|
||||
Cols []string
|
||||
}
|
||||
|
||||
// NewIndex new an index object
|
||||
func NewIndex(name string, indexType int) *Index {
|
||||
return &Index{true, name, indexType, make([]string, 0)}
|
||||
}
|
||||
|
||||
func (index *Index) XName(tableName string) string {
|
||||
if !strings.HasPrefix(index.Name, "UQE_") &&
|
||||
!strings.HasPrefix(index.Name, "IDX_") {
|
||||
tableParts := strings.Split(strings.Replace(tableName, `"`, "", -1), ".")
|
||||
tableName = tableParts[len(tableParts)-1]
|
||||
if index.Type == UniqueType {
|
||||
return fmt.Sprintf("UQE_%v_%v", tableName, index.Name)
|
||||
}
|
||||
return fmt.Sprintf("IDX_%v_%v", tableName, index.Name)
|
||||
}
|
||||
return index.Name
|
||||
}
|
||||
|
||||
// AddColumn add columns which will be composite index
|
||||
func (index *Index) AddColumn(cols ...string) {
|
||||
for _, col := range cols {
|
||||
index.Cols = append(index.Cols, col)
|
||||
}
|
||||
}
|
||||
|
||||
func (index *Index) Equal(dst *Index) bool {
|
||||
if index.Type != dst.Type {
|
||||
return false
|
||||
}
|
||||
if len(index.Cols) != len(dst.Cols) {
|
||||
return false
|
||||
}
|
||||
|
||||
for i := 0; i < len(index.Cols); i++ {
|
||||
var found bool
|
||||
for j := 0; j < len(dst.Cols); j++ {
|
||||
if index.Cols[i] == dst.Cols[j] {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
41
vendor/xorm.io/xorm/schemas/pk.go
generated
vendored
Normal file
41
vendor/xorm.io/xorm/schemas/pk.go
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
// Copyright 2019 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package schemas
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/gob"
|
||||
|
||||
"xorm.io/xorm/internal/utils"
|
||||
)
|
||||
|
||||
type PK []interface{}
|
||||
|
||||
func NewPK(pks ...interface{}) *PK {
|
||||
p := PK(pks)
|
||||
return &p
|
||||
}
|
||||
|
||||
func (p *PK) IsZero() bool {
|
||||
for _, k := range *p {
|
||||
if utils.IsZero(k) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (p *PK) ToString() (string, error) {
|
||||
buf := new(bytes.Buffer)
|
||||
enc := gob.NewEncoder(buf)
|
||||
err := enc.Encode(*p)
|
||||
return buf.String(), err
|
||||
}
|
||||
|
||||
func (p *PK) FromString(content string) error {
|
||||
dec := gob.NewDecoder(bytes.NewBufferString(content))
|
||||
err := dec.Decode(p)
|
||||
return err
|
||||
}
|
236
vendor/xorm.io/xorm/schemas/quote.go
generated
vendored
Normal file
236
vendor/xorm.io/xorm/schemas/quote.go
generated
vendored
Normal file
@@ -0,0 +1,236 @@
|
||||
// Copyright 2020 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package schemas
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Quoter represents a quoter to the SQL table name and column name
|
||||
type Quoter struct {
|
||||
Prefix byte
|
||||
Suffix byte
|
||||
IsReserved func(string) bool
|
||||
}
|
||||
|
||||
var (
|
||||
// AlwaysFalseReverse always think it's not a reverse word
|
||||
AlwaysNoReserve = func(string) bool { return false }
|
||||
|
||||
// AlwaysReverse always reverse the word
|
||||
AlwaysReserve = func(string) bool { return true }
|
||||
|
||||
// CommanQuoteMark represnets the common quote mark
|
||||
CommanQuoteMark byte = '`'
|
||||
|
||||
// CommonQuoter represetns a common quoter
|
||||
CommonQuoter = Quoter{CommanQuoteMark, CommanQuoteMark, AlwaysReserve}
|
||||
)
|
||||
|
||||
func (q Quoter) IsEmpty() bool {
|
||||
return q.Prefix == 0 && q.Suffix == 0
|
||||
}
|
||||
|
||||
func (q Quoter) Quote(s string) string {
|
||||
var buf strings.Builder
|
||||
q.QuoteTo(&buf, s)
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// Trim removes quotes from s
|
||||
func (q Quoter) Trim(s string) string {
|
||||
if len(s) < 2 {
|
||||
return s
|
||||
}
|
||||
|
||||
var buf strings.Builder
|
||||
for i := 0; i < len(s); i++ {
|
||||
switch {
|
||||
case i == 0 && s[i] == q.Prefix:
|
||||
case i == len(s)-1 && s[i] == q.Suffix:
|
||||
case s[i] == q.Suffix && s[i+1] == '.':
|
||||
case s[i] == q.Prefix && s[i-1] == '.':
|
||||
default:
|
||||
buf.WriteByte(s[i])
|
||||
}
|
||||
}
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
func (q Quoter) Join(a []string, sep string) string {
|
||||
var b strings.Builder
|
||||
q.JoinWrite(&b, a, sep)
|
||||
return b.String()
|
||||
}
|
||||
|
||||
func (q Quoter) JoinWrite(b *strings.Builder, a []string, sep string) error {
|
||||
if len(a) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
n := len(sep) * (len(a) - 1)
|
||||
for i := 0; i < len(a); i++ {
|
||||
n += len(a[i])
|
||||
}
|
||||
|
||||
b.Grow(n)
|
||||
for i, s := range a {
|
||||
if i > 0 {
|
||||
if _, err := b.WriteString(sep); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if s != "*" {
|
||||
q.QuoteTo(b, strings.TrimSpace(s))
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func findWord(v string, start int) int {
|
||||
for j := start; j < len(v); j++ {
|
||||
switch v[j] {
|
||||
case '.', ' ':
|
||||
return j
|
||||
}
|
||||
}
|
||||
return len(v)
|
||||
}
|
||||
|
||||
func findStart(value string, start int) int {
|
||||
if value[start] == '.' {
|
||||
return start + 1
|
||||
}
|
||||
if value[start] != ' ' {
|
||||
return start
|
||||
}
|
||||
|
||||
var k int
|
||||
for j := start; j < len(value); j++ {
|
||||
if value[j] != ' ' {
|
||||
k = j
|
||||
break
|
||||
}
|
||||
}
|
||||
if k-1 == len(value) {
|
||||
return len(value)
|
||||
}
|
||||
if (value[k] == 'A' || value[k] == 'a') && (value[k+1] == 'S' || value[k+1] == 's') {
|
||||
k = k + 2
|
||||
}
|
||||
|
||||
for j := k; j < len(value); j++ {
|
||||
if value[j] != ' ' {
|
||||
return j
|
||||
}
|
||||
}
|
||||
return len(value)
|
||||
}
|
||||
|
||||
func (q Quoter) quoteWordTo(buf *strings.Builder, word string) error {
|
||||
var realWord = word
|
||||
if (word[0] == CommanQuoteMark && word[len(word)-1] == CommanQuoteMark) ||
|
||||
(word[0] == q.Prefix && word[len(word)-1] == q.Suffix) {
|
||||
realWord = word[1 : len(word)-1]
|
||||
}
|
||||
|
||||
if q.IsEmpty() {
|
||||
_, err := buf.WriteString(realWord)
|
||||
return err
|
||||
}
|
||||
|
||||
isReserved := q.IsReserved(realWord)
|
||||
if isReserved {
|
||||
if err := buf.WriteByte(q.Prefix); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if _, err := buf.WriteString(realWord); err != nil {
|
||||
return err
|
||||
}
|
||||
if isReserved {
|
||||
return buf.WriteByte(q.Suffix)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// QuoteTo quotes the table or column names. i.e. if the quotes are [ and ]
|
||||
// name -> [name]
|
||||
// `name` -> [name]
|
||||
// [name] -> [name]
|
||||
// schema.name -> [schema].[name]
|
||||
// `schema`.`name` -> [schema].[name]
|
||||
// `schema`.name -> [schema].[name]
|
||||
// schema.`name` -> [schema].[name]
|
||||
// [schema].name -> [schema].[name]
|
||||
// schema.[name] -> [schema].[name]
|
||||
// name AS a -> [name] AS a
|
||||
// schema.name AS a -> [schema].[name] AS a
|
||||
func (q Quoter) QuoteTo(buf *strings.Builder, value string) error {
|
||||
var i int
|
||||
for i < len(value) {
|
||||
start := findStart(value, i)
|
||||
if start > i {
|
||||
if _, err := buf.WriteString(value[i:start]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
var nextEnd = findWord(value, start)
|
||||
|
||||
if err := q.quoteWordTo(buf, value[start:nextEnd]); err != nil {
|
||||
return err
|
||||
}
|
||||
i = nextEnd
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Strings quotes a slice of string
|
||||
func (q Quoter) Strings(s []string) []string {
|
||||
var res = make([]string, 0, len(s))
|
||||
for _, a := range s {
|
||||
res = append(res, q.Quote(a))
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// Replace replaces common quote(`) as the quotes on the sql
|
||||
func (q Quoter) Replace(sql string) string {
|
||||
if q.IsEmpty() {
|
||||
return sql
|
||||
}
|
||||
|
||||
var buf strings.Builder
|
||||
buf.Grow(len(sql))
|
||||
|
||||
var beginSingleQuote bool
|
||||
for i := 0; i < len(sql); i++ {
|
||||
if !beginSingleQuote && sql[i] == CommanQuoteMark {
|
||||
var j = i + 1
|
||||
for ; j < len(sql); j++ {
|
||||
if sql[j] == CommanQuoteMark {
|
||||
break
|
||||
}
|
||||
}
|
||||
word := sql[i+1 : j]
|
||||
isReserved := q.IsReserved(word)
|
||||
if isReserved {
|
||||
buf.WriteByte(q.Prefix)
|
||||
}
|
||||
buf.WriteString(word)
|
||||
if isReserved {
|
||||
buf.WriteByte(q.Suffix)
|
||||
}
|
||||
i = j
|
||||
} else {
|
||||
if sql[i] == '\'' {
|
||||
beginSingleQuote = !beginSingleQuote
|
||||
}
|
||||
buf.WriteByte(sql[i])
|
||||
}
|
||||
}
|
||||
return buf.String()
|
||||
}
|
146
vendor/xorm.io/xorm/schemas/table.go
generated
vendored
Normal file
146
vendor/xorm.io/xorm/schemas/table.go
generated
vendored
Normal file
@@ -0,0 +1,146 @@
|
||||
// Copyright 2019 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package schemas
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Table represents a database table
|
||||
type Table struct {
|
||||
Name string
|
||||
Type reflect.Type
|
||||
columnsSeq []string
|
||||
columnsMap map[string][]*Column
|
||||
columns []*Column
|
||||
Indexes map[string]*Index
|
||||
PrimaryKeys []string
|
||||
AutoIncrement string
|
||||
Created map[string]bool
|
||||
Updated string
|
||||
Deleted string
|
||||
Version string
|
||||
StoreEngine string
|
||||
Charset string
|
||||
Comment string
|
||||
}
|
||||
|
||||
func NewEmptyTable() *Table {
|
||||
return NewTable("", nil)
|
||||
}
|
||||
|
||||
// NewTable creates a new Table object
|
||||
func NewTable(name string, t reflect.Type) *Table {
|
||||
return &Table{Name: name, Type: t,
|
||||
columnsSeq: make([]string, 0),
|
||||
columns: make([]*Column, 0),
|
||||
columnsMap: make(map[string][]*Column),
|
||||
Indexes: make(map[string]*Index),
|
||||
Created: make(map[string]bool),
|
||||
PrimaryKeys: make([]string, 0),
|
||||
}
|
||||
}
|
||||
|
||||
func (table *Table) Columns() []*Column {
|
||||
return table.columns
|
||||
}
|
||||
|
||||
func (table *Table) ColumnsSeq() []string {
|
||||
return table.columnsSeq
|
||||
}
|
||||
|
||||
func (table *Table) columnsByName(name string) []*Column {
|
||||
for k, cols := range table.columnsMap {
|
||||
if strings.EqualFold(k, name) {
|
||||
return cols
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (table *Table) GetColumn(name string) *Column {
|
||||
cols := table.columnsByName(name)
|
||||
if cols != nil {
|
||||
return cols[0]
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (table *Table) GetColumnIdx(name string, idx int) *Column {
|
||||
cols := table.columnsByName(name)
|
||||
if cols != nil && idx < len(cols) {
|
||||
return cols[idx]
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// PKColumns reprents all primary key columns
|
||||
func (table *Table) PKColumns() []*Column {
|
||||
columns := make([]*Column, len(table.PrimaryKeys))
|
||||
for i, name := range table.PrimaryKeys {
|
||||
columns[i] = table.GetColumn(name)
|
||||
}
|
||||
return columns
|
||||
}
|
||||
|
||||
func (table *Table) ColumnType(name string) reflect.Type {
|
||||
t, _ := table.Type.FieldByName(name)
|
||||
return t.Type
|
||||
}
|
||||
|
||||
func (table *Table) AutoIncrColumn() *Column {
|
||||
return table.GetColumn(table.AutoIncrement)
|
||||
}
|
||||
|
||||
func (table *Table) VersionColumn() *Column {
|
||||
return table.GetColumn(table.Version)
|
||||
}
|
||||
|
||||
func (table *Table) UpdatedColumn() *Column {
|
||||
return table.GetColumn(table.Updated)
|
||||
}
|
||||
|
||||
func (table *Table) DeletedColumn() *Column {
|
||||
return table.GetColumn(table.Deleted)
|
||||
}
|
||||
|
||||
// AddColumn adds a column to table
|
||||
func (table *Table) AddColumn(col *Column) {
|
||||
table.columnsSeq = append(table.columnsSeq, col.Name)
|
||||
table.columns = append(table.columns, col)
|
||||
colName := strings.ToLower(col.Name)
|
||||
if c, ok := table.columnsMap[colName]; ok {
|
||||
table.columnsMap[colName] = append(c, col)
|
||||
} else {
|
||||
table.columnsMap[colName] = []*Column{col}
|
||||
}
|
||||
|
||||
if col.IsPrimaryKey {
|
||||
table.PrimaryKeys = append(table.PrimaryKeys, col.Name)
|
||||
}
|
||||
if col.IsAutoIncrement {
|
||||
table.AutoIncrement = col.Name
|
||||
}
|
||||
if col.IsCreated {
|
||||
table.Created[col.Name] = true
|
||||
}
|
||||
if col.IsUpdated {
|
||||
table.Updated = col.Name
|
||||
}
|
||||
if col.IsDeleted {
|
||||
table.Deleted = col.Name
|
||||
}
|
||||
if col.IsVersion {
|
||||
table.Version = col.Name
|
||||
}
|
||||
}
|
||||
|
||||
// AddIndex adds an index or an unique to table
|
||||
func (table *Table) AddIndex(index *Index) {
|
||||
table.Indexes[index.Name] = index
|
||||
}
|
336
vendor/xorm.io/xorm/schemas/type.go
generated
vendored
Normal file
336
vendor/xorm.io/xorm/schemas/type.go
generated
vendored
Normal file
@@ -0,0 +1,336 @@
|
||||
// Copyright 2019 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package schemas
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type DBType string
|
||||
|
||||
const (
|
||||
POSTGRES DBType = "postgres"
|
||||
SQLITE DBType = "sqlite3"
|
||||
MYSQL DBType = "mysql"
|
||||
MSSQL DBType = "mssql"
|
||||
ORACLE DBType = "oracle"
|
||||
)
|
||||
|
||||
// SQLType represents SQL types
|
||||
type SQLType struct {
|
||||
Name string
|
||||
DefaultLength int
|
||||
DefaultLength2 int
|
||||
}
|
||||
|
||||
const (
|
||||
UNKNOW_TYPE = iota
|
||||
TEXT_TYPE
|
||||
BLOB_TYPE
|
||||
TIME_TYPE
|
||||
NUMERIC_TYPE
|
||||
ARRAY_TYPE
|
||||
)
|
||||
|
||||
func (s *SQLType) IsType(st int) bool {
|
||||
if t, ok := SqlTypes[s.Name]; ok && t == st {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (s *SQLType) IsText() bool {
|
||||
return s.IsType(TEXT_TYPE)
|
||||
}
|
||||
|
||||
func (s *SQLType) IsBlob() bool {
|
||||
return s.IsType(BLOB_TYPE)
|
||||
}
|
||||
|
||||
func (s *SQLType) IsTime() bool {
|
||||
return s.IsType(TIME_TYPE)
|
||||
}
|
||||
|
||||
func (s *SQLType) IsNumeric() bool {
|
||||
return s.IsType(NUMERIC_TYPE)
|
||||
}
|
||||
|
||||
func (s *SQLType) IsArray() bool {
|
||||
return s.IsType(ARRAY_TYPE)
|
||||
}
|
||||
|
||||
func (s *SQLType) IsJson() bool {
|
||||
return s.Name == Json || s.Name == Jsonb
|
||||
}
|
||||
|
||||
var (
|
||||
Bit = "BIT"
|
||||
TinyInt = "TINYINT"
|
||||
SmallInt = "SMALLINT"
|
||||
MediumInt = "MEDIUMINT"
|
||||
Int = "INT"
|
||||
Integer = "INTEGER"
|
||||
BigInt = "BIGINT"
|
||||
|
||||
Enum = "ENUM"
|
||||
Set = "SET"
|
||||
|
||||
Char = "CHAR"
|
||||
Varchar = "VARCHAR"
|
||||
NChar = "NCHAR"
|
||||
NVarchar = "NVARCHAR"
|
||||
TinyText = "TINYTEXT"
|
||||
Text = "TEXT"
|
||||
NText = "NTEXT"
|
||||
Clob = "CLOB"
|
||||
MediumText = "MEDIUMTEXT"
|
||||
LongText = "LONGTEXT"
|
||||
Uuid = "UUID"
|
||||
UniqueIdentifier = "UNIQUEIDENTIFIER"
|
||||
SysName = "SYSNAME"
|
||||
|
||||
Date = "DATE"
|
||||
DateTime = "DATETIME"
|
||||
SmallDateTime = "SMALLDATETIME"
|
||||
Time = "TIME"
|
||||
TimeStamp = "TIMESTAMP"
|
||||
TimeStampz = "TIMESTAMPZ"
|
||||
Year = "YEAR"
|
||||
|
||||
Decimal = "DECIMAL"
|
||||
Numeric = "NUMERIC"
|
||||
Money = "MONEY"
|
||||
SmallMoney = "SMALLMONEY"
|
||||
|
||||
Real = "REAL"
|
||||
Float = "FLOAT"
|
||||
Double = "DOUBLE"
|
||||
|
||||
Binary = "BINARY"
|
||||
VarBinary = "VARBINARY"
|
||||
TinyBlob = "TINYBLOB"
|
||||
Blob = "BLOB"
|
||||
MediumBlob = "MEDIUMBLOB"
|
||||
LongBlob = "LONGBLOB"
|
||||
Bytea = "BYTEA"
|
||||
|
||||
Bool = "BOOL"
|
||||
Boolean = "BOOLEAN"
|
||||
|
||||
Serial = "SERIAL"
|
||||
BigSerial = "BIGSERIAL"
|
||||
|
||||
Json = "JSON"
|
||||
Jsonb = "JSONB"
|
||||
|
||||
Array = "ARRAY"
|
||||
|
||||
SqlTypes = map[string]int{
|
||||
Bit: NUMERIC_TYPE,
|
||||
TinyInt: NUMERIC_TYPE,
|
||||
SmallInt: NUMERIC_TYPE,
|
||||
MediumInt: NUMERIC_TYPE,
|
||||
Int: NUMERIC_TYPE,
|
||||
Integer: NUMERIC_TYPE,
|
||||
BigInt: NUMERIC_TYPE,
|
||||
|
||||
Enum: TEXT_TYPE,
|
||||
Set: TEXT_TYPE,
|
||||
Json: TEXT_TYPE,
|
||||
Jsonb: TEXT_TYPE,
|
||||
|
||||
Char: TEXT_TYPE,
|
||||
NChar: TEXT_TYPE,
|
||||
Varchar: TEXT_TYPE,
|
||||
NVarchar: TEXT_TYPE,
|
||||
TinyText: TEXT_TYPE,
|
||||
Text: TEXT_TYPE,
|
||||
NText: TEXT_TYPE,
|
||||
MediumText: TEXT_TYPE,
|
||||
LongText: TEXT_TYPE,
|
||||
Uuid: TEXT_TYPE,
|
||||
Clob: TEXT_TYPE,
|
||||
SysName: TEXT_TYPE,
|
||||
|
||||
Date: TIME_TYPE,
|
||||
DateTime: TIME_TYPE,
|
||||
Time: TIME_TYPE,
|
||||
TimeStamp: TIME_TYPE,
|
||||
TimeStampz: TIME_TYPE,
|
||||
SmallDateTime: TIME_TYPE,
|
||||
Year: TIME_TYPE,
|
||||
|
||||
Decimal: NUMERIC_TYPE,
|
||||
Numeric: NUMERIC_TYPE,
|
||||
Real: NUMERIC_TYPE,
|
||||
Float: NUMERIC_TYPE,
|
||||
Double: NUMERIC_TYPE,
|
||||
Money: NUMERIC_TYPE,
|
||||
SmallMoney: NUMERIC_TYPE,
|
||||
|
||||
Binary: BLOB_TYPE,
|
||||
VarBinary: BLOB_TYPE,
|
||||
|
||||
TinyBlob: BLOB_TYPE,
|
||||
Blob: BLOB_TYPE,
|
||||
MediumBlob: BLOB_TYPE,
|
||||
LongBlob: BLOB_TYPE,
|
||||
Bytea: BLOB_TYPE,
|
||||
UniqueIdentifier: BLOB_TYPE,
|
||||
|
||||
Bool: NUMERIC_TYPE,
|
||||
|
||||
Serial: NUMERIC_TYPE,
|
||||
BigSerial: NUMERIC_TYPE,
|
||||
|
||||
Array: ARRAY_TYPE,
|
||||
}
|
||||
|
||||
intTypes = sort.StringSlice{"*int", "*int16", "*int32", "*int8"}
|
||||
uintTypes = sort.StringSlice{"*uint", "*uint16", "*uint32", "*uint8"}
|
||||
)
|
||||
|
||||
// !nashtsai! treat following var as interal const values, these are used for reflect.TypeOf comparison
|
||||
var (
|
||||
c_EMPTY_STRING string
|
||||
c_BOOL_DEFAULT bool
|
||||
c_BYTE_DEFAULT byte
|
||||
c_COMPLEX64_DEFAULT complex64
|
||||
c_COMPLEX128_DEFAULT complex128
|
||||
c_FLOAT32_DEFAULT float32
|
||||
c_FLOAT64_DEFAULT float64
|
||||
c_INT64_DEFAULT int64
|
||||
c_UINT64_DEFAULT uint64
|
||||
c_INT32_DEFAULT int32
|
||||
c_UINT32_DEFAULT uint32
|
||||
c_INT16_DEFAULT int16
|
||||
c_UINT16_DEFAULT uint16
|
||||
c_INT8_DEFAULT int8
|
||||
c_UINT8_DEFAULT uint8
|
||||
c_INT_DEFAULT int
|
||||
c_UINT_DEFAULT uint
|
||||
c_TIME_DEFAULT time.Time
|
||||
)
|
||||
|
||||
var (
|
||||
IntType = reflect.TypeOf(c_INT_DEFAULT)
|
||||
Int8Type = reflect.TypeOf(c_INT8_DEFAULT)
|
||||
Int16Type = reflect.TypeOf(c_INT16_DEFAULT)
|
||||
Int32Type = reflect.TypeOf(c_INT32_DEFAULT)
|
||||
Int64Type = reflect.TypeOf(c_INT64_DEFAULT)
|
||||
|
||||
UintType = reflect.TypeOf(c_UINT_DEFAULT)
|
||||
Uint8Type = reflect.TypeOf(c_UINT8_DEFAULT)
|
||||
Uint16Type = reflect.TypeOf(c_UINT16_DEFAULT)
|
||||
Uint32Type = reflect.TypeOf(c_UINT32_DEFAULT)
|
||||
Uint64Type = reflect.TypeOf(c_UINT64_DEFAULT)
|
||||
|
||||
Float32Type = reflect.TypeOf(c_FLOAT32_DEFAULT)
|
||||
Float64Type = reflect.TypeOf(c_FLOAT64_DEFAULT)
|
||||
|
||||
Complex64Type = reflect.TypeOf(c_COMPLEX64_DEFAULT)
|
||||
Complex128Type = reflect.TypeOf(c_COMPLEX128_DEFAULT)
|
||||
|
||||
StringType = reflect.TypeOf(c_EMPTY_STRING)
|
||||
BoolType = reflect.TypeOf(c_BOOL_DEFAULT)
|
||||
ByteType = reflect.TypeOf(c_BYTE_DEFAULT)
|
||||
BytesType = reflect.SliceOf(ByteType)
|
||||
|
||||
TimeType = reflect.TypeOf(c_TIME_DEFAULT)
|
||||
)
|
||||
|
||||
var (
|
||||
PtrIntType = reflect.PtrTo(IntType)
|
||||
PtrInt8Type = reflect.PtrTo(Int8Type)
|
||||
PtrInt16Type = reflect.PtrTo(Int16Type)
|
||||
PtrInt32Type = reflect.PtrTo(Int32Type)
|
||||
PtrInt64Type = reflect.PtrTo(Int64Type)
|
||||
|
||||
PtrUintType = reflect.PtrTo(UintType)
|
||||
PtrUint8Type = reflect.PtrTo(Uint8Type)
|
||||
PtrUint16Type = reflect.PtrTo(Uint16Type)
|
||||
PtrUint32Type = reflect.PtrTo(Uint32Type)
|
||||
PtrUint64Type = reflect.PtrTo(Uint64Type)
|
||||
|
||||
PtrFloat32Type = reflect.PtrTo(Float32Type)
|
||||
PtrFloat64Type = reflect.PtrTo(Float64Type)
|
||||
|
||||
PtrComplex64Type = reflect.PtrTo(Complex64Type)
|
||||
PtrComplex128Type = reflect.PtrTo(Complex128Type)
|
||||
|
||||
PtrStringType = reflect.PtrTo(StringType)
|
||||
PtrBoolType = reflect.PtrTo(BoolType)
|
||||
PtrByteType = reflect.PtrTo(ByteType)
|
||||
|
||||
PtrTimeType = reflect.PtrTo(TimeType)
|
||||
)
|
||||
|
||||
// Type2SQLType generate SQLType acorrding Go's type
|
||||
func Type2SQLType(t reflect.Type) (st SQLType) {
|
||||
switch k := t.Kind(); k {
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32:
|
||||
st = SQLType{Int, 0, 0}
|
||||
case reflect.Int64, reflect.Uint64:
|
||||
st = SQLType{BigInt, 0, 0}
|
||||
case reflect.Float32:
|
||||
st = SQLType{Float, 0, 0}
|
||||
case reflect.Float64:
|
||||
st = SQLType{Double, 0, 0}
|
||||
case reflect.Complex64, reflect.Complex128:
|
||||
st = SQLType{Varchar, 64, 0}
|
||||
case reflect.Array, reflect.Slice, reflect.Map:
|
||||
if t.Elem() == reflect.TypeOf(c_BYTE_DEFAULT) {
|
||||
st = SQLType{Blob, 0, 0}
|
||||
} else {
|
||||
st = SQLType{Text, 0, 0}
|
||||
}
|
||||
case reflect.Bool:
|
||||
st = SQLType{Bool, 0, 0}
|
||||
case reflect.String:
|
||||
st = SQLType{Varchar, 255, 0}
|
||||
case reflect.Struct:
|
||||
if t.ConvertibleTo(TimeType) {
|
||||
st = SQLType{DateTime, 0, 0}
|
||||
} else {
|
||||
// TODO need to handle association struct
|
||||
st = SQLType{Text, 0, 0}
|
||||
}
|
||||
case reflect.Ptr:
|
||||
st = Type2SQLType(t.Elem())
|
||||
default:
|
||||
st = SQLType{Text, 0, 0}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// default sql type change to go types
|
||||
func SQLType2Type(st SQLType) reflect.Type {
|
||||
name := strings.ToUpper(st.Name)
|
||||
switch name {
|
||||
case Bit, TinyInt, SmallInt, MediumInt, Int, Integer, Serial:
|
||||
return reflect.TypeOf(1)
|
||||
case BigInt, BigSerial:
|
||||
return reflect.TypeOf(int64(1))
|
||||
case Float, Real:
|
||||
return reflect.TypeOf(float32(1))
|
||||
case Double:
|
||||
return reflect.TypeOf(float64(1))
|
||||
case Char, NChar, Varchar, NVarchar, TinyText, Text, NText, MediumText, LongText, Enum, Set, Uuid, Clob, SysName:
|
||||
return reflect.TypeOf("")
|
||||
case TinyBlob, Blob, LongBlob, Bytea, Binary, MediumBlob, VarBinary, UniqueIdentifier:
|
||||
return reflect.TypeOf([]byte{})
|
||||
case Bool:
|
||||
return reflect.TypeOf(true)
|
||||
case DateTime, Date, Time, TimeStamp, TimeStampz, SmallDateTime, Year:
|
||||
return reflect.TypeOf(c_TIME_DEFAULT)
|
||||
case Decimal, Numeric, Money, SmallMoney:
|
||||
return reflect.TypeOf("")
|
||||
default:
|
||||
return reflect.TypeOf("")
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user