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

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