1.1 --- a/src/gazzera.lpi Tue Oct 13 15:53:54 2009 +0200
1.2 +++ b/src/gazzera.lpi Thu Oct 15 19:12:00 2009 +0200
1.3 @@ -12,7 +12,7 @@
1.4 </Flags>
1.5 <MainUnit Value="0"/>
1.6 <TargetFileExt Value=""/>
1.7 - <ActiveEditorIndexAtStart Value="8"/>
1.8 + <ActiveEditorIndexAtStart Value="1"/>
1.9 </General>
1.10 <PublishOptions>
1.11 <Version Value="2"/>
1.12 @@ -112,14 +112,12 @@
1.13 <UnitName Value="mainwindowunit"/>
1.14 <CursorPos X="35" Y="623"/>
1.15 <TopLine Value="601"/>
1.16 - <EditorIndex Value="13"/>
1.17 <UsageCount Value="62"/>
1.18 <Bookmarks Count="3">
1.19 <Item0 X="29" Y="86" ID="1"/>
1.20 <Item1 X="10" Y="407" ID="2"/>
1.21 <Item2 X="1" Y="270" ID="6"/>
1.22 </Bookmarks>
1.23 - <Loaded Value="True"/>
1.24 <SyntaxHighlighter Value="Delphi"/>
1.25 </Unit10>
1.26 <Unit11>
1.27 @@ -185,9 +183,9 @@
1.28 <Unit19>
1.29 <Filename Value="node\nodedatabaseunit.pas"/>
1.30 <UnitName Value="nodedatabaseunit"/>
1.31 - <CursorPos X="1" Y="115"/>
1.32 + <CursorPos X="31" Y="103"/>
1.33 <TopLine Value="92"/>
1.34 - <EditorIndex Value="15"/>
1.35 + <EditorIndex Value="3"/>
1.36 <UsageCount Value="63"/>
1.37 <Loaded Value="True"/>
1.38 <SyntaxHighlighter Value="Delphi"/>
1.39 @@ -197,9 +195,7 @@
1.40 <UnitName Value="peerunit"/>
1.41 <CursorPos X="63" Y="49"/>
1.42 <TopLine Value="25"/>
1.43 - <EditorIndex Value="2"/>
1.44 <UsageCount Value="29"/>
1.45 - <Loaded Value="True"/>
1.46 <SyntaxHighlighter Value="Delphi"/>
1.47 </Unit20>
1.48 <Unit21>
1.49 @@ -391,9 +387,7 @@
1.50 <UnitName Value="actionsunit"/>
1.51 <CursorPos X="67" Y="62"/>
1.52 <TopLine Value="60"/>
1.53 - <EditorIndex Value="14"/>
1.54 <UsageCount Value="32"/>
1.55 - <Loaded Value="True"/>
1.56 <SyntaxHighlighter Value="Delphi"/>
1.57 </Unit46>
1.58 <Unit47>
1.59 @@ -488,9 +482,9 @@
1.60 <Unit59>
1.61 <Filename Value="node\plugins\browsepluginunit.pas"/>
1.62 <UnitName Value="browsepluginunit"/>
1.63 - <CursorPos X="1" Y="138"/>
1.64 - <TopLine Value="117"/>
1.65 - <EditorIndex Value="12"/>
1.66 + <CursorPos X="112" Y="123"/>
1.67 + <TopLine Value="111"/>
1.68 + <EditorIndex Value="2"/>
1.69 <UsageCount Value="32"/>
1.70 <Loaded Value="True"/>
1.71 <SyntaxHighlighter Value="Delphi"/>
1.72 @@ -498,11 +492,9 @@
1.73 <Unit60>
1.74 <Filename Value="ultimatesockets\normalsocketunit.pas"/>
1.75 <UnitName Value="normalsocketunit"/>
1.76 - <CursorPos X="47" Y="57"/>
1.77 + <CursorPos X="29" Y="39"/>
1.78 <TopLine Value="35"/>
1.79 - <EditorIndex Value="8"/>
1.80 <UsageCount Value="67"/>
1.81 - <Loaded Value="True"/>
1.82 <SyntaxHighlighter Value="Delphi"/>
1.83 </Unit60>
1.84 <Unit61>
1.85 @@ -572,9 +564,7 @@
1.86 <UnitName Value="mainunit"/>
1.87 <CursorPos X="22" Y="87"/>
1.88 <TopLine Value="76"/>
1.89 - <EditorIndex Value="1"/>
1.90 <UsageCount Value="53"/>
1.91 - <Loaded Value="True"/>
1.92 <SyntaxHighlighter Value="Delphi"/>
1.93 </Unit69>
1.94 <Unit70>
1.95 @@ -594,9 +584,7 @@
1.96 <UnitName Value="messagesunit"/>
1.97 <CursorPos X="46" Y="937"/>
1.98 <TopLine Value="911"/>
1.99 - <EditorIndex Value="11"/>
1.100 <UsageCount Value="71"/>
1.101 - <Loaded Value="True"/>
1.102 <SyntaxHighlighter Value="Delphi"/>
1.103 </Unit72>
1.104 <Unit73>
1.105 @@ -630,9 +618,7 @@
1.106 <UnitName Value="socketunit"/>
1.107 <CursorPos X="61" Y="373"/>
1.108 <TopLine Value="349"/>
1.109 - <EditorIndex Value="10"/>
1.110 <UsageCount Value="44"/>
1.111 - <Loaded Value="True"/>
1.112 <SyntaxHighlighter Value="Delphi"/>
1.113 </Unit77>
1.114 <Unit78>
1.115 @@ -671,9 +657,7 @@
1.116 <UnitName Value="grouppluginunit"/>
1.117 <CursorPos X="1" Y="80"/>
1.118 <TopLine Value="59"/>
1.119 - <EditorIndex Value="6"/>
1.120 <UsageCount Value="13"/>
1.121 - <Loaded Value="True"/>
1.122 <SyntaxHighlighter Value="Delphi"/>
1.123 </Unit82>
1.124 <Unit83>
1.125 @@ -689,9 +673,7 @@
1.126 <UnitName Value="friendpluginunit"/>
1.127 <CursorPos X="1" Y="232"/>
1.128 <TopLine Value="217"/>
1.129 - <EditorIndex Value="3"/>
1.130 <UsageCount Value="40"/>
1.131 - <Loaded Value="True"/>
1.132 <SyntaxHighlighter Value="Delphi"/>
1.133 </Unit84>
1.134 <Unit85>
1.135 @@ -739,9 +721,7 @@
1.136 <UnitName Value="pluginmanagerunit"/>
1.137 <CursorPos X="90" Y="113"/>
1.138 <TopLine Value="104"/>
1.139 - <EditorIndex Value="9"/>
1.140 <UsageCount Value="52"/>
1.141 - <Loaded Value="True"/>
1.142 <SyntaxHighlighter Value="Delphi"/>
1.143 </Unit90>
1.144 <Unit91>
1.145 @@ -804,9 +784,7 @@
1.146 <UnitName Value="sharemanagerunit"/>
1.147 <CursorPos X="1" Y="194"/>
1.148 <TopLine Value="173"/>
1.149 - <EditorIndex Value="4"/>
1.150 <UsageCount Value="46"/>
1.151 - <Loaded Value="True"/>
1.152 <SyntaxHighlighter Value="Delphi"/>
1.153 </Unit98>
1.154 <Unit99>
1.155 @@ -932,9 +910,11 @@
1.156 <Unit117>
1.157 <Filename Value="node\plugins\searchpluginunit.pas"/>
1.158 <UnitName Value="searchpluginunit"/>
1.159 - <CursorPos X="1" Y="80"/>
1.160 - <TopLine Value="66"/>
1.161 + <CursorPos X="1" Y="154"/>
1.162 + <TopLine Value="132"/>
1.163 + <EditorIndex Value="1"/>
1.164 <UsageCount Value="22"/>
1.165 + <Loaded Value="True"/>
1.166 <SyntaxHighlighter Value="Delphi"/>
1.167 </Unit117>
1.168 <Unit118>
1.169 @@ -983,9 +963,7 @@
1.170 <UnitName Value="downloadpluginunit"/>
1.171 <CursorPos X="106" Y="171"/>
1.172 <TopLine Value="156"/>
1.173 - <EditorIndex Value="16"/>
1.174 <UsageCount Value="38"/>
1.175 - <Loaded Value="True"/>
1.176 <SyntaxHighlighter Value="Delphi"/>
1.177 </Unit124>
1.178 <Unit125>
1.179 @@ -1222,9 +1200,7 @@
1.180 <UnitName Value="modelunit"/>
1.181 <CursorPos X="22" Y="30"/>
1.182 <TopLine Value="1"/>
1.183 - <EditorIndex Value="7"/>
1.184 <UsageCount Value="17"/>
1.185 - <Loaded Value="True"/>
1.186 <SyntaxHighlighter Value="Delphi"/>
1.187 </Unit158>
1.188 <Unit159>
1.189 @@ -1892,133 +1868,15 @@
1.190 <UnitName Value="sharedpanelunit"/>
1.191 <CursorPos X="11" Y="9"/>
1.192 <TopLine Value="1"/>
1.193 - <EditorIndex Value="5"/>
1.194 <UsageCount Value="10"/>
1.195 - <Loaded Value="True"/>
1.196 <SyntaxHighlighter Value="Delphi"/>
1.197 </Unit250>
1.198 </Units>
1.199 - <JumpHistory Count="30" HistoryIndex="29">
1.200 + <JumpHistory Count="1" HistoryIndex="0">
1.201 <Position1>
1.202 - <Filename Value="ultimatesockets\normalsocketunit.pas"/>
1.203 - <Caret Line="62" Column="58" TopLine="35"/>
1.204 - </Position1>
1.205 - <Position2>
1.206 - <Filename Value="ultimatesockets\normalsocketunit.pas"/>
1.207 - <Caret Line="60" Column="58" TopLine="35"/>
1.208 - </Position2>
1.209 - <Position3>
1.210 - <Filename Value="gui\mainwindowunit.pas"/>
1.211 - <Caret Line="416" Column="9" TopLine="409"/>
1.212 - </Position3>
1.213 - <Position4>
1.214 - <Filename Value="gui\mainwindowunit.pas"/>
1.215 - <Caret Line="632" Column="16" TopLine="604"/>
1.216 - </Position4>
1.217 - <Position5>
1.218 - <Filename Value="gui\actionsunit.pas"/>
1.219 - <Caret Line="20" Column="45" TopLine="16"/>
1.220 - </Position5>
1.221 - <Position6>
1.222 - <Filename Value="gui\mainwindowunit.pas"/>
1.223 - <Caret Line="632" Column="16" TopLine="604"/>
1.224 - </Position6>
1.225 - <Position7>
1.226 - <Filename Value="gui\mainwindowunit.pas"/>
1.227 - <Caret Line="623" Column="35" TopLine="601"/>
1.228 - </Position7>
1.229 - <Position8>
1.230 - <Filename Value="gui\actionsunit.pas"/>
1.231 - <Caret Line="64" Column="1" TopLine="22"/>
1.232 - </Position8>
1.233 - <Position9>
1.234 - <Filename Value="node\nodedatabaseunit.pas"/>
1.235 - <Caret Line="31" Column="5" TopLine="20"/>
1.236 - </Position9>
1.237 - <Position10>
1.238 <Filename Value="gazzera.pas"/>
1.239 <Caret Line="93" Column="12" TopLine="58"/>
1.240 - </Position10>
1.241 - <Position11>
1.242 - <Filename Value="node\mainunit.pas"/>
1.243 - <Caret Line="87" Column="22" TopLine="76"/>
1.244 - </Position11>
1.245 - <Position12>
1.246 - <Filename Value="node\nodedatabaseunit.pas"/>
1.247 - <Caret Line="8" Column="10" TopLine="1"/>
1.248 - </Position12>
1.249 - <Position13>
1.250 - <Filename Value="node\nodedatabaseunit.pas"/>
1.251 - <Caret Line="110" Column="14" TopLine="88"/>
1.252 - </Position13>
1.253 - <Position14>
1.254 - <Filename Value="node\nodedatabaseunit.pas"/>
1.255 - <Caret Line="105" Column="1" TopLine="84"/>
1.256 - </Position14>
1.257 - <Position15>
1.258 - <Filename Value="node\nodedatabaseunit.pas"/>
1.259 - <Caret Line="108" Column="1" TopLine="87"/>
1.260 - </Position15>
1.261 - <Position16>
1.262 - <Filename Value="node\nodedatabaseunit.pas"/>
1.263 - <Caret Line="109" Column="1" TopLine="88"/>
1.264 - </Position16>
1.265 - <Position17>
1.266 - <Filename Value="node\nodedatabaseunit.pas"/>
1.267 - <Caret Line="110" Column="1" TopLine="89"/>
1.268 - </Position17>
1.269 - <Position18>
1.270 - <Filename Value="node\nodedatabaseunit.pas"/>
1.271 - <Caret Line="108" Column="1" TopLine="87"/>
1.272 - </Position18>
1.273 - <Position19>
1.274 - <Filename Value="node\nodedatabaseunit.pas"/>
1.275 - <Caret Line="109" Column="1" TopLine="88"/>
1.276 - </Position19>
1.277 - <Position20>
1.278 - <Filename Value="node\nodedatabaseunit.pas"/>
1.279 - <Caret Line="110" Column="1" TopLine="89"/>
1.280 - </Position20>
1.281 - <Position21>
1.282 - <Filename Value="node\nodedatabaseunit.pas"/>
1.283 - <Caret Line="108" Column="1" TopLine="87"/>
1.284 - </Position21>
1.285 - <Position22>
1.286 - <Filename Value="node\nodedatabaseunit.pas"/>
1.287 - <Caret Line="109" Column="1" TopLine="88"/>
1.288 - </Position22>
1.289 - <Position23>
1.290 - <Filename Value="node\nodedatabaseunit.pas"/>
1.291 - <Caret Line="112" Column="1" TopLine="91"/>
1.292 - </Position23>
1.293 - <Position24>
1.294 - <Filename Value="node\nodedatabaseunit.pas"/>
1.295 - <Caret Line="115" Column="1" TopLine="92"/>
1.296 - </Position24>
1.297 - <Position25>
1.298 - <Filename Value="node\plugins\grouppluginunit.pas"/>
1.299 - <Caret Line="100" Column="1" TopLine="79"/>
1.300 - </Position25>
1.301 - <Position26>
1.302 - <Filename Value="ultimatesockets\normalsocketunit.pas"/>
1.303 - <Caret Line="59" Column="59" TopLine="35"/>
1.304 - </Position26>
1.305 - <Position27>
1.306 - <Filename Value="node\plugins\grouppluginunit.pas"/>
1.307 - <Caret Line="64" Column="1" TopLine="43"/>
1.308 - </Position27>
1.309 - <Position28>
1.310 - <Filename Value="ultimatesockets\normalsocketunit.pas"/>
1.311 - <Caret Line="56" Column="1" TopLine="35"/>
1.312 - </Position28>
1.313 - <Position29>
1.314 - <Filename Value="node\plugins\grouppluginunit.pas"/>
1.315 - <Caret Line="80" Column="1" TopLine="59"/>
1.316 - </Position29>
1.317 - <Position30>
1.318 - <Filename Value="ultimatesockets\normalsocketunit.pas"/>
1.319 - <Caret Line="54" Column="13" TopLine="35"/>
1.320 - </Position30>
1.321 + </Position1>
1.322 </JumpHistory>
1.323 </ProjectOptions>
1.324 <CompilerOptions>
2.1 --- a/src/node/plugins/searchpluginunit.pas Tue Oct 13 15:53:54 2009 +0200
2.2 +++ b/src/node/plugins/searchpluginunit.pas Thu Oct 15 19:12:00 2009 +0200
2.3 @@ -1,170 +1,184 @@
2.4 -unit searchpluginunit;
2.5 -{$H+}
2.6 -
2.7 -interface
2.8 -uses Classes, SysUtils, pluginunit, peerunit, messagesunit, logunit,
2.9 - interfacemessageunit, Types, controllercommandsunit, propertiesunit, dateutils,
2.10 - dictionaryunit, databaseunit, nodedatabaseunit, msxstrings;
2.11 -
2.12 -type
2.13 -
2.14 -TActiveSearch = class
2.15 - searchId: integer;
2.16 - gid: string;
2.17 - started: TDateTime;
2.18 -end;
2.19 -
2.20 -TSearchPlugin = class(TPlugin)
2.21 - private
2.22 - activeSearches: TDictionary;
2.23 - procedure readFileSearch(m:TMsgFileSearch);
2.24 - procedure readFileSearchReply(m:TMsgFileSearchReply);
2.25 - procedure everyFiveSeconds;
2.26 - procedure commandStartFileSearch(m:TMsgCommandStartFileSearch);
2.27 - protected
2.28 - function getName: string; override;
2.29 - public
2.30 - procedure Initialize; override;
2.31 - procedure Finalize; override;
2.32 - procedure OnMessage(m:TMessage); override;
2.33 -end;
2.34 -
2.35 -
2.36 -implementation
2.37 -uses objectsunit;
2.38 -
2.39 -function TSearchPlugin.getName: string;
2.40 -begin
2.41 - result := 'Search Plugin';
2.42 -end;
2.43 -
2.44 -procedure TSearchPlugin.Initialize;
2.45 -begin
2.46 - log(llInfo, 'Initialize');
2.47 - registerMessageType(mtFileSearch);
2.48 - registerMessageType(mtFileSearchReply);
2.49 - registerMessageType(mtCommandStartFileSearch);
2.50 - registerMessageType(mtMetaFiveSeconds);
2.51 - activeSearches := TDictionary.create;
2.52 -end;
2.53 -
2.54 -procedure TSearchPlugin.Finalize;
2.55 -begin
2.56 - log(llInfo, 'Finalize');
2.57 - activeSearches.free;
2.58 -end;
2.59 -
2.60 -procedure TSearchPlugin.OnMessage(m:TMessage);
2.61 -begin
2.62 - case m.msgType of
2.63 - mtFileSearch: readFileSearch(TMsgFileSearch(m));
2.64 - mtFileSearchReply: readFileSearchReply(TMsgFileSearchReply(m));
2.65 - mtCommandStartFileSearch: commandStartFileSearch(TMsgCommandStartFileSearch(m));
2.66 - mtMetaFiveSeconds: everyFiveSeconds;
2.67 - end;
2.68 -end;
2.69 -
2.70 -procedure TSearchPlugin.everyFiveSeconds;
2.71 -var
2.72 - i: integer;
2.73 - a: TActiveSearch;
2.74 -begin
2.75 - for i := activeSearches.count-1 downto 0 do
2.76 - begin
2.77 - a := activeSearches[activeSearches.byIndex(i)] as TActiveSearch;
2.78 - if (a.started + (OneMinute*2)) < now() then
2.79 - begin
2.80 - log(llInfo, 'Removing a search that timed out ' + activeSearches.byIndex(i));
2.81 - activeSearches.remove(activeSearches.byIndex(i));
2.82 - end;
2.83 - end;
2.84 -end;
2.85 -
2.86 -procedure TSearchPlugin.commandStartFileSearch(m:TMsgCommandStartFileSearch);
2.87 -var
2.88 - n, i: integer;
2.89 - peers: TStringList;
2.90 - q: TMsgFileSearch;
2.91 - s: TActiveSearch;
2.92 -begin
2.93 - repeat
2.94 - n := Random(maxLongint);
2.95 - until activeSearches[inttostr(n)] = nil;
2.96 - s := TActiveSearch.Create;
2.97 - s.searchId := n;
2.98 - s.started := now();
2.99 - activeSearches[inttostr(n)] := s; // TODO this is never released!!
2.100 - for i:=0 to PluginManager.PeerList.count-1 do
2.101 - PluginManager.PeerList.get(i).enqueue(TMsgFileSearch.create(n, m.keywords, m.min, m.max));
2.102 - Notifier.postToController(TMsgCommandNewFileSearch.Create(n, m.keywords));
2.103 -end;
2.104 -
2.105 -procedure TSearchPlugin.readFileSearch(m:TMsgFileSearch);
2.106 -var
2.107 - rs: TResultSet;
2.108 - i: integer;
2.109 - kw: TStringDynArray;
2.110 - q: string;
2.111 -begin
2.112 - log(llDebug, 'Received FileSearch');
2.113 - q := ' where ok = 1 ';
2.114 - kw := SeparateString(m.keywords, ' ');
2.115 - for i:=0 to length(kw)-1 do
2.116 - begin
2.117 - kw[i] := '%'+kw[i]+'%';
2.118 - q := q + 'and (filename like ?)';
2.119 - end;
2.120 -
2.121 - if m.minSize > 0 then
2.122 - begin
2.123 - setlength(kw, length(kw) + 1);
2.124 - kw[length(kw)-1] := inttostr((int64(m.minsize) * int64(1024*1024)));
2.125 - q := q + ' and (size >= ?)';
2.126 - end;
2.127 - if m.maxSize > 0 then
2.128 - begin
2.129 - setlength(kw, length(kw)+1);
2.130 - kw[length(kw)-1] := inttostr((int64(m.maxsize) * int64(1024*1024)));
2.131 - q := q + ' and (size <= ?)';
2.132 - end;
2.133 -
2.134 - (* use this one instead:
2.135 -
2.136 - select filename, hash, size from (
2.137 - select 1 x,* from files where filename like '%m%' and size < 1000 and size > 400
2.138 - union
2.139 - select 2 x,* from files where virtualpath like '%m%' and size < 1000 and size > 400
2.140 - ) order by x asc limit 100
2.141 - *)
2.142 -
2.143 - q := 'select filename, hash, size from files ' + q + ' limit 100';
2.144 - log(llInfo, 'Search query: ' + q);
2.145 - rs := Database.executeQuery(q, kw);
2.146 - try
2.147 - while rs.next do
2.148 - begin
2.149 - log(llDebug, 'Sending a result');
2.150 - m.peer.enqueue(TMsgFileSearchReply.Create(m.searchid, rs[0], rs[1], strtoint64(rs[2])));
2.151 - end;
2.152 - log(llDebug, 'finished sending results');
2.153 - finally
2.154 - log(llDebug, 'closing resultset');
2.155 - rs.Free;
2.156 - end;
2.157 -end;
2.158 -
2.159 -procedure TSearchPlugin.readFileSearchReply(m:TMsgFileSearchReply);
2.160 -var s: TActiveSearch;
2.161 -begin
2.162 - log(llDebug, 'Received FileSearchReply');
2.163 - log(llDebug, m.name + ' ' + inttostr(m.size) + ' ' +m.hash);
2.164 - s := activeSearches[inttostr(m.searchId)] as TActiveSearch;
2.165 - if s = nil then
2.166 - log(llWarning, 'Received reply summary without search.. timeout?')
2.167 - else
2.168 - notifier.postToController(TMsgCommandFileSearchReply.Create(m.searchId,
2.169 - m.peer.gid, m.name, m.hash, m.size));
2.170 -end;
2.171 -
2.172 -
2.173 -end.
2.174 +unit searchpluginunit;
2.175 +{$H+}
2.176 +
2.177 +interface
2.178 +uses Classes, SysUtils, pluginunit, peerunit, messagesunit, logunit,
2.179 + interfacemessageunit, Types, controllercommandsunit, propertiesunit, dateutils,
2.180 + dictionaryunit, databaseunit, nodedatabaseunit, msxstrings;
2.181 +
2.182 +type
2.183 +
2.184 +TActiveSearch = class
2.185 + searchId: integer;
2.186 + gid: string;
2.187 + started: TDateTime;
2.188 +end;
2.189 +
2.190 +TSearchPlugin = class(TPlugin)
2.191 + private
2.192 + activeSearches: TDictionary;
2.193 + procedure readFileSearch(m:TMsgFileSearch);
2.194 + procedure readFileSearchReply(m:TMsgFileSearchReply);
2.195 + procedure everyFiveSeconds;
2.196 + procedure commandStartFileSearch(m:TMsgCommandStartFileSearch);
2.197 + protected
2.198 + function getName: string; override;
2.199 + public
2.200 + procedure Initialize; override;
2.201 + procedure Finalize; override;
2.202 + procedure OnMessage(m:TMessage); override;
2.203 +end;
2.204 +
2.205 +
2.206 +implementation
2.207 +uses objectsunit;
2.208 +
2.209 +function TSearchPlugin.getName: string;
2.210 +begin
2.211 + result := 'Search Plugin';
2.212 +end;
2.213 +
2.214 +procedure TSearchPlugin.Initialize;
2.215 +begin
2.216 + log(llInfo, 'Initialize');
2.217 + registerMessageType(mtFileSearch);
2.218 + registerMessageType(mtFileSearchReply);
2.219 + registerMessageType(mtCommandStartFileSearch);
2.220 + registerMessageType(mtMetaFiveSeconds);
2.221 + activeSearches := TDictionary.create;
2.222 +end;
2.223 +
2.224 +procedure TSearchPlugin.Finalize;
2.225 +begin
2.226 + log(llInfo, 'Finalize');
2.227 + activeSearches.free;
2.228 +end;
2.229 +
2.230 +procedure TSearchPlugin.OnMessage(m:TMessage);
2.231 +begin
2.232 + case m.msgType of
2.233 + mtFileSearch: readFileSearch(TMsgFileSearch(m));
2.234 + mtFileSearchReply: readFileSearchReply(TMsgFileSearchReply(m));
2.235 + mtCommandStartFileSearch: commandStartFileSearch(TMsgCommandStartFileSearch(m));
2.236 + mtMetaFiveSeconds: everyFiveSeconds;
2.237 + end;
2.238 +end;
2.239 +
2.240 +procedure TSearchPlugin.everyFiveSeconds;
2.241 +var
2.242 + i: integer;
2.243 + a: TActiveSearch;
2.244 +begin
2.245 + for i := activeSearches.count-1 downto 0 do
2.246 + begin
2.247 + a := activeSearches[activeSearches.byIndex(i)] as TActiveSearch;
2.248 + if (a.started + (OneMinute*2)) < now() then
2.249 + begin
2.250 + log(llInfo, 'Removing a search that timed out ' + activeSearches.byIndex(i));
2.251 + activeSearches.remove(activeSearches.byIndex(i));
2.252 + end;
2.253 + end;
2.254 +end;
2.255 +
2.256 +procedure TSearchPlugin.commandStartFileSearch(m:TMsgCommandStartFileSearch);
2.257 +var
2.258 + n, i: integer;
2.259 + peers: TStringList;
2.260 + q: TMsgFileSearch;
2.261 + s: TActiveSearch;
2.262 +begin
2.263 + repeat
2.264 + n := Random(maxLongint);
2.265 + until activeSearches[inttostr(n)] = nil;
2.266 + s := TActiveSearch.Create;
2.267 + s.searchId := n;
2.268 + s.started := now();
2.269 + activeSearches[inttostr(n)] := s; // TODO this is never released!!
2.270 + for i:=0 to PluginManager.PeerList.count-1 do
2.271 + PluginManager.PeerList.get(i).enqueue(TMsgFileSearch.create(n, m.keywords, m.min, m.max));
2.272 + Notifier.postToController(TMsgCommandNewFileSearch.Create(n, m.keywords));
2.273 +end;
2.274 +
2.275 +procedure TSearchPlugin.readFileSearch(m:TMsgFileSearch);
2.276 +var
2.277 + rs: TResultSet;
2.278 + i: integer;
2.279 + kw: TStringDynArray;
2.280 + q: string;
2.281 +begin
2.282 + log(llDebug, 'Received FileSearch');
2.283 + q := ' where ok = 1 ';
2.284 + kw := SeparateString(m.keywords, ' ');
2.285 + for i:=0 to length(kw)-1 do
2.286 + begin
2.287 + kw[i] := '%'+kw[i]+'%';
2.288 + q := q + 'and (filename like ?)';
2.289 + end;
2.290 +
2.291 + if m.minSize > 0 then
2.292 + begin
2.293 + setlength(kw, length(kw) + 1);
2.294 + kw[length(kw)-1] := inttostr((int64(m.minsize) * int64(1024*1024)));
2.295 + q := q + ' and (size >= ?)';
2.296 + end;
2.297 + if m.maxSize > 0 then
2.298 + begin
2.299 + setlength(kw, length(kw)+1);
2.300 + kw[length(kw)-1] := inttostr((int64(m.maxsize) * int64(1024*1024)));
2.301 + q := q + ' and (size <= ?)';
2.302 + end;
2.303 +
2.304 + (* use this one instead:
2.305 +
2.306 + select filename, hash, size from (
2.307 + select 1 x,* from files where filename like '%m%' and size < 1000 and size > 400
2.308 + union
2.309 + select 2 x,* from files where virtualpath like '%m%' and size < 1000 and size > 400
2.310 + ) order by x asc limit 100
2.311 + *)
2.312 +
2.313 + (*
2.314 + with groups:
2.315 +
2.316 +select f.filename, f.hash, f.size from shares_visible_per_user s, paths p, files f where f.virtualPath = p.name and p.shareId = s.shareId
2.317 +
2.318 + *)
2.319 +
2.320 + // add GID to query
2.321 + setlength(kw, length(kw)+1);
2.322 + kw[length(kw)-1] := m.peer.gid;
2.323 + q := q + ' and (s.gid = ?)';
2.324 +
2.325 +
2.326 +
2.327 + q := 'select f.filename, f.hash, f.size from shares_visible_per_user s, paths p, files f where f.virtualPath = p.name and p.shareId = s.shareId ' + q + ' limit 100';
2.328 + log(llInfo, 'Search query: ' + q);
2.329 + rs := Database.executeQuery(q, kw);
2.330 + try
2.331 + while rs.next do
2.332 + begin
2.333 + log(llDebug, 'Sending a result');
2.334 + m.peer.enqueue(TMsgFileSearchReply.Create(m.searchid, rs[0], rs[1], strtoint64(rs[2])));
2.335 + end;
2.336 + log(llDebug, 'finished sending results');
2.337 + finally
2.338 + log(llDebug, 'closing resultset');
2.339 + rs.Free;
2.340 + end;
2.341 +end;
2.342 +
2.343 +procedure TSearchPlugin.readFileSearchReply(m:TMsgFileSearchReply);
2.344 +var s: TActiveSearch;
2.345 +begin
2.346 + log(llDebug, 'Received FileSearchReply');
2.347 + log(llDebug, m.name + ' ' + inttostr(m.size) + ' ' +m.hash);
2.348 + s := activeSearches[inttostr(m.searchId)] as TActiveSearch;
2.349 + if s = nil then
2.350 + log(llWarning, 'Received reply summary without search.. timeout?')
2.351 + else
2.352 + notifier.postToController(TMsgCommandFileSearchReply.Create(m.searchId,
2.353 + m.peer.gid, m.name, m.hash, m.size));
2.354 +end;
2.355 +
2.356 +
2.357 +end.