+struct backsql_attr_schema_info {
+ backsql_info *bas_bi;
+ SQLHDBC bas_dbh;
+ SQLHSTMT bas_sth;
+ unsigned long *bas_oc_id;
+ int bas_rc;
+};
+
+static int
+backsql_oc_get_attr_mapping( void *v_oc, void *v_bas )
+{
+ RETCODE rc;
+ BACKSQL_ROW_NTS at_row;
+ backsql_oc_map_rec *oc_map = (backsql_oc_map_rec *)v_oc;
+ backsql_at_map_rec *at_map;
+ struct backsql_attr_schema_info *bas = (struct backsql_attr_schema_info *)v_bas;
+
+ /* bas->bas_oc_id has been bound to bas->bas_sth */
+ *bas->bas_oc_id = oc_map->bom_id;
+
+ Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_attr_mapping(): "
+ "executing at_query\n"
+ " \"%s\"\n"
+ " for objectClass \"%s\"\n"
+ " with param oc_id=\"%lu\"\n",
+ bas->bas_bi->sql_at_query,
+ BACKSQL_OC_NAME( oc_map ),
+ *bas->bas_oc_id );
+
+ rc = SQLExecute( bas->bas_sth );
+ if ( rc != SQL_SUCCESS ) {
+ Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_attr_mapping(): "
+ "error executing at_query\n"
+ " \"%s\"\n"
+ " for objectClass \"%s\"\n"
+ " with param oc_id=\"%lu\"\n",
+ bas->bas_bi->sql_at_query,
+ BACKSQL_OC_NAME( oc_map ),
+ *bas->bas_oc_id );
+ backsql_PrintErrors( bas->bas_bi->sql_db_env,
+ bas->bas_dbh, bas->bas_sth, rc );
+ bas->bas_rc = LDAP_OTHER;
+ return BACKSQL_AVL_STOP;
+ }
+
+ backsql_BindRowAsStrings( bas->bas_sth, &at_row );
+ for ( ; rc = SQLFetch( bas->bas_sth ), BACKSQL_SUCCESS( rc ); ) {
+ const char *text = NULL;
+ char *next = NULL;
+ struct berval bv;
+ struct berbuf bb = BB_NULL;
+
+ Debug( LDAP_DEBUG_TRACE,
+ "attributeType:\n"
+ "\tname=\"%s\"\n"
+ "\tsel_expr=\"%s\"\n"
+ "\tfrom=\"%s\"\n",
+ at_row.cols[ 0 ], at_row.cols[ 1 ],
+ at_row.cols[ 2 ] );
+ Debug( LDAP_DEBUG_TRACE,
+ "\tjoin_where=\"%s\"\n"
+ "\tadd_proc=\"%s\"\n"
+ "\tdelete_proc=\"%s\"\n",
+ at_row.cols[ 3 ], at_row.cols[ 4 ],
+ at_row.cols[ 5 ]);
+ /* TimesTen */
+ Debug( LDAP_DEBUG_TRACE, "\tsel_expr_u=\"%s\"\n",
+ at_row.cols[ 8 ], 0, 0 );
+ at_map = (backsql_at_map_rec *)ch_calloc( 1,
+ sizeof( backsql_at_map_rec ) );
+ rc = slap_str2ad( at_row.cols[ 0 ],
+ &at_map->bam_ad, &text );
+ if ( rc != LDAP_SUCCESS ) {
+ Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_attr_mapping(): "
+ "attribute \"%s\" for objectClass \"%s\" "
+ "is not defined in schema: %s\n",
+ at_row.cols[ 0 ],
+ BACKSQL_OC_NAME( oc_map ), text );
+ bas->bas_rc = LDAP_CONSTRAINT_VIOLATION;
+ return BACKSQL_AVL_STOP;
+ }
+
+ ber_str2bv( at_row.cols[ 1 ], 0, 1, &at_map->bam_sel_expr );
+ if ( at_row.value_len[ 8 ] < 0 ) {
+ BER_BVZERO( &at_map->bam_sel_expr_u );
+
+ } else {
+ ber_str2bv( at_row.cols[ 8 ], 0, 1,
+ &at_map->bam_sel_expr_u );
+ }
+
+ ber_str2bv( at_row.cols[ 2 ], 0, 0, &bv );
+ backsql_merge_from_clause( bas->bas_bi, &bb, &bv );
+ at_map->bam_from_tbls = bb.bb_val;
+ if ( at_row.value_len[ 3 ] < 0 ) {
+ BER_BVZERO( &at_map->bam_join_where );
+
+ } else {
+ ber_str2bv( at_row.cols[ 3 ], 0, 1,
+ &at_map->bam_join_where );
+ }
+ at_map->bam_add_proc = NULL;
+ if ( at_row.value_len[ 4 ] > 0 ) {
+ at_map->bam_add_proc = ch_strdup( at_row.cols[4] );
+ }
+ at_map->bam_delete_proc = NULL;
+ if ( at_row.value_len[ 5 ] > 0 ) {
+ at_map->bam_delete_proc = ch_strdup( at_row.cols[ 5 ] );
+ }
+ at_map->bam_param_order = strtol( at_row.cols[ 6 ],
+ &next, 0 );
+ if ( next == at_row.cols[ 6 ] || next[0] != '\0' ) {
+ /* error */
+ }
+ at_map->bam_expect_return = strtol( at_row.cols[ 7 ],
+ &next, 0 );
+ if ( next == at_row.cols[ 7 ] || next[0] != '\0' ) {
+ /* error */
+ }
+ backsql_make_attr_query( bas->bas_bi, oc_map, at_map );
+ Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_attr_mapping(): "
+ "preconstructed query \"%s\"\n",
+ at_map->bam_query, 0, 0 );
+ at_map->bam_next = NULL;
+ if ( avl_insert( &oc_map->bom_attrs, at_map, backsql_cmp_attr, backsql_dup_attr ) == BACKSQL_DUPLICATE ) {
+ Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_attr_mapping(): "
+ "duplicate attribute \"%s\" "
+ "in objectClass \"%s\" map\n",
+ at_map->bam_ad->ad_cname.bv_val,
+ oc_map->bom_oc->soc_cname.bv_val, 0 );
+ }
+
+ if ( !BER_BVISNULL( &bas->bas_bi->sql_upper_func ) &&
+ BER_BVISNULL( &at_map->bam_sel_expr_u ) )
+ {
+ struct berbuf bb = BB_NULL;
+
+ backsql_strfcat( &bb, "bcbc",
+ &bas->bas_bi->sql_upper_func,
+ '(' /* ) */ ,
+ &at_map->bam_sel_expr,
+ /* ( */ ')' );
+ at_map->bam_sel_expr_u = bb.bb_val;
+ }
+ }
+ backsql_FreeRow( &at_row );
+ SQLFreeStmt( bas->bas_sth, SQL_CLOSE );
+
+ Debug( LDAP_DEBUG_TRACE, "backsql_load_schema_map(\"%s\"): "
+ "autoadding 'objectClass' and 'ref' mappings\n",
+ BACKSQL_OC_NAME( oc_map ), 0, 0 );
+
+ (void)backsql_add_sysmaps( bas->bas_bi, oc_map );
+
+ return BACKSQL_AVL_CONTINUE;
+}
+
+