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