b71a32a2daabdc694c991a532a2331f4b79244e7
[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 lc = 0;
23         int rc = 0;
24         char buf[128];
25
26         if (!fp) return 1;
27         while (fgets(buf, sizeof(buf), fp)) {
28                 char *k, *v, *e;
29
30                 lc++;
31                 e = buf + strlen(buf) - 1;
32                 if (*e == '\n') *e = '\0';
33                 else {
34                         g_warning("%s:%d line too long", conffile, lc);
35                         rc = 1;
36                         break;
37                 }
38                 if ((k = strchr(buf, '#'))) {
39                         e=k;
40                         *e = '\0';
41                 }
42                 for (k = buf; k < e && isspace(*k); k++) /*nothing*/ ;
43                 for (v = k; v < e && !isspace(*v)
44                             && *v != ':' && *v != '='; v++) /*nothing*/ ;
45                 *v++ = '\0';
46                 if (*k == '\0') continue; /* empty or comment-only line */
47                 for (; v < e && (isspace(*v) || *v == ':' || *v == '=')
48                                                         ; v++) /*nothing*/ ;
49                 if (v >= e) {
50                         g_warning("%s:%d no value for key \"%s\"",
51                                         conffile, lc, k);
52                         rc = 1;
53                         break;
54                 } 
55 #ifdef TEST_CONFIG
56                 printf("k=%s v=%s\n", k, v);
57 #endif
58                 if      (!strcmp(k, "host"))     host = strdup(v);
59                 else if (!strcmp(k, "user"))     user = strdup(v);
60                 else if (!strcmp(k, "password")) pass = strdup(v);
61                 else if (!strcmp(k, "database")) dbnm = strdup(v);
62                 else {
63                         g_warning("%s:%d unrecognized key \"%s\"",
64                                         conffile, lc, k);
65                         rc = 1;
66                         break;
67                 }
68         }
69         return rc;
70 }
71
72 int dbstore(uint8_t which, uint32_t val)
73 {
74         time_t t;
75         int i;
76         MYSQL mysql;
77         int rc = 0;
78         struct tm tm;
79         char buf[64];
80         char tstr[32];
81         char *table = (which == 1) ? "cold" : "hot";
82         char statement[64];
83         MYSQL_RES *result;
84         uint32_t prev_val = 0;
85
86         t = time(NULL);
87         (void)gmtime_r(&t, &tm);
88         (void)strftime(tstr, sizeof(tstr), "%Y-%m-%d %H:%M:%S", &tm);
89         mysql_init(&mysql);
90         if(!mysql_real_connect(&mysql, host, user, pass, dbnm, 0, NULL, 0)) {
91                 g_warning("mysql connect error: %s\n", mysql_error(&mysql));
92                 return 1;
93         }
94         mysql_autocommit(&mysql, FALSE);
95         /* ======== */
96         snprintf(statement, sizeof(statement),
97                  "select value from %scnt order by timestamp desc limit 1;\n",
98                  table);
99         if ((rc = mysql_query(&mysql, statement)))
100                 g_warning("mysql \"%s\" error: %s\n",
101                                 statement, mysql_error(&mysql));
102         else if ((result = mysql_store_result(&mysql))){
103                 MYSQL_ROW row = mysql_fetch_row(result);
104                 if (row && *row) prev_val = atoi(*row);
105                 mysql_free_result(result);
106         }
107         if (val <= prev_val) {
108                 snprintf(statement, sizeof(statement),
109                          "insert into %sadj values (\"%s\",%u);\n",
110                          table, tstr, prev_val);
111                 g_info("%s %u <= %u, %s", table, val, prev_val, statement);
112                 if ((rc = mysql_query(&mysql, statement)))
113                         g_warning("mysql \"%s\" error: %s\n",
114                                         statement, mysql_error(&mysql));
115         }
116         snprintf(statement, sizeof(statement),
117                  "insert into %scnt values (\"%s\",%u);\n",
118                  table, tstr, val);
119         if ((rc = mysql_query(&mysql, statement)))
120                 g_warning("mysql \"%s\" error: %s\n",
121                                 statement, mysql_error(&mysql));
122         /* ======== */
123         if (!rc) {
124                 if ((rc = mysql_commit(&mysql)))
125                         g_warning("mysql commit error: %s\n",
126                                         mysql_error(&mysql));
127         }
128         mysql_close(&mysql);
129         return rc;
130 }
131
132 #ifdef TEST_CONFIG
133 int main(int const argc, char *argv[])
134 {
135         if (dbconfig(argv[1])) {
136                 printf("could not parse config file\n");
137                 return 1;
138         }
139         printf("host: %s\nuser: %s\npass: %s\ndbnm: %s\n",
140                 host, user, pass, dbnm);
141         return 0;
142 }
143 #endif