[pkg-fso-commits] [SCM] libframeworkd-phonegui branch, upstream, updated. 640da47bfcff755388d0fb8f443eb34e0dea3c72

Didier 'Ptitjes ptitjes at free.fr
Sat Dec 27 20:50:07 UTC 2008


The following commit has been merged in the upstream branch:
commit 500da2b70dae8cb83660ad6bbfa67f75dc4a9246
Author: Didier 'Ptitjes <ptitjes at free.fr>
Date:   Sun Dec 14 04:48:00 2008 +0100

    Read SQL file to init database and use prepared statement where possible.
    Signed-off-by: Didier 'Ptitjes <ptitjes at free.fr>

diff --git a/ophonekitd/data/phonelog-database.sql b/ophonekitd/data/phonelog-database.sql
new file mode 100644
index 0000000..b4e9bf8
--- /dev/null
+++ b/ophonekitd/data/phonelog-database.sql
@@ -0,0 +1,78 @@
+CREATE TABLE call_ids (
+	id INTEGER PRIMARY KEY,
+	number TEXT
+);
+
+CREATE TABLE call_events (
+	id INTEGER,
+	status INTEGER,
+	eventTime TIMESTAMP,
+	FOREIGN KEY (id) REFERENCES call_ids(id)
+);
+
+CREATE TRIGGER insert_call_events_eventTime AFTER  INSERT ON call_events
+BEGIN
+	UPDATE call_events SET eventTime = DATETIME('NOW')  WHERE rowid = new.rowid;
+END;
+
+CREATE VIEW calls AS
+SELECT 
+	id,
+	
+	(SELECT number
+		FROM call_ids
+		WHERE call_ids.id = call_events.id
+	)
+	AS number,
+	
+	(SELECT status
+		FROM call_events as e
+		WHERE e.id = call_events.id
+			AND (e.status = 0 OR e.status = 1)
+	)
+	AS direction,
+	
+	(SELECT eventTime
+		FROM call_events as e
+		WHERE e.id = call_events.id
+			AND (e.status = 0 OR e.status = 1)
+	)
+	AS startTime,
+	
+	(SELECT eventTime
+		FROM call_events as e
+		WHERE e.id = call_events.id
+			AND e.status = 2
+	)
+	AS activeTime,
+	
+	(SELECT eventTime
+		FROM call_events as e
+		WHERE e.id = call_events.id
+			AND e.status = 4
+	)
+	AS releaseTime,
+	
+	strftime('%M:%S',strftime('%s',(SELECT eventTime
+		FROM call_events as e
+		WHERE e.id = call_events.id
+			AND e.status = 4
+	)) - strftime('%s',(SELECT eventTime
+		FROM call_events as e
+		WHERE e.id = call_events.id
+			AND e.status = 2
+	)), "unixepoch")
+	AS duration
+	
+FROM call_events
+GROUP BY id;
+
+CREATE VIEW missed_calls AS
+SELECT id, number, direction, startTime FROM calls WHERE activeTime IS NULL;
+
+CREATE VIEW due_calls AS
+SELECT id, number, startTime
+FROM calls
+WHERE
+	direction = 0 AND activeTime IS NULL
+	AND id NOT IN (SELECT id FROM calls WHERE direction = 1 AND activeTime IS NOT NULL);
diff --git a/ophonekitd/src/ophonekitd-phonelog.c b/ophonekitd/src/ophonekitd-phonelog.c
index 0138ed8..e9ebae4 100644
--- a/ophonekitd/src/ophonekitd-phonelog.c
+++ b/ophonekitd/src/ophonekitd-phonelog.c
@@ -22,72 +22,136 @@
 #include <sqlite3.h>
 
 #define PHONELOG_DB_LOCATION "/var/db/phonelog.db"
-#define PHONELOG_CREATE_CALL_IDS_TABLE \
-	"CREATE TABLE call_ids (id INTEGER PRIMARY KEY, number TEXT)"
-#define PHONELOG_CREATE_CALL_EVENTS_TABLE \
-	"CREATE TABLE call_events (id INTEGER, status INT, eventTime TIMESTAMP, FOREIGN KEY (id) REFERENCES call_ids(id))"
-#define PHONELOG_CREATE_CALL_EVENTS_TRIGGER \
-	"CREATE TRIGGER insert_call_events_eventTime AFTER  INSERT ON call_events\nBEGIN\nUPDATE call_events SET eventTime = DATETIME('NOW')  WHERE rowid = new.rowid;\nEND"
+#define PHONELOG_DATABASE_SQL_FILE "/usr/share/ophonekitd/phonelog-database.sql"
+
+#define PHONELOG_INSERT_CALL \
+	"INSERT INTO call_ids (id, number) values (NULL, ?)"
+#define PHONELOG_INSERT_CALL_EVENT \
+	"INSERT INTO call_events (id, status) values (?, ?)"
 
 sqlite3 *db;
+sqlite3_stmt *insert_call;
+sqlite3_stmt *insert_call_event;
+
+int read_file(const char *name, char **content) {
+	FILE *file;
+	long size;
+	size_t result;
+
+	file = fopen(name, "rb");
+	if (file == NULL) {
+		g_debug("phonelog - file error while opening %s", name);
+		return 1;
+	}
+
+	/* Get file size */
+	fseek(file, 0, SEEK_END);
+	size = ftell(file);
+	rewind(file);
+
+	/* Allocate memory to contain the whole file */
+	*content = (char*) malloc(sizeof(char) * size);
+	if (*content == NULL) {
+		g_debug("phonelog - memory error while reading %s", name);
+		return 1;
+	}
+
+	/* Copy the file into the buffer */
+	result = fread(*content, 1, size, file);
+	if (result != size) {
+		g_debug("phonelog - file error while reading %s", name);
+		return 1;
+	}
+
+	fclose(file);
+	return 0;
+}
+
+void debug_io_error(const char* activity, int fatal) {
+	if (fatal) {
+		g_error("phonelog - error while %s\n", activity);
+		sqlite3_close(db);
+		db = 0;
+	} else {
+		g_debug("phonelog - error while %s\n", activity);
+	}
+}
+
+void debug_sqlite3_error(const char* activity, const int rc, int fatal) {
+	const char *err = sqlite3_errmsg(db);
+
+	if (fatal) {
+		g_error("phonelog - error while %s: %s (code=%d)\n", activity, err, rc);
+		sqlite3_close(db);
+		db = 0;
+	} else {
+		g_debug("phonelog - error while %s: %s (code=%d)\n", activity, err, rc);
+	}
+
+	if (err) {
+		sqlite3_free(&err);
+	}
+}
 
 void phonelog_init_database() {
 	int rc;
-	char *err = 0;
 	struct stat info;
 	int dbIsNew;
 
 	/* Test whether the database file exists */
 	dbIsNew = stat(PHONELOG_DB_LOCATION, &info) != 0;
 
-	if (dbIsNew) {
-		g_debug("phonelog - creating database tables and triggers");
-	}
-
 	/* Open the database */
-	rc = sqlite3_open(PHONELOG_DB_LOCATION, &db);
-	if (rc) {
-		g_debug("phonelog - can't open database: %s\n", sqlite3_errmsg(db));
-		sqlite3_close(db);
-		db = 0;
+	if ((rc = sqlite3_open(PHONELOG_DB_LOCATION, &db)) != SQLITE_OK) {
+		debug_sqlite3_error("opening database", rc, 1);
 		return;
 	}
 
 	/* Create the call_events table and trigger if the database is new */
 	if (dbIsNew) {
-		rc = sqlite3_exec(db, PHONELOG_CREATE_CALL_IDS_TABLE, 0, 0, &err);
-		if (rc != SQLITE_OK) {
-			g_debug("phonelog - SQL error: %s\n", err);
-			sqlite3_free(&err);
+		char *sql;
+		char *err = 0;
+
+		g_debug("phonelog - initiating database tables, triggers and views");
 
-			sqlite3_close(db);
-			db = 0;
+		if (read_file(PHONELOG_DATABASE_SQL_FILE, &sql)) {
+			debug_io_error("reading database SQL file", 1);
 			return;
 		}
 
-		rc = sqlite3_exec(db, PHONELOG_CREATE_CALL_EVENTS_TABLE, 0, 0, &err);
-		if (rc != SQLITE_OK) {
-			g_debug("phonelog - SQL error: %s\n", err);
-			sqlite3_free(&err);
-
-			sqlite3_close(db);
-			db = 0;
+		if ((rc = sqlite3_exec(db, sql, 0, 0, &err)) != SQLITE_OK) {
+			debug_sqlite3_error("executing SQL file", rc, 1);
 			return;
 		}
+	}
 
-		rc = sqlite3_exec(db, PHONELOG_CREATE_CALL_EVENTS_TRIGGER, 0, 0, &err);
-		if (rc != SQLITE_OK) {
-			g_debug("phonelog - SQL error: %s\n", err);
-			sqlite3_free(&err);
+	/* Prepare insert statements once and for all */
+	if (db) {
+		const char *pzTail;
+
+		if ((rc = sqlite3_prepare_v2(db, PHONELOG_INSERT_CALL, -1,
+				&insert_call, &pzTail)) != SQLITE_OK) {
+			debug_sqlite3_error("preparing insert call statement", rc, 1);
+			return;
+		}
 
-			sqlite3_close(db);
-			db = 0;
+		if ((rc = sqlite3_prepare_v2(db, PHONELOG_INSERT_CALL_EVENT, -1,
+				&insert_call_event, &pzTail)) != SQLITE_OK) {
+			debug_sqlite3_error("preparing insert call event statement", rc, 1);
 			return;
 		}
 	}
 }
 
 void phonelog_close_database() {
+	/* Finalize insert statements */
+	if (insert_call) {
+		sqlite3_finalize(insert_call);
+	}
+	if (insert_call_event) {
+		sqlite3_finalize(insert_call_event);
+	}
+
 	/* Close the database */
 	if (db) {
 		sqlite3_close(db);
@@ -96,50 +160,49 @@ void phonelog_close_database() {
 
 int phonelog_add_new_call(const gchar* number) {
 	int rc;
-	char *err = 0;
-	char *stmt = 0;
 
 	if (db) {
 		g_debug("phonelog - add new call, number: %s", number);
 
-		stmt = malloc(51 + strlen(number) + 1);
-		sprintf(stmt, "INSERT INTO call_ids (id, number) values (NULL, %s)",
-				number);
-		g_debug(stmt);
+		if ((rc = sqlite3_reset(insert_call)) != SQLITE_OK)
+			goto sqlite_error;
 
-		rc = sqlite3_exec(db, stmt, 0, 0, &err);
-		free(stmt);
+		if ((rc = sqlite3_bind_text(insert_call, 1, number, -1,
+				SQLITE_TRANSIENT)) != SQLITE_OK)
+			goto sqlite_error;
 
-		if (rc != SQLITE_OK) {
-			g_debug("phonelog - SQL error: %s\n", err);
-			sqlite3_free(&err);
-			return -1;
-		}
+		if ((rc = sqlite3_step(insert_call)) != SQLITE_DONE)
+			goto sqlite_error;
 
 		return sqlite3_last_insert_rowid(db);
 	}
+	return -1;
+
+	sqlite_error: debug_sqlite3_error("inserting call", rc, 0);
+	return -1;
 }
 
 void phonelog_log_call_event(const int unique_id, const int status) {
 	int rc;
-	char *err = 0;
-	char *stmt = 0;
-
-	g_debug("phonelog - logging call event, unique id: %u, status: %d",
-			unique_id, status);
 
 	if (db) {
-		stmt = malloc(48 + 100 + 1);
-		sprintf(stmt, "INSERT INTO call_events (id, status) values (%u, %u)",
+		g_debug("phonelog - logging call event, unique id: %u, status: %u",
 				unique_id, status);
-		g_debug(stmt);
 
-		rc = sqlite3_exec(db, stmt, 0, 0, &err);
-		free(stmt);
+		if ((rc = sqlite3_reset(insert_call_event)) != SQLITE_OK)
+			goto sqlite_error;
 
-		if (rc != SQLITE_OK) {
-			g_debug("phonelog - SQL error: %s\n", err);
-			sqlite3_free(&err);
-		}
+		if ((rc = sqlite3_bind_int(insert_call_event, 1, unique_id))
+				!= SQLITE_OK)
+			goto sqlite_error;
+
+		if ((rc = sqlite3_bind_int(insert_call_event, 2, status)) != SQLITE_OK)
+			goto sqlite_error;
+
+		if ((rc = sqlite3_step(insert_call_event)) != SQLITE_DONE)
+			goto sqlite_error;
 	}
+	return;
+
+	sqlite_error: debug_sqlite3_error("inserting call event", rc, 0);
 }

-- 
libframeworkd-phonegui



More information about the pkg-fso-commits mailing list