Back to index

openldap  2.4.31
Classes | Defines | Typedefs | Functions | Variables
ndbio.cpp File Reference
#include "portable.h"
#include <stdio.h>
#include <ac/string.h>
#include <ac/errno.h>
#include <lutil.h>
#include "back-ndb.h"

Go to the source code of this file.

Classes

struct  MedVar

Defines

#define V_INS   1
#define V_DEL   2
#define V_REP   3

Typedefs

typedef struct MedVar MedVar

Functions

static int ndb_name_cmp (const void *v1, const void *v2)
static int ndb_oc_dup_err (void *v1, void *v2)
NdbAttrInfondb_ai_find (struct ndb_info *ni, AttributeType *at)
NdbAttrInfondb_ai_get (struct ndb_info *ni, struct berval *aname)
static int ndb_ai_check (struct ndb_info *ni, NdbOcInfo *oci, AttributeType **attrs, char **ptr, int *col, int create)
static int ndb_oc_create (struct ndb_info *ni, NdbOcInfo *oci, int create)
int ndb_oc_read (struct ndb_info *ni, const NdbDictionary::Dictionary *myDict)
static int ndb_oc_list (struct ndb_info *ni, const NdbDictionary::Dictionary *myDict, struct berval *oname, int implied, NdbOcs *out)
int ndb_aset_get (struct ndb_info *ni, struct berval *sname, struct berval *attrs, NdbOcInfo **ret)
int ndb_aset_create (struct ndb_info *ni, NdbOcInfo *oci)
static int ndb_oc_check (BackendDB *be, Ndb *ndb, struct berval *ocsin, NdbOcs *out)
int ndb_oc_attrs (NdbTransaction *txn, const NdbDictionary::Table *myTable, Entry *e, NdbOcInfo *no, NdbAttrInfo **attrs, int nattrs, Attribute *old)
static int ndb_oc_put (const NdbDictionary::Dictionary *myDict, NdbTransaction *txn, NdbOcInfo *no, Entry *e)
int ndb_entry_put_data (BackendDB *be, NdbArgs *NA)
static void ndb_oc_get (Operation *op, NdbOcInfo *no, int *j, int *nocs, NdbOcInfo ***oclist)
int ndb_entry_get_data (Operation *op, NdbArgs *NA, int update)
static int ndb_oc_del (NdbTransaction *txn, Uint64 eid, NdbOcInfo *no)
int ndb_entry_del_data (BackendDB *be, NdbArgs *NA)
int ndb_dn2rdns (struct berval *dn, NdbRdns *rdns)
static int ndb_rdns2keys (NdbOperation *myop, NdbRdns *rdns)
int ndb_entry_put_info (BackendDB *be, NdbArgs *NA, int update)
struct bervalndb_str2bvarray (char *str, int len, char delim, void *ctx)
struct bervalndb_ref2oclist (const char *ref, void *ctx)
int ndb_entry_get_info (Operation *op, NdbArgs *NA, int update, struct berval *matched)
int ndb_entry_del_info (BackendDB *be, NdbArgs *NA)
int ndb_next_id (BackendDB *be, Ndb *ndb, ID *id)
static void ndb_thread_hfree (void *key, void *data)
int ndb_thread_handle (Operation *op, Ndb **ndb)
int ndb_entry_get (Operation *op, struct berval *ndn, ObjectClass *oc, AttributeDescription *ad, int rw, Entry **ent)
void ndb_trans_backoff (int num_retries)
void ndb_check_referral (Operation *op, SlapReply *rs, NdbArgs *NA)

Variables

static int ndb_flush_blobs

Class Documentation

struct MedVar

Definition at line 31 of file ndbio.cpp.

Class Members
char buf
Int16 len

Define Documentation

#define V_DEL   2

Definition at line 528 of file ndbio.cpp.

#define V_INS   1

Definition at line 527 of file ndbio.cpp.

#define V_REP   3

Definition at line 529 of file ndbio.cpp.


Typedef Documentation

typedef struct MedVar MedVar

Function Documentation

static int ndb_ai_check ( struct ndb_info ni,
NdbOcInfo oci,
AttributeType **  attrs,
char **  ptr,
int col,
int  create 
) [static]

Definition at line 106 of file ndbio.cpp.

{
       NdbAttrInfo *ai;
       int i;

       for ( i=0; attrs[i]; i++ ) {
              if ( attrs[i] == slap_schema.si_ad_objectClass->ad_type )
                     continue;
              /* skip attrs that are in a superior */
              if ( oci->no_oc && oci->no_oc->soc_sups ) {
                     int j, k, found=0;
                     ObjectClass *oc;
                     for ( j=0; oci->no_oc->soc_sups[j]; j++ ) {
                            oc = oci->no_oc->soc_sups[j];
                            if ( oc->soc_kind == LDAP_SCHEMA_ABSTRACT )
                                   continue;
                            if ( oc->soc_required ) {
                                   for ( k=0; oc->soc_required[k]; k++ ) {
                                          if ( attrs[i] == oc->soc_required[k] ) {
                                                 found = 1;
                                                 break;
                                          }
                                   }
                                   if ( found ) break;
                            }
                            if ( oc->soc_allowed ) {
                                   for ( k=0; oc->soc_allowed[k]; k++ ) {
                                          if ( attrs[i] == oc->soc_allowed[k] ) {
                                                 found = 1;
                                                 break;
                                          }
                                   }
                                   if ( found ) break;
                            }
                     }
                     if ( found )
                            continue;
              }

              ai = ndb_ai_get( ni, &attrs[i]->sat_cname );
              if ( !ai ) {
                     /* can never happen */
                     return LDAP_OTHER;
              }

              /* An attrset may have already been connected */
              if (( oci->no_flag & NDB_INFO_ATSET ) && ai->na_oi == oci )
                     continue;

              /* An indexed attr is defined before its OC is */
              if ( !ai->na_oi ) {
                     ai->na_oi = oci;
                     ai->na_column = (*col)++;
              }

              oci->no_attrs[oci->no_nattrs++] = ai;

              /* An attrset attr may already be defined */
              if ( ai->na_oi != oci ) {
                     int j;
                     for ( j=0; j<oci->no_nsets; j++ )
                            if ( oci->no_sets[j] == ai->na_oi ) break;
                     if ( j >= oci->no_nsets ) {
                            /* FIXME: data loss if more sets are in use */
                            if ( oci->no_nsets < NDB_MAX_OCSETS ) {
                                   oci->no_sets[oci->no_nsets++] = ai->na_oi;
                            }
                     }
                     continue;
              }

              if ( create ) {
                     if ( ai->na_flag & NDB_INFO_ATBLOB ) {
                            *ptr += sprintf( *ptr, ", `%s` BLOB", ai->na_attr->sat_cname.bv_val );
                     } else {
                            *ptr += sprintf( *ptr, ", `%s` VARCHAR(%d)", ai->na_attr->sat_cname.bv_val,
                                   ai->na_len );
                     }
              }
       }
       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

NdbAttrInfo* ndb_ai_find ( struct ndb_info ni,
AttributeType at 
)

Definition at line 59 of file ndbio.cpp.

{
       NdbAttrInfo atmp;
       atmp.na_name = at->sat_cname;

       return (NdbAttrInfo *)avl_find( ni->ni_ai_tree, &atmp, ndb_name_cmp );
}

Here is the call graph for this function:

Here is the caller graph for this function:

NdbAttrInfo* ndb_ai_get ( struct ndb_info ni,
struct berval aname 
)

Definition at line 69 of file ndbio.cpp.

{
       NdbAttrInfo atmp, *ai;
       atmp.na_name = *aname;

       ai = (NdbAttrInfo *)avl_find( ni->ni_ai_tree, &atmp, ndb_name_cmp );
       if ( !ai ) {
              const char *text;
              AttributeDescription *ad = NULL;

              if ( slap_bv2ad( aname, &ad, &text ))
                     return NULL;

              ai = (NdbAttrInfo *)ch_malloc( sizeof( NdbAttrInfo ));
              ai->na_desc = ad;
              ai->na_attr = ai->na_desc->ad_type;
              ai->na_name = ai->na_attr->sat_cname;
              ai->na_oi = NULL;
              ai->na_flag = 0;
              ai->na_ixcol = 0;
              ai->na_len = ai->na_attr->sat_atype.at_syntax_len;
              /* Reasonable default */
              if ( !ai->na_len ) {
                     if ( ai->na_attr->sat_syntax == slap_schema.si_syn_distinguishedName )
                            ai->na_len = 1024;
                     else
                            ai->na_len = 128;
              }
              /* Arbitrary limit */
              if ( ai->na_len > 1024 )
                     ai->na_len = 1024;
              avl_insert( &ni->ni_ai_tree, ai, ndb_name_cmp, avl_dup_error );
       }
       return ai;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int ndb_aset_create ( struct ndb_info ni,
NdbOcInfo oci 
)

Definition at line 471 of file ndbio.cpp.

{
       char buf[4096], *ptr;
       NdbAttrInfo *ai;
       int i;

       ptr = buf + sprintf( buf,
              "CREATE TABLE IF NOT EXISTS `%s` (eid bigint unsigned NOT NULL, vid int unsigned NOT NULL",
              oci->no_table.bv_val );

       for ( i=0; i<oci->no_nattrs; i++ ) {
              if ( oci->no_attrs[i]->na_oi != oci )
                     continue;
              ai = oci->no_attrs[i];
              ptr += sprintf( ptr, ", `%s` VARCHAR(%d)", ai->na_attr->sat_cname.bv_val,
                     ai->na_len );
              if ( ai->na_flag & NDB_INFO_INDEX ) {
                     ptr += sprintf( ptr, ", INDEX (`%s`)", ai->na_attr->sat_cname.bv_val );
              }
       }
       ptr = lutil_strcopy( ptr, ", PRIMARY KEY(eid, vid) ) ENGINE=ndb PARTITION BY KEY(eid)" );
       i = mysql_real_query( &ni->ni_sql, buf, ptr - buf );
       if ( i ) {
              Debug( LDAP_DEBUG_ANY,
                     "ndb_aset_create: CREATE TABLE %s failed, %s (%d)\n",
                     oci->no_table.bv_val, mysql_error(&ni->ni_sql), mysql_errno(&ni->ni_sql) );
       }
       return i;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int ndb_aset_get ( struct ndb_info ni,
struct berval sname,
struct berval attrs,
NdbOcInfo **  ret 
)

Definition at line 425 of file ndbio.cpp.

{
       NdbOcInfo *oci, octmp;
       int i, rc;

       octmp.no_name = *sname;
       oci = (NdbOcInfo *)avl_find( ni->ni_oc_tree, &octmp, ndb_name_cmp );
       if ( oci )
              return LDAP_ALREADY_EXISTS;

       for ( i=0; !BER_BVISNULL( &attrs[i] ); i++ ) {
              if ( !at_bvfind( &attrs[i] ))
                     return LDAP_NO_SUCH_ATTRIBUTE;
       }
       i++;

       oci = (NdbOcInfo *)ch_calloc( 1, sizeof( NdbOcInfo ) + sizeof( ObjectClass ) +
              i*sizeof(AttributeType *) + sname->bv_len+1 );
       oci->no_oc = (ObjectClass *)(oci+1);
       oci->no_oc->soc_required = (AttributeType **)(oci->no_oc+1);
       oci->no_table.bv_val = (char *)(oci->no_oc->soc_required+i);

       for ( i=0; !BER_BVISNULL( &attrs[i] ); i++ )
              oci->no_oc->soc_required[i] = at_bvfind( &attrs[i] );

       strcpy( oci->no_table.bv_val, sname->bv_val );
       oci->no_table.bv_len = sname->bv_len;
       oci->no_name = oci->no_table;
       oci->no_oc->soc_cname = oci->no_name;
       oci->no_flag = NDB_INFO_ATSET;

       if ( !ber_bvcmp( sname, &slap_schema.si_oc_extensibleObject->soc_cname ))
              oci->no_oc->soc_kind = slap_schema.si_oc_extensibleObject->soc_kind;

       rc = ndb_oc_create( ni, oci, 0 );
       if ( !rc )
              rc = avl_insert( &ni->ni_oc_tree, oci, ndb_name_cmp, avl_dup_error );
       if ( rc ) {
              ch_free( oci );
       } else {
              *ret = oci;
       }
       return rc;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void ndb_check_referral ( Operation op,
SlapReply rs,
NdbArgs NA 
)

Definition at line 1640 of file ndbio.cpp.

{
       struct berval dn, ndn;
       int i, dif;
       dif = NA->erdns - NA->rdns->nr_num;

       /* Set full DN of matched into entry */
       for ( i=0; i<dif; i++ ) {
              dnParent( &NA->e->e_name, &dn );
              dnParent( &NA->e->e_nname, &ndn );
              NA->e->e_name = dn;
              NA->e->e_nname = ndn;
       }

       /* return referral only if "disclose" is granted on the object */
       if ( access_allowed( op, NA->e, slap_schema.si_ad_entry,
              NULL, ACL_DISCLOSE, NULL )) {
              Attribute a;
              for ( i=0; !BER_BVISNULL( &NA->ocs[i] ); i++ );
              a.a_numvals = i;
              a.a_desc = slap_schema.si_ad_objectClass;
              a.a_vals = NA->ocs;
              a.a_nvals = NA->ocs;
              a.a_next = NULL;
              NA->e->e_attrs = &a;
              if ( is_entry_referral( NA->e )) {
                     NA->e->e_attrs = NULL;
                     ndb_entry_get_data( op, NA, 0 );
                     rs->sr_ref = get_entry_referrals( op, NA->e );
                     if ( rs->sr_ref ) {
                            rs->sr_err = LDAP_REFERRAL;
                            rs->sr_flags |= REP_REF_MUSTBEFREED;
                     }
                     attrs_free( NA->e->e_attrs );
              }
              NA->e->e_attrs = NULL;
       }
}

Here is the call graph for this function:

int ndb_dn2rdns ( struct berval dn,
NdbRdns rdns 
)

Definition at line 1080 of file ndbio.cpp.

{
       char *beg, *end;
       int i, len;

       /* Walk thru RDNs */
       end = dn->bv_val + dn->bv_len;
       for ( i=0; i<NDB_MAX_RDNS; i++ ) {
              for ( beg = end-1; beg > dn->bv_val; beg-- ) {
                     if (*beg == ',') {
                            beg++;
                            break;
                     }
              }
              if ( beg >= dn->bv_val ) {
                     len = end - beg;
                     /* RDN is too long */
                     if ( len > NDB_RDN_LEN )
                            return LDAP_CONSTRAINT_VIOLATION;
                     memcpy( rdns->nr_buf[i]+1, beg, len );
              } else {
                     break;
              }
              rdns->nr_buf[i][0] = len;
              end = beg - 1;
       }
       /* Too many RDNs in DN */
       if ( i == NDB_MAX_RDNS && beg > dn->bv_val ) {
                     return LDAP_CONSTRAINT_VIOLATION;
       }
       rdns->nr_num = i;
       return 0;
}

Here is the caller graph for this function:

int ndb_entry_del_data ( BackendDB be,
NdbArgs NA 
)

Definition at line 1058 of file ndbio.cpp.

{
       struct ndb_info *ni = (struct ndb_info *) be->be_private;
       Uint64 eid = NA->e->e_id;
       int i;
       NdbOcs myOcs;

       ndb_oc_check( be, NA->ndb, NA->ocs, &myOcs );
       myOcs.no_info[myOcs.no_ninfo++] = ni->ni_opattrs;

       for ( i=0; i<myOcs.no_ninfo; i++ ) {
              if ( ndb_oc_del( NA->txn, eid, myOcs.no_info[i] ))
                     return LDAP_OTHER;
       }

       return 0;
}

Here is the call graph for this function:

int ndb_entry_del_info ( BackendDB be,
NdbArgs NA 
)

Definition at line 1455 of file ndbio.cpp.

{
       struct ndb_info *ni = (struct ndb_info *) be->be_private;
       const NdbDictionary::Dictionary *myDict = NA->ndb->getDictionary();
       const NdbDictionary::Table *myTable = myDict->getTable( DN2ID_TABLE );
       NdbOperation *myop;

       myop = NA->txn->getNdbOperation( myTable );
       if ( !myop )
              return LDAP_OTHER;
       if ( myop->deleteTuple())
              return LDAP_OTHER;

       if ( ndb_rdns2keys( myop, NA->rdns ))
              return LDAP_OTHER;

       return 0;
}

Here is the call graph for this function:

int ndb_entry_get ( Operation op,
struct berval ndn,
ObjectClass oc,
AttributeDescription ad,
int  rw,
Entry **  ent 
)

Definition at line 1550 of file ndbio.cpp.

{
       struct ndb_info *ni = (struct ndb_info *) op->o_bd->be_private;
       NdbArgs NA;
       Entry e = {0};
       int rc;

       /* Get our NDB handle */
       rc = ndb_thread_handle( op, &NA.ndb );

       NA.txn = NA.ndb->startTransaction();
       if( !NA.txn ) {
              Debug( LDAP_DEBUG_TRACE,
                     LDAP_XSTRING(ndb_entry_get) ": startTransaction failed: %s (%d)\n",
                     NA.ndb->getNdbError().message, NA.ndb->getNdbError().code, 0 );
              return 1;
       }

       e.e_name = *ndn;
       NA.e = &e;
       /* get entry */
       {
              NdbRdns rdns;
              rdns.nr_num = 0;
              NA.ocs = NULL;
              NA.rdns = &rdns;
              rc = ndb_entry_get_info( op, &NA, rw, NULL );
       }
       if ( rc == 0 ) {
              e.e_name = *ndn;
              e.e_nname = *ndn;
              rc = ndb_entry_get_data( op, &NA, 0 );
              ber_bvarray_free( NA.ocs );
              if ( rc == 0 ) {
                     if ( oc && !is_entry_objectclass_or_sub( &e, oc )) {
                            attrs_free( e.e_attrs );
                            rc = 1;
                     }
              }
       }
       if ( rc == 0 ) {
              *ent = entry_alloc();
              **ent = e;
              ber_dupbv( &(*ent)->e_name, ndn );
              ber_dupbv( &(*ent)->e_nname, ndn );
       } else {
              rc = 1;
       }
       NA.txn->close();
       return rc;
}
int ndb_entry_get_data ( Operation op,
NdbArgs NA,
int  update 
)

Definition at line 780 of file ndbio.cpp.

{
       struct ndb_info *ni = (struct ndb_info *) op->o_bd->be_private;
       const NdbDictionary::Dictionary *myDict = NA->ndb->getDictionary();
       const NdbDictionary::Table *myTable;
       NdbIndexScanOperation **myop = NULL;
       Uint64 eid;

       Attribute *a;
       NdbOcs myOcs;
       NdbOcInfo *oci, **oclist = NULL;
       char abuf[65536], *ptr, **attrs = NULL;
       struct berval bv[2];
       int *ocx = NULL;

       /* FIXME: abuf should be dynamically allocated */

       int i, j, k, nocs, nattrs, rc = LDAP_OTHER;

       eid = NA->e->e_id;

       ndb_oc_check( op->o_bd, NA->ndb, NA->ocs, &myOcs );
       myOcs.no_info[myOcs.no_ninfo++] = ni->ni_opattrs;
       nocs = myOcs.no_ninfo;

       oclist = (NdbOcInfo **)op->o_tmpcalloc( 1, nocs * sizeof(NdbOcInfo *), op->o_tmpmemctx );

       for ( i=0, j=0; i<myOcs.no_ninfo; i++ ) {
              ndb_oc_get( op, myOcs.no_info[i], &j, &nocs, &oclist );
       }

       nocs = j;
       nattrs = 0;
       for ( i=0; i<nocs; i++ )
              nattrs += oclist[i]->no_nattrs;

       ocx = (int *)op->o_tmpalloc( nocs * sizeof(int), op->o_tmpmemctx );

       attrs = (char **)op->o_tmpalloc( nattrs * sizeof(char *), op->o_tmpmemctx );

       myop = (NdbIndexScanOperation **)op->o_tmpalloc( nattrs * sizeof(NdbIndexScanOperation *), op->o_tmpmemctx );

       k = 0;
       ptr = abuf;
       for ( i=0; i<nocs; i++ ) {
              oci = oclist[i];

              myop[i] = NA->txn->getNdbIndexScanOperation( "PRIMARY", oci->no_table.bv_val );
              if ( !myop[i] )
                     goto leave;
              if ( myop[i]->readTuples( update ? NdbOperation::LM_Exclusive : NdbOperation::LM_CommittedRead ))
                     goto leave;
              if ( myop[i]->setBound( 0U, NdbIndexScanOperation::BoundEQ, &eid ))
                     goto leave;

              for ( j=0; j<oci->no_nattrs; j++ ) {
                     if ( oci->no_attrs[j]->na_oi != oci )
                            continue;
                     if ( oci->no_attrs[j]->na_flag & NDB_INFO_ATBLOB ) {
                            NdbBlob *bi = myop[i]->getBlobHandle( oci->no_attrs[j]->na_column );
                            attrs[k++] = (char *)bi;
                     } else {
                            attrs[k] = ptr;
                            *ptr++ = 0;
                            if ( oci->no_attrs[j]->na_len > 255 )
                                   *ptr++ = 0;
                            ptr += oci->no_attrs[j]->na_len + 1;
                            myop[i]->getValue( oci->no_attrs[j]->na_column, attrs[k++] );
                     }
              }
              ocx[i] = k;
       }
       /* Must use IgnoreError, because an entry with multiple objectClasses may not
        * actually have attributes defined in each class / table.
        */
       if ( NA->txn->execute( NdbTransaction::NoCommit, NdbOperation::AO_IgnoreError, 1) < 0 )
              goto leave;

       /* count results */
       for ( i=0; i<nocs; i++ ) {
              if (( j = myop[i]->nextResult(true) )) {
                     if ( j < 0 ) {
                            Debug( LDAP_DEBUG_TRACE,
                                   "ndb_entry_get_data: first nextResult(%d) failed: %s (%d)\n",
                                   i, myop[i]->getNdbError().message, myop[i]->getNdbError().code );
                     }
                     myop[i] = NULL;
              }
       }

       nattrs = 0;
       k = 0;
       for ( i=0; i<nocs; i++ ) {
              oci = oclist[i];
              for ( j=0; j<oci->no_nattrs; j++ ) {
                     unsigned char *buf;
                     int len;
                     if ( oci->no_attrs[j]->na_oi != oci )
                            continue;
                     if ( !myop[i] ) {
                            attrs[k] = NULL;
                     } else if ( oci->no_attrs[j]->na_flag & NDB_INFO_ATBLOB ) {
                            void *vi = attrs[k];
                            NdbBlob *bi = (NdbBlob *)vi;
                            int isNull;
                            bi->getNull( isNull );
                            if ( !isNull ) {
                                   nattrs++;
                            } else {
                                   attrs[k] = NULL;
                            }
                     } else {
                            buf = (unsigned char *)attrs[k];
                            len = buf[0];
                            if ( oci->no_attrs[j]->na_len > 255 ) {
                                   /* MedVar */
                                   len |= (buf[1] << 8);
                            }
                            if ( len ) {
                                   nattrs++;
                            } else {
                                   attrs[k] = NULL;
                            }
                     }
                     k++;
              }
       }

       a = attrs_alloc( nattrs+1 );
       NA->e->e_attrs = a;

       a->a_desc = slap_schema.si_ad_objectClass;
       a->a_vals = NULL;
       ber_bvarray_dup_x( &a->a_vals, NA->ocs, NULL );
       a->a_nvals = a->a_vals;
       a->a_numvals = myOcs.no_ntext;

       BER_BVZERO( &bv[1] );

       do {
              a = NA->e->e_attrs->a_next;
              k = 0;
              for ( i=0; i<nocs; k=ocx[i], i++ ) {
                     oci = oclist[i];
                     for ( j=0; j<oci->no_nattrs; j++ ) {
                            unsigned char *buf;
                            struct berval nbv;
                            if ( oci->no_attrs[j]->na_oi != oci )
                                   continue;
                            buf = (unsigned char *)attrs[k++];
                            if ( !buf )
                                   continue;
                            if ( !myop[i] ) {
                                   a=a->a_next;
                                   continue;
                            }
                            if ( oci->no_attrs[j]->na_flag & NDB_INFO_ATBLOB ) {
                                   void *vi = (void *)buf;
                                   NdbBlob *bi = (NdbBlob *)vi;
                                   Uint64 len;
                                   Uint32 len2;
                                   int isNull;
                                   bi->getNull( isNull );
                                   if ( isNull ) {
                                          a = a->a_next;
                                          continue;
                                   }
                                   bi->getLength( len );
                                   bv[0].bv_len = len;
                                   bv[0].bv_val = (char *)ch_malloc( len+1 );
                                   len2 = len;
                                   if ( bi->readData( bv[0].bv_val, len2 )) {
                                          Debug( LDAP_DEBUG_TRACE,
                                                 "ndb_entry_get_data: blob readData failed: %s (%d), len %d\n",
                                                 bi->getNdbError().message, bi->getNdbError().code, len2 );
                                   }
                                   bv[0].bv_val[len] = '\0';
                                   ber_bvarray_add_x( &a->a_vals, bv, NULL );
                            } else {
                                   bv[0].bv_len = buf[0];
                                   if ( oci->no_attrs[j]->na_len > 255 ) {
                                          /* MedVar */
                                          bv[0].bv_len |= (buf[1] << 8);
                                          bv[0].bv_val = (char *)buf+2;
                                          buf[1] = 0;
                                   } else {
                                          bv[0].bv_val = (char *)buf+1;
                                   }
                                   buf[0] = 0;
                                   if ( bv[0].bv_len == 0 ) {
                                          a = a->a_next;
                                          continue;
                                   }
                                   bv[0].bv_val[bv[0].bv_len] = '\0';
                                   value_add_one( &a->a_vals, bv );
                            }
                            a->a_desc = oci->no_attrs[j]->na_desc;
                            attr_normalize_one( a->a_desc, bv, &nbv, NULL );
                            a->a_numvals++;
                            if ( !BER_BVISNULL( &nbv )) {
                                   ber_bvarray_add_x( &a->a_nvals, &nbv, NULL );
                            } else if ( !a->a_nvals ) {
                                   a->a_nvals = a->a_vals;
                            }
                            a = a->a_next;
                     }
              }
              k = 0;
              for ( i=0; i<nocs; i++ ) {
                     if ( !myop[i] )
                            continue;
                     if ((j = myop[i]->nextResult(true))) {
                            if ( j < 0 ) {
                                   Debug( LDAP_DEBUG_TRACE,
                                          "ndb_entry_get_data: last nextResult(%d) failed: %s (%d)\n",
                                          i, myop[i]->getNdbError().message, myop[i]->getNdbError().code );
                            }
                            myop[i] = NULL;
                     } else {
                            k = 1;
                     }
              }
       } while ( k );

       rc = 0;
leave:
       if ( myop ) {
              op->o_tmpfree( myop, op->o_tmpmemctx );
       }
       if ( attrs ) {
              op->o_tmpfree( attrs, op->o_tmpmemctx );
       }
       if ( ocx ) {
              op->o_tmpfree( ocx, op->o_tmpmemctx );
       }
       if ( oclist ) {
              op->o_tmpfree( oclist, op->o_tmpmemctx );
       }

       return rc;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int ndb_entry_get_info ( Operation op,
NdbArgs NA,
int  update,
struct berval matched 
)

Definition at line 1322 of file ndbio.cpp.

{
       struct ndb_info *ni = (struct ndb_info *) op->o_bd->be_private;
       const NdbDictionary::Dictionary *myDict = NA->ndb->getDictionary();
       const NdbDictionary::Table *myTable = myDict->getTable( DN2ID_TABLE );
       NdbOperation *myop[NDB_MAX_RDNS];
       NdbRecAttr *eid[NDB_MAX_RDNS], *oc[NDB_MAX_RDNS];
       char idbuf[NDB_MAX_RDNS][2*sizeof(ID)];
       char ocbuf[NDB_MAX_RDNS][NDB_OC_BUFLEN];

       if ( matched ) {
              BER_BVZERO( matched );
       }
       if ( !myTable ) {
              return LDAP_OTHER;
       }

       myop[0] = NA->txn->getNdbOperation( myTable );
       if ( !myop[0] ) {
              return LDAP_OTHER;
       }

       if ( myop[0]->readTuple( update ? NdbOperation::LM_Exclusive : NdbOperation::LM_CommittedRead )) {
              return LDAP_OTHER;
       }

       if ( !NA->rdns->nr_num && ndb_dn2rdns( &NA->e->e_name, NA->rdns )) {
              return LDAP_NO_SUCH_OBJECT;
       }

       if ( ndb_rdns2keys( myop[0], NA->rdns )) {
              return LDAP_OTHER;
       }

       eid[0] = myop[0]->getValue( EID_COLUMN, idbuf[0] );
       if ( !eid[0] ) {
              return LDAP_OTHER;
       }

       ocbuf[0][0] = 0;
       ocbuf[0][1] = 0;
       if ( !NA->ocs ) {
              oc[0] = myop[0]->getValue( OCS_COLUMN, ocbuf[0] );
              if ( !oc[0] ) {
                     return LDAP_OTHER;
              }
       }

       if ( NA->txn->execute(NdbTransaction::NoCommit, NdbOperation::AO_IgnoreError, 1) < 0 ) {
              return LDAP_OTHER;
       }

       switch( myop[0]->getNdbError().code ) {
       case 0:
              if ( !eid[0]->isNULL() && ( NA->e->e_id = eid[0]->u_64_value() )) {
                     /* If we didn't care about OCs, or we got them */
                     if ( NA->ocs || ocbuf[0][0] || ocbuf[0][1] ) {
                            /* If wanted, return them */
                            if ( !NA->ocs )
                                   NA->ocs = ndb_ref2oclist( ocbuf[0], op->o_tmpmemctx );
                            break;
                     }
              }
              /* FALLTHRU */
       case NDB_NO_SUCH_OBJECT:    /* no such tuple: look for closest parent */
              if ( matched ) {
                     int i, j, k;
                     char dummy[2] = {0,0};

                     /* get to last RDN, then back up 1 */
                     k = NA->rdns->nr_num - 1;

                     for ( i=0; i<k; i++ ) {
                            myop[i] = NA->txn->getNdbOperation( myTable );
                            if ( !myop[i] )
                                   return LDAP_OTHER;
                            if ( myop[i]->readTuple( NdbOperation::LM_CommittedRead ))
                                   return LDAP_OTHER;
                            for ( j=0; j<=i; j++ ) {
                                   if ( myop[i]->equal( j+RDN_COLUMN, NA->rdns->nr_buf[j] ))
                                          return LDAP_OTHER;
                            }
                            for ( ;j<NDB_MAX_RDNS; j++ ) {
                                   if ( myop[i]->equal( j+RDN_COLUMN, dummy ))
                                          return LDAP_OTHER;
                            }
                            eid[i] = myop[i]->getValue( EID_COLUMN, idbuf[i] );
                            if ( !eid[i] ) {
                                   return LDAP_OTHER;
                            }
                            ocbuf[i][0] = 0;
                            ocbuf[i][1] = 0;
                            if ( !NA->ocs ) {
                                   oc[i] = myop[0]->getValue( OCS_COLUMN, ocbuf[i] );
                                   if ( !oc[i] ) {
                                          return LDAP_OTHER;
                                   }
                            }
                     }
                     if ( NA->txn->execute(NdbTransaction::NoCommit, NdbOperation::AO_IgnoreError, 1) < 0 ) {
                            return LDAP_OTHER;
                     }
                     for ( --i; i>=0; i-- ) {
                            if ( myop[i]->getNdbError().code == 0 ) {
                                   for ( j=0; j<=i; j++ )
                                          matched->bv_len += NA->rdns->nr_buf[j][0];
                                   NA->erdns = NA->rdns->nr_num;
                                   NA->rdns->nr_num = j;
                                   matched->bv_len += i;
                                   matched->bv_val = NA->e->e_name.bv_val +
                                          NA->e->e_name.bv_len - matched->bv_len;
                                   if ( !eid[i]->isNULL() )
                                          NA->e->e_id = eid[i]->u_64_value();
                                   if ( !NA->ocs )
                                          NA->ocs = ndb_ref2oclist( ocbuf[i], op->o_tmpmemctx );
                                   break;
                            }
                     }
              }
              return LDAP_NO_SUCH_OBJECT;
       default:
              return LDAP_OTHER;
       }

       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int ndb_entry_put_data ( BackendDB be,
NdbArgs NA 
)

Definition at line 716 of file ndbio.cpp.

{
       struct ndb_info *ni = (struct ndb_info *) be->be_private;
       Attribute *aoc;
       const NdbDictionary::Dictionary *myDict = NA->ndb->getDictionary();
       NdbOcs myOcs;
       int i, rc;

       /* Get the entry's objectClass attribute */
       aoc = attr_find( NA->e->e_attrs, slap_schema.si_ad_objectClass );
       if ( !aoc )
              return LDAP_OTHER;

       ndb_oc_check( be, NA->ndb, aoc->a_nvals, &myOcs );
       myOcs.no_info[myOcs.no_ninfo++] = ni->ni_opattrs;

       /* Walk thru objectclasses, find all the attributes belonging to a class */
       for ( i=0; i<myOcs.no_ninfo; i++ ) {
              rc = ndb_oc_put( myDict, NA->txn, myOcs.no_info[i], NA->e );
              if ( rc ) return rc;
       }

       /* slapadd tries to batch multiple entries per txn, but entry data is
        * transient and blob data is required to remain valid for the whole txn.
        * So we need to flush blobs before their source data disappears.
        */
       if (( slapMode & SLAP_TOOL_MODE ) && ndb_flush_blobs )
              NA->txn->execute( NdbTransaction::NoCommit );

       return 0;
}

Here is the call graph for this function:

int ndb_entry_put_info ( BackendDB be,
NdbArgs NA,
int  update 
)

Definition at line 1140 of file ndbio.cpp.

{
       struct ndb_info *ni = (struct ndb_info *) be->be_private;
       const NdbDictionary::Dictionary *myDict = NA->ndb->getDictionary();
       const NdbDictionary::Table *myTable = myDict->getTable( DN2ID_TABLE );
       NdbOperation *myop;
       NdbAttrInfo *ai;
       Attribute *aoc, *a;

       /* Get the entry's objectClass attribute; it's ok to be
        * absent on a fresh insert
        */
       aoc = attr_find( NA->e->e_attrs, slap_schema.si_ad_objectClass );
       if ( update && !aoc )
              return LDAP_OBJECT_CLASS_VIOLATION;

       myop = NA->txn->getNdbOperation( myTable );
       if ( !myop )
              return LDAP_OTHER;
       if ( update ) {
              if ( myop->updateTuple())
                     return LDAP_OTHER;
       } else {
              if ( myop->insertTuple())
                     return LDAP_OTHER;
       }

       if ( ndb_rdns2keys( myop, NA->rdns ))
              return LDAP_OTHER;

       /* Set entry ID */
       {
              Uint64 eid = NA->e->e_id;
              if ( myop->setValue( EID_COLUMN, eid ))
                     return LDAP_OTHER;
       }

       /* Set list of objectClasses */
       /* List is <sp> <class> <sp> <class> <sp> ... so that
        * searches for " class " will yield accurate results
        */
       if ( aoc ) {
              char *ptr, buf[sizeof(MedVar)];
              NdbOcs myOcs;
              int i;

              ndb_oc_check( be, NA->ndb, aoc->a_nvals, &myOcs );
              ptr = buf+2;
              *ptr++ = ' ';
              for ( i=0; i<myOcs.no_ntext; i++ ) {
                     /* data loss... */
                     if ( ptr + myOcs.no_text[i].bv_len + 1 >= &buf[sizeof(buf)] )
                            break;
                     ptr = lutil_strcopy( ptr, myOcs.no_text[i].bv_val );
                     *ptr++ = ' ';
              }

              /* implicit classes */
              if ( myOcs.no_nitext ) {
                     *ptr++ = '@';
                     *ptr++ = ' ';
                     for ( i=0; i<myOcs.no_nitext; i++ ) {
                            /* data loss... */
                            if ( ptr + myOcs.no_itext[i].bv_len + 1 >= &buf[sizeof(buf)] )
                                   break;
                            ptr = lutil_strcopy( ptr, myOcs.no_itext[i].bv_val );
                            *ptr++ = ' ';
                     }
              }

              i = ptr - buf - 2;
              buf[0] = i & 0xff;
              buf[1] = i >> 8;
              if ( myop->setValue( OCS_COLUMN, buf ))
                     return LDAP_OTHER;
       }

       /* Set any indexed attrs */
       for ( a = NA->e->e_attrs; a; a=a->a_next ) {
              ai = ndb_ai_find( ni, a->a_desc->ad_type );
              if ( ai && ( ai->na_flag & NDB_INFO_INDEX )) {
                     char *ptr, buf[sizeof(MedVar)];
                     int len;

                     ptr = buf+1;
                     len = a->a_vals[0].bv_len;
                     /* FIXME: data loss */
                     if ( len > ai->na_len )
                            len = ai->na_len;
                     buf[0] = len & 0xff;
                     if ( ai->na_len > 255 ) {
                            *ptr++ = len >> 8;
                     }
                     memcpy( ptr, a->a_vals[0].bv_val, len );
                     if ( myop->setValue( ai->na_ixcol, buf ))
                            return LDAP_OTHER;
              }
       }

       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int ndb_name_cmp ( const void v1,
const void v2 
) [static]

Definition at line 42 of file ndbio.cpp.

{
       NdbOcInfo *oc1 = (NdbOcInfo *)v1, *oc2 = (NdbOcInfo *)v2;
       return ber_bvstrcasecmp( &oc1->no_name, &oc2->no_name );
}

Here is the caller graph for this function:

int ndb_next_id ( BackendDB be,
Ndb *  ndb,
ID id 
)

Definition at line 1478 of file ndbio.cpp.

{
       struct ndb_info *ni = (struct ndb_info *) be->be_private;
       const NdbDictionary::Dictionary *myDict = ndb->getDictionary();
       const NdbDictionary::Table *myTable = myDict->getTable( NEXTID_TABLE );
       Uint64 nid = 0;
       int rc;

       if ( !myTable ) {
              Debug( LDAP_DEBUG_ANY, "ndb_next_id: " NEXTID_TABLE " table is missing\n",
                     0, 0, 0 );
              return LDAP_OTHER;
       }

       rc = ndb->getAutoIncrementValue( myTable, nid, 1000 );
       if ( !rc )
              *id = nid;
       return rc;
}

Here is the caller graph for this function:

int ndb_oc_attrs ( NdbTransaction *  txn,
const NdbDictionary::Table *  myTable,
Entry e,
NdbOcInfo no,
NdbAttrInfo **  attrs,
int  nattrs,
Attribute old 
)

Definition at line 536 of file ndbio.cpp.

{
       char buf[65538], *ptr;
       Attribute **an, **ao, *a;
       NdbOperation *myop;
       int i, j, max = 0;
       int changed, rc;
       Uint64 eid = e->e_id;

       if ( !nattrs )
              return 0;

       an = (Attribute **)ch_malloc( 2 * nattrs * sizeof(Attribute *));
       ao = an + nattrs;

       /* Turn lists of attrs into arrays for easier access */
       for ( i=0; i<nattrs; i++ ) {
              if ( attrs[i]->na_oi != no ) {
                     an[i] = NULL;
                     ao[i] = NULL;
                     continue;
              }
              for ( a=e->e_attrs; a; a=a->a_next ) {
                     if ( a->a_desc == slap_schema.si_ad_objectClass )
                            continue;
                     if ( a->a_desc->ad_type == attrs[i]->na_attr ) {
                            /* Don't process same attr twice */
                            if ( a->a_flags & SLAP_ATTR_IXADD )
                                   a = NULL;
                            else
                                   a->a_flags |= SLAP_ATTR_IXADD;
                            break;
                     }
              }
              an[i] = a;
              if ( a && a->a_numvals > max )
                     max = a->a_numvals;
              for ( a=old; a; a=a->a_next ) {
                     if ( a->a_desc == slap_schema.si_ad_objectClass )
                            continue;
                     if ( a->a_desc->ad_type == attrs[i]->na_attr )
                            break;
              }
              ao[i] = a;
              if ( a && a->a_numvals > max )
                     max = a->a_numvals;
       }

       for ( i=0; i<max; i++ ) {
              myop = NULL;
              for ( j=0; j<nattrs; j++ ) {
                     if ( !an[j] && !ao[j] )
                            continue;
                     changed = 0;
                     if ( an[j] && an[j]->a_numvals > i ) {
                            /* both old and new are present, compare for changes */
                            if ( ao[j] && ao[j]->a_numvals > i ) {
                                   if ( ber_bvcmp( &ao[j]->a_nvals[i], &an[j]->a_nvals[i] ))
                                          changed = V_REP;
                            } else {
                                   changed = V_INS;
                            }
                     } else {
                            if ( ao[j] && ao[j]->a_numvals > i )
                                   changed = V_DEL;
                     }
                     if ( changed ) {
                            if ( !myop ) {
                                   rc = LDAP_OTHER;
                                   myop = txn->getNdbOperation( myTable );
                                   if ( !myop ) {
                                          goto done;
                                   }
                                   if ( old ) {
                                          if ( myop->writeTuple()) {
                                                 goto done;
                                          }
                                   } else {
                                          if ( myop->insertTuple()) {
                                                 goto done;
                                          }
                                   }
                                   if ( myop->equal( EID_COLUMN, eid )) {
                                          goto done;
                                   }
                                   if ( myop->equal( VID_COLUMN, i )) {
                                          goto done;
                                   }
                            }
                            if ( attrs[j]->na_flag & NDB_INFO_ATBLOB ) {
                                   NdbBlob *myBlob = myop->getBlobHandle( attrs[j]->na_column );
                                   rc = LDAP_OTHER;
                                   if ( !myBlob ) {
                                          Debug( LDAP_DEBUG_TRACE, "ndb_oc_attrs: getBlobHandle failed %s (%d)\n",
                                                 myop->getNdbError().message, myop->getNdbError().code, 0 );
                                          goto done;
                                   }
                                   if ( slapMode & SLAP_TOOL_MODE )
                                          ndb_flush_blobs = 1;
                                   if ( changed & V_INS ) {
                                          if ( myBlob->setValue( an[j]->a_vals[i].bv_val, an[j]->a_vals[i].bv_len )) {
                                                 Debug( LDAP_DEBUG_TRACE, "ndb_oc_attrs: blob->setValue failed %s (%d)\n",
                                                        myBlob->getNdbError().message, myBlob->getNdbError().code, 0 );
                                                 goto done;
                                          }
                                   } else {
                                          if ( myBlob->setValue( NULL, 0 )) {
                                                 Debug( LDAP_DEBUG_TRACE, "ndb_oc_attrs: blob->setValue failed %s (%d)\n",
                                                        myBlob->getNdbError().message, myBlob->getNdbError().code, 0 );
                                                 goto done;
                                          }
                                   }
                            } else {
                                   if ( changed & V_INS ) {
                                          if ( an[j]->a_vals[i].bv_len > attrs[j]->na_len ) {
                                                 Debug( LDAP_DEBUG_ANY, "ndb_oc_attrs: attribute %s too long for column\n",
                                                        attrs[j]->na_name.bv_val, 0, 0 );
                                                 rc = LDAP_CONSTRAINT_VIOLATION;
                                                 goto done;
                                          }
                                          ptr = buf;
                                          *ptr++ = an[j]->a_vals[i].bv_len & 0xff;
                                          if ( attrs[j]->na_len > 255 ) {
                                                 /* MedVar */
                                                 *ptr++ = an[j]->a_vals[i].bv_len >> 8;
                                          }
                                          memcpy( ptr, an[j]->a_vals[i].bv_val, an[j]->a_vals[i].bv_len );
                                          ptr = buf;
                                   } else {
                                          ptr = NULL;
                                   }
                                   if ( myop->setValue( attrs[j]->na_column, ptr )) {
                                          rc = LDAP_OTHER;
                                          goto done;
                                   }
                            }
                     }
              }
       }
       rc = LDAP_SUCCESS;
done:
       ch_free( an );
       if ( rc ) {
              Debug( LDAP_DEBUG_TRACE, "ndb_oc_attrs: failed %s (%d)\n",
                     myop->getNdbError().message, myop->getNdbError().code, 0 );
       }
       return rc;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int ndb_oc_check ( BackendDB be,
Ndb *  ndb,
struct berval ocsin,
NdbOcs out 
) [static]

Definition at line 502 of file ndbio.cpp.

{
       struct ndb_info *ni = (struct ndb_info *) be->be_private;
       const NdbDictionary::Dictionary *myDict = ndb->getDictionary();

       int i, rc = 0;

       out->no_ninfo = 0;
       out->no_ntext = 0;
       out->no_nitext = 0;

       /* Find all objectclasses and their superiors. List
        * the superiors first.
        */

       ldap_pvt_thread_rdwr_rlock( &ni->ni_oc_rwlock );
       for ( i=0; !BER_BVISNULL( &ocsin[i] ); i++ ) {
              rc = ndb_oc_list( ni, myDict, &ocsin[i], 0, out );
              if ( rc ) break;
       }
       ldap_pvt_thread_rdwr_runlock( &ni->ni_oc_rwlock );
       return rc;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int ndb_oc_create ( struct ndb_info ni,
NdbOcInfo oci,
int  create 
) [static]

Definition at line 191 of file ndbio.cpp.

{
       char buf[4096], *ptr;
       int i, rc = 0, col;

       if ( create ) {
              ptr = buf + sprintf( buf,
                     "CREATE TABLE `%s` (eid bigint unsigned NOT NULL, vid int unsigned NOT NULL",
                     oci->no_table.bv_val );
       }

       col = 0;
       if ( oci->no_oc->soc_required ) {
              for ( i=0; oci->no_oc->soc_required[i]; i++ );
              col += i;
       }
       if ( oci->no_oc->soc_allowed ) {
              for ( i=0; oci->no_oc->soc_allowed[i]; i++ );
              col += i;
       }
       /* assume all are present */
       oci->no_attrs = (struct ndb_attrinfo **)ch_malloc( col * sizeof(struct ndb_attrinfo *));

       col = 2;
       ldap_pvt_thread_rdwr_wlock( &ni->ni_ai_rwlock );
       if ( oci->no_oc->soc_required ) {
              rc = ndb_ai_check( ni, oci, oci->no_oc->soc_required, &ptr, &col, create );
       }
       if ( !rc && oci->no_oc->soc_allowed ) {
              rc = ndb_ai_check( ni, oci, oci->no_oc->soc_allowed, &ptr, &col, create );
       }
       ldap_pvt_thread_rdwr_wunlock( &ni->ni_ai_rwlock );

       /* shrink down to just the needed size */
       oci->no_attrs = (struct ndb_attrinfo **)ch_realloc( oci->no_attrs,
              oci->no_nattrs * sizeof(struct ndb_attrinfo *));

       if ( create ) {
              ptr = lutil_strcopy( ptr, ", PRIMARY KEY(eid, vid) ) ENGINE=ndb PARTITION BY KEY(eid)" );
              rc = mysql_real_query( &ni->ni_sql, buf, ptr - buf );
              if ( rc ) {
                     Debug( LDAP_DEBUG_ANY,
                            "ndb_oc_create: CREATE TABLE %s failed, %s (%d)\n",
                            oci->no_table.bv_val, mysql_error(&ni->ni_sql), mysql_errno(&ni->ni_sql) );
              }
       }
       return rc;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int ndb_oc_del ( NdbTransaction *  txn,
Uint64  eid,
NdbOcInfo no 
) [static]

Definition at line 1027 of file ndbio.cpp.

{
       NdbIndexScanOperation *myop;
       int i, rc;

       for ( i=0; i<no->no_nsets; i++ ) {
              rc = ndb_oc_del( txn, eid, no->no_sets[i] );
              if ( rc ) return rc;
       }

       myop = txn->getNdbIndexScanOperation( "PRIMARY", no->no_table.bv_val );
       if ( !myop )
              return LDAP_OTHER;
       if ( myop->readTuples( NdbOperation::LM_Exclusive ))
              return LDAP_OTHER;
       if ( myop->setBound( 0U, NdbIndexScanOperation::BoundEQ, &eid ))
              return LDAP_OTHER;

       txn->execute(NoCommit);
       while ( myop->nextResult(true) == 0) {
              do {
                     myop->deleteCurrentTuple();
              } while (myop->nextResult(false) == 0);
              txn->execute(NoCommit);
       }

       return 0;
}

Here is the caller graph for this function:

static int ndb_oc_dup_err ( void v1,
void v2 
) [static]

Definition at line 49 of file ndbio.cpp.

{
       NdbOcInfo *oc = (NdbOcInfo *)v2;

       oc->no_oc = (ObjectClass *)v1;
       return -1;
}

Here is the caller graph for this function:

static void ndb_oc_get ( Operation op,
NdbOcInfo no,
int j,
int nocs,
NdbOcInfo ***  oclist 
) [static]

Definition at line 752 of file ndbio.cpp.

{
       int i;
       NdbOcInfo  **ol2;

       for ( i=0; i<no->no_nsets; i++ ) {
              ndb_oc_get( op, no->no_sets[i], j, nocs, oclist );
       }

       /* Don't insert twice */
       ol2 = *oclist;
       for ( i=0; i<*j; i++ )
              if ( ol2[i] == no )
                     return;

       if ( *j >= *nocs ) {
              *nocs *= 2;
              ol2 = (NdbOcInfo **)op->o_tmprealloc( *oclist, *nocs * sizeof(NdbOcInfo *), op->o_tmpmemctx );
              *oclist = ol2;
       }
       ol2 = *oclist;
       ol2[(*j)++] = no;
}

Here is the caller graph for this function:

static int ndb_oc_list ( struct ndb_info ni,
const NdbDictionary::Dictionary *  myDict,
struct berval oname,
int  implied,
NdbOcs out 
) [static]

Definition at line 339 of file ndbio.cpp.

{
       const NdbDictionary::Table *myTable;
       NdbOcInfo *oci, octmp;
       ObjectClass *oc;
       int i, rc;

       /* shortcut top */
       if ( ber_bvstrcasecmp( oname, &slap_schema.si_oc_top->soc_cname )) {
              octmp.no_name = *oname;
              oci = (NdbOcInfo *)avl_find( ni->ni_oc_tree, &octmp, ndb_name_cmp );
              if ( oci ) {
                     oc = oci->no_oc;
              } else {
                     oc = oc_bvfind( oname );
                     if ( !oc ) {
                            /* undefined - shouldn't happen */
                            return LDAP_INVALID_SYNTAX;
                     }
              }
              if ( oc->soc_sups ) {
                     int i;

                     for ( i=0; oc->soc_sups[i]; i++ ) {
                            rc = ndb_oc_list( ni, myDict, &oc->soc_sups[i]->soc_cname, 1, out );
                            if ( rc ) return rc;
                     }
              }
       } else {
              oc = slap_schema.si_oc_top;
       }
       /* Only insert once */
       for ( i=0; i<out->no_ntext; i++ )
              if ( out->no_text[i].bv_val == oc->soc_cname.bv_val )
                     break;
       if ( i == out->no_ntext ) {
              for ( i=0; i<out->no_nitext; i++ )
                     if ( out->no_itext[i].bv_val == oc->soc_cname.bv_val )
                            break;
              if ( i == out->no_nitext ) {
                     if ( implied )
                            out->no_itext[out->no_nitext++] = oc->soc_cname;
                     else
                            out->no_text[out->no_ntext++] = oc->soc_cname;
              }
       }

       /* ignore top, etc... */
       if ( oc->soc_kind == LDAP_SCHEMA_ABSTRACT )
              return 0;

       if ( !oci ) {
              ldap_pvt_thread_rdwr_runlock( &ni->ni_oc_rwlock );
              oci = (NdbOcInfo *)ch_malloc( sizeof( NdbOcInfo )+oc->soc_cname.bv_len+1 );
              oci->no_table.bv_val = (char *)(oci+1);
              strcpy( oci->no_table.bv_val, oc->soc_cname.bv_val );
              oci->no_table.bv_len = oc->soc_cname.bv_len;
              oci->no_name = oci->no_table;
              oci->no_oc = oc;
              oci->no_flag = 0;
              oci->no_nsets = 0;
              oci->no_nattrs = 0;
              ldap_pvt_thread_rdwr_wlock( &ni->ni_oc_rwlock );
              if ( avl_insert( &ni->ni_oc_tree, oci, ndb_name_cmp, ndb_oc_dup_err )) {
                     octmp.no_oc = oci->no_oc;
                     ch_free( oci );
                     oci = (NdbOcInfo *)octmp.no_oc;
              }
              /* see if the oc table already exists in the DB */
              myTable = myDict->getTable( oci->no_table.bv_val );
              rc = ndb_oc_create( ni, oci, myTable == NULL );
              ldap_pvt_thread_rdwr_wunlock( &ni->ni_oc_rwlock );
              ldap_pvt_thread_rdwr_rlock( &ni->ni_oc_rwlock );
              if ( rc ) return rc;
       }
       /* Only insert once */
       for ( i=0; i<out->no_ninfo; i++ )
              if ( out->no_info[i] == oci )
                     break;
       if ( i == out->no_ninfo )
              out->no_info[out->no_ninfo++] = oci;
       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int ndb_oc_put ( const NdbDictionary::Dictionary *  myDict,
NdbTransaction *  txn,
NdbOcInfo no,
Entry e 
) [static]

Definition at line 694 of file ndbio.cpp.

{
       const NdbDictionary::Table *myTable;
       int i, rc;

       for ( i=0; i<no->no_nsets; i++ ) {
              rc = ndb_oc_put( myDict, txn, no->no_sets[i], e );
              if ( rc )
                     return rc;
       }

       myTable = myDict->getTable( no->no_table.bv_val );
       if ( !myTable )
              return LDAP_OTHER;

       return ndb_oc_attrs( txn, myTable, e, no, no->no_attrs, no->no_nattrs, NULL );
}

Here is the call graph for this function:

Here is the caller graph for this function:

int ndb_oc_read ( struct ndb_info ni,
const NdbDictionary::Dictionary *  myDict 
)

Definition at line 242 of file ndbio.cpp.

{
       const NdbDictionary::Table *myTable;
       const NdbDictionary::Column *myCol;
       NdbOcInfo *oci, octmp;
       NdbAttrInfo *ai;
       ObjectClass *oc;
       NdbDictionary::Dictionary::List myList;
       struct berval bv;
       int i, j, rc, col;

       rc = myDict->listObjects( myList, NdbDictionary::Object::UserTable );
       /* Populate our objectClass structures */
       for ( i=0; i<myList.count; i++ ) {
              /* Ignore other DBs */
              if ( strcmp( myList.elements[i].database, ni->ni_dbname ))
                     continue;
              /* Ignore internal tables */
              if ( !strncmp( myList.elements[i].name, "OL_", 3 ))
                     continue;
              ber_str2bv( myList.elements[i].name, 0, 0, &octmp.no_name );
              oci = (NdbOcInfo *)avl_find( ni->ni_oc_tree, &octmp, ndb_name_cmp );
              if ( oci )
                     continue;

              oc = oc_bvfind( &octmp.no_name );
              if ( !oc ) {
                     /* undefined - shouldn't happen */
                     continue;
              }
              myTable = myDict->getTable( myList.elements[i].name );
              oci = (NdbOcInfo *)ch_malloc( sizeof( NdbOcInfo )+oc->soc_cname.bv_len+1 );
              oci->no_table.bv_val = (char *)(oci+1);
              strcpy( oci->no_table.bv_val, oc->soc_cname.bv_val );
              oci->no_table.bv_len = oc->soc_cname.bv_len;
              oci->no_name = oci->no_table;
              oci->no_oc = oc;
              oci->no_flag = 0;
              oci->no_nsets = 0;
              oci->no_nattrs = 0;
              col = 0;
              /* Make space for all attrs, even tho sups will be dropped */
              if ( oci->no_oc->soc_required ) {
                     for ( j=0; oci->no_oc->soc_required[j]; j++ );
                     col = j;
              }
              if ( oci->no_oc->soc_allowed ) {
                     for ( j=0; oci->no_oc->soc_allowed[j]; j++ );
                     col += j;
              }
              oci->no_attrs = (struct ndb_attrinfo **)ch_malloc( col * sizeof(struct ndb_attrinfo *));
              avl_insert( &ni->ni_oc_tree, oci, ndb_name_cmp, avl_dup_error );

              col = myTable->getNoOfColumns();
              /* Skip 0 and 1, eid and vid */
              for ( j = 2; j<col; j++ ) {
                     myCol = myTable->getColumn( j );
                     ber_str2bv( myCol->getName(), 0, 0, &bv );
                     ai = ndb_ai_get( ni, &bv );
                     /* shouldn't happen */
                     if ( !ai )
                            continue;
                     ai->na_oi = oci;
                     ai->na_column = j;
                     ai->na_len = myCol->getLength();
                     if ( myCol->getType() == NdbDictionary::Column::Blob )
                            ai->na_flag |= NDB_INFO_ATBLOB;
              }
       }
       /* Link to any attrsets */
       for ( i=0; i<myList.count; i++ ) {
              /* Ignore other DBs */
              if ( strcmp( myList.elements[i].database, ni->ni_dbname ))
                     continue;
              /* Ignore internal tables */
              if ( !strncmp( myList.elements[i].name, "OL_", 3 ))
                     continue;
              ber_str2bv( myList.elements[i].name, 0, 0, &octmp.no_name );
              oci = (NdbOcInfo *)avl_find( ni->ni_oc_tree, &octmp, ndb_name_cmp );
              /* shouldn't happen */
              if ( !oci )
                     continue;
              col = 2;
              if ( oci->no_oc->soc_required ) {
                     rc = ndb_ai_check( ni, oci, oci->no_oc->soc_required, NULL, &col, 0 );
              }
              if ( oci->no_oc->soc_allowed ) {
                     rc = ndb_ai_check( ni, oci, oci->no_oc->soc_allowed, NULL, &col, 0 );
              }
              /* shrink down to just the needed size */
              oci->no_attrs = (struct ndb_attrinfo **)ch_realloc( oci->no_attrs,
                     oci->no_nattrs * sizeof(struct ndb_attrinfo *));
       }
       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int ndb_rdns2keys ( NdbOperation *  myop,
NdbRdns rdns 
) [static]

Definition at line 1118 of file ndbio.cpp.

{
       int i;
       char dummy[2] = {0,0};

       /* Walk thru RDNs */
       for ( i=0; i<rdns->nr_num; i++ ) {
              if ( myop->equal( i+RDN_COLUMN, rdns->nr_buf[i] ))
                     return LDAP_OTHER;
       }
       for ( ; i<NDB_MAX_RDNS; i++ ) {
              if ( myop->equal( i+RDN_COLUMN, dummy ))
                     return LDAP_OTHER;
       }
       return 0;
}

Here is the caller graph for this function:

struct berval* ndb_ref2oclist ( const char *  ref,
void ctx 
) [read]

Definition at line 1298 of file ndbio.cpp.

{
       char *implied;

       /* MedVar */
       int len = ref[0] | (ref[1] << 8);

       /* don't return the implied classes */
       implied = (char *)memchr( ref+2, '@', len );
       if ( implied ) {
              len = implied - ref - 2;
              *implied = '\0';
       }

       return ndb_str2bvarray( (char *)ref+2, len, ' ', ctx );
}

Here is the call graph for this function:

Here is the caller graph for this function:

struct berval* ndb_str2bvarray ( char *  str,
int  len,
char  delim,
void ctx 
) [read]

Definition at line 1247 of file ndbio.cpp.

{
       struct berval *list, tmp;
       char *beg;
       int i, num;

       while ( *str == delim ) {
              str++;
              len--;
       }

       while ( str[len-1] == delim ) {
              str[--len] = '\0';
       }

       for ( i = 1, beg = str;; i++ ) {
              beg = strchr( beg, delim );
              if ( !beg )
                     break;
              if ( beg >= str + len )
                     break;
              beg++;
       }

       num = i;
       list = (struct berval *)slap_sl_malloc( (num+1)*sizeof(struct berval), ctx);

       for ( i = 0, beg = str; i<num; i++ ) {
              tmp.bv_val = beg;
              beg = strchr( beg, delim );
              if ( beg >= str + len )
                     beg = NULL;
              if ( beg ) {
                     tmp.bv_len = beg - tmp.bv_val;
              } else {
                     tmp.bv_len = len - (tmp.bv_val - str);
              }
              ber_dupbv_x( &list[i], &tmp, ctx );
              beg++;
       }

       BER_BVZERO( &list[i] );
       return list;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int ndb_thread_handle ( Operation op,
Ndb **  ndb 
)

Definition at line 1511 of file ndbio.cpp.

{
       struct ndb_info *ni = (struct ndb_info *) op->o_bd->be_private;
       void *data;

       if ( ldap_pvt_thread_pool_getkey( op->o_threadctx, ni, &data, NULL )) {
              Ndb *myNdb;
              int rc;
              ldap_pvt_thread_mutex_lock( &ni->ni_conn_mutex );
              myNdb = new Ndb( ni->ni_cluster[ni->ni_nextconn++], ni->ni_dbname );
              if ( ni->ni_nextconn >= ni->ni_nconns )
                     ni->ni_nextconn = 0;
              ldap_pvt_thread_mutex_unlock( &ni->ni_conn_mutex );
              if ( !myNdb ) {
                     return LDAP_OTHER;
              }
              rc = myNdb->init(1024);
              if ( rc ) {
                     delete myNdb;
                     Debug( LDAP_DEBUG_ANY, "ndb_thread_handle: err %d\n",
                            rc, 0, 0 );
                     return rc;
              }
              data = (void *)myNdb;
              if (( rc = ldap_pvt_thread_pool_setkey( op->o_threadctx, ni,
                     data, ndb_thread_hfree, NULL, NULL ))) {
                     delete myNdb;
                     Debug( LDAP_DEBUG_ANY, "ndb_thread_handle: err %d\n",
                            rc, 0, 0 );
                     return rc;
              }
       }
       *ndb = (Ndb *)data;
       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void ndb_thread_hfree ( void key,
void data 
) [static]

Definition at line 1504 of file ndbio.cpp.

{
       Ndb *ndb = (Ndb *)data;
       delete ndb;
}

Here is the caller graph for this function:

void ndb_trans_backoff ( int  num_retries)

Definition at line 1613 of file ndbio.cpp.

{
       int i;
       int delay = 0;
       int pow_retries = 1;
       unsigned long key = 0;
       unsigned long max_key = -1;
       struct timeval timeout;

       lutil_entropy( (unsigned char *) &key, sizeof( unsigned long ));

       for ( i = 0; i < num_retries; i++ ) {
              if ( i >= 5 ) break;
              pow_retries *= 4;
       }

       delay = 16384 * (key * (double) pow_retries / (double) max_key);
       delay = delay ? delay : 1;

       Debug( LDAP_DEBUG_TRACE,  "delay = %d, num_retries = %d\n", delay, num_retries, 0 );

       timeout.tv_sec = delay / 1000000;
       timeout.tv_usec = delay % 1000000;
       select( 0, NULL, NULL, NULL, &timeout );
}

Here is the call graph for this function:


Variable Documentation

int ndb_flush_blobs [static]

Definition at line 531 of file ndbio.cpp.