forked from go-gorp/gorp
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Restore dialect_postgres.go and dialect_postgres_test.go Restore relevant README sections and interface test. Restore GitHub Workflow configuration.
- Loading branch information
Showing
5 changed files
with
353 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
// 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 | ||
|
||
import ( | ||
"fmt" | ||
"reflect" | ||
"strings" | ||
"time" | ||
) | ||
|
||
type PostgresDialect struct { | ||
suffix string | ||
LowercaseFields bool | ||
} | ||
|
||
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 " + d.QuoteField(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" | ||
} | ||
|
||
func (d PostgresDialect) SleepClause(s time.Duration) string { | ||
return fmt.Sprintf("pg_sleep(%f)", s.Seconds()) | ||
} | ||
|
||
// 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 { | ||
if d.LowercaseFields { | ||
return `"` + strings.ToLower(f) + `"` | ||
} | ||
return `"` + 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) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
// 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. | ||
|
||
// +build !integration | ||
|
||
package gorp_test | ||
|
||
import ( | ||
"database/sql" | ||
"reflect" | ||
"testing" | ||
"time" | ||
|
||
"github.com/go-gorp/gorp/v3" | ||
"github.com/poy/onpar" | ||
"github.com/poy/onpar/expect" | ||
"github.com/poy/onpar/matchers" | ||
) | ||
|
||
func TestPostgresDialect(t *testing.T) { | ||
o := onpar.New() | ||
defer o.Run(t) | ||
|
||
o.BeforeEach(func(t *testing.T) (expect.Expectation, gorp.PostgresDialect) { | ||
return expect.New(t), gorp.PostgresDialect{ | ||
LowercaseFields: false, | ||
} | ||
}) | ||
|
||
o.Group("ToSqlType", func() { | ||
tests := []struct { | ||
name string | ||
value interface{} | ||
maxSize int | ||
autoIncr bool | ||
expected string | ||
}{ | ||
{"bool", true, 0, false, "boolean"}, | ||
{"int8", int8(1), 0, false, "integer"}, | ||
{"uint8", uint8(1), 0, false, "integer"}, | ||
{"int16", int16(1), 0, false, "integer"}, | ||
{"uint16", uint16(1), 0, false, "integer"}, | ||
{"int32", int32(1), 0, false, "integer"}, | ||
{"int (treated as int32)", int(1), 0, false, "integer"}, | ||
{"uint32", uint32(1), 0, false, "integer"}, | ||
{"uint (treated as uint32)", uint(1), 0, false, "integer"}, | ||
{"int64", int64(1), 0, false, "bigint"}, | ||
{"uint64", uint64(1), 0, false, "bigint"}, | ||
{"float32", float32(1), 0, false, "real"}, | ||
{"float64", float64(1), 0, false, "double precision"}, | ||
{"[]uint8", []uint8{1}, 0, false, "bytea"}, | ||
{"NullInt64", sql.NullInt64{}, 0, false, "bigint"}, | ||
{"NullFloat64", sql.NullFloat64{}, 0, false, "double precision"}, | ||
{"NullBool", sql.NullBool{}, 0, false, "boolean"}, | ||
{"Time", time.Time{}, 0, false, "timestamp with time zone"}, | ||
{"default-size string", "", 0, false, "text"}, | ||
{"sized string", "", 50, false, "varchar(50)"}, | ||
{"large string", "", 1024, false, "varchar(1024)"}, | ||
} | ||
for _, t := range tests { | ||
o.Spec(t.name, func(expect expect.Expectation, dialect gorp.PostgresDialect) { | ||
typ := reflect.TypeOf(t.value) | ||
sqlType := dialect.ToSqlType(typ, t.maxSize, t.autoIncr) | ||
expect(sqlType).To(matchers.Equal(t.expected)) | ||
}) | ||
} | ||
}) | ||
|
||
o.Spec("AutoIncrStr", func(expect expect.Expectation, dialect gorp.PostgresDialect) { | ||
expect(dialect.AutoIncrStr()).To(matchers.Equal("")) | ||
}) | ||
|
||
o.Spec("AutoIncrBindValue", func(expect expect.Expectation, dialect gorp.PostgresDialect) { | ||
expect(dialect.AutoIncrBindValue()).To(matchers.Equal("default")) | ||
}) | ||
|
||
o.Spec("AutoIncrInsertSuffix", func(expect expect.Expectation, dialect gorp.PostgresDialect) { | ||
cm := gorp.ColumnMap{ | ||
ColumnName: "foo", | ||
} | ||
expect(dialect.AutoIncrInsertSuffix(&cm)).To(matchers.Equal(` returning "foo"`)) | ||
}) | ||
|
||
o.Spec("CreateTableSuffix", func(expect expect.Expectation, dialect gorp.PostgresDialect) { | ||
expect(dialect.CreateTableSuffix()).To(matchers.Equal("")) | ||
}) | ||
|
||
o.Spec("CreateIndexSuffix", func(expect expect.Expectation, dialect gorp.PostgresDialect) { | ||
expect(dialect.CreateIndexSuffix()).To(matchers.Equal("using")) | ||
}) | ||
|
||
o.Spec("DropIndexSuffix", func(expect expect.Expectation, dialect gorp.PostgresDialect) { | ||
expect(dialect.DropIndexSuffix()).To(matchers.Equal("")) | ||
}) | ||
|
||
o.Spec("TruncateClause", func(expect expect.Expectation, dialect gorp.PostgresDialect) { | ||
expect(dialect.TruncateClause()).To(matchers.Equal("truncate")) | ||
}) | ||
|
||
o.Spec("SleepClause", func(expect expect.Expectation, dialect gorp.PostgresDialect) { | ||
expect(dialect.SleepClause(1 * time.Second)).To(matchers.Equal("pg_sleep(1.000000)")) | ||
expect(dialect.SleepClause(100 * time.Millisecond)).To(matchers.Equal("pg_sleep(0.100000)")) | ||
}) | ||
|
||
o.Spec("BindVar", func(expect expect.Expectation, dialect gorp.PostgresDialect) { | ||
expect(dialect.BindVar(0)).To(matchers.Equal("$1")) | ||
expect(dialect.BindVar(4)).To(matchers.Equal("$5")) | ||
}) | ||
|
||
o.Group("QuoteField", func() { | ||
o.Spec("By default, case is preserved", func(expect expect.Expectation, dialect gorp.PostgresDialect) { | ||
expect(dialect.QuoteField("Foo")).To(matchers.Equal(`"Foo"`)) | ||
expect(dialect.QuoteField("bar")).To(matchers.Equal(`"bar"`)) | ||
}) | ||
|
||
o.Group("With LowercaseFields set to true", func() { | ||
o.BeforeEach(func(expect expect.Expectation, dialect gorp.PostgresDialect) (expect.Expectation, gorp.PostgresDialect) { | ||
dialect.LowercaseFields = true | ||
return expect, dialect | ||
}) | ||
|
||
o.Spec("fields are lowercased", func(expect expect.Expectation, dialect gorp.PostgresDialect) { | ||
expect(dialect.QuoteField("Foo")).To(matchers.Equal(`"foo"`)) | ||
}) | ||
}) | ||
}) | ||
|
||
o.Group("QuotedTableForQuery", func() { | ||
o.Spec("using the default schema", func(expect expect.Expectation, dialect gorp.PostgresDialect) { | ||
expect(dialect.QuotedTableForQuery("", "foo")).To(matchers.Equal(`"foo"`)) | ||
}) | ||
|
||
o.Spec("with a supplied schema", func(expect expect.Expectation, dialect gorp.PostgresDialect) { | ||
expect(dialect.QuotedTableForQuery("foo", "bar")).To(matchers.Equal(`foo."bar"`)) | ||
}) | ||
}) | ||
|
||
o.Spec("IfSchemaNotExists", func(expect expect.Expectation, dialect gorp.PostgresDialect) { | ||
expect(dialect.IfSchemaNotExists("foo", "bar")).To(matchers.Equal("foo if not exists")) | ||
}) | ||
|
||
o.Spec("IfTableExists", func(expect expect.Expectation, dialect gorp.PostgresDialect) { | ||
expect(dialect.IfTableExists("foo", "bar", "baz")).To(matchers.Equal("foo if exists")) | ||
}) | ||
|
||
o.Spec("IfTableNotExists", func(expect expect.Expectation, dialect gorp.PostgresDialect) { | ||
expect(dialect.IfTableNotExists("foo", "bar", "baz")).To(matchers.Equal("foo if not exists")) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters