00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00037 #include <stdio.h>
00038 #include <string.h>
00039 #include <time.h>
00040 #include <sys/types.h>
00041 #include <dirent.h>
00042
00043 #include "../../mem/shm_mem.h"
00044 #include "../../mem/mem.h"
00045 #include "../../dprint.h"
00046
00047 #include "dbt_util.h"
00048 #include "dbt_lib.h"
00049
00050
00054 dbt_table_p dbt_load_file(str *tbn, str *dbn)
00055 {
00056 FILE *fin=NULL;
00057 char path[512], buf[4096];
00058 int c, crow, ccol, bp, sign, max_auto;
00059 dbt_val_t dtval;
00060 dbt_table_p dtp = NULL;
00061 dbt_column_p colp, colp0 = NULL;
00062 dbt_row_p rowp, rowp0 = NULL;
00063
00064 enum {DBT_FLINE_ST, DBT_NLINE_ST, DBT_DATA_ST} state;
00065
00066 DBG("DBT:dbt_load_file: request for table [%.*s]\n", tbn->len, tbn->s);
00067
00068 if(!tbn || !tbn->s || tbn->len<=0 || tbn->len>=255)
00069 return NULL;
00070 path[0] = 0;
00071 if(dbn && dbn->s && dbn->len>0)
00072 {
00073 DBG("DBT:dbt_load_file: db is [%.*s]\n", dbn->len, dbn->s);
00074 if(dbn->len+tbn->len<511)
00075 {
00076 strncpy(path, dbn->s, dbn->len);
00077 path[dbn->len] = '/';
00078 strncpy(path+dbn->len+1, tbn->s, tbn->len);
00079 path[dbn->len+tbn->len+1] = 0;
00080 }
00081 }
00082 if(path[0] == 0)
00083 {
00084 strncpy(path, tbn->s, tbn->len);
00085 path[tbn->len] = 0;
00086 }
00087
00088 DBG("DBT:dbt_load_file: loading file [%s]\n", path);
00089 fin = fopen(path, "rt");
00090 if(!fin)
00091 return NULL;
00092
00093 dtp = dbt_table_new(tbn->s, tbn->len);
00094 if(!dtp)
00095 goto done;
00096
00097 state = DBT_FLINE_ST;
00098 crow = ccol = -1;
00099 colp = colp0 = NULL;
00100 rowp = rowp0 = NULL;
00101 c = fgetc(fin);
00102 max_auto = 0;
00103 while(c!=EOF)
00104 {
00105 switch(state)
00106 {
00107 case DBT_FLINE_ST:
00108
00109 bp = 0;
00110 while(c==DBT_DELIM_C)
00111 c = fgetc(fin);
00112 if(c==DBT_DELIM_R && !colp0)
00113 goto clean;
00114 if(c==DBT_DELIM_R)
00115 {
00116 if(dtp->nrcols <= 0)
00117 goto clean;
00118 dtp->colv = (dbt_column_p*)
00119 shm_malloc(dtp->nrcols*sizeof(dbt_column_p));
00120 if(!dtp->colv)
00121 goto clean;
00122 colp0 = dtp->cols;
00123 for(ccol=0; ccol<dtp->nrcols && colp0; ccol++)
00124 {
00125 dtp->colv[ccol] = colp0;
00126 colp0 = colp0->next;
00127 }
00128 state = DBT_NLINE_ST;
00129 break;
00130 }
00131 while(c!=DBT_DELIM_C && c!='(' && c!=DBT_DELIM_R)
00132 {
00133 if(c==EOF)
00134 goto clean;
00135 buf[bp++] = c;
00136 c = fgetc(fin);
00137 }
00138 colp = dbt_column_new(buf, bp);
00139 if(!colp)
00140 goto clean;
00141
00142 while(c==DBT_DELIM_C)
00143 c = fgetc(fin);
00144 if(c!='(')
00145 goto clean;
00146 c = fgetc(fin);
00147 while(c==DBT_DELIM_C)
00148 c = fgetc(fin);
00149
00150 switch(c)
00151 {
00152 case 's':
00153 case 'S':
00154 colp->type = DB_STR;
00155 DBG("DBT: column[%d] is STR!\n", ccol+1);
00156 break;
00157 case 'i':
00158 case 'I':
00159 colp->type = DB_INT;
00160 DBG("DBT: column[%d] is INT!\n", ccol+1);
00161 break;
00162 case 'f':
00163 case 'F':
00164 colp->type = DB_FLOAT;
00165 DBG("DBT: column[%d] is FLOAT!\n", ccol+1);
00166 break;
00167 case 'd':
00168 case 'D':
00169 colp->type = DB_DOUBLE;
00170 DBG("DBT: column[%d] is DOUBLE!\n", ccol+1);
00171 break;
00172 default:
00173 DBG("DBT: wrong column type!\n");
00174 goto clean;
00175 }
00176
00177 while(c!=')' && c!= ',')
00178 c = fgetc(fin);
00179 if(c==',')
00180 {
00181
00182 c = fgetc(fin);
00183 while(c==DBT_DELIM_C)
00184 c = fgetc(fin);
00185 if(c=='N' || c=='n')
00186 {
00187
00188 colp->flag |= DBT_FLAG_NULL;
00189 }
00190 else if(colp->type==DB_INT && dtp->auto_col<0
00191 && (c=='A' || c=='a'))
00192 {
00193
00194 colp->flag |= DBT_FLAG_AUTO;
00195 dtp->auto_col = ccol+1;
00196 }
00197 else
00198 goto clean;
00199 while(c!=')' && c!=DBT_DELIM_R && c!=EOF)
00200 c = fgetc(fin);
00201 }
00202 if(c == ')')
00203 {
00204
00205 if(colp0)
00206 {
00207 colp->prev = colp0;
00208 colp0->next = colp;
00209 }
00210 else
00211 dtp->cols = colp;
00212 colp0 = colp;
00213 dtp->nrcols++;
00214 c = fgetc(fin);
00215 }
00216 else
00217 goto clean;
00218 ccol++;
00219 break;
00220
00221 case DBT_NLINE_ST:
00222
00223 while(c==DBT_DELIM_R)
00224 c = fgetc(fin);
00225 if(rowp)
00226 {
00227 if(dbt_table_check_row(dtp, rowp))
00228 goto clean;
00229
00230 if(!rowp0)
00231 dtp->rows = rowp;
00232 else
00233 {
00234 rowp0->next = rowp;
00235 rowp->prev = rowp0;
00236 }
00237 rowp0 = rowp;
00238 dtp->nrrows++;
00239 }
00240 if(c==EOF)
00241 break;
00242 crow++;
00243 ccol = 0;
00244 rowp = dbt_row_new(dtp->nrcols);
00245 if(!rowp)
00246 goto clean;
00247 state = DBT_DATA_ST;
00248
00249 break;
00250
00251 case DBT_DATA_ST:
00252
00253
00254
00255 if(ccol == dtp->nrcols && (c==DBT_DELIM_R || c==EOF))
00256 {
00257 state = DBT_NLINE_ST;
00258 break;
00259 }
00260 if(ccol>= dtp->nrcols)
00261 goto clean;
00262
00263 switch(dtp->colv[ccol]->type)
00264 {
00265 case DB_INT:
00266
00267 dtval.val.int_val = 0;
00268 dtval.type = DB_INT;
00269
00270 if(c==DBT_DELIM ||
00271 (ccol==dtp->nrcols-1
00272 && (c==DBT_DELIM_R || c==EOF)))
00273 dtval.nul = 1;
00274 else
00275 {
00276 dtval.nul = 0;
00277 sign = 1;
00278 if(c=='-')
00279 {
00280 sign = -1;
00281 c = fgetc(fin);
00282 }
00283 if(c<'0' || c>'9')
00284 goto clean;
00285 while(c>='0' && c<='9')
00286 {
00287 dtval.val.int_val=dtval.val.int_val*10+c-'0';
00288 c = fgetc(fin);
00289 }
00290 dtval.val.int_val *= sign;
00291
00292
00293 }
00294 if(c!=DBT_DELIM && c!=DBT_DELIM_R && c!=EOF)
00295 goto clean;
00296 if(dbt_row_set_val(rowp,&dtval,DB_INT,ccol))
00297 goto clean;
00298 if(ccol == dtp->auto_col)
00299 max_auto = (max_auto<dtval.val.int_val)?
00300 dtval.val.int_val:max_auto;
00301 break;
00302
00303 case DB_FLOAT:
00304
00305 dtval.val.float_val = 0.0;
00306 dtval.type = DB_FLOAT;
00307
00308 if(c==DBT_DELIM ||
00309 (ccol==dtp->nrcols-1
00310 && (c==DBT_DELIM_R || c==EOF)))
00311 dtval.nul = 1;
00312 else
00313 {
00314 dtval.nul = 0;
00315 sign = 1;
00316 if(c=='-')
00317 {
00318 sign = -1;
00319 c = fgetc(fin);
00320 }
00321 if(c<'0' || c>'9')
00322 goto clean;
00323 while(c>='0' && c<='9')
00324 {
00325 dtval.val.float_val = dtval.val.float_val*10
00326 + c - '0';
00327 c = fgetc(fin);
00328 }
00329 if(c=='.')
00330 {
00331 c = fgetc(fin);
00332 bp = 1;
00333 while(c>='0' && c<='9')
00334 {
00335 bp *= 10;
00336 dtval.val.float_val+=((float)(c-'0'))/bp;
00337 c = fgetc(fin);
00338 }
00339 }
00340 dtval.val.float_val *= sign;
00341
00342
00343 }
00344 if(c!=DBT_DELIM && c!=DBT_DELIM_R && c!=EOF)
00345 goto clean;
00346 if(dbt_row_set_val(rowp,&dtval,DB_FLOAT,ccol))
00347 goto clean;
00348 break;
00349
00350 case DB_DOUBLE:
00351
00352 dtval.val.double_val = 0.0;
00353 dtval.type = DB_DOUBLE;
00354
00355 if(c==DBT_DELIM ||
00356 (ccol==dtp->nrcols-1
00357 && (c==DBT_DELIM_R || c==EOF)))
00358 dtval.nul = 1;
00359 else
00360 {
00361 dtval.nul = 0;
00362 sign = 1;
00363 if(c=='-')
00364 {
00365 sign = -1;
00366 c = fgetc(fin);
00367 }
00368 if(c<'0' || c>'9')
00369 goto clean;
00370 while(c>='0' && c<='9')
00371 {
00372 dtval.val.double_val = dtval.val.double_val*10
00373 + c - '0';
00374 c = fgetc(fin);
00375 }
00376 if(c=='.')
00377 {
00378 c = fgetc(fin);
00379 bp = 1;
00380 while(c>='0' && c<='9')
00381 {
00382 bp *= 10;
00383 dtval.val.double_val+=((double)(c-'0'))/bp;
00384 c = fgetc(fin);
00385 }
00386 }
00387 dtval.val.double_val *= sign;
00388
00389
00390 }
00391 if(c!=DBT_DELIM && c!=DBT_DELIM_R && c!=EOF)
00392 goto clean;
00393 if(dbt_row_set_val(rowp,&dtval,DB_DOUBLE,ccol))
00394 goto clean;
00395 break;
00396
00397 case DB_STR:
00398
00399
00400 dtval.val.str_val.s = NULL;
00401 dtval.val.str_val.len = 0;
00402 dtval.type = DB_STR;
00403
00404 bp = 0;
00405 if(c==DBT_DELIM ||
00406 (ccol == dtp->nrcols-1
00407 && (c == DBT_DELIM_R || c==EOF)))
00408 dtval.nul = 1;
00409 else
00410 {
00411 dtval.nul = 0;
00412 while(c!=DBT_DELIM && c!=DBT_DELIM_R && c!=EOF)
00413 {
00414 if(c=='\\')
00415 {
00416 c = fgetc(fin);
00417 switch(c)
00418 {
00419 case 'n':
00420 c = '\n';
00421 break;
00422 case 'r':
00423 c = '\r';
00424 break;
00425 case 't':
00426 c = '\t';
00427 break;
00428 case '\\':
00429 c = '\\';
00430 break;
00431 case DBT_DELIM:
00432 c = DBT_DELIM;
00433 break;
00434 case '0':
00435 c = 0;
00436 break;
00437 default:
00438 goto clean;
00439 }
00440 }
00441 buf[bp++] = c;
00442 c = fgetc(fin);
00443 }
00444 dtval.val.str_val.s = buf;
00445 dtval.val.str_val.len = bp;
00446
00448 }
00449 if(c!=DBT_DELIM && c!=DBT_DELIM_R && c!=EOF)
00450 goto clean;
00451 if(dbt_row_set_val(rowp,&dtval,DB_STR,ccol))
00452 goto clean;
00453 break;
00454 default:
00455 goto clean;
00456 }
00457 if(c==DBT_DELIM)
00458 c = fgetc(fin);
00459 ccol++;
00460 break;
00461 }
00462 }
00463
00464 if(max_auto)
00465 dtp->auto_val = max_auto;
00466
00467 done:
00468 if(fin)
00469 fclose(fin);
00470 return dtp;
00471 clean:
00473
00474 DBG("DBT:dbt_load_file: error at row=%d col=%d c=%c\n", crow+1, ccol+1, c);
00475 if(dtp)
00476 dbt_table_free(dtp);
00477 return NULL;
00478 }
00479
00480
00484 int dbt_print_table(dbt_table_p _dtp, str *_dbn)
00485 {
00486 dbt_column_p colp = NULL;
00487 dbt_row_p rowp = NULL;
00488 FILE *fout = NULL;
00489 int ccol;
00490 char *p, path[512];
00491
00492 if(!_dtp || !_dtp->name.s || _dtp->name.len <= 0)
00493 return -1;
00494
00495 if(!_dbn || !_dbn->s || _dbn->len <= 0)
00496 {
00497 fout = stdout;
00498 fprintf(fout, "\n Content of [%.*s]\n", _dtp->name.len, _dtp->name.s);
00499 }
00500 else
00501 {
00502 if(_dtp->name.len+_dbn->len > 510)
00503 return -1;
00504 strncpy(path, _dbn->s, _dbn->len);
00505 path[_dbn->len] = '/';
00506 strncpy(path+_dbn->len+1, _dtp->name.s, _dtp->name.len);
00507 path[_dbn->len+_dtp->name.len+1] = 0;
00508 fout = fopen(path, "wt");
00509 if(!fout)
00510 return -1;
00511 }
00512
00513 colp = _dtp->cols;
00514 while(colp)
00515 {
00516 switch(colp->type)
00517 {
00518 case DB_INT:
00519 fprintf(fout, "%.*s(int", colp->name.len, colp->name.s);
00520 break;
00521 case DB_FLOAT:
00522 fprintf(fout, "%.*s(float", colp->name.len, colp->name.s);
00523 break;
00524 case DB_DOUBLE:
00525 fprintf(fout, "%.*s(double", colp->name.len, colp->name.s);
00526 break;
00527 case DB_STR:
00528 fprintf(fout, "%.*s(str", colp->name.len, colp->name.s);
00529 break;
00530 default:
00531 if(fout!=stdout)
00532 fclose(fout);
00533 return -1;
00534 }
00535
00536 if(colp->flag & DBT_FLAG_NULL)
00537 fprintf(fout,",null");
00538 else if(colp->type==DB_INT && colp->flag & DBT_FLAG_AUTO)
00539 fprintf(fout,",auto");
00540 fprintf(fout,")");
00541
00542 colp = colp->next;
00543 if(colp)
00544 fprintf(fout,"%c", DBT_DELIM_C);
00545 }
00546 fprintf(fout, "%c", DBT_DELIM_R);
00547 rowp = _dtp->rows;
00548 while(rowp)
00549 {
00550 for(ccol=0; ccol<_dtp->nrcols; ccol++)
00551 {
00552 switch(_dtp->colv[ccol]->type)
00553 {
00554 case DB_INT:
00555 if(!rowp->fields[ccol].nul)
00556 fprintf(fout,"%d",
00557 rowp->fields[ccol].val.int_val);
00558 break;
00559 case DB_FLOAT:
00560 if(!rowp->fields[ccol].nul)
00561 fprintf(fout, "%.2f",
00562 rowp->fields[ccol].val.float_val);
00563 break;
00564 case DB_DOUBLE:
00565 if(!rowp->fields[ccol].nul)
00566 fprintf(fout, "%.2f",
00567 rowp->fields[ccol].val.double_val);
00568 break;
00569 case DB_STR:
00570 if(!rowp->fields[ccol].nul)
00571 {
00572 p = rowp->fields[ccol].val.str_val.s;
00573 while(p < rowp->fields[ccol].val.str_val.s
00574 + rowp->fields[ccol].val.str_val.len)
00575 {
00576 switch(*p)
00577 {
00578 case '\n':
00579 fprintf(fout, "\\n");
00580 break;
00581 case '\r':
00582 fprintf(fout, "\\r");
00583 break;
00584 case '\t':
00585 fprintf(fout, "\\t");
00586 break;
00587 case '\\':
00588 fprintf(fout, "\\\\");
00589 break;
00590 case DBT_DELIM:
00591 fprintf(fout, "\\%c", DBT_DELIM);
00592 break;
00593 case '\0':
00594 fprintf(fout, "\\0");
00595 break;
00596 default:
00597 fprintf(fout, "%c", *p);
00598 }
00599 p++;
00600 }
00601 }
00602 break;
00603 default:
00604 if(fout!=stdout)
00605 fclose(fout);
00606 return -1;
00607 }
00608 if(ccol<_dtp->nrcols-1)
00609 fprintf(fout, "%c",DBT_DELIM);
00610 }
00611 fprintf(fout, "%c", DBT_DELIM_R);
00612 rowp = rowp->next;
00613 }
00614
00615 if(fout!=stdout)
00616 fclose(fout);
00617
00618 return 0;
00619 }
00620