statement.go 35 KB

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