diff --git a/debian/patches/sipwise/db_redis.patch b/debian/patches/sipwise/db_redis.patch
index fc8d0fcaf..03804d57f 100644
--- a/debian/patches/sipwise/db_redis.patch
+++ b/debian/patches/sipwise/db_redis.patch
@@ -1,7 +1,5 @@
-Index: kamailio/Makefile.groups
-===================================================================
---- kamailio.orig/Makefile.groups 2018-02-14 15:23:35.861985218 +0100
-+++ kamailio/Makefile.groups 2018-02-14 15:23:35.853985199 +0100
+--- a/Makefile.groups
++++ b/Makefile.groups
@@ -150,7 +150,7 @@
mod_list_jansson=jansson janssonrpc-c
@@ -11,10 +9,8 @@ Index: kamailio/Makefile.groups
# - modules depending on mono library
mod_list_mono=app_mono
-Index: kamailio/modules/db_redis/Makefile
-===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ kamailio/modules/db_redis/Makefile 2018-02-14 15:23:35.853985199 +0100
+--- /dev/null
++++ b/modules/db_redis/Makefile
@@ -0,0 +1,36 @@
+#
+# WARNING: do not run this directly, it should be run by the master Makefile
@@ -52,10 +48,8 @@ Index: kamailio/modules/db_redis/Makefile
+ REDISON=yes $(MAKE) -C ../../utils/kamctl/ install-modules
+
+install-scripts: install-redis-scripts
-Index: kamailio/modules/db_redis/README
-===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ kamailio/modules/db_redis/README 2018-02-14 15:23:35.853985199 +0100
+--- /dev/null
++++ b/modules/db_redis/README
@@ -0,0 +1,189 @@
+DB_REDIS Module
+
@@ -246,10 +240,8 @@ Index: kamailio/modules/db_redis/README
+modparam("acc_db", "db_url", DBURL_ACC)
+modparam("auth_db", "db_url", DBURL_AUTH)
+...
-Index: kamailio/modules/db_redis/db_redis_mod.c
-===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ kamailio/modules/db_redis/db_redis_mod.c 2018-02-14 15:23:35.853985199 +0100
+--- /dev/null
++++ b/modules/db_redis/db_redis_mod.c
@@ -0,0 +1,115 @@
+/**
+ * Copyright (C) 2018 Andreas Granig (sipwise.com)
@@ -366,10 +358,8 @@ Index: kamailio/modules/db_redis/db_redis_mod.c
+static void mod_destroy(void) {
+ LM_DBG("module destroying\n");
+}
-Index: kamailio/modules/db_redis/db_redis_mod.h
-===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ kamailio/modules/db_redis/db_redis_mod.h 2018-02-14 15:23:35.853985199 +0100
+--- /dev/null
++++ b/modules/db_redis/db_redis_mod.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2018 Andreas Granig (sipwise.com)
@@ -424,19 +414,15 @@ Index: kamailio/modules/db_redis/db_redis_mod.h
+extern str redis_schema_path;
+
+#endif /* _DB_REDIS_MOD_H */
-Index: kamailio/modules/db_redis/doc/Makefile
-===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ kamailio/modules/db_redis/doc/Makefile 2018-02-14 15:23:35.853985199 +0100
+--- /dev/null
++++ b/modules/db_redis/doc/Makefile
@@ -0,0 +1,4 @@
+docs = db_redis.xml
+
+docbook_dir = ../../../docbook
+include $(docbook_dir)/Makefile.module
-Index: kamailio/modules/db_redis/doc/db_redis.xml
-===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ kamailio/modules/db_redis/doc/db_redis.xml 2018-02-14 15:23:35.853985199 +0100
+--- /dev/null
++++ b/modules/db_redis/doc/db_redis.xml
@@ -0,0 +1,33 @@
+
+
+
+
-Index: kamailio/modules/db_redis/doc/db_redis_admin.xml
-===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ kamailio/modules/db_redis/doc/db_redis_admin.xml 2018-02-14 15:23:35.853985199 +0100
+--- /dev/null
++++ b/modules/db_redis/doc/db_redis_admin.xml
@@ -0,0 +1,192 @@
+
+
+
+
-Index: kamailio/modules/db_redis/redis_connection.c
-===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ kamailio/modules/db_redis/redis_connection.c 2018-02-14 15:23:35.853985199 +0100
-@@ -0,0 +1,301 @@
+--- /dev/null
++++ b/modules/db_redis/redis_connection.c
+@@ -0,0 +1,397 @@
+/*
+ * Copyright (C) 2018 Andreas Granig (sipwise.com)
+ *
@@ -699,6 +681,78 @@ Index: kamailio/modules/db_redis/redis_connection.c
+#include "redis_connection.h"
+#include "redis_table.h"
+
++static void print_query(redis_key_t *query) {
++ LM_DBG("Query dump:\n");
++ for (redis_key_t *k = query; k; k = k->next) {
++ LM_DBG(" %s\n", k->key.s);
++ }
++}
++
++static int db_redis_push_query(km_redis_con_t *con, redis_key_t *query) {
++
++ redis_command_t *cmd = NULL;
++ redis_command_t *tmp = NULL;
++ redis_key_t *new_query = NULL;
++
++ if (!query)
++ return 0;
++
++ cmd = (redis_command_t*)pkg_malloc(sizeof(redis_command_t));
++ if (!cmd) {
++ LM_ERR("Failed to allocate memory for redis command\n");
++ goto err;
++ }
++
++ // duplicate query, as original one might be free'd after being
++ // appended
++ while(query) {
++ if (db_redis_key_add_str(&new_query, &query->key) != 0) {
++ LM_ERR("Failed to duplicate query\n");
++ goto err;
++ }
++ query = query->next;
++ }
++
++ cmd->query = new_query;
++ cmd->next = NULL;
++
++ if (!con->command_queue) {
++ con->command_queue = cmd;
++ } else {
++ tmp = con->command_queue;
++ while (tmp->next)
++ tmp = tmp->next;
++ tmp->next = cmd;
++ }
++
++ return 0;
++
++err:
++ if (new_query) {
++ db_redis_key_free(&new_query);
++ }
++ if (cmd) {
++ pkg_free(cmd);
++ }
++ return -1;
++}
++
++static redis_key_t* db_redis_shift_query(km_redis_con_t *con) {
++ redis_command_t *cmd;
++ redis_key_t *query;
++
++ query = NULL;
++ cmd = con->command_queue;
++
++ if (cmd) {
++ query = cmd->query;
++ con->command_queue = cmd->next;
++ pkg_free(cmd);
++ }
++
++ return query;
++}
++
+int db_redis_connect(km_redis_con_t *con) {
+ struct timeval tv;
+ redisReply *reply;
@@ -864,14 +918,6 @@ Index: kamailio/modules/db_redis/redis_connection.c
+ pkg_free(_c);
+}
+
-+
-+static void print_query(redis_key_t *query) {
-+ LM_DBG("Query dump:\n");
-+ for (redis_key_t *k = query; k; k = k->next) {
-+ LM_DBG(" %s\n", k->key.s);
-+ }
-+}
-+
+void *db_redis_command_argv(km_redis_con_t *con, redis_key_t *query) {
+ char **argv = NULL;
+ int argc;
@@ -902,12 +948,17 @@ Index: kamailio/modules/db_redis/redis_connection.c
+ return reply;
+}
+
-+int db_redis_append_command_argv(km_redis_con_t *con, redis_key_t *query) {
++int db_redis_append_command_argv(km_redis_con_t *con, redis_key_t *query, int queue) {
+ char **argv = NULL;
+ int ret, argc;
+
+ print_query(query);
+
++ if (queue > 0 && db_redis_push_query(con, query) != 0) {
++ LM_ERR("Failed to queue redis command\n");
++ return -1;
++ }
++
+ argc = db_redis_key_list2arr(query, &argv);
+ if (argc < 0) {
+ LM_ERR("Failed to allocate memory for query array\n");
@@ -916,6 +967,10 @@ Index: kamailio/modules/db_redis/redis_connection.c
+ LM_DBG("query has %d args\n", argc);
+
+ ret = redisAppendCommandArgv(con->con, argc, (const char**)argv, NULL);
++
++ // this should actually never happen, because if all replies
++ // are properly consumed for the previous command, it won't send
++ // out a new query until redisGetReply is called
+ if (con->con->err == REDIS_ERR_EOF) {
+ if (db_redis_connect(con) != 0) {
+ LM_ERR("Failed to reconnect to redis db\n");
@@ -937,22 +992,40 @@ Index: kamailio/modules/db_redis/redis_connection.c
+
+int db_redis_get_reply(km_redis_con_t *con, void **reply) {
+ int ret;
++ redis_key_t *query;
+
+ *reply = NULL;
+ ret = redisGetReply(con->con, reply);
+ if (con->con->err == REDIS_ERR_EOF) {
++ LM_DBG("redis connection is gone, try reconnect\n");
++ con->append_counter = 0;
+ if (db_redis_connect(con) != 0) {
+ LM_ERR("Failed to reconnect to redis db\n");
+ if (con->con) {
+ redisFree(con->con);
+ con->con = NULL;
+ }
-+ return ret;
++ }
++ // take commands from oldest to newest and re-do again,
++ // but don't queue them once again in retry-mode
++ while ((query = db_redis_shift_query(con))) {
++ LM_DBG("re-queueing appended command\n");
++ if (db_redis_append_command_argv(con, query, 0) != 0) {
++ LM_ERR("Failed to re-queue redis command");
++ return -1;
++ }
++ db_redis_key_free(&query);
+ }
+ ret = redisGetReply(con->con, reply);
-+ }
-+ if (!con->con->err)
++ if (con->con->err != REDIS_ERR_EOF) {
++ con->append_counter--;
++ }
++ } else {
++ LM_DBG("get_reply successful, removing query\n");
++ query = db_redis_shift_query(con);
++ db_redis_key_free(&query);
+ con->append_counter--;
++ }
+ return ret;
+}
+
@@ -965,6 +1038,7 @@ Index: kamailio/modules/db_redis/redis_connection.c
+
+void db_redis_consume_replies(km_redis_con_t *con) {
+ redisReply *reply = NULL;
++ redis_key_t *query;
+ while (con->append_counter > 0 && !con->con->err) {
+ LM_DBG("consuming outstanding reply %u", con->append_counter);
+ db_redis_get_reply(con, (void**)&reply);
@@ -973,12 +1047,14 @@ Index: kamailio/modules/db_redis/redis_connection.c
+ reply = NULL;
+ }
+ }
++ while ((query = db_redis_shift_query(con))) {
++ LM_DBG("consuming queued command\n");
++ db_redis_key_free(&query);
++ }
+}
-Index: kamailio/modules/db_redis/redis_connection.h
-===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ kamailio/modules/db_redis/redis_connection.h 2018-02-14 15:23:35.853985199 +0100
-@@ -0,0 +1,73 @@
+--- /dev/null
++++ b/modules/db_redis/redis_connection.h
+@@ -0,0 +1,81 @@
+/**
+ * Copyright (C) 2018 Andreas Granig (sipwise.com)
+ *
@@ -1004,7 +1080,7 @@ Index: kamailio/modules/db_redis/redis_connection.h
+#ifndef _REDIS_CONNECTION_H_
+#define _REDIS_CONNECTION_H_
+
-+#include
++#include
+
+#include "db_redis_mod.h"
+
@@ -1025,12 +1101,20 @@ Index: kamailio/modules/db_redis/redis_connection.h
+ } \
+} while(0);
+
++typedef struct redis_key redis_key_t;
++
++typedef struct redis_command {
++ redis_key_t *query;
++ struct redis_command *next;
++} redis_command_t;
++
+typedef struct km_redis_con {
+ struct db_id* id;
+ unsigned int ref;
+ struct pool_con* next;
+
+ redisContext *con;
++ redis_command_t *command_queue;
+ unsigned int append_counter;
+ struct str_hash_table tables;
+} km_redis_con_t;
@@ -1046,17 +1130,15 @@ Index: kamailio/modules/db_redis/redis_connection.h
+
+int db_redis_connect(km_redis_con_t *con);
+void *db_redis_command_argv(km_redis_con_t *con, redis_key_t *query);
-+int db_redis_append_command_argv(km_redis_con_t *con, redis_key_t *query);
++int db_redis_append_command_argv(km_redis_con_t *con, redis_key_t *query, int queue);
+int db_redis_get_reply(km_redis_con_t *con, void **reply);
+void db_redis_consume_replies(km_redis_con_t *con);
+void db_redis_free_reply(redisReply **reply);
+
+#endif /* _REDIS_CONNECTION_H_ */
-Index: kamailio/modules/db_redis/redis_dbase.c
-===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ kamailio/modules/db_redis/redis_dbase.c 2018-02-14 15:23:35.853985199 +0100
-@@ -0,0 +1,2128 @@
+--- /dev/null
++++ b/modules/db_redis/redis_dbase.c
+@@ -0,0 +1,2151 @@
+/*
+ * Copyright (C) 2018 Andreas Granig (sipwise.com)
+ *
@@ -1087,6 +1169,7 @@ Index: kamailio/modules/db_redis/redis_dbase.c
+#include "redis_table.h"
+
+static void db_redis_dump_reply(redisReply *reply) {
++ int i;
+ if (reply->type == REDIS_REPLY_STRING) {
+ LM_DBG("%s\n", reply->str);
+ } else if (reply->type == REDIS_REPLY_INTEGER) {
@@ -1095,7 +1178,7 @@ Index: kamailio/modules/db_redis/redis_dbase.c
+ LM_DBG("\n");
+ } else if (reply->type == REDIS_REPLY_ARRAY) {
+ LM_DBG("printing %lu elements in array reply\n", reply->elements);
-+ for(int i = 0; i < reply->elements; ++i) {
++ for(i = 0; i < reply->elements; ++i) {
+ db_redis_dump_reply(reply->element[i]);
+ }
+ } else {
@@ -1275,7 +1358,8 @@ Index: kamailio/modules/db_redis/redis_dbase.c
+ return -1;
+}
+
-+static int db_redis_build_entry_manual_keys(redis_table_t *table, const db_key_t *_k, const db_val_t *_v, const int _n, int **manual_keys, int *manual_key_count) {
++static int db_redis_build_entry_manual_keys(redis_table_t *table, const db_key_t *_k,
++ const db_val_t *_v, const int _n, int **manual_keys, int *manual_key_count) {
+
+ // TODO: we also put keys here which are already part of type mapping!
+ // there must be removed for performance reasons
@@ -1292,9 +1376,10 @@ Index: kamailio/modules/db_redis/redis_dbase.c
+
+ for (key = table->entry_keys; key; key = key->next) {
+ int subkey_found = 0;
++ int i;
+ LM_DBG("checking for existence of entry key '%.*s' in query to get manual key\n",
+ key->key.len, key->key.s);
-+ for (int i = 0; i < _n; ++i) {
++ for (i = 0; i < _n; ++i) {
+ const db_key_t k = _k[i];
+ if (!str_strcmp(&key->key, (str*)k)) {
+ LM_DBG("found key in entry key\n");
@@ -1319,7 +1404,9 @@ Index: kamailio/modules/db_redis/redis_dbase.c
+ return -1;
+}
+
-+static int db_redis_find_query_key(redis_key_t *key, const str *table_name, str *type_name, const db_key_t *_k, const db_val_t *_v, const int _n, str *key_name, int *key_found) {
++static int db_redis_find_query_key(redis_key_t *key, const str *table_name,
++ str *type_name, const db_key_t *_k, const db_val_t *_v, const int _n,
++ str *key_name, int *key_found) {
+
+ unsigned int len;
+ str val = {NULL, 0};
@@ -1330,9 +1417,10 @@ Index: kamailio/modules/db_redis/redis_dbase.c
+
+ for (; key; key = key->next) {
+ int subkey_found = 0;
++ int i;
+ LM_DBG("checking for existence of entry key '%.*s' in query\n",
+ key->key.len, key->key.s);
-+ for (int i = 0; i < _n; ++i) {
++ for (i = 0; i < _n; ++i) {
+ const db_key_t k = _k[i];
+ const db_val_t v = _v[i];
+
@@ -1617,9 +1705,10 @@ Index: kamailio/modules/db_redis/redis_dbase.c
+ db_redis_free_reply(&reply);
+ break;
+ } else {
++ int i;
+ LM_DBG("populating query keys list with result of type query\n");
+ *query_keys_count = reply->elements;
-+ for (int i = 0; i < reply->elements; ++i) {
++ for (i = 0; i < reply->elements; ++i) {
+ redisReply *subreply = reply->element[i];
+ if (subreply->type == REDIS_REPLY_STRING) {
+ LM_DBG("adding resulting entry key '%s' from type query\n", subreply->str);
@@ -1681,6 +1770,8 @@ Index: kamailio/modules/db_redis/redis_dbase.c
+ redisReply *reply = NULL;
+ unsigned long cursor = 0;
+ char *match = NULL;
++ size_t j;
++ int l;
+
+ str match_pattern = {":entry::*", strlen(":entry::*")};
+
@@ -1755,7 +1846,7 @@ Index: kamailio/modules/db_redis/redis_dbase.c
+
+ *query_keys_count += reply->element[1]->elements;
+
-+ for (size_t j = 0; j < reply->element[1]->elements; ++i, ++j) {
++ for (j = 0; j < reply->element[1]->elements; ++i, ++j) {
+ redisReply *key = reply->element[1]->element[j];
+ if (!key) {
+ LM_ERR("Invalid null key at cursor result index %lu while scanning table '%.*s'\n",
@@ -1783,8 +1874,8 @@ Index: kamailio/modules/db_redis/redis_dbase.c
+ goto err;
+ }
+ memset(*manual_keys, 0, *manual_keys_count * sizeof(int));
-+ for (int i = 0; i < _n; ++i) {
-+ (*manual_keys)[i] = i;
++ for (l = 0; l < _n; ++l) {
++ (*manual_keys)[l] = l;
+ }
+
+ if (reply) {
@@ -2005,6 +2096,7 @@ Index: kamailio/modules/db_redis/redis_dbase.c
+ int *manual_keys, int manual_keys_count) {
+ db_val_t* dval;
+ db_row_t* drow;
++ size_t col;
+
+ if (reply->type != REDIS_REPLY_ARRAY) {
+ LM_ERR("Unexpected redis reply type, expecting array\n");
@@ -2017,7 +2109,7 @@ Index: kamailio/modules/db_redis/redis_dbase.c
+ }
+
+ // manually filter non-matching replies
-+ for (size_t col = 0; col < reply->elements; ++col) {
++ for (col = 0; col < reply->elements; ++col) {
+ if (col < manual_keys_count) {
+ int idx = manual_keys[col];
+ db_key_t k = _k[idx];
@@ -2045,7 +2137,7 @@ Index: kamailio/modules/db_redis/redis_dbase.c
+ RES_NUM_ROWS(_r), RES_ROW_N(_r), RES_COL_N(_r), reply->elements - manual_keys_count);
+ return -1;
+ }
-+ for (size_t col = manual_keys_count; col < reply->elements; ++col) {
++ for (col = manual_keys_count; col < reply->elements; ++col) {
+ size_t colidx = col - manual_keys_count;
+ size_t redisidx = col;
+ int coltype;
@@ -2095,6 +2187,8 @@ Index: kamailio/modules/db_redis/redis_dbase.c
+ redisReply *reply = NULL;
+ redis_key_t *query_v = NULL;
+ int num_rows = 0;
++ redis_key_t *key;
++ int j;
+
+ *_r = db_redis_new_result();
+ if (!*_r) {
@@ -2119,7 +2213,7 @@ Index: kamailio/modules/db_redis/redis_dbase.c
+ }
+ }
+
-+ for (redis_key_t *key = *keys; key; key = key->next) {
++ for (key = *keys; key; key = key->next) {
+ redis_key_t *tmp = NULL;
+ str *keyname = &(key->key);
+
@@ -2135,7 +2229,7 @@ Index: kamailio/modules/db_redis/redis_dbase.c
+ LM_ERR("Failed to add key name to list\n");
+ goto error;
+ }
-+ if (db_redis_append_command_argv(con, query_v) != REDIS_OK) {
++ if (db_redis_append_command_argv(con, query_v, 1) != REDIS_OK) {
+ LM_ERR("Failed to append redis command\n");
+ goto error;
+ }
@@ -2158,7 +2252,7 @@ Index: kamailio/modules/db_redis/redis_dbase.c
+
+ // we put the manual comparison columns first, so we can skip them
+ // easily in result, for the cost of potential duplicate column returns
-+ for (int j = 0; j < *manual_keys_count; ++j) {
++ for (j = 0; j < *manual_keys_count; ++j) {
+ int idx = (*manual_keys)[j];
+ str *k_name = _k[idx];
+ if (db_redis_key_add_str(&query_v, k_name) != 0) {
@@ -2166,7 +2260,7 @@ Index: kamailio/modules/db_redis/redis_dbase.c
+ goto error;
+ }
+ }
-+ for (int j = 0; j < _nc; ++j) {
++ for (j = 0; j < _nc; ++j) {
+ str *k_name = _c[j];
+ if (db_redis_key_add_str(&query_v, k_name) != 0) {
+ LM_ERR("Failed to add manual key to query list\n");
@@ -2174,7 +2268,7 @@ Index: kamailio/modules/db_redis/redis_dbase.c
+ }
+ }
+
-+ if (db_redis_append_command_argv(con, query_v) != REDIS_OK) {
++ if (db_redis_append_command_argv(con, query_v, 1) != REDIS_OK) {
+ LM_ERR("Failed to append redis command\n");
+ goto error;
+ }
@@ -2193,7 +2287,7 @@ Index: kamailio/modules/db_redis/redis_dbase.c
+ // reset and increment in convert_row
+ RES_NUM_ROWS(*_r) = RES_ROW_N(*_r) = 0;
+
-+ for (redis_key_t *key = *keys; key; key = key->next) {
++ for (key = *keys; key; key = key->next) {
+ // get reply for EXISTS query
+ if (db_redis_get_reply(con, (void**)&reply) != REDIS_OK) {
+ LM_ERR("Failed to get reply for query: %s\n",
@@ -2255,6 +2349,7 @@ Index: kamailio/modules/db_redis/redis_dbase.c
+ redis_key_t *k = NULL;
+ int type_keys_count = 0;
+ int all_type_keys_count = 0;
++ size_t col;
+
+ redisReply *reply = NULL;
+ redis_key_t *query_v = NULL;
@@ -2262,6 +2357,7 @@ Index: kamailio/modules/db_redis/redis_dbase.c
+ redis_key_t *all_type_keys = NULL;
+ db_val_t *db_vals = NULL;
+ db_key_t *db_keys = NULL;
++ redis_key_t *type_key;
+
+ if (!keys_count && do_table_scan) {
+ LM_DBG("performing full table scan\n");
@@ -2344,7 +2440,7 @@ Index: kamailio/modules/db_redis/redis_dbase.c
+
+ // manually filter non-matching replies
+ row_match = 1;
-+ for (size_t col = 0; col < reply->elements; ++col) {
++ for (col = 0; col < reply->elements; ++col) {
+ if (col < manual_keys_count) {
+ int idx = manual_keys[col];
+ db_key_t k = _k[idx];
@@ -2416,7 +2512,7 @@ Index: kamailio/modules/db_redis/redis_dbase.c
+ db_redis_check_reply(con, reply, error);
+ db_redis_free_reply(&reply);
+
-+ for (redis_key_t *type_key = type_keys; type_key; type_key = type_key->next) {
++ for (type_key = type_keys; type_key; type_key = type_key->next) {
+ if (db_redis_key_add_string(&query_v, "SREM", 4) != 0) {
+ LM_ERR("Failed to add srem command to post-delete query\n");
+ goto error;
@@ -2467,6 +2563,10 @@ Index: kamailio/modules/db_redis/redis_dbase.c
+ redisReply *reply = NULL;
+ redis_key_t *query_v = NULL;
+ int update_queries = 0;
++ redis_key_t *key;
++ int i;
++ int j;
++ size_t col;
+
+ if (!keys_count && do_table_scan) {
+ LM_DBG("performing full table scan\n");
@@ -2478,7 +2578,7 @@ Index: kamailio/modules/db_redis/redis_dbase.c
+ }
+ }
+
-+ for (redis_key_t *key = *keys; key; key = key->next) {
++ for (key = *keys; key; key = key->next) {
+ str *keyname = &key->key;
+
+ LM_DBG("fetching row for '%.*s' from redis\n", keyname->len, keyname->s);
@@ -2492,7 +2592,7 @@ Index: kamailio/modules/db_redis/redis_dbase.c
+ LM_ERR("Failed to add key name to pre-update exists query\n");
+ goto error;
+ }
-+ if (db_redis_append_command_argv(con, query_v) != REDIS_OK) {
++ if (db_redis_append_command_argv(con, query_v, 1) != REDIS_OK) {
+ LM_ERR("Failed to append redis command\n");
+ goto error;
+ }
@@ -2518,7 +2618,7 @@ Index: kamailio/modules/db_redis/redis_dbase.c
+ goto error;
+ }
+
-+ for (int j = 0; j < *manual_keys_count; ++j) {
++ for (j = 0; j < *manual_keys_count; ++j) {
+ int idx = (*manual_keys)[j];
+ str *k_name = _k[idx];
+ if (db_redis_key_add_str(&query_v, k_name) != 0) {
@@ -2527,7 +2627,7 @@ Index: kamailio/modules/db_redis/redis_dbase.c
+ }
+ }
+
-+ if (db_redis_append_command_argv(con, query_v) != REDIS_OK) {
++ if (db_redis_append_command_argv(con, query_v, 1) != REDIS_OK) {
+ LM_ERR("Failed to append redis command\n");
+ goto error;
+ }
@@ -2551,7 +2651,7 @@ Index: kamailio/modules/db_redis/redis_dbase.c
+ */
+
+
-+ for (redis_key_t *key = *keys; key; key = key->next) {
++ for (key = *keys; key; key = key->next) {
+ int row_match;
+
+ LM_DBG("fetching replies for '%.*s' from redis\n", key->key.len, key->key.s);
@@ -2592,7 +2692,7 @@ Index: kamailio/modules/db_redis/redis_dbase.c
+
+ // manually filter non-matching replies
+ row_match = 1;
-+ for (size_t col = 0; col < reply->elements; ++col) {
++ for (col = 0; col < reply->elements; ++col) {
+ if (col < *manual_keys_count) {
+ int idx = (*manual_keys)[col];
+ db_key_t k = _k[idx];
@@ -2623,7 +2723,7 @@ Index: kamailio/modules/db_redis/redis_dbase.c
+ goto error;
+ }
+
-+ for (int i = 0; i < _nu; ++i) {
++ for (i = 0; i < _nu; ++i) {
+ str *k = _uk[i];
+ str v = {NULL, 0};
+
@@ -2642,7 +2742,7 @@ Index: kamailio/modules/db_redis/redis_dbase.c
+ pkg_free(v.s);
+ }
+ update_queries++;
-+ if (db_redis_append_command_argv(con, query_v) != REDIS_OK) {
++ if (db_redis_append_command_argv(con, query_v, 1) != REDIS_OK) {
+ LM_ERR("Failed to append redis command\n");
+ goto error;
+ }
@@ -2652,7 +2752,7 @@ Index: kamailio/modules/db_redis/redis_dbase.c
+
+ LM_DBG("getting replies for %d queries\n", update_queries);
+
-+ for (int i = 0; i < update_queries; ++i) {
++ for (i = 0; i < update_queries; ++i) {
+ if (db_redis_get_reply(con, (void**)&reply) != REDIS_OK) {
+ LM_ERR("Failed to get reply for query: %s\n",
+ con->con->errstr);
@@ -2699,6 +2799,7 @@ Index: kamailio/modules/db_redis/redis_dbase.c
+ int *manual_keys = NULL;
+ int manual_keys_count = 0;
+ db_op_t *query_ops = NULL;
++ int i;
+
+ // TODO: implement order-by
+ // TODO: optimize mapping-based manual post-check (remove check for keys already
@@ -2748,7 +2849,7 @@ Index: kamailio/modules/db_redis/redis_dbase.c
+ LM_ERR("Failed to allocate memory for query op list\n");
+ goto error;
+ }
-+ for (int i = 0; i < _n; ++i) {
++ for (i = 0; i < _n; ++i) {
+ query_ops[i] = op;
+ }
+ } else {
@@ -2832,6 +2933,8 @@ Index: kamailio/modules/db_redis/redis_dbase.c
+ int type_keys_count = 0;
+ redis_key_t *query_v = NULL;
+ redisReply *reply = NULL;
++ int i;
++ redis_key_t *k;
+
+ con = REDIS_CON(_h);
+ if (con && con->con == NULL) {
@@ -2872,7 +2975,7 @@ Index: kamailio/modules/db_redis/redis_dbase.c
+ goto error;
+ }
+
-+ for (int i = 0; i < _n; ++i) {
++ for (i = 0; i < _n; ++i) {
+ str *k = _k[i];
+ str v;
+
@@ -2896,7 +2999,7 @@ Index: kamailio/modules/db_redis/redis_dbase.c
+ db_redis_check_reply(con, reply, error);
+ db_redis_free_reply(&reply);
+
-+ for (redis_key_t *k = type_keys; k; k = k->next) {
++ for (k = type_keys; k; k = k->next) {
+ str *type_key = &k->key;
+
+ LM_DBG("inserting entry key '%.*s' to type map '%.*s'\n",
@@ -2960,6 +3063,7 @@ Index: kamailio/modules/db_redis/redis_dbase.c
+ int free_op = 0;
+ int do_table_scan = 0;
+ db_op_t *query_ops = NULL;
++ int i;
+
+ // TODO: optimize mapping-based manual post-check (remove check for keys already
+ // in type query key)
@@ -2993,7 +3097,7 @@ Index: kamailio/modules/db_redis/redis_dbase.c
+ LM_ERR("Failed to allocate memory for query op list\n");
+ goto error;
+ }
-+ for (int i = 0; i < _n; ++i) {
++ for (i = 0; i < _n; ++i) {
+ query_ops[i] = op;
+ }
+ } else {
@@ -3071,6 +3175,7 @@ Index: kamailio/modules/db_redis/redis_dbase.c
+ int *manual_keys = NULL;
+ int manual_keys_count = 0;
+ db_op_t *query_ops = NULL;
++ int i;
+
+ // TODO: optimize mapping-based manual post-check (remove check for keys already
+ // in type query key)
@@ -3104,7 +3209,7 @@ Index: kamailio/modules/db_redis/redis_dbase.c
+ LM_ERR("Failed to allocate memory for query op list\n");
+ goto error;
+ }
-+ for (int i = 0; i < _n; ++i) {
++ for (i = 0; i < _n; ++i) {
+ query_ops[i] = op;
+ }
+ } else {
@@ -3185,10 +3290,8 @@ Index: kamailio/modules/db_redis/redis_dbase.c
+ db_free_result(_r);
+ return 0;
+}
-Index: kamailio/modules/db_redis/redis_dbase.h
-===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ kamailio/modules/db_redis/redis_dbase.h 2018-02-14 15:23:35.853985199 +0100
+--- /dev/null
++++ b/modules/db_redis/redis_dbase.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2018 Andreas Granig (sipwise.com)
@@ -3269,7 +3372,7 @@ Index: kamailio/modules/db_redis/redis_dbase.h
+ * Just like insert, but replace the row if it exists
+ */
+int db_redis_replace(const db1_con_t* handle, const db_key_t* keys, const db_val_t* vals,
-+ const int n, const int _un, const int _m);
++ const int n, const int _un, const int _m);
+
+/*
+ * Store name of table that will be used by
@@ -3278,11 +3381,9 @@ Index: kamailio/modules/db_redis/redis_dbase.h
+int db_redis_use_table(db1_con_t* _h, const str* _t);
+
+#endif /* _REDIS_BASE_H_ */
-Index: kamailio/modules/db_redis/redis_table.c
-===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ kamailio/modules/db_redis/redis_table.c 2018-02-14 15:23:35.853985199 +0100
-@@ -0,0 +1,838 @@
+--- /dev/null
++++ b/modules/db_redis/redis_table.c
+@@ -0,0 +1,841 @@
+/*
+ * Copyright (C) 2018 Andreas Granig (sipwise.com)
+ *
@@ -3474,11 +3575,12 @@ Index: kamailio/modules/db_redis/redis_table.c
+ redis_table_t *table;
+ redis_key_t *key;
+ redis_type_t *type;
++ int i, j;
+
+ LM_DBG("dumping all redis tables:\n");
+ ht = &con->tables;
+
-+ for (int i = 0; i < ht->size; ++i) {
++ for (i = 0; i < ht->size; ++i) {
+ last = (&ht->table[i])->prev;
+ clist_foreach(&ht->table[i], he, next) {
+ LM_DBG(" table %.*s\n", he->key.len, he->key.s);
@@ -3486,7 +3588,7 @@ Index: kamailio/modules/db_redis/redis_table.c
+
+ LM_DBG(" schema:\n");
+ col_ht = &table->columns;
-+ for (int j = 0; j < col_ht->size; ++j) {
++ for (j = 0; j < col_ht->size; ++j) {
+ col_last = (&col_ht->table[j])->prev;
+ clist_foreach(&col_ht->table[j], col_he, next) {
+ LM_DBG(" %.*s: %d\n",
@@ -3524,6 +3626,7 @@ Index: kamailio/modules/db_redis/redis_table.c
+ redis_table_t *table;
+ redis_key_t *key;
+ redis_type_t *type;
++ int j;
+
+ struct str_hash_table *col_ht;
+ struct str_hash_entry *col_he;
@@ -3544,7 +3647,7 @@ Index: kamailio/modules/db_redis/redis_table.c
+
+ LM_DBG(" schema:\n");
+ col_ht = &table->columns;
-+ for (int j = 0; j < col_ht->size; ++j) {
++ for (j = 0; j < col_ht->size; ++j) {
+ col_last = (&col_ht->table[j])->prev;
+ clist_foreach(&col_ht->table[j], col_he, next) {
+ LM_DBG(" %.*s: %d\n",
@@ -3583,15 +3686,16 @@ Index: kamailio/modules/db_redis/redis_table.c
+ redis_table_t *table;
+ redis_key_t *key, *tmpkey;
+ redis_type_t *type, *tmptype;
++ int i, j;
+
+ ht = &con->tables;
-+ for (int i = 0; i < ht->size; ++i) {
++ for (i = 0; i < ht->size; ++i) {
+ last = (&ht->table[i])->prev;
+ clist_foreach(&ht->table[i], he, next) {
+ table = (redis_table_t*) he->u.p;
+
+ col_ht = &table->columns;
-+ for (int j = 0; j < col_ht->size; ++j) {
++ for (j = 0; j < col_ht->size; ++j) {
+ col_last = (&col_ht->table[j])->prev;
+ clist_foreach(&col_ht->table[j], col_he, next) {
+ pkg_free(col_he->key.s);
@@ -4121,10 +4225,8 @@ Index: kamailio/modules/db_redis/redis_table.c
+ }
+ return -1;
+}
-Index: kamailio/modules/db_redis/redis_table.h
-===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ kamailio/modules/db_redis/redis_table.h 2018-02-14 15:23:35.853985199 +0100
+--- /dev/null
++++ b/modules/db_redis/redis_table.h
@@ -0,0 +1,66 @@
+/**
+ * Copyright (C) 2018 Andreas Granig (sipwise.com)
@@ -4169,7 +4271,7 @@ Index: kamailio/modules/db_redis/redis_table.h
+
+typedef struct redis_table redis_table_t;
+struct redis_table {
-+ int version;
++ int version;
+ redis_key_t *entry_keys;
+ redis_type_t *types;
+ struct str_hash_table columns;
@@ -4192,10 +4294,8 @@ Index: kamailio/modules/db_redis/redis_table.h
+int db_redis_keys_spec(char *spec);
+
+#endif /* _REDIS_TABLE_H_ */
-Index: kamailio/doc/stylesheets/dbschema_k/xsl/db_redis.xsl
-===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ kamailio/doc/stylesheets/dbschema_k/xsl/db_redis.xsl 2018-02-14 15:23:35.853985199 +0100
+--- /dev/null
++++ b/doc/stylesheets/dbschema_k/xsl/db_redis.xsl
@@ -0,0 +1,126 @@
+
+