statement.go 37 KB

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