diff options
Diffstat (limited to 'ldap/servers/slapd/plugin_mr.c')
-rw-r--r-- | ldap/servers/slapd/plugin_mr.c | 182 |
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; +} + |