/* Read table definitions from the DB and populate ObjectClassInfo */ extern "C" int ndb_oc_read( struct ndb_info *ni, const NdbDictionary::Dictionary *myDict ) { 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; }
static int ndb_cf_gen( ConfigArgs *c ) { struct ndb_info *ni = (struct ndb_info *)c->be->be_private; int i, rc; NdbAttrInfo *ai; NdbOcInfo *oci; ListNode *ln, **l2; struct berval bv, *bva; if ( c->op == SLAP_CONFIG_EMIT ) { char buf[BUFSIZ]; rc = 0; bv.bv_val = buf; switch( c->type ) { case NDB_ATLEN: if ( ni->ni_attrlens ) { for ( ln = ni->ni_attrlens; ln; ln=ln->ln_next ) { ai = (NdbAttrInfo *)ln->ln_data; bv.bv_len = snprintf( buf, sizeof(buf), "%s %d", ai->na_name.bv_val, ai->na_len ); value_add_one( &c->rvalue_vals, &bv ); } } else { rc = 1; } break; case NDB_ATSET: if ( ni->ni_attrsets ) { char *ptr, *end = buf+sizeof(buf); for ( ln = ni->ni_attrsets; ln; ln=ln->ln_next ) { oci = (NdbOcInfo *)ln->ln_data; ptr = lutil_strcopy( buf, oci->no_name.bv_val ); *ptr++ = ' '; for ( i=0; i<oci->no_nattrs; i++ ) { if ( end - ptr < oci->no_attrs[i]->na_name.bv_len+1 ) break; if ( i ) *ptr++ = ','; ptr = lutil_strcopy(ptr, oci->no_attrs[i]->na_name.bv_val ); } bv.bv_len = ptr - buf; value_add_one( &c->rvalue_vals, &bv ); } } else { rc = 1; } break; case NDB_INDEX: if ( ni->ni_attridxs ) { for ( ln = ni->ni_attridxs; ln; ln=ln->ln_next ) { ai = (NdbAttrInfo *)ln->ln_data; value_add_one( &c->rvalue_vals, &ai->na_name ); } } else { rc = 1; } break; case NDB_ATBLOB: if ( ni->ni_attrblobs ) { for ( ln = ni->ni_attrblobs; ln; ln=ln->ln_next ) { ai = (NdbAttrInfo *)ln->ln_data; value_add_one( &c->rvalue_vals, &ai->na_name ); } } else { rc = 1; } break; } return rc; } else if ( c->op == LDAP_MOD_DELETE ) { /* FIXME */ rc = 0; switch( c->type ) { case NDB_INDEX: if ( c->valx == -1 ) { /* delete all */ } else { } break; } return rc; } switch( c->type ) { case NDB_ATLEN: ber_str2bv( c->argv[1], 0, 0, &bv ); ai = ndb_ai_get( ni, &bv ); if ( !ai ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: invalid attr %s", c->log, c->argv[1] ); Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 ); return -1; } for ( ln = ni->ni_attrlens; ln; ln = ln->ln_next ) { if ( ln->ln_data == (void *)ai ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: attr len already set for %s", c->log, c->argv[1] ); Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 ); return -1; } } ai->na_len = atoi( c->argv[2] ); ai->na_flag |= NDB_INFO_ATLEN; ln = (ListNode *)ch_malloc( sizeof(ListNode)); ln->ln_data = ai; ln->ln_next = NULL; for ( l2 = &ni->ni_attrlens; *l2; l2 = &(*l2)->ln_next ); *l2 = ln; break; case NDB_INDEX: ber_str2bv( c->argv[1], 0, 0, &bv ); ai = ndb_ai_get( ni, &bv ); if ( !ai ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: invalid attr %s", c->log, c->argv[1] ); Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 ); return -1; } for ( ln = ni->ni_attridxs; ln; ln = ln->ln_next ) { if ( ln->ln_data == (void *)ai ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: attr index already set for %s", c->log, c->argv[1] ); Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 ); return -1; } } ai->na_flag |= NDB_INFO_INDEX; ln = (ListNode *)ch_malloc( sizeof(ListNode)); ln->ln_data = ai; ln->ln_next = NULL; for ( l2 = &ni->ni_attridxs; *l2; l2 = &(*l2)->ln_next ); *l2 = ln; break; case NDB_ATSET: ber_str2bv( c->argv[1], 0, 0, &bv ); bva = ndb_str2bvarray( c->argv[2], strlen( c->argv[2] ), ',', NULL ); rc = ndb_aset_get( ni, &bv, bva, &oci ); ber_bvarray_free( bva ); if ( rc ) { if ( rc == LDAP_ALREADY_EXISTS ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: attrset %s already defined", c->log, c->argv[1] ); } else { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: invalid attrset %s (%d)", c->log, c->argv[1], rc ); } Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 ); return -1; } ln = (ListNode *)ch_malloc( sizeof(ListNode)); ln->ln_data = oci; ln->ln_next = NULL; for ( l2 = &ni->ni_attrsets; *l2; l2 = &(*l2)->ln_next ); *l2 = ln; break; case NDB_ATBLOB: ber_str2bv( c->argv[1], 0, 0, &bv ); ai = ndb_ai_get( ni, &bv ); if ( !ai ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: invalid attr %s", c->log, c->argv[1] ); Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 ); return -1; } for ( ln = ni->ni_attrblobs; ln; ln = ln->ln_next ) { if ( ln->ln_data == (void *)ai ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: attr blob already set for %s", c->log, c->argv[1] ); Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 ); return -1; } } ai->na_flag |= NDB_INFO_ATBLOB; ln = (ListNode *)ch_malloc( sizeof(ListNode)); ln->ln_data = ai; ln->ln_next = NULL; for ( l2 = &ni->ni_attrblobs; *l2; l2 = &(*l2)->ln_next ); *l2 = ln; break; } return 0; }
static int ndb_ai_check( struct ndb_info *ni, NdbOcInfo *oci, AttributeType **attrs, char **ptr, int *col, int create ) { 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; }