mausch / FsSql

Functional wrapper around ADO.NET for F#
https://www.openhub.net/p/FsSql
Apache License 2.0
67 stars 15 forks source link

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

Open haf opened 9 years ago

haf commented 9 years ago

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 commented 9 years ago

Are you using Seq.ofDataReader?

haf commented 9 years ago

No, just Sql.map and Sql.map, but Seq.ofDataReader is it then :+1:

mausch commented 9 years ago

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 commented 9 years ago

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 commented 9 years ago

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

haf commented 9 years ago
    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 commented 9 years ago

This bug hasn't been fixed yet.

haf commented 8 years ago

Still there.

mausch commented 8 years ago

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

haf commented 8 years ago
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 commented 6 years ago

Is this still a bug?

haf commented 6 years ago

Yes