172 lines
4.1 KiB
Go
172 lines
4.1 KiB
Go
|
// Copyright 2012 James Cooper. All rights reserved.
|
||
|
// Use of this source code is governed by a MIT-style
|
||
|
// license that can be found in the LICENSE file.
|
||
|
|
||
|
// Package gorp provides a simple way to marshal Go structs to and from
|
||
|
// SQL databases. It uses the database/sql package, and should work with any
|
||
|
// compliant database/sql driver.
|
||
|
//
|
||
|
// Source code and project home:
|
||
|
// https://github.com/go-gorp/gorp
|
||
|
//
|
||
|
package gorp
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"reflect"
|
||
|
"strings"
|
||
|
)
|
||
|
|
||
|
// Implementation of Dialect for MySQL databases.
|
||
|
type MySQLDialect struct {
|
||
|
|
||
|
// Engine is the storage engine to use "InnoDB" vs "MyISAM" for example
|
||
|
Engine string
|
||
|
|
||
|
// Encoding is the character encoding to use for created tables
|
||
|
Encoding string
|
||
|
}
|
||
|
|
||
|
func (d MySQLDialect) QuerySuffix() string { return ";" }
|
||
|
|
||
|
func (d MySQLDialect) ToSqlType(val reflect.Type, maxsize int, isAutoIncr bool) string {
|
||
|
switch val.Kind() {
|
||
|
case reflect.Ptr:
|
||
|
return d.ToSqlType(val.Elem(), maxsize, isAutoIncr)
|
||
|
case reflect.Bool:
|
||
|
return "boolean"
|
||
|
case reflect.Int8:
|
||
|
return "tinyint"
|
||
|
case reflect.Uint8:
|
||
|
return "tinyint unsigned"
|
||
|
case reflect.Int16:
|
||
|
return "smallint"
|
||
|
case reflect.Uint16:
|
||
|
return "smallint unsigned"
|
||
|
case reflect.Int, reflect.Int32:
|
||
|
return "int"
|
||
|
case reflect.Uint, reflect.Uint32:
|
||
|
return "int unsigned"
|
||
|
case reflect.Int64:
|
||
|
return "bigint"
|
||
|
case reflect.Uint64:
|
||
|
return "bigint unsigned"
|
||
|
case reflect.Float64, reflect.Float32:
|
||
|
return "double"
|
||
|
case reflect.Slice:
|
||
|
if val.Elem().Kind() == reflect.Uint8 {
|
||
|
return "mediumblob"
|
||
|
}
|
||
|
}
|
||
|
|
||
|
switch val.Name() {
|
||
|
case "NullInt64":
|
||
|
return "bigint"
|
||
|
case "NullFloat64":
|
||
|
return "double"
|
||
|
case "NullBool":
|
||
|
return "tinyint"
|
||
|
case "Time":
|
||
|
return "datetime"
|
||
|
}
|
||
|
|
||
|
if maxsize < 1 {
|
||
|
maxsize = 255
|
||
|
}
|
||
|
|
||
|
/* == About varchar(N) ==
|
||
|
* N is number of characters.
|
||
|
* A varchar column can store up to 65535 bytes.
|
||
|
* Remember that 1 character is 3 bytes in utf-8 charset.
|
||
|
* Also remember that each row can store up to 65535 bytes,
|
||
|
* and you have some overheads, so it's not possible for a
|
||
|
* varchar column to have 65535/3 characters really.
|
||
|
* So it would be better to use 'text' type in stead of
|
||
|
* large varchar type.
|
||
|
*/
|
||
|
if maxsize < 256 {
|
||
|
return fmt.Sprintf("varchar(%d)", maxsize)
|
||
|
} else {
|
||
|
return "text"
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Returns auto_increment
|
||
|
func (d MySQLDialect) AutoIncrStr() string {
|
||
|
return "auto_increment"
|
||
|
}
|
||
|
|
||
|
func (d MySQLDialect) AutoIncrBindValue() string {
|
||
|
return "null"
|
||
|
}
|
||
|
|
||
|
func (d MySQLDialect) AutoIncrInsertSuffix(col *ColumnMap) string {
|
||
|
return ""
|
||
|
}
|
||
|
|
||
|
// Returns engine=%s charset=%s based on values stored on struct
|
||
|
func (d MySQLDialect) CreateTableSuffix() string {
|
||
|
if d.Engine == "" || d.Encoding == "" {
|
||
|
msg := "gorp - undefined"
|
||
|
|
||
|
if d.Engine == "" {
|
||
|
msg += " MySQLDialect.Engine"
|
||
|
}
|
||
|
if d.Engine == "" && d.Encoding == "" {
|
||
|
msg += ","
|
||
|
}
|
||
|
if d.Encoding == "" {
|
||
|
msg += " MySQLDialect.Encoding"
|
||
|
}
|
||
|
msg += ". Check that your MySQLDialect was correctly initialized when declared."
|
||
|
panic(msg)
|
||
|
}
|
||
|
|
||
|
return fmt.Sprintf(" engine=%s charset=%s", d.Engine, d.Encoding)
|
||
|
}
|
||
|
|
||
|
func (m MySQLDialect) CreateIndexSuffix() string {
|
||
|
return "using"
|
||
|
}
|
||
|
|
||
|
func (m MySQLDialect) DropIndexSuffix() string {
|
||
|
return "on"
|
||
|
}
|
||
|
|
||
|
func (m MySQLDialect) TruncateClause() string {
|
||
|
return "truncate"
|
||
|
}
|
||
|
|
||
|
// Returns "?"
|
||
|
func (d MySQLDialect) BindVar(i int) string {
|
||
|
return "?"
|
||
|
}
|
||
|
|
||
|
func (d MySQLDialect) InsertAutoIncr(exec SqlExecutor, insertSql string, params ...interface{}) (int64, error) {
|
||
|
return standardInsertAutoIncr(exec, insertSql, params...)
|
||
|
}
|
||
|
|
||
|
func (d MySQLDialect) QuoteField(f string) string {
|
||
|
return "`" + f + "`"
|
||
|
}
|
||
|
|
||
|
func (d MySQLDialect) QuotedTableForQuery(schema string, table string) string {
|
||
|
if strings.TrimSpace(schema) == "" {
|
||
|
return d.QuoteField(table)
|
||
|
}
|
||
|
|
||
|
return schema + "." + d.QuoteField(table)
|
||
|
}
|
||
|
|
||
|
func (d MySQLDialect) IfSchemaNotExists(command, schema string) string {
|
||
|
return fmt.Sprintf("%s if not exists", command)
|
||
|
}
|
||
|
|
||
|
func (d MySQLDialect) IfTableExists(command, schema, table string) string {
|
||
|
return fmt.Sprintf("%s if exists", command)
|
||
|
}
|
||
|
|
||
|
func (d MySQLDialect) IfTableNotExists(command, schema, table string) string {
|
||
|
return fmt.Sprintf("%s if not exists", command)
|
||
|
}
|