]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/back-sql/operational.c
remove unnecessary data from search_info
[openldap] / servers / slapd / back-sql / operational.c
index 7f701857347dba94358876acfdcfdd9925c3bce3..6edde629ca61613ace4f92c219973a02bc32759c 100644 (file)
@@ -1,8 +1,9 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 1999-2004 The OpenLDAP Foundation.
+ * Copyright 1999-2005 The OpenLDAP Foundation.
  * Portions Copyright 1999 Dmitry Kovalev.
+ * Portions Copyright 2002 Pierangelo Masarati.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  */
 /* ACKNOWLEDGEMENTS:
  * This work was initially developed by Dmitry Kovalev for inclusion
- * by OpenLDAP Software.
+ * by OpenLDAP Software.  Additional significant contributors include
+ * Pierangelo Masarati.
  */
 
 #include "portable.h"
 
-#ifdef SLAPD_SQL
-
 #include <stdio.h>
 #include <sys/types.h>
 
 #include "slap.h"
 #include "proto-sql.h"
+#include "lutil.h"
 
 /*
  * sets the supported operational attributes (if required)
  */
 
+Attribute *
+backsql_operational_entryUUID( backsql_info *bi, backsql_entryID *id )
+{
+       int                     rc;
+       struct berval           val, nval;
+       AttributeDescription    *desc = slap_schema.si_ad_entryUUID;
+       Attribute               *a;
+
+       backsql_entryUUID( bi, id, &val, NULL );
+
+       rc = (*desc->ad_type->sat_equality->smr_normalize)(
+                       SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
+                       desc->ad_type->sat_syntax,
+                       desc->ad_type->sat_equality,
+                       &val, &nval, NULL );
+       if ( rc != LDAP_SUCCESS ) {
+               ber_memfree( val.bv_val );
+               return NULL;
+       }
+
+       a = ch_malloc( sizeof( Attribute ) );
+       a->a_desc = desc;
+
+       a->a_vals = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
+       a->a_vals[ 0 ] = val;
+       BER_BVZERO( &a->a_vals[ 1 ] );
+
+       a->a_nvals = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
+       a->a_nvals[ 0 ] = nval;
+       BER_BVZERO( &a->a_nvals[ 1 ] );
+       
+       a->a_next = NULL;
+       a->a_flags = 0;
+
+       return a;
+}
+
+Attribute *
+backsql_operational_entryCSN( Operation *op )
+{
+       char            csnbuf[ LDAP_LUTIL_CSNSTR_BUFSIZE ];
+       struct berval   entryCSN;
+       Attribute       *a;
+
+       a = ch_malloc( sizeof( Attribute ) );
+       a->a_desc = slap_schema.si_ad_entryCSN;
+       a->a_vals = ch_malloc( 2 * sizeof( struct berval ) );
+       BER_BVZERO( &a->a_vals[ 1 ] );
+
+#ifdef BACKSQL_SYNCPROV
+       if ( op->o_sync && op->o_tag == LDAP_REQ_SEARCH ) {
+               assert( op->o_private != NULL );
+
+               entryCSN = *((struct berval *)op->o_private);
+
+       } else
+#endif /* BACKSQL_SYNCPROV */
+       {
+               slap_get_csn( op, csnbuf, sizeof(csnbuf), &entryCSN, 0 );
+       }
+
+       ber_dupbv( &a->a_vals[ 0 ], &entryCSN );
+
+       a->a_nvals = a->a_vals;
+
+       a->a_next = NULL;
+       a->a_flags = 0;
+
+       return a;
+}
+
 int
 backsql_operational(
        Operation       *op,
@@ -42,31 +114,57 @@ backsql_operational(
        SQLHDBC         dbh = SQL_NULL_HDBC;
        int             rc = 0;
        Attribute       **ap;
+       enum {
+               BACKSQL_OP_HASSUBORDINATES = 0,
+               BACKSQL_OP_ENTRYUUID,
+               BACKSQL_OP_ENTRYCSN,
+
+               BACKSQL_OP_LAST
+       };
+       int             get_conn = BACKSQL_OP_LAST,
+                       got[ BACKSQL_OP_LAST ] = { 0 };
 
        Debug( LDAP_DEBUG_TRACE, "==>backsql_operational(): entry \"%s\"\n",
                        rs->sr_entry->e_nname.bv_val, 0, 0 );
 
-       for ( ap = &rs->sr_operational_attrs; *ap; ap = &(*ap)->a_next )
-               /* just count */ ;
+       for ( ap = &rs->sr_operational_attrs; *ap; ap = &(*ap)->a_next ) {
+               if ( (*ap)->a_desc == slap_schema.si_ad_hasSubordinates ) {
+                       get_conn--;
+                       got[ BACKSQL_OP_HASSUBORDINATES ] = 1;
 
-       if ( ( SLAP_OPATTRS( rs->sr_attr_flags ) || ad_inlist( slap_schema.si_ad_hasSubordinates, rs->sr_attrs ) ) 
-                       && attr_find( rs->sr_entry->e_attrs, slap_schema.si_ad_hasSubordinates ) == NULL ) {
-               
-               rc = backsql_get_db_conn( op, &dbh );
-               if ( rc != LDAP_SUCCESS ) {
-                       Debug( LDAP_DEBUG_TRACE, "backsql_operational(): "
-                               "could not get connection handle - exiting\n", 
-                               0, 0, 0 );
-                       return 1;
+               } else if ( (*ap)->a_desc == slap_schema.si_ad_entryUUID ) {
+                       get_conn--;
+                       got[ BACKSQL_OP_ENTRYUUID ] = 1;
+
+               } else if ( (*ap)->a_desc == slap_schema.si_ad_entryCSN ) {
+                       get_conn--;
+                       got[ BACKSQL_OP_ENTRYCSN ] = 1;
                }
-               
-               rc = backsql_has_children( bi, dbh, &rs->sr_entry->e_nname );
+       }
+
+       if ( !get_conn ) {
+               return 0;
+       }
+
+       rc = backsql_get_db_conn( op, &dbh );
+       if ( rc != LDAP_SUCCESS ) {
+               Debug( LDAP_DEBUG_TRACE, "backsql_operational(): "
+                       "could not get connection handle - exiting\n", 
+                       0, 0, 0 );
+               return 1;
+       }
+
+       if ( ( SLAP_OPATTRS( rs->sr_attr_flags ) || ad_inlist( slap_schema.si_ad_hasSubordinates, rs->sr_attrs ) ) 
+                       && !got[ BACKSQL_OP_HASSUBORDINATES ]
+                       && attr_find( rs->sr_entry->e_attrs, slap_schema.si_ad_hasSubordinates ) == NULL )
+       {
+               rc = backsql_has_children( op, dbh, &rs->sr_entry->e_nname );
 
                switch( rc ) {
                case LDAP_COMPARE_TRUE:
                case LDAP_COMPARE_FALSE:
                        *ap = slap_operational_hasSubordinate( rc == LDAP_COMPARE_TRUE );
-                       assert( *ap );
+                       assert( *ap != NULL );
                        ap = &(*ap)->a_next;
                        rc = 0;
                        break;
@@ -74,15 +172,62 @@ backsql_operational(
                default:
                        Debug( LDAP_DEBUG_TRACE, "backsql_operational(): "
                                "has_children failed( %d)\n", rc, 0, 0 );
-                       rc = 1;
-                       break;
+                       return 1;
                }
        }
 
-       Debug( LDAP_DEBUG_TRACE, "<==backsql_operational()\n", 0, 0, 0);
+       if ( ( SLAP_OPATTRS( rs->sr_attr_flags ) || ad_inlist( slap_schema.si_ad_entryUUID, rs->sr_attrs ) ) 
+                       && !got[ BACKSQL_OP_ENTRYUUID ]
+                       && attr_find( rs->sr_entry->e_attrs, slap_schema.si_ad_entryUUID ) == NULL )
+       {
+               backsql_srch_info       bsi = { 0 };
+
+               rc = backsql_init_search( &bsi, &rs->sr_entry->e_nname,
+                               LDAP_SCOPE_BASE,
+                               (time_t)(-1), NULL, dbh, op, rs, NULL,
+                               BACKSQL_ISF_GET_ID );
+               if ( rc != LDAP_SUCCESS ) {
+                       Debug( LDAP_DEBUG_TRACE, "backsql_operational(): "
+                               "could not retrieve entry ID - no such entry\n", 
+                               0, 0, 0 );
+                       return 1;
+               }
+
+               *ap = backsql_operational_entryUUID( bi, &bsi.bsi_base_id );
+
+               (void)backsql_free_entryID( op, &bsi.bsi_base_id, 0 );
+
+               if ( bsi.bsi_attrs != NULL ) {
+                       op->o_tmpfree( bsi.bsi_attrs, op->o_tmpmemctx );
+               }
+
+               if ( *ap == NULL ) {
+                       Debug( LDAP_DEBUG_TRACE, "backsql_operational(): "
+                               "could not retrieve entryUUID\n", 
+                               0, 0, 0 );
+                       return 1;
+               }
+
+               ap = &(*ap)->a_next;
+       }
+
+       if ( ( SLAP_OPATTRS( rs->sr_attr_flags ) || ad_inlist( slap_schema.si_ad_entryCSN, rs->sr_attrs ) ) 
+                       && !got[ BACKSQL_OP_ENTRYCSN ]
+                       && attr_find( rs->sr_entry->e_attrs, slap_schema.si_ad_entryCSN ) == NULL )
+       {
+               *ap = backsql_operational_entryCSN( op );
+               if ( *ap == NULL ) {
+                       Debug( LDAP_DEBUG_TRACE, "backsql_operational(): "
+                               "could not retrieve entryCSN\n", 
+                               0, 0, 0 );
+                       return 1;
+               }
+
+               ap = &(*ap)->a_next;
+       }
+
+       Debug( LDAP_DEBUG_TRACE, "<==backsql_operational(%d)\n", rc, 0, 0);
 
        return rc;
 }
 
-#endif /* SLAPD_SQL */
-