modules/nh/nh.c

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

DEFINITIONS

This source file includes following functions.
  1. NH_convert
  2. NH_parse
  3. NH_check
  4. NH_free
  5. NH_register
  6. free_nh
  7. get_range
  8. update_range
  9. create_range
  10. NH_comrol

   1 /***************************************
   2   $Revision: 1.16 $
   3 
   4   Status: NOT REVUED, NOT TESTED
   5 
   6  Author(s):       Andrei Robachevsky
   7 
   8   ******************/ /******************
   9   Modification History:
  10         andrei (10/04/2000) Created.
  11   ******************/ /******************
  12   Copyright (c) 2000,2001,2002                    RIPE NCC
  13  
  14   All Rights Reserved
  15   
  16   Permission to use, copy, modify, and distribute this software and its
  17   documentation for any purpose and without fee is hereby granted,
  18   provided that the above copyright notice appear in all copies and that
  19   both that copyright notice and this permission notice appear in
  20   supporting documentation, and that the name of the author not be
  21   used in advertising or publicity pertaining to distribution of the
  22   software without specific, written prior permission.
  23   
  24   THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  25   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
  26   AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
  27   DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
  28   AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  29   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  30  ***************************************/
  31 
  32 #include "rip.h"
  33 
  34 #include <glib.h>
  35 #include <stdio.h>
  36 #include <strings.h>
  37 #include <glib.h>
  38 #include <stdlib.h>
  39 #include <ctype.h>
  40 #include <unistd.h>
  41 
  42 /*+ String sizes +*/
  43 #define STR_S   63
  44 #define STR_M   255
  45 #define STR_L   1023
  46 #define STR_XL  4095
  47 #define STR_XXL 16383
  48 #define STR_XXXL 65535
  49 
  50 /*
  51 CREATE TABLE nic_hdl (
  52   thread_id(11) DEFAULT '0' NOT NULL,
  53   range_id int(10) unsigned DEFAULT '0' NOT NULL auto_increment, 
  54   range_start int(10) DEFAULT '0' NOT NULL,
  55   range_end int(10) DEFAULT '0' NOT NULL,
  56   space char(4) DEFAULT '' NOT NULL,
  57   source char(10) DEFAULT '' NOT NULL,
  58   PRIMARY KEY (range_id, range_start, range_end)
  59 );
  60 
  61 */
  62 
  63 #define get_min_range(prange, sql_connection) get_range(MIN_NIC_ID, prange, sql_connection)
  64 static long get_range(long nic_id, range_t *prange, SQ_connection_t *sql_connection);
  65 static long update_range(long range_id, range_t *p_newrange, SQ_connection_t *sql_connection, int commit_now);
  66 static long create_range(range_t *p_range, SQ_connection_t *sql_connection, int commit_now);
  67 
  68 /************************************************************
  69 * int NH_convert()                                          *
  70 *                                                           *
  71 * Converts space & nic_id into a database nic-handle        *
  72 *                                                           *
  73 * Returns:                                                  *
  74 * The newly allocated string containing nic handle          *
  75 * The string should be freed when no longer used            *
  76 *                                                           *
  77 * NULL in case of failure                                   *
  78 *                                                           *
  79 ************************************************************/
  80 char *NH_convert(nic_handle_t *nh_ptr)
     /* [<][>][^][v][top][bottom][index][help] */
  81 {
  82  char *nic_id=NULL;
  83  char *nic_components[4];
  84  char *nic_handle;
  85  int nc=0;
  86   /* Check for special cases */
  87   /* Is is and AUTO nic-handle ? */
  88   if(nh_ptr->nic_id == AUTO_NIC_ID) return(NULL);
  89   if(nh_ptr->space) {
  90           nic_components[nc]=nh_ptr->space; nc++;
  91   }
  92   /* No nic-id ? */
  93   if(nh_ptr->nic_id != NULL_NIC_ID) { 
  94           nic_id = g_strdup_printf("%ld", nh_ptr->nic_id);
  95           nic_components[nc]=nic_id; nc++;
  96   }
  97           
  98   /* No source ? */
  99   if (nh_ptr->source) {
 100           nic_components[nc]=nh_ptr->source; nc++;
 101   }
 102   nic_components[nc]=NULL;
 103   nic_handle = g_strjoinv(NULL, nic_components);
 104   UT_free(nic_id);
 105   return(nic_handle);
 106 }
 107 
 108 /************************************************************
 109 * int NH_parse()                                            *
 110 *                                                           *
 111 * Parse a nic handle as supplied by DBupdate                *
 112 * The format is: <space>[<nic_id>|*][SOURCE]                *
 113 * Also extracts nic_id and space for regular nic-handles    *
 114 *                                                           *
 115 * Acceptable format is:                                     *
 116 * [A-Z][A-Z]*[1-9][0-9]*(-[A-Z][A-Z]*)?                     *
 117 *                                                           *
 118 * Returns:                                                  *
 119 * >0 - success                                              *
 120 *  0 - AUTO NIC                                             *
 121 * -1  - error                                               *
 122 *                                                           *
 123 ************************************************************/
 124 int NH_parse(const char *nic, nic_handle_t **nh_ptr_ptr)
     /* [<][>][^][v][top][bottom][index][help] */
 125 {
 126 const char *ptr;
 127 int res = 1;
 128 nic_handle_t *nh_ptr;
 129 
 130      *nh_ptr_ptr=NULL;
 131      if(!(nh_ptr=UT_calloc(1, sizeof(nic_handle_t)))) die;
 132      
 133      ptr=nic;   
 134 
 135      /* extract space */
 136      while(isalpha((int)*ptr))ptr++;
 137 
 138      /* sanity check - space <=4 characters */
 139      if((ptr-nic)>MAX_NH_SPACE_LENGTH) {
 140        UT_free(nh_ptr);
 141        return(-1);
 142      }
 143 
 144      if(!(nh_ptr->space=UT_malloc(ptr-nic+1))) die;
 145      strncpy(nh_ptr->space, nic, ptr-nic); *(nh_ptr->space+(ptr-nic))='\0';
 146 
 147      /* If there are no digits, then this is no nic-hdl */
 148      /* We reserve NULL_NIC_ID for such pretty identifiers */
 149      if(*ptr == '\0') {
 150        nh_ptr->nic_id=NULL_NIC_ID;
 151        nh_ptr->source=NULL;
 152      }
 153      else {
 154        /* Check if it is and AUTO nic */
 155        if (*ptr == '*') {
 156                /* For AUTO nic_id we reserve AUTO_NIC_ID */
 157                nh_ptr->nic_id=AUTO_NIC_ID;
 158                res=0;
 159                ptr++;
 160        } else {
 161          nic=ptr;
 162          /* convert digits (if any) and store first invalid characted in ptr */
 163          if(isdigit((int)*nic)){
 164              nh_ptr->nic_id=(int)strtol(nic, (char **)&ptr, 10);
 165          } else {    
 166              /* There were no digits at all */
 167              nh_ptr->nic_id=NULL_NIC_ID;
 168          }    
 169        }
 170        /* sanity check - if the ID does not exeed NH_MAX_ID */
 171        if(nh_ptr->nic_id > MAX_NIC_ID) {
 172          if(nh_ptr) {
 173            UT_free(nh_ptr->space);UT_free(nh_ptr);
 174          }
 175          return(-1);
 176        }
 177        /* check if there is any suffix */
 178        if (*ptr == '\0') nh_ptr->source=NULL;
 179        /* Copy suffix into source */
 180        else {
 181          /* sanity check - suffix does not exceed the length */
 182          if(strlen(ptr)>MAX_NH_SOURCE_LENGTH) {
 183              if(nh_ptr){
 184                UT_free(nh_ptr->space);UT_free(nh_ptr);
 185              }
 186              return(-1);
 187          }
 188          if(!(nh_ptr->source=UT_malloc(strlen(ptr)+1))) die;
 189          strcpy(nh_ptr->source, ptr);
 190        }
 191      } 
 192      *nh_ptr_ptr=nh_ptr;
 193      return(res);
 194 }
 195 
 196 
 197 
 198 /************************************************************
 199 * int NH_check()                                            *
 200 *                                                           *
 201 * Check a NIC handle in the repository                      *
 202 *                                                           *
 203 *                                                           *
 204 * Returns:                                                  *
 205 *  1 - success                                              *
 206 *  0 - error(nic_id exists or space is fully occupied)      *
 207 * -1 - error (f.e. more than one object with the same PK)   *
 208 *                                                           *
 209 ************************************************************/
 210 int NH_check(nic_handle_t *nh_ptr, SQ_connection_t *sql_connection)
     /* [<][>][^][v][top][bottom][index][help] */
 211 {
 212 range_t range;
 213 long range_id;
 214 long nic_id=nh_ptr->nic_id;
 215 
 216 
 217   range.space=nh_ptr->space;
 218   if(nh_ptr->source)range.source=nh_ptr->source; else range.source="";
 219   
 220   if (nic_id == AUTO_NIC_ID) {
 221   /* NIC handle is an AUTO one */
 222   /* get first range (with min range_end) for a given space */
 223    range_id = get_min_range(&range, sql_connection); 
 224    if(range_id<0)  return(-1); /* in case of an error */
 225 
 226    if ( range_id==0 ) {
 227   /* Nothing found */
 228   /* Allocate a hic-hdl in a new space with the first range {0-1} in it*/
 229         nic_id=1;
 230    } else {
 231       if ( range.end == MAX_NIC_ID ) return(0); /* space is fully occupied  */
 232       /* attach to range and may be join with next */
 233        nic_id = range.end+1;
 234    }
 235   }
 236 /* if not AUTO */  
 237   else {
 238     range_id = get_range(nic_id, &range, sql_connection);
 239     if(range_id <0)  return(-1); /* in case of an error */
 240     if(range_id!=0)  return(0); /* this nic_id already exists */
 241   }
 242   nh_ptr->nic_id=nic_id;
 243  return(1); 
 244 }
 245 
 246 /************************************************************
 247 * long NH_free()                                             *
 248 *                                                           *
 249 * Delete a NIC handle from the repository                   *
 250 *                                                           *
 251 * To finalize changes make commit/rollback                  *
 252 *                                                           *
 253 * Returns:                                                  *
 254 *  1 - success                                              *
 255 *  0 - error (range is not founnd)                          *
 256 * -1 - error (f.e. more than one object with the same PK)   *
 257 *                                                           *
 258 ************************************************************/
 259 int NH_free(nic_handle_t *nh_ptr, SQ_connection_t *sql_connection, int commit_now)
     /* [<][>][^][v][top][bottom][index][help] */
 260 {
 261 range_t range;
 262 long range_id;
 263 int old_start;
 264 long nic_id=nh_ptr->nic_id;
 265 
 266 
 267   range.space=nh_ptr->space;
 268   if(nh_ptr->source)range.source=nh_ptr->source; else range.source="";
 269   
 270   /* Search for the range containing the nic-handle */
 271   range_id = get_range(nic_id, &range, sql_connection);
 272   /* If range is not found or an error occcured - return */
 273   if(range_id==0) { return(0); }
 274   if(range_id<0)  { return(-1); }
 275   
 276   if(nic_id == range.start) {
 277   /* update range start and may be detele range and space */
 278    range.start+=1;
 279    range_id=update_range(range_id, &range, sql_connection, commit_now);
 280    if(range_id<=0) {  return(-1); }
 281   }
 282   else if(nic_id == range.end) { 
 283   /* update range end and may be detele range and space */
 284          range.end-=1;
 285          range_id=update_range(range_id, &range, sql_connection, commit_now);
 286          if(range_id<=0) {  return(-1); }
 287   }
 288   else { 
 289        /* split the range into two */ 
 290        /* shrink the old one */
 291          old_start=range.start;
 292          range.start=nic_id+1;
 293          range_id=update_range(range_id, &range, sql_connection, commit_now);
 294          if(range_id<=0) { return(-1); }
 295        /* create a new one */
 296          range.start=old_start;
 297          range.end=nic_id-1;
 298          range_id=create_range(&range, sql_connection, commit_now);
 299          if(range_id<=0) {  return(-1); }
 300   }
 301   
 302   return(1);
 303 }
 304 
 305 
 306 /************************************************************
 307 * int NH_register()                                         *
 308 *                                                           *
 309 * Get a NIC handle from the repository                      *
 310 *                                                           *
 311 *                                                           *
 312 * Returns:                                                  *
 313 * 1 - success                                               *
 314 * 0  - nic_id already exists or space is fully occupied     *
 315 * -1 - error (f.e. more than one object with the same PK)   *
 316 *                                                           *
 317 ************************************************************/
 318 int NH_register(nic_handle_t *nh_ptr, SQ_connection_t *sql_connection, int commit_now)
     /* [<][>][^][v][top][bottom][index][help] */
 319 {
 320 range_t range;
 321 long range_id;
 322 long nic_id=nh_ptr->nic_id;
 323 
 324 
 325 
 326 
 327  /* Yiu should check for nh first for AUTO nic-handles */
 328   if (nic_id == AUTO_NIC_ID) { return(0); };
 329 
 330   range.space=nh_ptr->space;
 331   if(nh_ptr->source)range.source=nh_ptr->source; else range.source="";
 332 
 333   range_id = get_range(nic_id, &range, sql_connection);
 334   if(range_id <0)  { return(-1); } /* in case of an error */
 335   if(range_id!=0)  { return(0); } /* this nic_id already exists */
 336  
 337   /* check if we can attach to existing next range */
 338   range_id = get_range(nic_id+1, &range, sql_connection);
 339   if(range_id <0)  { return(-1); } /* in case of an error */
 340 
 341     if( range_id>0 ) { 
 342     /* attach to range and may be join with previous */ 
 343      range.start-=1;
 344      range_id=update_range(range_id, &range, sql_connection, commit_now);
 345      if(range_id<=0) { return(-1); }
 346     }
 347     else {
 348      /* check if we can attach to existing previous range */
 349       if(nic_id>0) range_id = get_range(nic_id-1, &range, sql_connection);
 350       else range_id=0; /* there is no previous range in this case (nic_id==0) */
 351       if(range_id <0)  { return(-1); } /* in case of an error */
 352       if( range_id>0 ) { 
 353       /* attach to range and may be join with next */
 354        range.end+=1;
 355        range_id=update_range(range_id, &range, sql_connection, commit_now);
 356        if(range_id<=0) { return(-1); }
 357       }
 358       else {
 359        /* If we cannot attach to any existing range - create new {nic_id-nic_id} */
 360        range.end=range.start=nic_id;
 361        range_id=create_range(&range, sql_connection, commit_now);
 362        if(range_id <=0)  { return(-1); } /* in case of an error */
 363       }
 364     }  
 365  return(1);
 366 }
 367 
 368 /*
 369  Free nic_handle_t structure 
 370  */
 371 void free_nh(nic_handle_t *nh_ptr)
     /* [<][>][^][v][top][bottom][index][help] */
 372 {
 373  if(nh_ptr){
 374    if(nh_ptr->space) UT_free(nh_ptr->space);
 375    if(nh_ptr->source) UT_free(nh_ptr->source);
 376    UT_free(nh_ptr);
 377  }
 378 }
 379 
 380 
 381 /************************************************************
 382 * long get_range()                                          *
 383 *                                                           *
 384 * Searches for the range of the space containing            *
 385 * the specified nic_id                                      *
 386 *                                                           *
 387 * To request to search for the firt (min) range, nic_id     *
 388 * should be set to MIN_NIC_ID                               *
 389 *                                                           *
 390 * Returns:                                                  *
 391 * >0 - range exists, returns range_id                       *
 392 * 0  - range does not exist                                 *
 393 * -1 - DB error (f.e. more than one object with the same PK)*
 394 *                                                           *
 395 * **********************************************************/
 396 static long get_range(long nic_id, range_t *prange, SQ_connection_t *sql_connection)
     /* [<][>][^][v][top][bottom][index][help] */
 397 {
 398 SQ_result_set_t *sql_result;
 399 SQ_row_t *sql_row;
 400 char *sql_str;
 401 GString *query;
 402 long range_id=0;
 403 int sql_err;
 404 
 405  query = g_string_sized_new(STR_L);
 406  
 407 /* Define row numbers in the result of the query */
 408 #define RANGE_ID 0
 409 #define RANGE_START 1
 410 #define RANGE_END 2
 411  
 412  if (nic_id==MIN_NIC_ID) {
 413   /* requesting the first (min) range */
 414   g_string_sprintf(query, "SELECT range_id, range_start, range_end " 
 415                           "FROM nic_hdl "
 416                           "WHERE space='%s' "
 417                           "AND source='%s' "
 418                           "AND (range_start=0 "
 419                           "OR  range_start=1) ",
 420                           prange->space, prange->source);
 421  } else {
 422 
 423   g_string_sprintf(query, "SELECT range_id, range_start, range_end " 
 424                           "FROM nic_hdl "
 425                           "WHERE space='%s' "
 426                           "AND source='%s' "
 427                           "AND range_start<=%ld "
 428                           "AND range_end>=%ld ",
 429                           prange->space, prange->source, nic_id, nic_id);
 430  }
 431         
 432 /* execute query */
 433 /* fprintf(stderr, "get_range[%s]\n", query->str); */
 434  sql_err=SQ_execute_query(sql_connection, query->str, &sql_result);
 435  g_string_free(query, TRUE);
 436  
 437  if(sql_err) {
 438    fprintf(stderr,"ERROR: %s\n", SQ_error(sql_connection));
 439    return(-1);
 440  }
 441 
 442  if ((sql_row = SQ_row_next(sql_result)) != NULL) {
 443 /* Object exists */
 444    sql_str = SQ_get_column_string(sql_result, sql_row, RANGE_ID);
 445    if (sql_str != NULL) {
 446      range_id = atol(sql_str);
 447      UT_free(sql_str);
 448    }
 449    sql_str = SQ_get_column_string(sql_result, sql_row, RANGE_START);
 450    if (sql_str != NULL) {
 451      prange->start = atoi(sql_str);
 452      UT_free(sql_str);
 453    }
 454    sql_str = SQ_get_column_string(sql_result, sql_row, RANGE_END);
 455    if (sql_str != NULL) {
 456      prange->end = atoi(sql_str);
 457      UT_free(sql_str);
 458    }
 459 
 460 /* We must process all the rows of the result */
 461 /* otherwise we'll have them as part of the next qry */      
 462    while ( (sql_row = SQ_row_next(sql_result)) != NULL) range_id=-1;
 463  } else 
 464       range_id=0;  // object does not exist
 465    
 466  if(sql_result)SQ_free_result(sql_result);
 467  return(range_id);
 468 }
 469 
 470 
 471 
 472 
 473 /************************************************************
 474 * long update_range()                                       *
 475 *                                                           *
 476 * Updates the range by changing the boundaries              *
 477 * Deletes the range if nothing left                         *
 478 * Merges with neighbor ranges if there is no gap between    *
 479 *                                                           *
 480 * We never update range. We create a new one with specified * 
 481 * limits and mark old one(s) for deletion, so that we can   *
 482 * make commit/rollback properly. This is possible as the    * 
 483 * primary keys are (range_id, range_start, range_end)       *
 484 *                                                           *
 485 * To finalize changes make commit/rollback                  *
 486 *                                                           *
 487 * Returns:                                                  *
 488 * >0 - returns range_id on success                          *
 489 * -1 - error (f.e. more than one object with the same PK)   *
 490 *                                                           *
 491 ************************************************************/
 492               
 493 static long update_range(long range_id, range_t *p_newrange, SQ_connection_t *sql_connection, int commit_now)
     /* [<][>][^][v][top][bottom][index][help] */
 494 {
 495 GString *query;
 496 range_t range;
 497 long prev_range_id, next_range_id;
 498 int num;
 499 int sql_err;
 500 
 501  query = g_string_sized_new(STR_L);
 502 
 503 /* Do range check */
 504  if (( p_newrange->end > MAX_RANGE ) || ( p_newrange->start < MIN_RANGE )) return(-1);
 505 
 506 /* Check if the range collapses */
 507  if ( p_newrange->end < p_newrange->start ) {
 508  /* then delete the range */  
 509  /* Do this by marking the range for deletion for further commit/rollback */
 510   if(commit_now)
 511    g_string_sprintf(query, "DELETE FROM nic_hdl " 
 512                            "WHERE range_id=%ld ",
 513                             range_id);
 514   else  
 515    g_string_sprintf(query, "UPDATE nic_hdl SET thread_id=%d "
 516                            "WHERE range_id=%ld ",
 517                             NH_DELETE, range_id);   
 518       
 519 /*   fprintf(stderr, "update_range[%s]\n", query->str); */
 520    sql_err=SQ_execute_query(sql_connection, query->str, (SQ_result_set_t **)NULL);
 521    if(sql_err) {
 522     /* An error occured */
 523     g_string_free(query, TRUE);
 524     return(-1);
 525    }
 526    num = SQ_get_affected_rows(sql_connection); 
 527    /* this should not happen */
 528    if(num==0) die;
 529  
 530  }
 531  else {
 532   /* update the range for the same space/source */
 533   range.space=p_newrange->space;
 534   range.source=p_newrange->source; 
 535   /* Check if we can join with previous range of the same space */
 536   prev_range_id=get_range(p_newrange->start-1, &range, sql_connection);
 537   /* Check if such range exists and it is not ours (this happens when we are shrinking */
 538   if((prev_range_id>0) && (prev_range_id!=range_id)) {
 539    /* acquire the previous range */
 540    /* mark it for deletion for commit/rollback */
 541    if(commit_now)
 542       g_string_sprintf(query, "DELETE FROM nic_hdl "
 543                               "WHERE range_id=%ld ",
 544                                prev_range_id);
 545    else
 546       g_string_sprintf(query, "UPDATE nic_hdl SET thread_id=%d "
 547                               "WHERE range_id=%ld ",
 548                                NH_DELETE, prev_range_id);   
 549 
 550 
 551 
 552 /*    fprintf(stderr, "update_range[%s]\n", query->str); */
 553    sql_err=SQ_execute_query(sql_connection, query->str, (SQ_result_set_t **)NULL);
 554    if(sql_err) {
 555     /* An error occured */
 556     g_string_free(query, TRUE);
 557     return(-1);
 558    }
 559    num = SQ_get_affected_rows(sql_connection); 
 560    /* this should not happen */
 561    if(num==0) die;
 562    
 563    /* expand the boundaries */
 564    p_newrange->start=range.start;
 565   }
 566 
 567 /* Check if we can join with next range of the same space */
 568   next_range_id=get_range(p_newrange->end+1, &range, sql_connection);
 569   /* Check if such range exists and it is not ours (this happens when we are shrinking) */
 570   if((next_range_id>0) && (next_range_id!=range_id)) {
 571    /* acquire the next range */
 572    /* mark it for deletion for commit/rollback */
 573    if(commit_now)
 574      g_string_sprintf(query, "DELETE FROM nic_hdl "
 575                              "WHERE range_id=%ld ",
 576                               next_range_id);
 577    else    
 578      g_string_sprintf(query, "UPDATE nic_hdl SET thread_id=%d "
 579                              "WHERE range_id=%ld ",
 580                               NH_DELETE, next_range_id);   
 581 
 582 
 583 
 584 /*   fprintf(stderr, "update_range[%s]\n", query->str); */
 585    sql_err=SQ_execute_query(sql_connection, query->str, (SQ_result_set_t **)NULL);
 586    if(sql_err) {
 587     /* An error occured */
 588     g_string_free(query, TRUE);
 589     return(-1);
 590    }
 591    num = SQ_get_affected_rows(sql_connection); 
 592    /* this should not happen */
 593    if(num==0) die;
 594    
 595    /* expand the boundaries */
 596    p_newrange->end=range.end;
 597   }
 598  
 599 /* Now make a larger range. Mark current for deletion and new for commit/rollback */ 
 600   if(commit_now)
 601    g_string_sprintf(query, "UPDATE nic_hdl "
 602                            "SET range_start=%ld, range_end=%ld "
 603                            "WHERE range_id=%ld",
 604                            p_newrange->start, p_newrange->end, range_id);
 605   else {
 606 
 607    g_string_sprintf(query, "UPDATE nic_hdl SET thread_id=%d "
 608                            "WHERE range_id=%ld ",
 609                            NH_DELETE, range_id);
 610 /*   fprintf(stderr, "update_range[%s]\n", query->str); */
 611    sql_err=SQ_execute_query(sql_connection, query->str, (SQ_result_set_t **)NULL);
 612    if(sql_err) {
 613     /* An error occured */
 614     g_string_free(query, TRUE);
 615     return(-1);
 616    }
 617    num = SQ_get_affected_rows(sql_connection); 
 618    /* this should not happen */
 619    if(num==0) die;
 620    
 621    g_string_sprintf(query, "INSERT nic_hdl "
 622                            "SET thread_id=%d, range_id=%ld, space='%s', source='%s', range_start=%ld, range_end=%ld ",
 623                            NH_INSERT, range_id, p_newrange->space, p_newrange->source, p_newrange->start, p_newrange->end);  
 624   } 
 625 
 626 /*   fprintf(stderr, "update_range[%s]\n", query->str); */
 627    sql_err=SQ_execute_query(sql_connection, query->str, (SQ_result_set_t **)NULL);
 628    if(sql_err) {
 629     /* An error occured */
 630     g_string_free(query, TRUE);
 631     return(-1);
 632    }
 633    num = SQ_get_affected_rows(sql_connection); 
 634    /* this should not happen */
 635    if(num==0) die;
 636  } /* update the range */
 637 
 638  g_string_free(query, TRUE);
 639  return (range_id);
 640 }
 641                
 642 /************************************************************
 643 * long create_range()                                       *
 644 *                                                           *
 645 * Creates a new range in a given name space                 *
 646 *                                                           *
 647 * To finalize changes make commit/rollback                  *
 648 *                                                           *
 649 * Returns:                                                  *
 650 * >0 - returns range_id on success                          *
 651 * -1 - error (f.e. more than one object with the same PK)   *
 652 *                                                           *
 653 ************************************************************/
 654                 
 655 static long create_range(range_t *p_range, SQ_connection_t *sql_connection, int commit_now)
     /* [<][>][^][v][top][bottom][index][help] */
 656 {
 657 GString *query;
 658 int sql_err, num;
 659 long range_id;
 660 
 661  query = g_string_sized_new(STR_L);
 662  
 663  /* get the next range_id */
 664  /* XXX we cannot use autoincrement with MyISAM tables */
 665  /* XXX because they keep the max inserted id even if  */
 666  /* XXX it was deleted later, thus causing gaps we don't want */
 667  
 668  range_id=SQ_get_max_id(sql_connection, "range_id", "nic_hdl") +1;
 669  
 670  if(commit_now)
 671   g_string_sprintf(query, "INSERT nic_hdl "
 672                           "SET thread_id=0,  range_id=%ld, space='%s', source='%s', range_start=%ld, range_end=%ld ",
 673                            range_id, p_range->space, p_range->source, p_range->start, p_range->end);
 674  else    
 675   g_string_sprintf(query, "INSERT nic_hdl "
 676                           "SET thread_id=%d, range_id=%ld, space='%s', source='%s', range_start=%ld, range_end=%ld ",
 677                            NH_INSERT, range_id, p_range->space, p_range->source, p_range->start, p_range->end);
 678 
 679 /* fprintf(stderr, "create_range[%s]\n", query->str); */
 680  sql_err=SQ_execute_query(sql_connection, query->str, (SQ_result_set_t **)NULL);
 681  g_string_free(query, TRUE);
 682   
 683    if(sql_err) {
 684     /* An error occured */
 685     return(-1);
 686    }
 687    num = SQ_get_affected_rows(sql_connection); 
 688    /* this should not happen */
 689    if(num==0) die;
 690  return(range_id);
 691 }
 692 
 693 
 694 /************************************************************
 695 * int NH_comrol()                                           *
 696 *                                                           *
 697 * Commits or rolls back changes to NHR                      *
 698 *                                                           *
 699 *                                                           *
 700 * Returns:                                                  *
 701 * >0 - success                                              *
 702 * -1 - SQL error                                            *
 703 *                                                           *
 704 ************************************************************/
 705  
 706 int NH_comrol(SQ_connection_t *sql_connection, int thread_ins, int thread_del)
     /* [<][>][^][v][top][bottom][index][help] */
 707 {
 708 GString *query;
 709 int sql_err;
 710 
 711  query = g_string_sized_new(STR_L);
 712  
 713   g_string_sprintf(query, "DELETE FROM nic_hdl "
 714                           "WHERE thread_id=%d ",
 715                           thread_del);
 716 
 717 /* fprintf(stderr, "create_range[%s]\n", query->str); */
 718  sql_err=SQ_execute_query(sql_connection, query->str, (SQ_result_set_t **)NULL);
 719  if(sql_err) {
 720     /* An error occured */
 721     g_string_free(query, TRUE);
 722     fprintf(stderr,"ERROR: %s\n", SQ_error(sql_connection));
 723     die;
 724  }
 725 
 726  g_string_sprintf(query, "UPDATE nic_hdl "
 727                          "SET thread_id=0 "
 728                          "WHERE thread_id=%d ",
 729                           thread_ins);
 730 
 731 /* fprintf(stderr, "create_range[%s]\n", query->str); */
 732  sql_err=SQ_execute_query(sql_connection, query->str, (SQ_result_set_t **)NULL);
 733  g_string_free(query, TRUE);
 734   
 735  if(sql_err) {
 736     /* An error occured */
 737    fprintf(stderr,"ERROR: %s\n", SQ_error(sql_connection));
 738    die;
 739  }
 740  
 741  return(1);
 742                 
 743 }
 744 
 745 

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