From 002238dff53b284c9455554f146176ee8de2de4a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab 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 --- 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