public IEnumerable <IFileversion> SelectFiles(Library.Utility.IFilter filter) { using (var tmpnames = new FilteredFilenameTable(m_connection, filter, null)) using (var cmd = m_connection.CreateCommand()) { //First we trim the filelist to exclude filenames not found in any of the filesets cmd.ExecuteNonQuery(string.Format(@"DELETE FROM ""{0}"" WHERE ""Path"" NOT IN (SELECT DISTINCT ""Path"" FROM ""File"", ""FilesetEntry"" WHERE ""FilesetEntry"".""FileID"" = ""File"".""ID"" AND ""FilesetEntry"".""FilesetID"" IN (SELECT ""FilesetID"" FROM ""{1}"") ) ", tmpnames.Tablename, m_tablename)); //Then we select the matching results var filesets = string.Format(@"SELECT ""FilesetID"", ""Timestamp"" FROM ""{0}"" ORDER BY ""Timestamp"" DESC", m_tablename); var cartesianPathFileset = string.Format(@"SELECT ""A"".""Path"", ""B"".""FilesetID"" FROM ""{0}"" A, (" + filesets + @") B ORDER BY ""A"".""Path"" ASC, ""B"".""Timestamp"" DESC", tmpnames.Tablename, m_tablename); var filesWithSizes = @"SELECT ""Length"", ""FilesetEntry"".""FilesetID"", ""File"".""Path"" FROM ""Blockset"", ""FilesetEntry"", ""File"" WHERE ""File"".""BlocksetID"" = ""Blockset"".""ID"" AND ""FilesetEntry"".""FileID"" = ""File"".""ID"" "; var query = @"SELECT ""C"".""Path"", ""D"".""Length"", ""C"".""FilesetID"" FROM (" + cartesianPathFileset + @") C LEFT OUTER JOIN (" + filesWithSizes + @") D ON ""C"".""FilesetID"" = ""D"".""FilesetID"" AND ""C"".""Path"" = ""D"".""Path"""; using (var rd = cmd.ExecuteReader(query)) if (rd.Read()) { bool more; do { var f = new Fileversion(rd); yield return(f); more = f.More; } while(more); } } }
public IEnumerable<IFileversion> SelectFiles(Library.Utility.IFilter filter) { using(var tmpnames = new FilteredFilenameTable(m_connection, filter, null)) using(var cmd = m_connection.CreateCommand()) { //First we trim the filelist to exclude filenames not found in any of the filesets cmd.ExecuteNonQuery(string.Format(@"DELETE FROM ""{0}"" WHERE ""Path"" NOT IN (SELECT DISTINCT ""Path"" FROM ""File"", ""FilesetEntry"" WHERE ""FilesetEntry"".""FileID"" = ""File"".""ID"" AND ""FilesetEntry"".""FilesetID"" IN (SELECT ""FilesetID"" FROM ""{1}"") ) ", tmpnames.Tablename, m_tablename)); //Then we select the matching results var filesets = string.Format(@"SELECT ""FilesetID"", ""Timestamp"" FROM ""{0}"" ORDER BY ""Timestamp"" DESC", m_tablename); var cartesianPathFileset = string.Format(@"SELECT ""A"".""Path"", ""B"".""FilesetID"" FROM ""{0}"" A, (" + filesets + @") B ORDER BY ""A"".""Path"" ASC, ""B"".""Timestamp"" DESC", tmpnames.Tablename, m_tablename); var filesWithSizes = @"SELECT ""Length"", ""FilesetEntry"".""FilesetID"", ""File"".""Path"" FROM ""Blockset"", ""FilesetEntry"", ""File"" WHERE ""File"".""BlocksetID"" = ""Blockset"".""ID"" AND ""FilesetEntry"".""FileID"" = ""File"".""ID"" "; var query = @"SELECT ""C"".""Path"", ""D"".""Length"", ""C"".""FilesetID"" FROM (" + cartesianPathFileset + @") C LEFT OUTER JOIN (" + filesWithSizes + @") D ON ""C"".""FilesetID"" = ""D"".""FilesetID"" AND ""C"".""Path"" = ""D"".""Path"""; using(var rd = cmd.ExecuteReader(query)) if(rd.Read()) { bool more; do { var f = new Fileversion(rd); yield return f; more = f.More; } while(more); } } }
public IEnumerable <IFileversion> SelectFolderContents(Library.Utility.IFilter filter) { var tbname = "Filenames-" + Library.Utility.Utility.ByteArrayAsHexString(Guid.NewGuid().ToByteArray()); try { string pathprefix; if (filter == null || filter.Empty) { pathprefix = ""; } else if (filter as Library.Utility.FilterExpression == null || ((Library.Utility.FilterExpression)filter).Type != Duplicati.Library.Utility.FilterType.Simple || ((Library.Utility.FilterExpression)filter).GetSimpleList().Length != 1) { throw new ArgumentException("Filter for list-folder-contents must be a path prefix with no wildcards", "filter"); } else { pathprefix = ((Library.Utility.FilterExpression)filter).GetSimpleList().First(); } var dirsep = Duplicati.Library.Utility.Utility.GuessDirSeparator(pathprefix); if (pathprefix.Length > 0 || dirsep == "/") { pathprefix = Duplicati.Library.Utility.Utility.AppendDirSeparator(pathprefix, dirsep); } using (var tmpnames = new FilteredFilenameTable(m_connection, new Library.Utility.FilterExpression(new string[] { pathprefix + "*" }, true), null)) using (var cmd = m_connection.CreateCommand()) { //First we trim the filelist to exclude filenames not found in any of the filesets cmd.ExecuteNonQuery(string.Format(@"DELETE FROM ""{0}"" WHERE ""Path"" NOT IN (SELECT DISTINCT ""Path"" FROM ""File"", ""FilesetEntry"" WHERE ""FilesetEntry"".""FileID"" = ""File"".""ID"" AND ""FilesetEntry"".""FilesetID"" IN (SELECT ""FilesetID"" FROM ""{1}"") ) ", tmpnames.Tablename, m_tablename)); // If we had instr support this would work: /*var distinctPaths = @"SELECT DISTINCT :1 || " + * @"CASE(INSTR(SUBSTR(""Path"", :2), ""/"")) " + * @"WHEN 0 THEN SUBSTR(""Path"", :2) " + * @"ELSE SUBSTR(""Path"", :2, INSTR(SUBSTR(path, :2), ""/"")) " + * @"END AS ""Path"", ""FilesetID"" " + * @" FROM (" + cartesianPathFileset + @")";*/ // Instead we manually iterate the paths cmd.ExecuteNonQuery(string.Format(@"CREATE TEMPORARY TABLE ""{0}"" (""Path"" TEXT NOT NULL)", tbname)); using (var c2 = m_connection.CreateCommand()) { c2.CommandText = string.Format(@"INSERT INTO ""{0}"" (""Path"") VALUES (?)", tbname); c2.AddParameter(); foreach (var n in SelectFolderEntries(cmd, pathprefix, tmpnames.Tablename).Distinct()) { c2.SetParameterValue(0, n); c2.ExecuteNonQuery(); } c2.ExecuteNonQuery(string.Format(@"CREATE INDEX ""{0}_PathIndex"" ON ""{0}"" (""Path"")", tbname)); } //Then we select the matching results var filesets = string.Format(@"SELECT ""FilesetID"", ""Timestamp"" FROM ""{0}"" ORDER BY ""Timestamp"" DESC", m_tablename); var cartesianPathFileset = string.Format(@"SELECT ""A"".""Path"", ""B"".""FilesetID"" FROM ""{0}"" A, (" + filesets + @") B ORDER BY ""A"".""Path"" ASC, ""B"".""Timestamp"" DESC", tbname, m_tablename); var filesWithSizes = @"SELECT ""Length"", ""FilesetEntry"".""FilesetID"", ""File"".""Path"" FROM ""Blockset"", ""FilesetEntry"", ""File"" WHERE ""File"".""BlocksetID"" = ""Blockset"".""ID"" AND ""FilesetEntry"".""FileID"" = ""File"".""ID"" "; var query = @"SELECT ""C"".""Path"", ""D"".""Length"", ""C"".""FilesetID"" FROM (" + cartesianPathFileset + @") C LEFT OUTER JOIN (" + filesWithSizes + @") D ON ""C"".""FilesetID"" = ""D"".""FilesetID"" AND ""C"".""Path"" = ""D"".""Path"""; cmd.AddParameter(pathprefix, "1"); cmd.AddParameter(pathprefix.Length + 1, "2"); using (var rd = cmd.ExecuteReader(query)) if (rd.Read()) { bool more; do { var f = new Fileversion(rd); if (!(string.IsNullOrWhiteSpace(f.Path) || f.Path == pathprefix)) { yield return(f); more = f.More; } else { more = rd.Read(); } } while(more); } } } finally { try { using (var c = m_connection.CreateCommand()) c.ExecuteNonQuery(string.Format(@"DROP TABLE IF EXISTS ""{0}""", tbname)); } catch { } } }
public IEnumerable<IFileversion> SelectFolderContents(Library.Utility.IFilter filter) { var tbname = "Filenames-" + Library.Utility.Utility.ByteArrayAsHexString(Guid.NewGuid().ToByteArray()); try { string pathprefix; if (filter == null || filter.Empty) pathprefix = ""; else if (filter as Library.Utility.FilterExpression == null || ((Library.Utility.FilterExpression)filter).Type != Duplicati.Library.Utility.FilterType.Simple || ((Library.Utility.FilterExpression)filter).GetSimpleList().Length != 1) throw new ArgumentException("Filter for list-folder-contents must be a path prefix with no wildcards", "filter"); else pathprefix = ((Library.Utility.FilterExpression)filter).GetSimpleList().First(); if (pathprefix.Length > 0 || Duplicati.Library.Utility.Utility.IsClientLinux) pathprefix = Duplicati.Library.Utility.Utility.AppendDirSeparator(pathprefix); using(var tmpnames = new FilteredFilenameTable(m_connection, new Library.Utility.FilterExpression(pathprefix + "*", true), null)) using(var cmd = m_connection.CreateCommand()) { //First we trim the filelist to exclude filenames not found in any of the filesets cmd.ExecuteNonQuery(string.Format(@"DELETE FROM ""{0}"" WHERE ""Path"" NOT IN (SELECT DISTINCT ""Path"" FROM ""File"", ""FilesetEntry"" WHERE ""FilesetEntry"".""FileID"" = ""File"".""ID"" AND ""FilesetEntry"".""FilesetID"" IN (SELECT ""FilesetID"" FROM ""{1}"") ) ", tmpnames.Tablename, m_tablename)); // If we had instr support this would work: /*var distinctPaths = @"SELECT DISTINCT :1 || " + @"CASE(INSTR(SUBSTR(""Path"", :2), ""/"")) " + @"WHEN 0 THEN SUBSTR(""Path"", :2) " + @"ELSE SUBSTR(""Path"", :2, INSTR(SUBSTR(path, :2), ""/"")) " + @"END AS ""Path"", ""FilesetID"" " + @" FROM (" + cartesianPathFileset + @")";*/ // Instead we manually iterate the paths cmd.ExecuteNonQuery(string.Format(@"CREATE TEMPORARY TABLE ""{0}"" (""Path"" TEXT NOT NULL)", tbname)); using(var c2 = m_connection.CreateCommand()) { c2.CommandText = string.Format(@"INSERT INTO ""{0}"" (""Path"") VALUES (?)", tbname); c2.AddParameter(); foreach(var n in SelectFolderEntries(cmd, pathprefix, tmpnames.Tablename).Distinct()) { c2.SetParameterValue(0, n); c2.ExecuteNonQuery(); } c2.ExecuteNonQuery(string.Format(@"CREATE INDEX ""{0}_PathIndex"" ON ""{0}"" (""Path"")", tbname)); } //Then we select the matching results var filesets = string.Format(@"SELECT ""FilesetID"", ""Timestamp"" FROM ""{0}"" ORDER BY ""Timestamp"" DESC", m_tablename); var cartesianPathFileset = string.Format(@"SELECT ""A"".""Path"", ""B"".""FilesetID"" FROM ""{0}"" A, (" + filesets + @") B ORDER BY ""A"".""Path"" ASC, ""B"".""Timestamp"" DESC", tbname, m_tablename); var filesWithSizes = @"SELECT ""Length"", ""FilesetEntry"".""FilesetID"", ""File"".""Path"" FROM ""Blockset"", ""FilesetEntry"", ""File"" WHERE ""File"".""BlocksetID"" = ""Blockset"".""ID"" AND ""FilesetEntry"".""FileID"" = ""File"".""ID"" "; var query = @"SELECT ""C"".""Path"", ""D"".""Length"", ""C"".""FilesetID"" FROM (" + cartesianPathFileset + @") C LEFT OUTER JOIN (" + filesWithSizes + @") D ON ""C"".""FilesetID"" = ""D"".""FilesetID"" AND ""C"".""Path"" = ""D"".""Path"""; cmd.AddParameter(pathprefix, "1"); cmd.AddParameter(pathprefix.Length + 1, "2"); using(var rd = cmd.ExecuteReader(query)) if (rd.Read()) { bool more; do { var f = new Fileversion(rd); if (!(string.IsNullOrWhiteSpace(f.Path) || f.Path == pathprefix)) { yield return f; more = f.More; } else { more = rd.Read(); } } while(more); } } } finally { try { using(var c = m_connection.CreateCommand()) c.ExecuteNonQuery(string.Format(@"DROP TABLE IF EXISTS ""{0}""", tbname)); } catch { } } }