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: long.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_LongInit 00043 * --------------------------------------------------------------------------------------------- */ 00044 00045 OCI_Long * OCI_LongInit 00046 ( 00047 OCI_Statement *stmt, 00048 OCI_Long **plg, 00049 OCI_Define *def, 00050 unsigned int type 00051 ) 00052 { 00053 boolean res = TRUE; 00054 OCI_Long *lg = NULL; 00055 00056 OCI_CHECK(plg == NULL, NULL); 00057 00058 if (*plg == NULL) 00059 { 00060 *plg = (OCI_Long *) OCI_MemAlloc(OCI_IPC_LONG, sizeof(*lg), (size_t) 1, TRUE); 00061 } 00062 00063 if (*plg != NULL) 00064 { 00065 lg = *plg; 00066 00067 lg->size = 0; 00068 lg->stmt = stmt; 00069 lg->def = def; 00070 lg->type = type; 00071 lg->offset = 0; 00072 00073 if (def != NULL) 00074 { 00075 lg->hstate = OCI_OBJECT_FETCHED_CLEAN; 00076 } 00077 else if (lg->hstate != OCI_OBJECT_ALLOCATED_ARRAY) 00078 { 00079 lg->hstate = OCI_OBJECT_ALLOCATED; 00080 } 00081 } 00082 else 00083 { 00084 res = FALSE; 00085 } 00086 00087 OCI_RESULT(res); 00088 00089 return lg; 00090 } 00091 00092 /* ********************************************************************************************* * 00093 * PUBLIC FUNCTIONS 00094 * ********************************************************************************************* */ 00095 00096 /* --------------------------------------------------------------------------------------------- * 00097 * OCI_LongCreate 00098 * --------------------------------------------------------------------------------------------- */ 00099 00100 OCI_Long * OCI_API OCI_LongCreate 00101 ( 00102 OCI_Statement *stmt, 00103 unsigned int type 00104 ) 00105 { 00106 OCI_Long *lg = NULL; 00107 00108 OCI_CHECK_INITIALIZED(NULL); 00109 00110 OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, NULL); 00111 00112 lg = OCI_LongInit(stmt, &lg, NULL, type); 00113 00114 OCI_RESULT(lg != NULL); 00115 00116 return lg; 00117 } 00118 00119 /* --------------------------------------------------------------------------------------------- * 00120 * OCI_LongFree 00121 * --------------------------------------------------------------------------------------------- */ 00122 00123 boolean OCI_API OCI_LongFree 00124 ( 00125 OCI_Long *lg 00126 ) 00127 { 00128 OCI_CHECK_PTR(OCI_IPC_LONG, lg, FALSE); 00129 00130 OCI_CHECK_OBJECT_FETCHED(lg, FALSE); 00131 00132 OCI_FREE(lg->buffer); 00133 OCI_FREE(lg); 00134 00135 OCI_RESULT(TRUE); 00136 00137 return TRUE; 00138 } 00139 00140 /* --------------------------------------------------------------------------------------------- * 00141 * OCI_LongGetType 00142 * --------------------------------------------------------------------------------------------- */ 00143 00144 unsigned int OCI_API OCI_LongGetType 00145 ( 00146 OCI_Long *lg 00147 ) 00148 { 00149 OCI_CHECK_PTR(OCI_IPC_LONG, lg, OCI_UNKNOWN); 00150 00151 OCI_RESULT(TRUE); 00152 00153 return lg->type; 00154 } 00155 00156 /* --------------------------------------------------------------------------------------------- * 00157 * OCI_LongRead 00158 * --------------------------------------------------------------------------------------------- */ 00159 00160 unsigned int OCI_API OCI_LongRead 00161 ( 00162 OCI_Long *lg, 00163 void *buffer, 00164 unsigned int len 00165 ) 00166 { 00167 unsigned int size = len; 00168 unsigned int fact = 1; 00169 00170 OCI_CHECK_PTR(OCI_IPC_LONG, lg, 0); 00171 OCI_CHECK_PTR(OCI_IPC_VOID, buffer, 0); 00172 00173 OCI_CHECK_MIN(lg->stmt->con, lg->stmt, size, 1, 0); 00174 00175 OCI_CHECK(lg->offset >= lg->size, 0); 00176 00177 /* lg->size and lg offset are still expressed in odtext units even 00178 if the buffer had already been expanded to dtext * 00179 */ 00180 00181 if (lg->type == OCI_CLONG) 00182 { 00183 len *= (unsigned int) sizeof(odtext); 00184 } 00185 00186 /* check buffer size to read */ 00187 00188 if ((size + lg->offset) > lg->size) 00189 { 00190 size = lg->size - lg->offset; 00191 } 00192 00193 /* copy buffer */ 00194 00195 memcpy(buffer, lg->buffer + (size_t) lg->offset*fact, (size_t) (size*fact)); 00196 00197 lg->offset += size; 00198 00199 if (lg->type == OCI_CLONG) 00200 { 00201 ((dtext *) buffer)[size] = 0; 00202 00203 size /= (unsigned int) sizeof(dtext); 00204 } 00205 00206 OCI_RESULT(TRUE); 00207 00208 return size; 00209 } 00210 00211 /* --------------------------------------------------------------------------------------------- * 00212 * OCI_LongWrite 00213 * --------------------------------------------------------------------------------------------- */ 00214 00215 unsigned int OCI_API OCI_LongWrite 00216 ( 00217 OCI_Long *lg, 00218 void *buffer, 00219 unsigned int len 00220 ) 00221 { 00222 boolean res = TRUE; 00223 sword code = OCI_SUCCESS; 00224 void *obuf = NULL; 00225 void *handle = NULL; 00226 ub1 in_out = OCI_PARAM_IN; 00227 ub1 piece = OCI_ONE_PIECE; 00228 ub4 type = 0; 00229 ub4 iter = 0; 00230 ub4 dx = 0; 00231 ub4 count = 0; 00232 00233 OCI_CHECK_PTR(OCI_IPC_VOID, buffer, 0); 00234 OCI_CHECK_PTR(OCI_IPC_LONG, lg, 0); 00235 00236 OCI_CHECK_MIN(lg->stmt->con, lg->stmt, len, 1, 0); 00237 00238 if (lg->type == OCI_CLONG) 00239 { 00240 len *= (unsigned int) sizeof(dtext); 00241 } 00242 00243 if (lg->type == OCI_CLONG) 00244 { 00245 obuf = OCI_GetInputDataString(buffer, (int *) &len); 00246 } 00247 else 00248 { 00249 obuf = buffer; 00250 } 00251 00252 /* get piece info */ 00253 00254 OCI_CALL1 00255 ( 00256 res, lg->stmt->con, lg->stmt, 00257 00258 OCIStmtGetPieceInfo(lg->stmt->stmt, lg->stmt->con->err, &handle, 00259 &type, &in_out, &iter, &dx, &piece) 00260 ) 00261 00262 /* set up piece type */ 00263 00264 if (len > 0) 00265 { 00266 piece = (ub1) ((lg->size > 0) ? OCI_NEXT_PIECE : OCI_FIRST_PIECE); 00267 } 00268 else 00269 { 00270 piece = (ub1) OCI_LAST_PIECE; 00271 } 00272 00273 /* correct size to read for last piece */ 00274 00275 if ((lg->size + len) >= lg->stmt->long_size) 00276 { 00277 piece = OCI_LAST_PIECE; 00278 count = lg->stmt->long_size - lg->size; 00279 } 00280 else 00281 { 00282 count = len; 00283 } 00284 00285 /* set up info for writing */ 00286 00287 OCI_CALL1 00288 ( 00289 res, lg->stmt->con, lg->stmt, 00290 00291 OCIStmtSetPieceInfo(handle, type, lg->stmt->con->err, (dvoid *) obuf, 00292 &count, piece, (dvoid *) NULL, (ub2 *) NULL) 00293 ) 00294 00295 /* perform write call */ 00296 00297 if (res == TRUE) 00298 { 00299 code = OCIStmtExecute(lg->stmt->con->cxt, lg->stmt->stmt, 00300 lg->stmt->con->err, (ub4) 1, (ub4) 0, 00301 (OCISnapshot *) NULL, (OCISnapshot *) NULL, 00302 (ub4) 0); 00303 } 00304 00305 if ((code != OCI_SUCCESS) && (code != OCI_NEED_DATA)) 00306 { 00307 if (code == OCI_SUCCESS_WITH_INFO) 00308 { 00309 OCI_ExceptionOCI(lg->stmt->con->err, lg->stmt->con, lg->stmt, TRUE); 00310 } 00311 else 00312 { 00313 OCI_ExceptionOCI(lg->stmt->con->err, lg->stmt->con, lg->stmt, FALSE); 00314 res = FALSE; 00315 } 00316 } 00317 00318 if (lg->type == OCI_CLONG) 00319 { 00320 OCI_ReleaseDataString(obuf); 00321 } 00322 00323 /* update size */ 00324 00325 if (res == TRUE) 00326 { 00327 lg->size += count; 00328 00329 /* at this point, count is expressed in odtext bytes for character LONGs 00330 **/ 00331 00332 if (lg->type == OCI_CLONG) 00333 { 00334 count /= (unsigned int) sizeof(odtext); 00335 } 00336 00337 } 00338 00339 OCI_RESULT(res); 00340 00341 return count; 00342 } 00343 00344 /* --------------------------------------------------------------------------------------------- * 00345 * OCI_LongGetSize 00346 * --------------------------------------------------------------------------------------------- */ 00347 00348 unsigned int OCI_API OCI_LongGetSize 00349 ( 00350 OCI_Long *lg 00351 ) 00352 { 00353 unsigned int size = 0; 00354 00355 OCI_CHECK_PTR(OCI_IPC_LONG, lg, 0); 00356 00357 size = lg->size; 00358 00359 if (lg->type == OCI_CLONG) 00360 { 00361 size /= (unsigned int) sizeof(odtext); 00362 } 00363 00364 OCI_RESULT(TRUE); 00365 00366 return size; 00367 } 00368 00369 /* --------------------------------------------------------------------------------------------- * 00370 * OCI_LongGetBuffer 00371 * --------------------------------------------------------------------------------------------- */ 00372 00373 void * OCI_API OCI_LongGetBuffer 00374 ( 00375 OCI_Long *lg 00376 ) 00377 { 00378 OCI_CHECK_PTR(OCI_IPC_LONG, lg, NULL); 00379 00380 OCI_RESULT(TRUE); 00381 00382 return (void *) lg->buffer; 00383 }