00001 #include <stdio.h>
00002 #ifndef __USE_ISOC99
00003 #define __USE_ISOC99
00004 #include <stdlib.h>
00005 #undef __USE_ISOC99
00006 #else
00007 #include <stdlib.h>
00008 #endif
00009 #include <string.h>
00010 #include <alloca.h>
00011 #include <assert.h>
00012 #include <netinet/in.h>
00013 #define DB_COMMON_C
00014 #include "db.h"
00015 #undef DB_COMMON_C
00016 #include "xassert.h"
00017 #include "byteswap.h"
00018 #include "xmem.h"
00019 #include <signal.h>
00020
00021
00022 #ifdef ORACLE
00023 static const char *dbtype_string[] = {"char","integer","integer","integer",
00024 "integer","float","double","varchar",
00025 "varchar","unknown"};
00026 #endif
00027 #ifdef MYSQL
00028 static const char *dbtype_string[] = {"char","int2","int2","int4","int8",
00029 "float4","float8","text","varchar",
00030 "unknown"};
00031 #endif
00032 #ifdef POSTGRESQL
00033 static const char *dbtype_string[] = {"char","int2","int2","int4","int8",
00034 "float4","float8","text","varchar",
00035 "unknown"};
00036 #endif
00037 const char UNKNOWN_TYPE_STR[] = "unknown type";
00038
00039
00040
00041 static db_sigblock_fn g_db_sigblock = NULL;
00042 static void *g_db_sigblock_data = NULL;
00043
00044 void db_set_error_message(char *err)
00045 {
00046 strncpy(__db_error_message, err, 4095);
00047 }
00048
00049 void db_get_error_message(int maxlen, char *err)
00050 {
00051 strncpy(err, __db_error_message, maxlen);
00052 }
00053
00054 const char *db_type_string(DB_Type_t dbtype)
00055 {
00056 switch(dbtype)
00057 {
00058 case DB_CHAR:
00059 return dbtype_string[0];
00060 case DB_INT1:
00061 return dbtype_string[1];
00062 case DB_INT2:
00063 return dbtype_string[2];
00064 case DB_INT4:
00065 return dbtype_string[3];
00066 case DB_INT8:
00067 return dbtype_string[4];
00068 case DB_FLOAT:
00069 return dbtype_string[5];
00070 case DB_DOUBLE:
00071 return dbtype_string[6];
00072 case DB_STRING:
00073 return dbtype_string[7];
00074 case DB_VARCHAR:
00075 return dbtype_string[8];
00076 default:
00077 return UNKNOWN_TYPE_STR;
00078 }
00079 }
00080
00081
00082
00083 static void print_separator(int width);
00084
00085 #ifdef ORACLE
00086 char *db_stringtype_maxlen(int maxlen)
00087 {
00088 char *str;
00089 str = malloc(20);
00090 XASSERT(str);
00091 sprintf(str,"varchar(%d)",maxlen);
00092 return str;
00093 }
00094 #else
00095 char *db_stringtype_maxlen(int maxlen)
00096 {
00097 return (char *)db_type_string(DB_STRING);
00098 }
00099 #endif
00100
00101 int db_sizeof(DB_Type_t dbtype)
00102 {
00103 switch(dbtype)
00104 {
00105
00106
00107 case DB_CHAR:
00108 return sizeof(db_char_t);
00109 case DB_INT1:
00110 return sizeof(db_int1_t);
00111 case DB_INT2:
00112 return sizeof(db_int2_t);
00113 case DB_INT4:
00114 return sizeof(db_int4_t);
00115 case DB_INT8:
00116 return sizeof(db_int8_t);
00117 case DB_FLOAT:
00118 return sizeof(db_float_t);
00119 case DB_DOUBLE:
00120 return sizeof(db_double_t);
00121 case DB_STRING:
00122 case DB_VARCHAR:
00123 return sizeof(char *);
00124 default:
00125 return 0;
00126 }
00127 }
00128
00129
00130 static void print_separator(int width)
00131 {
00132 int i;
00133 putchar('+');
00134 for (i=0;i<width-2;i++)
00135 putchar('-');
00136 putchar('+');
00137 putchar('\n');
00138 }
00139
00140 static void print_separator1(int width)
00141 {
00142 int i;
00143 for (i=0;i<width;i++)
00144 putchar('-');
00145 putchar('\n');
00146 }
00147
00148
00149 void db_print_text_result(DB_Text_Result_t *res)
00150 {
00151 unsigned int i,j,tw, len;
00152 unsigned int *column_width;
00153
00154 column_width = alloca(res->num_cols);
00155 tw=res->num_cols*3+1;
00156 for (j=0; j<res->num_cols; j++)
00157 {
00158 column_width[j] = res->column_width[j];
00159 if (res->column_name[j])
00160 {
00161 len = strlen(res->column_name[j]);
00162 if (len>column_width[j])
00163 column_width[j] = len;
00164 }
00165 tw += column_width[j];
00166 }
00167
00168 if (res->num_rows == 0)
00169 {
00170
00171 return;
00172 }
00173
00174 print_separator(tw);
00175
00176 for (j=0; j<res->num_cols; j++)
00177 {
00178 printf("| ");
00179 printf("%-*s",res->column_width[j],res->column_name[j]);
00180 printf(" ");
00181 }
00182 printf("|\n");
00183
00184
00185
00186 print_separator(tw);
00187
00188 for (i=0; i<res->num_rows; i++)
00189 {
00190 for (j=0; j<res->num_cols; j++)
00191 {
00192 printf("| ");
00193 printf("%-*s",column_width[j],res->field[i][j]);
00194 printf(" ");
00195 }
00196 printf("|\n");
00197 }
00198
00199 print_separator(tw);
00200 }
00201
00202
00203
00204
00205 char db_binary_field_getchar(DB_Binary_Result_t *res, unsigned int row,
00206 unsigned int col)
00207 {
00208 if ( row<res->num_rows && col<res->num_cols)
00209 return dbtype2char(res->column[col].type,
00210 res->column[col].data+row*res->column[col].size);
00211 else
00212 {
00213 fprintf(stderr,"ERROR: Invalid (row,col) index > (0..%d,0..%d)\n",
00214 res->num_rows, res->num_cols);
00215 XASSERT(0);
00216 return '\0';
00217 }
00218 }
00219
00220 int db_binary_field_getint(DB_Binary_Result_t *res, unsigned int row,
00221 unsigned int col)
00222 {
00223 if ( row<res->num_rows && col<res->num_cols)
00224 return dbtype2int(res->column[col].type,
00225 res->column[col].data+row*res->column[col].size);
00226 else
00227 {
00228 fprintf(stderr,"ERROR: Invalid (row,col) index > (0..%d,0..%d)\n",
00229 res->num_rows, res->num_cols);
00230 XASSERT(0);
00231 return 0;
00232 }
00233 }
00234
00235
00236 long long db_binary_field_getlonglong(DB_Binary_Result_t *res, unsigned int row,
00237 unsigned int col)
00238 {
00239 if ( row<res->num_rows && col<res->num_cols)
00240 return dbtype2longlong(res->column[col].type,
00241 res->column[col].data+row*res->column[col].size);
00242 else
00243 {
00244 fprintf(stderr,"ERROR: Invalid (row,col) index > (0..%d,0..%d)\n",
00245 res->num_rows, res->num_cols);
00246 XASSERT(0);
00247 return 0L;
00248 }
00249 }
00250
00251 float db_binary_field_getfloat(DB_Binary_Result_t *res, unsigned int row,
00252 unsigned int col)
00253 {
00254 if ( row<res->num_rows && col<res->num_cols)
00255 return dbtype2float(res->column[col].type,
00256 res->column[col].data+row*res->column[col].size);
00257 else
00258 {
00259 fprintf(stderr,"ERROR: Invalid (row,col) index > (0..%d,0..%d)\n",
00260 res->num_rows, res->num_cols);
00261 XASSERT(0);
00262 return 0;
00263 }
00264 }
00265
00266 double db_binary_field_getdouble(DB_Binary_Result_t *res, unsigned int row,
00267 unsigned int col)
00268 {
00269 if ( row<res->num_rows && col<res->num_cols)
00270 return dbtype2double(res->column[col].type,
00271 res->column[col].data+row*res->column[col].size);
00272 else
00273 {
00274 fprintf(stderr,"ERROR: Invalid (row,col) index > (0..%d,0..%d)\n",
00275 res->num_rows, res->num_cols);
00276 XASSERT(0);
00277 return 0;
00278 }
00279 }
00280
00281 void db_binary_field_getstr(DB_Binary_Result_t *res, unsigned int row,
00282 unsigned int col, int len, char *str)
00283 {
00284 if ( row<res->num_rows && col<res->num_cols)
00285 dbtype2str(res->column[col].type,
00286 res->column[col].data+row*res->column[col].size,
00287 len,str);
00288 else
00289 {
00290 fprintf(stderr,"ERROR: Invalid (row,col) index > (0..%d,0..%d)\n",
00291 res->num_rows, res->num_cols);
00292 XASSERT(0);
00293 }
00294 }
00295
00296
00297
00298 int db_binary_field_is_null(DB_Binary_Result_t *res, unsigned int row,
00299 unsigned int col)
00300 {
00301 XASSERT( row<res->num_rows && col<res->num_cols );
00302 return res->column[col].is_null[row];
00303 }
00304
00305
00306 int db_binary_default_width(DB_Type_t dbtype)
00307 {
00308 switch(dbtype)
00309 {
00310 case DB_CHAR:
00311 return 1;
00312 case DB_INT1:
00313 return 4;
00314 case DB_INT2:
00315 return 6;
00316 case DB_INT4:
00317 return 12;
00318 case DB_INT8:
00319 return 23;
00320 case DB_FLOAT:
00321 return 12;
00322 case DB_DOUBLE:
00323 return 20;
00324 case DB_STRING:
00325 return 0;
00326 case DB_VARCHAR:
00327 return 0;
00328 default:
00329 return 0;
00330 }
00331 }
00332
00333
00334 void db_print_binary_result(DB_Binary_Result_t *res)
00335 {
00336 unsigned int i,j, len, total_width;
00337 unsigned int *column_width;
00338
00339 column_width = alloca(res->num_cols*sizeof(int));
00340
00341
00342 for (j=0; j<res->num_cols; j++)
00343 {
00344 if ( res->column[j].type == DB_STRING ||
00345 res->column[j].type == DB_VARCHAR )
00346 {
00347 column_width[j] = 0;
00348 for (i=0; i<res->num_rows; i++)
00349 {
00350 len = strlen(res->column[j].data+i*res->column[j].size);
00351 if (len>column_width[j])
00352 column_width[j] = len;
00353 }
00354 }
00355 else
00356 column_width[j] = db_binary_default_width(res->column[j].type);
00357 if (res->column[j].column_name)
00358 len = strlen(res->column[j].column_name);
00359 else
00360 len = 7;
00361 if (len>column_width[j])
00362 column_width[j] = len;
00363 }
00364
00365 total_width = 0;
00366 for (j=0; j<res->num_cols; j++)
00367 {
00368 if (res->column[j].column_name)
00369 printf("%-*s",column_width[j],res->column[j].column_name);
00370 else
00371 printf("%-s %03d","Col " ,j);
00372
00373 if (j<res->num_cols-1)
00374 printf(" | ");
00375 total_width += column_width[j];
00376 }
00377 printf("\n");
00378
00379 print_separator1(total_width+(res->num_cols-1)*3);
00380
00381 for (i=0; i<res->num_rows; i++)
00382 {
00383 for (j=0; j<res->num_cols; j++)
00384 {
00385 if (res->column[j].is_null[i])
00386 printf("%*s",column_width[j],"NULL");
00387 else
00388 db_print_binary_field(res->column[j].type, column_width[j],
00389 res->column[j].data+i*res->column[j].size);
00390 if (j<res->num_cols-1)
00391 printf(" | ");
00392 }
00393 printf("\n");
00394 }
00395 }
00396
00397
00398 void db_print_binary_field_type(DB_Type_t dbtype)
00399 {
00400 switch(dbtype)
00401 {
00402 case DB_CHAR:
00403 printf("DB_CHAR");
00404 break;
00405 case DB_INT1:
00406 printf("DB_INT1");
00407 break;
00408 case DB_INT2:
00409 printf("DB_INT2");
00410 break;
00411 case DB_INT4:
00412 printf("DB_INT4");
00413 break;
00414 case DB_INT8:
00415 printf("DB_INT8");
00416 break;
00417 case DB_FLOAT:
00418 printf("DB_FLOAT");
00419 break;
00420 case DB_DOUBLE:
00421 printf("DB_DOUBLE");
00422 break;
00423 case DB_STRING:
00424 printf("DB_STRING");
00425 break;
00426 case DB_VARCHAR:
00427 printf("DB_VARCHAR");
00428 break;
00429 default:
00430 return;
00431 }
00432 }
00433
00434
00435 int db_sprint_binary_field(DB_Type_t dbtype, int width, char *data, char *dst)
00436 {
00437 if (width>0)
00438 {
00439 switch(dbtype)
00440 {
00441 case DB_CHAR:
00442 return snprintf(dst,width+1,"%*c",width,*((char *)data));
00443 case DB_INT1:
00444 return snprintf(dst,width+1,"%*hhd",width,*((char *)data));
00445 case DB_INT2:
00446 return snprintf(dst,width+1,"% *hd",width,*((short *)data));
00447 case DB_INT4:
00448 return snprintf(dst,width+1,"% *d",width,*((int *)data));
00449 case DB_INT8:
00450 return snprintf(dst,width+1,"% *lld",width,*((long long *)data));
00451 case DB_FLOAT:
00452 return snprintf(dst,width+1,"% *g",width,*((float *)data));
00453 case DB_DOUBLE:
00454 return snprintf(dst,width+1,"% *g",width,*((double *)data));
00455 case DB_STRING:
00456 return snprintf(dst,width+1,"%-*s",width,(char *)data);
00457 case DB_VARCHAR:
00458 return snprintf(dst,width+1,"%-*s",width,(char *)data);
00459 default:
00460 return 0;
00461 }
00462 }
00463 else
00464 {
00465 switch(dbtype)
00466 {
00467 case DB_CHAR:
00468 return sprintf(dst,"%c",*((db_char_t *)data));
00469 case DB_INT1:
00470 return sprintf(dst,"% hhd",*((db_int1_t *)data));
00471 case DB_INT2:
00472 return sprintf(dst,"% hd",*((db_int2_t *)data));
00473 case DB_INT4:
00474 return sprintf(dst,"% d",*((db_int4_t *)data));
00475 case DB_INT8:
00476 return sprintf(dst,"% lld",*((db_int8_t *)data));
00477 case DB_FLOAT:
00478 return sprintf(dst,"% g",*((db_float_t *)data));
00479 case DB_DOUBLE:
00480 return sprintf(dst,"% g",*((db_double_t *)data));
00481 case DB_STRING:
00482 return sprintf(dst,"%-s",*((db_string_t *)data));
00483 case DB_VARCHAR:
00484 return sprintf(dst,"%-s",*((db_varchar_t *)data));
00485 default:
00486 return 0;
00487 }
00488 }
00489 }
00490
00491
00492
00493 void db_print_binary_field(DB_Type_t dbtype, int width, char *data)
00494 {
00495 char *buf;
00496
00497 buf = alloca(width+1);
00498 db_sprint_binary_field(dbtype, width, data, buf);
00499 fputs(buf,stdout);
00500 }
00501
00502
00503
00504
00505 void db_free_binary_result(DB_Binary_Result_t *db_result)
00506 {
00507 unsigned int i;
00508 if (db_result)
00509 {
00510 if (db_result->column)
00511 {
00512 for (i=0; i<db_result->num_cols; i++)
00513 {
00514 if (db_result->column[i].column_name)
00515 free(db_result->column[i].column_name);
00516 if (db_result->column[i].data)
00517 free(db_result->column[i].data);
00518 if (db_result->column[i].is_null)
00519 free(db_result->column[i].is_null);
00520 }
00521 free(db_result->column);
00522 }
00523 free(db_result);
00524 }
00525 }
00526
00527
00528 void db_free_text_result(DB_Text_Result_t *db_result)
00529 {
00530 if (db_result)
00531 {
00532 if (db_result->num_rows>0)
00533 {
00534 if (db_result->column_name)
00535 free(db_result->column_name);
00536 if (db_result->column_width)
00537 free(db_result->column_width);
00538 if (db_result->field)
00539 free(db_result->field);
00540 if (db_result->buffer)
00541 free(db_result->buffer);
00542 }
00543 free(db_result);
00544 }
00545 }
00546
00547
00548 void db_free_binary_result_tuple(DB_Binary_Result_t ***tuple, unsigned int nelems)
00549 {
00550 if (tuple && *tuple)
00551 {
00552 unsigned int ielem;
00553
00554 for (ielem = 0 ; ielem < nelems; ielem++)
00555 {
00556 if ((*tuple)[ielem])
00557 {
00558 db_free_binary_result((*tuple)[ielem]);
00559 (*tuple)[ielem] = NULL;
00560 }
00561 }
00562
00563 free(*tuple);
00564 *tuple = NULL;
00565 }
00566 }
00567
00568 char *search_replace(const char *string, const char *search,
00569 const char *replace)
00570 {
00571 int len, ls,lr;
00572 char *output,*outq, *next, *prev;
00573
00574 len = strlen(string);
00575 ls = strlen(search);
00576 lr = strlen(replace);
00577 outq = malloc((lr/ls+1)*len);
00578 XASSERT(outq);
00579 output = outq;
00580 prev = (char *)string;
00581 while( (prev < string+len) && (next = strstr(prev, search)))
00582 {
00583 while( prev<next)
00584 *outq++ = *prev++;
00585 sprintf(outq,"%s", replace);
00586 outq += lr;
00587 prev += ls;
00588 next += ls;
00589 }
00590 while (prev < string+len)
00591 *outq++ = *prev++;
00592 *outq = '\0';
00593
00594 return output;
00595 }
00596
00597
00598
00599
00600 char dbtype2char(DB_Type_t dbtype, char *data)
00601 {
00602 switch(dbtype)
00603 {
00604 case DB_CHAR:
00605 return (char) *((db_char_t *) data);
00606 case DB_INT1:
00607 return (char) *((db_int1_t *) data);
00608 case DB_INT2:
00609 return (char) *((db_int2_t *) data);
00610 case DB_INT4:
00611 return (char) *((db_int4_t *) data);
00612 case DB_INT8:
00613 return (char) *((db_int8_t *) data);
00614 case DB_FLOAT:
00615 return (char) *((db_float_t *) data);
00616 case DB_DOUBLE:
00617 return (char) *((db_double_t *) data);
00618 case DB_STRING:
00619 case DB_VARCHAR:
00620 default:
00621 return *data;
00622 }
00623 }
00624
00625 short dbtype2short(DB_Type_t dbtype, char *data)
00626 {
00627 int val;
00628 char *endptr;
00629 switch(dbtype)
00630 {
00631 case DB_CHAR:
00632 return (short) *((db_char_t *) data);
00633 case DB_INT1:
00634 return (short) *((db_int1_t *) data);
00635 case DB_INT2:
00636 return (short) *((db_int2_t *) data);
00637 case DB_INT4:
00638 return (short) *((db_int4_t *) data);
00639 case DB_INT8:
00640 return (short) *((db_int8_t *) data);
00641 case DB_FLOAT:
00642 return (short) *((db_float_t *) data);
00643 case DB_DOUBLE:
00644 return (short) *((db_double_t *) data);
00645 case DB_STRING:
00646 case DB_VARCHAR:
00647 default:
00648 val = strtol(data,&endptr,0);
00649 if (val==0 && endptr==data )
00650 fprintf(stderr,"dbtype2int: The string '%s' is not an integer.\n",data);
00651 return val;
00652 }
00653 }
00654
00655
00656 int dbtype2int(DB_Type_t dbtype, char *data)
00657 {
00658 int val;
00659 char *endptr;
00660 switch(dbtype)
00661 {
00662 case DB_CHAR:
00663 return (int) *((db_char_t *) data);
00664 case DB_INT1:
00665 return (int) *((db_int1_t *) data);
00666 case DB_INT2:
00667 return (int) *((db_int2_t *) data);
00668 case DB_INT4:
00669 return (int) *((db_int4_t *) data);
00670 case DB_INT8:
00671 return (int) *((db_int8_t *) data);
00672 case DB_FLOAT:
00673 return (int) *((db_float_t *) data);
00674 case DB_DOUBLE:
00675 return (int) *((db_double_t *) data);
00676 case DB_STRING:
00677 case DB_VARCHAR:
00678 default:
00679 val = strtol(data,&endptr,0);
00680 if (val==0 && endptr==data )
00681 fprintf(stderr,"dbtype2int: The string '%s' is not an integer.\n",data);
00682 return val;
00683 }
00684 }
00685
00686 long long dbtype2longlong(DB_Type_t dbtype, char *data)
00687 {
00688 int val;
00689 char *endptr;
00690 switch(dbtype)
00691 {
00692 case DB_CHAR:
00693 return (long long) *((db_char_t *) data);
00694 case DB_INT1:
00695 return (long long) *((db_int1_t *) data);
00696 case DB_INT2:
00697 return (long long) *((db_int2_t *) data);
00698 case DB_INT4:
00699 return (long long) *((db_int4_t *) data);
00700 case DB_INT8:
00701 return (long long) *((db_int8_t *) data);
00702 case DB_FLOAT:
00703 return (long long) *((db_float_t *) data);
00704 case DB_DOUBLE:
00705 return (long long) *((db_double_t *) data);
00706 case DB_STRING:
00707 case DB_VARCHAR:
00708 default:
00709 val = strtol(data,&endptr,0);
00710 if (val==0 && endptr==data )
00711 fprintf(stderr,"dbtype2int: The string '%s' is not an integer.\n",data);
00712 return val;
00713 }
00714 }
00715
00716
00717 float dbtype2float(DB_Type_t dbtype, char *data)
00718 {
00719 float val;
00720 char *endptr;
00721 switch(dbtype)
00722 {
00723 case DB_CHAR:
00724 return (float) *((db_char_t *) data);
00725 case DB_INT1:
00726 return (float) *((db_int1_t *) data);
00727 case DB_INT2:
00728 return (float) *((db_int2_t *) data);
00729 case DB_INT4:
00730 return (float) *((db_int4_t *) data);
00731 case DB_INT8:
00732 return (float) *((db_int8_t *) data);
00733 case DB_FLOAT:
00734 return (float) *((db_float_t *) data);
00735 case DB_DOUBLE:
00736 return (float) *((db_double_t *) data);
00737 case DB_STRING:
00738 case DB_VARCHAR:
00739 default:
00740 val = strtof(data,&endptr);
00741 if (val==0 && endptr==data )
00742 fprintf(stderr,"dbtype2int: The string '%s' is not a float.\n",data);
00743 return val;
00744 }
00745 }
00746
00747
00748 double dbtype2double(DB_Type_t dbtype, char *data)
00749 {
00750 double val;
00751 char *endptr;
00752 switch(dbtype)
00753 {
00754 case DB_CHAR:
00755 return (double) *((db_char_t *) data);
00756 case DB_INT1:
00757 return (double) *((db_int1_t *) data);
00758 case DB_INT2:
00759 return (double) *((db_int2_t *) data);
00760 case DB_INT4:
00761 return (double) *((db_int4_t *) data);
00762 case DB_INT8:
00763 return (double) *((db_int8_t *) data);
00764 case DB_FLOAT:
00765 return (double) *((db_float_t *) data);
00766 case DB_DOUBLE:
00767 return (double) *((db_double_t *) data);
00768 case DB_STRING:
00769 case DB_VARCHAR:
00770 default:
00771 val = strtod(data,&endptr);
00772 if (val==0 && endptr==data )
00773 fprintf(stderr,"dbtype2int: The string '%s' is not a double.\n",data);
00774 return val;
00775 }
00776 }
00777
00778
00779 void dbtype2str(DB_Type_t dbtype, char *data, int len, char *str)
00780 {
00781 switch(dbtype)
00782 {
00783 case DB_CHAR:
00784 snprintf(str, len, "%1c", *((db_char_t *) data));
00785 break;
00786 case DB_INT1:
00787 snprintf(str, len, "%hhd", *((db_int1_t *) data));
00788 break;
00789 case DB_INT2:
00790 snprintf(str, len, "%hd", *((db_int2_t *) data));
00791 break;
00792 case DB_INT4:
00793 snprintf(str, len, "%d", *((db_int4_t *) data));
00794 break;
00795 case DB_INT8:
00796 snprintf(str, len, "%lld", *((db_int8_t *) data));
00797 break;
00798 case DB_FLOAT:
00799 snprintf(str, len, "%f", *((db_float_t *) data));
00800 break;
00801 case DB_DOUBLE:
00802 snprintf(str, len, "%lf", *((db_double_t *) data));
00803 break;
00804 case DB_STRING:
00805 case DB_VARCHAR:
00806 default:
00807 strncpy(str,data,len);
00808 break;
00809 }
00810 }
00811
00812
00813
00814
00815 void db_lock(DB_Handle_t *h)
00816 {
00817 if ( h->db_lock == NULL )
00818 return;
00819 else
00820 {
00821 if (g_db_sigblock)
00822 {
00823 sigset_t mask;
00824 int status;
00825
00826 (*g_db_sigblock)(&mask, g_db_sigblock_data);
00827
00828 if((status = pthread_sigmask(SIG_BLOCK, &mask, NULL)))
00829 {
00830 fprintf(stderr,"pthread_sigmask call failed with status = %d\n", status);
00831 }
00832 }
00833
00834 pthread_mutex_lock( h->db_lock );
00835 }
00836 }
00837
00838 void db_unlock(DB_Handle_t *h)
00839 {
00840 if ( h->db_lock == NULL )
00841 return;
00842 else
00843 {
00844 pthread_mutex_unlock( h->db_lock );
00845
00846 if (g_db_sigblock)
00847 {
00848 sigset_t mask;
00849 int status;
00850
00851 (*g_db_sigblock)(&mask, g_db_sigblock_data);
00852
00853 if((status = pthread_sigmask(SIG_UNBLOCK, &mask, NULL)))
00854 {
00855 fprintf(stderr,"pthread_sigmask call failed with status = %d\n", status);
00856 }
00857 }
00858 }
00859 }
00860
00861 DB_Text_Result_t *db_binary_to_text(DB_Binary_Result_t *binres)
00862 {
00863 DB_Text_Result_t *result;
00864 unsigned int i,j,buflen;
00865 int total_width, n,len;
00866 long colname_length;
00867 char *p;
00868
00869
00870 if (binres==NULL)
00871 return NULL;
00872
00873
00874 result = (DB_Text_Result_t *)malloc(sizeof(DB_Text_Result_t));
00875 XASSERT(result);
00876 result->num_rows = binres->num_rows;
00877 result->num_cols = binres->num_cols;
00878 result->column_name = (char **)malloc(result->num_cols*sizeof(char *));
00879 XASSERT(result->column_name);
00880 result->column_width = (int *)malloc(result->num_cols*sizeof(int));
00881 XASSERT(result->column_width);
00882 total_width = 0;
00883 colname_length = 0;
00884
00885
00886 for (j=0; j<binres->num_cols; j++)
00887 {
00888
00889
00890 if ( binres->column[j].type == DB_STRING ||
00891 binres->column[j].type == DB_VARCHAR )
00892 {
00893 result->column_width[j] = 0;
00894 for (i=0; i<binres->num_rows; i++)
00895 {
00896 len = strlen(binres->column[j].data+i*binres->column[j].size);
00897 if (len>result->column_width[j])
00898 result->column_width[j] = len;
00899 }
00900 }
00901 else
00902 result->column_width[j] = db_binary_default_width(binres->column[j].type);
00903
00904 if (result->column_width[j] < 4)
00905 result->column_width[j] = 4;
00906
00907 total_width += result->column_width[j]+1;
00908
00909
00910 result->column_name[j] = (char *) colname_length;
00911 if (binres->column[j].column_name)
00912 colname_length += strlen(binres->column[j].column_name)+1;
00913 else
00914 colname_length += 1;
00915 }
00916
00917
00918
00919
00920 buflen = (3+result->num_cols)*sizeof(int) + colname_length +
00921 total_width*result->num_rows;
00922 #ifdef DEBUG
00923 printf("buflen = %d\n",buflen);
00924 #endif
00925 result->buffer = malloc(buflen);
00926 XASSERT(result->buffer);
00927 p = result->buffer;
00928
00929
00930 *((int *) p) = htonl(buflen);
00931 p += sizeof(int);
00932 *((int *) p) = htonl(result->num_rows);
00933 p += sizeof(int);
00934 *((int *) p) = htonl(result->num_cols);
00935 p += sizeof(int);
00936 for (i=0; i<result->num_cols; i++)
00937 {
00938 *((int *) p) = htonl(result->column_width[i]);
00939 p += sizeof(int);
00940 }
00941
00942
00943 for (i=0; i<result->num_cols; i++)
00944 {
00945 result->column_name[i] = p;
00946 if (binres->column[i].column_name)
00947 {
00948 p = memccpy(p, binres->column[i].column_name, 0,
00949 colname_length);
00950 }
00951 else
00952 *p++ = 0;
00953 XASSERT(p!=NULL);
00954 }
00955
00956
00957 result->field = (char ***) malloc(result->num_rows*sizeof(char **) + result->num_rows*result->num_cols*sizeof(char *));
00958 XASSERT(result->field);
00959 for (i=0; i<result->num_rows; i++)
00960 result->field[i] = (char **) &result->field[result->num_rows +
00961 i*result->num_cols];
00962
00963
00964 for(i = 0; i < result->num_rows; i++)
00965 {
00966 for (j = 0; j < result->num_cols; j++)
00967 {
00968 if (binres->column[j].is_null[i])
00969 n = snprintf(p,result->column_width[j]+1,"%*s",result->column_width[j],"NULL");
00970 else
00971 n = db_sprint_binary_field(binres->column[j].type,
00972
00973 0,
00974 binres->column[j].data+i*binres->column[j].size,
00975 p);
00976
00977
00978
00979
00980
00981
00982 result->field[i][j] = p;
00983 p += n;
00984 *p++ = 0;
00985 }
00986 }
00987 buflen = (int) (p - result->buffer)+1;
00988 *((int *) result->buffer) = htonl(buflen);
00989 #ifdef DEBUG
00990 printf("Resulting buffer length = %d\n",buflen);
00991 #endif
00992 return result;
00993 }
00994
00995
00996 void db_hton(DB_Type_t dbtype, int n, void *data)
00997 {
00998 #if __BYTE_ORDER == __LITTLE_ENDIAN
00999 db_byteswap(dbtype, n, data);
01000 #else
01001 return;
01002 #endif
01003 }
01004
01005 void db_byteswap(DB_Type_t dbtype, int n, char *val)
01006 {
01007 #if __BYTE_ORDER == __LITTLE_ENDIAN
01008 if ( !(dbtype == DB_STRING || dbtype == DB_VARCHAR) )
01009 byteswap(db_sizeof(dbtype), n, val);
01010 #else
01011 return;
01012 #endif
01013 }
01014
01015
01016
01017 void db_register_sigblock(db_sigblock_fn fn, void *data)
01018 {
01019
01020 if (!g_db_sigblock)
01021 {
01022 g_db_sigblock = fn;
01023 g_db_sigblock_data = data;
01024 }
01025 }