Link dynamically against sqlite3 but still use a copy of QSqlLiteDriver
This commit is contained in:
parent
331d471b51
commit
4c23072bef
18
3rdparty/qsqlite/CMakeLists.txt
vendored
18
3rdparty/qsqlite/CMakeLists.txt
vendored
@ -21,11 +21,19 @@ qt4_wrap_cpp(SQLITE-SOURCES-MOC ${SQLITE-MOC-HEADERS})
|
|||||||
include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
|
include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
|
||||||
add_definitions(-DQT_PLUGIN -DQT_NO_DEBUG)
|
add_definitions(-DQT_PLUGIN -DQT_NO_DEBUG)
|
||||||
add_definitions(-DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_FTS3_PARENTHESIS)
|
|
||||||
|
|
||||||
add_library(sqlite STATIC sqlite3.c)
|
find_path(SQLITE_INCLUDE_DIRS sqlite3.h)
|
||||||
set_target_properties(sqlite PROPERTIES COMPILE_FLAGS
|
find_library(SQLITE_LIBRARIES sqlite3)
|
||||||
"-Wno-pointer-to-int-cast -Wno-int-to-pointer-cast")
|
|
||||||
|
if (SQLITE_INCLUDE_DIRS AND SQLITE_LIBRARIES)
|
||||||
|
set(SQLITE_FOUND true)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (NOT SQLITE_FOUND)
|
||||||
|
message(SEND_ERROR "Could not find sqlite3")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
include_directories(${SQLITE_INCLUDE_DIRS})
|
||||||
|
|
||||||
add_library(qsqlite STATIC
|
add_library(qsqlite STATIC
|
||||||
${SQLITE-SOURCES}
|
${SQLITE-SOURCES}
|
||||||
@ -33,6 +41,6 @@ add_library(qsqlite STATIC
|
|||||||
${SQLITE-WIN32-RESOURCES}
|
${SQLITE-WIN32-RESOURCES}
|
||||||
)
|
)
|
||||||
target_link_libraries(qsqlite
|
target_link_libraries(qsqlite
|
||||||
sqlite
|
${SQLITE_LIBRARIES}
|
||||||
${QT_LIBRARIES}
|
${QT_LIBRARIES}
|
||||||
)
|
)
|
||||||
|
110643
3rdparty/qsqlite/sqlite3.c
vendored
110643
3rdparty/qsqlite/sqlite3.c
vendored
File diff suppressed because it is too large
Load Diff
5763
3rdparty/qsqlite/sqlite3.h
vendored
5763
3rdparty/qsqlite/sqlite3.h
vendored
File diff suppressed because it is too large
Load Diff
@ -304,31 +304,14 @@ if(ENABLE_VISUALISATIONS)
|
|||||||
endif(USE_SYSTEM_PROJECTM)
|
endif(USE_SYSTEM_PROJECTM)
|
||||||
endif(ENABLE_VISUALISATIONS)
|
endif(ENABLE_VISUALISATIONS)
|
||||||
|
|
||||||
# We compile our own qsqlite3 by default now, because in Qt 4.7 the symbols we
|
|
||||||
# need from it are private.
|
|
||||||
option(STATIC_SQLITE "Compile and use a static sqlite3 library" ON)
|
|
||||||
|
|
||||||
set(HAVE_STATIC_SQLITE ${STATIC_SQLITE})
|
# Build our copy of QSqlLiteDriver.
|
||||||
if(STATIC_SQLITE)
|
# We do this because we can't guarantee that the driver shipped with Qt exposes the
|
||||||
message(STATUS "Building static qsqlite plugin")
|
# raw sqlite3_ functions required for FTS support. This way we know that those symbols
|
||||||
|
# exist at compile-time and that our code links to the same sqlite library as the
|
||||||
|
# Qt driver.
|
||||||
add_subdirectory(3rdparty/qsqlite)
|
add_subdirectory(3rdparty/qsqlite)
|
||||||
include_directories("3rdparty/qsqlite")
|
include_directories("3rdparty/qsqlite")
|
||||||
else()
|
|
||||||
if (NOT I_HATE_MY_USERS)
|
|
||||||
message(FATAL_ERROR "No, really, Clementine needs sqlite to be linked "
|
|
||||||
"statically. If it's not, Clementine won't be able to resolve the "
|
|
||||||
"functions it needs to register full text search support. Search will "
|
|
||||||
"be really slow and users will be unhappy. If you're packaging "
|
|
||||||
"Clementine for a distribution and you really hate your users and want "
|
|
||||||
"them to have a bad time please rerun cmake with -DI_HATE_MY_USERS=ON")
|
|
||||||
else()
|
|
||||||
if (NOT MY_USERS_WILL_SUFFER_BECAUSE_OF_ME)
|
|
||||||
message(FATAL_ERROR "So you really hate your users and you want to "
|
|
||||||
"create a crippled package that doesn't work properly? Please send "
|
|
||||||
"an email to the devs and help us understand why.")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
endif(STATIC_SQLITE)
|
|
||||||
|
|
||||||
# When/if upstream accepts our patches then these options can be used to link
|
# When/if upstream accepts our patches then these options can be used to link
|
||||||
# to system installed qtsingleapplication instead.
|
# to system installed qtsingleapplication instead.
|
||||||
|
@ -1192,6 +1192,7 @@ target_link_libraries(clementine_lib
|
|||||||
${QTSINGLECOREAPPLICATION_LIBRARIES}
|
${QTSINGLECOREAPPLICATION_LIBRARIES}
|
||||||
${QTIOCOMPRESSOR_LIBRARIES}
|
${QTIOCOMPRESSOR_LIBRARIES}
|
||||||
${CMAKE_THREAD_LIBS_INIT}
|
${CMAKE_THREAD_LIBS_INIT}
|
||||||
|
${SQLITE_LIBRARIES}
|
||||||
z
|
z
|
||||||
Qocoa
|
Qocoa
|
||||||
)
|
)
|
||||||
@ -1265,11 +1266,8 @@ else (APPLE)
|
|||||||
target_link_libraries(clementine_lib ${QXT_LIBRARIES})
|
target_link_libraries(clementine_lib ${QXT_LIBRARIES})
|
||||||
endif (APPLE)
|
endif (APPLE)
|
||||||
|
|
||||||
# Link against the qsqlite plugin on windows and mac
|
|
||||||
if(HAVE_STATIC_SQLITE)
|
|
||||||
set(3RDPARTY_SQLITE_LIBRARY qsqlite)
|
set(3RDPARTY_SQLITE_LIBRARY qsqlite)
|
||||||
target_link_libraries(clementine_lib qsqlite)
|
target_link_libraries(clementine_lib qsqlite)
|
||||||
endif(HAVE_STATIC_SQLITE)
|
|
||||||
|
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
target_link_libraries(clementine_lib
|
target_link_libraries(clementine_lib
|
||||||
|
@ -40,7 +40,6 @@
|
|||||||
#cmakedefine HAVE_SKYDRIVE
|
#cmakedefine HAVE_SKYDRIVE
|
||||||
#cmakedefine HAVE_SPARKLE
|
#cmakedefine HAVE_SPARKLE
|
||||||
#cmakedefine HAVE_SPOTIFY_DOWNLOADER
|
#cmakedefine HAVE_SPOTIFY_DOWNLOADER
|
||||||
#cmakedefine HAVE_STATIC_SQLITE
|
|
||||||
#cmakedefine HAVE_UBUNTU_ONE
|
#cmakedefine HAVE_UBUNTU_ONE
|
||||||
#cmakedefine HAVE_WIIMOTEDEV
|
#cmakedefine HAVE_WIIMOTEDEV
|
||||||
#cmakedefine IMOBILEDEVICE_USES_UDIDS
|
#cmakedefine IMOBILEDEVICE_USES_UDIDS
|
||||||
|
@ -25,6 +25,8 @@
|
|||||||
|
|
||||||
#include <boost/scope_exit.hpp>
|
#include <boost/scope_exit.hpp>
|
||||||
|
|
||||||
|
#include <sqlite3.h>
|
||||||
|
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QLibrary>
|
#include <QLibrary>
|
||||||
@ -86,25 +88,6 @@ struct sqlite3_tokenizer_cursor {
|
|||||||
/* Tokenizer implementations will typically add additional fields */
|
/* Tokenizer implementations will typically add additional fields */
|
||||||
};
|
};
|
||||||
|
|
||||||
int (*Database::_sqlite3_value_type) (sqlite3_value*) = NULL;
|
|
||||||
sqlite_int64 (*Database::_sqlite3_value_int64) (sqlite3_value*) = NULL;
|
|
||||||
const uchar* (*Database::_sqlite3_value_text) (sqlite3_value*) = NULL;
|
|
||||||
void (*Database::_sqlite3_result_int64) (sqlite3_context*, sqlite_int64) = NULL;
|
|
||||||
void* (*Database::_sqlite3_user_data) (sqlite3_context*) = NULL;
|
|
||||||
|
|
||||||
int (*Database::_sqlite3_open) (const char*, sqlite3**) = NULL;
|
|
||||||
const char* (*Database::_sqlite3_errmsg) (sqlite3*) = NULL;
|
|
||||||
int (*Database::_sqlite3_close) (sqlite3*) = NULL;
|
|
||||||
sqlite3_backup* (*Database::_sqlite3_backup_init) (
|
|
||||||
sqlite3*, const char*, sqlite3*, const char*) = NULL;
|
|
||||||
int (*Database::_sqlite3_backup_step) (sqlite3_backup*, int) = NULL;
|
|
||||||
int (*Database::_sqlite3_backup_finish) (sqlite3_backup*) = NULL;
|
|
||||||
int (*Database::_sqlite3_backup_pagecount) (sqlite3_backup*) = NULL;
|
|
||||||
int (*Database::_sqlite3_backup_remaining) (sqlite3_backup*) = NULL;
|
|
||||||
|
|
||||||
bool Database::sStaticInitDone = false;
|
|
||||||
bool Database::sLoadedSqliteSymbols = false;
|
|
||||||
|
|
||||||
sqlite3_tokenizer_module* Database::sFTSTokenizer = NULL;
|
sqlite3_tokenizer_module* Database::sFTSTokenizer = NULL;
|
||||||
|
|
||||||
|
|
||||||
@ -218,11 +201,6 @@ int Database::FTSNext(
|
|||||||
|
|
||||||
|
|
||||||
void Database::StaticInit() {
|
void Database::StaticInit() {
|
||||||
if (sStaticInitDone) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
sStaticInitDone = true;
|
|
||||||
|
|
||||||
sFTSTokenizer = new sqlite3_tokenizer_module;
|
sFTSTokenizer = new sqlite3_tokenizer_module;
|
||||||
sFTSTokenizer->iVersion = 0;
|
sFTSTokenizer->iVersion = 0;
|
||||||
sFTSTokenizer->xCreate = &Database::FTSCreate;
|
sFTSTokenizer->xCreate = &Database::FTSCreate;
|
||||||
@ -230,86 +208,7 @@ void Database::StaticInit() {
|
|||||||
sFTSTokenizer->xOpen = &Database::FTSOpen;
|
sFTSTokenizer->xOpen = &Database::FTSOpen;
|
||||||
sFTSTokenizer->xNext = &Database::FTSNext;
|
sFTSTokenizer->xNext = &Database::FTSNext;
|
||||||
sFTSTokenizer->xClose = &Database::FTSClose;
|
sFTSTokenizer->xClose = &Database::FTSClose;
|
||||||
|
|
||||||
#ifdef HAVE_STATIC_SQLITE
|
|
||||||
// We statically link libqsqlite.dll on windows and mac so these symbols are already
|
|
||||||
// available
|
|
||||||
_sqlite3_value_type = sqlite3_value_type;
|
|
||||||
_sqlite3_value_int64 = sqlite3_value_int64;
|
|
||||||
_sqlite3_value_text = sqlite3_value_text;
|
|
||||||
_sqlite3_result_int64 = sqlite3_result_int64;
|
|
||||||
_sqlite3_user_data = sqlite3_user_data;
|
|
||||||
|
|
||||||
_sqlite3_open = sqlite3_open;
|
|
||||||
_sqlite3_errmsg = sqlite3_errmsg;
|
|
||||||
_sqlite3_close = sqlite3_close;
|
|
||||||
_sqlite3_backup_init = sqlite3_backup_init;
|
|
||||||
_sqlite3_backup_step = sqlite3_backup_step;
|
|
||||||
_sqlite3_backup_finish = sqlite3_backup_finish;
|
|
||||||
_sqlite3_backup_pagecount = sqlite3_backup_pagecount;
|
|
||||||
_sqlite3_backup_remaining = sqlite3_backup_remaining;
|
|
||||||
|
|
||||||
sLoadedSqliteSymbols = true;
|
|
||||||
return;
|
return;
|
||||||
#else // HAVE_STATIC_SQLITE
|
|
||||||
QString plugin_path = QLibraryInfo::location(QLibraryInfo::PluginsPath) +
|
|
||||||
"/sqldrivers/libqsqlite";
|
|
||||||
|
|
||||||
QLibrary library(plugin_path);
|
|
||||||
if (!library.load()) {
|
|
||||||
qLog(Error) << "QLibrary::load() failed for " << plugin_path;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_sqlite3_value_type = reinterpret_cast<int (*) (sqlite3_value*)>(
|
|
||||||
library.resolve("sqlite3_value_type"));
|
|
||||||
_sqlite3_value_int64 = reinterpret_cast<sqlite_int64 (*) (sqlite3_value*)>(
|
|
||||||
library.resolve("sqlite3_value_int64"));
|
|
||||||
_sqlite3_value_text = reinterpret_cast<const uchar* (*) (sqlite3_value*)>(
|
|
||||||
library.resolve("sqlite3_value_text"));
|
|
||||||
_sqlite3_result_int64 = reinterpret_cast<void (*) (sqlite3_context*, sqlite_int64)>(
|
|
||||||
library.resolve("sqlite3_result_int64"));
|
|
||||||
_sqlite3_user_data = reinterpret_cast<void* (*) (sqlite3_context*)>(
|
|
||||||
library.resolve("sqlite3_user_data"));
|
|
||||||
|
|
||||||
_sqlite3_open = reinterpret_cast<int (*) (const char*, sqlite3**)>(
|
|
||||||
library.resolve("sqlite3_open"));
|
|
||||||
_sqlite3_errmsg = reinterpret_cast<const char* (*) (sqlite3*)>(
|
|
||||||
library.resolve("sqlite3_errmsg"));
|
|
||||||
_sqlite3_close = reinterpret_cast<int (*) (sqlite3*)>(
|
|
||||||
library.resolve("sqlite3_close"));
|
|
||||||
_sqlite3_backup_init = reinterpret_cast<
|
|
||||||
sqlite3_backup* (*) (sqlite3*, const char*, sqlite3*, const char*)>(
|
|
||||||
library.resolve("sqlite3_backup_init"));
|
|
||||||
_sqlite3_backup_step = reinterpret_cast<int (*) (sqlite3_backup*, int)>(
|
|
||||||
library.resolve("sqlite3_backup_step"));
|
|
||||||
_sqlite3_backup_finish = reinterpret_cast<int (*) (sqlite3_backup*)>(
|
|
||||||
library.resolve("sqlite3_backup_finish"));
|
|
||||||
_sqlite3_backup_pagecount = reinterpret_cast<int (*) (sqlite3_backup*)>(
|
|
||||||
library.resolve("sqlite3_backup_pagecount"));
|
|
||||||
_sqlite3_backup_remaining = reinterpret_cast<int (*) (sqlite3_backup*)>(
|
|
||||||
library.resolve("sqlite3_backup_remaining"));
|
|
||||||
|
|
||||||
if (!_sqlite3_value_type ||
|
|
||||||
!_sqlite3_value_int64 ||
|
|
||||||
!_sqlite3_value_text ||
|
|
||||||
!_sqlite3_result_int64 ||
|
|
||||||
!_sqlite3_user_data ||
|
|
||||||
!_sqlite3_open ||
|
|
||||||
!_sqlite3_errmsg ||
|
|
||||||
!_sqlite3_close ||
|
|
||||||
!_sqlite3_backup_init ||
|
|
||||||
!_sqlite3_backup_step ||
|
|
||||||
!_sqlite3_backup_finish ||
|
|
||||||
!_sqlite3_backup_pagecount ||
|
|
||||||
!_sqlite3_backup_remaining) {
|
|
||||||
qLog(Fatal) << "Couldn't resolve sqlite symbols. Please compile "
|
|
||||||
"Clementine with -DSTATIC_SQLITE=ON.";
|
|
||||||
sLoadedSqliteSymbols = false;
|
|
||||||
} else {
|
|
||||||
sLoadedSqliteSymbols = true;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Database::Database(Application* app, QObject* parent, const QString& database_name)
|
Database::Database(Application* app, QObject* parent, const QString& database_name)
|
||||||
@ -727,10 +626,10 @@ void Database::DoBackup() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Database::OpenDatabase(const QString& filename, sqlite3** connection) const {
|
bool Database::OpenDatabase(const QString& filename, sqlite3** connection) const {
|
||||||
int ret = _sqlite3_open(filename.toUtf8(), connection);
|
int ret = sqlite3_open(filename.toUtf8(), connection);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
if (*connection) {
|
if (*connection) {
|
||||||
const char* error_message = _sqlite3_errmsg(*connection);
|
const char* error_message = sqlite3_errmsg(*connection);
|
||||||
qLog(Error) << "Failed to open database for backup:"
|
qLog(Error) << "Failed to open database for backup:"
|
||||||
<< filename
|
<< filename
|
||||||
<< error_message;
|
<< error_message;
|
||||||
@ -753,8 +652,8 @@ void Database::BackupFile(const QString& filename) {
|
|||||||
|
|
||||||
BOOST_SCOPE_EXIT((source_connection)(dest_connection)(task_id)(app_)) {
|
BOOST_SCOPE_EXIT((source_connection)(dest_connection)(task_id)(app_)) {
|
||||||
// Harmless to call sqlite3_close() with a NULL pointer.
|
// Harmless to call sqlite3_close() with a NULL pointer.
|
||||||
_sqlite3_close(source_connection);
|
sqlite3_close(source_connection);
|
||||||
_sqlite3_close(dest_connection);
|
sqlite3_close(dest_connection);
|
||||||
app_->task_manager()->SetTaskFinished(task_id);
|
app_->task_manager()->SetTaskFinished(task_id);
|
||||||
} BOOST_SCOPE_EXIT_END
|
} BOOST_SCOPE_EXIT_END
|
||||||
|
|
||||||
@ -768,26 +667,26 @@ void Database::BackupFile(const QString& filename) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sqlite3_backup* backup = _sqlite3_backup_init(
|
sqlite3_backup* backup = sqlite3_backup_init(
|
||||||
dest_connection, "main",
|
dest_connection, "main",
|
||||||
source_connection, "main");
|
source_connection, "main");
|
||||||
if (!backup) {
|
if (!backup) {
|
||||||
const char* error_message = _sqlite3_errmsg(dest_connection);
|
const char* error_message = sqlite3_errmsg(dest_connection);
|
||||||
qLog(Error) << "Failed to start database backup:" << error_message;
|
qLog(Error) << "Failed to start database backup:" << error_message;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ret = SQLITE_OK;
|
int ret = SQLITE_OK;
|
||||||
do {
|
do {
|
||||||
ret = _sqlite3_backup_step(backup, 16);
|
ret = sqlite3_backup_step(backup, 16);
|
||||||
const int page_count = _sqlite3_backup_pagecount(backup);
|
const int page_count = sqlite3_backup_pagecount(backup);
|
||||||
app_->task_manager()->SetTaskProgress(
|
app_->task_manager()->SetTaskProgress(
|
||||||
task_id, page_count - _sqlite3_backup_remaining(backup), page_count);
|
task_id, page_count - sqlite3_backup_remaining(backup), page_count);
|
||||||
} while (ret == SQLITE_OK);
|
} while (ret == SQLITE_OK);
|
||||||
|
|
||||||
if (ret != SQLITE_DONE) {
|
if (ret != SQLITE_DONE) {
|
||||||
qLog(Error) << "Database backup failed";
|
qLog(Error) << "Database backup failed";
|
||||||
}
|
}
|
||||||
|
|
||||||
_sqlite3_backup_finish(backup);
|
sqlite3_backup_finish(backup);
|
||||||
}
|
}
|
||||||
|
@ -143,27 +143,6 @@ class Database : public QObject {
|
|||||||
void (*) (sqlite3_context*, int, sqlite3_value**),
|
void (*) (sqlite3_context*, int, sqlite3_value**),
|
||||||
void (*) (sqlite3_context*));
|
void (*) (sqlite3_context*));
|
||||||
|
|
||||||
// Sqlite3 functions. These will be loaded from the sqlite3 plugin.
|
|
||||||
static int (*_sqlite3_value_type) (sqlite3_value*);
|
|
||||||
static sqlite_int64 (*_sqlite3_value_int64) (sqlite3_value*);
|
|
||||||
static const uchar* (*_sqlite3_value_text) (sqlite3_value*);
|
|
||||||
static void (*_sqlite3_result_int64) (sqlite3_context*, sqlite_int64);
|
|
||||||
static void* (*_sqlite3_user_data) (sqlite3_context*);
|
|
||||||
|
|
||||||
// These are necessary for SQLite backups.
|
|
||||||
static int (*_sqlite3_open) (const char*, sqlite3**);
|
|
||||||
static const char* (*_sqlite3_errmsg) (sqlite3*);
|
|
||||||
static int (*_sqlite3_close) (sqlite3*);
|
|
||||||
static sqlite3_backup* (*_sqlite3_backup_init) (
|
|
||||||
sqlite3*, const char*, sqlite3*, const char*);
|
|
||||||
static int (*_sqlite3_backup_step) (sqlite3_backup*, int);
|
|
||||||
static int (*_sqlite3_backup_finish) (sqlite3_backup*);
|
|
||||||
static int (*_sqlite3_backup_pagecount) (sqlite3_backup*);
|
|
||||||
static int (*_sqlite3_backup_remaining) (sqlite3_backup*);
|
|
||||||
|
|
||||||
static bool sStaticInitDone;
|
|
||||||
static bool sLoadedSqliteSymbols;
|
|
||||||
|
|
||||||
static sqlite3_tokenizer_module* sFTSTokenizer;
|
static sqlite3_tokenizer_module* sFTSTokenizer;
|
||||||
|
|
||||||
static int FTSCreate(int argc, const char* const* argv, sqlite3_tokenizer** tokenizer);
|
static int FTSCreate(int argc, const char* const* argv, sqlite3_tokenizer** tokenizer);
|
||||||
|
@ -106,10 +106,8 @@ using boost::scoped_ptr;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Load sqlite plugin on windows and mac.
|
// Load sqlite plugin on windows and mac.
|
||||||
#ifdef HAVE_STATIC_SQLITE
|
|
||||||
#include <QtPlugin>
|
#include <QtPlugin>
|
||||||
Q_IMPORT_PLUGIN(qsqlite)
|
Q_IMPORT_PLUGIN(qsqlite)
|
||||||
#endif
|
|
||||||
|
|
||||||
void LoadTranslation(const QString& prefix, const QString& path,
|
void LoadTranslation(const QString& prefix, const QString& path,
|
||||||
const QString& language) {
|
const QString& language) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user