Skip to content

Commit

Permalink
[linq] some fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
exilon committed Jan 27, 2022
1 parent 9690168 commit 9ca3226
Show file tree
Hide file tree
Showing 5 changed files with 585 additions and 443 deletions.
10 changes: 10 additions & 0 deletions Quick.Arrays.pas
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,17 @@ TEnumerator = class(Generics.Collections.TEnumerator<T>)
public
constructor Create(var aArray: TArray<T>);
end;
private type
arrayofT = array of T;
ParrayofT = ^arrayofT;
private
fArray : TArray<T>;
function GetItem(Index : Integer) : T;
procedure SetItem(Index : Integer; const aValue : T);
function GetCapacity: Integer;
function GetCount: Integer;
procedure SetCapacity(const Value: Integer);
function GetPArray: ParrayofT;
public
function GetEnumerator: TEnumerator<T>;
property AsArray : TArray<T> read fArray;
Expand All @@ -72,6 +76,7 @@ TEnumerator = class(Generics.Collections.TEnumerator<T>)
procedure Remove(aItem : T);
function Contains(aItem : T) : Boolean;
function IndexOf(aItem : T) : Integer;
property PArray : ParrayofT read GetPArray;
class operator Implicit(const Value : TxArray<T>) : TArray<T>;
class operator Implicit(const Value : TArray<T>) : TxArray<T>;
end;
Expand Down Expand Up @@ -128,6 +133,11 @@ function TxArray<T>.GetItem(Index : Integer) : T;
Result := fArray[Index];
end;

function TXArray<T>.GetPArray: ParrayofT;
begin
Pointer(Result) := fArray;
end;

procedure TXArray<T>.SetCapacity(const Value: Integer);
begin
if Value = High(fArray) then Exit;
Expand Down
8 changes: 6 additions & 2 deletions Quick.Collections.pas
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
{ ***************************************************************************
Copyright (c) 2016-2021 Kike Pérez
Copyright (c) 2016-2022 Kike Pérez
Unit : Quick.Collections
Description : Generic Collections
Author : Kike Pérez
Version : 1.2
Created : 07/03/2020
Modified : 05/08/2021
Modified : 27/01/2022
This file is part of QuickLib: https://github.com/exilon/QuickLib
Expand Down Expand Up @@ -461,7 +461,11 @@ procedure TxList<T>.TrimExcess;

function TxList<T>.Where(const aMatchString: string; aUseRegEx: Boolean): ILinqArray<T>;
begin
{$IFDEF DELPHIRX104_UP}
Result := TLinqArray<T>.Create(fList.PList^);
{$ELSE}
Result := TLinqArray<T>.Create(fList.ToArray);
{$ENDIF}
Result.Where(aMatchString, aUseRegEx);
end;

Expand Down
49 changes: 41 additions & 8 deletions Quick.Linq.pas
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
Author : Kike Pérez
Version : 1.0
Created : 04/04/2019
Modified : 19/01/2022
Modified : 27/01/2022
This file is part of QuickLib: https://github.com/exilon/QuickLib
Expand Down Expand Up @@ -145,12 +145,14 @@ TLinqArrayHelper = record helper for TArray<string>
TLinqQuery<T : class> = class(TInterfacedObject,ILinqQuery<T>)
private type
arrayOfT = array of T;
TArrType = (atArray, atXArray, atList, atObjectList);
private
fWhereClause : TExpression;
fOrderBy : TArray<string>;
fOrderDirection : TOrderDirection;
//fPList : Pointer;
fPList : Pointer;
fList : arrayOfT;
fArrType : TArrType;
function FormatParams(const aWhereClause : string; aWhereParams : array of const) : string;
procedure DoOrderBy(vArray : ArrayOfT);
function Compare(const aPropertyName : string; L, R : T) : Integer;
Expand Down Expand Up @@ -205,30 +207,43 @@ procedure TLinqQuery<T>.Clear;
constructor TLinqQuery<T>.Create(aArray: TArray<T>);
begin
Clear;
fPList := Pointer(aArray);
fList := aArray;
fArrType := TArrType.atArray;
end;

{$IFNDEF FPC}
constructor TLinqQuery<T>.Create(aObjectList: TObjectList<T>);
begin
Clear;
//Create(aObjectList.List);
//fPList := Pointer(aObjectList.List);
//fList := arrayOfT(fPList);
fPList := Pointer(aObjectList);
{$IFDEF DELPHIRX104_UP}
fList := aObjectList.PList^;
{$ELSE}
fList := aObjectList.List;
{$ENDIF}
fArrType := TArrType.atObjectList;
end;
{$ENDIF}

constructor TLinqQuery<T>.Create(aXArray: TxArray<T>);
begin
Clear;
fList := aXArray;
fPList := Pointer(aXArray);
fList := aXArray.PArray^;
fArrType := TArrType.atXArray;
end;

constructor TLinqQuery<T>.Create(aList: TList<T>);
begin
Clear;
fPList := Pointer(aList);
{$IFDEF DELPHIRX104_UP}
fList := aList.PList^;
{$ELSE}
fList := aList.ToArray;
{$ENDIF}
fArrType := TArrType.atList;
end;

function TLinqQuery<T>.Compare(const aPropertyName: string; L, R: T): Integer;
Expand Down Expand Up @@ -285,8 +300,22 @@ function TLinqQuery<T>.Delete: Integer;
begin
if fWhereClause.Validate(fList[i]) then
begin
TObject(fList[i]).Free;
//System.Delete(fList,i,1);
case fArrType of
TArrType.atArray, TArrType.atXArray :
begin
TObject(fList[i]).Free;
System.Delete(fList,i,1);
//fPList := Pointer(fList);
end;
TArrType.atList :
begin
TList<T>(fPList).Delete(i);
end;
TArrType.atObjectList :
begin
TObjectList<T>(fPList).Delete(i);
end;
end;
Inc(Result);
end;
end;
Expand Down Expand Up @@ -588,7 +617,11 @@ function TLinqArray<T>.Count: Integer;

constructor TLinqArray<T>.Create(aArray: TArray<T>);
begin
{$IFDEF DELPHIRX104_UP}
Pointer(fArray) := aArray;
{$ELSE}
fArray := aArray;
{$ENDIF}
end;

function TLinqArray<T>.Delete: Integer;
Expand Down
17 changes: 15 additions & 2 deletions samples/delphi/QuickCollections/InterfacedLists.dpr
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ begin

//add values
myarray := ['Joe','Mat','Lee'];
//remove if starts with J
myarray.Where('^J',True).Delete;
//search for regex match
cout('Search for regex match',ccYellow);
for name in myarray.Where('e$',True).Select do
Expand All @@ -73,9 +75,9 @@ begin

//search for regex match
cout('Search for regex match',ccYellow);
for name in List.Where('e$',True).Select do
for name in List.Where('^Ma',True).Select do
begin
cout('User %s ends with "e"',[name],etInfo);
cout('User %s starts with "Ma"',[name],etInfo);
end;

//add values to objectlist
Expand All @@ -102,6 +104,17 @@ begin
user := ListObj.Where('Roles2 CONTAINS ?',['SuperAdmin']).SelectFirst;
if user <> nil then cout('%s is %s',[user.Name,CommaText(user.Roles)],etInfo);

cout('List before remove Mat',ccYellow);
for user in ListObj do
begin
cout('User "%s"',[user.Name],etInfo);
end;
ListObj.Where('Name = ?',['Mat']).Delete;
cout('List after remove Mat',ccYellow);
for user in ListObj do
begin
cout('User "%s"',[user.Name],etInfo);
end;

cout('Press ENTER to Exit',ccYellow);
ConsoleWaitForEnterKey;
Expand Down
Loading

0 comments on commit 9ca3226

Please sign in to comment.