## modules/nh/nh.c

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

## FUNCTIONS

This source file includes following functions.

1. get_min_range
2. NH_convert
3. NH_parse
4. NH_check
5. NH_free
6. NH_register
7. free_nh
8. get_range
9. update_range
10. create_range
11. 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)
         /* [<][>][^][v][top][bottom][index][help] */
      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] */