/[xmltv_parser]/trunk/GBPVRProgramDatabaseFixer/SQLLITE.cs
ViewVC logotype

Annotation of /trunk/GBPVRProgramDatabaseFixer/SQLLITE.cs

Parent Directory Parent Directory | Revision Log Revision Log


Revision 216 - (hide annotations) (download)
Sun Mar 17 01:15:17 2013 UTC (6 years, 10 months ago) by william
File size: 55901 byte(s)

1 william 156 //#define SQLLITE_CONNECTION_TEST
2     using System;
3     using System.Collections.Generic;
4     using System.Linq;
5     using System.Text;
6     using System.Data.SQLite;
7     using System.Diagnostics;
8     using Enterprise.Logging;
9 william 163 using libxmltv;
10 william 165 using libxmltv.Interfaces;
11     using libxmltv.Core;
12 william 156 namespace GBPVRProgramDatabaseFixer
13     {
14 william 182 public interface IOldNewProgram
15     {
16     SQLLITE.IPROGRAMME OldProgram { get; }
17     SQLLITE.IPROGRAMME NewProgram { get; }
18     }
19 william 163 public interface ISQLLITE
20 william 156 {
21 william 163 List<SQLLITE.IPROGRAMME> Programs { get; }
22     List<SQLLITE.IRECORDING_SCHEDULE> Recordings { get; }
23     List<SQLLITE.ICHANNEL> Channels { get; }
24     IDateTimeRange GetProgramsDateRange(List<SQLLITE.IPROGRAMME> programs);
25 william 215 List<IOldNewProgram> FixGBPVRProgramsDatabase(List<SQLLITE.IPROGRAMME> gbpvr_programs, List<libxmltv.Interfaces.IProgramDefinition> xmltv_programs, out List<SQLLITE.IPROGRAMME> removed_programs);
26 william 163
27 william 183 void RemoveOldGBPVRPrograms(List<SQLLITE.IPROGRAMME> programs);
28 william 215 void UpdateGBPVRPrograms(List<IOldNewProgram> programs);
29 william 183
30 william 163 }
31     public class SQLLITE : ISQLLITE
32     {
33 william 182 private class OldNewProgram : IOldNewProgram
34 william 176 {
35 william 215 public OldNewProgram() : this(new PROGRAMME()) { }
36     public OldNewProgram(IPROGRAMME _old) : this(_old,_old) { }
37 william 180 public OldNewProgram(IPROGRAMME _old, IPROGRAMME _new) { OldProgram = _old; NewProgram = _new; }
38    
39     public IPROGRAMME OldProgram { get; private set; }
40     public IPROGRAMME NewProgram { get; private set; }
41 william 176 }
42 william 163 public static ISQLLITE Create(string database, EventHandler<EventArgs> OnInstanceCreated)
43     {
44     return new SQLLITE(database, OnInstanceCreated);
45     }
46    
47 william 156 #region DATABASE DEFINITIONS
48 william 159
49     public interface ICHANNEL
50     {
51     Int64 oid { get; }
52     String name { get; }
53     String channelID { get; }
54     Int64 channel_number { get; }
55     String favourite_channel { get; }
56     String display_name { get; }
57     }
58     private class CHANNEL : ICHANNEL
59     {
60 william 184 public CHANNEL()
61 william 159 {
62 william 184 BaseDatabaseDefinition<CHANNEL>.CreateDefault(this);
63 william 159 }
64     //public RECORDING_SCHEDULE(SQLiteDataReader r, int index) { BaseDatabaseDefinition<RECORDING_SCHEDULE>.Create(this, r, index); }
65    
66     public static void Create(ref CHANNEL instance, SQLiteDataReader r, int index)
67     {
68     BaseDatabaseDefinition<CHANNEL>.Create(ref instance, r, index);
69     }
70     #region ICHANNEL members
71     public Int64 oid { get; set; }
72     public String name { get; set; }
73     public String channelID { get; set; }
74     public Int64 channel_number { get; set; }
75     public String favourite_channel { get; set; }
76     public String display_name { get; set; }
77     #endregion
78     }
79 william 156 public interface IRECORDING_SCHEDULE
80     {
81     Int64 oid { get; }
82     Int64 programme_oid { get; }
83     Int64 capture_source_oid { get; }
84     Int16 status { get; }
85     String filename { get; }
86     Int64 recording_type { get; }
87     Int64 recording_group { get; }
88     DateTime manual_start_time { get; }
89     DateTime manual_end_time { get; }
90     Int64 manual_channel_oid { get; }
91     Int64 quality_level { get; }
92     Int64 pre_pad_minutes { get; }
93 william 184 Int64 post_pad_minutes { get; }
94 william 156 Int32 priority { get; }
95     String conversion_profile { get; }
96     }
97    
98     private static class BaseDatabaseDefinition<T>
99     {
100     public static void CreateDefault(T instance)
101     {
102     try
103     {
104     Type t = typeof(T);
105     var props = t.GetProperties();
106     foreach (var prop in props)
107     {
108     Type prop_type = prop.PropertyType;
109     object field_value = null;
110     try
111     {
112     if (prop_type == typeof(string))
113     {
114     field_value = string.Empty;
115     }
116     else
117     {
118     field_value = Activator.CreateInstance(prop_type);
119     }
120     }
121     catch (Exception ex)
122     {
123     throw ex;
124     }
125     prop.SetValue(instance, field_value, null);
126     }
127     }
128     catch (Exception ex)
129     {
130     throw ex;
131     }
132     }
133     public static void Create(ref T instance, SQLiteDataReader r, int index)
134 william 184 {
135 william 156 string field_name = r.GetName(index);
136     Type field_type = r.GetFieldType(index);
137     object field_value = r.GetValue(index);
138     //gLog.Verbose.Debug.WriteLine("Name: '{0}' Type: '{1}' Value: '{2}'", field_name, field_type.Name, field_value == null ? "null" : field_value.ToString());
139    
140     Type t = typeof(T);
141     var props = t.GetProperties();
142     foreach (var prop in props)
143     {
144     if (prop.Name.ToLower() == field_name.ToLower())
145     {
146     if (prop.PropertyType == field_type)
147     {
148     Type db_type = field_value.GetType();
149     try
150     {
151     if (db_type == typeof(System.DBNull))
152     {
153     prop.SetValue(instance, null, null);
154     }
155     else
156     {
157     prop.SetValue(instance, field_value, null);
158     }
159 william 184
160 william 156 }
161 william 184 catch (Exception ex)
162 william 156 {
163     throw ex;
164     }
165     }
166     else
167     {
168     gLog.Verbose.Debug.WriteLine("Found Property: {0} but there was a type mismatch. Property Type: '{1}' Expected: '{2}'", prop.Name, prop.PropertyType.Name, field_type.Name);
169     throw new InvalidOperationException(string.Format("Found Property: {0} but there was a type mismatch. Property Type: '{1}' Expected: '{2}'", prop.Name, prop.PropertyType.Name, field_type.Name));
170     }
171     }
172     }
173    
174     }
175     }
176    
177     private class RECORDING_SCHEDULE : IRECORDING_SCHEDULE
178     {
179 william 184 public RECORDING_SCHEDULE()
180 william 156 {
181 william 184 BaseDatabaseDefinition<RECORDING_SCHEDULE>.CreateDefault(this);
182 william 156 }
183     //public RECORDING_SCHEDULE(SQLiteDataReader r, int index) { BaseDatabaseDefinition<RECORDING_SCHEDULE>.Create(this, r, index); }
184    
185     public static void Create(ref RECORDING_SCHEDULE instance, SQLiteDataReader r, int index)
186     {
187 william 184 BaseDatabaseDefinition<RECORDING_SCHEDULE>.Create(ref instance, r, index);
188 william 156 }
189    
190     #region IRECORDING_SCHEDULE members
191 william 184 public Int64 oid { get; set; }
192     public Int64 programme_oid { get; set; }
193     public Int64 capture_source_oid { get; set; }
194 william 156 public Int16 status { get; set; }
195     public String filename { get; set; }
196 william 184 public Int64 recording_type { get; set; }
197     public Int64 recording_group { get; set; }
198     public DateTime manual_start_time { get; set; }
199 william 156 public DateTime manual_end_time { get; set; }
200     public Int64 manual_channel_oid { get; set; }
201     public Int64 quality_level { get; set; }
202     public Int64 pre_pad_minutes { get; set; }
203     public Int64 post_pad_minutes { get; set; }
204     public Int32 priority { get; set; }
205     public String conversion_profile { get; set; }
206     #endregion
207     }
208    
209 william 182 public interface IPROGRAMME : IEquatable<IPROGRAMME>
210 william 184 {
211 william 168 Int64 oid { get; set; }
212     String name { get; set; }
213     String sub_title { get; set; }
214     String description { get; set; }
215     DateTime start_time { get; set; }
216     DateTime end_time { get; set; }
217     Int64 channel_oid { get; set; }
218     String unique_identifier { get; set; }
219     String rating { get; set; }
220 william 165
221 william 182 string ToString();
222 william 165 IProgramDefinition AsXMLTVProgramDefinition(ISQLLITE sqllite);
223 william 156 }
224     private class PROGRAMME : IPROGRAMME
225     {
226 william 184 public PROGRAMME()
227 william 156 {
228 william 184 BaseDatabaseDefinition<PROGRAMME>.CreateDefault(this);
229 william 156 }
230     //public PROGRAMME(SQLiteDataReader r, int index) : base(r, index) { }
231     public static void Create(ref PROGRAMME instance, SQLiteDataReader r, int index)
232     {
233     BaseDatabaseDefinition<PROGRAMME>.Create(ref instance, r, index);
234     }
235     #region IPROGRAMME members
236     public Int64 oid { get; set; }
237     public String name { get; set; }
238     public String sub_title { get; set; }
239     public String description { get; set; }
240     public DateTime start_time { get; set; }
241     public DateTime end_time { get; set; }
242     public Int64 channel_oid { get; set; }
243     public String unique_identifier { get; set; }
244     public String rating { get; set; }
245 william 165 public IProgramDefinition AsXMLTVProgramDefinition(ISQLLITE sqllite)
246     {
247     ProgramList.ProgramDefintion definition = new ProgramList.ProgramDefintion();
248 william 181
249 william 165 var channel = sqllite.Channels.Find(s => s.oid == this.channel_oid);
250 william 181 var channelname = channel.display_name;
251     var split = channelname.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
252     definition.ChannelNumber = Convert.ToInt32(split.First());
253     definition.ChannelName = string.IsNullOrEmpty(split.Last()) ? string.Empty : split.Last().ToString();
254 william 165 definition.Description = this.description;
255 william 168 definition.Start = this.start_time.ToDateTimeString();
256     definition.Stop = this.end_time.ToDateTimeString();
257 william 165 definition.SubTitle = this.sub_title;
258     definition.Title = this.name;
259     return definition;
260     }
261 william 156 #endregion
262 william 182
263     public bool Equals(IPROGRAMME other)
264     {
265     return this.ToString() == other.ToString();
266     }
267     public override string ToString()
268     {
269     StringBuilder builder = new StringBuilder();
270    
271     builder.AppendFormat("oid: '{0}' ", oid);
272     builder.AppendFormat("name: '{0}' ", name);
273     builder.AppendFormat("sub_title: '{0}' ", sub_title);
274     builder.AppendFormat("description: '{0}' ", description);
275     builder.AppendFormat("start_time: '{0}' ", start_time.ToDateTimeString());
276     builder.AppendFormat("end_time: '{0}' ", end_time.ToDateTimeString());
277     builder.AppendFormat("channel_oid: '{0}' ", channel_oid);
278     builder.AppendFormat("unique_identifier: '{0}' ", unique_identifier);
279     builder.AppendFormat("rating: '{0}'", rating);
280    
281     return builder.ToString();
282     }
283     public override bool Equals(object obj)
284     {
285     if (obj == null) { throw new ArgumentNullException("obj", "Object to compare cannot be null"); }
286     if (obj.GetType().IsAssignableFrom(typeof(IPROGRAMME)))
287     {
288     return this.Equals((IPROGRAMME)obj);
289     }
290     return base.Equals(obj);
291     }
292     public override int GetHashCode()
293     {
294     return this.ToString().GetHashCode();
295     }
296 william 156 }
297     #endregion
298     private static class TABLES
299     {
300     public const string RECORDING_SCHEDULE = "RECORDING_SCHEDULE";
301     public const string PROGRAMME = "PROGRAMME";
302 william 159 public const string CHANNEL = "CHANNEL";
303 william 156 }
304 william 203 private string DATABASE_BACKUP_FILE = string.Empty;
305 william 156 //public SQLLite() { }
306 william 184 protected SQLLITE(string database, EventHandler<EventArgs> OnInstanceCreated)
307 william 156 {
308     this.OnInstanceCreated = OnInstanceCreated;
309     //CreateConnection(database);
310     this.Database = database;
311 william 157 if (!CreateDatabaseBackup())
312     {
313     gLog.Error.WriteLine("Failed to backup database.");
314     return;
315     }
316 william 156 ConnectionTest();
317 william 159 ReadChannelData();
318 william 156 ReadRecodringScheduleData();
319     ReadProgrammeData();
320     OnCreatedInstance(this, new EventArgs());
321     }
322    
323     [NonSerialized]
324     private EventHandler<EventArgs> _OnInstanceCreated;
325     private EventHandler<EventArgs> OnInstanceCreated { get { return _OnInstanceCreated; } set { _OnInstanceCreated = value; } }
326 william 184
327 william 156 private void OnCreatedInstance(object sender, EventArgs e)
328     {
329     if (OnInstanceCreated != null) { OnInstanceCreated.Invoke(sender, e); }
330     }
331    
332     private string Database;
333 william 184 #region ISQLLITE members
334 william 156 public List<IPROGRAMME> Programs { get; private set; }
335     public List<IRECORDING_SCHEDULE> Recordings { get; private set; }
336 william 159 public List<ICHANNEL> Channels { get; private set; }
337 william 163
338     public IDateTimeRange GetProgramsDateRange(List<SQLLITE.IPROGRAMME> programs)
339     {
340     var list = new List<IPROGRAMME>(programs.ToArray());
341     DateTime first = new DateTime();
342     DateTime last = new DateTime();
343 william 184 first = list.OrderBy(s => s.start_time).ToList().First().start_time;
344 william 163 last = list.OrderBy(s => s.start_time).ToList().Last().start_time;
345 william 167 gLog.Verbose.Debug.WriteLine("\tFirst: {0} = ({1})", first.ToString("yyyy/MM/dd HH:mm:ss.fffffff"), first.ToDateTimeString());
346     gLog.Verbose.Debug.WriteLine("\tLast: {0} = ({1})", last.ToString("yyyy/MM/dd HH:mm:ss.fffffff"), last.ToDateTimeString());
347 william 163 var range = DateTimeRange.Create(first, last);
348     return range;
349     }
350    
351 william 215 public List<IOldNewProgram> FixGBPVRProgramsDatabase(List<SQLLITE.IPROGRAMME> gbpvr_programs, List<libxmltv.Interfaces.IProgramDefinition> xmltv_programs, out List<SQLLITE.IPROGRAMME> source_invalid)
352 william 163 {
353 william 169 source_invalid = new List<IPROGRAMME>();
354 william 215 List<IOldNewProgram> source_valid = new List<IOldNewProgram>();
355 william 180 gbpvr_programs = gbpvr_programs.OrderBy(s => s.start_time).ToList();
356     xmltv_programs = xmltv_programs.OrderBy(s => DateTime.Parse(s.Start)).ToList();
357     gbpvr_programs.TrimExcess();
358     xmltv_programs.TrimExcess();
359 william 176
360 william 168 double total = gbpvr_programs.Count;
361 william 166 double index = 0;
362     double progress = 0;
363 william 168 foreach (var program in gbpvr_programs)
364 william 180 {
365 william 169 progress = 100.0 * (index / total);
366 william 184 gLog.ReportProgress(this, new ReportProgressEventArgs((int)progress, string.Format("Filtering GBPVR Programs: {0:00}%", (int)progress)));
367 william 180 // find an entry in xmltv_programs by Channel Number & StartDate
368     var program_xmltv_entry = program.AsXMLTVProgramDefinition(this);
369     var xmltv_entry = xmltv_programs.Find(s => s.ChannelNumber == program_xmltv_entry.ChannelNumber && s.Start == program_xmltv_entry.Start);
370 william 168 if (xmltv_entry == null)
371 william 163 {
372 william 180 // xmltv entry was not found
373     source_invalid.Add(program);
374 william 163 }
375 william 164 else
376     {
377 william 180 // check if the xmltv entry has different data from the current program
378 william 184 if (!xmltv_entry.Equals(program_xmltv_entry))
379 william 172 {
380 william 180 // data is different
381 william 182 var updated_program = program;
382    
383     if (program_xmltv_entry.Title != xmltv_entry.Title)
384 william 180 {
385 william 182 gLog.Verbose.Warn.WriteLine(" Program oid: '{0}' - replacing title", updated_program.oid);
386     updated_program.name = xmltv_entry.Title;
387 william 180 }
388 william 182 if (program_xmltv_entry.SubTitle != xmltv_entry.SubTitle)
389     {
390     gLog.Verbose.Warn.WriteLine(" Program oid: '{0}' - replacing sub_title", updated_program.oid);
391     updated_program.sub_title = xmltv_entry.SubTitle;
392     }
393     if (program_xmltv_entry.Stop != xmltv_entry.Stop)
394     {
395     gLog.Verbose.Warn.WriteLine(" Program oid: '{0}' - replacing end_time", updated_program.oid);
396     updated_program.end_time = DateTime.Parse(xmltv_entry.Stop);
397     }
398     if (program_xmltv_entry.Start != xmltv_entry.Start)
399     {
400     gLog.Verbose.Warn.WriteLine(" Program oid: '{0}' - replacing start_time", updated_program.oid);
401     updated_program.start_time = DateTime.Parse(xmltv_entry.Start);
402     }
403     if (program_xmltv_entry.Description != xmltv_entry.Description)
404     {
405     gLog.Verbose.Warn.WriteLine(" Program oid: '{0}' - replacing description", updated_program.oid);
406     updated_program.description = xmltv_entry.Description;
407     }
408    
409     var updated_xmltv_entry = updated_program.AsXMLTVProgramDefinition(this);
410     if (!xmltv_entry.Equals(updated_xmltv_entry))
411     {
412     throw new Exception(string.Format("Program oid '{0}' was not properly updated.", updated_program.oid));
413     }
414 william 196 //source_valid.Add(new OldNewProgram(program, updated_program));
415 william 215 source_valid.Add(new OldNewProgram(program, updated_program));
416 william 172 }
417 william 176 else
418     {
419 william 180 // data is the same
420 william 196 //source_valid.Add(new OldNewProgram(program, program));
421 william 215 source_valid.Add(new OldNewProgram(program));
422 william 176 }
423     }
424 william 181 index++;
425 william 176 }
426 william 192 gLog.Info.WriteLine("Total XMLTV Programs: 0x{0:x8}", xmltv_programs.Count);
427     gLog.Info.WriteLine("Total Valid GB-PVR Programs: 0x{0:x8}", source_valid.Count);
428     gLog.Info.WriteLine("Total Invalid GB-PVR Programs: 0x{0:x8}", source_invalid.Count);
429     gLog.Info.WriteLine("Total GB-PVR Programs (Valid+Invalid): 0x{0:x8} == 0x{1:x8}", source_valid.Count + source_invalid.Count, gbpvr_programs.Count);
430 william 180 #region old-code
431     //List<OldNewProgram> source_update = new List<OldNewProgram>();
432     ////if (range == null)
433     ////{
434     //// gLog.Warn.WriteLine("The DateTimeRange passed in is null...returning the original program list");
435     //// return list;
436     ////}
437     ////gLog.Warn.WriteLine("FilterProgramsByDateRange has not been implemented");
438     //double total = gbpvr_programs.Count;
439     //double index = 0;
440     //double progress = 0;
441     //foreach (var program in gbpvr_programs)
442     //{
443     // progress = 100.0 * (index / total);
444     // gLog.ReportProgress(this, new ReportProgressEventArgs((int)progress, string.Format("Filtering GBPVR Programs: {0:00}%", (int)progress)));
445     // var channel_oid = program.channel_oid;
446     // var channel = this.Channels.Find(s => s.oid == channel_oid);
447     // var start_date = program.start_time;
448     // //var xmltv_entry_list = xmltv_programs.FindAll(s => s.ChannelNumber == channel.channel_number && s.Start == start_date.ToDateTimeString());
449     // var query = from c in xmltv_programs
450     // where
451     // c.ChannelNumber == channel.channel_number &&
452     // c.Start == start_date.ToDateTimeString()
453     // select c;
454     // IProgramDefinition xmltv_entry = null;
455     // if (query.Count()-1 > 0)
456     // {
457     // gLog.Verbose.Error.WriteLine("Found more than one entry: Matching channel='{0}' and start='{1}'", channel.channel_number, start_date.ToDateTimeString());
458     // gLog.Verbose.Error.WriteLine(" GB-PVR Program Data: oid='{0}' channel_oid='{1}' name='{2}' sub_title='{3}' description='{4}'", program.oid, program.channel_oid, program.name, program.sub_title, program.description);
459     // if (Debugger.IsAttached)
460     // {
461     // gLog.Error.WriteLine(" Found: {0} matching entries", query.Count());
462     // int k_index = 0;
463     // foreach (var k in query)
464     // {
465     // gLog.Verbose.Error.WriteLine(" query[{0}]: channel='{1}' start='{2}' ('{3}') title='{4}' subtitle='{5}' description='{6}'", k_index, k.ChannelNumber, k.Start, DateTime.Parse(k.Start).ToString("yyyy/MM/dd HH:mm:ss.fffffff"), k.Title, k.SubTitle, k.Description);
466     // k_index++;
467     // }
468     // Debugger.Break();
469     // }
470     // }
471     // else
472     // {
473     // xmltv_entry = query.FirstOrDefault();
474     // }
475     // if (xmltv_entry == null)
476     // {
477     // //gLog.Verbose.Warn.WriteLine("Invalidating GB-PVR Program: oid='{0}' channel_oid='{1}' title='{2}' start='{3}'", program.oid, program.channel_oid, program.name, program.start_time.ToDateTimeString());
478     // source_invalid.Add(program);
479     // }
480     // else
481     // {
482     // //gLog.Verbose.Warn.WriteLine("Updating GB-PVR Program (if needed): oid='{0}' channel_oid='{1}' title='{2}' subtitle='{3}' start='{4}'", program.oid, program.channel_oid, program.name, program.sub_title, program.start_time.ToDateTimeString());
483     // var updated_program = program;
484     // bool needsupdate = false;
485     // if (xmltv_entry.Title != program.name)
486     // {
487     // //gLog.Verbose.Warn.WriteLine(" Updating:");
488     // //gLog.Verbose.Warn.WriteLine(" Old Title: {0}", program.name);
489     // //gLog.Verbose.Warn.WriteLine(" New Title: {0}", xmltv_entry.Title);
490     // updated_program.name = xmltv_entry.Title;
491     // needsupdate = true;
492     // }
493     // if (xmltv_entry.SubTitle != program.sub_title)
494     // {
495     // //gLog.Verbose.Warn.WriteLine(" Updating:");
496     // //gLog.Verbose.Warn.WriteLine(" Old SubTile: {0}", program.sub_title);
497     // //gLog.Verbose.Warn.WriteLine(" New SubTile: {0}", xmltv_entry.SubTitle);
498     // updated_program.sub_title = xmltv_entry.SubTitle;
499     // needsupdate = true;
500     // }
501     // if (xmltv_entry.Description != program.description)
502     // {
503     // //gLog.Verbose.Warn.WriteLine(" Updating:");
504     // //gLog.Verbose.Warn.WriteLine(" Old Descption: {0}", program.description);
505     // //gLog.Verbose.Warn.WriteLine(" New Descption: {0}", xmltv_entry.Description);
506     // updated_program.description = xmltv_entry.Description;
507     // needsupdate = true;
508     // }
509     // if (DateTime.Parse(xmltv_entry.Start) != program.start_time)
510     // {
511     // //gLog.Verbose.Warn.WriteLine(" Updating:");
512     // //gLog.Verbose.Warn.WriteLine(" Old StartTime: {0}", program.start_time.ToDateTimeString());
513     // //gLog.Verbose.Warn.WriteLine(" New StartTime: {0}", DateTime.Parse(xmltv_entry.Start).ToDateTimeString());
514     // updated_program.start_time = DateTime.Parse(xmltv_entry.Start);
515     // needsupdate = true;
516     // }
517     // if (DateTime.Parse(xmltv_entry.Stop) != program.end_time)
518     // {
519     // //gLog.Verbose.Warn.WriteLine(" Updating:");
520     // //gLog.Verbose.Warn.WriteLine(" Old EndTime: {0}", program.end_time.ToDateTimeString());
521     // //gLog.Verbose.Warn.WriteLine(" New EndTime: {0}", DateTime.Parse(xmltv_entry.Stop).ToDateTimeString());
522     // updated_program.end_time = DateTime.Parse(xmltv_entry.Stop);
523     // needsupdate = true;
524     // }
525     // if (needsupdate)
526     // {
527     // OldNewProgram p = new OldNewProgram();
528     // p.OldProgram = program;
529     // p.NewProgram = updated_program;
530     // source_update.Add(p);
531     // }
532     // source_valid.Add(updated_program);
533     // }
534     // index++;
535     //}
536     //source_valid = source_valid.OrderBy(s => s.channel_oid).ThenBy(s => s.start_time).ToList();
537     //source_invalid = source_invalid.OrderBy(s => s.channel_oid).ThenBy(s => s.start_time).ToList();
538     //if (source_invalid.Count > 0)
539     //{
540     // double source_invalid_count = source_valid.Count;
541     // double source_invalid_index = 0;
542     // double source_invalid_progress = 0;
543     // foreach (var old_program in source_invalid)
544     // {
545     // source_invalid_progress = 100.0 * (source_invalid_index / source_invalid_count);
546     // gLog.ReportProgress(this, new ReportProgressEventArgs((int)source_invalid_progress, string.Format("Removing old GBPVR Programs: {0:00}%", (int)source_invalid_progress)));
547     // // remove database entry
548     // if (!RemoveProgramDatabaseEntry(old_program))
549     // {
550     // gLog.Error.WriteLine("Failed to remove program with oid: '{0}'", old_program.oid);
551     // }
552     // else
553     // {
554     // gLog.Verbose.Info.WriteLine("Removed program with oid: '{0}'", old_program.oid);
555     // }
556     // source_invalid_index++;
557     // }
558     //}
559     //else
560     //{
561     // gLog.Info.WriteLine("No old GB-PVR Programs needed to be removed.");
562     //}
563     //if (source_update.Count > 0)
564     //{
565     // double source_update_count = source_valid.Count;
566     // double source_update_index = 0;
567     // double source_update_progress = 0;
568     // foreach (var p in source_update)
569     // {
570     // source_update_progress = 100.0 * (source_update_index / source_update_count);
571     // gLog.ReportProgress(this, new ReportProgressEventArgs((int)source_update_progress, string.Format("Updating GBPVR Programs: {0:00}%", (int)source_update_progress)));
572     // // remove database entry
573     // if (!UpdateProgramDatabaseEntry(p.OldProgram,p.NewProgram))
574     // {
575     // gLog.Error.WriteLine("Failed to update program with oid: '{0}'", p.OldProgram.oid);
576     // }
577     // else
578     // {
579     // gLog.Verbose.Info.WriteLine("Upated program with oid: '{0}'", p.OldProgram.oid);
580     // }
581     // source_update_index++;
582     // }
583     //}
584     //else
585     //{
586     // gLog.Info.WriteLine("No GB-PVR Programs needed to be updated.");
587     //}
588     //gLog.Info.WriteLine("Total XMLTV Programs: 0x{0:x8}", xmltv_programs.Count);
589     //gLog.Info.WriteLine("Updated: 0x{0:x8} GB-PVR Programs", source_valid.Count);
590     //gLog.Info.WriteLine("Removed: 0x{0:x8} GB-PVR Programs", source_invalid.Count);
591     //gLog.Info.WriteLine("Total GB-PVR Programs (Updated & Removed): 0x{0:x8}", source_valid.Count + source_invalid.Count);
592     #endregion
593 william 176
594 william 166 return source_valid;
595 william 163 }
596 william 156 #endregion
597    
598    
599     private string CreateConnectionString()
600     {
601     string connection_string = string.Format("Data Source={0}", this.Database);
602     return connection_string;
603     }
604    
605     private SQLiteConnection CreateConnection() { SQLiteConnection connection = new SQLiteConnection(CreateConnectionString()); return connection; }
606    
607     [Conditional("SQLLITE_CONNECTION_TEST")]
608     private void ConnectionTest()
609     {
610     try
611     {
612     using (SQLiteConnection con = CreateConnection())
613     {
614     con.Open();
615 william 159 string command_text = string.Format("select * from {0};", TABLES.CHANNEL);
616 william 156 gLog.Verbose.Debug.WriteLine("Executing Command: '{0}'", command_text);
617     using (SQLiteCommand cmd = new SQLiteCommand(command_text, con))
618     {
619     using (SQLiteDataReader r = cmd.ExecuteReader())
620     {
621     if (!r.HasRows)
622     {
623     gLog.Warn.WriteLine("Query: '{0}' returned no rows.", cmd.CommandText);
624     }
625     else
626     {
627     while (r.Read())
628     {
629     for (int i = 0; i < r.FieldCount; i++)
630     {
631     string field_name = r.GetName(i);
632     Type field_type = r.GetFieldType(i);
633     object field_value = r.GetValue(i);
634     gLog.Verbose.Debug.WriteLine("Name: '{0}' Type: '{1}' Value: '{2}'", field_name, field_type.Name, field_value == null ? "null" : field_value.ToString());
635     }
636     break;
637     }
638     }
639     }
640     }
641 william 157 con.Clone();
642 william 156 }
643     OnCreatedInstance(this, new EventArgs());
644     }
645     catch (Exception ex)
646     {
647     gLog.Error.WriteLine(ex.ToString());
648     }
649     }
650    
651 william 157
652     private bool CreateDatabaseBackup()
653     {
654     try
655     {
656     string backup_file = string.Format("{0}.{1}", this.Database, DateTime.Now.ToString("yyyyMMddHHmmss"));
657     gLog.Info.WriteLine("Creating Database backup...");
658     gLog.Info.WriteLine("\tSource: {0}", this.Database);
659     gLog.Info.WriteLine("\tDestination: {0}", backup_file);
660    
661     System.IO.File.Copy(this.Database, backup_file);
662 william 203 DATABASE_BACKUP_FILE = backup_file;
663 william 157 return true;
664     }
665     catch (Exception ex)
666     {
667     gLog.Error.WriteLine(ex.ToString());
668     return false;
669     }
670     }
671 william 159 private void ReadChannelData()
672     {
673     try
674     {
675     List<ICHANNEL> channels = new List<ICHANNEL>();
676     using (SQLiteConnection con = CreateConnection())
677     {
678 william 184 try
679 william 159 {
680 william 184 con.Open();
681     string command_text = string.Format("select * from {0};", TABLES.CHANNEL);
682     gLog.Verbose.Debug.WriteLine("Executing Command: '{0}'", command_text);
683     using (SQLiteCommand cmd = new SQLiteCommand(command_text, con))
684 william 159 {
685 william 184 using (SQLiteDataReader r = cmd.ExecuteReader())
686 william 159 {
687 william 184 if (!r.HasRows)
688 william 159 {
689 william 184 gLog.Warn.WriteLine("Query: '{0}' returned no rows.", cmd.CommandText);
690     }
691     else
692     {
693     while (r.Read())
694 william 159 {
695 william 184 CHANNEL channel = new CHANNEL();
696     for (int i = 0; i < r.FieldCount; i++)
697     {
698     CHANNEL.Create(ref channel, r, i);
699     }
700     channels.Add(channel);
701 william 159 }
702     }
703     }
704     }
705     }
706 william 184 catch (SQLiteException ex)
707     {
708     gLog.Error.WriteLine(ex.ToString());
709     }
710     finally
711     {
712     con.Close();
713     }
714 william 159 }
715     this.Channels = channels;
716     }
717     catch (Exception ex)
718     {
719     gLog.Error.WriteLine(ex.ToString());
720     }
721     }
722 william 156 private void ReadProgrammeData()
723     {
724     try
725     {
726     List<IPROGRAMME> programs = new List<IPROGRAMME>();
727     using (SQLiteConnection con = CreateConnection())
728     {
729 william 184 try
730 william 156 {
731 william 184 con.Open();
732     string command_text = string.Format("select * from {0};", TABLES.PROGRAMME);
733     gLog.Verbose.Debug.WriteLine("Executing Command: '{0}'", command_text);
734     using (SQLiteCommand cmd = new SQLiteCommand(command_text, con))
735 william 156 {
736 william 184 using (SQLiteDataReader r = cmd.ExecuteReader())
737 william 156 {
738 william 184 if (!r.HasRows)
739 william 156 {
740 william 184 gLog.Warn.WriteLine("Query: '{0}' returned no rows.", cmd.CommandText);
741     }
742     else
743     {
744     while (r.Read())
745 william 156 {
746 william 184 PROGRAMME program = new PROGRAMME();
747     for (int i = 0; i < r.FieldCount; i++)
748     {
749     PROGRAMME.Create(ref program, r, i);
750     }
751     programs.Add(program);
752 william 156 }
753     }
754     }
755     }
756     }
757 william 184 catch (SQLiteException ex)
758     {
759     gLog.Error.WriteLine(ex.ToString());
760     }
761     finally
762     {
763     con.Close();
764     }
765 william 156 }
766     this.Programs = programs;
767     }
768     catch (Exception ex)
769     {
770     gLog.Error.WriteLine(ex.ToString());
771     }
772     }
773     private void ReadRecodringScheduleData()
774     {
775     try
776     {
777     List<IRECORDING_SCHEDULE> recordings = new List<IRECORDING_SCHEDULE>();
778     using (SQLiteConnection con = CreateConnection())
779     {
780 william 184 try
781 william 156 {
782 william 184 con.Open();
783     string command_text = string.Format("select * from {0};", TABLES.RECORDING_SCHEDULE);
784     gLog.Verbose.Debug.WriteLine("Executing Command: '{0}'", command_text);
785     using (SQLiteCommand cmd = new SQLiteCommand(command_text, con))
786 william 156 {
787 william 184 using (SQLiteDataReader r = cmd.ExecuteReader())
788 william 156 {
789 william 184 if (!r.HasRows)
790 william 156 {
791 william 184 gLog.Warn.WriteLine("Query: '{0}' returned no rows.", cmd.CommandText);
792     }
793     else
794     {
795     while (r.Read())
796 william 156 {
797 william 184 RECORDING_SCHEDULE recording = new RECORDING_SCHEDULE();
798     for (int i = 0; i < r.FieldCount; i++)
799     {
800     RECORDING_SCHEDULE.Create(ref recording, r, i);
801     }
802     recordings.Add(recording);
803 william 156 }
804     }
805     }
806     }
807     }
808 william 184 catch (SQLiteException ex)
809     {
810     gLog.Error.WriteLine(ex.ToString());
811     }
812     finally
813     {
814     con.Close();
815     }
816 william 156 }
817     this.Recordings = recordings;
818     }
819     catch (Exception ex)
820     {
821     gLog.Error.WriteLine(ex.ToString());
822     }
823     }
824 william 159
825 william 183 public void RemoveOldGBPVRPrograms(List<SQLLITE.IPROGRAMME> programs)
826 william 190 {
827 william 211 //gLog.Info.WriteLine("Removing {0} gbpvr programs.", programs.Count);
828     //double total = programs.Count;
829     //double index = 0;
830     //double progress = 0;
831     //Stopwatch st = new Stopwatch();
832     //st.Start();
833     //foreach (var program in programs)
834     //{
835     // progress = 100.0 * (index / total);
836     // gLog.ReportProgress(this, new ReportProgressEventArgs((int)progress, string.Format("Removing GBPVR Program ({0:00}%) oid='{1}'", (int)progress, program.oid)));
837     // if (!RemoveProgramDatabaseEntry(program))
838     // {
839     // gLog.Error.WriteLine("Failed to remove program with oid: {0}", program.oid);
840     // }
841     // index++;
842     //}
843     ////Stopwatch st = new Stopwatch();
844     ////st.Start();
845     ////if (!RemoveAllProgramDatabaseEntries())
846     ////{
847     //// gLog.Error.WriteLine("Failed to remove one or more program(s)");
848     ////}
849     //st.Stop();
850     //gLog.Warn.WriteLine(" operation took: {0:0.00000} seconds", st.Elapsed.TotalSeconds);
851    
852     int ChunkSize = 1024;
853     var ChunkList = programs.Chunk<IPROGRAMME>(ChunkSize);
854    
855 william 208 double total = programs.Count;
856     double index = 0;
857     double progress = 0;
858 william 211 Stopwatch st1 = new Stopwatch();
859     st1.Start();
860     foreach (var p in ChunkList)
861 william 190 {
862 william 208 progress = 100.0 * (index / total);
863 william 211 if (!RemoveProgramDatabaseEntry(p))
864 william 208 {
865 william 211 gLog.Error.WriteLine("Failed to remove one or more program(s)");
866 william 208 }
867 william 213 gLog.ReportProgress(this, new ReportProgressEventArgs((int)progress, string.Format("Removing {0} gbpvr programs ({1} of {2}) {3:00}%", p.Count(), index, total, (int)progress)));
868 william 211 index += (double)p.Count();
869 william 190 }
870 william 211 st1.Stop();
871     gLog.Warn.WriteLine(" operation took: {0:0.00000} seconds overall", st1.Elapsed.TotalSeconds);
872 william 183 }
873 william 215 public void UpdateGBPVRPrograms(List<IOldNewProgram> programs)
874 william 183 {
875 william 208 int ChunkSize = 1024;
876 william 215 var ChunkList = programs.Chunk<IOldNewProgram>(ChunkSize);
877 william 193
878 william 199 double total = programs.Count;
879     double index = 0;
880 william 208 double progress = 0;
881 william 199 Stopwatch st1 = new Stopwatch();
882     st1.Start();
883 william 196 foreach (var p in ChunkList)
884 william 189 {
885 william 203 //Stopwatch st2 = new Stopwatch();
886     //st2.Start();
887 william 208 progress = 100.0 * (index / total);
888 william 204 //gLog.Warn.WriteLine("Inserting {0} gbpvr programs ({1} of {2})", p.Count(), index, total);
889 william 208 if (!UpdateProgramEntryDatabase(p))
890 william 193 {
891 william 208 gLog.Error.WriteLine("Failed to update one or more program(s)");
892 william 196 }
893 william 203 //st2.Stop();
894     //gLog.Warn.WriteLine(" operation took: {0:0.00000} seconds", st2.Elapsed.TotalSeconds);
895     //gLog.Warn.WriteLine(System.Environment.NewLine);
896 william 213 gLog.ReportProgress(this, new ReportProgressEventArgs((int)progress, string.Format("Updating {0} gbpvr programs ({1} of {2}) {3:00}%", p.Count(), index, total, (int)progress)));
897 william 201 index += (double)p.Count();
898 william 195 }
899 william 199 st1.Stop();
900 william 208 gLog.Warn.WriteLine(" operation took: {0:0.00000} seconds overall", st1.Elapsed.TotalSeconds);
901 william 183 }
902 william 174
903 william 186 private bool RemoveAllProgramDatabaseEntries()
904     {
905     bool result = false;
906     try
907     {
908     using (SQLiteConnection con = CreateConnection())
909     {
910     try
911     {
912     //gLog.Verbose.Info.WriteLine("Removing old program with oid: '{0}'", old_program.oid);
913     con.Open();
914     string command_text = string.Format(@"DELETE FROM [{0}];", TABLES.PROGRAMME);
915     //gLog.Verbose.Debug.WriteLine("Executing Command: '{0}'", command_text);
916     using (SQLiteCommand cmd = new SQLiteCommand(command_text, con))
917     {
918     //cmd.Parameters.Add(new SQLiteParameter("oid", old_program.oid));
919     int rowsupdated = cmd.ExecuteNonQuery();
920     //gLog.Verbose.Info.WriteLine("Updated '{0}' rows", rowsupdated);
921     }
922     result = true;
923     }
924     catch (SQLiteException ex)
925     {
926     gLog.Error.WriteLine(ex.ToString());
927     result = false;
928     }
929     finally
930     {
931     con.Close();
932     }
933     }
934     }
935     catch (Exception ex)
936     {
937     gLog.Error.WriteLine(ex.ToString());
938     result = false;
939     }
940     return result;
941     }
942 william 211 private bool RemoveProgramDatabaseEntry(IEnumerable<IPROGRAMME> list)
943 william 174 {
944     bool result = false;
945 william 183 try
946     {
947     using (SQLiteConnection con = CreateConnection())
948     {
949     try
950     {
951 william 211 //gLog.Verbose.Info.WriteLine("Updating old program with oid: '{0}'", new_program.oid);
952 william 183 con.Open();
953 william 211 //string command_text = string.Format(@"UPDATE [{0}] SET [name]=@name,[sub_title]=@subtitle, WHERE [OID] = @oid", TABLES.PROGRAMME);
954     string command_text = string.Empty;
955     command_text = BuildGBPVRMultiDeleteCommand(list);
956 william 185 //gLog.Verbose.Debug.WriteLine("Executing Command: '{0}'", command_text);
957 william 183 using (SQLiteCommand cmd = new SQLiteCommand(command_text, con))
958     {
959     int rowsupdated = cmd.ExecuteNonQuery();
960 william 185 //gLog.Verbose.Info.WriteLine("Updated '{0}' rows", rowsupdated);
961 william 183 }
962 william 211
963 william 183 result = true;
964     }
965     catch (SQLiteException ex)
966     {
967     gLog.Error.WriteLine(ex.ToString());
968     result = false;
969     }
970 william 184 finally
971     {
972     con.Close();
973     }
974 william 183 }
975     }
976     catch (Exception ex)
977     {
978     gLog.Error.WriteLine(ex.ToString());
979     result = false;
980     }
981 william 174 return result;
982     }
983 william 215 private bool UpdateProgramEntryDatabase(IEnumerable<IOldNewProgram> list)
984 william 208 {
985     bool result = false;
986     try
987     {
988     using (SQLiteConnection con = CreateConnection())
989     {
990     try
991     {
992     //gLog.Verbose.Info.WriteLine("Updating old program with oid: '{0}'", new_program.oid);
993     con.Open();
994     //string command_text = string.Format(@"UPDATE [{0}] SET [name]=@name,[sub_title]=@subtitle, WHERE [OID] = @oid", TABLES.PROGRAMME);
995     string command_text = string.Empty;
996     command_text = BuildGBPVRMultiUpdateCommand(list);
997     //gLog.Verbose.Debug.WriteLine("Executing Command: '{0}'", command_text);
998     using (SQLiteCommand cmd = new SQLiteCommand(command_text, con))
999     {
1000     int rowsupdated = cmd.ExecuteNonQuery();
1001     //gLog.Verbose.Info.WriteLine("Updated '{0}' rows", rowsupdated);
1002     }
1003    
1004     result = true;
1005     }
1006     catch (SQLiteException ex)
1007     {
1008     gLog.Error.WriteLine(ex.ToString());
1009     result = false;
1010     }
1011     finally
1012     {
1013     con.Close();
1014     }
1015     }
1016     }
1017     catch (Exception ex)
1018     {
1019     gLog.Error.WriteLine(ex.ToString());
1020     result = false;
1021     }
1022     return result;
1023     }
1024 william 201 private bool InsertProgramEntryDatabase(IEnumerable<IPROGRAMME> list)
1025 william 186 {
1026     bool result = false;
1027     try
1028     {
1029     using (SQLiteConnection con = CreateConnection())
1030     {
1031     try
1032     {
1033     //gLog.Verbose.Info.WriteLine("Updating old program with oid: '{0}'", new_program.oid);
1034     con.Open();
1035     //string command_text = string.Format(@"UPDATE [{0}] SET [name]=@name,[sub_title]=@subtitle, WHERE [OID] = @oid", TABLES.PROGRAMME);
1036     string command_text = string.Empty;
1037 william 189 command_text = BuildGBPVRMultiInsertCommand(list);
1038 william 186 //gLog.Verbose.Debug.WriteLine("Executing Command: '{0}'", command_text);
1039     using (SQLiteCommand cmd = new SQLiteCommand(command_text, con))
1040 william 189 {
1041 william 186 int rowsupdated = cmd.ExecuteNonQuery();
1042     //gLog.Verbose.Info.WriteLine("Updated '{0}' rows", rowsupdated);
1043     }
1044    
1045     result = true;
1046     }
1047     catch (SQLiteException ex)
1048     {
1049     gLog.Error.WriteLine(ex.ToString());
1050     result = false;
1051     }
1052     finally
1053     {
1054     con.Close();
1055     }
1056     }
1057     }
1058     catch (Exception ex)
1059     {
1060     gLog.Error.WriteLine(ex.ToString());
1061     result = false;
1062     }
1063     return result;
1064     }
1065 william 211
1066     #region Multi-Delete Command Support
1067     private string BuildGBPVRMultiDeleteCommand(IEnumerable<IPROGRAMME> list)
1068     {
1069     StringBuilder builder = new StringBuilder();
1070     /*
1071     insert into table1 (field1,field2) values (value1,value2);
1072     insert into table1 (field1,field2) values (value1,value2);
1073     insert into table1 (field1,field2) values (value1,value2);
1074     insert into table1 (field1,field2) values (value1,value2)
1075     */
1076     builder.AppendLine("begin transaction;");
1077     foreach (var t in list)
1078     {
1079     builder.AppendLine(BuildGBPVRSingleDeleteCommand(t));
1080     }
1081     builder.AppendLine("end transaction;");
1082     return builder.ToString();
1083     }
1084     private string BuildGBPVRSingleDeleteCommand(IPROGRAMME program)
1085     {
1086     StringBuilder builder = new StringBuilder();
1087     builder.AppendFormat("delete from {0} where oid={1};", TABLES.PROGRAMME, program.oid);
1088     return builder.ToString();
1089     }
1090     #endregion
1091 william 208 #region Multi-Update Command Support
1092 william 215 private string BuildGBPVRMultiUpdateCommand(IEnumerable<IOldNewProgram> list)
1093 william 208 {
1094     StringBuilder builder = new StringBuilder();
1095     /*
1096     insert into table1 (field1,field2) values (value1,value2);
1097     insert into table1 (field1,field2) values (value1,value2);
1098     insert into table1 (field1,field2) values (value1,value2);
1099     insert into table1 (field1,field2) values (value1,value2)
1100     */
1101     builder.AppendLine("begin transaction;");
1102     foreach (var t in list)
1103     {
1104 william 216 if (!t.OldProgram.Equals(t.NewProgram))
1105 william 215 {
1106 william 216 // only update the entry if it is different
1107 william 215 builder.AppendLine(BuildGBPVRSingleUpdateCommand(t.NewProgram));
1108     }
1109 william 208 }
1110     builder.AppendLine("end transaction;");
1111     return builder.ToString();
1112     }
1113     private string BuildGBPVRSingleUpdateCommand(IPROGRAMME program)
1114     {
1115     StringBuilder builder = new StringBuilder();
1116     builder.AppendFormat("update {0} SET ", TABLES.PROGRAMME);
1117     builder.AppendFormat("name=\"{0}\", ", program.name);
1118     builder.AppendFormat("sub_title=\"{0}\", ", program.sub_title);
1119     builder.AppendFormat("description=\"{0}\", ", program.description);
1120     builder.AppendFormat("start_time='{0}', ", program.start_time.ToString("yyyy/MM/dd HH:mm:ss.fffffff"));
1121     builder.AppendFormat("end_time='{0}', ", program.end_time.ToString("yyyy/MM/dd HH:mm:ss.fffffff"));
1122     builder.AppendFormat("channel_oid={0}, ", program.channel_oid);
1123     builder.AppendFormat("unique_identifier=\"{0}\", ", program.unique_identifier);
1124     builder.AppendFormat("rating=\"{0}\" ", program.rating);
1125 william 209 builder.AppendFormat("where oid={0};", program.oid);
1126 william 208 return builder.ToString();
1127     }
1128     #endregion
1129     #region Multi-Insert Command Support
1130 william 201 private string BuildGBPVRMultiInsertCommand(IEnumerable<IPROGRAMME> list)
1131 william 174 {
1132 william 189 StringBuilder builder = new StringBuilder();
1133     /*
1134     insert into table1 (field1,field2) values (value1,value2);
1135     insert into table1 (field1,field2) values (value1,value2);
1136     insert into table1 (field1,field2) values (value1,value2);
1137     insert into table1 (field1,field2) values (value1,value2)
1138     */
1139 william 194 builder.AppendLine("begin transaction;");
1140 william 189 foreach (var t in list)
1141 william 183 {
1142 william 189 builder.AppendLine(BuildGBPVRSingleInsertCommand(t));
1143 william 183 }
1144 william 194 builder.AppendLine("end transaction;");
1145 william 189 return builder.ToString();
1146 william 174 }
1147 william 208
1148 william 189 private string BuildGBPVRSingleInsertCommand(IPROGRAMME program)
1149     {
1150     StringBuilder builder = new StringBuilder();
1151     builder.AppendFormat("insert into {0} (oid,name,sub_title,description,start_time,end_time,channel_oid,unique_identifier,rating) values (", TABLES.PROGRAMME);
1152     builder.AppendFormat("{0},",program.oid);
1153     builder.AppendFormat("\"{0}\",", program.name);
1154     builder.AppendFormat("\"{0}\",", program.sub_title);
1155     builder.AppendFormat("\"{0}\",", program.description);
1156 william 206 builder.AppendFormat("'{0}',", program.start_time.ToString("yyyy/MM/dd HH:mm:ss.fffffff"));
1157     builder.AppendFormat("'{0}',", program.end_time.ToString("yyyy/MM/dd HH:mm:ss.fffffff"));
1158 william 189 builder.AppendFormat("{0},", program.channel_oid);
1159     builder.AppendFormat("\"{0}\",", program.unique_identifier);
1160     builder.AppendFormat("\"{0}\");", program.rating);
1161     return builder.ToString();
1162     }
1163 william 208 #endregion
1164    
1165 william 156 }
1166     }

  ViewVC Help
Powered by ViewVC 1.1.22