Game Development Community

MySQL for TGE

by Ron Yacketta · 03/02/2004 (11:09 am) · 75 comments

Download Code File

I found a forum thread by Felix Kollmann which lead me to a dead end on his site, after reading more of the thread I noticed that Stefan Beffy Moises snagged a copy of the code and tossed it on his www site (Thanxs Beffy!!!).

Looking at the code revealed that it needed a bit of an updated to be TGE 1.2 compliant as well as to get the ball rolling for cross platform compliancy.

I spent an hour or so last night updating the ConsoleMethods and adding a new one, as well as #if def'ing the winsock.h.

Decided to toss this back into the resource section so it does not get lost again. The .zip contains everything you need to get up and running


-Ron

You will need to download the original zip file from Beffy's site in order to use my updates

Updates:
03/04/04 Yacketta updated zip file

Updated 3/15/05
Got am e-mail regarding this resource and the inability to get it working as stated in the documentation. After some minor digging I found that the ConsoleMethod's needed to be updated as follows

ConsoleMethod (MySQL, GetRowCellDirect, const char*, 4, 4, "MySQL.GetRowCellDirect (ResultID, FieldNr)")
{
	MySQL* pThis= dynamic_cast<MySQL*> (object);

	return pThis->GetRowCell (atoi (argv[2]), atoi (argv[3]));
}

ConsoleMethod (MySQL, GetRowCell, const char*, 4, 4, "MySQL.GetRowCell (ResultID, FieldName)")
{
	MySQL* pThis= dynamic_cast<MySQL*> (object);

	return pThis->GetRowCell (atoi (argv[2]), argv[3]);
}

ConsoleMethod (MySQL, NumFields, S32, 2, 2, "MySQL.NumFields()")
{
	MySQL* pThis= dynamic_cast<MySQL*> (object);

	return pThis->NumFields();
}

ConsoleMethod (MySQL, GetFieldName, const char*, 4, 4, "MySQL.GetFieldName (ResultID, FieldIndex)")
{
	MySQL* pThis= dynamic_cast<MySQL*> (object);

	return pThis->GetFieldName (atoi (argv[2]), atoi (argv[3]));
}

the above changes enables one to get this resource compiled using visual studio 2003. I did not perform any unit or end to end tests with a mysql db

-Ron
Page«First 1 2 3 4 Next»
#61
04/01/2007 (6:12 am)
Yeah, I'm using MySQL 5.x and can't get it to run. Just seeing if I can get a fresh MySQL 5.0 compile (if I can find where they keep the source?)
#62
04/10/2007 (5:47 am)
I downloaded the file http://www.scatteredlands.com/TGE_mySQL_packed.zip. Are there any updates for TGE 1.5 and VC++ 2005 the express one.
Thank for any help!
#63
04/11/2007 (11:43 am)
it compiles fine in vc++ 2005 with tge 1.5. What errors are you getting?
#64
06/19/2007 (7:11 am)
Robin: Thanks for the response so long ago. I forgot to click on the notify checkbox and am so busy I forgot to follow up until now. I wanted the exact information you gave me and I appreciate it greatly. So many changes in TGE 1.5.xx and with the advent of Constructor (which my artist is gaga about) I find myself doing a complete rebuild and asking the same question. Has anyone done this in TGE 1.5.xx, so you saved me a lot of time and possible frustration and I thank you.
#65
06/19/2007 (7:22 am)
Has anyone worked out the MySql 5 issue for passwords yet? I have several NEW servers with Apache 2.xx and MySql 5.xx and need to know this before I implement it. Has the code been updated at
www.scatteredlands.com/TGE_mySQL_packed.zip?
#66
07/24/2007 (7:22 am)
Use old_passwords in the config file, then reset the passwords. That works fine. Also, i didnt create this resource, i'm only hosting a file that was a dead link before.
#67
08/03/2007 (7:17 pm)
Why are you calling mysql_shutdown() in the destructor?

22.2.3.65. mysql_shutdown()
int mysql_shutdown(MYSQL *mysql, enum mysql_enum_shutdown_level shutdown_level) 
Description 
Asks the database server to shut down. The connected user must have SHUTDOWN privileges. The shutdown_level argument was added in MySQL 5.0.1. MySQL 5.0 servers support only one type of shutdown; shutdown_level must be equal to SHUTDOWN_DEFAULT. Additional shutdown levels are planned to make it possible to choose the desired level. Dynamically linked executables which have been compiled with older versions of the libmysqlclient headers and call mysql_shutdown() need to be used with the old libmysqlclient dynamic library.

If mysql_init() allocates a new object, it is freed when mysql_close() is called to close the connection.
#68
08/05/2007 (11:39 am)
You are also not offering any methods of escaping control charaters which could lead to dangerious querys suceptable to SQL Injection Attacks.

Try something like;

int MySQL::doquery(const char *fmt, ...)
{
    va_list ap;
    va_start(ap, fmt);
	bool ret = qquery(fmt, ap);
	va_end(ap);
	return ret;
}

#define MAXQUERYSIZE 12288
int MySQL::qquery(const char *fmt, va_list ap)
{
	if (!m_bConnected)
		return false;
	char buf[MAXQUERYSIZE];
	memset(buf, 0, MAXQUERYSIZE);

    char *top = (char*)fmt + dStrlen(fmt);
    register char *ptr = buf;
    const char *str;

	// Will we overflow?
	if (dStrlen(fmt) >= MAXQUERYSIZE) 
	{
		Con::printf("MySQL: Would overflow on query: %s", fmt);
		return -1;
	}

	int i = 0;
    for ( ; fmt < top; fmt++) 
	{
		i++;
		if (*fmt == '%' && *(fmt+1)) 
		{
			switch (*(++fmt)) 
			{
			case '?': 
				str = va_arg(ap, const char *);
				if (dStrlen(str)*2+1+i >= MAXQUERYSIZE)
				{
					// Worst case, we could overflow. GTFO now.
					Con::printf("MySQL: Could overflow on query: %s", fmt);
					return -1;
				}
				ptr += mysql_real_escape_string(&m_Instance, ptr, str, strlen(str));
				break;

			case 's':
				str = va_arg(ap, const char *);
				if (dStrlen(str)+i >= MAXQUERYSIZE)
				{
					Con::printf("MySQL: Would overflow on query: %s", fmt);
					return -1;
				}
				while (*str) *(ptr++) = *(str++);
				break;

			case '%':
				*(ptr++) = '%';
				break;

			default:
				*(ptr++) = '%';
				*(ptr++) = *fmt;
				break;
			}
		} 
		else
			*(ptr++) = *fmt;
	}

	*ptr = '[[4fc75d0705172]]';

	if (mysql_real_query(&m_Instance, buf, ptr - buf)) 
	{
		Con::printf("MySQL: Failed on query: %s", buf);
		return (-1);
	}

	return (ptr - buf);
}

then in C++ you can create a query like;

MySQL.doquery("INSERT INTO accounts VALUES(name, password, age) ('%?', '%?', %?);", name, password, dItoa(age));

The %? within the format string will safely sanitize the input with mysql_real_escape_string. %s will not send it through the escape. There is no %d, %f, etc, just use one of the number to ascii functions (dItoa, dFtoa, etc).
#69
08/20/2007 (9:25 am)
Are there any issues with using or bundling this code into a product or other resource?
#70
08/20/2007 (10:55 am)
i dont think so. With proper credit you can just make a new resource out of it. That's what we're here for
#71
09/05/2007 (6:54 pm)
is there an updated resource with the changes listed above and does this compile fine with 1.5.2?
#72
10/02/2007 (4:16 pm)
I dont know who is using this resource, but I think there was a problem with the FreeResult method (it doesnt do anything). Looking at it, the linked list implementation didn't really make any sense to me, so I rewrote it so that it actually works. I suggest anyone who is using this take a look at how he made the FreeResult method. Maybe I am missing something, but heres the version I came up with.

void MySQL::FreeResult (MYSQL_RES* _pResult)
{


	ResultEntry* pCurrent= &m_Results;
	ResultEntry* pPrevious = 0;
	while (pCurrent)
	{
		if (pCurrent->m_pResult== _pResult)
		{
			mysql_free_result (pCurrent->m_pResult);

			if (pCurrent->m_pNext)
			{
				pPrevious->m_pNext = pCurrent->m_pNext;
			}
			else
			{
				pPrevious->m_pNext = 0;
			}
			delete pCurrent;
			return;
		}
		pPrevious = pCurrent;
		pCurrent = pCurrent->m_pNext;
	}		
}
#73
11/04/2007 (11:39 am)
This didn't work very well at all under Mac OS X, perhaps because I'm using the latest mysql client libraries. In addition, there were a couple of bugs and inefficiencies.

To fix these, I did the following:

- Changed call to mysql_init() to allocate instance data for us, and class to hold instance pointer (m_InstancePtr) rather than data structure (m_Instance). Changed all reference to m_Instance to m_InstancePtr. This also means the mysql_close() call will free the instance data for you.
- Removed incorrect mysql_shutdown() call -- mysql_shutdown() attempts to tell the database server to shutdown, which will always fail since the connection is closed.
- removed mysql_init from constructor. No reason to allocate and free the memory for the instance unless we are actually going to connect.

If anyone is interested in getting these changes, let me know, perhaps I can do an updated resource for them.
#74
12/31/2007 (2:06 pm)
This is unfortunately useless to me now as the MySQL client library is GPL licenced unless a commercial licence is purchased. Time to switch to PostGreSQL.
#75
04/08/2008 (10:50 pm)
According to the way metioned above,I can compile successfully.But I have a problem:How I can create a database?
Page«First 1 2 3 4 Next»