You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
241 lines
6.1 KiB
241 lines
6.1 KiB
7 years ago
|
From 002238dff53b284c9455554f146176ee8de2de4a Mon Sep 17 00:00:00 2001
|
||
|
From: Mauro Carvalho Chehab <mchehab@redhat.com>
|
||
|
Date: Fri, 31 May 2013 12:41:01 -0300
|
||
|
Subject: [PATCH 02/32] ras-record: make the code more generic
|
||
|
|
||
|
Now that we're ready to add more tables to the database, make
|
||
|
the code that creates and inserts data into the table more
|
||
|
generic.
|
||
|
|
||
|
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
|
||
|
---
|
||
|
ras-record.c | 173 +++++++++++++++++++++++++++++++++++++---------------------
|
||
|
1 files changed, 110 insertions(+), 63 deletions(-)
|
||
|
|
||
|
diff --git a/ras-record.c b/ras-record.c
|
||
|
index 8995c9e..3af0791 100644
|
||
|
--- a/ras-record.c
|
||
|
+++ b/ras-record.c
|
||
|
@@ -28,80 +28,128 @@
|
||
|
#include "ras-mc-handler.h"
|
||
|
#include "ras-logger.h"
|
||
|
|
||
|
+/* #define DEBUG_SQL 1 */
|
||
|
+
|
||
|
#define SQLITE_RAS_DB RASSTATEDIR "/" RAS_DB_FNAME
|
||
|
|
||
|
-const char *mc_event_db = " mc_event ";
|
||
|
-const char *mc_event_db_create_fields = "("
|
||
|
- "id INTEGER PRIMARY KEY"
|
||
|
- ", timestamp TEXT"
|
||
|
- ", err_count INTEGER"
|
||
|
- ", err_type TEXT"
|
||
|
- ", err_msg TEXT" /* 5 */
|
||
|
- ", label TEXT"
|
||
|
- ", mc INTEGER"
|
||
|
- ", top_layer INTEGER"
|
||
|
- ", middle_layer INTEGER"
|
||
|
- ", lower_layer INTEGER" /* 10 */
|
||
|
- ", address INTEGER"
|
||
|
- ", grain INTEGER"
|
||
|
- ", syndrome INTEGER"
|
||
|
- ", driver_detail TEXT" /* 14 */
|
||
|
- ")";
|
||
|
-
|
||
|
-const char *mc_event_db_fields = "("
|
||
|
- "id"
|
||
|
- ", timestamp"
|
||
|
- ", err_count"
|
||
|
- ", err_type"
|
||
|
- ", err_msg" /* 5 */
|
||
|
- ", label"
|
||
|
- ", mc"
|
||
|
- ", top_layer"
|
||
|
- ", middle_layer"
|
||
|
- ", lower_layer" /* 10 */
|
||
|
- ", address"
|
||
|
- ", grain"
|
||
|
- ", syndrome"
|
||
|
- ", driver_detail" /* 14 */
|
||
|
- ")";
|
||
|
-
|
||
|
-#define NUM_MC_EVENT_DB_VALUES 14
|
||
|
-
|
||
|
-const char *createdb = "CREATE TABLE IF NOT EXISTS";
|
||
|
+
|
||
|
+#define ARRAY_SIZE(x) (sizeof(x)/sizeof(*(x)))
|
||
|
+
|
||
|
+struct db_fields {
|
||
|
+ char *name;
|
||
|
+ char *type;
|
||
|
+};
|
||
|
+
|
||
|
+struct db_table_descriptor {
|
||
|
+ char *name;
|
||
|
+ const struct db_fields *fields;
|
||
|
+ size_t num_fields;
|
||
|
+};
|
||
|
+
|
||
|
+static const struct db_fields mc_event_fields[] = {
|
||
|
+ { .name="id", .type="INTEGER PRIMARY KEY" },
|
||
|
+ { .name="timestamp", .type="TEXT" },
|
||
|
+ { .name="err_count", .type="INTEGER" },
|
||
|
+ { .name="err_type", .type="TEXT" },
|
||
|
+ { .name="err_msg", .type="TEXT" },
|
||
|
+ { .name="label", .type="TEXT" },
|
||
|
+ { .name="mc", .type="INTEGER" },
|
||
|
+ { .name="top_layer", .type="INTEGER" },
|
||
|
+ { .name="middle_layer", .type="INTEGER" },
|
||
|
+ { .name="lower_layer", .type="INTEGER" },
|
||
|
+ { .name="address", .type="INTEGER" },
|
||
|
+ { .name="grain", .type="INTEGER" },
|
||
|
+ { .name="syndrome", .type="INTEGER" },
|
||
|
+ { .name="driver_detail", .type="TEXT" },
|
||
|
+};
|
||
|
+
|
||
|
+static const struct db_table_descriptor mc_event_tab = {
|
||
|
+ .name = "mc_event",
|
||
|
+ .fields = mc_event_fields,
|
||
|
+ .num_fields = ARRAY_SIZE(mc_event_fields),
|
||
|
+};
|
||
|
+
|
||
|
const char *insertdb = "INSERT INTO";
|
||
|
const char *valuesdb = " VALUES ";
|
||
|
|
||
|
-static int ras_mc_prepare_stmt(struct sqlite3_priv *priv)
|
||
|
+static int ras_mc_prepare_stmt(struct sqlite3_priv *priv,
|
||
|
+ sqlite3_stmt **stmt,
|
||
|
+ const struct db_table_descriptor *db_tab)
|
||
|
+
|
||
|
{
|
||
|
int i, rc;
|
||
|
- char sql[1024];
|
||
|
+ char sql[1024], *p = sql, *end = sql + sizeof(sql);
|
||
|
+ const struct db_fields *field;
|
||
|
+
|
||
|
+ p += snprintf(p, end - p, "INSERT INTO %s (",
|
||
|
+ db_tab->name);
|
||
|
+
|
||
|
+ for (i = 0; i < db_tab->num_fields; i++) {
|
||
|
+ field = &db_tab->fields[i];
|
||
|
+ p += snprintf(p, end - p, "%s", field->name);
|
||
|
+
|
||
|
+ if (i < db_tab->num_fields - 1)
|
||
|
+ p += snprintf(p, end - p, ", ");
|
||
|
+ }
|
||
|
|
||
|
- strcpy(sql, insertdb);
|
||
|
- strcat(sql, mc_event_db);
|
||
|
- strcat(sql, mc_event_db_fields);
|
||
|
- strcat(sql, valuesdb);
|
||
|
+ p += snprintf(p, end - p, ") VALUES ( NULL, ");
|
||
|
|
||
|
- strcat(sql, "(NULL, "); /* Auto-increment field */
|
||
|
- for (i = 1; i < NUM_MC_EVENT_DB_VALUES; i++) {
|
||
|
- if (i < NUM_MC_EVENT_DB_VALUES - 1)
|
||
|
+ for (i = 1; i < db_tab->num_fields; i++) {
|
||
|
+ if (i < db_tab->num_fields - 1)
|
||
|
strcat(sql, "?, ");
|
||
|
else
|
||
|
strcat(sql, "?)");
|
||
|
}
|
||
|
|
||
|
- rc = sqlite3_prepare_v2(priv->db, sql, -1, &priv->stmt, NULL);
|
||
|
+#ifdef DEBUG_SQL
|
||
|
+ log(TERM, LOG_INFO, "SQL: %s\n", sql);
|
||
|
+#endif
|
||
|
+
|
||
|
+ rc = sqlite3_prepare_v2(priv->db, sql, -1, stmt, NULL);
|
||
|
if (rc != SQLITE_OK)
|
||
|
- log(TERM, LOG_ERR, "Failed to prepare insert db on %s: error = %s\n",
|
||
|
- SQLITE_RAS_DB, sqlite3_errmsg(priv->db));
|
||
|
+ log(TERM, LOG_ERR,
|
||
|
+ "Failed to prepare insert db at table %s (db %s): error = %s\n",
|
||
|
+ db_tab->name, SQLITE_RAS_DB, sqlite3_errmsg(priv->db));
|
||
|
|
||
|
return rc;
|
||
|
}
|
||
|
|
||
|
+static int ras_mc_create_table(struct sqlite3_priv *priv,
|
||
|
+ const struct db_table_descriptor *db_tab)
|
||
|
+{
|
||
|
+ const struct db_fields *field;
|
||
|
+ char sql[1024], *p = sql, *end = sql + sizeof(sql);
|
||
|
+ int i,rc;
|
||
|
+
|
||
|
+ p += snprintf(p, end - p, "CREATE TABLE IF NOT EXISTS %s (",
|
||
|
+ db_tab->name);
|
||
|
+
|
||
|
+ for (i = 0; i < db_tab->num_fields; i++) {
|
||
|
+ field = &db_tab->fields[i];
|
||
|
+ p += snprintf(p, end - p, "%s %s", field->name, field->type);
|
||
|
+
|
||
|
+ if (i < db_tab->num_fields - 1)
|
||
|
+ p += snprintf(p, end - p, ", ");
|
||
|
+ }
|
||
|
+ p += snprintf(p, end - p, ")");
|
||
|
+
|
||
|
+#ifdef DEBUG_SQL
|
||
|
+ log(TERM, LOG_INFO, "SQL: %s\n", sql);
|
||
|
+#endif
|
||
|
+
|
||
|
+ rc = sqlite3_exec(priv->db, sql, NULL, NULL, NULL);
|
||
|
+ if (rc != SQLITE_OK) {
|
||
|
+ log(TERM, LOG_ERR,
|
||
|
+ "Failed to create table %s on %s: error = %d\n",
|
||
|
+ db_tab->name, SQLITE_RAS_DB, rc);
|
||
|
+ }
|
||
|
+ return rc;
|
||
|
+}
|
||
|
+
|
||
|
int ras_mc_event_opendb(unsigned cpu, struct ras_events *ras)
|
||
|
{
|
||
|
int rc;
|
||
|
sqlite3 *db;
|
||
|
- char sql[1024];
|
||
|
struct sqlite3_priv *priv;
|
||
|
|
||
|
printf("Calling %s()\n", __FUNCTION__);
|
||
|
@@ -137,27 +185,26 @@ int ras_mc_event_opendb(unsigned cpu, struct ras_events *ras)
|
||
|
free(priv);
|
||
|
return -1;
|
||
|
}
|
||
|
+ priv->db = db;
|
||
|
|
||
|
- strcpy(sql, createdb);
|
||
|
- strcat(sql, mc_event_db);
|
||
|
- strcat(sql, mc_event_db_create_fields);
|
||
|
- rc = sqlite3_exec(db, sql, NULL, NULL, NULL);
|
||
|
+ rc = ras_mc_create_table(priv, &mc_event_tab);
|
||
|
if (rc != SQLITE_OK) {
|
||
|
- log(TERM, LOG_ERR,
|
||
|
- "cpu %u: Failed to create db on %s: error = %d\n",
|
||
|
- cpu, SQLITE_RAS_DB, rc);
|
||
|
+ sqlite3_close(db);
|
||
|
free(priv);
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
- priv->db = db;
|
||
|
- ras->db_priv = priv;
|
||
|
-
|
||
|
- rc = ras_mc_prepare_stmt(priv);
|
||
|
- if (rc == SQLITE_OK)
|
||
|
+ rc = ras_mc_prepare_stmt(priv, &priv->stmt, &mc_event_tab);
|
||
|
+ if (rc == SQLITE_OK) {
|
||
|
log(TERM, LOG_INFO,
|
||
|
"cpu %u: Recording events at %s\n",
|
||
|
cpu, SQLITE_RAS_DB);
|
||
|
+ ras->db_priv = priv;
|
||
|
+ } else {
|
||
|
+ sqlite3_close(db);
|
||
|
+ free(priv);
|
||
|
+ return -1;
|
||
|
+ }
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
--
|
||
|
1.7.1
|
||
|
|