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 #include <stdio.h>
00030 #include <stdlib.h>
00031 #include <string.h>
00032
00033 #include "xsb_config.h"
00034 #include "cell_xsb.h"
00035
00036 #ifdef WIN_NT
00037 #define XSB_DLL
00038 #endif
00039
00040 #include "cinterf.h"
00041 #include "io_builtins_xsb.h"
00042 #include "driver_manager_defs.h"
00043
00044 static struct xsb_connectionHandle* isConnectionHandle(char* handle);
00045 static struct xsb_queryHandle* isQueryHandle(char* handle);
00046 static char* buildSQLQuery(prolog_term sqlQueryList);
00047 static union functionPtrs* getDriverFunction(char* driver, int type);
00048 static int bindReturnList(prolog_term returnList, struct xsb_data** result, struct xsb_queryHandle*);
00049 static void freeQueryHandle(struct xsb_queryHandle* qHandle, int pos);
00050 static void freeConnectionHandle(struct xsb_connectionHandle* cHandle, int pos);
00051 static int closeQueryHandle(char* queryHandle);
00052
00053 struct xsb_connectionHandle* CHandles[MAX_CONNECTIONS];
00054 struct xsb_queryHandle* QHandles[MAX_QUERIES];
00055 struct driver* DBdrivers[MAX_DRIVERS];
00056 int numDrivers, numCHandles, numQHandles;
00057 char* errorMesg;
00058 char* errorNumber;
00059
00060
00061 DllExport int call_conv initialise(void)
00062 {
00063 numDrivers = numCHandles = numQHandles = 0;
00064 errorMesg = NULL;
00065 errorNumber = NULL;
00066 return TRUE;
00067 }
00068
00069
00070 DllExport int call_conv openConnection(void)
00071 {
00072 int (*connectDriver)(struct xsb_connectionHandle*);
00073 char* (*errorMesgDriver)();
00074 struct xsb_connectionHandle* cHandle;
00075 char *handle, *driver, *server, *database=NULL, *user, *password, *dsn;
00076 int val;
00077
00078 handle = ptoc_string(1);
00079 driver = ptoc_string(2);
00080 server = ptoc_string(3);
00081 if (strlen(server) == 0)
00082 dsn = ptoc_string(4);
00083 else
00084 database = ptoc_string(4);
00085 user = ptoc_string(5);
00086 password = ptoc_string(6);
00087
00088 if (isConnectionHandle(handle) != NULL) {
00089 errorMesg = "XSB_DBI ERROR: Connection handle already exists";
00090 errorNumber = "XSB_DBI_006";
00091 return FALSE;
00092 }
00093
00094 if (getDriverFunction(driver, CONNECT) != NULL)
00095 connectDriver = getDriverFunction(driver, CONNECT)->connectDriver;
00096 else
00097 return FALSE;
00098
00099 cHandle = (struct xsb_connectionHandle *)malloc(sizeof(struct xsb_connectionHandle));
00100 cHandle->handle = (char *)malloc((strlen(handle) + 1) * sizeof(char));
00101 strcpy(cHandle->handle, handle);
00102 cHandle->driver = (char *)malloc((strlen(driver) + 1) * sizeof(char));
00103 strcpy(cHandle->driver, driver);
00104 if (strlen(server) == 0) {
00105 cHandle->dsn = (char *)malloc((strlen(dsn) + 1) * sizeof(char));
00106 strcpy(cHandle->dsn, dsn);
00107 cHandle->server = NULL;
00108 cHandle->database = NULL;
00109 }
00110 else {
00111 cHandle->server = (char *)malloc((strlen(server) + 1) * sizeof(char));
00112 strcpy(cHandle->server, server);
00113 cHandle->database = (char *)malloc((strlen(database) + 1) * sizeof(char));
00114 strcpy(cHandle->database, database);
00115 cHandle->dsn = NULL;
00116 }
00117 cHandle->user = (char *)malloc((strlen(user) + 1) * sizeof(char));
00118 strcpy(cHandle->user, user);
00119 cHandle->password = (char *)malloc((strlen(password) + 1) * sizeof(char));
00120 strcpy(cHandle->password, password);
00121
00122 CHandles[numCHandles++] = cHandle;
00123 if ((val = connectDriver(cHandle)) != SUCCESS) {
00124 if (getDriverFunction(cHandle->driver, ERROR_MESG) != NULL)
00125 errorMesgDriver = getDriverFunction(cHandle->driver, ERROR_MESG)->errorMesgDriver;
00126 else
00127 return FALSE;
00128
00129 errorMesg = errorMesgDriver();
00130 errorNumber = "XSB_DBI_000";
00131 freeConnectionHandle(cHandle, numCHandles - 1);
00132 return FALSE;
00133 }
00134
00135 return TRUE;
00136 }
00137
00138
00139 DllExport int call_conv closeConnection(void)
00140 {
00141 int (*disconnectDriver)(struct xsb_connectionHandle *);
00142 int (*closeStmtDriver)(struct xsb_queryHandle *);
00143 char* (*errorMesgDriver)();
00144 char* handle;
00145 int val, i, j;
00146
00147 handle = ptoc_string(1);
00148
00149 for (i = 0 ; i < numCHandles ; i++) {
00150 if (!strcmp(CHandles[i]->handle, handle)) {
00151 if (getDriverFunction(CHandles[i]->driver, DISCONNECT) != NULL)
00152 disconnectDriver = getDriverFunction(CHandles[i]->driver, DISCONNECT)->disconnectDriver;
00153 else
00154 return FALSE;
00155
00156 val = disconnectDriver(CHandles[i]);
00157
00158 if (val == FAILURE) {
00159 errorMesgDriver = getDriverFunction(CHandles[i]->driver, ERROR_MESG)->errorMesgDriver;
00160 errorMesg = errorMesgDriver();
00161 return FALSE;
00162 }
00163
00164 for (j = 0 ; j < numQHandles ; j++) {
00165 if (!strcmp(QHandles[j]->connHandle->handle, handle)) {
00166 if (getDriverFunction(CHandles[i]->driver, ERROR_MESG) != NULL)
00167 closeStmtDriver = getDriverFunction(CHandles[i]->driver, ERROR_MESG)->closeStmtDriver;
00168 else
00169 return FALSE;
00170
00171 val = closeStmtDriver(QHandles[j]);
00172 if (val == FAILURE) {
00173 errorMesgDriver = getDriverFunction(CHandles[i]->driver, ERROR_MESG)->errorMesgDriver;
00174 errorMesg = errorMesgDriver();
00175 return FALSE;
00176 }
00177 freeQueryHandle(QHandles[j], j);
00178 break;
00179 }
00180 }
00181 freeConnectionHandle(CHandles[i], i);
00182 return TRUE;
00183 }
00184 }
00185
00186 errorMesg = "XSB_DBI ERROR: Connection handle does not exist";
00187 errorNumber = "XSB_DBI_004";
00188 return FALSE;
00189 }
00190
00191
00192 DllExport int call_conv queryConnection(void)
00193 {
00194 struct xsb_data** (*queryDriver)(struct xsb_queryHandle*);
00195 char* (*errorMesgDriver)();
00196 prolog_term returnList, sqlQueryList;
00197 struct xsb_connectionHandle* cHandle;
00198 struct xsb_queryHandle* qHandle;
00199 struct xsb_data** result;
00200 char *chandle, *qhandle, *sqlQuery;
00201 int val;
00202
00203 chandle = ptoc_string(1);
00204 qhandle = ptoc_string(2);
00205 sqlQueryList = reg_term(3);
00206 returnList = reg_term(4);
00207
00208 result = NULL;
00209
00210 if ((qHandle = isQueryHandle(qhandle)) != NULL) {
00211 if (strcmp(qHandle->connHandle->handle, chandle)) {
00212 errorMesg = "XSB_DBI ERROR: Query handle already exists";
00213 errorNumber = "XSB_DBI_007";;
00214 return FALSE;
00215 }
00216
00217 if (getDriverFunction(qHandle->connHandle->driver, QUERY) != NULL) {
00218 queryDriver =
00219 getDriverFunction(qHandle->connHandle->driver, QUERY)->queryDriver;
00220 }
00221 else {
00222 return FALSE;
00223 }
00224
00225 sqlQuery = buildSQLQuery(sqlQueryList);
00226 if (strcmp(qHandle->query, sqlQuery)) {
00227 errorMesg =
00228 "XSB DBI ERROR: Same query handle used for different queries";
00229 errorNumber = "XSB_DBI_010";
00230 return FALSE;
00231 }
00232
00233 result = queryDriver(qHandle);
00234 if (result == NULL && qHandle->state == QUERY_RETRIEVE) {
00235 closeQueryHandle(qhandle);
00236 }
00237 }
00238 else if ((cHandle = isConnectionHandle(chandle)) != NULL) {
00239 sqlQuery = buildSQLQuery(sqlQueryList);
00240 qHandle = (struct xsb_queryHandle *)malloc(sizeof(struct xsb_queryHandle));
00241 qHandle->handle = (char *)malloc((strlen(qhandle) + 1) * sizeof(char));
00242 strcpy(qHandle->handle, qhandle);
00243 qHandle->connHandle = cHandle;
00244 qHandle->query = (char *)malloc((strlen(sqlQuery) + 1) * sizeof(char));
00245 strcpy(qHandle->query, sqlQuery);
00246 qHandle->state = QUERY_BEGIN;
00247 QHandles[numQHandles++] = qHandle;
00248
00249 if (getDriverFunction(qHandle->connHandle->driver, QUERY) != NULL)
00250 queryDriver = getDriverFunction(qHandle->connHandle->driver, QUERY)->queryDriver;
00251 else
00252 return FALSE;
00253
00254 result = queryDriver(qHandle);
00255 }
00256 else {
00257 errorMesg = "XSB_DBI ERROR: Connection handle does not exist";
00258 errorNumber = "XSB_DBI_004";
00259 return FALSE;
00260 }
00261
00262 if (result == NULL) {
00263 closeQueryHandle(qhandle);
00264 }
00265
00266 val = bindReturnList(returnList, result, qHandle);
00267 if (val == TOO_MANY_RETURN_COLS || val == TOO_FEW_RETURN_COLS || val == INVALID_RETURN_LIST)
00268 return FALSE;
00269
00270 if ((cHandle = isConnectionHandle(chandle)) != NULL) {
00271 if (getDriverFunction(cHandle->driver, ERROR_MESG) != NULL)
00272 errorMesgDriver =
00273 getDriverFunction(cHandle->driver, ERROR_MESG)->errorMesgDriver;
00274 else
00275 return FALSE;
00276
00277 errorMesg = errorMesgDriver();
00278 errorNumber = "XSB_DBI_000";
00279 }
00280
00281 if (errorMesg == NULL && val == RESULT_NONEMPTY_OR_NOT_REQUESTED)
00282 return TRUE;
00283 else
00284 return FALSE;
00285 }
00286
00287 DllExport int call_conv prepareStatement(void)
00288 {
00289 int (*prepareStmtDriver)(struct xsb_queryHandle*);
00290 char* (*errorMesgDriver)();
00291 prolog_term sqlQueryList;
00292 char *chandle, *qhandle, *sqlQuery;
00293 struct xsb_queryHandle* qHandle;
00294 struct xsb_connectionHandle* cHandle;
00295 int val;
00296
00297 chandle = ptoc_string(1);
00298 qhandle = ptoc_string(2);
00299 sqlQueryList = reg_term(3);
00300
00301 if ((cHandle = isConnectionHandle(chandle)) == NULL) {
00302 errorMesg = "XSB_DBI ERROR: Connection handle does not exist";
00303 errorNumber = "XSB_DBI_004";
00304 return FALSE;
00305 }
00306
00307 if ((qHandle = isQueryHandle(qhandle)) != NULL) {
00308 errorMesg = "XSB_DBI ERROR: Query handle already exists";
00309 errorNumber = "XSB_DBI_007";
00310 return FALSE;
00311 }
00312
00313 sqlQuery = buildSQLQuery(sqlQueryList);
00314
00315 qHandle = (struct xsb_queryHandle *)malloc(sizeof(struct xsb_queryHandle));
00316 qHandle->connHandle = cHandle;
00317 qHandle->query = (char *)malloc((strlen(sqlQuery) + 1) * sizeof(char));
00318 strcpy(qHandle->query, sqlQuery);
00319 qHandle->handle = (char *)malloc((strlen(qhandle) + 1) * sizeof(char));
00320 strcpy(qHandle->handle, qhandle);
00321 qHandle->state = QUERY_BEGIN;
00322
00323 if (getDriverFunction(cHandle->driver, PREPARE) != NULL)
00324 prepareStmtDriver = getDriverFunction(cHandle->driver, PREPARE)->prepareStmtDriver;
00325 else
00326 return FALSE;
00327 if ((val = prepareStmtDriver(qHandle)) != FAILURE) {
00328 qHandle->numParams = val;
00329 QHandles[numQHandles++] = qHandle;
00330 }
00331 else {
00332 if (getDriverFunction(cHandle->driver, ERROR_MESG) != NULL)
00333 errorMesgDriver = getDriverFunction(cHandle->driver, ERROR_MESG)->errorMesgDriver;
00334 else
00335 return FALSE;
00336 errorMesg = errorMesgDriver();
00337 errorNumber = "XSB_DBI_000";
00338 free(qHandle->query);
00339 free(qHandle);
00340 return FALSE;
00341 }
00342
00343 return TRUE;
00344 }
00345
00346 DllExport int call_conv executePreparedStatement(void)
00347 {
00348 struct xsb_data** (*executeStmtDriver)(struct xsb_data**, struct xsb_queryHandle*);
00349 char* (*errorMesgDriver)();
00350 struct xsb_queryHandle* qHandle;
00351 struct xsb_connectionHandle* cHandle;
00352 struct xsb_data** bindValues;
00353 struct xsb_data** result;
00354 prolog_term bindList, returnList, element;
00355 char *queryHandle, *chandle;
00356 double temp_float;
00357 int i, temp_int, val;
00358
00359 queryHandle = ptoc_string(1);
00360 bindList = reg_term(2);
00361 returnList = reg_term(3);
00362
00363 if ((qHandle = isQueryHandle(queryHandle)) == NULL) {
00364 errorMesg = "XSB_DBI ERROR: Query handle does not exist";
00365 errorNumber = "XSB_DBI_005";
00366 return FALSE;
00367 }
00368
00369 if (qHandle->state == QUERY_BEGIN) {
00370 bindValues =
00371 (struct xsb_data **)malloc(qHandle->numParams * sizeof(struct xsb_data *));
00372 for (i = 0 ; i < qHandle->numParams ; i++) {
00373 bindValues[i] = (struct xsb_data *)malloc(sizeof(struct xsb_data));
00374 if (is_nil(bindList)) {
00375 errorMesg = "XSB_DBI ERROR: Not all paremeters supplied";
00376 errorNumber = "XSB_DBI_008";
00377 return FALSE;
00378 }
00379 element = p2p_car(bindList);
00380 if (is_string(element)) {
00381 bindValues[i]->type = STRING_TYPE;
00382 bindValues[i]->length = strlen(p2c_string(element));
00383 bindValues[i]->val = (union xsb_value *)malloc(sizeof(union xsb_value));
00384 bindValues[i]->val->str_val =
00385 (char *)malloc((strlen(p2c_string(element)) + 1) * sizeof(char));
00386 strcpy(bindValues[i]->val->str_val, p2c_string(element));
00387 }
00388 else if (is_int(element)) {
00389 bindValues[i]->type = INT_TYPE;
00390 bindValues[i]->val = (union xsb_value *)malloc(sizeof(union xsb_value));
00391 bindValues[i]->val->i_val = (int *)malloc(sizeof(int));
00392 temp_int = p2c_int(element);
00393 bindValues[i]->val->i_val = &temp_int;
00394 }
00395 else if (is_float(element)) {
00396 bindValues[i]->type = FLOAT_TYPE;
00397 bindValues[i]->val = (union xsb_value *)malloc(sizeof(union xsb_value));
00398 bindValues[i]->val->f_val = (double *)malloc(sizeof(double));
00399 temp_float = p2c_float(element);
00400 bindValues[i]->val->f_val = &temp_float;
00401 }
00402 else if (is_functor(element)) {
00403 }
00404 else if (is_var(element)) {
00405 errorMesg = "XSB_DBI ERROR: Unbound variable in parameter list";
00406 errorNumber = "XSB_DBI_009";
00407 return FALSE;
00408 }
00409 bindList = p2p_cdr(bindList);
00410 }
00411 }
00412
00413 if (getDriverFunction(qHandle->connHandle->driver, EXEC_PREPARE) != NULL)
00414 executeStmtDriver =
00415 getDriverFunction(qHandle->connHandle->driver, EXEC_PREPARE)->executeStmtDriver;
00416 else
00417 return FALSE;
00418
00419 result = executeStmtDriver(bindValues, qHandle);
00420
00421 if (result == NULL && qHandle->state == QUERY_BEGIN) {
00422 if (getDriverFunction(qHandle->connHandle->driver, ERROR_MESG) != NULL)
00423 errorMesgDriver =
00424 getDriverFunction(qHandle->connHandle->driver, ERROR_MESG)->errorMesgDriver;
00425 else
00426 return FALSE;
00427
00428 errorMesg = errorMesgDriver();
00429 return FALSE;
00430 }
00431
00432 val = bindReturnList(returnList, result, qHandle);
00433
00434 if (result == NULL) {
00435 qHandle->state = QUERY_BEGIN;
00436 }
00437
00438 if (val == TOO_MANY_RETURN_COLS || val == TOO_FEW_RETURN_COLS || val == INVALID_RETURN_LIST)
00439 return FALSE;
00440
00441 cHandle = qHandle->connHandle;
00442 chandle = cHandle->handle;
00443 if ((cHandle = isConnectionHandle(chandle)) != NULL) {
00444 if (getDriverFunction(cHandle->driver, ERROR_MESG) != NULL)
00445 errorMesgDriver =
00446 getDriverFunction(cHandle->driver, ERROR_MESG)->errorMesgDriver;
00447 else
00448 return FALSE;
00449
00450 errorMesg = errorMesgDriver();
00451 errorNumber = "XSB_DBI_000";
00452 }
00453
00454 if (errorMesg == NULL && val == RESULT_NONEMPTY_OR_NOT_REQUESTED)
00455 return TRUE;
00456 else
00457 return FALSE;
00458 }
00459
00460
00461 DllExport int call_conv closeStatement(void)
00462 {
00463 char* queryHandle;
00464
00465 queryHandle = ptoc_string(1);
00466 return closeQueryHandle(queryHandle);
00467 }
00468
00469
00470 DllExport int call_conv exception(void)
00471 {
00472 prolog_term number;
00473 prolog_term message;
00474
00475 number = reg_term(1);
00476 message = reg_term(2);
00477 if (is_var(message) && errorMesg != NULL && errorNumber != NULL) {
00478 c2p_string(errorMesg, message);
00479 c2p_string(errorNumber, number);
00480 errorMesg = NULL;
00481 errorNumber = NULL;
00482 return TRUE;
00483 }
00484
00485 return FALSE;
00486 }
00487
00488
00489 static char* buildSQLQuery(prolog_term sqlQueryList)
00490 {
00491 prolog_term element;
00492 char* sqlQuery;
00493 char* temp;
00494 char* t1;
00495 int i, cnt;
00496
00497 sqlQuery = (char *)malloc(QUERY_SIZE * sizeof(char));
00498 sqlQuery[0] = '\0';
00499 while (!is_nil(sqlQueryList)) {
00500 element = p2p_car(sqlQueryList);
00501 sqlQueryList = p2p_cdr(sqlQueryList);
00502 if (is_string(element)) {
00503 t1 = (char *)malloc(ELEMENT_SIZE * sizeof(char));
00504 sprintf(t1, "%s", p2c_string(element));
00505 if (t1[0] == TERM_CHAR) {
00506 cnt = 0;
00507 temp = (char *)malloc(ELEMENT_SIZE * sizeof(char));
00508 temp[cnt++] = '\'';
00509
00510 for (i = 0 ; i < strlen(t1) ; i++) {
00511 if (t1[i] == '\'') {
00512 temp[cnt++] = '\\';
00513 temp[cnt++] = t1[i];
00514 }
00515 else {
00516 temp[cnt++] = t1[i];
00517 }
00518 }
00519 temp[cnt++] = '\'';
00520 strcat(sqlQuery, temp);
00521 }
00522 else {
00523 strcat(sqlQuery, t1);
00524 }
00525 }
00526 else if (is_int(element)) {
00527 temp = (char *)malloc(ELEMENT_SIZE * sizeof(char));
00528 sprintf(temp, "%d", p2c_int(element));
00529 strcat(sqlQuery, temp);
00530 }
00531 else if (is_float(element)) {
00532 temp = (char *)malloc(ELEMENT_SIZE * sizeof(char));
00533 sprintf(temp, "%f", p2c_float(element));
00534 strcat(sqlQuery, temp);
00535 }
00536 else if (is_var(element)) {
00537 errorMesg = "XSB_DBI ERROR: Unbound variable in parameter list";
00538 }
00539 }
00540
00541 return sqlQuery;
00542 }
00543
00544
00545 static int bindReturnList(prolog_term returnList, struct xsb_data** result, struct xsb_queryHandle* qHandle)
00546 {
00547 prolog_term element;
00548 char* temp;
00549 char c;
00550 int i, j;
00551 int rFlag;
00552
00553 if (is_nil(returnList) && result == NULL) {
00554 rFlag = RESULT_NONEMPTY_OR_NOT_REQUESTED;
00555 }
00556
00557 if (!is_nil(returnList) && result == NULL && qHandle->state == QUERY_BEGIN) {
00558 errorMesg = "XSB_DBI_ERROR: Invalid return list in query";
00559 errorNumber = "XSB_DBI_012";
00560 rFlag = INVALID_RETURN_LIST;
00561 }
00562 else if (!is_nil(returnList) && result == NULL) {
00563 while (!is_nil(returnList)) {
00564 element = p2p_car(returnList);
00565 c2p_nil(element);
00566 returnList = p2p_cdr(returnList);
00567 }
00568 rFlag = RESULT_EMPTY_BUT_REQUESTED;
00569 }
00570
00571 i = 0;
00572 if (result != NULL) {
00573 while (!is_nil(returnList)) {
00574 if (qHandle->numResultCols <= i) {
00575 errorMesg = "XSB_DBI ERROR: Number of requested columns exceeds the number of columns in the query";
00576 errorNumber = "XSB_DBI_011";
00577 rFlag = TOO_MANY_RETURN_COLS;
00578 return rFlag;
00579 }
00580 element = p2p_car(returnList);
00581 if (result == NULL) {
00582 c2p_nil(element);
00583 }
00584 else if (is_var(element) && result[i]->type == STRING_TYPE) {
00585 if (result[i]->val == NULL)
00586 c2p_nil(element);
00587 else {
00588 c = result[i]->val->str_val[0];
00589 if (c == TERM_CHAR) {
00590 temp = (char *)malloc(strlen(result[i]->val->str_val) * sizeof(char));
00591 for (j = 1 ; j < strlen(result[i]->val->str_val) ; j++) {
00592 temp[j-1] = result[i]->val->str_val[j];
00593 }
00594 temp[strlen(result[i]->val->str_val) - 1] = '\0';
00595 c2p_functor("term", 1, element);
00596 c2p_string(temp, p2p_arg(element, 1));
00597 }
00598 else {
00599 c2p_string(result[i]->val->str_val, element);
00600 }
00601 }
00602 }
00603 else if (is_var(element) && result[i]->type == INT_TYPE)
00604 c2p_int(*(result[i]->val->i_val), element);
00605 else if (is_var(element) && result[i]->type == FLOAT_TYPE)
00606 c2p_float(*(result[i]->val->f_val), element);
00607 returnList = p2p_cdr(returnList);
00608 i++;
00609 }
00610 rFlag = RESULT_NONEMPTY_OR_NOT_REQUESTED;
00611 }
00612
00613 if (result != NULL && qHandle->numResultCols > i) {
00614 errorMesg = "XSB_DBI ERROR: Number of requested columns is less than the number of returned columns";
00615 errorNumber = "XSB_DBI_013";
00616 rFlag = TOO_FEW_RETURN_COLS;
00617 return rFlag;
00618 }
00619
00620 return rFlag;
00621 }
00622
00623
00624 static void freeConnectionHandle(struct xsb_connectionHandle* cHandle, int pos)
00625 {
00626 int j;
00627
00628 free(cHandle->handle);
00629 free(cHandle->driver);
00630 if (cHandle->server == NULL)
00631 free(cHandle->dsn);
00632 else {
00633 free(cHandle->server);
00634 free(cHandle->database);
00635 }
00636 free(cHandle->user);
00637 free(cHandle->password);
00638 free(cHandle);
00639 for (j = pos + 1 ; j < numCHandles ; j++)
00640 CHandles[j-1] = CHandles[j];
00641 CHandles[numCHandles-1] = NULL;
00642 numCHandles--;
00643 }
00644
00645
00646 static int closeQueryHandle(char* queryHandle)
00647 {
00648 int (*closeStmtDriver)(struct xsb_queryHandle*);
00649 char* (*errorMesgDriver)();
00650 char* driverName;
00651 int i, result;
00652
00653 for (i = 0 ; i < numQHandles ; i++) {
00654 if (!strcmp(QHandles[i]->handle, queryHandle)) {
00655 driverName = QHandles[i]->connHandle->driver;
00656
00657 if (getDriverFunction(driverName, CLOSE_STMT) != NULL)
00658 closeStmtDriver = getDriverFunction(driverName, CLOSE_STMT)->closeStmtDriver;
00659 else
00660 return FALSE;
00661
00662 result = closeStmtDriver(QHandles[i]);
00663 if (result == FAILURE) {
00664 if (getDriverFunction(driverName, ERROR_MESG) != NULL)
00665 errorMesgDriver = getDriverFunction(driverName, ERROR_MESG)->errorMesgDriver;
00666 else
00667 return FALSE;
00668
00669 errorMesg = errorMesgDriver();
00670 return FALSE;
00671 }
00672 freeQueryHandle(QHandles[i], i);
00673 }
00674 }
00675
00676 return TRUE;
00677 }
00678
00679
00680 static void freeQueryHandle(struct xsb_queryHandle* qHandle, int pos)
00681 {
00682 int j;
00683
00684 free(qHandle->handle);
00685 free(qHandle->query);
00686 free(qHandle);
00687 for (j = pos + 1 ; j < numQHandles ; j++)
00688 QHandles[j-1] = QHandles[j];
00689 QHandles[numQHandles-1] = NULL;
00690 numQHandles--;
00691 }
00692
00693
00694 static struct xsb_connectionHandle* isConnectionHandle(char* handle)
00695 {
00696 int i;
00697 for (i = 0 ; i < numCHandles ; i++)
00698 if (!strcmp(CHandles[i]->handle, handle))
00699 return CHandles[i];
00700 return NULL;
00701 }
00702
00703
00704 static struct xsb_queryHandle* isQueryHandle(char* handle)
00705 {
00706 int i;
00707 for (i = 0 ; i < numQHandles ; i++)
00708 if (!strcmp(QHandles[i]->handle, handle))
00709 return QHandles[i];
00710 return NULL;
00711 }
00712
00713
00714 DllExport int call_conv registerXSBDriver(char* drivername, int num)
00715 {
00716 struct driver* dr;
00717 int i;
00718
00719 for (i = 0 ; i < numDrivers ; i++) {
00720 if (!strcmp(DBdrivers[i]->driver, drivername)) {
00721 errorMesg = "XSB_DBI ERROR: driver already registered";
00722 errorNumber = "XSB_DBI_001";
00723 return -1;
00724 }
00725 }
00726 dr = (struct driver *)malloc(sizeof(struct driver));
00727 dr->driver = drivername;
00728 dr->numberFunctions = num;
00729 dr->functions =
00730 (struct driverFunction **)malloc(num * sizeof(struct driverFunction *));
00731 for (i = 0 ; i < num ; i++)
00732 dr->functions[i] = NULL;
00733
00734 DBdrivers[numDrivers++] = dr;
00735 return 0;
00736 }
00737
00738
00739 DllExport int call_conv registerXSBFunction(char* drivername, int type, union functionPtrs* func)
00740 {
00741 int i, j;
00742
00743 for (i = 0 ; i < numDrivers ; i++) {
00744 if (!strcmp(DBdrivers[i]->driver, drivername)) {
00745 for (j = 0 ; j < DBdrivers[i]->numberFunctions ; j++) {
00746 if (DBdrivers[i]->functions[j] == NULL) {
00747 DBdrivers[i]->functions[j] =
00748 (struct driverFunction *)malloc(sizeof(struct driverFunction));
00749 DBdrivers[i]->functions[j]->functionType = type;
00750 DBdrivers[i]->functions[j]->functionName = func;
00751 break;
00752 }
00753 }
00754 }
00755 }
00756
00757 return 0;
00758 }
00759
00760
00761 static union functionPtrs* getDriverFunction(char* drivername, int type)
00762 {
00763 int i, j;
00764
00765 for (i = 0 ; i < numDrivers ; i++) {
00766 if (!strcmp(DBdrivers[i]->driver, drivername)) {
00767 for (j = 0 ; j < DBdrivers[i]->numberFunctions ; j++) {
00768 if (DBdrivers[i]->functions[j]->functionType == type) {
00769 return DBdrivers[i]->functions[j]->functionName;
00770 }
00771 }
00772 errorMesg = "XSB_DBI ERROR: Function does not exist in this driver";
00773 errorNumber = "XSB_DBI_003";
00774 return NULL;
00775 }
00776 }
00777 errorMesg = "XSB_DBI ERROR: Driver does not exist";
00778 errorNumber = "XSB_DBI_002";
00779 return NULL;
00780 }