support for multiple dialects

This commit is contained in:
lqs 2020-07-01 19:54:03 +08:00
parent 49f6472d51
commit 47a1b9de22
6 changed files with 66 additions and 9 deletions

View File

@ -36,7 +36,7 @@ type database struct {
db *sql.DB
tx *sql.Tx
logger func(sql string, durationNano int64)
dialect string
dialect dialect
retryPolicy func(error) bool
enableCallerInfo bool
interceptor InterceptorFunc
@ -67,7 +67,7 @@ func Open(driverName string, dataSourceName string) (db Database, err error) {
}
}
db = &database{
dialect: driverName,
dialect: getDialectFromDriverName(driverName),
db: sqlDB,
}
return

View File

@ -30,6 +30,7 @@ func newMockDatabase() Database {
if err != nil {
panic(err)
}
db.(*database).dialect = dialectMySQL
return db
}

30
dialect.go Normal file
View File

@ -0,0 +1,30 @@
package sqlingo
type dialect int
const (
dialectUnknown dialect = iota
dialectMySQL
dialectSqlite3
dialectPostgres
dialectMSSQL
dialectCount
)
type dialectArray [dialectCount]string
func getDialectFromDriverName(driverName string) dialect {
switch driverName {
case "mysql":
return dialectMySQL
case "sqlite3":
return dialectSqlite3
case "postgres":
return dialectPostgres
case "sqlserver", "mssql":
return dialectMSSQL
default:
return dialectUnknown
}
}

View File

@ -174,6 +174,20 @@ func (e expression) GetSQL(scope scope) (string, error) {
return e.builder(scope)
}
func quoteIdentifier(identifier string) (result dialectArray) {
for dialect := dialect(0); dialect < dialectCount; dialect++ {
switch dialect {
case dialectMySQL:
result[dialect] = "`" + identifier + "`"
case dialectMSSQL:
result[dialect] = "[" + identifier + "]"
default:
result[dialect] = "\"" + identifier + "\""
}
}
return
}
func quoteString(s string) string {
bytes := []byte(s)
buf := make([]byte, len(s)*2+2)

View File

@ -19,14 +19,24 @@ type StringField interface {
}
func newFieldExpression(tableName string, fieldName string) expression {
shortFieldNameSql := getSQLForName(fieldName)
fullFieldNameSql := getSQLForName(tableName) + "." + shortFieldNameSql
tableNameSqlArray := quoteIdentifier(tableName)
fieldNameSqlArray := quoteIdentifier(fieldName)
var fullFieldNameSqlArray dialectArray
for dialect := dialect(0); dialect < dialectCount; dialect++ {
fullFieldNameSqlArray[dialect] = tableNameSqlArray[dialect] + "." + fieldNameSqlArray[dialect]
}
return expression{
builder: func(scope scope) (string, error) {
if len(scope.Tables) != 1 || scope.lastJoin != nil || scope.Tables[0].GetName() != tableName {
return fullFieldNameSql, nil
dialect := dialectUnknown
if scope.Database != nil {
dialect = scope.Database.dialect
}
return shortFieldNameSql, nil
if len(scope.Tables) != 1 || scope.lastJoin != nil || scope.Tables[0].GetName() != tableName {
return fullFieldNameSqlArray[dialect], nil
}
return fieldNameSqlArray[dialect], nil
},
}
}

View File

@ -2,9 +2,11 @@ package sqlingo
import "testing"
var dummyMySQLScope = scope{Database: &database{dialect: dialectMySQL}}
func assertValue(t *testing.T, value interface{}, expectedSql string) {
t.Helper()
if generatedSql, _, _ := getSQL(scope{}, value); generatedSql != expectedSql {
if generatedSql, _, _ := getSQL(dummyMySQLScope, value); generatedSql != expectedSql {
t.Errorf("value [%v] generated [%s] expected [%s]", value, generatedSql, expectedSql)
}
}
@ -18,7 +20,7 @@ func assertLastSql(t *testing.T, expectedSql string) {
func assertError(t *testing.T, value interface{}) {
t.Helper()
if generatedSql, _, err := getSQL(scope{}, value); err == nil {
if generatedSql, _, err := getSQL(dummyMySQLScope, value); err == nil {
t.Errorf("value [%v] generated [%s] expected error", value, generatedSql)
}
}