| Current File : /home/jvzmxxx/wiki/extensions/Wikibase/lib/includes/Store/Sql/PropertyInfoTable.php |
<?php
namespace Wikibase;
use DBAccessBase;
use DBError;
use InvalidArgumentException;
use ResultWrapper;
use Wikibase\DataModel\Entity\PropertyId;
/**
* Class PropertyInfoTable implements PropertyInfoStore on top of an SQL table.
*
* @since 0.4
*
* @license GPL-2.0+
* @author Daniel Kinzler
* @author Bene* < benestar.wikimedia@gmail.com >
*/
class PropertyInfoTable extends DBAccessBase implements PropertyInfoStore {
/**
* @var string
*/
private $tableName;
/**
* @var bool
*/
private $isReadonly;
/**
* @param bool $isReadonly Whether the table can be modified.
* @param string|bool $wiki The wiki's database to connect to.
* Must be a value LBFactory understands. Defaults to false, which is the local wiki.
*
* @throws InvalidArgumentException
*/
public function __construct( $isReadonly, $wiki = false ) {
if ( !is_bool( $isReadonly ) ) {
throw new InvalidArgumentException( '$isReadonly must be boolean.' );
}
if ( !is_string( $wiki ) && $wiki !== false ) {
throw new InvalidArgumentException( '$wiki must be a string or false.' );
}
parent::__construct( $wiki );
$this->tableName = 'wb_property_info';
$this->isReadonly = $isReadonly;
}
/**
* Decodes an info blob.
*
* @param string|null|bool $blob
*
* @return array|null The decoded blob as an associative array, or null if the blob
* could not be decoded.
*/
private function decodeBlob( $blob ) {
if ( $blob === false || $blob === null ) {
return null;
}
$info = json_decode( $blob, true );
if ( !is_array( $info ) ) {
$info = null;
}
return $info;
}
/**
* Decodes a result with info blobs.
*
* @param ResultWrapper $res
*
* @return array[] The array of decoded blobs
*/
private function decodeResult( ResultWrapper $res ) {
$infos = array();
foreach ( $res as $row ) {
$info = $this->decodeBlob( $row->pi_info );
if ( $info === null ) {
wfLogWarning( "failed to decode property info blob for property "
. $row->pi_property_id . ": " . $row->pi_info );
continue;
}
$infos[$row->pi_property_id] = $info;
}
return $infos;
}
/**
* @see PropertyInfoStore::getPropertyInfo
*
* @param PropertyId $propertyId
*
* @return array|null
* @throws InvalidArgumentException
* @throws DBError
*/
public function getPropertyInfo( PropertyId $propertyId ) {
$dbr = $this->getConnection( DB_SLAVE );
$res = $dbr->selectField(
$this->tableName,
'pi_info',
array( 'pi_property_id' => $propertyId->getNumericId() ),
__METHOD__
);
$this->releaseConnection( $dbr );
if ( $res === false ) {
$info = null;
} else {
$info = $this->decodeBlob( $res );
if ( $info === null ) {
wfLogWarning( "failed to decode property info blob for " . $propertyId . ": " . substr( $res, 0, 200 ) );
}
}
return $info;
}
/**
* @see PropertyDataTypeLookup::getPropertyInfoForDataType
*
* @param string $dataType
*
* @return array[]
* @throws DBError
*/
public function getPropertyInfoForDataType( $dataType ) {
$dbr = $this->getConnection( DB_SLAVE );
$res = $dbr->select(
$this->tableName,
array( 'pi_property_id', 'pi_info' ),
array( 'pi_type' => $dataType ),
__METHOD__
);
$infos = $this->decodeResult( $res );
$this->releaseConnection( $dbr );
return $infos;
}
/**
* @see PropertyInfoStore::getAllPropertyInfo
*
* @return array[]
* @throws DBError
*/
public function getAllPropertyInfo() {
$dbr = $this->getConnection( DB_SLAVE );
$res = $dbr->select(
$this->tableName,
array( 'pi_property_id', 'pi_info' ),
array(),
__METHOD__
);
$infos = $this->decodeResult( $res );
$this->releaseConnection( $dbr );
return $infos;
}
/**
* @see PropertyInfoStore::setPropertyInfo
*
* @param PropertyId $propertyId
* @param array $info
*
* @throws DBError
* @throws InvalidArgumentException
*/
public function setPropertyInfo( PropertyId $propertyId, array $info ) {
if ( $this->isReadonly ) {
throw new DBError( 'Cannot write when in readonly mode' );
}
if ( !isset( $info[ PropertyInfoStore::KEY_DATA_TYPE ] ) ) {
throw new InvalidArgumentException( 'Missing required info field: ' . PropertyInfoStore::KEY_DATA_TYPE );
}
$type = $info[ PropertyInfoStore::KEY_DATA_TYPE ];
$json = json_encode( $info );
$dbw = $this->getConnection( DB_MASTER );
$dbw->replace(
$this->tableName,
array( 'pi_property_id' ),
array(
'pi_property_id' => $propertyId->getNumericId(),
'pi_info' => $json,
'pi_type' => $type,
),
__METHOD__
);
$this->releaseConnection( $dbw );
}
/**
* @see PropertyInfoStore::removePropertyInfo
*
* @param PropertyId $propertyId
*
* @throws DBError
* @throws InvalidArgumentException
* @return bool
*/
public function removePropertyInfo( PropertyId $propertyId ) {
if ( $this->isReadonly ) {
throw new DBError( 'Cannot write when in readonly mode' );
}
$dbw = $this->getConnection( DB_MASTER );
$dbw->delete(
$this->tableName,
array( 'pi_property_id' => $propertyId->getNumericId() ),
__METHOD__
);
$c = $dbw->affectedRows();
$this->releaseConnection( $dbw );
return $c > 0;
}
/**
* Returns a database connection suitable for writing to the database that
* contains the property info table.
*
* This is for use for closely related classes that want to operate directly
* on the database table.
*/
public function getWriteConnection() {
return $this->getConnection( DB_MASTER );
}
/**
* Returns the (logical) name of the database table that contains the property info.
*
* This is for use for closely related classes that want to operate directly
* on the database table.
*
* @return string
*/
public function getTableName() {
return $this->tableName;
}
}