t.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522
  1. /*
  2. * Copyright (c) 2000-2018, 达梦数据库有限公司.
  3. * All rights reserved.
  4. */
  5. package dm
  6. import (
  7. "database/sql/driver"
  8. "io"
  9. "reflect"
  10. "strings"
  11. )
  12. type DmRows struct {
  13. filterable
  14. CurrentRows *innerRows
  15. finish func()
  16. }
  17. func (r *DmRows) Columns() []string {
  18. if err := r.CurrentRows.dmStmt.checkClosed(); err != nil {
  19. return nil
  20. }
  21. if len(r.filterChain.filters) == 0 {
  22. return r.columns()
  23. }
  24. return r.filterChain.reset().DmRowsColumns(r)
  25. }
  26. func (r *DmRows) Close() error {
  27. if err := r.CurrentRows.dmStmt.checkClosed(); err != nil {
  28. return err
  29. }
  30. if len(r.filterChain.filters) == 0 {
  31. return r.close()
  32. }
  33. return r.filterChain.reset().DmRowsClose(r)
  34. }
  35. func (r *DmRows) Next(dest []driver.Value) error {
  36. if err := r.CurrentRows.dmStmt.checkClosed(); err != nil {
  37. return err
  38. }
  39. if len(r.filterChain.filters) == 0 {
  40. return r.next(dest)
  41. }
  42. return r.filterChain.reset().DmRowsNext(r, dest)
  43. }
  44. func (r *DmRows) HasNextResultSet() bool {
  45. if err := r.CurrentRows.dmStmt.checkClosed(); err != nil {
  46. return false
  47. }
  48. if len(r.filterChain.filters) == 0 {
  49. return r.hasNextResultSet()
  50. }
  51. return r.filterChain.reset().DmRowsHasNextResultSet(r)
  52. }
  53. func (r *DmRows) NextResultSet() error {
  54. if err := r.CurrentRows.dmStmt.checkClosed(); err != nil {
  55. return err
  56. }
  57. if len(r.filterChain.filters) == 0 {
  58. return r.nextResultSet()
  59. }
  60. return r.filterChain.reset().DmRowsNextResultSet(r)
  61. }
  62. func (r *DmRows) ColumnTypeScanType(index int) reflect.Type {
  63. if err := r.CurrentRows.dmStmt.checkClosed(); err != nil {
  64. return nil
  65. }
  66. if len(r.filterChain.filters) == 0 {
  67. return r.columnTypeScanType(index)
  68. }
  69. return r.filterChain.reset().DmRowsColumnTypeScanType(r, index)
  70. }
  71. func (r *DmRows) ColumnTypeDatabaseTypeName(index int) string {
  72. if err := r.CurrentRows.dmStmt.checkClosed(); err != nil {
  73. return ""
  74. }
  75. if len(r.filterChain.filters) == 0 {
  76. return r.columnTypeDatabaseTypeName(index)
  77. }
  78. return r.filterChain.reset().DmRowsColumnTypeDatabaseTypeName(r, index)
  79. }
  80. func (r *DmRows) ColumnTypeLength(index int) (length int64, ok bool) {
  81. if err := r.CurrentRows.dmStmt.checkClosed(); err != nil {
  82. return -1, false
  83. }
  84. if len(r.filterChain.filters) == 0 {
  85. return r.columnTypeLength(index)
  86. }
  87. return r.filterChain.reset().DmRowsColumnTypeLength(r, index)
  88. }
  89. func (r *DmRows) ColumnTypeNullable(index int) (nullable, ok bool) {
  90. if err := r.CurrentRows.dmStmt.checkClosed(); err != nil {
  91. return false, false
  92. }
  93. if len(r.filterChain.filters) == 0 {
  94. return r.columnTypeNullable(index)
  95. }
  96. return r.filterChain.reset().DmRowsColumnTypeNullable(r, index)
  97. }
  98. func (r *DmRows) ColumnTypePrecisionScale(index int) (precision, scale int64, ok bool) {
  99. if err := r.CurrentRows.dmStmt.checkClosed(); err != nil {
  100. return -1, -1, false
  101. }
  102. if len(r.filterChain.filters) == 0 {
  103. return r.columnTypePrecisionScale(index)
  104. }
  105. return r.filterChain.reset().DmRowsColumnTypePrecisionScale(r, index)
  106. }
  107. func (dest *DmRows) Scan(src interface{}) error {
  108. switch src := src.(type) {
  109. case nil:
  110. *dest = *new(DmRows)
  111. return nil
  112. case *DmRows:
  113. *dest = *src
  114. return nil
  115. default:
  116. return UNSUPPORTED_SCAN
  117. }
  118. }
  119. func (rows *DmRows) columns() []string {
  120. return rows.CurrentRows.Columns()
  121. }
  122. func (rows *DmRows) close() error {
  123. if f := rows.finish; f != nil {
  124. f()
  125. rows.finish = nil
  126. }
  127. return rows.CurrentRows.Close()
  128. }
  129. func (rows *DmRows) next(dest []driver.Value) error {
  130. return rows.CurrentRows.Next(dest)
  131. }
  132. func (rows *DmRows) hasNextResultSet() bool {
  133. return rows.CurrentRows.HasNextResultSet()
  134. }
  135. func (rows *DmRows) nextResultSet() error {
  136. return rows.CurrentRows.NextResultSet()
  137. }
  138. func (rows *DmRows) columnTypeScanType(index int) reflect.Type {
  139. return rows.CurrentRows.ColumnTypeScanType(index)
  140. }
  141. func (rows *DmRows) columnTypeDatabaseTypeName(index int) string {
  142. return rows.CurrentRows.ColumnTypeDatabaseTypeName(index)
  143. }
  144. func (rows *DmRows) columnTypeLength(index int) (length int64, ok bool) {
  145. return rows.CurrentRows.ColumnTypeLength(index)
  146. }
  147. func (rows *DmRows) columnTypeNullable(index int) (nullable, ok bool) {
  148. return rows.CurrentRows.ColumnTypeNullable(index)
  149. }
  150. func (rows *DmRows) columnTypePrecisionScale(index int) (precision, scale int64, ok bool) {
  151. return rows.CurrentRows.ColumnTypePrecisionScale(index)
  152. }
  153. type innerRows struct {
  154. dmStmt *DmStatement
  155. id int16
  156. columns []column
  157. datas [][][]byte
  158. datasOffset int
  159. datasStartPos int64
  160. currentPos int64
  161. totalRowCount int64
  162. fetchSize int
  163. sizeOfRow int
  164. isBdta bool
  165. nextExecInfo *execRetInfo
  166. next *innerRows
  167. dmRows *DmRows
  168. closed bool
  169. }
  170. func (innerRows *innerRows) checkClosed() error {
  171. if innerRows.closed {
  172. return ECGO_RESULTSET_CLOSED.throw()
  173. }
  174. return nil
  175. }
  176. func (innerRows *innerRows) Columns() []string {
  177. if err := innerRows.checkClosed(); err != nil {
  178. return nil
  179. }
  180. columnNames := make([]string, len(innerRows.columns))
  181. nameCase := innerRows.dmStmt.dmConn.dmConnector.columnNameCase
  182. for i, column := range innerRows.columns {
  183. if nameCase == COLUMN_NAME_NATURAL_CASE {
  184. columnNames[i] = column.name
  185. } else if nameCase == COLUMN_NAME_UPPER_CASE {
  186. columnNames[i] = strings.ToUpper(column.name)
  187. } else if nameCase == COLUMN_NAME_LOWER_CASE {
  188. columnNames[i] = strings.ToLower(column.name)
  189. } else {
  190. columnNames[i] = column.name
  191. }
  192. }
  193. return columnNames
  194. }
  195. func (innerRows *innerRows) Close() error {
  196. if innerRows.closed {
  197. return nil
  198. }
  199. innerRows.closed = true
  200. if innerRows.dmStmt.innerUsed {
  201. innerRows.dmStmt.close()
  202. } else {
  203. delete(innerRows.dmStmt.rsMap, innerRows.id)
  204. }
  205. innerRows.dmStmt = nil
  206. return nil
  207. }
  208. func (innerRows *innerRows) Next(dest []driver.Value) error {
  209. err := innerRows.checkClosed()
  210. if err != nil {
  211. return err
  212. }
  213. if innerRows.totalRowCount == 0 || innerRows.currentPos >= innerRows.totalRowCount {
  214. return io.EOF
  215. }
  216. if innerRows.currentPos+1 == innerRows.totalRowCount {
  217. innerRows.currentPos++
  218. innerRows.datasOffset++
  219. return io.EOF
  220. }
  221. if innerRows.currentPos+1 < innerRows.datasStartPos || innerRows.currentPos+1 >= innerRows.datasStartPos+int64(len(innerRows.datas)) {
  222. if innerRows.fetchData(innerRows.currentPos + 1) {
  223. innerRows.currentPos++
  224. err := innerRows.getRowData(dest)
  225. if err != nil {
  226. return err
  227. }
  228. } else {
  229. innerRows.currentPos++
  230. innerRows.datasOffset++
  231. return io.EOF
  232. }
  233. } else {
  234. innerRows.currentPos++
  235. innerRows.datasOffset++
  236. err := innerRows.getRowData(dest)
  237. if err != nil {
  238. return err
  239. }
  240. }
  241. return nil
  242. }
  243. func (innerRows *innerRows) HasNextResultSet() bool {
  244. err := innerRows.checkClosed()
  245. if err != nil {
  246. return false
  247. }
  248. if innerRows.nextExecInfo != nil {
  249. return innerRows.nextExecInfo.hasResultSet
  250. }
  251. innerRows.nextExecInfo, err = innerRows.dmStmt.dmConn.Access.Dm_build_814(innerRows.dmStmt, 0)
  252. if err != nil {
  253. return false
  254. }
  255. if innerRows.nextExecInfo.hasResultSet {
  256. innerRows.next = newInnerRows(innerRows.id+1, innerRows.dmStmt, innerRows.nextExecInfo)
  257. return true
  258. }
  259. return false
  260. }
  261. func (innerRows *innerRows) NextResultSet() error {
  262. err := innerRows.checkClosed()
  263. if err != nil {
  264. return err
  265. }
  266. if innerRows.nextExecInfo == nil {
  267. innerRows.HasNextResultSet()
  268. }
  269. if innerRows.next == nil {
  270. return io.EOF
  271. }
  272. innerRows.next.dmRows = innerRows.dmRows
  273. innerRows.dmRows.CurrentRows = innerRows.next
  274. return nil
  275. }
  276. func (innerRows *innerRows) ColumnTypeScanType(index int) reflect.Type {
  277. if err := innerRows.checkClosed(); err != nil {
  278. return nil
  279. }
  280. if column := innerRows.checkIndex(index); column != nil {
  281. return column.ScanType()
  282. }
  283. return nil
  284. }
  285. func (innerRows *innerRows) ColumnTypeDatabaseTypeName(index int) string {
  286. if err := innerRows.checkClosed(); err != nil {
  287. return ""
  288. }
  289. if column := innerRows.checkIndex(index); column != nil {
  290. return column.typeName
  291. }
  292. return ""
  293. }
  294. func (innerRows *innerRows) ColumnTypeLength(index int) (length int64, ok bool) {
  295. if err := innerRows.checkClosed(); err != nil {
  296. return 0, false
  297. }
  298. if column := innerRows.checkIndex(index); column != nil {
  299. return column.Length()
  300. }
  301. return 0, false
  302. }
  303. func (innerRows *innerRows) ColumnTypeNullable(index int) (nullable, ok bool) {
  304. if err := innerRows.checkClosed(); err != nil {
  305. return false, false
  306. }
  307. if column := innerRows.checkIndex(index); column != nil {
  308. return column.nullable, true
  309. }
  310. return false, false
  311. }
  312. func (innerRows *innerRows) ColumnTypePrecisionScale(index int) (precision, scale int64, ok bool) {
  313. if err := innerRows.checkClosed(); err != nil {
  314. return 0, 0, false
  315. }
  316. if column := innerRows.checkIndex(index); column != nil {
  317. return column.PrecisionScale()
  318. }
  319. return 0, 0, false
  320. }
  321. func newDmRows(currentRows *innerRows) *DmRows {
  322. dr := new(DmRows)
  323. dr.resetFilterable(&currentRows.dmStmt.filterable)
  324. dr.CurrentRows = currentRows
  325. dr.idGenerator = dmRowsIDGenerator
  326. currentRows.dmRows = dr
  327. return dr
  328. }
  329. func newInnerRows(id int16, stmt *DmStatement, execInfo *execRetInfo) *innerRows {
  330. rows := new(innerRows)
  331. rows.id = id
  332. rows.dmStmt = stmt
  333. rows.columns = stmt.columns
  334. rows.datas = execInfo.rsDatas
  335. rows.totalRowCount = execInfo.updateCount
  336. rows.isBdta = execInfo.rsBdta
  337. rows.fetchSize = stmt.fetchSize
  338. if len(execInfo.rsDatas) == 0 {
  339. rows.sizeOfRow = 0
  340. } else {
  341. rows.sizeOfRow = execInfo.rsSizeof / len(execInfo.rsDatas)
  342. }
  343. rows.currentPos = -1
  344. rows.datasOffset = -1
  345. rows.datasStartPos = 0
  346. rows.nextExecInfo = nil
  347. rows.next = nil
  348. if rows.dmStmt.rsMap != nil {
  349. rows.dmStmt.rsMap[rows.id] = rows
  350. }
  351. if stmt.dmConn.dmConnector.enRsCache && execInfo.rsCacheOffset > 0 &&
  352. int64(len(execInfo.rsDatas)) == execInfo.updateCount {
  353. rp.put(stmt, stmt.nativeSql, execInfo)
  354. }
  355. return rows
  356. }
  357. func newLocalInnerRows(stmt *DmStatement, columns []column, rsDatas [][][]byte) *innerRows {
  358. rows := new(innerRows)
  359. rows.id = 0
  360. rows.dmStmt = stmt
  361. rows.fetchSize = stmt.fetchSize
  362. if columns == nil {
  363. rows.columns = make([]column, 0)
  364. } else {
  365. rows.columns = columns
  366. }
  367. if rsDatas == nil {
  368. rows.datas = make([][][]byte, 0)
  369. rows.totalRowCount = 0
  370. } else {
  371. rows.datas = rsDatas
  372. rows.totalRowCount = int64(len(rsDatas))
  373. }
  374. rows.isBdta = false
  375. return rows
  376. }
  377. func (innerRows *innerRows) checkIndex(index int) *column {
  378. if index < 0 || index > len(innerRows.columns)-1 {
  379. return nil
  380. }
  381. return &innerRows.columns[index]
  382. }
  383. func (innerRows *innerRows) fetchData(startPos int64) bool {
  384. execInfo, err := innerRows.dmStmt.dmConn.Access.Dm_build_821(innerRows, startPos)
  385. if err != nil {
  386. return false
  387. }
  388. innerRows.totalRowCount = execInfo.updateCount
  389. if execInfo.rsDatas != nil {
  390. innerRows.datas = execInfo.rsDatas
  391. innerRows.datasStartPos = startPos
  392. innerRows.datasOffset = 0
  393. return true
  394. }
  395. return false
  396. }
  397. func (innerRows *innerRows) getRowData(dest []driver.Value) (err error) {
  398. for i, column := range innerRows.columns {
  399. if i <= len(dest)-1 {
  400. if column.colType == CURSOR {
  401. var tmpExecInfo *execRetInfo
  402. tmpExecInfo, err = innerRows.dmStmt.dmConn.Access.Dm_build_814(innerRows.dmStmt, 1)
  403. if err != nil {
  404. return err
  405. }
  406. if tmpExecInfo.hasResultSet {
  407. dest[i] = newDmRows(newInnerRows(innerRows.id+1, innerRows.dmStmt, tmpExecInfo))
  408. } else {
  409. dest[i] = nil
  410. }
  411. continue
  412. }
  413. dest[i], err = column.getColumnData(innerRows.datas[innerRows.datasOffset][i+1], innerRows.dmStmt.dmConn)
  414. innerRows.columns[i].isBdta = innerRows.isBdta
  415. if err != nil {
  416. return err
  417. }
  418. } else {
  419. return nil
  420. }
  421. }
  422. return nil
  423. }
  424. func (innerRows *innerRows) getRowCount() int64 {
  425. innerRows.checkClosed()
  426. if innerRows.totalRowCount == INT64_MAX {
  427. return -1
  428. }
  429. return innerRows.totalRowCount
  430. }