static GType fuzzy_get_gtype (SqliteConnectionData *cdata, GdaSqlitePStmt *ps, gint colnum) { const gchar *ctype; GType gtype = GDA_TYPE_NULL; gint real_col = colnum + ps->nb_rowid_columns; if (_GDA_PSTMT (ps)->types [colnum] != GDA_TYPE_NULL) return _GDA_PSTMT (ps)->types [colnum]; ctype = SQLITE3_CALL (sqlite3_column_origin_name) (ps->sqlite_stmt, real_col); if (ctype && !strcmp (ctype, "rowid")) gtype = G_TYPE_INT64; else { ctype = SQLITE3_CALL (sqlite3_column_decltype) (ps->sqlite_stmt, real_col); if (ctype) { GType *pg; pg = g_hash_table_lookup (cdata->types_hash, ctype); gtype = pg ? *pg : GDA_TYPE_NULL; } if (gtype == GDA_TYPE_NULL) gtype = _gda_sqlite_compute_g_type (SQLITE3_CALL (sqlite3_column_type) (ps->sqlite_stmt, real_col)); } return gtype; }
/* * Blob read request */ static glong gda_sqlite_blob_op_read (GdaBlobOp *op, GdaBlob *blob, glong offset, glong size) { GdaSqliteBlobOp *bop; GdaBinary *bin; gpointer buffer = NULL; int rc; g_return_val_if_fail (GDA_IS_SQLITE_BLOB_OP (op), -1); bop = GDA_SQLITE_BLOB_OP (op); GdaSqliteBlobOpPrivate *priv = gda_sqlite_blob_op_get_instance_private (bop); g_return_val_if_fail (priv->sblob, -1); if (offset >= G_MAXINT) return -1; g_return_val_if_fail (blob, -1); if (offset > G_MAXINT) return -1; if (size > G_MAXINT) return -1; GdaSqliteProvider *prov = g_weak_ref_get (&priv->provider); g_return_val_if_fail (prov != NULL, -1); bin = gda_blob_get_binary (blob); gda_binary_set_data (bin, (guchar*) "", 0); /* fetch blob data using C API into bin->data, and set bin->binary_length */ int rsize; int len; len = SQLITE3_CALL (prov, sqlite3_blob_bytes) (priv->sblob); if (len < 0){ g_object_unref (prov); return -1; } else if (len == 0) { g_object_unref (prov); return 0; } rsize = (int) size; if (offset >= len) { g_object_unref (prov); return -1; } if (len - offset < rsize) rsize = len - offset; rc = SQLITE3_CALL (prov, sqlite3_blob_read) (priv->sblob, buffer, rsize, offset); if (rc != SQLITE_OK) { gda_binary_reset_data (bin); g_object_unref (prov); return -1; } gda_binary_set_data (bin, buffer, rsize); g_object_unref (prov); return gda_binary_get_size (bin); }
/* * Get length request */ static glong gda_sqlite_blob_op_get_length (GdaBlobOp *op) { GdaSqliteBlobOp *bop; int len; g_return_val_if_fail (GDA_IS_SQLITE_BLOB_OP (op), -1); bop = GDA_SQLITE_BLOB_OP (op); GdaSqliteBlobOpPrivate *priv = gda_sqlite_blob_op_get_instance_private (bop); g_return_val_if_fail (priv->sblob, -1); GdaSqliteProvider *prov = g_weak_ref_get (&priv->provider); g_return_val_if_fail (prov != NULL, -1); len = SQLITE3_CALL (prov, sqlite3_blob_bytes) (priv->sblob); g_object_unref (prov); return len >= 0 ? len : 0; }
static void gda_sqlite_recordset_dispose (GObject *object) { GdaSqliteRecordset *recset = (GdaSqliteRecordset *) object; g_return_if_fail (GDA_IS_SQLITE_RECORDSET (recset)); if (recset->priv) { GdaSqlitePStmt *ps; ps = GDA_SQLITE_PSTMT (GDA_DATA_SELECT (object)->prep_stmt); ps->stmt_used = FALSE; virt_cnc_set_working_obj (gda_data_select_get_connection ((GdaDataSelect*) recset), recset); SQLITE3_CALL (sqlite3_reset) (ps->sqlite_stmt); virt_cnc_set_working_obj (gda_data_select_get_connection ((GdaDataSelect*) recset), NULL); if (recset->priv->tmp_row) g_object_unref (recset->priv->tmp_row); g_free (recset->priv); recset->priv = NULL; } parent_class->dispose (object); }
static void gda_sqlite_blob_op_finalize (GObject * object) { GdaSqliteBlobOp *bop = (GdaSqliteBlobOp *) object; g_return_if_fail (GDA_IS_SQLITE_BLOB_OP (bop)); GdaSqliteBlobOpPrivate *priv = gda_sqlite_blob_op_get_instance_private (bop); /* free specific information */ if (priv->sblob) { GdaSqliteProvider *prov = g_weak_ref_get (&priv->provider); if (prov != NULL) { SQLITE3_CALL (prov, sqlite3_blob_close) (priv->sblob); g_object_unref (prov); } #ifdef GDA_DEBUG_NO g_print ("CLOSED blob %p\n", bop); #endif } g_weak_ref_clear (&priv->provider); G_OBJECT_CLASS (gda_sqlite_blob_op_parent_class)->finalize (object); }
static GdaRow * fetch_next_sqlite_row (GdaSqliteRecordset *model, gboolean do_store, GError **error) { int rc; SqliteConnectionData *cdata; GdaSqlitePStmt *ps; GdaRow *prow = NULL; GdaConnection *cnc; glong length; cnc = gda_data_select_get_connection ((GdaDataSelect*) model); cdata = (SqliteConnectionData*) gda_connection_internal_get_provider_data_error (cnc, error); if (!cdata) return NULL; ps = GDA_SQLITE_PSTMT (GDA_DATA_SELECT (model)->prep_stmt); virt_cnc_set_working_obj (gda_data_select_get_connection ((GdaDataSelect*) model), model); if (model->priv->empty_forced) rc = SQLITE_DONE; else rc = SQLITE3_CALL (sqlite3_step) (ps->sqlite_stmt); switch (rc) { case SQLITE_ROW: { gint col, real_col; prow = gda_row_new (_GDA_PSTMT (ps)->ncols); for (col = 0; col < _GDA_PSTMT (ps)->ncols; col++) { GValue *value; GType type = _GDA_PSTMT (ps)->types [col]; real_col = col + ps->nb_rowid_columns; if (type == GDA_TYPE_NULL) { type = fuzzy_get_gtype (cdata, ps, col); if (type == GDA_TYPE_BLOB) { /* extra check: make sure we have a rowid for this blob, or fallback to binary */ if (ps->rowid_hash) { gint oidcol = 0; const char *ctable; ctable = SQLITE3_CALL (sqlite3_column_name) (ps->sqlite_stmt, real_col); if (ctable) oidcol = GPOINTER_TO_INT (g_hash_table_lookup (ps->rowid_hash, ctable)); if (oidcol == 0) { ctable = SQLITE3_CALL (sqlite3_column_table_name) (ps->sqlite_stmt, real_col); if (ctable) oidcol = GPOINTER_TO_INT (g_hash_table_lookup (ps->rowid_hash, ctable)); } if (oidcol == 0) type = GDA_TYPE_BINARY; } else type = GDA_TYPE_BINARY; } if (type != GDA_TYPE_NULL) { GdaColumn *column; _GDA_PSTMT (ps)->types [col] = type; column = gda_data_model_describe_column (GDA_DATA_MODEL (model), col); gda_column_set_g_type (column, type); column = (GdaColumn *) g_slist_nth_data (_GDA_PSTMT (ps)->tmpl_columns, col); gda_column_set_g_type (column, type); } } /* fill GValue */ value = gda_row_get_value (prow, col); GError *may_error; may_error = (GError*) SQLITE3_CALL (sqlite3_column_blob) (ps->sqlite_stmt, real_col); if (may_error && g_hash_table_lookup (error_blobs_hash, may_error)) { /*g_print ("Row invalidated: [%s]\n", may_error->message);*/ gda_row_invalidate_value_e (prow, value, may_error); g_hash_table_remove (error_blobs_hash, may_error); } else if (SQLITE3_CALL (sqlite3_column_text) (ps->sqlite_stmt, real_col) == NULL) { /* we have a NULL value */ gda_value_set_null (value); } else { gda_value_reset_with_type (value, type); if (type == GDA_TYPE_NULL) ; else if (type == G_TYPE_INT) { gint64 i; i = SQLITE3_CALL (sqlite3_column_int64) (ps->sqlite_stmt, real_col); if ((i > G_MAXINT) || (i < G_MININT)) { GError *lerror = NULL; g_set_error (&lerror, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_DATA_ERROR, "%s", _("Integer value is too big")); gda_row_invalidate_value_e (prow, value, lerror); } else g_value_set_int (value, (gint) i); } else if (type == G_TYPE_UINT) { guint64 i; i = (gint64) SQLITE3_CALL (sqlite3_column_int64) (ps->sqlite_stmt, real_col); if (i > G_MAXUINT) { GError *lerror = NULL; g_set_error (&lerror, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_DATA_ERROR, "%s", _("Integer value is too big")); gda_row_invalidate_value_e (prow, value, lerror); } else g_value_set_uint (value, (gint) i); } else if (type == G_TYPE_INT64) g_value_set_int64 (value, SQLITE3_CALL (sqlite3_column_int64) (ps->sqlite_stmt, real_col)); else if (type == G_TYPE_UINT64) g_value_set_uint64 (value, (guint64) SQLITE3_CALL (sqlite3_column_int64) (ps->sqlite_stmt, real_col)); else if (type == G_TYPE_DOUBLE) g_value_set_double (value, SQLITE3_CALL (sqlite3_column_double) (ps->sqlite_stmt, real_col)); else if (type == G_TYPE_STRING) g_value_set_string (value, (gchar *) SQLITE3_CALL (sqlite3_column_text) (ps->sqlite_stmt, real_col)); else if (type == GDA_TYPE_BINARY) { GdaBinary *bin; bin = gda_binary_new (); length = SQLITE3_CALL (sqlite3_column_bytes) (ps->sqlite_stmt, real_col); if (length > 0) { gda_binary_set_data (bin, SQLITE3_CALL (sqlite3_column_blob) (ps->sqlite_stmt, /* Flawfinder: ignore */ real_col), length); } gda_value_take_binary (value, bin); } else if (type == GDA_TYPE_BLOB) { GdaBlobOp *bop = NULL; gint oidcol = 0; if (ps->rowid_hash) { const char *ctable; ctable = SQLITE3_CALL (sqlite3_column_name) (ps->sqlite_stmt, real_col); if (ctable) oidcol = GPOINTER_TO_INT (g_hash_table_lookup (ps->rowid_hash, ctable)); if (oidcol == 0) { ctable = SQLITE3_CALL (sqlite3_column_table_name) (ps->sqlite_stmt, real_col); if (ctable) oidcol = GPOINTER_TO_INT (g_hash_table_lookup (ps->rowid_hash, ctable)); } } if (oidcol != 0) { gint64 rowid; rowid = SQLITE3_CALL (sqlite3_column_int64) (ps->sqlite_stmt, oidcol - 1); /* remove 1 because it was added in the first place */ bop = _gda_sqlite_blob_op_new (cnc, SQLITE3_CALL (sqlite3_column_database_name) (ps->sqlite_stmt, real_col), SQLITE3_CALL (sqlite3_column_table_name) (ps->sqlite_stmt, real_col), SQLITE3_CALL (sqlite3_column_origin_name) (ps->sqlite_stmt, real_col), rowid); } if (!bop) { GError *lerror = NULL; g_set_error (&lerror, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_DATA_ERROR, "%s", _("Unable to open BLOB")); gda_row_invalidate_value_e (prow, value, lerror); } else { GdaBlob *blob; blob = gda_blob_new (); gda_blob_set_op (blob, bop); g_object_unref (bop); gda_value_take_blob (value, blob); } } else if (type == G_TYPE_BOOLEAN) g_value_set_boolean (value, SQLITE3_CALL (sqlite3_column_int) (ps->sqlite_stmt, real_col) == 0 ? FALSE : TRUE); else if (type == G_TYPE_DATE) { GDate date; if (!gda_parse_iso8601_date (&date, (gchar *) SQLITE3_CALL (sqlite3_column_text) (ps->sqlite_stmt, real_col))) { GError *lerror = NULL; g_set_error (&lerror, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_DATA_ERROR, _("Invalid date '%s' (date format should be YYYY-MM-DD)"), (gchar *) SQLITE3_CALL (sqlite3_column_text) (ps->sqlite_stmt, real_col)); gda_row_invalidate_value_e (prow, value, lerror); } else g_value_set_boxed (value, &date); } else if (type == GDA_TYPE_TIME) { GdaTime timegda; if (!gda_parse_iso8601_time (&timegda, (gchar *) SQLITE3_CALL (sqlite3_column_text) (ps->sqlite_stmt, real_col))) { GError *lerror = NULL; g_set_error (&lerror, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_DATA_ERROR, _("Invalid time '%s' (time format should be HH:MM:SS[.ms])"), (gchar *) SQLITE3_CALL (sqlite3_column_text) (ps->sqlite_stmt, real_col)); gda_row_invalidate_value_e (prow, value, lerror); } else { if (timegda.timezone == GDA_TIMEZONE_INVALID) timegda.timezone = 0; /* set to GMT */ gda_value_set_time (value, &timegda); } } else if (type == GDA_TYPE_TIMESTAMP) { GdaTimestamp timestamp; if (!gda_parse_iso8601_timestamp (×tamp, (gchar *) SQLITE3_CALL (sqlite3_column_text) (ps->sqlite_stmt, real_col))) { GError *lerror = NULL; g_set_error (&lerror, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_DATA_ERROR, _("Invalid timestamp '%s' (format should be YYYY-MM-DD HH:MM:SS[.ms])"), (gchar *) SQLITE3_CALL (sqlite3_column_text) (ps->sqlite_stmt, real_col)); gda_row_invalidate_value_e (prow, value, lerror); } else { if (timestamp.timezone == GDA_TIMEZONE_INVALID) timestamp.timezone = 0; /* set to GMT */ gda_value_set_timestamp (value, ×tamp); } } else if (type == G_TYPE_CHAR) { gint64 i; i = (gint64) SQLITE3_CALL (sqlite3_column_int64) (ps->sqlite_stmt, real_col); if ((i > G_MAXINT8) || (i < G_MININT8)) { GError *lerror = NULL; g_set_error (&lerror, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_DATA_ERROR, "%s", _("Integer value is too big")); gda_row_invalidate_value_e (prow, value, lerror); } else g_value_set_schar (value, (gchar) i); } else if (type == G_TYPE_UCHAR) { gint64 i; i = (gint64) SQLITE3_CALL (sqlite3_column_int64) (ps->sqlite_stmt, real_col); if ((i > G_MAXUINT8) || (i < 0)) { GError *lerror = NULL; g_set_error (&lerror, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_DATA_ERROR, "%s", _("Integer value is too big")); gda_row_invalidate_value_e (prow, value, lerror); } else g_value_set_uchar (value, (guchar) i); } else if (type == GDA_TYPE_SHORT) { gint64 i; i = (gint64) SQLITE3_CALL (sqlite3_column_int64) (ps->sqlite_stmt, real_col); if ((i > G_MAXSHORT) || (i < G_MINSHORT)) { GError *lerror = NULL; g_set_error (&lerror, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_DATA_ERROR, "%s", _("Integer value is too big")); gda_row_invalidate_value_e (prow, value, lerror); } else gda_value_set_short (value, (guchar) i); } else if (type == GDA_TYPE_USHORT) { gint64 i; i = (gint64) SQLITE3_CALL (sqlite3_column_int64) (ps->sqlite_stmt, real_col); if ((i > G_MAXUSHORT) || (i < 0)) { GError *lerror = NULL; g_set_error (&lerror, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_DATA_ERROR, "%s", _("Integer value is too big")); gda_row_invalidate_value_e (prow, value, lerror); } else gda_value_set_ushort (value, (guchar) i); } else { GError *lerror = NULL; g_set_error (&lerror, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_DATA_ERROR, "Unhandled type '%s' in SQLite recordset", gda_g_type_to_string (_GDA_PSTMT (ps)->types [col])); gda_row_invalidate_value_e (prow, value, lerror); } } } if (do_store) { /* insert row */ gda_data_select_take_row (GDA_DATA_SELECT (model), prow, model->priv->next_row_num); } model->priv->next_row_num ++; break; } case SQLITE_BUSY: /* nothing to do */ break; case SQLITE_DONE: GDA_DATA_SELECT (model)->advertized_nrows = model->priv->next_row_num; SQLITE3_CALL (sqlite3_reset) (ps->sqlite_stmt); break; case SQLITE_READONLY: case SQLITE_MISUSE: g_set_error (error, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_INTERNAL_ERROR, "%s", _("SQLite provider fatal internal error")); break; case SQLITE_ERROR: default: { GError *lerror = NULL; SQLITE3_CALL (sqlite3_reset) (ps->sqlite_stmt); if (rc == SQLITE_IOERR_TRUNCATE) g_set_error (&lerror, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_TRUNCATED_ERROR, "%s", _("Truncated data")); else g_set_error (&lerror, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_INTERNAL_ERROR, "%s", SQLITE3_CALL (sqlite3_errmsg) (cdata->connection)); gda_data_select_add_exception (GDA_DATA_SELECT (model), lerror); if (rc == SQLITE_ERROR) g_propagate_error (error, g_error_copy (lerror)); GDA_DATA_SELECT (model)->advertized_nrows = model->priv->next_row_num; break; } } virt_cnc_set_working_obj (gda_data_select_get_connection ((GdaDataSelect*) model), NULL); return prow; }
/* * the @ps struct is modified and transferred to the new data model created in * this function */ GdaDataModel * _gda_sqlite_recordset_new (GdaConnection *cnc, GdaSqlitePStmt *ps, GdaSet *exec_params, GdaDataModelAccessFlags flags, GType *col_types, gboolean force_empty) { GdaSqliteRecordset *model; SqliteConnectionData *cdata; gint i; GdaDataModelAccessFlags rflags; g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL); g_return_val_if_fail (ps != NULL, NULL); cdata = (SqliteConnectionData*) gda_connection_internal_get_provider_data_error (cnc, NULL); if (!cdata) return NULL; if (!cdata->types_hash) _gda_sqlite_compute_types_hash (cdata); /* make sure @ps reports the correct number of columns */ if (_GDA_PSTMT (ps)->ncols < 0) _GDA_PSTMT (ps)->ncols = SQLITE3_CALL (sqlite3_column_count) (ps->sqlite_stmt) - ps->nb_rowid_columns; /* completing ps */ g_assert (! ps->stmt_used); ps->stmt_used = TRUE; if (!_GDA_PSTMT (ps)->types && (_GDA_PSTMT (ps)->ncols > 0)) { /* create prepared statement's columns */ GSList *list; for (i = 0; i < _GDA_PSTMT (ps)->ncols; i++) _GDA_PSTMT (ps)->tmpl_columns = g_slist_prepend (_GDA_PSTMT (ps)->tmpl_columns, gda_column_new ()); _GDA_PSTMT (ps)->tmpl_columns = g_slist_reverse (_GDA_PSTMT (ps)->tmpl_columns); /* create prepared statement's types, all types are initialized to GDA_TYPE_NULL */ _GDA_PSTMT (ps)->types = g_new (GType, _GDA_PSTMT (ps)->ncols); for (i = 0; i < _GDA_PSTMT (ps)->ncols; i++) _GDA_PSTMT (ps)->types [i] = GDA_TYPE_NULL; if (col_types) { for (i = 0; ; i++) { if (col_types [i] > 0) { if (col_types [i] == G_TYPE_NONE) break; if (i >= _GDA_PSTMT (ps)->ncols) g_warning (_("Column %d out of range (0-%d), ignoring its specified type"), i, _GDA_PSTMT (ps)->ncols - 1); else _GDA_PSTMT (ps)->types [i] = col_types [i]; } } } /* fill GdaColumn's data */ for (i=0, list = _GDA_PSTMT (ps)->tmpl_columns; i < GDA_PSTMT (ps)->ncols; i++, list = list->next) { GdaColumn *column; gint real_col = i + ps->nb_rowid_columns; column = GDA_COLUMN (list->data); gda_column_set_description (column, SQLITE3_CALL (sqlite3_column_name) (ps->sqlite_stmt, real_col)); gda_column_set_name (column, SQLITE3_CALL (sqlite3_column_name) (ps->sqlite_stmt, real_col)); gda_column_set_dbms_type (column, SQLITE3_CALL (sqlite3_column_decltype) (ps->sqlite_stmt, real_col)); if (_GDA_PSTMT (ps)->types [i] != GDA_TYPE_NULL) gda_column_set_g_type (column, _GDA_PSTMT (ps)->types [i]); } } /* determine access mode: RANDOM or CURSOR FORWARD are the only supported; if CURSOR BACKWARD * is requested, then we need RANDOM mode */ if (flags & GDA_DATA_MODEL_ACCESS_RANDOM) rflags = GDA_DATA_MODEL_ACCESS_RANDOM; else if (flags & GDA_DATA_MODEL_ACCESS_CURSOR_BACKWARD) rflags = GDA_DATA_MODEL_ACCESS_RANDOM; else rflags = GDA_DATA_MODEL_ACCESS_CURSOR_FORWARD; /* create data model */ model = g_object_new (GDA_TYPE_SQLITE_RECORDSET, "connection", cnc, "prepared-stmt", ps, "model-usage", rflags, "exec-params", exec_params, "auto-reset", force_empty, NULL); gboolean is_virt; is_virt = GDA_IS_VCONNECTION_DATA_MODEL (cnc) ? TRUE : FALSE; if (is_virt) { /* steal the lock */ _gda_vconnection_change_working_obj ((GdaVconnectionDataModel*) cnc, (GObject*) model); _gda_vconnection_set_working_obj ((GdaVconnectionDataModel*) cnc, NULL); } /* fill the data model */ read_rows_to_init_col_types (model); return GDA_DATA_MODEL (model); }
GdaBlobOp * _gda_sqlite_blob_op_new (GdaConnection *cnc, const gchar *db_name, const gchar *table_name, const gchar *column_name, sqlite3_int64 rowid) { GdaSqliteBlobOp *bop = NULL; int rc; sqlite3_blob *sblob; gchar *db, *table; gboolean free_strings = TRUE; gboolean transaction_started = FALSE; g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL); g_return_val_if_fail (table_name, NULL); g_return_val_if_fail (column_name, NULL); g_return_val_if_fail (GDA_IS_SQLITE_PROVIDER (gda_connection_get_provider (cnc)), NULL); GdaSqliteBlobOpPrivate *priv = gda_sqlite_blob_op_get_instance_private (bop); if (db_name) { db = (gchar *) db_name; table = (gchar *) table_name; free_strings = FALSE; } else if (! _split_identifier_string (g_strdup (table_name), &db, &table)) return NULL; SqliteConnectionData *cdata; cdata = (SqliteConnectionData*) gda_connection_internal_get_provider_data_error (cnc, NULL); if (!cdata || ! _gda_sqlite_check_transaction_started (cnc, &transaction_started, NULL)) return NULL; GdaSqliteProvider *prov = GDA_SQLITE_PROVIDER (gda_connection_get_provider (cnc)); rc = SQLITE3_CALL (prov, sqlite3_blob_open) (cdata->connection, db ? db : "main", table, column_name, rowid, 1, /* Read & Write */ &(sblob)); if (rc != SQLITE_OK) { #ifdef GDA_DEBUG_NO g_print ("ERROR: %s\n", SQLITE3_CALL (prov, sqlite3_errmsg) (cdata->connection)); #endif if (transaction_started) gda_connection_rollback_transaction (cnc, NULL, NULL); goto out; } bop = g_object_new (GDA_TYPE_SQLITE_BLOB_OP, "connection", cnc, NULL); priv->sblob = sblob; g_weak_ref_set (&priv->provider, prov); #ifdef GDA_DEBUG_NO g_print ("OPENED blob %p\n", bop); #endif out: if (free_strings) { g_free (db); g_free (table); } return (GdaBlobOp*) bop; }
/* * Blob write request */ static glong gda_sqlite_blob_op_write (GdaBlobOp *op, GdaBlob *blob, glong offset) { GdaSqliteBlobOp *bop; GdaBinary *bin; glong nbwritten = -1; int len; g_return_val_if_fail (GDA_IS_SQLITE_BLOB_OP (op), -1); bop = GDA_SQLITE_BLOB_OP (op); GdaSqliteBlobOpPrivate *priv = gda_sqlite_blob_op_get_instance_private (bop); g_return_val_if_fail (priv->sblob, -1); g_return_val_if_fail (blob, -1); GdaSqliteProvider *prov = g_weak_ref_get (&priv->provider); g_return_val_if_fail (prov != NULL, -1); len = SQLITE3_CALL (prov, sqlite3_blob_bytes) (priv->sblob); if (len < 0) { g_object_unref (prov); return -1; } if (gda_blob_get_op (blob) && (gda_blob_get_op (blob) != op)) { /* use data through blob->op */ #define buf_size 16384 gint nread = 0; GdaBlob *tmpblob = gda_blob_new (); gda_blob_set_op (tmpblob, gda_blob_get_op (blob)); nbwritten = 0; for (nread = gda_blob_op_read (gda_blob_get_op (tmpblob), tmpblob, nbwritten, buf_size); nread > 0; nread = gda_blob_op_read (gda_blob_get_op (tmpblob), tmpblob, nbwritten, buf_size)) { int tmp_written; int rc; int wlen; if (nread + offset + nbwritten > len) wlen = len - offset - nbwritten; else wlen = nread; rc = SQLITE3_CALL (prov, sqlite3_blob_write) (priv->sblob, gda_binary_get_data (gda_blob_get_binary (tmpblob)), wlen, offset + nbwritten); if (rc != SQLITE_OK) tmp_written = -1; else tmp_written = wlen; if (tmp_written < 0) { /* treat error */ gda_blob_free ((gpointer) tmpblob); g_object_unref (prov); return -1; } nbwritten += tmp_written; if (nread < buf_size) /* nothing more to read */ break; } gda_blob_free ((gpointer) tmpblob); } else { /* write blob using bin->data and bin->binary_length */ int rc; int wlen; bin = gda_blob_get_binary (blob); if (gda_binary_get_size (bin) + offset > len) wlen = len - offset; else wlen = gda_binary_get_size (bin); rc = SQLITE3_CALL (prov, sqlite3_blob_write) (priv->sblob, gda_binary_get_data (bin), wlen, offset); if (rc != SQLITE_OK) nbwritten = -1; else nbwritten = wlen; } g_object_unref (prov); return nbwritten; }