Files
mariadb-connector-python/mariadb/mariadb_exception.c
Georg Richter 29b05e3b09 Various fixes and changes for SQLAlchemy support:
- added a thin python wrapper around mariadb module
- added constansts under mariadb.constants (CLIENT, CURSOR, INDICATOR)
- bench and test are now in testing subdirectory
- updated documentation
2020-07-24 12:13:31 +02:00

165 lines
5.3 KiB
C

/************************************************************************************
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>
/* Exceptions */
PyObject *Mariadb_InterfaceError;
PyObject *Mariadb_Error;
PyObject *Mariadb_DatabaseError;
PyObject *Mariadb_DataError;
PyObject *Mariadb_PoolError;
PyObject *Mariadb_OperationalError;
PyObject *Mariadb_IntegrityError;
PyObject *Mariadb_InternalError;
PyObject *Mariadb_ProgrammingError;
PyObject *Mariadb_NotSupportedError;
PyObject *Mariadb_Warning;
struct st_error_map {
char sqlstate[3];
uint8_t type;
};
static PyObject *get_exception_type(const char *sqlstate)
{
if (!sqlstate || strlen(sqlstate) != 5)
return NULL;
if (!strncmp(sqlstate, "21", 2) ||
!strncmp(sqlstate, "22", 2) ||
!strncmp(sqlstate, "02", 2))
return Mariadb_DataError;
if (!strncmp(sqlstate, "07", 2) ||
!strncmp(sqlstate, "2B", 2) ||
!strncmp(sqlstate, "2D", 2) ||
!strncmp(sqlstate, "33", 2) ||
!strncmp(sqlstate, "HY", 2))
return Mariadb_DatabaseError;
if (!strncmp(sqlstate, "23", 2) ||
!strncmp(sqlstate, "XA", 2))
return Mariadb_IntegrityError;
if (!strncmp(sqlstate, "0A", 2))
return Mariadb_NotSupportedError;
if (!strncmp(sqlstate, "40", 2) ||
!strncmp(sqlstate, "44", 2))
return Mariadb_InternalError;
if (!strncmp(sqlstate, "0K", 2) ||
!strncmp(sqlstate, "08", 2) ||
!strncmp(sqlstate, "HZ", 2))
return Mariadb_OperationalError;
if (!strncmp(sqlstate, "24", 2) ||
!strncmp(sqlstate, "25", 2) ||
!strncmp(sqlstate, "26", 2) ||
!strncmp(sqlstate, "27", 2) ||
!strncmp(sqlstate, "28", 2) ||
!strncmp(sqlstate, "2A", 2) ||
!strncmp(sqlstate, "2C", 2) ||
!strncmp(sqlstate, "2F", 2) ||
!strncmp(sqlstate, "34", 2) ||
!strncmp(sqlstate, "35", 2) ||
!strncmp(sqlstate, "3C", 2) ||
!strncmp(sqlstate, "3D", 2) ||
!strncmp(sqlstate, "3F", 2) ||
!strncmp(sqlstate, "37", 2) ||
!strncmp(sqlstate, "42", 2) ||
!strncmp(sqlstate, "70", 2))
return Mariadb_ProgrammingError;
return NULL;
}
/**
mariadb_throw_exception()
@brief raises an exception
@param handle[in] a connection or statement handle
@param exception_type[in] type of exception
@param is_statement[in] 1 is handle is a MYSQL_STMT handle
@param message[in] Error message. If message is NULL, the error
message will be retrieved from specified handle.
@param ... [in] message parameter
@return void
*/
void mariadb_throw_exception(void *handle,
PyObject *exception_type,
unsigned char is_statement,
const char *message,
...)
{
va_list ap;
PyObject *ErrorMsg= 0;
PyObject *ErrorNo= 0;
PyObject *SqlState= 0;
PyObject *Exception= 0;
//if (!exception_type)
// exception_type= Mariadb_InterfaceError;
if (message)
{
ErrorNo= PyLong_FromLong(-1);
SqlState= PyUnicode_FromString("HY000");
va_start(ap, message);
ErrorMsg= PyUnicode_FromFormatV(message, ap);
va_end(ap);
} else
{
exception_type= get_exception_type(is_statement ? mysql_stmt_sqlstate((MYSQL_STMT*) handle) : mysql_sqlstate((MYSQL *)handle));
if (!exception_type)
exception_type= Mariadb_DatabaseError;
ErrorNo= PyLong_FromLong(is_statement ?
mysql_stmt_errno((MYSQL_STMT *)handle) : mysql_errno((MYSQL *)handle));
ErrorMsg= PyUnicode_FromString(is_statement ?
mysql_stmt_error((MYSQL_STMT *)handle) : mysql_error((MYSQL *)handle));
SqlState= PyUnicode_FromString(is_statement ?
mysql_stmt_sqlstate((MYSQL_STMT *)handle) : mysql_sqlstate((MYSQL *)handle));
}
if (!(Exception= PyObject_CallFunctionObjArgs(exception_type, ErrorMsg, NULL)))
{
PyErr_SetString(PyExc_RuntimeError,
"Failed to create exception");
return;
}
PyObject_SetAttr(Exception, PyUnicode_FromString("sqlstate"), SqlState);
PyObject_SetAttr(Exception, PyUnicode_FromString("errno"), ErrorNo);
PyObject_SetAttr(Exception, PyUnicode_FromString("errmsg"), ErrorMsg);
/* For MySQL Connector/Python compatibility */
PyObject_SetAttr(Exception, PyUnicode_FromString("msg"), ErrorMsg);
PyErr_SetObject(exception_type, Exception);
Py_XDECREF(ErrorMsg);
Py_XDECREF(ErrorNo);
Py_XDECREF(SqlState);
}