genmai.go
func (db *DB) Select(output interface{}, args ...interface{}) (err error) {
	defer func() {
		if e := recover(); e != nil {
			buf := make([]byte, 4096)
			n := runtime.Stack(buf, false)
			err = fmt.Errorf("%v\n%v", e, string(buf[:n]))
		}
	}()
	rv := reflect.ValueOf(output)
	if rv.Kind() != reflect.Ptr {
		return fmt.Errorf("Select: first argument must be a pointer")
	}
	for rv.Kind() == reflect.Ptr {
		rv = rv.Elem()
	}
	var tableName string
	for _, arg := range args {
		if f, ok := arg.(*From); ok {
			if tableName != "" {
				return fmt.Errorf("Select: From statement specified more than once")
			}
			tableName = f.TableName
		}
	}
	var selectFunc selectFunc
	ptrN := 0
	switch rv.Kind() {
	case reflect.Slice:
		t := rv.Type().Elem()
		for ; t.Kind() == reflect.Ptr; ptrN++ {
			t = t.Elem()
		}
		if t.Kind() != reflect.Struct {
			return fmt.Errorf("Select: argument of slice must be slice of struct, but %v", rv.Type())
		}
		if tableName == "" {
			tableName = db.tableName(t)
		}
		selectFunc = db.selectToSlice
	case reflect.Invalid:
		return fmt.Errorf("Select: nil pointer dereference")
	default:
		if tableName == "" {
			return fmt.Errorf("Select: From statement must be given if any Function is given")
		}
		selectFunc = db.selectToValue
	}
	col, from, conditions, err := db.classify(tableName, args)
	if err != nil {
		return err
	}
	queries := []string{`SELECT`, col, `FROM`, db.dialect.Quote(from)}
	var values []interface{}
	for _, cond := range conditions {
		q, a := cond.build(0, false)
		queries = append(queries, q...)
		values = append(values, a...)
	}
	query := strings.Join(queries, " ")
	stmt, err := db.prepare(query, values...)
	if err != nil {
		return err
	}
	defer stmt.Close()
	rows, err := stmt.Query(values...)
	if err != nil {
		return err
	}
	defer rows.Close()
	value, err := selectFunc(rows, rv.Type())
	if err != nil {
		return err
	}
	rv.Set(value)
	return nil
}
func (db *DB) Select(output interface{}, args ...interface{}) (err error) {
	defer func() {
		if e := recover(); e != nil {
			buf := make([]byte, 4096)
			n := runtime.Stack(buf, false)
			err = fmt.Errorf("%v\n%v", e, string(buf[:n]))
		}
	}()
	rv := reflect.ValueOf(output)
	if rv.Kind() != reflect.Ptr {
		return fmt.Errorf("Select: first argument must be a pointer")
	}
	for rv.Kind() == reflect.Ptr {
		rv = rv.Elem()
	}
	var tableName string
	for _, arg := range args {
		if f, ok := arg.(*From); ok {
			if tableName != "" {
				return fmt.Errorf("Select: From statement specified more than once")
			}
			tableName = f.TableName
		}
	}
	var selectFunc selectFunc
	ptrN := 0
	switch rv.Kind() {
	case reflect.Slice:
		t := rv.Type().Elem()
		for ; t.Kind() == reflect.Ptr; ptrN++ {
			t = t.Elem()
		}
		if t.Kind() != reflect.Struct {
			return fmt.Errorf("Select: argument of slice must be slice of struct, but %v", rv.Type())
		}
		if tableName == "" {
			tableName = db.tableName(t)
		}
		selectFunc = db.selectToSlice
	case reflect.Invalid:
		return fmt.Errorf("Select: nil pointer dereference")
	default:
		if tableName == "" {
			return fmt.Errorf("Select: From statement must be given if any Function is given")
		}
		selectFunc = db.selectToValue
	}
	col, from, conditions, err := db.classify(tableName, args)
	if err != nil {
		return err
	}
	queries := []string{`SELECT`, col, `FROM`, db.dialect.Quote(from)}
	var values []interface{}
	for _, cond := range conditions {
		q, a := cond.build(0, false)
		queries = append(queries, q...)
		values = append(values, a...)
	}
	query := strings.Join(queries, " ")
	stmt, err := db.prepare(query, values...)
	if err != nil {
		return err
	}
	defer stmt.Close()
	rows, err := stmt.Query(values...)
	if err != nil {
		return err
	}
	defer rows.Close()
	value, err := selectFunc(rows, rv.Type())
	if err != nil {
		return err
	}
	rv.Set(value)
	return nil
}
// Select fetch data into the output from the database.
// output argument must be pointer to a slice of struct. If not a pointer or not a slice of struct, It returns error.
// The table name of the database will be determined from name of struct. e.g. If *[]ATableName passed to output argument, table name will be "a_table_name".
// If args are not given, fetch the all data like "SELECT * FROM table" SQL.