1/* 2* Copyright (c) 2011-2013 Yorba Foundation 3* 4* This program is free software; you can redistribute it and/or 5* modify it under the terms of the GNU Lesser General Public 6* License as published by the Free Software Foundation; either 7* version 2.1 of the License, or (at your option) any later version. 8* 9* This program is distributed in the hope that it will be useful, 10* but WITHOUT ANY WARRANTY; without even the implied warranty of 11* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12* General Public License for more details. 13* 14* You should have received a copy of the GNU General Public 15* License along with this program; if not, write to the 16* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17* Boston, MA 02110-1301 USA 18*/ 19 20public struct EventID { 21 public const int64 INVALID = -1; 22 23 public int64 id; 24 25 public EventID (int64 id = INVALID) { 26 this.id = id; 27 } 28 29 public bool is_invalid () { 30 return (id == INVALID); 31 } 32 33 public bool is_valid () { 34 return (id != INVALID); 35 } 36} 37 38public class EventRow { 39 public EventID event_id; 40 public string? name; 41 public int64 time_created; 42 public string? primary_source_id; 43 public string? comment; 44} 45 46public class EventTable : DatabaseTable { 47 private static EventTable instance = null; 48 49 private EventTable () { 50 var stmt = create_stmt ( 51 "CREATE TABLE IF NOT EXISTS EventTable (" 52 + "id INTEGER PRIMARY KEY, " 53 + "name TEXT, " 54 + "primary_photo_id INTEGER, " 55 + "time_created INTEGER," 56 + "primary_source_id TEXT," 57 + "comment TEXT" 58 + ")"); 59 60 var res = stmt.step (); 61 if (res != Sqlite.DONE) 62 fatal ("create photo table", res); 63 64 set_table_name ("EventTable"); 65 } 66 67 public static EventTable get_instance () { 68 if (instance == null) 69 instance = new EventTable (); 70 71 return instance; 72 } 73 74 // Returns a valid source ID, creating one from a legacy primary photo ID when needed. 75 private string? source_id_upgrade (int64 primary_photo_id, string? primary_source_id) { 76 if (MediaCollectionRegistry.get_instance ().is_valid_source_id (primary_source_id)) { 77 return primary_source_id; 78 } 79 if (primary_photo_id != PhotoID.INVALID) { 80 // Upgrade to source_id from photo_id. 81 return PhotoID.upgrade_photo_id_to_source_id (PhotoID (primary_photo_id)); 82 } 83 return null; 84 } 85 86 public EventRow create (string? primary_source_id, string? comment) throws DatabaseError { 87 assert (primary_source_id != null && primary_source_id != ""); 88 89 var stmt = create_stmt ("INSERT INTO EventTable (primary_source_id, time_created, comment) VALUES (?, ?, ?)"); 90 91 int64 time_created = now_sec (); 92 93 bind_text (stmt, 1, primary_source_id); 94 bind_int64 (stmt, 2, time_created); 95 bind_text (stmt, 3, comment); 96 97 var res = stmt.step (); 98 if (res != Sqlite.DONE) 99 throw_error ("EventTable.create", res); 100 101 EventRow row = new EventRow (); 102 row.event_id = EventID (db.last_insert_rowid ()); 103 row.name = null; 104 row.primary_source_id = primary_source_id; 105 row.time_created = time_created; 106 row.comment = comment; 107 108 return row; 109 } 110 111 // NOTE: The event_id in EventRow is ignored here. No checking is done to prevent 112 // against creating duplicate events or for the validity of other fields in the row (i.e. 113 // the primary photo ID). 114 public EventID create_from_row (EventRow row) { 115 var stmt = create_stmt ("INSERT INTO EventTable (name, primary_photo_id, primary_source_id, time_created, comment) VALUES (?, ?, ?, ?, ?)"); 116 117 bind_text (stmt, 1, row.name); 118 bind_int64 (stmt, 2, PhotoID.INVALID); 119 bind_text (stmt, 3, row.primary_source_id); 120 bind_int64 (stmt, 4, row.time_created); 121 bind_text (stmt, 5, row.comment); 122 123 var res = stmt.step (); 124 if (res != Sqlite.DONE) { 125 fatal ("Event create_from_row", res); 126 127 return EventID (); 128 } 129 130 return EventID (db.last_insert_rowid ()); 131 } 132 133 public EventRow? get_row (EventID event_id) { 134 var stmt = create_stmt ("SELECT name, primary_photo_id, primary_source_id, time_created, comment FROM EventTable WHERE id=?"); 135 136 bind_int64 (stmt, 1, event_id.id); 137 138 if (stmt.step () != Sqlite.ROW) { 139 return null; 140 } 141 142 EventRow row = new EventRow (); 143 row.event_id = event_id; 144 row.name = stmt.column_text (0); 145 if (row.name != null && row.name.length == 0) 146 row.name = null; 147 row.primary_source_id = source_id_upgrade (stmt.column_int64 (1), stmt.column_text (2)); 148 row.time_created = stmt.column_int64 (3); 149 row.comment = stmt.column_text (4); 150 151 return row; 152 } 153 154 public void remove (EventID event_id) throws DatabaseError { 155 delete_by_id (event_id.id); 156 } 157 158 public Gee.ArrayList < EventRow?> get_events () { 159 var stmt = create_stmt ("SELECT id, name, primary_photo_id, primary_source_id, time_created, comment FROM EventTable"); 160 161 Gee.ArrayList < EventRow?> event_rows = new Gee.ArrayList < EventRow?> (); 162 for (;;) { 163 var res = stmt.step (); 164 if (res == Sqlite.DONE) { 165 break; 166 } else if (res != Sqlite.ROW) { 167 fatal ("get_events", res); 168 169 break; 170 } 171 172 EventRow row = new EventRow (); 173 174 row.event_id = EventID (stmt.column_int64 (0)); 175 row.name = stmt.column_text (1); 176 row.primary_source_id = source_id_upgrade (stmt.column_int64 (2), stmt.column_text (3)); 177 row.time_created = stmt.column_int64 (4); 178 row.comment = stmt.column_text (5); 179 180 event_rows.add (row); 181 } 182 183 return event_rows; 184 } 185 186 public bool rename (EventID event_id, string? name) { 187 return update_text_by_id (event_id.id, "name", name != null ? name : ""); 188 } 189 190 public string? get_name (EventID event_id) { 191 Sqlite.Statement stmt; 192 if (!select_by_id (event_id.id, "name", out stmt)) 193 return null; 194 195 string name = stmt.column_text (0); 196 197 return (name != null && name.length > 0) ? name : null; 198 } 199 200 public string? get_primary_source_id (EventID event_id) { 201 Sqlite.Statement stmt; 202 if (!select_by_id (event_id.id, "primary_source_id", out stmt)) 203 return null; 204 205 return stmt.column_text (0); 206 } 207 208 public bool set_primary_source_id (EventID event_id, string primary_source_id) { 209 return update_text_by_id (event_id.id, "primary_source_id", primary_source_id); 210 } 211 212 public int64 get_time_created (EventID event_id) { 213 Sqlite.Statement stmt; 214 if (!select_by_id (event_id.id, "time_created", out stmt)) 215 return 0; 216 217 return stmt.column_int64 (0); 218 } 219 220 public bool set_comment (EventID event_id, string new_comment) { 221 return update_text_by_id (event_id.id, "comment", new_comment != null ? new_comment : ""); 222 } 223} 224