00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <unistd.h>
00004 #include <errno.h>
00005 #include <string.h>
00006 #include <sys/types.h>
00007 #include <sys/socket.h>
00008 #include <sys/types.h>
00009 #include <arpa/inet.h>
00010 #include <sys/wait.h>
00011 #include <netinet/in.h>
00012 #include <zlib.h>
00013 #include <pthread.h>
00014 #include <alloca.h>
00015 #include "db.h"
00016 #include "xassert.h"
00017 #include "timer.h"
00018 #include "xmem.h"
00019
00020
00021 DB_Text_Result_t *db_recv_text_query(int sockfd, int comp, char **errmsg)
00022 {
00023 DB_Text_Result_t *result;
00024 char *buffer, *zbuf;
00025 int nrows, ncols;
00026
00027 nrows = Readint(sockfd);
00028 ncols = Readint(sockfd);
00029
00030 if (nrows<=0)
00031 {
00032
00033
00034 char *msg = NULL;
00035
00036 result = malloc(sizeof(DB_Text_Result_t));
00037 XASSERT(result);
00038 memset(result, 0, sizeof(DB_Text_Result_t));
00039 result->num_rows = 0;
00040 result->num_cols = ncols;
00041
00042 if (nrows == -1)
00043 {
00044
00045
00046 free(result);
00047 result = NULL;
00048
00049 msg = receive_string(sockfd);
00050
00051 if (errmsg)
00052 {
00053 *errmsg = strdup(msg);
00054 }
00055 }
00056
00057
00058 return result;
00059 }
00060 else
00061 {
00062
00063 if (comp)
00064 {
00065 int tmp;
00066 unsigned long zlen, buflen;
00067 Readn(sockfd, &tmp, sizeof(int));
00068 zlen = (unsigned long) ntohl(tmp);
00069
00070 if (zlen>0)
00071 {
00072
00073 Readn(sockfd, &tmp, sizeof(int));
00074 buflen = (unsigned long) ntohl(tmp);
00075
00076 zbuf = malloc(zlen);
00077 XASSERT(zbuf);
00078 Readn(sockfd, zbuf, zlen);
00079
00080
00081 buffer = malloc(buflen);
00082 XASSERT(buffer);
00083 *((int *)buffer) = htonl((int)buflen);
00084 if (uncompress ((unsigned char*)buffer+sizeof(int), &buflen,
00085 (unsigned char *)zbuf, zlen) != Z_OK) {
00086 free(zbuf);
00087 free(buffer);
00088 fprintf(stderr,"db_recv_text_query: uncompress failed.\n");
00089 return NULL;
00090 }
00091 free(zbuf);
00092 buflen += sizeof(int);
00093
00094
00095 if (buflen != htonl(*((int *)buffer)))
00096 {
00097 free(buffer);
00098 fprintf(stderr,"db_recv_text_query failed: Uncompressed length = %lu, should be %d.\n",
00099 buflen,htonl(*((int *)buffer)));
00100 return NULL;
00101 }
00102 }
00103 else
00104 return NULL;
00105 }
00106 else
00107 {
00108 int tmp, buflen;
00109 Readn(sockfd, &tmp, sizeof(int));
00110 buflen = ntohl(tmp);
00111 if (buflen>0)
00112 {
00113 buffer = malloc(buflen);
00114 XASSERT(buffer);
00115 *((int *)buffer) = htonl(buflen);
00116
00117 Readn(sockfd, buffer+sizeof(int), buflen-sizeof(int));
00118 }
00119 else
00120 return NULL;
00121 }
00122
00123 return db_unpack_text(buffer);
00124 }
00125 }
00126
00127
00128 DB_Text_Result_t *db_unpack_text(char *buf)
00129 {
00130 DB_Text_Result_t *result;
00131 char *p;
00132 int buflen;
00133 unsigned int i,j;
00134
00135 result = malloc(sizeof(DB_Text_Result_t));
00136 XASSERT(result);
00137 result->buffer = buf;
00138
00139
00140 p = buf;
00141 buflen = ntohl(*((int *) p));
00142 p += sizeof(int);
00143 result->num_rows = ntohl(*((int *) p));
00144 p += sizeof(int);
00145 result->num_cols = ntohl(*((int *) p));
00146 p += sizeof(int);
00147
00148
00149 result->column_width = (int *)malloc(result->num_cols*sizeof(int));
00150 XASSERT(result->column_width);
00151 for (i=0; i<result->num_cols; i++)
00152 {
00153 result->column_width[i] = ntohl(*((int *) p));
00154 p += sizeof(int);
00155 }
00156
00157
00158 result->column_name = (char **)malloc(result->num_cols*sizeof(char *));
00159 XASSERT(result->column_name);
00160 result->column_name[0] = p;
00161 for (i=1; i<result->num_cols; i++)
00162 {
00163 while(*p++);
00164 result->column_name[i] = p;
00165 }
00166 while(*p++);
00167
00168
00169 result->field = (char ***) malloc(result->num_rows*sizeof(char **) + result->num_rows*result->num_cols*sizeof(char *));
00170 XASSERT(result->field);
00171 for (i=0; i<result->num_rows; i++)
00172 result->field[i] = (char **) &result->field[result->num_rows +
00173 i*result->num_cols];
00174 for(i = 0; i < result->num_rows; i++)
00175 {
00176 for (j = 0; j < result->num_cols; j++)
00177 {
00178 result->field[i][j] = p;
00179 while(*p++);
00180 }
00181 }
00182 return result;
00183 }
00184
00185 DB_Binary_Result_t *db_recv_binary_query(int sockfd, int comp, char **errmsg)
00186 {
00187
00188 int i, anynull, nrows;
00189 DB_Column_t *col;
00190 DB_Binary_Result_t *result;
00191
00192 result = malloc(sizeof(DB_Binary_Result_t));
00193 XASSERT(result);
00194 nrows = Readint(sockfd);
00195
00196 if (nrows == -1)
00197 {
00198 char *msg = receive_string(sockfd);
00199
00200 if (errmsg)
00201 {
00202 *errmsg = strdup(msg);
00203 }
00204
00205 return NULL;
00206 }
00207 else
00208 result->num_rows = (unsigned int) nrows;
00209 result->num_cols = (unsigned int) Readint(sockfd);
00210
00211 result->column = malloc(result->num_cols*sizeof(DB_Column_t));
00212 XASSERT(result->column);
00213 for (i=0; i<result->num_cols; i++)
00214 {
00215 col = &result->column[i];
00216 col->num_rows = result->num_rows;
00217
00218 col->column_name = receive_string(sockfd);
00219
00220
00221 col->type = (DB_Type_t) Readint(sockfd);
00222
00223
00224 col->size = Readint(sockfd);
00225
00226
00227 col->data = malloc(result->num_rows*col->size);
00228 XASSERT(col->data);
00229 Readn(sockfd, col->data, result->num_rows*col->size);
00230
00231 db_ntoh(col->type, result->num_rows, col->data);
00232
00233 anynull = Readint(sockfd);
00234
00235 col->is_null = malloc(result->num_rows*sizeof(short));
00236 XASSERT(col->is_null);
00237 if (anynull)
00238 {
00239 Readn(sockfd, col->is_null, result->num_rows*sizeof(short));
00240 db_ntoh(DB_INT2, result->num_rows, (void *)col->is_null);
00241
00242 }
00243 else
00244 memset(col->is_null, 0, result->num_rows*sizeof(short));
00245 }
00246
00247 return result;
00248 }
00249
00250
00251
00252
00253 DB_Binary_Result_t **db_recv_binary_query_ntuple(int sockfd, char **errmsg)
00254 {
00255 DB_Binary_Result_t **results = NULL;
00256 DB_Binary_Result_t *exeResult = NULL;
00257
00258 int nelems;
00259 int iElem;
00260
00261
00262
00263 nelems = Readint(sockfd);
00264
00265 if (nelems == -1)
00266 {
00267
00268 char *msg = receive_string(sockfd);
00269
00270 if (errmsg)
00271 {
00272 *errmsg = strdup(msg);
00273 }
00274
00275 return NULL;
00276 }
00277
00278 results = calloc(nelems, sizeof(DB_Binary_Result_t *));
00279 XASSERT(results);
00280
00281 for (iElem = 0; iElem < nelems; iElem++)
00282 {
00283 #if 0
00284 {
00285 nrows = Readint(sockfd);
00286 ncols = Readint(sockfd);
00287
00288 exeResult = malloc(sizeof(DB_Binary_Result_t));
00289 XASSERT(exeResult);
00290
00291 exeResult->column = malloc(ncols * sizeof(DB_Column_t));
00292 XASSERT(exeResult->column);
00293 for (iCol = 0; iCol < ncols; iCol++)
00294 {
00295 pCol = &exeResult->column[iCol];
00296 pCol->num_rows = nrows;
00297
00298
00299 pCol->column_name = receive_string(sockfd);
00300
00301
00302 pCol->type = (DB_Type_t)Readint(sockfd);
00303
00304
00305 pCol->size = Readint(sockfd);
00306
00307
00308 pCol->data = malloc(nrows * pCol->size);
00309 XASSERT(pCol->data);
00310 Readn(sockfd, pCol->data, nrows * pCol->size);
00311 db_ntoh(pCol->type, exeResult->num_rows, pCol->data);
00312
00313
00314 anynull = Readint(sockfd);
00315
00316
00317 pCol->is_null = calloc(nrows, sizeof(short));
00318 XASSERT(pCol->is_null);
00319 if (anynull)
00320 {
00321 Readn(sockfd, pCol->is_null, nrows * sizeof(short));
00322 db_ntoh(DB_INT2, nrows, (void *)pCol->is_null);
00323 }
00324 }
00325 }
00326 #endif
00327
00328
00329 exeResult = db_recv_binary_query(sockfd, 0, errmsg);
00330 if (!exeResult)
00331 {
00332 char *msg = receive_string(sockfd);
00333
00334 if (errmsg)
00335 {
00336 *errmsg = strdup(msg);
00337 }
00338
00339 return NULL;
00340 }
00341
00342
00343 results[iElem] = exeResult;
00344 }
00345
00346 return results;
00347 }
00348
00349 DB_Text_Result_t *db_client_query_txt(int sockfd, char *query, int compress, char **errmsg)
00350 {
00351 int len,ctmp;
00352 struct iovec vec[3];
00353
00354
00355 vec[1].iov_len = strlen(query);
00356 vec[1].iov_base = query;
00357 len = htonl(vec[1].iov_len);
00358 vec[0].iov_len = sizeof(len);
00359 vec[0].iov_base = &len;
00360
00361 ctmp = htonl(compress);
00362 vec[2].iov_len = sizeof(ctmp);
00363 vec[2].iov_base = &ctmp;
00364
00365 Writevn(sockfd, vec, 3);
00366
00367
00368 return db_recv_text_query(sockfd, compress, errmsg);
00369 }
00370
00371
00372 DB_Binary_Result_t *db_client_query_bin(int sockfd, char *query, int compress, char **errmsg)
00373 {
00374 int len,ctmp;
00375 struct iovec vec[3];
00376
00377
00378 vec[1].iov_len = strlen(query);
00379 vec[1].iov_base = query;
00380 len = htonl(vec[1].iov_len);
00381 vec[0].iov_len = sizeof(len);
00382 vec[0].iov_base = &len;
00383
00384 ctmp = htonl(compress);
00385 vec[2].iov_len = sizeof(ctmp);
00386 vec[2].iov_base = &ctmp;
00387
00388 Writevn(sockfd, vec, 3);
00389
00390
00391 return db_recv_binary_query(sockfd, compress, errmsg);
00392 }
00393
00394 DB_Binary_Result_t *db_client_query_bin_array(int sockfd, char *query,
00395 int compress, int n_args,
00396 DB_Type_t *intype, void **argin )
00397 {
00398 int i,vc,tc;
00399 int *tmp;
00400 struct iovec *vec;
00401 char *errmsg = NULL;
00402
00403 vec = malloc((4+3*n_args)*sizeof(struct iovec));
00404 XASSERT(vec);
00405 tmp = malloc((4+3*n_args)*sizeof(int));
00406 XASSERT(tmp);
00407
00408
00409
00410 tc = 0; vc = 0;
00411 vec[vc+1].iov_len = strlen(query);
00412 vec[vc+1].iov_base = query;
00413 tmp[tc] = htonl(vec[vc+1].iov_len);
00414 vec[vc].iov_len = sizeof(tmp[tc]);
00415 vec[vc].iov_base = &tmp[tc];
00416 ++tc; vc+=2;
00417
00418 tmp[tc] = htonl(compress);
00419 vec[vc].iov_len = sizeof(tmp[tc]);
00420 vec[vc].iov_base = &tmp[tc];
00421 ++tc; ++vc;
00422
00423 tmp[tc] = htonl(n_args);
00424 vec[vc].iov_len = sizeof(tmp[tc]);
00425 vec[vc].iov_base = &tmp[tc];
00426 ++tc; ++vc;
00427 for (i=0; i<n_args; i++)
00428 {
00429
00430 tmp[tc] = htonl((int)intype[i]);
00431 vec[vc].iov_len = sizeof(tmp[tc]);
00432 vec[vc].iov_base = &tmp[tc];
00433 ++tc; ++vc;
00434 if (intype[i] == DB_STRING || intype[i]==DB_VARCHAR)
00435 {
00436
00437 if (argin[i]==NULL)
00438 vec[vc+1].iov_len = 0;
00439 else
00440 vec[vc+1].iov_len = strlen((char *)argin[i]);
00441 vec[vc+1].iov_base = argin[i];
00442 tmp[tc] = htonl(vec[vc+1].iov_len);
00443 vec[vc].iov_len = sizeof(tmp[tc]);
00444 vec[vc].iov_base = &tmp[tc];
00445 ++tc; vc+=2;
00446 }
00447 else
00448 {
00449
00450 db_byteswap(intype[i], 1, (char *)argin[i]);
00451 vec[vc].iov_len = db_sizeof(intype[i]);
00452 vec[vc].iov_base = argin[i];
00453 ++tc; ++vc;
00454 }
00455 }
00456
00457 Writevn(sockfd, vec, vc);
00458
00459 for (i=0; i<n_args; i++)
00460 {
00461 if (!(intype[i] == DB_STRING || intype[i]==DB_VARCHAR))
00462 db_byteswap(intype[i], 1, (char *)argin[i]);
00463 }
00464 free(tmp);
00465 free(vec);
00466
00467
00468 return db_recv_binary_query(sockfd, compress, &errmsg);
00469 }
00470
00471
00472
00473
00474
00475
00476
00477
00478 DB_Binary_Result_t **db_client_query_bin_ntuple(int sockfd, const char *stmnt, unsigned int nexes, unsigned int nargs, DB_Type_t *dbtypes, void **values)
00479 {
00480 char *errmsg = NULL;
00481 int *len = NULL;
00482 int tmp[10 + MAXARG];
00483 int tc;
00484 int vc;
00485 int sum;
00486 char *str = NULL;
00487 char *buffer[MAXARG];
00488 char *pBuf = NULL;
00489 void *stmntDup = NULL;
00490 int iArg;
00491 int iExe;
00492 struct iovec *vec = NULL;
00493
00494 tc = 0;
00495 vc = 0;
00496 len = malloc(nexes * sizeof(int));
00497 XASSERT(len);
00498 vec = malloc((4 + nargs * 3) * sizeof(struct iovec));
00499
00500
00501
00502
00503 XASSERT(vec);
00504
00505 stmntDup = (void *)strdup(stmnt);
00506 XASSERT(stmntDup);
00507
00508
00509 vec[1].iov_len = strlen(stmntDup);
00510 vec[1].iov_base = stmntDup;
00511
00512
00513 tmp[tc] = ntohl(vec[1].iov_len);
00514 vec[0].iov_len = sizeof(tmp[tc]);
00515 vec[0].iov_base = &tmp[tc];
00516 ++tc;
00517 vc += 2;
00518
00519
00520 tmp[tc] = htonl(nexes);
00521 vec[vc].iov_len = sizeof(tmp[tc]);
00522 vec[vc].iov_base = &tmp[tc];
00523 ++tc; ++vc;
00524
00525
00526 tmp[tc] = htonl(nargs);
00527 vec[vc].iov_len = sizeof(tmp[tc]);
00528 vec[vc].iov_base = &tmp[tc];
00529 ++tc;
00530 ++vc;
00531
00532
00533 for (iArg = 0; iArg < nargs; iArg++)
00534 {
00535 tmp[tc] = htonl((int)dbtypes[iArg]);
00536 vec[vc].iov_len = sizeof(tmp[tc]);
00537 vec[vc].iov_base = &tmp[tc];
00538 ++tc;
00539 ++vc;
00540 }
00541
00542 for (iArg = 0; iArg < nargs; iArg++)
00543 {
00544 if (dbtypes[iArg] == DB_STRING || dbtypes[iArg] == DB_VARCHAR)
00545 {
00546
00547
00548 sum = 0;
00549 for (iExe = 0; iExe < nexes; iExe++)
00550 {
00551 str = ((char **)values[iArg])[iExe];
00552 if (str)
00553 {
00554 len[iExe] = strlen(str);
00555 }
00556 else
00557 {
00558 len[iExe] = 0;
00559 }
00560
00561 sum += len[iExe] + 1;
00562
00563
00564 }
00565
00566
00567 tmp[tc] = htonl(sum);
00568 vec[vc].iov_len = sizeof(tmp[tc]);
00569 vec[vc].iov_base = &tmp[tc];
00570 ++tc;
00571 ++vc;
00572
00573
00574 buffer[iArg] = malloc(sum);
00575 XASSERT(buffer[iArg]);
00576 pBuf = buffer[iArg];
00577 for (iExe = 0; iExe < nexes; iExe++)
00578 {
00579 memcpy(pBuf, ((char **)values[iArg])[iExe], len[iExe]);
00580 pBuf += len[iExe];
00581 *pBuf++ = 0;
00582 }
00583
00584 vec[vc].iov_len = sum;
00585 vec[vc].iov_base = buffer[iArg];
00586 ++vc;
00587 }
00588 else
00589 {
00590
00591 buffer[iArg] = NULL;
00592 db_hton(dbtypes[iArg], nexes, values[iArg]);
00593 vec[vc].iov_len = db_sizeof(dbtypes[iArg]) * nexes;
00594 vec[vc].iov_base = values[iArg];
00595 ++vc;
00596 }
00597 }
00598
00599
00600 Writevn(sockfd, vec, vc);
00601
00602 free(stmntDup);
00603 free(vec);
00604 free(len);
00605
00606 for (iArg = 0; iArg < nargs; iArg++)
00607 {
00608 if (buffer[iArg])
00609 {
00610 free(buffer[iArg]);
00611 buffer[iArg] = NULL;
00612 }
00613
00614 if (!(dbtypes[iArg] == DB_STRING || dbtypes[iArg] == DB_VARCHAR))
00615 {
00616 db_ntoh(dbtypes[iArg], nexes, values[iArg]);
00617 }
00618 }
00619
00620
00621 return db_recv_binary_query_ntuple(sockfd, &errmsg);
00622 }
00623
00624 int db_client_dms(int sockfd, int *row_count, char *query)
00625 {
00626 int status, n;
00627
00628
00629 send_string(sockfd,query);
00630
00631
00632 status = Readint(sockfd);
00633 n = Readint(sockfd);
00634 if (row_count)
00635 *row_count = n;
00636
00637 return status;
00638 }
00639
00640
00641 int db_client_dms_array(int sockfd, int *row_count, char *query,
00642 int n_rows, int n_args, DB_Type_t *intype,
00643 void **argin )
00644 {
00645 int status, n, i, j, tmp[10+MAXARG], tc, vc;
00646 int *len, sum;
00647 char *str, *buffer[MAXARG], *p;
00648 struct iovec *vec;
00649
00650 tc = 0; vc = 0;
00651 len = malloc(n_rows*sizeof(int));
00652 XASSERT(len);
00653 vec = malloc((4+n_args*3)*sizeof(struct iovec));
00654 XASSERT(vec);
00655 vec[1].iov_len = strlen(query);
00656 vec[1].iov_base = query;
00657 tmp[tc] = ntohl(vec[1].iov_len);
00658 vec[0].iov_len = sizeof(tmp[tc]);
00659 vec[0].iov_base = &tmp[tc];
00660 ++tc; vc += 2;
00661
00662 tmp[tc] = htonl(n_rows);
00663 vec[vc].iov_len = sizeof(tmp[tc]);
00664 vec[vc].iov_base = &tmp[tc];
00665 ++tc; ++vc;
00666
00667 tmp[tc] = htonl(n_args);
00668 vec[vc].iov_len = sizeof(tmp[tc]);
00669 vec[vc].iov_base = &tmp[tc];
00670 ++tc; ++vc;
00671
00672 for (i=0; i<n_args; i++)
00673 {
00674 tmp[tc] = htonl((int)intype[i]);
00675 vec[vc].iov_len = sizeof(tmp[tc]);
00676 vec[vc].iov_base = &tmp[tc];
00677 ++tc; ++vc;
00678 }
00679
00680 for (i=0; i<n_args; i++)
00681 {
00682 if ( intype[i] == DB_STRING || intype[i] == DB_VARCHAR )
00683 {
00684 sum = 0;
00685 for (j=0; j<n_rows; j++)
00686 {
00687 str = ((char **)argin[i])[j];
00688 if (str)
00689 len[j] = strlen(str);
00690 else
00691 len[j] = 0;
00692 sum += len[j]+1;
00693 }
00694
00695 tmp[tc] = htonl(sum);
00696 vec[vc].iov_len = sizeof(tmp[tc]);
00697 vec[vc].iov_base = &tmp[tc];
00698 ++tc; ++vc;
00699
00700
00701 buffer[i] = malloc(sum);
00702 XASSERT(buffer[i]);
00703 p = buffer[i];
00704 for (j=0; j<n_rows; j++)
00705 {
00706 memcpy(p, ((char **)argin[i])[j], len[j]);
00707 p += len[j];
00708 *p++ = 0;
00709 }
00710
00711 vec[vc].iov_len = sum;
00712 vec[vc].iov_base = buffer[i];
00713 ++vc;
00714 }
00715 else
00716 {
00717 buffer[i] = NULL;
00718 db_hton(intype[i], n_rows, argin[i]);
00719 vec[vc].iov_len = db_sizeof(intype[i])*n_rows;
00720 vec[vc].iov_base = argin[i];
00721 ++vc;
00722 }
00723 }
00724 Writevn(sockfd, vec, vc);
00725
00726 free(vec);
00727 free(len);
00728 for (i=0; i<n_args; i++)
00729 {
00730 if (buffer[i])
00731 free(buffer[i]);
00732 if ( !(intype[i] == DB_STRING || intype[i] == DB_VARCHAR ))
00733 db_ntoh(intype[i], n_rows, argin[i]);
00734 }
00735
00736 status = Readint(sockfd);
00737 n = Readint(sockfd);
00738 if (row_count)
00739 *row_count = n;
00740
00741 return status;
00742 }
00743
00744
00745
00746
00747 int db_client_bulk_insert_array(int sockfd, char *table,
00748 int n_rows, int n_args, DB_Type_t *intype,
00749 void **argin )
00750 {
00751 int status, i, j, tmp[10+MAXARG], tc, vc;
00752 int *len, sum;
00753 char *str, *buffer[MAXARG], *p;
00754 struct iovec *vec;
00755
00756 tc = 0; vc = 0;
00757 len = malloc(n_rows*sizeof(int));
00758 XASSERT(len);
00759 vec = malloc((4+n_args*3)*sizeof(struct iovec));
00760 XASSERT(vec);
00761 vec[1].iov_len = strlen(table);
00762 vec[1].iov_base = table;
00763 tmp[tc] = ntohl(vec[1].iov_len);
00764 vec[0].iov_len = sizeof(tmp[tc]);
00765 vec[0].iov_base = &tmp[tc];
00766 ++tc; vc += 2;
00767
00768 tmp[tc] = htonl(n_rows);
00769 vec[vc].iov_len = sizeof(tmp[tc]);
00770 vec[vc].iov_base = &tmp[tc];
00771 ++tc; ++vc;
00772
00773 tmp[tc] = htonl(n_args);
00774 vec[vc].iov_len = sizeof(tmp[tc]);
00775 vec[vc].iov_base = &tmp[tc];
00776 ++tc; ++vc;
00777
00778 for (i=0; i<n_args; i++)
00779 {
00780 tmp[tc] = htonl((int)intype[i]);
00781 vec[vc].iov_len = sizeof(tmp[tc]);
00782 vec[vc].iov_base = &tmp[tc];
00783 ++tc; ++vc;
00784 }
00785
00786 for (i=0; i<n_args; i++)
00787 {
00788 if ( intype[i] == DB_STRING || intype[i] == DB_VARCHAR )
00789 {
00790 sum = 0;
00791 for (j=0; j<n_rows; j++)
00792 {
00793 str = ((char **)argin[i])[j];
00794 if (str)
00795 len[j] = strlen(str);
00796 else
00797 len[j] = 0;
00798 sum += len[j]+1;
00799 }
00800
00801 tmp[tc] = htonl(sum);
00802 vec[vc].iov_len = sizeof(tmp[tc]);
00803 vec[vc].iov_base = &tmp[tc];
00804 ++tc; ++vc;
00805
00806
00807 buffer[i] = malloc(sum);
00808 XASSERT(buffer[i]);
00809 p = buffer[i];
00810 for (j=0; j<n_rows; j++)
00811 {
00812 memcpy(p, ((char **)argin[i])[j], len[j]);
00813 p += len[j];
00814 *p++ = 0;
00815 }
00816
00817 vec[vc].iov_len = sum;
00818 vec[vc].iov_base = buffer[i];
00819 ++vc;
00820 }
00821 else
00822 {
00823 buffer[i] = NULL;
00824 db_hton(intype[i], n_rows, argin[i]);
00825 vec[vc].iov_len = db_sizeof(intype[i])*n_rows;
00826 vec[vc].iov_base = argin[i];
00827 ++vc;
00828 }
00829 }
00830 Writevn(sockfd, vec, vc);
00831
00832 free(vec);
00833 free(len);
00834 for (i=0; i<n_args; i++)
00835 {
00836 if (buffer[i])
00837 free(buffer[i]);
00838 if ( !(intype[i] == DB_STRING || intype[i] == DB_VARCHAR ))
00839 db_ntoh(intype[i], n_rows, argin[i]);
00840 }
00841
00842 status = Readint(sockfd);
00843
00844 return status;
00845 }
00846
00847
00848 int db_client_sequence_drop(int sockfd, char *table)
00849 {
00850 send_string(sockfd, table);
00851 return Readint(sockfd);
00852 }
00853
00854 int db_client_sequence_create(int sockfd, char *table)
00855 {
00856 send_string(sockfd, table);
00857 return Readint(sockfd);
00858 }
00859
00860 long long db_client_sequence_getnext(int sockfd, char *table)
00861 {
00862 send_string(sockfd, table);
00863 return Readlonglong(sockfd);
00864 }
00865
00866
00867 long long *db_client_sequence_getnext_n(int sockfd, char *table, int n)
00868 {
00869 int i, status;
00870 long long *seqnums;
00871 struct iovec vec[3];
00872 int tmp, len;
00873
00874 vec[1].iov_len = strlen(table);
00875 vec[1].iov_base = table;
00876 len = htonl(vec[1].iov_len);
00877 vec[0].iov_len = sizeof(len);
00878 vec[0].iov_base = &len;
00879 tmp = htonl(n);
00880 vec[2].iov_len = sizeof(tmp);
00881 vec[2].iov_base = &tmp;
00882 Writevn(sockfd, vec, 3);
00883
00884 status = Readint(sockfd);
00885 if (status==0)
00886 {
00887 seqnums = malloc(n*sizeof(long long));
00888 XASSERT(seqnums);
00889 for (i=0; i<n; i++)
00890 seqnums[i] = (long long)Readlonglong(sockfd);
00891 return seqnums;
00892 }
00893 else
00894 return NULL;
00895 }
00896
00897
00898 long long db_client_sequence_getcurrent(int sockfd, char *table)
00899 {
00900 send_string(sockfd, table);
00901 return (long long)Readlonglong(sockfd);
00902 }
00903
00904 long long db_client_sequence_getlast(int sockfd, char *table)
00905 {
00906 send_string(sockfd, table);
00907 return (long long)Readlonglong(sockfd);
00908 }