Diff for /sql/oracle/parser3oracle.C between versions 1.52 and 1.59

version 1.52, 2004/03/04 09:10:13 version 1.59, 2004/06/18 11:29:55
Line 83  static int pa_setenv(const char *name, c Line 83  static int pa_setenv(const char *name, c
                         strcat(buf, value);                          strcat(buf, value);
                         value=buf;                          value=buf;
                 }                  }
   
                 return setenv(name, value, 1/*overwrite*/);                   return setenv(name, value, 1/*overwrite*/); 
         } else {          } else {
                 unsetenv(name);                  unsetenv(name);
Line 139  struct OracleSQL_query_lobs { Line 138  struct OracleSQL_query_lobs {
                 } *row;                  } *row;
                 int count;                  int count;
         };          };
         struct cbf_context_struct {  
                 Connection *connection;  
                 return_rows *rows;  
         };  
         struct Item {          struct Item {
                 const char *name_ptr; size_t name_size;                  const char *name_ptr; size_t name_size;
                 char *data_ptr; size_t data_size;                  char *data_ptr; size_t data_size;
                 OCILobLocator *locator;                  OCILobLocator *locator;
                 OCIBind *bind;                  OCIBind *bind;
                 return_rows rows;                  return_rows rows;
                   Connection *connection;
         } items[MAX_IN_LOBS];          } items[MAX_IN_LOBS];
         int count;          int count;
 };  };
Line 173  static sb4 cbf_get_data(dvoid *ctxp, Line 169  static sb4 cbf_get_data(dvoid *ctxp,
                                                 ub1 *piecep,                                                   ub1 *piecep, 
                                                 dvoid **indpp,                                                   dvoid **indpp, 
                                                 ub2 **rcodepp);                                                  ub2 **rcodepp);
 static void tolower(char *out, const char *in, size_t size);  static void tolower_str(char *out, const char *in, size_t size);
 static void toupper(char *out, const char *in, size_t size);  static void toupper_str(char *out, const char *in, size_t size);
   
 static const char *options2env(char *s, Connection::Options* options) {  static const char *options2env(char *s, Connection::Options* options) {
         while(s) {          while(s) {
Line 183  static const char *options2env(char *s, Line 179  static const char *options2env(char *s,
                                 if(char *value=lsplit(key, '=')) {                                  if(char *value=lsplit(key, '=')) {
                                         if( strcmp( key, "ClientCharset" ) == 0 ) {                                          if( strcmp( key, "ClientCharset" ) == 0 ) {
                                                 if(options) {                                                  if(options) {
                                                         toupper(value, value, strlen(value));                                                          toupper_str(value, value, strlen(value));
                                                         options->cstrClientCharset = value;                                                          options->cstrClientCharset = value;
                                                 }                                                  }
                                                 continue;                                                  continue;
Line 249  public: Line 245  public:
         }          }
   
         /**     connect          /**     connect
                 @param used_only_in_connect_url                  @param url
                         format: @b user:pass@service?                          format: @b user:pass@service?
                            ORACLE_HOME=/u01/app/oracle/product/8.1.5&                             ORACLE_HOME=/u01/app/oracle/product/8.1.5&
                            ORA_NLS33=/u01/app/oracle/product/8.1.5/ocommon/nls/admin/data&                             ORA_NLS33=/u01/app/oracle/product/8.1.5/ocommon/nls/admin/data&
Line 257  public: Line 253  public:
                            ORA_ENCRYPT_LOGIN=TRUE                             ORA_ENCRYPT_LOGIN=TRUE
   
                 @todo environment manupulation doesnt look thread safe                  @todo environment manupulation doesnt look thread safe
                   @todo allocate 'aused_only_in_connect_url' on gc heap, so it can be manipulated directly
         */          */
         void connect(          void connect(
                 char *used_only_in_connect_url,                   char *url, 
                 SQL_Driver_services& services,                   SQL_Driver_services& services, 
                 void **connection_ref ///< output: Connection *                  void **connection_ref ///< output: Connection *
                 ) {                  ) 
           {
                   // connections are cross-request, do not use services._alloc [linked with request]
                 Connection& connection=*(Connection  *)services.malloc(sizeof(Connection));                  Connection& connection=*(Connection  *)services.malloc(sizeof(Connection));
                 connection.services=&services;                  connection.services=&services;
                 connection.options.bLowerCaseColumnNames = true;                  connection.options.bLowerCaseColumnNames = true;
                 *connection_ref=&connection;                  *connection_ref=&connection;
   
                 char *user=used_only_in_connect_url;                  char *user=url;
                 char *service=lsplit(user, '@');                  char *service=lsplit(user, '@');
                 char *pwd=lsplit(user, ':');                  char *pwd=lsplit(user, ':');
                 char *options=lsplit(service, '?');                  char *options=lsplit(service, '?');
Line 345  public: Line 344  public:
         void disconnect(void *aconnection) {          void disconnect(void *aconnection) {
             Connection& connection=*static_cast<Connection *>(aconnection);              Connection& connection=*static_cast<Connection *>(aconnection);
   
                 // free fetch buffers                  // free fetch buffers. leave that to GC [no such services func. yet?]
                   /*
                 for(int i=0; i<MAX_COLS; i++) {                  for(int i=0; i<MAX_COLS; i++) {
                         if(void* fetch_buffer=connection.fetch_buffers[i])                          if(void* fetch_buffer=connection.fetch_buffers[i])
                                 ::free(fetch_buffer);                                  connection.services->free(fetch_buffer);
                         else                          else
                                 break;                                  break;
                 }                                         }
                   */
   
                 // Terminate a user session                  // Terminate a user session
                 OCISessionEnd(                  OCISessionEnd(
Line 372  public: Line 373  public:
                 OCIHandleFree(                  OCIHandleFree(
                         (dvoid *)connection.envhp, (ub4)OCI_HTYPE_ENV);                          (dvoid *)connection.envhp, (ub4)OCI_HTYPE_ENV);
   
                 // connections are cross-request, do not use services._alloc [linked with request]                  // free connection. leave that to GC [no such services func. yet?]
                 ::free(&connection);                  // connection.services->free(&connection);
         }          }
         void commit(void *aconnection) {          void commit(void *aconnection) {
             Connection& connection=*static_cast<Connection *>(aconnection);              Connection& connection=*static_cast<Connection *>(aconnection);
Line 420  public: Line 421  public:
                 SQL_Driver_query_event_handlers& handlers)                   SQL_Driver_query_event_handlers& handlers) 
         {          {
                 Connection& connection=*static_cast<Connection *>(aconnection);                  Connection& connection=*static_cast<Connection *>(aconnection);
                   const char* cstrClientCharset=connection.options.cstrClientCharset;
                 OracleSQL_query_lobs lobs={{0}, 0};                  OracleSQL_query_lobs lobs={{0}, 0};
                 OCIStmt *stmthp=0;                  OCIStmt *stmthp=0;
   
                 SQL_Driver_services& services=*connection.services;                  SQL_Driver_services& services=*connection.services;
   
                 // transcode from $request:charset to connect-string?client_charset                  // transcode from $request:charset to connect-string?client_charset
                 size_t transcoded_statement_size;                  if(cstrClientCharset) {
                 if(const char* cstrClientCharset=connection.options.cstrClientCharset)                          size_t transcoded_statement_size;
                         services.transcode(astatement, strlen(astatement),                          services.transcode(astatement, strlen(astatement),
                                 astatement, transcoded_statement_size,                                  astatement, transcoded_statement_size,
                                 services.request_charset(),                                  services.request_charset(),
                                 cstrClientCharset);                                  cstrClientCharset);
                   }
   
                 bool failed=false;                  bool failed=false;
                 if(setjmp(connection.mark)) {                  if(setjmp(connection.mark)) {
Line 448  public: Line 451  public:
                                 (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT));                                  (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT));
                         {                          {
                                 for(int i=0; i<lobs.count; i++) {                                  for(int i=0; i<lobs.count; i++) {
                                           OracleSQL_query_lobs::Item &item=lobs.items[i];
                                         check(connection, "alloc output var desc", OCIDescriptorAlloc(                                          check(connection, "alloc output var desc", OCIDescriptorAlloc(
                                                 (dvoid *)connection.envhp, (dvoid **)&lobs.items[i].locator, (ub4)OCI_DTYPE_LOB, 0, 0));                                                  (dvoid *)connection.envhp, (dvoid **)&item.locator, (ub4)OCI_DTYPE_LOB, 0, 0));
   
                                         check(connection, "bind output", OCIBindByPos(stmthp,                                           char placeholder_buf[MAX_STRING];
                                                 &lobs.items[i].bind, connection.errhp,                                           sb4 placeh_len=snprintf(placeholder_buf, sizeof(placeholder_buf), 
                                                 (ub4)1+i,                                                   ":%.*s", item.name_size, item.name_ptr);
                                                 (dvoid *)&lobs.items[i].locator,                                           check(connection, "bind lob", OCIBindByName(stmthp, 
                                                 (sword)sizeof (lobs.items[i].locator), SQLT_CLOB, (dvoid *)0,                                                   &item.bind, connection.errhp, 
                                                   (text*)placeholder_buf, placeh_len,
                                                   (dvoid *)&item.locator, 
                                                   (sword)sizeof (item.locator), SQLT_CLOB, (dvoid *)0, 
                                                 (ub2 *)0, (ub2 *)0, (ub4)0, (ub4 *)0, OCI_DATA_AT_EXEC));                                                  (ub2 *)0, (ub2 *)0, (ub4)0, (ub4 *)0, OCI_DATA_AT_EXEC));
   
                                         lobs.items[i].rows.count=0;                                          item.rows.count=0;
                                         OracleSQL_query_lobs::cbf_context_struct cbf_context={&connection, &lobs.items[i].rows};                                          item.connection=&connection;
                                         check(connection, "bind dynamic", OCIBindDynamic(                                          check(connection, "bind dynamic", OCIBindDynamic(
                                                 lobs.items[i].bind, connection.errhp,                                                   item.bind, connection.errhp, 
                                                 (dvoid *) &cbf_context, cbf_no_data,                                                   (dvoid *) &item, cbf_no_data, 
                                                 (dvoid *) &cbf_context, cbf_get_data));                                                  (dvoid *) &item, cbf_get_data));
                                 }                                  }
                         }                          }
   
Line 650  private: // private funcs Line 657  private: // private funcs
                 OCIStmt *stmthp, unsigned long offset, unsigned long limit,                   OCIStmt *stmthp, unsigned long offset, unsigned long limit, 
                 SQL_Driver_query_event_handlers& handlers)                   SQL_Driver_query_event_handlers& handlers) 
         {          {
                   const char* cstrClientCharset=connection.options.cstrClientCharset;
                 SQL_Driver_services& services=*connection.services;                  SQL_Driver_services& services=*connection.services;
   
                 ub4 prefetch_rows=100;                  ub4 prefetch_rows=100;
Line 705  private: // private funcs Line 713  private: // private funcs
                                         (dvoid**) &col_name, (ub4 *) &col_name_len, (ub4)OCI_ATTR_NAME,                                           (dvoid**) &col_name, (ub4 *) &col_name_len, (ub4)OCI_ATTR_NAME, 
                                         (OCIError *)connection.errhp));                                          (OCIError *)connection.errhp));
                                 // transcode to $request:charset from connect-string?client_charset                                  // transcode to $request:charset from connect-string?client_charset
                                 if(const char* cstrClientCharset=connection.options.cstrClientCharset) {                                  if(cstrClientCharset) {
                                         services.transcode(col_name, col_name_len,                                          services.transcode(col_name, col_name_len,
                                                 col_name, col_name_len,                                                  col_name, col_name_len,
                                                 cstrClientCharset,                                                  cstrClientCharset,
Line 717  private: // private funcs Line 725  private: // private funcs
                                         size_t length=(size_t)col_name_len;                                          size_t length=(size_t)col_name_len;
                                         char *ptr=(char *)services.malloc_atomic(length+1);                                          char *ptr=(char *)services.malloc_atomic(length+1);
                                         if( connection.options.bLowerCaseColumnNames )                                           if( connection.options.bLowerCaseColumnNames ) 
                                                 tolower(ptr, col_name, length);                                                  tolower_str(ptr, col_name, length);
                                         else                                          else
                                                 memcpy(ptr, col_name, length);                                                                                            memcpy(ptr, col_name, length);                                          
                                         ptr[length]=0;                                          ptr[length]=0;
Line 744  private: // private funcs Line 752  private: // private funcs
                                         char*& buf=connection.fetch_buffers[column_count-1];                                          char*& buf=connection.fetch_buffers[column_count-1];
                                         ptr=buf; // get cached buffer                                          ptr=buf; // get cached buffer
                                         if(!ptr) // allocate if needed, caching it                                          if(!ptr) // allocate if needed, caching it
                                                 ptr=buf=(char *)::/*see disconnect*/malloc(MAX_OUT_STRING_LENGTH+1/*terminator*/);                                                  ptr=buf=(char *)services.malloc_atomic(MAX_OUT_STRING_LENGTH+1/*terminator*/);
                                         col.str=(char*)ptr;                                          col.str=(char*)ptr;
                                         size=MAX_OUT_STRING_LENGTH;                                          size=MAX_OUT_STRING_LENGTH;
                                         break;                                          break;
Line 824  private: // private funcs Line 832  private: // private funcs
                                                 if(str && length)                                                  if(str && length)
                                                 {                                                  {
                                                         // transcode to $request:charset from connect-string?client_charset                                                          // transcode to $request:charset from connect-string?client_charset
                                                         if(const char* cstrClientCharset=connection.options.cstrClientCharset) {                                                          if(cstrClientCharset)
                                                                 const char* dest;  
                                                                 size_t dest_length;  
                                                                 services.transcode(str, length,                                                                  services.transcode(str, length,
                                                                         dest, dest_length,                                                                          str, length,
                                                                         cstrClientCharset,                                                                          cstrClientCharset,
                                                                         services.request_charset());                                                                          services.request_charset());
                                                                 str=dest;  
                                                                 length=dest_length;  
                                                         }  
                                                 }                                                  }
   
                                                 check(connection, handlers.add_row_cell(connection.sql_error, str, length));                                                  check(connection, handlers.add_row_cell(connection.sql_error, str, length));
Line 894  private: // conn client library funcs Line 897  private: // conn client library funcs
                 ub2 dty, dvoid *indp, ub2 *alenp, ub2 *rcodep,                  ub2 dty, dvoid *indp, ub2 *alenp, ub2 *rcodep,
                 ub4 maxarr_len, ub4 *curelep, ub4 mode));                  ub4 maxarr_len, ub4 *curelep, ub4 mode));
   
           OCI_DECL(BindByName, (OCIStmt *stmtp, OCIBind **bindp, OCIError *errhp,
                   text* placeholder, sb4 placeh_len, dvoid *valuep, sb4 value_sz,
                   ub2 dty, dvoid *indp, ub2 *alenp, ub2 *rcodep,
                   ub4 maxarr_len, ub4 *curelep, ub4 mode));
   
         OCI_DECL(BindDynamic, (OCIBind *bindp, OCIError *errhp, dvoid *ictxp,          OCI_DECL(BindDynamic, (OCIBind *bindp, OCIError *errhp, dvoid *ictxp,
                 OCICallbackInBind icbfp, dvoid *octxp,                  OCICallbackInBind icbfp, dvoid *octxp,
                 OCICallbackOutBind ocbfp));                  OCICallbackOutBind ocbfp));
Line 985  private: // conn client library funcs li Line 993  private: // conn client library funcs li
                 OCI_LINK(Initialize);                  OCI_LINK(Initialize);
                 OCI_LINK(EnvInit);                  OCI_LINK(EnvInit);
                 OCI_LINK(AttrGet);              OCI_LINK(AttrSet);                  OCI_LINK(AttrGet);              OCI_LINK(AttrSet);
                 OCI_LINK(BindByPos);            OCI_LINK(BindDynamic);                  OCI_LINK(BindByPos);            OCI_LINK(BindByName);   OCI_LINK(BindDynamic);
                 OCI_LINK(DefineByPos);                  OCI_LINK(DefineByPos);
                 OCI_LINK(DescriptorAlloc);              OCI_LINK(DescriptorFree);                  OCI_LINK(DescriptorAlloc);              OCI_LINK(DescriptorFree);
                 OCI_LINK(ErrorGet);                  OCI_LINK(ErrorGet);
Line 1090  static sb4 cbf_get_data(dvoid *ctxp, Line 1098  static sb4 cbf_get_data(dvoid *ctxp,
                                  ub1 *piecep,                                    ub1 *piecep, 
                                  dvoid **indpp,                                    dvoid **indpp, 
                                  ub2 **rcodepp) {                                   ub2 **rcodepp) {
         OracleSQL_query_lobs::cbf_context_struct &context=          OracleSQL_query_lobs::Item& context=*static_cast<OracleSQL_query_lobs::Item*>(ctxp);
                 *(OracleSQL_query_lobs::cbf_context_struct *)ctxp;  
   
         if(index==0) {          if(index==0) {
                 static ub4  rows;                  static ub4  rows;
Line 1099  static sb4 cbf_get_data(dvoid *ctxp, Line 1106  static sb4 cbf_get_data(dvoid *ctxp,
                         OracleSQL_driver->OCIAttrGet(                          OracleSQL_driver->OCIAttrGet(
                                 (CONST dvoid *) bindp, OCI_HTYPE_BIND, (dvoid *)&rows,                                   (CONST dvoid *) bindp, OCI_HTYPE_BIND, (dvoid *)&rows, 
                                 (ub4 *)sizeof(ub2), OCI_ATTR_ROWS_RETURNED, context.connection->errhp)) ;                                  (ub4 *)sizeof(ub2), OCI_ATTR_ROWS_RETURNED, context.connection->errhp)) ;
                 context.rows->count=(ub2)rows;                  context.rows.count=(ub2)rows;
                 context.rows->row=(OracleSQL_query_lobs::return_rows::return_row *)                  context.rows.row=(OracleSQL_query_lobs::return_rows::return_row *)
                         context.connection->services->malloc_atomic(sizeof(OracleSQL_query_lobs::return_rows::return_row)*rows);                          context.connection->services->malloc_atomic(sizeof(OracleSQL_query_lobs::return_rows::return_row)*rows);
         }          }
   
         OracleSQL_query_lobs::return_rows::return_row &var=context.rows->row[index];          OracleSQL_query_lobs::return_rows::return_row &var=context.rows.row[index];
   
         check(*context.connection, "alloc output var desc dynamic", OracleSQL_driver->OCIDescriptorAlloc(          check(*context.connection, "alloc output var desc dynamic", OracleSQL_driver->OCIDescriptorAlloc(
                 (dvoid *) context.connection->envhp, (dvoid **)&var.locator,                   (dvoid *) context.connection->envhp, (dvoid **)&var.locator, 
Line 1120  static sb4 cbf_get_data(dvoid *ctxp, Line 1127  static sb4 cbf_get_data(dvoid *ctxp,
         return OCI_CONTINUE;          return OCI_CONTINUE;
 }  }
   
 static void tolower(char *out, const char *in, size_t size) {  static void tolower_str(char *out, const char *in, size_t size) {
         while(size--)          while(size--)
                 *out++=(char)tolower(*in++);                  *out++=(char)tolower(*in++);
 }  }
 static void toupper(char *out, const char *in, size_t size) {  static void toupper_str(char *out, const char *in, size_t size) {
         while(size--)          while(size--)
                 *out++=(char)toupper(*in++);                  *out++=(char)toupper(*in++);
 }  }

Removed from v.1.52  
changed lines
  Added in v.1.59


E-mail: