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