• 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.1 2010-12-13 00:00 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 
00281             if (type == OCI_TIF_TYPE)
00282             {
00283                 boolean pdt = FALSE;
00284 
00285                 /* check if it's system predefined type if order to avoid the next call
00286                    that is not allowed on system types */
00287 
00288                 OCI_CALL2
00289                 (
00290                     res, con,
00291 
00292                     OCIAttrGet(parmh1, OCI_DTYPE_PARAM, &pdt,
00293                                NULL, OCI_ATTR_IS_PREDEFINED_TYPE, con->err)
00294                 )
00295 
00296                 if (pdt == FALSE)
00297                 {
00298                     OCI_CALL2
00299                     (
00300                         res, con,
00301 
00302                         OCIAttrGet(parmh1, OCI_DTYPE_PARAM, &typinf->tcode,
00303                                    NULL, OCI_ATTR_TYPECODE, con->err)
00304                     )
00305                 }
00306             }
00307 
00308             /* do we need get more attributes for collections ? */
00309 
00310             if (typinf->tcode == SQLT_NCO)
00311             {
00312                 typinf->nb_cols = 1;
00313 
00314                 ptype  = OCI_DESC_COLLECTION;
00315                 etype  = OCI_DESC_TYPE;
00316                 parmh2 = parmh1;
00317 
00318                 OCI_CALL2
00319                 (
00320                     res, con,
00321 
00322                     OCIAttrGet(parmh1, OCI_DTYPE_PARAM, &typinf->ccode,
00323                                NULL, OCI_ATTR_COLLECTION_TYPECODE, con->err)
00324                 )
00325             }
00326             else
00327             {
00328                 OCI_CALL2
00329                 (
00330                     res, con,
00331 
00332                     OCIAttrGet(parmh1, OCI_DTYPE_PARAM, &parmh2,
00333                                NULL, attr_type, con->err)
00334                 )
00335 
00336                 OCI_CALL2
00337                 (
00338                     res, con,
00339 
00340                     OCIAttrGet(parmh1, OCI_DTYPE_PARAM, &typinf->nb_cols,
00341                                NULL, num_type, con->err)
00342                 )
00343             }
00344 
00345             /* allocates memory for cached offsets */
00346 
00347             if (typinf->nb_cols > 0)
00348             {
00349                 typinf->offsets = (int *) OCI_MemAlloc(OCI_IPC_ARRAY,
00350                                                        sizeof(*typinf->offsets),
00351                                                        (size_t) typinf->nb_cols,
00352                                                        FALSE);
00353 
00354                 res = (typinf->offsets != NULL);
00355 
00356                 if (res == TRUE)
00357                 {
00358                     memset(typinf->offsets, -1, sizeof(*typinf->offsets) * typinf->nb_cols);
00359                 }
00360             }
00361 
00362             /* allocates memory for children */
00363 
00364             if (typinf->nb_cols > 0)
00365             {
00366                 typinf->cols = (OCI_Column *) OCI_MemAlloc(OCI_IPC_COLUMN,
00367                                                            sizeof(*typinf->cols),
00368                                                            (size_t) typinf->nb_cols,
00369                                                            TRUE);
00370 
00371                 /* describe children */
00372 
00373                 if (typinf->cols != NULL)
00374                 {
00375                     for (i = 0; i < typinf->nb_cols; i++)
00376                     {
00377                         res = res && OCI_ColumnDescribe(&typinf->cols[i], con,
00378                                                         NULL, parmh2, i + 1, ptype);
00379 
00380                         res = res && OCI_ColumnMap(&typinf->cols[i], NULL);
00381 
00382                         if (res == FALSE)
00383                             break;
00384                     }
00385                 }
00386                 else
00387                     res = FALSE;
00388             }
00389 
00390             /* free describe handle */
00391 
00392             if (dschp != NULL)
00393                 OCI_HandleFree(dschp, OCI_HTYPE_DESCRIBE);
00394         }
00395     }
00396 
00397     /* handle errors */
00398 
00399     if (res == FALSE)
00400     {
00401         OCI_TypeInfoFree(typinf);
00402         typinf = NULL;
00403     }
00404 
00405     OCI_RESULT(res);
00406 
00407     /* increment type info reference counter on success */
00408 
00409     if (typinf != NULL)
00410         typinf->refcount++;
00411 
00412     return typinf;
00413 }
00414 
00415 /* --------------------------------------------------------------------------------------------- *
00416  * OCI_TypeInfoFree
00417  * --------------------------------------------------------------------------------------------- */
00418 
00419 boolean OCI_API OCI_TypeInfoFree
00420 (
00421     OCI_TypeInfo *typinf
00422 )
00423 {
00424     boolean res = TRUE;
00425 
00426     OCI_CHECK_PTR(OCI_IPC_TYPE_INFO, typinf, FALSE);
00427 
00428     typinf->refcount--;
00429 
00430     if (typinf->refcount == 0)
00431     {
00432         OCI_ListRemove(typinf->con->tinfs, typinf);
00433 
00434         res = OCI_TypeInfoClose(typinf);
00435 
00436         OCI_FREE(typinf);
00437     }
00438 
00439     OCI_RESULT(res);
00440 
00441     return res;
00442 }
00443 
00444 /* --------------------------------------------------------------------------------------------- *
00445  * OCI_TypeInfoGetType
00446  * --------------------------------------------------------------------------------------------- */
00447 
00448 unsigned int OCI_API OCI_TypeInfoGetType
00449 (
00450     OCI_TypeInfo *typinf
00451 )
00452 {
00453     OCI_CHECK_PTR(OCI_IPC_TYPE_INFO, typinf, OCI_UNKNOWN);
00454 
00455     OCI_RESULT(TRUE);
00456 
00457     return typinf->type;
00458 }
00459 
00460 /* --------------------------------------------------------------------------------------------- *
00461  * OCI_TypeInfoGetColumnCount
00462  * --------------------------------------------------------------------------------------------- */
00463 
00464 unsigned int OCI_API OCI_TypeInfoGetColumnCount
00465 (
00466     OCI_TypeInfo *typinf
00467 )
00468 {
00469     OCI_CHECK_PTR(OCI_IPC_TYPE_INFO, typinf, 0);
00470 
00471     OCI_RESULT(TRUE);
00472 
00473     return typinf->nb_cols;
00474 }
00475 
00476 /* --------------------------------------------------------------------------------------------- *
00477  * OCI_TypeInfoGetColumn
00478  * --------------------------------------------------------------------------------------------- */
00479 
00480 OCI_Column * OCI_API OCI_TypeInfoGetColumn
00481 (
00482     OCI_TypeInfo *typinf,
00483     unsigned int  index
00484 )
00485 {
00486     OCI_CHECK_PTR(OCI_IPC_TYPE_INFO, typinf, NULL);
00487     OCI_CHECK_BOUND(typinf->con, index, 1,  typinf->nb_cols, NULL);
00488 
00489     OCI_RESULT(TRUE);
00490 
00491     return &(typinf->cols[index-1]);
00492 }
00493 
00494 /* --------------------------------------------------------------------------------------------- *
00495  * OCI_TypeInfoGetName
00496  * --------------------------------------------------------------------------------------------- */
00497 
00498 const mtext * OCI_API OCI_TypeInfoGetName
00499 (
00500     OCI_TypeInfo *typinf
00501 )
00502 {
00503     OCI_CHECK_PTR(OCI_IPC_TYPE_INFO, typinf, NULL);
00504 
00505     OCI_RESULT(TRUE);
00506 
00507     return typinf->name;
00508 }

Generated on Mon Dec 13 2010 22:32:02 for OCILIB (C Driver for Oracle) by  doxygen 1.7.2