/* KInterbasDB Python Package - Implementation of Parameter Conversion DB->Py ** ** Version 3.1 ** ** The following contributors hold Copyright (C) over their respective ** portions of code (see license.txt for details): ** ** [Original Author (maintained through version 2.0-0.3.1):] ** 1998-2001 [alex] Alexander Kuznetsov ** [Maintainers (after version 2.0-0.3.1):] ** 2001-2002 [maz] Marek Isalski ** 2002-2004 [dsr] David Rushby ** [Contributors:] ** 2001 [eac] Evgeny A. Cherkashin ** 2001-2002 [janez] Janez Jere */ /* This source file is designed to be directly included in _kiconversion.c, ** without the involvement of a header file. */ static PyObject *conv_out_char(char *data, int size) { return PyString_FromStringAndSize(data, size); } /* conv_out_char */ static PyObject *conv_out_varchar(char *data) { /* The first sizeof(short) bytes contain the size of the string. */ return PyString_FromStringAndSize( data + sizeof(short), (int) *( (short *)data ) ); } /* conv_out_varchar */ static PyObject *_conv_out_integer_types( PyObject *py_raw, boolean is_fixed_point, short scale ) { if (!is_fixed_point) { /* Simply return the integer value. */ return py_raw; } else { /* We're converting a fixed-point rather than an integer; return a 2-tuple ** of the form: (value, scale) */ PyObject *fixed_tuple = PyTuple_New(2); PyObject *py_scale; if (fixed_tuple == NULL) { return NULL; } py_scale = PyInt_FromLong(scale); if (py_scale == NULL) { Py_DECREF(fixed_tuple); return NULL; } PyTuple_SET_ITEM(fixed_tuple, 0, py_raw); /* "steals" ref to py_raw */ PyTuple_SET_ITEM(fixed_tuple, 1, py_scale); /* "steals" ref to py_scale */ return fixed_tuple; } } /* _conv_out_integer_types_return_integer_or_fixed_tuple */ static PyObject *conv_out_short_long( char *data, short data_type, boolean is_fixed_point, short scale ) { /* 2004.04.16:64BC: On x86_64/1.5.1pre1, ISC_LONG is actually an int. */ long conv_long = (long)( data_type == SQL_SHORT ? ( *((ISC_SHORT *) data) ) : ( *((ISC_LONG *) data) ) ); PyObject *py_int = PyInt_FromLong(conv_long); return _conv_out_integer_types(py_int, is_fixed_point, scale); } /* conv_out_short_long */ #ifdef INTERBASE6_OR_LATER static PyObject *conv_out_int64(char *data, boolean is_fixed_point, short scale ) { const LONG_LONG dataLL = *((LONG_LONG *) data); PyObject *py_int = PythonIntOrLongFrom64BitValue(dataLL); return _conv_out_integer_types(py_int, is_fixed_point, scale); } /* conv_out_int64 */ #endif /* INTERBASE6_OR_LATER */ static PyObject *conv_out_floating(const double raw, const unsigned short dialect, const short scale ) { /* It's possible that a user would define a field as DECIMAL/NUMERIC with ** a scale of zero, but the API provides no way for us to detect that. */ if (dialect >= 3 || scale == 0) { return PyFloat_FromDouble(raw); }{ /* The value being converted is from a field that's logically fixed-point ** rather than floating-point. This can only arise in pre-dialect-3 ** databases. */ /* This is a perfect application for Py_BuildValue, but it doesn't ** support 64-bit integers. */ PyObject *fixed_tuple; PyObject *py_scaled_integer; PyObject *py_scale; fixed_tuple = PyTuple_New(2); if (fixed_tuple != NULL) { py_scaled_integer = PythonIntOrLongFrom64BitValue( (LONG_LONG) (raw * pow(10.0f, (double) -scale)) ); if (py_scaled_integer == NULL) { Py_DECREF(fixed_tuple); fixed_tuple = NULL; } else { py_scale = PyInt_FromLong(scale); if (py_scale == NULL) { Py_DECREF(fixed_tuple); fixed_tuple = NULL; Py_DECREF(py_scaled_integer); } else { PyTuple_SET_ITEM(fixed_tuple, 0, py_scaled_integer); /* "steals" ref */ PyTuple_SET_ITEM(fixed_tuple, 1, py_scale); /* "steals" ref */ } } } return fixed_tuple; }} /* conv_out_floating */ /* Date/time types: */ static PyObject *conv_out_timestamp(char *data) { struct tm c_tm; ENTER_DB isc_decode_timestamp( (ISC_TIMESTAMP *)data, &c_tm ); LEAVE_DB return Py_BuildValue("(iiiiii)", c_tm.tm_year+1900, c_tm.tm_mon+1, c_tm.tm_mday, c_tm.tm_hour, c_tm.tm_min, c_tm.tm_sec ); } /* conv_out_timestamp */ #ifdef INTERBASE6_OR_LATER static PyObject *conv_out_date(char *data) { struct tm c_tm; ENTER_DB isc_decode_sql_date( (ISC_DATE *)data, &c_tm ); LEAVE_DB return Py_BuildValue("(iii)", c_tm.tm_year+1900, c_tm.tm_mon+1, c_tm.tm_mday); } /* conv_out_date */ static PyObject *conv_out_time(char *data) { struct tm c_tm; ENTER_DB isc_decode_sql_time( (ISC_TIME *)data, &c_tm ); LEAVE_DB return Py_BuildValue("(iii)", c_tm.tm_hour, c_tm.tm_min, c_tm.tm_sec); } /* conv_out_time */ #endif /* INTERBASE6_OR_LATER */