implement autoadjustment
[pulsecounter.git] / linux / dbstore.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <stdint.h>
4 #include <time.h>
5 #include <ctype.h>
6 #include <string.h>
7
8 #include <glib.h>
9
10 #include <mysql/mysql.h>
11
12 #include "dbstore.h"
13
14 static char *host = NULL;
15 static char *user = NULL;
16 static char *pass = NULL;
17 static char *dbnm = "watermeter";
18
19 int dbconfig(char *conffile)
20 {
21         FILE *fp = fopen(conffile, "r");
22         int rc = 0;
23         char buf[128];
24
25         if (!fp)
26                 return 1;
27         while (fgets(buf, sizeof(buf), fp)) {
28                 char *k, *v, *e;
29
30                 e = buf + strlen(buf) - 1;
31                 if (*e == '\n')
32                         *e = '\0';
33                 else {
34                         /* line too long */
35                         rc = 1;
36                         break;
37                 }
38                 for (k = buf; k < e && isspace(k); k++) /*nothing*/ ;
39                 if (*k == '#') break;
40                 for (v = k; v < e && !isspace(v)
41                             && *v != ':' && *v != '='; v++) /*nothing*/ ;
42                 if (v < e && (*v == ':' || *v == '=')) v++;
43                 for (; v < e && (isspace(v) || *v == ':' || *v == '=')
44                                                         ; v++) /*nothing*/ ;
45                 if (v >= e) {
46                         /* no value */
47                         rc = 1;
48                         break;
49                 }
50                 if      (!strcmp(k, "host"))     host = strdup(v);
51                 else if (!strcmp(k, "user"))     user = strdup(v);
52                 else if (!strcmp(k, "password")) pass = strdup(v);
53                 else if (!strcmp(k, "database")) dbnm = strdup(v);
54                 else {
55                         /* unknown key */
56                         rc = 1;
57                         break;
58                 }
59         }
60         return rc;
61 }
62
63 int dbstore(uint8_t which, uint32_t val)
64 {
65         time_t t;
66         int i;
67         MYSQL mysql;
68         int rc = 0;
69         struct tm tm;
70         char buf[64];
71         char tstr[32];
72         char *table = (which == 1) ? "cold" : "hot";
73         char statement[64];
74         MYSQL_RES *result;
75         uint32_t prev_val = 0;
76
77         t = time(NULL);
78         (void)gmtime_r(&t, &tm);
79         (void)strftime(tstr, sizeof(tstr), "%Y-%m-%d %H:%M:%S", &tm);
80         mysql_init(&mysql);
81         if(!mysql_real_connect(&mysql, host, user, pass, dbnm, 0, NULL, 0)) {
82                 g_warning("mysql connect error: %s\n", mysql_error(&mysql));
83                 return 1;
84         }
85         mysql_autocommit(&mysql, FALSE);
86         /* ======== */
87         snprintf(statement, sizeof(statement),
88                  "select value from %scnt order by timestamp desc limit 1;\n",
89                  table);
90         if ((rc = mysql_query(&mysql, statement)))
91                 g_warning("mysql \"%s\" error: %s\n",
92                                 statement, mysql_error(&mysql));
93         else if ((result = mysql_store_result(&mysql))){
94                 MYSQL_ROW row = mysql_fetch_row(result);
95                 if (row && *row) prev_val = atoi(*row);
96                 mysql_free_result(result);
97         }
98         if (val <= prev_val) {
99                 snprintf(statement, sizeof(statement),
100                          "insert into %sadj values (\"%s\",%u);\n",
101                          table, tstr, prev_val);
102                 g_info("%s %u <= %u, %s", table, val, prev_val, statement);
103                 if ((rc = mysql_query(&mysql, statement)))
104                         g_warning("mysql \"%s\" error: %s\n",
105                                         statement, mysql_error(&mysql));
106         }
107         snprintf(statement, sizeof(statement),
108                  "insert into %scnt values (\"%s\",%u);\n",
109                  table, tstr, val);
110         if ((rc = mysql_query(&mysql, statement)))
111                 g_warning("mysql \"%s\" error: %s\n",
112                                 statement, mysql_error(&mysql));
113         /* ======== */
114         if (!rc) {
115                 if ((rc = mysql_commit(&mysql)))
116                         g_warning("mysql commit error: %s\n",
117                                         mysql_error(&mysql));
118         }
119         mysql_close(&mysql);
120         return rc;
121 }