------------------ POSTGRESQL, LO and VISUAL BASIC MINI-HOWTO ------------------------- Author: Denis Gasparin (denis@edistar.com) Release Date: 29 October 2001 Description: Example based Mini-Howto on Pgsql Large Objects Interface and Visual Basic This document tells about using Large Objects and Visual Basic. All the main connection interfaces available in VB are discussed: DAO, ADO and RDO. Requirements to get the subroutines to work: - DAO, ADO and RDO interfaces available in VB; - created the lo type using the appropriate functions available in contrib/lo in the Postgresql source tree; - Installed and properly configured the latest version of the Postgresql ODBC driver. In the example the database used has one table with only two fields. Here is the SQL definition: CREATE TABLE MYTABLE( MAIN INTEGER, OBJECT LO ); The odbc DSN i used in the example is named pgsql_test_blob. To insert a record, i suggest you to use the INSERT sql statement instead of the AddNew method (available in DAO, RDO and ADO). The AddNew method force you to declare a Recordset and this is bad because when you open it, VB creates a cursor and has to pass all the records in the table, slowing a lot your application. I think the examples are very simple and self explanatory. Some tip about which interface to use: - ADO and RDO are the best interfaces to connect to postgres. Personally, i think ADO is better only because it is new and actively supported by Microsoft. RDO is the old interface and it is not more developed; - DAO is very very heavy and i suggest you to not use it unless you are forced to do so. I apologize for possible errors and, if you want, contact me and let me know. My e-mail address is denis@edistar.com. ------------------------ VISUAL BASIC EXAMPLES ------------------------------------- Private Sub DAO_Connect() Dim chunk() As Byte Dim fd As Integer Dim flen As Long Dim ws As Workspace Dim cn As Database Dim rs As DAO.Recordset Dim strConnection As String ' Initialize the DB Engine Set ws = DBEngine.Workspaces(0) Let strConnection = "ODBC;DSN=pgsql_test_blob;" Set cn = ws.OpenDatabase("", False, False, strConnection) ' Open the table MYTABLE Set rs = cn.OpenRecordset("MYTABLE") ' ' Add a new record to the table ' rs.AddNew rs!main = 100 '' a random integer value '' fd = FreeFile Open "mydocument" For Binary Access Read As fd flen = LOF(fd) If flen = 0 Then Close MsgBox "Error while opening the file" End End If ' Get the blob object into the chunk variable ReDim chunk(1 to flen) Get fd, , chunk() ' Store it in the database rs!object.AppendChunk chunk() ' Update changes rs.Update ' Close the file Close fd ' Close the record set rs.Close ' ' Read the blob object from the first record of MYTABLE ' Set rs = Nothing ' Open the table Set rs = cn.OpenRecordset("MYTABLE") ' Open a file for writing fd = FreeFile Open "mydocument" For Binary Access Write As fd flen = rs!object.FieldSize ReDim chunk(1 to flen) ' Get it from the database chunk() = rs!object.GetChunk(0, flen) ' ...and put it into the file Put fd, , chunk() ' Close all... rs.Close Close fd cn.Close Close End Sub Private Sub ADO_Store() Dim cn As New ADODB.Connection Dim rs As ADODB.Recordset Dim cmd As ADODB.Command Dim chunk() As Byte Dim fd As Integer Dim flen As Long Dim main As ADODB.Parameter Dim object As ADODB.Parameter ' Connect to the database using ODBC With cn .ConnectionString = "dsn=pgsql_test_blob;" .Open .CursorLocation = adUseClient End With ' Here is an example if you want to issue a direct command to the database ' 'Set cmd = New ADODB.Command 'With cmd ' .CommandText = "delete from MYTABLE" ' .ActiveConnection = cn ' .Execute 'End With 'Set cmd = Nothing ' ' Here is an example of how insert directly into the database without using ' a recordset and the AddNew method ' Set cmd = New ADODB.Command cmd.ActiveConnection = cn cmd.CommandText = "insert into MYTABLE(main,object) values(?,?)" cmd.CommandType = adCmdText ' The main parameter Set main = cmd.CreateParameter("main", adInteger, adParamInput) main.Value = 100 '' a random integer value '' cmd.Parameters.Append main ' Open the file for reading fd = FreeFile Open "mydocument" For Binary Access Read As fd flen = LOF(fd) If flen = 0 Then Close MsgBox "Error while opening the file" End End If ' The object parameter ' ' The fourth parameter indicates the memory to allocate to store the object Set object = cmd.CreateParameter("object", adLongVarBinary, adParamInput, flen + 100) ReDim chunk(1 to flen) Get fd, , chunk() ' Insert the object into the parameter object object.AppendChunk chunk() cmd.Parameters.Append object ' Now execute the command Set rs = cmd.Execute ' ... and close all cn.Close Close End Sub Private Sub ADO_Fetch() ' ' Fetch the first record present in MYTABLE with a lo object stored Dim cn As New ADODB.Connection Dim rs As ADODB.Recordset Dim fd As Integer Dim flen As Long Dim chunk() As Byte ' Connect to the database using ODBC With cn .ConnectionString = "dsn=pgsql_test_blob;" .Open .CursorLocation = adUseClient End With ' Open a recordset of the table Set rs = New ADODB.Recordset rs.Open "MYTABLE", cn, adOpenKeyset, adLockOptimistic, adCmdTable ' Get the len of the stored object flen = rs!object.ActualSize ' Initialize the file where to store the blob fd = FreeFile Open "mydocument" For Binary Access Write As fd ReDim chunk(1 to flen) ' Get it from the database chunk() = rs!object.GetChunk(flen) ' ... and store in the file Put fd, , chunk() Close End Sub Private Sub RDO_Store() Dim cn As New RDO.rdoConnection Dim rs As RDO.rdoResultset Dim cmd As RDO.rdoQuery Dim fd As Integer Dim flen As Long Dim chunk() As Byte ' Connect to the database using ODBC With cn .Connect = "dsn=pgsql_test_blob;" .LoginTimeout = 3 .CursorDriver = rdUseOdbc .EstablishConnection rdDriverNoPrompt, True End With ' Create the INSERT statement to store the record in the database Set cmd = cn.CreateQuery("insert", "insert into MYTABLE (main,object) values(?,?)") ' Insert the first parameter cmd.rdoParameters(0).Value = 100 '' a random integer value '' ' Open the file for reading fd = FreeFile Open "mydocument" For Binary Access Read As fd flen = LOF(fd) If flen = 0 Then Close MsgBox "errore in apertura file" End End If ReDim chunk(1 To flen) ' Get it ... Get fd, , chunk() ' and store into the parameter object cmd.rdoParameters(1).Type = rdTypeLONGVARBINARY cmd.rdoParameters(1).AppendChunk chunk() ' Finally execute the INSERT statement cmd.Execute ' Close all Close End Sub Private Sub RDO_Fetch() ' ' Fetch the first record present in MYTABLE with a lo object stored Dim cn As New RDO.rdoConnection Dim rs As RDO.rdoResultset Dim fd As Integer Dim flen As Long Dim chunk() As Byte ' Connect to the database using ODBC With cn .Connect = "dsn=pgsql_test_blob;" .LoginTimeout = 3 .CursorDriver = rdUseOdbc .EstablishConnection rdDriverNoPrompt, True End With ' Open the table Set rs = cn.OpenResultset("select * from MYTABLE", rdOpenKeyset) ' Get the length of the file flen = rs!object.ColumnSize ' Initialize the file where to store the object fd = FreeFile Open "mydocument" For Binary Access Write As fd ReDim chunk(1 To flen) ' Get it from the database chunk() = rs!object.GetChunk(flen) Put fd, , chunk() Close End Sub