/* -*- mode: C; indent-tabs-mode: t; c-basic-offset: 8; -*- */ #include "mysqlmod.h" PyObject *_mysql_MySQLError; PyObject *_mysql_Warning; PyObject *_mysql_Error; PyObject *_mysql_DatabaseError; PyObject *_mysql_InterfaceError; PyObject *_mysql_DataError; PyObject *_mysql_OperationalError; PyObject *_mysql_IntegrityError; PyObject *_mysql_InternalError; PyObject *_mysql_ProgrammingError; PyObject *_mysql_NotSupportedError; PyObject *_mysql_error_map; int _mysql_server_init_done = 0; PyObject * _mysql_Exception(_mysql_ConnectionObject *c) { PyObject *t, *e; int merr; if (!(t = PyTuple_New(2))) return NULL; if (!_mysql_server_init_done) { e = _mysql_InternalError; PyTuple_SET_ITEM(t, 0, PyInt_FromLong(-1L)); PyTuple_SET_ITEM(t, 1, PyString_FromString("server not initialized")); PyErr_SetObject(e, t); Py_DECREF(t); return NULL; } merr = mysql_errno(&(c->connection)); if (!merr) e = _mysql_InterfaceError; else if (merr > CR_MAX_ERROR) { PyTuple_SET_ITEM(t, 0, PyInt_FromLong(-1L)); PyTuple_SET_ITEM(t, 1, PyString_FromString("error totally whack")); PyErr_SetObject(_mysql_InterfaceError, t); Py_DECREF(t); return NULL; } else { PyObject *py_merr = PyInt_FromLong(merr); e = PyDict_GetItem(_mysql_error_map, py_merr); Py_DECREF(py_merr); if (!e) { if (merr < 1000) e = _mysql_InternalError; else e = _mysql_OperationalError; } } PyTuple_SET_ITEM(t, 0, PyInt_FromLong((long)merr)); PyTuple_SET_ITEM(t, 1, PyString_FromString(mysql_error(&(c->connection)))); PyErr_SetObject(e, t); Py_DECREF(t); return NULL; } static char _mysql_server_init__doc__[] = "Initialize embedded server. If this client is not linked against\n\ the embedded server library, this function does nothing.\n\ \n\ args -- sequence of command-line arguments\n\ groups -- sequence of groups to use in defaults files\n\ "; static PyObject *_mysql_server_init( PyObject *self, PyObject *args, PyObject *kwargs) { static char *kwlist[] = {"args", "groups", NULL}; char **cmd_args_c=NULL, **groups_c=NULL, *s; Py_ssize_t cmd_argc=0, i, groupc; PyObject *cmd_args=NULL, *groups=NULL, *ret=NULL, *item; if (_mysql_server_init_done) { PyErr_SetString(_mysql_ProgrammingError, "already initialized"); return NULL; } if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OO", kwlist, &cmd_args, &groups)) return NULL; #if MYSQL_VERSION_ID >= 40000 if (cmd_args) { if (!PySequence_Check(cmd_args)) { PyErr_SetString(PyExc_TypeError, "args must be a sequence"); goto finish; } cmd_argc = PySequence_Size(cmd_args); if (cmd_argc == -1) { PyErr_SetString(PyExc_TypeError, "args could not be sized"); goto finish; } cmd_args_c = (char **) PyMem_Malloc(cmd_argc*sizeof(char *)); for (i=0; i< cmd_argc; i++) { item = PySequence_GetItem(cmd_args, i); s = PyString_AsString(item); Py_DECREF(item); if (!s) { PyErr_SetString(PyExc_TypeError, "args must contain strings"); goto finish; } cmd_args_c[i] = s; } } if (groups) { if (!PySequence_Check(groups)) { PyErr_SetString(PyExc_TypeError, "groups must be a sequence"); goto finish; } groupc = PySequence_Size(groups); if (groupc == -1) { PyErr_SetString(PyExc_TypeError, "groups could not be sized"); goto finish; } groups_c = (char **) PyMem_Malloc((1+groupc)*sizeof(char *)); for (i=0; i< groupc; i++) { item = PySequence_GetItem(groups, i); s = PyString_AsString(item); Py_DECREF(item); if (!s) { PyErr_SetString(PyExc_TypeError, "groups must contain strings"); goto finish; } groups_c[i] = s; } groups_c[groupc] = (char *)NULL; } /* even though this may block, don't give up the interpreter lock so that the server can't be initialized multiple times. */ if (mysql_server_init(cmd_argc, cmd_args_c, groups_c)) { _mysql_Exception(NULL); goto finish; } #endif ret = Py_None; Py_INCREF(Py_None); _mysql_server_init_done = 1; finish: PyMem_Free(groups_c); PyMem_Free(cmd_args_c); return ret; } static char _mysql_server_end__doc__[] = "Shut down embedded server. If not using an embedded server, this\n\ does nothing."; static PyObject *_mysql_server_end( PyObject *self, PyObject *unused) { if (_mysql_server_init_done) { #if MYSQL_VERSION_ID >= 40000 mysql_server_end(); #endif _mysql_server_init_done = 0; Py_INCREF(Py_None); return Py_None; } return _mysql_Exception(NULL); } #if MYSQL_VERSION_ID >= 32314 static char _mysql_thread_safe__doc__[] = "Indicates whether the client is compiled as thread-safe."; static PyObject *_mysql_thread_safe( PyObject *self, PyObject *unused) { check_server_init(NULL); return PyInt_FromLong((long)mysql_thread_safe()); } #endif extern char _mysql_connect__doc__[]; PyObject * _mysql_connect( PyObject *self, PyObject *args, PyObject *kwargs); static char _mysql_debug__doc__[] = "Does a DBUG_PUSH with the given string.\n\ mysql_debug() uses the Fred Fish debug library.\n\ To use this function, you must compile the client library to\n\ support debugging.\n\ "; static PyObject * _mysql_debug( PyObject *self, PyObject *args) { char *debug; if (!PyArg_ParseTuple(args, "s", &debug)) return NULL; mysql_debug(debug); Py_INCREF(Py_None); return Py_None; } extern char _mysql_escape_string__doc__[]; PyObject * _mysql_escape_string( _mysql_ConnectionObject *self, PyObject *args); extern char _mysql_string_literal__doc__[]; PyObject * _mysql_string_literal( _mysql_ConnectionObject *self, PyObject *args); static PyObject *_mysql_NULL; PyObject * _escape_item( PyObject *item, PyObject *d) { PyObject *quoted=NULL, *itemtype, *itemconv; if (!(itemtype = PyObject_Type(item))) goto error; itemconv = PyObject_GetItem(d, itemtype); Py_DECREF(itemtype); if (!itemconv) { PyErr_Clear(); itemconv = PyObject_GetItem(d, (PyObject *) &PyString_Type); } if (!itemconv) { PyErr_SetString(PyExc_TypeError, "no default type converter defined"); goto error; } quoted = PyObject_CallFunction(itemconv, "OO", item, d); Py_DECREF(itemconv); error: return quoted; } extern char _mysql_escape__doc__[]; PyObject * _mysql_escape( PyObject *self, PyObject *args); static char _mysql_get_client_info__doc__[] = "get_client_info() -- Returns a string that represents\n\ the client library version."; static PyObject * _mysql_get_client_info( PyObject *self, PyObject *unused) { check_server_init(NULL); return PyString_FromString(mysql_get_client_info()); } extern PyTypeObject _mysql_ConnectionObject_Type; extern PyTypeObject _mysql_ResultObject_Type; static PyMethodDef _mysql_methods[] = { { "connect", (PyCFunction)_mysql_connect, METH_VARARGS | METH_KEYWORDS, _mysql_connect__doc__ }, { "debug", (PyCFunction)_mysql_debug, METH_VARARGS, _mysql_debug__doc__ }, { "get_client_info", (PyCFunction)_mysql_get_client_info, METH_NOARGS, _mysql_get_client_info__doc__ }, #if MYSQL_VERSION_ID >= 32314 { "thread_safe", (PyCFunction)_mysql_thread_safe, METH_NOARGS, _mysql_thread_safe__doc__ }, #endif { "server_init", (PyCFunction)_mysql_server_init, METH_VARARGS | METH_KEYWORDS, _mysql_server_init__doc__ }, { "server_end", (PyCFunction)_mysql_server_end, METH_NOARGS, _mysql_server_end__doc__ }, {NULL, NULL} /* sentinel */ }; static PyObject * _mysql_NewException( PyObject *dict, PyObject *edict, char *name) { PyObject *e; if (!(e = PyDict_GetItemString(edict, name))) return NULL; if (PyDict_SetItemString(dict, name, e)) return NULL; return e; } #define QUOTE(X) _QUOTE(X) #define _QUOTE(X) #X static char _mysql___doc__[] = "an adaptation of the MySQL C API (mostly)\n\ \n\ You probably are better off using MySQLdb instead of using this\n\ module directly.\n\ \n\ In general, renaming goes from mysql_* to _mysql.*. _mysql.connect()\n\ returns a connection object (MYSQL). Functions which expect MYSQL * as\n\ an argument are now methods of the connection object. A number of things\n\ return result objects (MYSQL_RES). Functions which expect MYSQL_RES * as\n\ an argument are now methods of the result object. Deprecated functions\n\ (as of 3.23) are NOT implemented.\n\ "; PyMODINIT_FUNC init_mysql(void) { PyObject *dict, *module, *emod, *edict, *version_tuple; module = Py_InitModule3("_mysql", _mysql_methods, _mysql___doc__); if (!module) return; /* this really should never happen */ /* Populate final object settings */ _mysql_ConnectionObject_Type.ob_type = &PyType_Type; _mysql_ResultObject_Type.ob_type = &PyType_Type; _mysql_FieldObject_Type.ob_type = &PyType_Type; _mysql_ConnectionObject_Type.tp_alloc = PyType_GenericAlloc; _mysql_ConnectionObject_Type.tp_new = PyType_GenericNew; _mysql_ConnectionObject_Type.tp_free = _PyObject_GC_Del; _mysql_ResultObject_Type.tp_alloc = PyType_GenericAlloc; _mysql_ResultObject_Type.tp_new = PyType_GenericNew; _mysql_ResultObject_Type.tp_free = _PyObject_GC_Del; _mysql_FieldObject_Type.tp_alloc = PyType_GenericAlloc; _mysql_FieldObject_Type.tp_new = PyType_GenericNew; _mysql_FieldObject_Type.tp_free = _PyObject_GC_Del; if (!(dict = PyModule_GetDict(module))) goto error; /* Module constants */ version_tuple = PyRun_String(QUOTE(version_info), Py_eval_input, dict, dict); if (PyModule_AddObject(module, "version_info", version_tuple) < 0) goto error; if (PyModule_AddStringConstant(module, "__version__", QUOTE(__version__)) < 0) goto error; if (PyModule_AddStringConstant(module, "NULL", "NULL") < 0) goto error; /* Register types */ if (PyDict_SetItemString(dict, "connection", (PyObject *)&_mysql_ConnectionObject_Type)) goto error; Py_INCREF(&_mysql_ConnectionObject_Type); if (PyDict_SetItemString(dict, "result", (PyObject *)&_mysql_ResultObject_Type)) goto error; Py_INCREF(&_mysql_ResultObject_Type); if (PyDict_SetItemString(dict, "field", (PyObject *)&_mysql_FieldObject_Type)) goto error; Py_INCREF(&_mysql_FieldObject_Type); /* Reach into the exceptions module. */ if (!(emod = PyImport_ImportModule("MySQLdb.exceptions"))) goto error; if (!(edict = PyModule_GetDict(emod))) goto error; if (!(_mysql_MySQLError = _mysql_NewException(dict, edict, "MySQLError"))) goto error; if (!(_mysql_Warning = _mysql_NewException(dict, edict, "Warning"))) goto error; if (!(_mysql_Error = _mysql_NewException(dict, edict, "Error"))) goto error; if (!(_mysql_InterfaceError = _mysql_NewException(dict, edict, "InterfaceError"))) goto error; if (!(_mysql_DatabaseError = _mysql_NewException(dict, edict, "DatabaseError"))) goto error; if (!(_mysql_DataError = _mysql_NewException(dict, edict, "DataError"))) goto error; if (!(_mysql_OperationalError = _mysql_NewException(dict, edict, "OperationalError"))) goto error; if (!(_mysql_IntegrityError = _mysql_NewException(dict, edict, "IntegrityError"))) goto error; if (!(_mysql_InternalError = _mysql_NewException(dict, edict, "InternalError"))) goto error; if (!(_mysql_ProgrammingError = _mysql_NewException(dict, edict, "ProgrammingError"))) goto error; if (!(_mysql_NotSupportedError = _mysql_NewException(dict, edict, "NotSupportedError"))) goto error; if (!(_mysql_error_map = PyDict_GetItemString(edict, "error_map"))) goto error; Py_DECREF(emod); error: if (PyErr_Occurred()) PyErr_SetString(PyExc_ImportError, "_mysql: init failed"); return; }