用C为python3.1封装mysql接口(一)

3.1没mysql模块? 或者没找到。。。来了兴致,自己封装了下

用C为python3.1写的mysql接口的胶水代码:

/*main.cpp 指定编译为C代码,工程设置为dll,编译后得到的模块名.dll 修改为模块名.pyd*/
#include <Python.h> 
#include <mysql/mysql.h>

struct my_sqldata
{
    MYSQL mysql_conn;        //用于连接mysql的
    MYSQL_RES *mysql_result;//查询后的结果
    MYSQL_ROW curren_row;    //当前行

    unsigned int num_row;    //查询的结果集的行数
    unsigned int num_col;    //此次查询的行的列数

    unsigned int cur_row;    //当前行
    unsigned int cur_col;    //当前列

    unsigned int affected_rownum;    //受影响的行数
    int m_isconnect;        //是否连接上  1则连上
    int m_isfree;            //是否被释放  1表示释放
};


//连接数据库
static  int my_sql_connect(void *temp, char *host, char *user, char *passwd,  char *db, unsigned int port, char *unix_socket, unsigned long  clientflag)
{
    struct my_sqldata *mysql_conn = (struct my_sqldata*)(temp);
    if(!mysql_conn)
        return -1;
    if((mysql_conn->m_isfree == 1) || (mysql_conn->m_isconnect == 1))//已释放或者已连接上。则返回
        return -1;
     if(mysql_real_connect(&mysql_conn->mysql_conn, host, user,  passwd, db, port, unix_socket, clientflag) != NULL)//非NULL表示成功
    {
        mysql_conn->m_isconnect = 1;//已连接上
        return 0;
    }
    else
        return -1;
}
//返回初始化成功的用于连接mysql的handle
//成功返回指针。失败返回NULL
static void *my_sql_init()
{
    struct my_sqldata *mycon = (struct my_sqldata*)malloc(sizeof(struct my_sqldata));
    if(!mycon)
        return NULL;
    memset(mycon, 0, sizeof(struct my_sqldata));
    if(mysql_init(&mycon->mysql_conn) != NULL)//初始化成功
    {
        return (void*)mycon;
    }
    else
    {
        free(mycon);//先释放
        return NULL;
    }
}

//关闭用于mysql数据库连接的handle
static int my_sql_close(void *temp)
{
    int closeresult = 0;
    struct my_sqldata *mycon = (struct my_sqldata*)temp;
    if(!mycon)
        return -1;
    if(mycon->m_isfree == 1)//释放过了。
        return -1;
    if(mycon->mysql_result != NULL)//如果结果集非空。则释放他
    {
        mysql_free_result(mycon->mysql_result);
    }
    mysql_close(&mycon->mysql_conn);    //关闭
    memset(mycon, 0, sizeof(struct my_sqldata));//清空
    mycon->m_isfree = 1;    //表示已释放
    free(mycon);//释放
    return 0;
}

//设置字符编码
static int my_sql_set_coding(void *temp, char *coding)
{
    struct my_sqldata *mysql_conn = (struct my_sqldata*)temp;
    if((!mysql_conn)||(!coding))
        return -1;
    if((mysql_conn->m_isfree == 1) ||(mysql_conn->m_isconnect != 1))//释放过了或者未连接上
        return -1;
    if(mysql_set_character_set(&mysql_conn->mysql_conn, coding) == 0)//成功
        return 0;
    else
        return -1;
}

//返回在此数据库连接上查询的结果
//参数mysql_conn为已经建立的合法的连接
//query为以字符''为结尾的字串
//查询/更新/插入成功返回受影响的行数,失败返回-1
static int my_sql_query(void *temp, char *query)
{
    unsigned int len = strlen(query);
    struct my_sqldata *mysql_conn = (struct my_sqldata*)temp;
    if((!mysql_conn)||(!query))//任一为NULL。则返回NULL
        return -1;
    if(len == 0)
        return -1;
    if((mysql_conn->m_isfree == 1) ||(mysql_conn->m_isconnect != 1))//释放过了或者未连接上
        return -1;
    if(mysql_real_query(&mysql_conn->mysql_conn, query, len) != 0)//非0则查询失败
        return -1;
    mysql_conn->mysql_result = mysql_store_result(&mysql_conn->mysql_conn);
    if(!mysql_conn->mysql_result)//装入查询结果,如果是update,insert等。可能会走到这块
    {
        mysql_conn->affected_rownum = mysql_affected_rows(&mysql_conn->mysql_conn);
        return mysql_conn->affected_rownum;
    }
    mysql_conn->cur_col = 0;//当前列
    mysql_conn->cur_row = 0;//当前行
    mysql_conn->num_row = mysql_num_rows(mysql_conn->mysql_result);    //获取此次查询结果的行数
    mysql_conn->num_col = mysql_num_fields(mysql_conn->mysql_result);//获取列数
    mysql_conn->affected_rownum = mysql_affected_rows(&mysql_conn->mysql_conn);

    return mysql_conn->affected_rownum;
}

//获取受影响的行数
static int my_sql_get_affectedrows(void *temp)
{
    struct my_sqldata *mysql_conn = (struct my_sqldata*)temp;
    if(!temp)
        return -1;
    if((mysql_conn->m_isfree == 1) ||(mysql_conn->m_isconnect != 1))//释放过或者未连接上
    {
        return -1;
    }
    return mysql_conn->affected_rownum;
}

//获取下一个字段,最早返回第0字段
static char *my_sql_get_field(void *temp, int index)
{
    struct my_sqldata *mysql_conn = (struct my_sqldata*)temp;
    unsigned int numcol;
    if(!mysql_conn)
        return NULL;
    if((mysql_conn->m_isfree == 1) ||(mysql_conn->m_isconnect != 1))//释放过了或者未连接上
        return NULL;
    if(mysql_conn->curren_row == NULL)//当前行为NULL,则返回NULL
    {
        return NULL;
    }
    if(mysql_conn->cur_col >= mysql_conn->num_col)//当前列大于等于总列数
        return NULL;
    if(index != -1)//要获取指定的列
    {
        if((index >= 0)&&(index < mysql_conn->num_col))//指定的列号在合法范围内
        {
            mysql_conn->cur_col = index;         //重置当前列号
            return mysql_conn->curren_row[index];//返回所需的列
        }
    }
    if(index == -1)//获取下一列
    {
        numcol = mysql_conn->cur_col;
        mysql_conn->cur_col++;
        return mysql_conn->curren_row[numcol];
    }
    return NULL;
}

//返回当前列序号
static int my_sql_get_curcol(void *temp)
{
    struct my_sqldata *mysql_conn = (struct my_sqldata*)temp;
    if(!mysql_conn)
        return -1;
    if(mysql_conn->m_isfree == 1)//释放过了
        return -1;
    if(mysql_conn->cur_col > 0)//获取过行中的字段
        return mysql_conn->cur_col - 1;
    else
        return mysql_conn->cur_col;
}

//返回当前行序号
static int my_sql_get_currow(void *temp)
{
    struct my_sqldata *mysql_conn = (struct my_sqldata*)temp;
    if(!mysql_conn)
        return -1;
    if(mysql_conn->m_isfree == 1)//释放过了
        return -1;
    if(mysql_conn->cur_row > 0)//从结果集中装入过行
        return mysql_conn->cur_row - 1;
    else
        return mysql_conn->cur_row;

}
//接入新的一行,第一次调用的时候。获取第0行
//返回当前行
static int my_sql_fetch_row(void *temp)
{
    unsigned int numrow;
    struct my_sqldata *mysql_conn = (struct my_sqldata*)temp;
    if(!mysql_conn)
        return -1;
    if((mysql_conn->m_isfree == 1) ||(mysql_conn->m_isconnect != 1))//释放过了或者未连接上
        return -1;
    if(mysql_conn->cur_row >= mysql_conn->num_row)//当前行大于等于总行数
        return -1;
    mysql_conn->curren_row = mysql_fetch_row(mysql_conn->mysql_result);
    if(mysql_conn->curren_row == NULL)
        return -1;
    mysql_conn->cur_col = 0;
    numrow = mysql_conn->cur_row;
    mysql_conn->cur_row++;
    return numrow;
}
//获取总行数
static unsigned int my_sql_get_numrow(void *temp)
{
    struct my_sqldata *mysql_conn = (struct my_sqldata*)temp;
    if(!mysql_conn)
        return 0;
    if(mysql_conn->m_isfree == 1)//释放过了
        return 0;
    return mysql_conn->num_row;
}
//获取总列数
static unsigned int my_sql_get_numcol(void *temp)
{
    struct my_sqldata *mysql_conn = (struct my_sqldata*)temp;
    if(!mysql_conn)
        return 0;
    if(mysql_conn->m_isfree == 1)//释放过了
        return 0;
    return mysql_conn->num_col;
}
//获取错误信息
static char *my_sql_error(void *temp)
{
    struct my_sqldata *mysql_conn = (struct my_sqldata*)temp;
    if(!mysql_conn)
        return NULL;
    if((mysql_conn->m_isfree == 1) ||(mysql_conn->m_isconnect != 1))//释放过了或者未连接上
        return NULL;
    return (char*)mysql_error(&mysql_conn->mysql_conn);
}


static PyObject *_my_sql_connect(PyObject *self, PyObject *args)
{
    unsigned int temp = 0;
    char *host = NULL;
    char *user = NULL;
    char *passwd = NULL;
    char *db = NULL;
    unsigned int port = 0;
    char *unix_socket = NULL;
    unsigned long clientflag = 0;

    int result = 0;
     if(!PyArg_ParseTuple(args, "issssisl", &temp, &host,  &user, &passwd, &db, &port, &unix_socket,  &clientflag))
        return NULL;
    result = my_sql_connect((void*)temp, host, user, passwd, db, port, unix_socket, clientflag);
    return Py_BuildValue("i", result);
}

static PyObject *_my_sql_init(PyObject *self, PyObject *args)
{
    unsigned int temp = 0;
    temp = (unsigned int)my_sql_init();
    return Py_BuildValue("i", temp);
}
static PyObject *_my_sql_close(PyObject *self, PyObject *args)
{
    unsigned int temp = 0;
    int result = 0;
    if(!PyArg_ParseTuple(args, "i", &temp))
        return NULL;
    result = my_sql_close((void*)temp);
    return Py_BuildValue("i", result);
}

static PyObject *_my_sql_set_coding(PyObject *self, PyObject *args)
{
    unsigned int temp = 0;
    int result = 0;
    char *coding = NULL;
    if(!PyArg_ParseTuple(args, "is", &temp, &coding))
        return NULL;
    result = my_sql_set_coding((void*)temp, coding);
    return Py_BuildValue("i", result);
}
static PyObject *_my_sql_query(PyObject *self, PyObject *args)
{
    unsigned int temp = 0;
    char *query = NULL;
    int result = 0;
    if(!PyArg_ParseTuple(args, "is", &temp, &query))
        return NULL;
    result = my_sql_query((void*)temp, query);
    return Py_BuildValue("i", result);
}
static PyObject *_my_sql_get_affectedrows(PyObject *self, PyObject *args)
{
    unsigned int temp = 0;
    int affects = 0;
    if(!PyArg_ParseTuple(args, "i", &temp))
        return NULL;
    affects = my_sql_get_affectedrows((void*)temp);
    return Py_BuildValue("i", affects);
}
static PyObject *_my_sql_fetch_row(PyObject *self, PyObject *args)
{
    unsigned int temp = 0;
    int result = 0;
    if(!PyArg_ParseTuple(args, "i", &temp))
        return NULL;
    result = my_sql_fetch_row((void*)temp);
    return Py_BuildValue("i", result);
}
static PyObject *_my_sql_get_field(PyObject *self, PyObject *args)
{
    unsigned int temp = 0;
    int index = 0;
    char *nextfield = NULL;
    if(!PyArg_ParseTuple(args, "ii", &temp, &index))
        return NULL;
    nextfield = my_sql_get_field((void*)temp, index);
    return Py_BuildValue("s", nextfield);
}
static PyObject *_my_sql_get_currow(PyObject *self, PyObject *args)
{
    unsigned int temp = 0;
    unsigned int currowid = 0;
    if(!PyArg_ParseTuple(args, "i", &temp))
        return NULL;
    currowid = my_sql_get_currow((void*)temp);
    return Py_BuildValue("i", currowid);
}

static PyObject *_my_sql_get_curcol(PyObject *self, PyObject *args)
{
    unsigned int temp = 0;
    unsigned int curcolid = 0;
    if(!PyArg_ParseTuple(args, "i", &temp))
        return NULL;
    curcolid = my_sql_get_curcol((void*)temp);
    return Py_BuildValue("i", curcolid);
}

static PyObject *_my_sql_get_numrow(PyObject *self, PyObject *args)
{
    unsigned int temp = 0;
    unsigned int rowscount = 0;
    if(!PyArg_ParseTuple(args, "i", &temp))
        return NULL;
    rowscount = my_sql_get_numrow((void*)temp);
    return Py_BuildValue("i", rowscount);
}

static PyObject *_my_sql_get_numcol(PyObject *self, PyObject *args)
{
    unsigned int temp = 0;
    unsigned int colscount = 0;
    if(!PyArg_ParseTuple(args, "i", &temp))
        return NULL;
    colscount = my_sql_get_numcol((void*)temp);
    return Py_BuildValue("i", colscount);
}
static PyObject *_my_sql_error(PyObject *self, PyObject *args)
{
    unsigned int temp = 0;
    char *error = NULL;
    if(!PyArg_ParseTuple(args, "i", &temp))
        return NULL;
    error = my_sql_error((void*)temp);
    return Py_BuildValue("s", error);
}
static PyMethodDef mytestMethods[] =
{
//    {"mystrlen",        my_strlen,                    METH_VARARGS, "We test strlen of C"},
//    {"mystrcat",        my_strcat,                    METH_VARARGS, "We test strcat of C"},
    {"connect",            _my_sql_connect,            METH_VARARGS, "We test connect of C"},
    {"creat",            _my_sql_init,                METH_VARARGS, "We test creat of C"},
    {"close",            _my_sql_close,                METH_VARARGS, "We test close of C"},
    {"setcoding",        _my_sql_set_coding,            METH_VARARGS, "We test setcoding of C"},
    {"query",            _my_sql_query,                METH_VARARGS, "We test query of C"},
    {"affects",            _my_sql_get_affectedrows,    METH_VARARGS, "We test affectedrowsnum of C"},
    {"fetchnextrow",    _my_sql_fetch_row,            METH_VARARGS, "We test fetchrow of C"},
    {"nextfield",        _my_sql_get_field,            METH_VARARGS, "We test nextfield of C"},
    {"currowid",        _my_sql_get_currow,            METH_VARARGS, "We test currowid of C"},
    {"curcolid",        _my_sql_get_curcol,            METH_VARARGS, "We test curcolid of C"},
    {"rowscount",        _my_sql_get_numrow,            METH_VARARGS, "We test getrowscount of C"},
    {"colscount",        _my_sql_get_numcol,            METH_VARARGS, "We test getcolscount of C"},
    {"error",            _my_sql_error,                METH_VARARGS, "We test error of C"},
    {NULL, NULL, 0, NULL}
};
char name[] = "mytest";
static PyModuleDef mytestModule;

_declspec(dllexport)void PyInit__mytest()
{
    memset(&mytestModule, 0, sizeof(PyModuleDef));
    mytestModule.m_methods = mytestMethods;
    mytestModule.m_name = name;
    PyModule_Create2(&mytestModule, PYTHON_API_VERSION);
}
原文地址:https://www.cnblogs.com/lcinx/p/10570424.html