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
gda_sqlite_recordset_init(GdaSqliteRecordset * recset,G_GNUC_UNUSED GdaSqliteRecordsetClass * klass)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
gda_sqlite_recordset_class_init(GdaSqliteRecordsetClass * klass)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
gda_sqlite_recordset_dispose(GObject * object)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
_gda_sqlite_recordset_get_type(void)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
read_rows_to_init_col_types(GdaSqliteRecordset * model)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 *
_gda_sqlite_recordset_new(GdaConnection * cnc,GdaSqlitePStmt * ps,GdaSet * exec_params,GdaDataModelAccessFlags flags,GType * col_types,gboolean force_empty)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
fuzzy_get_gtype(SqliteConnectionData * cdata,GdaSqlitePStmt * ps,gint colnum)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
virt_cnc_set_working_obj(GdaConnection * cnc,GdaSqliteRecordset * model)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 *
fetch_next_sqlite_row(GdaSqliteRecordset * model,gboolean do_store,GError ** error)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
gda_sqlite_recordset_fetch_nb_rows(GdaDataSelect * model)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
gda_sqlite_recordset_fetch_random(GdaDataSelect * model,GdaRow ** prow,gint rownum,GError ** error)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
gda_sqlite_recordset_fetch_next(GdaDataSelect * model,GdaRow ** prow,gint rownum,GError ** error)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