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