Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"System.InvalidOperationException: DataReader has been closed" with Sql.map #28

Open
haf opened this issue Feb 20, 2015 · 12 comments
Open
Labels

Comments

@haf
Copy link
Contributor

haf commented Feb 20, 2015

Is there any nice ways of reading a sequence of mapped results lazily after opening a data reader, without getting 'System.InvalidOperationException: DataReader has been closed`?

@mausch
Copy link
Owner

mausch commented Feb 21, 2015

Are you using Seq.ofDataReader?

@haf
Copy link
Contributor Author

haf commented Feb 21, 2015

No, just Sql.map and Sql.map, but Seq.ofDataReader is it then 👍

@mausch
Copy link
Owner

mausch commented Feb 21, 2015

Well, Sql.map is just a composition of Sql.ofDataReader and Seq.map, which means you're already using Sql.ofDataReader... Could you post a failing test for that InvalidOperationException?

@haf
Copy link
Contributor Author

haf commented Feb 21, 2015

Probably, give me a while to fix it though; we're a bit late right now, so I need to focus on the release -- but any help fixing the connection error would be very appreciated =)

@haf haf changed the title Question: read sequence lazyily after opening it? "System.InvalidOperationException: DataReader has been closed" with Sql.map Feb 21, 2015
@mausch mausch added the bug label Feb 26, 2015
@haf
Copy link
Contributor Author

haf commented Feb 26, 2015

Ok, ran into this again, let's get you a repro.

@haf
Copy link
Contributor Author

haf commented Feb 26, 2015

    testCase "/28/System.InvalidOperationException: DataReader has been closed" <| fun _ ->
      let first (xs : _ seq) : _ option =
        if Seq.isEmpty xs then None else Seq.head xs |> Some
      let mapper (r : #IDataRecord) =
        r?required_field |> Option.get : string
      let mgr, P, tx = prepare ()
      Sql.execNonQuery mgr
                       "insert into some_table(id, required_field) values (@id, @rf)"
                       [ P("@id", "dead")
                         P("@rf", "beaf") ] |> ignore
      Sql.execReaderWith mgr
                         "select * from some_table" [] mapper
      |> first
      |> fun o ->
        Assert.Equal("has value", Some "beaf", o)

@haf
Copy link
Contributor Author

haf commented Apr 29, 2015

This bug hasn't been fixed yet.

@haf
Copy link
Contributor Author

haf commented Mar 31, 2016

Still there.

@mausch
Copy link
Owner

mausch commented Mar 31, 2016

Can you post the code for prepare in your previous example?

@haf
Copy link
Contributor Author

haf commented Apr 1, 2016

module ReCQ.SQLite.Tests.ExternalBugs

open Fuchu
open NodaTime
open System
open System.Data
open ReCQ.SQLite
open ReCQ.SQLite.Tests

let prepare conn mgr tableName =
  let createDDL = (sprintf "CREATE TABLE %s (id TEXT CONSTRAINT pk_id PRIMARY KEY, required_field TEXT NOT NULL)" tableName)
  Sql.execNonQuery mgr createDDL [] |> ignore
  Sql.Parameter.make, Tx.TransactionBuilder()

[<Tests>]
let tests =
  testList "https://github.com/mausch/FsSql/issues" [
    testCase "/23/'No connection associated with' ... nested with outer error" <| fun conn mgr ->
      let P, tx = prepare conn mgr "someTable"

      let nested (f_cont : Sql.ConnectionManager -> _) =
        tx {
          let! ret = f_cont
          return ret
        }
      let inner =
        tx {
          do! Tx.execNonQueryi "insert into someTable(id) values(@id)"
                               [ P("@id", "290345632deadbeef") ]
        }

      match nested inner mgr with
      | Tx.Commit _ ->
        ()

      | Tx.Failed (Platform.SQLiteException Platform.SQLiteConstraintErrorCode) ->
        ()

      | Tx.Failed e ->
        Tests.failtestf "other error: %s" e.Message

      | Tx.Rollback _ ->
        ()

    testCase "/28/System.InvalidOperationException: DataReader has been closed" <| fun conn mgr ->
      Tests.skiptest "still an issue 2015-04-29"
      use conn = SQLiteConn.openConnType InMemory
      let first (xs : _ seq) : _ option = if Seq.isEmpty xs then None else Seq.head xs |> Some
      let mapper (r : #IDataRecord)     = r?required_field |> Option.get : string
      let P, tx = prepare conn mgr "anotherTable"
      let rows =
        Sql.execNonQuery mgr
                         "insert into anotherTable(id, required_field) values (@id, @rf)"
                         [ P("@id", "dead")
                           P("@rf", "beaf") ]
      Assert.Equal("rows eq", 1, rows)
      Sql.execReaderWith mgr "select * from anotherTable" [] mapper
      |> first
      |> fun o -> Assert.Equal("has value", Some "beaf", o)
  ]

@czifro
Copy link

czifro commented May 8, 2018

Is this still a bug?

@haf
Copy link
Contributor Author

haf commented May 8, 2018

Yes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants