statement.go 37 KB

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