OCILIB (C Driver for Oracle) 3.9.2
|
00001 /* 00002 +-----------------------------------------------------------------------------------------+ 00003 | | 00004 | OCILIB - C Driver for Oracle | 00005 | | 00006 | (C Wrapper for Oracle OCI) | 00007 | | 00008 | Website : http://www.ocilib.net | 00009 | | 00010 | Copyright (c) 2007-2011 Vincent ROGIER <vince.rogier@ocilib.net> | 00011 | | 00012 +-----------------------------------------------------------------------------------------+ 00013 | | 00014 | This library is free software; you can redistribute it and/or | 00015 | modify it under the terms of the GNU Lesser General Public | 00016 | License as published by the Free Software Foundation; either | 00017 | version 2 of the License, or (at your option) any later version. | 00018 | | 00019 | This library is distributed in the hope that it will be useful, | 00020 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 00021 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 00022 | Lesser General Public License for more details. | 00023 | | 00024 | You should have received a copy of the GNU Lesser General Public | 00025 | License along with this library; if not, write to the Free | 00026 | Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 00027 | | 00028 +-----------------------------------------------------------------------------------------+ 00029 */ 00030 00031 /* --------------------------------------------------------------------------------------------- * 00032 * $Id: lob.c, v 3.9.2 2011-07-13 00:00 Vincent Rogier $ 00033 * --------------------------------------------------------------------------------------------- */ 00034 00035 #include "ocilib_internal.h" 00036 00037 /* ********************************************************************************************* * 00038 * PRIVATE FUNCTIONS 00039 * ********************************************************************************************* */ 00040 00041 /* --------------------------------------------------------------------------------------------- * 00042 * OCI_LobInit 00043 * --------------------------------------------------------------------------------------------- */ 00044 00045 OCI_Lob * OCI_LobInit 00046 ( 00047 OCI_Connection *con, 00048 OCI_Lob **plob, 00049 OCILobLocator *handle, 00050 ub4 type 00051 ) 00052 { 00053 ub2 csid = OCI_DEFAULT; 00054 ub1 csfrm = OCI_DEFAULT; 00055 OCI_Lob * lob = NULL; 00056 boolean res = TRUE; 00057 ub1 lobtype = 0; 00058 00059 OCI_CHECK(plob == NULL, NULL); 00060 00061 if (*plob == NULL) 00062 { 00063 *plob = (OCI_Lob *) OCI_MemAlloc(OCI_IPC_LOB, sizeof(*lob), (size_t) 1, TRUE); 00064 } 00065 00066 if (*plob != NULL) 00067 { 00068 lob = *plob; 00069 00070 lob->type = type; 00071 lob->con = con; 00072 lob->handle = handle; 00073 lob->offset = 1; 00074 00075 if ((lob->handle == NULL) || (lob->hstate == OCI_OBJECT_ALLOCATED_ARRAY)) 00076 { 00077 ub4 empty = 0; 00078 00079 if (lob->type == OCI_NCLOB) 00080 { 00081 csfrm = SQLCS_NCHAR; 00082 lobtype = OCI_TEMP_CLOB; 00083 } 00084 else if (lob->type == OCI_CLOB) 00085 { 00086 csfrm = SQLCS_IMPLICIT; 00087 lobtype = OCI_TEMP_CLOB; 00088 } 00089 else 00090 { 00091 lobtype = OCI_TEMP_BLOB; 00092 } 00093 00094 /* allocate handle for non fetched lob (temporary lob) */ 00095 00096 if (lob->hstate != OCI_OBJECT_ALLOCATED_ARRAY) 00097 { 00098 lob->hstate = OCI_OBJECT_ALLOCATED; 00099 00100 res = (OCI_SUCCESS == OCI_DescriptorAlloc((dvoid *) lob->con->env, 00101 (dvoid **) (void *) &lob->handle, 00102 (ub4) OCI_DTYPE_LOB, 00103 (size_t) 0, (dvoid **) NULL)); 00104 } 00105 00106 OCI_CALL2 00107 ( 00108 res, lob->con, 00109 00110 OCIAttrSet((dvoid *) lob->handle, (ub4) OCI_DTYPE_LOB, 00111 (dvoid *) &empty, (ub4) sizeof(empty), 00112 (ub4) OCI_ATTR_LOBEMPTY, lob->con->err) 00113 ) 00114 00115 OCI_CALL2 00116 ( 00117 res, lob->con, 00118 00119 OCILobCreateTemporary(lob->con->cxt, lob->con->err, 00120 lob->handle, csid, csfrm, lobtype, 00121 FALSE, OCI_DURATION_SESSION) 00122 ) 00123 00124 } 00125 else 00126 { 00127 lob->hstate = OCI_OBJECT_FETCHED_CLEAN; 00128 } 00129 } 00130 else 00131 { 00132 res = FALSE; 00133 } 00134 00135 /* check for failure */ 00136 00137 if (res == FALSE) 00138 { 00139 OCI_LobFree(lob); 00140 lob = NULL; 00141 } 00142 00143 return lob; 00144 } 00145 00146 /* ********************************************************************************************* * 00147 * PUBLIC FUNCTIONS 00148 * ********************************************************************************************* */ 00149 00150 /* --------------------------------------------------------------------------------------------- * 00151 * OCI_LobCreate 00152 * --------------------------------------------------------------------------------------------- */ 00153 00154 OCI_Lob * OCI_API OCI_LobCreate 00155 ( 00156 OCI_Connection *con, 00157 unsigned int type 00158 ) 00159 { 00160 OCI_Lob *lob = NULL; 00161 00162 OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, NULL); 00163 00164 lob = OCI_LobInit(con, &lob, NULL, type); 00165 00166 OCI_RESULT(lob != NULL); 00167 00168 return lob; 00169 } 00170 00171 /* --------------------------------------------------------------------------------------------- * 00172 * OCI_LobFree 00173 * --------------------------------------------------------------------------------------------- */ 00174 00175 boolean OCI_API OCI_LobFree 00176 ( 00177 OCI_Lob *lob 00178 ) 00179 { 00180 boolean res = TRUE; 00181 00182 OCI_CHECK_PTR(OCI_IPC_LOB, lob, FALSE); 00183 00184 OCI_CHECK_OBJECT_FETCHED(lob, FALSE); 00185 00186 if (OCI_LobIsTemporary(lob) == TRUE) 00187 { 00188 OCI_CALL2 00189 ( 00190 res, lob->con, 00191 00192 OCILobFreeTemporary(lob->con->cxt, lob->con->err, lob->handle) 00193 ) 00194 } 00195 00196 if (lob->hstate == OCI_OBJECT_ALLOCATED) 00197 { 00198 OCI_DescriptorFree((dvoid *) lob->handle, (ub4) OCI_DTYPE_LOB); 00199 } 00200 00201 if (lob->hstate != OCI_OBJECT_ALLOCATED_ARRAY) 00202 { 00203 OCI_FREE(lob); 00204 } 00205 00206 OCI_RESULT(res); 00207 00208 return res; 00209 } 00210 00211 /* --------------------------------------------------------------------------------------------- * 00212 * OCI_LobArrayCreate 00213 * --------------------------------------------------------------------------------------------- */ 00214 00215 OCI_Lob ** OCI_API OCI_LobArrayCreate 00216 ( 00217 OCI_Connection *con, 00218 unsigned int type, 00219 unsigned int nbelem 00220 ) 00221 { 00222 OCI_Array *arr = NULL; 00223 OCI_Lob **lobs = NULL; 00224 00225 arr = OCI_ArrayCreate(con, nbelem, OCI_CDT_LOB, type, sizeof(OCILobLocator *), 00226 sizeof(OCI_Lob), OCI_DTYPE_LOB, NULL); 00227 00228 if (arr != NULL) 00229 { 00230 lobs = (OCI_Lob **) arr->tab_obj; 00231 } 00232 00233 return lobs; 00234 } 00235 00236 /* --------------------------------------------------------------------------------------------- * 00237 * OCI_LobArrayFree 00238 * --------------------------------------------------------------------------------------------- */ 00239 00240 boolean OCI_API OCI_LobArrayFree 00241 ( 00242 OCI_Lob **lobs 00243 ) 00244 { 00245 return OCI_ArrayFreeFromHandles((void **) lobs); 00246 } 00247 00248 /* --------------------------------------------------------------------------------------------- * 00249 * OCI_LobGetType 00250 * --------------------------------------------------------------------------------------------- */ 00251 00252 unsigned int OCI_API OCI_LobGetType 00253 ( 00254 OCI_Lob *lob 00255 ) 00256 { 00257 OCI_CHECK_PTR(OCI_IPC_LOB, lob, OCI_UNKNOWN); 00258 00259 OCI_RESULT(TRUE); 00260 00261 return lob->type; 00262 } 00263 00264 /* --------------------------------------------------------------------------------------------- * 00265 * OCI_LobSeek 00266 * --------------------------------------------------------------------------------------------- */ 00267 00268 boolean OCI_API OCI_LobSeek 00269 ( 00270 OCI_Lob *lob, 00271 big_uint offset, 00272 unsigned int mode 00273 ) 00274 { 00275 boolean res = TRUE; 00276 big_uint size = 0; 00277 00278 OCI_CHECK_PTR(OCI_IPC_LOB, lob, FALSE); 00279 00280 size = OCI_LobGetLength(lob); 00281 00282 if ((mode == OCI_SEEK_CUR && (offset + lob->offset-1) > size)) 00283 { 00284 res = FALSE; 00285 } 00286 else if (mode == OCI_SEEK_SET) 00287 { 00288 lob->offset = offset + 1; 00289 } 00290 else if (mode == OCI_SEEK_END) 00291 { 00292 lob->offset = size-offset + 1; 00293 } 00294 else if (mode == OCI_SEEK_CUR) 00295 { 00296 lob->offset += offset; 00297 } 00298 else 00299 { 00300 res = FALSE; 00301 } 00302 00303 OCI_RESULT(res); 00304 00305 return res; 00306 } 00307 00308 /* --------------------------------------------------------------------------------------------- * 00309 * OCI_LobGetOffset 00310 * --------------------------------------------------------------------------------------------- */ 00311 00312 big_uint OCI_API OCI_LobGetOffset 00313 ( 00314 OCI_Lob *lob 00315 ) 00316 { 00317 OCI_CHECK_PTR(OCI_IPC_LOB, lob, 0); 00318 00319 OCI_RESULT(TRUE); 00320 00321 return lob->offset - 1; 00322 } 00323 00324 /* --------------------------------------------------------------------------------------------- * 00325 * OCI_LobRead2 00326 * --------------------------------------------------------------------------------------------- */ 00327 00328 boolean OCI_API OCI_LobRead2 00329 ( 00330 OCI_Lob *lob, 00331 void *buffer, 00332 unsigned int *char_count, 00333 unsigned int *byte_count 00334 ) 00335 { 00336 boolean res = TRUE; 00337 ub2 csid = 0; 00338 ub1 csfrm = 0; 00339 00340 OCI_CHECK_PTR(OCI_IPC_LOB, lob, FALSE); 00341 OCI_CHECK_PTR(OCI_IPC_LOB, char_count, FALSE); 00342 OCI_CHECK_PTR(OCI_IPC_LOB, byte_count, FALSE); 00343 00344 if (lob->type != OCI_BLOB) 00345 { 00346 00347 #ifdef OCI_USERDATA_WIDE 00348 00349 csid = OCI_UTF16ID; 00350 00351 #endif 00352 00353 if (((*byte_count) == 0) && ((*char_count) > 0)) 00354 { 00355 if (OCILib.nls_utf8 == TRUE) 00356 { 00357 (*byte_count) = (*char_count) * (ub4) UTF8_BYTES_PER_CHAR; 00358 } 00359 else 00360 { 00361 (*byte_count) = (*char_count) * (ub4) sizeof(odtext); 00362 } 00363 } 00364 } 00365 00366 if (lob->type == OCI_NCLOB) 00367 { 00368 csfrm = SQLCS_NCHAR; 00369 } 00370 else 00371 { 00372 csfrm = SQLCS_IMPLICIT; 00373 } 00374 00375 OCI_CHECK_MIN(lob->con, NULL, (*byte_count), 1, FALSE); 00376 00377 #ifdef OCI_LOB2_API_ENABLED 00378 00379 if (OCILib.use_lob_ub8) 00380 { 00381 ub8 size_in_out_char = (ub8) (*char_count); 00382 ub8 size_in_out_byte = (ub8) (*byte_count); 00383 00384 OCI_CALL2 00385 ( 00386 res, lob->con, 00387 00388 OCILobRead2(lob->con->cxt, lob->con->err, lob->handle, 00389 &size_in_out_byte, &size_in_out_char, 00390 (ub8) lob->offset, buffer,(ub8) (*byte_count), 00391 (ub1) OCI_ONE_PIECE, (void *) NULL, 00392 NULL, csid, csfrm) 00393 ) 00394 00395 (*char_count) = (ub4) size_in_out_char; 00396 (*byte_count) = (ub4) size_in_out_byte; 00397 } 00398 00399 else 00400 00401 #endif 00402 00403 { 00404 ub4 size_in_out_char_byte = 0; 00405 00406 if (lob->type == OCI_BLOB) 00407 { 00408 size_in_out_char_byte = (*byte_count); 00409 } 00410 else 00411 { 00412 size_in_out_char_byte = (*char_count); 00413 } 00414 00415 OCI_CALL2 00416 ( 00417 res, lob->con, 00418 00419 OCILobRead(lob->con->cxt, lob->con->err, lob->handle, 00420 &size_in_out_char_byte, (ub4) lob->offset, 00421 buffer, (ub4) (*byte_count), (void *) NULL, 00422 NULL, csid, csfrm) 00423 ) 00424 00425 (*char_count) = (ub4) size_in_out_char_byte; 00426 (*byte_count) = (ub4) size_in_out_char_byte; 00427 } 00428 00429 if (lob->type != OCI_BLOB) 00430 { 00431 unsigned int byte_offset = (ub4) (*byte_count); 00432 00433 if (OCILib.nls_utf8 == FALSE) 00434 { 00435 byte_offset *= sizeof(odtext); 00436 } 00437 00438 memset(((char *) buffer) + byte_offset, 0, sizeof(odtext)); 00439 00440 #ifndef OCI_LOB2_API_ENABLED 00441 00442 if (OCILib.nls_utf8 == TRUE) 00443 { 00444 (*char_count) = OCI_StringUTF8Length((const char *) buffer); 00445 } 00446 00447 #endif 00448 00449 } 00450 00451 if (res == TRUE) 00452 { 00453 if (lob->type == OCI_BLOB) 00454 { 00455 lob->offset += (big_uint) (*byte_count); 00456 } 00457 else 00458 { 00459 lob->offset += (big_uint) (*char_count); 00460 00461 if (OCILib.nls_utf8 == FALSE) 00462 { 00463 OCI_ConvertString(buffer, (int) (*char_count), sizeof(odtext), sizeof(dtext)); 00464 } 00465 } 00466 } 00467 00468 OCI_RESULT(res); 00469 00470 return res; 00471 } 00472 00473 /* --------------------------------------------------------------------------------------------- * 00474 * OCI_LobRead 00475 * --------------------------------------------------------------------------------------------- */ 00476 00477 unsigned int OCI_API OCI_LobRead 00478 ( 00479 OCI_Lob *lob, 00480 void *buffer, 00481 unsigned int len 00482 ) 00483 { 00484 unsigned int char_count = 0; 00485 unsigned int byte_count = 0; 00486 unsigned int *ptr_count = NULL; 00487 00488 if (lob != NULL) 00489 { 00490 if(lob->type == OCI_BLOB) 00491 { 00492 byte_count = len; 00493 ptr_count = &byte_count; 00494 } 00495 else 00496 { 00497 char_count = len; 00498 ptr_count = &char_count; 00499 } 00500 } 00501 00502 OCI_LobRead2(lob, buffer, &char_count, &byte_count); 00503 00504 return (ptr_count ? *ptr_count : 0); 00505 } 00506 00507 /* --------------------------------------------------------------------------------------------- * 00508 * OCI_LobWrite 00509 * --------------------------------------------------------------------------------------------- */ 00510 00511 boolean OCI_API OCI_LobWrite2 00512 ( 00513 OCI_Lob *lob, 00514 void *buffer, 00515 unsigned int *char_count, 00516 unsigned int *byte_count 00517 ) 00518 { 00519 boolean res = TRUE; 00520 ub2 csid = 0; 00521 ub1 csfrm = 0; 00522 void *obuf = NULL; 00523 00524 OCI_CHECK_PTR(OCI_IPC_LOB, char_count, FALSE); 00525 OCI_CHECK_PTR(OCI_IPC_LOB, byte_count, FALSE); 00526 00527 if (lob->type != OCI_BLOB) 00528 { 00529 00530 #ifdef OCI_USERDATA_WIDE 00531 00532 csid = OCI_UTF16ID; 00533 00534 #endif 00535 00536 if (((*byte_count) == 0) && ((*char_count) > 0)) 00537 { 00538 if (OCILib.nls_utf8 == TRUE) 00539 { 00540 (*byte_count) = (unsigned int) strlen(buffer); 00541 } 00542 else 00543 { 00544 (*byte_count) = (*char_count) * (ub4) sizeof(dtext); 00545 } 00546 } 00547 00548 if (((*char_count) == 0) && ((*byte_count) > 0)) 00549 { 00550 if (OCILib.nls_utf8 == TRUE) 00551 { 00552 00553 #ifndef OCI_LOB2_API_ENABLED 00554 00555 (*char_count) = OCI_StringUTF8Length((const char *) buffer); 00556 00557 #endif 00558 00559 } 00560 else 00561 { 00562 (*char_count) = (*byte_count) / (ub4) sizeof(dtext); 00563 } 00564 } 00565 00566 obuf = OCI_GetInputDataString(buffer, (int *) byte_count); 00567 00568 (*byte_count) *= sizeof(odtext); 00569 } 00570 else 00571 { 00572 obuf = buffer; 00573 } 00574 00575 if (lob->type == OCI_NCLOB) 00576 { 00577 csfrm = SQLCS_NCHAR; 00578 } 00579 else 00580 { 00581 csfrm = SQLCS_IMPLICIT; 00582 } 00583 00584 OCI_CHECK_MIN(lob->con, NULL, (*byte_count), 1, FALSE); 00585 00586 #ifdef OCI_LOB2_API_ENABLED 00587 00588 if (OCILib.use_lob_ub8) 00589 { 00590 ub8 size_in_out_char = (ub8) (*char_count); 00591 ub8 size_in_out_byte = (ub8) (*byte_count); 00592 00593 OCI_CALL2 00594 ( 00595 res, lob->con, 00596 00597 OCILobWrite2(lob->con->cxt, lob->con->err, lob->handle, 00598 &size_in_out_byte, &size_in_out_char, 00599 (ub8) lob->offset, obuf, (ub8) (*byte_count), 00600 (ub1) OCI_ONE_PIECE, (void *) NULL, 00601 NULL, csid, csfrm) 00602 ) 00603 00604 (*char_count) = (ub4) size_in_out_char; 00605 (*byte_count) = (ub4) size_in_out_byte; 00606 } 00607 00608 else 00609 00610 #endif 00611 00612 { 00613 ub4 size_in_out_char_byte = 0; 00614 00615 if ((lob->type == OCI_BLOB) || (OCILib.nls_utf8 == TRUE)) 00616 { 00617 size_in_out_char_byte = (*byte_count); 00618 } 00619 else 00620 { 00621 size_in_out_char_byte = (*char_count); 00622 } 00623 00624 OCI_CALL2 00625 ( 00626 res, lob->con, 00627 00628 OCILobWrite(lob->con->cxt, lob->con->err, lob->handle, 00629 &size_in_out_char_byte, (ub4) lob->offset, 00630 obuf, (ub4) (*byte_count), (ub1) OCI_ONE_PIECE, 00631 (void *) NULL, NULL, csid, csfrm) 00632 ) 00633 00634 if (lob->type == OCI_BLOB) 00635 { 00636 (*byte_count) = (ub4) size_in_out_char_byte; 00637 } 00638 else 00639 { 00640 (*char_count) = (ub4) size_in_out_char_byte; 00641 } 00642 } 00643 00644 if (res == TRUE) 00645 { 00646 if (lob->type == OCI_BLOB) 00647 { 00648 lob->offset += (big_uint) (*byte_count); 00649 } 00650 else 00651 { 00652 lob->offset += (big_uint) (*char_count); 00653 00654 if (OCILib.nls_utf8 == FALSE) 00655 { 00656 OCI_ReleaseDataString(obuf); 00657 } 00658 } 00659 } 00660 00661 OCI_RESULT(res); 00662 00663 return res; 00664 } 00665 00666 /* --------------------------------------------------------------------------------------------- * 00667 * OCI_LobWrite 00668 * --------------------------------------------------------------------------------------------- */ 00669 00670 unsigned int OCI_API OCI_LobWrite 00671 ( 00672 OCI_Lob *lob, 00673 void *buffer, 00674 unsigned int len 00675 ) 00676 { 00677 unsigned int char_count = 0; 00678 unsigned int byte_count = 0; 00679 unsigned int *ptr_count = NULL; 00680 00681 if (lob != NULL) 00682 { 00683 if(lob->type == OCI_BLOB) 00684 { 00685 byte_count = len; 00686 ptr_count = &byte_count; 00687 } 00688 else 00689 { 00690 char_count = len; 00691 ptr_count = &char_count; 00692 } 00693 } 00694 00695 OCI_LobWrite2(lob, buffer, &char_count, &byte_count); 00696 00697 return (ptr_count ? *ptr_count : 0); 00698 } 00699 00700 /* --------------------------------------------------------------------------------------------- * 00701 * OCI_LobTruncate 00702 * --------------------------------------------------------------------------------------------- */ 00703 00704 boolean OCI_API OCI_LobTruncate 00705 ( 00706 OCI_Lob *lob, 00707 big_uint size 00708 ) 00709 { 00710 boolean res = TRUE; 00711 00712 OCI_CHECK_PTR(OCI_IPC_LOB, lob, FALSE); 00713 00714 #ifdef OCI_LOB2_API_ENABLED 00715 00716 if (OCILib.use_lob_ub8) 00717 { 00718 OCI_CALL2 00719 ( 00720 res, lob->con, 00721 00722 OCILobTrim2(lob->con->cxt, lob->con->err, lob->handle, (ub8) size) 00723 ) 00724 } 00725 else 00726 00727 #endif 00728 00729 { 00730 OCI_CALL2 00731 ( 00732 res, lob->con, 00733 00734 OCILobTrim(lob->con->cxt, lob->con->err, lob->handle, (ub4) size) 00735 ) 00736 } 00737 00738 OCI_RESULT(res); 00739 00740 return res; 00741 } 00742 00743 /* --------------------------------------------------------------------------------------------- * 00744 * OCI_LobErase 00745 * --------------------------------------------------------------------------------------------- */ 00746 00747 big_uint OCI_API OCI_LobErase 00748 ( 00749 OCI_Lob *lob, 00750 big_uint offset, 00751 big_uint size 00752 ) 00753 { 00754 boolean res = TRUE; 00755 00756 OCI_CHECK_PTR(OCI_IPC_LOB, lob, 0); 00757 OCI_CHECK_MIN(lob->con, NULL, size, 1, 0); 00758 00759 #ifdef OCI_LOB2_API_ENABLED 00760 00761 if (OCILib.use_lob_ub8) 00762 { 00763 ub8 lob_size = (ub8) size; 00764 00765 OCI_CALL2 00766 ( 00767 res, lob->con, 00768 00769 OCILobErase2(lob->con->cxt, lob->con->err, lob->handle, (ub8 *) &lob_size, (ub8) (offset + 1)) 00770 ) 00771 00772 size = (big_uint) lob_size; 00773 } 00774 else 00775 00776 #endif 00777 00778 { 00779 ub4 lob_size = (ub4) size; 00780 00781 OCI_CALL2 00782 ( 00783 res, lob->con, 00784 00785 OCILobErase(lob->con->cxt, lob->con->err, lob->handle, &lob_size, (ub4) offset + 1) 00786 ) 00787 00788 size = (big_uint) lob_size; 00789 } 00790 00791 OCI_RESULT(res); 00792 00793 return size; 00794 } 00795 00796 /* --------------------------------------------------------------------------------------------- * 00797 * OCI_LobGetLength 00798 * --------------------------------------------------------------------------------------------- */ 00799 00800 big_uint OCI_API OCI_LobGetLength 00801 ( 00802 OCI_Lob *lob 00803 ) 00804 { 00805 boolean res = TRUE; 00806 big_uint size = 0; 00807 00808 OCI_CHECK_PTR(OCI_IPC_LOB, lob, 0); 00809 00810 #ifdef OCI_LOB2_API_ENABLED 00811 00812 if (OCILib.use_lob_ub8) 00813 { 00814 ub8 lob_size = 0; 00815 00816 OCI_CALL2 00817 ( 00818 res, lob->con, 00819 00820 OCILobGetLength2(lob->con->cxt, lob->con->err, lob->handle, (ub8 *) &lob_size) 00821 ) 00822 00823 size = (big_uint) lob_size; 00824 } 00825 else 00826 00827 #endif 00828 00829 { 00830 ub4 lob_size = 0; 00831 00832 OCI_CALL2 00833 ( 00834 res, lob->con, 00835 00836 OCILobGetLength(lob->con->cxt, lob->con->err, lob->handle, &lob_size) 00837 ) 00838 00839 size = (big_uint) lob_size; 00840 } 00841 00842 OCI_RESULT(res); 00843 00844 return size; 00845 } 00846 00847 /* --------------------------------------------------------------------------------------------- * 00848 * OCI_LobGetChunkSize 00849 * --------------------------------------------------------------------------------------------- */ 00850 00851 unsigned int OCI_API OCI_LobGetChunkSize 00852 ( 00853 OCI_Lob *lob 00854 ) 00855 { 00856 boolean res = TRUE; 00857 ub4 size = 0; 00858 00859 OCI_CHECK_PTR(OCI_IPC_LOB, lob, 0); 00860 00861 OCI_CALL2 00862 ( 00863 res, lob->con, 00864 00865 OCILobGetChunkSize(lob->con->cxt, lob->con->err, lob->handle, &size) 00866 ) 00867 00868 OCI_RESULT(res); 00869 00870 return (unsigned int) size; 00871 } 00872 00873 /* --------------------------------------------------------------------------------------------- * 00874 * OCI_LobCopy 00875 * --------------------------------------------------------------------------------------------- */ 00876 00877 boolean OCI_API OCI_LobCopy 00878 ( 00879 OCI_Lob *lob, 00880 OCI_Lob *lob_src, 00881 big_uint offset_dst, 00882 big_uint offset_src, 00883 big_uint count 00884 ) 00885 { 00886 boolean res = TRUE; 00887 00888 OCI_CHECK_PTR(OCI_IPC_LOB, lob, FALSE); 00889 OCI_CHECK_PTR(OCI_IPC_LOB, lob_src, FALSE); 00890 00891 #ifdef OCI_LOB2_API_ENABLED 00892 00893 if (OCILib.use_lob_ub8) 00894 { 00895 00896 OCI_CALL2 00897 ( 00898 res, lob->con, 00899 00900 OCILobCopy2(lob->con->cxt, lob->con->err, lob->handle, 00901 lob_src->handle, (ub8) count, 00902 (ub8) (offset_dst + 1), 00903 (ub8) (offset_src + 1)) 00904 ) 00905 } 00906 else 00907 00908 #endif 00909 00910 { 00911 OCI_CALL2 00912 ( 00913 res, lob->con, 00914 00915 OCILobCopy(lob->con->cxt, lob->con->err, lob->handle, 00916 lob_src->handle, (ub4) count, 00917 (ub4) (offset_dst + 1), 00918 (ub4) (offset_src + 1)) 00919 ) 00920 } 00921 00922 OCI_RESULT(res); 00923 00924 return res; 00925 } 00926 00927 /* --------------------------------------------------------------------------------------------- * 00928 * OCI_LobCopyFromFile 00929 * --------------------------------------------------------------------------------------------- */ 00930 00931 boolean OCI_API OCI_LobCopyFromFile 00932 ( 00933 OCI_Lob *lob, 00934 OCI_File *file, 00935 big_uint offset_dst, 00936 big_uint offset_src, 00937 big_uint count 00938 ) 00939 { 00940 boolean res = TRUE; 00941 00942 OCI_CHECK_PTR(OCI_IPC_LOB, lob, FALSE); 00943 OCI_CHECK_PTR(OCI_IPC_FILE, file, FALSE); 00944 00945 #ifdef OCI_LOB2_API_ENABLED 00946 00947 if (OCILib.use_lob_ub8) 00948 { 00949 OCI_CALL2 00950 ( 00951 res, lob->con, 00952 00953 OCILobLoadFromFile2(lob->con->cxt, lob->con->err, 00954 lob->handle, file->handle, 00955 (ub8) count, 00956 (ub8) (offset_dst + 1), 00957 (ub8) (offset_src + 1)) 00958 ) 00959 } 00960 else 00961 00962 #endif 00963 00964 { 00965 OCI_CALL2 00966 ( 00967 res, lob->con, 00968 00969 OCILobLoadFromFile(lob->con->cxt, lob->con->err, 00970 lob->handle, file->handle, 00971 (ub4) count, 00972 (ub4) (offset_dst + 1), 00973 (ub4) (offset_src + 1)) 00974 ) 00975 } 00976 00977 OCI_RESULT(res); 00978 00979 return res; 00980 } 00981 00982 /* --------------------------------------------------------------------------------------------- * 00983 * OCI_LobAppend2 00984 * --------------------------------------------------------------------------------------------- */ 00985 00986 boolean OCI_API OCI_LobAppend2 00987 ( 00988 OCI_Lob *lob, 00989 void *buffer, 00990 unsigned int *char_count, 00991 unsigned int *byte_count 00992 ) 00993 { 00994 boolean res = TRUE; 00995 ub2 csid = 0; 00996 ub1 csfrm = 0; 00997 void *obuf = NULL; 00998 00999 OCI_CHECK_PTR(OCI_IPC_LOB, char_count, FALSE); 01000 OCI_CHECK_PTR(OCI_IPC_LOB, byte_count, FALSE); 01001 01002 /* OCILobWriteAppend() seems to cause problems on Oracle client 8.1 and 9.0 01003 It's an Oracle known bug #886191 01004 So we use OCI_LobSeek() + OCI_LobWrite() instead */ 01005 01006 if (OCILib.version_runtime < OCI_10_1) 01007 { 01008 return OCI_LobSeek(lob, OCI_LobGetLength(lob), OCI_SEEK_SET) && 01009 OCI_LobWrite2(lob, buffer, char_count, byte_count); 01010 } 01011 01012 if (lob->type != OCI_BLOB) 01013 { 01014 01015 #ifdef OCI_USERDATA_WIDE 01016 01017 csid = OCI_UTF16ID; 01018 01019 #endif 01020 01021 if (((*byte_count) == 0) && ((*char_count) > 0)) 01022 { 01023 if (OCILib.nls_utf8 == TRUE) 01024 { 01025 (*byte_count) = (unsigned int) strlen(buffer); 01026 } 01027 else 01028 { 01029 (*byte_count) = (*char_count) * (ub4) sizeof(dtext); 01030 } 01031 } 01032 01033 if (((*char_count) == 0) && ((*byte_count) > 0)) 01034 { 01035 if (OCILib.nls_utf8 == TRUE) 01036 { 01037 01038 #ifndef OCI_LOB2_API_ENABLED 01039 01040 (*char_count) = OCI_StringUTF8Length((const char *) buffer); 01041 01042 #endif 01043 01044 } 01045 else 01046 { 01047 (*char_count) = (*byte_count) / (ub4) sizeof(dtext); 01048 } 01049 } 01050 01051 obuf = OCI_GetInputDataString(buffer, (int *) byte_count); 01052 01053 (*byte_count) *= sizeof(odtext); 01054 } 01055 else 01056 { 01057 obuf = buffer; 01058 } 01059 01060 if (lob->type == OCI_NCLOB) 01061 { 01062 csfrm = SQLCS_NCHAR; 01063 } 01064 else 01065 { 01066 csfrm = SQLCS_IMPLICIT; 01067 } 01068 01069 OCI_CHECK_MIN(lob->con, NULL, (*byte_count), 1, FALSE); 01070 01071 #ifdef OCI_LOB2_API_ENABLED 01072 01073 if (OCILib.use_lob_ub8) 01074 { 01075 ub8 size_in_out_char = (ub8) (*char_count); 01076 ub8 size_in_out_byte = (ub8) (*byte_count); 01077 01078 OCI_CALL2 01079 ( 01080 res, lob->con, 01081 01082 OCILobWriteAppend2(lob->con->cxt, lob->con->err, lob->handle, 01083 &size_in_out_byte, &size_in_out_char, 01084 obuf, (ub8) (*byte_count), (ub1) OCI_ONE_PIECE, 01085 (dvoid *) NULL, NULL, csid, csfrm) 01086 ) 01087 01088 (*char_count) = (ub4) size_in_out_char; 01089 (*byte_count) = (ub4) size_in_out_byte; 01090 } 01091 01092 else 01093 01094 #endif 01095 01096 { 01097 ub4 size_in_out_char_byte = 0; 01098 01099 if ((lob->type == OCI_BLOB) || (OCILib.nls_utf8 == TRUE)) 01100 { 01101 size_in_out_char_byte = (*byte_count); 01102 } 01103 else 01104 { 01105 size_in_out_char_byte = (*char_count); 01106 } 01107 01108 OCI_CALL2 01109 ( 01110 res, lob->con, 01111 01112 OCILobWriteAppend(lob->con->cxt, lob->con->err, lob->handle, 01113 &size_in_out_char_byte, obuf, (*byte_count), 01114 (ub1) OCI_ONE_PIECE, (dvoid *) NULL, NULL, csid, csfrm) 01115 ) 01116 01117 if (lob->type == OCI_BLOB) 01118 { 01119 (*byte_count) = (ub4) size_in_out_char_byte; 01120 } 01121 else 01122 { 01123 (*char_count) = (ub4) size_in_out_char_byte; 01124 } 01125 } 01126 01127 if (res == TRUE) 01128 { 01129 if (lob->type == OCI_BLOB) 01130 { 01131 lob->offset += (big_uint) (*byte_count); 01132 } 01133 else 01134 { 01135 lob->offset += (big_uint) (*char_count); 01136 01137 if (OCILib.nls_utf8 == FALSE) 01138 { 01139 OCI_ReleaseDataString(obuf); 01140 } 01141 } 01142 } 01143 01144 OCI_RESULT(res); 01145 01146 return res; 01147 } 01148 01149 /* --------------------------------------------------------------------------------------------- * 01150 * OCI_LobAppend 01151 * --------------------------------------------------------------------------------------------- */ 01152 01153 unsigned int OCI_API OCI_LobAppend 01154 ( 01155 OCI_Lob *lob, 01156 void *buffer, 01157 unsigned int len 01158 ) 01159 { 01160 unsigned int char_count = 0; 01161 unsigned int byte_count = 0; 01162 unsigned int *ptr_count = NULL; 01163 01164 if (lob != NULL) 01165 { 01166 if(lob->type == OCI_BLOB) 01167 { 01168 byte_count = len; 01169 ptr_count = &byte_count; 01170 } 01171 else 01172 { 01173 char_count = len; 01174 ptr_count = &char_count; 01175 } 01176 } 01177 01178 OCI_LobAppend2(lob, buffer, &char_count, &byte_count); 01179 01180 return (ptr_count ? *ptr_count : 0); 01181 } 01182 01183 /* --------------------------------------------------------------------------------------------- * 01184 * OCI_LobAppendLob 01185 * --------------------------------------------------------------------------------------------- */ 01186 01187 boolean OCI_API OCI_LobAppendLob 01188 ( 01189 OCI_Lob *lob, 01190 OCI_Lob *lob_src 01191 ) 01192 { 01193 boolean res = TRUE; 01194 big_uint length = 0; 01195 01196 OCI_CHECK_PTR(OCI_IPC_LOB, lob, FALSE); 01197 OCI_CHECK_PTR(OCI_IPC_LOB, lob_src, FALSE); 01198 01199 /* 01200 this might cause an ORA-24805 on Oracle 8.1.x only ! 01201 I couldn’t find a bug ID on Metalink, but Oracle 9i had many fixes for 01202 lobs ! 01203 */ 01204 01205 OCI_CALL2 01206 ( 01207 res, lob->con, 01208 01209 OCILobAppend(lob->con->cxt, lob->con->err, lob->handle, lob_src->handle) 01210 ) 01211 01212 if (res == TRUE) 01213 { 01214 length = OCI_LobGetLength(lob); 01215 01216 lob->offset += length; 01217 } 01218 01219 OCI_RESULT(res); 01220 01221 return res; 01222 } 01223 01224 /* --------------------------------------------------------------------------------------------- * 01225 * OCI_LobIsTemporary 01226 * --------------------------------------------------------------------------------------------- */ 01227 01228 boolean OCI_API OCI_LobIsTemporary 01229 ( 01230 OCI_Lob *lob 01231 ) 01232 { 01233 boolean value = FALSE; 01234 boolean res = TRUE; 01235 01236 OCI_CHECK_PTR(OCI_IPC_LOB, lob, FALSE); 01237 01238 OCI_CALL2 01239 ( 01240 res, lob->con, 01241 01242 OCILobIsTemporary(lob->con->env, lob->con->err, lob->handle, &value) 01243 ) 01244 01245 OCI_RESULT(res); 01246 01247 return value; 01248 } 01249 01250 /* --------------------------------------------------------------------------------------------- * 01251 * OCI_LobOpen 01252 * --------------------------------------------------------------------------------------------- */ 01253 01254 boolean OCI_API OCI_LobOpen 01255 ( 01256 OCI_Lob *lob, 01257 unsigned int mode 01258 ) 01259 { 01260 boolean res = TRUE; 01261 01262 OCI_CHECK_PTR(OCI_IPC_LOB, lob, FALSE); 01263 01264 OCI_CALL2 01265 ( 01266 res, lob->con, 01267 01268 OCILobOpen(lob->con->cxt, lob->con->err, lob->handle, (ub1) mode) 01269 ) 01270 01271 OCI_RESULT(res); 01272 01273 return res; 01274 } 01275 01276 /* --------------------------------------------------------------------------------------------- * 01277 * OCI_LobClose 01278 * --------------------------------------------------------------------------------------------- */ 01279 01280 boolean OCI_API OCI_LobClose 01281 ( 01282 OCI_Lob *lob 01283 ) 01284 { 01285 boolean res = TRUE; 01286 01287 OCI_CHECK_PTR(OCI_IPC_LOB, lob, FALSE); 01288 01289 OCI_CALL2 01290 ( 01291 res, lob->con, 01292 01293 OCILobClose(lob->con->cxt, lob->con->err, lob->handle) 01294 ) 01295 01296 OCI_RESULT(res); 01297 01298 return res; 01299 } 01300 01301 /* --------------------------------------------------------------------------------------------- * 01302 * OCI_LobIsEqual 01303 * --------------------------------------------------------------------------------------------- */ 01304 01305 boolean OCI_API OCI_LobIsEqual 01306 ( 01307 OCI_Lob *lob, 01308 OCI_Lob *lob2 01309 ) 01310 { 01311 boolean value = FALSE; 01312 boolean res = TRUE; 01313 01314 OCI_CHECK_PTR(OCI_IPC_LOB, lob,FALSE); 01315 OCI_CHECK_PTR(OCI_IPC_LOB, lob2, FALSE); 01316 01317 OCI_CALL2 01318 ( 01319 res, lob->con, 01320 01321 OCILobIsEqual(lob->con->env, lob->handle, lob2->handle, &value) 01322 ) 01323 01324 OCI_RESULT(res); 01325 01326 return value; 01327 } 01328 01329 /* --------------------------------------------------------------------------------------------- * 01330 * OCI_LobAssign 01331 * --------------------------------------------------------------------------------------------- */ 01332 01333 boolean OCI_API OCI_LobAssign 01334 ( 01335 OCI_Lob *lob, 01336 OCI_Lob *lob_src 01337 ) 01338 { 01339 boolean res = TRUE; 01340 01341 OCI_CHECK_PTR(OCI_IPC_LOB, lob, FALSE); 01342 OCI_CHECK_PTR(OCI_IPC_LOB, lob_src, FALSE); 01343 01344 if ((lob->hstate == OCI_OBJECT_ALLOCATED) || (lob->hstate == OCI_OBJECT_ALLOCATED_ARRAY)) 01345 { 01346 OCI_CALL2 01347 ( 01348 res, lob->con, 01349 01350 OCILobLocatorAssign(lob->con->cxt, lob->con->err, lob_src->handle, &lob->handle) 01351 ) 01352 } 01353 else 01354 { 01355 OCI_CALL2 01356 ( 01357 res, lob->con, 01358 01359 OCILobAssign(lob->con->env, lob->con->err, lob_src->handle, &lob->handle) 01360 ) 01361 } 01362 01363 OCI_RESULT(res); 01364 01365 return res; 01366 } 01367 01368 /* --------------------------------------------------------------------------------------------- * 01369 * OCI_LobGetMaxSize 01370 * --------------------------------------------------------------------------------------------- */ 01371 01372 big_uint OCI_API OCI_LobGetMaxSize 01373 ( 01374 OCI_Lob *lob 01375 ) 01376 { 01377 boolean res = TRUE; 01378 big_uint size = 0; 01379 01380 OCI_CHECK_PTR(OCI_IPC_LOB, lob, 0); 01381 01382 #ifdef OCI_LOB2_API_ENABLED 01383 01384 if (OCILib.use_lob_ub8) 01385 { 01386 OCI_CALL2 01387 ( 01388 res, lob->con, 01389 01390 OCILobGetStorageLimit(lob->con->cxt, lob->con->err, lob->handle, (ub8 *) &size) 01391 ) 01392 } 01393 01394 #endif 01395 01396 OCI_RESULT(res); 01397 01398 return size; 01399 } 01400 01401 /* --------------------------------------------------------------------------------------------- * 01402 * OCI_LobFlush 01403 * --------------------------------------------------------------------------------------------- */ 01404 01405 boolean OCI_API OCI_LobFlush 01406 ( 01407 OCI_Lob *lob 01408 ) 01409 { 01410 boolean res = TRUE; 01411 01412 OCI_CHECK_PTR(OCI_IPC_LOB, lob, FALSE); 01413 01414 OCI_CALL2 01415 ( 01416 res, lob->con, 01417 01418 OCILobFlushBuffer(lob->con->cxt, lob->con->err, lob->handle, (ub4) OCI_DEFAULT) 01419 ) 01420 01421 OCI_RESULT(res); 01422 01423 return res; 01424 } 01425 01426 /* --------------------------------------------------------------------------------------------- * 01427 * OCI_LobEnableBuffering 01428 * --------------------------------------------------------------------------------------------- */ 01429 01430 boolean OCI_API OCI_LobEnableBuffering 01431 ( 01432 OCI_Lob *lob, 01433 boolean value 01434 ) 01435 { 01436 boolean res = TRUE; 01437 01438 OCI_CHECK_PTR(OCI_IPC_LOB, lob, FALSE); 01439 01440 if (value == TRUE) 01441 { 01442 OCI_CALL2 01443 ( 01444 res, lob->con, 01445 01446 OCILobEnableBuffering(lob->con->cxt, lob->con->err, lob->handle) 01447 ) 01448 } 01449 else 01450 { 01451 OCI_CALL2 01452 ( 01453 res, lob->con, 01454 01455 OCILobDisableBuffering(lob->con->cxt, lob->con->err, lob->handle) 01456 ) 01457 } 01458 01459 OCI_RESULT(res); 01460 01461 return res; 01462 } 01463