2017-06-08 20:01:42 +02:00
#define LOCK_LCN_LISTS
2017-03-31 16:55:37 +02:00
using System ;
using System.Collections.Generic ;
using System.Data ;
using System.Data.SQLite ;
using System.IO ;
using System.Windows.Forms ;
using ChanSort.Api ;
2017-06-08 20:01:42 +02:00
namespace ChanSort.Loader.Hisense2017
2017-03-31 16:55:37 +02:00
{
public class HisDbSerializer : SerializerBase
{
2017-06-08 20:01:42 +02:00
/ *
* The 2017 Hisense / Loewe data model for channel lists is a bit different than all other supported models and need some workarounds to be supported .
* It is based on a flat "Services" table which doesn ' t hold program numbers and a FavoritesList / FavoritesItem table to assign numbers
* to physical tuner lists and user favorite lists alike .
*
* Physical channel lists ( e . g . for $ av , Astra , Hot Bird ) have their own ChannelList in the channelList dictionary and use
* ChannelInfo . NewProgramNr to hold the program number . This doesn ' t allow the user to add services from other lists .
*
* The user favorite lists ( FAV1 - FAV4 ) use the separate favList ChannelList filled with all services from all physical lists .
* ChannelInfo . FavIndex [ 0 - 3 ] holds the information for the program numbers in FAV1 - 4. The value - 1 is used to indicate "not included" .
*
* The $ all list is hidden from the user and automatically updated to match the contents of all other lists ( except $ av and FAV1 - 4 ) .
*
* The $ av list is hidden from the user and not updated at all .
*
* This loader poses the following restrictions on the database :
* - a service must not appear in more than one physical channel list ( $ all and FAV1 - 4 are not part of this restriction )
* - a service can ' t appear more than once in any list
*
* /
/// <summary>
/// list of all table names in the database
/// </summary>
private readonly List < string > tableNames = new List < string > ( ) ;
/// <summary>
/// mapping of Service.Pid => ChannelInfo
/// </summary>
2017-03-31 16:55:37 +02:00
private readonly Dictionary < long , ChannelInfo > channelsById = new Dictionary < long , ChannelInfo > ( ) ;
2017-06-08 20:01:42 +02:00
/// <summary>
/// mapping of FavoriteList.Pid => ChannelList.
/// This dict does not include real user favorite lists (FAV1-FAV4).
/// </summary>
2017-03-31 16:55:37 +02:00
private readonly Dictionary < int , ChannelList > channelLists = new Dictionary < int , ChannelList > ( ) ;
2017-06-08 20:01:42 +02:00
/// <summary>
/// This list is filled with all channels/services and serves as a holder for favorite lists 1-4
/// </summary>
2019-08-29 16:57:20 +02:00
private readonly ChannelList userFavList = new ChannelList ( 0 , "Favorites" ) ;
2017-06-08 20:01:42 +02:00
/// <summary>
/// mapping of FavoriteList.Pid for FAV1-4 => index of the internal favorite list within userFavList (0-3)
/// Pids that don't belong to the FAV1-4 are not included in this dictionary.
/// </summary>
2017-03-31 16:55:37 +02:00
private readonly Dictionary < int , int > favListIdToFavIndex = new Dictionary < int , int > ( ) ;
2017-06-08 20:01:42 +02:00
/// <summary>
/// FavoriteList.Pid of the $all list
/// </summary>
private int pidAll ;
/// <summary>
/// FavoriteList.Pid of the $av list
/// </summary>
private int pidAv ;
/// <summary>
/// Fields of the ChannelInfo that will be shown in the UI
/// </summary>
2017-03-31 16:55:37 +02:00
private static readonly List < string > ColumnNames = new List < string >
{
"OldPosition" ,
"Position" ,
"Source" ,
"NewProgramNr" ,
"Name" ,
"ShortName" ,
"Favorites" ,
2017-06-08 20:01:42 +02:00
"Skip" ,
2017-03-31 16:55:37 +02:00
"Lock" ,
"Hidden" ,
"Encrypted" ,
"FreqInMhz" ,
"OriginalNetworkId" ,
"TransportStreamId" ,
"ServiceId" ,
2019-08-29 16:57:20 +02:00
//"ServiceType",
2017-03-31 16:55:37 +02:00
"ServiceTypeName" ,
"NetworkName" ,
2017-06-08 20:01:42 +02:00
"Satellite"
// "SymbolRate"
2017-03-31 16:55:37 +02:00
} ;
2017-06-08 20:01:42 +02:00
#region class HisTransponder
/// <summary>
/// This class holds information from the Tuner table
/// </summary>
2017-03-31 16:55:37 +02:00
public class HisTransponder : Transponder
{
public SignalSource SignalSource { get ; set ; }
public string Source { get ; set ; }
public HisTransponder ( int id ) : base ( id )
{
}
}
2017-06-08 20:01:42 +02:00
#endregion
2017-03-31 16:55:37 +02:00
#region ctor ( )
public HisDbSerializer ( string inputFile ) : base ( inputFile )
{
DepencencyChecker . AssertVc2010RedistPackageX86Installed ( ) ;
Features . ChannelNameEdit = ChannelNameEditMode . All ;
2019-11-08 02:31:44 +01:00
Features . DeleteMode = DeleteMode . FlagWithPrNr ;
2017-06-08 20:01:42 +02:00
Features . CanSkipChannels = true ;
2019-11-24 20:00:48 +01:00
Features . CanLockChannels = true ;
Features . CanHideChannels = true ;
2017-03-31 16:55:37 +02:00
Features . CanHaveGaps = true ;
2019-11-08 02:31:44 +01:00
Features . MixedSourceFavorites = true ;
Features . SortedFavorites = true ;
2017-03-31 16:55:37 +02:00
}
#endregion
#region Load ( )
public override void Load ( )
{
using ( var conn = new SQLiteConnection ( "Data Source=" + FileName ) )
{
conn . Open ( ) ;
using ( var cmd = conn . CreateCommand ( ) )
{
RepairCorruptedDatabaseImage ( cmd ) ;
LoadTableNames ( cmd ) ;
2017-06-08 20:01:42 +02:00
// make sure this .db file contains the required tables
if ( ! tableNames . Contains ( "service" ) | | ! tableNames . Contains ( "tuner" ) | | ! tableNames . Contains ( "favoriteitem" ) )
throw new FileLoadException ( "File doesn't contain service/tuner/favoriteitem tables" ) ;
LoadLists ( cmd ) ;
2017-03-31 16:55:37 +02:00
LoadTunerData ( cmd ) ;
LoadServiceData ( cmd ) ;
LoadFavorites ( cmd ) ;
}
}
if ( channelsById . Count = = 0 )
MessageBox . Show ( Resources . Load_NoChannelsMsg , Resources . Load_NoChannelsCaption , MessageBoxButtons . OK ) ;
}
#endregion
#region RepairCorruptedDatabaseImage ( )
private void RepairCorruptedDatabaseImage ( SQLiteCommand cmd )
{
cmd . CommandText = "REINDEX" ;
cmd . ExecuteNonQuery ( ) ;
}
#endregion
#region LoadTableNames ( )
private void LoadTableNames ( SQLiteCommand cmd )
{
cmd . CommandText = "SELECT name FROM sqlite_master WHERE type = 'table' order by name" ;
using ( var r = cmd . ExecuteReader ( ) )
{
while ( r . Read ( ) )
tableNames . Add ( r . GetString ( 0 ) . ToLower ( ) ) ;
}
}
#endregion
#region LoadLists ( )
private void LoadLists ( SQLiteCommand cmd )
{
cmd . CommandText = "select Pid, Name from FavoriteList" ;
using ( var r = cmd . ExecuteReader ( ) )
{
while ( r . Read ( ) )
{
int listId = r . GetInt32 ( 0 ) ;
string name = r . GetString ( 1 ) ;
2017-06-08 20:01:42 +02:00
if ( name = = "$all" )
pidAll = listId ;
else if ( name = = "$av" )
pidAv = listId ;
else if ( name . StartsWith ( "FAV" ) )
2017-03-31 16:55:37 +02:00
{
2017-06-08 20:01:42 +02:00
// all real user favorite lists are using the "userFavList"
favListIdToFavIndex . Add ( listId , int . Parse ( name . Substring ( 3 ) ) - 1 ) ;
2017-03-31 16:55:37 +02:00
continue ;
}
2017-06-08 20:01:42 +02:00
// lists for physical channel sources
2019-08-29 16:57:20 +02:00
var list = new ChannelList ( 0 , name ) ;
2017-03-31 16:55:37 +02:00
list . VisibleColumnFieldNames = ColumnNames ;
channelLists . Add ( listId , list ) ;
2017-06-08 20:01:42 +02:00
if ( name . StartsWith ( "$" ) )
list . ReadOnly = true ;
else
DataRoot . AddChannelList ( list ) ; // only lists in the DataRoot will be visible in the UI
2017-03-31 16:55:37 +02:00
}
}
2017-06-08 20:01:42 +02:00
// add the special list for the user favorites 1-4
userFavList . VisibleColumnFieldNames = ColumnNames ;
userFavList . IsMixedSourceFavoritesList = true ;
channelLists . Add ( 0 , userFavList ) ;
DataRoot . AddChannelList ( userFavList ) ;
2017-03-31 16:55:37 +02:00
}
#endregion
#region LoadTunerData ( )
private void LoadTunerData ( SQLiteCommand cmd )
{
List < Tuple < string , SignalSource , string > > inputs = new List < Tuple < string , SignalSource , string > >
{
Tuple . Create ( "C" , SignalSource . DvbC , "symbolrate" ) ,
Tuple . Create ( "C2" , SignalSource . DvbC , "bandwidth" ) ,
Tuple . Create ( "S" , SignalSource . DvbS , "symbolrate" ) ,
Tuple . Create ( "S2" , SignalSource . DvbS , "symbolrate" ) ,
Tuple . Create ( "T" , SignalSource . DvbT , "bandwidth" ) ,
Tuple . Create ( "T2" , SignalSource . DvbT , "bandwidth" ) ,
} ;
2017-06-08 20:01:42 +02:00
2017-03-31 16:55:37 +02:00
foreach ( var input in inputs )
{
var table = input . Item1 ;
var symrate = input . Item3 ;
LoadTunerData ( cmd , "DVB" + table + "Tuner" , ", Frequency," + symrate , ( t , r , i0 ) = >
{
t . Source = "DVB-" + input . Item1 ;
t . SignalSource = input . Item2 ;
t . FrequencyInMhz = ( decimal ) r . GetInt32 ( i0 + 0 ) / 1000 ;
t . SymbolRate = r . GetInt32 ( i0 + 1 ) ;
} ) ;
}
}
private void LoadTunerData ( SQLiteCommand cmd , string joinTable , string joinFields , Action < HisTransponder , SQLiteDataReader , int > enhanceTransponderInfo )
{
if ( ! tableNames . Contains ( joinTable . ToLower ( ) ) )
return ;
cmd . CommandText = $"select tuner.tunerid, oid, tid, satellite {joinFields} "
+ $" from tuner inner join {joinTable} on {joinTable}.tunerid=tuner.tunerid" ;
using ( var r = cmd . ExecuteReader ( ) )
{
while ( r . Read ( ) )
{
var id = r . GetInt32 ( 0 ) ;
var trans = new HisTransponder ( id ) ;
trans . OriginalNetworkId = r . GetInt32 ( 1 ) ;
trans . TransportStreamId = r . GetInt32 ( 2 ) ;
trans . Satellite = DataRoot . Satellites . TryGet ( r . GetInt32 ( 3 ) ) ;
enhanceTransponderInfo ( trans , r , 4 ) ;
DataRoot . AddTransponder ( trans . Satellite , trans ) ;
}
}
}
#endregion
#region LoadServiceData ( )
private void LoadServiceData ( SQLiteCommand cmd )
{
cmd . CommandText = @ "
2017-06-08 20:01:42 +02:00
select s . pid , s . type , anls . Frequency , digs . TunerId , digs . Sid , Name , ShortName , Encrypted , Visible , Selectable , ParentalLock , MediaType
2017-03-31 16:55:37 +02:00
from service s
left outer join AnalogService anls on anls . ServiceId = s . Pid
left outer join DVBService digs on digs . ServiceId = s . Pid
";
using ( var r = cmd . ExecuteReader ( ) )
{
while ( r . Read ( ) )
{
ChannelInfo ci = null ;
2017-06-08 20:01:42 +02:00
if ( ! r . IsDBNull ( 2 ) ) // AnalogService
2017-03-31 16:55:37 +02:00
ci = new ChannelInfo ( SignalSource . Analog , r . GetInt32 ( 0 ) , - 1 , r . GetString ( 5 ) ) ;
2017-06-08 20:01:42 +02:00
else if ( ! r . IsDBNull ( 3 ) ) // DvbService
2017-03-31 16:55:37 +02:00
{
2017-06-08 20:01:42 +02:00
var trans = ( HisTransponder ) DataRoot . Transponder . TryGet ( r . GetInt32 ( 3 ) ) ;
2017-03-31 16:55:37 +02:00
ci = new ChannelInfo ( trans . SignalSource , r . GetInt32 ( 0 ) , - 1 , r . GetString ( 5 ) ) ;
ci . Transponder = trans ;
ci . FreqInMhz = trans . FrequencyInMhz ;
ci . OriginalNetworkId = trans . OriginalNetworkId ;
ci . TransportStreamId = trans . TransportStreamId ;
ci . Source = trans . Source ;
ci . ServiceId = r . GetInt32 ( 4 ) ;
ci . ShortName = r . GetString ( 6 ) ;
ci . Encrypted = r . GetInt32 ( 7 ) ! = 0 ;
ci . Hidden = r . GetInt32 ( 8 ) = = 0 ;
ci . Skip = r . GetInt32 ( 9 ) = = 0 ;
ci . Lock = r . GetInt32 ( 10 ) ! = 0 ;
2017-06-08 20:01:42 +02:00
var mediaType = r . GetInt32 ( 11 ) ;
if ( mediaType = = 1 )
{
ci . SignalSource | = SignalSource . Tv ;
ci . ServiceTypeName = "TV" ;
}
else if ( mediaType = = 2 )
{
ci . SignalSource | = SignalSource . Radio ;
ci . ServiceTypeName = "Radio" ;
}
else
ci . ServiceTypeName = mediaType . ToString ( ) ;
2017-03-31 16:55:37 +02:00
}
2017-06-08 20:01:42 +02:00
else if ( r . GetInt32 ( 1 ) = = 0 ) // A/V input
{
2017-03-31 16:55:37 +02:00
ci = new ChannelInfo ( SignalSource . AvInput , r . GetInt32 ( 0 ) , - 1 , r . GetString ( 5 ) ) ;
2017-06-08 20:01:42 +02:00
ci . ServiceTypeName = "A/V" ;
}
2017-03-31 16:55:37 +02:00
if ( ci ! = null )
channelsById . Add ( ci . RecordIndex , ci ) ;
}
}
}
#endregion
#region LoadFavorites ( )
private void LoadFavorites ( SQLiteCommand cmd )
{
2017-06-08 20:01:42 +02:00
cmd . CommandText = @ "
select fi . FavoriteId , fi . ServiceId , fi . ChannelNum , fi . Selectable , fi . Visible , fi . isDeleted , fi . Protected , l . Lcn
from FavoriteItem fi
left outer join Lcn l on l . ServiceId = fi . ServiceId and l . FavoriteId = fi . FavoriteId
";
2017-03-31 16:55:37 +02:00
using ( var r = cmd . ExecuteReader ( ) )
{
while ( r . Read ( ) )
{
int favListId = r . GetInt32 ( 0 ) ;
var ci = channelsById . TryGet ( r . GetInt32 ( 1 ) ) ;
2017-06-08 20:01:42 +02:00
if ( ci = = null )
continue ;
int favListIdx = favListIdToFavIndex . TryGet ( favListId , - 1 ) ;
if ( favListIdx > = 0 )
2019-11-10 20:09:27 +01:00
ci . OldFavIndex [ favListIdx ] = r . GetInt32 ( 2 ) ;
2017-06-08 20:01:42 +02:00
ci . SetOldPosition ( favListIdx + 1 , r . GetInt32 ( 2 ) ) ; // 0=main nr, 1-4=fav 1-4
if ( favListIdx < 0 )
2017-03-31 16:55:37 +02:00
{
2017-06-08 20:01:42 +02:00
// physical channel list (specific satellite, $av, ...)
2017-03-31 16:55:37 +02:00
var list = channelLists . TryGet ( favListId ) ;
2017-06-08 20:01:42 +02:00
if ( ! r . IsDBNull ( 7 ) ) // LCN
{
ci . ProgramNrPreset = r . GetInt32 ( 7 ) ;
#if LOCK_LCN_LISTS
list . ReadOnly = true ;
#endif
}
ci . Skip = r . GetInt32 ( 3 ) = = 0 ;
ci . Lock = r . GetInt32 ( 6 ) ! = 0 ;
ci . Hidden = r . GetInt32 ( 4 ) = = 0 ;
ci . IsDeleted = r . GetInt32 ( 5 ) ! = 0 ;
ci . Source = list . ShortCaption ;
if ( ci . IsDeleted )
ci . OldProgramNr = - 1 ;
if ( ( ci . SignalSource & ( SignalSource . MaskAntennaCableSat | SignalSource . MaskAnalogDigital ) ) = = SignalSource . DvbS )
ci . Satellite = list . ShortCaption ;
2017-03-31 16:55:37 +02:00
DataRoot . AddChannel ( list , ci ) ;
}
}
}
foreach ( var ci in channelsById . Values )
2017-06-08 20:01:42 +02:00
DataRoot . AddChannel ( userFavList , ci ) ;
2017-03-31 16:55:37 +02:00
}
#endregion
// Saving ====================================
#region Save ( )
public override void Save ( string tvOutputFile )
{
if ( tvOutputFile ! = FileName )
File . Copy ( FileName , tvOutputFile , true ) ;
using ( var conn = new SQLiteConnection ( "Data Source=" + tvOutputFile ) )
{
conn . Open ( ) ;
using ( var trans = conn . BeginTransaction ( ) )
using ( var cmd = conn . CreateCommand ( ) )
{
cmd . Transaction = trans ;
try
{
#if ! LOCK_LCN_LISTS
ResetLcn ( cmd ) ;
#endif
2017-06-08 20:01:42 +02:00
UpdateServices ( cmd ) ;
UpdatePhysicalChannelLists ( cmd ) ;
UpdateUserFavoriteLists ( cmd ) ;
2017-03-31 16:55:37 +02:00
trans . Commit ( ) ;
FileName = tvOutputFile ;
}
catch
{
trans . Rollback ( ) ;
throw ;
}
}
}
}
#endregion
2017-06-08 20:01:42 +02:00
#region ResetLcn ( )
2017-03-31 16:55:37 +02:00
2017-06-08 20:01:42 +02:00
private void ResetLcn ( SQLiteCommand cmd )
2017-03-31 16:55:37 +02:00
{
2017-06-08 20:01:42 +02:00
cmd . CommandText = "delete from Lcn where FavoriteId<>" + pidAv ;
cmd . ExecuteNonQuery ( ) ;
2017-03-31 16:55:37 +02:00
}
#endregion
2017-06-08 20:01:42 +02:00
#region UpdateServices ( )
private void UpdateServices ( SQLiteCommand cmd )
2017-03-31 16:55:37 +02:00
{
2017-06-08 20:01:42 +02:00
cmd . CommandText = "update Service set Name=@name, ShortName=@sname, ParentalLock=@lock, Visible=@vis, Selectable=@sel, FavTag=@fav1, FavTag2=@fav1, FavTag3=@fav3, FavTag4=@fav4 where Pid=@servId" ;
cmd . Parameters . Clear ( ) ;
cmd . Parameters . Add ( "@servId" , DbType . Int32 ) ;
cmd . Parameters . Add ( "@name" , DbType . String ) ;
cmd . Parameters . Add ( "@sname" , DbType . String ) ;
cmd . Parameters . Add ( "@lock" , DbType . Int32 ) ;
cmd . Parameters . Add ( "@vis" , DbType . Int32 ) ;
cmd . Parameters . Add ( "@sel" , DbType . Int32 ) ;
cmd . Parameters . Add ( "@fav1" , DbType . Int32 ) ;
cmd . Parameters . Add ( "@fav2" , DbType . Int32 ) ;
cmd . Parameters . Add ( "@fav3" , DbType . Int32 ) ;
cmd . Parameters . Add ( "@fav4" , DbType . Int32 ) ;
cmd . Prepare ( ) ;
foreach ( var ci in channelsById . Values )
2017-03-31 16:55:37 +02:00
{
2017-06-08 20:01:42 +02:00
cmd . Parameters [ "@servId" ] . Value = ci . RecordIndex ;
cmd . Parameters [ "@name" ] . Value = ci . Name ;
cmd . Parameters [ "@sname" ] . Value = ci . ShortName ;
cmd . Parameters [ "@lock" ] . Value = ci . Lock ? 1 : 0 ;
cmd . Parameters [ "@vis" ] . Value = ci . Hidden ? 0 : 1 ;
cmd . Parameters [ "@sel" ] . Value = ci . Skip ? 0 : 1 ;
cmd . Parameters [ "@fav1" ] . Value = ( ci . Favorites & Favorites . A ) ! = 0 ? 1 : 0 ;
cmd . Parameters [ "@fav2" ] . Value = ( ci . Favorites & Favorites . B ) ! = 0 ? 1 : 0 ;
cmd . Parameters [ "@fav3" ] . Value = ( ci . Favorites & Favorites . C ) ! = 0 ? 1 : 0 ;
cmd . Parameters [ "@fav4" ] . Value = ( ci . Favorites & Favorites . D ) ! = 0 ? 1 : 0 ;
2017-03-31 16:55:37 +02:00
cmd . ExecuteNonQuery ( ) ;
}
}
#endregion
2017-06-08 20:01:42 +02:00
#region UpdatePhysicalChannelLists ( )
private void UpdatePhysicalChannelLists ( SQLiteCommand cmd )
2017-03-31 16:55:37 +02:00
{
2017-06-08 20:01:42 +02:00
cmd . CommandText = "update FavoriteItem set ChannelNum=@ch, isDeleted=@del, Protected=@prot, Selectable=@sel, Visible=@vis where FavoriteId=@favId and ServiceId=@servId" ;
2017-03-31 16:55:37 +02:00
cmd . Parameters . Clear ( ) ;
2017-06-08 20:01:42 +02:00
cmd . Parameters . Add ( "@favId" , DbType . Int32 ) ;
cmd . Parameters . Add ( "@servId" , DbType . Int32 ) ;
cmd . Parameters . Add ( "@ch" , DbType . Int32 ) ;
cmd . Parameters . Add ( "@del" , DbType . Int32 ) ;
cmd . Parameters . Add ( "@prot" , DbType . Int32 ) ;
cmd . Parameters . Add ( "@sel" , DbType . Int32 ) ;
cmd . Parameters . Add ( "@vis" , DbType . Int32 ) ;
cmd . Prepare ( ) ;
foreach ( var entry in channelLists )
{
var list = entry . Value ;
if ( list . ReadOnly ) // don't update read-only lists (i.e. containing LCNs)
continue ;
2017-03-31 16:55:37 +02:00
2017-06-08 20:01:42 +02:00
// don't update the $all list directly. It will be updated while iterating all other lists
var favId = entry . Key ;
if ( favId = = pidAll )
continue ;
foreach ( var ci in list . Channels )
2017-03-31 16:55:37 +02:00
{
2017-06-08 20:01:42 +02:00
if ( ci . IsProxy ) // ignore proxies for missing channels that might have been added by applying a reference list
continue ;
cmd . Parameters [ "@favId" ] . Value = favId ;
cmd . Parameters [ "@servId" ] . Value = ci . RecordIndex ;
2019-11-08 02:31:44 +01:00
cmd . Parameters [ "@ch" ] . Value = ci . NewProgramNr ;
cmd . Parameters [ "@del" ] . Value = ci . IsDeleted ? 1 : 0 ; // 1 or -1 ?
2017-06-08 20:01:42 +02:00
// not sure if the following columns are used at all. they also exist in the Services table
cmd . Parameters [ "@prot" ] . Value = ci . Lock ? - 1 : 0 ;
cmd . Parameters [ "@sel" ] . Value = ci . Skip ? 0 : - 1 ;
cmd . Parameters [ "@vis" ] . Value = ci . Hidden ? 0 : - 1 ;
2017-03-31 16:55:37 +02:00
cmd . ExecuteNonQuery ( ) ;
2017-06-08 20:01:42 +02:00
// update the $all list with the same values
if ( pidAll ! = 0 & & favId ! = pidAv )
2017-03-31 16:55:37 +02:00
{
2017-06-08 20:01:42 +02:00
cmd . Parameters [ "@favId" ] . Value = pidAll ;
2017-03-31 16:55:37 +02:00
cmd . ExecuteNonQuery ( ) ;
}
}
2017-06-08 20:01:42 +02:00
}
2017-03-31 16:55:37 +02:00
}
#endregion
2017-06-08 20:01:42 +02:00
#region UpdateUserFavoriteLists ( )
private void UpdateUserFavoriteLists ( SQLiteCommand cmd )
2017-03-31 16:55:37 +02:00
{
2017-06-08 20:01:42 +02:00
// delete all FavoriteItem records that belong to the FAV1-4 lists
cmd . Parameters . Clear ( ) ;
cmd . CommandText = "delete from FavoriteItem where FavoriteId in (select Pid from FavoriteList where name like 'FAV_')" ;
cmd . ExecuteNonQuery ( ) ;
2017-03-31 16:55:37 +02:00
2017-06-08 20:01:42 +02:00
// (re-)insert the user's new favorites
cmd . CommandText = "insert into FavoriteItem (FavoriteId, ServiceId, ChannelNum) values (@favId, @servId, @ch)" ;
cmd . Parameters . Add ( "@favId" , DbType . Int32 ) ;
cmd . Parameters . Add ( "@servId" , DbType . Int32 ) ;
cmd . Parameters . Add ( "@ch" , DbType . Int32 ) ;
foreach ( var entry in favListIdToFavIndex )
{
var favIndex = entry . Value ;
cmd . Parameters [ "@favId" ] . Value = entry . Key ;
foreach ( var ci in userFavList . Channels )
{
if ( ci . IsProxy ) // ignore proxies for missing channels that might have been added by applying a reference list
continue ;
2017-03-31 16:55:37 +02:00
2017-06-08 20:01:42 +02:00
var num = ci . GetPosition ( favIndex + 1 ) ;
if ( num > 0 )
{
cmd . Parameters [ "@servId" ] . Value = ci . RecordIndex ;
cmd . Parameters [ "@ch" ] . Value = num ;
cmd . ExecuteNonQuery ( ) ;
}
}
}
2017-03-31 16:55:37 +02:00
}
#endregion
}
}