modules/ud/ud_comrol.c

/* [<][>]
[^][v][top][bottom][index][help] */

FUNCTIONS

This source file includes following functions.
  1. rollback
  2. commit
  3. delete

   1 /***************************************
   2   $Revision: 1.13 $
   3 
   4   rollback(), commit(), delete() - rollback, commit update transaction, delete an object
   5 
   6   Status: NOT REVUED, NOT TESTED
   7 
   8  Author(s):       Andrei Robachevsky
   9 
  10   ******************/ /******************
  11   Modification History:
  12         andrei (17/01/2000) Created.
  13   ******************/ /******************
  14   Copyright (c) 2000                              RIPE NCC
  15  
  16   All Rights Reserved
  17   
  18   Permission to use, copy, modify, and distribute this software and its
  19   documentation for any purpose and without fee is hereby granted,
  20   provided that the above copyright notice appear in all copies and that
  21   both that copyright notice and this permission notice appear in
  22   supporting documentation, and that the name of the author not be
  23   used in advertising or publicity pertaining to distribution of the
  24   software without specific, written prior permission.
  25   
  26   THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  27   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
  28   AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
  29   DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
  30   AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  31   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  32  ***************************************/
  33 #include "ud.h"
  34 #include "ud_int.h"
  35 #include "ud_comrol.h"
  36 #include "rp.h"
  37 
  38 #define RIPE_REG 17
  39 
  40 /************************************************************
  41 * int rollback(Transaction_t *tr)
  42 * Rollback the transaction
  43 *
  44 * **********************************************************/ 
  45 int rollback(Transaction_t *tr) {
     /* [<][>][^][v][top][bottom][index][help] */
  46 GString *query;
  47 long sequence_id;
  48 int i, j;
  49 int sql_err;
  50 
  51  if(ACT_DELETE(tr->action)) return(0);
  52         
  53  if ((query = g_string_sized_new(STR_XXL)) == NULL){ 
  54    fprintf(stderr, "E: cannot allocate gstring\n"); 
  55    tr->succeeded=0;
  56    tr->error |= ERROR_U_MEM;
  57    return(ERROR_U_MEM); }
  58 
  59 /* Lock all relevant tables */
  60    g_string_sprintf(query, "LOCK TABLES %s WRITE,",  DF_get_class_sql_table(tr->class_type));
  61     
  62     for (i=0; tables[tr->class_type][i] != NULL; i++) 
  63       g_string_sprintfa(query, " %s WRITE,", tables[tr->class_type][i]);
  64     
  65     for (i=TAB_START; tables[tr->class_type][i] != NULL; i++)
  66       g_string_sprintfa(query, " %s WRITE,", tables[tr->class_type][i]);
  67     
  68     g_string_sprintfa(query, " last WRITE, history WRITE ");
  69     
  70     sql_err=SQ_execute_query(tr->sql_connection, query->str, NULL);
  71 
  72     /*fprintf(stderr,"%s\n", query->str);*/
  73 
  74 
  75 /* Process AUX and LEAF tables */
  76     for (i=TAB_START; tables[tr->class_type][i] != NULL; i++) {
  77     /* Delete what has been inserted */
  78     g_string_sprintf(query, "DELETE FROM %s WHERE object_id=%ld AND thread_id=%d", tables[tr->class_type][i], tr->object_id, tr->thread_ins);
  79     sql_err=SQ_execute_query(tr->sql_connection, query->str, NULL);
  80 
  81     /* Normalize what has been updated/touched */
  82     g_string_sprintf(query, "UPDATE %s SET thread_id=0 WHERE object_id=%ld AND thread_id=%d", tables[tr->class_type][i], tr->object_id, tr->thread_upd);
  83     sql_err = SQ_execute_query(tr->sql_connection, query->str, (SQ_result_set_t **)NULL);
  84   }
  85 
  86 /* Process MAIN tables */
  87     g_string_sprintf(query, "DELETE FROM %s WHERE  object_id=%ld AND thread_id=%d", 
  88                              DF_get_class_sql_table(tr->class_type), tr->object_id, tr->thread_ins);
  89     sql_err = SQ_execute_query(tr->sql_connection, query->str, (SQ_result_set_t **)NULL);
  90     
  91     /* This is needed only for objects with dummies, as they are updated with TR_UPDATE */
  92     /* We use this tag when commiting the update to set dummy==0 */
  93     /* XXX may be later this should be reconsidered */
  94     g_string_sprintf(query, "UPDATE %s SET thread_id=0 WHERE  object_id=%ld AND thread_id=%d", 
  95                              DF_get_class_sql_table(tr->class_type), tr->object_id, tr->thread_upd);
  96     sql_err = SQ_execute_query(tr->sql_connection, query->str, (SQ_result_set_t **)NULL);
  97 
  98 /* Now tables  that might be affected by dummies */
  99     for(j=0; j < tr->ndummy; j++) 
 100     for (i=0; tables[tr->class_type][i] != NULL; i++) {
 101         g_string_sprintf(query, "DELETE FROM %s WHERE object_id=%ld ", tables[tr->class_type][i], tr->dummy_id[j]);
 102         sql_err = SQ_execute_query(tr->sql_connection, query->str, (SQ_result_set_t **)NULL);
 103     } 
 104 
 105 /* Rollback last and history tables */
 106     if(ACT_UPDATE(tr->action)) { /* so we are updating an object */
 107    g_string_sprintf(query, "DELETE FROM history WHERE object_id=%ld AND sequence_id=%ld", tr->object_id, tr->sequence_id-1);
 108    sql_err = SQ_execute_query(tr->sql_connection, query->str, (SQ_result_set_t **)NULL);
 109    /* we do not need to delete a row in the last for updates    */
 110   }
 111     else { /* we failed to create an object */
 112       sequence_id=1; /* sequence start == 1 */
 113    g_string_sprintf(query, "DELETE FROM last WHERE object_id=%ld AND sequence_id=%ld", tr->object_id, sequence_id);
 114    sql_err = SQ_execute_query(tr->sql_connection, query->str, (SQ_result_set_t **)NULL);
 115   }
 116 
 117 
 118     for(j=0; j < tr->ndummy; j++){/* if dummies have been created */
 119          g_string_sprintf(query, "DELETE FROM last WHERE object_id=%ld ", tr->dummy_id[j]);
 120          sql_err = SQ_execute_query(tr->sql_connection, query->str, (SQ_result_set_t **)NULL);
 121   }
 122   
 123   /* Unlock all tables */
 124   g_string_sprintf(query, "UNLOCK TABLES ");
 125   sql_err = SQ_execute_query(tr->sql_connection, query->str, (SQ_result_set_t **)NULL);
 126 
 127   
 128   g_string_free(query, TRUE);
 129   return(0);
 130 } /* rollback() */
 131 
 132 /************************************************************
 133 * int commit(Transaction_t *tr)
 134 * Commit the transaction
 135 *
 136 * **********************************************************/ 
 137 int commit(Transaction_t *tr) {
     /* [<][>][^][v][top][bottom][index][help] */
 138 GString *query;
 139 int err=0;
 140 int i,j;
 141 A_Type_t attr_type;
 142 int sql_err;
 143 
 144 if(ACT_DELETE(tr->action)) return(0);
 145 
 146  if ((query = g_string_sized_new(STR_XXL)) == NULL){ 
 147    fprintf(stderr, "E: cannot allocate gstring\n"); 
 148    tr->succeeded=0;
 149    tr->error|=ERROR_U_MEM;
 150    return(ERROR_U_MEM); 
 151  }
 152 
 153 /* Lock all relevant tables */
 154     g_string_sprintf(query, "LOCK TABLES %s WRITE,", DF_get_class_sql_table(tr->class_type));
 155     
 156     for (i=0; tables[tr->class_type][i] != NULL; i++) 
 157       g_string_sprintfa(query, " %s WRITE,", tables[tr->class_type][i]);
 158     
 159     for (i=TAB_START; tables[tr->class_type][i] != NULL; i++)
 160       g_string_sprintfa(query, " %s WRITE,", tables[tr->class_type][i]);
 161     
 162     g_string_sprintfa(query, " last WRITE, history WRITE ");
 163     
 164     sql_err = SQ_execute_query(tr->sql_connection, query->str, (SQ_result_set_t **)NULL);
 165 
 166 /* fprintf(stderr,"%s\n", query->str); */
 167 
 168 /* Commit the transaction for AUX and LEAF tables that may be affected (taken from object template) */
 169   for (i=TAB_START; tables[tr->class_type][i] != NULL; i++) {
 170  /* Delete old records from the tables */  
 171     g_string_sprintf(query, "DELETE FROM %s WHERE object_id=%ld AND thread_id=0 ", tables[tr->class_type][i], tr->object_id);
 172     sql_err = SQ_execute_query(tr->sql_connection, query->str, (SQ_result_set_t **)NULL);
 173     /*    fprintf(stderr, "D: query (del old): %s\n", query->str);  */
 174 
 175  /* Set thread_id to 0 to commit the transaction */    
 176     g_string_sprintf(query, "UPDATE %s SET thread_id=0 WHERE object_id=%ld", tables[tr->class_type][i], tr->object_id);
 177     sql_err = SQ_execute_query(tr->sql_connection, query->str, (SQ_result_set_t **)NULL);
 178     /*    fprintf(stderr, "D: query (com new): %s\n", query->str); */
 179   }
 180   
 181 /* Commit the transaction for the MAIN tables */
 182 
 183 /* Commit the transaction for person_role, mntner, as_set, route_set tables */
 184 /* They require different handling because of dummies */
 185 /* The rule is: Update: dummy->0, Insert: preserve dummy value */
 186 /* These tables do not require deletions since we cannot have such condition (object_id==0 AND thread_id==0) */
 187  if((tr->class_type==C_PN) || (tr->class_type==C_RO) || 
 188    (tr->class_type==C_AS) || (tr->class_type==C_RS) ||
 189    (tr->class_type==C_MT)){
 190 
 191  /* Process the rows updated/touched */
 192     g_string_sprintf(query, "UPDATE %s SET thread_id=0, dummy=0 WHERE object_id=%ld AND thread_id=%d ",  DF_get_class_sql_table(tr->class_type), tr->object_id, tr->thread_upd);
 193     sql_err = SQ_execute_query(tr->sql_connection, query->str, (SQ_result_set_t **)NULL);
 194  }
 195  
 196  switch (tr->class_type) {
 197    case C_IR:
 198    case C_IN:
 199    case C_I6:
 200    case C_FS: 
 201     if((tr->save)){ /* Some special processing for tables with the second attribute */
 202      /* Update the second field of the table with query like one below */
 203      /* UPDATE %s SET thread_id=%d, local_as='%s' WHERE object_id=%ld */
 204      
 205      switch(tr->class_type) {
 206       /* Local-as for inet-rtr */
 207       case C_IR: attr_type=A_LA;
 208                  break;
 209       /* netname for inetnum and inet6num */           
 210       case C_IN: 
 211       case C_I6: attr_type=A_NA;
 212                  break;
 213       /* filter for filter-set */           
 214       case C_FS: attr_type=A_FI;
 215                  break;
 216       default:
 217                  die;
 218                  break;           
 219      }
 220      g_string_sprintf(query, DF_get_update_query(attr_type), DF_get_class_sql_table(tr->class_type), 0, (char *)tr->save, tr->object_id);
 221      sql_err = SQ_execute_query(tr->sql_connection, query->str, (SQ_result_set_t **)NULL);
 222     }
 223     else die;
 224     break;
 225    
 226    default:  
 227  /* Process all other MAIN tables for updates/inserts and person_role, mntner, as_set, route_set tables for rows inserts */
 228     g_string_sprintf(query, "UPDATE %s SET thread_id=0 WHERE object_id=%ld AND thread_id>0", DF_get_class_sql_table(tr->class_type), tr->object_id);
 229     sql_err = SQ_execute_query(tr->sql_connection, query->str, (SQ_result_set_t **)NULL);
 230     break;
 231  }  
 232 
 233 
 234 /* for tables that might be affected by dummies */
 235  for(j=0; j < tr->ndummy; j++)/* if dummies have been created */
 236    for (i=0; tables[tr->class_type][i] != NULL; i++) {
 237     g_string_sprintf(query, "UPDATE %s SET thread_id=0 WHERE object_id=%ld ", tables[tr->class_type][i], tr->dummy_id[j]);
 238     sql_err = SQ_execute_query(tr->sql_connection, query->str, (SQ_result_set_t **)NULL);
 239  }
 240 
 241 
 242    for(j=0; j < tr->ndummy; j++){/* if dummies have been created*/
 243          g_string_sprintf(query, "UPDATE last SET thread_id=0 WHERE object_id=%ld ", tr->dummy_id[j]);
 244          sql_err = SQ_execute_query(tr->sql_connection, query->str, (SQ_result_set_t **)NULL);
 245   }
 246   
 247  /* Unlock all tables */
 248  g_string_sprintf(query, "UNLOCK TABLES ");
 249  sql_err = SQ_execute_query(tr->sql_connection, query->str, (SQ_result_set_t **)NULL);
 250 
 251  /* Update radix tree for route, inetnum and inaddr-arpa domain*/
 252  if(tr->standalone==0) { /* only if server*/
 253  
 254  /* Create a radix node for the object */
 255    if( (   (tr->class_type==C_RT) 
 256         || (tr->class_type==C_IN) 
 257         || (tr->class_type==C_I6)
 258         || (tr->class_type==C_DN))
 259        && (tr->packptr)) {
 260      rp_upd_pack_t *packptr = tr->packptr;
 261      
 262      packptr->key = tr->object_id;
 263      
 264      if( RP_pack_node(RX_OPER_CRE, packptr, RIPE_REG) == RX_OK ) {
 265        err = 0;
 266      } else {
 267        err = (-1) ;
 268      }
 269    }   
 270    /* XXX Check for errors */
 271  } 
 272 
 273   g_string_free(query, TRUE);
 274   return(err);
 275 } /* commit() */
 276 
 277 
 278 
 279 /******************************************************
 280 *int delete(Transaction_t *tr)
 281 * Delete the object
 282 *
 283 *****************************************************/
 284 int delete(Transaction_t *tr) 
     /* [<][>][^][v][top][bottom][index][help] */
 285 {
 286 GString *query;
 287 int err=0;
 288 int i;
 289 int num;
 290 long ref_id;
 291 long num_rec;
 292 long timestamp;
 293 
 294 char sobject_id[STR_M];
 295 char *sql_str;
 296 int sql_err;
 297 
 298 
 299  /* Try to allocate g_string. Return on error */        
 300  if ((query = g_string_sized_new(STR_XXL)) == NULL){ 
 301    fprintf(stderr, "E: cannot allocate gstring\n");
 302    tr->succeeded=0;
 303    tr->error|=ERROR_U_MEM;
 304    return(ERROR_U_MEM); 
 305  }
 306 
 307 
 308 /* Check for referential integrity of deletion */
 309 
 310    sprintf(sobject_id, "%ld", tr->object_id);
 311 
 312    switch(tr->class_type){
 313     case C_PN:
 314     case C_RO:
 315         
 316        if(tr->dummy==1)break; /* This is if the override exists */
 317        
 318        /* Check that this person/role object is not referenced */
 319         
 320        for (i=0; t_ipn[i] != NULL; i++) { 
 321         /* Calculate number of references */
 322         sql_str= get_field_str(tr->sql_connection, "COUNT(*)", t_ipn[i], "pe_ro_id", sobject_id, NULL);
 323         if(sql_str) {
 324          num_rec = atol(sql_str);  free(sql_str);
 325          ref_id=tr->object_id;
 326          /* Check if it is a self reference (for role objects) */
 327          if(num_rec==1) {
 328           sql_str= get_field_str(tr->sql_connection, "object_id", t_ipn[i], "pe_ro_id", sobject_id, NULL);
 329           if(sql_str) {
 330            ref_id = atol(sql_str);  free(sql_str);
 331           } else {
 332            tr->succeeded=0; tr->error |= ERROR_U_DBS; break;
 333           }
 334          }
 335          /* If there are references (and not the only self reference) we cannot delete */
 336          if((num_rec>1) || (ref_id!=tr->object_id)) {
 337            g_string_sprintfa(tr->error_script,"E[%d][%ld]:ref integrity: %s\n" ,ERROR_U_OBJ, num_rec, t_ipn[i]);
 338            tr->succeeded=0; tr->error |= ERROR_U_OBJ;
 339          }
 340         } else {
 341         /* SQL error occured */
 342          tr->succeeded=0; tr->error |= ERROR_U_DBS;
 343          g_string_sprintfa(tr->error_script,"E[%d][%s]:%s\n", ERROR_U_DBS, t_ipn[i], SQ_error(tr->sql_connection));
 344         }
 345        }
 346        
 347        /* Check that this person/role object is not referenced by name (legacy stuff) */
 348        
 349        for (i=0; t_ipn[i] != NULL; i++) { 
 350         /* Calculate number of references */
 351         
 352         g_string_sprintf(query, "SELECT COUNT(*) FROM %s, person_role "
 353                                 "WHERE person_role.object_id=%s.pe_ro_id "
 354                                 "AND person_role.nic_hdl='%s' ", t_ipn[i], t_ipn[i], tr->save);
 355         
 356         sql_str= get_qresult_str(tr->sql_connection, query->str);
 357         if(sql_str) {
 358          num_rec = atol(sql_str);  free(sql_str);
 359          /* If there are references (no self reference is possible in this case) we cannot delete */
 360          if(num_rec>0) {
 361            g_string_sprintfa(tr->error_script,"E[%d][%ld]:ref integrity: %s\n" ,ERROR_U_OBJ, num_rec, t_ipn[i]);
 362            tr->succeeded=0; tr->error |= ERROR_U_OBJ;
 363          }
 364         } else {
 365         /* SQL error occured */
 366          tr->succeeded=0; tr->error |= ERROR_U_DBS;
 367          g_string_sprintfa(tr->error_script,"E[%d][%s]:%s\n", ERROR_U_DBS, t_ipn[i], SQ_error(tr->sql_connection));
 368         }
 369        }
 370           
 371        break;
 372         
 373     case C_MT:
 374     
 375         if(tr->dummy==1)break; /* This is if the override exists */
 376         
 377         /* Check that this mntner object is not referenced */
 378         
 379        for (i=0; t_imt[i] != NULL; i++) { 
 380        /* Calculate number of references */
 381         sql_str= get_field_str(tr->sql_connection, "COUNT(*)", t_imt[i], "mnt_id", sobject_id, NULL);
 382         if(sql_str) {
 383          num_rec = atol(sql_str);  free(sql_str);
 384          ref_id=tr->object_id;
 385          /* Check if it is a self reference  */
 386          if(num_rec==1) { 
 387             sql_str= get_field_str(tr->sql_connection, "object_id", t_imt[i], "mnt_id", sobject_id, NULL);
 388             if(sql_str) {
 389               ref_id = atol(sql_str);  free(sql_str);
 390             } else {
 391               tr->succeeded=0; tr->error |= ERROR_U_DBS; break;
 392             } 
 393          }
 394          /* If there are references (and not the only self reference) we cannot delete */ 
 395          if((num_rec>1) || (ref_id!=tr->object_id)) {
 396            g_string_sprintfa(tr->error_script,"E[%d][%ld]:ref integrity: %s\n" ,ERROR_U_OBJ, num_rec, t_imt[i]);
 397            tr->succeeded=0; tr->error |= ERROR_U_OBJ;
 398          }
 399         } else {
 400          tr->succeeded=0; tr->error |= ERROR_U_DBS;
 401         }
 402        }   
 403        break;
 404         
 405     case C_RS:
 406     case C_AS:
 407         /* Check that this set object is not referenced */
 408         /* Calculate number of references */
 409         sql_str= get_field_str(tr->sql_connection, "COUNT(*)", "member_of", "set_id", sobject_id, NULL);
 410         if(sql_str) {
 411          num_rec = atol(sql_str);  free(sql_str);
 412          /* XXX though set may contain other sets as memebers, */
 413          /* there is no member-of attribute in these objects. */
 414          /* So no self-reference is possible */
 415          if(num_rec!=0) {
 416            g_string_sprintfa(tr->error_script,"E[%d][%ld]:ref integrity: %s\n" ,ERROR_U_OBJ, num_rec, "member_of");
 417            tr->succeeded=0; tr->error |= ERROR_U_OBJ;
 418           /* XXX Do not refuse the transaction but change the object to dummy */
 419          }
 420         } else {
 421          tr->succeeded=0; tr->error |= ERROR_U_DBS;
 422         }
 423         break;
 424 
 425     default:
 426         break;    
 427    } 
 428    
 429  /* Check if we have passed referential integrity check */  
 430  if(tr->succeeded==0){
 431        return(-1);
 432  }
 433           
 434 
 435 /* Lock all relevant tables */
 436     g_string_sprintf(query, "LOCK TABLES %s WRITE,", DF_get_class_sql_table(tr->class_type));
 437     
 438     for (i=0; tables[tr->class_type][i] != NULL; i++) 
 439       g_string_sprintfa(query, " %s WRITE,", tables[tr->class_type][i]);
 440     
 441     for (i=TAB_START; tables[tr->class_type][i] != NULL; i++)
 442       g_string_sprintfa(query, " %s WRITE,", tables[tr->class_type][i]);
 443     
 444     g_string_sprintfa(query, " last WRITE, history WRITE ");
 445     
 446     sql_err = SQ_execute_query(tr->sql_connection, query->str, (SQ_result_set_t **)NULL);
 447 
 448     for (i=TAB_START; tables[tr->class_type][i] != NULL; i++) {
 449     g_string_sprintf(query, "DELETE FROM %s WHERE object_id=%ld ", tables[tr->class_type][i], tr->object_id);
 450     sql_err = SQ_execute_query(tr->sql_connection, query->str, (SQ_result_set_t **)NULL);
 451     /*    fprintf(stderr, "D: query (delete): %s\n", query->str);*/
 452   }
 453 
 454 /* Process the MAIN table  */
 455     g_string_sprintf(query, "DELETE FROM %s WHERE object_id=%ld ", DF_get_class_sql_table(tr->class_type), tr->object_id);
 456     sql_err = SQ_execute_query(tr->sql_connection, query->str, (SQ_result_set_t **)NULL);
 457 
 458 /* Update the history table */
 459     g_string_sprintf(query,     "INSERT history "
 460                                 "SELECT 0, object_id, sequence_id, timestamp, object_type, object "
 461                                 "FROM last "
 462                                 "WHERE object_id=%ld ", tr->object_id);
 463 
 464       
 465   sql_err = SQ_execute_query(tr->sql_connection, query->str, (SQ_result_set_t **)NULL);
 466   if (sql_err) {
 467          fprintf(stderr, "E ERROR!<perform_update>: INSERT history failed:[%d][%s]\n", num, query->str);
 468          tr->succeeded=0;
 469          tr->error |=ERROR_U_DBS;
 470   }
 471 
 472   /* get sequence number */
 473   tr->sequence_id = get_sequence_id(tr);
 474   tr->sequence_id++;
 475        
 476   /* insert new version into the last */
 477   timestamp=time(NULL);
 478   
 479  /* empty the contents, but leave in the table to restrict re-use of object_id */ 
 480   g_string_sprintf(query, "UPDATE last SET object='', timestamp=%ld  WHERE object_id=%ld ", timestamp, tr->object_id);
 481 
 482   sql_err = SQ_execute_query(tr->sql_connection, query->str, (SQ_result_set_t **)NULL);
 483   if (sql_err) {
 484         fprintf(stderr, "E ERROR!<perform_update>: UPDATE last failed: [%d][%s]\n", num, query->str);
 485          tr->succeeded=0;
 486          tr->error |= ERROR_U_DBS;
 487   }
 488 
 489 
 490   /* Do more in the forest
 491    * Update radix tree for route and inetnum
 492    */
 493   if(tr->standalone==0) { /* only if server */
 494   /* Collect some data for radix tree and NH repository update */
 495     g_slist_foreach((tr->object)->attributes, get_rx_data, tr);
 496 
 497     /* Only for these types of objects and only if we have collected data (tr->save != NULL) */
 498     if( (   (tr->class_type==C_RT) 
 499          || (tr->class_type==C_IN) 
 500          || (tr->class_type==C_I6)
 501          || (tr->class_type==C_DN))
 502         && (tr->packptr)) {
 503       rp_upd_pack_t *packptr = tr->packptr;
 504       
 505       packptr->key = tr->object_id;
 506       if( RP_pack_node(RX_OPER_DEL, packptr, RIPE_REG) == RX_OK ) {
 507         err = 0;
 508       } else {
 509         err = (-1) ;
 510       }
 511     }
 512   }
 513   
 514  /* Unlock all tables */
 515   g_string_sprintf(query, "UNLOCK TABLES ");
 516   sql_err = SQ_execute_query(tr->sql_connection, query->str, (SQ_result_set_t **)NULL);
 517 
 518   g_string_free(query, TRUE);
 519 
 520   return(err);
 521 
 522 } /* delete() */              

/* [<][>][^][v][top][bottom][index][help] */