~psycopg/psycopg/2.0.x

« back to all changes in this revision

Viewing changes to psycopg/typecast_mxdatetime.c

  • Committer: Federico Di Gregorio
  • Date: 2004-10-19 03:17:12 UTC
  • Revision ID: fog-3331e1822980e428b2fe291ebc794e704e32642a
Initial psycopg 2 import after SVN crash.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* typecast_mxdatetime.c - date and time typecasting functions to mx types
 
2
 *
 
3
 * Copyright (C) 2001-2003 Federico Di Gregorio <fog@debian.org>
 
4
 *
 
5
 * This file is part of the psycopg module.
 
6
 *
 
7
 * This program is free software; you can redistribute it and/or
 
8
 * modify it under the terms of the GNU General Public License
 
9
 * as published by the Free Software Foundation; either version 2,
 
10
 * or (at your option) any later version.
 
11
 *
 
12
 * This program is distributed in the hope that it will be useful,
 
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
 * GNU General Public License for more details.
 
16
 *
 
17
 * You should have received a copy of the GNU General Public License
 
18
 * along with this program; if not, write to the Free Software
 
19
 * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
20
 */
 
21
 
 
22
#include "mxDateTime.h"
 
23
 
 
24
/* the pointer to the mxDateTime API is initialized by the module init code,
 
25
   we just need to grab it */
 
26
extern mxDateTimeModule_APIObject *mxDateTimeP;
 
27
 
 
28
/** DATE - cast a date into mx.DateTime python object **/
 
29
 
 
30
static PyObject *
 
31
typecast_MXDATE_cast(PyObject *s, PyObject *curs)
 
32
{
 
33
    int n, y=0, m=0, d=0;
 
34
    int hh=0, mm=0;
 
35
    double ss=0.0;
 
36
    char *str;
 
37
 
 
38
    if (s == Py_None) {Py_INCREF(s); return s;}
 
39
 
 
40
    str = PyString_AsString(s);
 
41
    
 
42
    /* check for infinity */
 
43
    if (!strcmp(str, "infinity") || !strcmp(str, "-infinity")) {
 
44
        if (str[0] == '-') {
 
45
            return mxDateTimeP->DateTime_FromDateAndTime(-999998,1,1, 0,0,0);
 
46
        }
 
47
        else {
 
48
            return mxDateTimeP->DateTime_FromDateAndTime(999999,12,31, 0,0,0);
 
49
        }
 
50
    }
 
51
    
 
52
    Dprintf("typecast_MXDATE_cast: s = %s", str);
 
53
    n = sscanf(str, "%d-%d-%d %d:%d:%lf", &y, &m, &d, &hh, &mm, &ss);
 
54
    Dprintf("typecast_MXDATE_cast: date parsed, %d components", n);
 
55
    
 
56
    if (n != 3 && n != 6) {
 
57
        PyErr_SetString(DataError, "unable to parse date");
 
58
        return NULL;
 
59
    }
 
60
    return mxDateTimeP->DateTime_FromDateAndTime(y, m, d, hh, mm, ss);
 
61
}
 
62
 
 
63
/** TIME - parse time into an mx.DateTime object **/
 
64
 
 
65
static PyObject *
 
66
typecast_MXTIME_cast(PyObject *s, PyObject *curs)
 
67
{
 
68
    int n, hh=0, mm=0;
 
69
    double ss=0.0;    
 
70
    char *str;
 
71
 
 
72
    if (s == Py_None) {Py_INCREF(s); return s;}
 
73
 
 
74
    str = PyString_AsString(s);
 
75
    
 
76
    Dprintf("typecast_MXTIME_cast: s = %s", str);
 
77
    
 
78
    n = sscanf(str, "%d:%d:%lf", &hh, &mm, &ss);
 
79
    Dprintf("typecast_MXTIME_cast: time parsed, %d components", n);
 
80
    Dprintf("typecast_MXTIME_cast: hh = %d, mm = %d, ss = %f", hh, mm, ss);
 
81
    
 
82
    if (n != 3) {
 
83
        PyErr_SetString(DataError, "unable to parse time");
 
84
        return NULL;
 
85
    }
 
86
 
 
87
    return mxDateTimeP->DateTimeDelta_FromTime(hh, mm ,ss);
 
88
}
 
89
 
 
90
/** INTERVAL - parse an interval into an mx.DateTimeDelta **/
 
91
 
 
92
static PyObject *
 
93
typecast_MXINTERVAL_cast(PyObject *s, PyObject *curs)
 
94
{
 
95
    long years = 0, months = 0, days = 0, denominator = 1;
 
96
    double hours = 0.0, minutes = 0.0, seconds = 0.0, hundredths = 0.0;
 
97
    double v = 0.0, sign = 1.0;
 
98
    int part = 0;
 
99
    char *str;
 
100
 
 
101
    if (s == Py_None) {Py_INCREF(s); return s;}
 
102
    
 
103
    str = PyString_AsString(s);
 
104
    Dprintf("typecast_MXINTERVAL_cast: s = %s", str);
 
105
    
 
106
    while (*str) {
 
107
        switch (*str) {
 
108
 
 
109
        case '-':
 
110
            sign = -1.0;
 
111
            break;
 
112
 
 
113
        case '0': case '1': case '2': case '3': case '4':
 
114
        case '5': case '6': case '7': case '8': case '9':
 
115
            v = v*10 + (double)*str - (double)'0';
 
116
            Dprintf("typecast_MXINTERVAL_cast: v = %f", v);
 
117
            if (part == 6){
 
118
                denominator *= 10;
 
119
                Dprintf("typecast_MXINTERVAL_cast: denominator = %ld",
 
120
                        denominator);
 
121
            }
 
122
            break;
 
123
 
 
124
        case 'y':
 
125
            if (part == 0) {
 
126
                years = (long)(v*sign);
 
127
                str = skip_until_space(str);
 
128
                Dprintf("typecast_MXINTERVAL_cast: years = %ld, rest = %s",
 
129
                        years, str);
 
130
                v = 0.0; sign = 1.0; part = 1;
 
131
            }
 
132
            break;
 
133
 
 
134
        case 'm':
 
135
            if (part <= 1) {
 
136
                months = (long)(v*sign);
 
137
                str = skip_until_space(str);
 
138
                Dprintf("typecast_MXINTERVAL_cast: months = %ld, rest = %s",
 
139
                        months, str);
 
140
                v = 0.0; sign = 1.0; part = 2;
 
141
            }
 
142
            break;
 
143
 
 
144
        case 'd':
 
145
            if (part <= 2) {
 
146
                days = (long)(v*sign);
 
147
                str = skip_until_space(str);
 
148
                Dprintf("typecast_MXINTERVAL_cast: days = %ld, rest = %s",
 
149
                        days, str);
 
150
                v = 0.0; sign = 1.0; part = 3;
 
151
            }
 
152
            break;
 
153
 
 
154
        case ':':
 
155
            if (part <= 3) {
 
156
                hours = v;
 
157
                Dprintf("typecast_MXINTERVAL_cast: hours = %f", hours);
 
158
                v = 0.0; part = 4;
 
159
            }
 
160
            else if (part == 4) {
 
161
                minutes = v;
 
162
                Dprintf("typecast_MXINTERVAL_cast: minutes = %f", minutes);
 
163
                v = 0.0; part = 5;
 
164
            }
 
165
            break;
 
166
 
 
167
        case '.':
 
168
            if (part == 5) {
 
169
                seconds = v;
 
170
                Dprintf("typecast_MXINTERVAL_cast: seconds = %f", seconds);
 
171
                v = 0.0; part = 6;
 
172
            }
 
173
            break;   
 
174
 
 
175
        default:
 
176
            break;
 
177
        }
 
178
        
 
179
        str++;
 
180
    }
 
181
 
 
182
    /* manage last value, be it minutes or seconds or hundredths of a second */
 
183
    if (part == 4) {
 
184
        minutes = v;
 
185
        Dprintf("typecast_MXINTERVAL_cast: minutes = %f", minutes);
 
186
    }
 
187
    else if (part == 5) {
 
188
        seconds = v;
 
189
        Dprintf("typecast_MXINTERVAL_cast: seconds = %f", seconds);
 
190
    }
 
191
    else if (part == 6) {
 
192
        hundredths = v;
 
193
        Dprintf("typecast_MXINTERVAL_cast: hundredths = %f", hundredths);
 
194
        hundredths = hundredths/denominator;
 
195
        Dprintf("typecast_MXINTERVAL_cast: fractions = %.20f", hundredths);
 
196
    }
 
197
    
 
198
    /* calculates seconds */
 
199
    if (sign < 0.0) {
 
200
        seconds = - (hundredths + seconds + minutes*60 + hours*3600);
 
201
    }
 
202
    else {
 
203
        seconds += hundredths + minutes*60 + hours*3600;
 
204
    }
 
205
 
 
206
    /* calculates days */
 
207
    days += years*365 + months*30;
 
208
    
 
209
    Dprintf("typecast_MXINTERVAL_cast: days = %ld, seconds = %f",
 
210
            days, seconds);
 
211
    return mxDateTimeP->DateTimeDelta_FromDaysAndSeconds(days, seconds);
 
212
}
 
213
 
 
214
/* psycopg defaults to using mx types */
 
215
 
 
216
#ifdef PSYCOPG_DEFAULT_MXDATETIME 
 
217
#define typecast_DATE_cast typecast_MXDATE_cast
 
218
#define typecast_TIME_cast typecast_MXTIME_cast
 
219
#define typecast_INTERVAL_cast typecast_MXINTERVAL_cast
 
220
#define typecast_DATETIME_cast typecast_MXDATE_cast
 
221
#endif
 
222