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_db_open( BackendDB *be, ConfigReply *cr ) { struct ndb_info *ni = (struct ndb_info *) be->be_private; char sqlbuf[BUFSIZ], *ptr; int rc, i; if ( be->be_suffix == NULL ) { snprintf( cr->msg, sizeof( cr->msg ), "ndb_db_open: need suffix" ); Debug( LDAP_DEBUG_ANY, "%s\n", cr->msg, 0, 0 ); return -1; } Debug( LDAP_DEBUG_ARGS, LDAP_XSTRING(ndb_db_open) ": \"%s\"\n", be->be_suffix[0].bv_val, 0, 0 ); if ( ni->ni_nconns < 1 ) ni->ni_nconns = 1; ni->ni_cluster = (Ndb_cluster_connection **)ch_calloc( ni->ni_nconns, sizeof( Ndb_cluster_connection *)); for ( i=0; i<ni->ni_nconns; i++ ) { ni->ni_cluster[i] = new Ndb_cluster_connection( ni->ni_connectstr ); rc = ni->ni_cluster[i]->connect( 20, 5, 1 ); if ( rc ) { snprintf( cr->msg, sizeof( cr->msg ), "ndb_db_open: ni_cluster[%d]->connect failed (%d)", i, rc ); goto fail; } } for ( i=0; i<ni->ni_nconns; i++ ) { rc = ni->ni_cluster[i]->wait_until_ready( 30, 30 ); if ( rc ) { snprintf( cr->msg, sizeof( cr->msg ), "ndb_db_open: ni_cluster[%d]->wait failed (%d)", i, rc ); goto fail; } } mysql_init( &ni->ni_sql ); if ( !mysql_real_connect( &ni->ni_sql, ni->ni_hostname, ni->ni_username, ni->ni_password, "", ni->ni_port, ni->ni_socket, ni->ni_clflag )) { snprintf( cr->msg, sizeof( cr->msg ), "ndb_db_open: mysql_real_connect failed, %s (%d)", mysql_error(&ni->ni_sql), mysql_errno(&ni->ni_sql) ); rc = -1; goto fail; } sprintf( sqlbuf, "CREATE DATABASE IF NOT EXISTS %s", ni->ni_dbname ); rc = mysql_query( &ni->ni_sql, sqlbuf ); if ( rc ) { snprintf( cr->msg, sizeof( cr->msg ), "ndb_db_open: CREATE DATABASE %s failed, %s (%d)", ni->ni_dbname, mysql_error(&ni->ni_sql), mysql_errno(&ni->ni_sql) ); goto fail; } sprintf( sqlbuf, "USE %s", ni->ni_dbname ); rc = mysql_query( &ni->ni_sql, sqlbuf ); if ( rc ) { snprintf( cr->msg, sizeof( cr->msg ), "ndb_db_open: USE DATABASE %s failed, %s (%d)", ni->ni_dbname, mysql_error(&ni->ni_sql), mysql_errno(&ni->ni_sql) ); goto fail; } ptr = sqlbuf; ptr += sprintf( ptr, "CREATE TABLE IF NOT EXISTS " DN2ID_TABLE " (" "eid bigint unsigned NOT NULL, " "object_classes VARCHAR(1024) NOT NULL, " "a0 VARCHAR(128) NOT NULL DEFAULT '', " "a1 VARCHAR(128) NOT NULL DEFAULT '', " "a2 VARCHAR(128) NOT NULL DEFAULT '', " "a3 VARCHAR(128) NOT NULL DEFAULT '', " "a4 VARCHAR(128) NOT NULL DEFAULT '', " "a5 VARCHAR(128) NOT NULL DEFAULT '', " "a6 VARCHAR(128) NOT NULL DEFAULT '', " "a7 VARCHAR(128) NOT NULL DEFAULT '', " "a8 VARCHAR(128) NOT NULL DEFAULT '', " "a9 VARCHAR(128) NOT NULL DEFAULT '', " "a10 VARCHAR(128) NOT NULL DEFAULT '', " "a11 VARCHAR(128) NOT NULL DEFAULT '', " "a12 VARCHAR(128) NOT NULL DEFAULT '', " "a13 VARCHAR(128) NOT NULL DEFAULT '', " "a14 VARCHAR(128) NOT NULL DEFAULT '', " "a15 VARCHAR(128) NOT NULL DEFAULT '', " "PRIMARY KEY (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15), " "UNIQUE KEY eid (eid) USING HASH" ); /* Create index columns */ if ( ni->ni_attridxs ) { ListNode *ln; int newcol = 0; *ptr++ = ','; *ptr++ = ' '; for ( ln = ni->ni_attridxs; ln; ln=ln->ln_next ) { NdbAttrInfo *ai = (NdbAttrInfo *)ln->ln_data; ptr += sprintf( ptr, "`%s` VARCHAR(%d), ", ai->na_name.bv_val, ai->na_len ); } ptr = lutil_strcopy(ptr, "KEY " INDEX_NAME " (" ); for ( ln = ni->ni_attridxs; ln; ln=ln->ln_next ) { NdbAttrInfo *ai = (NdbAttrInfo *)ln->ln_data; if ( newcol ) *ptr++ = ','; *ptr++ = '`'; ptr = lutil_strcopy( ptr, ai->na_name.bv_val ); *ptr++ = '`'; ai->na_ixcol = newcol + 18; newcol++; } *ptr++ = ')'; } strcpy( ptr, ") ENGINE=ndb" ); rc = mysql_query( &ni->ni_sql, sqlbuf ); if ( rc ) { snprintf( cr->msg, sizeof( cr->msg ), "ndb_db_open: CREATE TABLE " DN2ID_TABLE " failed, %s (%d)", mysql_error(&ni->ni_sql), mysql_errno(&ni->ni_sql) ); goto fail; } rc = mysql_query( &ni->ni_sql, "CREATE TABLE IF NOT EXISTS " NEXTID_TABLE " (" "a bigint unsigned AUTO_INCREMENT PRIMARY KEY ) ENGINE=ndb" ); if ( rc ) { snprintf( cr->msg, sizeof( cr->msg ), "ndb_db_open: CREATE TABLE " NEXTID_TABLE " failed, %s (%d)", mysql_error(&ni->ni_sql), mysql_errno(&ni->ni_sql) ); goto fail; } { NdbOcInfo *oci; rc = ndb_aset_get( ni, &ndb_optable, ndb_opattrs, &oci ); if ( rc ) { snprintf( cr->msg, sizeof( cr->msg ), "ndb_db_open: ndb_aset_get( %s ) failed (%d)", ndb_optable.bv_val, rc ); goto fail; } for ( i=0; ndb_oplens[i] >= 0; i++ ) { if ( ndb_oplens[i] ) oci->no_attrs[i]->na_len = ndb_oplens[i]; } rc = ndb_aset_create( ni, oci ); if ( rc ) { snprintf( cr->msg, sizeof( cr->msg ), "ndb_db_open: ndb_aset_create( %s ) failed (%d)", ndb_optable.bv_val, rc ); goto fail; } ni->ni_opattrs = oci; } /* Create attribute sets */ { ListNode *ln; for ( ln = ni->ni_attrsets; ln; ln=ln->ln_next ) { NdbOcInfo *oci = (NdbOcInfo *)ln->ln_data; rc = ndb_aset_create( ni, oci ); if ( rc ) { snprintf( cr->msg, sizeof( cr->msg ), "ndb_db_open: ndb_aset_create( %s ) failed (%d)", oci->no_name.bv_val, rc ); goto fail; } } } /* Initialize any currently used objectClasses */ { Ndb *ndb; const NdbDictionary::Dictionary *myDict; ndb = new Ndb( ni->ni_cluster[0], ni->ni_dbname ); ndb->init(1024); myDict = ndb->getDictionary(); ndb_oc_read( ni, myDict ); delete ndb; } #ifdef DO_MONITORING /* monitor setup */ rc = ndb_monitor_db_open( be ); if ( rc != 0 ) { goto fail; } #endif return 0; fail: Debug( LDAP_DEBUG_ANY, "%s\n", cr->msg, 0, 0 ); ndb_db_close( be, NULL ); return rc; }