Example #1
0
// Compile outputs the INSERT statement using the given dialect and parameters.
// An error may be returned because of a pre-existing error or because
// an error occurred during compilation.
func (stmt InsertStmt) Compile(d dialect.Dialect, ps *Parameters) (string, error) {
	// Check for delayed errors
	if err := stmt.Error(); err != nil {
		return "", err
	}

	cols := len(stmt.columns)
	// No columns? no statement!
	if cols == 0 {
		return "", ErrNoColumns
	}

	columns := make([]string, len(stmt.columns))
	for i, column := range stmt.columns {
		columns[i] = fmt.Sprintf(`"%s"`, column.Name())
	}

	// args must be divisable by cols without remainder
	if len(stmt.args)%cols != 0 {
		return "", fmt.Errorf(
			`sol: size mismatch between arguments and columns during INSERT: %d is not a multiple of %d`,
			len(stmt.args),
			cols,
		)
	}

	// Determine the number of rows that will be inserted
	rows := len(stmt.args) / cols
	// If there are no arguments, default to one rows and create
	// placeholder values
	if rows == 0 {
		rows = 1
		stmt.args = make([]interface{}, cols)
		for i, _ := range stmt.args {
			stmt.args[i] = nil
		}
	}
	parameters := make([]string, rows)

	var param int
	for i := 0; i < rows; i += 1 {
		row := make([]string, cols)
		for j := 0; j < cols; j += 1 {
			// Parameters are dialect specific
			row[j] = d.Param(param)
			ps.Add(stmt.args[param])
			param += 1
		}
		// TODO Parameters compilation?
		parameters[i] = fmt.Sprintf(`(%s)`, strings.Join(row, ", "))
	}

	// TODO Bulk insert syntax is dialect specific
	return fmt.Sprintf(
		`INSERT INTO %s (%s) VALUES %s`,
		stmt.table.Name(),
		strings.Join(columns, ", "),
		strings.Join(parameters, ", "),
	), nil
}
Example #2
0
// Parameter compilation is dialect dependent. For instance, dialects such
// as PostGres require the parameter index.
func (p *Parameter) Compile(d dialect.Dialect, ps *Parameters) (string, error) {
	ps.Add(p.Value)
	return d.Param(ps.Len() - 1), nil
}