Repository: xbmc/xbmc
File: xbmc/video/VideoDatabase.cpp (C++)

Code before:
    CommitTransaction();

    return idSet;
  }
  catch (...)
  {
    CLog::LogF(LOGERROR, "({}) failed", idSet);
  }
  RollbackTransaction();
  return -1;
}

int CVideoDatabase::AddMovieVersion(CFileItem& item, int idMovie, const ART::Artwork& art)
{
  CVideoInfoTag* tag{item.GetVideoInfoTag()};

  const int idFile{
      AddFile(item.GetDynPath(), "", tag->m_dateAdded, tag->GetPlayCount(), tag->m_lastPlayed)};
  if (idFile < 0)
    return -1;
  item.GetVideoInfoTag()->m_iFileId = idFile;

  if (tag->HasStreamDetails() && !SetStreamDetailsForFileId(tag->m_streamDetails, idFile))
    return -1;

  if (!AddVideoVersion(item.GetVideoContentType(), idMovie, idFile, tag->GetAssetInfo().GetId(),
                       VideoAssetType::VERSION))
    return -1;

  for (const auto& [type, url] : art)
    if (!SetArtForItem(idFile, MediaTypeVideoVersion, type, url))
      return -1;

  return idFile;
}

int CVideoDatabase::GetMatchingTvShow(const CVideoInfoTag& details) const
{
  // first try matching on uniqueid, then on title + year
  int id = -1;
  if (details.HasUniqueID())
  {
    //! @todo better handling when no default uniqueid is defined ("unknown" - legacy nfo)
    //! @todo loop through the non-default uniqueid when no match is found

    id = GetDbId(PrepareSQL("SELECT uniqueid.media_id FROM uniqueid "
                            "JOIN tvshow ON uniqueid.media_id=tvshow.idShow "
                            "WHERE uniqueid.media_type='%s' "
                            "AND uniqueid.value='%s' "
                            "AND uniqueid.type='%s' ",
                            MediaTypeTvShow, details.GetUniqueID().c_str(),

Review comment (bug):
uh? I missed something or this calls the non-updating function and doesn't fix the bug.
Since this is the only caller, only  AddOrUpdateVideoVersion (without the existsAction) is needed.
To follow the existing patterns more closely please make idFile the first parameter.

It will be fine as a quick fix, but later on please examine AddVideoAsset() which already does almost the same thing.

Code after:
    CommitTransaction();

    return idSet;
  }
  catch (...)
  {
    CLog::LogF(LOGERROR, "({}) failed", idSet);
  }
  RollbackTransaction();
  return -1;
}

int CVideoDatabase::AddMovieVersion(CFileItem& item, int idMovie, const ART::Artwork& art)
{
  CVideoInfoTag* tag{item.GetVideoInfoTag()};

  const int idFile{
      AddFile(item.GetDynPath(), "", tag->m_dateAdded, tag->GetPlayCount(), tag->m_lastPlayed)};
  if (idFile < 0)
    return -1;
  item.GetVideoInfoTag()->m_iFileId = idFile;

  if (tag->HasStreamDetails() && !SetStreamDetailsForFileId(tag->m_streamDetails, idFile))
    return -1;

  if (!AddOrUpdateVideoVersion(item.GetVideoContentType(), idMovie, idFile,
                               tag->GetAssetInfo().GetId(), VideoAssetType::VERSION))
    return -1;

  if (!SetArtForItem(idFile, MediaTypeVideoVersion, art))
    return -1;

  return idFile;
}

int CVideoDatabase::GetMatchingTvShow(const CVideoInfoTag& details) const
{
  // first try matching on uniqueid, then on title + year
  int id = -1;
  if (details.HasUniqueID())
  {
    //! @todo better handling when no default uniqueid is defined ("unknown" - legacy nfo)
    //! @todo loop through the non-default uniqueid when no match is found

    id = GetDbId(PrepareSQL("SELECT uniqueid.media_id FROM uniqueid "
                            "JOIN tvshow ON uniqueid.media_id=tvshow.idShow "
                            "WHERE uniqueid.media_type='%s' "
                            "AND uniqueid.value='%s' "
                            "AND uniqueid.type='%s' ",
                            MediaTypeTvShow, details.GetUniqueID().c_str(),
                            details.GetDefaultUniqueID().c_str()));