mirror of
				https://github.com/owntone/owntone-server.git
				synced 2025-10-29 15:55:02 -04:00 
			
		
		
		
	[db] Move initialization of new db into its own file (db_init.c)
This commit is contained in:
		
							parent
							
								
									91c3eb622c
								
							
						
					
					
						commit
						f7aa3c225b
					
				| @ -79,6 +79,7 @@ forked_daapd_LDADD = -lrt \ | ||||
| 
 | ||||
| forked_daapd_SOURCES = main.c \
 | ||||
| 	db.c db.h \
 | ||||
| 	db_init.c db_init.h \
 | ||||
| 	db_upgrade.c db_upgrade.h \
 | ||||
| 	logger.c logger.h \
 | ||||
| 	conffile.c conffile.h \
 | ||||
|  | ||||
							
								
								
									
										397
									
								
								src/db.c
									
									
									
									
									
								
							
							
						
						
									
										397
									
								
								src/db.c
									
									
									
									
									
								
							| @ -44,6 +44,7 @@ | ||||
| #include "cache.h" | ||||
| #include "misc.h" | ||||
| #include "db.h" | ||||
| #include "db_init.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 | ||||
| @ -5278,7 +4887,7 @@ db_check_version(void) | ||||
| 	  return -1; | ||||
| 	} | ||||
| 
 | ||||
|       ret = db_create_indices(); | ||||
|       ret = db_init_indices(hdl); | ||||
|       if (ret < 0) | ||||
| 	{ | ||||
| 	  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"); | ||||
| 
 | ||||
|       ret = db_create_tables(); | ||||
|       ret = db_init_tables(hdl); | ||||
|       if (ret < 0) | ||||
| 	{ | ||||
| 	  DPRINTF(E_FATAL, L_DB, "Could not create tables\n"); | ||||
|  | ||||
							
								
								
									
										414
									
								
								src/db_init.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										414
									
								
								src/db_init.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,414 @@ | ||||
| /*
 | ||||
|  * 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', '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" }, | ||||
|   }; | ||||
| 
 | ||||
| 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 *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_init_indices(hdl); | ||||
| 
 | ||||
|   return ret; | ||||
| } | ||||
| 
 | ||||
							
								
								
									
										37
									
								
								src/db_init.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								src/db_init.h
									
									
									
									
									
										Normal file
									
								
							| @ -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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user