Fix bug 328603 - Calendar sqlite database issues; renaming of storage.sdb. r=philipp
authorDaniel Boelzle [:dbo] <daniel.boelzle@sun.com>
Tue, 27 Jan 2009 16:10:22 +0100
changeset 1771 daa8b76471bff769faf7b05d3b536753489bdfe7
parent 1770 b2cb2f44642f705404dc663666fff7e0e39bd62b
child 1772 45a9d5cedf9459fbbf8cc8569cf8adde570c660a
push idunknown
push userunknown
push dateunknown
reviewersphilipp
bugs328603
Fix bug 328603 - Calendar sqlite database issues; renaming of storage.sdb. r=philipp
calendar/providers/storage/calStorageCalendar.js
--- a/calendar/providers/storage/calStorageCalendar.js
+++ b/calendar/providers/storage/calStorageCalendar.js
@@ -367,33 +367,75 @@ calStorageCalendar.prototype = {
         var path = aUri.path;
         var pos = path.indexOf("?id=");
 
         if (pos != -1) {
             id = parseInt(path.substr(pos+4));
             path = path.substr(0, pos);
         }
 
+        this.mCalId = id;
+        this.mUri = aUri;
+
         var dbService;
         if (aUri.scheme == "file") {
             var fileURL = aUri.QueryInterface(Components.interfaces.nsIFileURL);
             if (!fileURL)
                 throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
 
             // open the database
             dbService = Components.classes[kStorageServiceContractID].getService(kStorageServiceIID);
             this.mDB = dbService.openDatabase(fileURL.file);
         } else if (aUri.scheme == "moz-profile-calendar") {
             dbService = Components.classes[kStorageServiceContractID].getService(kStorageServiceIID);
+            let localDB = cal.getCalendarDirectory();
+            localDB.append("local.sqlite");
+            localDB = dbService.openDatabase(localDB);
+
             this.mDB = dbService.openSpecialDatabase("profile");
+            if (this.mDB.tableExists("cal_events")) { // migrate data to local.sqlite:
+                this.initDB(); // upgrade schema before migating data
+                let attachStatement = createStatement(this.mDB, "ATTACH DATABASE :file_path AS local_sqlite");
+                try {
+                    attachStatement.params.file_path = localDB.databaseFile.path;
+                    attachStatement.execute();
+                } catch (exc) {
+                    cal.ERROR(exc + ", error: " + this.mDB.lastErrorString);
+                    throw exc;
+                } finally {
+                    attachStatement.reset();
+                }
+                try {
+                    // hold lock on storage.sdb until we've migrated data from storage.sdb:
+                    this.mDB.beginTransactionAs(Components.interfaces.mozIStorageConnection.TRANSACTION_EXCLUSIVE);
+                    try {
+                        if (this.mDB.tableExists("cal_events")) { // check again (with lock)
+                            // take over data and drop from storage.sdb tables:
+                            for (let table in sqlTables) {
+                                this.mDB.executeSimpleSQL("CREATE TABLE local_sqlite." +  table +
+                                                          " AS SELECT * FROM " + table +
+                                                          "; DROP TABLE IF EXISTS " +  table);
+                            }
+                            this.mDB.commitTransaction();
+                        } else { // migration done in the meantime
+                            this.mDB.rollbackTransaction();
+                        }
+                    } catch (exc) {
+                        cal.ERROR(exc + ", error: " + this.mDB.lastErrorString);
+                        this.mDB.rollbackTransaction();
+                        throw exc;
+                    }
+                } finally {
+                    this.mDB.executeSimpleSQL("DETACH DATABASE local_sqlite");
+                }
+            }
+
+            this.mDB = localDB;
         }
 
-        this.mCalId = id;
-        this.mUri = aUri;
-
         this.initDB();
     },
 
     refresh: function() {
         // no-op
     },
 
     // void addItem( in calIItemBase aItem, in calIOperationListener aListener );