~rainct/zeitgeist/961974

« back to all changes in this revision

Viewing changes to src/sql.vala

  • Committer: Siegfried-Angel Gevatter Pujals
  • Date: 2012-04-05 12:12:49 UTC
  • Revision ID: siegfried@gevatter.com-20120405121249-k6e2ajamjik0x5s5
Enhanced database corruption detection and recovery.

Show diffs side-by-side

added added

removed removed

Lines of Context:
4
4
 *             By Siegfried-Angel Gevatter Pujals <siegfried@gevatter.com>
5
5
 *             By Seif Lotfy <seif@lotfy.com>
6
6
 * Copyright © 2011 Manish Sinha <manishsinha@ubuntu.com>
 
7
 * Copyright © 2012 Canonical Ltd.
 
8
 *             By Siegfried-A. Gevatter <siegfried.gevatter@collabora.co.uk>
7
9
 *
8
10
 * This program is free software: you can redistribute it and/or modify
9
11
 * it under the terms of the GNU Lesser General Public License as published by
106
108
            {
107
109
                try
108
110
                {
109
 
                    // Error (like a malformed database) may not be exposed
 
111
                    // Errors (like a malformed database) may not be exposed
110
112
                    // until we try to operate on the database.
111
113
                    if (is_read_only)
112
114
                    {
142
144
                    // The database disk image is malformed
143
145
                    warning ("It looks like your database is corrupt. " +
144
146
                        "It will be renamed and a new one will be created.");
145
 
                    try
146
 
                    {
147
 
                        Utils.retire_database ();
148
 
                    }
149
 
                    catch (Error err)
150
 
                    {
151
 
                        string message =
152
 
                            "Could not rename database: %s".printf (
153
 
                                err.message);
154
 
                        throw new EngineError.DATABASE_RETIRE_FAILED (message);
155
 
                    }
 
147
                    Utils.retire_database ();
156
148
                    open_database (false);
157
149
                }
158
150
                else if (rc == Sqlite.PERM || rc == Sqlite.CANTOPEN)
329
321
                string error_message = "%s: %d, %s".printf (
330
322
                    msg, rc, database.errmsg ());
331
323
                warning ("%s\n", error_message);
 
324
                assert_not_corrupt (rc);
332
325
                throw new EngineError.DATABASE_ERROR (error_message);
333
326
            }
334
327
        }
335
328
 
 
329
        /**
 
330
         * Ensure `rc' isn't SQLITE_CORRUPT. If it is, schedule a database
 
331
         * retire and Zeitgeist restart so a new database can be created,
 
332
         * unless in read-only mode, in which case EngineError.DATABASE_ERROR
 
333
         * will be thrown.
 
334
         *
 
335
         * This function should be called whenever assert_query_success isn't
 
336
         * used.
 
337
         *
 
338
         * @param rc error code returned by a SQLite call
 
339
         */
 
340
        public void assert_not_corrupt (int rc)
 
341
            throws EngineError
 
342
        {
 
343
            if (unlikely (rc == Sqlite.CORRUPT))
 
344
            {
 
345
                warning ("It looks like your database is corrupt: %s".printf (
 
346
                    database.errmsg ()));
 
347
                if (!is_read_only)
 
348
                {
 
349
                    // Sets a flag in the database indicating that it is
 
350
                    // corrupt. This will trigger a database retire and
 
351
                    // re-creation on the next startup.
 
352
                    DatabaseSchema.set_corruption_flag (database);
 
353
                }
 
354
                throw new EngineError.DATABASE_CORRUPT (database.errmsg ());
 
355
            }
 
356
        }
 
357
 
336
358
        private void prepare_read_queries () throws EngineError
337
359
        {
338
360
            int rc;