gitlab.com/beacon-software/gadget@v0.0.0-20181217202115-54565ea1ed5e/database/qb/delete.go (about) 1 package qb 2 3 import ( 4 "fmt" 5 "strings" 6 7 "gitlab.com/beacon-software/gadget/errors" 8 ) 9 10 /* 11 DELETE [LOW_PRIORITY] [QUICK] [IGNORE] 12 tbl_name[.*] [, tbl_name[.*]] ... 13 FROM table_references 14 [WHERE where_condition] 15 */ 16 17 // DeleteQuery for removing rows from a database 18 type DeleteQuery struct { 19 tables []Table 20 from Table 21 joins []*Join 22 where *whereCondition 23 // NICE TO HAVE: Add orderby and limit logic, order by and limit only apply to single table case 24 err error 25 } 26 27 // GetAlias of the passed table name in this query 28 func (q *DeleteQuery) GetAlias(tableName string) string { 29 return tableName 30 } 31 32 // From sets the primary table the query will find rows in. 33 func (q *DeleteQuery) From(table Table) *DeleteQuery { 34 q.from = table 35 return q 36 } 37 38 // InnerJoin with another table in the database. 39 func (q *DeleteQuery) InnerJoin(table Table) *Join { 40 join := NewJoin(Inner, Right, table) 41 q.joins = append(q.joins, join) 42 return join 43 } 44 45 // OuterJoin with another table in the database. 46 func (q *DeleteQuery) OuterJoin(direction JoinDirection, table Table) *Join { 47 join := NewJoin(Outer, direction, table) 48 q.joins = append(q.joins, join) 49 return join 50 } 51 52 // Where determines what rows to delete from. 53 func (q *DeleteQuery) Where(condition *ConditionExpression) *DeleteQuery { 54 q.where.expression = condition 55 return q 56 } 57 58 // Validate that this query is executable 59 func (q *DeleteQuery) Validate() bool { 60 if nil == q.from && len(q.tables) == 0 { 61 q.err = errors.New("at least one table must be specified to delete from") 62 return false 63 } 64 65 if nil == q.where.expression { 66 q.err = errors.New("delete requires a where clause") 67 return false 68 } 69 70 for _, join := range q.joins { 71 if nil != join.err { 72 q.err = join.err 73 return false 74 } 75 } 76 77 return true 78 } 79 80 // SQL representation of this delete query. 81 func (q *DeleteQuery) SQL() (string, []interface{}, error) { 82 if !q.Validate() { 83 return "", nil, q.err 84 } 85 lines := []string{"DELETE"} 86 values := []interface{}{} 87 rowsInLines := make([]string, len(q.tables)) 88 89 if len(q.tables) == 1 && nil == q.from { 90 q.from = q.tables[0] 91 } else { 92 for i, table := range q.tables { 93 rowsInLines[i] = fmt.Sprintf("`%s`", table.GetName()) 94 } 95 lines = append(lines, strings.Join(rowsInLines, ", ")) 96 } 97 98 // FROM 99 lines = append(lines, fmt.Sprintf("FROM `%s`", q.from.GetName())) 100 101 // JOIN 102 for _, join := range q.joins { 103 joinSQL, joinValues := join.SQL() 104 lines = append(lines, joinSQL) 105 values = append(values, joinValues...) 106 } 107 108 // WHERE 109 if where, whereValues, ok := q.where.sql(); ok { 110 lines = append(lines, "WHERE", where) 111 values = append(values, whereValues...) 112 } 113 114 return strings.Join(lines, " "), values, q.err 115 }