|
| |
57 |
57 |
|
|
| |
58 |
58 |
|
|
| |
59 |
59 |
|
|
| |
|
60 |
|
|
| |
|
61 |
#include <oci.h> |
|
| |
60 |
62 |
|
|
| |
61 |
63 |
|
|
| |
|
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 |
|
|
|
| |
105 |
|
#include <oci.h> |
|
| |
106 |
107 |
|
|
| |
107 |
108 |
|
|
| |
108 |
109 |
|
|
|
| |
337 |
338 |
|
|
| |
338 |
339 |
static int lob_buffer_size = 16384; |
|
| |
339 |
340 |
|
|
| |
|
341 |
|
|
| |
|
342 |
static ub4 prefetch_rows = 0; |
|
| |
|
343 |
static ub4 prefetch_memory = 0; |
|
| |
|
344 |
|
|
| |
340 |
345 |
|
|
| |
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 |
|
|
| |
|
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 |
|
|
| |
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 |
|
|
| |
2055 |
2066 |
|
|
|
| |
2142 |
2153 |
case SQLT_LNG: |
|
| |
2143 |
2154 |
|
|
| |
2144 |
2155 |
|
|
| |
|
2156 |
|
|
| |
|
2157 |
|
|
| |
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 |
|
|
| |
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 |
|
|
| |
|
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 |
|
|
| |
|
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 |
|
|
| |
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; |
|
| |
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 |
} |