# MySQL in Borland C++ ansteuern



## mytos-stealth (24. September 2003)

Hallo Leute,

Ich habe einen Auftrag für ein Programm gekriegt bei dem ich ein bischen Hilfe brauche, und zwar von euch!

Ich habe es mit C++ (Borland Builder 6.0) schon geschafft auf einen MySQL- Server zu connecten, aber ich kann keine Daten auslesen, verändern geschweigedenn schreiben.

wenn mir jemand helfen kann dann fände ich es wirklcih schön wenn mir dieser jemand befehle dafür posten würde oder sogar ein prog schreiben in dem ich mir dann ein paar tipps selber erarbeiten kann danke!

Nach dem Beitrag vom lieben Admin:

OS: MS Win XP
Prog: Borland C++ Builder 6.0(Enterprise)


Danke und mit freundlichen Grüßen 

Mytos-Stealth


----------



## chibisuke (24. September 2003)

hmmm.. 
1.) mit dem sourcecode von MySQL wird eine library mitgeliefert... die MySQL Client lib... damit solltest du arbeiten...
2.) MySQL_init, mysql_connect, mysql_query ......und so weiter, siehe example sources die ebenfalls mitgeliefert werden...


----------



## mytos-stealth (25. September 2003)

*danke soweit!*

jop!

danke erstmal vielmals!

wenn mir jetzt nochmal jemand ein beispiel geben kann wäre das sehr cool!

aber danke schonmal vielmals!

cya!

Mit freundlichen Güßen

Mytos-Stealth


----------



## chibisuke (25. September 2003)

nun das wohl bekannteste "beispiel" für die anwendung der lib is wohl PHP...

aber ich zeig dir jetzt einfach mal eine klasse (in ner DLL) die ich vor einiger zeit entwickelt hab,,,

das is der header:


```
#ifndef __CC_CCMYSQL_INCLUDE
#define __CC_CCMYSQL_INCLUDE
#include <windows.h>
#include <stdio.h>
#include <process.h>
#include "mysql.h"
//#define USE_GCC

#ifndef USE_GCC
#define STARTSEH() __try {
#define ENDSEH(a) } __except(1) {a}
#define ENDEXCEPT()
#else
#define STARTSEH()
#define ENDSEH(a)
#endif

///////////////////////////////////////////////////
// public abstract class CCObject
class __declspec(dllexport) CCObject {
};

////////////////////////////////////////////////////
//  public interface CCDatabase extends CCObject
//  BaseClass for Database Access for use with
//  explizit binding
class __declspec(dllexport) CCDatabase :CCObject{
	public:
		virtual bool connect(char* server, char* user, char* pass, char* db="") = 0;
		virtual void disconnect() = 0;
		virtual void SelectDB(char* db) = 0;
		virtual bool query(char* query) = 0;
		virtual void* GetEntry(char* name) = 0;
		virtual void* GetEntry(int nr) = 0;
		virtual bool NextRow() = 0;
		virtual bool PrevRow() = 0;

		bool connected;
};

////////////////////////////////////////////////////////
// public class CCMySQL implements CCDatabase
// MySQL Class
class __declspec(dllexport) CCMySQL :public CCDatabase{
	public:
		CCMySQL();
		CCMySQL(char* server, char* user, char* pass, char* db="");
		~CCMySQL();
		bool connect(char* server, char* user, char* pass, char* db="");
		void disconnect();
		void SelectDB(char* db);
		bool query(char* query);
		void* GetEntry(char* name);
		void* GetEntry(int nr);
		bool NextRow();
		bool PrevRow();

	protected:
		MYSQL* connection;
		MYSQL_RES* result;
		MYSQL_ROW mysql_row;
		MYSQL_FIELD *mysql_field;
		char**** data;
		int entry;
		int* datasize;
};

extern "C" CCDatabase __declspec(dllexport) *createDatabaseConnection(char* server, char* user, char* pass, char* db="");
extern "C" void __declspec(dllexport) freeDatabaseConnection(CCDatabase* connection);
extern "C" void __declspec(dllexport) DBEscapeString(char*, char*, size_t);
#endif
```

und der code dafür sieht so aus:


```
#include "CCMySQL.h"
#define __DEBUG 1
#define BREAKALLOC NULL
#if __DEBUG == 1
#include <crtdbg.h> 

int __cdecl MyAllocHook(
   int      nAllocType,
   void   * pvData,
   size_t   nSize,
   int      nBlockUse,
   long     lRequest,
   const unsigned char * szFileName,
   int      nLine
   )
{
   char *operation[] = { "", "allocating", "re-allocating", "freeing" };
   char *blockType[] = { "Free", "Normal", "CRT", "Ignore", "Client" };

   if ( nBlockUse == _CRT_BLOCK )  { // Ignore internal C runtime library allocations
      return( TRUE );
   }

   _ASSERT( ( nAllocType > 0 ) && ( nAllocType < 4 ) );
   _ASSERT( ( nBlockUse >= 0 ) && ( nBlockUse < 5 ) );
#if printMemAllocReport == 1
   _CrtDbgReport(0,0,0,0,"Memory operation in %s, line %d: %s a %d-byte '%s' block (# %ld)",
            szFileName, nLine, operation[nAllocType], nSize, 
            blockType[nBlockUse], lRequest );
   if ( pvData != NULL )
      _CrtDbgReport(0,0,0,0," at %X", pvData );
	 _CrtDbgReport(0,0,0,0,"\n");
#endif
	if(BREAKALLOC) __asm int 3
	 return( TRUE );         // Allow the memory operation to proceed
}


BOOL APIENTRY DllMain(HANDLE hModule, 
                      DWORD  ul_reason_for_call, 
                      LPVOID lpReserved)
{
    switch( ul_reason_for_call ) {
    case DLL_PROCESS_ATTACH:
		_CrtSetAllocHook( MyAllocHook );
		break;
    case DLL_PROCESS_DETACH:
		_CrtDumpMemoryLeaks();
    }
    return TRUE;
}

#endif





///////////////////////////
// Ctor
CCMySQL::CCMySQL() {
	this->connected = false;
	this->entry = 0;
	this->result = NULL;
	this->connection = ::mysql_init(NULL);
	this->data = new char***[1];
	this->data[0] = NULL;
	this->datasize = new int[1];
	this->datasize[0] = 1;
	
}

///////////////////////////
// Dtor

CCMySQL::~CCMySQL() {
	this->entry = 0;
	if(this->result != NULL) {
		::mysql_free_result(this->result);
	}
	if(this->data[0] != NULL) {
		int i = 0, j = 0;
		for(j = 0; this->data[j] != NULL; j++) {
			for(i = 0; this->data[j][i] != NULL; i++) {
				delete this->data[j][i][0];
				delete this->data[j][i][1];
				delete this->data[j][i];
			}
			delete this->data[j];
		}
	}
	
	delete this->data;
	delete this->datasize;
	this->data = NULL;
	this->disconnect();
	mysql_shutdown(this->connection);
}

///////////////////////////
// Ctor & connect
CCMySQL::CCMySQL(char* server, char* user, char* pass, char* db) {
	this->connected = false;
	this->result = NULL;
	this->data = new char***[1];
	this->data[0] = NULL;
	this->datasize = new int[1];
	this->datasize[0] = 1;
	this->connection = ::mysql_init(NULL);
	this->connect(server, user, pass, db);
}

////////////////////////////
// connect
bool CCMySQL::connect(char* server, char* user, char* pass, char* db) {
	void* res = mysql_connect(this->connection, server, user, pass);
	if(::strcmp(db, "") != 0) {
		this->SelectDB(db);
	}
	if(res == NULL) {
		this->connected = false;
		return false; 
	}
	else {
		this->connected = true;
		return true;
	}
}

/////////////////////////////
//  disconnect
void CCMySQL::disconnect() {
STARTSEH()
		this->connected = false;
		::mysql_close(this->connection);
ENDSEH((void)0;)
}

/////////////////////////////
// Select Database
void CCMySQL::SelectDB(char* db) {
	if(::mysql_select_db(this->connection, db) == 0) {
		::printf("%s", ::mysql_error(this->connection));
	}
}

/////////////////////////////
// Send Query
bool CCMySQL::query(char* query) {
	int i = 0;
	if(this->result != NULL) {
		::mysql_free_result(this->result);
		this->result = NULL;
	}
	if(::mysql_query(this->connection, query) == 0) {
	}
	if(::mysql_error(this->connection)[0] != '\0') {
		return false;
	}
	this->result = ::mysql_store_result(this->connection);
	if(this->data[0] != NULL) {
		int i = 0, j = 0;
		for(j = 0; this->data[j] != NULL; j++) {
			for(i = 0; this->data[j][i] != NULL; i++) {
				delete this->data[j][i][0];
				delete this->data[j][i][1];
				delete this->data[j][i];
			}
			delete this->data[j];
		}
		::realloc(this->datasize, sizeof(int));
		this->datasize[0] = 1;
		this->data = (char****)::realloc(this->data, this->datasize[0] * sizeof(char***));
		this->data[0] = NULL;
	}
	if(this->result == NULL) {
		return true;
	}
	for(int j = 0;(this->mysql_row=::mysql_fetch_row(this->result))!=NULL; j++) {	
		this->datasize[0]++;
		this->data = (char****)::realloc(this->data, this->datasize[0] * sizeof(char***));
		this->datasize = (int*)::realloc(this->datasize, (this->datasize[0]+1) * sizeof(int));
		this->data[j] = new char**[1];
		this->datasize[j+1] = 1;
		this->data[j+1] = NULL;
		::mysql_field_seek(this->result, 0);
		for (this->mysql_field=::mysql_fetch_field(result), i=0; this->mysql_field; this->mysql_field=::mysql_fetch_field(this->result), i++) {
			if(this->mysql_row[i]) {
				this->datasize[j+1]++;
				this->data[j] = (char***)::realloc(this->data[j], this->datasize[j+1] * sizeof(char**));
				this->data[j][i] = new char*[2];
				this->data[j][i][0] = new char[::strlen(this->mysql_field->name)+1];
				this->data[j][i][1] = new char[::strlen(this->mysql_row[i])+1];
				this->data[j][i+1] = NULL;
				::strcpy(this->data[j][i][1], this->mysql_row[i]);
				::strcpy(this->data[j][i][0], this->mysql_field->name);
			}
		}

	}
	this->entry = 0;
	if(this->result != NULL) {
		::mysql_free_result(this->result);
		this->result = NULL;
	}
	return true;
}

///////////////////////////
// Load next DataRow
bool CCMySQL::NextRow() {
	if(this->data[this->entry] == NULL) {
		return false;
	}
	if(this->data[this->entry+1] != NULL) {
		this->entry++;
		return true;
	}
	return false;
}

////////////////////////////
// Load Previous DataRow
bool CCMySQL::PrevRow() {
	if(this->entry > 0) {
		this->entry--;
		return true;
	}
	return false;
}

///////////////////////////////////
// GetDataEntry as char[] using ID
void* CCMySQL::GetEntry(int nr) {
	if(this->data[this->entry] != NULL) {
		return this->data[this->entry][nr][1];
	}
	else return false;
}

///////////////////////////////////////
// Get DataEntry as char[] using Name

void* CCMySQL::GetEntry(char* name) {
	if(this->data[this->entry] == NULL) {
		return false;
	}
	for(int i = 0; this->data[this->entry][i] != NULL; i++) {
		if(::_stricmp(this->data[this->entry][i][0], name) == 0) {
			return this->data[this->entry][i][1];
		}
	}
	return false;
}

//////////////////////////////////////////
// DLL Functions for explizit DLL Binding

CCDatabase* createDatabaseConnection(char* server, char* user, char* pass, char* db) {
	return (CCDatabase*) new CCMySQL(server, user, pass, db);
}
void freeDatabaseConnection(CCDatabase* connection) {
	CCMySQL* con = (CCMySQL*)(void*)connection;
	delete con;
}

void DBEscapeString(char* out, char* in, size_t len) {
	::mysql_escape_string(out, in, len);
}
```

ich hoffe das zeigt dir wie man mit der lib umgeht, wenn du willst kannst du die klasse auch benutzen wird so und so zusammen mit meinem projekt veröffendlicht werden, diese klasse sogar als GPL..


----------



## Sinac (26. September 2003)

Also wenn du "Aufträge" für Programme annimmst solltest eigentlich vorher sehn ob dus hinbekommst oda nicht...
Außerdem ist beim BCB ein Beispiel UND ein Tutorial bei, zieh dir den ODBC Treiber für MySQL und dann ist das einfah nurnoch dem Tutorial folgen!

Greetz...
Sinac


----------



## chibisuke (26. September 2003)

vergiss ODBC bei MySQL.. das funktioniert nur wenn der MySQL server auf windows leuft und selbst dann nur wenn der MySQL server es zulässt (muss man einrichten)...


----------



## mytos-stealth (27. September 2003)

*sicher*

ich bin mir nicht ganz sicher ob der source code da oben wirklich c++ builder 6 ist!

wenn ja bitte nur einmal ein ja reinschreiben!

danke!


----------



## chibisuke (27. September 2003)

nein dabei handelt es sich um ne DLL die is in visual C++ geschrieben, aber sollte trotzdem mit minimalen anpassungen auch auf borland laufen... wenn nein, dann meldest dich bei mir, dann gib ich dir die kompilierte DLL und die header die du brauchst zum einbinden ;-)
icq:135118529

vergiss nicht das du die MySQL Clientlib in das projekt einfügen musst und die mitkompilieren... die mysql.h und alle anderen clientlib dateien müssen natürlich im selben verzeichnis wie die dateien hier sein, sonst findet er logischerweise die notwendigen include dateien nicht (dabei mitt unbedingt auf TLS umschalten wenn dus als DLL kompilieren willst, stürzt sonst ab)


----------



## xylon50 (28. März 2006)

*ähnliche Probleme*

Hallo,

ich versuche auch mit dem Borland Builder 6 eine Verbindung zu einer MySQL-Datenbank herzustellen. Ich habe mal den guten Rat befolgt und habe mir die Treiber runtergeladen und installiert und habe dann das Tutorial abgelaufen. Natürlich wird da von einer anderen Datenbank gesprochen, aber nach der Treiberinstallation stand mir dieser auch zur Wahl. Alles sah soweit gut aus, allerdings bekomme ich nun immer die Fehlermeldung:

Unable to load libmysql.dll

Ich habe die Datei also in alle Pfade kopiert die mir einigermaßen sinnvoll erschienen. Das hat aber leider auch nicht geholfen.  

Ach ja, ich habe MySQL in der XAMPP-Version drauf, da ich mit php arbeite... sollte aber doch nichts ausmachen, oder?

Vielen Dank im Voraus,
xylon50


----------

