• 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.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_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         col->type    = OCI_CDT_NUMERIC;
00396         col->subtype = OCI_NUM_NUMBER;
00397         col->icode   = SQLT_VNU;
00398         col->bufsize = sizeof(OCINumber);
00399 
00400         break;
00401 
00402     case SQLT_DAT:
00403     case SQLT_ODT:
00404 
00405         col->type = OCI_CDT_DATETIME;
00406 
00407         /* We map to SQLT_ODT only it the column is not part of a
00408            "returning into" clause (workaround for Oracle
00409            known bug #3269146
00410         */
00411 
00412         if (col->bufsize == 0)
00413         {
00414             col->icode   = SQLT_ODT;
00415             col->bufsize = sizeof(OCIDate);
00416         }
00417 
00418         break;
00419 
00420     case SQLT_CUR:
00421     case SQLT_RSET:
00422 
00423         col->type    = OCI_CDT_CURSOR;
00424         col->bufsize = sizeof(OCIStmt *);
00425         col->dtype   = OCI_HTYPE_STMT;
00426         break;
00427 
00428     case SQLT_RID:
00429     case SQLT_RDD:
00430 
00431         col->icode = SQLT_STR;
00432         col->type  = OCI_CDT_TEXT;
00433 
00434         if ((col->ocode == SQLT_RDD) || (col->size > sizeof(OCIRowid *)))
00435         {
00436             /* For Oracle 7 ROWIDs and regular ROWID descriptors, the
00437                max size of the hex value is defined by the constant
00438                OCI_SIZE_ROWID
00439             */
00440 
00441             col->bufsize = (OCI_SIZE_ROWID + 1) * (ub4) sizeof(dtext);
00442         }
00443         else
00444         {
00445             /* For ROWID descriptor, if column size is bigger than the size
00446                 of the descriptor, it means that an UROWID column and then
00447                 the column size is the maximum size needed for representing
00448                 its value as an hex string
00449             */
00450 
00451             col->bufsize = (ub4) ((col->size + 1) * (ub2) sizeof(dtext));
00452         }
00453 
00454         break;
00455 
00456     case SQLT_BIN:
00457 
00458         /* adding one extra character space for string conversion */
00459 
00460         col->type    = OCI_CDT_RAW;
00461         col->bufsize = (ub4) (col->size + (ub2) sizeof(dtext));
00462         break;
00463 
00464     case SQLT_BLOB:
00465 
00466         col->type    = OCI_CDT_LOB;
00467         col->subtype = OCI_BLOB;
00468         col->dtype   = OCI_DTYPE_LOB;
00469         col->bufsize = (ub4) sizeof(OCILobLocator *);
00470         break;
00471 
00472     case SQLT_CLOB:
00473 
00474         col->type    = OCI_CDT_LOB;
00475         col->dtype   = OCI_DTYPE_LOB;
00476         col->bufsize = (ub4) sizeof(OCILobLocator *);
00477 
00478         if (col->csfrm == SQLCS_NCHAR)
00479             col->subtype = OCI_NCLOB;
00480         else
00481             col->subtype = OCI_CLOB;
00482 
00483         break;
00484 
00485     case SQLT_BFILE:
00486 
00487         col->type    = OCI_CDT_FILE;
00488         col->subtype = OCI_BFILE;
00489         col->dtype   = OCI_DTYPE_LOB;
00490         col->bufsize = (ub4) sizeof(OCILobLocator *);
00491         break;
00492 
00493     case SQLT_CFILE:
00494 
00495         col->type    = OCI_CDT_FILE;
00496         col->subtype = OCI_CFILE;
00497         col->bufsize = (ub4) sizeof(OCILobLocator *);
00498         col->dtype   = OCI_DTYPE_LOB;
00499         break;
00500 
00501     case SQLT_LNG:
00502     case SQLT_LVC:
00503     case SQLT_LBI:
00504     case SQLT_LVB:
00505     case SQLT_VBI:
00506 
00507         if ((col->icode == SQLT_LNG || col->icode == SQLT_LVC) &&
00508             (stmt != NULL && stmt->long_mode == OCI_LONG_IMPLICIT))
00509         {
00510             col->type    = OCI_CDT_TEXT;
00511             col->bufsize = (OCI_SIZE_LONG+1) * ((ub2) sizeof(dtext));
00512             col->subtype = OCI_CLONG;
00513 
00514             if (OCILib.nls_utf8 == TRUE)
00515             {
00516                 col->bufsize *= UTF8_BYTES_PER_CHAR;
00517             }
00518         }
00519         else
00520         {
00521             col->type    = OCI_CDT_LONG;
00522             col->bufsize = INT_MAX;
00523 
00524             if (col->icode == SQLT_LBI ||
00525                 col->icode == SQLT_LVB ||
00526                 col->icode == SQLT_VBI)
00527             {
00528                 col->subtype = OCI_BLONG;
00529             }
00530             else
00531             {
00532                 col->subtype = OCI_CLONG;
00533             }
00534 
00535         }
00536 
00537         break;
00538 
00539         #if OCI_VERSION_COMPILE >= OCI_9_0
00540 
00541     case SQLT_TIMESTAMP:
00542 
00543         col->type    = OCI_CDT_TIMESTAMP;
00544         col->subtype = OCI_TIMESTAMP;
00545         col->dtype   = OCI_DTYPE_TIMESTAMP;
00546         col->bufsize = (ub4) sizeof(OCIDateTime *);
00547         break;
00548 
00549     case SQLT_TIMESTAMP_TZ:
00550 
00551         col->type    = OCI_CDT_TIMESTAMP;
00552         col->subtype = OCI_TIMESTAMP_TZ;
00553         col->dtype   = OCI_DTYPE_TIMESTAMP_TZ;
00554         col->bufsize = (ub4) sizeof(OCIDateTime *);
00555         break;
00556 
00557     case SQLT_TIMESTAMP_LTZ:
00558 
00559         col->type    = OCI_CDT_TIMESTAMP;
00560         col->subtype = OCI_TIMESTAMP_LTZ;
00561         col->dtype   = OCI_DTYPE_TIMESTAMP_LTZ;
00562         col->bufsize = (ub4) sizeof(OCIDateTime *);
00563         break;
00564 
00565     case SQLT_INTERVAL_YM:
00566 
00567         col->type    = OCI_CDT_INTERVAL;
00568         col->subtype = OCI_INTERVAL_YM;
00569         col->dtype   = OCI_DTYPE_INTERVAL_YM;
00570         col->bufsize = (ub4) sizeof(OCIInterval *);
00571         break;
00572 
00573     case SQLT_INTERVAL_DS:
00574 
00575         col->type    = OCI_CDT_INTERVAL;
00576         col->subtype = OCI_INTERVAL_DS;
00577         col->dtype   = OCI_DTYPE_INTERVAL_DS;
00578         col->bufsize = (ub4) sizeof(OCIInterval *);
00579         break;
00580 
00581         #endif
00582 
00583         #if OCI_VERSION_COMPILE >= OCI_9_0
00584 
00585     case SQLT_PNTY:
00586 
00587         #endif
00588 
00589     case SQLT_NTY:
00590 
00591         col->icode   = SQLT_NTY;
00592         col->bufsize = (ub4) sizeof(void *);
00593 
00594         if (col->typinf->tcode == SQLT_NCO)
00595             col->type = OCI_CDT_COLLECTION;
00596         else
00597             col->type = OCI_CDT_OBJECT;
00598 
00599         break;
00600 
00601     case SQLT_REF:
00602 
00603         col->icode   = SQLT_REF;
00604         col->bufsize = (ub4) sizeof(OCIRef *);
00605         col->type    = OCI_CDT_REF;
00606 
00607         break;
00608 
00609     case SQLT_CHR:
00610     case SQLT_STR:
00611     case SQLT_VCS:
00612     case SQLT_AFC:
00613     case SQLT_AVC:
00614     case SQLT_VST:
00615     case SQLT_LAB:
00616     case SQLT_OSL:
00617     case SQLT_SLS:
00618     default:
00619 
00620         col->icode   = SQLT_STR;
00621         col->type    = OCI_CDT_TEXT;
00622         col->bufsize = (ub4) ((col->size + 1) * (ub2) sizeof(dtext));
00623 
00624         if (OCILib.nls_utf8 == TRUE)
00625         {
00626             col->bufsize *= UTF8_BYTES_PER_CHAR;
00627         }
00628 
00629         break;
00630     }
00631 
00632     return res;
00633 }
00634 
00635 /* ********************************************************************************************* *
00636  *                            PUBLIC FUNCTIONS
00637  * ********************************************************************************************* */
00638 
00639 /* --------------------------------------------------------------------------------------------- *
00640  * OCI_ColumnGetName
00641  * --------------------------------------------------------------------------------------------- */
00642 
00643 const mtext * OCI_API OCI_ColumnGetName
00644 (
00645     OCI_Column *col
00646 )
00647 {
00648     OCI_CHECK_PTR(OCI_IPC_COLUMN, col, NULL);
00649 
00650     return col->name;
00651 }
00652 
00653 /* --------------------------------------------------------------------------------------------- *
00654  * OCI_ColumnGetType
00655  * --------------------------------------------------------------------------------------------- */
00656 
00657 unsigned int OCI_API OCI_ColumnGetType
00658 (
00659     OCI_Column *col
00660 )
00661 {
00662     OCI_CHECK_PTR(OCI_IPC_COLUMN, col, OCI_UNKNOWN);
00663 
00664     OCI_RESULT(TRUE);
00665 
00666     return col->type;
00667 }
00668 
00669 /* --------------------------------------------------------------------------------------------- *
00670  * OCI_ColumnGetCharsetForm
00671  * --------------------------------------------------------------------------------------------- */
00672 
00673 unsigned int OCI_API OCI_ColumnGetCharsetForm
00674 (
00675     OCI_Column *col
00676 )
00677 {
00678     OCI_CHECK_PTR(OCI_IPC_COLUMN, col, OCI_CSF_NONE);
00679 
00680     OCI_RESULT(TRUE);
00681 
00682     if (col->csfrm == SQLCS_NCHAR)
00683         return OCI_CSF_NATIONAL;
00684     else if (col->csfrm == SQLCS_IMPLICIT)
00685         return OCI_CSF_DEFAULT;
00686     else
00687         return OCI_CSF_NONE;
00688 }
00689 
00690 /* --------------------------------------------------------------------------------------------- *
00691  * OCI_ColumnGetSize
00692  * --------------------------------------------------------------------------------------------- */
00693 
00694 unsigned int OCI_API OCI_ColumnGetSize
00695 (
00696     OCI_Column *col
00697 )
00698 {
00699     OCI_CHECK_PTR(OCI_IPC_COLUMN, col, 0);
00700 
00701     OCI_RESULT(TRUE);
00702 
00703     /* Oracle 9i introduced CHAR attribute on string columns to indicate the
00704        size of the column is not in bytes (default) but in chars
00705        OCI_ColumnDescribe() already managed the Oracle compatibly
00706        version, so if col->charsize is zero it means :
00707        - the column is not a string column
00708        - the size is not in char
00709        - client does not support the OCI_ATTR_CHAR_SIZE attribute */
00710 
00711     if (col->charused == TRUE && col->charsize > 0)
00712         return col->charsize;
00713     else
00714         return col->size;
00715 }
00716 
00717 /* --------------------------------------------------------------------------------------------- *
00718  * OCI_ColumnGetScale
00719  * --------------------------------------------------------------------------------------------- */
00720 
00721 int OCI_API OCI_ColumnGetScale
00722 (
00723     OCI_Column *col
00724 )
00725 {
00726     OCI_CHECK_PTR(OCI_IPC_COLUMN, col, 0);
00727 
00728     OCI_RESULT(TRUE);
00729 
00730     return (int) col->scale;
00731 }
00732 
00733 /* --------------------------------------------------------------------------------------------- *
00734  * OCI_ColumnGetPrecision
00735  * --------------------------------------------------------------------------------------------- */
00736 
00737 int OCI_API OCI_ColumnGetPrecision
00738 (
00739     OCI_Column *col
00740 )
00741 {
00742     OCI_CHECK_PTR(OCI_IPC_COLUMN, col, 0);
00743 
00744     OCI_RESULT(TRUE);
00745 
00746     if (col->type == OCI_CDT_NUMERIC)
00747         return (int) col->prec;
00748     else
00749         return 0;
00750 }
00751 
00752 /* --------------------------------------------------------------------------------------------- *
00753  * OCI_ColumnGetFractionalPrecision
00754  * --------------------------------------------------------------------------------------------- */
00755 
00756 int OCI_API OCI_ColumnGetFractionalPrecision
00757 (
00758     OCI_Column *col
00759 )
00760 {
00761     OCI_CHECK_PTR(OCI_IPC_COLUMN, col, 0);
00762 
00763     OCI_RESULT(TRUE);
00764 
00765     if (col->type == OCI_CDT_TIMESTAMP)
00766         return (int) col->prec;
00767     else if (col->type == OCI_CDT_INTERVAL)
00768         return (int) col->prec2;
00769     else
00770         return 0;
00771 }
00772 
00773 /* --------------------------------------------------------------------------------------------- *
00774  * OCI_ColumnGetLeadingPrecision
00775  * --------------------------------------------------------------------------------------------- */
00776 
00777 int OCI_API OCI_ColumnGetLeadingPrecision
00778 (
00779     OCI_Column *col
00780 )
00781 {
00782     OCI_CHECK_PTR(OCI_IPC_COLUMN, col, 0);
00783 
00784     OCI_RESULT(TRUE);
00785 
00786     if (col->type == OCI_CDT_INTERVAL)
00787         return (int) col->prec;
00788     else
00789         return 0;
00790 }
00791 
00792 /* --------------------------------------------------------------------------------------------- *
00793  * OCI_ColumnGetNullable
00794  * --------------------------------------------------------------------------------------------- */
00795 
00796 boolean OCI_API OCI_ColumnGetNullable
00797 (
00798     OCI_Column *col
00799 )
00800 {
00801     OCI_CHECK_PTR(OCI_IPC_COLUMN, col, FALSE);
00802 
00803     OCI_RESULT(TRUE);
00804 
00805     return (col->null == TRUE);
00806 }
00807 
00808 /* --------------------------------------------------------------------------------------------- *
00809  * OCI_ColumnGetCharUsed
00810  * --------------------------------------------------------------------------------------------- */
00811 
00812 boolean OCI_API OCI_ColumnGetCharUsed
00813 (
00814     OCI_Column *col
00815 )
00816 {
00817     OCI_CHECK_PTR(OCI_IPC_COLUMN, col, FALSE);
00818 
00819     OCI_RESULT(TRUE);
00820 
00821     return (boolean) col->charused;
00822 }
00823 
00824 /* --------------------------------------------------------------------------------------------- *
00825  * OCI_ColumnGetSQLType
00826  * --------------------------------------------------------------------------------------------- */
00827 
00828 const mtext * OCI_API OCI_ColumnGetSQLType
00829 (
00830     OCI_Column *col
00831 )
00832 {
00833     OCI_CHECK_PTR(OCI_IPC_COLUMN, col, NULL);
00834 
00835     /* VARCHAR type will not be returned because Oracle does not make any
00836        difference with VARCHAR2. If a column is created with VARCHAR, it is
00837        internally created as VARCHAR2
00838     */
00839 
00840     OCI_RESULT(TRUE);
00841 
00842     switch(col->ocode)
00843     {
00844     case SQLT_AFC:
00845 
00846         if (col->csfrm == SQLCS_NCHAR)
00847             return MT("NCHAR");
00848         else
00849             return MT("CHAR");
00850 
00851     case SQLT_AVC:
00852     case SQLT_STR:
00853     case SQLT_CHR:
00854 
00855         if (col->csfrm == SQLCS_NCHAR)
00856             return MT("NVARCHAR2");
00857         else
00858             return MT("VARCHAR2");
00859 
00860     case SQLT_NUM:
00861 
00862         if (col->scale == -127 && col->prec > 0)
00863             return MT("FLOAT");
00864         else
00865             return MT("NUMBER");
00866 
00867     case SQLT_INT:
00868 
00869         return MT("INTEGER");
00870 
00871     case SQLT_FLT:
00872 
00873         return MT("FLOAT");
00874 
00875         #if OCI_VERSION_COMPILE >= OCI_10_1
00876 
00877     case SQLT_BFLOAT:
00878     case SQLT_IBFLOAT:
00879 
00880         return MT("BINARY FLOAT");
00881 
00882     case SQLT_BDOUBLE:
00883     case SQLT_IBDOUBLE:
00884 
00885         return MT("BINARY DOUBLE");
00886 
00887         #endif
00888 
00889     case SQLT_LNG:
00890 
00891         return MT("LONG");
00892 
00893     case SQLT_DAT:
00894     case SQLT_ODT:
00895     case SQLT_DATE:
00896 
00897         return MT("DATE");
00898 
00899     case SQLT_RDD:
00900     case SQLT_RID:
00901 
00902         return MT("ROWID");
00903 
00904     case SQLT_BIN:
00905 
00906         return MT("RAW");
00907 
00908     case SQLT_LBI:
00909 
00910         return MT("LONG RAW");
00911 
00912     case SQLT_RSET:
00913 
00914         return MT("RESULTSET");
00915 
00916     case SQLT_CUR:
00917 
00918         return MT("CURSOR");
00919 
00920     case SQLT_CLOB:
00921 
00922         if (col->subtype == OCI_NCLOB)
00923             return MT("NCLOB");
00924         else
00925             return MT("CLOB");
00926 
00927     case SQLT_BLOB:
00928 
00929         return MT("BLOB");
00930 
00931     case SQLT_BFILE:
00932 
00933         return MT("BINARY FILE LOB");
00934 
00935     case SQLT_CFILE:
00936 
00937         return MT("CFILE");
00938 
00939         #if OCI_VERSION_COMPILE >= OCI_9_0
00940 
00941     case SQLT_TIMESTAMP:
00942 
00943         return MT("TIMESTAMP");
00944 
00945     case SQLT_TIMESTAMP_TZ:
00946 
00947         return MT("TIMESTAMP WITH TIME ZONE");
00948 
00949     case SQLT_TIMESTAMP_LTZ:
00950 
00951         return MT("TIMESTAMP WITH LOCAL TIME ZONE");
00952 
00953     case SQLT_INTERVAL_YM:
00954 
00955         return MT("INTERVAL YEAR TO MONTH");
00956 
00957     case SQLT_INTERVAL_DS:
00958 
00959         return MT("INTERVAL DAY TO SECOND");
00960 
00961         #endif
00962 
00963     case SQLT_REF:
00964 
00965         return MT("REF");
00966 
00967         #if OCI_VERSION_COMPILE >= OCI_9_0
00968 
00969     case SQLT_PNTY:
00970         #endif
00971 
00972     case SQLT_NTY:
00973 
00974         if (col->typinf != NULL)
00975             return col->typinf->name;
00976         else
00977             return MT("NAMED TYPE");
00978 
00979     default:
00980 
00981         /* unknown datatype ? Should not happen because all
00982              datatypes are supported */
00983 
00984         return MT("?");
00985     }
00986 }
00987 
00988 /* --------------------------------------------------------------------------------------------- *
00989  * OCI_ColumnGetFullSQLType
00990  * --------------------------------------------------------------------------------------------- */
00991 
00992 unsigned int OCI_API OCI_ColumnGetFullSQLType
00993 (
00994     OCI_Column  *col,
00995     mtext       *buffer,
00996     unsigned int len
00997 )
00998 {
00999     OCI_CHECK_PTR(OCI_IPC_COLUMN, col, 0);
01000     OCI_CHECK_PTR(OCI_IPC_STRING, buffer, 0);
01001 
01002     OCI_RESULT(TRUE);
01003 
01004     buffer[0] = 0;
01005 
01006     /* ISO C functions are supposed to be "standard", but we still see specific
01007        implementations that make some usage not portable and worse not compatible.
01008        MS Windows is implementing string conversion characters (%s/%ls) of the
01009        printf/wprintf family differently from unixes !
01010     */
01011 
01012     /* This function returns the same strings as Sql*Plus DESC command */
01013 
01014     switch(col->ocode)
01015     {
01016     case SQLT_AFC:
01017 
01018         #if defined(OCI_METADATA_WIDE) && !defined(_WINDOWS)
01019         len = mtsprintf(buffer, len, MT("%lsCHAR(%i%ls)"),
01020         #else
01021         len = mtsprintf(buffer, len, MT("%sCHAR(%i%s)"),
01022                         #endif
01023                         col->csfrm    == SQLCS_NCHAR ? MT("N") : MT(""),
01024                         (int) (col->charused == TRUE ? col->charsize : col->size),
01025                         col->charused == TRUE &&
01026                         col->csfrm    != SQLCS_NCHAR ? MT(" CHAR") : MT(""));
01027         break;
01028 
01029     case SQLT_AVC:
01030     case SQLT_STR:
01031     case SQLT_CHR:
01032 
01033         #if defined(OCI_METADATA_WIDE) && !defined(_WINDOWS)
01034         len = mtsprintf(buffer, len, MT("%lsVARCHAR(%i%ls)"),
01035         #else
01036         len = mtsprintf(buffer, len, MT("%sVARCHAR(%i%s)"),
01037                         #endif
01038                         col->csfrm    == SQLCS_NCHAR ? MT("N") : MT(""),
01039                         (int) (col->charused == TRUE ? col->charsize : col->size),
01040                         col->charused == TRUE &&
01041                         col->csfrm    != SQLCS_NCHAR ? MT(" CHAR") : MT(""));
01042         break;
01043 
01044     case SQLT_NUM:
01045 
01046         if (col->scale == -127 && col->prec > 0)
01047             len = mtsprintf(buffer, len,  MT("FLOAT(%i)"), col->prec);
01048         else if (col->scale > 0 && col->prec > 0)
01049             len = mtsprintf(buffer, len,  MT("NUMBER(%i,%i)"),
01050                             (int) col->prec, (int) col->scale);
01051         else if (col->prec > 0)
01052             len = mtsprintf(buffer, len,  MT("NUMBER(%i)"), (int) col->prec);
01053         else
01054             len = mtsprintf(buffer, len,  MT("NUMBER"));
01055 
01056         break;
01057 
01058     case SQLT_INT:
01059 
01060         len = mtsprintf(buffer, len,  MT("NUMBER"));
01061         break;
01062 
01063     case SQLT_FLT:
01064 
01065         len = mtsprintf(buffer, len,  MT("FLOAT(%i)"), (int) col->prec);
01066         break;
01067 
01068         #if OCI_VERSION_COMPILE >= OCI_10_1
01069 
01070     case SQLT_BFLOAT:
01071     case SQLT_IBFLOAT:
01072 
01073         len = mtsprintf(buffer, len,  MT("BINARY FLOAT"));
01074         break;
01075 
01076     case SQLT_BDOUBLE:
01077     case SQLT_IBDOUBLE:
01078 
01079         len = mtsprintf(buffer, len,  MT("BINARY DOUBLE"));
01080         break;
01081 
01082         #endif
01083 
01084     case SQLT_LNG:
01085 
01086         len = mtsprintf(buffer, len, MT("LONG"));
01087         break;
01088 
01089     case SQLT_DAT:
01090     case SQLT_ODT:
01091     case SQLT_DATE:
01092 
01093         len = mtsprintf(buffer, len, MT("DATE"));
01094         break;
01095 
01096     case SQLT_RDD:
01097     case SQLT_RID:
01098 
01099         len = mtsprintf(buffer, len,  MT("ROWID"));
01100         break;
01101 
01102     case SQLT_BIN:
01103         len = mtsprintf(buffer, len, MT("RAW(%i)"), (int) col->size);
01104         break;
01105 
01106     case SQLT_LBI:
01107 
01108         len = mtsprintf(buffer, len, MT("LONG RAW(%i)"), (int) col->size);
01109         break;
01110 
01111     case SQLT_RSET:
01112 
01113         len = mtsprintf(buffer, len,  MT("RESULTSET"));
01114         break;
01115 
01116     case SQLT_CUR:
01117 
01118         len = mtsprintf(buffer, len,  MT("CURSOR"));
01119         break;
01120 
01121     case SQLT_CLOB:
01122 
01123         if (col->subtype == OCI_NCLOB)
01124             len = mtsprintf(buffer, len,  MT("NCLOB"));
01125         else
01126             len = mtsprintf(buffer, len,  MT("CLOB"));
01127         break;
01128 
01129     case SQLT_BLOB:
01130 
01131         len = mtsprintf(buffer, len,  MT("BLOB"));
01132         break;
01133 
01134     case SQLT_BFILE:
01135 
01136         len = mtsprintf(buffer, len,  MT("BINARY FILE LOB"));
01137         break;
01138 
01139     case SQLT_CFILE:
01140 
01141         len = mtsprintf(buffer, len,  MT("CFILE"));
01142         break;
01143 
01144         #if OCI_VERSION_COMPILE >= OCI_9_0
01145 
01146     case SQLT_TIMESTAMP:
01147 
01148         len = mtsprintf(buffer, len,  MT("TIMESTAMP(%i)"), (int) col->prec);
01149         break;
01150 
01151     case SQLT_TIMESTAMP_TZ:
01152 
01153         len = mtsprintf(buffer, len,  MT("TIMESTAMP(%i) WITH TIME ZONE"),
01154                         (int) col->prec);
01155         break;
01156 
01157     case SQLT_TIMESTAMP_LTZ:
01158 
01159         len = mtsprintf(buffer, len,  MT("TIMESTAMP(%i) WITH LOCAL TIME ZONE"),
01160                         (int) col->prec);
01161         break;
01162 
01163     case SQLT_INTERVAL_YM:
01164 
01165         len = mtsprintf(buffer, len,  MT("INTERVAL(%i) YEAR TO MONTH(%i)"),
01166                         (int) col->prec, (int) col->prec2);
01167         break;
01168 
01169     case SQLT_INTERVAL_DS:
01170 
01171         len = mtsprintf(buffer, len,  MT("INTERVAL(%i) DAY TO SECOND(%i)"),
01172                         (int) col->prec, (int) col->prec2);
01173         break;
01174 
01175         #endif
01176 
01177     case SQLT_REF:
01178 
01179         len = mtsprintf(buffer, len,  MT("REF"));
01180         break;
01181 
01182         #if OCI_VERSION_COMPILE >= OCI_9_0
01183 
01184     case SQLT_PNTY:
01185         #endif
01186 
01187     case SQLT_NTY:
01188 
01189         if (col->typinf != NULL)
01190             len = mtsprintf(buffer, len, col->typinf->name);
01191         else
01192             len = mtsprintf(buffer, len, MT("NAMED TYPE"));
01193         break;
01194 
01195     default:
01196 
01197         mtsncat(buffer, MT("?"), (size_t) len);
01198     }
01199 
01200     return len;
01201 }
01202 
01203 /* --------------------------------------------------------------------------------------------- *
01204  * OCI_ColumnGetTypeInfo
01205  * --------------------------------------------------------------------------------------------- */
01206 
01207 OCI_TypeInfo * OCI_API OCI_ColumnGetTypeInfo
01208 (
01209     OCI_Column *col
01210 )
01211 {
01212     OCI_CHECK_PTR(OCI_IPC_COLUMN, col, NULL);
01213 
01214     OCI_RESULT(TRUE);
01215 
01216     return col->typinf;
01217 }
01218 
01219 /* --------------------------------------------------------------------------------------------- *
01220  * OCI_ColumnGetSubType
01221  * --------------------------------------------------------------------------------------------- */
01222 
01223 unsigned int OCI_API OCI_ColumnGetSubType
01224 (
01225     OCI_Column *col
01226 )
01227 {
01228     unsigned int type = OCI_UNKNOWN;
01229 
01230     OCI_CHECK_PTR(OCI_IPC_COLUMN, col, OCI_UNKNOWN);
01231 
01232     OCI_RESULT(TRUE);
01233 
01234     if (col->type == OCI_CDT_LONG      ||
01235         col->type == OCI_CDT_LOB       ||
01236         col->type == OCI_CDT_FILE      ||
01237         col->type == OCI_CDT_TIMESTAMP ||
01238         col->type == OCI_CDT_INTERVAL)
01239     {
01240         type = col->subtype;
01241     }
01242 
01243     return type;
01244 }

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