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 (&registering);
151 		if (type == 0)
152 			type = g_type_register_static (GDA_TYPE_DATA_SELECT, CLASS_PREFIX "Recordset", &info, 0);
153 		g_mutex_unlock (&registering);
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 (&timestamp,
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, &timestamp);
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