/** * sqlChannel.cc * * Author: Matthias Crauwels * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, * USA. * * $Id: sqlChannel.cc,v 1.6 2008/01/16 02:03:39 buzlip01 Exp $ */ #include #include #include "dbHandle.h" #include "ELog.h" #include "misc.h" #include "sqlChannel.h" #include "chanfix.h" namespace gnuworld { namespace cf { const sqlChannel::flagType sqlChannel::F_BLOCKED = 0x00000001 ; const sqlChannel::flagType sqlChannel::F_ALERT = 0x00000002 ; const int sqlChannel::EV_MISC = 1 ; /* Uncategorized event */ const int sqlChannel::EV_NOTE = 2 ; /* Miscellaneous notes */ const int sqlChannel::EV_CHANFIX = 3 ; /* Manual chanfixes */ const int sqlChannel::EV_BLOCK = 4 ; /* Channel block */ const int sqlChannel::EV_UNBLOCK = 5 ; /* Channel unblock */ const int sqlChannel::EV_ALERT = 6 ; /* Channel alert */ const int sqlChannel::EV_UNALERT = 7 ; /* Channel unalert */ const int sqlChannel::EV_REQUESTOP = 8 ; /* Requestops */ const int sqlChannel::EV_TEMPBLOCK = 9 ; /* Temp channel block */ const int sqlChannel::EV_UNTEMPBLOCK = 10 ; /* Temp channel unblock */ const int sqlChannel::EV_SIMULATE = 11 ; /* Fix simulation */ unsigned long int sqlChannel::maxUserId = 0; sqlChannel::sqlChannel(sqlManager* _myManager) : id(0), channel(), user_name(), last(0), start(0), maxScore(0), modesRemoved(false), flags(0), inSQL(false) { myManager = _myManager; } void sqlChannel::setAllMembers(dbHandle* theDB, int row) { id = atoi(theDB->GetValue(row, 0)); channel = theDB->GetValue(row, 1); flags = atoi(theDB->GetValue(row, 2)); inSQL = true; if (id > maxUserId) maxUserId = id; } /** * This function inserts a brand new channel into the DB. */ bool sqlChannel::Insert(dbHandle* cacheCon) { /* Get a connection instance to our backend */ //dbHandle* cacheCon = myManager->getConnection(); /* Grab the next available user id */ id = ++maxUserId; /* Create the INSERT statement */ std::stringstream insertString; insertString << "INSERT INTO channels " << "(id, channel, flags) " << "VALUES " << "(" << id << ", " << "'" << escapeSQLChars(channel) << "', " << flags << ")" ; if (!cacheCon->Exec(insertString.str())) { elog << "sqlChannel::Insert> Something went wrong: " << cacheCon->ErrorMessage() << std::endl; inSQL = false; maxUserId--; } else { inSQL = true; } /* Dispose of our connection instance */ //myManager->removeConnection(cacheCon); return inSQL; } // sqlChannel::Insert() bool sqlChannel::Delete(dbHandle* cacheCon) { bool retval = false; /* Get a connection instance to our backend */ //dbHandle* cacheCon = myManager->getConnection(); /* Create the DELETE statement */ std::stringstream deleteString; deleteString << "DELETE FROM channels " << "WHERE id = '" << id << "'" ; if (!cacheCon->Exec(deleteString.str())) { elog << "sqlChannel::Delete> Something went wrong: " << cacheCon->ErrorMessage() << std::endl; retval = false; } else retval = true; /* Dispose of our connection instance */ //myManager->removeConnection(cacheCon); return retval; } bool sqlChannel::commit(dbHandle* cacheCon) { bool retval = false; /* Get a connection instance to our backend */ //dbHandle* cacheCon = myManager->getConnection(); /* Create the UPDATE statement */ std::stringstream chanCommit; chanCommit << "UPDATE channels SET " << "flags = " << flags << " WHERE " << "id = " << id ; if (!cacheCon->Exec(chanCommit.str())) { elog << "sqlChannel::commit> Something went wrong: " << cacheCon->ErrorMessage() << std::endl; retval = false; } else retval = true; /* Dispose of our connection instance */ //myManager->removeConnection(cacheCon); return retval; } /** * This method writes a 'notes' record, recording an event that has * occured in this channel. */ void sqlChannel::addNote(dbHandle* cacheCon, unsigned short eventType, iClient* theUser, const std::string& theMessage) { unsigned int num_notes = countNotes(cacheCon, 0); while (num_notes >= MAXNOTECOUNT) { if (!deleteOldestNote(cacheCon)) return; num_notes--; } /* Get a connection instance to our backend */ //dbHandle* cacheCon = myManager->getConnection(); /* Create the INSERT statement */ std::stringstream theLog; theLog << "INSERT INTO notes (ts, channelID, user_name, event, message) " << "VALUES (" << "date_part('epoch', CURRENT_TIMESTAMP)::int" << ", " << id << ", '" << theUser->getAccount() << "', " << eventType << ", " << "'" << escapeSQLChars(theMessage) << "')" ; if (!cacheCon->Exec(theLog.str())) { elog << "sqlChannel::addNote> Something went wrong: " << cacheCon->ErrorMessage() << std::endl; } /* Dispose of our connection instance */ //myManager->removeConnection(cacheCon); return; } const std::string sqlChannel::getLastNote(dbHandle* cacheCon, unsigned short eventType, time_t& eventTime) { std::string retval; /* Get a connection instance to our backend */ //dbHandle* cacheCon = myManager->getConnection(); /* Retrieve the last note */ std::stringstream queryString; queryString << "SELECT message,ts" << " FROM notes WHERE channelID = " << id << " AND event = " << eventType << " ORDER BY ts DESC LIMIT 1" ; if (cacheCon->Exec(queryString.str(),true)) { if (cacheCon->Tuples() > 0) { std::string note = cacheCon->GetValue(0, 0); eventTime = atoi(cacheCon->GetValue(0, 1)); retval = note; } } /* Dispose of our connection instance */ //myManager->removeConnection(cacheCon); return retval; } bool sqlChannel::deleteNote(dbHandle* cacheCon, unsigned int messageId) { bool retval = false; /* Get a connection instance to our backend */ //dbHandle* cacheCon = myManager->getConnection(); /* Create the DELETE statement */ std::stringstream deleteString; deleteString << "DELETE FROM notes WHERE channelID = " << id << " AND id = " << messageId ; if (!cacheCon->Exec(deleteString.str())) { elog << "sqlChannel::deleteNote> Something went wrong: " << cacheCon->ErrorMessage() << std::endl; retval = false; } else retval = true; /* Dispose of our connection instance */ //myManager->removeConnection(cacheCon); return retval; } bool sqlChannel::deleteOldestNote(dbHandle* cacheCon) { bool retval = false; /* Get a connection instance to our backend */ //dbHandle* cacheCon = myManager->getConnection(); /* Retrieve the id of the oldest note */ std::stringstream selectString; selectString << "SELECT id FROM notes WHERE channelID = " << id << " ORDER BY ts ASC LIMIT 1" ; if (cacheCon->Exec(selectString.str(),true)) { if (cacheCon->Tuples() > 0) { unsigned int note_id = atoi(cacheCon->GetValue(0, 0)); std::stringstream deleteString; deleteString << "DELETE FROM notes WHERE id = " << note_id ; if (cacheCon->Exec(deleteString.str(),true)) retval = true; } } /* Dispose of our connection instance */ //myManager->removeConnection(cacheCon); return retval; } bool sqlChannel::deleteAllNotes(dbHandle* cacheCon) { bool retval = false; /* Get a connection instance to our backend */ //dbHandle* cacheCon = myManager->getConnection(); /* Create the DELETE statement */ std::stringstream deleteString; deleteString << "DELETE FROM notes WHERE channelID = " << id ; if (!cacheCon->Exec(deleteString.str())) { elog << "sqlChannel::deleteAllNotes> Something went wrong: " << cacheCon->ErrorMessage() << std::endl; retval = false; } else retval = true; /* Dispose of our connection instance */ //myManager->removeConnection(cacheCon); return retval; } size_t sqlChannel::countNotes(dbHandle* cacheCon, unsigned short eventType) { /* Get a connection instance to our backend */ //dbHandle* cacheCon = myManager->getConnection(); /* Count the notes */ std::stringstream queryString; queryString << "SELECT count(id) FROM notes WHERE channelID = " << id ; if (eventType) { queryString << " AND event = " << eventType ; } size_t num_notes = 0; if (cacheCon->Exec(queryString.str(),true)) num_notes = atoi(cacheCon->GetValue(0, 0)); /* Dispose of our connection instance */ //myManager->removeConnection(cacheCon); return num_notes; } sqlChannel::~sqlChannel() { // No heap space allocated } } // namespace cf } // namespace gnuworld