mirror of
https://github.com/mariadb-corporation/mariadb-connector-python.git
synced 2025-08-11 02:43:15 +00:00
Make code more PEP-7 compliant
This commit is contained in:
76
include/docs/exception.h
Normal file
76
include/docs/exception.h
Normal file
@ -0,0 +1,76 @@
|
||||
/*****************************************************************************
|
||||
Copyright (C) 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
|
||||
******************************************************************************/
|
||||
|
||||
PyDoc_STRVAR(
|
||||
exception_interface__doc__,
|
||||
"Exception raised for errors that are related to the database interface "\
|
||||
"rather than the database itself"
|
||||
);
|
||||
|
||||
PyDoc_STRVAR(
|
||||
exception_warning__doc__,
|
||||
"Exception raised for important warnings like data truncations "\
|
||||
"while inserting, etc"
|
||||
);
|
||||
|
||||
PyDoc_STRVAR(
|
||||
exception_database__doc__,
|
||||
"Exception raised for errors that are related to the database"
|
||||
);
|
||||
|
||||
PyDoc_STRVAR(
|
||||
exception_data__doc__,
|
||||
"Exception raised for errors that are due to problems with the "\
|
||||
"processed data like division by zero, numeric value out of range, etc."
|
||||
);
|
||||
|
||||
PyDoc_STRVAR(
|
||||
exception_pool__doc__,
|
||||
"Exeception rasied for errors related to ConnectionPool class."
|
||||
);
|
||||
|
||||
PyDoc_STRVAR(
|
||||
exception_operational__doc__,
|
||||
"Exception raised for errors that are related to the database's "\
|
||||
"operation and not necessarily under the control of the programmer."
|
||||
);
|
||||
|
||||
PyDoc_STRVAR(
|
||||
exception_integrity__doc__,
|
||||
"Exception raised when the relational integrity of the database "\
|
||||
"is affected, e.g. a foreign key check fails"
|
||||
);
|
||||
|
||||
PyDoc_STRVAR(
|
||||
exception_internal__doc__,
|
||||
"Exception raised when the database encounters an internal error, "\
|
||||
"e.g. the cursor is not valid anymore";
|
||||
);
|
||||
|
||||
PyDoc_STRVAR(
|
||||
exception_programming__doc__,
|
||||
"Exception raised for programming errors, e.g. table not found or "\
|
||||
"already exists, syntax error in the SQL statement"
|
||||
);
|
||||
|
||||
PyDoc_STRVAR(
|
||||
exception_notsupported__doc__,
|
||||
"Exception raised in case a method or database API was used which is "\
|
||||
"not supported by the database"
|
||||
);
|
@ -1,5 +1,5 @@
|
||||
/************************************************************************************
|
||||
Copyright (C) 2018 Georg Richter and MariaDB Corporation AB
|
||||
/******************************************************************************
|
||||
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
|
||||
@ -15,7 +15,7 @@
|
||||
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
|
||||
*************************************************************************************/
|
||||
******************************************************************************/
|
||||
#define PY_SSIZE_T_CLEAN
|
||||
#include "Python.h"
|
||||
#include "bytesobject.h"
|
||||
@ -276,53 +276,103 @@ int Mariadb_traverse(PyObject *self,
|
||||
void *arg);
|
||||
|
||||
/* Function prototypes */
|
||||
void mariadb_throw_exception(void *handle,
|
||||
void
|
||||
mariadb_throw_exception(void *handle,
|
||||
PyObject *execption_type,
|
||||
unsigned char is_statement,
|
||||
const char *message,
|
||||
...);
|
||||
|
||||
PyObject *MrdbIndicator_Object(uint32_t type);
|
||||
long MrdbIndicator_AsLong(PyObject *v);
|
||||
PyObject *Mariadb_DBAPIType_Object(uint32_t type);
|
||||
PyObject *MrdbConnection_affected_rows(MrdbConnection *self);
|
||||
PyObject *MrdbConnection_ping(MrdbConnection *self);
|
||||
PyObject *MrdbConnection_kill(MrdbConnection *self, PyObject *args);
|
||||
PyObject *MrdbConnection_reconnect(MrdbConnection *self);
|
||||
PyObject *MrdbConnection_reset(MrdbConnection *self);
|
||||
PyObject *MrdbConnection_autocommit(MrdbConnection *self,
|
||||
PyObject *args);
|
||||
PyObject *MrdbConnection_change_user(MrdbConnection *self,
|
||||
PyObject *args);
|
||||
PyObject *MrdbConnection_rollback(MrdbConnection *self);
|
||||
PyObject *MrdbConnection_commit(MrdbConnection *self);
|
||||
PyObject *MrdbConnection_close(MrdbConnection *self);
|
||||
PyObject *MrdbConnection_connect( PyObject *self,PyObject *args, PyObject *kwargs);
|
||||
void MrdbConnection_SetAttributes(MrdbConnection *self);
|
||||
PyObject *
|
||||
MrdbIndicator_Object(uint32_t type);
|
||||
|
||||
long
|
||||
MrdbIndicator_AsLong(PyObject *v);
|
||||
|
||||
PyObject *
|
||||
Mariadb_DBAPIType_Object(uint32_t type);
|
||||
|
||||
PyObject *
|
||||
MrdbConnection_affected_rows(MrdbConnection *self);
|
||||
|
||||
PyObject *
|
||||
MrdbConnection_ping(MrdbConnection *self);
|
||||
|
||||
PyObject *
|
||||
MrdbConnection_kill(MrdbConnection *self, PyObject *args);
|
||||
|
||||
PyObject *
|
||||
MrdbConnection_reconnect(MrdbConnection *self);
|
||||
|
||||
PyObject *
|
||||
MrdbConnection_reset(MrdbConnection *self);
|
||||
|
||||
PyObject *
|
||||
MrdbConnection_autocommit(MrdbConnection *self, PyObject *args);
|
||||
|
||||
PyObject *
|
||||
MrdbConnection_change_user(MrdbConnection *self, PyObject *args);
|
||||
|
||||
PyObject
|
||||
*MrdbConnection_rollback(MrdbConnection *self);
|
||||
|
||||
PyObject *
|
||||
MrdbConnection_commit(MrdbConnection *self);
|
||||
|
||||
PyObject *
|
||||
MrdbConnection_close(MrdbConnection *self);
|
||||
|
||||
PyObject *
|
||||
MrdbConnection_connect( PyObject *self,PyObject *args, PyObject *kwargs);
|
||||
|
||||
void
|
||||
MrdbConnection_SetAttributes(MrdbConnection *self);
|
||||
|
||||
/* Pooling */
|
||||
PyObject *MrdbPool_add(PyObject *self, PyObject *args, PyObject *kwargs);
|
||||
PyObject *MrdbPool_getconnection(MrdbPool *self);
|
||||
PyObject *
|
||||
MrdbPool_add(PyObject *self, PyObject *args, PyObject *kwargs);
|
||||
|
||||
PyObject *
|
||||
MrdbPool_getconnection(MrdbPool *self);
|
||||
|
||||
/* TPC methods */
|
||||
PyObject *MrdbConnection_xid(MrdbConnection *self, PyObject *args);
|
||||
PyObject *MrdbConnection_tpc_begin(MrdbConnection *self, PyObject *args);
|
||||
PyObject *MrdbConnection_tpc_commit(MrdbConnection *self, PyObject *args);
|
||||
PyObject *MrdbConnection_tpc_rollback(MrdbConnection *self, PyObject *args);
|
||||
PyObject *MrdbConnection_tpc_prepare(MrdbConnection *self);
|
||||
PyObject *MrdbConnection_tpc_recover(MrdbConnection *self);
|
||||
PyObject *
|
||||
MrdbConnection_xid(MrdbConnection *self, PyObject *args);
|
||||
|
||||
PyObject *
|
||||
MrdbConnection_tpc_begin(MrdbConnection *self, PyObject *args);
|
||||
|
||||
PyObject *
|
||||
MrdbConnection_tpc_commit(MrdbConnection *self, PyObject *args);
|
||||
|
||||
PyObject *
|
||||
MrdbConnection_tpc_rollback(MrdbConnection *self, PyObject *args);
|
||||
|
||||
PyObject *
|
||||
MrdbConnection_tpc_prepare(MrdbConnection *self);
|
||||
|
||||
PyObject *
|
||||
MrdbConnection_tpc_recover(MrdbConnection *self);
|
||||
|
||||
/* codecs prototypes */
|
||||
uint8_t mariadb_check_bulk_parameters(MrdbCursor *self,
|
||||
PyObject *data);
|
||||
uint8_t mariadb_check_execute_parameters(MrdbCursor *self,
|
||||
PyObject *data);
|
||||
uint8_t mariadb_param_update(void *data, MYSQL_BIND *bind, uint32_t row_nr);
|
||||
uint8_t
|
||||
mariadb_check_bulk_parameters(MrdbCursor *self, PyObject *data);
|
||||
|
||||
uint8_t
|
||||
mariadb_check_execute_parameters(MrdbCursor *self, PyObject *data);
|
||||
|
||||
uint8_t
|
||||
mariadb_param_update(void *data, MYSQL_BIND *bind, uint32_t row_nr);
|
||||
|
||||
/* parser prototypes */
|
||||
MrdbParser *MrdbParser_init(const char *statement, size_t length);
|
||||
void MrdbParser_end(MrdbParser *p);
|
||||
uint8_t MrdbParser_parse(MrdbParser *p, uint8_t is_batch, char *errmsg, size_t errmsg_len);
|
||||
MrdbParser *
|
||||
MrdbParser_init(const char *statement, size_t length);
|
||||
|
||||
void
|
||||
MrdbParser_end(MrdbParser *p);
|
||||
|
||||
uint8_t
|
||||
MrdbParser_parse(MrdbParser *p, uint8_t is_batch, char *errmsg, size_t errmsg_len);
|
||||
|
||||
|
||||
/* Global defines */
|
||||
@ -335,7 +385,8 @@ uint8_t MrdbParser_parse(MrdbParser *p, uint8_t is_batch, char *errmsg, size_t e
|
||||
#define MAX_POOL_SIZE 64
|
||||
|
||||
#define TIMEDIFF(a,b)\
|
||||
((a).tv_sec * (uint64_t)1E09 + (a).tv_nsec) - ((b).tv_sec * (uint64_t)1E09 + (b).tv_nsec)
|
||||
((a).tv_sec * (uint64_t)1E09 + (a).tv_nsec) -\
|
||||
((b).tv_sec * (uint64_t)1E09 + (b).tv_nsec)
|
||||
|
||||
/* Helper macros */
|
||||
|
||||
@ -346,21 +397,24 @@ uint8_t MrdbParser_parse(MrdbParser *p, uint8_t is_batch, char *errmsg, size_t e
|
||||
(mysql_get_server_version((mysql)) >= (version))
|
||||
|
||||
#define MARIADB_CHECK_CONNECTION(connection, ret)\
|
||||
if (!(connection) || !(connection)->mysql) {\
|
||||
if (!(connection) || !(connection)->mysql)\
|
||||
{\
|
||||
mariadb_throw_exception((connection)->mysql, Mariadb_Error, 0,\
|
||||
"Invalid connection or not connected");\
|
||||
return (ret);\
|
||||
}
|
||||
|
||||
#define MARIADB_CHECK_TPC(connection)\
|
||||
if (connection->tpc_state == TPC_STATE_NONE) {\
|
||||
if (connection->tpc_state == TPC_STATE_NONE)\
|
||||
{\
|
||||
mariadb_throw_exception(connection->mysql, Mariadb_ProgrammingError, 0,\
|
||||
"Transaction not started");\
|
||||
return NULL;\
|
||||
}
|
||||
|
||||
#define MARIADB_FREE_MEM(a)\
|
||||
if (a) {\
|
||||
if (a)\
|
||||
{\
|
||||
PyMem_RawFree((a));\
|
||||
(a)= NULL;\
|
||||
}
|
||||
|
232
src/mariadb.c
232
src/mariadb.c
@ -1,5 +1,5 @@
|
||||
/************************************************************************************
|
||||
Copyright (C) 2018 Georg Richter and MariaDB Corporation AB
|
||||
/******************************************************************************
|
||||
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
|
||||
@ -15,11 +15,12 @@
|
||||
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
|
||||
*************************************************************************************/
|
||||
******************************************************************************/
|
||||
#define MARIADB_CONNECTION
|
||||
|
||||
#include "mariadb_python.h"
|
||||
#include "docs/module.h"
|
||||
#include "docs/exception.h"
|
||||
#include <structmember.h>
|
||||
#include <datetime.h>
|
||||
|
||||
@ -27,29 +28,37 @@ PyObject *Mrdb_Pickle= NULL;
|
||||
PyObject *cnx_pool= NULL;
|
||||
extern uint16_t max_pool_size;
|
||||
|
||||
int Mariadb_traverse(PyObject *self,
|
||||
int
|
||||
Mariadb_traverse(PyObject *self,
|
||||
visitproc visit,
|
||||
void *arg)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyObject *Mariadb_date_from_ticks(PyObject *self,
|
||||
PyObject *args);
|
||||
static PyObject *Mariadb_time_from_ticks(PyObject *self,
|
||||
PyObject *args);
|
||||
static PyObject *Mariadb_timestamp_from_ticks(PyObject *self,
|
||||
PyObject *args);
|
||||
static PyObject *Mariadb_date(PyObject *self,
|
||||
PyObject *args);
|
||||
static PyObject *Mariadb_time(PyObject *self,
|
||||
PyObject *args);
|
||||
static PyObject *Mariadb_timestamp(PyObject *self,
|
||||
PyObject *args);
|
||||
static PyObject *Mariadb_binary(PyObject *self,
|
||||
PyObject *args);
|
||||
static PyObject *
|
||||
Mariadb_date_from_ticks(PyObject *self, PyObject *args);
|
||||
|
||||
static PyMethodDef Mariadb_Methods[] =
|
||||
static PyObject *
|
||||
Mariadb_time_from_ticks(PyObject *self, PyObject *args);
|
||||
|
||||
static PyObject *
|
||||
Mariadb_timestamp_from_ticks(PyObject *self, PyObject *args);
|
||||
|
||||
static PyObject
|
||||
*Mariadb_date(PyObject *self, PyObject *args);
|
||||
|
||||
static PyObject *
|
||||
Mariadb_time(PyObject *self, PyObject *args);
|
||||
|
||||
static PyObject *
|
||||
Mariadb_timestamp(PyObject *self, PyObject *args);
|
||||
|
||||
static PyObject *
|
||||
Mariadb_binary(PyObject *self, PyObject *args);
|
||||
|
||||
static PyMethodDef
|
||||
Mariadb_Methods[] =
|
||||
{
|
||||
/* PEP-249: mandatory */
|
||||
{"Binary", (PyCFunction)Mariadb_binary,
|
||||
@ -86,7 +95,8 @@ static PyMethodDef Mariadb_Methods[] =
|
||||
};
|
||||
|
||||
/* MariaDB module definition */
|
||||
static struct PyModuleDef mariadb_module= {
|
||||
static struct PyModuleDef
|
||||
mariadb_module= {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"mariadb",
|
||||
"MariaDB Connector for Python",
|
||||
@ -109,28 +119,10 @@ struct st_constants {
|
||||
{NULL, {0}} /* Always last */
|
||||
};
|
||||
|
||||
static char exception_interface_doc[]= "Exception raised for errors that are related to the database interface "
|
||||
"rather than the database itself";
|
||||
static char exception_warning_doc[]= "Exception raised for important warnings like data truncations while inserting, etc";
|
||||
static char exception_database_doc[]= "Exception raised for errors that are related to the database";
|
||||
static char exception_data_doc[] = "Exception raised for errors that are due to problems with the processed data "
|
||||
"like division by zero, numeric value out of range, etc.";
|
||||
static char exception_pool_doc[] = "Exeception rasied for errors related to ConnectionPool class.";
|
||||
static char exception_operational_doc[] = "Exception raised for errors that are related to the database's operation "
|
||||
"and not necessarily under the control of the programmer.";
|
||||
static char exception_integrity_doc[]= "Exception raised when the relational integrity of the database is affected, "
|
||||
"e.g. a foreign key check fails";
|
||||
static char exception_internal_doc[]= "Exception raised when the database encounters an internal error, "
|
||||
"e.g. the cursor is not valid anymore";
|
||||
static char exception_programming_doc[]= "Exception raised for programming errors, e.g. table not found or already "
|
||||
"exists, syntax error in the SQL statement";
|
||||
static char exception_notsupported_doc[]= "Exception raised in case a method or database API was used which is not "
|
||||
"supported by the database";
|
||||
|
||||
static void mariadb_add_exception(PyObject *module,
|
||||
PyObject **exception,
|
||||
const char *exception_name,
|
||||
char *doc,
|
||||
const char *doc,
|
||||
const char *object_name)
|
||||
{
|
||||
*exception= PyErr_NewExceptionWithDoc(exception_name,
|
||||
@ -150,30 +142,42 @@ PyMODINIT_FUNC PyInit_mariadb(void)
|
||||
|
||||
Py_TYPE(&MrdbConnection_Type) = &PyType_Type;
|
||||
if (PyType_Ready(&MrdbConnection_Type) == -1)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* we need pickle for object serialization */
|
||||
Mrdb_Pickle= PyImport_ImportModule("pickle");
|
||||
|
||||
Py_TYPE(&MrdbCursor_Type) = &PyType_Type;
|
||||
if (PyType_Ready(&MrdbCursor_Type) == -1)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
Py_TYPE(&MrdbPool_Type) = &PyType_Type;
|
||||
if (PyType_Ready(&MrdbPool_Type) == -1)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
/* Mariadb module constants */
|
||||
while (intvals->name) {
|
||||
@ -183,11 +187,15 @@ PyMODINIT_FUNC PyInit_mariadb(void)
|
||||
}
|
||||
|
||||
/* PEP-249: mandatory module globals */
|
||||
PyModule_AddObject(module, "apilevel", PyUnicode_FromString(MARIADB_PY_APILEVEL));
|
||||
PyModule_AddObject(module, "paramstyle", PyUnicode_FromString(MARIADB_PY_PARAMSTYLE));
|
||||
PyModule_AddObject(module, "threadsafety", PyLong_FromLong(MARIADB_PY_THREADSAFETY));
|
||||
PyModule_AddObject(module, "apilevel",
|
||||
PyUnicode_FromString(MARIADB_PY_APILEVEL));
|
||||
PyModule_AddObject(module, "paramstyle",
|
||||
PyUnicode_FromString(MARIADB_PY_PARAMSTYLE));
|
||||
PyModule_AddObject(module, "threadsafety",
|
||||
PyLong_FromLong(MARIADB_PY_THREADSAFETY));
|
||||
/* optional (MariaDB specific) globals */
|
||||
PyModule_AddObject(module, "mariadbapi_version", PyUnicode_FromString(mysql_get_client_info()));
|
||||
PyModule_AddObject(module, "mariadbapi_version",
|
||||
PyUnicode_FromString(mysql_get_client_info()));
|
||||
|
||||
Mariadb_Error= PyErr_NewException("mariadb.Error",
|
||||
PyExc_Exception,
|
||||
@ -196,47 +204,66 @@ PyMODINIT_FUNC PyInit_mariadb(void)
|
||||
PyModule_AddObject(module, "Error", Mariadb_Error);
|
||||
|
||||
mariadb_add_exception(module, &Mariadb_InterfaceError,
|
||||
"mariadb.InterfaceError", exception_interface_doc, "InterfaceError");
|
||||
"mariadb.InterfaceError",
|
||||
exception_interface__doc__, "InterfaceError");
|
||||
mariadb_add_exception(module, &Mariadb_OperationalError,
|
||||
"mariadb.OperationalError", exception_operational_doc, "OperationalError");
|
||||
"mariadb.OperationalError",
|
||||
exception_operational__doc__, "OperationalError");
|
||||
mariadb_add_exception(module, &Mariadb_Warning,
|
||||
"mariadb.Warning", exception_warning_doc, "Warning");
|
||||
"mariadb.Warning", exception_warning__doc__, "Warning");
|
||||
mariadb_add_exception(module, &Mariadb_IntegrityError,
|
||||
"mariadb.IntegrityError", exception_integrity_doc, "IntegrityError");
|
||||
"mariadb.IntegrityError",
|
||||
exception_integrity__doc__, "IntegrityError");
|
||||
mariadb_add_exception(module, &Mariadb_InternalError,
|
||||
"mariadb.InternalError", exception_internal_doc, "InternalError");
|
||||
"mariadb.InternalError",
|
||||
exception_internal__doc__, "InternalError");
|
||||
mariadb_add_exception(module, &Mariadb_ProgrammingError,
|
||||
"mariadb.ProgrammingError", exception_programming_doc, "ProgrammingError");
|
||||
"mariadb.ProgrammingError",
|
||||
exception_programming__doc__, "ProgrammingError");
|
||||
mariadb_add_exception(module, &Mariadb_NotSupportedError,
|
||||
"mariadb.NotSupportedError", exception_notsupported_doc, "NotSupportedError");
|
||||
"mariadb.NotSupportedError",
|
||||
exception_notsupported__doc__, "NotSupportedError");
|
||||
mariadb_add_exception(module, &Mariadb_DatabaseError,
|
||||
"mariadb.DatabaseError", exception_database_doc, "DatabaseError");
|
||||
"mariadb.DatabaseError",
|
||||
exception_database__doc__, "DatabaseError");
|
||||
mariadb_add_exception(module, &Mariadb_DataError,
|
||||
"mariadb.DatabaseError.DataError", exception_data_doc, "DataError");
|
||||
"mariadb.DatabaseError.DataError",
|
||||
exception_data__doc__, "DataError");
|
||||
mariadb_add_exception(module, &Mariadb_PoolError,
|
||||
"mariadb.PoolError", exception_pool_doc, "PoolError");
|
||||
"mariadb.PoolError",
|
||||
exception_pool__doc__, "PoolError");
|
||||
|
||||
Py_INCREF(&MrdbConnection_Type);
|
||||
PyModule_AddObject(module, "connection", (PyObject *)&MrdbConnection_Type);
|
||||
|
||||
cnx_pool= PyDict_New();
|
||||
Py_INCREF(&MrdbPool_Type);
|
||||
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, "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));
|
||||
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);
|
||||
PyModule_AddObject(module, "fieldinfo",
|
||||
(PyObject *)&Mariadb_Fieldinfo_Type);
|
||||
|
||||
return module;
|
||||
error:
|
||||
@ -244,29 +271,37 @@ error:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static time_t get_ticks(PyObject *object)
|
||||
static time_t
|
||||
get_ticks(PyObject *object)
|
||||
{
|
||||
time_t ticks= 0;
|
||||
if (Py_TYPE(object) == &PyFloat_Type)
|
||||
{
|
||||
ticks= (time_t)PyFloat_AsDouble(object);
|
||||
}
|
||||
if (Py_TYPE(object) == &PyLong_Type)
|
||||
{
|
||||
ticks= (time_t)PyLong_AsLong(object);
|
||||
}
|
||||
return ticks;
|
||||
}
|
||||
|
||||
static PyObject *Mariadb_date_from_ticks(PyObject *module,
|
||||
PyObject *args)
|
||||
static PyObject *
|
||||
Mariadb_date_from_ticks(PyObject *module, PyObject *args)
|
||||
{
|
||||
PyObject *o, *Date;
|
||||
struct tm *ts;
|
||||
time_t epoch;
|
||||
|
||||
if (!PyDateTimeAPI)
|
||||
{
|
||||
PyDateTime_IMPORT;
|
||||
|
||||
}
|
||||
|
||||
if (!PyArg_ParseTuple(args, "O", &o))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
epoch= get_ticks(o);
|
||||
ts= localtime(&epoch);
|
||||
@ -275,19 +310,22 @@ static PyObject *Mariadb_date_from_ticks(PyObject *module,
|
||||
return Date;
|
||||
}
|
||||
|
||||
static PyObject *Mariadb_time_from_ticks(PyObject *module,
|
||||
PyObject *args)
|
||||
static PyObject *
|
||||
Mariadb_time_from_ticks(PyObject *module, PyObject *args)
|
||||
{
|
||||
struct tm *ts;
|
||||
time_t epoch;
|
||||
PyObject *o, *Time= NULL;
|
||||
|
||||
if (!PyDateTimeAPI)
|
||||
{
|
||||
PyDateTime_IMPORT;
|
||||
|
||||
}
|
||||
|
||||
if (!PyArg_ParseTuple(args, "O", &o))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
epoch= get_ticks(o);
|
||||
ts= localtime(&epoch);
|
||||
@ -296,81 +334,103 @@ static PyObject *Mariadb_time_from_ticks(PyObject *module,
|
||||
return Time;
|
||||
}
|
||||
|
||||
static PyObject *Mariadb_timestamp_from_ticks(PyObject *module,
|
||||
PyObject *args)
|
||||
static PyObject *
|
||||
Mariadb_timestamp_from_ticks(PyObject *module, PyObject *args)
|
||||
{
|
||||
PyObject *o,*Timestamp;
|
||||
struct tm *ts;
|
||||
time_t epoch;
|
||||
|
||||
if (!PyDateTimeAPI)
|
||||
{
|
||||
PyDateTime_IMPORT;
|
||||
}
|
||||
|
||||
if (!PyArg_ParseTuple(args, "O", &o))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
epoch= get_ticks(o);
|
||||
ts= localtime(&epoch);
|
||||
|
||||
Timestamp= PyDateTime_FromDateAndTime(ts->tm_year + 1900, ts->tm_mon + 1, ts->tm_mday, ts->tm_hour, ts->tm_min, ts->tm_sec, 0);
|
||||
Timestamp= PyDateTime_FromDateAndTime(ts->tm_year + 1900, ts->tm_mon + 1,
|
||||
ts->tm_mday, ts->tm_hour,
|
||||
ts->tm_min, ts->tm_sec, 0);
|
||||
return Timestamp;
|
||||
}
|
||||
|
||||
static PyObject *Mariadb_date(PyObject *self,
|
||||
PyObject *args)
|
||||
static PyObject *
|
||||
Mariadb_date(PyObject *self, PyObject *args)
|
||||
{
|
||||
PyObject *date= NULL;
|
||||
int32_t year=0, month=0, day= 0;
|
||||
|
||||
if (!PyDateTimeAPI)
|
||||
{
|
||||
PyDateTime_IMPORT;
|
||||
}
|
||||
|
||||
if (!PyArg_ParseTuple(args, "iii", &year, &month, &day))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
date= PyDate_FromDate(year, month, day);
|
||||
return date;
|
||||
}
|
||||
|
||||
static PyObject *Mariadb_timestamp(PyObject *self,
|
||||
PyObject *args)
|
||||
static PyObject *
|
||||
Mariadb_timestamp(PyObject *self, PyObject *args)
|
||||
{
|
||||
PyObject *timestamp= NULL;
|
||||
int32_t year=0, month=0, day= 0;
|
||||
int32_t hour=0, min=0, sec= 0;
|
||||
|
||||
if (!PyDateTimeAPI)
|
||||
{
|
||||
PyDateTime_IMPORT;
|
||||
if (!PyArg_ParseTuple(args, "iiiiii", &year, &month, &day, &hour, &min, &sec))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
timestamp= PyDateTime_FromDateAndTime(year, month, day, hour, min, sec, 0);
|
||||
if (!PyArg_ParseTuple(args, "iiiiii", &year, &month, &day,
|
||||
&hour, &min, &sec))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
timestamp= PyDateTime_FromDateAndTime(year, month, day,
|
||||
hour, min, sec, 0);
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
|
||||
static PyObject *Mariadb_time(PyObject *self,
|
||||
PyObject *args)
|
||||
static PyObject *
|
||||
Mariadb_time(PyObject *self, PyObject *args)
|
||||
{
|
||||
PyObject *time= NULL;
|
||||
int32_t hour=0, min=0, sec= 0;
|
||||
if (!PyDateTimeAPI)
|
||||
{
|
||||
PyDateTime_IMPORT;
|
||||
}
|
||||
|
||||
if (!PyArg_ParseTuple(args, "iii", &hour, &min, &sec))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
time= PyTime_FromTime(hour, min, sec, 0);
|
||||
return time;
|
||||
}
|
||||
|
||||
static PyObject *Mariadb_binary(PyObject *self,
|
||||
PyObject *args)
|
||||
static PyObject *
|
||||
Mariadb_binary(PyObject *self, PyObject *args)
|
||||
{
|
||||
PyObject *b,*o;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "O", &o))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
b= PyBytes_FromObject(o);
|
||||
return b;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/************************************************************************************
|
||||
Copyright (C) 2018 Georg Richter and MariaDB Corporation AB
|
||||
/*****************************************************************************
|
||||
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
|
||||
@ -15,19 +15,22 @@
|
||||
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"
|
||||
#include <datetime.h>
|
||||
|
||||
/* {{{ mariadb_pydate_to_tm
|
||||
/*
|
||||
converts a Python date/time/datetime object to MYSQL_TIME
|
||||
*/
|
||||
static void mariadb_pydate_to_tm(enum enum_field_types type,
|
||||
static void
|
||||
mariadb_pydate_to_tm(enum enum_field_types type,
|
||||
PyObject *obj,
|
||||
MYSQL_TIME *tm)
|
||||
{
|
||||
if (!PyDateTimeAPI)
|
||||
{
|
||||
PyDateTime_IMPORT;
|
||||
}
|
||||
memset(tm, 0, sizeof(MYSQL_TIME));
|
||||
if (type == MYSQL_TYPE_TIME ||
|
||||
type == MYSQL_TYPE_DATETIME)
|
||||
@ -59,10 +62,8 @@ static void mariadb_pydate_to_tm(enum enum_field_types type,
|
||||
tm->time_type= MYSQL_TIMESTAMP_DATETIME;
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ mariadb_get_pickled
|
||||
|
||||
/*
|
||||
Checks if the blob is a serialized (pickled) Python Object
|
||||
|
||||
conditions:
|
||||
@ -70,11 +71,16 @@ static void mariadb_pydate_to_tm(enum enum_field_types type,
|
||||
- Last Byte must be 0x2E
|
||||
- unpickle must return success
|
||||
*/
|
||||
static PyObject *mariadb_get_pickled(unsigned char *data, size_t length)
|
||||
static PyObject *
|
||||
mariadb_get_pickled(unsigned char *data, size_t length)
|
||||
{
|
||||
PyObject *obj= NULL;
|
||||
|
||||
if (length < 3)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (*data == 0x80 && *(data +1) <= 0x04 && *(data + length - 1) == 0x2E)
|
||||
{
|
||||
PyObject *byte= PyBytes_FromStringAndSize((char *)data, length);
|
||||
@ -86,15 +92,17 @@ static PyObject *mariadb_get_pickled(unsigned char *data, size_t length)
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
void field_fetch_fromtext(MrdbCursor *self, char *data, unsigned int column)
|
||||
void
|
||||
field_fetch_fromtext(MrdbCursor *self, char *data, unsigned int column)
|
||||
{
|
||||
MYSQL_TIME tm;
|
||||
unsigned long *length;
|
||||
|
||||
if (!PyDateTimeAPI)
|
||||
{
|
||||
PyDateTime_IMPORT;
|
||||
}
|
||||
|
||||
if (!data)
|
||||
{
|
||||
@ -128,8 +136,10 @@ void field_fetch_fromtext(MrdbCursor *self, char *data, unsigned int column)
|
||||
}
|
||||
case MYSQL_TYPE_TIME:
|
||||
memset(&tm, 0, sizeof(MYSQL_TIME));
|
||||
sscanf(data, "%d:%d:%d.%ld", &tm.hour, &tm.minute, &tm.second, &tm.second_part );
|
||||
self->values[column]= PyTime_FromTime((int)tm.hour, (int)tm.minute, (int)tm.second, (int)tm.second_part);
|
||||
sscanf(data, "%d:%d:%d.%ld", &tm.hour, &tm.minute,
|
||||
&tm.second, &tm.second_part );
|
||||
self->values[column]= PyTime_FromTime((int)tm.hour, (int)tm.minute,
|
||||
(int)tm.second, (int)tm.second_part);
|
||||
break;
|
||||
case MYSQL_TYPE_DATE:
|
||||
memset(&tm, 0, sizeof(MYSQL_TIME));
|
||||
@ -139,22 +149,35 @@ void field_fetch_fromtext(MrdbCursor *self, char *data, unsigned int column)
|
||||
case MYSQL_TYPE_DATETIME:
|
||||
case MYSQL_TYPE_TIMESTAMP:
|
||||
memset(&tm, 0, sizeof(MYSQL_TIME));
|
||||
sscanf(data, "%d-%d-%d %d:%d:%d.%ld", &tm.year, &tm.month, &tm.day, &tm.hour, &tm.minute, &tm.second, &tm.second_part);
|
||||
self->values[column]= PyDateTime_FromDateAndTime(tm.year, tm.month, tm.day, tm.hour, tm.minute, tm.second, tm.second_part);
|
||||
sscanf(data, "%d-%d-%d %d:%d:%d.%ld", &tm.year, &tm.month, &tm.day,
|
||||
&tm.hour, &tm.minute, &tm.second, &tm.second_part);
|
||||
self->values[column]= PyDateTime_FromDateAndTime(tm.year, tm.month,
|
||||
tm.day, tm.hour, tm.minute, tm.second, tm.second_part);
|
||||
break;
|
||||
case MYSQL_TYPE_TINY_BLOB:
|
||||
case MYSQL_TYPE_MEDIUM_BLOB:
|
||||
case MYSQL_TYPE_BLOB:
|
||||
case MYSQL_TYPE_LONG_BLOB:
|
||||
if (length[column] > self->fields[column].max_length)
|
||||
{
|
||||
self->fields[column].max_length= length[column];
|
||||
}
|
||||
if (self->fields[column].flags & BINARY_FLAG)
|
||||
{
|
||||
if (!(self->values[column]= mariadb_get_pickled((unsigned char *)data, (size_t)length[column])))
|
||||
self->values[column]= PyBytes_FromStringAndSize((const char *)data, (Py_ssize_t)length[column]);
|
||||
if (!(self->values[column]=
|
||||
mariadb_get_pickled((unsigned char *)data,
|
||||
(size_t)length[column])))
|
||||
{
|
||||
self->values[column]=
|
||||
PyBytes_FromStringAndSize((const char *)data,
|
||||
(Py_ssize_t)length[column]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
self->values[column]=
|
||||
PyUnicode_FromStringAndSize((const char *)data,
|
||||
(Py_ssize_t)length[column]);
|
||||
}
|
||||
else
|
||||
self->values[column]= PyUnicode_FromStringAndSize((const char *)data, (Py_ssize_t)length[column]);
|
||||
break;
|
||||
case MYSQL_TYPE_GEOMETRY:
|
||||
case MYSQL_TYPE_STRING:
|
||||
@ -168,10 +191,14 @@ void field_fetch_fromtext(MrdbCursor *self, char *data, unsigned int column)
|
||||
{
|
||||
unsigned long utf8len;
|
||||
|
||||
self->values[column]= PyUnicode_FromStringAndSize((const char *)data, (Py_ssize_t)length[column]);
|
||||
self->values[column]=
|
||||
PyUnicode_FromStringAndSize((const char *)data,
|
||||
(Py_ssize_t)length[column]);
|
||||
utf8len= (unsigned long)PyUnicode_GET_LENGTH(self->values[column]);
|
||||
if (utf8len > self->fields[column].max_length)
|
||||
{
|
||||
self->fields[column].max_length= utf8len;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -179,22 +206,25 @@ void field_fetch_fromtext(MrdbCursor *self, char *data, unsigned int column)
|
||||
}
|
||||
}
|
||||
|
||||
/* {{{ field_fetch_callback
|
||||
/* field_fetch_callback
|
||||
This function was previously registered with mysql_stmt_attr_set and
|
||||
STMT_ATTR_FIELD_FETCH_CALLBACK parameter. Instead of filling a bind buffer
|
||||
MariaDB Connector/C sends raw data in row for the specified column. In case
|
||||
of a NULL value row ptr will be NULL.
|
||||
STMT_ATTR_FIELD_FETCH_CALLBACK parameter. Instead of filling a bind
|
||||
buffer MariaDB Connector/C sends raw data in row for the specified column.
|
||||
In case of a NULL value row ptr will be NULL.
|
||||
|
||||
The cursor handle was also previously registered with mysql_stmt_attr_set
|
||||
and STMT_ATTR_USER_DATA parameter and will be passed in data variable.
|
||||
*/
|
||||
|
||||
void field_fetch_callback(void *data, unsigned int column, unsigned char **row)
|
||||
void
|
||||
field_fetch_callback(void *data, unsigned int column, unsigned char **row)
|
||||
{
|
||||
MrdbCursor *self= (MrdbCursor *)data;
|
||||
|
||||
if (!PyDateTimeAPI)
|
||||
{
|
||||
PyDateTime_IMPORT;
|
||||
}
|
||||
|
||||
if (!row)
|
||||
{
|
||||
@ -208,26 +238,30 @@ void field_fetch_callback(void *data, unsigned int column, unsigned char **row)
|
||||
self->values[column]= Py_None;
|
||||
break;
|
||||
case MYSQL_TYPE_TINY:
|
||||
self->values[column]= (self->fields[column].flags & UNSIGNED_FLAG) ?
|
||||
self->values[column]= (self->fields[column].flags &
|
||||
UNSIGNED_FLAG) ?
|
||||
PyLong_FromUnsignedLong((unsigned long)*row[0]) :
|
||||
PyLong_FromLong((long)*row[0]);
|
||||
*row+= 1;
|
||||
break;
|
||||
case MYSQL_TYPE_SHORT:
|
||||
case MYSQL_TYPE_YEAR:
|
||||
self->values[column]= (self->fields[column].flags & UNSIGNED_FLAG) ?
|
||||
self->values[column]=
|
||||
(self->fields[column].flags & UNSIGNED_FLAG) ?
|
||||
PyLong_FromUnsignedLong((unsigned long)uint2korr(*row)) :
|
||||
PyLong_FromLong((long)sint2korr(*row));
|
||||
*row+= 2;
|
||||
break;
|
||||
case MYSQL_TYPE_INT24:
|
||||
self->values[column]= (self->fields[column].flags & UNSIGNED_FLAG) ?
|
||||
self->values[column]=
|
||||
(self->fields[column].flags & UNSIGNED_FLAG) ?
|
||||
PyLong_FromUnsignedLong((unsigned long)uint3korr(*row)) :
|
||||
PyLong_FromLong((long)sint3korr(*row));
|
||||
*row+= 4;
|
||||
break;
|
||||
case MYSQL_TYPE_LONG:
|
||||
self->values[column]= (self->fields[column].flags & UNSIGNED_FLAG) ?
|
||||
self->values[column]=
|
||||
(self->fields[column].flags & UNSIGNED_FLAG) ?
|
||||
PyLong_FromUnsignedLong((unsigned long)uint4korr(*row)) :
|
||||
PyLong_FromLong((long)sint4korr(*row));
|
||||
*row+= 4;
|
||||
@ -235,7 +269,8 @@ void field_fetch_callback(void *data, unsigned int column, unsigned char **row)
|
||||
case MYSQL_TYPE_LONGLONG:
|
||||
{
|
||||
long long l= sint8korr(*row);
|
||||
self->values[column]= (self->fields[column].flags & UNSIGNED_FLAG) ?
|
||||
self->values[column]=
|
||||
(self->fields[column].flags & UNSIGNED_FLAG) ?
|
||||
PyLong_FromUnsignedLongLong((unsigned long long)l) :
|
||||
PyLong_FromLongLong(l);
|
||||
*row+= 8;
|
||||
@ -281,7 +316,8 @@ void field_fetch_callback(void *data, unsigned int column, unsigned char **row)
|
||||
}
|
||||
if (len == 11)
|
||||
second_part= uint4korr(*row + 7);
|
||||
self->values[column]= PyDateTime_FromDateAndTime(year, month, day, hour, minute, second, second_part);
|
||||
self->values[column]= PyDateTime_FromDateAndTime(year, month,
|
||||
day, hour, minute, second, second_part);
|
||||
*row+= len;
|
||||
break;
|
||||
}
|
||||
@ -330,7 +366,8 @@ void field_fetch_callback(void *data, unsigned int column, unsigned char **row)
|
||||
hour+= (day * 24);
|
||||
if (is_negative)
|
||||
hour*= -1;
|
||||
self->values[column]= PyTime_FromTime(hour, minute, second, second_part);
|
||||
self->values[column]= PyTime_FromTime(hour, minute,
|
||||
second, second_part);
|
||||
*row+= len;
|
||||
break;
|
||||
}
|
||||
@ -344,12 +381,17 @@ void field_fetch_callback(void *data, unsigned int column, unsigned char **row)
|
||||
self->fields[column].max_length= length;
|
||||
if (self->fields[column].flags & BINARY_FLAG)
|
||||
{
|
||||
if (!(self->values[column]= mariadb_get_pickled(*row, (size_t)length)))
|
||||
self->values[column]= PyBytes_FromStringAndSize((const char *)*row, (Py_ssize_t)length);
|
||||
if (!(self->values[column]=
|
||||
mariadb_get_pickled(*row, (size_t)length)))
|
||||
self->values[column]=
|
||||
PyBytes_FromStringAndSize((const char *)*row,
|
||||
(Py_ssize_t)length);
|
||||
}
|
||||
else {
|
||||
self->values[column]=
|
||||
PyUnicode_FromStringAndSize((const char *)*row,
|
||||
(Py_ssize_t)length);
|
||||
}
|
||||
else
|
||||
self->values[column]= PyUnicode_FromStringAndSize((const char *)*row, (Py_ssize_t)length);
|
||||
|
||||
*row+= length;
|
||||
break;
|
||||
}
|
||||
@ -367,8 +409,11 @@ void field_fetch_callback(void *data, unsigned int column, unsigned char **row)
|
||||
unsigned long utf8len;
|
||||
length= mysql_net_field_length(row);
|
||||
|
||||
self->values[column]= PyUnicode_FromStringAndSize((const char *)*row, (Py_ssize_t)length);
|
||||
utf8len= (unsigned long)PyUnicode_GET_LENGTH(self->values[column]);
|
||||
self->values[column]=
|
||||
PyUnicode_FromStringAndSize((const char *)*row,
|
||||
(Py_ssize_t)length);
|
||||
utf8len=
|
||||
(unsigned long)PyUnicode_GET_LENGTH(self->values[column]);
|
||||
if (utf8len > self->fields[column].max_length)
|
||||
self->fields[column].max_length= utf8len;
|
||||
*row+= length;
|
||||
@ -377,18 +422,20 @@ void field_fetch_callback(void *data, unsigned int column, unsigned char **row)
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ mariadb_get_column_info
|
||||
/*
|
||||
mariadb_get_column_info
|
||||
This function analyzes the Python object and calculates the corresponding
|
||||
MYSQL_TYPE, unsigned flag or NULL values and stores the information in
|
||||
MrdbParamInfo pointer.
|
||||
*/
|
||||
static uint8_t mariadb_get_column_info(PyObject *obj,
|
||||
MrdbParamInfo *paraminfo)
|
||||
static uint8_t
|
||||
mariadb_get_column_info(PyObject *obj, MrdbParamInfo *paraminfo)
|
||||
{
|
||||
if (!PyDateTimeAPI)
|
||||
{
|
||||
PyDateTime_IMPORT;
|
||||
}
|
||||
|
||||
if (obj == NULL)
|
||||
{
|
||||
@ -405,32 +452,25 @@ static uint8_t mariadb_get_column_info(PyObject *obj,
|
||||
paraminfo->is_negative= 1;
|
||||
paraminfo->type= MYSQL_TYPE_LONGLONG;
|
||||
return 0;
|
||||
} else if (Py_TYPE(obj) == &PyFloat_Type)
|
||||
{
|
||||
} else if (Py_TYPE(obj) == &PyFloat_Type) {
|
||||
paraminfo->type= MYSQL_TYPE_DOUBLE;
|
||||
return 0;
|
||||
} else if (Py_TYPE(obj) == &PyBytes_Type)
|
||||
{
|
||||
} else if (Py_TYPE(obj) == &PyBytes_Type) {
|
||||
paraminfo->type= MYSQL_TYPE_LONG_BLOB;
|
||||
return 0;
|
||||
} else if (PyDate_CheckExact(obj))
|
||||
{
|
||||
} else if (PyDate_CheckExact(obj)) {
|
||||
paraminfo->type= MYSQL_TYPE_DATE;
|
||||
return 0;
|
||||
} else if (PyTime_CheckExact(obj))
|
||||
{
|
||||
} else if (PyTime_CheckExact(obj)) {
|
||||
paraminfo->type= MYSQL_TYPE_TIME;
|
||||
return 0;
|
||||
} else if (PyDateTime_CheckExact(obj))
|
||||
{
|
||||
} else if (PyDateTime_CheckExact(obj)) {
|
||||
paraminfo->type= MYSQL_TYPE_DATETIME;
|
||||
return 0;
|
||||
} else if (Py_TYPE(obj) == &PyUnicode_Type)
|
||||
{
|
||||
} else if (Py_TYPE(obj) == &PyUnicode_Type) {
|
||||
paraminfo->type= MYSQL_TYPE_VAR_STRING;
|
||||
return 0;
|
||||
} else if (obj == Py_None)
|
||||
{
|
||||
} else if (obj == Py_None) {
|
||||
paraminfo->type= MYSQL_TYPE_NULL;
|
||||
return 0;
|
||||
}
|
||||
@ -443,9 +483,8 @@ static uint8_t mariadb_get_column_info(PyObject *obj,
|
||||
|
||||
return 1;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ mariadb_get_parameter
|
||||
/*
|
||||
|
||||
mariadb_get_parameter()
|
||||
@brief Returns a bulk parameter which was passed to
|
||||
@ -458,9 +497,9 @@ static uint8_t mariadb_get_column_info(PyObject *obj,
|
||||
@param paran[in][out] bulk parameter pointer
|
||||
|
||||
@return 0 on success, 1 on error
|
||||
|
||||
*/
|
||||
static uint8_t mariadb_get_parameter(MrdbCursor *self,
|
||||
static uint8_t
|
||||
mariadb_get_parameter(MrdbCursor *self,
|
||||
uint8_t is_bulk,
|
||||
uint32_t row_nr,
|
||||
uint32_t column_nr,
|
||||
@ -479,7 +518,8 @@ static uint8_t mariadb_get_parameter(MrdbCursor *self,
|
||||
column_nr < 0)
|
||||
{
|
||||
mariadb_throw_exception(self->stmt, Mariadb_DataError, 0,
|
||||
"Can't access data at row %d, column %d", row_nr + 1, column_nr + 1);
|
||||
"Can't access data at row %d, column %d",
|
||||
row_nr + 1, column_nr + 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -498,7 +538,8 @@ static uint8_t mariadb_get_parameter(MrdbCursor *self,
|
||||
if (!(column= PyTuple_GetItem(row, column_nr)))
|
||||
{
|
||||
mariadb_throw_exception(self->stmt, Mariadb_DataError, 0,
|
||||
"Can't access column number %d at row %d", column_nr + 1, row_nr + 1);
|
||||
"Can't access column number %d at row %d",
|
||||
column_nr + 1, row_nr + 1);
|
||||
return 1;
|
||||
}
|
||||
} else
|
||||
@ -507,7 +548,8 @@ static uint8_t mariadb_get_parameter(MrdbCursor *self,
|
||||
if (!PyDict_Contains(row, key))
|
||||
{
|
||||
mariadb_throw_exception(self->stmt, Mariadb_DataError, 0,
|
||||
"Can't find key '%s' in parameter data", self->parser->keys[column_nr]);
|
||||
"Can't find key '%s' in parameter data",
|
||||
self->parser->keys[column_nr]);
|
||||
return 1;
|
||||
}
|
||||
column= PyDict_GetItem(row, key);
|
||||
@ -519,28 +561,29 @@ static uint8_t mariadb_get_parameter(MrdbCursor *self,
|
||||
if (!MARIADB_FEATURE_SUPPORTED(self->stmt->mysql, 100206))
|
||||
{
|
||||
mariadb_throw_exception(NULL, Mariadb_DataError, 0,
|
||||
"MariaDB %s doesn't support indicator variables. Required version is 10.2.6 or newer", mysql_get_server_info(self->stmt->mysql));
|
||||
"MariaDB %s doesn't support indicator variables. "\
|
||||
"Required version is 10.2.6 or newer",
|
||||
mysql_get_server_info(self->stmt->mysql));
|
||||
return 1;
|
||||
}
|
||||
param->indicator= (char)MrdbIndicator_AsLong(column);
|
||||
param->value= NULL; /* you can't have both indicator and value */
|
||||
} else if (column == Py_None)
|
||||
{
|
||||
} else if (column == Py_None) {
|
||||
if (MARIADB_FEATURE_SUPPORTED(self->stmt->mysql, 100206))
|
||||
{
|
||||
param->indicator= STMT_INDICATOR_NULL;
|
||||
param->value= NULL;
|
||||
}
|
||||
} else
|
||||
{
|
||||
}
|
||||
else {
|
||||
param->value= column;
|
||||
param->indicator= STMT_INDICATOR_NONE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ mariadb_get_parameter_info
|
||||
/*
|
||||
mariadb_get_parameter_info
|
||||
mariadb_get_parameter_info fills the MYSQL_BIND structure
|
||||
with correct field_types for the Python objects.
|
||||
|
||||
@ -548,7 +591,8 @@ static uint8_t mariadb_get_parameter(MrdbCursor *self,
|
||||
the field type (e.g. by checking maxbit size for a PyLong).
|
||||
If the types in this column differ we will return an error.
|
||||
*/
|
||||
static uint8_t mariadb_get_parameter_info(MrdbCursor *self,
|
||||
static uint8_t
|
||||
mariadb_get_parameter_info(MrdbCursor *self,
|
||||
MYSQL_BIND *param,
|
||||
uint32_t column_nr)
|
||||
{
|
||||
@ -583,7 +627,8 @@ static uint8_t mariadb_get_parameter_info(MrdbCursor *self,
|
||||
if (mariadb_get_column_info(paramvalue.value, &pinfo))
|
||||
{
|
||||
mariadb_throw_exception(NULL, Mariadb_DataError, 1,
|
||||
"Invalid parameter type at row %d, column %d", i+1, column_nr + 1);
|
||||
"Invalid parameter type at row %d, column %d",
|
||||
i+1, column_nr + 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -593,13 +638,17 @@ static uint8_t mariadb_get_parameter_info(MrdbCursor *self,
|
||||
if (pinfo.type == MYSQL_TYPE_LONGLONG)
|
||||
{
|
||||
if (pinfo.bits > bits)
|
||||
{
|
||||
bits= (uint32_t)pinfo.bits;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!param->buffer_type ||
|
||||
param->buffer_type == MYSQL_TYPE_NULL)
|
||||
{
|
||||
param->buffer_type= pinfo.type;
|
||||
}
|
||||
else {
|
||||
/* except for NULL the parameter types must match */
|
||||
if (param->buffer_type != pinfo.type &&
|
||||
@ -611,7 +660,8 @@ static uint8_t mariadb_get_parameter_info(MrdbCursor *self,
|
||||
pinfo.type == MYSQL_TYPE_LONGLONG)
|
||||
break;
|
||||
mariadb_throw_exception(NULL, Mariadb_DataError, 1,
|
||||
"Invalid parameter type at row %d, column %d", i+1, column_nr + 1);
|
||||
"Invalid parameter type at row %d, column %d",
|
||||
i+1, column_nr + 1);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@ -621,25 +671,31 @@ static uint8_t mariadb_get_parameter_info(MrdbCursor *self,
|
||||
if (param->buffer_type == MYSQL_TYPE_LONGLONG)
|
||||
{
|
||||
if (bits <= 8)
|
||||
{
|
||||
param->buffer_type= MYSQL_TYPE_TINY;
|
||||
else if (bits <= 16)
|
||||
}
|
||||
else if (bits <= 16) {
|
||||
param->buffer_type= MYSQL_TYPE_SHORT;
|
||||
else if (bits <= 32)
|
||||
}
|
||||
else if (bits <= 32) {
|
||||
param->buffer_type= MYSQL_TYPE_LONG;
|
||||
else if (bits <= 64)
|
||||
}
|
||||
else if (bits <= 64) {
|
||||
param->buffer_type= MYSQL_TYPE_LONGLONG;
|
||||
else
|
||||
}
|
||||
else {
|
||||
param->buffer_type= MYSQL_TYPE_VAR_STRING;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ mariadb_check_bulk_parameters
|
||||
/* mariadb_check_bulk_parameters
|
||||
This function validates the specified bulk parameters and
|
||||
translates the field types to MYSQL_TYPE_*.
|
||||
*/
|
||||
uint8_t mariadb_check_bulk_parameters(MrdbCursor *self,
|
||||
uint8_t
|
||||
mariadb_check_bulk_parameters(MrdbCursor *self,
|
||||
PyObject *data)
|
||||
{
|
||||
uint32_t i;
|
||||
@ -658,14 +714,16 @@ uint8_t mariadb_check_bulk_parameters(MrdbCursor *self,
|
||||
Py_TYPE(obj) != &PyTuple_Type)
|
||||
{
|
||||
mariadb_throw_exception(NULL, Mariadb_DataError, 0,
|
||||
"Invalid parameter type in row %d. (Row data must be provided as tuple(s))", i+1);
|
||||
"Invalid parameter type in row %d. "\
|
||||
" (Row data must be provided as tuple(s))", i+1);
|
||||
return 1;
|
||||
}
|
||||
if (self->parser->paramstyle == PYFORMAT &&
|
||||
Py_TYPE(obj) != &PyDict_Type)
|
||||
{
|
||||
mariadb_throw_exception(NULL, Mariadb_DataError, 0,
|
||||
"Invalid parameter type in row %d. (Row data must be provided as dict)", i+1);
|
||||
"Invalid parameter type in row %d. "\
|
||||
" (Row data must be provided as dict)", i+1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -683,7 +741,8 @@ uint8_t mariadb_check_bulk_parameters(MrdbCursor *self,
|
||||
}
|
||||
|
||||
if (!self->is_prepared &&
|
||||
!(self->params= PyMem_RawCalloc(self->param_count, sizeof(MYSQL_BIND))))
|
||||
!(self->params= PyMem_RawCalloc(self->param_count,
|
||||
sizeof(MYSQL_BIND))))
|
||||
{
|
||||
mariadb_throw_exception(NULL, Mariadb_InterfaceError, 0,
|
||||
"Not enough memory (tried to allocated %lld bytes)",
|
||||
@ -691,7 +750,8 @@ uint8_t mariadb_check_bulk_parameters(MrdbCursor *self,
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!(self->value= PyMem_RawCalloc(self->param_count, sizeof(MrdbParamValue))))
|
||||
if (!(self->value= PyMem_RawCalloc(self->param_count,
|
||||
sizeof(MrdbParamValue))))
|
||||
{
|
||||
mariadb_throw_exception(NULL, Mariadb_InterfaceError, 0,
|
||||
"Not enough memory (tried to allocated %lld bytes)",
|
||||
@ -710,15 +770,16 @@ error:
|
||||
MARIADB_FREE_MEM(self->value);
|
||||
return 1;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ mariadb_check_execute_parameters */
|
||||
uint8_t mariadb_check_execute_parameters(MrdbCursor *self,
|
||||
uint8_t
|
||||
mariadb_check_execute_parameters(MrdbCursor *self,
|
||||
PyObject *data)
|
||||
{
|
||||
uint32_t i;
|
||||
if (!self->param_count)
|
||||
{
|
||||
self->param_count= self->parser->param_count;
|
||||
}
|
||||
|
||||
if (!self->param_count)
|
||||
{
|
||||
@ -747,18 +808,18 @@ uint8_t mariadb_check_execute_parameters(MrdbCursor *self,
|
||||
for (i=0; i < self->param_count; i++)
|
||||
{
|
||||
if (mariadb_get_parameter_info(self, &self->params[i], i))
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
error:
|
||||
MARIADB_FREE_MEM(self->paraminfo);
|
||||
MARIADB_FREE_MEM(self->value);
|
||||
return 1;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ mariadb_param_to_bind */
|
||||
/**
|
||||
/*
|
||||
mariadb_param_to_bind()
|
||||
|
||||
@brief Set the current value for the specified bind buffer
|
||||
@ -768,7 +829,8 @@ error:
|
||||
|
||||
@return 0 on succes, otherwise error
|
||||
*/
|
||||
static uint8_t mariadb_param_to_bind(MYSQL_BIND *bind,
|
||||
static uint8_t
|
||||
mariadb_param_to_bind(MYSQL_BIND *bind,
|
||||
MrdbParamValue *value)
|
||||
{
|
||||
if (value->indicator > 0)
|
||||
@ -784,27 +846,39 @@ static uint8_t mariadb_param_to_bind(MYSQL_BIND *bind,
|
||||
{
|
||||
case MYSQL_TYPE_TINY:
|
||||
if (bind->is_unsigned)
|
||||
{
|
||||
value->num[0]= (uint8_t)PyLong_AsUnsignedLong(value->value);
|
||||
else
|
||||
}
|
||||
else {
|
||||
value->num[0]= (int8_t)PyLong_AsLong(value->value);
|
||||
}
|
||||
break;
|
||||
case MYSQL_TYPE_SHORT:
|
||||
if (bind->is_unsigned)
|
||||
{
|
||||
*(uint16_t *)&value->num= (uint16_t)PyLong_AsUnsignedLong(value->value);
|
||||
else
|
||||
}
|
||||
else {
|
||||
*(int16_t *)&value->num= (int16_t)PyLong_AsLong(value->value);
|
||||
}
|
||||
break;
|
||||
case MYSQL_TYPE_LONG:
|
||||
if (bind->is_unsigned)
|
||||
{
|
||||
*(uint32_t *)&value->num= (uint32_t)PyLong_AsUnsignedLong(value->value);
|
||||
else
|
||||
}
|
||||
else {
|
||||
*(int32_t *)&value->num= (int32_t)PyLong_AsLong(value->value);
|
||||
}
|
||||
break;
|
||||
case MYSQL_TYPE_LONGLONG:
|
||||
if (bind->is_unsigned)
|
||||
{
|
||||
*(uint64_t *)value->num= (uint64_t)PyLong_AsUnsignedLongLong(value->value);
|
||||
else
|
||||
}
|
||||
else {
|
||||
*(int64_t *)value->num= (int64_t)PyLong_AsLongLong(value->value);
|
||||
}
|
||||
break;
|
||||
case MYSQL_TYPE_DOUBLE:
|
||||
*(double *)value->num= (double)PyFloat_AsDouble(value->value);
|
||||
@ -816,8 +890,7 @@ static uint8_t mariadb_param_to_bind(MYSQL_BIND *bind,
|
||||
dump= PyObject_CallMethod(Mrdb_Pickle, "dumps", "O", value->value);
|
||||
bind->buffer_length= (unsigned long)PyBytes_GET_SIZE(dump);
|
||||
bind->buffer= (void *) PyBytes_AS_STRING(dump);
|
||||
} else
|
||||
{
|
||||
} else {
|
||||
bind->buffer_length= (unsigned long)PyBytes_GET_SIZE(value->value);
|
||||
bind->buffer= (void *) PyBytes_AS_STRING(value->value);
|
||||
}
|
||||
@ -842,10 +915,8 @@ static uint8_t mariadb_param_to_bind(MYSQL_BIND *bind,
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ mariadb_param_update */
|
||||
/**
|
||||
/*
|
||||
mariadb_param_update()
|
||||
@brief Callback function which updates the bind structure's buffer and
|
||||
length with data from the specified row number. This callback function
|
||||
@ -859,18 +930,24 @@ static uint8_t mariadb_param_to_bind(MYSQL_BIND *bind,
|
||||
|
||||
@return 0 on success, otherwise error (=1)
|
||||
*/
|
||||
uint8_t mariadb_param_update(void *data, MYSQL_BIND *bind, uint32_t row_nr)
|
||||
uint8_t
|
||||
mariadb_param_update(void *data, MYSQL_BIND *bind, uint32_t row_nr)
|
||||
{
|
||||
MrdbCursor *self= (MrdbCursor *)data;
|
||||
uint32_t i;
|
||||
|
||||
if (!self)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (i=0; i < self->param_count; i++)
|
||||
{
|
||||
if (mariadb_get_parameter(self, (self->array_size > 0), row_nr, i, &self->value[i]))
|
||||
if (mariadb_get_parameter(self, (self->array_size > 0),
|
||||
row_nr, i, &self->value[i]))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if (self->value[i].indicator)
|
||||
{
|
||||
bind[i].u.indicator= &self->value[i].indicator;
|
||||
@ -922,4 +999,3 @@ int clock_gettime(int dummy, struct timespec *ct)
|
||||
}
|
||||
|
||||
#endif
|
||||
/* }}} */
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*****************************************************************************
|
||||
Copyright (C) 2018,2019 Georg Richter and MariaDB Corporation AB
|
||||
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
|
||||
@ -15,52 +15,77 @@
|
||||
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"
|
||||
#include "docs/connection.h"
|
||||
|
||||
void MrdbConnection_dealloc(MrdbConnection *self);
|
||||
void
|
||||
MrdbConnection_dealloc(MrdbConnection *self);
|
||||
|
||||
extern PyObject *cnx_pool;
|
||||
|
||||
static PyObject *MrdbConnection_cursor(MrdbConnection *self,
|
||||
PyObject *args,
|
||||
PyObject *kwargs);
|
||||
static PyObject
|
||||
*MrdbConnection_cursor(MrdbConnection *self, PyObject *args, PyObject *kwargs);
|
||||
|
||||
static PyObject
|
||||
*MrdbConnection_exception(PyObject *self, void *closure);
|
||||
|
||||
static PyObject *MrdbConnection_exception(PyObject *self, void *closure);
|
||||
#define GETTER_EXCEPTION(name, exception, doc)\
|
||||
{ name,MrdbConnection_exception, NULL, doc, &exception }
|
||||
|
||||
static PyObject *MrdbConnection_getid(MrdbConnection *self, void *closure);
|
||||
static PyObject *MrdbConnection_getuser(MrdbConnection *self, void *closure);
|
||||
static PyObject *MrdbConnection_getreconnect(MrdbConnection *self,
|
||||
void *closure);
|
||||
static int MrdbConnection_setreconnect(MrdbConnection *self,
|
||||
PyObject *args,
|
||||
void *closure);
|
||||
static PyObject *MrdbConnection_getdb(MrdbConnection *self, void *closure);
|
||||
static int MrdbConnection_setdb(MrdbConnection *self, PyObject *arg, void *closure);
|
||||
static PyObject *MrdbConnection_escape_string(MrdbConnection *self,
|
||||
PyObject *args);
|
||||
static PyObject *MrdbConnection_server_version(MrdbConnection *self);
|
||||
static PyObject *MrdbConnection_server_info(MrdbConnection *self);
|
||||
static PyObject *
|
||||
MrdbConnection_getid(MrdbConnection *self, void *closure);
|
||||
|
||||
static PyObject *MrdbConnection_warnings(MrdbConnection *self);
|
||||
static PyObject *MrdbConnection_getautocommit(MrdbConnection *self);
|
||||
static int MrdbConnection_setautocommit(MrdbConnection *self, PyObject *arg, void *closure);
|
||||
static PyObject *
|
||||
MrdbConnection_getuser(MrdbConnection *self, void *closure);
|
||||
|
||||
static PyGetSetDef MrdbConnection_sets[]=
|
||||
static PyObject *
|
||||
MrdbConnection_getreconnect(MrdbConnection *self, void *closure);
|
||||
|
||||
static int
|
||||
MrdbConnection_setreconnect(MrdbConnection *self, PyObject *args,
|
||||
void *closure);
|
||||
static PyObject *
|
||||
MrdbConnection_getdb(MrdbConnection *self, void *closure);
|
||||
|
||||
static int
|
||||
MrdbConnection_setdb(MrdbConnection *self, PyObject *arg, void *closure);
|
||||
|
||||
static PyObject *
|
||||
MrdbConnection_escape_string(MrdbConnection *self, PyObject *args);
|
||||
|
||||
static PyObject *
|
||||
MrdbConnection_server_version(MrdbConnection *self);
|
||||
|
||||
static PyObject *
|
||||
MrdbConnection_server_info(MrdbConnection *self);
|
||||
|
||||
static PyObject *
|
||||
MrdbConnection_warnings(MrdbConnection *self);
|
||||
|
||||
static PyObject *
|
||||
MrdbConnection_getautocommit(MrdbConnection *self);
|
||||
|
||||
static int
|
||||
MrdbConnection_setautocommit(MrdbConnection *self, PyObject *arg,
|
||||
void *closure);
|
||||
|
||||
static PyGetSetDef
|
||||
MrdbConnection_sets[]=
|
||||
{
|
||||
{"autocommit", (getter)MrdbConnection_getautocommit, (setter)MrdbConnection_setautocommit,
|
||||
{"autocommit", (getter)MrdbConnection_getautocommit,
|
||||
(setter)MrdbConnection_setautocommit,
|
||||
connection_autocommit__doc__, NULL},
|
||||
{"connection_id", (getter)MrdbConnection_getid, NULL,
|
||||
connection_connection_id__doc__, NULL},
|
||||
{"database", (getter)MrdbConnection_getdb, (setter)MrdbConnection_setdb,
|
||||
connection_database__doc__, NULL},
|
||||
{"auto_reconnect", (getter)MrdbConnection_getreconnect, (setter)MrdbConnection_setreconnect,
|
||||
{"auto_reconnect", (getter)MrdbConnection_getreconnect,
|
||||
(setter)MrdbConnection_setreconnect,
|
||||
connection_auto_reconnect__doc__, NULL},
|
||||
{"user", (getter)MrdbConnection_getuser, NULL, connection_user__doc__, NULL},
|
||||
{"user", (getter)MrdbConnection_getuser, NULL, connection_user__doc__,
|
||||
NULL},
|
||||
{"warnings", (getter)MrdbConnection_warnings, NULL,
|
||||
connection_warnings__doc__, NULL},
|
||||
{"server_version", (getter)MrdbConnection_server_version, NULL,
|
||||
@ -79,7 +104,8 @@ static PyGetSetDef MrdbConnection_sets[]=
|
||||
{NULL}
|
||||
};
|
||||
|
||||
static PyMethodDef MrdbConnection_Methods[] =
|
||||
static PyMethodDef
|
||||
MrdbConnection_Methods[] =
|
||||
{
|
||||
/* PEP-249 methods */
|
||||
{"close", (PyCFunction)MrdbConnection_close,
|
||||
@ -157,7 +183,8 @@ static PyMethodDef MrdbConnection_Methods[] =
|
||||
{NULL} /* alwa+ys last */
|
||||
};
|
||||
|
||||
static struct PyMemberDef MrdbConnection_Members[] =
|
||||
static struct
|
||||
PyMemberDef MrdbConnection_Members[] =
|
||||
{
|
||||
{"character_set",
|
||||
T_OBJECT,
|
||||
@ -202,12 +229,15 @@ static struct PyMemberDef MrdbConnection_Members[] =
|
||||
{NULL} /* always last */
|
||||
};
|
||||
|
||||
static void Mrdb_ConnAttrStr(MYSQL *mysql, PyObject **obj, enum mariadb_value attr)
|
||||
static void
|
||||
Mrdb_ConnAttrStr(MYSQL *mysql, PyObject **obj, enum mariadb_value attr)
|
||||
{
|
||||
char *val= NULL;
|
||||
|
||||
if (mariadb_get_infov(mysql, attr, &val) || !val)
|
||||
{
|
||||
return;
|
||||
}
|
||||
*obj= PyUnicode_FromString(val);
|
||||
}
|
||||
|
||||
@ -216,11 +246,15 @@ void MrdbConnection_SetAttributes(MrdbConnection *self)
|
||||
MY_CHARSET_INFO cinfo;
|
||||
|
||||
Mrdb_ConnAttrStr(self->mysql, &self->host, MARIADB_CONNECTION_HOST);
|
||||
Mrdb_ConnAttrStr(self->mysql, &self->tls_cipher, MARIADB_CONNECTION_SSL_CIPHER);
|
||||
Mrdb_ConnAttrStr(self->mysql, &self->tls_version, MARIADB_CONNECTION_TLS_VERSION);
|
||||
Mrdb_ConnAttrStr(self->mysql, &self->unix_socket, MARIADB_CONNECTION_UNIX_SOCKET);
|
||||
Mrdb_ConnAttrStr(self->mysql, &self->tls_cipher,
|
||||
MARIADB_CONNECTION_SSL_CIPHER);
|
||||
Mrdb_ConnAttrStr(self->mysql, &self->tls_version,
|
||||
MARIADB_CONNECTION_TLS_VERSION);
|
||||
Mrdb_ConnAttrStr(self->mysql, &self->unix_socket,
|
||||
MARIADB_CONNECTION_UNIX_SOCKET);
|
||||
mariadb_get_infov(self->mysql, MARIADB_CONNECTION_PORT, &self->port);
|
||||
mariadb_get_infov(self->mysql, MARIADB_CONNECTION_MARIADB_CHARSET_INFO, &cinfo);
|
||||
mariadb_get_infov(self->mysql, MARIADB_CONNECTION_MARIADB_CHARSET_INFO,
|
||||
&cinfo);
|
||||
self->charset= PyUnicode_FromString(cinfo.csname);
|
||||
self->collation= PyUnicode_FromString(cinfo.name);
|
||||
}
|
||||
@ -231,9 +265,6 @@ MrdbConnection_Initialize(MrdbConnection *self,
|
||||
PyObject *dsnargs)
|
||||
{
|
||||
int rc;
|
||||
/* Todo: we need to support all dsn parameters, the current
|
||||
implementation is just a small subset.
|
||||
*/
|
||||
char *dsn= NULL, *host=NULL, *user= NULL, *password= NULL, *schema= NULL,
|
||||
*socket= NULL, *init_command= NULL, *default_file= NULL,
|
||||
*default_group= NULL, *local_infile= NULL,
|
||||
@ -256,7 +287,8 @@ MrdbConnection_Initialize(MrdbConnection *self,
|
||||
"ssl_key", "ssl_ca", "ssl_cert", "ssl_crl",
|
||||
"ssl_cipher", "ssl_capath", "ssl_crlpath",
|
||||
"ssl_verify_cert", "ssl",
|
||||
"client_flags", "charset", "pool_name", "pool_size", "pool_reset_connection", "plugin_dir",
|
||||
"client_flags", "charset", "pool_name", "pool_size",
|
||||
"pool_reset_connection", "plugin_dir",
|
||||
NULL
|
||||
};
|
||||
|
||||
@ -271,8 +303,11 @@ MrdbConnection_Initialize(MrdbConnection *self,
|
||||
&ssl_key, &ssl_ca, &ssl_cert, &ssl_crl,
|
||||
&ssl_cipher, &ssl_capath, &ssl_crlpath,
|
||||
&ssl_verify_cert, &ssl_enforce,
|
||||
&client_flags, &charset, &pool_name, &pool_size, &reset_session, &plugin_dir))
|
||||
&client_flags, &charset, &pool_name, &pool_size,
|
||||
&reset_session, &plugin_dir))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (dsn)
|
||||
{
|
||||
@ -497,7 +532,9 @@ PyObject *MrdbConnection_close(MrdbConnection *self)
|
||||
int rc= 0;
|
||||
pthread_mutex_lock(&self->pool->lock);
|
||||
if (self->pool->reset_session)
|
||||
{
|
||||
rc= mysql_reset_connection(self->mysql);
|
||||
}
|
||||
if (!rc)
|
||||
{
|
||||
self->inuse= 0;
|
||||
@ -536,8 +573,8 @@ MrdbConnection_exception(PyObject *self, void *closure)
|
||||
return exception;
|
||||
}
|
||||
|
||||
/* {{{ MrdbConnection_commit */
|
||||
PyObject *MrdbConnection_commit(MrdbConnection *self)
|
||||
PyObject *
|
||||
MrdbConnection_commit(MrdbConnection *self)
|
||||
{
|
||||
int rc= 0;
|
||||
MARIADB_CHECK_CONNECTION(self, NULL);
|
||||
@ -557,10 +594,10 @@ PyObject *MrdbConnection_commit(MrdbConnection *self)
|
||||
return NULL;
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
} /* }}} */
|
||||
}
|
||||
|
||||
/* {{{ MrdbConnection_rollback */
|
||||
PyObject *MrdbConnection_rollback(MrdbConnection *self)
|
||||
PyObject *
|
||||
MrdbConnection_rollback(MrdbConnection *self)
|
||||
{
|
||||
int rc= 0;
|
||||
MARIADB_CHECK_CONNECTION(self, NULL);
|
||||
@ -583,10 +620,9 @@ PyObject *MrdbConnection_rollback(MrdbConnection *self)
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ DBAPIType Object */
|
||||
PyObject *Mariadb_DBAPIType_Object(uint32_t type)
|
||||
PyObject *
|
||||
Mariadb_DBAPIType_Object(uint32_t type)
|
||||
{
|
||||
PyObject *types= Py_BuildValue("(I)", (uint32_t)type);
|
||||
PyObject *number= PyObject_CallObject((PyObject *)&Mariadb_DBAPIType_Type,
|
||||
@ -594,10 +630,9 @@ PyObject *Mariadb_DBAPIType_Object(uint32_t type)
|
||||
Py_DECREF(types);
|
||||
return number;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/*{{{ Mariadb_xid */
|
||||
PyObject *MrdbConnection_xid(MrdbConnection *self, PyObject *args)
|
||||
PyObject *
|
||||
MrdbConnection_xid(MrdbConnection *self, PyObject *args)
|
||||
{
|
||||
PyObject *xid= NULL;
|
||||
char *format_id= NULL,
|
||||
@ -607,19 +642,22 @@ PyObject *MrdbConnection_xid(MrdbConnection *self, PyObject *args)
|
||||
if (!PyArg_ParseTuple(args, "ssi", &format_id,
|
||||
&transaction_id,
|
||||
&branch_qualifier))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(xid= Py_BuildValue("(ssi)", format_id,
|
||||
transaction_id,
|
||||
branch_qualifier)))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return xid;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ MrdbConnection_tpc_begin */
|
||||
PyObject *MrdbConnection_tpc_begin(MrdbConnection *self, PyObject *args)
|
||||
PyObject *
|
||||
MrdbConnection_tpc_begin(MrdbConnection *self, PyObject *args)
|
||||
{
|
||||
char *transaction_id= 0,
|
||||
*format_id=0;
|
||||
@ -630,7 +668,9 @@ PyObject *MrdbConnection_tpc_begin(MrdbConnection *self, PyObject *args)
|
||||
if (!PyArg_ParseTuple(args, "(ssi)", &format_id,
|
||||
&transaction_id,
|
||||
&branch_qualifier))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* MariaDB ignores format_id and branch_qualifier */
|
||||
snprintf(stmt, 127, "XA BEGIN '%s'", transaction_id);
|
||||
@ -648,10 +688,9 @@ PyObject *MrdbConnection_tpc_begin(MrdbConnection *self, PyObject *args)
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ MrdbConnection_tpc_commit */
|
||||
PyObject *MrdbConnection_tpc_commit(MrdbConnection *self, PyObject *args)
|
||||
PyObject *
|
||||
MrdbConnection_tpc_commit(MrdbConnection *self, PyObject *args)
|
||||
{
|
||||
char *transaction_id= 0,
|
||||
*format_id=0;
|
||||
@ -664,7 +703,9 @@ PyObject *MrdbConnection_tpc_commit(MrdbConnection *self, PyObject *args)
|
||||
if (!PyArg_ParseTuple(args, "|(ssi)", &format_id,
|
||||
&transaction_id,
|
||||
&branch_qualifier))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!args && self->tpc_state != TPC_STATE_PREPARE)
|
||||
{
|
||||
|
@ -1,5 +1,5 @@
|
||||
/************************************************************************************
|
||||
Copyright (C) 2018 Georg Richter and MariaDB Corporation AB
|
||||
/*****************************************************************************
|
||||
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
|
||||
@ -15,32 +15,60 @@
|
||||
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>
|
||||
#include <docs/cursor.h>
|
||||
|
||||
static void MrdbCursor_dealloc(MrdbCursor *self);
|
||||
static PyObject *MrdbCursor_close(MrdbCursor *self);
|
||||
static PyObject *MrdbCursor_execute(MrdbCursor *self,
|
||||
PyObject *args, PyObject *kwargs);
|
||||
static PyObject *MrdbCursor_nextset(MrdbCursor *self);
|
||||
static PyObject *MrdbCursor_executemany(MrdbCursor *self,
|
||||
PyObject *args);
|
||||
static PyObject *MrdbCursor_description(MrdbCursor *self);
|
||||
static PyObject *MrdbCursor_fetchall(MrdbCursor *self);
|
||||
static PyObject *MrdbCursor_fetchone(MrdbCursor *self);
|
||||
static PyObject *MrdbCursor_fetchmany(MrdbCursor *self,
|
||||
static void
|
||||
MrdbCursor_dealloc(MrdbCursor *self);
|
||||
|
||||
static PyObject *
|
||||
MrdbCursor_close(MrdbCursor *self);
|
||||
|
||||
static PyObject *
|
||||
MrdbCursor_execute(MrdbCursor *self,
|
||||
PyObject *args,
|
||||
PyObject *kwargs);
|
||||
static PyObject *MrdbCursor_scroll(MrdbCursor *self,
|
||||
|
||||
static PyObject *
|
||||
MrdbCursor_nextset(MrdbCursor *self);
|
||||
|
||||
static PyObject *
|
||||
MrdbCursor_executemany(MrdbCursor *self,
|
||||
PyObject *args);
|
||||
|
||||
static PyObject *
|
||||
MrdbCursor_description(MrdbCursor *self);
|
||||
|
||||
static PyObject *
|
||||
MrdbCursor_fetchall(MrdbCursor *self);
|
||||
|
||||
static PyObject *
|
||||
MrdbCursor_fetchone(MrdbCursor *self);
|
||||
|
||||
static PyObject
|
||||
*MrdbCursor_fetchmany(MrdbCursor *self,
|
||||
PyObject *args,
|
||||
PyObject *kwargs);
|
||||
static PyObject *MrdbCursor_callproc(MrdbCursor *self,
|
||||
|
||||
static PyObject *
|
||||
MrdbCursor_scroll(MrdbCursor *self,
|
||||
PyObject *args,
|
||||
PyObject *kwargs);
|
||||
|
||||
static PyObject *
|
||||
MrdbCursor_callproc(MrdbCursor *self,
|
||||
PyObject *args);
|
||||
static PyObject *MrdbCursor_fieldcount(MrdbCursor *self);
|
||||
void field_fetch_fromtext(MrdbCursor *self, char *data, unsigned int column);
|
||||
void field_fetch_callback(void *data, unsigned int column, unsigned char **row);
|
||||
|
||||
static PyObject *
|
||||
MrdbCursor_fieldcount(MrdbCursor *self);
|
||||
|
||||
void
|
||||
field_fetch_fromtext(MrdbCursor *self, char *data, unsigned int column);
|
||||
|
||||
void
|
||||
field_fetch_callback(void *data, unsigned int column, unsigned char **row);
|
||||
static PyObject *mariadb_get_sequence_or_tuple(MrdbCursor *self);
|
||||
static PyObject * MrdbCursor_iter(PyObject *self);
|
||||
static PyObject * MrdbCursor_iternext(PyObject *self);
|
||||
@ -73,9 +101,13 @@ strncpy((a)->statement, (s), (l));\
|
||||
|
||||
#define MARIADB_SET_SEQUENCE_OR_TUPLE_ITEM(self, row, column)\
|
||||
if ((self)->is_named_tuple)\
|
||||
PyStructSequence_SET_ITEM((row), (column), (self)->values[(column)]);\
|
||||
else\
|
||||
{\
|
||||
PyStructSequence_SET_ITEM((row), (column),\
|
||||
(self)->values[(column)]);\
|
||||
}\
|
||||
else {\
|
||||
PyTuple_SET_ITEM((row), (column), (self)->values[(column)]);\
|
||||
}
|
||||
|
||||
|
||||
static char *mariadb_named_tuple_name= "Row";
|
||||
@ -807,7 +839,9 @@ static int MrdbCursor_fetchinternal(MrdbCursor *self)
|
||||
}
|
||||
|
||||
if (!(row= mysql_fetch_row(self->result)))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (i= 0; i < field_count; i++)
|
||||
{
|
||||
@ -816,11 +850,8 @@ static int MrdbCursor_fetchinternal(MrdbCursor *self)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* {{{ MrdbCursor_fetchone
|
||||
PEP-249 fetchone() method
|
||||
*/
|
||||
static
|
||||
PyObject *MrdbCursor_fetchone(MrdbCursor *self)
|
||||
static PyObject *
|
||||
MrdbCursor_fetchone(MrdbCursor *self)
|
||||
{
|
||||
PyObject *row;
|
||||
uint32_t i;
|
||||
@ -828,7 +859,9 @@ PyObject *MrdbCursor_fetchone(MrdbCursor *self)
|
||||
|
||||
MARIADB_CHECK_STMT(self);
|
||||
if (PyErr_Occurred())
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!field_count)
|
||||
{
|
||||
@ -845,25 +878,20 @@ PyObject *MrdbCursor_fetchone(MrdbCursor *self)
|
||||
|
||||
self->row_number++;
|
||||
if (!(row= mariadb_get_sequence_or_tuple(self)))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i= 0; i < field_count; i++)
|
||||
{
|
||||
MARIADB_SET_SEQUENCE_OR_TUPLE_ITEM(self, row, i);
|
||||
}
|
||||
return row;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ MrdbCursor_scroll
|
||||
PEP-249: (optional) scroll() method
|
||||
|
||||
Parameter: value
|
||||
mode=[relative(default),absolute]
|
||||
|
||||
Todo: support for forward only cursor
|
||||
*/
|
||||
static
|
||||
PyObject *MrdbCursor_scroll(MrdbCursor *self, PyObject *args,
|
||||
static PyObject *
|
||||
MrdbCursor_scroll(MrdbCursor *self,
|
||||
PyObject *args,
|
||||
PyObject *kwargs)
|
||||
{
|
||||
char *modestr= NULL;
|
||||
@ -877,7 +905,9 @@ PyObject *MrdbCursor_scroll(MrdbCursor *self, PyObject *args,
|
||||
|
||||
MARIADB_CHECK_STMT(self);
|
||||
if (PyErr_Occurred())
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!CURSOR_FIELD_COUNT(self))
|
||||
{
|
||||
@ -896,7 +926,9 @@ PyObject *MrdbCursor_scroll(MrdbCursor *self, PyObject *args,
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs,
|
||||
"O!|s", kw_list, &PyLong_Type, &Pos, &modestr))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (modestr != NULL)
|
||||
{
|
||||
@ -905,8 +937,10 @@ PyObject *MrdbCursor_scroll(MrdbCursor *self, PyObject *args,
|
||||
break;
|
||||
mode++;
|
||||
};
|
||||
} else
|
||||
}
|
||||
else {
|
||||
mode= 0;
|
||||
}
|
||||
|
||||
if (!scroll_modes[mode]) {
|
||||
mariadb_throw_exception(NULL, Mariadb_DataError, 0,
|
||||
@ -921,7 +955,8 @@ PyObject *MrdbCursor_scroll(MrdbCursor *self, PyObject *args,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!mode) {
|
||||
if (!mode)
|
||||
{
|
||||
new_position= self->row_number + position;
|
||||
if (new_position < 0 || new_position > CURSOR_NUM_ROWS(self))
|
||||
{
|
||||
@ -929,26 +964,27 @@ PyObject *MrdbCursor_scroll(MrdbCursor *self, PyObject *args,
|
||||
"Position value is out of range");
|
||||
return NULL;
|
||||
}
|
||||
} else
|
||||
}
|
||||
else {
|
||||
new_position= position; /* absolute */
|
||||
}
|
||||
|
||||
if (!self->is_text)
|
||||
{
|
||||
mysql_stmt_data_seek(self->stmt, new_position);
|
||||
else
|
||||
}
|
||||
else {
|
||||
mysql_data_seek(self->result, new_position);
|
||||
}
|
||||
|
||||
self->row_number= (unsigned long)new_position;
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
/*}}}*/
|
||||
|
||||
/* {{{ MrdbCursor_fetchmany
|
||||
PEP-249 fetchmany() method
|
||||
|
||||
Optional parameters: size
|
||||
*/
|
||||
static
|
||||
PyObject *MrdbCursor_fetchmany(MrdbCursor *self, PyObject *args,
|
||||
PyObject *
|
||||
MrdbCursor_fetchmany(MrdbCursor *self,
|
||||
PyObject *args,
|
||||
PyObject *kwargs)
|
||||
{
|
||||
PyObject *List= NULL;
|
||||
@ -959,7 +995,9 @@ PyObject *MrdbCursor_fetchmany(MrdbCursor *self, PyObject *args,
|
||||
|
||||
MARIADB_CHECK_STMT(self);
|
||||
if (PyErr_Occurred())
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!field_count)
|
||||
{
|
||||
@ -970,54 +1008,72 @@ PyObject *MrdbCursor_fetchmany(MrdbCursor *self, PyObject *args,
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs,
|
||||
"|l:fetchmany", kw_list, &rows))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!rows)
|
||||
{
|
||||
rows= self->row_array_size;
|
||||
}
|
||||
|
||||
if (!(List= PyList_New(0)))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* if rows=0, return an empty list */
|
||||
if (!rows)
|
||||
{
|
||||
return List;
|
||||
}
|
||||
|
||||
for (i=0; i < rows; i++)
|
||||
{
|
||||
uint32_t j;
|
||||
PyObject *Row;
|
||||
if (MrdbCursor_fetchinternal(self))
|
||||
{
|
||||
goto end;
|
||||
}
|
||||
self->affected_rows= CURSOR_NUM_ROWS(self);
|
||||
if (!(Row= mariadb_get_sequence_or_tuple(self)))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
for (j=0; j < field_count; j++)
|
||||
{
|
||||
MARIADB_SET_SEQUENCE_OR_TUPLE_ITEM(self, Row, j);
|
||||
}
|
||||
PyList_Append(List, Row);
|
||||
}
|
||||
end:
|
||||
return List;
|
||||
}
|
||||
|
||||
static PyObject *mariadb_get_sequence_or_tuple(MrdbCursor *self)
|
||||
static PyObject *
|
||||
mariadb_get_sequence_or_tuple(MrdbCursor *self)
|
||||
{
|
||||
unsigned int field_count= CURSOR_FIELD_COUNT(self);
|
||||
if (self->is_named_tuple)
|
||||
{
|
||||
return PyStructSequence_New(self->sequence_type);
|
||||
else
|
||||
}
|
||||
else {
|
||||
return PyTuple_New(field_count);
|
||||
}
|
||||
/* }}} */
|
||||
}
|
||||
|
||||
/* {{{ MrdbCursor_fetchall()
|
||||
PEP-249 fetchall() method */
|
||||
static
|
||||
PyObject *MrdbCursor_fetchall(MrdbCursor *self)
|
||||
static PyObject *
|
||||
MrdbCursor_fetchall(MrdbCursor *self)
|
||||
{
|
||||
PyObject *List;
|
||||
unsigned int field_count= CURSOR_FIELD_COUNT(self);
|
||||
MARIADB_CHECK_STMT(self);
|
||||
if (PyErr_Occurred())
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!field_count)
|
||||
{
|
||||
@ -1027,7 +1083,9 @@ PyObject *MrdbCursor_fetchall(MrdbCursor *self)
|
||||
}
|
||||
|
||||
if (!(List= PyList_New(0)))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while (!MrdbCursor_fetchinternal(self))
|
||||
{
|
||||
@ -1037,7 +1095,9 @@ PyObject *MrdbCursor_fetchall(MrdbCursor *self)
|
||||
self->row_number++;
|
||||
|
||||
if (!(Row= mariadb_get_sequence_or_tuple(self)))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (j=0; j < field_count; j++)
|
||||
{
|
||||
@ -1049,31 +1109,36 @@ PyObject *MrdbCursor_fetchall(MrdbCursor *self)
|
||||
mysql_stmt_num_rows(self->stmt);
|
||||
return List;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ MrdbCursor_executemany_fallback
|
||||
/* MrdbCursor_executemany_fallback
|
||||
bulk execution for server < 10.2.6
|
||||
*/
|
||||
static
|
||||
uint8_t MrdbCursor_executemany_fallback(MrdbCursor *self,
|
||||
static uint8_t
|
||||
MrdbCursor_executemany_fallback(MrdbCursor *self,
|
||||
const char *statement,
|
||||
size_t len)
|
||||
{
|
||||
uint32_t i;
|
||||
int rc= 0;
|
||||
|
||||
if (mysql_stmt_attr_set(self->stmt, STMT_ATTR_PREBIND_PARAMS, &self->param_count))
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
self->row_count= 0;
|
||||
|
||||
for (i=0; i < self->array_size; i++)
|
||||
{
|
||||
int rc= 0;
|
||||
/* Load values */
|
||||
if (mariadb_param_update(self, self->params, i))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if (mysql_stmt_bind_param(self->stmt, self->params))
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
if (i==0)
|
||||
{
|
||||
@ -1081,10 +1146,14 @@ uint8_t MrdbCursor_executemany_fallback(MrdbCursor *self,
|
||||
(unsigned long)self->parser->statement.length);
|
||||
}
|
||||
if (!rc)
|
||||
{
|
||||
rc= mysql_stmt_execute(self->stmt);
|
||||
}
|
||||
Py_END_ALLOW_THREADS;
|
||||
if (rc)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
self->row_count++;
|
||||
}
|
||||
return 0;
|
||||
@ -1092,18 +1161,14 @@ error:
|
||||
mariadb_throw_exception(self->stmt, NULL, 1, NULL);
|
||||
return 1;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ MrdbCursor_executemany
|
||||
PEP-249 executemany() method
|
||||
|
||||
Paramter: A List of one or more tuples
|
||||
|
||||
/*
|
||||
Note: When conecting to a server < 10.2.6 this command will be emulated
|
||||
by executing preparing and executing statement n times (where n is
|
||||
the number of tuples in list)
|
||||
*/
|
||||
PyObject *MrdbCursor_executemany(MrdbCursor *self,
|
||||
static PyObject *
|
||||
MrdbCursor_executemany(MrdbCursor *self,
|
||||
PyObject *Args)
|
||||
{
|
||||
char *statement= NULL;
|
||||
@ -1111,16 +1176,20 @@ PyObject *MrdbCursor_executemany(MrdbCursor *self,
|
||||
int rc;
|
||||
uint8_t do_prepare= 1;
|
||||
char errmsg[128];
|
||||
|
||||
MARIADB_CHECK_STMT(self);
|
||||
|
||||
if (PyErr_Occurred())
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
self->data= NULL;
|
||||
|
||||
if (!PyArg_ParseTuple(Args, "s#O!", &statement, &statement_len,
|
||||
&PyList_Type, &self->data))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
if (!self->data)
|
||||
@ -1188,7 +1257,8 @@ PyObject *MrdbCursor_executemany(MrdbCursor *self,
|
||||
mariadb_throw_exception(self->stmt, NULL, 1, NULL);
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
rc= mysql_stmt_execute(self->stmt);
|
||||
Py_END_ALLOW_THREADS;
|
||||
@ -1208,17 +1278,17 @@ error:
|
||||
self->parser= NULL;
|
||||
return NULL;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ MrdbCursor_nextset
|
||||
PEP-249: Optional nextset() method
|
||||
*/
|
||||
PyObject *MrdbCursor_nextset(MrdbCursor *self)
|
||||
static PyObject *
|
||||
MrdbCursor_nextset(MrdbCursor *self)
|
||||
{
|
||||
MARIADB_CHECK_STMT(self);
|
||||
int rc;
|
||||
MARIADB_CHECK_STMT(self);
|
||||
|
||||
if (PyErr_Occurred())
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!CURSOR_FIELD_COUNT(self))
|
||||
{
|
||||
@ -1240,6 +1310,7 @@ PyObject *MrdbCursor_nextset(MrdbCursor *self)
|
||||
rc= mysql_next_result(self->connection->mysql);
|
||||
}
|
||||
Py_END_ALLOW_THREADS;
|
||||
|
||||
if (rc)
|
||||
{
|
||||
Py_INCREF(Py_None);
|
||||
@ -1248,45 +1319,47 @@ PyObject *MrdbCursor_nextset(MrdbCursor *self)
|
||||
if (CURSOR_FIELD_COUNT(self))
|
||||
{
|
||||
if (MrdbCursor_InitResultSet(self))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
}
|
||||
else {
|
||||
self->fields= 0;
|
||||
}
|
||||
Py_RETURN_TRUE;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ Mariadb_row_count
|
||||
PEP-249: rowcount attribute
|
||||
*/
|
||||
static PyObject *Mariadb_row_count(MrdbCursor *self)
|
||||
static PyObject *
|
||||
Mariadb_row_count(MrdbCursor *self)
|
||||
{
|
||||
int64_t row_count= 0;
|
||||
|
||||
MARIADB_CHECK_STMT(self);
|
||||
if (PyErr_Occurred())
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* PEP-249 requires to return -1 if the cursor was not executed before */
|
||||
if (!self->statement)
|
||||
{
|
||||
return PyLong_FromLongLong(-1);
|
||||
}
|
||||
|
||||
if (CURSOR_FIELD_COUNT(self))
|
||||
row_count= CURSOR_NUM_ROWS(self);
|
||||
else
|
||||
{
|
||||
row_count= CURSOR_NUM_ROWS(self);
|
||||
}
|
||||
else {
|
||||
row_count= self->row_count ? self->row_count : CURSOR_AFFECTED_ROWS(self);
|
||||
if (!row_count)
|
||||
row_count= -1;
|
||||
}
|
||||
return PyLong_FromLongLong(row_count);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ Mariadb_row_number
|
||||
PEP-249: rownumber attribute
|
||||
*/
|
||||
static PyObject *Mariadb_row_number(MrdbCursor *self)
|
||||
static PyObject *
|
||||
Mariadb_row_number(MrdbCursor *self)
|
||||
{
|
||||
unsigned int field_count= CURSOR_FIELD_COUNT(self);
|
||||
if (!field_count) {
|
||||
@ -1295,26 +1368,27 @@ static PyObject *Mariadb_row_number(MrdbCursor *self)
|
||||
}
|
||||
return PyLong_FromLongLong(self->row_number);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static PyObject *MrdbCursor_warnings(MrdbCursor *self)
|
||||
static PyObject *
|
||||
MrdbCursor_warnings(MrdbCursor *self)
|
||||
{
|
||||
MARIADB_CHECK_STMT(self);
|
||||
|
||||
return PyLong_FromLong((long)CURSOR_WARNING_COUNT(self));
|
||||
}
|
||||
|
||||
/* {{{ MrdbCursor_getbuffered */
|
||||
static PyObject *MrdbCursor_getbuffered(MrdbCursor *self)
|
||||
static PyObject *
|
||||
MrdbCursor_getbuffered(MrdbCursor *self)
|
||||
{
|
||||
if (self->is_buffered)
|
||||
{
|
||||
Py_RETURN_TRUE;
|
||||
}
|
||||
Py_RETURN_FALSE;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ MrdbCursor_setbuffered */
|
||||
static int MrdbCursor_setbuffered(MrdbCursor *self, PyObject *arg)
|
||||
static int
|
||||
MrdbCursor_setbuffered(MrdbCursor *self, PyObject *arg)
|
||||
{
|
||||
if (!arg || Py_TYPE(arg) != &PyBool_Type)
|
||||
{
|
||||
@ -1325,19 +1399,16 @@ static int MrdbCursor_setbuffered(MrdbCursor *self, PyObject *arg)
|
||||
self->is_buffered= PyObject_IsTrue(arg);
|
||||
return 0;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ MrdbCursor_lastrowid */
|
||||
static PyObject *MrdbCursor_lastrowid(MrdbCursor *self)
|
||||
static PyObject *
|
||||
MrdbCursor_lastrowid(MrdbCursor *self)
|
||||
{
|
||||
MARIADB_CHECK_STMT(self);
|
||||
return PyLong_FromUnsignedLongLong(CURSOR_INSERT_ID(self));
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* iterator protocol */
|
||||
|
||||
/* {{{ MrdbCursor_iter */
|
||||
static PyObject *
|
||||
MrdbCursor_iter(PyObject *self)
|
||||
{
|
||||
@ -1345,9 +1416,7 @@ MrdbCursor_iter(PyObject *self)
|
||||
Py_INCREF(self);
|
||||
return self;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ MrdbCursor_iternext */
|
||||
static PyObject *
|
||||
MrdbCursor_iternext(PyObject *self)
|
||||
{
|
||||
@ -1362,29 +1431,30 @@ MrdbCursor_iternext(PyObject *self)
|
||||
}
|
||||
return res;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ MrdbCursor_closed */
|
||||
static PyObject *MrdbCursor_closed(MrdbCursor *self)
|
||||
static PyObject
|
||||
*MrdbCursor_closed(MrdbCursor *self)
|
||||
{
|
||||
if (self->is_closed || !self->stmt || self->stmt->mysql == NULL)
|
||||
Py_RETURN_TRUE;
|
||||
Py_RETURN_FALSE;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ MrdbCursor_inoutparam */
|
||||
static PyObject *MrdbCursor_sp_outparams(MrdbCursor *self)
|
||||
static PyObject *
|
||||
MrdbCursor_sp_outparams(MrdbCursor *self)
|
||||
{
|
||||
if (!self->is_closed && self->stmt &&
|
||||
self->stmt->mysql &&
|
||||
(self->stmt->mysql->server_status & SERVER_PS_OUT_PARAMS))
|
||||
{
|
||||
Py_RETURN_TRUE;
|
||||
}
|
||||
|
||||
Py_RETURN_FALSE;
|
||||
}
|
||||
|
||||
static PyObject *MrdbCursor_callproc(MrdbCursor *self, PyObject *args)
|
||||
static PyObject *
|
||||
MrdbCursor_callproc(MrdbCursor *self, PyObject *args)
|
||||
{
|
||||
const char *sp;
|
||||
Py_ssize_t sp_len;
|
||||
@ -1411,7 +1481,9 @@ static PyObject *MrdbCursor_callproc(MrdbCursor *self, PyObject *args)
|
||||
for (i=0; i < param_count; i++)
|
||||
{
|
||||
if (i)
|
||||
{
|
||||
strcat(stmt, ",");
|
||||
}
|
||||
strcat(stmt, "?");
|
||||
}
|
||||
strcat(stmt, ")");
|
||||
@ -1424,7 +1496,9 @@ static PyObject *MrdbCursor_callproc(MrdbCursor *self, PyObject *args)
|
||||
Py_DECREF(new_args);
|
||||
end:
|
||||
if (stmt)
|
||||
{
|
||||
PyMem_RawFree(stmt);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/************************************************************************************
|
||||
Copyright (C) 2018 Georg Richter and MariaDB Corporation AB
|
||||
/*****************************************************************************
|
||||
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
|
||||
@ -15,7 +15,7 @@
|
||||
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>
|
||||
|
||||
@ -47,34 +47,39 @@ int32_t datetime_field_types[]= {
|
||||
|
||||
int32_t rowid_field_types[]= {-1};
|
||||
|
||||
static void
|
||||
Mariadb_DBAPIType_dealloc(Mariadb_DBAPIType *self);
|
||||
|
||||
static void Mariadb_DBAPIType_dealloc(Mariadb_DBAPIType *self);
|
||||
|
||||
static PyMethodDef Mariadb_DBAPIType_Methods[] =
|
||||
static PyMethodDef
|
||||
Mariadb_DBAPIType_Methods[] =
|
||||
{
|
||||
{NULL} /* always last */
|
||||
};
|
||||
|
||||
static struct PyMemberDef Mariadb_DBAPIType_Members[] =
|
||||
static struct PyMemberDef
|
||||
Mariadb_DBAPIType_Members[] =
|
||||
{
|
||||
{NULL}
|
||||
};
|
||||
|
||||
static void Mariadb_DBAPIType_dealloc(Mariadb_DBAPIType *self)
|
||||
static void
|
||||
Mariadb_DBAPIType_dealloc(Mariadb_DBAPIType *self)
|
||||
{
|
||||
Py_TYPE(self)->tp_free((PyObject*)self);
|
||||
}
|
||||
|
||||
static PyObject *Mariadb_DBAPIType_richcompare(Mariadb_DBAPIType *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
|
||||
{
|
||||
res= Py_NotImplemented;
|
||||
}
|
||||
else {
|
||||
switch(op) {
|
||||
case Py_EQ:
|
||||
case Py_NE:
|
||||
@ -175,7 +180,8 @@ PyTypeObject Mariadb_DBAPIType_Type =
|
||||
0, /* (PyObject *) tp_defined */
|
||||
};
|
||||
|
||||
static int Mariadb_DBAPIType_initialize(Mariadb_DBAPIType *self,
|
||||
static int
|
||||
Mariadb_DBAPIType_initialize(Mariadb_DBAPIType *self,
|
||||
PyObject *args,
|
||||
PyObject *kwargs)
|
||||
|
||||
@ -183,7 +189,9 @@ static int Mariadb_DBAPIType_initialize(Mariadb_DBAPIType *self,
|
||||
uint32_t group=0;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "I", &group))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch(group) {
|
||||
case DBAPI_NUMBER:
|
||||
@ -207,4 +215,3 @@ static int Mariadb_DBAPIType_initialize(Mariadb_DBAPIType *self,
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/************************************************************************************
|
||||
Copyright (C) 2018 Georg Richter and MariaDB Corporation AB
|
||||
/*****************************************************************************
|
||||
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
|
||||
@ -15,22 +15,25 @@
|
||||
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 Mariadb_Fieldinfo_dealloc(Mariadb_Fieldinfo *self);
|
||||
static void
|
||||
Mariadb_Fieldinfo_dealloc(Mariadb_Fieldinfo *self);
|
||||
|
||||
/* todo: write more documentation, this is just a placeholder */
|
||||
/* todo: move information into docs subdirectory */
|
||||
static char mariadb_fieldinfo_documentation[] =
|
||||
"Returns a MariaDB field information object";
|
||||
|
||||
static PyObject *Mariadb_Fieldinfo_gettype(Mariadb_Fieldinfo *self,
|
||||
PyObject *args);
|
||||
static PyObject *Mariadb_Fieldinfo_getflag(Mariadb_Fieldinfo *self,
|
||||
PyObject *args);
|
||||
static PyObject *
|
||||
Mariadb_Fieldinfo_gettype(Mariadb_Fieldinfo *self, PyObject *args);
|
||||
|
||||
static PyMethodDef Mariadb_Fieldinfo_Methods[] =
|
||||
static PyObject *
|
||||
Mariadb_Fieldinfo_getflag(Mariadb_Fieldinfo *self, PyObject *args);
|
||||
|
||||
static PyMethodDef
|
||||
Mariadb_Fieldinfo_Methods[] =
|
||||
{
|
||||
{"type", (PyCFunction)Mariadb_Fieldinfo_gettype,
|
||||
METH_VARARGS,
|
||||
@ -41,18 +44,20 @@ static PyMethodDef Mariadb_Fieldinfo_Methods[] =
|
||||
{NULL} /* always last */
|
||||
};
|
||||
|
||||
static struct PyMemberDef Mariadb_Fieldinfo_Members[] =
|
||||
static struct PyMemberDef
|
||||
Mariadb_Fieldinfo_Members[] =
|
||||
{
|
||||
{NULL}
|
||||
};
|
||||
|
||||
static void Mariadb_Fieldinfo_dealloc(Mariadb_Fieldinfo *self)
|
||||
static void
|
||||
Mariadb_Fieldinfo_dealloc(Mariadb_Fieldinfo *self)
|
||||
{
|
||||
Py_TYPE(self)->tp_free((PyObject*)self);
|
||||
}
|
||||
|
||||
static int Mariadb_Fieldinfo_traverse(
|
||||
Mariadb_Fieldinfo *self,
|
||||
static int
|
||||
Mariadb_Fieldinfo_traverse(Mariadb_Fieldinfo *self,
|
||||
visitproc visit,
|
||||
void *arg)
|
||||
{
|
||||
@ -171,7 +176,9 @@ static PyObject *Mariadb_Fieldinfo_gettype(Mariadb_Fieldinfo *self,
|
||||
PyObject *type= NULL;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "O!", &PyTuple_Type, &data))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (PyTuple_Size(data) != 8)
|
||||
{
|
||||
@ -224,8 +231,8 @@ struct st_flag {
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
static PyObject *Mariadb_Fieldinfo_getflag(Mariadb_Fieldinfo *self,
|
||||
PyObject *args)
|
||||
static PyObject *
|
||||
Mariadb_Fieldinfo_getflag(Mariadb_Fieldinfo *self, PyObject *args)
|
||||
{
|
||||
uint16_t i=0;
|
||||
unsigned long flag_val= 0;
|
||||
@ -234,7 +241,9 @@ static PyObject *Mariadb_Fieldinfo_getflag(Mariadb_Fieldinfo *self,
|
||||
char str_flag[512]= {0};
|
||||
|
||||
if (!PyArg_ParseTuple(args, "O!", &PyTuple_Type, &data))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (PyTuple_Size(data) != 8)
|
||||
{
|
||||
@ -254,14 +263,18 @@ static PyObject *Mariadb_Fieldinfo_getflag(Mariadb_Fieldinfo *self,
|
||||
flag_val= PyLong_AsUnsignedLong(flag);
|
||||
|
||||
if (!flag_val)
|
||||
{
|
||||
goto end;
|
||||
}
|
||||
|
||||
while(flag_name[i].name)
|
||||
{
|
||||
if (flag_val & flag_name[i].flag)
|
||||
{
|
||||
if (!str_flag[0])
|
||||
{
|
||||
strcat(str_flag, flag_name[i].name);
|
||||
}
|
||||
else {
|
||||
strcat(str_flag, " | ");
|
||||
strcat(str_flag, flag_name[i].name);
|
||||
@ -272,4 +285,3 @@ static PyObject *Mariadb_Fieldinfo_getflag(Mariadb_Fieldinfo *self,
|
||||
end:
|
||||
return PyUnicode_FromString(str_flag);
|
||||
}
|
||||
|
||||
|
@ -1,296 +0,0 @@
|
||||
/************************************************************************************
|
||||
Copyright (C) 2018 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_VARSTRING, 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 */
|
||||
};
|
||||
|
||||
uint32_t *rowid_field_types= {-1};
|
||||
|
||||
static void Mariadb_Fieldinfo_dealloc(Mariadb_Fieldinfo *self);
|
||||
|
||||
/* todo: write more documentation, this is just a placeholder */
|
||||
static char mariadb_fieldinfo_documentation[] =
|
||||
"Returns a MariaDB field information object";
|
||||
|
||||
static PyObject *Mariadb_Fieldinfo_gettype(Mariadb_Fieldinfo *self,
|
||||
PyObject *args);
|
||||
static PyObject *Mariadb_Fieldinfo_getflag(Mariadb_Fieldinfo *self,
|
||||
PyObject *args);
|
||||
|
||||
static PyMethodDef Mariadb_Fieldinfo_Methods[] =
|
||||
{
|
||||
{"type", (PyCFunction)Mariadb_Fieldinfo_gettype,
|
||||
METH_VARARGS,
|
||||
"Returns type information for the given field"},
|
||||
{"flag", (PyCFunction)Mariadb_Fieldinfo_getflag,
|
||||
METH_VARARGS,
|
||||
"Returns flag information for the given field"},
|
||||
{NULL} /* always last */
|
||||
};
|
||||
|
||||
static struct PyMemberDef Mariadb_Fieldinfo_Members[] =
|
||||
{
|
||||
{NULL}
|
||||
};
|
||||
|
||||
static void Mariadb_Fieldinfo_dealloc(Mariadb_Fieldinfo *self)
|
||||
{
|
||||
Py_TYPE(self)->tp_free((PyObject*)self);
|
||||
}
|
||||
|
||||
PyTypeObject Mariadb_Fieldinfo_Type =
|
||||
{
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
"fieldinfo",
|
||||
sizeof(Mariadb_Fieldinfo),
|
||||
0,
|
||||
(destructor)Mariadb_Fieldinfo_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,
|
||||
mariadb_fieldinfo_documentation, /* 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 */
|
||||
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 *)Mariadb_Fieldinfo_Methods, /* tp_methods */
|
||||
(struct PyMemberDef *)Mariadb_Fieldinfo_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 */
|
||||
0, /* (initproc)p_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 */
|
||||
};
|
||||
|
||||
|
||||
struct st_type_mapping {
|
||||
enum enum_field_types type;
|
||||
const char *name;
|
||||
} type_code[]= {
|
||||
{MYSQL_TYPE_DECIMAL, "DECIMAL"},
|
||||
{MYSQL_TYPE_TINY, "TINY"},
|
||||
{MYSQL_TYPE_SHORT, "SHORT"},
|
||||
{MYSQL_TYPE_LONG, "LONG"},
|
||||
{MYSQL_TYPE_FLOAT, "FLOAT"},
|
||||
{MYSQL_TYPE_DOUBLE, "DOUBLE"},
|
||||
{MYSQL_TYPE_NULL, "NULL"},
|
||||
{MYSQL_TYPE_TIMESTAMP, "TIMESTAMP"},
|
||||
{MYSQL_TYPE_LONGLONG, "LONGLONG"},
|
||||
{MYSQL_TYPE_INT24, "INT24"},
|
||||
{MYSQL_TYPE_DATE, "DATE"},
|
||||
{MYSQL_TYPE_TIME, "TIME"},
|
||||
{MYSQL_TYPE_DATETIME, "DATETIME"},
|
||||
{MYSQL_TYPE_YEAR, "YEAR"},
|
||||
{MYSQL_TYPE_NEWDATE, "NEWDATE"},
|
||||
{MYSQL_TYPE_VARCHAR, "VARCHAR"},
|
||||
{MYSQL_TYPE_BIT, "BIT"},
|
||||
{MYSQL_TYPE_JSON, "JSON"},
|
||||
{MYSQL_TYPE_NEWDECIMAL, "NEWDECIMAL"},
|
||||
{MYSQL_TYPE_ENUM, "ENUM"},
|
||||
{MYSQL_TYPE_SET, "SET"},
|
||||
{MYSQL_TYPE_TINY_BLOB, "BLOB"},
|
||||
{MYSQL_TYPE_MEDIUM_BLOB, "MEDIUM_BLOB"},
|
||||
{MYSQL_TYPE_LONG_BLOB, "LONG_BLOB"},
|
||||
{MYSQL_TYPE_BLOB, "BLOB"},
|
||||
{MYSQL_TYPE_VAR_STRING, "VAR_STRING"},
|
||||
{MYSQL_TYPE_STRING, "STRING"},
|
||||
{MYSQL_TYPE_GEOMETRY, "GEOMETRY"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
static PyObject *Mariadb_Fieldinfo_gettype(Mariadb_Fieldinfo *self,
|
||||
PyObject *args)
|
||||
{
|
||||
uint16_t i=0;
|
||||
enum enum_field_types field_type;
|
||||
PyObject *data= NULL;
|
||||
PyObject *type= NULL;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "O!", &PyTuple_Type, &data))
|
||||
return NULL;
|
||||
|
||||
if (PyTuple_Size(data) != 8)
|
||||
{
|
||||
mariadb_throw_exception(NULL, Mariadb_InterfaceError, 0,
|
||||
"Parameter isn't a (valid) description sequence");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
type= PyTuple_GetItem(data, 1);
|
||||
|
||||
if (Py_TYPE(type) != &PyLong_Type)
|
||||
{
|
||||
mariadb_throw_exception(NULL, Mariadb_InterfaceError, 0,
|
||||
"Parameter isn't a (valid) description sequence");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
field_type= PyLong_AsLong(type);
|
||||
|
||||
while(type_code[i].name)
|
||||
{
|
||||
if (type_code[i].type == field_type)
|
||||
{
|
||||
return PyUnicode_FromString(type_code[i].name);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return PyUnicode_FromString("UNKNOWN");
|
||||
}
|
||||
|
||||
struct st_flag {
|
||||
uint32_t flag;
|
||||
const char *name;
|
||||
} flag_name[]= {
|
||||
{NOT_NULL_FLAG, "NOT_NULL"},
|
||||
{PRI_KEY_FLAG, "PRIMARY_KEY"},
|
||||
{UNIQUE_KEY_FLAG, "UNIQUE_KEY"},
|
||||
{MULTIPLE_KEY_FLAG, "PART_KEY"},
|
||||
{BLOB_FLAG, "BLOB"},
|
||||
{UNSIGNED_FLAG, "UNSIGNED"},
|
||||
{ZEROFILL_FLAG, "ZEROFILL"},
|
||||
{BINARY_FLAG, "BINARY"},
|
||||
{ENUM_FLAG, "NUMERIC"},
|
||||
{AUTO_INCREMENT_FLAG, "AUTO_INCREMENT"},
|
||||
{TIMESTAMP_FLAG, "TIMESTAMP"},
|
||||
{SET_FLAG, "SET"},
|
||||
{NO_DEFAULT_VALUE_FLAG, "NO_DEFAULT"},
|
||||
{ON_UPDATE_NOW_FLAG, "UPDATE_TIMESTAMP"},
|
||||
{NUM_FLAG, "NUMERIC"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
static PyObject *Mariadb_Fieldinfo_getflag(Mariadb_Fieldinfo *self,
|
||||
PyObject *args)
|
||||
{
|
||||
uint16_t i=0;
|
||||
unsigned long flag_val= 0;
|
||||
PyObject *data= NULL;
|
||||
PyObject *flag= NULL;
|
||||
char str_flag[512]= {0};
|
||||
|
||||
if (!PyArg_ParseTuple(args, "O!", &PyTuple_Type, &data))
|
||||
return NULL;
|
||||
|
||||
if (PyTuple_Size(data) != 8)
|
||||
{
|
||||
mariadb_throw_exception(NULL, Mariadb_InterfaceError, 0,
|
||||
"Parameter isn't a (valid) description sequence");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
flag= PyTuple_GetItem(data, 7);
|
||||
|
||||
if (Py_TYPE(flag) != &PyLong_Type)
|
||||
{
|
||||
mariadb_throw_exception(NULL, Mariadb_InterfaceError, 0,
|
||||
"Parameter isn't a (valid) description sequence");
|
||||
return NULL;
|
||||
}
|
||||
flag_val= PyLong_AsUnsignedLong(flag);
|
||||
|
||||
if (!flag_val)
|
||||
goto end;
|
||||
|
||||
while(flag_name[i].name)
|
||||
{
|
||||
if (flag_val & flag_name[i].flag)
|
||||
{
|
||||
if (!str_flag[0])
|
||||
strcat(str_flag, flag_name[i].name);
|
||||
else {
|
||||
strcat(str_flag, " | ");
|
||||
strcat(str_flag, flag_name[i].name);
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
end:
|
||||
return PyUnicode_FromString(str_flag);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/************************************************************************************
|
||||
Copyright (C) 2018 Georg Richter and MariaDB Corporation AB
|
||||
/******************************************************************************
|
||||
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
|
||||
@ -15,32 +15,37 @@
|
||||
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);
|
||||
static void
|
||||
MrdbIndicator_dealloc(MrdbIndicator *self);
|
||||
|
||||
/* todo: write more documentation, this is just a placeholder */
|
||||
/* todo: move documentation to include/docs */
|
||||
static char MrdbIndicator_documentation[] =
|
||||
"Returns a MariaDB information object";
|
||||
"Returns a MariaDB indicator object";
|
||||
|
||||
static PyMethodDef MrdbIndicator_Methods[] =
|
||||
static PyMethodDef
|
||||
MrdbIndicator_Methods[] =
|
||||
{
|
||||
{NULL} /* always last */
|
||||
};
|
||||
|
||||
static struct PyMemberDef MrdbIndicator_Members[] =
|
||||
static struct PyMemberDef
|
||||
MrdbIndicator_Members[] =
|
||||
{
|
||||
{NULL} /* always last */
|
||||
};
|
||||
|
||||
static void MrdbIndicator_dealloc(MrdbIndicator *self)
|
||||
static void
|
||||
MrdbIndicator_dealloc(MrdbIndicator *self)
|
||||
{
|
||||
Py_TYPE(self)->tp_free((PyObject*)self);
|
||||
}
|
||||
|
||||
static int MrdbIndicator_initialize(MrdbIndicator *self,
|
||||
static int
|
||||
MrdbIndicator_initialize(MrdbIndicator *self,
|
||||
PyObject *args,
|
||||
PyObject *kwargs)
|
||||
{
|
||||
@ -48,7 +53,9 @@ static int MrdbIndicator_initialize(MrdbIndicator *self,
|
||||
PyObject *obj;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "O!", &PyLong_Type, &obj))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
indicator= PyLong_AsLong(obj);
|
||||
|
||||
@ -64,15 +71,16 @@ static int MrdbIndicator_initialize(MrdbIndicator *self,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int MrdbIndicator_traverse(
|
||||
MrdbIndicator *self,
|
||||
static int
|
||||
MrdbIndicator_traverse(MrdbIndicator *self,
|
||||
visitproc visit,
|
||||
void *arg)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyTypeObject MrdbIndicator_Type =
|
||||
PyTypeObject
|
||||
MrdbIndicator_Type =
|
||||
{
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
"mariadb.indicator",
|
||||
@ -140,8 +148,8 @@ PyTypeObject MrdbIndicator_Type =
|
||||
0, /* (PyObject *) tp_defined */
|
||||
};
|
||||
|
||||
/* {{{ MrdbIndicator_Object */
|
||||
PyObject *MrdbIndicator_Object(uint32_t type)
|
||||
PyObject *
|
||||
MrdbIndicator_Object(uint32_t type)
|
||||
{
|
||||
PyObject *types= Py_BuildValue("(I)", (uint32_t)type);
|
||||
PyObject *number= PyObject_CallObject((PyObject *)&MrdbIndicator_Type,
|
||||
@ -149,12 +157,13 @@ PyObject *MrdbIndicator_Object(uint32_t type)
|
||||
Py_DECREF(types);
|
||||
return number;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
long MrdbIndicator_AsLong(PyObject *v)
|
||||
long
|
||||
MrdbIndicator_AsLong(PyObject *v)
|
||||
{
|
||||
if (!MrdbIndicator_Check(v))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return (long)((MrdbIndicator *)v)->indicator;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/************************************************************************************
|
||||
Copyright (C) 2019 Georg Richter and MariaDB Corporation AB
|
||||
/*****************************************************************************
|
||||
Copyright (C) 2019,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
|
||||
@ -15,32 +15,46 @@
|
||||
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>
|
||||
|
||||
#define IS_WHITESPACE(a) (a==32 || a==9 || a==10 || a==13)
|
||||
#define IN_LITERAL(p) ((p)->in_literal[0] || (p)->in_literal[1] || (p)->in_literal[2])
|
||||
#define IN_LITERAL(p) ((p)->in_literal[0] ||\
|
||||
(p)->in_literal[1] ||\
|
||||
(p)->in_literal[2])
|
||||
|
||||
const char *comment_start= "/*";
|
||||
const char *comment_end= "*/";
|
||||
const char literals[3]= {'\'', '\"', '`'};
|
||||
|
||||
static uint8_t check_keyword(char* ofs, char* end, char* keyword, size_t keylen)
|
||||
static uint8_t
|
||||
check_keyword(char* ofs, char* end, char* keyword, size_t keylen)
|
||||
{
|
||||
int i;
|
||||
|
||||
if ((size_t)(end - ofs) < keylen + 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < (int)keylen; i++)
|
||||
{
|
||||
if (toupper(*(ofs + i)) != keyword[i])
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!IS_WHITESPACE(*(ofs + keylen)))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void MrdbParser_end(MrdbParser* p)
|
||||
void
|
||||
MrdbParser_end(MrdbParser* p)
|
||||
{
|
||||
if (p)
|
||||
{
|
||||
@ -48,7 +62,9 @@ void MrdbParser_end(MrdbParser* p)
|
||||
{
|
||||
uint32_t i;
|
||||
for (i=0; i < p->param_count; i++)
|
||||
{
|
||||
MARIADB_FREE_MEM(p->keys[i].str);
|
||||
}
|
||||
MARIADB_FREE_MEM(p->keys);
|
||||
}
|
||||
MARIADB_FREE_MEM(p->statement.str);
|
||||
@ -56,12 +72,15 @@ void MrdbParser_end(MrdbParser* p)
|
||||
}
|
||||
}
|
||||
|
||||
MrdbParser *MrdbParser_init(const char *statement, size_t length)
|
||||
MrdbParser *
|
||||
MrdbParser_init(const char *statement, size_t length)
|
||||
{
|
||||
MrdbParser *p;
|
||||
|
||||
if (!statement || !length)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((p= PyMem_RawCalloc(1, sizeof(MrdbParser))))
|
||||
{
|
||||
@ -76,7 +95,8 @@ MrdbParser *MrdbParser_init(const char *statement, size_t length)
|
||||
return p;
|
||||
}
|
||||
|
||||
static void parser_error(char *errmsg, size_t errmsg_len, const char *errstr)
|
||||
static void
|
||||
parser_error(char *errmsg, size_t errmsg_len, const char *errstr)
|
||||
{
|
||||
if (errmsg_len)
|
||||
{
|
||||
@ -84,7 +104,9 @@ static void parser_error(char *errmsg, size_t errmsg_len, const char *errstr)
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t MrdbParser_parse(MrdbParser *p, uint8_t is_batch, char *errmsg, size_t errmsg_len)
|
||||
uint8_t
|
||||
MrdbParser_parse(MrdbParser *p, uint8_t is_batch,
|
||||
char *errmsg, size_t errmsg_len)
|
||||
{
|
||||
char *a, *end;
|
||||
char lastchar= 0;
|
||||
@ -178,7 +200,8 @@ uint8_t MrdbParser_parse(MrdbParser *p, uint8_t is_batch, char *errmsg, size_t e
|
||||
{
|
||||
if (p->paramstyle && p->paramstyle != QMARK)
|
||||
{
|
||||
parser_error(errmsg, errmsg_len, "Mixing different parameter styles is not supported");
|
||||
parser_error(errmsg, errmsg_len,
|
||||
"Mixing different parameter styles is not supported");
|
||||
return 1;
|
||||
}
|
||||
p->paramstyle= QMARK;
|
||||
@ -194,7 +217,8 @@ uint8_t MrdbParser_parse(MrdbParser *p, uint8_t is_batch, char *errmsg, size_t e
|
||||
{
|
||||
if (p->paramstyle && p->paramstyle != FORMAT)
|
||||
{
|
||||
parser_error(errmsg, errmsg_len, "Mixing different parameter styles is not supported");
|
||||
parser_error(errmsg, errmsg_len,
|
||||
"Mixing different parameter styles is not supported");
|
||||
return 1;
|
||||
}
|
||||
p->paramstyle= FORMAT;
|
||||
@ -213,7 +237,8 @@ uint8_t MrdbParser_parse(MrdbParser *p, uint8_t is_batch, char *errmsg, size_t e
|
||||
ssize_t keylen= val_end - a + 1;
|
||||
if (p->paramstyle && p->paramstyle != PYFORMAT)
|
||||
{
|
||||
parser_error(errmsg, errmsg_len, "Mixing different parameter styles is not supported");
|
||||
parser_error(errmsg, errmsg_len,
|
||||
"Mixing different parameter styles is not supported");
|
||||
return 1;
|
||||
}
|
||||
p->paramstyle= PYFORMAT;
|
||||
@ -222,9 +247,11 @@ uint8_t MrdbParser_parse(MrdbParser *p, uint8_t is_batch, char *errmsg, size_t e
|
||||
if (p->keys)
|
||||
{
|
||||
MrdbString *m;
|
||||
if (!(m= PyMem_RawRealloc(p->keys, p->param_count * sizeof(MrdbString))))
|
||||
if (!(m= PyMem_RawRealloc(p->keys,
|
||||
p->param_count * sizeof(MrdbString))))
|
||||
{
|
||||
parser_error(errmsg, errmsg_len, "Not enough memory");
|
||||
parser_error(errmsg, errmsg_len,
|
||||
"Not enough memory");
|
||||
return 1;
|
||||
}
|
||||
p->keys= m;
|
||||
@ -232,16 +259,19 @@ uint8_t MrdbParser_parse(MrdbParser *p, uint8_t is_batch, char *errmsg, size_t e
|
||||
else {
|
||||
if (!(p->keys= PyMem_RawMalloc(sizeof(MrdbString))))
|
||||
{
|
||||
parser_error(errmsg, errmsg_len, "Not enough memory");
|
||||
parser_error(errmsg, errmsg_len,
|
||||
"Not enough memory");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (!(p->keys[p->param_count - 1].str= PyMem_RawCalloc(1, keylen - 2)))
|
||||
if (!(p->keys[p->param_count - 1].str=
|
||||
PyMem_RawCalloc(1, keylen - 2)))
|
||||
{
|
||||
parser_error(errmsg, errmsg_len, "Not enough memory");
|
||||
return 1;
|
||||
}
|
||||
memcpy(p->keys[p->param_count - 1].str, a + 2, keylen - 3);
|
||||
|
||||
p->keys[p->param_count - 1].length= keylen - 3;
|
||||
memmove(a+1, val_end+2, end - a - keylen);
|
||||
a+= 1;
|
||||
@ -256,7 +286,9 @@ uint8_t MrdbParser_parse(MrdbParser *p, uint8_t is_batch, char *errmsg, size_t e
|
||||
/* Do we have an insert statement ? */
|
||||
if (!p->is_insert && check_keyword(a, end, "INSERT", 6))
|
||||
{
|
||||
if (lastchar == 0 || (IS_WHITESPACE(lastchar)) || lastchar == '/')
|
||||
if (lastchar == 0 ||
|
||||
(IS_WHITESPACE(lastchar)) ||
|
||||
lastchar == '/')
|
||||
{
|
||||
p->is_insert = 1;
|
||||
a += 7;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/************************************************************************************
|
||||
/******************************************************************************
|
||||
Copyright (C) 2018 Georg Richter and MariaDB Corporation AB
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
@ -15,23 +15,37 @@
|
||||
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>
|
||||
#include <docs/pool.h>
|
||||
|
||||
static void MrdbPool_dealloc(MrdbPool *self);
|
||||
static PyObject *MrdbPool_addconnection(MrdbPool *self, PyObject *args);
|
||||
static PyObject *MrdbPool_setconfig(MrdbPool *self, PyObject *args, PyObject *kwargs);
|
||||
static PyObject *MrdbPool_poolsize(MrdbPool *self);
|
||||
static PyObject *MrdbPool_poolname(MrdbPool *self);
|
||||
static int MrdbPool_set_resetconnection(MrdbPool *self, PyObject *arg);
|
||||
static PyObject * MrdbPool_get_resetconnection(MrdbPool *self);
|
||||
static void
|
||||
MrdbPool_dealloc(MrdbPool *self);
|
||||
|
||||
static PyObject
|
||||
*MrdbPool_addconnection(MrdbPool *self, PyObject *args);
|
||||
|
||||
static PyObject *
|
||||
MrdbPool_setconfig(MrdbPool *self, PyObject *args, PyObject *kwargs);
|
||||
|
||||
static PyObject *
|
||||
MrdbPool_poolsize(MrdbPool *self);
|
||||
|
||||
static PyObject *
|
||||
MrdbPool_poolname(MrdbPool *self);
|
||||
|
||||
static int
|
||||
MrdbPool_set_resetconnection(MrdbPool *self, PyObject *arg);
|
||||
|
||||
static PyObject *
|
||||
MrdbPool_get_resetconnection(MrdbPool *self);
|
||||
|
||||
extern PyObject *cnx_pool;
|
||||
uint16_t max_pool_size= MAX_POOL_SIZE;
|
||||
|
||||
static PyGetSetDef MrdbPool_sets[]=
|
||||
static PyGetSetDef
|
||||
MrdbPool_sets[]=
|
||||
{
|
||||
{"pool_name", (getter)MrdbPool_poolname, NULL,
|
||||
pool_pool_name__doc__},
|
||||
@ -43,7 +57,8 @@ static PyGetSetDef MrdbPool_sets[]=
|
||||
{NULL}
|
||||
};
|
||||
|
||||
static PyMethodDef MrdbPool_Methods[] =
|
||||
static PyMethodDef
|
||||
MrdbPool_Methods[] =
|
||||
{
|
||||
|
||||
{"add_connection", (PyCFunction)MrdbPool_addconnection,
|
||||
@ -58,7 +73,8 @@ static PyMethodDef MrdbPool_Methods[] =
|
||||
{NULL} /* always last */
|
||||
};
|
||||
|
||||
static struct PyMemberDef MrdbPool_Members[] =
|
||||
static struct PyMemberDef
|
||||
MrdbPool_Members[] =
|
||||
{
|
||||
{"max_size",
|
||||
T_SHORT,
|
||||
@ -68,8 +84,7 @@ static struct PyMemberDef MrdbPool_Members[] =
|
||||
{NULL}
|
||||
};
|
||||
|
||||
/* {{{ MrdbPool_initialize
|
||||
Pool initialization
|
||||
/* Pool initialization
|
||||
|
||||
Keywords:
|
||||
pool_name name of the pool
|
||||
@ -78,8 +93,8 @@ static struct PyMemberDef MrdbPool_Members[] =
|
||||
idle_timeout
|
||||
acquire_timeout
|
||||
*/
|
||||
static int MrdbPool_initialize(MrdbPool *self, PyObject *args,
|
||||
PyObject *kwargs)
|
||||
static int
|
||||
MrdbPool_initialize(MrdbPool *self, PyObject *args, PyObject *kwargs)
|
||||
{
|
||||
char *key_words[]= {"pool_name", "pool_size", "pool_reset_connection", NULL};
|
||||
PyObject *pool_kwargs= NULL;
|
||||
@ -96,7 +111,9 @@ static int MrdbPool_initialize(MrdbPool *self, PyObject *args,
|
||||
Py_ssize_t pos = 0;
|
||||
|
||||
if (!self)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* check if pool already exists */
|
||||
if ((pn= PyDict_GetItemString(kwargs, "pool_name")))
|
||||
@ -115,19 +132,26 @@ static int MrdbPool_initialize(MrdbPool *self, PyObject *args,
|
||||
if (!strncmp(utf8key, "pool", 4))
|
||||
{
|
||||
if (!pool_kwargs)
|
||||
{
|
||||
pool_kwargs= PyDict_New();
|
||||
}
|
||||
PyDict_SetItemString(pool_kwargs, utf8key, value);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if (!conn_kwargs)
|
||||
{
|
||||
conn_kwargs= PyDict_New();
|
||||
}
|
||||
PyDict_SetItemString(conn_kwargs, utf8key, value);
|
||||
}
|
||||
}
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, pool_kwargs,
|
||||
"|s#ib:ConnectionPool", key_words, &pool_name, &pool_name_length,
|
||||
&pool_size, &reset_session))
|
||||
"|s#ib:ConnectionPool", key_words, &pool_name,
|
||||
&pool_name_length, &pool_size, &reset_session))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pool_size > max_pool_size)
|
||||
{
|
||||
@ -157,7 +181,9 @@ static int MrdbPool_initialize(MrdbPool *self, PyObject *args,
|
||||
{
|
||||
if (!(self->connection[i]=
|
||||
(MrdbConnection *)MrdbConnection_connect(NULL, args, self->configuration)))
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
clock_gettime(CLOCK_MONOTONIC_RAW, &self->connection[i]->last_used);
|
||||
Py_INCREF(self->connection[i]);
|
||||
self->connection[i]->pool= self;
|
||||
@ -183,17 +209,17 @@ error:
|
||||
MARIADB_FREE_MEM(self->connection);
|
||||
return -1;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static int MrdbPool_traverse(
|
||||
MrdbPool *self,
|
||||
static int
|
||||
MrdbPool_traverse(MrdbPool *self,
|
||||
visitproc visit,
|
||||
void *arg)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyTypeObject MrdbPool_Type =
|
||||
PyTypeObject
|
||||
MrdbPool_Type =
|
||||
{
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
"mariadb.ConnectionPool",
|
||||
@ -259,8 +285,8 @@ PyTypeObject MrdbPool_Type =
|
||||
0, /* tp_free Low-level free-memory routine */
|
||||
};
|
||||
|
||||
/*{{{ MrDBPool_dealloc */
|
||||
void MrdbPool_dealloc(MrdbPool *self)
|
||||
void
|
||||
MrdbPool_dealloc(MrdbPool *self)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
@ -296,15 +322,16 @@ void MrdbPool_dealloc(MrdbPool *self)
|
||||
/* }}} */
|
||||
|
||||
PyObject *
|
||||
MrdbPool_add(
|
||||
PyObject *self,
|
||||
MrdbPool_add(PyObject *self,
|
||||
PyObject *args,
|
||||
PyObject *kwargs)
|
||||
{
|
||||
MrdbPool *c;
|
||||
|
||||
if (!(c= (MrdbPool *)PyType_GenericAlloc(&MrdbPool_Type, 1)))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (MrdbPool_initialize(c, args, kwargs))
|
||||
{
|
||||
@ -314,7 +341,8 @@ MrdbPool_add(
|
||||
return (PyObject *) c;
|
||||
}
|
||||
|
||||
PyObject *MrdbPool_getconnection(MrdbPool *self)
|
||||
PyObject *
|
||||
MrdbPool_getconnection(MrdbPool *self)
|
||||
{
|
||||
uint32_t i;
|
||||
MrdbConnection *conn= NULL;
|
||||
@ -337,7 +365,8 @@ PyObject *MrdbPool_getconnection(MrdbPool *self)
|
||||
conn= self->connection[i];
|
||||
tdiff= t;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
self->connection[i]->pool= NULL;
|
||||
MrdbConnection_close(self->connection[i]);
|
||||
self->connection[i]= NULL;
|
||||
@ -345,23 +374,29 @@ PyObject *MrdbPool_getconnection(MrdbPool *self)
|
||||
}
|
||||
}
|
||||
if (conn)
|
||||
{
|
||||
conn->inuse= 1;
|
||||
}
|
||||
pthread_mutex_unlock(&self->lock);
|
||||
if (conn)
|
||||
{
|
||||
return (PyObject *)conn;
|
||||
}
|
||||
mariadb_throw_exception(NULL, Mariadb_PoolError, 0,
|
||||
"No more connections from pool '%s' available",
|
||||
self->pool_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static PyObject *MrdbPool_setconfig(MrdbPool *self, PyObject *args, PyObject *kwargs)
|
||||
static PyObject
|
||||
*MrdbPool_setconfig(MrdbPool *self, PyObject *args, PyObject *kwargs)
|
||||
{
|
||||
self->configuration= kwargs;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject * MrdbPool_addconnection(MrdbPool *self, PyObject *args)
|
||||
static PyObject *
|
||||
MrdbPool_addconnection(MrdbPool *self, PyObject *args)
|
||||
{
|
||||
uint32_t i;
|
||||
MrdbConnection *conn= NULL;
|
||||
@ -375,7 +410,9 @@ static PyObject * MrdbPool_addconnection(MrdbPool *self, PyObject *args)
|
||||
}
|
||||
|
||||
if (!PyArg_ParseTuple(args, "|O!", &MrdbConnection_Type, &conn))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (conn && conn->pool)
|
||||
{
|
||||
@ -391,8 +428,11 @@ static PyObject * MrdbPool_addconnection(MrdbPool *self, PyObject *args)
|
||||
if (!self->connection[i])
|
||||
{
|
||||
if (!conn &&
|
||||
(!(conn = (MrdbConnection *)MrdbConnection_connect(NULL, args, self->configuration))))
|
||||
(!(conn = (MrdbConnection *)MrdbConnection_connect(NULL, args,
|
||||
self->configuration))))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
self->connection[i]= conn;
|
||||
self->connection[i]->inuse= 0;
|
||||
clock_gettime(CLOCK_MONOTONIC_RAW, &self->connection[i]->last_used);
|
||||
@ -410,25 +450,30 @@ static PyObject * MrdbPool_addconnection(MrdbPool *self, PyObject *args)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static PyObject *MrdbPool_poolname(MrdbPool *self)
|
||||
static PyObject *
|
||||
MrdbPool_poolname(MrdbPool *self)
|
||||
{
|
||||
return PyUnicode_FromString(self->pool_name);
|
||||
}
|
||||
|
||||
static PyObject *MrdbPool_poolsize(MrdbPool *self)
|
||||
static PyObject
|
||||
*MrdbPool_poolsize(MrdbPool *self)
|
||||
{
|
||||
return PyLong_FromUnsignedLongLong(self->pool_size);
|
||||
}
|
||||
|
||||
static PyObject *MrdbPool_get_resetconnection(MrdbPool *self)
|
||||
static PyObject *
|
||||
MrdbPool_get_resetconnection(MrdbPool *self)
|
||||
{
|
||||
if (self->reset_session)
|
||||
{
|
||||
Py_RETURN_TRUE;
|
||||
}
|
||||
Py_RETURN_FALSE;
|
||||
}
|
||||
|
||||
/* {{{ MrdbCursor_setbuffered */
|
||||
static int MrdbPool_set_resetconnection(MrdbPool *self, PyObject *arg)
|
||||
static int
|
||||
MrdbPool_set_resetconnection(MrdbPool *self, PyObject *arg)
|
||||
{
|
||||
if (!arg || Py_TYPE(arg) != &PyBool_Type)
|
||||
{
|
||||
@ -439,4 +484,3 @@ static int MrdbPool_set_resetconnection(MrdbPool *self, PyObject *arg)
|
||||
self->reset_session= PyObject_IsTrue(arg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user