session_insert.go 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751
  1. // Copyright 2016 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. "errors"
  7. "fmt"
  8. "reflect"
  9. "sort"
  10. "strconv"
  11. "strings"
  12. "github.com/xormplus/core"
  13. )
  14. // Insert insert one or more beans
  15. func (session *Session) Insert(beans ...interface{}) (int64, error) {
  16. var affected int64
  17. var err error
  18. if session.isAutoClose {
  19. defer session.Close()
  20. }
  21. for _, bean := range beans {
  22. switch bean.(type) {
  23. case map[string]interface{}:
  24. cnt, err := session.insertMapInterface(bean.(map[string]interface{}))
  25. if err != nil {
  26. return affected, err
  27. }
  28. affected += cnt
  29. case []map[string]interface{}:
  30. s := bean.([]map[string]interface{})
  31. session.autoResetStatement = false
  32. for i := 0; i < len(s); i++ {
  33. cnt, err := session.insertMapInterface(s[i])
  34. if err != nil {
  35. return affected, err
  36. }
  37. affected += cnt
  38. }
  39. case map[string]string:
  40. cnt, err := session.insertMapString(bean.(map[string]string))
  41. if err != nil {
  42. return affected, err
  43. }
  44. affected += cnt
  45. case []map[string]string:
  46. s := bean.([]map[string]string)
  47. session.autoResetStatement = false
  48. for i := 0; i < len(s); i++ {
  49. cnt, err := session.insertMapString(s[i])
  50. if err != nil {
  51. return affected, err
  52. }
  53. affected += cnt
  54. }
  55. default:
  56. sliceValue := reflect.Indirect(reflect.ValueOf(bean))
  57. if sliceValue.Kind() == reflect.Slice {
  58. size := sliceValue.Len()
  59. if size > 0 {
  60. if session.engine.SupportInsertMany() {
  61. cnt, err := session.innerInsertMulti(bean)
  62. if err != nil {
  63. return affected, err
  64. }
  65. affected += cnt
  66. } else {
  67. for i := 0; i < size; i++ {
  68. cnt, err := session.innerInsert(sliceValue.Index(i).Interface())
  69. if err != nil {
  70. return affected, err
  71. }
  72. affected += cnt
  73. }
  74. }
  75. }
  76. } else {
  77. cnt, err := session.innerInsert(bean)
  78. if err != nil {
  79. return affected, err
  80. }
  81. affected += cnt
  82. }
  83. }
  84. }
  85. return affected, err
  86. }
  87. func (session *Session) innerInsertMulti(rowsSlicePtr interface{}) (int64, error) {
  88. sliceValue := reflect.Indirect(reflect.ValueOf(rowsSlicePtr))
  89. if sliceValue.Kind() != reflect.Slice {
  90. return 0, errors.New("needs a pointer to a slice")
  91. }
  92. if sliceValue.Len() <= 0 {
  93. return 0, errors.New("could not insert a empty slice")
  94. }
  95. if err := session.statement.setRefBean(sliceValue.Index(0).Interface()); err != nil {
  96. return 0, err
  97. }
  98. tableName := session.statement.TableName()
  99. if len(tableName) <= 0 {
  100. return 0, ErrTableNotFound
  101. }
  102. table := session.statement.RefTable
  103. size := sliceValue.Len()
  104. var colNames []string
  105. var colMultiPlaces []string
  106. var args []interface{}
  107. var cols []*core.Column
  108. for i := 0; i < size; i++ {
  109. v := sliceValue.Index(i)
  110. vv := reflect.Indirect(v)
  111. elemValue := v.Interface()
  112. var colPlaces []string
  113. // handle BeforeInsertProcessor
  114. // !nashtsai! does user expect it's same slice to passed closure when using Before()/After() when insert multi??
  115. for _, closure := range session.beforeClosures {
  116. closure(elemValue)
  117. }
  118. if processor, ok := interface{}(elemValue).(BeforeInsertProcessor); ok {
  119. processor.BeforeInsert()
  120. }
  121. // --
  122. if i == 0 {
  123. for _, col := range table.Columns() {
  124. ptrFieldValue, err := col.ValueOfV(&vv)
  125. if err != nil {
  126. return 0, err
  127. }
  128. fieldValue := *ptrFieldValue
  129. if col.IsAutoIncrement && isZero(fieldValue.Interface()) {
  130. continue
  131. }
  132. if col.MapType == core.ONLYFROMDB {
  133. continue
  134. }
  135. if col.IsDeleted {
  136. continue
  137. }
  138. if session.statement.omitColumnMap.contain(col.Name) {
  139. continue
  140. }
  141. if len(session.statement.columnMap) > 0 && !session.statement.columnMap.contain(col.Name) {
  142. continue
  143. }
  144. if (col.IsCreated || col.IsUpdated) && session.statement.UseAutoTime {
  145. val, t := session.engine.nowTime(col)
  146. args = append(args, val)
  147. var colName = col.Name
  148. session.afterClosures = append(session.afterClosures, func(bean interface{}) {
  149. col := table.GetColumn(colName)
  150. setColumnTime(bean, col, t)
  151. })
  152. } else if col.IsVersion && session.statement.checkVersion {
  153. args = append(args, 1)
  154. var colName = col.Name
  155. session.afterClosures = append(session.afterClosures, func(bean interface{}) {
  156. col := table.GetColumn(colName)
  157. setColumnInt(bean, col, 1)
  158. })
  159. } else {
  160. arg, err := session.value2Interface(col, fieldValue)
  161. if err != nil {
  162. return 0, err
  163. }
  164. args = append(args, arg)
  165. }
  166. colNames = append(colNames, col.Name)
  167. cols = append(cols, col)
  168. colPlaces = append(colPlaces, "?")
  169. }
  170. } else {
  171. for _, col := range cols {
  172. ptrFieldValue, err := col.ValueOfV(&vv)
  173. if err != nil {
  174. return 0, err
  175. }
  176. fieldValue := *ptrFieldValue
  177. if col.IsAutoIncrement && isZero(fieldValue.Interface()) {
  178. continue
  179. }
  180. if col.MapType == core.ONLYFROMDB {
  181. continue
  182. }
  183. if col.IsDeleted {
  184. continue
  185. }
  186. if session.statement.omitColumnMap.contain(col.Name) {
  187. continue
  188. }
  189. if len(session.statement.columnMap) > 0 && !session.statement.columnMap.contain(col.Name) {
  190. continue
  191. }
  192. if (col.IsCreated || col.IsUpdated) && session.statement.UseAutoTime {
  193. val, t := session.engine.nowTime(col)
  194. args = append(args, val)
  195. var colName = col.Name
  196. session.afterClosures = append(session.afterClosures, func(bean interface{}) {
  197. col := table.GetColumn(colName)
  198. setColumnTime(bean, col, t)
  199. })
  200. } else if col.IsVersion && session.statement.checkVersion {
  201. args = append(args, 1)
  202. var colName = col.Name
  203. session.afterClosures = append(session.afterClosures, func(bean interface{}) {
  204. col := table.GetColumn(colName)
  205. setColumnInt(bean, col, 1)
  206. })
  207. } else {
  208. arg, err := session.value2Interface(col, fieldValue)
  209. if err != nil {
  210. return 0, err
  211. }
  212. args = append(args, arg)
  213. }
  214. colPlaces = append(colPlaces, "?")
  215. }
  216. }
  217. colMultiPlaces = append(colMultiPlaces, strings.Join(colPlaces, ", "))
  218. }
  219. cleanupProcessorsClosures(&session.beforeClosures)
  220. var sql string
  221. if session.engine.dialect.DBType() == core.ORACLE {
  222. temp := fmt.Sprintf(") INTO %s (%v%v%v) VALUES (",
  223. session.engine.Quote(tableName),
  224. session.engine.QuoteStr(),
  225. strings.Join(colNames, session.engine.QuoteStr()+", "+session.engine.QuoteStr()),
  226. session.engine.QuoteStr())
  227. sql = fmt.Sprintf("INSERT ALL INTO %s (%v%v%v) VALUES (%v) SELECT 1 FROM DUAL",
  228. session.engine.Quote(tableName),
  229. session.engine.QuoteStr(),
  230. strings.Join(colNames, session.engine.QuoteStr()+", "+session.engine.QuoteStr()),
  231. session.engine.QuoteStr(),
  232. strings.Join(colMultiPlaces, temp))
  233. } else {
  234. sql = fmt.Sprintf("INSERT INTO %s (%v%v%v) VALUES (%v)",
  235. session.engine.Quote(tableName),
  236. session.engine.QuoteStr(),
  237. strings.Join(colNames, session.engine.QuoteStr()+", "+session.engine.QuoteStr()),
  238. session.engine.QuoteStr(),
  239. strings.Join(colMultiPlaces, "),("))
  240. }
  241. res, err := session.exec(sql, args...)
  242. if err != nil {
  243. session.engine.logger.Error(err)
  244. return 0, err
  245. }
  246. session.cacheInsert(tableName)
  247. lenAfterClosures := len(session.afterClosures)
  248. for i := 0; i < size; i++ {
  249. elemValue := reflect.Indirect(sliceValue.Index(i)).Addr().Interface()
  250. // handle AfterInsertProcessor
  251. if session.isAutoCommit {
  252. // !nashtsai! does user expect it's same slice to passed closure when using Before()/After() when insert multi??
  253. for _, closure := range session.afterClosures {
  254. closure(elemValue)
  255. }
  256. if processor, ok := interface{}(elemValue).(AfterInsertProcessor); ok {
  257. processor.AfterInsert()
  258. }
  259. } else {
  260. if lenAfterClosures > 0 {
  261. if value, has := session.afterInsertBeans[elemValue]; has && value != nil {
  262. *value = append(*value, session.afterClosures...)
  263. } else {
  264. afterClosures := make([]func(interface{}), lenAfterClosures)
  265. copy(afterClosures, session.afterClosures)
  266. session.afterInsertBeans[elemValue] = &afterClosures
  267. }
  268. } else {
  269. if _, ok := interface{}(elemValue).(AfterInsertProcessor); ok {
  270. session.afterInsertBeans[elemValue] = nil
  271. }
  272. }
  273. }
  274. }
  275. cleanupProcessorsClosures(&session.afterClosures)
  276. return res.RowsAffected()
  277. }
  278. // InsertMulti insert multiple records
  279. func (session *Session) InsertMulti(rowsSlicePtr interface{}) (int64, error) {
  280. if session.isAutoClose {
  281. defer session.Close()
  282. }
  283. sliceValue := reflect.Indirect(reflect.ValueOf(rowsSlicePtr))
  284. if sliceValue.Kind() != reflect.Slice {
  285. return 0, ErrParamsType
  286. }
  287. if sliceValue.Len() <= 0 {
  288. return 0, nil
  289. }
  290. return session.innerInsertMulti(rowsSlicePtr)
  291. }
  292. func (session *Session) innerInsert(bean interface{}) (int64, error) {
  293. if err := session.statement.setRefBean(bean); err != nil {
  294. return 0, err
  295. }
  296. if len(session.statement.TableName()) <= 0 {
  297. return 0, ErrTableNotFound
  298. }
  299. table := session.statement.RefTable
  300. // handle BeforeInsertProcessor
  301. for _, closure := range session.beforeClosures {
  302. closure(bean)
  303. }
  304. cleanupProcessorsClosures(&session.beforeClosures) // cleanup after used
  305. if processor, ok := interface{}(bean).(BeforeInsertProcessor); ok {
  306. processor.BeforeInsert()
  307. }
  308. colNames, args, err := session.genInsertColumns(bean)
  309. if err != nil {
  310. return 0, err
  311. }
  312. // insert expr columns, override if exists
  313. exprColumns := session.statement.getExpr()
  314. exprColVals := make([]string, 0, len(exprColumns))
  315. for _, v := range exprColumns {
  316. // remove the expr columns
  317. for i, colName := range colNames {
  318. if colName == v.colName {
  319. colNames = append(colNames[:i], colNames[i+1:]...)
  320. args = append(args[:i], args[i+1:]...)
  321. }
  322. }
  323. // append expr column to the end
  324. colNames = append(colNames, v.colName)
  325. exprColVals = append(exprColVals, v.expr)
  326. }
  327. colPlaces := strings.Repeat("?, ", len(colNames)-len(exprColumns))
  328. if len(exprColVals) > 0 {
  329. colPlaces = colPlaces + strings.Join(exprColVals, ", ")
  330. } else {
  331. if len(colPlaces) > 0 {
  332. colPlaces = colPlaces[0 : len(colPlaces)-2]
  333. }
  334. }
  335. var sqlStr string
  336. var tableName = session.statement.TableName()
  337. var output string
  338. if session.engine.dialect.DBType() == core.MSSQL && len(table.AutoIncrement) > 0 {
  339. output = fmt.Sprintf(" OUTPUT Inserted.%s", table.AutoIncrement)
  340. }
  341. if len(colPlaces) > 0 {
  342. sqlStr = fmt.Sprintf("INSERT INTO %s (%v%v%v)%s VALUES (%v)",
  343. session.engine.Quote(tableName),
  344. session.engine.QuoteStr(),
  345. strings.Join(colNames, session.engine.Quote(", ")),
  346. session.engine.QuoteStr(),
  347. output,
  348. colPlaces)
  349. } else {
  350. if session.engine.dialect.DBType() == core.MYSQL {
  351. sqlStr = fmt.Sprintf("INSERT INTO %s VALUES ()", session.engine.Quote(tableName))
  352. } else {
  353. sqlStr = fmt.Sprintf("INSERT INTO %s%s DEFAULT VALUES", session.engine.Quote(tableName), output)
  354. }
  355. }
  356. if len(table.AutoIncrement) > 0 && session.engine.dialect.DBType() == core.POSTGRES {
  357. sqlStr = sqlStr + " RETURNING " + session.engine.Quote(table.AutoIncrement)
  358. }
  359. handleAfterInsertProcessorFunc := func(bean interface{}) {
  360. if session.isAutoCommit {
  361. for _, closure := range session.afterClosures {
  362. closure(bean)
  363. }
  364. if processor, ok := interface{}(bean).(AfterInsertProcessor); ok {
  365. processor.AfterInsert()
  366. }
  367. } else {
  368. lenAfterClosures := len(session.afterClosures)
  369. if lenAfterClosures > 0 {
  370. if value, has := session.afterInsertBeans[bean]; has && value != nil {
  371. *value = append(*value, session.afterClosures...)
  372. } else {
  373. afterClosures := make([]func(interface{}), lenAfterClosures)
  374. copy(afterClosures, session.afterClosures)
  375. session.afterInsertBeans[bean] = &afterClosures
  376. }
  377. } else {
  378. if _, ok := interface{}(bean).(AfterInsertProcessor); ok {
  379. session.afterInsertBeans[bean] = nil
  380. }
  381. }
  382. }
  383. cleanupProcessorsClosures(&session.afterClosures) // cleanup after used
  384. }
  385. // for postgres, many of them didn't implement lastInsertId, so we should
  386. // implemented it ourself.
  387. if session.engine.dialect.DBType() == core.ORACLE && len(table.AutoIncrement) > 0 {
  388. res, err := session.queryBytes("select seq_atable.currval from dual", args...)
  389. if err != nil {
  390. return 0, err
  391. }
  392. defer handleAfterInsertProcessorFunc(bean)
  393. session.cacheInsert(tableName)
  394. if table.Version != "" && session.statement.checkVersion {
  395. verValue, err := table.VersionColumn().ValueOf(bean)
  396. if err != nil {
  397. session.engine.logger.Error(err)
  398. } else if verValue.IsValid() && verValue.CanSet() {
  399. session.incrVersionFieldValue(verValue)
  400. }
  401. }
  402. if len(res) < 1 {
  403. return 0, errors.New("insert no error but not returned id")
  404. }
  405. idByte := res[0][table.AutoIncrement]
  406. id, err := strconv.ParseInt(string(idByte), 10, 64)
  407. if err != nil || id <= 0 {
  408. return 1, err
  409. }
  410. aiValue, err := table.AutoIncrColumn().ValueOf(bean)
  411. if err != nil {
  412. session.engine.logger.Error(err)
  413. }
  414. if aiValue == nil || !aiValue.IsValid() || !aiValue.CanSet() {
  415. return 1, nil
  416. }
  417. aiValue.Set(int64ToIntValue(id, aiValue.Type()))
  418. return 1, nil
  419. } else if len(table.AutoIncrement) > 0 && (session.engine.dialect.DBType() == core.POSTGRES || session.engine.dialect.DBType() == core.MSSQL) {
  420. res, err := session.queryBytes(sqlStr, args...)
  421. if err != nil {
  422. return 0, err
  423. }
  424. defer handleAfterInsertProcessorFunc(bean)
  425. session.cacheInsert(tableName)
  426. if table.Version != "" && session.statement.checkVersion {
  427. verValue, err := table.VersionColumn().ValueOf(bean)
  428. if err != nil {
  429. session.engine.logger.Error(err)
  430. } else if verValue.IsValid() && verValue.CanSet() {
  431. session.incrVersionFieldValue(verValue)
  432. }
  433. }
  434. if len(res) < 1 {
  435. return 0, errors.New("insert successfully but not returned id")
  436. }
  437. idByte := res[0][table.AutoIncrement]
  438. id, err := strconv.ParseInt(string(idByte), 10, 64)
  439. if err != nil || id <= 0 {
  440. return 1, err
  441. }
  442. aiValue, err := table.AutoIncrColumn().ValueOf(bean)
  443. if err != nil {
  444. session.engine.logger.Error(err)
  445. }
  446. if aiValue == nil || !aiValue.IsValid() || !aiValue.CanSet() {
  447. return 1, nil
  448. }
  449. aiValue.Set(int64ToIntValue(id, aiValue.Type()))
  450. return 1, nil
  451. } else {
  452. res, err := session.exec(sqlStr, args...)
  453. if err != nil {
  454. session.engine.logger.Error(err)
  455. return 0, err
  456. }
  457. defer handleAfterInsertProcessorFunc(bean)
  458. session.cacheInsert(tableName)
  459. if table.Version != "" && session.statement.checkVersion {
  460. verValue, err := table.VersionColumn().ValueOf(bean)
  461. if err != nil {
  462. session.engine.logger.Error(err)
  463. } else if verValue.IsValid() && verValue.CanSet() {
  464. session.incrVersionFieldValue(verValue)
  465. }
  466. }
  467. if table.AutoIncrement == "" {
  468. return res.RowsAffected()
  469. }
  470. var id int64
  471. id, err = res.LastInsertId()
  472. if err != nil || id <= 0 {
  473. return res.RowsAffected()
  474. }
  475. aiValue, err := table.AutoIncrColumn().ValueOf(bean)
  476. if err != nil {
  477. session.engine.logger.Error(err)
  478. }
  479. if aiValue == nil || !aiValue.IsValid() || !aiValue.CanSet() {
  480. return res.RowsAffected()
  481. }
  482. aiValue.Set(int64ToIntValue(id, aiValue.Type()))
  483. return res.RowsAffected()
  484. }
  485. }
  486. // InsertOne insert only one struct into database as a record.
  487. // The in parameter bean must a struct or a point to struct. The return
  488. // parameter is inserted and error
  489. func (session *Session) InsertOne(bean interface{}) (int64, error) {
  490. if session.isAutoClose {
  491. defer session.Close()
  492. }
  493. return session.innerInsert(bean)
  494. }
  495. func (session *Session) cacheInsert(table string) error {
  496. if !session.statement.UseCache {
  497. return nil
  498. }
  499. cacher := session.engine.getCacher(table)
  500. if cacher == nil {
  501. return nil
  502. }
  503. session.engine.logger.Debug("[cache] clear sql:", table)
  504. cacher.ClearIds(table)
  505. return nil
  506. }
  507. // genInsertColumns generates insert needed columns
  508. func (session *Session) genInsertColumns(bean interface{}) ([]string, []interface{}, error) {
  509. table := session.statement.RefTable
  510. colNames := make([]string, 0, len(table.ColumnsSeq()))
  511. args := make([]interface{}, 0, len(table.ColumnsSeq()))
  512. for _, col := range table.Columns() {
  513. if col.MapType == core.ONLYFROMDB {
  514. continue
  515. }
  516. if col.IsDeleted {
  517. continue
  518. }
  519. if session.statement.omitColumnMap.contain(col.Name) {
  520. continue
  521. }
  522. if len(session.statement.columnMap) > 0 && !session.statement.columnMap.contain(col.Name) {
  523. continue
  524. }
  525. if _, ok := session.statement.incrColumns[col.Name]; ok {
  526. continue
  527. } else if _, ok := session.statement.decrColumns[col.Name]; ok {
  528. continue
  529. }
  530. fieldValuePtr, err := col.ValueOf(bean)
  531. if err != nil {
  532. return nil, nil, err
  533. }
  534. fieldValue := *fieldValuePtr
  535. if col.IsAutoIncrement {
  536. switch fieldValue.Type().Kind() {
  537. case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int, reflect.Int64:
  538. if fieldValue.Int() == 0 {
  539. continue
  540. }
  541. case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint, reflect.Uint64:
  542. if fieldValue.Uint() == 0 {
  543. continue
  544. }
  545. case reflect.String:
  546. if len(fieldValue.String()) == 0 {
  547. continue
  548. }
  549. case reflect.Ptr:
  550. if fieldValue.Pointer() == 0 {
  551. continue
  552. }
  553. }
  554. }
  555. // !evalphobia! set fieldValue as nil when column is nullable and zero-value
  556. if _, ok := getFlagForColumn(session.statement.nullableMap, col); ok {
  557. if col.Nullable && isZero(fieldValue.Interface()) {
  558. var nilValue *int
  559. fieldValue = reflect.ValueOf(nilValue)
  560. }
  561. }
  562. if (col.IsCreated || col.IsUpdated) && session.statement.UseAutoTime /*&& isZero(fieldValue.Interface())*/ {
  563. // if time is non-empty, then set to auto time
  564. val, t := session.engine.nowTime(col)
  565. args = append(args, val)
  566. var colName = col.Name
  567. session.afterClosures = append(session.afterClosures, func(bean interface{}) {
  568. col := table.GetColumn(colName)
  569. setColumnTime(bean, col, t)
  570. })
  571. } else if col.IsVersion && session.statement.checkVersion {
  572. args = append(args, 1)
  573. } else {
  574. arg, err := session.value2Interface(col, fieldValue)
  575. if err != nil {
  576. return colNames, args, err
  577. }
  578. args = append(args, arg)
  579. }
  580. colNames = append(colNames, col.Name)
  581. }
  582. return colNames, args, nil
  583. }
  584. func (session *Session) insertMapInterface(m map[string]interface{}) (int64, error) {
  585. if len(m) == 0 {
  586. return 0, ErrParamsType
  587. }
  588. var columns = make([]string, 0, len(m))
  589. for k := range m {
  590. columns = append(columns, k)
  591. }
  592. sort.Strings(columns)
  593. qm := strings.Repeat("?,", len(columns))
  594. qm = "(" + qm[:len(qm)-1] + ")"
  595. tableName := session.statement.TableName()
  596. if len(tableName) <= 0 {
  597. return 0, ErrTableNotFound
  598. }
  599. var sql = fmt.Sprintf("INSERT INTO %s (`%s`) VALUES %s", session.engine.Quote(tableName), strings.Join(columns, "`,`"), qm)
  600. var args = make([]interface{}, 0, len(m))
  601. for _, colName := range columns {
  602. args = append(args, m[colName])
  603. }
  604. if err := session.cacheInsert(tableName); err != nil {
  605. return 0, err
  606. }
  607. res, err := session.exec(sql, args...)
  608. if err != nil {
  609. session.engine.logger.Error(err)
  610. return 0, err
  611. }
  612. affected, err := res.RowsAffected()
  613. if err != nil {
  614. return 0, err
  615. }
  616. return affected, nil
  617. }
  618. func (session *Session) insertMapString(m map[string]string) (int64, error) {
  619. if len(m) == 0 {
  620. return 0, ErrParamsType
  621. }
  622. var columns = make([]string, 0, len(m))
  623. for k := range m {
  624. columns = append(columns, k)
  625. }
  626. sort.Strings(columns)
  627. qm := strings.Repeat("?,", len(columns))
  628. qm = "(" + qm[:len(qm)-1] + ")"
  629. tableName := session.statement.TableName()
  630. if len(tableName) <= 0 {
  631. return 0, ErrTableNotFound
  632. }
  633. var sql = fmt.Sprintf("INSERT INTO %s (`%s`) VALUES %s", session.engine.Quote(tableName), strings.Join(columns, "`,`"), qm)
  634. var args = make([]interface{}, 0, len(m))
  635. for _, colName := range columns {
  636. args = append(args, m[colName])
  637. }
  638. if err := session.cacheInsert(tableName); err != nil {
  639. return 0, err
  640. }
  641. res, err := session.exec(sql, args...)
  642. if err != nil {
  643. session.engine.logger.Error(err)
  644. return 0, err
  645. }
  646. affected, err := res.RowsAffected()
  647. if err != nil {
  648. return 0, err
  649. }
  650. return affected, nil
  651. }