summaryrefslogtreecommitdiffstats
path: root/ldap/servers/slapd/plugin_mr.c
diff options
context:
space:
mode:
Diffstat (limited to 'ldap/servers/slapd/plugin_mr.c')
-rw-r--r--ldap/servers/slapd/plugin_mr.c182
1 files changed, 180 insertions, 2 deletions
diff --git a/ldap/servers/slapd/plugin_mr.c b/ldap/servers/slapd/plugin_mr.c
index 8f62a7a0..014082b7 100644
--- a/ldap/servers/slapd/plugin_mr.c
+++ b/ldap/servers/slapd/plugin_mr.c
@@ -47,9 +47,16 @@
#include "slap.h"
+struct mr_indexer_private {
+ Slapi_Value **sva; /* if using index_sv_fn */
+ struct berval **bva; /* if using index_fn */
+};
+
static oid_item_t* global_mr_oids = NULL;
static PRLock* global_mr_oids_lock = NULL;
+static int default_mr_indexer_create(Slapi_PBlock* pb);
+
static void
init_global_mr_lock()
{
@@ -78,6 +85,27 @@ plugin_mr_find( const char *nameoroid )
return ( pi );
}
+static int
+plugin_mr_get_type(struct slapdplugin *pi)
+{
+ int rc = LDAP_FILTER_EQUALITY;
+ if (pi) {
+ char **str = pi->plg_mr_names;
+ for (; str && *str; ++str) {
+ if (PL_strcasestr(*str, "substr")) {
+ rc = LDAP_FILTER_SUBSTRINGS;
+ break;
+ }
+ if (PL_strcasestr(*str, "approx")) {
+ rc = LDAP_FILTER_APPROX;
+ break;
+ }
+ }
+ }
+
+ return rc;
+}
+
static struct slapdplugin*
plugin_mr_find_registered (char* oid)
{
@@ -144,15 +172,32 @@ slapi_mr_indexer_create (Slapi_PBlock* opb)
!(rc = slapi_pblock_get (&pb, SLAPI_PLUGIN_MR_INDEXER_CREATE_FN, &createFn)) &&
createFn != NULL &&
!(rc = createFn (&pb)) &&
- !(rc = slapi_pblock_get (&pb, SLAPI_PLUGIN_MR_INDEX_FN, &indexFn)) &&
- indexFn != NULL)
+ ((!(rc = slapi_pblock_get (&pb, SLAPI_PLUGIN_MR_INDEX_FN, &indexFn)) &&
+ indexFn != NULL) ||
+ (!(rc = slapi_pblock_get (&pb, SLAPI_PLUGIN_MR_INDEX_SV_FN, &indexFn)) &&
+ indexFn != NULL)))
{
/* Success: this plugin can handle it. */
memcpy (opb, &pb, sizeof(Slapi_PBlock));
plugin_mr_bind (oid, mrp); /* for future reference */
+ rc = 0; /* success */
break;
}
}
+ if (rc != 0) {
+ /* look for a new syntax-style mr plugin */
+ struct slapdplugin *pi = plugin_mr_find(oid);
+ if (pi) {
+ Slapi_PBlock pb;
+ memcpy (&pb, opb, sizeof(Slapi_PBlock));
+ slapi_pblock_set(&pb, SLAPI_PLUGIN, pi);
+ rc = default_mr_indexer_create(&pb);
+ if (!rc) {
+ memcpy (opb, &pb, sizeof(Slapi_PBlock));
+ plugin_mr_bind (oid, pi); /* for future reference */
+ }
+ }
+ }
}
}
return rc;
@@ -229,3 +274,136 @@ slapi_mr_filter_index (Slapi_Filter* f, Slapi_PBlock* pb)
return rc;
}
+static struct mr_indexer_private *
+mr_indexer_private_new()
+{
+ return (struct mr_indexer_private *)slapi_ch_calloc(1, sizeof(struct mr_indexer_private));
+}
+
+static void
+mr_indexer_private_done(struct mr_indexer_private *mrip)
+{
+ if (mrip && mrip->sva) {
+ valuearray_free(&mrip->sva);
+ } else if (mrip && mrip->bva) {
+ ber_bvecfree(mrip->bva);
+ mrip->bva = NULL;
+ }
+}
+
+static void
+mr_indexer_private_free(struct mr_indexer_private **mrip)
+{
+ if (mrip) {
+ mr_indexer_private_done(*mrip);
+ slapi_ch_free((void **)mrip);
+ }
+}
+
+/* this function takes SLAPI_PLUGIN_MR_VALUES as Slapi_Value ** and
+ returns SLAPI_PLUGIN_MR_KEYS as Slapi_Value **
+*/
+static int
+mr_wrap_mr_index_sv_fn(Slapi_PBlock* pb)
+{
+ int rc = -1;
+ Slapi_Value **in_vals = NULL;
+ Slapi_Value **out_vals = NULL;
+ struct slapdplugin *pi = NULL;
+
+ slapi_pblock_set(pb, SLAPI_PLUGIN_MR_KEYS, out_vals); /* make sure output is cleared */
+ slapi_pblock_get(pb, SLAPI_PLUGIN, &pi);
+ if (!pi) {
+ LDAPDebug0Args(LDAP_DEBUG_ANY, "mr_wrap_mr_index_sv_fn: error - no plugin specified\n");
+ } else if (!pi->plg_mr_values2keys) {
+ LDAPDebug0Args(LDAP_DEBUG_ANY, "mr_wrap_mr_index_sv_fn: error - plugin has no plg_mr_values2keys function\n");
+ } else {
+ struct mr_indexer_private *mrip = NULL;
+ int ftype = plugin_mr_get_type(pi);
+ slapi_pblock_get(pb, SLAPI_PLUGIN_MR_VALUES, &in_vals);
+ (*pi->plg_mr_values2keys)(pb, in_vals, &out_vals, ftype);
+ slapi_pblock_set(pb, SLAPI_PLUGIN_MR_KEYS, out_vals);
+ /* we have to save out_vals to free next time or during destroy */
+ slapi_pblock_get(pb, SLAPI_PLUGIN_OBJECT, &mrip);
+ mr_indexer_private_done(mrip); /* free old vals, if any */
+ mrip->sva = out_vals; /* save pointer for later */
+ rc = 0;
+ }
+ return rc;
+}
+
+/* this function takes SLAPI_PLUGIN_MR_VALUES as struct berval ** and
+ returns SLAPI_PLUGIN_MR_KEYS as struct berval **
+*/
+static int
+mr_wrap_mr_index_fn(Slapi_PBlock* pb)
+{
+ int rc = -1;
+ struct berval **in_vals = NULL;
+ struct berval **out_vals = NULL;
+ struct mr_indexer_private *mrip = NULL;
+ Slapi_Value **in_vals_sv = NULL;
+ Slapi_Value **out_vals_sv = NULL;
+
+ slapi_pblock_get(pb, SLAPI_PLUGIN_MR_VALUES, &in_vals); /* get bervals */
+ /* convert bervals to sv ary */
+ valuearray_init_bervalarray(in_vals, &in_vals_sv);
+ slapi_pblock_set(pb, SLAPI_PLUGIN_MR_VALUES, in_vals_sv); /* use sv */
+ rc = mr_wrap_mr_index_sv_fn(pb);
+ /* get result sv keys */
+ slapi_pblock_get(pb, SLAPI_PLUGIN_MR_KEYS, &out_vals_sv);
+ /* convert to bvec */
+ valuearray_get_bervalarray(out_vals_sv, &out_vals);
+ valuearray_free(&out_vals_sv); /* don't need svals */
+ /* we have to save out_vals to free next time or during destroy */
+ slapi_pblock_get(pb, SLAPI_PLUGIN_OBJECT, &mrip);
+ mr_indexer_private_done(mrip); /* free old vals, if any */
+ mrip->bva = out_vals; /* save pointer for later */
+
+ return rc;
+}
+
+static int
+default_mr_indexer_destroy(Slapi_PBlock* pb)
+{
+ struct mr_indexer_private *mrip = NULL;
+
+ slapi_pblock_get(pb, SLAPI_PLUGIN_OBJECT, &mrip);
+ mr_indexer_private_free(&mrip);
+ mrip = NULL;
+ slapi_pblock_set(pb, SLAPI_PLUGIN_OBJECT, mrip);
+
+ return 0;
+}
+
+/* this is the default mr indexer create func
+ for new syntax-style mr plugins */
+static int
+default_mr_indexer_create(Slapi_PBlock* pb)
+{
+ int rc = -1;
+ struct slapdplugin *pi = NULL;
+
+ slapi_pblock_get(pb, SLAPI_PLUGIN, &pi);
+ if (NULL == pi) {
+ LDAPDebug0Args(LDAP_DEBUG_ANY, "default_mr_indexer_create: error - no plugin specified\n");
+ goto done;
+ }
+
+ if (NULL == pi->plg_mr_values2keys) {
+ LDAPDebug1Arg(LDAP_DEBUG_ANY, "default_mr_indexer_create: error - plugin [%s] has no plg_mr_values2keys function\n",
+ pi->plg_name);
+ goto done;
+ }
+
+ slapi_pblock_set(pb, SLAPI_PLUGIN_OBJECT, mr_indexer_private_new());
+ slapi_pblock_set(pb, SLAPI_PLUGIN_MR_INDEX_FN, mr_wrap_mr_index_fn);
+ slapi_pblock_set(pb, SLAPI_PLUGIN_MR_INDEX_SV_FN, mr_wrap_mr_index_sv_fn);
+ slapi_pblock_set(pb, SLAPI_PLUGIN_DESTROY_FN, default_mr_indexer_destroy);
+ slapi_pblock_set(pb, SLAPI_PLUGIN_MR_INDEXER_CREATE_FN, default_mr_indexer_create);
+ rc = 0;
+
+done:
+ return rc;
+}
+