Merge pull request #303 from chme/dbinit
Move db init into its own source file
This commit is contained in:
commit
f0e2218a8c
|
@ -79,6 +79,7 @@ forked_daapd_LDADD = -lrt \
|
||||||
|
|
||||||
forked_daapd_SOURCES = main.c \
|
forked_daapd_SOURCES = main.c \
|
||||||
db.c db.h \
|
db.c db.h \
|
||||||
|
db_init.c db_init.h \
|
||||||
db_upgrade.c db_upgrade.h \
|
db_upgrade.c db_upgrade.h \
|
||||||
logger.c logger.h \
|
logger.c logger.h \
|
||||||
conffile.c conffile.h \
|
conffile.c conffile.h \
|
||||||
|
|
397
src/db.c
397
src/db.c
|
@ -44,6 +44,7 @@
|
||||||
#include "cache.h"
|
#include "cache.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "db.h"
|
#include "db.h"
|
||||||
|
#include "db_init.h"
|
||||||
#include "db_upgrade.h"
|
#include "db_upgrade.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -4808,398 +4809,6 @@ db_perthread_deinit(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define T_ADMIN \
|
|
||||||
"CREATE TABLE IF NOT EXISTS admin(" \
|
|
||||||
" key VARCHAR(32) NOT NULL," \
|
|
||||||
" value VARCHAR(32) NOT NULL" \
|
|
||||||
");"
|
|
||||||
|
|
||||||
#define T_FILES \
|
|
||||||
"CREATE TABLE IF NOT EXISTS files (" \
|
|
||||||
" id INTEGER PRIMARY KEY NOT NULL," \
|
|
||||||
" path VARCHAR(4096) NOT NULL," \
|
|
||||||
" fname VARCHAR(255) NOT NULL," \
|
|
||||||
" title VARCHAR(1024) DEFAULT NULL COLLATE DAAP," \
|
|
||||||
" artist VARCHAR(1024) DEFAULT NULL COLLATE DAAP," \
|
|
||||||
" album VARCHAR(1024) NOT NULL COLLATE DAAP," \
|
|
||||||
" genre VARCHAR(255) DEFAULT NULL COLLATE DAAP," \
|
|
||||||
" comment VARCHAR(4096) DEFAULT NULL COLLATE DAAP," \
|
|
||||||
" type VARCHAR(255) DEFAULT NULL COLLATE DAAP," \
|
|
||||||
" composer VARCHAR(1024) DEFAULT NULL COLLATE DAAP," \
|
|
||||||
" orchestra VARCHAR(1024) DEFAULT NULL COLLATE DAAP," \
|
|
||||||
" conductor VARCHAR(1024) DEFAULT NULL COLLATE DAAP," \
|
|
||||||
" grouping VARCHAR(1024) DEFAULT NULL COLLATE DAAP," \
|
|
||||||
" url VARCHAR(1024) DEFAULT NULL," \
|
|
||||||
" bitrate INTEGER DEFAULT 0," \
|
|
||||||
" samplerate INTEGER DEFAULT 0," \
|
|
||||||
" song_length INTEGER DEFAULT 0," \
|
|
||||||
" file_size INTEGER DEFAULT 0," \
|
|
||||||
" year INTEGER DEFAULT 0," \
|
|
||||||
" track INTEGER DEFAULT 0," \
|
|
||||||
" total_tracks INTEGER DEFAULT 0," \
|
|
||||||
" disc INTEGER DEFAULT 0," \
|
|
||||||
" total_discs INTEGER DEFAULT 0," \
|
|
||||||
" bpm INTEGER DEFAULT 0," \
|
|
||||||
" compilation INTEGER DEFAULT 0," \
|
|
||||||
" artwork INTEGER DEFAULT 0," \
|
|
||||||
" rating INTEGER DEFAULT 0," \
|
|
||||||
" play_count INTEGER DEFAULT 0," \
|
|
||||||
" seek INTEGER DEFAULT 0," \
|
|
||||||
" data_kind INTEGER DEFAULT 0," \
|
|
||||||
" item_kind INTEGER DEFAULT 0," \
|
|
||||||
" description INTEGER DEFAULT 0," \
|
|
||||||
" time_added INTEGER DEFAULT 0," \
|
|
||||||
" time_modified INTEGER DEFAULT 0," \
|
|
||||||
" time_played INTEGER DEFAULT 0," \
|
|
||||||
" db_timestamp INTEGER DEFAULT 0," \
|
|
||||||
" disabled INTEGER DEFAULT 0," \
|
|
||||||
" sample_count INTEGER DEFAULT 0," \
|
|
||||||
" codectype VARCHAR(5) DEFAULT NULL," \
|
|
||||||
" idx INTEGER NOT NULL," \
|
|
||||||
" has_video INTEGER DEFAULT 0," \
|
|
||||||
" contentrating INTEGER DEFAULT 0," \
|
|
||||||
" bits_per_sample INTEGER DEFAULT 0," \
|
|
||||||
" album_artist VARCHAR(1024) NOT NULL COLLATE DAAP," \
|
|
||||||
" media_kind INTEGER NOT NULL," \
|
|
||||||
" tv_series_name VARCHAR(1024) DEFAULT NULL COLLATE DAAP," \
|
|
||||||
" tv_episode_num_str VARCHAR(1024) DEFAULT NULL COLLATE DAAP," \
|
|
||||||
" tv_network_name VARCHAR(1024) DEFAULT NULL COLLATE DAAP," \
|
|
||||||
" tv_episode_sort INTEGER NOT NULL," \
|
|
||||||
" tv_season_num INTEGER NOT NULL," \
|
|
||||||
" songartistid INTEGER NOT NULL," \
|
|
||||||
" songalbumid INTEGER NOT NULL," \
|
|
||||||
" title_sort VARCHAR(1024) DEFAULT NULL COLLATE DAAP," \
|
|
||||||
" artist_sort VARCHAR(1024) DEFAULT NULL COLLATE DAAP," \
|
|
||||||
" album_sort VARCHAR(1024) DEFAULT NULL COLLATE DAAP," \
|
|
||||||
" composer_sort VARCHAR(1024) DEFAULT NULL COLLATE DAAP," \
|
|
||||||
" album_artist_sort VARCHAR(1024) DEFAULT NULL COLLATE DAAP," \
|
|
||||||
" virtual_path VARCHAR(4096) DEFAULT NULL," \
|
|
||||||
" directory_id INTEGER DEFAULT 0," \
|
|
||||||
" date_released INTEGER DEFAULT 0" \
|
|
||||||
");"
|
|
||||||
|
|
||||||
#define T_PL \
|
|
||||||
"CREATE TABLE IF NOT EXISTS playlists (" \
|
|
||||||
" id INTEGER PRIMARY KEY NOT NULL," \
|
|
||||||
" title VARCHAR(255) NOT NULL COLLATE DAAP," \
|
|
||||||
" type INTEGER NOT NULL," \
|
|
||||||
" query VARCHAR(1024)," \
|
|
||||||
" db_timestamp INTEGER NOT NULL," \
|
|
||||||
" disabled INTEGER DEFAULT 0," \
|
|
||||||
" path VARCHAR(4096)," \
|
|
||||||
" idx INTEGER NOT NULL," \
|
|
||||||
" special_id INTEGER DEFAULT 0," \
|
|
||||||
" virtual_path VARCHAR(4096)," \
|
|
||||||
" parent_id INTEGER DEFAULT 0," \
|
|
||||||
" directory_id INTEGER DEFAULT 0" \
|
|
||||||
");"
|
|
||||||
|
|
||||||
#define T_PLITEMS \
|
|
||||||
"CREATE TABLE IF NOT EXISTS playlistitems (" \
|
|
||||||
" id INTEGER PRIMARY KEY NOT NULL," \
|
|
||||||
" playlistid INTEGER NOT NULL," \
|
|
||||||
" filepath VARCHAR(4096) NOT NULL" \
|
|
||||||
");"
|
|
||||||
|
|
||||||
#define T_GROUPS \
|
|
||||||
"CREATE TABLE IF NOT EXISTS groups (" \
|
|
||||||
" id INTEGER PRIMARY KEY NOT NULL," \
|
|
||||||
" type INTEGER NOT NULL," \
|
|
||||||
" name VARCHAR(1024) NOT NULL COLLATE DAAP," \
|
|
||||||
" persistentid INTEGER NOT NULL," \
|
|
||||||
"CONSTRAINT groups_type_unique_persistentid UNIQUE (type, persistentid)" \
|
|
||||||
");"
|
|
||||||
|
|
||||||
#define T_PAIRINGS \
|
|
||||||
"CREATE TABLE IF NOT EXISTS pairings(" \
|
|
||||||
" remote VARCHAR(64) PRIMARY KEY NOT NULL," \
|
|
||||||
" name VARCHAR(255) NOT NULL," \
|
|
||||||
" guid VARCHAR(16) NOT NULL" \
|
|
||||||
");"
|
|
||||||
|
|
||||||
#define T_SPEAKERS \
|
|
||||||
"CREATE TABLE IF NOT EXISTS speakers(" \
|
|
||||||
" id INTEGER PRIMARY KEY NOT NULL," \
|
|
||||||
" selected INTEGER NOT NULL," \
|
|
||||||
" volume INTEGER NOT NULL," \
|
|
||||||
" name VARCHAR(255) DEFAULT NULL" \
|
|
||||||
");"
|
|
||||||
|
|
||||||
#define T_INOTIFY \
|
|
||||||
"CREATE TABLE IF NOT EXISTS inotify (" \
|
|
||||||
" wd INTEGER PRIMARY KEY NOT NULL," \
|
|
||||||
" cookie INTEGER NOT NULL," \
|
|
||||||
" path VARCHAR(4096) NOT NULL" \
|
|
||||||
");"
|
|
||||||
|
|
||||||
#define T_DIRECTORIES \
|
|
||||||
"CREATE TABLE IF NOT EXISTS directories (" \
|
|
||||||
" id INTEGER PRIMARY KEY NOT NULL," \
|
|
||||||
" virtual_path VARCHAR(4096) NOT NULL," \
|
|
||||||
" db_timestamp INTEGER DEFAULT 0," \
|
|
||||||
" disabled INTEGER DEFAULT 0," \
|
|
||||||
" parent_id INTEGER DEFAULT 0" \
|
|
||||||
");"
|
|
||||||
|
|
||||||
#define TRG_GROUPS_INSERT_FILES \
|
|
||||||
"CREATE TRIGGER update_groups_new_file AFTER INSERT ON files FOR EACH ROW" \
|
|
||||||
" BEGIN" \
|
|
||||||
" INSERT OR IGNORE INTO groups (type, name, persistentid) VALUES (1, NEW.album, NEW.songalbumid);" \
|
|
||||||
" INSERT OR IGNORE INTO groups (type, name, persistentid) VALUES (2, NEW.album_artist, NEW.songartistid);" \
|
|
||||||
" END;"
|
|
||||||
|
|
||||||
#define TRG_GROUPS_UPDATE_FILES \
|
|
||||||
"CREATE TRIGGER update_groups_update_file AFTER UPDATE OF songalbumid ON files FOR EACH ROW" \
|
|
||||||
" BEGIN" \
|
|
||||||
" INSERT OR IGNORE INTO groups (type, name, persistentid) VALUES (1, NEW.album, NEW.songalbumid);" \
|
|
||||||
" INSERT OR IGNORE INTO groups (type, name, persistentid) VALUES (2, NEW.album_artist, NEW.songartistid);" \
|
|
||||||
" END;"
|
|
||||||
|
|
||||||
#define Q_PL1 \
|
|
||||||
"INSERT INTO playlists (id, title, type, query, db_timestamp, path, idx, special_id)" \
|
|
||||||
" VALUES(1, 'Library', 0, '1 = 1', 0, '', 0, 0);"
|
|
||||||
|
|
||||||
#define Q_PL2 \
|
|
||||||
"INSERT INTO playlists (id, title, type, query, db_timestamp, path, idx, special_id)" \
|
|
||||||
" VALUES(2, 'Music', 0, 'f.media_kind = 1', 0, '', 0, 6);"
|
|
||||||
|
|
||||||
#define Q_PL3 \
|
|
||||||
"INSERT INTO playlists (id, title, type, query, db_timestamp, path, idx, special_id)" \
|
|
||||||
" VALUES(3, 'Movies', 0, 'f.media_kind = 2', 0, '', 0, 4);"
|
|
||||||
|
|
||||||
#define Q_PL4 \
|
|
||||||
"INSERT INTO playlists (id, title, type, query, db_timestamp, path, idx, special_id)" \
|
|
||||||
" VALUES(4, 'TV Shows', 0, 'f.media_kind = 64', 0, '', 0, 5);"
|
|
||||||
|
|
||||||
#define Q_PL5 \
|
|
||||||
"INSERT INTO playlists (id, title, type, query, db_timestamp, path, idx, special_id)" \
|
|
||||||
" VALUES(5, 'Podcasts', 0, 'f.media_kind = 4', 0, '', 0, 1);"
|
|
||||||
|
|
||||||
#define Q_PL6 \
|
|
||||||
"INSERT INTO playlists (id, title, type, query, db_timestamp, path, idx, special_id)" \
|
|
||||||
" VALUES(6, 'Audiobooks', 0, 'f.media_kind = 8', 0, '', 0, 7);"
|
|
||||||
|
|
||||||
/* These are the remaining automatically-created iTunes playlists, but
|
|
||||||
* their query is unknown
|
|
||||||
" VALUES(6, 'iTunes U', 0, 'media_kind = 256', 0, '', 0, 13);"
|
|
||||||
" VALUES(8, 'Purchased', 0, 'media_kind = 1024', 0, '', 0, 8);"
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#define Q_DIR1 \
|
|
||||||
"INSERT INTO directories (id, virtual_path, db_timestamp, disabled, parent_id)" \
|
|
||||||
" VALUES (1, '/', 0, 0, 0);"
|
|
||||||
#define Q_DIR2 \
|
|
||||||
"INSERT INTO directories (id, virtual_path, db_timestamp, disabled, parent_id)" \
|
|
||||||
" VALUES (2, '/file:', 0, 0, 1);"
|
|
||||||
#define Q_DIR3 \
|
|
||||||
"INSERT INTO directories (id, virtual_path, db_timestamp, disabled, parent_id)" \
|
|
||||||
" VALUES (3, '/http:', 0, 0, 1);"
|
|
||||||
#define Q_DIR4 \
|
|
||||||
"INSERT INTO directories (id, virtual_path, db_timestamp, disabled, parent_id)" \
|
|
||||||
" VALUES (4, '/spotify:', 0, 4294967296, 1);"
|
|
||||||
|
|
||||||
/* Rule of thumb: Will the current version of forked-daapd work with the new
|
|
||||||
* version of the database? If yes, then it is a minor upgrade, if no, then it
|
|
||||||
* is a major upgrade. In other words minor version upgrades permit downgrading
|
|
||||||
* forked-daapd after the database was upgraded. */
|
|
||||||
#define SCHEMA_VERSION_MAJOR 19
|
|
||||||
#define SCHEMA_VERSION_MINOR 00
|
|
||||||
#define Q_SCVER_MAJOR \
|
|
||||||
"INSERT INTO admin (key, value) VALUES ('schema_version_major', '19');"
|
|
||||||
#define Q_SCVER_MINOR \
|
|
||||||
"INSERT INTO admin (key, value) VALUES ('schema_version_minor', '00');"
|
|
||||||
|
|
||||||
struct db_init_query {
|
|
||||||
char *query;
|
|
||||||
char *desc;
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct db_init_query db_init_table_queries[] =
|
|
||||||
{
|
|
||||||
{ T_ADMIN, "create table admin" },
|
|
||||||
{ T_FILES, "create table files" },
|
|
||||||
{ T_PL, "create table playlists" },
|
|
||||||
{ T_PLITEMS, "create table playlistitems" },
|
|
||||||
{ T_GROUPS, "create table groups" },
|
|
||||||
{ T_PAIRINGS, "create table pairings" },
|
|
||||||
{ T_SPEAKERS, "create table speakers" },
|
|
||||||
{ T_INOTIFY, "create table inotify" },
|
|
||||||
{ T_DIRECTORIES, "create table directories" },
|
|
||||||
|
|
||||||
{ TRG_GROUPS_INSERT_FILES, "create trigger update_groups_new_file" },
|
|
||||||
{ TRG_GROUPS_UPDATE_FILES, "create trigger update_groups_update_file" },
|
|
||||||
|
|
||||||
{ Q_PL1, "create default playlist" },
|
|
||||||
{ Q_PL2, "create default smart playlist 'Music'" },
|
|
||||||
{ Q_PL3, "create default smart playlist 'Movies'" },
|
|
||||||
{ Q_PL4, "create default smart playlist 'TV Shows'" },
|
|
||||||
{ Q_PL5, "create default smart playlist 'Podcasts'" },
|
|
||||||
{ Q_PL6, "create default smart playlist 'Audiobooks'" },
|
|
||||||
{ Q_DIR1, "create default root directory '/'" },
|
|
||||||
{ Q_DIR2, "create default base directory '/file:'" },
|
|
||||||
{ Q_DIR3, "create default base directory '/http:'" },
|
|
||||||
{ Q_DIR4, "create default base directory '/spotify:'" },
|
|
||||||
|
|
||||||
{ Q_SCVER_MAJOR, "set schema version major" },
|
|
||||||
{ Q_SCVER_MINOR, "set schema version minor" },
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* Indices must be prefixed with idx_ for db_drop_indices() to id them */
|
|
||||||
|
|
||||||
#define I_RESCAN \
|
|
||||||
"CREATE INDEX IF NOT EXISTS idx_rescan ON files(path, db_timestamp);"
|
|
||||||
|
|
||||||
#define I_SONGARTISTID \
|
|
||||||
"CREATE INDEX IF NOT EXISTS idx_sari ON files(songartistid);"
|
|
||||||
|
|
||||||
/* Used by Q_GROUP_ALBUMS */
|
|
||||||
#define I_SONGALBUMID \
|
|
||||||
"CREATE INDEX IF NOT EXISTS idx_sali ON files(songalbumid, disabled, media_kind, album_sort, disc, track);"
|
|
||||||
|
|
||||||
/* Used by Q_GROUP_ARTISTS */
|
|
||||||
#define I_STATEMKINDSARI \
|
|
||||||
"CREATE INDEX IF NOT EXISTS idx_state_mkind_sari ON files(disabled, media_kind, songartistid);"
|
|
||||||
|
|
||||||
#define I_STATEMKINDSALI \
|
|
||||||
"CREATE INDEX IF NOT EXISTS idx_state_mkind_sali ON files(disabled, media_kind, songalbumid);"
|
|
||||||
|
|
||||||
#define I_ARTIST \
|
|
||||||
"CREATE INDEX IF NOT EXISTS idx_artist ON files(artist, artist_sort);"
|
|
||||||
|
|
||||||
#define I_ALBUMARTIST \
|
|
||||||
"CREATE INDEX IF NOT EXISTS idx_albumartist ON files(album_artist, album_artist_sort);"
|
|
||||||
|
|
||||||
/* Used by Q_BROWSE_COMPOSERS */
|
|
||||||
#define I_COMPOSER \
|
|
||||||
"CREATE INDEX IF NOT EXISTS idx_composer ON files(disabled, media_kind, composer_sort);"
|
|
||||||
|
|
||||||
/* Used by Q_BROWSE_GENRES */
|
|
||||||
#define I_GENRE \
|
|
||||||
"CREATE INDEX IF NOT EXISTS idx_genre ON files(disabled, media_kind, genre);"
|
|
||||||
|
|
||||||
/* Used by Q_PLITEMS for smart playlists */
|
|
||||||
#define I_TITLE \
|
|
||||||
"CREATE INDEX IF NOT EXISTS idx_title ON files(disabled, media_kind, title_sort);"
|
|
||||||
|
|
||||||
#define I_ALBUM \
|
|
||||||
"CREATE INDEX IF NOT EXISTS idx_album ON files(album, album_sort);"
|
|
||||||
|
|
||||||
#define I_FILELIST \
|
|
||||||
"CREATE INDEX IF NOT EXISTS idx_filelist ON files(disabled, virtual_path, time_modified);"
|
|
||||||
|
|
||||||
#define I_FILE_DIR \
|
|
||||||
"CREATE INDEX IF NOT EXISTS idx_file_dir ON files(disabled, directory_id);"
|
|
||||||
|
|
||||||
#define I_PL_PATH \
|
|
||||||
"CREATE INDEX IF NOT EXISTS idx_pl_path ON playlists(path);"
|
|
||||||
|
|
||||||
#define I_PL_DISABLED \
|
|
||||||
"CREATE INDEX IF NOT EXISTS idx_pl_disabled ON playlists(disabled, type, virtual_path, db_timestamp);"
|
|
||||||
|
|
||||||
#define I_PL_DIR \
|
|
||||||
"CREATE INDEX IF NOT EXISTS idx_pl_dir ON files(disabled, directory_id);"
|
|
||||||
|
|
||||||
#define I_FILEPATH \
|
|
||||||
"CREATE INDEX IF NOT EXISTS idx_filepath ON playlistitems(filepath ASC);"
|
|
||||||
|
|
||||||
#define I_PLITEMID \
|
|
||||||
"CREATE INDEX IF NOT EXISTS idx_playlistid ON playlistitems(playlistid, filepath);"
|
|
||||||
|
|
||||||
#define I_GRP_PERSIST \
|
|
||||||
"CREATE INDEX IF NOT EXISTS idx_grp_persist ON groups(persistentid);"
|
|
||||||
|
|
||||||
#define I_PAIRING \
|
|
||||||
"CREATE INDEX IF NOT EXISTS idx_pairingguid ON pairings(guid);"
|
|
||||||
|
|
||||||
#define I_DIR_VPATH \
|
|
||||||
"CREATE INDEX IF NOT EXISTS idx_dir_vpath ON directories(disabled, virtual_path);"
|
|
||||||
|
|
||||||
#define I_DIR_PARENT \
|
|
||||||
"CREATE INDEX IF NOT EXISTS idx_dir_parentid ON directories(parent_id);"
|
|
||||||
|
|
||||||
static const struct db_init_query db_init_index_queries[] =
|
|
||||||
{
|
|
||||||
{ I_RESCAN, "create rescan index" },
|
|
||||||
{ I_SONGARTISTID, "create songartistid index" },
|
|
||||||
{ I_SONGALBUMID, "create songalbumid index" },
|
|
||||||
{ I_STATEMKINDSARI, "create state/mkind/sari index" },
|
|
||||||
{ I_STATEMKINDSALI, "create state/mkind/sali index" },
|
|
||||||
|
|
||||||
{ I_ARTIST, "create artist index" },
|
|
||||||
{ I_ALBUMARTIST, "create album_artist index" },
|
|
||||||
{ I_COMPOSER, "create composer index" },
|
|
||||||
{ I_GENRE, "create genre index" },
|
|
||||||
{ I_TITLE, "create title index" },
|
|
||||||
{ I_ALBUM, "create album index" },
|
|
||||||
{ I_FILELIST, "create filelist index" },
|
|
||||||
{ I_FILE_DIR, "create file dir index" },
|
|
||||||
|
|
||||||
{ I_PL_PATH, "create playlist path index" },
|
|
||||||
{ I_PL_DISABLED, "create playlist state index" },
|
|
||||||
{ I_PL_DIR, "create playlist dir index" },
|
|
||||||
|
|
||||||
{ I_FILEPATH, "create file path index" },
|
|
||||||
{ I_PLITEMID, "create playlist id index" },
|
|
||||||
|
|
||||||
{ I_GRP_PERSIST, "create groups persistentid index" },
|
|
||||||
|
|
||||||
{ I_PAIRING, "create pairing guid index" },
|
|
||||||
|
|
||||||
{ I_DIR_VPATH, "create directories disabled_virtualpath index" },
|
|
||||||
{ I_DIR_PARENT, "create directories parentid index" },
|
|
||||||
};
|
|
||||||
|
|
||||||
static int
|
|
||||||
db_create_indices(void)
|
|
||||||
{
|
|
||||||
char *errmsg;
|
|
||||||
int i;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
for (i = 0; i < (sizeof(db_init_index_queries) / sizeof(db_init_index_queries[0])); i++)
|
|
||||||
{
|
|
||||||
DPRINTF(E_DBG, L_DB, "DB init index query: %s\n", db_init_index_queries[i].desc);
|
|
||||||
|
|
||||||
ret = sqlite3_exec(hdl, db_init_index_queries[i].query, NULL, NULL, &errmsg);
|
|
||||||
if (ret != SQLITE_OK)
|
|
||||||
{
|
|
||||||
DPRINTF(E_FATAL, L_DB, "DB init error: %s\n", errmsg);
|
|
||||||
|
|
||||||
sqlite3_free(errmsg);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
static int
|
|
||||||
db_create_tables(void)
|
|
||||||
{
|
|
||||||
char *errmsg;
|
|
||||||
int i;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
for (i = 0; i < (sizeof(db_init_table_queries) / sizeof(db_init_table_queries[0])); i++)
|
|
||||||
{
|
|
||||||
DPRINTF(E_DBG, L_DB, "DB init table query: %s\n", db_init_table_queries[i].desc);
|
|
||||||
|
|
||||||
ret = sqlite3_exec(hdl, db_init_table_queries[i].query, NULL, NULL, &errmsg);
|
|
||||||
if (ret != SQLITE_OK)
|
|
||||||
{
|
|
||||||
DPRINTF(E_FATAL, L_DB, "DB init error: %s\n", errmsg);
|
|
||||||
|
|
||||||
sqlite3_free(errmsg);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = db_create_indices();
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -5278,7 +4887,7 @@ db_check_version(void)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = db_create_indices();
|
ret = db_init_indices(hdl);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_DB, "Database upgrade errored out, rolling back changes ...\n");
|
DPRINTF(E_LOG, L_DB, "Database upgrade errored out, rolling back changes ...\n");
|
||||||
|
@ -5373,7 +4982,7 @@ db_init(void)
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_DB, "Could not check database version, trying DB init\n");
|
DPRINTF(E_LOG, L_DB, "Could not check database version, trying DB init\n");
|
||||||
|
|
||||||
ret = db_create_tables();
|
ret = db_init_tables(hdl);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
DPRINTF(E_FATAL, L_DB, "Could not create tables\n");
|
DPRINTF(E_FATAL, L_DB, "Could not create tables\n");
|
||||||
|
|
|
@ -0,0 +1,436 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2009-2011 Julien BLACHE <jb@jblache.org>
|
||||||
|
* Copyright (C) 2010 Kai Elwert <elwertk@googlemail.com>
|
||||||
|
* Copyright (C) 2016 Christian Meffert <christian.meffert@googlemail.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sqlite3.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#include "db_init.h"
|
||||||
|
#include "logger.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define T_ADMIN \
|
||||||
|
"CREATE TABLE IF NOT EXISTS admin(" \
|
||||||
|
" key VARCHAR(32) NOT NULL," \
|
||||||
|
" value VARCHAR(32) NOT NULL" \
|
||||||
|
");"
|
||||||
|
|
||||||
|
#define T_FILES \
|
||||||
|
"CREATE TABLE IF NOT EXISTS files (" \
|
||||||
|
" id INTEGER PRIMARY KEY NOT NULL," \
|
||||||
|
" path VARCHAR(4096) NOT NULL," \
|
||||||
|
" fname VARCHAR(255) NOT NULL," \
|
||||||
|
" title VARCHAR(1024) DEFAULT NULL COLLATE DAAP," \
|
||||||
|
" artist VARCHAR(1024) DEFAULT NULL COLLATE DAAP," \
|
||||||
|
" album VARCHAR(1024) NOT NULL COLLATE DAAP," \
|
||||||
|
" genre VARCHAR(255) DEFAULT NULL COLLATE DAAP," \
|
||||||
|
" comment VARCHAR(4096) DEFAULT NULL COLLATE DAAP," \
|
||||||
|
" type VARCHAR(255) DEFAULT NULL COLLATE DAAP," \
|
||||||
|
" composer VARCHAR(1024) DEFAULT NULL COLLATE DAAP," \
|
||||||
|
" orchestra VARCHAR(1024) DEFAULT NULL COLLATE DAAP," \
|
||||||
|
" conductor VARCHAR(1024) DEFAULT NULL COLLATE DAAP," \
|
||||||
|
" grouping VARCHAR(1024) DEFAULT NULL COLLATE DAAP," \
|
||||||
|
" url VARCHAR(1024) DEFAULT NULL," \
|
||||||
|
" bitrate INTEGER DEFAULT 0," \
|
||||||
|
" samplerate INTEGER DEFAULT 0," \
|
||||||
|
" song_length INTEGER DEFAULT 0," \
|
||||||
|
" file_size INTEGER DEFAULT 0," \
|
||||||
|
" year INTEGER DEFAULT 0," \
|
||||||
|
" track INTEGER DEFAULT 0," \
|
||||||
|
" total_tracks INTEGER DEFAULT 0," \
|
||||||
|
" disc INTEGER DEFAULT 0," \
|
||||||
|
" total_discs INTEGER DEFAULT 0," \
|
||||||
|
" bpm INTEGER DEFAULT 0," \
|
||||||
|
" compilation INTEGER DEFAULT 0," \
|
||||||
|
" artwork INTEGER DEFAULT 0," \
|
||||||
|
" rating INTEGER DEFAULT 0," \
|
||||||
|
" play_count INTEGER DEFAULT 0," \
|
||||||
|
" seek INTEGER DEFAULT 0," \
|
||||||
|
" data_kind INTEGER DEFAULT 0," \
|
||||||
|
" item_kind INTEGER DEFAULT 0," \
|
||||||
|
" description INTEGER DEFAULT 0," \
|
||||||
|
" time_added INTEGER DEFAULT 0," \
|
||||||
|
" time_modified INTEGER DEFAULT 0," \
|
||||||
|
" time_played INTEGER DEFAULT 0," \
|
||||||
|
" db_timestamp INTEGER DEFAULT 0," \
|
||||||
|
" disabled INTEGER DEFAULT 0," \
|
||||||
|
" sample_count INTEGER DEFAULT 0," \
|
||||||
|
" codectype VARCHAR(5) DEFAULT NULL," \
|
||||||
|
" idx INTEGER NOT NULL," \
|
||||||
|
" has_video INTEGER DEFAULT 0," \
|
||||||
|
" contentrating INTEGER DEFAULT 0," \
|
||||||
|
" bits_per_sample INTEGER DEFAULT 0," \
|
||||||
|
" album_artist VARCHAR(1024) NOT NULL COLLATE DAAP," \
|
||||||
|
" media_kind INTEGER NOT NULL," \
|
||||||
|
" tv_series_name VARCHAR(1024) DEFAULT NULL COLLATE DAAP," \
|
||||||
|
" tv_episode_num_str VARCHAR(1024) DEFAULT NULL COLLATE DAAP," \
|
||||||
|
" tv_network_name VARCHAR(1024) DEFAULT NULL COLLATE DAAP," \
|
||||||
|
" tv_episode_sort INTEGER NOT NULL," \
|
||||||
|
" tv_season_num INTEGER NOT NULL," \
|
||||||
|
" songartistid INTEGER NOT NULL," \
|
||||||
|
" songalbumid INTEGER NOT NULL," \
|
||||||
|
" title_sort VARCHAR(1024) DEFAULT NULL COLLATE DAAP," \
|
||||||
|
" artist_sort VARCHAR(1024) DEFAULT NULL COLLATE DAAP," \
|
||||||
|
" album_sort VARCHAR(1024) DEFAULT NULL COLLATE DAAP," \
|
||||||
|
" composer_sort VARCHAR(1024) DEFAULT NULL COLLATE DAAP," \
|
||||||
|
" album_artist_sort VARCHAR(1024) DEFAULT NULL COLLATE DAAP," \
|
||||||
|
" virtual_path VARCHAR(4096) DEFAULT NULL," \
|
||||||
|
" directory_id INTEGER DEFAULT 0," \
|
||||||
|
" date_released INTEGER DEFAULT 0" \
|
||||||
|
");"
|
||||||
|
|
||||||
|
#define T_PL \
|
||||||
|
"CREATE TABLE IF NOT EXISTS playlists (" \
|
||||||
|
" id INTEGER PRIMARY KEY NOT NULL," \
|
||||||
|
" title VARCHAR(255) NOT NULL COLLATE DAAP," \
|
||||||
|
" type INTEGER NOT NULL," \
|
||||||
|
" query VARCHAR(1024)," \
|
||||||
|
" db_timestamp INTEGER NOT NULL," \
|
||||||
|
" disabled INTEGER DEFAULT 0," \
|
||||||
|
" path VARCHAR(4096)," \
|
||||||
|
" idx INTEGER NOT NULL," \
|
||||||
|
" special_id INTEGER DEFAULT 0," \
|
||||||
|
" virtual_path VARCHAR(4096)," \
|
||||||
|
" parent_id INTEGER DEFAULT 0," \
|
||||||
|
" directory_id INTEGER DEFAULT 0" \
|
||||||
|
");"
|
||||||
|
|
||||||
|
#define T_PLITEMS \
|
||||||
|
"CREATE TABLE IF NOT EXISTS playlistitems (" \
|
||||||
|
" id INTEGER PRIMARY KEY NOT NULL," \
|
||||||
|
" playlistid INTEGER NOT NULL," \
|
||||||
|
" filepath VARCHAR(4096) NOT NULL" \
|
||||||
|
");"
|
||||||
|
|
||||||
|
#define T_GROUPS \
|
||||||
|
"CREATE TABLE IF NOT EXISTS groups (" \
|
||||||
|
" id INTEGER PRIMARY KEY NOT NULL," \
|
||||||
|
" type INTEGER NOT NULL," \
|
||||||
|
" name VARCHAR(1024) NOT NULL COLLATE DAAP," \
|
||||||
|
" persistentid INTEGER NOT NULL," \
|
||||||
|
"CONSTRAINT groups_type_unique_persistentid UNIQUE (type, persistentid)" \
|
||||||
|
");"
|
||||||
|
|
||||||
|
#define T_PAIRINGS \
|
||||||
|
"CREATE TABLE IF NOT EXISTS pairings(" \
|
||||||
|
" remote VARCHAR(64) PRIMARY KEY NOT NULL," \
|
||||||
|
" name VARCHAR(255) NOT NULL," \
|
||||||
|
" guid VARCHAR(16) NOT NULL" \
|
||||||
|
");"
|
||||||
|
|
||||||
|
#define T_SPEAKERS \
|
||||||
|
"CREATE TABLE IF NOT EXISTS speakers(" \
|
||||||
|
" id INTEGER PRIMARY KEY NOT NULL," \
|
||||||
|
" selected INTEGER NOT NULL," \
|
||||||
|
" volume INTEGER NOT NULL," \
|
||||||
|
" name VARCHAR(255) DEFAULT NULL" \
|
||||||
|
");"
|
||||||
|
|
||||||
|
#define T_INOTIFY \
|
||||||
|
"CREATE TABLE IF NOT EXISTS inotify (" \
|
||||||
|
" wd INTEGER PRIMARY KEY NOT NULL," \
|
||||||
|
" cookie INTEGER NOT NULL," \
|
||||||
|
" path VARCHAR(4096) NOT NULL" \
|
||||||
|
");"
|
||||||
|
|
||||||
|
#define T_DIRECTORIES \
|
||||||
|
"CREATE TABLE IF NOT EXISTS directories (" \
|
||||||
|
" id INTEGER PRIMARY KEY NOT NULL," \
|
||||||
|
" virtual_path VARCHAR(4096) NOT NULL," \
|
||||||
|
" db_timestamp INTEGER DEFAULT 0," \
|
||||||
|
" disabled INTEGER DEFAULT 0," \
|
||||||
|
" parent_id INTEGER DEFAULT 0" \
|
||||||
|
");"
|
||||||
|
|
||||||
|
#define TRG_GROUPS_INSERT_FILES \
|
||||||
|
"CREATE TRIGGER update_groups_new_file AFTER INSERT ON files FOR EACH ROW" \
|
||||||
|
" BEGIN" \
|
||||||
|
" INSERT OR IGNORE INTO groups (type, name, persistentid) VALUES (1, NEW.album, NEW.songalbumid);" \
|
||||||
|
" INSERT OR IGNORE INTO groups (type, name, persistentid) VALUES (2, NEW.album_artist, NEW.songartistid);" \
|
||||||
|
" END;"
|
||||||
|
|
||||||
|
#define TRG_GROUPS_UPDATE_FILES \
|
||||||
|
"CREATE TRIGGER update_groups_update_file AFTER UPDATE OF songalbumid ON files FOR EACH ROW" \
|
||||||
|
" BEGIN" \
|
||||||
|
" INSERT OR IGNORE INTO groups (type, name, persistentid) VALUES (1, NEW.album, NEW.songalbumid);" \
|
||||||
|
" INSERT OR IGNORE INTO groups (type, name, persistentid) VALUES (2, NEW.album_artist, NEW.songartistid);" \
|
||||||
|
" END;"
|
||||||
|
|
||||||
|
#define Q_PL1 \
|
||||||
|
"INSERT INTO playlists (id, title, type, query, db_timestamp, path, idx, special_id)" \
|
||||||
|
" VALUES(1, 'Library', 0, '1 = 1', 0, '', 0, 0);"
|
||||||
|
|
||||||
|
#define Q_PL2 \
|
||||||
|
"INSERT INTO playlists (id, title, type, query, db_timestamp, path, idx, special_id)" \
|
||||||
|
" VALUES(2, 'Music', 0, 'f.media_kind = 1', 0, '', 0, 6);"
|
||||||
|
|
||||||
|
#define Q_PL3 \
|
||||||
|
"INSERT INTO playlists (id, title, type, query, db_timestamp, path, idx, special_id)" \
|
||||||
|
" VALUES(3, 'Movies', 0, 'f.media_kind = 2', 0, '', 0, 4);"
|
||||||
|
|
||||||
|
#define Q_PL4 \
|
||||||
|
"INSERT INTO playlists (id, title, type, query, db_timestamp, path, idx, special_id)" \
|
||||||
|
" VALUES(4, 'TV Shows', 0, 'f.media_kind = 64', 0, '', 0, 5);"
|
||||||
|
|
||||||
|
#define Q_PL5 \
|
||||||
|
"INSERT INTO playlists (id, title, type, query, db_timestamp, path, idx, special_id)" \
|
||||||
|
" VALUES(5, 'Podcasts', 0, 'f.media_kind = 4', 0, '', 0, 1);"
|
||||||
|
|
||||||
|
#define Q_PL6 \
|
||||||
|
"INSERT INTO playlists (id, title, type, query, db_timestamp, path, idx, special_id)" \
|
||||||
|
" VALUES(6, 'Audiobooks', 0, 'f.media_kind = 8', 0, '', 0, 7);"
|
||||||
|
|
||||||
|
/* These are the remaining automatically-created iTunes playlists, but
|
||||||
|
* their query is unknown
|
||||||
|
" VALUES(6, 'iTunes U', 0, 'media_kind = 256', 0, '', 0, 13);"
|
||||||
|
" VALUES(8, 'Purchased', 0, 'media_kind = 1024', 0, '', 0, 8);"
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#define Q_DIR1 \
|
||||||
|
"INSERT INTO directories (id, virtual_path, db_timestamp, disabled, parent_id)" \
|
||||||
|
" VALUES (1, '/', 0, 0, 0);"
|
||||||
|
#define Q_DIR2 \
|
||||||
|
"INSERT INTO directories (id, virtual_path, db_timestamp, disabled, parent_id)" \
|
||||||
|
" VALUES (2, '/file:', 0, 0, 1);"
|
||||||
|
#define Q_DIR3 \
|
||||||
|
"INSERT INTO directories (id, virtual_path, db_timestamp, disabled, parent_id)" \
|
||||||
|
" VALUES (3, '/http:', 0, 0, 1);"
|
||||||
|
#define Q_DIR4 \
|
||||||
|
"INSERT INTO directories (id, virtual_path, db_timestamp, disabled, parent_id)" \
|
||||||
|
" VALUES (4, '/spotify:', 0, 4294967296, 1);"
|
||||||
|
|
||||||
|
#define Q_SCVER_MAJOR \
|
||||||
|
"INSERT INTO admin (key, value) VALUES ('schema_version_major', '%d');"
|
||||||
|
#define Q_SCVER_MINOR \
|
||||||
|
"INSERT INTO admin (key, value) VALUES ('schema_version_minor', '%02d');"
|
||||||
|
|
||||||
|
struct db_init_query {
|
||||||
|
char *query;
|
||||||
|
char *desc;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct db_init_query db_init_table_queries[] =
|
||||||
|
{
|
||||||
|
{ T_ADMIN, "create table admin" },
|
||||||
|
{ T_FILES, "create table files" },
|
||||||
|
{ T_PL, "create table playlists" },
|
||||||
|
{ T_PLITEMS, "create table playlistitems" },
|
||||||
|
{ T_GROUPS, "create table groups" },
|
||||||
|
{ T_PAIRINGS, "create table pairings" },
|
||||||
|
{ T_SPEAKERS, "create table speakers" },
|
||||||
|
{ T_INOTIFY, "create table inotify" },
|
||||||
|
{ T_DIRECTORIES, "create table directories" },
|
||||||
|
|
||||||
|
{ TRG_GROUPS_INSERT_FILES, "create trigger update_groups_new_file" },
|
||||||
|
{ TRG_GROUPS_UPDATE_FILES, "create trigger update_groups_update_file" },
|
||||||
|
|
||||||
|
{ Q_PL1, "create default playlist" },
|
||||||
|
{ Q_PL2, "create default smart playlist 'Music'" },
|
||||||
|
{ Q_PL3, "create default smart playlist 'Movies'" },
|
||||||
|
{ Q_PL4, "create default smart playlist 'TV Shows'" },
|
||||||
|
{ Q_PL5, "create default smart playlist 'Podcasts'" },
|
||||||
|
{ Q_PL6, "create default smart playlist 'Audiobooks'" },
|
||||||
|
{ Q_DIR1, "create default root directory '/'" },
|
||||||
|
{ Q_DIR2, "create default base directory '/file:'" },
|
||||||
|
{ Q_DIR3, "create default base directory '/http:'" },
|
||||||
|
{ Q_DIR4, "create default base directory '/spotify:'" },
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* Indices must be prefixed with idx_ for db_drop_indices() to id them */
|
||||||
|
|
||||||
|
#define I_RESCAN \
|
||||||
|
"CREATE INDEX IF NOT EXISTS idx_rescan ON files(path, db_timestamp);"
|
||||||
|
|
||||||
|
#define I_SONGARTISTID \
|
||||||
|
"CREATE INDEX IF NOT EXISTS idx_sari ON files(songartistid);"
|
||||||
|
|
||||||
|
/* Used by Q_GROUP_ALBUMS */
|
||||||
|
#define I_SONGALBUMID \
|
||||||
|
"CREATE INDEX IF NOT EXISTS idx_sali ON files(songalbumid, disabled, media_kind, album_sort, disc, track);"
|
||||||
|
|
||||||
|
/* Used by Q_GROUP_ARTISTS */
|
||||||
|
#define I_STATEMKINDSARI \
|
||||||
|
"CREATE INDEX IF NOT EXISTS idx_state_mkind_sari ON files(disabled, media_kind, songartistid);"
|
||||||
|
|
||||||
|
#define I_STATEMKINDSALI \
|
||||||
|
"CREATE INDEX IF NOT EXISTS idx_state_mkind_sali ON files(disabled, media_kind, songalbumid);"
|
||||||
|
|
||||||
|
#define I_ARTIST \
|
||||||
|
"CREATE INDEX IF NOT EXISTS idx_artist ON files(artist, artist_sort);"
|
||||||
|
|
||||||
|
#define I_ALBUMARTIST \
|
||||||
|
"CREATE INDEX IF NOT EXISTS idx_albumartist ON files(album_artist, album_artist_sort);"
|
||||||
|
|
||||||
|
/* Used by Q_BROWSE_COMPOSERS */
|
||||||
|
#define I_COMPOSER \
|
||||||
|
"CREATE INDEX IF NOT EXISTS idx_composer ON files(disabled, media_kind, composer_sort);"
|
||||||
|
|
||||||
|
/* Used by Q_BROWSE_GENRES */
|
||||||
|
#define I_GENRE \
|
||||||
|
"CREATE INDEX IF NOT EXISTS idx_genre ON files(disabled, media_kind, genre);"
|
||||||
|
|
||||||
|
/* Used by Q_PLITEMS for smart playlists */
|
||||||
|
#define I_TITLE \
|
||||||
|
"CREATE INDEX IF NOT EXISTS idx_title ON files(disabled, media_kind, title_sort);"
|
||||||
|
|
||||||
|
#define I_ALBUM \
|
||||||
|
"CREATE INDEX IF NOT EXISTS idx_album ON files(album, album_sort);"
|
||||||
|
|
||||||
|
#define I_FILELIST \
|
||||||
|
"CREATE INDEX IF NOT EXISTS idx_filelist ON files(disabled, virtual_path, time_modified);"
|
||||||
|
|
||||||
|
#define I_FILE_DIR \
|
||||||
|
"CREATE INDEX IF NOT EXISTS idx_file_dir ON files(disabled, directory_id);"
|
||||||
|
|
||||||
|
#define I_PL_PATH \
|
||||||
|
"CREATE INDEX IF NOT EXISTS idx_pl_path ON playlists(path);"
|
||||||
|
|
||||||
|
#define I_PL_DISABLED \
|
||||||
|
"CREATE INDEX IF NOT EXISTS idx_pl_disabled ON playlists(disabled, type, virtual_path, db_timestamp);"
|
||||||
|
|
||||||
|
#define I_PL_DIR \
|
||||||
|
"CREATE INDEX IF NOT EXISTS idx_pl_dir ON files(disabled, directory_id);"
|
||||||
|
|
||||||
|
#define I_FILEPATH \
|
||||||
|
"CREATE INDEX IF NOT EXISTS idx_filepath ON playlistitems(filepath ASC);"
|
||||||
|
|
||||||
|
#define I_PLITEMID \
|
||||||
|
"CREATE INDEX IF NOT EXISTS idx_playlistid ON playlistitems(playlistid, filepath);"
|
||||||
|
|
||||||
|
#define I_GRP_PERSIST \
|
||||||
|
"CREATE INDEX IF NOT EXISTS idx_grp_persist ON groups(persistentid);"
|
||||||
|
|
||||||
|
#define I_PAIRING \
|
||||||
|
"CREATE INDEX IF NOT EXISTS idx_pairingguid ON pairings(guid);"
|
||||||
|
|
||||||
|
#define I_DIR_VPATH \
|
||||||
|
"CREATE INDEX IF NOT EXISTS idx_dir_vpath ON directories(disabled, virtual_path);"
|
||||||
|
|
||||||
|
#define I_DIR_PARENT \
|
||||||
|
"CREATE INDEX IF NOT EXISTS idx_dir_parentid ON directories(parent_id);"
|
||||||
|
|
||||||
|
static const struct db_init_query db_init_index_queries[] =
|
||||||
|
{
|
||||||
|
{ I_RESCAN, "create rescan index" },
|
||||||
|
{ I_SONGARTISTID, "create songartistid index" },
|
||||||
|
{ I_SONGALBUMID, "create songalbumid index" },
|
||||||
|
{ I_STATEMKINDSARI, "create state/mkind/sari index" },
|
||||||
|
{ I_STATEMKINDSALI, "create state/mkind/sali index" },
|
||||||
|
|
||||||
|
{ I_ARTIST, "create artist index" },
|
||||||
|
{ I_ALBUMARTIST, "create album_artist index" },
|
||||||
|
{ I_COMPOSER, "create composer index" },
|
||||||
|
{ I_GENRE, "create genre index" },
|
||||||
|
{ I_TITLE, "create title index" },
|
||||||
|
{ I_ALBUM, "create album index" },
|
||||||
|
{ I_FILELIST, "create filelist index" },
|
||||||
|
{ I_FILE_DIR, "create file dir index" },
|
||||||
|
|
||||||
|
{ I_PL_PATH, "create playlist path index" },
|
||||||
|
{ I_PL_DISABLED, "create playlist state index" },
|
||||||
|
{ I_PL_DIR, "create playlist dir index" },
|
||||||
|
|
||||||
|
{ I_FILEPATH, "create file path index" },
|
||||||
|
{ I_PLITEMID, "create playlist id index" },
|
||||||
|
|
||||||
|
{ I_GRP_PERSIST, "create groups persistentid index" },
|
||||||
|
|
||||||
|
{ I_PAIRING, "create pairing guid index" },
|
||||||
|
|
||||||
|
{ I_DIR_VPATH, "create directories disabled_virtualpath index" },
|
||||||
|
{ I_DIR_PARENT, "create directories parentid index" },
|
||||||
|
};
|
||||||
|
|
||||||
|
int
|
||||||
|
db_init_indices(sqlite3 *hdl)
|
||||||
|
{
|
||||||
|
char *errmsg;
|
||||||
|
int i;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
for (i = 0; i < (sizeof(db_init_index_queries) / sizeof(db_init_index_queries[0])); i++)
|
||||||
|
{
|
||||||
|
DPRINTF(E_DBG, L_DB, "DB init index query: %s\n", db_init_index_queries[i].desc);
|
||||||
|
|
||||||
|
ret = sqlite3_exec(hdl, db_init_index_queries[i].query, NULL, NULL, &errmsg);
|
||||||
|
if (ret != SQLITE_OK)
|
||||||
|
{
|
||||||
|
DPRINTF(E_FATAL, L_DB, "DB init error: %s\n", errmsg);
|
||||||
|
|
||||||
|
sqlite3_free(errmsg);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
db_init_tables(sqlite3 *hdl)
|
||||||
|
{
|
||||||
|
char *query;
|
||||||
|
char *errmsg;
|
||||||
|
int i;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
for (i = 0; i < (sizeof(db_init_table_queries) / sizeof(db_init_table_queries[0])); i++)
|
||||||
|
{
|
||||||
|
DPRINTF(E_DBG, L_DB, "DB init table query: %s\n", db_init_table_queries[i].desc);
|
||||||
|
|
||||||
|
ret = sqlite3_exec(hdl, db_init_table_queries[i].query, NULL, NULL, &errmsg);
|
||||||
|
if (ret != SQLITE_OK)
|
||||||
|
{
|
||||||
|
DPRINTF(E_FATAL, L_DB, "DB init error: %s\n", errmsg);
|
||||||
|
|
||||||
|
sqlite3_free(errmsg);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
query = sqlite3_mprintf(Q_SCVER_MAJOR, SCHEMA_VERSION_MAJOR);
|
||||||
|
DPRINTF(E_DBG, L_DB, "DB init table query: %s\n", query);
|
||||||
|
|
||||||
|
ret = sqlite3_exec(hdl, query, NULL, NULL, &errmsg);
|
||||||
|
sqlite3_free(query);
|
||||||
|
if (ret != SQLITE_OK)
|
||||||
|
{
|
||||||
|
DPRINTF(E_FATAL, L_DB, "DB init error: %s\n", errmsg);
|
||||||
|
sqlite3_free(errmsg);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
query = sqlite3_mprintf(Q_SCVER_MINOR, SCHEMA_VERSION_MINOR);
|
||||||
|
DPRINTF(E_DBG, L_DB, "DB init table query: %s\n", query);
|
||||||
|
|
||||||
|
ret = sqlite3_exec(hdl, query, NULL, NULL, &errmsg);
|
||||||
|
sqlite3_free(query);
|
||||||
|
if (ret != SQLITE_OK)
|
||||||
|
{
|
||||||
|
DPRINTF(E_FATAL, L_DB, "DB init error: %s\n", errmsg);
|
||||||
|
sqlite3_free(errmsg);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = db_init_indices(hdl);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2015 Christian Meffert <christian.meffert@googlemail.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SRC_DB_INIT_H_
|
||||||
|
#define SRC_DB_INIT_H_
|
||||||
|
|
||||||
|
#include <sqlite3.h>
|
||||||
|
|
||||||
|
/* Rule of thumb: Will the current version of forked-daapd work with the new
|
||||||
|
* version of the database? If yes, then it is a minor upgrade, if no, then it
|
||||||
|
* is a major upgrade. In other words minor version upgrades permit downgrading
|
||||||
|
* forked-daapd after the database was upgraded. */
|
||||||
|
#define SCHEMA_VERSION_MAJOR 19
|
||||||
|
#define SCHEMA_VERSION_MINOR 00
|
||||||
|
|
||||||
|
int
|
||||||
|
db_init_indices(sqlite3 *hdl);
|
||||||
|
|
||||||
|
int
|
||||||
|
db_init_tables(sqlite3 *hdl);
|
||||||
|
|
||||||
|
#endif /* SRC_DB_INIT_H_ */
|
Loading…
Reference in New Issue