]> granicus.if.org Git - vnstat/commitdiff
implement second layer of interface merge support
authorTeemu Toivola <git@humdi.net>
Sun, 10 Mar 2019 20:47:52 +0000 (22:47 +0200)
committerTeemu Toivola <git@humdi.net>
Sun, 10 Mar 2019 20:47:52 +0000 (22:47 +0200)
src/dbsql.c
src/dbsql.h

index ef60c64eb47cb299c4af5108cc511eeec8f1c590..f305934afdbf9ecf80554571eaed6d212b5bb64a 100644 (file)
@@ -342,7 +342,7 @@ uint64_t db_getinterfacecount(void)
 
 uint64_t db_getinterfacecountbyname(const char *iface)
 {
-       int rc, i, search_count = 1;
+       int rc;
        uint64_t result = 0;
        char sql[512], *inquery = NULL;
        sqlite3_stmt *sqlstmt;
@@ -354,12 +354,7 @@ uint64_t db_getinterfacecountbyname(const char *iface)
                        sqlite3_snprintf(512, sql, "select count(*) from interface");
                }
        } else {
-               for (i = 0; i < (int)strlen(iface); i++) {
-                       if (iface[i] == '+') {
-                               search_count++;
-                       }
-               }
-               inquery = getifaceinquery(iface, (unsigned int)search_count);
+               inquery = getifaceinquery(iface);
                if (inquery == NULL) {
                        return 0;
                }
@@ -415,6 +410,34 @@ sqlite3_int64 db_getinterfaceid(const char *iface, const int createifnotfound)
        return ifaceid;
 }
 
+char *db_getinterfaceidin(const char *iface)
+{
+       int rc;
+       char sql[512], *result, *inquery;
+       sqlite3_stmt *sqlstmt;
+
+       result = NULL;
+       inquery = getifaceinquery(iface);
+       if (inquery == NULL) {
+               return NULL;
+       }
+       sqlite3_snprintf(512, sql, "select group_concat(id) from interface where name in (%q)", inquery);
+       free(inquery);
+       rc = sqlite3_prepare_v2(db, sql, -1, &sqlstmt, NULL);
+       if (rc == SQLITE_OK) {
+               if (sqlite3_step(sqlstmt) == SQLITE_ROW) {
+                       result = strdup((const char *)sqlite3_column_text(sqlstmt, 0));
+               }
+               sqlite3_finalize(sqlstmt);
+       } else {
+               db_errcode = rc;
+               snprintf(errorstring, 1024, "Failed to get interface id from database (%d): %s", rc, sqlite3_errmsg(db));
+               printe(PT_Error);
+       }
+
+       return result;
+}
+
 int db_setactive(const char *iface, const int active)
 {
        char sql[512];
@@ -495,16 +518,25 @@ int db_getcounters(const char *iface, uint64_t *rxcounter, uint64_t *txcounter)
 int db_getinterfaceinfo(const char *iface, interfaceinfo *info)
 {
        int rc;
-       char sql[512];
+       char sql[512], *ifaceidin = NULL;
        sqlite3_int64 ifaceid = 0;
        sqlite3_stmt *sqlstmt;
 
-       ifaceid = db_getinterfaceid(iface, 0);
-       if (ifaceid == 0) {
-               return 0;
+       if (strchr(iface, '+') == NULL) {
+               ifaceid = db_getinterfaceid(iface, 0);
+               if (ifaceid == 0) {
+                       return 0;
+               }
+               sqlite3_snprintf(512, sql, "select name, alias, active, strftime('%%s', created, 'utc'), strftime('%%s', updated, 'utc'), rxcounter, txcounter, rxtotal, txtotal from interface where id=%"PRId64";", (int64_t)ifaceid);
+       } else {
+               ifaceidin = db_getinterfaceidin(iface);
+               if (ifaceidin == NULL || strlen(ifaceidin) < 1) {
+                       return 0;
+               }
+               sqlite3_snprintf(512, sql, "select \"%q\", NULL, max(active), max(strftime('%%s', created, 'utc')), min(strftime('%%s', updated, 'utc')), 0, 0, sum(rxtotal), sum(txtotal) from interface where id in (%q);", iface, ifaceidin);
+               free(ifaceidin);
        }
 
-       sqlite3_snprintf(512, sql, "select name, alias, active, strftime('%%s', created, 'utc'), strftime('%%s', updated, 'utc'), rxcounter, txcounter, rxtotal, txtotal from interface where id=%"PRId64";", (int64_t)ifaceid);
        rc = sqlite3_prepare_v2(db, sql, -1, &sqlstmt, NULL);
        if (rc != SQLITE_OK) {
                db_errcode = rc;
@@ -1204,15 +1236,21 @@ void dbdatalistfree(dbdatalist **dbdata)
 
 }
 
-char *getifaceinquery(const char *input, const unsigned int ifacecount)
+char *getifaceinquery(const char *input)
 {
-       unsigned int i, j;
+       unsigned int i, j, ifacecount = 1;
        char *result;
 
        if (input[strlen(input)-1] == '+') {
                return NULL;
        }
 
+       for (i = 0; i < (unsigned int)strlen(input); i++) {
+               if (input[i] == '+') {
+                       ifacecount++;
+               }
+       }
+
        /* each interface requires two quotes and comma or \0 so 3 extra chars */
        j = (unsigned int)strlen(input) + ifacecount * 3;
        result = malloc(sizeof(char) * j);
index c68ca1629ea46aba2a84a2cdcd19b804ab9e4896..0b8950f6717ae07e05344da6aa16e71c00193b09 100644 (file)
@@ -45,6 +45,7 @@ int db_removeinterface(const char *iface);
 uint64_t db_getinterfacecount(void);
 uint64_t db_getinterfacecountbyname(const char *iface);
 sqlite3_int64 db_getinterfaceid(const char *iface, const int createifnotfound);
+char *db_getinterfaceidin(const char *iface);
 int db_setactive(const char *iface, const int active);
 int db_setupdated(const char *iface, const time_t timestamp);
 int db_setcounters(const char *iface, const uint64_t rxcounter, const uint64_t txcounter);
@@ -77,7 +78,7 @@ void updatelistinfo(dbdatalistinfo *listinfo, const uint64_t rx, const uint64_t
 int dbdatalistadd(dbdatalist **dbdata, const uint64_t rx, const uint64_t tx, const time_t timestamp, const int64_t rowid);
 void dbdatalistfree(dbdatalist **dbdata);
 
-char *getifaceinquery(const char *input, const unsigned int ifacecount);
+char *getifaceinquery(const char *input);
 
 /* global db */
 extern sqlite3 *db;