statement.go 40 KB

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