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(&currentRows.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  }