gorm/dialect_sqlite3.go
Gerhard Gruber c807fe3202 Started with expression extension
Improved questionmark parameter placeholder replacementw

Added support for subqueries in Where and Having clauses

Queries can be transformed into subqueries by calling .Subquery() on a db object

See main_test.go:TestQueryBuilderSubselectInWhere

Fixed comment spacing

Refactoring, adding Having Subquery support, allowing db.T for tablenames

Removed quoting from tablename in db.T, use db.QT for that

Refactoring, adding Having Subquery support, allowing db.T for tablenames

Added changes

Started with expression extension

Refactoring, adding Having Subquery support, allowing db.T for tablenames

Added method to easily update fields of the Model struct

Added column comparison and Join support

Added subquery support for InnerJoin querybuilder

Fixed column comparison

Added support for column prefixes

Models can set their column prefix by implementing the method ColumnPrefix() string

Fixed multi-parameter subselects and introduced aliasing

Improved Related method

Improved Related method to search for foreign key struct fields with the suffix "ID" (additional to "Id")

Got QueryExpr support from upstream

Added support for subqueries in Where and Having clauses

Queries can be transformed into subqueries by calling .Subquery() on a db object

See main_test.go:TestQueryBuilderSubselectInWhere

Improved questionmark parameter placeholder replacementw

Refactoring, adding Having Subquery support, allowing db.T for tablenames

Removed quoting from tablename in db.T, use db.QT for that

Removed quoting from tablename in db.T, use db.QT for that

Added changes

Added method to easily update fields of the Model struct

Fixed column comparison

Added support for column prefixes

Models can set their column prefix by implementing the method ColumnPrefix() string

Fixed multi-parameter subselects and introduced aliasing

Improved Related method

Improved Related method to search for foreign key struct fields with the suffix "ID" (additional to "Id")

Added select extension for multiple columns

Added support for LEFT RIGHT OUTER joins

Fixed slice support for lexpr.In()

Publizised LExpr

Added DateFormatting for all dialects

Added SUM function for columns

Fixed FormatDate

Added count for column

Removed literal expressions LExpr

Rewrote LExpr methods to work with expr structs.

Added methods BAnd and BOr (bitwise & and | )

Added SetLogWriter method

Added NotIn query expression

Added Distinct query expression

Added DistinctColumn query expression

Same as Distinct but returns a string

Added method OnExp to jexpr

Improved query expression .Eq() method for nil pointers

Fixed rebase errors
2018-02-26 16:00:19 +01:00

125 lines
3.0 KiB
Go

package gorm
import (
"fmt"
"reflect"
"strings"
"time"
)
type sqlite3 struct {
commonDialect
}
func init() {
RegisterDialect("sqlite3", &sqlite3{})
}
func (sqlite3) GetName() string {
return "sqlite3"
}
// Get Data Type for Sqlite Dialect
func (s *sqlite3) DataTypeOf(field *StructField) string {
var dataValue, sqlType, size, additionalType = ParseFieldStructForDialect(field, s)
if sqlType == "" {
switch dataValue.Kind() {
case reflect.Bool:
sqlType = "bool"
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uintptr:
if s.fieldCanAutoIncrement(field) {
field.TagSettings["AUTO_INCREMENT"] = "AUTO_INCREMENT"
sqlType = "integer primary key autoincrement"
} else {
sqlType = "integer"
}
case reflect.Int64, reflect.Uint64:
if s.fieldCanAutoIncrement(field) {
field.TagSettings["AUTO_INCREMENT"] = "AUTO_INCREMENT"
sqlType = "integer primary key autoincrement"
} else {
sqlType = "bigint"
}
case reflect.Float32, reflect.Float64:
sqlType = "real"
case reflect.String:
if size > 0 && size < 65532 {
sqlType = fmt.Sprintf("varchar(%d)", size)
} else {
sqlType = "text"
}
case reflect.Struct:
if _, ok := dataValue.Interface().(time.Time); ok {
sqlType = "datetime"
}
default:
if IsByteArrayOrSlice(dataValue) {
sqlType = "blob"
}
}
}
if sqlType == "" {
panic(fmt.Sprintf("invalid sql type %s (%s) for sqlite3", dataValue.Type().Name(), dataValue.Kind().String()))
}
if strings.TrimSpace(additionalType) == "" {
return sqlType
}
return fmt.Sprintf("%v %v", sqlType, additionalType)
}
func (s sqlite3) HasIndex(tableName string, indexName string) bool {
var count int
s.db.QueryRow(fmt.Sprintf("SELECT count(*) FROM sqlite_master WHERE tbl_name = ? AND sql LIKE '%%INDEX %v ON%%'", indexName), tableName).Scan(&count)
return count > 0
}
func (s sqlite3) HasTable(tableName string) bool {
var count int
s.db.QueryRow("SELECT count(*) FROM sqlite_master WHERE type='table' AND name=?", tableName).Scan(&count)
return count > 0
}
func (s sqlite3) HasColumn(tableName string, columnName string) bool {
var count int
s.db.QueryRow(fmt.Sprintf("SELECT count(*) FROM sqlite_master WHERE tbl_name = ? AND (sql LIKE '%%\"%v\" %%' OR sql LIKE '%%%v %%');\n", columnName, columnName), tableName).Scan(&count)
return count > 0
}
func (s sqlite3) CurrentDatabase() (name string) {
var (
ifaces = make([]interface{}, 3)
pointers = make([]*string, 3)
i int
)
for i = 0; i < 3; i++ {
ifaces[i] = &pointers[i]
}
if err := s.db.QueryRow("PRAGMA database_list").Scan(ifaces...); err != nil {
return
}
if pointers[1] != nil {
name = *pointers[1]
}
return
}
func (sqlite3) FormatDate(e *expr, format string) *expr {
mapping := map[rune]string{
'y': "%Y",
'm': "%m",
'w': "%W",
'd': "%d",
'D': "%w",
'h': "%H",
'M': "%M",
's': "%S",
}
parsedFormat := parseDateFormat(format, mapping)
e.expr = "(strftime('" + parsedFormat + "', " + e.expr + "))"
return e
}