Merge lp:~zeitgeist/zeitgeist/dbfails into lp:~zeitgeist/zeitgeist/bluebird

Proposed by Siegfried Gevatter
Status: Merged
Merge reported by: Siegfried Gevatter
Merged at revision: not available
Proposed branch: lp:~zeitgeist/zeitgeist/dbfails
Merge into: lp:~zeitgeist/zeitgeist/bluebird
Diff against target: 329 lines (+149/-25)
6 files modified
doc/zeitgeist-daemon.1 (+6/-0)
src/errors.vala (+6/-1)
src/sql-schema.vala (+13/-6)
src/sql.vala (+69/-7)
src/utils.vala (+18/-4)
src/zeitgeist-daemon.vala (+37/-7)
To merge this branch: bzr merge lp:~zeitgeist/zeitgeist/dbfails
Reviewer Review Type Date Requested Status
Michal Hruby (community) Approve
Siegfried Gevatter Needs Fixing
Review via email: mp+87195@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Siegfried Gevatter (rainct) wrote :

<mhr3> RainCT, can you propagate the error one more level up, so there's no need for the posix.exit?

review: Needs Fixing
lp:~zeitgeist/zeitgeist/dbfails updated
357. By Michal Hruby

Add a define to explain query plans

358. By Michal Hruby

Merge lp:~zeitgeist/zeitgeist/bluebird-no-distinct

359. By Seif Lotfy

Add Exclusive lock for secure writing

360. By Michal Hruby

Add real-world query samples

361. By Michal Hruby

Don't use fts when using in-memory database

362. By Michal Hruby

Don't display debug messages by default

363. By Michal Hruby

Add a way to disable extensions

364. By Seif Lotfy

Fix bug 909708 where inserting and event with 2 subjects.
Since we already parse the subjects before insertion I added a list with subj_uris to find if there is a duplicate and return 0 if one is found

365. By Michal Hruby

Fix Reindex in FTS indexer

366. By Michal Hruby

Disable the VolumeMonitor in StorageMonitor extension to avoid weird races

Revision history for this message
Michal Hruby (mhr3) wrote :

Yes, please :)

review: Needs Fixing
lp:~zeitgeist/zeitgeist/dbfails updated
367. By Seif Lotfy

optimize allocations of variants

368. By Seif Lotfy

Seperate the allocation optimization into a new method optimize_variant_allocation.
This optimization effects marshalling by slowint it down by around 0.06s for 10k
events yet saves us 10MB in memory consumption.

369. By Siegfried Gevatter

Merge Seif's FTS changes removing database writes.

370. By Siegfried Gevatter

Automatically recover from corrupt database and be more clear
on some other errors.

Revision history for this message
Michal Hruby (mhr3) wrote :

282 + throw err;
289 + throw err;
293 + throw err;

Seems like it could be moved out of the ifs.

Other than that it's fine.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'doc/zeitgeist-daemon.1'
2--- doc/zeitgeist-daemon.1 2012-01-02 19:31:15 +0000
3+++ doc/zeitgeist-daemon.1 2012-01-25 11:17:27 +0000
4@@ -87,6 +87,12 @@
5 .TP
6 .B 10
7 There is already a running Zeitgeist instance.
8+.TP
9+.B 21
10+Could not access the database file.
11+.TP
12+.B 22
13+The database file is locked.
14
15 .SH SEE ALSO
16 \fBzeitgeist-datahub\fR, \fBgnome-activity-journal\fR
17
18=== modified file 'src/errors.vala'
19--- src/errors.vala 2011-10-20 13:32:51 +0000
20+++ src/errors.vala 2012-01-25 11:17:27 +0000
21@@ -23,10 +23,15 @@
22 [DBus (name = "org.gnome.zeitgeist.EngineError")]
23 public errordomain EngineError
24 {
25+ BACKUP_FAILED,
26+ DATABASE_BUSY,
27+ DATABASE_CANTOPEN,
28+ DATABASE_CORRUPT,
29 DATABASE_ERROR,
30+ DATABASE_RETIRE_FAILED,
31 INVALID_ARGUMENT,
32 INVALID_KEY,
33- BACKUP_FAILED,
34+ EXISTING_INSTANCE,
35 }
36
37 // vala doesn't include proper headers, this fixes it
38
39=== modified file 'src/sql-schema.vala'
40--- src/sql-schema.vala 2011-12-31 19:15:54 +0000
41+++ src/sql-schema.vala 2012-01-25 11:17:27 +0000
42@@ -414,8 +414,8 @@
43 }
44
45 /**
46- * Execute the given SQL. If the query doesn't succeed, log a
47- * critical warning (potentially aborting the program).
48+ * Execute the given SQL. If the query doesn't succeed, throw
49+ * an error.
50 *
51 * @param database the database on which to run the query
52 * @param sql the SQL query to run
53@@ -426,10 +426,17 @@
54 int rc = database.exec (sql);
55 if (rc != Sqlite.OK)
56 {
57- const string fmt_str = "Can't create database: %d, %s\n\n" +
58- "Unable to execute SQL:\n%s";
59- var err_msg = fmt_str.printf (rc, database.errmsg (), sql);
60- throw new EngineError.DATABASE_ERROR (err_msg);
61+ if (rc == Sqlite.CORRUPT)
62+ {
63+ throw new EngineError.DATABASE_CORRUPT (database.errmsg ());
64+ }
65+ else
66+ {
67+ const string fmt_str = "Can't create database: %d, %s\n\n" +
68+ "Unable to execute SQL:\n%s";
69+ var err_msg = fmt_str.printf (rc, database.errmsg (), sql);
70+ throw new EngineError.DATABASE_ERROR (err_msg);
71+ }
72 }
73 }
74
75
76=== modified file 'src/sql.vala'
77--- src/sql.vala 2012-01-02 19:30:51 +0000
78+++ src/sql.vala 2012-01-25 11:17:27 +0000
79@@ -67,13 +67,7 @@
80
81 public ZeitgeistDatabase () throws EngineError
82 {
83- message ("Opening DB from %s", Utils.get_database_file_path ());
84- int rc = Sqlite.Database.open_v2 (
85- Utils.get_database_file_path (),
86- out database);
87- assert_query_success (rc, "Can't open database");
88-
89- DatabaseSchema.ensure_schema (database);
90+ open_database (true);
91
92 prepare_queries ();
93
94@@ -82,6 +76,74 @@
95 database.update_hook (update_callback);
96 }
97
98+ private void open_database (bool retry)
99+ throws EngineError
100+ {
101+ int rc = Sqlite.Database.open_v2 (
102+ Utils.get_database_file_path (),
103+ out database);
104+
105+ if (rc == Sqlite.OK)
106+ {
107+ try
108+ {
109+ // Error (like a malformed database) may not be exposed
110+ // until we try to operate on the database.
111+ DatabaseSchema.ensure_schema (database);
112+ }
113+ catch (EngineError err)
114+ {
115+ if (err is EngineError.DATABASE_CORRUPT && retry)
116+ rc = Sqlite.CORRUPT;
117+ else if (err is EngineError.DATABASE_CANTOPEN)
118+ rc = Sqlite.CANTOPEN;
119+ else if (err is EngineError.DATABASE_BUSY)
120+ rc = Sqlite.BUSY;
121+ else
122+ throw err;
123+ }
124+ }
125+
126+ if (rc != Sqlite.OK)
127+ {
128+ if (rc == Sqlite.CORRUPT && retry)
129+ {
130+ // The database disk image is malformed
131+ warning ("It looks like your database is corrupt. " +
132+ "It will be renamed and a new one will be created.");
133+ try
134+ {
135+ Utils.retire_database ();
136+ }
137+ catch (Error err)
138+ {
139+ string message =
140+ "Could not rename database: %s".printf (
141+ err.message);
142+ throw new EngineError.DATABASE_RETIRE_FAILED (message);
143+ }
144+ open_database (false);
145+ }
146+ else if (rc == Sqlite.PERM || rc == Sqlite.CANTOPEN)
147+ {
148+ // Access permission denied / Unable to open database file
149+ throw new EngineError.DATABASE_CANTOPEN (
150+ database.errmsg ());
151+ }
152+ else if (rc == Sqlite.BUSY)
153+ {
154+ // The database file is locked
155+ throw new EngineError.DATABASE_BUSY (database.errmsg ());
156+ }
157+ else
158+ {
159+ string message = "Can't open database: %d, %s".printf(rc,
160+ database.errmsg ());
161+ throw new EngineError.DATABASE_ERROR (message);
162+ }
163+ }
164+ }
165+
166 public uint32 get_last_id () throws EngineError
167 {
168 int last_id = -1;
169
170=== modified file 'src/utils.vala'
171--- src/utils.vala 2011-10-31 15:28:09 +0000
172+++ src/utils.vala 2012-01-25 11:17:27 +0000
173@@ -31,7 +31,8 @@
174 private static string DATABASE_FILE_BACKUP_PATH;
175 private static string LOCAL_EXTENSIONS_PATH;
176
177- public const string ZEITGEIST_DATA_FOLDER = "zeitgeist";
178+ public const string DATA_FOLDER = "zeitgeist";
179+ public const string DATABASE_BASENAME = "activity.sqlite";
180 public const string USER_EXTENSION_PATH = "";
181
182 // D-Bus
183@@ -48,7 +49,7 @@
184
185 DATA_PATH = Environment.get_variable ("ZEITGEIST_DATA_PATH") ??
186 Path.build_filename (Environment.get_user_data_dir (),
187- ZEITGEIST_DATA_FOLDER);
188+ DATA_FOLDER);
189
190 if (!FileUtils.test (DATA_PATH, FileTest.IS_DIR))
191 {
192@@ -66,7 +67,7 @@
193
194 DATABASE_FILE_PATH =
195 Environment.get_variable ("ZEITGEIST_DATABASE_PATH") ??
196- Path.build_filename (get_data_path (), "activity.sqlite");
197+ Path.build_filename (get_data_path (), DATABASE_BASENAME);
198
199 debug ("DATABASE_FILE_PATH = %s", DATABASE_FILE_PATH);
200
201@@ -80,13 +81,20 @@
202
203 DATABASE_FILE_BACKUP_PATH =
204 Environment.get_variable ("ZEITGEIST_DATABASE_BACKUP_PATH") ??
205- Path.build_filename (get_data_path (), "activity.sqlite.bck");
206+ Path.build_filename (get_data_path (),
207+ DATABASE_BASENAME + ".bck");
208
209 debug ("DATABASE_FILE_BACKUP_PATH = %s", DATABASE_FILE_BACKUP_PATH);
210
211 return DATABASE_FILE_BACKUP_PATH;
212 }
213
214+ public string get_database_file_retire_name ()
215+ {
216+ return DATABASE_BASENAME + ".%s.bck".printf (
217+ new DateTime.now_local ().format ("%Y%m%d-%H%M%S"));
218+ }
219+
220 public unowned string get_local_extensions_path ()
221 {
222 if (LOCAL_EXTENSIONS_PATH != null) return LOCAL_EXTENSIONS_PATH;
223@@ -113,6 +121,12 @@
224
225 original.copy (destination, FileCopyFlags.OVERWRITE, null, null);
226 }
227+
228+ public void retire_database () throws Error
229+ {
230+ File dbfile = File.new_for_path (get_database_file_path ());
231+ dbfile.set_display_name (get_database_file_retire_name ());
232+ }
233 }
234 }
235
236
237=== modified file 'src/zeitgeist-daemon.vala'
238--- src/zeitgeist-daemon.vala 2012-01-02 19:30:51 +0000
239+++ src/zeitgeist-daemon.vala 2012-01-25 11:17:27 +0000
240@@ -329,6 +329,7 @@
241 }
242
243 static void run ()
244+ throws Error
245 {
246 DBusConnection connection;
247 bool name_owned;
248@@ -342,8 +343,7 @@
249 }
250 catch (IOError err)
251 {
252- critical ("%s", err.message);
253- return;
254+ throw err;
255 }
256 if (name_owned)
257 {
258@@ -353,9 +353,10 @@
259 }
260 else
261 {
262- critical ("An existing instance was found. Please use " +
263+ warning ("An existing instance was found. Please use " +
264 "--replace to stop it and start a new instance.");
265- Posix.exit (10);
266+ throw new EngineError.EXISTING_INSTANCE (
267+ "Zeitgeist is running already.");
268 }
269 }
270
271@@ -370,8 +371,24 @@
272 }
273 catch (Error err)
274 {
275- critical ("%s", err.message);
276- return;
277+ if (err is EngineError.DATABASE_CANTOPEN)
278+ {
279+ warning ("Could not access the database file.\n" +
280+ "Please check the permissions of file %s.",
281+ Utils.get_database_file_path ());
282+ throw err;
283+ }
284+ else if (err is EngineError.DATABASE_BUSY)
285+ {
286+ warning ("It looks like another Zeitgeist instance " +
287+ "is already running (the database is locked). " +
288+ "If you want to start a new instance, use --replace.");
289+ throw err;
290+ }
291+ else
292+ {
293+ throw err;
294+ }
295 }
296
297 uint owner_id = Bus.own_name_on_connection (connection,
298@@ -437,7 +454,7 @@
299
300 return 0;
301 }
302-
303+
304 LogLevelFlags discarded = LogLevelFlags.LEVEL_DEBUG;
305 if (log_level != null)
306 {
307@@ -472,9 +489,22 @@
308
309 run ();
310 }
311+ catch (EngineError.EXISTING_INSTANCE err)
312+ {
313+ return 10;
314+ }
315+ catch (EngineError.DATABASE_CANTOPEN err)
316+ {
317+ return 21;
318+ }
319+ catch (EngineError.DATABASE_BUSY err)
320+ {
321+ return 22;
322+ }
323 catch (Error err)
324 {
325 warning ("%s", err.message);
326+ return 1;
327 }
328
329 return 0;

Subscribers

People subscribed via source and target branches