python-cx_Oracle/TimestampVar.c

239 lines
9.0 KiB
C

//-----------------------------------------------------------------------------
// TimestampVar.c
// Defines the routines for handling timestamp variables.
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Timestamp type
//-----------------------------------------------------------------------------
typedef struct {
Variable_HEAD
OCIDateTime **data;
} udt_TimestampVar;
//-----------------------------------------------------------------------------
// Declaration of date/time variable functions.
//-----------------------------------------------------------------------------
static int TimestampVar_Initialize(udt_TimestampVar*, udt_Cursor*);
static void TimestampVar_Finalize(udt_TimestampVar*);
static int TimestampVar_SetValue(udt_TimestampVar*, unsigned, PyObject*);
static PyObject *TimestampVar_GetValue(udt_TimestampVar*, unsigned);
//-----------------------------------------------------------------------------
// Python type declarations
//-----------------------------------------------------------------------------
static PyTypeObject g_TimestampVarType = {
PyObject_HEAD_INIT(NULL)
0, // ob_size
"cx_Oracle.TIMESTAMP", // tp_name
sizeof(udt_TimestampVar), // tp_basicsize
0, // tp_itemsize
(destructor) Variable_Free, // tp_dealloc
0, // tp_print
0, // tp_getattr
0, // tp_setattr
0, // tp_compare
(reprfunc) Variable_Repr, // tp_repr
0, // tp_as_number
0, // tp_as_sequence
0, // tp_as_mapping
0, // tp_hash
0, // tp_call
0, // tp_str
(getattrofunc) Variable_GetAttr, // tp_getattro
0, // tp_setattro
0, // tp_as_buffer
Py_TPFLAGS_DEFAULT, // tp_flags
0 // tp_doc
};
//-----------------------------------------------------------------------------
// variable type declarations
//-----------------------------------------------------------------------------
static udt_VariableType vt_Timestamp = {
(InitializeProc) TimestampVar_Initialize,
(FinalizeProc) TimestampVar_Finalize,
(PreDefineProc) NULL,
(PostDefineProc) NULL,
(IsNullProc) NULL,
(SetValueProc) TimestampVar_SetValue,
(GetValueProc) TimestampVar_GetValue,
&g_TimestampVarType, // Python type
SQLT_TIMESTAMP, // Oracle type
SQLCS_IMPLICIT, // charset form
sizeof(OCIDateTime*), // element length (default)
0, // is variable length
1, // can be copied
1 // can be in array
};
//-----------------------------------------------------------------------------
// TimestampVar_Initialize()
// Initialize the variable.
//-----------------------------------------------------------------------------
static int TimestampVar_Initialize(
udt_TimestampVar *var, // variable to initialize
udt_Cursor *cursor) // cursor variable associated with
{
sword status;
ub4 i;
// initialize the LOB locators
for (i = 0; i < var->allocatedElements; i++) {
status = OCIDescriptorAlloc(var->environment->handle,
(dvoid**) &var->data[i], OCI_DTYPE_TIMESTAMP, 0, 0);
if (Environment_CheckForError(var->environment, status,
"TimestampVar_Initialize()") < 0)
return -1;
}
return 0;
}
//-----------------------------------------------------------------------------
// TimestampVar_Finalize()
// Prepare for variable destruction.
//-----------------------------------------------------------------------------
static void TimestampVar_Finalize(
udt_TimestampVar *var) // variable to free
{
ub4 i;
for (i = 0; i < var->allocatedElements; i++) {
if (var->data[i])
OCIDescriptorFree(var->data[i], OCI_DTYPE_TIMESTAMP);
}
}
#ifdef NATIVE_DATETIME
//-----------------------------------------------------------------------------
// TimestampVar_SetValue()
// Set the value of the variable.
//-----------------------------------------------------------------------------
static int TimestampVar_SetValue(
udt_TimestampVar *var, // variable to set value for
unsigned pos, // array position to set
PyObject *value) // value to set
{
sword status;
uword valid;
// make sure a timestamp is being bound
if (!PyDateTime_Check(value)) {
PyErr_SetString(PyExc_TypeError, "expecting timestamp data");
return -1;
}
// store a copy of the value
status = OCIDateTimeConstruct(var->environment->handle,
var->environment->errorHandle, var->data[pos],
(sb2) PyDateTime_GET_YEAR(value),
PyDateTime_GET_MONTH(value),
PyDateTime_GET_DAY(value),
PyDateTime_DATE_GET_HOUR(value),
PyDateTime_DATE_GET_MINUTE(value),
PyDateTime_DATE_GET_SECOND(value),
PyDateTime_DATE_GET_MICROSECOND(value) * 1000, NULL, 0);
if (Environment_CheckForError(var->environment, status,
"TimestampVar_SetValue(): create structure") < 0)
return -1;
status = OCIDateTimeCheck(var->environment->handle,
var->environment->errorHandle, var->data[pos], &valid);
if (Environment_CheckForError(var->environment, status,
"TimestampVar_SetValue()") < 0)
return -1;
if (valid != 0) {
PyErr_SetString(g_DataErrorException, "invalid date");
return -1;
}
return 0;
}
#else
//-----------------------------------------------------------------------------
// TimestampVar_SetValue()
// Set the value of the variable.
//-----------------------------------------------------------------------------
static int TimestampVar_SetValue(
udt_TimestampVar *var, // variable to set value for
unsigned pos, // array position to set
PyObject *value) // value to set
{
udt_ExternalDateTimeVar *dateValue;
sword status;
uword valid;
// make sure a date is being bound
if (value->ob_type != &g_ExternalDateTimeVarType) {
PyErr_SetString(PyExc_TypeError, "expecting date data");
return -1;
}
// store a copy of the value
dateValue = (udt_ExternalDateTimeVar*) value;
status = OCIDateTimeConstruct(var->environment->handle,
var->environment->errorHandle, var->data[pos],
dateValue->year, dateValue->month, dateValue->day, dateValue->hour,
dateValue->minute, dateValue->second, dateValue->fsecond * 1000,
NULL, 0);
if (Environment_CheckForError(var->environment, status,
"TimestampVar_SetValue(): create structure") < 0)
return -1;
status = OCIDateTimeCheck(var->environment->handle,
var->environment->errorHandle, var->data[pos], &valid);
if (Environment_CheckForError(var->environment, status,
"TimestampVar_SetValue()") < 0)
return -1;
if (valid != 0) {
PyErr_SetString(g_DataErrorException, "invalid date");
return -1;
}
return 0;
}
#endif
//-----------------------------------------------------------------------------
// TimestampVar_GetValue()
// Returns the value stored at the given array position.
//-----------------------------------------------------------------------------
static PyObject *TimestampVar_GetValue(
udt_TimestampVar *var, // variable to determine value for
unsigned pos) // array position
{
ub1 hour, minute, second, month, day;
sword status;
ub4 fsecond;
sb2 year;
status = OCIDateTimeGetDate(var->environment->handle,
var->environment->errorHandle, var->data[pos], &year, &month,
&day);
if (Environment_CheckForError(var->environment, status,
"TimestampVar_GetValue(): date portion") < 0)
return NULL;
status = OCIDateTimeGetTime(var->environment->handle,
var->environment->errorHandle, var->data[pos], &hour, &minute,
&second, &fsecond);
if (Environment_CheckForError(var->environment, status,
"TimestampVar_GetValue(): time portion") < 0)
return NULL;
#ifdef NATIVE_DATETIME
return PyDateTime_FromDateAndTime(year, month, day, hour, minute, second,
fsecond / 1000);
#else
return ExternalDateTimeVar_NewFromC(&g_ExternalDateTimeVarType, year,
month, day, hour, minute, second, fsecond / 1000);
#endif
}