// 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 }
// 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 }