From 15c15acb7f9b1269dcd3b8095e71851aeacd508f Mon Sep 17 00:00:00 2001 From: Jason Hutchinson Date: Wed, 8 Nov 2017 14:49:02 -0600 Subject: [PATCH 1/2] add CreateSchemaCommand to Dialect interface --- dialect.go | 3 +++ dialect_mysql.go | 4 ++++ dialect_oracle.go | 4 ++++ dialect_postgres.go | 4 ++++ dialect_sqlite.go | 4 ++++ dialect_sqlserver.go | 4 ++++ table.go | 2 +- 7 files changed, 24 insertions(+), 1 deletion(-) diff --git a/dialect.go b/dialect.go index 22e30999..9c2c0cb6 100644 --- a/dialect.go +++ b/dialect.go @@ -72,6 +72,9 @@ type Dialect interface { IfSchemaNotExists(command, schema string) string IfTableExists(command, schema, table string) string IfTableNotExists(command, schema, table string) string + + // The command to create a new database/schema + CreateSchemaCommand() string } // IntegerAutoIncrInserter is implemented by dialects that can perform diff --git a/dialect_mysql.go b/dialect_mysql.go index 06606b8b..a2ff47f2 100644 --- a/dialect_mysql.go +++ b/dialect_mysql.go @@ -174,3 +174,7 @@ func (d MySQLDialect) IfTableExists(command, schema, table string) string { func (d MySQLDialect) IfTableNotExists(command, schema, table string) string { return fmt.Sprintf("%s if not exists", command) } + +func (d MySQLDialect) CreateSchemaCommand() string { + return "create schema" +} diff --git a/dialect_oracle.go b/dialect_oracle.go index c381380f..c7ba8cc6 100644 --- a/dialect_oracle.go +++ b/dialect_oracle.go @@ -144,3 +144,7 @@ func (d OracleDialect) IfTableExists(command, schema, table string) string { func (d OracleDialect) IfTableNotExists(command, schema, table string) string { return fmt.Sprintf("%s if not exists", command) } + +func (d OracleDialect) CreateSchemaCommand() string { + return "create schema" +} diff --git a/dialect_postgres.go b/dialect_postgres.go index a53973cd..ad2a4a26 100644 --- a/dialect_postgres.go +++ b/dialect_postgres.go @@ -150,3 +150,7 @@ func (d PostgresDialect) IfTableExists(command, schema, table string) string { func (d PostgresDialect) IfTableNotExists(command, schema, table string) string { return fmt.Sprintf("%s if not exists", command) } + +func (d PostgresDialect) CreateSchemaCommand() string { + return "create schema" +} diff --git a/dialect_sqlite.go b/dialect_sqlite.go index 7d9b2975..fccbd312 100644 --- a/dialect_sqlite.go +++ b/dialect_sqlite.go @@ -117,3 +117,7 @@ func (d SqliteDialect) IfTableExists(command, schema, table string) string { func (d SqliteDialect) IfTableNotExists(command, schema, table string) string { return fmt.Sprintf("%s if not exists", command) } + +func (d SqliteDialect) CreateSchemaCommand() string { + return "create schema" +} diff --git a/dialect_sqlserver.go b/dialect_sqlserver.go index 8808af59..b293e8ff 100644 --- a/dialect_sqlserver.go +++ b/dialect_sqlserver.go @@ -150,3 +150,7 @@ func (d SqlServerDialect) IfTableNotExists(command, schema, table string) string func (d SqlServerDialect) CreateIndexSuffix() string { return "" } func (d SqlServerDialect) DropIndexSuffix() string { return "" } + +func (d SqlServerDialect) CreateSchemaCommand() string { + return "create schema" +} diff --git a/table.go b/table.go index 5c513909..fe713ff9 100644 --- a/table.go +++ b/table.go @@ -176,7 +176,7 @@ func (t *TableMap) SqlForCreate(ifNotExists bool) string { dialect := t.dbmap.Dialect if strings.TrimSpace(t.SchemaName) != "" { - schemaCreate := "create schema" + schemaCreate := dialect.CreateSchemaCommand() if ifNotExists { s.WriteString(dialect.IfSchemaNotExists(schemaCreate, t.SchemaName)) } else { From af38f4280fbd7033024c8ab40608b88045b2c593 Mon Sep 17 00:00:00 2001 From: Jason Hutchinson Date: Wed, 8 Nov 2017 14:49:15 -0600 Subject: [PATCH 2/2] add CockroachDB support --- dialect_cockroachdb.go | 156 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 dialect_cockroachdb.go diff --git a/dialect_cockroachdb.go b/dialect_cockroachdb.go new file mode 100644 index 00000000..5f1ddea4 --- /dev/null +++ b/dialect_cockroachdb.go @@ -0,0 +1,156 @@ +// 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" + "time" +) + +type CockroachdbDialect struct { + suffix string +} + +func (d CockroachdbDialect) QuerySuffix() string { return ";" } + +func (d CockroachdbDialect) 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 CockroachdbDialect) AutoIncrStr() string { + return "" +} + +func (d CockroachdbDialect) AutoIncrBindValue() string { + return "default" +} + +func (d CockroachdbDialect) AutoIncrInsertSuffix(col *ColumnMap) string { + return " returning " + d.QuoteField(col.ColumnName) +} + +// Returns suffix +func (d CockroachdbDialect) CreateTableSuffix() string { + return d.suffix +} + +func (d CockroachdbDialect) CreateIndexSuffix() string { + return "using" +} + +func (d CockroachdbDialect) DropIndexSuffix() string { + return "" +} + +func (d CockroachdbDialect) TruncateClause() string { + return "truncate" +} + +func (d CockroachdbDialect) SleepClause(s time.Duration) string { + return fmt.Sprintf("pg_sleep(%f)", s.Seconds()) +} + +// Returns "$(i+1)" +func (d CockroachdbDialect) BindVar(i int) string { + return fmt.Sprintf("$%d", i+1) +} + +func (d CockroachdbDialect) 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 CockroachdbDialect) QuoteField(f string) string { + return `"` + f + `"` +} + +func (d CockroachdbDialect) QuotedTableForQuery(schema string, table string) string { + if strings.TrimSpace(schema) == "" { + return d.QuoteField(table) + } + + return schema + "." + d.QuoteField(table) +} + +func (d CockroachdbDialect) IfSchemaNotExists(command, schema string) string { + return fmt.Sprintf("%s if not exists", command) +} + +func (d CockroachdbDialect) IfTableExists(command, schema, table string) string { + return fmt.Sprintf("%s if exists", command) +} + +func (d CockroachdbDialect) IfTableNotExists(command, schema, table string) string { + return fmt.Sprintf("%s if not exists", command) +} + +func (d CockroachdbDialect) CreateSchemaCommand() string { + return "create database" +}