On Fri, 19 Jun 1998 [EMAIL PROTECTED] wrote:
> Ok, let's go to "stateless" SQL statements.
> Where would you like to connect to database?
I think part of the confusion here is that I am thinking in terms of
databases with explicit support for transactions rather than Xbase and
Access databases which lack such support (last I checked).
I was thinking that you would have some class like
> class ODBCConnection connection where
> odbcOpenConnection::String -> IO connection
> odbcTransaction::(ODBCTransaction transaction)=>connection->transaction
> odbcCloseConnection::connection -> IO ()
Transactions allow you to have a safe query interface with the database
until you commit your changes. My guess (though I haven't tried it just
yet) is that you will want to pass your function to the transaction class
and have it behave like a stored procedure.
> class ODBCTransaction transaction where
> odbcSelect::transaction -> SQLSelect -> [ODBCResult]
> odbcChange::transaction -> SQLChange -> IO()
> odbcCommit::transaction -> IO ()
> transact::(ODBCConnection connection)=>connection -> (x->[SQLChange])-> IO()
> transact connection client = do
> transaction <- openTransaction connection
> mapM (odbcChange transaction) $ client transaction
> success <- odbcCommit transaction
> return ()
SQLSelect and SQLChange are abstractions for commands that query or modify
the contents of the database.
> Will it be affordable to connect and disconnect in
> sqlSelect or doTransaction functions proposed by you?
I presume that odbcSelect could be implemented by using unsafePerformIO to
returns a result list owned by the C code. When haskell is done with the
result list, it calls the garbage collector callback function.
Since you already have the connection in this context, there is no
additional cost of openning and closing a connection or of establishing a
new transaction.
> What structure are you going to use to retreive data.
> I used lazy list (of tuples or of lists). What will be placed to this
> list when its evaluation is forced after disconnecting from database?
I don't know enough of greencard to be able to answer this directly. I
believe that you can use the garbage collector callbacks to avoid forcing
evaluation.
If the ODBC implementation does not allow the user to maintain multiple
unconsumed queries then that is a larger problem. Many ODBC
drivers are "thread safe" (some directly support cursors) so they should
take care of this for you. If they don't then I suppose you would need to
copy the query results locally until Haskell elects either to
consume them or garbage collect them.
> Does this mean one have to choose between lazy data structure and
> connecting-query-disconnecting as a single IO action?
I am not sure I follow your point here. I am saying that you can
establish transactions in the IOMonad and use them outside the IOMonad.
ODBC drivers tend to suppot laziness because they know that some queries
will be quite large and may not need to be returned completely. The Java
JDBC interface specifies that results have a next() function that returns
the next item in the result list.
I hope I am making more sense here. I have not spent the time trying to
do the difficult work of connecting via raw ODBC and I applaud your effort
in this regard. Perhaps I am wrong about this and am failing to
understand what is really required to make an ODBC connection (my
experience is more with JDBC). Or perhaps I am playing monday morning
quarterback. In either case, I will need to connect to a SQL database
shortly and am just trying to think about the best way to think about it.
-Alex-
___________________________________________________________________
S. Alexander Jacobson i2x Media
1-212-697-0184 voice 1-212-697-1427 fax