⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 storage_mysql.c

📁 这是一个完全开放的
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * jabberd - Jabber Open Source Server * Copyright (c) 2002-2003 Jeremie Miller, Thomas Muldowney, *                         Ryan Eatmon, Robert Norris * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA *//** @file sm/storage_mysql.c  * @brief mysql storage module  * @author Robert Norris  * $Date: 2004/11/13 16:08:33 $  * $Revision: 1.13.2.6 $  */#include "sm.h"#ifdef STORAGE_MYSQL#include <mysql.h>/** internal structure, holds our data */typedef struct drvdata_st {    MYSQL *conn;    char *prefix;    xht filters;    int txn;} *drvdata_t;#define FALLBACK_BLOCKSIZE (4096)/** internal: do and return the math and ensure it gets realloc'd */static size_t _st_mysql_realloc(void **oblocks, size_t len) {    void *nblocks;    size_t nlen;    static size_t block_size = 0;    if (block_size == 0) {#ifdef HAVE_GETPAGESIZE        block_size = getpagesize();#elif defined(_SC_PAGESIZE)        block_size = sysconf(_SC_PAGESIZE);#elif defined(_SC_PAGE_SIZE)        block_size = sysconf(_SC_PAGE_SIZE);    #else        block_size = FALLBACK_BLOCKSIZE;#endif    }    /* round up to standard block sizes */    nlen = (((len-1)/block_size)+1)*block_size;    /* keep trying till we get it */    while((nblocks = realloc(*oblocks, nlen)) == NULL) sleep(1);    *oblocks = nblocks;    return nlen;}/** this is the safety check used to make sure there's always enough mem */#define MYSQL_SAFE(blocks, size, len) if((size) >= len) len = _st_mysql_realloc((void**)&(blocks),(size + 1));static void _st_mysql_convert_filter_recursive(st_driver_t drv, st_filter_t f, char **buf, int *buflen, int *nbuf) {    drvdata_t data = (drvdata_t) drv->private;    st_filter_t scan;     char *cval;    int vlen;    switch(f->type) {        case st_filter_type_PAIR:            /* do sql escape processing of f->val */            cval = (char *) malloc(sizeof(char) * ((strlen((char *) f->val) * 2) + 1));            vlen = mysql_real_escape_string(data->conn, cval, (char *) f->val, strlen((char *) f->val));            MYSQL_SAFE((*buf), *buflen + 12 + vlen - strlen(f->val), *buflen);            *nbuf += sprintf(&((*buf)[*nbuf]), "( `%s` = \'%s\' ) ", f->key, cval);            free(cval);            break;        case st_filter_type_AND:            MYSQL_SAFE((*buf), *buflen + 2, *buflen);            *nbuf += sprintf(&((*buf)[*nbuf]), "( ");            for(scan = f->sub; scan != NULL; scan = scan->next) {                _st_mysql_convert_filter_recursive(drv, scan, buf, buflen, nbuf);                if(scan->next != NULL) {                    MYSQL_SAFE((*buf), *buflen + 4, *buflen);                    *nbuf += sprintf(&((*buf)[*nbuf]), "AND ");                }            }            MYSQL_SAFE((*buf), *buflen + 2, *buflen);            *nbuf += sprintf(&((*buf)[*nbuf]), ") ");            return;        case st_filter_type_OR:            MYSQL_SAFE((*buf), *buflen + 2, *buflen);            *nbuf += sprintf(&((*buf)[*nbuf]), "( ");            for(scan = f->sub; scan != NULL; scan = scan->next) {                _st_mysql_convert_filter_recursive(drv, scan, buf, buflen, nbuf);                if(scan->next != NULL) {                    MYSQL_SAFE((*buf), *buflen + 3, *buflen);                    *nbuf += sprintf(&((*buf)[*nbuf]), "OR ");                }            }            MYSQL_SAFE((*buf), *buflen + 2, *buflen);            *nbuf += sprintf(&((*buf)[*nbuf]), ") ");            return;        case st_filter_type_NOT:            MYSQL_SAFE((*buf), *buflen + 6, *buflen);            *nbuf += sprintf(&((*buf)[*nbuf]), "( NOT ");            _st_mysql_convert_filter_recursive(drv, f->sub, buf, buflen, nbuf);            MYSQL_SAFE((*buf), *buflen + 2, *buflen);            *nbuf += sprintf(&((*buf)[*nbuf]), ") ");            return;    }}static char *_st_mysql_convert_filter(st_driver_t drv, const char *owner, const char *filter) {    drvdata_t data = (drvdata_t) drv->private;    char *buf = NULL, *sbuf = NULL, *cfilter;    int buflen = 0, nbuf = 0, fbuf;    st_filter_t f;    MYSQL_SAFE(buf, 24 + strlen(owner), buflen);    nbuf = sprintf(buf, "`collection-owner` = '%s'", owner);    sbuf = xhash_get(data->filters, filter);    if(sbuf != NULL) {        MYSQL_SAFE(buf, buflen + strlen(sbuf) + 7, buflen);        nbuf += sprintf(&buf[nbuf], " AND %s", sbuf);        return buf;    }    cfilter = pstrdup(xhash_pool(data->filters), filter);    f = storage_filter(filter);    if(f == NULL)        return buf;    MYSQL_SAFE(buf, buflen + 5, buflen);    nbuf += sprintf(&buf[nbuf], " AND ");    fbuf = nbuf;    _st_mysql_convert_filter_recursive(drv, f, &buf, &buflen, &nbuf);    xhash_put(data->filters, cfilter, pstrdup(xhash_pool(data->filters), &buf[fbuf]));    pool_free(f->p);    return buf;}static st_ret_t _st_mysql_add_type(st_driver_t drv, const char *type) {    return st_SUCCESS;}static st_ret_t _st_mysql_put_guts(st_driver_t drv, const char *type, const char *owner, os_t os) {    drvdata_t data = (drvdata_t) drv->private;    char *left = NULL, *right = NULL;    int lleft = 0, lright = 0, nleft, nright;    os_object_t o;    char *key, *cval = NULL;    void *val;    int vlen;    os_type_t ot;    char *xml;    int xlen;    char tbuf[128];    if(os_count(os) == 0)        return st_SUCCESS;    if(data->prefix != NULL) {        snprintf(tbuf, sizeof(tbuf), "%s%s", data->prefix, type);        type = tbuf;    }    if(os_iter_first(os))        do {            MYSQL_SAFE(left, strlen(type) + 36, lleft);            nleft = sprintf(left, "INSERT INTO `%s` ( `collection-owner`", type);                MYSQL_SAFE(right, strlen(owner) + 15, lright);            nright = sprintf(right, " ) VALUES ( '%s'", owner);                o = os_iter_object(os);            if(os_object_iter_first(o))                do {                    os_object_iter_get(o, &key, &val, &ot);                            switch(ot) {                        case os_type_BOOLEAN:                            cval = val ? strdup("1") : strdup("0");                            vlen = 1;                            break;                                case os_type_INTEGER:                            cval = (char *) malloc(sizeof(char) * 20);                            sprintf(cval, "%d", (int) val);                            vlen = strlen(cval);                            break;                                case os_type_STRING:                            cval = (char *) malloc(sizeof(char) * ((strlen((char *) val) * 2) + 1));                            vlen = mysql_real_escape_string(data->conn, cval, (char *) val, strlen((char *) val));                            break;                                /* !!! might not be a good idea to mark nads this way */                        case os_type_NAD:                            nad_print((nad_t) val, 0, &xml, &xlen);                            cval = (char *) malloc(sizeof(char) * ((xlen * 2) + 4));                            vlen = mysql_real_escape_string(data->conn, &cval[3], xml, xlen) + 3;                            strncpy(cval, "NAD", 3);                            break;                    }                            log_debug(ZONE, "key %s val %s", key, cval);                            MYSQL_SAFE(left, lleft + strlen(key) + 4, lleft);                    nleft += sprintf(&left[nleft], ", `%s`", key);                            MYSQL_SAFE(right, lright + strlen(cval) + 4, lright);                    nright += sprintf(&right[nright], ", '%s'", cval);                            free(cval);                } while(os_object_iter_next(o));                MYSQL_SAFE(left, lleft + strlen(right) + 2, lleft);            sprintf(&left[nleft], "%s )", right);                    log_debug(ZONE, "prepared sql: %s", left);                if(mysql_query(data->conn, left) != 0) {                log_write(drv->st->sm->log, LOG_ERR, "mysql: sql insert failed: %s", mysql_error(data->conn));                free(left);                free(right);                return st_FAILED;            }            } while(os_iter_next(os));    free(left);    free(right);    return st_SUCCESS;}static st_ret_t _st_mysql_put(st_driver_t drv, const char *type, const char *owner, os_t os) {    drvdata_t data = (drvdata_t) drv->private;    if(os_count(os) == 0)        return st_SUCCESS;    if(mysql_ping(data->conn) != 0) {        log_write(drv->st->sm->log, LOG_ERR, "mysql: connection to database lost");        return st_FAILED;    }    if(data->txn) {        if(mysql_query(data->conn, "SET TRANSACTION ISOLATION LEVEL SERIALIZABLE") != 0) {            log_write(drv->st->sm->log, LOG_ERR, "mysql: sql transaction setup failed: %s", mysql_error(data->conn));            return st_FAILED;        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -