int64_t find_album_art(const char *path, const char *image_data, int image_size) { char *album_art = NULL; char *sql; char **result; int cols, rows; int64_t ret = 0; if( (image_size && (album_art = check_embedded_art(path, image_data, image_size))) || (album_art = check_for_album_file(path)) ) { sql = sqlite3_mprintf("SELECT ID from ALBUM_ART where PATH = '%q'", album_art ? album_art : path); if( (sql_get_table(db, sql, &result, &rows, &cols) == SQLITE_OK) && rows ) { ret = strtoll(result[1], NULL, 10); } else { if( sql_exec(db, "INSERT into ALBUM_ART (PATH) VALUES ('%q')", album_art) == SQLITE_OK ) ret = sqlite3_last_insert_rowid(db); } sqlite3_free_table(result); sqlite3_free(sql); } free(album_art); return ret; }
sqlite_int64 find_album_art(const char * path, const char * image_data, int image_size) { char * album_art = NULL; char * sql; char ** result; int cols, rows; sqlite_int64 ret = 0; char * mypath; const char * dir; struct stat st; if( stat(path, &st) == 0 && S_ISDIR(st.st_mode) ) { mypath = NULL; dir = path; } else { mypath = strdup(path); dir = dirname(mypath); } if( (image_size && (album_art = check_embedded_art(path, image_data, image_size))) || (album_art = check_for_album_file(dir, path)) ) { sql = sqlite3_mprintf("SELECT ID from ALBUM_ART where PATH = '%q'", album_art ? album_art : path); if( (sql_get_table(db, sql, &result, &rows, &cols) == SQLITE_OK) && rows ) { ret = strtoll(result[1], NULL, 10); } else { if( sql_exec(db, "INSERT into ALBUM_ART (PATH) VALUES ('%q')", album_art) == SQLITE_OK ) ret = sqlite3_last_insert_rowid(db); } sqlite3_free_table(result); sqlite3_free(sql); } free(album_art); free(mypath); return ret; }
sqlite_int64 get_next_available_id(const char * table, const char * parentID) { char * sql; char **result; int ret, rows; sqlite_int64 objectID = 0; asprintf(&sql, "SELECT OBJECT_ID from %s where ID = " "(SELECT max(ID) from %s where PARENT_ID = '%s')", table, table, parentID); ret = sql_get_table(db, sql, &result, &rows, NULL); if( rows ) { objectID = strtoll(strrchr(result[1], '$')+1, NULL, 16) + 1; } sqlite3_free_table(result); free(sql); return objectID; }
int fill_playlists() { int rows, i, found, len; char **result; char *plpath, *plname, *fname; char class[] = "playlistContainer"; struct song_metadata plist; struct stat file; char type[4]; sqlite_int64 plID, detailID; char sql_buf[1024] = "SELECT ID, NAME, PATH from PLAYLISTS where ITEMS > FOUND"; if( sql_get_table(db, sql_buf, &result, &rows, NULL) != SQLITE_OK ) return -1; if( !rows ) { sqlite3_free_table(result); return 0; } rows++; for( i=3; i<rows*3; i++ ) { plID = strtoll(result[i], NULL, 10); plname = result[++i]; plpath = result[++i]; strncpy(type, strrchr(plpath, '.')+1, 4); if( start_plist(plpath, NULL, &file, NULL, type) != 0 ) continue; DPRINTF(E_DEBUG, L_SCANNER, "Scanning playlist \"%s\" [%s]\n", plname, plpath); if( sql_get_int_field(db, "SELECT ID from OBJECTS where PARENT_ID = '"MUSIC_PLIST_ID"'" " and NAME = '%q'", plname) <= 0 ) { detailID = GetFolderMetadata(plname, NULL, NULL, NULL, NULL); sql_exec(db, "INSERT into OBJECTS" " (OBJECT_ID, PARENT_ID, DETAIL_ID, CLASS, NAME) " "VALUES" " ('%s$%llX', '%s', %lld, 'container.%s', '%q')", MUSIC_PLIST_ID, plID, MUSIC_PLIST_ID, detailID, class, plname); } plpath = dirname(plpath); found = 0; while( next_plist_track(&plist, &file, NULL, type) == 0 ) { if( sql_get_int_field(db, "SELECT 1 from OBJECTS where OBJECT_ID = '%s$%llX$%d'", MUSIC_PLIST_ID, plID, plist.track) == 1 ) { //DEBUG DPRINTF(E_DEBUG, L_SCANNER, "%d: already in database\n", plist.track); found++; freetags(&plist); continue; } fname = plist.path; DPRINTF(E_DEBUG, L_SCANNER, "%d: checking database for %s\n", plist.track, plist.path); if( !strpbrk(fname, "\\/") ) { len = strlen(fname) + strlen(plpath) + 2; plist.path = malloc(len); snprintf(plist.path, len, "%s/%s", plpath, fname); free(fname); fname = plist.path; } else { while( *fname == '\\' ) { fname++; } } retry: //DEBUG DPRINTF(E_DEBUG, L_SCANNER, "* Searching for %s in db\n", fname); detailID = sql_get_int_field(db, "SELECT ID from DETAILS where PATH like '%%%q'", fname); if( detailID > 0 ) { DPRINTF(E_DEBUG, L_SCANNER, "+ %s found in db\n", fname); sql_exec(db, "INSERT into OBJECTS" " (OBJECT_ID, PARENT_ID, CLASS, DETAIL_ID, NAME, REF_ID) " "SELECT" " '%s$%llX$%d', '%s$%llX', CLASS, DETAIL_ID, NAME, OBJECT_ID from OBJECTS" " where DETAIL_ID = %lld and OBJECT_ID glob '" BROWSEDIR_ID "$*'", MUSIC_PLIST_ID, plID, plist.track, MUSIC_PLIST_ID, plID, detailID); found++; } else { DPRINTF(E_DEBUG, L_SCANNER, "- %s not found in db\n", fname); if( strchr(fname, '\\') ) { fname = modifyString(fname, "\\", "/", 0); goto retry; } else if( (fname = strchr(fname, '/')) ) { fname++; goto retry; } } freetags(&plist); } sql_exec(db, "UPDATE PLAYLISTS set FOUND = %d where ID = %lld", found, plID); }
static void check_db(sqlite3 *db, int new_db, pid_t *scanner_pid) { struct media_dir_s *media_path = NULL; char cmd[PATH_MAX*2]; char **result; int i, rows = 0; int ret; if (!new_db) { /* Check if any new media dirs appeared */ media_path = media_dirs; while (media_path) { ret = sql_get_int_field(db, "SELECT TIMESTAMP from DETAILS where PATH = %Q", media_path->path); if (ret != media_path->types) { ret = 1; goto rescan; } media_path = media_path->next; } /* Check if any media dirs disappeared */ sql_get_table(db, "SELECT VALUE from SETTINGS where KEY = 'media_dir'", &result, &rows, NULL); for (i=1; i <= rows; i++) { media_path = media_dirs; while (media_path) { if (strcmp(result[i], media_path->path) == 0) break; media_path = media_path->next; } if (!media_path) { ret = 2; sqlite3_free_table(result); goto rescan; } } sqlite3_free_table(result); } ret = db_upgrade(db); if (ret != 0) { rescan: if (ret < 0) DPRINTF(E_WARN, L_GENERAL, "Creating new database at %s/files.db\n", db_path); else if (ret == 1) DPRINTF(E_WARN, L_GENERAL, "New media_dir detected; rescanning...\n"); else if (ret == 2) DPRINTF(E_WARN, L_GENERAL, "Removed media_dir detected; rescanning...\n"); else DPRINTF(E_WARN, L_GENERAL, "Database version mismatch; need to recreate...\n"); sqlite3_close(db); snprintf(cmd, sizeof(cmd), "rm -rf %s/files.db %s/art_cache", db_path, db_path); if (system(cmd) != 0) DPRINTF(E_FATAL, L_GENERAL, "Failed to clean old file cache! Exiting...\n"); open_db(&db); if (CreateDatabase() != 0) DPRINTF(E_FATAL, L_GENERAL, "ERROR: Failed to create sqlite database! Exiting...\n"); #if USE_FORK scanning = 1; sqlite3_close(db); *scanner_pid = fork(); open_db(&db); if (!(*scanner_pid)) /* child (scanner) process */ { start_scanner(); sqlite3_close(db); log_close(); freeoptions(); exit(EXIT_SUCCESS); } #else start_scanner(); #endif } }
insert_container(const char * item, const char * rootParent, const char * refID, const char *class, const char *artist, const char *genre, const char *album_art) { char **result; char **result2; char *sql; int cols, rows, ret; int parentID = 0, objectID = 0; sqlite_int64 detailID = 0; sql = sqlite3_mprintf("SELECT OBJECT_ID from OBJECTS" " where PARENT_ID = '%s'" " and NAME = '%q'" " and CLASS = 'container.%s' limit 1", rootParent, item, class); ret = sql_get_table(db, sql, &result, &rows, &cols); sqlite3_free(sql); if( cols ) { parentID = strtol(rindex(result[1], '$')+1, NULL, 16); objectID = get_next_available_id("OBJECTS", result[1]); } else { parentID = get_next_available_id("OBJECTS", rootParent); if( refID ) { sql = sqlite3_mprintf("SELECT DETAIL_ID from OBJECTS where OBJECT_ID = %Q", refID); ret = sql_get_table(db, sql, &result2, &rows, NULL); if( ret == SQLITE_OK ) {