Kodi MariaDB schema (MyVideos131)
The addon writes directly to Kodi's video database (MariaDB at
192.168.178.17:3306, DB MyVideos131) rather
than going through Kodi's scanner. This page documents the tables and
columns it touches — generated from real production rows + the
INSERT INTO sites grep'd from
library_sync.py.
Table map (everything the addon touches)
| Table | Used for | Writers | Readers |
|---|---|---|---|
path | One row per source path (disk folder OR plugin URL) | library_sync.ensure_*, _ensure_path | Kodi library windows, Kodi scanner, library_sync._purge_stale_* |
files | One row per file. For EasyPlayTV rows: strFilename = the full plugin URL (same string as episode.c18 / movie.c22). For Kodi-scraped disk rows: strFilename = the basename. | library_sync._insert_movie, _insert_episode | Kodi player (resume + playCount), library_sync stale cleanup |
movie | One row per movie | library_sync._insert_movie | Kodi library windows, library_sync stale cleanup |
tvshow | One row per series | library_sync._insert_tvshow, prefix_existing_tvshows, fix_sort_titles, backfill_series_art | Kodi library windows, library_sync stale cleanup |
seasons | One row per (show, season_number) | library_sync._ensure_season | Kodi library windows |
episode | One row per episode | library_sync._insert_episode | Kodi library windows, library_sync stale cleanup |
tvshowlinkpath | Many-to-many between tvshow and path (a show can hang off multiple source paths) | library_sync._insert_tvshow | Kodi scanner, library_sync |
uniqueid | Provider ids (tmdb / imdb / tvdb per media_id+type) | library_sync._insert_movie, _insert_tvshow, _insert_episode | Kodi scraper, library_sync de-dup checks |
genre + genre_link | Genre table + linking to tvshow/movie | library_sync._get_or_create_genre, _insert_tvshow, _insert_movie | Kodi library windows (genre tiles) |
art | Image rows (poster, fanart, thumb, season poster, episode still) | library_sync._insert_movie, _insert_tvshow, _insert_episode, _ensure_season, backfill_series_art | Kodi UI (renders the artwork) |
videoversion | Kodi 21's per-media-version row — every movie needs one | library_sync._insert_movie | Kodi's scanner |
bookmark | Resume points + play counts (via join to files.playCount) | Kodi's player | Kodi UI (resume bar, watch ticks) |
The path row — the most important row in the schema for the addon
One row in path holds every file the addon manages. The
addon relies on two path rows:
| idPath | strPath | strContent | strScraper | exclude | Purpose |
|---|---|---|---|---|---|
| 485 | plugin://plugin.video.easyplaytv/ | (varies — set to tvshows by ensure_series_path_config) | metadata.tvshows.themoviedb.org.python | 1 | The plugin source path where every episode + movie file lives. exclude=1 stops Kodi's scanner from creating duplicate un-prefixed rows — see the warning in ensure_series_path_config. |
| 3736 | /home/osmc/.kodi/.../Series/ | tvshows | metadata.tvshows.themoviedb.org.python | 1 | The on-disk Series folder that used to hold .strm files. exclude=1 on this row means Kodi's scanner can't re-attach to it (or to any per-show sub-folder under it) and create duplicate un-prefixed rows; the only active source is the plugin path. |
The single idPath=485 plugin row gets its strContent
updated by both ensure_path_config (sets "movies") and
ensure_series_path_config (sets "tvshows"). They run in
different code paths and one overrides the other — currently whatever
runs last wins. In practice this doesn't matter because the addon never
relies on this column for routing (every query goes through showlink /
file joins), but it's an inconsistency that could confuse a future Kodi
scanner that reads it.
The tvshow table — column inventory (the addon cares about)
Kodi's tvshow table has 30+ columns. Most are huge XML
blobs. The ones the addon writes:
| Column | What goes in | Why |
|---|---|---|
c00 | "[ITVX] Ackley Bridge" (display title with prefix) | Visible title. Sorts and search use c15 for the base name. |
c01 | plot (overview) | from TMDb |
c05 | premiered (ISO date) | from TMDb's first_air_date |
c08 | XML blob of poster + backdrop | via library_sync._build_thumbs |
c09 | original title (display title without prefix) | sort-by-original-name grouping |
c10 | episodeguide JSON: {"tmdb":"12345","imdb":"tt…","tvdb":"…","…"} | Required by Kodi's VideoInfoScanner before TMDb.GetEpisodeList — see warning in _insert_tvshow. If empty, episodes won't be fetched by Kodi's scan. |
c11 | fanart XML | from library_sync._build_fanart |
c12 | The uniqueid id for the tmdb uniqueid (set in the same INSERT flow after the uniqueid INSERT) | Kodi uses c12 to point at the "primary" uniqueid. Required for the scanner. |
c13 | MPAA rating ("Rated TV-14") | TMDb content_ratings US branch |
c14 | genre string ("Drama / Comedy") | " / " - separated |
c15 | sort title (display title stripped of [PROVIDER]) | set by library_sync.fix_sort_titles |
c17 | IMDB id (legacy — also stored via uniqueid table) | back-compat |
The episode table
| Column | What |
|---|---|
c00 | Episode display title in " |
c01 | plot |
c04 | rating (TMDb vote_average) |
c05 | votes |
c06 | aired date (TMDb air_date) |
c07 | thumb XML |
c12 | season number (string) |
c13 | episode number (string) |
c18 | The play URL — the plugin://plugin.video.easyplaytv/?… link Kodi uses for playback |
idFile | FK to files.idFile — Kodi reads strFilename and the play URL from this joined row |
idShow, idSeason | parent ids |
For Kodi's own disk-source rows (e.g. an Optima HTTP source), the two columns hold different shapes:
episode.c18holds the fullhttp://kodi:kodi@optima:80/Videos/Master/Series/24/Season 1/S01E01 - 12AM-1AM.mkvURL — what Kodi's player reads for play.files.strFilenameholds just the bare basename (S01E01 - 12AM-1AM.mkv) — what Kodi's library window displays as the filename column.
For EasyPlayTV's plugin-source rows, the addon writes the same full URL into both columns:
episode.c18=plugin://plugin.video.easyplaytv/?action=resolve_vod&provider=bbc&episode_id=…files.strFilename= the same full plugin URL.
There's no truncation in the addon's
_insert_episode:
the code at line 1136 simply aliases plugin_filename = strm_url
and inserts that string into both files.strFilename and
episode.c18. If a skin falls back to the filename column for
an episode row whose c00 (title) is empty, the raw
plugin://...?action=resolve_vod&... URL will leak through into
the display. Movies have the same shape: movie.c22 =
files.strFilename = full plugin URL.
The videoversion table (Kodi 21 addition)
Kodi 21 introduced the videoversion table to support
multiple "versions" of a movie (theatrical cut, director's cut, etc.).
The addon's
library_sync._insert_movie
INSERTs a single row with media_type='movie', idType=40400,
itemType=0. idType=40400 is the canonical "default version" id
for MyVideos131; if Kodi introduced a new version-type in a future
schema, the addon would need to insert that one too. Without this row
the movie shows in the library but can't be played through Kodi's
UI navigation (it falls through to "no video version available").
Idempotency / collision queries
- Movie:
SELECT f.idFile FROM files f JOIN movie m ON f.idFile = m.idFile WHERE f.idPath = %s AND f.strFilename = %s— duplicate movie check (skips insert if found). - Episode:
SELECT idEpisode FROM episode WHERE idShow = %s AND c12 = %s AND c13 = %s— duplicate episode check by (idShow, season, episode). - TV show:
SELECT idShow FROM tvshow WHERE c00 = %s— duplicate show check with the prefix-name lookup logic in library_sync._insert_tvshow.