Add _ensure_schema() to create SQLite tables if missing
- Creates all required tables (item, artist, album, avformat_info, store_info, item_to_container, track_size_calc) in Library.itdb - Creates location table in Locations.itdb - Called from Nano7Database.__init__(), so empty DB is always valid - Fixes 'no such table: item' error on iPod with wiped DB
This commit is contained in:
parent
8c9e146a6c
commit
cc429eed31
@ -31,6 +31,76 @@ logger = logging.getLogger(__name__)
|
|||||||
|
|
||||||
MASTER_CONTAINER_PID = 203092939621887772 # "iPod" master playlist
|
MASTER_CONTAINER_PID = 203092939621887772 # "iPod" master playlist
|
||||||
|
|
||||||
|
LIBRARY_SCHEMA_SQL = """
|
||||||
|
CREATE TABLE IF NOT EXISTS item (
|
||||||
|
pid INTEGER PRIMARY KEY, media_kind INTEGER, is_song INTEGER,
|
||||||
|
date_modified INTEGER, year INTEGER, is_compilation INTEGER,
|
||||||
|
is_user_disabled INTEGER, remember_bookmark INTEGER,
|
||||||
|
exclude_from_shuffle INTEGER, part_of_gapless_album INTEGER,
|
||||||
|
chosen_by_auto_fill INTEGER, artwork_status INTEGER,
|
||||||
|
artwork_cache_id INTEGER, total_time_ms INTEGER,
|
||||||
|
track_number INTEGER, track_count INTEGER, disc_number INTEGER,
|
||||||
|
disc_count INTEGER, album_pid INTEGER, artist_pid INTEGER,
|
||||||
|
title TEXT, artist TEXT, album TEXT, album_artist TEXT,
|
||||||
|
sort_title TEXT, sort_artist TEXT, sort_album TEXT,
|
||||||
|
sort_album_artist TEXT, title_order INTEGER, artist_order INTEGER,
|
||||||
|
album_order INTEGER, physical_order INTEGER
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS artist (
|
||||||
|
pid INTEGER PRIMARY KEY, kind INTEGER, artwork_status INTEGER,
|
||||||
|
artwork_album_pid INTEGER, name TEXT, name_order INTEGER,
|
||||||
|
sort_name TEXT, is_unknown INTEGER, has_songs INTEGER,
|
||||||
|
has_music_videos INTEGER, has_non_compilation_tracks INTEGER,
|
||||||
|
album_count INTEGER
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS album (
|
||||||
|
pid INTEGER PRIMARY KEY, kind INTEGER, artwork_status INTEGER,
|
||||||
|
artwork_item_pid INTEGER, artist_pid INTEGER, user_rating INTEGER,
|
||||||
|
name TEXT, name_order INTEGER, all_compilations INTEGER,
|
||||||
|
feed_url TEXT, season_number INTEGER, is_unknown INTEGER,
|
||||||
|
has_songs INTEGER, has_music_videos INTEGER, sort_order INTEGER,
|
||||||
|
artist_order INTEGER, has_any_compilations INTEGER, sort_name TEXT,
|
||||||
|
artist_count_calc INTEGER, has_movies INTEGER, item_count INTEGER,
|
||||||
|
min_volume_normalization_energy INTEGER
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS avformat_info (
|
||||||
|
item_pid INTEGER, sub_id INTEGER, audio_format INTEGER,
|
||||||
|
bit_rate INTEGER, channels INTEGER, sample_rate INTEGER,
|
||||||
|
duration INTEGER, gapless_heuristic_info INTEGER,
|
||||||
|
gapless_encoding_delay INTEGER, gapless_encoding_drain INTEGER,
|
||||||
|
gapless_last_frame_resynch INTEGER, analysis_inhibit_flags INTEGER,
|
||||||
|
audio_fingerprint INTEGER, volume_normalization_energy INTEGER
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS store_info (
|
||||||
|
item_pid INTEGER PRIMARY KEY
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS item_to_container (
|
||||||
|
item_pid INTEGER, container_pid INTEGER, physical_order INTEGER,
|
||||||
|
shuffle_order INTEGER
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS track_size_calc (
|
||||||
|
kind TEXT PRIMARY KEY, size INTEGER DEFAULT 0
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT OR IGNORE INTO track_size_calc (kind, size) VALUES ('audio', 0);
|
||||||
|
"""
|
||||||
|
|
||||||
|
LOCATIONS_SCHEMA_SQL = """
|
||||||
|
CREATE TABLE IF NOT EXISTS location (
|
||||||
|
item_pid INTEGER, sub_id INTEGER, base_location_id INTEGER,
|
||||||
|
location_type INTEGER, location TEXT, extension INTEGER,
|
||||||
|
kind_id INTEGER, date_created INTEGER, file_size INTEGER,
|
||||||
|
file_creator INTEGER, file_type INTEGER,
|
||||||
|
num_dir_levels_file INTEGER, num_dir_levels_lib INTEGER
|
||||||
|
);
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
class Nano7Database:
|
class Nano7Database:
|
||||||
"""Manages iPod Nano 7 SQLite database and iTunesCDB"""
|
"""Manages iPod Nano 7 SQLite database and iTunesCDB"""
|
||||||
@ -62,6 +132,25 @@ class Nano7Database:
|
|||||||
".mp4": struct.unpack(">I", b"MP4 ")[0],
|
".mp4": struct.unpack(">I", b"MP4 ")[0],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self._ensure_schema()
|
||||||
|
|
||||||
|
def _ensure_schema(self) -> None:
|
||||||
|
"""Create required tables in Library.itdb and Locations.itdb if missing."""
|
||||||
|
sqlite_path = self.sqlite_path
|
||||||
|
locations_path = self.locations_path
|
||||||
|
|
||||||
|
for db_path, schema in [(sqlite_path, LIBRARY_SCHEMA_SQL),
|
||||||
|
(locations_path, LOCATIONS_SCHEMA_SQL)]:
|
||||||
|
try:
|
||||||
|
os.makedirs(os.path.dirname(db_path), exist_ok=True)
|
||||||
|
conn = sqlite3.connect(db_path)
|
||||||
|
conn.executescript(schema)
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
logger.info(f"Schema ensured in {os.path.basename(db_path)}")
|
||||||
|
except Exception as e:
|
||||||
|
logger.warning(f"Failed to ensure schema in {db_path}: {e}")
|
||||||
|
|
||||||
def _detect_firewire_id(self) -> bytes:
|
def _detect_firewire_id(self) -> bytes:
|
||||||
"""Parse FirewireGuid from SysInfo file on the iPod."""
|
"""Parse FirewireGuid from SysInfo file on the iPod."""
|
||||||
sysinfo_path = os.path.join(
|
sysinfo_path = os.path.join(
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user