{
* UQuery.pas
*
* Defines a singleton object that encapsulates a query on the code snippets
* database.
*
* v1.0 of 04 Feb 2007 - Original version.
* v1.1 of 14 Sep 2008 - Added new Refresh method to IQuery that re-applies the
* previous search.
*
*
* ***** BEGIN LICENSE BLOCK *****
*
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
* the specific language governing rights and limitations under the License.
*
* The Original Code is UQuery.pas
*
* The Initial Developer of the Original Code is Peter Johnson
* (http://www.delphidabbler.com/).
*
* Portions created by the Initial Developer are Copyright (C) 2007-2008 Peter
* Johnson. All Rights Reserved.
*
* ***** END LICENSE BLOCK *****
}
unit UQuery;
interface
uses
// Project
USearch, USnippets;
type
{
IQuery:
Interface to object that encapsulates a query on the code snippets database.
It enables a search to be run against the database and provides access to
the selected routines.
}
IQuery = interface(IInterface)
['{10998D72-CD5D-482B-9626-D771A50C53BA}']
function ApplySearch(const Search: ISearch): Boolean;
{Runs query by applying a search to the whole database. If search succeeds
matching routines and search are stored in query's Selection and Search
properties. If search fails Selection and Search are left unchanged.
@param Search [in] Search to apply.
@return True if search succeeds and False if it fails.
}
procedure Reset;
{Resets query. Selection property is set to all routines in database and
Search property is set to nul search.
}
function Refresh: Boolean;
{Re-applies the current search if one exists.
@return True if search was re-applied, False if there was no search to
apply.
}
function GetCurrentSearch: ISearch;
{Gets value of CurrentSearch property.
@return Search object used to generate current search.
}
function GetSelection: TRoutineList;
{Gets value of Selection property.
@return List of routines matching current query.
}
procedure GetCatSelection(const Cat: TCategory;
const Routines: TRoutineList);
{Provides list of routines selected by last search that are in a specified
category.
@param Cat [in] Reference to required category.
@param Routines [in] Object to receive routine list. List is emptied
before routines are copied in.
}
property CurrentSearch: ISearch read GetCurrentSearch;
{Reference to search object used to generate current query}
property Selection: TRoutineList read GetSelection;
{List of routines that match current query. This records all routines in
database if there is no search}
end;
function Query: IQuery;
{Returns singleton instance of object that encapsulates a query on the
snippets database.
@return Singleton object.
}
implementation
uses
// Delphi
SysUtils;
type
{
TQuery:
Class that encapsulates a query on the code snippets database. It enables a
search to be run against the database and makes the found routines
available.
}
TQuery = class(TInterfacedObject,
IQuery
)
strict private
fSelection: TRoutineList;
{List of routines selected by current query}
fSearch: ISearch;
{Reference to search object used by current query}
protected
{ IQuery methods }
function ApplySearch(const Search: ISearch): Boolean;
{Runs query by applying a search to the whole database. If search succeeds
matching routines and search are stored in query's Selection and Search
properties. If search fails Selection and Search are left unchanged.
@param Search [in] Search to apply.
@return True if search succeeds and False if it fails.
}
function Refresh: Boolean;
{Re-applies the current search if one exists.
@return True if search was re-applied, False if there was no search to
apply.
}
procedure Reset;
{Resets query. Selection property is set to all routines in database and
Search property is set to nul search.
}
function GetCurrentSearch: ISearch;
{Gets reference to current search object.
@return Required search object.
}
function GetSelection: TRoutineList;
{Gets reference to list of routines selected by last search.
@return Reference to required list of routines.
}
procedure GetCatSelection(const Cat: TCategory;
const Routines: TRoutineList);
{Provides list of routines selected by last search that are in a specified
category.
@param Cat [in] Reference to required category.
@param Routines [in] Object to receive routine list. List is emptied
before routines are copied in.
}
public
constructor Create;
{Class constructor. Sets up object with all routines in database selected.
}
destructor Destroy; override;
{Class destructor. Tears down object.
}
end;
var
// Private global query singleton object
PvtQuery: IQuery = nil;
function Query: IQuery;
{Returns singleton instance of object that encapsulates a query on the
snippets database.
@return Singleton object.
}
begin
if not Assigned(PvtQuery) then
PvtQuery := TQuery.Create;
Result := PvtQuery;
end;
{ TQuery }
function TQuery.ApplySearch(const Search: ISearch): Boolean;
{Runs query by applying a search to the whole database. If search succeeds
matching routines and search are stored in query's Selection and Search
properties. If search fails Selection and Search are left unchanged.
@param Search [in] Search to apply.
@return True if search succeeds and False if it fails.
}
var
FoundList: TRoutineList; // list receives found routines
begin
Assert(Assigned(Search), // ** do not localise
'TQuery.ApplySearch: Search is nil');
FoundList := TRoutineList.Create;
try
// Get list of routines that match search
// if there are no routines found we leave current selection alone
Result := (Search as ISearch).Execute(Snippets.Routines, FoundList);
if Result then
begin
// Search succeeded: record search and list of routines
fSearch := Search;
fSelection.Assign(FoundList);
end;
finally
FreeAndNil(FoundList);
end;
end;
constructor TQuery.Create;
{Class constructor. Sets up object with all routines in database selected.
}
begin
inherited;
fSelection := TRoutineList.Create;
Reset;
end;
destructor TQuery.Destroy;
{Class destructor. Tears down object.
}
begin
FreeAndNil(fSelection);
fSearch := nil;
inherited;
end;
procedure TQuery.GetCatSelection(const Cat: TCategory;
const Routines: TRoutineList);
{Provides list of routines selected by last search that are in a specified
category.
@param Cat [in] Reference to required category.
@param Routines [in] Object to receive routine list. List is emptied before
routines are copied in.
}
var
Idx: Integer; // Loops thru all routines in selection
begin
Routines.Clear;
for Idx := 0 to Pred(fSelection.Count) do
begin
if Cat.Routines.Contains(fSelection[Idx]) then
Routines.Add(fSelection[Idx]);
end;
end;
function TQuery.GetCurrentSearch: ISearch;
{Gets reference to current search object.
@return Required search object.
}
begin
Result := fSearch;
end;
function TQuery.GetSelection: TRoutineList;
{Gets reference to list of routines selected by last search.
@return Reference to required list of routines.
}
begin
Result := fSelection;
end;
function TQuery.Refresh: Boolean;
{Re-applies the current search if one exists.
@return True if search was re-applied, False if there was no search to
apply.
}
begin
if Assigned(fSearch) then
Result := ApplySearch(fSearch)
else
Result := False;
end;
procedure TQuery.Reset;
{Resets query. Selection property is set to all routines in database and
Search property is set to nul search.
}
begin
fSelection.Assign(Snippets.Routines);
fSearch := TSearchFactory.CreateNulSearch;
end;
initialization
finalization
// Free the singletion
PvtQuery := nil;
end.