diff options
author | Federico Di Gregorio <fog@initd.org> | 2004-10-19 03:17:12 +0000 |
---|---|---|
committer | Federico Di Gregorio <fog@initd.org> | 2004-10-19 03:17:12 +0000 |
commit | c904d97f696a665958c2cc43333d09c0e6357577 (patch) | |
tree | de88cb1cb6a48230f79bc0b532835d26a33660e9 /psycopg/adapter_datetime.c | |
download | psycopg2-c904d97f696a665958c2cc43333d09c0e6357577.tar.gz |
Initial psycopg 2 import after SVN crash.
Diffstat (limited to 'psycopg/adapter_datetime.c')
-rw-r--r-- | psycopg/adapter_datetime.c | 439 |
1 files changed, 439 insertions, 0 deletions
diff --git a/psycopg/adapter_datetime.c b/psycopg/adapter_datetime.c new file mode 100644 index 0000000..03729ba --- /dev/null +++ b/psycopg/adapter_datetime.c @@ -0,0 +1,439 @@ +/* adapter_datetime.c - python date/time objects + * + * Copyright (C) 2004 Federico Di Gregorio <fog@debian.org> + * + * This file is part of psycopg. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2, + * or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include <Python.h> +#include <structmember.h> +#include <stringobject.h> +#include <datetime.h> + +#include <time.h> +#include <string.h> + +#define PSYCOPG_MODULE +#include "psycopg/config.h" +#include "psycopg/python.h" +#include "psycopg/psycopg.h" +#include "psycopg/adapter_datetime.h" + + +/* the pointer to the datetime module API is initialized by the module init + code, we just need to grab it */ +extern PyObject* pyDateTimeModuleP; +extern PyObject *pyDateTypeP; +extern PyObject *pyTimeTypeP; +extern PyObject *pyDateTimeTypeP; +extern PyObject *pyDeltaTypeP; + +/* datetime_str, datetime_getquoted - return result of quoting */ + +static PyObject * +pydatetime_str(pydatetimeObject *self) +{ + if (self->type <= PSYCO_DATETIME_TIMESTAMP) { + PyObject *res = NULL; + PyObject *iso = PyObject_CallMethod(self->wrapped, "isoformat", NULL); + if (iso) { + res = PyString_FromFormat("'%s'", PyString_AsString(iso)); + Py_DECREF(iso); + } + return res; + } + else { + PyDateTime_Delta *obj = (PyDateTime_Delta*)self->wrapped; + + char buffer[8]; + int i, j, x; + int a = obj->microseconds; + + for (i=1000000, j=0; i > 0 ; i /= 10) { + x = a/i; + a -= x*i; + buffer[j++] = '0'+x; + } + buffer[j] = '\0'; + + return PyString_FromFormat("'%d days %d.%s seconds'", + obj->days, obj->seconds, buffer); + } +} + +PyObject * +pydatetime_getquoted(pydatetimeObject *self, PyObject *args) +{ + if (!PyArg_ParseTuple(args, "")) return NULL; + return pydatetime_str(self); +} + +PyObject * +pydatetime_prepare(pydatetimeObject *self, PyObject *args) +{ + PyObject *fake; + + if (!PyArg_ParseTuple(args, "O", &fake)) return NULL; + + Py_INCREF(Py_None); + return Py_None; +} + +/** the DateTime wrapper object **/ + +/* object member list */ + +static struct PyMemberDef pydatetimeObject_members[] = { + {"adapted", T_OBJECT, offsetof(pydatetimeObject, wrapped), RO}, + {"type", T_INT, offsetof(pydatetimeObject, type), RO}, + {NULL} +}; + +/* object method table */ + +static PyMethodDef pydatetimeObject_methods[] = { + {"getquoted", (PyCFunction)pydatetime_getquoted, METH_VARARGS, + "getquoted() -> wrapped object value as SQL date/time"}, + {"prepare", (PyCFunction)pydatetime_prepare, METH_VARARGS, + "prepare(conn) -> currently does nothing"}, + {NULL} /* Sentinel */ +}; + +/* initialization and finalization methods */ + +static int +pydatetime_setup(pydatetimeObject *self, PyObject *obj, int type) +{ + Dprintf("pydatetime_setup: init datetime object at %p, refcnt = %d", + self, ((PyObject *)self)->ob_refcnt); + + self->type = type; + self->wrapped = obj; + Py_INCREF(self->wrapped); + + Dprintf("pydatetime_setup: good pydatetime object at %p, refcnt = %d", + self, ((PyObject *)self)->ob_refcnt); + return 0; +} + +static void +pydatetime_dealloc(PyObject* obj) +{ + pydatetimeObject *self = (pydatetimeObject *)obj; + + Py_XDECREF(self->wrapped); + + Dprintf("mpydatetime_dealloc: deleted pydatetime object at %p, " + "refcnt = %d", obj, obj->ob_refcnt); + + obj->ob_type->tp_free(obj); +} + +static int +pydatetime_init(PyObject *obj, PyObject *args, PyObject *kwds) +{ + PyObject *dt; + int type = -1; /* raise an error if type was not passed! */ + + if (!PyArg_ParseTuple(args, "O|i", &dt, &type)) + return -1; + + return pydatetime_setup((pydatetimeObject *)obj, dt, type); +} + +static PyObject * +pydatetime_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + return type->tp_alloc(type, 0); +} + +static void +pydatetime_del(PyObject* self) +{ + PyObject_Del(self); +} + +static PyObject * +pydatetime_repr(pydatetimeObject *self) +{ + return PyString_FromFormat("<psycopg.datetime object at %p>", self); +} + +/* object type */ + +#define pydatetimeType_doc \ +"psycopg.Pydatetime(datetime, type) -> new datetime wrapper object" + +PyTypeObject pydatetimeType = { + PyObject_HEAD_INIT(NULL) + 0, + "psycopg.datetime", + sizeof(pydatetimeObject), + 0, + pydatetime_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + + 0, /*tp_compare*/ + (reprfunc)pydatetime_repr, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ + + 0, /*tp_call*/ + (reprfunc)pydatetime_str, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /*tp_flags*/ + + pydatetimeType_doc, /*tp_doc*/ + + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + + /* Attribute descriptor and subclassing stuff */ + + pydatetimeObject_methods, /*tp_methods*/ + pydatetimeObject_members, /*tp_members*/ + 0, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + 0, /*tp_dictoffset*/ + + pydatetime_init, /*tp_init*/ + PyType_GenericAlloc, /*tp_alloc*/ + pydatetime_new, /*tp_new*/ + (freefunc)pydatetime_del, /*tp_free Low-level free-memory routine */ + 0, /*tp_is_gc For PyObject_IS_GC */ + 0, /*tp_bases*/ + 0, /*tp_mro method resolution order */ + 0, /*tp_cache*/ + 0, /*tp_subclasses*/ + 0 /*tp_weaklist*/ +}; + + +/** module-level functions **/ + +#ifdef PSYCOPG_DEFAULT_PYDATETIME + +PyObject * +psyco_Date(PyObject *self, PyObject *args) +{ + PyObject *res = NULL; + int year, month, day; + + PyObject* obj = NULL; + + if (!PyArg_ParseTuple(args, "iii", &year, &month, &day)) + return NULL; + + obj = PyObject_CallFunction(pyDateTypeP, "iii", year, month, day); + + if (obj) { + res = PyObject_CallFunction((PyObject *)&pydatetimeType, + "Oi", obj, PSYCO_DATETIME_DATE); + Py_DECREF(obj); + } + + return res; +} + +PyObject * +psyco_Time(PyObject *self, PyObject *args) +{ + PyObject *res = NULL; + int hours, minutes=0; + double micro, seconds=0.0; + + PyObject* obj = NULL; + + if (!PyArg_ParseTuple(args, "iid", &hours, &minutes, &seconds)) + return NULL; + + micro = (seconds - floor(seconds)) * 1000000.0; + + obj = PyObject_CallFunction(pyTimeTypeP, "iiii", + hours, minutes, (int)round(seconds), (int)round(micro)); + + if (obj) { + res = PyObject_CallFunction((PyObject *)&pydatetimeType, + "Oi", obj, PSYCO_DATETIME_TIME); + Py_DECREF(obj); + } + + return res; +} + +PyObject * +psyco_Timestamp(PyObject *self, PyObject *args) +{ + PyObject *res = NULL; + int year, month, day; + int hour=0, minute=0; /* default to midnight */ + double micro, second=0.0; + + PyObject* obj = NULL; + + if (!PyArg_ParseTuple(args, "lii|iid", &year, &month, &day, + &hour, &minute, &second)) + return NULL; + + micro = (second - floor(second)) * 1000000.0; + + obj = PyObject_CallFunction(pyDateTimeTypeP, "iiiiiii", + year, month, day, hour, minute, (int)round(second), (int)round(micro)); + + if (obj) { + res = PyObject_CallFunction((PyObject *)&pydatetimeType, + "Oi", obj, PSYCO_DATETIME_TIMESTAMP); + Py_DECREF(obj); + } + + return res; +} + +PyObject * +psyco_DateFromTicks(PyObject *self, PyObject *args) +{ + PyObject *res = NULL; + struct tm tm; + time_t t; + double ticks; + + if (!PyArg_ParseTuple(args, "d", &ticks)) + return NULL; + + t = (time_t)round(ticks); + if (gmtime_r(&t, &tm)) { + args = Py_BuildValue("iii", tm.tm_year, tm.tm_mon, tm.tm_mday); + if (args) { + res = psyco_Date(self, args); + Py_DECREF(args); + } + } + return res; +} + +PyObject * +psyco_TimeFromTicks(PyObject *self, PyObject *args) +{ + PyObject *res = NULL; + struct tm tm; + time_t t; + double ticks; + + if (!PyArg_ParseTuple(args,"d", &ticks)) + return NULL; + + t = (time_t)round(ticks); + if (gmtime_r(&t, &tm)) { + args = Py_BuildValue("iid", tm.tm_hour, tm.tm_min, (double)tm.tm_sec); + if (args) { + res = psyco_Time(self, args); + Py_DECREF(args); + } + } + return res; +} + +PyObject * +psyco_TimestampFromTicks(PyObject *self, PyObject *args) +{ + PyObject *res = NULL; + struct tm tm; + time_t t; + double ticks; + + if (!PyArg_ParseTuple(args,"d", &ticks)) + return NULL; + + t = (time_t)round(ticks); + if (gmtime_r(&t, &tm)) { + args = Py_BuildValue("iiiiid", + tm.tm_year, tm.tm_mon, tm.tm_mday, + tm.tm_hour, tm.tm_min, (double)tm.tm_sec); + if (args) { + res = psyco_Timestamp(self, args); + Py_DECREF(args); + } + } + return res; +} + +#endif + +PyObject * +psyco_DateFromPy(PyObject *self, PyObject *args) +{ + PyObject *obj; + + if (!PyArg_ParseTuple(args, "O!", pyDateTypeP, &obj)) + return NULL; + + return PyObject_CallFunction((PyObject *)&pydatetimeType, "Oi", obj, + PSYCO_DATETIME_DATE); +} + +PyObject * +psyco_TimeFromPy(PyObject *self, PyObject *args) +{ + PyObject *obj; + + if (!PyArg_ParseTuple(args, "O!", pyTimeTypeP, &obj)) + return NULL; + + return PyObject_CallFunction((PyObject *)&pydatetimeType, "Oi", obj, + PSYCO_DATETIME_TIME); +} + +PyObject * +psyco_TimestampFromPy(PyObject *self, PyObject *args) +{ + PyObject *obj; + + if (!PyArg_ParseTuple(args, "O!", pyDateTimeTypeP, &obj)) + return NULL; + + return PyObject_CallFunction((PyObject *)&pydatetimeType, "Oi", obj, + PSYCO_DATETIME_TIMESTAMP); +} + +PyObject * +psyco_IntervalFromPy(PyObject *self, PyObject *args) +{ + PyObject *obj; + + if (!PyArg_ParseTuple(args, "O!", pyDeltaTypeP, &obj)) + return NULL; + + return PyObject_CallFunction((PyObject *)&pydatetimeType, "Oi", obj, + PSYCO_DATETIME_INTERVAL); +} |