Update sync-collection REPORT to match -04 of draft.

This commit is contained in:
Andrew McMillan 2010-11-30 12:31:25 +13:00
parent 04ecf36c88
commit 4e12eb82e4
2 changed files with 97 additions and 82 deletions

View File

@ -1206,16 +1206,21 @@ DECLARE
in_old_sync_token ALIAS FOR $1; in_old_sync_token ALIAS FOR $1;
in_collection_id ALIAS FOR $2; in_collection_id ALIAS FOR $2;
tmp_int INT8; tmp_int INT8;
old_modification_time sync_tokens.modification_time%TYPE;
BEGIN BEGIN
IF in_old_sync_token > 0 THEN IF in_old_sync_token > 0 THEN
SELECT 1 INTO tmp_int FROM sync_changes SELECT modification_time INTO old_modification_time FROM sync_tokens WHERE sync_token = in_old_sync_token;
WHERE collection_id = in_collection_id
AND sync_time > (SELECT modification_time FROM sync_tokens WHERE sync_token = in_old_sync_token)
LIMIT 1;
IF NOT FOUND THEN IF NOT FOUND THEN
-- They are in an inconsistent state: we return NULL so they can re-start the process -- They are in an inconsistent state: we return NULL so they can re-start the process
RETURN NULL; RETURN NULL;
END IF; END IF;
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;
END IF;
END IF; END IF;
SELECT nextval('sync_tokens_sync_token_seq') INTO tmp_int; SELECT nextval('sync_tokens_sync_token_seq') INTO tmp_int;
INSERT INTO sync_tokens(collection_id, sync_token) VALUES( in_collection_id, tmp_int ); INSERT INTO sync_tokens(collection_id, sync_token) VALUES( in_collection_id, tmp_int );

View File

@ -34,6 +34,9 @@ function display_status( $status_code ) {
} }
$collection = new DAVResource( $request->path ); $collection = new DAVResource( $request->path );
if ( !$collection->Exists() ) {
$request->DoResponse( 404 );
}
$params = array( ':collection_id' => $collection->GetProperty('collection_id'), ':sync_token' => $sync_token ); $params = array( ':collection_id' => $collection->GetProperty('collection_id'), ':sync_token' => $sync_token );
$sql = "SELECT new_sync_token( :sync_token, :collection_id)"; $sql = "SELECT new_sync_token( :sync_token, :collection_id)";
@ -45,7 +48,7 @@ $row = $qry->Fetch();
if ( !isset($row->new_sync_token) ) { if ( !isset($row->new_sync_token) ) {
/** If we got a null back then they gave us a sync token we know not of, so provide a full sync */ /** If we got a null back then they gave us a sync token we know not of, so provide a full sync */
$sync_token =0; $sync_token = 0;
$params[':sync_token'] = $sync_token; $params[':sync_token'] = $sync_token;
if ( !$qry->QDo($sql, $params) || $qry->rows() <= 0 ) { if ( !$qry->QDo($sql, $params) || $qry->rows() <= 0 ) {
$request->DoResponse( 500, translate("Database error") ); $request->DoResponse( 500, translate("Database error") );
@ -54,9 +57,14 @@ if ( !isset($row->new_sync_token) ) {
} }
$new_token = $row->new_sync_token; $new_token = $row->new_sync_token;
if ( $sync_token == 0 ) { if ( $sync_token == $new_token ) {
// No change, so we just re-send the old token.
$responses[] = new XMLElement( 'sync-token', $new_token );
}
else {
if ( $sync_token == 0 ) {
$sql = <<<EOSQL $sql = <<<EOSQL
SELECT collection.*, calendar_item.*, caldav_data.*, addressbook_resource.*, 201 AS sync_status FROM collection SELECT collection.*, calendar_item.*, caldav_data.*, addressbook_resource.*, 201 AS sync_status FROM collection
LEFT JOIN caldav_data USING (collection_id) LEFT JOIN caldav_data USING (collection_id)
LEFT JOIN calendar_item USING (dav_id) LEFT JOIN calendar_item USING (dav_id)
LEFT JOIN addressbook_resource USING (dav_id) LEFT JOIN addressbook_resource USING (dav_id)
@ -64,10 +72,10 @@ SELECT collection.*, calendar_item.*, caldav_data.*, addressbook_resource.*, 201
ORDER BY collection.collection_id, caldav_data.dav_id ORDER BY collection.collection_id, caldav_data.dav_id
EOSQL; EOSQL;
unset($params[':sync_token']); unset($params[':sync_token']);
} }
else { else {
$sql = <<<EOSQL $sql = <<<EOSQL
SELECT collection.*, calendar_item.*, caldav_data.*, addressbook_resource.*, sync_changes.* SELECT collection.*, calendar_item.*, caldav_data.*, addressbook_resource.*, sync_changes.*
FROM collection LEFT JOIN sync_changes USING(collection_id) FROM collection LEFT JOIN sync_changes USING(collection_id)
LEFT JOIN caldav_data USING (collection_id,dav_id) LEFT JOIN caldav_data USING (collection_id,dav_id)
LEFT JOIN calendar_item USING (collection_id,dav_id) LEFT JOIN calendar_item USING (collection_id,dav_id)
@ -76,13 +84,13 @@ SELECT collection.*, calendar_item.*, caldav_data.*, addressbook_resource.*, syn
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)
ORDER BY collection.collection_id, sync_changes.dav_name, sync_changes.sync_time ORDER BY collection.collection_id, sync_changes.dav_name, sync_changes.sync_time
EOSQL; EOSQL;
} }
$qry = new AwlQuery($sql, $params ); $qry = new AwlQuery($sql, $params );
$last_dav_name = ''; $last_dav_name = '';
$first_status = 0; $first_status = 0;
if ( $qry->Exec("REPORT",__LINE__,__FILE__) ) { if ( $qry->Exec("REPORT",__LINE__,__FILE__) ) {
while( $object = $qry->Fetch() ) { while( $object = $qry->Fetch() ) {
if ( $object->dav_name == $last_dav_name ) { if ( $object->dav_name == $last_dav_name ) {
/** The complex case: this is the second or subsequent for this dav_id */ /** The complex case: this is the second or subsequent for this dav_id */
@ -98,41 +106,43 @@ if ( $qry->Exec("REPORT",__LINE__,__FILE__) ) {
else if ( $object->sync_status == 201 && $first_status == 404 ) { else if ( $object->sync_status == 201 && $first_status == 404 ) {
// ... Delete ... Create ... is indicated as a create, but don't forget we started with a delete // ... Delete ... Create ... is indicated as a create, but don't forget we started with a delete
array_pop($responses); array_pop($responses);
$resultset = array(
new XMLElement( 'href', ConstructURL($object->dav_name) ),
new XMLElement( 'status', display_status($object->sync_status) )
);
$dav_resource = new DAVResource($object); $dav_resource = new DAVResource($object);
$resultset = array_merge( $resultset, $dav_resource->GetPropStat($proplist,$reply) ); $resultset = $dav_resource->GetPropStat($proplist,$reply);
$responses[] = new XMLElement( 'sync-response', $resultset ); array_unshift($resultset, new XMLElement( 'href', ConstructURL($object->dav_name)));
$responses[] = new XMLElement( 'response', $resultset );
} }
/** Else: /** Else:
* the object existed at start and we have multiple modifications, * the object existed at start and we have multiple modifications,
* or, * or,
* the object didn't exist at start and we have subsequent modifications, * the object didn't exist at start and we have subsequent modifications,
* but: * but:
* in either case we simply stick with our first report. * in either case we simply stick with our existing report.
*/ */
} }
else { else {
/** The simple case: this is the first one for this dav_id */ /** The simple case: this is the first one for this dav_id */
if ( $object->sync_status == 404 ) {
$resultset = array( $resultset = array(
new XMLElement( 'href', ConstructURL($object->dav_name) ), new XMLElement( 'href', ConstructURL($object->dav_name) ),
new XMLElement( 'status', display_status($object->sync_status) ) new XMLElement( 'status', display_status($object->sync_status) )
); );
$first_status = 404;
}
else {
$dav_resource = new DAVResource($object); $dav_resource = new DAVResource($object);
$resultset = array_merge( $resultset, $dav_resource->GetPropStat($proplist,$reply) ); $resultset = $dav_resource->GetPropStat($proplist,$reply);
$response_tag = 'response'; array_unshift($resultset, new XMLElement( 'href', ConstructURL($object->dav_name)));
if ( isset($c->use_old_sync_response_tag) && $c->use_old_sync_response_tag ) $response_tag = 'sync-response';
$responses[] = new XMLElement( $response_tag, $resultset );
$first_status = $object->sync_status; $first_status = $object->sync_status;
}
$responses[] = new XMLElement( 'response', $resultset );
$last_dav_name = $object->dav_name; $last_dav_name = $object->dav_name;
} }
} }
$responses[] = new XMLElement( 'sync-token', $new_token ); $responses[] = new XMLElement( 'sync-token', $new_token );
} }
else { else {
$request->DoResponse( 500, translate("Database error") ); $request->DoResponse( 500, translate("Database error") );
}
} }
$multistatus = new XMLElement( "multistatus", $responses, $reply->GetXmlNsArray() ); $multistatus = new XMLElement( "multistatus", $responses, $reply->GetXmlNsArray() );