gitee.com/chunanyong/dm@v1.8.12/t.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 (dest *DmRows) Scan(src interface{}) error {
   121  	switch src := src.(type) {
   122  	case nil:
   123  		*dest = *new(DmRows)
   124  		return nil
   125  	case *DmRows:
   126  		*dest = *src
   127  		return nil
   128  	default:
   129  		return UNSUPPORTED_SCAN
   130  	}
   131  }
   132  
   133  func (rows *DmRows) columns() []string {
   134  	return rows.CurrentRows.Columns()
   135  }
   136  
   137  func (rows *DmRows) close() error {
   138  	if f := rows.finish; f != nil {
   139  		f()
   140  		rows.finish = nil
   141  	}
   142  	return rows.CurrentRows.Close()
   143  }
   144  
   145  func (rows *DmRows) next(dest []driver.Value) error {
   146  	return rows.CurrentRows.Next(dest)
   147  }
   148  
   149  func (rows *DmRows) hasNextResultSet() bool {
   150  	return rows.CurrentRows.HasNextResultSet()
   151  }
   152  
   153  func (rows *DmRows) nextResultSet() error {
   154  	return rows.CurrentRows.NextResultSet()
   155  }
   156  
   157  func (rows *DmRows) columnTypeScanType(index int) reflect.Type {
   158  	return rows.CurrentRows.ColumnTypeScanType(index)
   159  }
   160  
   161  func (rows *DmRows) columnTypeDatabaseTypeName(index int) string {
   162  	return rows.CurrentRows.ColumnTypeDatabaseTypeName(index)
   163  }
   164  
   165  func (rows *DmRows) columnTypeLength(index int) (length int64, ok bool) {
   166  	return rows.CurrentRows.ColumnTypeLength(index)
   167  }
   168  
   169  func (rows *DmRows) columnTypeNullable(index int) (nullable, ok bool) {
   170  	return rows.CurrentRows.ColumnTypeNullable(index)
   171  }
   172  
   173  func (rows *DmRows) columnTypePrecisionScale(index int) (precision, scale int64, ok bool) {
   174  	return rows.CurrentRows.ColumnTypePrecisionScale(index)
   175  }
   176  
   177  type innerRows struct {
   178  	dmStmt *DmStatement
   179  
   180  	id int16
   181  
   182  	columns []column
   183  
   184  	datas [][][]byte
   185  
   186  	datasOffset int
   187  
   188  	datasStartPos int64
   189  
   190  	currentPos int64
   191  
   192  	totalRowCount int64
   193  
   194  	fetchSize int
   195  
   196  	sizeOfRow int
   197  
   198  	isBdta bool
   199  
   200  	nextExecInfo *execRetInfo
   201  
   202  	next *innerRows
   203  
   204  	dmRows *DmRows
   205  
   206  	closed bool
   207  }
   208  
   209  func (innerRows *innerRows) checkClosed() error {
   210  	if innerRows.closed {
   211  		return ECGO_RESULTSET_CLOSED.throw()
   212  	}
   213  	return nil
   214  }
   215  
   216  func (innerRows *innerRows) Columns() []string {
   217  	if err := innerRows.checkClosed(); err != nil {
   218  		return nil
   219  	}
   220  
   221  	columnNames := make([]string, len(innerRows.columns))
   222  	nameCase := innerRows.dmStmt.dmConn.dmConnector.columnNameCase
   223  
   224  	for i, column := range innerRows.columns {
   225  		if nameCase == COLUMN_NAME_NATURAL_CASE {
   226  			columnNames[i] = column.name
   227  		} else if nameCase == COLUMN_NAME_UPPER_CASE {
   228  			columnNames[i] = strings.ToUpper(column.name)
   229  		} else if nameCase == COLUMN_NAME_LOWER_CASE {
   230  			columnNames[i] = strings.ToLower(column.name)
   231  		} else {
   232  			columnNames[i] = column.name
   233  		}
   234  	}
   235  
   236  	return columnNames
   237  }
   238  
   239  func (innerRows *innerRows) Close() error {
   240  	if innerRows.closed {
   241  		return nil
   242  	}
   243  
   244  	innerRows.closed = true
   245  
   246  	if innerRows.dmStmt.innerUsed {
   247  		innerRows.dmStmt.close()
   248  	} else {
   249  		delete(innerRows.dmStmt.rsMap, innerRows.id)
   250  	}
   251  
   252  	innerRows.dmStmt = nil
   253  
   254  	return nil
   255  }
   256  
   257  func (innerRows *innerRows) Next(dest []driver.Value) error {
   258  	err := innerRows.checkClosed()
   259  	if err != nil {
   260  		return err
   261  	}
   262  
   263  	if innerRows.totalRowCount == 0 || innerRows.currentPos >= innerRows.totalRowCount {
   264  		return io.EOF
   265  	}
   266  
   267  	if innerRows.currentPos+1 == innerRows.totalRowCount {
   268  		innerRows.currentPos++
   269  		innerRows.datasOffset++
   270  		return io.EOF
   271  	}
   272  
   273  	if innerRows.currentPos+1 < innerRows.datasStartPos || innerRows.currentPos+1 >= innerRows.datasStartPos+int64(len(innerRows.datas)) {
   274  		if innerRows.fetchData(innerRows.currentPos + 1) {
   275  			innerRows.currentPos++
   276  			err := innerRows.getRowData(dest)
   277  			if err != nil {
   278  				return err
   279  			}
   280  		} else {
   281  			innerRows.currentPos++
   282  			innerRows.datasOffset++
   283  			return io.EOF
   284  		}
   285  	} else {
   286  		innerRows.currentPos++
   287  		innerRows.datasOffset++
   288  		err := innerRows.getRowData(dest)
   289  		if err != nil {
   290  			return err
   291  		}
   292  	}
   293  
   294  	return nil
   295  }
   296  
   297  func (innerRows *innerRows) HasNextResultSet() bool {
   298  	err := innerRows.checkClosed()
   299  	if err != nil {
   300  		return false
   301  	}
   302  
   303  	if innerRows.nextExecInfo != nil {
   304  		return innerRows.nextExecInfo.hasResultSet
   305  	}
   306  
   307  	innerRows.nextExecInfo, err = innerRows.dmStmt.dmConn.Access.Dm_build_1463(innerRows.dmStmt, 0)
   308  	if err != nil {
   309  		return false
   310  	}
   311  
   312  	if innerRows.nextExecInfo.hasResultSet {
   313  		innerRows.next = newInnerRows(innerRows.id+1, innerRows.dmStmt, innerRows.nextExecInfo)
   314  		return true
   315  	}
   316  
   317  	return false
   318  }
   319  
   320  func (innerRows *innerRows) NextResultSet() error {
   321  	err := innerRows.checkClosed()
   322  	if err != nil {
   323  		return err
   324  	}
   325  
   326  	if innerRows.nextExecInfo == nil {
   327  		innerRows.HasNextResultSet()
   328  	}
   329  
   330  	if innerRows.next == nil {
   331  		return io.EOF
   332  	}
   333  
   334  	innerRows.next.dmRows = innerRows.dmRows
   335  	innerRows.dmRows.CurrentRows = innerRows.next
   336  	return nil
   337  }
   338  
   339  func (innerRows *innerRows) ColumnTypeScanType(index int) reflect.Type {
   340  	if err := innerRows.checkClosed(); err != nil {
   341  		return nil
   342  	}
   343  	if column := innerRows.checkIndex(index); column != nil {
   344  		return column.ScanType()
   345  	}
   346  	return nil
   347  }
   348  
   349  func (innerRows *innerRows) ColumnTypeDatabaseTypeName(index int) string {
   350  	if err := innerRows.checkClosed(); err != nil {
   351  		return ""
   352  	}
   353  	if column := innerRows.checkIndex(index); column != nil {
   354  		return column.typeName
   355  	}
   356  	return ""
   357  }
   358  
   359  func (innerRows *innerRows) ColumnTypeLength(index int) (length int64, ok bool) {
   360  	if err := innerRows.checkClosed(); err != nil {
   361  		return 0, false
   362  	}
   363  	if column := innerRows.checkIndex(index); column != nil {
   364  		return column.Length()
   365  	}
   366  	return 0, false
   367  }
   368  
   369  func (innerRows *innerRows) ColumnTypeNullable(index int) (nullable, ok bool) {
   370  	if err := innerRows.checkClosed(); err != nil {
   371  		return false, false
   372  	}
   373  	if column := innerRows.checkIndex(index); column != nil {
   374  		return column.nullable, true
   375  	}
   376  	return false, false
   377  }
   378  
   379  func (innerRows *innerRows) ColumnTypePrecisionScale(index int) (precision, scale int64, ok bool) {
   380  	if err := innerRows.checkClosed(); err != nil {
   381  		return 0, 0, false
   382  	}
   383  	if column := innerRows.checkIndex(index); column != nil {
   384  		return column.PrecisionScale()
   385  	}
   386  	return 0, 0, false
   387  }
   388  
   389  func newDmRows(currentRows *innerRows) *DmRows {
   390  	dr := new(DmRows)
   391  	dr.resetFilterable(&currentRows.dmStmt.filterable)
   392  	dr.CurrentRows = currentRows
   393  	dr.idGenerator = dmRowsIDGenerator
   394  	currentRows.dmRows = dr
   395  	return dr
   396  }
   397  
   398  func newInnerRows(id int16, stmt *DmStatement, execInfo *execRetInfo) *innerRows {
   399  	rows := new(innerRows)
   400  	rows.id = id
   401  	rows.dmStmt = stmt
   402  	rows.columns = stmt.columns
   403  	rows.datas = execInfo.rsDatas
   404  	rows.totalRowCount = execInfo.updateCount
   405  	rows.isBdta = execInfo.rsBdta
   406  	rows.fetchSize = stmt.fetchSize
   407  
   408  	if len(execInfo.rsDatas) == 0 {
   409  		rows.sizeOfRow = 0
   410  	} else {
   411  		rows.sizeOfRow = execInfo.rsSizeof / len(execInfo.rsDatas)
   412  	}
   413  
   414  	rows.currentPos = -1
   415  	rows.datasOffset = -1
   416  	rows.datasStartPos = 0
   417  
   418  	rows.nextExecInfo = nil
   419  	rows.next = nil
   420  
   421  	if rows.dmStmt.rsMap != nil {
   422  		rows.dmStmt.rsMap[rows.id] = rows
   423  	}
   424  
   425  	if stmt.dmConn.dmConnector.enRsCache && execInfo.rsCacheOffset > 0 &&
   426  		int64(len(execInfo.rsDatas)) == execInfo.updateCount {
   427  		rp.put(stmt, stmt.nativeSql, execInfo)
   428  	}
   429  
   430  	return rows
   431  }
   432  
   433  func newLocalInnerRows(stmt *DmStatement, columns []column, rsDatas [][][]byte) *innerRows {
   434  	rows := new(innerRows)
   435  	rows.id = 0
   436  	rows.dmStmt = stmt
   437  	rows.fetchSize = stmt.fetchSize
   438  
   439  	if columns == nil {
   440  		rows.columns = make([]column, 0)
   441  	} else {
   442  		rows.columns = columns
   443  	}
   444  
   445  	if rsDatas == nil {
   446  		rows.datas = make([][][]byte, 0)
   447  		rows.totalRowCount = 0
   448  	} else {
   449  		rows.datas = rsDatas
   450  		rows.totalRowCount = int64(len(rsDatas))
   451  	}
   452  
   453  	rows.isBdta = false
   454  	return rows
   455  }
   456  
   457  func (innerRows *innerRows) checkIndex(index int) *column {
   458  	if index < 0 || index > len(innerRows.columns)-1 {
   459  		return nil
   460  	}
   461  
   462  	return &innerRows.columns[index]
   463  }
   464  
   465  func (innerRows *innerRows) fetchData(startPos int64) bool {
   466  	execInfo, err := innerRows.dmStmt.dmConn.Access.Dm_build_1470(innerRows, startPos)
   467  	if err != nil {
   468  		return false
   469  	}
   470  
   471  	innerRows.totalRowCount = execInfo.updateCount
   472  	if execInfo.rsDatas != nil {
   473  		innerRows.datas = execInfo.rsDatas
   474  		innerRows.datasStartPos = startPos
   475  		innerRows.datasOffset = 0
   476  		return true
   477  	}
   478  
   479  	return false
   480  }
   481  
   482  func (innerRows *innerRows) getRowData(dest []driver.Value) (err error) {
   483  	for i, column := range innerRows.columns {
   484  
   485  		if i <= len(dest)-1 {
   486  			if column.colType == CURSOR {
   487  				var tmpExecInfo *execRetInfo
   488  				tmpExecInfo, err = innerRows.dmStmt.dmConn.Access.Dm_build_1463(innerRows.dmStmt, 1)
   489  				if err != nil {
   490  					return err
   491  				}
   492  
   493  				if tmpExecInfo.hasResultSet {
   494  					dest[i] = newDmRows(newInnerRows(innerRows.id+1, innerRows.dmStmt, tmpExecInfo))
   495  				} else {
   496  					dest[i] = nil
   497  				}
   498  				continue
   499  			}
   500  
   501  			dest[i], err = column.getColumnData(innerRows.datas[innerRows.datasOffset][i+1], innerRows.dmStmt.dmConn)
   502  			innerRows.columns[i].isBdta = innerRows.isBdta
   503  			if err != nil {
   504  				return err
   505  			}
   506  		} else {
   507  			return nil
   508  		}
   509  	}
   510  
   511  	return nil
   512  }
   513  
   514  func (innerRows *innerRows) getRowCount() int64 {
   515  	innerRows.checkClosed()
   516  
   517  	if innerRows.totalRowCount == INT64_MAX {
   518  		return -1
   519  	}
   520  
   521  	return innerRows.totalRowCount
   522  }