Files
SabreTools/RombaSharp/Features/RefreshDats.cs

148 lines
4.9 KiB
C#
Raw Normal View History

2020-08-01 13:25:32 -07:00
using System.Collections.Generic;
using System.IO;
using SabreTools.Core;
using SabreTools.DatFiles;
2020-12-08 15:15:41 -08:00
using SabreTools.DatItems;
2021-02-02 10:23:43 -08:00
using SabreTools.DatItems.Formats;
2020-12-10 23:24:09 -08:00
using SabreTools.DatTools;
using SabreTools.FileTypes;
2020-12-07 13:57:26 -08:00
using SabreTools.Help;
2020-12-11 22:52:28 -08:00
using SabreTools.IO;
2020-12-08 11:09:05 -08:00
using SabreTools.Logging;
2020-08-01 13:25:32 -07:00
using Microsoft.Data.Sqlite;
namespace RombaSharp.Features
{
internal class RefreshDats : BaseFeature
{
public const string Value = "Refresh DATs";
public RefreshDats()
{
Name = Value;
Flags = new List<string>() { "refresh-dats" };
Description = "Refreshes the DAT index from the files in the DAT master directory tree.";
2020-12-07 13:57:26 -08:00
_featureType = ParameterType.Flag;
2020-08-01 13:25:32 -07:00
LongDescription = @"Refreshes the DAT index from the files in the DAT master directory tree.
Detects any changes in the DAT master directory tree and updates the DAT index
accordingly, marking deleted or overwritten dats as orphaned and updating
contents of any changed dats.";
2020-12-07 13:57:26 -08:00
Features = new Dictionary<string, SabreTools.Help.Feature>();
2020-08-01 13:25:32 -07:00
2021-02-03 11:10:19 -08:00
// Common Features
AddCommonFeatures();
2020-08-01 13:25:32 -07:00
AddFeature(WorkersInt32Input);
AddFeature(MissingSha1sStringInput);
}
2021-03-19 20:52:11 -07:00
public override bool ProcessFeatures(Dictionary<string, SabreTools.Help.Feature> features)
2020-08-01 13:25:32 -07:00
{
2021-03-19 20:52:11 -07:00
// If the base fails, just fail out
if (!base.ProcessFeatures(features))
return false;
2020-08-01 13:25:32 -07:00
// Get feature flags
int workers = GetInt32(features, WorkersInt32Value);
string missingSha1s = GetString(features, MissingSha1sStringValue);
// Make sure the db is set
if (string.IsNullOrWhiteSpace(_db))
{
_db = "db.sqlite";
_connectionString = $"Data Source={_db};Version = 3;";
}
// Make sure the file exists
if (!File.Exists(_db))
EnsureDatabase(_db, _connectionString);
2020-08-01 13:25:32 -07:00
// Make sure the dats dir is set
if (string.IsNullOrWhiteSpace(_dats))
_dats = "dats";
2020-12-11 22:52:28 -08:00
_dats = Path.Combine(PathTool.GetRuntimeDirectory(), _dats);
2020-08-01 13:25:32 -07:00
// Make sure the folder exists
if (!Directory.Exists(_dats))
Directory.CreateDirectory(_dats);
// First get a list of SHA-1's from the input DATs
DatFile datroot = DatFile.Create();
datroot.Header.Type = "SuperDAT";
DatFromDir.PopulateFromDir(datroot, _dats, asFiles: TreatAsFile.NonArchive, hashes: Hash.Standard);
2020-12-14 15:43:01 -08:00
datroot.Items.BucketBy(ItemKey.SHA1, DedupeType.None);
2020-08-01 13:25:32 -07:00
// Create a List of dat hashes in the database (SHA-1)
List<string> databaseDats = new List<string>();
List<string> unneeded = new List<string>();
SqliteConnection dbc = new SqliteConnection(_connectionString);
dbc.Open();
// Populate the List from the database
InternalStopwatch watch = new InternalStopwatch("Populating the list of existing DATs");
string query = "SELECT DISTINCT hash FROM dat";
SqliteCommand slc = new SqliteCommand(query, dbc);
SqliteDataReader sldr = slc.ExecuteReader();
if (sldr.HasRows)
{
sldr.Read();
string hash = sldr.GetString(0);
if (datroot.Items.ContainsKey(hash))
{
datroot.Items.Remove(hash);
databaseDats.Add(hash);
}
else if (!databaseDats.Contains(hash))
{
unneeded.Add(hash);
}
}
2020-12-14 15:43:01 -08:00
datroot.Items.BucketBy(ItemKey.Machine, DedupeType.None, norename: true);
2020-08-01 13:25:32 -07:00
watch.Stop();
slc.Dispose();
sldr.Dispose();
// Loop through the Dictionary and add all data
watch.Start("Adding new DAT information");
foreach (string key in datroot.Items.Keys)
{
foreach (Rom value in datroot.Items[key])
{
AddDatToDatabase(value, dbc);
}
}
watch.Stop();
// Now loop through and remove all references to old Dats
if (unneeded.Count > 0)
{
watch.Start("Removing unmatched DAT information");
query = "DELETE FROM dat WHERE";
foreach (string dathash in unneeded)
{
query += $" OR hash=\"{dathash}\"";
}
query = query.Replace("WHERE OR", "WHERE");
slc = new SqliteCommand(query, dbc);
slc.ExecuteNonQuery();
slc.Dispose();
watch.Stop();
}
dbc.Dispose();
2021-03-19 20:52:11 -07:00
return true;
2020-08-01 13:25:32 -07:00
}
}
}