Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
86.96% covered (warning)
86.96%
40 / 46
81.82% covered (warning)
81.82%
9 / 11
CRAP
0.00% covered (danger)
0.00%
0 / 1
PageSelectQueryBuilder
86.96% covered (warning)
86.96%
40 / 46
81.82% covered (warning)
81.82%
9 / 11
17.64
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 wherePageIds
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
 whereNamespace
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 whereTitlePrefix
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
1
 whereTitles
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 orderByTitle
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 orderByPageId
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 fetchPageRecord
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
3
 fetchPageRecords
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
3
 fetchPageRecordArray
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 fetchPageIds
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace MediaWiki\Page;
4
5use Iterator;
6use MediaWiki\Cache\LinkCache;
7use Wikimedia\Assert\Assert;
8use Wikimedia\Rdbms\IExpression;
9use Wikimedia\Rdbms\IReadableDatabase;
10use Wikimedia\Rdbms\LikeValue;
11use Wikimedia\Rdbms\SelectQueryBuilder;
12
13/**
14 * @since 1.36
15 */
16class PageSelectQueryBuilder extends SelectQueryBuilder {
17
18    /** @var PageStore */
19    private $pageStore;
20
21    /** @var LinkCache|null */
22    private $linkCache;
23
24    /**
25     * @param IReadableDatabase $db
26     * @param PageStore $pageStore
27     * @param LinkCache|null $linkCache A link cache to store any retrieved rows into
28     *
29     * @internal
30     */
31    public function __construct( IReadableDatabase $db, PageStore $pageStore, ?LinkCache $linkCache = null ) {
32        parent::__construct( $db );
33        $this->pageStore = $pageStore;
34        $this->table( 'page' );
35        $this->linkCache = $linkCache;
36    }
37
38    /**
39     * Find by provided page ids.
40     *
41     * @param int|int[] $pageIds
42     *
43     * @return PageSelectQueryBuilder
44     */
45    public function wherePageIds( $pageIds ): self {
46        Assert::parameterType( [ 'integer', 'array' ], $pageIds, '$pageIds' );
47
48        if ( $pageIds ) {
49            $this->conds( [ 'page_id' => $pageIds ] );
50        } else {
51            $this->conds( '0 = 1' ); // force empty result set
52        }
53
54        return $this;
55    }
56
57    /**
58     * Find by provided namespace.
59     *
60     * @param int $namespace
61     *
62     * @return PageSelectQueryBuilder
63     */
64    public function whereNamespace( int $namespace ): self {
65        $this->conds( [ 'page_namespace' => $namespace ] );
66        return $this;
67    }
68
69    /**
70     * Find by provided prefix.
71     *
72     * @param int $namespace
73     * @param string $prefix
74     *
75     * @return PageSelectQueryBuilder
76     */
77    public function whereTitlePrefix( int $namespace, string $prefix ): self {
78        $this->whereNamespace( $namespace );
79        $this->conds(
80            $this->db->expr( 'page_title', IExpression::LIKE, new LikeValue( $prefix, $this->db->anyString() ) )
81        );
82        return $this;
83    }
84
85    /**
86     * Find by provided page titles.
87     *
88     * @param int $namespace
89     * @param string|string[] $pageTitles
90     *
91     * @return PageSelectQueryBuilder
92     */
93    public function whereTitles( int $namespace, $pageTitles ): self {
94        Assert::parameterType( [ 'string', 'array' ], $pageTitles, '$pageTitles' );
95        $this->conds( [ 'page_namespace' => $namespace ] );
96        $this->conds( [ 'page_title' => $pageTitles ] );
97        return $this;
98    }
99
100    /**
101     * Order results by namespace and title in $direction
102     *
103     * @param string $dir one of self::SORT_ACS or self::SORT_DESC
104     *
105     * @return PageSelectQueryBuilder
106     */
107    public function orderByTitle( string $dir = self::SORT_ASC ): self {
108        $this->orderBy( [ 'page_namespace', 'page_title' ], $dir );
109        return $this;
110    }
111
112    /**
113     * Order results by page id.
114     *
115     * @param string $dir one of self::SORT_ACS or self::SORT_DESC
116     *
117     * @return PageSelectQueryBuilder
118     */
119    public function orderByPageId( string $dir = self::SORT_ASC ): self {
120        $this->orderBy( 'page_id', $dir );
121        return $this;
122    }
123
124    /**
125     * Fetch a single PageRecord that matches specified criteria.
126     *
127     * @return PageRecord|null
128     */
129    public function fetchPageRecord(): ?PageRecord {
130        $this->fields( $this->pageStore->getSelectFields() );
131
132        $row = $this->fetchRow();
133        if ( !$row ) {
134            return null;
135        }
136
137        $rec = $this->pageStore->newPageRecordFromRow( $row );
138        if ( $this->linkCache ) {
139            $this->linkCache->addGoodLinkObjFromRow( $rec, $row );
140        }
141        return $rec;
142    }
143
144    /**
145     * Fetch PageRecords for the specified query.
146     *
147     * @return Iterator<ExistingPageRecord>
148     */
149    public function fetchPageRecords(): Iterator {
150        $this->fields( $this->pageStore->getSelectFields() );
151
152        $result = $this->fetchResultSet();
153        foreach ( $result as $row ) {
154            $rec = $this->pageStore->newPageRecordFromRow( $row );
155            if ( $this->linkCache ) {
156                $this->linkCache->addGoodLinkObjFromRow( $rec, $row );
157            }
158            yield $rec;
159        }
160        $result->free();
161    }
162
163    /**
164     * Fetch PageRecords for the specified query as an associative
165     * array, using page IDs as array keys.
166     *
167     * @return ExistingPageRecord[]
168     */
169    public function fetchPageRecordArray(): array {
170        $recs = [];
171
172        foreach ( $this->fetchPageRecords() as $rec ) {
173            $recs[ $rec->getId() ] = $rec;
174        }
175
176        return $recs;
177    }
178
179    /**
180     * Returns an array of page ids matching the query.
181     *
182     * @return int[]
183     */
184    public function fetchPageIds(): array {
185        $this->field( 'page_id' );
186        return array_map( 'intval', $this->fetchFieldValues() );
187    }
188
189}