1 /* 2 * Copyright (C) 2001 - 2002 Carlos Perelló Marín <carlos@gnome-db.org> 3 * Copyright (C) 2002 - 2003 Gonzalo Paniagua Javier <gonzalo@src.gnome.org> 4 * Copyright (C) 2002 - 2005 Rodrigo Moya <rodrigo@gnome-db.org> 5 * Copyright (C) 2005 Denis Fortin <denis.fortin@free.fr> 6 * Copyright (C) 2005 - 2013 Vivien Malerba <malerba@gnome-db.org> 7 * Copyright (C) 2005 Álvaro Peña <alvaropg@telefonica.net> 8 * Copyright (C) 2006 - 2008 Murray Cumming <murrayc@murrayc.com> 9 * Copyright (C) 2007 Armin Burgmeier <arminb@src.gnome.org> 10 * Copyright (C) 2009 Bas Driessen <bas.driessen@xobas.com> 11 * Copyright (C) 2010 David King <davidk@openismus.com> 12 * Copyright (C) 2011 Marco Ciampa <ciampix@libero.it> 13 * 14 * This library is free software; you can redistribute it and/or 15 * modify it under the terms of the GNU Lesser General Public 16 * License as published by the Free Software Foundation; either 17 * version 2 of the License, or (at your option) any later version. 18 * 19 * This library is distributed in the hope that it will be useful, 20 * but WITHOUT ANY WARRANTY; without even the implied warranty of 21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 22 * Lesser General Public License for more details. 23 * 24 * You should have received a copy of the GNU Lesser General Public 25 * License along with this library; if not, write to the 26 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 27 * Boston, MA 02110-1301, USA. 28 */ 29 30 #include <stdarg.h> 31 #include <string.h> 32 #include <glib/gi18n-lib.h> 33 #include "gda-sqlite.h" 34 #include "gda-sqlite-util.h" 35 #include "gda-sqlite-recordset.h" 36 #include "gda-sqlite-provider.h" 37 #include "gda-sqlite-blob-op.h" 38 #include <libgda/gda-util.h> 39 #include <libgda/gda-connection-private.h> 40 41 #include "virtual/gda-vconnection-data-model.h" 42 #include "virtual/gda-vconnection-data-model-private.h" 43 44 #define _GDA_PSTMT(x) ((GdaPStmt*)(x)) 45 46 static void gda_sqlite_recordset_class_init (GdaSqliteRecordsetClass *klass); 47 static void gda_sqlite_recordset_init (GdaSqliteRecordset *recset, 48 GdaSqliteRecordsetClass *klass); 49 static void gda_sqlite_recordset_dispose (GObject *object); 50 51 /* virtual methods */ 52 static gint gda_sqlite_recordset_fetch_nb_rows (GdaDataSelect *model); 53 static gboolean gda_sqlite_recordset_fetch_random (GdaDataSelect *model, GdaRow **prow, gint rownum, GError **error); 54 55 static gboolean gda_sqlite_recordset_fetch_next (GdaDataSelect *model, GdaRow **prow, gint rownum, GError **error); 56 57 58 static GdaRow *fetch_next_sqlite_row (GdaSqliteRecordset *model, gboolean do_store, GError **error); 59 60 static void virt_cnc_set_working_obj (GdaConnection *cnc, GdaSqliteRecordset *model); 61 62 struct _GdaSqliteRecordsetPrivate { 63 gboolean empty_forced; 64 gint next_row_num; 65 GdaRow *tmp_row; /* used in cursor mode */ 66 }; 67 static GObjectClass *parent_class = NULL; 68 GHashTable *error_blobs_hash = NULL; 69 70 /* 71 * Object init and finalize 72 */ 73 static void 74 gda_sqlite_recordset_init (GdaSqliteRecordset *recset, 75 G_GNUC_UNUSED GdaSqliteRecordsetClass *klass) 76 { 77 g_return_if_fail (GDA_IS_SQLITE_RECORDSET (recset)); 78 recset->priv = g_new0 (GdaSqliteRecordsetPrivate, 1); 79 recset->priv->next_row_num = 0; 80 recset->priv->empty_forced = FALSE; 81 } 82 83 static void 84 gda_sqlite_recordset_class_init (GdaSqliteRecordsetClass *klass) 85 { 86 GObjectClass *object_class = G_OBJECT_CLASS (klass); 87 GdaDataSelectClass *pmodel_class = GDA_DATA_SELECT_CLASS (klass); 88 89 parent_class = g_type_class_peek_parent (klass); 90 91 object_class->dispose = gda_sqlite_recordset_dispose; 92 pmodel_class->fetch_nb_rows = gda_sqlite_recordset_fetch_nb_rows; 93 pmodel_class->fetch_random = gda_sqlite_recordset_fetch_random; 94 95 pmodel_class->fetch_next = gda_sqlite_recordset_fetch_next; 96 pmodel_class->fetch_prev = NULL; 97 pmodel_class->fetch_at = NULL; 98 99 g_assert (!error_blobs_hash); 100 error_blobs_hash = g_hash_table_new (NULL, NULL); 101 } 102 103 static void 104 gda_sqlite_recordset_dispose (GObject *object) 105 { 106 GdaSqliteRecordset *recset = (GdaSqliteRecordset *) object; 107 108 g_return_if_fail (GDA_IS_SQLITE_RECORDSET (recset)); 109 110 if (recset->priv) { 111 GdaSqlitePStmt *ps; 112 ps = GDA_SQLITE_PSTMT (GDA_DATA_SELECT (object)->prep_stmt); 113 ps->stmt_used = FALSE; 114 virt_cnc_set_working_obj (gda_data_select_get_connection ((GdaDataSelect*) recset), recset); 115 SQLITE3_CALL (sqlite3_reset) (ps->sqlite_stmt); 116 virt_cnc_set_working_obj (gda_data_select_get_connection ((GdaDataSelect*) recset), NULL); 117 118 if (recset->priv->tmp_row) 119 g_object_unref (recset->priv->tmp_row); 120 g_free (recset->priv); 121 recset->priv = NULL; 122 } 123 124 parent_class->dispose (object); 125 } 126 127 /* 128 * Public functions 129 */ 130 131 GType 132 _gda_sqlite_recordset_get_type (void) 133 { 134 static GType type = 0; 135 136 if (G_UNLIKELY (type == 0)) { 137 static GMutex registering; 138 static const GTypeInfo info = { 139 sizeof (GdaSqliteRecordsetClass), 140 (GBaseInitFunc) NULL, 141 (GBaseFinalizeFunc) NULL, 142 (GClassInitFunc) gda_sqlite_recordset_class_init, 143 NULL, 144 NULL, 145 sizeof (GdaSqliteRecordset), 146 0, 147 (GInstanceInitFunc) gda_sqlite_recordset_init, 148 0 149 }; 150 g_mutex_lock (®istering); 151 if (type == 0) 152 type = g_type_register_static (GDA_TYPE_DATA_SELECT, CLASS_PREFIX "Recordset", &info, 0); 153 g_mutex_unlock (®istering); 154 } 155 156 return type; 157 } 158 159 static void 160 read_rows_to_init_col_types (GdaSqliteRecordset *model) 161 { 162 gint i; 163 gint *missing_cols, nb_missing; 164 GdaDataSelect *pmodel = (GdaDataSelect*) model; 165 166 missing_cols = g_new (gint, pmodel->prep_stmt->ncols); 167 for (nb_missing = 0, i = 0; i < pmodel->prep_stmt->ncols; i++) { 168 if (pmodel->prep_stmt->types[i] == GDA_TYPE_NULL) 169 missing_cols [nb_missing++] = i; 170 } 171 172 #ifdef GDA_DEBUG_NO 173 if (nb_missing == 0) 174 g_print ("All columns are known for model %p\n", pmodel); 175 #endif 176 177 for (; nb_missing > 0; ) { 178 GdaRow *prow; 179 prow = fetch_next_sqlite_row (model, TRUE, NULL); 180 if (!prow) 181 break; 182 #ifdef GDA_DEBUG_NO 183 g_print ("Prefetched row %d of model %p\n", model->priv->next_row_num - 1, pmodel); 184 #endif 185 for (i = nb_missing - 1; i >= 0; i--) { 186 if (pmodel->prep_stmt->types [missing_cols [i]] != GDA_TYPE_NULL) { 187 #ifdef GDA_DEBUG_NO 188 g_print ("Found type '%s' for col %d\n", 189 g_type_name (pmodel->prep_stmt->types [missing_cols [i]]), 190 missing_cols [i]); 191 #endif 192 memmove (missing_cols + i, missing_cols + i + 1, sizeof (gint) * (nb_missing - i - 1)); 193 nb_missing --; 194 } 195 } 196 } 197 198 #ifdef GDA_DEBUG_NO 199 if (nb_missing > 0) 200 g_print ("Hey!, some columns are still not known for prep stmt %p\n", pmodel->prep_stmt); 201 #endif 202 203 g_free (missing_cols); 204 } 205 206 /* 207 * the @ps struct is modified and transferred to the new data model created in 208 * this function 209 */ 210 GdaDataModel * 211 _gda_sqlite_recordset_new (GdaConnection *cnc, GdaSqlitePStmt *ps, GdaSet *exec_params, 212 GdaDataModelAccessFlags flags, GType *col_types, gboolean force_empty) 213 { 214 GdaSqliteRecordset *model; 215 SqliteConnectionData *cdata; 216 gint i; 217 GdaDataModelAccessFlags rflags; 218 219 g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL); 220 g_return_val_if_fail (ps != NULL, NULL); 221 222 cdata = (SqliteConnectionData*) gda_connection_internal_get_provider_data (cnc); 223 if (!cdata) 224 return NULL; 225 226 if (!cdata->types_hash) 227 _gda_sqlite_compute_types_hash (cdata); 228 229 /* make sure @ps reports the correct number of columns */ 230 if (_GDA_PSTMT (ps)->ncols < 0) 231 _GDA_PSTMT (ps)->ncols = SQLITE3_CALL (sqlite3_column_count) (ps->sqlite_stmt) - 232 ps->nb_rowid_columns; 233 234 /* completing ps */ 235 g_assert (! ps->stmt_used); 236 ps->stmt_used = TRUE; 237 if (!_GDA_PSTMT (ps)->types && (_GDA_PSTMT (ps)->ncols > 0)) { 238 /* create prepared statement's columns */ 239 GSList *list; 240 for (i = 0; i < _GDA_PSTMT (ps)->ncols; i++) 241 _GDA_PSTMT (ps)->tmpl_columns = g_slist_prepend (_GDA_PSTMT (ps)->tmpl_columns, 242 gda_column_new ()); 243 _GDA_PSTMT (ps)->tmpl_columns = g_slist_reverse (_GDA_PSTMT (ps)->tmpl_columns); 244 245 /* create prepared statement's types, all types are initialized to GDA_TYPE_NULL */ 246 _GDA_PSTMT (ps)->types = g_new (GType, _GDA_PSTMT (ps)->ncols); 247 for (i = 0; i < _GDA_PSTMT (ps)->ncols; i++) 248 _GDA_PSTMT (ps)->types [i] = GDA_TYPE_NULL; 249 250 if (col_types) { 251 for (i = 0; ; i++) { 252 if (col_types [i] > 0) { 253 if (col_types [i] == G_TYPE_NONE) 254 break; 255 if (i >= _GDA_PSTMT (ps)->ncols) 256 g_warning (_("Column %d out of range (0-%d), ignoring its specified type"), i, 257 _GDA_PSTMT (ps)->ncols - 1); 258 else 259 _GDA_PSTMT (ps)->types [i] = col_types [i]; 260 } 261 } 262 } 263 264 /* fill GdaColumn's data */ 265 for (i=0, list = _GDA_PSTMT (ps)->tmpl_columns; 266 i < GDA_PSTMT (ps)->ncols; 267 i++, list = list->next) { 268 GdaColumn *column; 269 gint real_col = i + ps->nb_rowid_columns; 270 271 column = GDA_COLUMN (list->data); 272 gda_column_set_description (column, SQLITE3_CALL (sqlite3_column_name) (ps->sqlite_stmt, real_col)); 273 gda_column_set_name (column, SQLITE3_CALL (sqlite3_column_name) (ps->sqlite_stmt, real_col)); 274 gda_column_set_dbms_type (column, SQLITE3_CALL (sqlite3_column_decltype) (ps->sqlite_stmt, real_col)); 275 if (_GDA_PSTMT (ps)->types [i] != GDA_TYPE_NULL) 276 gda_column_set_g_type (column, _GDA_PSTMT (ps)->types [i]); 277 } 278 } 279 280 /* determine access mode: RANDOM or CURSOR FORWARD are the only supported; if CURSOR BACKWARD 281 * is requested, then we need RANDOM mode */ 282 if (flags & GDA_DATA_MODEL_ACCESS_RANDOM) 283 rflags = GDA_DATA_MODEL_ACCESS_RANDOM; 284 else if (flags & GDA_DATA_MODEL_ACCESS_CURSOR_BACKWARD) 285 rflags = GDA_DATA_MODEL_ACCESS_RANDOM; 286 else 287 rflags = GDA_DATA_MODEL_ACCESS_CURSOR_FORWARD; 288 289 /* create data model */ 290 model = g_object_new (GDA_TYPE_SQLITE_RECORDSET, "connection", cnc, 291 "prepared-stmt", ps, "model-usage", rflags, 292 "exec-params", exec_params, 293 "auto-reset", force_empty, NULL); 294 gboolean is_virt; 295 is_virt = GDA_IS_VCONNECTION_DATA_MODEL (cnc) ? TRUE : FALSE; 296 if (is_virt) { 297 /* steal the lock */ 298 _gda_vconnection_change_working_obj ((GdaVconnectionDataModel*) cnc, (GObject*) model); 299 _gda_vconnection_set_working_obj ((GdaVconnectionDataModel*) cnc, NULL); 300 } 301 302 /* fill the data model */ 303 read_rows_to_init_col_types (model); 304 305 return GDA_DATA_MODEL (model); 306 } 307 308 static GType 309 fuzzy_get_gtype (SqliteConnectionData *cdata, GdaSqlitePStmt *ps, gint colnum) 310 { 311 const gchar *ctype; 312 GType gtype = GDA_TYPE_NULL; 313 gint real_col = colnum + ps->nb_rowid_columns; 314 315 if (_GDA_PSTMT (ps)->types [colnum] != GDA_TYPE_NULL) 316 return _GDA_PSTMT (ps)->types [colnum]; 317 318 ctype = SQLITE3_CALL (sqlite3_column_origin_name) (ps->sqlite_stmt, real_col); 319 if (ctype && !strcmp (ctype, "rowid")) 320 gtype = G_TYPE_INT64; 321 else { 322 ctype = SQLITE3_CALL (sqlite3_column_decltype) (ps->sqlite_stmt, real_col); 323 324 if (ctype) { 325 GType *pg; 326 pg = g_hash_table_lookup (cdata->types_hash, ctype); 327 gtype = pg ? *pg : GDA_TYPE_NULL; 328 } 329 if (gtype == GDA_TYPE_NULL) 330 gtype = _gda_sqlite_compute_g_type (SQLITE3_CALL (sqlite3_column_type) (ps->sqlite_stmt, real_col)); 331 } 332 333 return gtype; 334 } 335 336 static void 337 virt_cnc_set_working_obj (GdaConnection *cnc, GdaSqliteRecordset *model) 338 { 339 gboolean is_virt; 340 is_virt = GDA_IS_VCONNECTION_DATA_MODEL (cnc) ? TRUE : FALSE; 341 if (is_virt) 342 _gda_vconnection_set_working_obj ((GdaVconnectionDataModel*) cnc, (GObject*) model); 343 } 344 345 static GdaRow * 346 fetch_next_sqlite_row (GdaSqliteRecordset *model, gboolean do_store, GError **error) 347 { 348 int rc; 349 SqliteConnectionData *cdata; 350 GdaSqlitePStmt *ps; 351 GdaRow *prow = NULL; 352 353 cdata = (SqliteConnectionData*) gda_connection_internal_get_provider_data_error 354 (gda_data_select_get_connection ((GdaDataSelect*) model), error); 355 if (!cdata) 356 return NULL; 357 ps = GDA_SQLITE_PSTMT (GDA_DATA_SELECT (model)->prep_stmt); 358 359 virt_cnc_set_working_obj (gda_data_select_get_connection ((GdaDataSelect*) model), model); 360 361 if (model->priv->empty_forced) 362 rc = SQLITE_DONE; 363 else 364 rc = SQLITE3_CALL (sqlite3_step) (ps->sqlite_stmt); 365 switch (rc) { 366 case SQLITE_ROW: { 367 gint col, real_col; 368 prow = gda_row_new (_GDA_PSTMT (ps)->ncols); 369 for (col = 0; col < _GDA_PSTMT (ps)->ncols; col++) { 370 GValue *value; 371 GType type = _GDA_PSTMT (ps)->types [col]; 372 373 real_col = col + ps->nb_rowid_columns; 374 375 if (type == GDA_TYPE_NULL) { 376 type = fuzzy_get_gtype (cdata, ps, col); 377 if (type == GDA_TYPE_BLOB) { 378 /* extra check: make sure we have a rowid for this blob, or fallback to binary */ 379 if (ps->rowid_hash) { 380 gint oidcol = 0; 381 const char *ctable; 382 ctable = SQLITE3_CALL (sqlite3_column_name) (ps->sqlite_stmt, real_col); 383 if (ctable) 384 oidcol = GPOINTER_TO_INT (g_hash_table_lookup (ps->rowid_hash, 385 ctable)); 386 if (oidcol == 0) { 387 ctable = SQLITE3_CALL (sqlite3_column_table_name) (ps->sqlite_stmt, real_col); 388 if (ctable) 389 oidcol = GPOINTER_TO_INT (g_hash_table_lookup (ps->rowid_hash, 390 ctable)); 391 } 392 if (oidcol == 0) 393 type = GDA_TYPE_BINARY; 394 } 395 else 396 type = GDA_TYPE_BINARY; 397 } 398 if (type != GDA_TYPE_NULL) { 399 GdaColumn *column; 400 401 _GDA_PSTMT (ps)->types [col] = type; 402 column = gda_data_model_describe_column (GDA_DATA_MODEL (model), col); 403 gda_column_set_g_type (column, type); 404 column = (GdaColumn *) g_slist_nth_data (_GDA_PSTMT (ps)->tmpl_columns, col); 405 gda_column_set_g_type (column, type); 406 } 407 } 408 409 /* fill GValue */ 410 value = gda_row_get_value (prow, col); 411 GError *may_error; 412 may_error = (GError*) SQLITE3_CALL (sqlite3_column_blob) (ps->sqlite_stmt, real_col); 413 if (may_error && g_hash_table_lookup (error_blobs_hash, may_error)) { 414 /*g_print ("Row invalidated: [%s]\n", may_error->message);*/ 415 gda_row_invalidate_value_e (prow, value, may_error); 416 g_hash_table_remove (error_blobs_hash, may_error); 417 } 418 else if (SQLITE3_CALL (sqlite3_column_text) (ps->sqlite_stmt, real_col) == NULL) { 419 /* we have a NULL value */ 420 gda_value_set_null (value); 421 } 422 else { 423 gda_value_reset_with_type (value, type); 424 425 if (type == GDA_TYPE_NULL) 426 ; 427 else if (type == G_TYPE_INT) { 428 gint64 i; 429 i = SQLITE3_CALL (sqlite3_column_int64) (ps->sqlite_stmt, real_col); 430 if ((i > G_MAXINT) || (i < G_MININT)) { 431 GError *lerror = NULL; 432 g_set_error (&lerror, GDA_SERVER_PROVIDER_ERROR, 433 GDA_SERVER_PROVIDER_DATA_ERROR, 434 "%s", _("Integer value is too big")); 435 gda_row_invalidate_value_e (prow, value, lerror); 436 } 437 else 438 g_value_set_int (value, (gint) i); 439 } 440 else if (type == G_TYPE_UINT) { 441 guint64 i; 442 i = (gint64) SQLITE3_CALL (sqlite3_column_int64) (ps->sqlite_stmt, real_col); 443 if (i > G_MAXUINT) { 444 GError *lerror = NULL; 445 g_set_error (&lerror, GDA_SERVER_PROVIDER_ERROR, 446 GDA_SERVER_PROVIDER_DATA_ERROR, 447 "%s", _("Integer value is too big")); 448 gda_row_invalidate_value_e (prow, value, lerror); 449 } 450 else 451 g_value_set_uint (value, (gint) i); 452 } 453 else if (type == G_TYPE_INT64) 454 g_value_set_int64 (value, SQLITE3_CALL (sqlite3_column_int64) (ps->sqlite_stmt, real_col)); 455 else if (type == G_TYPE_UINT64) 456 g_value_set_uint64 (value, (guint64) SQLITE3_CALL (sqlite3_column_int64) (ps->sqlite_stmt, 457 real_col)); 458 else if (type == G_TYPE_DOUBLE) 459 g_value_set_double (value, SQLITE3_CALL (sqlite3_column_double) (ps->sqlite_stmt, 460 real_col)); 461 else if (type == G_TYPE_STRING) 462 g_value_set_string (value, (gchar *) SQLITE3_CALL (sqlite3_column_text) (ps->sqlite_stmt, 463 real_col)); 464 else if (type == GDA_TYPE_BINARY) { 465 GdaBinary *bin; 466 467 bin = g_new0 (GdaBinary, 1); 468 bin->binary_length = SQLITE3_CALL (sqlite3_column_bytes) (ps->sqlite_stmt, real_col); 469 if (bin->binary_length > 0) { 470 bin->data = g_new (guchar, bin->binary_length); 471 memcpy (bin->data, SQLITE3_CALL (sqlite3_column_blob) (ps->sqlite_stmt, /* Flawfinder: ignore */ 472 real_col), 473 bin->binary_length); 474 } 475 else 476 bin->binary_length = 0; 477 gda_value_take_binary (value, bin); 478 } 479 else if (type == GDA_TYPE_BLOB) { 480 GdaBlobOp *bop = NULL; 481 gint oidcol = 0; 482 483 if (ps->rowid_hash) { 484 const char *ctable; 485 ctable = SQLITE3_CALL (sqlite3_column_name) (ps->sqlite_stmt, real_col); 486 if (ctable) 487 oidcol = GPOINTER_TO_INT (g_hash_table_lookup (ps->rowid_hash, 488 ctable)); 489 if (oidcol == 0) { 490 ctable = SQLITE3_CALL (sqlite3_column_table_name) (ps->sqlite_stmt, real_col); 491 if (ctable) 492 oidcol = GPOINTER_TO_INT (g_hash_table_lookup (ps->rowid_hash, 493 ctable)); 494 } 495 } 496 if (oidcol != 0) { 497 gint64 rowid; 498 rowid = SQLITE3_CALL (sqlite3_column_int64) (ps->sqlite_stmt, oidcol - 1); /* remove 1 499 because it was added in the first place */ 500 bop = _gda_sqlite_blob_op_new (cdata, 501 SQLITE3_CALL (sqlite3_column_database_name) (ps->sqlite_stmt, 502 real_col), 503 SQLITE3_CALL (sqlite3_column_table_name) (ps->sqlite_stmt, 504 real_col), 505 SQLITE3_CALL (sqlite3_column_origin_name) (ps->sqlite_stmt, 506 real_col), 507 rowid); 508 } 509 if (!bop) { 510 GError *lerror = NULL; 511 g_set_error (&lerror, GDA_SERVER_PROVIDER_ERROR, 512 GDA_SERVER_PROVIDER_DATA_ERROR, 513 "%s", _("Unable to open BLOB")); 514 gda_row_invalidate_value_e (prow, value, lerror); 515 } 516 else { 517 GdaBlob *blob; 518 blob = g_new0 (GdaBlob, 1); 519 gda_blob_set_op (blob, bop); 520 g_object_unref (bop); 521 gda_value_take_blob (value, blob); 522 } 523 } 524 else if (type == G_TYPE_BOOLEAN) 525 g_value_set_boolean (value, SQLITE3_CALL (sqlite3_column_int) (ps->sqlite_stmt, real_col) == 0 ? FALSE : TRUE); 526 else if (type == G_TYPE_DATE) { 527 GDate date; 528 if (!gda_parse_iso8601_date (&date, 529 (gchar *) SQLITE3_CALL (sqlite3_column_text) (ps->sqlite_stmt, 530 real_col))) { 531 GError *lerror = NULL; 532 g_set_error (&lerror, GDA_SERVER_PROVIDER_ERROR, 533 GDA_SERVER_PROVIDER_DATA_ERROR, 534 _("Invalid date '%s' (date format should be YYYY-MM-DD)"), 535 (gchar *) SQLITE3_CALL (sqlite3_column_text) (ps->sqlite_stmt, real_col)); 536 gda_row_invalidate_value_e (prow, value, lerror); 537 } 538 else 539 g_value_set_boxed (value, &date); 540 } 541 else if (type == GDA_TYPE_TIME) { 542 GdaTime timegda; 543 if (!gda_parse_iso8601_time (&timegda, 544 (gchar *) SQLITE3_CALL (sqlite3_column_text) (ps->sqlite_stmt, 545 real_col))) { 546 GError *lerror = NULL; 547 g_set_error (&lerror, GDA_SERVER_PROVIDER_ERROR, 548 GDA_SERVER_PROVIDER_DATA_ERROR, 549 _("Invalid time '%s' (time format should be HH:MM:SS[.ms])"), 550 (gchar *) SQLITE3_CALL (sqlite3_column_text) (ps->sqlite_stmt, real_col)); 551 gda_row_invalidate_value_e (prow, value, lerror); 552 } 553 else { 554 if (timegda.timezone == GDA_TIMEZONE_INVALID) 555 timegda.timezone = 0; /* set to GMT */ 556 gda_value_set_time (value, &timegda); 557 } 558 } 559 else if (type == GDA_TYPE_TIMESTAMP) { 560 GdaTimestamp timestamp; 561 if (!gda_parse_iso8601_timestamp (×tamp, 562 (gchar *) SQLITE3_CALL (sqlite3_column_text) (ps->sqlite_stmt, 563 real_col))) { 564 GError *lerror = NULL; 565 g_set_error (&lerror, GDA_SERVER_PROVIDER_ERROR, 566 GDA_SERVER_PROVIDER_DATA_ERROR, 567 _("Invalid timestamp '%s' (format should be YYYY-MM-DD HH:MM:SS[.ms])"), 568 (gchar *) SQLITE3_CALL (sqlite3_column_text) (ps->sqlite_stmt, real_col)); 569 gda_row_invalidate_value_e (prow, value, lerror); 570 } 571 else { 572 if (timestamp.timezone == GDA_TIMEZONE_INVALID) 573 timestamp.timezone = 0; /* set to GMT */ 574 gda_value_set_timestamp (value, ×tamp); 575 } 576 } 577 else if (type == G_TYPE_CHAR) { 578 gint64 i; 579 i = (gint64) SQLITE3_CALL (sqlite3_column_int64) (ps->sqlite_stmt, real_col); 580 if ((i > G_MAXINT8) || (i < G_MININT8)) { 581 GError *lerror = NULL; 582 g_set_error (&lerror, GDA_SERVER_PROVIDER_ERROR, 583 GDA_SERVER_PROVIDER_DATA_ERROR, 584 "%s", _("Integer value is too big")); 585 gda_row_invalidate_value_e (prow, value, lerror); 586 } 587 else 588 g_value_set_schar (value, (gchar) i); 589 } 590 else if (type == G_TYPE_UCHAR) { 591 gint64 i; 592 i = (gint64) SQLITE3_CALL (sqlite3_column_int64) (ps->sqlite_stmt, real_col); 593 if ((i > G_MAXUINT8) || (i < 0)) { 594 GError *lerror = NULL; 595 g_set_error (&lerror, GDA_SERVER_PROVIDER_ERROR, 596 GDA_SERVER_PROVIDER_DATA_ERROR, 597 "%s", _("Integer value is too big")); 598 gda_row_invalidate_value_e (prow, value, lerror); 599 } 600 else 601 g_value_set_uchar (value, (guchar) i); 602 } 603 else if (type == GDA_TYPE_SHORT) { 604 gint64 i; 605 i = (gint64) SQLITE3_CALL (sqlite3_column_int64) (ps->sqlite_stmt, real_col); 606 if ((i > G_MAXSHORT) || (i < G_MINSHORT)) { 607 GError *lerror = NULL; 608 g_set_error (&lerror, GDA_SERVER_PROVIDER_ERROR, 609 GDA_SERVER_PROVIDER_DATA_ERROR, 610 "%s", _("Integer value is too big")); 611 gda_row_invalidate_value_e (prow, value, lerror); 612 } 613 else 614 gda_value_set_short (value, (guchar) i); 615 } 616 else if (type == GDA_TYPE_USHORT) { 617 gint64 i; 618 i = (gint64) SQLITE3_CALL (sqlite3_column_int64) (ps->sqlite_stmt, real_col); 619 if ((i > G_MAXUSHORT) || (i < 0)) { 620 GError *lerror = NULL; 621 g_set_error (&lerror, GDA_SERVER_PROVIDER_ERROR, 622 GDA_SERVER_PROVIDER_DATA_ERROR, 623 "%s", _("Integer value is too big")); 624 gda_row_invalidate_value_e (prow, value, lerror); 625 } 626 else 627 gda_value_set_ushort (value, (guchar) i); 628 } 629 else { 630 GError *lerror = NULL; 631 g_set_error (&lerror, GDA_SERVER_PROVIDER_ERROR, 632 GDA_SERVER_PROVIDER_DATA_ERROR, 633 "Unhandled type '%s' in SQLite recordset", 634 gda_g_type_to_string (_GDA_PSTMT (ps)->types [col])); 635 gda_row_invalidate_value_e (prow, value, lerror); 636 } 637 } 638 } 639 640 if (do_store) { 641 /* insert row */ 642 gda_data_select_take_row (GDA_DATA_SELECT (model), prow, model->priv->next_row_num); 643 } 644 model->priv->next_row_num ++; 645 break; 646 } 647 case SQLITE_BUSY: 648 /* nothing to do */ 649 break; 650 case SQLITE_DONE: 651 GDA_DATA_SELECT (model)->advertized_nrows = model->priv->next_row_num; 652 SQLITE3_CALL (sqlite3_reset) (ps->sqlite_stmt); 653 break; 654 case SQLITE_READONLY: 655 case SQLITE_MISUSE: 656 g_set_error (error, GDA_SERVER_PROVIDER_ERROR, 657 GDA_SERVER_PROVIDER_INTERNAL_ERROR, 658 "%s", _("SQLite provider fatal internal error")); 659 break; 660 case SQLITE_ERROR: 661 default: { 662 GError *lerror = NULL; 663 SQLITE3_CALL (sqlite3_reset) (ps->sqlite_stmt); 664 if (rc == SQLITE_IOERR_TRUNCATE) 665 g_set_error (&lerror, GDA_DATA_MODEL_ERROR, 666 GDA_DATA_MODEL_TRUNCATED_ERROR, "%s", _("Truncated data")); 667 else 668 g_set_error (&lerror, GDA_SERVER_PROVIDER_ERROR, 669 GDA_SERVER_PROVIDER_INTERNAL_ERROR, 670 "%s", SQLITE3_CALL (sqlite3_errmsg) (cdata->connection)); 671 gda_data_select_add_exception (GDA_DATA_SELECT (model), lerror); 672 if (rc == SQLITE_ERROR) 673 g_propagate_error (error, g_error_copy (lerror)); 674 GDA_DATA_SELECT (model)->advertized_nrows = model->priv->next_row_num; 675 break; 676 } 677 } 678 679 virt_cnc_set_working_obj (gda_data_select_get_connection ((GdaDataSelect*) model), NULL); 680 681 return prow; 682 } 683 684 685 /* 686 * GdaDataSelect virtual methods 687 */ 688 static gint 689 gda_sqlite_recordset_fetch_nb_rows (GdaDataSelect *model) 690 { 691 GdaSqliteRecordset *imodel; 692 GdaRow *prow = NULL; 693 694 imodel = GDA_SQLITE_RECORDSET (model); 695 if (model->advertized_nrows >= 0) 696 return model->advertized_nrows; 697 698 for (prow = fetch_next_sqlite_row (imodel, TRUE, NULL); 699 prow; 700 prow = fetch_next_sqlite_row (imodel, TRUE, NULL)); 701 return model->advertized_nrows; 702 } 703 704 /* 705 * Create a new filled #GdaRow object for the row at position @rownum. 706 * 707 * Each new #GdaRow created needs to be "given" to the #GdaDataSelect implementation using 708 * gda_data_select_take_row() because backward iterating is not supported. 709 */ 710 static gboolean 711 gda_sqlite_recordset_fetch_random (GdaDataSelect *model, GdaRow **prow, gint rownum, GError **error) 712 { 713 GdaSqliteRecordset *imodel; 714 715 imodel = GDA_SQLITE_RECORDSET (model); 716 if (imodel->priv->next_row_num >= rownum) { 717 g_set_error (error, GDA_SERVER_PROVIDER_ERROR, 718 GDA_SERVER_PROVIDER_INTERNAL_ERROR, 719 "%s", _("Requested row could not be found")); 720 return TRUE; 721 } 722 for (*prow = fetch_next_sqlite_row (imodel, TRUE, error); 723 *prow && (imodel->priv->next_row_num < rownum); 724 *prow = fetch_next_sqlite_row (imodel, TRUE, error)); 725 726 return TRUE; 727 } 728 729 /* 730 * Create a new filled #GdaRow object for the next cursor row 731 * 732 * Each new #GdaRow created is referenced only by imodel->priv->tmp_row (the #GdaDataSelect implementation 733 * never keeps a reference to it). 734 * Before a new #GdaRow gets created, the previous one, if set, is discarded. 735 */ 736 static gboolean 737 gda_sqlite_recordset_fetch_next (GdaDataSelect *model, GdaRow **prow, gint rownum, GError **error) 738 { 739 GdaSqliteRecordset *imodel = (GdaSqliteRecordset*) model; 740 741 if (imodel->priv->tmp_row) { 742 g_object_unref (imodel->priv->tmp_row); 743 imodel->priv->tmp_row = NULL; 744 } 745 if (imodel->priv->next_row_num != rownum) { 746 GError *lerror = NULL; 747 *prow = NULL; 748 g_set_error (&lerror, GDA_DATA_MODEL_ERROR, 749 GDA_DATA_MODEL_ROW_NOT_FOUND_ERROR, 750 "%s", _("Can't set iterator on requested row")); 751 gda_data_select_add_exception (GDA_DATA_SELECT (model), lerror); 752 if (error) 753 g_propagate_error (error, g_error_copy (lerror)); 754 return TRUE; 755 } 756 *prow = fetch_next_sqlite_row (imodel, FALSE, error); 757 imodel->priv->tmp_row = *prow; 758 759 return TRUE; 760 } 761