2014-09-16 19:32:35 +04:00
package gorm
import (
"fmt"
"reflect"
2016-02-14 08:51:34 +03:00
"strings"
2015-02-17 17:55:14 +03:00
"time"
2014-09-16 19:32:35 +04:00
)
2015-03-17 05:40:42 +03:00
type mssql struct {
commonDialect
2014-09-16 19:32:35 +04:00
}
2016-02-14 13:06:42 +03:00
func init ( ) {
RegisterDialect ( "mssql" , & mssql { } )
}
2016-02-13 18:51:36 +03:00
func ( mssql ) DataTypeOf ( field * StructField ) string {
2016-02-14 08:51:34 +03:00
var dataValue , sqlType , size , additionalType = ParseFieldStructForDialect ( field )
2016-02-13 18:51:36 +03:00
2016-02-14 08:51:34 +03:00
if sqlType == "" {
switch dataValue . Kind ( ) {
case reflect . Bool :
sqlType = "bit"
case reflect . Int , reflect . Int8 , reflect . Int16 , reflect . Int32 , reflect . Uint , reflect . Uint8 , reflect . Uint16 , reflect . Uint32 , reflect . Uintptr :
if _ , ok := field . TagSettings [ "AUTO_INCREMENT" ] ; ok || field . IsPrimaryKey {
sqlType = "int IDENTITY(1,1)"
} else {
sqlType = "int"
}
case reflect . Int64 , reflect . Uint64 :
if _ , ok := field . TagSettings [ "AUTO_INCREMENT" ] ; ok || field . IsPrimaryKey {
sqlType = "bigint IDENTITY(1,1)"
} else {
sqlType = "bigint"
}
case reflect . Float32 , reflect . Float64 :
sqlType = "float"
case reflect . String :
2014-09-16 19:32:35 +04:00
if size > 0 && size < 65532 {
2016-02-14 08:51:34 +03:00
sqlType = fmt . Sprintf ( "nvarchar(%d)" , size )
} else {
sqlType = "text"
}
case reflect . Struct :
if _ , ok := dataValue . Interface ( ) . ( time . Time ) ; ok {
sqlType = "datetime2"
}
default :
if _ , ok := dataValue . Interface ( ) . ( [ ] byte ) ; ok {
if size > 0 && size < 65532 {
sqlType = fmt . Sprintf ( "varchar(%d)" , size )
} else {
sqlType = "text"
}
2014-09-16 19:32:35 +04:00
}
}
}
2016-02-14 08:51:34 +03:00
if sqlType == "" {
panic ( fmt . Sprintf ( "invalid sql type %s (%s) for mssql" , dataValue . Type ( ) . Name ( ) , dataValue . Kind ( ) . String ( ) ) )
}
if strings . TrimSpace ( additionalType ) == "" {
return sqlType
}
return fmt . Sprintf ( "%v %v" , sqlType , additionalType )
2014-09-16 19:32:35 +04:00
}
2016-01-18 15:32:52 +03:00
func ( s mssql ) HasIndex ( scope * Scope , tableName string , indexName string ) bool {
var count int
s . RawScanInt ( scope , & count , "SELECT count(*) FROM sys.indexes WHERE name=? AND object_id=OBJECT_ID(?)" , indexName , tableName )
return count > 0
}
2015-03-17 05:40:42 +03:00
func ( s mssql ) 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 = s . currentDatabase ( scope )
2015-08-06 22:37:26 +03:00
)
2015-08-09 00:08:25 +03:00
s . RawScanInt ( scope , & count , "SELECT count(*) FROM INFORMATION_SCHEMA.tables WHERE table_name = ? AND table_catalog = ?" , tableName , databaseName )
2014-09-16 19:32:35 +04:00
return count > 0
}
2015-03-17 05:40:42 +03:00
func ( s mssql ) 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 = s . currentDatabase ( scope )
2015-08-06 22:37:26 +03:00
)
2015-08-09 00:08:25 +03:00
s . RawScanInt ( scope , & count , "SELECT count(*) FROM information_schema.columns WHERE table_catalog = ? AND table_name = ? AND column_name = ?" , databaseName , tableName , columnName )
2014-09-16 19:32:35 +04:00
return count > 0
}
2016-01-19 06:53:53 +03:00
func ( s mssql ) currentDatabase ( scope * Scope ) ( name string ) {
2015-08-11 19:05:53 +03:00
s . RawScanString ( scope , & name , "SELECT DB_NAME() AS [Current Database]" )
2015-08-11 18:59:59 +03:00
return
2015-08-06 22:37:26 +03:00
}
2016-01-18 15:32:52 +03:00
func ( mssql ) LimitAndOffsetSQL ( limit , offset int ) ( sql string ) {
if limit < 0 && offset < 0 {
return
}
if offset < 0 {
offset = 0
}
sql += fmt . Sprintf ( " OFFSET %d ROWS" , offset )
if limit >= 0 {
sql += fmt . Sprintf ( " FETCH NEXT %d ROWS ONLY" , limit )
}
return
}