package pg

import (
	
	
	

	
	
	
)

// Discard is used with Query and QueryOne to discard rows.
var Discard orm.Discard

// NullTime is a time.Time wrapper that marshals zero time as JSON null and
// PostgreSQL NULL.
type NullTime = types.NullTime

// Scan returns ColumnScanner that copies the columns in the
// row into the values.
func ( ...interface{}) orm.ColumnScanner {
	return orm.Scan(...)
}

// Safe represents a safe SQL query.
type Safe = types.Safe

// Ident represents a SQL identifier, e.g. table or column name.
type Ident = types.Ident

// SafeQuery replaces any placeholders found in the query.
func ( string,  ...interface{}) *orm.SafeQueryAppender {
	return orm.SafeQuery(, ...)
}

// In accepts a slice and returns a wrapper that can be used with PostgreSQL
// IN operator:
//
//    Where("id IN (?)", pg.In([]int{1, 2, 3, 4}))
//
// produces
//
//    WHERE id IN (1, 2, 3, 4)
func ( interface{}) types.ValueAppender {
	return types.In()
}

// InMulti accepts multiple values and returns a wrapper that can be used
// with PostgreSQL IN operator:
//
//    Where("(id1, id2) IN (?)", pg.InMulti([]int{1, 2}, []int{3, 4}))
//
// produces
//
//    WHERE (id1, id2) IN ((1, 2), (3, 4))
func ( ...interface{}) types.ValueAppender {
	return types.InMulti(...)
}

// Array accepts a slice and returns a wrapper for working with PostgreSQL
// array data type.
//
// For struct fields you can use array tag:
//
//    Emails  []string `pg:",array"`
func ( interface{}) *types.Array {
	return types.NewArray()
}

// Hstore accepts a map and returns a wrapper for working with hstore data type.
// Supported map types are:
//   - map[string]string
//
// For struct fields you can use hstore tag:
//
//    Attrs map[string]string `pg:",hstore"`
func ( interface{}) *types.Hstore {
	return types.NewHstore()
}

// SetLogger sets the logger to the given one.
func ( internal.Logging) {
	internal.Logger = 
}

//------------------------------------------------------------------------------

type Query = orm.Query

// Model returns a new query for the optional model.
func ( ...interface{}) *Query {
	return orm.NewQuery(nil, ...)
}

// ModelContext returns a new query for the optional model with a context.
func ( context.Context,  ...interface{}) *Query {
	return orm.NewQueryContext(, nil, ...)
}

// DBI is a DB interface implemented by *DB and *Tx.
type DBI interface {
	Model(model ...interface{}) *Query
	ModelContext(c context.Context, model ...interface{}) *Query

	Exec(query interface{}, params ...interface{}) (Result, error)
	ExecContext(c context.Context, query interface{}, params ...interface{}) (Result, error)
	ExecOne(query interface{}, params ...interface{}) (Result, error)
	ExecOneContext(c context.Context, query interface{}, params ...interface{}) (Result, error)
	Query(model, query interface{}, params ...interface{}) (Result, error)
	QueryContext(c context.Context, model, query interface{}, params ...interface{}) (Result, error)
	QueryOne(model, query interface{}, params ...interface{}) (Result, error)
	QueryOneContext(c context.Context, model, query interface{}, params ...interface{}) (Result, error)

	Begin() (*Tx, error)
	RunInTransaction(ctx context.Context, fn func(*Tx) error) error

	CopyFrom(r io.Reader, query interface{}, params ...interface{}) (Result, error)
	CopyTo(w io.Writer, query interface{}, params ...interface{}) (Result, error)
}

var (
	_ DBI = (*DB)(nil)
	_ DBI = (*Tx)(nil)
)

//------------------------------------------------------------------------------

// Strings is a type alias for a slice of strings.
type Strings []string

var (
	_ orm.HooklessModel   = (*Strings)(nil)
	_ types.ValueAppender = (*Strings)(nil)
)

// Init initializes the Strings slice.
func ( *Strings) () error {
	if  := *; len() > 0 {
		* = [:0]
	}
	return nil
}

// NextColumnScanner ...
func ( *Strings) () orm.ColumnScanner {
	return 
}

// AddColumnScanner ...
func (Strings) ( orm.ColumnScanner) error {
	return nil
}

// ScanColumn scans the columns and appends them to `strings`.
func ( *Strings) ( types.ColumnInfo,  types.Reader,  int) error {
	 := make([]byte, )
	,  := io.ReadFull(, )
	if  != nil {
		return 
	}

	* = append(*, internal.BytesToString())
	return nil
}

// AppendValue appends the values from `strings` to the given byte slice.
func ( Strings) ( []byte,  int) ([]byte, error) {
	if len() == 0 {
		return , nil
	}

	for ,  := range  {
		 = types.AppendString(, , 1)
		 = append(, ',')
	}
	 = [:len()-1]
	return , nil
}

//------------------------------------------------------------------------------

// Ints is a type alias for a slice of int64 values.
type Ints []int64

var (
	_ orm.HooklessModel   = (*Ints)(nil)
	_ types.ValueAppender = (*Ints)(nil)
)

// Init initializes the Int slice.
func ( *Ints) () error {
	if  := *; len() > 0 {
		* = [:0]
	}
	return nil
}

// NewColumnScanner ...
func ( *Ints) () orm.ColumnScanner {
	return 
}

// AddColumnScanner ...
func (Ints) ( orm.ColumnScanner) error {
	return nil
}

// ScanColumn scans the columns and appends them to `ints`.
func ( *Ints) ( types.ColumnInfo,  types.Reader,  int) error {
	,  := types.ScanInt64(, )
	if  != nil {
		return 
	}

	* = append(*, )
	return nil
}

// AppendValue appends the values from `ints` to the given byte slice.
func ( Ints) ( []byte,  int) ([]byte, error) {
	if len() == 0 {
		return , nil
	}

	for ,  := range  {
		 = strconv.AppendInt(, , 10)
		 = append(, ',')
	}
	 = [:len()-1]
	return , nil
}

//------------------------------------------------------------------------------

// IntSet is a set of int64 values.
type IntSet map[int64]struct{}

var _ orm.HooklessModel = (*IntSet)(nil)

// Init initializes the IntSet.
func ( *IntSet) () error {
	if len(*) > 0 {
		* = make(map[int64]struct{})
	}
	return nil
}

// NextColumnScanner ...
func ( *IntSet) () orm.ColumnScanner {
	return 
}

// AddColumnScanner ...
func (IntSet) ( orm.ColumnScanner) error {
	return nil
}

// ScanColumn scans the columns and appends them to `IntSet`.
func ( *IntSet) ( types.ColumnInfo,  types.Reader,  int) error {
	,  := types.ScanInt64(, )
	if  != nil {
		return 
	}

	 := *
	if  == nil {
		* = make(IntSet)
		 = *
	}

	[] = struct{}{}
	return nil
}