[CalendarServer-changes] [13198] CalendarServer/trunk/txdav

source_changes at macosforge.org source_changes at macosforge.org
Tue Apr 8 11:01:59 PDT 2014


Revision: 13198
          http://trac.calendarserver.org//changeset/13198
Author:   sagen at apple.com
Date:     2014-04-08 11:01:59 -0700 (Tue, 08 Apr 2014)
Log Message:
-----------
make addDelegate idempotent; add delegation-related indices to schema

Modified Paths:
--------------
    CalendarServer/trunk/txdav/common/datastore/sql.py
    CalendarServer/trunk/txdav/common/datastore/sql_schema/current-oracle-dialect.sql
    CalendarServer/trunk/txdav/common/datastore/sql_schema/current.sql
    CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_34_to_35.sql
    CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/postgres-dialect/upgrade_from_34_to_35.sql
    CalendarServer/trunk/txdav/who/test/test_delegates.py

Modified: CalendarServer/trunk/txdav/common/datastore/sql.py
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql.py	2014-04-08 16:31:32 UTC (rev 13197)
+++ CalendarServer/trunk/txdav/common/datastore/sql.py	2014-04-08 18:01:59 UTC (rev 13198)
@@ -1452,6 +1452,7 @@
         )
 
 
+    @inlineCallbacks
     def addDelegate(self, delegator, delegate, readWrite):
         """
         Adds a row to the DELEGATES table.  The delegate should not be a
@@ -1465,14 +1466,21 @@
             read-only access
         @type readWrite: C{boolean}
         """
-        return self._addDelegateQuery.on(
-            self,
-            delegator=delegator.encode("utf-8"),
-            delegate=delegate.encode("utf-8"),
-            readWrite=1 if readWrite else 0
-        )
+        savepoint = SavepointAction("addDelegate")
+        yield savepoint.acquire(self)
+        try:
+            yield self._addDelegateQuery.on(
+                self,
+                delegator=delegator.encode("utf-8"),
+                delegate=delegate.encode("utf-8"),
+                readWrite=1 if readWrite else 0
+            )
+        except Exception:
+            # Row already exists
+            yield savepoint.rollback(self)
 
 
+    @inlineCallbacks
     def addDelegateGroup(self, delegator, delegateGroupID, readWrite,
                          isExternal=False):
         """
@@ -1487,13 +1495,19 @@
             read-only access
         @type readWrite: C{boolean}
         """
-        return self._addDelegateGroupQuery.on(
-            self,
-            delegator=delegator.encode("utf-8"),
-            groupID=delegateGroupID,
-            readWrite=1 if readWrite else 0,
-            isExternal=1 if isExternal else 0
-        )
+        savepoint = SavepointAction("addDelegateGroup")
+        yield savepoint.acquire(self)
+        try:
+            yield self._addDelegateGroupQuery.on(
+                self,
+                delegator=delegator.encode("utf-8"),
+                groupID=delegateGroupID,
+                readWrite=1 if readWrite else 0,
+                isExternal=1 if isExternal else 0
+            )
+        except Exception:
+            # Row already exists
+            yield savepoint.rollback(self)
 
 
     def removeDelegate(self, delegator, delegate, readWrite):

Modified: CalendarServer/trunk/txdav/common/datastore/sql_schema/current-oracle-dialect.sql
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql_schema/current-oracle-dialect.sql	2014-04-08 16:31:32 UTC (rev 13197)
+++ CalendarServer/trunk/txdav/common/datastore/sql_schema/current-oracle-dialect.sql	2014-04-08 18:01:59 UTC (rev 13198)
@@ -8,7 +8,7 @@
     "HOSTNAME" nvarchar2(255),
     "PID" integer not null,
     "PORT" integer not null,
-    "TIME" timestamp default CURRENT_TIMESTAMP at time zone 'UTC' not null,
+    "TIME" timestamp default CURRENT_TIMESTAMP at time zone 'UTC' not null, 
     primary key("HOSTNAME", "PORT")
 );
 
@@ -80,7 +80,7 @@
     "NOTIFICATION_DATA" nclob,
     "MD5" nchar(32),
     "CREATED" timestamp default CURRENT_TIMESTAMP at time zone 'UTC',
-    "MODIFIED" timestamp default CURRENT_TIMESTAMP at time zone 'UTC',
+    "MODIFIED" timestamp default CURRENT_TIMESTAMP at time zone 'UTC', 
     unique("NOTIFICATION_UID", "NOTIFICATION_HOME_RESOURCE_ID")
 );
 
@@ -98,8 +98,8 @@
     "ALARM_VEVENT_ALLDAY" nclob default null,
     "ALARM_VTODO_TIMED" nclob default null,
     "ALARM_VTODO_ALLDAY" nclob default null,
-    "TIMEZONE" nclob default null,
-    primary key("CALENDAR_HOME_RESOURCE_ID", "CALENDAR_RESOURCE_ID"),
+    "TIMEZONE" nclob default null, 
+    primary key("CALENDAR_HOME_RESOURCE_ID", "CALENDAR_RESOURCE_ID"), 
     unique("CALENDAR_HOME_RESOURCE_ID", "CALENDAR_RESOURCE_NAME")
 );
 
@@ -149,7 +149,7 @@
     "PRIVATE_COMMENTS" integer default 0 not null,
     "MD5" nchar(32),
     "CREATED" timestamp default CURRENT_TIMESTAMP at time zone 'UTC',
-    "MODIFIED" timestamp default CURRENT_TIMESTAMP at time zone 'UTC',
+    "MODIFIED" timestamp default CURRENT_TIMESTAMP at time zone 'UTC', 
     unique("CALENDAR_RESOURCE_ID", "RESOURCE_NAME")
 );
 
@@ -213,8 +213,8 @@
 create table ATTACHMENT_CALENDAR_OBJECT (
     "ATTACHMENT_ID" integer not null references ATTACHMENT on delete cascade,
     "MANAGED_ID" nvarchar2(255),
-    "CALENDAR_OBJECT_RESOURCE_ID" integer not null references CALENDAR_OBJECT on delete cascade,
-    primary key("ATTACHMENT_ID", "CALENDAR_OBJECT_RESOURCE_ID"),
+    "CALENDAR_OBJECT_RESOURCE_ID" integer not null references CALENDAR_OBJECT on delete cascade, 
+    primary key("ATTACHMENT_ID", "CALENDAR_OBJECT_RESOURCE_ID"), 
     unique("MANAGED_ID", "CALENDAR_OBJECT_RESOURCE_ID")
 );
 
@@ -222,7 +222,7 @@
     "RESOURCE_ID" integer not null,
     "NAME" nvarchar2(255),
     "VALUE" nclob,
-    "VIEWER_UID" nvarchar2(255),
+    "VIEWER_UID" nvarchar2(255), 
     primary key("RESOURCE_ID", "NAME", "VIEWER_UID")
 );
 
@@ -249,8 +249,8 @@
     "BIND_MODE" integer not null,
     "BIND_STATUS" integer not null,
     "BIND_REVISION" integer default 0 not null,
-    "MESSAGE" nclob,
-    primary key("ADDRESSBOOK_HOME_RESOURCE_ID", "OWNER_HOME_RESOURCE_ID"),
+    "MESSAGE" nclob, 
+    primary key("ADDRESSBOOK_HOME_RESOURCE_ID", "OWNER_HOME_RESOURCE_ID"), 
     unique("ADDRESSBOOK_HOME_RESOURCE_ID", "ADDRESSBOOK_RESOURCE_NAME")
 );
 
@@ -263,8 +263,8 @@
     "KIND" integer not null,
     "MD5" nchar(32),
     "CREATED" timestamp default CURRENT_TIMESTAMP at time zone 'UTC',
-    "MODIFIED" timestamp default CURRENT_TIMESTAMP at time zone 'UTC',
-    unique("ADDRESSBOOK_HOME_RESOURCE_ID", "RESOURCE_NAME"),
+    "MODIFIED" timestamp default CURRENT_TIMESTAMP at time zone 'UTC', 
+    unique("ADDRESSBOOK_HOME_RESOURCE_ID", "RESOURCE_NAME"), 
     unique("ADDRESSBOOK_HOME_RESOURCE_ID", "VCARD_UID")
 );
 
@@ -283,14 +283,14 @@
     "MEMBER_ID" integer not null,
     "REVISION" integer not null,
     "REMOVED" integer default 0 not null,
-    "MODIFIED" timestamp default CURRENT_TIMESTAMP at time zone 'UTC',
+    "MODIFIED" timestamp default CURRENT_TIMESTAMP at time zone 'UTC', 
     primary key("GROUP_ID", "MEMBER_ID", "REVISION")
 );
 
 create table ABO_FOREIGN_MEMBERS (
     "GROUP_ID" integer not null references ADDRESSBOOK_OBJECT on delete cascade,
     "ADDRESSBOOK_ID" integer not null references ADDRESSBOOK_HOME on delete cascade,
-    "MEMBER_ADDRESS" nvarchar2(255),
+    "MEMBER_ADDRESS" nvarchar2(255), 
     primary key("GROUP_ID", "MEMBER_ADDRESS")
 );
 
@@ -302,8 +302,8 @@
     "BIND_MODE" integer not null,
     "BIND_STATUS" integer not null,
     "BIND_REVISION" integer default 0 not null,
-    "MESSAGE" nclob,
-    primary key("ADDRESSBOOK_HOME_RESOURCE_ID", "GROUP_RESOURCE_ID"),
+    "MESSAGE" nclob, 
+    primary key("ADDRESSBOOK_HOME_RESOURCE_ID", "GROUP_RESOURCE_ID"), 
     unique("ADDRESSBOOK_HOME_RESOURCE_ID", "GROUP_ADDRESSBOOK_NAME")
 );
 
@@ -333,7 +333,7 @@
     "RESOURCE_NAME" nvarchar2(255),
     "REVISION" integer not null,
     "DELETED" integer not null,
-    "MODIFIED" timestamp default CURRENT_TIMESTAMP at time zone 'UTC',
+    "MODIFIED" timestamp default CURRENT_TIMESTAMP at time zone 'UTC', 
     unique("NOTIFICATION_HOME_RESOURCE_ID", "RESOURCE_NAME")
 );
 
@@ -343,7 +343,7 @@
     "MODIFIED" integer not null,
     "SUBSCRIBER_GUID" nvarchar2(255),
     "USER_AGENT" nvarchar2(255) default null,
-    "IP_ADDR" nvarchar2(255) default null,
+    "IP_ADDR" nvarchar2(255) default null, 
     primary key("TOKEN", "RESOURCE_KEY")
 );
 
@@ -352,7 +352,7 @@
     "ORGANIZER" nvarchar2(255),
     "ATTENDEE" nvarchar2(255),
     "ICALUID" nvarchar2(255),
-    "ACCESSED" timestamp default CURRENT_TIMESTAMP at time zone 'UTC',
+    "ACCESSED" timestamp default CURRENT_TIMESTAMP at time zone 'UTC', 
     primary key("ORGANIZER", "ATTENDEE", "ICALUID")
 );
 
@@ -426,18 +426,20 @@
 create table DELEGATES (
     "DELEGATOR" nvarchar2(255),
     "DELEGATE" nvarchar2(255),
-    "READ_WRITE" integer not null
+    "READ_WRITE" integer not null, 
+    primary key("DELEGATOR", "READ_WRITE", "DELEGATE")
 );
 
 create table DELEGATE_GROUPS (
     "DELEGATOR" nvarchar2(255),
     "GROUP_ID" integer not null,
     "READ_WRITE" integer not null,
-    "IS_EXTERNAL" integer not null
+    "IS_EXTERNAL" integer not null, 
+    primary key("DELEGATOR", "READ_WRITE", "GROUP_ID")
 );
 
 create table EXTERNAL_DELEGATE_GROUPS (
-    "DELEGATOR" nvarchar2(255),
+    "DELEGATOR" nvarchar2(255) primary key,
     "GROUP_UID_READ" nvarchar2(255),
     "GROUP_UID_WRITE" nvarchar2(255)
 );
@@ -698,7 +700,7 @@
     JOB_ID
 );
 
-create index GROUPS_GROUP_UID_ebf7a1d4 on GROUPS (
+create index GROUPS_GROUP_UID_b35cce23 on GROUPS (
     GROUP_UID
 );
 
@@ -710,6 +712,12 @@
     MEMBER_UID
 );
 
+create index DELEGATE_TO_DELEGATOR_5e149b11 on DELEGATES (
+    DELEGATE,
+    READ_WRITE,
+    DELEGATOR
+);
+
 create index CALENDAR_OBJECT_SPLIT_af71dcda on CALENDAR_OBJECT_SPLITTER_WORK (
     RESOURCE_ID
 );
@@ -800,12 +808,12 @@
 -- Extras
 
 create or replace function next_job return integer is
-  cursor c1 is select ID from JOB for update skip locked;
+  cursor c1 is select JOB_ID from JOB for update skip locked;
   result integer;
 begin
   open c1;
   fetch c1 into result;
-  select ID from JOB where ID = result for update;
+  select JOB_ID from JOB where ID = result for update;
   return result;
 end;
 /

Modified: CalendarServer/trunk/txdav/common/datastore/sql_schema/current.sql
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql_schema/current.sql	2014-04-08 16:31:32 UTC (rev 13197)
+++ CalendarServer/trunk/txdav/common/datastore/sql_schema/current.sql	2014-04-08 18:01:59 UTC (rev 13198)
@@ -806,18 +806,24 @@
 create table DELEGATES (
   DELEGATOR                     varchar(255) not null,
   DELEGATE                      varchar(255) not null,
-  READ_WRITE                    integer      not null -- 1 = ReadWrite, 0 = ReadOnly
+  READ_WRITE                    integer      not null, -- 1 = ReadWrite, 0 = ReadOnly
+
+  primary key (DELEGATOR, READ_WRITE, DELEGATE)
 );
+create index DELEGATE_TO_DELEGATOR on
+  DELEGATES(DELEGATE, READ_WRITE, DELEGATOR);
 
 create table DELEGATE_GROUPS (
   DELEGATOR                     varchar(255) not null,
   GROUP_ID                      integer      not null,
   READ_WRITE                    integer      not null, -- 1 = ReadWrite, 0 = ReadOnly
-  IS_EXTERNAL                   integer      not null -- 1 = ReadWrite, 0 = ReadOnly
+  IS_EXTERNAL                   integer      not null, -- 1 = ReadWrite, 0 = ReadOnly
+
+  primary key (DELEGATOR, READ_WRITE, GROUP_ID)
 );
 
 create table EXTERNAL_DELEGATE_GROUPS (
-  DELEGATOR                     varchar(255) not null,
+  DELEGATOR                     varchar(255) primary key not null,
   GROUP_UID_READ                varchar(255),
   GROUP_UID_WRITE               varchar(255)
 );

Modified: CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_34_to_35.sql
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_34_to_35.sql	2014-04-08 16:31:32 UTC (rev 13197)
+++ CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_34_to_35.sql	2014-04-08 18:01:59 UTC (rev 13198)
@@ -55,24 +55,26 @@
 create table DELEGATES (
     "DELEGATOR" nvarchar2(255),
     "DELEGATE" nvarchar2(255),
-    "READ_WRITE" integer not null
+    "READ_WRITE" integer not null,
+    primary key("DELEGATOR", "READ_WRITE", "DELEGATE")
 );
 
 create table DELEGATE_GROUPS (
     "DELEGATOR" nvarchar2(255),
     "GROUP_ID" integer not null,
     "READ_WRITE" integer not null,
-    "IS_EXTERNAL" integer not null
+    "IS_EXTERNAL" integer not null,
+    primary key("DELEGATOR", "READ_WRITE", "GROUP_ID")
 );
 
 create table EXTERNAL_DELEGATE_GROUPS (
-    "DELEGATOR" nvarchar2(255),
+    "DELEGATOR" nvarchar2(255) primary key,
     "GROUP_UID_READ" nvarchar2(255),
     "GROUP_UID_WRITE" nvarchar2(255)
 );
 
 
-create index GROUPS_GROUP_UID_ebf7a1d4 on GROUPS (
+create index GROUPS_GROUP_UID_b35cce23 on GROUPS (
     GROUP_UID
 );
 
@@ -84,7 +86,13 @@
     MEMBER_UID
 );
 
+create index DELEGATE_TO_DELEGATOR_5e149b11 on DELEGATES (
+    DELEGATE,
+    READ_WRITE,
+    DELEGATOR
+);
 
+
 -- Now update the version
 -- No data upgrades
 update CALENDARSERVER set VALUE = '35' where NAME = 'VERSION';

Modified: CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/postgres-dialect/upgrade_from_34_to_35.sql
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/postgres-dialect/upgrade_from_34_to_35.sql	2014-04-08 16:31:32 UTC (rev 13197)
+++ CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/postgres-dialect/upgrade_from_34_to_35.sql	2014-04-08 18:01:59 UTC (rev 13198)
@@ -38,7 +38,7 @@
 create table GROUPS (
   GROUP_ID                      integer      primary key default nextval('RESOURCE_ID_SEQ'),    -- implicit index
   NAME                          varchar(255) not null,
-  GROUP_UID                    varchar(255) not null,
+  GROUP_UID                     varchar(255) not null,
   MEMBERSHIP_HASH               varchar(255) not null,
   EXTANT                        integer default 1,
   CREATED                       timestamp default timezone('UTC', CURRENT_TIMESTAMP),
@@ -48,7 +48,7 @@
 
 create table GROUP_MEMBERSHIP (
   GROUP_ID                      integer,
-  MEMBER_UID                   varchar(255) not null
+  MEMBER_UID                    varchar(255) not null
 );
 create index GROUP_MEMBERSHIP_GROUP on GROUP_MEMBERSHIP(GROUP_ID);
 create index GROUP_MEMBERSHIP_MEMBER on GROUP_MEMBERSHIP(MEMBER_UID);
@@ -66,20 +66,27 @@
 create table DELEGATES (
   DELEGATOR                     varchar(255) not null,
   DELEGATE                      varchar(255) not null,
-  READ_WRITE                    integer      not null -- 1 = ReadWrite, 0 = ReadOnly
+  READ_WRITE                    integer      not null, -- 1 = ReadWrite, 0 = ReadOnly
+
+  primary key (DELEGATOR, READ_WRITE, DELEGATE)
 );
+create index DELEGATE_TO_DELEGATOR on
+  DELEGATES(DELEGATE, READ_WRITE, DELEGATOR);
 
+
 create table DELEGATE_GROUPS (
   DELEGATOR                     varchar(255) not null,
   GROUP_ID                      integer      not null,
   READ_WRITE                    integer      not null, -- 1 = ReadWrite, 0 = ReadOnly
-  IS_EXTERNAL                   integer      not null -- 1 = ReadWrite, 0 = ReadOnly
+  IS_EXTERNAL                   integer      not null, -- 1 = ReadWrite, 0 = ReadOnly
+
+  primary key (DELEGATOR, READ_WRITE, GROUP_ID)
 );
 
 create table EXTERNAL_DELEGATE_GROUPS (
-  DELEGATOR                     varchar(255) not null,
-  GROUP_UID_READ               varchar(255),
-  GROUP_UID_WRITE              varchar(255)
+  DELEGATOR                     varchar(255) primary key not null,
+  GROUP_UID_READ                varchar(255),
+  GROUP_UID_WRITE               varchar(255)
 );
 
 -- Now update the version

Modified: CalendarServer/trunk/txdav/who/test/test_delegates.py
===================================================================
--- CalendarServer/trunk/txdav/who/test/test_delegates.py	2014-04-08 16:31:32 UTC (rev 13197)
+++ CalendarServer/trunk/txdav/who/test/test_delegates.py	2014-04-08 18:01:59 UTC (rev 13198)
@@ -39,7 +39,7 @@
 
     @inlineCallbacks
     def test_directDelegation(self):
-        txn = self.store.newTransaction()
+        txn = self.store.newTransaction(label="test_directDelegation")
 
         delegator = yield self.directory.recordWithUID(u"__wsanchez1__")
         delegate1 = yield self.directory.recordWithUID(u"__sagen1__")
@@ -53,7 +53,7 @@
         self.assertEquals([u"__wsanchez1__"], [d.uid for d in delegators])
 
         yield txn.commit()  # So delegateService will see the changes
-        txn = self.store.newTransaction()
+        txn = self.store.newTransaction(label="test_directDelegation")
 
         # The "proxy-write" pseudoGroup will have one member
         pseudoGroup = yield self.directory.recordWithShortName(
@@ -130,7 +130,7 @@
         yield pseudoGroup.setMembers([delegate1, delegate2])
 
         # Verify the assignments were made
-        txn = self.store.newTransaction()
+        txn = self.store.newTransaction(label="test_directDelegation")
         delegates = (yield delegatesOf(txn, delegator, True))
         self.assertEquals(
             set([u"__sagen1__", u"__cdaboo1__"]),
@@ -142,7 +142,7 @@
         yield pseudoGroup.setMembers([delegate2])
 
         # Verify the assignments were made
-        txn = self.store.newTransaction()
+        txn = self.store.newTransaction(label="test_directDelegation")
         delegates = (yield delegatesOf(txn, delegator, True))
         self.assertEquals(
             set([u"__cdaboo1__"]),
@@ -153,7 +153,7 @@
 
     @inlineCallbacks
     def test_indirectDelegation(self):
-        txn = self.store.newTransaction()
+        txn = self.store.newTransaction(label="test_indirectDelegation")
 
         delegator = yield self.directory.recordWithUID(u"__wsanchez1__")
         delegate1 = yield self.directory.recordWithUID(u"__sagen1__")
@@ -233,3 +233,55 @@
             set([d.uid for d in delegates])
         )
         yield txn.commit()
+
+
+    @inlineCallbacks
+    def test_noDuplication(self):
+        """
+        Make sure addDelegate( ) is idempotent
+        """
+        delegator = yield self.directory.recordWithUID(u"__wsanchez1__")
+
+        # Delegate users:
+        delegate1 = yield self.directory.recordWithUID(u"__sagen1__")
+
+        txn = self.store.newTransaction(label="test_noDuplication")
+        yield addDelegate(txn, delegator, delegate1, True)
+        yield txn.commit()
+
+        txn = self.store.newTransaction(label="test_noDuplication")
+        yield addDelegate(txn, delegator, delegate1, True)
+        yield txn.commit()
+
+        txn = self.store.newTransaction(label="test_noDuplication")
+        results = (
+            yield txn._selectDelegatesQuery.on(
+                txn,
+                delegator=delegator.uid.encode("utf-8"),
+                readWrite=1
+            )
+        )
+        yield txn.commit()
+        self.assertEquals([["__sagen1__"]], results)
+
+        # Delegate groups:
+        group1 = yield self.directory.recordWithUID(u"__top_group_1__")
+
+        txn = self.store.newTransaction(label="test_noDuplication")
+        yield addDelegate(txn, delegator, group1, True)
+        yield txn.commit()
+
+        txn = self.store.newTransaction(label="test_noDuplication")
+        yield addDelegate(txn, delegator, group1, True)
+        yield txn.commit()
+
+        txn = self.store.newTransaction(label="test_noDuplication")
+        results = (
+            yield txn._selectDelegateGroupsQuery.on(
+                txn,
+                delegator=delegator.uid.encode("utf-8"),
+                readWrite=1
+            )
+        )
+        yield txn.commit()
+        self.assertEquals([["__top_group_1__"]], results)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20140408/bfd10783/attachment-0001.html>


More information about the calendarserver-changes mailing list