You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

statement.go 35KB

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