Moved Objects from c to python code

Indicator, BINARY, NUMBER, STRING and DATE objects were moved
to python code
This commit is contained in:
Georg Richter
2020-11-30 16:49:16 +01:00
parent e8d7854fef
commit 7df428ecf8
10 changed files with 75 additions and 472 deletions

View File

@ -93,15 +93,6 @@ int clock_gettime(int dummy, struct timespec *ct);
/* Magic constant for checking dynamic columns */
#define PYTHON_DYNCOL_VALUE 0xA378BD8E
enum enum_dataapi_groups
{
DBAPI_NUMBER= 1,
DBAPI_STRING,
DBAPI_DATETIME,
DBAPI_BINARY,
DBAPI_ROWID
};
enum enum_extended_field_type
{
EXT_TYPE_NONE=0,
@ -210,7 +201,7 @@ typedef struct mrdb_pool{
typedef struct {
enum enum_field_types type;
PyObject *Value;
char indicator;
uint8_t indicator;
} Mariadb_Value;
/* Parameter info for cursor.executemany()
@ -233,11 +224,6 @@ typedef struct {
MYSQL_TIME tm;
} MrdbParamValue;
typedef struct {
PyObject_HEAD
enum enum_indicator_type indicator;
} MrdbIndicator;
/* PEP-249: Cursor object */
typedef struct {
PyObject_HEAD
@ -281,12 +267,6 @@ typedef struct
PyObject_HEAD
} Mariadb_Fieldinfo;
typedef struct
{
PyObject_HEAD
int32_t *types;
} Mariadb_DBAPIType;
typedef struct {
ps_field_fetch_func func;
int pack_len;
@ -314,10 +294,8 @@ extern PyObject *decimal_module,
/* Object types */
extern PyTypeObject MrdbPool_Type;
extern PyTypeObject Mariadb_Fieldinfo_Type;
extern PyTypeObject MrdbIndicator_Type;
extern PyTypeObject MrdbConnection_Type;
extern PyTypeObject MrdbCursor_Type;
extern PyTypeObject Mariadb_DBAPIType_Type;
int Mariadb_traverse(PyObject *self,
visitproc visit,
@ -333,15 +311,6 @@ mariadb_throw_exception(void *handle,
enum enum_extended_field_type mariadb_extended_field_type(const MYSQL_FIELD *field);
PyObject *
MrdbIndicator_Object(uint32_t type);
long
MrdbIndicator_AsLong(PyObject *v);
PyObject *
Mariadb_DBAPIType_Object(uint32_t type);
PyObject *
MrdbConnection_affected_rows(MrdbConnection *self);
@ -468,7 +437,7 @@ if ((obj)->thread_state)\
}
#define MrdbIndicator_Check(a)\
(Py_TYPE((a)) == &MrdbIndicator_Type)
(PyObject_HasAttrString(a, "indicator"))
#define MARIADB_CHECK_CONNECTION(connection, ret)\
if (!(connection) || !(connection)->mysql)\

View File

@ -8,10 +8,8 @@ Minimum supported Python version is 3.6
'''
from ._mariadb import (
BINARY,
Binary,
ConnectionPool,
DATETIME,
DataError,
DatabaseError,
Date,
@ -20,13 +18,10 @@ from ._mariadb import (
IntegrityError,
InterfaceError,
InternalError,
NUMBER,
NotSupportedError,
OperationalError,
PoolError,
ProgrammingError,
ROWID,
STRING,
Time,
TimeFromTicks,
Timestamp,
@ -35,14 +30,53 @@ from ._mariadb import (
_CONNECTION_POOLS,
__version__,
__version_info__,
apilevel,
paramstyle,
threadsafety,
connect,
fieldinfo,
mariadbapi_version,
)
apilevel = '2.0'
paramstyle = 'qmark'
threadsafety = True
from mariadb.constants import FIELD_TYPE
class DbApiType(frozenset):
def __eq__(self, field_type):
if (isinstance(field_type, DbApiType)):
return not self.difference(field_type)
return field_type in self
BINARY = DbApiType([FIELD_TYPE.GEOMETRY,
FIELD_TYPE.LONG_BLOB,
FIELD_TYPE.MEDIUM_BLOB,
FIELD_TYPE.TINY_BLOB,
FIELD_TYPE.BLOB])
STRING = DbApiType([FIELD_TYPE.ENUM,
FIELD_TYPE.JSON,
FIELD_TYPE.STRING,
FIELD_TYPE.VARCHAR,
FIELD_TYPE.VAR_STRING])
NUMBER = DbApiType([FIELD_TYPE.DECIMAL,
FIELD_TYPE.DOUBLE,
FIELD_TYPE.FLOAT,
FIELD_TYPE.INT24,
FIELD_TYPE.LONG,
FIELD_TYPE.LONGLONG,
FIELD_TYPE.NEWDECIMAL,
FIELD_TYPE.SHORT,
FIELD_TYPE.TINY,
FIELD_TYPE.YEAR])
DATE = DbApiType([FIELD_TYPE.DATE])
TIME = DbApiType([FIELD_TYPE.TIME])
DATETIME = TIMESTAMP = DbApiType([FIELD_TYPE.DATETIME,
FIELD_TYPE.TIMESTAMP])
ROWID = DbApiType()
'''
test attribute
'''

View File

@ -4,10 +4,14 @@ MariaDB indicator variables
Indicator values are used in executemany() method of cursor class to
indicate special values.
'''
class MrdbIndicator():
indicator= 0
import mariadb._mariadb as m
def __init__(self, indicator):
self.indicator = indicator
NULL = MrdbIndicator(1)
DEFAULT = MrdbIndicator(2)
IGNORE = MrdbIndicator(3)
IGNORE_ROW = MrdbIndicator(4)
NULL = m.indicator_null
DEFAULT = m.indicator_default
IGNORE = m.indicator_ignore
IGNORE_ROW = m.indicator_row

View File

@ -1 +1,9 @@
__all__ = ["CLIENT", "INDICATOR", "CURSOR", "FIELD_TYPE"]
class FOO():
def __init__(self, indicator):
self.indicator = indicator
FOO_NULL = FOO(1)
FOO_DEFAULT = FOO(2)
__all__ = ["CLIENT", "CURSOR", "FIELD_TYPE", "INDICATOR"]

View File

@ -28,7 +28,8 @@ extern int codecs_datetime_init(void);
PyObject *cnx_pool= NULL;
PyObject *decimal_module= NULL,
*decimal_type= NULL;
*decimal_type= NULL,
*indicator_module= NULL;
extern uint16_t max_pool_size;
int
@ -177,24 +178,12 @@ PyMODINIT_FUNC PyInit__mariadb(void)
goto error;
}
Py_TYPE(&MrdbIndicator_Type) = &PyType_Type;
if (PyType_Ready(&MrdbIndicator_Type) == -1)
{
goto error;
}
Py_TYPE(&Mariadb_Fieldinfo_Type) = &PyType_Type;
if (PyType_Ready(&Mariadb_Fieldinfo_Type) == -1)
{
goto error;
}
Py_TYPE(&Mariadb_DBAPIType_Type) = &PyType_Type;
if (PyType_Ready(&Mariadb_DBAPIType_Type) == -1)
{
goto error;
}
/* PEP-396: Module version numbers */
PyModule_AddObject(module, "__version__",
PyUnicode_FromString(PY_MARIADB_VERSION));
@ -269,26 +258,6 @@ PyMODINIT_FUNC PyInit__mariadb(void)
PyModule_AddObject(module, "ConnectionPool", (PyObject *)&MrdbPool_Type);
PyModule_AddObject(module, "_CONNECTION_POOLS", cnx_pool);
PyModule_AddObject(module, "indicator_null",
MrdbIndicator_Object(STMT_INDICATOR_NULL));
PyModule_AddObject(module, "indicator_default",
MrdbIndicator_Object(STMT_INDICATOR_DEFAULT));
PyModule_AddObject(module, "indicator_ignore",
MrdbIndicator_Object(STMT_INDICATOR_IGNORE));
PyModule_AddObject(module, "indicator_row",
MrdbIndicator_Object(STMT_INDICATOR_IGNORE_ROW));
PyModule_AddObject(module, "NUMBER",
Mariadb_DBAPIType_Object(DBAPI_NUMBER));
PyModule_AddObject(module, "BINARY",
Mariadb_DBAPIType_Object(DBAPI_BINARY));
PyModule_AddObject(module, "STRING",
Mariadb_DBAPIType_Object(DBAPI_STRING));
PyModule_AddObject(module, "DATETIME",
Mariadb_DBAPIType_Object(DBAPI_DATETIME));
PyModule_AddObject(module, "ROWID",
Mariadb_DBAPIType_Object(DBAPI_ROWID));
Py_INCREF(&Mariadb_Fieldinfo_Type);
PyModule_AddObject(module, "fieldinfo",
(PyObject *)&Mariadb_Fieldinfo_Type);

View File

@ -24,6 +24,11 @@
#define IS_DECIMAL_TYPE(type) \
((type) == MYSQL_TYPE_NEWDECIMAL || (type) == MYSQL_TYPE_DOUBLE || (type) == MYSQL_TYPE_FLOAT)
long MrdbIndicator_AsLong(PyObject *column)
{
PyObject *pyLong= PyObject_GetAttrString(column, "indicator");
return PyLong_AsLong(pyLong);
}
int codecs_datetime_init(void)
{
@ -982,7 +987,7 @@ mariadb_get_parameter(MrdbCursor *self,
mysql_get_server_info(self->stmt->mysql));
goto end;
}
param->indicator= (char)MrdbIndicator_AsLong(column);
param->indicator= (uint8_t)MrdbIndicator_AsLong(column);
param->value= NULL; /* you can't have both indicator and value */
} else if (column == Py_None) {
param->value= NULL;

View File

@ -722,6 +722,7 @@ MrdbConnection_rollback(MrdbConnection *self)
Py_RETURN_NONE;
}
/*
PyObject *
Mariadb_DBAPIType_Object(uint32_t type)
{
@ -730,7 +731,7 @@ Mariadb_DBAPIType_Object(uint32_t type)
types);
Py_DECREF(types);
return number;
}
} */
PyObject *
MrdbConnection_xid(MrdbConnection *self, PyObject *args)

View File

@ -1,217 +0,0 @@
/*****************************************************************************
Copyright (C) 2018-2020 Georg Richter and MariaDB Corporation AB
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not see <http://www.gnu.org/licenses>
or write to the Free Software Foundation, Inc.,
51 Franklin St., Fifth Floor, Boston, MA 02110, USA
*****************************************************************************/
#include <mariadb_python.h>
int32_t numeric_field_types[]= {
MYSQL_TYPE_DECIMAL, MYSQL_TYPE_TINY, MYSQL_TYPE_SHORT,
MYSQL_TYPE_LONG, MYSQL_TYPE_INT24, MYSQL_TYPE_FLOAT,
MYSQL_TYPE_DOUBLE, MYSQL_TYPE_LONGLONG, MYSQL_TYPE_YEAR,
MYSQL_TYPE_NEWDECIMAL,
-1 /* always last */
};
int32_t string_field_types[]= {
MYSQL_TYPE_VARCHAR, MYSQL_TYPE_JSON, MYSQL_TYPE_STRING,
MYSQL_TYPE_VAR_STRING, MYSQL_TYPE_ENUM,
-1 /* always last */
};
int32_t binary_field_types[]= {
MYSQL_TYPE_TINY_BLOB, MYSQL_TYPE_MEDIUM_BLOB,
MYSQL_TYPE_BLOB, MYSQL_TYPE_LONG_BLOB, MYSQL_TYPE_GEOMETRY,
-1 /* always last */
};
int32_t datetime_field_types[]= {
MYSQL_TYPE_TIMESTAMP, MYSQL_TYPE_DATE, MYSQL_TYPE_TIME,
MYSQL_TYPE_DATETIME,
-1 /* always last */
};
int32_t rowid_field_types[]= {-1};
static void
Mariadb_DBAPIType_dealloc(Mariadb_DBAPIType *self);
static PyMethodDef
Mariadb_DBAPIType_Methods[] =
{
{NULL} /* always last */
};
static struct PyMemberDef
Mariadb_DBAPIType_Members[] =
{
{NULL}
};
static void
Mariadb_DBAPIType_dealloc(Mariadb_DBAPIType *self)
{
Py_TYPE(self)->tp_free((PyObject*)self);
}
static PyObject *
Mariadb_DBAPIType_richcompare(Mariadb_DBAPIType *self,
PyObject *type,
int op)
{
PyObject *res= NULL;
if (Py_TYPE(type) != &PyLong_Type)
{
res= Py_NotImplemented;
}
else {
switch(op) {
case Py_EQ:
case Py_NE:
{
int32_t val, i= 0;
val= (uint32_t)PyLong_AsLong(type);
while (self->types[i] != -1) {
if (self->types[i] == val) {
res= (op == Py_EQ) ? Py_True : Py_False;
goto end;
}
i++;
}
res= (op == Py_EQ) ? Py_False : Py_True;
}
break;
default:
res= Py_NotImplemented;
break;
}
}
end:
Py_INCREF(res);
return res;
}
static
int Mariadb_DBAPIType_initialize(Mariadb_DBAPIType *self,
PyObject *args,
PyObject *kwargs);
PyTypeObject Mariadb_DBAPIType_Type =
{
PyVarObject_HEAD_INIT(NULL, 0)
"dbapitype",
sizeof(Mariadb_DBAPIType),
0,
(destructor)Mariadb_DBAPIType_dealloc, /* tp_dealloc */
0, /*tp_print*/
0, /* tp_getattr */
0, /* tp_setattr */
0, /*tp_compare*/
0, /* tp_repr */
/* Method suites for standard classes */
0, /* (PyNumberMethods *) tp_as_number */
0, /* (PySequenceMethods *) tp_as_sequence */
0, /* (PyMappingMethods *) tp_as_mapping */
/* More standard operations (here for binary compatibility) */
0, /* (hashfunc) tp_hash */
0, /* (ternaryfunc) tp_call */
0, /* (reprfunc) tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
/* Functions to access object as input/output buffer */
0, /* (PyBufferProcs *) tp_as_buffer */
/* (tp_flags) Flags to define presence of optional/expanded features */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE,
0, /* tp_doc Documentation string */
/* call function for all accessible objects */
(traverseproc)Mariadb_traverse,/* tp_traverse */
/* delete references to contained objects */
0, /* tp_clear */
/* rich comparisons */
(richcmpfunc)Mariadb_DBAPIType_richcompare,
/* weak reference enabler */
0, /* (long) tp_weaklistoffset */
/* Iterators */
0, /* (getiterfunc) tp_iter */
0, /* (iternextfunc) tp_iternext */
/* Attribute descriptor and subclassing stuff */
(struct PyMethodDef *)Mariadb_DBAPIType_Methods, /* tp_methods */
(struct PyMemberDef *)Mariadb_DBAPIType_Members, /* tp_members */
0, /* (struct getsetlist *) tp_getset; */
0, /* (struct _typeobject *) tp_base; */
0, /* (PyObject *) tp_dict */
0, /* (descrgetfunc) tp_descr_get */
0, /* (descrsetfunc) tp_descr_set */
0, /* (long) tp_dictoffset */
(initproc)Mariadb_DBAPIType_initialize, /* (initproc)p_init */
PyType_GenericAlloc, //NULL, /* tp_alloc */
PyType_GenericNew, //NULL, /* tp_new */
0, /* tp_free Low-level free-memory routine */
0, /* (PyObject *) tp_bases */
0, /* (PyObject *) tp_mro method resolution order */
0, /* (PyObject *) tp_defined */
};
static int
Mariadb_DBAPIType_initialize(Mariadb_DBAPIType *self,
PyObject *args,
PyObject *kwargs)
{
uint32_t group=0;
if (!PyArg_ParseTuple(args, "I", &group))
{
return -1;
}
switch(group) {
case DBAPI_NUMBER:
self->types= numeric_field_types;
return 0;
case DBAPI_STRING:
self->types= string_field_types;
return 0;
case DBAPI_BINARY:
self->types= binary_field_types;
return 0;
case DBAPI_DATETIME:
self->types= datetime_field_types;
return 0;
case DBAPI_ROWID:
self->types= rowid_field_types;
return 0;
default:
mariadb_throw_exception(NULL, Mariadb_InterfaceError, 0,
"Invalid DBAPI type");
return -1;
}
}

View File

@ -1,169 +0,0 @@
/******************************************************************************
Copyright (C) 2018-2020 Georg Richter and MariaDB Corporation AB
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not see <http://www.gnu.org/licenses>
or write to the Free Software Foundation, Inc.,
51 Franklin St., Fifth Floor, Boston, MA 02110, USA
*****************************************************************************/
#include <mariadb_python.h>
static void
MrdbIndicator_dealloc(MrdbIndicator *self);
/* todo: move documentation to include/docs */
static char MrdbIndicator_documentation[] =
"Returns a MariaDB indicator object";
static PyMethodDef
MrdbIndicator_Methods[] =
{
{NULL} /* always last */
};
static struct PyMemberDef
MrdbIndicator_Members[] =
{
{NULL} /* always last */
};
static void
MrdbIndicator_dealloc(MrdbIndicator *self)
{
Py_TYPE(self)->tp_free((PyObject*)self);
}
static int
MrdbIndicator_initialize(MrdbIndicator *self,
PyObject *args,
PyObject *kwargs)
{
int indicator;
PyObject *obj;
if (!PyArg_ParseTuple(args, "O!", &PyLong_Type, &obj))
{
return -1;
}
indicator= PyLong_AsLong(obj);
/* check if indicator is in range */
if (indicator < STMT_INDICATOR_NULL ||
indicator > STMT_INDICATOR_IGNORE_ROW)
{
mariadb_throw_exception(NULL, Mariadb_InterfaceError, 0,
"Invalid indicator value");
return -1;
}
self->indicator= indicator;
return 0;
}
static int
MrdbIndicator_traverse(MrdbIndicator *self,
visitproc visit,
void *arg)
{
return 0;
}
PyTypeObject
MrdbIndicator_Type =
{
PyVarObject_HEAD_INIT(NULL, 0)
"mariadb.indicator",
sizeof(MrdbIndicator),
0,
(destructor)MrdbIndicator_dealloc, /* tp_dealloc */
0, /*tp_print*/
0, /* tp_getattr */
0, /* tp_setattr */
0, /*tp_compare*/
0, /* tp_repr */
/* Method suites for standard classes */
0, /* (PyNumberMethods *) tp_as_number */
0, /* (PySequenceMethods *) tp_as_sequence */
0, /* (PyMappingMethods *) tp_as_mapping */
/* More standard operations (here for binary compatibility) */
0, /* (hashfunc) tp_hash */
0, /* (ternaryfunc) tp_call */
0, /* (reprfunc) tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
/* Functions to access object as input/output buffer */
0, /* (PyBufferProcs *) tp_as_buffer */
/* (tp_flags) Flags to define presence of optional/expanded features */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE,
MrdbIndicator_documentation, /* tp_doc Documentation string */
/* call function for all accessible objects */
(traverseproc)MrdbIndicator_traverse,/* tp_traverse */
/* delete references to contained objects */
0, /* tp_clear */
/* rich comparisons */
0, /* (richcmpfunc) tp_richcompare */
/* weak reference enabler */
0, /* (long) tp_weaklistoffset */
/* Iterators */
0, /* (getiterfunc) tp_iter */
0, /* (iternextfunc) tp_iternext */
/* Attribute descriptor and subclassing stuff */
(struct PyMethodDef *)MrdbIndicator_Methods, /* tp_methods */
(struct PyMemberDef *)MrdbIndicator_Members, /* tp_members */
0, /* (struct getsetlist *) tp_getset; */
0, /* (struct _typeobject *) tp_base; */
0, /* (PyObject *) tp_dict */
0, /* (descrgetfunc) tp_descr_get */
0, /* (descrsetfunc) tp_descr_set */
0, /* (long) tp_dictoffset */
(initproc)MrdbIndicator_initialize,/* tp_init */
PyType_GenericAlloc, //NULL, /* tp_alloc */
PyType_GenericNew, //NULL, /* tp_new */
NULL, /* tp_free Low-level free-memory routine */
0, /* (PyObject *) tp_bases */
0, /* (PyObject *) tp_mro method resolution order */
0, /* (PyObject *) tp_defined */
};
PyObject *
MrdbIndicator_Object(uint32_t type)
{
PyObject *types= Py_BuildValue("(I)", (uint32_t)type);
PyObject *number= PyObject_CallObject((PyObject *)&MrdbIndicator_Type,
types);
Py_DECREF(types);
return number;
}
long
MrdbIndicator_AsLong(PyObject *v)
{
if (!MrdbIndicator_Check(v))
{
return -1;
}
return (long)((MrdbIndicator *)v)->indicator;
}

View File

@ -80,8 +80,7 @@ setup(name='mariadb',
'mariadb/mariadb_exception.c', 'mariadb/mariadb_cursor.c',
'mariadb/mariadb_codecs.c', 'mariadb/mariadb_field.c',
'mariadb/mariadb_parser.c',
'mariadb/mariadb_pooling.c',
'mariadb/mariadb_dbapitype.c', 'mariadb/mariadb_indicator.c'],
'mariadb/mariadb_pooling.c'],
define_macros= define_macros,
include_dirs=cfg.includes,
library_dirs=cfg.lib_dirs,
@ -90,6 +89,6 @@ setup(name='mariadb',
extra_link_args = cfg.extra_link_args,
extra_objects= cfg.extra_objects
)],
py_modules=['mariadb.__init__', 'mariadb.constants.CLIENT', 'mariadb.constants.INDICATOR', 'mariadb.constants.CURSOR',
'mariadb.constants.FIELD_TYPE'],
py_modules=['mariadb.__init__', 'mariadb.constants.CLIENT', 'mariadb.constants.CURSOR',
'mariadb.constants.FIELD_TYPE', 'mariadb.constants.INDICATOR'],
)