using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Security.Cryptography; using System.Text; using System.Threading.Tasks; using Npgsql; using NpgsqlTypes; using skyscraper5.Dvb.Descriptors; using skyscraper5.Dvb.Psi.Model; using skyscraper5.Mpeg2.Psi.Model; using skyscraper5.Skyscraper.Scraper.Storage.Split; using skyscraper5.Skyscraper.Scraper.Storage.Utilities; namespace skyscraper5.Data.PostgreSql { public partial class PostgresqlDataStore { public bool StoreEitEvent(EitEvent eitEvent) { if (knownEitEvents == null) knownEitEvents = new HashSet(); DatabaseKeyEitEvent key = new DatabaseKeyEitEvent(eitEvent.ServiceId, eitEvent.TransportStreamId, eitEvent.OriginalNetworkId, eitEvent.EventId, eitEvent.StartTime); if (knownEitEvents.Contains(key)) return false; if (TestForEitEvent(key)) { knownEitEvents.Add(key); return false; } EnqueueTask(x => WriteEitEvent(x, eitEvent)); knownEitEvents.Add(key); return true; } public void Ping() { using (NpgsqlConnection conn = new NpgsqlConnection(connectionStringBuilder.ToString())) { conn.Open(); NpgsqlCommand command = conn.CreateCommand(); command.CommandText = "SELECT relname FROM pg_catalog.pg_class"; NpgsqlDataReader dataReader = command.ExecuteReader(); bool hasDsmCcTables = false; bool hasDvbTables = false; bool hasScte35Tables = false; bool hasSkyscraper5Tables = false; while (dataReader.Read()) { string tableName = dataReader.GetString(0); if (tableName.StartsWith("dsmcc_")) hasDsmCcTables = true; if (tableName.StartsWith("dvb_")) hasDvbTables = true; if (tableName.StartsWith("scte35_")) hasScte35Tables = true; if (tableName.StartsWith("skyscraper5_")) hasSkyscraper5Tables = true; } dataReader.Close(); command.Dispose(); conn.Close(); if (!hasDsmCcTables || !hasDvbTables || !hasScte35Tables || !hasSkyscraper5Tables) { throw new SchemaMissingException("The PostgreSQL schema does not seem to be installed."); } } } public IEnumerable> SelectAllPmt() { throw new NotImplementedException(); } public SdtService SelectSdtById(int networkId, int tsId, ushort programMappingProgramNumber) { throw new NotImplementedException(); } public IEnumerable> SelectAllSdt() { throw new NotImplementedException(); } private HashSet knownEitEvents; private bool TestForEitEvent(DatabaseKeyEitEvent eitEvent) { using (NpgsqlConnection conn = new NpgsqlConnection(connectionStringBuilder.ToString())) { conn.Open(); return TestForEitEventEx(eitEvent, conn); } } private static bool TestForEitEventEx(DatabaseKeyEitEvent eitEvent, NpgsqlConnection conn) { NpgsqlCommand command = conn.CreateCommand(); command.CommandText = "SELECT dateadded FROM dvb_eit WHERE sid = @sid AND tsid = @tsid AND onid = @onid AND event_id = @event_id AND start_time = @start_time"; command.Parameters.AddWithValue("@sid", NpgsqlDbType.Integer, (int)eitEvent.ServiceId); command.Parameters.AddWithValue("@tsid", NpgsqlDbType.Integer, (int)eitEvent.TransportStreamId); command.Parameters.AddWithValue("@onid", NpgsqlDbType.Integer, (int)eitEvent.OriginalNetworkId); command.Parameters.AddWithValue("@event_id", NpgsqlDbType.Integer, (int)eitEvent.EventId); command.Parameters.AddWithValue("@start_time", NpgsqlDbType.Timestamp, eitEvent.StartTime); NpgsqlDataReader dataReader = command.ExecuteReader(); bool result = dataReader.Read(); dataReader.Close(); return result; } private void WriteEitEvent(NpgsqlConnection conn, EitEvent eitEvent) { DatabaseKeyEitEvent key = new DatabaseKeyEitEvent(eitEvent.ServiceId, eitEvent.TransportStreamId, eitEvent.OriginalNetworkId, eitEvent.EventId, eitEvent.StartTime); if (TestForEitEventEx(key, conn)) { return; } NpgsqlCommand command = conn.CreateCommand(); command.CommandText = "INSERT INTO dvb_eit " + "(sid, tsid, onid, event_id, start_time, running_status, free_ca, iso_639_language_code, event_name, text, extended_text, pdc, private_data_specifier, vps_string, reference_service_id, reference_event_id, control_remote_access_over_internet, do_not_apply_revocation, do_not_scramble) " + "VALUES " + "(@sid, @tsid, @onid, @event_id, @start_time, @running_status, @free_ca, @iso_639_language_code, @event_name, @text, @extended_text, @pdc, @private_data_specifier, @vps_string, @reference_service_id, @reference_event_id, @control_remote_access_over_internet, @do_not_apply_revocation, @do_not_scramble)"; command.Parameters.AddWithValue("@sid", NpgsqlDbType.Integer, (int)eitEvent.ServiceId); command.Parameters.AddWithValue("@tsid", NpgsqlDbType.Integer, (int)eitEvent.TransportStreamId); command.Parameters.AddWithValue("@onid", NpgsqlDbType.Integer, (int)eitEvent.OriginalNetworkId); command.Parameters.AddWithValue("@event_id", NpgsqlDbType.Integer, (int)eitEvent.EventId); command.Parameters.AddWithValue("@start_time", NpgsqlDbType.Timestamp, eitEvent.StartTime); command.Parameters.AddWithValue("@running_status", NpgsqlDbType.Integer, (int)eitEvent.RunningStatus); command.Parameters.AddWithValue("@free_ca", NpgsqlDbType.Boolean, eitEvent.FreeCa); command.Parameters.AddWithValue("@iso_639_language_code", NpgsqlDbType.Varchar, eitEvent.Iso639LanguageCode); command.Parameters.AddWithValue("@event_name", NpgsqlDbType.Text, eitEvent.EventName.TrimJunk()); command.Parameters.AddWithValue("@text", NpgsqlDbType.Text, eitEvent.Text.TrimJunk()); if (eitEvent.ExtendedText != null) { StringBuilder sb = new StringBuilder(); foreach (string s in eitEvent.ExtendedText) if (s != null) sb.Append(s.Trim('\0')); command.Parameters.AddWithValue("@extended_text", NpgsqlDbType.Text, sb.ToString().TrimJunk()); } else { command.Parameters.AddWithValue("@extended_text", NpgsqlDbType.Text, DBNull.Value); } command.Parameters.AddWithValue("@pdc", NpgsqlDbType.Timestamp, eitEvent.Pdc); if (eitEvent.PrivateDataSpecifier.HasValue) command.Parameters.AddWithValue("@private_data_specifier", NpgsqlDbType.Bigint, (long)eitEvent.PrivateDataSpecifier); else command.Parameters.AddWithValue("@private_data_specifier", NpgsqlDbType.Bigint, DBNull.Value); command.Parameters.AddWithValue("@vps_string", NpgsqlDbType.Text, eitEvent.VpsString); if (eitEvent.ReferenceServiceId.HasValue) command.Parameters.AddWithValue("@reference_service_id", NpgsqlDbType.Integer, eitEvent.ReferenceServiceId); else command.Parameters.AddWithValue("@reference_service_id", NpgsqlDbType.Integer, DBNull.Value); if (eitEvent.ReferenceEventId.HasValue) command.Parameters.AddWithValue("@reference_event_id", NpgsqlDbType.Integer, eitEvent.ReferenceEventId); else command.Parameters.AddWithValue("@reference_event_id", NpgsqlDbType.Integer, DBNull.Value); if (eitEvent.ControlRemoteAccessOverInternet.HasValue) command.Parameters.AddWithValue("@control_remote_access_over_internet", NpgsqlDbType.Integer, eitEvent.ControlRemoteAccessOverInternet); else command.Parameters.AddWithValue("@control_remote_access_over_internet", NpgsqlDbType.Integer, DBNull.Value); if (eitEvent.DoNotApplyRevocation.HasValue) command.Parameters.AddWithValue("@do_not_apply_revocation", NpgsqlDbType.Boolean, eitEvent.DoNotApplyRevocation); else command.Parameters.AddWithValue("@do_not_apply_revocation", NpgsqlDbType.Boolean, DBNull.Value); if (eitEvent.DoNotScramble.HasValue) command.Parameters.AddWithValue("@do_not_scramble", NpgsqlDbType.Boolean, eitEvent.DoNotScramble); else command.Parameters.AddWithValue("@do_not_scramble", NpgsqlDbType.Boolean, DBNull.Value); command.Parameters.CheckNulls(); command.ExecuteNonQuery(); WriteEitCaSystems(conn, eitEvent); WriteEitComponents(conn, eitEvent); WriteEitContent(conn, eitEvent); WriteEitCrids(conn, eitEvent); WriteEitItems(conn, eitEvent); WriteEitLinkages(conn, eitEvent); WriteEitParentalRatings(conn, eitEvent); } private void WriteEitParentalRatings(NpgsqlConnection conn, EitEvent eitEvent) { if (eitEvent.ParentalRatings == null) return; NpgsqlCommand command = conn.CreateCommand(); command.CommandText = "INSERT INTO dvb_eit_parental_ratings " + "(sid,tsid,onid,event_id,start_time,ordinal,k,v) " + "VALUES " + "(@sid,@tsid,@onid,@event_id,@start_time,@ordinal,@k,@v)"; command.Parameters.AddWithValue("@sid", NpgsqlDbType.Integer, (int)eitEvent.ServiceId); command.Parameters.AddWithValue("@tsid", NpgsqlDbType.Integer, (int)eitEvent.TransportStreamId); command.Parameters.AddWithValue("@onid", NpgsqlDbType.Integer, (int)eitEvent.OriginalNetworkId); command.Parameters.AddWithValue("@event_id", NpgsqlDbType.Integer, (int)eitEvent.EventId); command.Parameters.AddWithValue("@start_time", NpgsqlDbType.Timestamp, eitEvent.StartTime); command.Parameters.Add("@ordinal", NpgsqlDbType.Integer); command.Parameters.Add("@k", NpgsqlDbType.Varchar); command.Parameters.Add("@v", NpgsqlDbType.Integer); for (int i = 0; i < eitEvent.ParentalRatings.Length; i++) { if (eitEvent.ParentalRatings[i] == null) continue; command.Parameters["@ordinal"].Value = i; command.Parameters["@k"].Value = eitEvent.ParentalRatings[i].Item1; command.Parameters["@v"].Value = eitEvent.ParentalRatings[i].Item2; command.ExecuteNonQuery(); } } private void WriteEitLinkages(NpgsqlConnection conn, EitEvent eitEvent) { if (eitEvent.Linkages == null) return; NpgsqlCommand command = conn.CreateCommand(); command.CommandText = "insert into dvb_eit_linkages (sid, tsid, onid, event_id, start_time, ordinal, l_tsid, l_onid, l_sid, linkage_type, handover_type, handover_origin_type, handover_network_id, handover_initial_service_id, target_event_id, target_event_listed, target_event_simulcasted, table_type, private_data_bytes, bouquet_id) " + "values " + "(@sid,@tsid,@onid,@event_id,@start_time,@ordinal,@l_tsid,@l_onid,@l_sid,@linkage_type,@handover_type,@handover_origin_type,@handover_network_id,@handover_initial_service_id,@target_event_id,@target_event_listed,@target_event_simulcasted,@table_type,@private_data_bytes,@bouquet_id)"; command.Parameters.AddParameter("@sid", NpgsqlDbType.Integer, (int)eitEvent.ServiceId); command.Parameters.AddParameter("@tsid", NpgsqlDbType.Integer, (int)eitEvent.TransportStreamId); command.Parameters.AddParameter("@onid", NpgsqlDbType.Integer, (int)eitEvent.OriginalNetworkId); command.Parameters.AddParameter("@event_id", NpgsqlDbType.Integer, (int)eitEvent.EventId); command.Parameters.AddParameter("@start_time", NpgsqlDbType.Timestamp, eitEvent.StartTime); command.Parameters.Add("@ordinal", NpgsqlDbType.Integer); command.Parameters.Add("@l_tsid", NpgsqlDbType.Integer); command.Parameters.Add("@l_onid", NpgsqlDbType.Integer); command.Parameters.Add("@l_sid", NpgsqlDbType.Integer); command.Parameters.Add("@linkage_type", NpgsqlDbType.Integer); command.Parameters.Add("@handover_type", NpgsqlDbType.Integer); command.Parameters.Add("@handover_origin_type", NpgsqlDbType.Boolean); command.Parameters.Add("@handover_network_id", NpgsqlDbType.Integer); command.Parameters.Add("@handover_initial_service_id", NpgsqlDbType.Integer); command.Parameters.Add("@target_event_id", NpgsqlDbType.Integer); command.Parameters.Add("@target_event_listed", NpgsqlDbType.Boolean); command.Parameters.Add("@target_event_simulcasted", NpgsqlDbType.Boolean); //@table_type,@private_data_bytes,@bouquet_id)"; command.Parameters.Add("@table_type", NpgsqlDbType.Integer); command.Parameters.Add("@private_data_bytes", NpgsqlDbType.Bytea); command.Parameters.Add("@bouquet_id", NpgsqlDbType.Integer); for (int i = 0; i < eitEvent.Linkages.Count; i++) { LinkageDescriptor linkage = eitEvent.Linkages[i]; command.Parameters["@ordinal"].Value = i; command.Parameters["@l_tsid"].Value = (int)linkage.TransportStreamId; command.Parameters["@l_onid"].Value = (int)linkage.OriginalNetworkId; command.Parameters["@l_sid"].Value = (int)linkage.ServiceId; command.Parameters["@linkage_type"].Value = (int)linkage.LinkageType; command.Parameters["@handover_type"].Value = linkage.HandoverType.HasValue ? (int)linkage.HandoverType.Value : DBNull.Value; command.Parameters["@handover_origin_type"].Value = linkage.HandoverOriginType.HasValue ? linkage.HandoverOriginType.Value : DBNull.Value; command.Parameters["@handover_network_id"].Value = linkage.HandoverNetworkId.HasValue ? (int)linkage.HandoverNetworkId.Value : DBNull.Value; command.Parameters["@handover_initial_service_id"].Value = linkage.HandoverInitialServiceId.HasValue ? (int)linkage.HandoverInitialServiceId.Value : DBNull.Value; command.Parameters["@target_event_id"].Value = linkage.TargetEventId.HasValue ? (int)linkage.TargetEventId.Value : DBNull.Value; command.Parameters["@target_event_listed"].Value = linkage.TargetEventListed.HasValue ? linkage.TargetEventListed.Value : DBNull.Value; command.Parameters["@target_event_simulcasted"].Value = linkage.TargetEventSimulcasted.HasValue ? linkage.TargetEventSimulcasted.Value : DBNull.Value; command.Parameters["@table_type"].Value = linkage.TableType.HasValue ? (int)linkage.TableType.Value : DBNull.Value; command.Parameters["@private_data_bytes"].Value = linkage.PrivateDataBytes != null ? linkage.PrivateDataBytes : DBNull.Value; command.Parameters["@bouquet_id"].Value = linkage.BouquetId.HasValue ? (int)linkage.BouquetId.Value : DBNull.Value; command.ExecuteNonQuery(); WriteEitLinkageExtendedEventLinkages(conn, eitEvent, i); WriteEitLinkageIpmacLinkages(conn, eitEvent, i); WriteEitLinkageSsuLinkStructure(conn, eitEvent, i); } } private void WriteEitLinkageSsuLinkStructure(NpgsqlConnection conn, EitEvent eitEvent, int i) { if (eitEvent.Linkages[i].SystemSoftwareUpdateLinkStructure == null) return; for (int j = 0; j < eitEvent.Linkages[i].SystemSoftwareUpdateLinkStructure.Count; j++) { LinkageDescriptor.OuiPrivateData ssuLinkStruct = eitEvent.Linkages[i].SystemSoftwareUpdateLinkStructure[j]; throw new NotImplementedException(); } } private void WriteEitLinkageIpmacLinkages(NpgsqlConnection conn, EitEvent eitEvent, int i) { if (eitEvent.Linkages[i].IpMacNotificationLinkages == null) return; for (int j = 0; i < eitEvent.Linkages[i].IpMacNotificationLinkages.Count; j++) { LinkageDescriptor.IpMacNotificationLinkage ipMacNotificationLinkage = eitEvent.Linkages[i].IpMacNotificationLinkages[j]; throw new NotImplementedException(); } } private void WriteEitLinkageExtendedEventLinkages(NpgsqlConnection conn, EitEvent eitEvent, int i) { if (eitEvent.Linkages[i].ExtendedEventLinkages == null) return; for (int j = 0; i < eitEvent.Linkages[i].ExtendedEventLinkages.Length; j++) { LinkageDescriptor.ExtendedEventLinkageInfo extendedEventLinkage = eitEvent.Linkages[i].ExtendedEventLinkages[j]; throw new NotImplementedException(); } } private void WriteEitItems(NpgsqlConnection conn, EitEvent eitEvent) { if (eitEvent.Items == null) return; NpgsqlCommand command = conn.CreateCommand(); command.CommandText = "INSERT INTO dvb_eit_items (sid, tsid, onid, event_id, start_time, description, item, ordinal) " + "VALUES (@sid, @tsid, @onid, @event_id, @start_time, @description, @item, @ordinal)"; command.Parameters.AddParameter("@sid", NpgsqlDbType.Integer, eitEvent.ServiceId); command.Parameters.AddParameter("@tsid", NpgsqlDbType.Integer, eitEvent.TransportStreamId); command.Parameters.AddParameter("@onid", NpgsqlDbType.Integer, eitEvent.OriginalNetworkId); command.Parameters.AddParameter("@event_id", NpgsqlDbType.Integer, eitEvent.EventId); command.Parameters.AddParameter("@start_time", NpgsqlDbType.Timestamp, eitEvent.StartTime); command.Parameters.Add("@description", NpgsqlDbType.Text); command.Parameters.Add("@item", NpgsqlDbType.Text); command.Parameters.Add("@ordinal", NpgsqlDbType.Integer); for (int i = 0; i < eitEvent.Items.Count; i++) { EitEvent.EitEventItem item = eitEvent.Items[i]; command.Parameters["@description"].Value = item.Description; command.Parameters["@item"].Value = item.Item; command.Parameters["@ordinal"].Value = i; command.Parameters.CheckNulls(); command.ExecuteNonQuery(); } command.Dispose(); } private void WriteEitCrids(NpgsqlConnection conn, EitEvent eitEvent) { if (eitEvent.Crids == null) return; NpgsqlCommand command = conn.CreateCommand(); command.CommandText = "INSERT INTO dvb_eit_crids " + "(sid, tsid, onid, event_id, start_time, ordinal, crid_type, crid_location, crid_bytes, crid_ref) " + "VALUES " + "(@sid, @tsid, @onid, @event_id, @start_time, @ordinal, @crid_type, @crid_location, @crid_bytes, @crid_ref)"; command.Parameters.AddParameter("@sid", NpgsqlDbType.Integer, (int)eitEvent.ServiceId); command.Parameters.AddParameter("@tsid", NpgsqlDbType.Integer, (int)eitEvent.TransportStreamId); command.Parameters.AddParameter("@onid", NpgsqlDbType.Integer, (int)eitEvent.OriginalNetworkId); command.Parameters.AddParameter("@event_id", NpgsqlDbType.Integer, (int)eitEvent.EventId); command.Parameters.AddParameter("@start_time", NpgsqlDbType.Timestamp, eitEvent.StartTime); command.Parameters.Add("@ordinal", NpgsqlDbType.Integer); command.Parameters.Add("@crid_type", NpgsqlDbType.Integer); command.Parameters.Add("@crid_location", NpgsqlDbType.Integer); command.Parameters.Add("@crid_bytes", NpgsqlDbType.Bytea); command.Parameters.Add("@crid_ref", NpgsqlDbType.Integer); int ordinal = 0; foreach (ContentIdentifierDescriptor.Crid eitEventCrid in eitEvent.Crids) { command.Parameters["@ordinal"].Value = ordinal++; command.Parameters["@crid_type"].Value = (int)eitEventCrid.CridType; command.Parameters["@crid_location"].Value = (int)eitEventCrid.CridLocation; command.Parameters["@crid_bytes"].Value = eitEventCrid.CridBytes; command.Parameters["@crid_ref"].Value = (int?)eitEventCrid.CridRef; command.Parameters.CheckNulls(); } } private void WriteEitContent(NpgsqlConnection conn, EitEvent eitEvent) { if (eitEvent.Content == null) return; NpgsqlCommand command = conn.CreateCommand(); command.CommandText = "INSERT INTO dvb_eit_content " + "(sid,tsid,onid,event_id,start_time,ordinal,l,m,r) " + "VALUES " + "(@sid,@tsid,@onid,@event_id,@start_time,@ordinal,@l,@m,@r)"; command.Parameters.AddWithValue("@sid", NpgsqlDbType.Integer, (int)eitEvent.ServiceId); command.Parameters.AddWithValue("@tsid", NpgsqlDbType.Integer, (int)eitEvent.TransportStreamId); command.Parameters.AddWithValue("@onid", NpgsqlDbType.Integer, (int)eitEvent.OriginalNetworkId); command.Parameters.AddWithValue("@event_id", NpgsqlDbType.Integer, (int)eitEvent.EventId); command.Parameters.AddWithValue("@start_time", NpgsqlDbType.Timestamp, eitEvent.StartTime); command.Parameters.Add("@ordinal", NpgsqlDbType.Integer); command.Parameters.Add("@l", NpgsqlDbType.Integer); command.Parameters.Add("@m", NpgsqlDbType.Integer); command.Parameters.Add("@r", NpgsqlDbType.Integer); for (int i = 0; i < eitEvent.Content.Length; i++) { command.Parameters["@ordinal"].Value = i; command.Parameters["@l"].Value = eitEvent.Content[i].Item1; command.Parameters["@m"].Value = eitEvent.Content[i].Item2; command.Parameters["@r"].Value = eitEvent.Content[i].Item3; command.ExecuteNonQuery(); } } private void WriteEitComponents(NpgsqlConnection conn, EitEvent eitEvent) { if (eitEvent.Components == null) return; NpgsqlCommand command = conn.CreateCommand(); command.CommandText = "INSERT INTO dvb_eit_components " + "(sid, tsid, onid, event_id, start_time, ordinal, stream_content_ext, stream_content, component_type, component_tag, iso_639_language_code, text) " + "VALUES " + "(@sid, @tsid, @onid, @event_id, @start_time, @ordinal, @stream_content_ext, @stream_content, @component_type, @component_tag, @iso_639_language_code, @text)"; command.Parameters.AddWithValue("@sid", NpgsqlDbType.Integer, (int)eitEvent.ServiceId); command.Parameters.AddWithValue("@tsid", NpgsqlDbType.Integer, (int)eitEvent.TransportStreamId); command.Parameters.AddWithValue("@onid", NpgsqlDbType.Integer, (int)eitEvent.OriginalNetworkId); command.Parameters.AddWithValue("@event_id", NpgsqlDbType.Integer, (int)eitEvent.EventId); command.Parameters.AddWithValue("@start_time", NpgsqlDbType.Timestamp, eitEvent.StartTime); command.Parameters.Add("@ordinal", NpgsqlDbType.Integer); command.Parameters.Add("@stream_content_ext", NpgsqlDbType.Integer); command.Parameters.Add("@stream_content", NpgsqlDbType.Integer); command.Parameters.Add("@component_type", NpgsqlDbType.Integer); command.Parameters.Add("@component_tag", NpgsqlDbType.Integer); command.Parameters.Add("@iso_639_language_code", NpgsqlDbType.Varchar); command.Parameters.Add("@text", NpgsqlDbType.Text); int ordinal = 0; foreach (ComponentDescriptor component in eitEvent.Components) { command.Parameters["@ordinal"].Value = ordinal++; command.Parameters["@stream_content_ext"].Value = component.StreamContentExt; command.Parameters["@stream_content"].Value = component.StreamContent; command.Parameters["@component_type"].Value = component.ComponentType; command.Parameters["@component_tag"].Value = component.ComponentTag; command.Parameters["@iso_639_language_code"].Value = component.Iso639LanguageCode; string text = component.Text; if (text != null) text = component.Text.Trim('\0'); command.Parameters["@text"].Value = text; command.Parameters.CheckNulls(); command.ExecuteNonQuery(); } } private void WriteEitCaSystems(NpgsqlConnection conn, EitEvent eitEvent) { if (eitEvent.CaSystems == null) return; NpgsqlCommand cmd = conn.CreateCommand(); cmd.CommandText = "insert into dvb_eit_ca_systems (sid, tsid, onid, event_id, start_time, ordinal, caid)\r\nvalues (@sid, @tsid, @onid, @event_id, @start_time, @ordinal, @caid)"; cmd.Parameters.AddWithValue("@sid", NpgsqlDbType.Integer, (int)eitEvent.ServiceId); cmd.Parameters.AddWithValue("@tsid", NpgsqlDbType.Integer, (int)eitEvent.TransportStreamId); cmd.Parameters.AddWithValue("@onid", NpgsqlDbType.Integer, (int)eitEvent.OriginalNetworkId); cmd.Parameters.AddWithValue("@event_id", NpgsqlDbType.Integer, (int)eitEvent.EventId); cmd.Parameters.AddWithValue("@start_time", NpgsqlDbType.Timestamp, eitEvent.StartTime); cmd.Parameters.Add("@ordinal", NpgsqlDbType.Integer); cmd.Parameters.Add("@caid", NpgsqlDbType.Integer); for (int i = 0; i < eitEvent.CaSystems.Length; i++) { cmd.Parameters["@ordinal"].Value = i; cmd.Parameters["@caid"].Value = (int)eitEvent.CaSystems[i]; cmd.ExecuteNonQuery(); } } } }