summaryrefslogtreecommitdiffstats
path: root/rasodmg/oqlquery.cc
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 /rasodmg/oqlquery.cc
downloadrasdaman-upstream-8f27e65bddd7d4b8515ce620fb485fdd78fcdf89.tar.gz
rasdaman-upstream-8f27e65bddd7d4b8515ce620fb485fdd78fcdf89.tar.xz
rasdaman-upstream-8f27e65bddd7d4b8515ce620fb485fdd78fcdf89.zip
Initial commitv8.0
Diffstat (limited to 'rasodmg/oqlquery.cc')
-rw-r--r--rasodmg/oqlquery.cc628
1 files changed, 628 insertions, 0 deletions
diff --git a/rasodmg/oqlquery.cc b/rasodmg/oqlquery.cc
new file mode 100644
index 0000000..4b1a3f1
--- /dev/null
+++ b/rasodmg/oqlquery.cc
@@ -0,0 +1,628 @@
+/*
+* 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>.
+/
+/**
+ * SOURCE: oqlquery.cc
+ *
+ * MODULE: rasodmg
+ * CLASS: r_OQL_Query
+ * FUNCTION: r_oql_execute()
+ *
+ * COMMENTS:
+ * None
+*/
+
+static const char rcsid[] = "@(#)rasodmg, r_OQL_Query and r_oql_execute(): $Id: oqlquery.cc,v 1.25 2002/08/28 12:21:57 coman Exp $";
+
+#include "rasodmg/oqlquery.hh"
+
+#include <string.h>
+#include <ctype.h> // isdigit()
+#ifdef __VISUALC__
+#include <strstrea.h>
+#else
+#include <strstream>
+#endif
+
+#ifdef __VISUALC__
+#ifndef __EXECUTABLE__
+#define __EXECUTABLE__
+#define OQLQUERY_NOT_SET
+#endif
+#endif
+
+#include "rasodmg/database.hh"
+#include "rasodmg/transaction.hh"
+#include "rasodmg/set.hh"
+#include "rasodmg/gmarray.hh"
+
+#include "raslib/rmdebug.hh"
+#include "clientcomm/clientcomm.hh"
+
+#ifdef OQLQUERY_NOT_SET
+#undef __EXECUTABLE__
+#endif
+
+r_OQL_Query::r_OQL_Query()
+ : queryString(0),
+ parameterizedQueryString(0),
+ mddConstants(0)
+{
+}
+
+
+r_OQL_Query::r_OQL_Query( const char* s )
+ : queryString(0),
+ mddConstants(0)
+{
+ parameterizedQueryString = new char[strlen(s)+1];
+ strcpy( parameterizedQueryString, s );
+
+ reset_query();
+}
+
+
+r_OQL_Query::r_OQL_Query( const r_OQL_Query& q )
+ : queryString(0),
+ parameterizedQueryString(0),
+ mddConstants(0)
+{
+ // copy the query string
+ if(q.queryString) {
+ queryString = new char[strlen(q.queryString)+1];
+ strcpy( queryString, q.queryString);
+ }
+
+ // copy the parameterized query string
+ if(q.parameterizedQueryString) {
+ parameterizedQueryString = new char[strlen(q.parameterizedQueryString)+1];
+ strcpy( parameterizedQueryString, q.parameterizedQueryString );
+ }
+
+ if( q.mddConstants ) {
+ mddConstants = new r_Set< r_GMarray* >( *(q.mddConstants) );
+ }
+}
+
+
+r_OQL_Query::~r_OQL_Query()
+{
+ if( queryString )
+ delete[] queryString;
+ queryString = 0;
+
+ if( parameterizedQueryString )
+ delete[] parameterizedQueryString;
+ parameterizedQueryString = 0;
+
+ if( mddConstants )
+ delete mddConstants;
+ mddConstants = 0;
+}
+
+
+const r_OQL_Query&
+r_OQL_Query::operator=( const r_OQL_Query& q )
+{
+ if( this != &q )
+ {
+ // clean up and copy the query string
+
+ if( queryString )
+ {
+ delete[] queryString;
+ queryString = 0;
+ }
+
+ if( q.queryString )
+ {
+ queryString = new char[strlen(q.queryString)+1];
+ strcpy( queryString, q.queryString );
+ }
+
+ if( mddConstants )
+ {
+ delete mddConstants;
+ mddConstants = 0;
+ }
+
+ if( q.mddConstants )
+ {
+ mddConstants = new r_Set< r_GMarray* >( *(q.mddConstants) );
+ }
+
+ // clean up and copy the parameterized query string
+ if( parameterizedQueryString )
+ {
+ delete[] parameterizedQueryString;
+ parameterizedQueryString = 0;
+ }
+
+ if( q.parameterizedQueryString )
+ {
+ parameterizedQueryString = new char[strlen(q.parameterizedQueryString)+1];
+ strcpy( parameterizedQueryString, q.parameterizedQueryString );
+ }
+ }
+
+ return *this;
+}
+
+
+r_OQL_Query&
+r_OQL_Query::operator<<( const char* s ) throw( r_Error )
+{
+ try
+ {
+ replaceNextArgument( s );
+ }
+ catch( ... )
+ {
+ throw;
+ }
+
+ return *this;
+}
+
+
+r_OQL_Query&
+r_OQL_Query::operator<<( r_Char c ) throw( r_Error )
+{
+ char valueString[2];
+
+ valueString[0] = c;
+ valueString[1] = '\0';
+
+ try
+ {
+ replaceNextArgument( valueString );
+ }
+ catch( ... )
+ {
+ throw;
+ }
+
+ return *this;
+}
+
+
+r_OQL_Query&
+r_OQL_Query::operator<<( r_Short s ) throw( r_Error )
+{
+ char valueString[256];
+
+ std::ostrstream valueStream( valueString, 256 );
+
+ valueStream << s << std::ends;
+
+ try
+ {
+ replaceNextArgument( valueString );
+ }
+ catch( ... )
+ {
+ throw;
+ }
+
+ return *this;
+}
+
+
+r_OQL_Query&
+r_OQL_Query::operator<<( r_UShort us ) throw( r_Error )
+{
+ char valueString[256];
+
+ std::ostrstream valueStream( valueString, 256 );
+
+ valueStream << us << std::ends;
+
+ try
+ {
+ replaceNextArgument( valueString );
+ }
+ catch( ... )
+ {
+ throw;
+ }
+
+ return *this;
+}
+
+
+r_OQL_Query&
+r_OQL_Query::operator<<( r_Long l ) throw( r_Error )
+{
+ char valueString[256];
+
+ std::ostrstream valueStream( valueString, 256 );
+
+ valueStream << l << std::ends;
+
+ try
+ {
+ replaceNextArgument( valueString );
+ }
+ catch( ... )
+ {
+ throw;
+ }
+
+ return *this;
+}
+
+
+r_OQL_Query&
+r_OQL_Query::operator<<( r_ULong ul ) throw( r_Error )
+{
+ char valueString[256];
+
+ std::ostrstream valueStream( valueString, 256 );
+
+ valueStream << ul << std::ends;
+
+ try
+ {
+ replaceNextArgument( valueString );
+ }
+ catch( ... )
+ {
+ throw;
+ }
+
+ return *this;
+}
+
+
+r_OQL_Query&
+r_OQL_Query::operator<<( r_Point pt ) throw( r_Error )
+{
+ char valueString[256];
+
+ std::ostrstream valueStream( valueString, 256 );
+
+ valueStream << pt << std::ends;
+
+ try
+ {
+ replaceNextArgument( valueString );
+ }
+ catch( ... )
+ {
+ throw;
+ }
+
+ return *this;
+}
+
+
+r_OQL_Query&
+r_OQL_Query::operator<<( r_Sinterval in ) throw( r_Error )
+{
+ char valueString[256];
+
+ std::ostrstream valueStream( valueString, 256 );
+
+ valueStream << in << std::ends;
+
+ try
+ {
+ replaceNextArgument( valueString );
+ }
+ catch( ... )
+ {
+ throw;
+ }
+
+ return *this;
+}
+
+
+r_OQL_Query&
+r_OQL_Query::operator<<( r_Minterval in ) throw( r_Error )
+{
+ char valueString[256];
+
+ std::ostrstream valueStream( valueString, 256 );
+
+ valueStream << in << std::ends;
+
+ try
+ {
+ replaceNextArgument( valueString );
+ }
+ catch( ... )
+ {
+ throw;
+ }
+
+ return *this;
+}
+
+
+r_OQL_Query&
+r_OQL_Query::operator<<( r_GMarray& in ) throw( r_Error )
+{
+ // determine number of next mdd (starting with 0)
+ unsigned long mddNo = 0;
+ if( mddConstants )
+ mddNo = mddConstants->cardinality();
+
+ char valueString[256];
+ std::ostrstream valueStream( valueString, 256 );
+ valueStream << "#MDD" << mddNo << "#" << std::ends;
+
+ try
+ {
+ replaceNextArgument( valueString );
+ }
+ catch( ... )
+ {
+ throw;
+ }
+
+ // save reference to in
+ if( !mddConstants )
+ mddConstants = new r_Set< r_GMarray* >();
+
+ mddConstants->insert_element( &in );
+
+ return *this;
+}
+
+
+
+
+int
+r_OQL_Query::is_update_query() const
+{
+ return !is_retrieval_query();
+}
+
+
+
+int
+r_OQL_Query::is_retrieval_query() const
+{
+ int returnValue = 0;
+
+ if( parameterizedQueryString )
+ returnValue = strstr( parameterizedQueryString, "select" ) ||
+ strstr( parameterizedQueryString, "SELECT" );
+
+ return returnValue;
+}
+
+
+
+void
+r_OQL_Query::reset_query()
+{
+ if( queryString )
+ delete[] queryString;
+
+ queryString = new char[strlen(parameterizedQueryString)+1];
+ strcpy( queryString, parameterizedQueryString );
+
+ if( mddConstants )
+ {
+ delete mddConstants;
+ mddConstants = 0;
+ }
+}
+
+
+void
+r_OQL_Query::replaceNextArgument( const char* valueString )
+ throw( r_Error )
+{
+ char* argumentBegin=NULL;
+ char* argumentEnd=NULL;
+ char* argumentVal=NULL;
+ int argumentLength=0;
+ char* tmpString=NULL;
+ int length=0;
+
+ // locate the next argument in the query string
+
+ argumentBegin = argumentEnd = strchr( queryString, '$' );
+
+ if( !argumentBegin )
+ {
+ r_Error err = r_Error( r_Error::r_Error_QueryParameterCountInvalid );
+ throw err;
+ }
+
+ // while( *argumentEnd != ' ' && *argumentEnd != '\0' )
+ argumentEnd++;
+
+ //is digit or invalid argument format
+ if(!isdigit(*argumentEnd))
+ throw r_Error( QUERYPARAMETERINVALID );
+
+ while( isdigit(*argumentEnd) && *argumentEnd != ' ' && *argumentEnd != '\0' )
+ argumentEnd++;
+
+ argumentLength = argumentEnd - argumentBegin;
+ argumentVal = new char[ argumentLength + 1];
+ strncpy(argumentVal, argumentBegin, argumentLength);
+ argumentVal[argumentLength] = '\0';
+
+ while(true)
+ {
+ // allocate a new query string and fill it
+ tmpString = queryString;
+ length = strlen(queryString) - argumentLength + strlen(valueString);
+ queryString = new char[ length + 1 ];
+
+ *argumentBegin = '\0';
+ std::ostrstream queryStream( queryString, length + 1 );
+
+ queryStream << tmpString << valueString << argumentEnd << std::ends;
+
+ //update the reference
+ argumentEnd=queryString+strlen(tmpString)+strlen(valueString);
+
+ //remove buffer
+ delete[] tmpString;
+
+ //search again for this parameter
+ argumentEnd = argumentBegin = strstr( argumentEnd, argumentVal );
+
+ //end string?
+ if(argumentBegin == NULL)
+ break;
+
+ //skip $
+ argumentEnd++;
+
+ //is digit or invalid argument format
+ if(!isdigit(*argumentEnd))
+ {
+ delete [] argumentVal;
+ throw r_Error( QUERYPARAMETERINVALID );
+ }
+
+ //skip digits
+ while( isdigit(*argumentEnd) && *argumentEnd != ' ' && *argumentEnd != '\0' )
+ argumentEnd++;
+ }
+
+ delete[] argumentVal;
+}
+
+
+
+// HP COMPILER BUG
+// The iterator type needs a typedef because otherwise the compiler creates a duplicate
+// definition for each instance of the following template function.
+typedef r_Iterator<r_GMarray*> r_Iterator_r_GMarray;
+
+void r_oql_execute( r_OQL_Query& query, r_Set< r_Ref_Any > &result )
+ throw( r_Error )
+{
+ if( r_Database::actual_database == 0 || r_Database::actual_database->get_status() == r_Database::not_open )
+ {
+ r_Error err = r_Error( r_Error::r_Error_DatabaseClosed );
+ throw err;
+ }
+
+ if( r_Transaction::actual_transaction == 0 || r_Transaction::actual_transaction->get_status() != r_Transaction::active )
+ {
+ r_Error err = r_Error( r_Error::r_Error_TransactionNotOpen );
+ throw err;
+ }
+
+ try
+ {
+ r_Database::actual_database->getComm()->executeQuery( query, result );
+ }
+ catch( ... )
+ {
+ throw; // re-throw the exception
+ }
+
+ // reset the arguments of the query object
+ query.reset_query();
+}
+
+
+
+void r_oql_execute( r_OQL_Query& query, r_Set< r_Ref< r_GMarray > > &result )
+ throw( r_Error )
+{
+ if( r_Database::actual_database == 0 || r_Database::actual_database->get_status() == r_Database::not_open )
+ {
+ r_Error err = r_Error( r_Error::r_Error_DatabaseClosed );
+ throw err;
+ }
+
+ if( r_Transaction::actual_transaction == 0 || r_Transaction::actual_transaction->get_status() != r_Transaction::active )
+ {
+ r_Error err = r_Error( r_Error::r_Error_TransactionNotOpen );
+ throw err;
+ }
+
+ try
+ {
+ r_Set< r_Ref_Any > genericSet;
+
+
+ r_Database::actual_database->getComm()->executeQuery( query, genericSet );
+
+ const r_Type* typeSchema = genericSet.get_element_type_schema();
+
+ if( !typeSchema || typeSchema->type_id() != r_Type::MARRAYTYPE )
+ {
+ r_Error err( r_Error::r_Error_TypeInvalid );
+ throw err;
+ }
+
+ //
+ // iterate through the generic set and build a specific one
+ //
+ result.set_type_by_name( genericSet.get_type_name() );
+ result.set_type_structure( genericSet.get_type_structure() );
+
+ r_Iterator< r_Ref_Any > iter;
+ for( iter=genericSet.create_iterator(); iter.not_done(); iter++ )
+ result.insert_element( r_Ref<r_GMarray>(*iter) );
+ }
+ catch( ... )
+ {
+ throw; // re-throw the exception
+ }
+
+ // reset the arguments of the query object
+ query.reset_query();
+}
+
+
+
+void r_oql_execute( r_OQL_Query& query )
+ throw( r_Error )
+{
+ if( r_Database::actual_database == 0 || r_Database::actual_database->get_status() == r_Database::not_open )
+ {
+ r_Error err = r_Error( r_Error::r_Error_DatabaseClosed );
+ throw err;
+ }
+
+ if( r_Transaction::actual_transaction == 0 || r_Transaction::actual_transaction->get_status() != r_Transaction::active )
+ {
+ r_Error err = r_Error( r_Error::r_Error_TransactionNotOpen );
+ throw err;
+ }
+
+ try
+ {
+ r_Database::actual_database->getComm()->executeQuery( query );
+ }
+ catch( ... )
+ {
+ throw; // re-throw the exception
+ }
+
+ // reset the arguments of the query object
+ query.reset_query();
+}
+