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: