statement.go 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284
  1. // Copyright 2015 The Xorm Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package xorm
  5. import (
  6. "bytes"
  7. "database/sql/driver"
  8. "encoding/json"
  9. "errors"
  10. "fmt"
  11. "reflect"
  12. "strings"
  13. "time"
  14. "github.com/go-xorm/builder"
  15. "github.com/xormplus/core"
  16. )
  17. type incrParam struct {
  18. colName string
  19. arg interface{}
  20. }
  21. type decrParam struct {
  22. colName string
  23. arg interface{}
  24. }
  25. type exprParam struct {
  26. colName string
  27. expr string
  28. }
  29. // Statement save all the sql info for executing SQL
  30. type Statement struct {
  31. RefTable *core.Table
  32. Engine *Engine
  33. Start int
  34. LimitN int
  35. idParam *core.PK
  36. OrderStr string
  37. JoinStr string
  38. joinArgs []interface{}
  39. GroupByStr string
  40. HavingStr string
  41. ColumnStr string
  42. selectStr string
  43. columnMap map[string]bool
  44. useAllCols bool
  45. OmitStr string
  46. AltTableName string
  47. tableName string
  48. RawSQL string
  49. RawParams []interface{}
  50. UseCascade bool
  51. UseAutoJoin bool
  52. StoreEngine string
  53. Charset string
  54. UseCache bool
  55. UseAutoTime bool
  56. noAutoCondition bool
  57. IsDistinct bool
  58. IsForUpdate bool
  59. TableAlias string
  60. allUseBool bool
  61. checkVersion bool
  62. unscoped bool
  63. mustColumnMap map[string]bool
  64. nullableMap map[string]bool
  65. incrColumns map[string]incrParam
  66. decrColumns map[string]decrParam
  67. exprColumns map[string]exprParam
  68. cond builder.Cond
  69. bufferSize int
  70. }
  71. // Init reset all the statement's fields
  72. func (statement *Statement) Init() {
  73. statement.RefTable = nil
  74. statement.Start = 0
  75. statement.LimitN = 0
  76. statement.OrderStr = ""
  77. statement.UseCascade = true
  78. statement.JoinStr = ""
  79. statement.joinArgs = make([]interface{}, 0)
  80. statement.GroupByStr = ""
  81. statement.HavingStr = ""
  82. statement.ColumnStr = ""
  83. statement.OmitStr = ""
  84. statement.columnMap = make(map[string]bool)
  85. statement.AltTableName = ""
  86. statement.tableName = ""
  87. statement.idParam = nil
  88. statement.RawSQL = ""
  89. statement.RawParams = make([]interface{}, 0)
  90. statement.UseCache = true
  91. statement.UseAutoTime = true
  92. statement.noAutoCondition = false
  93. statement.IsDistinct = false
  94. statement.IsForUpdate = false
  95. statement.TableAlias = ""
  96. statement.selectStr = ""
  97. statement.allUseBool = false
  98. statement.useAllCols = false
  99. statement.mustColumnMap = make(map[string]bool)
  100. statement.nullableMap = make(map[string]bool)
  101. statement.checkVersion = true
  102. statement.unscoped = false
  103. statement.incrColumns = make(map[string]incrParam)
  104. statement.decrColumns = make(map[string]decrParam)
  105. statement.exprColumns = make(map[string]exprParam)
  106. statement.cond = builder.NewCond()
  107. statement.bufferSize = 0
  108. }
  109. // NoAutoCondition if you do not want convert bean's field as query condition, then use this function
  110. func (statement *Statement) NoAutoCondition(no ...bool) *Statement {
  111. statement.noAutoCondition = true
  112. if len(no) > 0 {
  113. statement.noAutoCondition = no[0]
  114. }
  115. return statement
  116. }
  117. // Alias set the table alias
  118. func (statement *Statement) Alias(alias string) *Statement {
  119. statement.TableAlias = alias
  120. return statement
  121. }
  122. // SQL adds raw sql statement
  123. func (statement *Statement) SQL(query interface{}, args ...interface{}) *Statement {
  124. switch query.(type) {
  125. case (*builder.Builder):
  126. var err error
  127. statement.RawSQL, statement.RawParams, err = query.(*builder.Builder).ToSQL()
  128. if err != nil {
  129. statement.Engine.logger.Error(err)
  130. }
  131. case string:
  132. statement.RawSQL = query.(string)
  133. statement.RawParams = args
  134. default:
  135. statement.Engine.logger.Error("unsupported sql type")
  136. }
  137. return statement
  138. }
  139. // Where add Where statement
  140. func (statement *Statement) Where(query interface{}, args ...interface{}) *Statement {
  141. return statement.And(query, args...)
  142. }
  143. // And add Where & and statement
  144. func (statement *Statement) And(query interface{}, args ...interface{}) *Statement {
  145. switch query.(type) {
  146. case string:
  147. cond := builder.Expr(query.(string), args...)
  148. statement.cond = statement.cond.And(cond)
  149. case map[string]interface{}:
  150. cond := builder.Eq(query.(map[string]interface{}))
  151. statement.cond = statement.cond.And(cond)
  152. case builder.Cond:
  153. cond := query.(builder.Cond)
  154. statement.cond = statement.cond.And(cond)
  155. for _, v := range args {
  156. if vv, ok := v.(builder.Cond); ok {
  157. statement.cond = statement.cond.And(vv)
  158. }
  159. }
  160. default:
  161. // TODO: not support condition type
  162. }
  163. return statement
  164. }
  165. // Or add Where & Or statement
  166. func (statement *Statement) Or(query interface{}, args ...interface{}) *Statement {
  167. switch query.(type) {
  168. case string:
  169. cond := builder.Expr(query.(string), args...)
  170. statement.cond = statement.cond.Or(cond)
  171. case map[string]interface{}:
  172. cond := builder.Eq(query.(map[string]interface{}))
  173. statement.cond = statement.cond.Or(cond)
  174. case builder.Cond:
  175. cond := query.(builder.Cond)
  176. statement.cond = statement.cond.Or(cond)
  177. for _, v := range args {
  178. if vv, ok := v.(builder.Cond); ok {
  179. statement.cond = statement.cond.Or(vv)
  180. }
  181. }
  182. default:
  183. // TODO: not support condition type
  184. }
  185. return statement
  186. }
  187. // In generate "Where column IN (?) " statement
  188. func (statement *Statement) In(column string, args ...interface{}) *Statement {
  189. in := builder.In(statement.Engine.Quote(column), args...)
  190. statement.cond = statement.cond.And(in)
  191. return statement
  192. }
  193. // NotIn generate "Where column NOT IN (?) " statement
  194. func (statement *Statement) NotIn(column string, args ...interface{}) *Statement {
  195. notIn := builder.NotIn(statement.Engine.Quote(column), args...)
  196. statement.cond = statement.cond.And(notIn)
  197. return statement
  198. }
  199. func (statement *Statement) setRefValue(v reflect.Value) error {
  200. var err error
  201. statement.RefTable, err = statement.Engine.autoMapType(reflect.Indirect(v))
  202. if err != nil {
  203. return err
  204. }
  205. statement.tableName = statement.Engine.tbName(v)
  206. return nil
  207. }
  208. // Table tempororily set table name, the parameter could be a string or a pointer of struct
  209. func (statement *Statement) Table(tableNameOrBean interface{}) *Statement {
  210. v := rValue(tableNameOrBean)
  211. t := v.Type()
  212. if t.Kind() == reflect.String {
  213. statement.AltTableName = tableNameOrBean.(string)
  214. } else if t.Kind() == reflect.Struct {
  215. var err error
  216. statement.RefTable, err = statement.Engine.autoMapType(v)
  217. if err != nil {
  218. statement.Engine.logger.Error(err)
  219. return statement
  220. }
  221. statement.AltTableName = statement.Engine.tbName(v)
  222. }
  223. return statement
  224. }
  225. // Auto generating update columnes and values according a struct
  226. func buildUpdates(engine *Engine, table *core.Table, bean interface{},
  227. includeVersion bool, includeUpdated bool, includeNil bool,
  228. includeAutoIncr bool, allUseBool bool, useAllCols bool,
  229. mustColumnMap map[string]bool, nullableMap map[string]bool,
  230. columnMap map[string]bool, update, unscoped bool) ([]string, []interface{}) {
  231. var colNames = make([]string, 0)
  232. var args = make([]interface{}, 0)
  233. for _, col := range table.Columns() {
  234. if !includeVersion && col.IsVersion {
  235. continue
  236. }
  237. if col.IsCreated {
  238. continue
  239. }
  240. if !includeUpdated && col.IsUpdated {
  241. continue
  242. }
  243. if !includeAutoIncr && col.IsAutoIncrement {
  244. continue
  245. }
  246. if col.IsDeleted && !unscoped {
  247. continue
  248. }
  249. if use, ok := columnMap[strings.ToLower(col.Name)]; ok && !use {
  250. continue
  251. }
  252. fieldValuePtr, err := col.ValueOf(bean)
  253. if err != nil {
  254. engine.logger.Error(err)
  255. continue
  256. }
  257. fieldValue := *fieldValuePtr
  258. fieldType := reflect.TypeOf(fieldValue.Interface())
  259. if fieldType == nil {
  260. continue
  261. }
  262. requiredField := useAllCols
  263. includeNil := useAllCols
  264. if b, ok := getFlagForColumn(mustColumnMap, col); ok {
  265. if b {
  266. requiredField = true
  267. } else {
  268. continue
  269. }
  270. }
  271. // !evalphobia! set fieldValue as nil when column is nullable and zero-value
  272. if b, ok := getFlagForColumn(nullableMap, col); ok {
  273. if b && col.Nullable && isZero(fieldValue.Interface()) {
  274. var nilValue *int
  275. fieldValue = reflect.ValueOf(nilValue)
  276. fieldType = reflect.TypeOf(fieldValue.Interface())
  277. includeNil = true
  278. }
  279. }
  280. var val interface{}
  281. if fieldValue.CanAddr() {
  282. if structConvert, ok := fieldValue.Addr().Interface().(core.Conversion); ok {
  283. data, err := structConvert.ToDB()
  284. if err != nil {
  285. engine.logger.Error(err)
  286. } else {
  287. val = data
  288. }
  289. goto APPEND
  290. }
  291. }
  292. if structConvert, ok := fieldValue.Interface().(core.Conversion); ok {
  293. data, err := structConvert.ToDB()
  294. if err != nil {
  295. engine.logger.Error(err)
  296. } else {
  297. val = data
  298. }
  299. goto APPEND
  300. }
  301. if fieldType.Kind() == reflect.Ptr {
  302. if fieldValue.IsNil() {
  303. if includeNil {
  304. args = append(args, nil)
  305. colNames = append(colNames, fmt.Sprintf("%v=?", engine.Quote(col.Name)))
  306. }
  307. continue
  308. } else if !fieldValue.IsValid() {
  309. continue
  310. } else {
  311. // dereference ptr type to instance type
  312. fieldValue = fieldValue.Elem()
  313. fieldType = reflect.TypeOf(fieldValue.Interface())
  314. requiredField = true
  315. }
  316. }
  317. switch fieldType.Kind() {
  318. case reflect.Bool:
  319. if allUseBool || requiredField {
  320. val = fieldValue.Interface()
  321. } else {
  322. // if a bool in a struct, it will not be as a condition because it default is false,
  323. // please use Where() instead
  324. continue
  325. }
  326. case reflect.String:
  327. if !requiredField && fieldValue.String() == "" {
  328. continue
  329. }
  330. // for MyString, should convert to string or panic
  331. if fieldType.String() != reflect.String.String() {
  332. val = fieldValue.String()
  333. } else {
  334. val = fieldValue.Interface()
  335. }
  336. case reflect.Int8, reflect.Int16, reflect.Int, reflect.Int32, reflect.Int64:
  337. if !requiredField && fieldValue.Int() == 0 {
  338. continue
  339. }
  340. val = fieldValue.Interface()
  341. case reflect.Float32, reflect.Float64:
  342. if !requiredField && fieldValue.Float() == 0.0 {
  343. continue
  344. }
  345. val = fieldValue.Interface()
  346. case reflect.Uint8, reflect.Uint16, reflect.Uint, reflect.Uint32, reflect.Uint64:
  347. if !requiredField && fieldValue.Uint() == 0 {
  348. continue
  349. }
  350. t := int64(fieldValue.Uint())
  351. val = reflect.ValueOf(&t).Interface()
  352. case reflect.Struct:
  353. if fieldType.ConvertibleTo(core.TimeType) {
  354. t := fieldValue.Convert(core.TimeType).Interface().(time.Time)
  355. if !requiredField && (t.IsZero() || !fieldValue.IsValid()) {
  356. continue
  357. }
  358. val = engine.formatColTime(col, t)
  359. } else if nulType, ok := fieldValue.Interface().(driver.Valuer); ok {
  360. val, _ = nulType.Value()
  361. } else {
  362. if !col.SQLType.IsJson() {
  363. engine.autoMapType(fieldValue)
  364. if table, ok := engine.Tables[fieldValue.Type()]; ok {
  365. if len(table.PrimaryKeys) == 1 {
  366. pkField := reflect.Indirect(fieldValue).FieldByName(table.PKColumns()[0].FieldName)
  367. // fix non-int pk issues
  368. if pkField.IsValid() && (!requiredField && !isZero(pkField.Interface())) {
  369. val = pkField.Interface()
  370. } else {
  371. continue
  372. }
  373. } else {
  374. //TODO: how to handler?
  375. panic("not supported")
  376. }
  377. } else {
  378. val = fieldValue.Interface()
  379. }
  380. } else {
  381. // Blank struct could not be as update data
  382. if requiredField || !isStructZero(fieldValue) {
  383. bytes, err := json.Marshal(fieldValue.Interface())
  384. if err != nil {
  385. panic(fmt.Sprintf("mashal %v failed", fieldValue.Interface()))
  386. }
  387. if col.SQLType.IsText() {
  388. val = string(bytes)
  389. } else if col.SQLType.IsBlob() {
  390. val = bytes
  391. }
  392. } else {
  393. continue
  394. }
  395. }
  396. }
  397. case reflect.Array, reflect.Slice, reflect.Map:
  398. if !requiredField {
  399. if fieldValue == reflect.Zero(fieldType) {
  400. continue
  401. }
  402. if fieldType.Kind() == reflect.Array {
  403. if isArrayValueZero(fieldValue) {
  404. continue
  405. }
  406. } else if fieldValue.IsNil() || !fieldValue.IsValid() || fieldValue.Len() == 0 {
  407. continue
  408. }
  409. }
  410. if col.SQLType.IsText() {
  411. bytes, err := json.Marshal(fieldValue.Interface())
  412. if err != nil {
  413. engine.logger.Error(err)
  414. continue
  415. }
  416. val = string(bytes)
  417. } else if col.SQLType.IsBlob() {
  418. var bytes []byte
  419. var err error
  420. if fieldType.Kind() == reflect.Slice &&
  421. fieldType.Elem().Kind() == reflect.Uint8 {
  422. if fieldValue.Len() > 0 {
  423. val = fieldValue.Bytes()
  424. } else {
  425. continue
  426. }
  427. } else if fieldType.Kind() == reflect.Array &&
  428. fieldType.Elem().Kind() == reflect.Uint8 {
  429. val = fieldValue.Slice(0, 0).Interface()
  430. } else {
  431. bytes, err = json.Marshal(fieldValue.Interface())
  432. if err != nil {
  433. engine.logger.Error(err)
  434. continue
  435. }
  436. val = bytes
  437. }
  438. } else {
  439. continue
  440. }
  441. default:
  442. val = fieldValue.Interface()
  443. }
  444. APPEND:
  445. args = append(args, val)
  446. if col.IsPrimaryKey && engine.dialect.DBType() == "ql" {
  447. continue
  448. }
  449. colNames = append(colNames, fmt.Sprintf("%v = ?", engine.Quote(col.Name)))
  450. }
  451. return colNames, args
  452. }
  453. func (statement *Statement) needTableName() bool {
  454. return len(statement.JoinStr) > 0
  455. }
  456. func (statement *Statement) colName(col *core.Column, tableName string) string {
  457. if statement.needTableName() {
  458. var nm = tableName
  459. if len(statement.TableAlias) > 0 {
  460. nm = statement.TableAlias
  461. }
  462. return statement.Engine.Quote(nm) + "." + statement.Engine.Quote(col.Name)
  463. }
  464. return statement.Engine.Quote(col.Name)
  465. }
  466. // TableName return current tableName
  467. func (statement *Statement) TableName() string {
  468. if statement.AltTableName != "" {
  469. return statement.AltTableName
  470. }
  471. return statement.tableName
  472. }
  473. // ID generate "where id = ? " statement or for composite key "where key1 = ? and key2 = ?"
  474. func (statement *Statement) ID(id interface{}) *Statement {
  475. idValue := reflect.ValueOf(id)
  476. idType := reflect.TypeOf(idValue.Interface())
  477. switch idType {
  478. case ptrPkType:
  479. if pkPtr, ok := (id).(*core.PK); ok {
  480. statement.idParam = pkPtr
  481. return statement
  482. }
  483. case pkType:
  484. if pk, ok := (id).(core.PK); ok {
  485. statement.idParam = &pk
  486. return statement
  487. }
  488. }
  489. switch idType.Kind() {
  490. case reflect.String:
  491. statement.idParam = &core.PK{idValue.Convert(reflect.TypeOf("")).Interface()}
  492. return statement
  493. }
  494. statement.idParam = &core.PK{id}
  495. return statement
  496. }
  497. // Incr Generate "Update ... Set column = column + arg" statement
  498. func (statement *Statement) Incr(column string, arg ...interface{}) *Statement {
  499. k := strings.ToLower(column)
  500. if len(arg) > 0 {
  501. statement.incrColumns[k] = incrParam{column, arg[0]}
  502. } else {
  503. statement.incrColumns[k] = incrParam{column, 1}
  504. }
  505. return statement
  506. }
  507. // Decr Generate "Update ... Set column = column - arg" statement
  508. func (statement *Statement) Decr(column string, arg ...interface{}) *Statement {
  509. k := strings.ToLower(column)
  510. if len(arg) > 0 {
  511. statement.decrColumns[k] = decrParam{column, arg[0]}
  512. } else {
  513. statement.decrColumns[k] = decrParam{column, 1}
  514. }
  515. return statement
  516. }
  517. // SetExpr Generate "Update ... Set column = {expression}" statement
  518. func (statement *Statement) SetExpr(column string, expression string) *Statement {
  519. k := strings.ToLower(column)
  520. statement.exprColumns[k] = exprParam{column, expression}
  521. return statement
  522. }
  523. // Generate "Update ... Set column = column + arg" statement
  524. func (statement *Statement) getInc() map[string]incrParam {
  525. return statement.incrColumns
  526. }
  527. // Generate "Update ... Set column = column - arg" statement
  528. func (statement *Statement) getDec() map[string]decrParam {
  529. return statement.decrColumns
  530. }
  531. // Generate "Update ... Set column = {expression}" statement
  532. func (statement *Statement) getExpr() map[string]exprParam {
  533. return statement.exprColumns
  534. }
  535. func (statement *Statement) col2NewColsWithQuote(columns ...string) []string {
  536. newColumns := make([]string, 0)
  537. for _, col := range columns {
  538. col = strings.Replace(col, "`", "", -1)
  539. col = strings.Replace(col, statement.Engine.QuoteStr(), "", -1)
  540. ccols := strings.Split(col, ",")
  541. for _, c := range ccols {
  542. fields := strings.Split(strings.TrimSpace(c), ".")
  543. if len(fields) == 1 {
  544. newColumns = append(newColumns, statement.Engine.quote(fields[0]))
  545. } else if len(fields) == 2 {
  546. newColumns = append(newColumns, statement.Engine.quote(fields[0])+"."+
  547. statement.Engine.quote(fields[1]))
  548. } else {
  549. panic(errors.New("unwanted colnames"))
  550. }
  551. }
  552. }
  553. return newColumns
  554. }
  555. func (statement *Statement) colmap2NewColsWithQuote() []string {
  556. newColumns := make([]string, 0, len(statement.columnMap))
  557. for col := range statement.columnMap {
  558. fields := strings.Split(strings.TrimSpace(col), ".")
  559. if len(fields) == 1 {
  560. newColumns = append(newColumns, statement.Engine.quote(fields[0]))
  561. } else if len(fields) == 2 {
  562. newColumns = append(newColumns, statement.Engine.quote(fields[0])+"."+
  563. statement.Engine.quote(fields[1]))
  564. } else {
  565. panic(errors.New("unwanted colnames"))
  566. }
  567. }
  568. return newColumns
  569. }
  570. // Distinct generates "DISTINCT col1, col2 " statement
  571. func (statement *Statement) Distinct(columns ...string) *Statement {
  572. statement.IsDistinct = true
  573. statement.Cols(columns...)
  574. return statement
  575. }
  576. // ForUpdate generates "SELECT ... FOR UPDATE" statement
  577. func (statement *Statement) ForUpdate() *Statement {
  578. statement.IsForUpdate = true
  579. return statement
  580. }
  581. // Select replace select
  582. func (statement *Statement) Select(str string) *Statement {
  583. statement.selectStr = str
  584. return statement
  585. }
  586. // Cols generate "col1, col2" statement
  587. func (statement *Statement) Cols(columns ...string) *Statement {
  588. cols := col2NewCols(columns...)
  589. for _, nc := range cols {
  590. statement.columnMap[strings.ToLower(nc)] = true
  591. }
  592. newColumns := statement.colmap2NewColsWithQuote()
  593. statement.ColumnStr = strings.Join(newColumns, ", ")
  594. statement.ColumnStr = strings.Replace(statement.ColumnStr, statement.Engine.quote("*"), "*", -1)
  595. return statement
  596. }
  597. // AllCols update use only: update all columns
  598. func (statement *Statement) AllCols() *Statement {
  599. statement.useAllCols = true
  600. return statement
  601. }
  602. // MustCols update use only: must update columns
  603. func (statement *Statement) MustCols(columns ...string) *Statement {
  604. newColumns := col2NewCols(columns...)
  605. for _, nc := range newColumns {
  606. statement.mustColumnMap[strings.ToLower(nc)] = true
  607. }
  608. return statement
  609. }
  610. // UseBool indicates that use bool fields as update contents and query contiditions
  611. func (statement *Statement) UseBool(columns ...string) *Statement {
  612. if len(columns) > 0 {
  613. statement.MustCols(columns...)
  614. } else {
  615. statement.allUseBool = true
  616. }
  617. return statement
  618. }
  619. // Omit do not use the columns
  620. func (statement *Statement) Omit(columns ...string) {
  621. newColumns := col2NewCols(columns...)
  622. for _, nc := range newColumns {
  623. statement.columnMap[strings.ToLower(nc)] = false
  624. }
  625. statement.OmitStr = statement.Engine.Quote(strings.Join(newColumns, statement.Engine.Quote(", ")))
  626. }
  627. // Nullable Update use only: update columns to null when value is nullable and zero-value
  628. func (statement *Statement) Nullable(columns ...string) {
  629. newColumns := col2NewCols(columns...)
  630. for _, nc := range newColumns {
  631. statement.nullableMap[strings.ToLower(nc)] = true
  632. }
  633. }
  634. // Top generate LIMIT limit statement
  635. func (statement *Statement) Top(limit int) *Statement {
  636. statement.Limit(limit)
  637. return statement
  638. }
  639. // Limit generate LIMIT start, limit statement
  640. func (statement *Statement) Limit(limit int, start ...int) *Statement {
  641. statement.LimitN = limit
  642. if len(start) > 0 {
  643. statement.Start = start[0]
  644. }
  645. return statement
  646. }
  647. // OrderBy generate "Order By order" statement
  648. func (statement *Statement) OrderBy(order string) *Statement {
  649. if len(statement.OrderStr) > 0 {
  650. statement.OrderStr += ", "
  651. }
  652. statement.OrderStr += order
  653. return statement
  654. }
  655. // Desc generate `ORDER BY xx DESC`
  656. func (statement *Statement) Desc(colNames ...string) *Statement {
  657. var buf bytes.Buffer
  658. fmt.Fprintf(&buf, statement.OrderStr)
  659. if len(statement.OrderStr) > 0 {
  660. fmt.Fprint(&buf, ", ")
  661. }
  662. newColNames := statement.col2NewColsWithQuote(colNames...)
  663. fmt.Fprintf(&buf, "%v DESC", strings.Join(newColNames, " DESC, "))
  664. statement.OrderStr = buf.String()
  665. return statement
  666. }
  667. // Asc provide asc order by query condition, the input parameters are columns.
  668. func (statement *Statement) Asc(colNames ...string) *Statement {
  669. var buf bytes.Buffer
  670. fmt.Fprintf(&buf, statement.OrderStr)
  671. if len(statement.OrderStr) > 0 {
  672. fmt.Fprint(&buf, ", ")
  673. }
  674. newColNames := statement.col2NewColsWithQuote(colNames...)
  675. fmt.Fprintf(&buf, "%v ASC", strings.Join(newColNames, " ASC, "))
  676. statement.OrderStr = buf.String()
  677. return statement
  678. }
  679. // Join The joinOP should be one of INNER, LEFT OUTER, CROSS etc - this will be prepended to JOIN
  680. func (statement *Statement) Join(joinOP string, tablename interface{}, condition string, args ...interface{}) *Statement {
  681. var buf bytes.Buffer
  682. if len(statement.JoinStr) > 0 {
  683. fmt.Fprintf(&buf, "%v %v JOIN ", statement.JoinStr, joinOP)
  684. } else {
  685. fmt.Fprintf(&buf, "%v JOIN ", joinOP)
  686. }
  687. switch tablename.(type) {
  688. case []string:
  689. t := tablename.([]string)
  690. if len(t) > 1 {
  691. fmt.Fprintf(&buf, "%v AS %v", statement.Engine.Quote(t[0]), statement.Engine.Quote(t[1]))
  692. } else if len(t) == 1 {
  693. fmt.Fprintf(&buf, statement.Engine.Quote(t[0]))
  694. }
  695. case []interface{}:
  696. t := tablename.([]interface{})
  697. l := len(t)
  698. var table string
  699. if l > 0 {
  700. f := t[0]
  701. switch f.(type) {
  702. case string:
  703. table = f.(string)
  704. case TableName:
  705. table = f.(TableName).TableName()
  706. default:
  707. v := rValue(f)
  708. t := v.Type()
  709. if t.Kind() == reflect.Struct {
  710. fmt.Fprintf(&buf, statement.Engine.tbName(v))
  711. } else {
  712. fmt.Fprintf(&buf, statement.Engine.Quote(fmt.Sprintf("%v", f)))
  713. }
  714. }
  715. }
  716. if l > 1 {
  717. fmt.Fprintf(&buf, "%v AS %v", statement.Engine.Quote(table),
  718. statement.Engine.Quote(fmt.Sprintf("%v", t[1])))
  719. } else if l == 1 {
  720. fmt.Fprintf(&buf, statement.Engine.Quote(table))
  721. }
  722. case TableName:
  723. fmt.Fprintf(&buf, tablename.(TableName).TableName())
  724. case string:
  725. fmt.Fprintf(&buf, tablename.(string))
  726. default:
  727. v := rValue(tablename)
  728. t := v.Type()
  729. if t.Kind() == reflect.Struct {
  730. fmt.Fprintf(&buf, statement.Engine.tbName(v))
  731. } else {
  732. fmt.Fprintf(&buf, statement.Engine.Quote(fmt.Sprintf("%v", tablename)))
  733. }
  734. }
  735. fmt.Fprintf(&buf, " ON %v", condition)
  736. statement.JoinStr = buf.String()
  737. statement.joinArgs = append(statement.joinArgs, args...)
  738. return statement
  739. }
  740. // GroupBy generate "Group By keys" statement
  741. func (statement *Statement) GroupBy(keys string) *Statement {
  742. statement.GroupByStr = keys
  743. return statement
  744. }
  745. // Having generate "Having conditions" statement
  746. func (statement *Statement) Having(conditions string) *Statement {
  747. statement.HavingStr = fmt.Sprintf("HAVING %v", conditions)
  748. return statement
  749. }
  750. // Unscoped always disable struct tag "deleted"
  751. func (statement *Statement) Unscoped() *Statement {
  752. statement.unscoped = true
  753. return statement
  754. }
  755. func (statement *Statement) genColumnStr() string {
  756. var buf bytes.Buffer
  757. if statement.RefTable == nil {
  758. return ""
  759. }
  760. columns := statement.RefTable.Columns()
  761. for _, col := range columns {
  762. if statement.OmitStr != "" {
  763. if _, ok := getFlagForColumn(statement.columnMap, col); ok {
  764. continue
  765. }
  766. }
  767. if col.MapType == core.ONLYTODB {
  768. continue
  769. }
  770. if buf.Len() != 0 {
  771. buf.WriteString(", ")
  772. }
  773. if col.IsPrimaryKey && statement.Engine.Dialect().DBType() == "ql" {
  774. buf.WriteString("id() AS ")
  775. }
  776. if statement.JoinStr != "" {
  777. if statement.TableAlias != "" {
  778. buf.WriteString(statement.TableAlias)
  779. } else {
  780. buf.WriteString(statement.TableName())
  781. }
  782. buf.WriteString(".")
  783. }
  784. statement.Engine.QuoteTo(&buf, col.Name)
  785. }
  786. return buf.String()
  787. }
  788. func (statement *Statement) genCreateTableSQL() string {
  789. return statement.Engine.dialect.CreateTableSql(statement.RefTable, statement.TableName(),
  790. statement.StoreEngine, statement.Charset)
  791. }
  792. func (statement *Statement) genIndexSQL() []string {
  793. var sqls []string
  794. tbName := statement.TableName()
  795. for _, index := range statement.RefTable.Indexes {
  796. if index.Type == core.IndexType {
  797. sql := statement.Engine.dialect.CreateIndexSql(tbName, index)
  798. if sql != "" {
  799. sqls = append(sqls, sql)
  800. }
  801. }
  802. }
  803. return sqls
  804. }
  805. func uniqueName(tableName, uqeName string) string {
  806. return fmt.Sprintf("UQE_%v_%v", tableName, uqeName)
  807. }
  808. func (statement *Statement) genUniqueSQL() []string {
  809. var sqls []string
  810. tbName := statement.TableName()
  811. for _, index := range statement.RefTable.Indexes {
  812. if index.Type == core.UniqueType {
  813. sql := statement.Engine.dialect.CreateIndexSql(tbName, index)
  814. sqls = append(sqls, sql)
  815. }
  816. }
  817. return sqls
  818. }
  819. func (statement *Statement) genDelIndexSQL() []string {
  820. var sqls []string
  821. tbName := statement.TableName()
  822. for idxName, index := range statement.RefTable.Indexes {
  823. var rIdxName string
  824. if index.Type == core.UniqueType {
  825. rIdxName = uniqueName(tbName, idxName)
  826. } else if index.Type == core.IndexType {
  827. rIdxName = indexName(tbName, idxName)
  828. }
  829. sql := fmt.Sprintf("DROP INDEX %v", statement.Engine.Quote(rIdxName))
  830. if statement.Engine.dialect.IndexOnTable() {
  831. sql += fmt.Sprintf(" ON %v", statement.Engine.Quote(statement.TableName()))
  832. }
  833. sqls = append(sqls, sql)
  834. }
  835. return sqls
  836. }
  837. func (statement *Statement) genAddColumnStr(col *core.Column) (string, []interface{}) {
  838. quote := statement.Engine.Quote
  839. sql := fmt.Sprintf("ALTER TABLE %v ADD %v", quote(statement.TableName()),
  840. col.String(statement.Engine.dialect))
  841. if statement.Engine.dialect.DBType() == core.MYSQL && len(col.Comment) > 0 {
  842. sql += " COMMENT '" + col.Comment + "'"
  843. }
  844. sql += ";"
  845. return sql, []interface{}{}
  846. }
  847. func (statement *Statement) buildConds(table *core.Table, bean interface{}, includeVersion bool, includeUpdated bool, includeNil bool, includeAutoIncr bool, addedTableName bool) (builder.Cond, error) {
  848. return statement.Engine.buildConds(table, bean, includeVersion, includeUpdated, includeNil, includeAutoIncr, statement.allUseBool, statement.useAllCols,
  849. statement.unscoped, statement.mustColumnMap, statement.TableName(), statement.TableAlias, addedTableName)
  850. }
  851. func (statement *Statement) mergeConds(bean interface{}) error {
  852. if !statement.noAutoCondition {
  853. var addedTableName = (len(statement.JoinStr) > 0)
  854. autoCond, err := statement.buildConds(statement.RefTable, bean, true, true, false, true, addedTableName)
  855. if err != nil {
  856. return err
  857. }
  858. statement.cond = statement.cond.And(autoCond)
  859. }
  860. if err := statement.processIDParam(); err != nil {
  861. return err
  862. }
  863. return nil
  864. }
  865. func (statement *Statement) genConds(bean interface{}) (string, []interface{}, error) {
  866. if err := statement.mergeConds(bean); err != nil {
  867. return "", nil, err
  868. }
  869. return builder.ToSQL(statement.cond)
  870. }
  871. func (statement *Statement) genGetSQL(bean interface{}) (string, []interface{}, error) {
  872. v := rValue(bean)
  873. isStruct := v.Kind() == reflect.Struct
  874. if isStruct {
  875. statement.setRefValue(v)
  876. }
  877. var columnStr = statement.ColumnStr
  878. if len(statement.selectStr) > 0 {
  879. columnStr = statement.selectStr
  880. } else {
  881. // TODO: always generate column names, not use * even if join
  882. if len(statement.JoinStr) == 0 {
  883. if len(columnStr) == 0 {
  884. if len(statement.GroupByStr) > 0 {
  885. columnStr = statement.Engine.Quote(strings.Replace(statement.GroupByStr, ",", statement.Engine.Quote(","), -1))
  886. } else {
  887. columnStr = statement.genColumnStr()
  888. }
  889. }
  890. } else {
  891. if len(columnStr) == 0 {
  892. if len(statement.GroupByStr) > 0 {
  893. columnStr = statement.Engine.Quote(strings.Replace(statement.GroupByStr, ",", statement.Engine.Quote(","), -1))
  894. }
  895. }
  896. }
  897. }
  898. if len(columnStr) == 0 {
  899. columnStr = "*"
  900. }
  901. if isStruct {
  902. if err := statement.mergeConds(bean); err != nil {
  903. return "", nil, err
  904. }
  905. }
  906. condSQL, condArgs, err := builder.ToSQL(statement.cond)
  907. if err != nil {
  908. return "", nil, err
  909. }
  910. sqlStr, err := statement.genSelectSQL(columnStr, condSQL, true)
  911. if err != nil {
  912. return "", nil, err
  913. }
  914. return sqlStr, append(statement.joinArgs, condArgs...), nil
  915. }
  916. func (statement *Statement) genCountSQL(beans ...interface{}) (string, []interface{}, error) {
  917. var condSQL string
  918. var condArgs []interface{}
  919. var err error
  920. if len(beans) > 0 {
  921. statement.setRefValue(rValue(beans[0]))
  922. condSQL, condArgs, err = statement.genConds(beans[0])
  923. } else {
  924. condSQL, condArgs, err = builder.ToSQL(statement.cond)
  925. }
  926. if err != nil {
  927. return "", nil, err
  928. }
  929. var selectSQL = statement.selectStr
  930. if len(selectSQL) <= 0 {
  931. if statement.IsDistinct {
  932. selectSQL = fmt.Sprintf("count(DISTINCT %s)", statement.ColumnStr)
  933. } else {
  934. selectSQL = "count(*)"
  935. }
  936. }
  937. sqlStr, err := statement.genSelectSQL(selectSQL, condSQL, false)
  938. if err != nil {
  939. return "", nil, err
  940. }
  941. return sqlStr, append(statement.joinArgs, condArgs...), nil
  942. }
  943. func (statement *Statement) genSumSQL(bean interface{}, columns ...string) (string, []interface{}, error) {
  944. statement.setRefValue(rValue(bean))
  945. var sumStrs = make([]string, 0, len(columns))
  946. for _, colName := range columns {
  947. if !strings.Contains(colName, " ") && !strings.Contains(colName, "(") {
  948. colName = statement.Engine.Quote(colName)
  949. }
  950. sumStrs = append(sumStrs, fmt.Sprintf("COALESCE(sum(%s),0)", colName))
  951. }
  952. sumSelect := strings.Join(sumStrs, ", ")
  953. condSQL, condArgs, err := statement.genConds(bean)
  954. if err != nil {
  955. return "", nil, err
  956. }
  957. sqlStr, err := statement.genSelectSQL(sumSelect, condSQL, true)
  958. if err != nil {
  959. return "", nil, err
  960. }
  961. return sqlStr, append(statement.joinArgs, condArgs...), nil
  962. }
  963. func (statement *Statement) genSelectSQL(columnStr, condSQL string, needLimit bool) (a string, err error) {
  964. var distinct string
  965. if statement.IsDistinct && !strings.HasPrefix(columnStr, "count") {
  966. distinct = "DISTINCT "
  967. }
  968. var dialect = statement.Engine.Dialect()
  969. var quote = statement.Engine.Quote
  970. var top string
  971. var mssqlCondi string
  972. if err := statement.processIDParam(); err != nil {
  973. return "", err
  974. }
  975. var buf bytes.Buffer
  976. if len(condSQL) > 0 {
  977. fmt.Fprintf(&buf, " WHERE %v", condSQL)
  978. }
  979. var whereStr = buf.String()
  980. var fromStr = " FROM "
  981. if dialect.DBType() == core.MSSQL && strings.Contains(statement.TableName(), "..") {
  982. fromStr += statement.TableName()
  983. } else {
  984. fromStr += quote(statement.TableName())
  985. }
  986. if statement.TableAlias != "" {
  987. if dialect.DBType() == core.ORACLE {
  988. fromStr += " " + quote(statement.TableAlias)
  989. } else {
  990. fromStr += " AS " + quote(statement.TableAlias)
  991. }
  992. }
  993. if statement.JoinStr != "" {
  994. fromStr = fmt.Sprintf("%v %v", fromStr, statement.JoinStr)
  995. }
  996. if dialect.DBType() == core.MSSQL {
  997. if statement.LimitN > 0 {
  998. top = fmt.Sprintf(" TOP %d ", statement.LimitN)
  999. }
  1000. if statement.Start > 0 {
  1001. var column string
  1002. if len(statement.RefTable.PKColumns()) == 0 {
  1003. for _, index := range statement.RefTable.Indexes {
  1004. if len(index.Cols) == 1 {
  1005. column = index.Cols[0]
  1006. break
  1007. }
  1008. }
  1009. if len(column) == 0 {
  1010. column = statement.RefTable.ColumnsSeq()[0]
  1011. }
  1012. } else {
  1013. column = statement.RefTable.PKColumns()[0].Name
  1014. }
  1015. if statement.needTableName() {
  1016. if len(statement.TableAlias) > 0 {
  1017. column = statement.TableAlias + "." + column
  1018. } else {
  1019. column = statement.TableName() + "." + column
  1020. }
  1021. }
  1022. var orderStr string
  1023. if len(statement.OrderStr) > 0 {
  1024. orderStr = " ORDER BY " + statement.OrderStr
  1025. }
  1026. var groupStr string
  1027. if len(statement.GroupByStr) > 0 {
  1028. groupStr = " GROUP BY " + statement.GroupByStr
  1029. }
  1030. mssqlCondi = fmt.Sprintf("(%s NOT IN (SELECT TOP %d %s%s%s%s%s))",
  1031. column, statement.Start, column, fromStr, whereStr, orderStr, groupStr)
  1032. }
  1033. }
  1034. // !nashtsai! REVIEW Sprintf is considered slowest mean of string concatnation, better to work with builder pattern
  1035. a = fmt.Sprintf("SELECT %v%v%v%v%v", distinct, top, columnStr, fromStr, whereStr)
  1036. if len(mssqlCondi) > 0 {
  1037. if len(whereStr) > 0 {
  1038. a += " AND " + mssqlCondi
  1039. } else {
  1040. a += " WHERE " + mssqlCondi
  1041. }
  1042. }
  1043. if statement.GroupByStr != "" {
  1044. a = fmt.Sprintf("%v GROUP BY %v", a, statement.GroupByStr)
  1045. }
  1046. if statement.HavingStr != "" {
  1047. a = fmt.Sprintf("%v %v", a, statement.HavingStr)
  1048. }
  1049. if statement.OrderStr != "" {
  1050. a = fmt.Sprintf("%v ORDER BY %v", a, statement.OrderStr)
  1051. }
  1052. if needLimit {
  1053. if dialect.DBType() != core.MSSQL && dialect.DBType() != core.ORACLE {
  1054. if statement.Start > 0 {
  1055. a = fmt.Sprintf("%v LIMIT %v OFFSET %v", a, statement.LimitN, statement.Start)
  1056. } else if statement.LimitN > 0 {
  1057. a = fmt.Sprintf("%v LIMIT %v", a, statement.LimitN)
  1058. }
  1059. } else if dialect.DBType() == core.ORACLE {
  1060. if statement.Start != 0 || statement.LimitN != 0 {
  1061. a = fmt.Sprintf("SELECT %v FROM (SELECT %v,ROWNUM RN FROM (%v) at WHERE ROWNUM <= %d) aat WHERE RN > %d", columnStr, columnStr, a, statement.Start+statement.LimitN, statement.Start)
  1062. }
  1063. }
  1064. }
  1065. if statement.IsForUpdate {
  1066. a = dialect.ForUpdateSql(a)
  1067. }
  1068. return
  1069. }
  1070. func (statement *Statement) processIDParam() error {
  1071. if statement.idParam == nil {
  1072. return nil
  1073. }
  1074. if len(statement.RefTable.PrimaryKeys) != len(*statement.idParam) {
  1075. return fmt.Errorf("ID condition is error, expect %d primarykeys, there are %d",
  1076. len(statement.RefTable.PrimaryKeys),
  1077. len(*statement.idParam),
  1078. )
  1079. }
  1080. for i, col := range statement.RefTable.PKColumns() {
  1081. var colName = statement.colName(col, statement.TableName())
  1082. statement.cond = statement.cond.And(builder.Eq{colName: (*(statement.idParam))[i]})
  1083. }
  1084. return nil
  1085. }
  1086. func (statement *Statement) joinColumns(cols []*core.Column, includeTableName bool) string {
  1087. var colnames = make([]string, len(cols))
  1088. for i, col := range cols {
  1089. if includeTableName {
  1090. colnames[i] = statement.Engine.Quote(statement.TableName()) +
  1091. "." + statement.Engine.Quote(col.Name)
  1092. } else {
  1093. colnames[i] = statement.Engine.Quote(col.Name)
  1094. }
  1095. }
  1096. return strings.Join(colnames, ", ")
  1097. }
  1098. func (statement *Statement) convertIDSQL(sqlStr string) string {
  1099. if statement.RefTable != nil {
  1100. cols := statement.RefTable.PKColumns()
  1101. if len(cols) == 0 {
  1102. return ""
  1103. }
  1104. colstrs := statement.joinColumns(cols, false)
  1105. sqls := splitNNoCase(sqlStr, " from ", 2)
  1106. if len(sqls) != 2 {
  1107. return ""
  1108. }
  1109. var top string
  1110. if statement.LimitN > 0 && statement.Engine.dialect.DBType() == core.MSSQL {
  1111. top = fmt.Sprintf("TOP %d ", statement.LimitN)
  1112. }
  1113. newsql := fmt.Sprintf("SELECT %s%s FROM %v", top, colstrs, sqls[1])
  1114. return newsql
  1115. }
  1116. return ""
  1117. }
  1118. func (statement *Statement) convertUpdateSQL(sqlStr string) (string, string) {
  1119. if statement.RefTable == nil || len(statement.RefTable.PrimaryKeys) != 1 {
  1120. return "", ""
  1121. }
  1122. colstrs := statement.joinColumns(statement.RefTable.PKColumns(), true)
  1123. sqls := splitNNoCase(sqlStr, "where", 2)
  1124. if len(sqls) != 2 {
  1125. if len(sqls) == 1 {
  1126. return sqls[0], fmt.Sprintf("SELECT %v FROM %v",
  1127. colstrs, statement.Engine.Quote(statement.TableName()))
  1128. }
  1129. return "", ""
  1130. }
  1131. var whereStr = sqls[1]
  1132. //TODO: for postgres only, if any other database?
  1133. var paraStr string
  1134. if statement.Engine.dialect.DBType() == core.POSTGRES {
  1135. paraStr = "$"
  1136. } else if statement.Engine.dialect.DBType() == core.MSSQL {
  1137. paraStr = ":"
  1138. }
  1139. if paraStr != "" {
  1140. if strings.Contains(sqls[1], paraStr) {
  1141. dollers := strings.Split(sqls[1], paraStr)
  1142. whereStr = dollers[0]
  1143. for i, c := range dollers[1:] {
  1144. ccs := strings.SplitN(c, " ", 2)
  1145. whereStr += fmt.Sprintf(paraStr+"%v %v", i+1, ccs[1])
  1146. }
  1147. }
  1148. }
  1149. return sqls[0], fmt.Sprintf("SELECT %v FROM %v WHERE %v",
  1150. colstrs, statement.Engine.Quote(statement.TableName()),
  1151. whereStr)
  1152. }