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