I just thought I'd let you in on the progress, so if anyone can see any obvious errors at this stage, bugs can be avoided later, and it gives other the chance to see the method.
Obviously, you first need to make the Makefile change I showed above, so that MySQL code will work.
I have created 2 files, these are
mysql.h:
#ifndef _MYSQL_H
#include <mysql/mysql.h>
#define _MYSQL_H 1
#endif
#define SQL_ERR mysql_error(SQL_conn)
#define MAX_SQL_FIELDNAME 30
/* mysql_field_count doesn't exist before v3.22.24 */
#if !defined(MYSQL_VERSION_ID) || (MYSQL_VERSION_ID<32224)
#define mysql_field_count mysql_num_fields
#endif
#ifdef _MYSQL_C
MYSQL *SQL_conn = NULL; /* MySQL Connection handler is a global */
char *SQL_server = "localhost"; /* MySQL Server URL (usually localhost) */
char *SQL_user = "my_user"; /* MySQL Server Username */
char *SQL_password = "my_password";/* MySQL Server Password */
char *SQL_database = "my_db"; /* MySQL MUD Database Name */
char *SQLTBL_users = "my_users"; /* MySQL Table for player index */
char *SQLTBL_pfiles = "my_pfiles"; /* MySQL Table for player data */
#else
extern MYSQL *SQL_conn; /* Extern MySQL Connection for outside mysql.c */
#endif
mysql.c:
/* Simple C functions that connect to MySQL Database server */
/* Created for TrigunMUD by Jamdog - 27th June 2010 */
#define _MYSQL_C 1
#include "conf.h"
#include "sysdep.h"
#include "structs.h"
#include "utils.h"
#include "db.h"
#include "mysql.h"
/*
* connect_to_mysql function
* Sets up the actual database connection, called at MUD startup
*/
MYSQL *connect_to_mysql(void) {
SQL_conn = mysql_init(NULL);
/* Connect to database */
if (!mysql_real_connect(SQL_conn, SQL_server,
SQL_user, SQL_password, SQL_database, 0, NULL, 0)) {
log("SYSERR: MySQL: %s\n", SQL_ERR);
return NULL;
}
return(SQL_conn);
}
/*
* run_database_query function
* Query the database, and return the results (or NULL)
*/
MYSQL_RES *run_database_query(const char *q)
{
MYSQL_RES *res;
if (!SQL_conn) return NULL;
if (!q || !(*q)) return NULL;
/* send SQL query */
if (mysql_query(SQL_conn, q)) {
log("SYSERR: MySQL: %s\n", SQL_ERR);
return(NULL);
}
res = mysql_use_result(SQL_conn);
return res;
}
/*
* MySQL Version of the load_char function
*/
void mysql_load_char(int pid, struct char_data *ch)
{
MYSQL_RES *res;
MYSQL_ROW row;
MYSQL_FIELD *field;
char q[MAX_STRING_LENGTH];
char f1[128], f2[128], f3[128], f4[128];
int i;
sprintf(q, "SELECT * FROM %s WHERE id='%d'", SQLTBL_pfiles, pid);
if (!(res = run_database_query(q))) {
log("SYSERR: MYSQL: Invalid or missing pfile data (ID: %d), %s", pid, SQL_ERR);
}
/* Should only be one row, so grab it */
row = mysql_fetch_row(res);
mysql_field_seek (res, 0); /* Go to the first column */
for (i = 0; i < mysql_num_fields(res); i++) /* Cycle through result columns */
{
field = mysql_fetch_field (res);
switch (*(field->name)) {
case 'a':
if (!strcmp((field->name), "ac")) GET_AC(ch) = atoi(row[i]);
else if (!strcmp((field->name), "act_flags")) {
if (!sscanf(row[i], "%s %s %s %s", f1, f2, f3, f4) == 4) {
for (i=0; i<PR_ARRAY_MAX; i++)
PLR_FLAGS(ch)[i] = 0;
log("SYSERR: MySQL: Invalid act_flags field in %s (ID: %d)", SQLTBL_pfiles, pid);
} else {
PLR_FLAGS(ch)[0] = asciiflag_conv(f1);
PLR_FLAGS(ch)[1] = asciiflag_conv(f2);
PLR_FLAGS(ch)[2] = asciiflag_conv(f3);
PLR_FLAGS(ch)[3] = asciiflag_conv(f4);
}
}
break;
default:
log("SYSERR: MySQL: Unhandled field %s in table %s", (field->name), SQLTBL_pfiles);
break;
}
}
/* free MySQL results table */
mysql_free_result(res);
}
I decided to make SQL_conn a global, permanently 'open' connection to the database rather than keep opening a db connection every time you want to run a query, then closing it. This should save time.
Obviously, mysql_load_char is unfinished, but has a couple of example fields done, to show method.
The database connection data (host, username, password, etc...) would be editable by Imps in cedit eventually. Obviously, you would need to set these for your server...
If no-one sees and glaring errors in my code, I'll continue... ;)