OCILIB (C Driver for Oracle) 3.12.1
format.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-2013 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: format.c, Vincent Rogier $
00033  * --------------------------------------------------------------------------------------------- */
00034 
00035 #include "ocilib_internal.h"
00036 
00037 /* ********************************************************************************************* *
00038  *                             PRIVATE FUNCTIONS
00039  * ********************************************************************************************* */
00040 
00041 /* --------------------------------------------------------------------------------------------- *
00042  * OCI_ParseSqlFmt
00043  * --------------------------------------------------------------------------------------------- */
00044 
00045 int OCI_ParseSqlFmt
00046 (
00047     OCI_Statement *stmt,
00048     mtext         *buf,
00049     const mtext   *format,
00050     va_list       *pargs
00051 )
00052 {
00053     int size        = 0;
00054     int len         = 0;
00055     boolean quote   = FALSE;
00056     mtext *pb       = buf;
00057     const mtext *pf = format;
00058 
00059     OCI_CHECK(format == NULL, 0);
00060 
00061     for (; *pf != 0; pf++)
00062     {
00063         if (*pf != MT('%'))
00064         {
00065             if (buf != NULL)
00066             {
00067                 *(pb++) = *pf;
00068             }
00069 
00070             size++;
00071             continue;
00072         }
00073         else
00074         {
00075             quote = TRUE;
00076             len   = 0;
00077 
00078             if ( *(++pf) == MT('%'))
00079             {
00080                 if (buf != NULL)
00081                 {
00082                     *pb = *pf;
00083                 }
00084 
00085                 quote = FALSE;
00086                 len   = 1;
00087             }
00088         }
00089 
00090         switch (*pf)
00091         {
00092             case MT('s'):
00093             case MT('m'):
00094             {
00095                 const mtext *str = (const mtext *) va_arg(*pargs, const mtext *);
00096 
00097                 if (str != NULL && str[0] != 0)
00098                 {
00099                     len = (int) ((str!= NULL) ? mtslen(str) : OCI_SIZE_NULL);
00100 
00101                     if ((quote == TRUE) && (*pf != MT('m')))
00102                     {
00103                         if (buf != NULL)
00104                         {
00105                             *pb =  MT('\'');
00106                             mtscpy(pb + (size_t) 1, str);
00107                             *(pb + (size_t) (len + 1)) = MT('\'');
00108                         }
00109 
00110                         len+=2;
00111                     }
00112                     else if (buf != NULL)
00113                     {
00114                         mtscpy(pb, str);
00115                     }
00116                 }
00117                 else
00118                 {
00119                     if (*pf != MT('m'))
00120                     {
00121                         len = OCI_SIZE_NULL;
00122 
00123                         if (buf != NULL)
00124                         {
00125                             mtscpy(pb, OCI_STRING_NULL);
00126                         }
00127                     }
00128                 }
00129                 break;
00130             }
00131             case MT('t'):
00132             {
00133                 OCI_Date *date = (OCI_Date *) va_arg(*pargs, OCI_Date *);
00134 
00135                 if (buf != NULL)
00136                 {
00137                     if (date != NULL)
00138                     {
00139                         len = mtsprintf(pb, OCI_SIZE_DATE,
00140                                         MT("to_date('%02i%02i%04i%02i%02i%02i',")
00141                                         MT("'DDMMYYYYHH24MISS')"),
00142                                         date->handle->OCIDateDD,
00143                                         date->handle->OCIDateMM,
00144                                         date->handle->OCIDateYYYY,
00145                                         date->handle->OCIDateTime.OCITimeHH,
00146                                         date->handle->OCIDateTime.OCITimeMI,
00147                                         date->handle->OCIDateTime.OCITimeSS);
00148                     }
00149                     else
00150                     {
00151                         mtscpy(pb, OCI_STRING_NULL);
00152                         len = OCI_SIZE_NULL;
00153                     }
00154                 }
00155                 else
00156                 {
00157                     len = ((date != NULL) ? OCI_SIZE_DATE : OCI_SIZE_NULL);
00158                 }
00159 
00160                 break;
00161             }
00162             case MT('p'):
00163             {
00164                 OCI_Timestamp *tmsp = (OCI_Timestamp *) va_arg(*pargs, OCI_Timestamp *);
00165 
00166                 if (buf != NULL)
00167                 {
00168                     if (tmsp != NULL)
00169                     {
00170                         mtext str_ff[12];
00171                         int yy, mm, dd, hh, mi, ss, ff;
00172 
00173                         yy = mm = dd = mi = hh = ss = ff = 0;
00174 
00175                         OCI_TimestampGetDateTime(tmsp, &yy, &mm, &dd,
00176                                                  &hh, &mi, &ss, &ff);
00177 
00178                         if (ff > 0)
00179                         {
00180                             mtsprintf(str_ff, (int) msizeof(str_ff)- 1, MT("%i"), ff);
00181                         }
00182                         else
00183                         {
00184                             mtscpy(str_ff, MT("00"));
00185                         }
00186 
00187                         str_ff[2] = 0;
00188 
00189                         len = mtsprintf(pb, OCI_SIZE_TIMESTAMP,
00190                                         MT("to_timestamp('%02i%02i%04i%02i%02i%02i%s',")
00191                                         MT("'DDMMYYYYHH24MISSFF')"),
00192                                         dd, mm, yy, hh, mi, ss, str_ff);
00193                     }
00194                     else
00195                     {
00196                         mtscpy(pb, OCI_STRING_NULL);
00197                         len = OCI_SIZE_NULL;
00198                     }
00199                 }
00200                 else
00201                 {
00202                     len = ((tmsp != NULL) ? OCI_SIZE_TIMESTAMP : OCI_SIZE_NULL);
00203                 }
00204 
00205                 break;
00206             }
00207             case MT('v'):
00208             {
00209                 mtext temp[128];
00210 
00211                 OCI_Interval *itv = (OCI_Interval *) va_arg(*pargs, OCI_Interval *);
00212 
00213                 temp[0] = 0;
00214 
00215                 if (itv != NULL)
00216                 {
00217                     OCI_IntervalToText(itv, 3, 3, (int) msizeof(temp)- 1, temp);
00218 
00219                     len = (int) mtslen(temp);
00220 
00221                     if ((buf != NULL) && (len > 0))
00222                     {
00223                         mtscpy(pb, temp);
00224                     }
00225                 }
00226                 else
00227                 {
00228                     len = OCI_SIZE_NULL;
00229 
00230                     if ((buf != NULL) && (len > 0))
00231                     {
00232                         mtscpy(pb, OCI_STRING_NULL);
00233                     }
00234                 }
00235 
00236                 break;
00237             }
00238             case MT('i'):
00239             {
00240                 mtext temp[64];
00241 
00242                 temp[0] = 0;
00243 
00244                 len = (int) mtsprintf(temp, (int) msizeof(temp) - 1, MT("%i"), va_arg(*pargs, int));
00245 
00246                 if ((buf != NULL) && (len > 0))
00247                 {
00248                     mtscpy(pb, temp);
00249                 }
00250 
00251                 break;
00252             }
00253             case MT('u'):
00254             {
00255                 mtext temp[64];
00256 
00257                 temp[0] = 0;
00258 
00259                 len = (int) mtsprintf(temp, (int)  msizeof(temp) - 1, MT("%u"), va_arg(*pargs, unsigned int));
00260 
00261                 if ((buf != NULL) && (len > 0))
00262                 {
00263                     mtscpy(pb, temp);
00264                 }
00265 
00266                 break;
00267             }
00268             case MT('l'):
00269             {
00270                 mtext temp[64];
00271 
00272                 temp[0] = 0;
00273 
00274                 pf++;
00275 
00276                 if (*pf == MT('i'))
00277                 {
00278                     len = (int) mtsprintf(temp, (int) msizeof(temp) - 1, MT("%lld"), va_arg(*pargs, big_int));
00279                 }
00280                 else if (*pf == MT('u'))
00281                 {
00282                     len = (int) mtsprintf(temp, (int) msizeof(temp) - 1, MT("%llu"), va_arg(*pargs, big_uint));
00283                 }
00284                 else
00285                 {
00286                     len = 0;
00287                 }
00288 
00289                 if ((buf != NULL) && (len > 0))
00290                 {
00291                     mtscpy(pb, temp);
00292                 }
00293 
00294                 break;
00295             }
00296             case MT('h'):
00297             {
00298                 mtext temp[128];
00299 
00300                 temp[0] = 0;
00301 
00302                 pf++;
00303 
00304                 /* short ints must be passed as int to va_args */
00305 
00306                 if (*pf == 'i')
00307                 {
00308                     len = (int) mtsprintf(temp, (int) msizeof(temp) - 1, MT("%hd"), va_arg(*pargs, int));
00309                 }
00310                 else if (*pf == 'u')
00311                 {
00312                     len = (int) mtsprintf(temp, (int) msizeof(temp) - 1, MT("%hu"), va_arg(*pargs, unsigned int));
00313                 }           
00314                 else
00315                 {
00316                     len = 0;
00317                 }
00318 
00319                 if ((buf != NULL) && (len > 0))
00320                 {
00321                     mtscpy(pb, temp);
00322                 }
00323 
00324                 break;
00325             }
00326             case MT('g'):
00327             {
00328                 mtext temp[128];
00329 
00330                 temp[0] = 0;
00331 
00332                 len = (int) mtsprintf(temp, (int) msizeof(temp) - 1, MT("%lf"), va_arg(*pargs, double));
00333 
00334                 if ((buf != NULL) && (len > 0))
00335                 {
00336                     mtscpy(pb, temp);
00337                 }
00338 
00339                 break;
00340             }
00341             case MT('r'):
00342             {
00343                 mtext temp[128];
00344 
00345                 OCI_Ref *ref = (OCI_Ref *) va_arg(*pargs, OCI_Ref *);
00346 
00347                 temp[0] = 0;
00348 
00349                 if (ref != NULL)
00350                 {
00351                     OCI_RefToText(ref, (unsigned int) msizeof(temp) - 1, temp);
00352 
00353                     len = (int) mtslen(temp);
00354 
00355                     if ((buf != NULL) && (len > 0))
00356                     {
00357                         mtscpy(pb, temp);
00358                     }
00359                 }
00360                 else
00361                 {
00362                     len = OCI_SIZE_NULL;
00363 
00364                     if ((buf != NULL) && (len > 0))
00365                     {
00366                         mtscpy(pb, OCI_STRING_NULL);
00367                     }
00368                 }
00369 
00370                 break;
00371             }
00372             default:
00373             {
00374                 OCI_ExceptionParsingToken(stmt->con, stmt, *pf);
00375 
00376                 return 0;
00377             }
00378         }
00379 
00380         if (buf != NULL)
00381         {
00382             pb += (size_t) len;
00383         }
00384 
00385         size += len;
00386     }
00387 
00388     if (buf != NULL)
00389     {
00390         *pb = 0;
00391     }
00392 
00393     return size;
00394 }