[CalendarServer-changes] [1204]
CalendarServer/branches/users/cdaboo/sqlprops-1202/twistedcaldav
source_changes at macosforge.org
source_changes at macosforge.org
Sat Feb 17 10:01:38 PST 2007
Revision: 1204
http://trac.macosforge.org/projects/calendarserver/changeset/1204
Author: cdaboo at apple.com
Date: 2007-02-17 10:01:37 -0800 (Sat, 17 Feb 2007)
Log Message:
-----------
Merge forward.
Modified Paths:
--------------
CalendarServer/branches/users/cdaboo/sqlprops-1202/twistedcaldav/__init__.py
CalendarServer/branches/users/cdaboo/sqlprops-1202/twistedcaldav/sql.py
CalendarServer/branches/users/cdaboo/sqlprops-1202/twistedcaldav/static.py
Added Paths:
-----------
CalendarServer/branches/users/cdaboo/sqlprops-1202/twistedcaldav/sqlprops.py
CalendarServer/branches/users/cdaboo/sqlprops-1202/twistedcaldav/test/test_sqlprops.py
Modified: CalendarServer/branches/users/cdaboo/sqlprops-1202/twistedcaldav/__init__.py
===================================================================
--- CalendarServer/branches/users/cdaboo/sqlprops-1202/twistedcaldav/__init__.py 2007-02-17 17:42:22 UTC (rev 1203)
+++ CalendarServer/branches/users/cdaboo/sqlprops-1202/twistedcaldav/__init__.py 2007-02-17 18:01:37 UTC (rev 1204)
@@ -45,6 +45,7 @@
"root",
"schedule",
"sql",
+ "sqlprops",
"static",
]
Modified: CalendarServer/branches/users/cdaboo/sqlprops-1202/twistedcaldav/sql.py
===================================================================
--- CalendarServer/branches/users/cdaboo/sqlprops-1202/twistedcaldav/sql.py 2007-02-17 17:42:22 UTC (rev 1203)
+++ CalendarServer/branches/users/cdaboo/sqlprops-1202/twistedcaldav/sql.py 2007-02-17 18:01:37 UTC (rev 1204)
@@ -35,14 +35,16 @@
A generic SQL database.
"""
- def __init__(self, dbpath, version):
+ def __init__(self, dbpath, version, utf8=False):
"""
- @param resource: the L{twistedcaldav.static.CalDAVFile} resource to
- index. C{resource} must be a calendar collection (ie.
- C{resource.isPseudoCalendarCollection()} returns C{True}.)
+ @param dppath: C{str} containing the file path to the database file.
+ @param version: C{str} containing the version for the database schema.
+ @param utf8: C{True} if utf8 encoded C{str} should be returned for SQl TEXT data,
+ C{False} if C{unicode} should be returned.
"""
self.dbpath = dbpath
self.version = version
+ self.utf8 = utf8
def _db_type(self):
"""
@@ -58,6 +60,8 @@
if not hasattr(self, "_db_connection"):
db_filename = self.dbpath
self._db_connection = sqlite.connect(db_filename)
+ if self.utf8:
+ self._db_connection.text_factory = str
#
# Set up the schema
Copied: CalendarServer/branches/users/cdaboo/sqlprops-1202/twistedcaldav/sqlprops.py (from rev 1203, CalendarServer/branches/users/cdaboo/sqlprops-1126/twistedcaldav/sqlprops.py)
===================================================================
--- CalendarServer/branches/users/cdaboo/sqlprops-1202/twistedcaldav/sqlprops.py (rev 0)
+++ CalendarServer/branches/users/cdaboo/sqlprops-1202/twistedcaldav/sqlprops.py 2007-02-17 18:01:37 UTC (rev 1204)
@@ -0,0 +1,395 @@
+##
+# Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+#
+# DRI: Wilfredo Sanchez, wsanchez at apple.com
+##
+
+"""
+DAV Property store an sqlite database.
+
+This API is considered private to static.py and is therefore subject to
+change.
+"""
+
+__all__ = ["sqlPropertyStore"]
+
+import cPickle
+import os
+
+from twisted.python import log
+from twisted.web2 import responsecode
+from twisted.web2.http import HTTPError, StatusResponse
+
+from twistedcaldav.root import RootResource
+from twistedcaldav.sql import AbstractSQLDatabase
+
+DEBUG_LOG = False
+
+class sqlPropertyStore (object):
+ """
+ A dead property store that uses an SQLite database backend.
+ """
+
+ def __init__(self, resource):
+ self.resource = resource
+ if os.path.exists(os.path.dirname(resource.fp.path)):
+ if resource.isCollection() and isinstance(resource, RootResource):
+ self.rname = ""
+ indexpath = resource.fp.path
+ else:
+ self.rname = os.path.basename(resource.fp.path)
+ indexpath = os.path.dirname(resource.fp.path)
+ self.index = SQLPropertiesDatabase(indexpath)
+ else:
+ self.index = None
+
+ def get(self, qname):
+ """
+ Read property from index.
+
+ @param qname: C{tuple} of property namespace and name.
+ """
+ if not self.index:
+ raise HTTPError(StatusResponse(
+ responsecode.NOT_FOUND,
+ "No such property: {%s}%s" % qname
+ ))
+
+ value = self.index.getPropertyValue(self.rname, qname)
+ if not value:
+ raise HTTPError(StatusResponse(
+ responsecode.NOT_FOUND,
+ "No such property: {%s}%s" % qname
+ ))
+
+ return value
+
+ def getAll(self, qnames):
+ """
+ Read properties from index.
+
+ @param qnames: C{list} of C{tuple} of property namespace and name.
+ @return: a C{list} of property classes
+ """
+ if not qnames:
+ return None
+
+ if not self.index:
+ raise HTTPError(StatusResponse(
+ responsecode.NOT_FOUND,
+ "No such property: {%s}%s" % qnames[0]
+ ))
+
+ return self.index.getAllPropertyValues(self.rname, qnames)
+
+ def getAllResources(self, qnames):
+ """
+ Read properties for all child resources from index.
+
+ @param qnames: C{list} of C{tuple} of property namespace and name.
+ @return: a C{dict} with resource name as keys and C{dict} of property name/classes as values
+ """
+ if not qnames:
+ return None
+
+ if not self.index:
+ raise HTTPError(StatusResponse(
+ responsecode.NOT_FOUND,
+ "No such property: {%s}%s" % qnames[0]
+ ))
+
+ return self.index.getAllResourcePropertyValues(qnames)
+
+ def set(self, property):
+ """
+ Write property into index.
+
+ @param property: C{Property} to write
+ """
+
+ if self.index:
+ self.index.setPropertyValue(self.rname, property.qname(), property)
+
+ def delete(self, qname):
+ """
+ Delete proeprty from index.
+
+ DELETE from PROPERTIES where NAME=<<rname>> and PROPNAME=<<pname>>
+
+ @param qname:
+ """
+
+ if self.index:
+ self.index.removeProperty(self.rname, qname)
+
+ def deleteAll(self):
+ """
+ Delete proeprty from index.
+
+ DELETE from PROPERTIES where NAME=<<rname>> and PROPNAME=<<pname>>
+
+ @param qname:
+ """
+
+ if self.index:
+ self.index.removeResource(self.rname)
+
+ def contains(self, qname):
+ if self.index:
+ value = self.index.getPropertyValue(self.rname, qname)
+ return value is not None
+ else:
+ return False
+
+ def list(self):
+ """
+ List all property names for this resource.
+
+ SELECT PROPNAME from PROPERTIES where NAME=<<rname>>
+
+ """
+
+ if self.index:
+ return self.index.listProperties(self.rname)
+ else:
+ return ()
+
+class SQLPropertiesDatabase(AbstractSQLDatabase):
+ """
+ A database to maintain calendar user proxy group memberships.
+
+ SCHEMA:
+
+ Properties Database:
+
+ ROW: RESOURCENAME, PROPERTYNAME, PROPERTYVALUE
+
+ """
+
+ dbType = "SQLPROPERTIES"
+ dbFilename = ".db.sqlproperties"
+ dbFormatVersion = "1"
+
+ def _encode(clazz, name):
+ return "{%s}%s" % name
+
+ def _decode(clazz, name):
+ index = name.find("}")
+
+ if (index is -1 or not len(name) > index or not name[0] == "{"):
+ raise ValueError("Invalid encoded name: %r" % (name,))
+
+ return (name[1:index], name[index+1:])
+
+ _encode = classmethod(_encode)
+ _decode = classmethod(_decode)
+
+ def __init__(self, path):
+ path = os.path.join(path, SQLPropertiesDatabase.dbFilename)
+ super(SQLPropertiesDatabase, self).__init__(path, SQLPropertiesDatabase.dbFormatVersion, utf8=True)
+
+ def setPropertyValue(self, rname, pname, pvalue):
+ """
+ Add a property.
+
+ @param rname: a C{str} containing the resource name.
+ @param pname: a C{str} containing the name of the property to set.
+ @param pvalue: a C{str} containing the property value to set.
+ """
+
+ # Remove what is there, then add it back.
+ self._delete_from_db(rname, self._encode(pname))
+ self._add_to_db(rname, self._encode(pname), cPickle.dumps(pvalue))
+ self._db_commit()
+
+ def getPropertyValue(self, rname, pname):
+ """
+ Get a property.
+
+ @param rname: a C{str} containing the resource name.
+ @param pname: a C{str} containing the name of the property to get.
+ @return: a C{str} containing the property value.
+ """
+
+ # Remove what is there, then add it back.
+ if DEBUG_LOG:
+ log.msg("getPropertyValue: %s \"%s\" \"%s\"" % (self.dbpath, rname, pname))
+ members = []
+ for row in self._db_execute("select PROPERTYVALUE from PROPERTIES where RESOURCENAME = :1 and PROPERTYNAME = :2", rname, self._encode(pname)):
+ members.append(row[0])
+ setlength = len(members)
+ if setlength == 0:
+ return None
+ elif setlength == 1:
+ return cPickle.loads(members[0])
+ else:
+ raise ValueError("Multiple properties of the same name \"%s\" stored for resource \"%s\"" % (pname, rname,))
+
+ def getAllPropertyValues(self, rname, pnames):
+ """
+ Get specified property values from specific resource.
+
+ @param rname: a C{str} containing the resource name.
+ @param pnames: a C{list} of C{str} containing the name of the properties to get.
+ @return: a C{dict} containing property name/value.
+ """
+
+ # Remove what is there, then add it back.
+ if DEBUG_LOG:
+ log.msg("getAllPropertyValues: %s \"%s\"" % (self.dbpath, pnames))
+ properties = {}
+ statement = "select PROPERTYNAME, PROPERTYVALUE from PROPERTIES where RESOURCENAME = :1 and ("
+ args = [rname]
+ for i, pname in enumerate(pnames):
+ if i != 0:
+ statement += " or "
+ statement += "PROPERTYNAME=:%s" % (i + 2,)
+ args.append(self._encode(pname))
+ statement += ")"
+
+ for row in self._db_execute(statement, *args):
+ properties[self._decode(row[0])] = cPickle.loads(row[1])
+
+ return properties
+
+ def getAllResourcePropertyValues(self, pnames):
+ """
+ Get specified property values from all resources.
+
+ @param pnames: a C{list} of C{str} containing the name of the properties to get.
+ @return: a C{dict} containing C{str} keys (names of child resources) and C{dict} values of property name/value.
+ """
+
+ # Remove what is there, then add it back.
+ if DEBUG_LOG:
+ log.msg("getAllPropertyValues: %s \"%s\"" % (self.dbpath, pnames))
+ members = {}
+ statement = "select RESOURCENAME, PROPERTYNAME, PROPERTYVALUE from PROPERTIES where "
+ args = []
+ for i, pname in enumerate(pnames):
+ if i != 0:
+ statement += " or "
+ statement += "PROPERTYNAME=:%s" % (i + 1,)
+ args.append(self._encode(pname))
+
+ for row in self._db_execute(statement, *args):
+ members.setdefault(row[0], {})[self._decode(row[1])] = cPickle.loads(row[2])
+
+ return members
+
+ def removeProperty(self, rname, pname):
+ """
+ Remove a property.
+
+ @param rname: a C{str} containing the resource name.
+ @param pname: a C{str} containing the name of the property to get.
+ @return: a C{str} containing the property value.
+ """
+
+ self._delete_from_db(rname, self._encode(pname))
+ self._db_commit()
+
+ def removeResource(self, rname):
+ """
+ Remove all properties for resource.
+
+ @param rname: a C{str} containing the resource name.
+ @return: a C{str} containing the property value.
+ """
+
+ self._delete_all_from_db(rname)
+ self._db_commit()
+
+ def listProperties(self, rname):
+ """
+ List all properties in resource.
+
+ @param rname: a C{str} containing the resource name.
+ @return: a C{set} containing the property names.
+ """
+
+ members = set()
+ for row in self._db_execute("select PROPERTYNAME from PROPERTIES where RESOURCENAME = :1", rname):
+ members.add(self._decode(row[0]))
+ return members
+
+ def _add_to_db(self, rname, pname, pvalue):
+ """
+ Add a property.
+
+ @param rname: a C{str} containing the resource name.
+ @param pname: a C{str} containing the name of the property to set.
+ @param pvalue: a C{str} containing the property value to set.
+ """
+
+ self._db_execute(
+ """
+ insert into PROPERTIES (RESOURCENAME, PROPERTYNAME, PROPERTYVALUE)
+ values (:1, :2, :3)
+ """, rname, pname, pvalue
+ )
+
+ def _delete_all_from_db(self, rname):
+ """
+ Remove a property.
+
+ @param rname: a C{str} containing the resource name.
+ @param pname: a C{str} containing the name of the property to get.
+ @return: a C{str} containing the property value.
+ """
+
+ self._db_execute("delete from PROPERTIES where RESOURCENAME = :1", rname)
+
+ def _delete_from_db(self, rname, pname):
+ """
+ Remove a property.
+
+ @param rname: a C{str} containing the resource name.
+ @param pname: a C{str} containing the name of the property to get.
+ @return: a C{str} containing the property value.
+ """
+
+ self._db_execute("delete from PROPERTIES where RESOURCENAME = :1 and PROPERTYNAME = :2", rname, pname)
+
+ def _db_type(self):
+ """
+ @return: the collection type assigned to this index.
+ """
+ return SQLPropertiesDatabase.dbType
+
+ def _db_init_data_tables(self, q):
+ """
+ Initialise the underlying database tables.
+ @param q: a database cursor to use.
+ """
+
+ #
+ # PROPERTIES table
+ #
+ q.execute(
+ """
+ create table PROPERTIES (
+ RESOURCENAME text,
+ PROPERTYNAME text,
+ PROPERTYVALUE text
+ )
+ """
+ )
Modified: CalendarServer/branches/users/cdaboo/sqlprops-1202/twistedcaldav/static.py
===================================================================
--- CalendarServer/branches/users/cdaboo/sqlprops-1202/twistedcaldav/static.py 2007-02-17 17:42:22 UTC (rev 1203)
+++ CalendarServer/branches/users/cdaboo/sqlprops-1202/twistedcaldav/static.py 2007-02-17 18:01:37 UTC (rev 1204)
@@ -61,6 +61,7 @@
from twistedcaldav.notifications import NotificationsCollectionResource, NotificationResource
from twistedcaldav.resource import CalDAVResource, isCalendarCollectionResource, isPseudoCalendarCollectionResource
from twistedcaldav.schedule import ScheduleInboxResource, ScheduleOutboxResource
+from twistedcaldav.sqlprops import sqlPropertyStore, SQLPropertiesDatabase
from twistedcaldav.dropbox import DropBoxHomeResource, DropBoxCollectionResource, DropBoxChildResource
from twistedcaldav.directory.calendar import DirectoryCalendarHomeProvisioningResource
from twistedcaldav.directory.calendar import DirectoryCalendarHomeTypeProvisioningResource
@@ -71,6 +72,10 @@
"""
CalDAV-accessible L{DAVFile} resource.
"""
+
+ db_names = (db_basename, SQLPropertiesDatabase.dbFilename)
+
+
def __repr__(self):
if self.isCalendarCollection():
return "<%s (calendar collection): %s>" % (self.__class__.__name__, self.fp.path)
@@ -81,6 +86,14 @@
# CalDAV
##
+ def deadProperties(self):
+ if not hasattr(self, "_dead_properties"):
+ #if self.fp.path.find("user01") != -1:
+ self._dead_properties = sqlPropertyStore(self)
+ #else:
+ # self._dead_properties = xattrPropertyStore(self)
+ return self._dead_properties
+
def resourceType(self):
if self.isCalendarCollection():
return davxml.ResourceType.calendar
@@ -261,7 +274,7 @@
def listChildren(self):
return [
child for child in super(CalDAVFile, self).listChildren()
- if child != db_basename
+ if child not in CalDAVFile.db_names
]
##
@@ -289,7 +302,7 @@
for f in top.listdir():
# Ignore the database
- if top_level and f == db_basename:
+ if top_level and f in CalDAVFile.db_names:
continue
child = top.child(f)
Copied: CalendarServer/branches/users/cdaboo/sqlprops-1202/twistedcaldav/test/test_sqlprops.py (from rev 1203, CalendarServer/branches/users/cdaboo/sqlprops-1126/twistedcaldav/test/test_sqlprops.py)
===================================================================
--- CalendarServer/branches/users/cdaboo/sqlprops-1202/twistedcaldav/test/test_sqlprops.py (rev 0)
+++ CalendarServer/branches/users/cdaboo/sqlprops-1202/twistedcaldav/test/test_sqlprops.py 2007-02-17 18:01:37 UTC (rev 1204)
@@ -0,0 +1,187 @@
+##
+# Copyright (c) 2005-2007 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.
+#
+# DRI: Wilfredo Sanchez, wsanchez at apple.com
+##
+
+import os
+import time
+
+from twisted.web2.dav import davxml
+
+from twistedcaldav import caldavxml, customxml
+from twistedcaldav.root import RootResource
+from twistedcaldav.sqlprops import sqlPropertyStore, SQLPropertiesDatabase
+from twistedcaldav.static import CalDAVFile
+import twistedcaldav.test.util
+
+class SQLProps (twistedcaldav.test.util.TestCase):
+ """
+ SQL properties tests
+ """
+
+ props = (
+ davxml.DisplayName.fromString("My Name"),
+ davxml.ACL(
+ davxml.ACE(
+ davxml.Principal(davxml.Authenticated()),
+ davxml.Grant(davxml.Privilege(davxml.Read())),
+ davxml.Protected(),
+ ),
+ ),
+ caldavxml.CalendarDescription.fromString("My Calendar"),
+ customxml.TwistedScheduleAutoRespond(),
+ )
+
+ def _setUpIndex(self):
+ self.collection_name, self.collection_uri = self.mkdtemp("sql")
+ rsrc = CalDAVFile(os.path.join(self.collection_name, "file.ics"))
+ return sqlPropertyStore(rsrc)
+
+ def _setOnePropertyAndTest(self, prop):
+ index = self._setUpIndex()
+ index.set(prop)
+ self.assertTrue(index.contains(prop.qname()),
+ msg="Could not find property %s." % prop)
+ self.assertTrue(index.get(prop.qname()) == prop,
+ msg="Could not get property %s." % prop)
+
+ def _setProperty(self, index, prop):
+ index.set(prop)
+
+ def _testProperty(self, index, prop):
+ self.assertTrue(index.contains(prop.qname()),
+ msg="Could not find property %s." % prop)
+ self.assertTrue(index.get(prop.qname()) == prop,
+ msg="Could not get property %s." % prop)
+
+ def _testPropertyList(self, proplist):
+ self.assertTrue(len(proplist) == len(SQLProps.props),
+ msg="Number of properties returned %s not equal to number queried %s." % (len(proplist), len(SQLProps.props),))
+ for prop in SQLProps.props:
+ for k, v in proplist.iteritems():
+ if prop == v:
+ del proplist[k]
+ break
+ self.assertTrue(len(proplist) == 0,
+ msg="Incorrect properties returned %s." % proplist)
+
+ def _testResourcePropertyList(self, num_resources, resourcedict):
+ self.assertTrue(len(resourcedict) == num_resources,
+ msg="Number of resources returned %s not equal to number queried %s." % (len(resourcedict), num_resources,))
+ for i in xrange(num_resources):
+ fname = "file%04s.ics" % (i,)
+ self.assertTrue(resourcedict.has_key(fname),
+ msg="Resource %s not returned in query results" % (fname,))
+ self._testPropertyList(resourcedict[fname])
+
+ def _setupMultipleResources(self, number):
+ self.collection_name, self.collection_uri = self.mkdtemp("sql")
+ for i in xrange(number):
+ rsrc = CalDAVFile(os.path.join(self.collection_name, "file%04s.ics" % (i,)))
+ index = sqlPropertyStore(rsrc)
+ for prop in SQLProps.props:
+ index.set(prop)
+ return index
+
+ def test_db_init_directory(self):
+ self.collection_name, self.collection_uri = self.mkdtemp("sql")
+ rsrc = CalDAVFile(self.collection_name)
+ index = sqlPropertyStore(rsrc)
+ db = index.index._db()
+ self.assertTrue(os.path.exists(os.path.join(os.path.dirname(self.collection_name), SQLPropertiesDatabase.dbFilename)),
+ msg="Could not initialize index via collection resource.")
+
+ def test_db_init_root(self):
+ self.collection_name, self.collection_uri = self.mkdtemp("sql")
+ rsrc = RootResource(self.collection_name)
+ index = sqlPropertyStore(rsrc)
+ db = index.index._db()
+ self.assertTrue(os.path.exists(os.path.join(self.collection_name, SQLPropertiesDatabase.dbFilename)),
+ msg="Could not initialize index via collection resource.")
+
+ def test_db_init_file(self):
+ index = self._setUpIndex()
+ db = index.index._db()
+ self.assertTrue(os.path.exists(os.path.join(self.collection_name, SQLPropertiesDatabase.dbFilename)),
+ msg="Could not initialize index via file resource.")
+
+ def test_setoneproperty(self):
+ for prop in SQLProps.props:
+ self._setOnePropertyAndTest(prop)
+
+ def test_setunknownproperty(self):
+ doc = davxml.WebDAVDocument.fromString("""<?xml version="1.0" encoding="utf-8" ?><guess/>""")
+ self._setOnePropertyAndTest(doc.root_element)
+
+ def test_setmultipleproperties(self):
+ index = self._setUpIndex()
+ for prop in SQLProps.props:
+ self._setProperty(index, prop)
+ for prop in SQLProps.props:
+ self._testProperty(index, prop)
+ proplist = set(index.list())
+ expected_proplist = set([prop.qname() for prop in SQLProps.props])
+ self.assertTrue(proplist == expected_proplist,
+ msg="Property lists do not match: %s != %s." % (proplist, expected_proplist))
+
+ def test_deleteproperties(self):
+ index = self._setUpIndex()
+ for prop in SQLProps.props:
+ self._setProperty(index, prop)
+
+ remaining_props = [p for p in SQLProps.props]
+ for prop in SQLProps.props:
+ remaining_props.pop(0)
+ index.delete(prop.qname())
+ proplist = set(index.list())
+ expected_proplist = set([prop.qname() for prop in remaining_props])
+ self.assertTrue(proplist == expected_proplist,
+ msg="Property lists do not match: %s != %s." % (proplist, expected_proplist))
+
+ def test_deleteallproperties(self):
+ index = self._setUpIndex()
+ for prop in SQLProps.props:
+ self._setProperty(index, prop)
+
+ index.deleteAll()
+ for prop in SQLProps.props:
+ self.assertFalse(index.contains(prop.qname()),
+ msg="Could not find property %s." % prop)
+
+ def test_getallproperties(self):
+ index = self._setUpIndex()
+ for prop in SQLProps.props:
+ self._setProperty(index, prop)
+
+ result = index.getAll([p.qname() for p in SQLProps.props])
+ self._testPropertyList(result)
+
+ def test_getallresourceproperties(self):
+ num_resources = 10
+ index = self._setupMultipleResources(num_resources)
+ result = index.getAllResources([p.qname() for p in SQLProps.props])
+ self._testResourcePropertyList(num_resources, result)
+
+# def test_timegetallresourceproperties(self):
+# num_resources = 1000
+# index = self._setupMultipleResources(num_resources)
+# t1 = time.time()
+# result = index.getAllResources([p.qname() for p in SQLProps.props])
+# t2 = time.time()
+# self.assertTrue(t1 == t2,
+# msg="Time for 1000 prop query = %s" % (t2 - t1,))
+#
+# self._testResourcePropertyList(num_resources, result)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20070217/7c95a4bf/attachment.html
More information about the calendarserver-changes
mailing list