Commit c3f6ceea authored by Hugo Beauzée-Luyssen's avatar Hugo Beauzée-Luyssen

Split main tables creation in a separated file

This will ease up the migrations, as those are the only tables we
absolutely need to keep the content of. It will be easier to just create
a new version of the model, and include it from the migration script,
instead of having the main "create table" and the migration one
parent ec3600e7
......@@ -352,4 +352,14 @@ pkgconfig_DATA = medialibrary.pc
EXTRA_DIST += medialibrary.pc \
src/database/migrations/migration3-5.sql \
src/database/migrations/migration7-8.sql \
src/database/migrations/migration13-14.sql
src/database/migrations/migration13-14.sql \
src/database/tables/File_v14.sql \
src/database/tables/File_triggers_v14.sql \
src/database/tables/Media_v14.sql \
src/database/tables/Media_triggers_v14.sql \
src/database/tables/Folder_v14.sql \
src/database/tables/Folder_triggers_v14.sql \
$(NULL)
......@@ -170,44 +170,19 @@ int64_t File::folderId()
void File::createTable( sqlite::Connection* dbConnection )
{
std::string req = "CREATE TABLE IF NOT EXISTS " + policy::FileTable::Name + "("
"id_file INTEGER PRIMARY KEY AUTOINCREMENT,"
"media_id UNSIGNED INT DEFAULT NULL,"
"playlist_id UNSIGNED INT DEFAULT NULL,"
"mrl TEXT,"
"type UNSIGNED INTEGER,"
"last_modification_date UNSIGNED INT,"
"size UNSIGNED INT,"
"folder_id UNSIGNED INTEGER,"
"is_present BOOLEAN NOT NULL DEFAULT 1,"
"is_removable BOOLEAN NOT NULL,"
"is_external BOOLEAN NOT NULL,"
"FOREIGN KEY (media_id) REFERENCES " + policy::MediaTable::Name
+ "(id_media) ON DELETE CASCADE,"
"FOREIGN KEY (playlist_id) REFERENCES " + policy::PlaylistTable::Name
+ "(id_playlist) ON DELETE CASCADE,"
"FOREIGN KEY (folder_id) REFERENCES " + policy::FolderTable::Name
+ "(id_folder) ON DELETE CASCADE,"
"UNIQUE( mrl, folder_id ) ON CONFLICT FAIL"
")";
std::string req {
#include "database/tables/File_v14.sql"
};
sqlite::Tools::executeRequest( dbConnection, req );
}
void File::createTriggers(sqlite::Connection* dbConnection)
{
std::string triggerReq = "CREATE TRIGGER IF NOT EXISTS is_folder_present AFTER UPDATE OF is_present ON "
+ policy::FolderTable::Name +
" BEGIN"
" UPDATE " + policy::FileTable::Name + " SET is_present = new.is_present WHERE folder_id = new.id_folder;"
" END";
std::string mediaIndexReq = "CREATE INDEX IF NOT EXISTS file_media_id_index ON " +
policy::FileTable::Name + "(media_id)";
std::string folderIndexReq = "CREATE INDEX IF NOT EXISTS file_folder_id_index ON " +
policy::FileTable::Name + "(folder_id)";
sqlite::Tools::executeRequest( dbConnection, triggerReq );
sqlite::Tools::executeRequest( dbConnection, mediaIndexReq );
sqlite::Tools::executeRequest( dbConnection, folderIndexReq );
const std::string reqs[] = {
#include "database/tables/File_triggers_v14.sql"
};
for ( const auto& req : reqs )
sqlite::Tools::executeRequest( dbConnection, req );
}
std::shared_ptr<File> File::createFromMedia( MediaLibraryPtr ml, int64_t mediaId, Type type, const fs::IFile& fileFs,
......
......@@ -73,48 +73,20 @@ Folder::Folder(MediaLibraryPtr ml, const std::string& path, int64_t parent, int6
void Folder::createTable( sqlite::Connection* connection)
{
std::string req = "CREATE TABLE IF NOT EXISTS " + policy::FolderTable::Name +
"("
"id_folder INTEGER PRIMARY KEY AUTOINCREMENT,"
"path TEXT,"
"parent_id UNSIGNED INTEGER,"
"is_blacklisted BOOLEAN NOT NULL DEFAULT 0,"
"device_id UNSIGNED INTEGER,"
"is_present BOOLEAN NOT NULL DEFAULT 1,"
"is_removable BOOLEAN NOT NULL,"
"FOREIGN KEY (parent_id) REFERENCES " + policy::FolderTable::Name +
"(id_folder) ON DELETE CASCADE,"
"FOREIGN KEY (device_id) REFERENCES " + policy::DeviceTable::Name +
"(id_device) ON DELETE CASCADE,"
"UNIQUE(path, device_id) ON CONFLICT FAIL"
")";
std::string exclEntryReq = "CREATE TABLE IF NOT EXISTS ExcludedEntryFolder("
"folder_id UNSIGNED INTEGER NOT NULL,"
"FOREIGN KEY (folder_id) REFERENCES " + policy::FolderTable::Name +
"(id_folder) ON DELETE CASCADE,"
"UNIQUE(folder_id) ON CONFLICT FAIL"
")";
sqlite::Tools::executeRequest( connection, req );
sqlite::Tools::executeRequest( connection, exclEntryReq );
const std::string reqs[] = {
#include "database/tables/Folder_v14.sql"
};
for ( const auto& req : reqs )
sqlite::Tools::executeRequest( connection, req );
}
void Folder::createTriggers( sqlite::Connection* connection )
{
std::string triggerReq = "CREATE TRIGGER IF NOT EXISTS is_device_present AFTER UPDATE OF is_present ON "
+ policy::DeviceTable::Name +
" WHEN old.is_present != new.is_present"
" BEGIN"
" UPDATE " + policy::FolderTable::Name + " SET is_present = new.is_present WHERE device_id = new.id_device;"
" END";
std::string deviceIndexReq = "CREATE INDEX IF NOT EXISTS folder_device_id_idx ON " +
policy::FolderTable::Name + " (device_id)";
std::string parentFolderIndexReq = "CREATE INDEX IF NOT EXISTS parent_folder_id_idx ON " +
policy::FolderTable::Name + " (parent_id)";
sqlite::Tools::executeRequest( connection, triggerReq );
sqlite::Tools::executeRequest( connection, deviceIndexReq );
sqlite::Tools::executeRequest( connection, parentFolderIndexReq );
const std::string reqs[] = {
#include "database/tables/Folder_triggers_v14.sql"
};
for ( const auto& req : reqs )
sqlite::Tools::executeRequest( connection, req );
}
std::shared_ptr<Folder> Folder::create( MediaLibraryPtr ml, const std::string& mrl,
......
......@@ -540,80 +540,21 @@ void Media::setTitleBuffered( const std::string& title )
void Media::createTable( sqlite::Connection* connection )
{
std::string req = "CREATE TABLE IF NOT EXISTS " + policy::MediaTable::Name + "("
"id_media INTEGER PRIMARY KEY AUTOINCREMENT,"
"type INTEGER,"
"subtype INTEGER NOT NULL DEFAULT " +
std::to_string( static_cast<typename std::underlying_type<IMedia::SubType>::type>(
IMedia::SubType::Unknown ) ) + ","
"duration INTEGER DEFAULT -1,"
"play_count UNSIGNED INTEGER,"
"last_played_date UNSIGNED INTEGER,"
"insertion_date UNSIGNED INTEGER,"
"release_date UNSIGNED INTEGER,"
"thumbnail_id INTEGER,"
"thumbnail_generated BOOLEAN NOT NULL DEFAULT 0,"
"title TEXT COLLATE NOCASE,"
"filename TEXT,"
"is_favorite BOOLEAN NOT NULL DEFAULT 0,"
"is_present BOOLEAN NOT NULL DEFAULT 1,"
"FOREIGN KEY(thumbnail_id) REFERENCES " + policy::ThumbnailTable::Name
+ "(id_thumbnail)"
")";
const std::string vtableReq = "CREATE VIRTUAL TABLE IF NOT EXISTS "
+ policy::MediaTable::Name + "Fts USING FTS3("
"title,"
"labels"
")";
sqlite::Tools::executeRequest( connection, req );
sqlite::Tools::executeRequest( connection, vtableReq );
std::string reqs[] = {
#include "database/tables/Media_v14.sql"
};
for ( const auto& req : reqs )
sqlite::Tools::executeRequest( connection, req );
}
void Media::createTriggers( sqlite::Connection* connection )
{
const std::string indexReq = "CREATE INDEX IF NOT EXISTS index_last_played_date ON "
+ policy::MediaTable::Name + "(last_played_date DESC)";
static const std::string triggerReq = "CREATE TRIGGER IF NOT EXISTS has_files_present AFTER UPDATE OF "
"is_present ON " + policy::FileTable::Name +
" BEGIN "
" UPDATE " + policy::MediaTable::Name + " SET is_present="
"(SELECT EXISTS("
"SELECT id_file FROM " + policy::FileTable::Name +
" WHERE media_id=new.media_id AND is_present != 0 LIMIT 1"
") )"
"WHERE id_media=new.media_id;"
" END;";
static const std::string triggerReq2 = "CREATE TRIGGER IF NOT EXISTS cascade_file_deletion AFTER DELETE ON "
+ policy::FileTable::Name +
" BEGIN "
" DELETE FROM " + policy::MediaTable::Name + " WHERE "
"(SELECT COUNT(id_file) FROM " + policy::FileTable::Name + " WHERE media_id=old.media_id) = 0"
" AND id_media=old.media_id;"
" END;";
static const std::string vtableInsertTrigger = "CREATE TRIGGER IF NOT EXISTS insert_media_fts"
" AFTER INSERT ON " + policy::MediaTable::Name +
" BEGIN"
" INSERT INTO " + policy::MediaTable::Name + "Fts(rowid,title,labels) VALUES(new.id_media, new.title, '');"
" END";
static const std::string vtableDeleteTrigger = "CREATE TRIGGER IF NOT EXISTS delete_media_fts"
" BEFORE DELETE ON " + policy::MediaTable::Name +
" BEGIN"
" DELETE FROM " + policy::MediaTable::Name + "Fts WHERE rowid = old.id_media;"
" END";
static const std::string vtableUpdateTitleTrigger2 = "CREATE TRIGGER IF NOT EXISTS update_media_title_fts"
" AFTER UPDATE OF title ON " + policy::MediaTable::Name +
" BEGIN"
" UPDATE " + policy::MediaTable::Name + "Fts SET title = new.title WHERE rowid = new.id_media;"
" END";
sqlite::Tools::executeRequest( connection, indexReq );
sqlite::Tools::executeRequest( connection, triggerReq );
sqlite::Tools::executeRequest( connection, triggerReq2 );
sqlite::Tools::executeRequest( connection, vtableInsertTrigger );
sqlite::Tools::executeRequest( connection, vtableDeleteTrigger );
sqlite::Tools::executeRequest( connection, vtableUpdateTitleTrigger2 );
const std::string reqs[] = {
#include "database/tables/Media_triggers_v14.sql"
};
for ( const auto& req : reqs )
sqlite::Tools::executeRequest( connection, req );
}
bool Media::addLabel( LabelPtr label )
......
"CREATE TRIGGER IF NOT EXISTS is_folder_present AFTER UPDATE OF is_present ON "
+ policy::FolderTable::Name +
" BEGIN"
" UPDATE " + policy::FileTable::Name + " SET is_present = new.is_present WHERE folder_id = new.id_folder;"
" END",
"CREATE INDEX IF NOT EXISTS file_media_id_index ON " +
policy::FileTable::Name + "(media_id)",
"CREATE INDEX IF NOT EXISTS file_folder_id_index ON " +
policy::FileTable::Name + "(folder_id)",
"CREATE TABLE IF NOT EXISTS " + policy::FileTable::Name +
"("
"id_file INTEGER PRIMARY KEY AUTOINCREMENT,"
"media_id UNSIGNED INT DEFAULT NULL,"
"playlist_id UNSIGNED INT DEFAULT NULL,"
"mrl TEXT,"
"type UNSIGNED INTEGER,"
"last_modification_date UNSIGNED INT,"
"size UNSIGNED INT,"
"folder_id UNSIGNED INTEGER,"
"is_present BOOLEAN NOT NULL DEFAULT 1,"
"is_removable BOOLEAN NOT NULL,"
"is_external BOOLEAN NOT NULL,"
"FOREIGN KEY (media_id) REFERENCES " + policy::MediaTable::Name
+ "(id_media) ON DELETE CASCADE,"
"FOREIGN KEY (playlist_id) REFERENCES " + policy::PlaylistTable::Name
+ "(id_playlist) ON DELETE CASCADE,"
"FOREIGN KEY (folder_id) REFERENCES " + policy::FolderTable::Name
+ "(id_folder) ON DELETE CASCADE,"
"UNIQUE( mrl, folder_id ) ON CONFLICT FAIL"
")"
"CREATE TRIGGER IF NOT EXISTS is_device_present AFTER UPDATE OF is_present ON "
+ policy::DeviceTable::Name +
" WHEN old.is_present != new.is_present"
" BEGIN"
" UPDATE " + policy::FolderTable::Name + " SET is_present = new.is_present WHERE device_id = new.id_device;"
" END",
"CREATE INDEX IF NOT EXISTS folder_device_id_idx ON " +
policy::FolderTable::Name + " (device_id)",
"CREATE INDEX IF NOT EXISTS parent_folder_id_idx ON " +
policy::FolderTable::Name + " (parent_id)"
"CREATE TABLE IF NOT EXISTS " + policy::FolderTable::Name +
"("
"id_folder INTEGER PRIMARY KEY AUTOINCREMENT,"
"path TEXT,"
"parent_id UNSIGNED INTEGER,"
"is_blacklisted BOOLEAN NOT NULL DEFAULT 0,"
"device_id UNSIGNED INTEGER,"
"is_present BOOLEAN NOT NULL DEFAULT 1,"
"is_removable BOOLEAN NOT NULL,"
"FOREIGN KEY (parent_id) REFERENCES " + policy::FolderTable::Name +
"(id_folder) ON DELETE CASCADE,"
"FOREIGN KEY (device_id) REFERENCES " + policy::DeviceTable::Name +
"(id_device) ON DELETE CASCADE,"
"UNIQUE(path, device_id) ON CONFLICT FAIL"
")",
"CREATE TABLE IF NOT EXISTS ExcludedEntryFolder"
"("
"folder_id UNSIGNED INTEGER NOT NULL,"
"FOREIGN KEY (folder_id) REFERENCES " + policy::FolderTable::Name +
"(id_folder) ON DELETE CASCADE,"
"UNIQUE(folder_id) ON CONFLICT FAIL"
")"
"CREATE INDEX IF NOT EXISTS index_last_played_date ON "
+ policy::MediaTable::Name + "(last_played_date DESC)",
"CREATE TRIGGER IF NOT EXISTS has_files_present AFTER UPDATE OF "
"is_present ON " + policy::FileTable::Name + " "
"BEGIN "
"UPDATE " + policy::MediaTable::Name + " SET is_present="
"(SELECT EXISTS("
"SELECT id_file FROM " + policy::FileTable::Name +
" WHERE media_id=new.media_id AND is_present != 0 LIMIT 1"
") )"
"WHERE id_media=new.media_id;"
"END;",
"CREATE TRIGGER IF NOT EXISTS cascade_file_deletion AFTER DELETE ON "
+ policy::FileTable::Name +
" BEGIN "
" DELETE FROM " + policy::MediaTable::Name + " WHERE "
"(SELECT COUNT(id_file) FROM " + policy::FileTable::Name +
" WHERE media_id=old.media_id) = 0"
" AND id_media=old.media_id;"
" END;",
"CREATE TRIGGER IF NOT EXISTS insert_media_fts"
" AFTER INSERT ON " + policy::MediaTable::Name +
" BEGIN"
" INSERT INTO " + policy::MediaTable::Name + "Fts(rowid,title,labels) VALUES(new.id_media, new.title, '');"
" END",
"CREATE TRIGGER IF NOT EXISTS delete_media_fts"
" BEFORE DELETE ON " + policy::MediaTable::Name +
" BEGIN"
" DELETE FROM " + policy::MediaTable::Name + "Fts WHERE rowid = old.id_media;"
" END",
"CREATE TRIGGER IF NOT EXISTS update_media_title_fts"
" AFTER UPDATE OF title ON " + policy::MediaTable::Name +
" BEGIN"
" UPDATE " + policy::MediaTable::Name + "Fts SET title = new.title WHERE rowid = new.id_media;"
" END",
"CREATE TABLE IF NOT EXISTS " + policy::MediaTable::Name + "("
"id_media INTEGER PRIMARY KEY AUTOINCREMENT,"
"type INTEGER,"
"subtype INTEGER NOT NULL DEFAULT " +
std::to_string( static_cast<typename std::underlying_type<IMedia::SubType>::type>(
IMedia::SubType::Unknown ) ) + ","
"duration INTEGER DEFAULT -1,"
"play_count UNSIGNED INTEGER,"
"last_played_date UNSIGNED INTEGER,"
"insertion_date UNSIGNED INTEGER,"
"release_date UNSIGNED INTEGER,"
"thumbnail_id INTEGER,"
"thumbnail_generated BOOLEAN NOT NULL DEFAULT 0,"
"title TEXT COLLATE NOCASE,"
"filename TEXT,"
"is_favorite BOOLEAN NOT NULL DEFAULT 0,"
"is_present BOOLEAN NOT NULL DEFAULT 1,"
"FOREIGN KEY(thumbnail_id) REFERENCES " + policy::ThumbnailTable::Name
+ "(id_thumbnail)"
")",
"CREATE VIRTUAL TABLE IF NOT EXISTS "
+ policy::MediaTable::Name + "Fts USING FTS3("
"title,"
"labels"
")"
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment