diff options
author | diosmosis <diosmosis@users.noreply.github.com> | 2019-07-29 23:08:46 +0300 |
---|---|---|
committer | Thomas Steur <tsteur@users.noreply.github.com> | 2019-07-29 23:08:46 +0300 |
commit | 77e879bc4d86f9e8584415f575040a89f872edd6 (patch) | |
tree | bb26eac87188ef70f7c543e52287ab97495ff3df | |
parent | 868bb88a7abf961f6f723c1a053a670f1b04913e (diff) |
Save DataTable metadata in records if added during archiving. (#14671)3.12.0-b1
* Save DataTable metadata in records if added during archiving.
* Use descriptive and rare string row label.
-rw-r--r-- | core/DataTable.php | 34 | ||||
-rw-r--r-- | tests/PHPUnit/Unit/DataTableTest.php | 37 |
2 files changed, 70 insertions, 1 deletions
diff --git a/core/DataTable.php b/core/DataTable.php index 727cc5dd01..356ce86f69 100644 --- a/core/DataTable.php +++ b/core/DataTable.php @@ -200,9 +200,17 @@ class DataTable implements DataTableInterface, \IteratorAggregate, \ArrayAccess /** The ID of the Summary Row. */ const ID_SUMMARY_ROW = -1; + /** + * The ID of the special metadata row. This row only exists in the serialized row data and stores the datatable metadata. + * + * This allows us to save datatable metadata in archive data. + */ + const ID_ARCHIVED_METADATA_ROW = -3; + /** The original label of the Summary Row. */ const LABEL_SUMMARY_ROW = -1; const LABEL_TOTALS_ROW = -2; + const LABEL_ARCHIVED_METADATA_ROW = '__datatable_metadata__'; /** * Name for metadata that contains extra {@link Piwik\Plugin\ProcessedMetric}s for a DataTable. @@ -1291,6 +1299,15 @@ class DataTable implements DataTableInterface, \IteratorAggregate, \ArrayAccess $subtableId = 0; throw new Exception("Maximum recursion level of " . self::$maximumDepthLevelAllowed . " reached. Maybe you have set a DataTable\Row with an associated DataTable belonging already to one of its parent tables?"); } + + // gather metadata before filters are called, so their metadata is not stored in serialized form + $metadata = $this->getAllTableMetadata(); + foreach ($metadata as $key => $value) { + if (!is_scalar($value) && !is_string($value)) { + unset($metadata[$key]); + } + } + if (!is_null($maximumRowsInDataTable)) { $this->filter('Truncate', array($maximumRowsInDataTable - 1, @@ -1341,6 +1358,16 @@ class DataTable implements DataTableInterface, \IteratorAggregate, \ArrayAccess $rows[self::ID_SUMMARY_ROW] = $this->summaryRow->export(); } + if (!empty($metadata)) { + $metadataRow = new Row(); + $metadataRow->setColumns($metadata); + + // set the label so the row will be indexed correctly internally + $metadataRow->setColumn('label', self::LABEL_ARCHIVED_METADATA_ROW); + + $rows[self::ID_ARCHIVED_METADATA_ROW] = $metadataRow->export(); + } + $aSerializedDataTable[$forcedId] = serialize($rows); unset($rows); @@ -1402,6 +1429,13 @@ class DataTable implements DataTableInterface, \IteratorAggregate, \ArrayAccess unset($rows[self::ID_SUMMARY_ROW]); } + if (array_key_exists(self::ID_ARCHIVED_METADATA_ROW, $rows)) { + $metadata = $rows[self::ID_ARCHIVED_METADATA_ROW][Row::COLUMNS]; + unset($metadata['label']); + $this->setAllTableMetadata($metadata); + unset($rows[self::ID_ARCHIVED_METADATA_ROW]); + } + foreach ($rows as $id => $row) { if (isset($row->c)) { $this->addRow(new Row($row->c)); // Pre Piwik 2.13 diff --git a/tests/PHPUnit/Unit/DataTableTest.php b/tests/PHPUnit/Unit/DataTableTest.php index 424fce0186..fbc1f5adee 100644 --- a/tests/PHPUnit/Unit/DataTableTest.php +++ b/tests/PHPUnit/Unit/DataTableTest.php @@ -12,6 +12,7 @@ use Piwik\Common; use Piwik\DataTable\Manager; use Piwik\DataTable\Row; use Piwik\DataTable; +use Piwik\Date; use Piwik\Timer; use Symfony\Component\VarDumper\Cloner\Data; @@ -672,7 +673,9 @@ class DataTableTest extends \PHPUnit_Framework_TestCase $subtableId = $row[Row::DATATABLE_ASSOCIATED]; - if ($row[Row::COLUMNS]['label'] === DataTable::LABEL_SUMMARY_ROW) { + if ($row[Row::COLUMNS]['label'] === DataTable::LABEL_SUMMARY_ROW + || $row[Row::COLUMNS]['label'] === DataTable::LABEL_ARCHIVED_METADATA_ROW + ) { $this->assertNull($subtableId); } else { @@ -713,6 +716,38 @@ class DataTableTest extends \PHPUnit_Framework_TestCase ), $tables); } + public function test_serializationOfDataTableMetadata() + { + $table = new DataTable(); + $table->addRow(new Row([ + Row::COLUMNS => ['label' => 'abc', 'nb_visits' => 5], + ])); + $table->setAllTableMetadata([ + 'str' => 'str value', + 'int' => 5, + 'float' => 3.65, + 'bool' => true, + 'object' => Date::today(), + ]); + + $serialized = $table->getSerialized(); + + $newTable = DataTable::fromSerializedArray(reset($serialized)); + + $this->assertEquals([ + new Row([ + Row::COLUMNS => ['label' => 'abc', 'nb_visits' => 5], + ]), + ], $newTable->getRows()); + + $this->assertEquals([ + 'str' => 'str value', + 'int' => 5, + 'float' => 3.65, + 'bool' => true, + ], $newTable->getAllTableMetadata()); + } + private function addManyRows(DataTable $table, $numRows) { for ($i = 0; $i < $numRows; $i++) { |