| GNOME Data Access 5 manual |
|---|
The following example is available in the samples/Blobs source directory
and illustrate how to manipulate BLOBs. This test program offers 2 operations which are to
store the contents of a file to the database (which returns the ID of the stored data), and to
fetch a stored data from the database from its ID (which creates a fetched_<ID> file).
The code is:
#include <libgda/libgda.h>
#include <libgda/sql-parser/gda-sql-parser.h>
#include <libgda/gda-blob-op.h>
GdaConnection *open_connection (void);
static gboolean do_store (GdaConnection *cnc, const gchar *filename, GError **error);
static gboolean do_fetch (GdaConnection *cnc, gint id, GError **error);
int
main (int argc, char *argv[])
{
GdaConnection *cnc;
const gchar *filename = NULL;
gint id = 0;
gboolean store;
GError *error = NULL;
gboolean result;
/* parse arguments */
if (argc != 3)
goto help;
if (! g_ascii_strcasecmp (argv[1], "store")) {
filename = argv[2];
store = TRUE;
}
else if (! g_ascii_strcasecmp (argv[1], "fetch")) {
id = atoi (argv[2]);
store = FALSE;
}
else
goto help;
/* do the job */
gda_init ();
cnc = open_connection ();
if (store)
result = do_store (cnc, filename, &error);
else
result = do_fetch (cnc, id, &error);
gda_connection_close (cnc);
if (!result) {
g_print ("ERROR: %s\n", error && error->message ? error->message : "No detail");
g_clear_error (&error);
}
else
g_print ("Ok.\n");
return result ? 0 : 1;
help:
g_print ("%s [store <filename> | fetch <ID>]\n", argv[0]);
return 0;
}
/*
* Open a connection to the example.db file
*/
GdaConnection *
open_connection (void)
{
GdaConnection *cnc;
GError *error = NULL;
cnc = gda_connection_open_from_string ("SQLite", "DB_DIR=.;DB_NAME=testblob", NULL,
GDA_CONNECTION_OPTIONS_NONE,
&error);
if (!cnc) {
g_print ("Could not open connection to SQLite database in testblob.db file: %s\n",
error && error->message ? error->message : "No detail");
exit (1);
}
return cnc;
}
static gboolean
do_store (GdaConnection *cnc, const gchar *filename, GError **error)
{
if (! g_file_test (filename, G_FILE_TEST_EXISTS) ||
g_file_test (filename, G_FILE_TEST_IS_DIR)) {
g_set_error (error, 0, 0,
"%s", "File does not exist or is a directory");
return FALSE;
}
GdaSqlParser *parser;
GdaStatement *stmt;
GdaSet *params, *newrow;
GdaHolder *holder;
GValue *value;
GdaBlob *blob;
gint res;
parser = gda_sql_parser_new ();
stmt = gda_sql_parser_parse_string (parser,
"INSERT INTO blobstable (data) VALUES (##blob::blob)",
NULL, error);
g_object_unref (parser);
if (!stmt)
return FALSE;
if (! gda_statement_get_parameters (stmt, ¶ms, error)) {
g_object_unref (stmt);
return FALSE;
}
holder = gda_set_get_holder (params, "blob");
value = gda_value_new_blob_from_file (filename);
blob = (GdaBlob*) gda_value_get_blob (value);
g_assert (gda_holder_take_value (holder, value, NULL));
g_print ("STORING file '%s' to database BLOB\n", filename);
res = gda_connection_statement_execute_non_select (cnc, stmt, params, &newrow, error);
g_object_unref (params);
g_object_unref (stmt);
if (newrow) {
GSList *list;
g_print ("Inserted row is (for each numbered column in the table):\n");
for (list = newrow->holders; list; list = list->next) {
const GValue *value;
gchar *tmp;
value = gda_holder_get_value (GDA_HOLDER (list->data));
tmp = gda_value_stringify (value);
g_print (" [%s] = [%s]\n", gda_holder_get_id (GDA_HOLDER (list->data)), tmp);
g_free (tmp);
}
g_object_unref (newrow);
}
else
g_print ("Provider did not return the inserted row\n");
return (res == -1) ? FALSE : TRUE;
}
static gboolean
do_fetch (GdaConnection *cnc, gint id, GError **error)
{
GdaSqlParser *parser;
GdaStatement *stmt;
GdaSet *params;
GdaDataModel *model;
const GValue *value;
GdaBlob *blob;
gboolean result = TRUE;
gchar *filename;
filename = g_strdup_printf ("fetched_%d", id);
g_print ("FETCHING BLOB with ID %d to file '%s'\n", id, filename);
parser = gda_sql_parser_new ();
stmt = gda_sql_parser_parse_string (parser,
"SELECT data FROM blobstable WHERE id=##id::int",
NULL, error);
g_object_unref (parser);
if (!stmt)
return FALSE;
if (! gda_statement_get_parameters (stmt, ¶ms, error)) {
g_object_unref (stmt);
return FALSE;
}
g_assert (gda_set_set_holder_value (params, NULL, "id", id));
model = gda_connection_statement_execute_select (cnc, stmt, params, error);
g_object_unref (params);
g_object_unref (stmt);
if (! model)
return FALSE;
value = gda_data_model_get_value_at (model, 0, 0, error);
if (!value) {
g_object_unref (model);
return FALSE;
}
g_assert (G_VALUE_TYPE (value) == GDA_TYPE_BLOB);
blob = (GdaBlob*) gda_value_get_blob (value);
if (blob->op) {
GValue *dest_value;
GdaBlob *dest_blob;
dest_value = gda_value_new_blob_from_file (filename);
dest_blob = (GdaBlob*) gda_value_get_blob (dest_value);
result = gda_blob_op_write_all (dest_blob->op, (GdaBlob*) blob);
gda_value_free (dest_value);
}
else
result = g_file_set_contents (filename, (gchar *) ((GdaBinary*)blob)->data,
((GdaBinary*)blob)->binary_length, error);
g_free (filename);
return result;
}