Michael left a comment, calling for some sample F# source code. Don’s already provided some samples on-line as part of the F# documentation, and there are a large number of samples in the F# distribution, so look there first!
But I thought I’d put up a sample of my own too. This is a GUI app which lets users insert, update, and delete rows from an SQL database table. The GUI part is built from a DataGridView in a Windows form. The database here is an embedded Firebird database called “DB.FDB”, in the working directory, containing a table called “MYTABLE”.
01 - open System;;
02 - open System.Windows.Forms;;
03 - open FirebirdSql.Data.FirebirdClient;;
04 -
05 - let connection = new FbConnection("ServerType=1;User=SYSDBA;Password=masterkey;Dialect=3;Database=db.fdb");;
06 - let adapter = new FbDataAdapter("SELECT * FROM MYTABLE;", connection);;
07 - let builder = new FbCommandBuilder(adapter);;
08 - do adapter.UpdateCommand <- builder.GetUpdateCommand();;
09 - do adapter.InsertCommand <- builder.GetInsertCommand();;
10 - do adapter.DeleteCommand <- builder.GetDeleteCommand();;
11 -
12 - let table = new Data.DataTable();; // this is like a proxy for the database table
13 - do ignore(adapter.Fill(table));;
14 -
15 - let view = new DataGridView();; // this is tabular data viewing/entry GUI thingy
16 - do view.DataSource <- table;;
17 - do view.RowLeave.Add (fun _ -> ignore(adapter.Update(table)));;
18 -
19 - let form = new Form();; // this is the top-level form...
20 - do form.Controls.Add(view);; // ...which only contains our GUI thingy
21 -
22 - [<system .STAThread>] // some magic we need for GUI apps
23 - do Application.Run(form);; // go go go!!!
This example has been stripped back a lot – you’d need to embelish it heavily to make the form into something more pretty and useable. Nonetheless, there are a couple of nice things to notice here.
First, look at line 17, where we tell the DataGridView that when the user leaves a row, the database should be updated. The nice thing is that the code to handle the RowLeave event is an ordinary function, and in its body we refer to the table and adapter that are within its “closure”/enclosing environment. Nice – event handlers often need to work on things that are within their environment, but are not accessible from their event parameters. (The treatment of events in F# is nice for other reasons too, but that’s just icing on the cake.)
Second, the managed .net Firebird library is accessible so easily. We just need to tell the F# compiler that we’re using the dll for the Firebird ADO.NET Provider, FirebirdSql.Data.FirebirdClient.dll. To do that we use the -r compiler command-line option (not shown above). Then the library is available to be opened like a normal F# library (line 3), and its classes are available to be used like normal F# classes (lines 5-7).