77 #define REDIS_DEFAULT_PORT 6379 80 static void *redis_open_conn(
const DBConf *db_conf)
82 redisContext *redis = NULL;
84 redisReply *
reply = NULL;
93 struct timeval timeout = { 1, 500000 };
96 error(0,
"REDIS: can not connect to server!");
97 error(0,
"REDIS: %s", redis->errstr);
101 info(0,
"REDIS: Connected to server at %s:%ld.",
106 if (strncmp(
"OK",
reply->str, 2) != 0) {
107 error(0,
"REDIS: Password authentication failed!");
110 freeReplyObject(
reply);
115 if (strncmp(
"OK",
reply->str, 2) != 0)
116 warning(0,
"REDIS: CONFIG SET TIMEOUT %ld failed - could not set timeout",
120 freeReplyObject(
reply);
125 if (strncmp(
"OK",
reply->str, 2) != 0)
126 error(0,
"REDIS: SELECT %ld failed - could not select database", conf->
database);
129 freeReplyObject(
reply);
132 reply = redisCommand(redis,
"INFO");
133 if (
reply->type != REDIS_REPLY_STRING) {
134 error(0,
"REDIS: INFO command to get version failed!");
140 #if defined(REDIS_DEBUG) 141 debug(
"dbpool.redis",0,
"Received REDIS_REPLY_STRING for INFO cmd");
176 error(0,
"REDIS: Could not parse version from INFO output!");
183 freeReplyObject(
reply);
188 freeReplyObject(
reply);
196 static void redis_close_conn(
void *conn)
201 redisFree((redisContext*) conn);
205 static int redis_check_conn(
void *conn)
212 reply = redisCommand(conn,
"PING");
214 if (strcmp(
reply->str,
"PONG") == 0) {
215 freeReplyObject(
reply);
220 error(0,
"REDIS: server connection check failed!");
221 if (((redisContext*)conn)->err != 0) {
223 error(0,
"REDIS: %s", ((redisContext*)conn)->errstr);
224 }
else if (
reply != NULL) {
229 freeReplyObject(
reply);
233 static List *redis_populate_array(redisReply *
reply)
242 for (i = 0; i <
reply->elements; i++) {
243 switch(
reply->element[i]->type) {
244 case REDIS_REPLY_NIL:
247 case REDIS_REPLY_ARRAY: {
249 arr = redis_populate_array(
reply->element[i]);
254 if (
reply->element[i]->str == NULL ||
reply->element[i]->len == 0) {
258 #if defined(REDIS_DEBUG) 270 static int redis_select(
void *conn,
const Octstr *sql,
List *binds,
List **res)
282 #if defined(REDIS_DEBUG) 286 argv = gw_malloc(
sizeof(*argv) * binds_len);
287 for (i = 0; i < binds_len; i++) {
289 #if defined(REDIS_DEBUG) 294 #if defined(REDIS_DEBUG) 300 reply = redisCommandArgv(conn, binds_len, argv, NULL);
306 #if defined(REDIS_DEBUG) 318 switch (
reply->type) {
319 case REDIS_REPLY_ERROR:
320 #if defined(REDIS_DEBUG) 321 debug(
"dbpool.redis",0,
"Received REDIS_REPLY_ERROR");
323 error(0,
"REDIS: redisCommand() failed: `%s'",
reply->str);
325 case REDIS_REPLY_NIL:
326 #if defined(REDIS_DEBUG) 327 debug(
"dbpool.redis",0,
"Received REDIS_REPLY_NIL");
330 case REDIS_REPLY_STATUS:
331 #if defined(REDIS_DEBUG) 332 debug(
"dbpool.redis",0,
"Received REDIS_REPLY_STATUS");
336 case REDIS_REPLY_STRING:
337 #if defined(REDIS_DEBUG) 338 debug(
"dbpool.redis",0,
"Received REDIS_REPLY_STRING");
345 freeReplyObject(
reply);
349 case REDIS_REPLY_INTEGER:
350 #if defined(REDIS_DEBUG) 351 debug(
"dbpool.redis",0,
"Received REDIS_REPLY_INTEGER");
358 freeReplyObject(
reply);
361 case REDIS_REPLY_ARRAY:
362 #if defined(REDIS_DEBUG) 363 debug(
"dbpool.redis",0,
"Received REDIS_REPLY_ARRAY");
366 row = redis_populate_array(
reply);
368 freeReplyObject(
reply);
372 #if defined(REDIS_DEBUG) 373 error(0,
"REDIS: Received unknown Redis reply type %d",
reply->type);
378 freeReplyObject(
reply);
384 static int redis_update(
void *conn,
const Octstr *sql,
List *binds)
395 #if defined(REDIS_DEBUG) 399 argv = gw_malloc(
sizeof(*argv) * binds_len);
400 for (i = 0; i < binds_len; i++) {
402 #if defined(REDIS_DEBUG) 407 #if defined(REDIS_DEBUG) 413 reply = redisCommandArgv(conn, binds_len, argv, NULL);
419 #if defined(REDIS_DEBUG) 431 switch (
reply->type) {
432 case REDIS_REPLY_ERROR:
433 #if defined(REDIS_DEBUG) 434 debug(
"dbpool.redis",0,
"Received REDIS_REPLY_ERROR");
436 error(0,
"REDIS: redisCommand() failed: `%s'",
reply->str);
438 case REDIS_REPLY_STATUS:
440 #if defined(REDIS_DEBUG) 441 debug(
"dbpool.redis",0,
"Received REDIS_REPLY_STATUS: %s",
reply->str);
443 if (strcmp(
reply->str,
"OK") == 0) {
444 freeReplyObject(
reply);
448 case REDIS_REPLY_INTEGER:
451 #if defined(REDIS_DEBUG) 452 debug(
"dbpool.redis",0,
"Received REDIS_REPLY_INTEGER: %qi",
reply->integer);
460 ret = (int)
reply->integer;
461 freeReplyObject(
reply);
463 case REDIS_REPLY_ARRAY:
466 #if defined(REDIS_DEBUG) 467 debug(
"dbpool.redis",0,
"Received REDIS_REPLY_ARRAY");
469 freeReplyObject(
reply);
473 case REDIS_REPLY_NIL:
476 #if defined(REDIS_DEBUG) 477 debug(
"dbpool.redis",0,
"Received REDIS_REPLY_NIL");
481 #if defined(REDIS_DEBUG) 482 debug(
"dbpool.redis",0,
"Received unknown Redis reply %d",
reply->type);
487 freeReplyObject(
reply);
493 static void redis_conf_destroy(
DBConf *db_conf)
505 static struct db_ops redis_ops = {
506 .
open = redis_open_conn,
507 .close = redis_close_conn,
508 .check = redis_check_conn,
509 .select = redis_select,
510 .update = redis_update,
511 .conf_destroy = redis_conf_destroy
void error(int err, const char *fmt,...)
static Octstr * delimiter
void info(int err, const char *fmt,...)
gw_assert(wtls_machine->packet_to_send !=NULL)
void gwlist_append(List *list, void *item)
void gwlist_produce(List *list, void *item)
long gwlist_len(List *list)
void * gwlist_get(List *list, long pos)
void octstr_strip_blanks(Octstr *text)
#define octstr_get_cstr(ostr)
#define octstr_copy(ostr, from, len)
long octstr_search_char(const Octstr *ostr, int ch, long pos)
Octstr * octstr_imm(const char *cstr)
void * gwlist_extract_first(List *list)
#define octstr_duplicate(ostr)
void warning(int err, const char *fmt,...)
Octstr * octstr_format(const char *fmt,...)
void octstr_destroy(Octstr *ostr)
#define octstr_create(cstr)
void octstr_destroy_item(void *os)
long octstr_len(const Octstr *ostr)
void debug(const char *place, int err, const char *fmt,...)
int octstr_str_compare(const Octstr *ostr, const char *str)
void octstr_format_append(Octstr *os, const char *fmt,...)
int octstr_get_char(const Octstr *ostr, long pos)
#define octstr_create_from_data(data, len)
List * octstr_split(const Octstr *os, const Octstr *sep)
void *(* open)(const DBConf *conf)
static void reply(HTTPClient *c, List *push_headers)
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)