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

D:/Perso/dev/ocilib/ocilib/src/typeinfo.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: typeinfo.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_TypeInfoClose
00043  * --------------------------------------------------------------------------------------------- */
00044 
00045 boolean OCI_TypeInfoClose
00046 (
00047     OCI_TypeInfo *typinf
00048 )
00049 {
00050     ub2 i;
00051 
00052     OCI_CHECK(typinf == NULL, FALSE);
00053 
00054     for (i=0; i < typinf->nb_cols; i++)
00055     {
00056         OCI_FREE(typinf->cols[i].name);
00057     }
00058 
00059     OCI_FREE(typinf->cols);
00060     OCI_FREE(typinf->name);
00061     OCI_FREE(typinf->schema);
00062     OCI_FREE(typinf->offsets);
00063 
00064     return TRUE;
00065 }
00066 
00067 /* ********************************************************************************************* *
00068  *                            PUBLIC FUNCTIONS
00069  * ********************************************************************************************* */
00070 
00071 /* --------------------------------------------------------------------------------------------- *
00072  * OCI_TypeInfoGet
00073  * --------------------------------------------------------------------------------------------- */
00074 
00075 OCI_TypeInfo * OCI_API OCI_TypeInfoGet
00076 (
00077     OCI_Connection *con,
00078     const mtext    *name,
00079     unsigned int    type
00080 )
00081 {
00082     OCI_TypeInfo *typinf = NULL;
00083     OCI_Item *item       = NULL;
00084     OCIDescribe *dschp   = NULL;
00085     OCIParam *parmh1     = NULL;
00086     OCIParam *parmh2     = NULL;
00087     mtext *str           = NULL;
00088     int etype            = OCI_DESC_COLUMN;
00089     int ptype            = 0;
00090     ub1 item_type        = 0;
00091     ub4 attr_type        = 0;
00092     ub4 num_type         = 0;
00093     boolean res          = TRUE;
00094     boolean found        = FALSE;
00095     ub2 i;
00096 
00097     mtext obj_schema[OCI_SIZE_OBJ_NAME+1];
00098     mtext obj_name[OCI_SIZE_OBJ_NAME+1];
00099 
00100     OCI_CHECK_INITIALIZED(NULL);
00101 
00102     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, NULL);
00103     OCI_CHECK_PTR(OCI_IPC_STRING, name, NULL);
00104 
00105     if (type == OCI_TIF_TABLE)
00106         item_type = OCI_PTYPE_TABLE;
00107     else if (type == OCI_TIF_VIEW)
00108         item_type = OCI_PTYPE_VIEW;
00109     else if (type == OCI_TIF_TYPE)
00110         item_type = OCI_PTYPE_TYPE;
00111     else
00112         return NULL;
00113 
00114     obj_schema[0] = 0;
00115     obj_name[0]   = 0;
00116 
00117     /* is the schema provided in the object name ? */
00118 
00119     for (str = (mtext *) name; *str != 0; str++)
00120     {
00121         if (*str == MT('.'))
00122         {
00123             mtsncat(obj_schema, name, str-name);
00124             mtsncat(obj_name, ++str, (size_t) OCI_SIZE_OBJ_NAME);
00125             break;
00126         }
00127     }
00128 
00129     /* if the schema is not provided, we just copy the object name */
00130 
00131     if (obj_name[0] == 0)
00132     {
00133         mtsncat(obj_name, name, (size_t) OCI_SIZE_OBJ_NAME);
00134     }
00135 
00136     /* type name must be uppercase */
00137 
00138     for (str = obj_name; *str != 0; str++)
00139         *str = (mtext) mttoupper(*str);
00140 
00141     /* schema name must be uppercase */
00142 
00143     for (str = obj_schema; *str != 0; str++)
00144         *str = (mtext) mttoupper(*str);
00145 
00146     /* first try to find it in list */
00147 
00148     item = con->tinfs->head;
00149 
00150     /* walk along the list to find the type */
00151 
00152     while (item != NULL)
00153     {
00154         typinf = (OCI_TypeInfo *) item->data;
00155 
00156         if ((typinf != NULL) && (typinf->type == type))
00157         {
00158             if ((mtscasecmp(typinf->name,   obj_name  ) == 0) &&
00159                 (mtscasecmp(typinf->schema, obj_schema) == 0))
00160             {
00161                 found = TRUE;
00162                 break;
00163             }
00164         }
00165 
00166         item = item->next;
00167     }
00168 
00169     /* Not found, so create type object */
00170 
00171     if (found == FALSE)
00172     {
00173         item = OCI_ListAppend(con->tinfs, sizeof(OCI_TypeInfo));
00174 
00175         res = (item != NULL);
00176 
00177         if (res == TRUE)
00178         {
00179             typinf = (OCI_TypeInfo *) item->data;
00180 
00181             typinf->type        = type;
00182             typinf->con         = con;
00183             typinf->name        = mtsdup(obj_name);
00184             typinf->schema      = mtsdup(obj_schema);
00185             typinf->struct_size = 0;
00186 
00187             res = (OCI_SUCCESS == OCI_HandleAlloc(OCILib.env,
00188                                                   (dvoid **) (void *) &dschp,
00189                                                   OCI_HTYPE_DESCRIBE, (size_t) 0,
00190                                                   (dvoid **) NULL));
00191         }
00192 
00193         if (res == TRUE)
00194         {
00195             if (type == OCI_TIF_TYPE)
00196             {
00197                 void *ostr1 = NULL;
00198                 void *ostr2 = NULL;
00199                 int osize1  = -1;
00200                 int osize2  = -1;
00201 
00202                 attr_type = OCI_ATTR_LIST_TYPE_ATTRS;
00203                 num_type  = OCI_ATTR_NUM_TYPE_ATTRS;
00204                 ptype     = OCI_DESC_TYPE;
00205 
00206                 ostr1 = OCI_GetInputMetaString(typinf->schema, &osize1);
00207                 ostr2 = OCI_GetInputMetaString(typinf->name,   &osize2);
00208 
00209                 OCI_CALL2
00210                 (
00211                     res, con,
00212 
00213                     OCITypeByName(OCILib.env, con->err, con->cxt,
00214                                   (text *) ostr1, (ub4) osize1,
00215                                   (text *) ostr2, (ub4) osize2,
00216                                   (text *) NULL, (ub4) 0,
00217                                   OCI_DURATION_SESSION, OCI_TYPEGET_ALL,
00218                                   &typinf->tdo)
00219                 )
00220 
00221                 OCI_CALL2
00222                 (
00223                     res, con,
00224 
00225                     OCIDescribeAny(con->cxt, con->err, (void *) typinf->tdo,
00226                                    0, OCI_OTYPE_PTR, OCI_DEFAULT,
00227                                    OCI_PTYPE_TYPE, dschp)
00228                 )
00229 
00230                 OCI_ReleaseMetaString(ostr1);
00231                 OCI_ReleaseMetaString(ostr2);
00232             }
00233             else
00234             {
00235                 mtext buffer[(OCI_SIZE_OBJ_NAME*2) + 2];
00236 
00237                 size_t size = sizeof(buffer)/sizeof(mtext);
00238                 void *ostr1 = NULL;
00239                 int osize1  = -1;
00240 
00241                 attr_type = OCI_ATTR_LIST_COLUMNS;
00242                 num_type  = OCI_ATTR_NUM_COLS;
00243                 ptype     = OCI_DESC_TABLE;
00244                 str       = buffer;
00245 
00246                 str[0] = 0;
00247 
00248                 if ((typinf->schema != NULL) && (typinf->schema[0] != 0))
00249                 {
00250                     str   = mtsncat(buffer, typinf->schema, size);
00251                     size -= mtslen(typinf->schema);
00252                     str   = mtsncat(str, MT("."), size);
00253                     size -= (size_t) 1;
00254                 }
00255 
00256                 mtsncat(str, typinf->name, size);
00257 
00258                 ostr1 = OCI_GetInputMetaString(str, &osize1);
00259 
00260                 OCI_CALL2
00261                 (
00262                     res, con,
00263 
00264                     OCIDescribeAny(con->cxt, con->err, (dvoid *) ostr1,
00265                                    (ub4) osize1, OCI_OTYPE_NAME,
00266                                    OCI_DEFAULT, item_type, dschp)
00267                 )
00268 
00269                 OCI_ReleaseMetaString(ostr1);
00270             }
00271 
00272             OCI_CALL2
00273             (
00274                 res, con,
00275 
00276                 OCIAttrGet(dschp, OCI_HTYPE_DESCRIBE, &parmh1,
00277                            NULL, OCI_ATTR_PARAM, con->err)
00278             )
00279 
00280             /* do we need get more attributes for collections ? */
00281 
00282             if (type == OCI_TIF_TYPE)
00283             {
00284                 OCI_CALL2
00285                 (
00286                     res, con,
00287 
00288                     OCIAttrGet(parmh1, OCI_DTYPE_PARAM, &typinf->tcode,
00289                                NULL, OCI_ATTR_TYPECODE, con->err)
00290                 )
00291 
00292             }
00293 
00294             if (typinf->tcode == SQLT_NCO)
00295             {
00296                 typinf->nb_cols = 1;
00297 
00298                 ptype  = OCI_DESC_COLLECTION;
00299                 etype  = OCI_DESC_TYPE;
00300                 parmh2 = parmh1;
00301 
00302                 OCI_CALL2
00303                 (
00304                     res, con,
00305 
00306                     OCIAttrGet(parmh1, OCI_DTYPE_PARAM, &typinf->ccode,
00307                                NULL, OCI_ATTR_COLLECTION_TYPECODE, con->err)
00308                 )
00309             }
00310             else
00311             {
00312                 OCI_CALL2
00313                 (
00314                     res, con,
00315 
00316                     OCIAttrGet(parmh1, OCI_DTYPE_PARAM, &parmh2,
00317                                NULL, attr_type, con->err)
00318                 )
00319 
00320                 OCI_CALL2
00321                 (
00322                     res, con,
00323 
00324                     OCIAttrGet(parmh1, OCI_DTYPE_PARAM, &typinf->nb_cols,
00325                                NULL, num_type, con->err)
00326                 )
00327             }
00328 
00329             /* allocates memory for cached offsets */
00330 
00331             if (typinf->nb_cols > 0)
00332             {
00333                 typinf->offsets = (int *) OCI_MemAlloc(OCI_IPC_ARRAY,
00334                                                        sizeof(*typinf->offsets),
00335                                                        (size_t) typinf->nb_cols,
00336                                                        FALSE);
00337 
00338                 res = (typinf->offsets != NULL);
00339 
00340                 if (res == TRUE)
00341                 {
00342                     memset(typinf->offsets, -1, sizeof(*typinf->offsets) * typinf->nb_cols);
00343                 }
00344             }
00345 
00346             /* allocates memory for children */
00347 
00348             if (typinf->nb_cols > 0)
00349             {
00350                 typinf->cols = (OCI_Column *) OCI_MemAlloc(OCI_IPC_COLUMN,
00351                                                            sizeof(*typinf->cols),
00352                                                            (size_t) typinf->nb_cols,
00353                                                            TRUE);
00354 
00355                 /* describe children */
00356 
00357                 if (typinf->cols != NULL)
00358                 {
00359                     for (i = 0; i < typinf->nb_cols; i++)
00360                     {
00361                         res = res && OCI_ColumnDescribe(&typinf->cols[i], con,
00362                                                         NULL, parmh2, i + 1, ptype);
00363 
00364                         res = res && OCI_ColumnMap(&typinf->cols[i], NULL);
00365 
00366                         if (res == FALSE)
00367                             break;
00368                     }
00369                 }
00370                 else
00371                     res = FALSE;
00372             }
00373 
00374             /* free describe handle */
00375 
00376             if (dschp != NULL)
00377                 OCI_HandleFree(dschp, OCI_HTYPE_DESCRIBE);
00378         }
00379     }
00380 
00381     /* handle errors */
00382 
00383     if (res == FALSE)
00384     {
00385         OCI_TypeInfoFree(typinf);
00386         typinf = NULL;
00387     }
00388 
00389     OCI_RESULT(res);
00390 
00391     /* increment type info reference counter on success */
00392 
00393     if (typinf != NULL)
00394         typinf->refcount++;
00395 
00396     return typinf;
00397 }
00398 
00399 /* --------------------------------------------------------------------------------------------- *
00400  * OCI_TypeInfoFree
00401  * --------------------------------------------------------------------------------------------- */
00402 
00403 boolean OCI_API OCI_TypeInfoFree
00404 (
00405     OCI_TypeInfo *typinf
00406 )
00407 {
00408     boolean res = TRUE;
00409 
00410     OCI_CHECK_PTR(OCI_IPC_TYPE_INFO, typinf, FALSE);
00411 
00412     typinf->refcount--;
00413 
00414     if (typinf->refcount == 0)
00415     {
00416         OCI_ListRemove(typinf->con->tinfs, typinf);
00417 
00418         res = OCI_TypeInfoClose(typinf);
00419 
00420         OCI_FREE(typinf);
00421     }
00422 
00423     OCI_RESULT(res);
00424 
00425     return res;
00426 }
00427 
00428 /* --------------------------------------------------------------------------------------------- *
00429  * OCI_TypeInfoGetType
00430  * --------------------------------------------------------------------------------------------- */
00431 
00432 unsigned int OCI_API OCI_TypeInfoGetType
00433 (
00434     OCI_TypeInfo *typinf
00435 )
00436 {
00437     OCI_CHECK_PTR(OCI_IPC_TYPE_INFO, typinf, OCI_UNKNOWN);
00438 
00439     OCI_RESULT(TRUE);
00440 
00441     return typinf->type;
00442 }
00443 
00444 /* --------------------------------------------------------------------------------------------- *
00445  * OCI_TypeInfoGetColumnCount
00446  * --------------------------------------------------------------------------------------------- */
00447 
00448 unsigned int OCI_API OCI_TypeInfoGetColumnCount
00449 (
00450     OCI_TypeInfo *typinf
00451 )
00452 {
00453     OCI_CHECK_PTR(OCI_IPC_TYPE_INFO, typinf, 0);
00454 
00455     OCI_RESULT(TRUE);
00456 
00457     return typinf->nb_cols;
00458 }
00459 
00460 /* --------------------------------------------------------------------------------------------- *
00461  * OCI_TypeInfoGetColumn
00462  * --------------------------------------------------------------------------------------------- */
00463 
00464 OCI_Column * OCI_API OCI_TypeInfoGetColumn
00465 (
00466     OCI_TypeInfo *typinf,
00467     unsigned int  index
00468 )
00469 {
00470     OCI_CHECK_PTR(OCI_IPC_TYPE_INFO, typinf, NULL);
00471     OCI_CHECK_BOUND(typinf->con, index, 1,  typinf->nb_cols, NULL);
00472 
00473     OCI_RESULT(TRUE);
00474 
00475     return &(typinf->cols[index-1]);
00476 }
00477 
00478 /* --------------------------------------------------------------------------------------------- *
00479  * OCI_TypeInfoGetName
00480  * --------------------------------------------------------------------------------------------- */
00481 
00482 const mtext * OCI_API OCI_TypeInfoGetName
00483 (
00484     OCI_TypeInfo *typinf
00485 )
00486 {
00487     OCI_CHECK_PTR(OCI_IPC_TYPE_INFO, typinf, NULL);
00488 
00489     OCI_RESULT(TRUE);
00490 
00491     return typinf->name;
00492 }

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