rasdaman server"
#define DEFAULT_SERV "localhost"
#define PARAM_PORT_FLAG 'p'
#define PARAM_PORT "port"
#define HELP_PORT " rasmgr port number"
#define DEFAULT_PORT 7001
#define DEFAULT_PORT_STR "7001"
#define PARAM_DB_FLAG 'd'
#define PARAM_DB "database"
#define HELP_DB " name of database"
#define DEFAULT_DB "RASBASE"
#define PARAM_USER "user"
#define HELP_USER " name of user"
#define DEFAULT_USER "rasguest"
#define PARAM_PASSWD "passwd"
#define HELP_PASSWD " password of user"
#define DEFAULT_PASSWD "rasguest"
#define PARAM_FILE_FLAG 'f'
#define PARAM_FILE "file"
#define HELP_FILE " file name for upload through $i parameters within queries; each $i needs its own file parameter, in proper sequence. Requires --mdddomain and --mddtype"
#define PARAM_DOMAIN "mdddomain"
#define HELP_DOMAIN " domain of marray, format: \'[x0:x1,y0:y1]\' (required only if --file specified and file is in data format r_Array)"
#define PARAM_MDDTYPE "mddtype"
// this is for display only; internally MDD_STRINGTYPE is used
#define DEFAULT_MDDTYPE "byte string"
#define HELP_MDDTYPE " type of marray (required only if --file specified and file is in data format r_Array)"
#define PARAM_QUERY_FLAG 'q'
#define PARAM_QUERY "query"
#define HELP_QUERY " query string to be sent to the rasdaman server for execution"
#define PARAM_OUT "out"
#define HELP_OUT " use display method t for cell values of result MDDs where t is one of none, file, formatted, string, hex. Implies --content"
#define DEFAULT_OUT OUT_NONE
#define PARAM_OUT_FILE "file"
#define PARAM_OUT_STRING "string"
#define PARAM_OUT_HEX "hex"
#define PARAM_OUT_FORMATTED "formatted"
#define PARAM_OUT_NONE "none"
#define DEFAULT_OUT_STR PARAM_OUT_NONE
#define PARAM_CONTENT "content"
#define HELP_CONTENT "display result, if any (see also --out and --type for output formatting)"
#define PARAM_TYPE "type"
#define HELP_TYPE "display type information for results"
#define PARAM_OUTFILE_FLAG 'o'
#define PARAM_OUTFILE "outfile"
#define HELP_OUTFILE " file name template for storing result images (ignored for scalar results). Use '%d' to indicate auto numbering position, like with printf(1). For well-known file types, a proper suffix is appended to the resulting file name. Implies --out file."
#define DEFAULT_OUTFILE "rasql_%d"
#define PARAM_QUIET "quiet"
#define HELP_QUIET "print no ornament messages, only results and errors"
#define PARAM_DEBUG "debug"
#define HELP_DEBUG "generate diagnostic output"
// global variables and default settings
// -------------------------------------
r_Database db;
r_Transaction ta;
bool dbIsOpen = false;
bool taIsOpen = false;
// suppress regular messages in log? (cmd line parameter '--quiet')
bool quietLog = false;
// logging mechanism that respects 'quiet' flag:
#define LOG(a) { if (!quietLog) std::cout << a; }
int optionValueIndex=0;
const char *serverName = DEFAULT_SERV;
r_ULong serverPort = DEFAULT_PORT;
const char *baseName = DEFAULT_DB;
const char *user = DEFAULT_USER;
const char *passwd = DEFAULT_PASSWD;
const char *fileName = NULL;
const char *queryString=NULL;
bool output = false;
bool displayType = false;
OUTPUT_TYPE outputType = DEFAULT_OUT;
const char *outFileMask = DEFAULT_OUTFILE;
r_Minterval mddDomain;
bool mddDomainDef = false;
const char* mddTypeName = NULL;
bool mddTypeNameDef = false;
// query result set.
// we define it here because on empty results the set seems to be corrupt which kills the default destructor
r_Set< r_Ref_Any > result_set;
// end of globals
void
parseParams(int argc, char** argv) throw (RasqlError, r_Error)
{
CommandLineParser &cmlInter = CommandLineParser::getInstance();
CommandLineParameter &clp_help = cmlInter.addFlagParameter( PARAM_HELP_FLAG, PARAM_HELP, HELP_HELP );
CommandLineParameter &clp_query = cmlInter.addStringParameter(PARAM_QUERY_FLAG, PARAM_QUERY, HELP_QUERY );
CommandLineParameter &clp_file = cmlInter.addStringParameter(PARAM_FILE_FLAG, PARAM_FILE, HELP_FILE );
CommandLineParameter &clp_content = cmlInter.addFlagParameter( CommandLineParser::noShortName, PARAM_CONTENT, HELP_CONTENT );
CommandLineParameter &clp_out = cmlInter.addStringParameter( CommandLineParser::noShortName, PARAM_OUT, HELP_OUT, DEFAULT_OUT_STR );
CommandLineParameter &clp_outfile = cmlInter.addStringParameter( CommandLineParser::noShortName, PARAM_OUTFILE, HELP_OUTFILE, DEFAULT_OUTFILE );
CommandLineParameter &clp_mddDomain = cmlInter.addStringParameter( CommandLineParser::noShortName, PARAM_DOMAIN, HELP_DOMAIN );
CommandLineParameter &clp_mddType = cmlInter.addStringParameter( CommandLineParser::noShortName, PARAM_MDDTYPE, HELP_MDDTYPE, DEFAULT_MDDTYPE );
CommandLineParameter &clp_type = cmlInter.addFlagParameter( CommandLineParser::noShortName, PARAM_TYPE, HELP_TYPE );
CommandLineParameter &clp_server = cmlInter.addStringParameter( PARAM_SERV_FLAG, PARAM_SERV, HELP_SERV, DEFAULT_SERV );
CommandLineParameter &clp_port = cmlInter.addStringParameter( PARAM_PORT_FLAG, PARAM_PORT, HELP_PORT, DEFAULT_PORT_STR);
CommandLineParameter &clp_database = cmlInter.addStringParameter( PARAM_DB_FLAG, PARAM_DB, HELP_DB, DEFAULT_DB );
CommandLineParameter &clp_user = cmlInter.addStringParameter(CommandLineParser::noShortName, PARAM_USER, HELP_USER, DEFAULT_USER );
CommandLineParameter &clp_passwd = cmlInter.addStringParameter(CommandLineParser::noShortName, PARAM_PASSWD, HELP_PASSWD, DEFAULT_PASSWD );
CommandLineParameter &clp_quiet = cmlInter.addFlagParameter(CommandLineParser::noShortName, PARAM_QUIET, HELP_QUIET );
#ifdef DEBUG
CommandLineParameter &clp_debug = cmlInter.addFlagParameter( CommandLineParser::noShortName, PARAM_DEBUG, HELP_DEBUG );
#endif
try
{
cmlInter.processCommandLine(argc, argv);
if (cmlInter.isPresent( PARAM_HELP_FLAG ) || argc == 1)
{
cout << "usage: " << argv[0] << " [--query querystring|-q querystring] [options]" << endl;
cout << "options:" << endl;
cmlInter.printHelp();
exit( EXIT_USAGE ); // FIXME: exit no good style!!
}
// check mandatory parameters ====================================================
// evaluate mandatory parameter collection --------------------------------------
if (cmlInter.isPresent( PARAM_QUERY ))
queryString = cmlInter.getValueAsString( PARAM_QUERY );
else
throw RasqlError( NOQUERY );
// check optional parameters ====================================================
// evaluate optional parameter file --------------------------------------
if (cmlInter.isPresent( PARAM_FILE ))
fileName = cmlInter.getValueAsString( PARAM_FILE );
// evaluate optional parameter server --------------------------------------
if (cmlInter.isPresent( PARAM_SERV ))
serverName = cmlInter.getValueAsString( PARAM_SERV );
// evaluate optional parameter port --------------------------------------
if (cmlInter.isPresent( PARAM_PORT ))
serverPort = cmlInter.getValueAsLong( PARAM_PORT );
// evaluate optional parameter database --------------------------------------
if (cmlInter.isPresent( PARAM_DB ))
baseName = cmlInter.getValueAsString( PARAM_DB );
// evaluate optional parameter user --------------------------------------
if (cmlInter.isPresent( PARAM_USER ))
user = cmlInter.getValueAsString( PARAM_USER );
// evaluate optional parameter passwd --------------------------------------
if (cmlInter.isPresent( PARAM_PASSWD ))
passwd = cmlInter.getValueAsString( PARAM_PASSWD );
// evaluate optional parameter content --------------------------------------
if (cmlInter.isPresent( PARAM_CONTENT ))
output = true;
// evaluate optional parameter type --------------------------------------
if (cmlInter.isPresent( PARAM_TYPE ))
displayType = true;
// evaluate optional parameter hex --------------------------------------
if (cmlInter.isPresent( PARAM_OUT ))
{
output = true;
const char* val = cmlInter.getValueAsString( PARAM_OUT );
if (val !=0 && strcmp( val, PARAM_OUT_STRING ) == 0)
outputType = OUT_STRING;
else if (val !=0 && strcmp( val, PARAM_OUT_FILE ) == 0)
outputType = OUT_FILE;
else if (val !=0 && strcmp( val, PARAM_OUT_FORMATTED ) == 0)
outputType = OUT_FORMATTED;
else if (val !=0 && strcmp( val, PARAM_OUT_HEX ) == 0)
outputType = OUT_HEX;
else if (val !=0 && strcmp( val, PARAM_OUT_NONE ) == 0)
outputType = OUT_NONE;
else
throw RasqlError( ILLEGALOUTPUTTYPE );
}
// evaluate optional parameter outfile --------------------------------------
if (cmlInter.isPresent( PARAM_OUTFILE ))
{
outFileMask = cmlInter.getValueAsString( PARAM_OUTFILE );
outputType = OUT_FILE;
}
// evaluate optional parameter domain --------------------------------------
if ( cmlInter.isPresent( PARAM_DOMAIN ) )
{
try
{
mddDomain = r_Minterval(cmlInter.getValueAsString( PARAM_DOMAIN ));
mddDomainDef = true;
}
catch ( r_Error& e ) // Minterval constructor had syntax problems
{
throw RasqlError( NOVALIDDOMAIN );
}
}
// evaluate optional parameter MDD type name --------------------------------------
if (cmlInter.isPresent( PARAM_MDDTYPE ))
{
mddTypeName = cmlInter.getValueAsString( PARAM_MDDTYPE );
mddTypeNameDef = true;
}
// evaluate optional parameter 'quiet' --------------------------------------------
if (cmlInter.isPresent( PARAM_QUIET ))
{
quietLog = true;
}
#ifdef DEBUG
// evaluate optional parameter MDD type name --------------------------------------
SET_OUTPUT( cmlInter.isPresent( PARAM_DEBUG ) );
#endif
}
catch(CmlException& err)
{
cerr << err.what() << endl;
throw RasqlError( ERRORPARSINGCOMMANDLINE );
}
} // parseParams()
void
openDatabase() throw (r_Error)
{
ENTER( "openDatabase" );
if (! dbIsOpen)
{
LOG( "opening database " << baseName << " at " << serverName << ":" << serverPort << "..." << flush );
db.set_servername(serverName, serverPort);
db.set_useridentification(user, passwd);
TALK( "database was closed, opening database=" << baseName << ", server=" << serverName << ", port=" << serverPort << ", user=" << user << ", passwd=" << passwd << "..." );
db.open(baseName);
TALK( "ok" );
dbIsOpen = true;
LOG( "ok" << endl << flush );
}
LEAVE( "openDatabase" );
} // openDatabase()
void
closeDatabase() throw (r_Error)
{
ENTER( "closeDatabase" );
if (dbIsOpen)
{
TALK( "database was open, closing it" );
db.close();
dbIsOpen = false;
}
LEAVE( "closeDatabase" );
return;
} // closeDatabase()
void
openTransaction(bool readwrite) throw (r_Error)
{
ENTER( "openTransaction, readwrite=" << (readwrite ? "rw" : "ro" ) );
if (! taIsOpen)
{
if (readwrite)
{
TALK( "transaction was closed, opening rw..." );
ta.begin(r_Transaction::read_write);
TALK( "ok" );
}
else
{
TALK( "transaction was closed, opening ro..." );
ta.begin(r_Transaction::read_only);
TALK( "ok" );
}
taIsOpen = true;
}
LEAVE( "openTransaction" );
} // openTransaction()
void
closeTransaction( bool doCommit ) throw (r_Error)
{
ENTER( "closeTransaction, doCommit=" << doCommit );
if (taIsOpen)
{
if (doCommit)
{
TALK( "transaction was open, committing it..." );
ta.commit();
TALK( "ok" );
}
else
{
TALK( "transaction was open, aborting it..." );
ta.abort();
TALK( "ok" );
}
taIsOpen = false;
}
LEAVE( "closeTransaction" );
return;
} // closeTransaction()
void printScalar( const r_Scalar& scalar )
{
ENTER( "printScalar" );
switch( scalar.get_type()->type_id() )
{
case r_Type::BOOL:
LOG( ( ((r_Primitive*)&scalar)->get_boolean() ? "t" : "f" ) << flush );
break;
case r_Type::CHAR:
LOG( (int)((r_Primitive*)&scalar)->get_char() << flush );
break;
case r_Type::OCTET:
LOG( (int)((r_Primitive*)&scalar)->get_octet() << flush );
break;
case r_Type::SHORT:
LOG( ((r_Primitive*)&scalar)->get_short() << flush );
break;
case r_Type::USHORT:
LOG( ((r_Primitive*)&scalar)->get_ushort() << flush );
break;
case r_Type::LONG:
LOG( ((r_Primitive*)&scalar)->get_long() << flush );
break;
case r_Type::ULONG:
LOG( ((r_Primitive*)&scalar)->get_ulong() << flush );
break;
case r_Type::FLOAT:
LOG( ((r_Primitive*)&scalar)->get_float() << flush );
break;
case r_Type::DOUBLE:
LOG( ((r_Primitive*)&scalar)->get_double() << flush );
break;
case r_Type::COMPLEXTYPE1:
case r_Type::COMPLEXTYPE2:
LOG( "(" << ((r_Complex*)&scalar)->get_re() << "," << ((r_Complex*)&scalar)->get_im() << ")" << flush );
break;
case r_Type::STRUCTURETYPE:
{
r_Structure* structValue = (r_Structure*)&scalar;
LOG( "{ " << flush );
for( int i=0; icount_elements(); i++ )
{
printScalar( (*structValue)[i] );
if( i < structValue->count_elements()-1 )
LOG( ", " << flush );
}
LOG( " }" << endl );
}
break;
default:
LOG( "scalar type " << scalar.get_type()->type_id() << " not supported!" << endl );
break;
}
LEAVE( "printScalar" );
} // printScalar()
// result_set should be parameter, but is global -- see def for reason
void printResult( /* r_Set< r_Ref_Any > result_set */ )
{
ENTER( "printResult" );
LOG( "Query result collection has " << result_set.cardinality() << " element(s):" << endl );
if (displayType)
{
cout << " Oid...................: " << result_set.get_oid() << endl;
cout << " Type Structure........: "
<< ( result_set.get_type_structure() ? result_set.get_type_structure() : "" ) << endl;
cout << " Type Schema...........: " << flush;
if( result_set.get_type_schema() )
result_set.get_type_schema()->print_status( cout );
else
cout << "(no name)" << flush;
cout << endl;
cout << " Number of entries.....: " << result_set.cardinality() << endl;
cout << " Element Type Schema...: " << flush;
if( result_set.get_element_type_schema() )
result_set.get_element_type_schema()->print_status( cout );
else
cout << "(no name)" << flush;
cout << endl;
}
/* The following can be used if the type is known and the element type is not atomic.
r_Set< r_Ref< r_Point > >* set2 = (r_Set< r_Ref< r_Point > >*)&result_set;
r_Iterator< r_Ref > iter2 = set2->create_iterator();
for( iter2.reset(); iter2.not_done(); iter2++ )
cout << **iter2 << endl;
*/
r_Iterator< r_Ref_Any > iter = result_set.create_iterator();
// iter.not_done() seems to behave wrongly on empty set, therefore this additional check -- PB 2003-aug-16
for ( int i=1 ; i<=result_set.cardinality() && iter.not_done(); iter++, i++ )
{
switch( result_set.get_element_type_schema()->type_id() )
{
case r_Type::MARRAYTYPE:
switch ( outputType )
{
case OUT_NONE:
break;
case OUT_STRING:
{
int numCells = r_Ref(*iter)->get_array_size();
const char* theStuff = r_Ref(*iter)->get_array();
LOG( " Result object " << i << ": " );
for (int cnt = 0; cnt < numCells; cnt++)
cout << theStuff[cnt];
cout << endl;
}
break;
case OUT_HEX:
{
int numCells = r_Ref(*iter)->get_array_size();
const char* theStuff = r_Ref(*iter)->get_array();
LOG( " Result object " << i << ": " );
cout << hex;
for (int cnt = 0; cnt < numCells; cnt++)
cout << setw(2) << (unsigned short) (0xff & theStuff[cnt]) << " ";
cout << dec << endl;
}
break;
case OUT_FORMATTED:
LOG( " Result object " << i << ":" << endl );
// for (int cnt = 0; cnt < numCells; cnt++)
printScalar( *(r_Ref(*iter)) );
cout << endl;
break;
case OUT_FILE:
{
char defFileName[FILENAME_MAX];
(void) snprintf( defFileName, sizeof(defFileName)-1, outFileMask, i );
TALK( "filename for #" << i << " is " << defFileName );
// special treatment only for DEFs
r_Data_Format mafmt = r_Ref(*iter)->get_current_format();
switch (mafmt)
{
case r_TIFF:
strcat( defFileName, ".tif" ); break;
case r_JPEG:
strcat( defFileName, ".jpg" ); break;
case r_HDF:
strcat( defFileName, ".hdf" ); break;
case r_PNG:
strcat( defFileName, ".png" ); break;
case r_BMP:
strcat( defFileName, ".bmp" ); break;
case r_VFF:
strcat( defFileName, ".vff" ); break;
default:
strcat( defFileName, ".unknown" ); break;
break;
}
LOG( " Result object " << i << ": going into file " << defFileName << "..." << flush );
FILE *tfile = fopen( defFileName, "wb" );
fwrite((void*)r_Ref(*iter)->get_array(), 1, r_Ref(*iter)->get_array_size(), tfile );
fclose(tfile);
LOG( "ok." << endl );
}
break;
default:
cerr << "Internal error: unknown output type, ignoring action: " << outputType << endl;
break;
} // switch(outputType)
break;
case r_Type::POINTTYPE:
LOG( " Result element " << i << ": " );
cout << *(r_Ref(*iter)) << endl;
break;
case r_Type::SINTERVALTYPE:
LOG( " Result element " << i << ": " );
cout << *(r_Ref(*iter)) << endl;
break;
case r_Type::MINTERVALTYPE:
LOG( " Result element " << i << ": " );
cout << *(r_Ref(*iter)) << endl;
break;
case r_Type::OIDTYPE:
LOG( " Result element " << i << ": " );
cout << *(r_Ref(*iter)) << endl;
break;
default:
LOG( " Result element " << i << ": " << flush );
printScalar( *(r_Ref(*iter)) );
cout << endl;
// or simply
// r_Ref(*iter)->print_status( cout );
} // switch
} // for(...)
LEAVE( "printResult" );
} // printResult()
/*
* get database type structure from type name
* returns ptr if an MDD type with the given name exists in the database, NULL otherwise
* throws r_Error upon general database comm error
* needs an open transaction
*/
r_Marray_Type * getTypeFromDatabase( const char *mddTypeName ) throw(RasqlError, r_Error)
{
ENTER( "getTypeFromDatabase, mddTypeName=" << mddTypeName );
r_Marray_Type *retval = NULL;
char* typeStructure = NULL;
// first, try to get type structure from database using a separate r/o transaction
try
{
typeStructure = db.getComm()->getTypeStructure(mddTypeName, ClientComm::r_MDDType_Type);
TALK( "type structure is " << typeStructure );
}
catch (r_Error& err)
{
if (err.get_kind() == r_Error::r_Error_DatabaseClassUndefined)
{
TALK( "Type is not a well known type: " << typeStructure );
typeStructure = new char[strlen(mddTypeName) + 1];
// earlier code tried this one below, but I feel we better are strict -- PB 2003-jul-06
// strcpy(typeStructure, mddTypeName);
// TALK( "using instead: " << typeStructure );
throw RasqlError( MDDTYPEINVALID );
}
else // unanticipated error
{
TALK( "Error during type retrieval from database: " << err.get_errorno() << " " << err.what() );
throw;
}
}
// next, find out whether it is an MDD type (and not a base or set type, eg)
try
{
r_Type* tempType = r_Type::get_any_type(typeStructure);
TALK( "get_any_type() for this type returns: " << tempType );
if (tempType->isMarrayType())
{
retval = (r_Marray_Type*)tempType;
tempType = NULL;
TALK( "found MDD type: " << retval );
}
else
{
TALK( "type is not an marray type: " << typeStructure );
delete tempType;
tempType = NULL;
retval = NULL;
throw RasqlError( MDDTYPEINVALID );
}
}
catch (r_Error& err)
{
TALK( "Error during retrieval of MDD type structure (" << typeStructure << "): " << err.get_errorno() << " " << err.what() );
throw;
}
delete [] typeStructure;
typeStructure = NULL;
LEAVE( "getTypeFromDatabase, retval=" << retval );
return retval;
} // getTypeFromDatabase()
void doStuff( int argc, char** argv ) throw (r_Error)
{
char *fileContents = NULL; // contents of file satisfying "$1" parameter in query
r_Ref fileMDD = NULL; // MDD to satisfy a "$1" parameter
r_Marray_Type *mddType = NULL; // this MDD's type
ENTER( "doStuff" );
r_OQL_Query query( queryString );
TALK( "query is: " << query.get_query() );
if ( fileName != NULL )
{
openTransaction( false );
// if no type name was specified then assume byte string (for encoded files)
if ( ! mddTypeNameDef )
mddTypeName = MDD_STRINGTYPE;
LOG( "fetching type information for " << mddTypeName << " from database, using readonly transaction..." << flush );
mddType = getTypeFromDatabase( mddTypeName );
closeTransaction( true );
LOG( "ok" << endl );
LOG( "reading file " << fileName << "..." << flush );
FILE* fileD = fopen( fileName, "r" );
if (fileD == NULL)
throw RasqlError( FILEINACCESSIBLE );
fseek( fileD, 0, SEEK_END );
int size = ftell( fileD );
TALK( "file size is " << size << " bytes" );
try
{
fileContents = new char[size];
}
catch(std::bad_alloc)
{
TALK( "Unable to claim memory: " << size << " Bytes" );
throw RasqlError( UNABLETOCLAIMRESOURCEFORFILE );
}
fseek( fileD, 0, SEEK_SET );
fread( fileContents, 1, size, fileD );
fclose( fileD );
// if no domain specified (this is the case with encoded files), then set to byte stream:
if ( ! mddDomainDef )
{
mddDomain = r_Minterval( 1 ) << r_Sinterval ( 0, size-1 );
TALK( "domain set to " << mddDomain );
}
if (size != mddDomain.cell_count() * mddType->base_type().size())
throw RasqlError( FILESIZEMISMATCH );
LOG( "ok" << endl );
TALK( "setting up MDD with domain " << mddDomain << " and base type " << mddTypeName );
fileMDD = new (mddTypeName) r_GMarray( mddDomain, mddType->base_type().size() );
fileMDD->set_type_schema( mddType );
fileMDD->set_array_size( mddDomain.cell_count() * mddType->base_type().size() );
fileMDD->set_array( fileContents );
query << *fileMDD;
TALK( "constants are:" );
r_Set * myConstSet = (r_Set *) query.get_constants();
r_Iterator< r_GMarray *> iter = myConstSet->create_iterator();
int i;
for ( i=1, iter.reset(); iter.not_done(); iter++, i++ )
{
r_Ref< r_GMarray > myConstant = *iter;
LOG( " constant " << i << ": " );
myConstant->print_status( cout );
// the following can be used for sporadic debugging of input files, but beware: is very verbose!
#if 0
cout << " Contents: " << hex;
const char *a = myConstant->get_array();
for (int m=0; m < myConstant->get_array_size(); m++)
cout << (unsigned short) (a[m] & 0xFF) << " ";
cout << dec << endl;
#endif
}
}
if( query.is_update_query() )
{
openTransaction( true );
r_Marray* mddConst = NULL;
LOG( "Executing update query..." << flush );
r_oql_execute( query );
LOG( "ok" << endl );
if( mddConst )
delete mddConst;
closeTransaction( true );
}
else
{
openTransaction( false );
// should be defined here, but is global; see def for reason
// r_Set< r_Ref_Any > result_set;
LOG( "Executing retrieval query..." << flush );
r_oql_execute( query, result_set );
LOG( "ok" << endl );
// generate output only if explicitly requested
if( output )
printResult( /* result_set */ );
closeTransaction( true );
}
if (fileContents != NULL)
delete [] fileContents;
LEAVE( "doStuff" );
}
/*
* returns 0 on success, -1 on error
*/
int main(int argc, char** argv)
{
SET_OUTPUT( false ); // inhibit unconditional debug output, await cmd line evaluation
int retval = EXIT_SUCCESS; // overall result status
try
{
parseParams( argc, argv );
// put LOG after parsing parameters to respect a '--quiet'
LOG( argv[0] << ": rasdaman query tool v1.0, rasdaman v" << RMANVERSION/1000 << " -- generated on " << COMPDATE << "." << endl );
openDatabase();
doStuff( argc, argv );
closeDatabase();
retval = EXIT_SUCCESS;
}
catch (RasqlError& e)
{
cerr << argv[0] << ": " << e.what() << endl;
retval = EXIT_FAILURE;
}
catch (const r_Error& e)
{
cerr << "rasdaman error " << e.get_errorno() << ": " << e.what() << endl;
retval = EXIT_FAILURE;
}
catch (...)
{
cerr << argv[0] << ": panic: unexpected internal exception." << endl;
retval = EXIT_FAILURE;
}
if (retval != EXIT_SUCCESS && (dbIsOpen || taIsOpen) )
{
LOG( "aborting transaction..." << flush );
closeTransaction( false ); // abort transaction and close database, ignore any further exceptions
LOG( "ok" << endl );
closeDatabase();
}
LOG( argv[0] << " done." << endl );
return retval;
} // main()
// end of rasql.cc