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

D:/Perso/dev/ocilib/ocilib/src/column.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: column.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_ColumnDescribe
00043  * --------------------------------------------------------------------------------------------- */
00044 
00045 boolean OCI_ColumnDescribe
00046 (
00047     OCI_Column     *col,
00048     OCI_Connection *con,
00049     OCI_Statement  *stmt,
00050     void           *handle,
00051     int             index,
00052     int             ptype
00053 )
00054 {
00055     void *ostr   = NULL;
00056     void *param  = NULL;
00057     boolean res  = TRUE;
00058     int osize    = 0;
00059     ub4 htype    = 0;
00060     ub4 attrname = 0;
00061 
00062     /* get descriptor */
00063 
00064     if (ptype == OCI_DESC_COLLECTION)
00065     {
00066         OCI_CALL1
00067         (
00068             res, con, stmt,
00069 
00070             OCIAttrGet((dvoid *) handle, (ub4) OCI_DTYPE_PARAM, (dvoid *) &param,
00071                        (ub4 *) NULL, (ub4) OCI_ATTR_COLLECTION_ELEMENT, con->err)
00072         )
00073 
00074         attrname = OCI_ATTR_TYPE_NAME;
00075     }
00076     else
00077     {
00078         if (ptype == OCI_DESC_RESULTSET)
00079             htype = OCI_HTYPE_STMT;
00080         else
00081             htype = OCI_DTYPE_PARAM;
00082 
00083         OCI_CALL1
00084         (
00085             res, con, stmt,
00086 
00087             OCIParamGet((dvoid *) handle, htype,  con->err, (void**) &param,
00088                         (ub4) index)
00089         )
00090     }
00091 
00092     /* sql code */
00093 
00094     OCI_CALL1
00095     (
00096         res, con, stmt,
00097 
00098         OCIAttrGet((dvoid *) param, (ub4) OCI_DTYPE_PARAM, (dvoid *) &col->ocode,
00099                    (ub4 *) NULL, (ub4) OCI_ATTR_DATA_TYPE, con->err)
00100     )
00101 
00102     /* size */
00103 
00104     OCI_CALL1
00105     (
00106         res, con, stmt,
00107 
00108         OCIAttrGet((dvoid *) param, (ub4)  OCI_DTYPE_PARAM, (dvoid *) &col->size,
00109                    (ub4 *) NULL, (ub4) OCI_ATTR_DATA_SIZE, con->err)
00110     )
00111 
00112     /* scale */
00113 
00114     OCI_CALL1
00115     (
00116         res, con, stmt,
00117 
00118         OCIAttrGet((dvoid *) param, (ub4) OCI_DTYPE_PARAM, (dvoid *) &col->scale,
00119                    (ub4 *) NULL, (ub4) OCI_ATTR_SCALE, con->err)
00120     )
00121 
00122     /* precision */
00123 
00124     if (ptype == OCI_DESC_RESULTSET)
00125     {
00126         sb2 prec = 0;
00127 
00128         OCI_CALL1
00129         (
00130             res, con, stmt,
00131 
00132             OCIAttrGet((dvoid *) param, (ub4) OCI_DTYPE_PARAM, (dvoid *) &prec,
00133                        (ub4 *) NULL, (ub4) OCI_ATTR_PRECISION, con->err)
00134         )
00135 
00136         col->prec = (sb2) prec;
00137     }
00138     else
00139     {
00140         ub1 prec = 0;
00141 
00142         OCI_CALL1
00143         (
00144             res, con, stmt,
00145 
00146             OCIAttrGet((dvoid *) param, (ub4) OCI_DTYPE_PARAM, (dvoid *) &prec,
00147                        (ub4 *) NULL, (ub4) OCI_ATTR_PRECISION, con->err)
00148         )
00149 
00150         col->prec = (sb2) prec;
00151     }
00152 
00153     /* charset form */
00154 
00155     OCI_CALL1
00156     (
00157         res, con, stmt,
00158 
00159         OCIAttrGet((dvoid *) param, (ub4) OCI_DTYPE_PARAM, (dvoid *) &col->csfrm,
00160                    (ub4 *) NULL, (ub4) OCI_ATTR_CHARSET_FORM, con->err)
00161     )
00162 
00163     /* type of column length for string based column */
00164 
00165     #if OCI_VERSION_COMPILE >= OCI_9_0
00166 
00167     if ((OCILib.version_runtime >= OCI_9_0) && (con->ver_num >= OCI_9_0))
00168     {
00169         /* char used - no error checking because on Oracle 9.0, querying
00170                        this param that is not char/varchar based will cause an
00171                        error */
00172 
00173         OCI_CALL1
00174         (
00175             res, con, stmt,
00176 
00177             OCIAttrGet((dvoid *) param, (ub4) OCI_DTYPE_PARAM,
00178                        (dvoid *) &col->charused, (ub4 *) NULL,
00179                        (ub4) OCI_ATTR_CHAR_USED, con->err)
00180         )
00181     }
00182 
00183     /* char size */
00184 
00185     if (col->charused == TRUE)
00186     {
00187         OCI_CALL1
00188         (
00189             res, con, stmt,
00190 
00191             OCIAttrGet((dvoid *) param, (ub4) OCI_DTYPE_PARAM,
00192                        (dvoid *) &col->charsize, (ub4 *) NULL,
00193                        (ub4) OCI_ATTR_CHAR_SIZE, con->err)
00194         )
00195     }
00196 
00197     if ((OCILib.version_runtime >= OCI_9_0) && (con->ver_num >= OCI_9_0))
00198     {
00199         /* fractional time precision for timestamps */
00200 
00201         if (col->ocode == SQLT_TIMESTAMP    ||
00202             col->ocode == SQLT_TIMESTAMP_TZ ||
00203             col->ocode == SQLT_TIMESTAMP_LTZ)
00204         {
00205             OCI_CALL1
00206             (
00207                 res, con, stmt,
00208 
00209                 OCIAttrGet((dvoid *) param, (ub4) OCI_DTYPE_PARAM,
00210                            (dvoid *) &col->prec, (ub4 *) NULL,
00211                            (ub4) OCI_ATTR_FSPRECISION, con->err)
00212             )
00213         }
00214 
00215         /* leading and fractional precision for interval */
00216 
00217         if (col->ocode == SQLT_INTERVAL_DS ||
00218             col->ocode == SQLT_INTERVAL_YM)
00219         {
00220             OCI_CALL1
00221             (
00222                 res, con, stmt,
00223 
00224                 OCIAttrGet((dvoid *) param, (ub4) OCI_DTYPE_PARAM,
00225                            (dvoid *) &col->prec, (ub4 *) NULL,
00226                            (ub4) OCI_ATTR_LFPRECISION, con->err)
00227             )
00228 
00229             OCI_CALL1
00230             (
00231                 res, con, stmt,
00232 
00233                 OCIAttrGet((dvoid *) param, (ub4) OCI_DTYPE_PARAM,
00234                            (dvoid *) &col->prec2, (ub4 *) NULL,
00235                            (ub4) OCI_ATTR_FSPRECISION, con->err)
00236             )
00237         }
00238     }
00239 
00240     #endif
00241 
00242     /* check nullable only for table based column */
00243 
00244     if (ptype == OCI_DESC_TABLE)
00245     {
00246         OCI_CALL1
00247         (
00248             res, con, stmt,
00249 
00250             OCIAttrGet((dvoid *) param, (ub4) OCI_DTYPE_PARAM,
00251                        (dvoid *) &col->null, (ub4 *) NULL,
00252                        (ub4) OCI_ATTR_IS_NULL, con->err)
00253         )
00254     }
00255     else
00256         col->null = TRUE;
00257 
00258     /* name */
00259 
00260     if (ptype == OCI_DESC_COLLECTION)
00261         attrname = OCI_ATTR_TYPE_NAME;
00262     else
00263         attrname = OCI_ATTR_NAME;
00264 
00265     /* name */
00266 
00267     if (ptype == OCI_DESC_COLLECTION)
00268         attrname = OCI_ATTR_TYPE_NAME;
00269     else
00270         attrname = OCI_ATTR_NAME;
00271 
00272     OCI_CALL1
00273     (
00274         res, con, stmt,
00275 
00276         OCIAttrGet((dvoid *) param, (ub4) OCI_DTYPE_PARAM, (dvoid *) &ostr,
00277                    (ub4 *) &osize, (ub4) attrname, con->err)
00278     )
00279 
00280     if ((res == TRUE) && (ostr != NULL))
00281     {
00282         col->name = (mtext *) OCI_MemAlloc(OCI_IPC_STRING, sizeof(mtext),
00283                                            (size_t) ((osize / (int) sizeof(omtext)) + 1),
00284                                            TRUE);
00285 
00286         if (col->name != NULL)
00287         {
00288             OCI_CopyString(ostr, col->name, &osize,
00289                            sizeof(omtext), sizeof(mtext));
00290         }
00291         else
00292             res = FALSE;
00293     }
00294 
00295     /* user type descriptor */
00296 
00297     if (col->ocode == SQLT_NTY || col->ocode == SQLT_REF)
00298     {
00299         OCI_CALL1
00300         (
00301             res, con, stmt,
00302 
00303             OCIAttrGet((dvoid *) param, (ub4) OCI_DTYPE_PARAM,
00304                        (dvoid *) &ostr, (ub4 *) &osize,
00305                        (ub4) OCI_ATTR_TYPE_NAME, con->err)
00306         )
00307 
00308         if ((res == TRUE) && (ostr != NULL))
00309         {
00310             mtext *tmp = (mtext *) OCI_MemAlloc(OCI_IPC_STRING, sizeof(mtext),
00311                                                 (size_t)((osize / (int) sizeof(omtext)) + 1),
00312                                                 TRUE);
00313 
00314             if (tmp != NULL)
00315             {
00316                 OCI_CopyString(ostr, tmp, &osize, sizeof(omtext), sizeof(mtext));
00317                 col->typinf = OCI_TypeInfoGet(con, tmp, OCI_TIF_TYPE);
00318             }
00319 
00320             res = (col->typinf != NULL);
00321 
00322             OCI_FREE(tmp);
00323         }
00324     }
00325 
00326     if (param != NULL)
00327     {
00328         res = (OCI_SUCCESS == OCIDescriptorFree(param, OCI_DTYPE_PARAM));
00329     }
00330 
00331     return res;
00332 }
00333 
00334 /* --------------------------------------------------------------------------------------------- *
00335  * OCI_ColumnMap
00336  * --------------------------------------------------------------------------------------------- */
00337 
00338 boolean OCI_ColumnMap
00339 (
00340     OCI_Column    *col,
00341     OCI_Statement *stmt
00342 )
00343 {
00344     boolean res = TRUE;
00345 
00346     OCI_CHECK(col == NULL, FALSE);
00347 
00348     /* map Oracle SQL code to OCILIB types and setup of internal buffer size */
00349 
00350     col->icode = col->ocode;
00351 
00352     switch (col->icode)
00353     {
00354         case SQLT_INT:
00355 
00356             col->type = OCI_CDT_NUMERIC;
00357 
00358             /* set bufsize only if it's not a "returning into" placeholder */
00359 
00360             if (col->bufsize == 0)
00361             {
00362                 col->subtype = OCI_NUM_INT;
00363                 col->bufsize = sizeof(int);
00364             }
00365 
00366             break;
00367 
00368         case SQLT_UIN:
00369 
00370             col->type = OCI_CDT_NUMERIC;
00371 
00372             /* set bufsize only if it's not a "returning into" placeholder */
00373 
00374             if (col->bufsize == 0)
00375             {
00376                 col->subtype = OCI_NUM_UINT;
00377                 col->bufsize = sizeof(unsigned int);
00378             }
00379 
00380             break;
00381 
00382         case SQLT_FLT:
00383         case SQLT_VNU:
00384         case SQLT_PDN:
00385         case SQLT_NUM:
00386 
00387             #if OCI_VERSION_COMPILE >= OCI_10_1
00388 
00389         case SQLT_BFLOAT:
00390         case SQLT_BDOUBLE:
00391         case SQLT_IBFLOAT:
00392         case SQLT_IBDOUBLE:
00393 
00394             #endif
00395 
00396             col->type    = OCI_CDT_NUMERIC;
00397             col->subtype = OCI_NUM_NUMBER;
00398             col->icode   = SQLT_VNU;
00399             col->bufsize = sizeof(OCINumber);
00400 
00401             break;
00402 
00403         case SQLT_DAT:
00404         case SQLT_ODT:
00405 
00406             col->type = OCI_CDT_DATETIME;
00407 
00408             /* We map to SQLT_ODT only it the column is not part of a
00409                "returning into" clause (workaround for Oracle
00410                known bug #3269146
00411             */
00412 
00413             if (col->bufsize == 0)
00414             {
00415                 col->icode   = SQLT_ODT;
00416                 col->bufsize = sizeof(OCIDate);
00417             }
00418 
00419             break;
00420 
00421         case SQLT_CUR:
00422         case SQLT_RSET:
00423 
00424             col->type    = OCI_CDT_CURSOR;
00425             col->bufsize = sizeof(OCIStmt *);
00426             col->dtype   = OCI_HTYPE_STMT;
00427             break;
00428 
00429         case SQLT_RID:
00430         case SQLT_RDD:
00431 
00432             col->icode = SQLT_STR;
00433             col->type  = OCI_CDT_TEXT;
00434 
00435             if ((col->ocode == SQLT_RDD) || (col->size > sizeof(OCIRowid *)))
00436             {
00437                 /* For Oracle 7 ROWIDs and regular ROWID descriptors, the
00438                    max size of the hex value is defined by the constant
00439                    OCI_SIZE_ROWID
00440                 */
00441 
00442                 col->bufsize = (OCI_SIZE_ROWID + 1) * (ub4) sizeof(dtext);
00443             }
00444             else
00445             {
00446                 /* For ROWID descriptor, if column size is bigger than the size
00447                     of the descriptor, it means that an UROWID column and then
00448                     the column size is the maximum size needed for representing
00449                     its value as an hex string
00450                 */
00451 
00452                 col->bufsize = (ub4) ((col->size + 1) * (ub2) sizeof(dtext));
00453             }
00454 
00455             if (OCILib.nls_utf8 == TRUE)
00456             {
00457                 col->bufsize *= UTF8_BYTES_PER_CHAR;
00458             }
00459 
00460             break;
00461 
00462         case SQLT_BIN:
00463 
00464             /* adding one extra character space for string conversion */
00465 
00466             col->type    = OCI_CDT_RAW;
00467             col->bufsize = (ub4) (col->size + (ub2) sizeof(dtext));
00468             break;
00469 
00470         case SQLT_BLOB:
00471 
00472             col->type    = OCI_CDT_LOB;
00473             col->subtype = OCI_BLOB;
00474             col->dtype   = OCI_DTYPE_LOB;
00475             col->bufsize = (ub4) sizeof(OCILobLocator *);
00476             break;
00477 
00478         case SQLT_CLOB:
00479 
00480             col->type    = OCI_CDT_LOB;
00481             col->dtype   = OCI_DTYPE_LOB;
00482             col->bufsize = (ub4) sizeof(OCILobLocator *);
00483 
00484             if (col->csfrm == SQLCS_NCHAR)
00485                 col->subtype = OCI_NCLOB;
00486             else
00487                 col->subtype = OCI_CLOB;
00488 
00489             break;
00490 
00491         case SQLT_BFILE:
00492 
00493             col->type    = OCI_CDT_FILE;
00494             col->subtype = OCI_BFILE;
00495             col->dtype   = OCI_DTYPE_LOB;
00496             col->bufsize = (ub4) sizeof(OCILobLocator *);
00497             break;
00498 
00499         case SQLT_CFILE:
00500 
00501             col->type    = OCI_CDT_FILE;
00502             col->subtype = OCI_CFILE;
00503             col->bufsize = (ub4) sizeof(OCILobLocator *);
00504             col->dtype   = OCI_DTYPE_LOB;
00505             break;
00506 
00507         case SQLT_LNG:
00508         case SQLT_LVC:
00509         case SQLT_LBI:
00510         case SQLT_LVB:
00511         case SQLT_VBI:
00512 
00513             if ((col->icode == SQLT_LNG || col->icode == SQLT_LVC) &&
00514                 (stmt != NULL && stmt->long_mode == OCI_LONG_IMPLICIT))
00515             {
00516                 col->type    = OCI_CDT_TEXT;
00517                 col->bufsize = (OCI_SIZE_LONG+1) * ((ub2) sizeof(dtext));
00518                 col->subtype = OCI_CLONG;
00519 
00520                 if (OCILib.nls_utf8 == TRUE)
00521                 {
00522                     col->bufsize *= UTF8_BYTES_PER_CHAR;
00523                 }
00524             }
00525             else
00526             {
00527                 col->type    = OCI_CDT_LONG;
00528                 col->bufsize = INT_MAX;
00529 
00530                 if (col->icode == SQLT_LBI ||
00531                     col->icode == SQLT_LVB ||
00532                     col->icode == SQLT_VBI)
00533                 {
00534                     col->subtype = OCI_BLONG;
00535                 }
00536                 else
00537                 {
00538                     col->subtype = OCI_CLONG;
00539                 }
00540 
00541             }
00542 
00543             break;
00544 
00545             #if OCI_VERSION_COMPILE >= OCI_9_0
00546 
00547         case SQLT_TIMESTAMP:
00548 
00549             col->type    = OCI_CDT_TIMESTAMP;
00550             col->subtype = OCI_TIMESTAMP;
00551             col->dtype   = OCI_DTYPE_TIMESTAMP;
00552             col->bufsize = (ub4) sizeof(OCIDateTime *);
00553             break;
00554 
00555         case SQLT_TIMESTAMP_TZ:
00556 
00557             col->type    = OCI_CDT_TIMESTAMP;
00558             col->subtype = OCI_TIMESTAMP_TZ;
00559             col->dtype   = OCI_DTYPE_TIMESTAMP_TZ;
00560             col->bufsize = (ub4) sizeof(OCIDateTime *);
00561             break;
00562 
00563         case SQLT_TIMESTAMP_LTZ:
00564 
00565             col->type    = OCI_CDT_TIMESTAMP;
00566             col->subtype = OCI_TIMESTAMP_LTZ;
00567             col->dtype   = OCI_DTYPE_TIMESTAMP_LTZ;
00568             col->bufsize = (ub4) sizeof(OCIDateTime *);
00569             break;
00570 
00571         case SQLT_INTERVAL_YM:
00572 
00573             col->type    = OCI_CDT_INTERVAL;
00574             col->subtype = OCI_INTERVAL_YM;
00575             col->dtype   = OCI_DTYPE_INTERVAL_YM;
00576             col->bufsize = (ub4) sizeof(OCIInterval *);
00577             break;
00578 
00579         case SQLT_INTERVAL_DS:
00580 
00581             col->type    = OCI_CDT_INTERVAL;
00582             col->subtype = OCI_INTERVAL_DS;
00583             col->dtype   = OCI_DTYPE_INTERVAL_DS;
00584             col->bufsize = (ub4) sizeof(OCIInterval *);
00585             break;
00586 
00587             #endif
00588 
00589             #if OCI_VERSION_COMPILE >= OCI_9_0
00590 
00591         case SQLT_PNTY:
00592 
00593             #endif
00594 
00595         case SQLT_NTY:
00596 
00597             col->icode   = SQLT_NTY;
00598             col->bufsize = (ub4) sizeof(void *);
00599 
00600             if (col->typinf->tcode == SQLT_NCO)
00601                 col->type = OCI_CDT_COLLECTION;
00602             else
00603                 col->type = OCI_CDT_OBJECT;
00604 
00605             break;
00606 
00607         case SQLT_REF:
00608 
00609             col->icode   = SQLT_REF;
00610             col->bufsize = (ub4) sizeof(OCIRef *);
00611             col->type    = OCI_CDT_REF;
00612 
00613             break;
00614 
00615         case SQLT_CHR:
00616         case SQLT_STR:
00617         case SQLT_VCS:
00618         case SQLT_AFC:
00619         case SQLT_AVC:
00620         case SQLT_VST:
00621         case SQLT_LAB:
00622         case SQLT_OSL:
00623         case SQLT_SLS:
00624         default:
00625 
00626             col->icode   = SQLT_STR;
00627             col->type    = OCI_CDT_TEXT;
00628             col->bufsize = (ub4) ((col->size + 1) * (ub2) sizeof(dtext));
00629 
00630             if (OCILib.nls_utf8 == TRUE)
00631             {
00632                 col->bufsize *= UTF8_BYTES_PER_CHAR;
00633             }
00634 
00635             break;
00636     }
00637 
00638     return res;
00639 }
00640 
00641 /* ********************************************************************************************* *
00642  *                            PUBLIC FUNCTIONS
00643  * ********************************************************************************************* */
00644 
00645 /* --------------------------------------------------------------------------------------------- *
00646  * OCI_ColumnGetName
00647  * --------------------------------------------------------------------------------------------- */
00648 
00649 const mtext * OCI_API OCI_ColumnGetName
00650 (
00651     OCI_Column *col
00652 )
00653 {
00654     OCI_CHECK_PTR(OCI_IPC_COLUMN, col, NULL);
00655 
00656     return col->name;
00657 }
00658 
00659 /* --------------------------------------------------------------------------------------------- *
00660  * OCI_ColumnGetType
00661  * --------------------------------------------------------------------------------------------- */
00662 
00663 unsigned int OCI_API OCI_ColumnGetType
00664 (
00665     OCI_Column *col
00666 )
00667 {
00668     OCI_CHECK_PTR(OCI_IPC_COLUMN, col, OCI_UNKNOWN);
00669 
00670     OCI_RESULT(TRUE);
00671 
00672     return col->type;
00673 }
00674 
00675 /* --------------------------------------------------------------------------------------------- *
00676  * OCI_ColumnGetCharsetForm
00677  * --------------------------------------------------------------------------------------------- */
00678 
00679 unsigned int OCI_API OCI_ColumnGetCharsetForm
00680 (
00681     OCI_Column *col
00682 )
00683 {
00684     OCI_CHECK_PTR(OCI_IPC_COLUMN, col, OCI_CSF_NONE);
00685 
00686     OCI_RESULT(TRUE);
00687 
00688     if (col->csfrm == SQLCS_NCHAR)
00689         return OCI_CSF_NATIONAL;
00690     else if (col->csfrm == SQLCS_IMPLICIT)
00691         return OCI_CSF_DEFAULT;
00692     else
00693         return OCI_CSF_NONE;
00694 }
00695 
00696 /* --------------------------------------------------------------------------------------------- *
00697  * OCI_ColumnGetSize
00698  * --------------------------------------------------------------------------------------------- */
00699 
00700 unsigned int OCI_API OCI_ColumnGetSize
00701 (
00702     OCI_Column *col
00703 )
00704 {
00705     OCI_CHECK_PTR(OCI_IPC_COLUMN, col, 0);
00706 
00707     OCI_RESULT(TRUE);
00708 
00709     /* Oracle 9i introduced CHAR attribute on string columns to indicate the
00710        size of the column is not in bytes (default) but in chars
00711        OCI_ColumnDescribe() already managed the Oracle compatibly
00712        version, so if col->charsize is zero it means :
00713        - the column is not a string column
00714        - the size is not in char
00715        - client does not support the OCI_ATTR_CHAR_SIZE attribute */
00716 
00717     if (col->charused == TRUE && col->charsize > 0)
00718         return col->charsize;
00719     else
00720         return col->size;
00721 }
00722 
00723 /* --------------------------------------------------------------------------------------------- *
00724  * OCI_ColumnGetScale
00725  * --------------------------------------------------------------------------------------------- */
00726 
00727 int OCI_API OCI_ColumnGetScale
00728 (
00729     OCI_Column *col
00730 )
00731 {
00732     OCI_CHECK_PTR(OCI_IPC_COLUMN, col, 0);
00733 
00734     OCI_RESULT(TRUE);
00735 
00736     return (int) col->scale;
00737 }
00738 
00739 /* --------------------------------------------------------------------------------------------- *
00740  * OCI_ColumnGetPrecision
00741  * --------------------------------------------------------------------------------------------- */
00742 
00743 int OCI_API OCI_ColumnGetPrecision
00744 (
00745     OCI_Column *col
00746 )
00747 {
00748     OCI_CHECK_PTR(OCI_IPC_COLUMN, col, 0);
00749 
00750     OCI_RESULT(TRUE);
00751 
00752     if (col->type == OCI_CDT_NUMERIC)
00753         return (int) col->prec;
00754     else
00755         return 0;
00756 }
00757 
00758 /* --------------------------------------------------------------------------------------------- *
00759  * OCI_ColumnGetFractionalPrecision
00760  * --------------------------------------------------------------------------------------------- */
00761 
00762 int OCI_API OCI_ColumnGetFractionalPrecision
00763 (
00764     OCI_Column *col
00765 )
00766 {
00767     OCI_CHECK_PTR(OCI_IPC_COLUMN, col, 0);
00768 
00769     OCI_RESULT(TRUE);
00770 
00771     if (col->type == OCI_CDT_TIMESTAMP)
00772         return (int) col->prec;
00773     else if (col->type == OCI_CDT_INTERVAL)
00774         return (int) col->prec2;
00775     else
00776         return 0;
00777 }
00778 
00779 /* --------------------------------------------------------------------------------------------- *
00780  * OCI_ColumnGetLeadingPrecision
00781  * --------------------------------------------------------------------------------------------- */
00782 
00783 int OCI_API OCI_ColumnGetLeadingPrecision
00784 (
00785     OCI_Column *col
00786 )
00787 {
00788     OCI_CHECK_PTR(OCI_IPC_COLUMN, col, 0);
00789 
00790     OCI_RESULT(TRUE);
00791 
00792     if (col->type == OCI_CDT_INTERVAL)
00793         return (int) col->prec;
00794     else
00795         return 0;
00796 }
00797 
00798 /* --------------------------------------------------------------------------------------------- *
00799  * OCI_ColumnGetNullable
00800  * --------------------------------------------------------------------------------------------- */
00801 
00802 boolean OCI_API OCI_ColumnGetNullable
00803 (
00804     OCI_Column *col
00805 )
00806 {
00807     OCI_CHECK_PTR(OCI_IPC_COLUMN, col, FALSE);
00808 
00809     OCI_RESULT(TRUE);
00810 
00811     return (col->null == TRUE);
00812 }
00813 
00814 /* --------------------------------------------------------------------------------------------- *
00815  * OCI_ColumnGetCharUsed
00816  * --------------------------------------------------------------------------------------------- */
00817 
00818 boolean OCI_API OCI_ColumnGetCharUsed
00819 (
00820     OCI_Column *col
00821 )
00822 {
00823     OCI_CHECK_PTR(OCI_IPC_COLUMN, col, FALSE);
00824 
00825     OCI_RESULT(TRUE);
00826 
00827     return (boolean) col->charused;
00828 }
00829 
00830 /* --------------------------------------------------------------------------------------------- *
00831  * OCI_ColumnGetSQLType
00832  * --------------------------------------------------------------------------------------------- */
00833 
00834 const mtext * OCI_API OCI_ColumnGetSQLType
00835 (
00836     OCI_Column *col
00837 )
00838 {
00839     OCI_CHECK_PTR(OCI_IPC_COLUMN, col, NULL);
00840 
00841     /* VARCHAR type will not be returned because Oracle does not make any
00842        difference with VARCHAR2. If a column is created with VARCHAR, it is
00843        internally created as VARCHAR2
00844     */
00845 
00846     OCI_RESULT(TRUE);
00847 
00848     switch(col->ocode)
00849     {
00850         case SQLT_AFC:
00851 
00852             if (col->csfrm == SQLCS_NCHAR)
00853                 return MT("NCHAR");
00854             else
00855                 return MT("CHAR");
00856 
00857         case SQLT_AVC:
00858         case SQLT_STR:
00859         case SQLT_CHR:
00860 
00861             if (col->csfrm == SQLCS_NCHAR)
00862                 return MT("NVARCHAR2");
00863             else
00864                 return MT("VARCHAR2");
00865 
00866         case SQLT_NUM:
00867 
00868             if (col->scale == -127 && col->prec > 0)
00869                 return MT("FLOAT");
00870             else
00871                 return MT("NUMBER");
00872 
00873         case SQLT_INT:
00874 
00875             return MT("INTEGER");
00876 
00877         case SQLT_FLT:
00878 
00879             return MT("FLOAT");
00880 
00881             #if OCI_VERSION_COMPILE >= OCI_10_1
00882 
00883         case SQLT_BFLOAT:
00884         case SQLT_IBFLOAT:
00885 
00886             return MT("BINARY FLOAT");
00887 
00888         case SQLT_BDOUBLE:
00889         case SQLT_IBDOUBLE:
00890 
00891             return MT("BINARY DOUBLE");
00892 
00893             #endif
00894 
00895         case SQLT_LNG:
00896 
00897             return MT("LONG");
00898 
00899         case SQLT_DAT:
00900         case SQLT_ODT:
00901         case SQLT_DATE:
00902 
00903             return MT("DATE");
00904 
00905         case SQLT_RDD:
00906         case SQLT_RID:
00907 
00908             return MT("ROWID");
00909 
00910         case SQLT_BIN:
00911 
00912             return MT("RAW");
00913 
00914         case SQLT_LBI:
00915 
00916             return MT("LONG RAW");
00917 
00918         case SQLT_RSET:
00919 
00920             return MT("RESULTSET");
00921 
00922         case SQLT_CUR:
00923 
00924             return MT("CURSOR");
00925 
00926         case SQLT_CLOB:
00927 
00928             if (col->subtype == OCI_NCLOB)
00929                 return MT("NCLOB");
00930             else
00931                 return MT("CLOB");
00932 
00933         case SQLT_BLOB:
00934 
00935             return MT("BLOB");
00936 
00937         case SQLT_BFILE:
00938 
00939             return MT("BINARY FILE LOB");
00940 
00941         case SQLT_CFILE:
00942 
00943             return MT("CFILE");
00944 
00945             #if OCI_VERSION_COMPILE >= OCI_9_0
00946 
00947         case SQLT_TIMESTAMP:
00948 
00949             return MT("TIMESTAMP");
00950 
00951         case SQLT_TIMESTAMP_TZ:
00952 
00953             return MT("TIMESTAMP WITH TIME ZONE");
00954 
00955         case SQLT_TIMESTAMP_LTZ:
00956 
00957             return MT("TIMESTAMP WITH LOCAL TIME ZONE");
00958 
00959         case SQLT_INTERVAL_YM:
00960 
00961             return MT("INTERVAL YEAR TO MONTH");
00962 
00963         case SQLT_INTERVAL_DS:
00964 
00965             return MT("INTERVAL DAY TO SECOND");
00966 
00967             #endif
00968 
00969         case SQLT_REF:
00970 
00971             return MT("REF");
00972 
00973             #if OCI_VERSION_COMPILE >= OCI_9_0
00974 
00975         case SQLT_PNTY:
00976             #endif
00977 
00978         case SQLT_NTY:
00979 
00980             if (col->typinf != NULL)
00981                 return col->typinf->name;
00982             else
00983                 return MT("NAMED TYPE");
00984 
00985         default:
00986 
00987             /* unknown datatype ? Should not happen because all
00988                  datatypes are supported */
00989 
00990             return MT("?");
00991     }
00992 }
00993 
00994 /* --------------------------------------------------------------------------------------------- *
00995  * OCI_ColumnGetFullSQLType
00996  * --------------------------------------------------------------------------------------------- */
00997 
00998 unsigned int OCI_API OCI_ColumnGetFullSQLType
00999 (
01000     OCI_Column  *col,
01001     mtext       *buffer,
01002     unsigned int len
01003 )
01004 {
01005     OCI_CHECK_PTR(OCI_IPC_COLUMN, col, 0);
01006     OCI_CHECK_PTR(OCI_IPC_STRING, buffer, 0);
01007 
01008     OCI_RESULT(TRUE);
01009 
01010     buffer[0] = 0;
01011 
01012     /* ISO C functions are supposed to be "standard", but we still see specific
01013        implementations that make some usage not portable and worse not compatible.
01014        MS Windows is implementing string conversion characters (%s/%ls) of the
01015        printf/wprintf family differently from unixes !
01016     */
01017 
01018     /* This function returns the same strings as Sql*Plus DESC command */
01019 
01020     switch(col->ocode)
01021     {
01022         case SQLT_AFC:
01023 
01024             #if defined(OCI_METADATA_WIDE) && !defined(_WINDOWS)
01025             len = mtsprintf(buffer, len, MT("%lsCHAR(%i%ls)"),
01026             #else
01027             len = mtsprintf(buffer, len, MT("%sCHAR(%i%s)"),
01028                             #endif
01029                             col->csfrm    == SQLCS_NCHAR ? MT("N") : MT(""),
01030                             (int) (col->charused == TRUE ? col->charsize : col->size),
01031                             col->charused == TRUE &&
01032                             col->csfrm    != SQLCS_NCHAR ? MT(" CHAR") : MT(""));
01033             break;
01034 
01035         case SQLT_AVC:
01036         case SQLT_STR:
01037         case SQLT_CHR:
01038 
01039             #if defined(OCI_METADATA_WIDE) && !defined(_WINDOWS)
01040             len = mtsprintf(buffer, len, MT("%lsVARCHAR(%i%ls)"),
01041             #else
01042             len = mtsprintf(buffer, len, MT("%sVARCHAR(%i%s)"),
01043                             #endif
01044                             col->csfrm    == SQLCS_NCHAR ? MT("N") : MT(""),
01045                             (int) (col->charused == TRUE ? col->charsize : col->size),
01046                             col->charused == TRUE &&
01047                             col->csfrm    != SQLCS_NCHAR ? MT(" CHAR") : MT(""));
01048             break;
01049 
01050         case SQLT_NUM:
01051 
01052             if (col->scale == -127 && col->prec > 0)
01053                 len = mtsprintf(buffer, len,  MT("FLOAT(%i)"), col->prec);
01054             else if (col->scale > 0 && col->prec > 0)
01055                 len = mtsprintf(buffer, len,  MT("NUMBER(%i,%i)"),
01056                                 (int) col->prec, (int) col->scale);
01057             else if (col->prec > 0)
01058                 len = mtsprintf(buffer, len,  MT("NUMBER(%i)"), (int) col->prec);
01059             else
01060                 len = mtsprintf(buffer, len,  MT("NUMBER"));
01061 
01062             break;
01063 
01064         case SQLT_INT:
01065 
01066             len = mtsprintf(buffer, len,  MT("NUMBER"));
01067             break;
01068 
01069         case SQLT_FLT:
01070 
01071             len = mtsprintf(buffer, len,  MT("FLOAT(%i)"), (int) col->prec);
01072             break;
01073 
01074             #if OCI_VERSION_COMPILE >= OCI_10_1
01075 
01076         case SQLT_BFLOAT:
01077         case SQLT_IBFLOAT:
01078 
01079             len = mtsprintf(buffer, len,  MT("BINARY FLOAT"));
01080             break;
01081 
01082         case SQLT_BDOUBLE:
01083         case SQLT_IBDOUBLE:
01084 
01085             len = mtsprintf(buffer, len,  MT("BINARY DOUBLE"));
01086             break;
01087 
01088             #endif
01089 
01090         case SQLT_LNG:
01091 
01092             len = mtsprintf(buffer, len, MT("LONG"));
01093             break;
01094 
01095         case SQLT_DAT:
01096         case SQLT_ODT:
01097         case SQLT_DATE:
01098 
01099             len = mtsprintf(buffer, len, MT("DATE"));
01100             break;
01101 
01102         case SQLT_RDD:
01103         case SQLT_RID:
01104 
01105             len = mtsprintf(buffer, len,  MT("ROWID"));
01106             break;
01107 
01108         case SQLT_BIN:
01109             len = mtsprintf(buffer, len, MT("RAW(%i)"), (int) col->size);
01110             break;
01111 
01112         case SQLT_LBI:
01113 
01114             len = mtsprintf(buffer, len, MT("LONG RAW(%i)"), (int) col->size);
01115             break;
01116 
01117         case SQLT_RSET:
01118 
01119             len = mtsprintf(buffer, len,  MT("RESULTSET"));
01120             break;
01121 
01122         case SQLT_CUR:
01123 
01124             len = mtsprintf(buffer, len,  MT("CURSOR"));
01125             break;
01126 
01127         case SQLT_CLOB:
01128 
01129             if (col->subtype == OCI_NCLOB)
01130                 len = mtsprintf(buffer, len,  MT("NCLOB"));
01131             else
01132                 len = mtsprintf(buffer, len,  MT("CLOB"));
01133             break;
01134 
01135         case SQLT_BLOB:
01136 
01137             len = mtsprintf(buffer, len,  MT("BLOB"));
01138             break;
01139 
01140         case SQLT_BFILE:
01141 
01142             len = mtsprintf(buffer, len,  MT("BINARY FILE LOB"));
01143             break;
01144 
01145         case SQLT_CFILE:
01146 
01147             len = mtsprintf(buffer, len,  MT("CFILE"));
01148             break;
01149 
01150             #if OCI_VERSION_COMPILE >= OCI_9_0
01151 
01152         case SQLT_TIMESTAMP:
01153 
01154             len = mtsprintf(buffer, len,  MT("TIMESTAMP(%i)"), (int) col->prec);
01155             break;
01156 
01157         case SQLT_TIMESTAMP_TZ:
01158 
01159             len = mtsprintf(buffer, len,  MT("TIMESTAMP(%i) WITH TIME ZONE"),
01160                             (int) col->prec);
01161             break;
01162 
01163         case SQLT_TIMESTAMP_LTZ:
01164 
01165             len = mtsprintf(buffer, len,  MT("TIMESTAMP(%i) WITH LOCAL TIME ZONE"),
01166                             (int) col->prec);
01167             break;
01168 
01169         case SQLT_INTERVAL_YM:
01170 
01171             len = mtsprintf(buffer, len,  MT("INTERVAL(%i) YEAR TO MONTH(%i)"),
01172                             (int) col->prec, (int) col->prec2);
01173             break;
01174 
01175         case SQLT_INTERVAL_DS:
01176 
01177             len = mtsprintf(buffer, len,  MT("INTERVAL(%i) DAY TO SECOND(%i)"),
01178                             (int) col->prec, (int) col->prec2);
01179             break;
01180 
01181             #endif
01182 
01183         case SQLT_REF:
01184 
01185             len = mtsprintf(buffer, len,  MT("REF"));
01186             break;
01187 
01188             #if OCI_VERSION_COMPILE >= OCI_9_0
01189 
01190         case SQLT_PNTY:
01191             #endif
01192 
01193         case SQLT_NTY:
01194 
01195             if (col->typinf != NULL)
01196                 len = mtsprintf(buffer, len, col->typinf->name);
01197             else
01198                 len = mtsprintf(buffer, len, MT("NAMED TYPE"));
01199             break;
01200 
01201         default:
01202 
01203             mtsncat(buffer, MT("?"), (size_t) len);
01204     }
01205 
01206     return len;
01207 }
01208 
01209 /* --------------------------------------------------------------------------------------------- *
01210  * OCI_ColumnGetTypeInfo
01211  * --------------------------------------------------------------------------------------------- */
01212 
01213 OCI_TypeInfo * OCI_API OCI_ColumnGetTypeInfo
01214 (
01215     OCI_Column *col
01216 )
01217 {
01218     OCI_CHECK_PTR(OCI_IPC_COLUMN, col, NULL);
01219 
01220     OCI_RESULT(TRUE);
01221 
01222     return col->typinf;
01223 }
01224 
01225 /* --------------------------------------------------------------------------------------------- *
01226  * OCI_ColumnGetSubType
01227  * --------------------------------------------------------------------------------------------- */
01228 
01229 unsigned int OCI_API OCI_ColumnGetSubType
01230 (
01231     OCI_Column *col
01232 )
01233 {
01234     unsigned int type = OCI_UNKNOWN;
01235 
01236     OCI_CHECK_PTR(OCI_IPC_COLUMN, col, OCI_UNKNOWN);
01237 
01238     OCI_RESULT(TRUE);
01239 
01240     if (col->type == OCI_CDT_LONG      ||
01241         col->type == OCI_CDT_LOB       ||
01242         col->type == OCI_CDT_FILE      ||
01243         col->type == OCI_CDT_TIMESTAMP ||
01244         col->type == OCI_CDT_INTERVAL)
01245     {
01246         type = col->subtype;
01247     }
01248 
01249     return type;
01250 }

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