|
| 1 | +package sqlz |
| 2 | + |
| 3 | +import ( |
| 4 | + "database/sql" |
| 5 | + "fmt" |
| 6 | + "strings" |
| 7 | + "time" |
| 8 | + |
| 9 | + "github.com/jmoiron/sqlx" |
| 10 | +) |
| 11 | + |
| 12 | +// SetCmd represents a PostgreSQL SET command |
| 13 | +type SetCmd struct { |
| 14 | + *Statement |
| 15 | + level string |
| 16 | + configParam string |
| 17 | + value string |
| 18 | + execer Ext |
| 19 | +} |
| 20 | + |
| 21 | +// Set creates a new SetCmd object, with configuration parameter |
| 22 | +// and its value. |
| 23 | +func (db *DB) Set(configParam, value string) *SetCmd { |
| 24 | + return &SetCmd{ |
| 25 | + configParam: configParam, |
| 26 | + value: value, |
| 27 | + execer: db.DB, |
| 28 | + Statement: &Statement{db.ErrHandlers}, |
| 29 | + } |
| 30 | +} |
| 31 | + |
| 32 | +// Set creates a new SetCmd object, with configuration parameter |
| 33 | +// and its value. |
| 34 | +func (tx *Tx) Set(configParam, value string) *SetCmd { |
| 35 | + return &SetCmd{ |
| 36 | + configParam: configParam, |
| 37 | + value: value, |
| 38 | + execer: tx.Tx, |
| 39 | + Statement: &Statement{tx.ErrHandlers}, |
| 40 | + } |
| 41 | +} |
| 42 | + |
| 43 | +// SetTimeout sets a statement timeout. When set, any statement |
| 44 | +// (in the transaction) that takes more than the specified duration |
| 45 | +// will be aborted, starting from the time the command arrives |
| 46 | +// at the server from the client. A value of zero turns this off. |
| 47 | +func (tx *Tx) SetTimeout(d time.Duration) (res sql.Result, err error) { |
| 48 | + stmt := &SetCmd{ |
| 49 | + configParam: "statement_timeout", |
| 50 | + value: fmt.Sprintf("\"%dms\"", d.Milliseconds()), |
| 51 | + execer: tx.Tx, |
| 52 | + Statement: &Statement{tx.ErrHandlers}, |
| 53 | + } |
| 54 | + |
| 55 | + return stmt.Local().Exec() |
| 56 | +} |
| 57 | + |
| 58 | +// Local sets the configuration parameter locally in a transaction. |
| 59 | +// The effect of SET LOCAL will last only till the end of the |
| 60 | +// current transaction, whether committed or not. |
| 61 | +func (cmd *SetCmd) Local() *SetCmd { |
| 62 | + cmd.level = "LOCAL" |
| 63 | + return cmd |
| 64 | +} |
| 65 | + |
| 66 | +// Session sets the configuration parameter to the entire session. |
| 67 | +// The effect of SET SESSION will last only till the end of the |
| 68 | +// current session. if issued within a transaction that is later aborted, |
| 69 | +// the effects of the SET command disappear when the transaction is rolled |
| 70 | +// back. Once the surrounding transaction is committed, the effects will persist |
| 71 | +// until the end of the session, unless overridden by another SET. |
| 72 | +func (cmd *SetCmd) Session() *SetCmd { |
| 73 | + cmd.level = "SESSION" |
| 74 | + return cmd |
| 75 | +} |
| 76 | + |
| 77 | +// ToSQL generates the SET command SQL and returns a list of |
| 78 | +// bindings. It is used internally by Exec, but is exported if you |
| 79 | +// wish to use it directly. |
| 80 | +func (cmd *SetCmd) ToSQL(rebind bool) (string, []interface{}) { |
| 81 | + clauses := []string{"SET"} |
| 82 | + if cmd.level != "" { |
| 83 | + clauses = append(clauses, cmd.level) |
| 84 | + } |
| 85 | + |
| 86 | + clauses = append(clauses, cmd.configParam, "TO", cmd.value) |
| 87 | + |
| 88 | + asSQL := strings.Join(clauses, " ") |
| 89 | + |
| 90 | + if rebind { |
| 91 | + if db, ok := cmd.execer.(*sqlx.DB); ok { |
| 92 | + asSQL = db.Rebind(asSQL) |
| 93 | + } else if tx, ok := cmd.execer.(*sqlx.Tx); ok { |
| 94 | + asSQL = tx.Rebind(asSQL) |
| 95 | + } |
| 96 | + } |
| 97 | + |
| 98 | + return asSQL, []interface{}{} |
| 99 | +} |
| 100 | + |
| 101 | +// Exec executes the SET command, returning the standard |
| 102 | +// sql.Result struct and an error if the query failed. |
| 103 | +func (cmd *SetCmd) Exec() (res sql.Result, err error) { |
| 104 | + asSQL, bindings := cmd.ToSQL(true) |
| 105 | + res, err = cmd.execer.Exec(asSQL, bindings...) |
| 106 | + cmd.Statement.HandleError(err) |
| 107 | + |
| 108 | + return res, err |
| 109 | +} |
0 commit comments