/// <summary> /// Check if a DAT contains the given rom /// </summary> /// <param name="datdata">Dat to match against</param> /// <param name="sorted">True if the DAT is already sorted accordingly, false otherwise (default)</param> /// <returns>True if it contains the rom, false otherwise</returns> public bool HasDuplicates(DatFile datdata, bool sorted = false) { // Check for an empty rom list first if (datdata.Count == 0) { return(false); } // We want to get the proper key for the DatItem string key = SortAndGetKey(datdata, sorted); // If the key doesn't exist, return the empty list if (!datdata.Contains(key)) { return(false); } // Try to find duplicates List <DatItem> roms = datdata[key]; foreach (DatItem rom in roms) { if (this.Equals(rom)) { return(true); } } return(false); }
/// <summary> /// List all duplicates found in a DAT based on a rom /// </summary> /// <param name="datdata">Dat to match against</param> /// <param name="remove">True to mark matched roms for removal from the input, false otherwise (default)</param> /// <param name="sorted">True if the DAT is already sorted accordingly, false otherwise (default)</param> /// <returns>List of matched DatItem objects</returns> public List <DatItem> GetDuplicates(DatFile datdata, bool remove = false, bool sorted = false) { List <DatItem> output = new List <DatItem>(); // Check for an empty rom list first if (datdata.Count == 0) { return(output); } // We want to get the proper key for the DatItem string key = SortAndGetKey(datdata, sorted); // If the key doesn't exist, return the empty list if (!datdata.Contains(key)) { return(output); } // Try to find duplicates List <DatItem> roms = datdata[key]; List <DatItem> left = new List <DatItem>(); for (int i = 0; i < roms.Count; i++) { DatItem datItem = roms[i]; if (this.Equals(datItem)) { datItem.Remove = true; output.Add(datItem); } else { left.Add(datItem); } } // If we're in removal mode, add back all roms with the proper flags if (remove) { datdata.Remove(key); datdata.AddRange(key, output); datdata.AddRange(key, left); } return(output); }
/// <summary> /// Wrap refreshing the database with potentially new dats /// </summary> /// <param name="workers">How many workers to launch for the job, default from config</param> /// <param name="missingSha1s">Write paths of dats with missing sha1s into this file</param> private static void InitRefreshDats( int workers, string missingSha1s) { // 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)) { DatabaseTools.EnsureDatabase(_dbSchema, _db, _connectionString); } // Make sure the dats dir is set if (String.IsNullOrWhiteSpace(_dats)) { _dats = "dats"; } _dats = Path.Combine(Globals.ExeDir, _dats); // 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 = new DatFile { Type = "SuperDAT", }; // TODO: All instances of Hash.DeepHashes should be made into 0x0 eventually datroot.PopulateFromDir(_dats, Hash.DeepHashes, false, false, SkipFileType.None, false, false, _tmpdir, false, null, true, null); datroot.BucketBy(SortedBy.SHA1, DedupeType.None); // 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.Contains(hash)) { datroot.Remove(hash); databaseDats.Add(hash); } else if (!databaseDats.Contains(hash)) { unneeded.Add(hash); } } datroot.BucketBy(SortedBy.Game, DedupeType.None, norename: true); 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.Keys) { foreach (Rom value in datroot[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(); }