[CalendarServer-changes] [4484] CalendarServer/branches/users/cdaboo/partition-4464

source_changes at macosforge.org source_changes at macosforge.org
Thu Aug 6 09:12:02 PDT 2009


Revision: 4484
          http://trac.macosforge.org/projects/calendarserver/changeset/4484
Author:   cdaboo at apple.com
Date:     2009-08-06 09:11:58 -0700 (Thu, 06 Aug 2009)
Log Message:
-----------
Augment record database implementation. This can read data from an XML file or a DBAPI database. Nothing makes
use of this right now - next up will be integration with the DirectoryService classes.

Modified Paths:
--------------
    CalendarServer/branches/users/cdaboo/partition-4464/conf/auth/accounts.dtd
    CalendarServer/branches/users/cdaboo/partition-4464/twistedcaldav/database.py
    CalendarServer/branches/users/cdaboo/partition-4464/twistedcaldav/directory/xmlaccountsparser.py
    CalendarServer/branches/users/cdaboo/partition-4464/twistedcaldav/test/test_database.py

Added Paths:
-----------
    CalendarServer/branches/users/cdaboo/partition-4464/twistedcaldav/directory/augment.py
    CalendarServer/branches/users/cdaboo/partition-4464/twistedcaldav/directory/test/augments.xml
    CalendarServer/branches/users/cdaboo/partition-4464/twistedcaldav/directory/test/test_augment.py

Modified: CalendarServer/branches/users/cdaboo/partition-4464/conf/auth/accounts.dtd
===================================================================
--- CalendarServer/branches/users/cdaboo/partition-4464/conf/auth/accounts.dtd	2009-08-05 21:35:27 UTC (rev 4483)
+++ CalendarServer/branches/users/cdaboo/partition-4464/conf/auth/accounts.dtd	2009-08-06 16:11:58 UTC (rev 4484)
@@ -17,16 +17,16 @@
 <!ELEMENT accounts (user*, group*, resource*, location*) >
   <!ATTLIST accounts realm CDATA "">
 
-  <!ELEMENT user (uid+, guid, password, enable?, hosted-at, name, first-name?, last-name?, email-address*, enable-calendar?, cuaddr*)>
+  <!ELEMENT user (uid*, guid, password?, enable?, hosted-at?, name?, first-name?, last-name?, email-address*, enable-calendar?, cuaddr*)>
     <!ATTLIST user repeat CDATA "1">
 
-  <!ELEMENT group (uid+, guid, password, enable?, hosted-at, name, members, enable-calendar?, cuaddr*)>
+  <!ELEMENT group (uid*, guid, password?, enable?, hosted-at?, name?, members, enable-calendar?, cuaddr*)>
     <!ATTLIST group repeat CDATA "1">
 
-  <!ELEMENT resource (uid+, guid, password, enable?, hosted-at, name, enable-calendar?, cuaddr*, auto-schedule?, proxies?, read-only-proxies?)>
+  <!ELEMENT resource (uid*, guid, password?, enable?, hosted-at?, name?, enable-calendar?, cuaddr*, auto-schedule?, proxies?, read-only-proxies?)>
     <!ATTLIST resource repeat CDATA "1">
 
-  <!ELEMENT location (uid+, guid, password, enable?, hosted-at, name, enable-calendar?, cuaddr*, auto-schedule?, proxies?, read-only-proxies?)>
+  <!ELEMENT location (uid*, guid, password?, enable?, hosted-at?, name?, enable-calendar?, cuaddr*, auto-schedule?, proxies?, read-only-proxies?)>
     <!ATTLIST location repeat CDATA "1">
 
   <!ELEMENT member (#PCDATA)>

Modified: CalendarServer/branches/users/cdaboo/partition-4464/twistedcaldav/database.py
===================================================================
--- CalendarServer/branches/users/cdaboo/partition-4464/twistedcaldav/database.py	2009-08-05 21:35:27 UTC (rev 4483)
+++ CalendarServer/branches/users/cdaboo/partition-4464/twistedcaldav/database.py	2009-08-06 16:11:58 UTC (rev 4484)
@@ -59,8 +59,6 @@
     def __init__(self, dbID, dbapiName, dbapiArgs, persistent, **kwargs):
         """
         
-        @param pool: the ADAPI ConnectionPool to use.
-        @type dbpath: L{ConnectionPool}
         @param persistent: C{True} if the data in the DB must be perserved during upgrades,
             C{False} if the DB data can be re-created from an external source.
         @type persistent: bool
@@ -140,9 +138,43 @@
         if not self.initialized:
             yield self.open()
 
-        result = (yield self._db_execute(sql, *query_params))
+        yield self._db_execute(sql, *query_params)
+
+    @inlineCallbacks
+    def executescript(self, script):
+        
+        if not self.initialized:
+            yield self.open()
+
+        yield self._db_execute_script(script)
+
+    @inlineCallbacks
+    def query(self, sql, *query_params):
+        
+        if not self.initialized:
+            yield self.open()
+
+        result = (yield self._db_all_values_for_sql(sql, *query_params))
         returnValue(result)
 
+    @inlineCallbacks
+    def queryList(self, sql, *query_params):
+        
+        if not self.initialized:
+            yield self.open()
+
+        result = (yield self._db_values_for_sql(sql, *query_params))
+        returnValue(result)
+
+    @inlineCallbacks
+    def queryOne(self, sql, *query_params):
+        
+        if not self.initialized:
+            yield self.open()
+
+        result = (yield self._db_value_for_sql(sql, *query_params))
+        returnValue(result)
+
     def _db_version(self):
         """
         @return: the schema version assigned to this DB.
@@ -191,7 +223,7 @@
         #
         yield self._db_execute(
             """
-            create table CALDAV (
+            create table if not exists CALDAV (
                 KEY text unique,
                 VALUE text unique
             )
@@ -199,13 +231,13 @@
         )
         yield self._db_execute(
             """
-            insert into CALDAV (KEY, VALUE)
+            insert or ignore into CALDAV (KEY, VALUE)
             values ('SCHEMA_VERSION', :1)
             """, (self._db_version(),)
         )
         yield self._db_execute(
             """
-            insert into CALDAV (KEY, VALUE)
+            insert or ignore into CALDAV (KEY, VALUE)
             values ('TYPE', :1)
             """, (self._db_type(),)
         )
@@ -273,12 +305,27 @@
         """
         Remove the stored schema version table.
         """
-        yield self._db_execute("drop table CALDAV")
+        yield self._db_execute("drop table if exists CALDAV")
 
     @inlineCallbacks
+    def _db_all_values_for_sql(self, sql, *query_params):
+        """
+        Execute an SQL query and obtain the resulting values.
+        @param sql: the SQL query to execute.
+        @param query_params: parameters to C{sql}.
+        @return: an interable of values in the first column of each row
+            resulting from executing C{sql} with C{query_params}.
+        @raise AssertionError: if the query yields multiple columns.
+        """
+        
+        results = (yield self.pool.runQuery(sql, *query_params))
+        returnValue(tuple(results))
+
+    @inlineCallbacks
     def _db_values_for_sql(self, sql, *query_params):
         """
         Execute an SQL query and obtain the resulting values.
+
         @param sql: the SQL query to execute.
         @param query_params: parameters to C{sql}.
         @return: an interable of values in the first column of each row
@@ -293,6 +340,7 @@
     def _db_value_for_sql(self, sql, *query_params):
         """
         Execute an SQL query and obtain a single value.
+
         @param sql: the SQL query to execute.
         @param query_params: parameters to C{sql}.
         @return: the value resulting from the executing C{sql} with
@@ -305,15 +353,14 @@
             value = row
         returnValue(value)
 
-    @inlineCallbacks
     def _db_execute(self, sql, *query_params):
         """
-        Execute an SQL query and obtain the resulting values.
+        Execute an SQL operation that returns None.
+
         @param sql: the SQL query to execute.
         @param query_params: parameters to C{sql}.
         @return: an iterable of tuples for each row resulting from executing
             C{sql} with C{query_params}.
         """
         
-        results = (yield self.pool.runQuery(sql, *query_params))
-        returnValue(results)
+        return self.pool.runOperation(sql, *query_params)

Added: CalendarServer/branches/users/cdaboo/partition-4464/twistedcaldav/directory/augment.py
===================================================================
--- CalendarServer/branches/users/cdaboo/partition-4464/twistedcaldav/directory/augment.py	                        (rev 0)
+++ CalendarServer/branches/users/cdaboo/partition-4464/twistedcaldav/directory/augment.py	2009-08-06 16:11:58 UTC (rev 4484)
@@ -0,0 +1,263 @@
+##
+# Copyright (c) 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.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##
+
+from twistedcaldav.database import AbstractADBAPIDatabase
+from twistedcaldav.directory.xmlaccountsparser import XMLAccountsParser,\
+    RECORD_TYPES
+
+from twisted.internet.defer import inlineCallbacks, returnValue, succeed
+
+class AugmentRecord(object):
+    """
+    Augmented directory record information
+    """
+
+    def __init__(
+        self,
+        guid,
+        enabled,
+        hostedAt,
+        enabledForCalendaring,
+        autoSchedule,
+        calendarUserAddresses,  
+    ):
+        self.guid = guid
+        self.enabled = enabled
+        self.hostedAt = hostedAt
+        self.enabledForCalendaring = enabledForCalendaring
+        self.autoSchedule = autoSchedule
+        self.calendarUserAddresses = calendarUserAddresses
+
+class AugmentDB(object):
+    """
+    Abstract base class for an augment record database.
+    """
+    
+    def __init__(self):
+        pass
+    
+    def getAugmentRecord(self, guid):
+        """
+        Get an AugmentRecord for the specified GUID.
+
+        @param guid: directory GUID to lookup
+        @type guid: C{str}
+        
+        @return: L{Deferred}
+        """
+        
+        raise NotImplementedError("Child class must define this.")
+
+class AugmentXMLDB(AugmentDB):
+    """
+    XMLFile based augment database implementation.
+    """
+    
+    def __init__(self, xmlfilepath):
+        
+        self.xmlfilepath = xmlfilepath
+        self.db = {}
+        
+        self._parseXML()
+
+    def getAugmentRecord(self, guid):
+        """
+        Get an AugmentRecord for the specified GUID.
+
+        @param guid: directory GUID to lookup
+        @type guid: C{str}
+        
+        @return: L{Deferred}
+        """
+        
+        return succeed(self.db.get(guid))
+
+    def _parseXML(self):
+        
+        # We will re-use the XML account format and associated classes
+        
+        # Create a parser and do the parse
+        parser = XMLAccountsParser(self.xmlfilepath, externalUpdate=False)
+        
+        # Add all records to our DB
+        for recordType in RECORD_TYPES.values():
+            for record in parser.items[recordType].itervalues():
+                
+                # Create augment record from XML account record
+                augment = AugmentRecord(
+                    guid=record.guid,
+                    enabled=record.enabled,
+                    hostedAt=record.hostedAt,
+                    enabledForCalendaring=record.enabledForCalendaring,
+                    autoSchedule=record.autoSchedule,
+                    calendarUserAddresses=record.calendarUserAddresses,
+                )
+                
+                self.db[augment.guid] = augment
+
+
+class AugmentADAPI(AugmentDB, AbstractADBAPIDatabase):
+    """
+    DBAPI based augment database implementation.
+    """
+
+    schema_version = "1"
+    schema_type    = "AugmentDB"
+    
+    def __init__(self, dbID, dbapiName, dbapiArgs, **kwargs):
+        
+        self.cachedPartitions = {}
+        self.cachedHostedAt = {}
+        
+        AbstractADBAPIDatabase.__init__(self, dbID, dbapiName, dbapiArgs, True, **kwargs)
+        
+    @inlineCallbacks
+    def getAugmentRecord(self, guid):
+        """
+        Get an AugmentRecord for the specified GUID.
+
+        @param guid: directory GUID to lookup
+        @type guid: C{str}
+
+        @return: L{Deferred}
+        """
+        
+        # Query for the record information
+        results = (yield self.query("select GUID, ENABLED, PARTITIONID, CALENDARING, AUTOSCHEDULE, CUADDRS from AUGMENTS where GUID = :1", (guid,)))
+        if not results:
+            returnValue(None)
+        else:
+            guid, enabled, partitionid, enabdledForCalendaring, autoSchedule, cuaddrs = results[0]
+            
+            record = AugmentRecord(
+                guid = guid,
+                enabled = enabled == "T",
+                hostedAt = (yield self._getPartition(partitionid)),
+                enabledForCalendaring = enabdledForCalendaring == "T",
+                autoSchedule = autoSchedule == "T",
+                calendarUserAddresses = set(cuaddrs.split("\t")) if cuaddrs else set(),
+            )
+            
+            returnValue(record)
+
+    @inlineCallbacks
+    def addAugmentRecord(self, record):
+
+        partitionid = (yield self._getPartitionID(record.hostedAt))
+        cuaddrs = "\t".join(record.calendarUserAddresses)
+        
+        yield self.execute(
+            """insert into AUGMENTS
+            (GUID, ENABLED, PARTITIONID, CALENDARING, AUTOSCHEDULE, CUADDRS)
+            values (:1, :2, :3, :4, :5, :6)""",
+            (
+                record.guid,
+                "T" if record.enabled else "F",
+                partitionid,
+                "T" if record.enabledForCalendaring else "F",
+                "T" if record.autoSchedule else "F",
+                cuaddrs,)
+        )
+
+    @inlineCallbacks
+    def _getPartitionID(self, hostedat, createIfMissing=True):
+        
+        # We will use a cache for these as we do not expect changes whilst running
+        try:
+            returnValue(self.cachedHostedAt[hostedat])
+        except KeyError:
+            pass
+
+        partitionid = (yield self.queryOne("select PARTITIONID from PARTITIONS where HOSTEDAT = :1", (hostedat,)))
+        if partitionid == None:
+            yield self.execute("insert into PARTITIONS (HOSTEDAT) values (:1)", (hostedat,))
+            partitionid = (yield self.queryOne("select PARTITIONID from PARTITIONS where HOSTEDAT = :1", (hostedat,)))
+        self.cachedHostedAt[hostedat] = partitionid
+        returnValue(partitionid)
+
+    @inlineCallbacks
+    def _getPartition(self, partitionid):
+        
+        # We will use a cache for these as we do not expect changes whilst running
+        try:
+            returnValue(self.cachedPartitions[partitionid])
+        except KeyError:
+            pass
+
+        partition = (yield self.queryOne("select HOSTEDAT from PARTITIONS where PARTITIONID = :1", (partitionid,)))
+        self.cachedPartitions[partitionid] = partition
+        returnValue(partition)
+
+    @inlineCallbacks
+    def _getCUAddrs(self, augmentid):
+        
+        return self.queryList("select CUADDR from CUADDRS where AUGMENTID = :1", (augmentid,))
+
+    def _db_version(self):
+        """
+        @return: the schema version assigned to this index.
+        """
+        return AugmentADAPI.schema_version
+        
+    def _db_type(self):
+        """
+        @return: the collection type assigned to this index.
+        """
+        return AugmentADAPI.schema_type
+    
+    @inlineCallbacks
+    def _db_init_data_tables(self):
+        """
+        Initialise the underlying database tables.
+        """
+
+        #
+        # TESTTYPE table
+        #
+        yield self._db_execute(
+            """
+            create table AUGMENTS (
+                GUID         text unique,
+                ENABLED      text(1),
+                PARTITIONID  text,
+                CALENDARING  text(1),
+                AUTOSCHEDULE text(1),
+                CUADDRS      text
+            )
+            """
+        )
+        yield self._db_execute(
+            """
+            create table PARTITIONS (
+                PARTITIONID  integer primary key autoincrement,
+                HOSTEDAT     text
+            )
+            """
+        )
+
+    @inlineCallbacks
+    def _db_remove_data_tables(self):
+        yield self._db_execute("drop table if exists AUGMENTS")
+        yield self._db_execute("drop table if exists PARTITIONS")
+
+class AugmentSqliteDB(AugmentADAPI):
+    """
+    Sqlite based augment database implementation.
+    """
+
+    def __init__(self, dbpath):
+        
+        super(AugmentSqliteDB, self).__init__("Augments", "sqlite3", (dbpath,))

Added: CalendarServer/branches/users/cdaboo/partition-4464/twistedcaldav/directory/test/augments.xml
===================================================================
--- CalendarServer/branches/users/cdaboo/partition-4464/twistedcaldav/directory/test/augments.xml	                        (rev 0)
+++ CalendarServer/branches/users/cdaboo/partition-4464/twistedcaldav/directory/test/augments.xml	2009-08-06 16:11:58 UTC (rev 4484)
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+Copyright (c) 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.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<!DOCTYPE accounts SYSTEM "../../../conf/auth/accounts.dtd">
+
+<accounts realm="Test">
+  <user>
+    <guid>D11F03A0-97EA-48AF-9A6C-FAC7F3975766</guid>
+    <enable>true</enable>
+  </user>
+  <user>
+    <guid>6423F94A-6B76-4A3A-815B-D52CFD77935D</guid>
+    <enable>true</enable>
+    <enable-calendar>true</enable-calendar>
+    <cuaddr>mailto:wsanchez at example.com</cuaddr>
+  </user>
+  <user>
+    <guid>5A985493-EE2C-4665-94CF-4DFEA3A89500</guid>
+    <enable>false</enable>
+  </user>
+  <user>
+    <guid>8B4288F6-CC82-491D-8EF9-642EF4F3E7D0</guid>
+    <enable>true</enable>
+    <enable-calendar>false</enable-calendar>
+  </user>
+  <user>
+    <guid>5FF60DAD-0BDE-4508-8C77-15F0CA5C8DD1</guid>
+    <enable>true</enable>
+    <hosted-at>00001</hosted-at>
+  </user>
+  <user>
+    <guid>543D28BA-F74F-4D5F-9243-B3E3A61171E5</guid>
+    <enable>true</enable>
+    <hosted-at>00002</hosted-at>
+  </user>
+  <user>
+    <guid>6A73326A-F781-47E7-A9F8-AF47364D4152</guid>
+    <enable>true</enable>
+    <hosted-at>00002</hosted-at>
+    <enable>true</enable>
+    <enable-calendar>true</enable-calendar>
+    <auto-schedule>true</auto-schedule>
+    <cuaddr>mailto:usera at example.com</cuaddr>
+    <cuaddr>mailto:user.a at example.com</cuaddr>
+    <cuaddr>mailto:user_a at example.com</cuaddr>
+  </user>
+</accounts>

Added: CalendarServer/branches/users/cdaboo/partition-4464/twistedcaldav/directory/test/test_augment.py
===================================================================
--- CalendarServer/branches/users/cdaboo/partition-4464/twistedcaldav/directory/test/test_augment.py	                        (rev 0)
+++ CalendarServer/branches/users/cdaboo/partition-4464/twistedcaldav/directory/test/test_augment.py	2009-08-06 16:11:58 UTC (rev 4484)
@@ -0,0 +1,78 @@
+##
+# Copyright (c) 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.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##
+
+from twistedcaldav.test.util import TestCase
+from twistedcaldav.directory.augment import AugmentXMLDB, AugmentSqliteDB
+from twisted.python.filepath import FilePath
+from twisted.internet.defer import inlineCallbacks
+import os
+
+xmlFile = FilePath(os.path.join(os.path.dirname(__file__), "augments.xml"))
+
+testRecords = (
+    {"guid":"D11F03A0-97EA-48AF-9A6C-FAC7F3975766", "enabled":True,  "hostedAt":"", "enabledForCalendaring":False, "autoSchedule":False, "calendarUserAddresses":set()},
+    {"guid":"6423F94A-6B76-4A3A-815B-D52CFD77935D", "enabled":True,  "hostedAt":"", "enabledForCalendaring":True, "autoSchedule":False, "calendarUserAddresses":set(("mailto:wsanchez at example.com",))},
+    {"guid":"5A985493-EE2C-4665-94CF-4DFEA3A89500", "enabled":False, "hostedAt":"", "enabledForCalendaring":False, "autoSchedule":False, "calendarUserAddresses":set()},
+    {"guid":"8B4288F6-CC82-491D-8EF9-642EF4F3E7D0", "enabled":True,  "hostedAt":"", "enabledForCalendaring":False, "autoSchedule":False, "calendarUserAddresses":set()},
+    {"guid":"5FF60DAD-0BDE-4508-8C77-15F0CA5C8DD1", "enabled":True,  "hostedAt":"00001", "enabledForCalendaring":False, "autoSchedule":False, "calendarUserAddresses":set()},
+    {"guid":"543D28BA-F74F-4D5F-9243-B3E3A61171E5", "enabled":True,  "hostedAt":"00002", "enabledForCalendaring":False, "autoSchedule":False, "calendarUserAddresses":set()},
+    {"guid":"6A73326A-F781-47E7-A9F8-AF47364D4152", "enabled":True,  "hostedAt":"00002", "enabledForCalendaring":True, "autoSchedule":True, "calendarUserAddresses":set(("mailto:usera at example.com", "mailto:user.a at example.com", "mailto:user_a at example.com",))},
+)
+
+class AugmentTests(TestCase):
+
+    @inlineCallbacks
+    def _checkRecord(self, db, items):
+        
+        record = (yield db.getAugmentRecord(items["guid"]))
+        self.assertTrue(record is not None)
+        
+        for k,v in items.iteritems():
+            self.assertEqual(getattr(record, k), v)
+
+    @inlineCallbacks
+    def _checkNoRecord(self, db, guid):
+        
+        record = (yield db.getAugmentRecord(guid))
+        self.assertTrue(record is None)
+
+class AugmentXMLTests(AugmentTests):
+
+    @inlineCallbacks
+    def test_read(self):
+        
+        db = AugmentXMLDB(xmlFile)
+
+        for item in testRecords:
+            yield self._checkRecord(db, item)
+
+        yield self._checkNoRecord(db, "D11F03A0-97EA-48AF-9A6C-FAC7F3975767")
+
+class AugmentSqliteTests(AugmentTests):
+
+    @inlineCallbacks
+    def test_read(self):
+        
+        db = AugmentSqliteDB(self.mktemp())
+
+        dbxml = AugmentXMLDB(xmlFile)
+        for record in dbxml.db.values():
+            yield db.addAugmentRecord(record)
+
+        for item in testRecords:
+            yield self._checkRecord(db, item)
+
+        yield self._checkNoRecord(db, "D11F03A0-97EA-48AF-9A6C-FAC7F3975767")

Modified: CalendarServer/branches/users/cdaboo/partition-4464/twistedcaldav/directory/xmlaccountsparser.py
===================================================================
--- CalendarServer/branches/users/cdaboo/partition-4464/twistedcaldav/directory/xmlaccountsparser.py	2009-08-05 21:35:27 UTC (rev 4483)
+++ CalendarServer/branches/users/cdaboo/partition-4464/twistedcaldav/directory/xmlaccountsparser.py	2009-08-06 16:11:58 UTC (rev 4484)
@@ -79,7 +79,7 @@
     def __repr__(self):
         return "<%s %r>" % (self.__class__.__name__, self.xmlFile)
 
-    def __init__(self, xmlFile):
+    def __init__(self, xmlFile, externalUpdate=True):
 
         if type(xmlFile) is str:
             xmlFile = FilePath(xmlFile)
@@ -102,7 +102,8 @@
             log.error("Ignoring file %r because it is not a repository builder file" % (self.xmlFile,))
             return
         self._parseXML(accounts_node)
-        self._updateExternalDatabases()
+        if externalUpdate:
+            self._updateExternalDatabases()
 
     def _updateExternalDatabases(self):
         resourceInfoDatabase = ResourceInfoDatabase(config.DataRoot)
@@ -344,6 +345,9 @@
             for email in self.emailAddresses:
                 self.calendarUserAddresses.add("mailto:%s" % (email,))
 
+        if not self.shortNames:
+            self.shortNames.append(self.guid)
+
     def _parseMembers(self, node, addto):
         for child in node._get_childNodes():
             if child._get_localName() == ELEMENT_MEMBER:

Modified: CalendarServer/branches/users/cdaboo/partition-4464/twistedcaldav/test/test_database.py
===================================================================
--- CalendarServer/branches/users/cdaboo/partition-4464/twistedcaldav/test/test_database.py	2009-08-05 21:35:27 UTC (rev 4483)
+++ CalendarServer/branches/users/cdaboo/partition-4464/twistedcaldav/test/test_database.py	2009-08-06 16:11:58 UTC (rev 4484)
@@ -127,8 +127,10 @@
         """
         db = Database.TestDB(self.mktemp())
         yield db.execute("INSERT into TESTTYPE (KEY, VALUE) values (:1, :2)", ("FOO", "BAR",))
-        items = (yield db.execute("SELECT * from TESTTYPE"))
-        self.assertEqual(items, [("FOO", "BAR"),])
+        items = (yield db.query("SELECT * from TESTTYPE"))
+        self.assertEqual(items, (("FOO", "BAR"),))
+        items = (yield db.queryList("SELECT * from TESTTYPE"))
+        self.assertEqual(items, ("FOO",))
 
     @inlineCallbacks
     def test_close(self):
@@ -153,15 +155,15 @@
         db = Database.TestDB(db_file)
         yield db.open()
         yield db.execute("INSERT into TESTTYPE (KEY, VALUE) values (:1, :2)", ("FOO", "BAR",))
-        items = (yield db.execute("SELECT * from TESTTYPE"))
-        self.assertEqual(items, [("FOO", "BAR")])
+        items = (yield db.query("SELECT * from TESTTYPE"))
+        self.assertEqual(items, (("FOO", "BAR"),))
         db.close()
         db = None
 
         db = Database.TestDBRecreateUpgrade(db_file)
         yield self.inlineCallbackRaises(Database.TestDBRecreateUpgrade.RecreateDBException, db.open)
-        items = (yield db.execute("SELECT * from TESTTYPE"))
-        self.assertEqual(items, [])
+        items = (yield db.query("SELECT * from TESTTYPE"))
+        self.assertEqual(items, ())
 
     def test_version_upgrade_persistent(self):
         """
@@ -171,8 +173,8 @@
         db = Database.TestDB(db_file, persistent=True)
         yield db.open()
         yield db.execute("INSERT into TESTTYPE (KEY, VALUE) values (:1, :2)", "FOO", "BAR")
-        items = (yield db.execute("SELECT * from TESTTYPE"))
-        self.assertEqual(items, [("FOO", "BAR")])
+        items = (yield db.query("SELECT * from TESTTYPE"))
+        self.assertEqual(items, (("FOO", "BAR")))
         db.close()
         db = None
 
@@ -184,8 +186,8 @@
 
         db = Database.TestDB(db_file, persistent=True, autocommit=True)
         yield db.open()
-        items = (yield db.execute("SELECT * from TESTTYPE"))
-        self.assertEqual(items, [("FOO", "BAR")])
+        items = (yield db.query("SELECT * from TESTTYPE"))
+        self.assertEqual(items, (("FOO", "BAR")))
 
     def test_version_upgrade_persistent_add_index(self):
         """
@@ -195,12 +197,12 @@
         db = Database.TestDB(db_file, persistent=True, autocommit=True)
         yield db.open()
         yield db.execute("INSERT into TESTTYPE (KEY, VALUE) values (:1, :2)", "FOO", "BAR")
-        items = (yield db._db_execute("SELECT * from TESTTYPE"))
-        self.assertEqual(items, [("FOO", "BAR")])
+        items = (yield db.query("SELECT * from TESTTYPE"))
+        self.assertEqual(items, (("FOO", "BAR")))
         db.close()
         db = None
 
         db = Database.TestDBCreateIndexOnUpgrade(db_file, persistent=True, autocommit=True)
         yield db.open()
-        items = (yield db._db_execute("SELECT * from TESTTYPE"))
-        self.assertEqual(items, [("FOO", "BAR")])
+        items = (yield db.query("SELECT * from TESTTYPE"))
+        self.assertEqual(items, (("FOO", "BAR")))
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20090806/580ce957/attachment-0001.html>


More information about the calendarserver-changes mailing list