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  }