2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4 * Copyright 1999-2004 The OpenLDAP Foundation.
5 * Portions Copyright 1999 Dmitry Kovalev.
6 * Portions Copyright 2004 Mark Adamson.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted only as authorized by the OpenLDAP
13 * A copy of this license is available in the file LICENSE in the
14 * top-level directory of the distribution or, alternatively, at
15 * <http://www.OpenLDAP.org/license.html>.
18 * This work was initially developed by Dmitry Kovalev for inclusion
19 * by OpenLDAP Software.
25 #include <sys/types.h>
26 #include "ac/string.h"
29 #include "proto-sql.h"
31 #define BACKSQL_DUPLICATE (-1)
33 /* NOTE: by default, cannot just compare pointers because
34 * objectClass/attributeType order would be machine-dependent
35 * (and tests would fail!); however, if you don't want to run
36 * tests, or see attributeTypes written in the same order
37 * they are defined, define */
38 /* #undef BACKSQL_USE_PTR_CMP */
41 * Uses the pointer to the ObjectClass structure
44 backsql_cmp_oc( const void *v_m1, const void *v_m2 )
46 const backsql_oc_map_rec *m1 = v_m1,
49 #ifdef BACKSQL_USE_PTR_CMP
50 return SLAP_PTRCMP( m1->bom_oc, m2->bom_oc );
51 #else /* ! BACKSQL_USE_PTR_CMP */
52 return ber_bvcmp( &m1->bom_oc->soc_cname, &m2->bom_oc->soc_cname );
53 #endif /* ! BACKSQL_USE_PTR_CMP */
57 backsql_cmp_oc_id( const void *v_m1, const void *v_m2 )
59 const backsql_oc_map_rec *m1 = v_m1,
62 return ( m1->bom_id < m2->bom_id ? -1 : ( m1->bom_id > m2->bom_id ? 1 : 0 ) );
66 * Uses the pointer to the AttributeDescription structure
69 backsql_cmp_attr( const void *v_m1, const void *v_m2 )
71 const backsql_at_map_rec *m1 = v_m1,
74 #ifdef BACKSQL_USE_PTR_CMP
75 return SLAP_PTRCMP( m1->bam_ad, m2->bam_ad );
76 #else /* ! BACKSQL_USE_PTR_CMP */
77 return ber_bvcmp( &m1->bam_ad->ad_cname, &m2->bam_ad->ad_cname );
78 #endif /* ! BACKSQL_USE_PTR_CMP */
82 backsql_dup_attr( void *v_m1, void *v_m2 )
84 backsql_at_map_rec *m1 = v_m1,
87 assert( m1->bam_ad == m2->bam_ad );
89 /* duplicate definitions of attributeTypes are appended;
90 * this allows to define multiple rules for the same
91 * attributeType. Use with care! */
92 for ( ; m1->bam_next ; m1 = m1->bam_next );
96 return BACKSQL_DUPLICATE;
100 backsql_make_attr_query(
101 backsql_oc_map_rec *oc_map,
102 backsql_at_map_rec *at_map )
104 struct berbuf bb = BB_NULL;
106 #ifdef BACKSQL_ALIASING_QUOTE
107 backsql_strfcat( &bb, "lblcbclblbcbl",
108 (ber_len_t)STRLENOF( "SELECT " ), "SELECT ",
109 &at_map->bam_sel_expr,
110 (ber_len_t)STRLENOF( " " BACKSQL_ALIASING ), " " BACKSQL_ALIASING,
111 BACKSQL_ALIASING_QUOTE,
112 &at_map->bam_ad->ad_cname,
113 BACKSQL_ALIASING_QUOTE,
114 (ber_len_t)STRLENOF( " FROM " ), " FROM ",
115 &at_map->bam_from_tbls,
116 (ber_len_t)STRLENOF( " WHERE " ), " WHERE ",
120 (ber_len_t)STRLENOF( "=?" ), "=?" );
121 #else /* ! BACKSQL_ALIASING_QUOTE */
122 backsql_strfcat( &bb, "lblblblbcbl",
123 (ber_len_t)STRLENOF( "SELECT " ), "SELECT ",
124 &at_map->bam_sel_expr,
125 (ber_len_t)STRLENOF( " " BACKSQL_ALIASING ), " " BACKSQL_ALIASING,
126 &at_map->bam_ad->ad_cname,
127 (ber_len_t)STRLENOF( " FROM " ), " FROM ",
128 &at_map->bam_from_tbls,
129 (ber_len_t)STRLENOF( " WHERE " ), " WHERE ",
133 (ber_len_t)STRLENOF( "=?" ), "=?" );
134 #endif /* ! BACKSQL_ALIASING_QUOTE */
136 if ( !BER_BVISNULL( &at_map->bam_join_where ) ) {
137 backsql_strfcat( &bb, "lb",
138 (ber_len_t)STRLENOF( " AND " ), " AND ",
139 &at_map->bam_join_where );
142 #ifdef BACKSQL_ALIASING_QUOTE
143 backsql_strfcat( &bb, "lcbc",
144 (ber_len_t)STRLENOF( " ORDER BY " ), " ORDER BY ",
145 BACKSQL_ALIASING_QUOTE,
146 &at_map->bam_sel_expr,
147 BACKSQL_ALIASING_QUOTE );
148 #else /* ! BACKSQL_ALIASING_QUOTE */
149 backsql_strfcat( &bb, "lb",
150 (ber_len_t)STRLENOF( " ORDER BY " ), " ORDER BY ",
151 &at_map->bam_sel_expr );
152 #endif /* ! BACKSQL_ALIASING_QUOTE */
154 at_map->bam_query = bb.bb_val.bv_val;
160 backsql_add_sysmaps( backsql_oc_map_rec *oc_map )
162 backsql_at_map_rec *at_map;
163 char s[] = "+9223372036854775807L";
168 snprintf( s, sizeof( s ), "%ld", oc_map->bom_id );
169 sbv.bv_len = strlen( s );
171 /* extra objectClasses */
172 at_map = (backsql_at_map_rec *)ch_calloc(1,
173 sizeof( backsql_at_map_rec ) );
174 at_map->bam_ad = slap_schema.si_ad_objectClass;
175 ber_str2bv( "ldap_entry_objclasses.oc_name", 0, 1,
176 &at_map->bam_sel_expr );
177 ber_str2bv( "ldap_entry_objclasses,ldap_entries", 0, 1,
178 &at_map->bam_from_tbls );
180 bb.bb_len = at_map->bam_from_tbls.bv_len + 1;
181 bb.bb_val = at_map->bam_from_tbls;
182 backsql_merge_from_clause( &bb, &oc_map->bom_keytbl );
183 at_map->bam_from_tbls = bb.bb_val;
185 BER_BVZERO( &bb.bb_val );
187 backsql_strfcat( &bb, "lbcblb",
188 (ber_len_t)STRLENOF( "ldap_entries.id=ldap_entry_objclasses.entry_id AND ldap_entries.keyval=" ),
189 "ldap_entries.id=ldap_entry_objclasses.entry_id AND ldap_entries.keyval=",
193 (ber_len_t)STRLENOF( " and ldap_entries.oc_map_id=" ),
194 " and ldap_entries.oc_map_id=",
196 at_map->bam_join_where = bb.bb_val;
198 at_map->bam_oc = oc_map->bom_oc;
200 at_map->bam_add_proc = NULL;
203 "INSERT INTO ldap_entry_objclasses "
204 "(entry_id,oc_name) VALUES "
205 "((SELECT id FROM ldap_entries "
207 "18446744073709551615UL " /* 64 bit ULONG */
209 snprintf( tmp, sizeof(tmp),
210 "INSERT INTO ldap_entry_objclasses "
211 "(entry_id,oc_name) VALUES "
212 "((SELECT id FROM ldap_entries "
213 "WHERE oc_map_id=%lu "
214 "AND keyval=?),?)", oc_map->bom_id );
215 at_map->bam_add_proc = ch_strdup( tmp );
218 at_map->bam_delete_proc = NULL;
221 "DELETE FROM ldap_entry_objclasses "
222 "WHERE entry_id=(SELECT id FROM ldap_entries "
224 "18446744073709551615UL " /* 64 bit ULONG */
225 "AND keyval=?) AND oc_name=?";
226 snprintf( tmp, sizeof(tmp),
227 "DELETE FROM ldap_entry_objclasses "
228 "WHERE entry_id=(SELECT id FROM ldap_entries "
229 "WHERE oc_map_id=%lu"
230 "AND keyval=?) AND oc_name=?",
232 at_map->bam_delete_proc = ch_strdup( tmp );
235 at_map->bam_param_order = 0;
236 at_map->bam_expect_return = 0;
237 at_map->bam_next = NULL;
239 backsql_make_attr_query( oc_map, at_map );
240 if ( avl_insert( &oc_map->bom_attrs, at_map, backsql_cmp_attr, backsql_dup_attr ) == BACKSQL_DUPLICATE ) {
241 Debug( LDAP_DEBUG_TRACE, "backsql_add_sysmaps(): "
242 "duplicate attribute \"%s\" in objectClass \"%s\" map\n",
243 at_map->bam_ad->ad_cname.bv_val,
244 oc_map->bom_oc->soc_cname.bv_val, 0 );
247 /* FIXME: we need to correct the objectClass join_where
248 * after the attribute query is built */
249 ch_free( at_map->bam_join_where.bv_val );
250 BER_BVZERO( &bb.bb_val );
252 backsql_strfcat( &bb, "lbcblb",
253 (ber_len_t)STRLENOF( /* "ldap_entries.id=ldap_entry_objclasses.entry_id AND " */ "ldap_entries.keyval=" ),
254 /* "ldap_entries.id=ldap_entry_objclasses.entry_id AND " */ "ldap_entries.keyval=",
258 (ber_len_t)STRLENOF( " AND ldap_entries.oc_map_id=" ),
259 " AND ldap_entries.oc_map_id=",
261 at_map->bam_join_where = bb.bb_val;
263 /* referral attribute */
264 at_map = (backsql_at_map_rec *)ch_calloc( 1,
265 sizeof( backsql_at_map_rec ) );
266 at_map->bam_ad = slap_schema.si_ad_ref;
267 ber_str2bv( "ldap_referrals.url", 0, 1, &at_map->bam_sel_expr );
268 ber_str2bv( "ldap_referrals,ldap_entries", 0, 1, &at_map->bam_from_tbls );
270 bb.bb_len = at_map->bam_from_tbls.bv_len + 1;
271 bb.bb_val = at_map->bam_from_tbls;
272 backsql_merge_from_clause( &bb, &oc_map->bom_keytbl );
273 at_map->bam_from_tbls = bb.bb_val;
275 BER_BVZERO( &bb.bb_val );
277 backsql_strfcat( &bb, "lbcblb",
278 (ber_len_t)STRLENOF( "ldap_entries.id=ldap_referrals.entry_id AND ldap_entries.keyval=" ),
279 "ldap_entries.id=ldap_referrals.entry_id AND ldap_entries.keyval=",
283 (ber_len_t)STRLENOF( " AND ldap_entries.oc_map_id=" ),
284 " AND ldap_entries.oc_map_id=",
287 at_map->bam_join_where = bb.bb_val;
289 at_map->bam_oc = NULL;
291 at_map->bam_add_proc = NULL;
294 "INSERT INTO ldap_referrals "
295 "(entry_id,url) VALUES "
296 "((SELECT id FROM ldap_entries "
298 "18446744073709551615UL " /* 64 bit ULONG */
300 snprintf( tmp, sizeof(tmp),
301 "INSERT INTO ldap_referrals "
302 "(entry_id,url) VALUES "
303 "((SELECT id FROM ldap_entries "
304 "WHERE oc_map_id=%lu "
305 "AND keyval=?),?)", oc_map->bom_id );
306 at_map->bam_add_proc = ch_strdup( tmp );
309 at_map->bam_delete_proc = NULL;
312 "DELETE FROM ldap_referrals "
313 "WHERE entry_id=(SELECT id FROM ldap_entries "
315 "18446744073709551615UL " /* 64 bit ULONG */
316 "AND keyval=?) and url=?";
317 snprintf( tmp, sizeof(tmp),
318 "DELETE FROM ldap_referrals "
319 "WHERE entry_id=(SELECT id FROM ldap_entries "
320 "WHERE oc_map_id=%lu"
321 "AND keyval=?) and url=?",
323 at_map->bam_delete_proc = ch_strdup( tmp );
326 at_map->bam_param_order = 0;
327 at_map->bam_expect_return = 0;
328 at_map->bam_next = NULL;
330 backsql_make_attr_query( oc_map, at_map );
331 if ( avl_insert( &oc_map->bom_attrs, at_map, backsql_cmp_attr, backsql_dup_attr ) == BACKSQL_DUPLICATE ) {
332 Debug( LDAP_DEBUG_TRACE, "backsql_add_sysmaps(): "
333 "duplicate attribute \"%s\" in objectClass \"%s\" map\n",
334 at_map->bam_ad->ad_cname.bv_val,
335 oc_map->bom_oc->soc_cname.bv_val, 0 );
341 struct backsql_attr_schema_info {
342 backsql_info *bas_bi;
345 unsigned long *bas_oc_id;
350 backsql_oc_get_attr_mapping( void *v_oc, void *v_bas )
353 BACKSQL_ROW_NTS at_row;
354 backsql_oc_map_rec *oc_map = (backsql_oc_map_rec *)v_oc;
355 backsql_at_map_rec *at_map;
356 struct backsql_attr_schema_info *bas = (struct backsql_attr_schema_info *)v_bas;
358 /* bas->bas_oc_id has been bound to bas->bas_sth */
359 *bas->bas_oc_id = oc_map->bom_id;
361 Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_attr_mapping(): "
362 "executing at_query\n"
364 " for objectClass \"%s\"\n"
365 " with param oc_id=\"%lu\"\n",
366 bas->bas_bi->sql_at_query,
367 BACKSQL_OC_NAME( oc_map ),
370 rc = SQLExecute( bas->bas_sth );
371 if ( rc != SQL_SUCCESS ) {
372 Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_attr_mapping(): "
373 "error executing at_query\n"
375 " for objectClass \"%s\"\n"
376 " with param oc_id=\"%lu\"\n",
377 bas->bas_bi->sql_at_query,
378 BACKSQL_OC_NAME( oc_map ),
380 backsql_PrintErrors( bas->bas_bi->sql_db_env,
381 bas->bas_dbh, bas->bas_sth, rc );
382 bas->bas_rc = LDAP_OTHER;
383 return BACKSQL_AVL_STOP;
386 backsql_BindRowAsStrings( bas->bas_sth, &at_row );
387 for ( ; rc = SQLFetch( bas->bas_sth ), BACKSQL_SUCCESS( rc ); ) {
388 const char *text = NULL;
391 struct berbuf bb = BB_NULL;
393 Debug( LDAP_DEBUG_TRACE,
396 "\tsel_expr=\"%s\"\n"
398 at_row.cols[ 0 ], at_row.cols[ 1 ],
400 Debug( LDAP_DEBUG_TRACE,
401 "\tjoin_where=\"%s\"\n"
402 "\tadd_proc=\"%s\"\n"
403 "\tdelete_proc=\"%s\"\n",
404 at_row.cols[ 3 ], at_row.cols[ 4 ],
407 Debug( LDAP_DEBUG_TRACE, "\tsel_expr_u=\"%s\"\n",
408 at_row.cols[ 8 ], 0, 0 );
409 at_map = (backsql_at_map_rec *)ch_calloc( 1,
410 sizeof( backsql_at_map_rec ) );
411 rc = slap_str2ad( at_row.cols[ 0 ],
412 &at_map->bam_ad, &text );
413 if ( rc != LDAP_SUCCESS ) {
414 Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_attr_mapping(): "
415 "attribute \"%s\" for objectClass \"%s\" "
416 "is not defined in schema: %s\n",
418 BACKSQL_OC_NAME( oc_map ), text );
419 bas->bas_rc = LDAP_CONSTRAINT_VIOLATION;
420 return BACKSQL_AVL_STOP;
423 ber_str2bv( at_row.cols[ 1 ], 0, 1, &at_map->bam_sel_expr );
424 if ( at_row.value_len[ 8 ] < 0 ) {
425 BER_BVZERO( &at_map->bam_sel_expr_u );
428 ber_str2bv( at_row.cols[ 8 ], 0, 1,
429 &at_map->bam_sel_expr_u );
432 ber_str2bv( at_row.cols[ 2 ], 0, 0, &bv );
433 backsql_merge_from_clause( &bb, &bv );
434 at_map->bam_from_tbls = bb.bb_val;
435 if ( at_row.value_len[ 3 ] < 0 ) {
436 BER_BVZERO( &at_map->bam_join_where );
439 ber_str2bv( at_row.cols[ 3 ], 0, 1,
440 &at_map->bam_join_where );
442 at_map->bam_add_proc = NULL;
443 if ( at_row.value_len[ 4 ] > 0 ) {
444 at_map->bam_add_proc = ch_strdup( at_row.cols[4] );
446 at_map->bam_delete_proc = NULL;
447 if ( at_row.value_len[ 5 ] > 0 ) {
448 at_map->bam_delete_proc = ch_strdup( at_row.cols[ 5 ] );
450 at_map->bam_param_order = strtol( at_row.cols[ 6 ],
452 if ( next == at_row.cols[ 6 ] || next[0] != '\0' ) {
455 at_map->bam_expect_return = strtol( at_row.cols[ 7 ],
457 if ( next == at_row.cols[ 7 ] || next[0] != '\0' ) {
460 backsql_make_attr_query( oc_map, at_map );
461 Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_attr_mapping(): "
462 "preconstructed query \"%s\"\n",
463 at_map->bam_query, 0, 0 );
464 at_map->bam_next = NULL;
465 if ( avl_insert( &oc_map->bom_attrs, at_map, backsql_cmp_attr, backsql_dup_attr ) == BACKSQL_DUPLICATE ) {
466 Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_attr_mapping(): "
467 "duplicate attribute \"%s\" "
468 "in objectClass \"%s\" map\n",
469 at_map->bam_ad->ad_cname.bv_val,
470 oc_map->bom_oc->soc_cname.bv_val, 0 );
473 if ( !BER_BVISNULL( &bas->bas_bi->sql_upper_func ) &&
474 BER_BVISNULL( &at_map->bam_sel_expr_u ) )
476 struct berbuf bb = BB_NULL;
478 backsql_strfcat( &bb, "bcbc",
479 &bas->bas_bi->sql_upper_func,
481 &at_map->bam_sel_expr,
483 at_map->bam_sel_expr_u = bb.bb_val;
486 backsql_FreeRow( &at_row );
487 SQLFreeStmt( bas->bas_sth, SQL_CLOSE );
489 Debug( LDAP_DEBUG_TRACE, "backsql_load_schema_map(\"%s\"): "
490 "autoadding 'objectClass' and 'ref' mappings\n",
491 BACKSQL_OC_NAME( oc_map ), 0, 0 );
493 (void)backsql_add_sysmaps( oc_map );
495 return BACKSQL_AVL_CONTINUE;
500 backsql_load_schema_map( backsql_info *bi, SQLHDBC dbh )
502 SQLHSTMT sth = SQL_NULL_HSTMT;
504 BACKSQL_ROW_NTS oc_row;
506 backsql_oc_map_rec *oc_map;
507 struct backsql_attr_schema_info bas;
509 Debug( LDAP_DEBUG_TRACE, "==>backsql_load_schema_map()\n", 0, 0, 0 );
512 * TimesTen : See if the ldap_entries.dn_ru field exists in the schema
514 if ( !BACKSQL_DONTCHECK_LDAPINFO_DN_RU( bi ) ) {
515 rc = backsql_Prepare( dbh, &sth,
516 backsql_check_dn_ru_query, 0 );
517 if ( rc == SQL_SUCCESS ) {
518 /* Yes, the field exists */
519 bi->sql_flags |= BSQLF_HAS_LDAPINFO_DN_RU;
520 Debug( LDAP_DEBUG_TRACE, "ldapinfo.dn_ru field exists "
521 "in the schema\n", 0, 0, 0 );
523 /* No such field exists */
524 bi->sql_flags &= ~BSQLF_HAS_LDAPINFO_DN_RU;
527 SQLFreeStmt( sth, SQL_DROP );
530 Debug( LDAP_DEBUG_TRACE, "backsql_load_schema_map(): oc_query \"%s\"\n",
531 bi->sql_oc_query, 0, 0 );
533 rc = backsql_Prepare( dbh, &sth, bi->sql_oc_query, 0 );
534 if ( rc != SQL_SUCCESS ) {
535 Debug( LDAP_DEBUG_TRACE, "backsql_load_schema_map(): "
536 "error preparing oc_query: \"%s\"\n",
537 bi->sql_oc_query, 0, 0 );
538 backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc );
542 rc = SQLExecute( sth );
543 if ( rc != SQL_SUCCESS ) {
544 Debug( LDAP_DEBUG_TRACE, "backsql_load_schema_map(): "
545 "error executing oc_query: \n", 0, 0, 0 );
546 backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc );
550 backsql_BindRowAsStrings( sth, &oc_row );
551 rc = SQLFetch( sth );
552 for ( ; BACKSQL_SUCCESS( rc ); rc = SQLFetch( sth ) ) {
555 oc_map = (backsql_oc_map_rec *)ch_calloc( 1,
556 sizeof( backsql_oc_map_rec ) );
558 oc_map->bom_id = strtol( oc_row.cols[ 0 ], NULL, 0 );
560 oc_map->bom_oc = oc_find( oc_row.cols[ 1 ] );
561 if ( oc_map->bom_oc == NULL ) {
562 Debug( LDAP_DEBUG_TRACE, "backsql_load_schema_map(): "
563 "objectClass \"%s\" is not defined in schema\n",
564 oc_row.cols[ 1 ], 0, 0 );
565 return LDAP_OTHER; /* undefined objectClass ? */
568 ber_str2bv( oc_row.cols[ 2 ], 0, 1, &oc_map->bom_keytbl );
569 ber_str2bv( oc_row.cols[ 3 ], 0, 1, &oc_map->bom_keycol );
570 oc_map->bom_create_proc = ( oc_row.value_len[ 4 ] < 0 ) ? NULL
571 : ch_strdup( oc_row.cols[ 4 ] );
574 if ( BACKSQL_CREATE_NEEDS_SELECT( bi ) ) {
576 oc_map->bom_create_keyval = ( oc_row.value_len[ 5 ] < 0 )
577 ? NULL : ch_strdup( oc_row.cols[ 5 ] );
579 oc_map->bom_delete_proc = ( oc_row.value_len[ colnum ] < 0 ) ? NULL
580 : ch_strdup( oc_row.cols[ colnum ] );
581 oc_map->bom_expect_return = strtol( oc_row.cols[ colnum + 1 ],
585 if ( ( oc_row.ncols > colnum ) &&
586 ( oc_row.value_len[ colnum ] > 0 ) )
590 oc_map->bom_create_hint = NULL;
591 rc = slap_str2ad( oc_row.cols[ colnum ],
592 &oc_map->bom_create_hint, &text );
593 if ( rc != SQL_SUCCESS ) {
594 Debug( LDAP_DEBUG_TRACE, "load_schema_map(): "
596 "AttributeDescription %s "
597 "in create_hint: %s (%d)\n",
598 oc_row.cols[ colnum ],
600 backsql_PrintErrors( bi->sql_db_env, dbh,
607 * FIXME: first attempt to check for offending
608 * instructions in {create|delete}_proc
611 oc_map->bom_attrs = NULL;
612 if ( avl_insert( &bi->sql_oc_by_oc, oc_map, backsql_cmp_oc, avl_dup_error ) == -1 ) {
613 Debug( LDAP_DEBUG_TRACE, "backsql_load_schema_map(): "
614 "duplicate objectClass \"%s\" in objectClass map\n",
615 oc_map->bom_oc->soc_cname.bv_val, 0, 0 );
618 if ( avl_insert( &bi->sql_oc_by_id, oc_map, backsql_cmp_oc_id, avl_dup_error ) == -1 ) {
619 Debug( LDAP_DEBUG_TRACE, "backsql_load_schema_map(): "
620 "duplicate objectClass \"%s\" in objectClass by ID map\n",
621 oc_map->bom_oc->soc_cname.bv_val, 0, 0 );
624 oc_id = oc_map->bom_id;
625 Debug( LDAP_DEBUG_TRACE, "backsql_load_schema_map(): "
626 "objectClass \"%s\":\n keytbl=\"%s\" keycol=\"%s\"\n",
627 BACKSQL_OC_NAME( oc_map ),
628 oc_map->bom_keytbl.bv_val, oc_map->bom_keycol.bv_val );
629 if ( oc_map->bom_create_proc ) {
630 Debug( LDAP_DEBUG_TRACE, " create_proc=\"%s\"\n",
631 oc_map->bom_create_proc, 0, 0 );
633 if ( oc_map->bom_create_keyval ) {
634 Debug( LDAP_DEBUG_TRACE, " create_keyval=\"%s\"\n",
635 oc_map->bom_create_keyval, 0, 0 );
637 if ( oc_map->bom_create_hint ) {
638 Debug( LDAP_DEBUG_TRACE, " create_hint=\"%s\"\n",
639 oc_map->bom_create_hint->ad_cname.bv_val,
642 if ( oc_map->bom_delete_proc ) {
643 Debug( LDAP_DEBUG_TRACE, " delete_proc=\"%s\"\n",
644 oc_map->bom_delete_proc, 0, 0 );
646 Debug( LDAP_DEBUG_TRACE, " expect_return: "
647 "add=%d, del=%d; attributes:\n",
648 BACKSQL_IS_ADD( oc_map->bom_expect_return ),
649 BACKSQL_IS_DEL( oc_map->bom_expect_return ), 0 );
652 backsql_FreeRow( &oc_row );
653 SQLFreeStmt( sth, SQL_DROP );
655 /* prepare for attribute fetching */
656 Debug( LDAP_DEBUG_TRACE, "backsql_load_schema_map(): at_query \"%s\"\n",
657 bi->sql_at_query, 0, 0 );
659 rc = backsql_Prepare( dbh, &sth, bi->sql_at_query, 0 );
660 if ( rc != SQL_SUCCESS ) {
661 Debug( LDAP_DEBUG_TRACE, "backsql_load_schema_map(): "
662 "error preparing at_query: \"%s\"\n",
663 bi->sql_at_query, 0, 0 );
664 backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc );
668 rc = backsql_BindParamInt( sth, 1, SQL_PARAM_INPUT, &oc_id );
669 if ( rc != SQL_SUCCESS ) {
670 Debug( LDAP_DEBUG_TRACE, "backsql_load_schema_map(): "
671 "error binding param \"oc_id\" for at_query\n", 0, 0, 0 );
672 backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc );
673 SQLFreeStmt( sth, SQL_DROP );
680 bas.bas_oc_id = &oc_id;
681 bas.bas_rc = LDAP_SUCCESS;
683 (void)avl_apply( bi->sql_oc_by_oc, backsql_oc_get_attr_mapping,
684 &bas, BACKSQL_AVL_STOP, AVL_INORDER );
686 SQLFreeStmt( sth, SQL_DROP );
688 bi->sql_flags |= BSQLF_SCHEMA_LOADED;
690 Debug( LDAP_DEBUG_TRACE, "<==backsql_load_schema_map()\n", 0, 0, 0 );
696 backsql_oc2oc( backsql_info *bi, ObjectClass *oc )
698 backsql_oc_map_rec tmp, *res;
701 Debug( LDAP_DEBUG_TRACE, "==>backsql_oc2oc(): "
702 "searching for objectclass with name=\"%s\"\n",
703 oc->soc_cname.bv_val, 0, 0 );
704 #endif /* BACKSQL_TRACE */
707 res = (backsql_oc_map_rec *)avl_find( bi->sql_oc_by_oc, &tmp, backsql_cmp_oc );
710 Debug( LDAP_DEBUG_TRACE, "<==backsql_oc2oc(): "
711 "found name=\"%s\", id=%d\n",
712 BACKSQL_OC_NAME( res ), res->bom_id, 0 );
714 Debug( LDAP_DEBUG_TRACE, "<==backsql_oc2oc(): "
715 "not found\n", 0, 0, 0 );
717 #endif /* BACKSQL_TRACE */
723 backsql_name2oc( backsql_info *bi, struct berval *oc_name )
725 backsql_oc_map_rec tmp, *res;
728 Debug( LDAP_DEBUG_TRACE, "==>oc_with_name(): "
729 "searching for objectclass with name=\"%s\"\n",
730 oc_name->bv_val, 0, 0 );
731 #endif /* BACKSQL_TRACE */
733 tmp.bom_oc = oc_bvfind( oc_name );
734 if ( tmp.bom_oc == NULL ) {
738 res = (backsql_oc_map_rec *)avl_find( bi->sql_oc_by_oc, &tmp, backsql_cmp_oc );
741 Debug( LDAP_DEBUG_TRACE, "<==oc_with_name(): "
742 "found name=\"%s\", id=%d\n",
743 BACKSQL_OC_NAME( res ), res->bom_id, 0 );
745 Debug( LDAP_DEBUG_TRACE, "<==oc_with_name(): "
746 "not found\n", 0, 0, 0 );
748 #endif /* BACKSQL_TRACE */
754 backsql_id2oc( backsql_info *bi, unsigned long id )
756 backsql_oc_map_rec tmp, *res;
759 Debug( LDAP_DEBUG_TRACE, "==>oc_with_id(): "
760 "searching for objectclass with id='%d'\n", id, 0, 0 );
761 #endif /* BACKSQL_TRACE */
764 res = (backsql_oc_map_rec *)avl_find( bi->sql_oc_by_id, &tmp,
769 Debug( LDAP_DEBUG_TRACE, "<==oc_with_name(): "
770 "found name=\"%s\", id=%d\n",
771 BACKSQL_OC_NAME( res ), res->bom_id, 0 );
773 Debug( LDAP_DEBUG_TRACE, "<==oc_with_name(): "
774 "not found\n", 0, 0, 0 );
776 #endif /* BACKSQL_TRACE */
782 backsql_ad2at( backsql_oc_map_rec* objclass, AttributeDescription *ad )
784 backsql_at_map_rec tmp, *res;
787 Debug( LDAP_DEBUG_TRACE, "==>backsql_ad2at(): "
788 "searching for attribute \"%s\" for objectclass \"%s\"\n",
789 ad->ad_cname.bv_val, BACKSQL_OC_NAME( objclass ), 0 );
790 #endif /* BACKSQL_TRACE */
793 res = (backsql_at_map_rec *)avl_find( objclass->bom_attrs, &tmp,
798 Debug( LDAP_DEBUG_TRACE, "<==backsql_ad2at(): "
799 "found name=\"%s\", sel_expr=\"%s\"\n",
800 res->bam_ad->ad_cname.bv_val,
801 res->bam_sel_expr.bv_val, 0 );
803 Debug( LDAP_DEBUG_TRACE, "<==backsql_ad2at(): "
804 "not found\n", 0, 0, 0 );
806 #endif /* BACKSQL_TRACE */
811 /* attributeType inheritance */
813 backsql_at_map_rec **ret;
814 AttributeDescription *ad;
818 #define SUPAD2AT_STOP (-1)
821 supad2at_f( void *v_at, void *v_arg )
823 backsql_at_map_rec *at = (backsql_at_map_rec *)v_at;
824 struct supad2at_t *va = (struct supad2at_t *)v_arg;
826 if ( is_at_subtype( at->bam_ad->ad_type, va->ad->ad_type ) ) {
827 backsql_at_map_rec **ret;
830 /* if already listed, holler! (should never happen) */
832 for ( i = 0; i < va->n; i++ ) {
833 if ( va->ret[ i ]->bam_ad == at->bam_ad ) {
843 ret = ch_realloc( va->ret,
844 sizeof( backsql_at_map_rec *) * ( va->n + 2 ) );
847 return SUPAD2AT_STOP;
860 * stores in *pret a NULL terminated array of pointers
861 * to backsql_at_map_rec whose attributeType is supad->ad_type
865 backsql_supad2at( backsql_oc_map_rec *objclass, AttributeDescription *supad,
866 backsql_at_map_rec ***pret )
868 struct supad2at_t va;
881 rc = avl_apply( objclass->bom_attrs, supad2at_f, &va,
882 SUPAD2AT_STOP, AVL_INORDER );
883 if ( rc == SUPAD2AT_STOP ) {
893 backsql_free_attr( void *v_at )
895 backsql_at_map_rec *at = v_at;
897 Debug( LDAP_DEBUG_TRACE, "==>free_attr(): \"%s\"\n",
898 at->bam_ad->ad_cname.bv_val, 0, 0 );
899 ch_free( at->bam_sel_expr.bv_val );
900 if ( !BER_BVISNULL( &at->bam_from_tbls ) ) {
901 ch_free( at->bam_from_tbls.bv_val );
903 if ( !BER_BVISNULL( &at->bam_join_where ) ) {
904 ch_free( at->bam_join_where.bv_val );
906 if ( at->bam_add_proc != NULL ) {
907 ch_free( at->bam_add_proc );
909 if ( at->bam_delete_proc != NULL ) {
910 ch_free( at->bam_delete_proc );
912 if ( at->bam_query != NULL ) {
913 ch_free( at->bam_query );
917 if ( !BER_BVISNULL( &at->bam_sel_expr_u ) ) {
918 ch_free( at->bam_sel_expr_u.bv_val );
921 if ( at->bam_next ) {
922 backsql_free_attr( at->bam_next );
927 Debug( LDAP_DEBUG_TRACE, "<==free_attr()\n", 0, 0, 0 );
931 backsql_free_oc( void *v_oc )
933 backsql_oc_map_rec *oc = v_oc;
935 Debug( LDAP_DEBUG_TRACE, "==>free_oc(): \"%s\"\n",
936 BACKSQL_OC_NAME( oc ), 0, 0 );
937 avl_free( oc->bom_attrs, backsql_free_attr );
938 ch_free( oc->bom_keytbl.bv_val );
939 ch_free( oc->bom_keycol.bv_val );
940 if ( oc->bom_create_proc != NULL ) {
941 ch_free( oc->bom_create_proc );
943 if ( oc->bom_create_keyval != NULL ) {
944 ch_free( oc->bom_create_keyval );
946 if ( oc->bom_delete_proc != NULL ) {
947 ch_free( oc->bom_delete_proc );
951 Debug( LDAP_DEBUG_TRACE, "<==free_oc()\n", 0, 0, 0 );
955 backsql_destroy_schema_map( backsql_info *bi )
957 Debug( LDAP_DEBUG_TRACE, "==>destroy_schema_map()\n", 0, 0, 0 );
958 avl_free( bi->sql_oc_by_oc, 0 );
959 avl_free( bi->sql_oc_by_id, backsql_free_oc );
960 Debug( LDAP_DEBUG_TRACE, "<==destroy_schema_map()\n", 0, 0, 0 );