void IEpgDataSink.EndChannelPrograms(string id, string name) { if (_currentChannels == null) { return; } if (_channelPrograms.Count == 0) { return; } // Sort programs _channelPrograms.SortIfNeeded(); _channelPrograms.AlreadySorted = true; // Fix end times _channelPrograms.FixEndTimes(); ClipProgramsToWindow(); // Remove overlapping programs _channelPrograms.RemoveOverlappingPrograms(); if (!_deleteExisting) { // Remove programs overlapping ones in DB: // First retrieve all programs for current channels SqlBuilder sb = new SqlBuilder(StatementType.Select, typeof(Program)); sb.AddConstraint(Operator.In, "idChannel", _currentChannels, "IdChannel"); //sb.AddConstraint(Operator.Equals, "idChannel", _currentChannels.IdChannel); //sb.AddOrderByField(false, "starttime"); SqlStatement stmt = sb.GetStatement(true); ProgramList dbPrograms = new ProgramList(ObjectFactory.GetCollection <Program>(stmt.Execute())); _channelPrograms.RemoveOverlappingPrograms(dbPrograms); } foreach (Channel chan in _currentChannels) { layer.RemoveOldPrograms(chan.IdChannel); } DeleteBeforeImportOption programsToDelete = _deleteExisting ? DeleteBeforeImportOption.OverlappingPrograms : DeleteBeforeImportOption.None; layer.InsertPrograms(_channelPrograms, programsToDelete, ThreadPriority.BelowNormal); //_channelPrograms.Clear(); _channelPrograms = null; _currentChannels = null; }
/// <summary> /// Batch inserts programs - intended for faster EPG import. You must make sure before that there are no duplicates /// (e.g. delete all program data of the current channel). /// Also you MUST provide a true copy of "aProgramList". If you update it's reference in your own code the values will get overwritten /// (possibly before they are written to disk)! /// </summary> /// <param name="aProgramList">A list of persistable gentle.NET Program objects mapping to the Programs table</param> /// <param name="progamsToDelete">Flag specifying which existing programs to delete before the insert</param> /// <param name="aThreadPriority">Use "Lowest" for Background imports allowing LiveTV, AboveNormal for full speed</param> /// <returns>The record count of programs if successful, 0 on errors</returns> /// <remarks><para>Inserts are queued to be performed in the background. Each batch of inserts is executed in a single transaction. /// You may also optionally specify to delete either all existing programs in the same channel(s) as the programs to be inserted /// (<see cref="DeleteBeforeImportOption.ProgramsOnSameChannel"/>), or existing programs that would otherwise overlap new programs /// (<see cref="DeleteBeforeImportOption.OverlappingPrograms"/>), or none (<see cref="DeleteBeforeImportOption.None"/>). /// The deletion is also performed in the same transaction as the inserts so that EPG will not be at any time empty.</para> /// <para>After all insert have completed and the background thread is idle for 60 seconds, the program states are /// automatically updated to reflect the changes.</para></remarks> public int InsertPrograms(List<Program> aProgramList, DeleteBeforeImportOption progamsToDelete, ThreadPriority aThreadPriority) { try { int sleepTime = 10; switch (aThreadPriority) { case ThreadPriority.Highest: case ThreadPriority.AboveNormal: aThreadPriority = ThreadPriority.Normal; sleepTime = 0; break; case ThreadPriority.Normal: // this is almost enough on dualcore systems for one cpu to gather epg and the other to insert it sleepTime = 10; break; case ThreadPriority.BelowNormal: // on faster systems this might be enough for background importing sleepTime = 20; break; case ThreadPriority.Lowest: // even a single core system is enough to use MP while importing. sleepTime = 40; break; } ImportParams param = new ImportParams(); param.ProgramList = new ProgramList(aProgramList); param.ProgamsToDelete = progamsToDelete; param.SleepTime = sleepTime; param.Priority = aThreadPriority; lock (_programInsertsQueue) { _programInsertsQueue.Enqueue(param); _pendingProgramInserts.Set(); if (_insertProgramsThread == null) { _insertProgramsThread = new Thread(InsertProgramsThreadStart) { Priority = ThreadPriority.Lowest, Name = "SQL EPG importer", IsBackground = true }; _insertProgramsThread.Start(); } } return aProgramList.Count; } catch (Exception ex) { Log.Error("BusinessLayer: InsertPrograms error - {0}, {1}", ex.Message, ex.StackTrace); return 0; } }