LinqList.dpr 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  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. users3 : TObjectList<TUser>;
  42. user : TUser;
  43. i : Integer;
  44. n : Integer;
  45. crono : TChronometer;
  46. login : TLoginInfo;
  47. begin
  48. try
  49. ReportMemoryLeaksOnShutdown := True;
  50. users := TIndexedObjectList<TUser>.Create(True);
  51. users.Indexes.Add('Name','Name');
  52. users.Indexes.Add('Surname','fSurname',TClassField.cfField);
  53. users.Indexes.Add('id','Id');
  54. users2 := TSearchObjectList<TUser>.Create(False);
  55. users3 := TObjectList<TUser>.Create(True);
  56. cout('Generating list...',etInfo);
  57. //generate first dummy entries
  58. for i := 1 to numusers - high(UserNames) do
  59. begin
  60. user := TUser.Create;
  61. user.Id := Random(999999999999999);
  62. user.Name := 'Name' + i.ToString;
  63. user.SurName := 'SurName' + i.ToString;
  64. user.Age := 18 + Random(20);
  65. users.Add(user);
  66. users2.Add(user);
  67. users3.Add(user);
  68. end;
  69. //generate real entries to search
  70. for i := 0 to high(UserNames) do
  71. begin
  72. user := TUser.Create;
  73. user.Id := Random(999999999999999);
  74. user.Name := UserNames[i];
  75. user.SurName := UserSurnames[i];
  76. user.Age := 18 + Random(20);
  77. login.Username := user.Name;
  78. login.UserPassword := RandomPassword(8,[pfIncludeNumbers,pfIncludeSigns]);
  79. login.Locked := False;
  80. user.LoginInfo := login;
  81. users.Add(user);
  82. users2.Add(user);
  83. users3.Add(user);
  84. end;
  85. crono := TChronometer.Create;
  86. //test search by index
  87. crono.Start;
  88. user := users.Get('Name','Peter');
  89. crono.Stop;
  90. if user <> nil then cout('Found by Index: %s %s in %s',[user.Name,user.SurName,crono.ElapsedTime],etSuccess)
  91. else cout('Not found!',etError);
  92. //test search by normal iteration
  93. user := nil;
  94. crono.Start;
  95. for i := 0 to users.Count - 1 do
  96. begin
  97. //if (users[i].Name = 'Anus') or (users[i].SurName = 'Smith') then
  98. if users[i].Name = 'Peter' then
  99. begin
  100. user := users[i];
  101. crono.Stop;
  102. Break;
  103. end;
  104. end;
  105. if user <> nil then cout('Found by Iteration: %s %s at %d position in %s',[user.Name,user.SurName,i,crono.ElapsedTime],etSuccess)
  106. else cout('Not found by Iteration!',etError);
  107. //test search by Linq iteration
  108. crono.Start;
  109. //user := TLinq.From<TUser>(users2).Where('(Name = ?) OR (SurName = ?)',['Anus','Smith']).OrderBy('Name').SelectFirst;
  110. user := TLinq<TUser>.From(users3).Where('Name = ?',['Peter']).SelectFirst;
  111. crono.Stop;
  112. if user <> nil then cout('Found by Linq: %s %s in %s',[user.Name,user.SurName,crono.ElapsedTime],etSuccess)
  113. else cout('Not found by Linq! (%s)',[crono.ElapsedTime],etError);
  114. //test search by Linq iteration (predicate)
  115. crono.Start;
  116. //user := TLinq.From<TUser>(users2).Where('(Name = ?) OR (SurName = ?)',['Anus','Smith']).OrderBy('Name').SelectFirst;
  117. user := TLinq<TUser>.From(users3).Where(function(aUser : TUser) : Boolean
  118. begin
  119. Result := aUser.Name = 'Peter';
  120. end).SelectFirst;
  121. crono.Stop;
  122. if user <> nil then cout('Found by Linq (predicate): %s %s in %s',[user.Name,user.SurName,crono.ElapsedTime],etSuccess)
  123. else cout('Not found by Linq! (%s)',[crono.ElapsedTime],etError);
  124. //test search by embeded iteration
  125. crono.Start;
  126. user := users2.Get('Name','Peter');
  127. crono.Stop;
  128. if user <> nil then cout('Found by Search: %s %s in %s',[user.Name,user.SurName,crono.ElapsedTime],etSuccess)
  129. else cout('Not found!',etError);
  130. //ConsoleWaitForEnterKey;
  131. cout('Multi results:',etInfo);
  132. //test search by normal iteration
  133. user := nil;
  134. n := 0;
  135. cout('Found by Iteration:',etInfo);
  136. for i := 0 to users.Count - 1 do
  137. begin
  138. //if ((users[i].Name = 'Anna') or (users[i].Age > 30)) or (users[i].SurName = 'Smith') then
  139. //if users[i].Age > 18 then
  140. if (users[i].Name = 'Anna') then
  141. begin
  142. Inc(n);
  143. user := users[i];
  144. cout('%d. %s %s',[n,user.Name,user.SurName],etSuccess)
  145. end;
  146. end;
  147. if user = nil then cout('Not found by Iteration!',etError);
  148. //test search by Linq iteration
  149. user := nil;
  150. n := 0;
  151. cout('Found by Linq:',etInfo);
  152. //TLinq<TUser>.From(users2).Where('Name Like ?',['p%']).Delete;
  153. TLinq<TUser>.From(users2).Where('Name = ?',['Peter']).Update(['Name'],['Poter']);
  154. //for user in TLinq<TUser>.From(users2).Where('(Name = ?) OR (SurName = ?) OR (SurName = ?)',['Peter','Smith','Huan']).Select do
  155. //for user in TLinq<TUser>.From(users2).Where('(Name = ?) OR (Age > ?) OR (SurName = ?)',['Anna',30,'Smith']).Select do
  156. //for user in TLinq<TUser>.From(users2).Where('Age > ?',[18]).Select do
  157. //for user in TLinq<TUser>.From(users2).Where('SurName Like ?',['%son']).Select do
  158. //for user in TLinq<TUser>.From(users2).Where('SurName Like ?',['p%']).Select do
  159. //for user in TLinq<TUser>.From(users2).Where('1 = 1',[]).Select do
  160. for user in TLinq<TUser>.From(users2).Where('(LoginInfo.UserName Like ?) OR (LoginInfo.UserName Like ?)',['p%','a%'])
  161. .OrderBy('Name')
  162. .Select do
  163. begin
  164. Inc(n);
  165. cout('Login.Username: %d. %s %s',[n,user.Name,user.SurName],etSuccess);
  166. end;
  167. if user = nil then cout('Not found by Linq!',etError);
  168. cout('Press a key to Exit',etInfo);
  169. Readln;
  170. users.Free;
  171. users2.Free;
  172. crono.Free;
  173. except
  174. on E: Exception do
  175. cout('%s : %s',[E.ClassName,E.Message],etError);
  176. end;
  177. end.