Minor cleanup to the core/db/ sources -- they were largely untouched from

the initial set of cleanups.
This commit is contained in:
casey langen 2016-11-26 15:21:33 -08:00
parent 64a187d1b8
commit 0b059c8aee
9 changed files with 89 additions and 365 deletions

View File

@ -155,7 +155,6 @@
<ClInclude Include="sdk\IPlugin.h" />
<ClInclude Include="sdk\IMetadataWriter.h" />
<ClInclude Include="db\Connection.h" />
<ClInclude Include="db\dbconfig.h" />
<ClInclude Include="db\ScopedTransaction.h" />
<ClInclude Include="db\Statement.h" />
<ClInclude Include="audio\Buffer.h" />

View File

@ -123,9 +123,6 @@
<ClInclude Include="db\Connection.h">
<Filter>src\db</Filter>
</ClInclude>
<ClInclude Include="db\dbconfig.h">
<Filter>src\db</Filter>
</ClInclude>
<ClInclude Include="db\ScopedTransaction.h">
<Filter>src\db</Filter>
</ClInclude>

View File

@ -49,218 +49,135 @@ Connection::Connection()
this->UpdateReferenceCount(true);
}
Connection::~Connection(){
Connection::~Connection() {
this->Close();
this->UpdateReferenceCount(false);
}
//////////////////////////////////////////
///\brief
///Open a connection to the database
///
///\param database
///Connection string. In SQLite this is the filename
///
///\param options
///Bit options. Unused at the moment
///
///\param cache
///Cachesize in KB
///
///\returns
///Error code returned by SQLite
//////////////////////////////////////////
int Connection::Open(const char *database, unsigned int options, unsigned int cache) {
int error;
#ifdef UTF_WIDECHAR
error = sqlite3_open16(database,&this->connection);
error = sqlite3_open16(database, &this->connection);
#else
error = sqlite3_open(database,&this->connection);
error = sqlite3_open(database, &this->connection);
#endif
if (error==SQLITE_OK) {
if (error == SQLITE_OK) {
this->Initialize(cache);
}
return error;
}
//////////////////////////////////////////
///\brief
///Open a connection to the database
///
///\param database
///Connection string. In SQLite this is the filename
///
///\param options
///Bit options. Unused at the moment
///
///\param cache
///Cachesize in KB
///
///\returns
///Error code returned by SQLite
//////////////////////////////////////////
int Connection::Open(const std::string &database,unsigned int options,unsigned int cache){
int Connection::Open(const std::string &database, unsigned int options, unsigned int cache) {
int error;
#ifdef WIN32
std::wstring wdatabase = u8to16(database);
error = sqlite3_open16(wdatabase.c_str(),&this->connection);
error = sqlite3_open16(wdatabase.c_str(), &this->connection);
#else
error = sqlite3_open(database.c_str(),&this->connection);
error = sqlite3_open(database.c_str(), &this->connection);
#endif
if (error==SQLITE_OK) {
if (error == SQLITE_OK) {
this->Initialize(cache);
}
return error;
}
//////////////////////////////////////////
///\brief
///Close connection to the database
///
///\returns
///Errorcode ( musik::core::db::ReturnCode )
//////////////////////////////////////////
int Connection::Close() {
if (sqlite3_close(this->connection) == SQLITE_OK) {
this->connection = 0;
return musik::core::db::Okay;
return Okay;
}
return musik::core::db::Error;
return Error;
}
//////////////////////////////////////////
///\brief
///Execute a SQL string
///
///\param sql
///SQL to execute
///
///\returns
///Errorcode musik::core::db::ReturnCode
///
///\see
///musik::core::db::ReturnCode
//////////////////////////////////////////
int Connection::Execute(const char* sql) {
sqlite3_stmt *stmt = NULL;
sqlite3_stmt *stmt = nullptr;
// Prepaire seems to give errors when interrupted
/* prepare seems to give errors when interrupted */
{
boost::mutex::scoped_lock lock(this->mutex);
if(sqlite3_prepare_v2(this->connection,sql,-1,&stmt,NULL)!=SQLITE_OK){
if (sqlite3_prepare_v2(this->connection, sql, -1, &stmt, nullptr) != SQLITE_OK) {
sqlite3_finalize(stmt);
return db::Error;
return Error;
}
}
// Execute the statement
int error = this->StepStatement(stmt);
if(error!=SQLITE_OK && error!=SQLITE_DONE){
int error = this->StepStatement(stmt);
if (error != SQLITE_OK && error != SQLITE_DONE){
sqlite3_finalize(stmt);
return db::Error;
return Error;
}
sqlite3_reset(stmt);
sqlite3_finalize(stmt);
return musik::core::db::Okay;
return Okay;
}
//////////////////////////////////////////
///\brief
///Execute a SQL string
///
///\param sql
///SQL to execute
///
///\returns
///Errorcode musik::core::db::ReturnCode
///
///\see
///musik::core::db::ReturnCode
//////////////////////////////////////////
int Connection::Execute(const wchar_t* sql) {
sqlite3_stmt *stmt = NULL;
sqlite3_stmt *stmt = nullptr;
{
boost::mutex::scoped_lock lock(this->mutex);
int err = sqlite3_prepare16_v2(this->connection,sql,-1,&stmt,NULL);
if(err!=SQLITE_OK){
int err = sqlite3_prepare16_v2(this->connection, sql, -1, &stmt, nullptr);
if (err != SQLITE_OK) {
sqlite3_finalize(stmt);
return db::Error;
return Error;
}
}
// Execute the statement
int error = this->StepStatement(stmt);
if(error!=SQLITE_OK && error!=SQLITE_DONE){
if (error != SQLITE_OK && error != SQLITE_DONE) {
sqlite3_finalize(stmt);
return db::Error;
return Error;
}
sqlite3_reset(stmt);
sqlite3_finalize(stmt);
return musik::core::db::Okay;
return Okay;
}
void Connection::Checkpoint() {
sqlite3_wal_checkpoint(this->connection, nullptr);
}
//////////////////////////////////////////
///\brief
///Get the last inserted row ID
///
///\returns
///Last inserted row ID
///
///\see
///http://www.sqlite.org/c3ref/last_insert_rowid.html
//////////////////////////////////////////
int Connection::LastInsertedId(){
return (int) sqlite3_last_insert_rowid(this->connection);
}
//////////////////////////////////////////
///\brief
///Initializes the database.
///
///\param cache
///Size of the cache to use in kilobytes
///
///This will set all the initial PRAGMAS
//////////////////////////////////////////
void Connection::Initialize(unsigned int cache) {
// sqlite3_enable_shared_cache(1);
sqlite3_busy_timeout(this->connection, 10000);
sqlite3_exec(this->connection, "PRAGMA synchronous=OFF", NULL, NULL, NULL); // Not a critical DB. Sync set to OFF
sqlite3_exec(this->connection, "PRAGMA page_size=4096", NULL, NULL, NULL); // According to windows standard page size
sqlite3_exec(this->connection, "PRAGMA auto_vacuum=0", NULL, NULL, NULL); // No autovaccum.
sqlite3_exec(this->connection, "PRAGMA auto_vacuum=0", NULL, NULL, NULL); // No autovaccum.
sqlite3_exec(this->connection, "PRAGMA journal_mode=WAL", NULL, NULL, NULL); // Allow reading while writing (write-ahead-logging)
sqlite3_exec(this->connection, "PRAGMA synchronous=OFF", nullptr, nullptr, nullptr); // Not a critical DB. Sync set to OFF
sqlite3_exec(this->connection, "PRAGMA page_size=4096", nullptr, nullptr, nullptr); // According to windows standard page size
sqlite3_exec(this->connection, "PRAGMA auto_vacuum=0", nullptr, nullptr, nullptr); // No autovaccum.
sqlite3_exec(this->connection, "PRAGMA journal_mode=WAL", nullptr, nullptr, nullptr); // Allow reading while writing (write-ahead-logging)
if (cache != 0) {
// Divide by 4 to since the page_size is 4096
// Total cache is the same as page_size*cache_size
cache = cache / 4;
std::string cacheSize("PRAGMA cache_size=" + boost::lexical_cast<std::string>(cache));
sqlite3_exec(this->connection,cacheSize.c_str(), NULL, NULL, NULL); // size * 1.5kb = 6Mb cache
sqlite3_exec(this->connection,cacheSize.c_str(), nullptr, nullptr, nullptr); // size * 1.5kb = 6Mb cache
}
sqlite3_exec(this->connection, "PRAGMA case_sensitive_like=0", NULL, NULL, NULL); // More speed if case insensitive
sqlite3_exec(this->connection, "PRAGMA count_changes=0", NULL, NULL, NULL); // If set it counts changes on SQL UPDATE. More speed when not.
sqlite3_exec(this->connection, "PRAGMA legacy_file_format=OFF", NULL, NULL, NULL); // No reason to be backwards compatible :)
sqlite3_exec(this->connection, "PRAGMA temp_store=MEMORY", NULL, NULL, NULL); // MEMORY, not file. More speed.
sqlite3_exec(this->connection, "PRAGMA case_sensitive_like=0", nullptr, nullptr, nullptr); // More speed if case insensitive
sqlite3_exec(this->connection, "PRAGMA count_changes=0", nullptr, nullptr, nullptr); // If set it counts changes on SQL UPDATE. More speed when not.
sqlite3_exec(this->connection, "PRAGMA legacy_file_format=OFF", nullptr, nullptr, nullptr); // No reason to be backwards compatible :)
sqlite3_exec(this->connection, "PRAGMA temp_store=MEMORY", nullptr, nullptr, nullptr); // MEMORY, not file. More speed.
}
void Connection::Interrupt(){
void Connection::Interrupt() {
boost::mutex::scoped_lock lock(this->mutex);
sqlite3_interrupt(this->connection);
}
@ -279,7 +196,7 @@ void Connection::UpdateReferenceCount(bool init) {
}
else {
--count;
if (count <= 0){
if (count <= 0) {
sqlite3_shutdown();
count = 0;
}

View File

@ -35,7 +35,6 @@
#pragma once
#include <core/config.h>
#include <core/db/dbconfig.h>
#include <core/db/Statement.h>
#include <core/db/ScopedTransaction.h>
@ -48,6 +47,13 @@ struct sqlite3_stmt;
namespace musik { namespace core { namespace db {
typedef enum {
Okay = 0,
Row = 100,
Done = 101,
Error = 1
} ReturnCode;
class Connection : boost::noncopyable {
public:
Connection();

View File

@ -58,7 +58,7 @@ void ScopedTransaction::CommitAndRestart() {
this->Begin();
}
void ScopedTransaction::Begin(){
void ScopedTransaction::Begin() {
/* we use an IMMEDIATE transaction because we have write-ahead-logging
enabled on this instance, this generally results in faster queries
and also allows reads while writing */
@ -81,4 +81,6 @@ void ScopedTransaction::End() {
this->connection->Checkpoint();
}
}
this->canceled = false;
}

View File

@ -40,229 +40,97 @@
using namespace musik::core::db;
//////////////////////////////////////////
///\brief
///Constructor
///
///\param sql
///SQL to be precomiled
///
///\param connection
///database Connection
//////////////////////////////////////////
Statement::Statement(const char* sql,Connection &connection)
Statement::Statement(const char* sql, Connection &connection)
: connection(&connection)
, stmt(NULL)
{
, stmt(nullptr) {
boost::mutex::scoped_lock lock(connection.mutex);
int err = sqlite3_prepare_v2(
this->connection->connection, sql, -1, &this->stmt, NULL);
this->connection->connection, sql, -1, &this->stmt, nullptr);
if (err!=SQLITE_OK) {
return;
}
}
//////////////////////////////////////////
///\brief
///Constructor used by the CachedStatement
//////////////////////////////////////////
Statement::Statement(Connection &connection) : connection(&connection),stmt(NULL) {
Statement::Statement(Connection &connection)
: connection(&connection)
, stmt(nullptr) {
}
//////////////////////////////////////////
///\brief
///Destructor that will finalize the statement
//////////////////////////////////////////
Statement::~Statement(){
int err=sqlite3_finalize(this->stmt);
Statement::~Statement() {
int err = sqlite3_finalize(this->stmt);
}
//////////////////////////////////////////
///\brief
///Reset a statment to be able to re-execute it later
//////////////////////////////////////////
void Statement::Reset(){
int err = sqlite3_reset(this->stmt);
void Statement::Reset() {
int err = sqlite3_reset(this->stmt);
}
//////////////////////////////////////////
///\brief
///Unbinds all previously binded parameters
//////////////////////////////////////////
void Statement::UnBindAll(){
DB_ASSERT(sqlite3_clear_bindings(this->stmt));
void Statement::UnbindAll() {
sqlite3_clear_bindings(this->stmt);
}
//////////////////////////////////////////
///\brief
///Execute/Step through the statment
///
///\returns
///musik::core::db::ReturnCode
//////////////////////////////////////////
int Statement::Step(){
int Statement::Step() {
return this->connection->StepStatement(this->stmt);
}
//////////////////////////////////////////
///\brief
///Bind a integer to a statment parameter
///
///\param position
///Position of the parameter (0 is the first)
///
///\param bindInt
///Integer to bind
//////////////////////////////////////////
void Statement::BindInt(int position,int bindInt){
DB_ASSERT(sqlite3_bind_int(this->stmt, position + 1, bindInt));
void Statement::BindInt(int position,int bindInt) {
sqlite3_bind_int(this->stmt, position + 1, bindInt);
}
//////////////////////////////////////////
///\brief
///Bind a 64bit integer to a statment parameter
///
///\param position
///Position of the parameter (0 is the first)
///
///\param bindInt
///Integer to bind
//////////////////////////////////////////
void Statement::BindInt(int position, uint64 bindInt){
DB_ASSERT(sqlite3_bind_int64(this->stmt, position + 1, bindInt));
void Statement::BindInt(int position, uint64 bindInt) {
sqlite3_bind_int64(this->stmt, position + 1, bindInt);
}
//////////////////////////////////////////
///\brief
///Bind a text to a statment parameter
///
///\param position
///Position of the parameter (0 is the first)
///
///\param bindText
///Text to bind
//////////////////////////////////////////
void Statement::BindText(int position, const char* bindText) {
DB_ASSERT(sqlite3_bind_text(
sqlite3_bind_text(
this->stmt,
position + 1,
bindText,
-1,
SQLITE_STATIC));
SQLITE_STATIC);
}
//////////////////////////////////////////
///\brief
///Bind a text to a statment parameter
///
///\param position
///Position of the parameter (0 is the first)
///
///\param bindText
///Text to bind
//////////////////////////////////////////
void Statement::BindText(int position ,const std::string &bindText) {
DB_ASSERT(sqlite3_bind_text(
sqlite3_bind_text(
this->stmt, position + 1,
bindText.c_str(),
-1,
SQLITE_TRANSIENT));
SQLITE_TRANSIENT);
}
//////////////////////////////////////////
///\brief
///Bind a text to a statment parameter
///
///\param position
///Position of the parameter (0 is the first)
///
///\param bindText
///Text to bind
//////////////////////////////////////////
void Statement::BindTextW(int position,const wchar_t* bindText){
DB_ASSERT(sqlite3_bind_text16(
sqlite3_bind_text16(
this->stmt,
position + 1,
bindText,
-1,
SQLITE_STATIC));
SQLITE_STATIC);
}
//////////////////////////////////////////
///\brief
///Bind a text to a statment parameter
///
///\param position
///Position of the parameter (0 is the first)
///
///\param bindText
///Text to bind
//////////////////////////////////////////
void Statement::BindTextW(int position,const std::wstring &bindText){
DB_ASSERT(sqlite3_bind_text16(
sqlite3_bind_text16(
this->stmt,
position + 1,
bindText.c_str(),
-1,
SQLITE_TRANSIENT));
SQLITE_TRANSIENT);
}
//////////////////////////////////////////
///\brief
///Get the results of a column if Step() return a musik::core::db::Row
///
///\param column
///Column to get (0 is the first)
///
///\returns
///Column data
//////////////////////////////////////////
int Statement::ColumnInt(int column){
return sqlite3_column_int(this->stmt,column);
int Statement::ColumnInt(int column) {
return sqlite3_column_int(this->stmt, column);
}
//////////////////////////////////////////
///\brief
///Get the results of a column if Step() return a musik::core::db::Row
///
///\param column
///Column to get (0 is the first)
///
///\returns
///Column data
//////////////////////////////////////////
uint64 Statement::ColumnInt64(int column){
return sqlite3_column_int64(this->stmt,column);
uint64 Statement::ColumnInt64(int column) {
return sqlite3_column_int64(this->stmt, column);
}
//////////////////////////////////////////
///\brief
///Get the results of a column if Step() return a musik::core::db::Row
///
///\param column
///Column to get (0 is the first)
///
///\returns
///Column data
//////////////////////////////////////////
const char* Statement::ColumnText(int column){
const char* Statement::ColumnText(int column) {
const char* text = (char*) sqlite3_column_text(this->stmt, column);
return text ? text : "";
}
//////////////////////////////////////////
///\brief
///Get the results of a column if Step() return a musik::core::db::Row
///
///\param column
///Column to get (0 is the first)
///
///\returns
///Column data
//////////////////////////////////////////
const wchar_t* Statement::ColumnTextW(int column){
const wchar_t* text = (wchar_t*) sqlite3_column_text16(this->stmt,column);
const wchar_t* Statement::ColumnTextW(int column) {
const wchar_t* text = (wchar_t*) sqlite3_column_text16(this->stmt, column);
return text ? text : L"";
}

View File

@ -45,18 +45,15 @@ struct sqlite3_stmt;
//////////////////////////////////////////
namespace musik{ namespace core{ namespace db{
namespace musik { namespace core { namespace db {
class Connection;
//////////////////////////////////////////
///\brief
///Class for precompiling SQL statements
//////////////////////////////////////////
class Statement : boost::noncopyable{
class Statement : boost::noncopyable {
public:
Statement(const char* sql,Connection &connection);
virtual ~Statement();
void Reset();
int Step();
@ -72,7 +69,7 @@ namespace musik{ namespace core{ namespace db{
const char* ColumnText(int column);
const wchar_t* ColumnTextW(int column);
void UnBindAll();
void UnbindAll();
private:
friend class Connection;

View File

@ -1,62 +0,0 @@
//////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2007-2016 musikcube team
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// * Neither the name of the author nor the names of other contributors may
// be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////////
#pragma once
#ifdef _DEBUG
#ifdef __MSVC__
#define DB_ASSERT(x) _ASSERT(x==0)
#else //__MSVC__
#define DB_ASSERT(x) x
#endif//__MSVC
#else
#define DB_ASSERT(x) x
#endif
namespace musik{ namespace core{ namespace db{
//////////////////////////////////////////
///\brief
///The ReturnCode is used by several method to return the status of a execution
//////////////////////////////////////////
typedef enum {
Okay = 0,
Row = 100,
Done = 101,
Error = 1
} ReturnCode;
} } }

View File

@ -620,7 +620,7 @@ void Indexer::RunAnalyzers() {
trackId = getNextTrack.ColumnInt(0);
getNextTrack.Reset();
getNextTrack.UnBindAll();
getNextTrack.UnbindAll();
IndexerTrack track(trackId);