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