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 #ifdef WIN_NT
00029 #include <windows.h>
00030 #endif
00031
00032 #ifdef WIN_NT
00033 #define XSB_DLL
00034 #endif
00035
00036 #include "mysql_driver_defs.h"
00037
00038 static void driverMySQL_error(MYSQL* mysql);
00039 static int driverMySQL_getXSBType(MYSQL_FIELD* field);
00040 static struct xsb_data** driverMySQL_getNextRow(struct driverMySQL_queryInfo* query);
00041
00042 struct driverMySQL_connectionInfo* mysqlHandles[MAX_HANDLES];
00043 struct driverMySQL_queryInfo* mysqlQueries[MAX_QUERIES];
00044 int numHandles, numQueries;
00045 const char* errorMesg;
00046
00047
00048
00049
00050 DllExport int call_conv driverMySQL_initialise()
00051 {
00052 numHandles = 0;
00053 numQueries = 0;
00054 errorMesg = NULL;
00055
00056 return TRUE;
00057 }
00058
00059
00060 DllExport int call_conv driverMySQL_connect(struct xsb_connectionHandle* handle)
00061 {
00062 struct driverMySQL_connectionInfo* mysqlHandle;
00063 MYSQL* mysql;
00064
00065 mysql = (MYSQL *)malloc(sizeof(MYSQL));
00066 if (!mysql_init(mysql))
00067 {
00068 driverMySQL_error(mysql);
00069 free(mysql);
00070 return FAILURE;
00071 }
00072
00073 if (!mysql_real_connect(mysql, handle->server, handle->user, handle->password, handle->database, 0, NULL, 0))
00074 {
00075 driverMySQL_error(mysql);
00076 free(mysql);
00077 return FAILURE;
00078 }
00079
00080 mysqlHandle = (struct driverMySQL_connectionInfo *)malloc(sizeof(struct driverMySQL_connectionInfo));
00081 mysqlHandle->handle = (char *)malloc((strlen(handle->handle) + 1) * sizeof(char));
00082 strcpy(mysqlHandle->handle, handle->handle);
00083 mysqlHandle->mysql = mysql;
00084 mysqlHandles[numHandles++] = mysqlHandle;
00085
00086 return SUCCESS;
00087 }
00088
00089
00090 DllExport int call_conv driverMySQL_disconnect(struct xsb_connectionHandle* handle)
00091 {
00092 int i, j;
00093
00094 for (i = 0 ; i < numHandles ; i++)
00095 {
00096 if (!strcmp(handle->handle, mysqlHandles[i]->handle))
00097 {
00098 mysql_close(mysqlHandles[i]->mysql);
00099 free(mysqlHandles[i]->mysql);
00100 for (j = i + 1 ; j < numHandles ; j++)
00101 mysqlHandles[j-1] = mysqlHandles[j];
00102 numHandles--;
00103 break;
00104 }
00105 }
00106
00107 return SUCCESS;
00108 }
00109
00110
00111 DllExport struct xsb_data** call_conv driverMySQL_query(struct xsb_queryHandle* handle)
00112 {
00113 struct driverMySQL_connectionInfo* connection;
00114 struct driverMySQL_queryInfo* query;
00115 MYSQL_RES* resultSet;
00116 int i;
00117
00118 query = NULL;
00119 connection = NULL;
00120 if (handle->state == QUERY_RETRIEVE)
00121 {
00122 for (i = 0 ; i < numQueries ; i++)
00123 {
00124 if (!strcmp(mysqlQueries[i]->handle, handle->handle))
00125 {
00126 query = mysqlQueries[i];
00127 break;
00128 }
00129 }
00130 }
00131 else if (handle->state == QUERY_BEGIN)
00132 {
00133 for (i = 0 ; i < numHandles ; i++)
00134 {
00135 if (!strcmp(mysqlHandles[i]->handle, handle->connHandle->handle))
00136 {
00137 connection = mysqlHandles[i];
00138 break;
00139 }
00140 }
00141 query = (struct driverMySQL_queryInfo *)malloc(sizeof(struct driverMySQL_queryInfo));
00142 query->handle = (char *)malloc((strlen(handle->handle) + 1) * sizeof(char));
00143 strcpy(query->handle, handle->handle);
00144 query->query = (char *)malloc((strlen(handle->query) + 1) * sizeof(char));
00145 strcpy(query->query, handle->query);
00146 query->connection = connection;
00147
00148 if (mysql_query(query->connection->mysql, query->query))
00149 {
00150 driverMySQL_error(query->connection->mysql);
00151 return NULL;
00152 }
00153 else
00154 {
00155 if ((resultSet = mysql_use_result(query->connection->mysql)) == NULL)
00156 {
00157 driverMySQL_error(query->connection->mysql);
00158 return NULL;
00159 }
00160 query->resultSet = resultSet;
00161 mysqlQueries[numQueries++] = query;
00162 handle->state = QUERY_RETRIEVE;
00163 handle->numResultCols = mysql_num_fields(resultSet);
00164 }
00165 }
00166
00167 return driverMySQL_getNextRow(query);
00168 }
00169
00170
00171 static struct xsb_data** driverMySQL_getNextRow(struct driverMySQL_queryInfo* query)
00172 {
00173 struct xsb_data** result;
00174 MYSQL_ROW row;
00175 int numFields;
00176 int i, j;
00177
00178 result = NULL;
00179 if ((row = mysql_fetch_row(query->resultSet)) == NULL)
00180 {
00181 if (mysql_errno(query->connection->mysql))
00182 driverMySQL_error(query->connection->mysql);
00183 else
00184 {
00185 for (i = 0 ; i < numQueries ; i++)
00186 {
00187 if (!strcmp(mysqlQueries[i]->handle, query->handle))
00188 {
00189 mysql_free_result(query->resultSet);
00190 free(query->query);
00191 free(query->handle);
00192 free(query);
00193 for (j = i + 1 ; j < numQueries ; j++)
00194 mysqlQueries[j-1] = mysqlQueries[j];
00195 numQueries--;
00196 }
00197 }
00198 }
00199 return NULL;
00200 }
00201
00202 numFields = mysql_num_fields(query->resultSet);
00203 result = (struct xsb_data **)malloc(numFields * sizeof(struct xsb_data *));
00204 for (i = 0 ; i < numFields ; i++)
00205 {
00206 result[i] = (struct xsb_data *)malloc(sizeof(struct xsb_data));
00207 result[i]->val = (union xsb_value *)malloc(sizeof(union xsb_value));
00208 result[i]->type = driverMySQL_getXSBType(mysql_fetch_field_direct(query->resultSet, i));
00209 switch (result[i]->type)
00210 {
00211 case INT_TYPE:
00212 result[i]->val->i_val = (int *)malloc(sizeof(int));
00213 result[i]->val->i_val = (int *)row[i];
00214 break;
00215
00216 case FLOAT_TYPE:
00217 result[i]->val->f_val = (double *)malloc(sizeof(double));
00218 result[i]->val->f_val = (double *)row[i];
00219 break;
00220
00221 case STRING_TYPE:
00222 result[i]->val->str_val = (char *)malloc(strlen(row[i]) * sizeof(char));
00223 strcpy(result[i]->val->str_val, (char *)row[i]);
00224 break;
00225 }
00226 }
00227
00228 return result;
00229 }
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361 DllExport char* call_conv driverMySQL_errorMesg()
00362 {
00363 char* temp;
00364 if (errorMesg != NULL)
00365 {
00366 temp = (char *)malloc((strlen(errorMesg) + 1) * sizeof(char));
00367 strcpy(temp, errorMesg);
00368 errorMesg = NULL;
00369 }
00370 return NULL;
00371 }
00372
00373
00374 static void driverMySQL_error(MYSQL* mysql)
00375 {
00376 errorMesg = mysql_error(mysql);
00377 }
00378
00379
00380 static int driverMySQL_getXSBType(MYSQL_FIELD* field)
00381 {
00382 int type;
00383
00384 type = 0;
00385 switch (field->type)
00386 {
00387 case FIELD_TYPE_TINY:
00388 case FIELD_TYPE_SHORT:
00389 case FIELD_TYPE_LONG:
00390 case FIELD_TYPE_INT24:
00391 case FIELD_TYPE_LONGLONG:
00392 type = INT_TYPE;
00393 break;
00394
00395 case FIELD_TYPE_DECIMAL:
00396 case FIELD_TYPE_FLOAT:
00397 case FIELD_TYPE_DOUBLE:
00398 type = FLOAT_TYPE;
00399 break;
00400
00401 case FIELD_TYPE_STRING:
00402 case FIELD_TYPE_DATE:
00403 case FIELD_TYPE_TIMESTAMP:
00404 case FIELD_TYPE_TIME:
00405 case FIELD_TYPE_DATETIME:
00406 case FIELD_TYPE_YEAR:
00407 case FIELD_TYPE_NEWDATE:
00408 case FIELD_TYPE_ENUM:
00409 case FIELD_TYPE_SET:
00410 case FIELD_TYPE_TINY_BLOB:
00411 case FIELD_TYPE_MEDIUM_BLOB:
00412 case FIELD_TYPE_LONG_BLOB:
00413 case FIELD_TYPE_BLOB:
00414 case FIELD_TYPE_VAR_STRING:
00415 case FIELD_TYPE_NULL:
00416 default:
00417 type = STRING_TYPE;
00418 break;
00419 }
00420
00421 return type;
00422 }
00423
00424
00425 DllExport int call_conv driverMySQL_register(void)
00426 {
00427 union functionPtrs* funcConnect;
00428 union functionPtrs* funcDisconnect;
00429 union functionPtrs* funcQuery;
00430 union functionPtrs* funcErrorMesg;
00431
00432
00433
00434 registerXSBDriver("mysql", 4);
00435
00436 funcConnect = (union functionPtrs *)malloc(sizeof(union functionPtrs));
00437 funcConnect->connectDriver = driverMySQL_connect;
00438 registerXSBFunction("mysql", CONNECT, funcConnect);
00439
00440 funcDisconnect = (union functionPtrs *)malloc(sizeof(union functionPtrs));
00441 funcDisconnect->disconnectDriver = driverMySQL_disconnect;
00442 registerXSBFunction("mysql", DISCONNECT, funcDisconnect);
00443
00444 funcQuery = (union functionPtrs *)malloc(sizeof(union functionPtrs));
00445 funcQuery->queryDriver = driverMySQL_query;
00446 registerXSBFunction("mysql", QUERY, funcQuery);
00447
00448 funcErrorMesg = (union functionPtrs *)malloc(sizeof(union functionPtrs));
00449 funcErrorMesg->errorMesgDriver = driverMySQL_errorMesg;
00450 registerXSBFunction("mysql", ERROR_MESG, funcErrorMesg);
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460 return TRUE;
00461 }
00462