func (s *Store) MustFind(q Query) ResultSet {
	rs, err := s.Find(q)
	if err != nil {
		panic(err)
	}
	return rs
}
MustFind performs a query and returns a result set with the results.
It panics if the query fails.
package kallax
import (
	"bytes"
	"database/sql"
	"errors"
	"fmt"
	"log"
	"time"
	"github.com/Masterminds/squirrel"
	"github.com/lann/builder"
)
var (
	ErrNonNewDocument = errors.New("kallax: cannot insert a non new document")
	ErrNewDocument = errors.New("kallax: cannot updated a new document")
	ErrEmptyID = errors.New("kallax: a record without id is not allowed")
	ErrNoRowUpdate = errors.New("kallax: update affected no rows")
	ErrNotWritable = errors.New("kallax: record is not writable")
	ErrStop = errors.New("kallax: stopped ForEach execution")
	ErrInvalidTxCallback = errors.New("kallax: invalid transaction callback given")
	ErrNotFound = errors.New("kallax: entity not found")
	ErrCantSetID = errors.New("kallax: model does not have an auto incrementable primary key, it needs to implement IDSetter interface")
	ErrNoColumns = errors.New("kallax: your model does not have any column besides its autoincrementable primary key and cannot be inserted")
)
type GenericStorer interface {
	GenericStore() *Store
	SetGenericStore(*Store)
}
func StoreFrom(to, from GenericStorer) {
	if to == nil || from == nil {
		return
	}
	to.SetGenericStore(from.GenericStore())
}
type LoggerFunc func(string, ...interface{})
func defaultLogger(message string, args ...interface{}) {
	log.Printf("%s, args: %v", message, args)
}
type proxyLogger struct {
	squirrel.DBProxyContext
	logger LoggerFunc
}
func (p *proxyLogger) Exec(query string, args ...interface{}) (sql.Result, error) {
	start := time.Now()
	result, err := p.DBProxyContext.Exec(query, args...)
	p.logger(fmt.Sprintf("kallax: Exec: (%v) %s", time.Since(start), query), args...)
	return result, err
}
func (p *proxyLogger) Query(query string, args ...interface{}) (*sql.Rows, error) {
	start := time.Now()
	rows, err := p.DBProxyContext.Query(query, args...)
	p.logger(fmt.Sprintf("kallax: Query: (%v) %s", time.Since(start), query), args...)
	return rows, err
}
func (p *proxyLogger) QueryRow(query string, args ...interface{}) squirrel.RowScanner {
	start := time.Now()
	rowScanner := p.DBProxyContext.QueryRow(query, args...)
	p.logger(fmt.Sprintf("kallax: QueryRow: (%v) %s", time.Since(start), query), args...)
	return rowScanner
}
func (p *proxyLogger) Prepare(query string) (*sql.Stmt, error) {
	start := time.Now()
	statement, err := p.DBProxyContext.Prepare(query)
	p.logger(fmt.Sprintf("kallax: Prepare: (%v) %s", time.Since(start), query))
	return statement, err
}
type dbRunner struct {
	*sql.DB
}
func (r *dbRunner) QueryRow(query string, args ...interface{}) squirrel.RowScanner {
	return r.DB.QueryRow(query, args...)
}
type txRunner struct {
	*sql.Tx
}
func (r *txRunner) QueryRow(query string, args ...interface{}) squirrel.RowScanner {
	return r.Tx.QueryRow(query, args...)
}
type Store struct {
	db        squirrel.DBProxyContext
	runner    squirrel.DBProxyContext
	useCacher bool
	logger    LoggerFunc
}
func NewStore(db *sql.DB) *Store {
	return (&Store{
		db:        &dbRunner{db},
		useCacher: true,
	}).init()
}
func (s *Store) init() *Store {
	s.runner = s.db
	if s.useCacher {
		s.runner = squirrel.NewStmtCacher(s.db)
	}
	if s.logger != nil {
		s.runner = &proxyLogger{logger: s.logger, DBProxyContext: s.runner}
	}
	return s
}
func (s *Store) Debug() *Store {
	return s.DebugWith(defaultLogger)
}
func (s *Store) DebugWith(logger LoggerFunc) *Store {
	return (&Store{
		db:        s.db,
		useCacher: s.useCacher,
		logger:    logger,
	}).init()
}
func (s *Store) DisableCacher() *Store {
	return (&Store{
		db:        s.db,
		logger:    s.logger,
		useCacher: false,
	}).init()
}
func (s *Store) Insert(schema Schema, record Record) error {
	if record.IsPersisted() {
		return ErrNonNewDocument
	}
	cols := ColumnNames(schema.Columns())
	if schema.isPrimaryKeyAutoIncrementable() {
		cols = cols[1:]
	}
	if len(cols) == 0 {
		return ErrNoColumns
	}
	values, cols, err := RecordValues(record, cols...)
	if err != nil {
		return err
	}
	virtualCols, virtualColValues := virtualColumns(record, cols)
	cols = append(cols, virtualCols...)
	values = append(values, virtualColValues...)
	var colBuf bytes.Buffer
	var valBuf bytes.Buffer
	for i, col := range cols {
		if i != 0 {
			colBuf.WriteRune(',')
			valBuf.WriteRune(',')
		}
		colBuf.WriteString(col)
		valBuf.WriteString(fmt.Sprintf("$%d", i+1))
	}
	var query bytes.Buffer
	query.WriteString("INSERT INTO ")
	query.WriteString(schema.Table())
	query.WriteString(" (")
	query.WriteString(colBuf.String())
	query.WriteString(") VALUES (")
	query.WriteString(valBuf.String())
	query.WriteString(")")
	if schema.isPrimaryKeyAutoIncrementable() {
		var pk interface{}
		pk, err = record.ColumnAddress(schema.ID().String())
		if err != nil {
			return err
		}
		query.WriteString(fmt.Sprintf(" RETURNING %s", schema.ID().String()))
		rows, err := s.runner.Query(query.String(), values...)
		if err != nil {
			return err
		}
		if rows.Next() {
			err = rows.Scan(pk)
			rows.Close()
			if err != nil {
				return err
			}
		}
	} else {
		_, err = s.runner.Exec(query.String(), values...)
	}
	if err != nil {
		return err
	}
	record.setWritable(true)
	record.setPersisted()
	return nil
}
func (s *Store) Update(schema Schema, record Record, cols ...SchemaField) (int64, error) {
	if !record.IsWritable() {
		return 0, ErrNotWritable
	}
	if !record.IsPersisted() {
		return 0, ErrNewDocument
	}
	if record.GetID().IsEmpty() {
		return 0, ErrEmptyID
	}
	if len(cols) == 0 {
		cols = schema.Columns()
	}
	columnNames := ColumnNames(cols)
	values, columnNames, err := RecordValues(record, columnNames...)
	if err != nil {
		return 0, err
	}
	virtualCols, virtualColValues := virtualColumns(record, columnNames)
	columnNames = append(columnNames, virtualCols...)
	values = append(values, virtualColValues...)
	var query bytes.Buffer
	query.WriteString("UPDATE ")
	query.WriteString(schema.Table())
	query.WriteString(" SET ")
	for i, col := range columnNames {
		if i != 0 {
			query.WriteRune(',')
		}
		query.WriteString(col)
		query.WriteRune('=')
		query.WriteString(fmt.Sprintf("$%d", i+1))
	}
	query.WriteString(" WHERE ")
	query.WriteString(schema.ID().String())
	query.WriteRune('=')
	query.WriteString(fmt.Sprintf("$%d", len(columnNames)+1))
	result, err := s.runner.Exec(query.String(), append(values, record.GetID())...)
	if err != nil {
		return 0, err
	}
	cnt, err := result.RowsAffected()
	if err != nil {
		return 0, err
	}
	if cnt == 0 {
		return 0, ErrNoRowUpdate
	}
	return cnt, nil
}
func (s *Store) Save(schema Schema, record Record) (updated bool, err error) {
	if !record.IsPersisted() {
		return false, s.Insert(schema, record)
	}
	rowsUpdated, err := s.Update(schema, record)
	if err != nil {
		return false, err
	}
	return rowsUpdated > 0, nil
}
func (s *Store) Delete(schema Schema, record Record) error {
	if record.GetID().IsEmpty() {
		return ErrEmptyID
	}
	var query bytes.Buffer
	query.WriteString("DELETE FROM ")
	query.WriteString(schema.Table())
	query.WriteString(" WHERE ")
	query.WriteString(schema.ID().String())
	query.WriteString("=$1")
	_, err := s.runner.Exec(query.String(), record.GetID())
	return err
}
func (s *Store) RawQuery(sql string, params ...interface{}) (ResultSet, error) {
	rows, err := s.runner.Query(sql, params...)
	if err != nil {
		return nil, err
	}
	return NewResultSet(rows, true, nil), nil
}
func (s *Store) RawExec(sql string, params ...interface{}) (int64, error) {
	result, err := s.runner.Exec(sql, params...)
	if err != nil {
		return 0, err
	}
	return result.RowsAffected()
}
func (s *Store) Find(q Query) (ResultSet, error) {
	rels := q.getRelationships()
	if containsRelationshipOfType(rels, OneToMany) {
		return NewBatchingResultSet(newBatchQueryRunner(q.Schema(), s.runner, q)), nil
	}
	columns, builder := q.compile()
	if offset := q.GetOffset(); offset > 0 {
		builder = builder.Offset(offset)
	}
	if limit := q.GetLimit(); limit > 0 {
		builder = builder.Limit(limit)
	}
	rows, err := builder.RunWith(s.runner).Query()
	if err != nil {
		return nil, err
	}
	return NewResultSet(
		rows,
		q.isReadOnly(),
		q.getRelationships(),
		columns...,
	), nil
}