http urls monitor.

select.go 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526
  1. package sqlbuilder
  2. import (
  3. "context"
  4. "database/sql"
  5. "errors"
  6. "fmt"
  7. "strings"
  8. "upper.io/db.v3"
  9. "upper.io/db.v3/internal/immutable"
  10. "upper.io/db.v3/internal/sqladapter/exql"
  11. )
  12. type selectorQuery struct {
  13. table *exql.Columns
  14. tableArgs []interface{}
  15. as string
  16. distinct bool
  17. where *exql.Where
  18. whereArgs []interface{}
  19. groupBy *exql.GroupBy
  20. groupByArgs []interface{}
  21. orderBy *exql.OrderBy
  22. orderByArgs []interface{}
  23. limit exql.Limit
  24. offset exql.Offset
  25. columns *exql.Columns
  26. columnsArgs []interface{}
  27. joins []*exql.Join
  28. joinsArgs []interface{}
  29. amendFn func(string) string
  30. }
  31. func (sq *selectorQuery) and(b *sqlBuilder, terms ...interface{}) error {
  32. where, whereArgs := b.t.toWhereWithArguments(terms)
  33. if sq.where == nil {
  34. sq.where, sq.whereArgs = &exql.Where{}, []interface{}{}
  35. }
  36. sq.where.Append(&where)
  37. sq.whereArgs = append(sq.whereArgs, whereArgs...)
  38. return nil
  39. }
  40. func (sq *selectorQuery) arguments() []interface{} {
  41. return joinArguments(
  42. sq.columnsArgs,
  43. sq.tableArgs,
  44. sq.joinsArgs,
  45. sq.whereArgs,
  46. sq.groupByArgs,
  47. sq.orderByArgs,
  48. )
  49. }
  50. func (sq *selectorQuery) statement() *exql.Statement {
  51. stmt := &exql.Statement{
  52. Type: exql.Select,
  53. Table: sq.table,
  54. Columns: sq.columns,
  55. Distinct: sq.distinct,
  56. Limit: sq.limit,
  57. Offset: sq.offset,
  58. Where: sq.where,
  59. OrderBy: sq.orderBy,
  60. GroupBy: sq.groupBy,
  61. }
  62. if len(sq.joins) > 0 {
  63. stmt.Joins = exql.JoinConditions(sq.joins...)
  64. }
  65. stmt.SetAmendment(sq.amendFn)
  66. return stmt
  67. }
  68. func (sq *selectorQuery) pushJoin(t string, tables []interface{}) error {
  69. fragments, args, err := columnFragments(tables)
  70. if err != nil {
  71. return err
  72. }
  73. if sq.joins == nil {
  74. sq.joins = []*exql.Join{}
  75. }
  76. sq.joins = append(sq.joins,
  77. &exql.Join{
  78. Type: t,
  79. Table: exql.JoinColumns(fragments...),
  80. },
  81. )
  82. sq.joinsArgs = append(sq.joinsArgs, args...)
  83. return nil
  84. }
  85. type selector struct {
  86. builder *sqlBuilder
  87. fn func(*selectorQuery) error
  88. prev *selector
  89. }
  90. var _ = immutable.Immutable(&selector{})
  91. func (sel *selector) SQLBuilder() *sqlBuilder {
  92. if sel.prev == nil {
  93. return sel.builder
  94. }
  95. return sel.prev.SQLBuilder()
  96. }
  97. func (sel *selector) String() string {
  98. s, err := sel.Compile()
  99. if err != nil {
  100. panic(err.Error())
  101. }
  102. return prepareQueryForDisplay(s)
  103. }
  104. func (sel *selector) frame(fn func(*selectorQuery) error) *selector {
  105. return &selector{prev: sel, fn: fn}
  106. }
  107. func (sel *selector) clone() Selector {
  108. return sel.frame(func(*selectorQuery) error {
  109. return nil
  110. })
  111. }
  112. func (sel *selector) From(tables ...interface{}) Selector {
  113. return sel.frame(
  114. func(sq *selectorQuery) error {
  115. fragments, args, err := columnFragments(tables)
  116. if err != nil {
  117. return err
  118. }
  119. sq.table = exql.JoinColumns(fragments...)
  120. sq.tableArgs = args
  121. return nil
  122. },
  123. )
  124. }
  125. func (sel *selector) setColumns(columns ...interface{}) Selector {
  126. return sel.frame(func(sq *selectorQuery) error {
  127. sq.columns = nil
  128. return sq.pushColumns(columns...)
  129. })
  130. }
  131. func (sel *selector) Columns(columns ...interface{}) Selector {
  132. return sel.frame(func(sq *selectorQuery) error {
  133. return sq.pushColumns(columns...)
  134. })
  135. }
  136. func (sq *selectorQuery) pushColumns(columns ...interface{}) error {
  137. f, args, err := columnFragments(columns)
  138. if err != nil {
  139. return err
  140. }
  141. c := exql.JoinColumns(f...)
  142. if sq.columns != nil {
  143. sq.columns.Append(c)
  144. } else {
  145. sq.columns = c
  146. }
  147. sq.columnsArgs = append(sq.columnsArgs, args...)
  148. return nil
  149. }
  150. func (sel *selector) Distinct(exps ...interface{}) Selector {
  151. return sel.frame(func(sq *selectorQuery) error {
  152. sq.distinct = true
  153. return sq.pushColumns(exps...)
  154. })
  155. }
  156. func (sel *selector) Where(terms ...interface{}) Selector {
  157. return sel.frame(func(sq *selectorQuery) error {
  158. if len(terms) == 1 && terms[0] == nil {
  159. sq.where, sq.whereArgs = &exql.Where{}, []interface{}{}
  160. return nil
  161. }
  162. return sq.and(sel.SQLBuilder(), terms...)
  163. })
  164. }
  165. func (sel *selector) And(terms ...interface{}) Selector {
  166. return sel.frame(func(sq *selectorQuery) error {
  167. return sq.and(sel.SQLBuilder(), terms...)
  168. })
  169. }
  170. func (sel *selector) Amend(fn func(string) string) Selector {
  171. return sel.frame(func(sq *selectorQuery) error {
  172. sq.amendFn = fn
  173. return nil
  174. })
  175. }
  176. func (sel *selector) Arguments() []interface{} {
  177. sq, err := sel.build()
  178. if err != nil {
  179. return nil
  180. }
  181. return sq.arguments()
  182. }
  183. func (sel *selector) GroupBy(columns ...interface{}) Selector {
  184. return sel.frame(func(sq *selectorQuery) error {
  185. fragments, args, err := columnFragments(columns)
  186. if err != nil {
  187. return err
  188. }
  189. if fragments != nil {
  190. sq.groupBy = exql.GroupByColumns(fragments...)
  191. }
  192. sq.groupByArgs = args
  193. return nil
  194. })
  195. }
  196. func (sel *selector) OrderBy(columns ...interface{}) Selector {
  197. return sel.frame(func(sq *selectorQuery) error {
  198. if len(columns) == 1 && columns[0] == nil {
  199. sq.orderBy = nil
  200. sq.orderByArgs = nil
  201. return nil
  202. }
  203. var sortColumns exql.SortColumns
  204. for i := range columns {
  205. var sort *exql.SortColumn
  206. switch value := columns[i].(type) {
  207. case db.RawValue:
  208. query, args := Preprocess(value.Raw(), value.Arguments())
  209. sort = &exql.SortColumn{
  210. Column: exql.RawValue(query),
  211. }
  212. sq.orderByArgs = append(sq.orderByArgs, args...)
  213. case db.Function:
  214. fnName, fnArgs := value.Name(), value.Arguments()
  215. if len(fnArgs) == 0 {
  216. fnName = fnName + "()"
  217. } else {
  218. fnName = fnName + "(?" + strings.Repeat("?, ", len(fnArgs)-1) + ")"
  219. }
  220. fnName, fnArgs = Preprocess(fnName, fnArgs)
  221. sort = &exql.SortColumn{
  222. Column: exql.RawValue(fnName),
  223. }
  224. sq.orderByArgs = append(sq.orderByArgs, fnArgs...)
  225. case string:
  226. if strings.HasPrefix(value, "-") {
  227. sort = &exql.SortColumn{
  228. Column: exql.ColumnWithName(value[1:]),
  229. Order: exql.Descendent,
  230. }
  231. } else {
  232. chunks := strings.SplitN(value, " ", 2)
  233. order := exql.Ascendent
  234. if len(chunks) > 1 && strings.ToUpper(chunks[1]) == "DESC" {
  235. order = exql.Descendent
  236. }
  237. sort = &exql.SortColumn{
  238. Column: exql.ColumnWithName(chunks[0]),
  239. Order: order,
  240. }
  241. }
  242. default:
  243. return fmt.Errorf("Can't sort by type %T", value)
  244. }
  245. sortColumns.Columns = append(sortColumns.Columns, sort)
  246. }
  247. sq.orderBy = &exql.OrderBy{
  248. SortColumns: &sortColumns,
  249. }
  250. return nil
  251. })
  252. }
  253. func (sel *selector) Using(columns ...interface{}) Selector {
  254. return sel.frame(func(sq *selectorQuery) error {
  255. joins := len(sq.joins)
  256. if joins == 0 {
  257. return errors.New(`cannot use Using() without a preceding Join() expression`)
  258. }
  259. lastJoin := sq.joins[joins-1]
  260. if lastJoin.On != nil {
  261. return errors.New(`cannot use Using() and On() with the same Join() expression`)
  262. }
  263. fragments, args, err := columnFragments(columns)
  264. if err != nil {
  265. return err
  266. }
  267. sq.joinsArgs = append(sq.joinsArgs, args...)
  268. lastJoin.Using = exql.UsingColumns(fragments...)
  269. return nil
  270. })
  271. }
  272. func (sel *selector) FullJoin(tables ...interface{}) Selector {
  273. return sel.frame(func(sq *selectorQuery) error {
  274. return sq.pushJoin("FULL", tables)
  275. })
  276. }
  277. func (sel *selector) CrossJoin(tables ...interface{}) Selector {
  278. return sel.frame(func(sq *selectorQuery) error {
  279. return sq.pushJoin("CROSS", tables)
  280. })
  281. }
  282. func (sel *selector) RightJoin(tables ...interface{}) Selector {
  283. return sel.frame(func(sq *selectorQuery) error {
  284. return sq.pushJoin("RIGHT", tables)
  285. })
  286. }
  287. func (sel *selector) LeftJoin(tables ...interface{}) Selector {
  288. return sel.frame(func(sq *selectorQuery) error {
  289. return sq.pushJoin("LEFT", tables)
  290. })
  291. }
  292. func (sel *selector) Join(tables ...interface{}) Selector {
  293. return sel.frame(func(sq *selectorQuery) error {
  294. return sq.pushJoin("", tables)
  295. })
  296. }
  297. func (sel *selector) On(terms ...interface{}) Selector {
  298. return sel.frame(func(sq *selectorQuery) error {
  299. joins := len(sq.joins)
  300. if joins == 0 {
  301. return errors.New(`cannot use On() without a preceding Join() expression`)
  302. }
  303. lastJoin := sq.joins[joins-1]
  304. if lastJoin.On != nil {
  305. return errors.New(`cannot use Using() and On() with the same Join() expression`)
  306. }
  307. w, a := sel.SQLBuilder().t.toWhereWithArguments(terms)
  308. o := exql.On(w)
  309. lastJoin.On = &o
  310. sq.joinsArgs = append(sq.joinsArgs, a...)
  311. return nil
  312. })
  313. }
  314. func (sel *selector) Limit(n int) Selector {
  315. return sel.frame(func(sq *selectorQuery) error {
  316. if n < 0 {
  317. n = 0
  318. }
  319. sq.limit = exql.Limit(n)
  320. return nil
  321. })
  322. }
  323. func (sel *selector) Offset(n int) Selector {
  324. return sel.frame(func(sq *selectorQuery) error {
  325. if n < 0 {
  326. n = 0
  327. }
  328. sq.offset = exql.Offset(n)
  329. return nil
  330. })
  331. }
  332. func (sel *selector) template() *exql.Template {
  333. return sel.SQLBuilder().t.Template
  334. }
  335. func (sel *selector) As(alias string) Selector {
  336. return sel.frame(func(sq *selectorQuery) error {
  337. if sq.table == nil {
  338. return errors.New("Cannot use As() without a preceding From() expression")
  339. }
  340. last := len(sq.table.Columns) - 1
  341. if raw, ok := sq.table.Columns[last].(*exql.Raw); ok {
  342. compiled, err := exql.ColumnWithName(alias).Compile(sel.template())
  343. if err != nil {
  344. return err
  345. }
  346. sq.table.Columns[last] = exql.RawValue(raw.Value + " AS " + compiled)
  347. }
  348. return nil
  349. })
  350. }
  351. func (sel *selector) statement() *exql.Statement {
  352. sq, _ := sel.build()
  353. return sq.statement()
  354. }
  355. func (sel *selector) QueryRow() (*sql.Row, error) {
  356. return sel.QueryRowContext(sel.SQLBuilder().sess.Context())
  357. }
  358. func (sel *selector) QueryRowContext(ctx context.Context) (*sql.Row, error) {
  359. sq, err := sel.build()
  360. if err != nil {
  361. return nil, err
  362. }
  363. return sel.SQLBuilder().sess.StatementQueryRow(ctx, sq.statement(), sq.arguments()...)
  364. }
  365. func (sel *selector) Prepare() (*sql.Stmt, error) {
  366. return sel.PrepareContext(sel.SQLBuilder().sess.Context())
  367. }
  368. func (sel *selector) PrepareContext(ctx context.Context) (*sql.Stmt, error) {
  369. sq, err := sel.build()
  370. if err != nil {
  371. return nil, err
  372. }
  373. return sel.SQLBuilder().sess.StatementPrepare(ctx, sq.statement())
  374. }
  375. func (sel *selector) Query() (*sql.Rows, error) {
  376. return sel.QueryContext(sel.SQLBuilder().sess.Context())
  377. }
  378. func (sel *selector) QueryContext(ctx context.Context) (*sql.Rows, error) {
  379. sq, err := sel.build()
  380. if err != nil {
  381. return nil, err
  382. }
  383. return sel.SQLBuilder().sess.StatementQuery(ctx, sq.statement(), sq.arguments()...)
  384. }
  385. func (sel *selector) Iterator() Iterator {
  386. return sel.IteratorContext(sel.SQLBuilder().sess.Context())
  387. }
  388. func (sel *selector) IteratorContext(ctx context.Context) Iterator {
  389. sess := sel.SQLBuilder().sess
  390. sq, err := sel.build()
  391. if err != nil {
  392. return &iterator{sess, nil, err}
  393. }
  394. rows, err := sess.StatementQuery(ctx, sq.statement(), sq.arguments()...)
  395. return &iterator{sess, rows, err}
  396. }
  397. func (sel *selector) Paginate(pageSize uint) Paginator {
  398. return newPaginator(sel.clone(), pageSize)
  399. }
  400. func (sel *selector) All(destSlice interface{}) error {
  401. return sel.Iterator().All(destSlice)
  402. }
  403. func (sel *selector) One(dest interface{}) error {
  404. return sel.Iterator().One(dest)
  405. }
  406. func (sel *selector) build() (*selectorQuery, error) {
  407. sq, err := immutable.FastForward(sel)
  408. if err != nil {
  409. return nil, err
  410. }
  411. return sq.(*selectorQuery), nil
  412. }
  413. func (sel *selector) Compile() (string, error) {
  414. return sel.statement().Compile(sel.template())
  415. }
  416. func (sel *selector) Prev() immutable.Immutable {
  417. if sel == nil {
  418. return nil
  419. }
  420. return sel.prev
  421. }
  422. func (sel *selector) Fn(in interface{}) error {
  423. if sel.fn == nil {
  424. return nil
  425. }
  426. return sel.fn(in.(*selectorQuery))
  427. }
  428. func (sel *selector) Base() interface{} {
  429. return &selectorQuery{}
  430. }