// 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) }