statement.go 38 KB

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