From: <ibr...@us...> - 2010-09-24 12:20:31
|
Revision: 3692 http://tora.svn.sourceforge.net/tora/?rev=3692&view=rev Author: ibre5041 Date: 2010-09-24 12:20:23 +0000 (Fri, 24 Sep 2010) Log Message: ----------- - code cleanups - better memory allocations - stability fixes(Oracle environment is iitialized in threaded mode now) - initiall support for named collections - ANADATA supports datatime Modified Paths: -------------- branches/tora-trotl/src/trotl/src/trotl_anydata.cpp branches/tora-trotl/src/trotl/src/trotl_anydata.h branches/tora-trotl/src/trotl/src/trotl_base.h branches/tora-trotl/src/trotl/src/trotl_common.h branches/tora-trotl/src/trotl/src/trotl_date.h branches/tora-trotl/src/trotl/src/trotl_int.h branches/tora-trotl/src/trotl/src/trotl_lob.cpp branches/tora-trotl/src/trotl/src/trotl_misc.h branches/tora-trotl/src/trotl/src/trotl_rid.cpp branches/tora-trotl/src/trotl/src/trotl_stat.cpp branches/tora-trotl/src/trotl/src/trotl_stat.h branches/tora-trotl/src/trotl/src/trotl_string.h branches/tora-trotl/src/trotl/src/trotl_var.cpp branches/tora-trotl/src/trotl/src/trotl_var.h Modified: branches/tora-trotl/src/trotl/src/trotl_anydata.cpp =================================================================== --- branches/tora-trotl/src/trotl/src/trotl_anydata.cpp 2010-09-19 18:30:55 UTC (rev 3691) +++ branches/tora-trotl/src/trotl/src/trotl_anydata.cpp 2010-09-24 12:20:23 UTC (rev 3692) @@ -41,6 +41,49 @@ Util::RegisterInFactory<BindParANYDATA, CustDefineParFactTwoParmSing> regCustDefineNTY_ANYDATA("SYS.ANYDATA"); +void BindParANYDATA::init(SqlStatement &stmt) +{ + sword res; + _anydatatdo = 0; + + + _oan_buffer = new OCIAnyData* [ _cnt ]; + + res = OCICALL(OCITypeByName(_stmt._env, _stmt._errh, _stmt._conn._svc_ctx, + (const oratext*)"SYS", strlen("SYS"), + (const oratext*)"ANYDATA", strlen("ANYDATA"), + 0, 0, + OCI_DURATION_SESSION, OCI_TYPEGET_ALL, + (OCIType**) &_anydatatdo)); + oci_check_error(__TROTL_HERE__, _stmt._errh, res); + + if(_anydatatdo == NULL) + throw OciException(__TROTL_HERE__, "Unknown datatype in the database: SYS.ANYDATA"); + + for(int i=0; i<g_OCIPL_BULK_ROWS; i++) + { + _oan_buffer[i] = NULL; + } +} + +void BindParANYDATA::define_hook(SqlStatement &stmt) +{ + sword res = OCICALL(OCIDefineObject(defnpp, stmt._errh, + _anydatatdo, + (dvoid **) &(_oan_buffer[0]), //(dvoid **) &_oan_buffer, + (ub4 *) 0, + 0, //(dvoid **) &_any_indp, + (ub4 *) 0)); + oci_check_error(__TROTL_HERE__, stmt._errh, res); +// // TODO OCIDefineArrayOfStruct here ?? +} + +void BindParANYDATA::bind_hook(SqlStatement &stmt) +{ + //TODO + throw OciException(__TROTL_HERE__, "Not implemented yet"); +} + // TODO tstring BindParANYDATA::get_string(unsigned int row) const { @@ -65,7 +108,6 @@ OCINumber num; OCINumber *num_ptr = # ub4 len; - OCIInd indp; // TODO check indp here text str_buf[61]; ub4 str_len = sizeof(str_buf) / sizeof(*str_buf); @@ -93,35 +135,56 @@ } case OCI_TYPECODE_VARCHAR2: { - OCIInd indp; // TODO check indp here + OCIInd _indp; // TODO check indp here OCIString *str = (OCIString *) 0; ub4 len, len2; sword res1 = OCICALL(OCIAnyDataAccess(_stmt._conn._svc_ctx, _stmt._errh, - _oan_buffer[row], (OCITypeCode)OCI_TYPECODE_VARCHAR2, - (OCIType *)0, (dvoid *)&indp, (dvoid *)&str, &len)); - oci_check_error(__TROTL_HERE__, _env._errh, res1); + _oan_buffer[row], (OCITypeCode)OCI_TYPECODE_VARCHAR2, + (OCIType *)0, (dvoid *)&_indp, (dvoid *)&str, &len)); + oci_check_error(__TROTL_HERE__, _stmt._errh, res1); return tstring( (const char *)OCIStringPtr(_stmt._env, str), OCIStringSize(_stmt._env, str)); } -// case OCI_TYPECODE_DATE: + case OCI_TYPECODE_DATE: + { // /*checkerr(ctxptr->errhp, OCIAnyDataAccess(ctxptr->svchp, // ctxptr->errhp, oan_buffer, // (OCITypeCode)OCI_TYPECODE_DATE, // (OCIType *)0, (dvoid *)&indp, (dvoid *)&date, &len)); // OCIDateGetDate( (CONST OCIDate *) &date, &year1, &month1, &day1 ); */ - -// checkerr(ctxptr->errhp, OCIAnyDataAccess(ctxptr->svchp, -// ctxptr->errhp, oan_buffer, -// (OCITypeCode)OCI_TYPECODE_DATE, -// (OCIType *)0, (dvoid *)&indp, -// (dvoid **)&date_ptr, &len)); + OCIInd _indp; // TODO check indp here + OCIDate *date_ptr = 0; + text str_buf[200]; + ub4 str_len = sizeof(str_buf) / sizeof( *str_buf); + ub4 len; + + sword res1= OCICALL(OCIAnyDataAccess(_stmt._conn._svc_ctx, _stmt._errh, + _oan_buffer[row], (OCITypeCode)OCI_TYPECODE_DATE, + (OCIType *)0, (dvoid *)&_indp, + (dvoid **)&date_ptr, &len)); + oci_check_error(__TROTL_HERE__, _stmt._errh, res1); // OCIDateGetDate( (CONST OCIDate *) date_ptr, &year1, &month1, &day1 ); - + + + const char fmt[] = "YYYY:MM:DD HH24:MI:SS"; + const char lang_fmt[] = "American"; + + res1 = OCICALL(OCIDateToText(_stmt._errh, + date_ptr, + (CONST text*) fmt, + (ub4) sizeof(fmt)-1, + (CONST text*) lang_fmt, + (ub4) sizeof(lang_fmt)-1, + (ub4 *)&str_len, + str_buf + )); + oci_check_error(__TROTL_HERE__, _stmt._errh, res1); + str_buf[ min( (str_len+1) , (unsigned)sizeof(str_buf) ) ] = '\0'; + + return (const char*)str_buf; // printf("c2 is %d/%d/%d\n", day1, month1, year1); - -// break; - + } // case OCI_TYPECODE_OBJECT: // checkerr(ctxptr->errhp, OCIAnyDataAccess(ctxptr->svchp, ctxptr->errhp, // oan_buffer, (OCITypeCode) OCI_TYPECODE_OBJECT, @@ -211,52 +274,7 @@ return _stringrepres.str(); }; - -void BindParANYDATA::init(SqlStatement &stmt) -{ - sword res; - _anydatatdo = 0; - - - _oan_buffer = new OCIAnyData* [ _cnt ]; - - res = OCICALL(OCITypeByName(_stmt._env, _stmt._errh, _stmt._conn._svc_ctx, - (const oratext*)"SYS", strlen("SYS"), - (const oratext*)"ANYDATA", strlen("ANYDATA"), - 0, 0, - OCI_DURATION_SESSION, OCI_TYPEGET_ALL, - (OCIType**) &_anydatatdo - )); - oci_check_error(__TROTL_HERE__, _stmt._errh, res); - - if(_anydatatdo == NULL) - throw OciException(__TROTL_HERE__, "Unknown datatype in the database: SYS.ANYDATA"); - - for(int i=0; i<g_OCIPL_BULK_ROWS; i++) - { - _oan_buffer[i] = NULL; - } -} - -void BindParANYDATA::define_hook(SqlStatement &stmt) -{ - sword res = OCICALL(OCIDefineObject(defnpp, stmt._errh, - _anydatatdo, - (dvoid **) &(_oan_buffer[0]), //(dvoid **) &_oan_buffer, - (ub4 *) 0, - 0, //(dvoid **) &_any_indp, - (ub4 *) 0)); - oci_check_error(__TROTL_HERE__, stmt._errh, res); -// // TODO OCIDefineArrayOfStruct here ?? -} - -void BindParANYDATA::bind_hook(SqlStatement &stmt) -{ - //TODO - throw OciException(__TROTL_HERE__, "Not implemented yet"); -} - tstring SqlANYDATA::str() const { return _stringrepres.str(); Modified: branches/tora-trotl/src/trotl/src/trotl_anydata.h =================================================================== --- branches/tora-trotl/src/trotl/src/trotl_anydata.h 2010-09-19 18:30:55 UTC (rev 3691) +++ branches/tora-trotl/src/trotl/src/trotl_anydata.h 2010-09-24 12:20:23 UTC (rev 3692) @@ -54,40 +54,41 @@ friend struct ConvertorForWrite; // TODO remember OCIConn or at least svcctx in this class - BindParANYDATA(unsigned int pos, SqlStatement &stmt, ColumnType &ct) : SqlStatement::BindPar(pos, stmt, ct) - , _oan_buffer(NULL), _any_indp(NULL) + BindParANYDATA(unsigned int pos, SqlStatement &stmt, ColumnType &ct) + : SqlStatement::BindPar(pos, stmt, ct) + , _oan_buffer(NULL) + , _any_indp(NULL) { - valuep = NULL; value_sz = 0; delete[] indp; indp = NULL; delete[] rcodep; rcodep = NULL; dty = SQLT_NTY; - value_sz = 0; type_name = ct.get_type_str(); + value_sz = sizeof(OCIAnyData*); + for(unsigned i = 0; i < _cnt; ++i) + { + ((ub2*)rlenp)[i] = (ub2) value_sz; + } + init(stmt); } - BindParANYDATA(unsigned int pos, SqlStatement &stmt, BindVarDecl &decl): SqlStatement::BindPar(pos, stmt, decl) - , _oan_buffer(NULL), _any_indp(NULL) + BindParANYDATA(unsigned int pos, SqlStatement &stmt, BindVarDecl &decl) + : SqlStatement::BindPar(pos, stmt, decl) + , _oan_buffer(NULL) + , _any_indp(NULL) { - valuep = NULL; dty = SQLT_NTY; - value_sz = 0; type_name = "SYS.ANYDATA"; + value_sz = sizeof(OCIAnyData*); + for(unsigned i = 0; i < _cnt; ++i) + { + ((ub4*)rlenp)[i] = (ub4) value_sz; + } + init(stmt); - }; - + } + ~BindParANYDATA() { - if(valuep) - { - delete[] (unsigned char*) valuep; - valuep = NULL; - } - /* - if(_xmlvaluep) - { - delete[] _xmlvaluep; - _xmlvaluep = NULL; - } - */ + // TODO free _any_indp, _oan_buffer } virtual tstring get_string(unsigned int row) const; Modified: branches/tora-trotl/src/trotl/src/trotl_base.h =================================================================== --- branches/tora-trotl/src/trotl/src/trotl_base.h 2010-09-19 18:30:55 UTC (rev 3691) +++ branches/tora-trotl/src/trotl/src/trotl_base.h 2010-09-24 12:20:23 UTC (rev 3692) @@ -335,7 +335,7 @@ { typedef OciSimpleHandle<OCIEnv> super; - OciEnvAlloc(ub4 oci_mode=OCI_OBJECT) // OCI_OBJECT for OCINumber... functions + OciEnvAlloc(ub4 oci_mode=OCI_OBJECT|OCI_THREADED) // OCI_OBJECT for OCINumber... functions { sword res = OCICALL(OCIEnvCreate(&_handle, oci_mode, 0/*ctxp*/, 0, 0, 0, 0/*xtramem_sz*/, 0/*usrmempp*/)); //std::cerr << "OCIEnvCreate:" << res << std::endl; @@ -422,14 +422,40 @@ inline void oci_check_error(tstring where, OCIError* errh, sword res) { - if (res != OCI_SUCCESS) + switch(res) + { + case OCI_SUCCESS: + case OCI_SUCCESS_WITH_INFO: + break; + case OCI_ERROR: throw OciException(where, errh); + break; + case OCI_INVALID_HANDLE: + throw OciException(where, "Invalid handle"); + break; + default: + throw OciException(where, "Unsupported result code"); + break; + } } inline void oci_check_error(tstring where, OCIEnv* envh, sword res) { - if (res != OCI_SUCCESS) + switch(res) + { + case OCI_SUCCESS: + case OCI_SUCCESS_WITH_INFO: + break; + case OCI_ERROR: throw OciException(where, envh); + break; + case OCI_INVALID_HANDLE: + throw OciException(where, "Invalid handle"); + break; + default: + throw OciException(where, "Unsupported result code"); + break; + } } /* Modified: branches/tora-trotl/src/trotl/src/trotl_common.h =================================================================== --- branches/tora-trotl/src/trotl/src/trotl_common.h 2010-09-19 18:30:55 UTC (rev 3691) +++ branches/tora-trotl/src/trotl/src/trotl_common.h 2010-09-24 12:20:23 UTC (rev 3692) @@ -136,7 +136,6 @@ #define __TROTL_HERE1__(x) STR(x)"\t" + __PRETTY_FUNCTION__ // #define __HERE2__(x,y) ::trotl::tstring("("y":" STR(x)"(") + __PRETTY_FUNCTION__ +")" // #define __HERE3__(x,y) ::trotl::tstring("\n(") + __PRETTY_FUNCTION__ + ") " y ":" STR(x) + "\n" - #define STR(a) #a #else // #define __TROTL_HERE__ __HERE3__(__LINE__, __FILE__) // #define __HERE_SHORT__ __HERE3__(__LINE__, __FILE__) @@ -145,10 +144,11 @@ // #define __HERE3__(x,y) std::string("\n(") + __FUNCTION__ + ") " y ":" STR(x) + "\n" #define __TROTL_HERE__ std::string(__FILE__) + ":"__TROTL_HERE1__(__LINE__) #define __TROTL_HERE1__(x) STR(x)"\t" + __FUNCSIG__ - #define STR(a) #a #endif //__GNUC__ #else //DEBUG #define __TROTL_HERE__ "" #endif +#define STR(a) #a + #endif Modified: branches/tora-trotl/src/trotl/src/trotl_date.h =================================================================== --- branches/tora-trotl/src/trotl/src/trotl_date.h 2010-09-19 18:30:55 UTC (rev 3691) +++ branches/tora-trotl/src/trotl/src/trotl_date.h 2010-09-24 12:20:23 UTC (rev 3692) @@ -52,28 +52,32 @@ */ struct TROTL_EXPORT BindParDate: public SqlStatement::BindPar { - BindParDate(unsigned int pos, SqlStatement &stmt, BindVarDecl &decl): SqlStatement::BindPar(pos, stmt, decl) + BindParDate(unsigned int pos, SqlStatement &stmt, ColumnType &ct) : SqlStatement::BindPar(pos, stmt, ct) { - valuep = new unsigned char [ _cnt * sizeof(OCIDate) ]; -// memset(valuep, 0x00, _cnt * sizeof(OCIDate) ); + valuep = (void**) new unsigned char [ _cnt * sizeof(OCIDate) ]; + memset(valuep, 0x00, _cnt * sizeof(OCIDate) ); dty = SQLT_ODT; value_sz = sizeof(OCIDate); - type_name = "DATE"; - - memset(valuep, 0x00, _cnt * sizeof(OCIDate) ); + for(unsigned i = 0; i < _cnt; ++i) + { + ((ub2*)rlenp)[i] = (ub2) value_sz; + } + type_name = ct.get_type_str(); } - BindParDate(unsigned int pos, SqlStatement &stmt, ColumnType &ct) : SqlStatement::BindPar(pos, stmt, ct) + BindParDate(unsigned int pos, SqlStatement &stmt, BindVarDecl &decl): SqlStatement::BindPar(pos, stmt, decl) { - valuep = new unsigned char [ _cnt * sizeof(OCIDate) ]; -// memset(valuep, 0x00, _cnt * sizeof(OCIDate) ); + valuep = (void**) new unsigned char [ _cnt * sizeof(OCIDate) ]; + memset(valuep, 0x00, _cnt * sizeof(OCIDate) ); dty = SQLT_ODT; value_sz = sizeof(OCIDate); - type_name = ct.get_type_str(); - - memset(valuep, 0x00, _cnt * sizeof(OCIDate) ); + for(unsigned i = 0; i < _cnt; ++i) + { + ((ub4*)rlenp)[i] = (ub4) value_sz; + } + type_name = "DATE"; } ~BindParDate() @@ -85,25 +89,8 @@ } } -// template<class return_type> -// return_type get_number(unsigned int row) const -// { -// throw_ocipl_exception( -// OciException( -// __TROTL_HERE__, -// "Invalid datatype in conversion(BindParDate to %d%s)\n" -// ).arg(sizeof(return_type)).arg(typeid(return_type).name()) -// ); -// } - virtual tstring get_string(unsigned int row) const; -// virtual int get_int(unsigned int row) const { return get_number<int>(row); }; -// virtual unsigned int get_uint(unsigned int row) const { return get_number<unsigned int>(row); }; -// virtual long get_long(unsigned int row) const { return get_number<long>(row); }; -// virtual unsigned long get_ulong(unsigned int row) const { return get_number<unsigned long>(row); }; -// virtual float get_float(unsigned int row) const { return get_number<float>(row); }; -// virtual double get_double(unsigned int row) const { return get_number<double>(row); }; protected: BindParDate(const BindParDate &other); }; Modified: branches/tora-trotl/src/trotl/src/trotl_int.h =================================================================== --- branches/tora-trotl/src/trotl/src/trotl_int.h 2010-09-19 18:30:55 UTC (rev 3691) +++ branches/tora-trotl/src/trotl/src/trotl_int.h 2010-09-24 12:20:23 UTC (rev 3692) @@ -192,31 +192,30 @@ { BindParNumber(unsigned int pos, SqlStatement &stmt, ColumnType &ct) : SqlStatement::BindPar(pos, stmt, ct) { - // SQLT_NUM - unsigned char[22] - // I am not sure here, SQLT_VNU can one byte longer than SQLT_NUM - probably - valuep = new unsigned char [ _cnt * ( OCI_NUMBER_SIZE + 1) ]; + valuep = (void**) new unsigned char [ _cnt * (OCI_NUMBER_SIZE) ]; + memset(valuep, 0x00, _cnt * (OCI_NUMBER_SIZE) ); - // memset(valuep, 0x5a, cnt * OCI_NUMBER_SIZE ); - // ((unsigned char*)valuep)[0] = pos; - memset(valuep, 0x00, _cnt * (OCI_NUMBER_SIZE+1) ); - dty = SQLT_VNU; //dty = SQLT_NUM; - value_sz = OCI_NUMBER_SIZE + 1; + value_sz = OCI_NUMBER_SIZE; + for(unsigned i = 0; i < _cnt; ++i) + { + ((ub2*)rlenp)[i] = (ub2) value_sz; + } type_name = ct.get_type_str(); } BindParNumber(unsigned int pos, SqlStatement &stmt, BindVarDecl &decl): SqlStatement::BindPar(pos, stmt, decl) { - // SQLT_NUM - unsigned char[22] - // I am not sure here, SQLT_VNU can one byte longer than SQLT_NUM - probably - valuep = new unsigned char [ decl.bracket[1] * ( OCI_NUMBER_SIZE + 1) ]; + valuep = (void**) new unsigned char [ decl.bracket[1] * (OCI_NUMBER_SIZE) ]; + memset(valuep, 0x00, decl.bracket[1] * (OCI_NUMBER_SIZE) ); - // memset(valuep, 0x5a, cnt * OCI_NUMBER_SIZE ); - // ((unsigned char*)valuep)[0] = pos; - memset(valuep, 0x00, decl.bracket[1] * (OCI_NUMBER_SIZE+1) ); - dty = SQLT_VNU; //dty = SQLT_NUM; - value_sz = OCI_NUMBER_SIZE + 1; + value_sz = OCI_NUMBER_SIZE; + for(unsigned i = 0; i < _cnt; ++i) + { + ((ub4*)rlenp)[i] = (ub4) value_sz; + } + type_name = "NUMBER"; }; Modified: branches/tora-trotl/src/trotl/src/trotl_lob.cpp =================================================================== --- branches/tora-trotl/src/trotl/src/trotl_lob.cpp 2010-09-19 18:30:55 UTC (rev 3691) +++ branches/tora-trotl/src/trotl/src/trotl_lob.cpp 2010-09-24 12:20:23 UTC (rev 3692) @@ -58,22 +58,30 @@ BindParLob::BindParLob(unsigned int pos, SqlStatement &stmt, ColumnType &ct) : BindPar(pos, stmt, ct) { //valuep = new unsigned char [ _cnt * ( sizeof(OCILobLocator*) ) ]; - valuep = malloc( _cnt * sizeof(OCILobLocator*) ); + valuep = (void**) malloc( _cnt * sizeof(OCILobLocator*) ); + memset(valuep, 0, _cnt * sizeof(OCILobLocator*) ); - ////memset(valuep, 0x5a, _cnt * sizeof(OCILobLocator*) ); + value_sz = sizeof(OCILobLocator*); + for(unsigned i = 0; i < _cnt; ++i) + { + ((ub2*)rlenp)[i] = (ub2) value_sz; + } - value_sz = sizeof(OCILobLocator*); descAlloc(); } BindParLob::BindParLob(unsigned int pos, SqlStatement &stmt, BindVarDecl &decl): BindPar(pos, stmt, decl) { //valuep = new unsigned char [ decl.bracket[1] * ( OCI_NUMBER_SIZE + 1) ]; - valuep = malloc( _cnt * sizeof(OCILobLocator*) ); + valuep = (void**) malloc( _cnt * sizeof(OCILobLocator*) ); + memset(valuep, 0, _cnt * sizeof(OCILobLocator*) ); - ////memset(valuep, 0x5a, _cnt * sizeof(OCILobLocator*) ); + value_sz = sizeof(OCILobLocator*); + for(unsigned i = 0; i < _cnt; ++i) + { + ((ub4*)rlenp)[i] = (ub4) value_sz; + } - value_sz = sizeof(OCILobLocator*); descAlloc(); }; Modified: branches/tora-trotl/src/trotl/src/trotl_misc.h =================================================================== --- branches/tora-trotl/src/trotl/src/trotl_misc.h 2010-09-19 18:30:55 UTC (rev 3691) +++ branches/tora-trotl/src/trotl/src/trotl_misc.h 2010-09-24 12:20:23 UTC (rev 3692) @@ -54,29 +54,26 @@ */ struct TROTL_EXPORT BindParMisc: public SqlStatement::BindPar { -public: BindParMisc(unsigned int pos, SqlStatement &stmt, BindVarDecl &decl) : SqlStatement::BindPar(pos, stmt, decl) { // amount of bytes = (string length +1 ) * (array length) - valuep = new char [ (128) * (decl.bracket[1]) ]; + valuep = (void**) new char [ (128) * (decl.bracket[1]) ]; + memset(valuep, 0x00, 128 * (decl.bracket[1])); + dty = SQLT_STR; value_sz = 128; - alenp = new ub2 [decl.bracket[1]]; type_name = typeid(tstring).name(); - - memset(valuep, 0x00, 128 * (decl.bracket[1])); } BindParMisc(unsigned int pos, SqlStatement &stmt, ColumnType &ct) : SqlStatement::BindPar(pos, stmt, ct) { // amount of bytes = (string length +1 ) * (array length) - valuep = new char [ ( 128 ) * (_cnt) ]; // +1 for ending zero + valuep = (void**) new char [ ( 128 ) * (_cnt) ]; // +1 for ending zero + memset(valuep, 0x00, (128) * _cnt); + dty = SQLT_STR; value_sz = 128; - alenp = new ub2 [_cnt]; type_name = typeid(tstring).name(); - - memset(valuep, 0x00, (128) * _cnt); } @@ -87,16 +84,11 @@ delete[] (char*)valuep; valuep = NULL; } - if(alenp) - { - delete[] (ub2*)alenp; - alenp = NULL; - } } virtual tstring get_string(unsigned int row) const { - return is_null(row) ? "NULL" : tstring(((char*)valuep)+(row * value_sz)); + return is_null(row) ? "NULL" : tstring(((char*)valuep)+(row * value_sz)); } protected: Modified: branches/tora-trotl/src/trotl/src/trotl_rid.cpp =================================================================== --- branches/tora-trotl/src/trotl/src/trotl_rid.cpp 2010-09-19 18:30:55 UTC (rev 3691) +++ branches/tora-trotl/src/trotl/src/trotl_rid.cpp 2010-09-24 12:20:23 UTC (rev 3692) @@ -47,13 +47,12 @@ // // Register Bind datatypes in factory(Define - SELECT) -Util::RegisterInFactory<BindParRid, DefineParFactTwoParmSing, int> regDefineNumberRid(SQLT_RDD); +Util::RegisterInFactory<BindParRid, DefineParFactTwoParmSing, int> regDefineRid(SQLT_RDD); BindParRid::BindParRid(unsigned int pos, SqlStatement &stmt, BindVarDecl &decl): BindPar(pos, stmt, decl) { - //valuep = new unsigned char [ decl.bracket[1] * ( OCI_NUMBER_SIZE + 1) ]; - valuep = malloc( _cnt * sizeof(OCIRowid*) ); - ////memset(valuep, 0x5a, _cnt * sizeof(OCIRowid*) ); + valuep = (void**) malloc( _cnt * sizeof(OCIRowid*) ); + memset(valuep, 0, _cnt * sizeof(OCIRowid*) ); dty = SQLT_RDD; value_sz = sizeof(OCIRowid*); @@ -64,9 +63,8 @@ BindParRid::BindParRid(unsigned int pos, SqlStatement &stmt, ColumnType &ct) : BindPar(pos, stmt, ct) { - //valuep = new unsigned char [ _cnt * ( sizeof(OCIRowid*) ) ]; - valuep = malloc( _cnt * sizeof(OCIRowid*) ); - ////memset(valuep, 0x5a, _cnt * sizeof(OCIRowid*) ); + valuep = (void**) malloc( _cnt * sizeof(OCIRowid*) ); + memset(valuep, 0, _cnt * sizeof(OCIRowid*) ); dty = SQLT_RDD; value_sz = sizeof(OCIRowid*); Modified: branches/tora-trotl/src/trotl/src/trotl_stat.cpp =================================================================== --- branches/tora-trotl/src/trotl/src/trotl_stat.cpp 2010-09-19 18:30:55 UTC (rev 3691) +++ branches/tora-trotl/src/trotl/src/trotl_stat.cpp 2010-09-24 12:20:23 UTC (rev 3692) @@ -48,7 +48,7 @@ namespace trotl { -int TROTL_EXPORT g_OCIPL_BULK_ROWS = 3; +int TROTL_EXPORT g_OCIPL_BULK_ROWS = 1; int TROTL_EXPORT g_OCIPL_MAX_LONG = 30000; @@ -98,11 +98,11 @@ for(unsigned dpos = 1; dpos <= get_column_count(); ++dpos) { std::auto_ptr<BindPar> bp; - dvoid* parmdp; - sword res = OCICALL(OCIParamGet(_handle, get_type_id(), _errh, &parmdp, dpos)); + OCIParam* parmdp; + sword res = OCICALL(OCIParamGet(_handle, get_type_id(), _errh, (void**)&parmdp, dpos)); oci_check_error(__TROTL_HERE__, _errh, res); - _columns[dpos].describe(_errh, parmdp); + _columns[dpos].describe(*this, parmdp); res = OCICALL(OCIDescriptorFree(parmdp, OCI_DTYPE_PARAM)); oci_check_error(__TROTL_HERE__, _env, res); @@ -112,7 +112,7 @@ // << "This: " << this << std::endl // << "Columns:" << _columns[dpos].get_type_str(true) << std::endl; - // Use column datatype for lookup in hash table + // Use column datatype for lookup in a hash table // and call appropriate create function from the factory if( _columns[dpos]._data_type != SQLT_NTY) _all_defines[dpos] = DefineParFactTwoParmSing::Instance().create( @@ -128,8 +128,12 @@ _columns[dpos] ); if(_all_defines[dpos].get() == NULL) - throw OciException(__TROTL_HERE__, "DefinePar: Data type not registered: %s(%d)\n" - ).arg(_columns[dpos]._data_type_name).arg(_columns[dpos]._data_type); + throw OciException(__TROTL_HERE__, "DefinePar: Data type not registered: %s(%d:%d:%d:%s)\n") + .arg(_columns[dpos]._data_type_name) + .arg(_columns[dpos]._data_type) + .arg(_columns[dpos]._typecode) + .arg(_columns[dpos]._collection_typecode) + .arg(_columns[dpos]._data_type_name); define(*_all_defines[dpos]); } _state |= DEFINED; @@ -399,9 +403,10 @@ _conn._svc_ctx, _handle, // *stmtp _errh, // *errhp - iters,//_stmt_type == STMT_SELECT ? rows : 1, // iters + iters, //_stmt_type == STMT_SELECT ? rows : 1, // iters 0, // rowoff (CONST OCISnapshot*)0, (OCISnapshot*)0, mode)); + std::cout << "OCIStmtExecute" << std::endl; //std::cout << std::endl // << "iters:" << iters << std::endl; @@ -507,6 +512,7 @@ // << "This: " << this << std::endl // << "Bind:'"<< bp.bind_name << "' " << bp.bind_name.length() << std::endl; + sword res = OCICALL(OCIBindByName (_handle, &bp.bindp, _errh, @@ -523,7 +529,6 @@ //NULL for non-PL/SQL statements (ub4*)(((_stmt_type == STMT_DECLARE ||_stmt_type == STMT_BEGIN ) && bp._max_cnt > 1) ? &bp._cnt : NULL), OCI_DEFAULT)); - oci_check_error(__TROTL_HERE__, _errh, res); // std::cout << std::endl @@ -538,25 +543,25 @@ bp._bound = true; } -void SqlStatement::define(BindPar &dp) -{ - sword res = OCICALL(OCIDefineByPos(_handle/*stmtp*/, - &dp.defnpp, - _errh, - dp._pos, - dp.valuep, - dp.value_sz, - dp.dty, - dp.indp, - dp.rlenp, - dp.rcodep, -// (ub2*)0, (ub2*)0, - OCI_DEFAULT)); - oci_check_error(__TROTL_HERE__, _errh, res); + void SqlStatement::define(BindPar &dp) + { + sword res = OCICALL(OCIDefineByPos(_handle/*stmtp*/, + &dp.defnpp, // (OCIDefine **) + _errh, // (OCIError*) + dp._pos, // ub4 position + dp.valuep, // dvoid *valuep + dp.value_sz, // sb4 value_sz + dp.dty, // ub2 dty + dp.indp, // dvoid *indp + (ub2*) dp.rlenp, // ub2 *rlenp + NULL, // ub2 *rcodep + dp.mode)); + oci_check_error(__TROTL_HERE__, _errh, res); + std::cout << "OCIDefineByPos" << std::endl; + + dp.define_hook(*this); + } - dp.define_hook(*this); -} - SqlStatement::~SqlStatement() { if( get_stmt_type() == STMT_SELECT ) @@ -568,7 +573,7 @@ delete [] _in_binds; delete [] _out_binds; } - _state |= 255; + _state |= 0xff; }; template<> Modified: branches/tora-trotl/src/trotl/src/trotl_stat.h =================================================================== --- branches/tora-trotl/src/trotl/src/trotl_stat.h 2010-09-19 18:30:55 UTC (rev 3691) +++ branches/tora-trotl/src/trotl/src/trotl_stat.h 2010-09-24 12:20:23 UTC (rev 3692) @@ -87,93 +87,120 @@ **/ struct TROTL_EXPORT BindPar { - enum { - BIND_IN=1, BIND_INOUT=2, BIND_OUT=4, DEFINE_SELECT=8 - }; + enum { + BIND_IN=1, + BIND_INOUT=2, + BIND_OUT=4, + DEFINE_SELECT=8 + }; + + /* Placeholder for Bind operations */ + BindPar(unsigned int pos, SqlStatement &stmt, BindVarDecl &decl) + : valuep(NULL) + , indp(NULL) + , rlenp(NULL) + // , rcodep(NULL) + , alenp(NULL) + , mode(OCI_DEFAULT) + , bindp(NULL) + , defnpp(NULL) + , _env(stmt._env) + , _stmt(stmt) + , _pos(pos) + , _max_cnt(decl.bracket[1]) + , _cnt(decl.bracket[1]) + , _bound(false) + , type_name("") + , bind_name(decl.bindname) + , bind_typename(decl.bindtype) + { + indp = new OCIInd [_cnt]; + memset(indp, 0, sizeof(OCIInd)*_cnt); + + rlenp = malloc( sizeof(ub4) * _cnt); // OCIBindByPos uses ub4* for lenp + alenp = new ub2 [_cnt]; + + if(decl.inout == "in") + _bind_type = BIND_IN; + else if(decl.inout == "inout") + _bind_type = BIND_INOUT; + else if(decl.inout == "out") + _bind_type = BIND_OUT; + }; - BindPar(unsigned int pos, SqlStatement &stmt, BindVarDecl &decl): - valuep(NULL), indp(NULL), rlenp(NULL), rcodep(NULL), alenp(NULL), - bindp(NULL), defnpp(NULL), _env(stmt._env), _stmt(stmt),//_conn(conn), - _pos(pos), _max_cnt(decl.bracket[1]), _cnt(decl.bracket[1]), - _bound(false), type_name(""), bind_name(decl.bindname), bind_typename(decl.bindtype) - { - indp = new OCIInd [_cnt]; - memset(indp, 0, sizeof(OCIInd)*_cnt); -//// memset(indp, 0x5a, sizeof(OCIInd)*_cnt); + /* Placeholder for Define operations */ + BindPar(unsigned int pos, SqlStatement &stmt, ColumnType &ct) + : valuep(NULL) + , indp(NULL) + , rlenp(NULL) + // , rcodep(NULL) + , alenp(NULL) + , mode(OCI_DEFAULT) + , bindp(NULL) + , defnpp(NULL) + , _env(stmt._env) + , _stmt(stmt) + , _pos(pos) + , _max_cnt(g_OCIPL_BULK_ROWS) + , _cnt(g_OCIPL_BULK_ROWS) + , _bound(false) + , type_name("") + , bind_name("") + , bind_typename("") + { + indp = new OCIInd [_cnt]; + memset(indp, 0, sizeof(OCIInd)*_cnt); + + rlenp = malloc( sizeof(ub2) * _cnt); // OciDefineByPos uses ub2* for lenp + + _bind_type = DEFINE_SELECT; + }; - rlenp = new ub2 [_cnt]; - rcodep= new ub2 [_cnt]; - - if(decl.inout == "in") - _bind_type = BIND_IN; - else if(decl.inout == "inout") - _bind_type = BIND_INOUT; - else if(decl.inout == "out") - _bind_type = BIND_OUT; - - //std::cerr << "BindPar::BindPar" << std::endl; - }; + virtual ~BindPar() + { + if(indp) { delete[] indp; indp = NULL; } + if(rlenp) { free(rlenp); rlenp = NULL; } + // if(rcodep) { delete[] rcodep; rcodep = NULL; } + if(alenp) {delete[] alenp; alenp = NULL; } + }; - BindPar(unsigned int pos, SqlStatement &stmt, ColumnType &ct): - valuep(NULL), indp(NULL), rlenp(NULL), rcodep(NULL), alenp(NULL), - bindp(NULL), defnpp(NULL), _env(stmt._env), _stmt(stmt),//_conn(conn), - _pos(pos), _max_cnt(g_OCIPL_BULK_ROWS), _cnt(g_OCIPL_BULK_ROWS), - _bound(false), type_name(""), bind_name(""), bind_typename("") - { - indp = new OCIInd [_cnt]; - memset(indp, 0, sizeof(OCIInd)*_cnt); - //// memset(indp, 0x5a, sizeof(OCIInd)*_cnt); - - //alenp = new ub2 [_cnt]; - rcodep= new ub2 [_cnt]; - - _bind_type = DEFINE_SELECT; - - //std::cerr<< "BindPar::BindPar" << std::endl; - }; - - virtual ~BindPar() - { - if(indp) delete[] indp; - if(rlenp) delete[] rlenp; - if(rcodep) delete[] rcodep; - if(alenp) delete[] alenp; - indp = NULL; - rlenp = rcodep = alenp = NULL; - } - - // every datatype can be converted to a string - virtual tstring get_string(unsigned int row) const = 0; + // every datatype can be converted to a string + virtual tstring get_string(unsigned int row) const = 0; - // This callback is used by descendents to call - // OCIBindArrayOfStructures, OCIBindObject etc, ... - virtual void bind_hook(SqlStatement&) {}; - virtual void define_hook(SqlStatement&) {}; + /* These two callbacks are used by descendents to call + * OCIBindArrayOfStructures, OCIBindObject etc, ... + * is called *after* OCIDefineByPos + */ + virtual void bind_hook(SqlStatement&) {}; + virtual void define_hook(SqlStatement&) {}; - dvoid *valuep; - sb4 value_sz; - ub2 dty; - OCIInd *indp; - ub2 *rlenp, *rcodep; - ub2 *alenp; - OCIBind *bindp; - OCIDefine *defnpp; //TODO union with OCIBind *bindpp - OciEnv &_env; -// OciConnection &_conn; - SqlStatement &_stmt; - unsigned int _pos, /*_cnt,*/ _max_cnt, _bind_type; - size_t _cnt; - bool _bound; - tstring type_name, bind_name, bind_typename; + /* members used for OCI calls */ + dvoid **valuep; + sb4 value_sz; + ub2 dty; + OCIInd *indp; // OCIInd aka sb2 ignored for SQL_NTY and SQL_REF + void *rlenp; + //ub2 *rcodep; + ub2 *alenp; + ub4 mode; // define mode = OCI_DEFAULT, except for SQLT_LONG = OCI_DYNAMIC_FETCH TODO fix long + OCIBind *bindp; + OCIDefine *defnpp; //TODO union with OCIBind *bindpp + + OciEnv &_env; + SqlStatement &_stmt; + unsigned int _pos, /*_cnt,*/ _max_cnt, _bind_type; + size_t _cnt; + bool _bound; + tstring type_name, bind_name, bind_typename; - bool is_null(unsigned row) const {return indp[row]==OCI_IND_NULL;}; - bool is_not_null(unsigned row) const {return indp[row]!=OCI_IND_NULL;}; - + /* NOTE these two function do not work with complex types SQLT_NTY */ + bool is_null(unsigned row) const {return indp[row]==OCI_IND_NULL;}; + bool is_not_null(unsigned row) const {return indp[row]!=OCI_IND_NULL;}; protected: - BindPar(const BindPar &other); - friend class SqlStatement; + BindPar(const BindPar &other); + friend class SqlStatement; }; // class BindPar - + SqlStatement(OciConnection& conn, const tstring& stmt, ub4 lang=OCI_NTV_SYNTAX, int bulk_rows=g_OCIPL_BULK_ROWS); bool execute_internal(ub4 rows, ub4 mode); Modified: branches/tora-trotl/src/trotl/src/trotl_string.h =================================================================== --- branches/tora-trotl/src/trotl/src/trotl_string.h 2010-09-19 18:30:55 UTC (rev 3691) +++ branches/tora-trotl/src/trotl/src/trotl_string.h 2010-09-24 12:20:23 UTC (rev 3692) @@ -60,34 +60,28 @@ // returned. struct TROTL_EXPORT BindParVarchar: public SqlStatement::BindPar { -public: - BindParVarchar(unsigned int pos, SqlStatement &stmt, BindVarDecl &decl) : SqlStatement::BindPar(pos, stmt, decl) + BindParVarchar(unsigned int pos, SqlStatement &stmt, ColumnType &ct) : SqlStatement::BindPar(pos, stmt, ct) { - // amount of bytes = (string length +1 ) * (array length) - valuep = new char [ (decl.bracket[0]+1) * (decl.bracket[1]) ]; + /* amount of bytes = (string length +1 ) * (array length) */ + valuep = (void**) new char [ ( ct._width + 1 ) * (_cnt) ]; // +1 for ending zero + memset(valuep, 0x00, (ct._width + 1) * _cnt); + dty = SQLT_STR; - value_sz = decl.bracket[0]+1; - alenp = new ub2 [decl.bracket[1]]; + value_sz = ct._width + 1; type_name = typeid(tstring).name(); - - memset(valuep, 0x00, (decl.bracket[0]+1) * (decl.bracket[1])); - //memset(alenp, 0x00, (decl.bracket[0]+1) * decl.bracket[1]); } - BindParVarchar(unsigned int pos, SqlStatement &stmt, ColumnType &ct) : SqlStatement::BindPar(pos, stmt, ct) + BindParVarchar(unsigned int pos, SqlStatement &stmt, BindVarDecl &decl) : SqlStatement::BindPar(pos, stmt, decl) { // amount of bytes = (string length +1 ) * (array length) - valuep = new char [ ( ct._width + 1 ) * (_cnt) ]; // +1 for ending zero + valuep = (void**) new char [ (decl.bracket[0]+1) * (decl.bracket[1]) ]; + memset(valuep, 0x00, (decl.bracket[0]+1) * (decl.bracket[1])); + dty = SQLT_STR; - value_sz = ct._width + 1; - alenp = new ub2 [_cnt]; + value_sz = decl.bracket[0]+1; type_name = typeid(tstring).name(); - - memset(valuep, 0x00, (ct._width + 1) * _cnt); - //memset(alenp, 0x00, sizeof(ub2) * _cnt); } - ~BindParVarchar() { if(valuep) @@ -95,11 +89,6 @@ delete[] (char*)valuep; valuep = NULL; } - if(alenp) - { - delete[] (ub2*)alenp; - alenp = NULL; - } } // template<class return_type> @@ -132,31 +121,24 @@ **/ struct TROTL_EXPORT BindParChar: public SqlStatement::BindPar { -public: - BindParChar(unsigned int pos, SqlStatement &stmt, BindVarDecl &decl): SqlStatement::BindPar(pos, stmt, decl) + BindParChar(unsigned int pos, SqlStatement &stmt, ColumnType &ct) : SqlStatement::BindPar(pos, stmt, ct) { - valuep = new char [ (decl.bracket[0]) * (decl.bracket[1]) ]; + valuep = (void**) new char [ ( ct._width + 1 ) * _cnt ]; + memset(valuep, 0x00, ( ct._width + 1 ) * _cnt); + dty = SQLT_CHR; - value_sz = decl.bracket[0]; - alenp = new ub2 [decl.bracket[1]]; + value_sz = ct._width; type_name = typeid(tstring).name(); - - memset(valuep, 0x00, (decl.bracket[0]) * (decl.bracket[1])); - memset(alenp, 0x00, sizeof(ub2) * decl.bracket[1]); - //memset(valuep, 0x5a, (decl.bracket[0]) * (decl.bracket[1])); } - BindParChar(unsigned int pos, SqlStatement &stmt, ColumnType &ct) : SqlStatement::BindPar(pos, stmt, ct) + BindParChar(unsigned int pos, SqlStatement &stmt, BindVarDecl &decl): SqlStatement::BindPar(pos, stmt, decl) { - // amount of bytes = (string length +1 ) * (array length) - valuep = new char [ ( ct._width + 1 ) * _cnt ]; + valuep = (void**) new char [ (decl.bracket[0]) * (decl.bracket[1]) ]; + memset(valuep, 0x00, (decl.bracket[0]) * (decl.bracket[1])); + dty = SQLT_CHR; - value_sz = ct._width; - alenp = new ub2 [_cnt]; + value_sz = decl.bracket[0]; type_name = typeid(tstring).name(); - - memset(valuep, 0x00, ( ct._width + 1 ) * _cnt); - memset(alenp, 0x00, sizeof(ub2) * _cnt); } ~BindParChar() @@ -166,21 +148,8 @@ delete[] (char*)valuep; valuep = NULL; } - if(alenp) - { - delete[] (ub2*)alenp; - alenp = NULL; - } } - template<class return_type> - return_type get_number(unsigned int row) const - { - throw OciException(__TROTL_HERE__, "Invalid datatype in conversion(BindParChar to %d%s)\n" - ).arg(sizeof(return_type)).arg(typeid(return_type).name()); -// return (return_type)0; - } - virtual tstring get_string(unsigned int row) const { // std::cout << " S:" << value_sz << ":" << dty << " "; @@ -190,12 +159,6 @@ return ""; } -// virtual int get_int(unsigned int row) const { return get_number<int>(row); }; -// virtual unsigned int get_uint(unsigned int row) const { return get_number<unsigned int>(row); }; -// virtual long get_long(unsigned int row) const { return get_number<long>(row); }; -// virtual unsigned long get_ulong(unsigned int row) const { return get_number<unsigned long>(row); }; -// virtual float get_float(unsigned int row) const { return get_number<float>(row); }; -// virtual double get_double(unsigned int row) const { return get_number<double>(row); }; protected: BindParChar(const BindParChar &other); }; @@ -204,26 +167,25 @@ **/ struct TROTL_EXPORT BindParRaw: public SqlStatement::BindPar { -public: - BindParRaw(unsigned int pos, SqlStatement &stmt, BindVarDecl &decl): SqlStatement::BindPar(pos, stmt, decl) - { - valuep = new char [ (decl.bracket[0]) * (decl.bracket[1]) ]; - dty = SQLT_BIN; - value_sz = decl.bracket[0]; - alenp = new ub2 [decl.bracket[1]]; - type_name = "RAW"; - } - BindParRaw(unsigned int pos, SqlStatement &stmt, ColumnType &ct) : SqlStatement::BindPar(pos, stmt, ct) { // amount of bytes = (string length +1 ) * (array length) - valuep = new char [ ( ct._width + 1 ) * _cnt ]; + valuep = (void**) new char [ ( ct._width + 1 ) * _cnt ]; + memset(valuep, 0x00, (ct._width + 1) * _cnt); + dty = SQLT_BIN; value_sz = ct._width; - alenp = new ub2 [_cnt]; type_name = ct.get_type_str(); + } - //// memset(valuep, 0x5a, value_sz * _cnt); + BindParRaw(unsigned int pos, SqlStatement &stmt, BindVarDecl &decl): SqlStatement::BindPar(pos, stmt, decl) + { + valuep = (void**) new char [ (decl.bracket[0]) * (decl.bracket[1]) ]; + memset(valuep, 0x00, (decl.bracket[0]) * (decl.bracket[1])); + + dty = SQLT_BIN; + value_sz = decl.bracket[0]; + type_name = "RAW"; } ~BindParRaw() @@ -233,21 +195,8 @@ delete[] (char*)valuep; valuep = NULL; } - if(alenp) - { - delete[] (ub2*)alenp; - alenp = NULL; - } } - - template<class return_type> - return_type get_number(unsigned int row) const - { - throw OciException(__TROTL_HERE__, "Invalid datatype in conversion(BindParRaw to %d%s)\n" - ).arg(sizeof(return_type)).arg(typeid(return_type).name()); - return (return_type)0; - } - + virtual tstring get_string(unsigned int row) const { if(!indp[row]) Modified: branches/tora-trotl/src/trotl/src/trotl_var.cpp =================================================================== --- branches/tora-trotl/src/trotl/src/trotl_var.cpp 2010-09-19 18:30:55 UTC (rev 3691) +++ branches/tora-trotl/src/trotl/src/trotl_var.cpp 2010-09-24 12:20:23 UTC (rev 3692) @@ -40,15 +40,25 @@ #endif #include "trotl_var.h" +#include "trotl_stat.h" namespace trotl { -ColumnType::ColumnType(OCIError* errh, dvoid* handle) +ColumnType::ColumnType(SqlStatement &stat, dvoid* handle): _data_type(0) + , _width(0) + , _char_semantics(0) + , _scale(-127) + , _precision(0) + , _nullable(false) + , _utf16(false) + , _collection_dschp(NULL) + , _tdo(NULL) + , _oref(NULL) { - describe(errh, handle); + describe(stat, handle); } -void ColumnType::describe(OCIError* errh, dvoid* handle) +void ColumnType::describe(SqlStatement &stat, dvoid* handle) { // get column name text* pcol_name = NULL; @@ -58,26 +68,40 @@ ub1 cform; sword res; + OCIDescribe *dschp = (OCIDescribe *) 0; + OCIParam *parmp; + ub1 fsprecision, lfprecision; + size = sizeof(pcol_name); - res = OCICALL(OCIAttrGet(handle, OCI_DTYPE_PARAM, &pcol_name, &size, OCI_ATTR_NAME, errh)); - oci_check_error(__TROTL_HERE__, errh, res); + res = OCICALL(OCIAttrGet(handle, OCI_DTYPE_PARAM, &pcol_name, &size, OCI_ATTR_NAME, stat._errh)); + oci_check_error(__TROTL_HERE__, stat._errh, res); _column_name.assign((const char*)pcol_name, size); + // TODO use this attribute + size = sizeof(fsprecision); + res = OCICALL(OCIAttrGet(handle, OCI_DTYPE_PARAM, (dvoid*)&fsprecision, &size, OCI_ATTR_FSPRECISION, stat._errh)); + oci_check_error(__TROTL_HERE__, stat._errh, res); + + // TODO use this attribute + size = sizeof(lfprecision); + res = OCICALL(OCIAttrGet(handle, OCI_DTYPE_PARAM, (dvoid*)&lfprecision, &size, OCI_ATTR_LFPRECISION, stat._errh)); + oci_check_error(__TROTL_HERE__, stat._errh, res); + // get column data type size = sizeof(_data_type); - res = OCICALL(OCIAttrGet(handle, OCI_DTYPE_PARAM, &_data_type, &size, OCI_ATTR_DATA_TYPE, errh)); - oci_check_error(__TROTL_HERE__, errh, res); + res = OCICALL(OCIAttrGet(handle, OCI_DTYPE_PARAM, &_data_type, &size, OCI_ATTR_DATA_TYPE, stat._errh)); + oci_check_error(__TROTL_HERE__, stat._errh, res); // get NULL-ability flag size = sizeof(_nullable); - res = OCICALL(OCIAttrGet(handle, OCI_DTYPE_PARAM, &_nullable, &size, OCI_ATTR_IS_NULL, errh)); - oci_check_error(__TROTL_HERE__, errh, res); + res = OCICALL(OCIAttrGet(handle, OCI_DTYPE_PARAM, &_nullable, &size, OCI_ATTR_IS_NULL, stat._errh)); + oci_check_error(__TROTL_HERE__, stat._errh, res); #if ORACLE_MAJOR_VERSION>=9 // Oracle 9 -> // retrieve the length semantics for the column size = sizeof(_char_semantics); - res = OCICALL(OCIAttrGet(handle, OCI_DTYPE_PARAM, &_char_semantics, &size, OCI_ATTR_CHAR_USED, errh)); + res = OCICALL(OCIAttrGet(handle, OCI_DTYPE_PARAM, &_char_semantics, &size, OCI_ATTR_CHAR_USED, stat._errh)); if (res != OCI_SUCCESS) _char_semantics = 0; // <- Oracle 9 @@ -86,32 +110,33 @@ if (_char_semantics) { // get the column width in characters - res = OCICALL(OCIAttrGet(handle, OCI_DTYPE_PARAM, &_width, &size, OCI_ATTR_CHAR_SIZE, errh)); - oci_check_error(__TROTL_HERE__, errh, res); + res = OCICALL(OCIAttrGet(handle, OCI_DTYPE_PARAM, &_width, &size, OCI_ATTR_CHAR_SIZE, stat._errh)); + oci_check_error(__TROTL_HERE__, stat._errh, res); } else #endif { // get the column width in bytes - res = OCICALL(OCIAttrGet(handle, OCI_DTYPE_PARAM, &_width, &size, OCI_ATTR_DATA_SIZE, errh)); - oci_check_error(__TROTL_HERE__, errh, res); + res = OCICALL(OCIAttrGet(handle, OCI_DTYPE_PARAM, &_width, &size, OCI_ATTR_DATA_SIZE, stat._errh)); + oci_check_error(__TROTL_HERE__, stat._errh, res); } - switch(_data_type) { + switch(_data_type) + { default: //case OCI_TYPECODE_VARCHAR: _precision = 0; _scale = -127; break; - case SQLT_NUM: { + case SQLT_NUM: size = sizeof(_precision); - res = OCICALL(OCIAttrGet(handle, OCI_DTYPE_PARAM, &_precision, &size, OCI_ATTR_PRECISION, errh)); - oci_check_error(__TROTL_HERE__, errh, res); + res = OCICALL(OCIAttrGet(handle, OCI_DTYPE_PARAM, &_precision, &size, OCI_ATTR_PRECISION, stat._errh)); + oci_check_error(__TROTL_HERE__, stat._errh, res); size = sizeof(_scale); - res = OCICALL(OCIAttrGet(handle, OCI_DTYPE_PARAM, &_scale, &size, OCI_ATTR_SCALE, errh)); - oci_check_error(__TROTL_HERE__, errh, res); - break;} + res = OCICALL(OCIAttrGet(handle, OCI_DTYPE_PARAM, &_scale, &size, OCI_ATTR_SCALE, stat._errh)); + oci_check_error(__TROTL_HERE__, stat._errh, res); + break; case SQLT_DAT: #if ORACLE_MAJOR_VERSION>=8 && ORACLE_MINOR_VERSION>=1 case SQLT_TIME: @@ -122,22 +147,139 @@ #endif _precision = 0; _scale = -127; + break; case SQLT_NTY: + { + OCIType *tdo = 0; + OCIRef *oref = 0; ub4 ssize, nsize; + size = sizeof(oref); + res = OCICALL(OCIAttrGet(handle, OCI_DTYPE_PARAM, (dvoid*)&oref, &size, OCI_ATTR_REF_TDO, stat._errh)); + oci_check_error(__TROTL_HERE__, stat._errh, res); + _oref = oref; + + res = OCICALL(OCITypeByRef(stat._env, stat._errh, oref, OCI_DURATION_SESSION, OCI_TYPEGET_HEADER, &tdo)); + oci_check_error(__TROTL_HERE__, stat._errh, res); + _tdo = tdo; + + // size = sizeof(tdo2); + // res = OCICALL(OCIAttrGet(handle, OCI_DTYPE_PARAM, (dvoid*)&tdo2, &size, OCI_ATTR_TDO, stat._errh)); + // oci_check_error(__TROTL_HERE__, stat._errh, res); + + // size = sizeof(_typecode); + // res = OCICALL(OCIAttrGet(parmp, OCI_DTYPE_PARAM, (dvoid*)&_typecode, &size, OCI_ATTR_TYPECODE, stat._errh)); + // //oci_check_error(__TROTL_HERE__, stat._errh, res); + // checkerr(stat._errh, res); + + // size = sizeof(boolean); + // res = OCICALL(OCIAttrGet(handle, OCI_DTYPE_PARAM, &boolean, &size, OCI_ATTR_IS_INCOMPLETE_TYPE, stat._errh)); + // oci_check_error(__TROTL_HERE__, stat._errh, res); + + // size = sizeof(boolean); + // res = OCICALL(OCIAttrGet(handle, OCI_DTYPE_PARAM, &boolean, &size, OCI_ATTR_IS_SYSTEM_TYPE, stat._errh)); + // oci_check_error(__TROTL_HERE__, stat._errh, res); + + // size = sizeof(boolean); + // res = OCICALL(OCIAttrGet(handle, OCI_DTYPE_PARAM, &boolean, &size, OCI_ATTR_IS_PREDEFINED_TYPE, stat._errh)); + // oci_check_error(__TROTL_HERE__, stat._errh, res); + + // size = sizeof(boolean); + // res = OCICALL(OCIAttrGet(handle, OCI_DTYPE_PARAM, &boolean, &size, OCI_ATTR_IS_TRANSIENT_TYPE, stat._errh)); + // oci_check_error(__TROTL_HERE__, stat._errh, res); + + // size = sizeof(boolean); + // res = OCICALL(OCIAttrGet(handle, OCI_DTYPE_PARAM, &boolean, &size, OCI_ATTR_IS_SYSTEM_GENERATED_TYPE, stat._errh)); + // oci_check_error(__TROTL_HERE__, stat._errh, res); + + // size = sizeof(boolean); + // res = OCICALL(OCIAttrGet(handle, OCI_DTYPE_PARAM, &boolean, &size, OCI_ATTR_HAS_NESTED_TABLE, stat._errh)); + //oci_check_error(__TROTL_HERE__, stat._errh, res); + + // size = sizeof(obj_id); + // res = OCICALL(OCIAttrGet(handle, OCI_DTYPE_PARAM, (dvoid*)&obj_name, &size, OCI_ATTR_OBJ_ID, stat._errh)); + // oci_check_error(__TROTL_HERE__, stat._errh, res); + + // size = sizeof(obj_name); + // res = OCICALL(OCIAttrGet(handle, OCI_DTYPE_PARAM, (dvoid*)&obj_name, &size, OCI_ATTR_OBJ_NAME, stat._errh)); + // oci_check_error(__TROTL_HERE__, stat._errh, res); + + // size = sizeof(obj_schema); + // res = OCICALL(OCIAttrGet(handle, OCI_DTYPE_PARAM, (dvoid*)&obj_name, &size, OCI_ATTR_OBJ_SCHEMA, stat._errh)); + // oci_check_error(__TROTL_HERE__, stat._errh, res); + ssize = sizeof(pschema_name); - res = OCICALL(OCIAttrGet(handle, OCI_DTYPE_PARAM, &pschema_name, &ssize, OCI_ATTR_SCHEMA_NAME, errh)); - oci_check_error(__TROTL_HERE__, errh, res); - + res = OCICALL(OCIAttrGet(handle, OCI_DTYPE_PARAM, &pschema_name, &ssize, OCI_ATTR_SCHEMA_NAME, stat._errh)); + oci_check_error(__TROTL_HERE__, stat._errh, res); nsize = sizeof(ptype_name); - res = OCICALL(OCIAttrGet(handle, OCI_DTYPE_PARAM, &ptype_name, &nsize, OCI_ATTR_TYPE_NAME, errh)); - oci_check_error(__TROTL_HERE__, errh, res); + res = OCICALL(OCIAttrGet(handle, OCI_DTYPE_PARAM, &ptype_name, &nsize, OCI_ATTR_TYPE_NAME, stat._errh)); + oci_check_error(__TROTL_HERE__, stat._errh, res); + _data_type_name = tstring((char*)pschema_name, ssize) + "." + tstring((char*)ptype_name,nsize); + + res = OCICALL(OCIHandleAlloc((dvoid *) stat._env, (dvoid **) &dschp, (ub4) OCI_HTYPE_DESCRIBE, (size_t) 0, (dvoid **) 0)); + oci_check_error(__TROTL_HERE__, stat._errh, res); + + res = OCICALL(OCIDescribeAny(stat._conn._svc_ctx, stat._errh, + (dvoid *) oref, 0, OCI_OTYPE_REF, (ub1)OCI_DEFAULT, (ub1) OCI_PTYPE_TYPE, dschp)); + oci_check_error(__TROTL_HERE__, stat._errh, res); + + res = OCICALL(OCIAttrGet((dvoid *) dschp, (ub4) OCI_HTYPE_DESCRIBE, (dvoid *)&parmp, (ub4 *)0, (ub4)OCI_ATTR_PARAM, stat._errh)); + oci_check_error(__TROTL_HERE__, stat._errh, res); + + size = sizeof(_typecode); + res = OCICALL(OCIAttrGet(parmp, OCI_DTYPE_PARAM, (dvoid*)&_typecode, &size, OCI_ATTR_TYPECODE, stat._errh)); + oci_check_error(__TROTL_HERE__, stat._errh, res); - _data_type_name = tstring((char*)pschema_name, ssize) + "." + tstring((char*)ptype_name); -// _data_type_name.assign((const char*)ptype_name, size); -// _data_type_schema.assign((const char*)pschema_name, size); + if (_typecode == OCI_TYPECODE_NAMEDCOLLECTION) + { + ub4 ssize; + ub2 len; + text* col_type_name = NULL; + text* col_schema_name = NULL; + res = OCICALL(OCIAttrGet((dvoid *) parmp, (ub4) OCI_DTYPE_PARAM, + (dvoid *)&_collection_typecode, (ub4 *)0, (ub4)OCI_ATTR_COLLECTION_TYPECODE, stat._errh)); + oci_check_error(__TROTL_HERE__, stat._errh, res); + + res = OCICALL(OCIAttrGet((dvoid *) parmp, (ub4) OCI_DTYPE_PARAM, + (dvoid *)&_collection_dschp, (ub4 *)0, (ub4)OCI_ATTR_COLLECTION_ELEMENT, stat._errh)); + oci_check_error(__TROTL_HERE__, stat._errh, res); + + /* get the data size */ + res = OCICALL(OCIAttrGet((dvoid*) _collection_dschp, (ub4) OCI_DTYPE_PARAM, (dvoid*) &len, (ub4 *) 0, (ub4) OCI_ATTR_DATA_SIZE, stat._errh)); + oci_check_error(__TROTL_HERE__, stat._errh, res); + + /* get the name of the collection */ + res = OCICALL(OCIAttrGet((dvoid*) _collection_dschp, (ub4) OCI_DTYPE_PARAM, (dvoid*) &col_type_name, (ub4 *) &ssize, (ub4) OCI_ATTR_TYPE_NAME, stat._errh)); + oci_check_error(__TROTL_HERE__, stat._errh, res); + + /* get the name of the schema */ + res = OCICALL(OCIAttrGet((dvoid*) _collection_dschp, (ub4) OCI_DTYPE_PARAM, (dvoid*) &col_schema_name, (ub4 *) &ssize, (ub4) OCI_ATTR_SCHEMA_NAME, stat._errh)); + oci_check_error(__TROTL_HERE__, stat._errh, res); + + /* get the data type */ + res = OCICALL(OCIAttrGet((dvoid*) _collection_dschp, (ub4) OCI_DTYPE_PARAM, (dvoid*) &_collection_typecode, (ub4 *) 0, (ub4) OCI_ATTR_DATA_TYPE, stat._errh)); + oci_check_error(__TROTL_HERE__, stat._errh, res); + + ub4 num_elems = 0; + if (_collection_typecode == OCI_TYPECODE_VARRAY) + { + /* get the number of elements */ + res = OCICALL(OCIAttrGet((dvoid*) _collection_dschp, (ub4) OCI_DTYPE_PARAM, (dvoid*) &num_elems, (ub4 *) 0, (ub4) OCI_ATTR_NUM_ELEMS, stat._errh)); + oci_check_error(__TROTL_HERE__, stat._errh, res); + } + std::cout << "OCI_ATTR_COLLECTION_TYPECODE: " << _collection_typecode << std::endl + << "OCI_ATTR_COLLECTION_ELEMENT: " << _collection_dschp << std::endl + << "OCI_ATTR_DATA_SIZE: " << len << std::endl + << "OCI_ATTR_TYPE_NAME: " << col_type_name << std::endl + << "OCI_ATTR_SCHEMA_NAME: " << col_schema_name << std::endl + << "OCI_ATTR_DATA_TYPE: " << _collection_typecode << std::endl + << "OCI_ATTR_NUM_ELEMS: " << num_elems << std::endl + << "========================================" << std::endl; + _data_type = (OCI_TYPECODE_VARRAY << 8) + _collection_typecode; + } break; + } case SQLT_LNG: _width = g_OCIPL_MAX_LONG; //TODO long can have up to 2GB break; @@ -145,8 +287,8 @@ case SQLT_STR: case SQLT_VCS: case SQLT_CLOB: - res = OCICALL(OCIAttrGet(handle, OCI_DTYPE_PARAM, &cform, 0, OCI_ATTR_CHARSET_FORM, errh)); - oci_check_error(__TROTL_HERE__, errh, res); + res = OCICALL(OCIAttrGet(handle, OCI_DTYPE_PARAM, &cform, 0, OCI_ATTR_CHARSET_FORM, stat._errh)); + oci_check_error(__TROTL_HERE__, stat._errh, res); _utf16 = (cform == SQLCS_NCHAR); break; } @@ -181,6 +323,7 @@ str << "NUMBER(" << (int)_precision << "," << (int)_scale << ")"; else str << "NUMBER(" << (int)_precision << ")"; + break; case SQLT_DAT: // OCI_TYPECODE_DATE: str << "DATE"; @@ -397,3 +540,5 @@ // ret.insert(ret.end(), desc); // } + + Modified: branches/tora-trotl/src/trotl/src/trotl_var.h =================================================================== --- branches/tora-trotl/src/trotl/src/trotl_var.h 2010-09-19 18:30:55 UTC (rev 3691) +++ branches/tora-trotl/src/trotl/src/trotl_var.h 2010-09-24 12:20:23 UTC (rev 3692) @@ -61,6 +61,8 @@ { tstring _column_name; tstring _data_type_name; + tstring _data_type_dblink; // ?? TODO + ub2 _data_type; ub2 _width; ub1 _char_semantics; // for Oracle 9 @@ -69,21 +71,28 @@ ub1 _nullable; bool _utf16; - ColumnType(): - _data_type(0), - _width(0), - _char_semantics(0), - _scale(-127), - _precision(0), - _nullable(false), - _utf16(false) - {}; + // for complex types + OCITypeCode _typecode, _collection_typecode; + dvoid *_collection_dschp; + OCIType *_tdo; + OCIRef *_oref; + + ColumnType(): _data_type(0) + , _width(0) + , _char_semantics(0) + , _scale(-127) + , _precision(0) + , _nullable(false) + , _utf16(false) + , _collection_dschp(NULL) + , _tdo(NULL) + , _oref(NULL) + {}; - ColumnType(OCIError* errh, dvoid* handle); - - tstring get_type_str(bool show_null=false) const; - - void describe(OCIError* errh, dvoid* handle); + ColumnType(SqlStatement &stat, dvoid* handle); + void describe(SqlStatement &stat, dvoid* handle); + + tstring get_type_str(bool show_null=false) const; }; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |