Cicalese has uploaded a new change for review.
https://gerrit.wikimedia.org/r/263581
Change subject: Add page_props table access class
......................................................................
Add page_props table access class
Change-Id: I022b9e3ca47dc63650b8a62260603b0893a80e69
---
M autoload.php
A includes/PageProps.php
M includes/actions/InfoAction.php
A tests/phpunit/includes/PagePropsTest.php
4 files changed, 403 insertions(+), 13 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core
refs/changes/81/263581/1
diff --git a/autoload.php b/autoload.php
index 49a3faf..bfeebe0 100644
--- a/autoload.php
+++ b/autoload.php
@@ -871,6 +871,7 @@
'OrphanStats' => __DIR__ . '/maintenance/storage/orphanStats.php',
'Orphans' => __DIR__ . '/maintenance/orphans.php',
'OutputPage' => __DIR__ . '/includes/OutputPage.php',
+ 'PageProps' => __DIR__ . '/includes/PageProps.php',
'PNGHandler' => __DIR__ . '/includes/media/PNG.php',
'PNGMetadataExtractor' => __DIR__ .
'/includes/media/PNGMetadataExtractor.php',
'PPCustomFrame_DOM' => __DIR__ .
'/includes/parser/Preprocessor_DOM.php',
diff --git a/includes/PageProps.php b/includes/PageProps.php
new file mode 100644
index 0000000..25620ec
--- /dev/null
+++ b/includes/PageProps.php
@@ -0,0 +1,204 @@
+<?php
+/**
+ * Access to properties of a page.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+/**
+ * Gives access to properties of a page.
+ *
+ * @since 1.27
+ *
+ */
+class PageProps {
+
+ /** @var int $pageId page ID of the page being queried */
+ private $pageId;
+
+ /**
+ * Create a PageProps object
+ *
+ * @param Title $title
+ *
+ */
+ public function __construct( Title $title ) {
+ $this->pageId = $title->getArticleID();
+ }
+
+ /**
+ * Get page property value for a given property name.
+ *
+ * @param string $propertyName
+ *
+ * @return string|bool property value array or false if not found
+ *
+ */
+ public function getProperty( $propertyName ) {
+
+ if ( $this->pageId < 1 ) {
+ return false;
+ }
+
+ $propertyValue = self::getCachedProperty( $this->pageId,
$propertyName );
+ if ( $propertyValue !== false ) {
+ return $propertyValue;
+ }
+
+ $dbr = wfGetDB( DB_SLAVE );
+ $row = $dbr->selectRow(
+ 'page_props',
+ array( 'pp_value' ),
+ array(
+ 'pp_page' => $this->pageId,
+ 'pp_propname' => $propertyName
+ ),
+ __METHOD__
+ );
+
+ if ( $row !== false ) {
+ $propertyValue = $row->pp_value;
+ self::cacheProperty( $this->pageId, $propertyName,
$propertyValue );
+ return $propertyValue;
+ }
+
+ return false;
+ }
+
+ /**
+ * Get all page property values.
+ *
+ * @return array property value array
+ *
+ */
+ public function getProperties() {
+
+ if ( $this->pageId < 1 ) {
+ return array();
+ }
+
+ $pageProperties = self::getCachedProperties( $this->pageId );
+ if ( $pageProperties !== false ) {
+ return $pageProperties;
+ }
+
+ $dbr = wfGetDB( DB_SLAVE );
+ $result = $dbr->select(
+ 'page_props',
+ array(
+ 'pp_propname',
+ 'pp_value'
+ ),
+ array(
+ 'pp_page' => $this->pageId
+ ),
+ __METHOD__
+ );
+
+ $pageProperties = array();
+
+ foreach ( $result as $row ) {
+ $pageProperties[$row->pp_propname] = $row->pp_value;
+ }
+
+ self::cacheProperties( $this->pageId, $pageProperties );
+
+ return $pageProperties;
+ }
+
+ /** Cache parameters */
+ const CACHE_TTL = 10; // integer; TTL in seconds
+ const CACHE_SIZE = 100; // integer; max cached pages
+
+ /** Property cache */
+ private static $cache = null;
+
+ /**
+ * Get a property from the cache.
+ *
+ * @param int $pageId page ID of page being queried
+ * @param string $propertyName name of property being queried
+ *
+ * @return string|bool property value array or false if not found
+ *
+ */
+ private static function getCachedProperty( $pageId, $propertyName ) {
+ if ( is_null( self::$cache ) ) {
+ return false;
+ }
+ if ( self::$cache->has( $pageId, $propertyName, self::CACHE_TTL
) ) {
+ return self::$cache->get( $pageId, $propertyName );
+ }
+ if ( self::$cache->has( 0, $pageId, self::CACHE_TTL ) ) {
+ $pageProperties = self::$cache->get( 0, $pageId );
+ if ( isset( $pageProperties[$propertyName] ) ) {
+ return $pageProperties[$propertyName];
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Get properties from the cache.
+ *
+ * @param int $pageId page ID of page being queried
+ *
+ * @return string|bool property value array or false if not found
+ *
+ */
+ private static function getCachedProperties( $pageId ) {
+ if ( is_null( self::$cache ) ) {
+ return false;
+ }
+ if ( self::$cache->has( 0, $pageId, self::CACHE_TTL ) ) {
+ return self::$cache->get( 0, $pageId );
+ }
+ return false;
+ }
+
+ /**
+ * Save a property to the cache.
+ *
+ * @param int $pageId page ID of page being cached
+ * @param string $propertyName name of property being cached
+ * @param mixed $propertyValue value of property
+ *
+ */
+ private static function cacheProperty( $pageId, $propertyName,
+ $propertyValue ) {
+ if ( is_null( self::$cache ) ) {
+ self::$cache = new ProcessCacheLRU( self::CACHE_SIZE );
+ }
+ self::$cache->set( $pageId, $propertyName, $propertyValue );
+ }
+
+ /**
+ * Save properties to the cache.
+ *
+ * @param int $pageId page ID of page being cached
+ * @param array $pageProperties associative array of page properties to
be cached
+ *
+ */
+ private static function cacheProperties( $pageId, $pageProperties ) {
+ if ( is_null( self::$cache ) ) {
+ self::$cache = new ProcessCacheLRU( self::CACHE_SIZE );
+ }
+ self::$cache->clear( $pageId );
+ self::$cache->set( 0, $pageId, $pageProperties );
+ }
+}
diff --git a/includes/actions/InfoAction.php b/includes/actions/InfoAction.php
index 7389ae2..ff909f5 100644
--- a/includes/actions/InfoAction.php
+++ b/includes/actions/InfoAction.php
@@ -203,19 +203,8 @@
$pageCounts = $this->pageCounts( $this->page );
- // Get page properties
- $dbr = wfGetDB( DB_SLAVE );
- $result = $dbr->select(
- 'page_props',
- array( 'pp_propname', 'pp_value' ),
- array( 'pp_page' => $id ),
- __METHOD__
- );
-
- $pageProperties = array();
- foreach ( $result as $row ) {
- $pageProperties[$row->pp_propname] = $row->pp_value;
- }
+ $props = new PageProps( $title );
+ $pageProperties = $props->getProperties();
// Basic information
$pageInfo = array();
diff --git a/tests/phpunit/includes/PagePropsTest.php
b/tests/phpunit/includes/PagePropsTest.php
new file mode 100644
index 0000000..2567368
--- /dev/null
+++ b/tests/phpunit/includes/PagePropsTest.php
@@ -0,0 +1,196 @@
+<?php
+
+/**
+ * @group Database
+ * ^--- tell jenkins this test needs the database
+ *
+ * @group medium
+ * ^--- tell phpunit that these test cases may take longer than 2 seconds.
+ */
+class TestPageProps extends MediaWikiLangTestCase {
+
+ /**
+ * @var WikiPage $the_page
+ */
+ private $the_page;
+
+ /**
+ * @var int $the_page_id
+ */
+ private $the_page_id;
+
+ protected function setUp() {
+ global $wgExtraNamespaces, $wgNamespaceContentModels,
$wgContentHandlers, $wgContLang;
+
+ parent::setUp();
+
+ $wgExtraNamespaces[12312] = 'Dummy';
+ $wgExtraNamespaces[12313] = 'Dummy_talk';
+
+ $wgNamespaceContentModels[12312] = 'DUMMY';
+ $wgContentHandlers['DUMMY'] = 'DummyContentHandlerForTesting';
+
+ MWNamespace::getCanonicalNamespaces( true ); # reset namespace
cache
+ $wgContLang->resetNamespaces(); # reset namespace cache
+ if ( !$this->the_page ) {
+ $this->the_page = $this->createPage(
+ 'PagePropsTest_the_page',
+ "just a dummy page",
+ CONTENT_MODEL_WIKITEXT
+ );
+
+ $this->the_page_id =
$this->the_page->getTitle()->getArticleID();
+
+ $properties = array(
+ "property1" => "value1",
+ "property2" => "value2",
+ "property3" => "value3",
+ "property4" => "value4"
+ );
+ $this->setProperties( $properties );
+ }
+ }
+
+ protected function tearDown() {
+ global $wgExtraNamespaces, $wgNamespaceContentModels,
$wgContentHandlers, $wgContLang;
+
+ parent::tearDown();
+
+ unset( $wgExtraNamespaces[12312] );
+ unset( $wgExtraNamespaces[12313] );
+
+ unset( $wgNamespaceContentModels[12312] );
+ unset( $wgContentHandlers['DUMMY'] );
+
+ MWNamespace::getCanonicalNamespaces( true ); # reset namespace
cache
+ $wgContLang->resetNamespaces(); # reset namespace cache
+ }
+
+ public function testGetSingleProperty() {
+ $title = $this->the_page->getTitle();
+ $props = new PageProps( $title );
+ $value = $props->getProperty( "property1" );
+ $this->assertEquals( $value, "value1", "Get property" );
+ }
+
+ public function testGetAllProperties() {
+ $title = $this->the_page->getTitle();
+ $props = new PageProps( $title );
+ $this->assertEquals( $this->getProperties(),
$props->getProperties(), "Get all properties" );
+ }
+
+ public function testSingleCache() {
+ $title = $this->the_page->getTitle();
+ $props = new PageProps( $title );
+ $value1 = $props->getProperty( "property1" );
+ $this->setProperty( "property1", "another value" );
+ $value2 = $props->getProperty( "property1" );
+ $this->assertEquals( $value1, $value2, "Single cache" );
+ }
+
+ public function testMultiCache() {
+ $title = $this->the_page->getTitle();
+ $props = new PageProps( $title );
+ $properties1 = $props->getProperties();
+ $this->setProperty( "property1", "another value" );
+ $properties2 = $props->getProperties();
+ $this->assertEquals( $properties1, $properties2, "Multi Cache"
);
+ }
+
+ public function testClearCache() {
+ $title = $this->the_page->getTitle();
+ $props = new PageProps( $title );
+ $value1 = $props->getProperty( "property1" );
+ $this->setProperty( "property1", "another value" );
+ $props->getProperties();
+ $value2 = $props->getProperty( "property1" );
+ $this->assertNotEquals( $value1, $value2, "Clear cache" );
+ }
+
+ protected function createPage( $page, $text, $model = null ) {
+ if ( is_string( $page ) ) {
+ if ( !preg_match( '/:/', $page ) &&
+ ( $model === null || $model ===
CONTENT_MODEL_WIKITEXT )
+ ) {
+ $ns = $this->getDefaultWikitextNS();
+ $page = MWNamespace::getCanonicalName( $ns ) .
':' . $page;
+ }
+
+ $page = Title::newFromText( $page );
+ }
+
+ if ( $page instanceof Title ) {
+ $page = new WikiPage( $page );
+ }
+
+ if ( $page->exists() ) {
+ $page->doDeleteArticle( "done" );
+ }
+
+ $content = ContentHandler::makeContent( $text,
$page->getTitle(), $model );
+ $page->doEditContent( $content, "testing", EDIT_NEW );
+
+ return $page;
+ }
+
+ protected function setProperties( $properties ) {
+
+ $rows = array();
+
+ foreach ( $properties as $propertyName => $propertyValue ) {
+
+ $row = array(
+ 'pp_page' => $this->the_page_id,
+ 'pp_propname' => $propertyName,
+ 'pp_value' => $propertyValue
+ );
+
+ $rows[] = $row;
+ }
+
+ $dbw = wfGetDB( DB_MASTER );
+ $dbw->replace(
+ 'page_props',
+ array (
+ array (
+ 'pp_page',
+ 'pp_propname'
+ )
+ ),
+ $rows,
+ __METHOD__
+ );
+ }
+
+ protected function getProperties() {
+
+ $dbr = wfGetDB( DB_SLAVE );
+ $result = $dbr->select(
+ 'page_props',
+ array(
+ 'pp_propname',
+ 'pp_value'
+ ),
+ array(
+ 'pp_page' => $this->the_page_id,
+ ),
+ __METHOD__
+ );
+
+ $pageProperties = array();
+
+ foreach ( $result as $row ) {
+ $pageProperties[$row->pp_propname] = $row->pp_value;
+ }
+
+ return $pageProperties;
+ }
+ protected function setProperty( $propertyName, $propertyValue ) {
+
+ $properties = array();
+ $properties[$propertyName] = $propertyValue;
+
+ $this->setProperties( $properties );
+
+ }
+}
--
To view, visit https://gerrit.wikimedia.org/r/263581
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I022b9e3ca47dc63650b8a62260603b0893a80e69
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Cicalese <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits