pred@2009: /** pred@2009: * vim: set ts=4 : pred@2009: * ============================================================================= pred@2009: * SourceMod Client Preferences Extension pred@2009: * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. pred@2009: * ============================================================================= pred@2009: * pred@2009: * This program is free software; you can redistribute it and/or modify it under pred@2009: * the terms of the GNU General Public License, version 3.0, as published by the pred@2009: * Free Software Foundation. pred@2009: * pred@2009: * This program is distributed in the hope that it will be useful, but WITHOUT pred@2009: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS pred@2009: * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more pred@2009: * details. pred@2009: * pred@2009: * You should have received a copy of the GNU General Public License along with pred@2009: * this program. If not, see . pred@2009: * pred@2009: * As a special exception, AlliedModders LLC gives you permission to link the pred@2009: * code of this program (as well as its derivative works) to "Half-Life 2," the pred@2009: * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software pred@2009: * by the Valve Corporation. You must obey the GNU General Public License in pred@2009: * all respects for all other code used. Additionally, AlliedModders LLC grants pred@2009: * this exception to all derivative works. AlliedModders LLC defines further pred@2009: * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), pred@2009: * or . pred@2009: * pred@2009: * Version: $Id$ pred@2009: */ pred@2009: pred@2009: #include "query.h" pred@2009: pred@2009: pred@2009: void TQueryOp::RunThinkPart() pred@2009: { pred@2009: //handler for threaded sql queries pred@2009: pred@2207: if (m_type == Query_Connect) pred@2207: { pred@2207: return; pred@2207: } pred@2207: dvander@2373: switch (m_type) pred@2009: { dvander@2373: case Query_InsertCookie: pred@2009: { dvander@2373: g_CookieManager.InsertCookieCallback(m_pCookie, m_insertId); dvander@2373: break; dvander@2373: } pred@2207: dvander@2373: case Query_SelectData: dvander@2373: { pred@2592: g_CookieManager.ClientConnectCallback(m_serial, m_pResult); dvander@2373: break; dvander@2373: } pred@2207: dvander@2373: case Query_SelectId: dvander@2373: { dvander@2373: g_CookieManager.SelectIdCallback(m_pCookie, m_pResult); dvander@2373: break; dvander@2373: } pred@2207: dvander@2373: default: dvander@2373: { dvander@2373: break; pred@2009: } pred@2009: } pred@2009: } pred@2009: pred@2009: void TQueryOp::RunThreadPart() pred@2009: { pred@2207: if (m_type == Query_Connect) pred@2207: { pred@2207: g_ClientPrefs.DatabaseConnect(); pred@2207: } pred@2207: else pred@2009: { dvander@2359: assert(m_database != NULL); pred@2207: dvander@2373: /* I don't think this is needed anymore... keeping for now. */ pred@2207: m_database->LockForFullAtomicOperation(); pred@2009: pred@2207: if (!BindParamsAndRun()) pred@2207: { dvander@2364: g_pSM->LogError(myself, pred@2592: "Failed SQL Query, Error: \"%s\" (Query id %i - serial %i)", dvander@2373: m_database->GetError(), dvander@2364: m_type, pred@2592: m_serial); pred@2207: } pred@2009: pred@2207: m_database->UnlockFromFullAtomicOperation(); pred@2207: } pred@2009: } pred@2009: pred@2009: IDBDriver *TQueryOp::GetDriver() pred@2009: { dvander@2359: assert(m_database != NULL); pred@2207: pred@2207: return m_database->GetDriver(); pred@2009: } dvander@2373: pred@2009: IdentityToken_t *TQueryOp::GetOwner() pred@2009: { pred@2009: return myself->GetIdentity(); pred@2009: } pred@2220: pred@2009: void TQueryOp::Destroy() pred@2009: { dvander@2373: if (m_pResult != NULL) dvander@2373: { dvander@2373: m_pResult->Destroy(); dvander@2373: } pred@2009: delete this; pred@2009: } pred@2009: pred@2592: TQueryOp::TQueryOp(enum querytype type, int serial) pred@2009: { pred@2009: m_type = type; pred@2592: m_serial = serial; pred@2207: m_database = NULL; dvander@2373: m_insertId = -1; dvander@2373: m_pResult = NULL; pred@2207: } pred@2009: pred@2207: TQueryOp::TQueryOp(enum querytype type, Cookie *cookie) pred@2207: { pred@2207: m_type = type; pred@2207: m_pCookie = cookie; pred@2207: m_database = NULL; dvander@2373: m_insertId = -1; dvander@2373: m_pResult = NULL; pred@2207: } pred@2207: dvander@2373: void TQueryOp::SetDatabase(IDatabase *db) pred@2207: { pred@2207: m_database = db; pred@2207: m_database->IncReferenceCount(); pred@2009: } pred@2009: pred@2207: bool TQueryOp::BindParamsAndRun() pred@2207: { dvander@2373: size_t ignore; dvander@2373: char query[2048]; pred@2207: pred@2207: switch (m_type) pred@2207: { pred@2207: case Query_InsertCookie: pred@2207: { dvander@2373: char safe_name[MAX_NAME_LENGTH*2 + 1]; dvander@2373: char safe_desc[MAX_DESC_LENGTH*2 + 1]; dvander@2373: dvander@2373: m_database->QuoteString(m_params.cookie->name, dvander@2373: safe_name, dvander@2373: sizeof(safe_name), dvander@2373: &ignore); dvander@2373: m_database->QuoteString(m_params.cookie->description, dvander@2373: safe_desc, dvander@2373: sizeof(safe_desc), dvander@2373: &ignore); pred@2207: dvander@2373: if (g_DriverType == Driver_MySQL) dvander@2373: { dvander@2373: UTIL_Format(query, dvander@2373: sizeof(query), dvander@2373: "INSERT IGNORE INTO sm_cookies (name, description, access) \ dvander@2373: VALUES (\"%s\", \"%s\", %d)", dvander@2373: safe_name, dvander@2373: safe_desc, dvander@2373: m_params.cookie->access); dvander@2373: } dvander@2373: else if (g_DriverType == Driver_SQLite) dvander@2373: { dvander@2373: UTIL_Format(query, dvander@2373: sizeof(query), dvander@2373: "INSERT OR IGNORE INTO sm_cookies (name, description, access) \ dvander@2373: VALUES (\"%s\", \"%s\", %d)", dvander@2373: safe_name, dvander@2373: safe_desc, dvander@2373: m_params.cookie->access); dvander@2373: } dvander@2373: dvander@2373: if (!m_database->DoSimpleQuery(query)) dvander@2373: { dvander@2373: return false; dvander@2373: } dvander@2373: dvander@2373: m_insertId = m_database->GetInsertID(); dvander@2373: dvander@2373: return true; pred@2207: } pred@2207: pred@2207: case Query_SelectData: pred@2207: { dvander@2373: char safe_str[128]; dvander@2373: dvander@2373: m_database->QuoteString(m_params.steamId, safe_str, sizeof(safe_str), &ignore); pred@2207: dvander@2373: UTIL_Format(query, dvander@2373: sizeof(query), dvander@2373: "SELECT sm_cookies.name, sm_cookie_cache.value, sm_cookies.description, \ pred@2668: sm_cookies.access, sm_cookie_cache.timestamp \ dvander@2373: FROM sm_cookies \ dvander@2373: JOIN sm_cookie_cache \ dvander@2373: ON sm_cookies.id = sm_cookie_cache.cookie_id \ dvander@2373: WHERE player = \"%s\"", dvander@2373: safe_str); dvander@2373: dvander@2373: m_pResult = m_database->DoQuery(query); dvander@2373: dvander@2373: return (m_pResult != NULL); pred@2207: } pred@2207: pred@2207: case Query_InsertData: pred@2207: { dvander@2373: char safe_id[128]; dvander@2373: char safe_val[MAX_VALUE_LENGTH*2 + 1]; dvander@2373: dvander@2373: m_database->QuoteString(m_params.steamId, dvander@2373: safe_id, dvander@2373: sizeof(safe_id), dvander@2373: &ignore); dvander@2373: m_database->QuoteString(m_params.data->value, dvander@2373: safe_val, dvander@2373: sizeof(safe_val), dvander@2373: &ignore); pred@2207: dvander@2373: if (g_DriverType == Driver_MySQL) pred@2207: { dvander@2373: UTIL_Format(query, dvander@2373: sizeof(query), dvander@2373: "INSERT INTO sm_cookie_cache (player, cookie_id, value, timestamp) \ dvander@2373: VALUES (\"%s\", %d, \"%s\", %d) \ dvander@2373: ON DUPLICATE KEY UPDATE \ dvander@2373: value = \"%s\", timestamp = %d", dvander@2373: safe_id, dvander@2373: m_params.cookieId, dvander@2373: safe_val, pred@2668: (unsigned int)m_params.data->timestamp, dvander@2373: safe_val, pred@2668: (unsigned int)m_params.data->timestamp); dvander@2373: } dvander@2373: else if (g_DriverType == Driver_SQLite) dvander@2373: { dvander@2373: UTIL_Format(query, dvander@2373: sizeof(query), dvander@2373: "INSERT OR REPLACE INTO sm_cookie_cache \ dvander@2373: (player, cookie_id, value, timestamp) \ dvander@2373: VALUES (\"%s\", %d, \"%s\", %d)", dvander@2373: safe_id, dvander@2373: m_params.cookieId, dvander@2373: safe_val, pred@2668: (unsigned int)m_params.data->timestamp); pred@2207: } pred@2207: dvander@2373: if (!m_database->DoSimpleQuery(query)) dvander@2373: { dvander@2373: return false; dvander@2373: } dvander@2373: dvander@2373: m_insertId = m_database->GetInsertID(); dvander@2373: dvander@2373: return true; pred@2207: } pred@2207: pred@2207: case Query_SelectId: pred@2207: { dvander@2373: char safe_name[MAX_NAME_LENGTH*2 + 1]; dvander@2373: pred@2207: /* the steamId var was actually used to store the name of the cookie - Save duplicating vars */ dvander@2373: m_database->QuoteString(m_params.steamId, dvander@2373: safe_name, dvander@2373: sizeof(safe_name), dvander@2373: &ignore); pred@2207: dvander@2373: UTIL_Format(query, dvander@2373: sizeof(query), dvander@2373: "SELECT id FROM sm_cookies WHERE name = \"%s\"", dvander@2373: safe_name); dvander@2373: dvander@2373: m_pResult = m_database->DoQuery(query); dvander@2373: dvander@2373: return (m_pResult != NULL); pred@2207: } pred@2207: pred@2207: default: pred@2207: { pred@2207: break; pred@2207: } pred@2207: pred@2207: } pred@2207: dvander@2373: assert(false); pred@2207: dvander@2373: return false; pred@2207: } pred@2009: pred@2207: ParamData::~ParamData() pred@2207: { pred@2207: if (cookie) pred@2207: { pred@2207: g_ClientPrefs.cookieMutex->Lock(); pred@2207: cookie->usedInQuery--; pred@2207: pred@2207: if (cookie->shouldDelete && cookie->usedInQuery <= 0) pred@2207: { pred@2207: g_ClientPrefs.cookieMutex->Unlock(); pred@2207: delete cookie; pred@2207: cookie = NULL; pred@2207: } pred@2207: pred@2207: g_ClientPrefs.cookieMutex->Unlock(); pred@2207: } pred@2207: pred@2207: if (data) pred@2207: { pred@2207: /* Data is only ever passed in a client disconnect query and always needs to be deleted */ pred@2207: delete data; pred@2207: data = NULL; pred@2207: } pred@2207: } pred@2207: pred@2207: ParamData::ParamData() pred@2207: { pred@2207: cookie = NULL; pred@2207: data = NULL; pred@2207: steamId[0] = '\0'; pred@2207: cookieId = 0; pred@2208: } dvander@2373: