[libgda] sqlite: add mechanism to use a different library



commit 6d23910c2cc1863e6e4364e563ba5dcc6c27bd08
Author: Daniel Espinosa Ortiz <esodan gmail com>
Date:   Wed Mar 6 15:03:37 2019 -0600

    sqlite: add mechanism to use a different library
    
    Added API to use a SQLite provider with a different
    library, like SQLCipher, so is possible to derivate
    GdaSqliteProvider to implement new providers using
    different providers.
    
    This operation requires to limitate GDA's extension
    functions to SQLite SQL engine to use the default
    internal one. Derived providers will require to
    implement their own extensions.

 libgda/sqlite/gda-sqlite-blob-op.c                 |  64 ++-
 libgda/sqlite/gda-sqlite-meta.c                    |  42 +-
 libgda/sqlite/gda-sqlite-provider.c                | 436 ++++++++++++---------
 libgda/sqlite/gda-sqlite-provider.h                |   4 +
 libgda/sqlite/gda-sqlite-pstmt.c                   |   7 +-
 libgda/sqlite/gda-sqlite-recordset.c               |  99 +++--
 libgda/sqlite/gda-sqlite.h                         |  22 +-
 libgda/sqlite/gda-symbols-util.c                   | 160 ++++----
 libgda/sqlite/gda-symbols-util.h                   |   3 +-
 libgda/sqlite/virtual/gda-vconnection-data-model.c |  10 +-
 libgda/sqlite/virtual/gda-vprovider-data-model.c   | 134 ++++---
 11 files changed, 557 insertions(+), 424 deletions(-)
---
diff --git a/libgda/sqlite/gda-sqlite-blob-op.c b/libgda/sqlite/gda-sqlite-blob-op.c
index 60023b6f7..781eff5e9 100644
--- a/libgda/sqlite/gda-sqlite-blob-op.c
+++ b/libgda/sqlite/gda-sqlite-blob-op.c
@@ -28,6 +28,7 @@
 #include <sql-parser/gda-sql-parser.h>
 
 struct _GdaSqliteBlobOpPrivate {
+       GWeakRef      provider;
        sqlite3_blob  *sblob;
 };
 
@@ -79,6 +80,7 @@ gda_sqlite_blob_op_init (GdaSqliteBlobOp *op, G_GNUC_UNUSED GdaSqliteBlobOpClass
 
        op->priv = g_new0 (GdaSqliteBlobOpPrivate, 1);
        op->priv->sblob = NULL;
+       g_weak_ref_init (&op->priv->provider, NULL);
 }
 
 static void
@@ -104,11 +106,16 @@ gda_sqlite_blob_op_finalize (GObject * object)
 
        /* free specific information */
        if (bop->priv->sblob) {
-               SQLITE3_CALL (sqlite3_blob_close) (bop->priv->sblob);
+               GdaSqliteProvider *prov = g_weak_ref_get (&bop->priv->provider);
+               if (prov != NULL) {
+                       SQLITE3_CALL (prov, sqlite3_blob_close) (bop->priv->sblob);
+                       g_object_unref (prov);
+               }
 #ifdef GDA_DEBUG_NO
                g_print ("CLOSED blob %p\n", bop);
 #endif
        }
+       g_weak_ref_clear (&bop->priv->provider);
        g_free (bop->priv);
        bop->priv = NULL;
 
@@ -130,6 +137,7 @@ _gda_sqlite_blob_op_new (GdaConnection *cnc,
        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);
 
        if (db_name) {
                db = (gchar *) db_name;
@@ -145,13 +153,16 @@ _gda_sqlite_blob_op_new (GdaConnection *cnc,
            ! _gda_sqlite_check_transaction_started (cnc, &transaction_started, NULL))
                return NULL;
 
-       rc = SQLITE3_CALL (sqlite3_blob_open) (cdata->connection, db ? db : "main",
-                                              table, column_name, rowid,
-                               1, /* Read & Write */
-                               &(sblob));
+       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 (sqlite3_errmsg) (cdata->connection));
+               g_print ("ERROR: %s\n", SQLITE3_CALL (prov, sqlite3_errmsg) (cdata->connection));
 #endif
                if (transaction_started)
                        gda_connection_rollback_transaction (cnc, NULL, NULL);
@@ -160,6 +171,7 @@ _gda_sqlite_blob_op_new (GdaConnection *cnc,
 
        bop = g_object_new (GDA_TYPE_SQLITE_BLOB_OP, "connection", cnc, NULL);
        bop->priv->sblob = sblob;
+       g_weak_ref_set (&bop->priv->provider, prov);
 #ifdef GDA_DEBUG_NO
        g_print ("OPENED blob %p\n", bop);
 #endif
@@ -185,8 +197,11 @@ gda_sqlite_blob_op_get_length (GdaBlobOp *op)
        bop = GDA_SQLITE_BLOB_OP (op);
        g_return_val_if_fail (bop->priv, -1);
        g_return_val_if_fail (bop->priv->sblob, -1);
+       GdaSqliteProvider *prov = g_weak_ref_get (&bop->priv->provider);
+       g_return_val_if_fail (prov != NULL, -1);
 
-       len = SQLITE3_CALL (sqlite3_blob_bytes) (bop->priv->sblob);
+       len = SQLITE3_CALL (prov, sqlite3_blob_bytes) (bop->priv->sblob);
+       g_object_unref (prov);
        return len >= 0 ? len : 0;
 }
 
@@ -214,6 +229,9 @@ gda_sqlite_blob_op_read (GdaBlobOp *op, GdaBlob *blob, glong offset, glong size)
        if (size > G_MAXINT)
                return -1;
 
+       GdaSqliteProvider *prov = g_weak_ref_get (&bop->priv->provider);
+       g_return_val_if_fail (prov != NULL, -1);
+
        bin = gda_blob_get_binary (blob);
        gda_binary_set_data (bin, (guchar*) "", 0);
 
@@ -221,25 +239,32 @@ gda_sqlite_blob_op_read (GdaBlobOp *op, GdaBlob *blob, glong offset, glong size)
        int rsize;
        int len;
 
-       len = SQLITE3_CALL (sqlite3_blob_bytes) (bop->priv->sblob);
-       if (len < 0)
+       len = SQLITE3_CALL (prov, sqlite3_blob_bytes) (bop->priv->sblob);
+       if (len < 0){
+               g_object_unref (prov);
                return -1;
-       else if (len == 0)
+       } else if (len == 0) {
+               g_object_unref (prov);
                return 0;
+       }
                
        rsize = (int) size;
-       if (offset >= len)
+       if (offset >= len) {
+               g_object_unref (prov);
                return -1;
+       }
 
        if (len - offset < rsize)
                rsize = len - offset;
   
-       rc = SQLITE3_CALL (sqlite3_blob_read) (bop->priv->sblob, buffer, rsize, offset);
+       rc = SQLITE3_CALL (prov, sqlite3_blob_read) (bop->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);
 }
@@ -261,9 +286,14 @@ gda_sqlite_blob_op_write (GdaBlobOp *op, GdaBlob *blob, glong offset)
        g_return_val_if_fail (bop->priv->sblob, -1);
        g_return_val_if_fail (blob, -1);
 
-       len = SQLITE3_CALL (sqlite3_blob_bytes) (bop->priv->sblob);
-       if (len < 0)
+       GdaSqliteProvider *prov = g_weak_ref_get (&bop->priv->provider);
+       g_return_val_if_fail (prov != NULL, -1);
+
+       len = SQLITE3_CALL (prov, sqlite3_blob_bytes) (bop->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 */
@@ -286,7 +316,7 @@ gda_sqlite_blob_op_write (GdaBlobOp *op, GdaBlob *blob, glong offset)
                        else
                                wlen = nread;
 
-                       rc = SQLITE3_CALL (sqlite3_blob_write) (bop->priv->sblob,
+                       rc = SQLITE3_CALL (prov, sqlite3_blob_write) (bop->priv->sblob,
                                                                gda_binary_get_data (gda_blob_get_binary 
(tmpblob)), wlen, offset + nbwritten);
                        if (rc != SQLITE_OK)
                                tmp_written = -1;
@@ -296,6 +326,7 @@ gda_sqlite_blob_op_write (GdaBlobOp *op, GdaBlob *blob, glong offset)
                        if (tmp_written < 0) {
                                /* treat error */
                                gda_blob_free ((gpointer) tmpblob);
+                               g_object_unref (prov);
                                return -1;
                        }
                        nbwritten += tmp_written;
@@ -315,12 +346,13 @@ gda_sqlite_blob_op_write (GdaBlobOp *op, GdaBlob *blob, glong offset)
                else
                        wlen = gda_binary_get_size (bin);
 
-               rc = SQLITE3_CALL (sqlite3_blob_write) (bop->priv->sblob, gda_binary_get_data (bin), wlen, 
offset);
+               rc = SQLITE3_CALL (prov, sqlite3_blob_write) (bop->priv->sblob, gda_binary_get_data (bin), 
wlen, offset);
                if (rc != SQLITE_OK)
                        nbwritten = -1;
                else
                        nbwritten = wlen;
        }
+       g_object_unref (prov);
 
        return nbwritten;
 }
diff --git a/libgda/sqlite/gda-sqlite-meta.c b/libgda/sqlite/gda-sqlite-meta.c
index d2567dfaf..870dd6279 100644
--- a/libgda/sqlite/gda-sqlite-meta.c
+++ b/libgda/sqlite/gda-sqlite-meta.c
@@ -362,7 +362,7 @@ get_affinity (const gchar *type)
 }
 
 static gboolean
-fill_udt_model (SqliteConnectionData *cdata, GHashTable *added_hash, 
+fill_udt_model (GdaSqliteProvider *prov, SqliteConnectionData *cdata, GHashTable *added_hash,
                GdaDataModel *mod_model, const GValue *p_udt_schema, GError **error)
 {
        gint status;
@@ -373,7 +373,7 @@ fill_udt_model (SqliteConnectionData *cdata, GHashTable *added_hash,
 
        cstr = g_value_get_string (p_udt_schema);
        str = g_strdup_printf ("SELECT name FROM %s.sqlite_master WHERE type='table' AND name not like 
'sqlite_%%'", cstr);
-       status = SQLITE3_CALL (sqlite3_prepare_v2) (cdata->connection, str, -1, &tables_stmt, NULL);
+       status = SQLITE3_CALL (prov, sqlite3_prepare_v2) (cdata->connection, str, -1, &tables_stmt, NULL);
        g_free (str);
        if ((status != SQLITE_OK) || !tables_stmt)
                return FALSE;
@@ -381,31 +381,31 @@ fill_udt_model (SqliteConnectionData *cdata, GHashTable *added_hash,
        if (!cdata->types_hash)
                 _gda_sqlite_compute_types_hash (cdata);
 
-       for (status = SQLITE3_CALL (sqlite3_step) (tables_stmt);
+       for (status = SQLITE3_CALL (prov, sqlite3_step) (tables_stmt);
             status == SQLITE_ROW;
-            status = SQLITE3_CALL (sqlite3_step) (tables_stmt)) {
+            status = SQLITE3_CALL (prov, sqlite3_step) (tables_stmt)) {
                gchar *sql;
                sqlite3_stmt *fields_stmt;
                gint fields_status;
 
                if (strcmp (cstr, "main")) 
                        sql = g_strdup_printf ("PRAGMA %s.table_info(%s);", cstr,
-                                              SQLITE3_CALL (sqlite3_column_text) (tables_stmt, 0));
+                                              SQLITE3_CALL (prov, sqlite3_column_text) (tables_stmt, 0));
                else
                        sql = g_strdup_printf ("PRAGMA table_info('%s');",
-                                              SQLITE3_CALL (sqlite3_column_text) (tables_stmt, 0));
-               fields_status = SQLITE3_CALL (sqlite3_prepare_v2) (cdata->connection, sql,
+                                              SQLITE3_CALL (prov, sqlite3_column_text) (tables_stmt, 0));
+               fields_status = SQLITE3_CALL (prov, sqlite3_prepare_v2) (cdata->connection, sql,
                                                                   -1, &fields_stmt, NULL);
                g_free (sql);
                if ((fields_status != SQLITE_OK) || !fields_stmt)
                        break;
                
-               for (fields_status = SQLITE3_CALL (sqlite3_step) (fields_stmt);
+               for (fields_status = SQLITE3_CALL (prov, sqlite3_step) (fields_stmt);
                     fields_status == SQLITE_ROW; 
-                    fields_status = SQLITE3_CALL (sqlite3_step) (fields_stmt)) {
+                    fields_status = SQLITE3_CALL (prov, sqlite3_step) (fields_stmt)) {
                        GType gtype;
                        GType *pg;
-                       const gchar *typname = (gchar *) SQLITE3_CALL (sqlite3_column_text) (fields_stmt, 2);
+                       const gchar *typname = (gchar *) SQLITE3_CALL (prov, sqlite3_column_text) 
(fields_stmt, 2);
                        if (!typname || !(*typname)) 
                                continue;
 
@@ -435,9 +435,9 @@ fill_udt_model (SqliteConnectionData *cdata, GHashTable *added_hash,
                                g_hash_table_insert (added_hash, g_strdup (typname), GINT_TO_POINTER (1));
                        }
                }
-               SQLITE3_CALL (sqlite3_finalize) (fields_stmt);
+               SQLITE3_CALL (prov, sqlite3_finalize) (fields_stmt);
        }
-       SQLITE3_CALL (sqlite3_finalize) (tables_stmt);
+       SQLITE3_CALL (prov, sqlite3_finalize) (tables_stmt);
 
        return retval;
 }
@@ -459,7 +459,7 @@ nocase_str_equal (gconstpointer v1, gconstpointer v2)
 }
 
 gboolean
-_gda_sqlite_meta__udt (G_GNUC_UNUSED GdaServerProvider *prov, GdaConnection *cnc,
+_gda_sqlite_meta__udt (GdaServerProvider *prov, GdaConnection *cnc,
                       GdaMetaStore *store, GdaMetaContext *context, GError **error)
 {
        SqliteConnectionData *cdata;
@@ -496,7 +496,7 @@ _gda_sqlite_meta__udt (G_GNUC_UNUSED GdaServerProvider *prov, GdaConnection *cnc
                }
                 if (!strcmp (g_value_get_string (cvalue), TMP_DATABASE_NAME))
                        continue; /* nothing to do */
-               if (! fill_udt_model (cdata, added_hash, mod_model, cvalue, error)) {
+               if (! fill_udt_model (GDA_SQLITE_PROVIDER (prov), cdata, added_hash, mod_model, cvalue, 
error)) {
                        retval = FALSE;
                         break;
                }
@@ -515,7 +515,7 @@ _gda_sqlite_meta__udt (G_GNUC_UNUSED GdaServerProvider *prov, GdaConnection *cnc
 }
 
 gboolean
-_gda_sqlite_meta_udt (G_GNUC_UNUSED GdaServerProvider *prov, GdaConnection *cnc,
+_gda_sqlite_meta_udt (GdaServerProvider *prov, GdaConnection *cnc,
                      GdaMetaStore *store, GdaMetaContext *context, GError **error,
                      G_GNUC_UNUSED const GValue *udt_catalog, const GValue *udt_schema)
 {
@@ -535,7 +535,7 @@ _gda_sqlite_meta_udt (G_GNUC_UNUSED GdaServerProvider *prov, GdaConnection *cnc,
        mod_model = gda_meta_store_create_modify_data_model (store, context->table_name);
        g_assert (mod_model);
 
-       if (! fill_udt_model (cdata, added_hash, mod_model, udt_schema, error))
+       if (! fill_udt_model (GDA_SQLITE_PROVIDER (prov), cdata, added_hash, mod_model, udt_schema, error))
                retval = FALSE;
 
        g_hash_table_destroy (added_hash);
@@ -968,6 +968,7 @@ fill_columns_model (GdaConnection *cnc, SqliteConnectionData *cdata,
                             G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_NONE};
        GdaStatement *stmt;
        GError *lerror = NULL;
+  GdaSqliteProvider *prov = GDA_SQLITE_PROVIDER (gda_connection_get_provider (GDA_CONNECTION (cnc)));
        
        schema_name = g_value_get_string (p_table_schema);
        stmt = get_statement (I_PRAGMA_TABLE_INFO, schema_name, g_value_get_string (p_table_name), NULL);
@@ -1012,7 +1013,7 @@ fill_columns_model (GdaConnection *cnc, SqliteConnectionData *cdata,
                        continue; /* ignore that table */
                
                this_col_name = g_value_get_string (nthis_col_pname);
-               if (SQLITE3_CALL (sqlite3_table_column_metadata) (cdata->connection,
+               if (SQLITE3_CALL (prov, sqlite3_table_column_metadata) (cdata->connection,
                                                                  g_value_get_string (p_table_schema), 
                                                                  this_table_name, this_col_name,
                                                                  &pzDataType, &pzCollSeq,
@@ -1253,6 +1254,8 @@ fill_constraints_tab_model (GdaConnection *cnc, SqliteConnectionData *cdata, Gda
        gint i;
        GdaStatement *stmt;
        GError *lerror = NULL;
+       GdaSqliteProvider *prov = GDA_SQLITE_PROVIDER (gda_connection_get_provider (GDA_CONNECTION (cnc)));
+
 
        schema_name = g_value_get_string (p_table_schema);
 
@@ -1301,7 +1304,7 @@ fill_constraints_tab_model (GdaConnection *cnc, SqliteConnectionData *cdata, Gda
                        continue; /* ignore that table */
                
                this_col_name = g_value_get_string (this_col_pname);
-               if (SQLITE3_CALL (sqlite3_table_column_metadata) (cdata->connection,
+               if (SQLITE3_CALL (prov, sqlite3_table_column_metadata) (cdata->connection,
                                                                  g_value_get_string (p_table_schema), 
                                                                  this_table_name, this_col_name,
                                                                  &pzDataType, &pzCollSeq,
@@ -1829,6 +1832,7 @@ fill_key_columns_model (GdaConnection *cnc, SqliteConnectionData *cdata, GdaData
        const gchar *schema_name, *const_name;
        gint i;
        GdaStatement *stmt;
+       GdaSqliteProvider *prov = GDA_SQLITE_PROVIDER (gda_connection_get_provider (cnc));
 
        schema_name = g_value_get_string (p_table_schema);
        const_name = g_value_get_string (constraint_name);
@@ -1877,7 +1881,7 @@ fill_key_columns_model (GdaConnection *cnc, SqliteConnectionData *cdata, GdaData
                                continue; /* ignore that table */
                        
                        this_col_name = g_value_get_string (this_col_pname);
-                       if (SQLITE3_CALL (sqlite3_table_column_metadata) (cdata->connection, 
g_value_get_string (p_table_schema), 
+                       if (SQLITE3_CALL (prov, sqlite3_table_column_metadata) (cdata->connection, 
g_value_get_string (p_table_schema),
                                                                         this_table_name, this_col_name,
                                                                         &pzDataType, &pzCollSeq,
                                                                         &pNotNull, &pPrimaryKey, &pAutoinc)
diff --git a/libgda/sqlite/gda-sqlite-provider.c b/libgda/sqlite/gda-sqlite-provider.c
index 07be81afc..c7aa197e6 100644
--- a/libgda/sqlite/gda-sqlite-provider.c
+++ b/libgda/sqlite/gda-sqlite-provider.c
@@ -259,11 +259,28 @@ gda_sqlite_provider_iface_init (GdaProviderInterface *iface);
 // API routines from library
 Sqlite3ApiRoutines *s3r;
 
+/**
+ * call it if you are implementing a new derived provider using
+ * a different SQLite library, like SQLCipher
+ */
+static gpointer
+gda_sqlite_provider_get_api_internal (GdaSqliteProvider *prov) {
+  return s3r;
+}
+/* properties */
+enum
+{
+       PROP_0,
+       PROP_IS_DEFAULT,
+       PROP_CONNECTION
+};
+
 /*
  * GObject methods
  */
 typedef struct {
        GPtrArray       *internal_stmt;
+       gboolean         is_default;
 } GdaSqliteProviderPrivate;
 
 
@@ -872,22 +889,24 @@ GdaServerProviderMeta sqlite_meta_functions = {
        NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* padding */
 };
 
-enum {
-  PROP_CONNECTION = 1
-};
-
-
 static void
 gda_sqlite_provider_get_property (G_GNUC_UNUSED GObject    *object,
                           guint       property_id,
                           GValue     *value,
                           G_GNUC_UNUSED GParamSpec *pspec)
 {
-  switch (property_id) {
-  case PROP_CONNECTION:
+       GdaSqliteProviderPrivate *priv = gda_sqlite_provider_get_instance_private (GDA_SQLITE_PROVIDER 
(object));
+       switch (property_id) {
+       case PROP_IS_DEFAULT:
+               g_value_set_boolean (value, priv->is_default);
+               break;
+       case PROP_CONNECTION:
                g_value_set_object (value, NULL);
-    break;
-  }
+               break;
+       default:
+               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+               break;
+       }
 }
 
 static void
@@ -896,10 +915,17 @@ gda_sqlite_provider_set_property (G_GNUC_UNUSED GObject      *object,
                           G_GNUC_UNUSED const GValue *value,
                           G_GNUC_UNUSED GParamSpec   *pspec)
 {
-  switch (property_id) {
-  case PROP_CONNECTION:
-    break;
-  }
+       GdaSqliteProviderPrivate *priv = gda_sqlite_provider_get_instance_private (GDA_SQLITE_PROVIDER 
(object));
+       switch (property_id) {
+       case PROP_IS_DEFAULT:
+               priv->is_default = g_value_get_boolean (value);
+               break;
+       case PROP_CONNECTION:
+               break;
+       default:
+               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+               break;
+       }
 }
 
 static void
@@ -914,11 +940,18 @@ gda_sqlite_provider_dispose (GObject *object)
 static void
 gda_sqlite_provider_class_init (GdaSqliteProviderClass *klass)
 {
-  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+       object_class->get_property = gda_sqlite_provider_get_property;
+       object_class->set_property = gda_sqlite_provider_set_property;
+       object_class->dispose = gda_sqlite_provider_dispose;
 
-  object_class->get_property = gda_sqlite_provider_get_property;
-  object_class->set_property = gda_sqlite_provider_set_property;
-  object_class->dispose = gda_sqlite_provider_dispose;
+
+       g_object_class_install_property (object_class, PROP_IS_DEFAULT,
+               g_param_spec_boolean ("is-default", "Is Default Provider",
+                                                                                                       
_("Set to TRUE if the provider is the internal default"),
+                                                                                                       TRUE,
+                                                                                                       
(G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));
        /* set virtual functions */
        gda_server_provider_set_impl_functions (GDA_SERVER_PROVIDER_CLASS (klass),
                                                GDA_SERVER_PROVIDER_FUNCTIONS_BASE,
@@ -936,10 +969,11 @@ gda_sqlite_provider_class_init (GdaSqliteProviderClass *klass)
 
        module2 = find_sqlite_library ("libsqlite3");
        if (module2)
-               load_symbols (module2);
+               load_symbols (module2, &s3r);
        if (s3r == NULL) {
                g_warning (_("Can't find libsqlite3." G_MODULE_SUFFIX " file."));
        }
+       klass->get_api = gda_sqlite_provider_get_api_internal;
 #endif
 }
 
@@ -962,18 +996,21 @@ gda_sqlite_provider_init (GdaSqliteProvider *sqlite_prv)
                        g_error ("Could not parse internal statement: %s\n", internal_sql[i]);
                }
        }
+       /* Set as defualt */
+       priv->is_default = TRUE;
 
        /* meta data init */
        _gda_sqlite_provider_meta_init ((GdaServerProvider*) sqlite_prv);
 }
 
 static GdaWorker *
-gda_sqlite_provider_create_worker (G_GNUC_UNUSED GdaServerProvider *provider, gboolean for_cnc)
+gda_sqlite_provider_create_worker (GdaServerProvider *provider, gboolean for_cnc)
 {
        /* see http://www.sqlite.org/threadsafe.html */
+       GdaSqliteProvider *prov = GDA_SQLITE_PROVIDER (provider);
 
        static GdaWorker *unique_worker = NULL;
-       if (SQLITE3_CALL (sqlite3_threadsafe) ()) {
+       if (SQLITE3_CALL (prov, sqlite3_threadsafe) ()) {
                if (for_cnc)
                        return gda_worker_new ();
                else
@@ -1071,6 +1108,8 @@ gda_sqlite_provider_open_connection (GdaServerProvider *provider, GdaConnection
        g_return_val_if_fail (GDA_IS_SQLITE_PROVIDER (provider), FALSE);
        g_return_val_if_fail (GDA_IS_CONNECTION (cnc), FALSE);
 
+       GdaSqliteProvider *prov = GDA_SQLITE_PROVIDER (provider);
+
        /* get all parameters received */
        dirname = gda_quark_list_find (params, "DB_DIR");
        if (!dirname)
@@ -1169,14 +1208,15 @@ gda_sqlite_provider_open_connection (GdaServerProvider *provider, GdaConnection
        }
 
        cdata = g_new0 (SqliteConnectionData, 1);
+       g_weak_ref_init (&cdata->provider, prov);
 
        if (filename)
                cdata->file = filename;
 
-       errmsg = SQLITE3_CALL (sqlite3_open_v2) (filename, &cdata->connection, SQLITE_OPEN_FULLMUTEX | 
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
+       errmsg = SQLITE3_CALL (prov, sqlite3_open_v2) (filename, &cdata->connection, SQLITE_OPEN_FULLMUTEX | 
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
 
        if (errmsg != SQLITE_OK) {
-               gda_connection_add_event_string (cnc, SQLITE3_CALL (sqlite3_errmsg) (cdata->connection));
+               gda_connection_add_event_string (cnc, SQLITE3_CALL (prov, sqlite3_errmsg) 
(cdata->connection));
                gda_sqlite_free_cnc_data (cdata);
 
                return FALSE;
@@ -1190,7 +1230,7 @@ gda_sqlite_provider_open_connection (GdaServerProvider *provider, GdaConnection
                passphrase = gda_quark_list_find (auth, "PASSWORD");
 
        if (passphrase != NULL) {
-               errmsg = SQLITE3_CALL (sqlite3_key_v2) (cdata->connection, filename,
+               errmsg = SQLITE3_CALL (prov,sqlite3_key_v2) (cdata->connection, filename,
                                                       (void*) passphrase, strlen (passphrase));
                if (errmsg != SQLITE_OK) {
                        gda_connection_add_event_string (cnc, _("Wrong encryption passphrase"));
@@ -1216,6 +1256,8 @@ gda_sqlite_provider_prepare_connection (GdaServerProvider *provider, GdaConnecti
        if (!cdata)
                return FALSE;
 
+       GdaSqliteProvider *prov = GDA_SQLITE_PROVIDER (provider);
+
        const gchar *use_extra_functions = NULL, *with_fk = NULL, *regexp, *locale_collate, *extensions;
        with_fk = gda_quark_list_find (params, "FK");
        use_extra_functions = gda_quark_list_find (params, "EXTRA_FUNCTIONS");
@@ -1226,10 +1268,10 @@ gda_sqlite_provider_prepare_connection (GdaServerProvider *provider, GdaConnecti
        extensions = gda_quark_list_find (params, "EXTENSIONS");
 
        /* use extended result codes */
-       SQLITE3_CALL (sqlite3_extended_result_codes) (cdata->connection, 1);
+       SQLITE3_CALL (prov, sqlite3_extended_result_codes) (cdata->connection, 1);
 
        /* allow a busy timeout of 500 ms */
-       SQLITE3_CALL (sqlite3_busy_timeout) (cdata->connection, 500);
+       SQLITE3_CALL (prov, sqlite3_busy_timeout) (cdata->connection, 500);
 
        /* allow loading extensions using SELECT load_extension ()... */
        if (extensions && ((*extensions == 't') || (*extensions == 'T'))) {
@@ -1268,7 +1310,7 @@ gda_sqlite_provider_prepare_connection (GdaServerProvider *provider, GdaConnecti
                gint status;
                gchar *errmsg;
 
-               status = SQLITE3_CALL (sqlite3_get_table) (cdata->connection, "SELECT name"
+               status = SQLITE3_CALL (prov, sqlite3_get_table) (cdata->connection, "SELECT name"
                                                           " FROM (SELECT * FROM sqlite_master UNION ALL "
                                                           "       SELECT * FROM sqlite_temp_master)",
                                                           &data,
@@ -1276,10 +1318,10 @@ gda_sqlite_provider_prepare_connection (GdaServerProvider *provider, GdaConnecti
                                                           &ncols,
                                                           &errmsg);
                if (status == SQLITE_OK)
-                       SQLITE3_CALL (sqlite3_free_table) (data);
+                       SQLITE3_CALL (prov, sqlite3_free_table) (data);
                else {
                        gda_connection_add_event_string (cnc, errmsg);
-                       SQLITE3_CALL (sqlite3_free) (errmsg);
+                       SQLITE3_CALL (prov, sqlite3_free) (errmsg);
                        gda_sqlite_free_cnc_data (cdata);
                        gda_connection_internal_set_provider_data (cnc, NULL, NULL);
                        return FALSE;
@@ -1293,11 +1335,11 @@ gda_sqlite_provider_prepare_connection (GdaServerProvider *provider, GdaConnecti
        int res;
        sqlite3_stmt *pStmt;
        if (enforce_fk)
-               res = SQLITE3_CALL (sqlite3_prepare_v2) (cdata->connection,
+               res = SQLITE3_CALL (prov, sqlite3_prepare_v2) (cdata->connection,
                                                      "PRAGMA foreign_keys = ON", -1,
                                                      &pStmt, NULL);
        else
-               res = SQLITE3_CALL (sqlite3_prepare_v2) (cdata->connection,
+               res = SQLITE3_CALL (prov, sqlite3_prepare_v2) (cdata->connection,
                                                      "PRAGMA foreign_keys = OFF", -1,
                                                      &pStmt, NULL);
 
@@ -1309,9 +1351,9 @@ gda_sqlite_provider_prepare_connection (GdaServerProvider *provider, GdaConnecti
                }
        }
        else {
-               res = SQLITE3_CALL (sqlite3_step) (pStmt);
-               SQLITE3_CALL (sqlite3_reset) (pStmt);
-               SQLITE3_CALL (sqlite3_finalize) (pStmt);
+               res = SQLITE3_CALL (prov, sqlite3_step) (pStmt);
+               SQLITE3_CALL (prov, sqlite3_reset) (pStmt);
+               SQLITE3_CALL (prov, sqlite3_finalize) (pStmt);
                if (res != SQLITE_DONE) {
                        if (with_fk) {
                                gda_sqlite_free_cnc_data (cdata);
@@ -1329,58 +1371,60 @@ gda_sqlite_provider_prepare_connection (GdaServerProvider *provider, GdaConnecti
 #endif
        }
 
-       if (!use_extra_functions || ((*use_extra_functions == 't') || (*use_extra_functions == 'T'))) {
-               gsize i;
-
-               for (i = 0; i < sizeof (scalars) / sizeof (ScalarFunction); i++) {
-                       ScalarFunction *func = (ScalarFunction *) &(scalars [i]);
-                       gint res = SQLITE3_CALL (sqlite3_create_function) (cdata->connection,
-                                                                          func->name, func->nargs,
-                                                                          SQLITE_UTF8, func->user_data,
-                                                                          func->xFunc, NULL, NULL);
-                       if (res != SQLITE_OK) {
-                               gda_connection_add_event_string (cnc, _("Could not register function '%s'"),
-                                                                func->name);
-                               gda_sqlite_free_cnc_data (cdata);
-                               gda_connection_internal_set_provider_data (cnc, NULL, NULL);
-                               return FALSE;
+       if (priv->is_default) {
+               if (!use_extra_functions || ((*use_extra_functions == 't') || (*use_extra_functions == 'T'))) 
{
+                       gsize i;
+
+                       for (i = 0; i < sizeof (scalars) / sizeof (ScalarFunction); i++) {
+                               ScalarFunction *func = (ScalarFunction *) &(scalars [i]);
+                               gint res = (s3r->sqlite3_create_function) (cdata->connection,
+                                                                                        func->name, 
func->nargs,
+                                                                                        SQLITE_UTF8, prov,
+                                                                                        func->xFunc, NULL, 
NULL);
+                               if (res != SQLITE_OK) {
+                                       gda_connection_add_event_string (cnc, _("Could not register function 
'%s'"),
+                                                                        func->name);
+                                       gda_sqlite_free_cnc_data (cdata);
+                                       gda_connection_internal_set_provider_data (cnc, NULL, NULL);
+                                       return FALSE;
+                               }
                        }
                }
-       }
 
-       if (!regexp || ((*regexp == 't') || (*regexp == 'T'))) {
-               gsize i;
-
-               for (i = 0; i < sizeof (regexp_functions) / sizeof (ScalarFunction); i++) {
-                       ScalarFunction *func = (ScalarFunction *) &(regexp_functions [i]);
-                       gint res = SQLITE3_CALL (sqlite3_create_function) (cdata->connection,
-                                                                          func->name, func->nargs,
-                                                                          SQLITE_UTF8, func->user_data,
-                                                                          func->xFunc, NULL, NULL);
-                       if (res != SQLITE_OK) {
-                               gda_connection_add_event_string (cnc, _("Could not register function '%s'"),
-                                                                func->name);
-                               gda_sqlite_free_cnc_data (cdata);
-                               gda_connection_internal_set_provider_data (cnc, NULL, NULL);
-                               return FALSE;
+               if (!regexp || ((*regexp == 't') || (*regexp == 'T'))) {
+                       gsize i;
+
+                       for (i = 0; i < sizeof (regexp_functions) / sizeof (ScalarFunction); i++) {
+                               ScalarFunction *func = (ScalarFunction *) &(regexp_functions [i]);
+                               gint res = (s3r->sqlite3_create_function) (cdata->connection,
+                                                                                        func->name, 
func->nargs,
+                                                                                        SQLITE_UTF8, prov,
+                                                                                        func->xFunc, NULL, 
NULL);
+                               if (res != SQLITE_OK) {
+                                       gda_connection_add_event_string (cnc, _("Could not register function 
'%s'"),
+                                                                        func->name);
+                                       gda_sqlite_free_cnc_data (cdata);
+                                       gda_connection_internal_set_provider_data (cnc, NULL, NULL);
+                                       return FALSE;
+                               }
                        }
                }
-       }
 
-       if (! locale_collate || ((*locale_collate == 't') || (*locale_collate == 'T'))) {
-               gsize i;
-               for (i = 0; i < sizeof (collation_functions) / sizeof (CollationFunction); i++) {
-                       CollationFunction *func = (CollationFunction*) &(collation_functions [i]);
-                       gint res;
-                       res = SQLITE3_CALL (sqlite3_create_collation) (cdata->connection, func->name,
-                                                                      SQLITE_UTF8, NULL, func->xFunc);
-                       if (res != SQLITE_OK) {
-                               gda_connection_add_event_string (cnc,
-                                                                _("Could not define the %s collation"),
-                                                                func->name);
-                               gda_sqlite_free_cnc_data (cdata);
-                               gda_connection_internal_set_provider_data (cnc, NULL, NULL);
-                               return FALSE;
+               if (! locale_collate || ((*locale_collate == 't') || (*locale_collate == 'T'))) {
+                       gsize i;
+                       for (i = 0; i < sizeof (collation_functions) / sizeof (CollationFunction); i++) {
+                               CollationFunction *func = (CollationFunction*) &(collation_functions [i]);
+                               gint res;
+                               res = (s3r->sqlite3_create_collation) (cdata->connection, func->name,
+                                                                                    SQLITE_UTF8, prov, 
func->xFunc);
+                               if (res != SQLITE_OK) {
+                                       gda_connection_add_event_string (cnc,
+                                                                        _("Could not define the %s 
collation"),
+                                                                        func->name);
+                                       gda_sqlite_free_cnc_data (cdata);
+                                       gda_connection_internal_set_provider_data (cnc, NULL, NULL);
+                                       return FALSE;
+                               }
                        }
                }
        }
@@ -1622,6 +1666,7 @@ gda_sqlite_provider_perform_operation (GdaServerProvider *provider, GdaConnectio
                gint errmsg;
                gchar *filename, *tmp;
                gboolean retval = TRUE;
+               GdaSqliteProvider *prov = GDA_SQLITE_PROVIDER (provider);
 
                value = gda_server_operation_get_value_at (op, "/DB_DEF_P/DB_NAME");
                 if (value && G_VALUE_HOLDS (value, G_TYPE_STRING) && g_value_get_string (value))
@@ -1642,13 +1687,13 @@ gda_sqlite_provider_perform_operation (GdaServerProvider *provider, GdaConnectio
                g_free (tmp);
 
                cdata = g_new0 (SqliteConnectionData, 1);
-               errmsg = SQLITE3_CALL (sqlite3_open) (filename, &cdata->connection);
+               errmsg = SQLITE3_CALL (prov, sqlite3_open) (filename, &cdata->connection);
                g_free (filename);
 
                if (errmsg != SQLITE_OK) {
                        g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
                                     GDA_SERVER_PROVIDER_PREPARE_STMT_ERROR,
-                                    "%s", SQLITE3_CALL (sqlite3_errmsg) (cdata->connection));
+                                    "%s", SQLITE3_CALL (prov, sqlite3_errmsg) (cdata->connection));
                        retval = FALSE;
                }
 
@@ -1658,19 +1703,19 @@ gda_sqlite_provider_perform_operation (GdaServerProvider *provider, GdaConnectio
                    g_value_get_string (value) &&
                    *g_value_get_string (value)) {
                        const gchar *passphrase = g_value_get_string (value);
-                       errmsg = SQLITE3_CALL (sqlite3_key_v2) (cdata->connection, cdata->file, (void*) 
passphrase,
+                       errmsg = SQLITE3_CALL (prov, sqlite3_key_v2) (cdata->connection, cdata->file, (void*) 
passphrase,
                                                             strlen (passphrase));
                        if (errmsg != SQLITE_OK) {
                                g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
                                             GDA_SERVER_PROVIDER_INTERNAL_ERROR,
-                                            "%s", SQLITE3_CALL (sqlite3_errmsg) (cdata->connection));
+                                            "%s", SQLITE3_CALL (prov, sqlite3_errmsg) (cdata->connection));
                                retval = FALSE;
                        }
                        else {
                                /* create some contents */
                                int res;
                                sqlite3_stmt *pStmt;
-                               res = SQLITE3_CALL (sqlite3_prepare_v2) (cdata->connection,
+                               res = SQLITE3_CALL (prov, sqlite3_prepare_v2) (cdata->connection,
                                                                      "CREATE TABLE data (id int)", -1,
                                                                      &pStmt, NULL);
 
@@ -1682,9 +1727,9 @@ gda_sqlite_provider_perform_operation (GdaServerProvider *provider, GdaConnectio
                                        retval = FALSE;
                                        goto outcontents;
                                }
-                               res = SQLITE3_CALL (sqlite3_step) (pStmt);
-                               SQLITE3_CALL (sqlite3_reset) (pStmt);
-                               SQLITE3_CALL (sqlite3_finalize) (pStmt);
+                               res = SQLITE3_CALL (prov, sqlite3_step) (pStmt);
+                               SQLITE3_CALL (prov, sqlite3_reset) (pStmt);
+                               SQLITE3_CALL (prov, sqlite3_finalize) (pStmt);
                                if (res != SQLITE_DONE) {
                                        g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
                                                     GDA_SERVER_PROVIDER_INTERNAL_ERROR,
@@ -1695,7 +1740,7 @@ gda_sqlite_provider_perform_operation (GdaServerProvider *provider, GdaConnectio
                                        /* end */
                                }
 
-                               res = SQLITE3_CALL (sqlite3_prepare_v2) (cdata->connection,
+                               res = SQLITE3_CALL (prov, sqlite3_prepare_v2) (cdata->connection,
                                                                      "DROP TABLE data", -1,
                                                                      &pStmt, NULL);
 
@@ -1707,9 +1752,9 @@ gda_sqlite_provider_perform_operation (GdaServerProvider *provider, GdaConnectio
                                        retval = FALSE;
                                        goto outcontents;
                                }
-                               res = SQLITE3_CALL (sqlite3_step) (pStmt);
-                               SQLITE3_CALL (sqlite3_reset) (pStmt);
-                               SQLITE3_CALL (sqlite3_finalize) (pStmt);
+                               res = SQLITE3_CALL (prov, sqlite3_step) (pStmt);
+                               SQLITE3_CALL (prov, sqlite3_reset) (pStmt);
+                               SQLITE3_CALL (prov, sqlite3_finalize) (pStmt);
                                if (res != SQLITE_DONE) {
                                        g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
                                                     GDA_SERVER_PROVIDER_INTERNAL_ERROR,
@@ -2875,6 +2920,7 @@ real_prepare (GdaServerProvider *provider, GdaConnection *cnc, GdaStatement *stm
        GdaStatement *real_stmt;
        GHashTable *hash;
        gint nb_rows_added;
+       GdaSqliteProvider *prov = GDA_SQLITE_PROVIDER (provider);
 
        /* get SQLite's private data */
        cdata = (SqliteConnectionData*) gda_connection_internal_get_provider_data_error (cnc, error);
@@ -2892,10 +2938,10 @@ real_prepare (GdaServerProvider *provider, GdaConnection *cnc, GdaStatement *stm
                goto out_err;
 
        /* prepare statement */
-       status = SQLITE3_CALL (sqlite3_prepare_v2) (cdata->connection, sql, -1, &sqlite_stmt, &left);
+       status = SQLITE3_CALL (prov, sqlite3_prepare_v2) (cdata->connection, sql, -1, &sqlite_stmt, &left);
        if (status != SQLITE_OK) {
                g_set_error (error, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_PREPARE_STMT_ERROR,
-                            "%s", SQLITE3_CALL (sqlite3_errmsg) (cdata->connection));
+                            "%s", SQLITE3_CALL (prov, sqlite3_errmsg) (cdata->connection));
                goto out_err;
        }
 
@@ -3134,6 +3180,7 @@ fill_blob_data (GdaConnection *cnc, GdaSet *params,
        sqlite3_int64 rowid = -1;
        GdaDataModel *model = NULL;
        GError *lerror = NULL;
+       GdaSqliteProvider *prov = GDA_SQLITE_PROVIDER (gda_connection_get_provider (cnc));
 
        /* get single ROWID or a list of ROWID */
        stmt = gda_pstmt_get_gda_statement (GDA_PSTMT (pstmt));
@@ -3144,7 +3191,7 @@ fill_blob_data (GdaConnection *cnc, GdaSet *params,
                goto blobs_out;
        }
        if (gda_statement_get_statement_type (stmt) == GDA_SQL_STATEMENT_INSERT) {
-               rowid = SQLITE3_CALL (sqlite3_last_insert_rowid) (cdata->connection);
+               rowid = SQLITE3_CALL (prov, sqlite3_last_insert_rowid) (cdata->connection);
        }
        else if (gda_statement_get_statement_type (stmt) == GDA_SQL_STATEMENT_UPDATE) {
                GdaSqlStatement *sel_stmt;
@@ -3272,6 +3319,7 @@ gda_sqlite_provider_statement_execute (GdaServerProvider *provider, GdaConnectio
        gboolean allow_noparam;
        gboolean empty_rs = FALSE; /* TRUE when @allow_noparam is TRUE and there is a problem with @params
                                      => resulting data model will be empty (0 row) */
+       GdaSqliteProvider *prov = GDA_SQLITE_PROVIDER (provider);
 
        g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL);
        g_return_val_if_fail (gda_connection_get_provider (cnc) == provider, NULL);
@@ -3303,11 +3351,11 @@ gda_sqlite_provider_statement_execute (GdaServerProvider *provider, GdaConnectio
                        if (!sql)
                                return NULL;
 
-                       status = SQLITE3_CALL (sqlite3_prepare_v2) (cdata->connection, sql, -1,
+                       status = SQLITE3_CALL (prov, sqlite3_prepare_v2) (cdata->connection, sql, -1,
                                                                    &sqlite_stmt, (const char**) &left);
                        if (status != SQLITE_OK) {
                                g_set_error (error, GDA_SERVER_PROVIDER_ERROR, 
GDA_SERVER_PROVIDER_PREPARE_STMT_ERROR,
-                                            "%s", SQLITE3_CALL (sqlite3_errmsg) (cdata->connection));
+                                            "%s", SQLITE3_CALL (prov, sqlite3_errmsg) (cdata->connection));
                                g_free (sql);
                                return NULL;
                        }
@@ -3355,12 +3403,12 @@ gda_sqlite_provider_statement_execute (GdaServerProvider *provider, GdaConnectio
        }
 
        /* reset prepared stmt */
-       if ((SQLITE3_CALL (sqlite3_reset) (_gda_sqlite_pstmt_get_stmt (ps)) != SQLITE_OK) ||
-           (SQLITE3_CALL (sqlite3_clear_bindings) (_gda_sqlite_pstmt_get_stmt (ps)) != SQLITE_OK)) {
+       if ((SQLITE3_CALL (prov, sqlite3_reset) (_gda_sqlite_pstmt_get_stmt (ps)) != SQLITE_OK) ||
+           (SQLITE3_CALL (prov, sqlite3_clear_bindings) (_gda_sqlite_pstmt_get_stmt (ps)) != SQLITE_OK)) {
                GdaConnectionEvent *event;
                const char *errmsg;
 
-               errmsg = SQLITE3_CALL (sqlite3_errmsg) (cdata->connection);
+               errmsg = SQLITE3_CALL (prov, sqlite3_errmsg) (cdata->connection);
                event = gda_connection_point_available_event (cnc, GDA_CONNECTION_EVENT_ERROR);
                gda_connection_event_set_description (event, errmsg);
                gda_connection_add_event (cnc, event);
@@ -3402,7 +3450,7 @@ gda_sqlite_provider_statement_execute (GdaServerProvider *provider, GdaConnectio
                if (!h) {
                        if (allow_noparam) {
                                /* bind param to NULL */
-                               SQLITE3_CALL (sqlite3_bind_null) (_gda_sqlite_pstmt_get_stmt (ps), i);
+                               SQLITE3_CALL (prov, sqlite3_bind_null) (_gda_sqlite_pstmt_get_stmt (ps), i);
                                empty_rs = TRUE;
                                continue;
                        }
@@ -3422,7 +3470,7 @@ gda_sqlite_provider_statement_execute (GdaServerProvider *provider, GdaConnectio
                if (!gda_holder_is_valid (h)) {
                        if (allow_noparam) {
                                /* bind param to NULL */
-                               SQLITE3_CALL (sqlite3_bind_null) (_gda_sqlite_pstmt_get_stmt (ps), i);
+                               SQLITE3_CALL (prov, sqlite3_bind_null) (_gda_sqlite_pstmt_get_stmt (ps), i);
                                empty_rs = TRUE;
                                continue;
                        }
@@ -3472,7 +3520,7 @@ gda_sqlite_provider_statement_execute (GdaServerProvider *provider, GdaConnectio
                if (!value || gda_value_is_null (value)) {
                        GdaStatement *rstmt;
                        if (! gda_rewrite_statement_for_null_parameters (stmt, params, &rstmt, error))
-                               SQLITE3_CALL (sqlite3_bind_null) (_gda_sqlite_pstmt_get_stmt (ps), i);
+                               SQLITE3_CALL (prov, sqlite3_bind_null) (_gda_sqlite_pstmt_get_stmt (ps), i);
                        else if (!rstmt)
                                return NULL;
                        else {
@@ -3525,38 +3573,38 @@ gda_sqlite_provider_statement_execute (GdaServerProvider *provider, GdaConnectio
                        }
                }
                else if (G_VALUE_TYPE (value) == G_TYPE_STRING)
-                       SQLITE3_CALL (sqlite3_bind_text) (_gda_sqlite_pstmt_get_stmt (ps), i,
+                       SQLITE3_CALL (prov, sqlite3_bind_text) (_gda_sqlite_pstmt_get_stmt (ps), i,
                                                          g_value_get_string (value), -1, SQLITE_TRANSIENT);
                else if (G_VALUE_TYPE (value) == GDA_TYPE_TEXT) {
                        GdaText *text = (GdaText*) g_value_get_boxed (value);
                        const gchar *tstr = gda_text_get_string (text);
-                       SQLITE3_CALL (sqlite3_bind_text) (_gda_sqlite_pstmt_get_stmt (ps), i,
+                       SQLITE3_CALL (prov, sqlite3_bind_text) (_gda_sqlite_pstmt_get_stmt (ps), i,
                                                          tstr, -1, SQLITE_TRANSIENT);
     }
                else if (G_VALUE_TYPE (value) == G_TYPE_INT)
-                       SQLITE3_CALL (sqlite3_bind_int) (_gda_sqlite_pstmt_get_stmt (ps), i, g_value_get_int 
(value));
+                       SQLITE3_CALL (prov, sqlite3_bind_int) (_gda_sqlite_pstmt_get_stmt (ps), i, 
g_value_get_int (value));
                else if (G_VALUE_TYPE (value) == G_TYPE_LONG)
-                       SQLITE3_CALL (sqlite3_bind_int) (_gda_sqlite_pstmt_get_stmt (ps), i, g_value_get_long 
(value));
+                       SQLITE3_CALL (prov, sqlite3_bind_int) (_gda_sqlite_pstmt_get_stmt (ps), i, 
g_value_get_long (value));
                else if (G_VALUE_TYPE (value) == G_TYPE_DOUBLE)
-                       SQLITE3_CALL (sqlite3_bind_double) (_gda_sqlite_pstmt_get_stmt (ps), i, 
g_value_get_double (value));
+                       SQLITE3_CALL (prov, sqlite3_bind_double) (_gda_sqlite_pstmt_get_stmt (ps), i, 
g_value_get_double (value));
                else if (G_VALUE_TYPE (value) == G_TYPE_FLOAT)
-                       SQLITE3_CALL (sqlite3_bind_double) (_gda_sqlite_pstmt_get_stmt (ps), i, 
g_value_get_float (value));
+                       SQLITE3_CALL (prov, sqlite3_bind_double) (_gda_sqlite_pstmt_get_stmt (ps), i, 
g_value_get_float (value));
                else if (G_VALUE_TYPE (value) == G_TYPE_UINT)
-                       SQLITE3_CALL (sqlite3_bind_int) (_gda_sqlite_pstmt_get_stmt (ps), i, g_value_get_uint 
(value));
+                       SQLITE3_CALL (prov, sqlite3_bind_int) (_gda_sqlite_pstmt_get_stmt (ps), i, 
g_value_get_uint (value));
                else if (G_VALUE_TYPE (value) == G_TYPE_BOOLEAN)
-                       SQLITE3_CALL (sqlite3_bind_int) (_gda_sqlite_pstmt_get_stmt (ps), i, 
g_value_get_boolean (value) ? 1 : 0);
+                       SQLITE3_CALL (prov, sqlite3_bind_int) (_gda_sqlite_pstmt_get_stmt (ps), i, 
g_value_get_boolean (value) ? 1 : 0);
                else if (G_VALUE_TYPE (value) == G_TYPE_INT64)
-                       SQLITE3_CALL (sqlite3_bind_int64) (_gda_sqlite_pstmt_get_stmt (ps), i, 
g_value_get_int64 (value));
+                       SQLITE3_CALL (prov, sqlite3_bind_int64) (_gda_sqlite_pstmt_get_stmt (ps), i, 
g_value_get_int64 (value));
                else if (G_VALUE_TYPE (value) == G_TYPE_UINT64)
-                       SQLITE3_CALL (sqlite3_bind_int64) (_gda_sqlite_pstmt_get_stmt (ps), i, 
g_value_get_uint64 (value));
+                       SQLITE3_CALL (prov, sqlite3_bind_int64) (_gda_sqlite_pstmt_get_stmt (ps), i, 
g_value_get_uint64 (value));
                else if (G_VALUE_TYPE (value) == GDA_TYPE_SHORT)
-                       SQLITE3_CALL (sqlite3_bind_int) (_gda_sqlite_pstmt_get_stmt (ps), i, 
gda_value_get_short (value));
+                       SQLITE3_CALL (prov, sqlite3_bind_int) (_gda_sqlite_pstmt_get_stmt (ps), i, 
gda_value_get_short (value));
                else if (G_VALUE_TYPE (value) == GDA_TYPE_USHORT)
-                       SQLITE3_CALL (sqlite3_bind_int) (_gda_sqlite_pstmt_get_stmt (ps), i, 
gda_value_get_ushort (value));
+                       SQLITE3_CALL (prov, sqlite3_bind_int) (_gda_sqlite_pstmt_get_stmt (ps), i, 
gda_value_get_ushort (value));
                else if (G_VALUE_TYPE (value) == G_TYPE_CHAR)
-                       SQLITE3_CALL (sqlite3_bind_int) (_gda_sqlite_pstmt_get_stmt (ps), i, 
g_value_get_schar (value));
+                       SQLITE3_CALL (prov, sqlite3_bind_int) (_gda_sqlite_pstmt_get_stmt (ps), i, 
g_value_get_schar (value));
                else if (G_VALUE_TYPE (value) == G_TYPE_UCHAR)
-                       SQLITE3_CALL (sqlite3_bind_int) (_gda_sqlite_pstmt_get_stmt (ps), i, 
g_value_get_uchar (value));
+                       SQLITE3_CALL (prov, sqlite3_bind_int) (_gda_sqlite_pstmt_get_stmt (ps), i, 
g_value_get_uchar (value));
                else if (G_VALUE_TYPE (value) == GDA_TYPE_BLOB) {
                        glong blob_len;
                        GdaBlob *blob = (GdaBlob*) gda_value_get_blob (value);
@@ -3594,7 +3642,7 @@ gda_sqlite_provider_statement_execute (GdaServerProvider *provider, GdaConnectio
                        pb->blob = blob;
                        blobs_list = g_slist_prepend (blobs_list, pb);
 
-                       if (SQLITE3_CALL (sqlite3_bind_zeroblob) (_gda_sqlite_pstmt_get_stmt (ps), i, (int) 
blob_len) !=
+                       if (SQLITE3_CALL (prov, sqlite3_bind_zeroblob) (_gda_sqlite_pstmt_get_stmt (ps), i, 
(int) blob_len) !=
                            SQLITE_OK) {
                                event = gda_connection_point_available_event (cnc, 
GDA_CONNECTION_EVENT_ERROR);
                                gda_connection_event_set_description (event,
@@ -3606,7 +3654,7 @@ gda_sqlite_provider_statement_execute (GdaServerProvider *provider, GdaConnectio
                }
                else if (G_VALUE_TYPE (value) == GDA_TYPE_BINARY) {
                        GdaBinary *bin = (GdaBinary *) gda_value_get_binary (value);
-                       SQLITE3_CALL (sqlite3_bind_blob) (_gda_sqlite_pstmt_get_stmt (ps), i,
+                       SQLITE3_CALL (prov, sqlite3_bind_blob) (_gda_sqlite_pstmt_get_stmt (ps), i,
                                                          gda_binary_get_data (bin), gda_binary_get_size 
(bin), SQLITE_TRANSIENT);
                }
                else if (G_VALUE_TYPE (value) == GDA_TYPE_TIME) {
@@ -3634,7 +3682,7 @@ gda_sqlite_provider_statement_execute (GdaServerProvider *provider, GdaConnectio
 
                        if (tofree)
                                gda_time_free (gtime);
-                       SQLITE3_CALL (sqlite3_bind_text) (_gda_sqlite_pstmt_get_stmt (ps), i, g_string_free 
(string, FALSE), -1, g_free);
+                       SQLITE3_CALL (prov, sqlite3_bind_text) (_gda_sqlite_pstmt_get_stmt (ps), i, 
g_string_free (string, FALSE), -1, g_free);
                }
                else if (G_VALUE_TYPE (value) == G_TYPE_DATE) {
                        gchar *str;
@@ -3643,7 +3691,7 @@ gda_sqlite_provider_statement_execute (GdaServerProvider *provider, GdaConnectio
                        ts = g_value_get_boxed (value);
                        str = g_strdup_printf ("%4d-%02d-%02d", g_date_get_year (ts),
                                               g_date_get_month (ts), g_date_get_day (ts));
-                       SQLITE3_CALL (sqlite3_bind_text) (_gda_sqlite_pstmt_get_stmt (ps), i, str, -1, 
g_free);
+                       SQLITE3_CALL (prov, sqlite3_bind_text) (_gda_sqlite_pstmt_get_stmt (ps), i, str, -1, 
g_free);
                }
                else if (g_type_is_a (G_VALUE_TYPE (value), G_TYPE_DATE_TIME)) {
                        GDateTime *timestamp;
@@ -3663,13 +3711,13 @@ gda_sqlite_provider_statement_execute (GdaServerProvider *provider, GdaConnectio
                        if (tofree)
                                g_date_time_unref (timestamp);
 
-                       SQLITE3_CALL (sqlite3_bind_text) (_gda_sqlite_pstmt_get_stmt (ps), i, string, -1, 
g_free);
+                       SQLITE3_CALL (prov, sqlite3_bind_text) (_gda_sqlite_pstmt_get_stmt (ps), i, string, 
-1, g_free);
                }
                else if (G_VALUE_TYPE (value) == GDA_TYPE_NUMERIC) {
                        const GdaNumeric *gdan;
 
                        gdan = gda_value_get_numeric (value);
-                       SQLITE3_CALL (sqlite3_bind_text) (_gda_sqlite_pstmt_get_stmt (ps), i, 
gda_numeric_get_string((GdaNumeric*)gdan), -1, SQLITE_TRANSIENT);
+                       SQLITE3_CALL (prov, sqlite3_bind_text) (_gda_sqlite_pstmt_get_stmt (ps), i, 
gda_numeric_get_string((GdaNumeric*)gdan), -1, SQLITE_TRANSIENT);
                }
                else {
                        gchar *str;
@@ -3762,26 +3810,26 @@ gda_sqlite_provider_statement_execute (GdaServerProvider *provider, GdaConnectio
                }
 
                 /* actually execute the command */
-                handle = SQLITE3_CALL (sqlite3_db_handle) (_gda_sqlite_pstmt_get_stmt (ps));
-                status = SQLITE3_CALL (sqlite3_step) (_gda_sqlite_pstmt_get_stmt (ps));
+                handle = SQLITE3_CALL (prov, sqlite3_db_handle) (_gda_sqlite_pstmt_get_stmt (ps));
+                status = SQLITE3_CALL (prov, sqlite3_step) (_gda_sqlite_pstmt_get_stmt (ps));
                 guint tries = 0;
                 while (status == SQLITE_BUSY) {
                         if (gda_statement_get_statement_type (stmt) == GDA_SQL_STATEMENT_COMMIT) {
                                 break;
                         }
-                        status = SQLITE3_CALL (sqlite3_step) (_gda_sqlite_pstmt_get_stmt (ps));
+                        status = SQLITE3_CALL (prov, sqlite3_step) (_gda_sqlite_pstmt_get_stmt (ps));
                         if (tries == 10) {
                                 break;
                         }
                         tries++;
                 }
-                changes = SQLITE3_CALL (sqlite3_changes) (handle);
+                changes = SQLITE3_CALL (prov, sqlite3_changes) (handle);
                 if (status != SQLITE_DONE) {
-                        if (SQLITE3_CALL (sqlite3_errcode) (handle) != SQLITE_OK) {
+                        if (SQLITE3_CALL (prov, sqlite3_errcode) (handle) != SQLITE_OK) {
                                const char *errmsg;
-                                SQLITE3_CALL (sqlite3_reset) (_gda_sqlite_pstmt_get_stmt (ps));
+                                SQLITE3_CALL (prov, sqlite3_reset) (_gda_sqlite_pstmt_get_stmt (ps));
 
-                               errmsg = SQLITE3_CALL (sqlite3_errmsg) (handle);
+                               errmsg = SQLITE3_CALL (prov, sqlite3_errmsg) (handle);
                                 event = gda_connection_point_available_event (cnc, 
GDA_CONNECTION_EVENT_ERROR);
                                 gda_connection_event_set_description (event, errmsg);
                                g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
@@ -3813,7 +3861,7 @@ gda_sqlite_provider_statement_execute (GdaServerProvider *provider, GdaConnectio
                        event = fill_blob_data (cnc, params, cdata, ps, blobs_list, error);
                        if (event) {
                                /* an error occurred */
-                               SQLITE3_CALL (sqlite3_reset) (_gda_sqlite_pstmt_get_stmt (ps));
+                               SQLITE3_CALL (prov, sqlite3_reset) (_gda_sqlite_pstmt_get_stmt (ps));
                                if (new_ps)
                                        g_object_unref (ps);
                                if (transaction_started)
@@ -3834,7 +3882,7 @@ gda_sqlite_provider_statement_execute (GdaServerProvider *provider, GdaConnectio
                        else if (! g_ascii_strncasecmp (gda_pstmt_get_sql (_GDA_PSTMT (ps)), "INSERT", 6)) {
                                sqlite3_int64 last_id;
                                count_changes = TRUE;
-                               last_id = SQLITE3_CALL (sqlite3_last_insert_rowid) (handle);
+                               last_id = SQLITE3_CALL (prov, sqlite3_last_insert_rowid) (handle);
                                str = g_strdup_printf ("INSERT %lld %d", last_id, changes);
                                if (last_inserted_row)
                                        *last_inserted_row = make_last_inserted_set (cnc, stmt, last_id);
@@ -3864,7 +3912,7 @@ gda_sqlite_provider_statement_execute (GdaServerProvider *provider, GdaConnectio
                                                                             gda_connection_add_event (cnc, 
event);
                        }
                        gda_connection_internal_statement_executed (cnc, stmt, params, event);
-                       SQLITE3_CALL (sqlite3_reset) (_gda_sqlite_pstmt_get_stmt (ps));
+                       SQLITE3_CALL (prov, sqlite3_reset) (_gda_sqlite_pstmt_get_stmt (ps));
                        if (new_ps)
                                g_object_unref (ps);
 
@@ -3915,15 +3963,15 @@ scalar_gda_file_exists_func (sqlite3_context *context, int argc, sqlite3_value *
        const gchar *path;
 
        if (argc != 1) {
-               SQLITE3_CALL (sqlite3_result_error) (context, _("Function requires one argument"), -1);
+               (s3r->sqlite3_result_error) (context, _("Function requires one argument"), -1);
                return;
        }
 
-       path = (gchar *) SQLITE3_CALL (sqlite3_value_text) (argv [0]);
+       path = (gchar *) (s3r->sqlite3_value_text) (argv [0]);
        if (g_file_test (path, G_FILE_TEST_EXISTS))
-               SQLITE3_CALL (sqlite3_result_int) (context, 1);
+               (s3r->sqlite3_result_int) (context, 1);
        else
-               SQLITE3_CALL (sqlite3_result_int) (context, 0);
+               (s3r->sqlite3_result_int) (context, 0);
 }
 
 
@@ -3936,18 +3984,18 @@ scalar_gda_hex_print_func (sqlite3_context *context, int argc, sqlite3_value **a
        gchar *str;
 
        if (argc != 1) {
-               SQLITE3_CALL (sqlite3_result_error) (context, _("Function requires one argument"), -1);
+               (s3r->sqlite3_result_error) (context, _("Function requires one argument"), -1);
                return;
        }
 
        bin = gda_binary_new ();
-       guchar* buffer = (guchar*) SQLITE3_CALL (sqlite3_value_blob) (argv [0]);
+       guchar* buffer = (guchar*) (s3r->sqlite3_value_blob) (argv [0]);
        if (!buffer) {
                gda_binary_free (bin);
-               SQLITE3_CALL (sqlite3_result_null) (context);
+               (s3r->sqlite3_result_null) (context);
                return;
        }
-       glong length = SQLITE3_CALL (sqlite3_value_bytes) (argv [0]);
+       glong length = (s3r->sqlite3_value_bytes) (argv [0]);
        gda_binary_set_data (bin, buffer, length);
        g_free (free);
        gda_value_take_binary ((value = gda_value_new (GDA_TYPE_BINARY)), bin);
@@ -3955,7 +4003,7 @@ scalar_gda_hex_print_func (sqlite3_context *context, int argc, sqlite3_value **a
        str = gda_data_handler_get_str_from_value (dh, value);
 
        gda_value_free (value);
-       SQLITE3_CALL (sqlite3_result_text) (context, str, -1, g_free);
+       (s3r->sqlite3_result_text) (context, str, -1, g_free);
 }
 
 static void
@@ -3968,18 +4016,18 @@ scalar_gda_hex_print_func2 (sqlite3_context *context, int argc, sqlite3_value **
        gint size;
 
        if (argc != 2) {
-               SQLITE3_CALL (sqlite3_result_error) (context, _("Function requires two arguments"), -1);
+               (s3r->sqlite3_result_error) (context, _("Function requires two arguments"), -1);
                return;
        }
 
        bin = gda_binary_new ();
-       guchar* buffer = (guchar*) SQLITE3_CALL (sqlite3_value_blob) (argv [0]);
+       guchar* buffer = (guchar*) (s3r->sqlite3_value_blob) (argv [0]);
        if (!buffer) {
                gda_binary_free (bin);
-               SQLITE3_CALL (sqlite3_result_null) (context);
+               (s3r->sqlite3_result_null) (context);
                return;
        }
-       glong length = SQLITE3_CALL (sqlite3_value_bytes) (argv [0]);
+       glong length = (s3r->sqlite3_value_bytes) (argv [0]);
        gda_binary_set_data (bin, buffer, length);
        gda_value_take_binary ((value = gda_value_new (GDA_TYPE_BINARY)), bin);
        dh = gda_data_handler_get_default (GDA_TYPE_BINARY);
@@ -3987,9 +4035,9 @@ scalar_gda_hex_print_func2 (sqlite3_context *context, int argc, sqlite3_value **
 
        gda_value_free (value);
 
-       size = SQLITE3_CALL (sqlite3_value_int) (argv [1]);
+       size = (s3r->sqlite3_value_int) (argv [1]);
 
-       SQLITE3_CALL (sqlite3_result_text) (context, str, size, g_free);
+       (s3r->sqlite3_result_text) (context, str, size, g_free);
 }
 
 static void
@@ -3999,25 +4047,25 @@ scalar_rmdiacr (sqlite3_context *context, int argc, sqlite3_value **argv)
        CaseModif ncase = CASE_UNCHANGED;
 
        if (argc == 2) {
-               data = (gchar*) SQLITE3_CALL (sqlite3_value_text) (argv [1]);
+               data = (gchar*) (s3r->sqlite3_value_text) (argv [1]);
                if ((*data == 'u') || (*data == 'U'))
                        ncase = CASE_UP;
                else if ((*data == 'l') || (*data == 'l'))
                        ncase = CASE_DOWN;
        }
        else if (argc != 1) {
-               SQLITE3_CALL (sqlite3_result_error) (context, _("Function requires one or two arguments"), 
-1);
+               (s3r->sqlite3_result_error) (context, _("Function requires one or two arguments"), -1);
                return;
        }
 
-       data = (gchar*) SQLITE3_CALL (sqlite3_value_text) (argv [0]);
+       data = (gchar*) (s3r->sqlite3_value_text) (argv [0]);
        if (!data) {
-               SQLITE3_CALL (sqlite3_result_null) (context);
+               (s3r->sqlite3_result_null) (context);
                return;
        }
 
        tmp = remove_diacritics_and_change_case (data, -1, ncase);
-       SQLITE3_CALL (sqlite3_result_text) (context, tmp, -1, g_free);
+       (s3r->sqlite3_result_text) (context, tmp, -1, g_free);
 }
 
 static void
@@ -4026,18 +4074,18 @@ scalar_lower (sqlite3_context *context, int argc, sqlite3_value **argv)
        gchar *data, *tmp;
 
        if (argc != 1) {
-               SQLITE3_CALL (sqlite3_result_error) (context, _("Function requires one argument"), -1);
+               (s3r->sqlite3_result_error) (context, _("Function requires one argument"), -1);
                return;
        }
 
-       data = (gchar*) SQLITE3_CALL (sqlite3_value_text) (argv [0]);
+       data = (gchar*) (s3r->sqlite3_value_text) (argv [0]);
        if (!data) {
-               SQLITE3_CALL (sqlite3_result_null) (context);
+               (s3r->sqlite3_result_null) (context);
                return;
        }
 
        tmp = g_utf8_strdown (data, -1);
-       SQLITE3_CALL (sqlite3_result_text) (context, tmp, -1, g_free);
+       (s3r->sqlite3_result_text) (context, tmp, -1, g_free);
 }
 
 static void
@@ -4046,18 +4094,18 @@ scalar_upper (sqlite3_context *context, int argc, sqlite3_value **argv)
        gchar *data, *tmp;
 
        if (argc != 1) {
-               SQLITE3_CALL (sqlite3_result_error) (context, _("Function requires one argument"), -1);
+               (s3r->sqlite3_result_error) (context, _("Function requires one argument"), -1);
                return;
        }
 
-       data = (gchar*) SQLITE3_CALL (sqlite3_value_text) (argv [0]);
+       data = (gchar*) (s3r->sqlite3_value_text) (argv [0]);
        if (!data) {
-               SQLITE3_CALL (sqlite3_result_null) (context);
+               (s3r->sqlite3_result_null) (context);
                return;
        }
 
        tmp = g_utf8_strup (data, -1);
-       SQLITE3_CALL (sqlite3_result_text) (context, tmp, -1, g_free);
+       (s3r->sqlite3_result_text) (context, tmp, -1, g_free);
 }
 
 static void
@@ -4069,17 +4117,17 @@ scalar_gda_hex_func (sqlite3_context *context, int argc, sqlite3_value **argv)
        gint i;
 
        if (argc != 1) {
-               SQLITE3_CALL (sqlite3_result_error) (context, _("Function requires one argument"), -1);
+               (s3r->sqlite3_result_error) (context, _("Function requires one argument"), -1);
                return;
        }
 
-       data = (guchar*) SQLITE3_CALL (sqlite3_value_blob) (argv [0]);
+       data = (guchar*) (s3r->sqlite3_value_blob) (argv [0]);
        if (!data) {
-               SQLITE3_CALL (sqlite3_result_null) (context);
+               (s3r->sqlite3_result_null) (context);
                return;
        }
 
-       length = SQLITE3_CALL (sqlite3_value_bytes) (argv [0]);
+       length = (s3r->sqlite3_value_bytes) (argv [0]);
        string = g_string_new ("");
        for (i = 0; i < length; i++) {
                if ((i > 0) && (i % 4 == 0))
@@ -4087,7 +4135,7 @@ scalar_gda_hex_func (sqlite3_context *context, int argc, sqlite3_value **argv)
                g_string_append_printf (string, "%02x", data [i]);
        }
 
-       SQLITE3_CALL (sqlite3_result_text) (context, string->str, -1, g_free);
+       (s3r->sqlite3_result_text) (context, string->str, -1, g_free);
        g_string_free (string, FALSE);
 }
 
@@ -4101,18 +4149,18 @@ scalar_gda_hex_func2 (sqlite3_context *context, int argc, sqlite3_value **argv)
        guint size;
 
        if (argc != 2) {
-               SQLITE3_CALL (sqlite3_result_error) (context, _("Function requires two arguments"), -1);
+               (s3r->sqlite3_result_error) (context, _("Function requires two arguments"), -1);
                return;
        }
 
-       data = (guchar*) SQLITE3_CALL (sqlite3_value_blob) (argv [0]);
+       data = (guchar*) (s3r->sqlite3_value_blob) (argv [0]);
        if (!data) {
-               SQLITE3_CALL (sqlite3_result_null) (context);
+               (s3r->sqlite3_result_null) (context);
                return;
        }
 
-       length = SQLITE3_CALL (sqlite3_value_bytes) (argv [0]);
-       size = SQLITE3_CALL (sqlite3_value_int) (argv [1]);
+       length = (s3r->sqlite3_value_bytes) (argv [0]);
+       size = (s3r->sqlite3_value_int) (argv [1]);
 
        string = g_string_new ("");
        for (i = 0; (i < length) && (string->len < (size / 2) * 2 + 2); i++) {
@@ -4123,7 +4171,7 @@ scalar_gda_hex_func2 (sqlite3_context *context, int argc, sqlite3_value **argv)
 
        if (string->len > size)
                string->str[size] = 0;
-       SQLITE3_CALL (sqlite3_result_text) (context, string->str, -1, g_free);
+       (s3r->sqlite3_result_text) (context, string->str, -1, g_free);
        g_string_free (string, FALSE);
 }
 
@@ -4141,24 +4189,24 @@ scalar_regexp_func (sqlite3_context *context, int argc, sqlite3_value **argv)
        static GHashTable *re_hash = NULL; /* hash of GRegex */
 
        if ((argc != 2) && (argc != 3)) {
-               SQLITE3_CALL (sqlite3_result_error) (context, _("Function requires two or three arguments"), 
-1);
+               (s3r->sqlite3_result_error) (context, _("Function requires two or three arguments"), -1);
                return;
        }
 
-       str = (gchar*) SQLITE3_CALL (sqlite3_value_text) (argv [1]);
+       str = (gchar*) (s3r->sqlite3_value_text) (argv [1]);
        if (!str) {
-               SQLITE3_CALL (sqlite3_result_null) (context);
+               (s3r->sqlite3_result_null) (context);
                return;
        }
 
-       pattern = (gchar*) SQLITE3_CALL (sqlite3_value_text) (argv [0]);
+       pattern = (gchar*) (s3r->sqlite3_value_text) (argv [0]);
        if (!pattern) {
-               SQLITE3_CALL (sqlite3_result_null) (context);
+               (s3r->sqlite3_result_null) (context);
                return;
        }
 
        if (argc == 3)
-               options = (gchar*) SQLITE3_CALL (sqlite3_value_text) (argv [2]);
+               options = (gchar*) (s3r->sqlite3_value_text) (argv [2]);
 
        if (options) {
                const gchar *ptr;
@@ -4199,9 +4247,9 @@ scalar_regexp_func (sqlite3_context *context, int argc, sqlite3_value **argv)
                                       error && error->message ? error->message : _("Invalid regular 
expression"));
                        g_clear_error (&error);
                        if (as_boolean)
-                               SQLITE3_CALL (sqlite3_result_int) (context, 0);
+                               (s3r->sqlite3_result_int) (context, 0);
                        else
-                               SQLITE3_CALL (sqlite3_result_null) (context);
+                               (s3r->sqlite3_result_null) (context);
 
                        g_string_free (sig, TRUE);
                        return;
@@ -4227,19 +4275,19 @@ scalar_regexp_func (sqlite3_context *context, int argc, sqlite3_value **argv)
 
        if (as_boolean) {
                if (g_regex_match (regex, str, 0, NULL))
-                       SQLITE3_CALL (sqlite3_result_int) (context, 1);
+                       (s3r->sqlite3_result_int) (context, 1);
                else
-                       SQLITE3_CALL (sqlite3_result_int) (context, 0);
+                       (s3r->sqlite3_result_int) (context, 0);
        }
        else {
                GMatchInfo *match_info;
                g_regex_match (regex, str, 0, &match_info);
                if (g_match_info_matches (match_info)) {
                        gchar *word = g_match_info_fetch (match_info, 0);
-                       SQLITE3_CALL (sqlite3_result_text) (context, word, -1, g_free);
+                       (s3r->sqlite3_result_text) (context, word, -1, g_free);
                }
                else
-                       SQLITE3_CALL (sqlite3_result_null) (context);
+                       (s3r->sqlite3_result_null) (context);
                g_match_info_free (match_info);
        }
 }
@@ -4248,7 +4296,7 @@ static void
 scalar_regexp_match_func (sqlite3_context *context, int argc, sqlite3_value **argv)
 {
        if ((argc != 2) && (argc != 3)) {
-               SQLITE3_CALL (sqlite3_result_error) (context, _("Function requires two or three arguments"), 
-1);
+               (s3r->sqlite3_result_error) (context, _("Function requires two or three arguments"), -1);
                return;
        }
 
@@ -4269,7 +4317,11 @@ gda_sqlite_free_cnc_data (SqliteConnectionData *cdata)
                return;
 
        if (cdata->connection) {
-               SQLITE3_CALL (sqlite3_close_v2) (cdata->connection);
+               GdaSqliteProvider *prov = g_weak_ref_get (&cdata->provider);
+               if (prov != NULL) {
+                       (s3r->sqlite3_close_v2) (cdata->connection);
+                       g_object_unref (prov);
+               }
        }
        g_free (cdata->file);
        if (cdata->types_hash)
@@ -4353,6 +4405,20 @@ gda_sqlite_provider_unescape_string (G_GNUC_UNUSED GdaServerProvider *provider,
        return retval;
 }
 
+/**
+ * gda_sqlite_provider_get_api:
+ * @prov: a #GdaSqliteProvider to get API loaded from library in use
+ *
+ * Returns: a pointer to internal loaded API from library
+ */
+gpointer
+gda_sqlite_provider_get_api (GdaSqliteProvider *prov) {
+       GdaSqliteProviderClass *klass = GDA_SQLITE_PROVIDER_GET_CLASS (prov);
+       if (klass->get_api != NULL) {
+               return klass->get_api (prov);
+       }
+       return NULL;
+}
 
 /* GdaProviderMeta implementations */
 
diff --git a/libgda/sqlite/gda-sqlite-provider.h b/libgda/sqlite/gda-sqlite-provider.h
index 0d1e8b640..aae1b66da 100644
--- a/libgda/sqlite/gda-sqlite-provider.h
+++ b/libgda/sqlite/gda-sqlite-provider.h
@@ -35,11 +35,15 @@ G_DECLARE_DERIVABLE_TYPE (GdaSqliteProvider, gda_sqlite_provider, GDA, SQLITE_PR
 struct _GdaSqliteProviderClass {
        GdaServerProviderClass parent_class;
 
+       gpointer (*get_api) (GdaSqliteProvider *prov);
+
        /* Padding for future expansion */
        void (*_gda_reserved1) (void);
        void (*_gda_reserved2) (void);
 };
 
+gpointer gda_sqlite_provider_get_api (GdaSqliteProvider *prov);
+
 G_END_DECLS
 
 #endif
diff --git a/libgda/sqlite/gda-sqlite-pstmt.c b/libgda/sqlite/gda-sqlite-pstmt.c
index e3598a1bb..762d68984 100644
--- a/libgda/sqlite/gda-sqlite-pstmt.c
+++ b/libgda/sqlite/gda-sqlite-pstmt.c
@@ -66,7 +66,11 @@ _gda_sqlite_pstmt_dispose (GObject *object)
 
        /* free memory */
        if (priv->sqlite_stmt != NULL) {
-               SQLITE3_CALL (sqlite3_finalize) (priv->sqlite_stmt);
+               GdaSqliteProvider *prov = g_weak_ref_get (&priv->provider);
+               if (prov != NULL) {
+                       SQLITE3_CALL (prov, sqlite3_finalize) (priv->sqlite_stmt);
+                       g_object_unref (prov);
+               }
                priv->sqlite_stmt = NULL;
        }
 
@@ -74,6 +78,7 @@ _gda_sqlite_pstmt_dispose (GObject *object)
                g_hash_table_destroy (priv->rowid_hash);
                priv->rowid_hash = NULL;
        }
+       g_weak_ref_clear (&priv->provider);
 
        /* chain to parent class */
        G_OBJECT_CLASS (_gda_sqlite_pstmt_parent_class)->finalize (object);
diff --git a/libgda/sqlite/gda-sqlite-recordset.c b/libgda/sqlite/gda-sqlite-recordset.c
index bc7e703ee..6a5044491 100644
--- a/libgda/sqlite/gda-sqlite-recordset.c
+++ b/libgda/sqlite/gda-sqlite-recordset.c
@@ -63,6 +63,7 @@ static GdaRow *fetch_next_sqlite_row (GdaSqliteRecordset *model, gboolean do_sto
 static void virt_cnc_set_working_obj (GdaConnection *cnc, GdaSqliteRecordset *model);
 
 struct _GdaSqliteRecordsetPrivate {
+       GWeakRef      provider;
        gboolean      empty_forced;
        gint          next_row_num;
        GdaRow       *tmp_row; /* used in cursor mode */
@@ -81,6 +82,7 @@ gda_sqlite_recordset_init (GdaSqliteRecordset *recset,
        recset->priv = g_new0 (GdaSqliteRecordsetPrivate, 1);
        recset->priv->next_row_num = 0;
        recset->priv->empty_forced = FALSE;
+       g_weak_ref_init (&recset->priv->provider, NULL);
 }
 
 static void
@@ -117,7 +119,11 @@ gda_sqlite_recordset_dispose (GObject *object)
                if (ps != NULL) {
                        _gda_sqlite_pstmt_set_is_used (ps, FALSE);
                        virt_cnc_set_working_obj (gda_data_select_get_connection ((GdaDataSelect*) recset), 
recset);
-                       SQLITE3_CALL (sqlite3_reset) (_gda_sqlite_pstmt_get_stmt (ps));
+                       GdaSqliteProvider *prov = g_weak_ref_get (&recset->priv->provider);
+                       if (prov != NULL) {
+                               SQLITE3_CALL (prov, sqlite3_reset) (_gda_sqlite_pstmt_get_stmt (ps));
+                               g_object_unref (prov);
+                       }
                        virt_cnc_set_working_obj (gda_data_select_get_connection ((GdaDataSelect*) recset), 
NULL);
                }
 
@@ -125,6 +131,7 @@ gda_sqlite_recordset_dispose (GObject *object)
                        g_object_unref (recset->priv->tmp_row);
                        recset->priv->tmp_row = NULL;
                }
+               g_weak_ref_clear (&recset->priv->provider);
        }
 
        parent_class->dispose (object);
@@ -246,10 +253,11 @@ _gda_sqlite_recordset_new (GdaConnection *cnc, GdaSqlitePStmt *ps, GdaSet *exec_
 
         if (!cdata->types_hash)
                 _gda_sqlite_compute_types_hash (cdata);
+       GdaSqliteProvider *prov = GDA_SQLITE_PROVIDER (gda_connection_get_provider (cnc));
 
         /* make sure @ps reports the correct number of columns */
        if (gda_pstmt_get_ncols (_GDA_PSTMT (ps)) < 0)
-               gda_pstmt_set_cols (_GDA_PSTMT (ps), SQLITE3_CALL (sqlite3_column_count) 
(_gda_sqlite_pstmt_get_stmt (ps)) -
+               gda_pstmt_set_cols (_GDA_PSTMT (ps), SQLITE3_CALL (prov, sqlite3_column_count) 
(_gda_sqlite_pstmt_get_stmt (ps)) -
                        _gda_sqlite_pstmt_get_nb_rowid_columns (ps), gda_pstmt_get_types (_GDA_PSTMT (ps)));
 
         /* completing ps */
@@ -290,9 +298,9 @@ _gda_sqlite_recordset_new (GdaConnection *cnc, GdaSqlitePStmt *ps, GdaSet *exec_
                        gint real_col = i + _gda_sqlite_pstmt_get_nb_rowid_columns (ps);
                        
                        column = GDA_COLUMN (list->data);
-                       gda_column_set_description (column, SQLITE3_CALL (sqlite3_column_name) 
(_gda_sqlite_pstmt_get_stmt (ps), real_col));
-                       gda_column_set_name (column, SQLITE3_CALL (sqlite3_column_name) 
(_gda_sqlite_pstmt_get_stmt (ps), real_col));
-                       gda_column_set_dbms_type (column, SQLITE3_CALL (sqlite3_column_decltype) 
(_gda_sqlite_pstmt_get_stmt (ps), real_col));
+                       gda_column_set_description (column, SQLITE3_CALL (prov, sqlite3_column_name) 
(_gda_sqlite_pstmt_get_stmt (ps), real_col));
+                       gda_column_set_name (column, SQLITE3_CALL (prov, sqlite3_column_name) 
(_gda_sqlite_pstmt_get_stmt (ps), real_col));
+                       gda_column_set_dbms_type (column, SQLITE3_CALL (prov, sqlite3_column_decltype) 
(_gda_sqlite_pstmt_get_stmt (ps), real_col));
                        if (gda_pstmt_get_types (_GDA_PSTMT (ps)) [i] != GDA_TYPE_NULL)
                                gda_column_set_g_type (column, gda_pstmt_get_types (_GDA_PSTMT (ps)) [i]);
                }
@@ -335,12 +343,15 @@ fuzzy_get_gtype (SqliteConnectionData *cdata, GdaSqlitePStmt *ps, gint colnum)
 
        if (gda_pstmt_get_types (_GDA_PSTMT (ps)) [colnum] != GDA_TYPE_NULL)
                return gda_pstmt_get_types (_GDA_PSTMT (ps)) [colnum];
-       
-       ctype = SQLITE3_CALL (sqlite3_column_origin_name) (_gda_sqlite_pstmt_get_stmt (ps), real_col);
+
+       GdaSqliteProvider *prov = _gda_sqlite_pstmt_get_provider (ps);
+       g_return_val_if_fail (prov != NULL, G_TYPE_INVALID);
+
+       ctype = SQLITE3_CALL (prov, sqlite3_column_origin_name) (_gda_sqlite_pstmt_get_stmt (ps), real_col);
        if (ctype && !strcmp (ctype, "rowid"))
                gtype = G_TYPE_INT64;
        else {
-               ctype = SQLITE3_CALL (sqlite3_column_decltype) (_gda_sqlite_pstmt_get_stmt (ps), real_col);
+               ctype = SQLITE3_CALL (prov, sqlite3_column_decltype) (_gda_sqlite_pstmt_get_stmt (ps), 
real_col);
                
                if (ctype) {
                        GType *pg;
@@ -348,7 +359,7 @@ fuzzy_get_gtype (SqliteConnectionData *cdata, GdaSqlitePStmt *ps, gint colnum)
                        gtype = pg ? *pg : GDA_TYPE_NULL;
                }
                if (gtype == GDA_TYPE_NULL) 
-                       gtype = _gda_sqlite_compute_g_type (SQLITE3_CALL (sqlite3_column_type) 
(_gda_sqlite_pstmt_get_stmt (ps), real_col));
+                       gtype = _gda_sqlite_compute_g_type (SQLITE3_CALL (prov, sqlite3_column_type) 
(_gda_sqlite_pstmt_get_stmt (ps), real_col));
        }
 
        return gtype;
@@ -371,9 +382,11 @@ fetch_next_sqlite_row (GdaSqliteRecordset *model, gboolean do_store, GError **er
        GdaSqlitePStmt *ps;
        GdaRow *prow = NULL;
        GdaConnection *cnc;
+       GdaSqliteProvider *prov;
        glong length;
 
        cnc = gda_data_select_get_connection ((GdaDataSelect*) model);
+       prov = GDA_SQLITE_PROVIDER (gda_connection_get_provider (cnc));
        cdata = (SqliteConnectionData*) gda_connection_internal_get_provider_data_error (cnc, error);
        if (!cdata)
                return NULL;
@@ -384,7 +397,7 @@ fetch_next_sqlite_row (GdaSqliteRecordset *model, gboolean do_store, GError **er
        if (model->priv->empty_forced)
                rc = SQLITE_DONE;
        else            
-               rc = SQLITE3_CALL (sqlite3_step) (_gda_sqlite_pstmt_get_stmt (ps));
+               rc = SQLITE3_CALL (prov, sqlite3_step) (_gda_sqlite_pstmt_get_stmt (ps));
        switch (rc) {
        case  SQLITE_ROW: {
                gint col, real_col;
@@ -402,12 +415,12 @@ fetch_next_sqlite_row (GdaSqliteRecordset *model, gboolean do_store, GError **er
                                        if (_gda_sqlite_pstmt_get_rowid_hash (ps)) {
                                                gint oidcol = 0;
                                                const char *ctable;
-                                               ctable = SQLITE3_CALL (sqlite3_column_name) 
(_gda_sqlite_pstmt_get_stmt (ps), real_col);
+                                               ctable = SQLITE3_CALL (prov, sqlite3_column_name) 
(_gda_sqlite_pstmt_get_stmt (ps), real_col);
                                                if (ctable)
                                                        oidcol = GPOINTER_TO_INT (g_hash_table_lookup 
(_gda_sqlite_pstmt_get_rowid_hash (ps),
                                                                                                       
ctable));
                                                if (oidcol == 0) {
-                                                       ctable = SQLITE3_CALL (sqlite3_column_table_name) 
(_gda_sqlite_pstmt_get_stmt (ps), real_col);
+                                                       ctable = SQLITE3_CALL (prov, 
sqlite3_column_table_name) (_gda_sqlite_pstmt_get_stmt (ps), real_col);
                                                        if (ctable)
                                                                oidcol = GPOINTER_TO_INT (g_hash_table_lookup 
(_gda_sqlite_pstmt_get_rowid_hash (ps),
                                                                                                              
 ctable));
@@ -432,13 +445,13 @@ fetch_next_sqlite_row (GdaSqliteRecordset *model, gboolean do_store, GError **er
                        /* fill GValue */
                        value = gda_row_get_value (prow, col);
                        GError *may_error;
-                       may_error = (GError*) SQLITE3_CALL (sqlite3_column_blob) (_gda_sqlite_pstmt_get_stmt 
(ps), real_col);
+                       may_error = (GError*) SQLITE3_CALL (prov, sqlite3_column_blob) 
(_gda_sqlite_pstmt_get_stmt (ps), 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) (_gda_sqlite_pstmt_get_stmt (ps), 
real_col) == NULL) {
+                       else if (SQLITE3_CALL (prov, sqlite3_column_text) (_gda_sqlite_pstmt_get_stmt (ps), 
real_col) == NULL) {
                                /* we have a NULL value */
                                gda_value_set_null (value);
                        }
@@ -449,7 +462,7 @@ fetch_next_sqlite_row (GdaSqliteRecordset *model, gboolean do_store, GError **er
                                        ;
                                else if (type == G_TYPE_INT) {
                                        gint64 i;
-                                       i = SQLITE3_CALL (sqlite3_column_int64) (_gda_sqlite_pstmt_get_stmt 
(ps), real_col);
+                                       i = SQLITE3_CALL (prov, sqlite3_column_int64) 
(_gda_sqlite_pstmt_get_stmt (ps), real_col);
                                        if ((i > G_MAXINT) || (i < G_MININT)) {
                                                GError *lerror = NULL;
                                                g_set_error (&lerror, GDA_SERVER_PROVIDER_ERROR,
@@ -462,7 +475,7 @@ fetch_next_sqlite_row (GdaSqliteRecordset *model, gboolean do_store, GError **er
                                }
                                else if (type == G_TYPE_UINT) {
                                        guint64 i;
-                                       i = (gint64) SQLITE3_CALL (sqlite3_column_int64) 
(_gda_sqlite_pstmt_get_stmt (ps), real_col);
+                                       i = (gint64) SQLITE3_CALL (prov, sqlite3_column_int64) 
(_gda_sqlite_pstmt_get_stmt (ps), real_col);
                                        if (i > G_MAXUINT) {
                                                GError *lerror = NULL;
                                                g_set_error (&lerror, GDA_SERVER_PROVIDER_ERROR,
@@ -474,19 +487,19 @@ fetch_next_sqlite_row (GdaSqliteRecordset *model, gboolean do_store, GError **er
                                                g_value_set_uint (value, (gint) i);
                                }
                                else if (type == G_TYPE_INT64)
-                                       g_value_set_int64 (value, SQLITE3_CALL (sqlite3_column_int64) 
(_gda_sqlite_pstmt_get_stmt (ps), real_col));
+                                       g_value_set_int64 (value, SQLITE3_CALL (prov, sqlite3_column_int64) 
(_gda_sqlite_pstmt_get_stmt (ps), real_col));
                                else if (type == G_TYPE_UINT64)
-                                       g_value_set_uint64 (value, (guint64) SQLITE3_CALL 
(sqlite3_column_int64) (_gda_sqlite_pstmt_get_stmt (ps),
+                                       g_value_set_uint64 (value, (guint64) SQLITE3_CALL (prov, 
sqlite3_column_int64) (_gda_sqlite_pstmt_get_stmt (ps),
                                                                                                   real_col));
                                else if (type == G_TYPE_DOUBLE)
-                                       g_value_set_double (value, SQLITE3_CALL (sqlite3_column_double) 
(_gda_sqlite_pstmt_get_stmt (ps),
+                                       g_value_set_double (value, SQLITE3_CALL (prov, sqlite3_column_double) 
(_gda_sqlite_pstmt_get_stmt (ps),
                                                                                          real_col));
                                else if (type == G_TYPE_STRING)
-                                       g_value_set_string (value, (gchar *) SQLITE3_CALL 
(sqlite3_column_text) (_gda_sqlite_pstmt_get_stmt (ps),
+                                       g_value_set_string (value, (gchar *) SQLITE3_CALL (prov, 
sqlite3_column_text) (_gda_sqlite_pstmt_get_stmt (ps),
                                                                                                  real_col));
                                else if (type == GDA_TYPE_TEXT) {
                                        GdaText *text = gda_text_new ();
-                                       gda_text_set_string (text, (const gchar *) SQLITE3_CALL 
(sqlite3_column_text) (_gda_sqlite_pstmt_get_stmt (ps),
+                                       gda_text_set_string (text, (const gchar *) SQLITE3_CALL (prov, 
sqlite3_column_text) (_gda_sqlite_pstmt_get_stmt (ps),
                                                                                                  real_col));
                                        g_value_take_boxed (value, text);
                                }
@@ -494,9 +507,9 @@ fetch_next_sqlite_row (GdaSqliteRecordset *model, gboolean do_store, GError **er
                                        GdaBinary *bin;
                                        
                                        bin = gda_binary_new ();
-                                       length = SQLITE3_CALL (sqlite3_column_bytes) 
(_gda_sqlite_pstmt_get_stmt (ps), real_col);
+                                       length = SQLITE3_CALL (prov, sqlite3_column_bytes) 
(_gda_sqlite_pstmt_get_stmt (ps), real_col);
                                        if (length > 0) {
-                                               gda_binary_set_data (bin, SQLITE3_CALL (sqlite3_column_blob) 
(_gda_sqlite_pstmt_get_stmt (ps), /* Flawfinder: ignore */
+                                               gda_binary_set_data (bin, SQLITE3_CALL (prov, 
sqlite3_column_blob) (_gda_sqlite_pstmt_get_stmt (ps), /* Flawfinder: ignore */
                                                                                                       
real_col), length);
                                        }
                                        gda_value_take_binary (value, bin);
@@ -507,12 +520,12 @@ fetch_next_sqlite_row (GdaSqliteRecordset *model, gboolean do_store, GError **er
 
                                        if (_gda_sqlite_pstmt_get_rowid_hash (ps)) {
                                                const char *ctable;
-                                               ctable = SQLITE3_CALL (sqlite3_column_name) 
(_gda_sqlite_pstmt_get_stmt (ps), real_col);
+                                               ctable = SQLITE3_CALL (prov, sqlite3_column_name) 
(_gda_sqlite_pstmt_get_stmt (ps), real_col);
                                                if (ctable)
                                                        oidcol = GPOINTER_TO_INT (g_hash_table_lookup 
(_gda_sqlite_pstmt_get_rowid_hash (ps),
                                                                                                       
ctable));
                                                if (oidcol == 0) {
-                                                       ctable = SQLITE3_CALL (sqlite3_column_table_name) 
(_gda_sqlite_pstmt_get_stmt (ps), real_col);
+                                                       ctable = SQLITE3_CALL (prov, 
sqlite3_column_table_name) (_gda_sqlite_pstmt_get_stmt (ps), real_col);
                                                        if (ctable)
                                                                oidcol = GPOINTER_TO_INT (g_hash_table_lookup 
(_gda_sqlite_pstmt_get_rowid_hash (ps),
                                                                                                              
 ctable));
@@ -520,14 +533,14 @@ fetch_next_sqlite_row (GdaSqliteRecordset *model, gboolean do_store, GError **er
                                        }
                                        if (oidcol != 0) {
                                                gint64 rowid;
-                                               rowid = SQLITE3_CALL (sqlite3_column_int64) 
(_gda_sqlite_pstmt_get_stmt (ps), oidcol - 1); /* remove 1
+                                               rowid = SQLITE3_CALL (prov, sqlite3_column_int64) 
(_gda_sqlite_pstmt_get_stmt (ps), 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) (_gda_sqlite_pstmt_get_stmt (ps),
+                                                                              SQLITE3_CALL (prov, 
sqlite3_column_database_name) (_gda_sqlite_pstmt_get_stmt (ps),
                                                                                                            
real_col),
-                                                                              SQLITE3_CALL 
(sqlite3_column_table_name) (_gda_sqlite_pstmt_get_stmt (ps),
+                                                                              SQLITE3_CALL (prov, 
sqlite3_column_table_name) (_gda_sqlite_pstmt_get_stmt (ps),
                                                                                                         
real_col),
-                                                                              SQLITE3_CALL 
(sqlite3_column_origin_name) (_gda_sqlite_pstmt_get_stmt (ps),
+                                                                              SQLITE3_CALL (prov, 
sqlite3_column_origin_name) (_gda_sqlite_pstmt_get_stmt (ps),
                                                                                                          
real_col),
                                                                              rowid);
                                        }
@@ -547,17 +560,17 @@ fetch_next_sqlite_row (GdaSqliteRecordset *model, gboolean do_store, GError **er
                                        }
                                }
                                else if (type == G_TYPE_BOOLEAN)
-                                       g_value_set_boolean (value, SQLITE3_CALL (sqlite3_column_int) 
(_gda_sqlite_pstmt_get_stmt (ps), real_col) == 0 ? FALSE : TRUE);
+                                       g_value_set_boolean (value, SQLITE3_CALL (prov, sqlite3_column_int) 
(_gda_sqlite_pstmt_get_stmt (ps), 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) (_gda_sqlite_pstmt_get_stmt (ps),
+                                                                    (gchar *) SQLITE3_CALL (prov, 
sqlite3_column_text) (_gda_sqlite_pstmt_get_stmt (ps),
                                                                                                    
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) 
(_gda_sqlite_pstmt_get_stmt (ps), real_col));
+                                                            (gchar *) SQLITE3_CALL (prov, 
sqlite3_column_text) (_gda_sqlite_pstmt_get_stmt (ps), real_col));
                                                gda_row_invalidate_value_e (prow, value, lerror);
                                        }
                                        else
@@ -566,13 +579,13 @@ fetch_next_sqlite_row (GdaSqliteRecordset *model, gboolean do_store, GError **er
                                else if (type == GDA_TYPE_TIME) {
                                        GdaTime* timegda = gda_time_new ();
                                        if (!gda_parse_iso8601_time (timegda,
-                                                                    (gchar *) SQLITE3_CALL 
(sqlite3_column_text) (_gda_sqlite_pstmt_get_stmt (ps),
+                                                                    (gchar *) SQLITE3_CALL (prov, 
sqlite3_column_text) (_gda_sqlite_pstmt_get_stmt (ps),
                                                                                                    
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) 
(_gda_sqlite_pstmt_get_stmt (ps), real_col));
+                                                            (gchar *) SQLITE3_CALL (prov, 
sqlite3_column_text) (_gda_sqlite_pstmt_get_stmt (ps), real_col));
                                                gda_row_invalidate_value_e (prow, value, lerror);
                                        }
                                        else {
@@ -584,14 +597,14 @@ fetch_next_sqlite_row (GdaSqliteRecordset *model, gboolean do_store, GError **er
                                }
                                else if (g_type_is_a (type, G_TYPE_DATE_TIME)) {
                                        GDateTime* timestamp = gda_parse_iso8601_timestamp (
-                                                                         (gchar *) SQLITE3_CALL 
(sqlite3_column_text) (_gda_sqlite_pstmt_get_stmt (ps),
+                                                                         (gchar *) SQLITE3_CALL (prov, 
sqlite3_column_text) (_gda_sqlite_pstmt_get_stmt (ps),
                                                                                real_col));
                                        if (timestamp == NULL) {
                                                GError *lerror = NULL;
                                                g_set_error (&lerror, GDA_SERVER_PROVIDER_ERROR,
                                                             GDA_SERVER_PROVIDER_DATA_ERROR,
                                                             _("Invalid timestamp '%s' (format should be 
YYYY-MM-DDTHH:MM:SS[.ms])"),
-                                                            (gchar *) SQLITE3_CALL (sqlite3_column_text) 
(_gda_sqlite_pstmt_get_stmt (ps), real_col));
+                                                            (gchar *) SQLITE3_CALL (prov, 
sqlite3_column_text) (_gda_sqlite_pstmt_get_stmt (ps), real_col));
                                                gda_row_invalidate_value_e (prow, value, lerror);
                                        }
                                        else {
@@ -601,7 +614,7 @@ fetch_next_sqlite_row (GdaSqliteRecordset *model, gboolean do_store, GError **er
                                }
                                else if (type == G_TYPE_CHAR) {
                                        gint64 i;
-                                       i = (gint64) SQLITE3_CALL (sqlite3_column_int64) 
(_gda_sqlite_pstmt_get_stmt (ps), real_col);
+                                       i = (gint64) SQLITE3_CALL (prov, sqlite3_column_int64) 
(_gda_sqlite_pstmt_get_stmt (ps), real_col);
                                        if ((i > G_MAXINT8) || (i < G_MININT8)) {
                                                GError *lerror = NULL;
                                                g_set_error (&lerror, GDA_SERVER_PROVIDER_ERROR,
@@ -614,7 +627,7 @@ fetch_next_sqlite_row (GdaSqliteRecordset *model, gboolean do_store, GError **er
                                }
                                else if (type == G_TYPE_UCHAR) {
                                        gint64 i;
-                                       i = (gint64) SQLITE3_CALL (sqlite3_column_int64) 
(_gda_sqlite_pstmt_get_stmt (ps), real_col);
+                                       i = (gint64) SQLITE3_CALL (prov, sqlite3_column_int64) 
(_gda_sqlite_pstmt_get_stmt (ps), real_col);
                                        if ((i > G_MAXUINT8) || (i < 0)) {
                                                GError *lerror = NULL;
                                                g_set_error (&lerror, GDA_SERVER_PROVIDER_ERROR,
@@ -627,7 +640,7 @@ fetch_next_sqlite_row (GdaSqliteRecordset *model, gboolean do_store, GError **er
                                }
                                else if (type == GDA_TYPE_SHORT) {
                                        gint64 i;
-                                       i = (gint64) SQLITE3_CALL (sqlite3_column_int64) 
(_gda_sqlite_pstmt_get_stmt (ps), real_col);
+                                       i = (gint64) SQLITE3_CALL (prov, sqlite3_column_int64) 
(_gda_sqlite_pstmt_get_stmt (ps), real_col);
                                        if ((i > G_MAXSHORT) || (i < G_MINSHORT)) {
                                                GError *lerror = NULL;
                                                g_set_error (&lerror, GDA_SERVER_PROVIDER_ERROR,
@@ -640,7 +653,7 @@ fetch_next_sqlite_row (GdaSqliteRecordset *model, gboolean do_store, GError **er
                                }
                                else if (type == GDA_TYPE_USHORT) {
                                        gint64 i;
-                                       i = (gint64) SQLITE3_CALL (sqlite3_column_int64) 
(_gda_sqlite_pstmt_get_stmt (ps), real_col);
+                                       i = (gint64) SQLITE3_CALL (prov, sqlite3_column_int64) 
(_gda_sqlite_pstmt_get_stmt (ps), real_col);
                                        if ((i > G_MAXUSHORT) || (i < 0)) {
                                                GError *lerror = NULL;
                                                g_set_error (&lerror, GDA_SERVER_PROVIDER_ERROR,
@@ -674,7 +687,7 @@ fetch_next_sqlite_row (GdaSqliteRecordset *model, gboolean do_store, GError **er
                break;
        case SQLITE_DONE:
                gda_data_select_set_advertized_nrows (GDA_DATA_SELECT (model), model->priv->next_row_num);
-               SQLITE3_CALL (sqlite3_reset) (_gda_sqlite_pstmt_get_stmt (ps));
+               SQLITE3_CALL (prov, sqlite3_reset) (_gda_sqlite_pstmt_get_stmt (ps));
                break;
        case SQLITE_READONLY:
        case SQLITE_MISUSE:
@@ -685,14 +698,14 @@ fetch_next_sqlite_row (GdaSqliteRecordset *model, gboolean do_store, GError **er
        case SQLITE_ERROR:
        default: {
                GError *lerror = NULL;
-               SQLITE3_CALL (sqlite3_reset) (_gda_sqlite_pstmt_get_stmt (ps));
+               SQLITE3_CALL (prov, sqlite3_reset) (_gda_sqlite_pstmt_get_stmt (ps));
                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));
+                                    "%s", SQLITE3_CALL (prov, 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));
diff --git a/libgda/sqlite/gda-sqlite.h b/libgda/sqlite/gda-sqlite.h
index 1b4864fac..bb1a4ae7c 100644
--- a/libgda/sqlite/gda-sqlite.h
+++ b/libgda/sqlite/gda-sqlite.h
@@ -29,27 +29,18 @@
 #include <libgda/libgda.h>
 #include <libgda/gda-data-handler.h>
 #include <libgda/gda-connection-private.h>
+#include <libgda/sqlite/gda-sqlite-provider.h>
 
 #ifdef WITH_BDBSQLITE
   #include <dbsql.h>
   #include "gda-symbols-util.h"
   #define SQLITE3_CALL(x) (s3r->x)
 #else
-  #ifdef STATIC_SQLITE
-    #include "sqlite-src/sqlite3.h"
-    #define SQLITE3_CALL(x) (x)
-  #else
-    #ifdef HAVE_SQLITE
-      #include <sqlite3.h>
-      #include "gda-symbols-util.h"
-      #define SQLITE3_CALL(x) (s3r->x)
-      #if (SQLITE_VERSION_NUMBER < 3005000)
-        typedef sqlite_int64 sqlite3_int64;
-      #endif
-    #else
-      #include "sqlite-src/sqlite3.h"
-      #define SQLITE3_CALL(x) (x)
-    #endif
+  #include <sqlite3.h>
+  #include "gda-symbols-util.h"
+  #define SQLITE3_CALL(p,x) (((Sqlite3ApiRoutines*) gda_sqlite_provider_get_api(p))->x)
+  #if (SQLITE_VERSION_NUMBER < 3005000)
+    typedef sqlite_int64 sqlite3_int64;
   #endif
 #endif
 
@@ -59,6 +50,7 @@
 typedef struct {
        GdaServerProviderConnectionData parent;
        sqlite3      *connection;
+       GWeakRef     provider;
        gchar        *file;
        GHashTable   *types_hash; /* key = type name, value = pointer to a GType */
        GType        *types_array;/* holds GType values, pointed by @types_hash */
diff --git a/libgda/sqlite/gda-symbols-util.c b/libgda/sqlite/gda-symbols-util.c
index 2349a76bb..aa74f0468 100644
--- a/libgda/sqlite/gda-symbols-util.c
+++ b/libgda/sqlite/gda-symbols-util.c
@@ -141,161 +141,163 @@ find_sqlite_library (const gchar *name_part)
 }
 
 void
-load_symbols (GModule *module)
+load_symbols (GModule *module, Sqlite3ApiRoutines** apilib)
 {
        g_assert (module);
-       s3r = g_new (Sqlite3ApiRoutines, 1);
+       (*apilib) = g_new (Sqlite3ApiRoutines, 1);
 
-       if (! g_module_symbol (module, "sqlite3_bind_blob", (gpointer*) &(s3r->sqlite3_bind_blob)))
+       if (! g_module_symbol (module, "sqlite3_bind_blob", (gpointer*) &((*apilib)->sqlite3_bind_blob)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_bind_double", (gpointer*) &(s3r->sqlite3_bind_double)))
+       if (! g_module_symbol (module, "sqlite3_bind_double", (gpointer*) &((*apilib)->sqlite3_bind_double)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_bind_int", (gpointer*) &(s3r->sqlite3_bind_int)))
+       if (! g_module_symbol (module, "sqlite3_bind_int", (gpointer*) &((*apilib)->sqlite3_bind_int)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_bind_int64", (gpointer*) &(s3r->sqlite3_bind_int64)))
+       if (! g_module_symbol (module, "sqlite3_bind_int64", (gpointer*) &((*apilib)->sqlite3_bind_int64)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_bind_null", (gpointer*) &(s3r->sqlite3_bind_null)))
+       if (! g_module_symbol (module, "sqlite3_bind_null", (gpointer*) &((*apilib)->sqlite3_bind_null)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_bind_text", (gpointer*) &(s3r->sqlite3_bind_text)))
+       if (! g_module_symbol (module, "sqlite3_bind_text", (gpointer*) &((*apilib)->sqlite3_bind_text)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_bind_zeroblob", (gpointer*) &(s3r->sqlite3_bind_zeroblob)))
+       if (! g_module_symbol (module, "sqlite3_bind_zeroblob", (gpointer*) 
&((*apilib)->sqlite3_bind_zeroblob)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_blob_bytes", (gpointer*) &(s3r->sqlite3_blob_bytes)))
+       if (! g_module_symbol (module, "sqlite3_blob_bytes", (gpointer*) &((*apilib)->sqlite3_blob_bytes)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_blob_close", (gpointer*) &(s3r->sqlite3_blob_close)))
+       if (! g_module_symbol (module, "sqlite3_blob_close", (gpointer*) &((*apilib)->sqlite3_blob_close)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_blob_open", (gpointer*) &(s3r->sqlite3_blob_open)))
+       if (! g_module_symbol (module, "sqlite3_blob_open", (gpointer*) &((*apilib)->sqlite3_blob_open)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_blob_read", (gpointer*) &(s3r->sqlite3_blob_read)))
+       if (! g_module_symbol (module, "sqlite3_blob_read", (gpointer*) &((*apilib)->sqlite3_blob_read)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_blob_write", (gpointer*) &(s3r->sqlite3_blob_write)))
+       if (! g_module_symbol (module, "sqlite3_blob_write", (gpointer*) &((*apilib)->sqlite3_blob_write)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_busy_timeout", (gpointer*) &(s3r->sqlite3_busy_timeout)))
+       if (! g_module_symbol (module, "sqlite3_busy_timeout", (gpointer*) 
&((*apilib)->sqlite3_busy_timeout)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_changes", (gpointer*) &(s3r->sqlite3_changes)))
+       if (! g_module_symbol (module, "sqlite3_changes", (gpointer*) &((*apilib)->sqlite3_changes)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_clear_bindings", (gpointer*) &(s3r->sqlite3_clear_bindings)))
+       if (! g_module_symbol (module, "sqlite3_clear_bindings", (gpointer*) 
&((*apilib)->sqlite3_clear_bindings)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_close", (gpointer*) &(s3r->sqlite3_close)))
+       if (! g_module_symbol (module, "sqlite3_close", (gpointer*) &((*apilib)->sqlite3_close)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_close_v2", (gpointer*) &(s3r->sqlite3_close_v2)))
+       if (! g_module_symbol (module, "sqlite3_close_v2", (gpointer*) &((*apilib)->sqlite3_close_v2)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_column_blob", (gpointer*) &(s3r->sqlite3_column_blob)))
+       if (! g_module_symbol (module, "sqlite3_column_blob", (gpointer*) &((*apilib)->sqlite3_column_blob)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_column_bytes", (gpointer*) &(s3r->sqlite3_column_bytes)))
+       if (! g_module_symbol (module, "sqlite3_column_bytes", (gpointer*) 
&((*apilib)->sqlite3_column_bytes)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_column_count", (gpointer*) &(s3r->sqlite3_column_count)))
+       if (! g_module_symbol (module, "sqlite3_column_count", (gpointer*) 
&((*apilib)->sqlite3_column_count)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_column_database_name", (gpointer*) 
&(s3r->sqlite3_column_database_name)))
+       if (! g_module_symbol (module, "sqlite3_column_database_name", (gpointer*) 
&((*apilib)->sqlite3_column_database_name)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_column_decltype", (gpointer*) 
&(s3r->sqlite3_column_decltype)))
+       if (! g_module_symbol (module, "sqlite3_column_decltype", (gpointer*) 
&((*apilib)->sqlite3_column_decltype)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_column_double", (gpointer*) &(s3r->sqlite3_column_double)))
+       if (! g_module_symbol (module, "sqlite3_column_double", (gpointer*) 
&((*apilib)->sqlite3_column_double)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_column_int", (gpointer*) &(s3r->sqlite3_column_int)))
+       if (! g_module_symbol (module, "sqlite3_column_int", (gpointer*) &((*apilib)->sqlite3_column_int)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_column_int64", (gpointer*) &(s3r->sqlite3_column_int64)))
+       if (! g_module_symbol (module, "sqlite3_column_int64", (gpointer*) 
&((*apilib)->sqlite3_column_int64)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_column_name", (gpointer*) &(s3r->sqlite3_column_name)))
+       if (! g_module_symbol (module, "sqlite3_column_name", (gpointer*) &((*apilib)->sqlite3_column_name)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_column_origin_name", (gpointer*) 
&(s3r->sqlite3_column_origin_name)))
+       if (! g_module_symbol (module, "sqlite3_column_origin_name", (gpointer*) 
&((*apilib)->sqlite3_column_origin_name)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_column_table_name", (gpointer*) 
&(s3r->sqlite3_column_table_name)))
+       if (! g_module_symbol (module, "sqlite3_column_table_name", (gpointer*) 
&((*apilib)->sqlite3_column_table_name)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_column_text", (gpointer*) &(s3r->sqlite3_column_text)))
+       if (! g_module_symbol (module, "sqlite3_column_text", (gpointer*) &((*apilib)->sqlite3_column_text)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_column_type", (gpointer*) &(s3r->sqlite3_column_type)))
+       if (! g_module_symbol (module, "sqlite3_column_type", (gpointer*) &((*apilib)->sqlite3_column_type)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_config", (gpointer*) &(s3r->sqlite3_config)))
+       if (! g_module_symbol (module, "sqlite3_config", (gpointer*) &((*apilib)->sqlite3_config)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_create_function", (gpointer*) 
&(s3r->sqlite3_create_function)))
+       if (! g_module_symbol (module, "sqlite3_create_function", (gpointer*) 
&((*apilib)->sqlite3_create_function)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_create_module", (gpointer*) &(s3r->sqlite3_create_module)))
+       if (! g_module_symbol (module, "sqlite3_create_module", (gpointer*) 
&((*apilib)->sqlite3_create_module)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_db_handle", (gpointer*) &(s3r->sqlite3_db_handle)))
+       if (! g_module_symbol (module, "sqlite3_db_handle", (gpointer*) &((*apilib)->sqlite3_db_handle)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_declare_vtab", (gpointer*) &(s3r->sqlite3_declare_vtab)))
+       if (! g_module_symbol (module, "sqlite3_declare_vtab", (gpointer*) 
&((*apilib)->sqlite3_declare_vtab)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_errcode", (gpointer*) &(s3r->sqlite3_errcode)))
+       if (! g_module_symbol (module, "sqlite3_errcode", (gpointer*) &((*apilib)->sqlite3_errcode)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_errmsg", (gpointer*) &(s3r->sqlite3_errmsg)))
+       if (! g_module_symbol (module, "sqlite3_errmsg", (gpointer*) &((*apilib)->sqlite3_errmsg)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_exec", (gpointer*) &(s3r->sqlite3_exec)))
+       if (! g_module_symbol (module, "sqlite3_exec", (gpointer*) &((*apilib)->sqlite3_exec)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_extended_result_codes", (gpointer*) 
&(s3r->sqlite3_extended_result_codes)))
+       if (! g_module_symbol (module, "sqlite3_extended_result_codes", (gpointer*) 
&((*apilib)->sqlite3_extended_result_codes)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_finalize", (gpointer*) &(s3r->sqlite3_finalize)))
+       if (! g_module_symbol (module, "sqlite3_finalize", (gpointer*) &((*apilib)->sqlite3_finalize)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_free", (gpointer*) &(s3r->sqlite3_free)))
+       if (! g_module_symbol (module, "sqlite3_free", (gpointer*) &((*apilib)->sqlite3_free)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_free_table", (gpointer*) &(s3r->sqlite3_free_table)))
+       if (! g_module_symbol (module, "sqlite3_free_table", (gpointer*) &((*apilib)->sqlite3_free_table)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_get_table", (gpointer*) &(s3r->sqlite3_get_table)))
+       if (! g_module_symbol (module, "sqlite3_get_table", (gpointer*) &((*apilib)->sqlite3_get_table)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_last_insert_rowid", (gpointer*) 
&(s3r->sqlite3_last_insert_rowid)))
+       if (! g_module_symbol (module, "sqlite3_last_insert_rowid", (gpointer*) 
&((*apilib)->sqlite3_last_insert_rowid)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_malloc", (gpointer*) &(s3r->sqlite3_malloc)))
+       if (! g_module_symbol (module, "sqlite3_malloc", (gpointer*) &((*apilib)->sqlite3_malloc)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_mprintf", (gpointer*) &(s3r->sqlite3_mprintf)))
+       if (! g_module_symbol (module, "sqlite3_mprintf", (gpointer*) &((*apilib)->sqlite3_mprintf)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_open", (gpointer*) &(s3r->sqlite3_open)))
+       if (! g_module_symbol (module, "sqlite3_open", (gpointer*) &((*apilib)->sqlite3_open)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_open_v2", (gpointer*) &(s3r->sqlite3_open_v2)))
+       if (! g_module_symbol (module, "sqlite3_open_v2", (gpointer*) &((*apilib)->sqlite3_open_v2)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_prepare", (gpointer*) &(s3r->sqlite3_prepare)))
+       if (! g_module_symbol (module, "sqlite3_prepare", (gpointer*) &((*apilib)->sqlite3_prepare)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_prepare_v2", (gpointer*) &(s3r->sqlite3_prepare_v2)))
+       if (! g_module_symbol (module, "sqlite3_prepare_v2", (gpointer*) &((*apilib)->sqlite3_prepare_v2)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_reset", (gpointer*) &(s3r->sqlite3_reset)))
+       if (! g_module_symbol (module, "sqlite3_reset", (gpointer*) &((*apilib)->sqlite3_reset)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_result_blob", (gpointer*) &(s3r->sqlite3_result_blob)))
+       if (! g_module_symbol (module, "sqlite3_result_blob", (gpointer*) &((*apilib)->sqlite3_result_blob)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_result_double", (gpointer*) &(s3r->sqlite3_result_double)))
+       if (! g_module_symbol (module, "sqlite3_result_double", (gpointer*) 
&((*apilib)->sqlite3_result_double)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_result_error", (gpointer*) &(s3r->sqlite3_result_error)))
+       if (! g_module_symbol (module, "sqlite3_result_error", (gpointer*) 
&((*apilib)->sqlite3_result_error)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_result_int", (gpointer*) &(s3r->sqlite3_result_int)))
+       if (! g_module_symbol (module, "sqlite3_result_int", (gpointer*) &((*apilib)->sqlite3_result_int)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_result_int64", (gpointer*) &(s3r->sqlite3_result_int64)))
+       if (! g_module_symbol (module, "sqlite3_result_int64", (gpointer*) 
&((*apilib)->sqlite3_result_int64)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_result_null", (gpointer*) &(s3r->sqlite3_result_null)))
+       if (! g_module_symbol (module, "sqlite3_result_null", (gpointer*) &((*apilib)->sqlite3_result_null)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_result_text", (gpointer*) &(s3r->sqlite3_result_text)))
+       if (! g_module_symbol (module, "sqlite3_result_text", (gpointer*) &((*apilib)->sqlite3_result_text)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_step", (gpointer*) &(s3r->sqlite3_step)))
+       if (! g_module_symbol (module, "sqlite3_step", (gpointer*) &((*apilib)->sqlite3_step)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_table_column_metadata", (gpointer*) 
&(s3r->sqlite3_table_column_metadata)))
+       if (! g_module_symbol (module, "sqlite3_table_column_metadata", (gpointer*) 
&((*apilib)->sqlite3_table_column_metadata)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_threadsafe", (gpointer*) &(s3r->sqlite3_threadsafe)))
+       if (! g_module_symbol (module, "sqlite3_threadsafe", (gpointer*) &((*apilib)->sqlite3_threadsafe)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_value_blob", (gpointer*) &(s3r->sqlite3_value_blob)))
+       if (! g_module_symbol (module, "sqlite3_value_blob", (gpointer*) &((*apilib)->sqlite3_value_blob)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_value_bytes", (gpointer*) &(s3r->sqlite3_value_bytes)))
+       if (! g_module_symbol (module, "sqlite3_value_bytes", (gpointer*) &((*apilib)->sqlite3_value_bytes)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_value_int", (gpointer*) &(s3r->sqlite3_value_int)))
+       if (! g_module_symbol (module, "sqlite3_value_int", (gpointer*) &((*apilib)->sqlite3_value_int)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_value_int64", (gpointer*) &(s3r->sqlite3_value_int64)))
+       if (! g_module_symbol (module, "sqlite3_value_int64", (gpointer*) &((*apilib)->sqlite3_value_int64)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_value_double", (gpointer*) &(s3r->sqlite3_value_double)))
+       if (! g_module_symbol (module, "sqlite3_value_double", (gpointer*) 
&((*apilib)->sqlite3_value_double)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_value_text", (gpointer*) &(s3r->sqlite3_value_text)))
+       if (! g_module_symbol (module, "sqlite3_value_text", (gpointer*) &((*apilib)->sqlite3_value_text)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_value_type", (gpointer*) &(s3r->sqlite3_value_type)))
+       if (! g_module_symbol (module, "sqlite3_value_type", (gpointer*) &((*apilib)->sqlite3_value_type)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_key", (gpointer*) &(s3r->sqlite3_key)))
-               s3r->sqlite3_key = NULL;
-       if (! g_module_symbol (module, "sqlite3_rekey", (gpointer*) &(s3r->sqlite3_key)))
-               s3r->sqlite3_rekey = NULL;
+       if (! g_module_symbol (module, "sqlite3_key", (gpointer*) &((*apilib)->sqlite3_key)))
+               (*apilib)->sqlite3_key = NULL;
+       if (! g_module_symbol (module, "sqlite3_key_v2", (gpointer*) &((*apilib)->sqlite3_key_v2)))
+               (*apilib)->sqlite3_key_v2 = NULL;
+       if (! g_module_symbol (module, "sqlite3_rekey", (gpointer*) &((*apilib)->sqlite3_key)))
+               (*apilib)->sqlite3_rekey = NULL;
 
-       if (! g_module_symbol (module, "sqlite3_create_collation", (gpointer*) 
&(s3r->sqlite3_create_collation)))
+       if (! g_module_symbol (module, "sqlite3_create_collation", (gpointer*) 
&((*apilib)->sqlite3_create_collation)))
                goto onerror;
-       if (! g_module_symbol (module, "sqlite3_enable_load_extension", (gpointer*) 
&(s3r->sqlite3_enable_load_extension)))
-               s3r->sqlite3_enable_load_extension = NULL;
+       if (! g_module_symbol (module, "sqlite3_enable_load_extension", (gpointer*) 
&((*apilib)->sqlite3_enable_load_extension)))
+               (*apilib)->sqlite3_enable_load_extension = NULL;
        return;
 
  onerror:
-       g_free (s3r);
-       s3r = NULL;
+       g_free ((*apilib));
+       apilib = NULL;
        g_module_close (module);        
 }
 
diff --git a/libgda/sqlite/gda-symbols-util.h b/libgda/sqlite/gda-symbols-util.h
index 8fca02daa..1a2a4010f 100644
--- a/libgda/sqlite/gda-symbols-util.h
+++ b/libgda/sqlite/gda-symbols-util.h
@@ -110,6 +110,7 @@ typedef struct {
        int  (*sqlite3_value_type)(sqlite3_value*);
 
        int  (*sqlite3_key)(sqlite3 *, const void *, int);
+       int  (*sqlite3_key_v2)(sqlite3 *, const char *, const void *, int);
        int  (*sqlite3_rekey)(sqlite3 *, const void *, int);
 
        int  (*sqlite3_create_collation) (sqlite3*, const char *, int, void*, int(*xCompare)(void*,int,const 
void*,int,const void*));
@@ -120,7 +121,7 @@ typedef struct {
 extern Sqlite3ApiRoutines *s3r;
 
 GModule *find_sqlite_library (const gchar *name_part);
-void     load_symbols (GModule *module);
+void     load_symbols (GModule *module, Sqlite3ApiRoutines **apilib);
 
 G_END_DECLS
 
diff --git a/libgda/sqlite/virtual/gda-vconnection-data-model.c 
b/libgda/sqlite/virtual/gda-vconnection-data-model.c
index 095c20d70..d8ffb5c51 100644
--- a/libgda/sqlite/virtual/gda-vconnection-data-model.c
+++ b/libgda/sqlite/virtual/gda-vconnection-data-model.c
@@ -261,6 +261,7 @@ gda_vconnection_data_model_add (GdaVconnectionDataModel *cnc, GdaVconnectionData
        gboolean retval = TRUE;
        SqliteConnectionData *scnc;
        GdaVconnectionDataModelPrivate *priv = gda_vconnection_data_model_get_instance_private (cnc);
+       GdaSqliteProvider *sprov = GDA_SQLITE_PROVIDER (gda_connection_get_provider (GDA_CONNECTION (cnc)));
 
        static gint counter = 0;
 
@@ -300,13 +301,13 @@ gda_vconnection_data_model_add (GdaVconnectionDataModel *cnc, GdaVconnectionData
        /* actually create the virtual table in @cnc */
        prov = (GdaVirtualProvider *) gda_connection_get_provider (GDA_CONNECTION (cnc));
        str = g_strdup_printf ("CREATE VIRTUAL TABLE %s USING %s ('%s')", td->table_name, G_OBJECT_TYPE_NAME 
(prov), td->unique_name);
-       rc = SQLITE3_CALL (sqlite3_exec) (scnc->connection, str, NULL, 0, &zErrMsg);
+       rc = SQLITE3_CALL (sprov, sqlite3_exec) (scnc->connection, str, NULL, 0, &zErrMsg);
        g_free (str);
        if (rc != SQLITE_OK) {
                g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
                             GDA_SERVER_PROVIDER_INTERNAL_ERROR,
                             _("Internal Error: when trying to add data model spec for virtual connetion: 
%s"), zErrMsg);
-               SQLITE3_CALL (sqlite3_free) (zErrMsg);
+               SQLITE3_CALL (sprov, sqlite3_free) (zErrMsg);
                _gda_vconnection_data_model_table_data_free (td);
                priv->table_data_list = g_slist_remove (priv->table_data_list, td);
                retval = FALSE;
@@ -328,6 +329,7 @@ get_rid_of_vtable (GdaVconnectionDataModel *cnc, GdaVConnectionTableData *td, gb
        char *zErrMsg = NULL;
        gboolean allok = TRUE;
        GdaVconnectionDataModelPrivate *priv = gda_vconnection_data_model_get_instance_private (cnc);
+       GdaSqliteProvider *prov = GDA_SQLITE_PROVIDER (gda_connection_get_provider (GDA_CONNECTION (cnc)));
 
        SqliteConnectionData *scnc;
        scnc = (SqliteConnectionData*) gda_connection_internal_get_provider_data_error ((GdaConnection *) 
cnc, error);
@@ -336,14 +338,14 @@ get_rid_of_vtable (GdaVconnectionDataModel *cnc, GdaVConnectionTableData *td, gb
 
        if (scnc) {
                str = g_strdup_printf ("DROP TABLE %s", td->table_name);
-               rc = SQLITE3_CALL (sqlite3_exec) (scnc->connection, str, NULL, 0, &zErrMsg);
+               rc = SQLITE3_CALL (prov, sqlite3_exec) (scnc->connection, str, NULL, 0, &zErrMsg);
                g_free (str);
 
                if (rc != SQLITE_OK) {
                        g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
                                     GDA_SERVER_PROVIDER_INTERNAL_ERROR,
                                     "%s", zErrMsg);
-                       SQLITE3_CALL (sqlite3_free) (zErrMsg);
+                       SQLITE3_CALL (prov, sqlite3_free) (zErrMsg);
                        allok = FALSE;
                        if (!force)
                                return FALSE;
diff --git a/libgda/sqlite/virtual/gda-vprovider-data-model.c 
b/libgda/sqlite/virtual/gda-vprovider-data-model.c
index 664d57500..b2f23e814 100644
--- a/libgda/sqlite/virtual/gda-vprovider-data-model.c
+++ b/libgda/sqlite/virtual/gda-vprovider-data-model.c
@@ -72,7 +72,7 @@ static GObject        *gda_vprovider_data_model_statement_execute (GdaServerProv
                                                                   GError **error);
 static const gchar   *gda_vprovider_data_model_get_name (GdaServerProvider *provider);
 
-static GValue **create_gvalues_array_from_sqlite3_array (int argc, sqlite3_value **argv);
+static GValue **create_gvalues_array_from_sqlite3_array (GdaSqliteProvider *prov, int argc, sqlite3_value 
**argv);
 
 
 /*
@@ -189,6 +189,7 @@ struct VirtualCursor {
        sqlite3_vtab_cursor      base; /* base.pVtab is a pointer to the sqlite3_vtab virtual table */
        VirtualFilteredData     *data; /* a ref is held here */
        gint                     row; /* starts at 0 */
+       GWeakRef                 provider;
 };
 
 
@@ -198,6 +199,7 @@ virtual_filtered_data_new (VirtualTable *vtable, GdaDataModel *model,
                           int idxNum, const char *idxStr, int argc, sqlite3_value **argv)
 {
        VirtualFilteredData *data;
+       GdaSqliteProvider *prov = GDA_SQLITE_PROVIDER (gda_connection_get_provider (GDA_CONNECTION 
(vtable->cnc)));
 
        g_assert (model);
        data = g_new0 (VirtualFilteredData, 1);
@@ -206,7 +208,7 @@ virtual_filtered_data_new (VirtualTable *vtable, GdaDataModel *model,
        data->idxNum = idxNum;
        data->idxStr = idxStr ? g_strdup (idxStr) : NULL;
        data->argc = argc;
-       data->argv = create_gvalues_array_from_sqlite3_array (argc, argv);
+       data->argv = create_gvalues_array_from_sqlite3_array (prov, argc, argv);
        data->model = g_object_ref (model);
        if (GDA_IS_DATA_PROXY (model))
                data->iter = g_object_new (GDA_TYPE_DATA_MODEL_ITER,
@@ -381,9 +383,9 @@ gda_vprovider_data_model_open_connection (GdaServerProvider *provider, GdaConnec
                gda_connection_add_event_string (cnc, _("Connection is closed"));
                return FALSE;
        }
-
+       GdaSqliteProvider *prov = GDA_SQLITE_PROVIDER (provider);
        /* Module to declare wirtual tables */
-       if (SQLITE3_CALL (sqlite3_create_module) (scnc->connection, G_OBJECT_TYPE_NAME (provider), &Module, 
cnc) != SQLITE_OK)
+       if (SQLITE3_CALL (prov, sqlite3_create_module) (scnc->connection, G_OBJECT_TYPE_NAME (provider), 
&Module, cnc) != SQLITE_OK)
                return FALSE;
        /*g_print ("==== Declared module for DB %p\n", scnc->connection);*/
 
@@ -529,6 +531,7 @@ virtualCreate (sqlite3 *db, void *pAux, int argc, const char *const *argv, sqlit
        gchar *spec_name, *tmp;
        GdaVConnectionTableData *td;
        GHashTable *hash;
+       GdaSqliteProvider *prov = GDA_SQLITE_PROVIDER (gda_connection_get_provider (GDA_CONNECTION (cnc)));
 
        TRACE (NULL, NULL);
 
@@ -545,7 +548,7 @@ virtualCreate (sqlite3 *db, void *pAux, int argc, const char *const *argv, sqlit
        g_free (spec_name);
        if (!td) {
                /* wrong usage! */
-               *pzErr = SQLITE3_CALL (sqlite3_mprintf) (_("Wrong usage of Libgda's virtual tables"));
+               *pzErr = SQLITE3_CALL (prov, sqlite3_mprintf) (_("Wrong usage of Libgda's virtual tables"));
                return SQLITE_ERROR;
        }
 
@@ -553,7 +556,7 @@ virtualCreate (sqlite3 *db, void *pAux, int argc, const char *const *argv, sqlit
        if (td->spec->data_model) {
                ncols = gda_data_model_get_n_columns (td->spec->data_model);
                if (ncols <= 0) {
-                       *pzErr = SQLITE3_CALL (sqlite3_mprintf) (_("Data model must have at least one 
column"));
+                       *pzErr = SQLITE3_CALL (prov, sqlite3_mprintf) (_("Data model must have at least one 
column"));
                        return SQLITE_ERROR;
                }
                td->real_model = td->spec->data_model;
@@ -566,11 +569,11 @@ virtualCreate (sqlite3 *db, void *pAux, int argc, const char *const *argv, sqlit
        if (!td->columns) {
                if (error && error->message) {
                        int len = strlen (error->message) + 1;
-                       *pzErr = SQLITE3_CALL (sqlite3_malloc) (sizeof (gchar) * len);
+                       *pzErr = SQLITE3_CALL (prov, sqlite3_malloc) (sizeof (gchar) * len);
                        memcpy (*pzErr, error->message, len); /* Flawfinder: ignore */
                }
                else 
-                       *pzErr = SQLITE3_CALL (sqlite3_mprintf) (_("Could not compute virtual table's 
columns"));
+                       *pzErr = SQLITE3_CALL (prov, sqlite3_mprintf) (_("Could not compute virtual table's 
columns"));
                return SQLITE_ERROR;
        }
        ncols = g_list_length (td->columns);
@@ -593,7 +596,7 @@ virtualCreate (sqlite3 *db, void *pAux, int argc, const char *const *argv, sqlit
                        g_string_append (sql, ", ");
                column = g_list_nth_data (td->columns, i);
                if (!column) {
-                       *pzErr = SQLITE3_CALL (sqlite3_mprintf) (_("Can't get data model description for 
column %d"), i);
+                       *pzErr = SQLITE3_CALL (prov, sqlite3_mprintf) (_("Can't get data model description 
for column %d"), i);
                        g_string_free (sql, TRUE);
                        return SQLITE_ERROR;
                }
@@ -645,7 +648,7 @@ virtualCreate (sqlite3 *db, void *pAux, int argc, const char *const *argv, sqlit
                gtype = gda_column_get_g_type (column);
                type = g_type_name (gtype);
                if (!type) {
-                       *pzErr = SQLITE3_CALL (sqlite3_mprintf) (_("Can't get data model's column type for 
column %d"), i);
+                       *pzErr = SQLITE3_CALL (prov, sqlite3_mprintf) (_("Can't get data model's column type 
for column %d"), i);
                        g_string_free (sql, TRUE);
                        return SQLITE_ERROR;
                }
@@ -705,9 +708,9 @@ virtualCreate (sqlite3 *db, void *pAux, int argc, const char *const *argv, sqlit
        vtable->rows_offset = 0;
        *ppVtab = &(vtable->base);
 
-       if (SQLITE3_CALL (sqlite3_declare_vtab) (db, sql->str) != SQLITE_OK) {
+       if (SQLITE3_CALL (prov, sqlite3_declare_vtab) (db, sql->str) != SQLITE_OK) {
                sqlite3_mutex_enter (sqlite3_db_mutex (db));
-               *pzErr = SQLITE3_CALL (sqlite3_mprintf) (_("Can't declare virtual table (\"%s\"): %s"), 
sql->str,
+               *pzErr = SQLITE3_CALL (prov, sqlite3_mprintf) (_("Can't declare virtual table (\"%s\"): %s"), 
sql->str,
                                                         sqlite3_errmsg (db));
                sqlite3_mutex_leave (sqlite3_db_mutex (db));
 
@@ -801,6 +804,8 @@ handle_data_model_exception (sqlite3_vtab *pVtab, GdaDataModel *model)
 {
        GError **exceptions;
        gint i;
+       VirtualTable *vtab = (VirtualTable*) pVtab;
+       GdaSqliteProvider *prov = GDA_SQLITE_PROVIDER (gda_connection_get_provider (GDA_CONNECTION 
(vtab->cnc)));
        exceptions = gda_data_model_get_exceptions (model);
        if (!exceptions)
                return SQLITE_OK;
@@ -824,8 +829,8 @@ handle_data_model_exception (sqlite3_vtab *pVtab, GdaDataModel *model)
                if (!e)
                        e = trunc_error;
                if (pVtab->zErrMsg)
-                       SQLITE3_CALL (sqlite3_free) (pVtab->zErrMsg);
-               pVtab->zErrMsg = SQLITE3_CALL (sqlite3_mprintf)
+                       SQLITE3_CALL (prov, sqlite3_free) (pVtab->zErrMsg);
+               pVtab->zErrMsg = SQLITE3_CALL (prov, sqlite3_mprintf)
                        ("%s", e->message ? e->message : _("No detail"));
                if (fatal_error)
                        return SQLITE_ERROR;
@@ -840,13 +845,14 @@ virtualNext (sqlite3_vtab_cursor *cur)
 {
        VirtualCursor *cursor = (VirtualCursor*) cur;
        VirtualFilteredData *data;
-       /*VirtualTable *vtable = (VirtualTable*) cur->pVtab;*/
+       VirtualTable *vtab = (VirtualTable*) cur->pVtab;
+       GdaSqliteProvider *prov = GDA_SQLITE_PROVIDER (gda_connection_get_provider (GDA_CONNECTION 
(vtab->cnc)));
 
        TRACE (cur->pVtab, cur);
 
        data = cursor->data;
        if (!data) {
-               cur->pVtab->zErrMsg = SQLITE3_CALL (sqlite3_mprintf)
+               cur->pVtab->zErrMsg = SQLITE3_CALL (prov, sqlite3_mprintf)
                        (_("Internal SQLite error: no data to iterate on"));
                return SQLITE_MISUSE;
        }
@@ -963,17 +969,19 @@ static int
 virtualColumn (sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i)
 {
        VirtualCursor *cursor = (VirtualCursor*) cur;
+       VirtualTable *vtab = (VirtualTable*) cur->pVtab;
+       GdaSqliteProvider *prov = GDA_SQLITE_PROVIDER (gda_connection_get_provider (GDA_CONNECTION 
(vtab->cnc)));
 
        TRACE (cur->pVtab, cur);
        
        if (i == ((VirtualTable*) cur->pVtab)->td->n_columns) {
                /* private hidden column, which returns the row number */
-               SQLITE3_CALL (sqlite3_result_int) (ctx, cursor->row);
+               SQLITE3_CALL (prov, sqlite3_result_int) (ctx, cursor->row);
                return SQLITE_OK;
        }
 
        if (i >= cursor->data->ncols) {
-               SQLITE3_CALL (sqlite3_result_text) (ctx, _("Column not found"), -1, SQLITE_TRANSIENT);
+               SQLITE3_CALL (prov, sqlite3_result_text) (ctx, _("Column not found"), -1, SQLITE_TRANSIENT);
                return SQLITE_MISUSE;
        }
        
@@ -982,7 +990,7 @@ virtualColumn (sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i)
        value = get_data_value ((VirtualTable*) cur->pVtab, cursor, cursor->row, 0, i, &lerror);
        if (! value) {
                g_hash_table_insert (error_blobs_hash, lerror, GINT_TO_POINTER (1));
-               SQLITE3_CALL (sqlite3_result_blob) (ctx, lerror, sizeof (GError), NULL);
+               SQLITE3_CALL (prov, sqlite3_result_blob) (ctx, lerror, sizeof (GError), NULL);
        }
        else if (G_VALUE_TYPE (value) == G_TYPE_ERROR) {
                GError *lerror;
@@ -996,16 +1004,16 @@ virtualColumn (sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i)
                        g_set_error (&lerror, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_DATA_ERROR,
                                     _("No detail"));
                g_hash_table_insert (error_blobs_hash, lerror, GINT_TO_POINTER (1));
-               SQLITE3_CALL (sqlite3_result_blob) (ctx, lerror, sizeof (GError), NULL);
+               SQLITE3_CALL (prov, sqlite3_result_blob) (ctx, lerror, sizeof (GError), NULL);
        }
        else if (!value || gda_value_is_null (value))
-               SQLITE3_CALL (sqlite3_result_null) (ctx);
+               SQLITE3_CALL (prov, sqlite3_result_null) (ctx);
        else  if (G_VALUE_TYPE (value) == G_TYPE_INT) 
-               SQLITE3_CALL (sqlite3_result_int) (ctx, g_value_get_int (value));
+               SQLITE3_CALL (prov, sqlite3_result_int) (ctx, g_value_get_int (value));
        else if (G_VALUE_TYPE (value) == G_TYPE_INT64) 
-               SQLITE3_CALL (sqlite3_result_int64) (ctx, g_value_get_int64 (value));
+               SQLITE3_CALL (prov, sqlite3_result_int64) (ctx, g_value_get_int64 (value));
        else if (G_VALUE_TYPE (value) == G_TYPE_DOUBLE) 
-               SQLITE3_CALL (sqlite3_result_double) (ctx, g_value_get_double (value));
+               SQLITE3_CALL (prov, sqlite3_result_double) (ctx, g_value_get_double (value));
        else if (G_VALUE_TYPE (value) == GDA_TYPE_BLOB) {
                GdaBlob *blob;
                GdaBinary *bin;
@@ -1014,18 +1022,18 @@ virtualColumn (sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i)
                if (gda_blob_get_op (blob) &&
                    (gda_binary_get_size (bin) != gda_blob_op_get_length (gda_blob_get_op(blob))))
                        gda_blob_op_read_all (gda_blob_get_op (blob), blob);
-               SQLITE3_CALL (sqlite3_result_blob) (ctx, gda_binary_get_data (gda_blob_get_binary (blob)),
+               SQLITE3_CALL (prov, sqlite3_result_blob) (ctx, gda_binary_get_data (gda_blob_get_binary 
(blob)),
                                                    gda_binary_get_size (gda_blob_get_binary (blob)),
                                                    SQLITE_TRANSIENT);
        }
        else if (G_VALUE_TYPE (value) == GDA_TYPE_BINARY) {
                GdaBinary *bin;
                bin = gda_value_get_binary (value);
-               SQLITE3_CALL (sqlite3_result_blob) (ctx, gda_binary_get_data (bin), gda_binary_get_size 
(bin), SQLITE_TRANSIENT);
+               SQLITE3_CALL (prov, sqlite3_result_blob) (ctx, gda_binary_get_data (bin), gda_binary_get_size 
(bin), SQLITE_TRANSIENT);
        }
        else {
                gchar *str = gda_value_stringify (value);
-               SQLITE3_CALL (sqlite3_result_text) (ctx, str, -1, SQLITE_TRANSIENT);
+               SQLITE3_CALL (prov, sqlite3_result_text) (ctx, str, -1, SQLITE_TRANSIENT);
                g_free (str);
        }
 
@@ -1045,28 +1053,28 @@ virtualRowid (sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid)
 
 /* NEVER returns %NULL */
 static GValue *
-create_value_from_sqlite3_value_notype (sqlite3_value *svalue)
+create_value_from_sqlite3_value_notype (GdaSqliteProvider *prov, sqlite3_value *svalue)
 {
        GValue *value;
        value = g_new0 (GValue, 1);
 
-       switch (SQLITE3_CALL (sqlite3_value_type) (svalue)) {
+       switch (SQLITE3_CALL (prov, sqlite3_value_type) (svalue)) {
        case SQLITE_INTEGER:
                g_value_init (value, G_TYPE_INT64);
-               g_value_set_int64 (value, SQLITE3_CALL (sqlite3_value_int64) (svalue));
+               g_value_set_int64 (value, SQLITE3_CALL (prov, sqlite3_value_int64) (svalue));
                break;
        case SQLITE_FLOAT:
                g_value_init (value, G_TYPE_DOUBLE);
-               g_value_set_double (value, SQLITE3_CALL (sqlite3_value_double) (svalue));
+               g_value_set_double (value, SQLITE3_CALL (prov, sqlite3_value_double) (svalue));
                break;
        case SQLITE_BLOB: {
                GdaBinary *bin;
                g_value_init (value, GDA_TYPE_BINARY);
                bin = gda_binary_new ();
-               glong length = SQLITE3_CALL (sqlite3_value_bytes) (svalue);
+               glong length = SQLITE3_CALL (prov, sqlite3_value_bytes) (svalue);
                if (length > 0) {
                        //gpointer data = g_new (guchar, length);
-                       gda_binary_set_data (bin, SQLITE3_CALL (sqlite3_value_blob) (svalue), length);
+                       gda_binary_set_data (bin, SQLITE3_CALL (prov, sqlite3_value_blob) (svalue), length);
                }
                gda_value_take_binary (value, bin);
                break;
@@ -1077,7 +1085,7 @@ create_value_from_sqlite3_value_notype (sqlite3_value *svalue)
        case SQLITE3_TEXT:
        default:
                g_value_init (value, G_TYPE_STRING);
-               g_value_set_string (value, (gchar *) SQLITE3_CALL (sqlite3_value_text) (svalue));
+               g_value_set_string (value, (gchar *) SQLITE3_CALL (prov, sqlite3_value_text) (svalue));
                break;
        }
        return value;
@@ -1087,7 +1095,7 @@ create_value_from_sqlite3_value_notype (sqlite3_value *svalue)
  * Returns: a new array of @argc values, and %NULL if @argc = 0
  */
 static GValue **
-create_gvalues_array_from_sqlite3_array (int argc, sqlite3_value **argv)
+create_gvalues_array_from_sqlite3_array (GdaSqliteProvider *prov, int argc, sqlite3_value **argv)
 {
        GValue **array;
        gint i;
@@ -1095,7 +1103,7 @@ create_gvalues_array_from_sqlite3_array (int argc, sqlite3_value **argv)
                return NULL;
        array = g_new (GValue *, argc);
        for (i = 0; i < argc; i++)
-               array[i] = create_value_from_sqlite3_value_notype (argv[i]);
+               array[i] = create_value_from_sqlite3_value_notype (prov, argv[i]);
        return array;
 }
 
@@ -1103,6 +1111,7 @@ static void
 virtual_table_manage_real_data_model (VirtualTable *vtable, int idxNum, const char *idxStr,
                                      int argc, sqlite3_value **argv)
 {
+       GdaSqliteProvider *prov = GDA_SQLITE_PROVIDER (gda_connection_get_provider (GDA_CONNECTION 
(vtable->cnc)));
        /*g_print ("================== %s (VTable=> %p, %s)\n", __FUNCTION__,
          vtable, vtable->td->table_name);*/
        if (!vtable->td->spec->create_filtered_model_func && !vtable->td->spec->create_model_func)
@@ -1116,7 +1125,7 @@ virtual_table_manage_real_data_model (VirtualTable *vtable, int idxNum, const ch
        /* actual data model creation */
        if (vtable->td->spec->create_filtered_model_func) {
                GValue **gargv;
-               gargv = create_gvalues_array_from_sqlite3_array (argc, argv);
+               gargv = create_gvalues_array_from_sqlite3_array (prov, argc, argv);
                vtable->td->real_model = vtable->td->spec->create_filtered_model_func (vtable->td->spec,
                                                                                       idxNum, idxStr,
                                                                                       argc, gargv);
@@ -1162,6 +1171,7 @@ virtualFilter (sqlite3_vtab_cursor *pVtabCursor, int idxNum, const char *idxStr,
 {
        VirtualCursor *cursor = (VirtualCursor*) pVtabCursor;
        VirtualTable *vtable = (VirtualTable*) pVtabCursor->pVtab;
+       GdaSqliteProvider *prov = GDA_SQLITE_PROVIDER (gda_connection_get_provider (GDA_CONNECTION 
(vtable->cnc)));
 
        TRACE (pVtabCursor->pVtab, pVtabCursor);
 #ifdef GDA_DEBUG_VIRTUAL
@@ -1185,7 +1195,7 @@ virtualFilter (sqlite3_vtab_cursor *pVtabCursor, int idxNum, const char *idxStr,
                                GValue **avalues;
                                gint i;
                                gboolean equal = TRUE;
-                               avalues = create_gvalues_array_from_sqlite3_array (argc, argv);
+                               avalues = create_gvalues_array_from_sqlite3_array (prov, argc, argv);
                                for (i = 0; i < argc; i++) {
                                        GValue *v1, *v2;
                                        v1 = vd->argv [i];
@@ -1426,6 +1436,7 @@ static int
 update_data_select_model (sqlite3_vtab *tab, gint optype, G_GNUC_UNUSED int nData, sqlite3_value **apData)
 {
        VirtualTable *vtable = (VirtualTable *) tab;
+       GdaSqliteProvider *prov = GDA_SQLITE_PROVIDER (gda_connection_get_provider (GDA_CONNECTION 
(vtable->cnc)));
 
        /* determine parameters required to execute MOD statement */
        GdaStatement *stmt = NULL;
@@ -1452,14 +1463,14 @@ update_data_select_model (sqlite3_vtab *tab, gint optype, G_GNUC_UNUSED int nDat
                
        if (! vtable->td->modif_stmt [ptype]) {
                if (! stmt) {
-                       tab->zErrMsg = SQLITE3_CALL (sqlite3_mprintf)
+                       tab->zErrMsg = SQLITE3_CALL (prov, sqlite3_mprintf)
                                (_("No statement specified to modify the data"));
                        return SQLITE_READONLY;
                }
                
                GdaSet *params;
                if (! gda_statement_get_parameters (stmt, &params, NULL) || !params) {
-                       tab->zErrMsg = SQLITE3_CALL (sqlite3_mprintf)
+                       tab->zErrMsg = SQLITE3_CALL (prov, sqlite3_mprintf)
                                (_("Invalid statement specified to modify the data"));
                        g_object_unref (stmt);
                        return SQLITE_READONLY;
@@ -1479,7 +1490,7 @@ update_data_select_model (sqlite3_vtab *tab, gint optype, G_GNUC_UNUSED int nDat
                        
                id = gda_holder_get_id (holder);
                if (!id) {
-                       tab->zErrMsg = SQLITE3_CALL (sqlite3_mprintf)
+                       tab->zErrMsg = SQLITE3_CALL (prov, sqlite3_mprintf)
                                (_("Invalid parameter in statement to modify the data"));
                        return SQLITE_READONLY;
                }
@@ -1490,8 +1501,8 @@ update_data_select_model (sqlite3_vtab *tab, gint optype, G_GNUC_UNUSED int nDat
                                GType type;
                                GValue *value;
                                type = gda_column_get_g_type (gda_data_model_describe_column 
(vtable->td->real_model, i));
-                               if ((type != GDA_TYPE_NULL) && SQLITE3_CALL (sqlite3_value_text) (apData 
[i+2]))
-                                       value = gda_value_new_from_string ((const gchar*) SQLITE3_CALL 
(sqlite3_value_text) (apData [i+2]), type);
+                               if ((type != GDA_TYPE_NULL) && SQLITE3_CALL (prov, sqlite3_value_text) 
(apData [i+2]))
+                                       value = gda_value_new_from_string ((const gchar*) SQLITE3_CALL (prov, 
sqlite3_value_text) (apData [i+2]), type);
                                else
                                        value = gda_value_new_null ();
                                if (gda_holder_take_value (holder, value, NULL))
@@ -1499,7 +1510,7 @@ update_data_select_model (sqlite3_vtab *tab, gint optype, G_GNUC_UNUSED int nDat
                        }
                }
                else if (*id == '-') {
-                       gint64 rowid = SQLITE3_CALL (sqlite3_value_int64) (apData [0]);
+                       gint64 rowid = SQLITE3_CALL (prov, sqlite3_value_int64) (apData [0]);
                        long int i;
                        const GValue *value;
 
@@ -1516,7 +1527,7 @@ update_data_select_model (sqlite3_vtab *tab, gint optype, G_GNUC_UNUSED int nDat
                                      &exec_set, NULL);
                        if (! exec_set) {
                                /* can't give value to param named @id */
-                               tab->zErrMsg = SQLITE3_CALL (sqlite3_mprintf)
+                               tab->zErrMsg = SQLITE3_CALL (prov, sqlite3_mprintf)
                                        (_("Invalid parameter in statement to modify the data"));
                                return SQLITE_READONLY;
                        }
@@ -1524,7 +1535,7 @@ update_data_select_model (sqlite3_vtab *tab, gint optype, G_GNUC_UNUSED int nDat
                        if (! eh ||
                            ! gda_holder_set_bind (holder, eh, NULL)) {
                                /* can't give value to param named @id */
-                               tab->zErrMsg = SQLITE3_CALL (sqlite3_mprintf)
+                               tab->zErrMsg = SQLITE3_CALL (prov, sqlite3_mprintf)
                                        (_("Invalid parameter in statement to modify the data"));
                                return SQLITE_READONLY;
                        }
@@ -1556,7 +1567,7 @@ update_data_select_model (sqlite3_vtab *tab, gint optype, G_GNUC_UNUSED int nDat
                                                          vtable->td->modif_params [ptype],
                                                          NULL, &lerror) == -1)) {
                /* failed to execute */
-               tab->zErrMsg = SQLITE3_CALL (sqlite3_mprintf)
+               tab->zErrMsg = SQLITE3_CALL (prov, sqlite3_mprintf)
                        (_("Failed to modify data: %s"),
                         lerror && lerror->message ? lerror->message : _("No detail"));
                g_clear_error (&lerror);
@@ -1580,6 +1591,7 @@ static int
 virtualUpdate (sqlite3_vtab *tab, int nData, sqlite3_value **apData, sqlite_int64 *pRowid)
 {
        VirtualTable *vtable = (VirtualTable *) tab;
+       GdaSqliteProvider *prov = GDA_SQLITE_PROVIDER (gda_connection_get_provider (GDA_CONNECTION 
(vtable->cnc)));
        const gchar *api_misuse_error = NULL;
        gint optype; /* 1 => DELETE
                      * 2 => INSERT
@@ -1602,17 +1614,17 @@ virtualUpdate (sqlite3_vtab *tab, int nData, sqlite3_value **apData, sqlite_int6
        /* determine operation type */
        if (nData == 1)
                optype = 1;
-       else if ((nData > 1) && (SQLITE3_CALL (sqlite3_value_type) (apData[0]) == SQLITE_NULL)) {
+       else if ((nData > 1) && (SQLITE3_CALL (prov, sqlite3_value_type) (apData[0]) == SQLITE_NULL)) {
                optype = 2;
-               if (SQLITE3_CALL (sqlite3_value_type) (apData[1]) != SQLITE_NULL) {
+               if (SQLITE3_CALL (prov, sqlite3_value_type) (apData[1]) != SQLITE_NULL) {
                        /* argc>1 and argv[0] is not NULL: rowid is imposed by SQLite
                         * which is not supported */
                        return SQLITE_READONLY;
                }       }
-       else if ((nData > 1) && (SQLITE3_CALL (sqlite3_value_type) (apData[0]) == SQLITE_INTEGER)) {
+       else if ((nData > 1) && (SQLITE3_CALL (prov, sqlite3_value_type) (apData[0]) == SQLITE_INTEGER)) {
                optype = 3;
-               if (SQLITE3_CALL (sqlite3_value_int) (apData[0]) != 
-                   SQLITE3_CALL (sqlite3_value_int) (apData[1])) {
+               if (SQLITE3_CALL (prov, sqlite3_value_int) (apData[0]) !=
+                   SQLITE3_CALL (prov, sqlite3_value_int) (apData[1])) {
                        /* argc>1 and argv[0]==argv[1]: rowid is imposed by SQLite 
                         * which is not supported */
                        return SQLITE_READONLY;
@@ -1638,7 +1650,7 @@ virtualUpdate (sqlite3_vtab *tab, int nData, sqlite3_value **apData, sqlite_int6
                        return update_data_select_model (tab, optype, nData, apData);
                else {
                        TO_IMPLEMENT;
-                       tab->zErrMsg = SQLITE3_CALL (sqlite3_mprintf)
+                       tab->zErrMsg = SQLITE3_CALL (prov, sqlite3_mprintf)
                                (_("Data model representing the table is read only"));
                        return SQLITE_READONLY;
                }
@@ -1651,8 +1663,8 @@ virtualUpdate (sqlite3_vtab *tab, int nData, sqlite3_value **apData, sqlite_int6
 
        if (optype == 1) {
                /* DELETE */
-               if (SQLITE3_CALL (sqlite3_value_type) (apData[0]) == SQLITE_INTEGER) {
-                       gint rowid = SQLITE3_CALL (sqlite3_value_int) (apData [0]);
+               if (SQLITE3_CALL (prov, sqlite3_value_type) (apData[0]) == SQLITE_INTEGER) {
+                       gint rowid = SQLITE3_CALL (prov, sqlite3_value_int) (apData [0]);
                        return gda_data_model_remove_row (vtable->td->real_model, rowid, NULL) ?
                                SQLITE_OK : SQLITE_READONLY;
                }
@@ -1670,12 +1682,12 @@ virtualUpdate (sqlite3_vtab *tab, int nData, sqlite3_value **apData, sqlite_int6
                        GType type;
                        GValue *value;
                        type = gda_column_get_g_type (gda_data_model_describe_column (vtable->td->real_model, 
i - 2));
-                       if ((type != GDA_TYPE_NULL) && SQLITE3_CALL (sqlite3_value_text) (apData [i]))
-                               value = gda_value_new_from_string ((const gchar*) SQLITE3_CALL 
(sqlite3_value_text) (apData [i]), type);
+                       if ((type != GDA_TYPE_NULL) && SQLITE3_CALL (prov, sqlite3_value_text) (apData [i]))
+                               value = gda_value_new_from_string ((const gchar*) SQLITE3_CALL (prov, 
sqlite3_value_text) (apData [i]), type);
                        else
                                value = gda_value_new_null ();
                        /*g_print ("TXT #%s# => value %p (type=%s) apData[]=%p\n",
-                         SQLITE3_CALL (sqlite3_value_text) (apData [i]), value,
+                         SQLITE3_CALL (prov, sqlite3_value_text) (apData [i]), value,
                          g_type_name (type), apData[i]);*/
                        values = g_list_prepend (values, value);
                }
@@ -1696,13 +1708,13 @@ virtualUpdate (sqlite3_vtab *tab, int nData, sqlite3_value **apData, sqlite_int6
                for (i = 2; i < (nData - 1); i++) {
                        GValue *value;
                        GType type;
-                       gint rowid = SQLITE3_CALL (sqlite3_value_int) (apData [0]);
+                       gint rowid = SQLITE3_CALL (prov, sqlite3_value_int) (apData [0]);
                        gboolean res;
                        GError *error = NULL;
 
-                       /*g_print ("%d => %s\n", i, SQLITE3_CALL (sqlite3_value_text) (apData [i]));*/
+                       /*g_print ("%d => %s\n", i, SQLITE3_CALL (prov, sqlite3_value_text) (apData [i]));*/
                        type = gda_column_get_g_type (gda_data_model_describe_column (vtable->td->real_model, 
i - 2));
-                       value = gda_value_new_from_string ((const gchar*) SQLITE3_CALL (sqlite3_value_text) 
(apData [i]), type);
+                       value = gda_value_new_from_string ((const gchar*) SQLITE3_CALL (prov, 
sqlite3_value_text) (apData [i]), type);
                        res = gda_data_model_set_value_at (vtable->td->real_model, i - 2, rowid,
                                                           value, &error);
                        gda_value_free (value);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]