[libgda] LDAP: execute all API calls in worker thread
- From: Vivien Malerba <vivien src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgda] LDAP: execute all API calls in worker thread
- Date: Sun, 30 Nov 2014 22:06:09 +0000 (UTC)
commit 4b349c46e54e39cd1d3fcf6646798f120340a2fa
Author: Vivien Malerba <malerba gnome-db org>
Date: Sun Nov 30 22:31:22 2014 +0100
LDAP: execute all API calls in worker thread
libgda/gda-blob-op.c | 8 +-
libgda/gda-connection-internal.h | 2 +-
libgda/gda-connection-private.h | 1 +
libgda/gda-connection.c | 28 +-
libgda/gda-data-select.c | 14 +-
libgda/gda-server-provider-private.h | 4 +-
libgda/gda-server-provider.c | 154 +++---
libgda/libgda.symbols | 3 +
providers/ldap/gda-ldap-provider.c | 159 +++++-
providers/ldap/gda-ldap-util.c | 461 +++++++++++-----
providers/ldap/gda-ldap-util.h | 7 +-
providers/ldap/gda-ldap.h | 20 +-
providers/ldap/gdaprov-data-model-ldap.c | 852 +++++++++++++++++++-----------
13 files changed, 1144 insertions(+), 569 deletions(-)
---
diff --git a/libgda/gda-blob-op.c b/libgda/gda-blob-op.c
index b4b367a..d118558 100644
--- a/libgda/gda-blob-op.c
+++ b/libgda/gda-blob-op.c
@@ -223,7 +223,7 @@ gda_blob_op_get_length (GdaBlobOp *op)
gda_lockable_lock ((GdaLockable*) op->priv->cnc); /* CNC LOCK */
GMainContext *context;
- context = _gda_server_provider_get_real_main_context (op->priv->cnc);
+ context = gda_server_provider_get_real_main_context (op->priv->cnc);
WorkerData data;
data.op = op;
@@ -286,7 +286,7 @@ gda_blob_op_read (GdaBlobOp *op, GdaBlob *blob, glong offset, glong size)
gda_lockable_lock ((GdaLockable*) op->priv->cnc); /* CNC LOCK */
GMainContext *context;
- context = _gda_server_provider_get_real_main_context (op->priv->cnc);
+ context = gda_server_provider_get_real_main_context (op->priv->cnc);
WorkerData data;
data.op = op;
@@ -378,7 +378,7 @@ gda_blob_op_write (GdaBlobOp *op, GdaBlob *blob, glong offset)
gda_lockable_lock ((GdaLockable*) op->priv->cnc); /* CNC LOCK */
GMainContext *context;
- context = _gda_server_provider_get_real_main_context (op->priv->cnc);
+ context = gda_server_provider_get_real_main_context (op->priv->cnc);
WorkerData data;
data.op = op;
@@ -442,7 +442,7 @@ gda_blob_op_write_all (GdaBlobOp *op, GdaBlob *blob)
gda_lockable_lock ((GdaLockable*) op->priv->cnc); /* CNC LOCK */
GMainContext *context;
- context = _gda_server_provider_get_real_main_context (op->priv->cnc);
+ context = gda_server_provider_get_real_main_context (op->priv->cnc);
WorkerData data;
data.op = op;
diff --git a/libgda/gda-connection-internal.h b/libgda/gda-connection-internal.h
index b264a18..dc58f2c 100644
--- a/libgda/gda-connection-internal.h
+++ b/libgda/gda-connection-internal.h
@@ -48,7 +48,7 @@ guint _gda_connection_get_exec_slowdown (GdaConnection *cnc);
void _gda_connection_status_start_batch (GdaConnection *cnc, GdaConnectionStatus status);
void _gda_connection_status_stop_batch (GdaConnection *cnc);
-void _gda_connection_set_status (GdaConnection *cnc, GdaConnectionStatus status);
+void gda_connection_set_status (GdaConnection *cnc, GdaConnectionStatus status);
/*
* Opens a connection to an SQLite database. This function is intended to be used
diff --git a/libgda/gda-connection-private.h b/libgda/gda-connection-private.h
index d62d72b..4aedb51 100644
--- a/libgda/gda-connection-private.h
+++ b/libgda/gda-connection-private.h
@@ -53,6 +53,7 @@ void gda_connection_internal_set_provider_data
GDestroyNotify
destroy_func);
GdaServerProviderConnectionData *gda_connection_internal_get_provider_data_error (GdaConnection *cnc, GError
**error);
void _gda_connection_internal_set_worker_thread (GdaConnection *cnc, GThread
*thread);
+GdaWorker *gda_connection_internal_get_worker (GdaServerProviderConnectionData *data);
/*
* Connection's events
diff --git a/libgda/gda-connection.c b/libgda/gda-connection.c
index 42c6d9a..3f0b14a 100644
--- a/libgda/gda-connection.c
+++ b/libgda/gda-connection.c
@@ -1578,15 +1578,17 @@ assert_status_transaction (GdaConnectionStatus old, GdaConnectionStatus new)
}
}
-/*
- * _gda_connection_set_status:
+/**
+ * gda_connection_set_status: (skip)
+ * @cnc: a #GdaConnection
*
- * Set @cnc's new status, may emit the "status-changed" signal along the way
+ * Set @cnc's new status, may emit the "status-changed" signal along the way. This function is reserved to
database
+ * provider's implementation
*
* WARNING: @cnc _MUST_ be locked before this function is called
*/
void
-_gda_connection_set_status (GdaConnection *cnc, GdaConnectionStatus status)
+gda_connection_set_status (GdaConnection *cnc, GdaConnectionStatus status)
{
if (!cnc || (status == cnc->priv->status))
return;
@@ -5914,6 +5916,24 @@ _gda_connection_internal_set_worker_thread (GdaConnection *cnc, GThread *thread)
}
/**
+ * gda_connection_internal_get_worker: (skip)
+ * @data: (allow-none): a #GdaServerProviderConnectionData, or %NULL
+ *
+ * Retreive a pointer to the #GdaWorker used internally by the connection. This function is reserved to
+ * database provider's implementation and should not be used otherwise.
+ *
+ * Returns: (transfer none): the #GdaWorker, or %NULL
+ */
+GdaWorker *
+gda_connection_internal_get_worker (GdaServerProviderConnectionData *data)
+{
+ if (data)
+ return data->worker;
+ else
+ return NULL;
+}
+
+/**
* gda_connection_internal_get_provider_data_error: (skip)
* @cnc: a #GdaConnection object
* @error: (allow-none): a place to store errors, or %NULL
diff --git a/libgda/gda-data-select.c b/libgda/gda-data-select.c
index e9e4d0c..26bd0e8 100644
--- a/libgda/gda-data-select.c
+++ b/libgda/gda-data-select.c
@@ -42,7 +42,7 @@
#include <sql-parser/gda-sql-parser.h>
#include <gda-statement-priv.h>
#include <thread-wrapper/gda-worker.h>
-#include <libgda/gda-server-provider-private.h> /* for _gda_server_provider_get_real_main_context () */
+#include <libgda/gda-server-provider-private.h> /* for gda_server_provider_get_real_main_context () */
#define CLASS(x) (GDA_DATA_SELECT_CLASS (G_OBJECT_GET_CLASS (x)))
@@ -3910,7 +3910,7 @@ static gint
_gda_data_select_fetch_nb_rows (GdaDataSelect *model)
{
GMainContext *context;
- context = _gda_server_provider_get_real_main_context (model->priv->cnc);
+ context = gda_server_provider_get_real_main_context (model->priv->cnc);
gint nbrows = -1;
gint *result;
@@ -3949,7 +3949,7 @@ static gboolean
_gda_data_select_fetch_random (GdaDataSelect *model, GdaRow **prow, gint rownum, GError **error)
{
GMainContext *context;
- context = _gda_server_provider_get_real_main_context (model->priv->cnc);
+ context = gda_server_provider_get_real_main_context (model->priv->cnc);
WorkerData jdata;
jdata.model = model;
@@ -3982,7 +3982,7 @@ static gboolean
_gda_data_select_store_all (GdaDataSelect *model, GError **error)
{
GMainContext *context;
- context = _gda_server_provider_get_real_main_context (model->priv->cnc);
+ context = gda_server_provider_get_real_main_context (model->priv->cnc);
gpointer result;
gda_worker_do_job (model->priv->worker, context, 0, (gpointer) &result, NULL,
@@ -4010,7 +4010,7 @@ static gboolean
_gda_data_select_fetch_next (GdaDataSelect *model, GdaRow **prow, gint rownum, GError **error)
{
GMainContext *context;
- context = _gda_server_provider_get_real_main_context (model->priv->cnc);
+ context = gda_server_provider_get_real_main_context (model->priv->cnc);
WorkerData jdata;
jdata.model = model;
@@ -4043,7 +4043,7 @@ static gboolean
_gda_data_select_fetch_prev (GdaDataSelect *model, GdaRow **prow, gint rownum, GError **error)
{
GMainContext *context;
- context = _gda_server_provider_get_real_main_context (model->priv->cnc);
+ context = gda_server_provider_get_real_main_context (model->priv->cnc);
WorkerData jdata;
jdata.model = model;
@@ -4076,7 +4076,7 @@ static gboolean
_gda_data_select_fetch_at (GdaDataSelect *model, GdaRow **prow, gint rownum, GError **error)
{
GMainContext *context;
- context = _gda_server_provider_get_real_main_context (model->priv->cnc);
+ context = gda_server_provider_get_real_main_context (model->priv->cnc);
WorkerData jdata;
jdata.model = model;
diff --git a/libgda/gda-server-provider-private.h b/libgda/gda-server-provider-private.h
index 0c3ff43..0c0abe5 100644
--- a/libgda/gda-server-provider-private.h
+++ b/libgda/gda-server-provider-private.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2005 Dan Winship <danw src gnome org>
- * Copyright (C) 2005 - 2013 Vivien Malerba <malerba gnome-db org>
+ * Copyright (C) 2005 - 2014 Vivien Malerba <malerba gnome-db org>
* Copyright (C) 2005 �lvaro Pe�a <alvaropg telefonica net>
* Copyright (C) 2007 Murray Cumming <murrayc murrayc com>
*
@@ -40,7 +40,7 @@ struct _GdaServerProviderPrivate {
/*
* Getting the GMainContext to use with the GdaWorker
*/
-GMainContext *_gda_server_provider_get_real_main_context (GdaConnection *cnc);
+GMainContext *gda_server_provider_get_real_main_context (GdaConnection *cnc);
/*
* GdaServerProvider's virtual functions access
diff --git a/libgda/gda-server-provider.c b/libgda/gda-server-provider.c
index afa7187..13691f5 100644
--- a/libgda/gda-server-provider.c
+++ b/libgda/gda-server-provider.c
@@ -495,17 +495,19 @@ _gda_server_provider_create_worker (GdaServerProvider *provider, gboolean for_cn
return (fset->create_worker) (provider, for_cnc);
}
-/*
- * Obtain a #GMainContext on which to iterate.
+/**
+ * gda_server_provider_get_real_main_context: (skip)
* @cnc: (allow-none): a #GdaConnection, or %NULL
*
+ * Obtain a #GMainContext on which to iterate. This function is reserved to database provider's
implementations.
+ *
* NB: if @cnc is NOT %NULL and has a #GdaWorker associated, and if we are in its worker thread, then this
function
* returns %NULL (to avoid generating contexts which are never used)
*
* Returns: a #GMainContext, or %NULL. Don't forget to call g_main_context_unref() when done
*/
GMainContext *
-_gda_server_provider_get_real_main_context (GdaConnection *cnc)
+gda_server_provider_get_real_main_context (GdaConnection *cnc)
{
GMainContext *context;
if (cnc) {
@@ -556,7 +558,7 @@ gda_server_provider_get_version (GdaServerProvider *provider)
g_return_val_if_fail (GDA_IS_SERVER_PROVIDER (provider), NULL);
GMainContext *context;
- context = _gda_server_provider_get_real_main_context (NULL);
+ context = gda_server_provider_get_real_main_context (NULL);
GdaWorker *worker;
worker = _gda_server_provider_create_worker (provider, FALSE);
@@ -602,7 +604,7 @@ gda_server_provider_get_name (GdaServerProvider *provider)
g_return_val_if_fail (GDA_IS_SERVER_PROVIDER (provider), NULL);
GMainContext *context;
- context = _gda_server_provider_get_real_main_context (NULL);
+ context = gda_server_provider_get_real_main_context (NULL);
GdaWorker *worker;
worker = _gda_server_provider_create_worker (provider, FALSE);
@@ -662,7 +664,7 @@ gda_server_provider_get_server_version (GdaServerProvider *provider, GdaConnecti
}
GMainContext *context;
- context = _gda_server_provider_get_real_main_context (cnc);
+ context = gda_server_provider_get_real_main_context (cnc);
WorkerGetInfoData data;
data.worker = cdata->worker;
@@ -739,7 +741,7 @@ gda_server_provider_supports_operation (GdaServerProvider *provider, GdaConnecti
worker = _gda_server_provider_create_worker (provider, FALSE);
GMainContext *context;
- context = _gda_server_provider_get_real_main_context (cnc);
+ context = gda_server_provider_get_real_main_context (cnc);
WorkerSupportsOperationData data;
data.worker = worker;
@@ -951,7 +953,7 @@ gda_server_provider_create_operation (GdaServerProvider *provider, GdaConnection
worker = _gda_server_provider_create_worker (provider, FALSE);
GMainContext *context;
- context = _gda_server_provider_get_real_main_context (cnc);
+ context = gda_server_provider_get_real_main_context (cnc);
WorkerCreateOperationData data;
data.worker = worker;
@@ -1078,7 +1080,7 @@ gda_server_provider_render_operation (GdaServerProvider *provider, GdaConnection
worker = _gda_server_provider_create_worker (provider, FALSE);
GMainContext *context;
- context = _gda_server_provider_get_real_main_context (cnc);
+ context = gda_server_provider_get_real_main_context (cnc);
WorkerRenderOperationData data;
data.worker = worker;
@@ -1161,7 +1163,7 @@ gda_server_provider_perform_operation (GdaServerProvider *provider, GdaConnectio
worker = _gda_server_provider_create_worker (provider, FALSE);
GMainContext *context;
- context = _gda_server_provider_get_real_main_context (cnc);
+ context = gda_server_provider_get_real_main_context (cnc);
WorkerPerformOperationData data;
data.worker = worker;
@@ -1261,7 +1263,7 @@ gda_server_provider_supports_feature (GdaServerProvider *provider, GdaConnection
worker = _gda_server_provider_create_worker (provider, FALSE);
GMainContext *context;
- context = _gda_server_provider_get_real_main_context (cnc);
+ context = gda_server_provider_get_real_main_context (cnc);
WorkerSupportsFeatureData data;
data.worker = worker;
@@ -1339,7 +1341,7 @@ gda_server_provider_get_data_handler_g_type (GdaServerProvider *provider, GdaCon
worker = _gda_server_provider_create_worker (provider, FALSE);
GMainContext *context;
- context = _gda_server_provider_get_real_main_context (cnc);
+ context = gda_server_provider_get_real_main_context (cnc);
WorkerTypeData data;
data.worker = worker;
@@ -1399,7 +1401,7 @@ gda_server_provider_get_data_handler_dbms (GdaServerProvider *provider, GdaConne
worker = _gda_server_provider_create_worker (provider, FALSE);
GMainContext *context;
- context = _gda_server_provider_get_real_main_context (cnc);
+ context = gda_server_provider_get_real_main_context (cnc);
WorkerTypeData data;
data.worker = worker;
@@ -1474,7 +1476,7 @@ gda_server_provider_get_default_dbms_type (GdaServerProvider *provider, GdaConne
worker = _gda_server_provider_create_worker (provider, FALSE);
GMainContext *context;
- context = _gda_server_provider_get_real_main_context (cnc);
+ context = gda_server_provider_get_real_main_context (cnc);
WorkerTypeData data;
data.worker = worker;
@@ -1704,7 +1706,7 @@ gda_server_provider_escape_string (GdaServerProvider *provider, GdaConnection *c
worker = _gda_server_provider_create_worker (provider, FALSE);
GMainContext *context;
- context = _gda_server_provider_get_real_main_context (cnc);
+ context = gda_server_provider_get_real_main_context (cnc);
WorkerEscapeData data;
data.worker = worker;
@@ -1774,7 +1776,7 @@ gda_server_provider_unescape_string (GdaServerProvider *provider, GdaConnection
worker = _gda_server_provider_create_worker (provider, FALSE);
GMainContext *context;
- context = _gda_server_provider_get_real_main_context (cnc);
+ context = gda_server_provider_get_real_main_context (cnc);
WorkerEscapeData data;
data.worker = worker;
@@ -1852,7 +1854,7 @@ gda_server_provider_create_parser (GdaServerProvider *provider, GdaConnection *c
worker = _gda_server_provider_create_worker (provider, FALSE);
GMainContext *context;
- context = _gda_server_provider_get_real_main_context (cnc);
+ context = gda_server_provider_get_real_main_context (cnc);
WorkerParserData data;
data.worker = worker;
@@ -1957,7 +1959,7 @@ _gda_server_provider_create_connection (GdaServerProvider *provider, const gchar
g_return_val_if_fail (!dsn_string || !cnc_string, FALSE);
GMainContext *context;
- context = _gda_server_provider_get_real_main_context (NULL);
+ context = gda_server_provider_get_real_main_context (NULL);
GdaWorker *worker;
worker = _gda_server_provider_create_worker (provider, FALSE);
@@ -2096,7 +2098,7 @@ stage2_open_connection (GdaWorker *worker, GdaConnection *cnc, gpointer result)
if (!cdata) {
g_warning ("Internal error: connection reported as opened, yet no provider data set");
result = NULL;
- _gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_CLOSED);
+ gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_CLOSED);
}
else {
g_signal_emit_by_name (G_OBJECT (cnc), "opened");
@@ -2167,7 +2169,7 @@ _gda_server_provider_open_connection (GdaServerProvider *provider, GdaConnection
if (cb_func) {
if (!gda_worker_set_callback (worker, context,
(GdaWorkerCallback) server_provider_job_done_callback,
provider, error)) {
- _gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_CLOSED);
+ gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_CLOSED);
gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */
gda_worker_unref (worker);
return FALSE;
@@ -2195,7 +2197,7 @@ _gda_server_provider_open_connection (GdaServerProvider *provider, GdaConnection
(GdaWorkerFunc) worker_open_connection,
jdata, NULL, NULL, error);
if (job_id == 0) {
- _gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_CLOSED);
+ gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_CLOSED);
gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */
WorkerOpenConnectionData_free (jdata);
return FALSE; /* error */
@@ -2300,10 +2302,10 @@ stage2_close_connection (GdaConnection *cnc, gpointer result)
if (cdata->provider_data_destroy_func)
cdata->provider_data_destroy_func (cdata);
}
- _gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_CLOSED);
+ gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_CLOSED);
}
else
- _gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_IDLE);
+ gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_IDLE);
gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */
@@ -2336,7 +2338,7 @@ _gda_server_provider_close_connection (GdaServerProvider *provider, GdaConnectio
}
GMainContext *context;
- context = _gda_server_provider_get_real_main_context (cnc);
+ context = gda_server_provider_get_real_main_context (cnc);
WorkerCloseConnectionData *jdata;
jdata = g_slice_new (WorkerCloseConnectionData);
@@ -2344,7 +2346,7 @@ _gda_server_provider_close_connection (GdaServerProvider *provider, GdaConnectio
jdata->provider = provider;
jdata->cnc = g_object_ref (cnc);
- _gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_BUSY);
+ gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_BUSY);
GdaWorker *worker;
worker = cdata->worker;
@@ -2420,7 +2422,7 @@ _gda_server_provider_statement_prepare (GdaServerProvider *provider, GdaConnecti
worker = gda_worker_ref (cdata->worker);
GMainContext *context;
- context = _gda_server_provider_get_real_main_context (cnc);
+ context = gda_server_provider_get_real_main_context (cnc);
WorkerPrepareStatementData data;
data.worker = worker;
@@ -2428,14 +2430,14 @@ _gda_server_provider_statement_prepare (GdaServerProvider *provider, GdaConnecti
data.cnc = cnc;
data.stmt = stmt;
- _gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_BUSY);
+ gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_BUSY);
gpointer retval;
gda_worker_do_job (worker, context, 0, &retval, NULL,
(GdaWorkerFunc) worker_statement_prepare, (gpointer) &data, NULL, NULL, NULL);
if (context)
g_main_context_unref (context);
- _gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_IDLE);
+ gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_IDLE);
gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */
gda_worker_unref (worker);
@@ -2536,7 +2538,7 @@ _gda_server_provider_statement_execute (GdaServerProvider *provider, GdaConnecti
worker = gda_worker_ref (cdata->worker);
GMainContext *context;
- context = _gda_server_provider_get_real_main_context (cnc);
+ context = gda_server_provider_get_real_main_context (cnc);
WorkerExecuteStatementData data;
data.worker = worker;
@@ -2548,14 +2550,14 @@ _gda_server_provider_statement_execute (GdaServerProvider *provider, GdaConnecti
data.col_types = col_types;
data.last_inserted_row = last_inserted_row;
- _gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_BUSY);
+ gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_BUSY);
gpointer retval;
gda_worker_do_job (worker, context, 0, &retval, NULL,
(GdaWorkerFunc) worker_statement_execute, (gpointer) &data, NULL, NULL, error);
if (context)
g_main_context_unref (context);
- _gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_IDLE);
+ gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_IDLE);
gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */
gda_worker_unref (worker);
@@ -2625,7 +2627,7 @@ _gda_server_provider_statement_to_sql (GdaServerProvider *provider, GdaConnecti
worker = _gda_server_provider_create_worker (provider, FALSE);
GMainContext *context;
- context = _gda_server_provider_get_real_main_context (cnc);
+ context = gda_server_provider_get_real_main_context (cnc);
WorkerStmtToSQLData data;
data.worker = worker;
@@ -2636,14 +2638,14 @@ _gda_server_provider_statement_to_sql (GdaServerProvider *provider, GdaConnecti
data.flags = flags;
data.params_used = params_used;
- _gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_BUSY);
+ gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_BUSY);
gpointer retval;
gda_worker_do_job (worker, context, 0, &retval, NULL,
(GdaWorkerFunc) worker_stmt_to_sql, (gpointer) &data, NULL, NULL, error);
if (context)
g_main_context_unref (context);
- _gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_IDLE);
+ gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_IDLE);
if (cnc)
gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */
@@ -2706,7 +2708,7 @@ _gda_server_provider_identifier_quote (GdaServerProvider *provider, GdaConnectio
worker = _gda_server_provider_create_worker (provider, FALSE);
GMainContext *context;
- context = _gda_server_provider_get_real_main_context (cnc);
+ context = gda_server_provider_get_real_main_context (cnc);
WorkerIdentifierQuoteData data;
data.worker = worker;
@@ -2716,14 +2718,14 @@ _gda_server_provider_identifier_quote (GdaServerProvider *provider, GdaConnectio
data.for_meta_store = for_meta_store;
data.force_quotes = force_quotes;
- _gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_BUSY);
+ gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_BUSY);
gpointer retval;
gda_worker_do_job (worker, context, 0, &retval, NULL,
(GdaWorkerFunc) worker_identifier_quote, (gpointer) &data, NULL, NULL, NULL);
if (context)
g_main_context_unref (context);
- _gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_IDLE);
+ gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_IDLE);
if (cnc)
gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */
@@ -2927,7 +2929,7 @@ _gda_server_provider_meta_0arg (GdaServerProvider *provider, GdaConnection *cnc,
worker = gda_worker_ref (cdata->worker);
GMainContext *context;
- context = _gda_server_provider_get_real_main_context (cnc);
+ context = gda_server_provider_get_real_main_context (cnc);
WorkerMetaData data;
data.worker = worker;
@@ -2942,14 +2944,14 @@ _gda_server_provider_meta_0arg (GdaServerProvider *provider, GdaConnection *cnc,
data.values[2] = NULL;
data.values[3] = NULL;
- _gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_BUSY);
+ gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_BUSY);
gpointer retval;
gda_worker_do_job (worker, context, 0, &retval, NULL,
(GdaWorkerFunc) worker_meta, (gpointer) &data, NULL, NULL, NULL);
if (context)
g_main_context_unref (context);
- _gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_IDLE);
+ gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_IDLE);
if (cnc)
gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */
@@ -2988,7 +2990,7 @@ _gda_server_provider_meta_1arg (GdaServerProvider *provider, GdaConnection *cnc,
worker = gda_worker_ref (cdata->worker);
GMainContext *context;
- context = _gda_server_provider_get_real_main_context (cnc);
+ context = gda_server_provider_get_real_main_context (cnc);
WorkerMetaData data;
data.worker = worker;
@@ -3003,14 +3005,14 @@ _gda_server_provider_meta_1arg (GdaServerProvider *provider, GdaConnection *cnc,
data.values[2] = NULL;
data.values[3] = NULL;
- _gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_BUSY);
+ gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_BUSY);
gpointer retval;
gda_worker_do_job (worker, context, 0, &retval, NULL,
(GdaWorkerFunc) worker_meta, (gpointer) &data, NULL, NULL, NULL);
if (context)
g_main_context_unref (context);
- _gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_IDLE);
+ gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_IDLE);
if (cnc)
gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */
@@ -3049,7 +3051,7 @@ _gda_server_provider_meta_2arg (GdaServerProvider *provider, GdaConnection *cnc,
worker = gda_worker_ref (cdata->worker);
GMainContext *context;
- context = _gda_server_provider_get_real_main_context (cnc);
+ context = gda_server_provider_get_real_main_context (cnc);
WorkerMetaData data;
data.worker = worker;
@@ -3064,14 +3066,14 @@ _gda_server_provider_meta_2arg (GdaServerProvider *provider, GdaConnection *cnc,
data.values[2] = NULL;
data.values[3] = NULL;
- _gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_BUSY);
+ gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_BUSY);
gpointer retval;
gda_worker_do_job (worker, context, 0, &retval, NULL,
(GdaWorkerFunc) worker_meta, (gpointer) &data, NULL, NULL, NULL);
if (context)
g_main_context_unref (context);
- _gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_IDLE);
+ gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_IDLE);
if (cnc)
gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */
@@ -3111,7 +3113,7 @@ _gda_server_provider_meta_3arg (GdaServerProvider *provider, GdaConnection *cnc,
worker = gda_worker_ref (cdata->worker);
GMainContext *context;
- context = _gda_server_provider_get_real_main_context (cnc);
+ context = gda_server_provider_get_real_main_context (cnc);
WorkerMetaData data;
data.worker = worker;
@@ -3126,14 +3128,14 @@ _gda_server_provider_meta_3arg (GdaServerProvider *provider, GdaConnection *cnc,
data.values[2] = value2;
data.values[3] = NULL;
- _gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_BUSY);
+ gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_BUSY);
gpointer retval;
gda_worker_do_job (worker, context, 0, &retval, NULL,
(GdaWorkerFunc) worker_meta, (gpointer) &data, NULL, NULL, NULL);
if (context)
g_main_context_unref (context);
- _gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_IDLE);
+ gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_IDLE);
if (cnc)
gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */
@@ -3173,7 +3175,7 @@ _gda_server_provider_meta_4arg (GdaServerProvider *provider, GdaConnection *cnc,
worker = gda_worker_ref (cdata->worker);
GMainContext *context;
- context = _gda_server_provider_get_real_main_context (cnc);
+ context = gda_server_provider_get_real_main_context (cnc);
WorkerMetaData data;
data.worker = worker;
@@ -3188,14 +3190,14 @@ _gda_server_provider_meta_4arg (GdaServerProvider *provider, GdaConnection *cnc,
data.values[2] = value2;
data.values[3] = value3;
- _gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_BUSY);
+ gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_BUSY);
gpointer retval;
gda_worker_do_job (worker, context, 0, &retval, NULL,
(GdaWorkerFunc) worker_meta, (gpointer) &data, NULL, NULL, NULL);
if (context)
g_main_context_unref (context);
- _gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_IDLE);
+ gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_IDLE);
if (cnc)
gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */
@@ -3266,7 +3268,7 @@ _gda_server_provider_begin_transaction (GdaServerProvider *provider, GdaConnecti
worker = gda_worker_ref (cdata->worker);
GMainContext *context;
- context = _gda_server_provider_get_real_main_context (cnc);
+ context = gda_server_provider_get_real_main_context (cnc);
WorkerTransactionData data;
data.worker = worker;
@@ -3275,14 +3277,14 @@ _gda_server_provider_begin_transaction (GdaServerProvider *provider, GdaConnecti
data.name = name;
data.level = level;
- _gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_BUSY);
+ gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_BUSY);
gpointer retval;
gda_worker_do_job (worker, context, 0, &retval, NULL,
(GdaWorkerFunc) worker_begin_transaction, (gpointer) &data, NULL, NULL, error);
if (context)
g_main_context_unref (context);
- _gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_IDLE);
+ gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_IDLE);
gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */
gda_worker_unref (worker);
@@ -3336,7 +3338,7 @@ _gda_server_provider_commit_transaction (GdaServerProvider *provider, GdaConnect
worker = gda_worker_ref (cdata->worker);
GMainContext *context;
- context = _gda_server_provider_get_real_main_context (cnc);
+ context = gda_server_provider_get_real_main_context (cnc);
WorkerTransactionData data;
data.worker = worker;
@@ -3344,14 +3346,14 @@ _gda_server_provider_commit_transaction (GdaServerProvider *provider, GdaConnect
data.cnc = cnc;
data.name = name;
- _gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_BUSY);
+ gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_BUSY);
gpointer retval;
gda_worker_do_job (worker, context, 0, &retval, NULL,
(GdaWorkerFunc) worker_commit_transaction, (gpointer) &data, NULL, NULL, error);
if (context)
g_main_context_unref (context);
- _gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_IDLE);
+ gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_IDLE);
gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */
gda_worker_unref (worker);
@@ -3405,7 +3407,7 @@ _gda_server_provider_rollback_transaction (GdaServerProvider *provider, GdaConne
worker = gda_worker_ref (cdata->worker);
GMainContext *context;
- context = _gda_server_provider_get_real_main_context (cnc);
+ context = gda_server_provider_get_real_main_context (cnc);
WorkerTransactionData data;
data.worker = worker;
@@ -3413,14 +3415,14 @@ _gda_server_provider_rollback_transaction (GdaServerProvider *provider, GdaConne
data.cnc = cnc;
data.name = name;
- _gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_BUSY);
+ gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_BUSY);
gpointer retval;
gda_worker_do_job (worker, context, 0, &retval, NULL,
(GdaWorkerFunc) worker_rollback_transaction, (gpointer) &data, NULL, NULL, error);
if (context)
g_main_context_unref (context);
- _gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_IDLE);
+ gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_IDLE);
gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */
gda_worker_unref (worker);
@@ -3466,7 +3468,7 @@ _gda_server_provider_add_savepoint (GdaServerProvider *provider, GdaConnection *
worker = gda_worker_ref (cdata->worker);
GMainContext *context;
- context = _gda_server_provider_get_real_main_context (cnc);
+ context = gda_server_provider_get_real_main_context (cnc);
WorkerTransactionData data;
data.worker = worker;
@@ -3474,14 +3476,14 @@ _gda_server_provider_add_savepoint (GdaServerProvider *provider, GdaConnection *
data.cnc = cnc;
data.name = name;
- _gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_BUSY);
+ gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_BUSY);
gpointer retval;
gda_worker_do_job (worker, context, 0, &retval, NULL,
(GdaWorkerFunc) worker_add_savepoint, (gpointer) &data, NULL, NULL, error);
if (context)
g_main_context_unref (context);
- _gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_IDLE);
+ gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_IDLE);
gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */
gda_worker_unref (worker);
@@ -3527,7 +3529,7 @@ _gda_server_provider_rollback_savepoint (GdaServerProvider *provider, GdaConnect
worker = gda_worker_ref (cdata->worker);
GMainContext *context;
- context = _gda_server_provider_get_real_main_context (cnc);
+ context = gda_server_provider_get_real_main_context (cnc);
WorkerTransactionData data;
data.worker = worker;
@@ -3535,14 +3537,14 @@ _gda_server_provider_rollback_savepoint (GdaServerProvider *provider, GdaConnect
data.cnc = cnc;
data.name = name;
- _gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_BUSY);
+ gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_BUSY);
gpointer retval;
gda_worker_do_job (worker, context, 0, &retval, NULL,
(GdaWorkerFunc) worker_rollback_savepoint, (gpointer) &data, NULL, NULL, error);
if (context)
g_main_context_unref (context);
- _gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_IDLE);
+ gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_IDLE);
gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */
gda_worker_unref (worker);
@@ -3588,7 +3590,7 @@ _gda_server_provider_delete_savepoint (GdaServerProvider *provider, GdaConnectio
worker = gda_worker_ref (cdata->worker);
GMainContext *context;
- context = _gda_server_provider_get_real_main_context (cnc);
+ context = gda_server_provider_get_real_main_context (cnc);
WorkerTransactionData data;
data.worker = worker;
@@ -3596,14 +3598,14 @@ _gda_server_provider_delete_savepoint (GdaServerProvider *provider, GdaConnectio
data.cnc = cnc;
data.name = name;
- _gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_BUSY);
+ gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_BUSY);
gpointer retval;
gda_worker_do_job (worker, context, 0, &retval, NULL,
(GdaWorkerFunc) worker_delete_savepoint, (gpointer) &data, NULL, NULL, error);
if (context)
g_main_context_unref (context);
- _gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_IDLE);
+ gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_IDLE);
gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */
gda_worker_unref (worker);
@@ -3738,7 +3740,7 @@ _gda_server_provider_xa (GdaServerProvider *provider, GdaConnection *cnc, const
worker = gda_worker_ref (cdata->worker);
GMainContext *context;
- context = _gda_server_provider_get_real_main_context (cnc);
+ context = gda_server_provider_get_real_main_context (cnc);
WorkerXAData data;
data.worker = worker;
@@ -3747,14 +3749,14 @@ _gda_server_provider_xa (GdaServerProvider *provider, GdaConnection *cnc, const
data.trx = trx;
data.type = type;
- _gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_BUSY);
+ gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_BUSY);
gpointer retval;
gda_worker_do_job (worker, context, 0, &retval, NULL,
(GdaWorkerFunc) worker_xa, (gpointer) &data, NULL, NULL, error);
if (context)
g_main_context_unref (context);
- _gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_IDLE);
+ gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_IDLE);
gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */
gda_worker_unref (worker);
@@ -3783,7 +3785,7 @@ _gda_server_provider_xa_recover (GdaServerProvider *provider, GdaConnection *cnc
worker = gda_worker_ref (cdata->worker);
GMainContext *context;
- context = _gda_server_provider_get_real_main_context (cnc);
+ context = gda_server_provider_get_real_main_context (cnc);
WorkerXAData data;
data.worker = worker;
@@ -3792,14 +3794,14 @@ _gda_server_provider_xa_recover (GdaServerProvider *provider, GdaConnection *cnc
data.trx = NULL;
data.type = GDA_XA_RECOVER;
- _gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_BUSY);
+ gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_BUSY);
gpointer retval;
gda_worker_do_job (worker, context, 0, &retval, NULL,
(GdaWorkerFunc) worker_xa, (gpointer) &data, NULL, NULL, error);
if (context)
g_main_context_unref (context);
- _gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_IDLE);
+ gda_connection_set_status (cnc, GDA_CONNECTION_STATUS_IDLE);
gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */
gda_worker_unref (worker);
diff --git a/libgda/libgda.symbols b/libgda/libgda.symbols
index 33ad7ec..a1a4647 100644
--- a/libgda/libgda.symbols
+++ b/libgda/libgda.symbols
@@ -139,6 +139,7 @@
gda_connection_insert_row_into_table_v
gda_connection_internal_change_transaction_state
gda_connection_internal_get_provider_data_error
+ gda_connection_internal_get_worker
gda_connection_internal_reset_transaction_status
gda_connection_internal_savepoint_added
gda_connection_internal_savepoint_removed
@@ -166,6 +167,7 @@
gda_connection_rollback_savepoint
gda_connection_rollback_transaction
gda_connection_set_main_context
+ gda_connection_set_status
gda_connection_statement_execute
gda_connection_statement_execute_non_select
gda_connection_statement_execute_select
@@ -591,6 +593,7 @@
gda_server_provider_get_default_dbms_type
gda_server_provider_get_impl_functions_for_class
gda_server_provider_get_name
+ gda_server_provider_get_real_main_context
gda_server_provider_get_server_version
gda_server_provider_get_type
gda_server_provider_get_version
diff --git a/providers/ldap/gda-ldap-provider.c b/providers/ldap/gda-ldap-provider.c
index 85b4c74..9a0e26a 100644
--- a/providers/ldap/gda-ldap-provider.c
+++ b/providers/ldap/gda-ldap-provider.c
@@ -6,7 +6,7 @@
* Copyright (C) 2004 Julio M. Merino Vidal <jmmv menta net>
* Copyright (C) 2004 J�rg Billeter <j bitron ch>
* Copyright (C) 2004 Szalai Ferenc <szferi einstein ki iif hu>
- * Copyright (C) 2005 - 2012 Vivien Malerba <malerba gnome-db org>
+ * Copyright (C) 2005 - 2014 Vivien Malerba <malerba gnome-db org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -37,6 +37,8 @@
#include "gda-ldap-provider.h"
#include "gdaprov-data-model-ldap.h"
#include "gda-ldap-util.h"
+#include <libgda/gda-server-provider-private.h> /* for gda_server_provider_get_real_main_context () */
+#include <libgda/gda-connection-internal.h> /* for gda_connection_set_status() */
static void gda_ldap_provider_class_init (GdaLdapProviderClass *klass);
static void gda_ldap_provider_init (GdaLdapProvider *provider,
@@ -48,6 +50,7 @@ static const gchar *gda_ldap_provider_get_version (GdaServerProvider *provider);
static GdaConnection *gda_ldap_provider_create_connection (GdaServerProvider *provider);
static gboolean gda_ldap_provider_prepare_connection (GdaServerProvider *provider, GdaConnection *cnc,
GdaQuarkList *params, GdaQuarkList *auth);
+static gboolean gda_ldap_provider_close_connection (GdaServerProvider *provider, GdaConnection *cnc);
static GObject *gda_ldap_provider_statement_execute (GdaServerProvider *provider, GdaConnection *cnc,
GdaStatement *stmt, GdaSet *params,
GdaStatementModelUsage model_usage,
@@ -83,7 +86,7 @@ GdaServerProviderBase ldap_base_functions = {
NULL,
NULL,
gda_ldap_provider_prepare_connection,
- NULL,
+ gda_ldap_provider_close_connection,
NULL,
NULL,
NULL,
@@ -268,6 +271,8 @@ LdapAuthMapping mappings[] = {
};
/*
+ * Function called during initialization phase => no need to use the GdaWorker object
+ *
* Using @url and @username, performs the following tasks:
* - bind to the LDAP server anonymously
* - search the directory to identify the entry for the provided user name,
@@ -631,49 +636,112 @@ gda_ldap_provider_prepare_connection (GdaServerProvider *provider, GdaConnection
g_object_set_data ((GObject*) cnc, "__gda_connection_LDAP", (gpointer) 0x01);
gda_virtual_connection_internal_set_provider_data (GDA_VIRTUAL_CONNECTION (cnc),
cdata, (GDestroyNotify) gda_ldap_free_cnc_data);
- gda_ldap_may_unbind (cdata);
+ gda_ldap_may_unbind (GDA_LDAP_CONNECTION (cnc));
return TRUE;
}
/*
+ * Close connection request
+ *
+ * In this function, the following _must_ be done:
+ * - Actually close the connection to the database using @cnc's associated LdapConnectionData structure
+ * - Free the LdapConnectionData structure and its contents
+ *
+ * Returns: TRUE if no error occurred, or FALSE otherwise (and an ERROR connection event must be added to
@cnc)
+ */
+static gboolean
+gda_ldap_provider_close_connection (GdaServerProvider *provider, GdaConnection *cnc)
+{
+ LdapConnectionData *cdata;
+ g_return_val_if_fail (GDA_IS_CONNECTION (cnc), FALSE);
+ g_return_val_if_fail (gda_connection_get_provider (cnc) == provider, FALSE);
+
+ /* Close the connection using the C API */
+ cdata = (LdapConnectionData*) gda_virtual_connection_internal_get_provider_data
(GDA_VIRTUAL_CONNECTION (cnc));
+ if (!cdata)
+ return FALSE;
+
+ if (cdata->handle) {
+ ldap_unbind_ext (cdata->handle, NULL, NULL);
+ cdata->handle = NULL;
+ }
+
+ GdaServerProviderBase *fset;
+ fset = gda_server_provider_get_impl_functions_for_class (parent_class,
GDA_SERVER_PROVIDER_FUNCTIONS_BASE);
+ return fset->close_connection (provider, cnc);
+}
+
+
+gpointer
+worker_gda_ldap_may_unbind (LdapConnectionData *cdata, GError **error)
+{
+ if (cdata->handle) {
+ ldap_unbind_ext (cdata->handle, NULL, NULL);
+ cdata->handle = NULL;
+ }
+
+ return NULL;
+}
+
+/*
* Unbinds the connection if possible (i.e. if cdata->keep_bound_count is 0)
* This allows to avoid keeping the connection to the LDAP server if unused
*/
void
-gda_ldap_may_unbind (LdapConnectionData *cdata)
+gda_ldap_may_unbind (GdaLdapConnection *cnc)
{
- if (!cdata || (cdata->keep_bound_count > 0))
+ gda_lockable_lock ((GdaLockable*) cnc); /* CNC LOCK */
+
+ LdapConnectionData *cdata;
+ cdata = (LdapConnectionData*) gda_virtual_connection_internal_get_provider_data
(GDA_VIRTUAL_CONNECTION (cnc));
+ if (!cdata || (cdata->keep_bound_count > 0)) {
+ gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */
return;
- if (cdata->handle) {
- ldap_unbind_ext (cdata->handle, NULL, NULL);
- cdata->handle = NULL;
}
+
+ GdaServerProviderConnectionData *pcdata;
+ pcdata = gda_connection_internal_get_provider_data_error ((GdaConnection*) cnc, NULL);
+
+ GdaWorker *worker;
+ worker = gda_worker_ref (gda_connection_internal_get_worker (pcdata));
+
+ GMainContext *context;
+ context = gda_server_provider_get_real_main_context ((GdaConnection *) cnc);
+
+ gpointer retval;
+ gda_worker_do_job (worker, context, 0, &retval, NULL,
+ (GdaWorkerFunc) worker_gda_ldap_may_unbind, (gpointer) cdata, NULL, NULL, NULL);
+ if (context)
+ g_main_context_unref (context);
+
+ gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */
+
+ gda_worker_unref (worker);
}
/*
* Makes sure the connection is opened
*/
gboolean
-gda_ldap_ensure_bound (LdapConnectionData *cdata, GError **error)
+gda_ldap_ensure_bound (GdaLdapConnection *cnc, GError **error)
{
+ LdapConnectionData *cdata;
+ cdata = (LdapConnectionData*) gda_virtual_connection_internal_get_provider_data
(GDA_VIRTUAL_CONNECTION (cnc));
+
if (!cdata)
return FALSE;
else if (cdata->handle)
return TRUE;
- return gda_ldap_rebind (cdata, error);
+ return gda_ldap_rebind (cnc, error);
}
-/*
- * Reopens a connection after the server has closed it (possibly because of a timeout)
- *
- * If it fails, then @cdata is left unchanged, otherwise it is modified to be useable again.
- */
-gboolean
-gda_ldap_rebind (LdapConnectionData *cdata, GError **error)
+
+gpointer
+worker_gda_ldap_rebind (LdapConnectionData *cdata, GError **error)
{
if (!cdata)
- return FALSE;
+ return NULL;
/*g_print ("Trying to reconnect...\n");*/
LDAP *ld;
@@ -682,7 +750,7 @@ gda_ldap_rebind (LdapConnectionData *cdata, GError **error)
if (res != LDAP_SUCCESS) {
g_set_error (error, GDA_CONNECTION_ERROR, GDA_CONNECTION_OPEN_ERROR,
"%s", ldap_err2string (res));
- return FALSE;
+ return NULL;
}
/* set protocol version to 3 by default */
@@ -697,7 +765,7 @@ gda_ldap_rebind (LdapConnectionData *cdata, GError **error)
g_set_error (error, GDA_CONNECTION_ERROR, GDA_CONNECTION_OPEN_ERROR,
"%s", ldap_err2string (res));
ldap_unbind_ext (ld, NULL, NULL);
- return FALSE;
+ return NULL;
}
}
@@ -721,7 +789,7 @@ gda_ldap_rebind (LdapConnectionData *cdata, GError **error)
g_set_error (error, GDA_CONNECTION_ERROR, GDA_CONNECTION_OPEN_ERROR,
"%s", ldap_err2string (res));
ldap_unbind_ext (ld, NULL, NULL);
- return FALSE;
+ return NULL;
}
/* time limit */
@@ -731,7 +799,7 @@ gda_ldap_rebind (LdapConnectionData *cdata, GError **error)
g_set_error (error, GDA_CONNECTION_ERROR, GDA_CONNECTION_OPEN_ERROR,
"%s", ldap_err2string (res));
ldap_unbind_ext (ld, NULL, NULL);
- return FALSE;
+ return NULL;
}
/* size limit */
@@ -741,7 +809,7 @@ gda_ldap_rebind (LdapConnectionData *cdata, GError **error)
g_set_error (error, GDA_CONNECTION_ERROR, GDA_CONNECTION_OPEN_ERROR,
"%s", ldap_err2string (res));
ldap_unbind_ext (ld, NULL, NULL);
- return FALSE;
+ return NULL;
}
/* all ok */
@@ -752,7 +820,46 @@ gda_ldap_rebind (LdapConnectionData *cdata, GError **error)
cdata->handle = ld;
/*g_print ("Reconnected!\n");*/
- return TRUE;
+ return (gpointer) 0x01;
+}
+
+/*
+ * Reopens a connection after the server has closed it (possibly because of a timeout)
+ */
+gboolean
+gda_ldap_rebind (GdaLdapConnection *cnc, GError **error)
+{
+ g_return_val_if_fail (GDA_IS_LDAP_CONNECTION (cnc), FALSE);
+ gda_lockable_lock ((GdaLockable*) cnc); /* CNC LOCK */
+
+ LdapConnectionData *cdata;
+ cdata = (LdapConnectionData*) gda_virtual_connection_internal_get_provider_data
(GDA_VIRTUAL_CONNECTION (cnc));
+ if (!cdata) {
+ gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */
+ g_warning ("cdata != NULL failed");
+ return FALSE;
+ }
+
+ GdaServerProviderConnectionData *pcdata;
+ pcdata = gda_connection_internal_get_provider_data_error ((GdaConnection*) cnc, NULL);
+
+ GdaWorker *worker;
+ worker = gda_worker_ref (gda_connection_internal_get_worker (pcdata));
+
+ GMainContext *context;
+ context = gda_server_provider_get_real_main_context ((GdaConnection *) cnc);
+
+ gpointer retval;
+ gda_worker_do_job (worker, context, 0, &retval, NULL,
+ (GdaWorkerFunc) worker_gda_ldap_rebind, (gpointer) cdata, NULL, NULL, error);
+ if (context)
+ g_main_context_unref (context);
+
+ gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */
+
+ gda_worker_unref (worker);
+
+ return retval ? TRUE : FALSE;
}
/*
@@ -967,9 +1074,7 @@ gda_ldap_provider_statement_execute (GdaServerProvider *provider, GdaConnection
}
/* check connection to LDAP is Ok */
- LdapConnectionData *cdata;
- cdata = (LdapConnectionData*) gda_virtual_connection_internal_get_provider_data
(GDA_VIRTUAL_CONNECTION (cnc));
- if (! gda_ldap_ensure_bound (cdata, error))
+ if (! gda_ldap_ensure_bound (GDA_LDAP_CONNECTION (cnc), error))
return NULL;
GdaServerProviderBase *fset;
diff --git a/providers/ldap/gda-ldap-util.c b/providers/ldap/gda-ldap-util.c
index 3c0eea9..b4f09bb 100644
--- a/providers/ldap/gda-ldap-util.c
+++ b/providers/ldap/gda-ldap-util.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 - 2012 Vivien Malerba <malerba gnome-db org>
+ * Copyright (C) 2011 - 2014 Vivien Malerba <malerba gnome-db org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -22,9 +22,10 @@
#include <glib/gi18n-lib.h>
#include "gda-ldap.h"
#include "gda-ldap-util.h"
-#include <sqlite/virtual/gda-ldap-connection.h>
#include <gda-util.h>
#include <libgda/gda-debug-macros.h>
+#include <libgda/gda-server-provider-private.h> /* for gda_server_provider_get_real_main_context () */
+#include <libgda/gda-connection-internal.h> /* for gda_connection_set_status() */
static void
ldap_attribute_free (LdapAttribute *lat)
@@ -330,36 +331,35 @@ gda_ldap_get_type_info (const gchar *oid)
return retval ? retval : &unknown_type;
}
-/**
- * gda_ldap_get_attr_info:
- *
- * Returns: the #LdapAttribute for @attribute, or %NULL
- */
-LdapAttribute *
-gda_ldap_get_attr_info (LdapConnectionData *cdata, const gchar *attribute)
+typedef struct {
+ GdaLdapConnection *cnc;
+ LdapConnectionData *cdata;
+ const gchar *attribute;
+} WorkerLdapAttrInfoData;
+
+static LdapAttribute *
+worker_gda_ldap_get_attr_info (WorkerLdapAttrInfoData *data, GError **error)
{
LdapAttribute *retval = NULL;
- if (! attribute || !cdata)
- return NULL;
- if (cdata->attributes_hash)
- return g_hash_table_lookup (cdata->attributes_hash, attribute);
+ if (data->cdata->attributes_hash)
+ return g_hash_table_lookup (data->cdata->attributes_hash, data->attribute);
/* initialize known types */
- cdata->attributes_hash = g_hash_table_new_full (g_str_hash, g_str_equal,
+ data->cdata->attributes_hash = g_hash_table_new_full (g_str_hash, g_str_equal,
NULL,
(GDestroyNotify) ldap_attribute_free);
- if (cdata->attributes_cache_file) {
+ if (data->cdata->attributes_cache_file) {
/* try to load from cache file, which must contain one line per attribute:
* <syntax oid>,0|1,<attribute name>
*/
- gchar *data;
- if (g_file_get_contents (cdata->attributes_cache_file, &data, NULL, NULL)) {
+ gchar *fdata;
+ if (g_file_get_contents (data->cdata->attributes_cache_file, &fdata, NULL, NULL)) {
gchar *start, *ptr;
gchar **array;
- start = data;
+ start = fdata;
while (1) {
gboolean done = FALSE;
for (ptr = start; *ptr && (*ptr != '\n'); ptr++);
@@ -376,7 +376,7 @@ gda_ldap_get_attr_info (LdapConnectionData *cdata, const gchar *attribute)
lat->name = g_strdup (array[2]);
lat->type = gda_ldap_get_type_info (array[0]);
lat->single_value = (*array[1] == '0' ? FALSE : TRUE);
- g_hash_table_insert (cdata->attributes_hash,
+ g_hash_table_insert (data->cdata->attributes_hash,
lat->name, lat);
/*g_print ("CACHE ADDED [%s][%p][%d] for OID %s\n",
lat->name, lat->type, lat->single_value,
@@ -389,8 +389,8 @@ gda_ldap_get_attr_info (LdapConnectionData *cdata, const gchar *attribute)
else
start = ptr+1;
}
- g_free (data);
- return g_hash_table_lookup (cdata->attributes_hash, attribute);
+ g_free (fdata);
+ return g_hash_table_lookup (data->cdata->attributes_hash, data->attribute);
}
}
@@ -403,25 +403,25 @@ gda_ldap_get_attr_info (LdapConnectionData *cdata, const gchar *attribute)
char *schema_attrs[] = {"attributeTypes", NULL};
/* look for subschema */
- if (! gda_ldap_ensure_bound (cdata, NULL))
+ if (! gda_ldap_ensure_bound (data->cnc, NULL))
return NULL;
- res = ldap_search_ext_s (cdata->handle, "", LDAP_SCOPE_BASE,
+ res = ldap_search_ext_s (data->cdata->handle, "", LDAP_SCOPE_BASE,
"(objectclass=*)",
subschemasubentry, 0,
NULL, NULL, NULL, 0,
&msg);
if (res != LDAP_SUCCESS) {
- gda_ldap_may_unbind (cdata);
+ gda_ldap_may_unbind (data->cnc);
return NULL;
}
- if ((entry = ldap_first_entry (cdata->handle, msg))) {
+ if ((entry = ldap_first_entry (data->cdata->handle, msg))) {
char *attr;
BerElement *ber;
- if ((attr = ldap_first_attribute (cdata->handle, entry, &ber))) {
+ if ((attr = ldap_first_attribute (data->cdata->handle, entry, &ber))) {
BerValue **bvals;
- if ((bvals = ldap_get_values_len (cdata->handle, entry, attr))) {
+ if ((bvals = ldap_get_values_len (data->cdata->handle, entry, attr))) {
subschema = g_strdup (bvals[0]->bv_val);
ldap_value_free_len (bvals);
}
@@ -433,41 +433,41 @@ gda_ldap_get_attr_info (LdapConnectionData *cdata, const gchar *attribute)
ldap_msgfree (msg);
if (! subschema) {
- gda_ldap_may_unbind (cdata);
+ gda_ldap_may_unbind (data->cnc);
return NULL;
}
/* look for attributeTypes */
- res = ldap_search_ext_s (cdata->handle, subschema, LDAP_SCOPE_BASE,
+ res = ldap_search_ext_s (data->cdata->handle, subschema, LDAP_SCOPE_BASE,
"(objectclass=*)",
schema_attrs, 0,
NULL, NULL, NULL, 0,
&msg);
g_free (subschema);
if (res != LDAP_SUCCESS) {
- gda_ldap_may_unbind (cdata);
+ gda_ldap_may_unbind (data->cnc);
return NULL;
}
- if (cdata->attributes_cache_file)
+ if (data->cdata->attributes_cache_file)
string = g_string_new ("# Cache file. This file can safely be removed, in this case\n"
"# it will be automatically recreated.\n"
"# DO NOT MODIFY\n");
- for (entry = ldap_first_entry (cdata->handle, msg);
+ for (entry = ldap_first_entry (data->cdata->handle, msg);
entry;
- entry = ldap_next_entry (cdata->handle, msg)) {
+ entry = ldap_next_entry (data->cdata->handle, msg)) {
char *attr;
BerElement *ber;
- for (attr = ldap_first_attribute (cdata->handle, msg, &ber);
+ for (attr = ldap_first_attribute (data->cdata->handle, msg, &ber);
attr;
- attr = ldap_next_attribute (cdata->handle, msg, ber)) {
+ attr = ldap_next_attribute (data->cdata->handle, msg, ber)) {
if (strcasecmp(attr, "attributeTypes")) {
ldap_memfree (attr);
continue;
}
BerValue **bvals;
- bvals = ldap_get_values_len (cdata->handle, entry, attr);
+ bvals = ldap_get_values_len (data->cdata->handle, entry, attr);
if (bvals) {
gint i;
for (i = 0; bvals[i]; i++) {
@@ -484,7 +484,7 @@ gda_ldap_get_attr_info (LdapConnectionData *cdata, const gchar *attribute)
lat->name = g_strdup (at->at_names [0]);
lat->type = gda_ldap_get_type_info (at->at_syntax_oid);
lat->single_value = (at->at_single_value == 0 ? FALSE : TRUE);
- g_hash_table_insert (cdata->attributes_hash,
+ g_hash_table_insert (data->cdata->attributes_hash,
lat->name, lat);
/*g_print ("ADDED [%s][%p][%d] for OID %s\n",
lat->name, lat->type, lat->single_value,
@@ -510,21 +510,66 @@ gda_ldap_get_attr_info (LdapConnectionData *cdata, const gchar *attribute)
ldap_msgfree (msg);
if (string) {
- if (! g_file_set_contents (cdata->attributes_cache_file, string->str, -1, NULL)) {
+ if (! g_file_set_contents (data->cdata->attributes_cache_file, string->str, -1, NULL)) {
gchar *dirname;
- dirname = g_path_get_dirname (cdata->attributes_cache_file);
+ dirname = g_path_get_dirname (data->cdata->attributes_cache_file);
g_mkdir_with_parents (dirname, 0700);
g_free (dirname);
- g_file_set_contents (cdata->attributes_cache_file, string->str, -1, NULL);
+ g_file_set_contents (data->cdata->attributes_cache_file, string->str, -1, NULL);
}
g_string_free (string, TRUE);
}
- gda_ldap_may_unbind (cdata);
- retval = g_hash_table_lookup (cdata->attributes_hash, attribute);
+ gda_ldap_may_unbind (data->cnc);
+ retval = g_hash_table_lookup (data->cdata->attributes_hash, data->attribute);
return retval;
}
+/**
+ * gda_ldap_get_attr_info:
+ * @cnc: a #GdaLdapConnection
+ * @cdata:
+ * @attribute:
+ *
+ * Returns: (transfer none): the #LdapAttribute for @attribute, or %NULL
+ */
+LdapAttribute *
+gda_ldap_get_attr_info (GdaLdapConnection *cnc, LdapConnectionData *cdata, const gchar *attribute)
+{
+ g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL);
+ if (! attribute || !cdata)
+ return NULL;
+
+ gda_lockable_lock ((GdaLockable*) cnc); /* CNC LOCK */
+
+ GdaServerProviderConnectionData *pcdata;
+ pcdata = gda_connection_internal_get_provider_data_error ((GdaConnection*) cnc, NULL);
+
+ GdaWorker *worker;
+ worker = gda_worker_ref (gda_connection_internal_get_worker (pcdata));
+
+ GMainContext *context;
+ context = gda_server_provider_get_real_main_context ((GdaConnection *) cnc);
+
+ WorkerLdapAttrInfoData data;
+ data.cnc = cnc;
+ data.cdata = cdata;
+ data.attribute = attribute;
+
+ gda_connection_set_status ((GdaConnection*) cnc, GDA_CONNECTION_STATUS_BUSY);
+ gpointer retval;
+ gda_worker_do_job (worker, context, 0, &retval, NULL,
+ (GdaWorkerFunc) worker_gda_ldap_get_attr_info, (gpointer) &data, NULL, NULL, NULL);
+ if (context)
+ g_main_context_unref (context);
+
+ gda_connection_set_status ((GdaConnection*) cnc, GDA_CONNECTION_STATUS_IDLE);
+ gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */
+
+ gda_worker_unref (worker);
+ return (LdapAttribute*) retval;
+}
+
/*
* Classes
*/
@@ -532,32 +577,21 @@ static gchar **make_array_from_strv (char **values, guint *out_size);
static void classes_h_func (GdaLdapClass *lcl, gchar **supclasses, LdapConnectionData *cdata);
static gint classes_sort (GdaLdapClass *lcl1, GdaLdapClass *lcl2);
-/**
- * gdaprov_ldap_get_class_info:
- * @cnc: a #GdaLdapConnection (not %NULL)
- * @classname: the class name (not %NULL)
- *
- * Returns: the #GdaLdapClass for @classname, or %NULL
- */
-GdaLdapClass *
-gdaprov_ldap_get_class_info (GdaLdapConnection *cnc, const gchar *classname)
-{
- GdaLdapClass *retval = NULL;
+typedef struct {
+ GdaLdapConnection *cnc;
LdapConnectionData *cdata;
- g_return_val_if_fail (GDA_IS_LDAP_CONNECTION (cnc), NULL);
- g_return_val_if_fail (classname, NULL);
-
- cdata = (LdapConnectionData*) gda_virtual_connection_internal_get_provider_data
(GDA_VIRTUAL_CONNECTION (cnc));
- if (!cdata)
- return NULL;
+ const gchar *classname;
+} WorkerLdapClassInfoData;
- if (cdata->classes_hash)
- return g_hash_table_lookup (cdata->classes_hash, classname);
+static GdaLdapClass *
+worker_gdaprov_ldap_get_class_info (WorkerLdapClassInfoData *data, GError **error)
+{
+ GdaLdapClass *retval = NULL;
/* initialize known classes */
- cdata->classes_hash = g_hash_table_new_full (g_str_hash, g_str_equal,
- NULL,
- (GDestroyNotify) ldap_class_free);
+ data->cdata->classes_hash = g_hash_table_new_full (g_str_hash, g_str_equal,
+ NULL,
+ (GDestroyNotify) ldap_class_free);
LDAPMessage *msg, *entry;
int res;
@@ -567,25 +601,25 @@ gdaprov_ldap_get_class_info (GdaLdapConnection *cnc, const gchar *classname)
char *schema_attrs[] = {"objectClasses", NULL};
/* look for subschema */
- if (! gda_ldap_ensure_bound (cdata, NULL))
+ if (! gda_ldap_ensure_bound (data->cnc, NULL))
return NULL;
- res = ldap_search_ext_s (cdata->handle, "", LDAP_SCOPE_BASE,
+ res = ldap_search_ext_s (data->cdata->handle, "", LDAP_SCOPE_BASE,
"(objectclass=*)",
subschemasubentry, 0,
NULL, NULL, NULL, 0,
&msg);
if (res != LDAP_SUCCESS) {
- gda_ldap_may_unbind (cdata);
+ gda_ldap_may_unbind (data->cnc);
return NULL;
}
- if ((entry = ldap_first_entry (cdata->handle, msg))) {
+ if ((entry = ldap_first_entry (data->cdata->handle, msg))) {
char *attr;
BerElement *ber;
- if ((attr = ldap_first_attribute (cdata->handle, entry, &ber))) {
+ if ((attr = ldap_first_attribute (data->cdata->handle, entry, &ber))) {
BerValue **bvals;
- if ((bvals = ldap_get_values_len (cdata->handle, entry, attr))) {
+ if ((bvals = ldap_get_values_len (data->cdata->handle, entry, attr))) {
subschema = g_strdup (bvals[0]->bv_val);
ldap_value_free_len (bvals);
}
@@ -597,39 +631,39 @@ gdaprov_ldap_get_class_info (GdaLdapConnection *cnc, const gchar *classname)
ldap_msgfree (msg);
if (! subschema) {
- gda_ldap_may_unbind (cdata);
+ gda_ldap_may_unbind (data->cnc);
return NULL;
}
/* look for attributeTypes */
- res = ldap_search_ext_s (cdata->handle, subschema, LDAP_SCOPE_BASE,
+ res = ldap_search_ext_s (data->cdata->handle, subschema, LDAP_SCOPE_BASE,
"(objectclass=*)",
schema_attrs, 0,
NULL, NULL, NULL, 0,
&msg);
g_free (subschema);
if (res != LDAP_SUCCESS) {
- gda_ldap_may_unbind (cdata);
+ gda_ldap_may_unbind (data->cnc);
return NULL;
}
GHashTable *h_refs;
h_refs = g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify) g_strfreev);
- for (entry = ldap_first_entry (cdata->handle, msg);
+ for (entry = ldap_first_entry (data->cdata->handle, msg);
entry;
- entry = ldap_next_entry (cdata->handle, msg)) {
+ entry = ldap_next_entry (data->cdata->handle, msg)) {
char *attr;
BerElement *ber;
- for (attr = ldap_first_attribute (cdata->handle, msg, &ber);
+ for (attr = ldap_first_attribute (data->cdata->handle, msg, &ber);
attr;
- attr = ldap_next_attribute (cdata->handle, msg, ber)) {
+ attr = ldap_next_attribute (data->cdata->handle, msg, ber)) {
if (strcasecmp(attr, "objectClasses")) {
ldap_memfree (attr);
continue;
}
BerValue **bvals;
- bvals = ldap_get_values_len (cdata->handle, entry, attr);
+ bvals = ldap_get_values_len (data->cdata->handle, entry, attr);
if (bvals) {
gint i;
for (i = 0; bvals[i]; i++) {
@@ -655,7 +689,7 @@ gdaprov_ldap_get_class_info (GdaLdapConnection *cnc, const gchar *classname)
g_print (" oc_names[%d] = %s\n",
k, lcl->names[k]);
#endif
- g_hash_table_insert (cdata->classes_hash,
+ g_hash_table_insert (data->cdata->classes_hash,
lcl->names[k],
lcl);
}
@@ -692,7 +726,7 @@ gdaprov_ldap_get_class_info (GdaLdapConnection *cnc, const gchar *classname)
if (refs)
g_hash_table_insert (h_refs, lcl, refs);
else
- cdata->top_classes = g_slist_insert_sorted
(cdata->top_classes,
+ data->cdata->top_classes = g_slist_insert_sorted
(data->cdata->top_classes,
lcl, (GCompareFunc)
classes_sort);
#ifdef CLASS_DEBUG
for (k = 0; oc->oc_sup_oids && oc->oc_sup_oids[k]; k++)
@@ -732,14 +766,69 @@ gdaprov_ldap_get_class_info (GdaLdapConnection *cnc, const gchar *classname)
ldap_msgfree (msg);
/* create hierarchy */
- g_hash_table_foreach (h_refs, (GHFunc) classes_h_func, cdata);
+ g_hash_table_foreach (h_refs, (GHFunc) classes_h_func, data->cdata);
g_hash_table_destroy (h_refs);
- retval = g_hash_table_lookup (cdata->classes_hash, classname);
- gda_ldap_may_unbind (cdata);
+ retval = g_hash_table_lookup (data->cdata->classes_hash, data->classname);
+ gda_ldap_may_unbind (data->cnc);
return retval;
}
+/**
+ * gdaprov_ldap_get_class_info:
+ * @cnc: a #GdaLdapConnection (not %NULL)
+ * @classname: the class name (not %NULL)
+ *
+ * Returns: the #GdaLdapClass for @classname, or %NULL
+ */
+GdaLdapClass *
+gdaprov_ldap_get_class_info (GdaLdapConnection *cnc, const gchar *classname)
+{
+ g_return_val_if_fail (GDA_IS_LDAP_CONNECTION (cnc), NULL);
+ g_return_val_if_fail (classname, NULL);
+
+ gda_lockable_lock ((GdaLockable*) cnc); /* CNC LOCK */
+
+ LdapConnectionData *cdata;
+ cdata = (LdapConnectionData*) gda_virtual_connection_internal_get_provider_data
(GDA_VIRTUAL_CONNECTION (cnc));
+ if (!cdata) {
+ gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */
+ return NULL;
+ }
+
+ if (cdata->classes_hash) {
+ gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */
+ return g_hash_table_lookup (cdata->classes_hash, classname);
+ }
+
+ GdaServerProviderConnectionData *pcdata;
+ pcdata = gda_connection_internal_get_provider_data_error ((GdaConnection*) cnc, NULL);
+
+ GdaWorker *worker;
+ worker = gda_worker_ref (gda_connection_internal_get_worker (pcdata));
+
+ GMainContext *context;
+ context = gda_server_provider_get_real_main_context ((GdaConnection *) cnc);
+
+ WorkerLdapClassInfoData data;
+ data.cnc = cnc;
+ data.cdata = cdata;
+ data.classname = classname;
+
+ gda_connection_set_status ((GdaConnection*) cnc, GDA_CONNECTION_STATUS_BUSY);
+ gpointer retval;
+ gda_worker_do_job (worker, context, 0, &retval, NULL,
+ (GdaWorkerFunc) worker_gdaprov_ldap_get_class_info, (gpointer) &data, NULL, NULL,
NULL);
+ if (context)
+ g_main_context_unref (context);
+
+ gda_connection_set_status ((GdaConnection*) cnc, GDA_CONNECTION_STATUS_IDLE);
+ gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */
+
+ gda_worker_unref (worker);
+ return (GdaLdapClass*) retval;
+}
+
static gint
my_sort_func (gconstpointer a, gconstpointer b)
{
@@ -831,14 +920,14 @@ gdaprov_ldap_get_top_classes (GdaLdapConnection *cnc)
* to the specified GType if any)
*/
GType
-gda_ldap_get_g_type (LdapConnectionData *cdata, const gchar *attribute_name, const gchar *specified_gtype)
+gda_ldap_get_g_type (GdaLdapConnection *cnc, LdapConnectionData *cdata, const gchar *attribute_name, const
gchar *specified_gtype)
{
GType coltype = GDA_TYPE_NULL;
if (specified_gtype)
coltype = gda_g_type_from_string (specified_gtype);
if ((coltype == G_TYPE_INVALID) || (coltype == GDA_TYPE_NULL)) {
LdapAttribute *lat;
- lat = gda_ldap_get_attr_info (cdata, attribute_name);
+ lat = gda_ldap_get_attr_info (cnc, cdata, attribute_name);
if (lat)
coltype = lat->type->gtype;
}
@@ -1166,7 +1255,6 @@ gboolean
gda_ldap_parse_dn (const char *attr, gchar **out_userdn)
{
LDAPDN tmpDN;
-
if (out_userdn)
*out_userdn = NULL;
@@ -1209,27 +1297,24 @@ attr_array_sort_func (gconstpointer a, gconstpointer b)
return strcmp (att1->attr_name, att2->attr_name);
}
-GdaLdapEntry *
-gdaprov_ldap_describe_entry (GdaLdapConnection *cnc, const gchar *dn, GError **error)
-{
+typedef struct {
+ GdaLdapConnection *cnc;
LdapConnectionData *cdata;
- g_return_val_if_fail (GDA_IS_LDAP_CONNECTION (cnc), NULL);
- g_return_val_if_fail (!dn || (dn && *dn), NULL);
+ const gchar *dn;
+} WorkerLdapDescrEntryData;
- cdata = (LdapConnectionData*) gda_virtual_connection_internal_get_provider_data
(GDA_VIRTUAL_CONNECTION (cnc));
- if (!cdata)
- return NULL;
-
-
- if (! gda_ldap_ensure_bound (cdata, error))
+static GdaLdapEntry *
+worker_gdaprov_ldap_describe_entry (WorkerLdapDescrEntryData *data, GError **error)
+{
+ if (! gda_ldap_ensure_bound (data->cnc, error))
return NULL;
int res;
LDAPMessage *msg = NULL;
const gchar *real_dn;
- real_dn = dn ? dn : cdata->base_dn;
+ real_dn = data->dn ? data->dn : data->cdata->base_dn;
retry:
- res = ldap_search_ext_s (cdata->handle, real_dn, LDAP_SCOPE_BASE,
+ res = ldap_search_ext_s (data->cdata->handle, real_dn, LDAP_SCOPE_BASE,
"(objectClass=*)", NULL, 0,
NULL, NULL, NULL, -1,
&msg);
@@ -1243,10 +1328,10 @@ gdaprov_ldap_describe_entry (GdaLdapConnection *cnc, const gchar *dn, GError **e
GdaLdapEntry *lentry;
GArray *array = NULL;
- nb_entries = ldap_count_entries (cdata->handle, msg);
+ nb_entries = ldap_count_entries (data->cdata->handle, msg);
if (nb_entries == 0) {
ldap_msgfree (msg);
- gda_ldap_may_unbind (cdata);
+ gda_ldap_may_unbind (data->cnc);
return NULL;
}
else if (nb_entries > 1) {
@@ -1254,7 +1339,7 @@ gdaprov_ldap_describe_entry (GdaLdapConnection *cnc, const gchar *dn, GError **e
GDA_SERVER_PROVIDER_INTERNAL_ERROR,
_("LDAP server returned more than one entry with DN '%s'"),
real_dn);
- gda_ldap_may_unbind (cdata);
+ gda_ldap_may_unbind (data->cnc);
return NULL;
}
@@ -1262,13 +1347,13 @@ gdaprov_ldap_describe_entry (GdaLdapConnection *cnc, const gchar *dn, GError **e
lentry->dn = g_strdup (real_dn);
lentry->attributes_hash = g_hash_table_new (g_str_hash, g_str_equal);
array = g_array_new (TRUE, FALSE, sizeof (GdaLdapAttribute*));
- ldap_row = ldap_first_entry (cdata->handle, msg);
- for (attr = ldap_first_attribute (cdata->handle, ldap_row, &ber);
+ ldap_row = ldap_first_entry (data->cdata->handle, msg);
+ for (attr = ldap_first_attribute (data->cdata->handle, ldap_row, &ber);
attr;
- attr = ldap_next_attribute (cdata->handle, ldap_row, ber)) {
+ attr = ldap_next_attribute (data->cdata->handle, ldap_row, ber)) {
BerValue **bvals;
GArray *varray = NULL;
- bvals = ldap_get_values_len (cdata->handle, ldap_row, attr);
+ bvals = ldap_get_values_len (data->cdata->handle, ldap_row, attr);
if (bvals) {
gint i;
for (i = 0; bvals [i]; i++) {
@@ -1276,9 +1361,9 @@ gdaprov_ldap_describe_entry (GdaLdapConnection *cnc, const gchar *dn, GError **e
varray = g_array_new (TRUE, FALSE, sizeof (GValue *));
GValue *value;
GType type;
- type = gda_ldap_get_g_type (cdata, attr, NULL);
+ type = gda_ldap_get_g_type (data->cnc, data->cdata, attr, NULL);
/*g_print ("Type for attr %s is %s\n", attr, gda_g_type_to_string
(type)); */
- value = gda_ldap_attr_value_to_g_value (cdata, type, bvals[i]);
+ value = gda_ldap_attr_value_to_g_value (data->cdata, type, bvals[i]);
g_array_append_val (varray, value);
}
ldap_value_free_len (bvals);
@@ -1305,13 +1390,13 @@ gdaprov_ldap_describe_entry (GdaLdapConnection *cnc, const gchar *dn, GError **e
lentry->nb_attributes = array->len;
g_array_free (array, FALSE);
}
- gda_ldap_may_unbind (cdata);
+ gda_ldap_may_unbind (data->cnc);
return lentry;
}
case LDAP_SERVER_DOWN: {
gint i;
for (i = 0; i < 5; i++) {
- if (gda_ldap_rebind (cdata, NULL))
+ if (gda_ldap_rebind (data->cnc, NULL))
goto retry;
g_usleep (G_USEC_PER_SEC * 2);
}
@@ -1319,15 +1404,58 @@ gdaprov_ldap_describe_entry (GdaLdapConnection *cnc, const gchar *dn, GError **e
default: {
/* error */
int ldap_errno;
- ldap_get_option (cdata->handle, LDAP_OPT_ERROR_NUMBER, &ldap_errno);
+ ldap_get_option (data->cdata->handle, LDAP_OPT_ERROR_NUMBER, &ldap_errno);
g_set_error (error, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_OTHER_ERROR,
"%s", ldap_err2string(ldap_errno));
- gda_ldap_may_unbind (cdata);
+ gda_ldap_may_unbind (data->cnc);
return NULL;
}
}
}
+GdaLdapEntry *
+gdaprov_ldap_describe_entry (GdaLdapConnection *cnc, const gchar *dn, GError **error)
+{
+ g_return_val_if_fail (GDA_IS_LDAP_CONNECTION (cnc), NULL);
+ g_return_val_if_fail (!dn || (dn && *dn), NULL);
+
+ gda_lockable_lock ((GdaLockable*) cnc); /* CNC LOCK */
+
+ LdapConnectionData *cdata;
+ cdata = (LdapConnectionData*) gda_virtual_connection_internal_get_provider_data
(GDA_VIRTUAL_CONNECTION (cnc));
+ if (!cdata) {
+ gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */
+ return NULL;
+ }
+
+ GdaServerProviderConnectionData *pcdata;
+ pcdata = gda_connection_internal_get_provider_data_error ((GdaConnection*) cnc, NULL);
+
+ GdaWorker *worker;
+ worker = gda_worker_ref (gda_connection_internal_get_worker (pcdata));
+
+ GMainContext *context;
+ context = gda_server_provider_get_real_main_context ((GdaConnection *) cnc);
+
+ WorkerLdapDescrEntryData data;
+ data.cnc = cnc;
+ data.cdata = cdata;
+ data.dn = dn;
+
+ gda_connection_set_status ((GdaConnection*) cnc, GDA_CONNECTION_STATUS_BUSY);
+ gpointer retval;
+ gda_worker_do_job (worker, context, 0, &retval, NULL,
+ (GdaWorkerFunc) worker_gdaprov_ldap_describe_entry, (gpointer) &data, NULL, NULL,
error);
+ if (context)
+ g_main_context_unref (context);
+
+ gda_connection_set_status ((GdaConnection*) cnc, GDA_CONNECTION_STATUS_IDLE);
+ gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */
+
+ gda_worker_unref (worker);
+ return (GdaLdapEntry*) retval;
+}
+
static gint
entry_array_sort_func (gconstpointer a, gconstpointer b)
{
@@ -1337,26 +1465,21 @@ entry_array_sort_func (gconstpointer a, gconstpointer b)
return strcmp (e2->dn, e1->dn);
}
-GdaLdapEntry **
-gdaprov_ldap_get_entry_children (GdaLdapConnection *cnc, const gchar *dn, gchar **attributes,
- GError **error)
-{
+typedef struct {
+ GdaLdapConnection *cnc;
LdapConnectionData *cdata;
- g_return_val_if_fail (GDA_IS_LDAP_CONNECTION (cnc), NULL);
- g_return_val_if_fail (!dn || (dn && *dn), NULL);
-
- cdata = (LdapConnectionData*) gda_virtual_connection_internal_get_provider_data
(GDA_VIRTUAL_CONNECTION (cnc));
- if (!cdata)
- return NULL;
-
- if (! gda_ldap_ensure_bound (cdata, error))
- return NULL;
+ const gchar *dn;
+ gchar **attributes;
+} WorkerEntryChildrenData;
+GdaLdapEntry **
+worker_gdaprov_ldap_get_entry_children (WorkerEntryChildrenData *data, GError **error)
+{
int res;
LDAPMessage *msg = NULL;
retry:
- res = ldap_search_ext_s (cdata->handle, dn ? dn : cdata->base_dn, LDAP_SCOPE_ONELEVEL,
- "(objectClass=*)", attributes, 0,
+ res = ldap_search_ext_s (data->cdata->handle, data->dn ? data->dn : data->cdata->base_dn,
LDAP_SCOPE_ONELEVEL,
+ "(objectClass=*)", data->attributes, 0,
NULL, NULL, NULL, -1,
&msg);
@@ -1367,12 +1490,12 @@ gdaprov_ldap_get_entry_children (GdaLdapConnection *cnc, const gchar *dn, gchar
GArray *children;
children = g_array_new (TRUE, FALSE, sizeof (GdaLdapEntry *));
- for (ldap_row = ldap_first_entry (cdata->handle, msg);
+ for (ldap_row = ldap_first_entry (data->cdata->handle, msg);
ldap_row;
- ldap_row = ldap_next_entry (cdata->handle, ldap_row)) {
+ ldap_row = ldap_next_entry (data->cdata->handle, ldap_row)) {
char *attr;
GdaLdapEntry *lentry = NULL;
- attr = ldap_get_dn (cdata->handle, ldap_row);
+ attr = ldap_get_dn (data->cdata->handle, ldap_row);
if (attr) {
gchar *userdn = NULL;
if (gda_ldap_parse_dn (attr, &userdn)) {
@@ -1397,17 +1520,17 @@ gdaprov_ldap_get_entry_children (GdaLdapConnection *cnc, const gchar *dn, gchar
_("Could not parse distinguished name returned by LDAP server"));
break;
}
- else if (attributes) {
+ else if (data->attributes) {
BerElement* ber;
GArray *array; /* array of GdaLdapAttribute pointers */
lentry->attributes_hash = g_hash_table_new (g_str_hash, g_str_equal);
array = g_array_new (TRUE, FALSE, sizeof (GdaLdapAttribute*));
- for (attr = ldap_first_attribute (cdata->handle, ldap_row, &ber);
+ for (attr = ldap_first_attribute (data->cdata->handle, ldap_row, &ber);
attr;
- attr = ldap_next_attribute (cdata->handle, ldap_row, ber)) {
+ attr = ldap_next_attribute (data->cdata->handle, ldap_row, ber)) {
BerValue **bvals;
GArray *varray = NULL;
- bvals = ldap_get_values_len (cdata->handle, ldap_row, attr);
+ bvals = ldap_get_values_len (data->cdata->handle, ldap_row, attr);
if (bvals) {
gint i;
for (i = 0; bvals [i]; i++) {
@@ -1415,9 +1538,9 @@ gdaprov_ldap_get_entry_children (GdaLdapConnection *cnc, const gchar *dn, gchar
varray = g_array_new (TRUE, FALSE, sizeof
(GValue *));
GValue *value;
GType type;
- type = gda_ldap_get_g_type (cdata, attr, NULL);
+ type = gda_ldap_get_g_type (data->cnc, data->cdata,
attr, NULL);
/*g_print ("%d Type for attr %s is %s\n", i, attr,
gda_g_type_to_string (type));*/
- value = gda_ldap_attr_value_to_g_value (cdata, type,
bvals[i]);
+ value = gda_ldap_attr_value_to_g_value (data->cdata,
type, bvals[i]);
g_array_append_val (varray, value);
}
ldap_value_free_len (bvals);
@@ -1447,7 +1570,7 @@ gdaprov_ldap_get_entry_children (GdaLdapConnection *cnc, const gchar *dn, gchar
g_array_append_val (children, lentry);
}
ldap_msgfree (msg);
- gda_ldap_may_unbind (cdata);
+ gda_ldap_may_unbind (data->cnc);
if (children) {
g_array_sort (children, (GCompareFunc) entry_array_sort_func);
return (GdaLdapEntry**) g_array_free (children, FALSE);
@@ -1458,7 +1581,7 @@ gdaprov_ldap_get_entry_children (GdaLdapConnection *cnc, const gchar *dn, gchar
case LDAP_SERVER_DOWN: {
gint i;
for (i = 0; i < 5; i++) {
- if (gda_ldap_rebind (cdata, NULL))
+ if (gda_ldap_rebind (data->cnc, NULL))
goto retry;
g_usleep (G_USEC_PER_SEC * 2);
}
@@ -1466,15 +1589,63 @@ gdaprov_ldap_get_entry_children (GdaLdapConnection *cnc, const gchar *dn, gchar
default: {
/* error */
int ldap_errno;
- ldap_get_option (cdata->handle, LDAP_OPT_ERROR_NUMBER, &ldap_errno);
+ ldap_get_option (data->cdata->handle, LDAP_OPT_ERROR_NUMBER, &ldap_errno);
g_set_error (error, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_OTHER_ERROR,
"%s", ldap_err2string(ldap_errno));
- gda_ldap_may_unbind (cdata);
+ gda_ldap_may_unbind (data->cnc);
return NULL;
}
}
}
+GdaLdapEntry **
+gdaprov_ldap_get_entry_children (GdaLdapConnection *cnc, const gchar *dn, gchar **attributes, GError **error)
+{
+ g_return_val_if_fail (GDA_IS_LDAP_CONNECTION (cnc), NULL);
+ g_return_val_if_fail (!dn || (dn && *dn), NULL);
+
+ if (! gda_ldap_ensure_bound (cnc, error))
+ return NULL;
+
+ gda_lockable_lock ((GdaLockable*) cnc); /* CNC LOCK */
+
+ LdapConnectionData *cdata;
+ cdata = (LdapConnectionData*) gda_virtual_connection_internal_get_provider_data
(GDA_VIRTUAL_CONNECTION (cnc));
+ if (!cdata) {
+ gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */
+ g_warning ("cdata != NULL failed");
+ return NULL;
+ }
+
+ GdaServerProviderConnectionData *pcdata;
+ pcdata = gda_connection_internal_get_provider_data_error ((GdaConnection*) cnc, NULL);
+
+ GdaWorker *worker;
+ worker = gda_worker_ref (gda_connection_internal_get_worker (pcdata));
+
+ GMainContext *context;
+ context = gda_server_provider_get_real_main_context ((GdaConnection *) cnc);
+
+ WorkerEntryChildrenData data;
+ data.cnc = cnc;
+ data.cdata = cdata;
+ data.dn = dn;
+ data.attributes = attributes;
+
+ gda_connection_set_status ((GdaConnection*) cnc, GDA_CONNECTION_STATUS_BUSY);
+ gpointer retval;
+ gda_worker_do_job (worker, context, 0, &retval, NULL,
+ (GdaWorkerFunc) worker_gdaprov_ldap_get_entry_children, (gpointer) &data, NULL,
NULL, error);
+ if (context)
+ g_main_context_unref (context);
+
+ gda_connection_set_status ((GdaConnection*) cnc, GDA_CONNECTION_STATUS_IDLE);
+ gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */
+
+ gda_worker_unref (worker);
+ return (GdaLdapEntry **) retval;
+}
+
gchar **
gdaprov_ldap_dn_split (const gchar *dn, gboolean all)
{
@@ -1572,7 +1743,7 @@ def_cmp_func (GdaLdapAttributeDefinition *def1, GdaLdapAttributeDefinition *def2
}
static GSList *
-handle_ldap_class (LdapConnectionData *cdata, GdaLdapClass *kl, GSList *retlist, GHashTable *hash)
+handle_ldap_class (GdaLdapConnection *cnc, LdapConnectionData *cdata, GdaLdapClass *kl, GSList *retlist,
GHashTable *hash)
{
guint j;
/*g_print ("Class [%s] (%s)\n", kl->oid, kl->names[0]);*/
@@ -1580,7 +1751,7 @@ handle_ldap_class (LdapConnectionData *cdata, GdaLdapClass *kl, GSList *retlist,
/*g_print (" attr [%s] REQ\n", kl->req_attributes [j]);*/
GdaLdapAttributeDefinition *def;
LdapAttribute *latt;
- latt = gda_ldap_get_attr_info (cdata, kl->req_attributes [j]);
+ latt = gda_ldap_get_attr_info (cnc, cdata, kl->req_attributes [j]);
def = g_hash_table_lookup (hash, kl->req_attributes [j]);
if (def)
def->required = TRUE;
@@ -1597,7 +1768,7 @@ handle_ldap_class (LdapConnectionData *cdata, GdaLdapClass *kl, GSList *retlist,
/*g_print (" attr [%s] OPT\n", kl->opt_attributes [j]);*/
GdaLdapAttributeDefinition *def;
LdapAttribute *latt;
- latt = gda_ldap_get_attr_info (cdata, kl->opt_attributes [j]);
+ latt = gda_ldap_get_attr_info (cnc, cdata, kl->opt_attributes [j]);
def = g_hash_table_lookup (hash, kl->opt_attributes [j]);
if (!def) {
def = g_new0 (GdaLdapAttributeDefinition, 1);
@@ -1612,7 +1783,7 @@ handle_ldap_class (LdapConnectionData *cdata, GdaLdapClass *kl, GSList *retlist,
/* handle parents */
GSList *list;
for (list = kl->parents; list; list = list->next)
- retlist = handle_ldap_class (cdata, (GdaLdapClass*) list->data, retlist, hash);
+ retlist = handle_ldap_class (cnc, cdata, (GdaLdapClass*) list->data, retlist, hash);
return retlist;
}
@@ -1648,7 +1819,7 @@ gdaprov_ldap_get_attributes_list (GdaLdapConnection *cnc, GdaLdapAttribute *obje
/*g_warning (_("Can't get information about '%s' class"), tmp);*/
continue;
}
- retlist = handle_ldap_class (cdata, kl, retlist, hash);
+ retlist = handle_ldap_class (cnc, cdata, kl, retlist, hash);
}
g_hash_table_destroy (hash);
diff --git a/providers/ldap/gda-ldap-util.h b/providers/ldap/gda-ldap-util.h
index 3b76d7f..e3b32d8 100644
--- a/providers/ldap/gda-ldap-util.h
+++ b/providers/ldap/gda-ldap-util.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 - 2012 Vivien Malerba <malerba gnome-db org>
+ * Copyright (C) 2011 - 2014 Vivien Malerba <malerba gnome-db org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -26,6 +26,7 @@
#include <glib.h>
#include "gda-ldap.h"
+#include <virtual/gda-ldap-connection.h>
/*
* Attributes
@@ -43,8 +44,8 @@ typedef struct {
} LdapAttribute;
LdapAttrType *gda_ldap_get_type_info (const gchar *oid);
-LdapAttribute *gda_ldap_get_attr_info (LdapConnectionData *cdata, const gchar *attribute);
-GType gda_ldap_get_g_type (LdapConnectionData *cdata, const gchar *attribute, const gchar
*specified_gtype);
+LdapAttribute *gda_ldap_get_attr_info (GdaLdapConnection *cnc, LdapConnectionData *cdata, const gchar
*attribute);
+GType gda_ldap_get_g_type (GdaLdapConnection *cnc, LdapConnectionData *cdata, const gchar
*attribute, const gchar *specified_gtype);
/*
* Misc.
diff --git a/providers/ldap/gda-ldap.h b/providers/ldap/gda-ldap.h
index e815082..77a81a5 100644
--- a/providers/ldap/gda-ldap.h
+++ b/providers/ldap/gda-ldap.h
@@ -2,7 +2,7 @@
* Copyright (C) 2001 - 2002 Gonzalo Paniagua Javier <gonzalo gnome-db org>
* Copyright (C) 2001 - 2002 Rodrigo Moya <rodrigo gnome-db org>
* Copyright (C) 2003 Danilo Schoeneberg <dj starfire-programming net>
- * Copyright (C) 2005 - 2012 Vivien Malerba <malerba gnome-db org>
+ * Copyright (C) 2005 - 2014 Vivien Malerba <malerba gnome-db org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -33,6 +33,18 @@
#include <glib.h>
#include <libgda/libgda.h>
#include <libgda/gda-connection-private.h>
+#include <virtual/gda-ldap-connection.h>
+
+/*
+ * Note about thread safety:
+ * the doc says: "libldap is thread safe in the sense that multiple
+ * threads can use separate LDAP* handles without running into concurrency
+ * issues; except for library initialization, all accesses to common data
+ * (i.e. global variables) is read-only."
+ *
+ * Here each LDAP handle is treated in its own thread, and function like ldap_str2dn(), ldap_dnfree(),
+ * are considered thread safe.
+ */
/*
* Provider's specific connection data
@@ -57,8 +69,8 @@ typedef struct {
GHashTable *classes_hash; /* key = class name, value = a #LdapClass */
} LdapConnectionData;
-void gda_ldap_may_unbind (LdapConnectionData *cdata);
-gboolean gda_ldap_ensure_bound (LdapConnectionData *cdata, GError **error);
-gboolean gda_ldap_rebind (LdapConnectionData *cdata, GError **error);
+void gda_ldap_may_unbind (GdaLdapConnection *cnc);
+gboolean gda_ldap_ensure_bound (GdaLdapConnection *cnc, GError **error);
+gboolean gda_ldap_rebind (GdaLdapConnection *cnc, GError **error);
#endif
diff --git a/providers/ldap/gdaprov-data-model-ldap.c b/providers/ldap/gdaprov-data-model-ldap.c
index 6a7143f..591dcac 100644
--- a/providers/ldap/gdaprov-data-model-ldap.c
+++ b/providers/ldap/gdaprov-data-model-ldap.c
@@ -30,6 +30,8 @@
#include "gda-ldap-util.h"
#include "gdaprov-data-model-ldap.h"
#include <libgda/gda-debug-macros.h>
+#include <libgda/gda-server-provider-private.h> /* for gda_server_provider_get_real_main_context () */
+#include <libgda/gda-connection-internal.h> /* for gda_connection_set_status() */
#define GDA_DEBUG_SUBSEARCHES
#undef GDA_DEBUG_SUBSEARCHES
@@ -65,7 +67,7 @@ struct _LdapPart {
#define LDAP_PART(x) ((LdapPart*)(x))
static LdapPart *ldap_part_new (LdapPart *parent, const gchar *base_dn, GdaLdapSearchScope scope);
-static void ldap_part_free (LdapPart *part, LdapConnectionData *cdata);
+static void ldap_part_free (LdapPart *part, GdaLdapConnection *cdata);
static gboolean ldap_part_split (LdapPart *part, GdaDataModelLdap *model, gboolean *out_error);
static LdapPart *ldap_part_next (LdapPart *part, gboolean executed);
#ifdef GDA_DEBUG_SUBSEARCHES
@@ -295,11 +297,10 @@ gda_data_model_ldap_dispose (GObject *object)
g_array_free (model->priv->column_mv_actions, TRUE);
if (model->priv->top_exec) {
- LdapConnectionData *cdata;
if (!model->priv->cnc)
g_warning ("LDAP connection's cnc private attribute should not be NULL,
please report this bug to http://bugzilla.gnome.org/ for the \"libgda\" product.");
- cdata = (LdapConnectionData*) gda_virtual_connection_internal_get_provider_data
(GDA_VIRTUAL_CONNECTION (model->priv->cnc));
- ldap_part_free (model->priv->top_exec, cdata);
+ else
+ ldap_part_free (model->priv->top_exec, GDA_LDAP_CONNECTION
(model->priv->cnc));
}
if (model->priv->cnc) {
@@ -556,7 +557,7 @@ _ldap_compute_columns (GdaConnection *cnc, const gchar *attributes,
}
}
- coltype = gda_ldap_get_g_type (cdata, sub [0], sub [1]);
+ coltype = gda_ldap_get_g_type ((GdaLdapConnection*) cnc, cdata, sub [0], sub [1]);
tmp = g_strdup (sub [0]);
if (attrs)
g_array_append_val (attrs, tmp);
@@ -701,38 +702,37 @@ csv_quote (const gchar *string)
return retval;
}
+typedef struct {
+ GdaLdapConnection *cnc;
+ LdapConnectionData *cdata;
+ GdaDataModelLdap *imodel;
+ GdaDataModelIter *iter;
+} WorkerIterData;
+
static void
-update_iter_from_ldap_row (GdaDataModelLdap *imodel, GdaDataModelIter *iter)
+worker_update_iter_from_ldap_row (WorkerIterData *data, GError **error)
{
gboolean update_model;
BerElement* ber;
char *attr;
GdaHolder *holder;
gint j, nb;
- LdapConnectionData *cdata;
GSList *holders_set = NULL;
- g_return_if_fail (imodel->priv->cnc);
- cdata = (LdapConnectionData*) gda_virtual_connection_internal_get_provider_data
(GDA_VIRTUAL_CONNECTION (imodel->priv->cnc));
- g_return_if_fail (cdata);
-
- /* LDAP connection must have been kept opened */
- g_assert (cdata->handle);
-
- g_object_get (G_OBJECT (iter), "update-model", &update_model, NULL);
- g_object_set (G_OBJECT (iter), "update-model", FALSE, NULL);
+ g_object_get (G_OBJECT (data->iter), "update-model", &update_model, NULL);
+ g_object_set (G_OBJECT (data->iter), "update-model", FALSE, NULL);
/* column 0 is the DN */
- holder = GDA_HOLDER (GDA_SET (iter)->holders->data);
- attr = ldap_get_dn (cdata->handle, imodel->priv->current_exec->ldap_row);
+ holder = GDA_HOLDER (GDA_SET (data->iter)->holders->data);
+ attr = ldap_get_dn (data->cdata->handle, data->imodel->priv->current_exec->ldap_row);
if (attr) {
gchar *userdn;
if (gda_ldap_parse_dn (attr, &userdn)) {
- if (imodel->priv->base_dn && *imodel->priv->base_dn &&
- imodel->priv->use_rdn &&
- g_str_has_suffix (userdn, imodel->priv->base_dn)) {
+ if (data->imodel->priv->base_dn && *data->imodel->priv->base_dn &&
+ data->imodel->priv->use_rdn &&
+ g_str_has_suffix (userdn, data->imodel->priv->base_dn)) {
gint i;
- i = strlen (userdn) - strlen (imodel->priv->base_dn);
+ i = strlen (userdn) - strlen (data->imodel->priv->base_dn);
if (i > 0) {
userdn [i] = 0;
for (i--; (i >= 0) && (userdn [i] != ','); i--);
@@ -750,34 +750,34 @@ update_iter_from_ldap_row (GdaDataModelLdap *imodel, GdaDataModelIter *iter)
else
gda_holder_force_invalid (holder);
- nb = g_slist_length (((GdaSet*) iter)->holders);
+ nb = g_slist_length (((GdaSet*) data->iter)->holders);
for (j = 1; j < nb; j++) {
- holder = (GdaHolder*) (g_slist_nth_data (((GdaSet*) iter)->holders, j));
+ holder = (GdaHolder*) (g_slist_nth_data (((GdaSet*) data->iter)->holders, j));
gda_holder_set_value (holder, NULL, NULL);
}
- if (imodel->priv->row_mult)
+ if (data->imodel->priv->row_mult)
goto out;
- for (attr = ldap_first_attribute (cdata->handle, imodel->priv->current_exec->ldap_row, &ber);
+ for (attr = ldap_first_attribute (data->cdata->handle, data->imodel->priv->current_exec->ldap_row,
&ber);
attr;
- attr = ldap_next_attribute (cdata->handle, imodel->priv->current_exec->ldap_row, ber)) {
+ attr = ldap_next_attribute (data->cdata->handle, data->imodel->priv->current_exec->ldap_row,
ber)) {
BerValue **bvals;
gboolean holder_added_to_cm = FALSE;
- holder = gda_set_get_holder ((GdaSet*) iter, attr);
+ holder = gda_set_get_holder ((GdaSet*) data->iter, attr);
if (!holder)
continue;
- j = g_slist_index (((GdaSet*) iter)->holders, holder);
+ j = g_slist_index (((GdaSet*) data->iter)->holders, holder);
- bvals = ldap_get_values_len (cdata->handle,
- imodel->priv->current_exec->ldap_row, attr);
+ bvals = ldap_get_values_len (data->cdata->handle,
+ data->imodel->priv->current_exec->ldap_row, attr);
if (bvals) {
if (bvals[0] && bvals[1]) {
/* multiple values */
MultipleValueAction act;
- act = g_array_index (imodel->priv->column_mv_actions,
+ act = g_array_index (data->imodel->priv->column_mv_actions,
MultipleValueAction, j-1);
switch (act) {
case MULTIPLE_VALUE_ACTION_SET_NULL:
@@ -808,8 +808,8 @@ update_iter_from_ldap_row (GdaDataModelLdap *imodel, GdaDataModelIter *iter)
break;
case MULTIPLE_VALUE_ACTION_MULTIPLY: {
ColumnMultiplier *cm;
- if (! imodel->priv->row_mult) {
- imodel->priv->row_mult = row_multiplier_new ();
+ if (! data->imodel->priv->row_mult) {
+ data->imodel->priv->row_mult = row_multiplier_new ();
/* create @cm for the previous columns */
GSList *list;
for (list = holders_set; list; list = list->next) {
@@ -817,7 +817,7 @@ update_iter_from_ldap_row (GdaDataModelLdap *imodel, GdaDataModelIter *iter)
ch = (GdaHolder*) list->data;
cm = column_multiplier_new (ch,
gda_holder_get_value (ch));
- g_array_append_val (imodel->priv->row_mult->cms, cm);
+ g_array_append_val
(data->imodel->priv->row_mult->cms, cm);
}
}
/* add new @cm */
@@ -825,12 +825,12 @@ update_iter_from_ldap_row (GdaDataModelLdap *imodel, GdaDataModelIter *iter)
gint i;
for (i = 0; bvals[i]; i++) {
GValue *value;
- value = gda_ldap_attr_value_to_g_value (cdata,
+ value = gda_ldap_attr_value_to_g_value (data->cdata,
gda_holder_get_g_type
(holder),
bvals[i]);
g_array_append_val (cm->values, value); /* value can be %NULL
*/
}
- g_array_append_val (imodel->priv->row_mult->cms, cm);
+ g_array_append_val (data->imodel->priv->row_mult->cms, cm);
holder_added_to_cm = TRUE;
break;
}
@@ -873,7 +873,7 @@ update_iter_from_ldap_row (GdaDataModelLdap *imodel, GdaDataModelIter *iter)
else if (bvals[0]) {
/* convert string to the correct type */
GValue *value;
- value = gda_ldap_attr_value_to_g_value (cdata, gda_holder_get_g_type (holder),
+ value = gda_ldap_attr_value_to_g_value (data->cdata, gda_holder_get_g_type
(holder),
bvals[0]);
if (value)
gda_holder_take_value (holder, value, NULL);
@@ -888,10 +888,10 @@ update_iter_from_ldap_row (GdaDataModelLdap *imodel, GdaDataModelIter *iter)
gda_holder_set_value (holder, NULL, NULL);
ldap_memfree (attr);
holders_set = g_slist_prepend (holders_set, holder);
- if (imodel->priv->row_mult && !holder_added_to_cm) {
+ if (data->imodel->priv->row_mult && !holder_added_to_cm) {
ColumnMultiplier *cm;
cm = column_multiplier_new (holder, gda_holder_get_value (holder));
- g_array_append_val (imodel->priv->row_mult->cms, cm);
+ g_array_append_val (data->imodel->priv->row_mult->cms, cm);
}
}
if (holders_set)
@@ -901,26 +901,76 @@ update_iter_from_ldap_row (GdaDataModelLdap *imodel, GdaDataModelIter *iter)
ber_free (ber, 0);
out:
- if (imodel->priv->row_mult)
- row_multiplier_set_holders (imodel->priv->row_mult);
+ if (data->imodel->priv->row_mult)
+ row_multiplier_set_holders (data->imodel->priv->row_mult);
- if (gda_data_model_iter_is_valid (iter)) {
- imodel->priv->iter_row ++;
- if ((imodel->priv->iter_row == imodel->priv->n_rows - 1) && imodel->priv->truncated) {
+ if (gda_data_model_iter_is_valid (data->iter)) {
+ data->imodel->priv->iter_row ++;
+ if ((data->imodel->priv->iter_row == data->imodel->priv->n_rows - 1) &&
data->imodel->priv->truncated) {
GError *e = NULL;
g_set_error (&e, GDA_DATA_MODEL_ERROR,
GDA_DATA_MODEL_TRUNCATED_ERROR,
"%s", _("Truncated result because LDAP server limit encountered"));
- add_exception (imodel, e);
+ add_exception (data->imodel, e);
}
}
else
- imodel->priv->iter_row = 0;
+ data->imodel->priv->iter_row = 0;
- g_object_set (G_OBJECT (iter), "current-row", imodel->priv->iter_row,
+ g_object_set (G_OBJECT (data->iter), "current-row", data->imodel->priv->iter_row,
"update-model", update_model, NULL);
}
+static void
+update_iter_from_ldap_row (GdaDataModelLdap *imodel, GdaDataModelIter *iter)
+{
+ g_return_if_fail (imodel);
+ g_return_if_fail (iter);
+ g_return_if_fail (imodel->priv->cnc);
+
+ GdaConnection *cnc;
+ cnc = imodel->priv->cnc;
+ gda_lockable_lock ((GdaLockable*) cnc); /* CNC LOCK */
+
+ LdapConnectionData *cdata;
+ cdata = (LdapConnectionData*) gda_virtual_connection_internal_get_provider_data
(GDA_VIRTUAL_CONNECTION (cnc));
+ if (!cdata) {
+ gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */
+ g_warning ("cdata != NULL failed");
+ return;
+ }
+
+ /* LDAP connection must have been kept opened */
+ g_assert (cdata->handle);
+
+ GdaServerProviderConnectionData *pcdata;
+ pcdata = gda_connection_internal_get_provider_data_error ((GdaConnection*) cnc, NULL);
+
+ GdaWorker *worker;
+ worker = gda_worker_ref (gda_connection_internal_get_worker (pcdata));
+
+ GMainContext *context;
+ context = gda_server_provider_get_real_main_context ((GdaConnection *) cnc);
+
+ WorkerIterData data;
+ data.cnc = (GdaLdapConnection*) cnc;
+ data.cdata = cdata;
+ data.imodel = imodel;
+ data.iter = iter;
+
+ gda_connection_set_status ((GdaConnection*) cnc, GDA_CONNECTION_STATUS_BUSY);
+ gpointer retval;
+ gda_worker_do_job (worker, context, 0, &retval, NULL,
+ (GdaWorkerFunc) worker_update_iter_from_ldap_row, (gpointer) &data, NULL, NULL,
NULL);
+ if (context)
+ g_main_context_unref (context);
+
+ gda_connection_set_status ((GdaConnection*) cnc, GDA_CONNECTION_STATUS_IDLE);
+ gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */
+
+ gda_worker_unref (worker);
+}
+
/*
* Add an exception to @model
* WARNING: steals @e
@@ -933,36 +983,28 @@ add_exception (GdaDataModelLdap *model, GError *e)
g_array_append_val (model->priv->exceptions, e);
}
-/*
- * Execute model->priv->current_exec and either:
- * - sets model->priv->current_exec->ldap_msg, or
- * - create some children and execute one, or
- * - sets model->priv->current_exec->ldap_msg to %NULL if an error occurred
- *
- * In any case model->priv->current_exec->executed is set to %TRUE and should be %FALSE when entering
- * the function (ie. for any LdapConnectionData this function has to be called at most once)
- */
-static void
-execute_ldap_search (GdaDataModelLdap *model)
+typedef struct {
+ GdaLdapConnection *cnc;
+ LdapConnectionData *cdata;
+ GdaDataModelLdap *model;
+} WorkerSearchData;
+
+static gpointer
+worker_execute_ldap_search (WorkerSearchData *data, GError **error)
{
LDAPMessage *msg = NULL;
int lscope, res = 0;
- LdapConnectionData *cdata;
-
- g_return_if_fail (model->priv->cnc);
- cdata = (LdapConnectionData*) gda_virtual_connection_internal_get_provider_data
(GDA_VIRTUAL_CONNECTION (model->priv->cnc));
- g_return_if_fail (cdata);
GError *e = NULL;
- if (! gda_ldap_ensure_bound (cdata, &e)) {
- add_exception (model, e);
- return;
+ if (! gda_ldap_ensure_bound (data->cnc, &e)) {
+ add_exception (data->model, e);
+ return NULL;
}
- g_assert (model->priv->current_exec);
- g_assert (! model->priv->current_exec->executed);
+ g_assert (data->model->priv->current_exec);
+ g_assert (! data->model->priv->current_exec->executed);
- switch (model->priv->current_exec->scope) {
+ switch (data->model->priv->current_exec->scope) {
default:
case GDA_LDAP_SEARCH_BASE:
lscope = LDAP_SCOPE_BASE;
@@ -976,9 +1018,9 @@ execute_ldap_search (GdaDataModelLdap *model)
}
#ifdef GDA_DEBUG_SUBSEARCHES
- if (model->priv->scope == GDA_LDAP_SEARCH_SUBTREE) {
- g_print ("Model %p model->priv->top_exec:\n", model);
- ldap_part_dump (model->priv->top_exec);
+ if (data->model->priv->scope == GDA_LDAP_SEARCH_SUBTREE) {
+ g_print ("Model %p model->priv->top_exec:\n", data->model);
+ ldap_part_dump (data->model->priv->top_exec);
}
#endif
@@ -987,8 +1029,8 @@ execute_ldap_search (GdaDataModelLdap *model)
static gint sims = 10;
retry:
if ((sims > 0) &&
- (model->priv->scope == GDA_LDAP_SEARCH_SUBTREE) &&
- (! model->priv->current_exec->parent || ! model->priv->current_exec->parent->parent)) {
+ (data->model->priv->scope == GDA_LDAP_SEARCH_SUBTREE) &&
+ (! data->model->priv->current_exec->parent || ! data->model->priv->current_exec->parent->parent))
{
g_print ("Simulating LDAP_ADMINLIMIT_EXCEEDED\n");
res = LDAP_ADMINLIMIT_EXCEEDED;
sims --;
@@ -997,12 +1039,12 @@ execute_ldap_search (GdaDataModelLdap *model)
#else
retry:
#endif
- res = ldap_search_ext_s (cdata->handle, model->priv->current_exec->base_dn, lscope,
- model->priv->filter,
- (char**) model->priv->attributes->data, 0,
+ res = ldap_search_ext_s (data->cdata->handle, data->model->priv->current_exec->base_dn, lscope,
+ data->model->priv->filter,
+ (char**) data->model->priv->attributes->data, 0,
NULL, NULL, NULL, -1,
&msg);
- model->priv->current_exec->executed = TRUE;
+ data->model->priv->current_exec->executed = TRUE;
#define GDA_DEBUG_FORCE_ERROR
#undef GDA_DEBUG_FORCE_ERROR
@@ -1011,25 +1053,25 @@ execute_ldap_search (GdaDataModelLdap *model)
GError *e = NULL;
int ldap_errno;
g_print ("SIMULATING error\n");
- ldap_get_option (cdata->handle, LDAP_OPT_ERROR_NUMBER, &ldap_errno);
+ ldap_get_option (data->cdata->handle, LDAP_OPT_ERROR_NUMBER, &ldap_errno);
g_set_error (&e, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_OTHER_ERROR,
"%s", "Simulated error");
- add_exception (model, e);
- return;
+ add_exception (data->model, e);
+ return NULL;
#else
switch (res) {
case LDAP_SUCCESS:
case LDAP_NO_SUCH_OBJECT:
/* all Ok */
- model->priv->current_exec->ldap_msg = msg;
- model->priv->current_exec->nb_entries = ldap_count_entries (cdata->handle, msg);
+ data->model->priv->current_exec->ldap_msg = msg;
+ data->model->priv->current_exec->nb_entries = ldap_count_entries (data->cdata->handle, msg);
/* keep the connection opened for this LdapPart */
- cdata->keep_bound_count ++;
+ data->cdata->keep_bound_count ++;
#ifdef GDA_DEBUG_SUBSEARCHES
g_print ("model->priv->current_exec->nb_entries = %d\n",
- model->priv->current_exec->nb_entries);
+ data->model->priv->current_exec->nb_entries);
#endif
break;
case LDAP_ADMINLIMIT_EXCEEDED:
@@ -1039,23 +1081,23 @@ execute_ldap_search (GdaDataModelLdap *model)
g_print ("LIMIT_EXCEEDED!\n");
#endif
gboolean handled = FALSE;
- if ((cdata->time_limit == 0) && (cdata->size_limit == 0) &&
- (model->priv->scope == GDA_LDAP_SEARCH_SUBTREE)) {
+ if ((data->cdata->time_limit == 0) && (data->cdata->size_limit == 0) &&
+ (data->model->priv->scope == GDA_LDAP_SEARCH_SUBTREE)) {
gboolean split_error;
- if (ldap_part_split (model->priv->current_exec, model, &split_error)) {
+ if (ldap_part_split (data->model->priv->current_exec, data->model, &split_error)) {
/* create some children to re-run the search */
if (msg)
ldap_msgfree (msg);
- model->priv->current_exec = LDAP_PART
(model->priv->current_exec->children->data);
- execute_ldap_search (model);
+ data->model->priv->current_exec = LDAP_PART
(data->model->priv->current_exec->children->data);
+ worker_execute_ldap_search (data, NULL);
handled = TRUE;
}
else if (!split_error) {
LdapPart *next;
- next = ldap_part_next (model->priv->current_exec, FALSE);
+ next = ldap_part_next (data->model->priv->current_exec, FALSE);
if (next) {
- model->priv->current_exec = next;
- execute_ldap_search (model);
+ data->model->priv->current_exec = next;
+ worker_execute_ldap_search (data, NULL);
handled = TRUE;
}
}
@@ -1065,19 +1107,19 @@ execute_ldap_search (GdaDataModelLdap *model)
#ifdef GDA_DEBUG_SUBSEARCHES
g_print ("Output truncated!\n");
#endif
- model->priv->truncated = TRUE;
- model->priv->current_exec->ldap_msg = msg;
- model->priv->current_exec->nb_entries = ldap_count_entries (cdata->handle, msg);
+ data->model->priv->truncated = TRUE;
+ data->model->priv->current_exec->ldap_msg = msg;
+ data->model->priv->current_exec->nb_entries = ldap_count_entries
(data->cdata->handle, msg);
/* keep the connection opened for this LdapPart */
- cdata->keep_bound_count ++;
+ data->cdata->keep_bound_count ++;
}
break;
}
case LDAP_SERVER_DOWN: {
gint i;
for (i = 0; i < 5; i++) {
- if (gda_ldap_rebind (cdata, NULL))
+ if (gda_ldap_rebind (data->cnc, NULL))
goto retry;
g_usleep (G_USEC_PER_SEC * 2);
}
@@ -1086,139 +1128,237 @@ execute_ldap_search (GdaDataModelLdap *model)
/* error */
GError *e = NULL;
int ldap_errno;
- ldap_get_option (cdata->handle, LDAP_OPT_ERROR_NUMBER, &ldap_errno);
+ ldap_get_option (data->cdata->handle, LDAP_OPT_ERROR_NUMBER, &ldap_errno);
g_set_error (&e, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_OTHER_ERROR,
"%s", ldap_err2string (ldap_errno));
- add_exception (model, e);
- gda_ldap_may_unbind (cdata);
- return;
+ add_exception (data->model, e);
+ gda_ldap_may_unbind (data->cnc);
+ return NULL;
}
}
#endif /*GDA_DEBUG_FORCE_ERROR*/
- if (model->priv->truncated) {
+ if (data->model->priv->truncated) {
/* compute totel number of rows now that we know it */
- if (model->priv->top_exec->ldap_msg)
- model->priv->n_rows = model->priv->current_exec->nb_entries;
+ if (data->model->priv->top_exec->ldap_msg)
+ data->model->priv->n_rows = data->model->priv->current_exec->nb_entries;
else {
LdapPart *iter;
- model->priv->n_rows = 0;
- for (iter = model->priv->top_exec; iter; iter = ldap_part_next (iter, TRUE))
- model->priv->n_rows += iter->nb_entries;
+ data->model->priv->n_rows = 0;
+ for (iter = data->model->priv->top_exec; iter; iter = ldap_part_next (iter, TRUE))
+ data->model->priv->n_rows += iter->nb_entries;
}
}
#ifdef GDA_DEBUG_NO
gint tmpnb = 0;
- if (model->priv->top_exec->ldap_msg)
- tmpnb = model->priv->current_exec->nb_entries;
+ if (data->model->priv->top_exec->ldap_msg)
+ tmpnb = data->model->priv->current_exec->nb_entries;
else {
LdapPart *iter;
- for (iter = model->priv->top_exec; iter; iter = ldap_part_next (iter, TRUE))
+ for (iter = data->model->priv->top_exec; iter; iter = ldap_part_next (iter, TRUE))
tmpnb += iter->nb_entries;
}
g_print ("So far found %d\n", tmpnb);
#endif
+
+ return NULL;
}
-static gboolean
-gda_data_model_ldap_iter_next (GdaDataModel *model, GdaDataModelIter *iter)
+/*
+ * Execute model->priv->current_exec and either:
+ * - sets model->priv->current_exec->ldap_msg, or
+ * - create some children and execute one, or
+ * - sets model->priv->current_exec->ldap_msg to %NULL if an error occurred
+ *
+ * In any case model->priv->current_exec->executed is set to %TRUE and should be %FALSE when entering
+ * the function (ie. for any LdapConnectionData this function has to be called at most once)
+ */
+static void
+execute_ldap_search (GdaDataModelLdap *model)
{
- GdaDataModelLdap *imodel;
- LdapConnectionData *cdata;
- LdapPart *cpart;
+ g_return_if_fail (model);
+ g_return_if_fail (model->priv->cnc);
- g_return_val_if_fail (GDA_IS_DATA_MODEL_LDAP (model), FALSE);
- g_return_val_if_fail (GDA_IS_DATA_MODEL_ITER (iter), FALSE);
- imodel = GDA_DATA_MODEL_LDAP (model);
- g_return_val_if_fail (imodel->priv, FALSE);
+ GdaConnection *cnc;
+ cnc = model->priv->cnc;
+ gda_lockable_lock ((GdaLockable*) cnc); /* CNC LOCK */
- if (! imodel->priv->cnc) {
- /* error */
- gda_data_model_iter_invalidate_contents (iter);
- return FALSE;
+ LdapConnectionData *cdata;
+ cdata = (LdapConnectionData*) gda_virtual_connection_internal_get_provider_data
(GDA_VIRTUAL_CONNECTION (cnc));
+ if (!cdata) {
+ gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */
+ g_warning ("cdata != NULL failed");
+ return;
}
- cdata = (LdapConnectionData*) gda_virtual_connection_internal_get_provider_data
(GDA_VIRTUAL_CONNECTION (imodel->priv->cnc));
- if (!cdata || ! gda_ldap_ensure_bound (cdata, NULL)) {
- /* error */
- gda_data_model_iter_invalidate_contents (iter);
- return FALSE;
- }
+ GdaServerProviderConnectionData *pcdata;
+ pcdata = gda_connection_internal_get_provider_data_error ((GdaConnection*) cnc, NULL);
+
+ GdaWorker *worker;
+ worker = gda_worker_ref (gda_connection_internal_get_worker (pcdata));
+
+ GMainContext *context;
+ context = gda_server_provider_get_real_main_context ((GdaConnection *) cnc);
+
+ WorkerSearchData data;
+ data.cnc = GDA_LDAP_CONNECTION (cnc);
+ data.cdata = cdata;
+ data.model = model;
+
+ gda_connection_set_status ((GdaConnection*) cnc, GDA_CONNECTION_STATUS_BUSY);
+ gpointer retval;
+ gda_worker_do_job (worker, context, 0, &retval, NULL,
+ (GdaWorkerFunc) worker_execute_ldap_search, (gpointer) &data, NULL, NULL, NULL);
+ if (context)
+ g_main_context_unref (context);
+
+ gda_connection_set_status ((GdaConnection*) cnc, GDA_CONNECTION_STATUS_IDLE);
+ gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */
+
+ gda_worker_unref (worker);
+}
+
+
+static gpointer
+worker_gda_data_model_ldap_iter_next (WorkerIterData *data, GError **error)
+{
+ LdapPart *cpart;
/* initialize LDAP search if necessary */
- if (! imodel->priv->base_dn)
- imodel->priv->base_dn = g_strdup (cdata->base_dn);
- if (! imodel->priv->attributes)
- imodel->priv->attributes = g_array_new (TRUE, FALSE, sizeof (gchar*));
- if (! imodel->priv->top_exec) {
- imodel->priv->top_exec = ldap_part_new (NULL, imodel->priv->base_dn, imodel->priv->scope);
- imodel->priv->current_exec = imodel->priv->top_exec;
+ if (! data->imodel->priv->base_dn)
+ data->imodel->priv->base_dn = g_strdup (data->cdata->base_dn);
+ if (! data->imodel->priv->attributes)
+ data->imodel->priv->attributes = g_array_new (TRUE, FALSE, sizeof (gchar*));
+ if (! data->imodel->priv->top_exec) {
+ data->imodel->priv->top_exec = ldap_part_new (NULL, data->imodel->priv->base_dn,
data->imodel->priv->scope);
+ data->imodel->priv->current_exec = data->imodel->priv->top_exec;
}
- while (imodel->priv->current_exec) {
- cpart = imodel->priv->current_exec;
+ while (data->imodel->priv->current_exec) {
+ cpart = data->imodel->priv->current_exec;
if (! cpart->executed)
- execute_ldap_search (imodel);
- cpart = imodel->priv->current_exec;
+ execute_ldap_search (data->imodel);
+ cpart = data->imodel->priv->current_exec;
if (! cpart->ldap_msg) {
/* error somewhere */
- gda_data_model_iter_invalidate_contents (iter);
- gda_ldap_may_unbind (cdata);
- return FALSE;
+ gda_data_model_iter_invalidate_contents (data->iter);
+ gda_ldap_may_unbind (data->cnc);
+
+ return NULL;
}
if (! cpart->ldap_row)
/* not yet on 1st row */
- cpart->ldap_row = ldap_first_entry (cdata->handle, cpart->ldap_msg);
+ cpart->ldap_row = ldap_first_entry (data->cdata->handle, cpart->ldap_msg);
else {
- if (imodel->priv->row_mult) {
- if (! row_multiplier_index_next (imodel->priv->row_mult)) {
- row_multiplier_free (imodel->priv->row_mult);
- imodel->priv->row_mult = NULL;
+ if (data->imodel->priv->row_mult) {
+ if (! row_multiplier_index_next (data->imodel->priv->row_mult)) {
+ row_multiplier_free (data->imodel->priv->row_mult);
+ data->imodel->priv->row_mult = NULL;
}
}
- if (! imodel->priv->row_mult) {
+ if (! data->imodel->priv->row_mult) {
/* move to the next row */
- cpart->ldap_row = ldap_next_entry (cdata->handle, cpart->ldap_row);
+ cpart->ldap_row = ldap_next_entry (data->cdata->handle, cpart->ldap_row);
}
}
if (cpart->ldap_row) {
- update_iter_from_ldap_row (imodel, iter);
+ update_iter_from_ldap_row (data->imodel, data->iter);
break;
}
else {
/* nothing more for this part, switch to the next one */
- ldap_msgfree (imodel->priv->current_exec->ldap_msg);
- imodel->priv->current_exec->ldap_msg = NULL;
+ ldap_msgfree (data->imodel->priv->current_exec->ldap_msg);
+ data->imodel->priv->current_exec->ldap_msg = NULL;
- g_assert (cdata->keep_bound_count > 0);
- cdata->keep_bound_count --;
- gda_ldap_may_unbind (cdata);
+ g_assert (data->cdata->keep_bound_count > 0);
+ data->cdata->keep_bound_count --;
+ gda_ldap_may_unbind (data->cnc);
- imodel->priv->current_exec = ldap_part_next (cpart, FALSE);
+ data->imodel->priv->current_exec = ldap_part_next (cpart, FALSE);
}
}
- if (!imodel->priv->current_exec) {
+ if (!data->imodel->priv->current_exec) {
/* execution is over */
- gda_data_model_iter_invalidate_contents (iter);
- g_object_set (G_OBJECT (iter), "current-row", -1, NULL);
- if (imodel->priv->truncated) {
+ gda_data_model_iter_invalidate_contents (data->iter);
+ g_object_set (G_OBJECT (data->iter), "current-row", -1, NULL);
+ if (data->imodel->priv->truncated) {
GError *e = NULL;
g_set_error (&e, GDA_DATA_MODEL_ERROR,
GDA_DATA_MODEL_TRUNCATED_ERROR,
"%s", _("Truncated result because LDAP server limit encountered"));
- add_exception (imodel, e);
+ add_exception (data->imodel, e);
}
- g_signal_emit_by_name (iter, "end-of-data");
- gda_ldap_may_unbind (cdata);
- return FALSE;
+ g_signal_emit_by_name (data->iter, "end-of-data");
+ gda_ldap_may_unbind (data->cnc);
+
+ return NULL;
+ }
+
+ gda_ldap_may_unbind (data->cnc);
+ return (gpointer) 0x01;
+}
+
+static gboolean
+gda_data_model_ldap_iter_next (GdaDataModel *model, GdaDataModelIter *iter)
+{
+ g_return_val_if_fail (GDA_IS_DATA_MODEL_LDAP (model), FALSE);
+ g_return_val_if_fail (GDA_IS_DATA_MODEL_ITER (iter), FALSE);
+ GdaDataModelLdap *imodel = (GdaDataModelLdap*) model;
+ g_return_val_if_fail (imodel->priv, FALSE);
+
+ if (! imodel->priv->cnc) {
+ /* error */
+ gda_data_model_iter_invalidate_contents (iter);
+ return FALSE;
+ }
+
+ GdaConnection *cnc;
+ cnc = imodel->priv->cnc;
+ gda_lockable_lock ((GdaLockable*) cnc); /* CNC LOCK */
+
+ LdapConnectionData *cdata;
+ cdata = (LdapConnectionData*) gda_virtual_connection_internal_get_provider_data
(GDA_VIRTUAL_CONNECTION (cnc));
+ if (!cdata || ! gda_ldap_ensure_bound ((GdaLdapConnection*) cnc, NULL)) {
+ /* error */
+ if (!cdata)
+ g_warning ("cdata != NULL failed");
+ gda_data_model_iter_invalidate_contents (iter);
+ gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */
+ return FALSE;
}
- gda_ldap_may_unbind (cdata);
- return TRUE;
+ GdaServerProviderConnectionData *pcdata;
+ pcdata = gda_connection_internal_get_provider_data_error ((GdaConnection*) cnc, NULL);
+
+ GdaWorker *worker;
+ worker = gda_worker_ref (gda_connection_internal_get_worker (pcdata));
+
+ GMainContext *context;
+ context = gda_server_provider_get_real_main_context ((GdaConnection *) cnc);
+
+ WorkerIterData data;
+ data.cnc = (GdaLdapConnection*) cnc;
+ data.cdata = cdata;
+ data.imodel = imodel;
+ data.iter = iter;
+
+ gda_connection_set_status ((GdaConnection*) cnc, GDA_CONNECTION_STATUS_BUSY);
+ gpointer retval;
+ gda_worker_do_job (worker, context, 0, &retval, NULL,
+ (GdaWorkerFunc) worker_gda_data_model_ldap_iter_next, (gpointer) &data, NULL,
NULL, NULL);
+ if (context)
+ g_main_context_unref (context);
+
+ gda_connection_set_status ((GdaConnection*) cnc, GDA_CONNECTION_STATUS_IDLE);
+ gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */
+
+ gda_worker_unref (worker);
+
+ return retval ? TRUE : FALSE;
}
static GdaValueAttribute
@@ -1280,25 +1420,74 @@ ldap_part_new (LdapPart *parent, const gchar *base_dn, GdaLdapSearchScope scope)
return part;
}
-static void
-ldap_part_free (LdapPart *part, LdapConnectionData *cdata)
+typedef struct {
+ GdaLdapConnection *cnc;
+ LdapConnectionData *cdata;
+ LdapPart *part;
+} WorkerLdapPartData;
+
+static gpointer
+worker_ldap_part_free (WorkerLdapPartData *data, GError **error)
{
- g_assert (part);
- g_free (part->base_dn);
- if (part->children) {
- g_slist_foreach (part->children, (GFunc) ldap_part_free, cdata);
- g_slist_free (part->children);
+ g_free (data->part->base_dn);
+ if (data->part->children) {
+ g_slist_foreach (data->part->children, (GFunc) ldap_part_free, data->cnc);
+ g_slist_free (data->part->children);
}
- if (part->ldap_msg) {
- ldap_msgfree (part->ldap_msg);
+ if (data->part->ldap_msg) {
+ ldap_msgfree (data->part->ldap_msg);
/* Release the connection being opened for this LdapPart */
- g_assert (cdata);
- g_assert (cdata->keep_bound_count > 0);
- cdata->keep_bound_count --;
- gda_ldap_may_unbind (cdata);
+ g_assert (data->cdata);
+ g_assert (data->cdata->keep_bound_count > 0);
+ data->cdata->keep_bound_count --;
+ gda_ldap_may_unbind (data->cnc);
+ }
+ g_free (data->part);
+ return NULL;
+}
+
+static void
+ldap_part_free (LdapPart *part, GdaLdapConnection *cnc)
+{
+ g_return_if_fail (part);
+ g_return_if_fail (cnc);
+
+ gda_lockable_lock ((GdaLockable*) cnc); /* CNC LOCK */
+
+ LdapConnectionData *cdata;
+ cdata = (LdapConnectionData*) gda_virtual_connection_internal_get_provider_data
(GDA_VIRTUAL_CONNECTION (cnc));
+ if (!cdata) {
+ gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */
+ g_warning ("cdata != NULL failed");
+ return;
}
- g_free (part);
+
+ GdaServerProviderConnectionData *pcdata;
+ pcdata = gda_connection_internal_get_provider_data_error ((GdaConnection*) cnc, NULL);
+
+ GdaWorker *worker;
+ worker = gda_worker_ref (gda_connection_internal_get_worker (pcdata));
+
+ GMainContext *context;
+ context = gda_server_provider_get_real_main_context ((GdaConnection *) cnc);
+
+ WorkerLdapPartData data;
+ data.cnc = cnc;
+ data.cdata = cdata;
+ data.part = part;
+
+ gda_connection_set_status ((GdaConnection*) cnc, GDA_CONNECTION_STATUS_BUSY);
+ gpointer retval;
+ gda_worker_do_job (worker, context, 0, &retval, NULL,
+ (GdaWorkerFunc) worker_ldap_part_free, (gpointer) &data, NULL, NULL, NULL);
+ if (context)
+ g_main_context_unref (context);
+
+ gda_connection_set_status ((GdaConnection*) cnc, GDA_CONNECTION_STATUS_IDLE);
+ gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */
+
+ gda_worker_unref (worker);
}
/*
@@ -1391,9 +1580,7 @@ ldap_part_split (LdapPart *part, GdaDataModelLdap *model, gboolean *out_error)
}
if (!sub) {
/* error */
- LdapConnectionData *cdata;
- cdata = (LdapConnectionData*) gda_virtual_connection_internal_get_provider_data
(GDA_VIRTUAL_CONNECTION (model->priv->cnc));
- g_slist_foreach (part->children, (GFunc) ldap_part_free, cdata);
+ g_slist_foreach (part->children, (GFunc) ldap_part_free, model->priv->cnc);
g_slist_free (part->children);
part->children = NULL;
break;
@@ -1562,7 +1749,7 @@ row_multiplier_index_next (RowMultiplier *rm)
}
/*
- * Writing support
+ * Writing data
*/
typedef struct {
@@ -1571,108 +1758,54 @@ typedef struct {
} FHData;
static void removed_attrs_func (const gchar *attr_name, GdaLdapAttribute *attr, FHData *data);
-gboolean
-gdaprov_ldap_modify (GdaLdapConnection *cnc, GdaLdapModificationType modtype,
- GdaLdapEntry *entry, GdaLdapEntry *ref_entry, GError **error)
-{
+typedef struct {
+ GdaLdapConnection *cnc;
LdapConnectionData *cdata;
- int res;
-
- g_return_val_if_fail (GDA_IS_LDAP_CONNECTION (cnc), FALSE);
- g_return_val_if_fail (entry, FALSE);
- if (entry)
- g_return_val_if_fail (gdaprov_ldap_is_dn (entry->dn), FALSE);
- if (ref_entry)
- g_return_val_if_fail (gdaprov_ldap_is_dn (ref_entry->dn), FALSE);
-
- cdata = (LdapConnectionData*) gda_virtual_connection_internal_get_provider_data
(GDA_VIRTUAL_CONNECTION (cnc));
- g_return_val_if_fail (cdata, FALSE);
-
- if (! gda_ldap_ensure_bound (cdata, error))
- return FALSE;
-
- /* checks */
- if ((modtype != GDA_LDAP_MODIFICATION_INSERT) &&
- (modtype != GDA_LDAP_MODIFICATION_ATTR_ADD) &&
- (modtype != GDA_LDAP_MODIFICATION_ATTR_DEL) &&
- (modtype != GDA_LDAP_MODIFICATION_ATTR_REPL) &&
- (modtype != GDA_LDAP_MODIFICATION_ATTR_DIFF)) {
- g_warning (_("Unknown GdaLdapModificationType %d"), modtype);
- gda_ldap_may_unbind (cdata);
- return FALSE;
- }
-
- if (((modtype == GDA_LDAP_MODIFICATION_DELETE) || (modtype == GDA_LDAP_MODIFICATION_INSERT)) &&
- !entry) {
- g_warning ("%s", _("No GdaLdapEntry specified"));
- gda_ldap_may_unbind (cdata);
- return FALSE;
- }
-
- if ((modtype == GDA_LDAP_MODIFICATION_ATTR_ADD) && !entry) {
- g_warning ("%s", _("No GdaLdapEntry specified to define attributes to add"));
- gda_ldap_may_unbind (cdata);
- return FALSE;
- }
-
- if ((modtype == GDA_LDAP_MODIFICATION_ATTR_DEL) && !entry) {
- g_warning ("%s", _("No GdaLdapEntry specified to define attributes to remove"));
- gda_ldap_may_unbind (cdata);
- return FALSE;
- }
+ GdaLdapModificationType modtype;
+ GdaLdapEntry *entry;
+ GdaLdapEntry *ref_entry;
+} WorkerLdapModData;
- if ((modtype == GDA_LDAP_MODIFICATION_ATTR_REPL) && !entry) {
- g_warning ("%s", _("No GdaLdapEntry specified to define attributes to replace"));
- gda_ldap_may_unbind (cdata);
- return FALSE;
- }
-
- if ((modtype == GDA_LDAP_MODIFICATION_ATTR_DIFF) && (!entry || !ref_entry)) {
- g_warning ("%s", _("No GdaLdapEntry specified to compare attributes"));
- gda_ldap_may_unbind (cdata);
- return FALSE;
- }
- if ((modtype == GDA_LDAP_MODIFICATION_ATTR_DIFF) && strcmp (entry->dn, ref_entry->dn)) {
- g_warning ("%s", _("GdaLdapEntry specified to compare have different DN"));
- gda_ldap_may_unbind (cdata);
- return FALSE;
- }
+gpointer
+worker_gdaprov_ldap_modify (WorkerLdapModData *data, GError **error)
+{
+ int res;
/* handle DELETE operation */
- if (modtype == GDA_LDAP_MODIFICATION_DELETE) {
- res = ldap_delete_ext_s (cdata->handle, entry->dn, NULL, NULL);
+ if (data->modtype == GDA_LDAP_MODIFICATION_DELETE) {
+ res = ldap_delete_ext_s (data->cdata->handle, data->entry->dn, NULL, NULL);
if (res != LDAP_SUCCESS) {
g_set_error (error, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_OTHER_ERROR,
"%s", ldap_err2string (res));
- gda_ldap_may_unbind (cdata);
- return FALSE;
+ gda_ldap_may_unbind (data->cnc);
+ return NULL;
}
else {
- gda_ldap_may_unbind (cdata);
- return TRUE;
+ gda_ldap_may_unbind (data->cnc);
+ return (gpointer) 0x01;
}
}
/* build array of modifications to perform */
GArray *mods_array;
mods_array = g_array_new (TRUE, FALSE, sizeof (LDAPMod*));
- if (modtype == GDA_LDAP_MODIFICATION_ATTR_DIFF) {
+ if (data->modtype == GDA_LDAP_MODIFICATION_ATTR_DIFF) {
/* index ref_entry's attributes */
GHashTable *hash;
guint i;
hash = g_hash_table_new (g_str_hash, g_str_equal);
- for (i = 0; i < ref_entry->nb_attributes; i++) {
+ for (i = 0; i < data->ref_entry->nb_attributes; i++) {
GdaLdapAttribute *attr;
- attr = ref_entry->attributes [i];
+ attr = data->ref_entry->attributes [i];
g_hash_table_insert (hash, attr->attr_name, attr);
}
- for (i = 0; i < entry->nb_attributes; i++) {
+ for (i = 0; i < data->entry->nb_attributes; i++) {
LDAPMod *mod;
GdaLdapAttribute *attr, *ref_attr;
guint j;
- attr = entry->attributes [i];
+ attr = data->entry->attributes [i];
ref_attr = g_hash_table_lookup (hash, attr->attr_name);
mod = g_new0 (LDAPMod, 1);
@@ -1686,37 +1819,37 @@ gdaprov_ldap_modify (GdaLdapConnection *cnc, GdaLdapModificationType modtype,
mod->mod_bvalues = g_new0 (struct berval *, attr->nb_values + 1); /* last is NULL */
for (j = 0; j < attr->nb_values; j++)
- mod->mod_bvalues[j] = gda_ldap_attr_g_value_to_value (cdata, attr->values
[j]);
+ mod->mod_bvalues[j] = gda_ldap_attr_g_value_to_value (data->cdata,
attr->values [j]);
g_array_append_val (mods_array, mod);
}
FHData fhdata;
- fhdata.cdata = cdata;
+ fhdata.cdata = data->cdata;
fhdata.mods_array = mods_array;
g_hash_table_foreach (hash, (GHFunc) removed_attrs_func, &fhdata);
g_hash_table_destroy (hash);
}
else {
guint i;
- for (i = 0; i < entry->nb_attributes; i++) {
+ for (i = 0; i < data->entry->nb_attributes; i++) {
LDAPMod *mod;
GdaLdapAttribute *attr;
guint j;
- attr = entry->attributes [i];
+ attr = data->entry->attributes [i];
mod = g_new0 (LDAPMod, 1);
mod->mod_op = LDAP_MOD_BVALUES;
- if ((modtype == GDA_LDAP_MODIFICATION_INSERT) ||
- (modtype == GDA_LDAP_MODIFICATION_ATTR_ADD))
+ if ((data->modtype == GDA_LDAP_MODIFICATION_INSERT) ||
+ (data->modtype == GDA_LDAP_MODIFICATION_ATTR_ADD))
mod->mod_op |= LDAP_MOD_ADD;
- else if (modtype == GDA_LDAP_MODIFICATION_ATTR_DEL)
+ else if (data->modtype == GDA_LDAP_MODIFICATION_ATTR_DEL)
mod->mod_op |= LDAP_MOD_DELETE;
else
mod->mod_op |= LDAP_MOD_REPLACE;
mod->mod_type = attr->attr_name; /* no duplication */
mod->mod_bvalues = g_new0 (struct berval *, attr->nb_values + 1); /* last is NULL */
for (j = 0; j < attr->nb_values; j++)
- mod->mod_bvalues[j] = gda_ldap_attr_g_value_to_value (cdata, attr->values
[j]);
+ mod->mod_bvalues[j] = gda_ldap_attr_g_value_to_value (data->cdata,
attr->values [j]);
g_array_append_val (mods_array, mod);
}
}
@@ -1724,10 +1857,10 @@ gdaprov_ldap_modify (GdaLdapConnection *cnc, GdaLdapModificationType modtype,
gboolean retval = TRUE;
if (mods_array->len > 0) {
/* apply modifications */
- if (modtype == GDA_LDAP_MODIFICATION_INSERT)
- res = ldap_add_ext_s (cdata->handle, entry->dn, (LDAPMod **) mods_array->data, NULL,
NULL);
+ if (data->modtype == GDA_LDAP_MODIFICATION_INSERT)
+ res = ldap_add_ext_s (data->cdata->handle, data->entry->dn, (LDAPMod **)
mods_array->data, NULL, NULL);
else
- res = ldap_modify_ext_s (cdata->handle, entry->dn, (LDAPMod **) mods_array->data,
NULL, NULL);
+ res = ldap_modify_ext_s (data->cdata->handle, data->entry->dn, (LDAPMod **)
mods_array->data, NULL, NULL);
if (res != LDAP_SUCCESS) {
g_set_error (error, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_OTHER_ERROR,
@@ -1744,15 +1877,96 @@ gdaprov_ldap_modify (GdaLdapConnection *cnc, GdaLdapModificationType modtype,
if (mod->mod_values) {
guint j;
for (j = 0; mod->mod_values [j]; j++)
- gda_ldap_attr_value_free (cdata, mod->mod_bvalues [j]);
+ gda_ldap_attr_value_free (data->cdata, mod->mod_bvalues [j]);
g_free (mod->mod_values);
}
g_free (mod);
}
g_array_free (mods_array, TRUE);
- gda_ldap_may_unbind (cdata);
- return retval;
+ gda_ldap_may_unbind (data->cnc);
+ return retval ? (gpointer) 0x01 : NULL;
+}
+
+gboolean
+gdaprov_ldap_modify (GdaLdapConnection *cnc, GdaLdapModificationType modtype,
+ GdaLdapEntry *entry, GdaLdapEntry *ref_entry, GError **error)
+{
+ /* checks */
+ if (! entry || ! entry->dn) {
+ g_warning ("%s", _("No GdaLdapEntry specified"));
+ return FALSE;
+ }
+ g_return_val_if_fail (gdaprov_ldap_is_dn (entry->dn), FALSE);
+ if (ref_entry)
+ g_return_val_if_fail (gdaprov_ldap_is_dn (ref_entry->dn), FALSE);
+
+ if ((modtype != GDA_LDAP_MODIFICATION_INSERT) &&
+ (modtype != GDA_LDAP_MODIFICATION_ATTR_ADD) &&
+ (modtype != GDA_LDAP_MODIFICATION_ATTR_DEL) &&
+ (modtype != GDA_LDAP_MODIFICATION_ATTR_REPL) &&
+ (modtype != GDA_LDAP_MODIFICATION_ATTR_DIFF)) {
+ g_warning (_("Unknown GdaLdapModificationType %d"), modtype);
+ return FALSE;
+ }
+
+ if (modtype == GDA_LDAP_MODIFICATION_ATTR_DIFF) {
+ if (!ref_entry) {
+ g_warning ("%s", _("No GdaLdapEntry specified to compare attributes"));
+ return FALSE;
+ }
+ if (strcmp (entry->dn, ref_entry->dn)) {
+ g_warning ("%s", _("GdaLdapEntry specified to compare have different DN"));
+ return FALSE;
+ }
+ }
+
+ g_return_val_if_fail (GDA_IS_LDAP_CONNECTION (cnc), FALSE);
+
+ gda_lockable_lock ((GdaLockable*) cnc); /* CNC LOCK */
+
+ LdapConnectionData *cdata;
+ cdata = (LdapConnectionData*) gda_virtual_connection_internal_get_provider_data
(GDA_VIRTUAL_CONNECTION (cnc));
+ if (!cdata) {
+ gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */
+ g_warning ("cdata != NULL failed");
+ return FALSE;
+ }
+
+ if (! gda_ldap_ensure_bound (cnc, error)) {
+ gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */
+ return FALSE;
+ }
+
+ GdaServerProviderConnectionData *pcdata;
+ pcdata = gda_connection_internal_get_provider_data_error ((GdaConnection*) cnc, NULL);
+
+ GdaWorker *worker;
+ worker = gda_worker_ref (gda_connection_internal_get_worker (pcdata));
+
+ GMainContext *context;
+ context = gda_server_provider_get_real_main_context ((GdaConnection *) cnc);
+
+ WorkerLdapModData data;
+ data.cnc = cnc;
+ data.cdata = cdata;
+ data.modtype = modtype;
+ data.entry = entry;
+ data.ref_entry = ref_entry;
+
+ gda_connection_set_status ((GdaConnection*) cnc, GDA_CONNECTION_STATUS_BUSY);
+ gpointer retval;
+ gda_worker_do_job (worker, context, 0, &retval, NULL,
+ (GdaWorkerFunc) worker_gdaprov_ldap_modify, (gpointer) &data, NULL, NULL, error);
+ if (context)
+ g_main_context_unref (context);
+
+ gda_connection_set_status ((GdaConnection*) cnc, GDA_CONNECTION_STATUS_IDLE);
+ gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */
+
+ gda_worker_unref (worker);
+
+ return retval ? TRUE : FALSE;
}
static void
@@ -1770,37 +1984,30 @@ removed_attrs_func (const gchar *attr_name, GdaLdapAttribute *attr, FHData *data
g_array_append_val (data->mods_array, mod);
}
-gboolean
-gdaprov_ldap_rename_entry (GdaLdapConnection *cnc, const gchar *current_dn, const gchar *new_dn,
- GError **error)
-{
- g_return_val_if_fail (GDA_IS_LDAP_CONNECTION (cnc), FALSE);
- g_return_val_if_fail (current_dn && *current_dn, FALSE);
- g_return_val_if_fail (gdaprov_ldap_is_dn (current_dn), FALSE);
- g_return_val_if_fail (new_dn && *new_dn, FALSE);
- g_return_val_if_fail (gdaprov_ldap_is_dn (new_dn), FALSE);
-
+typedef struct {
+ GdaLdapConnection *cnc;
LdapConnectionData *cdata;
- cdata = (LdapConnectionData*) gda_virtual_connection_internal_get_provider_data
(GDA_VIRTUAL_CONNECTION (cnc));
- g_return_val_if_fail (cdata, FALSE);
-
- if (! gda_ldap_ensure_bound (cdata, error))
- return FALSE;
+ const gchar *current_dn;
+ const gchar *new_dn;
+} WorkerRenamEntryData;
+gpointer
+worker_gdaprov_ldap_rename_entry (WorkerRenamEntryData *data, GError **error)
+{
gchar **carray, **narray;
int res;
gboolean retval = TRUE;
gchar *parent = NULL;
- carray = gda_ldap_dn_split (current_dn, FALSE);
- narray = gda_ldap_dn_split (new_dn, FALSE);
+ carray = gda_ldap_dn_split (data->current_dn, FALSE);
+ narray = gda_ldap_dn_split (data->new_dn, FALSE);
if (carray[1] && narray[1] && strcmp (carray[1], narray[1]))
parent = narray [1];
else if (! carray[1] && narray[1])
parent = narray [1];
- res = ldap_rename_s (cdata->handle, current_dn, narray[0], parent, 1, NULL, NULL);
+ res = ldap_rename_s (data->cdata->handle, data->current_dn, narray[0], parent, 1, NULL, NULL);
g_strfreev (carray);
g_strfreev (narray);
@@ -1810,6 +2017,59 @@ gdaprov_ldap_rename_entry (GdaLdapConnection *cnc, const gchar *current_dn, cons
retval = FALSE;
}
- gda_ldap_may_unbind (cdata);
- return retval;
+ gda_ldap_may_unbind (data->cnc);
+ return retval ? (gpointer) 0x01 : NULL;
+}
+
+gboolean
+gdaprov_ldap_rename_entry (GdaLdapConnection *cnc, const gchar *current_dn, const gchar *new_dn, GError
**error)
+{
+ g_return_val_if_fail (GDA_IS_LDAP_CONNECTION (cnc), FALSE);
+ g_return_val_if_fail (current_dn && *current_dn, FALSE);
+ g_return_val_if_fail (gdaprov_ldap_is_dn (current_dn), FALSE);
+ g_return_val_if_fail (new_dn && *new_dn, FALSE);
+ g_return_val_if_fail (gdaprov_ldap_is_dn (new_dn), FALSE);
+
+ gda_lockable_lock ((GdaLockable*) cnc); /* CNC LOCK */
+
+ if (! gda_ldap_ensure_bound (cnc, error)) {
+ gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */
+ return FALSE;
+ }
+
+ LdapConnectionData *cdata;
+ cdata = (LdapConnectionData*) gda_virtual_connection_internal_get_provider_data
(GDA_VIRTUAL_CONNECTION (cnc));
+ if (!cdata) {
+ gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */
+ g_warning ("cdata != NULL failed");
+ return FALSE;
+ }
+
+ GdaServerProviderConnectionData *pcdata;
+ pcdata = gda_connection_internal_get_provider_data_error ((GdaConnection*) cnc, NULL);
+
+ GdaWorker *worker;
+ worker = gda_worker_ref (gda_connection_internal_get_worker (pcdata));
+
+ GMainContext *context;
+ context = gda_server_provider_get_real_main_context ((GdaConnection *) cnc);
+
+ WorkerRenamEntryData data;
+ data.cnc = (GdaLdapConnection*) cnc;
+ data.cdata = cdata;
+ data.current_dn = current_dn;
+ data.new_dn = new_dn;
+
+ gda_connection_set_status ((GdaConnection*) cnc, GDA_CONNECTION_STATUS_BUSY);
+ gpointer retval;
+ gda_worker_do_job (worker, context, 0, &retval, NULL,
+ (GdaWorkerFunc) worker_gdaprov_ldap_rename_entry, (gpointer) &data, NULL, NULL,
error);
+ if (context)
+ g_main_context_unref (context);
+
+ gda_connection_set_status ((GdaConnection*) cnc, GDA_CONNECTION_STATUS_IDLE);
+ gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */
+
+ gda_worker_unref (worker);
+ return retval ? TRUE : FALSE;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]