[CalendarServer-changes] [4574] CalendarServer/branches/users/wsanchez/deployment/twistedcaldav

source_changes at macosforge.org source_changes at macosforge.org
Tue Oct 6 11:04:14 PDT 2009


Revision: 4574
          http://trac.macosforge.org/projects/calendarserver/changeset/4574
Author:   cdaboo at apple.com
Date:     2009-10-06 11:04:11 -0700 (Tue, 06 Oct 2009)
Log Message:
-----------
Add an index on the timespan sqlite db. Tweak the yields in scheduling to yield once per
attendee only (provided there is more than one).

Modified Paths:
--------------
    CalendarServer/branches/users/wsanchez/deployment/twistedcaldav/index.py
    CalendarServer/branches/users/wsanchez/deployment/twistedcaldav/schedule.py
    CalendarServer/branches/users/wsanchez/deployment/twistedcaldav/test/test_index.py

Modified: CalendarServer/branches/users/wsanchez/deployment/twistedcaldav/index.py
===================================================================
--- CalendarServer/branches/users/wsanchez/deployment/twistedcaldav/index.py	2009-10-05 17:56:49 UTC (rev 4573)
+++ CalendarServer/branches/users/wsanchez/deployment/twistedcaldav/index.py	2009-10-06 18:04:11 UTC (rev 4574)
@@ -52,7 +52,7 @@
 log = Logger()
 
 db_basename = db_prefix + "sqlite"
-schema_version = "7"
+schema_version = "8"
 collection_types = {"Calendar": "Regular Calendar Collection", "iTIP": "iTIP Calendar Collection"}
 
 icalfbtype_to_indexfbtype = {
@@ -396,6 +396,11 @@
             )
             """
         )
+        q.execute(
+            """
+            create index STARTENDFLOAT on TIMESPAN (START, END, FLOAT)
+            """
+        )
 
         if uidunique:
             #
@@ -417,12 +422,24 @@
         Upgrade the database tables.
         """
         
+        schemaChanged = False
+
+        # 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
         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()

Modified: CalendarServer/branches/users/wsanchez/deployment/twistedcaldav/schedule.py
===================================================================
--- CalendarServer/branches/users/wsanchez/deployment/twistedcaldav/schedule.py	2009-10-05 17:56:49 UTC (rev 4573)
+++ CalendarServer/branches/users/wsanchez/deployment/twistedcaldav/schedule.py	2009-10-06 18:04:11 UTC (rev 4574)
@@ -444,12 +444,13 @@
         autoresponses = []
         for recipient in recipients:
 
-            # Yield to the reactor once through each loop
-            d = Deferred()
-            def _timedDeferred():
-                d.callback(True)
-            reactor.callLater(0.0, _timedDeferred)
-            yield d
+            # Yield to the reactor once through each loop if more than one attendee
+            if len(recipients) > 1:
+                d = Deferred()
+                def _timedDeferred():
+                    d.callback(True)
+                reactor.callLater(0.0, _timedDeferred)
+                yield d
 
             # Get the principal resource for this recipient
             principal = self.principalForCalendarUserAddress(recipient)
@@ -515,13 +516,6 @@
                         matchtotal = 0
                         for calendarResourceURL in fbset:
 
-                            # Yield to the reactor once through each loop
-                            d = Deferred()
-                            def _timedDeferred():
-                                d.callback(True)
-                            reactor.callLater(0.0, _timedDeferred)
-                            yield d
-
                             calendarResource = yield request.locateResource(calendarResourceURL)
                             if calendarResource is None or not calendarResource.exists() or not isCalendarCollectionResource(calendarResource):
                                 # We will ignore missing calendars. If the recipient has failed to

Modified: CalendarServer/branches/users/wsanchez/deployment/twistedcaldav/test/test_index.py
===================================================================
--- CalendarServer/branches/users/wsanchez/deployment/twistedcaldav/test/test_index.py	2009-10-05 17:56:49 UTC (rev 4573)
+++ CalendarServer/branches/users/wsanchez/deployment/twistedcaldav/test/test_index.py	2009-10-06 18:04:11 UTC (rev 4574)
@@ -432,6 +432,10 @@
 
             self.assertEqual(set(instances), index_results, msg=description)
 
+    def test_DBIndexed(self):
+    
+        self.assertEqual(set([row[1] for row in self.db._db_execute("PRAGMA index_list(TIMESPAN)")]), set(("STARTENDFLOAT",)))
+
 class SQLIndexUpgradeTests (twistedcaldav.test.util.TestCase):
     """
     Test abstract SQL DB class
@@ -582,57 +586,152 @@
                 """, name, uid, calendar.resourceType(), instances.limit
             )
 
+    class OldIndexv7(Index):
+
+        def _db_version(self):
+            """
+            @return: the schema version assigned to this index.
+            """
+            return "7"
+
+        def _db_init_data_tables_base(self, q, uidunique):
+            """
+            Initialise the underlying database tables.
+            @param q:           a database cursor to use.
+            """
+            #
+            # RESOURCE table is the primary index table
+            #   NAME: Last URI component (eg. <uid>.ics, RESOURCE primary key)
+            #   UID: iCalendar UID (may or may not be unique)
+            #   TYPE: iCalendar component type
+            #   RECURRANCE_MAX: Highest date of recurrence expansion
+            #   ORGANIZER: cu-address of the Organizer of the event
+            #
+            if uidunique:
+                q.execute(
+                    """
+                    create table RESOURCE (
+                        NAME           text unique,
+                        UID            text unique,
+                        TYPE           text,
+                        RECURRANCE_MAX date,
+                        ORGANIZER      text
+                    )
+                    """
+                )
+            else:
+                q.execute(
+                    """
+                    create table RESOURCE (
+                        NAME           text unique,
+                        UID            text,
+                        TYPE           text,
+                        RECURRANCE_MAX date
+                    )
+                    """
+                )
+    
+            #
+            # TIMESPAN table tracks (expanded) time spans for resources
+            #   NAME: Related resource (RESOURCE foreign key)
+            #   FLOAT: 'Y' if start/end are floating, 'N' otherwise
+            #   START: Start date
+            #   END: End date
+            #   FBTYPE: FBTYPE value:
+            #     '?' - unknown
+            #     'F' - free
+            #     'B' - busy
+            #     'U' - busy-unavailable
+            #     'T' - busy-tentative
+            #
+            q.execute(
+                """
+                create table TIMESPAN (
+                    NAME  text,
+                    FLOAT text(1),
+                    START date,
+                    END   date,
+                    FBTYPE text(1)
+                )
+                """
+            )
+    
+            if uidunique:
+                #
+                # RESERVED table tracks reserved UIDs
+                #   UID: The UID being reserved
+                #   TIME: When the reservation was made
+                #
+                q.execute(
+                    """
+                    create table RESERVED (
+                        UID  text unique,
+                        TIME date
+                    )
+                    """
+                )
+
     def setUp(self):
         super(SQLIndexUpgradeTests, self).setUp()
         self.site.resource.isCalendarCollection = lambda: True
         self.db = Index(self.site.resource)
-        self.olddb = SQLIndexUpgradeTests.OldIndexv6(self.site.resource)
+        self.olddbv6 = SQLIndexUpgradeTests.OldIndexv6(self.site.resource)
+        self.olddbv7 = SQLIndexUpgradeTests.OldIndexv7(self.site.resource)
 
     def prepareOldDB(self):
-        if os.path.exists(self.olddb.dbpath):
-            os.remove(self.olddb.dbpath)
+        if os.path.exists(self.olddbv6.dbpath):
+            os.remove(self.olddbv6.dbpath)
 
     def test_old_schema(self):
         
-        self.prepareOldDB()
+        for olddb in (self.olddbv6, self.olddbv7):
+            self.prepareOldDB()
+    
+            schema = olddb._db_value_for_sql(
+                """
+                select VALUE from CALDAV
+                 where KEY = 'SCHEMA_VERSION'
+                """)
+            self.assertEqual(schema, olddb._db_version())
 
-        schema = self.olddb._db_value_for_sql(
-            """
-            select VALUE from CALDAV
-             where KEY = 'SCHEMA_VERSION'
-            """)
-        self.assertEqual(schema, self.olddb._db_version())
-
     def test_empty_upgrade(self):
         
-        self.prepareOldDB()
+        for olddb in (self.olddbv6, self.olddbv7):
+            self.prepareOldDB()
+    
+            schema = olddb._db_value_for_sql(
+                """
+                select VALUE from CALDAV
+                 where KEY = 'SCHEMA_VERSION'
+                """)
+            self.assertEqual(schema, olddb._db_version())
+    
+            if olddb._db_version() == "6":
+                self.assertRaises(sqlite3.OperationalError, olddb._db_value_for_sql, "select ORGANIZER from RESOURCE")
+                self.assertRaises(sqlite3.OperationalError, olddb._db_value_for_sql, "select FBTYPE from TIMESPAN")
+            elif olddb._db_version() == "7":
+                olddb._db_value_for_sql("select ORGANIZER from RESOURCE")
+                olddb._db_value_for_sql("select FBTYPE from TIMESPAN")
+            self.assertEqual(set([row[1] for row in olddb._db_execute("PRAGMA index_list(TIMESPAN)")]), set())
+    
+            schema = self.db._db_value_for_sql(
+                """
+                select VALUE from CALDAV
+                 where KEY = 'SCHEMA_VERSION'
+                """)
+            self.assertEqual(schema, self.db._db_version())
+    
+            value = self.db._db_value_for_sql("select ORGANIZER from RESOURCE")
+            self.assertEqual(value, None)
+            self.assertEqual(set([row[1] for row in self.db._db_execute("PRAGMA index_list(TIMESPAN)")]), set(("STARTENDFLOAT",)))
 
-        schema = self.olddb._db_value_for_sql(
-            """
-            select VALUE from CALDAV
-             where KEY = 'SCHEMA_VERSION'
-            """)
-        self.assertEqual(schema, self.olddb._db_version())
-
-        self.assertRaises(sqlite3.OperationalError, self.olddb._db_value_for_sql, "select ORGANIZER from RESOURCE")
-        self.assertRaises(sqlite3.OperationalError, self.olddb._db_value_for_sql, "select FBTYPE from TIMESPAN")
-
-        schema = self.db._db_value_for_sql(
-            """
-            select VALUE from CALDAV
-             where KEY = 'SCHEMA_VERSION'
-            """)
-        self.assertEqual(schema, self.db._db_version())
-
-        value = self.db._db_value_for_sql("select ORGANIZER from RESOURCE")
-        self.assertEqual(value, None)
-
     def test_basic_upgrade(self):
         
-        self.prepareOldDB()
-
-        calendar_name = "1.ics"
-        calendar_data = """BEGIN:VCALENDAR
+        for olddb in (self.olddbv6, self.olddbv7):
+            self.prepareOldDB()
+    
+            calendar_name = "1.ics"
+            calendar_data = """BEGIN:VCALENDAR
 VERSION:2.0
 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
 BEGIN:VEVENT
@@ -645,28 +744,39 @@
 END:VEVENT
 END:VCALENDAR
 """
+    
+            olddb.addResource(calendar_name, Component.fromString(calendar_data))
+            self.assertTrue(olddb.resourceExists(calendar_name))
+    
+            if olddb._db_version() == "6":
+                self.assertRaises(sqlite3.OperationalError, olddb._db_value_for_sql, "select ORGANIZER from RESOURCE")
+                self.assertRaises(sqlite3.OperationalError, olddb._db_value_for_sql, "select FBTYPE from TIMESPAN")
+            elif olddb._db_version() == "7":
+                olddb._db_value_for_sql("select ORGANIZER from RESOURCE")
+                olddb._db_value_for_sql("select FBTYPE from TIMESPAN")
+            self.assertEqual(set([row[1] for row in olddb._db_execute("PRAGMA index_list(TIMESPAN)")]), set())
+    
+            value = self.db._db_value_for_sql("select ORGANIZER from RESOURCE where NAME = :1", calendar_name)
+            if olddb._db_version() == "6":
+                self.assertEqual(value, "?")
+            else:
+                self.assertEqual(value, "mailto:user1 at example.com")
+    
+            value = self.db._db_value_for_sql("select FBTYPE from TIMESPAN where NAME = :1", calendar_name)
+            if olddb._db_version() == "6":
+                self.assertEqual(value, "?")
+            else:
+                self.assertEqual(value, "B")
+    
+            self.db.addResource(calendar_name, Component.fromString(calendar_data))
+            self.assertTrue(olddb.resourceExists(calendar_name))
+    
+            value = self.db._db_value_for_sql("select ORGANIZER from RESOURCE where NAME = :1", calendar_name)
+            self.assertEqual(value, "mailto:user1 at example.com")
+    
+            value = self.db._db_value_for_sql("select FBTYPE from TIMESPAN where NAME = :1", calendar_name)
+            self.assertEqual(value, "B")
 
-        self.olddb.addResource(calendar_name, Component.fromString(calendar_data))
-        self.assertTrue(self.olddb.resourceExists(calendar_name))
-
-        self.assertRaises(sqlite3.OperationalError, self.olddb._db_value_for_sql, "select ORGANIZER from RESOURCE")
-        self.assertRaises(sqlite3.OperationalError, self.olddb._db_value_for_sql, "select FBTYPE from TIMESPAN")
-
-        value = self.db._db_value_for_sql("select ORGANIZER from RESOURCE where NAME = :1", calendar_name)
-        self.assertEqual(value, "?")
-
-        value = self.db._db_value_for_sql("select FBTYPE from TIMESPAN where NAME = :1", calendar_name)
-        self.assertEqual(value, "?")
-
-        self.db.addResource(calendar_name, Component.fromString(calendar_data))
-        self.assertTrue(self.olddb.resourceExists(calendar_name))
-
-        value = self.db._db_value_for_sql("select ORGANIZER from RESOURCE where NAME = :1", calendar_name)
-        self.assertEqual(value, "mailto:user1 at example.com")
-
-        value = self.db._db_value_for_sql("select FBTYPE from TIMESPAN where NAME = :1", calendar_name)
-        self.assertEqual(value, "B")
-
 class MemcacheTests(SQLIndexTests):
     def setUp(self):
         super(MemcacheTests, self).setUp()
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20091006/ab999b6a/attachment-0001.html>


More information about the calendarserver-changes mailing list