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