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})
|
||||
|
||||
add_definitions(-DQT_PLUGIN -DQT_NO_DEBUG)
|
||||
add_definitions(-DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_FTS3_PARENTHESIS)
|
||||
|
||||
add_library(sqlite STATIC sqlite3.c)
|
||||
set_target_properties(sqlite PROPERTIES COMPILE_FLAGS
|
||||
"-Wno-pointer-to-int-cast -Wno-int-to-pointer-cast")
|
||||
find_path(SQLITE_INCLUDE_DIRS sqlite3.h)
|
||||
find_library(SQLITE_LIBRARIES sqlite3)
|
||||
|
||||
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
|
||||
${SQLITE-SOURCES}
|
||||
@ -33,6 +41,6 @@ add_library(qsqlite STATIC
|
||||
${SQLITE-WIN32-RESOURCES}
|
||||
)
|
||||
target_link_libraries(qsqlite
|
||||
sqlite
|
||||
${SQLITE_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(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})
|
||||
if(STATIC_SQLITE)
|
||||
message(STATUS "Building static qsqlite plugin")
|
||||
add_subdirectory(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)
|
||||
# Build our copy of QSqlLiteDriver.
|
||||
# We do this because we can't guarantee that the driver shipped with Qt exposes the
|
||||
# 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)
|
||||
include_directories("3rdparty/qsqlite")
|
||||
|
||||
# When/if upstream accepts our patches then these options can be used to link
|
||||
# to system installed qtsingleapplication instead.
|
||||
|
@ -1192,6 +1192,7 @@ target_link_libraries(clementine_lib
|
||||
${QTSINGLECOREAPPLICATION_LIBRARIES}
|
||||
${QTIOCOMPRESSOR_LIBRARIES}
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
${SQLITE_LIBRARIES}
|
||||
z
|
||||
Qocoa
|
||||
)
|
||||
@ -1265,11 +1266,8 @@ else (APPLE)
|
||||
target_link_libraries(clementine_lib ${QXT_LIBRARIES})
|
||||
endif (APPLE)
|
||||
|
||||
# Link against the qsqlite plugin on windows and mac
|
||||
if(HAVE_STATIC_SQLITE)
|
||||
set(3RDPARTY_SQLITE_LIBRARY qsqlite)
|
||||
target_link_libraries(clementine_lib qsqlite)
|
||||
endif(HAVE_STATIC_SQLITE)
|
||||
set(3RDPARTY_SQLITE_LIBRARY qsqlite)
|
||||
target_link_libraries(clementine_lib qsqlite)
|
||||
|
||||
if (WIN32)
|
||||
target_link_libraries(clementine_lib
|
||||
|
@ -40,7 +40,6 @@
|
||||
#cmakedefine HAVE_SKYDRIVE
|
||||
#cmakedefine HAVE_SPARKLE
|
||||
#cmakedefine HAVE_SPOTIFY_DOWNLOADER
|
||||
#cmakedefine HAVE_STATIC_SQLITE
|
||||
#cmakedefine HAVE_UBUNTU_ONE
|
||||
#cmakedefine HAVE_WIIMOTEDEV
|
||||
#cmakedefine IMOBILEDEVICE_USES_UDIDS
|
||||
|
@ -25,6 +25,8 @@
|
||||
|
||||
#include <boost/scope_exit.hpp>
|
||||
|
||||
#include <sqlite3.h>
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QDir>
|
||||
#include <QLibrary>
|
||||
@ -86,25 +88,6 @@ struct sqlite3_tokenizer_cursor {
|
||||
/* 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;
|
||||
|
||||
|
||||
@ -218,11 +201,6 @@ int Database::FTSNext(
|
||||
|
||||
|
||||
void Database::StaticInit() {
|
||||
if (sStaticInitDone) {
|
||||
return;
|
||||
}
|
||||
sStaticInitDone = true;
|
||||
|
||||
sFTSTokenizer = new sqlite3_tokenizer_module;
|
||||
sFTSTokenizer->iVersion = 0;
|
||||
sFTSTokenizer->xCreate = &Database::FTSCreate;
|
||||
@ -230,86 +208,7 @@ void Database::StaticInit() {
|
||||
sFTSTokenizer->xOpen = &Database::FTSOpen;
|
||||
sFTSTokenizer->xNext = &Database::FTSNext;
|
||||
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;
|
||||
#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)
|
||||
@ -727,10 +626,10 @@ void Database::DoBackup() {
|
||||
}
|
||||
|
||||
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 (*connection) {
|
||||
const char* error_message = _sqlite3_errmsg(*connection);
|
||||
const char* error_message = sqlite3_errmsg(*connection);
|
||||
qLog(Error) << "Failed to open database for backup:"
|
||||
<< filename
|
||||
<< error_message;
|
||||
@ -753,8 +652,8 @@ void Database::BackupFile(const QString& filename) {
|
||||
|
||||
BOOST_SCOPE_EXIT((source_connection)(dest_connection)(task_id)(app_)) {
|
||||
// Harmless to call sqlite3_close() with a NULL pointer.
|
||||
_sqlite3_close(source_connection);
|
||||
_sqlite3_close(dest_connection);
|
||||
sqlite3_close(source_connection);
|
||||
sqlite3_close(dest_connection);
|
||||
app_->task_manager()->SetTaskFinished(task_id);
|
||||
} BOOST_SCOPE_EXIT_END
|
||||
|
||||
@ -768,26 +667,26 @@ void Database::BackupFile(const QString& filename) {
|
||||
return;
|
||||
}
|
||||
|
||||
sqlite3_backup* backup = _sqlite3_backup_init(
|
||||
sqlite3_backup* backup = sqlite3_backup_init(
|
||||
dest_connection, "main",
|
||||
source_connection, "main");
|
||||
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;
|
||||
return;
|
||||
}
|
||||
|
||||
int ret = SQLITE_OK;
|
||||
do {
|
||||
ret = _sqlite3_backup_step(backup, 16);
|
||||
const int page_count = _sqlite3_backup_pagecount(backup);
|
||||
ret = sqlite3_backup_step(backup, 16);
|
||||
const int page_count = sqlite3_backup_pagecount(backup);
|
||||
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);
|
||||
|
||||
if (ret != SQLITE_DONE) {
|
||||
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*));
|
||||
|
||||
// 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 int FTSCreate(int argc, const char* const* argv, sqlite3_tokenizer** tokenizer);
|
||||
|
@ -106,10 +106,8 @@ using boost::scoped_ptr;
|
||||
#endif
|
||||
|
||||
// Load sqlite plugin on windows and mac.
|
||||
#ifdef HAVE_STATIC_SQLITE
|
||||
# include <QtPlugin>
|
||||
Q_IMPORT_PLUGIN(qsqlite)
|
||||
#endif
|
||||
#include <QtPlugin>
|
||||
Q_IMPORT_PLUGIN(qsqlite)
|
||||
|
||||
void LoadTranslation(const QString& prefix, const QString& path,
|
||||
const QString& language) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user