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