package squirrel import ( "bytes" "database/sql" "fmt" "strings" "github.com/lann/builder" ) type deleteData struct { PlaceholderFormat PlaceholderFormat RunWith BaseRunner Prefixes []Sqlizer What []string From string Joins []Sqlizer Usings []string WhereParts []Sqlizer OrderBys []string Limit string Offset string Suffixes []Sqlizer } func (d *deleteData) Exec() (sql.Result, error) { if d.RunWith == nil { return nil, RunnerNotSet } return ExecWith(d.RunWith, d) } func (d *deleteData) ToSql() (sqlStr string, args []interface{}, err error) { if len(d.From) == 0 { err = fmt.Errorf("delete statements must specify a From table") return } sql := &bytes.Buffer{} if len(d.Prefixes) > 0 { args, err = appendToSql(d.Prefixes, sql, " ", args) if err != nil { return } sql.WriteString(" ") } sql.WriteString("DELETE") if len(d.What) > 0 { sql.WriteString(" ") sql.WriteString(strings.Join(d.What, ", ")) } sql.WriteString(" FROM ") sql.WriteString(d.From) if len(d.Usings) > 0 { sql.WriteString(" USING ") sql.WriteString(strings.Join(d.Usings, ", ")) } if len(d.Joins) > 0 { sql.WriteString(" ") args, err = appendToSql(d.Joins, sql, " ", args) if err != nil { return } } if len(d.WhereParts) > 0 { sql.WriteString(" WHERE ") args, err = appendToSql(d.WhereParts, sql, " AND ", args) if err != nil { return } } if len(d.OrderBys) > 0 { sql.WriteString(" ORDER BY ") sql.WriteString(strings.Join(d.OrderBys, ", ")) } if len(d.Limit) > 0 { sql.WriteString(" LIMIT ") sql.WriteString(d.Limit) } if len(d.Offset) > 0 { sql.WriteString(" OFFSET ") sql.WriteString(d.Offset) } if len(d.Suffixes) > 0 { sql.WriteString(" ") args, err = appendToSql(d.Suffixes, sql, " ", args) if err != nil { return } } sqlStr, err = d.PlaceholderFormat.ReplacePlaceholders(sql.String()) return } // Builder // DeleteBuilder builds SQL DELETE statements. type DeleteBuilder builder.Builder func init() { builder.Register(DeleteBuilder{}, deleteData{}) } // Format methods // PlaceholderFormat sets PlaceholderFormat (e.g. Question or Dollar) for the // query. func (b DeleteBuilder) PlaceholderFormat(f PlaceholderFormat) DeleteBuilder { return builder.Set(b, "PlaceholderFormat", f).(DeleteBuilder) } // Runner methods // RunWith sets a Runner (like database/sql.DB) to be used with e.g. Exec. func (b DeleteBuilder) RunWith(runner BaseRunner) DeleteBuilder { return setRunWith(b, runner).(DeleteBuilder) } // Exec builds and Execs the query with the Runner set by RunWith. func (b DeleteBuilder) Exec() (sql.Result, error) { data := builder.GetStruct(b).(deleteData) return data.Exec() } // SQL methods // ToSql builds the query into a SQL string and bound args. func (b DeleteBuilder) ToSql() (string, []interface{}, error) { data := builder.GetStruct(b).(deleteData) return data.ToSql() } // MustSql builds the query into a SQL string and bound args. // It panics if there are any errors. func (b DeleteBuilder) MustSql() (string, []interface{}) { sql, args, err := b.ToSql() if err != nil { panic(err) } return sql, args } // Prefix adds an expression to the beginning of the query func (b DeleteBuilder) Prefix(sql string, args ...interface{}) DeleteBuilder { return b.PrefixExpr(Expr(sql, args...)) } // PrefixExpr adds an expression to the very beginning of the query func (b DeleteBuilder) PrefixExpr(expr Sqlizer) DeleteBuilder { return builder.Append(b, "Prefixes", expr).(DeleteBuilder) } // What injects something between DELETE and FROM in the query, allowing the MySQL specific // multi-table syntax, itself often useful with joins. func (b DeleteBuilder) What(what ...string) DeleteBuilder { return builder.Extend(b, "What", what).(DeleteBuilder) } // From sets the table to be deleted from. func (b DeleteBuilder) From(from string) DeleteBuilder { return builder.Set(b, "From", from).(DeleteBuilder) } // Using adds USING expressions to the query. func (b DeleteBuilder) Using(usings ...string) DeleteBuilder { return builder.Extend(b, "Usings", usings).(DeleteBuilder) } // JoinClause adds a join clause to the query. func (b DeleteBuilder) JoinClause(pred interface{}, args ...interface{}) DeleteBuilder { return builder.Append(b, "Joins", newPart(pred, args...)).(DeleteBuilder) } // Join adds a JOIN clause to the query. func (b DeleteBuilder) Join(join string, rest ...interface{}) DeleteBuilder { return b.JoinClause("JOIN "+join, rest...) } // LeftJoin adds a LEFT JOIN clause to the query. func (b DeleteBuilder) LeftJoin(join string, rest ...interface{}) DeleteBuilder { return b.JoinClause("LEFT JOIN "+join, rest...) } // RightJoin adds a RIGHT JOIN clause to the query. func (b DeleteBuilder) RightJoin(join string, rest ...interface{}) DeleteBuilder { return b.JoinClause("RIGHT JOIN "+join, rest...) } // InnerJoin adds a INNER JOIN clause to the query. func (b DeleteBuilder) InnerJoin(join string, rest ...interface{}) DeleteBuilder { return b.JoinClause("INNER JOIN "+join, rest...) } // CrossJoin adds a CROSS JOIN clause to the query. func (b DeleteBuilder) CrossJoin(join string, rest ...interface{}) DeleteBuilder { return b.JoinClause("CROSS JOIN "+join, rest...) } // Where adds WHERE expressions to the query. // // See SelectBuilder.Where for more information. func (b DeleteBuilder) Where(pred interface{}, args ...interface{}) DeleteBuilder { return builder.Append(b, "WhereParts", newWherePart(pred, args...)).(DeleteBuilder) } // OrderBy adds ORDER BY expressions to the query. func (b DeleteBuilder) OrderBy(orderBys ...string) DeleteBuilder { return builder.Extend(b, "OrderBys", orderBys).(DeleteBuilder) } // Limit sets a LIMIT clause on the query. func (b DeleteBuilder) Limit(limit uint64) DeleteBuilder { return builder.Set(b, "Limit", fmt.Sprintf("%d", limit)).(DeleteBuilder) } // Offset sets a OFFSET clause on the query. func (b DeleteBuilder) Offset(offset uint64) DeleteBuilder { return builder.Set(b, "Offset", fmt.Sprintf("%d", offset)).(DeleteBuilder) } // Suffix adds an expression to the end of the query func (b DeleteBuilder) Suffix(sql string, args ...interface{}) DeleteBuilder { return b.SuffixExpr(Expr(sql, args...)) } // SuffixExpr adds an expression to the end of the query func (b DeleteBuilder) SuffixExpr(expr Sqlizer) DeleteBuilder { return builder.Append(b, "Suffixes", expr).(DeleteBuilder) } func (b DeleteBuilder) Query() (*sql.Rows, error) { data := builder.GetStruct(b).(deleteData) return data.Query() } func (d *deleteData) Query() (*sql.Rows, error) { if d.RunWith == nil { return nil, RunnerNotSet } return QueryWith(d.RunWith, d) }