diff options
Diffstat (limited to 'vendor/github.com/uptrace/bun/schema')
-rw-r--r-- | vendor/github.com/uptrace/bun/schema/append.go | 125 | ||||
-rw-r--r-- | vendor/github.com/uptrace/bun/schema/append_value.go | 316 | ||||
-rw-r--r-- | vendor/github.com/uptrace/bun/schema/dialect.go | 194 | ||||
-rw-r--r-- | vendor/github.com/uptrace/bun/schema/field.go | 136 | ||||
-rw-r--r-- | vendor/github.com/uptrace/bun/schema/formatter.go | 250 | ||||
-rw-r--r-- | vendor/github.com/uptrace/bun/schema/hook.go | 43 | ||||
-rw-r--r-- | vendor/github.com/uptrace/bun/schema/reflect.go | 51 | ||||
-rw-r--r-- | vendor/github.com/uptrace/bun/schema/relation.go | 45 | ||||
-rw-r--r-- | vendor/github.com/uptrace/bun/schema/scan.go | 519 | ||||
-rw-r--r-- | vendor/github.com/uptrace/bun/schema/sqlfmt.go | 99 | ||||
-rw-r--r-- | vendor/github.com/uptrace/bun/schema/sqltype.go | 141 | ||||
-rw-r--r-- | vendor/github.com/uptrace/bun/schema/table.go | 1094 | ||||
-rw-r--r-- | vendor/github.com/uptrace/bun/schema/tables.go | 114 | ||||
-rw-r--r-- | vendor/github.com/uptrace/bun/schema/zerochecker.go | 161 |
14 files changed, 0 insertions, 3288 deletions
diff --git a/vendor/github.com/uptrace/bun/schema/append.go b/vendor/github.com/uptrace/bun/schema/append.go deleted file mode 100644 index 0cfc1180b..000000000 --- a/vendor/github.com/uptrace/bun/schema/append.go +++ /dev/null @@ -1,125 +0,0 @@ -package schema - -import ( - "fmt" - "reflect" - "strconv" - "time" - - "github.com/uptrace/bun/dialect" -) - -func Append(fmter 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 fmter.Dialect().AppendUint32(b, v) - case uint64: - return fmter.Dialect().AppendUint64(b, v) - case float32: - return dialect.AppendFloat32(b, v) - case float64: - return dialect.AppendFloat64(b, v) - case string: - return fmter.Dialect().AppendString(b, v) - case time.Time: - return fmter.Dialect().AppendTime(b, v) - case []byte: - return fmter.Dialect().AppendBytes(b, v) - case QueryAppender: - return AppendQueryAppender(fmter, b, v) - default: - vv := reflect.ValueOf(v) - if vv.Kind() == reflect.Ptr && vv.IsNil() { - return dialect.AppendNull(b) - } - appender := Appender(fmter.Dialect(), vv.Type()) - return appender(fmter, b, vv) - } -} - -//------------------------------------------------------------------------------ - -func In(slice interface{}) QueryAppender { - v := reflect.ValueOf(slice) - if v.Kind() != reflect.Slice { - return &inValues{ - err: fmt.Errorf("bun: In(non-slice %T)", slice), - } - } - return &inValues{ - slice: v, - } -} - -type inValues struct { - slice reflect.Value - err error -} - -var _ QueryAppender = (*inValues)(nil) - -func (in *inValues) AppendQuery(fmter Formatter, b []byte) (_ []byte, err error) { - if in.err != nil { - return nil, in.err - } - return appendIn(fmter, b, in.slice), nil -} - -func appendIn(fmter Formatter, b []byte, slice reflect.Value) []byte { - sliceLen := slice.Len() - - if sliceLen == 0 { - return dialect.AppendNull(b) - } - - for i := 0; i < sliceLen; i++ { - if i > 0 { - b = append(b, ", "...) - } - - elem := slice.Index(i) - if elem.Kind() == reflect.Interface { - elem = elem.Elem() - } - - if elem.Kind() == reflect.Slice && elem.Type() != bytesType { - b = append(b, '(') - b = appendIn(fmter, b, elem) - b = append(b, ')') - } else { - b = fmter.AppendValue(b, elem) - } - } - return b -} - -//------------------------------------------------------------------------------ - -func NullZero(value interface{}) QueryAppender { - return nullZero{ - value: value, - } -} - -type nullZero struct { - value interface{} -} - -func (nz nullZero) AppendQuery(fmter Formatter, b []byte) (_ []byte, err error) { - if isZero(nz.value) { - return dialect.AppendNull(b), nil - } - return fmter.AppendValue(b, reflect.ValueOf(nz.value)), nil -} diff --git a/vendor/github.com/uptrace/bun/schema/append_value.go b/vendor/github.com/uptrace/bun/schema/append_value.go deleted file mode 100644 index a67b41e38..000000000 --- a/vendor/github.com/uptrace/bun/schema/append_value.go +++ /dev/null @@ -1,316 +0,0 @@ -package schema - -import ( - "database/sql/driver" - "fmt" - "net" - "reflect" - "strconv" - "strings" - "time" - - "github.com/puzpuzpuz/xsync/v3" - "github.com/uptrace/bun/dialect" - "github.com/uptrace/bun/dialect/sqltype" - "github.com/uptrace/bun/extra/bunjson" - "github.com/uptrace/bun/internal" - "github.com/vmihailenco/msgpack/v5" -) - -type ( - AppenderFunc func(fmter Formatter, b []byte, v reflect.Value) []byte - CustomAppender func(typ reflect.Type) AppenderFunc -) - -var appenders = []AppenderFunc{ - reflect.Bool: AppendBoolValue, - reflect.Int: AppendIntValue, - reflect.Int8: AppendIntValue, - reflect.Int16: AppendIntValue, - reflect.Int32: AppendIntValue, - reflect.Int64: AppendIntValue, - reflect.Uint: AppendUintValue, - reflect.Uint8: AppendUintValue, - reflect.Uint16: AppendUintValue, - reflect.Uint32: appendUint32Value, - reflect.Uint64: appendUint64Value, - reflect.Uintptr: nil, - reflect.Float32: AppendFloat32Value, - reflect.Float64: AppendFloat64Value, - reflect.Complex64: nil, - reflect.Complex128: nil, - reflect.Array: AppendJSONValue, - reflect.Chan: nil, - reflect.Func: nil, - reflect.Interface: nil, - reflect.Map: AppendJSONValue, - reflect.Ptr: nil, - reflect.Slice: AppendJSONValue, - reflect.String: AppendStringValue, - reflect.Struct: AppendJSONValue, - reflect.UnsafePointer: nil, -} - -var appenderCache = xsync.NewMapOf[reflect.Type, AppenderFunc]() - -func FieldAppender(dialect Dialect, field *Field) AppenderFunc { - if field.Tag.HasOption("msgpack") { - return appendMsgpack - } - - fieldType := field.StructField.Type - - switch strings.ToUpper(field.UserSQLType) { - case sqltype.JSON, sqltype.JSONB: - if fieldType.Implements(driverValuerType) { - return appendDriverValue - } - - if fieldType.Kind() != reflect.Ptr { - if reflect.PointerTo(fieldType).Implements(driverValuerType) { - return addrAppender(appendDriverValue) - } - } - - return AppendJSONValue - } - - return Appender(dialect, fieldType) -} - -func Appender(dialect Dialect, typ reflect.Type) AppenderFunc { - if v, ok := appenderCache.Load(typ); ok { - return v - } - - fn := appender(dialect, typ) - - if v, ok := appenderCache.LoadOrStore(typ, fn); ok { - return v - } - return fn -} - -func appender(dialect Dialect, typ reflect.Type) AppenderFunc { - switch typ { - case bytesType: - return appendBytesValue - case timeType: - return appendTimeValue - case timePtrType: - return PtrAppender(appendTimeValue) - case ipNetType: - return appendIPNetValue - case ipType, netipPrefixType, netipAddrType: - return appendStringer - case jsonRawMessageType: - return appendJSONRawMessageValue - } - - kind := typ.Kind() - - if typ.Implements(queryAppenderType) { - if kind == reflect.Ptr { - return nilAwareAppender(appendQueryAppenderValue) - } - return appendQueryAppenderValue - } - if typ.Implements(driverValuerType) { - if kind == reflect.Ptr { - return nilAwareAppender(appendDriverValue) - } - return appendDriverValue - } - - if kind != reflect.Ptr { - ptr := reflect.PointerTo(typ) - if ptr.Implements(queryAppenderType) { - return addrAppender(appendQueryAppenderValue) - } - if ptr.Implements(driverValuerType) { - return addrAppender(appendDriverValue) - } - } - - switch kind { - case reflect.Interface: - return ifaceAppenderFunc - case reflect.Ptr: - if typ.Implements(jsonMarshalerType) { - return nilAwareAppender(AppendJSONValue) - } - if fn := Appender(dialect, typ.Elem()); fn != nil { - return PtrAppender(fn) - } - case reflect.Slice: - if typ.Elem().Kind() == reflect.Uint8 { - return appendBytesValue - } - case reflect.Array: - if typ.Elem().Kind() == reflect.Uint8 { - return appendArrayBytesValue - } - } - - return appenders[typ.Kind()] -} - -func ifaceAppenderFunc(fmter Formatter, b []byte, v reflect.Value) []byte { - if v.IsNil() { - return dialect.AppendNull(b) - } - elem := v.Elem() - appender := Appender(fmter.Dialect(), elem.Type()) - return appender(fmter, b, elem) -} - -func nilAwareAppender(fn AppenderFunc) AppenderFunc { - return func(fmter Formatter, b []byte, v reflect.Value) []byte { - if v.IsNil() { - return dialect.AppendNull(b) - } - return fn(fmter, b, v) - } -} - -func PtrAppender(fn AppenderFunc) AppenderFunc { - return func(fmter Formatter, b []byte, v reflect.Value) []byte { - if v.IsNil() { - return dialect.AppendNull(b) - } - return fn(fmter, b, v.Elem()) - } -} - -func AppendBoolValue(fmter Formatter, b []byte, v reflect.Value) []byte { - return fmter.Dialect().AppendBool(b, v.Bool()) -} - -func AppendIntValue(fmter Formatter, b []byte, v reflect.Value) []byte { - return strconv.AppendInt(b, v.Int(), 10) -} - -func AppendUintValue(fmter Formatter, b []byte, v reflect.Value) []byte { - return strconv.AppendUint(b, v.Uint(), 10) -} - -func appendUint32Value(fmter Formatter, b []byte, v reflect.Value) []byte { - return fmter.Dialect().AppendUint32(b, uint32(v.Uint())) -} - -func appendUint64Value(fmter Formatter, b []byte, v reflect.Value) []byte { - return fmter.Dialect().AppendUint64(b, v.Uint()) -} - -func AppendFloat32Value(fmter Formatter, b []byte, v reflect.Value) []byte { - return dialect.AppendFloat32(b, float32(v.Float())) -} - -func AppendFloat64Value(fmter Formatter, b []byte, v reflect.Value) []byte { - return dialect.AppendFloat64(b, float64(v.Float())) -} - -func appendBytesValue(fmter Formatter, b []byte, v reflect.Value) []byte { - return fmter.Dialect().AppendBytes(b, v.Bytes()) -} - -func appendArrayBytesValue(fmter Formatter, b []byte, v reflect.Value) []byte { - if v.CanAddr() { - return fmter.Dialect().AppendBytes(b, v.Slice(0, v.Len()).Bytes()) - } - - tmp := make([]byte, v.Len()) - reflect.Copy(reflect.ValueOf(tmp), v) - b = fmter.Dialect().AppendBytes(b, tmp) - return b -} - -func AppendStringValue(fmter Formatter, b []byte, v reflect.Value) []byte { - return fmter.Dialect().AppendString(b, v.String()) -} - -func AppendJSONValue(fmter Formatter, b []byte, v reflect.Value) []byte { - bb, err := bunjson.Marshal(v.Interface()) - if err != nil { - return dialect.AppendError(b, err) - } - - if len(bb) > 0 && bb[len(bb)-1] == '\n' { - bb = bb[:len(bb)-1] - } - - return fmter.Dialect().AppendJSON(b, bb) -} - -func appendTimeValue(fmter Formatter, b []byte, v reflect.Value) []byte { - tm := v.Interface().(time.Time) - return fmter.Dialect().AppendTime(b, tm) -} - -func appendIPNetValue(fmter Formatter, b []byte, v reflect.Value) []byte { - ipnet := v.Interface().(net.IPNet) - return fmter.Dialect().AppendString(b, ipnet.String()) -} - -func appendStringer(fmter Formatter, b []byte, v reflect.Value) []byte { - return fmter.Dialect().AppendString(b, v.Interface().(fmt.Stringer).String()) -} - -func appendJSONRawMessageValue(fmter Formatter, b []byte, v reflect.Value) []byte { - bytes := v.Bytes() - if bytes == nil { - return dialect.AppendNull(b) - } - return fmter.Dialect().AppendString(b, internal.String(bytes)) -} - -func appendQueryAppenderValue(fmter Formatter, b []byte, v reflect.Value) []byte { - return AppendQueryAppender(fmter, b, v.Interface().(QueryAppender)) -} - -func appendDriverValue(fmter Formatter, b []byte, v reflect.Value) []byte { - value, err := v.Interface().(driver.Valuer).Value() - if err != nil { - return dialect.AppendError(b, err) - } - if _, ok := value.(driver.Valuer); ok { - return dialect.AppendError(b, fmt.Errorf("driver.Valuer returns unsupported type %T", value)) - } - return Append(fmter, b, value) -} - -func addrAppender(fn AppenderFunc) AppenderFunc { - return func(fmter Formatter, b []byte, v reflect.Value) []byte { - if !v.CanAddr() { - err := fmt.Errorf("bun: Append(nonaddressable %T)", v.Interface()) - return dialect.AppendError(b, err) - } - return fn(fmter, b, v.Addr()) - } -} - -func appendMsgpack(fmter Formatter, b []byte, v reflect.Value) []byte { - hexEnc := internal.NewHexEncoder(b) - - enc := msgpack.GetEncoder() - defer msgpack.PutEncoder(enc) - - enc.Reset(hexEnc) - if err := enc.EncodeValue(v); err != nil { - return dialect.AppendError(b, err) - } - - if err := hexEnc.Close(); err != nil { - return dialect.AppendError(b, err) - } - - return hexEnc.Bytes() -} - -func AppendQueryAppender(fmter Formatter, b []byte, app QueryAppender) []byte { - bb, err := app.AppendQuery(fmter, b) - if err != nil { - return dialect.AppendError(b, err) - } - return bb -} diff --git a/vendor/github.com/uptrace/bun/schema/dialect.go b/vendor/github.com/uptrace/bun/schema/dialect.go deleted file mode 100644 index bb40af62b..000000000 --- a/vendor/github.com/uptrace/bun/schema/dialect.go +++ /dev/null @@ -1,194 +0,0 @@ -package schema - -import ( - "database/sql" - "encoding/hex" - "strconv" - "time" - "unicode/utf8" - - "github.com/uptrace/bun/dialect" - "github.com/uptrace/bun/dialect/feature" - "github.com/uptrace/bun/internal/parser" -) - -type Dialect interface { - Init(db *sql.DB) - - Name() dialect.Name - Features() feature.Feature - - Tables() *Tables - OnTable(table *Table) - - IdentQuote() byte - - AppendUint32(b []byte, n uint32) []byte - AppendUint64(b []byte, n uint64) []byte - AppendTime(b []byte, tm time.Time) []byte - AppendString(b []byte, s string) []byte - AppendBytes(b []byte, bs []byte) []byte - AppendJSON(b, jsonb []byte) []byte - AppendBool(b []byte, v bool) []byte - - // AppendSequence adds the appropriate instruction for the driver to create a sequence - // from which (autoincremented) values for the column will be generated. - AppendSequence(b []byte, t *Table, f *Field) []byte - - // DefaultVarcharLen should be returned for dialects in which specifying VARCHAR length - // is mandatory in queries that modify the schema (CREATE TABLE / ADD COLUMN, etc). - // Dialects that do not have such requirement may return 0, which should be interpreted so by the caller. - DefaultVarcharLen() int - - // DefaultSchema should returns the name of the default database schema. - DefaultSchema() string -} - -// ------------------------------------------------------------------------------ - -type BaseDialect struct{} - -func (BaseDialect) AppendUint32(b []byte, n uint32) []byte { - return strconv.AppendUint(b, uint64(n), 10) -} - -func (BaseDialect) AppendUint64(b []byte, n uint64) []byte { - return strconv.AppendUint(b, n, 10) -} - -func (BaseDialect) AppendTime(b []byte, tm time.Time) []byte { - b = append(b, '\'') - b = tm.UTC().AppendFormat(b, "2006-01-02 15:04:05.999999-07:00") - b = append(b, '\'') - return b -} - -func (BaseDialect) AppendString(b []byte, s string) []byte { - b = append(b, '\'') - for _, r := range s { - if r == '\000' { - continue - } - - if r == '\'' { - b = append(b, '\'', '\'') - continue - } - - if r < utf8.RuneSelf { - b = append(b, byte(r)) - continue - } - - l := len(b) - if cap(b)-l < utf8.UTFMax { - b = append(b, make([]byte, utf8.UTFMax)...) - } - n := utf8.EncodeRune(b[l:l+utf8.UTFMax], r) - b = b[:l+n] - } - b = append(b, '\'') - return b -} - -func (BaseDialect) AppendBytes(b, bs []byte) []byte { - if bs == nil { - return dialect.AppendNull(b) - } - - b = append(b, `'\x`...) - - s := len(b) - b = append(b, make([]byte, hex.EncodedLen(len(bs)))...) - hex.Encode(b[s:], bs) - - b = append(b, '\'') - - return b -} - -func (BaseDialect) AppendJSON(b, jsonb []byte) []byte { - b = append(b, '\'') - - p := parser.New(jsonb) - for p.Valid() { - c := p.Read() - switch c { - case '"': - b = append(b, '"') - case '\'': - b = append(b, "''"...) - case '\000': - continue - case '\\': - if p.CutPrefix([]byte("u0000")) { - b = append(b, `\\u0000`...) - } else { - b = append(b, '\\') - if p.Valid() { - b = append(b, p.Read()) - } - } - default: - b = append(b, c) - } - } - - b = append(b, '\'') - - return b -} - -func (BaseDialect) AppendBool(b []byte, v bool) []byte { - return dialect.AppendBool(b, v) -} - -// ------------------------------------------------------------------------------ - -type nopDialect struct { - BaseDialect - - tables *Tables - features feature.Feature -} - -func newNopDialect() *nopDialect { - d := new(nopDialect) - d.tables = NewTables(d) - d.features = feature.Returning - return d -} - -func (d *nopDialect) Init(*sql.DB) {} - -func (d *nopDialect) Name() dialect.Name { - return dialect.Invalid -} - -func (d *nopDialect) Features() feature.Feature { - return d.features -} - -func (d *nopDialect) Tables() *Tables { - return d.tables -} - -func (d *nopDialect) OnField(field *Field) {} - -func (d *nopDialect) OnTable(table *Table) {} - -func (d *nopDialect) IdentQuote() byte { - return '"' -} - -func (d *nopDialect) DefaultVarcharLen() int { - return 0 -} - -func (d *nopDialect) AppendSequence(b []byte, _ *Table, _ *Field) []byte { - return b -} - -func (d *nopDialect) DefaultSchema() string { - return "nop" -} diff --git a/vendor/github.com/uptrace/bun/schema/field.go b/vendor/github.com/uptrace/bun/schema/field.go deleted file mode 100644 index 06d0a5094..000000000 --- a/vendor/github.com/uptrace/bun/schema/field.go +++ /dev/null @@ -1,136 +0,0 @@ -package schema - -import ( - "fmt" - "reflect" - - "github.com/uptrace/bun/dialect" - "github.com/uptrace/bun/internal" - "github.com/uptrace/bun/internal/tagparser" -) - -type Field struct { - StructField reflect.StructField - IsPtr bool - - Tag tagparser.Tag - IndirectType reflect.Type - Index []int - - Name string // SQL name, .e.g. id - SQLName Safe // escaped SQL name, e.g. "id" - GoName string // struct field name, e.g. Id - - DiscoveredSQLType string - UserSQLType string - CreateTableSQLType string - SQLDefault string - - OnDelete string - OnUpdate string - - IsPK bool - NotNull bool - NullZero bool - AutoIncrement bool - Identity bool - - Append AppenderFunc - Scan ScannerFunc - IsZero IsZeroerFunc -} - -func (f *Field) String() string { - return f.Name -} - -func (f *Field) WithIndex(path []int) *Field { - if len(path) == 0 { - return f - } - clone := *f - clone.Index = makeIndex(path, f.Index) - return &clone -} - -func (f *Field) Clone() *Field { - cp := *f - cp.Index = cp.Index[:len(f.Index):len(f.Index)] - return &cp -} - -func (f *Field) Value(strct reflect.Value) reflect.Value { - return internal.FieldByIndexAlloc(strct, f.Index) -} - -func (f *Field) HasNilValue(v reflect.Value) bool { - if len(f.Index) == 1 { - return v.Field(f.Index[0]).IsNil() - } - - for _, index := range f.Index { - if v.Kind() == reflect.Ptr { - if v.IsNil() { - return true - } - v = v.Elem() - } - v = v.Field(index) - } - return v.IsNil() -} - -func (f *Field) HasZeroValue(v reflect.Value) bool { - if len(f.Index) == 1 { - return f.IsZero(v.Field(f.Index[0])) - } - - for _, index := range f.Index { - if v.Kind() == reflect.Ptr { - if v.IsNil() { - return true - } - v = v.Elem() - } - v = v.Field(index) - } - return f.IsZero(v) -} - -func (f *Field) AppendValue(fmter Formatter, b []byte, strct reflect.Value) []byte { - fv, ok := fieldByIndex(strct, f.Index) - if !ok { - return dialect.AppendNull(b) - } - - if (f.IsPtr && fv.IsNil()) || (f.NullZero && f.IsZero(fv)) { - return dialect.AppendNull(b) - } - if f.Append == nil { - panic(fmt.Errorf("bun: AppendValue(unsupported %s)", fv.Type())) - } - return f.Append(fmter, b, fv) -} - -func (f *Field) ScanValue(strct reflect.Value, src interface{}) error { - if src == nil { - if fv, ok := fieldByIndex(strct, f.Index); ok { - return f.ScanWithCheck(fv, src) - } - return nil - } - - fv := internal.FieldByIndexAlloc(strct, f.Index) - return f.ScanWithCheck(fv, src) -} - -func (f *Field) ScanWithCheck(fv reflect.Value, src interface{}) error { - if f.Scan == nil { - return fmt.Errorf("bun: Scan(unsupported %s)", f.IndirectType) - } - return f.Scan(fv, src) -} - -func (f *Field) SkipUpdate() bool { - return f.Tag.HasOption("skipupdate") -} diff --git a/vendor/github.com/uptrace/bun/schema/formatter.go b/vendor/github.com/uptrace/bun/schema/formatter.go deleted file mode 100644 index 1d8d9a9ee..000000000 --- a/vendor/github.com/uptrace/bun/schema/formatter.go +++ /dev/null @@ -1,250 +0,0 @@ -package schema - -import ( - "reflect" - "strconv" - "strings" - - "github.com/uptrace/bun/dialect" - "github.com/uptrace/bun/dialect/feature" - "github.com/uptrace/bun/internal" - "github.com/uptrace/bun/internal/parser" -) - -var nopFormatter = Formatter{ - dialect: newNopDialect(), -} - -type Formatter struct { - dialect Dialect - args *namedArgList -} - -func NewFormatter(dialect Dialect) Formatter { - return Formatter{ - dialect: dialect, - } -} - -func NewNopFormatter() Formatter { - return nopFormatter -} - -func (f Formatter) IsNop() bool { - return f.dialect.Name() == dialect.Invalid -} - -func (f Formatter) Dialect() Dialect { - return f.dialect -} - -func (f Formatter) IdentQuote() byte { - return f.dialect.IdentQuote() -} - -func (f Formatter) AppendName(b []byte, name string) []byte { - return dialect.AppendName(b, name, f.IdentQuote()) -} - -func (f Formatter) AppendIdent(b []byte, ident string) []byte { - return dialect.AppendIdent(b, ident, f.IdentQuote()) -} - -func (f Formatter) AppendValue(b []byte, v reflect.Value) []byte { - if v.Kind() == reflect.Ptr && v.IsNil() { - return dialect.AppendNull(b) - } - appender := Appender(f.dialect, v.Type()) - return appender(f, b, v) -} - -func (f Formatter) HasFeature(feature feature.Feature) bool { - return f.dialect.Features().Has(feature) -} - -func (f Formatter) WithArg(arg NamedArgAppender) Formatter { - return Formatter{ - dialect: f.dialect, - args: f.args.WithArg(arg), - } -} - -func (f Formatter) WithNamedArg(name string, value interface{}) Formatter { - return Formatter{ - dialect: f.dialect, - args: f.args.WithArg(&namedArg{name: name, value: value}), - } -} - -func (f Formatter) FormatQuery(query string, args ...interface{}) string { - if f.IsNop() || (args == nil && f.args == nil) || strings.IndexByte(query, '?') == -1 { - return query - } - return internal.String(f.AppendQuery(nil, query, args...)) -} - -func (f Formatter) AppendQuery(dst []byte, query string, args ...interface{}) []byte { - if f.IsNop() || (args == nil && f.args == nil) || strings.IndexByte(query, '?') == -1 { - return append(dst, query...) - } - return f.append(dst, parser.NewString(query), args) -} - -func (f Formatter) append(dst []byte, p *parser.Parser, args []interface{}) []byte { - var namedArgs NamedArgAppender - if len(args) == 1 { - if v, ok := args[0].(NamedArgAppender); ok { - namedArgs = v - } else if v, ok := newStructArgs(f, args[0]); ok { - namedArgs = v - } - } - - var argIndex int - for p.Valid() { - b, ok := p.ReadSep('?') - if !ok { - dst = append(dst, b...) - continue - } - if len(b) > 0 && b[len(b)-1] == '\\' { - dst = append(dst, b[:len(b)-1]...) - dst = append(dst, '?') - continue - } - dst = append(dst, b...) - - name, numeric := p.ReadIdentifier() - if name != "" { - if numeric { - idx, err := strconv.Atoi(name) - if err != nil { - goto restore_arg - } - - if idx >= len(args) { - goto restore_arg - } - - dst = f.appendArg(dst, args[idx]) - continue - } - - if namedArgs != nil { - dst, ok = namedArgs.AppendNamedArg(f, dst, name) - if ok { - continue - } - } - - dst, ok = f.args.AppendNamedArg(f, dst, name) - if ok { - continue - } - - restore_arg: - dst = append(dst, '?') - dst = append(dst, name...) - continue - } - - if argIndex >= len(args) { - dst = append(dst, '?') - continue - } - - arg := args[argIndex] - argIndex++ - - dst = f.appendArg(dst, arg) - } - - return dst -} - -func (f Formatter) appendArg(b []byte, arg interface{}) []byte { - switch arg := arg.(type) { - case QueryAppender: - bb, err := arg.AppendQuery(f, b) - if err != nil { - return dialect.AppendError(b, err) - } - return bb - default: - return Append(f, b, arg) - } -} - -//------------------------------------------------------------------------------ - -type NamedArgAppender interface { - AppendNamedArg(fmter Formatter, b []byte, name string) ([]byte, bool) -} - -type namedArgList struct { - arg NamedArgAppender - next *namedArgList -} - -func (l *namedArgList) WithArg(arg NamedArgAppender) *namedArgList { - return &namedArgList{ - arg: arg, - next: l, - } -} - -func (l *namedArgList) AppendNamedArg(fmter Formatter, b []byte, name string) ([]byte, bool) { - for l != nil && l.arg != nil { - if b, ok := l.arg.AppendNamedArg(fmter, b, name); ok { - return b, true - } - l = l.next - } - return b, false -} - -//------------------------------------------------------------------------------ - -type namedArg struct { - name string - value interface{} -} - -var _ NamedArgAppender = (*namedArg)(nil) - -func (a *namedArg) AppendNamedArg(fmter Formatter, b []byte, name string) ([]byte, bool) { - if a.name == name { - return fmter.appendArg(b, a.value), true - } - return b, false -} - -//------------------------------------------------------------------------------ - -type structArgs struct { - table *Table - strct reflect.Value -} - -var _ NamedArgAppender = (*structArgs)(nil) - -func newStructArgs(fmter Formatter, strct interface{}) (*structArgs, bool) { - v := reflect.ValueOf(strct) - if !v.IsValid() { - return nil, false - } - - v = reflect.Indirect(v) - if v.Kind() != reflect.Struct { - return nil, false - } - - return &structArgs{ - table: fmter.Dialect().Tables().Get(v.Type()), - strct: v, - }, true -} - -func (m *structArgs) AppendNamedArg(fmter Formatter, b []byte, name string) ([]byte, bool) { - return m.table.AppendNamedArg(fmter, b, name, m.strct) -} diff --git a/vendor/github.com/uptrace/bun/schema/hook.go b/vendor/github.com/uptrace/bun/schema/hook.go deleted file mode 100644 index f8c32f689..000000000 --- a/vendor/github.com/uptrace/bun/schema/hook.go +++ /dev/null @@ -1,43 +0,0 @@ -package schema - -import ( - "context" - "database/sql" - "reflect" -) - -type Model interface { - ScanRows(ctx context.Context, rows *sql.Rows) (int, error) - Value() interface{} -} - -type Query interface { - QueryAppender - Operation() string - GetModel() Model - GetTableName() string -} - -//------------------------------------------------------------------------------ - -type BeforeAppendModelHook interface { - BeforeAppendModel(ctx context.Context, query Query) error -} - -var beforeAppendModelHookType = reflect.TypeFor[BeforeAppendModelHook]() - -//------------------------------------------------------------------------------ - -type BeforeScanRowHook interface { - BeforeScanRow(context.Context) error -} - -var beforeScanRowHookType = reflect.TypeFor[BeforeScanRowHook]() - -//------------------------------------------------------------------------------ - -type AfterScanRowHook interface { - AfterScanRow(context.Context) error -} - -var afterScanRowHookType = reflect.TypeFor[AfterScanRowHook]() diff --git a/vendor/github.com/uptrace/bun/schema/reflect.go b/vendor/github.com/uptrace/bun/schema/reflect.go deleted file mode 100644 index 3435fa1c8..000000000 --- a/vendor/github.com/uptrace/bun/schema/reflect.go +++ /dev/null @@ -1,51 +0,0 @@ -package schema - -import ( - "database/sql/driver" - "encoding/json" - "net" - "net/netip" - "reflect" - "time" -) - -var ( - bytesType = reflect.TypeFor[[]byte]() - timePtrType = reflect.TypeFor[*time.Time]() - timeType = reflect.TypeFor[time.Time]() - ipType = reflect.TypeFor[net.IP]() - ipNetType = reflect.TypeFor[net.IPNet]() - netipPrefixType = reflect.TypeFor[netip.Prefix]() - netipAddrType = reflect.TypeFor[netip.Addr]() - jsonRawMessageType = reflect.TypeFor[json.RawMessage]() - - driverValuerType = reflect.TypeFor[driver.Valuer]() - queryAppenderType = reflect.TypeFor[QueryAppender]() - jsonMarshalerType = reflect.TypeFor[json.Marshaler]() -) - -func indirectType(t reflect.Type) reflect.Type { - if t.Kind() == reflect.Ptr { - t = t.Elem() - } - return t -} - -func fieldByIndex(v reflect.Value, index []int) (_ reflect.Value, ok bool) { - if len(index) == 1 { - return v.Field(index[0]), true - } - - for i, idx := range index { - if i > 0 { - if v.Kind() == reflect.Ptr { - if v.IsNil() { - return v, false - } - v = v.Elem() - } - } - v = v.Field(idx) - } - return v, true -} diff --git a/vendor/github.com/uptrace/bun/schema/relation.go b/vendor/github.com/uptrace/bun/schema/relation.go deleted file mode 100644 index f653cd7a3..000000000 --- a/vendor/github.com/uptrace/bun/schema/relation.go +++ /dev/null @@ -1,45 +0,0 @@ -package schema - -import ( - "fmt" -) - -const ( - InvalidRelation = iota - HasOneRelation - BelongsToRelation - HasManyRelation - ManyToManyRelation -) - -type Relation struct { - // Base and Join can be explained with this query: - // - // SELECT * FROM base_table JOIN join_table - - Type int - Field *Field - JoinTable *Table - BasePKs []*Field - JoinPKs []*Field - OnUpdate string - OnDelete string - Condition []string - - PolymorphicField *Field - PolymorphicValue string - - M2MTable *Table - M2MBasePKs []*Field - M2MJoinPKs []*Field -} - -// References returns true if the table to which the Relation belongs needs to declare a foreign key constraint to create the relation. -// For other relations, the constraint is created in either the referencing table (1:N, 'has-many' relations) or a mapping table (N:N, 'm2m' relations). -func (r *Relation) References() bool { - return r.Type == HasOneRelation || r.Type == BelongsToRelation -} - -func (r *Relation) String() string { - return fmt.Sprintf("relation=%s", r.Field.GoName) -} diff --git a/vendor/github.com/uptrace/bun/schema/scan.go b/vendor/github.com/uptrace/bun/schema/scan.go deleted file mode 100644 index 9db46cd6f..000000000 --- a/vendor/github.com/uptrace/bun/schema/scan.go +++ /dev/null @@ -1,519 +0,0 @@ -package schema - -import ( - "bytes" - "database/sql" - "fmt" - "net" - "reflect" - "strconv" - "strings" - "time" - - "github.com/puzpuzpuz/xsync/v3" - "github.com/vmihailenco/msgpack/v5" - - "github.com/uptrace/bun/dialect/sqltype" - "github.com/uptrace/bun/extra/bunjson" - "github.com/uptrace/bun/internal" -) - -var scannerType = reflect.TypeFor[sql.Scanner]() - -type ScannerFunc func(dest reflect.Value, src interface{}) error - -var scanners []ScannerFunc - -func init() { - scanners = []ScannerFunc{ - reflect.Bool: scanBool, - reflect.Int: scanInt64, - reflect.Int8: scanInt64, - reflect.Int16: scanInt64, - reflect.Int32: scanInt64, - reflect.Int64: scanInt64, - reflect.Uint: scanUint64, - reflect.Uint8: scanUint64, - reflect.Uint16: scanUint64, - reflect.Uint32: scanUint64, - reflect.Uint64: scanUint64, - reflect.Uintptr: scanUint64, - reflect.Float32: scanFloat, - reflect.Float64: scanFloat, - reflect.Complex64: nil, - reflect.Complex128: nil, - reflect.Array: nil, - reflect.Interface: scanInterface, - reflect.Map: scanJSON, - reflect.Ptr: nil, - reflect.Slice: scanJSON, - reflect.String: scanString, - reflect.Struct: scanJSON, - reflect.UnsafePointer: nil, - } -} - -var scannerCache = xsync.NewMapOf[reflect.Type, ScannerFunc]() - -func FieldScanner(dialect Dialect, field *Field) ScannerFunc { - if field.Tag.HasOption("msgpack") { - return scanMsgpack - } - if field.Tag.HasOption("json_use_number") { - return scanJSONUseNumber - } - if field.StructField.Type.Kind() == reflect.Interface { - switch strings.ToUpper(field.UserSQLType) { - case sqltype.JSON, sqltype.JSONB: - return scanJSONIntoInterface - } - } - return Scanner(field.StructField.Type) -} - -func Scanner(typ reflect.Type) ScannerFunc { - if v, ok := scannerCache.Load(typ); ok { - return v - } - - fn := scanner(typ) - - if v, ok := scannerCache.LoadOrStore(typ, fn); ok { - return v - } - return fn -} - -func scanner(typ reflect.Type) ScannerFunc { - kind := typ.Kind() - - if kind == reflect.Ptr { - if fn := Scanner(typ.Elem()); fn != nil { - return PtrScanner(fn) - } - } - - switch typ { - case bytesType: - return scanBytes - case timeType: - return scanTime - case ipType: - return scanIP - case ipNetType: - return scanIPNet - case jsonRawMessageType: - return scanBytes - } - - if typ.Implements(scannerType) { - return scanScanner - } - - if kind != reflect.Ptr { - ptr := reflect.PointerTo(typ) - if ptr.Implements(scannerType) { - return addrScanner(scanScanner) - } - } - - if typ.Kind() == reflect.Slice && typ.Elem().Kind() == reflect.Uint8 { - return scanBytes - } - - return scanners[kind] -} - -func scanBool(dest reflect.Value, src interface{}) error { - switch src := src.(type) { - case nil: - dest.SetBool(false) - return nil - case bool: - dest.SetBool(src) - return nil - case int64: - dest.SetBool(src != 0) - return nil - case []byte: - f, err := strconv.ParseBool(internal.String(src)) - if err != nil { - return err - } - dest.SetBool(f) - return nil - case string: - f, err := strconv.ParseBool(src) - if err != nil { - return err - } - dest.SetBool(f) - return nil - default: - return scanError(dest.Type(), src) - } -} - -func scanInt64(dest reflect.Value, src interface{}) error { - switch src := src.(type) { - case nil: - dest.SetInt(0) - return nil - case int64: - dest.SetInt(src) - return nil - case uint64: - dest.SetInt(int64(src)) - return nil - case []byte: - n, err := strconv.ParseInt(internal.String(src), 10, 64) - if err != nil { - return err - } - dest.SetInt(n) - return nil - case string: - n, err := strconv.ParseInt(src, 10, 64) - if err != nil { - return err - } - dest.SetInt(n) - return nil - default: - return scanError(dest.Type(), src) - } -} - -func scanUint64(dest reflect.Value, src interface{}) error { - switch src := src.(type) { - case nil: - dest.SetUint(0) - return nil - case uint64: - dest.SetUint(src) - return nil - case int64: - dest.SetUint(uint64(src)) - return nil - case []byte: - n, err := strconv.ParseUint(internal.String(src), 10, 64) - if err != nil { - return err - } - dest.SetUint(n) - return nil - case string: - n, err := strconv.ParseUint(src, 10, 64) - if err != nil { - return err - } - dest.SetUint(n) - return nil - default: - return scanError(dest.Type(), src) - } -} - -func scanFloat(dest reflect.Value, src interface{}) error { - switch src := src.(type) { - case nil: - dest.SetFloat(0) - return nil - case float32: - dest.SetFloat(float64(src)) - return nil - case float64: - dest.SetFloat(src) - return nil - case []byte: - f, err := strconv.ParseFloat(internal.String(src), 64) - if err != nil { - return err - } - dest.SetFloat(f) - return nil - case string: - f, err := strconv.ParseFloat(src, 64) - if err != nil { - return err - } - dest.SetFloat(f) - return nil - default: - return scanError(dest.Type(), src) - } -} - -func scanString(dest reflect.Value, src interface{}) error { - switch src := src.(type) { - case nil: - dest.SetString("") - return nil - case string: - dest.SetString(src) - return nil - case []byte: - dest.SetString(string(src)) - return nil - case time.Time: - dest.SetString(src.Format(time.RFC3339Nano)) - return nil - case int64: - dest.SetString(strconv.FormatInt(src, 10)) - return nil - case uint64: - dest.SetString(strconv.FormatUint(src, 10)) - return nil - case float64: - dest.SetString(strconv.FormatFloat(src, 'G', -1, 64)) - return nil - default: - return scanError(dest.Type(), src) - } -} - -func scanBytes(dest reflect.Value, src interface{}) error { - switch src := src.(type) { - case nil: - dest.SetBytes(nil) - return nil - case string: - dest.SetBytes([]byte(src)) - return nil - case []byte: - clone := make([]byte, len(src)) - copy(clone, src) - - dest.SetBytes(clone) - return nil - default: - return scanError(dest.Type(), src) - } -} - -func scanTime(dest reflect.Value, src interface{}) error { - switch src := src.(type) { - case nil: - destTime := dest.Addr().Interface().(*time.Time) - *destTime = time.Time{} - return nil - case time.Time: - destTime := dest.Addr().Interface().(*time.Time) - *destTime = src - return nil - case string: - srcTime, err := internal.ParseTime(src) - if err != nil { - return err - } - destTime := dest.Addr().Interface().(*time.Time) - *destTime = srcTime - return nil - case []byte: - srcTime, err := internal.ParseTime(internal.String(src)) - if err != nil { - return err - } - destTime := dest.Addr().Interface().(*time.Time) - *destTime = srcTime - return nil - default: - return scanError(dest.Type(), src) - } -} - -func scanScanner(dest reflect.Value, src interface{}) error { - return dest.Interface().(sql.Scanner).Scan(src) -} - -func scanMsgpack(dest reflect.Value, src interface{}) error { - if src == nil { - return scanNull(dest) - } - - b, err := toBytes(src) - if err != nil { - return err - } - - dec := msgpack.GetDecoder() - defer msgpack.PutDecoder(dec) - - dec.Reset(bytes.NewReader(b)) - return dec.DecodeValue(dest) -} - -func scanJSON(dest reflect.Value, src interface{}) error { - if src == nil { - return scanNull(dest) - } - - b, err := toBytes(src) - if err != nil { - return err - } - - return bunjson.Unmarshal(b, dest.Addr().Interface()) -} - -func scanJSONUseNumber(dest reflect.Value, src interface{}) error { - if src == nil { - return scanNull(dest) - } - - b, err := toBytes(src) - if err != nil { - return err - } - - dec := bunjson.NewDecoder(bytes.NewReader(b)) - dec.UseNumber() - return dec.Decode(dest.Addr().Interface()) -} - -func scanIP(dest reflect.Value, src interface{}) error { - if src == nil { - return scanNull(dest) - } - - b, err := toBytes(src) - if err != nil { - return err - } - - ip := net.ParseIP(internal.String(b)) - if ip == nil { - return fmt.Errorf("bun: invalid ip: %q", b) - } - - ptr := dest.Addr().Interface().(*net.IP) - *ptr = ip - - return nil -} - -func scanIPNet(dest reflect.Value, src interface{}) error { - if src == nil { - return scanNull(dest) - } - - b, err := toBytes(src) - if err != nil { - return err - } - - _, ipnet, err := net.ParseCIDR(internal.String(b)) - if err != nil { - return err - } - - ptr := dest.Addr().Interface().(*net.IPNet) - *ptr = *ipnet - - return nil -} - -func addrScanner(fn ScannerFunc) ScannerFunc { - return func(dest reflect.Value, src interface{}) error { - if !dest.CanAddr() { - return fmt.Errorf("bun: Scan(nonaddressable %T)", dest.Interface()) - } - return fn(dest.Addr(), src) - } -} - -func toBytes(src interface{}) ([]byte, error) { - switch src := src.(type) { - case string: - return internal.Bytes(src), nil - case []byte: - return src, nil - default: - return nil, fmt.Errorf("bun: got %T, wanted []byte or string", src) - } -} - -func PtrScanner(fn ScannerFunc) ScannerFunc { - return func(dest reflect.Value, src interface{}) error { - if src == nil { - if !dest.CanAddr() { - if dest.IsNil() { - return nil - } - return fn(dest.Elem(), src) - } - - if !dest.IsNil() { - dest.Set(reflect.New(dest.Type().Elem())) - } - return nil - } - - if dest.IsNil() { - dest.Set(reflect.New(dest.Type().Elem())) - } - - if dest.Kind() == reflect.Map { - return fn(dest, src) - } - - return fn(dest.Elem(), src) - } -} - -func scanNull(dest reflect.Value) error { - if nilable(dest.Kind()) && dest.IsNil() { - return nil - } - dest.Set(reflect.New(dest.Type()).Elem()) - return nil -} - -func scanJSONIntoInterface(dest reflect.Value, src interface{}) error { - if dest.IsNil() { - if src == nil { - return nil - } - - b, err := toBytes(src) - if err != nil { - return err - } - - return bunjson.Unmarshal(b, dest.Addr().Interface()) - } - - dest = dest.Elem() - if fn := Scanner(dest.Type()); fn != nil { - return fn(dest, src) - } - return scanError(dest.Type(), src) -} - -func scanInterface(dest reflect.Value, src interface{}) error { - if dest.IsNil() { - if src == nil { - return nil - } - dest.Set(reflect.ValueOf(src)) - return nil - } - - dest = dest.Elem() - if fn := Scanner(dest.Type()); fn != nil { - return fn(dest, src) - } - return scanError(dest.Type(), src) -} - -func nilable(kind reflect.Kind) bool { - switch kind { - case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: - return true - } - return false -} - -func scanError(dest reflect.Type, src interface{}) error { - return fmt.Errorf("bun: can't scan %#v (%T) into %s", src, src, dest.String()) -} diff --git a/vendor/github.com/uptrace/bun/schema/sqlfmt.go b/vendor/github.com/uptrace/bun/schema/sqlfmt.go deleted file mode 100644 index 7b4a9493f..000000000 --- a/vendor/github.com/uptrace/bun/schema/sqlfmt.go +++ /dev/null @@ -1,99 +0,0 @@ -package schema - -import ( - "strings" - - "github.com/uptrace/bun/internal" -) - -type QueryAppender interface { - AppendQuery(fmter Formatter, b []byte) ([]byte, error) -} - -type ColumnsAppender interface { - AppendColumns(fmter Formatter, b []byte) ([]byte, error) -} - -//------------------------------------------------------------------------------ - -// Safe represents a safe SQL query. -type Safe string - -var _ QueryAppender = (*Safe)(nil) - -func (s Safe) AppendQuery(fmter Formatter, b []byte) ([]byte, error) { - return append(b, s...), nil -} - -//------------------------------------------------------------------------------ - -// Name represents a single SQL name, for example, a column name. -type Name string - -var _ QueryAppender = (*Name)(nil) - -func (s Name) AppendQuery(fmter Formatter, b []byte) ([]byte, error) { - return fmter.AppendName(b, string(s)), nil -} - -//------------------------------------------------------------------------------ - -// Ident represents a SQL identifier, for example, -// a fully qualified column name such as `table_name.col_name`. -type Ident string - -var _ QueryAppender = (*Ident)(nil) - -func (s Ident) AppendQuery(fmter Formatter, b []byte) ([]byte, error) { - return fmter.AppendIdent(b, string(s)), nil -} - -//------------------------------------------------------------------------------ - -type QueryWithArgs struct { - Query string - Args []interface{} -} - -var _ QueryAppender = QueryWithArgs{} - -func SafeQuery(query string, args []interface{}) QueryWithArgs { - if args == nil { - args = make([]interface{}, 0) - } else if len(query) > 0 && strings.IndexByte(query, '?') == -1 { - internal.Warn.Printf("query %q has %v args, but no placeholders", query, args) - } - return QueryWithArgs{ - Query: query, - Args: args, - } -} - -func UnsafeIdent(ident string) QueryWithArgs { - return QueryWithArgs{Query: ident} -} - -func (q QueryWithArgs) IsZero() bool { - return q.Query == "" && q.Args == nil -} - -func (q QueryWithArgs) AppendQuery(fmter Formatter, b []byte) ([]byte, error) { - if q.Args == nil { - return fmter.AppendIdent(b, q.Query), nil - } - return fmter.AppendQuery(b, q.Query, q.Args...), nil -} - -//------------------------------------------------------------------------------ - -type QueryWithSep struct { - QueryWithArgs - Sep string -} - -func SafeQueryWithSep(query string, args []interface{}, sep string) QueryWithSep { - return QueryWithSep{ - QueryWithArgs: SafeQuery(query, args), - Sep: sep, - } -} diff --git a/vendor/github.com/uptrace/bun/schema/sqltype.go b/vendor/github.com/uptrace/bun/schema/sqltype.go deleted file mode 100644 index e96174065..000000000 --- a/vendor/github.com/uptrace/bun/schema/sqltype.go +++ /dev/null @@ -1,141 +0,0 @@ -package schema - -import ( - "bytes" - "database/sql" - "encoding/json" - "reflect" - "time" - - "github.com/uptrace/bun/dialect" - "github.com/uptrace/bun/dialect/sqltype" - "github.com/uptrace/bun/internal" -) - -var ( - bunNullTimeType = reflect.TypeFor[NullTime]() - nullTimeType = reflect.TypeFor[sql.NullTime]() - nullBoolType = reflect.TypeFor[sql.NullBool]() - nullFloatType = reflect.TypeFor[sql.NullFloat64]() - nullIntType = reflect.TypeFor[sql.NullInt64]() - nullStringType = reflect.TypeFor[sql.NullString]() -) - -var sqlTypes = []string{ - reflect.Bool: sqltype.Boolean, - reflect.Int: sqltype.BigInt, - reflect.Int8: sqltype.SmallInt, - reflect.Int16: sqltype.SmallInt, - reflect.Int32: sqltype.Integer, - reflect.Int64: sqltype.BigInt, - reflect.Uint: sqltype.BigInt, - reflect.Uint8: sqltype.SmallInt, - reflect.Uint16: sqltype.SmallInt, - reflect.Uint32: sqltype.Integer, - reflect.Uint64: sqltype.BigInt, - reflect.Uintptr: sqltype.BigInt, - reflect.Float32: sqltype.Real, - reflect.Float64: sqltype.DoublePrecision, - reflect.Complex64: "", - reflect.Complex128: "", - reflect.Array: "", - reflect.Interface: "", - reflect.Map: sqltype.VarChar, - reflect.Ptr: "", - reflect.Slice: sqltype.VarChar, - reflect.String: sqltype.VarChar, - reflect.Struct: sqltype.VarChar, -} - -func DiscoverSQLType(typ reflect.Type) string { - switch typ { - case timeType, nullTimeType, bunNullTimeType: - return sqltype.Timestamp - case nullBoolType: - return sqltype.Boolean - case nullFloatType: - return sqltype.DoublePrecision - case nullIntType: - return sqltype.BigInt - case nullStringType: - return sqltype.VarChar - case jsonRawMessageType: - return sqltype.JSON - } - - switch typ.Kind() { - case reflect.Slice: - if typ.Elem().Kind() == reflect.Uint8 { - return sqltype.Blob - } - } - - return sqlTypes[typ.Kind()] -} - -//------------------------------------------------------------------------------ - -var jsonNull = []byte("null") - -// NullTime is a time.Time wrapper that marshals zero time as JSON null and SQL NULL. -type NullTime struct { - time.Time -} - -var ( - _ json.Marshaler = (*NullTime)(nil) - _ json.Unmarshaler = (*NullTime)(nil) - _ sql.Scanner = (*NullTime)(nil) - _ QueryAppender = (*NullTime)(nil) -) - -func (tm NullTime) MarshalJSON() ([]byte, error) { - if tm.IsZero() { - return jsonNull, nil - } - return tm.Time.MarshalJSON() -} - -func (tm *NullTime) UnmarshalJSON(b []byte) error { - if bytes.Equal(b, jsonNull) { - tm.Time = time.Time{} - return nil - } - return tm.Time.UnmarshalJSON(b) -} - -func (tm NullTime) AppendQuery(fmter Formatter, b []byte) ([]byte, error) { - if tm.IsZero() { - return dialect.AppendNull(b), nil - } - return fmter.Dialect().AppendTime(b, tm.Time), nil -} - -func (tm *NullTime) Scan(src interface{}) error { - if src == nil { - tm.Time = time.Time{} - return nil - } - - switch src := src.(type) { - case time.Time: - tm.Time = src - return nil - case string: - newtm, err := internal.ParseTime(src) - if err != nil { - return err - } - tm.Time = newtm - return nil - case []byte: - newtm, err := internal.ParseTime(internal.String(src)) - if err != nil { - return err - } - tm.Time = newtm - return nil - default: - return scanError(bunNullTimeType, src) - } -} diff --git a/vendor/github.com/uptrace/bun/schema/table.go b/vendor/github.com/uptrace/bun/schema/table.go deleted file mode 100644 index 13b989e4d..000000000 --- a/vendor/github.com/uptrace/bun/schema/table.go +++ /dev/null @@ -1,1094 +0,0 @@ -package schema - -import ( - "database/sql" - "fmt" - "reflect" - "sort" - "strings" - "time" - - "github.com/jinzhu/inflection" - - "github.com/uptrace/bun/internal" - "github.com/uptrace/bun/internal/tagparser" -) - -const ( - beforeAppendModelHookFlag internal.Flag = 1 << iota - beforeScanHookFlag - afterScanHookFlag - beforeScanRowHookFlag - afterScanRowHookFlag -) - -var ( - baseModelType = reflect.TypeFor[BaseModel]() - tableNameInflector = inflection.Plural -) - -type BaseModel struct{} - -// SetTableNameInflector overrides the default func that pluralizes -// model name to get table name, e.g. my_article becomes my_articles. -func SetTableNameInflector(fn func(string) string) { - tableNameInflector = fn -} - -// Table represents a SQL table created from Go struct. -type Table struct { - dialect Dialect - - Type reflect.Type - ZeroValue reflect.Value // reflect.Struct - ZeroIface interface{} // struct pointer - - TypeName string - ModelName string - - Schema string - Name string - SQLName Safe - SQLNameForSelects Safe - Alias string - SQLAlias Safe - - allFields []*Field // all fields including scanonly - Fields []*Field // PKs + DataFields - PKs []*Field - DataFields []*Field - relFields []*Field - - FieldMap map[string]*Field - StructMap map[string]*structField - - Relations map[string]*Relation - Unique map[string][]*Field - - SoftDeleteField *Field - UpdateSoftDeleteField func(fv reflect.Value, tm time.Time) error - - flags internal.Flag -} - -type structField struct { - Index []int - Table *Table -} - -func (table *Table) init(dialect Dialect, typ reflect.Type) { - table.dialect = dialect - table.Type = typ - table.ZeroValue = reflect.New(table.Type).Elem() - table.ZeroIface = reflect.New(table.Type).Interface() - table.TypeName = internal.ToExported(table.Type.Name()) - table.ModelName = internal.Underscore(table.Type.Name()) - tableName := tableNameInflector(table.ModelName) - table.setName(tableName) - table.Alias = table.ModelName - table.SQLAlias = table.quoteIdent(table.ModelName) - table.Schema = dialect.DefaultSchema() - - table.Fields = make([]*Field, 0, typ.NumField()) - table.FieldMap = make(map[string]*Field, typ.NumField()) - table.processFields(typ) - - hooks := []struct { - typ reflect.Type - flag internal.Flag - }{ - {beforeAppendModelHookType, beforeAppendModelHookFlag}, - - {beforeScanRowHookType, beforeScanRowHookFlag}, - {afterScanRowHookType, afterScanRowHookFlag}, - } - - typ = reflect.PointerTo(table.Type) - for _, hook := range hooks { - if typ.Implements(hook.typ) { - table.flags = table.flags.Set(hook.flag) - } - } -} - -func (t *Table) processFields(typ reflect.Type) { - type embeddedField struct { - prefix string - index []int - unexported bool - subtable *Table - subfield *Field - } - - names := make(map[string]struct{}) - embedded := make([]embeddedField, 0, 10) - - for i, n := 0, typ.NumField(); i < n; i++ { - sf := typ.Field(i) - unexported := sf.PkgPath != "" - - tagstr := sf.Tag.Get("bun") - if tagstr == "-" { - names[sf.Name] = struct{}{} - continue - } - tag := tagparser.Parse(tagstr) - - if unexported && !sf.Anonymous { // unexported - continue - } - - if sf.Anonymous { - if sf.Name == "BaseModel" && sf.Type == baseModelType { - t.processBaseModelField(sf) - continue - } - - sfType := sf.Type - if sfType.Kind() == reflect.Ptr { - sfType = sfType.Elem() - } - - if sfType.Kind() != reflect.Struct { // ignore unexported non-struct types - continue - } - - subtable := t.dialect.Tables().InProgress(sfType) - - for _, subfield := range subtable.allFields { - embedded = append(embedded, embeddedField{ - index: sf.Index, - unexported: unexported, - subtable: subtable, - subfield: subfield, - }) - } - - if tagstr != "" { - tag := tagparser.Parse(tagstr) - if tag.HasOption("inherit") || tag.HasOption("extend") { - t.Name = subtable.Name - t.TypeName = subtable.TypeName - t.SQLName = subtable.SQLName - t.SQLNameForSelects = subtable.SQLNameForSelects - t.Alias = subtable.Alias - t.SQLAlias = subtable.SQLAlias - t.ModelName = subtable.ModelName - } - } - - continue - } - - if prefix, ok := tag.Option("embed"); ok { - fieldType := indirectType(sf.Type) - if fieldType.Kind() != reflect.Struct { - panic(fmt.Errorf("bun: embed %s.%s: got %s, wanted reflect.Struct", - t.TypeName, sf.Name, fieldType.Kind())) - } - - subtable := t.dialect.Tables().InProgress(fieldType) - for _, subfield := range subtable.allFields { - embedded = append(embedded, embeddedField{ - prefix: prefix, - index: sf.Index, - unexported: unexported, - subtable: subtable, - subfield: subfield, - }) - } - continue - } - - field := t.newField(sf, tag) - t.addField(field) - names[field.Name] = struct{}{} - - if field.IndirectType.Kind() == reflect.Struct { - if t.StructMap == nil { - t.StructMap = make(map[string]*structField) - } - t.StructMap[field.Name] = &structField{ - Index: field.Index, - Table: t.dialect.Tables().InProgress(field.IndirectType), - } - } - } - - // Only unambiguous embedded fields must be serialized. - ambiguousNames := make(map[string]int) - ambiguousTags := make(map[string]int) - - // Embedded types can never override a field that was already present at - // the top-level. - for name := range names { - ambiguousNames[name]++ - ambiguousTags[name]++ - } - - for _, f := range embedded { - ambiguousNames[f.prefix+f.subfield.Name]++ - if !f.subfield.Tag.IsZero() { - ambiguousTags[f.prefix+f.subfield.Name]++ - } - } - - for _, embfield := range embedded { - subfield := embfield.subfield.Clone() - - if ambiguousNames[subfield.Name] > 1 && - !(!subfield.Tag.IsZero() && ambiguousTags[subfield.Name] == 1) { - continue // ambiguous embedded field - } - - subfield.Index = makeIndex(embfield.index, subfield.Index) - if embfield.prefix != "" { - subfield.Name = embfield.prefix + subfield.Name - subfield.SQLName = t.quoteIdent(subfield.Name) - } - t.addField(subfield) - if v, ok := subfield.Tag.Options["unique"]; ok { - t.addUnique(subfield, embfield.prefix, v) - } - } - - if len(embedded) > 0 { - // https://github.com/uptrace/bun/issues/1095 - // < v1.2, all fields follow the order corresponding to the struct - // >= v1.2, < v1.2.8, fields of nested structs have been moved to the end. - // >= v1.2.8, The default behavior remains the same as initially, - sortFieldsByStruct(t.allFields) - sortFieldsByStruct(t.Fields) - sortFieldsByStruct(t.PKs) - sortFieldsByStruct(t.DataFields) - } -} - -func sortFieldsByStruct(fields []*Field) { - sort.Slice(fields, func(i, j int) bool { - left, right := fields[i], fields[j] - for k := 0; k < len(left.Index) && k < len(right.Index); k++ { - if left.Index[k] != right.Index[k] { - return left.Index[k] < right.Index[k] - } - } - // NOTE: should not reach - return true - }) -} - -func (t *Table) addUnique(field *Field, prefix string, tagOptions []string) { - var names []string - if len(tagOptions) == 1 { - // Split the value by comma, this will allow multiple names to be specified. - // We can use this to create multiple named unique constraints where a single column - // might be included in multiple constraints. - names = strings.Split(tagOptions[0], ",") - } else { - names = tagOptions - } - - for _, uname := range names { - if t.Unique == nil { - t.Unique = make(map[string][]*Field) - } - if uname != "" && prefix != "" { - uname = prefix + uname - } - t.Unique[uname] = append(t.Unique[uname], field) - } -} - -func (t *Table) setName(name string) { - t.Name = name - t.SQLName = t.quoteIdent(name) - t.SQLNameForSelects = t.quoteIdent(name) - if t.SQLAlias == "" { - t.Alias = name - t.SQLAlias = t.quoteIdent(name) - } -} - -func (t *Table) String() string { - return "model=" + t.TypeName -} - -func (t *Table) CheckPKs() error { - if len(t.PKs) == 0 { - return fmt.Errorf("bun: %s does not have primary keys", t) - } - return nil -} - -func (t *Table) addField(field *Field) { - t.allFields = append(t.allFields, field) - - if field.Tag.HasOption("rel") || field.Tag.HasOption("m2m") { - t.relFields = append(t.relFields, field) - return - } - - if field.Tag.HasOption("join") { - internal.Warn.Printf( - `%s.%s "join" option must come together with "rel" option`, - t.TypeName, field.GoName, - ) - } - - t.FieldMap[field.Name] = field - if altName, ok := field.Tag.Option("alt"); ok { - t.FieldMap[altName] = field - } - - if field.Tag.HasOption("scanonly") { - return - } - - if _, ok := field.Tag.Options["soft_delete"]; ok { - t.SoftDeleteField = field - t.UpdateSoftDeleteField = softDeleteFieldUpdater(field) - } - - t.Fields = append(t.Fields, field) - if field.IsPK { - t.PKs = append(t.PKs, field) - } else { - t.DataFields = append(t.DataFields, field) - } -} - -func (t *Table) LookupField(name string) *Field { - if field, ok := t.FieldMap[name]; ok { - return field - } - - table := t - var index []int - for { - structName, columnName, ok := strings.Cut(name, "__") - if !ok { - field, ok := table.FieldMap[name] - if !ok { - return nil - } - return field.WithIndex(index) - } - name = columnName - - strct := table.StructMap[structName] - if strct == nil { - return nil - } - table = strct.Table - index = append(index, strct.Index...) - } -} - -func (t *Table) HasField(name string) bool { - _, ok := t.FieldMap[name] - return ok -} - -func (t *Table) Field(name string) (*Field, error) { - field, ok := t.FieldMap[name] - if !ok { - return nil, fmt.Errorf("bun: %s does not have column=%s", t, name) - } - return field, nil -} - -func (t *Table) fieldByGoName(name string) *Field { - for _, f := range t.allFields { - if f.GoName == name { - return f - } - } - return nil -} - -func (t *Table) processBaseModelField(f reflect.StructField) { - tag := tagparser.Parse(f.Tag.Get("bun")) - - if isKnownTableOption(tag.Name) { - internal.Warn.Printf( - "%s.%s tag name %q is also an option name, is it a mistake? Try table:%s.", - t.TypeName, f.Name, tag.Name, tag.Name, - ) - } - - for name := range tag.Options { - if !isKnownTableOption(name) { - internal.Warn.Printf("%s.%s has unknown tag option: %q", t.TypeName, f.Name, name) - } - } - - if tag.Name != "" { - schema, _ := t.schemaFromTagName(tag.Name) - t.Schema = schema - - // Eventually, we should only assign the "table" portion as the table name, - // which will also require a change in how the table name is appended to queries. - // Until that is done, set table name to tag.Name. - t.setName(tag.Name) - } - - if s, ok := tag.Option("table"); ok { - schema, _ := t.schemaFromTagName(s) - t.Schema = schema - t.setName(s) - } - - if s, ok := tag.Option("select"); ok { - t.SQLNameForSelects = t.quoteTableName(s) - } - - if s, ok := tag.Option("alias"); ok { - t.Alias = s - t.SQLAlias = t.quoteIdent(s) - } -} - -// schemaFromTagName splits the bun.BaseModel tag name into schema and table name -// in case it is specified in the "schema"."table" format. -// Assume default schema if one isn't explicitly specified. -func (t *Table) schemaFromTagName(name string) (string, string) { - schema, table := t.dialect.DefaultSchema(), name - if schemaTable := strings.Split(name, "."); len(schemaTable) == 2 { - schema, table = schemaTable[0], schemaTable[1] - } - return schema, table -} - -// nolint -func (t *Table) newField(sf reflect.StructField, tag tagparser.Tag) *Field { - sqlName := internal.Underscore(sf.Name) - if tag.Name != "" && tag.Name != sqlName { - if isKnownFieldOption(tag.Name) { - internal.Warn.Printf( - "%s.%s tag name %q is also an option name, is it a mistake? Try column:%s.", - t.TypeName, sf.Name, tag.Name, tag.Name, - ) - } - sqlName = tag.Name - } - - if s, ok := tag.Option("column"); ok { - sqlName = s - } - - for name := range tag.Options { - if !isKnownFieldOption(name) { - internal.Warn.Printf("%s.%s has unknown tag option: %q", t.TypeName, sf.Name, name) - } - } - - field := &Field{ - StructField: sf, - IsPtr: sf.Type.Kind() == reflect.Ptr, - - Tag: tag, - IndirectType: indirectType(sf.Type), - Index: sf.Index, - - Name: sqlName, - GoName: sf.Name, - SQLName: t.quoteIdent(sqlName), - } - - field.NotNull = tag.HasOption("notnull") - field.NullZero = tag.HasOption("nullzero") - if tag.HasOption("pk") { - field.IsPK = true - field.NotNull = true - } - if tag.HasOption("autoincrement") { - field.AutoIncrement = true - field.NullZero = true - } - if tag.HasOption("identity") { - field.Identity = true - } - - if v, ok := tag.Options["unique"]; ok { - t.addUnique(field, "", v) - } - if s, ok := tag.Option("default"); ok { - field.SQLDefault = s - } - if s, ok := field.Tag.Option("type"); ok { - field.UserSQLType = s - } - field.DiscoveredSQLType = DiscoverSQLType(field.IndirectType) - field.Append = FieldAppender(t.dialect, field) - field.Scan = FieldScanner(t.dialect, field) - field.IsZero = zeroChecker(field.StructField.Type) - - return field -} - -//--------------------------------------------------------------------------------------- - -func (t *Table) initRelations() { - for _, field := range t.relFields { - t.processRelation(field) - } - t.relFields = nil -} - -func (t *Table) processRelation(field *Field) { - if rel, ok := field.Tag.Option("rel"); ok { - t.initRelation(field, rel) - return - } - if field.Tag.HasOption("m2m") { - t.addRelation(t.m2mRelation(field)) - return - } - panic("not reached") -} - -func (t *Table) initRelation(field *Field, rel string) { - switch rel { - case "belongs-to": - t.addRelation(t.belongsToRelation(field)) - case "has-one": - t.addRelation(t.hasOneRelation(field)) - case "has-many": - t.addRelation(t.hasManyRelation(field)) - default: - panic(fmt.Errorf("bun: unknown relation=%s on field=%s", rel, field.GoName)) - } -} - -func (t *Table) addRelation(rel *Relation) { - if t.Relations == nil { - t.Relations = make(map[string]*Relation) - } - _, ok := t.Relations[rel.Field.GoName] - if ok { - panic(fmt.Errorf("%s already has %s", t, rel)) - } - t.Relations[rel.Field.GoName] = rel -} - -func (t *Table) belongsToRelation(field *Field) *Relation { - joinTable := t.dialect.Tables().InProgress(field.IndirectType) - if err := joinTable.CheckPKs(); err != nil { - panic(err) - } - - rel := &Relation{ - Type: BelongsToRelation, - Field: field, - JoinTable: joinTable, - } - - if field.Tag.HasOption("join_on") { - rel.Condition = field.Tag.Options["join_on"] - } - - rel.OnUpdate = "ON UPDATE NO ACTION" - if onUpdate, ok := field.Tag.Options["on_update"]; ok { - if len(onUpdate) > 1 { - panic(fmt.Errorf("bun: %s belongs-to %s: on_update option must be a single field", t.TypeName, field.GoName)) - } - - rule := strings.ToUpper(onUpdate[0]) - if !isKnownFKRule(rule) { - internal.Warn.Printf("bun: %s belongs-to %s: unknown on_update rule %s", t.TypeName, field.GoName, rule) - } - - s := fmt.Sprintf("ON UPDATE %s", rule) - rel.OnUpdate = s - } - - rel.OnDelete = "ON DELETE NO ACTION" - if onDelete, ok := field.Tag.Options["on_delete"]; ok { - if len(onDelete) > 1 { - panic(fmt.Errorf("bun: %s belongs-to %s: on_delete option must be a single field", t.TypeName, field.GoName)) - } - - rule := strings.ToUpper(onDelete[0]) - if !isKnownFKRule(rule) { - internal.Warn.Printf("bun: %s belongs-to %s: unknown on_delete rule %s", t.TypeName, field.GoName, rule) - } - s := fmt.Sprintf("ON DELETE %s", rule) - rel.OnDelete = s - } - - if join, ok := field.Tag.Options["join"]; ok { - baseColumns, joinColumns := parseRelationJoin(join) - for i, baseColumn := range baseColumns { - joinColumn := joinColumns[i] - - if f := t.FieldMap[baseColumn]; f != nil { - rel.BasePKs = append(rel.BasePKs, f) - } else { - panic(fmt.Errorf( - "bun: %s belongs-to %s: %s must have column %s", - t.TypeName, field.GoName, t.TypeName, baseColumn, - )) - } - - if f := joinTable.FieldMap[joinColumn]; f != nil { - rel.JoinPKs = append(rel.JoinPKs, f) - } else { - panic(fmt.Errorf( - "bun: %s belongs-to %s: %s must have column %s", - t.TypeName, field.GoName, joinTable.TypeName, joinColumn, - )) - } - } - return rel - } - - rel.JoinPKs = joinTable.PKs - fkPrefix := internal.Underscore(field.GoName) + "_" - for _, joinPK := range joinTable.PKs { - fkName := fkPrefix + joinPK.Name - if fk := t.FieldMap[fkName]; fk != nil { - rel.BasePKs = append(rel.BasePKs, fk) - continue - } - - if fk := t.FieldMap[joinPK.Name]; fk != nil { - rel.BasePKs = append(rel.BasePKs, fk) - continue - } - - panic(fmt.Errorf( - "bun: %s belongs-to %s: %s must have column %s "+ - "(to override, use join:base_column=join_column tag on %s field)", - t.TypeName, field.GoName, t.TypeName, fkName, field.GoName, - )) - } - return rel -} - -func (t *Table) hasOneRelation(field *Field) *Relation { - if err := t.CheckPKs(); err != nil { - panic(err) - } - - joinTable := t.dialect.Tables().InProgress(field.IndirectType) - rel := &Relation{ - Type: HasOneRelation, - Field: field, - JoinTable: joinTable, - } - - if field.Tag.HasOption("join_on") { - rel.Condition = field.Tag.Options["join_on"] - } - - if join, ok := field.Tag.Options["join"]; ok { - baseColumns, joinColumns := parseRelationJoin(join) - for i, baseColumn := range baseColumns { - if f := t.FieldMap[baseColumn]; f != nil { - rel.BasePKs = append(rel.BasePKs, f) - } else { - panic(fmt.Errorf( - "bun: %s has-one %s: %s must have column %s", - field.GoName, t.TypeName, t.TypeName, baseColumn, - )) - } - - joinColumn := joinColumns[i] - if f := joinTable.FieldMap[joinColumn]; f != nil { - rel.JoinPKs = append(rel.JoinPKs, f) - } else { - panic(fmt.Errorf( - "bun: %s has-one %s: %s must have column %s", - field.GoName, t.TypeName, joinTable.TypeName, joinColumn, - )) - } - } - return rel - } - - rel.BasePKs = t.PKs - fkPrefix := internal.Underscore(t.ModelName) + "_" - for _, pk := range t.PKs { - fkName := fkPrefix + pk.Name - if f := joinTable.FieldMap[fkName]; f != nil { - rel.JoinPKs = append(rel.JoinPKs, f) - continue - } - - if f := joinTable.FieldMap[pk.Name]; f != nil { - rel.JoinPKs = append(rel.JoinPKs, f) - continue - } - - panic(fmt.Errorf( - "bun: %s has-one %s: %s must have column %s "+ - "(to override, use join:base_column=join_column tag on %s field)", - field.GoName, t.TypeName, joinTable.TypeName, fkName, field.GoName, - )) - } - return rel -} - -func (t *Table) hasManyRelation(field *Field) *Relation { - if err := t.CheckPKs(); err != nil { - panic(err) - } - if field.IndirectType.Kind() != reflect.Slice { - panic(fmt.Errorf( - "bun: %s.%s has-many relation requires slice, got %q", - t.TypeName, field.GoName, field.IndirectType.Kind(), - )) - } - - joinTable := t.dialect.Tables().InProgress(indirectType(field.IndirectType.Elem())) - polymorphicValue, isPolymorphic := field.Tag.Option("polymorphic") - rel := &Relation{ - Type: HasManyRelation, - Field: field, - JoinTable: joinTable, - } - - if field.Tag.HasOption("join_on") { - rel.Condition = field.Tag.Options["join_on"] - } - - var polymorphicColumn string - - if join, ok := field.Tag.Options["join"]; ok { - baseColumns, joinColumns := parseRelationJoin(join) - for i, baseColumn := range baseColumns { - joinColumn := joinColumns[i] - - if isPolymorphic && baseColumn == "type" { - polymorphicColumn = joinColumn - continue - } - - if f := t.FieldMap[baseColumn]; f != nil { - rel.BasePKs = append(rel.BasePKs, f) - } else { - panic(fmt.Errorf( - "bun: %s has-many %s: %s must have column %s", - t.TypeName, field.GoName, t.TypeName, baseColumn, - )) - } - - if f := joinTable.FieldMap[joinColumn]; f != nil { - rel.JoinPKs = append(rel.JoinPKs, f) - } else { - panic(fmt.Errorf( - "bun: %s has-many %s: %s must have column %s", - t.TypeName, field.GoName, joinTable.TypeName, joinColumn, - )) - } - } - } else { - rel.BasePKs = t.PKs - fkPrefix := internal.Underscore(t.ModelName) + "_" - if isPolymorphic { - polymorphicColumn = fkPrefix + "type" - } - - for _, pk := range t.PKs { - joinColumn := fkPrefix + pk.Name - if fk := joinTable.FieldMap[joinColumn]; fk != nil { - rel.JoinPKs = append(rel.JoinPKs, fk) - continue - } - - if fk := joinTable.FieldMap[pk.Name]; fk != nil { - rel.JoinPKs = append(rel.JoinPKs, fk) - continue - } - - panic(fmt.Errorf( - "bun: %s has-many %s: %s must have column %s "+ - "(to override, use join:base_column=join_column tag on the field %s)", - t.TypeName, field.GoName, joinTable.TypeName, joinColumn, field.GoName, - )) - } - } - - if isPolymorphic { - rel.PolymorphicField = joinTable.FieldMap[polymorphicColumn] - if rel.PolymorphicField == nil { - panic(fmt.Errorf( - "bun: %s has-many %s: %s must have polymorphic column %s", - t.TypeName, field.GoName, joinTable.TypeName, polymorphicColumn, - )) - } - - if polymorphicValue == "" { - polymorphicValue = t.ModelName - } - rel.PolymorphicValue = polymorphicValue - } - - return rel -} - -func (t *Table) m2mRelation(field *Field) *Relation { - if field.IndirectType.Kind() != reflect.Slice { - panic(fmt.Errorf( - "bun: %s.%s m2m relation requires slice, got %q", - t.TypeName, field.GoName, field.IndirectType.Kind(), - )) - } - joinTable := t.dialect.Tables().InProgress(indirectType(field.IndirectType.Elem())) - - if err := t.CheckPKs(); err != nil { - panic(err) - } - if err := joinTable.CheckPKs(); err != nil { - panic(err) - } - - m2mTableName, ok := field.Tag.Option("m2m") - if !ok { - panic(fmt.Errorf("bun: %s must have m2m tag option", field.GoName)) - } - - m2mTable := t.dialect.Tables().ByName(m2mTableName) - if m2mTable == nil { - panic(fmt.Errorf( - "bun: can't find m2m %s table (use db.RegisterModel)", - m2mTableName, - )) - } - - rel := &Relation{ - Type: ManyToManyRelation, - Field: field, - JoinTable: joinTable, - M2MTable: m2mTable, - } - - if field.Tag.HasOption("join_on") { - rel.Condition = field.Tag.Options["join_on"] - } - - var leftColumn, rightColumn string - - if join, ok := field.Tag.Options["join"]; ok { - left, right := parseRelationJoin(join) - leftColumn = left[0] - rightColumn = right[0] - } else { - leftColumn = t.TypeName - rightColumn = joinTable.TypeName - } - - leftField := m2mTable.fieldByGoName(leftColumn) - if leftField == nil { - panic(fmt.Errorf( - "bun: %s many-to-many %s: %s must have field %s "+ - "(to override, use tag join:LeftField=RightField on field %s.%s", - t.TypeName, field.GoName, m2mTable.TypeName, leftColumn, t.TypeName, field.GoName, - )) - } - - rightField := m2mTable.fieldByGoName(rightColumn) - if rightField == nil { - panic(fmt.Errorf( - "bun: %s many-to-many %s: %s must have field %s "+ - "(to override, use tag join:LeftField=RightField on field %s.%s", - t.TypeName, field.GoName, m2mTable.TypeName, rightColumn, t.TypeName, field.GoName, - )) - } - - leftRel := m2mTable.belongsToRelation(leftField) - rel.BasePKs = leftRel.JoinPKs - rel.M2MBasePKs = leftRel.BasePKs - - rightRel := m2mTable.belongsToRelation(rightField) - rel.JoinPKs = rightRel.JoinPKs - rel.M2MJoinPKs = rightRel.BasePKs - - return rel -} - -//------------------------------------------------------------------------------ - -func (t *Table) Dialect() Dialect { return t.dialect } - -func (t *Table) HasBeforeAppendModelHook() bool { return t.flags.Has(beforeAppendModelHookFlag) } - -// DEPRECATED. Use HasBeforeScanRowHook. -func (t *Table) HasBeforeScanHook() bool { return t.flags.Has(beforeScanHookFlag) } - -// DEPRECATED. Use HasAfterScanRowHook. -func (t *Table) HasAfterScanHook() bool { return t.flags.Has(afterScanHookFlag) } - -func (t *Table) HasBeforeScanRowHook() bool { return t.flags.Has(beforeScanRowHookFlag) } -func (t *Table) HasAfterScanRowHook() bool { return t.flags.Has(afterScanRowHookFlag) } - -//------------------------------------------------------------------------------ - -func (t *Table) AppendNamedArg( - fmter Formatter, b []byte, name string, strct reflect.Value, -) ([]byte, bool) { - if field, ok := t.FieldMap[name]; ok { - return field.AppendValue(fmter, b, strct), true - } - return b, false -} - -func (t *Table) quoteTableName(s string) Safe { - // Don't quote if table name contains placeholder (?) or parentheses. - if strings.IndexByte(s, '?') >= 0 || - strings.IndexByte(s, '(') >= 0 || - strings.IndexByte(s, ')') >= 0 { - return Safe(s) - } - return t.quoteIdent(s) -} - -func (t *Table) quoteIdent(s string) Safe { - return Safe(NewFormatter(t.dialect).AppendIdent(nil, s)) -} - -func isKnownTableOption(name string) bool { - switch name { - case "table", "alias", "select": - return true - } - return false -} - -func isKnownFieldOption(name string) bool { - switch name { - case "column", - "alt", - "type", - "array", - "hstore", - "composite", - "multirange", - "json_use_number", - "msgpack", - "notnull", - "nullzero", - "default", - "unique", - "soft_delete", - "scanonly", - "skipupdate", - - "pk", - "autoincrement", - "rel", - "join", - "join_on", - "on_update", - "on_delete", - "m2m", - "polymorphic", - "identity": - return true - } - return false -} - -func isKnownFKRule(name string) bool { - switch name { - case "CASCADE", - "RESTRICT", - "SET NULL", - "SET DEFAULT": - return true - } - return false -} - -func parseRelationJoin(join []string) ([]string, []string) { - var ss []string - if len(join) == 1 { - ss = strings.Split(join[0], ",") - } else { - ss = join - } - - baseColumns := make([]string, len(ss)) - joinColumns := make([]string, len(ss)) - for i, s := range ss { - ss := strings.Split(strings.TrimSpace(s), "=") - if len(ss) != 2 { - panic(fmt.Errorf("can't parse relation join: %q", join)) - } - baseColumns[i] = ss[0] - joinColumns[i] = ss[1] - } - return baseColumns, joinColumns -} - -//------------------------------------------------------------------------------ - -func softDeleteFieldUpdater(field *Field) func(fv reflect.Value, tm time.Time) error { - typ := field.StructField.Type - - switch typ { - case timeType: - return func(fv reflect.Value, tm time.Time) error { - ptr := fv.Addr().Interface().(*time.Time) - *ptr = tm - return nil - } - case nullTimeType: - return func(fv reflect.Value, tm time.Time) error { - ptr := fv.Addr().Interface().(*sql.NullTime) - *ptr = sql.NullTime{Time: tm} - return nil - } - case nullIntType: - return func(fv reflect.Value, tm time.Time) error { - ptr := fv.Addr().Interface().(*sql.NullInt64) - *ptr = sql.NullInt64{Int64: tm.UnixNano()} - return nil - } - } - - switch field.IndirectType.Kind() { - case reflect.Int64: - return func(fv reflect.Value, tm time.Time) error { - ptr := fv.Addr().Interface().(*int64) - *ptr = tm.UnixNano() - return nil - } - case reflect.Ptr: - typ = typ.Elem() - default: - return softDeleteFieldUpdaterFallback(field) - } - - switch typ { //nolint:gocritic - case timeType: - return func(fv reflect.Value, tm time.Time) error { - fv.Set(reflect.ValueOf(&tm)) - return nil - } - } - - switch typ.Kind() { //nolint:gocritic - case reflect.Int64: - return func(fv reflect.Value, tm time.Time) error { - utime := tm.UnixNano() - fv.Set(reflect.ValueOf(&utime)) - return nil - } - } - - return softDeleteFieldUpdaterFallback(field) -} - -func softDeleteFieldUpdaterFallback(field *Field) func(fv reflect.Value, tm time.Time) error { - return func(fv reflect.Value, tm time.Time) error { - return field.ScanWithCheck(fv, tm) - } -} - -func makeIndex(a, b []int) []int { - dest := make([]int, 0, len(a)+len(b)) - dest = append(dest, a...) - dest = append(dest, b...) - return dest -} diff --git a/vendor/github.com/uptrace/bun/schema/tables.go b/vendor/github.com/uptrace/bun/schema/tables.go deleted file mode 100644 index e215e499d..000000000 --- a/vendor/github.com/uptrace/bun/schema/tables.go +++ /dev/null @@ -1,114 +0,0 @@ -package schema - -import ( - "fmt" - "reflect" - "sync" - - "github.com/puzpuzpuz/xsync/v3" -) - -type Tables struct { - dialect Dialect - - mu sync.Mutex - tables *xsync.MapOf[reflect.Type, *Table] - - inProgress map[reflect.Type]*Table -} - -func NewTables(dialect Dialect) *Tables { - return &Tables{ - dialect: dialect, - tables: xsync.NewMapOf[reflect.Type, *Table](), - inProgress: make(map[reflect.Type]*Table), - } -} - -func (t *Tables) Register(models ...interface{}) { - for _, model := range models { - _ = t.Get(reflect.TypeOf(model).Elem()) - } -} - -func (t *Tables) Get(typ reflect.Type) *Table { - typ = indirectType(typ) - if typ.Kind() != reflect.Struct { - panic(fmt.Errorf("got %s, wanted %s", typ.Kind(), reflect.Struct)) - } - - if v, ok := t.tables.Load(typ); ok { - return v - } - - t.mu.Lock() - defer t.mu.Unlock() - - if v, ok := t.tables.Load(typ); ok { - return v - } - - table := t.InProgress(typ) - table.initRelations() - - t.dialect.OnTable(table) - for _, field := range table.FieldMap { - if field.UserSQLType == "" { - field.UserSQLType = field.DiscoveredSQLType - } - if field.CreateTableSQLType == "" { - field.CreateTableSQLType = field.UserSQLType - } - } - - t.tables.Store(typ, table) - return table -} - -func (t *Tables) InProgress(typ reflect.Type) *Table { - if table, ok := t.inProgress[typ]; ok { - return table - } - - table := new(Table) - t.inProgress[typ] = table - table.init(t.dialect, typ) - - return table -} - -// ByModel gets the table by its Go name. -func (t *Tables) ByModel(name string) *Table { - var found *Table - t.tables.Range(func(typ reflect.Type, table *Table) bool { - if table.TypeName == name { - found = table - return false - } - return true - }) - return found -} - -// ByName gets the table by its SQL name. -func (t *Tables) ByName(name string) *Table { - var found *Table - t.tables.Range(func(typ reflect.Type, table *Table) bool { - if table.Name == name { - found = table - return false - } - return true - }) - return found -} - -// All returns all registered tables. -func (t *Tables) All() []*Table { - var found []*Table - t.tables.Range(func(typ reflect.Type, table *Table) bool { - found = append(found, table) - return true - }) - return found -} diff --git a/vendor/github.com/uptrace/bun/schema/zerochecker.go b/vendor/github.com/uptrace/bun/schema/zerochecker.go deleted file mode 100644 index 7c8418eaf..000000000 --- a/vendor/github.com/uptrace/bun/schema/zerochecker.go +++ /dev/null @@ -1,161 +0,0 @@ -package schema - -import ( - "database/sql/driver" - "reflect" -) - -var isZeroerType = reflect.TypeFor[isZeroer]() - -type isZeroer interface { - IsZero() bool -} - -func isZero(v interface{}) bool { - switch v := v.(type) { - case isZeroer: - return v.IsZero() - case string: - return v == "" - case []byte: - return v == nil - case int: - return v == 0 - case int64: - return v == 0 - case uint: - return v == 0 - case uint64: - return v == 0 - case float32: - return v == 0 - case float64: - return v == 0 - case int8: - return v == 0 - case int16: - return v == 0 - case int32: - return v == 0 - case uint8: - return v == 0 - case uint16: - return v == 0 - case uint32: - return v == 0 - default: - rv := reflect.ValueOf(v) - fn := zeroChecker(rv.Type()) - return fn(rv) - } -} - -type IsZeroerFunc func(reflect.Value) bool - -func zeroChecker(typ reflect.Type) IsZeroerFunc { - if typ.Implements(isZeroerType) { - return isZeroInterface - } - - kind := typ.Kind() - - if kind != reflect.Ptr { - ptr := reflect.PointerTo(typ) - if ptr.Implements(isZeroerType) { - return addrChecker(isZeroInterface) - } - } - - switch kind { - case reflect.Array: - if typ.Elem().Kind() == reflect.Uint8 { - return isZeroBytes - } - return isZeroLen - case reflect.String: - return isZeroLen - case reflect.Bool: - return isZeroBool - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - return isZeroInt - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - return isZeroUint - case reflect.Float32, reflect.Float64: - return isZeroFloat - case reflect.Interface, reflect.Ptr, reflect.Slice, reflect.Map: - return isNil - } - - if typ.Implements(driverValuerType) { - return isZeroDriverValue - } - - return notZero -} - -func addrChecker(fn IsZeroerFunc) IsZeroerFunc { - return func(v reflect.Value) bool { - if !v.CanAddr() { - return false - } - return fn(v.Addr()) - } -} - -func isZeroInterface(v reflect.Value) bool { - if v.Kind() == reflect.Ptr && v.IsNil() { - return true - } - return v.Interface().(isZeroer).IsZero() -} - -func isZeroDriverValue(v reflect.Value) bool { - if v.Kind() == reflect.Ptr { - return v.IsNil() - } - - valuer := v.Interface().(driver.Valuer) - value, err := valuer.Value() - if err != nil { - return false - } - return value == nil -} - -func isZeroLen(v reflect.Value) bool { - return v.Len() == 0 -} - -func isNil(v reflect.Value) bool { - return v.IsNil() -} - -func isZeroBool(v reflect.Value) bool { - return !v.Bool() -} - -func isZeroInt(v reflect.Value) bool { - return v.Int() == 0 -} - -func isZeroUint(v reflect.Value) bool { - return v.Uint() == 0 -} - -func isZeroFloat(v reflect.Value) bool { - return v.Float() == 0 -} - -func isZeroBytes(v reflect.Value) bool { - b := v.Slice(0, v.Len()).Bytes() - for _, c := range b { - if c != 0 { - return false - } - } - return true -} - -func notZero(v reflect.Value) bool { - return false -} |