THIS IS A TEST INSTANCE ONLY! REPOSITORIES CAN BE DELETED AT ANY TIME!

You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

879 lines
22KB

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