pkg://mySQLmodule-0.1.4.tar.gz:14125/mySQLmodule.c
downloads
/*
An interface to the mySQL database system for Python
Copyright (C) 1997 Joseph Skinner <joe@earthlink.co.nz>
Query cursor code and some modifications
Copyright (C) 1997 James Henstridge <james@daa.com.au>
Based on mSQLmodule which was by the following people:
Portions copyright (C) 1995 Thawte Consulting, cc
(Those portions covered by the next copyright notice)
Portions copyright (C) 1994 Anthony Baxter.
*******************************************************************
Ported to mySQL Skinner (joe@earthlight.co.nz) Janurary 1997
-- STATUS : BETA
--VERSION 0.1.0
- converted source
- added support for some of the types not included in mSQL
- added support for return of auto_increment values
an auto_increment value is returned as a result from an insert
VERSION 0.1.2 (1997-04-02)
- added support for varchar
- added support for username and passwords
VERSION 0.1.4 (1997-09-09)
- added decimal and float types
- added a query cursor. (Mainly to support mysqldb - the Python
DB API module for MySQL) See New file.
- changed behavior so that currently unhandled types are returned
as strings, so that the python programmer can figure out what to
do with them.
-- TODO
- support timestamps
- support all unsupported mysql types
*/
/* This mSQLmodule copyright (it only applies to those sections):
******************************************************
*
* Based on a prior work by Anthony Baxter
* Updated, fixed and extended by David Gibson working for
* Thawte Consulting cc, South Africa.
*
* Copyright 1995 Thawte Consulting cc
* Portions copyright (C) 1994 Anthony Baxter.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this source file to use, copy, modify, merge, or publish it
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or in any new file that contains a substantial portion of
* this file.
*
* THE AUTHOR MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF
* THE SOFTWARE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT
* EXPRESS OR IMPLIED WARRANTY. THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NON-INFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE TO YOU OR ANY OTHER PARTY FOR ANY SPECIAL,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
* WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE, STRICT LIABILITY OR
* ANY OTHER ACTION ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*
******************************************************
mSQLmodule ChangeLog:- (slightly mangled by msql2mysql)
Modified by David Gibson December 1995
- listdbs and listtables now return a list of strings
- new Python naming conventions introduced
- queries now return data types in native Python format (String,Float,Int)
- solved spurious 'function requires at least one argument' error: old
getargs would not handle optional arguments. ParseTuple is being used now.
(so method table has got 1's in now)
(old Parse routine still needed for subscript handling)
- mysql_free_result now called after query!
- assignment to subscript trapped correctly. Ditto len()
- added DbType to the module dictionary
- mySQL.error object introduced
******************************************************
*/
/* #define DEBUG_MYSQLMOD */
#define INCLUDE_DATE_TIME_SUPPORT 1
/* #undef INCLUDE_DATE_TIME_SUPPORT */
#include "Python.h"
#include <sys/types.h>
#include <sys/stat.h>
#include "mysql.h"
char PROGNAME[] = "python";
static PyObject *pythonify_res();
static PyObject *pythonify_single_res();
static PyObject *pythonify_lf_res();
typedef struct {
PyObject_HEAD
MYSQL handle;
int valid;
} mysqlobject;
typedef struct {
PyObject_HEAD
MYSQL_RES * res;
unsigned long affected_rows;
unsigned long insert_id;
} mysqlres;
staticforward PyTypeObject MsqlType;
staticforward PyTypeObject ResType;
static PyObject *mySQLError;
static PyObject *newmysqlres(MYSQL_RES *, MYSQL);
#define is_mysqlobject(v) ((v)->ob_type == &MsqlType)
static PyObject *
mysqlmod_connect(self, args)
PyObject *self, *args;
{
char *dbname = NULL;
char *dbuser = NULL;
char *dbpass = NULL;
mysqlobject *n;
MYSQL newhandle;
if (!PyArg_ParseTuple(args, "|sss:connect", &dbname, &dbuser, &dbpass))
return NULL;
if (!(mysql_connect(&newhandle, dbname, dbuser, dbpass))) {
PyErr_SetString(mySQLError, "connect(): could not connect to MySQL");
return NULL;
}
if (newhandle.net.error) { /*JWS changed -1 to NULL */
PyErr_SetString(mySQLError, mysql_error(&newhandle));
return NULL;
} else {
n = PyObject_NEW(mysqlobject, &MsqlType);
if (!n)
return NULL;
n->valid = 1;
n->handle = newhandle;
return ((PyObject *) n);
}
}
static PyObject *
mysqlobj_selectdb(self, args)
mysqlobject *self;
PyObject *args;
{
char *dbname;
if (!PyArg_ParseTuple(args, "s:selectdb", &dbname))
return NULL;
if (mysql_select_db(&(self->handle), dbname) == -1) {
PyErr_SetString(mySQLError, mysql_error(&(self->handle)));
return NULL;
}
Py_INCREF(Py_None);
return (Py_None);
}
static PyObject *
mysqlobj_listdbs(self, args)
mysqlobject *self;
PyObject *args;
{
MYSQL_RES *res;
PyObject *resobj;
if (!PyArg_ParseTuple(args, ":listdbs"))
return NULL;
if ((res = mysql_list_dbs(&(self->handle), NULL)) == NULL) { /* JWS added NULL */
Py_INCREF(Py_None);
return (Py_None);
}
resobj = pythonify_single_res(res);
return (resobj);
}
static PyObject *
mysqlobj_listtables(self, args)
mysqlobject *self;
PyObject *args;
{
MYSQL_RES *res;
PyObject *resobj;
if (!PyArg_ParseTuple(args, ":listtables"))
return NULL;
if ((res = mysql_list_tables(&(self->handle), NULL)) == NULL) {
Py_INCREF(Py_None);
return (Py_None);
}
resobj = pythonify_single_res(res);
return (resobj);
}
static PyObject *
mysqlobj_listfields(self, args)
mysqlobject *self;
PyObject *args;
{
char *tname;
MYSQL_RES *res;
PyObject *resobj;
if (!PyArg_ParseTuple(args, "s:listfields", &tname))
return NULL;
if ((res = mysql_list_fields(&(self->handle), tname, NULL)) == NULL) {
Py_INCREF(Py_None);
return (Py_None);
}
resobj = pythonify_lf_res(res);
return (resobj);
}
static PyObject *
mysqlobj_query_helper(self, query)
mysqlobject *self;
char *query;
{
MYSQL_RES *res;
PyObject *resobj;
if (mysql_query(&(self->handle), query) == -1) {
PyErr_SetString(mySQLError, mysql_error(&(self->handle)));
return NULL;
}
res = mysql_store_result(&(self->handle));
if (!res) {
/* new code to handle returning of auto_increment keys */
if (mysql_error(&(self->handle))[0] == 0 &&
mysql_num_fields(&(self->handle)) == 0 &&
mysql_insert_id(&(self->handle)) != 0) {
ulong used_id;
used_id = mysql_insert_id(&(self->handle));
return (PyInt_FromLong(used_id));
} else {
Py_INCREF(Py_None);
return (Py_None);
}
}
resobj = pythonify_res(res);
mysql_free_result(res);
return (resobj);
}
static PyObject *
mysqlobj_query(self, args)
mysqlobject *self;
PyObject *args;
{
char *query;
if (!PyArg_ParseTuple(args, "s:query", &query))
return NULL;
return mysqlobj_query_helper(self, query);
}
static PyObject *
mysqlobj_create(self, args)
mysqlobject *self;
PyObject *args;
{
char *dbname;
if (!PyArg_ParseTuple(args, "s:create", &dbname))
return NULL;
if (mysql_create_db(&(self->handle), dbname) == -1) {
PyErr_SetString(mySQLError, mysql_error(&(self->handle)));
return NULL;
}
Py_INCREF(Py_None);
return (Py_None);
}
static PyObject *
mysqlobj_drop(self, args)
mysqlobject *self;
PyObject *args;
{
char *dbname;
if (!PyArg_ParseTuple(args, "s:drop", &dbname))
return NULL;
if (mysql_drop_db(&(self->handle), dbname) == -1) {
PyErr_SetString(mySQLError, mysql_error(&(self->handle)));
return NULL;
}
Py_INCREF(Py_None);
return (Py_None);
}
static PyObject *
mysqlobj_reload(self, args)
mysqlobject *self;
PyObject *args;
{
if (!PyArg_ParseTuple(args, ":reload"))
return NULL;
if (mysql_reload(&(self->handle)) == -1) {
PyErr_SetString(mySQLError, mysql_error(&(self->handle)));
return NULL;
}
Py_INCREF(Py_None);
return (Py_None);
}
static PyObject *
mysqlobj_shutdown(self, args)
mysqlobject *self;
PyObject *args;
{
if (!PyArg_ParseTuple(args, ":shutdown"))
return NULL;
if (mysql_shutdown(&(self->handle)) == -1) {
PyErr_SetString(mySQLError, mysql_error(&(self->handle)));
return NULL;
}
Py_INCREF(Py_None);
return (Py_None);
}
/* return a cursor object for the given query */
static PyObject *
mysqlobj_querycursor(self, args)
mysqlobject *self;
PyObject *args;
{
char *query;
if (!PyArg_ParseTuple(args, "s:querycursor", &query))
return NULL;
if (mysql_query(&(self->handle), query) == -1) {
PyErr_SetString(mySQLError, mysql_error(&(self->handle)));
return NULL;
}
return newmysqlres(mysql_store_result(&(self->handle)),
self->handle);
}
/*
* Take an mySQL MYSQL_ROW, turn it into a tuple. Used by pythonify_res,
* pythonify_n_rows, pythonify_single_res2
*/
static PyObject *
pythonify_row(res, thisrow)
MYSQL_RES *res;
MYSQL_ROW thisrow;
{
PyObject *rowtuple, *fieldobj;
MYSQL_FIELD *tf;
int i, n;
uint *lengths;
n = mysql_num_fields(res);
lengths = mysql_fetch_lengths(res);
rowtuple = PyTuple_New(n);
mysql_field_seek(res, 0); /* JWS use the mysql macro */
for (i = 0; i < n; i++) {
tf = mysql_fetch_field(res);
if (thisrow[i])
/*
mysql types
FIELD_TYPE_DECIMAL, FIELD_TYPE_CHAR,
FIELD_TYPE_SHORT, FIELD_TYPE_LONG,
FIELD_TYPE_FLOAT, FIELD_TYPE_DOUBLE,
FIELD_TYPE_NULL, FIELD_TYPE_TIME,
FIELD_TYPE_LONGLONG,FIELD_TYPE_INT24,
FIELD_TYPE_TINY_BLOB=249,
FIELD_TYPE_MEDIUM_BLOB=250,
FIELD_TYPE_LONG_BLOB=251,
FIELD_TYPE_BLOB=252,
FIELD_TYPE_VAR_STRING=253,
FIELD_TYPE_STRING=254
*/
switch (tf->type) {
case FIELD_TYPE_SHORT:
case FIELD_TYPE_LONG:
fieldobj = PyInt_FromLong(atol(thisrow[i]));
break;
case FIELD_TYPE_CHAR:
case FIELD_TYPE_STRING:
case FIELD_TYPE_VAR_STRING:
#ifdef INCLUDE_DATE_TIME_SUPPORT
case FIELD_TYPE_DATE:
case FIELD_TYPE_TIME:
case FIELD_TYPE_DATETIME:
case FIELD_TYPE_TIMESTAMP:
#endif
fieldobj = PyString_FromString(thisrow[i]);
break;
case FIELD_TYPE_TINY_BLOB:
case FIELD_TYPE_MEDIUM_BLOB:
case FIELD_TYPE_LONG_BLOB:
case FIELD_TYPE_BLOB:
fieldobj = PyString_FromStringAndSize(thisrow[i],
lengths[i]);
break;
case FIELD_TYPE_DECIMAL:
case FIELD_TYPE_DOUBLE:
case FIELD_TYPE_FLOAT:
fieldobj = PyFloat_FromDouble(atof(thisrow[i]));
break;
default: /* JH - unhandled types now return strings */
fieldobj = PyString_FromString(thisrow[i]);
break;
} else {
Py_INCREF(Py_None);
fieldobj = Py_None;
}
PyTuple_SetItem(rowtuple, i, fieldobj);
}
return rowtuple;
}
/*
* Take an mySQL MYSQL_RES, turn it into a list of tuples.
*/
static PyObject *
pythonify_res(res)
MYSQL_RES *res;
{
PyObject *reslist, *rowtuple;
MYSQL_ROW thisrow;
#ifdef DEBUG_MYSQLMOD
printf("data ready, %d rows of %d fields\n", mysql_num_rows(res), mysql_num_fields(res));
#endif
reslist = PyList_New(0);
while (thisrow = mysql_fetch_row(res)) {
rowtuple = pythonify_row(res, thisrow);
PyList_Append(reslist, rowtuple);
Py_DECREF(rowtuple);
}
return (reslist);
}
/* get a particular number of rows */
static PyObject *
pythonify_n_rows(res, num)
MYSQL_RES *res;
int num;
{
PyObject *reslist, *rowtuple;
MYSQL_ROW thisrow;
int i;
#ifdef DEBUG_MYSQLMOD
printf("data ready, %d rows of %d fields\n", mysql_num_rows(res), mysql_num_fields(res));
#endif
reslist = PyList_New(0);
for (i = 0; (thisrow = mysql_fetch_row(res)) && i < num; i++) {
rowtuple = pythonify_row(res, thisrow);
PyList_Append(reslist, rowtuple);
Py_DECREF(rowtuple);
}
return (reslist);
}
/* return the result in the same form as lists give it */
static PyObject *
pythonify_single_res2(res)
MYSQL_RES *res;
{
MYSQL_ROW thisrow;
#ifdef DEBUG_MYSQLMOD
printf("data ready, %d rows of %d fields\n", mysql_num_rows(res), mysql_num_fields(res));
#endif
if (thisrow = mysql_fetch_row(res))
return pythonify_row(res, thisrow);
else {
Py_INCREF(Py_None);
return Py_None;
}
}
/*
* Take an mySQL MYSQL_RES, turn it into a list of strings.
*/
static PyObject *
pythonify_single_res(res)
MYSQL_RES *res;
{
PyObject *reslist, *str;
MYSQL_ROW thisrow;
int n;
#ifdef DEBUG_MYSQLMOD
printf("data ready, %d rows of %d fields\n", mysql_num_rows(res), mysql_num_fields(res));
#endif
reslist = PyList_New(0);
n = mysql_num_fields(res);
if (n != 1) {
PyErr_SetString(mySQLError, "expected mySQL to return singletons");
return NULL;
}
while (thisrow = mysql_fetch_row(res)) {
str = PyString_FromString(thisrow[0]);
PyList_Append(reslist, str);
}
return (reslist);
}
/*
* Take an mySQL MYSQL_RES, return a list of tuples of the FetchField data.
*/
static PyObject *
pythonify_lf_res(res)
MYSQL_RES *res;
{
PyObject *reslist, *thistuple;
int i, n;
char *type, flags[14];
MYSQL_FIELD *tf;
#ifdef DEBUG_MYSQLMOD
printf("data ready, %d fields\n", mysql_num_fields(res));
#endif
reslist = PyList_New(0);
n = mysql_num_fields(res);
for (i = 0; i < n; i++) {
tf = &(mysql_fetch_field_direct(res, i));
#ifdef DEBUG_MYSQLMOD
printf("value of tf->type is %d \n", tf->type);
#endif
switch (tf->type) {
case FIELD_TYPE_SHORT:
type = "short";
break;
case FIELD_TYPE_LONG:
type = "long";
break;
case FIELD_TYPE_CHAR:
type = "char";
break;
case FIELD_TYPE_DOUBLE:
type = "double";
break;
case FIELD_TYPE_DECIMAL:
type = "decimal";
break;
case FIELD_TYPE_FLOAT:
type = "float";
break;
case FIELD_TYPE_TINY_BLOB:
type = "tiny blob";
break;
case FIELD_TYPE_MEDIUM_BLOB:
type = "medium blob";
break;
case FIELD_TYPE_LONG_BLOB:
type = "long blob";
break;
case FIELD_TYPE_BLOB:
type = "blob";
break;
#ifdef INCLUDE_DATE_TIME_SUPPORT
case FIELD_TYPE_DATE:
type = "date";
break;
case FIELD_TYPE_TIME:
type = "time";
break;
case FIELD_TYPE_DATETIME:
type = "datetime";
break;
case FIELD_TYPE_TIMESTAMP:
type = "timestamp";
break;
#endif
case FIELD_TYPE_NULL:
case FIELD_TYPE_LONGLONG:
case FIELD_TYPE_INT24:
type = "unhandled";
break;
case FIELD_TYPE_VAR_STRING:
type = "varchar";
break;
case FIELD_TYPE_STRING:
type = "string";
break;
default:
type = "????";
break;
}
if (IS_PRI_KEY(tf->flags))
strcpy(flags, "pri");
else
flags[0] = 0;
if (IS_NOT_NULL(tf->flags))
if (flags[0])
strcat(flags, " notnull");
else
strcpy(flags, "notnull");
else
flags[0] = 0;
thistuple = Py_BuildValue("(sssis)", tf->name, tf->table, type, tf->length,
flags);
PyList_Append(reslist, thistuple);
Py_DECREF(thistuple);
}
return (reslist);
}
static struct PyMethodDef mysqlobj_methods[] =
{
{"selectdb", (PyCFunction) mysqlobj_selectdb, 1},
{"query", (PyCFunction) mysqlobj_query, 1},
{"querycursor", (PyCFunction) mysqlobj_querycursor, 1},
{"listdbs", (PyCFunction) mysqlobj_listdbs, 1},
{"listtables", (PyCFunction) mysqlobj_listtables, 1},
{"listfields", (PyCFunction) mysqlobj_listfields, 1},
{"create", (PyCFunction) mysqlobj_create, 1},
{"drop", (PyCFunction) mysqlobj_drop, 1},
{"reload", (PyCFunction) mysqlobj_reload, 1},
{"shutdown", (PyCFunction) mysqlobj_shutdown, 1},
{NULL, NULL} /* sentinel */
};
static PyObject *
mysqlobj_getattr(ms, name)
mysqlobject *ms;
char *name;
{
return Py_FindMethod(mysqlobj_methods, (PyObject *) ms, name);
}
static void
mysqlobj_dealloc(m)
register mysqlobject *m;
{
if (m->valid)
mysql_close(&(m->handle));
PyMem_DEL(m);
}
static int
mysqlobj_len(self, subs)
PyObject *self, *subs;
{
PyErr_SetString(mySQLError, "can't take length of an mySQL handle");
return -1;
}
static PyObject *
mysqlobj_subscript(self, subs)
PyObject *self, *subs;
{
char *query;
if (!PyArg_Parse(subs, "s", &query)) {
PyErr_SetString(mySQLError, "subscript expects a query string");
return NULL;
}
return mysqlobj_query_helper(self, query);
}
static int
mysqlobj_ass_sub(self, subs, val)
PyObject *self, *subs, *val;
{
PyErr_SetString(mySQLError, "can't assign to an mySQL handle (use query insert)");
return -1; /* -1 is error code in interpreter main loop! (ceval.c) */
}
static PyMappingMethods mysql_as_mapping =
{
(inquiry) mysqlobj_len, /*length */
(binaryfunc) mysqlobj_subscript, /*subscript */
(objobjargproc) mysqlobj_ass_sub, /*assign subscript */
};
static PyTypeObject MsqlType =
{
PyObject_HEAD_INIT(&PyType_Type)
0,
"mysqlobject",
sizeof(mysqlobject),
0,
(destructor) mysqlobj_dealloc, /*tp_dealloc */
0, /*tp_print */
(getattrfunc) mysqlobj_getattr, /*tp_getattr */
0, /*tp_setattr */
0, /*tp_compare */
0, /*tp_repr */
0, /*tp_as_number */
0, /*tp_as_sequence */
&mysql_as_mapping, /*tp_as_mapping */
};
/* mysqlres object methods */
static PyObject *
mysqlres_fields(self, args)
mysqlres *self;
PyObject *args;
{
if (!PyArg_ParseTuple(args, ":fields"))
return NULL;
if (self->res == NULL) {
PyErr_SetString(mySQLError,
"can't complete opperation; no response body");
return NULL;
}
return pythonify_lf_res(self->res);
}
static PyObject *
mysqlres_fetchall(self, args)
mysqlres *self;
PyObject *args;
{
if (!PyArg_ParseTuple(args, ":fetchall"))
return NULL;
if (self->res == NULL) {
PyErr_SetString(mySQLError,
"can't complete opperation; no response body");
return NULL;
}
mysql_data_seek(self->res, 0);
return pythonify_res(self->res);
}
static PyObject *
mysqlres_fetchone(self, args)
mysqlres *self;
PyObject *args;
{
if (!PyArg_ParseTuple(args, ":fetchone"))
return NULL;
if (self->res == NULL) {
PyErr_SetString(mySQLError,
"can't complete opperation; no response body");
return NULL;
}
return pythonify_single_res2(self->res);
}
static PyObject *
mysqlres_fetchmany(self, args)
mysqlres *self;
PyObject *args;
{
int i;
if (!PyArg_ParseTuple(args, "i:fetchmany", &i))
return NULL;
if (self->res == NULL) {
PyErr_SetString(mySQLError,
"can't complete opperation; no response body");
return NULL;
}
return pythonify_n_rows(self->res, i);
}
static PyObject *
mysqlres_seek(self, args)
mysqlres *self;
PyObject *args;
{
int i;
if (!PyArg_ParseTuple(args, "i:seek", &i))
return NULL;
if (self->res == NULL) {
PyErr_SetString(mySQLError,
"can't complete opperation; no response body");
return NULL;
}
mysql_data_seek(self->res, i);
Py_INCREF(Py_None);
return Py_None;
}
static PyObject *
mysqlres_numrows(self, args)
mysqlres *self;
PyObject *args;
{
if (!PyArg_ParseTuple(args, ":numrows"))
return NULL;
if (self->res == NULL) {
PyErr_SetString(mySQLError,
"can't complete opperation; no response body");
return NULL;
}
return PyInt_FromLong((long) mysql_num_rows(self->res));
}
static PyObject *
mysqlres_numfields(self, args)
mysqlres *self;
PyObject *args;
{
if (!PyArg_ParseTuple(args, ":numfields"))
return NULL;
if (self->res == NULL) {
PyErr_SetString(mySQLError,
"can't complete opperation; no response body");
return NULL;
}
return PyInt_FromLong((long) mysql_num_fields(self->res));
}
static PyObject *
mysqlres_eof(self, args)
mysqlres *self;
PyObject *args;
{
if (!PyArg_ParseTuple(args, ":eof"))
return NULL;
if (self->res == NULL) {
PyErr_SetString(mySQLError,
"can't complete opperation; no response body");
return NULL;
}
if (mysql_eof(self->res)) {
Py_INCREF(Py_True);
return Py_True;
} else {
Py_INCREF(Py_False);
return Py_False;
}
}
static PyObject *
mysqlres_affectedrows(self, args)
mysqlres *self;
PyObject *args;
{
if (!PyArg_ParseTuple(args, ":affectedrows"))
return NULL;
return PyInt_FromLong(self->affected_rows);
}
static PyObject *
mysqlres_insertid(self, args)
mysqlres *self;
PyObject *args;
{
if (!PyArg_ParseTuple(args, ":insertid"))
return NULL;
return PyInt_FromLong(self->insert_id);
}
static struct PyMethodDef mysqlres_methods[] =
{
{"fields", (PyCFunction) mysqlres_fields, 1},
{"fetchall", (PyCFunction) mysqlres_fetchall, 1},
{"fetchone", (PyCFunction) mysqlres_fetchone, 1},
{"fetchmany", (PyCFunction) mysqlres_fetchmany, 1},
{"seek", (PyCFunction) mysqlres_seek, 1},
{"numrows", (PyCFunction) mysqlres_numrows, 1},
{"numfields", (PyCFunction) mysqlres_numfields, 1},
{"eof", (PyCFunction) mysqlres_eof, 1},
{"affectedrows", (PyCFunction) mysqlres_affectedrows, 1},
{"insert_id", (PyCFunction)mysqlres_insertid, 1},
{NULL, NULL}
};
static PyObject *
newmysqlres(MYSQL_RES *res, MYSQL conn)
{
mysqlres *self;
self = PyObject_NEW(mysqlres, &ResType);
if (self == NULL)
return NULL;
self->res = res;
self->affected_rows = conn.affected_rows;
self->insert_id = conn.insert_id;
return (PyObject *) self;
}
static PyObject *
mysqlres_getattr(ms, name)
mysqlres *ms;
char *name;
{
return Py_FindMethod(mysqlres_methods, (PyObject *) ms, name);
}
static void
mysqlres_dealloc(m)
register mysqlres *m;
{
if (m->res != NULL)
mysql_free_result(m->res);
PyMem_DEL(m);
}
static PyTypeObject ResType =
{
PyObject_HEAD_INIT(&PyType_Type)
0,
"mysqlres",
sizeof(mysqlres),
0,
(destructor) mysqlres_dealloc, /*tp_dealloc */
0, /*tp_print */
(getattrfunc) mysqlres_getattr, /*tp_getattr */
0, /*tp_setattr */
0, /*tp_compare */
0, /*tp_repr */
0, /*tp_as_number */
0, /*tp_as_sequence */
0, /*tp_as_mapping */
};
static struct PyMethodDef mysql_methods[] =
{
{"connect", mysqlmod_connect, 1},
{NULL, NULL}
};
void
initmySQL()
{
PyObject *module, *dict;
module = Py_InitModule("mySQL", mysql_methods);
dict = PyModule_GetDict(module);
if (PyDict_SetItemString(dict, "DbType", (PyObject *) & MsqlType) != 0)
Py_FatalError("Cannot add to mySQL dictionary");
if (PyDict_SetItemString(dict, "CursorType", (PyObject *) & ResType) != 0)
Py_FatalError("Cannot add to mySQL dictionary");
mySQLError = PyString_FromString("mySQL.error");
if (PyDict_SetItemString(dict, "error", mySQLError) != 0)
Py_FatalError("Cannot add to mySQL dictionary");
}