views:

541

answers:

4

I'm trying to delete all calendar entries from today forward. I run a query then call getEntries() on the query result. getEntries() always returns 25 entries (or less if there are fewer than 25 entries on the calendar). Why aren't all the entries returned? I'm expecting about 80 entries.

As a test, I tried running the query, deleting the 25 entries returned, running the query again, deleting again, etc. This works, but there must be a better way.

Below is the Java code that only runs the query once.

CalendarQuery myQuery = new CalendarQuery(feedUrl);

DateFormat dfGoogle = new SimpleDateFormat("yyyy-MM-dd'T00:00:00'");
Date dt = Calendar.getInstance().getTime();

myQuery.setMinimumStartTime(DateTime.parseDateTime(dfGoogle.format(dt)));
// Make the end time far into the future so we delete everything
myQuery.setMaximumStartTime(DateTime.parseDateTime("2099-12-31T23:59:59"));

// Execute the query and get the response
CalendarEventFeed resultFeed = service.query(myQuery, CalendarEventFeed.class);

// !!! This returns 25 (or less if there are fewer than 25 entries on the calendar) !!!
int test = resultFeed.getEntries().size();

// Delete all the entries returned by the query
for (int j = 0; j < resultFeed.getEntries().size(); j++) {
   CalendarEventEntry entry = resultFeed.getEntries().get(j);

   entry.delete();
}

PS: I've looked at the Data API Developer's Guide and the Google Data API Javadoc. These sites are okay, but not great. Does anyone know of additional Google API documentation?

+5  A: 

You can increase the number of results with myQuery.setMaxResults(). There will be a maximum maximum though, so you can make multiple queries ('paged' results) by varying myQuery.setStartIndex().

http://code.google.com/apis/gdata/javadoc/com/google/gdata/client/Query.html#setMaxResults(int) http://code.google.com/apis/gdata/javadoc/com/google/gdata/client/Query.html#setStartIndex(int)

Jim Blackler
Thanks. Reading pages of results worked well.
Dean Hill
In case it is useful to anyone, I included my multi-page query code as a separate answer. That way people can see a coded solution.
Dean Hill
A: 

Unfortunately, Google is going to limit the maximum number of queries you can retrieve. This is so as to keep the query governor in their guidelines (HTTP requests not allowed to take more than 30 seconds, for example). They've built their whole architecture around this, so you might as well build the logic as you have.

Chris Kaminski
+1  A: 

Based on the answers from Jim Blackler and Chris Kaminski, I enhanced my code to read the query results in pages. I also do the delete as a batch, which should be faster than doing individual deletions.

I'm providing the Java code here in case it is useful to anyone.

CalendarQuery myQuery = new CalendarQuery(feedUrl);

DateFormat dfGoogle = new SimpleDateFormat("yyyy-MM-dd'T00:00:00'"); 
Date dt = Calendar.getInstance().getTime(); 

myQuery.setMinimumStartTime(DateTime.parseDateTime(dfGoogle.format(dt))); 
// Make the end time far into the future so we delete everything 
myQuery.setMaximumStartTime(DateTime.parseDateTime("2099-12-31T23:59:59")); 

// Set the maximum number of results to return for the query.
// Note: A GData server may choose to provide fewer results, but will never provide
// more than the requested maximum.
myQuery.setMaxResults(5000);
int startIndex = 1;
int entriesReturned;

List<CalendarEventEntry> allCalEntries = new ArrayList<CalendarEventEntry>();
CalendarEventFeed resultFeed;

// Run our query as many times as necessary to get all the
// Google calendar entries we want
while (true) {
    myQuery.setStartIndex(startIndex);

    // Execute the query and get the response
    resultFeed = service.query(myQuery, CalendarEventFeed.class);

    entriesReturned = resultFeed.getEntries().size();
    if (entriesReturned == 0)
        // We've hit the end of the list
        break;

    // Add the returned entries to our local list
    allCalEntries.addAll(resultFeed.getEntries());

    startIndex = startIndex + entriesReturned;
}

// Delete all the entries as a batch delete
CalendarEventFeed batchRequest = new CalendarEventFeed();

for (int i = 0; i < allCalEntries.size(); i++) {
    CalendarEventEntry entry = allCalEntries.get(i);

    BatchUtils.setBatchId(entry, Integer.toString(i));
    BatchUtils.setBatchOperationType(entry, BatchOperationType.DELETE);
    batchRequest.getEntries().add(entry);
}

// Get the batch link URL and send the batch request
Link batchLink = resultFeed.getLink(Link.Rel.FEED_BATCH, Link.Type.ATOM);
CalendarEventFeed batchResponse = service.batch(new URL(batchLink.getHref()), batchRequest);

// Ensure that all the operations were successful
boolean isSuccess = true;
StringBuffer batchFailureMsg = new StringBuffer("These entries in the batch delete failed:");
for (CalendarEventEntry entry : batchResponse.getEntries()) {
    String batchId = BatchUtils.getBatchId(entry);
    if (!BatchUtils.isSuccess(entry)) {
        isSuccess = false;
        BatchStatus status = BatchUtils.getBatchStatus(entry);
        batchFailureMsg.append("\nID: " + batchId + "  Reason: " + status.getReason());
    }
}

if (!isSuccess) {
    throw new Exception(batchFailureMsg.toString());
}
Dean Hill
A: 

There is a small quote on the API page http://code.google.com/apis/calendar/data/1.0/reference.html#Parameters

Note: The max-results query parameter for Calendar is set to 25 by default, so that you won't receive an entire calendar feed by accident. If you want to receive the entire feed, you can specify a very large number for max-results.

So to get all events from a google calendar feed, we do this:

google.calendarurl.com/.../basic?max-results=999999

in the API you can also query with setMaxResults=999999