github.com/aacfactory/fns-contrib/databases/sql@v1.2.84/dac/query.go (about)

     1  package dac
     2  
     3  import (
     4  	"github.com/aacfactory/errors"
     5  	"github.com/aacfactory/fns-contrib/databases/sql"
     6  	"github.com/aacfactory/fns-contrib/databases/sql/dac/conditions"
     7  	"github.com/aacfactory/fns-contrib/databases/sql/dac/groups"
     8  	"github.com/aacfactory/fns-contrib/databases/sql/dac/orders"
     9  	"github.com/aacfactory/fns-contrib/databases/sql/dac/specifications"
    10  	"github.com/aacfactory/fns/context"
    11  )
    12  
    13  type QueryOptions struct {
    14  	cond    conditions.Condition
    15  	orders  orders.Orders
    16  	groupBy groups.GroupBy
    17  }
    18  
    19  type QueryOption func(options *QueryOptions)
    20  
    21  func Conditions(cond conditions.Condition) QueryOption {
    22  	return func(options *QueryOptions) {
    23  		options.cond = cond
    24  	}
    25  }
    26  
    27  func Orders(orders orders.Orders) QueryOption {
    28  	return func(options *QueryOptions) {
    29  		options.orders = orders
    30  	}
    31  }
    32  
    33  func GroupBy(by groups.GroupBy) QueryOption {
    34  	return func(options *QueryOptions) {
    35  		options.groupBy = by
    36  	}
    37  }
    38  
    39  func Asc(name string) orders.Orders {
    40  	return orders.Asc(name)
    41  }
    42  
    43  func Desc(name string) orders.Orders {
    44  	return orders.Desc(name)
    45  }
    46  
    47  func Query[T Table](ctx context.Context, offset int, length int, options ...QueryOption) (entries []T, err error) {
    48  	opt := QueryOptions{}
    49  	for _, option := range options {
    50  		option(&opt)
    51  	}
    52  
    53  	_, query, arguments, fields, buildErr := specifications.BuildQuery[T](
    54  		ctx,
    55  		specifications.Condition{Condition: opt.cond},
    56  		specifications.Orders(opt.orders),
    57  		offset, length,
    58  	)
    59  	if buildErr != nil {
    60  		err = errors.Warning("sql: query failed").WithCause(buildErr)
    61  		return
    62  	}
    63  
    64  	rows, queryErr := sql.Query(ctx, query, arguments...)
    65  	if queryErr != nil {
    66  		err = errors.Warning("sql: query failed").WithCause(queryErr)
    67  		return
    68  	}
    69  
    70  	entries, err = specifications.ScanRows[T](ctx, rows, fields)
    71  	_ = rows.Close()
    72  	if err != nil {
    73  		err = errors.Warning("sql: query failed").WithCause(err)
    74  		return
    75  	}
    76  	return
    77  }
    78  
    79  func One[T Table](ctx context.Context, options ...QueryOption) (entry T, has bool, err error) {
    80  	entries, queryErr := Query[T](ctx, 0, 1, options...)
    81  	if queryErr != nil {
    82  		err = queryErr
    83  		return
    84  	}
    85  	has = len(entries) == 1
    86  	if has {
    87  		entry = entries[0]
    88  	}
    89  	return
    90  }
    91  
    92  func ALL[T Table](ctx context.Context, options ...QueryOption) (entries []T, err error) {
    93  	entries, err = Query[T](ctx, 0, 0, options...)
    94  	return
    95  }