• Main Page
  • Modules
  • Data Structures
  • Files
  • File List

D:/Perso/dev/ocilib/ocilib/src/define.c

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-2010 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: define.c, v 3.8.0 2010-10-24 21:53 Vincent Rogier $
00033  * --------------------------------------------------------------------------------------------- */
00034 
00035 #include "ocilib_internal.h"
00036 
00037 /* ********************************************************************************************* *
00038  *                             PRIVATE FUNCTIONS
00039  * ********************************************************************************************* */
00040 
00041 /* --------------------------------------------------------------------------------------------- *
00042  * OCI_GetDefine
00043  * --------------------------------------------------------------------------------------------- */
00044 
00045 OCI_Define * OCI_GetDefine
00046 (
00047     OCI_Resultset *rs,
00048     unsigned int   index
00049 )
00050 {
00051     OCI_CHECK_PTR(OCI_IPC_RESULTSET, rs, NULL);
00052     OCI_CHECK_BOUND(rs->stmt->con, index,  1,  rs->nb_defs, NULL);
00053 
00054     return &rs->defs[index-1];
00055 }
00056 
00057 /* --------------------------------------------------------------------------------------------- *
00058  * OCI_GetDefineIndex
00059  * --------------------------------------------------------------------------------------------- */
00060 
00061 int OCI_GetDefineIndex
00062 (
00063     OCI_Resultset *rs,
00064     const mtext   *name
00065 )
00066 {
00067     OCI_HashEntry *he = NULL;
00068     int index         = -1;
00069 
00070     OCI_CHECK_PTR(OCI_IPC_RESULTSET, rs, -1);
00071     OCI_CHECK_PTR(OCI_IPC_STRING, name, -1);
00072 
00073     if (rs->map == NULL)
00074     {
00075         /* create the map at the first call to OCI_Getxxxxx2() to save
00076            time and memory when it's not needed */
00077 
00078         rs->map = OCI_HashCreate(OCI_HASH_DEFAULT_SIZE, OCI_HASH_INTEGER);
00079 
00080         if (rs->map != NULL)
00081         {
00082             ub4 i;
00083 
00084             for (i = 0; i < rs->nb_defs; i++)
00085             {
00086                 OCI_HashAddInt(rs->map, rs->defs[i].col.name, (i+1));
00087             }
00088         }
00089     }
00090 
00091     /* check out we got our map object */
00092 
00093     OCI_CHECK(rs->map == NULL, -1);
00094 
00095     he = OCI_HashLookup(rs->map, name, FALSE);
00096 
00097     while (he != NULL)
00098     {
00099         /* no more entries or key matched => so we got it ! */
00100 
00101         if (he->next == NULL || mtscasecmp(he->key, name) == 0)
00102         {
00103             index = he->values->value.num;
00104             break;
00105         }
00106     }
00107 
00108     return index;
00109 }
00110 
00111 /* --------------------------------------------------------------------------------------------- *
00112  * OCI_DefineGetData
00113  * --------------------------------------------------------------------------------------------- */
00114 
00115 void * OCI_DefineGetData
00116 (
00117     OCI_Define *def
00118 )
00119 {
00120     OCI_CHECK(def == NULL, NULL);
00121     OCI_CHECK(def->rs->row_cur < 1, NULL);
00122 
00123     switch (def->col.type)
00124     {
00125     case OCI_CDT_LONG:
00126     case OCI_CDT_CURSOR:
00127     case OCI_CDT_TIMESTAMP:
00128     case OCI_CDT_INTERVAL:
00129     case OCI_CDT_LOB:
00130     case OCI_CDT_FILE:
00131     case OCI_CDT_OBJECT:
00132     case OCI_CDT_COLLECTION:
00133     case OCI_CDT_REF:
00134 
00135         /* handle based types */
00136 
00137         return def->buf.data[def->rs->row_cur-1];
00138 
00139     default:
00140 
00141         /* scalar types */
00142 
00143         return (((ub1  *) (def->buf.data)) +
00144                 (size_t) (def->col.bufsize * (def->rs->row_cur-1)));
00145     }
00146 }
00147 
00148 /* --------------------------------------------------------------------------------------------- *
00149  * OCI_DefineGetNumber
00150  * --------------------------------------------------------------------------------------------- */
00151 
00152 boolean OCI_DefineGetNumber
00153 (
00154     OCI_Resultset *rs,
00155     unsigned int   index,
00156     void          *value,
00157     uword          type,
00158     uword          size
00159 )
00160 {
00161     OCI_Define *def = OCI_GetDefine(rs, index);
00162     boolean res     = FALSE;
00163 
00164     if (OCI_NOT_NULL(def) == TRUE)
00165     {
00166         void *data = OCI_DefineGetData(def);
00167 
00168         switch (def->col.type)
00169         {
00170         case OCI_CDT_NUMERIC:
00171         {
00172             res = OCI_NumberGet(rs->stmt->con, (OCINumber *) data, value,
00173                                 size, type);
00174             break;
00175         }
00176         case OCI_CDT_TEXT:
00177         {
00178             const mtext *fmt = OCI_GetDefaultFormatNumeric(rs->stmt->con);
00179             ub4 fmt_size     = (ub4) mtslen(fmt);
00180 
00181             res = OCI_NumberGetFromStr(rs->stmt->con, value, size, type,
00182                                        (dtext *) data,
00183                                        (int) dtslen((dtext *) data),
00184                                        fmt, fmt_size);
00185             break;
00186         }
00187         }
00188     }
00189 
00190     OCI_RESULT(res);
00191 
00192     return res;
00193 }
00194 
00195 /* --------------------------------------------------------------------------------------------- *
00196  * OCI_DefineAlloc
00197  * --------------------------------------------------------------------------------------------- */
00198 
00199 boolean OCI_DefineAlloc
00200 (
00201     OCI_Define *def
00202 )
00203 {
00204     boolean res = TRUE;
00205     ub4 bufsize = 0;
00206     ub4 indsize = 0;
00207     ub4 i;
00208 
00209     /* this function allocates internal buffers, handles, indicators, arrays, ...
00210        for the given output define handle */
00211 
00212     OCI_CHECK(def == NULL, FALSE);
00213 
00214     /* Allocate null indicators array */
00215 
00216     if (def->col.ocode == SQLT_NTY || def->col.ocode == SQLT_REF)
00217         indsize = (ub4) sizeof(void*);
00218     else
00219         indsize = (ub4) sizeof(sb2);
00220 
00221     if (res == TRUE)
00222     {
00223         def->buf.inds = (void *) OCI_MemAlloc(OCI_IPC_INDICATOR_ARRAY,
00224                                               (size_t) indsize,
00225                                               (size_t) def->buf.count, TRUE);
00226         res = (def->buf.inds != NULL);
00227     }
00228 
00229     if (def->col.type == OCI_CDT_OBJECT)
00230     {
00231         def->buf.obj_inds = (void *) OCI_MemAlloc(OCI_IPC_INDICATOR_ARRAY,
00232                                                   sizeof(void *),
00233                                                   (size_t) def->buf.count,
00234                                                   TRUE);
00235         res = (def->buf.obj_inds != NULL);
00236     }
00237 
00238     /* Allocate row data sizes array */
00239 
00240     if (res == TRUE)
00241     {
00242         def->buf.lens = (void *) OCI_MemAlloc(OCI_IPC_LEN_ARRAY,
00243                                               (size_t) def->buf.sizelen,
00244                                               (size_t) def->buf.count, TRUE);
00245 
00246         res = (def->buf.lens != NULL);
00247     }
00248 
00249     /* initialize length array with buffer default size.
00250        But, Oracle uses different sizes for static fetch and callback fetch....*/
00251 
00252     if (res == TRUE)
00253     {
00254         for (i=0; i < def->buf.count; i++)
00255         {
00256             if (def->buf.sizelen == (int) sizeof(ub2))
00257                 *(ub2*)(((ub1 *)def->buf.lens) +
00258                         (size_t) (def->buf.sizelen*i)) = (ub2) def->col.bufsize;
00259             else if (def->buf.sizelen == (int) sizeof(ub4))
00260                 *(ub4*)(((ub1 *)def->buf.lens) +
00261                         (size_t) (def->buf.sizelen*i)) = (ub4) def->col.bufsize;
00262         }
00263     }
00264 
00265     /* Allocate buffer array */
00266 
00267     if (res == TRUE)
00268     {
00269         if (def->col.type == OCI_CDT_LONG)
00270             bufsize = (ub4) sizeof(OCI_Long *);
00271         else
00272             bufsize = def->col.bufsize;
00273 
00274         def->buf.data = (void *) OCI_MemAlloc(OCI_IPC_BUFF_ARRAY, (size_t) bufsize,
00275                                               (size_t) def->buf.count, TRUE);
00276 
00277         res = (def->buf.data != NULL);
00278     }
00279 
00280     /* Allocate descriptor for cursor, lob and file, interval and timestamp */
00281 
00282     if (res == TRUE)
00283     {
00284         if (def->col.dtype != 0)
00285         {
00286             if (def->col.type == OCI_CDT_CURSOR)
00287             {
00288                 for (i = 0; (i < def->buf.count) && (res == TRUE); i++)
00289                 {
00290                     res = (OCI_SUCCESS == OCI_HandleAlloc((dvoid  *) OCILib.env,
00291                                                           (dvoid **) &(def->buf.data[i]),
00292                                                           (ub4) def->col.dtype,
00293                                                           (size_t) 0, (dvoid **) NULL));
00294                 }
00295             }
00296             else
00297             {
00298                 res = (OCI_SUCCESS == OCI_DescriptorArrayAlloc
00299                        (
00300                            (dvoid  *) OCILib.env,
00301                            (dvoid **) def->buf.data,
00302                            (ub4) def->col.dtype,
00303                            (ub4) def->buf.count,
00304                            (size_t) 0, (dvoid **) NULL
00305                        )
00306                        );
00307 
00308                 if ((res == TRUE) && (def->col.type == OCI_CDT_LOB))
00309                 {
00310                     ub4 empty = 0;
00311 
00312                     for (i = 0; (i < def->buf.count) && (res == TRUE); i++)
00313                     {
00314                         OCI_CALL1
00315                         (
00316                             res, def->rs->stmt->con, def->rs->stmt,
00317 
00318                             OCIAttrSet((dvoid *) def->buf.data[i],
00319                                        (ub4) def->col.dtype,
00320                                        (void *) &empty, (ub4) sizeof(empty),
00321                                        (ub4) OCI_ATTR_LOBEMPTY,
00322                                        def->rs->stmt->con->err)
00323                         )
00324                     }
00325                 }
00326             }
00327         }
00328     }
00329 
00330     return res;
00331 }
00332 
00333 /* --------------------------------------------------------------------------------------------- *
00334  * OCI_DefineDef
00335  * --------------------------------------------------------------------------------------------- */
00336 
00337 boolean OCI_DefineDef
00338 (
00339     OCI_Define *def
00340 )
00341 {
00342     boolean res    = TRUE;
00343     ub2 fetch_mode = 0;
00344 
00345     OCI_CHECK(def == NULL, FALSE);
00346 
00347     /*check define mode for long columns */
00348 
00349     if (def->col.type == OCI_CDT_LONG)
00350         fetch_mode = OCI_DYNAMIC_FETCH;
00351     else
00352         fetch_mode = OCI_DEFAULT;
00353 
00354     /* oracle defining */
00355 
00356     OCI_CALL1
00357     (
00358         res, def->rs->stmt->con, def->rs->stmt,
00359 
00360         OCIDefineByPos(def->rs->stmt->stmt,
00361                        (OCIDefine **) &def->buf.handle,
00362                        def->rs->stmt->con->err,
00363                        def->rs->nb_defs,
00364                        (void *) def->buf.data,
00365                        (sb4   ) def->col.bufsize,
00366                        (ub2   ) def->col.icode,
00367                        (void *) def->buf.inds,
00368                        (ub2  *) def->buf.lens,
00369                        (ub2  *) NULL,
00370                        (ub4   ) fetch_mode)
00371     )
00372 
00373     if (def->col.ocode == SQLT_NTY || def->col.ocode == SQLT_REF)
00374     {
00375         OCI_CALL1
00376         (
00377             res, def->rs->stmt->con, def->rs->stmt,
00378 
00379             OCIDefineObject((OCIDefine *) def->buf.handle,
00380                             def->rs->stmt->con->err,
00381                             def->col.typinf->tdo,
00382                             (void **) def->buf.data,
00383                             (ub4   *) NULL,
00384                             (void **) def->buf.obj_inds,
00385                             (ub4   *) NULL)
00386         )
00387     }
00388 
00389     if(( def->col.type == OCI_CDT_TEXT)  ||
00390        ((def->col.type == OCI_CDT_LOB)   && (def->col.subtype != OCI_BLOB))  ||
00391        ((def->col.type == OCI_CDT_FILE)  && (def->col.subtype != OCI_BFILE)) ||
00392        ((def->col.type == OCI_CDT_LONG)  && (def->col.subtype != OCI_BLONG)))
00393     {
00394 
00395         if ((def->col.csfrm == SQLCS_NCHAR) || (OCILib.nls_utf8 == TRUE))
00396         {
00397             ub1 csfrm = SQLCS_NCHAR;
00398 
00399             OCI_CALL1
00400             (
00401                 res, def->rs->stmt->con, def->rs->stmt,
00402 
00403                 OCIAttrSet((dvoid *) def->buf.handle,
00404                            (ub4    ) OCI_HTYPE_DEFINE,
00405                            (dvoid *) &csfrm,
00406                            (ub4    ) sizeof(csfrm),
00407                            (ub4    ) OCI_ATTR_CHARSET_FORM,
00408                            def->rs->stmt->con->err)
00409             )
00410         }
00411 
00412         #ifdef OCI_CHARSET_MIXED
00413 
00414         /* setup Unicode mode for user data on mixed builds */
00415         {
00416             ub2 csid = OCI_UTF16ID;
00417 
00418             OCI_CALL1
00419             (
00420                 res, def->rs->stmt->con, def->rs->stmt,
00421 
00422                 OCIAttrSet((dvoid *) def->buf.handle,
00423                            (ub4    ) OCI_HTYPE_DEFINE,
00424                            (dvoid *) &csid,
00425                            (ub4    ) sizeof(csid),
00426                            (ub4    ) OCI_ATTR_CHARSET_ID,
00427                            def->rs->stmt->con->err)
00428             )
00429         }
00430 
00431         #endif
00432 
00433     }
00434 
00435     return res;
00436 }
00437 
00438 /* --------------------------------------------------------------------------------------------- *
00439  * OCI_DefineRequestBuffer
00440  * --------------------------------------------------------------------------------------------- */
00441 
00442 boolean OCI_DefineRequestBuffer
00443 (
00444     OCI_Define  *def,
00445     unsigned int size
00446 )
00447 {
00448     boolean res = TRUE;
00449 
00450     size++;
00451 
00452     if (OCILib.nls_utf8 == TRUE)
00453         size *= UTF8_BYTES_PER_CHAR;
00454     else
00455         size *= sizeof(dtext);
00456 
00457     if (def->buf.tmpbuf == NULL)
00458     {
00459         def->buf.tmpbuf = (dtext *) OCI_MemAlloc(OCI_IPC_STRING,
00460                                                  (size_t) size,
00461                                                  (size_t) 1,
00462                                                  TRUE);
00463 
00464         if (def->buf.tmpbuf != NULL)
00465             def->buf.tmpsize = size;
00466         else
00467             res = FALSE;
00468 
00469     }
00470     else if (def->buf.tmpsize < size)
00471     {
00472         def->buf.tmpbuf = (dtext *) OCI_MemRealloc(def->buf.tmpbuf,
00473                                                    OCI_IPC_STRING,
00474                                                    (size_t) size,
00475                                                    (size_t) 1);
00476 
00477         if (def->buf.tmpbuf != NULL)
00478             def->buf.tmpsize = size;
00479         else
00480             res = FALSE;
00481     }
00482 
00483     def->buf.tmpbuf[0] = 0;
00484 
00485     return res;
00486 }

Generated on Sun Oct 24 2010 22:02:54 for OCILIB (C Driver for Oracle) by  doxygen 1.7.1