func (q *Query) argToString(arg interface{}) string {
	switch arg.(type) {
	case string:
		return arg.(string)
	case []byte:
		return string(arg.([]byte))
	case int, int8, int16, int32, uint, uint8, uint16, uint32:
		return fmt.Sprintf("%d", arg)
	case int64, uint64:
		return fmt.Sprintf("%d", arg)
	case float32, float64:
		return fmt.Sprintf("%f", arg)
	case bool:
		return fmt.Sprintf("%d", arg)
	default:
		return fmt.Sprintf("%v", arg)
	}
}
Convert arguments to string - used only for debug argument strings
Not to be exported or used to try to escape strings...
package query
import (
	"database/sql"
	"fmt"
	"sort"
	"strconv"
	"strings"
)
var Debug bool
func init() {
	Debug = false  
}
type Result map[string]interface{}
type Func func(q *Query) *Query
type Query struct {
	tablename  string
	primarykey string
	sql    string
	sel    string
	join   string
	where  string
	group  string
	having string
	order  string
	offset string
	limit  string
	args []interface{}
}
func New(t string, pk string) *Query {
	if database == nil {
		return nil
	}
	q := &Query{
		tablename:  t,
		primarykey: pk,
	}
	return q
}
func Exec(sql string, args ...interface{}) (sql.Result, error) {
	results, err := database.Exec(sql, args...)
	return results, err
}
func Rows(sql string, args ...interface{}) (*sql.Rows, error) {
	results, err := database.Query(sql, args...)
	return results, err
}
func (q *Query) Copy() *Query {
	return &Query{
		tablename:  q.tablename,
		primarykey: q.primarykey,
		sql:        q.sql,
		sel:        q.sel,
		join:       q.join,
		where:      q.where,
		group:      q.group,
		having:     q.having,
		order:      q.order,
		offset:     q.offset,
		limit:      q.limit,
		args:       q.args,
	}
}
func (q *Query) InsertJoin(a int64, b int64) error {
	return q.InsertJoins([]int64{a}, []int64{b})
}
func (q *Query) InsertJoins(a []int64, b []int64) error {
	if len(a) == 0 || len(b) == 0 {
		return fmt.Errorf("Null data for joins insert %s", q.table())
	}
	values := ""
	for _, av := range a {
		for _, bv := range b {
			if av != 0 && bv != 0 {
				values += fmt.Sprintf("(%d,%d),", av, bv)
			}
		}
	}
	values = strings.TrimRight(values, ",")
	sql := fmt.Sprintf("INSERT into %s VALUES %s;", q.table(), values)
	if Debug {
		fmt.Printf("JOINS SQL:%s\n", sql)
	}
	_, err := database.Exec(sql)
	return err
}
func (q *Query) UpdateJoins(id int64, a []int64, b []int64) error {
	if Debug {
		fmt.Printf("SetJoins %s %s=%d: %v %v \n", q.table(), q.pk(), id, a, b)
	}
	err := q.Where(fmt.Sprintf("%s=?", q.pk()), id).Delete()
	if err != nil {
		return err
	}
	if len(a) > 0 && len(b) > 0 {
		err = q.InsertJoins(a, b)
		if err != nil {
			return err
		}
	}
	return nil
}
func (q *Query) Insert(params map[string]string) (int64, error) {
	sql := q.insertSQL(params)
	if Debug {
		fmt.Printf("INSERT SQL:%s %v\n", sql, valuesFromParams(params))
	}
	id, err := database.Insert(sql, valuesFromParams(params)...)
	if err != nil {
		return 0, err
	}
	return id, nil
}
func (q *Query) insertSQL(params map[string]string) string {
	var cols, vals []string
	for i, k := range sortedParamKeys(params) {
		cols = append(cols, database.QuoteField(k))
		vals = append(vals, database.Placeholder(i+1))
	}
	query := fmt.Sprintf("INSERT INTO %s (%s) VALUES(%s) %s;", q.table(), strings.Join(cols, ","), strings.Join(vals, ","), database.InsertSQL(q.pk()))
	return query
}
func (q *Query) Update(params map[string]string) error {
	return q.UpdateAll(params)
}
func (q *Query) Delete() error {
	return q.DeleteAll()
}
func (q *Query) UpdateAll(params map[string]string) error {
	var output []string
	for _, key := range sortedParamKeys(params) {
		v := params[key]
		if v == "null" {
			output = append(output, fmt.Sprintf("%s=null", database.QuoteField(key)))
			delete(params, key)
		} else {
			output = append(output, fmt.Sprintf("%s=?", database.QuoteField(key)))
		}
	}
	querySQL := strings.Join(output, ",")
	q.Select(fmt.Sprintf("UPDATE %s SET %s", q.table(), querySQL))
	values := valuesFromParams(params)
	q.args = append(values, q.args...)
	if Debug {
		fmt.Printf("UPDATE SQL:%s\n%v\n", q.QueryString(), values)
	}
	_, err := q.Result()
	return err
}
func (q *Query) DeleteAll() error {
	q.Select(fmt.Sprintf("DELETE FROM %s", q.table()))
	if Debug {
		fmt.Printf("DELETE SQL:%s <= %v\n", q.QueryString(), q.args)
	}
	_, err := q.Result()
	return err
}
func (q *Query) Count() (int64, error) {
	s := q.sel
	countSelect := fmt.Sprintf("SELECT COUNT(%s) FROM %s", q.pk(), q.table())
	q.Select(countSelect)
	o := strings.Replace(q.order, "ORDER BY ", "", 1)
	q.order = ""
	var count int64
	rows, err := q.Rows()
	if err != nil {
		return 0, fmt.Errorf("Error querying database for count: %s\nQuery:%s", err, q.QueryString())
	}
	defer rows.Close()
	for rows.Next() {
		err = rows.Scan(&count)
		if err != nil {
			return 0, err
		}
	}
	q.Select(s)
	q.Order(o)
	q.reset()
	return count, err
}
func (q *Query) Result() (sql.Result, error) {
	results, err := database.Exec(q.QueryString(), q.args...)
	return results, err
}
func (q *Query) Rows() (*sql.Rows, error) {
	results, err := database.Query(q.QueryString(), q.args...)
	return results, err
}
func (q *Query) FirstResult() (Result, error) {
	q.Limit(1)
	results, err := q.Results()
	if err != nil {
		return nil, err
	}
	if len(results) == 0 {
		return nil, fmt.Errorf("No results found for Query:%s", q.QueryString())
	}
	return results[0], nil
}
func (q *Query) ResultInt64(c string) (int64, error) {
	result, err := q.FirstResult()
	if err != nil || result[c] == nil {
		return 0, err
	}
	var i int64
	switch result[c].(type) {
	case int64:
		i = result[c].(int64)
	case int:
		i = int64(result[c].(int))
	case float64:
		i = int64(result[c].(float64))
	case string:
		f, err := strconv.ParseFloat(result[c].(string), 64)
		if err != nil {
			return i, err
		}
		i = int64(f)
	}
	return i, nil
}
func (q *Query) ResultFloat64(c string) (float64, error) {
	result, err := q.FirstResult()
	if err != nil || result[c] == nil {
		return 0, err
	}
	var f float64
	switch result[c].(type) {
	case float64:
		f = result[c].(float64)
	case int:
		f = float64(result[c].(int))
	case int64:
		f = float64(result[c].(int))
	case string:
		f, err = strconv.ParseFloat(result[c].(string), 64)
		if err != nil {
			return f, err
		}
	}
	return f, nil
}
func (q *Query) Results() ([]Result, error) {
	var results []Result
	rows, err := q.Rows()
	if err != nil {
		return results, fmt.Errorf("Error querying database for rows: %s\nQUERY:%s", err, q)
	}
	defer rows.Close()
	cols, err := rows.Columns()
	if err != nil {
		return results, fmt.Errorf("Error fetching columns: %s\nQUERY:%s\nCOLS:%s", err, q, cols)
	}
	for rows.Next() {
		result, err := scanRow(cols, rows)
		if err != nil {
			return results, fmt.Errorf("Error fetching row: %s\nQUERY:%s\nCOLS:%s", err, q, cols)
		}
		results = append(results, result)
	}
	return results, nil
}
func (q *Query) ResultIDs() []int64 {
	var ids []int64
	if Debug {
		fmt.Printf("#info ResultIDs:%s\n", q.DebugString())
	}
	results, err := q.Results()
	if err != nil {
		return ids
	}
	for _, r := range results {
		if r["id"] != nil {
			ids = append(ids, r["id"].(int64))
		}
	}
	return ids
}
func (q *Query) ResultIDSets(a, b string) map[int64][]int64 {
	idSets := make(map[int64][]int64, 0)
	results, err := q.Results()
	if err != nil {
		return idSets
	}
	for _, r := range results {
		if r[a] != nil && r[b] != nil {
			av := r[a].(int64)
			bv := r[b].(int64)
			idSets[av] = append(idSets[av], bv)
		}
	}
	if Debug {
		fmt.Printf("#info ResultIDSets:%s\n", q.DebugString())
	}
	return idSets
}
func (q *Query) QueryString() string {
	if q.sql == "" {
		if q.sel == "" {
			q.sel = fmt.Sprintf("SELECT %s.* FROM %s", q.table(), q.table())
		}
		q.sql = fmt.Sprintf("%s %s %s %s %s %s %s %s", q.sel, q.join, q.where, q.group, q.having, q.order, q.offset, q.limit)
		q.sql = strings.TrimRight(q.sql, " ")
		q.sql = strings.Replace(q.sql, "  ", " ", -1)
		q.sql = strings.Replace(q.sql, "   ", " ", -1)
		q.replaceArgPlaceholders()
		q.sql = q.sql + ";"
	}
	return q.sql
}
func (q *Query) Apply(f Func) *Query {
	return f(q)
}
func (q *Query) Conditions(funcs ...Func) *Query {
	for _, f := range funcs {
		q = f(q)
	}
	return q
}
func (q *Query) SQL(sql string) *Query {
	q.sql = sql
	q.reset()
	return q
}
func (q *Query) Limit(limit int) *Query {
	q.limit = fmt.Sprintf("LIMIT %d", limit)
	q.reset()
	return q
}
func (q *Query) Offset(offset int) *Query {
	q.offset = fmt.Sprintf("OFFSET %d", offset)
	q.reset()
	return q
}
func (q *Query) Where(sql string, args ...interface{}) *Query {
	if len(q.where) > 0 {
		q.where = fmt.Sprintf("%s AND (%s)", q.where, sql)
	} else {
		q.where = fmt.Sprintf("WHERE (%s)", sql)
	}
	if args != nil {
		if q.args == nil {
			q.args = args
		} else {
			q.args = append(q.args, args...)
		}
	}
	q.reset()
	return q
}
func (q *Query) OrWhere(sql string, args ...interface{}) *Query {
	if len(q.where) > 0 {
		q.where = fmt.Sprintf("%s OR (%s)", q.where, sql)
	} else {
		q.where = fmt.Sprintf("WHERE (%s)", sql)
	}
	if args != nil {
		if q.args == nil {
			q.args = args
		} else {
			q.args = append(q.args, args...)
		}
	}
	q.reset()
	return q
}
func (q *Query) WhereIn(col string, IDs []int64) *Query {
	if len(IDs) == 0 {
		q.Limit(0)
		q.reset()
		return q
	}
	in := ""
	for _, ID := range IDs {
		in = fmt.Sprintf("%s%d,", in, ID)
	}
	in = strings.TrimRight(in, ",")
	sql := fmt.Sprintf("%s IN (%s)", col, in)
	if len(q.where) > 0 {
		q.where = fmt.Sprintf("%s AND (%s)", q.where, sql)
	} else {
		q.where = fmt.Sprintf("WHERE (%s)", sql)
	}
	q.reset()
	return q
}
func (q *Query) Join(otherModel string) *Query {
	modelTable := q.tablename
	tables := []string{
		modelTable,
		ToPlural(otherModel),
	}
	sort.Strings(tables)
	joinTable := fmt.Sprintf("%s_%s", tables[0], tables[1])
	sql := fmt.Sprintf("INNER JOIN %s ON %s.id = %s.%s_id", database.QuoteField(joinTable), database.QuoteField(modelTable), database.QuoteField(joinTable), ToSingular(modelTable))
	if len(q.join) > 0 {
		q.join = fmt.Sprintf("%s %s", q.join, sql)
	} else {
		q.join = fmt.Sprintf("%s", sql)
	}
	q.reset()
	return q
}
func (q *Query) Order(sql string) *Query {
	if sql == "" {
		q.order = ""
	} else {
		q.order = fmt.Sprintf("ORDER BY %s", sql)
	}
	q.reset()
	return q
}
func (q *Query) Group(sql string) *Query {
	if sql == "" {
		q.group = ""
	} else {
		q.group = fmt.Sprintf("GROUP BY %s", sql)
	}
	q.reset()
	return q
}
func (q *Query) Having(sql string) *Query {
	if sql == "" {
		q.having = ""
	} else {
		q.having = fmt.Sprintf("HAVING %s", sql)
	}
	q.reset()
	return q
}
func (q *Query) Select(sql string) *Query {
	q.sel = sql
	q.reset()
	return q
}
func (q *Query) DebugString() string {
	return fmt.Sprintf("--\nQuery-SQL:%s\nARGS:%s\n--", q.QueryString(), q.argString())
}
func (q *Query) reset() {
	q.sql = ""
}
func (q *Query) argString() string {
	output := "-"
	for _, a := range q.args {
		output = output + fmt.Sprintf("'%s',", q.argToString(a))
	}
	output = strings.TrimRight(output, ",")
	output = output + ""
	return output
}