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

📄 storage_mysql.c

📁 这是一个完全开放的
💻 C
📖 第 1 页 / 共 2 页
字号:
        if(mysql_query(data->conn, "BEGIN") != 0) {            log_write(drv->st->sm->log, LOG_ERR, "mysql: sql transaction begin failed: %s", mysql_error(data->conn));            return st_FAILED;        }    }    if(_st_mysql_put_guts(drv, type, owner, os) != st_SUCCESS) {        if(data->txn)            mysql_query(data->conn, "ROLLBACK");        return st_FAILED;    }    if(data->txn)        if(mysql_query(data->conn, "COMMIT") != 0) {            log_write(drv->st->sm->log, LOG_ERR, "mysql: sql transaction commit failed: %s", mysql_error(data->conn));            mysql_query(data->conn, "ROLLBACK");            return st_FAILED;        }    return st_SUCCESS;}static st_ret_t _st_mysql_get(st_driver_t drv, const char *type, const char *owner, const char *filter, os_t *os) {    drvdata_t data = (drvdata_t) drv->private;    char *cond, *buf = NULL;    int buflen = 0;    MYSQL_RES *res;    int ntuples, nfields, i, j;    MYSQL_FIELD *fields;    MYSQL_ROW tuple;    unsigned long *lengths;    os_object_t o;    char *val;    os_type_t ot;    int ival;    nad_t nad;    char tbuf[128];    if(mysql_ping(data->conn) != 0) {        log_write(drv->st->sm->log, LOG_ERR, "mysql: connection to database lost");        return st_FAILED;    }    if(data->prefix != NULL) {        snprintf(tbuf, sizeof(tbuf), "%s%s", data->prefix, type);        type = tbuf;    }    cond = _st_mysql_convert_filter(drv, owner, filter);    log_debug(ZONE, "generated filter: %s", cond);    MYSQL_SAFE(buf, strlen(type) + strlen(cond) + 50, buflen);    sprintf(buf, "SELECT * FROM `%s` WHERE %s ORDER BY `object-sequence`", type, cond);    free(cond);    log_debug(ZONE, "prepared sql: %s", buf);    if(mysql_query(data->conn, buf) != 0) {        log_write(drv->st->sm->log, LOG_ERR, "mysql: sql select failed: %s", mysql_error(data->conn));        free(buf);        return st_FAILED;    }    free(buf);    res = mysql_store_result(data->conn);    if(res == NULL) {        log_write(drv->st->sm->log, LOG_ERR, "mysql: sql result retrieval failed: %s", mysql_error(data->conn));        return st_FAILED;    }    ntuples = mysql_num_rows(res);    if(ntuples == 0) {        mysql_free_result(res);        return st_NOTFOUND;    }    log_debug(ZONE, "%d tuples returned", ntuples);    nfields = mysql_num_fields(res);    if(nfields == 0) {        log_debug(ZONE, "weird, tuples were returned but no fields *shrug*");        mysql_free_result(res);        return st_NOTFOUND;    }    fields = mysql_fetch_fields(res);    *os = os_new();    for(i = 0; i < ntuples; i++) {        o = os_object_new(*os);        if((tuple = mysql_fetch_row(res)) == NULL)            break;        for(j = 0; j < nfields; j++) {            if(strcmp(fields[j].name, "collection-owner") == 0 || strcmp(fields[j].name, "object-sequence") == 0)                continue;            if(tuple[j] == NULL)                continue;            lengths = mysql_fetch_lengths(res);            switch(fields[j].type) {                case FIELD_TYPE_TINY:   /* tinyint */                    ot = os_type_BOOLEAN;                    break;                case FIELD_TYPE_LONG:   /* integer */                    ot = os_type_INTEGER;                    break;                case FIELD_TYPE_BLOB:   /* text */                    ot = os_type_STRING;                    break;                default:                    log_debug(ZONE, "unknown field type %d, ignoring it", fields[j].type);                    continue;            }            val = tuple[j];            switch(ot) {                case os_type_BOOLEAN:                    ival = (val[0] == '0') ? 0 : 1;                    os_object_put(o, fields[j].name, &ival, ot);                    break;                case os_type_INTEGER:                    ival = atoi(val);                    os_object_put(o, fields[j].name, &ival, ot);                    break;                case os_type_STRING:                    os_object_put(o, fields[j].name, val, os_type_STRING);                    break;            }        }    }    mysql_free_result(res);    return st_SUCCESS;}static st_ret_t _st_mysql_delete(st_driver_t drv, const char *type, const char *owner, const char *filter) {    drvdata_t data = (drvdata_t) drv->private;    char *cond, *buf = NULL;    int buflen = 0;    char tbuf[128];    if(mysql_ping(data->conn) != 0) {        log_write(drv->st->sm->log, LOG_ERR, "mysql: connection to database lost");        return st_FAILED;    }    if(data->prefix != NULL) {        snprintf(tbuf, sizeof(tbuf), "%s%s", data->prefix, type);        type = tbuf;    }    cond = _st_mysql_convert_filter(drv, owner, filter);    log_debug(ZONE, "generated filter: %s", cond);    MYSQL_SAFE(buf, strlen(type) + strlen(cond) + 19, buflen);    sprintf(buf, "DELETE FROM `%s` WHERE %s", type, cond);    free(cond);    log_debug(ZONE, "prepared sql: %s", buf);    if(mysql_query(data->conn, buf) != 0) {        log_write(drv->st->sm->log, LOG_ERR, "mysql: sql delete failed: %s", mysql_error(data->conn));        free(buf);        return st_FAILED;    }    free(buf);    return st_SUCCESS;}static st_ret_t _st_mysql_replace(st_driver_t drv, const char *type, const char *owner, const char *filter, os_t os) {    drvdata_t data = (drvdata_t) drv->private;    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;        }        if(mysql_query(data->conn, "BEGIN") != 0) {            log_write(drv->st->sm->log, LOG_ERR, "mysql: sql transaction begin failed: %s", mysql_error(data->conn));            return st_FAILED;        }    }    if(_st_mysql_delete(drv, type, owner, filter) == st_FAILED) {        if(data->txn)            mysql_query(data->conn, "ROLLBACK");        return st_FAILED;    }    if(_st_mysql_put_guts(drv, type, owner, os) == st_FAILED) {        if(data->txn)            mysql_query(data->conn, "ROLLBACK");        return st_FAILED;    }    if(data->txn)        if(mysql_query(data->conn, "COMMIT") != 0) {            log_write(drv->st->sm->log, LOG_ERR, "mysql: sql transaction commit failed: %s", mysql_error(data->conn));            mysql_query(data->conn, "ROLLBACK");            return st_FAILED;        }    return st_SUCCESS;}static void _st_mysql_free(st_driver_t drv) {    drvdata_t data = (drvdata_t) drv->private;    mysql_close(data->conn);    xhash_free(data->filters);    free(data);}st_ret_t st_mysql_init(st_driver_t drv) {    char *host, *port, *dbname, *user, *pass;    MYSQL *conn;    drvdata_t data;    host = config_get_one(drv->st->sm->config, "storage.mysql.host", 0);    port = config_get_one(drv->st->sm->config, "storage.mysql.port", 0);    dbname = config_get_one(drv->st->sm->config, "storage.mysql.dbname", 0);    user = config_get_one(drv->st->sm->config, "storage.mysql.user", 0);    pass = config_get_one(drv->st->sm->config, "storage.mysql.pass", 0);    if(host == NULL || port == NULL || dbname == NULL || user == NULL || pass == NULL) {        log_write(drv->st->sm->log, LOG_ERR, "mysql: invalid driver config");        return st_FAILED;    }    conn = mysql_init(NULL);    if(conn == NULL) {        log_write(drv->st->sm->log, LOG_ERR, "mysql: unable to allocate database connection state");        return st_FAILED;    }    if(mysql_real_connect(conn, host, user, pass, dbname, atoi(port), NULL, 0) == NULL) {        log_write(drv->st->sm->log, LOG_ERR, "mysql: connection to database failed: %s", mysql_error(conn));        mysql_close(conn);        return 1;    }    data = (drvdata_t) malloc(sizeof(struct drvdata_st));    memset(data, 0, sizeof(struct drvdata_st));    data->conn = conn;    data->filters = xhash_new(17);    if(config_get_one(drv->st->sm->config, "storage.mysql.transactions", 0) != NULL)        data->txn = 1;    else        log_write(drv->st->sm->log, LOG_WARNING, "mysql: transactions disabled");    data->prefix = config_get_one(drv->st->sm->config, "storage.mysql.prefix", 0);    drv->private = (void *) data;    drv->add_type = _st_mysql_add_type;    drv->put = _st_mysql_put;    drv->get = _st_mysql_get;    drv->delete = _st_mysql_delete;    drv->replace = _st_mysql_replace;    drv->free = _st_mysql_free;    return st_SUCCESS;}#endif

⌨️ 快捷键说明

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