Flow.Launcher/Plugins/Flow.Launcher.Plugin.Explorer/Search/WindowsIndex/QueryConstructor.cs

140 lines
5.4 KiB
C#
Raw Normal View History

2020-05-26 11:49:59 +00:00
using Microsoft.Search.Interop;
namespace Flow.Launcher.Plugin.Explorer.Search.WindowsIndex
{
public class QueryConstructor
{
private readonly Settings settings;
2020-05-11 20:47:45 +00:00
private const string SystemIndex = "SystemIndex";
public QueryConstructor(Settings settings)
{
this.settings = settings;
}
2020-05-11 20:47:45 +00:00
public CSearchQueryHelper CreateBaseQuery()
{
2020-05-18 11:31:28 +00:00
var baseQuery = CreateQueryHelper();
2020-05-11 20:47:45 +00:00
// Set the number of results we want. Don't set this property if all results are needed.
baseQuery.QueryMaxResults = settings.MaxResult;
2020-05-11 20:47:45 +00:00
// Set list of columns we want to display, getting the path presently
baseQuery.QuerySelectColumns = "System.FileName, System.ItemUrl, System.ItemType";
2020-05-11 20:47:45 +00:00
2020-05-18 11:31:28 +00:00
// Filter based on file name
2020-05-11 20:47:45 +00:00
baseQuery.QueryContentProperties = "System.FileName";
// Set sorting order
//baseQuery.QuerySorting = "System.ItemType DESC";
return baseQuery;
}
2020-05-18 11:31:28 +00:00
internal CSearchQueryHelper CreateQueryHelper()
{
// This uses the Microsoft.Search.Interop assembly
var manager = new CSearchManager();
// SystemIndex catalog is the default catalog in Windows
var catalogManager = manager.GetCatalog(SystemIndex);
// Get the ISearchQueryHelper which will help us to translate AQS --> SQL necessary to query the indexer
var queryHelper = catalogManager.GetQueryHelper();
return queryHelper;
}
///<summary>
2020-05-18 10:13:31 +00:00
/// Set the required WHERE clause restriction to search on the first level of a specified directory.
///</summary>
public string QueryWhereRestrictionsForTopLevelDirectorySearch(string path)
{
2020-05-27 21:41:14 +00:00
var searchDepth = $"directory='file:";
2020-05-27 21:41:14 +00:00
return QueryWhereRestrictionsFromLocationPath(path, searchDepth);
}
///<summary>
/// Set the required WHERE clause restriction to search all files and subfolders of a specified directory.
///</summary>
public string QueryWhereRestrictionsForTopLevelDirectoryAllFilesAndFoldersSearch(string path)
{
var searchDepth = $"scope='file:";
return QueryWhereRestrictionsFromLocationPath(path, searchDepth);
}
private string QueryWhereRestrictionsFromLocationPath(string path, string searchDepth)
{
2020-05-28 11:35:12 +00:00
if (path.EndsWith(Constants.DirectorySeperator))
2020-05-27 21:41:14 +00:00
return searchDepth + $"{path}'";
2020-05-28 11:35:12 +00:00
var indexOfSeparator = path.LastIndexOf(Constants.DirectorySeperator);
var itemName = path.Substring(indexOfSeparator + 1);
2020-05-28 11:35:12 +00:00
if (itemName.StartsWith(Constants.AllFilesFolderSearchWildcard))
2020-05-27 21:41:14 +00:00
itemName = itemName.Substring(1);
var previousLevelDirectory = path.Substring(0, indexOfSeparator);
2020-05-27 21:41:14 +00:00
if (string.IsNullOrEmpty(itemName))
return searchDepth + $"{previousLevelDirectory}'";
return $"(System.FileName LIKE '{itemName}%' " +
$"OR CONTAINS(System.FileName,'\"{itemName}*\"',1033)) AND " +
2020-05-27 21:41:14 +00:00
searchDepth + $"{previousLevelDirectory}'";
}
2020-05-18 10:13:31 +00:00
///<summary>
/// Search will be performed on all folders and files on the first level of a specified directory.
///</summary>
2020-05-26 11:49:59 +00:00
public string QueryForTopLevelDirectorySearch(string path)
{
string query = "SELECT TOP " + settings.MaxResult + $" {CreateBaseQuery().QuerySelectColumns} FROM {SystemIndex} WHERE ";
2020-05-28 11:35:12 +00:00
if (path.LastIndexOf(Constants.AllFilesFolderSearchWildcard) > path.LastIndexOf(Constants.DirectorySeperator))
2020-05-27 21:41:14 +00:00
return query + QueryWhereRestrictionsForTopLevelDirectoryAllFilesAndFoldersSearch(path);
2020-05-27 21:41:14 +00:00
return query + QueryWhereRestrictionsForTopLevelDirectorySearch(path);
}
///<summary>
/// Search will be performed on all folders and files based on user's search keywords.
///</summary>
public string QueryForAllFilesAndFolders(string userSearchString)
{
2020-05-18 11:31:28 +00:00
// Generate SQL from constructed parameters, converting the userSearchString from AQS->WHERE clause
return CreateBaseQuery().GenerateSQLFromUserQuery(userSearchString) + " AND " + QueryWhereRestrictionsForAllFilesAndFoldersSearch();
}
///<summary>
/// Set the required WHERE clause restriction to search for all files and folders.
///</summary>
public string QueryWhereRestrictionsForAllFilesAndFoldersSearch()
{
return $"scope='file:'";
}
///<summary>
/// Search will be performed on all indexed file contents for the specified search keywords.
///</summary>
public string QueryForFileContentSearch(string userSearchString)
{
string query = "SELECT TOP " + settings.MaxResult + $" {CreateBaseQuery().QuerySelectColumns} FROM {SystemIndex} WHERE ";
return query + QueryWhereRestrictionsForFileContentSearch(userSearchString) + " AND " + QueryWhereRestrictionsForAllFilesAndFoldersSearch();
}
///<summary>
/// Set the required WHERE clause restriction to search within file content.
///</summary>
public string QueryWhereRestrictionsForFileContentSearch(string searchQuery)
{
return $"FREETEXT('{searchQuery}')";
}
}
}