apr_dbd_mysql.c

来自「linux网络服务器工具」· C语言 代码 · 共 1,277 行 · 第 1/3 页

C
1,277
字号
        case APR_DBD_TYPE_ZTIMESTAMP:            *((char*)bind->buffer+bind->buffer_length-1) = '\0';            *(char**)data = bind->buffer;            break;        case APR_DBD_TYPE_BLOB:        case APR_DBD_TYPE_CLOB:            {            apr_bucket *e;            apr_bucket_brigade *b = (apr_bucket_brigade*)data;            e = apr_bucket_lob_create(row, n, 0, len,                                      row->res->pool, b->bucket_alloc);            APR_BRIGADE_INSERT_TAIL(b, e);            }            break;        case APR_DBD_TYPE_NULL:            *(void**)data = NULL;            break;        default:            return APR_EGENERAL;        }    }    else {        if (row->row[n] == NULL) {            return APR_ENOENT;        }        switch (type) {        case APR_DBD_TYPE_TINY:            *(char*)data = atoi(row->row[n]);            break;        case APR_DBD_TYPE_UTINY:            *(unsigned char*)data = atoi(row->row[n]);            break;        case APR_DBD_TYPE_SHORT:            *(short*)data = atoi(row->row[n]);            break;        case APR_DBD_TYPE_USHORT:            *(unsigned short*)data = atoi(row->row[n]);            break;        case APR_DBD_TYPE_INT:            *(int*)data = atoi(row->row[n]);            break;        case APR_DBD_TYPE_UINT:            *(unsigned int*)data = atoi(row->row[n]);            break;        case APR_DBD_TYPE_LONG:            *(long*)data = atol(row->row[n]);            break;        case APR_DBD_TYPE_ULONG:            *(unsigned long*)data = atol(row->row[n]);            break;        case APR_DBD_TYPE_LONGLONG:            *(apr_int64_t*)data = apr_atoi64(row->row[n]);            break;        case APR_DBD_TYPE_ULONGLONG:            *(apr_uint64_t*)data = apr_atoi64(row->row[n]);            break;        case APR_DBD_TYPE_FLOAT:            *(float*)data = atof(row->row[n]);            break;        case APR_DBD_TYPE_DOUBLE:            *(double*)data = atof(row->row[n]);            break;        case APR_DBD_TYPE_STRING:        case APR_DBD_TYPE_TEXT:        case APR_DBD_TYPE_TIME:        case APR_DBD_TYPE_DATE:        case APR_DBD_TYPE_DATETIME:        case APR_DBD_TYPE_TIMESTAMP:        case APR_DBD_TYPE_ZTIMESTAMP:            *(char**)data = row->row[n];            break;        case APR_DBD_TYPE_BLOB:        case APR_DBD_TYPE_CLOB:            {            apr_bucket *e;            apr_bucket_brigade *b = (apr_bucket_brigade*)data;            e = apr_bucket_pool_create(row->row[n], row->len[n],                                       row->res->pool, b->bucket_alloc);            APR_BRIGADE_INSERT_TAIL(b, e);            }            break;        case APR_DBD_TYPE_NULL:            *(void**)data = NULL;            break;        default:            return APR_EGENERAL;        }    }    return 0;}static const char *dbd_mysql_error(apr_dbd_t *sql, int n){    return mysql_error(sql->conn);}static int dbd_mysql_query(apr_dbd_t *sql, int *nrows, const char *query){    int ret;    if (sql->trans && sql->trans->errnum) {        return sql->trans->errnum;    }    ret = mysql_query(sql->conn, query);    if (ret != 0) {        ret = mysql_errno(sql->conn);    }    *nrows = mysql_affected_rows(sql->conn);    if (TXN_NOTICE_ERRORS(sql->trans)) {        sql->trans->errnum = ret;    }    return ret;}static const char *dbd_mysql_escape(apr_pool_t *pool, const char *arg,                                    apr_dbd_t *sql){    unsigned long len = strlen(arg);    char *ret = apr_palloc(pool, 2*len + 1);    mysql_real_escape_string(sql->conn, ret, arg, len);    return ret;}static apr_status_t stmt_close(void *data){    mysql_stmt_close(data);    return APR_SUCCESS;}static int dbd_mysql_prepare(apr_pool_t *pool, apr_dbd_t *sql,                             const char *query, const char *label,                             int nargs, int nvals, apr_dbd_type_e *types,                             apr_dbd_prepared_t **statement){    /* Translate from apr_dbd to native query format */    int ret;    if (!*statement) {        *statement = apr_palloc(pool, sizeof(apr_dbd_prepared_t));    }    (*statement)->stmt = mysql_stmt_init(sql->conn);    if ((*statement)->stmt) {        apr_pool_cleanup_register(pool, (*statement)->stmt,                                  stmt_close, apr_pool_cleanup_null);        ret = mysql_stmt_prepare((*statement)->stmt, query, strlen(query));        if (ret != 0) {            ret = mysql_stmt_errno((*statement)->stmt);        }        (*statement)->nargs = nargs;        (*statement)->nvals = nvals;        (*statement)->types = types;        return ret;    }    return CR_OUT_OF_MEMORY;}static void dbd_mysql_bind(apr_dbd_prepared_t *statement,                           const char **values, MYSQL_BIND *bind){    int i, j;    for (i = 0, j = 0; i < statement->nargs; i++, j++) {        bind[i].length = &bind[i].buffer_length;        bind[i].is_unsigned = 0;        bind[i].is_null = NULL;        if (values[j] == NULL) {            bind[i].buffer_type = MYSQL_TYPE_NULL;        }        else {            switch (statement->types[i]) {            case APR_DBD_TYPE_BLOB:            case APR_DBD_TYPE_CLOB:                bind[i].buffer_type = MYSQL_TYPE_LONG_BLOB;                bind[i].buffer = (void*)values[j];                bind[i].buffer_length = atol(values[++j]);                /* skip table and column */                j += 2;                break;            default:                bind[i].buffer_type = MYSQL_TYPE_VAR_STRING;                bind[i].buffer = (void*)values[j];                bind[i].buffer_length = strlen(values[j]);                break;            }        }    }    return;}static int dbd_mysql_pquery_internal(apr_pool_t *pool, apr_dbd_t *sql,                                     int *nrows, apr_dbd_prepared_t *statement,                                     MYSQL_BIND *bind){    int ret;    ret = mysql_stmt_bind_param(statement->stmt, bind);    if (ret != 0) {        *nrows = 0;        ret = mysql_stmt_errno(statement->stmt);    }    else {        ret = mysql_stmt_execute(statement->stmt);        if (ret != 0) {            ret = mysql_stmt_errno(statement->stmt);        }        *nrows = mysql_stmt_affected_rows(statement->stmt);    }    return ret;}static int dbd_mysql_pquery(apr_pool_t *pool, apr_dbd_t *sql,                            int *nrows, apr_dbd_prepared_t *statement,                            const char **values){    MYSQL_BIND *bind;    int ret;    if (sql->trans && sql->trans->errnum) {        return sql->trans->errnum;    }    bind = apr_palloc(pool, statement->nargs * sizeof(MYSQL_BIND));    dbd_mysql_bind(statement, values, bind);    ret = dbd_mysql_pquery_internal(pool, sql, nrows, statement, bind);    if (TXN_NOTICE_ERRORS(sql->trans)) {        sql->trans->errnum = ret;    }    return ret;}static int dbd_mysql_pvquery(apr_pool_t *pool, apr_dbd_t *sql, int *nrows,                             apr_dbd_prepared_t *statement, va_list args){    const char **values;    int i;    if (sql->trans && sql->trans->errnum) {        return sql->trans->errnum;    }    values = apr_palloc(pool, sizeof(*values) * statement->nvals);    for (i = 0; i < statement->nvals; i++) {        values[i] = va_arg(args, const char*);    }    return dbd_mysql_pquery(pool, sql, nrows, statement, values);}static int dbd_mysql_pselect_internal(apr_pool_t *pool, apr_dbd_t *sql,                                      apr_dbd_results_t **res,                                      apr_dbd_prepared_t *statement,                                      int random, MYSQL_BIND *bind){    int nfields, i;    my_bool *is_nullr;#if MYSQL_VERSION_ID >= 50000    my_bool *error;#endif    int ret;    unsigned long *length, maxlen;    ret = mysql_stmt_bind_param(statement->stmt, bind);    if (ret == 0) {        ret = mysql_stmt_execute(statement->stmt);        if (!ret) {            if (!*res) {                *res = apr_pcalloc(pool, sizeof(apr_dbd_results_t));            }            (*res)->random = random;            (*res)->statement = statement->stmt;            (*res)->res = mysql_stmt_result_metadata(statement->stmt);            (*res)->pool = pool;            apr_pool_cleanup_register(pool, (*res)->res,                                      free_result, apr_pool_cleanup_null);            nfields = mysql_num_fields((*res)->res);            if (!(*res)->bind) {                (*res)->bind = apr_palloc(pool, nfields*sizeof(MYSQL_BIND));                length = apr_pcalloc(pool, nfields*sizeof(unsigned long));#if MYSQL_VERSION_ID >= 50000                error = apr_palloc(pool, nfields*sizeof(my_bool));#endif                is_nullr = apr_pcalloc(pool, nfields*sizeof(my_bool));                for ( i = 0; i < nfields; ++i ) {                    maxlen = ((*res)->res->fields[i].length < sql->fldsz ?                              (*res)->res->fields[i].length : sql->fldsz) + 1;                    if ((*res)->res->fields[i].type == MYSQL_TYPE_BLOB) {                        (*res)->bind[i].buffer_type = MYSQL_TYPE_LONG_BLOB;                    }                    else {                        (*res)->bind[i].buffer_type = MYSQL_TYPE_VAR_STRING;                    }                    (*res)->bind[i].buffer_length = maxlen;                    (*res)->bind[i].length = &length[i];                    (*res)->bind[i].buffer = apr_palloc(pool, maxlen);                    (*res)->bind[i].is_null = is_nullr+i;#if MYSQL_VERSION_ID >= 50000                    (*res)->bind[i].error = error+i;#endif                }            }            ret = mysql_stmt_bind_result(statement->stmt, (*res)->bind);            if (!ret) {                ret = mysql_stmt_store_result(statement->stmt);            }        }    }    if (ret != 0) {        ret = mysql_stmt_errno(statement->stmt);    }    return ret;}static int dbd_mysql_pselect(apr_pool_t *pool, apr_dbd_t *sql,                             apr_dbd_results_t **res,                             apr_dbd_prepared_t *statement, int random,                             const char **args){    int ret;    MYSQL_BIND *bind;    if (sql->trans && sql->trans->errnum) {        return sql->trans->errnum;    }    bind = apr_palloc(pool, statement->nargs * sizeof(MYSQL_BIND));    dbd_mysql_bind(statement, args, bind);    ret = dbd_mysql_pselect_internal(pool, sql,  res, statement, random, bind);    if (TXN_NOTICE_ERRORS(sql->trans)) {        sql->trans->errnum = ret;    }    return ret;}static int dbd_mysql_pvselect(apr_pool_t *pool, apr_dbd_t *sql,                              apr_dbd_results_t **res,                              apr_dbd_prepared_t *statement, int random,                              va_list args){    const char **values;    int i;    if (sql->trans && sql->trans->errnum) {        return sql->trans->errnum;    }    values = apr_palloc(pool, sizeof(*values) * statement->nvals);    for (i = 0; i < statement->nvals; i++) {        values[i] = va_arg(args, const char*);    }    return dbd_mysql_pselect(pool, sql, res, statement, random, values);}static void dbd_mysql_bbind(apr_pool_t *pool, apr_dbd_prepared_t *statement,                            const void **values, MYSQL_BIND *bind){    void *arg;    int i, j;    apr_dbd_type_e type;    for (i = 0, j = 0; i < statement->nargs; i++, j++) {        arg = (void *)values[j];        bind[i].length = &bind[i].buffer_length;        bind[i].is_null = NULL;        type = (arg == NULL ? APR_DBD_TYPE_NULL : statement->types[i]);        switch (type) {        case APR_DBD_TYPE_TINY:            bind[i].buffer = arg;            bind[i].buffer_type = MYSQL_TYPE_TINY;            bind[i].is_unsigned = 0;            break;        case APR_DBD_TYPE_UTINY:            bind[i].buffer = arg;            bind[i].buffer_type = MYSQL_TYPE_TINY;            bind[i].is_unsigned = 1;            break;        case APR_DBD_TYPE_SHORT:            bind[i].buffer = arg;            bind[i].buffer_type = MYSQL_TYPE_SHORT;            bind[i].is_unsigned = 0;            break;        case APR_DBD_TYPE_USHORT:            bind[i].buffer = arg;            bind[i].buffer_type = MYSQL_TYPE_SHORT;            bind[i].is_unsigned = 1;            break;        case APR_DBD_TYPE_INT:            bind[i].buffer = arg;            bind[i].buffer_type = MYSQL_TYPE_LONG;            bind[i].is_unsigned = 0;            break;        case APR_DBD_TYPE_UINT:            bind[i].buffer = arg;            bind[i].buffer_type = MYSQL_TYPE_LONG;            bind[i].is_unsigned = 1;            break;        case APR_DBD_TYPE_LONG:            if (sizeof(int) == sizeof(long)) {                bind[i].buffer = arg;            }            else {                bind[i].buffer = apr_palloc(pool, sizeof(int));                *(int*)bind[i].buffer = *(long*)arg;            }

⌨️ 快捷键说明

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