C:/Users/vincent/Data/Perso/dev/ocilib/ocilib/src/date.c

00001 /*
00002    +----------------------------------------------------------------------+   
00003    |                                                                      |
00004    |                     OCILIB - C Driver for Oracle                     |
00005    |                                                                      |
00006    |                      (C Wrapper for Oracle OCI)                      |
00007    |                                                                      |
00008    +----------------------------------------------------------------------+
00009    |                      Website : http://www.ocilib.net                 |
00010    +----------------------------------------------------------------------+
00011    |               Copyright (c) 2007-2009 Vincent ROGIER                 |
00012    +----------------------------------------------------------------------+
00013    | This library is free software; you can redistribute it and/or        |
00014    | modify it under the terms of the GNU Lesser General Public           |
00015    | License as published by the Free Software Foundation; either         |
00016    | version 2 of the License, or (at your option) any later version.     |
00017    |                                                                      |
00018    | This library is distributed in the hope that it will be useful,      |
00019    | but WITHOUT ANY WARRANTY; without even the implied warranty of       |
00020    | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU    |
00021    | Lesser General Public License for more details.                      |
00022    |                                                                      |
00023    | You should have received a copy of the GNU Lesser General Public     |
00024    | License along with this library; if not, write to the Free           |
00025    | Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.   |
00026    +----------------------------------------------------------------------+
00027    |          Author: Vincent ROGIER <vince.rogier@gmail.com>             |
00028    +----------------------------------------------------------------------+ 
00029 */
00030 
00031 /* ------------------------------------------------------------------------ *
00032  * $Id: date.c, v 3.4.0 2009-07-30 17:40 Vince $
00033  * ------------------------------------------------------------------------ */
00034 
00035 #include "ocilib_internal.h"
00036 
00037 /* ************************************************************************ *
00038  *                             PRIVATE FUNCTIONS
00039  * ************************************************************************ */
00040 
00041 /* ------------------------------------------------------------------------ *
00042  * OCI_DateInit
00043  * ------------------------------------------------------------------------ */
00044 
00045 OCI_Date * OCI_DateInit(OCI_Connection *con, OCI_Date **pdate, OCIDate *buffer,
00046                         boolean allocate, boolean ansi)
00047 {
00048     OCI_Date *date = NULL;
00049     boolean res    = TRUE;
00050 
00051     OCI_CHECK(pdate == NULL, NULL);
00052 
00053     if (*pdate == NULL)
00054         *pdate = (OCI_Date *) OCI_MemAlloc(OCI_IPC_DATE, sizeof(*date), 1, TRUE);
00055 
00056     if (*pdate != NULL)
00057     {
00058         date = *pdate;
00059 
00060         date->con = con;
00061 
00062         /* get the right error handle */
00063 
00064         if (con != NULL)
00065             date->err = con->err;
00066         else
00067             date->err = OCILib.err;
00068 
00069         /* allocate buffer if needed */
00070 
00071         if ((date->handle == NULL) && ((allocate == TRUE) || (ansi == TRUE)))
00072         {
00073             date->allocated = TRUE;
00074 
00075             if (allocate == TRUE)
00076                 date->hstate = OCI_OBJECT_ALLOCATED;
00077 
00078             date->handle = (OCIDate *) OCI_MemAlloc(OCI_IPC_OCIDATE, 
00079                                                     sizeof(*date->handle), 
00080                                                     1, TRUE);
00081 
00082             res = (date->handle != NULL);
00083         }
00084         else
00085         {
00086             date->hstate  = OCI_OBJECT_FETCHED_CLEAN;
00087             date->handle  = buffer;
00088         }
00089 
00090         /* if the input buffer is an SQLT_DAT buffer, we need to convert it */
00091 
00092         if ((ansi == TRUE) && (buffer != NULL))
00093         {
00094             unsigned char *d = (unsigned char *) buffer;
00095             
00096             date->handle->OCIDateYYYY = (sb2) (((d[0] - 100) * 100) + (d[1] - 100));
00097             date->handle->OCIDateMM   = (ub1) d[2];
00098             date->handle->OCIDateDD   = (ub1) d[3];
00099 
00100             date->handle->OCIDateTime.OCITimeHH = (ub1) (d[4] - 1);
00101             date->handle->OCIDateTime.OCITimeMI = (ub1) (d[5] - 1);
00102             date->handle->OCIDateTime.OCITimeSS = (ub1) (d[6] - 1);
00103         }
00104     }
00105     else
00106         res = FALSE;
00107 
00108    /* check for failure */
00109 
00110     if (res == FALSE)
00111     {
00112         OCI_DateFree(date);
00113         date = NULL;
00114     }
00115     
00116     return date;
00117 }
00118 
00119 /* ************************************************************************ *
00120  *                             PUBLIC FUNCTIONS
00121  * ************************************************************************ */
00122 
00123 /* ------------------------------------------------------------------------ *
00124  * OCI_DateCreate
00125  * ------------------------------------------------------------------------ */
00126 
00127 OCI_Date * OCI_API OCI_DateCreate(OCI_Connection *con)
00128 {
00129     OCI_Date *date = NULL;
00130     
00131     OCI_CHECK_INITIALIZED(NULL);
00132 
00133     date = OCI_DateInit(con, &date, NULL, TRUE, FALSE);
00134 
00135     OCI_RESULT(date != NULL);
00136 
00137     return date;
00138 }
00139 
00140 /* ------------------------------------------------------------------------ *
00141  * OCI_DateFree
00142  * ------------------------------------------------------------------------ */
00143 
00144 boolean OCI_API OCI_DateFree(OCI_Date *date)
00145 {
00146     OCI_CHECK_PTR(OCI_IPC_DATE, date, FALSE);
00147 
00148     OCI_CHECK_OBJECT_FETCHED(date, FALSE);
00149 
00150     if (date->allocated == TRUE)
00151         OCI_FREE(date->handle);
00152 
00153     OCI_FREE(date);
00154 
00155     OCI_RESULT(TRUE);
00156 
00157     return TRUE;
00158 }
00159 
00160 /* ------------------------------------------------------------------------ *
00161  * OCI_DateAddDays
00162  * ------------------------------------------------------------------------ */
00163 
00164 boolean OCI_API OCI_DateAddDays(OCI_Date *date, int nb)
00165 {
00166     boolean res = TRUE;
00167 
00168     OCI_CHECK_PTR(OCI_IPC_DATE, date, FALSE);
00169 
00170     OCI_CALL4
00171     (
00172         res, date->err, date->con,
00173         
00174         OCIDateAddDays(date->err, date->handle, (sb4) nb, date->handle)
00175     )
00176 
00177     OCI_RESULT(res);
00178 
00179     return res;
00180 }
00181 
00182 /* ------------------------------------------------------------------------ *
00183  * OCI_DateAddMonths
00184  * ------------------------------------------------------------------------ */
00185 
00186 boolean OCI_API OCI_DateAddMonths(OCI_Date *date, int nb)
00187 {
00188     boolean res = TRUE;
00189 
00190     OCI_CHECK_PTR(OCI_IPC_DATE, date, FALSE);
00191 
00192     OCI_CALL4
00193     (
00194         res, date->err, date->con,
00195         
00196         OCIDateAddMonths(date->err, date->handle, (sb4) nb, date->handle)
00197     )
00198 
00199     OCI_RESULT(res);
00200 
00201     return res;
00202 }
00203 
00204 /* ------------------------------------------------------------------------ *
00205  * OCI_DateAssign
00206  * ------------------------------------------------------------------------ */
00207 
00208 boolean OCI_API OCI_DateAssign(OCI_Date *date, OCI_Date *date_src)
00209 {
00210     boolean res = TRUE;
00211 
00212     OCI_CHECK_PTR(OCI_IPC_DATE, date,     FALSE);
00213     OCI_CHECK_PTR(OCI_IPC_DATE, date_src, FALSE);
00214 
00215     OCI_CALL4
00216     (
00217         res, date->err, date->con, 
00218 
00219         OCIDateAssign(date->err, date_src->handle, date->handle)
00220     )
00221 
00222     OCI_RESULT(res);
00223 
00224     return res;
00225 }
00226 
00227 /* ------------------------------------------------------------------------ *
00228  * OCI_DateCheck
00229  * ------------------------------------------------------------------------ */
00230 
00231 int OCI_API OCI_DateCheck(OCI_Date *date)
00232 {
00233     boolean res = TRUE;
00234     uword valid = 0;
00235 
00236     OCI_CHECK_PTR(OCI_IPC_DATE, date, OCI_ERROR);
00237 
00238     OCI_CALL4
00239     (
00240         res, date->err, date->con, 
00241         
00242         OCIDateCheck(date->err, date->handle, &valid)
00243     )
00244 
00245     OCI_RESULT(res);
00246 
00247     return (int) valid;
00248 }
00249 
00250 /* ------------------------------------------------------------------------ *
00251  * OCI_DateCompare
00252  * ------------------------------------------------------------------------ */
00253 
00254 int OCI_API OCI_DateCompare(OCI_Date *date, OCI_Date *date2)
00255 {
00256     boolean res = TRUE;
00257     sword value = -1;
00258 
00259     OCI_CHECK_PTR(OCI_IPC_DATE, date, -1);
00260 
00261     OCI_CALL4
00262     (
00263         res, date->err, date->con,
00264         
00265         OCIDateCompare(date->err, date->handle, date2->handle, &value)
00266     )
00267 
00268     OCI_RESULT(res);
00269 
00270     return (int) value;
00271 }
00272 
00273 /* ------------------------------------------------------------------------ *
00274  * OCI_DateDaysBetween
00275  * ------------------------------------------------------------------------ */
00276 
00277 int OCI_API OCI_DateDaysBetween(OCI_Date *date, OCI_Date *date2)
00278 {
00279     boolean res = TRUE;
00280     sb4 nb      = 0;
00281 
00282     OCI_CHECK_PTR(OCI_IPC_DATE, date,  OCI_ERROR);
00283     OCI_CHECK_PTR(OCI_IPC_DATE, date2, OCI_ERROR);
00284 
00285     OCI_CALL4
00286     (
00287         res, date->err, date->con, 
00288         
00289         OCIDateDaysBetween(date->err, date->handle, date2->handle, &nb)
00290     )
00291 
00292     OCI_RESULT(res);
00293 
00294     return (sb4) nb;
00295 }
00296 
00297 /* ------------------------------------------------------------------------ *
00298  * OCI_DateFromText
00299  * ------------------------------------------------------------------------ */
00300 
00301 boolean OCI_API OCI_DateFromText(OCI_Date *date, const mtext *str, 
00302                                  const mtext *fmt)
00303 {
00304     void *ostr1 = NULL;
00305     void *ostr2 = NULL;
00306     int  osize1 = -1;
00307     int  osize2 = -1;
00308     boolean res = TRUE;
00309 
00310     OCI_CHECK_PTR(OCI_IPC_DATE, date, FALSE);
00311     OCI_CHECK_PTR(OCI_IPC_STRING, str,  FALSE);
00312     OCI_CHECK_PTR(OCI_IPC_STRING, fmt,  FALSE);
00313 
00314     ostr1 = OCI_GetInputMetaString(str, &osize1);
00315     ostr2 = OCI_GetInputMetaString(fmt, &osize2);
00316 
00317     OCI_CALL4
00318     (
00319         res, date->err, date->con,
00320         
00321         OCIDateFromText(date->err,
00322                         (oratext *) ostr1, (ub4) osize1,
00323                         (oratext *) ostr2, (ub1) osize2,
00324                         (oratext *) NULL,  (ub4) 0, date->handle)
00325     )
00326 
00327     OCI_ReleaseMetaString(ostr1);
00328     OCI_ReleaseMetaString(ostr2);
00329 
00330     OCI_RESULT(res);
00331 
00332     return res;
00333 }
00334 
00335 /* ------------------------------------------------------------------------ *
00336  * OCI_DateGetDate
00337  * ------------------------------------------------------------------------ */
00338 
00339 boolean OCI_API OCI_DateGetDate(OCI_Date *date, int *year, int *month, int *day)
00340 {
00341     sb2 yr = 0;
00342     ub1 mt = 0;
00343     ub1 dy = 0;
00344 
00345     OCI_CHECK_PTR(OCI_IPC_DATE, date,  FALSE);
00346     OCI_CHECK_PTR(OCI_IPC_INT, year,  FALSE);
00347     OCI_CHECK_PTR(OCI_IPC_INT, month, FALSE);
00348     OCI_CHECK_PTR(OCI_IPC_INT, day,   FALSE);
00349 
00350     *year  = 0;
00351     *month = 0;
00352     *day   = 0;
00353 
00354     OCIDateGetDate(date->handle, &yr, &mt, &dy);
00355 
00356     *year  = (int) yr;
00357     *month = (int) mt;
00358     *day   = (int) dy;
00359 
00360     OCI_RESULT(TRUE);
00361 
00362     return TRUE;
00363 }
00364 
00365 /* ------------------------------------------------------------------------ *
00366  * OCI_DateGetTime
00367  * ------------------------------------------------------------------------ */
00368 
00369 boolean OCI_API OCI_DateGetTime(OCI_Date *date, int *hour, int *min, int *sec)
00370 {
00371     ub1 hr = 0;
00372     ub1 mn = 0;
00373     ub1 sc = 0;
00374 
00375     OCI_CHECK_PTR(OCI_IPC_DATE, date, FALSE);
00376     OCI_CHECK_PTR(OCI_IPC_INT, hour, FALSE);
00377     OCI_CHECK_PTR(OCI_IPC_INT, min , FALSE);
00378     OCI_CHECK_PTR(OCI_IPC_INT, sec,  FALSE);
00379 
00380     *hour = 0;
00381     *min  = 0;
00382     *sec  = 0;
00383 
00384     OCIDateGetTime(date->handle, &hr, &mn, &sc);
00385 
00386     *hour = (int) hr;
00387     *min  = (int) mn;
00388     *sec  = (int) sc;
00389 
00390     OCI_RESULT(TRUE);
00391 
00392     return TRUE;
00393 }
00394 
00395 /* ------------------------------------------------------------------------ *
00396  * OCI_DateGetDateTime
00397  * ------------------------------------------------------------------------ */
00398 
00399 boolean OCI_API OCI_DateGetDateTime(OCI_Date *date, int *year, int *month, 
00400                                     int *day, int *hour, int *min, int *sec)
00401 {
00402     return (OCI_DateGetDate(date, year, month, day) &&
00403             OCI_DateGetTime(date, hour, min, sec));
00404 }
00405 
00406 /* ------------------------------------------------------------------------ *
00407  * OCI_DateLastDay
00408  * ------------------------------------------------------------------------ */
00409 
00410 boolean OCI_API OCI_DateLastDay(OCI_Date *date)
00411 {
00412     boolean res = TRUE;
00413 
00414     OCI_CHECK_PTR(OCI_IPC_DATE, date, FALSE);
00415 
00416     OCI_CALL4
00417     (
00418         res, date->err, date->con, 
00419         
00420         OCIDateLastDay(date->err, date->handle, date->handle)
00421     )
00422 
00423     OCI_RESULT(res);
00424 
00425     return res;
00426 }
00427 
00428 /* ------------------------------------------------------------------------ *
00429  * OCI_DateNextDay
00430  * ------------------------------------------------------------------------ */
00431 
00432 boolean OCI_API OCI_DateNextDay(OCI_Date *date, const mtext *day)
00433 {
00434     boolean res = TRUE;
00435 
00436     OCI_CHECK_PTR(OCI_IPC_DATE, date, FALSE);
00437     OCI_CHECK_PTR(OCI_IPC_STRING, day,  FALSE);
00438 
00439     OCI_CALL4
00440     (
00441         res, date->err, date->con, 
00442         
00443         OCIDateNextDay(date->err, date->handle, (oratext *) day,
00444                        (ub4) mtextsize(day), date->handle)
00445     )
00446 
00447     OCI_RESULT(res);
00448 
00449     return res;
00450 }
00451 
00452 /* ------------------------------------------------------------------------ *
00453  * OCI_DateSetDate
00454  * ------------------------------------------------------------------------ */
00455 
00456 boolean OCI_API OCI_DateSetDate(OCI_Date *date, int year, int month, int day)
00457 {
00458     OCI_CHECK_PTR(OCI_IPC_DATE, date, FALSE);
00459 
00460     OCIDateSetDate(date->handle, (sb2) year, (ub1) month, (ub1) day);
00461 
00462     OCI_RESULT(TRUE);
00463 
00464     return TRUE;
00465 }
00466 
00467 /* ------------------------------------------------------------------------ *
00468  * OCI_DateSetTime
00469  * ------------------------------------------------------------------------ */
00470 
00471 boolean OCI_API OCI_DateSetTime(OCI_Date *date, int hour, int min, int sec)
00472 {
00473     OCI_CHECK_PTR(OCI_IPC_DATE, date, FALSE);
00474 
00475     OCIDateSetTime(date->handle, (ub1) hour, (ub1) min, (ub1) sec);
00476 
00477     OCI_RESULT(TRUE);
00478 
00479     return TRUE;
00480 }
00481 
00482 /* ------------------------------------------------------------------------ *
00483  * OCI_DateSetDateTime
00484  * ------------------------------------------------------------------------ */
00485 
00486 boolean OCI_API OCI_DateSetDateTime(OCI_Date *date, int year, int month, 
00487                                     int day, int hour, int min, int sec)
00488 {
00489     return (OCI_DateSetDate(date, year, month, day) &&
00490             OCI_DateSetTime(date, hour, min, sec));
00491 }
00492 
00493 /* ------------------------------------------------------------------------ *
00494  * OCI_DateSysDate
00495  * ------------------------------------------------------------------------ */
00496 
00497 boolean OCI_API OCI_DateSysDate(OCI_Date *date)
00498 {
00499     boolean res = TRUE;
00500 
00501     OCI_CHECK_PTR(OCI_IPC_DATE, date, FALSE);
00502 
00503     OCI_CALL4
00504     (
00505         res, date->err, date->con, 
00506         
00507         OCIDateSysDate(date->err, date->handle)
00508     )
00509 
00510     OCI_RESULT(res);
00511 
00512     return res;
00513 }
00514 
00515 /* ------------------------------------------------------------------------ *
00516  * OCI_DateToText
00517  * ------------------------------------------------------------------------ */
00518 
00519 boolean OCI_API OCI_DateToText(OCI_Date *date, const mtext *fmt, int size, 
00520                                mtext *str)
00521 {
00522     void *ostr1 = NULL;
00523     void *ostr2 = NULL;
00524     int  osize1 = size*sizeof(mtext);
00525     int  osize2 = -1;
00526     boolean res = TRUE;
00527 
00528     OCI_CHECK_PTR(OCI_IPC_DATE, date,  FALSE);
00529     OCI_CHECK_PTR(OCI_IPC_STRING, str, FALSE);
00530     OCI_CHECK_PTR(OCI_IPC_STRING, fmt, FALSE);
00531 
00532     /* init output buffer in case of OCI failure */
00533  
00534     str[0] = 0;
00535 
00536     ostr1 = OCI_GetInputMetaString(str, &osize1);
00537     ostr2 = OCI_GetInputMetaString(fmt, &osize2);
00538 
00539     OCI_CALL4
00540     (
00541         res, date->err, date->con, 
00542         
00543         OCIDateToText(date->err, date->handle, (oratext *) ostr2, 
00544                       (ub1) osize2, (oratext *) NULL, (ub4) 0,
00545                       (ub4*) &osize1, (oratext *) ostr1)
00546     )
00547 
00548     OCI_GetOutputMetaString(ostr1, str, &osize1);
00549 
00550     OCI_ReleaseMetaString(ostr1);
00551     OCI_ReleaseMetaString(ostr2);
00552 
00553     /* set null string terminator*/
00554 
00555     str[osize1/sizeof(mtext)] = 0;
00556 
00557     OCI_RESULT(res);
00558 
00559     return res;
00560 }
00561 
00562 /* ------------------------------------------------------------------------ *
00563  * OCI_DateZoneToZone
00564  * ------------------------------------------------------------------------ */
00565 
00566 boolean OCI_API OCI_DateZoneToZone(OCI_Date *date, const mtext *zone1, 
00567                                    const mtext *zone2)
00568 {
00569     void *ostr1 = NULL;
00570     void *ostr2 = NULL;
00571     int osize1  = -1;
00572     int osize2  = -1;
00573     boolean res = TRUE;
00574 
00575     OCI_CHECK_PTR(OCI_IPC_DATE, date,    FALSE);
00576     OCI_CHECK_PTR(OCI_IPC_STRING, zone1, FALSE);
00577     OCI_CHECK_PTR(OCI_IPC_STRING, zone2, FALSE);
00578 
00579     ostr1 = OCI_GetInputMetaString(zone1, &osize1);
00580     ostr2 = OCI_GetInputMetaString(zone2, &osize2);
00581    
00582     OCI_CALL4
00583     (
00584         res, date->err, date->con, 
00585         
00586         OCIDateZoneToZone(date->err, date->handle,
00587                           (oratext *) ostr1, (ub4) osize1,
00588                           (oratext *) ostr2, (ub4) osize2,
00589                           date->handle)
00590     )
00591 
00592     OCI_ReleaseMetaString(ostr1);
00593     OCI_ReleaseMetaString(ostr2);
00594 
00595     OCI_RESULT(res);
00596 
00597     return res;
00598 }
00599 
00600 /* ------------------------------------------------------------------------ *
00601  * OCI_DateToCTime
00602  * ------------------------------------------------------------------------ */
00603 
00604 boolean OCI_API OCI_DateToCTime(OCI_Date *date, struct tm *ptm, time_t *pt)
00605 {
00606     time_t time = -1;
00607     struct tm t;
00608 
00609     OCI_CHECK_PTR(OCI_IPC_DATE, date, FALSE);
00610 
00611     t.tm_year  = date->handle->OCIDateYYYY - 1900;
00612     t.tm_mon   = date->handle->OCIDateMM - 1;
00613     t.tm_mday  = date->handle->OCIDateDD;
00614 
00615     t.tm_hour  = date->handle->OCIDateTime.OCITimeHH;
00616     t.tm_min   = date->handle->OCIDateTime.OCITimeMI;
00617     t.tm_sec   = date->handle->OCIDateTime.OCITimeSS;
00618 
00619     t.tm_wday  = 0;
00620     t.tm_yday  = 0;
00621     t.tm_isdst = -1;
00622 
00623     time = mktime(&t);
00624 
00625     if (ptm != NULL)
00626         memcpy(ptm, &t, sizeof(t));
00627 
00628     if (pt != NULL)
00629         *pt = time;
00630 
00631     OCI_RESULT(TRUE);
00632 
00633     return (time != -1);
00634 }
00635 
00636 /* ------------------------------------------------------------------------ *
00637  * OCI_DateFromCTime
00638  * ------------------------------------------------------------------------ */
00639 
00640 boolean OCI_API OCI_DateFromCTime(OCI_Date *date, struct tm *ptm, time_t t)
00641 {
00642     OCI_CHECK_PTR(OCI_IPC_DATE, date, FALSE);
00643 
00644     if (ptm == NULL && t == 0)
00645         OCI_ExceptionNullPointer(OCI_IPC_TM);
00646 
00647     if (ptm == NULL)
00648         ptm = localtime(&t);
00649 
00650     date->handle->OCIDateYYYY = (sb2) ptm->tm_year + 1900;
00651     date->handle->OCIDateMM   = (ub1) ptm->tm_mon  + 1;
00652     date->handle->OCIDateDD   = (ub1) ptm->tm_mday;
00653 
00654     date->handle->OCIDateTime.OCITimeHH = (ub1) ptm->tm_hour;
00655     date->handle->OCIDateTime.OCITimeMI = (ub1) ptm->tm_min;
00656     date->handle->OCIDateTime.OCITimeSS = (ub1) ptm->tm_sec;
00657 
00658     OCI_RESULT(TRUE);
00659 
00660     return TRUE;
00661 }

Generated on Thu Jul 30 17:41:52 2009 for OCILIB (C Driver for Oracle) by  doxygen 1.5.4