summaryrefslogtreecommitdiffstats
path: root/relblobif/test
diff options
context:
space:
mode:
authorConstantin Jucovschi <cj@ubuntu.localdomain>2009-04-24 07:20:22 -0400
committerConstantin Jucovschi <cj@ubuntu.localdomain>2009-04-24 07:20:22 -0400
commit8f27e65bddd7d4b8515ce620fb485fdd78fcdf89 (patch)
treebd328a4dd4f92d32202241b5e3a7f36177792c5f /relblobif/test
downloadrasdaman-upstream-8f27e65bddd7d4b8515ce620fb485fdd78fcdf89.tar.gz
rasdaman-upstream-8f27e65bddd7d4b8515ce620fb485fdd78fcdf89.tar.xz
rasdaman-upstream-8f27e65bddd7d4b8515ce620fb485fdd78fcdf89.zip
Initial commitv8.0
Diffstat (limited to 'relblobif/test')
-rw-r--r--relblobif/test/Makefile65
-rw-r--r--relblobif/test/README.txt5
-rw-r--r--relblobif/test/blobdump.c323
-rw-r--r--relblobif/test/blobdump.pgc315
-rw-r--r--relblobif/test/dblob.C242
5 files changed, 950 insertions, 0 deletions
diff --git a/relblobif/test/Makefile b/relblobif/test/Makefile
new file mode 100644
index 0000000..fe98b32
--- /dev/null
+++ b/relblobif/test/Makefile
@@ -0,0 +1,65 @@
+# -*-Makefile-*-
+#
+# This file is part of rasdaman community.
+#
+# Rasdaman community is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Rasdaman community 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+#
+# Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+# rasdaman GmbH.
+#
+# For more information please see <http://www.rasdaman.org>
+# or contact Peter Baumann via <baumann@rasdaman.com>. # Top Level makefile. This points to the various modules that have to be build
+# and/or deployed
+#
+#
+# MAKEFILE FOR:
+# test programs of module relblobif
+#
+# COMMENTS:
+# List environment dependencies, known bugs, specialities etc.
+#
+##################################################################
+######################### Definitions ############################
+
+LDFLAGS += $(L_SYM)$(RMANHOME)/lib $(LIBAKINSIDE) $(RMANBASE)/mymalloc/mymalloc_cln.o -lcrypt
+
+# source files
+CPPSOURCES = updateblob.c deleteblob.c createtable.c droptable.c insertblob.c readblob.c r.c r2.c # copytile.c
+
+# all test programs
+ALLTESTS = ${CPPSOURCES:%.c=%}
+
+# object files
+OBJS = ${CPPSOURCES:%.c=%.o}
+
+NEEDSTL =
+
+# Needed rasdaman libraries for linking. To be completed.
+#NEEDEDLIBS = $(QLPARSER) $(RELBLOBIF) $(RELADMINIF) $(RASLIB) $(RELCATALOGIF) $(RELMDDIF) $(RASLIB) $(CACHETAMGR) $(RELINDEXIF) $(CACHETAMGR) $(RASQL) $(QLPARSER)
+
+MISCCLEAN = core client.bm client.dbg client.log ir.out
+
+########################### Targets ##############################
+
+# make all tests
+.PHONY: test
+test: $(ALLTESTS)
+
+########################### Dependencies #########################
+
+blobdump: blobdump.o
+ $(CXX) -o $@ $^ $(LDFLAGS) $(BASEDBLDFLAGS) $(L_SYM)$(PGSQL_ROOT)/lib $(l_SYM)ecpg
+blobdump.o: blobdump.c
+blobdump.c: blobdump.pgc
+
diff --git a/relblobif/test/README.txt b/relblobif/test/README.txt
new file mode 100644
index 0000000..ea20ca4
--- /dev/null
+++ b/relblobif/test/README.txt
@@ -0,0 +1,5 @@
+relblobif/test:
+
+Strictly speaking these are not rasdaman tests, they do not contribute to systemtest.
+Rather they allow to test a DBMS for how it behaves wrt. long fields (char, varchar, blobs) if attacked with binary contents.
+
diff --git a/relblobif/test/blobdump.c b/relblobif/test/blobdump.c
new file mode 100644
index 0000000..bc2f44f
--- /dev/null
+++ b/relblobif/test/blobdump.c
@@ -0,0 +1,323 @@
+#include "mymalloc/mymalloc.h"
+/* Processed by ecpg (3.1.1) */
+/* These include files are added by the preprocessor */
+#include <ecpgtype.h>
+#include <ecpglib.h>
+#include <ecpgerrno.h>
+#include <sqlca.h>
+#line 1 "blobdump.pgc"
+/* End of automatic include section */
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community 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 General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+/*************************************************************
+ *
+ *
+ * PURPOSE:
+ * dump RAS_TILES blob table.
+ * Depending on parameters, either a particular tuple is printed
+ * or the whole table. Optionally also the blob is dumped in hex.
+ * Parameters: see usage().
+ *
+ *
+ * COMMENTS:
+ * - assumes RAS_TILES
+ *
+ ************************************************************/
+
+using namespace std;
+
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h> /* getopt */
+
+#include <sqlca.h>
+
+// SQL error codes:
+#include "externs.h"
+
+// PG stuff
+#include "libpq-fe.h" // C interface to PgSQL
+#include "libpq/libpq-fs.h" /* large object (lo) api */
+// libq-style connection ptr taken from ECPG connect (needed for libq functions):
+// (currently used by relblobif/blobtile.pgc)
+PGconn *pgConn = NULL;
+PGresult *pgResult = NULL;
+
+#define RC_OK 0
+#define RC_ERROR -1
+
+#define QUERYSIZE 2000
+static char pgQuery[QUERYSIZE];
+
+void exitNicely()
+{
+ PQclear( pgResult );
+ (void) PQexec( pgConn, "ROLLBACK WORK" );
+ PQfinish( pgConn );
+ exit( RC_ERROR );
+}
+
+
+void
+disconnect()
+{
+ pgResult = PQexec( pgConn, "ROLLBACK WORK" );
+ if (PQresultStatus(pgResult) != PGRES_COMMAND_OK)
+ {
+ cerr << "error during disconnect: " << PQerrorMessage(pgConn) << endl << flush;
+ PQclear( pgResult );
+ exit( RC_ERROR );
+ }
+ PQclear( pgResult );
+
+ PQfinish( pgConn );
+ pgConn = NULL;
+}
+
+void
+connect( const char * db )
+{
+ char pgConnInfo[200];
+
+ (void) snprintf( pgConnInfo, (size_t) sizeof(pgConnInfo), "dbname = %s", db );
+ pgConn = PQconnectdb( pgConnInfo );
+ if (PQstatus(pgConn) != CONNECTION_OK)
+ {
+ cerr << "error during connect: " << PQerrorMessage(pgConn) << endl << flush;
+ exitNicely();
+ }
+
+ pgResult = PQexec( pgConn, "BEGIN TRANSACTION" );
+ if (PQresultStatus(pgResult) != PGRES_COMMAND_OK)
+ {
+ cerr << "error during being ta: " << PQerrorMessage(pgConn) << endl << flush;
+ PQclear( pgResult );
+ exit( RC_ERROR );
+ }
+ PQclear( pgResult );
+
+}
+
+// read one tuple from ras_tiles, identified by myOId, and display it (with contents if withDump==true)
+void
+readFromDb( long myOId, bool withDump )
+{
+ unsigned int blobOid = 0;
+ short dataFormat = 0;
+ unsigned long size = 0;
+ char *cells = NULL;
+
+ // (1) --- access tuple
+ int result = snprintf( pgQuery, (size_t) sizeof(pgQuery), "SELECT Tile, DataFormat FROM RAS_TILES WHERE BlobId = %d", myOId );
+
+ pgResult = PQexec( pgConn, pgQuery );
+ if (PQresultStatus(pgResult) != PGRES_TUPLES_OK)
+ {
+ cerr << "error during 'select': " << PQerrorMessage(pgConn) << endl << flush;
+ exitNicely();
+ }
+ else if (PQntuples(pgResult) < 1)
+ {
+ cerr << "no tuple with id " << myOId << endl << flush;
+ exitNicely();
+ }
+
+ blobOid = atoi( PQgetvalue( pgResult, 0, 0 ) );
+ dataFormat = atoi( PQgetvalue( pgResult, 0, 1 ) );
+ PQclear( pgResult );
+
+ // (2) --- open, read, close blob
+ int fd = lo_open( pgConn, blobOid, INV_READ ); // open; manual tells no error indication
+ size = lo_lseek( pgConn, fd, 0, SEEK_END ); // determine blob size; FIXME: more efficient method??
+ (void) lo_lseek( pgConn, fd, 0, SEEK_SET ); // rewind for reading
+ cells = (char*) mymalloc( size * sizeof(char) ); // allocate buffer for blob
+ if (cells == NULL)
+ {
+ cerr << "error during malloc()" << endl << flush;
+ exitNicely();
+ }
+ int loResult = lo_read( pgConn, fd, cells, size );
+ if (loResult < 0)
+ {
+ cerr << "error during lo_read(): " << PQerrorMessage(pgConn) << endl << flush;
+ exitNicely();
+ }
+ else if (loResult != size) // did not get all
+ {
+ cerr << "error (did not get all bytes): " << PQerrorMessage(pgConn) << endl << flush;
+ exitNicely();
+ }
+ int ignoredPgResult = lo_close( pgConn, fd ); // close blob
+
+ if (withDump)
+ {
+ cout << " id = " << myOId << ", dataFormat = " << dataFormat << ", bloboid = " << blobOid << ", blob length = " << size << ", contents = ";
+ for (int a = 0; a < size; a++)
+ cout << " " << hex << (0xff & (unsigned int)(cells[a])) << dec;
+ cout << dec << endl;
+ }
+ else
+ {
+ cout << " id = " << myOId << ", dataFormat = " << dataFormat << ", bloboid = " << blobOid << ", blob length = " << size << endl;
+ }
+
+ free( cells );
+}
+
+// read all tuples from ras_tiles and display them (with contents if withDump==true)
+void
+readAllFromDb( bool withDump )
+{
+ unsigned int blobOid;
+ long myId;
+ short dataFormat;
+ unsigned long size = 0;
+ char *cells = NULL;
+ int rowNumber = 0;
+
+ // (1) --- declare cursor
+ pgResult = PQexec( pgConn, "SELECT BlobId, Tile, DataFormat FROM RAS_TILES" );
+ if (PQresultStatus(pgResult) != PGRES_TUPLES_OK && PQresultStatus(pgResult) != PGRES_COMMAND_OK)
+ {
+ cerr << "error during 'declare cursor': " << PQerrorMessage(pgConn) << endl << flush;
+ exitNicely();
+ }
+
+ do
+ {
+ myId = atoi( PQgetvalue( pgResult, rowNumber, 0 ) );
+ blobOid = atoi( PQgetvalue( pgResult, rowNumber, 1 ) );
+ dataFormat = atoi( PQgetvalue( pgResult, rowNumber, 2 ) );
+
+ // (2) --- open, read, close blob
+ int fd = lo_open( pgConn, blobOid, INV_READ ); // open; manual tells no error indication
+ size = lo_lseek( pgConn, fd, 0, SEEK_END ); // determine blob size; FIXME: more efficient method??
+ (void) lo_lseek( pgConn, fd, 0, SEEK_SET ); // rewind for reading
+ cells = (char*) mymalloc( size * sizeof(char) ); // allocate buffer for blob
+ if (cells == NULL)
+ {
+ cerr << "error: readFromDb() - no tuples found " << endl;
+ return;
+ }
+ int loResult = lo_read( pgConn, fd, cells, size );
+ if (loResult < 0)
+ {
+ cerr << "error: readFromDb() - no tuples found " << endl;
+ return;
+ }
+ else if (loResult != size) // did not get all
+ {
+ cerr << "error: readFromDb() - no tuples found " << endl;
+ return;
+ }
+ int ignoredPgResult = lo_close( pgConn, fd ); // close blob
+
+ if (withDump)
+ {
+ cout << " id = " << myId << ", dataFormat = " << dataFormat << ", bloboid = " << blobOid << ", blob length = " << size << ", contents = ";
+ for (int a = 0; a < size; a++)
+ cout << " " << hex << (0xff & (unsigned int)(cells[a])) << dec;
+ cout << endl;
+ }
+ else
+ {
+ cout << " id = " << myId << ", dataFormat = " << dataFormat << ", bloboid = " << blobOid << ", blob length = " << size << endl;
+ }
+
+ rowNumber++;
+ } while (PQresultStatus(pgResult) == PGRES_TUPLES_OK || PQresultStatus(pgResult) == PGRES_COMMAND_OK);
+
+ (void) PQexec( pgConn, "CLOSE TileLoop" );
+ PQclear( pgResult );
+ free( cells );
+}
+
+void usage(const char *prog)
+{
+ cout << "Usage: " << prog << " -d db [-i id] [-c]" << endl;
+ cout << "where:" << endl;
+ cout << " -d db log into PG server using PG database name db (mandatory)" << endl;
+ cout << " -i id dump blob with identifier id (default: dump whole table)" << endl;
+ cout << " -c dump blob contents too (default: descriptor data only)" << endl;
+ cout << " -h (help) print this overview" << endl;
+}
+
+int
+main(int argc, char* argv[])
+{
+ char *prog = argv[0]; // prog name
+ char db[100]; // DB connect string
+ int blobOid = 0; // tuple to be dumped
+ bool withDump = false; // by default, don't dump blob contents
+ char c; // getop var
+ int result; // for sscanf()
+
+ cout << prog << ": dump rasdaman blob table." << endl;
+
+ opterr = 0;
+ while ((c = getopt(argc, argv, "d:i:c")) != -1)
+ {
+ switch (c)
+ {
+ case 'd':
+ (void) strncpy( db, optarg, sizeof(db) );
+ break;
+ case 'i':
+ result = sscanf( optarg, "%d", &blobOid );
+ if (result != 1)
+ {
+ cerr << prog << ": positive integer expected: " << optarg << endl;
+ exit( RC_ERROR );
+ }
+ break;
+ case 'c':
+ withDump = true;
+ break;
+ case 'h':
+ case '?':
+ case ':':
+ usage(prog);
+ exit( RC_OK );
+ break;
+ }
+ }
+ if (optind < argc || argc == 1)
+ {
+ usage( prog );
+ exit( RC_ERROR );
+ }
+
+ connect( db );
+
+ if (blobOid > 0)
+ readFromDb( blobOid, withDump );
+ else
+ readAllFromDb( withDump );
+
+ disconnect();
+
+ cout << prog << ": done." << endl;
+}
+
diff --git a/relblobif/test/blobdump.pgc b/relblobif/test/blobdump.pgc
new file mode 100644
index 0000000..69b35b7
--- /dev/null
+++ b/relblobif/test/blobdump.pgc
@@ -0,0 +1,315 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community 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 General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+#include "mymalloc/mymalloc.h"
+/*************************************************************
+ *
+ *
+ * PURPOSE:
+ * dump RAS_TILES blob table.
+ * Depending on parameters, either a particular tuple is printed
+ * or the whole table. Optionally also the blob is dumped in hex.
+ * Parameters: see usage().
+ *
+ *
+ * COMMENTS:
+ * - assumes RAS_TILES
+ *
+ ************************************************************/
+
+using namespace std;
+
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h> /* getopt */
+
+#include <sqlca.h>
+
+// SQL error codes:
+#include "externs.h"
+
+// PG stuff
+#include "libpq-fe.h" // C interface to PgSQL
+#include "libpq/libpq-fs.h" /* large object (lo) api */
+// libq-style connection ptr taken from ECPG connect (needed for libq functions):
+// (currently used by relblobif/blobtile.pgc)
+PGconn *pgConn = NULL;
+PGresult *pgResult = NULL;
+
+#define RC_OK 0
+#define RC_ERROR -1
+
+#define QUERYSIZE 2000
+static char pgQuery[QUERYSIZE];
+
+void exitNicely()
+{
+ PQclear( pgResult );
+ (void) PQexec( pgConn, "ROLLBACK WORK" );
+ PQfinish( pgConn );
+ exit( RC_ERROR );
+}
+
+
+void
+disconnect()
+{
+ pgResult = PQexec( pgConn, "ROLLBACK WORK" );
+ if (PQresultStatus(pgResult) != PGRES_COMMAND_OK)
+ {
+ cerr << "error during disconnect: " << PQerrorMessage(pgConn) << endl << flush;
+ PQclear( pgResult );
+ exit( RC_ERROR );
+ }
+ PQclear( pgResult );
+
+ PQfinish( pgConn );
+ pgConn = NULL;
+}
+
+void
+connect( const char * db )
+{
+ char pgConnInfo[200];
+
+ (void) snprintf( pgConnInfo, (size_t) sizeof(pgConnInfo), "dbname = %s", db );
+ pgConn = PQconnectdb( pgConnInfo );
+ if (PQstatus(pgConn) != CONNECTION_OK)
+ {
+ cerr << "error during connect: " << PQerrorMessage(pgConn) << endl << flush;
+ exitNicely();
+ }
+
+ pgResult = PQexec( pgConn, "BEGIN TRANSACTION" );
+ if (PQresultStatus(pgResult) != PGRES_COMMAND_OK)
+ {
+ cerr << "error during being ta: " << PQerrorMessage(pgConn) << endl << flush;
+ PQclear( pgResult );
+ exit( RC_ERROR );
+ }
+ PQclear( pgResult );
+
+}
+
+// read one tuple from ras_tiles, identified by myOId, and display it (with contents if withDump==true)
+void
+readFromDb( long myOId, bool withDump )
+{
+ unsigned int blobOid = 0;
+ short dataFormat = 0;
+ unsigned long size = 0;
+ char *cells = NULL;
+
+ // (1) --- access tuple
+ int result = snprintf( pgQuery, (size_t) sizeof(pgQuery), "SELECT Tile, DataFormat FROM RAS_TILES WHERE BlobId = %d", myOId );
+
+ pgResult = PQexec( pgConn, pgQuery );
+ if (PQresultStatus(pgResult) != PGRES_TUPLES_OK)
+ {
+ cerr << "error during 'select': " << PQerrorMessage(pgConn) << endl << flush;
+ exitNicely();
+ }
+ else if (PQntuples(pgResult) < 1)
+ {
+ cerr << "no tuple with id " << myOId << endl << flush;
+ exitNicely();
+ }
+
+ blobOid = atoi( PQgetvalue( pgResult, 0, 0 ) );
+ dataFormat = atoi( PQgetvalue( pgResult, 0, 1 ) );
+ PQclear( pgResult );
+
+ // (2) --- open, read, close blob
+ int fd = lo_open( pgConn, blobOid, INV_READ ); // open; manual tells no error indication
+ size = lo_lseek( pgConn, fd, 0, SEEK_END ); // determine blob size; FIXME: more efficient method??
+ (void) lo_lseek( pgConn, fd, 0, SEEK_SET ); // rewind for reading
+ cells = (char*) mymalloc( size * sizeof(char) ); // allocate buffer for blob
+ if (cells == NULL)
+ {
+ cerr << "error during malloc()" << endl << flush;
+ exitNicely();
+ }
+ int loResult = lo_read( pgConn, fd, cells, size );
+ if (loResult < 0)
+ {
+ cerr << "error during lo_read(): " << PQerrorMessage(pgConn) << endl << flush;
+ exitNicely();
+ }
+ else if (loResult != size) // did not get all
+ {
+ cerr << "error (did not get all bytes): " << PQerrorMessage(pgConn) << endl << flush;
+ exitNicely();
+ }
+ int ignoredPgResult = lo_close( pgConn, fd ); // close blob
+
+ if (withDump)
+ {
+ cout << " id = " << myOId << ", dataFormat = " << dataFormat << ", bloboid = " << blobOid << ", blob length = " << size << ", contents = ";
+ for (int a = 0; a < size; a++)
+ cout << " " << hex << (0xff & (unsigned int)(cells[a])) << dec;
+ cout << dec << endl;
+ }
+ else
+ {
+ cout << " id = " << myOId << ", dataFormat = " << dataFormat << ", bloboid = " << blobOid << ", blob length = " << size << endl;
+ }
+
+ free( cells );
+}
+
+// read all tuples from ras_tiles and display them (with contents if withDump==true)
+void
+readAllFromDb( bool withDump )
+{
+ unsigned int blobOid;
+ long myId;
+ short dataFormat;
+ unsigned long size = 0;
+ char *cells = NULL;
+ int rowNumber = 0;
+
+ // (1) --- declare cursor
+ pgResult = PQexec( pgConn, "SELECT BlobId, Tile, DataFormat FROM RAS_TILES" );
+ if (PQresultStatus(pgResult) != PGRES_TUPLES_OK && PQresultStatus(pgResult) != PGRES_COMMAND_OK)
+ {
+ cerr << "error during 'declare cursor': " << PQerrorMessage(pgConn) << endl << flush;
+ exitNicely();
+ }
+
+ do
+ {
+ myId = atoi( PQgetvalue( pgResult, rowNumber, 0 ) );
+ blobOid = atoi( PQgetvalue( pgResult, rowNumber, 1 ) );
+ dataFormat = atoi( PQgetvalue( pgResult, rowNumber, 2 ) );
+
+ // (2) --- open, read, close blob
+ int fd = lo_open( pgConn, blobOid, INV_READ ); // open; manual tells no error indication
+ size = lo_lseek( pgConn, fd, 0, SEEK_END ); // determine blob size; FIXME: more efficient method??
+ (void) lo_lseek( pgConn, fd, 0, SEEK_SET ); // rewind for reading
+ cells = (char*) mymalloc( size * sizeof(char) ); // allocate buffer for blob
+ if (cells == NULL)
+ {
+ cerr << "error: readFromDb() - no tuples found " << endl;
+ return;
+ }
+ int loResult = lo_read( pgConn, fd, cells, size );
+ if (loResult < 0)
+ {
+ cerr << "error: readFromDb() - no tuples found " << endl;
+ return;
+ }
+ else if (loResult != size) // did not get all
+ {
+ cerr << "error: readFromDb() - no tuples found " << endl;
+ return;
+ }
+ int ignoredPgResult = lo_close( pgConn, fd ); // close blob
+
+ if (withDump)
+ {
+ cout << " id = " << myId << ", dataFormat = " << dataFormat << ", bloboid = " << blobOid << ", blob length = " << size << ", contents = ";
+ for (int a = 0; a < size; a++)
+ cout << " " << hex << (0xff & (unsigned int)(cells[a])) << dec;
+ cout << endl;
+ }
+ else
+ {
+ cout << " id = " << myId << ", dataFormat = " << dataFormat << ", bloboid = " << blobOid << ", blob length = " << size << endl;
+ }
+
+ rowNumber++;
+ } while (PQresultStatus(pgResult) == PGRES_TUPLES_OK || PQresultStatus(pgResult) == PGRES_COMMAND_OK);
+
+ (void) PQexec( pgConn, "CLOSE TileLoop" );
+ PQclear( pgResult );
+ free( cells );
+}
+
+void usage(const char *prog)
+{
+ cout << "Usage: " << prog << " -d db [-i id] [-c]" << endl;
+ cout << "where:" << endl;
+ cout << " -d db log into PG server using PG database name db (mandatory)" << endl;
+ cout << " -i id dump blob with identifier id (default: dump whole table)" << endl;
+ cout << " -c dump blob contents too (default: descriptor data only)" << endl;
+ cout << " -h (help) print this overview" << endl;
+}
+
+int
+main(int argc, char* argv[])
+{
+ char *prog = argv[0]; // prog name
+ char db[100]; // DB connect string
+ int blobOid = 0; // tuple to be dumped
+ bool withDump = false; // by default, don't dump blob contents
+ char c; // getop var
+ int result; // for sscanf()
+
+ cout << prog << ": dump rasdaman blob table." << endl;
+
+ opterr = 0;
+ while ((c = getopt(argc, argv, "d:i:c")) != -1)
+ {
+ switch (c)
+ {
+ case 'd':
+ (void) strncpy( db, optarg, sizeof(db) );
+ break;
+ case 'i':
+ result = sscanf( optarg, "%d", &blobOid );
+ if (result != 1)
+ {
+ cerr << prog << ": positive integer expected: " << optarg << endl;
+ exit( RC_ERROR );
+ }
+ break;
+ case 'c':
+ withDump = true;
+ break;
+ case 'h':
+ case '?':
+ case ':':
+ usage(prog);
+ exit( RC_OK );
+ break;
+ }
+ }
+ if (optind < argc || argc == 1)
+ {
+ usage( prog );
+ exit( RC_ERROR );
+ }
+
+ connect( db );
+
+ if (blobOid > 0)
+ readFromDb( blobOid, withDump );
+ else
+ readAllFromDb( withDump );
+
+ disconnect();
+
+ cout << prog << ": done." << endl;
+}
+
diff --git a/relblobif/test/dblob.C b/relblobif/test/dblob.C
new file mode 100644
index 0000000..c9e2f3d
--- /dev/null
+++ b/relblobif/test/dblob.C
@@ -0,0 +1,242 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community 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 General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+#include "databaseif.hh"
+#include "transactionif.hh"
+#include "adminif.hh"
+#include "typefactory.hh"
+#include "blobtile.hh"
+#include "raslib/rmdebug.hh"
+#include <iostream.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "externs.h"
+#include "dbref.hh"
+
+RMINITGLOBALS('C')
+
+
+int
+main(int argc, char *argv[])
+ {
+ try {
+ RManDebug = 12;
+ RMInit::dbgOut = cout.rdbuf();
+ if (argc == 1)
+ {
+ printf("Usage:\n");
+ printf("\t%s DBNAME TEST ARGS\n", argv[0]);
+ printf("\twith DBNAME the name of the Database\n");
+ printf("\tand TEST of:\n");
+ printf("\t\t1 : Read BLOBTile ARGS=BlobId\n");
+ printf("\t\t2 : Insert new BLOBTile ARGS=Blobdata\n");
+ printf("\t\t3 : same as above with commit\n");
+ printf("\t\t4 : Update BLOBTile ARGS=BlobId Blobdata\n");
+ printf("\t\t5 : Delete BLOBTile ARGS=BlobId\n");
+ printf("\t\t6 : Insert new BLOBTile ARGS=Blobdatalength\n");
+ }
+ else {
+ if (argc >= 3)
+ {
+ AdminIf* myAdmin;
+ DatabaseIf database;
+ TransactionIf ta;
+ OId* id1 = 0;
+ BLOBTile* b = 0;
+ DbRef<BLOBTile> d;
+
+ short test = atoi(argv[2]);
+ RManDebug = 12;
+ switch (test)
+ {
+ case 1:
+ if (argc == 4)
+ {
+ cout << "Connect to Database: " << argv[1] << endl;
+ myAdmin = AdminIf::instance();
+ database.open(argv[1]);
+ ta.begin(&database);
+
+ id1 = new OId(atof(argv[3]));
+ cout << "Reading BLOBTile with Id " << *id1 << endl;
+ cout << "scop1" << endl;
+ {
+ d = DbRef<BLOBTile>(*id1);
+ cout << "Got BLOBTile" << endl;
+ cout << *d;
+ cout << "Refcount\t:" << d->getReferenceCount() << endl;
+ }
+ cout << "scop1" << endl;
+ ta.abort();
+ database.close();
+ delete myAdmin;
+ }
+ else {
+ printf("YOU DIRTY ASHOLE! NOT THE RIGHT COUNT OF ARGS!\n");
+ }
+ break;
+ case 2:
+ if (argc == 4)
+ {
+ cout << "Connect to Database: " << argv[1] << endl;
+ myAdmin = AdminIf::instance();
+ database.open(argv[1]);
+ ta.begin(&database);
+
+ b = new BLOBTile(strlen(argv[3]), argv[3]);
+ cout << *b;
+ //unneeded b->setPersistent(1);
+ b->validate();
+
+ cout << "Aborting Transaction" << endl;
+ ta.abort();
+ database.close();
+ delete myAdmin;
+ }
+ else {
+ printf("YOU DIRTY ASHOLE! NOT THE RIGHT COUNT OF ARGS!\n");
+ }
+ break;
+
+ case 3:
+ if (argc == 4)
+ {
+ cout << "Connect to Database: " << argv[1] << endl;
+ myAdmin = AdminIf::instance();
+ database.open(argv[1]);
+ ta.begin(&database);
+
+ b = new BLOBTile(strlen(argv[3]), argv[3]);
+ //unneeded b->setPersistent(1);
+ cout << *b;
+ b->validate();
+
+ cout << "Commiting Transaction" << endl;
+ ta.commit();
+ database.close();
+ delete myAdmin;
+ }
+ else {
+ printf("YOU DIRTY ASHOLE! NOT THE RIGHT COUNT OF ARGS!\n");
+ }
+ break;
+
+ case 4:
+ if (argc == 5)
+ {
+ cout << "Connect to Database: " << argv[1] << endl;
+ myAdmin = AdminIf::instance();
+ database.open(argv[1]);
+ ta.begin(&database);
+
+ id1 = new OId(atof(argv[3]));
+ cout << "Reading BLOBTile with Id " << *id1 << endl;
+ d = DbRef<BLOBTile>(*id1);
+ cout << *d;
+
+ cout << "Resizing BLOBTile to " << strlen(argv[4]) << endl;
+ d->resize(strlen(argv[4]));
+ cout << *d;
+
+ cout << "Overwriting BLOBTile data" << endl;
+ memcpy(d->getCells(), argv[4], d->getSize());
+ cout << *d;
+
+ cout << "Updating Database" << endl;
+ d->setModified();
+
+ cout << "Commiting Transaction" << endl;
+ ta.commit();
+ database.close();
+ delete myAdmin;
+ }
+ else {
+ printf("YOU DIRTY ASHOLE! NOT THE RIGHT COUNT OF ARGS!\n");
+ }
+
+
+ case 5:
+ if (argc == 4)
+ {
+ cout << "Connect to Database: " << argv[1] << endl;
+ myAdmin = AdminIf::instance();
+ database.open(argv[1]);
+ ta.begin(&database);
+
+ id1 = new OId(atof(argv[3]));
+ cout << "Reading BLOBTile with Id " << *id1 << endl;
+ d = DbRef<BLOBTile>(*id1);
+ cout << *d;
+
+ cout << "Deleting BLOBTile from Database" << endl;
+ d->setPersistent(0);
+ cout << *d;
+
+ cout << "Commiting Transaction" << endl;
+ ta.commit();
+ database.close();
+ delete myAdmin;
+ }
+ else {
+ printf("YOU DIRTY ASHOLE! NOT THE RIGHT COUNT OF ARGS!\n");
+ }
+ case 6:
+ if (argc == 4)
+ {
+ cout << "Connect to Database: " << argv[1] << endl;
+ myAdmin = AdminIf::instance();
+ database.open(argv[1]);
+ ta.begin(&database);
+
+ b = new BLOBTile(atol(argv[3]), 'c');
+ cout << *b;
+ //unneeded b->setPersistent(1);
+ b->validate();
+
+ cout << "Commiting Transaction" << endl;
+ ta.commit();
+ database.close();
+ delete myAdmin;
+ }
+ else {
+ printf("YOU DIRTY ASHOLE! NOT THE RIGHT COUNT OF ARGS!\n");
+ }
+ break;
+
+ }
+ }
+ else {
+ printf("TOO FEW ARGS\n");
+ if (argc == 0)
+ {
+ TypeFactory type_();
+ }
+ }
+ }
+ }
+ catch (r_Error e)
+ {
+ cout << "caught " << e.what() << " kind " << e.get_kind() << " #" << e.get_errorno() << endl;
+ }
+ return 0;
+ }