summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdata/gdata-private.h3
-rw-r--r--gdata/gdata-query.c45
-rw-r--r--gdata/gdata-service.c15
3 files changed, 61 insertions, 2 deletions
diff --git a/gdata/gdata-private.h b/gdata/gdata-private.h
index f470561b..8ad24876 100644
--- a/gdata/gdata-private.h
+++ b/gdata/gdata-private.h
@@ -72,7 +72,10 @@ G_GNUC_INTERNAL void _gdata_service_secure_strfree (GDataSecureString str);
#include "gdata-query.h"
G_GNUC_INTERNAL void _gdata_query_set_next_uri (GDataQuery *self, const gchar *next_uri);
+G_GNUC_INTERNAL void _gdata_query_set_next_uri_end (GDataQuery *self);
+G_GNUC_INTERNAL gboolean _gdata_query_is_finished (GDataQuery *self);
G_GNUC_INTERNAL void _gdata_query_set_previous_uri (GDataQuery *self, const gchar *previous_uri);
+G_GNUC_INTERNAL void _gdata_query_set_previous_uri_end (GDataQuery *self);
#include "gdata-parsable.h"
G_GNUC_INTERNAL GDataParsable *_gdata_parsable_new_from_xml (GType parsable_type, const gchar *xml, gint length, gpointer user_data,
diff --git a/gdata/gdata-query.c b/gdata/gdata-query.c
index bf42fe2b..a2a7cd8b 100644
--- a/gdata/gdata-query.c
+++ b/gdata/gdata-query.c
@@ -66,6 +66,18 @@ struct _GDataQueryPrivate {
gboolean is_strict;
guint max_results;
+ /* Pagination management. Supports three states:
+ * 1. (next_uri == NULL && !use_next_uri):
+ * Implement pagination by incrementing #GDataQuery:start-index
+ * internally with each call to gdata_query_next_page(). Stop
+ * when the returned #GDataFeed is empty.
+ * 2a. (next_uri != NULL && use_next_uri):
+ * Implement pagination with an explicit URI for the next page,
+ * which will be used when gdata_query_next_page() is called.
+ * 2b. (next_uri == NULL && use_next_uri):
+ * End of pagination using known URIs; return an empty
+ * #GDataFeed when gdata_query_next_page() is called.
+ */
gchar *next_uri;
gchar *previous_uri;
gboolean use_next_uri;
@@ -967,6 +979,25 @@ _gdata_query_set_next_uri (GDataQuery *self, const gchar *next_uri)
}
void
+_gdata_query_set_next_uri_end (GDataQuery *self)
+{
+ g_return_if_fail (GDATA_IS_QUERY (self));
+
+ g_free (self->priv->next_uri);
+ self->priv->next_uri = NULL;
+ self->priv->use_next_uri = TRUE;
+ self->priv->use_previous_uri = FALSE;
+}
+
+gboolean
+_gdata_query_is_finished (GDataQuery *self)
+{
+ g_return_val_if_fail (GDATA_IS_QUERY (self), FALSE);
+
+ return (self->priv->next_uri == NULL && self->priv->use_next_uri);
+}
+
+void
_gdata_query_set_previous_uri (GDataQuery *self, const gchar *previous_uri)
{
g_return_if_fail (GDATA_IS_QUERY (self));
@@ -976,6 +1007,17 @@ _gdata_query_set_previous_uri (GDataQuery *self, const gchar *previous_uri)
self->priv->use_previous_uri = FALSE;
}
+void
+_gdata_query_set_previous_uri_end (GDataQuery *self)
+{
+ g_return_if_fail (GDATA_IS_QUERY (self));
+
+ g_free (self->priv->previous_uri);
+ self->priv->previous_uri = NULL;
+ self->priv->use_next_uri = TRUE;
+ self->priv->use_previous_uri = FALSE;
+}
+
/**
* gdata_query_next_page:
* @self: a #GDataQuery
@@ -1029,7 +1071,8 @@ gdata_query_previous_page (GDataQuery *self)
if (priv->previous_uri != NULL) {
priv->use_previous_uri = TRUE;
priv->use_next_uri = FALSE;
- } else if (priv->start_index <= priv->max_results) {
+ } else if (priv->start_index <= priv->max_results ||
+ (priv->previous_uri == NULL && priv->use_previous_uri)) {
return FALSE;
} else {
priv->start_index -= priv->max_results;
diff --git a/gdata/gdata-service.c b/gdata/gdata-service.c
index ad4c1bc4..300824b2 100644
--- a/gdata/gdata-service.c
+++ b/gdata/gdata-service.c
@@ -963,14 +963,27 @@ __gdata_service_query (GDataService *self, GDataAuthorizationDomain *domain, con
SoupMessage *message;
GDataFeed *feed;
+ klass = GDATA_SERVICE_GET_CLASS (self);
+
+ /* Are we off the end of the final page? */
+ if (query != NULL && _gdata_query_is_finished (query)) {
+ GTimeVal updated;
+
+ /* Build an empty dummy feed to signify the end of the list. */
+ g_get_current_time (&updated);
+ return _gdata_feed_new (klass->feed_type, "Empty feed", "feed1",
+ updated.tv_sec);
+ }
+
+ /* Send the request. */
message = _gdata_service_query (self, domain, feed_uri, query, cancellable, error);
if (message == NULL)
return NULL;
g_assert (message->response_body->data != NULL);
- klass = GDATA_SERVICE_GET_CLASS (self);
g_assert (klass->parse_feed != NULL);
+ /* Parse the response. */
feed = klass->parse_feed (self, domain, query, entry_type,
message, cancellable, progress_callback,
progress_user_data, error);