]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/back-sql/entry-id.c
slapi_ch_bvdup() should be implemented in terms of ber_dupbv()
[openldap] / servers / slapd / back-sql / entry-id.c
index 49d3346c7e5715d73f6dc1741ae93f60c057a98b..0e17f1c1f860e0cceaa3306c7e816458e6ce68d3 100644 (file)
@@ -1,7 +1,7 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 1999-2005 The OpenLDAP Foundation.
+ * Copyright 1999-2006 The OpenLDAP Foundation.
  * Portions Copyright 1999 Dmitry Kovalev.
  * Portions Copyright 2002 Pierangelo Masarati.
  * Portions Copyright 2004 Mark Adamson.
@@ -27,6 +27,7 @@
 #include <sys/types.h>
 #include "ac/string.h"
 
+#include "lutil.h"
 #include "slap.h"
 #include "proto-sql.h"
 
@@ -39,7 +40,7 @@ backsql_free_entryID( Operation *op, backsql_entryID *id, int freeit )
 {
        backsql_entryID         *next;
 
-       assert( id );
+       assert( id != NULL );
 
        next = id->eid_next;
 
@@ -154,7 +155,7 @@ backsql_dn2id(
        /* begin TimesTen */
        Debug( LDAP_DEBUG_TRACE, "   backsql_dn2id(\"%s\"): id_query \"%s\"\n",
                        ndn->bv_val, bi->sql_id_query, 0 );
-       assert( bi->sql_id_query );
+       assert( bi->sql_id_query != NULL );
        rc = backsql_Prepare( dbh, &sth, bi->sql_id_query, 0 );
        if ( rc != SQL_SUCCESS ) {
                Debug( LDAP_DEBUG_TRACE, 
@@ -231,7 +232,7 @@ backsql_dn2id(
                goto done;
        }
 
-       backsql_BindRowAsStrings( sth, &row );
+       backsql_BindRowAsStrings_x( sth, &row, op->o_tmpmemctx );
        rc = SQLFetch( sth );
        if ( BACKSQL_SUCCESS( rc ) ) {
                char    buf[ SLAP_TEXT_BUFLEN ];
@@ -250,43 +251,52 @@ backsql_dn2id(
                if ( id != NULL ) {
                        struct berval   dn;
 
+                       id->eid_next = NULL;
+
 #ifdef BACKSQL_ARBITRARY_KEY
                        ber_str2bv_x( row.cols[ 0 ], 0, 1, &id->eid_id,
                                        op->o_tmpmemctx );
                        ber_str2bv_x( row.cols[ 1 ], 0, 1, &id->eid_keyval,
                                        op->o_tmpmemctx );
 #else /* ! BACKSQL_ARBITRARY_KEY */
-                       id->eid_id = strtol( row.cols[ 0 ], NULL, 0 );
-                       id->eid_keyval = strtol( row.cols[ 1 ], NULL, 0 );
+                       if ( lutil_atoulx( &id->eid_id, row.cols[ 0 ], 0 ) != 0 ) {
+                               res = LDAP_OTHER;
+                               goto done;
+                       }
+                       if ( lutil_atoulx( &id->eid_keyval, row.cols[ 1 ], 0 ) != 0 ) {
+                               res = LDAP_OTHER;
+                               goto done;
+                       }
 #endif /* ! BACKSQL_ARBITRARY_KEY */
-                       id->eid_oc_id = strtol( row.cols[ 2 ], NULL, 0 );
+                       if ( lutil_atoulx( &id->eid_oc_id, row.cols[ 2 ], 0 ) != 0 ) {
+                               res = LDAP_OTHER;
+                               goto done;
+                       }
 
                        ber_str2bv( row.cols[ 3 ], 0, 0, &dn );
 
                        if ( backsql_api_odbc2dn( op, rs, &dn ) ) {
                                res = LDAP_OTHER;
-
-                       } else {
-                               res = dnPrettyNormal( NULL, &dn,
-                                               &id->eid_dn, &id->eid_ndn,
-                                               op->o_tmpmemctx );
-                               if ( res != LDAP_SUCCESS ) {
-                                       Debug( LDAP_DEBUG_TRACE,
-                                               "   backsql_dn2id(\"%s\"): "
-                                               "dnPrettyNormal failed (%d: %s)\n",
-                                               realndn.bv_val, res,
-                                               ldap_err2string( res ) );
-
-                                       /* cleanup... */
-                                       (void)backsql_free_entryID( op, id, 0 );
-                               }
-
-                               if ( dn.bv_val != row.cols[ 3 ] ) {
-                                       free( dn.bv_val );
-                               }
+                               goto done;
+                       }
+                       
+                       res = dnPrettyNormal( NULL, &dn,
+                                       &id->eid_dn, &id->eid_ndn,
+                                       op->o_tmpmemctx );
+                       if ( res != LDAP_SUCCESS ) {
+                               Debug( LDAP_DEBUG_TRACE,
+                                       "   backsql_dn2id(\"%s\"): "
+                                       "dnPrettyNormal failed (%d: %s)\n",
+                                       realndn.bv_val, res,
+                                       ldap_err2string( res ) );
+
+                               /* cleanup... */
+                               (void)backsql_free_entryID( op, id, 0 );
                        }
 
-                       id->eid_next = NULL;
+                       if ( dn.bv_val != row.cols[ 3 ] ) {
+                               free( dn.bv_val );
+                       }
                }
 
        } else {
@@ -324,9 +334,10 @@ backsql_dn2id(
                        }
                }
        }
-       backsql_FreeRow( &row );
 
 done:;
+       backsql_FreeRow_x( &row, op->o_tmpmemctx );
+
        Debug( LDAP_DEBUG_TRACE,
                "<==backsql_dn2id(\"%s\"): err=%d\n",
                ndn->bv_val, res, 0 );
@@ -343,11 +354,12 @@ done:;
 
 int
 backsql_count_children(
-       backsql_info            *bi,
+       Operation               *op,
        SQLHDBC                 dbh,
        struct berval           *dn,
        unsigned long           *nchildren )
 {
+       backsql_info            *bi = (backsql_info *)op->o_bd->be_private;
        SQLHSTMT                sth = SQL_NULL_HSTMT;
        BACKSQL_ROW_NTS         row;
        RETCODE                 rc;
@@ -367,7 +379,7 @@ backsql_count_children(
        /* begin TimesTen */
        Debug(LDAP_DEBUG_TRACE, "children id query \"%s\"\n", 
                        bi->sql_has_children_query, 0, 0);
-       assert( bi->sql_has_children_query );
+       assert( bi->sql_has_children_query != NULL );
        rc = backsql_Prepare( dbh, &sth, bi->sql_has_children_query, 0 );
        if ( rc != SQL_SUCCESS ) {
                Debug( LDAP_DEBUG_TRACE, 
@@ -399,24 +411,41 @@ backsql_count_children(
                return LDAP_OTHER;
        }
 
-       backsql_BindRowAsStrings( sth, &row );
+       backsql_BindRowAsStrings_x( sth, &row, op->o_tmpmemctx );
        
        rc = SQLFetch( sth );
        if ( BACKSQL_SUCCESS( rc ) ) {
                char *end;
 
                *nchildren = strtol( row.cols[ 0 ], &end, 0 );
-               if ( end[ 0 ] != '\0' && end[0] != '.' ) {
-                       /* FIXME: braindead RDBMSes return
-                        * a fractional number from COUNT!
-                        */
+               if ( end == row.cols[ 0 ] ) {
                        res = LDAP_OTHER;
+
+               } else {
+                       switch ( end[ 0 ] ) {
+                       case '\0':
+                               break;
+
+                       case '.': {
+                               unsigned long   ul;
+
+                               /* FIXME: braindead RDBMSes return
+                                * a fractional number from COUNT!
+                                */
+                               if ( lutil_atoul( &ul, end + 1 ) != 0 || ul != 0 ) {
+                                       res = LDAP_OTHER;
+                               }
+                               } break;
+
+                       default:
+                               res = LDAP_OTHER;
+                       }
                }
 
        } else {
                res = LDAP_OTHER;
        }
-       backsql_FreeRow( &row );
+       backsql_FreeRow_x( &row, op->o_tmpmemctx );
 
        SQLFreeStmt( sth, SQL_DROP );
 
@@ -428,14 +457,14 @@ backsql_count_children(
 
 int
 backsql_has_children(
-       backsql_info            *bi,
+       Operation               *op,
        SQLHDBC                 dbh,
        struct berval           *dn )
 {
        unsigned long   nchildren;
        int             rc;
 
-       rc = backsql_count_children( bi, dbh, dn, &nchildren );
+       rc = backsql_count_children( op, dbh, dn, &nchildren );
 
        if ( rc == LDAP_SUCCESS ) {
                return nchildren > 0 ? LDAP_COMPARE_TRUE : LDAP_COMPARE_FALSE;
@@ -455,11 +484,13 @@ backsql_get_attr_vals( void *v_at, void *v_bsi )
        BACKSQL_ROW_NTS         row;
        unsigned long           i,
                                k = 0,
-                               oldcount = 0;
+                               oldcount = 0,
+                               res = 0;
 #ifdef BACKSQL_COUNTQUERY
-       unsigned long           count,
-                               countsize = sizeof( count ),
-                               j;
+       unsigned                count,
+                               j,
+                               append = 0;
+       SQLLEN                  countsize = sizeof( count );
        Attribute               *attr = NULL;
 
        slap_mr_normalize_func          *normfunc = NULL;
@@ -469,8 +500,8 @@ backsql_get_attr_vals( void *v_at, void *v_bsi )
        slap_syntax_transform_func      *pretty = NULL;
 #endif /* BACKSQL_PRETTY_VALIDATE */
 
-       assert( at );
-       assert( bsi );
+       assert( at != NULL );
+       assert( bsi != NULL );
 
 #ifdef BACKSQL_ARBITRARY_KEY
        Debug( LDAP_DEBUG_TRACE, "==>backsql_get_attr_vals(): "
@@ -546,7 +577,7 @@ backsql_get_attr_vals( void *v_at, void *v_bsi )
        }
 
        Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
-               "number of values in query: %d\n", count, 0, 0 );
+               "number of values in query: %u\n", count, 0, 0 );
        SQLFreeStmt( sth, SQL_DROP );
        if ( count == 0 ) {
                return 1;
@@ -581,7 +612,7 @@ backsql_get_attr_vals( void *v_at, void *v_bsi )
                }
 
        } else {
-               Attribute       **ap;
+               append = 1;
 
                /* Make space for the array of values */
                attr = (Attribute *) ch_malloc( sizeof( Attribute ) );
@@ -609,10 +640,6 @@ backsql_get_attr_vals( void *v_at, void *v_bsi )
                } else {
                        attr->a_nvals = attr->a_vals;
                }
-
-               for ( ap = &bsi->bsi_e->e_attrs; (*ap) != NULL; ap = &(*ap)->a_next )
-                       /* goto last */ ;
-               *ap =  attr;
        }
 #endif /* BACKSQL_COUNTQUERY */
 
@@ -621,6 +648,11 @@ backsql_get_attr_vals( void *v_at, void *v_bsi )
                Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
                        "error preparing query: %s\n", at->bam_query, 0, 0 );
                backsql_PrintErrors( bi->sql_db_env, bsi->bsi_dbh, sth, rc );
+#ifdef BACKSQL_COUNTQUERY
+               if ( append ) {
+                       attr_free( attr );
+               }
+#endif /* BACKSQL_COUNTQUERY */
                return 1;
        }
 
@@ -629,6 +661,11 @@ backsql_get_attr_vals( void *v_at, void *v_bsi )
        if ( rc != SQL_SUCCESS ) {
                Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
                        "error binding key value parameter\n", 0, 0, 0 );
+#ifdef BACKSQL_COUNTQUERY
+               if ( append ) {
+                       attr_free( attr );
+               }
+#endif /* BACKSQL_COUNTQUERY */
                return 1;
        }
 
@@ -651,10 +688,15 @@ backsql_get_attr_vals( void *v_at, void *v_bsi )
                        at->bam_query, 0, 0 );
                backsql_PrintErrors( bi->sql_db_env, bsi->bsi_dbh, sth, rc );
                SQLFreeStmt( sth, SQL_DROP );
+#ifdef BACKSQL_COUNTQUERY
+               if ( append ) {
+                       attr_free( attr );
+               }
+#endif /* BACKSQL_COUNTQUERY */
                return 1;
        }
 
-       backsql_BindRowAsStrings( sth, &row );
+       backsql_BindRowAsStrings_x( sth, &row, bsi->bsi_op->o_tmpmemctx );
 #ifdef BACKSQL_COUNTQUERY
        j = oldcount;
 #endif /* BACKSQL_COUNTQUERY */
@@ -662,7 +704,7 @@ backsql_get_attr_vals( void *v_at, void *v_bsi )
                        BACKSQL_SUCCESS( rc );
                        rc = SQLFetch( sth ), k++ )
        {
-               for ( i = 0; i < row.ncols; i++ ) {
+               for ( i = 0; i < (unsigned long)row.ncols; i++ ) {
 
                        if ( row.value_len[ i ] > 0 ) {
                                struct berval           bv;
@@ -679,7 +721,8 @@ backsql_get_attr_vals( void *v_at, void *v_bsi )
                                                "in schema (%d)\n",
                                                bsi->bsi_e->e_name.bv_val,
                                                row.col_names[ i ].bv_val, retval );
-                                       return 1;
+                                       res = 1;
+                                       goto done;
                                }
 
                                if ( ad != at->bam_ad ) {
@@ -690,7 +733,8 @@ backsql_get_attr_vals( void *v_at, void *v_bsi )
                                                bsi->bsi_e->e_name.bv_val,
                                                ad->ad_cname.bv_val,
                                                at->bam_ad->ad_cname.bv_val );
-                                       return 1;
+                                       res = 1;
+                                       goto done;
                                }
 #endif /* BACKSQL_TRACE */
 
@@ -720,11 +764,11 @@ backsql_get_attr_vals( void *v_at, void *v_bsi )
                                         * but we're accepting the attributes;
                                         * should we fail at all? */
                                        snprintf( buf, sizeof( buf ),
-                                                       "unable to %s value #%d "
+                                                       "unable to %s value #%lu "
                                                        "of AttributeDescription %s",
                                                        pretty ? "prettify" : "validate",
-                                                       at->bam_ad->ad_cname.bv_val,
-                                                       k - oldcount );
+                                                       k - oldcount,
+                                                       at->bam_ad->ad_cname.bv_val );
                                        Debug( LDAP_DEBUG_TRACE,
                                                "==>backsql_get_attr_vals(\"%s\"): "
                                                "%s (%d)\n",
@@ -755,10 +799,10 @@ backsql_get_attr_vals( void *v_at, void *v_bsi )
                                                 * but we're accepting the attributes;
                                                 * should we fail at all? */
                                                snprintf( buf, sizeof( buf ),
-                                                       "unable to normalize value #%d "
+                                                       "unable to normalize value #%lu "
                                                        "of AttributeDescription %s",
-                                                       at->bam_ad->ad_cname.bv_val,
-                                                       k - oldcount );
+                                                       k - oldcount,
+                                                       at->bam_ad->ad_cname.bv_val );
                                                Debug( LDAP_DEBUG_TRACE,
                                                        "==>backsql_get_attr_vals(\"%s\"): "
                                                        "%s (%d)\n",
@@ -804,15 +848,35 @@ backsql_get_attr_vals( void *v_at, void *v_bsi )
                }
        }
 
-       backsql_FreeRow( &row );
+#ifdef BACKSQL_COUNTQUERY
+       if ( BER_BVISNULL( &attr->a_vals[ 0 ] ) ) {
+               /* don't leave around attributes with no values */
+               attr_free( attr );
+
+       } else if ( append ) {
+               Attribute       **ap;
+
+               for ( ap = &bsi->bsi_e->e_attrs; (*ap) != NULL; ap = &(*ap)->a_next )
+                       /* goto last */ ;
+               *ap =  attr;
+       }
+#endif /* BACKSQL_COUNTQUERY */
+
        SQLFreeStmt( sth, SQL_DROP );
        Debug( LDAP_DEBUG_TRACE, "<==backsql_get_attr_vals()\n", 0, 0, 0 );
 
        if ( at->bam_next ) {
-               return backsql_get_attr_vals( at->bam_next, v_bsi );
+               res = backsql_get_attr_vals( at->bam_next, v_bsi );
+       } else {
+               res = 1;
        }
 
-       return 1;
+#ifdef BACKSQL_TRACE
+done:;
+#endif /* BACKSQL_TRACE */
+       backsql_FreeRow_x( &row, bsi->bsi_op->o_tmpmemctx );
+
+       return res;
 }
 
 int
@@ -825,7 +889,7 @@ backsql_id2entry( backsql_srch_info *bsi, backsql_entryID *eid )
 
        Debug( LDAP_DEBUG_TRACE, "==>backsql_id2entry()\n", 0, 0, 0 );
 
-       assert( bsi->bsi_e );
+       assert( bsi->bsi_e != NULL );
 
        memset( bsi->bsi_e, 0, sizeof( Entry ) );
 
@@ -862,7 +926,7 @@ backsql_id2entry( backsql_srch_info *bsi, backsql_entryID *eid )
                        &bsi->bsi_oc->bom_oc->soc_cname,
                        bsi->bsi_op->o_tmpmemctx );
        if ( rc != LDAP_SUCCESS ) {
-               entry_clean( bsi->bsi_e );
+               backsql_entry_clean( op, bsi->bsi_e );
                return rc;
        }
 
@@ -966,7 +1030,7 @@ next:;
                                        "structural_class() failed %d (%s)\n",
                                        bsi->bsi_e->e_name.bv_val,
                                        rc, text ? text : "" );
-                               entry_clean( bsi->bsi_e );
+                               backsql_entry_clean( op, bsi->bsi_e );
                                return rc;
                        }
 
@@ -977,7 +1041,7 @@ next:;
                                        "to entry\n",
                                        bsi->bsi_e->e_name.bv_val, soc.bv_val,
                                        bsi->bsi_oc->bom_oc->soc_cname.bv_val );
-                               entry_clean( bsi->bsi_e );
+                               backsql_entry_clean( op, bsi->bsi_e );
                                return rc;
                        }
                }
@@ -987,7 +1051,7 @@ next:;
                                &bsi->bsi_oc->bom_oc->soc_cname,
                                bsi->bsi_op->o_tmpmemctx );
                if ( rc != LDAP_SUCCESS ) {
-                       entry_clean( bsi->bsi_e );
+                       backsql_entry_clean( op, bsi->bsi_e );
                        return rc;
                }
        }