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