package bun

import (
	
	
	

	
	
)

type ValuesQuery struct {
	baseQuery
	customValueQuery

	withOrder bool
}

var _ schema.NamedArgAppender = (*ValuesQuery)(nil)

func ( *DB,  interface{}) *ValuesQuery {
	 := &ValuesQuery{
		baseQuery: baseQuery{
			db:   ,
			conn: .DB,
		},
	}
	.setTableModel()
	return 
}

func ( *ValuesQuery) ( IConn) *ValuesQuery {
	.setConn()
	return 
}

// Value overwrites model value for the column.
func ( *ValuesQuery) ( string,  string,  ...interface{}) *ValuesQuery {
	if .table == nil {
		.err = errNilModel
		return 
	}
	.addValue(.table, , , )
	return 
}

func ( *ValuesQuery) () *ValuesQuery {
	.withOrder = true
	return 
}

func ( *ValuesQuery) ( schema.Formatter,  []byte,  string) ([]byte, bool) {
	switch  {
	case "Columns":
		,  := .AppendColumns(, )
		if  != nil {
			.setErr()
			return , true
		}
		return , true
	}
	return , false
}

// AppendColumns appends the table columns. It is used by CTE.
func ( *ValuesQuery) ( schema.Formatter,  []byte) ( []byte,  error) {
	if .err != nil {
		return nil, .err
	}
	if .model == nil {
		return nil, errNilModel
	}

	if .tableModel != nil {
		,  := .getFields()
		if  != nil {
			return nil, 
		}

		 = appendColumns(, "", )

		if .withOrder {
			 = append(, ", _order"...)
		}

		return , nil
	}

	switch model := .model.(type) {
	case *mapSliceModel:
		return .appendColumns(, )
	}

	return nil, fmt.Errorf("bun: Values does not support %T", .model)
}

func ( *ValuesQuery) () string {
	return "SELECT"
}

func ( *ValuesQuery) ( schema.Formatter,  []byte) ( []byte,  error) {
	if .err != nil {
		return nil, .err
	}
	if .model == nil {
		return nil, errNilModel
	}

	 = formatterWithModel(, )

	if .tableModel != nil {
		,  := .getFields()
		if  != nil {
			return nil, 
		}
		return .appendQuery(, , )
	}

	switch model := .model.(type) {
	case *mapSliceModel:
		return .appendValues(, )
	}

	return nil, fmt.Errorf("bun: Values does not support %T", .model)
}

func ( *ValuesQuery) (
	 schema.Formatter,
	 []byte,
	 []*schema.Field,
) ( []byte,  error) {
	 = append(, "VALUES "...)
	if .db.features.Has(feature.ValuesRow) {
		 = append(, "ROW("...)
	} else {
		 = append(, '(')
	}

	switch model := .tableModel.(type) {
	case *structTableModel:
		,  = .appendValues(, , , .strct)
		if  != nil {
			return nil, 
		}

		if .withOrder {
			 = append(, ", "...)
			 = strconv.AppendInt(, 0, 10)
		}
	case *sliceTableModel:
		 := .slice
		 := .Len()
		for  := 0;  < ; ++ {
			if  > 0 {
				 = append(, "), "...)
				if .db.features.Has(feature.ValuesRow) {
					 = append(, "ROW("...)
				} else {
					 = append(, '(')
				}
			}

			,  = .appendValues(, , , .Index())
			if  != nil {
				return nil, 
			}

			if .withOrder {
				 = append(, ", "...)
				 = strconv.AppendInt(, int64(), 10)
			}
		}
	default:
		return nil, fmt.Errorf("bun: Values does not support %T", .model)
	}

	 = append(, ')')

	return , nil
}

func ( *ValuesQuery) (
	 schema.Formatter,  []byte,  []*schema.Field,  reflect.Value,
) ( []byte,  error) {
	 := .IsNop()
	for ,  := range  {
		if  > 0 {
			 = append(, ", "...)
		}

		,  := .modelValues[.Name]
		if  {
			,  = .AppendQuery(, )
			if  != nil {
				return nil, 
			}
			continue
		}

		if  {
			 = append(, '?')
		} else {
			 = .AppendValue(, , indirect())
		}

		if .HasFeature(feature.DoubleColonCast) {
			 = append(, "::"...)
			 = append(, .UserSQLType...)
		}
	}
	return , nil
}