privateconststringBLOCK_VOLUME_IDS=@"SELECT ""ID"" FROM ""RemoteVolume"" WHERE ""Type"" = ""{2}""";
// Invalid blocksets include those that:
// - Have BlocksetEntries with unknown/invalid blocks (meaning the data to rebuild the blockset isn't available)
// - Invalid blocks include those that appear to be in non-Blocks volumes (e.g., are listed as being in an Index or Files volume) or that appear in an unknown volume (-1)
// - Have BlocklistHash entries with unknown/invalid blocks (meaning the data which defines the list of hashes that makes up the blockset isn't available)
// - Are defined in the Blockset table but have no entries in the BlocksetEntries table (this can happen during recreate if Files volumes reference blocksets that are not found in any Index files)
SELECT ""A"".""ID"" AS ""ID"", ""B"".""BlocksetID"" AS ""BlocksetID"" FROM ""FileLookup"" A LEFT JOIN ""Metadataset"" B ON ""A"".""MetadataID"" = ""B"".""ID""
SELECT ""A"".""ID"" AS ""BlocksetID"" FROM ""Blockset"" A LEFT JOIN ""BlocksetEntry"" B ON ""A"".""ID"" = ""B"".""BlocksetID"" WHERE ""A"".""Length"" > 0 AND ""B"".""BlocksetID"" IS NULL
privateconststringBROKEN_FILE_SETS=@"SELECT DISTINCT ""B"".""Timestamp"", ""A"".""FilesetID"", COUNT(""A"".""FileID"") AS ""FileCount"" FROM ""FilesetEntry"" A, ""Fileset"" B WHERE ""A"".""FilesetID"" = ""B"".""ID"" AND ""A"".""FileID"" IN ("+BROKEN_FILE_IDS+@")";
privateconststringBROKEN_FILE_NAMES=@"
SELECT ""A"".""Path"", ""B"".""Length"" FROM ""File"" A, ""Blockset"" B WHERE ""A"".""BlocksetID"" = ""B"".""ID"" AND ""A"".""ID"" IN ("
+BROKEN_FILE_IDS+
@") AND ""A"".""ID"" IN (SELECT ""FileID"" FROM ""FilesetEntry"" WHERE ""FilesetID"" = ?)";
deletecmd.CommandText=string.Format(@"INSERT OR IGNORE INTO ""{0}"" (""ID"") VALUES (?)",volidstable);
deletecmd.Parameters.Clear();
deletecmd.AddParameters(1);
foreach(varnameinnames)
{
varvolumeid=GetRemoteVolumeID(name,transaction);
deletecmd.SetParameterValue(0,volumeid);
deletecmd.ExecuteNonQuery();
}
varvolIdsSubQuery=string.Format(@"SELECT ""ID"" FROM ""{0}"" ",volidstable);
deletecmd.Parameters.Clear();
deletecmd.ExecuteNonQuery(string.Format(@"DELETE FROM ""IndexBlockLink"" WHERE ""BlockVolumeID"" IN ({0}) OR ""IndexVolumeID"" IN ({0})",volIdsSubQuery));
deletecmd.ExecuteNonQuery(string.Format(@"DELETE FROM ""Block"" WHERE ""VolumeID"" IN ({0})",volIdsSubQuery));
// Clean up temp tables for subqueries. We truncate content and then try to delete.
// Drop in try-block, as it fails in nested transactions (SQLite problem)
// System.Data.SQLite.SQLiteException (0x80004005): database table is locked
deletecmd.ExecuteNonQuery(string.Format(@"DELETE FROM ""{0}"" ",volidstable));
try
{
deletecmd.CommandTimeout=2;
deletecmd.ExecuteNonQuery(string.Format(@"DROP TABLE IF EXISTS ""{0}"" ",volidstable));
}
catch{/* Ignore, will be deleted on close anyway. */}