[libgda] New blob manipulation example



commit 0599d7f7644b8768471d18e094f837c719ed8178
Author: Vivien Malerba <malerba gnome-db org>
Date:   Fri Sep 17 19:13:43 2010 +0200

    New blob manipulation example

 Makefile.am               |    6 +-
 samples/Blobs/Makefile    |   13 +++
 samples/Blobs/README      |   41 ++++++++++
 samples/Blobs/blobtest.c  |  191 +++++++++++++++++++++++++++++++++++++++++++++
 samples/Blobs/testblob.db |  Bin 0 -> 3072 bytes
 5 files changed, 250 insertions(+), 1 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index a220366..d896bd3 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -92,7 +92,11 @@ example_files = \
 	samples/SimpleUIForm/README \
 	samples/SimpleUIForm/example.c \
 	samples/SimpleUIForm/Makefile \
-	samples/SimpleUIForm/ScreenShot.png
+	samples/SimpleUIForm/ScreenShot.png \
+	samples/Blobs/blobtest.c \
+	samples/Blobs/Makefile \
+	samples/Blobs/README \
+	samples/Blobs/testblob.db
 
 EXTRA_DIST = \
 	COPYING \
diff --git a/samples/Blobs/Makefile b/samples/Blobs/Makefile
new file mode 100644
index 0000000..bbd045e
--- /dev/null
+++ b/samples/Blobs/Makefile
@@ -0,0 +1,13 @@
+CFLAGS = -Wall -g -DGDA_DISABLE_DEPRECATED `pkg-config --cflags libgda-4.0`
+LDFLAGS = `pkg-config --libs libgda-4.0`
+
+all: blobtest
+
+blobtest: blobtest.c
+	$(CC) -o blobtest blobtest.c $(CFLAGS) $(LDFLAGS)
+
+clean:
+	rm -f *~
+	rm -f *.o
+	rm -f blobtest
+	rm -f fetched_*
diff --git a/samples/Blobs/README b/samples/Blobs/README
new file mode 100644
index 0000000..3f82f8d
--- /dev/null
+++ b/samples/Blobs/README
@@ -0,0 +1,41 @@
+Libgda Blobs example
+====================
+
+Description:
+------------
+
+The example in this directory illustrate how to manipulate BLOBS (binary large objects).
+This example uses an SQLite database, but can be modified to use any type of database,
+in this case you have to create the appropriate test table in your database, and modify the
+code of the open_connection() function.
+
+The SQLite SQL to create the test table is:
+CREATE TABLE blobstable (id INTEGER PRIMARY KEY AUTOINCREMENT, data blob);
+The PostgreSQL SQL to create the test table is (the "WITH OIDS" clause is optionnal
+but it's required to get the inserted row):
+CREATE TABLE blobstable (id serial PRIMARY KEY, data oid) WITH OIDS;
+
+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).
+
+Compiling and running:
+----------------------
+
+To compile (make sure Libgda is installed prior to this):
+> make
+
+and to run (stores the blobtest executable file):
+> ./blobtest store blobtest
+STORING file 'blobtest' to database BLOB
+Inserted row is (for each numbered column in the table):
+  [+0] = [1]
+  [+1] = [\177ELF\001\001\001\000\000\000\000\000\000\000\000\000\002\000\003\000\001\000\000\000p\215\004\0104\000\000\000\260/\000\000\000\000\000\000]
+Ok.
+> /blobtest fetch 1
+FETCHING BLOB with ID 1 to file 'fetched_1'
+Ok.
+
+> cmp blobtest fetched_1
+
+Should not return any difference
\ No newline at end of file
diff --git a/samples/Blobs/blobtest.c b/samples/Blobs/blobtest.c
new file mode 100644
index 0000000..39b855f
--- /dev/null
+++ b/samples/Blobs/blobtest.c
@@ -0,0 +1,191 @@
+#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,
+			     "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, &params, 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, &params, 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;
+}
diff --git a/samples/Blobs/testblob.db b/samples/Blobs/testblob.db
new file mode 100644
index 0000000..dcc8235
Binary files /dev/null and b/samples/Blobs/testblob.db differ



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]