[shotwell/wip/phako/new-database: 3/3] WIP
- From: Jens Georg <jensgeorg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [shotwell/wip/phako/new-database: 3/3] WIP
- Date: Sat, 22 Feb 2020 08:52:42 +0000 (UTC)
commit 230dddf00e803474147af15a7d9387a7983ac84b
Author: Jens Georg <mail jensge org>
Date: Sat Feb 22 09:51:53 2020 +0100
WIP
src/db/DatabaseTable.vala | 8 ++-
src/db/VideoTable.vala | 114 ++++++++++++--------------------
src/db/librygel-db/database-cursor.vala | 6 +-
src/db/librygel-db/database.vala | 15 +++--
src/db/librygel-db/row.vala | 42 ++++++++++++
src/meson.build | 1 +
6 files changed, 102 insertions(+), 84 deletions(-)
---
diff --git a/src/db/DatabaseTable.vala b/src/db/DatabaseTable.vala
index 6bac30e8..af7ddb6e 100644
--- a/src/db/DatabaseTable.vala
+++ b/src/db/DatabaseTable.vala
@@ -85,12 +85,12 @@ public abstract class DatabaseTable {
// XXX: errmsg() is global, and so this will not be accurate in a threaded situation
protected static void fatal(string op, int res) {
- error("%s: [%d] %s", op, res, db.errmsg());
+ //error("%s: [%d] %s", op, res, db.errmsg());
}
// XXX: errmsg() is global, and so this will not be accurate in a threaded situation
protected static void warning(string op, int res) {
- GLib.warning("%s: [%d] %s", op, res, db.errmsg());
+ //GLib.warning("%s: [%d] %s", op, res, db.errmsg());
}
protected void set_table_name(string table_name) {
@@ -175,7 +175,9 @@ public abstract class DatabaseTable {
// Caller needs to bind value #1 before calling execute_update_by_id()
private void prepare_update_by_id(int64 id, string column, out Sqlite.Statement stmt) {
- string sql = "UPDATE %s SET %s=? WHERE id=?".printf(table_name, column);
+ try {
+ string sql = "UPDATE %s SET %s=? WHERE id=?".printf(table_name, column);
+ db.exec (sql, {(Value) id
int res = db.prepare_v2(sql, -1, out stmt);
assert(res == Sqlite.OK);
diff --git a/src/db/VideoTable.vala b/src/db/VideoTable.vala
index 8f7cfa6f..86127013 100644
--- a/src/db/VideoTable.vala
+++ b/src/db/VideoTable.vala
@@ -102,7 +102,7 @@ public class VideoTable : DatabaseTable {
// VideoRow.video_id, event_id, time_created are ignored on input. All fields are set on exit
// with values stored in the database.
- public VideoID add(VideoRow video_row) throws DatabaseError {
+ public VideoID add(VideoRow video_row) throws Rygel.Database.DatabaseError {
db.exec(
"INSERT INTO VideoTable (filename, width, height, clip_duration, is_interpretable, "
+ "filesize, timestamp, exposure_time, import_id, event_id, md5, time_created, title, comment) "
@@ -171,91 +171,63 @@ public class VideoTable : DatabaseTable {
return false;
}
+ private VideoRow? row_from_db (Rygel.Database.Row row) throws Rygel.Database.DatabaseError {
+ VideoRow video_row = new VideoRow();
+ video_row.video_id.id = row.at<int64> (0);
+ video_row.filepath = row.at<string> (1);
+ video_row.width = row.at<int> (2);
+ video_row.height = row.at<int> (3);
+ video_row.clip_duration = row.at<double> (4);
+ video_row.is_interpretable = row.at<bool> (5);
+ video_row.filesize = row.at<int64> (6);
+ video_row.timestamp = (time_t) row.at<int64> (7);
+ video_row.exposure_time = (time_t) row.at<int64> (8);
+ video_row.import_id.id = row.at<int64> (9);
+ video_row.event_id.id = row.at<int64> (10);
+ video_row.md5 = row.at<string> (11);
+ video_row.time_created = (time_t) row.at<int64> (12);
+ video_row.rating = Rating.unserialize(row.at<int> (13));
+ video_row.title = row.at<string> (14);
+ video_row.backlinks = row.at<string> (15);
+ video_row.time_reimported = (time_t) row.at<int64>( 16);
+ video_row.flags = row.at<int64> (17);
+ video_row.comment = row.at<string> (18);
+
+ return video_row;
+ }
+
public VideoRow? get_row(VideoID video_id) {
try {
var cursor = db.exec_cursor(
- "SELECT filename, width, height, clip_duration, is_interpretable, filesize, timestamp, "
+ "SELECT id, filename, width, height, clip_duration, is_interpretable, filesize, timestamp, "
+ "exposure_time, import_id, event_id, md5, time_created, rating, title, backlinks, "
+ "time_reimported, flags, comment FROM VideoTable WHERE id=?",
{(GLib.Value) video_id.id});
- var column = 0;
- VideoRow = new VideoRow();
- row.video_id = cursor.next();
+ var video_row = row_from_db (cursor.next());
+ video_row.video_id = video_id;
+
+ return video_row;
} catch (Rygel.Database.DatabaseError err) {
return null;
}
-
- Sqlite.Statement stmt;
- int res = db.prepare_v2,
- -1, out stmt);
- assert(res == Sqlite.OK);
-
- res = stmt.bind_int64(1, video_id.id);
- assert(res == Sqlite.OK);
-
- if (stmt.step() != Sqlite.ROW)
- return null;
-
- VideoRow row = new VideoRow();
- row.video_id = video_id;
- row.filepath = stmt.column_text(0);
- row.width = stmt.column_int(1);
- row.height = stmt.column_int(2);
- row.clip_duration = stmt.column_double(3);
- row.is_interpretable = (stmt.column_int(4) == 1);
- row.filesize = stmt.column_int64(5);
- row.timestamp = (time_t) stmt.column_int64(6);
- row.exposure_time = (time_t) stmt.column_int64(7);
- row.import_id.id = stmt.column_int64(8);
- row.event_id.id = stmt.column_int64(9);
- row.md5 = stmt.column_text(10);
- row.time_created = (time_t) stmt.column_int64(11);
- row.rating = Rating.unserialize(stmt.column_int(12));
- row.title = stmt.column_text(13);
- row.backlinks = stmt.column_text(14);
- row.time_reimported = (time_t) stmt.column_int64(15);
- row.flags = stmt.column_int64(16);
- row.comment = stmt.column_text(17);
-
- return row;
}
public Gee.ArrayList<VideoRow?> get_all() {
- Sqlite.Statement stmt;
- int res = db.prepare_v2(
+ var all = new Gee.ArrayList<VideoRow?>();
+
+ try {
+ var cursor = db.exec_cursor(
"SELECT id, filename, width, height, clip_duration, is_interpretable, filesize, "
+ "timestamp, exposure_time, import_id, event_id, md5, time_created, rating, title, "
- + "backlinks, time_reimported, flags, comment FROM VideoTable",
- -1, out stmt);
- assert(res == Sqlite.OK);
-
- Gee.ArrayList<VideoRow?> all = new Gee.ArrayList<VideoRow?>();
-
- while ((res = stmt.step()) == Sqlite.ROW) {
- VideoRow row = new VideoRow();
- row.video_id.id = stmt.column_int64(0);
- row.filepath = stmt.column_text(1);
- row.width = stmt.column_int(2);
- row.height = stmt.column_int(3);
- row.clip_duration = stmt.column_double(4);
- row.is_interpretable = (stmt.column_int(5) == 1);
- row.filesize = stmt.column_int64(6);
- row.timestamp = (time_t) stmt.column_int64(7);
- row.exposure_time = (time_t) stmt.column_int64(8);
- row.import_id.id = stmt.column_int64(9);
- row.event_id.id = stmt.column_int64(10);
- row.md5 = stmt.column_text(11);
- row.time_created = (time_t) stmt.column_int64(12);
- row.rating = Rating.unserialize(stmt.column_int(13));
- row.title = stmt.column_text(14);
- row.backlinks = stmt.column_text(15);
- row.time_reimported = (time_t) stmt.column_int64(16);
- row.flags = stmt.column_int64(17);
- row.comment = stmt.column_text(18);
-
- all.add(row);
+ + "backlinks, time_reimported, flags, comment FROM VideoTable");
+
+ foreach (var row in cursor) {
+ all.add (row_from_db (row));
+ }
+ } catch (Rygel.Database.DatabaseError err) {
+ GLib.warning ("Error querying database for video rows: %s", err.message);
}
-
+
return all;
}
diff --git a/src/db/librygel-db/database-cursor.vala b/src/db/librygel-db/database-cursor.vala
index 682f7cfc..1d9bfd3e 100644
--- a/src/db/librygel-db/database-cursor.vala
+++ b/src/db/librygel-db/database-cursor.vala
@@ -133,12 +133,12 @@ public class Rygel.Database.Cursor : Object {
*
* @return a pointer to the current row
*/
- public Statement* next () throws DatabaseError {
+ public Row next () throws DatabaseError {
this.has_next ();
this.throw_if_code_is_error (this.current_state);
this.dirty = true;
- return this.statement;
+ return new Row (this.statement);
}
// convenience functions for "foreach"
@@ -163,7 +163,7 @@ public class Rygel.Database.Cursor : Object {
return this.cursor.has_next ();
}
- public unowned Statement @get () throws DatabaseError {
+ public Row @get () throws DatabaseError {
return this.cursor.next ();
}
}
diff --git a/src/db/librygel-db/database.vala b/src/db/librygel-db/database.vala
index 6fa34b67..9fd45106 100644
--- a/src/db/librygel-db/database.vala
+++ b/src/db/librygel-db/database.vala
@@ -25,11 +25,12 @@ using Sqlite;
namespace Rygel.Database {
public errordomain DatabaseError {
- SQLITE_ERROR, /// Error code translated from SQLite
- OPEN, /// Error while opening database file
- PREPARE, /// Error while preparing a statement
- BIND, /// Error while binding values to a statement
- STEP /// Error while running through a result set
+ SQLITE_ERROR, /// Error code translated from SQLite
+ OPEN, /// Error while opening database file
+ PREPARE, /// Error while preparing a statement
+ BIND, /// Error while binding values to a statement
+ STEP, /// Error while running through a result set
+ OUT_OF_RANGE /// Range error while iterating through columns
}
public enum Flavor {
@@ -269,8 +270,8 @@ public class Rygel.Database.Database : Object, Initable {
GLib.Value[]? args = null)
throws DatabaseError {
var cursor = this.exec_cursor (sql, args);
- var statement = cursor.next ();
- return statement->column_int (0);
+ var row = cursor.next ();
+ return row.at<int> (0);
}
/**
diff --git a/src/db/librygel-db/row.vala b/src/db/librygel-db/row.vala
new file mode 100644
index 00000000..d6a8e62a
--- /dev/null
+++ b/src/db/librygel-db/row.vala
@@ -0,0 +1,42 @@
+using Sqlite;
+
+public class Rygel.Database.Row : Object {
+ private Statement *statement;
+ internal Row (Statement *statement) {
+ this.statement = statement;
+ }
+
+ public T at<T>(int index) throws DatabaseError {
+ if (index >= statement->column_count ()) {
+ throw new DatabaseError.OUT_OF_RANGE ("Query result only contains %d columns",
+ statement->column_count ());
+ }
+ if (typeof (T) == typeof (int64) ||
+ typeof (T) == typeof (uint64) ||
+ typeof (T) == typeof (int) ||
+ typeof (T) == typeof (uint) ||
+ typeof (T) == typeof (long) ||
+ typeof (T) == typeof (ulong)) {
+ return (T) statement->column_int64 (index);
+ }
+
+ if (typeof (T) == typeof (float) ||
+ typeof (T) == typeof (double)) {
+ return (T) statement->column_double (index);
+ }
+
+ if (typeof (T) == typeof (string)) {
+ return statement->column_text (index).dup ();
+ }
+
+ if (typeof (T) == typeof (void*)) {
+ return statement->column_blob (index);
+ }
+
+ if (typeof (T) == typeof (bool)) {
+ return statement->column_int (index) != 0;
+ }
+
+ assert_not_reached ();
+ }
+}
diff --git a/src/meson.build b/src/meson.build
index f2d04457..78a1c14f 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -62,6 +62,7 @@ executable('shotwell',
'db/librygel-db/database.vala',
'db/librygel-db/database-cursor.vala',
'db/librygel-db/collate.c',
+ 'db/librygel-db/row.vala',
'db/Db.vala',
'db/DatabaseTable.vala',
'db/PhotoTable.vala',
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]