func (repo *PostgresRepository) DeleteInTx(ctx context.Context, tx nero.Tx, d *Deleter) (int64, error) {
	txx, ok := tx.(*sql.Tx)
	if !ok {
		return 0, errors.New("expecting tx to be *sql.Tx")
	}
	return repo.delete(ctx, txx, d)
}
DeleteInTx deletes a Player or many Players in a transaction
package playerrepo
import (
	"context"
	"database/sql"
	"fmt"
	"log"
	"os"
	"reflect"
	"strings"
	"github.com/Masterminds/squirrel"
	"github.com/pkg/errors"
	"github.com/sf9v/nero"
	"github.com/sf9v/nero/aggregate"
	"github.com/sf9v/nero/comparison"
	"github.com/sf9v/nero/sort"
	"github.com/sf9v/nero/test/integration/player"
)
type PostgresRepository struct {
	db     *sql.DB
	logger nero.Logger
	debug  bool
}
var _ Repository = (*PostgresRepository)(nil)
func NewPostgresRepository(db *sql.DB) *PostgresRepository {
	return &PostgresRepository{db: db}
}
func (repo *PostgresRepository) Debug() *PostgresRepository {
	l := log.New(os.Stdout, "[nero] ", log.LstdFlags|log.Lmicroseconds|log.Lmsgprefix)
	return &PostgresRepository{
		db:     repo.db,
		debug:  true,
		logger: l,
	}
}
func (repo *PostgresRepository) WithLogger(logger nero.Logger) *PostgresRepository {
	repo.logger = logger
	return repo
}
func (repo *PostgresRepository) BeginTx(ctx context.Context) (nero.Tx, error) {
	return repo.db.BeginTx(ctx, nil)
}
func (repo *PostgresRepository) Create(ctx context.Context, c *Creator) (string, error) {
	return repo.create(ctx, repo.db, c)
}
func (repo *PostgresRepository) CreateInTx(ctx context.Context, tx nero.Tx, c *Creator) (string, error) {
	txx, ok := tx.(*sql.Tx)
	if !ok {
		return "", errors.New("expecting tx to be *sql.Tx")
	}
	return repo.create(ctx, txx, c)
}
func (repo *PostgresRepository) create(ctx context.Context, runner nero.SQLRunner, c *Creator) (string, error) {
	if err := c.Validate(); err != nil {
		return "", err
	}
	columns := []string{
		"\"email\"",
		"\"name\"",
		"\"age\"",
		"\"race\"",
	}
	values := []interface{}{
		c.email,
		c.name,
		c.age,
		c.race,
	}
	if !isZero(c.updatedAt) {
		columns = append(columns, "updated_at")
		values = append(values, c.updatedAt)
	}
	qb := squirrel.Insert("\"players\"").
		Columns(columns...).
		Values(values...).
		Suffix("RETURNING \"id\"").
		PlaceholderFormat(squirrel.Dollar).
		RunWith(runner)
	if repo.debug && repo.logger != nil {
		sql, args, err := qb.ToSql()
		repo.logger.Printf("method: Create, stmt: %q, args: %v, error: %v", sql, args, err)
	}
	var id string
	err := qb.QueryRowContext(ctx).Scan(&id)
	if err != nil {
		return "", err
	}
	return id, nil
}
func (repo *PostgresRepository) CreateMany(ctx context.Context, cs ...*Creator) error {
	return repo.createMany(ctx, repo.db, cs...)
}
func (repo *PostgresRepository) CreateManyInTx(ctx context.Context, tx nero.Tx, cs ...*Creator) error {
	txx, ok := tx.(*sql.Tx)
	if !ok {
		return errors.New("expecting tx to be *sql.Tx")
	}
	return repo.createMany(ctx, txx, cs...)
}
func (repo *PostgresRepository) createMany(ctx context.Context, runner nero.SQLRunner, cs ...*Creator) error {
	if len(cs) == 0 {
		return nil
	}
	columns := []string{
		"\"email\"",
		"\"name\"",
		"\"age\"",
		"\"race\"",
		"\"updated_at\"",
	}
	qb := squirrel.Insert("\"players\"").Columns(columns...)
	for _, c := range cs {
		if err := c.Validate(); err != nil {
			return err
		}
		qb = qb.Values(
			c.email,
			c.name,
			c.age,
			c.race,
			c.updatedAt,
		)
	}
	qb = qb.Suffix("RETURNING \"id\"").
		PlaceholderFormat(squirrel.Dollar)
	if repo.debug && repo.logger != nil {
		sql, args, err := qb.ToSql()
		repo.logger.Printf("method: CreateMany, stmt: %q, args: %v, error: %v", sql, args, err)
	}
	_, err := qb.RunWith(runner).ExecContext(ctx)
	if err != nil {
		return err
	}
	return nil
}
func (repo *PostgresRepository) Query(ctx context.Context, q *Queryer) ([]*player.Player, error) {
	return repo.query(ctx, repo.db, q)
}
func (repo *PostgresRepository) QueryInTx(ctx context.Context, tx nero.Tx, q *Queryer) ([]*player.Player, error) {
	txx, ok := tx.(*sql.Tx)
	if !ok {
		return nil, errors.New("expecting tx to be *sql.Tx")
	}
	return repo.query(ctx, txx, q)
}
func (repo *PostgresRepository) query(ctx context.Context, runner nero.SQLRunner, q *Queryer) ([]*player.Player, error) {
	qb := repo.buildSelect(q)
	if repo.debug && repo.logger != nil {
		sql, args, err := qb.ToSql()
		repo.logger.Printf("method: Query, stmt: %q, args: %v, error: %v", sql, args, err)
	}
	rows, err := qb.RunWith(runner).QueryContext(ctx)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	players := []*player.Player{}
	for rows.Next() {
		var player player.Player
		err = rows.Scan(
			&player.ID,
			&player.Email,
			&player.Name,
			&player.Age,
			&player.Race,
			&player.UpdatedAt,
			&player.CreatedAt,
		)
		if err != nil {
			return nil, err
		}
		players = append(players, &player)
	}
	return players, nil
}
func (repo *PostgresRepository) QueryOne(ctx context.Context, q *Queryer) (*player.Player, error) {
	return repo.queryOne(ctx, repo.db, q)
}
func (repo *PostgresRepository) QueryOneInTx(ctx context.Context, tx nero.Tx, q *Queryer) (*player.Player, error) {
	txx, ok := tx.(*sql.Tx)
	if !ok {
		return nil, errors.New("expecting tx to be *sql.Tx")
	}
	return repo.queryOne(ctx, txx, q)
}
func (repo *PostgresRepository) queryOne(ctx context.Context, runner nero.SQLRunner, q *Queryer) (*player.Player, error) {
	qb := repo.buildSelect(q)
	if repo.debug && repo.logger != nil {
		sql, args, err := qb.ToSql()
		repo.logger.Printf("method: QueryOne, stmt: %q, args: %v, error: %v", sql, args, err)
	}
	var player player.Player
	err := qb.RunWith(runner).
		QueryRowContext(ctx).
		Scan(
			&player.ID,
			&player.Email,
			&player.Name,
			&player.Age,
			&player.Race,
			&player.UpdatedAt,
			&player.CreatedAt,
		)
	if err != nil {
		return nil, err
	}
	return &player, nil
}
func (repo *PostgresRepository) buildSelect(q *Queryer) squirrel.SelectBuilder {
	columns := []string{
		"\"id\"",
		"\"email\"",
		"\"name\"",
		"\"age\"",
		"\"race\"",
		"\"updated_at\"",
		"\"created_at\"",
	}
	qb := squirrel.Select(columns...).
		From("\"players\"").
		PlaceholderFormat(squirrel.Dollar)
	preds := []*comparison.Predicate{}
	for _, predFunc := range q.predFuncs {
		preds = predFunc(preds)
	}
	qb = squirrel.SelectBuilder(repo.buildPreds(squirrel.StatementBuilderType(qb), preds))
	sorts := []*sort.Sort{}
	for _, sortFunc := range q.sortFuncs {
		sorts = sortFunc(sorts)
	}
	qb = repo.buildSort(qb, sorts)
	if q.limit > 0 {
		qb = qb.Limit(uint64(q.limit))
	}
	if q.offset > 0 {
		qb = qb.Offset(uint64(q.offset))
	}
	return qb
}
func (repo *PostgresRepository) buildPreds(sb squirrel.StatementBuilderType, preds []*comparison.Predicate) squirrel.StatementBuilderType {
	for _, pred := range preds {
		ph := "?"
		fieldX, arg := pred.Field, pred.Arg
		args := []interface{}{}
		if fieldY, ok := arg.(Field); ok {  
			ph = fmt.Sprintf("%q", fieldY)
		} else if vals, ok := arg.([]interface{}); ok {  
			args = append(args, vals...)
		} else {  
			args = append(args, arg)
		}
		switch pred.Op {
		case comparison.Eq:
			sb = sb.Where(fmt.Sprintf("%q = "+ph, fieldX), args...)
		case comparison.NotEq:
			sb = sb.Where(fmt.Sprintf("%q <> "+ph, fieldX), args...)
		case comparison.Gt:
			sb = sb.Where(fmt.Sprintf("%q > "+ph, fieldX), args...)
		case comparison.GtOrEq:
			sb = sb.Where(fmt.Sprintf("%q >= "+ph, fieldX), args...)
		case comparison.Lt:
			sb = sb.Where(fmt.Sprintf("%q < "+ph, fieldX), args...)
		case comparison.LtOrEq:
			sb = sb.Where(fmt.Sprintf("%q <= "+ph, fieldX), args...)
		case comparison.IsNull, comparison.IsNotNull:
			fmtStr := "%q IS NULL"
			if pred.Op == comparison.IsNotNull {
				fmtStr = "%q IS NOT NULL"
			}
			sb = sb.Where(fmt.Sprintf(fmtStr, fieldX))
		case comparison.In, comparison.NotIn:
			fmtStr := "%q IN (%s)"
			if pred.Op == comparison.NotIn {
				fmtStr = "%q NOT IN (%s)"
			}
			phs := []string{}
			for range args {
				phs = append(phs, "?")
			}
			sb = sb.Where(fmt.Sprintf(fmtStr, fieldX, strings.Join(phs, ",")), args...)
		}
	}
	return sb
}
func (repo *PostgresRepository) buildSort(qb squirrel.SelectBuilder, sorts []*sort.Sort) squirrel.SelectBuilder {
	for _, s := range sorts {
		field := fmt.Sprintf("%q", s.Field)
		switch s.Direction {
		case sort.Asc:
			qb = qb.OrderBy(field + " ASC")
		case sort.Desc:
			qb = qb.OrderBy(field + " DESC")
		}
	}
	return qb
}
func (repo *PostgresRepository) Update(ctx context.Context, u *Updater) (int64, error) {
	return repo.update(ctx, repo.db, u)
}
func (repo *PostgresRepository) UpdateInTx(ctx context.Context, tx nero.Tx, u *Updater) (int64, error) {
	txx, ok := tx.(*sql.Tx)
	if !ok {
		return 0, errors.New("expecting tx to be *sql.Tx")
	}
	return repo.update(ctx, txx, u)
}
func (repo *PostgresRepository) update(ctx context.Context, runner nero.SQLRunner, u *Updater) (int64, error) {
	qb := squirrel.Update("\"players\"").
		PlaceholderFormat(squirrel.Dollar)
	cnt := 0
	if !isZero(u.email) {
		qb = qb.Set("\"email\"", u.email)
		cnt++
	}
	if !isZero(u.name) {
		qb = qb.Set("\"name\"", u.name)
		cnt++
	}
	if !isZero(u.age) {
		qb = qb.Set("\"age\"", u.age)
		cnt++
	}
	if !isZero(u.race) {
		qb = qb.Set("\"race\"", u.race)
		cnt++
	}
	if !isZero(u.updatedAt) {
		qb = qb.Set("\"updated_at\"", u.updatedAt)
		cnt++
	}
	if cnt == 0 {
		return 0, nil
	}
	preds := []*comparison.Predicate{}
	for _, predFunc := range u.predFuncs {
		preds = predFunc(preds)
	}
	qb = squirrel.UpdateBuilder(repo.buildPreds(squirrel.StatementBuilderType(qb), preds))
	if repo.debug && repo.logger != nil {
		sql, args, err := qb.ToSql()
		repo.logger.Printf("method: Update, stmt: %q, args: %v, error: %v", sql, args, err)
	}
	res, err := qb.RunWith(runner).ExecContext(ctx)
	if err != nil {
		return 0, err
	}
	rowsAffected, err := res.RowsAffected()
	if err != nil {
		return 0, err
	}
	return rowsAffected, nil
}
func (repo *PostgresRepository) Delete(ctx context.Context, d *Deleter) (int64, error) {
	return repo.delete(ctx, repo.db, d)
}