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.17 $
   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 /************************************************************
  39 * int rollback()                                            *
  40 *                                                           *
  41 * Rolls back the transaction                                *
  42 *                                                           *
  43 * It locks all relevant tables and processes the rollback   *
  44 * General approach is to delete all new records related     *
  45 * to the transaction (thread_id==thread_ins) and clean up   *
  46 * old ones (thread_id==thread_upd)                          *
  47 *                                                           *
  48 ************************************************************/
  49  
  50 int rollback(Transaction_t *tr) {
     /* [<][>][^][v][top][bottom][index][help] */
  51 GString *query;
  52 long sequence_id;
  53 int i, j;
  54 int sql_err;
  55 
  56  if(ACT_DELETE(tr->action)) return(0);
  57         
  58  if ((query = g_string_sized_new(STR_XXL)) == NULL){ 
  59    fprintf(stderr, "E: cannot allocate gstring\n"); 
  60    tr->succeeded=0;
  61    tr->error |= ERROR_U_MEM;
  62    return(ERROR_U_MEM); }
  63 
  64 /* Lock all relevant tables */
  65    g_string_sprintf(query, "LOCK TABLES %s WRITE,",  DF_get_class_sql_table(tr->class_type));
  66     
  67     for (i=0; tables[tr->class_type][i] != NULL; i++) 
  68       g_string_sprintfa(query, " %s WRITE,", tables[tr->class_type][i]);
  69     
  70     for (i=TAB_START; tables[tr->class_type][i] != NULL; i++)
  71       g_string_sprintfa(query, " %s WRITE,", tables[tr->class_type][i]);
  72     
  73     g_string_sprintfa(query, " last WRITE, history WRITE ");
  74     
  75     sql_err=SQ_execute_query(tr->sql_connection, query->str, NULL);
  76 
  77     /*fprintf(stderr,"%s\n", query->str);*/
  78 
  79 
  80 /* Process AUX and LEAF tables */
  81     for (i=TAB_START; tables[tr->class_type][i] != NULL; i++) {
  82     /* Delete what has been inserted */
  83     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);
  84     sql_err=SQ_execute_query(tr->sql_connection, query->str, NULL);
  85 
  86     /* Normalize what has been updated/touched */
  87     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);
  88     sql_err = SQ_execute_query(tr->sql_connection, query->str, (SQ_result_set_t **)NULL);
  89   }
  90 
  91 /* Process MAIN tables */
  92     g_string_sprintf(query, "DELETE FROM %s WHERE  object_id=%ld AND thread_id=%d", 
  93                              DF_get_class_sql_table(tr->class_type), tr->object_id, tr->thread_ins);
  94     sql_err = SQ_execute_query(tr->sql_connection, query->str, (SQ_result_set_t **)NULL);
  95     
  96     /* This is needed only for objects with dummies, as they are updated with TR_UPDATE */
  97     /* We use this tag when commiting the update to set dummy==0 */
  98     /* XXX may be later this should be reconsidered */
  99     g_string_sprintf(query, "UPDATE %s SET thread_id=0 WHERE  object_id=%ld AND thread_id=%d", 
 100                              DF_get_class_sql_table(tr->class_type), tr->object_id, tr->thread_upd);
 101     sql_err = SQ_execute_query(tr->sql_connection, query->str, (SQ_result_set_t **)NULL);
 102 
 103 /* Now tables  that might be affected by dummies */
 104     for(j=0; j < tr->ndummy; j++) 
 105     for (i=0; tables[tr->class_type][i] != NULL; i++) {
 106         g_string_sprintf(query, "DELETE FROM %s WHERE object_id=%ld ", tables[tr->class_type][i], tr->dummy_id[j]);
 107         sql_err = SQ_execute_query(tr->sql_connection, query->str, (SQ_result_set_t **)NULL);
 108     } 
 109 
 110 /* Rollback last and history tables */
 111     if(ACT_UPDATE(tr->action)) { /* so we are updating an object */
 112    g_string_sprintf(query, "DELETE FROM history WHERE object_id=%ld AND sequence_id=%ld", tr->object_id, tr->sequence_id-1);
 113    sql_err = SQ_execute_query(tr->sql_connection, query->str, (SQ_result_set_t **)NULL);
 114    /* we do not need to delete a row in the last for updates    */
 115   }
 116     else { /* we failed to create an object */
 117       sequence_id=1; /* sequence start == 1 */
 118    g_string_sprintf(query, "DELETE FROM last WHERE object_id=%ld AND sequence_id=%ld", tr->object_id, sequence_id);
 119    sql_err = SQ_execute_query(tr->sql_connection, query->str, (SQ_result_set_t **)NULL);
 120   }
 121 
 122 
 123     for(j=0; j < tr->ndummy; j++){/* if dummies have been created */
 124          g_string_sprintf(query, "DELETE FROM last WHERE object_id=%ld ", tr->dummy_id[j]);
 125          sql_err = SQ_execute_query(tr->sql_connection, query->str, (SQ_result_set_t **)NULL);
 126   }
 127   
 128   /* Unlock all tables */
 129   g_string_sprintf(query, "UNLOCK TABLES ");
 130   sql_err = SQ_execute_query(tr->sql_connection, query->str, (SQ_result_set_t **)NULL);
 131 
 132   
 133   g_string_free(query, TRUE);
 134   return(0);
 135 } /* rollback() */
 136 
 137 
 138 /************************************************************
 139 * int commit()                                              *
 140 *                                                           *
 141 * Commits the transaction                                   *
 142 *                                                           *
 143 * It locks all relevant tables and processes the rollback   *
 144 * General approach is to clean up all new and updated       *
 145 * records related to the transaction                        *
 146 * (thread_id==thread_ins) and (thread_id==thread_upd),      *
 147 * and delete untouched ones (thread_id==0)                  *
 148 *                                                           *
 149 ************************************************************/
 150 
 151 int commit(Transaction_t *tr) {
     /* [<][>][^][v][top][bottom][index][help] */
 152 GString *query;
 153 int err=0;
 154 int i,j;
 155 A_Type_t attr_type;
 156 int sql_err;
 157 
 158 if(ACT_DELETE(tr->action)) return(0);
 159 
 160  if ((query = g_string_sized_new(STR_XXL)) == NULL){ 
 161    fprintf(stderr, "E: cannot allocate gstring\n"); 
 162    tr->succeeded=0;
 163    tr->error|=ERROR_U_MEM;
 164    return(ERROR_U_MEM); 
 165  }
 166 
 167 /* Lock all relevant tables */
 168     g_string_sprintf(query, "LOCK TABLES %s WRITE,", DF_get_class_sql_table(tr->class_type));
 169     
 170     for (i=0; tables[tr->class_type][i] != NULL; i++) 
 171       g_string_sprintfa(query, " %s WRITE,", tables[tr->class_type][i]);
 172     
 173     for (i=TAB_START; tables[tr->class_type][i] != NULL; i++)
 174       g_string_sprintfa(query, " %s WRITE,", tables[tr->class_type][i]);
 175     
 176     g_string_sprintfa(query, " last WRITE, history WRITE ");
 177     
 178     sql_err = SQ_execute_query(tr->sql_connection, query->str, (SQ_result_set_t **)NULL);
 179 
 180 /* fprintf(stderr,"%s\n", query->str); */
 181 
 182 /* Commit the transaction for AUX and LEAF tables that may be affected (taken from object template) */
 183   for (i=TAB_START; tables[tr->class_type][i] != NULL; i++) {
 184  /* Delete old records from the tables */  
 185     g_string_sprintf(query, "DELETE FROM %s WHERE object_id=%ld AND thread_id=0 ", tables[tr->class_type][i], tr->object_id);
 186     sql_err = SQ_execute_query(tr->sql_connection, query->str, (SQ_result_set_t **)NULL);
 187     /*    fprintf(stderr, "D: query (del old): %s\n", query->str);  */
 188 
 189  /* Set thread_id to 0 to commit the transaction */    
 190     g_string_sprintf(query, "UPDATE %s SET thread_id=0 WHERE object_id=%ld", tables[tr->class_type][i], tr->object_id);
 191     sql_err = SQ_execute_query(tr->sql_connection, query->str, (SQ_result_set_t **)NULL);
 192     /*    fprintf(stderr, "D: query (com new): %s\n", query->str); */
 193   }
 194   
 195 /* Commit the transaction for the MAIN tables */
 196 
 197 /* Commit the transaction for person_role, mntner, as_set, route_set tables */
 198 /* They require different handling because of dummies */
 199 /* The rule is: Update: dummy->0, Insert: preserve dummy value */
 200 /* These tables do not require deletions since we cannot have such condition (object_id==0 AND thread_id==0) */
 201  if((tr->class_type==C_PN) || (tr->class_type==C_RO) || 
 202    (tr->class_type==C_AS) || (tr->class_type==C_RS) ||
 203    (tr->class_type==C_MT)){
 204 
 205  /* Process the rows updated/touched */
 206     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);
 207     sql_err = SQ_execute_query(tr->sql_connection, query->str, (SQ_result_set_t **)NULL);
 208  }
 209  
 210  switch (tr->class_type) {
 211    case C_IR:
 212    case C_IN:
 213    case C_I6:
 214    case C_FS: 
 215     if((tr->save)){ /* Some special processing for tables with the second attribute */
 216      /* Update the second field of the table with query like one below */
 217      /* UPDATE %s SET thread_id=%d, local_as='%s' WHERE object_id=%ld */
 218      
 219      switch(tr->class_type) {
 220       /* Local-as for inet-rtr */
 221       case C_IR: attr_type=A_LA;
 222                  break;
 223       /* netname for inetnum and inet6num */           
 224       case C_IN: 
 225       case C_I6: attr_type=A_NA;
 226                  break;
 227       /* filter for filter-set */           
 228       case C_FS: attr_type=A_FI;
 229                  break;
 230       default:
 231                  die;
 232                  break;           
 233      }
 234      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);
 235      sql_err = SQ_execute_query(tr->sql_connection, query->str, (SQ_result_set_t **)NULL);
 236     }
 237     else die;
 238     break;
 239    
 240    default:  
 241  /* Process all other MAIN tables for updates/inserts and person_role, mntner, as_set, route_set tables for rows inserts */
 242     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);
 243     sql_err = SQ_execute_query(tr->sql_connection, query->str, (SQ_result_set_t **)NULL);
 244     break;
 245  }  
 246 
 247 
 248 /* for tables that might be affected by dummies */
 249  for(j=0; j < tr->ndummy; j++)/* if dummies have been created */
 250    for (i=0; tables[tr->class_type][i] != NULL; i++) {
 251     g_string_sprintf(query, "UPDATE %s SET thread_id=0 WHERE object_id=%ld ", tables[tr->class_type][i], tr->dummy_id[j]);
 252     sql_err = SQ_execute_query(tr->sql_connection, query->str, (SQ_result_set_t **)NULL);
 253  }
 254 
 255 
 256    for(j=0; j < tr->ndummy; j++){/* if dummies have been created*/
 257          g_string_sprintf(query, "UPDATE last SET thread_id=0 WHERE object_id=%ld ", tr->dummy_id[j]);
 258          sql_err = SQ_execute_query(tr->sql_connection, query->str, (SQ_result_set_t **)NULL);
 259   }
 260   
 261  /* Unlock all tables */
 262  g_string_sprintf(query, "UNLOCK TABLES ");
 263  sql_err = SQ_execute_query(tr->sql_connection, query->str, (SQ_result_set_t **)NULL);
 264 
 265  /* Update radix tree for route, inetnum and inaddr-arpa domain*/
 266  if(tr->standalone==0) { /* only if server*/
 267  
 268  /* Create a radix node for the object */
 269    if( (   (tr->class_type==C_RT) 
 270         || (tr->class_type==C_IN) 
 271         || (tr->class_type==C_I6)
 272         || (tr->class_type==C_DN))
 273        && (ACT_UPD_RX(tr->action))) {
 274      rp_upd_pack_t *packptr = tr->packptr;
 275      
 276      packptr->key = tr->object_id;
 277      
 278      if( RP_pack_node(RX_OPER_CRE, packptr, tr->source_hdl) == RX_OK ) {
 279        err = 0;
 280      } else {
 281        err = (-1) ;
 282      }
 283    }   
 284    /* XXX Check for errors */
 285  } 
 286 
 287   g_string_free(query, TRUE);
 288   return(err);
 289 } /* commit() */
 290 
 291 
 292 /************************************************************
 293 * int delete()                                              *
 294 *                                                           *
 295 * Deletes the object                                        *
 296 *                                                           *
 297 * It checks for referential integrity and then deletes the  *
 298 * object from all relevant tables. Then it updates the      *
 299 * radix tree for routes, inetnums and rev.domains           *
 300 *                                                           *
 301 ************************************************************/
 302 int delete(Transaction_t *tr) 
     /* [<][>][^][v][top][bottom][index][help] */
 303 {
 304 GString *query;
 305 int err=0;
 306 int i;
 307 int num;
 308 long ref_id;
 309 long num_rec;
 310 long timestamp;
 311 
 312 char sobject_id[STR_M];
 313 char *sql_str;
 314 int sql_err;
 315 
 316 
 317  /* Try to allocate g_string. Return on error */        
 318  if ((query = g_string_sized_new(STR_XXL)) == NULL){ 
 319    fprintf(stderr, "E: cannot allocate gstring\n");
 320    tr->succeeded=0;
 321    tr->error|=ERROR_U_MEM;
 322    return(ERROR_U_MEM); 
 323  }
 324 
 325 
 326 /* Check for referential integrity of deletion */
 327 
 328    sprintf(sobject_id, "%ld", tr->object_id);
 329 
 330    switch(tr->class_type){
 331     case C_PN:
 332     case C_RO:
 333         
 334        /* Check that this person/role object is not referenced */
 335         
 336        for (i=0; t_ipn[i] != NULL; i++) { 
 337         /* Calculate number of references */
 338         sql_str= get_field_str(tr->sql_connection, "COUNT(*)", t_ipn[i], "pe_ro_id", sobject_id, NULL);
 339         if(sql_str) {
 340          num_rec = atol(sql_str);  free(sql_str);
 341          ref_id=tr->object_id;
 342          /* Check if it is a self reference (for role objects) */
 343          if(num_rec==1) {
 344           sql_str= get_field_str(tr->sql_connection, "object_id", t_ipn[i], "pe_ro_id", sobject_id, NULL);
 345           if(sql_str) {
 346            ref_id = atol(sql_str);  free(sql_str);
 347           } else {
 348            tr->succeeded=0; tr->error |= ERROR_U_DBS; break;
 349           }
 350          }
 351          /* If there are references (and not the only self reference) we cannot delete */
 352          if((num_rec>1) || (ref_id!=tr->object_id)) {
 353            g_string_sprintfa(tr->error_script,"E[%d][%ld]:ref integrity: %s\n" ,ERROR_U_OBJ, num_rec, t_ipn[i]);
 354            tr->succeeded=0; tr->error |= ERROR_U_OBJ;
 355          }
 356         } else {
 357         /* SQL error occured */
 358          tr->succeeded=0; tr->error |= ERROR_U_DBS;
 359          g_string_sprintfa(tr->error_script,"E[%d][%s]:%s\n", ERROR_U_DBS, t_ipn[i], SQ_error(tr->sql_connection));
 360         }
 361        }
 362        
 363        /* Check that this person/role object is not referenced by name (legacy stuff) */
 364        /* But allow overriding this check in NRTM mode and with override_integrity    */
 365        if(tr->dummy==1)break;
 366         
 367        for (i=0; t_ipn[i] != NULL; i++) { 
 368         /* Calculate number of references */
 369         
 370         g_string_sprintf(query, "SELECT COUNT(*) FROM %s, person_role "
 371                                 "WHERE person_role.object_id=%s.pe_ro_id "
 372                                 "AND person_role.nic_hdl='%s' ", t_ipn[i], t_ipn[i], tr->save);
 373         
 374         sql_str= get_qresult_str(tr->sql_connection, query->str);
 375         if(sql_str) {
 376          num_rec = atol(sql_str);  free(sql_str);
 377          /* If there are references (no self reference is possible in this case) we cannot delete */
 378          if(num_rec>0) {
 379            g_string_sprintfa(tr->error_script,"E[%d][%ld]:ref integrity: %s\n" ,ERROR_U_OBJ, num_rec, t_ipn[i]);
 380            tr->succeeded=0; tr->error |= ERROR_U_OBJ;
 381          }
 382         } else {
 383         /* SQL error occured */
 384          tr->succeeded=0; tr->error |= ERROR_U_DBS;
 385          g_string_sprintfa(tr->error_script,"E[%d][%s]:%s\n", ERROR_U_DBS, t_ipn[i], SQ_error(tr->sql_connection));
 386         }
 387        }
 388           
 389        break;
 390         
 391     case C_MT:
 392     
 393         /* Check that this mntner object is not referenced */
 394         
 395        for (i=0; t_imt[i] != NULL; i++) { 
 396        /* Calculate number of references */
 397         sql_str= get_field_str(tr->sql_connection, "COUNT(*)", t_imt[i], "mnt_id", sobject_id, NULL);
 398         if(sql_str) {
 399          num_rec = atol(sql_str);  free(sql_str);
 400          ref_id=tr->object_id;
 401          /* Check if it is a self reference  */
 402          if(num_rec==1) { 
 403             sql_str= get_field_str(tr->sql_connection, "object_id", t_imt[i], "mnt_id", sobject_id, NULL);
 404             if(sql_str) {
 405               ref_id = atol(sql_str);  free(sql_str);
 406             } else {
 407               tr->succeeded=0; tr->error |= ERROR_U_DBS; break;
 408             } 
 409          }
 410          /* If there are references (and not the only self reference) we cannot delete */ 
 411          if((num_rec>1) || (ref_id!=tr->object_id)) {
 412            g_string_sprintfa(tr->error_script,"E[%d][%ld]:ref integrity: %s\n" ,ERROR_U_OBJ, num_rec, t_imt[i]);
 413            tr->succeeded=0; tr->error |= ERROR_U_OBJ;
 414          }
 415         } else {
 416          tr->succeeded=0; tr->error |= ERROR_U_DBS;
 417         }
 418        }   
 419        break;
 420         
 421     case C_RS:
 422     case C_AS:
 423         /* Check that this set object is not referenced */
 424         /* Calculate number of references */
 425         sql_str= get_field_str(tr->sql_connection, "COUNT(*)", "member_of", "set_id", sobject_id, NULL);
 426         if(sql_str) {
 427          num_rec = atol(sql_str);  free(sql_str);
 428          /* XXX though set may contain other sets as memebers, */
 429          /* there is no member-of attribute in these objects. */
 430          /* So no self-reference is possible */
 431          if(num_rec!=0) {
 432            g_string_sprintfa(tr->error_script,"E[%d][%ld]:ref integrity: %s\n" ,ERROR_U_OBJ, num_rec, "member_of");
 433            /*tr->succeeded=0; tr->error |= ERROR_U_OBJ;*/
 434           /* XXX Do not refuse the transaction but change the object to dummy */
 435           /* Update the history table */
 436                g_string_sprintf(query,  "INSERT history "
 437                                         "SELECT 0, object_id, sequence_id, timestamp, object_type, object "
 438                                         "FROM last "
 439                                         "WHERE object_id=%ld ", tr->object_id);
 440 
 441       
 442                sql_err = SQ_execute_query(tr->sql_connection, query->str, (SQ_result_set_t **)NULL);
 443                if (sql_err) {
 444                 fprintf(stderr, "E ERROR!<perform_update>: INSERT history failed:[%d][%s]\n", num, query->str);
 445                 tr->succeeded=0;
 446                 tr->error |=ERROR_U_DBS;
 447                }
 448 
 449                /* get sequence number */
 450                tr->sequence_id = get_sequence_id(tr);
 451                tr->sequence_id++;
 452        
 453                /* insert new version into the last */
 454                timestamp=time(NULL);
 455               
 456               /* update the main table */
 457               g_string_sprintf(query, "UPDATE %s SET dummy=1 WHERE object_id=%ld ", DF_get_class_sql_table(tr->class_type), tr->object_id);
 458 
 459               sql_err = SQ_execute_query(tr->sql_connection, query->str, (SQ_result_set_t **)NULL);
 460               if (sql_err) {
 461                fprintf(stderr, "E ERROR!<perform_update>: UPDATE last failed: [%d][%s]\n", num, query->str);
 462                tr->succeeded=0;
 463                tr->error |= ERROR_U_DBS;
 464               }
 465  
 466               /* empty the contents, but leave in the table to restrict re-use of object_id */ 
 467               g_string_sprintf(query, "UPDATE last SET object='DUMMY SET', object_type=%d, sequence_id=%ld, timestamp=%ld  WHERE object_id=%ld ", DUMMY_TYPE, tr->sequence_id, timestamp, tr->object_id);
 468 
 469               sql_err = SQ_execute_query(tr->sql_connection, query->str, (SQ_result_set_t **)NULL);
 470               if (sql_err) {
 471                fprintf(stderr, "E ERROR!<perform_update>: UPDATE last failed: [%d][%s]\n", num, query->str);
 472                tr->succeeded=0;
 473                tr->error |= ERROR_U_DBS;
 474               }
 475               return(0);
 476 
 477          }
 478         } else {
 479          tr->succeeded=0; tr->error |= ERROR_U_DBS;
 480         }
 481         break;
 482 
 483     default:
 484         break;    
 485    } 
 486    
 487  /* Check if we have passed referential integrity check */  
 488  if(tr->succeeded==0){
 489        return(-1);
 490  }
 491           
 492 
 493 /* Lock all relevant tables */
 494     g_string_sprintf(query, "LOCK TABLES %s WRITE,", DF_get_class_sql_table(tr->class_type));
 495     
 496     for (i=0; tables[tr->class_type][i] != NULL; i++) 
 497       g_string_sprintfa(query, " %s WRITE,", tables[tr->class_type][i]);
 498     
 499     for (i=TAB_START; tables[tr->class_type][i] != NULL; i++)
 500       g_string_sprintfa(query, " %s WRITE,", tables[tr->class_type][i]);
 501     
 502     g_string_sprintfa(query, " last WRITE, history WRITE ");
 503     
 504     sql_err = SQ_execute_query(tr->sql_connection, query->str, (SQ_result_set_t **)NULL);
 505 
 506     for (i=TAB_START; tables[tr->class_type][i] != NULL; i++) {
 507     g_string_sprintf(query, "DELETE FROM %s WHERE object_id=%ld ", tables[tr->class_type][i], tr->object_id);
 508     sql_err = SQ_execute_query(tr->sql_connection, query->str, (SQ_result_set_t **)NULL);
 509     /*    fprintf(stderr, "D: query (delete): %s\n", query->str);*/
 510   }
 511 
 512 /* Process the MAIN table  */
 513     g_string_sprintf(query, "DELETE FROM %s WHERE object_id=%ld ", DF_get_class_sql_table(tr->class_type), tr->object_id);
 514     sql_err = SQ_execute_query(tr->sql_connection, query->str, (SQ_result_set_t **)NULL);
 515 
 516 /* Update the history table */
 517     g_string_sprintf(query,     "INSERT history "
 518                                 "SELECT 0, object_id, sequence_id, timestamp, object_type, object "
 519                                 "FROM last "
 520                                 "WHERE object_id=%ld ", tr->object_id);
 521 
 522       
 523   sql_err = SQ_execute_query(tr->sql_connection, query->str, (SQ_result_set_t **)NULL);
 524   if (sql_err) {
 525          fprintf(stderr, "E ERROR!<perform_update>: INSERT history failed:[%d][%s]\n", num, query->str);
 526          tr->succeeded=0;
 527          tr->error |=ERROR_U_DBS;
 528   }
 529 
 530   /* get sequence number */
 531   tr->sequence_id = get_sequence_id(tr);
 532   tr->sequence_id++;
 533        
 534   /* insert new version into the last */
 535   timestamp=time(NULL);
 536   
 537  /* empty the contents, but leave in the table to restrict re-use of object_id */ 
 538   g_string_sprintf(query, "UPDATE last SET object='', timestamp=%ld  WHERE object_id=%ld ", timestamp, tr->object_id);
 539 
 540   sql_err = SQ_execute_query(tr->sql_connection, query->str, (SQ_result_set_t **)NULL);
 541   if (sql_err) {
 542         fprintf(stderr, "E ERROR!<perform_update>: UPDATE last failed: [%d][%s]\n", num, query->str);
 543          tr->succeeded=0;
 544          tr->error |= ERROR_U_DBS;
 545   }
 546 
 547 
 548   /* Do more in the forest
 549    * Update radix tree for route and inetnum
 550    */
 551   if(tr->standalone==0) { /* only if server */
 552   /* Collect some data for radix tree and NH repository update */
 553     g_slist_foreach((tr->object)->attributes, get_rx_data, tr);
 554 
 555     /* Only for these types of objects and only if we have collected data (tr->save != NULL) */
 556     if( (   (tr->class_type==C_RT) 
 557          || (tr->class_type==C_IN) 
 558          || (tr->class_type==C_I6)
 559          || (tr->class_type==C_DN))
 560         && (ACT_UPD_RX(tr->action))) {
 561       rp_upd_pack_t *packptr = tr->packptr;
 562       
 563       packptr->key = tr->object_id;
 564       if( RP_pack_node(RX_OPER_DEL, packptr, tr->source_hdl) == RX_OK ) {
 565         err = 0;
 566       } else {
 567         err = (-1) ;
 568       }
 569     }
 570   }
 571   
 572  /* Unlock all tables */
 573   g_string_sprintf(query, "UNLOCK TABLES ");
 574   sql_err = SQ_execute_query(tr->sql_connection, query->str, (SQ_result_set_t **)NULL);
 575 
 576   g_string_free(query, TRUE);
 577 
 578   return(err);
 579 
 580 } /* delete() */              

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