program LinqList; {$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils, System.Generics.Collections, Quick.Commons, Quick.Console, Quick.Log, Quick.Chrono, Quick.Lists, Quick.Linq; type TLoginInfo = record Username : string; UserPassword : string; Locked : Boolean; end; TUser = class private fId : Int64; fName : string; fSurName : string; fAge : Integer; fLoginInfo : TLoginInfo; published property Id : Int64 read fId write fId; property Name : string read fName write fName; property SurName : string read fSurName write fSurName; property Age : Integer read fAge write fAge; property LoginInfo : TLoginInfo read fLoginInfo write fLoginInfo; end; const numusers = 100000; UserNames : array of string = ['Cliff','Alan','Anna','Phil','John','Michel','Jennifer','Peter','Brandon','Joe','Steve','Lorraine','Bill','Tom','Norma','Martin','Steffan','Wilma','Derek','Lewis','Paul', 'Erik','Robert','Nicolas','Frederik','Rose']; UserSurnames : array of string = ['Gordon','Summer','Huan','Paterson','Johnson','Michelson','Smith','Peterson','Miller','McCarney','Roller','Gonzalez','Thomson','Muller','Jefferson','Volkov','Matheu','Morrison','Newman','Lover','Sunday', 'Roberts','Landon','Yuri','Paris','Levis']; var users : TIndexedObjectList; users2 : TSearchObjectList; user : TUser; i : Integer; n : Integer; crono : TChronometer; login : TLoginInfo; begin try ReportMemoryLeaksOnShutdown := True; users := TIndexedObjectList.Create(True); users.Indexes.Add('Name','Name'); users.Indexes.Add('Surname','fSurname',TClassField.cfField); users.Indexes.Add('id','Id'); users2 := TSearchObjectList.Create(False); cout('Generating list...',etInfo); //generate first dummy entries for i := 1 to numusers - high(UserNames) do begin user := TUser.Create; user.Id := Random(999999999999999); user.Name := 'Name' + i.ToString; user.SurName := 'SurName' + i.ToString; user.Age := 18 + Random(20); users.Add(user); users2.Add(user); end; //generate real entries to search for i := 0 to high(UserNames) do begin user := TUser.Create; user.Id := Random(999999999999999); user.Name := UserNames[i]; user.SurName := UserSurnames[i]; user.Age := 18 + Random(20); login.Username := user.Name; login.UserPassword := RandomPassword(8,[pfIncludeNumbers,pfIncludeSigns]); login.Locked := False; user.LoginInfo := login; users.Add(user); users2.Add(user); end; crono := TChronometer.Create; //test search by index crono.Start; user := users.Get('Name','Peter'); crono.Stop; if user <> nil then cout('Found by Index: %s %s in %s',[user.Name,user.SurName,crono.ElapsedTime],etSuccess) else cout('Not found!',etError); //test search by normal iteration user := nil; crono.Start; for i := 0 to users.Count - 1 do begin //if (users[i].Name = 'Anus') or (users[i].SurName = 'Smith') then if users[i].Name = 'Peter' then begin user := users[i]; crono.Stop; Break; end; end; if user <> nil then cout('Found by Iteration: %s %s at %d position in %s',[user.Name,user.SurName,i,crono.ElapsedTime],etSuccess) else cout('Not found by Iteration!',etError); //test search by Linq iteration crono.Start; //user := TLinq.From(users2).Where('(Name = ?) OR (SurName = ?)',['Anus','Smith']).OrderBy('Name').SelectFirst; user := TLinq.From(users2).Where('Name = ?',['Peter']).SelectFirst; crono.Stop; if user <> nil then cout('Found by Linq: %s %s in %s',[user.Name,user.SurName,crono.ElapsedTime],etSuccess) else cout('Not found by Linq! (%s)',[crono.ElapsedTime],etError); //test search by Linq iteration (predicate) crono.Start; //user := TLinq.From(users2).Where('(Name = ?) OR (SurName = ?)',['Anus','Smith']).OrderBy('Name').SelectFirst; user := TLinq.From(users2).Where(function(aUser : TUser) : Boolean begin Result := aUser.Name = 'Peter'; end).SelectFirst; crono.Stop; if user <> nil then cout('Found by Linq (predicate): %s %s in %s',[user.Name,user.SurName,crono.ElapsedTime],etSuccess) else cout('Not found by Linq! (%s)',[crono.ElapsedTime],etError); //test search by embeded iteration crono.Start; user := users2.Get('Name','Peter'); crono.Stop; if user <> nil then cout('Found by Search: %s %s in %s',[user.Name,user.SurName,crono.ElapsedTime],etSuccess) else cout('Not found!',etError); //ConsoleWaitForEnterKey; cout('Multi results:',etInfo); //test search by normal iteration user := nil; n := 0; cout('Found by Iteration:',etInfo); for i := 0 to users.Count - 1 do begin //if ((users[i].Name = 'Anna') or (users[i].Age > 30)) or (users[i].SurName = 'Smith') then //if users[i].Age > 18 then if (users[i].Name = 'Anna') then begin Inc(n); user := users[i]; cout('%d. %s %s',[n,user.Name,user.SurName],etSuccess) end; end; if user = nil then cout('Not found by Iteration!',etError); //test search by Linq iteration user := nil; n := 0; cout('Found by Linq:',etInfo); //TLinq.From(users2).Where('Name Like ?',['p%']).Delete; TLinq.From(users2).Where('Name = ?',['Peter']).Update(['Name'],['Poter']); //for user in TLinq.From(users2).Where('(Name = ?) OR (SurName = ?) OR (SurName = ?)',['Peter','Smith','Huan']).Select do //for user in TLinq.From(users2).Where('(Name = ?) OR (Age > ?) OR (SurName = ?)',['Anna',30,'Smith']).Select do //for user in TLinq.From(users2).Where('Age > ?',[18]).Select do //for user in TLinq.From(users2).Where('SurName Like ?',['%son']).Select do //for user in TLinq.From(users2).Where('SurName Like ?',['p%']).Select do //for user in TLinq.From(users2).Where('1 = 1',[]).Select do for user in TLinq.From(users2).Where('(LoginInfo.UserName Like ?) OR (LoginInfo.UserName Like ?)',['p%','a%']) .OrderBy('Name') .Select do begin Inc(n); cout('Login.Username: %d. %s %s',[n,user.Name,user.SurName],etSuccess); end; if user = nil then cout('Not found by Linq!',etError); cout('Press a key to Exit',etInfo); Readln; users.Free; users2.Free; crono.Free; except on E: Exception do cout('%s : %s',[E.ClassName,E.Message],etError); end; end.