src/evsql_util.c
changeset 29 5de62ca9a5aa
parent 28 e944453ca924
child 30 d8fabd347a8e
equal deleted inserted replaced
28:e944453ca924 29:5de62ca9a5aa
     1 #include <assert.h>
       
     2 
       
     3 #include "evsql.h"
       
     4 #include "evsql_internal.h"
       
     5 #include "evpq.h"
       
     6 #include "lib/error.h"
       
     7 #include "lib/misc.h"
       
     8 
       
     9 int evsql_param_string (struct evsql_query_params *params, size_t param, const char *ptr) {
       
    10     struct evsql_query_param *p = &params->list[param];
       
    11     
       
    12     assert(p->type == EVSQL_PARAM_STRING);
       
    13 
       
    14     p->data_raw = ptr;
       
    15     p->length = 0;
       
    16 
       
    17     return 0;
       
    18 }
       
    19 
       
    20 int evsql_param_uint32 (struct evsql_query_params *params, size_t param, uint32_t uval) {
       
    21     struct evsql_query_param *p = &params->list[param];
       
    22     
       
    23     assert(p->type == EVSQL_PARAM_UINT32);
       
    24 
       
    25     p->data.uint32 = htonl(uval);
       
    26     p->data_raw = (const char *) &p->data.uint32;
       
    27     p->length = sizeof(uval);
       
    28 
       
    29     return 0;
       
    30 }
       
    31 
       
    32 const char *evsql_result_error (const struct evsql_result_info *res) {
       
    33     if (!res->error)
       
    34         return "No error";
       
    35 
       
    36     switch (res->evsql->type) {
       
    37         case EVSQL_EVPQ:
       
    38             if (!res->result.pq)
       
    39                 return "unknown error (no result)";
       
    40             
       
    41             return PQresultErrorMessage(res->result.pq);
       
    42 
       
    43         default:
       
    44             FATAL("res->evsql->type");
       
    45     }
       
    46 
       
    47 }
       
    48 
       
    49 size_t evsql_result_rows (const struct evsql_result_info *res) {
       
    50     switch (res->evsql->type) {
       
    51         case EVSQL_EVPQ:
       
    52             return PQntuples(res->result.pq);
       
    53 
       
    54         default:
       
    55             FATAL("res->evsql->type");
       
    56     }
       
    57 }
       
    58 
       
    59 size_t evsql_result_cols (const struct evsql_result_info *res) {
       
    60     switch (res->evsql->type) {
       
    61         case EVSQL_EVPQ:
       
    62             return PQnfields(res->result.pq);
       
    63 
       
    64         default:
       
    65             FATAL("res->evsql->type");
       
    66     }
       
    67 }
       
    68 
       
    69 int evsql_result_binary (const struct evsql_result_info *res, size_t row, size_t col, const char **ptr, size_t size, int nullok) {
       
    70     *ptr = NULL;
       
    71 
       
    72     switch (res->evsql->type) {
       
    73         case EVSQL_EVPQ:
       
    74             if (PQgetisnull(res->result.pq, row, col)) {
       
    75                 if (nullok)
       
    76                     return 0;
       
    77                 else
       
    78                     ERROR("[%zu:%zu] field is null", row, col);
       
    79             }
       
    80 
       
    81             if (PQfformat(res->result.pq, col) != 1)
       
    82                 ERROR("[%zu:%zu] PQfformat is not binary: %d", row, col, PQfformat(res->result.pq, col));
       
    83     
       
    84             if (size && PQgetlength(res->result.pq, row, col) != size)
       
    85                 ERROR("[%zu:%zu] field size mismatch: %zu -> %d", row, col, size, PQgetlength(res->result.pq, row, col));
       
    86 
       
    87             *ptr = PQgetvalue(res->result.pq, row, col);
       
    88 
       
    89             return 0;
       
    90 
       
    91         default:
       
    92             FATAL("res->evsql->type");
       
    93     }
       
    94 
       
    95 error:
       
    96     return -1;
       
    97 }
       
    98 
       
    99 int evsql_result_string (const struct evsql_result_info *res, size_t row, size_t col, const char **ptr, int nullok) {
       
   100     return evsql_result_binary(res, row, col, ptr, 0, nullok);
       
   101 }
       
   102 
       
   103 int evsql_result_uint16 (const struct evsql_result_info *res, size_t row, size_t col, uint16_t *uval, int nullok) {
       
   104     const char *data;
       
   105     int16_t sval;
       
   106 
       
   107     if (evsql_result_binary(res, row, col, &data, sizeof(*uval), nullok))
       
   108         goto error;
       
   109     
       
   110     if (!data)
       
   111         return 0;
       
   112 
       
   113     sval = ntohs(*((int16_t *) data));
       
   114 
       
   115     if (sval < 0)
       
   116         ERROR("negative value for unsigned: %d", sval);
       
   117 
       
   118     *uval = sval;
       
   119     
       
   120     return 0;
       
   121 
       
   122 error:
       
   123     return nullok ? 0 : -1;
       
   124 }
       
   125 
       
   126 int evsql_result_uint32 (const struct evsql_result_info *res, size_t row, size_t col, uint32_t *uval, int nullok) {
       
   127     const char *data;
       
   128     int32_t sval;
       
   129 
       
   130     if (evsql_result_binary(res, row, col, &data, sizeof(*uval), nullok))
       
   131         goto error;
       
   132     
       
   133     if (!data)
       
   134         return 0;
       
   135 
       
   136     sval = ntohl(*(int32_t *) data);
       
   137 
       
   138     if (sval < 0)
       
   139         ERROR("negative value for unsigned: %d", sval);
       
   140 
       
   141     *uval = sval;
       
   142     
       
   143     return 0;
       
   144 
       
   145 error:
       
   146     return nullok ? 0 : -1;
       
   147 }
       
   148 
       
   149 int evsql_result_uint64 (const struct evsql_result_info *res, size_t row, size_t col, uint64_t *uval, int nullok) {
       
   150     const char *data;
       
   151     int64_t sval;
       
   152 
       
   153     if (evsql_result_binary(res, row, col, &data, sizeof(*uval), nullok))
       
   154         goto error;
       
   155     
       
   156     if (!data)
       
   157         return 0;
       
   158 
       
   159     sval = ntohq(*(int64_t *) data);
       
   160 
       
   161     if (sval < 0)
       
   162         ERROR("negative value for unsigned: %ld", sval);
       
   163 
       
   164     *uval = sval;
       
   165     
       
   166     return 0;
       
   167 
       
   168 error:
       
   169     return nullok ? 0 : -1;
       
   170 }
       
   171 
       
   172 void evsql_result_free (const struct evsql_result_info *res) {
       
   173     switch (res->evsql->type) {
       
   174         case EVSQL_EVPQ:
       
   175             return PQclear(res->result.pq);
       
   176 
       
   177         default:
       
   178             FATAL("res->evsql->type");
       
   179     }
       
   180 }
       
   181 
       
   182 const char *evsql_conn_error (struct evsql_conn *conn) {
       
   183     switch (conn->evsql->type) {
       
   184         case EVSQL_EVPQ:
       
   185             if (!conn->engine.evpq)
       
   186                 return "unknown error (no conn)";
       
   187             
       
   188             return evpq_error_message(conn->engine.evpq);
       
   189 
       
   190         default:
       
   191             FATAL("res->evsql->type");
       
   192     }
       
   193 }
       
   194 
       
   195 const char *evsql_trans_error (struct evsql_trans *trans) {
       
   196     if (trans->conn == NULL)
       
   197         return "unknown error (no trans conn)";
       
   198 
       
   199     return evsql_conn_error(trans->conn);
       
   200 }
       
   201