Added support for the rows in the change notification message.
This commit is contained in:
parent
825c78c87c
commit
46eeb000b5
146
Subscription.c
146
Subscription.c
@ -32,6 +32,12 @@ typedef struct {
|
|||||||
ub4 operation;
|
ub4 operation;
|
||||||
} udt_MessageTable;
|
} udt_MessageTable;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
PyObject_HEAD
|
||||||
|
PyObject *rowid;
|
||||||
|
ub4 operation;
|
||||||
|
} udt_MessageRow;
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Declaration of subscription functions
|
// Declaration of subscription functions
|
||||||
@ -41,6 +47,7 @@ static PyObject *Subscription_Repr(udt_Subscription*);
|
|||||||
static PyObject *Subscription_RegisterQuery(udt_Subscription*, PyObject*);
|
static PyObject *Subscription_RegisterQuery(udt_Subscription*, PyObject*);
|
||||||
static void Message_Free(udt_Message*);
|
static void Message_Free(udt_Message*);
|
||||||
static void MessageTable_Free(udt_MessageTable*);
|
static void MessageTable_Free(udt_MessageTable*);
|
||||||
|
static void MessageRow_Free(udt_MessageRow*);
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// declaration of members for Python types
|
// declaration of members for Python types
|
||||||
@ -71,6 +78,12 @@ static PyMemberDef g_MessageTableTypeMembers[] = {
|
|||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static PyMemberDef g_MessageRowTypeMembers[] = {
|
||||||
|
{ "rowid", T_OBJECT, offsetof(udt_MessageRow, rowid), READONLY },
|
||||||
|
{ "operation", T_INT, offsetof(udt_MessageRow, operation), READONLY },
|
||||||
|
{ NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// declaration of methods for Python types
|
// declaration of methods for Python types
|
||||||
@ -218,6 +231,85 @@ static PyTypeObject g_MessageTableType = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static PyTypeObject g_MessageRowType = {
|
||||||
|
PyVarObject_HEAD_INIT(NULL, 0)
|
||||||
|
"cx_Oracle.MessageRow", // tp_name
|
||||||
|
sizeof(udt_MessageRow), // tp_basicsize
|
||||||
|
0, // tp_itemsize
|
||||||
|
(destructor) MessageRow_Free, // tp_dealloc
|
||||||
|
0, // tp_print
|
||||||
|
0, // tp_getattr
|
||||||
|
0, // tp_setattr
|
||||||
|
0, // tp_compare
|
||||||
|
0, // tp_repr
|
||||||
|
0, // tp_as_number
|
||||||
|
0, // tp_as_sequence
|
||||||
|
0, // tp_as_mapping
|
||||||
|
0, // tp_hash
|
||||||
|
0, // tp_call
|
||||||
|
0, // tp_str
|
||||||
|
0, // tp_getattro
|
||||||
|
0, // tp_setattro
|
||||||
|
0, // tp_as_buffer
|
||||||
|
Py_TPFLAGS_DEFAULT, // tp_flags
|
||||||
|
0, // tp_doc
|
||||||
|
0, // tp_traverse
|
||||||
|
0, // tp_clear
|
||||||
|
0, // tp_richcompare
|
||||||
|
0, // tp_weaklistoffset
|
||||||
|
0, // tp_iter
|
||||||
|
0, // tp_iternext
|
||||||
|
0, // tp_methods
|
||||||
|
g_MessageRowTypeMembers, // tp_members
|
||||||
|
0, // tp_getset
|
||||||
|
0, // tp_base
|
||||||
|
0, // tp_dict
|
||||||
|
0, // tp_descr_get
|
||||||
|
0, // tp_descr_set
|
||||||
|
0, // tp_dictoffset
|
||||||
|
0, // tp_init
|
||||||
|
0, // tp_alloc
|
||||||
|
0, // tp_new
|
||||||
|
0, // tp_free
|
||||||
|
0, // tp_is_gc
|
||||||
|
0 // tp_bases
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// MessageRow_Initialize()
|
||||||
|
// Initialize a new message row with the information from the descriptor.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
static int MessageRow_Initialize(
|
||||||
|
udt_MessageRow *self, // object to initialize
|
||||||
|
udt_Environment *env, // environment to use
|
||||||
|
dvoid *descriptor) // descriptor to get information from
|
||||||
|
{
|
||||||
|
ub4 rowidLength;
|
||||||
|
sword status;
|
||||||
|
char *rowid;
|
||||||
|
|
||||||
|
// determine operation
|
||||||
|
status = OCIAttrGet(descriptor, OCI_DTYPE_ROW_CHDES, &self->operation,
|
||||||
|
NULL, OCI_ATTR_CHDES_ROW_OPFLAGS, env->errorHandle);
|
||||||
|
if (Environment_CheckForError(env, status,
|
||||||
|
"MessageRow_Initialize(): get operation") < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
// determine table name
|
||||||
|
status = OCIAttrGet(descriptor, OCI_DTYPE_ROW_CHDES, &rowid, &rowidLength,
|
||||||
|
OCI_ATTR_CHDES_ROW_ROWID, env->errorHandle);
|
||||||
|
if (Environment_CheckForError(env, status,
|
||||||
|
"MessageRow_Initialize(): get rowid") < 0)
|
||||||
|
return -1;
|
||||||
|
self->rowid = cxString_FromEncodedString(rowid, rowidLength);
|
||||||
|
if (!self->rowid)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// MessageTable_Initialize()
|
// MessageTable_Initialize()
|
||||||
// Initialize a new message table with the information from the descriptor.
|
// Initialize a new message table with the information from the descriptor.
|
||||||
@ -227,7 +319,11 @@ static int MessageTable_Initialize(
|
|||||||
udt_Environment *env, // environment to use
|
udt_Environment *env, // environment to use
|
||||||
dvoid *descriptor) // descriptor to get information from
|
dvoid *descriptor) // descriptor to get information from
|
||||||
{
|
{
|
||||||
ub4 nameLength;
|
dvoid **rowDescriptor, *indicator;
|
||||||
|
ub4 nameLength, i, numRows;
|
||||||
|
udt_MessageRow *row;
|
||||||
|
boolean exists;
|
||||||
|
OCIColl *rows;
|
||||||
sword status;
|
sword status;
|
||||||
char *name;
|
char *name;
|
||||||
|
|
||||||
@ -248,6 +344,42 @@ static int MessageTable_Initialize(
|
|||||||
if (!self->name)
|
if (!self->name)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
// if change invalidated all rows, nothing to do
|
||||||
|
if (self->operation & OCI_OPCODE_ALLROWS)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// determine rows collection
|
||||||
|
status = OCIAttrGet(descriptor, OCI_DTYPE_TABLE_CHDES, &rows, NULL,
|
||||||
|
OCI_ATTR_CHDES_TABLE_ROW_CHANGES, env->errorHandle);
|
||||||
|
if (Environment_CheckForError(env, status,
|
||||||
|
"MessageTable_Initialize(): get rows collection") < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
// determine number of rows in collection
|
||||||
|
status = OCICollSize(env->handle, env->errorHandle, rows, &numRows);
|
||||||
|
if (Environment_CheckForError(env, status,
|
||||||
|
"MessageTable_Initialize(): get size of rows collection") < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
// populate the rows attribute
|
||||||
|
self->rows = PyList_New(numRows);
|
||||||
|
if (!self->rows)
|
||||||
|
return -1;
|
||||||
|
for (i = 0; i < numRows; i++) {
|
||||||
|
status = OCICollGetElem(env->handle, env->errorHandle, rows, i,
|
||||||
|
&exists, (dvoid*) &rowDescriptor, &indicator);
|
||||||
|
if (Environment_CheckForError(env, status,
|
||||||
|
"MessageTable_Initialize(): get element from collection") < 0)
|
||||||
|
return -1;
|
||||||
|
row = (udt_MessageRow*)
|
||||||
|
g_MessageRowType.tp_alloc(&g_MessageRowType, 0);
|
||||||
|
if (!row)
|
||||||
|
return -1;
|
||||||
|
PyList_SET_ITEM(self->rows, i, (PyObject*) row);
|
||||||
|
if (MessageRow_Initialize(row, env, *rowDescriptor) < 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -727,3 +859,15 @@ static void MessageTable_Free(
|
|||||||
Py_TYPE(self)->tp_free((PyObject*) self);
|
Py_TYPE(self)->tp_free((PyObject*) self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// MessageRow_Free()
|
||||||
|
// Free the memory associated with a row in a message.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
static void MessageRow_Free(
|
||||||
|
udt_MessageRow *self) // object to free
|
||||||
|
{
|
||||||
|
Py_CLEAR(self->rowid);
|
||||||
|
Py_TYPE(self)->tp_free((PyObject*) self);
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@ -351,6 +351,7 @@ static PyObject *Module_Initialize(void)
|
|||||||
MAKE_TYPE_READY(&g_SubscriptionType);
|
MAKE_TYPE_READY(&g_SubscriptionType);
|
||||||
MAKE_TYPE_READY(&g_MessageType);
|
MAKE_TYPE_READY(&g_MessageType);
|
||||||
MAKE_TYPE_READY(&g_MessageTableType);
|
MAKE_TYPE_READY(&g_MessageTableType);
|
||||||
|
MAKE_TYPE_READY(&g_MessageRowType);
|
||||||
#endif
|
#endif
|
||||||
MAKE_VARIABLE_TYPE_READY(&g_StringVarType);
|
MAKE_VARIABLE_TYPE_READY(&g_StringVarType);
|
||||||
MAKE_VARIABLE_TYPE_READY(&g_FixedCharVarType);
|
MAKE_VARIABLE_TYPE_READY(&g_FixedCharVarType);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user