From 7c15051f848e584c8979f12d2c37a86b1e221d02 Mon Sep 17 00:00:00 2001 From: Andrew McMillan Date: Tue, 17 Apr 2012 15:44:09 +1200 Subject: [PATCH] Further fixes to WebDAV synchronization. This should be fully reliable now and also cleans out all sync changes more than one week old. update-database is needed to pull the new function. --- dba/caldav_functions.sql | 33 ++++++++++++++----- inc/DAVResource.php | 2 +- inc/caldav-DELETE.php | 5 ++- inc/caldav-REPORT-sync-collection.php | 2 +- .../1036-REPORT-sync-initial-bound.result | 4 +-- testing/tests/binding/Restore-Database.result | 2 +- .../carddav/2010-REPORT-sync-initial.result | 2 +- .../carddav/2039-REPORT-sync-changed.result | 2 +- .../carddav/2039-REPORT-sync-changed.test | 2 +- testing/tests/carddav/Restore-Database.result | 2 +- .../0099-REPORT-sync-initial.result | 4 +-- .../0548-iCal-PROPFIND.result | 14 ++++---- .../0598-REPORT-sync-initial.result | 4 +-- .../0599-REPORT-sync-changed.result | 19 ++--------- .../0599-REPORT-sync-changed.test | 4 +-- .../1100-REPORT-sync-changed.result | 4 +-- .../1100-REPORT-sync-changed.test | 2 +- .../1101-REPORT-sync-changed.result | 4 +-- .../1101-REPORT-sync-changed.test | 2 +- .../1102-REPORT-sync-changed.result | 4 +-- .../1102-REPORT-sync-changed.test | 2 +- .../1103-REPORT-sync-changed.result | 4 +-- .../tests/scheduling/Restore-Database.result | 2 +- .../tests/timezone/Restore-Database.result | 2 +- 24 files changed, 65 insertions(+), 62 deletions(-) diff --git a/dba/caldav_functions.sql b/dba/caldav_functions.sql index 24313bf0..42c09280 100644 --- a/dba/caldav_functions.sql +++ b/dba/caldav_functions.sql @@ -1210,25 +1210,42 @@ DECLARE in_old_sync_token ALIAS FOR $1; in_collection_id ALIAS FOR $2; tmp_int INT8; + new_token sync_tokens.sync_token%TYPE; old_modification_time sync_tokens.modification_time%TYPE; BEGIN IF in_old_sync_token > 0 THEN - SELECT modification_time INTO old_modification_time FROM sync_tokens WHERE sync_token = in_old_sync_token; + SELECT modification_time INTO old_modification_time FROM sync_tokens + WHERE sync_token = in_old_sync_token AND collection_id = in_collection_id; IF NOT FOUND THEN -- They are in an inconsistent state: we return NULL so they can re-start the process RETURN NULL; END IF; + END IF; + + -- Find the most recent sync_token + SELECT sync_token, modification_time INTO new_token, old_modification_time FROM sync_tokens + WHERE collection_id = in_collection_id ORDER BY modification_time DESC LIMIT 1; + IF FOUND THEN SELECT 1 INTO tmp_int FROM sync_changes WHERE collection_id = in_collection_id AND sync_time > old_modification_time LIMIT 1; IF NOT FOUND THEN - -- Ensure we return the latest sync_token we have for this collection, since there are - -- no changes. - SELECT sync_token INTO tmp_int FROM sync_tokens WHERE collection_id = in_collection_id ORDER BY modification_time DESC LIMIT 1; - RETURN tmp_int; + -- Return the latest sync_token we have for this collection, since there are no changes. + RETURN new_token; END IF; END IF; - SELECT nextval('sync_tokens_sync_token_seq') INTO tmp_int; - INSERT INTO sync_tokens(collection_id, sync_token) VALUES( in_collection_id, tmp_int ); - RETURN tmp_int; + + -- Looks like we need a new sync_token for this collection... + SELECT nextval('sync_tokens_sync_token_seq') INTO new_token; + INSERT INTO sync_tokens(collection_id, sync_token) VALUES( in_collection_id, new_token ); + + -- Having created our new token we do some clean-up of old tokens + SELECT modification_time, sync_token INTO old_modification_time, tmp_int FROM sync_tokens + WHERE collection_id = in_collection_id AND modification_time < (current_timestamp - '7 days'::interval) + ORDER BY collection_id, modification_time DESC; + DELETE FROM sync_changes WHERE collection_id = in_collection_id AND sync_time < old_modification_time; + DELETE FROM sync_tokens WHERE collection_id = in_collection_id AND sync_token < tmp_int; + + -- Returning the new token + RETURN new_token; END $$ LANGUAGE 'PlPgSQL' STRICT; diff --git a/inc/DAVResource.php b/inc/DAVResource.php index ea3805b2..aabbcd36 100644 --- a/inc/DAVResource.php +++ b/inc/DAVResource.php @@ -1266,7 +1266,7 @@ EOQRY; if ( $this->IsPrincipal() ) return null; if ( $this->collection_id() == 0 ) return null; if ( !isset($this->sync_token) ) { - $sql = 'SELECT sync_token FROM sync_tokens WHERE collection_id = :collection_id ORDER BY sync_token DESC LIMIT 1'; + $sql = 'SELECT new_sync_token( 0, :collection_id) AS sync_token'; $params = array( ':collection_id' => $this->collection_id()); $qry = new AwlQuery($sql, $params ); if ( !$qry->Exec() || !$row = $qry->Fetch() ) { diff --git a/inc/caldav-DELETE.php b/inc/caldav-DELETE.php index af539d5a..52add374 100644 --- a/inc/caldav-DELETE.php +++ b/inc/caldav-DELETE.php @@ -82,10 +82,9 @@ else { $collection_id = $dav_resource->GetProperty('collection_id'); $params = array( ':dav_id' => $dav_resource->resource_id() ); - if ( $qry->QDo('SELECT new_sync_token(0,'.$collection_id.')') - && $qry->QDo("SELECT write_sync_change(collection_id, 404, caldav_data.dav_name) FROM caldav_data WHERE dav_id = :dav_id", $params ) - && $qry->QDo("DELETE FROM property WHERE dav_name = (SELECT dav_name FROM caldav_data WHERE dav_id = :dav_id)", $params ) + if ( $qry->QDo("DELETE FROM property WHERE dav_name = (SELECT dav_name FROM caldav_data WHERE dav_id = :dav_id)", $params ) && $qry->QDo("DELETE FROM locks WHERE dav_name = (SELECT dav_name FROM caldav_data WHERE dav_id = :dav_id)", $params ) + && $qry->QDo("SELECT write_sync_change(collection_id, 404, caldav_data.dav_name) FROM caldav_data WHERE dav_id = :dav_id", $params ) && $qry->QDo("DELETE FROM caldav_data WHERE dav_id = :dav_id", $params ) ) { if ( function_exists('log_caldav_action') ) { log_caldav_action( 'DELETE', $dav_resource->GetProperty('uid'), $dav_resource->GetProperty('user_no'), $collection_id, $request->path ); diff --git a/inc/caldav-REPORT-sync-collection.php b/inc/caldav-REPORT-sync-collection.php index f2e4c037..d1201721 100644 --- a/inc/caldav-REPORT-sync-collection.php +++ b/inc/caldav-REPORT-sync-collection.php @@ -100,7 +100,7 @@ EOSQL; LEFT JOIN calendar_item USING (collection_id,dav_id) LEFT JOIN addressbook_resource USING (dav_id) WHERE collection.collection_id = :collection_id - AND sync_time > (SELECT modification_time FROM sync_tokens WHERE sync_token = :sync_token) + AND sync_time >= (SELECT modification_time FROM sync_tokens WHERE sync_token = :sync_token) EOSQL; if ( isset($c->strict_result_ordering) && $c->strict_result_ordering ) { $sql .= " ORDER BY collection.collection_id, lower(sync_changes.dav_name), sync_changes.sync_time"; diff --git a/testing/tests/binding/1036-REPORT-sync-initial-bound.result b/testing/tests/binding/1036-REPORT-sync-initial-bound.result index 5ed1c571..86bef1c4 100644 --- a/testing/tests/binding/1036-REPORT-sync-initial-bound.result +++ b/testing/tests/binding/1036-REPORT-sync-initial-bound.result @@ -2,7 +2,7 @@ HTTP/1.1 207 Multi-Status Date: Dow, 01 Jan 2000 00:00:00 GMT DAV: 1, 2, 3, access-control, calendar-access, calendar-schedule DAV: extended-mkcol, bind, addressbook, calendar-auto-schedule, calendar-proxy -ETag: "d1e724878e4e8478a655c5fae6c1fa3c" +ETag: "4024ce3f5ccba7c419bf247a4632801e" Content-Length: 2302 Content-Type: text/xml; charset="utf-8" @@ -89,5 +89,5 @@ Content-Type: text/xml; charset="utf-8" HTTP/1.1 200 OK - data:,64 + data:,40 diff --git a/testing/tests/binding/Restore-Database.result b/testing/tests/binding/Restore-Database.result index 0205b771..d590a924 100644 --- a/testing/tests/binding/Restore-Database.result +++ b/testing/tests/binding/Restore-Database.result @@ -25,7 +25,7 @@ setval -------- - 59 + 36 (1 row) setval diff --git a/testing/tests/carddav/2010-REPORT-sync-initial.result b/testing/tests/carddav/2010-REPORT-sync-initial.result index 7b7136e9..d8b333f7 100644 --- a/testing/tests/carddav/2010-REPORT-sync-initial.result +++ b/testing/tests/carddav/2010-REPORT-sync-initial.result @@ -38,5 +38,5 @@ Content-Type: text/xml; charset="utf-8" HTTP/1.1 200 OK - data:,65 + data:,41 diff --git a/testing/tests/carddav/2039-REPORT-sync-changed.result b/testing/tests/carddav/2039-REPORT-sync-changed.result index cfdbf9c5..b984c011 100644 --- a/testing/tests/carddav/2039-REPORT-sync-changed.result +++ b/testing/tests/carddav/2039-REPORT-sync-changed.result @@ -71,5 +71,5 @@ Content-Type: text/xml; charset="utf-8" HTTP/1.1 200 OK - data:,66 + data:,42 diff --git a/testing/tests/carddav/2039-REPORT-sync-changed.test b/testing/tests/carddav/2039-REPORT-sync-changed.test index 01c3f7aa..02d0390b 100644 --- a/testing/tests/carddav/2039-REPORT-sync-changed.test +++ b/testing/tests/carddav/2039-REPORT-sync-changed.test @@ -10,7 +10,7 @@ HEAD BEGINDATA - 5 + data:,41 diff --git a/testing/tests/carddav/Restore-Database.result b/testing/tests/carddav/Restore-Database.result index 817acff0..095328c4 100644 --- a/testing/tests/carddav/Restore-Database.result +++ b/testing/tests/carddav/Restore-Database.result @@ -25,7 +25,7 @@ setval -------- - 64 + 40 (1 row) setval diff --git a/testing/tests/regression-suite/0099-REPORT-sync-initial.result b/testing/tests/regression-suite/0099-REPORT-sync-initial.result index acb9a0f0..3708716c 100644 --- a/testing/tests/regression-suite/0099-REPORT-sync-initial.result +++ b/testing/tests/regression-suite/0099-REPORT-sync-initial.result @@ -2,7 +2,7 @@ HTTP/1.1 207 Multi-Status Date: Dow, 01 Jan 2000 00:00:00 GMT DAV: 1, 2, 3, access-control, calendar-access, calendar-schedule DAV: extended-mkcol, bind, addressbook, calendar-auto-schedule, calendar-proxy -ETag: "3cf5a54d84dd74fc7e272361ff54c1c2" +ETag: "e19f623303e99e3b089b635e55823c28" Content-Length: 361 Content-Type: text/xml; charset="utf-8" @@ -17,5 +17,5 @@ Content-Type: text/xml; charset="utf-8" HTTP/1.1 200 OK - data:,17 + data:,12 diff --git a/testing/tests/regression-suite/0548-iCal-PROPFIND.result b/testing/tests/regression-suite/0548-iCal-PROPFIND.result index 9ef46ca8..78fa6e96 100644 --- a/testing/tests/regression-suite/0548-iCal-PROPFIND.result +++ b/testing/tests/regression-suite/0548-iCal-PROPFIND.result @@ -4,7 +4,7 @@ HTTP/1.1 207 Multi-Status Date: Dow, 01 Jan 2000 00:00:00 GMT DAV: 1, 2, 3, access-control, calendar-access, calendar-schedule DAV: extended-mkcol, bind, addressbook, calendar-auto-schedule, calendar-proxy -ETag: "bfb962d9c38d19e4ac04b8ced69de692" +ETag: "60916b1dd39825aaf565b74257f04c82" Content-Length: 29709 Content-Type: text/xml; charset="utf-8" @@ -240,7 +240,7 @@ Content-Type: text/xml; charset="utf-8" - data:,42 + data:,27 HTTP/1.1 200 OK @@ -365,7 +365,7 @@ Content-Type: text/xml; charset="utf-8" - data:,43 + data:,28 HTTP/1.1 200 OK @@ -508,7 +508,7 @@ Content-Type: text/xml; charset="utf-8" - data:,44 + data:,29 HTTP/1.1 200 OK @@ -641,7 +641,7 @@ Content-Type: text/xml; charset="utf-8" - data:,39 + data:,25 HTTP/1.1 200 OK @@ -774,7 +774,7 @@ Content-Type: text/xml; charset="utf-8" - data:,45 + data:,30 HTTP/1.1 200 OK @@ -918,7 +918,7 @@ Content-Type: text/xml; charset="utf-8" - data:,36 + data:,22 HTTP/1.1 200 OK diff --git a/testing/tests/regression-suite/0598-REPORT-sync-initial.result b/testing/tests/regression-suite/0598-REPORT-sync-initial.result index 9300fa63..243e31f5 100644 --- a/testing/tests/regression-suite/0598-REPORT-sync-initial.result +++ b/testing/tests/regression-suite/0598-REPORT-sync-initial.result @@ -2,7 +2,7 @@ HTTP/1.1 207 Multi-Status Date: Dow, 01 Jan 2000 00:00:00 GMT DAV: 1, 2, 3, access-control, calendar-access, calendar-schedule DAV: extended-mkcol, bind, addressbook, calendar-auto-schedule, calendar-proxy -ETag: "3ca2f604afe66d08212a8194f896e9a5" +ETag: "d09f24a62fb258fc8adec1116c3901dc" Content-Length: 4480 Content-Type: text/xml; charset="utf-8" @@ -170,5 +170,5 @@ Content-Type: text/xml; charset="utf-8" HTTP/1.1 200 OK - data:,46 + data:,27 diff --git a/testing/tests/regression-suite/0599-REPORT-sync-changed.result b/testing/tests/regression-suite/0599-REPORT-sync-changed.result index 71a07ac4..9d11637a 100644 --- a/testing/tests/regression-suite/0599-REPORT-sync-changed.result +++ b/testing/tests/regression-suite/0599-REPORT-sync-changed.result @@ -2,8 +2,8 @@ HTTP/1.1 207 Multi-Status Date: Dow, 01 Jan 2000 00:00:00 GMT DAV: 1, 2, 3, access-control, calendar-access, calendar-schedule DAV: extended-mkcol, bind, addressbook, calendar-auto-schedule, calendar-proxy -ETag: "ba74f029c7271d3094d45dabd5534418" -Content-Length: 4624 +ETag: "9335d41975cdc0507f9c9e85a7e961ea" +Content-Length: 4236 Content-Type: text/xml; charset="utf-8" @@ -62,15 +62,6 @@ Content-Type: text/xml; charset="utf-8" HTTP/1.1 200 OK - - /caldav.php/user1/home/3F4CF6227300FD062D9EF3CDFB30D32D-0.ics - - - "2c32a2f8aba853654eb17fe037a4db4d" - - HTTP/1.1 200 OK - - /caldav.php/user1/home/4aaf8f37-f232-4c8e-a72e-e171d4c4fe54.ics @@ -161,10 +152,6 @@ Content-Type: text/xml; charset="utf-8" HTTP/1.1 200 OK - - /caldav.php/user1/home/F56B49B10FC923D20FE2DC92D6580340-0.ics - HTTP/1.1 404 Not Found - /caldav.php/user1/home/fbd57454-d966-4a14-8341-abe1edb1ae66.ics @@ -174,5 +161,5 @@ Content-Type: text/xml; charset="utf-8" HTTP/1.1 200 OK - data:,47 + data:,27 diff --git a/testing/tests/regression-suite/0599-REPORT-sync-changed.test b/testing/tests/regression-suite/0599-REPORT-sync-changed.test index 60965b44..5dfe98a5 100644 --- a/testing/tests/regression-suite/0599-REPORT-sync-changed.test +++ b/testing/tests/regression-suite/0599-REPORT-sync-changed.test @@ -1,5 +1,5 @@ # -# Check for support of REPORT sync-collection with no sync-token +# Check for support of REPORT sync-collection with sync-token # TYPE=REPORT URL=http://mycaldav/caldav.php/user1/home/ @@ -10,7 +10,7 @@ HEAD BEGINDATA - data:,1 + data:,12 diff --git a/testing/tests/regression-suite/1100-REPORT-sync-changed.result b/testing/tests/regression-suite/1100-REPORT-sync-changed.result index 916d786f..38015e0c 100644 --- a/testing/tests/regression-suite/1100-REPORT-sync-changed.result +++ b/testing/tests/regression-suite/1100-REPORT-sync-changed.result @@ -2,7 +2,7 @@ HTTP/1.1 207 Multi-Status Date: Dow, 01 Jan 2000 00:00:00 GMT DAV: 1, 2, 3, access-control, calendar-access, calendar-schedule DAV: extended-mkcol, bind, addressbook, calendar-auto-schedule, calendar-proxy -ETag: "adf396e4066d8251128a3f8ecfcc0481" +ETag: "b74a74d1756d0fbbe7f839b73581dace" Content-Length: 1165 Content-Type: text/xml; charset="utf-8" @@ -42,5 +42,5 @@ Content-Type: text/xml; charset="utf-8" HTTP/1.1 200 OK - data:,58 + data:,36 diff --git a/testing/tests/regression-suite/1100-REPORT-sync-changed.test b/testing/tests/regression-suite/1100-REPORT-sync-changed.test index ce873270..e2020ec7 100644 --- a/testing/tests/regression-suite/1100-REPORT-sync-changed.test +++ b/testing/tests/regression-suite/1100-REPORT-sync-changed.test @@ -15,7 +15,7 @@ BEGINDATA - data:,47 + data:,27 ENDDATA diff --git a/testing/tests/regression-suite/1101-REPORT-sync-changed.result b/testing/tests/regression-suite/1101-REPORT-sync-changed.result index 7203451f..0f1f85ba 100644 --- a/testing/tests/regression-suite/1101-REPORT-sync-changed.result +++ b/testing/tests/regression-suite/1101-REPORT-sync-changed.result @@ -2,11 +2,11 @@ HTTP/1.1 207 Multi-Status Date: Dow, 01 Jan 2000 00:00:00 GMT DAV: 1, 2, 3, access-control, calendar-access, calendar-schedule DAV: extended-mkcol, bind, addressbook, calendar-auto-schedule, calendar-proxy -ETag: "a39452fdb89ce3ae9a822cec0e0efd10" +ETag: "dd8de466d4ad8e7acb47b6302ab04ef9" Content-Length: 117 Content-Type: text/xml; charset="utf-8" - data:,58 + data:,36 diff --git a/testing/tests/regression-suite/1101-REPORT-sync-changed.test b/testing/tests/regression-suite/1101-REPORT-sync-changed.test index ab97f738..5f469b70 100644 --- a/testing/tests/regression-suite/1101-REPORT-sync-changed.test +++ b/testing/tests/regression-suite/1101-REPORT-sync-changed.test @@ -17,7 +17,7 @@ BEGINDATA - data:,58 + data:,36 ENDDATA diff --git a/testing/tests/regression-suite/1102-REPORT-sync-changed.result b/testing/tests/regression-suite/1102-REPORT-sync-changed.result index 7203451f..0f1f85ba 100644 --- a/testing/tests/regression-suite/1102-REPORT-sync-changed.result +++ b/testing/tests/regression-suite/1102-REPORT-sync-changed.result @@ -2,11 +2,11 @@ HTTP/1.1 207 Multi-Status Date: Dow, 01 Jan 2000 00:00:00 GMT DAV: 1, 2, 3, access-control, calendar-access, calendar-schedule DAV: extended-mkcol, bind, addressbook, calendar-auto-schedule, calendar-proxy -ETag: "a39452fdb89ce3ae9a822cec0e0efd10" +ETag: "dd8de466d4ad8e7acb47b6302ab04ef9" Content-Length: 117 Content-Type: text/xml; charset="utf-8" - data:,58 + data:,36 diff --git a/testing/tests/regression-suite/1102-REPORT-sync-changed.test b/testing/tests/regression-suite/1102-REPORT-sync-changed.test index ab97f738..5f469b70 100644 --- a/testing/tests/regression-suite/1102-REPORT-sync-changed.test +++ b/testing/tests/regression-suite/1102-REPORT-sync-changed.test @@ -17,7 +17,7 @@ BEGINDATA - data:,58 + data:,36 ENDDATA diff --git a/testing/tests/regression-suite/1103-REPORT-sync-changed.result b/testing/tests/regression-suite/1103-REPORT-sync-changed.result index a81ef69b..22cd34d7 100644 --- a/testing/tests/regression-suite/1103-REPORT-sync-changed.result +++ b/testing/tests/regression-suite/1103-REPORT-sync-changed.result @@ -2,7 +2,7 @@ HTTP/1.1 207 Multi-Status Date: Dow, 01 Jan 2000 00:00:00 GMT DAV: 1, 2, 3, access-control, calendar-access, calendar-schedule DAV: extended-mkcol, bind, addressbook, calendar-auto-schedule, calendar-proxy -ETag: "9a90914dea200103fb2d8ed56e1468c2" +ETag: "bd79d222644ec62ac4d24d754dae06c2" Content-Length: 6649 Content-Type: text/xml; charset="utf-8" @@ -218,5 +218,5 @@ Content-Type: text/xml; charset="utf-8" HTTP/1.1 200 OK - data:,59 + data:,36 diff --git a/testing/tests/scheduling/Restore-Database.result b/testing/tests/scheduling/Restore-Database.result index 43c27fe7..00faf622 100644 --- a/testing/tests/scheduling/Restore-Database.result +++ b/testing/tests/scheduling/Restore-Database.result @@ -25,7 +25,7 @@ setval -------- - 66 + 42 (1 row) setval diff --git a/testing/tests/timezone/Restore-Database.result b/testing/tests/timezone/Restore-Database.result index 01de020c..6766746a 100644 --- a/testing/tests/timezone/Restore-Database.result +++ b/testing/tests/timezone/Restore-Database.result @@ -25,7 +25,7 @@ setval -------- - 79 + 47 (1 row) setval