using System; using System.Collections.Generic; using System.IO; using Microsoft.Data.Sqlite; using SabreTools.IO; namespace Headerer { internal static class Database { #region Constants /// /// Default location for the database /// private static readonly string DbFileName = Path.Combine(PathTool.GetRuntimeDirectory(), "Headerer.sqlite"); /// /// Connection string for the database /// private static readonly string DbConnectionString = $"Data Source={DbFileName};"; #endregion /// /// Add a header to the database /// /// String representing the header bytes /// SHA-1 of the deheadered file /// Name of the source skipper file /// Enable additional log statements for debugging public static void AddHeader(string header, string SHA1, string source, bool debug) { // Ensure the database exists EnsureDatabase(); // Open the database connection SqliteConnection dbc = new(DbConnectionString); dbc.Open(); string query = $"SELECT * FROM data WHERE sha1='{SHA1}' AND header='{header}'"; var slc = new SqliteCommand(query, dbc); SqliteDataReader sldr = slc.ExecuteReader(); bool exists = sldr.HasRows; if (!exists) { query = $"INSERT INTO data (sha1, header, type) VALUES ('{SHA1}', '{header}', '{source}')"; slc = new SqliteCommand(query, dbc); if (debug) Console.WriteLine($"Result of inserting header: {slc.ExecuteNonQuery()}"); } // Dispose of database objects slc.Dispose(); sldr.Dispose(); dbc.Dispose(); } /// /// Retrieve headers from the database /// /// SHA-1 of the deheadered file /// Enable additional log statements for debugging /// List of strings representing the headers to add public static List RetrieveHeaders(string SHA1, bool debug) { // Ensure the database exists EnsureDatabase(); // Open the database connection var dbc = new SqliteConnection(DbConnectionString); dbc.Open(); // Create the output list of headers List headers = []; string query = $"SELECT header, type FROM data WHERE sha1='{SHA1}'"; var slc = new SqliteCommand(query, dbc); SqliteDataReader sldr = slc.ExecuteReader(); if (sldr.HasRows) { while (sldr.Read()) { if (debug) Console.WriteLine($"Found match with rom type '{sldr.GetString(1)}'"); headers.Add(sldr.GetString(0)); } } else { Console.Error.WriteLine("No matching header could be found!"); } // Dispose of database objects slc.Dispose(); sldr.Dispose(); dbc.Dispose(); return headers; } /// /// Ensure that the database exists and has the proper schema /// private static void EnsureDatabase() { // Make sure the file exists if (!File.Exists(DbFileName)) File.Create(DbFileName); // Open the database connection SqliteConnection dbc = new(DbConnectionString); dbc.Open(); // Make sure the database has the correct schema string query = @" CREATE TABLE IF NOT EXISTS data ( 'sha1' TEXT NOT NULL, 'header' TEXT NOT NULL, 'type' TEXT NOT NULL, PRIMARY KEY (sha1, header, type) )"; SqliteCommand slc = new(query, dbc); slc.ExecuteNonQuery(); slc.Dispose(); dbc.Dispose(); } } }