src/evsql.c
author Tero Marttila <terom@fixme.fi>
Sun, 12 Oct 2008 00:17:09 +0300
changeset 21 e5da1d428e3e
child 23 1dee73ae4ad0
permissions -rw-r--r--
new evsql for queueing SQL queries
21
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     1
#define _GNU_SOURCE
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     2
#include <stdlib.h>
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     3
#include <sys/queue.h>
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     4
#include <assert.h>
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     5
#include <string.h>
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     6
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     7
#include "evsql.h"
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     8
#include "evpq.h"
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     9
#include "lib/log.h"
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    10
#include "lib/error.h"
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    11
#include "lib/misc.h"
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    12
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    13
enum evsql_type {
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    14
    EVSQL_EVPQ,
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    15
};
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    16
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    17
struct evsql {
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    18
    // callbacks
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    19
    evsql_error_cb error_fn;
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    20
    void *cb_arg;
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    21
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    22
    // backend engine
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    23
    enum evsql_type type;
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    24
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    25
    union {
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    26
        struct evpq_conn *evpq;
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    27
    } engine;
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    28
    
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    29
    // list of queries running or waiting to run
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    30
    TAILQ_HEAD(evsql_queue, evsql_query) queue;
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    31
};
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    32
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    33
struct evsql_query {
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    34
    // the evsql we are querying
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    35
    struct evsql *evsql;
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    36
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    37
    // the actual SQL query, this may or may not be ours, see _evsql_query_exec
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    38
    char *command;
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    39
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    40
    // our callback
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    41
    evsql_query_cb cb_fn;
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    42
    void *cb_arg;
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    43
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    44
    // our position in the query list
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    45
    TAILQ_ENTRY(evsql_query) entry;
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    46
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    47
    // the result
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    48
    union {
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    49
        PGresult *evpq;
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    50
    } result;
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    51
};
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    52
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    53
/*
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    54
 * Actually execute the given query.
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    55
 *
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    56
 * The backend should be able to accept the query at this time.
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    57
 *
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    58
 * query->command must be valid during the execution of this function, but once it returns, the command is not needed
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    59
 * anymore, and should be set to NULL.
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    60
 */
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    61
static int _evsql_query_exec (struct evsql *evsql, struct evsql_query *query, const char *command) {
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    62
    switch (evsql->type) {
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    63
        case EVSQL_EVPQ:
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    64
            // just pass it through
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    65
            return evpq_query(evsql->engine.evpq, command);
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    66
        
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    67
        default:
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    68
            FATAL("evsql->type");
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    69
    }
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    70
}
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    71
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    72
/*
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    73
 * Dequeue the query, execute the callback, and free it.
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    74
 */
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    75
static void _evsql_query_done (struct evsql_query *query, const struct evsql_result_info *result_info) {
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    76
    assert(query->command == NULL);
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    77
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    78
    // dequeue
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    79
    TAILQ_REMOVE(&query->evsql->queue, query, entry);
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    80
    
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    81
    if (result_info) 
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    82
        // call the callback
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    83
        query->cb_fn(*result_info, query->cb_arg);
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    84
    
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    85
    // free
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    86
    free(query);
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    87
}
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    88
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    89
/*
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    90
 * A query has failed, notify the user and remove it.
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    91
 */
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    92
static void _evsql_query_failure (struct evsql *evsql, struct evsql_query *query) {
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    93
    struct evsql_result_info result; ZINIT(result);
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    94
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    95
    // set up the result_info
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    96
    result.evsql = evsql;
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    97
    result.error = 1;
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    98
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    99
    // finish it off
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   100
    _evsql_query_done(query, &result);
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   101
}
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   102
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   103
/*
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   104
 * Clear every enqueued query and then free the evsql.
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   105
 *
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   106
 * If result_info is given, each query will also recieve it via their callback, and the error_fn will be called.
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   107
 */
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   108
static void _evsql_destroy (struct evsql *evsql, const struct evsql_result_info *result_info) {
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   109
    struct evsql_query *query;
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   110
    
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   111
    // clear the queue
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   112
    while ((query = TAILQ_FIRST(&evsql->queue)) != NULL) {
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   113
        _evsql_query_done(query, result_info);
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   114
        
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   115
        TAILQ_REMOVE(&evsql->queue, query, entry);
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   116
    }
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   117
    
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   118
    // do the error callback if required
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   119
    if (result_info)
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   120
        evsql->error_fn(evsql, evsql->cb_arg);
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   121
    
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   122
    // free
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   123
    free(evsql);
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   124
}
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   125
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   126
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   127
/*
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   128
 * Sends the next query if there are more enqueued
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   129
 */
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   130
static void _evsql_pump (struct evsql *evsql) {
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   131
    struct evsql_query *query;
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   132
    
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   133
    // look for the next query
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   134
    if ((query = TAILQ_FIRST(&evsql->queue)) != NULL) {
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   135
        // try and execute it
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   136
        if (_evsql_query_exec(evsql, query, query->command)) {
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   137
            // the query failed
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   138
            _evsql_query_failure(evsql, query);
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   139
        }
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   140
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   141
        // free the command
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   142
        free(query->command); query->command = NULL;
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   143
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   144
        // ok, then we just wait
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   145
    }
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   146
}
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   147
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   148
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   149
static void _evsql_evpq_connected (struct evpq_conn *conn, void *arg) {
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   150
    struct evsql *evsql = arg;
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   151
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   152
    // no state to update, just pump any waiting queries
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   153
    _evsql_pump(evsql);
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   154
}
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   155
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   156
static void _evsql_evpq_result (struct evpq_conn *conn, PGresult *result, void *arg) {
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   157
    struct evsql *evsql = arg;
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   158
    struct evsql_query *query;
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   159
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   160
    assert((query = TAILQ_FIRST(&evsql->queue)) != NULL);
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   161
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   162
    // if we get multiple results, only return the first one
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   163
    if (query->result.evpq) {
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   164
        WARNING("[evsql] evpq query returned multiple results, discarding previous one");
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   165
        
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   166
        PQclear(query->result.evpq); query->result.evpq = NULL;
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   167
    }
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   168
    
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   169
    // remember the result
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   170
    query->result.evpq = result;
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   171
}
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   172
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   173
static void _evsql_evpq_done (struct evpq_conn *conn, void *arg) {
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   174
    struct evsql *evsql = arg;
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   175
    struct evsql_query *query;
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   176
    struct evsql_result_info result; ZINIT(result);
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   177
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   178
    assert((query = TAILQ_FIRST(&evsql->queue)) != NULL);
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   179
    
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   180
    // set up the result_info
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   181
    result.evsql = evsql;
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   182
    
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   183
    if (query->result.evpq == NULL) {
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   184
        // if a query didn't return any results (bug?), warn and fail the query
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   185
        WARNING("[evsql] evpq query didn't return any results");
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   186
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   187
        result.error = 1;
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   188
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   189
    } else {
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   190
        result.error = 0;
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   191
        result.result.pq = query->result.evpq;
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   192
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   193
    }
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   194
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   195
    // finish it off
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   196
    _evsql_query_done(query, &result);
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   197
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   198
    // pump the next one
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   199
    _evsql_pump(evsql);
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   200
}
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   201
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   202
static void _evsql_evpq_failure (struct evpq_conn *conn, void *arg) {
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   203
    struct evsql *evsql = arg;
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   204
    struct evsql_result_info result; ZINIT(result);
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   205
    
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   206
    // OH SHI...
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   207
    
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   208
    // set up the result_info
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   209
    result.evsql = evsql;
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   210
    result.error = 1;
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   211
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   212
    // finish off the whole connection
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   213
    _evsql_destroy(evsql, &result);
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   214
}
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   215
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   216
static struct evpq_callback_info _evsql_evpq_cb_info = {
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   217
    .fn_connected       = _evsql_evpq_connected,
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   218
    .fn_result          = _evsql_evpq_result,
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   219
    .fn_done            = _evsql_evpq_done,
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   220
    .fn_failure         = _evsql_evpq_failure,
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   221
};
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   222
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   223
static struct evsql *_evsql_new_base (evsql_error_cb error_fn, void *cb_arg) {
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   224
    struct evsql *evsql = NULL;
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   225
    
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   226
    // allocate it
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   227
    if ((evsql = calloc(1, sizeof(*evsql))) == NULL)
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   228
        ERROR("calloc");
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   229
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   230
    // store
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   231
    evsql->error_fn = error_fn;
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   232
    evsql->cb_arg = cb_arg;
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   233
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   234
    // init
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   235
    TAILQ_INIT(&evsql->queue);
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   236
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   237
    // done
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   238
    return evsql;
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   239
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   240
error:
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   241
    return NULL;
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   242
}
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   243
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   244
struct evsql *evsql_new_pq (struct event_base *ev_base, const char *pq_conninfo, evsql_error_cb error_fn, void *cb_arg) {
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   245
    struct evsql *evsql = NULL;
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   246
    
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   247
    // base init
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   248
    if ((evsql = _evsql_new_base (error_fn, cb_arg)) == NULL)
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   249
        goto error;
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   250
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   251
    // connect the engine
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   252
    if ((evsql->engine.evpq = evpq_connect(ev_base, pq_conninfo, _evsql_evpq_cb_info, evsql)) == NULL)
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   253
        goto error;
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   254
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   255
    // done
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   256
    return evsql;
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   257
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   258
error:
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   259
    // XXX: more complicated than this?
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   260
    free(evsql); 
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   261
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   262
    return NULL;
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   263
}
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   264
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   265
/*
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   266
 * Checks what the state of the connection is in regards to executing a query.
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   267
 *
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   268
 * Returns:
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   269
 *      <0      connection failure, query not possible
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   270
 *      0       connection idle, can query immediately
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   271
 *      1       connection busy, must queue query
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   272
 */
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   273
static int _evsql_query_idle (struct evsql *evsql) {
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   274
    switch (evsql->type) {
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   275
        case EVSQL_EVPQ: {
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   276
            enum evpq_state state = evpq_state(evsql->engine.evpq);
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   277
            
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   278
            switch (state) {
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   279
                case EVPQ_CONNECT:
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   280
                case EVPQ_QUERY:
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   281
                    return 1;
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   282
                
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   283
                case EVPQ_CONNECTED:
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   284
                    return 0;
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   285
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   286
                case EVPQ_INIT:
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   287
                case EVPQ_FAILURE:
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   288
                    return -1;
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   289
                
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   290
                default:
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   291
                    FATAL("evpq_state");
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   292
            }
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   293
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   294
        }
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   295
        
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   296
        default:
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   297
            FATAL("evsql->type");
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   298
    }
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   299
}
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   300
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   301
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   302
struct evsql_query *evsql_query (struct evsql *evsql, const char *command, evsql_query_cb query_fn, void *cb_arg) {
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   303
    struct evsql_query *query;
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   304
    int idle;
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   305
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   306
    // allocate it
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   307
    if ((query = calloc(1, sizeof(*query))) == NULL)
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   308
        ERROR("calloc");
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   309
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   310
    // store
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   311
    query->evsql = evsql;
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   312
    query->cb_fn = query_fn;
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   313
    query->cb_arg = cb_arg;
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   314
    
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   315
    // check state
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   316
    if ((idle = _evsql_query_idle(evsql)) < 0)
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   317
        ERROR("connection is not valid");
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   318
    
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   319
    if (idle) {
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   320
        assert(TAILQ_EMPTY(&evsql->queue));
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   321
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   322
        // execute directly
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   323
        if (_evsql_query_exec(evsql, query, command))
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   324
            goto error;
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   325
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   326
    } else {
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   327
        // copy the command for later execution
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   328
        if ((query->command = strdup(command)) == NULL)
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   329
            ERROR("strdup");
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   330
    }
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   331
    
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   332
    // store it on the list
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   333
    TAILQ_INSERT_TAIL(&evsql->queue, query, entry);
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   334
    
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   335
    // success
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   336
    return query;
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   337
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   338
error:
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   339
    // do *NOT* free query->command, ever
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   340
    free(query);
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   341
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   342
    return NULL;
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   343
}
e5da1d428e3e new evsql for queueing SQL queries
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   344