[CalendarServer-changes] [6206] CalendarServer/trunk/txdav/base/propertystore
source_changes at macosforge.org
source_changes at macosforge.org
Mon Aug 30 13:53:35 PDT 2010
Revision: 6206
http://trac.macosforge.org/projects/calendarserver/changeset/6206
Author: cdaboo at apple.com
Date: 2010-08-30 13:53:34 -0700 (Mon, 30 Aug 2010)
Log Message:
-----------
Do a single SQL query to read in all of a resource's properties and use a write-through cache.
Modified Paths:
--------------
CalendarServer/trunk/txdav/base/propertystore/sql.py
CalendarServer/trunk/txdav/base/propertystore/test/base.py
CalendarServer/trunk/txdav/base/propertystore/test/test_sql.py
Modified: CalendarServer/trunk/txdav/base/propertystore/sql.py
===================================================================
--- CalendarServer/trunk/txdav/base/propertystore/sql.py 2010-08-30 19:17:50 UTC (rev 6205)
+++ CalendarServer/trunk/txdav/base/propertystore/sql.py 2010-08-30 20:53:34 UTC (rev 6206)
@@ -35,47 +35,78 @@
self._txn = txn
self._resourceID = resourceID
+ @property
+ def _cached(self):
+
+ if not hasattr(self, "_cached_properties"):
+ self._cached_properties = {}
+ rows = self._txn.execSQL(
+ """
+ select NAME, VIEWER_UID, VALUE from RESOURCE_PROPERTY
+ where RESOURCE_ID = %s
+ """,
+ [self._resourceID]
+ )
+ for name, uid, value in rows:
+ self._cached_properties[(name, uid)] = value
+
+ return self._cached_properties
def _getitem_uid(self, key, uid):
validKey(key)
- rows = self._txn.execSQL(
- "select VALUE from RESOURCE_PROPERTY where "
- "RESOURCE_ID = %s and NAME = %s and VIEWER_UID = %s",
- [self._resourceID, key.toString(), uid]
- )
- if not rows:
+
+ try:
+ value = self._cached[(key.toString(), uid)]
+ except KeyError:
raise KeyError(key)
- return WebDAVDocument.fromString(rows[0][0]).root_element
+ return WebDAVDocument.fromString(value).root_element
+
def _setitem_uid(self, key, value, uid):
validKey(key)
- try:
- self._delitem_uid(key, uid)
- except KeyError:
- pass
- self._txn.execSQL(
- "insert into RESOURCE_PROPERTY "
- "(RESOURCE_ID, NAME, VALUE, VIEWER_UID) values (%s, %s, %s, %s)",
- [self._resourceID, key.toString(), value.toxml(), uid]
- )
+ key_str = key.toString()
+ value_str = value.toxml()
+ if (key_str, uid) in self._cached:
+ self._txn.execSQL(
+ """
+ update RESOURCE_PROPERTY
+ set VALUE = %s
+ where RESOURCE_ID = %s and NAME = %s and VIEWER_UID = %s
+ """,
+ [value_str, self._resourceID, key_str, uid]
+ )
+ else:
+ self._txn.execSQL(
+ """
+ insert into RESOURCE_PROPERTY
+ (RESOURCE_ID, NAME, VALUE, VIEWER_UID)
+ values (%s, %s, %s, %s)
+ """,
+ [self._resourceID, key_str, value_str, uid]
+ )
+ self._cached[(key_str, uid)] = value_str
+
+
def _delitem_uid(self, key, uid):
validKey(key)
+
+ key_str = key.toString()
+ del self._cached[(key_str, uid)]
self._txn.execSQL(
- "delete from RESOURCE_PROPERTY where VIEWER_UID = %s"
- "and RESOURCE_ID = %s AND NAME = %s",
- [uid, self._resourceID, key.toString()],
+ """
+ delete from RESOURCE_PROPERTY
+ where RESOURCE_ID = %s and NAME = %s and VIEWER_UID = %s
+ """,
+ [self._resourceID, key_str, uid],
raiseOnZeroRowCount=lambda:KeyError(key)
)
def _keys_uid(self, uid):
- rows = self._txn.execSQL(
- "select NAME from RESOURCE_PROPERTY where "
- "VIEWER_UID = %s and RESOURCE_ID = %s",
- [uid, self._resourceID]
- )
- for row in rows:
- yield PropertyName.fromString(row[0])
+
+ for cachedKey, cachedUID in self._cached.keys():
+ if cachedUID == uid:
+ yield PropertyName.fromString(cachedKey)
Modified: CalendarServer/trunk/txdav/base/propertystore/test/base.py
===================================================================
--- CalendarServer/trunk/txdav/base/propertystore/test/base.py 2010-08-30 19:17:50 UTC (rev 6205)
+++ CalendarServer/trunk/txdav/base/propertystore/test/base.py 2010-08-30 20:53:34 UTC (rev 6206)
@@ -57,184 +57,175 @@
def test_set_get_contains(self):
self._preTest()
- store = self.propertyStore
name = propertyName("test")
value = propertyValue("Hello, World!")
# Test with commit after change
- store[name] = value
- self._changed(store)
- self.assertEquals(store.get(name, None), value)
- self.failUnless(name in store)
+ self.propertyStore[name] = value
+ self._changed(self.propertyStore)
+ self.assertEquals(self.propertyStore.get(name, None), value)
+ self.failUnless(name in self.propertyStore)
# Test without commit after change
value = propertyValue("Hello, Universe!")
- store[name] = value
- self.assertEquals(store.get(name, None), value)
- self.failUnless(name in store)
+ self.propertyStore[name] = value
+ self.assertEquals(self.propertyStore.get(name, None), value)
+ self.failUnless(name in self.propertyStore)
def test_delete_get_contains(self):
self._preTest()
- store = self.propertyStore
# Test with commit after change
name = propertyName("test")
value = propertyValue("Hello, World!")
- store[name] = value
- self._changed(store)
+ self.propertyStore[name] = value
+ self._changed(self.propertyStore)
- del store[name]
- self._changed(store)
+ del self.propertyStore[name]
+ self._changed(self.propertyStore)
- self.assertEquals(store.get(name, None), None)
- self.failIf(name in store)
+ self.assertEquals(self.propertyStore.get(name, None), None)
+ self.failIf(name in self.propertyStore)
# Test without commit after change
name = propertyName("test")
value = propertyValue("Hello, Universe!")
- store[name] = value
- self._changed(store)
+ self.propertyStore[name] = value
+ self._changed(self.propertyStore)
- del store[name]
+ del self.propertyStore[name]
- self.assertEquals(store.get(name, None), None)
- self.failIf(name in store)
+ self.assertEquals(self.propertyStore.get(name, None), None)
+ self.failIf(name in self.propertyStore)
def test_peruser(self):
self._preTest()
- store1 = self.propertyStore1
- store2 = self.propertyStore2
name = propertyName("test")
value1 = propertyValue("Hello, World1!")
value2 = propertyValue("Hello, World2!")
- store1[name] = value1
- self._changed(store1)
- self.assertEquals(store1.get(name, None), value1)
- self.assertEquals(store2.get(name, None), None)
- self.failUnless(name in store1)
- self.failIf(name in store2)
+ self.propertyStore1[name] = value1
+ self._changed(self.propertyStore1)
+ self.assertEquals(self.propertyStore1.get(name, None), value1)
+ self.assertEquals(self.propertyStore2.get(name, None), None)
+ self.failUnless(name in self.propertyStore1)
+ self.failIf(name in self.propertyStore2)
- store2[name] = value2
- self._changed(store2)
- self.assertEquals(store1.get(name, None), value1)
- self.assertEquals(store2.get(name, None), value2)
- self.failUnless(name in store1)
- self.failUnless(name in store2)
+ self.propertyStore2[name] = value2
+ self._changed(self.propertyStore2)
+ self.assertEquals(self.propertyStore1.get(name, None), value1)
+ self.assertEquals(self.propertyStore2.get(name, None), value2)
+ self.failUnless(name in self.propertyStore1)
+ self.failUnless(name in self.propertyStore2)
- del store2[name]
- self._changed(store2)
- self.assertEquals(store1.get(name, None), value1)
- self.assertEquals(store2.get(name, None), None)
- self.failUnless(name in store1)
- self.failIf(name in store2)
+ del self.propertyStore2[name]
+ self._changed(self.propertyStore2)
+ self.assertEquals(self.propertyStore1.get(name, None), value1)
+ self.assertEquals(self.propertyStore2.get(name, None), None)
+ self.failUnless(name in self.propertyStore1)
+ self.failIf(name in self.propertyStore2)
- del store1[name]
- self._changed(store1)
- self.assertEquals(store1.get(name, None), None)
- self.assertEquals(store2.get(name, None), None)
- self.failIf(name in store1)
- self.failIf(name in store2)
+ del self.propertyStore1[name]
+ self._changed(self.propertyStore1)
+ self.assertEquals(self.propertyStore1.get(name, None), None)
+ self.assertEquals(self.propertyStore2.get(name, None), None)
+ self.failIf(name in self.propertyStore1)
+ self.failIf(name in self.propertyStore2)
def test_peruser_shadow(self):
self._preTest()
- store1 = self.propertyStore1
- store2 = self.propertyStore2
name = propertyName("shadow")
- store1.setSpecialProperties((name,), ())
- store2.setSpecialProperties((name,), ())
+ self.propertyStore1.setSpecialProperties((name,), ())
+ self.propertyStore2.setSpecialProperties((name,), ())
value1 = propertyValue("Hello, World1!")
value2 = propertyValue("Hello, World2!")
- store1[name] = value1
- self._changed(store1)
- self.assertEquals(store1.get(name, None), value1)
- self.assertEquals(store2.get(name, None), value1)
- self.failUnless(name in store1)
- self.failUnless(name in store2)
+ self.propertyStore1[name] = value1
+ self._changed(self.propertyStore1)
+ self.assertEquals(self.propertyStore1.get(name, None), value1)
+ self.assertEquals(self.propertyStore2.get(name, None), value1)
+ self.failUnless(name in self.propertyStore1)
+ self.failUnless(name in self.propertyStore2)
- store2[name] = value2
- self._changed(store2)
- self.assertEquals(store1.get(name, None), value1)
- self.assertEquals(store2.get(name, None), value2)
- self.failUnless(name in store1)
- self.failUnless(name in store2)
+ self.propertyStore2[name] = value2
+ self._changed(self.propertyStore2)
+ self.assertEquals(self.propertyStore1.get(name, None), value1)
+ self.assertEquals(self.propertyStore2.get(name, None), value2)
+ self.failUnless(name in self.propertyStore1)
+ self.failUnless(name in self.propertyStore2)
- del store2[name]
- self._changed(store2)
- self.assertEquals(store1.get(name, None), value1)
- self.assertEquals(store2.get(name, None), value1)
- self.failUnless(name in store1)
- self.failUnless(name in store2)
+ del self.propertyStore2[name]
+ self._changed(self.propertyStore2)
+ self.assertEquals(self.propertyStore1.get(name, None), value1)
+ self.assertEquals(self.propertyStore2.get(name, None), value1)
+ self.failUnless(name in self.propertyStore1)
+ self.failUnless(name in self.propertyStore2)
- del store1[name]
- self._changed(store1)
- self.assertEquals(store1.get(name, None), None)
- self.assertEquals(store2.get(name, None), None)
- self.failIf(name in store1)
- self.failIf(name in store2)
+ del self.propertyStore1[name]
+ self._changed(self.propertyStore1)
+ self.assertEquals(self.propertyStore1.get(name, None), None)
+ self.assertEquals(self.propertyStore2.get(name, None), None)
+ self.failIf(name in self.propertyStore1)
+ self.failIf(name in self.propertyStore2)
def test_peruser_global(self):
self._preTest()
- store1 = self.propertyStore1
- store2 = self.propertyStore2
name = propertyName("global")
- store1.setSpecialProperties((), (name,))
- store2.setSpecialProperties((), (name,))
+ self.propertyStore1.setSpecialProperties((), (name,))
+ self.propertyStore2.setSpecialProperties((), (name,))
value1 = propertyValue("Hello, World1!")
value2 = propertyValue("Hello, World2!")
- store1[name] = value1
- self._changed(store1)
- self.assertEquals(store1.get(name, None), value1)
- self.assertEquals(store2.get(name, None), value1)
- self.failUnless(name in store1)
- self.failUnless(name in store2)
+ self.propertyStore1[name] = value1
+ self._changed(self.propertyStore1)
+ self.assertEquals(self.propertyStore1.get(name, None), value1)
+ self.assertEquals(self.propertyStore2.get(name, None), value1)
+ self.failUnless(name in self.propertyStore1)
+ self.failUnless(name in self.propertyStore2)
- store2[name] = value2
- self._changed(store2)
- self.assertEquals(store1.get(name, None), value2)
- self.assertEquals(store2.get(name, None), value2)
- self.failUnless(name in store1)
- self.failUnless(name in store2)
+ self.propertyStore2[name] = value2
+ self._changed(self.propertyStore2)
+ self.assertEquals(self.propertyStore1.get(name, None), value2)
+ self.assertEquals(self.propertyStore2.get(name, None), value2)
+ self.failUnless(name in self.propertyStore1)
+ self.failUnless(name in self.propertyStore2)
- del store2[name]
- self._changed(store2)
- self.assertEquals(store1.get(name, None), None)
- self.assertEquals(store2.get(name, None), None)
- self.failIf(name in store1)
- self.failIf(name in store2)
+ del self.propertyStore2[name]
+ self._changed(self.propertyStore2)
+ self.assertEquals(self.propertyStore1.get(name, None), None)
+ self.assertEquals(self.propertyStore2.get(name, None), None)
+ self.failIf(name in self.propertyStore1)
+ self.failIf(name in self.propertyStore2)
def test_iteration(self):
self._preTest()
- store = self.propertyStore
value = propertyValue("Hello, World!")
names = set(propertyName(str(i)) for i in (1,2,3,4))
for name in names:
- store[name] = value
+ self.propertyStore[name] = value
- self.assertEquals(set(store.keys()), names)
- self.assertEquals(len(store), len(names))
+ self.assertEquals(set(self.propertyStore.keys()), names)
+ self.assertEquals(len(self.propertyStore), len(names))
def test_delete_none(self):
@@ -247,19 +238,18 @@
def test_keyInPropertyName(self):
self._preTest()
- store = self.propertyStore
def doGet():
- store["xyzzy"]
+ self.propertyStore["xyzzy"]
def doSet():
- store["xyzzy"] = propertyValue("Hello, World!")
+ self.propertyStore["xyzzy"] = propertyValue("Hello, World!")
def doDelete():
- del store["xyzzy"]
+ del self.propertyStore["xyzzy"]
def doContains():
- return "xyzzy" in store
+ return "xyzzy" in self.propertyStore
self.assertRaises(TypeError, doGet)
self.assertRaises(TypeError, doSet)
@@ -269,7 +259,6 @@
def test_flush(self):
self._preTest()
- store = self.propertyStore
name = propertyName("test")
value = propertyValue("Hello, World!")
@@ -277,39 +266,38 @@
#
# Set value flushes correctly
#
- store[name] = value
+ self.propertyStore[name] = value
- self._changed(store)
- self._abort(store)
+ self._changed(self.propertyStore)
+ self._abort(self.propertyStore)
- self.assertEquals(store.get(name, None), value)
- self.assertEquals(len(store), 1)
+ self.assertEquals(self.propertyStore.get(name, None), value)
+ self.assertEquals(len(self.propertyStore), 1)
#
# Deleted value flushes correctly
#
- del store[name]
+ del self.propertyStore[name]
- self._changed(store)
- self._abort(store)
+ self._changed(self.propertyStore)
+ self._abort(self.propertyStore)
- self.assertEquals(store.get(name, None), None)
- self.assertEquals(len(store), 0)
+ self.assertEquals(self.propertyStore.get(name, None), None)
+ self.assertEquals(len(self.propertyStore), 0)
def test_abort(self):
self._preTest()
- store = self.propertyStore
name = propertyName("test")
value = propertyValue("Hello, World!")
- store[name] = value
+ self.propertyStore[name] = value
- self._abort(store)
+ self._abort(self.propertyStore)
- self.assertEquals(store.get(name, None), None)
- self.assertEquals(len(store), 0)
+ self.assertEquals(self.propertyStore.get(name, None), None)
+ self.assertEquals(len(self.propertyStore), 0)
def propertyName(name):
Modified: CalendarServer/trunk/txdav/base/propertystore/test/test_sql.py
===================================================================
--- CalendarServer/trunk/txdav/base/propertystore/test/test_sql.py 2010-08-30 19:17:50 UTC (rev 6205)
+++ CalendarServer/trunk/txdav/base/propertystore/test/test_sql.py 2010-08-30 20:53:34 UTC (rev 6206)
@@ -59,18 +59,40 @@
self._txn.commit()
delattr(self, "_txn")
self._txn = self.store.newTransaction()
- self.propertyStore1._txn = self._txn
- self.propertyStore2._txn = self._txn
+
+ store = self.propertyStore1
+ self.propertyStore = self.propertyStore1 = PropertyStore(
+ "user01", self._txn, 1
+ )
+ self.propertyStore1._shadowableKeys = store._shadowableKeys
+ self.propertyStore1._globalKeys = store._globalKeys
+ store = self.propertyStore2
+ self.propertyStore2 = PropertyStore("user01", self._txn, 1)
+ self.propertyStore2._setPerUserUID("user02")
+ self.propertyStore2._shadowableKeys = store._shadowableKeys
+ self.propertyStore2._globalKeys = store._globalKeys
+
def _abort(self, store):
if hasattr(self, "_txn"):
self._txn.abort()
delattr(self, "_txn")
self._txn = self.store.newTransaction()
- self.propertyStore1._txn = self._txn
- self.propertyStore2._txn = self._txn
+ store = self.propertyStore1
+ self.propertyStore = self.propertyStore1 = PropertyStore(
+ "user01", self._txn, 1
+ )
+ self.propertyStore1._shadowableKeys = store._shadowableKeys
+ self.propertyStore1._globalKeys = store._globalKeys
+
+ store = self.propertyStore2
+ self.propertyStore2 = PropertyStore("user01", self._txn, 1)
+ self.propertyStore2._setPerUserUID("user02")
+ self.propertyStore2._shadowableKeys = store._shadowableKeys
+ self.propertyStore2._globalKeys = store._globalKeys
+
@inlineCallbacks
def setUp(self):
self.notifierFactory = StubNotifierFactory()
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20100830/0f65659f/attachment-0001.html>
More information about the calendarserver-changes
mailing list