2014-07-02 13:47:30 +04:00
package gorm
import (
"fmt"
"reflect"
2016-01-19 15:58:38 +03:00
"strconv"
2015-02-17 17:55:14 +03:00
"time"
2014-07-02 13:47:30 +04:00
)
type commonDialect struct { }
2016-01-19 06:53:53 +03:00
func ( commonDialect ) BindVar ( i int ) string {
2015-03-17 05:40:42 +03:00
return "$$" // ?
2014-07-02 13:47:30 +04:00
}
2016-01-18 15:32:52 +03:00
func ( commonDialect ) Quote ( key string ) string {
return fmt . Sprintf ( ` "%s" ` , key )
2014-09-16 00:03:14 +04:00
}
2016-01-19 15:58:38 +03:00
func ( commonDialect ) DataTypeOf ( dataValue reflect . Value , tagSettings map [ string ] string ) string {
var size int
if num , ok := tagSettings [ "SIZE" ] ; ok {
size , _ = strconv . Atoi ( num )
}
switch dataValue . Kind ( ) {
2014-07-02 13:47:30 +04:00
case reflect . Bool :
return "BOOLEAN"
case reflect . Int , reflect . Int8 , reflect . Int16 , reflect . Int32 , reflect . Uint , reflect . Uint8 , reflect . Uint16 , reflect . Uint32 , reflect . Uintptr :
2016-01-19 15:58:38 +03:00
if _ , ok := tagSettings [ "AUTO_INCREMENT" ] ; ok {
2015-03-11 12:05:58 +03:00
return "INTEGER AUTO_INCREMENT"
}
2014-07-02 13:47:30 +04:00
return "INTEGER"
case reflect . Int64 , reflect . Uint64 :
2016-01-19 15:58:38 +03:00
if _ , ok := tagSettings [ "AUTO_INCREMENT" ] ; ok {
2015-03-11 12:05:58 +03:00
return "BIGINT AUTO_INCREMENT"
}
2014-07-02 13:47:30 +04:00
return "BIGINT"
case reflect . Float32 , reflect . Float64 :
return "FLOAT"
case reflect . String :
if size > 0 && size < 65532 {
return fmt . Sprintf ( "VARCHAR(%d)" , size )
}
2015-02-17 03:34:01 +03:00
return "VARCHAR(65532)"
2014-07-02 13:47:30 +04:00
case reflect . Struct :
2016-01-19 15:58:38 +03:00
if _ , ok := dataValue . Interface ( ) . ( time . Time ) ; ok {
2014-07-02 13:47:30 +04:00
return "TIMESTAMP"
}
default :
2016-01-19 15:58:38 +03:00
if _ , ok := dataValue . Interface ( ) . ( [ ] byte ) ; ok {
2014-07-02 13:47:30 +04:00
if size > 0 && size < 65532 {
return fmt . Sprintf ( "BINARY(%d)" , size )
}
2015-02-17 03:34:01 +03:00
return "BINARY(65532)"
2014-07-02 13:47:30 +04:00
}
}
2016-01-19 15:58:38 +03:00
panic ( fmt . Sprintf ( "invalid sql type %s (%s) for commonDialect" , dataValue . Type ( ) . Name ( ) , dataValue . Kind ( ) . String ( ) ) )
2014-07-02 13:47:30 +04:00
}
2016-01-18 15:32:52 +03:00
func ( c commonDialect ) HasIndex ( scope * Scope , tableName string , indexName string ) bool {
var (
count int
2016-01-19 06:53:53 +03:00
databaseName = c . currentDatabase ( scope )
2016-01-18 15:32:52 +03:00
)
c . RawScanInt ( scope , & count , "SELECT count(*) FROM INFORMATION_SCHEMA.STATISTICS WHERE table_schema = ? AND table_name = ? AND index_name = ?" , databaseName , tableName , indexName )
return count > 0
2014-07-30 10:18:15 +04:00
}
2016-01-18 15:32:52 +03:00
func ( commonDialect ) RemoveIndex ( scope * Scope , indexName string ) {
scope . Err ( scope . NewDB ( ) . Exec ( fmt . Sprintf ( "DROP INDEX %v ON %v" , indexName , scope . QuotedTableName ( ) ) ) . Error )
2014-07-02 13:47:30 +04:00
}
2015-03-17 05:40:42 +03:00
func ( c commonDialect ) HasTable ( scope * Scope , tableName string ) bool {
2015-08-06 22:37:26 +03:00
var (
count int
2016-01-19 06:53:53 +03:00
databaseName = c . currentDatabase ( scope )
2015-08-06 22:37:26 +03:00
)
2015-09-02 06:34:14 +03:00
c . RawScanInt ( scope , & count , "SELECT count(*) FROM INFORMATION_SCHEMA.TABLES WHERE table_schema = ? AND table_name = ?" , databaseName , tableName )
2014-07-02 13:47:30 +04:00
return count > 0
}
2015-03-17 05:40:42 +03:00
func ( c commonDialect ) HasColumn ( scope * Scope , tableName string , columnName string ) bool {
2015-08-06 22:37:26 +03:00
var (
count int
2016-01-19 06:53:53 +03:00
databaseName = c . currentDatabase ( scope )
2015-08-06 22:37:26 +03:00
)
2015-08-09 00:08:25 +03:00
c . RawScanInt ( scope , & count , "SELECT count(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = ? AND table_name = ? AND column_name = ?" , databaseName , tableName , columnName )
2015-03-02 18:02:40 +03:00
return count > 0
}
2015-08-09 00:08:25 +03:00
// RawScanInt scans the first column of the first row into the `scan' int pointer.
// This function captures raw query errors and propagates them to the original scope.
func ( commonDialect ) RawScanInt ( scope * Scope , scanPtr * int , query string , args ... interface { } ) {
scope . Err ( scope . NewDB ( ) . Raw ( query , args ... ) . Row ( ) . Scan ( scanPtr ) )
}
// RawScanString scans the first column of the first row into the `scan' string pointer.
// This function captures raw query errors and propagates them to the original scope.
func ( commonDialect ) RawScanString ( scope * Scope , scanPtr * string , query string , args ... interface { } ) {
scope . Err ( scope . NewDB ( ) . Raw ( query , args ... ) . Row ( ) . Scan ( scanPtr ) )
2014-07-29 08:02:03 +04:00
}
2015-08-06 22:37:26 +03:00
2016-01-19 06:53:53 +03:00
func ( commonDialect ) currentDatabase ( scope * Scope ) ( name string ) {
2015-08-11 18:59:59 +03:00
scope . Err ( scope . NewDB ( ) . Raw ( "SELECT DATABASE()" ) . Row ( ) . Scan ( & name ) )
return
2015-08-06 22:37:26 +03:00
}
2016-01-18 15:32:52 +03:00
func ( commonDialect ) LimitAndOffsetSQL ( limit , offset int ) ( sql string ) {
if limit >= 0 {
sql += fmt . Sprintf ( " LIMIT %d" , limit )
}
if offset >= 0 {
sql += fmt . Sprintf ( " OFFSET %d" , offset )
}
return
}
func ( commonDialect ) SelectFromDummyTable ( ) string {
return ""
}
2016-01-19 06:53:53 +03:00
func ( commonDialect ) LastInsertIdReturningSuffix ( tableName , columnName string ) string {
return ""
2016-01-18 15:32:52 +03:00
}