2
0

LinqList.dpr 6.7 KB

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