georgysavva / scany

Library for scanning data from a database into Go structs and more
MIT License
1.23k stars 67 forks source link

Do not Close rows after Scan #114

Closed dmzkrsk closed 8 months ago

dmzkrsk commented 12 months ago

I use this lib with a mssql database. MSSQL has ability to return multiple sets of data in a single query (example).

The problem is, when I use scany to handle sqlexp.MsgNext message to read data (the example above does not use it and works fine), it closes Rows, that are passed into, and rows.NextResultSet() returns false (see sqlexp.MsgNextResultSet in the example above).

I cloned the library and commented out rows.Close lines and now my local test works fine.

Also, a simple wrapper like this also works

type rowsNoClose struct {
  dbscan.Rows
}

func (r rowsNoClose) Close() error {
    return nil
}

Is it possible to implement an ability to skip closing rows right in the library?

georgysavva commented 11 months ago

Hi, thanks for opening this issue!

Only the high-level methods.ScanAll(), .ScanOne(), .Select(), and .Get() close the rows after processing them. I believe it's desirable in almost all scenarios, and I don't want to complicate the API to allow an optional parameter to disable that behavior.

In your case, you just need to go one level lower and use a slightly different scany API. Instead of using the methods described above that iterate through the rows for you, you should implement the for loop yourself and call the RowScanner.Scan() method. By doing that, you are in full control of when the iteration stops and rows are closed. Here is an example of this approach: https://pkg.go.dev/github.com/georgysavva/scany/v2@v2.0.0/sqlscan#example-RowScanner.

Let me know if you have any questions!

georgysavva commented 6 months ago

@dmzkrsk The feature you asked for is now available in the latest release v2.1.0. Here is the new API: https://pkg.go.dev/github.com/georgysavva/scany/v2@v2.1.0/sqlscan#ScanAllSets