📄 apr_dbd_pgsql.c
字号:
if (res) { ret = PQresultStatus(res); PQclear(res); if (!dbd_pgsql_is_success(ret)) { sql->trans->errnum = ret; return PGRES_FATAL_ERROR; } } else { sql->trans->errnum = ret; return PGRES_FATAL_ERROR; } } else if (TXN_NOTICE_ERRORS(sql->trans)){ sql->trans->errnum = 1; } return 1; } else { if (TXN_IGNORE_ERRORS(sql->trans)) { PGresult *res = PQexec(sql->conn, "RELEASE SAVEPOINT APR_DBD_TXN_SP"); if (res) { ret = PQresultStatus(res); PQclear(res); if (!dbd_pgsql_is_success(ret)) { sql->trans->errnum = ret; return PGRES_FATAL_ERROR; } } else { sql->trans->errnum = ret; return PGRES_FATAL_ERROR; } } } if (!*results) { *results = apr_pcalloc(pool, sizeof(apr_dbd_results_t)); } (*results)->random = seek; (*results)->handle = sql->conn; (*results)->pool = pool; } return ret;}static int dbd_pgsql_pselect(apr_pool_t *pool, apr_dbd_t *sql, apr_dbd_results_t **results, apr_dbd_prepared_t *statement, int seek, const char **values){ int *len, *fmt; const char **val; if (sql->trans && sql->trans->errnum) { return sql->trans->errnum; } val = apr_palloc(pool, sizeof(*val) * statement->nargs); len = apr_pcalloc(pool, sizeof(*len) * statement->nargs); fmt = apr_pcalloc(pool, sizeof(*fmt) * statement->nargs); dbd_pgsql_bind(statement, values, val, len, fmt); return dbd_pgsql_pselect_internal(pool, sql, results, statement, seek, val, len, fmt);}static int dbd_pgsql_pvselect(apr_pool_t *pool, apr_dbd_t *sql, apr_dbd_results_t **results, apr_dbd_prepared_t *statement, int seek, 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_pgsql_pselect(pool, sql, results, statement, seek, values);}static void dbd_pgsql_bbind(apr_pool_t *pool, apr_dbd_prepared_t * statement, const void **values, const char **val, int *len, int *fmt){ int i, j; apr_dbd_type_e type; for (i = 0, j = 0; i < statement->nargs; i++, j++) { type = (values[j] == NULL ? APR_DBD_TYPE_NULL : statement->types[i]); switch (type) { case APR_DBD_TYPE_TINY: val[i] = apr_itoa(pool, *(char*)values[j]); break; case APR_DBD_TYPE_UTINY: val[i] = apr_itoa(pool, *(unsigned char*)values[j]); break; case APR_DBD_TYPE_SHORT: val[i] = apr_itoa(pool, *(short*)values[j]); break; case APR_DBD_TYPE_USHORT: val[i] = apr_itoa(pool, *(unsigned short*)values[j]); break; case APR_DBD_TYPE_INT: val[i] = apr_itoa(pool, *(int*)values[j]); break; case APR_DBD_TYPE_UINT: val[i] = apr_itoa(pool, *(unsigned int*)values[j]); break; case APR_DBD_TYPE_LONG: val[i] = apr_ltoa(pool, *(long*)values[j]); break; case APR_DBD_TYPE_ULONG: val[i] = apr_ltoa(pool, *(unsigned long*)values[j]); break; case APR_DBD_TYPE_LONGLONG: val[i] = apr_psprintf(pool, "%" APR_INT64_T_FMT, *(apr_int64_t*)values[j]); break; case APR_DBD_TYPE_ULONGLONG: val[i] = apr_psprintf(pool, "%" APR_UINT64_T_FMT, *(apr_uint64_t*)values[j]); break; case APR_DBD_TYPE_FLOAT: val[i] = apr_psprintf(pool, "%f", *(float*)values[j]); break; case APR_DBD_TYPE_DOUBLE: val[i] = apr_psprintf(pool, "%lf", *(double*)values[j]); 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: val[i] = values[j]; break; case APR_DBD_TYPE_BLOB: case APR_DBD_TYPE_CLOB: val[i] = (char*)values[j]; len[i] = *(apr_size_t*)values[++j]; fmt[i] = 1; /* skip table and column */ j += 2; break; case APR_DBD_TYPE_NULL: default: val[i] = NULL; break; } } return;}static int dbd_pgsql_pbquery(apr_pool_t * pool, apr_dbd_t * sql, int *nrows, apr_dbd_prepared_t * statement, const void **values){ int *len, *fmt; const char **val; if (sql->trans && sql->trans->errnum) { return sql->trans->errnum; } val = apr_palloc(pool, sizeof(*val) * statement->nargs); len = apr_pcalloc(pool, sizeof(*len) * statement->nargs); fmt = apr_pcalloc(pool, sizeof(*fmt) * statement->nargs); dbd_pgsql_bbind(pool, statement, values, val, len, fmt); return dbd_pgsql_pquery_internal(pool, sql, nrows, statement, val, len, fmt);}static int dbd_pgsql_pvbquery(apr_pool_t * pool, apr_dbd_t * sql, int *nrows, apr_dbd_prepared_t * statement, va_list args){ const void **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 void*); } return dbd_pgsql_pbquery(pool, sql, nrows, statement, values);}static int dbd_pgsql_pbselect(apr_pool_t * pool, apr_dbd_t * sql, apr_dbd_results_t ** results, apr_dbd_prepared_t * statement, int seek, const void **values){ int *len, *fmt; const char **val; if (sql->trans && sql->trans->errnum) { return sql->trans->errnum; } val = apr_palloc(pool, sizeof(*val) * statement->nargs); len = apr_pcalloc(pool, sizeof(*len) * statement->nargs); fmt = apr_pcalloc(pool, sizeof(*fmt) * statement->nargs); dbd_pgsql_bbind(pool, statement, values, val, len, fmt); return dbd_pgsql_pselect_internal(pool, sql, results, statement, seek, val, len, fmt);}static int dbd_pgsql_pvbselect(apr_pool_t * pool, apr_dbd_t * sql, apr_dbd_results_t ** results, apr_dbd_prepared_t * statement, int seek, va_list args){ const void **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 void*); } return dbd_pgsql_pbselect(pool, sql, results, statement, seek, values);}static int dbd_pgsql_start_transaction(apr_pool_t *pool, apr_dbd_t *handle, apr_dbd_transaction_t **trans){ int ret = 0; PGresult *res; /* XXX handle recursive transactions here */ res = PQexec(handle->conn, "BEGIN TRANSACTION"); if (res) { ret = PQresultStatus(res); if (dbd_pgsql_is_success(ret)) { ret = 0; if (!*trans) { *trans = apr_pcalloc(pool, sizeof(apr_dbd_transaction_t)); } } PQclear(res); (*trans)->handle = handle; handle->trans = *trans; } else { ret = PGRES_FATAL_ERROR; } return ret;}static int dbd_pgsql_end_transaction(apr_dbd_transaction_t *trans){ PGresult *res; int ret = -1; /* no transaction is an error cond */ if (trans) { /* rollback on error or explicit rollback request */ if (trans->errnum || TXN_DO_ROLLBACK(trans)) { trans->errnum = 0; res = PQexec(trans->handle->conn, "ROLLBACK"); } else { res = PQexec(trans->handle->conn, "COMMIT"); } if (res) { ret = PQresultStatus(res); if (dbd_pgsql_is_success(ret)) { ret = 0; } PQclear(res); } else { ret = PGRES_FATAL_ERROR; } trans->handle->trans = NULL; } return ret;}static int dbd_pgsql_transaction_mode_get(apr_dbd_transaction_t *trans){ if (!trans) return APR_DBD_TRANSACTION_COMMIT; return trans->mode;}static int dbd_pgsql_transaction_mode_set(apr_dbd_transaction_t *trans, int mode){ if (!trans) return APR_DBD_TRANSACTION_COMMIT; return trans->mode = (mode & TXN_MODE_BITS);}static void null_notice_receiver(void *arg, const PGresult *res){ /* nothing */}static void null_notice_processor(void *arg, const char *message){ /* nothing */}static apr_dbd_t *dbd_pgsql_open(apr_pool_t *pool, const char *params, const char **error){ apr_dbd_t *sql; PGconn *conn = PQconnectdb(params); /* if there's an error in the connect string or something we get * back a * bogus connection object, and things like PQreset are * liable to segfault, so just close it out now. it would be nice * if we could give an indication of why we failed to connect... */ if (PQstatus(conn) != CONNECTION_OK) { if (error) { *error = apr_pstrdup(pool, PQerrorMessage(conn)); } PQfinish(conn); return NULL; } PQsetNoticeReceiver(conn, null_notice_receiver, NULL); PQsetNoticeProcessor(conn, null_notice_processor, NULL); sql = apr_pcalloc (pool, sizeof (*sql)); sql->conn = conn; return sql;}static apr_status_t dbd_pgsql_close(apr_dbd_t *handle){ PQfinish(handle->conn); return APR_SUCCESS;}static apr_status_t dbd_pgsql_check_conn(apr_pool_t *pool, apr_dbd_t *handle){ if (PQstatus(handle->conn) != CONNECTION_OK) { PQreset(handle->conn); if (PQstatus(handle->conn) != CONNECTION_OK) { return APR_EGENERAL; } } return APR_SUCCESS;}static int dbd_pgsql_select_db(apr_pool_t *pool, apr_dbd_t *handle, const char *name){ return APR_ENOTIMPL;}static void *dbd_pgsql_native(apr_dbd_t *handle){ return handle->conn;}static int dbd_pgsql_num_cols(apr_dbd_results_t* res){ return res->sz;}static int dbd_pgsql_num_tuples(apr_dbd_results_t* res){ if (res->random) { return res->ntuples; } else { return -1; }}APU_MODULE_DECLARE_DATA const apr_dbd_driver_t apr_dbd_pgsql_driver = { "pgsql", NULL, dbd_pgsql_native, dbd_pgsql_open, dbd_pgsql_check_conn, dbd_pgsql_close, dbd_pgsql_select_db, dbd_pgsql_start_transaction, dbd_pgsql_end_transaction, dbd_pgsql_query, dbd_pgsql_select, dbd_pgsql_num_cols, dbd_pgsql_num_tuples, dbd_pgsql_get_row, dbd_pgsql_get_entry, dbd_pgsql_error, dbd_pgsql_escape, dbd_pgsql_prepare, dbd_pgsql_pvquery, dbd_pgsql_pvselect, dbd_pgsql_pquery, dbd_pgsql_pselect, dbd_pgsql_get_name, dbd_pgsql_transaction_mode_get, dbd_pgsql_transaction_mode_set, "$%d", dbd_pgsql_pvbquery, dbd_pgsql_pvbselect, dbd_pgsql_pbquery, dbd_pgsql_pbselect, dbd_pgsql_datum_get};#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -