|
|
|
// (c) 2004 Mark Kretschmann <markey@web.de>
|
|
|
|
// (c) 2004 Christian Muehlhaeuser <chris@chris.de>
|
|
|
|
// (c) 2004 Sami Nieminen <sami.nieminen@iki.fi>
|
|
|
|
// (c) 2005 Ian Monroe <ian@monroe.nu>
|
|
|
|
// See COPYING file for licensing information.
|
|
|
|
|
|
|
|
#ifndef KLAMAV_COLLECTIONDB_H
|
|
|
|
#define KLAMAV_COLLECTIONDB_H
|
|
|
|
|
|
|
|
#include <kurl.h>
|
|
|
|
#include <tqdir.h> //stack allocated
|
|
|
|
#include <tqimage.h>
|
|
|
|
#include <tqobject.h> //baseclass
|
|
|
|
#include <tqptrqueue.h> //baseclass
|
|
|
|
#include <tqsemaphore.h> //stack allocated
|
|
|
|
#include <tqstringlist.h> //stack allocated
|
|
|
|
|
|
|
|
class DbConnection;
|
|
|
|
class DbConnectionPool;
|
|
|
|
|
|
|
|
|
|
|
|
class DbConfig
|
|
|
|
{};
|
|
|
|
|
|
|
|
|
|
|
|
class SqliteConfig : public DbConfig
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
SqliteConfig( const TQString& /* dbfile */ );
|
|
|
|
|
|
|
|
const TQString dbFile() const { return m_dbfile; }
|
|
|
|
|
|
|
|
private:
|
|
|
|
TQString m_dbfile;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class DbConnection
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
enum DbConnectionType { sqlite = 0, mysql = 1, postgresql = 2 };
|
|
|
|
|
|
|
|
DbConnection( DbConfig* /* config */ );
|
|
|
|
virtual ~DbConnection() = 0;
|
|
|
|
|
|
|
|
virtual TQStringList query( const TQString& /* statement */ ) = 0;
|
|
|
|
virtual int insert( const TQString& /* statement */, const TQString& /* table */ ) = 0;
|
|
|
|
const bool isInitialized() const { return m_initialized; }
|
|
|
|
virtual bool isConnected() const = 0;
|
|
|
|
virtual const TQString lastError() const { return "None"; }
|
|
|
|
protected:
|
|
|
|
bool m_initialized;
|
|
|
|
DbConfig *m_config;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
typedef struct sqlite3 sqlite3;
|
|
|
|
typedef struct sqlite3_context sqlite3_context;
|
|
|
|
typedef struct Mem sqlite3_value;
|
|
|
|
|
|
|
|
class SqliteConnection : public DbConnection
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
SqliteConnection( SqliteConfig* /* config */ );
|
|
|
|
~SqliteConnection();
|
|
|
|
|
|
|
|
TQStringList query( const TQString& /* statement */ );
|
|
|
|
int insert( const TQString& /* statement */, const TQString& /* table */ );
|
|
|
|
bool isConnected()const { return true; }
|
|
|
|
private:
|
|
|
|
static void sqlite_rand(sqlite3_context *context, int /*argc*/, sqlite3_value ** /*argv*/);
|
|
|
|
static void sqlite_power(sqlite3_context *context, int argc, sqlite3_value **argv);
|
|
|
|
|
|
|
|
sqlite3* m_db;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class DbConnectionPool : TQPtrQueue<DbConnection>
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
DbConnectionPool( bool temporary );
|
|
|
|
~DbConnectionPool();
|
|
|
|
|
|
|
|
const DbConnection::DbConnectionType getDbConnectionType() const { return m_dbConnType; }
|
|
|
|
const DbConfig *getDbConfig() const { return m_dbConfig; }
|
|
|
|
void createDbConnections();
|
|
|
|
|
|
|
|
DbConnection *getDbConnection();
|
|
|
|
void putDbConnection( const DbConnection* /* conn */ );
|
|
|
|
|
|
|
|
TQString escapeString( TQString string )
|
|
|
|
{
|
|
|
|
return
|
|
|
|
string.replace( '\'', "''" );
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
static const int POOL_SIZE = 5;
|
|
|
|
|
|
|
|
bool m_isTemporary;
|
|
|
|
TQSemaphore m_semaphore;
|
|
|
|
DbConnection::DbConnectionType m_dbConnType;
|
|
|
|
DbConfig *m_dbConfig;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class CollectionDB : public TQObject
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
|
|
|
|
signals:
|
|
|
|
|
|
|
|
public:
|
|
|
|
CollectionDB( bool temporary = false );
|
|
|
|
~CollectionDB();
|
|
|
|
|
|
|
|
static CollectionDB *instance();
|
|
|
|
|
|
|
|
const TQString escapeString( const TQString &string ) { return m_dbConnPool->escapeString(string); }
|
|
|
|
const TQString boolT() { if (m_dbConnPool->getDbConnectionType() == DbConnection::postgresql) return "'t'"; else return "1"; }
|
|
|
|
const TQString boolF() { if (m_dbConnPool->getDbConnectionType() == DbConnection::postgresql) return "'f'"; else return "0"; }
|
|
|
|
const TQString textColumnType() { if ( m_dbConnPool->getDbConnectionType() == DbConnection::postgresql ) return "TEXT"; else return "VARCHAR(255)"; }
|
|
|
|
const TQString textColumnType(int length){ if ( m_dbConnPool->getDbConnectionType() == DbConnection::postgresql ) return "TEXT"; else return TQString("VARCHAR(%1)").arg(length); }
|
|
|
|
// We might consider using LONGTEXT type, as some lyrics could be VERY long..???
|
|
|
|
const TQString longTextColumnType() { if ( m_dbConnPool->getDbConnectionType() == DbConnection::postgresql ) return "TEXT"; else return "TEXT"; }
|
|
|
|
const TQString randomFunc() { if ( m_dbConnPool->getDbConnectionType() == DbConnection::postgresql ) return "random()"; else return "RAND()"; }
|
|
|
|
|
|
|
|
int getType() { return m_dbConnPool->getDbConnectionType(); }
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This method returns a static DbConnection for components that want to use
|
|
|
|
* the same connection for the whole time. Should not be used anywhere else
|
|
|
|
* but in CollectionReader.
|
|
|
|
*
|
|
|
|
* @return static DbConnection
|
|
|
|
*/
|
|
|
|
DbConnection *getStaticDbConnection();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the DbConnection back to connection pool.
|
|
|
|
*
|
|
|
|
* @param conn DbConnection to be returned
|
|
|
|
*/
|
|
|
|
void returnStaticDbConnection( DbConnection *conn );
|
|
|
|
|
|
|
|
//sql helper methods
|
|
|
|
TQStringList query( const TQString& statement, DbConnection *conn = NULL );
|
|
|
|
int insert( const TQString& statement, const TQString& table, DbConnection *conn = NULL );
|
|
|
|
|
|
|
|
//table management methods
|
|
|
|
bool isEmpty();
|
|
|
|
bool isValid(const TQString &column, const TQString &table);
|
|
|
|
void createTables( DbConnection *conn = NULL );
|
|
|
|
void createActivityTable( DbConnection *conn = NULL );
|
|
|
|
void createMetaDBTable( DbConnection *conn = NULL );
|
|
|
|
void loadMetaDBTable( DbConnection *conn = NULL );
|
|
|
|
void dropTables( DbConnection *conn = NULL );
|
|
|
|
void clearTables( DbConnection *conn = NULL );
|
|
|
|
void moveTempTables( DbConnection *conn );
|
|
|
|
|
|
|
|
|
|
|
|
TQString typeCount( const TQString &type_id );
|
|
|
|
TQStringList messagesForType( const TQString &type_id, const bool isValue );
|
|
|
|
TQStringList allActivity( );
|
|
|
|
TQStringList allActivityOfType(const TQString &type, const TQString &days );
|
|
|
|
void insertEvent(const TQString &type, const TQString &event,const TQString &file = NULL, DbConnection *conn = NULL );
|
|
|
|
void expireActivity(const TQString &days );
|
|
|
|
void insertMetaDBEntry(const TQString &date, const TQString &submission, const TQString &creator,const TQString &virus,const TQString &alias, const TQString &sender,DbConnection *conn = NULL);
|
|
|
|
TQString latestMetaDBDate( );
|
|
|
|
|
|
|
|
protected:
|
|
|
|
TQCString md5sum( const TQString& artist, const TQString& album, const TQString& file = TQString::null );
|
|
|
|
/** Manages regular folder monitoring scan */
|
|
|
|
|
|
|
|
public slots:
|
|
|
|
|
|
|
|
private slots:
|
|
|
|
|
|
|
|
private:
|
|
|
|
//bump DATABASE_VERSION whenever changes to the table structure are made. will remove old db file.
|
|
|
|
static const int DATABASE_VERSION = 20;
|
|
|
|
static const int DATABASE_STATS_VERSION = 3;
|
|
|
|
static const int MONITOR_INTERVAL = 60; //sec
|
|
|
|
static const bool DEBUGSQL = false;
|
|
|
|
|
|
|
|
void initialize();
|
|
|
|
void destroy();
|
|
|
|
|
|
|
|
//general management methods
|
|
|
|
|
|
|
|
|
|
|
|
uint IDFromValue( TQString name, TQString value, bool autocreate = true, const bool temporary = false,
|
|
|
|
const bool updateSpelling = false, DbConnection *conn = NULL );
|
|
|
|
|
|
|
|
TQString valueFromID( TQString table, uint id );
|
|
|
|
|
|
|
|
//member variables
|
|
|
|
|
|
|
|
DbConnectionPool *m_dbConnPool;
|
|
|
|
|
|
|
|
bool m_isTemporary;
|
|
|
|
bool m_monitor;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#endif /* KLAMAV_COLLECTIONDB_H */
|