LinqList.dpr 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. program LinqList;
  2. {$APPTYPE CONSOLE}
  3. {$R *.res}
  4. uses
  5. System.SysUtils,
  6. System.Generics.Collections,
  7. Quick.Commons,
  8. Quick.Console,
  9. Quick.Chrono,
  10. Quick.Lists,
  11. Quick.Linq;
  12. type
  13. TLoginInfo = record
  14. Username : string;
  15. UserPassword : string;
  16. Locked : Boolean;
  17. end;
  18. TUser = class
  19. private
  20. fId : Int64;
  21. fName : string;
  22. fSurName : string;
  23. fAge : Integer;
  24. fLoginInfo : TLoginInfo;
  25. published
  26. property Id : Int64 read fId write fId;
  27. property Name : string read fName write fName;
  28. property SurName : string read fSurName write fSurName;
  29. property Age : Integer read fAge write fAge;
  30. property LoginInfo : TLoginInfo read fLoginInfo write fLoginInfo;
  31. end;
  32. const
  33. numusers = 100000;
  34. 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',
  35. 'Erik','Robert','Nicolas','Frederik','Rose'];
  36. 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',
  37. 'Roberts','Landon','Yuri','Paris','Levis'];
  38. var
  39. users : TIndexedObjectList<TUser>;
  40. users2 : TSearchObjectList<TUser>;
  41. user : TUser;
  42. i : Integer;
  43. n : Integer;
  44. crono : TChronometer;
  45. login : TLoginInfo;
  46. begin
  47. try
  48. ReportMemoryLeaksOnShutdown := True;
  49. users := TIndexedObjectList<TUser>.Create(True);
  50. users.Indexes.Add('Name','Name');
  51. users.Indexes.Add('Surname','fSurname',TClassField.cfField);
  52. users.Indexes.Add('id','Id');
  53. users2 := TSearchObjectList<TUser>.Create(False);
  54. cout('Generating list...',etInfo);
  55. //generate first dummy entries
  56. for i := 1 to numusers - high(UserNames) do
  57. begin
  58. user := TUser.Create;
  59. user.Id := Random(999999999999999);
  60. user.Name := 'Name' + i.ToString;
  61. user.SurName := 'SurName' + i.ToString;
  62. user.Age := 18 + Random(20);
  63. users.Add(user);
  64. users2.Add(user);
  65. end;
  66. //generate real entries to search
  67. for i := 0 to high(UserNames) do
  68. begin
  69. user := TUser.Create;
  70. user.Id := Random(999999999999999);
  71. user.Name := UserNames[i];
  72. user.SurName := UserSurnames[i];
  73. user.Age := 18 + Random(20);
  74. login.Username := user.Name;
  75. login.UserPassword := RandomPassword(8,[pfIncludeNumbers,pfIncludeSigns]);
  76. login.Locked := False;
  77. user.LoginInfo := login;
  78. users.Add(user);
  79. users2.Add(user);
  80. end;
  81. crono := TChronometer.Create;
  82. //test search by index
  83. crono.Start;
  84. user := users.Get('Name','Peter');
  85. crono.Stop;
  86. if user <> nil then cout('Found by Index: %s %s in %s',[user.Name,user.SurName,crono.ElapsedTime],etSuccess)
  87. else cout('Not found!',etError);
  88. //test search by normal iteration
  89. user := nil;
  90. crono.Start;
  91. for i := 0 to users.Count - 1 do
  92. begin
  93. //if (users[i].Name = 'Anus') or (users[i].SurName = 'Smith') then
  94. if users[i].Name = 'Peter' then
  95. begin
  96. user := users[i];
  97. crono.Stop;
  98. Break;
  99. end;
  100. end;
  101. if user <> nil then cout('Found by Iteration: %s %s at %d position in %s',[user.Name,user.SurName,i,crono.ElapsedTime],etSuccess)
  102. else cout('Not found by Iteration!',etError);
  103. //test search by Linq iteration
  104. crono.Start;
  105. //user := TLinq.From<TUser>(users2).Where('(Name = ?) OR (SurName = ?)',['Anus','Smith']).OrderBy('Name').SelectFirst;
  106. user := TLinq<TUser>.From(users2).Where('Name = ?',['Peter']).SelectFirst;
  107. crono.Stop;
  108. if user <> nil then cout('Found by Linq: %s %s in %s',[user.Name,user.SurName,crono.ElapsedTime],etSuccess)
  109. else cout('Not found by Linq! (%s)',[crono.ElapsedTime],etError);
  110. //test search by Linq iteration (predicate)
  111. crono.Start;
  112. //user := TLinq.From<TUser>(users2).Where('(Name = ?) OR (SurName = ?)',['Anus','Smith']).OrderBy('Name').SelectFirst;
  113. user := TLinq<TUser>.From(users2).Where(function(aUser : TUser) : Boolean
  114. begin
  115. Result := aUser.Name = 'Peter';
  116. end).SelectFirst;
  117. crono.Stop;
  118. if user <> nil then cout('Found by Linq (predicate): %s %s in %s',[user.Name,user.SurName,crono.ElapsedTime],etSuccess)
  119. else cout('Not found by Linq! (%s)',[crono.ElapsedTime],etError);
  120. //test search by embeded iteration
  121. crono.Start;
  122. user := users2.Get('Name','Peter');
  123. crono.Stop;
  124. if user <> nil then cout('Found by Search: %s %s in %s',[user.Name,user.SurName,crono.ElapsedTime],etSuccess)
  125. else cout('Not found!',etError);
  126. //ConsoleWaitForEnterKey;
  127. cout('Multi results:',etInfo);
  128. //test search by normal iteration
  129. user := nil;
  130. n := 0;
  131. cout('Found by Iteration:',etInfo);
  132. for i := 0 to users.Count - 1 do
  133. begin
  134. //if ((users[i].Name = 'Anna') or (users[i].Age > 30)) or (users[i].SurName = 'Smith') then
  135. //if users[i].Age > 18 then
  136. if (users[i].Name = 'Anna') then
  137. begin
  138. Inc(n);
  139. user := users[i];
  140. cout('%d. %s %s',[n,user.Name,user.SurName],etSuccess)
  141. end;
  142. end;
  143. if user = nil then cout('Not found by Iteration!',etError);
  144. //test search by Linq iteration
  145. user := nil;
  146. n := 0;
  147. cout('Found by Linq:',etInfo);
  148. //TLinq<TUser>.From(users2).Where('Name Like ?',['p%']).Delete;
  149. TLinq<TUser>.From(users2).Where('Name = ?',['Peter']).Update(['Name'],['Poter']);
  150. //for user in TLinq<TUser>.From(users2).Where('(Name = ?) OR (SurName = ?) OR (SurName = ?)',['Peter','Smith','Huan']).Select do
  151. //for user in TLinq<TUser>.From(users2).Where('(Name = ?) OR (Age > ?) OR (SurName = ?)',['Anna',30,'Smith']).Select do
  152. //for user in TLinq<TUser>.From(users2).Where('Age > ?',[18]).Select do
  153. //for user in TLinq<TUser>.From(users2).Where('SurName Like ?',['%son']).Select do
  154. //for user in TLinq<TUser>.From(users2).Where('SurName Like ?',['p%']).Select do
  155. //for user in TLinq<TUser>.From(users2).Where('1 = 1',[]).Select do
  156. for user in TLinq<TUser>.From(users2).Where('(LoginInfo.UserName Like ?) OR (LoginInfo.UserName Like ?)',['p%','a%'])
  157. .OrderBy('Name')
  158. .Select do
  159. begin
  160. Inc(n);
  161. cout('Login.Username: %d. %s %s',[n,user.Name,user.SurName],etSuccess);
  162. end;
  163. if user = nil then cout('Not found by Linq!',etError);
  164. cout('Press a key to Exit',etInfo);
  165. Readln;
  166. users.Free;
  167. users2.Free;
  168. crono.Free;
  169. except
  170. on E: Exception do
  171. cout('%s : %s',[E.ClassName,E.Message],etError);
  172. end;
  173. end.