Added support for SQL Server 2005

This commit is contained in:
Daniel Sullivan 2019-10-24 09:37:35 +09:00
parent 8072fb9d85
commit e20251c975
8 changed files with 56 additions and 19 deletions

View File

@ -13,6 +13,7 @@ import (
type cacheItem struct {
dataMutex sync.RWMutex
data interface{}
err error
created int64
accessMutex sync.RWMutex
accessCount int64
@ -97,7 +98,7 @@ func (c cache) Empty() {
}
}
func (c cache) GetItem(key string, offset int64) interface{} {
func (c cache) GetItem(key string, offset int64) (interface{}, error) {
fmt.Print("Getting item " + key + " ... ")
c.mutex.RLock()
@ -112,7 +113,7 @@ func (c cache) GetItem(key string, offset int64) interface{} {
if (item.created+offset > time.Now().Unix()) || offset == -1 {
fmt.Print("Found \n")
c.mutex.RUnlock()
return item.data
return item.data, item.err
}
fmt.Print("Expired \n")
@ -121,7 +122,7 @@ func (c cache) GetItem(key string, offset int64) interface{} {
}
c.mutex.RUnlock()
return nil
return nil, nil
}
type modelId struct {
@ -129,7 +130,7 @@ type modelId struct {
id string
}
func (c *cache) StoreItem(key string, data interface{}) {
func (c *cache) StoreItem(key string, data interface{}, errors error) {
fmt.Println("Storing item " + key)
// Affected IDs
@ -158,12 +159,14 @@ func (c *cache) StoreItem(key string, data interface{}) {
created: time.Now().UnixNano(),
accessCount: 1,
data: data,
err: errors,
}
c.mutex.Unlock()
} else {
c.mutex.RLock()
c.database[key].dataMutex.Lock()
c.database[key].data = data
c.database[key].err = errors
c.database[key].created = time.Now().UnixNano()
c.database[key].dataMutex.Unlock()
c.mutex.RUnlock()

View File

@ -75,17 +75,19 @@ func queryCallback(scope *Scope) {
if cacheOperation != nil {
// If the time is > 0, simply provide the cached results
if *cacheOperation > 0 || *cacheOperation == -1 {
cacheResults := scope.CacheStore().GetItem(key, *cacheOperation)
cacheResults, err := scope.CacheStore().GetItem(key, *cacheOperation)
if cacheResults != nil {
scope.Err(err) // Add any error if exists
results.Set(reflect.ValueOf(cacheResults))
fmt.Println("Cache HIT")
readFromDB = false
} else {
readFromDB = true
fmt.Println()
fmt.Println("Cache MISS")
writeToCache = true
}
} else {
fmt.Println("Cache REFRESH")
readFromDB = true
writeToCache = true
}
@ -128,7 +130,7 @@ func queryCallback(scope *Scope) {
}
if writeToCache {
scope.CacheStore().StoreItem(key, results.Interface())
scope.CacheStore().StoreItem(key, results.Interface(), scope.db.Error)
}
}
}

View File

@ -36,6 +36,8 @@ type Dialect interface {
// ModifyColumn modify column's type
ModifyColumn(tableName string, columnName string, typ string) error
HasTop(limit interface{}) string
// 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`
@ -81,6 +83,10 @@ func GetDialect(name string) (dialect Dialect, ok bool) {
return
}
func HasTop(limit interface{}) string {
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

View File

@ -40,6 +40,10 @@ func (commonDialect) Quote(key string) string {
return fmt.Sprintf(`"%s"`, key)
}
func (commonDialect) HasTop(limit interface{}) string {
return ""
}
func (s *commonDialect) fieldCanAutoIncrement(field *StructField) bool {
if value, ok := field.TagSettingsGet("AUTO_INCREMENT"); ok {
return strings.ToLower(value) != "false"

View File

@ -25,6 +25,10 @@ func (mysql) GetName() string {
return "mysql"
}
func (mysql) HasTop(limit interface{}) string {
return ""
}
func (mysql) Quote(key string) string {
return fmt.Sprintf("`%s`", key)
}

View File

@ -21,6 +21,10 @@ func (postgres) GetName() string {
return "postgres"
}
func (postgres) HasTop(limit interface{}) string {
return ""
}
func (postgres) BindVar(i int) string {
return fmt.Sprintf("$%v", i)
}

View File

@ -168,20 +168,30 @@ func (s mssql) CurrentDatabase() (name string) {
return
}
func (mssql) LimitAndOffsetSQL(limit, offset interface{}) (sql string) {
if offset != nil {
if parsedOffset, err := strconv.ParseInt(fmt.Sprint(offset), 0, 0); err == nil && parsedOffset >= 0 {
sql += fmt.Sprintf(" OFFSET %d ROWS", parsedOffset)
}
}
func (mssql) HasTop(limit interface{}) (sql string) {
if limit != nil {
if parsedLimit, err := strconv.ParseInt(fmt.Sprint(limit), 0, 0); err == nil && parsedLimit >= 0 {
if sql == "" {
// add default zero offset
sql += " OFFSET 0 ROWS"
sql += fmt.Sprintf(" TOP(%d)", parsedLimit)
}
sql += fmt.Sprintf(" FETCH NEXT %d ROWS ONLY", parsedLimit)
}
return
}
func (mssql) LimitAndOffsetSQL(limit, offset interface{}) (sql string) {
if offset != nil {
//if parsedOffset, err := strconv.ParseInt(fmt.Sprint(offset), 0, 0); err == nil && parsedOffset >= 0 {
// sql += fmt.Sprintf(" OFFSET %d ROWS", parsedOffset)
//}
}
if limit != nil {
//if parsedLimit, err := strconv.ParseInt(fmt.Sprint(limit), 0, 0); err == nil && parsedLimit >= 0 {
// if sql == "" {
// // add default zero offset
// sql += " OFFSET 0 ROWS"
// }
// sql += fmt.Sprintf(" FETCH NEXT %d ROWS ONLY", parsedLimit)
//}
}
return
}

View File

@ -905,11 +905,15 @@ func (scope *Scope) tableSQL() string {
}
}
func (scope *Scope) needTop() string {
return scope.Dialect().HasTop(scope.Search.limit)
}
func (scope *Scope) prepareQuerySQL() {
if scope.Search.raw {
scope.Raw(scope.CombinedConditionSql())
} else {
scope.Raw(fmt.Sprintf("SELECT %v FROM %v %v", scope.selectSQL(), scope.tableSQL(), scope.CombinedConditionSql()))
scope.Raw(fmt.Sprintf("SELECT %v %v FROM %v %v", scope.needTop(), scope.selectSQL(), scope.tableSQL(), scope.CombinedConditionSql()))
}
return
}