/* Copyright 2011-2015 Yorba Foundation * * This software is licensed under the GNU Lesser General Public License * (version 2.1 or later). See the COPYING file in this distribution. */ public struct EventID { public const int64 INVALID = -1; public int64 id; public EventID(int64 id = INVALID) { this.id = id; } public bool is_invalid() { return (id == INVALID); } public bool is_valid() { return (id != INVALID); } } public class EventRow { public EventID event_id; public string? name; public time_t time_created; public string? primary_source_id; public string? comment; } public class EventTable : DatabaseTable { private static EventTable instance = null; private EventTable() { Sqlite.Statement stmt; int res = db.prepare_v2("CREATE TABLE IF NOT EXISTS EventTable (" + "id INTEGER PRIMARY KEY, " + "name TEXT, " + "primary_photo_id INTEGER, " + "time_created INTEGER," + "primary_source_id TEXT," + "comment TEXT" + ")", -1, out stmt); assert(res == Sqlite.OK); res = stmt.step(); if (res != Sqlite.DONE) fatal("create photo table", res); set_table_name("EventTable"); } public static EventTable get_instance() { if (instance == null) instance = new EventTable(); return instance; } // Returns a valid source ID, creating one from a legacy primary photo ID when needed. private string? source_id_upgrade(int64 primary_photo_id, string? primary_source_id) { if (MediaCollectionRegistry.get_instance().is_valid_source_id(primary_source_id)) { return primary_source_id; } if (primary_photo_id != PhotoID.INVALID) { // Upgrade to source_id from photo_id. return PhotoID.upgrade_photo_id_to_source_id(PhotoID(primary_photo_id)); } return null; } public EventRow create(string? primary_source_id, string? comment) throws DatabaseError { assert(primary_source_id != null && primary_source_id != ""); Sqlite.Statement stmt; int res = db.prepare_v2( "INSERT INTO EventTable (primary_source_id, time_created, comment) VALUES (?, ?, ?)", -1, out stmt); assert(res == Sqlite.OK); time_t time_created = (time_t) now_sec(); res = stmt.bind_text(1, primary_source_id); assert(res == Sqlite.OK); res = stmt.bind_int64(2, time_created); assert(res == Sqlite.OK); res = stmt.bind_text(3, comment); assert(res == Sqlite.OK); res = stmt.step(); if (res != Sqlite.DONE) throw_error("EventTable.create", res); EventRow row = new EventRow(); row.event_id = EventID(db.last_insert_rowid()); row.name = null; row.primary_source_id = primary_source_id; row.time_created = time_created; row.comment = comment; return row; } // NOTE: The event_id in EventRow is ignored here. No checking is done to prevent // against creating duplicate events or for the validity of other fields in the row (i.e. // the primary photo ID). public EventID create_from_row(EventRow row) { Sqlite.Statement stmt; int res = db.prepare_v2("INSERT INTO EventTable (name, primary_photo_id, primary_source_id, time_created, comment) VALUES (?, ?, ?, ?, ?)", -1, out stmt); assert(res == Sqlite.OK); res = stmt.bind_text(1, row.name); assert(res == Sqlite.OK); res = stmt.bind_int64(2, PhotoID.INVALID); assert(res == Sqlite.OK); res = stmt.bind_text(3, row.primary_source_id); assert(res == Sqlite.OK); res = stmt.bind_int64(4, row.time_created); assert(res == Sqlite.OK); res = stmt.bind_text(5, row.comment); assert(res == Sqlite.OK); res = stmt.step(); if (res != Sqlite.DONE) { fatal("Event create_from_row", res); return EventID(); } return EventID(db.last_insert_rowid()); } public EventRow? get_row(EventID event_id) { Sqlite.Statement stmt; int res = db.prepare_v2( "SELECT name, primary_photo_id, primary_source_id, time_created, comment FROM EventTable WHERE id=?", -1, out stmt); assert(res == Sqlite.OK); res = stmt.bind_int64(1, event_id.id); assert(res == Sqlite.OK); if (stmt.step() != Sqlite.ROW) return null; EventRow row = new EventRow(); row.event_id = event_id; row.name = stmt.column_text(0); if (row.name != null && row.name.length == 0) row.name = null; row.primary_source_id = source_id_upgrade(stmt.column_int64(1), stmt.column_text(2)); row.time_created = (time_t) stmt.column_int64(3); row.comment = stmt.column_text(4); return row; } public void remove(EventID event_id) throws DatabaseError { delete_by_id(event_id.id); } public Gee.ArrayList get_events() { Sqlite.Statement stmt; int res = db.prepare_v2("SELECT id, name, primary_photo_id, primary_source_id, time_created, comment FROM EventTable", -1, out stmt); assert(res == Sqlite.OK); Gee.ArrayList event_rows = new Gee.ArrayList(); for (;;) { res = stmt.step(); if (res == Sqlite.DONE) { break; } else if (res != Sqlite.ROW) { fatal("get_events", res); break; } EventRow row = new EventRow(); row.event_id = EventID(stmt.column_int64(0)); row.name = stmt.column_text(1); row.primary_source_id = source_id_upgrade(stmt.column_int64(2), stmt.column_text(3)); row.time_created = (time_t) stmt.column_int64(4); row.comment = stmt.column_text(5); event_rows.add(row); } return event_rows; } public bool rename(EventID event_id, string? name) { return update_text_by_id(event_id.id, "name", name != null ? name : ""); } public string? get_name(EventID event_id) { Sqlite.Statement stmt; if (!select_by_id(event_id.id, "name", out stmt)) return null; string name = stmt.column_text(0); return (name != null && name.length > 0) ? name : null; } public string? get_primary_source_id(EventID event_id) { Sqlite.Statement stmt; if (!select_by_id(event_id.id, "primary_source_id", out stmt)) return null; return stmt.column_text(0); } public bool set_primary_source_id(EventID event_id, string primary_source_id) { return update_text_by_id(event_id.id, "primary_source_id", primary_source_id); } public time_t get_time_created(EventID event_id) { Sqlite.Statement stmt; if (!select_by_id(event_id.id, "time_created", out stmt)) return 0; return (time_t) stmt.column_int64(0); } public bool set_comment(EventID event_id, string new_comment) { return update_text_by_id(event_id.id, "comment", new_comment != null ? new_comment : ""); } }