extensions/clientprefs/query.cpp
author Nicholas Hastings <skamonkey@gmail.com>
Wed May 25 13:31:14 2011 -0400 (2011-05-25)
changeset 3285 065beec73902
parent 2767 c1f37afdcbb9
child 3804 90159516acd3
permissions -rw-r--r--
Backed out changeset: 65eb3df32b1c
     1 /**
     2  * vim: set ts=4 :
     3  * =============================================================================
     4  * SourceMod Client Preferences Extension
     5  * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
     6  * =============================================================================
     7  *
     8  * This program is free software; you can redistribute it and/or modify it under
     9  * the terms of the GNU General Public License, version 3.0, as published by the
    10  * Free Software Foundation.
    11  * 
    12  * This program is distributed in the hope that it will be useful, but WITHOUT
    13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    14  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
    15  * details.
    16  *
    17  * You should have received a copy of the GNU General Public License along with
    18  * this program.  If not, see <http://www.gnu.org/licenses/>.
    19  *
    20  * As a special exception, AlliedModders LLC gives you permission to link the
    21  * code of this program (as well as its derivative works) to "Half-Life 2," the
    22  * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
    23  * by the Valve Corporation.  You must obey the GNU General Public License in
    24  * all respects for all other code used.  Additionally, AlliedModders LLC grants
    25  * this exception to all derivative works.  AlliedModders LLC defines further
    26  * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
    27  * or <http://www.sourcemod.net/license.php>.
    28  *
    29  * Version: $Id$
    30  */
    31 
    32 #include "query.h"
    33 
    34 
    35 void TQueryOp::RunThinkPart()
    36 {
    37 	//handler for threaded sql queries
    38 
    39 	if (m_type == Query_Connect)
    40 	{
    41 		return;
    42 	}
    43 
    44 	switch (m_type)
    45 	{
    46 		case Query_InsertCookie:
    47 		{
    48 			g_CookieManager.InsertCookieCallback(m_pCookie, m_insertId);
    49 			break;
    50 		}
    51 
    52 		case Query_SelectData:
    53 		{
    54 			g_CookieManager.ClientConnectCallback(m_serial, m_pResult);
    55 			break;
    56 		}
    57 
    58 		case Query_SelectId:
    59 		{
    60 			g_CookieManager.SelectIdCallback(m_pCookie, m_pResult);
    61 			break;
    62 		}
    63 
    64 		default:
    65 		{
    66 			break;
    67 		}
    68 	}
    69 }
    70 
    71 void TQueryOp::RunThreadPart()
    72 {
    73 	if (m_type == Query_Connect)
    74 	{
    75 		g_ClientPrefs.DatabaseConnect();
    76 	}
    77 	else
    78 	{
    79 		assert(m_database != NULL);
    80 
    81 		/* I don't think this is needed anymore... keeping for now. */
    82 		m_database->LockForFullAtomicOperation();
    83 
    84 		if (!BindParamsAndRun())
    85 		{
    86 			g_pSM->LogError(myself, 
    87 							"Failed SQL Query, Error: \"%s\" (Query id %i - serial %i)", 
    88 							m_database->GetError(),
    89 							m_type, 
    90 							m_serial);
    91 		}
    92 
    93 		m_database->UnlockFromFullAtomicOperation();
    94 	}
    95 }
    96 
    97 IDBDriver *TQueryOp::GetDriver()
    98 {
    99 	assert(m_database != NULL);
   100 
   101 	return m_database->GetDriver();
   102 }
   103 
   104 IdentityToken_t *TQueryOp::GetOwner()
   105 {
   106 	return myself->GetIdentity();
   107 }
   108 
   109 void TQueryOp::Destroy()
   110 {
   111 	if (m_pResult != NULL)
   112 	{
   113 		m_pResult->Destroy();
   114 	}
   115 	delete this;
   116 }
   117 
   118 TQueryOp::TQueryOp(enum querytype type, int serial)
   119 {
   120 	m_type = type;
   121 	m_serial = serial;
   122 	m_database = NULL;
   123 	m_insertId = -1;
   124 	m_pResult = NULL;
   125 }
   126 
   127 TQueryOp::TQueryOp(enum querytype type, Cookie *cookie)
   128 {
   129 	m_type = type;
   130 	m_pCookie = cookie;
   131 	m_database = NULL;
   132 	m_insertId = -1;
   133 	m_pResult = NULL;
   134 }
   135 
   136 void TQueryOp::SetDatabase(IDatabase *db)
   137 {
   138 	m_database = db;
   139 	m_database->IncReferenceCount();
   140 }
   141 
   142 bool TQueryOp::BindParamsAndRun()
   143 {
   144 	size_t ignore;
   145 	char query[2048];
   146 
   147 	switch (m_type)
   148 	{
   149 		case Query_InsertCookie:
   150 		{
   151 			char safe_name[MAX_NAME_LENGTH*2 + 1];
   152 			char safe_desc[MAX_DESC_LENGTH*2 + 1];
   153 			
   154 			m_database->QuoteString(m_params.cookie->name, 
   155 				safe_name, 
   156 				sizeof(safe_name),
   157 				&ignore);
   158 			m_database->QuoteString(m_params.cookie->description,
   159 				safe_desc,
   160 				sizeof(safe_desc),
   161 				&ignore);
   162 
   163 			if (g_DriverType == Driver_MySQL)
   164 			{
   165 				UTIL_Format(query,
   166 					sizeof(query),
   167 					"INSERT IGNORE INTO sm_cookies (name, description, access) \
   168 					 VALUES (\"%s\", \"%s\", %d)",
   169 					safe_name,
   170 					safe_desc,
   171 					m_params.cookie->access);
   172 			}
   173 			else if (g_DriverType == Driver_SQLite)
   174 			{
   175 				UTIL_Format(query,
   176 					sizeof(query),
   177 					"INSERT OR IGNORE INTO sm_cookies (name, description, access) \
   178 					 VALUES ('%s', '%s', %d)",
   179 					 safe_name,
   180 					 safe_desc,
   181 					 m_params.cookie->access);
   182 			}
   183 
   184 			if (!m_database->DoSimpleQuery(query))
   185 			{
   186 				return false;
   187 			}
   188 
   189 			m_insertId = m_database->GetInsertID();
   190 
   191 			return true;
   192 		}
   193 
   194 		case Query_SelectData:
   195 		{
   196 			char safe_str[128];
   197 
   198 			m_database->QuoteString(m_params.steamId, safe_str, sizeof(safe_str), &ignore);
   199 
   200 			UTIL_Format(query,
   201 				sizeof(query),
   202 				"SELECT sm_cookies.name, sm_cookie_cache.value, sm_cookies.description, \
   203 						sm_cookies.access, sm_cookie_cache.timestamp 	\
   204 				FROM sm_cookies				\
   205 				JOIN sm_cookie_cache		\
   206 				ON sm_cookies.id = sm_cookie_cache.cookie_id \
   207 				WHERE player = '%s'",
   208 				safe_str);
   209 
   210 			m_pResult = m_database->DoQuery(query);
   211 
   212 			return (m_pResult != NULL);
   213 		}
   214 
   215 		case Query_InsertData:
   216 		{
   217 			char safe_id[128];
   218 			char safe_val[MAX_VALUE_LENGTH*2 + 1];
   219 
   220 			m_database->QuoteString(m_params.steamId,
   221 				safe_id,
   222 				sizeof(safe_id),
   223 				&ignore);
   224 			m_database->QuoteString(m_params.data->value,
   225 				safe_val,
   226 				sizeof(safe_val),
   227 				&ignore);
   228 
   229 			if (g_DriverType == Driver_MySQL)
   230 			{
   231 				UTIL_Format(query, 
   232 					sizeof(query),
   233 					"INSERT INTO sm_cookie_cache (player, cookie_id, value, timestamp) 	\
   234 					 VALUES (\"%s\", %d, \"%s\", %d)									\
   235 					 ON DUPLICATE KEY UPDATE											\
   236 					 value = \"%s\", timestamp = %d",
   237 					safe_id,
   238 					m_params.cookieId,
   239 					safe_val,
   240 					(unsigned int)m_params.data->timestamp,
   241 					safe_val,
   242 					(unsigned int)m_params.data->timestamp);
   243 			}
   244 			else if (g_DriverType == Driver_SQLite)
   245 			{
   246 				UTIL_Format(query,
   247 					sizeof(query),
   248 					"INSERT OR REPLACE INTO sm_cookie_cache						\
   249 					 (player, cookie_id, value, timestamp)						\
   250 					 VALUES ('%s', %d, '%s', %d)",
   251 					safe_id,
   252 					m_params.cookieId,
   253 					safe_val,
   254 					(unsigned int)m_params.data->timestamp);
   255 			}
   256 
   257 			if (!m_database->DoSimpleQuery(query))
   258 			{
   259 				return false;
   260 			}
   261 
   262 			m_insertId = m_database->GetInsertID();
   263 
   264 			return true;
   265 		}
   266 
   267 		case Query_SelectId:
   268 		{
   269 			char safe_name[MAX_NAME_LENGTH*2 + 1];
   270 
   271 			/* the steamId var was actually used to store the name of the cookie - Save duplicating vars */
   272 			m_database->QuoteString(m_params.steamId, 
   273 				safe_name,
   274 				sizeof(safe_name),
   275 				&ignore);
   276 
   277 			UTIL_Format(query, 
   278 				sizeof(query),
   279 				"SELECT id FROM sm_cookies WHERE name = '%s'",
   280 				safe_name);
   281 
   282 			m_pResult = m_database->DoQuery(query);
   283 
   284 			return (m_pResult != NULL);
   285 		}
   286 
   287 		default:
   288 		{
   289 			break;
   290 		}
   291 			
   292 	}
   293 
   294 	assert(false);
   295 
   296 	return false;
   297 }
   298 
   299 ParamData::~ParamData()
   300 {
   301 	if (cookie)
   302 	{
   303 		g_ClientPrefs.cookieMutex->Lock();
   304 		cookie->usedInQuery--;
   305 
   306 		if (cookie->shouldDelete && cookie->usedInQuery <= 0)
   307 		{
   308 			g_ClientPrefs.cookieMutex->Unlock();
   309 			delete cookie;
   310 			cookie = NULL;
   311 		}
   312 
   313 		g_ClientPrefs.cookieMutex->Unlock();	
   314 	}
   315 
   316 	if (data)
   317 	{
   318 		/* Data is only ever passed in a client disconnect query and always needs to be deleted */
   319 		delete data;
   320 		data = NULL;
   321 	}
   322 }
   323 
   324 ParamData::ParamData()
   325 {
   326 	cookie = NULL;
   327 	data = NULL;
   328 	steamId[0] = '\0';
   329 	cookieId = 0;
   330 }
   331