_ >   57 57      conflicting).
  58 58
  59 59 */
< >     60 /* Oracle 8 Call Interface */
    61 #include <oci.h>
60 62
  61 63 /* be sure to bump the version number if changes are made */
< >     64 #include "version.h"
62 65
  63 66 static char *ora_driver_version = "ArsDigita Oracle Driver version " ORA8_DRIVER_VERSION;
  64 67 static char *ora_driver_name = "Oracle8";
 
101 104 #include <sys/stat.h>
  102 105
  103 106
< >   104   /* Oracle 8 Call Interface */
  105   #include <oci.h>
106 107
  107 108
  108 109
 
337 338
  338 339 static int lob_buffer_size = 16384;
  339 340
< >     341 /* prefetch parameters, if zero leave defaults*/
    342 static ub4 prefetch_rows = 0;
    343 static ub4 prefetch_memory = 0;
    344
340 345 /* default values for the configuration parameters */
  341 346
  342 347 #define DEFAULT_DEBUG                   NS_FALSE
 
917 922     lob_buffer_size = 16384;
  918 923   Ns_Log (Notice, "%s driver LobBufferSize = %d", hdriver, lob_buffer_size);
  919 924
< >     925
    926   if (!Ns_ConfigGetInt (config_path, "PrefetchRows", &prefetch_rows))
    927       prefetch_rows = 0;
    928   Ns_Log (Notice, "%s driver PrefetchRows = %d", hdriver, prefetch_rows);
    929
    930   if (!Ns_ConfigGetInt (config_path, "PrefetchMemory", &prefetch_memory))
    931       prefetch_memory = 0;
    932   Ns_Log (Notice, "%s driver PrefetchMemory = %d", hdriver, prefetch_memory);
    933
    934
920 935   log (lexpos (), "entry (hdriver %p, config_path %s)", hdriver, nilp (config_path));
  921 936  
  922 937   oci_status = OCIInitialize (OCI_THREADED,
 
1573 1588
  1574 1589           if (fetchbuf->array_values != NULL)
  1575 1590             {
< >   1576                 Ns_Free(fetchbuf->array_values);
    1591               /* allocated from Tcl_SplitList so Tcl_Free it */
    1592               Tcl_Free((char *)fetchbuf->array_values);
1577 1593               fetchbuf->array_values = NULL;
  1578 1594               fetchbuf->array_count = 0;
  1579 1595             }
 
1661 1677   if (fetchbuf->fetch_length > fetchbuf->buf_size / 2)
  1662 1678     {
  1663 1679       fetchbuf->buf_size *= 2;
< >   1664         fetchbuf->buf = ns_realloc (fetchbuf->buf, fetchbuf->buf_size);
    1680       fetchbuf->buf = Ns_Realloc (fetchbuf->buf, fetchbuf->buf_size);
1665 1681     }
  1666 1682  
  1667 1683   fetchbuf->piecewise_fetch_length = fetchbuf->buf_size - fetchbuf->fetch_length;
 
1840 1856          
  1841 1857           /* this might work if the rest of our LONG stuff worked */
  1842 1858         case SQLT_LNG:
< >   1843             fetchbuf->buf_size = 1024;
    1859           fetchbuf->buf_size = lob_buffer_size;
1844 1860           fetchbuf->buf = Ns_Malloc (fetchbuf->buf_size);
  1845 1861           break;
  1846 1862          
 
1923 1939                                        &fetchbuf->def,
  1924 1940                                        connection->err,
  1925 1941                                        i + 1,
< >   1926                                          fetchbuf->buf,
  1927                                          fetchbuf->buf_size,
  1928                                          SQLT_LNG,
    1942                                        0,
    1943                                        (sb4)SB4MAXVAL,
    1944                                        fetchbuf->type,
1929 1945                                        &fetchbuf->is_null,
  1930 1946                                        &fetchbuf->fetch_length,
  1931 1947                                        0,
 
1937 1953               return 0;
  1938 1954             }
  1939 1955          
< >   1940             oci_status = OCIDefineDynamic (fetchbuf->def,
  1941                                            connection->err,
  1942                                            fetchbuf, long_get_data);
  1943             if (oci_error_p (lexpos (), dbh, "OCIDefineDynamic", 0, oci_status))
  1944               {
  1945                 flush_handle (dbh);
  1946                 return 0;
  1947               }
  1948            
1949 1956           log (lexpos (), "`OCIDefineDynamic ()' success");
  1950 1957           break;
  1951 1958          
 
2013 2020   oci_status_t oci_status;
  2014 2021   ora_connection_t *connection;
  2015 2022   int i;
< >   2016    
    2023   ub4 ret_len = 0;
    2024
2017 2025   log (lexpos (), "entry (dbh %p, row %p)", dbh, row);
  2018 2026  
  2019 2027   if (! dbh || !row)
 
2049 2057                              1,
  2050 2058                              OCI_FETCH_NEXT,
  2051 2059                              OCI_DEFAULT);
< >   2052     if (oci_status == OCI_NO_DATA)
    2060   if (oci_status == OCI_NEED_DATA) {
    2061       ;
    2062   }
    2063   else if (oci_status == OCI_NO_DATA)
2053 2064     {
  2054 2065       /* we've reached beyond the last row of the select, so flush the
  2055 2066          statement and tell AOLserver that it isn't going to get
 
2142 2153         case SQLT_LNG:
  2143 2154           /* this is broken for multi-part LONGs.  LONGs are being deprecated
  2144 2155            * by Oracle anyway, so no big loss
< >     2156            *
    2157            * Maybe fixed by davis@arsdigita.com
2145 2158            */
  2146 2159           if (fetchbuf->is_null == -1)
  2147 2160             fetchbuf->buf[0] = 0;
 
2152 2165               return NS_ERROR;
  2153 2166             }
  2154 2167           else
< >   2155               {
  2156                 fetchbuf->buf[fetchbuf->fetch_length] = 0;
  2157               }
    2168           {
    2169               fetchbuf->buf[0] = 0;
    2170               fetchbuf->fetch_length = 0;
    2171               ret_len = 0;
    2172  
    2173               log(lexpos(), "LONG start: buf_size=%d fetched=%d\n", fetchbuf->buf_size, fetchbuf->fetch_length);
    2174  
    2175               do {
    2176                   dvoid *def;
    2177                   ub1 inoutp;
    2178                   ub1 piece;
    2179                   ub4 type;
    2180                   ub4 iterp;
    2181                   ub4 idxp;
    2182         
    2183                   fetchbuf->fetch_length += ret_len;                    
    2184                   if (fetchbuf->fetch_length > fetchbuf->buf_size / 2) {
    2185                       fetchbuf->buf_size *= 2;
    2186                       fetchbuf->buf = ns_realloc (fetchbuf->buf, fetchbuf->buf_size);
    2187                   }
    2188                   ret_len = fetchbuf->buf_size - fetchbuf->fetch_length;
    2189  
    2190                   oci_status = OCIStmtGetPieceInfo(connection->stmt,
    2191                                                    connection->err,
    2192                                                    (dvoid **)&fetchbuf->def,  
    2193                                                    &type,
    2194                                                    &inoutp,
    2195                                                    &iterp,   
    2196                                                    &idxp,
    2197                                                    &piece);
    2198    
    2199                   if (oci_error_p (lexpos (), dbh, "OCIStmtGetPieceInfo", 0, oci_status)) {
    2200                       flush_handle (dbh);
    2201                       return NS_ERROR;
    2202                   }
    2203  
    2204                   oci_status = OCIStmtSetPieceInfo(
    2205                       fetchbuf->def,  
    2206                       OCI_HTYPE_DEFINE,  
    2207                       connection->err,
    2208                       (void *) (fetchbuf->buf + fetchbuf->fetch_length),
    2209                       &ret_len,
    2210                       piece,
    2211                       NULL,
    2212                       NULL);
    2213  
    2214                   if (oci_error_p (lexpos (), dbh, "OCIStmtGetPieceInfo", 0, oci_status)) {
    2215                       flush_handle (dbh);
    2216                       return NS_ERROR;
    2217                   }
    2218  
    2219                   oci_status = OCIStmtFetch(connection->stmt,
    2220                                             connection->err,
    2221                                             1,
    2222                                             OCI_FETCH_NEXT,
    2223                                             OCI_DEFAULT);  
    2224  
    2225                   log(lexpos(), "LONG: status=%d ret_len=%d buf_size=%d fetched=%d\n", oci_status, ret_len, fetchbuf->buf_size, fetchbuf->fetch_length);
    2226  
    2227                   if (oci_status != OCI_NEED_DATA
    2228                       && oci_error_p (lexpos (), dbh, "OCIStmtFetch", 0, oci_status)) {
    2229                       flush_handle (dbh);
    2230                       return NS_ERROR;
    2231                   }
    2232  
    2233                   if (oci_status == OCI_NO_DATA)
    2234                       break;   
    2235    
    2236               } while (oci_status == OCI_SUCCESS_WITH_INFO ||   
    2237                        oci_status == OCI_NEED_DATA);  
    2238  
    2239           }
    2240
    2241           fetchbuf->buf[fetchbuf->fetch_length] = 0;
    2242           log(lexpos(), "LONG done: status=%d buf_size=%d fetched=%d\n", oci_status, fetchbuf->buf_size, fetchbuf->fetch_length);
2158 2243          
  2159 2244           Ns_SetPutValue (row, i, fetchbuf->buf);
  2160 2245          
  2161 2246           break;
  2162 2247          
< >   2163            
2164 2248         default:
  2165 2249           /* add null termination and then do an ns_set put */
  2166 2250           if (fetchbuf->is_null == -1)
 
2172 2256               return NS_ERROR;
  2173 2257             }
  2174 2258           else
< >   2175               fetchbuf->buf[fetchbuf->fetch_length] = 0;
  2176            
    2259             fetchbuf->buf[fetchbuf->fetch_length] = 0;
    2260
2177 2261           Ns_SetPutValue (row, i, fetchbuf->buf);
  2178 2262
  2179 2263           break;
 
2527 2611 {
  2528 2612   oci_status_t oci_status;
  2529 2613   ora_connection_t *connection;
< >   2530     char *sql;
    2614   char *sql = 0;
2531 2615   OCIStmt *stmt = NULL;
  2532 2616  
  2533 2617   OCIDefine *table_name_def;
 
3362 3446                     }
  3363 3447                   flush_handle(dbh);
  3364 3448                   string_list_free_list(bind_variables);
< >   3365                     Tcl_Free((char *)argv);
3366 3449                   return TCL_ERROR;
  3367 3450                 }
  3368 3451               value = argv[argv_base + index];
 
3386 3469                                         "'", NULL);
  3387 3470                       flush_handle(dbh);
  3388 3471                       string_list_free_list(bind_variables);
< >   3389                         Tcl_Free((char *)argv);
3390 3472                       return TCL_ERROR;
  3391 3473                     }
  3392 3474                 }
 
3402 3484               strncpy(retbuf, value, EXEC_PLSQL_BUFFER_SIZE);
  3403 3485               fetchbuf->fetch_length = EXEC_PLSQL_BUFFER_SIZE;
  3404 3486               fetchbuf->is_null = 0;
< >     3487
3405 3488             }
  3406 3489           else
  3407 3490             {
 
3414 3497           if (dbh->verbose)
  3415 3498             Ns_Log(Notice, "bind variable '%s' = '%s'", var_p->string, value);
  3416 3499
< >   3417             log(lexpos(), "ns_ora exec_plsql:  binding variable %s", var_p->string);
    3500           log(lexpos(), "ns_ora exec_plsql_bind:  binding variable %s", var_p->string);
3418 3501
  3419 3502           oci_status = OCIBindByName(connection->stmt,
  3420 3503                                      &fetchbuf->bind,
 
3595 3678           flush_handle (dbh);
  3596 3679           return NS_ERROR;
  3597 3680         }
< >   3598         if (type == OCI_STMT_SELECT)
    3681       if (type == OCI_STMT_SELECT) {
3599 3682         iters = 0;
< >   3600         else
    3683         if (prefetch_rows > 0) {
    3684             /* Set prefetch rows attr for selects... */
    3685             oci_status = OCIAttrSet (connection->stmt,
    3686                                      OCI_HTYPE_STMT,
    3687                                      (dvoid *) &prefetch_rows,
    3688                                      0,
    3689                                      OCI_ATTR_PREFETCH_ROWS,
    3690                                      connection->err);
    3691             if (oci_error_p (lexpos (), dbh, "OCIAttrSet", query, oci_status))
    3692             {
    3693                 Tcl_SetResult(interp, dbh->dsExceptionMsg.string, TCL_VOLATILE);
    3694                 flush_handle (dbh);
    3695                 return NS_ERROR;
    3696             }
    3697         }
    3698         if (prefetch_memory > 0) {
    3699             /* Set prefetch rows attr for selects... */
    3700             oci_status = OCIAttrSet (connection->stmt,
    3701                                      OCI_HTYPE_STMT,
    3702                                      (dvoid *) &prefetch_memory,
    3703                                      0,
    3704                                      OCI_ATTR_PREFETCH_MEMORY,
    3705                                      connection->err);
    3706             if (oci_error_p (lexpos (), dbh, "OCIAttrSet", query, oci_status))
    3707             {
    3708                 Tcl_SetResult(interp, dbh->dsExceptionMsg.string, TCL_VOLATILE);
    3709                 flush_handle (dbh);
    3710                 return NS_ERROR;
    3711             }
    3712         }
    3713       } else {
3601 3714         iters = 1;
< >   3602  
    3715       }
    3716      
3603 3717       /* Check for statement type mismatch */
  3604 3718
  3605 3719       if (type != OCI_STMT_SELECT && ! dml_p) {
 
4158 4272   ub4   amtp = 0;
  4159 4273   ub4   piece = 0;
  4160 4274   ub4   remainder;            /* the number of bytes for the last piece */
< >   4161     int  fd;
    4275   int  fd = 0;
4162 4276   int bytes_to_write, bytes_written;
  4163 4277   int status = STREAM_WRITE_LOB_ERROR;
  4164 4278   oci_status_t oci_status;
 
4508 4622                 }
  4509 4623               flush_handle(dbh);
  4510 4624               string_list_free_list(bind_variables);
< >   4511                 Tcl_Free((char *)argv);
    4625               Tcl_Free((char *)lob_argv);
4512 4626               return TCL_ERROR;
  4513 4627             }
  4514 4628           value = argv[argv_base + index];
 
4522 4636                                 "'", NULL);
  4523 4637               flush_handle(dbh);
  4524 4638               string_list_free_list(bind_variables);
< >   4525                 Tcl_Free((char *)argv);
    4639               Tcl_Free((char *)lob_argv);
4526 4640               return TCL_ERROR;
  4527 4641             }
  4528 4642         }
 
4581 4695           if (tcl_error_p (lexpos (), interp, dbh, "OCIBindDynamic", query, oci_status))
  4582 4696             {
  4583 4697               flush_handle (dbh);
< >   4584                 Tcl_Free((char *)argv);
    4698               Tcl_Free((char *)lob_argv);
< _   4585 4699               string_list_free_list(bind_variables);
  4586 4700               return TCL_ERROR;
  4587 4701             }