OSDN Git Service

Merge pull request #201 from Bytom/v0.1
[bytom/vapor.git] / vendor / github.com / jinzhu / gorm / dialect.go
diff --git a/vendor/github.com/jinzhu/gorm/dialect.go b/vendor/github.com/jinzhu/gorm/dialect.go
new file mode 100755 (executable)
index 0000000..27b308a
--- /dev/null
@@ -0,0 +1,138 @@
+package gorm
+
+import (
+       "database/sql"
+       "fmt"
+       "reflect"
+       "strconv"
+       "strings"
+)
+
+// Dialect interface contains behaviors that differ across SQL database
+type Dialect interface {
+       // GetName get dialect's name
+       GetName() string
+
+       // SetDB set db for dialect
+       SetDB(db SQLCommon)
+
+       // BindVar return the placeholder for actual values in SQL statements, in many dbs it is "?", Postgres using $1
+       BindVar(i int) string
+       // Quote quotes field name to avoid SQL parsing exceptions by using a reserved word as a field name
+       Quote(key string) string
+       // DataTypeOf return data's sql type
+       DataTypeOf(field *StructField) string
+
+       // HasIndex check has index or not
+       HasIndex(tableName string, indexName string) bool
+       // HasForeignKey check has foreign key or not
+       HasForeignKey(tableName string, foreignKeyName string) bool
+       // RemoveIndex remove index
+       RemoveIndex(tableName string, indexName string) error
+       // HasTable check has table or not
+       HasTable(tableName string) bool
+       // HasColumn check has column or not
+       HasColumn(tableName string, columnName string) bool
+       // ModifyColumn modify column's type
+       ModifyColumn(tableName string, columnName string, typ string) error
+
+       // LimitAndOffsetSQL return generated SQL with Limit and Offset, as mssql has special case
+       LimitAndOffsetSQL(limit, offset interface{}) string
+       // SelectFromDummyTable return select values, for most dbs, `SELECT values` just works, mysql needs `SELECT value FROM DUAL`
+       SelectFromDummyTable() string
+       // LastInsertIdReturningSuffix most dbs support LastInsertId, but postgres needs to use `RETURNING`
+       LastInsertIDReturningSuffix(tableName, columnName string) string
+       // DefaultValueStr
+       DefaultValueStr() string
+
+       // BuildKeyName returns a valid key name (foreign key, index key) for the given table, field and reference
+       BuildKeyName(kind, tableName string, fields ...string) string
+
+       // CurrentDatabase return current database name
+       CurrentDatabase() string
+}
+
+var dialectsMap = map[string]Dialect{}
+
+func newDialect(name string, db SQLCommon) Dialect {
+       if value, ok := dialectsMap[name]; ok {
+               dialect := reflect.New(reflect.TypeOf(value).Elem()).Interface().(Dialect)
+               dialect.SetDB(db)
+               return dialect
+       }
+
+       fmt.Printf("`%v` is not officially supported, running under compatibility mode.\n", name)
+       commontDialect := &commonDialect{}
+       commontDialect.SetDB(db)
+       return commontDialect
+}
+
+// RegisterDialect register new dialect
+func RegisterDialect(name string, dialect Dialect) {
+       dialectsMap[name] = dialect
+}
+
+// GetDialect gets the dialect for the specified dialect name
+func GetDialect(name string) (dialect Dialect, ok bool) {
+       dialect, ok = dialectsMap[name]
+       return
+}
+
+// ParseFieldStructForDialect get field's sql data type
+var ParseFieldStructForDialect = func(field *StructField, dialect Dialect) (fieldValue reflect.Value, sqlType string, size int, additionalType string) {
+       // Get redirected field type
+       var (
+               reflectType = field.Struct.Type
+               dataType, _ = field.TagSettingsGet("TYPE")
+       )
+
+       for reflectType.Kind() == reflect.Ptr {
+               reflectType = reflectType.Elem()
+       }
+
+       // Get redirected field value
+       fieldValue = reflect.Indirect(reflect.New(reflectType))
+
+       if gormDataType, ok := fieldValue.Interface().(interface {
+               GormDataType(Dialect) string
+       }); ok {
+               dataType = gormDataType.GormDataType(dialect)
+       }
+
+       // Get scanner's real value
+       if dataType == "" {
+               var getScannerValue func(reflect.Value)
+               getScannerValue = func(value reflect.Value) {
+                       fieldValue = value
+                       if _, isScanner := reflect.New(fieldValue.Type()).Interface().(sql.Scanner); isScanner && fieldValue.Kind() == reflect.Struct {
+                               getScannerValue(fieldValue.Field(0))
+                       }
+               }
+               getScannerValue(fieldValue)
+       }
+
+       // Default Size
+       if num, ok := field.TagSettingsGet("SIZE"); ok {
+               size, _ = strconv.Atoi(num)
+       } else {
+               size = 255
+       }
+
+       // Default type from tag setting
+       notNull, _ := field.TagSettingsGet("NOT NULL")
+       unique, _ := field.TagSettingsGet("UNIQUE")
+       additionalType = notNull + " " + unique
+       if value, ok := field.TagSettingsGet("DEFAULT"); ok {
+               additionalType = additionalType + " DEFAULT " + value
+       }
+
+       return fieldValue, dataType, size, strings.TrimSpace(additionalType)
+}
+
+func currentDatabaseAndTable(dialect Dialect, tableName string) (string, string) {
+       if strings.Contains(tableName, ".") {
+               splitStrings := strings.SplitN(tableName, ".", 2)
+               return splitStrings[0], splitStrings[1]
+       }
+       return dialect.CurrentDatabase(), tableName
+}