📄 apr_dbd_pgsql.c
字号:
} } else if (TXN_NOTICE_ERRORS(sql->trans)){ sql->trans->errnum = ret; } } 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; } } } return ret;}static const char *dbd_pgsql_escape(apr_pool_t *pool, const char *arg, apr_dbd_t *sql){ size_t len = strlen(arg); char *ret = apr_palloc(pool, 2*len + 2); PQescapeString(ret, arg, len); return ret;}static int dbd_pgsql_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){ char *sqlcmd; char *sqlptr; size_t length, qlen; int i = 0; const char **args; size_t alen; int ret; PGresult *res; if (!*statement) { *statement = apr_palloc(pool, sizeof(apr_dbd_prepared_t)); } (*statement)->nargs = nargs; (*statement)->nvals = nvals; (*statement)->types = types; args = apr_palloc(pool, nargs * sizeof(*args)); qlen = strlen(query); length = qlen + 1; for (i = 0; i < nargs; i++) { switch (types[i]) { case APR_DBD_TYPE_TINY: case APR_DBD_TYPE_UTINY: case APR_DBD_TYPE_SHORT: case APR_DBD_TYPE_USHORT: args[i] = "smallint"; break; case APR_DBD_TYPE_INT: case APR_DBD_TYPE_UINT: args[i] = "integer"; break; case APR_DBD_TYPE_LONG: case APR_DBD_TYPE_ULONG: case APR_DBD_TYPE_LONGLONG: case APR_DBD_TYPE_ULONGLONG: args[i] = "bigint"; break; case APR_DBD_TYPE_FLOAT: args[i] = "real"; break; case APR_DBD_TYPE_DOUBLE: args[i] = "double precision"; break; case APR_DBD_TYPE_TEXT: args[i] = "text"; break; case APR_DBD_TYPE_TIME: args[i] = "time"; break; case APR_DBD_TYPE_DATE: args[i] = "date"; break; case APR_DBD_TYPE_DATETIME: case APR_DBD_TYPE_TIMESTAMP: args[i] = "timestamp"; break; case APR_DBD_TYPE_ZTIMESTAMP: args[i] = "timestamp with time zone"; break; case APR_DBD_TYPE_BLOB: case APR_DBD_TYPE_CLOB: args[i] = "bytea"; break; case APR_DBD_TYPE_NULL: args[i] = "varchar"; /* XXX Eh? */ break; default: args[i] = "varchar"; break; } length += 1 + strlen(args[i]); } if (!label) { /* don't really prepare; use in execParams instead */ (*statement)->prepared = 0; (*statement)->name = apr_pstrdup(pool, query); return 0; } (*statement)->name = apr_pstrdup(pool, label); /* length of SQL query that prepares this statement */ length = 8 + strlen(label) + 2 + 4 + length + 1; sqlcmd = apr_palloc(pool, length); sqlptr = sqlcmd; memcpy(sqlptr, "PREPARE ", 8); sqlptr += 8; length = strlen(label); memcpy(sqlptr, label, length); sqlptr += length; if (nargs > 0) { memcpy(sqlptr, " (",2); sqlptr += 2; for (i=0; i < nargs; ++i) { alen = strlen(args[i]); memcpy(sqlptr, args[i], alen); sqlptr += alen; *sqlptr++ = ','; } sqlptr[-1] = ')'; } memcpy(sqlptr, " AS ", 4); sqlptr += 4; memcpy(sqlptr, query, qlen); sqlptr += qlen; *sqlptr = 0; res = PQexec(sql->conn, sqlcmd); if ( res ) { ret = PQresultStatus(res); if (dbd_pgsql_is_success(ret)) { ret = 0; } /* Hmmm, do we do this here or register it on the pool? */ PQclear(res); } else { ret = PGRES_FATAL_ERROR; } (*statement)->prepared = 1; return ret;}static int dbd_pgsql_pquery_internal(apr_pool_t *pool, apr_dbd_t *sql, int *nrows, apr_dbd_prepared_t *statement, const char **values, const int *len, const int *fmt){ int ret; PGresult *res; if (TXN_IGNORE_ERRORS(sql->trans)) { PGresult *res = PQexec(sql->conn, "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 { return sql->trans->errnum = PGRES_FATAL_ERROR; } } if (statement->prepared) { res = PQexecPrepared(sql->conn, statement->name, statement->nargs, values, len, fmt, 0); } else { res = PQexecParams(sql->conn, statement->name, statement->nargs, 0, values, len, fmt, 0); } if (res) { ret = PQresultStatus(res); if (dbd_pgsql_is_success(ret)) { ret = 0; } *nrows = atoi(PQcmdTuples(res)); PQclear(res); } else { ret = PGRES_FATAL_ERROR; } if (ret != 0){ if (TXN_IGNORE_ERRORS(sql->trans)) { PGresult *res = PQexec(sql->conn, "ROLLBACK TO 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; } } else if (TXN_NOTICE_ERRORS(sql->trans)){ sql->trans->errnum = ret; } } 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; } } } return ret;}static void dbd_pgsql_bind(apr_dbd_prepared_t *statement, const char **values, const char **val, int *len, int *fmt){ int i, j; for (i = 0, j = 0; i < statement->nargs; i++, j++) { if (values[j] == NULL) { val[i] = NULL; } else { switch (statement->types[i]) { case APR_DBD_TYPE_BLOB: case APR_DBD_TYPE_CLOB: val[i] = (char *)values[j]; len[i] = atoi(values[++j]); fmt[i] = 1; /* skip table and column */ j += 2; break; default: val[i] = values[j]; break; } } } return;}static int dbd_pgsql_pquery(apr_pool_t *pool, apr_dbd_t *sql, int *nrows, apr_dbd_prepared_t *statement, 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_pquery_internal(pool, sql, nrows, statement, val, len, fmt);}static int dbd_pgsql_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_pgsql_pquery(pool, sql, nrows, statement, values);}static int dbd_pgsql_pselect_internal(apr_pool_t *pool, apr_dbd_t *sql, apr_dbd_results_t **results, apr_dbd_prepared_t *statement, int seek, const char **values, const int *len, const int *fmt){ PGresult *res; int rv; int ret = 0; if (seek) { /* synchronous query */ if (TXN_IGNORE_ERRORS(sql->trans)) { PGresult *res = PQexec(sql->conn, "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 (statement->prepared) { res = PQexecPrepared(sql->conn, statement->name, statement->nargs, values, len, fmt, 0); } else { res = PQexecParams(sql->conn, statement->name, statement->nargs, 0, values, len, fmt, 0); } if (res) { ret = PQresultStatus(res); if (dbd_pgsql_is_success(ret)) { ret = 0; } else { PQclear(res); } } else { ret = PGRES_FATAL_ERROR; } if (ret != 0) { if (TXN_IGNORE_ERRORS(sql->trans)) { PGresult *res = PQexec(sql->conn, "ROLLBACK TO 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; } } else if (TXN_NOTICE_ERRORS(sql->trans)){ sql->trans->errnum = ret; } return ret; } 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)->res = res; (*results)->ntuples = PQntuples(res); (*results)->sz = PQnfields(res); (*results)->random = seek; (*results)->pool = pool; apr_pool_cleanup_register(pool, res, clear_result, apr_pool_cleanup_null); } else { if (TXN_IGNORE_ERRORS(sql->trans)) { PGresult *res = PQexec(sql->conn, "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 (statement->prepared) { rv = PQsendQueryPrepared(sql->conn, statement->name, statement->nargs, values, len, fmt, 0); } else { rv = PQsendQueryParams(sql->conn, statement->name, statement->nargs, 0, values, len, fmt, 0); } if (rv == 0) { if (TXN_IGNORE_ERRORS(sql->trans)) { PGresult *res = PQexec(sql->conn, "ROLLBACK TO SAVEPOINT APR_DBD_TXN_SP");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -