...

Source file src/github.com/doug-martin/goqu/v9/update_dataset.go

Documentation: github.com/doug-martin/goqu/v9

     1  package goqu
     2  
     3  import (
     4  	"github.com/doug-martin/goqu/v9/exec"
     5  	"github.com/doug-martin/goqu/v9/exp"
     6  	"github.com/doug-martin/goqu/v9/internal/errors"
     7  	"github.com/doug-martin/goqu/v9/internal/sb"
     8  )
     9  
    10  type UpdateDataset struct {
    11  	dialect      SQLDialect
    12  	clauses      exp.UpdateClauses
    13  	isPrepared   prepared
    14  	queryFactory exec.QueryFactory
    15  	err          error
    16  }
    17  
    18  var ErrUnsupportedUpdateTableType = errors.New("unsupported table type, a string or identifier expression is required")
    19  
    20  // used internally by database to create a database with a specific adapter
    21  func newUpdateDataset(d string, queryFactory exec.QueryFactory) *UpdateDataset {
    22  	return &UpdateDataset{
    23  		clauses:      exp.NewUpdateClauses(),
    24  		dialect:      GetDialect(d),
    25  		queryFactory: queryFactory,
    26  	}
    27  }
    28  
    29  func Update(table interface{}) *UpdateDataset {
    30  	return newUpdateDataset("default", nil).Table(table)
    31  }
    32  
    33  // Set the parameter interpolation behavior. See examples
    34  //
    35  // prepared: If true the dataset WILL NOT interpolate the parameters.
    36  func (ud *UpdateDataset) Prepared(prepared bool) *UpdateDataset {
    37  	ret := ud.copy(ud.clauses)
    38  	ret.isPrepared = preparedFromBool(prepared)
    39  	return ret
    40  }
    41  
    42  func (ud *UpdateDataset) IsPrepared() bool {
    43  	return ud.isPrepared.Bool()
    44  }
    45  
    46  // Sets the adapter used to serialize values and create the SQL statement
    47  func (ud *UpdateDataset) WithDialect(dl string) *UpdateDataset {
    48  	ds := ud.copy(ud.GetClauses())
    49  	ds.dialect = GetDialect(dl)
    50  	return ds
    51  }
    52  
    53  // Returns the current adapter on the dataset
    54  func (ud *UpdateDataset) Dialect() SQLDialect {
    55  	return ud.dialect
    56  }
    57  
    58  // Returns the current adapter on the dataset
    59  func (ud *UpdateDataset) SetDialect(dialect SQLDialect) *UpdateDataset {
    60  	cd := ud.copy(ud.GetClauses())
    61  	cd.dialect = dialect
    62  	return cd
    63  }
    64  
    65  func (ud *UpdateDataset) Expression() exp.Expression {
    66  	return ud
    67  }
    68  
    69  // Clones the dataset
    70  func (ud *UpdateDataset) Clone() exp.Expression {
    71  	return ud.copy(ud.clauses)
    72  }
    73  
    74  // Returns the current clauses on the dataset.
    75  func (ud *UpdateDataset) GetClauses() exp.UpdateClauses {
    76  	return ud.clauses
    77  }
    78  
    79  // used internally to copy the dataset
    80  func (ud *UpdateDataset) copy(clauses exp.UpdateClauses) *UpdateDataset {
    81  	return &UpdateDataset{
    82  		dialect:      ud.dialect,
    83  		clauses:      clauses,
    84  		isPrepared:   ud.isPrepared,
    85  		queryFactory: ud.queryFactory,
    86  		err:          ud.err,
    87  	}
    88  }
    89  
    90  // Creates a WITH clause for a common table expression (CTE).
    91  //
    92  // The name will be available to use in the UPDATE from in the associated query; and can optionally
    93  // contain a list of column names "name(col1, col2, col3)".
    94  //
    95  // The name will refer to the results of the specified subquery.
    96  func (ud *UpdateDataset) With(name string, subquery exp.Expression) *UpdateDataset {
    97  	return ud.copy(ud.clauses.CommonTablesAppend(exp.NewCommonTableExpression(false, name, subquery)))
    98  }
    99  
   100  // Creates a WITH RECURSIVE clause for a common table expression (CTE)
   101  //
   102  // The name will be available to use in the UPDATE from in the associated query; and must
   103  // contain a list of column names "name(col1, col2, col3)" for a recursive clause.
   104  //
   105  // The name will refer to the results of the specified subquery. The subquery for
   106  // a recursive query will always end with a UNION or UNION ALL with a clause that
   107  // refers to the CTE by name.
   108  func (ud *UpdateDataset) WithRecursive(name string, subquery exp.Expression) *UpdateDataset {
   109  	return ud.copy(ud.clauses.CommonTablesAppend(exp.NewCommonTableExpression(true, name, subquery)))
   110  }
   111  
   112  // Sets the table to update.
   113  func (ud *UpdateDataset) Table(table interface{}) *UpdateDataset {
   114  	switch t := table.(type) {
   115  	case exp.Expression:
   116  		return ud.copy(ud.clauses.SetTable(t))
   117  	case string:
   118  		return ud.copy(ud.clauses.SetTable(exp.ParseIdentifier(t)))
   119  	default:
   120  		panic(ErrUnsupportedUpdateTableType)
   121  	}
   122  }
   123  
   124  // Sets the values to use in the SET clause. See examples.
   125  func (ud *UpdateDataset) Set(values interface{}) *UpdateDataset {
   126  	return ud.copy(ud.clauses.SetSetValues(values))
   127  }
   128  
   129  // Allows specifying other tables to reference in your update (If your dialect supports it). See examples.
   130  func (ud *UpdateDataset) From(tables ...interface{}) *UpdateDataset {
   131  	return ud.copy(ud.clauses.SetFrom(exp.NewColumnListExpression(tables...)))
   132  }
   133  
   134  // Adds a WHERE clause. See examples.
   135  func (ud *UpdateDataset) Where(expressions ...exp.Expression) *UpdateDataset {
   136  	return ud.copy(ud.clauses.WhereAppend(expressions...))
   137  }
   138  
   139  // Removes the WHERE clause. See examples.
   140  func (ud *UpdateDataset) ClearWhere() *UpdateDataset {
   141  	return ud.copy(ud.clauses.ClearWhere())
   142  }
   143  
   144  // Adds a ORDER clause. If the ORDER is currently set it replaces it. See examples.
   145  func (ud *UpdateDataset) Order(order ...exp.OrderedExpression) *UpdateDataset {
   146  	return ud.copy(ud.clauses.SetOrder(order...))
   147  }
   148  
   149  // Adds a more columns to the current ORDER BY clause. If no order has be previously specified it is the same as
   150  // calling Order. See examples.
   151  func (ud *UpdateDataset) OrderAppend(order ...exp.OrderedExpression) *UpdateDataset {
   152  	return ud.copy(ud.clauses.OrderAppend(order...))
   153  }
   154  
   155  // Adds a more columns to the beginning of the current ORDER BY clause. If no order has be previously specified it is the same as
   156  // calling Order. See examples.
   157  func (ud *UpdateDataset) OrderPrepend(order ...exp.OrderedExpression) *UpdateDataset {
   158  	return ud.copy(ud.clauses.OrderPrepend(order...))
   159  }
   160  
   161  // Removes the ORDER BY clause. See examples.
   162  func (ud *UpdateDataset) ClearOrder() *UpdateDataset {
   163  	return ud.copy(ud.clauses.ClearOrder())
   164  }
   165  
   166  // Adds a LIMIT clause. If the LIMIT is currently set it replaces it. See examples.
   167  func (ud *UpdateDataset) Limit(limit uint) *UpdateDataset {
   168  	if limit > 0 {
   169  		return ud.copy(ud.clauses.SetLimit(limit))
   170  	}
   171  	return ud.copy(ud.clauses.ClearLimit())
   172  }
   173  
   174  // Adds a LIMIT ALL clause. If the LIMIT is currently set it replaces it. See examples.
   175  func (ud *UpdateDataset) LimitAll() *UpdateDataset {
   176  	return ud.copy(ud.clauses.SetLimit(L("ALL")))
   177  }
   178  
   179  // Removes the LIMIT clause.
   180  func (ud *UpdateDataset) ClearLimit() *UpdateDataset {
   181  	return ud.copy(ud.clauses.ClearLimit())
   182  }
   183  
   184  // Adds a RETURNING clause to the dataset if the adapter supports it. See examples.
   185  func (ud *UpdateDataset) Returning(returning ...interface{}) *UpdateDataset {
   186  	return ud.copy(ud.clauses.SetReturning(exp.NewColumnListExpression(returning...)))
   187  }
   188  
   189  // Get any error that has been set or nil if no error has been set.
   190  func (ud *UpdateDataset) Error() error {
   191  	return ud.err
   192  }
   193  
   194  // Set an error on the dataset if one has not already been set. This error will be returned by a future call to Error
   195  // or as part of ToSQL. This can be used by end users to record errors while building up queries without having to
   196  // track those separately.
   197  func (ud *UpdateDataset) SetError(err error) *UpdateDataset {
   198  	if ud.err == nil {
   199  		ud.err = err
   200  	}
   201  
   202  	return ud
   203  }
   204  
   205  // Generates an UPDATE sql statement, if Prepared has been called with true then the parameters will not be interpolated.
   206  // See examples.
   207  //
   208  // Errors:
   209  //  * There is an error generating the SQL
   210  func (ud *UpdateDataset) ToSQL() (sql string, params []interface{}, err error) {
   211  	return ud.updateSQLBuilder().ToSQL()
   212  }
   213  
   214  // Appends this Dataset's UPDATE statement to the SQLBuilder
   215  // This is used internally when using updates in CTEs
   216  func (ud *UpdateDataset) AppendSQL(b sb.SQLBuilder) {
   217  	if ud.err != nil {
   218  		b.SetError(ud.err)
   219  		return
   220  	}
   221  	ud.dialect.ToUpdateSQL(b, ud.GetClauses())
   222  }
   223  
   224  func (ud *UpdateDataset) GetAs() exp.IdentifierExpression {
   225  	return nil
   226  }
   227  
   228  func (ud *UpdateDataset) ReturnsColumns() bool {
   229  	return ud.clauses.HasReturning()
   230  }
   231  
   232  // Generates the UPDATE sql, and returns an exec.QueryExecutor with the sql set to the UPDATE statement
   233  //    db.Update("test").Set(Record{"name":"Bob", update: time.Now()}).Executor()
   234  func (ud *UpdateDataset) Executor() exec.QueryExecutor {
   235  	return ud.queryFactory.FromSQLBuilder(ud.updateSQLBuilder())
   236  }
   237  
   238  func (ud *UpdateDataset) updateSQLBuilder() sb.SQLBuilder {
   239  	buf := sb.NewSQLBuilder(ud.isPrepared.Bool())
   240  	if ud.err != nil {
   241  		return buf.SetError(ud.err)
   242  	}
   243  	ud.dialect.ToUpdateSQL(buf, ud.clauses)
   244  	return buf
   245  }
   246  

View as plain text