Adding MySQL++

This tutorial follows from an original by Dome113.
== Installing the MySQL Community Server ==
Before we can do anything else, we need to download and install a 32 Bit version of the MySQL Community Server. 
http://www.mysql.de/downloads/mysql/
Choose "Complete" and setup your MySQL Server as you like it. 
Don't download a 64 Bit version. If you install a 64 Bit version, you won't be able to compile MySQL++! 
== Download and compile MySQL++ ==
We need to download MySQL++. The following link will lead you directly to the current version(3.2.1@2013.12.10).
http://tangentsoft.net/mysql++/
Untar the downloaded archive to your favorite location. I've unpacked it to "C:\Coding\Resources\mysql++-3.2.1". 
Once you've successfully unpacked MySQL++, open the directory "mysql++-3.2.1". 
As you can see there are different VC folders. 
Just open the directory that matches with your VC version. There isn't a version for VC2010 but that's ok. Just use the VC2008 directory.
Open the VC Project file that's located in these directories. There are a lot of examples but just leave them for now. Due to MySQL++ is setup for an earlier version of the MySQL Server, we need to adapt the project properties. Change from Debug to Release and open the project properties of the mysqlpp project.
Open "C/C++" and change to "General" and remove everything that's within the "Additional Include Directories". 
Now add the MySQL Servers include directory to them. 
My path: "C:\Program Files (x86)\MySQL\MySQL Server 5.5\include"
Now open "Linker" and change to "General". Remove everything that's within the "Additional Libary Directories" and add the MySQL Servers lib directory to it. 
My path: "C:\Program Files (x86)\MySQL\MySQL Server 5.5\lib"
Good! We're ready to compile MySQL++. Just compile the mysqlpp project. Once that is done we need to copy some .dll files to the bin directory of our mod. "mysqlpp.dll and libmysql.dll". Location: "mysql++-3.2.1\vc2008\Release" and "C:\Program Files (x86)\MySQL\MySQL Server 5.5\lib".
Now we're ready for the next step.
== Adding MySQL++ to the Source Engine ==
We're ready to add MySQL++ to the Source Engine. First of all this tutorial is made for a "Release" build. 
Open the server project properties. Go to "C/C++ - General" and add the following 2 lines to "Additional Include Directories": "fullpathto\mysql++-3.2.1\lib" and "fullpathto\MySQL Server 5.5\include". Of course you need to modify them.
After you're done, go to "Linker - General" and add the "fullpathto\mysql++-3.2.1\vc2008\Release" to the "Additional Library Directories".
The last thing you need to do in this step is adding "mysqlpp.lib" to the "Additional Dependencies" in "Linker - Input".
If you get linking errors for some functions (e.g. LNK2001: _mysql_free_result@4), you may also need to add "fullpathto\MySQL Server 5.5\lib" to "Additional Library Directories" and "libmysql.lib" to "Additional Dependencies".
Make sure to add these dependencies to the appropriate VPC files.
== Issues and Tips for MySQL++ ==
=== Issues: ===
You have to make your own class for MySQL++. If you try to add MySQL++ directly into large files as example "sdk_player.cpp", you'll get errors... These errors are quite confusing and really unnecessary because creating a own class for MySQL++ is always a good thing. In the next step you'll find an example class with an example function.
=== Tips: ===
Never build up a constant connection to your MySQL Server. It wastes a huge amount of resources and can cause major lags. For me, I'm establishing a connection at the start of an event. "As example: the player connects and I need some information about him from my database" Once I've got the information I need, I'll disconnect from my MySQL Server. For example if you're building up a level system with experience, don't try to update the players stats every time if something changes. Just update it after for example 5 Minutes or if he tries do disconnect. This saves a huge amount of resources.
== Creating a class and using MySQL++ ==
Here's a small example class for MySQL++ with an example function that inserts data into a MySQL database. It connects to a MySQL Server and looks if the Player is stored in a table called "playerinfo". It returns the players level. If the level is -1, the query didn't find something.
==== sqlconnector.h ====
#ifndef SQLCONNECTOR_H
#define SQLCONNECTOR_H
#define DBHOST "localhost"
#define DBUSER "username"
#define DBPASSWORD "somepassword"
#define	DB "databasename"
#define DBPORT 3306 //Standard port
#include "cbase.h"
class DBConnector {
public:
 DBConnector();
 int GetLevel(const char *SteamID);
};
#endif
==== sqlconnector.cpp ====
#include "cbase.h"
#include "mysql++.h"
#include "sqlconnector.h"
DBConnector::DBConnector()
{
}
int DBConnector::GetLevel(const char *SteamID)
{
 mysqlpp::Connection dbconn(false);
 if(dbconn.connect(DB,DBHOST,DBUSER,DBPASSWORD,DBPORT)) //establish a connection.
 {
		
 char buffer[120];
 Q_snprintf(buffer,120,"SELECT * FROM playerinfo WHERE steamid='%s'",SteamID); //A simple MySQL query. Q_snprintf converts our SteamID into our query.
 mysqlpp::Query query = dbconn.query(buffer); // Determine our query as "query"
 if (mysqlpp::StoreQueryResult res = query.store()) // Stores our query.
 {
 return atoi(res[0][0].c_str()); // Converts the C String output to a int.
 } else {
 Error(query.error()); // Returns a query error.
 }
		
 } else {
 Error(dbconn.error()); // Returns a connection error.
 }
 return -1; // If the query didn't work.
}
==== sdk_player.cpp ====
#include "sqlconnector.h"
...
CSDKPlayer::InitialSpawn()
{
 ...
 DBConnector* SQLPlayer = new DBConnector;
 Msg("Player Level:%i",SQLPlayer->GetLevel(engine->GetPlayerNetworkIDString(edict()),this);
}
That's all for now. Just post here, if you got some problems.
Category:ProgrammingCategory:Tutorials