Dynamic reading from an Oracle database
Implementation
let inline tryUnbox<'a> (x:obj) =
match x with
| :? 'a as result -> Some(result)
| _ -> None
type DynamicOracleDataReader(reader:OracleDataReader) =
member private x.Reader = reader
member x.Read() = reader.Read()
static member (?) (dr:DynamicOracleDataReader, name:string) : 'a option =
tryUnbox (dr.Reader.[name])
interface IDisposable with
member x.Dispose() = reader.Dispose()
type DynamicOracleCommand(cmd:OracleCommand) =
member private x.Command = cmd
static member (?<-) (cmd:DynamicOracleCommand, name:string, value) =
let p = new OracleParameter(name, box value)
cmd.Command.Parameters.Add(p) |> ignore
member x.ExecuteNonQuery() = cmd.ExecuteNonQuery()
member x.ExecuteReader() = new DynamicOracleDataReader(cmd.ExecuteReader())
member x.ExecuteScalar() = cmd.ExecuteScalar()
member x.Parameters = cmd.Parameters
interface IDisposable with
member x.Dispose() = cmd.Dispose()
type DynamicOracleConnection(connStr:string) =
let conn = new OracleConnection(connStr)
member private x.Connection = conn
// static member (?) (conn:DynamicOracleConnection, name) =
// let command = new OracleCommand(name, conn.Connection)
// command.CommandType <- CommandType.Text
// new DynamicOracleCommand(command)
member x.GenerateCommand(query:string) =
let command = new OracleCommand(query, conn)
command.BindByName <- true
new DynamicOracleCommand(command)
member x.Open() = conn.Open()
interface IDisposable with
member x.Dispose() = conn.Dispose()
Usage
type Order = {
OrderId: int
Comments: string option}
let connectionString =
"User Id = XXXXXX; " +
"Password = XXXXXX; " +
"Data Source = " +
"(Description = " +
"(Address = " +
"(Protocol = TCP) " +
"(Host = 127.0.0.1) " +
"(Port = 1521)) " +
"(Connect_Data = (Service_Name = XXXXXX)))"
let getOrderByIdQuery =
"select * " +
"from ORDERS " +
"where IDORDER = : orderId " +
"order by IDORDER"
let getOrderById (orderId: int) = seq {
use conn = new DynamicOracleConnection(connectionString)
use cmd = conn.GenerateCommand(getOrderByIdQuery)
cmd?orderId <- orderId
conn.Open()
use reader = cmd.ExecuteReader ()
while (reader.Read()) do
yield {
OrderId = defaultArg reader?IDORDER 0
Comments = reader?COMMENTS}}
References