1 | /***************************************
2 | $Revision: 1.8 $
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
639 | {
640 | GString *query;
641 | int sql_err, num;
642 |
643 | /* Allocate memory */
644 | if ((query = g_string_sized_new(STR_L)) == NULL){
645 | fprintf(stderr, "E: cannot allocate gstring\n");
646 | return(-1);
647 | }
648 |
649 | if(commit_now)
650 | g_string_sprintf(query, "INSERT nic_hdl "
651 | "SET thread_id=0, space='%s', source='%s', range_start=%ld, range_end=%ld ",
652 | p_range->space, p_range->source, p_range->start, p_range->end);
653 | else
654 | g_string_sprintf(query, "INSERT nic_hdl "
655 | "SET thread_id=%d, space='%s', source='%s', range_start=%ld, range_end=%ld ",
656 | NH_INSERT, p_range->space, p_range->source, p_range->start, p_range->end);
657 |
658 | /* fprintf(stderr, "create_range[%s]\n", query->str); */
659 | sql_err=SQ_execute_query(sql_connection, query->str, (SQ_result_set_t **)NULL);
660 | g_string_free(query, TRUE);
661 |
662 | if(sql_err) {
663 | /* An error occured */
664 | return(-1);
665 | }
666 | num = SQ_get_affected_rows(sql_connection);
667 | /* this should not happen */
668 | if(num==0) die;
669 | return(SQ_get_insert_id(sql_connection));
670 | }
671 |
672 |
673 | /************************************************************
674 | * int NH_comrol() *
675 | * *
676 | * Commits or rolls back changes to NHR *
677 | * *
678 | * *
679 | * Returns: *
680 | * >0 - success *
681 | * -1 - SQL error *
682 | * *
683 | ************************************************************/
684 |
685 | int NH_comrol(SQ_connection_t *sql_connection, int thread_ins, int thread_del)
686 | {
687 | GString *query;
688 | int sql_err;
689 |
690 | /* Allocate memory */
691 | if ((query = g_string_sized_new(STR_L)) == NULL){
692 | fprintf(stderr, "E: cannot allocate gstring\n");
693 | return(-1);
694 | }
695 |
696 | g_string_sprintf(query, "DELETE FROM nic_hdl "
697 | "WHERE thread_id=%d ",
698 | thread_del);
699 |
700 | /* fprintf(stderr, "create_range[%s]\n", query->str); */
701 | sql_err=SQ_execute_query(sql_connection, query->str, (SQ_result_set_t **)NULL);
702 | if(sql_err) {
703 | /* An error occured */
704 | g_string_free(query, TRUE);
705 | fprintf(stderr,"ERROR: %s\n", SQ_error(sql_connection));
706 | die;
707 | }
708 |
709 | g_string_sprintf(query, "UPDATE nic_hdl "
710 | "SET thread_id=0 "
711 | "WHERE thread_id=%d ",
712 | thread_ins);
713 |
714 | /* fprintf(stderr, "create_range[%s]\n", query->str); */
715 | sql_err=SQ_execute_query(sql_connection, query->str, (SQ_result_set_t **)NULL);
716 | g_string_free(query, TRUE);
717 |
718 | if(sql_err) {
719 | /* An error occured */
720 | fprintf(stderr,"ERROR: %s\n", SQ_error(sql_connection));
721 | die;
722 | }
723 |
724 | return(1);
725 |
726 | }
727 |
728 |