using skyscraper5.Skyscraper.Scraper.Storage.Split; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using MySqlConnector; using skyscraper5.Dvb.Descriptors; using skyscraper5.Dvb.Psi.Model; using skyscraper5.Teletext; using skyscraper5.Dvb.DataBroadcasting.IntModel; using System.IO; using skyscraper5.Skyscraper; using skyscraper5.Skyscraper.Headless; using skyscraper5.Skyscraper.Equipment; using skyscraper5.Mpeg2.Psi.Model; using skyscraper5.Skyscraper.Gps; using skyscraper5.src.Skyscraper.FrequencyListGenerator; using skyscraper5.Skyscraper.IO.CrazycatStreamReader; using skyscraper5.Skyscraper.Scraper.Storage.Utilities; using skyscraper5.src.InteractionChannel.Model; using skyscraper5.src.InteractionChannel.Model.Descriptors; using System.Net.NetworkInformation; using System.Net; using skyscraper5.src.Skyscraper.Scraper.Dns; namespace skyscraper5.Data.MySql { public partial class MySqlDataStorage : DataStorage { private void InsertBatCountryAvailability(MySqlConnection connection, MySqlTransaction transaction, BatBouquet batBouquet) { if (batBouquet.CountryAvailabilityDictionary == null) return; if (batBouquet.CountryAvailabilityDictionary.Count == 0) return; MySqlCommand command = connection.CreateCommand(); command.Transaction = transaction; command.CommandText = "INSERT INTO dvb_bat_country_availability (id, country, availability) VALUES (@id, @country, @availability)"; command.Parameters.AddWithValue("@id", batBouquet.BouquetId); command.Parameters.Add("@country", MySqlDbType.VarChar); command.Parameters.Add("@availability", MySqlDbType.Bool); foreach (KeyValuePair keyValuePair in batBouquet.CountryAvailabilityDictionary) { command.Parameters["@country"].Value = keyValuePair.Key; command.Parameters["@availability"].Value = keyValuePair.Value; command.ExecuteNonQuery(); } } private void InsertBatMultilingualName(MySqlConnection connection, MySqlTransaction transaction, BatBouquet batBouquet) { if (batBouquet.MultilingualBouquetName == null) return; if (batBouquet.MultilingualBouquetName.MultilingualBouquetName == null) return; if (batBouquet.MultilingualBouquetName.MultilingualBouquetName.Count == 0) return; MySqlCommand command = connection.CreateCommand(); command.Transaction = transaction; command.CommandText = "INSERT INTO dvb_bat_multilingual_bouquet_name (id, lang, name) VALUES (@id, @lang, @name)"; command.Parameters.AddWithValue("@id", batBouquet.BouquetId); command.Parameters.Add("@lang", MySqlDbType.VarChar); command.Parameters.Add("@name", MySqlDbType.VarChar); foreach (KeyValuePair keyValuePair in batBouquet.MultilingualBouquetName .MultilingualBouquetName) { command.Parameters["@lang"].Value = keyValuePair.Key; command.Parameters["@name"].Value = keyValuePair.Value; command.ExecuteNonQuery(); } } private BatBouquet GetBatBouquet(MySqlConnection connection, ushort newerBouquetId) { MySqlCommand command = connection.CreateCommand(); command.CommandText = "SELECT * FROM dvb_bat WHERE id = @id"; command.Parameters.AddWithValue("@id", newerBouquetId); MySqlDataReader dataReader = command.ExecuteReader(); BatBouquet result = null; if (dataReader.Read()) { ushort id = dataReader.GetUInt16(0); result = new BatBouquet(id); DateTime dateAdded = dataReader.GetDateTime(1); if (!dataReader.IsDBNull(2)) result.BouquetName = dataReader.GetString(2); if (!dataReader.IsDBNull(3)) { Guid guid = Guid.Parse(dataReader.GetString(3)); } if (!dataReader.IsDBNull(4)) result.PrivateDataSpecifier = dataReader.GetUInt32(4); if (!dataReader.IsDBNull(5)) result.UriLinkageType = dataReader.GetByte(5); if (!dataReader.IsDBNull(6)) result.Uri = dataReader.GetString(6); if (!dataReader.IsDBNull(7)) result.MinPollingInterval = dataReader.GetUInt16(7); if (!dataReader.IsDBNull(8)) result.ControlRemoteAccessOverInternet = dataReader.GetInt32(8); if (!dataReader.IsDBNull(9)) result.DoNotApplyRevocation = dataReader.GetBoolean(9); if (!dataReader.IsDBNull(10)) result.DoNotScramble = dataReader.GetBoolean(10); } dataReader.Close(); return result; } private struct BatTransportStreamCoordinate { public ushort BouquetId { get; } public ushort NetworkId { get; } public ushort TsId { get; } public BatTransportStreamCoordinate(ushort bouquetId, ushort networkId, ushort tsId) { BouquetId = bouquetId; NetworkId = networkId; TsId = tsId; } public bool Equals(BatTransportStreamCoordinate other) { return BouquetId == other.BouquetId && NetworkId == other.NetworkId && TsId == other.TsId; } public override bool Equals(object obj) { return obj is BatTransportStreamCoordinate other && Equals(other); } public override int GetHashCode() { return HashCode.Combine(BouquetId, NetworkId, TsId); } } private HashSet _batTransportStreamCoordinates; private void InsertBatTransportStreamCountryAvailability(MySqlTransaction transaction, ushort batBouquetBouquetId, BatTransportStream child) { if (child.CountryAvailability == null) return; if (child.CountryAvailability.Count == 0) return; MySqlCommand command = transaction.Connection.CreateCommand(); command.Transaction = transaction; command.CommandText = "INSERT INTO dvb_bat_transport_stream_country_availability (bouquet_id, original_network_id, transport_stream_id, country, availability) " + "VALUES (@bouquet_id, @original_network_id, @transport_stream_id, @country, @availability)"; command.Parameters.AddWithValue("@bouquet_id", batBouquetBouquetId); command.Parameters.AddWithValue("@original_network_id", child.OriginalNetworkId); command.Parameters.AddWithValue("@transport_stream_id", child.TransportStreamId); command.Parameters.Add("@country", MySqlDbType.VarChar); command.Parameters.Add("@availability", MySqlDbType.Bool); foreach (KeyValuePair valuePair in child.CountryAvailability) { command.Parameters["@country"].Value = valuePair.Key; command.Parameters["@availability"].Value = valuePair.Value; command.ExecuteNonQuery(); } } private void InsertBatTransportStreamServiceList(MySqlTransaction transaction, ushort batBouquetBouquetId, BatTransportStream child) { if (child.ServiceList == null) return; if (child.ServiceList.Count == 0) return; MySqlCommand command = transaction.Connection.CreateCommand(); command.Transaction = transaction; command.CommandText = "INSERT INTO dvb_bat_transport_stream_service_list (bouquet_id, original_network_id, transport_stream_id, service_id, service_type) " + "VALUES (@bouquet_id, @original_network_id, @transport_stream_id, @service_id, @service_type)"; command.Parameters.AddWithValue("@bouquet_id", batBouquetBouquetId); command.Parameters.AddWithValue("@original_network_id", child.OriginalNetworkId); command.Parameters.AddWithValue("@transport_stream_id", child.TransportStreamId); command.Parameters.Add("@service_id", MySqlDbType.Int32); command.Parameters.Add("@service_type", MySqlDbType.Int32); foreach (ServiceListDescriptor.Service service in child.ServiceList) { command.Parameters["@service_id"].Value = service.ServiceId; command.Parameters["@service_type"].Value = (int)service.ServiceType; command.ExecuteNonQuery(); } } public bool TestForBatBouquet(BatBouquet batBouquet) { using (MySqlConnection connection = new MySqlConnection(_mcsb.ToString())) { connection.Open(); MySqlCommand command = connection.CreateCommand(); command.CommandText = "SELECT dateadded FROM dvb_bat WHERE id = @id"; command.Parameters.AddWithValue("@id", batBouquet.BouquetId); MySqlDataReader dataReader = command.ExecuteReader(); bool result = dataReader.Read(); dataReader.Close(); connection.Close(); return result; } } public bool UpdateBatBouquet(BatBouquet newer) { using (MySqlConnection connection = new MySqlConnection(_mcsb.ToString())) { connection.Open(); bool result = false; BatBouquet older = GetBatBouquet(connection, newer.BouquetId); if (older.NeedUpdate(newer)) { MySqlCommand command = connection.CreateCommand(); command.CommandText = "UPDATE dvb_bat SET name = @name, private_dat_specifier = @private_dat_specifier, uri_linkage_type = @uri_linkage_type, url = @url, min_polling_interval =@min_polling_interval, control_remote_access_over_internet = @control_remote_access_over_internet, do_not_apply_revocation = @do_not_apply_revocation, do_not_scramble = @do_not_scramble WHERE id = @id"; command.Parameters.AddWithValue("@id", newer.BouquetId); command.Parameters.AddWithValue("@name", newer.BouquetName); command.Parameters.AddWithValue("@private_dat_specifier", newer.PrivateDataSpecifier); command.Parameters.AddWithValue("@uri_linkage_type", newer.UriLinkageType); command.Parameters.AddWithValue("@url", newer.Uri); command.Parameters.AddWithValue("@min_polling_interval", newer.MinPollingInterval); command.Parameters.AddWithValue("@control_remote_access_over_internet", newer.ControlRemoteAccessOverInternet); command.Parameters.AddWithValue("@do_not_apply_revocation", newer.DoNotApplyRevocation); command.Parameters.AddWithValue("@do_not_scramble", newer.DoNotScramble); command.ExecuteNonQuery(); result = true; } connection.Close(); return result; } } public void StoreBatBouquet(BatBouquet batBouquet) { bool hasLinkages = HasLinkages(batBouquet.Linkages); Guid uuid = hasLinkages ? Guid.NewGuid() : Guid.Empty; using (MySqlConnection connection = new MySqlConnection(_mcsb.ToString())) { connection.Open(); MySqlTransaction transaction = connection.BeginTransaction(); MySqlCommand command = connection.CreateCommand(); command.Transaction = transaction; command.CommandText = "INSERT INTO dvb_bat (id, name, uuid, private_dat_specifier, uri_linkage_type, url, min_polling_interval, control_remote_access_over_internet, do_not_apply_revocation, do_not_scramble) " + "VALUES " + "(@id, @name, @uuid, @private_dat_specifier, @uri_linkage_type, @url, @min_polling_interval, @control_remote_access_over_internet, @do_not_apply_revocation, @do_not_scramble)"; command.Parameters.AddWithValue("@id", batBouquet.BouquetId); command.Parameters.AddWithValue("@name", batBouquet.BouquetName); if (hasLinkages) command.Parameters.AddWithValue("@uuid", uuid.ToString()); else command.Parameters.AddWithValue("@uuid", DBNull.Value); command.Parameters.AddWithValue("@private_dat_specifier", batBouquet.PrivateDataSpecifier); command.Parameters.AddWithValue("@uri_linkage_type", batBouquet.UriLinkageType); command.Parameters.AddWithValue("@url", batBouquet.Uri); command.Parameters.AddWithValue("@min_polling_interval", batBouquet.MinPollingInterval); command.Parameters.AddWithValue("@control_remote_access_over_internet", batBouquet.ControlRemoteAccessOverInternet); command.Parameters.AddWithValue("@do_not_apply_revocation", batBouquet.DoNotApplyRevocation); command.Parameters.AddWithValue("@do_not_scramble", batBouquet.DoNotScramble); command.ExecuteNonQuery(); if (hasLinkages) InsertSdtLinkages(connection, uuid, batBouquet.Linkages, transaction); InsertBatCountryAvailability(connection, transaction, batBouquet); InsertBatMultilingualName(connection, transaction, batBouquet); transaction.Commit(); connection.Close(); } } public bool TestForBatTransportStream(ushort batBouquetBouquetId, BatTransportStream child) { if (_batTransportStreamCoordinates == null) _batTransportStreamCoordinates = new HashSet(); BatTransportStreamCoordinate coordinate = new BatTransportStreamCoordinate(batBouquetBouquetId, child.OriginalNetworkId, child.TransportStreamId); if (_batTransportStreamCoordinates.Contains(coordinate)) return true; using (MySqlConnection connection = new MySqlConnection(_mcsb.ToString())) { connection.Open(); MySqlCommand command = connection.CreateCommand(); command.CommandText = "SELECT dateadded FROM dvb_bat_transport_stream WHERE bouquet_id = @bouquet_id AND original_network_id = @original_network_id AND transport_stream_id = @transport_stream_id"; command.Parameters.AddWithValue("@bouquet_id", batBouquetBouquetId); command.Parameters.AddWithValue("@original_network_id", child.OriginalNetworkId); command.Parameters.AddWithValue("@transport_stream_id", child.TransportStreamId); MySqlDataReader dataReader = command.ExecuteReader(); bool result = dataReader.Read(); if (result) _batTransportStreamCoordinates.Add(coordinate); dataReader.Close(); return result; } } public bool UpdateBatTransportStream(ushort batBouquetBouquetId, BatTransportStream child) { //It's very unlikely that we'll need to Update BAT TS Info, as these don't contain much. return false; } public void StoreBatTransportStream(ushort batBouquetBouquetId, BatTransportStream child) { BatTransportStreamCoordinate coordinate = new BatTransportStreamCoordinate(batBouquetBouquetId, child.OriginalNetworkId, child.TransportStreamId); _batTransportStreamCoordinates.Add(coordinate); EnqueueSpeedhack(SpeedhackType.InsertBatTs, batBouquetBouquetId, child); } } }