sqlite_dbengine.cpp

来自「Amarok是一款在LINUX或其他类UNIX操作系统中运行的音频播放器软件。 」· C++ 代码 · 共 228 行

CPP
228
字号
// (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.#define DEBUG_PREFIX "SQLite-DBEngine"#include "app.h"#include "amarok.h"#include "amarokconfig.h"#include "debug.h"#include "sqlite_dbengine.h"#include <kapplication.h>#include <qfile.h>#include <qimage.h>#include <qtimer.h>#include <cmath>                 //DbConnection::sqlite_power()#include <ctime>                 //query()#include <unistd.h>              //usleep()#include "sqlite/sqlite3.h"AMAROK_EXPORT_PLUGIN( SqliteDbEngine )//////////////////////////////////////////////////////////////////////////////////////////// CLASS SqliteConnection//////////////////////////////////////////////////////////////////////////////////////////SqliteDbEngine::SqliteDbEngine()    : DbConnection( new SqliteConfig( "collection.db" ) ){    const QCString path = QString(/*amaroK::saveLocation()+*/"collection.db").local8Bit();    // Open database file and check for correctness    m_initialized = false;    QFile file( path );    if ( file.open( IO_ReadOnly ) )    {        QString format;        file.readLine( format, 50 );        if ( !format.startsWith( "SQLite format 3" ) )        {            warning() << "Database versions incompatible. Removing and rebuilding database.\n";        }        else if ( sqlite3_open( path, &m_db ) != SQLITE_OK )        {            warning() << "Database file corrupt. Removing and rebuilding database.\n";            sqlite3_close( m_db );        }        else            m_initialized = true;    }    if ( !m_initialized )    {        // Remove old db file; create new        QFile::remove( path );        if ( sqlite3_open( path, &m_db ) == SQLITE_OK )        {            m_initialized = true;        }    }    if ( m_initialized )    {        if( sqlite3_create_function(m_db, "rand", 0, SQLITE_UTF8, NULL, sqlite_rand, NULL, NULL) != SQLITE_OK )            m_initialized = false;        if( sqlite3_create_function(m_db, "power", 2, SQLITE_UTF8, NULL, sqlite_power, NULL, NULL) != SQLITE_OK )            m_initialized = false;    }    //optimization for speeding up SQLite    query( "PRAGMA default_synchronous = OFF;" );}SqliteDbEngine::~SqliteDbEngine(){    if ( m_db ) sqlite3_close( m_db );}QStringList SqliteDbEngine::query( const QString& statement ){    QStringList values;    int error;    const char* tail;    sqlite3_stmt* stmt;    //compile SQL program to virtual machine    error = sqlite3_prepare( m_db, statement.utf8(), statement.length(), &stmt, &tail );    if ( error != SQLITE_OK )    {        Debug::error() << k_funcinfo << " sqlite3_compile error:" << endl;        Debug::error() << sqlite3_errmsg( m_db ) << endl;        Debug::error() << "on query: " << statement << endl;        values = QStringList();    }    else    {        int busyCnt = 0;        int number = sqlite3_column_count( stmt );        //execute virtual machine by iterating over rows        while ( true )        {            error = sqlite3_step( stmt );            if ( error == SQLITE_BUSY )            {                if ( busyCnt++ > 20 ) {                    Debug::error() << "Busy-counter has reached maximum. Aborting this sql statement!\n";                    break;                }                ::usleep( 100000 ); // Sleep 100 msec                debug() << "sqlite3_step: BUSY counter: " << busyCnt << endl;            }            if ( error == SQLITE_MISUSE )                debug() << "sqlite3_step: MISUSE" << endl;            if ( error == SQLITE_DONE || error == SQLITE_ERROR )                break;            //iterate over columns            for ( int i = 0; i < number; i++ )            {                values << QString::fromUtf8( (const char*) sqlite3_column_text( stmt, i ) );            }        }        //deallocate vm resources        sqlite3_finalize( stmt );        if ( error != SQLITE_DONE )        {            Debug::error() << k_funcinfo << "sqlite_step error.\n";            Debug::error() << sqlite3_errmsg( m_db ) << endl;            Debug::error() << "on query: " << statement << endl;            values = QStringList();        }    }    return values;}int SqliteDbEngine::insert( const QString& statement, const QString& /* table */ ){    int error;    const char* tail;    sqlite3_stmt* stmt;    //compile SQL program to virtual machine    error = sqlite3_prepare( m_db, statement.utf8(), statement.length(), &stmt, &tail );    if ( error != SQLITE_OK )    {        Debug::error() << k_funcinfo << " sqlite3_compile error:" << endl;        Debug::error() << sqlite3_errmsg( m_db ) << endl;        Debug::error() << "on insert: " << statement << endl;    }    else    {        int busyCnt = 0;        //execute virtual machine by iterating over rows        while ( true )        {            error = sqlite3_step( stmt );            if ( error == SQLITE_BUSY )            {                if ( busyCnt++ > 20 ) {                    Debug::error() << "Busy-counter has reached maximum. Aborting this sql statement!\n";                    break;                }                ::usleep( 100000 ); // Sleep 100 msec                debug() << "sqlite3_step: BUSY counter: " << busyCnt << endl;            }            if ( error == SQLITE_MISUSE )                debug() << "sqlite3_step: MISUSE" << endl;            if ( error == SQLITE_DONE || error == SQLITE_ERROR )                break;        }        //deallocate vm resources        sqlite3_finalize( stmt );        if ( error != SQLITE_DONE )        {            Debug::error() << k_funcinfo << "sqlite_step error.\n";            Debug::error() << sqlite3_errmsg( m_db ) << endl;            Debug::error() << "on insert: " << statement << endl;        }    }    return sqlite3_last_insert_rowid( m_db );}// this implements a RAND() function compatible with the MySQL RAND() (0-param-form without seed)void SqliteDbEngine::sqlite_rand(sqlite3_context *context, int /*argc*/, sqlite3_value ** /*argv*/){    //sqlite3_result_double( context, static_cast<double>(KApplication::random()) / (RAND_MAX+1.0) );}// this implements a POWER() function compatible with the MySQL POWER()void SqliteDbEngine::sqlite_power(sqlite3_context *context, int argc, sqlite3_value **argv){    Q_ASSERT( argc==2 );    if( sqlite3_value_type(argv[0])==SQLITE_NULL || sqlite3_value_type(argv[1])==SQLITE_NULL ) {        sqlite3_result_null(context);        return;    }    double a = sqlite3_value_double(argv[0]);    double b = sqlite3_value_double(argv[1]);    sqlite3_result_double( context, pow(a,b) );}//////////////////////////////////////////////////////////////////////////////////////////// CLASS SqliteConfig//////////////////////////////////////////////////////////////////////////////////////////SqliteConfig::SqliteConfig( const QString& dbfile )    : m_dbfile( dbfile ){}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?