Open haf opened 9 years ago
Are you using Seq.ofDataReader
?
No, just Sql.map and Sql.map, but Seq.ofDataReader is it then :+1:
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
?
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 =)
Ok, ran into this again, let's get you a repro.
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)
This bug hasn't been fixed yet.
Still there.
Can you post the code for prepare
in your previous example?
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)
]
Is this still a bug?
Yes
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`?