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 + -
显示快捷键?