#include "main.h" #include #include // we're not really using this class just yet, but maybe some day class TLocalErrorDataObject { public: bool eof; bool error; long errorcode; std::string errorstring; long affected; }; // simple function to free/malloc a var's value void setMyVarString( mydll_myvar *pVar, char *s, long iForceLen = -1 ) { long iStrLen = 0; if ( iForceLen != -1 ) { iStrLen = iForceLen; } else { iStrLen = strlen(s); } if ( pVar->sValue != NULL ) { pVar->iStrlen = 0; free( pVar->sValue ); pVar->sValue = NULL; } pVar->sValue = static_cast( malloc( iStrLen + 4 ) ); memcpy( pVar->sValue, s, iStrLen ); pVar->sValue[iStrLen] = 0; pVar->sValue[iStrLen+1] = 0; pVar->sValue[iStrLen+2] = 0; pVar->sValue[iStrLen+3] = 0; pVar->iStrlen = iStrLen; } // simple function to free/malloc a field's name void setMyFieldString( mydll_myfield *pField, std::string s ) { long iStrLen = s.length(); if ( pField->sName != NULL ) { pField->iStrlen = 0; free( pField->sName ); pField->sName = NULL; } pField->sName = static_cast( malloc( iStrLen + 4 ) ); memcpy( pField->sName, s.c_str(), iStrLen ); pField->sName[iStrLen] = 0; pField->sName[iStrLen+1] = 0; pField->sName[iStrLen+2] = 0; pField->sName[iStrLen+3] = 0; pField->iStrlen = iStrLen; } // -------------------------------------------------------- class TLocalMySQLObject { protected: MYSQL aMysqlObj; MYSQL *pMysqlObj; bool bConnected; bool bCompression; bool bAnsiMode; MYSQL_RES *pCurrentResult; MYSQL_ROW aCurrentRow; std::string sCurrentQuery; unsigned int iCurrentRecord; unsigned int iRecordCount; public: std::string sHost; int iPort; std::string sUsername; std::string sPassword; TLocalMySQLObject() { pMysqlObj = &aMysqlObj; bConnected = false; bCompression = true; pCurrentResult = NULL; iCurrentRecord = 0; iRecordCount = 0; bAnsiMode = false; sCurrentQuery = ""; sHost = "localhost"; iPort = 3306; sUsername = "root"; sPassword = ""; } ~TLocalMySQLObject() { disconnect(); } bool connect() { mysql_init( pMysqlObj ); mysql_options( pMysqlObj, MYSQL_READ_DEFAULT_GROUP, "TLocalMySQLObject" ); unsigned long iFlags = 0; if ( bCompression ) { iFlags |= CLIENT_COMPRESS; } mysql_options( pMysqlObj, MYSQL_SET_CHARSET_NAME, "utf8" ); if ( !mysql_real_connect( pMysqlObj, sHost.c_str(), sUsername.c_str(), sPassword.c_str(), NULL, iPort, NULL, iFlags ) ) { } else { bConnected = true; } return bConnected; } void disconnect() { if ( bConnected ) { mysql_close( pMysqlObj ); } } bool selectDatabase( std::string sDatabase ) { if ( bConnected ) { mysql_select_db( pMysqlObj, sDatabase.c_str() ); if ( mysql_errno( pMysqlObj ) > 0 ) { return false; } return true; } return false; } void setQuery( std::string sQuery ) { this->sCurrentQuery = sQuery; } long long getLastID() { return mysql_insert_id( pMysqlObj ); } bool open( TLocalErrorDataObject *errData ) { if ( bConnected ) { int iError = mysql_real_query( pMysqlObj, sCurrentQuery.c_str(), sCurrentQuery.length() ); if ( iError == 0 ) { pCurrentResult = mysql_store_result( pMysqlObj ); iRecordCount = 0 ; if ( pCurrentResult != NULL ) { iRecordCount = mysql_num_rows( pCurrentResult ); } if ( errData != NULL ) { errData->eof = false; errData->error = false; errData->errorcode = 0; errData->errorstring = ""; errData->affected = mysql_affected_rows( pMysqlObj ); } return true; } else { if ( errData != NULL ) { errData->eof = false; errData->error = true; errData->errorcode = mysql_errno( pMysqlObj ); errData->errorstring = mysql_error( pMysqlObj ); errData->affected = 0; } } } else { } return false; } bool close() { if ( pCurrentResult != NULL ) { mysql_free_result( pCurrentResult ); pCurrentResult = NULL; return true; } return false; } bool isConnected() { return bConnected; } bool isOpen() { return ( pCurrentResult != NULL ); } bool isFirst() { return (iCurrentRecord == 1); } bool isLast() { return (iCurrentRecord == iRecordCount); } bool next() { if ( isOpen() ) { iCurrentRecord++; aCurrentRow = mysql_fetch_row( pCurrentResult ); return ( aCurrentRow != NULL ); } return false; } long getFieldCount() { return mysql_num_fields( pCurrentResult ); } long getRecordCount() { return iRecordCount; } bool retreiveFieldByIndex( long i, mydll_myfield *field ) { MYSQL_FIELD *f; f = mysql_fetch_field_direct( pCurrentResult, i ); setMyFieldString( field, f->name ); field->iMaxlen = f->length; switch ( f->type ) { case MYSQL_TYPE_TINY: case MYSQL_TYPE_SHORT: case MYSQL_TYPE_LONG: case MYSQL_TYPE_INT24: case MYSQL_TYPE_LONGLONG: case MYSQL_TYPE_BIT: field->iDatatype = FLDTYPE_INT; break; case MYSQL_TYPE_DECIMAL: case MYSQL_TYPE_NEWDECIMAL: case MYSQL_TYPE_FLOAT: case MYSQL_TYPE_DOUBLE: field->iDatatype = FLDTYPE_DOUBLE; break; case MYSQL_TYPE_DATE: case MYSQL_TYPE_TIME: case MYSQL_TYPE_DATETIME: field->iDatatype = FLDTYPE_DATE; break; case MYSQL_TYPE_TIMESTAMP: field->iDatatype = FLDTYPE_DATE; break; default: field->iDatatype = FLDTYPE_STRING; } if ( f->flags & PRI_KEY_FLAG > 0 ) { field->iFlags = FLDFLAG_PRIMARY; } else { field->iFlags = FLDFLAG_NORMAL; } return true; } bool retreiveValueByIndex( long i, long iDatatype, mydll_myvar *pVar ) { unsigned long *lengths = mysql_fetch_lengths( pCurrentResult ); switch ( iDatatype ) { case FLDTYPE_STRING: case FLDTYPE_UNKNOWN: setMyVarString( pVar, aCurrentRow[i], lengths[i] ); pVar->iValue = 0; pVar->dValue = 0; break; case FLDTYPE_INT: setMyVarString( pVar, aCurrentRow[i], lengths[i] ); pVar->iValue = atoi( aCurrentRow[i] ); pVar->dValue = pVar->iValue; break; case FLDTYPE_DOUBLE: setMyVarString( pVar, aCurrentRow[i], lengths[i] ); pVar->dValue = atof( aCurrentRow[i] ); pVar->iValue = static_cast( pVar->dValue ); break; case FLDTYPE_DATE: setMyVarString( pVar, aCurrentRow[i], lengths[i] ); pVar->iValue = 0; pVar->dValue = 0; break; } return true; } }; // ---------------------------------------------------- // the DllMain that gets called everytime the DLL is loaded/freed/etc BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { switch (fdwReason) { case DLL_PROCESS_ATTACH: // attach to process // nice opportunity to initialize our mysql.dll connection if ( mysql_library_init( 0, 0, 0 ) ) { return false; } break; case DLL_PROCESS_DETACH: // detach from process // you'll probably never see this being triggered, but it doesn't really matter mysql_library_end(); break; case DLL_THREAD_ATTACH: // attach to thread break; case DLL_THREAD_DETACH: // detach from thread break; } return TRUE; // succesful } // ---------------------------------------------------- long DLL_EXPORT mydll_createNewConnection() { TLocalMySQLObject *obj = new TLocalMySQLObject(); return reinterpret_cast( obj ); } void DLL_EXPORT mydll_setOptions( long iConn, char *sHost, long iPort, char *sUser, char *sPass ) { TLocalMySQLObject *obj = reinterpret_cast( iConn ); obj->sHost = sHost; obj->iPort = iPort; obj->sUsername = sUser; obj->sPassword = sPass; } bool DLL_EXPORT mydll_connect( long iConn ) { TLocalMySQLObject *obj = reinterpret_cast( iConn ); return obj->connect(); } void DLL_EXPORT mydll_disconnect( long iConn ) { TLocalMySQLObject *obj = reinterpret_cast( iConn ); return obj->disconnect(); } bool DLL_EXPORT mydll_selectDatabase( long iConn, char *sDBName ) { TLocalMySQLObject *obj = reinterpret_cast( iConn ); return obj->selectDatabase( sDBName ); } bool DLL_EXPORT mydll_openQuery( long iConn, char *sQuery ) { TLocalMySQLObject *obj = reinterpret_cast( iConn ); obj->setQuery( sQuery ); TLocalErrorDataObject err; if ( obj->open( &err ) ) { return true; } return false; } void DLL_EXPORT mydll_close( long iConn ) { TLocalMySQLObject *obj = reinterpret_cast( iConn ); obj->close(); } bool DLL_EXPORT mydll_isLast( long iConn ) { TLocalMySQLObject *obj = reinterpret_cast( iConn ); return obj->isLast(); } bool DLL_EXPORT mydll_next( long iConn ) { TLocalMySQLObject *obj = reinterpret_cast( iConn ); return obj->next(); } long DLL_EXPORT mydll_getFieldCount( long iConn ) { TLocalMySQLObject *obj = reinterpret_cast( iConn ); return obj->getFieldCount(); } long DLL_EXPORT mydll_getRecordCount( long iConn ) { TLocalMySQLObject *obj = reinterpret_cast( iConn ); return obj->getRecordCount(); } bool DLL_EXPORT mydll_fetchValue( long iConn, long iIndex, long iDatatype, mydll_myvar *pVar ) { TLocalMySQLObject *obj = reinterpret_cast( iConn ); return obj->retreiveValueByIndex( iIndex, iDatatype, pVar ); } bool DLL_EXPORT mydll_fetchField( long iConn, long iIndex, mydll_myfield *pField ) { TLocalMySQLObject *obj = reinterpret_cast( iConn ); return obj->retreiveFieldByIndex( iIndex, pField ); } void DLL_EXPORT mydll_closeConnection( long iConn ) { TLocalMySQLObject *obj = reinterpret_cast( iConn ); delete obj; }