MediaWiki 1.41.2
InsertQueryBuilder.php
Go to the documentation of this file.
1<?php
2
3namespace Wikimedia\Rdbms;
4
5use InvalidArgumentException;
6use UnexpectedValueException;
7
25 private $table = '';
26
30 private $rows = [];
31
35 private $caller = __CLASS__;
36
40 private $upsert = false;
41
45 private $set = [];
46
50 private $uniqueIndexFields = [];
51
55 protected $options = [];
56
58 protected $db;
59
66 public function __construct( IDatabase $db ) {
67 $this->db = $db;
68 }
69
77 public function connection( IDatabase $db ) {
78 if ( $this->db->getType() !== $db->getType() ) {
79 throw new InvalidArgumentException(
80 __METHOD__ . ' cannot switch to a database of a different type.'
81 );
82 }
83 $this->db = $db;
84 return $this;
85 }
86
105 public function queryInfo( $info ) {
106 if ( isset( $info['table'] ) ) {
107 $this->table( $info['table'] );
108 }
109 if ( isset( $info['rows'] ) ) {
110 $this->rows( $info['rows'] );
111 }
112 if ( isset( $info['options'] ) ) {
113 $this->options( (array)$info['options'] );
114 }
115 if ( isset( $info['upsert'] ) ) {
116 $this->onDuplicateKeyUpdate();
117 }
118 if ( isset( $info['uniqueIndexFields'] ) ) {
119 $this->uniqueIndexFields( (array)$info['uniqueIndexFields'] );
120 }
121 if ( isset( $info['set'] ) ) {
122 $this->set( (array)$info['set'] );
123 }
124 if ( isset( $info['caller'] ) ) {
125 $this->caller( $info['caller'] );
126 }
127 return $this;
128 }
129
137 public function table( $table ) {
138 $this->table = $table;
139 return $this;
140 }
141
149 public function insertInto( string $table ) {
150 return $this->table( $table );
151 }
152
160 public function insert( string $table ) {
161 return $this->table( $table );
162 }
163
172 public function option( $name, $value = null ) {
173 if ( $value === null ) {
174 $this->options[] = $name;
175 } else {
176 $this->options[$name] = $value;
177 }
178 return $this;
179 }
180
188 public function options( array $options ) {
189 $this->options = array_merge( $this->options, $options );
190 return $this;
191 }
192
203 public function rows( array $rows ) {
204 $this->rows = array_merge( $this->rows, $rows );
205 return $this;
206 }
207
217 public function row( array $row ) {
218 $this->rows[] = $row;
219 return $this;
220 }
221
230 public function ignore() {
231 $this->options[] = 'IGNORE';
232 return $this;
233 }
234
240 public function onDuplicateKeyUpdate() {
241 $this->upsert = true;
242 return $this;
243 }
244
251 public function uniqueIndexFields( $uniqueIndexFields ) {
252 if ( is_string( $uniqueIndexFields ) ) {
253 $uniqueIndexFields = [ $uniqueIndexFields ];
254 }
255 $this->uniqueIndexFields = $uniqueIndexFields;
256 return $this;
257 }
258
281 public function set( $set ) {
282 if ( is_array( $set ) ) {
283 foreach ( $set as $key => $value ) {
284 if ( is_int( $key ) ) {
285 $this->set[] = $value;
286 } else {
287 $this->set[$key] = $value;
288 }
289 }
290 } else {
291 $this->set[] = $set;
292 }
293 return $this;
294 }
295
303 public function andSet( $set ) {
304 return $this->set( $set );
305 }
306
314 public function caller( $fname ) {
315 $this->caller = $fname;
316 return $this;
317 }
318
322 public function execute() {
323 if ( !$this->rows ) {
324 // (T347610) For now, allow this but deprecate it, so we can trace these and fix them rapidly.
325 wfDeprecatedMsg( self::class . ' triggered with no rows set; exit early instead.' );
326 // TODO: Uncomment rather than deprecate once early-exist mitigations are in place.
327 // throw new UnexpectedValueException( __METHOD__ . ' can\'t have empty $rows value' );
328 }
329 if ( $this->table === '' ) {
330 throw new UnexpectedValueException(
331 __METHOD__ . ' expects table not to be empty' );
332 }
333 if ( $this->upsert && ( !$this->set || !$this->uniqueIndexFields ) ) {
334 throw new UnexpectedValueException(
335 __METHOD__ . ' called with upsert but no set value or unique key has been provided' );
336 }
337 if ( !$this->upsert && ( $this->set || $this->uniqueIndexFields ) ) {
338 throw new UnexpectedValueException(
339 __METHOD__ . ' is not called with upsert but set value or unique key has been provided' );
340 }
341 if ( $this->upsert ) {
342 $this->db->upsert( $this->table, $this->rows, [ $this->uniqueIndexFields ], $this->set, $this->caller );
343 return;
344 }
345 $this->db->insert( $this->table, $this->rows, $this->caller, $this->options );
346 }
347
361 public function getQueryInfo() {
362 $info = [
363 'table' => $this->table,
364 'rows' => $this->rows,
365 'upsert' => $this->upsert,
366 'set' => $this->set,
367 'uniqueIndexFields' => $this->uniqueIndexFields,
368 'options' => $this->options,
369 ];
370 if ( $this->caller !== __CLASS__ ) {
371 $info['caller'] = $this->caller;
372 }
373 return $info;
374 }
375}
wfDeprecatedMsg( $msg, $version=false, $component=false, $callerOffset=2)
Log a deprecation warning with arbitrary message text.
Build INSERT queries with a fluent interface.
insert(string $table)
Set table for the query.
uniqueIndexFields( $uniqueIndexFields)
Set the unique index fields.
option( $name, $value=null)
Manually set an option in the $options array to be passed to IDatabase::insert()
onDuplicateKeyUpdate()
Do an update instead of insert.
getQueryInfo()
Get an associative array describing the query in terms of its raw parameters to Database::insert().
connection(IDatabase $db)
Change the IDatabase object the query builder is bound to.
insertInto(string $table)
Set table for the query.
andSet( $set)
Add set values to the query.
queryInfo( $info)
Set the query parameters to the given values, appending to the values which were already set.
table( $table)
Manually set the table name to be passed to IDatabase::insert()
__construct(IDatabase $db)
Only for use in subclasses.
array $options
The options to be passed to IDatabase::insert()
row(array $row)
Add one row to be inserted.
rows(array $rows)
Add rows to be inserted.
options(array $options)
Manually set multiple options in the $options array to be passed to IDatabase::insert().
execute()
Run the constructed INSERT query and return the result.
caller( $fname)
Set the method name to be included in an SQL comment.
Basic database interface for live and lazy-loaded relation database handles.
Definition IDatabase.php:36
getType()
Get the RDBMS type of the server (e.g.