This patch adds blob read support to Firebird provider. Attached a patch file and 2 new files that should be posted (copied) in libgda/providers/firebird/ before aplying the patch.
Attachment:
libgda_firebird_090204-0.diff.gz
Description: GNU Zip compressed data
/* GDA Firebird Blob * Copyright (C) 1998-2004 The GNOME Foundation * * AUTHORS: * Albi Jeronimo <jeronimoalbi yahoo com ar> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "gda-firebird-blob.h" #include "gda-firebird-provider.h" #include "gda-firebird-recordset.h" #include <libgda/gda-intl.h> typedef struct _FirebirdBlobPrivate FirebirdBlobPrivate; /* FirebirdBlob private structure */ struct _FirebirdBlobPrivate { isc_blob_handle blob_handle; isc_tr_handle ftr; GdaBlobMode mode; ISC_QUAD blob_id; GdaConnection *cnc; }; static void gda_firebird_blob_free_data (GdaBlob *blob); static gint gda_firebird_blob_open (GdaBlob *blob, GdaBlobMode mode); static gint gda_firebird_blob_read (GdaBlob *blob, gpointer buf, gint size, gint *bytes_read); static gint gda_firebird_blob_close (GdaBlob *blob); /******************************** * FirebirdBlob public methods * ********************************/ GdaBlob * gda_firebird_blob_new (GdaConnection *cnc) { FirebirdBlobPrivate *priv; GdaBlob *blob; g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL); blob = g_new0 (GdaBlob, 1); blob->priv_data = g_new0 (FirebirdBlobPrivate, 1); priv = blob->priv_data; priv->mode = -1; priv->blob_handle = NULL; priv->cnc = cnc; priv->ftr = NULL; blob->free_data = gda_firebird_blob_free_data; blob->open = gda_firebird_blob_open; blob->read = gda_firebird_blob_read; blob->close = gda_firebird_blob_close; blob->write = NULL; blob->lseek = NULL; blob->remove = NULL; return blob; } void gda_firebird_blob_set_id (GdaBlob *blob, const ISC_QUAD *blob_id) { FirebirdBlobPrivate *priv; g_return_if_fail (blob != NULL); priv = blob->priv_data; priv->blob_id.gds_quad_high = blob_id->gds_quad_high; priv->blob_id.gds_quad_low = blob_id->gds_quad_low; } /******************************** * FirebirdBlob private methods * ********************************/ static void gda_firebird_blob_free_data (GdaBlob *blob) { FirebirdBlobPrivate *priv; ISC_STATUS status[20]; g_return_if_fail (blob != NULL); priv = blob->priv_data; /* Rollback transaction if active */ if (priv->ftr) isc_rollback_transaction (status, priv->ftr); g_free (priv); blob->priv_data = NULL; } static gint gda_firebird_blob_open (GdaBlob *blob, GdaBlobMode mode) { FirebirdBlobPrivate *priv; GdaFirebirdConnection *fcnc; g_return_val_if_fail (blob != NULL, -1); priv = blob->priv_data; /* Process Blob only if is not oppened */ if (!priv->blob_handle) { fcnc = g_object_get_data (G_OBJECT (priv->cnc), CONNECTION_DATA); if (!fcnc) { gda_connection_add_error_string (priv->cnc, _("Invalid Firebird handle")); return -1; } if (isc_start_transaction (fcnc->status, &(priv->ftr), 1, &(fcnc->handle), 0, NULL)) { gda_connection_add_error_string (priv->cnc, _("Unable to start transaction")); return -1; } priv->mode = mode; if (!isc_open_blob2 (fcnc->status, &(fcnc->handle), &(priv->ftr), &(priv->blob_handle), &(priv->blob_id), 0, NULL)) { return 0; } } gda_connection_add_error_string (priv->cnc, _("Blob already open")); return -1; } static gint gda_firebird_blob_read (GdaBlob *blob, gpointer buf, gint size, gint *bytes_read) { GdaFirebirdConnection *fcnc; FirebirdBlobPrivate *priv; gushort actual_segment_length; gint fetch_stat; g_return_val_if_fail (blob != NULL, -1); g_return_val_if_fail (blob->priv_data != NULL, -1); g_return_val_if_fail (bytes_read != NULL, -1); priv = blob->priv_data; /* Process Blob only if is oppened */ if (priv->blob_handle) { /* I don't know if buffer comes initialized, so I initialize */ if (!buf) buf = g_malloc0 (size); fcnc = g_object_get_data (G_OBJECT (priv->cnc), CONNECTION_DATA); if (!fcnc) { gda_connection_add_error_string (priv->cnc, _("Invalid Firebird handle")); return -1; } fetch_stat = isc_get_segment ( fcnc->status, &(priv->blob_handle), &actual_segment_length, (gushort) size, (gchar *) buf); /* If we reach blob EOF */ if (fetch_stat == isc_segstr_eof) { *(bytes_read) = (gint) actual_segment_length; return -1; } /* Fetched OK or partially */ if ((fetch_stat == 0) || (fetch_stat == isc_segment)) { *(bytes_read) = (gint) actual_segment_length; return 0; } else gda_connection_add_error_string (priv->cnc, _("Error getting blob segment.")); } gda_connection_add_error_string (priv->cnc, _("Can't read a closed Blob")); return -1; } static gint gda_firebird_blob_close (GdaBlob *blob) { FirebirdBlobPrivate *priv; GdaFirebirdConnection *fcnc; g_return_val_if_fail (blob != NULL, -1); g_return_val_if_fail (blob->priv_data != NULL, -1); priv = blob->priv_data; /* Close Blob if is opened */ if (priv->blob_handle) { fcnc = g_object_get_data (G_OBJECT (priv->cnc), CONNECTION_DATA); if (!fcnc) { gda_connection_add_error_string (priv->cnc, _("Invalid Firebird handle")); return -1; } if (!isc_close_blob (fcnc->status, &(priv->blob_handle))) { /* Rollback transaction if active */ if (priv->ftr) isc_rollback_transaction (fcnc->status, &(priv->ftr)); priv->blob_handle = NULL; priv->ftr = NULL; return 0; } else gda_connection_add_error_string (priv->cnc, _("Unable to close blob.")); } gda_connection_add_error_string (priv->cnc, _("Blob is closed")); return -1; }
/* GDA Firebird Blob * Copyright (C) 1998-2004 The GNOME Foundation * * AUTHORS: * Albi Jeronimo <jeronimoalbi yahoo com ar> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef _GDA_FIREBIRD_BLOB_H_ #define _GDA_FIREBIRD_BLOB_H #include <libgda/gda-blob.h> #include <libgda/gda-connection.h> #include <ibase.h> /* Firebird Blob public interface */ GdaBlob *gda_firebird_blob_new (GdaConnection *cnc); void gda_firebird_blob_set_id (GdaBlob *self, const ISC_QUAD *blob_id); #endif /* _GDA_FIREBIRD_BLOB_H */