bumps uptrace/bun deps to v1.2.8 (#3698)

This commit is contained in:
kim 2025-01-27 15:54:51 +00:00 committed by GitHub
commit 3617e27afa
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
35 changed files with 760 additions and 220 deletions

View file

@ -1,3 +1,26 @@
## [1.2.9](https://github.com/uptrace/bun/compare/v1.2.8...v1.2.9) (2025-01-26)
### Bug Fixes
* apply join condition to select with count ([e77b9e7](https://github.com/uptrace/bun/commit/e77b9e72fa5ae8e173d506a4e154ba64214c4aff)), closes [#597](https://github.com/uptrace/bun/issues/597)
* build ([702e525](https://github.com/uptrace/bun/commit/702e525e30ec93b6d4611359518e1008b67744af))
* individual replica timeout ([9f5e8b1](https://github.com/uptrace/bun/commit/9f5e8b1c46673bd1779bd4309a28db33dcd695bf))
* test ([dfc4059](https://github.com/uptrace/bun/commit/dfc405901907419d043bb6ced3ad20c131c1b972))
### Features
* add feature flag AlterColumnExists ([fc35e12](https://github.com/uptrace/bun/commit/fc35e1222242b3d581f0b7496a9021aadfc50b07)), closes [#704](https://github.com/uptrace/bun/issues/704)
* add Options ([815e11a](https://github.com/uptrace/bun/commit/815e11a023d2babf65d528a20ddffc7628636e7e))
* allow to specify read-only replica for SELECTs ([cbbe1e9](https://github.com/uptrace/bun/commit/cbbe1e94fd0c72d1870395a663c8053d7e8c6ace))
* downgrade to use the field in has-many-relation ([91e0d27](https://github.com/uptrace/bun/commit/91e0d2719a5a20b3208cea0232e2dbcb452d6c23)), closes [#1107](https://github.com/uptrace/bun/issues/1107)
* make WithReadOnlyReplica variadic ([4cbb15a](https://github.com/uptrace/bun/commit/4cbb15a53e566e03284253aa46be372338968954))
* **pgdialect:** allow to convert uint to int ([7d22ddd](https://github.com/uptrace/bun/commit/7d22ddd263b28b9fd6e172e0208c124b7c56f111))
* **pgdriver:** improve otel instrumentation ([c40e4f3](https://github.com/uptrace/bun/commit/c40e4f3c50c710903236dc89b56a843a0351a21a))
## [1.2.8](https://github.com/uptrace/bun/compare/v1.2.7...v1.2.8) (2025-01-06)

170
vendor/github.com/uptrace/bun/db.go generated vendored
View file

@ -9,6 +9,7 @@ import (
"reflect"
"strings"
"sync/atomic"
"time"
"github.com/uptrace/bun/dialect/feature"
"github.com/uptrace/bun/internal"
@ -26,32 +27,56 @@ type DBStats struct {
type DBOption func(db *DB)
func WithOptions(opts ...DBOption) DBOption {
return func(db *DB) {
for _, opt := range opts {
opt(db)
}
}
}
func WithDiscardUnknownColumns() DBOption {
return func(db *DB) {
db.flags = db.flags.Set(discardUnknownColumns)
}
}
type DB struct {
*sql.DB
func WithConnResolver(resolver ConnResolver) DBOption {
return func(db *DB) {
db.resolver = resolver
}
}
dialect schema.Dialect
type DB struct {
// Must be a pointer so we copy the whole state, not individual fields.
*noCopyState
queryHooks []QueryHook
fmter schema.Formatter
flags internal.Flag
stats DBStats
}
// noCopyState contains DB fields that must not be copied on clone(),
// for example, it is forbidden to copy atomic.Pointer.
type noCopyState struct {
*sql.DB
dialect schema.Dialect
resolver ConnResolver
flags internal.Flag
closed atomic.Bool
}
func NewDB(sqldb *sql.DB, dialect schema.Dialect, opts ...DBOption) *DB {
dialect.Init(sqldb)
db := &DB{
DB: sqldb,
dialect: dialect,
fmter: schema.NewFormatter(dialect),
noCopyState: &noCopyState{
DB: sqldb,
dialect: dialect,
},
fmter: schema.NewFormatter(dialect),
}
for _, opt := range opts {
@ -69,6 +94,22 @@ func (db *DB) String() string {
return b.String()
}
func (db *DB) Close() error {
if db.closed.Swap(true) {
return nil
}
firstErr := db.DB.Close()
if db.resolver != nil {
if err := db.resolver.Close(); err != nil && firstErr == nil {
firstErr = err
}
}
return firstErr
}
func (db *DB) DBStats() DBStats {
return DBStats{
Queries: atomic.LoadUint32(&db.stats.Queries),
@ -703,3 +744,116 @@ func (tx Tx) NewDropColumn() *DropColumnQuery {
func (db *DB) makeQueryBytes() []byte {
return internal.MakeQueryBytes()
}
//------------------------------------------------------------------------------
// ConnResolver enables routing queries to multiple databases.
type ConnResolver interface {
ResolveConn(query Query) IConn
Close() error
}
// TODO:
// - make monitoring interval configurable
// - make ping timeout configutable
// - allow adding read/write replicas for multi-master replication
type ReadWriteConnResolver struct {
replicas []*sql.DB // read-only replicas
healthyReplicas atomic.Pointer[[]*sql.DB]
nextReplica atomic.Int64
closed atomic.Bool
}
func NewReadWriteConnResolver(opts ...ReadWriteConnResolverOption) *ReadWriteConnResolver {
r := new(ReadWriteConnResolver)
for _, opt := range opts {
opt(r)
}
if len(r.replicas) > 0 {
r.healthyReplicas.Store(&r.replicas)
go r.monitor()
}
return r
}
type ReadWriteConnResolverOption func(r *ReadWriteConnResolver)
func WithReadOnlyReplica(dbs ...*sql.DB) ReadWriteConnResolverOption {
return func(r *ReadWriteConnResolver) {
r.replicas = append(r.replicas, dbs...)
}
}
func (r *ReadWriteConnResolver) Close() error {
if r.closed.Swap(true) {
return nil
}
var firstErr error
for _, db := range r.replicas {
if err := db.Close(); err != nil && firstErr == nil {
firstErr = err
}
}
return firstErr
}
// healthyReplica returns a random healthy replica.
func (r *ReadWriteConnResolver) ResolveConn(query Query) IConn {
if len(r.replicas) == 0 || !isReadOnlyQuery(query) {
return nil
}
replicas := r.loadHealthyReplicas()
if len(replicas) == 0 {
return nil
}
if len(replicas) == 1 {
return replicas[0]
}
i := r.nextReplica.Add(1)
return replicas[int(i)%len(replicas)]
}
func isReadOnlyQuery(query Query) bool {
sel, ok := query.(*SelectQuery)
if !ok {
return false
}
for _, el := range sel.with {
if !isReadOnlyQuery(el.query) {
return false
}
}
return true
}
func (r *ReadWriteConnResolver) loadHealthyReplicas() []*sql.DB {
if ptr := r.healthyReplicas.Load(); ptr != nil {
return *ptr
}
return nil
}
func (r *ReadWriteConnResolver) monitor() {
const interval = 5 * time.Second
for !r.closed.Load() {
healthy := make([]*sql.DB, 0, len(r.replicas))
for _, replica := range r.replicas {
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
err := replica.PingContext(ctx)
cancel()
if err == nil {
healthy = append(healthy, replica)
}
}
r.healthyReplicas.Store(&healthy)
time.Sleep(interval)
}
}

View file

@ -1,6 +1,11 @@
package feature
import "github.com/uptrace/bun/internal"
import (
"fmt"
"strconv"
"github.com/uptrace/bun/internal"
)
type Feature = internal.Flag
@ -35,4 +40,55 @@ const (
UpdateOrderLimit // UPDATE ... ORDER BY ... LIMIT ...
DeleteOrderLimit // DELETE ... ORDER BY ... LIMIT ...
DeleteReturning
AlterColumnExists // ADD/DROP COLUMN IF NOT EXISTS/IF EXISTS
)
type NotSupportError struct {
Flag Feature
}
func (err *NotSupportError) Error() string {
name, ok := flag2str[err.Flag]
if !ok {
name = strconv.FormatInt(int64(err.Flag), 10)
}
return fmt.Sprintf("bun: feature %s is not supported by current dialect", name)
}
func NewNotSupportError(flag Feature) *NotSupportError {
return &NotSupportError{Flag: flag}
}
var flag2str = map[Feature]string{
CTE: "CTE",
WithValues: "WithValues",
Returning: "Returning",
InsertReturning: "InsertReturning",
Output: "Output",
DefaultPlaceholder: "DefaultPlaceholder",
DoubleColonCast: "DoubleColonCast",
ValuesRow: "ValuesRow",
UpdateMultiTable: "UpdateMultiTable",
InsertTableAlias: "InsertTableAlias",
UpdateTableAlias: "UpdateTableAlias",
DeleteTableAlias: "DeleteTableAlias",
AutoIncrement: "AutoIncrement",
Identity: "Identity",
TableCascade: "TableCascade",
TableIdentity: "TableIdentity",
TableTruncate: "TableTruncate",
InsertOnConflict: "InsertOnConflict",
InsertOnDuplicateKey: "InsertOnDuplicateKey",
InsertIgnore: "InsertIgnore",
TableNotExists: "TableNotExists",
OffsetFetch: "OffsetFetch",
SelectExists: "SelectExists",
UpdateFromTable: "UpdateFromTable",
MSSavepoint: "MSSavepoint",
GeneratedIdentity: "GeneratedIdentity",
CompositeIn: "CompositeIn",
UpdateOrderLimit: "UpdateOrderLimit",
DeleteOrderLimit: "DeleteOrderLimit",
DeleteReturning: "DeleteReturning",
AlterColumnExists: "AlterColumnExists",
}

View file

@ -3,6 +3,7 @@ package pgdialect
import (
"database/sql"
"fmt"
"strconv"
"strings"
"github.com/uptrace/bun"
@ -25,8 +26,9 @@ func init() {
type Dialect struct {
schema.BaseDialect
tables *schema.Tables
features feature.Feature
tables *schema.Tables
features feature.Feature
uintAsInt bool
}
var _ schema.Dialect = (*Dialect)(nil)
@ -53,7 +55,8 @@ func New(opts ...DialectOption) *Dialect {
feature.SelectExists |
feature.GeneratedIdentity |
feature.CompositeIn |
feature.DeleteReturning
feature.DeleteReturning |
feature.AlterColumnExists
for _, opt := range opts {
opt(d)
@ -70,6 +73,12 @@ func WithoutFeature(other feature.Feature) DialectOption {
}
}
func WithAppendUintAsInt(on bool) DialectOption {
return func(d *Dialect) {
d.uintAsInt = on
}
}
func (d *Dialect) Init(*sql.DB) {}
func (d *Dialect) Name() dialect.Name {
@ -127,6 +136,20 @@ func (d *Dialect) IdentQuote() byte {
return '"'
}
func (d *Dialect) AppendUint32(b []byte, n uint32) []byte {
if d.uintAsInt {
return strconv.AppendInt(b, int64(int32(n)), 10)
}
return strconv.AppendUint(b, uint64(n), 10)
}
func (d *Dialect) AppendUint64(b []byte, n uint64) []byte {
if d.uintAsInt {
return strconv.AppendInt(b, int64(n), 10)
}
return strconv.AppendUint(b, n, 10)
}
func (d *Dialect) AppendSequence(b []byte, _ *schema.Table, _ *schema.Field) []byte {
return appendGeneratedAsIdentity(b)
}

View file

@ -2,5 +2,5 @@ package pgdialect
// Version is the current release version.
func Version() string {
return "1.2.8"
return "1.2.9"
}

View file

@ -2,5 +2,5 @@ package sqlitedialect
// Version is the current release version.
func Version() string {
return "1.2.8"
return "1.2.9"
}

View file

@ -94,7 +94,7 @@ func (m *hasManyModel) Scan(src interface{}) error {
for i, f := range m.rel.JoinPKs {
if f.Name == column {
m.structKey[i] = indirectFieldValue(field.Value(m.strct))
m.structKey[i] = indirectAsKey(field.Value(m.strct))
break
}
}
@ -144,19 +144,27 @@ func baseValues(model TableModel, fields []*schema.Field) map[internal.MapKey][]
func modelKey(key []interface{}, strct reflect.Value, fields []*schema.Field) []interface{} {
for _, f := range fields {
key = append(key, indirectFieldValue(f.Value(strct)))
key = append(key, indirectAsKey(f.Value(strct)))
}
return key
}
// indirectFieldValue return the field value dereferencing the pointer if necessary.
// indirectAsKey return the field value dereferencing the pointer if necessary.
// The value is then used as a map key.
func indirectFieldValue(field reflect.Value) interface{} {
func indirectAsKey(field reflect.Value) interface{} {
if field.Kind() != reflect.Ptr {
i := field.Interface()
if valuer, ok := i.(driver.Valuer); ok {
if v, err := valuer.Value(); err == nil {
return v
switch reflect.TypeOf(v).Kind() {
case reflect.Array, reflect.Chan, reflect.Func,
reflect.Map, reflect.Ptr, reflect.Slice, reflect.UnsafePointer:
// NOTE #1107, these types cannot be used as map key,
// let us use original logic.
return i
default:
return v
}
}
}
return i

View file

@ -103,7 +103,7 @@ func (m *m2mModel) scanM2MColumn(column string, src interface{}) error {
if err := field.Scan(dest, src); err != nil {
return err
}
m.structKey = append(m.structKey, indirectFieldValue(dest))
m.structKey = append(m.structKey, indirectAsKey(dest))
break
}
}

View file

@ -1,6 +1,6 @@
{
"name": "gobun",
"version": "1.2.8",
"version": "1.2.9",
"main": "index.js",
"repository": "git@github.com:uptrace/bun.git",
"author": "Vladimir Mihailenco <vladimir.webdev@gmail.com>",

View file

@ -24,7 +24,7 @@ const (
type withQuery struct {
name string
query schema.QueryAppender
query Query
recursive bool
}
@ -114,8 +114,16 @@ func (q *baseQuery) DB() *DB {
return q.db
}
func (q *baseQuery) GetConn() IConn {
return q.conn
func (q *baseQuery) resolveConn(query Query) IConn {
if q.conn != nil {
return q.conn
}
if q.db.resolver != nil {
if conn := q.db.resolver.ResolveConn(query); conn != nil {
return conn
}
}
return q.db.DB
}
func (q *baseQuery) GetModel() Model {
@ -128,10 +136,8 @@ func (q *baseQuery) GetTableName() string {
}
for _, wq := range q.with {
if v, ok := wq.query.(Query); ok {
if model := v.GetModel(); model != nil {
return v.GetTableName()
}
if model := wq.query.GetModel(); model != nil {
return wq.query.GetTableName()
}
}
@ -249,7 +255,7 @@ func (q *baseQuery) isSoftDelete() bool {
//------------------------------------------------------------------------------
func (q *baseQuery) addWith(name string, query schema.QueryAppender, recursive bool) {
func (q *baseQuery) addWith(name string, query Query, recursive bool) {
q.with = append(q.with, withQuery{
name: name,
query: query,
@ -565,28 +571,33 @@ func (q *baseQuery) scan(
hasDest bool,
) (sql.Result, error) {
ctx, event := q.db.beforeQuery(ctx, iquery, query, nil, query, q.model)
res, err := q._scan(ctx, iquery, query, model, hasDest)
q.db.afterQuery(ctx, event, res, err)
return res, err
}
rows, err := q.conn.QueryContext(ctx, query)
func (q *baseQuery) _scan(
ctx context.Context,
iquery Query,
query string,
model Model,
hasDest bool,
) (sql.Result, error) {
rows, err := q.resolveConn(iquery).QueryContext(ctx, query)
if err != nil {
q.db.afterQuery(ctx, event, nil, err)
return nil, err
}
defer rows.Close()
numRow, err := model.ScanRows(ctx, rows)
if err != nil {
q.db.afterQuery(ctx, event, nil, err)
return nil, err
}
if numRow == 0 && hasDest && isSingleRowModel(model) {
err = sql.ErrNoRows
return nil, sql.ErrNoRows
}
res := driver.RowsAffected(numRow)
q.db.afterQuery(ctx, event, res, err)
return res, err
return driver.RowsAffected(numRow), nil
}
func (q *baseQuery) exec(
@ -595,7 +606,7 @@ func (q *baseQuery) exec(
query string,
) (sql.Result, error) {
ctx, event := q.db.beforeQuery(ctx, iquery, query, nil, query, q.model)
res, err := q.conn.ExecContext(ctx, query)
res, err := q.resolveConn(iquery).ExecContext(ctx, query)
q.db.afterQuery(ctx, event, res, err)
return res, err
}

View file

@ -5,6 +5,7 @@ import (
"database/sql"
"fmt"
"github.com/uptrace/bun/dialect/feature"
"github.com/uptrace/bun/internal"
"github.com/uptrace/bun/schema"
)
@ -21,8 +22,7 @@ var _ Query = (*AddColumnQuery)(nil)
func NewAddColumnQuery(db *DB) *AddColumnQuery {
q := &AddColumnQuery{
baseQuery: baseQuery{
db: db,
conn: db.DB,
db: db,
},
}
return q
@ -133,6 +133,10 @@ func (q *AddColumnQuery) AppendQuery(fmter schema.Formatter, b []byte) (_ []byte
//------------------------------------------------------------------------------
func (q *AddColumnQuery) Exec(ctx context.Context, dest ...interface{}) (sql.Result, error) {
if q.ifNotExists && !q.hasFeature(feature.AlterColumnExists) {
return nil, feature.NewNotSupportError(feature.AlterColumnExists)
}
queryBytes, err := q.AppendQuery(q.db.fmter, q.db.makeQueryBytes())
if err != nil {
return nil, err

View file

@ -20,8 +20,7 @@ var _ Query = (*DropColumnQuery)(nil)
func NewDropColumnQuery(db *DB) *DropColumnQuery {
q := &DropColumnQuery{
baseQuery: baseQuery{
db: db,
conn: db.DB,
db: db,
},
}
return q

View file

@ -25,8 +25,7 @@ func NewDeleteQuery(db *DB) *DeleteQuery {
q := &DeleteQuery{
whereBaseQuery: whereBaseQuery{
baseQuery: baseQuery{
db: db,
conn: db.DB,
db: db,
},
},
}
@ -58,12 +57,12 @@ func (q *DeleteQuery) Apply(fns ...func(*DeleteQuery) *DeleteQuery) *DeleteQuery
return q
}
func (q *DeleteQuery) With(name string, query schema.QueryAppender) *DeleteQuery {
func (q *DeleteQuery) With(name string, query Query) *DeleteQuery {
q.addWith(name, query, false)
return q
}
func (q *DeleteQuery) WithRecursive(name string, query schema.QueryAppender) *DeleteQuery {
func (q *DeleteQuery) WithRecursive(name string, query Query) *DeleteQuery {
q.addWith(name, query, true)
return q
}
@ -128,7 +127,7 @@ func (q *DeleteQuery) WhereAllWithDeleted() *DeleteQuery {
func (q *DeleteQuery) Order(orders ...string) *DeleteQuery {
if !q.hasFeature(feature.DeleteOrderLimit) {
q.err = errors.New("bun: order is not supported for current dialect")
q.err = feature.NewNotSupportError(feature.DeleteOrderLimit)
return q
}
q.addOrder(orders...)
@ -137,7 +136,7 @@ func (q *DeleteQuery) Order(orders ...string) *DeleteQuery {
func (q *DeleteQuery) OrderExpr(query string, args ...interface{}) *DeleteQuery {
if !q.hasFeature(feature.DeleteOrderLimit) {
q.err = errors.New("bun: order is not supported for current dialect")
q.err = feature.NewNotSupportError(feature.DeleteOrderLimit)
return q
}
q.addOrderExpr(query, args...)
@ -152,7 +151,7 @@ func (q *DeleteQuery) ForceDelete() *DeleteQuery {
// ------------------------------------------------------------------------------
func (q *DeleteQuery) Limit(n int) *DeleteQuery {
if !q.hasFeature(feature.DeleteOrderLimit) {
q.err = errors.New("bun: limit is not supported for current dialect")
q.err = feature.NewNotSupportError(feature.DeleteOrderLimit)
return q
}
q.setLimit(n)
@ -166,7 +165,7 @@ func (q *DeleteQuery) Limit(n int) *DeleteQuery {
// To suppress the auto-generated RETURNING clause, use `Returning("NULL")`.
func (q *DeleteQuery) Returning(query string, args ...interface{}) *DeleteQuery {
if !q.hasFeature(feature.DeleteReturning) {
q.err = errors.New("bun: returning is not supported for current dialect")
q.err = feature.NewNotSupportError(feature.DeleteOrderLimit)
return q
}

View file

@ -29,8 +29,7 @@ func NewCreateIndexQuery(db *DB) *CreateIndexQuery {
q := &CreateIndexQuery{
whereBaseQuery: whereBaseQuery{
baseQuery: baseQuery{
db: db,
conn: db.DB,
db: db,
},
},
}

View file

@ -24,8 +24,7 @@ var _ Query = (*DropIndexQuery)(nil)
func NewDropIndexQuery(db *DB) *DropIndexQuery {
q := &DropIndexQuery{
baseQuery: baseQuery{
db: db,
conn: db.DB,
db: db,
},
}
return q

View file

@ -31,8 +31,7 @@ func NewInsertQuery(db *DB) *InsertQuery {
q := &InsertQuery{
whereBaseQuery: whereBaseQuery{
baseQuery: baseQuery{
db: db,
conn: db.DB,
db: db,
},
},
}
@ -64,12 +63,12 @@ func (q *InsertQuery) Apply(fns ...func(*InsertQuery) *InsertQuery) *InsertQuery
return q
}
func (q *InsertQuery) With(name string, query schema.QueryAppender) *InsertQuery {
func (q *InsertQuery) With(name string, query Query) *InsertQuery {
q.addWith(name, query, false)
return q
}
func (q *InsertQuery) WithRecursive(name string, query schema.QueryAppender) *InsertQuery {
func (q *InsertQuery) WithRecursive(name string, query Query) *InsertQuery {
q.addWith(name, query, true)
return q
}

View file

@ -26,8 +26,7 @@ var _ Query = (*MergeQuery)(nil)
func NewMergeQuery(db *DB) *MergeQuery {
q := &MergeQuery{
baseQuery: baseQuery{
db: db,
conn: db.DB,
db: db,
},
}
if q.db.dialect.Name() != dialect.MSSQL && q.db.dialect.Name() != dialect.PG {
@ -61,12 +60,12 @@ func (q *MergeQuery) Apply(fns ...func(*MergeQuery) *MergeQuery) *MergeQuery {
return q
}
func (q *MergeQuery) With(name string, query schema.QueryAppender) *MergeQuery {
func (q *MergeQuery) With(name string, query Query) *MergeQuery {
q.addWith(name, query, false)
return q
}
func (q *MergeQuery) WithRecursive(name string, query schema.QueryAppender) *MergeQuery {
func (q *MergeQuery) WithRecursive(name string, query Query) *MergeQuery {
q.addWith(name, query, true)
return q
}

View file

@ -15,23 +15,10 @@ type RawQuery struct {
comment string
}
// Deprecated: Use NewRaw instead. When add it to IDB, it conflicts with the sql.Conn#Raw
func (db *DB) Raw(query string, args ...interface{}) *RawQuery {
return &RawQuery{
baseQuery: baseQuery{
db: db,
conn: db.DB,
},
query: query,
args: args,
}
}
func NewRawQuery(db *DB, query string, args ...interface{}) *RawQuery {
return &RawQuery{
baseQuery: baseQuery{
db: db,
conn: db.DB,
db: db,
},
query: query,
args: args,

View file

@ -41,8 +41,7 @@ func NewSelectQuery(db *DB) *SelectQuery {
return &SelectQuery{
whereBaseQuery: whereBaseQuery{
baseQuery: baseQuery{
db: db,
conn: db.DB,
db: db,
},
},
}
@ -73,12 +72,12 @@ func (q *SelectQuery) Apply(fns ...func(*SelectQuery) *SelectQuery) *SelectQuery
return q
}
func (q *SelectQuery) With(name string, query schema.QueryAppender) *SelectQuery {
func (q *SelectQuery) With(name string, query Query) *SelectQuery {
q.addWith(name, query, false)
return q
}
func (q *SelectQuery) WithRecursive(name string, query schema.QueryAppender) *SelectQuery {
func (q *SelectQuery) WithRecursive(name string, query Query) *SelectQuery {
q.addWith(name, query, true)
return q
}
@ -537,6 +536,13 @@ func (q *SelectQuery) appendQuery(
return nil, err
}
if err := q.forEachInlineRelJoin(func(j *relationJoin) error {
j.applyTo(q)
return nil
}); err != nil {
return nil, err
}
b = append(b, "SELECT "...)
if len(q.distinctOn) > 0 {
@ -730,8 +736,6 @@ func (q *SelectQuery) appendColumns(fmter schema.Formatter, b []byte) (_ []byte,
func (q *SelectQuery) appendInlineRelColumns(
fmter schema.Formatter, b []byte, join *relationJoin,
) (_ []byte, err error) {
join.applyTo(q)
if join.columns != nil {
table := join.JoinModel.Table()
for i, col := range join.columns {
@ -795,7 +799,7 @@ func (q *SelectQuery) Rows(ctx context.Context) (*sql.Rows, error) {
query := internal.String(queryBytes)
ctx, event := q.db.beforeQuery(ctx, q, query, nil, query, q.model)
rows, err := q.conn.QueryContext(ctx, query)
rows, err := q.resolveConn(q).QueryContext(ctx, query)
q.db.afterQuery(ctx, event, nil, err)
return rows, err
}
@ -931,7 +935,7 @@ func (q *SelectQuery) Count(ctx context.Context) (int, error) {
ctx, event := q.db.beforeQuery(ctx, qq, query, nil, query, q.model)
var num int
err = q.conn.QueryRowContext(ctx, query).Scan(&num)
err = q.resolveConn(q).QueryRowContext(ctx, query).Scan(&num)
q.db.afterQuery(ctx, event, nil, err)
@ -949,13 +953,15 @@ func (q *SelectQuery) ScanAndCount(ctx context.Context, dest ...interface{}) (in
return int(n), nil
}
}
if _, ok := q.conn.(*DB); ok {
return q.scanAndCountConc(ctx, dest...)
if q.conn == nil {
return q.scanAndCountConcurrently(ctx, dest...)
}
return q.scanAndCountSeq(ctx, dest...)
}
func (q *SelectQuery) scanAndCountConc(ctx context.Context, dest ...interface{}) (int, error) {
func (q *SelectQuery) scanAndCountConcurrently(
ctx context.Context, dest ...interface{},
) (int, error) {
var count int
var wg sync.WaitGroup
var mu sync.Mutex
@ -1033,7 +1039,7 @@ func (q *SelectQuery) selectExists(ctx context.Context) (bool, error) {
ctx, event := q.db.beforeQuery(ctx, qq, query, nil, query, q.model)
var exists bool
err = q.conn.QueryRowContext(ctx, query).Scan(&exists)
err = q.resolveConn(q).QueryRowContext(ctx, query).Scan(&exists)
q.db.afterQuery(ctx, event, nil, err)

View file

@ -40,8 +40,7 @@ var _ Query = (*CreateTableQuery)(nil)
func NewCreateTableQuery(db *DB) *CreateTableQuery {
q := &CreateTableQuery{
baseQuery: baseQuery{
db: db,
conn: db.DB,
db: db,
},
varchar: db.Dialect().DefaultVarcharLen(),
}

View file

@ -21,8 +21,7 @@ var _ Query = (*DropTableQuery)(nil)
func NewDropTableQuery(db *DB) *DropTableQuery {
q := &DropTableQuery{
baseQuery: baseQuery{
db: db,
conn: db.DB,
db: db,
},
}
return q

View file

@ -22,8 +22,7 @@ var _ Query = (*TruncateTableQuery)(nil)
func NewTruncateTableQuery(db *DB) *TruncateTableQuery {
q := &TruncateTableQuery{
baseQuery: baseQuery{
db: db,
conn: db.DB,
db: db,
},
}
return q

View file

@ -32,8 +32,7 @@ func NewUpdateQuery(db *DB) *UpdateQuery {
q := &UpdateQuery{
whereBaseQuery: whereBaseQuery{
baseQuery: baseQuery{
db: db,
conn: db.DB,
db: db,
},
},
}
@ -65,12 +64,12 @@ func (q *UpdateQuery) Apply(fns ...func(*UpdateQuery) *UpdateQuery) *UpdateQuery
return q
}
func (q *UpdateQuery) With(name string, query schema.QueryAppender) *UpdateQuery {
func (q *UpdateQuery) With(name string, query Query) *UpdateQuery {
q.addWith(name, query, false)
return q
}
func (q *UpdateQuery) WithRecursive(name string, query schema.QueryAppender) *UpdateQuery {
func (q *UpdateQuery) WithRecursive(name string, query Query) *UpdateQuery {
q.addWith(name, query, true)
return q
}
@ -207,7 +206,7 @@ func (q *UpdateQuery) WhereAllWithDeleted() *UpdateQuery {
// ------------------------------------------------------------------------------
func (q *UpdateQuery) Order(orders ...string) *UpdateQuery {
if !q.hasFeature(feature.UpdateOrderLimit) {
q.err = errors.New("bun: order is not supported for current dialect")
q.err = feature.NewNotSupportError(feature.UpdateOrderLimit)
return q
}
q.addOrder(orders...)
@ -216,7 +215,7 @@ func (q *UpdateQuery) Order(orders ...string) *UpdateQuery {
func (q *UpdateQuery) OrderExpr(query string, args ...interface{}) *UpdateQuery {
if !q.hasFeature(feature.UpdateOrderLimit) {
q.err = errors.New("bun: order is not supported for current dialect")
q.err = feature.NewNotSupportError(feature.UpdateOrderLimit)
return q
}
q.addOrderExpr(query, args...)
@ -225,7 +224,7 @@ func (q *UpdateQuery) OrderExpr(query string, args ...interface{}) *UpdateQuery
func (q *UpdateQuery) Limit(n int) *UpdateQuery {
if !q.hasFeature(feature.UpdateOrderLimit) {
q.err = errors.New("bun: limit is not supported for current dialect")
q.err = feature.NewNotSupportError(feature.UpdateOrderLimit)
return q
}
q.setLimit(n)

View file

@ -25,8 +25,7 @@ var (
func NewValuesQuery(db *DB, model interface{}) *ValuesQuery {
q := &ValuesQuery{
baseQuery: baseQuery{
db: db,
conn: db.DB,
db: db,
},
}
q.setModel(model)

View file

@ -2,5 +2,5 @@ package bun
// Version is the current release version.
func Version() string {
return "1.2.8"
return "1.2.9"
}