← Index
NYTProf Performance Profile   « block view • line view • sub view »
For /usr/local/src/github.com/foswiki/core/bin/view
  Run on Sun Dec 4 17:17:59 2011
Reported on Sun Dec 4 17:26:58 2011

Filename/usr/local/src/github.com/foswiki/core/lib/Foswiki/Store/Interfaces/QueryAlgorithm.pm
StatementsExecuted 280 statements in 6.82ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
1113.26ms3.53msFoswiki::Store::Interfaces::QueryAlgorithm::::BEGIN@17Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@17
22111.35ms1.64sFoswiki::Store::Interfaces::QueryAlgorithm::::__ANON__[:187]Foswiki::Store::Interfaces::QueryAlgorithm::__ANON__[:187]
111677µs811µsFoswiki::Store::Interfaces::QueryAlgorithm::::BEGIN@20Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@20
111615µs1.30msFoswiki::Store::Interfaces::QueryAlgorithm::::BEGIN@9Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@9
111472µs648µsFoswiki::Store::Interfaces::QueryAlgorithm::::BEGIN@8Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@8
111218µs1.65sFoswiki::Store::Interfaces::QueryAlgorithm::::queryFoswiki::Store::Interfaces::QueryAlgorithm::query
11191µs262µsFoswiki::Store::Interfaces::QueryAlgorithm::::getListOfWebsFoswiki::Store::Interfaces::QueryAlgorithm::getListOfWebs
11179µs627µsFoswiki::Store::Interfaces::QueryAlgorithm::::getWebIteratorFoswiki::Store::Interfaces::QueryAlgorithm::getWebIterator
11155µs567µsFoswiki::Store::Interfaces::QueryAlgorithm::::__ANON__[:228]Foswiki::Store::Interfaces::QueryAlgorithm::__ANON__[:228]
11141µs1.65sFoswiki::Store::Interfaces::QueryAlgorithm::::__ANON__[:109]Foswiki::Store::Interfaces::QueryAlgorithm::__ANON__[:109]
11132µs75µsFoswiki::Store::Interfaces::QueryAlgorithm::::addACLFilterFoswiki::Store::Interfaces::QueryAlgorithm::addACLFilter
11131µs129µsFoswiki::Store::Interfaces::QueryAlgorithm::::BEGIN@342Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@342
11129µs107µsFoswiki::Store::Interfaces::QueryAlgorithm::::BEGIN@6Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@6
11128µs35µsFoswiki::Store::Interfaces::QueryAlgorithm::::BEGIN@4Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@4
11121µs38µsFoswiki::Store::Interfaces::QueryAlgorithm::::BEGIN@5Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@5
11119µs19µsFoswiki::Store::Interfaces::QueryAlgorithm::::newFoswiki::Store::Interfaces::QueryAlgorithm::new
11116µs119µsFoswiki::Store::Interfaces::QueryAlgorithm::::BEGIN@23Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@23
11111µs11µsFoswiki::Store::Interfaces::QueryAlgorithm::::BEGIN@18Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@18
11111µs11µsFoswiki::Store::Interfaces::QueryAlgorithm::::BEGIN@11Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@11
11110µs10µsFoswiki::Store::Interfaces::QueryAlgorithm::::addPagerFoswiki::Store::Interfaces::QueryAlgorithm::addPager
11110µs10µsFoswiki::Store::Interfaces::QueryAlgorithm::::BEGIN@10Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@10
11110µs10µsFoswiki::Store::Interfaces::QueryAlgorithm::::BEGIN@21Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@21
11110µs10µsFoswiki::Store::Interfaces::QueryAlgorithm::::BEGIN@19Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@19
11110µs10µsFoswiki::Store::Interfaces::QueryAlgorithm::::BEGIN@15Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@15
1119µs9µsFoswiki::Store::Interfaces::QueryAlgorithm::::BEGIN@13Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@13
1119µs9µsFoswiki::Store::Interfaces::QueryAlgorithm::::BEGIN@14Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@14
1119µs9µsFoswiki::Store::Interfaces::QueryAlgorithm::::BEGIN@16Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@16
1119µs9µsFoswiki::Store::Interfaces::QueryAlgorithm::::BEGIN@12Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@12
2217µs7µsFoswiki::Store::Interfaces::QueryAlgorithm::::CORE:matchFoswiki::Store::Interfaces::QueryAlgorithm::CORE:match (opcode)
1115µs5µsFoswiki::Store::Interfaces::QueryAlgorithm::::CORE:sortFoswiki::Store::Interfaces::QueryAlgorithm::CORE:sort (opcode)
2214µs4µsFoswiki::Store::Interfaces::QueryAlgorithm::::CORE:substFoswiki::Store::Interfaces::QueryAlgorithm::CORE:subst (opcode)
0000s0sFoswiki::Store::Interfaces::QueryAlgorithm::::getFieldFoswiki::Store::Interfaces::QueryAlgorithm::getField
0000s0sFoswiki::Store::Interfaces::QueryAlgorithm::::getFormFoswiki::Store::Interfaces::QueryAlgorithm::getForm
0000s0sFoswiki::Store::Interfaces::QueryAlgorithm::::getRefTopicFoswiki::Store::Interfaces::QueryAlgorithm::getRefTopic
0000s0sFoswiki::Store::Interfaces::QueryAlgorithm::::getRev1InfoFoswiki::Store::Interfaces::QueryAlgorithm::getRev1Info
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1# See bottom of file for license and copyright information
2package Foswiki::Store::Interfaces::QueryAlgorithm;
3
4248µs242µs
# spent 35µs (28+7) within Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@4 which was called: # once (28µs+7µs) by Foswiki::Store::QueryAlgorithms::BruteForce::BEGIN@29 at line 4
use strict;
# spent 35µs making 1 call to Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@4 # spent 7µs making 1 call to strict::import
5245µs256µs
# spent 38µs (21+17) within Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@5 which was called: # once (21µs+17µs) by Foswiki::Store::QueryAlgorithms::BruteForce::BEGIN@29 at line 5
use warnings;
# spent 38µs making 1 call to Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@5 # spent 18µs making 1 call to warnings::import
6258µs2184µs
# spent 107µs (29+77) within Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@6 which was called: # once (29µs+77µs) by Foswiki::Store::QueryAlgorithms::BruteForce::BEGIN@29 at line 6
use Assert;
# spent 107µs making 1 call to Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@6 # spent 77µs making 1 call to Assert::import
7
82157µs1648µs
# spent 648µs (472+175) within Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@8 which was called: # once (472µs+175µs) by Foswiki::Store::QueryAlgorithms::BruteForce::BEGIN@29 at line 8
use Foswiki::Store::Interfaces::SearchAlgorithm ();
92159µs11.30ms
# spent 1.30ms (615µs+688µs) within Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@9 which was called: # once (615µs+688µs) by Foswiki::Store::QueryAlgorithms::BruteForce::BEGIN@29 at line 9
use Foswiki::Search::Node ();
10243µs110µs
# spent 10µs within Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@10 which was called: # once (10µs+0s) by Foswiki::Store::QueryAlgorithms::BruteForce::BEGIN@29 at line 10
use Foswiki::Search::InfoCache ();
11244µs111µs
# spent 11µs within Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@11 which was called: # once (11µs+0s) by Foswiki::Store::QueryAlgorithms::BruteForce::BEGIN@29 at line 11
use Foswiki::Search::ResultSet ();
12241µs19µs
# spent 9µs within Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@12 which was called: # once (9µs+0s) by Foswiki::Store::QueryAlgorithms::BruteForce::BEGIN@29 at line 12
use Foswiki();
13241µs19µs
# spent 9µs within Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@13 which was called: # once (9µs+0s) by Foswiki::Store::QueryAlgorithms::BruteForce::BEGIN@29 at line 13
use Foswiki::Func();
14241µs19µs
# spent 9µs within Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@14 which was called: # once (9µs+0s) by Foswiki::Store::QueryAlgorithms::BruteForce::BEGIN@29 at line 14
use Foswiki::Meta ();
15241µs110µs
# spent 10µs within Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@15 which was called: # once (10µs+0s) by Foswiki::Store::QueryAlgorithms::BruteForce::BEGIN@29 at line 15
use Foswiki::MetaCache ();
16241µs19µs
# spent 9µs within Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@16 which was called: # once (9µs+0s) by Foswiki::Store::QueryAlgorithms::BruteForce::BEGIN@29 at line 16
use Foswiki::Query::Node ();
172201µs13.53ms
# spent 3.53ms (3.26+278µs) within Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@17 which was called: # once (3.26ms+278µs) by Foswiki::Store::QueryAlgorithms::BruteForce::BEGIN@29 at line 17
use Foswiki::Query::HoistREs ();
18242µs111µs
# spent 11µs within Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@18 which was called: # once (11µs+0s) by Foswiki::Store::QueryAlgorithms::BruteForce::BEGIN@29 at line 18
use Foswiki::ListIterator();
19241µs110µs
# spent 10µs within Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@19 which was called: # once (10µs+0s) by Foswiki::Store::QueryAlgorithms::BruteForce::BEGIN@29 at line 19
use Foswiki::Iterator::FilterIterator();
202157µs1811µs
# spent 811µs (677+135) within Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@20 which was called: # once (677µs+135µs) by Foswiki::Store::QueryAlgorithms::BruteForce::BEGIN@29 at line 20
use Foswiki::Iterator::ProcessIterator();
21248µs110µs
# spent 10µs within Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@21 which was called: # once (10µs+0s) by Foswiki::Store::QueryAlgorithms::BruteForce::BEGIN@29 at line 21
use Foswiki::Iterator::PagerIterator();
22
2321.97ms2221µs
# spent 119µs (16+102) within Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@23 which was called: # once (16µs+102µs) by Foswiki::Store::QueryAlgorithms::BruteForce::BEGIN@29 at line 23
use constant MONITOR => 0;
# spent 119µs making 1 call to Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@23 # spent 102µs making 1 call to constant::import
24
25=begin TML
26
27---+ package Foswiki::Store::Interfaces::QueryAlgorithm
28
29Interface to query algorithms.
30Implementations of this interface are found in Foswiki/Store/*Algorithms.
31
32The contract with query algorithms is specified by this interface description,
33plus the 'query' unit tests in Fn_SEARCH.
34The interface provides a default implementation of the 'getField' method,
35but all other methods are pure virtual and must be provided by subclasses.
36Note that if a subclass re-implements getField, then there is no direct
37need to inherit from this class (as long as all the methods are implemented).
38
39=cut
40
41=begin TML
42
43---++ ClassMethod new( $class, ) -> $cereal
44
45=cut
46
47
# spent 19µs within Foswiki::Store::Interfaces::QueryAlgorithm::new which was called: # once (19µs+0s) by Foswiki::Store::QueryAlgorithms::BruteForce::new at line 55 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Store/QueryAlgorithms/BruteForce.pm
sub new {
48324µs my $class = shift;
49 my $this = bless( {}, $class );
50 return $this;
51}
52
53=begin TML
54
55---++ ObjectMethod query( $query, $webs, $inputTopicSet, $session, $options ) -> $infoCache
56 * =$query= - A Foswiki::Query::Node object
57 * =$web= - name of the web being searched, or may be an array reference
58 to a set of webs to search
59 * =$inputTopicSet= - iterator over names of topics in that web to search
60 * =$session= - reference to the store object
61 * =$options= - hash of requested options
62This is the top-level interface to a query algorithm. A store module can call
63this method to start the 'hard work' query process. That process will call
64back to the =getField= method in this module to evaluate leaf data in the
65store.
66
67To monitor the hoisting and evaluation processes, use the MONITOR_EVAL
68setting in Foswiki::Query::Node
69
70this is a default implementation of the query() sub that uses the specific algorithms' _webQuery member function.
71
72=cut
73
74
# spent 1.65s (218µs+1.65) within Foswiki::Store::Interfaces::QueryAlgorithm::query which was called: # once (218µs+1.65s) by Foswiki::Store::VC::Store::query at line 575 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Store/VC/Store.pm
sub query {
7513179µs my ( $this, $query, $inputTopicSet, $session, $options ) = @_;
76
7714µs if ( $query->isEmpty() )
# spent 4µs making 1 call to Foswiki::Query::Node::isEmpty
78 { #TODO: does this do anything in a type=query context?
79 return Foswiki::Search::InfoCache->new( $session, '' );
80 }
81
82 my $date = $options->{'date'} || '';
83
84 # Fold constants
85160µs my $context = Foswiki::Meta->new( $session, $session->{webName} );
# spent 60µs making 1 call to Foswiki::Meta::new
86 print STDERR "--- before: " . $query->stringify() . "\n" if MONITOR;
871177µs $query->simplify( tom => $context, data => $context );
# spent 177µs making 1 call to Foswiki::Query::Node::simplify
88 print STDERR "--- simplified: " . $query->stringify() . "\n" if MONITOR;
89
901627µs my $webItr = $this->getWebIterator( $session, $options );
91
92 #do the search
93 my $queryItr = Foswiki::Iterator::ProcessIterator->new(
94 $webItr,
95
# spent 1.65s (41µs+1.65) within Foswiki::Store::Interfaces::QueryAlgorithm::__ANON__[/usr/local/src/github.com/foswiki/core/lib/Foswiki/Store/Interfaces/QueryAlgorithm.pm:109] which was called: # once (41µs+1.65s) by Foswiki::Iterator::ProcessIterator::next at line 51 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Iterator/ProcessIterator.pm
sub {
966688µs my $web = shift;
97 my $params = shift;
98
9911.65s my $infoCache =
100 $this->_webQuery( $params->{query}, $web, $params->{inputset},
101 $params->{session}, $params->{options} );
102
103 if ($date) {
104 $infoCache->filterByDate($date);
105 }
1061746µs $infoCache->sortResults($options);
# spent 746µs making 1 call to Foswiki::Search::InfoCache::sortResults
107
108 return $infoCache;
109 },
110 {
111151µs query => $query,
# spent 51µs making 1 call to Foswiki::Iterator::ProcessIterator::new
112 inputset => $inputTopicSet,
113 session => $session,
114 options => $options
115 }
116 );
117
118#sadly, the resultSet currently wants a real array, rather than an unevaluated iterator
11911.65s my @resultCacheList = $queryItr->all();
# spent 1.65s making 1 call to Foswiki::Iterator::ProcessIterator::all
120
121#and thus if the ResultSet could be created using an unevaluated process itr, which would somehow rely on........ eeeeek
122256µs my $resultset =
# spent 47µs making 1 call to Foswiki::Search::ResultSet::new # spent 8µs making 1 call to Foswiki::isTrue
123 new Foswiki::Search::ResultSet( \@resultCacheList, $options->{groupby},
124 $options->{order}, Foswiki::isTrue( $options->{reverse} ) );
125
126#consider if this is un-necessary - and that we can steal the web order sort from DBIStore and push up to the webItr
127 if ($date) {
128 $resultset->filterByDate($date);
129 }
130134µs $resultset->sortResults($options);
# spent 34µs making 1 call to Foswiki::Search::ResultSet::sortResults
131
132 #add permissions check
133175µs $resultset = $this->addACLFilter( $resultset, $options );
134
135 #add paging if applicable.
136110µs $this->addPager( $resultset, $options );
137}
138
139
# spent 10µs within Foswiki::Store::Interfaces::QueryAlgorithm::addPager which was called: # once (10µs+0s) by Foswiki::Store::Interfaces::QueryAlgorithm::query at line 136
sub addPager {
140514µs my $this = shift;
141 my $resultset = shift;
142 my $options = shift;
143
144 if ( $options->{paging_on} ) {
145 $resultset =
146 new Foswiki::Iterator::PagerIterator( $resultset,
147 $options->{pagesize}, $options->{showpage} );
148 }
149
150 return $resultset;
151}
152
153
# spent 75µs (32+43) within Foswiki::Store::Interfaces::QueryAlgorithm::addACLFilter which was called: # once (32µs+43µs) by Foswiki::Store::Interfaces::QueryAlgorithm::query at line 133
sub addACLFilter {
154433µs my $this = shift;
155 my $resultset = shift;
156 my $options = shift;
157
158 #add filtering for ACL test - probably should make it a seperate filter
159 $resultset = new Foswiki::Iterator::FilterIterator(
160 $resultset,
161
# spent 1.64s (1.35ms+1.64) within Foswiki::Store::Interfaces::QueryAlgorithm::__ANON__[/usr/local/src/github.com/foswiki/core/lib/Foswiki/Store/Interfaces/QueryAlgorithm.pm:187] which was called 22 times, avg 74.7ms/call: # 22 times (1.35ms+1.64s) by Foswiki::Iterator::FilterIterator::hasNext at line 66 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Iterator/FilterIterator.pm, avg 74.7ms/call
sub {
1621761.07ms my $listItem = shift;
163 my $params = shift;
164
165 #ACL test
166221.71ms my ( $web, $topic ) =
# spent 1.71ms making 22 calls to Foswiki::Func::normalizeWebTopicName, avg 78µs/call
167 Foswiki::Func::normalizeWebTopicName( '', $listItem );
168
169661.63s my $topicMeta =
# spent 1.63s making 22 calls to Foswiki::MetaCache::addMeta, avg 74.2ms/call # spent 179µs making 22 calls to Foswiki::Search::metacache, avg 8µs/call # spent 166µs making 22 calls to Foswiki::search, avg 8µs/call
170 $Foswiki::Plugins::SESSION->search->metacache->addMeta( $web,
171 $topic );
172 if ( not defined($topicMeta) ) {
173
174#TODO: OMG! Search.pm relies on Meta::load (in the metacache) returning a meta object even when the topic does not exist.
175#lets change that
176 $topicMeta =
177 new Foswiki::Meta( $Foswiki::Plugins::SESSION, $web, $topic );
178 }
179667.86ms my $info =
# spent 7.51ms making 22 calls to Foswiki::MetaCache::get, avg 341µs/call # spent 186µs making 22 calls to Foswiki::search, avg 8µs/call # spent 166µs making 22 calls to Foswiki::Search::metacache, avg 8µs/call
180 $Foswiki::Plugins::SESSION->search->metacache->get( $web, $topic,
181 $topicMeta );
182 ##ASSERT( defined( $info->{tom} ) ) if DEBUG;
183
184# Check security (don't show topics the current user does not have permission to view)
185 return 0 unless ( $info->{allowView} );
186 return 1;
187 },
188142µs $options
# spent 42µs making 1 call to Foswiki::Iterator::FilterIterator::new
189 );
190}
191
192
# spent 627µs (79+548) within Foswiki::Store::Interfaces::QueryAlgorithm::getWebIterator which was called: # once (79µs+548µs) by Foswiki::Store::Interfaces::QueryAlgorithm::query at line 90
sub getWebIterator {
1931084µs my $this = shift;
194 my $session = shift;
195 my $options = shift;
196
197 my $webNames = $options->{web} || '';
198 my $recurse = $options->{'recurse'} || '';
1991175µs my $isAdmin = $session->{users}->isAdmin( $session->{user} );
# spent 175µs making 1 call to Foswiki::Users::isAdmin
200
201 #get a complete list of webs to search
20215µs my $searchAllFlag = ( $webNames =~ /(^|[\,\s])(all|on)([\,\s]|$)/i );
2031262µs my @webs =
204 Foswiki::Store::Interfaces::QueryAlgorithm::getListOfWebs( $webNames,
205 $recurse, $searchAllFlag );
206145µs my $rawWebIter = new Foswiki::ListIterator( \@webs );
# spent 45µs making 1 call to Foswiki::ListIterator::new
207 my $webItr = new Foswiki::Iterator::FilterIterator(
208 $rawWebIter,
209
# spent 567µs (55+512) within Foswiki::Store::Interfaces::QueryAlgorithm::__ANON__[/usr/local/src/github.com/foswiki/core/lib/Foswiki/Store/Interfaces/QueryAlgorithm.pm:228] which was called: # once (55µs+512µs) by Foswiki::Iterator::FilterIterator::hasNext at line 66 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Iterator/FilterIterator.pm
sub {
210751µs my $web = shift;
211 my $params = shift;
212
213 # can't process what ain't thar
2141198µs return 0 unless $session->webExists($web);
# spent 198µs making 1 call to Foswiki::webExists
215
216197µs my $webObject = Foswiki::Meta->new( $session, $web );
# spent 97µs making 1 call to Foswiki::Meta::new
2172217µs my $thisWebNoSearchAll =
# spent 208µs making 1 call to Foswiki::Meta::getPreference # spent 9µs making 1 call to Foswiki::isTrue
218 Foswiki::isTrue( $webObject->getPreference('NOSEARCHALL') );
219
220 # make sure we can report this web on an 'all' search
221 # DON'T filter out unless it's part of an 'all' search.
222 return 0
223 if ( $searchAllFlag
224 && !$isAdmin
225 && ( $thisWebNoSearchAll || $web =~ /^[\.\_]/ )
226 && $web ne $session->{webName} );
227 return 1;
228 },
229 {}
230162µs );
# spent 62µs making 1 call to Foswiki::Iterator::FilterIterator::new
231}
232
233=begin TML
234
235---++ StaticMethod getField($class, $node, $data, $field ) -> $result
236 * =$class= is this package
237 * =$node= is the query node
238 * =$data= is the indexed object
239 * =$field= is the scalar being used to index the object
240=getField= is used by the query evaluation code in Foswiki::Query::Node to get
241information about a leaf node, or 'field'. A field can be a name, or a literal,
242and the information it refers to can be a scalar, a reference to a hash, or
243a reference to an array. The exact interpretation of fields is
244context-dependant, according to reasonably complex rules best documented by
245the Fn_SEARCH unit test and System.QuerySearch.
246
247The function must map the query schema to whatever the underlying
248store uses to store a topic. See System.QuerySearch for more information
249on the query schema.
250
251=cut
252
253# Implements Foswiki::Store::Interfaces::QueryAlgorithm
254sub getField {
255
256 # The getField function allows for Store specific optimisations
257 # such as direct database lookups. The default implementation
258 # works with the Foswiki::Meta object.
259 my ( $this, $node, $data, $field ) = @_;
260
261 my $result;
262 ASSERT( UNIVERSAL::isa( $data, 'Foswiki::Meta' ) ) if DEBUG;
263
264 print STDERR "\n----- getField($field)\n" if MONITOR;
265
266 if ( $field eq 'META:VERSIONS' ) {
267
268 # Disallow reloading versions for an object loaded here
269 # SMELL: violates Foswiki::Meta encapsulation
270 return [] if $data->{_loadedByQueryAlgorithm};
271
272 # Oooh, this is inefficient.
273 my $it = $data->getRevisionHistory();
274 my @revs;
275 while ( $it->hasNext() ) {
276 my $n = $it->next();
277 my $t =
278 $this->getRefTopic( $data, $data->web(), $data->topic(), $n );
279 $t->{_loadedByQueryAlgorithm} = 1;
280 push( @revs, $t );
281 }
282 return \@revs;
283 }
284
285 if ( $field =~ s/^META:// ) {
286 if ( $field eq 'TOPICINFO' ) {
287
288 # Ensure the revision info is populated from the store
289 $data->getRevisionInfo();
290 }
291 if ( $field eq 'CREATEINFO' ) {
292
293 # Ensure the revision info is populated from the store
294 return $this->getRev1Info($data);
295 }
296
297 if ( $Foswiki::Query::Node::isArrayType{$field} ) {
298
299 # Array type, have to use find
300 my @e = $data->find($field);
301 return \@e;
302 }
303 return $data->get($field);
304 }
305
306 if ( $field eq 'name' ) {
307
308 # Special accessor to compensate for lack of a topic
309 # name anywhere in the saved fields of meta
310 return $data->topic();
311 }
312
313 if ( $field eq 'text' ) {
314
315 # Special accessor to compensate for lack of the topic text
316 # name anywhere in the saved fields of meta
317 return $data->text();
318 }
319
320 if ( $field eq 'web' ) {
321
322 # Special accessor to compensate for lack of a web
323 # name anywhere in the saved fields of meta
324 return $data->web();
325 }
326
327 if ( $field eq ':topic_meta:' ) {
328
329 #TODO: Sven expects this to be replaced with a fast call to
330 # versions[0] - atm, thats needlessly slow
331 # return the meta obj itself
332 # actually should do this the way the versions feature is
333 # supposed to return a particular one..
334 # SMELL: CDot can't work out what this is for....
335 return $data;
336 }
337
338 return undef unless $data->topic();
339
340 if (MONITOR) {
341 print STDERR "----- getField(FIELD value $field)\n";
34221.36ms2228µs
# spent 129µs (31+98) within Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@342 which was called: # once (31µs+98µs) by Foswiki::Store::QueryAlgorithms::BruteForce::BEGIN@29 at line 342
use Data::Dumper;
# spent 129µs making 1 call to Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@342 # spent 98µs making 1 call to Exporter::import
343 print STDERR Dumper($data) . "\n";
344 }
345
346 # SHORTCUT; not a predefined name; assume it's a field
347 # 'name' instead.
348 $result = $data->get( 'FIELD', $field );
349 $result = $result->{value} if $result;
350 return $result;
351}
352
353=begin TML
354
355---++ StaticMethod getForm($class, $node, $data, $field ) -> $result
356 * =$class= is this package
357 * =$node= is the query node
358 * =$data= is the indexed object (must be Foswiki::Meta)
359 * =$formname= is the required form name
360
361=cut
362
363sub getForm {
364 my ( $this, $node, $data, $formname ) = @_;
365 return undef unless $data->topic();
366
367 my $form = $data->get('FORM');
368 return undef unless $form && $formname eq $form->{name};
369 print STDERR "----- getForm($formname)\n" if MONITOR;
370
371 # TODO: This is where multiple form support needs to reside.
372 # Return the array of FIELD for further indexing.
373 my @e = $data->find('FIELD');
374 return \@e;
375}
376
377=begin TML
378
379---++ StaticMethod getRefTopic($class, $relativeTo, $web, $topic, $rev) -> $topic
380 * =$class= is this package
381 * =$relativeTo= is a pointer into the data structure of this module where
382 the ref is relative to; for example, in the expression
383 "other/'Web.Topic'" then =$relativeTo= is =other=.
384 * =$web= the web; =Web= in the above example
385 * =$topic= the topic; =Topic= in the above example
386 * =$rev= optional revision to load
387This method supports the =Foswiki::Query::OP_ref= and =Foswiki::Query::OP_at=
388operators by abstracting the loading of a topic referred to in a string.
389
390=cut
391
392# Default implements gets a new Foswiki::Meta
393sub getRefTopic {
394
395 # Get a referenced topic
396 my ( $this, $relativeTo, $w, $t, $rev ) = @_;
397 my $meta = Foswiki::Meta->load( $relativeTo->session, $w, $t, $rev );
398 print STDERR "----- getRefTopic($w, $t) -> "
399 . ( $meta->getLoadedRev() ) . "\n"
400 if MONITOR;
401 return $meta;
402}
403
404=begin TML
405
406---++ StaticMethod getRev1Info($meta) -> %info
407
408Return revision info for the first revision in %info with at least:
409 * ={date}= in epochSec
410 * ={author}= canonical user ID
411 * ={version}= the revision number
412
413=cut
414
415# Default implements gets a new Foswiki::Meta
416sub getRev1Info {
417 my $this = shift;
418 my $meta = shift;
419
420 my $wikiname = $meta->getRev1Info('createwikiname');
421 return $meta->{_getRev1Info}->{rev1info};
422}
423
424=begin TML
425
426---+ getListOfWebs($webnames, $recurse, $serachAllFlag) -> @webs
427
428Convert a comma separated list of webs into the list we'll process
429TODO: this is part of the Store now, and so should not need to reference
430Meta - it rather uses the store.
431
432=cut
433
434
# spent 262µs (91+171) within Foswiki::Store::Interfaces::QueryAlgorithm::getListOfWebs which was called: # once (91µs+171µs) by Foswiki::Store::Interfaces::QueryAlgorithm::getWebIterator at line 203
sub getListOfWebs {
435837µs my ( $webName, $recurse, $searchAllFlag ) = @_;
436 my $session = $Foswiki::Plugins::SESSION;
437
438 my %excludeWeb;
439 my @tmpWebs;
440
441 #$web = Foswiki::Sandbox::untaint( $web,\&Foswiki::Sandbox::validateWebName );
442
44316µs if ($webName) {
444 foreach my $web ( split( /[\,\s]+/, $webName ) ) {
445222µs12µs $web =~ s#\.#/#go;
446
447 # the web processing loop filters for valid web names,
448 # so don't do it here.
449116µs12µs if ( $web =~ s/^-// ) {
450 $excludeWeb{$web} = 1;
451 }
452 else {
453210µs256µs if ( $web =~ /^(all|on)$/i
# spent 54µs making 1 call to Foswiki::isTrue # spent 3µs making 1 call to Foswiki::Store::Interfaces::QueryAlgorithm::CORE:match
454 || $Foswiki::cfg{EnableHierarchicalWebs}
455 && Foswiki::isTrue($recurse) )
456 {
457 my $webObject;
458 my $prefix = "$web/";
459 if ( $web =~ /^(all|on)$/i ) {
460 $webObject = Foswiki::Meta->new($session);
461 $prefix = '';
462 }
463 else {
464 $web = Foswiki::Sandbox::untaint( $web,
465 \&Foswiki::Sandbox::validateWebName );
466 ASSERT($web) if DEBUG;
467 push( @tmpWebs, $web );
468 $webObject = Foswiki::Meta->new( $session, $web );
469 }
470 my $it = $webObject->eachWeb(1);
471 while ( $it->hasNext() ) {
472 my $w = $prefix . $it->next();
473 next
474 unless $Foswiki::WebFilter::user_allowed->ok(
475 $session, $w );
476 $w = Foswiki::Sandbox::untaint( $w,
477 \&Foswiki::Sandbox::validateWebName );
478 ASSERT($web) if DEBUG;
479 push( @tmpWebs, $w );
480 }
481 }
482 else {
4831106µs $web = Foswiki::Sandbox::untaint( $web,
# spent 106µs making 1 call to Foswiki::Sandbox::untaint
484 \&Foswiki::Sandbox::validateWebName );
485 push( @tmpWebs, $web );
486 }
487 }
488 }
489
490 }
491 else {
492
493 # default to current web
494 my $web =
495 Foswiki::Sandbox::untaint( $session->{webName},
496 \&Foswiki::Sandbox::validateWebName );
497 push( @tmpWebs, $web );
498 if ( Foswiki::isTrue($recurse) ) {
499 require Foswiki::Meta;
500 my $webObject = Foswiki::Meta->new( $session, $session->{webName} );
501 my $it =
502 $webObject->eachWeb( $Foswiki::cfg{EnableHierarchicalWebs} );
503 while ( $it->hasNext() ) {
504 my $w = $session->{webName} . '/' . $it->next();
505 next
506 unless $Foswiki::WebFilter::user_allowed->ok( $session, $w );
507 $w = Foswiki::Sandbox::untaint( $w,
508 \&Foswiki::Sandbox::validateWebName );
509 push( @tmpWebs, $w );
510 }
511 }
512 }
513
514 my @webs;
515 foreach my $web (@tmpWebs) {
516310µs next unless defined $web;
517 push( @webs, $web ) unless $excludeWeb{$web};
518 $excludeWeb{$web} = 1; # eliminate duplicates
519 }
520
521 # Default to alphanumeric sort order
52215µs return sort @webs;
523}
524
52515µs1;
526__END__
 
# spent 7µs within Foswiki::Store::Interfaces::QueryAlgorithm::CORE:match which was called 2 times, avg 4µs/call: # once (5µs+0s) by Foswiki::Store::Interfaces::QueryAlgorithm::getWebIterator at line 202 # once (3µs+0s) by Foswiki::Store::Interfaces::QueryAlgorithm::getListOfWebs at line 453
sub Foswiki::Store::Interfaces::QueryAlgorithm::CORE:match; # opcode
# spent 5µs within Foswiki::Store::Interfaces::QueryAlgorithm::CORE:sort which was called: # once (5µs+0s) by Foswiki::Store::Interfaces::QueryAlgorithm::getListOfWebs at line 522
sub Foswiki::Store::Interfaces::QueryAlgorithm::CORE:sort; # opcode
# spent 4µs within Foswiki::Store::Interfaces::QueryAlgorithm::CORE:subst which was called 2 times, avg 2µs/call: # once (2µs+0s) by Foswiki::Store::Interfaces::QueryAlgorithm::getListOfWebs at line 445 # once (2µs+0s) by Foswiki::Store::Interfaces::QueryAlgorithm::getListOfWebs at line 449
sub Foswiki::Store::Interfaces::QueryAlgorithm::CORE:subst; # opcode