forked from mystiq/dex
147 lines
3.4 KiB
Go
147 lines
3.4 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"
|
|
)
|
|
|
|
type PostgresDialect struct {
|
|
suffix string
|
|
}
|
|
|
|
func (d PostgresDialect) QuerySuffix() string { return ";" }
|
|
|
|
func (d PostgresDialect) 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.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32:
|
|
if isAutoIncr {
|
|
return "serial"
|
|
}
|
|
return "integer"
|
|
case reflect.Int64, reflect.Uint64:
|
|
if isAutoIncr {
|
|
return "bigserial"
|
|
}
|
|
return "bigint"
|
|
case reflect.Float64:
|
|
return "double precision"
|
|
case reflect.Float32:
|
|
return "real"
|
|
case reflect.Slice:
|
|
if val.Elem().Kind() == reflect.Uint8 {
|
|
return "bytea"
|
|
}
|
|
}
|
|
|
|
switch val.Name() {
|
|
case "NullInt64":
|
|
return "bigint"
|
|
case "NullFloat64":
|
|
return "double precision"
|
|
case "NullBool":
|
|
return "boolean"
|
|
case "Time", "NullTime":
|
|
return "timestamp with time zone"
|
|
}
|
|
|
|
if maxsize > 0 {
|
|
return fmt.Sprintf("varchar(%d)", maxsize)
|
|
} else {
|
|
return "text"
|
|
}
|
|
|
|
}
|
|
|
|
// Returns empty string
|
|
func (d PostgresDialect) AutoIncrStr() string {
|
|
return ""
|
|
}
|
|
|
|
func (d PostgresDialect) AutoIncrBindValue() string {
|
|
return "default"
|
|
}
|
|
|
|
func (d PostgresDialect) AutoIncrInsertSuffix(col *ColumnMap) string {
|
|
return " returning " + col.ColumnName
|
|
}
|
|
|
|
// Returns suffix
|
|
func (d PostgresDialect) CreateTableSuffix() string {
|
|
return d.suffix
|
|
}
|
|
|
|
func (d PostgresDialect) CreateIndexSuffix() string {
|
|
return "using"
|
|
}
|
|
|
|
func (d PostgresDialect) DropIndexSuffix() string {
|
|
return ""
|
|
}
|
|
|
|
func (d PostgresDialect) TruncateClause() string {
|
|
return "truncate"
|
|
}
|
|
|
|
// Returns "$(i+1)"
|
|
func (d PostgresDialect) BindVar(i int) string {
|
|
return fmt.Sprintf("$%d", i+1)
|
|
}
|
|
|
|
func (d PostgresDialect) InsertAutoIncrToTarget(exec SqlExecutor, insertSql string, target interface{}, params ...interface{}) error {
|
|
rows, err := exec.query(insertSql, params...)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer rows.Close()
|
|
|
|
if !rows.Next() {
|
|
return fmt.Errorf("No serial value returned for insert: %s Encountered error: %s", insertSql, rows.Err())
|
|
}
|
|
if err := rows.Scan(target); err != nil {
|
|
return err
|
|
}
|
|
if rows.Next() {
|
|
return fmt.Errorf("more than two serial value returned for insert: %s", insertSql)
|
|
}
|
|
return rows.Err()
|
|
}
|
|
|
|
func (d PostgresDialect) QuoteField(f string) string {
|
|
return `"` + strings.ToLower(f) + `"`
|
|
}
|
|
|
|
func (d PostgresDialect) QuotedTableForQuery(schema string, table string) string {
|
|
if strings.TrimSpace(schema) == "" {
|
|
return d.QuoteField(table)
|
|
}
|
|
|
|
return schema + "." + d.QuoteField(table)
|
|
}
|
|
|
|
func (d PostgresDialect) IfSchemaNotExists(command, schema string) string {
|
|
return fmt.Sprintf("%s if not exists", command)
|
|
}
|
|
|
|
func (d PostgresDialect) IfTableExists(command, schema, table string) string {
|
|
return fmt.Sprintf("%s if exists", command)
|
|
}
|
|
|
|
func (d PostgresDialect) IfTableNotExists(command, schema, table string) string {
|
|
return fmt.Sprintf("%s if not exists", command)
|
|
}
|