terom@29: #include terom@29: terom@29: #include "evsql.h" terom@29: #include "../lib/error.h" terom@29: #include "../lib/misc.h" terom@29: terom@29: int evsql_param_string (struct evsql_query_params *params, size_t param, const char *ptr) { terom@29: struct evsql_query_param *p = ¶ms->list[param]; terom@29: terom@29: assert(p->type == EVSQL_PARAM_STRING); terom@29: terom@29: p->data_raw = ptr; terom@29: p->length = 0; terom@29: terom@29: return 0; terom@29: } terom@29: terom@29: int evsql_param_uint32 (struct evsql_query_params *params, size_t param, uint32_t uval) { terom@29: struct evsql_query_param *p = ¶ms->list[param]; terom@29: terom@29: assert(p->type == EVSQL_PARAM_UINT32); terom@29: terom@29: p->data.uint32 = htonl(uval); terom@29: p->data_raw = (const char *) &p->data.uint32; terom@29: p->length = sizeof(uval); terom@29: terom@29: return 0; terom@29: } terom@29: terom@29: const char *evsql_result_error (const struct evsql_result_info *res) { terom@29: if (!res->error) terom@29: return "No error"; terom@29: terom@29: switch (res->evsql->type) { terom@29: case EVSQL_EVPQ: terom@29: if (!res->result.pq) terom@29: return "unknown error (no result)"; terom@29: terom@29: return PQresultErrorMessage(res->result.pq); terom@29: terom@29: default: terom@29: FATAL("res->evsql->type"); terom@29: } terom@29: terom@29: } terom@29: terom@29: size_t evsql_result_rows (const struct evsql_result_info *res) { terom@29: switch (res->evsql->type) { terom@29: case EVSQL_EVPQ: terom@29: return PQntuples(res->result.pq); terom@29: terom@29: default: terom@29: FATAL("res->evsql->type"); terom@29: } terom@29: } terom@29: terom@29: size_t evsql_result_cols (const struct evsql_result_info *res) { terom@29: switch (res->evsql->type) { terom@29: case EVSQL_EVPQ: terom@29: return PQnfields(res->result.pq); terom@29: terom@29: default: terom@29: FATAL("res->evsql->type"); terom@29: } terom@29: } terom@29: terom@30: int evsql_result_buf (const struct evsql_result_info *res, size_t row, size_t col, const char **ptr, size_t *size, int nullok) { terom@29: *ptr = NULL; terom@29: terom@29: switch (res->evsql->type) { terom@29: case EVSQL_EVPQ: terom@29: if (PQgetisnull(res->result.pq, row, col)) { terom@29: if (nullok) terom@29: return 0; terom@29: else terom@29: ERROR("[%zu:%zu] field is null", row, col); terom@29: } terom@29: terom@29: if (PQfformat(res->result.pq, col) != 1) terom@29: ERROR("[%zu:%zu] PQfformat is not binary: %d", row, col, PQfformat(res->result.pq, col)); terom@29: terom@30: *size = PQgetlength(res->result.pq, row, col); terom@30: *ptr = PQgetvalue(res->result.pq, row, col); terom@29: terom@29: return 0; terom@29: terom@29: default: terom@29: FATAL("res->evsql->type"); terom@29: } terom@29: terom@29: error: terom@29: return -1; terom@29: } terom@29: terom@30: int evsql_result_binary (const struct evsql_result_info *res, size_t row, size_t col, const char **ptr, size_t size, int nullok) { terom@30: size_t real_size; terom@30: terom@30: if (evsql_result_buf(res, row, col, ptr, &real_size, nullok)) terom@30: goto error; terom@30: terom@30: if (size && real_size != size) terom@30: ERROR("[%zu:%zu] field size mismatch: %zu -> %zu", row, col, size, real_size); terom@30: terom@30: return 0; terom@30: terom@30: error: terom@30: return -1; terom@30: } terom@30: terom@29: int evsql_result_string (const struct evsql_result_info *res, size_t row, size_t col, const char **ptr, int nullok) { terom@29: return evsql_result_binary(res, row, col, ptr, 0, nullok); terom@29: } terom@29: terom@29: int evsql_result_uint16 (const struct evsql_result_info *res, size_t row, size_t col, uint16_t *uval, int nullok) { terom@29: const char *data; terom@29: int16_t sval; terom@29: terom@29: if (evsql_result_binary(res, row, col, &data, sizeof(*uval), nullok)) terom@29: goto error; terom@29: terom@29: if (!data) terom@29: return 0; terom@29: terom@29: sval = ntohs(*((int16_t *) data)); terom@29: terom@29: if (sval < 0) terom@29: ERROR("negative value for unsigned: %d", sval); terom@29: terom@29: *uval = sval; terom@29: terom@29: return 0; terom@29: terom@29: error: terom@29: return nullok ? 0 : -1; terom@29: } terom@29: terom@29: int evsql_result_uint32 (const struct evsql_result_info *res, size_t row, size_t col, uint32_t *uval, int nullok) { terom@29: const char *data; terom@29: int32_t sval; terom@29: terom@29: if (evsql_result_binary(res, row, col, &data, sizeof(*uval), nullok)) terom@29: goto error; terom@29: terom@29: if (!data) terom@29: return 0; terom@29: terom@29: sval = ntohl(*(int32_t *) data); terom@29: terom@29: if (sval < 0) terom@29: ERROR("negative value for unsigned: %d", sval); terom@29: terom@29: *uval = sval; terom@29: terom@29: return 0; terom@29: terom@29: error: terom@29: return nullok ? 0 : -1; terom@29: } terom@29: terom@29: int evsql_result_uint64 (const struct evsql_result_info *res, size_t row, size_t col, uint64_t *uval, int nullok) { terom@29: const char *data; terom@29: int64_t sval; terom@29: terom@29: if (evsql_result_binary(res, row, col, &data, sizeof(*uval), nullok)) terom@29: goto error; terom@29: terom@29: if (!data) terom@29: return 0; terom@29: terom@29: sval = ntohq(*(int64_t *) data); terom@29: terom@29: if (sval < 0) terom@29: ERROR("negative value for unsigned: %ld", sval); terom@29: terom@29: *uval = sval; terom@29: terom@29: return 0; terom@29: terom@29: error: terom@29: return nullok ? 0 : -1; terom@29: } terom@29: terom@29: void evsql_result_free (const struct evsql_result_info *res) { terom@29: switch (res->evsql->type) { terom@29: case EVSQL_EVPQ: terom@29: return PQclear(res->result.pq); terom@29: terom@29: default: terom@29: FATAL("res->evsql->type"); terom@29: } terom@29: } terom@29: terom@29: const char *evsql_conn_error (struct evsql_conn *conn) { terom@29: switch (conn->evsql->type) { terom@29: case EVSQL_EVPQ: terom@29: if (!conn->engine.evpq) terom@29: return "unknown error (no conn)"; terom@29: terom@29: return evpq_error_message(conn->engine.evpq); terom@29: terom@29: default: terom@29: FATAL("res->evsql->type"); terom@29: } terom@29: } terom@29: terom@29: const char *evsql_trans_error (struct evsql_trans *trans) { terom@29: if (trans->conn == NULL) terom@29: return "unknown error (no trans conn)"; terom@29: terom@29: return evsql_conn_error(trans->conn); terom@29: } terom@29: