338 lines
15 KiB
C#

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;
using skyscraper8.Skyscraper.Scraper.Storage;
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<string, bool> 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<string, string> 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<BatTransportStreamCoordinate> _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<string, bool> 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>();
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);
}
}
}