3 Star 9 Fork 0

Gitee 极速下载/cx-oracle

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
此仓库是为了提升国内下载速度的镜像仓库,每日同步一次。 原始仓库: https://github.com/oracle/python-cx_Oracle
克隆/下载
cxoObject.c 22.52 KB
一键复制 编辑 原始数据 按行查看 历史
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661
//-----------------------------------------------------------------------------
// Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
//
// Portions Copyright 2007-2015, Anthony Tuininga. All rights reserved.
//
// Portions Copyright 2001-2007, Computronix (Canada) Ltd., Edmonton, Alberta,
// Canada. All rights reserved.
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// cxoObject.c
// Defines the routines for handling objects in Oracle.
//-----------------------------------------------------------------------------
#include "cxoModule.h"
//-----------------------------------------------------------------------------
// cxoObject_new()
// Create a new object.
//-----------------------------------------------------------------------------
PyObject *cxoObject_new(cxoObjectType *objectType, dpiObject *handle)
{
cxoObject *obj;
obj = (cxoObject*) cxoPyTypeObject.tp_alloc(&cxoPyTypeObject, 0);
if (!obj)
return NULL;
Py_INCREF(objectType);
obj->objectType = objectType;
obj->handle = handle;
return (PyObject*) obj;
}
//-----------------------------------------------------------------------------
// cxoObject_free()
// Free an object.
//-----------------------------------------------------------------------------
static void cxoObject_free(cxoObject *obj)
{
if (obj->handle) {
dpiObject_release(obj->handle);
obj->handle = NULL;
}
Py_CLEAR(obj->objectType);
Py_TYPE(obj)->tp_free((PyObject*) obj);
}
//-----------------------------------------------------------------------------
// cxoObject_repr()
// Return a string representation of the object.
//-----------------------------------------------------------------------------
static PyObject *cxoObject_repr(cxoObject *obj)
{
PyObject *module, *name, *result;
if (cxoUtils_getModuleAndName(Py_TYPE(obj), &module, &name) < 0)
return NULL;
result = cxoUtils_formatString("<%s.%s %s.%s at %#x>",
Py_BuildValue("(OOOOl)", module, name, obj->objectType->schema,
obj->objectType->name, obj));
Py_DECREF(module);
Py_DECREF(name);
return result;
}
//-----------------------------------------------------------------------------
// cxoObject_convertFromPython()
// Convert a Python value to an Oracle value.
//-----------------------------------------------------------------------------
static int cxoObject_convertFromPython(cxoObject *obj, PyObject *value,
cxoTransformNum transformNum, dpiNativeTypeNum *nativeTypeNum,
dpiData *data, cxoBuffer *buffer)
{
dpiOracleTypeNum oracleTypeNum;
// None is treated as null
if (value == Py_None) {
data->isNull = 1;
return 0;
}
// convert the different Python types
cxoTransform_getTypeInfo(transformNum, &oracleTypeNum, nativeTypeNum);
if (cxoTransform_fromPython(transformNum, nativeTypeNum, value,
&data->value, buffer,
obj->objectType->connection->encodingInfo.encoding,
obj->objectType->connection->encodingInfo.nencoding, NULL, 0) < 0)
return -1;
data->isNull = 0;
return 0;
}
//-----------------------------------------------------------------------------
// cxoObject_convertToPython()
// Convert an Oracle value to a Python value.
//-----------------------------------------------------------------------------
static PyObject *cxoObject_convertToPython(cxoObject *obj,
cxoTransformNum transformNum, dpiData *data, cxoObjectType *objType)
{
if (data->isNull)
Py_RETURN_NONE;
return cxoTransform_toPython(transformNum, obj->objectType->connection,
objType, &data->value, NULL);
}
//-----------------------------------------------------------------------------
// cxoObject_getAttributeValue()
// Retrieve an attribute on the object.
//-----------------------------------------------------------------------------
static PyObject *cxoObject_getAttributeValue(cxoObject *obj,
cxoObjectAttr *attribute)
{
char numberAsStringBuffer[200], message[120];
dpiOracleTypeNum oracleTypeNum;
dpiNativeTypeNum nativeTypeNum;
dpiData data;
if (attribute->transformNum == CXO_TRANSFORM_UNSUPPORTED) {
snprintf(message, sizeof(message), "Oracle type %d not supported.",
attribute->oracleTypeNum);
return cxoError_raiseFromString(cxoNotSupportedErrorException,
message);
}
cxoTransform_getTypeInfo(attribute->transformNum, &oracleTypeNum,
&nativeTypeNum);
if (oracleTypeNum == DPI_ORACLE_TYPE_NUMBER &&
nativeTypeNum == DPI_NATIVE_TYPE_BYTES) {
data.value.asBytes.ptr = numberAsStringBuffer;
data.value.asBytes.length = sizeof(numberAsStringBuffer);
data.value.asBytes.encoding = NULL;
}
if (dpiObject_getAttributeValue(obj->handle, attribute->handle,
nativeTypeNum, &data) < 0)
return cxoError_raiseAndReturnNull();
return cxoObject_convertToPython(obj, attribute->transformNum, &data,
attribute->objectType);
}
//-----------------------------------------------------------------------------
// cxoObject_setAttributeValue()
// Set an attribute on the object.
//-----------------------------------------------------------------------------
static int cxoObject_setAttributeValue(cxoObject *obj,
cxoObjectAttr *attribute, PyObject *value)
{
dpiNativeTypeNum nativeTypeNum = 0;
cxoBuffer buffer;
dpiData data;
int status;
cxoBuffer_init(&buffer);
if (cxoObject_convertFromPython(obj, value, attribute->transformNum,
&nativeTypeNum, &data, &buffer) < 0)
return -1;
status = dpiObject_setAttributeValue(obj->handle, attribute->handle,
nativeTypeNum, &data);
cxoBuffer_clear(&buffer);
if (status < 0)
return cxoError_raiseAndReturnInt();
return 0;
}
//-----------------------------------------------------------------------------
// cxoObject_getAttr()
// Retrieve an attribute on an object.
//-----------------------------------------------------------------------------
static PyObject *cxoObject_getAttr(cxoObject *obj, PyObject *nameObject)
{
cxoObjectAttr *attribute;
attribute = (cxoObjectAttr*)
PyDict_GetItem(obj->objectType->attributesByName, nameObject);
if (attribute)
return cxoObject_getAttributeValue(obj, attribute);
return PyObject_GenericGetAttr( (PyObject*) obj, nameObject);
}
//-----------------------------------------------------------------------------
// cxoObject_setAttr()
// Set an attribute on an object.
//-----------------------------------------------------------------------------
static int cxoObject_setAttr(cxoObject *obj, PyObject *nameObject,
PyObject *value)
{
cxoObjectAttr *attribute;
attribute = (cxoObjectAttr*)
PyDict_GetItem(obj->objectType->attributesByName, nameObject);
if (attribute)
return cxoObject_setAttributeValue(obj, attribute, value);
return PyObject_GenericSetAttr( (PyObject*) obj, nameObject, value);
}
//-----------------------------------------------------------------------------
// cxoObject_internalAppend()
// Append an item to the collection.
//-----------------------------------------------------------------------------
static int cxoObject_internalAppend(cxoObject *obj, PyObject *value)
{
dpiNativeTypeNum nativeTypeNum = 0;
cxoBuffer buffer;
dpiData data;
int status;
cxoBuffer_init(&buffer);
if (cxoObject_convertFromPython(obj, value,
obj->objectType->elementTransformNum, &nativeTypeNum, &data,
&buffer) < 0)
return -1;
status = dpiObject_appendElement(obj->handle, nativeTypeNum, &data);
cxoBuffer_clear(&buffer);
if (status < 0)
return cxoError_raiseAndReturnInt();
return 0;
}
//-----------------------------------------------------------------------------
// cxoObject_internalExtend()
// Extend the collection by appending each of the items in the sequence.
//-----------------------------------------------------------------------------
int cxoObject_internalExtend(cxoObject *obj, PyObject *sequence)
{
PyObject *fastSequence, *element;
Py_ssize_t size, i;
fastSequence = PySequence_Fast(sequence, "expecting sequence");
if (!fastSequence)
return -1;
size = PySequence_Fast_GET_SIZE(fastSequence);
for (i = 0; i < size; i++) {
element = PySequence_Fast_GET_ITEM(fastSequence, i);
if (cxoObject_internalAppend(obj, element) < 0) {
Py_DECREF(fastSequence);
return -1;
}
}
Py_DECREF(fastSequence);
return 0;
}
//-----------------------------------------------------------------------------
// cxoObject_append()
// Append an item to the collection.
//-----------------------------------------------------------------------------
static PyObject *cxoObject_append(cxoObject *obj, PyObject *value)
{
if (cxoObject_internalAppend(obj, value) < 0)
return NULL;
Py_RETURN_NONE;
}
//-----------------------------------------------------------------------------
// cxoObject_internalGetElementByIndex()
// Internal method used for getting an element value for a particular index.
//-----------------------------------------------------------------------------
static PyObject *cxoObject_internalGetElementByIndex(cxoObject *obj,
int32_t index)
{
char numberAsStringBuffer[200], message[120];
dpiOracleTypeNum oracleTypeNum;
dpiNativeTypeNum nativeTypeNum;
dpiData data;
if (obj->objectType->elementTransformNum == CXO_TRANSFORM_UNSUPPORTED) {
snprintf(message, sizeof(message), "Oracle type %d not supported.",
obj->objectType->elementOracleTypeNum);
return cxoError_raiseFromString(cxoNotSupportedErrorException,
message);
}
cxoTransform_getTypeInfo(obj->objectType->elementTransformNum,
&oracleTypeNum, &nativeTypeNum);
if (oracleTypeNum == DPI_ORACLE_TYPE_NUMBER &&
nativeTypeNum == DPI_NATIVE_TYPE_BYTES) {
data.value.asBytes.ptr = numberAsStringBuffer;
data.value.asBytes.length = sizeof(numberAsStringBuffer);
data.value.asBytes.encoding = NULL;
}
if (dpiObject_getElementValueByIndex(obj->handle, index, nativeTypeNum,
&data) < 0)
return cxoError_raiseAndReturnNull();
return cxoObject_convertToPython(obj, obj->objectType->elementTransformNum,
&data, obj->objectType->elementObjectType);
}
//-----------------------------------------------------------------------------
// cxoObject_asDict()
// Returns a collection as a dictionary. If the object is not a collection,
// an error is returned.
//-----------------------------------------------------------------------------
static PyObject *cxoObject_asDict(cxoObject *obj, PyObject *args)
{
PyObject *dict, *key, *value;
int32_t index, nextIndex;
int exists;
// create the result dictionary
dict = PyDict_New();
if (!dict)
return NULL;
// populate it with each of the elements in the collection
if (dpiObject_getFirstIndex(obj->handle, &index, &exists) < 0) {
Py_DECREF(dict);
return cxoError_raiseAndReturnNull();
}
while (exists) {
value = cxoObject_internalGetElementByIndex(obj, index);
if (!value) {
Py_DECREF(dict);
return NULL;
}
key = PyLong_FromLong(index);
if (!key) {
Py_DECREF(value);
Py_DECREF(dict);
return NULL;
}
if (PyDict_SetItem(dict, key, value) < 0) {
Py_DECREF(key);
Py_DECREF(value);
Py_DECREF(dict);
return NULL;
}
Py_DECREF(key);
Py_DECREF(value);
if (dpiObject_getNextIndex(obj->handle, index, &nextIndex,
&exists) < 0) {
Py_DECREF(dict);
return cxoError_raiseAndReturnNull();
}
index = nextIndex;
}
return dict;
}
//-----------------------------------------------------------------------------
// cxoObject_asList()
// Returns a collection as a list of elements. If the object is not a
// collection, an error is returned.
//-----------------------------------------------------------------------------
static PyObject *cxoObject_asList(cxoObject *obj, PyObject *args)
{
PyObject *list, *elementValue;
int32_t index, nextIndex;
int exists;
// create the result list
list = PyList_New(0);
if (!list)
return NULL;
// populate it with each of the elements in the list
if (dpiObject_getFirstIndex(obj->handle, &index, &exists) < 0) {
Py_DECREF(list);
return cxoError_raiseAndReturnNull();
}
while (exists) {
elementValue = cxoObject_internalGetElementByIndex(obj, index);
if (!elementValue) {
Py_DECREF(list);
return NULL;
}
if (PyList_Append(list, elementValue) < 0) {
Py_DECREF(elementValue);
Py_DECREF(list);
return NULL;
}
Py_DECREF(elementValue);
if (dpiObject_getNextIndex(obj->handle, index, &nextIndex,
&exists) < 0) {
Py_DECREF(list);
return cxoError_raiseAndReturnNull();
}
index = nextIndex;
}
return list;
}
//-----------------------------------------------------------------------------
// cxoObject_copy()
// Return a copy of the object.
//-----------------------------------------------------------------------------
static PyObject *cxoObject_copy(cxoObject *obj, PyObject *args)
{
PyObject *copiedObj;
dpiObject *handle;
if (dpiObject_copy(obj->handle, &handle) < 0)
return cxoError_raiseAndReturnNull();
copiedObj = cxoObject_new(obj->objectType, handle);
if (!copiedObj) {
dpiObject_release(handle);
return NULL;
}
return copiedObj;
}
//-----------------------------------------------------------------------------
// cxoObject_delete()
// Delete the element at the specified index in the collection.
//-----------------------------------------------------------------------------
static PyObject *cxoObject_delete(cxoObject *obj, PyObject *args)
{
int32_t index;
if (!PyArg_ParseTuple(args, "i", &index))
return NULL;
if (dpiObject_deleteElementByIndex(obj->handle, index) < 0)
return cxoError_raiseAndReturnNull();
Py_RETURN_NONE;
}
//-----------------------------------------------------------------------------
// cxoObject_exists()
// Return true or false indicating if an element exists in the collection at
// the specified index.
//-----------------------------------------------------------------------------
static PyObject *cxoObject_exists(cxoObject *obj, PyObject *args)
{
int32_t index;
int exists;
if (!PyArg_ParseTuple(args, "i", &index))
return NULL;
if (dpiObject_getElementExistsByIndex(obj->handle, index, &exists) < 0)
return cxoError_raiseAndReturnNull();
if (exists)
Py_RETURN_TRUE;
Py_RETURN_FALSE;
}
//-----------------------------------------------------------------------------
// cxoObject_extend()
// Extend the collection by appending each of the items in the sequence.
//-----------------------------------------------------------------------------
static PyObject *cxoObject_extend(cxoObject *obj, PyObject *sequence)
{
if (cxoObject_internalExtend(obj, sequence) < 0)
return NULL;
Py_RETURN_NONE;
}
//-----------------------------------------------------------------------------
// cxoObject_getElement()
// Return the element at the given position in the collection.
//-----------------------------------------------------------------------------
static PyObject *cxoObject_getElement(cxoObject *obj, PyObject *args)
{
int32_t index;
if (!PyArg_ParseTuple(args, "i", &index))
return NULL;
return cxoObject_internalGetElementByIndex(obj, index);
}
//-----------------------------------------------------------------------------
// cxoObject_getFirstIndex()
// Return the index of the first entry in the collection.
//-----------------------------------------------------------------------------
static PyObject *cxoObject_getFirstIndex(cxoObject *obj, PyObject *args)
{
int32_t index;
int exists;
if (dpiObject_getFirstIndex(obj->handle, &index, &exists) < 0)
return cxoError_raiseAndReturnNull();
if (exists)
return PyLong_FromLong(index);
Py_RETURN_NONE;
}
//-----------------------------------------------------------------------------
// cxoObject_getLastIndex()
// Return the index of the last entry in the collection.
//-----------------------------------------------------------------------------
static PyObject *cxoObject_getLastIndex(cxoObject *obj, PyObject *args)
{
int32_t index;
int exists;
if (dpiObject_getLastIndex(obj->handle, &index, &exists) < 0)
return cxoError_raiseAndReturnNull();
if (exists)
return PyLong_FromLong(index);
Py_RETURN_NONE;
}
//-----------------------------------------------------------------------------
// cxoObject_getNextIndex()
// Return the index of the next entry in the collection following the index
// specified. If there is no next entry, None is returned.
//-----------------------------------------------------------------------------
static PyObject *cxoObject_getNextIndex(cxoObject *obj, PyObject *args)
{
int32_t index, nextIndex;
int exists;
if (!PyArg_ParseTuple(args, "i", &index))
return NULL;
if (dpiObject_getNextIndex(obj->handle, index, &nextIndex, &exists) < 0)
return cxoError_raiseAndReturnNull();
if (exists)
return PyLong_FromLong(nextIndex);
Py_RETURN_NONE;
}
//-----------------------------------------------------------------------------
// cxoObject_getPrevIndex()
// Return the index of the previous entry in the collection preceding the
// index specified. If there is no previous entry, None is returned.
//-----------------------------------------------------------------------------
static PyObject *cxoObject_getPrevIndex(cxoObject *obj, PyObject *args)
{
int32_t index, prevIndex;
int exists;
if (!PyArg_ParseTuple(args, "i", &index))
return NULL;
if (dpiObject_getPrevIndex(obj->handle, index, &prevIndex, &exists) < 0)
return cxoError_raiseAndReturnNull();
if (exists)
return PyLong_FromLong(prevIndex);
Py_RETURN_NONE;
}
//-----------------------------------------------------------------------------
// cxoObject_getSize()
// Return the size of a collection. If the object is not a collection, an
// error is returned.
//-----------------------------------------------------------------------------
static PyObject *cxoObject_getSize(cxoObject *obj, PyObject *args)
{
int32_t size;
if (dpiObject_getSize(obj->handle, &size) < 0)
return cxoError_raiseAndReturnNull();
return PyLong_FromLong(size);
}
//-----------------------------------------------------------------------------
// cxoObject_setElement()
// Set the element at the specified location to the given value.
//-----------------------------------------------------------------------------
static PyObject *cxoObject_setElement(cxoObject *obj, PyObject *args)
{
dpiNativeTypeNum nativeTypeNum = 0;
cxoBuffer buffer;
PyObject *value;
int32_t index;
dpiData data;
int status;
if (!PyArg_ParseTuple(args, "iO", &index, &value))
return NULL;
cxoBuffer_init(&buffer);
if (cxoObject_convertFromPython(obj, value,
obj->objectType->elementTransformNum, &nativeTypeNum, &data,
&buffer) < 0)
return NULL;
status = dpiObject_setElementValueByIndex(obj->handle, index,
nativeTypeNum, &data);
cxoBuffer_clear(&buffer);
if (status < 0)
return cxoError_raiseAndReturnNull();
Py_RETURN_NONE;
}
//-----------------------------------------------------------------------------
// cxoObject_trim()
// Trim a number of elements from the end of the collection.
//-----------------------------------------------------------------------------
static PyObject *cxoObject_trim(cxoObject *obj, PyObject *args)
{
int32_t numToTrim;
if (!PyArg_ParseTuple(args, "i", &numToTrim))
return NULL;
if (dpiObject_trim(obj->handle, numToTrim) < 0)
return cxoError_raiseAndReturnNull();
Py_RETURN_NONE;
}
//-----------------------------------------------------------------------------
// declaration of methods for Python type
//-----------------------------------------------------------------------------
static PyMethodDef cxoObjectMethods[] = {
{ "append", (PyCFunction) cxoObject_append, METH_O },
{ "asdict", (PyCFunction) cxoObject_asDict, METH_NOARGS },
{ "aslist", (PyCFunction) cxoObject_asList, METH_NOARGS },
{ "copy", (PyCFunction) cxoObject_copy, METH_NOARGS },
{ "delete", (PyCFunction) cxoObject_delete, METH_VARARGS },
{ "exists", (PyCFunction) cxoObject_exists, METH_VARARGS },
{ "extend", (PyCFunction) cxoObject_extend, METH_O },
{ "first", (PyCFunction) cxoObject_getFirstIndex, METH_NOARGS },
{ "getelement", (PyCFunction) cxoObject_getElement, METH_VARARGS },
{ "last", (PyCFunction) cxoObject_getLastIndex, METH_NOARGS },
{ "next", (PyCFunction) cxoObject_getNextIndex, METH_VARARGS },
{ "prev", (PyCFunction) cxoObject_getPrevIndex, METH_VARARGS },
{ "setelement", (PyCFunction) cxoObject_setElement, METH_VARARGS },
{ "size", (PyCFunction) cxoObject_getSize, METH_NOARGS },
{ "trim", (PyCFunction) cxoObject_trim, METH_VARARGS },
{ NULL, NULL }
};
//-----------------------------------------------------------------------------
// Declaration of members for Python type
//-----------------------------------------------------------------------------
static PyMemberDef cxoObjectMembers[] = {
{ "type", T_OBJECT, offsetof(cxoObject, objectType), READONLY },
{ NULL }
};
//-----------------------------------------------------------------------------
// Python type declaration
//-----------------------------------------------------------------------------
PyTypeObject cxoPyTypeObject = {
PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "cx_Oracle.Object",
.tp_basicsize = sizeof(cxoObject),
.tp_dealloc = (destructor) cxoObject_free,
.tp_repr = (reprfunc) cxoObject_repr,
.tp_getattro = (getattrofunc) cxoObject_getAttr,
.tp_setattro = (setattrofunc) cxoObject_setAttr,
.tp_flags = Py_TPFLAGS_DEFAULT,
.tp_methods = cxoObjectMethods,
.tp_members = cxoObjectMembers
};
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C/C++
1
https://gitee.com/mirrors/cx-oracle.git
git@gitee.com:mirrors/cx-oracle.git
mirrors
cx-oracle
cx-oracle
main

搜索帮助