statement.go 40 KB

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