[libgda/LIBGDA_4.2] Make virtual connections work better with cursor only data models
- From: Vivien Malerba <vivien src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgda/LIBGDA_4.2] Make virtual connections work better with cursor only data models
- Date: Wed, 21 Sep 2011 16:06:30 +0000 (UTC)
commit 413b475c51c98526d2eed6d15b53270f45df9373
Author: Vivien Malerba <malerba gnome-db org>
Date: Sun Sep 18 18:34:26 2011 +0200
Make virtual connections work better with cursor only data models
libgda/gda-data-select.c | 23 +++++++++---------
libgda/sqlite/gda-sqlite-recordset.c | 27 +++++++++++++++++-----
libgda/sqlite/virtual/gda-vprovider-data-model.c | 25 ++++++++++++++++++-
3 files changed, 55 insertions(+), 20 deletions(-)
---
diff --git a/libgda/gda-data-select.c b/libgda/gda-data-select.c
index 7ce2e06..337ee04 100644
--- a/libgda/gda-data-select.c
+++ b/libgda/gda-data-select.c
@@ -2032,7 +2032,7 @@ gda_data_select_iter_next (GdaDataModel *model, GdaDataModelIter *iter)
target_iter_row = imodel->priv->sh->iter_row + 1;
int_row = external_to_internal_row (imodel, target_iter_row, NULL);
- prow = gda_data_select_get_stored_row (model, int_row);
+ prow = gda_data_select_get_stored_row (imodel, int_row);
if (!prow)
CLASS (model)->fetch_next (imodel, &prow, int_row, NULL);
@@ -2043,8 +2043,8 @@ gda_data_select_iter_next (GdaDataModel *model, GdaDataModelIter *iter)
}
else {
gda_data_model_iter_invalidate_contents (iter);
- imodel->priv->sh->iter_row = G_MAXINT;
- g_object_set (G_OBJECT (iter), "current-row", -1, NULL);
+ imodel->priv->sh->iter_row = G_MAXINT;
+ g_object_set (G_OBJECT (iter), "current-row", -1, NULL);
g_signal_emit_by_name (iter, "end-of-data");
return FALSE;
}
@@ -2064,17 +2064,11 @@ gda_data_select_iter_prev (GdaDataModel *model, GdaDataModelIter *iter)
if (imodel->priv->sh->usage_flags & GDA_DATA_MODEL_ACCESS_RANDOM)
return gda_data_model_iter_move_prev_default (model, iter);
- if (! CLASS (model)->fetch_prev) {
- gda_data_model_iter_invalidate_contents (iter);
- return FALSE;
- }
-
g_return_val_if_fail (iter, FALSE);
g_return_val_if_fail (imodel->priv->iter == iter, FALSE);
if (imodel->priv->sh->iter_row <= 0)
goto prev_error;
-
else if (imodel->priv->sh->iter_row == G_MAXINT) {
g_assert (imodel->advertized_nrows >= 0);
target_iter_row = imodel->advertized_nrows - 1;
@@ -2083,9 +2077,14 @@ gda_data_select_iter_prev (GdaDataModel *model, GdaDataModelIter *iter)
target_iter_row = imodel->priv->sh->iter_row - 1;
int_row = external_to_internal_row (imodel, target_iter_row, NULL);
- prow = gda_data_select_get_stored_row (model, int_row);
- if (!prow)
+ prow = gda_data_select_get_stored_row (imodel, int_row);
+ if (!prow) {
+ if (! CLASS (model)->fetch_prev) {
+ gda_data_model_iter_invalidate_contents (iter);
+ return FALSE;
+ }
CLASS (model)->fetch_prev (imodel, &prow, int_row, NULL);
+ }
if (prow) {
imodel->priv->sh->iter_row = target_iter_row;
@@ -2117,7 +2116,7 @@ gda_data_select_iter_at_row (GdaDataModel *model, GdaDataModelIter *iter, gint r
g_return_val_if_fail (imodel->priv->iter == iter, FALSE);
int_row = external_to_internal_row (imodel, row, NULL);
- prow = gda_data_select_get_stored_row (model, int_row);
+ prow = gda_data_select_get_stored_row (imodel, int_row);
if (prow) {
imodel->priv->sh->iter_row = row;
diff --git a/libgda/sqlite/gda-sqlite-recordset.c b/libgda/sqlite/gda-sqlite-recordset.c
index 1fec57d..c67bd9c 100644
--- a/libgda/sqlite/gda-sqlite-recordset.c
+++ b/libgda/sqlite/gda-sqlite-recordset.c
@@ -160,17 +160,19 @@ read_rows_to_init_col_types (GdaSqliteRecordset *model)
if (pmodel->prep_stmt->types[i] == GDA_TYPE_NULL)
missing_cols [nb_missing++] = i;
}
- /*
+
+#ifdef GDA_DEBUG_NO
if (nb_missing == 0)
- g_print ("Hey!, all columns are known for prep stmt %p\n", pmodel->prep_stmt);
- */
+ g_print ("All columns are known for model %p\n", pmodel);
+#endif
+
for (; nb_missing > 0; ) {
GdaRow *prow;
prow = fetch_next_sqlite_row (model, TRUE, NULL);
if (!prow)
break;
#ifdef GDA_DEBUG_NO
- g_print ("Read row %d for prep stmt %p\n", model->priv->next_row_num - 1, pmodel->prep_stmt);
+ g_print ("Prefetched row %d of model %p\n", model->priv->next_row_num - 1, pmodel);
#endif
for (i = nb_missing - 1; i >= 0; i--) {
if (pmodel->prep_stmt->types [missing_cols [i]] != GDA_TYPE_NULL) {
@@ -669,12 +671,25 @@ gda_sqlite_recordset_fetch_random (GdaDataSelect *model, GdaRow **prow, gint row
* Before a new #GdaRow gets created, the previous one, if set, is discarded.
*/
static gboolean
-gda_sqlite_recordset_fetch_next (GdaDataSelect *model, GdaRow **prow, G_GNUC_UNUSED gint rownum, GError **error)
+gda_sqlite_recordset_fetch_next (GdaDataSelect *model, GdaRow **prow, gint rownum, GError **error)
{
GdaSqliteRecordset *imodel = (GdaSqliteRecordset*) model;
- if (imodel->priv->tmp_row)
+ if (imodel->priv->tmp_row) {
g_object_unref (imodel->priv->tmp_row);
+ imodel->priv->tmp_row = NULL;
+ }
+ if (imodel->priv->next_row_num != rownum) {
+ GError *lerror = NULL;
+ *prow = NULL;
+ g_set_error (&lerror, GDA_DATA_MODEL_ERROR,
+ GDA_DATA_MODEL_ROW_NOT_FOUND_ERROR,
+ "%s", _("Can't set iterator on requested row"));
+ gda_data_select_add_exception (GDA_DATA_SELECT (model), lerror);
+ if (error)
+ g_propagate_error (error, g_error_copy (lerror));
+ return TRUE;
+ }
*prow = fetch_next_sqlite_row (imodel, FALSE, error);
imodel->priv->tmp_row = *prow;
diff --git a/libgda/sqlite/virtual/gda-vprovider-data-model.c b/libgda/sqlite/virtual/gda-vprovider-data-model.c
index 50ffb2a..9e9b4d7 100644
--- a/libgda/sqlite/virtual/gda-vprovider-data-model.c
+++ b/libgda/sqlite/virtual/gda-vprovider-data-model.c
@@ -277,7 +277,7 @@ handle_data_model_exception (sqlite3_vtab *pVtab, GdaDataModel *model)
if (pVtab->zErrMsg)
SQLITE3_CALL (sqlite3_free) (pVtab->zErrMsg);
pVtab->zErrMsg = SQLITE3_CALL (sqlite3_mprintf)
- (e->message ? e->message : _("No detail"));
+ ("%s", e->message ? e->message : _("No detail"));
if (fatal_error)
return SQLITE_ERROR;
else
@@ -931,10 +931,31 @@ virtualFilter (sqlite3_vtab_cursor *pVtabCursor, int idxNum, const char *idxStr,
else
cursor->iter = gda_data_model_create_iter (vtable->td->real_model);
+ if (gda_data_model_iter_is_valid (cursor->iter) &&
+ (gda_data_model_iter_get_row (cursor->iter) > 0)) {
+ /*g_print ("@%d, rewinding...", gda_data_model_iter_get_row (cursor->iter));*/
+ for (;gda_data_model_iter_move_prev (cursor->iter););
+ /*g_print ("done: @%d\n", gda_data_model_iter_get_row (cursor->iter));*/
+ if (gda_data_model_iter_is_valid (cursor->iter))
+ goto onerror;
+ }
+ if (! gda_data_model_iter_is_valid (cursor->iter)) {
+ gda_data_model_iter_move_next (cursor->iter);
+ if (! gda_data_model_iter_is_valid (cursor->iter))
+ goto onerror;
+ }
cursor->model = g_object_ref (vtable->td->real_model);
- gda_data_model_iter_move_next (cursor->iter);
return handle_data_model_exception (pVtabCursor->pVtab, cursor->model);
+
+ onerror:
+ g_object_unref (cursor->iter);
+ cursor->iter = NULL;
+ if (pVtabCursor->pVtab->zErrMsg)
+ SQLITE3_CALL (sqlite3_free) (pVtabCursor->pVtab->zErrMsg);
+ pVtabCursor->pVtab->zErrMsg = SQLITE3_CALL (sqlite3_mprintf)
+ ("%s", _("Can't obtain an iterator located on the first row"));
+ return SQLITE_ERROR;
}
#ifdef GDA_DEBUG_VIRTUAL
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]