statement.go 36 KB

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