]> git.sur5r.net Git - openldap/commitdiff
rework connections so that they get cached on a per-thread basis (ITS#5095)
authorPierangelo Masarati <ando@openldap.org>
Mon, 20 Aug 2007 00:27:47 +0000 (00:27 +0000)
committerPierangelo Masarati <ando@openldap.org>
Mon, 20 Aug 2007 00:27:47 +0000 (00:27 +0000)
14 files changed:
servers/slapd/back-sql/add.c
servers/slapd/back-sql/back-sql.h
servers/slapd/back-sql/bind.c
servers/slapd/back-sql/compare.c
servers/slapd/back-sql/config.c
servers/slapd/back-sql/delete.c
servers/slapd/back-sql/entry-id.c
servers/slapd/back-sql/init.c
servers/slapd/back-sql/modify.c
servers/slapd/back-sql/modrdn.c
servers/slapd/back-sql/operational.c
servers/slapd/back-sql/proto-sql.h
servers/slapd/back-sql/search.c
servers/slapd/back-sql/sql-wrap.c

index ed10958b67c0df14d452773f34b15eb3a16f2a22..501c8bfd9693e73f8891a3672448753e1b509b52 100644 (file)
@@ -1520,7 +1520,7 @@ done:;
        }
 
        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 ) ) {
index 6965e3f5c9cf86f5949e933815cb3bc66e3019cb..7f336724eea5400747f33bcbaabaa5c1071f38a1 100644 (file)
@@ -473,14 +473,16 @@ typedef struct backsql_info {
         */
        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;
@@ -558,9 +560,10 @@ typedef struct backsql_info {
 #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;
 
index 4c8f710c0bdf59ff76b679b7af389536137bf47b..e76b8dbca6be5b30764ebad2c1afeaf1b2616842 100644 (file)
@@ -53,7 +53,7 @@ backsql_bind( Operation *op, SlapReply *rs )
        }
 
        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 );
@@ -94,7 +94,7 @@ backsql_bind( Operation *op, SlapReply *rs )
 
 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 ) ) {
index 8ac1d96b041612d99fa796ab2ef2348c604bc93c..24fe2e9fb126ffcef5ec54bff196ba34d957e0ef 100644 (file)
@@ -42,7 +42,7 @@ backsql_compare( Operation *op, SlapReply *rs )
        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 );
@@ -173,7 +173,7 @@ return_results:;
        }
 
        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 ) ) {
index e9857fa760c19ac09c1c3b791d63809a0bc099d4..db1170c884bc6b331ad1d65897ba13ca18de9eaf 100644 (file)
@@ -148,7 +148,20 @@ backsql_db_config(
                }
                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 ) {
index 2bfddfda6cefb22a0ebafe900391aa60c402ae71..8b3ec7c2ed881025abb679f6ecaf2c9ee1996571 100644 (file)
@@ -235,7 +235,7 @@ backsql_delete( Operation *op, SlapReply *rs )
                        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, 
@@ -472,7 +472,7 @@ done:;
        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 ) ) {
index 22aca8c01d39d045c90492e2a4c863291934e590..b86fc477a5372d251563e84dadf27c0feb1a9677 100644 (file)
@@ -36,7 +36,35 @@ struct berval backsql_baseObject_bv = BER_BVC( BACKSQL_BASEOBJECT_IDSTR );
 #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;
 
@@ -48,28 +76,28 @@ backsql_free_entryID( Operation *op, backsql_entryID *id, int freeit )
                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;
@@ -291,7 +319,7 @@ backsql_dn2id(
                                        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 ] ) {
index c317d3cb708407184ca166533ce7a6b22bbad6db..5f6bd0c2b848f16ce889c2dd607514cf46976afa 100644 (file)
@@ -77,7 +77,6 @@ sql_back_initialize(
        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;
@@ -126,13 +125,9 @@ backsql_db_destroy(
  
        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 ) {
@@ -161,6 +156,9 @@ backsql_db_destroy(
        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 );
        }
@@ -224,12 +222,14 @@ backsql_db_open(
        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 ) {
@@ -320,18 +320,20 @@ backsql_db_open(
                };
                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 ) {
 
                        /*
@@ -363,42 +365,112 @@ backsql_db_open(
                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 ) {
@@ -474,17 +546,20 @@ backsql_db_open(
        }
 
        /* 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 );
        }
@@ -528,7 +603,7 @@ backsql_db_open(
        }
 
        /*
-        * Prepare children ID selection query
+        * Prepare children count query
         */
        BER_BVZERO( &bb.bb_val );
        bb.bb_len = 0;
@@ -537,7 +612,7 @@ backsql_db_open(
                        "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;
  
        /*
@@ -583,23 +658,6 @@ backsql_db_close(
        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 */
index cbd261dc4635ebc65025414a7534ddddad9ed99e..0d84b3fef551a71e9b167d7c2bf150ddb8e2a0a1 100644 (file)
@@ -197,7 +197,7 @@ done:;
        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 ) ) {
index 4634078fdd57eef891ce375e16b4629c8754abf5..92613faba84ded8bce5df832c6f98b55cf6c3676 100644 (file)
@@ -197,7 +197,7 @@ backsql_modrdn( Operation *op, SlapReply *rs )
        }
 
        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
@@ -407,7 +407,7 @@ backsql_modrdn( Operation *op, SlapReply *rs )
                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,
@@ -510,11 +510,11 @@ done:;
        }
        
        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 ) ) {
index 60252f6d49f3c129bae71b0c03bc8e09b46e47e0..f6fe6aea4ff06f768f96c3286e6c6dd06ccc9cdd 100644 (file)
@@ -189,7 +189,7 @@ backsql_operational(
 
                *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 );
index 78b9251556bab10f07ba54de97cf797bc8e86d32..3af14d5ee0c63cc463639ff158db184856473433 100644 (file)
@@ -111,24 +111,32 @@ extern struct berval      backsql_baseObject_bv;
 #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
@@ -219,9 +227,9 @@ int backsql_init_db_env( backsql_info *si );
 
 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
index 93b7156ad016cb180eaac4eb4325b905d25c23e4..db0ccb580e3657587ddd644c036719efe5c0f43e 100644 (file)
@@ -1512,6 +1512,7 @@ backsql_srch_query( backsql_srch_info *bsi, struct berval *query )
                                        (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",
@@ -1548,11 +1549,13 @@ backsql_srch_query( backsql_srch_info *bsi, struct berval *query )
                {
                        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",
@@ -2112,7 +2115,6 @@ backsql_search( Operation *op, SlapReply *rs )
 
        /* 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 );
@@ -2175,9 +2177,9 @@ backsql_search( Operation *op, SlapReply *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,
@@ -2405,9 +2407,11 @@ backsql_search( Operation *op, SlapReply *rs )
                        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;
@@ -2456,8 +2460,8 @@ send_results:;
 
        /* 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 );
@@ -2495,7 +2499,7 @@ send_results:;
 #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 );
@@ -2538,8 +2542,8 @@ backsql_entry_get(
        *ent = NULL;
 
        rc = backsql_get_db_conn( op, &dbh );
-       if ( !dbh ) {
-               return LDAP_OTHER;
+       if ( rc != LDAP_SUCCESS ) {
+               return rc;
        }
 
        if ( at ) {
@@ -2557,7 +2561,7 @@ backsql_entry_get(
                        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 ) {
index 810fc6a4d8da8734b8f18f556444023372101d8f..5e40dc2a7bea1d92968b2e37977f61705b4e9246 100644 (file)
 
 #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 )
 {
@@ -310,29 +305,15 @@ backsql_FreeRow( BACKSQL_ROW_NTS *row )
        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
@@ -341,21 +322,18 @@ backsql_close_db_conn( void *v_conn )
         */
 
        /* 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;
 }
 
@@ -400,42 +378,44 @@ backsql_free_db_env( backsql_info *bi )
 }
 
 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;
                }
        }
@@ -444,7 +424,7 @@ backsql_open_db_conn( backsql_info *bi, unsigned long ldap_cid, backsql_db_conn
         * 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,
@@ -453,112 +433,100 @@ backsql_open_db_conn( backsql_info *bi, unsigned long ldap_cid, backsql_db_conn
        /* 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 );