OCILIB (C Driver for Oracle) 3.12.1
|
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-2013 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, 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 OCI_Lob * lob = NULL; 00054 boolean res = TRUE; 00055 00056 OCI_CHECK(plob == NULL, NULL); 00057 00058 if (*plob == NULL) 00059 { 00060 *plob = (OCI_Lob *) OCI_MemAlloc(OCI_IPC_LOB, sizeof(*lob), (size_t) 1, TRUE); 00061 } 00062 00063 if (*plob != NULL) 00064 { 00065 lob = *plob; 00066 00067 lob->type = type; 00068 lob->con = con; 00069 lob->handle = handle; 00070 lob->offset = 1; 00071 00072 if ((lob->handle == NULL) || (lob->hstate == OCI_OBJECT_ALLOCATED_ARRAY)) 00073 { 00074 ub2 csid = OCI_DEFAULT; 00075 ub1 csfrm = OCI_DEFAULT; 00076 ub1 lobtype = 0; 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 ub1 csfrm = 0; 00338 ub2 csid = 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 ub4 ora_byte_count = (ub4) *byte_count; 00432 00433 if (OCILib.nls_utf8 == FALSE) 00434 { 00435 ora_byte_count *= sizeof(odtext); 00436 } 00437 00438 memset(((char *) buffer) + ora_byte_count, 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 (*byte_count) = (ub4) (*char_count) * (ub4) sizeof(dtext); 00466 } 00467 } 00468 } 00469 00470 OCI_RESULT(res); 00471 00472 return res; 00473 } 00474 00475 /* --------------------------------------------------------------------------------------------- * 00476 * OCI_LobRead 00477 * --------------------------------------------------------------------------------------------- */ 00478 00479 unsigned int OCI_API OCI_LobRead 00480 ( 00481 OCI_Lob *lob, 00482 void *buffer, 00483 unsigned int len 00484 ) 00485 { 00486 unsigned int char_count = 0; 00487 unsigned int byte_count = 0; 00488 unsigned int *ptr_count = NULL; 00489 00490 if (lob != NULL) 00491 { 00492 if(lob->type == OCI_BLOB) 00493 { 00494 byte_count = len; 00495 ptr_count = &byte_count; 00496 } 00497 else 00498 { 00499 char_count = len; 00500 ptr_count = &char_count; 00501 } 00502 } 00503 00504 OCI_LobRead2(lob, buffer, &char_count, &byte_count); 00505 00506 return (ptr_count != NULL ? *ptr_count : 0); 00507 } 00508 00509 /* --------------------------------------------------------------------------------------------- * 00510 * OCI_LobWrite 00511 * --------------------------------------------------------------------------------------------- */ 00512 00513 boolean OCI_API OCI_LobWrite2 00514 ( 00515 OCI_Lob *lob, 00516 void *buffer, 00517 unsigned int *char_count, 00518 unsigned int *byte_count 00519 ) 00520 { 00521 boolean res = TRUE; 00522 ub1 csfrm = 0; 00523 ub2 csid = 0; 00524 void *obuf = NULL; 00525 00526 OCI_CHECK_PTR(OCI_IPC_LOB, char_count, FALSE); 00527 OCI_CHECK_PTR(OCI_IPC_LOB, byte_count, FALSE); 00528 00529 if (lob->type != OCI_BLOB) 00530 { 00531 00532 #ifdef OCI_USERDATA_WIDE 00533 00534 csid = OCI_UTF16ID; 00535 00536 #endif 00537 00538 if (((*byte_count) == 0) && ((*char_count) > 0)) 00539 { 00540 if (OCILib.nls_utf8 == TRUE) 00541 { 00542 (*byte_count) = (unsigned int) strlen(buffer); 00543 } 00544 else 00545 { 00546 (*byte_count) = (*char_count) * (ub4) sizeof(dtext); 00547 } 00548 } 00549 00550 if (((*char_count) == 0) && ((*byte_count) > 0)) 00551 { 00552 if (OCILib.nls_utf8 == TRUE) 00553 { 00554 00555 #ifndef OCI_LOB2_API_ENABLED 00556 00557 (*char_count) = OCI_StringUTF8Length((const char *) buffer); 00558 00559 #endif 00560 00561 } 00562 else 00563 { 00564 (*char_count) = (*byte_count) / (ub4) sizeof(dtext); 00565 } 00566 } 00567 00568 obuf = OCI_GetInputDataString(buffer, (int *) byte_count); 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 (*char_count) = (ub4) size_in_out_char_byte; 00637 (*byte_count) = (ub4) size_in_out_char_byte; 00638 } 00639 else 00640 { 00641 (*char_count) = (ub4) size_in_out_char_byte; 00642 (*byte_count) = (ub4) size_in_out_char_byte; 00643 00644 if (OCILib.nls_utf8 == FALSE) 00645 { 00646 (*byte_count) *= (ub4) sizeof(dtext); 00647 } 00648 } 00649 } 00650 00651 if (res == TRUE) 00652 { 00653 if (lob->type == OCI_BLOB) 00654 { 00655 lob->offset += (big_uint) (*byte_count); 00656 } 00657 else 00658 { 00659 lob->offset += (big_uint) (*char_count); 00660 00661 if (OCILib.nls_utf8 == FALSE) 00662 { 00663 OCI_ReleaseDataString(obuf); 00664 } 00665 } 00666 } 00667 00668 OCI_RESULT(res); 00669 00670 return res; 00671 } 00672 00673 /* --------------------------------------------------------------------------------------------- * 00674 * OCI_LobWrite 00675 * --------------------------------------------------------------------------------------------- */ 00676 00677 unsigned int OCI_API OCI_LobWrite 00678 ( 00679 OCI_Lob *lob, 00680 void *buffer, 00681 unsigned int len 00682 ) 00683 { 00684 unsigned int char_count = 0; 00685 unsigned int byte_count = 0; 00686 unsigned int *ptr_count = NULL; 00687 00688 if (lob != NULL) 00689 { 00690 if(lob->type == OCI_BLOB) 00691 { 00692 byte_count = len; 00693 ptr_count = &byte_count; 00694 } 00695 else 00696 { 00697 char_count = len; 00698 ptr_count = &char_count; 00699 } 00700 } 00701 00702 OCI_LobWrite2(lob, buffer, &char_count, &byte_count); 00703 00704 return (ptr_count != NULL ? *ptr_count : 0); 00705 } 00706 00707 /* --------------------------------------------------------------------------------------------- * 00708 * OCI_LobTruncate 00709 * --------------------------------------------------------------------------------------------- */ 00710 00711 boolean OCI_API OCI_LobTruncate 00712 ( 00713 OCI_Lob *lob, 00714 big_uint size 00715 ) 00716 { 00717 boolean res = TRUE; 00718 00719 OCI_CHECK_PTR(OCI_IPC_LOB, lob, FALSE); 00720 00721 #ifdef OCI_LOB2_API_ENABLED 00722 00723 if (OCILib.use_lob_ub8) 00724 { 00725 OCI_CALL2 00726 ( 00727 res, lob->con, 00728 00729 OCILobTrim2(lob->con->cxt, lob->con->err, lob->handle, (ub8) size) 00730 ) 00731 } 00732 else 00733 00734 #endif 00735 00736 { 00737 OCI_CALL2 00738 ( 00739 res, lob->con, 00740 00741 OCILobTrim(lob->con->cxt, lob->con->err, lob->handle, (ub4) size) 00742 ) 00743 } 00744 00745 OCI_RESULT(res); 00746 00747 return res; 00748 } 00749 00750 /* --------------------------------------------------------------------------------------------- * 00751 * OCI_LobErase 00752 * --------------------------------------------------------------------------------------------- */ 00753 00754 big_uint OCI_API OCI_LobErase 00755 ( 00756 OCI_Lob *lob, 00757 big_uint offset, 00758 big_uint size 00759 ) 00760 { 00761 boolean res = TRUE; 00762 00763 OCI_CHECK_PTR(OCI_IPC_LOB, lob, 0); 00764 OCI_CHECK_MIN(lob->con, NULL, size, 1, 0); 00765 00766 #ifdef OCI_LOB2_API_ENABLED 00767 00768 if (OCILib.use_lob_ub8) 00769 { 00770 ub8 lob_size = (ub8) size; 00771 00772 OCI_CALL2 00773 ( 00774 res, lob->con, 00775 00776 OCILobErase2(lob->con->cxt, lob->con->err, lob->handle, (ub8 *) &lob_size, (ub8) (offset + 1)) 00777 ) 00778 00779 size = (big_uint) lob_size; 00780 } 00781 else 00782 00783 #endif 00784 00785 { 00786 ub4 lob_size = (ub4) size; 00787 00788 OCI_CALL2 00789 ( 00790 res, lob->con, 00791 00792 OCILobErase(lob->con->cxt, lob->con->err, lob->handle, &lob_size, (ub4) offset + 1) 00793 ) 00794 00795 size = (big_uint) lob_size; 00796 } 00797 00798 OCI_RESULT(res); 00799 00800 return size; 00801 } 00802 00803 /* --------------------------------------------------------------------------------------------- * 00804 * OCI_LobGetLength 00805 * --------------------------------------------------------------------------------------------- */ 00806 00807 big_uint OCI_API OCI_LobGetLength 00808 ( 00809 OCI_Lob *lob 00810 ) 00811 { 00812 boolean res = TRUE; 00813 big_uint size = 0; 00814 00815 OCI_CHECK_PTR(OCI_IPC_LOB, lob, 0); 00816 00817 #ifdef OCI_LOB2_API_ENABLED 00818 00819 if (OCILib.use_lob_ub8) 00820 { 00821 ub8 lob_size = 0; 00822 00823 OCI_CALL2 00824 ( 00825 res, lob->con, 00826 00827 OCILobGetLength2(lob->con->cxt, lob->con->err, lob->handle, (ub8 *) &lob_size) 00828 ) 00829 00830 size = (big_uint) lob_size; 00831 } 00832 else 00833 00834 #endif 00835 00836 { 00837 ub4 lob_size = 0; 00838 00839 OCI_CALL2 00840 ( 00841 res, lob->con, 00842 00843 OCILobGetLength(lob->con->cxt, lob->con->err, lob->handle, &lob_size) 00844 ) 00845 00846 size = (big_uint) lob_size; 00847 } 00848 00849 OCI_RESULT(res); 00850 00851 return size; 00852 } 00853 00854 /* --------------------------------------------------------------------------------------------- * 00855 * OCI_LobGetChunkSize 00856 * --------------------------------------------------------------------------------------------- */ 00857 00858 unsigned int OCI_API OCI_LobGetChunkSize 00859 ( 00860 OCI_Lob *lob 00861 ) 00862 { 00863 boolean res = TRUE; 00864 ub4 size = 0; 00865 00866 OCI_CHECK_PTR(OCI_IPC_LOB, lob, 0); 00867 00868 OCI_CALL2 00869 ( 00870 res, lob->con, 00871 00872 OCILobGetChunkSize(lob->con->cxt, lob->con->err, lob->handle, &size) 00873 ) 00874 00875 OCI_RESULT(res); 00876 00877 return (unsigned int) size; 00878 } 00879 00880 /* --------------------------------------------------------------------------------------------- * 00881 * OCI_LobCopy 00882 * --------------------------------------------------------------------------------------------- */ 00883 00884 boolean OCI_API OCI_LobCopy 00885 ( 00886 OCI_Lob *lob, 00887 OCI_Lob *lob_src, 00888 big_uint offset_dst, 00889 big_uint offset_src, 00890 big_uint count 00891 ) 00892 { 00893 boolean res = TRUE; 00894 00895 OCI_CHECK_PTR(OCI_IPC_LOB, lob, FALSE); 00896 OCI_CHECK_PTR(OCI_IPC_LOB, lob_src, FALSE); 00897 00898 #ifdef OCI_LOB2_API_ENABLED 00899 00900 if (OCILib.use_lob_ub8) 00901 { 00902 00903 OCI_CALL2 00904 ( 00905 res, lob->con, 00906 00907 OCILobCopy2(lob->con->cxt, lob->con->err, lob->handle, 00908 lob_src->handle, (ub8) count, 00909 (ub8) (offset_dst + 1), 00910 (ub8) (offset_src + 1)) 00911 ) 00912 } 00913 else 00914 00915 #endif 00916 00917 { 00918 OCI_CALL2 00919 ( 00920 res, lob->con, 00921 00922 OCILobCopy(lob->con->cxt, lob->con->err, lob->handle, 00923 lob_src->handle, (ub4) count, 00924 (ub4) (offset_dst + 1), 00925 (ub4) (offset_src + 1)) 00926 ) 00927 } 00928 00929 OCI_RESULT(res); 00930 00931 return res; 00932 } 00933 00934 /* --------------------------------------------------------------------------------------------- * 00935 * OCI_LobCopyFromFile 00936 * --------------------------------------------------------------------------------------------- */ 00937 00938 boolean OCI_API OCI_LobCopyFromFile 00939 ( 00940 OCI_Lob *lob, 00941 OCI_File *file, 00942 big_uint offset_dst, 00943 big_uint offset_src, 00944 big_uint count 00945 ) 00946 { 00947 boolean res = TRUE; 00948 00949 OCI_CHECK_PTR(OCI_IPC_LOB, lob, FALSE); 00950 OCI_CHECK_PTR(OCI_IPC_FILE, file, FALSE); 00951 00952 #ifdef OCI_LOB2_API_ENABLED 00953 00954 if (OCILib.use_lob_ub8) 00955 { 00956 OCI_CALL2 00957 ( 00958 res, lob->con, 00959 00960 OCILobLoadFromFile2(lob->con->cxt, lob->con->err, 00961 lob->handle, file->handle, 00962 (ub8) count, 00963 (ub8) (offset_dst + 1), 00964 (ub8) (offset_src + 1)) 00965 ) 00966 } 00967 else 00968 00969 #endif 00970 00971 { 00972 OCI_CALL2 00973 ( 00974 res, lob->con, 00975 00976 OCILobLoadFromFile(lob->con->cxt, lob->con->err, 00977 lob->handle, file->handle, 00978 (ub4) count, 00979 (ub4) (offset_dst + 1), 00980 (ub4) (offset_src + 1)) 00981 ) 00982 } 00983 00984 OCI_RESULT(res); 00985 00986 return res; 00987 } 00988 00989 /* --------------------------------------------------------------------------------------------- * 00990 * OCI_LobAppend2 00991 * --------------------------------------------------------------------------------------------- */ 00992 00993 boolean OCI_API OCI_LobAppend2 00994 ( 00995 OCI_Lob *lob, 00996 void *buffer, 00997 unsigned int *char_count, 00998 unsigned int *byte_count 00999 ) 01000 { 01001 boolean res = TRUE; 01002 ub1 csfrm = 0; 01003 ub2 csid = 0; 01004 void *obuf = NULL; 01005 01006 OCI_CHECK_PTR(OCI_IPC_LOB, char_count, FALSE); 01007 OCI_CHECK_PTR(OCI_IPC_LOB, byte_count, FALSE); 01008 01009 /* OCILobWriteAppend() seems to cause problems on Oracle client 8.1 and 9.0 01010 It's an Oracle known bug #886191 01011 So we use OCI_LobSeek() + OCI_LobWrite() instead */ 01012 01013 if (OCILib.version_runtime < OCI_10_1) 01014 { 01015 return OCI_LobSeek(lob, OCI_LobGetLength(lob), OCI_SEEK_SET) && 01016 OCI_LobWrite2(lob, buffer, char_count, byte_count); 01017 } 01018 01019 if (lob->type != OCI_BLOB) 01020 { 01021 #ifdef OCI_USERDATA_WIDE 01022 01023 csid = OCI_UTF16ID; 01024 01025 #endif 01026 01027 if (((*byte_count) == 0) && ((*char_count) > 0)) 01028 { 01029 if (OCILib.nls_utf8 == TRUE) 01030 { 01031 (*byte_count) = (unsigned int) strlen(buffer); 01032 } 01033 else 01034 { 01035 (*byte_count) = (*char_count) * (ub4) sizeof(dtext); 01036 } 01037 } 01038 01039 if (((*char_count) == 0) && ((*byte_count) > 0)) 01040 { 01041 if (OCILib.nls_utf8 == TRUE) 01042 { 01043 01044 #ifndef OCI_LOB2_API_ENABLED 01045 01046 (*char_count) = OCI_StringUTF8Length((const char *) buffer); 01047 01048 #endif 01049 01050 } 01051 else 01052 { 01053 (*char_count) = (*byte_count) / (ub4) sizeof(dtext); 01054 } 01055 } 01056 01057 obuf = OCI_GetInputDataString(buffer, (int *) byte_count); 01058 } 01059 else 01060 { 01061 obuf = buffer; 01062 } 01063 01064 if (lob->type == OCI_NCLOB) 01065 { 01066 csfrm = SQLCS_NCHAR; 01067 } 01068 else 01069 { 01070 csfrm = SQLCS_IMPLICIT; 01071 } 01072 01073 OCI_CHECK_MIN(lob->con, NULL, (*byte_count), 1, FALSE); 01074 01075 #ifdef OCI_LOB2_API_ENABLED 01076 01077 if (OCILib.use_lob_ub8) 01078 { 01079 ub8 size_in_out_char = (ub8) (*char_count); 01080 ub8 size_in_out_byte = (ub8) (*byte_count); 01081 01082 OCI_CALL2 01083 ( 01084 res, lob->con, 01085 01086 OCILobWriteAppend2(lob->con->cxt, lob->con->err, lob->handle, 01087 &size_in_out_byte, &size_in_out_char, 01088 obuf, (ub8) (*byte_count), (ub1) OCI_ONE_PIECE, 01089 (dvoid *) NULL, NULL, csid, csfrm) 01090 ) 01091 01092 (*char_count) = (ub4) size_in_out_char; 01093 (*byte_count) = (ub4) size_in_out_byte; 01094 } 01095 01096 else 01097 01098 #endif 01099 01100 { 01101 ub4 size_in_out_char_byte = 0; 01102 01103 if ((lob->type == OCI_BLOB) || (OCILib.nls_utf8 == TRUE)) 01104 { 01105 size_in_out_char_byte = (*byte_count); 01106 } 01107 else 01108 { 01109 size_in_out_char_byte = (*char_count); 01110 } 01111 01112 OCI_CALL2 01113 ( 01114 res, lob->con, 01115 01116 OCILobWriteAppend(lob->con->cxt, lob->con->err, lob->handle, 01117 &size_in_out_char_byte, obuf, (*byte_count), 01118 (ub1) OCI_ONE_PIECE, (dvoid *) NULL, NULL, csid, csfrm) 01119 ) 01120 01121 if (lob->type == OCI_BLOB) 01122 { 01123 (*char_count) = (ub4) size_in_out_char_byte; 01124 (*byte_count) = (ub4) size_in_out_char_byte; 01125 } 01126 else 01127 { 01128 (*char_count) = (ub4) size_in_out_char_byte; 01129 (*byte_count) = (ub4) size_in_out_char_byte; 01130 01131 if (OCILib.nls_utf8 == FALSE) 01132 { 01133 (*byte_count) *= (ub4) sizeof(dtext); 01134 } 01135 } 01136 } 01137 01138 if (res == TRUE) 01139 { 01140 if (lob->type == OCI_BLOB) 01141 { 01142 lob->offset += (big_uint) (*byte_count); 01143 } 01144 else 01145 { 01146 lob->offset += (big_uint) (*char_count); 01147 01148 if (OCILib.nls_utf8 == FALSE) 01149 { 01150 OCI_ReleaseDataString(obuf); 01151 } 01152 } 01153 } 01154 01155 OCI_RESULT(res); 01156 01157 return res; 01158 } 01159 01160 /* --------------------------------------------------------------------------------------------- * 01161 * OCI_LobAppend 01162 * --------------------------------------------------------------------------------------------- */ 01163 01164 unsigned int OCI_API OCI_LobAppend 01165 ( 01166 OCI_Lob *lob, 01167 void *buffer, 01168 unsigned int len 01169 ) 01170 { 01171 unsigned int char_count = 0; 01172 unsigned int byte_count = 0; 01173 unsigned int *ptr_count = NULL; 01174 01175 if (lob != NULL) 01176 { 01177 if(lob->type == OCI_BLOB) 01178 { 01179 byte_count = len; 01180 ptr_count = &byte_count; 01181 } 01182 else 01183 { 01184 char_count = len; 01185 ptr_count = &char_count; 01186 } 01187 } 01188 01189 OCI_LobAppend2(lob, buffer, &char_count, &byte_count); 01190 01191 return (ptr_count != NULL ? *ptr_count : 0); 01192 } 01193 01194 /* --------------------------------------------------------------------------------------------- * 01195 * OCI_LobAppendLob 01196 * --------------------------------------------------------------------------------------------- */ 01197 01198 boolean OCI_API OCI_LobAppendLob 01199 ( 01200 OCI_Lob *lob, 01201 OCI_Lob *lob_src 01202 ) 01203 { 01204 boolean res = TRUE; 01205 01206 OCI_CHECK_PTR(OCI_IPC_LOB, lob, FALSE); 01207 OCI_CHECK_PTR(OCI_IPC_LOB, lob_src, FALSE); 01208 01209 /* 01210 this might cause an ORA-24805 on Oracle 8.1.x only ! 01211 I couldn’t find a bug ID on Metalink, but Oracle 9i had many fixes for 01212 lobs ! 01213 */ 01214 01215 OCI_CALL2 01216 ( 01217 res, lob->con, 01218 01219 OCILobAppend(lob->con->cxt, lob->con->err, lob->handle, lob_src->handle) 01220 ) 01221 01222 if (res == TRUE) 01223 { 01224 lob->offset += OCI_LobGetLength(lob); 01225 } 01226 01227 OCI_RESULT(res); 01228 01229 return res; 01230 } 01231 01232 /* --------------------------------------------------------------------------------------------- * 01233 * OCI_LobIsTemporary 01234 * --------------------------------------------------------------------------------------------- */ 01235 01236 boolean OCI_API OCI_LobIsTemporary 01237 ( 01238 OCI_Lob *lob 01239 ) 01240 { 01241 boolean value = FALSE; 01242 boolean res = TRUE; 01243 01244 OCI_CHECK_PTR(OCI_IPC_LOB, lob, FALSE); 01245 01246 OCI_CALL2 01247 ( 01248 res, lob->con, 01249 01250 OCILobIsTemporary(lob->con->env, lob->con->err, lob->handle, &value) 01251 ) 01252 01253 OCI_RESULT(res); 01254 01255 return value; 01256 } 01257 01258 /* --------------------------------------------------------------------------------------------- * 01259 * OCI_LobOpen 01260 * --------------------------------------------------------------------------------------------- */ 01261 01262 boolean OCI_API OCI_LobOpen 01263 ( 01264 OCI_Lob *lob, 01265 unsigned int mode 01266 ) 01267 { 01268 boolean res = TRUE; 01269 01270 OCI_CHECK_PTR(OCI_IPC_LOB, lob, FALSE); 01271 01272 OCI_CALL2 01273 ( 01274 res, lob->con, 01275 01276 OCILobOpen(lob->con->cxt, lob->con->err, lob->handle, (ub1) mode) 01277 ) 01278 01279 OCI_RESULT(res); 01280 01281 return res; 01282 } 01283 01284 /* --------------------------------------------------------------------------------------------- * 01285 * OCI_LobClose 01286 * --------------------------------------------------------------------------------------------- */ 01287 01288 boolean OCI_API OCI_LobClose 01289 ( 01290 OCI_Lob *lob 01291 ) 01292 { 01293 boolean res = TRUE; 01294 01295 OCI_CHECK_PTR(OCI_IPC_LOB, lob, FALSE); 01296 01297 OCI_CALL2 01298 ( 01299 res, lob->con, 01300 01301 OCILobClose(lob->con->cxt, lob->con->err, lob->handle) 01302 ) 01303 01304 OCI_RESULT(res); 01305 01306 return res; 01307 } 01308 01309 /* --------------------------------------------------------------------------------------------- * 01310 * OCI_LobIsEqual 01311 * --------------------------------------------------------------------------------------------- */ 01312 01313 boolean OCI_API OCI_LobIsEqual 01314 ( 01315 OCI_Lob *lob, 01316 OCI_Lob *lob2 01317 ) 01318 { 01319 boolean value = FALSE; 01320 boolean res = TRUE; 01321 01322 OCI_CHECK_PTR(OCI_IPC_LOB, lob,FALSE); 01323 OCI_CHECK_PTR(OCI_IPC_LOB, lob2, FALSE); 01324 01325 OCI_CALL2 01326 ( 01327 res, lob->con, 01328 01329 OCILobIsEqual(lob->con->env, lob->handle, lob2->handle, &value) 01330 ) 01331 01332 OCI_RESULT(res); 01333 01334 return value; 01335 } 01336 01337 /* --------------------------------------------------------------------------------------------- * 01338 * OCI_LobAssign 01339 * --------------------------------------------------------------------------------------------- */ 01340 01341 boolean OCI_API OCI_LobAssign 01342 ( 01343 OCI_Lob *lob, 01344 OCI_Lob *lob_src 01345 ) 01346 { 01347 boolean res = TRUE; 01348 01349 OCI_CHECK_PTR(OCI_IPC_LOB, lob, FALSE); 01350 OCI_CHECK_PTR(OCI_IPC_LOB, lob_src, FALSE); 01351 01352 if ((lob->hstate == OCI_OBJECT_ALLOCATED) || (lob->hstate == OCI_OBJECT_ALLOCATED_ARRAY)) 01353 { 01354 OCI_CALL2 01355 ( 01356 res, lob->con, 01357 01358 OCILobLocatorAssign(lob->con->cxt, lob->con->err, lob_src->handle, &lob->handle) 01359 ) 01360 } 01361 else 01362 { 01363 OCI_CALL2 01364 ( 01365 res, lob->con, 01366 01367 OCILobAssign(lob->con->env, lob->con->err, lob_src->handle, &lob->handle) 01368 ) 01369 } 01370 01371 OCI_RESULT(res); 01372 01373 return res; 01374 } 01375 01376 /* --------------------------------------------------------------------------------------------- * 01377 * OCI_LobGetMaxSize 01378 * --------------------------------------------------------------------------------------------- */ 01379 01380 big_uint OCI_API OCI_LobGetMaxSize 01381 ( 01382 OCI_Lob *lob 01383 ) 01384 { 01385 boolean res = TRUE; 01386 big_uint size = 0; 01387 01388 OCI_CHECK_PTR(OCI_IPC_LOB, lob, 0); 01389 01390 #ifdef OCI_LOB2_API_ENABLED 01391 01392 if (OCILib.use_lob_ub8) 01393 { 01394 OCI_CALL2 01395 ( 01396 res, lob->con, 01397 01398 OCILobGetStorageLimit(lob->con->cxt, lob->con->err, lob->handle, (ub8 *) &size) 01399 ) 01400 } 01401 01402 #endif 01403 01404 OCI_RESULT(res); 01405 01406 return size; 01407 } 01408 01409 /* --------------------------------------------------------------------------------------------- * 01410 * OCI_LobFlush 01411 * --------------------------------------------------------------------------------------------- */ 01412 01413 boolean OCI_API OCI_LobFlush 01414 ( 01415 OCI_Lob *lob 01416 ) 01417 { 01418 boolean res = TRUE; 01419 01420 OCI_CHECK_PTR(OCI_IPC_LOB, lob, FALSE); 01421 01422 OCI_CALL2 01423 ( 01424 res, lob->con, 01425 01426 OCILobFlushBuffer(lob->con->cxt, lob->con->err, lob->handle, (ub4) OCI_DEFAULT) 01427 ) 01428 01429 OCI_RESULT(res); 01430 01431 return res; 01432 } 01433 01434 /* --------------------------------------------------------------------------------------------- * 01435 * OCI_LobEnableBuffering 01436 * --------------------------------------------------------------------------------------------- */ 01437 01438 boolean OCI_API OCI_LobEnableBuffering 01439 ( 01440 OCI_Lob *lob, 01441 boolean value 01442 ) 01443 { 01444 boolean res = TRUE; 01445 01446 OCI_CHECK_PTR(OCI_IPC_LOB, lob, FALSE); 01447 01448 if (value == TRUE) 01449 { 01450 OCI_CALL2 01451 ( 01452 res, lob->con, 01453 01454 OCILobEnableBuffering(lob->con->cxt, lob->con->err, lob->handle) 01455 ) 01456 } 01457 else 01458 { 01459 OCI_CALL2 01460 ( 01461 res, lob->con, 01462 01463 OCILobDisableBuffering(lob->con->cxt, lob->con->err, lob->handle) 01464 ) 01465 } 01466 01467 OCI_RESULT(res); 01468 01469 return res; 01470 } 01471