statement.go 36 KB

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