http urls monitor.

update.go 5.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. package sqlbuilder
  2. import (
  3. "context"
  4. "database/sql"
  5. "upper.io/db.v3/internal/immutable"
  6. "upper.io/db.v3/internal/sqladapter/exql"
  7. )
  8. type updaterQuery struct {
  9. table string
  10. columnValues *exql.ColumnValues
  11. columnValuesArgs []interface{}
  12. limit int
  13. where *exql.Where
  14. whereArgs []interface{}
  15. err error
  16. amendFn func(string) string
  17. }
  18. func (uq *updaterQuery) and(b *sqlBuilder, terms ...interface{}) error {
  19. where, whereArgs := b.t.toWhereWithArguments(terms)
  20. if uq.where == nil {
  21. uq.where, uq.whereArgs = &exql.Where{}, []interface{}{}
  22. }
  23. uq.where.Append(&where)
  24. uq.whereArgs = append(uq.whereArgs, whereArgs...)
  25. return nil
  26. }
  27. func (uq *updaterQuery) statement() *exql.Statement {
  28. stmt := &exql.Statement{
  29. Type: exql.Update,
  30. Table: exql.TableWithName(uq.table),
  31. ColumnValues: uq.columnValues,
  32. }
  33. if uq.where != nil {
  34. stmt.Where = uq.where
  35. }
  36. if uq.limit != 0 {
  37. stmt.Limit = exql.Limit(uq.limit)
  38. }
  39. stmt.SetAmendment(uq.amendFn)
  40. return stmt
  41. }
  42. func (uq *updaterQuery) arguments() []interface{} {
  43. return joinArguments(
  44. uq.columnValuesArgs,
  45. uq.whereArgs,
  46. )
  47. }
  48. type updater struct {
  49. builder *sqlBuilder
  50. fn func(*updaterQuery) error
  51. prev *updater
  52. }
  53. var _ = immutable.Immutable(&updater{})
  54. func (upd *updater) SQLBuilder() *sqlBuilder {
  55. if upd.prev == nil {
  56. return upd.builder
  57. }
  58. return upd.prev.SQLBuilder()
  59. }
  60. func (upd *updater) template() *exql.Template {
  61. return upd.SQLBuilder().t.Template
  62. }
  63. func (upd *updater) String() string {
  64. s, err := upd.Compile()
  65. if err != nil {
  66. panic(err.Error())
  67. }
  68. return prepareQueryForDisplay(s)
  69. }
  70. func (upd *updater) setTable(table string) *updater {
  71. return upd.frame(func(uq *updaterQuery) error {
  72. uq.table = table
  73. return nil
  74. })
  75. }
  76. func (upd *updater) frame(fn func(*updaterQuery) error) *updater {
  77. return &updater{prev: upd, fn: fn}
  78. }
  79. func (upd *updater) Set(terms ...interface{}) Updater {
  80. return upd.frame(func(uq *updaterQuery) error {
  81. if uq.columnValues == nil {
  82. uq.columnValues = &exql.ColumnValues{}
  83. }
  84. if len(terms) == 1 {
  85. ff, vv, err := Map(terms[0], nil)
  86. if err == nil && len(ff) > 0 {
  87. cvs := make([]exql.Fragment, 0, len(ff))
  88. args := make([]interface{}, 0, len(vv))
  89. for i := range ff {
  90. cv := &exql.ColumnValue{
  91. Column: exql.ColumnWithName(ff[i]),
  92. Operator: upd.SQLBuilder().t.AssignmentOperator,
  93. }
  94. var localArgs []interface{}
  95. cv.Value, localArgs = upd.SQLBuilder().t.PlaceholderValue(vv[i])
  96. args = append(args, localArgs...)
  97. cvs = append(cvs, cv)
  98. }
  99. uq.columnValues.Insert(cvs...)
  100. uq.columnValuesArgs = append(uq.columnValuesArgs, args...)
  101. return nil
  102. }
  103. }
  104. cv, arguments := upd.SQLBuilder().t.setColumnValues(terms)
  105. uq.columnValues.Insert(cv.ColumnValues...)
  106. uq.columnValuesArgs = append(uq.columnValuesArgs, arguments...)
  107. return nil
  108. })
  109. }
  110. func (upd *updater) Amend(fn func(string) string) Updater {
  111. return upd.frame(func(uq *updaterQuery) error {
  112. uq.amendFn = fn
  113. return nil
  114. })
  115. }
  116. func (upd *updater) Arguments() []interface{} {
  117. uq, err := upd.build()
  118. if err != nil {
  119. return nil
  120. }
  121. return uq.arguments()
  122. }
  123. func (upd *updater) Where(terms ...interface{}) Updater {
  124. return upd.frame(func(uq *updaterQuery) error {
  125. uq.where, uq.whereArgs = &exql.Where{}, []interface{}{}
  126. return uq.and(upd.SQLBuilder(), terms...)
  127. })
  128. }
  129. func (upd *updater) And(terms ...interface{}) Updater {
  130. return upd.frame(func(uq *updaterQuery) error {
  131. return uq.and(upd.SQLBuilder(), terms...)
  132. })
  133. }
  134. func (upd *updater) Prepare() (*sql.Stmt, error) {
  135. return upd.PrepareContext(upd.SQLBuilder().sess.Context())
  136. }
  137. func (upd *updater) PrepareContext(ctx context.Context) (*sql.Stmt, error) {
  138. uq, err := upd.build()
  139. if err != nil {
  140. return nil, err
  141. }
  142. return upd.SQLBuilder().sess.StatementPrepare(ctx, uq.statement())
  143. }
  144. func (upd *updater) Exec() (sql.Result, error) {
  145. return upd.ExecContext(upd.SQLBuilder().sess.Context())
  146. }
  147. func (upd *updater) ExecContext(ctx context.Context) (sql.Result, error) {
  148. uq, err := upd.build()
  149. if err != nil {
  150. return nil, err
  151. }
  152. return upd.SQLBuilder().sess.StatementExec(ctx, uq.statement(), uq.arguments()...)
  153. }
  154. func (upd *updater) Limit(limit int) Updater {
  155. return upd.frame(func(uq *updaterQuery) error {
  156. uq.limit = limit
  157. return nil
  158. })
  159. }
  160. func (upd *updater) statement() (*exql.Statement, error) {
  161. iq, err := upd.build()
  162. if err != nil {
  163. return nil, err
  164. }
  165. return iq.statement(), nil
  166. }
  167. func (upd *updater) build() (*updaterQuery, error) {
  168. uq, err := immutable.FastForward(upd)
  169. if err != nil {
  170. return nil, err
  171. }
  172. return uq.(*updaterQuery), nil
  173. }
  174. func (upd *updater) Compile() (string, error) {
  175. s, err := upd.statement()
  176. if err != nil {
  177. return "", err
  178. }
  179. return s.Compile(upd.template())
  180. }
  181. func (upd *updater) Prev() immutable.Immutable {
  182. if upd == nil {
  183. return nil
  184. }
  185. return upd.prev
  186. }
  187. func (upd *updater) Fn(in interface{}) error {
  188. if upd.fn == nil {
  189. return nil
  190. }
  191. return upd.fn(in.(*updaterQuery))
  192. }
  193. func (upd *updater) Base() interface{} {
  194. return &updaterQuery{}
  195. }