[CalendarServer-changes] [4849] CalendarServer/trunk/twistedcaldav
source_changes at macosforge.org
source_changes at macosforge.org
Thu Dec 10 09:28:32 PST 2009
Revision: 4849
http://trac.macosforge.org/projects/calendarserver/changeset/4849
Author: cdaboo at apple.com
Date: 2009-12-10 09:28:29 -0800 (Thu, 10 Dec 2009)
Log Message:
-----------
Make sure db upgrades are done with an exclusive transaction.
Modified Paths:
--------------
CalendarServer/trunk/twistedcaldav/index.py
CalendarServer/trunk/twistedcaldav/sql.py
Modified: CalendarServer/trunk/twistedcaldav/index.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/index.py 2009-12-09 23:37:16 UTC (rev 4848)
+++ CalendarServer/trunk/twistedcaldav/index.py 2009-12-10 17:28:29 UTC (rev 4849)
@@ -460,34 +460,27 @@
"""
)
- def _db_upgrade(self, old_version):
+ def _db_can_upgrade(self, old_version):
"""
- Upgrade the database tables.
+ Can we do an in-place upgrade
"""
- schemaChanged = False
+ # Previous versions can be upgraded as per _db_upgrade_data_tables
+ return True
+ def _db_upgrade_data_tables(self, q, old_version):
+ """
+ Upgrade the data from an older version of the DB.
+ """
+
# When going to version 8 all we need to do is add an index
if old_version < "8":
- self._db_connection = sqlite.connect(self.dbpath, isolation_level=None)
- q = self._db_connection.cursor()
q.execute("create index STARTENDFLOAT on TIMESPAN (START, END, FLOAT)")
- schemaChanged = True
- # When going to version 7 all we need to do is add a column to the time-range
+ # When going to version 7,8 all we need to do is add a column to the resource and timespan
if old_version < "7":
- self._db_connection = sqlite.connect(self.dbpath, isolation_level=None)
- q = self._db_connection.cursor()
q.execute("alter table RESOURCE add column ORGANIZER text default '?'")
q.execute("alter table TIMESPAN add column FBTYPE text(1) default '?'")
- schemaChanged = True
-
- if schemaChanged:
- self._db_upgrade_schema(q)
- self._db_close()
- return self._db()
- else:
- return super(AbstractCalendarIndex, self)._db_upgrade(old_version)
def notExpandedBeyond(self, minDate):
"""
Modified: CalendarServer/trunk/twistedcaldav/sql.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/sql.py 2009-12-09 23:37:16 UTC (rev 4848)
+++ CalendarServer/trunk/twistedcaldav/sql.py 2009-12-10 17:28:29 UTC (rev 4849)
@@ -1,5 +1,5 @@
##
-# Copyright (c) 2005-2007 Apple Inc. All rights reserved.
+# Copyright (c) 2005-2009 Apple Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -99,24 +99,9 @@
# Create CALDAV table if needed
if self._test_schema_table(q):
- q.execute(
- """
- select VALUE from CALDAV
- where KEY = 'SCHEMA_VERSION'
- """)
- version = q.fetchone()
+
+ version, dbtype = self._get_schema_version(q)
- if version is not None: version = version[0]
-
- q.execute(
- """
- select VALUE from CALDAV
- where KEY = 'TYPE'
- """)
- dbtype = q.fetchone()
-
- if dbtype is not None: dbtype = dbtype[0]
-
if (version != self._db_version()) or (dbtype != self._db_type()):
# Clean-up first
@@ -125,13 +110,6 @@
self._db_connection.close()
del(self._db_connection)
- if version != self._db_version():
- log.err("Database %s has different schema (v.%s vs. v.%s)"
- % (db_filename, version, self._db_version()))
-
- # Upgrade the DB
- return self._db_upgrade(version)
-
if dbtype != self._db_type():
log.err("Database %s has different type (%s vs. %s)"
% (db_filename, dbtype, self._db_type()))
@@ -140,6 +118,13 @@
os.remove(db_filename)
return self._db()
+ if version != self._db_version():
+ log.err("Database %s has different schema (v.%s vs. v.%s)"
+ % (db_filename, version, self._db_version()))
+
+ # Upgrade the DB
+ return self._db_upgrade(version)
+
else:
self._db_init(db_filename, q)
@@ -155,6 +140,27 @@
""")
return q.fetchone()
+ def _get_schema_version(self, q):
+ q.execute(
+ """
+ select VALUE from CALDAV
+ where KEY = 'SCHEMA_VERSION'
+ """)
+ version = q.fetchone()
+
+ if version is not None: version = version[0]
+
+ q.execute(
+ """
+ select VALUE from CALDAV
+ where KEY = 'TYPE'
+ """)
+ dbtype = q.fetchone()
+
+ if dbtype is not None: dbtype = dbtype[0]
+
+ return version, dbtype
+
def _db_init(self, db_filename, q):
"""
Initialise the underlying database tables.
@@ -228,24 +234,38 @@
if do_commit:
self._db_commit()
+ def _db_can_upgrade(self, old_version):
+
+ return self.persistent
+
def _db_upgrade(self, old_version):
"""
Upgrade the database tables.
"""
- if self.persistent:
+ if self._db_can_upgrade(old_version):
self._db_connection = sqlite.connect(self.dbpath, isolation_level=None)
q = self._db_connection.cursor()
- self._db_upgrade_data_tables(q, old_version)
- self._db_upgrade_schema(q)
+ q.execute("begin exclusive transaction")
+
+ # We re-check whether the schema version again AFTER we've got an exclusive
+ # lock as some other server process may have snuck in and already upgraded it
+ # before we got the lock, or whilst we were waiting for it.
+ version, _ignore_dbtype = self._get_schema_version(q)
+
+ if version != self._db_version():
+ self._db_upgrade_data_tables(q, old_version)
+ self._db_upgrade_schema(q)
+
+ q.execute("commit")
self._db_close()
- return self._db()
else:
# Non-persistent DB's by default can be removed and re-created. However, for simple
# DB upgrades they SHOULD override this method and handle those for better performance.
os.remove(self.dbpath)
- return self._db()
-
+
+ return self._db()
+
def _db_upgrade_data_tables(self, q, old_version):
"""
Upgrade the data from an older version of the DB.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20091210/fffb13af/attachment.html>
More information about the calendarserver-changes
mailing list