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 \
 | 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"); | ||||||
|  | |||||||
							
								
								
									
										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