## 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.6 $
       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                              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 #include <glib.h>
      32 #include <stdio.h>
      33 #include <strings.h>
      34 #include <glib.h>
      35 #include <stdlib.h>
      36 #include <ctype.h>
      37 #include <unistd.h>
      38
      39 #include "nh.h"
      40 #include <stubs.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 *                                                           *
      74 * Returns:                                                  *
      75 * The size of the nic_handle in characters                  *
      76 *                                                           *
      77 ************************************************************/
      78 int NH_convert(char *nic, nic_handle_t *nh_ptr)
         /* [<][>][^][v][top][bottom][index][help] */
      79 {
      80   /* Check for special cases */
      81   /* Is is and AUTO nic-handle ? */
      82   if(nh_ptr->nic_id == AUTO_NIC_ID) return(-1);
      83   if(nh_ptr->space) nic+=sprintf(nic, "%s", nh_ptr->space);
      84   /* No nic-id ? */
      85   if(nh_ptr->nic_id != NULL_NIC_ID) nic+=sprintf(nic, "%ld", nh_ptr->nic_id);
      86   /* No source ? */
      87   if (nh_ptr->source) sprintf(nic, "%s", nh_ptr->source);
      88   return(1);
      89 }
      90
      91 /************************************************************
      92 * int NH_parse()                                            *
      93 *                                                           *
      94 * Parse a nic handle as supplied by DBupdate                *
      95 * The format is: <space>[<nic_id>|*][SOURCE]                *
      96 * Also extracts nic_id and space for regular nic-handles    *
      97 *                                                           *
      98 * Acceptable format is:                                     *
      99 * [A-Z][A-Z]*[1-9][0-9]*(-[A-Z][A-Z]*)?                     *
     100 *                                                           *
     101 * Returns:                                                  *
     102 * >0 - success                                              *
     103 *  0 - AUTO NIC                                             *
     104 * -1  - error (not defined and processed yet)               *
     105 *                                                           *
     106 ************************************************************/
     107 int NH_parse(char *nic, nic_handle_t **nh_ptr_ptr)
         /* [<][>][^][v][top][bottom][index][help] */
     108 {
     109 char *ptr;
     110 int res = 1;
     111 nic_handle_t *nh_ptr;
     112
     113      if(!(nh_ptr=calloc(1, sizeof(nic_handle_t)))) die;
     114
     115      ptr=nic;
     116
     117      /* extract space */
     118      while(isalpha((int)*ptr))ptr++;
     119      if(!(nh_ptr->space=malloc(ptr-nic+1))) die;
     120      strncpy(nh_ptr->space, nic, ptr-nic); *(nh_ptr->space+(ptr-nic))='\0';
     121
     122      /* If there are no digits, then this is no nic-hdl */
     123      /* We reserve NULL_NIC_ID for such pretty identifiers */
     124      if(*ptr == '\0') {
     125        nh_ptr->nic_id=NULL_NIC_ID;
     126        nh_ptr->source=NULL;
     127      }
     128      else {
     129        /* Check if it is and AUTO nic */
     130        if (*ptr == '*') {
     131                /* For AUTO nic_id we reserve AUTO_NIC_ID */
     132                nh_ptr->nic_id=AUTO_NIC_ID;
     133                res=0;
     134                ptr++;
     135        } else {
     136          nic=ptr;
     137          /* convert digits (if any) and store first invalid characted in ptr */
     138          nh_ptr->nic_id=(int)strtol(nic, &ptr, 10);
     139          /* Check if there were any digits at all */
     140          if(ptr == nic) nh_ptr->nic_id=NULL_NIC_ID;
     141        }
     142        /* check if there is any suffix */
     143        if (*ptr == '\0') nh_ptr->source=NULL;
     144        /* Copy suffix into source */
     145        else {
     146          if(!(nh_ptr->source=malloc(strlen(ptr)+1))) die;
     147          strcpy(nh_ptr->source, ptr);
     148        }
     149      }
     150      *nh_ptr_ptr=nh_ptr;
     151      return(res);
     152 }
     153
     154
     155
     156 /************************************************************
     157 * int NH_check()                                            *
     158 *                                                           *
     159 * Check a NIC handle in the repository                      *
     160 *                                                           *
     161 *                                                           *
     162 * Returns:                                                  *
     163 *  1 - success                                              *
     164 *  0 - error(nic_id exists or space is fully occupied)      *
     165 * -1 - error (f.e. more than one object with the same PK)   *
     166 *                                                           *
     167 ************************************************************/
     168 int NH_check(nic_handle_t *nh_ptr, SQ_connection_t *sql_connection)
         /* [<][>][^][v][top][bottom][index][help] */
     169 {
     170 range_t range;
     171 long range_id;
     172 long nic_id=nh_ptr->nic_id;
     173
     174
     175   range.space=nh_ptr->space;
     176   if(nh_ptr->source)range.source=nh_ptr->source; else range.source="";
     177
     178   if (nic_id == AUTO_NIC_ID) {
     179   /* NIC handle is an AUTO one */
     180   /* get first range (with min range_end) for a given space */
     181    range_id = get_min_range(&range, sql_connection);
     182    if(range_id<0)  return(-1); /* in case of an error */
     183
     184    if ( range_id==0 ) {
     185   /* Nothing found */
     186   /* Allocate a hic-hdl in a new space with the first range {0-1} in it*/
     187         nic_id=1;
     188    } else {
     189       if ( range.end == MAX_NIC_ID ) return(0); /* space is fully occupied  */
     190       /* attach to range and may be join with next */
     191        nic_id = range.end+1;
     192    }
     193   }
     194 /* if not AUTO */
     195   else {
     196     range_id = get_range(nic_id, &range, sql_connection);
     197     if(range_id <0)  return(-1); /* in case of an error */
     198     if(range_id!=0)  return(0); /* this nic_id already exists */
     199   }
     200   nh_ptr->nic_id=nic_id;
     201  return(1);
     202 }
     203
     204 /************************************************************
     205 * long NH_free()                                             *
     206 *                                                           *
     207 * Delete a NIC handle from the repository                   *
     208 *                                                           *
     209 * To finalize changes make commit/rollback                  *
     210 *                                                           *
     211 * Returns:                                                  *
     212 *  1 - success                                              *
     213 *  0 - error (range is not founnd)                          *
     214 * -1 - error (f.e. more than one object with the same PK)   *
     215 *                                                           *
     216 ************************************************************/
     217 int NH_free(nic_handle_t *nh_ptr, SQ_connection_t *sql_connection, int commit_now)
         /* [<][>][^][v][top][bottom][index][help] */
     218 {
     219 range_t range;
     220 long range_id;
     221 int old_start;
     222 long nic_id=nh_ptr->nic_id;
     223
     224
     225   range.space=nh_ptr->space;
     226   if(nh_ptr->source)range.source=nh_ptr->source; else range.source="";
     227
     228   /* Search for the range containing the nic-handle */
     229   range_id = get_range(nic_id, &range, sql_connection);
     230   /* If range is not found or an error occcured - return */
     231   if(range_id==0) { return(0); }
     232   if(range_id<0)  { return(-1); }
     233
     234   if(nic_id == range.start) {
     235   /* update range start and may be detele range and space */
     236    range.start+=1;
     237    range_id=update_range(range_id, &range, sql_connection, commit_now);
     238    if(range_id<=0) {  return(-1); }
     239   }
     240   else if(nic_id == range.end) {
     241   /* update range end and may be detele range and space */
     242          range.end-=1;
     243          range_id=update_range(range_id, &range, sql_connection, commit_now);
     244          if(range_id<=0) {  return(-1); }
     245   }
     246   else {
     247        /* split the range into two */
     248        /* shrink the old one */
     249          old_start=range.start;
     250          range.start=nic_id+1;
     251          range_id=update_range(range_id, &range, sql_connection, commit_now);
     252          if(range_id<=0) { return(-1); }
     253        /* create a new one */
     254          range.start=old_start;
     255          range.end=nic_id-1;
     256          range_id=create_range(&range, sql_connection, commit_now);
     257          if(range_id<=0) {  return(-1); }
     258   }
     259
     260   return(1);
     261 }
     262
     263
     264 /************************************************************
     265 * int NH_register()                                         *
     266 *                                                           *
     267 * Get a NIC handle from the repository                      *
     268 *                                                           *
     269 *                                                           *
     270 * Returns:                                                  *
     271 * 1 - success                                               *
     272 * 0  - nic_id already exists or space is fully occupied     *
     273 * -1 - error (f.e. more than one object with the same PK)   *
     274 *                                                           *
     275 ************************************************************/
     276 int NH_register(nic_handle_t *nh_ptr, SQ_connection_t *sql_connection, int commit_now)
         /* [<][>][^][v][top][bottom][index][help] */
     277 {
     278 range_t range;
     279 long range_id;
     280 long nic_id=nh_ptr->nic_id;
     281
     282
     283
     284
     285  /* Yiu should check for nh first for AUTO nic-handles */
     286   if (nic_id == AUTO_NIC_ID) { return(0); };
     287
     288   range.space=nh_ptr->space;
     289   if(nh_ptr->source)range.source=nh_ptr->source; else range.source="";
     290
     291   range_id = get_range(nic_id, &range, sql_connection);
     292   if(range_id <0)  { return(-1); } /* in case of an error */
     293   if(range_id!=0)  { return(0); } /* this nic_id already exists */
     294
     295   /* check if we can attach to existing next range */
     296   range_id = get_range(nic_id+1, &range, sql_connection);
     297   if(range_id <0)  { return(-1); } /* in case of an error */
     298
     299     if( range_id>0 ) {
     300     /* attach to range and may be join with previous */
     301      range.start-=1;
     302      range_id=update_range(range_id, &range, sql_connection, commit_now);
     303      if(range_id<=0) { return(-1); }
     304     }
     305     else {
     306      /* check if we can attach to existing previous range */
     307       if(nic_id>0) range_id = get_range(nic_id-1, &range, sql_connection);
     308       else range_id=0; /* there is no previous range in this case (nic_id==0) */
     309       if(range_id <0)  { return(-1); } /* in case of an error */
     310       if( range_id>0 ) {
     311       /* attach to range and may be join with next */
     312        range.end+=1;
     313        range_id=update_range(range_id, &range, sql_connection, commit_now);
     314        if(range_id<=0) { return(-1); }
     315       }
     316       else {
     317        /* If we cannot attach to any existing range - create new {nic_id-nic_id} */
     318        range.end=range.start=nic_id;
     319        range_id=create_range(&range, sql_connection, commit_now);
     320        if(range_id <=0)  { return(-1); } /* in case of an error */
     321       }
     322     }
     323  return(1);
     324 }
     325
     326 /*
     327  Free nic_handle_t structure
     328  */
     329 void free_nh(nic_handle_t *nh_ptr)
         /* [<][>][^][v][top][bottom][index][help] */
     330 {
     331  if(nh_ptr){
     332    if(nh_ptr->space)free(nh_ptr->space);
     333    if(nh_ptr->source)free(nh_ptr->source);
     334    free(nh_ptr);
     335  }
     336 }
     337
     338
     339 /************************************************************
     340 * long get_range()                                          *
     341 *                                                           *
     342 * Searches for the range of the space containing            *
     343 * the specified nic_id                                      *
     344 *                                                           *
     345 * To request to search for the firt (min) range, nic_id     *
     346 * should be set to MIN_NIC_ID                               *
     347 *                                                           *
     348 * Returns:                                                  *
     349 * >0 - range exists, returns range_id                       *
     350 * 0  - range does not exist                                 *
     351 * -1 - DB error (f.e. more than one object with the same PK)*
     352 *                                                           *
     353 * **********************************************************/
     354 static long get_range(long nic_id, range_t *prange, SQ_connection_t *sql_connection)
         /* [<][>][^][v][top][bottom][index][help] */
     355 {
     356 SQ_result_set_t *sql_result;
     357 SQ_row_t *sql_row;
     358 char *sql_str;
     359 GString *query;
     360 long range_id=0;
     361 int sql_err;
     362
     363  if ((query = g_string_sized_new(STR_L)) == NULL){
     364   fprintf(stderr, "E: cannot allocate gstring\n");
     365   return(-1);
     366  }
     367
     368 /* Define row numbers in the result of the query */
     369 #define RANGE_ID 0
     370 #define RANGE_START 1
     371 #define RANGE_END 2
     372
     373  if (nic_id==MIN_NIC_ID) {
     374   /* requesting the first (min) range */
     375   g_string_sprintf(query, "SELECT range_id, range_start, range_end "
     376                           "FROM nic_hdl "
     377                           "WHERE space='%s' "
     378                           "AND source='%s' "
     379                           "AND (range_start=0 "
     380                           "OR  range_start=1) ",
     381                           prange->space, prange->source);
     382  } else {
     383
     384   g_string_sprintf(query, "SELECT range_id, range_start, range_end "
     385                           "FROM nic_hdl "
     386                           "WHERE space='%s' "
     387                           "AND source='%s' "
     388                           "AND range_start<=%ld "
     389                           "AND range_end>=%ld ",
     390                           prange->space, prange->source, nic_id, nic_id);
     391  }
     392
     393 /* execute query */
     394 /* fprintf(stderr, "get_range[%s]\n", query->str); */
     395  sql_err=SQ_execute_query(sql_connection, query->str, &sql_result);
     396  g_string_free(query, TRUE);
     397
     398  if(sql_err) {
     399    fprintf(stderr,"ERROR: %s\n", SQ_error(sql_connection));
     400    return(-1);
     401  }
     402
     403  if ((sql_row = SQ_row_next(sql_result)) != NULL) {
     404 /* Object exists */
     405    sql_str = SQ_get_column_string(sql_result, sql_row, RANGE_ID);
     406    if (sql_str != NULL) {
     407      range_id = atol(sql_str);
     408      free(sql_str);
     409    }
     410    sql_str = SQ_get_column_string(sql_result, sql_row, RANGE_START);
     411    if (sql_str != NULL) {
     412      prange->start = atoi(sql_str);
     413      free(sql_str);
     414    }
     415    sql_str = SQ_get_column_string(sql_result, sql_row, RANGE_END);
     416    if (sql_str != NULL) {
     417      prange->end = atoi(sql_str);
     418      free(sql_str);
     419    }
     420
     421 /* We must process all the rows of the result */
     422 /* otherwise we'll have them as part of the next qry */
     423    while ( (sql_row = SQ_row_next(sql_result)) != NULL) range_id=-1;
     424  } else
     425       range_id=0;  // object does not exist
     426
     427  if(sql_result)SQ_free_result(sql_result);
     428  return(range_id);
     429 }
     430
     431
     432
     433
     434 /************************************************************
     435 * long update_range()                                       *
     436 *                                                           *
     437 * Updates the range by changing the boundaries              *
     438 * Deletes the range if nothing left                         *
     439 * Merges with neighbor ranges if there is no gap between    *
     440 *                                                           *
     441 * We never update range. We create a new one with specified *
     442 * limits and mark old one(s) for deletion, so that we can   *
     443 * make commit/rollback properly. This is possible as the    *
     444 * primary keys are (range_id, range_start, range_end)       *
     445 *                                                           *
     446 * To finalize changes make commit/rollback                  *
     447 *                                                           *
     448 * Returns:                                                  *
     449 * >0 - returns range_id on success                          *
     450 * -1 - error (f.e. more than one object with the same PK)   *
     451 *                                                           *
     452 ************************************************************/
     453
     454 static long update_range(long range_id, range_t *p_newrange, SQ_connection_t *sql_connection, int commit_now)
         /* [<][>][^][v][top][bottom][index][help] */
     455 {
     456 GString *query;
     457 range_t range;
     458 long prev_range_id, next_range_id;
     459 int num;
     460 int sql_err;
     461
     462 /* Allocate memory */
     463  if ((query = g_string_sized_new(STR_L)) == NULL){
     464   fprintf(stderr, "E: cannot allocate gstring\n");
     465   return(-1);
     466  }
     467
     468 /* Do range check */
     469  if (( p_newrange->end > MAX_RANGE ) || ( p_newrange->start < MIN_RANGE )) return(-1);
     470
     471 /* Check if the range collapses */
     472  if ( p_newrange->end < p_newrange->start ) {
     473  /* then delete the range */
     474  /* Do this by marking the range for deletion for further commit/rollback */
     475   if(commit_now)
     476    g_string_sprintf(query, "DELETE FROM nic_hdl "
     477                            "WHERE range_id=%ld ",
     478                             range_id);
     479   else
     480    g_string_sprintf(query, "UPDATE nic_hdl SET thread_id=%d "
     481                            "WHERE range_id=%ld ",
     482                             NH_DELETE, range_id);
     483
     484 /*   fprintf(stderr, "update_range[%s]\n", query->str); */
     485    sql_err=SQ_execute_query(sql_connection, query->str, (SQ_result_set_t **)NULL);
     486    if(sql_err) {
     487     /* An error occured */
     488     g_string_free(query, TRUE);
     489     return(-1);
     490    }
     491    num = mysql_affected_rows(sql_connection);
     492    /* this should not happen */
     493    if(num==0) die;
     494
     495  }
     496  else {
     497   /* update the range for the same space/source */
     498   range.space=p_newrange->space;
     499   range.source=p_newrange->source;
     500   /* Check if we can join with previous range of the same space */
     501   prev_range_id=get_range(p_newrange->start-1, &range, sql_connection);
     502   /* Check if such range exists and it is not ours (this happens when we are shrinking */
     503   if((prev_range_id>0) && (prev_range_id!=range_id)) {
     504    /* acquire the previous range */
     505    /* mark it for deletion for commit/rollback */
     506    if(commit_now)
     507       g_string_sprintf(query, "DELETE FROM nic_hdl "
     508                               "WHERE range_id=%ld ",
     509                                prev_range_id);
     510    else
     511       g_string_sprintf(query, "UPDATE nic_hdl SET thread_id=%d "
     512                               "WHERE range_id=%ld ",
     513                                NH_DELETE, prev_range_id);
     514
     515
     516
     517 /*    fprintf(stderr, "update_range[%s]\n", query->str); */
     518    sql_err=SQ_execute_query(sql_connection, query->str, (SQ_result_set_t **)NULL);
     519    if(sql_err) {
     520     /* An error occured */
     521     g_string_free(query, TRUE);
     522     return(-1);
     523    }
     524    num = mysql_affected_rows(sql_connection);
     525    /* this should not happen */
     526    if(num==0) die;
     527
     528    /* expand the boundaries */
     529    p_newrange->start=range.start;
     530   }
     531
     532 /* Check if we can join with next range of the same space */
     533   next_range_id=get_range(p_newrange->end+1, &range, sql_connection);
     534   /* Check if such range exists and it is not ours (this happens when we are shrinking) */
     535   if((next_range_id>0) && (next_range_id!=range_id)) {
     536    /* acquire the next range */
     537    /* mark it for deletion for commit/rollback */
     538    if(commit_now)
     539      g_string_sprintf(query, "DELETE FROM nic_hdl "
     540                              "WHERE range_id=%ld ",
     541                               next_range_id);
     542    else
     543      g_string_sprintf(query, "UPDATE nic_hdl SET thread_id=%d "
     544                              "WHERE range_id=%ld ",
     545                               NH_DELETE, next_range_id);
     546
     547
     548
     549 /*   fprintf(stderr, "update_range[%s]\n", query->str); */
     550    sql_err=SQ_execute_query(sql_connection, query->str, (SQ_result_set_t **)NULL);
     551    if(sql_err) {
     552     /* An error occured */
     553     g_string_free(query, TRUE);
     554     return(-1);
     555    }
     556    num = mysql_affected_rows(sql_connection);
     557    /* this should not happen */
     558    if(num==0) die;
     559
     560    /* expand the boundaries */
     561    p_newrange->end=range.end;
     562   }
     563
     564 /* Now make a larger range. Mark current for deletion and new for commit/rollback */
     565   if(commit_now)
     566    g_string_sprintf(query, "UPDATE nic_hdl "
     567                            "SET range_start=%ld, range_end=%ld "
     568                            "WHERE range_id=%ld",
     569                            p_newrange->start, p_newrange->end, range_id);
     570   else {
     571
     572    g_string_sprintf(query, "UPDATE nic_hdl SET thread_id=%d "
     573                            "WHERE range_id=%ld ",
     574                            NH_DELETE, range_id);
     575 /*   fprintf(stderr, "update_range[%s]\n", query->str); */
     576    sql_err=SQ_execute_query(sql_connection, query->str, (SQ_result_set_t **)NULL);
     577    if(sql_err) {
     578     /* An error occured */
     579     g_string_free(query, TRUE);
     580     return(-1);
     581    }
     582    num = mysql_affected_rows(sql_connection);
     583    /* this should not happen */
     584    if(num==0) die;
     585
     586    g_string_sprintf(query, "INSERT nic_hdl "
     587                            "SET thread_id=%d, range_id=%ld, space='%s', source='%s', range_start=%ld, range_end=%ld ",
     588                            NH_INSERT, range_id, p_newrange->space, p_newrange->source, p_newrange->start, p_newrange->end);
     589   }
     590
     591 /*   fprintf(stderr, "update_range[%s]\n", query->str); */
     592    sql_err=SQ_execute_query(sql_connection, query->str, (SQ_result_set_t **)NULL);
     593    if(sql_err) {
     594     /* An error occured */
     595     g_string_free(query, TRUE);
     596     return(-1);
     597    }
     598    num = mysql_affected_rows(sql_connection);
     599    /* this should not happen */
     600    if(num==0) die;
     601  } /* update the range */
     602
     603  g_string_free(query, TRUE);
     604  return (range_id);
     605 }
     606
     607 /************************************************************
     608 * long create_range()                                       *
     609 *                                                           *
     610 * Creates a new range in a given name space                 *
     611 *                                                           *
     612 * To finalize changes make commit/rollback                  *
     613 *                                                           *
     614 * Returns:                                                  *
     615 * >0 - returns range_id on success                          *
     616 * -1 - error (f.e. more than one object with the same PK)   *
     617 *                                                           *
     618 ************************************************************/
     619
     620 static long create_range(range_t *p_range, SQ_connection_t *sql_connection, int commit_now)
         /* [<][>][^][v][top][bottom][index][help] */
     621 {
     622 GString *query;
     623 int sql_err, num;
     624
     625  /* Allocate memory */
     626  if ((query = g_string_sized_new(STR_L)) == NULL){
     627   fprintf(stderr, "E: cannot allocate gstring\n");
     628   return(-1);
     629  }
     630
     631  if(commit_now)
     632   g_string_sprintf(query, "INSERT nic_hdl "
     633                           "SET thread_id=0, space='%s', source='%s', range_start=%ld, range_end=%ld ",
     634                            p_range->space, p_range->source, p_range->start, p_range->end);
     635  else
     636   g_string_sprintf(query, "INSERT nic_hdl "
     637                           "SET thread_id=%d, space='%s', source='%s', range_start=%ld, range_end=%ld ",
     638                            NH_INSERT, p_range->space, p_range->source, p_range->start, p_range->end);
     639
     640 /* fprintf(stderr, "create_range[%s]\n", query->str); */
     641  sql_err=SQ_execute_query(sql_connection, query->str, (SQ_result_set_t **)NULL);
     642  g_string_free(query, TRUE);
     643
     644    if(sql_err) {
     645     /* An error occured */
     646     return(-1);
     647    }
     648    num = mysql_affected_rows(sql_connection);
     649    /* this should not happen */
     650    if(num==0) die;
     651  return(mysql_insert_id(sql_connection));
     652 }
     653
     654
     655 /************************************************************
     656 * int NH_comrol()                                           *
     657 *                                                           *
     658 * Commits or rolls back changes to NHR                      *
     659 *                                                           *
     660 *                                                           *
     661 * Returns:                                                  *
     662 * >0 - success                                              *
     663 * -1 - SQL error                                            *
     664 *                                                           *
     665 ************************************************************/
     666
     667 int NH_comrol(SQ_connection_t *sql_connection, int thread_ins, int thread_del)
         /* [<][>][^][v][top][bottom][index][help] */
     668 {
     669 GString *query;
     670 int sql_err;
     671
     672  /* Allocate memory */
     673  if ((query = g_string_sized_new(STR_L)) == NULL){
     674   fprintf(stderr, "E: cannot allocate gstring\n");
     675   return(-1);
     676  }
     677
     678   g_string_sprintf(query, "DELETE FROM nic_hdl "
     679                           "WHERE thread_id=%d ",
     680                           thread_del);
     681
     682 /* fprintf(stderr, "create_range[%s]\n", query->str); */
     683  sql_err=SQ_execute_query(sql_connection, query->str, (SQ_result_set_t **)NULL);
     684  if(sql_err) {
     685     /* An error occured */
     686     g_string_free(query, TRUE);
     687     fprintf(stderr,"ERROR: %s\n", SQ_error(sql_connection));
     688     die;
     689  }
     690
     691  g_string_sprintf(query, "UPDATE nic_hdl "
     692                          "SET thread_id=0 "
     693                          "WHERE thread_id=%d ",
     694                           thread_ins);
     695
     696 /* fprintf(stderr, "create_range[%s]\n", query->str); */
     697  sql_err=SQ_execute_query(sql_connection, query->str, (SQ_result_set_t **)NULL);
     698  g_string_free(query, TRUE);
     699
     700  if(sql_err) {
     701     /* An error occured */
     702    fprintf(stderr,"ERROR: %s\n", SQ_error(sql_connection));
     703    die;
     704  }
     705
     706  return(1);
     707
     708 }
     709
     710

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