}
if ( !BER_BVISNULL( &bsi.bsi_base_id.eid_ndn ) ) {
- (void)backsql_free_entryID( op, &bsi.bsi_base_id, 0 );
+ (void)backsql_free_entryID( &bsi.bsi_base_id, 0, op->o_tmpmemctx );
}
if ( !BER_BVISNULL( &p.e_nname ) ) {
*/
struct berval sql_subtree_cond;
struct berval sql_children_cond;
- char *sql_oc_query,
- *sql_at_query;
- char *sql_insentry_stmt,
- *sql_delentry_stmt,
- *sql_renentry_stmt,
- *sql_delobjclasses_stmt;
+ struct berval sql_dn_match_cond;
+ char *sql_oc_query;
+ char *sql_at_query;
+ char *sql_insentry_stmt;
+ char *sql_delentry_stmt;
+ char *sql_renentry_stmt;
+ char *sql_delobjclasses_stmt;
char *sql_id_query;
char *sql_has_children_query;
+ char *sql_list_children_query;
MatchingRule *sql_caseIgnoreMatch;
MatchingRule *sql_telephoneNumberMatch;
#define BACKSQL_BASEOBJECT_OC 0
Avlnode *sql_db_conns;
+ SQLHDBC sql_dbh;
+ ldap_pvt_thread_mutex_t sql_dbconn_mutex;
Avlnode *sql_oc_by_oc;
Avlnode *sql_oc_by_id;
- ldap_pvt_thread_mutex_t sql_dbconn_mutex;
ldap_pvt_thread_mutex_t sql_schema_mutex;
SQLHENV sql_db_env;
}
rs->sr_err = backsql_get_db_conn( op, &dbh );
- if ( !dbh ) {
+ if ( rs->sr_err != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE, "backsql_bind(): "
"could not get connection handle - exiting\n",
0, 0, 0 );
error_return:;
if ( !BER_BVISNULL( &bsi.bsi_base_id.eid_ndn ) ) {
- (void)backsql_free_entryID( op, &bsi.bsi_base_id, 0 );
+ (void)backsql_free_entryID( &bsi.bsi_base_id, 0, op->o_tmpmemctx );
}
if ( !BER_BVISNULL( &e.e_nname ) ) {
Debug( LDAP_DEBUG_TRACE, "==>backsql_compare()\n", 0, 0, 0 );
rs->sr_err = backsql_get_db_conn( op, &dbh );
- if ( !dbh ) {
+ if ( rs->sr_err != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE, "backsql_compare(): "
"could not get connection handle - exiting\n",
0, 0, 0 );
}
if ( !BER_BVISNULL( &bsi.bsi_base_id.eid_ndn ) ) {
- (void)backsql_free_entryID( op, &bsi.bsi_base_id, 0 );
+ (void)backsql_free_entryID( &bsi.bsi_base_id, 0, op->o_tmpmemctx );
}
if ( !BER_BVISNULL( &e.e_nname ) ) {
}
ber_str2bv( argv[ 1 ], 0, 1, &bi->sql_children_cond );
Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
- "subtree_cond=%s\n", bi->sql_children_cond.bv_val, 0, 0 );
+ "children_cond=%s\n", bi->sql_children_cond.bv_val, 0, 0 );
+
+ } else if ( !strcasecmp( argv[ 0 ], "dn_match_cond" ) ) {
+ if ( argc < 2 ) {
+ Debug( LDAP_DEBUG_TRACE,
+ "<==backsql_db_config (%s line %d): "
+ "missing SQL condition "
+ "in \"dn_match_cond\" directive\n",
+ fname, lineno, 0 );
+ return 1;
+ }
+ ber_str2bv( argv[ 1 ], 0, 1, &bi->sql_dn_match_cond );
+ Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
+ "children_cond=%s\n", bi->sql_dn_match_cond.bv_val, 0, 0 );
} else if ( !strcasecmp( argv[ 0 ], "oc_query" ) ) {
if ( argc < 2 ) {
goto done;
}
- (void)backsql_free_entryID( op, &bsi.bsi_base_id, 0 );
+ (void)backsql_free_entryID( &bsi.bsi_base_id, 0, op->o_tmpmemctx );
/* check parent for "children" acl */
if ( !access_allowed( op, &p, slap_schema.si_ad_children,
Debug( LDAP_DEBUG_TRACE, "<==backsql_delete()\n", 0, 0, 0 );
if ( !BER_BVISNULL( &e_id.eid_ndn ) ) {
- (void)backsql_free_entryID( op, &e_id, 0 );
+ (void)backsql_free_entryID( &e_id, 0, op->o_tmpmemctx );
}
if ( !BER_BVISNULL( &d.e_nname ) ) {
#endif /* BACKSQL_ARBITRARY_KEY */
backsql_entryID *
-backsql_free_entryID( Operation *op, backsql_entryID *id, int freeit )
+backsql_entryID_dup( backsql_entryID *src, void *ctx )
+{
+ backsql_entryID *dst;
+
+ if ( src == NULL ) return NULL;
+
+ dst = slap_sl_calloc( 1, sizeof( backsql_entryID ), ctx );
+ ber_dupbv_x( &dst->eid_ndn, &src->eid_ndn, ctx );
+ if ( src->eid_dn.bv_val == src->eid_ndn.bv_val ) {
+ dst->eid_dn = dst->eid_ndn;
+ } else {
+ ber_dupbv_x( &dst->eid_dn, &src->eid_dn, ctx );
+ }
+
+#ifdef BACKSQL_ARBITRARY_KEY
+ ber_dupbv_x( &dst->eid_id, &src->eid_id, ctx );
+ ber_dupbv_x( &dst->eid_keyval, &src->eid_keyval, ctx );
+#else /* ! BACKSQL_ARBITRARY_KEY */
+ dst->eid_id = src->eid_id;
+ dst->eid_keyval = src->eid_keyval;
+#endif /* ! BACKSQL_ARBITRARY_KEY */
+
+ dst->eid_oc_id = src->eid_oc_id;
+
+ return dst;
+}
+
+backsql_entryID *
+backsql_free_entryID( backsql_entryID *id, int freeit, void *ctx )
{
backsql_entryID *next;
if ( !BER_BVISNULL( &id->eid_dn )
&& id->eid_dn.bv_val != id->eid_ndn.bv_val )
{
- op->o_tmpfree( id->eid_dn.bv_val, op->o_tmpmemctx );
+ slap_sl_free( id->eid_dn.bv_val, ctx );
BER_BVZERO( &id->eid_dn );
}
- op->o_tmpfree( id->eid_ndn.bv_val, op->o_tmpmemctx );
+ slap_sl_free( id->eid_ndn.bv_val, ctx );
BER_BVZERO( &id->eid_ndn );
}
#ifdef BACKSQL_ARBITRARY_KEY
if ( !BER_BVISNULL( &id->eid_id ) ) {
- op->o_tmpfree( id->eid_id.bv_val, op->o_tmpmemctx );
+ slap_sl_free( id->eid_id.bv_val, ctx );
BER_BVZERO( &id->eid_id );
}
if ( !BER_BVISNULL( &id->eid_keyval ) ) {
- op->o_tmpfree( id->eid_keyval.bv_val, op->o_tmpmemctx );
+ slap_sl_free( id->eid_keyval.bv_val, ctx );
BER_BVZERO( &id->eid_keyval );
}
#endif /* BACKSQL_ARBITRARY_KEY */
if ( freeit ) {
- op->o_tmpfree( id, op->o_tmpmemctx );
+ slap_sl_free( id, ctx );
}
return next;
ldap_err2string( res ) );
/* cleanup... */
- (void)backsql_free_entryID( op, id, 0 );
+ (void)backsql_free_entryID( id, 0, op->o_tmpmemctx );
}
if ( dn.bv_val != row.cols[ 3 ] ) {
bi->bi_entry_release_rw = backsql_entry_release;
bi->bi_connection_init = 0;
- bi->bi_connection_destroy = backsql_connection_destroy;
Debug( LDAP_DEBUG_TRACE,"<==sql_back_initialize()\n", 0, 0, 0 );
return 0;
Debug( LDAP_DEBUG_TRACE, "==>backsql_db_destroy()\n", 0, 0, 0 );
- ldap_pvt_thread_mutex_lock( &bi->sql_dbconn_mutex );
backsql_free_db_env( bi );
- ldap_pvt_thread_mutex_unlock( &bi->sql_dbconn_mutex );
ldap_pvt_thread_mutex_destroy( &bi->sql_dbconn_mutex );
- ldap_pvt_thread_mutex_lock( &bi->sql_schema_mutex );
backsql_destroy_schema_map( bi );
- ldap_pvt_thread_mutex_unlock( &bi->sql_schema_mutex );
ldap_pvt_thread_mutex_destroy( &bi->sql_schema_mutex );
if ( bi->sql_dbname ) {
if ( !BER_BVISNULL( &bi->sql_children_cond ) ) {
ch_free( bi->sql_children_cond.bv_val );
}
+ if ( !BER_BVISNULL( &bi->sql_dn_match_cond ) ) {
+ ch_free( bi->sql_dn_match_cond.bv_val );
+ }
if ( !BER_BVISNULL( &bi->sql_subtree_cond ) ) {
ch_free( bi->sql_subtree_cond.bv_val );
}
ConfigReply *cr )
{
backsql_info *bi = (backsql_info*)bd->be_private;
- SQLHDBC dbh = SQL_NULL_HDBC;
struct berbuf bb = BB_NULL;
+ Connection conn = { 0 };
OperationBuffer opbuf;
Operation* op;
-
+ SQLHDBC dbh = SQL_NULL_HDBC;
+ void *thrctx = ldap_pvt_thread_pool_context();
+
Debug( LDAP_DEBUG_TRACE, "==>backsql_db_open(): "
"testing RDBMS connection\n", 0, 0, 0 );
if ( bi->sql_dbname == NULL ) {
};
struct berbuf bb = BB_NULL;
+ Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
+ "subtree search SQL condition not specified "
+ "(use \"subtree_cond\" directive in slapd.conf); "
+ "preparing default\n",
+ 0, 0, 0);
+
if ( backsql_prepare_pattern( bi->sql_concat_func, values,
&concat ) ) {
Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
- "unable to prepare CONCAT pattern", 0, 0, 0 );
+ "unable to prepare CONCAT pattern for subtree search",
+ 0, 0, 0 );
return 1;
}
- Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
- "subtree search SQL condition not specified "
- "(use \"subtree_cond\" directive in slapd.conf)\n",
- 0, 0, 0);
-
if ( bi->sql_upper_func.bv_val ) {
/*
bi->sql_subtree_cond = bb.bb_val;
Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
- "setting \"%s\" as default\n",
+ "setting \"%s\" as default \"subtree_cond\"\n",
bi->sql_subtree_cond.bv_val, 0, 0 );
}
if ( bi->sql_children_cond.bv_val == NULL ) {
+ /*
+ * Prepare concat function for children search condition
+ */
+ struct berval concat;
+ struct berval values[] = {
+ BER_BVC( "'%,'" ),
+ BER_BVC( "?" ),
+ BER_BVNULL
+ };
struct berbuf bb = BB_NULL;
+ Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
+ "children search SQL condition not specified "
+ "(use \"children_cond\" directive in slapd.conf); "
+ "preparing default\n",
+ 0, 0, 0);
+
+ if ( backsql_prepare_pattern( bi->sql_concat_func, values,
+ &concat ) ) {
+ Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
+ "unable to prepare CONCAT pattern for children search", 0, 0, 0 );
+ return 1;
+ }
+
if ( bi->sql_upper_func.bv_val ) {
/*
* UPPER(ldap_entries.dn) LIKE UPPER(CONCAT('%,',?))
*/
- backsql_strfcat_x( &bb, NULL, "blbl",
+ backsql_strfcat_x( &bb, NULL, "blbbb",
+ &bi->sql_upper_func,
+ (ber_len_t)STRLENOF( "(ldap_entries.dn) LIKE " ),
+ "(ldap_entries.dn) LIKE ",
+ &bi->sql_upper_func_open,
+ &concat,
+ &bi->sql_upper_func_close );
+
+ } else {
+
+ /*
+ * ldap_entries.dn LIKE CONCAT('%,',?)
+ */
+
+ backsql_strfcat_x( &bb, NULL, "lb",
+ (ber_len_t)STRLENOF( "ldap_entries.dn LIKE " ),
+ "ldap_entries.dn LIKE ",
+ &concat );
+ }
+
+ ch_free( concat.bv_val );
+
+ bi->sql_children_cond = bb.bb_val;
+
+ Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
+ "setting \"%s\" as default \"children_cond\"\n",
+ bi->sql_children_cond.bv_val, 0, 0 );
+ }
+
+ if ( bi->sql_dn_match_cond.bv_val == NULL ) {
+ /*
+ * Prepare concat function for dn match search condition
+ */
+ struct berbuf bb = BB_NULL;
+
+ Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
+ "DN match search SQL condition not specified "
+ "(use \"dn_match_cond\" directive in slapd.conf); "
+ "preparing default\n",
+ 0, 0, 0);
+
+ if ( bi->sql_upper_func.bv_val ) {
+
+ /*
+ * UPPER(ldap_entries.dn)=?
+ */
+
+ backsql_strfcat_x( &bb, NULL, "blbcb",
&bi->sql_upper_func,
(ber_len_t)STRLENOF( "(ldap_entries.dn)=" ),
"(ldap_entries.dn)=",
- &bi->sql_upper_func,
- (ber_len_t)STRLENOF( "(?)" ), "(?)" );
+ &bi->sql_upper_func_open,
+ '?',
+ &bi->sql_upper_func_close );
} else {
/*
- * ldap_entries.dn LIKE CONCAT('%,',?)
+ * ldap_entries.dn=?
*/
backsql_strfcat_x( &bb, NULL, "l",
(ber_len_t)STRLENOF( "ldap_entries.dn=?" ),
- "ldap_entries.dn=?");
+ "ldap_entries.dn=?" );
}
- bi->sql_children_cond = bb.bb_val;
+ bi->sql_dn_match_cond = bb.bb_val;
Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
- "setting \"%s\" as default\n",
- bi->sql_children_cond.bv_val, 0, 0 );
+ "setting \"%s\" as default \"dn_match_cond\"\n",
+ bi->sql_dn_match_cond.bv_val, 0, 0 );
}
if ( bi->sql_oc_query == NULL ) {
}
/* This should just be to force schema loading */
+ connection_fake_init( &conn, &opbuf, thrctx );
op = &opbuf.ob_op;
- op->o_hdr = &opbuf.ob_hdr;
- op->o_connid = (unsigned long)(-1);
op->o_bd = bd;
if ( backsql_get_db_conn( op, &dbh ) != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
"connection failed, exiting\n", 0, 0, 0 );
return 1;
}
-
- if ( backsql_free_db_conn( op ) != SQL_SUCCESS ) {
+ if ( backsql_load_schema_map( bi, dbh ) != LDAP_SUCCESS ) {
+ Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
+ "schema mapping failed, exiting\n", 0, 0, 0 );
+ return 1;
+ }
+ if ( backsql_free_db_conn( op, dbh ) != SQL_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
"connection free failed\n", 0, 0, 0 );
}
}
/*
- * Prepare children ID selection query
+ * Prepare children count query
*/
BER_BVZERO( &bb.bb_val );
bb.bb_len = 0;
"FROM ldap_entries,ldap_entries ",
&bi->sql_aliasing, "subordinates "
"WHERE subordinates.parent=ldap_entries.id AND ",
- &bi->sql_children_cond );
+ &bi->sql_dn_match_cond );
bi->sql_has_children_query = bb.bb_val.bv_val;
/*
return 0;
}
-int
-backsql_connection_destroy( Backend *bd, Connection *c )
-{
- OperationBuffer opbuf;
- Operation* op = &opbuf.ob_op;
-
- op->o_hdr = &opbuf.ob_hdr;
- op->o_connid = c->c_connid;
- op->o_bd = bd;
-
- Debug( LDAP_DEBUG_TRACE, "==>backsql_connection_destroy()\n", 0, 0, 0 );
- backsql_free_db_conn( op );
- Debug( LDAP_DEBUG_TRACE, "<==backsql_connection_destroy()\n", 0, 0, 0 );
-
- return 0;
-}
-
#if SLAPD_SQL == SLAPD_MOD_DYNAMIC
/* conditionally define the init_module() function */
slap_graduate_commit_csn( op );
if ( !BER_BVISNULL( &bsi.bsi_base_id.eid_ndn ) ) {
- (void)backsql_free_entryID( op, &bsi.bsi_base_id, 0 );
+ (void)backsql_free_entryID( &bsi.bsi_base_id, 0, op->o_tmpmemctx );
}
if ( !BER_BVISNULL( &m.e_nname ) ) {
}
if ( newSuperior ) {
- (void)backsql_free_entryID( op, &bsi.bsi_base_id, 0 );
+ (void)backsql_free_entryID( &bsi.bsi_base_id, 0, op->o_tmpmemctx );
/*
* namingContext "" is not supported
char textbuf[ SLAP_TEXT_BUFLEN ] = { '\0' };
backsql_entry_clean( op, &r );
- (void)backsql_free_entryID( op, &e_id, 0 );
+ (void)backsql_free_entryID( &e_id, 0, op->o_tmpmemctx );
bsi.bsi_e = &r;
rs->sr_err = backsql_init_search( &bsi, &new_ndn,
}
if ( !BER_BVISNULL( &e_id.eid_ndn ) ) {
- (void)backsql_free_entryID( op, &e_id, 0 );
+ (void)backsql_free_entryID( &e_id, 0, op->o_tmpmemctx );
}
if ( !BER_BVISNULL( &n_id.eid_ndn ) ) {
- (void)backsql_free_entryID( op, &n_id, 0 );
+ (void)backsql_free_entryID( &n_id, 0, op->o_tmpmemctx );
}
if ( !BER_BVISNULL( &r.e_nname ) ) {
*ap = backsql_operational_entryUUID( bi, &bsi.bsi_base_id );
- (void)backsql_free_entryID( op, &bsi.bsi_base_id, 0 );
+ (void)backsql_free_entryID( &bsi.bsi_base_id, 0, op->o_tmpmemctx );
if ( bsi.bsi_attrs != NULL ) {
op->o_tmpfree( bsi.bsi_attrs, op->o_tmpmemctx );
#endif /* BACKSQL_ARBITRARY_KEY */
/* stores in *id the ID in table ldap_entries corresponding to DN, if any */
-int backsql_dn2id( Operation *op, SlapReply *rs, SQLHDBC dbh,
+extern int
+backsql_dn2id( Operation *op, SlapReply *rs, SQLHDBC dbh,
struct berval *ndn, backsql_entryID *id,
int matched, int muck );
/* stores in *nchildren the count of children for an entry */
-int backsql_count_children( Operation *op, SQLHDBC dbh,
+extern int
+backsql_count_children( Operation *op, SQLHDBC dbh,
struct berval *dn, unsigned long *nchildren );
/* returns LDAP_COMPARE_TRUE/LDAP_COMPARE_FALSE if the entry corresponding
* to DN has/has not children */
-int backsql_has_children( Operation *op, SQLHDBC dbh, struct berval *dn );
+extern int
+backsql_has_children( Operation *op, SQLHDBC dbh, struct berval *dn );
-/* frees *id and returns next in list */
-backsql_entryID *backsql_free_entryID( Operation *op, backsql_entryID *id,
- int freeit );
+/* free *id and return next in list */
+extern backsql_entryID *
+backsql_free_entryID( backsql_entryID *id, int freeit, void *ctx );
-/* turns an ID into an entry */
-int backsql_id2entry( backsql_srch_info *bsi, backsql_entryID *id );
+/* turn an ID into an entry */
+extern int
+backsql_id2entry( backsql_srch_info *bsi, backsql_entryID *id );
+
+/* duplicate an entryID */
+extern backsql_entryID *
+backsql_entryID_dup( backsql_entryID *eid, void *ctx );
/*
* operational.c
int backsql_free_db_env( backsql_info *si );
-int backsql_get_db_conn( Operation *op, SQLHDBC *dbh );
+int backsql_get_db_conn( Operation *op, SQLHDBC *dbh );
-int backsql_free_db_conn( Operation *op );
+int backsql_free_db_conn( Operation *op, SQLHDBC dbh );
/*
* util.c
(ber_len_t)STRLENOF( "9=9"), "9=9");
} else if ( !BER_BVISNULL( &bi->sql_subtree_cond ) ) {
+ /* This should always be true... */
backsql_strfcat_x( &bsi->bsi_join_where,
bsi->bsi_op->o_tmpmemctx,
"b",
{
lowid = PAGECOOKIE_TO_SQL_ID( ((PagedResultsState *)bsi->bsi_op->o_pagedresults_state)->ps_cookie );
}
+
if ( lowid ) {
char lowidstring[48];
int lowidlen;
- lowidlen = snprintf( lowidstring, 48, " AND ldap_entries.id>%d", lowid );
+ lowidlen = snprintf( lowidstring, sizeof( lowidstring ),
+ " AND ldap_entries.id>%lu", lowid );
backsql_strfcat_x( &bsi->bsi_join_where,
bsi->bsi_op->o_tmpmemctx,
"l",
/* If paged results are in effect, check the paging cookie */
if ( get_pagedresults( op ) > SLAP_CONTROL_IGNORED ) {
- PagedResultsState *ps = op->o_pagedresults_state;
rs->sr_err = parse_paged_cookie( op, rs );
if ( rs->sr_err != LDAP_SUCCESS ) {
send_ldap_result( op, rs );
* and then send to client; don't free entry_id if baseObject...
*/
for ( eid = bsi.bsi_id_list;
- eid != NULL;
- eid = backsql_free_entryID( op,
- eid, eid == &bsi.bsi_base_id ? 0 : 1 ) )
+ eid != NULL;
+ eid = backsql_free_entryID(
+ eid, eid == &bsi.bsi_base_id ? 0 : 1, op->o_tmpmemctx ) )
{
int rc;
Attribute *a_hasSubordinate = NULL,
rs->sr_attrs = op->ors_attrs;
rs->sr_operational_attrs = NULL;
rs->sr_entry = e;
+ e->e_private = (void *)eid;
rs->sr_flags = ( e == &user_entry ) ? REP_ENTRY_MODIFIABLE : 0;
/* FIXME: need the whole entry (ITS#3480) */
rs->sr_err = send_search_entry( op, rs );
+ e->e_private = NULL;
rs->sr_entry = NULL;
rs->sr_attrs = NULL;
rs->sr_operational_attrs = NULL;
/* cleanup in case of abandon */
for ( ; eid != NULL;
- eid = backsql_free_entryID( op,
- eid, eid == &bsi.bsi_base_id ? 0 : 1 ) )
+ eid = backsql_free_entryID(
+ eid, eid == &bsi.bsi_base_id ? 0 : 1, op->o_tmpmemctx ) )
;
backsql_entry_clean( op, &base_entry );
#endif /* BACKSQL_SYNCPROV */
done:;
- (void)backsql_free_entryID( op, &bsi.bsi_base_id, 0 );
+ (void)backsql_free_entryID( &bsi.bsi_base_id, 0, op->o_tmpmemctx );
if ( bsi.bsi_attrs != NULL ) {
op->o_tmpfree( bsi.bsi_attrs, op->o_tmpmemctx );
*ent = NULL;
rc = backsql_get_db_conn( op, &dbh );
- if ( !dbh ) {
- return LDAP_OTHER;
+ if ( rc != LDAP_SUCCESS ) {
+ return rc;
}
if ( at ) {
BACKSQL_ISF_GET_ENTRY );
if ( !BER_BVISNULL( &bsi.bsi_base_id.eid_ndn ) ) {
- (void)backsql_free_entryID( op, &bsi.bsi_base_id, 0 );
+ (void)backsql_free_entryID( &bsi.bsi_base_id, 0, op->o_tmpmemctx );
}
if ( rc == LDAP_SUCCESS ) {
#define MAX_ATTR_LEN 16384
-typedef struct backsql_db_conn {
- unsigned long ldap_cid;
- SQLHDBC dbh;
-} backsql_db_conn;
-
void
backsql_PrintErrors( SQLHENV henv, SQLHDBC hdbc, SQLHSTMT sth, int rc )
{
return backsql_FreeRow_x( row, NULL );
}
-static int
-backsql_cmp_connid( const void *v_c1, const void *v_c2 )
-{
- const backsql_db_conn *c1 = v_c1, *c2 = v_c2;
- if ( c1->ldap_cid > c2->ldap_cid ) {
- return 1;
- }
-
- if ( c1->ldap_cid < c2->ldap_cid ) {
- return -1;
- }
-
- return 0;
-}
-
static void
-backsql_close_db_conn( void *v_conn )
+backsql_close_db_handle( SQLHDBC dbh )
{
- backsql_db_conn *conn = (backsql_db_conn *)v_conn;
- unsigned long cid = conn->ldap_cid;
+ if ( dbh == SQL_NULL_HDBC ) {
+ return;
+ }
- Debug( LDAP_DEBUG_TRACE, "==>backsql_close_db_conn(%lu)\n",
- cid, 0, 0 );
+ Debug( LDAP_DEBUG_TRACE, "==>backsql_close_db_handle(%p)\n",
+ (void *)dbh, 0, 0 );
/*
* Default transact is SQL_ROLLBACK; commit is required only
*/
/* TimesTen */
- SQLTransact( SQL_NULL_HENV, conn->dbh, SQL_ROLLBACK );
- SQLDisconnect( conn->dbh );
- SQLFreeConnect( conn->dbh );
- ch_free( conn );
+ SQLTransact( SQL_NULL_HENV, dbh, SQL_ROLLBACK );
+ SQLDisconnect( dbh );
+ SQLFreeConnect( dbh );
- Debug( LDAP_DEBUG_TRACE, "<==backsql_close_db_conn(%lu)\n",
- cid, 0, 0 );
+ Debug( LDAP_DEBUG_TRACE, "<==backsql_close_db_handle(%p)\n",
+ (void *)dbh, 0, 0 );
}
int
backsql_conn_destroy(
backsql_info *bi )
{
- avl_free( bi->sql_db_conns, backsql_close_db_conn );
-
return 0;
}
}
static int
-backsql_open_db_conn( backsql_info *bi, unsigned long ldap_cid, backsql_db_conn **pdbc )
+backsql_open_db_handle(
+ backsql_info *bi,
+ SQLHDBC *dbhp )
{
/* TimesTen */
char DBMSName[ 32 ];
- backsql_db_conn *dbc;
int rc;
- assert( pdbc != NULL );
- *pdbc = NULL;
+ assert( dbhp != NULL );
+ *dbhp = SQL_NULL_HDBC;
- Debug( LDAP_DEBUG_TRACE, "==>backsql_open_db_conn(%lu)\n",
- ldap_cid, 0, 0 );
+ Debug( LDAP_DEBUG_TRACE, "==>backsql_open_db_handle()\n",
+ 0, 0, 0 );
- dbc = (backsql_db_conn *)ch_calloc( 1, sizeof( backsql_db_conn ) );
- dbc->ldap_cid = ldap_cid;
- rc = SQLAllocConnect( bi->sql_db_env, &dbc->dbh );
+ rc = SQLAllocConnect( bi->sql_db_env, dbhp );
if ( !BACKSQL_SUCCESS( rc ) ) {
- Debug( LDAP_DEBUG_TRACE, "backsql_open_db_conn(%lu): "
- "SQLAllocConnect() failed:\n", ldap_cid, 0, 0 );
+ Debug( LDAP_DEBUG_TRACE, "backsql_open_db_handle(): "
+ "SQLAllocConnect() failed:\n",
+ 0, 0, 0 );
backsql_PrintErrors( bi->sql_db_env, SQL_NULL_HDBC,
- SQL_NULL_HENV, rc );
+ SQL_NULL_HENV, rc );
return LDAP_UNAVAILABLE;
}
- rc = SQLConnect( dbc->dbh,
- (SQLCHAR*)bi->sql_dbname, SQL_NTS,
- (SQLCHAR*)bi->sql_dbuser, SQL_NTS,
- (SQLCHAR*)bi->sql_dbpasswd, SQL_NTS );
+ rc = SQLConnect( *dbhp,
+ (SQLCHAR*)bi->sql_dbname, SQL_NTS,
+ (SQLCHAR*)bi->sql_dbuser, SQL_NTS,
+ (SQLCHAR*)bi->sql_dbpasswd, SQL_NTS );
if ( rc != SQL_SUCCESS ) {
- Debug( LDAP_DEBUG_TRACE, "backsql_open_db_conn(%lu): "
+ Debug( LDAP_DEBUG_TRACE, "backsql_open_db_handle(): "
"SQLConnect() to database \"%s\" %s.\n",
- ldap_cid, bi->sql_dbname,
+ bi->sql_dbname,
rc == SQL_SUCCESS_WITH_INFO ?
- "succeeded with info" : "failed" );
- backsql_PrintErrors( bi->sql_db_env, dbc->dbh, SQL_NULL_HENV, rc );
+ "succeeded with info" : "failed",
+ 0 );
+ backsql_PrintErrors( bi->sql_db_env, *dbhp, SQL_NULL_HENV, rc );
if ( rc != SQL_SUCCESS_WITH_INFO ) {
+ SQLFreeConnect( *dbhp );
return LDAP_UNAVAILABLE;
}
}
* TimesTen : Turn off autocommit. We must explicitly
* commit any transactions.
*/
- SQLSetConnectOption( dbc->dbh, SQL_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF );
+ SQLSetConnectOption( *dbhp, SQL_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF );
/*
* See if this connection is to TimesTen. If it is,
/* Assume until proven otherwise */
bi->sql_flags &= ~BSQLF_USE_REVERSE_DN;
DBMSName[ 0 ] = '\0';
- rc = SQLGetInfo( dbc->dbh, SQL_DBMS_NAME, (PTR)&DBMSName,
+ rc = SQLGetInfo( *dbhp, SQL_DBMS_NAME, (PTR)&DBMSName,
sizeof( DBMSName ), NULL );
if ( rc == SQL_SUCCESS ) {
if ( strcmp( DBMSName, "TimesTen" ) == 0 ||
- strcmp( DBMSName, "Front-Tier" ) == 0 ) {
- Debug( LDAP_DEBUG_TRACE, "backsql_open_db_conn(%lu): "
- "TimesTen database!\n", ldap_cid, 0, 0 );
+ strcmp( DBMSName, "Front-Tier" ) == 0 )
+ {
+ Debug( LDAP_DEBUG_TRACE, "backsql_open_db_handle(): "
+ "TimesTen database!\n",
+ 0, 0, 0 );
bi->sql_flags |= BSQLF_USE_REVERSE_DN;
}
+
} else {
- Debug( LDAP_DEBUG_TRACE, "backsql_open_db_conn(%lu): "
- "SQLGetInfo() failed.\n", ldap_cid, 0, 0 );
- backsql_PrintErrors( bi->sql_db_env, dbc->dbh, SQL_NULL_HENV, rc );
- return rc;
+ Debug( LDAP_DEBUG_TRACE, "backsql_open_db_handle(): "
+ "SQLGetInfo() failed.\n",
+ 0, 0, 0 );
+ backsql_PrintErrors( bi->sql_db_env, *dbhp, SQL_NULL_HENV, rc );
+ SQLDisconnect( *dbhp );
+ SQLFreeConnect( *dbhp );
+ return LDAP_UNAVAILABLE;
}
/* end TimesTen */
- Debug( LDAP_DEBUG_TRACE, "backsql_open_db_conn(%lu): "
- "connected, adding to tree.\n", ldap_cid, 0, 0 );
- ldap_pvt_thread_mutex_lock( &bi->sql_dbconn_mutex );
- if ( avl_insert( &bi->sql_db_conns, dbc, backsql_cmp_connid, avl_dup_error ) ) {
- Debug( LDAP_DEBUG_TRACE, "backsql_open_db_conn(%lu): "
- "duplicate connection ID.\n", ldap_cid, 0, 0 );
- return LDAP_OTHER;
- }
- ldap_pvt_thread_mutex_unlock( &bi->sql_dbconn_mutex );
- Debug( LDAP_DEBUG_TRACE, "<==backsql_open_db_conn(%lu)\n", ldap_cid, 0, 0 );
-
- *pdbc = dbc;
+ Debug( LDAP_DEBUG_TRACE, "<==backsql_open_db_handle()\n",
+ 0, 0, 0 );
return LDAP_SUCCESS;
}
int
-backsql_free_db_conn( Operation *op )
+backsql_free_db_conn( Operation *op, SQLHDBC dbh )
{
- backsql_info *bi = (backsql_info *)op->o_bd->be_private;
- backsql_db_conn tmp = { 0 },
- *conn;
-
Debug( LDAP_DEBUG_TRACE, "==>backsql_free_db_conn()\n", 0, 0, 0 );
- tmp.ldap_cid = op->o_connid;
- ldap_pvt_thread_mutex_lock( &bi->sql_dbconn_mutex );
- conn = avl_delete( &bi->sql_db_conns, &tmp, backsql_cmp_connid );
- ldap_pvt_thread_mutex_unlock( &bi->sql_dbconn_mutex );
- /*
- * we have one thread per connection, as I understand -- so we can
- * get this out of critical section
- */
- if ( conn != NULL ) {
- Debug( LDAP_DEBUG_TRACE, "backsql_free_db_conn(): "
- "closing db connection %lu (%p)\n",
- op->o_connid, (void *)conn, 0 );
- backsql_close_db_conn( (void *)conn );
- }
+ (void)backsql_close_db_handle( dbh );
Debug( LDAP_DEBUG_TRACE, "<==backsql_free_db_conn()\n", 0, 0, 0 );
- return conn ? SQL_SUCCESS : SQL_ERROR;
+ return LDAP_SUCCESS;
+}
+
+static void *backsql_db_conn_dummy;
+
+static void
+backsql_db_conn_keyfree(
+ void *key,
+ void *data )
+{
+ backsql_close_db_handle( (SQLHDBC)data );
}
int
-backsql_get_db_conn( Operation *op, SQLHDBC *dbh )
+backsql_get_db_conn( Operation *op, SQLHDBC *dbhp )
{
- backsql_info *bi = (backsql_info *)op->o_bd->be_private;
- backsql_db_conn *dbc,
- tmp = { 0 };
- int rc = LDAP_SUCCESS;
+ backsql_info *bi = (backsql_info *)op->o_bd->be_private;
+ int rc = LDAP_SUCCESS;
+ SQLHDBC dbh = SQL_NULL_HDBC;
Debug( LDAP_DEBUG_TRACE, "==>backsql_get_db_conn()\n", 0, 0, 0 );
- assert( dbh != NULL );
- *dbh = SQL_NULL_HDBC;
+ assert( dbhp != NULL );
+ *dbhp = SQL_NULL_HDBC;
- tmp.ldap_cid = op->o_connid;
+ if ( op->o_threadctx ) {
+ void *data = NULL;
- /*
- * we have one thread per connection, as I understand --
- * so we do not need locking here
- */
- dbc = avl_find( bi->sql_db_conns, &tmp, backsql_cmp_connid );
- if ( !dbc ) {
- rc = backsql_open_db_conn( bi, op->o_connid, &dbc );
- if ( rc != LDAP_SUCCESS) {
- Debug( LDAP_DEBUG_TRACE, "backsql_get_db_conn(): "
- "could not get connection handle "
- "-- returning NULL\n", 0, 0, 0 );
- return rc;
- }
+ ldap_pvt_thread_pool_getkey( op->o_threadctx,
+ &backsql_db_conn_dummy, &data, NULL );
+ dbh = (SQLHDBC)data;
+
+ } else {
+ dbh = bi->sql_dbh;
}
- ldap_pvt_thread_mutex_lock( &bi->sql_schema_mutex );
- if ( !BACKSQL_SCHEMA_LOADED( bi ) ) {
- Debug( LDAP_DEBUG_TRACE, "backsql_get_db_conn(): "
- "first call -- reading schema map\n", 0, 0, 0 );
- rc = backsql_load_schema_map( bi, dbc->dbh );
+ if ( dbh == SQL_NULL_HDBC ) {
+ rc = backsql_open_db_handle( bi, &dbh );
if ( rc != LDAP_SUCCESS ) {
- ldap_pvt_thread_mutex_unlock( &bi->sql_schema_mutex );
- backsql_free_db_conn( op );
return rc;
}
+
+ if ( op->o_threadctx ) {
+ void *data = NULL;
+
+ data = (void *)dbh;
+ ldap_pvt_thread_pool_setkey( op->o_threadctx,
+ &backsql_db_conn_dummy, data,
+ backsql_db_conn_keyfree );
+
+ } else {
+ bi->sql_dbh = dbh;
+ }
}
- ldap_pvt_thread_mutex_unlock( &bi->sql_schema_mutex );
- *dbh = dbc->dbh;
+ *dbhp = dbh;
Debug( LDAP_DEBUG_TRACE, "<==backsql_get_db_conn()\n", 0, 0, 0 );