package pgdialect
import (
"database/sql"
"reflect"
"strconv"
"sync"
"time"
"github.com/uptrace/bun/dialect"
"github.com/uptrace/bun/dialect/feature"
"github.com/uptrace/bun/dialect/sqltype"
"github.com/uptrace/bun/schema"
)
type Dialect struct {
tables *schema .Tables
features feature .Feature
appenderMap sync .Map
scannerMap sync .Map
}
func New () *Dialect {
d := new (Dialect )
d .tables = schema .NewTables (d )
d .features = feature .CTE |
feature .Returning |
feature .DefaultPlaceholder |
feature .DoubleColonCast |
feature .InsertTableAlias |
feature .DeleteTableAlias |
feature .TableCascade |
feature .TableIdentity |
feature .TableTruncate
return d
}
func (d *Dialect ) Init (*sql .DB ) {}
func (d *Dialect ) Name () dialect .Name {
return dialect .PG
}
func (d *Dialect ) Features () feature .Feature {
return d .features
}
func (d *Dialect ) Tables () *schema .Tables {
return d .tables
}
func (d *Dialect ) OnTable (table *schema .Table ) {
for _ , field := range table .FieldMap {
d .onField (field )
}
}
func (d *Dialect ) onField (field *schema .Field ) {
field .DiscoveredSQLType = fieldSQLType (field )
if field .AutoIncrement {
switch field .DiscoveredSQLType {
case sqltype .SmallInt :
field .CreateTableSQLType = pgTypeSmallSerial
case sqltype .Integer :
field .CreateTableSQLType = pgTypeSerial
case sqltype .BigInt :
field .CreateTableSQLType = pgTypeBigSerial
}
}
if field .Tag .HasOption ("array" ) {
field .Append = arrayAppender (field .StructField .Type )
field .Scan = arrayScanner (field .StructField .Type )
}
}
func (d *Dialect ) IdentQuote () byte {
return '"'
}
func (d *Dialect ) Append (fmter schema .Formatter , b []byte , v interface {}) []byte {
switch v := v .(type ) {
case nil :
return dialect .AppendNull (b )
case bool :
return dialect .AppendBool (b , v )
case int :
return strconv .AppendInt (b , int64 (v ), 10 )
case int32 :
return strconv .AppendInt (b , int64 (v ), 10 )
case int64 :
return strconv .AppendInt (b , v , 10 )
case uint :
return strconv .AppendInt (b , int64 (v ), 10 )
case uint32 :
return strconv .AppendInt (b , int64 (v ), 10 )
case uint64 :
return strconv .AppendInt (b , int64 (v ), 10 )
case float32 :
return dialect .AppendFloat32 (b , v )
case float64 :
return dialect .AppendFloat64 (b , v )
case string :
return dialect .AppendString (b , v )
case time .Time :
return dialect .AppendTime (b , v )
case []byte :
return dialect .AppendBytes (b , v )
case schema .QueryAppender :
return schema .AppendQueryAppender (fmter , b , v )
default :
vv := reflect .ValueOf (v )
if vv .Kind () == reflect .Ptr && vv .IsNil () {
return dialect .AppendNull (b )
}
appender := d .Appender (vv .Type ())
return appender (fmter , b , vv )
}
}
func (d *Dialect ) Appender (typ reflect .Type ) schema .AppenderFunc {
if v , ok := d .appenderMap .Load (typ ); ok {
return v .(schema .AppenderFunc )
}
fn := schema .Appender (typ , customAppender )
if v , ok := d .appenderMap .LoadOrStore (typ , fn ); ok {
return v .(schema .AppenderFunc )
}
return fn
}
func (d *Dialect ) FieldAppender (field *schema .Field ) schema .AppenderFunc {
return schema .FieldAppender (d , field )
}
func (d *Dialect ) Scanner (typ reflect .Type ) schema .ScannerFunc {
if v , ok := d .scannerMap .Load (typ ); ok {
return v .(schema .ScannerFunc )
}
fn := scanner (typ )
if v , ok := d .scannerMap .LoadOrStore (typ , fn ); ok {
return v .(schema .ScannerFunc )
}
return fn
}
The pages are generated with Golds v0.3.6 . (GOOS=darwin GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds .