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.
This commit is contained in:
Andrew McMillan 2012-04-17 15:44:09 +12:00
parent 35ab0875a1
commit 7c15051f84
24 changed files with 65 additions and 62 deletions

View File

@ -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;

View File

@ -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() ) {

View File

@ -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 );

View File

@ -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";

View File

@ -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"
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
<sync-token>data:,64</sync-token>
<sync-token>data:,40</sync-token>
</multistatus>

View File

@ -25,7 +25,7 @@
setval
--------
59
36
(1 row)
setval

View File

@ -38,5 +38,5 @@ Content-Type: text/xml; charset="utf-8"
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
<sync-token>data:,65</sync-token>
<sync-token>data:,41</sync-token>
</multistatus>

View File

@ -71,5 +71,5 @@ Content-Type: text/xml; charset="utf-8"
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
<sync-token>data:,66</sync-token>
<sync-token>data:,42</sync-token>
</multistatus>

View File

@ -10,7 +10,7 @@ HEAD
BEGINDATA
<?xml version="1.0" encoding="utf-8" ?>
<D:sync-collection xmlns:D="DAV:">
<D:sync-token>5</D:sync-token>
<D:sync-token>data:,41</D:sync-token>
<D:prop>
<D:getetag/>
</D:prop>

View File

@ -25,7 +25,7 @@
setval
--------
64
40
(1 row)
setval

View File

@ -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"
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
<sync-token>data:,17</sync-token>
<sync-token>data:,12</sync-token>
</multistatus>

View File

@ -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"
</report>
</supported-report>
</supported-report-set>
<sync-token>data:,42</sync-token>
<sync-token>data:,27</sync-token>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
@ -365,7 +365,7 @@ Content-Type: text/xml; charset="utf-8"
</report>
</supported-report>
</supported-report-set>
<sync-token>data:,43</sync-token>
<sync-token>data:,28</sync-token>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
@ -508,7 +508,7 @@ Content-Type: text/xml; charset="utf-8"
</report>
</supported-report>
</supported-report-set>
<sync-token>data:,44</sync-token>
<sync-token>data:,29</sync-token>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
@ -641,7 +641,7 @@ Content-Type: text/xml; charset="utf-8"
</report>
</supported-report>
</supported-report-set>
<sync-token>data:,39</sync-token>
<sync-token>data:,25</sync-token>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
@ -774,7 +774,7 @@ Content-Type: text/xml; charset="utf-8"
</report>
</supported-report>
</supported-report-set>
<sync-token>data:,45</sync-token>
<sync-token>data:,30</sync-token>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
@ -918,7 +918,7 @@ Content-Type: text/xml; charset="utf-8"
</report>
</supported-report>
</supported-report-set>
<sync-token>data:,36</sync-token>
<sync-token>data:,22</sync-token>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>

View File

@ -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"
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
<sync-token>data:,46</sync-token>
<sync-token>data:,27</sync-token>
</multistatus>

View File

@ -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"
<?xml version="1.0" encoding="utf-8" ?>
@ -62,15 +62,6 @@ Content-Type: text/xml; charset="utf-8"
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
<response>
<href>/caldav.php/user1/home/3F4CF6227300FD062D9EF3CDFB30D32D-0.ics</href>
<propstat>
<prop>
<getetag>"2c32a2f8aba853654eb17fe037a4db4d"</getetag>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
<response>
<href>/caldav.php/user1/home/4aaf8f37-f232-4c8e-a72e-e171d4c4fe54.ics</href>
<propstat>
@ -161,10 +152,6 @@ Content-Type: text/xml; charset="utf-8"
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
<response>
<href>/caldav.php/user1/home/F56B49B10FC923D20FE2DC92D6580340-0.ics</href>
<status>HTTP/1.1 404 Not Found</status>
</response>
<response>
<href>/caldav.php/user1/home/fbd57454-d966-4a14-8341-abe1edb1ae66.ics</href>
<propstat>
@ -174,5 +161,5 @@ Content-Type: text/xml; charset="utf-8"
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
<sync-token>data:,47</sync-token>
<sync-token>data:,27</sync-token>
</multistatus>

View File

@ -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
<?xml version="1.0" encoding="utf-8" ?>
<D:sync-collection xmlns:D="DAV:">
<D:sync-token>data:,1</D:sync-token>
<D:sync-token>data:,12</D:sync-token>
<D:prop>
<D:getetag/>
</D:prop>

View File

@ -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"
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
<sync-token>data:,58</sync-token>
<sync-token>data:,36</sync-token>
</multistatus>

View File

@ -15,7 +15,7 @@ BEGINDATA
<getetag/>
<getlastmodified/>
</prop>
<sync-token>data:,47</sync-token>
<sync-token>data:,27</sync-token>
</sync-collection>
ENDDATA

View File

@ -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"
<?xml version="1.0" encoding="utf-8" ?>
<multistatus xmlns="DAV:">
<sync-token>data:,58</sync-token>
<sync-token>data:,36</sync-token>
</multistatus>

View File

@ -17,7 +17,7 @@ BEGINDATA
<getetag/>
<getlastmodified/>
</prop>
<sync-token>data:,58</sync-token>
<sync-token>data:,36</sync-token>
</sync-collection>
ENDDATA

View File

@ -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"
<?xml version="1.0" encoding="utf-8" ?>
<multistatus xmlns="DAV:">
<sync-token>data:,58</sync-token>
<sync-token>data:,36</sync-token>
</multistatus>

View File

@ -17,7 +17,7 @@ BEGINDATA
<getetag/>
<getlastmodified/>
</prop>
<sync-token>data:,58</sync-token>
<sync-token>data:,36</sync-token>
</sync-collection>
ENDDATA

View File

@ -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"
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
<sync-token>data:,59</sync-token>
<sync-token>data:,36</sync-token>
</multistatus>

View File

@ -25,7 +25,7 @@
setval
--------
66
42
(1 row)
setval

View File

@ -25,7 +25,7 @@
setval
--------
79
47
(1 row)
setval