Mercurial > p > mysql-python > mysqldb-2
changeset 55:e606fd52e866 MySQLdb
make things a little cleaner by moving to a src directory for the C code
author | kylev |
---|---|
date | Fri, 27 Feb 2009 19:14:09 +0000 |
parents | 6e31278d3433 |
children | 89b07ce2a788 |
files | _mysql.c _mysql.h _mysql_connections.c _mysql_fields.c _mysql_results.c setup.py src/connections.c src/fields.c src/mysqlmod.c src/mysqlmod.h src/results.c |
diffstat | 11 files changed, 3159 insertions(+), 3161 deletions(-) [+] |
line wrap: on
line diff
--- a/_mysql.c Mon Feb 23 23:52:44 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,542 +0,0 @@ -/* -*- mode: C; indent-tabs-mode: t; c-basic-offset: 8; -*- */ - -#include "_mysql.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_escape_sequence__doc__[] = -"escape_sequence(seq, dict) -- escape any special characters in sequence\n\ -seq using mapping dict to provide quoting functions for each type.\n\ -Returns a tuple of escaped items."; -static PyObject * -_mysql_escape_sequence( - PyObject *self, - PyObject *args) -{ - PyObject *o=NULL, *d=NULL, *r=NULL, *item, *quoted; - int i, n; - if (!PyArg_ParseTuple(args, "OO:escape_sequence", &o, &d)) - goto error; - if (!PyMapping_Check(d)) { - PyErr_SetString(PyExc_TypeError, - "argument 2 must be a mapping"); - return NULL; - } - if ((n = PyObject_Length(o)) == -1) goto error; - if (!(r = PyTuple_New(n))) goto error; - for (i=0; i<n; i++) { - item = PySequence_GetItem(o, i); - if (!item) goto error; - quoted = _escape_item(item, d); - Py_DECREF(item); - if (!quoted) goto error; - PyTuple_SET_ITEM(r, i, quoted); - } - return r; - error: - Py_XDECREF(r); - return NULL; -} - -static char _mysql_escape_dict__doc__[] = -"escape_sequence(d, dict) -- escape any special characters in\n\ -dictionary d using mapping dict to provide quoting functions for each type.\n\ -Returns a dictionary of escaped items."; -static PyObject * -_mysql_escape_dict( - PyObject *self, - PyObject *args) -{ - PyObject *o=NULL, *d=NULL, *r=NULL, *item, *quoted, *pkey; - Py_ssize_t ppos = 0; - if (!PyArg_ParseTuple(args, "O!O:escape_dict", &PyDict_Type, &o, &d)) - goto error; - if (!PyMapping_Check(d)) { - PyErr_SetString(PyExc_TypeError, - "argument 2 must be a mapping"); - return NULL; - } - if (!(r = PyDict_New())) goto error; - while (PyDict_Next(o, &ppos, &pkey, &item)) { - quoted = _escape_item(item, d); - if (!quoted) goto error; - if (PyDict_SetItem(r, pkey, quoted)==-1) goto error; - Py_DECREF(quoted); - } - return r; - error: - Py_XDECREF(r); - return NULL; -} - -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__ - }, - { - "escape", - (PyCFunction)_mysql_escape, - METH_VARARGS, - _mysql_escape__doc__ - }, - { - "escape_sequence", - (PyCFunction)_mysql_escape_sequence, - METH_VARARGS, - _mysql_escape_sequence__doc__ - }, - { - "escape_dict", - (PyCFunction)_mysql_escape_dict, - METH_VARARGS, - _mysql_escape_dict__doc__ - }, - { - "escape_string", - (PyCFunction)_mysql_escape_string, - METH_VARARGS, - _mysql_escape_string__doc__ - }, - { - "string_literal", - (PyCFunction)_mysql_string_literal, - METH_VARARGS, - _mysql_string_literal__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; -} - -
--- a/_mysql.h Mon Feb 23 23:52:44 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,93 +0,0 @@ -#ifndef _MYSQL_PYTHON__MYSQL_H_ -#define _MYSQL_PYTHON__MYSQL_H_ - -#include <Python.h> - -#ifdef MS_WIN32 -#include <windows.h> -#endif /* MS_WIN32 */ - -#include "structmember.h" -#include "mysql.h" -#include "my_config.h" -#include "mysqld_error.h" -#include "errmsg.h" - -#define MyAlloc(s,t) (s *) t.tp_alloc(&t,0) -#define MyFree(ob) ob->ob_type->tp_free((PyObject *)ob) - -#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN) -typedef int Py_ssize_t; -#define PY_SSIZE_T_MAX INT_MAX -#define PY_SSIZE_T_MIN INT_MIN -#endif - -typedef struct { - PyObject_HEAD - MYSQL connection; - int open; - PyObject *converter; -} _mysql_ConnectionObject; - -#define check_connection(c) if (!(c->open)) return _mysql_Exception(c) -#define result_connection(r) ((_mysql_ConnectionObject *)r->conn) -#define check_result_connection(r) check_connection(result_connection(r)) - -extern PyTypeObject _mysql_ConnectionObject_Type; - -typedef struct { - PyObject_HEAD - PyObject *conn; - MYSQL_RES *result; - int nfields; - int use; - PyObject *converter; -} _mysql_ResultObject; - -extern PyTypeObject _mysql_ResultObject_Type; - -typedef struct { - PyObject_HEAD - PyObject *result; - MYSQL_FIELD field; - unsigned int index; -} _mysql_FieldObject; - -extern PyTypeObject _mysql_FieldObject_Type; - -extern int _mysql_server_init_done; -#if MYSQL_VERSION_ID >= 40000 -#define check_server_init(x) if (!_mysql_server_init_done) { if (mysql_server_init(0, NULL, NULL)) { _mysql_Exception(NULL); return x; } else { _mysql_server_init_done = 1;} } -#else -#define check_server_init(x) if (!_mysql_server_init_done) _mysql_server_init_done = 1 -#endif - -extern PyObject *_mysql_MySQLError; -extern PyObject *_mysql_Warning; -extern PyObject *_mysql_Error; -extern PyObject *_mysql_DatabaseError; -extern PyObject *_mysql_InterfaceError; -extern PyObject *_mysql_DataError; -extern PyObject *_mysql_OperationalError; -extern PyObject *_mysql_IntegrityError; -extern PyObject *_mysql_InternalError; -extern PyObject *_mysql_ProgrammingError; -extern PyObject *_mysql_NotSupportedError; -extern PyObject *_mysql_error_map; - -extern PyObject * -_mysql_Exception(_mysql_ConnectionObject *c); - -extern int -_mysql_ResultObject_Initialize( - _mysql_ResultObject *self, - PyObject *args, - PyObject *kwargs); - -extern int -_mysql_FieldObject_Initialize( - _mysql_FieldObject *self, - PyObject *args, - PyObject *kwargs); - -#endif
--- a/_mysql_connections.c Mon Feb 23 23:52:44 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1473 +0,0 @@ -/* -*- mode: C; indent-tabs-mode: t; c-basic-offset: 8; -*- */ - -#include "_mysql.h" - -static int -_mysql_ConnectionObject_Initialize( - _mysql_ConnectionObject *self, - PyObject *args, - PyObject *kwargs) -{ - MYSQL *conn = NULL; - PyObject *conv = NULL; - PyObject *ssl = NULL; -#if HAVE_OPENSSL - char *key = NULL, *cert = NULL, *ca = NULL, - *capath = NULL, *cipher = NULL; -#endif - char *host = NULL, *user = NULL, *passwd = NULL, - *db = NULL, *unix_socket = NULL; - unsigned int port = 0; - unsigned int client_flag = 0; - static char *kwlist[] = { "host", "user", "passwd", "db", "port", - "unix_socket", "conv", - "connect_timeout", "compress", - "named_pipe", "init_command", - "read_default_file", "read_default_group", - "client_flag", "ssl", - "local_infile", - NULL } ; - int connect_timeout = 0; - int compress = -1, named_pipe = -1, local_infile = -1; - char *init_command=NULL, - *read_default_file=NULL, - *read_default_group=NULL; - - self->converter = NULL; - self->open = 0; - check_server_init(-1); - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ssssisOiiisssiOi:connect", - kwlist, - &host, &user, &passwd, &db, - &port, &unix_socket, &conv, - &connect_timeout, - &compress, &named_pipe, - &init_command, &read_default_file, - &read_default_group, - &client_flag, &ssl, - &local_infile - )) - return -1; - - /* Keep the converter mapping or a blank mapping dict */ - if (!conv) - conv = PyDict_New(); - else - Py_INCREF(conv); - if (!conv) - return -1; - self->converter = conv; - -#define _stringsuck(d,t,s) {t=PyMapping_GetItemString(s,#d);\ - if(t){d=PyString_AsString(t);Py_DECREF(t);}\ - PyErr_Clear();} - - if (ssl) { -#if HAVE_OPENSSL - PyObject *value = NULL; - _stringsuck(ca, value, ssl); - _stringsuck(capath, value, ssl); - _stringsuck(cert, value, ssl); - _stringsuck(key, value, ssl); - _stringsuck(cipher, value, ssl); -#else - PyErr_SetString(_mysql_NotSupportedError, - "client library does not have SSL support"); - return -1; -#endif - } - - Py_BEGIN_ALLOW_THREADS ; - conn = mysql_init(&(self->connection)); - if (connect_timeout) { - unsigned int timeout = connect_timeout; - mysql_options(&(self->connection), MYSQL_OPT_CONNECT_TIMEOUT, - (char *)&timeout); - } - if (compress != -1) { - mysql_options(&(self->connection), MYSQL_OPT_COMPRESS, 0); - client_flag |= CLIENT_COMPRESS; - } - if (named_pipe != -1) - mysql_options(&(self->connection), MYSQL_OPT_NAMED_PIPE, 0); - if (init_command != NULL) - mysql_options(&(self->connection), MYSQL_INIT_COMMAND, init_command); - if (read_default_file != NULL) - mysql_options(&(self->connection), MYSQL_READ_DEFAULT_FILE, read_default_file); - if (read_default_group != NULL) - mysql_options(&(self->connection), MYSQL_READ_DEFAULT_GROUP, read_default_group); - - if (local_infile != -1) - mysql_options(&(self->connection), MYSQL_OPT_LOCAL_INFILE, (char *) &local_infile); - -#if HAVE_OPENSSL - if (ssl) - mysql_ssl_set(&(self->connection), - key, cert, ca, capath, cipher); -#endif - - conn = mysql_real_connect(&(self->connection), host, user, passwd, db, - port, unix_socket, client_flag); - - Py_END_ALLOW_THREADS ; - - if (!conn) { - _mysql_Exception(self); - return -1; - } - /* - PyType_GenericAlloc() automatically sets up GC allocation and - tracking for GC objects, at least in 2.2.1, so it does not need to - be done here. tp_dealloc still needs to call PyObject_GC_UnTrack(), - however. - */ - self->open = 1; - return 0; -} - -char _mysql_connect__doc__[] = -"Returns a MYSQL connection object. Exclusive use of\n\ -keyword parameters strongly recommended. Consult the\n\ -MySQL C API documentation for more details.\n\ -\n\ -host\n\ - string, host to connect\n\ -\n\ -user\n\ - string, user to connect as\n\ -\n\ -passwd\n\ - string, password to use\n\ -\n\ -db\n\ - string, database to use\n\ -\n\ -port\n\ - integer, TCP/IP port to connect to\n\ -\n\ -unix_socket\n\ - string, location of unix_socket (UNIX-ish only)\n\ -\n\ -conv\n\ - mapping, maps MySQL FIELD_TYPE.* to Python functions which\n\ - convert a string to the appropriate Python type\n\ -\n\ -connect_timeout\n\ - number of seconds to wait before the connection\n\ - attempt fails.\n\ -\n\ -compress\n\ - if set, gzip compression is enabled\n\ -\n\ -named_pipe\n\ - if set, connect to server via named pipe (Windows only)\n\ -\n\ -init_command\n\ - command which is run once the connection is created\n\ -\n\ -read_default_file\n\ - see the MySQL documentation for mysql_options()\n\ -\n\ -read_default_group\n\ - see the MySQL documentation for mysql_options()\n\ -\n\ -client_flag\n\ - client flags from MySQLdb.constants.CLIENT\n\ -\n\ -load_infile\n\ - int, non-zero enables LOAD LOCAL INFILE, zero disables\n\ -\n\ -"; - -PyObject * -_mysql_connect( - PyObject *self, - PyObject *args, - PyObject *kwargs) -{ - _mysql_ConnectionObject *c=NULL; - - c = MyAlloc(_mysql_ConnectionObject, _mysql_ConnectionObject_Type); - if (c == NULL) return NULL; - if (_mysql_ConnectionObject_Initialize(c, args, kwargs)) { - Py_DECREF(c); - c = NULL; - } - return (PyObject *) c; -} - -static int _mysql_ConnectionObject_traverse( - _mysql_ConnectionObject *self, - visitproc visit, - void *arg) -{ - if (self->converter) - return visit(self->converter, arg); - return 0; -} - -static int _mysql_ConnectionObject_clear( - _mysql_ConnectionObject *self) -{ - Py_XDECREF(self->converter); - self->converter = NULL; - return 0; -} - -extern PyObject * -_escape_item( - PyObject *item, - PyObject *d); - -char _mysql_escape__doc__[] = -"escape(obj, dict) -- escape any special characters in object obj\n\ -using mapping dict to provide quoting functions for each type.\n\ -Returns a SQL literal string."; -PyObject * -_mysql_escape( - PyObject *self, - PyObject *args) -{ - PyObject *o=NULL, *d=NULL; - if (!PyArg_ParseTuple(args, "O|O:escape", &o, &d)) - return NULL; - if (d) { - if (!PyMapping_Check(d)) { - PyErr_SetString(PyExc_TypeError, - "argument 2 must be a mapping"); - return NULL; - } - return _escape_item(o, d); - } else { - if (!self) { - PyErr_SetString(PyExc_TypeError, - "argument 2 must be a mapping"); - return NULL; - } - return _escape_item(o, - ((_mysql_ConnectionObject *) self)->converter); - } -} - -char _mysql_escape_string__doc__[] = -"escape_string(s) -- quote any SQL-interpreted characters in string s.\n\ -\n\ -Use connection.escape_string(s), if you use it at all.\n\ -_mysql.escape_string(s) cannot handle character sets. You are\n\ -probably better off using connection.escape(o) instead, since\n\ -it will escape entire sequences as well as strings."; - -PyObject * -_mysql_escape_string( - _mysql_ConnectionObject *self, - PyObject *args) -{ - PyObject *str; - char *in, *out; - int len, size; - if (!PyArg_ParseTuple(args, "s#:escape_string", &in, &size)) return NULL; - str = PyString_FromStringAndSize((char *) NULL, size*2+1); - if (!str) return PyErr_NoMemory(); - out = PyString_AS_STRING(str); -#if MYSQL_VERSION_ID < 32321 - len = mysql_escape_string(out, in, size); -#else - check_server_init(NULL); - if (self && self->open) - len = mysql_real_escape_string(&(self->connection), out, in, size); - else - len = mysql_escape_string(out, in, size); -#endif - if (_PyString_Resize(&str, len) < 0) return NULL; - return (str); -} - -char _mysql_string_literal__doc__[] = -"string_literal(obj) -- converts object obj into a SQL string literal.\n\ -This means, any special SQL characters are escaped, and it is enclosed\n\ -within single quotes. In other words, it performs:\n\ -\n\ -\"'%s'\" % escape_string(str(obj))\n\ -\n\ -Use connection.string_literal(obj), if you use it at all.\n\ -_mysql.string_literal(obj) cannot handle character sets."; - -PyObject * -_mysql_string_literal( - _mysql_ConnectionObject *self, - PyObject *args) -{ - PyObject *str, *s, *o, *d; - char *in, *out; - int len, size; - if (!PyArg_ParseTuple(args, "O|O:string_literal", &o, &d)) return NULL; - s = PyObject_Str(o); - if (!s) return NULL; - in = PyString_AsString(s); - size = PyString_GET_SIZE(s); - str = PyString_FromStringAndSize((char *) NULL, size*2+3); - if (!str) return PyErr_NoMemory(); - out = PyString_AS_STRING(str); -#if MYSQL_VERSION_ID < 32321 - len = mysql_escape_string(out+1, in, size); -#else - check_server_init(NULL); - if (self && self->open) - len = mysql_real_escape_string(&(self->connection), out+1, in, size); - else - len = mysql_escape_string(out+1, in, size); -#endif - *out = *(out+len+1) = '\''; - if (_PyString_Resize(&str, len+2) < 0) return NULL; - Py_DECREF(s); - return (str); -} - -static char _mysql_ConnectionObject_close__doc__[] = -"Close the connection. No further activity possible."; - -static PyObject * -_mysql_ConnectionObject_close( - _mysql_ConnectionObject *self, - PyObject *unused) -{ - if (self->open) { - Py_BEGIN_ALLOW_THREADS - mysql_close(&(self->connection)); - Py_END_ALLOW_THREADS - self->open = 0; - } else { - PyErr_SetString(_mysql_ProgrammingError, - "closing a closed connection"); - return NULL; - } - _mysql_ConnectionObject_clear(self); - Py_INCREF(Py_None); - return Py_None; -} - -static char _mysql_ConnectionObject_affected_rows__doc__ [] = -"Return number of rows affected by the last query.\n\ -Non-standard. Use Cursor.rowcount.\n\ -"; - -static PyObject * -_mysql_ConnectionObject_affected_rows( - _mysql_ConnectionObject *self, - PyObject *unused) -{ - check_connection(self); - return PyLong_FromUnsignedLongLong(mysql_affected_rows(&(self->connection))); -} - -static char _mysql_ConnectionObject_dump_debug_info__doc__[] = -"Instructs the server to write some debug information to the\n\ -log. The connected user must have the process privilege for\n\ -this to work. Non-standard.\n\ -"; - -static PyObject * -_mysql_ConnectionObject_dump_debug_info( - _mysql_ConnectionObject *self, - PyObject *unused) -{ - int err; - - check_connection(self); - Py_BEGIN_ALLOW_THREADS - err = mysql_dump_debug_info(&(self->connection)); - Py_END_ALLOW_THREADS - if (err) return _mysql_Exception(self); - Py_INCREF(Py_None); - return Py_None; -} - -static char _mysql_ConnectionObject_autocommit__doc__[] = -"Set the autocommit mode. True values enable; False value disable.\n\ -"; -static PyObject * -_mysql_ConnectionObject_autocommit( - _mysql_ConnectionObject *self, - PyObject *args) -{ - int flag, err; - if (!PyArg_ParseTuple(args, "i", &flag)) return NULL; - Py_BEGIN_ALLOW_THREADS -#if MYSQL_VERSION_ID >= 40100 - err = mysql_autocommit(&(self->connection), flag); -#else - { - char query[256]; - snprintf(query, 256, "SET AUTOCOMMIT=%d", flag); - err = mysql_query(&(self->connection), query); - } -#endif - Py_END_ALLOW_THREADS - if (err) return _mysql_Exception(self); - Py_INCREF(Py_None); - return Py_None; -} - -static char _mysql_ConnectionObject_commit__doc__[] = -"Commits the current transaction\n\ -"; -static PyObject * -_mysql_ConnectionObject_commit( - _mysql_ConnectionObject *self, - PyObject *unused) -{ - int err; - - Py_BEGIN_ALLOW_THREADS -#if MYSQL_VERSION_ID >= 40100 - err = mysql_commit(&(self->connection)); -#else - err = mysql_query(&(self->connection), "COMMIT"); -#endif - Py_END_ALLOW_THREADS - if (err) return _mysql_Exception(self); - Py_INCREF(Py_None); - return Py_None; -} - -static char _mysql_ConnectionObject_rollback__doc__[] = -"Rolls backs the current transaction\n\ -"; -static PyObject * -_mysql_ConnectionObject_rollback( - _mysql_ConnectionObject *self, - PyObject *unused) -{ - int err; - - Py_BEGIN_ALLOW_THREADS -#if MYSQL_VERSION_ID >= 40100 - err = mysql_rollback(&(self->connection)); -#else - err = mysql_query(&(self->connection), "ROLLBACK"); -#endif - Py_END_ALLOW_THREADS - if (err) return _mysql_Exception(self); - Py_INCREF(Py_None); - return Py_None; -} - -static char _mysql_ConnectionObject_next_result__doc__[] = -"If more query results exist, next_result() reads the next query\n\ -results and returns the status back to application.\n\ -\n\ -After calling next_result() the state of the connection is as if\n\ -you had called query() for the next query. This means that you can\n\ -now call store_result(), warning_count(), affected_rows()\n\ -, and so forth. \n\ -\n\ -Returns 0 if there are more results; -1 if there are no more results\n\ -\n\ -Non-standard.\n\ -"; -static PyObject * -_mysql_ConnectionObject_next_result( - _mysql_ConnectionObject *self, - PyObject *unused) -{ - int err; - - Py_BEGIN_ALLOW_THREADS -#if MYSQL_VERSION_ID >= 40100 - err = mysql_next_result(&(self->connection)); -#else - err = -1; -#endif - Py_END_ALLOW_THREADS - if (err > 0) return _mysql_Exception(self); - return PyInt_FromLong(err); -} - -#if MYSQL_VERSION_ID >= 40100 - -static char _mysql_ConnectionObject_set_server_option__doc__[] = -"set_server_option(option) -- Enables or disables an option\n\ -for the connection.\n\ -\n\ -Non-standard.\n\ -"; -static PyObject * -_mysql_ConnectionObject_set_server_option( - _mysql_ConnectionObject *self, - PyObject *args) -{ - int err, flags=0; - if (!PyArg_ParseTuple(args, "i", &flags)) - return NULL; - Py_BEGIN_ALLOW_THREADS - err = mysql_set_server_option(&(self->connection), flags); - Py_END_ALLOW_THREADS - if (err) return _mysql_Exception(self); - return PyInt_FromLong(err); -} - -static char _mysql_ConnectionObject_sqlstate__doc__[] = -"Returns a string containing the SQLSTATE error code\n\ -for the last error. The error code consists of five characters.\n\ -'00000' means \"no error.\" The values are specified by ANSI SQL\n\ -and ODBC. For a list of possible values, see section 23\n\ -Error Handling in MySQL in the MySQL Manual.\n\ -\n\ -Note that not all MySQL errors are yet mapped to SQLSTATE's.\n\ -The value 'HY000' (general error) is used for unmapped errors.\n\ -\n\ -Non-standard.\n\ -"; -static PyObject * -_mysql_ConnectionObject_sqlstate( - _mysql_ConnectionObject *self, - PyObject *unused) -{ - return PyString_FromString(mysql_sqlstate(&(self->connection))); -} - -static char _mysql_ConnectionObject_warning_count__doc__[] = -"Returns the number of warnings generated during execution\n\ -of the previous SQL statement.\n\ -\n\ -Non-standard.\n\ -"; -static PyObject * -_mysql_ConnectionObject_warning_count( - _mysql_ConnectionObject *self, - PyObject *unused) -{ - return PyInt_FromLong(mysql_warning_count(&(self->connection))); -} - -#endif - -static char _mysql_ConnectionObject_errno__doc__[] = -"Returns the error code for the most recently invoked API function\n\ -that can succeed or fail. A return value of zero means that no error\n\ -occurred.\n\ -"; - -static PyObject * -_mysql_ConnectionObject_errno( - _mysql_ConnectionObject *self, - PyObject *unused) -{ - check_connection(self); - return PyInt_FromLong((long)mysql_errno(&(self->connection))); -} - -static char _mysql_ConnectionObject_error__doc__[] = -"Returns the error message for the most recently invoked API function\n\ -that can succeed or fail. An empty string ("") is returned if no error\n\ -occurred.\n\ -"; - -static PyObject * -_mysql_ConnectionObject_error( - _mysql_ConnectionObject *self, - PyObject *unused) -{ - check_connection(self); - return PyString_FromString(mysql_error(&(self->connection))); -} - -#if MYSQL_VERSION_ID >= 32303 - -static char _mysql_ConnectionObject_change_user__doc__[] = -"Changes the user and causes the database specified by db to\n\ -become the default (current) database on the connection\n\ -specified by mysql. In subsequent queries, this database is\n\ -the default for table references that do not include an\n\ -explicit database specifier.\n\ -\n\ -This function was introduced in MySQL Version 3.23.3.\n\ -\n\ -Fails unless the connected user can be authenticated or if he\n\ -doesn't have permission to use the database. In this case the\n\ -user and database are not changed.\n\ -\n\ -The db parameter may be set to None if you don't want to have\n\ -a default database.\n\ -"; - -static PyObject * -_mysql_ConnectionObject_change_user( - _mysql_ConnectionObject *self, - PyObject *args, - PyObject *kwargs) -{ - char *user, *pwd=NULL, *db=NULL; - int r; - static char *kwlist[] = { "user", "passwd", "db", NULL } ; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|ss:change_user", - kwlist, &user, &pwd, &db)) - return NULL; - check_connection(self); - Py_BEGIN_ALLOW_THREADS - r = mysql_change_user(&(self->connection), user, pwd, db); - Py_END_ALLOW_THREADS - if (r) return _mysql_Exception(self); - Py_INCREF(Py_None); - return Py_None; -} -#endif - -static char _mysql_ConnectionObject_character_set_name__doc__[] = -"Returns the default character set for the current connection.\n\ -Non-standard.\n\ -"; - -static PyObject * -_mysql_ConnectionObject_character_set_name( - _mysql_ConnectionObject *self, - PyObject *unused) -{ - const char *s; - - check_connection(self); -#if MYSQL_VERSION_ID >= 32321 - s = mysql_character_set_name(&(self->connection)); -#else - s = "latin1"; -#endif - return PyString_FromString(s); -} - -#if MYSQL_VERSION_ID >= 50007 -static char _mysql_ConnectionObject_set_character_set__doc__[] = -"Sets the default character set for the current connection.\n\ -Non-standard.\n\ -"; - -static PyObject * -_mysql_ConnectionObject_set_character_set( - _mysql_ConnectionObject *self, - PyObject *args) -{ - const char *s; - int err; - if (!PyArg_ParseTuple(args, "s", &s)) return NULL; - check_connection(self); - Py_BEGIN_ALLOW_THREADS - err = mysql_set_character_set(&(self->connection), s); - Py_END_ALLOW_THREADS - if (err) return _mysql_Exception(self); - Py_INCREF(Py_None); - return Py_None; -} -#endif - -#if MYSQL_VERSION_ID >= 50010 -static char _mysql_ConnectionObject_get_character_set_info__doc__[] = -"Returns a dict with information about the current character set:\n\ -\n\ -collation\n\ - collation name\n\ -name\n\ - character set name\n\ -comment\n\ - comment or descriptive name\n\ -dir\n\ - character set directory\n\ -mbminlen\n\ - min. length for multibyte string\n\ -mbmaxlen\n\ - max. length for multibyte string\n\ -\n\ -Not all keys may be present, particularly dir.\n\ -\n\ -Non-standard.\n\ -"; - -static PyObject * -_mysql_ConnectionObject_get_character_set_info( - _mysql_ConnectionObject *self, - PyObject *unused) -{ - PyObject *result; - MY_CHARSET_INFO cs; - - check_connection(self); - mysql_get_character_set_info(&(self->connection), &cs); - if (!(result = PyDict_New())) return NULL; - if (cs.csname) - PyDict_SetItemString(result, "name", PyString_FromString(cs.csname)); - if (cs.name) - PyDict_SetItemString(result, "collation", PyString_FromString(cs.name)); - if (cs.comment) - PyDict_SetItemString(result, "comment", PyString_FromString(cs.comment)); - if (cs.dir) - PyDict_SetItemString(result, "dir", PyString_FromString(cs.dir)); - PyDict_SetItemString(result, "mbminlen", PyInt_FromLong(cs.mbminlen)); - PyDict_SetItemString(result, "mbmaxlen", PyInt_FromLong(cs.mbmaxlen)); - return result; -} -#endif - -static char _mysql_ConnectionObject_get_host_info__doc__[] = -"Returns a string that represents the MySQL client library\n\ -version. Non-standard.\n\ -"; - -static PyObject * -_mysql_ConnectionObject_get_host_info( - _mysql_ConnectionObject *self, - PyObject *unused) -{ - check_connection(self); - return PyString_FromString(mysql_get_host_info(&(self->connection))); -} - -static char _mysql_ConnectionObject_get_proto_info__doc__[] = -"Returns an unsigned integer representing the protocol version\n\ -used by the current connection. Non-standard.\n\ -"; - -static PyObject * -_mysql_ConnectionObject_get_proto_info( - _mysql_ConnectionObject *self, - PyObject *unused) -{ - check_connection(self); - return PyInt_FromLong((long)mysql_get_proto_info(&(self->connection))); -} - -static char _mysql_ConnectionObject_get_server_info__doc__[] = -"Returns a string that represents the server version number.\n\ -Non-standard.\n\ -"; - -static PyObject * -_mysql_ConnectionObject_get_server_info( - _mysql_ConnectionObject *self, - PyObject *unused) -{ - check_connection(self); - return PyString_FromString(mysql_get_server_info(&(self->connection))); -} - -static char _mysql_ConnectionObject_info__doc__[] = -"Retrieves a string providing information about the most\n\ -recently executed query. Non-standard. Use messages or\n\ -Cursor.messages.\n\ -"; - -static PyObject * -_mysql_ConnectionObject_info( - _mysql_ConnectionObject *self, - PyObject *unused) -{ - const char *s; - - check_connection(self); - s = mysql_info(&(self->connection)); - if (s) return PyString_FromString(s); - Py_INCREF(Py_None); - return Py_None; -} - -static char _mysql_ConnectionObject_insert_id__doc__[] = -"Returns the ID generated for an AUTO_INCREMENT column by the previous\n\ -query. Use this function after you have performed an INSERT query into a\n\ -table that contains an AUTO_INCREMENT field.\n\ -\n\ -Note that this returns 0 if the previous query does not\n\ -generate an AUTO_INCREMENT value. If you need to save the value for\n\ -later, be sure to call this immediately after the query\n\ -that generates the value.\n\ -\n\ -The ID is updated after INSERT and UPDATE statements that generate\n\ -an AUTO_INCREMENT value or that set a column value to\n\ -LAST_INSERT_ID(expr). See section 6.3.5.2 Miscellaneous Functions\n\ -in the MySQL documentation.\n\ -\n\ -Also note that the value of the SQL LAST_INSERT_ID() function always\n\ -contains the most recently generated AUTO_INCREMENT value, and is not\n\ -reset between queries because the value of that function is maintained\n\ -in the server.\n\ -" ; - -static PyObject * -_mysql_ConnectionObject_insert_id( - _mysql_ConnectionObject *self, - PyObject *unused) -{ - my_ulonglong r; - - check_connection(self); - Py_BEGIN_ALLOW_THREADS - r = mysql_insert_id(&(self->connection)); - Py_END_ALLOW_THREADS - return PyLong_FromUnsignedLongLong(r); -} - -static char _mysql_ConnectionObject_kill__doc__[] = -"Asks the server to kill the thread specified by pid.\n\ -Non-standard."; - -static PyObject * -_mysql_ConnectionObject_kill( - _mysql_ConnectionObject *self, - PyObject *args) -{ - unsigned long pid; - int r; - if (!PyArg_ParseTuple(args, "i:kill", &pid)) return NULL; - check_connection(self); - Py_BEGIN_ALLOW_THREADS - r = mysql_kill(&(self->connection), pid); - Py_END_ALLOW_THREADS - if (r) return _mysql_Exception(self); - Py_INCREF(Py_None); - return Py_None; -} - -static char _mysql_ConnectionObject_field_count__doc__[] = -"Returns the number of columns for the most recent query on the\n\ -connection. Non-standard. Will probably give you bogus results\n\ -on most cursor classes. Use Cursor.rowcount.\n\ -"; - -static PyObject * -_mysql_ConnectionObject_field_count( - _mysql_ConnectionObject *self, - PyObject *unused) -{ - check_connection(self); -#if MYSQL_VERSION_ID < 32224 - return PyInt_FromLong((long)mysql_num_fields(&(self->connection))); -#else - return PyInt_FromLong((long)mysql_field_count(&(self->connection))); -#endif -} - -static char _mysql_ConnectionObject_ping__doc__[] = -"Checks whether or not the connection to the server is\n\ -working. If it has gone down, an automatic reconnection is\n\ -attempted.\n\ -\n\ -This function can be used by clients that remain idle for a\n\ -long while, to check whether or not the server has closed the\n\ -connection and reconnect if necessary.\n\ -\n\ -New in 1.2.2: Accepts an optional reconnect parameter. If True,\n\ -then the client will attempt reconnection. Note that this setting\n\ -is persistent. By default, this is on in MySQL<5.0.3, and off\n\ -thereafter.\n\ -\n\ -Non-standard. You should assume that ping() performs an\n\ -implicit rollback; use only when starting a new transaction.\n\ -You have been warned.\n\ -"; - -static PyObject * -_mysql_ConnectionObject_ping( - _mysql_ConnectionObject *self, - PyObject *args) -{ - int r, reconnect = -1; - if (!PyArg_ParseTuple(args, "|I", &reconnect)) return NULL; - check_connection(self); - if ( reconnect != -1 ) self->connection.reconnect = reconnect; - Py_BEGIN_ALLOW_THREADS - r = mysql_ping(&(self->connection)); - Py_END_ALLOW_THREADS - if (r) return _mysql_Exception(self); - Py_INCREF(Py_None); - return Py_None; -} - -static char _mysql_ConnectionObject_query__doc__[] = -"Execute a query. store_result() or use_result() will get the\n\ -result set, if any. Non-standard. Use cursor() to create a cursor,\n\ -then cursor.execute().\n\ -" ; - -static PyObject * -_mysql_ConnectionObject_query( - _mysql_ConnectionObject *self, - PyObject *args) -{ - char *query; - int len, r; - if (!PyArg_ParseTuple(args, "s#:query", &query, &len)) return NULL; - check_connection(self); - Py_BEGIN_ALLOW_THREADS - r = mysql_real_query(&(self->connection), query, len); - Py_END_ALLOW_THREADS - if (r) return _mysql_Exception(self); - Py_INCREF(Py_None); - return Py_None; -} - - -static char _mysql_ConnectionObject_select_db__doc__[] = -"Causes the database specified by db to become the default\n\ -(current) database on the connection specified by mysql. In subsequent\n\ -queries, this database is the default for table references that do not\n\ -include an explicit database specifier.\n\ -\n\ -Fails unless the connected user can be authenticated as having\n\ -permission to use the database.\n\ -\n\ -Non-standard.\n\ -"; - -static PyObject * -_mysql_ConnectionObject_select_db( - _mysql_ConnectionObject *self, - PyObject *args) -{ - char *db; - int r; - if (!PyArg_ParseTuple(args, "s:select_db", &db)) return NULL; - check_connection(self); - Py_BEGIN_ALLOW_THREADS - r = mysql_select_db(&(self->connection), db); - Py_END_ALLOW_THREADS - if (r) return _mysql_Exception(self); - Py_INCREF(Py_None); - return Py_None; -} - -static char _mysql_ConnectionObject_shutdown__doc__[] = -"Asks the database server to shut down. The connected user must\n\ -have shutdown privileges. Non-standard.\n\ -"; - -static PyObject * -_mysql_ConnectionObject_shutdown( - _mysql_ConnectionObject *self, - PyObject *unused) -{ - int r; - - check_connection(self); - Py_BEGIN_ALLOW_THREADS - r = mysql_shutdown(&(self->connection) -#if MYSQL_VERSION_ID >= 40103 - , SHUTDOWN_DEFAULT -#endif - ); - Py_END_ALLOW_THREADS - if (r) return _mysql_Exception(self); - Py_INCREF(Py_None); - return Py_None; -} - -static char _mysql_ConnectionObject_stat__doc__[] = -"Returns a character string containing information similar to\n\ -that provided by the mysqladmin status command. This includes\n\ -uptime in seconds and the number of running threads,\n\ -questions, reloads, and open tables. Non-standard.\n\ -"; - -static PyObject * -_mysql_ConnectionObject_stat( - _mysql_ConnectionObject *self, - PyObject *unused) -{ - const char *s; - - check_connection(self); - Py_BEGIN_ALLOW_THREADS - s = mysql_stat(&(self->connection)); - Py_END_ALLOW_THREADS - if (!s) return _mysql_Exception(self); - return PyString_FromString(s); -} - -static char _mysql_ConnectionObject_store_result__doc__[] = -"Returns a result object acquired by mysql_store_result\n\ -(results stored in the client). If no results are available,\n\ -None is returned. Non-standard.\n\ -"; - -static PyObject * -_mysql_ConnectionObject_store_result( - _mysql_ConnectionObject *self, - PyObject *unused) -{ - PyObject *arglist=NULL, *kwarglist=NULL, *result=NULL; - _mysql_ResultObject *r=NULL; - - check_connection(self); - arglist = Py_BuildValue("(OiO)", self, 0, self->converter); - if (!arglist) goto error; - kwarglist = PyDict_New(); - if (!kwarglist) goto error; - r = MyAlloc(_mysql_ResultObject, _mysql_ResultObject_Type); - if (!r) goto error; - if (_mysql_ResultObject_Initialize(r, arglist, kwarglist)) - goto error; - result = (PyObject *) r; - if (!(r->result)) { - Py_DECREF(result); - Py_INCREF(Py_None); - result = Py_None; - } - error: - Py_XDECREF(arglist); - Py_XDECREF(kwarglist); - return result; -} - -static char _mysql_ConnectionObject_thread_id__doc__[] = -"Returns the thread ID of the current connection. This value\n\ -can be used as an argument to kill() to kill the thread.\n\ -\n\ -If the connection is lost and you reconnect with ping(), the\n\ -thread ID will change. This means you should not get the\n\ -thread ID and store it for later. You should get it when you\n\ -need it.\n\ -\n\ -Non-standard."; - -static PyObject * -_mysql_ConnectionObject_thread_id( - _mysql_ConnectionObject *self, - PyObject *unused) -{ - unsigned long pid; - - check_connection(self); - Py_BEGIN_ALLOW_THREADS - pid = mysql_thread_id(&(self->connection)); - Py_END_ALLOW_THREADS - return PyInt_FromLong((long)pid); -} - -static char _mysql_ConnectionObject_use_result__doc__[] = -"Returns a result object acquired by mysql_use_result\n\ -(results stored in the server). If no results are available,\n\ -None is returned. Non-standard.\n\ -"; - -static PyObject * -_mysql_ConnectionObject_use_result( - _mysql_ConnectionObject *self, - PyObject *unused) -{ - PyObject *arglist=NULL, *kwarglist=NULL, *result=NULL; - _mysql_ResultObject *r=NULL; - - check_connection(self); - arglist = Py_BuildValue("(OiO)", self, 1, self->converter); - if (!arglist) return NULL; - kwarglist = PyDict_New(); - if (!kwarglist) goto error; - r = MyAlloc(_mysql_ResultObject, _mysql_ResultObject_Type); - if (!r) goto error; - result = (PyObject *) r; - if (_mysql_ResultObject_Initialize(r, arglist, kwarglist)) - goto error; - if (!(r->result)) { - Py_DECREF(result); - Py_INCREF(Py_None); - result = Py_None; - } - error: - Py_DECREF(arglist); - Py_XDECREF(kwarglist); - return result; -} - -static void -_mysql_ConnectionObject_dealloc( - _mysql_ConnectionObject *self) -{ - PyObject *o; - - PyObject_GC_UnTrack(self); - if (self->open) { - o = _mysql_ConnectionObject_close(self, NULL); - Py_XDECREF(o); - } - MyFree(self); -} - -static PyObject * -_mysql_ConnectionObject_repr( - _mysql_ConnectionObject *self) -{ - char buf[300]; - if (self->open) - sprintf(buf, "<_mysql.connection open to '%.256s' at %lx>", - self->connection.host, - (long)self); - else - sprintf(buf, "<_mysql.connection closed at %lx>", - (long)self); - return PyString_FromString(buf); -} - -static PyMethodDef _mysql_ConnectionObject_methods[] = { - { - "affected_rows", - (PyCFunction)_mysql_ConnectionObject_affected_rows, - METH_NOARGS, - _mysql_ConnectionObject_affected_rows__doc__ - }, - { - "autocommit", - (PyCFunction)_mysql_ConnectionObject_autocommit, - METH_VARARGS, - _mysql_ConnectionObject_autocommit__doc__ - }, - { - "commit", - (PyCFunction)_mysql_ConnectionObject_commit, - METH_NOARGS, - _mysql_ConnectionObject_commit__doc__ - }, - { - "rollback", - (PyCFunction)_mysql_ConnectionObject_rollback, - METH_NOARGS, - _mysql_ConnectionObject_rollback__doc__ - }, - { - "next_result", - (PyCFunction)_mysql_ConnectionObject_next_result, - METH_NOARGS, - _mysql_ConnectionObject_next_result__doc__ - }, -#if MYSQL_VERSION_ID >= 40100 - { - "set_server_option", - (PyCFunction)_mysql_ConnectionObject_set_server_option, - METH_VARARGS, - _mysql_ConnectionObject_set_server_option__doc__ - }, - { - "sqlstate", - (PyCFunction)_mysql_ConnectionObject_sqlstate, - METH_NOARGS, - _mysql_ConnectionObject_sqlstate__doc__ - }, - { - "warning_count", - (PyCFunction)_mysql_ConnectionObject_warning_count, - METH_NOARGS, - _mysql_ConnectionObject_warning_count__doc__ - }, -#endif -#if MYSQL_VERSION_ID >= 32303 - { - "change_user", - (PyCFunction)_mysql_ConnectionObject_change_user, - METH_VARARGS | METH_KEYWORDS, - _mysql_ConnectionObject_change_user__doc__ - }, -#endif - { - "character_set_name", - (PyCFunction)_mysql_ConnectionObject_character_set_name, - METH_NOARGS, - _mysql_ConnectionObject_character_set_name__doc__ - }, -#if MYSQL_VERSION_ID >= 50007 - { - "set_character_set", - (PyCFunction)_mysql_ConnectionObject_set_character_set, - METH_VARARGS, - _mysql_ConnectionObject_set_character_set__doc__ - }, -#endif -#if MYSQL_VERSION_ID >= 50010 - { - "get_character_set_info", - (PyCFunction)_mysql_ConnectionObject_get_character_set_info, - METH_VARARGS, - _mysql_ConnectionObject_get_character_set_info__doc__ - }, -#endif - { - "close", - (PyCFunction)_mysql_ConnectionObject_close, - METH_NOARGS, - _mysql_ConnectionObject_close__doc__ - }, - { - "dump_debug_info", - (PyCFunction)_mysql_ConnectionObject_dump_debug_info, - METH_NOARGS, - _mysql_ConnectionObject_dump_debug_info__doc__ - }, - { - "escape", - (PyCFunction)_mysql_escape, - METH_VARARGS, - _mysql_escape__doc__ - }, - { - "escape_string", - (PyCFunction)_mysql_escape_string, - METH_VARARGS, - _mysql_escape_string__doc__ - }, - { - "error", - (PyCFunction)_mysql_ConnectionObject_error, - METH_NOARGS, - _mysql_ConnectionObject_error__doc__ - }, - { - "errno", - (PyCFunction)_mysql_ConnectionObject_errno, - METH_NOARGS, - _mysql_ConnectionObject_errno__doc__ - }, - { - "field_count", - (PyCFunction)_mysql_ConnectionObject_field_count, - METH_NOARGS, - _mysql_ConnectionObject_field_count__doc__ - }, - { - "get_host_info", - (PyCFunction)_mysql_ConnectionObject_get_host_info, - METH_NOARGS, - _mysql_ConnectionObject_get_host_info__doc__ - }, - { - "get_proto_info", - (PyCFunction)_mysql_ConnectionObject_get_proto_info, - METH_NOARGS, - _mysql_ConnectionObject_get_proto_info__doc__ - }, - { - "get_server_info", - (PyCFunction)_mysql_ConnectionObject_get_server_info, - METH_NOARGS, - _mysql_ConnectionObject_get_server_info__doc__ - }, - { - "info", - (PyCFunction)_mysql_ConnectionObject_info, - METH_NOARGS, - _mysql_ConnectionObject_info__doc__ - }, - { - "insert_id", - (PyCFunction)_mysql_ConnectionObject_insert_id, - METH_NOARGS, - _mysql_ConnectionObject_insert_id__doc__ - }, - { - "kill", - (PyCFunction)_mysql_ConnectionObject_kill, - METH_VARARGS, - _mysql_ConnectionObject_kill__doc__ - }, - { - "ping", - (PyCFunction)_mysql_ConnectionObject_ping, - METH_VARARGS, - _mysql_ConnectionObject_ping__doc__ - }, - { - "query", - (PyCFunction)_mysql_ConnectionObject_query, - METH_VARARGS, - _mysql_ConnectionObject_query__doc__ - }, - { - "select_db", - (PyCFunction)_mysql_ConnectionObject_select_db, - METH_VARARGS, - _mysql_ConnectionObject_select_db__doc__ - }, - { - "shutdown", - (PyCFunction)_mysql_ConnectionObject_shutdown, - METH_NOARGS, - _mysql_ConnectionObject_shutdown__doc__ - }, - { - "stat", - (PyCFunction)_mysql_ConnectionObject_stat, - METH_NOARGS, - _mysql_ConnectionObject_stat__doc__ - }, - { - "store_result", - (PyCFunction)_mysql_ConnectionObject_store_result, - METH_NOARGS, - _mysql_ConnectionObject_store_result__doc__ - }, - { - "string_literal", - (PyCFunction)_mysql_string_literal, - METH_VARARGS, - _mysql_string_literal__doc__}, - { - "thread_id", - (PyCFunction)_mysql_ConnectionObject_thread_id, - METH_NOARGS, - _mysql_ConnectionObject_thread_id__doc__ - }, - { - "use_result", - (PyCFunction)_mysql_ConnectionObject_use_result, - METH_NOARGS, - _mysql_ConnectionObject_use_result__doc__ - }, - {NULL, NULL} /* sentinel */ -}; - -static struct PyMemberDef _mysql_ConnectionObject_memberlist[] = { - { - "open", - T_INT, - offsetof(_mysql_ConnectionObject, open), - RO, - "True if connection is open" - }, - { - "converter", - T_OBJECT, - offsetof(_mysql_ConnectionObject, converter), - 0, - "Type conversion mapping" - }, - { - "server_capabilities", - T_UINT, - offsetof(_mysql_ConnectionObject, connection.server_capabilities), - RO, - "Capabilites of server; consult MySQLdb.constants.CLIENT" - }, - { - "port", - T_UINT, - offsetof(_mysql_ConnectionObject, connection.port), - RO, - "TCP/IP port of the server connection" - }, - { - "client_flag", - T_UINT, - RO, - offsetof(_mysql_ConnectionObject, connection.client_flag), - "Client flags; refer to MySQLdb.constants.CLIENT" - }, - {NULL} /* Sentinel */ -}; - -static PyObject * -_mysql_ConnectionObject_getattr( - _mysql_ConnectionObject *self, - char *name) -{ - PyObject *res; - struct PyMemberDef *l; - - res = Py_FindMethod(_mysql_ConnectionObject_methods, (PyObject *)self, name); - if (res != NULL) - return res; - PyErr_Clear(); - if (strcmp(name, "closed") == 0) - return PyInt_FromLong((long)!(self->open)); - - for (l = _mysql_ConnectionObject_memberlist; l->name != NULL; l++) { - if (strcmp(l->name, name) == 0) - return PyMember_GetOne((char *)self, l); - } - - PyErr_SetString(PyExc_AttributeError, name); - return NULL; -} - -static int -_mysql_ConnectionObject_setattr( - _mysql_ConnectionObject *self, - char *name, - PyObject *v) -{ - struct PyMemberDef *l; - - if (v == NULL) { - PyErr_SetString(PyExc_AttributeError, - "can't delete connection attributes"); - return -1; - } - - for (l = _mysql_ConnectionObject_memberlist; l->name != NULL; l++) - if (strcmp(l->name, name) == 0) - return PyMember_SetOne((char *)self, l, v); - - PyErr_SetString(PyExc_AttributeError, name); - return -1; -} - -PyTypeObject _mysql_ConnectionObject_Type = { - PyObject_HEAD_INIT(NULL) - 0, - "_mysql.connection", /* (char *)tp_name For printing */ - sizeof(_mysql_ConnectionObject), /* tp_basicsize */ - 0, - (destructor)_mysql_ConnectionObject_dealloc, /* tp_dealloc */ - 0, /*tp_print*/ - (getattrfunc)_mysql_ConnectionObject_getattr, /* tp_getattr */ - (setattrfunc)_mysql_ConnectionObject_setattr, /* tp_setattr */ - 0, /*tp_compare*/ - (reprfunc)_mysql_ConnectionObject_repr, /* 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, /* (getattrofunc) tp_getattro */ - 0, /* (setattrofunc) tp_setattro */ - - /* Functions to access object as input/output buffer */ - 0, /* (PyBufferProcs *) tp_as_buffer */ - - /* Flags to define presence of optional/expanded features */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, - - _mysql_connect__doc__, /* (char *) tp_doc Documentation string */ - - /* call function for all accessible objects */ - (traverseproc)_mysql_ConnectionObject_traverse, /* tp_traverse */ - - /* delete references to contained objects */ - (inquiry)_mysql_ConnectionObject_clear, /* 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 *)_mysql_ConnectionObject_methods, /* tp_methods */ - (struct PyMemberDef *)_mysql_ConnectionObject_memberlist, /* tp_members */ - 0, /* (struct getsetlist *) tp_getset; */ - 0, /* (struct _typeobject *) tp_base; */ - 0, /* (PyObject *) tp_dict */ - 0, /* (descrgetfunc) tp_descr_get */ - 0, /* (descrsetfunc) tp_descr_set */ - 0, /* (long) tp_dictoffset */ - (initproc)_mysql_ConnectionObject_Initialize, /* tp_init */ - NULL, /* tp_alloc */ - 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 */ -};
--- a/_mysql_fields.c Mon Feb 23 23:52:44 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,295 +0,0 @@ -/* -*- mode: C; indent-tabs-mode: t; c-basic-offset: 8; -*- */ - -#include "_mysql.h" - -static char _mysql_FieldObject__doc__[] = -""; - -int -_mysql_FieldObject_Initialize( - _mysql_FieldObject *self, - PyObject *args, - PyObject *kwargs) -{ - static char *kwlist[] = {"result", "index", NULL}; - _mysql_ResultObject *result=NULL; - MYSQL_FIELD *field; - unsigned int index; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Oi", kwlist, - &result, &index)) - return -1; - - self->index = index; - field = mysql_fetch_field_direct(result->result, index); - if (!field) return -1; - self->field = *field; - self->result = (PyObject *) result; - Py_INCREF(result); - return 0; -} - -static int -_mysql_FieldObject_traverse( - _mysql_FieldObject *self, - visitproc visit, - void *arg) -{ - if (self->result) - return visit(self->result, arg); - return 0; -} - -static int -_mysql_FieldObject_clear( - _mysql_FieldObject *self) -{ - Py_XDECREF(self->result); - self->result = NULL; - return 0; -} - -static void -_mysql_FieldObject_dealloc( - _mysql_FieldObject *self) -{ - PyObject_GC_UnTrack((PyObject *)self); - _mysql_FieldObject_clear(self); - MyFree(self); -} - -static PyObject * -_mysql_FieldObject_repr( - _mysql_FieldObject *self) -{ - char buf[300]; - snprintf(buf, 300, "<_mysql.field object at %lx>", (long)self); - return PyString_FromString(buf); -} - -static PyMethodDef _mysql_FieldObject_methods[] = { - {NULL, NULL} /* sentinel */ -}; - -static struct PyMemberDef _mysql_FieldObject_memberlist[] = { - { - "result", - T_OBJECT, - offsetof(_mysql_FieldObject, result), - RO, - "Result set" - }, - { - "name", - T_STRING, - offsetof(_mysql_FieldObject, field.name), - RO, - "The name of the field. If the field was given\n\ -an alias with an AS clause, the value of name is the alias." - }, - { - "org_name", - T_STRING, - offsetof(_mysql_FieldObject, field.org_name), - RO, - "The name of the field. Aliases are ignored." - }, - { - "table", - T_STRING, - offsetof(_mysql_FieldObject, field.table), - RO, - "The name of the table containing this field,\n\ -if it isn't a calculated field. For calculated fields,\n\ -the table value is an empty string. If the column is selected from a view,\n\ -table names the view. If the table or view was given an alias with an AS clause,\n\ -the value of table is the alias.\n" - }, - { - "org_table", - T_STRING, - offsetof(_mysql_FieldObject, field.org_table), - RO, - "The name of the table. Aliases are ignored.\n\ -If the column is selected from a view, org_table names the underlying table.\n" - }, - { - "db", - T_STRING, - offsetof(_mysql_FieldObject, field.db), - RO, - "The name of the database that the field comes from.\n\ -If the field is a calculated field, db is an empty string." - }, - { - "catalog", - T_STRING, - offsetof(_mysql_FieldObject, field.catalog), - RO, - "The catalog name. This value is always \"def\"." - }, - { - "length", - T_ULONG, - offsetof(_mysql_FieldObject, field.length), - RO, - "The width of the field.\n\ -as specified in the table definition.\n" - }, - { - "max_length", - T_ULONG, - offsetof(_mysql_FieldObject, field.max_length), - RO, - "The maximum width of the field for the result set\n\ -(the length of the longest field value for the rows actually in the\n\ -result set). If you use conn.store_result(), this contains the\n\ -maximum length for the field. If you use conn.use_result(),\n\ -the value of this variable is zero.\n" - }, - { - "decimals", - T_UINT, - offsetof(_mysql_FieldObject, field.decimals), - RO, - "The number of decimals for numeric fields.\n" - }, - { - "charsetnr", - T_UINT, - offsetof(_mysql_FieldObject, field.charsetnr), - RO, - "The character set number for the field." - }, - { - "flags", - T_UINT, - offsetof(_mysql_FieldObject, field.flags), - RO, - "Different bit-flags for the field.\n\ -The bits are enumerated in MySQLdb.constants.FLAG.\n\ -The flags value may have zero or more of these bits set.\n" - }, - { - "type", - T_UINT, - offsetof(_mysql_FieldObject, field.type), - RO, - "The type of the field. The type values\n\ -are enumerated in MySQLdb.constants.FIELD_TYPE.\n" - }, - {NULL} /* Sentinel */ -}; - -static PyObject * -_mysql_FieldObject_getattr( - _mysql_FieldObject *self, - char *name) -{ - PyObject *res; - struct PyMemberDef *l; - - res = Py_FindMethod(_mysql_FieldObject_methods, (PyObject *)self, name); - if (res != NULL) - return res; - PyErr_Clear(); - - for (l = _mysql_FieldObject_memberlist; l->name != NULL; l++) { - if (strcmp(l->name, name) == 0) - return PyMember_GetOne((char *)self, l); - } - - PyErr_SetString(PyExc_AttributeError, name); - return NULL; -} - -static int -_mysql_FieldObject_setattr( - _mysql_FieldObject *self, - char *name, - PyObject *v) -{ - struct PyMemberDef *l; - - if (v == NULL) { - PyErr_SetString(PyExc_AttributeError, - "can't delete attributes"); - return -1; - } - - - for (l = _mysql_FieldObject_memberlist; l->name != NULL; l++) - if (strcmp(l->name, name) == 0) - return PyMember_SetOne((char *)self, l, v); - - PyErr_SetString(PyExc_AttributeError, name); - return -1; -} - -PyTypeObject _mysql_FieldObject_Type = { - PyObject_HEAD_INIT(NULL) - 0, - "_mysql.field", - sizeof(_mysql_FieldObject), - 0, - (destructor)_mysql_FieldObject_dealloc, /* tp_dealloc */ - 0, /*tp_print*/ - (getattrfunc)_mysql_FieldObject_getattr, /* tp_getattr */ - (setattrfunc)_mysql_FieldObject_setattr, /* tp_setattr */ - 0, /*tp_compare*/ - (reprfunc)_mysql_FieldObject_repr, /* 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, /* (getattrofunc) tp_getattro */ - 0, /* (setattrofunc) tp_setattro */ - - /* Functions to access object as input/output buffer */ - 0, /* (PyBufferProcs *) tp_as_buffer */ - - /* Flags to define presence of optional/expanded features */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, - - _mysql_FieldObject__doc__, /* (char *) tp_doc Documentation string */ - - /* call function for all accessible objects */ - (traverseproc)_mysql_FieldObject_traverse, /* tp_traverse */ - - /* delete references to contained objects */ - (inquiry)_mysql_FieldObject_clear, /* 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 *)_mysql_FieldObject_methods, /* tp_methods */ - (struct PyMemberDef *)_mysql_FieldObject_memberlist, /*tp_members */ - 0, /* (struct getsetlist *) tp_getset; */ - 0, /* (struct _typeobject *) tp_base; */ - 0, /* (PyObject *) tp_dict */ - 0, /* (descrgetfunc) tp_descr_get */ - 0, /* (descrsetfunc) tp_descr_set */ - 0, /* (long) tp_dictoffset */ - (initproc)_mysql_FieldObject_Initialize, /* tp_init */ - NULL, /* tp_alloc */ - 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 */ -};
--- a/_mysql_results.c Mon Feb 23 23:52:44 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,750 +0,0 @@ -/* -*- mode: C; indent-tabs-mode: t; c-basic-offset: 8; -*- */ - -#include "_mysql.h" - -static char _mysql_ResultObject__doc__[] = -"result(connection, use=0, converter={}) -- Result set from a query.\n\ -\n\ -Creating instances of this class directly is an excellent way to\n\ -shoot yourself in the foot. If using _mysql.connection directly,\n\ -use connection.store_result() or connection.use_result() instead.\n\ -If using MySQLdb.Connection, this is done by the cursor class.\n\ -Just forget you ever saw this. Forget... FOR-GET..."; - -int -_mysql_ResultObject_Initialize( - _mysql_ResultObject *self, - PyObject *args, - PyObject *kwargs) -{ - static char *kwlist[] = {"connection", "use", "converter", NULL}; - MYSQL_RES *result; - _mysql_ConnectionObject *conn=NULL; - int use=0; - PyObject *conv=NULL; - int n, i; - MYSQL_FIELD *fields; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|iO", kwlist, - &conn, &use, &conv)) - return -1; - if (!conv) conv = PyDict_New(); - if (!conv) return -1; - self->conn = (PyObject *) conn; - Py_INCREF(conn); - self->use = use; - Py_BEGIN_ALLOW_THREADS ; - if (use) - result = mysql_use_result(&(conn->connection)); - else - result = mysql_store_result(&(conn->connection)); - self->result = result; - Py_END_ALLOW_THREADS ; - if (!result) { - self->converter = PyTuple_New(0); - return 0; - } - n = mysql_num_fields(result); - self->nfields = n; - if (!(self->converter = PyTuple_New(n))) return -1; - fields = mysql_fetch_fields(result); - for (i=0; i<n; i++) { - PyObject *tmp, *fun; - tmp = PyInt_FromLong((long) fields[i].type); - if (!tmp) return -1; - fun = PyObject_GetItem(conv, tmp); - Py_DECREF(tmp); - if (!fun) { - PyErr_Clear(); - fun = Py_None; - Py_INCREF(Py_None); - } - if (PySequence_Check(fun)) { - int j, n2=PySequence_Size(fun); - PyObject *fun2=NULL; - for (j=0; j<n2; j++) { - PyObject *t = PySequence_GetItem(fun, j); - if (!t) continue; - if (!PyTuple_Check(t)) goto cleanup; - if (PyTuple_GET_SIZE(t) == 2) { - long mask; - PyObject *pmask=NULL; - pmask = PyTuple_GET_ITEM(t, 0); - fun2 = PyTuple_GET_ITEM(t, 1); - if (PyInt_Check(pmask)) { - mask = PyInt_AS_LONG(pmask); - if (mask & fields[i].flags) { - Py_DECREF(t); - break; - } - else { - goto cleanup; - } - } else { - Py_DECREF(t); - break; - } - } - cleanup: - Py_DECREF(t); - } - if (!fun2) fun2 = Py_None; - Py_INCREF(fun2); - Py_DECREF(fun); - fun = fun2; - } - PyTuple_SET_ITEM(self->converter, i, fun); - } - return 0; -} - -static int -_mysql_ResultObject_traverse( - _mysql_ResultObject *self, - visitproc visit, - void *arg) -{ - int r; - if (self->converter) { - if (!(r = visit(self->converter, arg))) return r; - } - if (self->conn) - return visit(self->conn, arg); - return 0; -} - -static int -_mysql_ResultObject_clear( - _mysql_ResultObject *self) -{ - Py_XDECREF(self->converter); - self->converter = NULL; - Py_XDECREF(self->conn); - self->conn = NULL; - return 0; -} - -static char _mysql_ResultObject_describe__doc__[] = -"Returns the sequence of 7-tuples required by the DB-API for\n\ -the Cursor.description attribute.\n\ -"; - -static PyObject * -_mysql_ResultObject_describe( - _mysql_ResultObject *self, - PyObject *unused) -{ - PyObject *d; - MYSQL_FIELD *fields; - unsigned int i, n; - - check_result_connection(self); - n = mysql_num_fields(self->result); - fields = mysql_fetch_fields(self->result); - if (!(d = PyTuple_New(n))) return NULL; - for (i=0; i<n; i++) { - PyObject *t; - t = Py_BuildValue("(siiiiii)", - fields[i].name, - (long) fields[i].type, - (long) fields[i].max_length, - (long) fields[i].length, - (long) fields[i].length, - (long) fields[i].decimals, - (long) !(IS_NOT_NULL(fields[i].flags))); - if (!t) goto error; - PyTuple_SET_ITEM(d, i, t); - } - return d; - error: - Py_XDECREF(d); - return NULL; -} - -static char _mysql_ResultObject_fields__doc__[] = -"Returns the sequence of 7-tuples required by the DB-API for\n\ -the Cursor.description attribute.\n\ -"; - -static PyObject * -_mysql_ResultObject_fields( - _mysql_ResultObject *self, - PyObject *unused) -{ - PyObject *arglist=NULL, *kwarglist=NULL; - PyObject *fields=NULL; - _mysql_FieldObject *field=NULL; - unsigned int i, n; - - check_result_connection(self); - kwarglist = PyDict_New(); - if (!kwarglist) goto error; - n = mysql_num_fields(self->result); - if (!(fields = PyTuple_New(n))) return NULL; - for (i=0; i<n; i++) { - arglist = Py_BuildValue("(Oi)", self, i); - if (!arglist) goto error; - field = MyAlloc(_mysql_FieldObject, _mysql_FieldObject_Type); - if (!field) goto error; - if (_mysql_FieldObject_Initialize(field, arglist, kwarglist)) - goto error; - Py_DECREF(arglist); - PyTuple_SET_ITEM(fields, i, (PyObject *) field); - } - Py_DECREF(kwarglist); - return fields; - error: - Py_XDECREF(arglist); - Py_XDECREF(kwarglist); - Py_XDECREF(fields); - return NULL; -} - -static char _mysql_ResultObject_field_flags__doc__[] = -"Returns a tuple of field flags, one for each column in the result.\n\ -" ; - -static PyObject * -_mysql_ResultObject_field_flags( - _mysql_ResultObject *self, - PyObject *unused) -{ - PyObject *d; - MYSQL_FIELD *fields; - unsigned int i, n; - - check_result_connection(self); - n = mysql_num_fields(self->result); - fields = mysql_fetch_fields(self->result); - if (!(d = PyTuple_New(n))) return NULL; - for (i=0; i<n; i++) { - PyObject *f; - if (!(f = PyInt_FromLong((long)fields[i].flags))) goto error; - PyTuple_SET_ITEM(d, i, f); - } - return d; - error: - Py_XDECREF(d); - return NULL; -} - -static PyObject * -_mysql_field_to_python( - PyObject *converter, - char *rowitem, - unsigned long length) -{ - PyObject *v; - if (rowitem) { - if (converter != Py_None) - v = PyObject_CallFunction(converter, - "s#", - rowitem, - (int)length); - else - v = PyString_FromStringAndSize(rowitem, - (int)length); - if (!v) - return NULL; - } else { - Py_INCREF(Py_None); - v = Py_None; - } - return v; -} - -static PyObject * -_mysql_row_to_tuple( - _mysql_ResultObject *self, - MYSQL_ROW row) -{ - unsigned int n, i; - unsigned long *length; - PyObject *r, *c; - - n = mysql_num_fields(self->result); - if (!(r = PyTuple_New(n))) return NULL; - length = mysql_fetch_lengths(self->result); - for (i=0; i<n; i++) { - PyObject *v; - c = PyTuple_GET_ITEM(self->converter, i); - v = _mysql_field_to_python(c, row[i], length[i]); - if (!v) goto error; - PyTuple_SET_ITEM(r, i, v); - } - return r; - error: - Py_XDECREF(r); - return NULL; -} - -static PyObject * -_mysql_row_to_dict( - _mysql_ResultObject *self, - MYSQL_ROW row) -{ - unsigned int n, i; - unsigned long *length; - PyObject *r, *c; - MYSQL_FIELD *fields; - - n = mysql_num_fields(self->result); - if (!(r = PyDict_New())) return NULL; - length = mysql_fetch_lengths(self->result); - fields = mysql_fetch_fields(self->result); - for (i=0; i<n; i++) { - PyObject *v; - c = PyTuple_GET_ITEM(self->converter, i); - v = _mysql_field_to_python(c, row[i], length[i]); - if (!v) goto error; - if (!PyMapping_HasKeyString(r, fields[i].name)) { - PyMapping_SetItemString(r, fields[i].name, v); - } else { - int len; - char buf[256]; - strncpy(buf, fields[i].table, 256); - len = strlen(buf); - strncat(buf, ".", 256-len); - len = strlen(buf); - strncat(buf, fields[i].name, 256-len); - PyMapping_SetItemString(r, buf, v); - } - Py_DECREF(v); - } - return r; - error: - Py_XDECREF(r); - return NULL; -} - -static PyObject * -_mysql_row_to_dict_old( - _mysql_ResultObject *self, - MYSQL_ROW row) -{ - unsigned int n, i; - unsigned long *length; - PyObject *r, *c; - MYSQL_FIELD *fields; - - n = mysql_num_fields(self->result); - if (!(r = PyDict_New())) return NULL; - length = mysql_fetch_lengths(self->result); - fields = mysql_fetch_fields(self->result); - for (i=0; i<n; i++) { - PyObject *v; - c = PyTuple_GET_ITEM(self->converter, i); - v = _mysql_field_to_python(c, row[i], length[i]); - if (!v) goto error; - { - int len=0; - char buf[256]=""; - if (strlen(fields[i].table)) { - strncpy(buf, fields[i].table, 256); - len = strlen(buf); - strncat(buf, ".", 256-len); - len = strlen(buf); - } - strncat(buf, fields[i].name, 256-len); - PyMapping_SetItemString(r, buf, v); - } - Py_DECREF(v); - } - return r; - error: - Py_XDECREF(r); - return NULL; -} - -typedef PyObject *_PYFUNC(_mysql_ResultObject *, MYSQL_ROW); - -int -_mysql__fetch_row( - _mysql_ResultObject *self, - PyObject **r, - int skiprows, - int maxrows, - _PYFUNC *convert_row) -{ - unsigned int i; - MYSQL_ROW row; - - for (i = skiprows; i<(skiprows+maxrows); i++) { - PyObject *v; - if (!self->use) - row = mysql_fetch_row(self->result); - else { - Py_BEGIN_ALLOW_THREADS; - row = mysql_fetch_row(self->result); - Py_END_ALLOW_THREADS; - } - if (!row && mysql_errno(&(((_mysql_ConnectionObject *)(self->conn))->connection))) { - _mysql_Exception((_mysql_ConnectionObject *)self->conn); - goto error; - } - if (!row) { - if (_PyTuple_Resize(r, i) == -1) goto error; - break; - } - v = convert_row(self, row); - if (!v) goto error; - PyTuple_SET_ITEM(*r, i, v); - } - return i-skiprows; - error: - return -1; -} - -static char _mysql_ResultObject_fetch_row__doc__[] = -"fetch_row([maxrows, how]) -- Fetches up to maxrows as a tuple.\n\ -The rows are formatted according to how:\n\ -\n\ - 0 -- tuples (default)\n\ - 1 -- dictionaries, key=column or table.column if duplicated\n\ - 2 -- dictionaries, key=table.column\n\ -"; - -static PyObject * -_mysql_ResultObject_fetch_row( - _mysql_ResultObject *self, - PyObject *args, - PyObject *kwargs) -{ - typedef PyObject *_PYFUNC(_mysql_ResultObject *, MYSQL_ROW); - static char *kwlist[] = { "maxrows", "how", NULL }; - static _PYFUNC *row_converters[] = - { - _mysql_row_to_tuple, - _mysql_row_to_dict, - _mysql_row_to_dict_old - }; - _PYFUNC *convert_row; - unsigned int maxrows=1, how=0, skiprows=0, rowsadded; - PyObject *r=NULL; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ii:fetch_row", kwlist, - &maxrows, &how)) - return NULL; - check_result_connection(self); - if (how < 0 || how >= sizeof(row_converters)) { - PyErr_SetString(PyExc_ValueError, "how out of range"); - return NULL; - } - convert_row = row_converters[how]; - if (maxrows) { - if (!(r = PyTuple_New(maxrows))) goto error; - rowsadded = _mysql__fetch_row(self, &r, skiprows, maxrows, - convert_row); - if (rowsadded == -1) goto error; - } else { - if (self->use) { - maxrows = 1000; - if (!(r = PyTuple_New(maxrows))) goto error; - while (1) { - rowsadded = _mysql__fetch_row(self, &r, skiprows, - maxrows, convert_row); - if (rowsadded == -1) goto error; - skiprows += rowsadded; - if (rowsadded < maxrows) break; - if (_PyTuple_Resize(&r, skiprows + maxrows) == -1) - goto error; - } - } else { - /* XXX if overflow, maxrows<0? */ - maxrows = (int) mysql_num_rows(self->result); - if (!(r = PyTuple_New(maxrows))) goto error; - rowsadded = _mysql__fetch_row(self, &r, 0, - maxrows, convert_row); - if (rowsadded == -1) goto error; - } - } - return r; - error: - Py_XDECREF(r); - return NULL; -} - - -static char _mysql_ResultObject_num_fields__doc__[] = -"Returns the number of fields (column) in the result." ; - -static PyObject * -_mysql_ResultObject_num_fields( - _mysql_ResultObject *self, - PyObject *unused) -{ - check_result_connection(self); - return PyInt_FromLong((long)mysql_num_fields(self->result)); -} - -static char _mysql_ResultObject_num_rows__doc__[] = -"Returns the number of rows in the result set. Note that if\n\ -use=1, this will not return a valid value until the entire result\n\ -set has been read.\n\ -"; - -static PyObject * -_mysql_ResultObject_num_rows( - _mysql_ResultObject *self, - PyObject *unused) -{ - check_result_connection(self); - return PyLong_FromUnsignedLongLong(mysql_num_rows(self->result)); -} - - -static char _mysql_ResultObject_data_seek__doc__[] = -"data_seek(n) -- seek to row n of result set"; -static PyObject * -_mysql_ResultObject_data_seek( - _mysql_ResultObject *self, - PyObject *args) -{ - unsigned int row; - if (!PyArg_ParseTuple(args, "i:data_seek", &row)) return NULL; - check_result_connection(self); - mysql_data_seek(self->result, row); - Py_INCREF(Py_None); - return Py_None; -} - -static char _mysql_ResultObject_row_seek__doc__[] = -"row_seek(n) -- seek by offset n rows of result set"; -static PyObject * -_mysql_ResultObject_row_seek( - _mysql_ResultObject *self, - PyObject *args) -{ - int offset; - MYSQL_ROW_OFFSET r; - if (!PyArg_ParseTuple(args, "i:row_seek", &offset)) return NULL; - check_result_connection(self); - if (self->use) { - PyErr_SetString(_mysql_ProgrammingError, - "cannot be used with connection.use_result()"); - return NULL; - } - r = mysql_row_tell(self->result); - mysql_row_seek(self->result, r+offset); - Py_INCREF(Py_None); - return Py_None; -} - -static char _mysql_ResultObject_row_tell__doc__[] = -"row_tell() -- return the current row number of the result set."; -static PyObject * -_mysql_ResultObject_row_tell( - _mysql_ResultObject *self, - PyObject *unused) -{ - MYSQL_ROW_OFFSET r; - - check_result_connection(self); - if (self->use) { - PyErr_SetString(_mysql_ProgrammingError, - "cannot be used with connection.use_result()"); - return NULL; - } - r = mysql_row_tell(self->result); - return PyInt_FromLong(r-self->result->data->data); -} - -static void -_mysql_ResultObject_dealloc( - _mysql_ResultObject *self) -{ - PyObject_GC_UnTrack((PyObject *)self); - mysql_free_result(self->result); - _mysql_ResultObject_clear(self); - MyFree(self); -} - -static PyObject * -_mysql_ResultObject_repr( - _mysql_ResultObject *self) -{ - char buf[300]; - sprintf(buf, "<_mysql.result object at %lx>", - (long)self); - return PyString_FromString(buf); -} - -static PyMethodDef _mysql_ResultObject_methods[] = { - { - "data_seek", - (PyCFunction)_mysql_ResultObject_data_seek, - METH_VARARGS, - _mysql_ResultObject_data_seek__doc__ - }, - { - "row_seek", - (PyCFunction)_mysql_ResultObject_row_seek, - METH_VARARGS, - _mysql_ResultObject_row_seek__doc__ - }, - { - "row_tell", - (PyCFunction)_mysql_ResultObject_row_tell, - METH_NOARGS, - _mysql_ResultObject_row_tell__doc__ - }, - { - "describe", - (PyCFunction)_mysql_ResultObject_describe, - METH_NOARGS, - _mysql_ResultObject_describe__doc__ - }, - { - "fields", - (PyCFunction)_mysql_ResultObject_fields, - METH_NOARGS, - _mysql_ResultObject_fields__doc__ - }, - { - "fetch_row", - (PyCFunction)_mysql_ResultObject_fetch_row, - METH_VARARGS | METH_KEYWORDS, - _mysql_ResultObject_fetch_row__doc__ - }, - { - "field_flags", - (PyCFunction)_mysql_ResultObject_field_flags, - METH_NOARGS, - _mysql_ResultObject_field_flags__doc__ - }, - { - "num_fields", - (PyCFunction)_mysql_ResultObject_num_fields, - METH_NOARGS, - _mysql_ResultObject_num_fields__doc__ - }, - { - "num_rows", - (PyCFunction)_mysql_ResultObject_num_rows, - METH_NOARGS, - _mysql_ResultObject_num_rows__doc__ - }, - {NULL, NULL} /* sentinel */ -}; - -static struct PyMemberDef _mysql_ResultObject_memberlist[] = { - { - "converter", - T_OBJECT, - offsetof(_mysql_ResultObject, converter), - RO, - "Type conversion mapping" - }, - {NULL} /* Sentinel */ -}; - -static PyObject * -_mysql_ResultObject_getattr( - _mysql_ResultObject *self, - char *name) -{ - PyObject *res; - struct PyMemberDef *l; - - res = Py_FindMethod(_mysql_ResultObject_methods, (PyObject *)self, name); - if (res != NULL) - return res; - PyErr_Clear(); - - for (l = _mysql_ResultObject_memberlist; l->name != NULL; l++) { - if (strcmp(l->name, name) == 0) - return PyMember_GetOne((char *)self, l); - } - - PyErr_SetString(PyExc_AttributeError, name); - return NULL; -} - -static int -_mysql_ResultObject_setattr( - _mysql_ResultObject *self, - char *name, - PyObject *v) -{ - struct PyMemberDef *l; - - if (v == NULL) { - PyErr_SetString(PyExc_AttributeError, - "can't delete connection attributes"); - return -1; - } - - for (l = _mysql_ResultObject_memberlist; l->name != NULL; l++) - if (strcmp(l->name, name) == 0) - return PyMember_SetOne((char *)self, l, v); - - PyErr_SetString(PyExc_AttributeError, name); - return -1; -} - -PyTypeObject _mysql_ResultObject_Type = { - PyObject_HEAD_INIT(NULL) - 0, - "_mysql.result", - sizeof(_mysql_ResultObject), - 0, - (destructor)_mysql_ResultObject_dealloc, /* tp_dealloc */ - 0, /*tp_print*/ - (getattrfunc)_mysql_ResultObject_getattr, /* tp_getattr */ - (setattrfunc)_mysql_ResultObject_setattr, /* tp_setattr */ - 0, /*tp_compare*/ - (reprfunc)_mysql_ResultObject_repr, /* 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, /* (getattrofunc) tp_getattro */ - 0, /* (setattrofunc) tp_setattro */ - - /* Functions to access object as input/output buffer */ - 0, /* (PyBufferProcs *) tp_as_buffer */ - - /* Flags to define presence of optional/expanded features */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, /* (long) tp_flags */ - - _mysql_ResultObject__doc__, /* (char *) tp_doc Documentation string */ - /* call function for all accessible objects */ - (traverseproc)_mysql_ResultObject_traverse, /* tp_traverse */ - /* delete references to contained objects */ - (inquiry)_mysql_ResultObject_clear, /* 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 *)_mysql_ResultObject_methods, /* tp_methods */ - (struct PyMemberDef *)_mysql_ResultObject_memberlist, /*tp_members */ - 0, /* (struct getsetlist *) tp_getset; */ - 0, /* (struct _typeobject *) tp_base; */ - 0, /* (PyObject *) tp_dict */ - 0, /* (descrgetfunc) tp_descr_get */ - 0, /* (descrsetfunc) tp_descr_set */ - 0, /* (long) tp_dictoffset */ - (initproc)_mysql_ResultObject_Initialize, /* tp_init */ - NULL, /* tp_alloc */ - 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 */ -};
--- a/setup.py Mon Feb 23 23:52:44 2009 +0000 +++ b/setup.py Fri Feb 27 19:14:09 2009 +0000 @@ -14,14 +14,12 @@ metadata, options = get_config() metadata['ext_modules'] = [ - Extension( - sources = [ - '_mysql.c', - '_mysql_connections.c', - '_mysql_results.c', - '_mysql_fields.c', - ], - **options), + Extension(sources=['src/mysqlmod.c', + 'src/connections.c', + 'src/results.c', + 'src/fields.c', + ], + **options), ] metadata['long_description'] = metadata['long_description'].replace(r'\n', '') metadata['test_suite'] = 'nose.collector'
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/connections.c Fri Feb 27 19:14:09 2009 +0000 @@ -0,0 +1,1473 @@ +/* -*- mode: C; indent-tabs-mode: t; c-basic-offset: 8; -*- */ + +#include "mysqlmod.h" + +static int +_mysql_ConnectionObject_Initialize( + _mysql_ConnectionObject *self, + PyObject *args, + PyObject *kwargs) +{ + MYSQL *conn = NULL; + PyObject *conv = NULL; + PyObject *ssl = NULL; +#if HAVE_OPENSSL + char *key = NULL, *cert = NULL, *ca = NULL, + *capath = NULL, *cipher = NULL; +#endif + char *host = NULL, *user = NULL, *passwd = NULL, + *db = NULL, *unix_socket = NULL; + unsigned int port = 0; + unsigned int client_flag = 0; + static char *kwlist[] = { "host", "user", "passwd", "db", "port", + "unix_socket", "conv", + "connect_timeout", "compress", + "named_pipe", "init_command", + "read_default_file", "read_default_group", + "client_flag", "ssl", + "local_infile", + NULL } ; + int connect_timeout = 0; + int compress = -1, named_pipe = -1, local_infile = -1; + char *init_command=NULL, + *read_default_file=NULL, + *read_default_group=NULL; + + self->converter = NULL; + self->open = 0; + check_server_init(-1); + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ssssisOiiisssiOi:connect", + kwlist, + &host, &user, &passwd, &db, + &port, &unix_socket, &conv, + &connect_timeout, + &compress, &named_pipe, + &init_command, &read_default_file, + &read_default_group, + &client_flag, &ssl, + &local_infile + )) + return -1; + + /* Keep the converter mapping or a blank mapping dict */ + if (!conv) + conv = PyDict_New(); + else + Py_INCREF(conv); + if (!conv) + return -1; + self->converter = conv; + +#define _stringsuck(d,t,s) {t=PyMapping_GetItemString(s,#d);\ + if(t){d=PyString_AsString(t);Py_DECREF(t);}\ + PyErr_Clear();} + + if (ssl) { +#if HAVE_OPENSSL + PyObject *value = NULL; + _stringsuck(ca, value, ssl); + _stringsuck(capath, value, ssl); + _stringsuck(cert, value, ssl); + _stringsuck(key, value, ssl); + _stringsuck(cipher, value, ssl); +#else + PyErr_SetString(_mysql_NotSupportedError, + "client library does not have SSL support"); + return -1; +#endif + } + + Py_BEGIN_ALLOW_THREADS ; + conn = mysql_init(&(self->connection)); + if (connect_timeout) { + unsigned int timeout = connect_timeout; + mysql_options(&(self->connection), MYSQL_OPT_CONNECT_TIMEOUT, + (char *)&timeout); + } + if (compress != -1) { + mysql_options(&(self->connection), MYSQL_OPT_COMPRESS, 0); + client_flag |= CLIENT_COMPRESS; + } + if (named_pipe != -1) + mysql_options(&(self->connection), MYSQL_OPT_NAMED_PIPE, 0); + if (init_command != NULL) + mysql_options(&(self->connection), MYSQL_INIT_COMMAND, init_command); + if (read_default_file != NULL) + mysql_options(&(self->connection), MYSQL_READ_DEFAULT_FILE, read_default_file); + if (read_default_group != NULL) + mysql_options(&(self->connection), MYSQL_READ_DEFAULT_GROUP, read_default_group); + + if (local_infile != -1) + mysql_options(&(self->connection), MYSQL_OPT_LOCAL_INFILE, (char *) &local_infile); + +#if HAVE_OPENSSL + if (ssl) + mysql_ssl_set(&(self->connection), + key, cert, ca, capath, cipher); +#endif + + conn = mysql_real_connect(&(self->connection), host, user, passwd, db, + port, unix_socket, client_flag); + + Py_END_ALLOW_THREADS ; + + if (!conn) { + _mysql_Exception(self); + return -1; + } + /* + PyType_GenericAlloc() automatically sets up GC allocation and + tracking for GC objects, at least in 2.2.1, so it does not need to + be done here. tp_dealloc still needs to call PyObject_GC_UnTrack(), + however. + */ + self->open = 1; + return 0; +} + +char _mysql_connect__doc__[] = +"Returns a MYSQL connection object. Exclusive use of\n\ +keyword parameters strongly recommended. Consult the\n\ +MySQL C API documentation for more details.\n\ +\n\ +host\n\ + string, host to connect\n\ +\n\ +user\n\ + string, user to connect as\n\ +\n\ +passwd\n\ + string, password to use\n\ +\n\ +db\n\ + string, database to use\n\ +\n\ +port\n\ + integer, TCP/IP port to connect to\n\ +\n\ +unix_socket\n\ + string, location of unix_socket (UNIX-ish only)\n\ +\n\ +conv\n\ + mapping, maps MySQL FIELD_TYPE.* to Python functions which\n\ + convert a string to the appropriate Python type\n\ +\n\ +connect_timeout\n\ + number of seconds to wait before the connection\n\ + attempt fails.\n\ +\n\ +compress\n\ + if set, gzip compression is enabled\n\ +\n\ +named_pipe\n\ + if set, connect to server via named pipe (Windows only)\n\ +\n\ +init_command\n\ + command which is run once the connection is created\n\ +\n\ +read_default_file\n\ + see the MySQL documentation for mysql_options()\n\ +\n\ +read_default_group\n\ + see the MySQL documentation for mysql_options()\n\ +\n\ +client_flag\n\ + client flags from MySQLdb.constants.CLIENT\n\ +\n\ +load_infile\n\ + int, non-zero enables LOAD LOCAL INFILE, zero disables\n\ +\n\ +"; + +PyObject * +_mysql_connect( + PyObject *self, + PyObject *args, + PyObject *kwargs) +{ + _mysql_ConnectionObject *c=NULL; + + c = MyAlloc(_mysql_ConnectionObject, _mysql_ConnectionObject_Type); + if (c == NULL) return NULL; + if (_mysql_ConnectionObject_Initialize(c, args, kwargs)) { + Py_DECREF(c); + c = NULL; + } + return (PyObject *) c; +} + +static int _mysql_ConnectionObject_traverse( + _mysql_ConnectionObject *self, + visitproc visit, + void *arg) +{ + if (self->converter) + return visit(self->converter, arg); + return 0; +} + +static int _mysql_ConnectionObject_clear( + _mysql_ConnectionObject *self) +{ + Py_XDECREF(self->converter); + self->converter = NULL; + return 0; +} + +extern PyObject * +_escape_item( + PyObject *item, + PyObject *d); + +char _mysql_escape__doc__[] = +"escape(obj, dict) -- escape any special characters in object obj\n\ +using mapping dict to provide quoting functions for each type.\n\ +Returns a SQL literal string."; +PyObject * +_mysql_escape( + PyObject *self, + PyObject *args) +{ + PyObject *o=NULL, *d=NULL; + if (!PyArg_ParseTuple(args, "O|O:escape", &o, &d)) + return NULL; + if (d) { + if (!PyMapping_Check(d)) { + PyErr_SetString(PyExc_TypeError, + "argument 2 must be a mapping"); + return NULL; + } + return _escape_item(o, d); + } else { + if (!self) { + PyErr_SetString(PyExc_TypeError, + "argument 2 must be a mapping"); + return NULL; + } + return _escape_item(o, + ((_mysql_ConnectionObject *) self)->converter); + } +} + +char _mysql_escape_string__doc__[] = +"escape_string(s) -- quote any SQL-interpreted characters in string s.\n\ +\n\ +Use connection.escape_string(s), if you use it at all.\n\ +_mysql.escape_string(s) cannot handle character sets. You are\n\ +probably better off using connection.escape(o) instead, since\n\ +it will escape entire sequences as well as strings."; + +PyObject * +_mysql_escape_string( + _mysql_ConnectionObject *self, + PyObject *args) +{ + PyObject *str; + char *in, *out; + int len, size; + if (!PyArg_ParseTuple(args, "s#:escape_string", &in, &size)) return NULL; + str = PyString_FromStringAndSize((char *) NULL, size*2+1); + if (!str) return PyErr_NoMemory(); + out = PyString_AS_STRING(str); +#if MYSQL_VERSION_ID < 32321 + len = mysql_escape_string(out, in, size); +#else + check_server_init(NULL); + if (self && self->open) + len = mysql_real_escape_string(&(self->connection), out, in, size); + else + len = mysql_escape_string(out, in, size); +#endif + if (_PyString_Resize(&str, len) < 0) return NULL; + return (str); +} + +char _mysql_string_literal__doc__[] = +"string_literal(obj) -- converts object obj into a SQL string literal.\n\ +This means, any special SQL characters are escaped, and it is enclosed\n\ +within single quotes. In other words, it performs:\n\ +\n\ +\"'%s'\" % escape_string(str(obj))\n\ +\n\ +Use connection.string_literal(obj), if you use it at all.\n\ +_mysql.string_literal(obj) cannot handle character sets."; + +PyObject * +_mysql_string_literal( + _mysql_ConnectionObject *self, + PyObject *args) +{ + PyObject *str, *s, *o, *d; + char *in, *out; + int len, size; + if (!PyArg_ParseTuple(args, "O|O:string_literal", &o, &d)) return NULL; + s = PyObject_Str(o); + if (!s) return NULL; + in = PyString_AsString(s); + size = PyString_GET_SIZE(s); + str = PyString_FromStringAndSize((char *) NULL, size*2+3); + if (!str) return PyErr_NoMemory(); + out = PyString_AS_STRING(str); +#if MYSQL_VERSION_ID < 32321 + len = mysql_escape_string(out+1, in, size); +#else + check_server_init(NULL); + if (self && self->open) + len = mysql_real_escape_string(&(self->connection), out+1, in, size); + else + len = mysql_escape_string(out+1, in, size); +#endif + *out = *(out+len+1) = '\''; + if (_PyString_Resize(&str, len+2) < 0) return NULL; + Py_DECREF(s); + return (str); +} + +static char _mysql_ConnectionObject_close__doc__[] = +"Close the connection. No further activity possible."; + +static PyObject * +_mysql_ConnectionObject_close( + _mysql_ConnectionObject *self, + PyObject *unused) +{ + if (self->open) { + Py_BEGIN_ALLOW_THREADS + mysql_close(&(self->connection)); + Py_END_ALLOW_THREADS + self->open = 0; + } else { + PyErr_SetString(_mysql_ProgrammingError, + "closing a closed connection"); + return NULL; + } + _mysql_ConnectionObject_clear(self); + Py_INCREF(Py_None); + return Py_None; +} + +static char _mysql_ConnectionObject_affected_rows__doc__ [] = +"Return number of rows affected by the last query.\n\ +Non-standard. Use Cursor.rowcount.\n\ +"; + +static PyObject * +_mysql_ConnectionObject_affected_rows( + _mysql_ConnectionObject *self, + PyObject *unused) +{ + check_connection(self); + return PyLong_FromUnsignedLongLong(mysql_affected_rows(&(self->connection))); +} + +static char _mysql_ConnectionObject_dump_debug_info__doc__[] = +"Instructs the server to write some debug information to the\n\ +log. The connected user must have the process privilege for\n\ +this to work. Non-standard.\n\ +"; + +static PyObject * +_mysql_ConnectionObject_dump_debug_info( + _mysql_ConnectionObject *self, + PyObject *unused) +{ + int err; + + check_connection(self); + Py_BEGIN_ALLOW_THREADS + err = mysql_dump_debug_info(&(self->connection)); + Py_END_ALLOW_THREADS + if (err) return _mysql_Exception(self); + Py_INCREF(Py_None); + return Py_None; +} + +static char _mysql_ConnectionObject_autocommit__doc__[] = +"Set the autocommit mode. True values enable; False value disable.\n\ +"; +static PyObject * +_mysql_ConnectionObject_autocommit( + _mysql_ConnectionObject *self, + PyObject *args) +{ + int flag, err; + if (!PyArg_ParseTuple(args, "i", &flag)) return NULL; + Py_BEGIN_ALLOW_THREADS +#if MYSQL_VERSION_ID >= 40100 + err = mysql_autocommit(&(self->connection), flag); +#else + { + char query[256]; + snprintf(query, 256, "SET AUTOCOMMIT=%d", flag); + err = mysql_query(&(self->connection), query); + } +#endif + Py_END_ALLOW_THREADS + if (err) return _mysql_Exception(self); + Py_INCREF(Py_None); + return Py_None; +} + +static char _mysql_ConnectionObject_commit__doc__[] = +"Commits the current transaction\n\ +"; +static PyObject * +_mysql_ConnectionObject_commit( + _mysql_ConnectionObject *self, + PyObject *unused) +{ + int err; + + Py_BEGIN_ALLOW_THREADS +#if MYSQL_VERSION_ID >= 40100 + err = mysql_commit(&(self->connection)); +#else + err = mysql_query(&(self->connection), "COMMIT"); +#endif + Py_END_ALLOW_THREADS + if (err) return _mysql_Exception(self); + Py_INCREF(Py_None); + return Py_None; +} + +static char _mysql_ConnectionObject_rollback__doc__[] = +"Rolls backs the current transaction\n\ +"; +static PyObject * +_mysql_ConnectionObject_rollback( + _mysql_ConnectionObject *self, + PyObject *unused) +{ + int err; + + Py_BEGIN_ALLOW_THREADS +#if MYSQL_VERSION_ID >= 40100 + err = mysql_rollback(&(self->connection)); +#else + err = mysql_query(&(self->connection), "ROLLBACK"); +#endif + Py_END_ALLOW_THREADS + if (err) return _mysql_Exception(self); + Py_INCREF(Py_None); + return Py_None; +} + +static char _mysql_ConnectionObject_next_result__doc__[] = +"If more query results exist, next_result() reads the next query\n\ +results and returns the status back to application.\n\ +\n\ +After calling next_result() the state of the connection is as if\n\ +you had called query() for the next query. This means that you can\n\ +now call store_result(), warning_count(), affected_rows()\n\ +, and so forth. \n\ +\n\ +Returns 0 if there are more results; -1 if there are no more results\n\ +\n\ +Non-standard.\n\ +"; +static PyObject * +_mysql_ConnectionObject_next_result( + _mysql_ConnectionObject *self, + PyObject *unused) +{ + int err; + + Py_BEGIN_ALLOW_THREADS +#if MYSQL_VERSION_ID >= 40100 + err = mysql_next_result(&(self->connection)); +#else + err = -1; +#endif + Py_END_ALLOW_THREADS + if (err > 0) return _mysql_Exception(self); + return PyInt_FromLong(err); +} + +#if MYSQL_VERSION_ID >= 40100 + +static char _mysql_ConnectionObject_set_server_option__doc__[] = +"set_server_option(option) -- Enables or disables an option\n\ +for the connection.\n\ +\n\ +Non-standard.\n\ +"; +static PyObject * +_mysql_ConnectionObject_set_server_option( + _mysql_ConnectionObject *self, + PyObject *args) +{ + int err, flags=0; + if (!PyArg_ParseTuple(args, "i", &flags)) + return NULL; + Py_BEGIN_ALLOW_THREADS + err = mysql_set_server_option(&(self->connection), flags); + Py_END_ALLOW_THREADS + if (err) return _mysql_Exception(self); + return PyInt_FromLong(err); +} + +static char _mysql_ConnectionObject_sqlstate__doc__[] = +"Returns a string containing the SQLSTATE error code\n\ +for the last error. The error code consists of five characters.\n\ +'00000' means \"no error.\" The values are specified by ANSI SQL\n\ +and ODBC. For a list of possible values, see section 23\n\ +Error Handling in MySQL in the MySQL Manual.\n\ +\n\ +Note that not all MySQL errors are yet mapped to SQLSTATE's.\n\ +The value 'HY000' (general error) is used for unmapped errors.\n\ +\n\ +Non-standard.\n\ +"; +static PyObject * +_mysql_ConnectionObject_sqlstate( + _mysql_ConnectionObject *self, + PyObject *unused) +{ + return PyString_FromString(mysql_sqlstate(&(self->connection))); +} + +static char _mysql_ConnectionObject_warning_count__doc__[] = +"Returns the number of warnings generated during execution\n\ +of the previous SQL statement.\n\ +\n\ +Non-standard.\n\ +"; +static PyObject * +_mysql_ConnectionObject_warning_count( + _mysql_ConnectionObject *self, + PyObject *unused) +{ + return PyInt_FromLong(mysql_warning_count(&(self->connection))); +} + +#endif + +static char _mysql_ConnectionObject_errno__doc__[] = +"Returns the error code for the most recently invoked API function\n\ +that can succeed or fail. A return value of zero means that no error\n\ +occurred.\n\ +"; + +static PyObject * +_mysql_ConnectionObject_errno( + _mysql_ConnectionObject *self, + PyObject *unused) +{ + check_connection(self); + return PyInt_FromLong((long)mysql_errno(&(self->connection))); +} + +static char _mysql_ConnectionObject_error__doc__[] = +"Returns the error message for the most recently invoked API function\n\ +that can succeed or fail. An empty string ("") is returned if no error\n\ +occurred.\n\ +"; + +static PyObject * +_mysql_ConnectionObject_error( + _mysql_ConnectionObject *self, + PyObject *unused) +{ + check_connection(self); + return PyString_FromString(mysql_error(&(self->connection))); +} + +#if MYSQL_VERSION_ID >= 32303 + +static char _mysql_ConnectionObject_change_user__doc__[] = +"Changes the user and causes the database specified by db to\n\ +become the default (current) database on the connection\n\ +specified by mysql. In subsequent queries, this database is\n\ +the default for table references that do not include an\n\ +explicit database specifier.\n\ +\n\ +This function was introduced in MySQL Version 3.23.3.\n\ +\n\ +Fails unless the connected user can be authenticated or if he\n\ +doesn't have permission to use the database. In this case the\n\ +user and database are not changed.\n\ +\n\ +The db parameter may be set to None if you don't want to have\n\ +a default database.\n\ +"; + +static PyObject * +_mysql_ConnectionObject_change_user( + _mysql_ConnectionObject *self, + PyObject *args, + PyObject *kwargs) +{ + char *user, *pwd=NULL, *db=NULL; + int r; + static char *kwlist[] = { "user", "passwd", "db", NULL } ; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|ss:change_user", + kwlist, &user, &pwd, &db)) + return NULL; + check_connection(self); + Py_BEGIN_ALLOW_THREADS + r = mysql_change_user(&(self->connection), user, pwd, db); + Py_END_ALLOW_THREADS + if (r) return _mysql_Exception(self); + Py_INCREF(Py_None); + return Py_None; +} +#endif + +static char _mysql_ConnectionObject_character_set_name__doc__[] = +"Returns the default character set for the current connection.\n\ +Non-standard.\n\ +"; + +static PyObject * +_mysql_ConnectionObject_character_set_name( + _mysql_ConnectionObject *self, + PyObject *unused) +{ + const char *s; + + check_connection(self); +#if MYSQL_VERSION_ID >= 32321 + s = mysql_character_set_name(&(self->connection)); +#else + s = "latin1"; +#endif + return PyString_FromString(s); +} + +#if MYSQL_VERSION_ID >= 50007 +static char _mysql_ConnectionObject_set_character_set__doc__[] = +"Sets the default character set for the current connection.\n\ +Non-standard.\n\ +"; + +static PyObject * +_mysql_ConnectionObject_set_character_set( + _mysql_ConnectionObject *self, + PyObject *args) +{ + const char *s; + int err; + if (!PyArg_ParseTuple(args, "s", &s)) return NULL; + check_connection(self); + Py_BEGIN_ALLOW_THREADS + err = mysql_set_character_set(&(self->connection), s); + Py_END_ALLOW_THREADS + if (err) return _mysql_Exception(self); + Py_INCREF(Py_None); + return Py_None; +} +#endif + +#if MYSQL_VERSION_ID >= 50010 +static char _mysql_ConnectionObject_get_character_set_info__doc__[] = +"Returns a dict with information about the current character set:\n\ +\n\ +collation\n\ + collation name\n\ +name\n\ + character set name\n\ +comment\n\ + comment or descriptive name\n\ +dir\n\ + character set directory\n\ +mbminlen\n\ + min. length for multibyte string\n\ +mbmaxlen\n\ + max. length for multibyte string\n\ +\n\ +Not all keys may be present, particularly dir.\n\ +\n\ +Non-standard.\n\ +"; + +static PyObject * +_mysql_ConnectionObject_get_character_set_info( + _mysql_ConnectionObject *self, + PyObject *unused) +{ + PyObject *result; + MY_CHARSET_INFO cs; + + check_connection(self); + mysql_get_character_set_info(&(self->connection), &cs); + if (!(result = PyDict_New())) return NULL; + if (cs.csname) + PyDict_SetItemString(result, "name", PyString_FromString(cs.csname)); + if (cs.name) + PyDict_SetItemString(result, "collation", PyString_FromString(cs.name)); + if (cs.comment) + PyDict_SetItemString(result, "comment", PyString_FromString(cs.comment)); + if (cs.dir) + PyDict_SetItemString(result, "dir", PyString_FromString(cs.dir)); + PyDict_SetItemString(result, "mbminlen", PyInt_FromLong(cs.mbminlen)); + PyDict_SetItemString(result, "mbmaxlen", PyInt_FromLong(cs.mbmaxlen)); + return result; +} +#endif + +static char _mysql_ConnectionObject_get_host_info__doc__[] = +"Returns a string that represents the MySQL client library\n\ +version. Non-standard.\n\ +"; + +static PyObject * +_mysql_ConnectionObject_get_host_info( + _mysql_ConnectionObject *self, + PyObject *unused) +{ + check_connection(self); + return PyString_FromString(mysql_get_host_info(&(self->connection))); +} + +static char _mysql_ConnectionObject_get_proto_info__doc__[] = +"Returns an unsigned integer representing the protocol version\n\ +used by the current connection. Non-standard.\n\ +"; + +static PyObject * +_mysql_ConnectionObject_get_proto_info( + _mysql_ConnectionObject *self, + PyObject *unused) +{ + check_connection(self); + return PyInt_FromLong((long)mysql_get_proto_info(&(self->connection))); +} + +static char _mysql_ConnectionObject_get_server_info__doc__[] = +"Returns a string that represents the server version number.\n\ +Non-standard.\n\ +"; + +static PyObject * +_mysql_ConnectionObject_get_server_info( + _mysql_ConnectionObject *self, + PyObject *unused) +{ + check_connection(self); + return PyString_FromString(mysql_get_server_info(&(self->connection))); +} + +static char _mysql_ConnectionObject_info__doc__[] = +"Retrieves a string providing information about the most\n\ +recently executed query. Non-standard. Use messages or\n\ +Cursor.messages.\n\ +"; + +static PyObject * +_mysql_ConnectionObject_info( + _mysql_ConnectionObject *self, + PyObject *unused) +{ + const char *s; + + check_connection(self); + s = mysql_info(&(self->connection)); + if (s) return PyString_FromString(s); + Py_INCREF(Py_None); + return Py_None; +} + +static char _mysql_ConnectionObject_insert_id__doc__[] = +"Returns the ID generated for an AUTO_INCREMENT column by the previous\n\ +query. Use this function after you have performed an INSERT query into a\n\ +table that contains an AUTO_INCREMENT field.\n\ +\n\ +Note that this returns 0 if the previous query does not\n\ +generate an AUTO_INCREMENT value. If you need to save the value for\n\ +later, be sure to call this immediately after the query\n\ +that generates the value.\n\ +\n\ +The ID is updated after INSERT and UPDATE statements that generate\n\ +an AUTO_INCREMENT value or that set a column value to\n\ +LAST_INSERT_ID(expr). See section 6.3.5.2 Miscellaneous Functions\n\ +in the MySQL documentation.\n\ +\n\ +Also note that the value of the SQL LAST_INSERT_ID() function always\n\ +contains the most recently generated AUTO_INCREMENT value, and is not\n\ +reset between queries because the value of that function is maintained\n\ +in the server.\n\ +" ; + +static PyObject * +_mysql_ConnectionObject_insert_id( + _mysql_ConnectionObject *self, + PyObject *unused) +{ + my_ulonglong r; + + check_connection(self); + Py_BEGIN_ALLOW_THREADS + r = mysql_insert_id(&(self->connection)); + Py_END_ALLOW_THREADS + return PyLong_FromUnsignedLongLong(r); +} + +static char _mysql_ConnectionObject_kill__doc__[] = +"Asks the server to kill the thread specified by pid.\n\ +Non-standard."; + +static PyObject * +_mysql_ConnectionObject_kill( + _mysql_ConnectionObject *self, + PyObject *args) +{ + unsigned long pid; + int r; + if (!PyArg_ParseTuple(args, "i:kill", &pid)) return NULL; + check_connection(self); + Py_BEGIN_ALLOW_THREADS + r = mysql_kill(&(self->connection), pid); + Py_END_ALLOW_THREADS + if (r) return _mysql_Exception(self); + Py_INCREF(Py_None); + return Py_None; +} + +static char _mysql_ConnectionObject_field_count__doc__[] = +"Returns the number of columns for the most recent query on the\n\ +connection. Non-standard. Will probably give you bogus results\n\ +on most cursor classes. Use Cursor.rowcount.\n\ +"; + +static PyObject * +_mysql_ConnectionObject_field_count( + _mysql_ConnectionObject *self, + PyObject *unused) +{ + check_connection(self); +#if MYSQL_VERSION_ID < 32224 + return PyInt_FromLong((long)mysql_num_fields(&(self->connection))); +#else + return PyInt_FromLong((long)mysql_field_count(&(self->connection))); +#endif +} + +static char _mysql_ConnectionObject_ping__doc__[] = +"Checks whether or not the connection to the server is\n\ +working. If it has gone down, an automatic reconnection is\n\ +attempted.\n\ +\n\ +This function can be used by clients that remain idle for a\n\ +long while, to check whether or not the server has closed the\n\ +connection and reconnect if necessary.\n\ +\n\ +New in 1.2.2: Accepts an optional reconnect parameter. If True,\n\ +then the client will attempt reconnection. Note that this setting\n\ +is persistent. By default, this is on in MySQL<5.0.3, and off\n\ +thereafter.\n\ +\n\ +Non-standard. You should assume that ping() performs an\n\ +implicit rollback; use only when starting a new transaction.\n\ +You have been warned.\n\ +"; + +static PyObject * +_mysql_ConnectionObject_ping( + _mysql_ConnectionObject *self, + PyObject *args) +{ + int r, reconnect = -1; + if (!PyArg_ParseTuple(args, "|I", &reconnect)) return NULL; + check_connection(self); + if ( reconnect != -1 ) self->connection.reconnect = reconnect; + Py_BEGIN_ALLOW_THREADS + r = mysql_ping(&(self->connection)); + Py_END_ALLOW_THREADS + if (r) return _mysql_Exception(self); + Py_INCREF(Py_None); + return Py_None; +} + +static char _mysql_ConnectionObject_query__doc__[] = +"Execute a query. store_result() or use_result() will get the\n\ +result set, if any. Non-standard. Use cursor() to create a cursor,\n\ +then cursor.execute().\n\ +" ; + +static PyObject * +_mysql_ConnectionObject_query( + _mysql_ConnectionObject *self, + PyObject *args) +{ + char *query; + int len, r; + if (!PyArg_ParseTuple(args, "s#:query", &query, &len)) return NULL; + check_connection(self); + Py_BEGIN_ALLOW_THREADS + r = mysql_real_query(&(self->connection), query, len); + Py_END_ALLOW_THREADS + if (r) return _mysql_Exception(self); + Py_INCREF(Py_None); + return Py_None; +} + + +static char _mysql_ConnectionObject_select_db__doc__[] = +"Causes the database specified by db to become the default\n\ +(current) database on the connection specified by mysql. In subsequent\n\ +queries, this database is the default for table references that do not\n\ +include an explicit database specifier.\n\ +\n\ +Fails unless the connected user can be authenticated as having\n\ +permission to use the database.\n\ +\n\ +Non-standard.\n\ +"; + +static PyObject * +_mysql_ConnectionObject_select_db( + _mysql_ConnectionObject *self, + PyObject *args) +{ + char *db; + int r; + if (!PyArg_ParseTuple(args, "s:select_db", &db)) return NULL; + check_connection(self); + Py_BEGIN_ALLOW_THREADS + r = mysql_select_db(&(self->connection), db); + Py_END_ALLOW_THREADS + if (r) return _mysql_Exception(self); + Py_INCREF(Py_None); + return Py_None; +} + +static char _mysql_ConnectionObject_shutdown__doc__[] = +"Asks the database server to shut down. The connected user must\n\ +have shutdown privileges. Non-standard.\n\ +"; + +static PyObject * +_mysql_ConnectionObject_shutdown( + _mysql_ConnectionObject *self, + PyObject *unused) +{ + int r; + + check_connection(self); + Py_BEGIN_ALLOW_THREADS + r = mysql_shutdown(&(self->connection) +#if MYSQL_VERSION_ID >= 40103 + , SHUTDOWN_DEFAULT +#endif + ); + Py_END_ALLOW_THREADS + if (r) return _mysql_Exception(self); + Py_INCREF(Py_None); + return Py_None; +} + +static char _mysql_ConnectionObject_stat__doc__[] = +"Returns a character string containing information similar to\n\ +that provided by the mysqladmin status command. This includes\n\ +uptime in seconds and the number of running threads,\n\ +questions, reloads, and open tables. Non-standard.\n\ +"; + +static PyObject * +_mysql_ConnectionObject_stat( + _mysql_ConnectionObject *self, + PyObject *unused) +{ + const char *s; + + check_connection(self); + Py_BEGIN_ALLOW_THREADS + s = mysql_stat(&(self->connection)); + Py_END_ALLOW_THREADS + if (!s) return _mysql_Exception(self); + return PyString_FromString(s); +} + +static char _mysql_ConnectionObject_store_result__doc__[] = +"Returns a result object acquired by mysql_store_result\n\ +(results stored in the client). If no results are available,\n\ +None is returned. Non-standard.\n\ +"; + +static PyObject * +_mysql_ConnectionObject_store_result( + _mysql_ConnectionObject *self, + PyObject *unused) +{ + PyObject *arglist=NULL, *kwarglist=NULL, *result=NULL; + _mysql_ResultObject *r=NULL; + + check_connection(self); + arglist = Py_BuildValue("(OiO)", self, 0, self->converter); + if (!arglist) goto error; + kwarglist = PyDict_New(); + if (!kwarglist) goto error; + r = MyAlloc(_mysql_ResultObject, _mysql_ResultObject_Type); + if (!r) goto error; + if (_mysql_ResultObject_Initialize(r, arglist, kwarglist)) + goto error; + result = (PyObject *) r; + if (!(r->result)) { + Py_DECREF(result); + Py_INCREF(Py_None); + result = Py_None; + } + error: + Py_XDECREF(arglist); + Py_XDECREF(kwarglist); + return result; +} + +static char _mysql_ConnectionObject_thread_id__doc__[] = +"Returns the thread ID of the current connection. This value\n\ +can be used as an argument to kill() to kill the thread.\n\ +\n\ +If the connection is lost and you reconnect with ping(), the\n\ +thread ID will change. This means you should not get the\n\ +thread ID and store it for later. You should get it when you\n\ +need it.\n\ +\n\ +Non-standard."; + +static PyObject * +_mysql_ConnectionObject_thread_id( + _mysql_ConnectionObject *self, + PyObject *unused) +{ + unsigned long pid; + + check_connection(self); + Py_BEGIN_ALLOW_THREADS + pid = mysql_thread_id(&(self->connection)); + Py_END_ALLOW_THREADS + return PyInt_FromLong((long)pid); +} + +static char _mysql_ConnectionObject_use_result__doc__[] = +"Returns a result object acquired by mysql_use_result\n\ +(results stored in the server). If no results are available,\n\ +None is returned. Non-standard.\n\ +"; + +static PyObject * +_mysql_ConnectionObject_use_result( + _mysql_ConnectionObject *self, + PyObject *unused) +{ + PyObject *arglist=NULL, *kwarglist=NULL, *result=NULL; + _mysql_ResultObject *r=NULL; + + check_connection(self); + arglist = Py_BuildValue("(OiO)", self, 1, self->converter); + if (!arglist) return NULL; + kwarglist = PyDict_New(); + if (!kwarglist) goto error; + r = MyAlloc(_mysql_ResultObject, _mysql_ResultObject_Type); + if (!r) goto error; + result = (PyObject *) r; + if (_mysql_ResultObject_Initialize(r, arglist, kwarglist)) + goto error; + if (!(r->result)) { + Py_DECREF(result); + Py_INCREF(Py_None); + result = Py_None; + } + error: + Py_DECREF(arglist); + Py_XDECREF(kwarglist); + return result; +} + +static void +_mysql_ConnectionObject_dealloc( + _mysql_ConnectionObject *self) +{ + PyObject *o; + + PyObject_GC_UnTrack(self); + if (self->open) { + o = _mysql_ConnectionObject_close(self, NULL); + Py_XDECREF(o); + } + MyFree(self); +} + +static PyObject * +_mysql_ConnectionObject_repr( + _mysql_ConnectionObject *self) +{ + char buf[300]; + if (self->open) + sprintf(buf, "<_mysql.connection open to '%.256s' at %lx>", + self->connection.host, + (long)self); + else + sprintf(buf, "<_mysql.connection closed at %lx>", + (long)self); + return PyString_FromString(buf); +} + +static PyMethodDef _mysql_ConnectionObject_methods[] = { + { + "affected_rows", + (PyCFunction)_mysql_ConnectionObject_affected_rows, + METH_NOARGS, + _mysql_ConnectionObject_affected_rows__doc__ + }, + { + "autocommit", + (PyCFunction)_mysql_ConnectionObject_autocommit, + METH_VARARGS, + _mysql_ConnectionObject_autocommit__doc__ + }, + { + "commit", + (PyCFunction)_mysql_ConnectionObject_commit, + METH_NOARGS, + _mysql_ConnectionObject_commit__doc__ + }, + { + "rollback", + (PyCFunction)_mysql_ConnectionObject_rollback, + METH_NOARGS, + _mysql_ConnectionObject_rollback__doc__ + }, + { + "next_result", + (PyCFunction)_mysql_ConnectionObject_next_result, + METH_NOARGS, + _mysql_ConnectionObject_next_result__doc__ + }, +#if MYSQL_VERSION_ID >= 40100 + { + "set_server_option", + (PyCFunction)_mysql_ConnectionObject_set_server_option, + METH_VARARGS, + _mysql_ConnectionObject_set_server_option__doc__ + }, + { + "sqlstate", + (PyCFunction)_mysql_ConnectionObject_sqlstate, + METH_NOARGS, + _mysql_ConnectionObject_sqlstate__doc__ + }, + { + "warning_count", + (PyCFunction)_mysql_ConnectionObject_warning_count, + METH_NOARGS, + _mysql_ConnectionObject_warning_count__doc__ + }, +#endif +#if MYSQL_VERSION_ID >= 32303 + { + "change_user", + (PyCFunction)_mysql_ConnectionObject_change_user, + METH_VARARGS | METH_KEYWORDS, + _mysql_ConnectionObject_change_user__doc__ + }, +#endif + { + "character_set_name", + (PyCFunction)_mysql_ConnectionObject_character_set_name, + METH_NOARGS, + _mysql_ConnectionObject_character_set_name__doc__ + }, +#if MYSQL_VERSION_ID >= 50007 + { + "set_character_set", + (PyCFunction)_mysql_ConnectionObject_set_character_set, + METH_VARARGS, + _mysql_ConnectionObject_set_character_set__doc__ + }, +#endif +#if MYSQL_VERSION_ID >= 50010 + { + "get_character_set_info", + (PyCFunction)_mysql_ConnectionObject_get_character_set_info, + METH_VARARGS, + _mysql_ConnectionObject_get_character_set_info__doc__ + }, +#endif + { + "close", + (PyCFunction)_mysql_ConnectionObject_close, + METH_NOARGS, + _mysql_ConnectionObject_close__doc__ + }, + { + "dump_debug_info", + (PyCFunction)_mysql_ConnectionObject_dump_debug_info, + METH_NOARGS, + _mysql_ConnectionObject_dump_debug_info__doc__ + }, + { + "escape", + (PyCFunction)_mysql_escape, + METH_VARARGS, + _mysql_escape__doc__ + }, + { + "escape_string", + (PyCFunction)_mysql_escape_string, + METH_VARARGS, + _mysql_escape_string__doc__ + }, + { + "error", + (PyCFunction)_mysql_ConnectionObject_error, + METH_NOARGS, + _mysql_ConnectionObject_error__doc__ + }, + { + "errno", + (PyCFunction)_mysql_ConnectionObject_errno, + METH_NOARGS, + _mysql_ConnectionObject_errno__doc__ + }, + { + "field_count", + (PyCFunction)_mysql_ConnectionObject_field_count, + METH_NOARGS, + _mysql_ConnectionObject_field_count__doc__ + }, + { + "get_host_info", + (PyCFunction)_mysql_ConnectionObject_get_host_info, + METH_NOARGS, + _mysql_ConnectionObject_get_host_info__doc__ + }, + { + "get_proto_info", + (PyCFunction)_mysql_ConnectionObject_get_proto_info, + METH_NOARGS, + _mysql_ConnectionObject_get_proto_info__doc__ + }, + { + "get_server_info", + (PyCFunction)_mysql_ConnectionObject_get_server_info, + METH_NOARGS, + _mysql_ConnectionObject_get_server_info__doc__ + }, + { + "info", + (PyCFunction)_mysql_ConnectionObject_info, + METH_NOARGS, + _mysql_ConnectionObject_info__doc__ + }, + { + "insert_id", + (PyCFunction)_mysql_ConnectionObject_insert_id, + METH_NOARGS, + _mysql_ConnectionObject_insert_id__doc__ + }, + { + "kill", + (PyCFunction)_mysql_ConnectionObject_kill, + METH_VARARGS, + _mysql_ConnectionObject_kill__doc__ + }, + { + "ping", + (PyCFunction)_mysql_ConnectionObject_ping, + METH_VARARGS, + _mysql_ConnectionObject_ping__doc__ + }, + { + "query", + (PyCFunction)_mysql_ConnectionObject_query, + METH_VARARGS, + _mysql_ConnectionObject_query__doc__ + }, + { + "select_db", + (PyCFunction)_mysql_ConnectionObject_select_db, + METH_VARARGS, + _mysql_ConnectionObject_select_db__doc__ + }, + { + "shutdown", + (PyCFunction)_mysql_ConnectionObject_shutdown, + METH_NOARGS, + _mysql_ConnectionObject_shutdown__doc__ + }, + { + "stat", + (PyCFunction)_mysql_ConnectionObject_stat, + METH_NOARGS, + _mysql_ConnectionObject_stat__doc__ + }, + { + "store_result", + (PyCFunction)_mysql_ConnectionObject_store_result, + METH_NOARGS, + _mysql_ConnectionObject_store_result__doc__ + }, + { + "string_literal", + (PyCFunction)_mysql_string_literal, + METH_VARARGS, + _mysql_string_literal__doc__}, + { + "thread_id", + (PyCFunction)_mysql_ConnectionObject_thread_id, + METH_NOARGS, + _mysql_ConnectionObject_thread_id__doc__ + }, + { + "use_result", + (PyCFunction)_mysql_ConnectionObject_use_result, + METH_NOARGS, + _mysql_ConnectionObject_use_result__doc__ + }, + {NULL, NULL} /* sentinel */ +}; + +static struct PyMemberDef _mysql_ConnectionObject_memberlist[] = { + { + "open", + T_INT, + offsetof(_mysql_ConnectionObject, open), + RO, + "True if connection is open" + }, + { + "converter", + T_OBJECT, + offsetof(_mysql_ConnectionObject, converter), + 0, + "Type conversion mapping" + }, + { + "server_capabilities", + T_UINT, + offsetof(_mysql_ConnectionObject, connection.server_capabilities), + RO, + "Capabilites of server; consult MySQLdb.constants.CLIENT" + }, + { + "port", + T_UINT, + offsetof(_mysql_ConnectionObject, connection.port), + RO, + "TCP/IP port of the server connection" + }, + { + "client_flag", + T_UINT, + RO, + offsetof(_mysql_ConnectionObject, connection.client_flag), + "Client flags; refer to MySQLdb.constants.CLIENT" + }, + {NULL} /* Sentinel */ +}; + +static PyObject * +_mysql_ConnectionObject_getattr( + _mysql_ConnectionObject *self, + char *name) +{ + PyObject *res; + struct PyMemberDef *l; + + res = Py_FindMethod(_mysql_ConnectionObject_methods, (PyObject *)self, name); + if (res != NULL) + return res; + PyErr_Clear(); + if (strcmp(name, "closed") == 0) + return PyInt_FromLong((long)!(self->open)); + + for (l = _mysql_ConnectionObject_memberlist; l->name != NULL; l++) { + if (strcmp(l->name, name) == 0) + return PyMember_GetOne((char *)self, l); + } + + PyErr_SetString(PyExc_AttributeError, name); + return NULL; +} + +static int +_mysql_ConnectionObject_setattr( + _mysql_ConnectionObject *self, + char *name, + PyObject *v) +{ + struct PyMemberDef *l; + + if (v == NULL) { + PyErr_SetString(PyExc_AttributeError, + "can't delete connection attributes"); + return -1; + } + + for (l = _mysql_ConnectionObject_memberlist; l->name != NULL; l++) + if (strcmp(l->name, name) == 0) + return PyMember_SetOne((char *)self, l, v); + + PyErr_SetString(PyExc_AttributeError, name); + return -1; +} + +PyTypeObject _mysql_ConnectionObject_Type = { + PyObject_HEAD_INIT(NULL) + 0, + "_mysql.connection", /* (char *)tp_name For printing */ + sizeof(_mysql_ConnectionObject), /* tp_basicsize */ + 0, + (destructor)_mysql_ConnectionObject_dealloc, /* tp_dealloc */ + 0, /*tp_print*/ + (getattrfunc)_mysql_ConnectionObject_getattr, /* tp_getattr */ + (setattrfunc)_mysql_ConnectionObject_setattr, /* tp_setattr */ + 0, /*tp_compare*/ + (reprfunc)_mysql_ConnectionObject_repr, /* 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, /* (getattrofunc) tp_getattro */ + 0, /* (setattrofunc) tp_setattro */ + + /* Functions to access object as input/output buffer */ + 0, /* (PyBufferProcs *) tp_as_buffer */ + + /* Flags to define presence of optional/expanded features */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, + + _mysql_connect__doc__, /* (char *) tp_doc Documentation string */ + + /* call function for all accessible objects */ + (traverseproc)_mysql_ConnectionObject_traverse, /* tp_traverse */ + + /* delete references to contained objects */ + (inquiry)_mysql_ConnectionObject_clear, /* 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 *)_mysql_ConnectionObject_methods, /* tp_methods */ + (struct PyMemberDef *)_mysql_ConnectionObject_memberlist, /* tp_members */ + 0, /* (struct getsetlist *) tp_getset; */ + 0, /* (struct _typeobject *) tp_base; */ + 0, /* (PyObject *) tp_dict */ + 0, /* (descrgetfunc) tp_descr_get */ + 0, /* (descrsetfunc) tp_descr_set */ + 0, /* (long) tp_dictoffset */ + (initproc)_mysql_ConnectionObject_Initialize, /* tp_init */ + NULL, /* tp_alloc */ + 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 */ +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/fields.c Fri Feb 27 19:14:09 2009 +0000 @@ -0,0 +1,295 @@ +/* -*- mode: C; indent-tabs-mode: t; c-basic-offset: 8; -*- */ + +#include "mysqlmod.h" + +static char _mysql_FieldObject__doc__[] = +""; + +int +_mysql_FieldObject_Initialize( + _mysql_FieldObject *self, + PyObject *args, + PyObject *kwargs) +{ + static char *kwlist[] = {"result", "index", NULL}; + _mysql_ResultObject *result=NULL; + MYSQL_FIELD *field; + unsigned int index; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Oi", kwlist, + &result, &index)) + return -1; + + self->index = index; + field = mysql_fetch_field_direct(result->result, index); + if (!field) return -1; + self->field = *field; + self->result = (PyObject *) result; + Py_INCREF(result); + return 0; +} + +static int +_mysql_FieldObject_traverse( + _mysql_FieldObject *self, + visitproc visit, + void *arg) +{ + if (self->result) + return visit(self->result, arg); + return 0; +} + +static int +_mysql_FieldObject_clear( + _mysql_FieldObject *self) +{ + Py_XDECREF(self->result); + self->result = NULL; + return 0; +} + +static void +_mysql_FieldObject_dealloc( + _mysql_FieldObject *self) +{ + PyObject_GC_UnTrack((PyObject *)self); + _mysql_FieldObject_clear(self); + MyFree(self); +} + +static PyObject * +_mysql_FieldObject_repr( + _mysql_FieldObject *self) +{ + char buf[300]; + snprintf(buf, 300, "<_mysql.field object at %lx>", (long)self); + return PyString_FromString(buf); +} + +static PyMethodDef _mysql_FieldObject_methods[] = { + {NULL, NULL} /* sentinel */ +}; + +static struct PyMemberDef _mysql_FieldObject_memberlist[] = { + { + "result", + T_OBJECT, + offsetof(_mysql_FieldObject, result), + RO, + "Result set" + }, + { + "name", + T_STRING, + offsetof(_mysql_FieldObject, field.name), + RO, + "The name of the field. If the field was given\n\ +an alias with an AS clause, the value of name is the alias." + }, + { + "org_name", + T_STRING, + offsetof(_mysql_FieldObject, field.org_name), + RO, + "The name of the field. Aliases are ignored." + }, + { + "table", + T_STRING, + offsetof(_mysql_FieldObject, field.table), + RO, + "The name of the table containing this field,\n\ +if it isn't a calculated field. For calculated fields,\n\ +the table value is an empty string. If the column is selected from a view,\n\ +table names the view. If the table or view was given an alias with an AS clause,\n\ +the value of table is the alias.\n" + }, + { + "org_table", + T_STRING, + offsetof(_mysql_FieldObject, field.org_table), + RO, + "The name of the table. Aliases are ignored.\n\ +If the column is selected from a view, org_table names the underlying table.\n" + }, + { + "db", + T_STRING, + offsetof(_mysql_FieldObject, field.db), + RO, + "The name of the database that the field comes from.\n\ +If the field is a calculated field, db is an empty string." + }, + { + "catalog", + T_STRING, + offsetof(_mysql_FieldObject, field.catalog), + RO, + "The catalog name. This value is always \"def\"." + }, + { + "length", + T_ULONG, + offsetof(_mysql_FieldObject, field.length), + RO, + "The width of the field.\n\ +as specified in the table definition.\n" + }, + { + "max_length", + T_ULONG, + offsetof(_mysql_FieldObject, field.max_length), + RO, + "The maximum width of the field for the result set\n\ +(the length of the longest field value for the rows actually in the\n\ +result set). If you use conn.store_result(), this contains the\n\ +maximum length for the field. If you use conn.use_result(),\n\ +the value of this variable is zero.\n" + }, + { + "decimals", + T_UINT, + offsetof(_mysql_FieldObject, field.decimals), + RO, + "The number of decimals for numeric fields.\n" + }, + { + "charsetnr", + T_UINT, + offsetof(_mysql_FieldObject, field.charsetnr), + RO, + "The character set number for the field." + }, + { + "flags", + T_UINT, + offsetof(_mysql_FieldObject, field.flags), + RO, + "Different bit-flags for the field.\n\ +The bits are enumerated in MySQLdb.constants.FLAG.\n\ +The flags value may have zero or more of these bits set.\n" + }, + { + "type", + T_UINT, + offsetof(_mysql_FieldObject, field.type), + RO, + "The type of the field. The type values\n\ +are enumerated in MySQLdb.constants.FIELD_TYPE.\n" + }, + {NULL} /* Sentinel */ +}; + +static PyObject * +_mysql_FieldObject_getattr( + _mysql_FieldObject *self, + char *name) +{ + PyObject *res; + struct PyMemberDef *l; + + res = Py_FindMethod(_mysql_FieldObject_methods, (PyObject *)self, name); + if (res != NULL) + return res; + PyErr_Clear(); + + for (l = _mysql_FieldObject_memberlist; l->name != NULL; l++) { + if (strcmp(l->name, name) == 0) + return PyMember_GetOne((char *)self, l); + } + + PyErr_SetString(PyExc_AttributeError, name); + return NULL; +} + +static int +_mysql_FieldObject_setattr( + _mysql_FieldObject *self, + char *name, + PyObject *v) +{ + struct PyMemberDef *l; + + if (v == NULL) { + PyErr_SetString(PyExc_AttributeError, + "can't delete attributes"); + return -1; + } + + + for (l = _mysql_FieldObject_memberlist; l->name != NULL; l++) + if (strcmp(l->name, name) == 0) + return PyMember_SetOne((char *)self, l, v); + + PyErr_SetString(PyExc_AttributeError, name); + return -1; +} + +PyTypeObject _mysql_FieldObject_Type = { + PyObject_HEAD_INIT(NULL) + 0, + "_mysql.field", + sizeof(_mysql_FieldObject), + 0, + (destructor)_mysql_FieldObject_dealloc, /* tp_dealloc */ + 0, /*tp_print*/ + (getattrfunc)_mysql_FieldObject_getattr, /* tp_getattr */ + (setattrfunc)_mysql_FieldObject_setattr, /* tp_setattr */ + 0, /*tp_compare*/ + (reprfunc)_mysql_FieldObject_repr, /* 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, /* (getattrofunc) tp_getattro */ + 0, /* (setattrofunc) tp_setattro */ + + /* Functions to access object as input/output buffer */ + 0, /* (PyBufferProcs *) tp_as_buffer */ + + /* Flags to define presence of optional/expanded features */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, + + _mysql_FieldObject__doc__, /* (char *) tp_doc Documentation string */ + + /* call function for all accessible objects */ + (traverseproc)_mysql_FieldObject_traverse, /* tp_traverse */ + + /* delete references to contained objects */ + (inquiry)_mysql_FieldObject_clear, /* 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 *)_mysql_FieldObject_methods, /* tp_methods */ + (struct PyMemberDef *)_mysql_FieldObject_memberlist, /*tp_members */ + 0, /* (struct getsetlist *) tp_getset; */ + 0, /* (struct _typeobject *) tp_base; */ + 0, /* (PyObject *) tp_dict */ + 0, /* (descrgetfunc) tp_descr_get */ + 0, /* (descrsetfunc) tp_descr_set */ + 0, /* (long) tp_dictoffset */ + (initproc)_mysql_FieldObject_Initialize, /* tp_init */ + NULL, /* tp_alloc */ + 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 */ +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mysqlmod.c Fri Feb 27 19:14:09 2009 +0000 @@ -0,0 +1,542 @@ +/* -*- 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_escape_sequence__doc__[] = +"escape_sequence(seq, dict) -- escape any special characters in sequence\n\ +seq using mapping dict to provide quoting functions for each type.\n\ +Returns a tuple of escaped items."; +static PyObject * +_mysql_escape_sequence( + PyObject *self, + PyObject *args) +{ + PyObject *o=NULL, *d=NULL, *r=NULL, *item, *quoted; + int i, n; + if (!PyArg_ParseTuple(args, "OO:escape_sequence", &o, &d)) + goto error; + if (!PyMapping_Check(d)) { + PyErr_SetString(PyExc_TypeError, + "argument 2 must be a mapping"); + return NULL; + } + if ((n = PyObject_Length(o)) == -1) goto error; + if (!(r = PyTuple_New(n))) goto error; + for (i=0; i<n; i++) { + item = PySequence_GetItem(o, i); + if (!item) goto error; + quoted = _escape_item(item, d); + Py_DECREF(item); + if (!quoted) goto error; + PyTuple_SET_ITEM(r, i, quoted); + } + return r; + error: + Py_XDECREF(r); + return NULL; +} + +static char _mysql_escape_dict__doc__[] = +"escape_sequence(d, dict) -- escape any special characters in\n\ +dictionary d using mapping dict to provide quoting functions for each type.\n\ +Returns a dictionary of escaped items."; +static PyObject * +_mysql_escape_dict( + PyObject *self, + PyObject *args) +{ + PyObject *o=NULL, *d=NULL, *r=NULL, *item, *quoted, *pkey; + Py_ssize_t ppos = 0; + if (!PyArg_ParseTuple(args, "O!O:escape_dict", &PyDict_Type, &o, &d)) + goto error; + if (!PyMapping_Check(d)) { + PyErr_SetString(PyExc_TypeError, + "argument 2 must be a mapping"); + return NULL; + } + if (!(r = PyDict_New())) goto error; + while (PyDict_Next(o, &ppos, &pkey, &item)) { + quoted = _escape_item(item, d); + if (!quoted) goto error; + if (PyDict_SetItem(r, pkey, quoted)==-1) goto error; + Py_DECREF(quoted); + } + return r; + error: + Py_XDECREF(r); + return NULL; +} + +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__ + }, + { + "escape", + (PyCFunction)_mysql_escape, + METH_VARARGS, + _mysql_escape__doc__ + }, + { + "escape_sequence", + (PyCFunction)_mysql_escape_sequence, + METH_VARARGS, + _mysql_escape_sequence__doc__ + }, + { + "escape_dict", + (PyCFunction)_mysql_escape_dict, + METH_VARARGS, + _mysql_escape_dict__doc__ + }, + { + "escape_string", + (PyCFunction)_mysql_escape_string, + METH_VARARGS, + _mysql_escape_string__doc__ + }, + { + "string_literal", + (PyCFunction)_mysql_string_literal, + METH_VARARGS, + _mysql_string_literal__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; +} + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mysqlmod.h Fri Feb 27 19:14:09 2009 +0000 @@ -0,0 +1,93 @@ +#ifndef _MYSQL_PYTHON__MYSQL_H_ +#define _MYSQL_PYTHON__MYSQL_H_ + +#include <Python.h> + +#ifdef MS_WIN32 +#include <windows.h> +#endif /* MS_WIN32 */ + +#include "structmember.h" +#include "mysql.h" +#include "my_config.h" +#include "mysqld_error.h" +#include "errmsg.h" + +#define MyAlloc(s,t) (s *) t.tp_alloc(&t,0) +#define MyFree(ob) ob->ob_type->tp_free((PyObject *)ob) + +#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN) +typedef int Py_ssize_t; +#define PY_SSIZE_T_MAX INT_MAX +#define PY_SSIZE_T_MIN INT_MIN +#endif + +typedef struct { + PyObject_HEAD + MYSQL connection; + int open; + PyObject *converter; +} _mysql_ConnectionObject; + +#define check_connection(c) if (!(c->open)) return _mysql_Exception(c) +#define result_connection(r) ((_mysql_ConnectionObject *)r->conn) +#define check_result_connection(r) check_connection(result_connection(r)) + +extern PyTypeObject _mysql_ConnectionObject_Type; + +typedef struct { + PyObject_HEAD + PyObject *conn; + MYSQL_RES *result; + int nfields; + int use; + PyObject *converter; +} _mysql_ResultObject; + +extern PyTypeObject _mysql_ResultObject_Type; + +typedef struct { + PyObject_HEAD + PyObject *result; + MYSQL_FIELD field; + unsigned int index; +} _mysql_FieldObject; + +extern PyTypeObject _mysql_FieldObject_Type; + +extern int _mysql_server_init_done; +#if MYSQL_VERSION_ID >= 40000 +#define check_server_init(x) if (!_mysql_server_init_done) { if (mysql_server_init(0, NULL, NULL)) { _mysql_Exception(NULL); return x; } else { _mysql_server_init_done = 1;} } +#else +#define check_server_init(x) if (!_mysql_server_init_done) _mysql_server_init_done = 1 +#endif + +extern PyObject *_mysql_MySQLError; +extern PyObject *_mysql_Warning; +extern PyObject *_mysql_Error; +extern PyObject *_mysql_DatabaseError; +extern PyObject *_mysql_InterfaceError; +extern PyObject *_mysql_DataError; +extern PyObject *_mysql_OperationalError; +extern PyObject *_mysql_IntegrityError; +extern PyObject *_mysql_InternalError; +extern PyObject *_mysql_ProgrammingError; +extern PyObject *_mysql_NotSupportedError; +extern PyObject *_mysql_error_map; + +extern PyObject * +_mysql_Exception(_mysql_ConnectionObject *c); + +extern int +_mysql_ResultObject_Initialize( + _mysql_ResultObject *self, + PyObject *args, + PyObject *kwargs); + +extern int +_mysql_FieldObject_Initialize( + _mysql_FieldObject *self, + PyObject *args, + PyObject *kwargs); + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/results.c Fri Feb 27 19:14:09 2009 +0000 @@ -0,0 +1,750 @@ +/* -*- mode: C; indent-tabs-mode: t; c-basic-offset: 8; -*- */ + +#include "mysqlmod.h" + +static char _mysql_ResultObject__doc__[] = +"result(connection, use=0, converter={}) -- Result set from a query.\n\ +\n\ +Creating instances of this class directly is an excellent way to\n\ +shoot yourself in the foot. If using _mysql.connection directly,\n\ +use connection.store_result() or connection.use_result() instead.\n\ +If using MySQLdb.Connection, this is done by the cursor class.\n\ +Just forget you ever saw this. Forget... FOR-GET..."; + +int +_mysql_ResultObject_Initialize( + _mysql_ResultObject *self, + PyObject *args, + PyObject *kwargs) +{ + static char *kwlist[] = {"connection", "use", "converter", NULL}; + MYSQL_RES *result; + _mysql_ConnectionObject *conn=NULL; + int use=0; + PyObject *conv=NULL; + int n, i; + MYSQL_FIELD *fields; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|iO", kwlist, + &conn, &use, &conv)) + return -1; + if (!conv) conv = PyDict_New(); + if (!conv) return -1; + self->conn = (PyObject *) conn; + Py_INCREF(conn); + self->use = use; + Py_BEGIN_ALLOW_THREADS ; + if (use) + result = mysql_use_result(&(conn->connection)); + else + result = mysql_store_result(&(conn->connection)); + self->result = result; + Py_END_ALLOW_THREADS ; + if (!result) { + self->converter = PyTuple_New(0); + return 0; + } + n = mysql_num_fields(result); + self->nfields = n; + if (!(self->converter = PyTuple_New(n))) return -1; + fields = mysql_fetch_fields(result); + for (i=0; i<n; i++) { + PyObject *tmp, *fun; + tmp = PyInt_FromLong((long) fields[i].type); + if (!tmp) return -1; + fun = PyObject_GetItem(conv, tmp); + Py_DECREF(tmp); + if (!fun) { + PyErr_Clear(); + fun = Py_None; + Py_INCREF(Py_None); + } + if (PySequence_Check(fun)) { + int j, n2=PySequence_Size(fun); + PyObject *fun2=NULL; + for (j=0; j<n2; j++) { + PyObject *t = PySequence_GetItem(fun, j); + if (!t) continue; + if (!PyTuple_Check(t)) goto cleanup; + if (PyTuple_GET_SIZE(t) == 2) { + long mask; + PyObject *pmask=NULL; + pmask = PyTuple_GET_ITEM(t, 0); + fun2 = PyTuple_GET_ITEM(t, 1); + if (PyInt_Check(pmask)) { + mask = PyInt_AS_LONG(pmask); + if (mask & fields[i].flags) { + Py_DECREF(t); + break; + } + else { + goto cleanup; + } + } else { + Py_DECREF(t); + break; + } + } + cleanup: + Py_DECREF(t); + } + if (!fun2) fun2 = Py_None; + Py_INCREF(fun2); + Py_DECREF(fun); + fun = fun2; + } + PyTuple_SET_ITEM(self->converter, i, fun); + } + return 0; +} + +static int +_mysql_ResultObject_traverse( + _mysql_ResultObject *self, + visitproc visit, + void *arg) +{ + int r; + if (self->converter) { + if (!(r = visit(self->converter, arg))) return r; + } + if (self->conn) + return visit(self->conn, arg); + return 0; +} + +static int +_mysql_ResultObject_clear( + _mysql_ResultObject *self) +{ + Py_XDECREF(self->converter); + self->converter = NULL; + Py_XDECREF(self->conn); + self->conn = NULL; + return 0; +} + +static char _mysql_ResultObject_describe__doc__[] = +"Returns the sequence of 7-tuples required by the DB-API for\n\ +the Cursor.description attribute.\n\ +"; + +static PyObject * +_mysql_ResultObject_describe( + _mysql_ResultObject *self, + PyObject *unused) +{ + PyObject *d; + MYSQL_FIELD *fields; + unsigned int i, n; + + check_result_connection(self); + n = mysql_num_fields(self->result); + fields = mysql_fetch_fields(self->result); + if (!(d = PyTuple_New(n))) return NULL; + for (i=0; i<n; i++) { + PyObject *t; + t = Py_BuildValue("(siiiiii)", + fields[i].name, + (long) fields[i].type, + (long) fields[i].max_length, + (long) fields[i].length, + (long) fields[i].length, + (long) fields[i].decimals, + (long) !(IS_NOT_NULL(fields[i].flags))); + if (!t) goto error; + PyTuple_SET_ITEM(d, i, t); + } + return d; + error: + Py_XDECREF(d); + return NULL; +} + +static char _mysql_ResultObject_fields__doc__[] = +"Returns the sequence of 7-tuples required by the DB-API for\n\ +the Cursor.description attribute.\n\ +"; + +static PyObject * +_mysql_ResultObject_fields( + _mysql_ResultObject *self, + PyObject *unused) +{ + PyObject *arglist=NULL, *kwarglist=NULL; + PyObject *fields=NULL; + _mysql_FieldObject *field=NULL; + unsigned int i, n; + + check_result_connection(self); + kwarglist = PyDict_New(); + if (!kwarglist) goto error; + n = mysql_num_fields(self->result); + if (!(fields = PyTuple_New(n))) return NULL; + for (i=0; i<n; i++) { + arglist = Py_BuildValue("(Oi)", self, i); + if (!arglist) goto error; + field = MyAlloc(_mysql_FieldObject, _mysql_FieldObject_Type); + if (!field) goto error; + if (_mysql_FieldObject_Initialize(field, arglist, kwarglist)) + goto error; + Py_DECREF(arglist); + PyTuple_SET_ITEM(fields, i, (PyObject *) field); + } + Py_DECREF(kwarglist); + return fields; + error: + Py_XDECREF(arglist); + Py_XDECREF(kwarglist); + Py_XDECREF(fields); + return NULL; +} + +static char _mysql_ResultObject_field_flags__doc__[] = +"Returns a tuple of field flags, one for each column in the result.\n\ +" ; + +static PyObject * +_mysql_ResultObject_field_flags( + _mysql_ResultObject *self, + PyObject *unused) +{ + PyObject *d; + MYSQL_FIELD *fields; + unsigned int i, n; + + check_result_connection(self); + n = mysql_num_fields(self->result); + fields = mysql_fetch_fields(self->result); + if (!(d = PyTuple_New(n))) return NULL; + for (i=0; i<n; i++) { + PyObject *f; + if (!(f = PyInt_FromLong((long)fields[i].flags))) goto error; + PyTuple_SET_ITEM(d, i, f); + } + return d; + error: + Py_XDECREF(d); + return NULL; +} + +static PyObject * +_mysql_field_to_python( + PyObject *converter, + char *rowitem, + unsigned long length) +{ + PyObject *v; + if (rowitem) { + if (converter != Py_None) + v = PyObject_CallFunction(converter, + "s#", + rowitem, + (int)length); + else + v = PyString_FromStringAndSize(rowitem, + (int)length); + if (!v) + return NULL; + } else { + Py_INCREF(Py_None); + v = Py_None; + } + return v; +} + +static PyObject * +_mysql_row_to_tuple( + _mysql_ResultObject *self, + MYSQL_ROW row) +{ + unsigned int n, i; + unsigned long *length; + PyObject *r, *c; + + n = mysql_num_fields(self->result); + if (!(r = PyTuple_New(n))) return NULL; + length = mysql_fetch_lengths(self->result); + for (i=0; i<n; i++) { + PyObject *v; + c = PyTuple_GET_ITEM(self->converter, i); + v = _mysql_field_to_python(c, row[i], length[i]); + if (!v) goto error; + PyTuple_SET_ITEM(r, i, v); + } + return r; + error: + Py_XDECREF(r); + return NULL; +} + +static PyObject * +_mysql_row_to_dict( + _mysql_ResultObject *self, + MYSQL_ROW row) +{ + unsigned int n, i; + unsigned long *length; + PyObject *r, *c; + MYSQL_FIELD *fields; + + n = mysql_num_fields(self->result); + if (!(r = PyDict_New())) return NULL; + length = mysql_fetch_lengths(self->result); + fields = mysql_fetch_fields(self->result); + for (i=0; i<n; i++) { + PyObject *v; + c = PyTuple_GET_ITEM(self->converter, i); + v = _mysql_field_to_python(c, row[i], length[i]); + if (!v) goto error; + if (!PyMapping_HasKeyString(r, fields[i].name)) { + PyMapping_SetItemString(r, fields[i].name, v); + } else { + int len; + char buf[256]; + strncpy(buf, fields[i].table, 256); + len = strlen(buf); + strncat(buf, ".", 256-len); + len = strlen(buf); + strncat(buf, fields[i].name, 256-len); + PyMapping_SetItemString(r, buf, v); + } + Py_DECREF(v); + } + return r; + error: + Py_XDECREF(r); + return NULL; +} + +static PyObject * +_mysql_row_to_dict_old( + _mysql_ResultObject *self, + MYSQL_ROW row) +{ + unsigned int n, i; + unsigned long *length; + PyObject *r, *c; + MYSQL_FIELD *fields; + + n = mysql_num_fields(self->result); + if (!(r = PyDict_New())) return NULL; + length = mysql_fetch_lengths(self->result); + fields = mysql_fetch_fields(self->result); + for (i=0; i<n; i++) { + PyObject *v; + c = PyTuple_GET_ITEM(self->converter, i); + v = _mysql_field_to_python(c, row[i], length[i]); + if (!v) goto error; + { + int len=0; + char buf[256]=""; + if (strlen(fields[i].table)) { + strncpy(buf, fields[i].table, 256); + len = strlen(buf); + strncat(buf, ".", 256-len); + len = strlen(buf); + } + strncat(buf, fields[i].name, 256-len); + PyMapping_SetItemString(r, buf, v); + } + Py_DECREF(v); + } + return r; + error: + Py_XDECREF(r); + return NULL; +} + +typedef PyObject *_PYFUNC(_mysql_ResultObject *, MYSQL_ROW); + +int +_mysql__fetch_row( + _mysql_ResultObject *self, + PyObject **r, + int skiprows, + int maxrows, + _PYFUNC *convert_row) +{ + unsigned int i; + MYSQL_ROW row; + + for (i = skiprows; i<(skiprows+maxrows); i++) { + PyObject *v; + if (!self->use) + row = mysql_fetch_row(self->result); + else { + Py_BEGIN_ALLOW_THREADS; + row = mysql_fetch_row(self->result); + Py_END_ALLOW_THREADS; + } + if (!row && mysql_errno(&(((_mysql_ConnectionObject *)(self->conn))->connection))) { + _mysql_Exception((_mysql_ConnectionObject *)self->conn); + goto error; + } + if (!row) { + if (_PyTuple_Resize(r, i) == -1) goto error; + break; + } + v = convert_row(self, row); + if (!v) goto error; + PyTuple_SET_ITEM(*r, i, v); + } + return i-skiprows; + error: + return -1; +} + +static char _mysql_ResultObject_fetch_row__doc__[] = +"fetch_row([maxrows, how]) -- Fetches up to maxrows as a tuple.\n\ +The rows are formatted according to how:\n\ +\n\ + 0 -- tuples (default)\n\ + 1 -- dictionaries, key=column or table.column if duplicated\n\ + 2 -- dictionaries, key=table.column\n\ +"; + +static PyObject * +_mysql_ResultObject_fetch_row( + _mysql_ResultObject *self, + PyObject *args, + PyObject *kwargs) +{ + typedef PyObject *_PYFUNC(_mysql_ResultObject *, MYSQL_ROW); + static char *kwlist[] = { "maxrows", "how", NULL }; + static _PYFUNC *row_converters[] = + { + _mysql_row_to_tuple, + _mysql_row_to_dict, + _mysql_row_to_dict_old + }; + _PYFUNC *convert_row; + unsigned int maxrows=1, how=0, skiprows=0, rowsadded; + PyObject *r=NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ii:fetch_row", kwlist, + &maxrows, &how)) + return NULL; + check_result_connection(self); + if (how < 0 || how >= sizeof(row_converters)) { + PyErr_SetString(PyExc_ValueError, "how out of range"); + return NULL; + } + convert_row = row_converters[how]; + if (maxrows) { + if (!(r = PyTuple_New(maxrows))) goto error; + rowsadded = _mysql__fetch_row(self, &r, skiprows, maxrows, + convert_row); + if (rowsadded == -1) goto error; + } else { + if (self->use) { + maxrows = 1000; + if (!(r = PyTuple_New(maxrows))) goto error; + while (1) { + rowsadded = _mysql__fetch_row(self, &r, skiprows, + maxrows, convert_row); + if (rowsadded == -1) goto error; + skiprows += rowsadded; + if (rowsadded < maxrows) break; + if (_PyTuple_Resize(&r, skiprows + maxrows) == -1) + goto error; + } + } else { + /* XXX if overflow, maxrows<0? */ + maxrows = (int) mysql_num_rows(self->result); + if (!(r = PyTuple_New(maxrows))) goto error; + rowsadded = _mysql__fetch_row(self, &r, 0, + maxrows, convert_row); + if (rowsadded == -1) goto error; + } + } + return r; + error: + Py_XDECREF(r); + return NULL; +} + + +static char _mysql_ResultObject_num_fields__doc__[] = +"Returns the number of fields (column) in the result." ; + +static PyObject * +_mysql_ResultObject_num_fields( + _mysql_ResultObject *self, + PyObject *unused) +{ + check_result_connection(self); + return PyInt_FromLong((long)mysql_num_fields(self->result)); +} + +static char _mysql_ResultObject_num_rows__doc__[] = +"Returns the number of rows in the result set. Note that if\n\ +use=1, this will not return a valid value until the entire result\n\ +set has been read.\n\ +"; + +static PyObject * +_mysql_ResultObject_num_rows( + _mysql_ResultObject *self, + PyObject *unused) +{ + check_result_connection(self); + return PyLong_FromUnsignedLongLong(mysql_num_rows(self->result)); +} + + +static char _mysql_ResultObject_data_seek__doc__[] = +"data_seek(n) -- seek to row n of result set"; +static PyObject * +_mysql_ResultObject_data_seek( + _mysql_ResultObject *self, + PyObject *args) +{ + unsigned int row; + if (!PyArg_ParseTuple(args, "i:data_seek", &row)) return NULL; + check_result_connection(self); + mysql_data_seek(self->result, row); + Py_INCREF(Py_None); + return Py_None; +} + +static char _mysql_ResultObject_row_seek__doc__[] = +"row_seek(n) -- seek by offset n rows of result set"; +static PyObject * +_mysql_ResultObject_row_seek( + _mysql_ResultObject *self, + PyObject *args) +{ + int offset; + MYSQL_ROW_OFFSET r; + if (!PyArg_ParseTuple(args, "i:row_seek", &offset)) return NULL; + check_result_connection(self); + if (self->use) { + PyErr_SetString(_mysql_ProgrammingError, + "cannot be used with connection.use_result()"); + return NULL; + } + r = mysql_row_tell(self->result); + mysql_row_seek(self->result, r+offset); + Py_INCREF(Py_None); + return Py_None; +} + +static char _mysql_ResultObject_row_tell__doc__[] = +"row_tell() -- return the current row number of the result set."; +static PyObject * +_mysql_ResultObject_row_tell( + _mysql_ResultObject *self, + PyObject *unused) +{ + MYSQL_ROW_OFFSET r; + + check_result_connection(self); + if (self->use) { + PyErr_SetString(_mysql_ProgrammingError, + "cannot be used with connection.use_result()"); + return NULL; + } + r = mysql_row_tell(self->result); + return PyInt_FromLong(r-self->result->data->data); +} + +static void +_mysql_ResultObject_dealloc( + _mysql_ResultObject *self) +{ + PyObject_GC_UnTrack((PyObject *)self); + mysql_free_result(self->result); + _mysql_ResultObject_clear(self); + MyFree(self); +} + +static PyObject * +_mysql_ResultObject_repr( + _mysql_ResultObject *self) +{ + char buf[300]; + sprintf(buf, "<_mysql.result object at %lx>", + (long)self); + return PyString_FromString(buf); +} + +static PyMethodDef _mysql_ResultObject_methods[] = { + { + "data_seek", + (PyCFunction)_mysql_ResultObject_data_seek, + METH_VARARGS, + _mysql_ResultObject_data_seek__doc__ + }, + { + "row_seek", + (PyCFunction)_mysql_ResultObject_row_seek, + METH_VARARGS, + _mysql_ResultObject_row_seek__doc__ + }, + { + "row_tell", + (PyCFunction)_mysql_ResultObject_row_tell, + METH_NOARGS, + _mysql_ResultObject_row_tell__doc__ + }, + { + "describe", + (PyCFunction)_mysql_ResultObject_describe, + METH_NOARGS, + _mysql_ResultObject_describe__doc__ + }, + { + "fields", + (PyCFunction)_mysql_ResultObject_fields, + METH_NOARGS, + _mysql_ResultObject_fields__doc__ + }, + { + "fetch_row", + (PyCFunction)_mysql_ResultObject_fetch_row, + METH_VARARGS | METH_KEYWORDS, + _mysql_ResultObject_fetch_row__doc__ + }, + { + "field_flags", + (PyCFunction)_mysql_ResultObject_field_flags, + METH_NOARGS, + _mysql_ResultObject_field_flags__doc__ + }, + { + "num_fields", + (PyCFunction)_mysql_ResultObject_num_fields, + METH_NOARGS, + _mysql_ResultObject_num_fields__doc__ + }, + { + "num_rows", + (PyCFunction)_mysql_ResultObject_num_rows, + METH_NOARGS, + _mysql_ResultObject_num_rows__doc__ + }, + {NULL, NULL} /* sentinel */ +}; + +static struct PyMemberDef _mysql_ResultObject_memberlist[] = { + { + "converter", + T_OBJECT, + offsetof(_mysql_ResultObject, converter), + RO, + "Type conversion mapping" + }, + {NULL} /* Sentinel */ +}; + +static PyObject * +_mysql_ResultObject_getattr( + _mysql_ResultObject *self, + char *name) +{ + PyObject *res; + struct PyMemberDef *l; + + res = Py_FindMethod(_mysql_ResultObject_methods, (PyObject *)self, name); + if (res != NULL) + return res; + PyErr_Clear(); + + for (l = _mysql_ResultObject_memberlist; l->name != NULL; l++) { + if (strcmp(l->name, name) == 0) + return PyMember_GetOne((char *)self, l); + } + + PyErr_SetString(PyExc_AttributeError, name); + return NULL; +} + +static int +_mysql_ResultObject_setattr( + _mysql_ResultObject *self, + char *name, + PyObject *v) +{ + struct PyMemberDef *l; + + if (v == NULL) { + PyErr_SetString(PyExc_AttributeError, + "can't delete connection attributes"); + return -1; + } + + for (l = _mysql_ResultObject_memberlist; l->name != NULL; l++) + if (strcmp(l->name, name) == 0) + return PyMember_SetOne((char *)self, l, v); + + PyErr_SetString(PyExc_AttributeError, name); + return -1; +} + +PyTypeObject _mysql_ResultObject_Type = { + PyObject_HEAD_INIT(NULL) + 0, + "_mysql.result", + sizeof(_mysql_ResultObject), + 0, + (destructor)_mysql_ResultObject_dealloc, /* tp_dealloc */ + 0, /*tp_print*/ + (getattrfunc)_mysql_ResultObject_getattr, /* tp_getattr */ + (setattrfunc)_mysql_ResultObject_setattr, /* tp_setattr */ + 0, /*tp_compare*/ + (reprfunc)_mysql_ResultObject_repr, /* 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, /* (getattrofunc) tp_getattro */ + 0, /* (setattrofunc) tp_setattro */ + + /* Functions to access object as input/output buffer */ + 0, /* (PyBufferProcs *) tp_as_buffer */ + + /* Flags to define presence of optional/expanded features */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, /* (long) tp_flags */ + + _mysql_ResultObject__doc__, /* (char *) tp_doc Documentation string */ + /* call function for all accessible objects */ + (traverseproc)_mysql_ResultObject_traverse, /* tp_traverse */ + /* delete references to contained objects */ + (inquiry)_mysql_ResultObject_clear, /* 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 *)_mysql_ResultObject_methods, /* tp_methods */ + (struct PyMemberDef *)_mysql_ResultObject_memberlist, /*tp_members */ + 0, /* (struct getsetlist *) tp_getset; */ + 0, /* (struct _typeobject *) tp_base; */ + 0, /* (PyObject *) tp_dict */ + 0, /* (descrgetfunc) tp_descr_get */ + 0, /* (descrsetfunc) tp_descr_set */ + 0, /* (long) tp_dictoffset */ + (initproc)_mysql_ResultObject_Initialize, /* tp_init */ + NULL, /* tp_alloc */ + 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 */ +};