mirror of
https://github.com/superseriousbusiness/gotosocial.git
synced 2024-10-19 00:34:31 +02:00
105 lines
2.5 KiB
Go
105 lines
2.5 KiB
Go
|
package pgdialect
|
||
|
|
||
|
import (
|
||
|
"encoding/json"
|
||
|
"net"
|
||
|
"reflect"
|
||
|
"time"
|
||
|
|
||
|
"github.com/uptrace/bun/dialect/sqltype"
|
||
|
"github.com/uptrace/bun/schema"
|
||
|
)
|
||
|
|
||
|
const (
|
||
|
// Date / Time
|
||
|
pgTypeTimestampTz = "TIMESTAMPTZ" // Timestamp with a time zone
|
||
|
pgTypeDate = "DATE" // Date
|
||
|
pgTypeTime = "TIME" // Time without a time zone
|
||
|
pgTypeTimeTz = "TIME WITH TIME ZONE" // Time with a time zone
|
||
|
pgTypeInterval = "INTERVAL" // Time Interval
|
||
|
|
||
|
// Network Addresses
|
||
|
pgTypeInet = "INET" // IPv4 or IPv6 hosts and networks
|
||
|
pgTypeCidr = "CIDR" // IPv4 or IPv6 networks
|
||
|
pgTypeMacaddr = "MACADDR" // MAC addresses
|
||
|
|
||
|
// Serial Types
|
||
|
pgTypeSmallSerial = "SMALLSERIAL" // 2 byte autoincrementing integer
|
||
|
pgTypeSerial = "SERIAL" // 4 byte autoincrementing integer
|
||
|
pgTypeBigSerial = "BIGSERIAL" // 8 byte autoincrementing integer
|
||
|
|
||
|
// Character Types
|
||
|
pgTypeChar = "CHAR" // fixed length string (blank padded)
|
||
|
pgTypeText = "TEXT" // variable length string without limit
|
||
|
|
||
|
// JSON Types
|
||
|
pgTypeJSON = "JSON" // text representation of json data
|
||
|
pgTypeJSONB = "JSONB" // binary representation of json data
|
||
|
|
||
|
// Binary Data Types
|
||
|
pgTypeBytea = "BYTEA" // binary string
|
||
|
)
|
||
|
|
||
|
var (
|
||
|
timeType = reflect.TypeOf((*time.Time)(nil)).Elem()
|
||
|
ipType = reflect.TypeOf((*net.IP)(nil)).Elem()
|
||
|
ipNetType = reflect.TypeOf((*net.IPNet)(nil)).Elem()
|
||
|
jsonRawMessageType = reflect.TypeOf((*json.RawMessage)(nil)).Elem()
|
||
|
)
|
||
|
|
||
|
func fieldSQLType(field *schema.Field) string {
|
||
|
if field.UserSQLType != "" {
|
||
|
return field.UserSQLType
|
||
|
}
|
||
|
|
||
|
if v, ok := field.Tag.Options["composite"]; ok {
|
||
|
return v
|
||
|
}
|
||
|
|
||
|
if _, ok := field.Tag.Options["hstore"]; ok {
|
||
|
return "hstore"
|
||
|
}
|
||
|
|
||
|
if _, ok := field.Tag.Options["array"]; ok {
|
||
|
switch field.IndirectType.Kind() {
|
||
|
case reflect.Slice, reflect.Array:
|
||
|
sqlType := sqlType(field.IndirectType.Elem())
|
||
|
return sqlType + "[]"
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return sqlType(field.IndirectType)
|
||
|
}
|
||
|
|
||
|
func sqlType(typ reflect.Type) string {
|
||
|
switch typ {
|
||
|
case ipType:
|
||
|
return pgTypeInet
|
||
|
case ipNetType:
|
||
|
return pgTypeCidr
|
||
|
case jsonRawMessageType:
|
||
|
return pgTypeJSONB
|
||
|
}
|
||
|
|
||
|
sqlType := schema.DiscoverSQLType(typ)
|
||
|
switch sqlType {
|
||
|
case sqltype.Timestamp:
|
||
|
sqlType = pgTypeTimestampTz
|
||
|
}
|
||
|
|
||
|
switch typ.Kind() {
|
||
|
case reflect.Map, reflect.Struct:
|
||
|
if sqlType == sqltype.VarChar {
|
||
|
return pgTypeJSONB
|
||
|
}
|
||
|
return sqlType
|
||
|
case reflect.Array, reflect.Slice:
|
||
|
if typ.Elem().Kind() == reflect.Uint8 {
|
||
|
return pgTypeBytea
|
||
|
}
|
||
|
return pgTypeJSONB
|
||
|
}
|
||
|
|
||
|
return sqlType
|
||
|
}
|