/** * Returns a DataTable that has the name '$name' from the current Archive. * If $idSubTable is specified, returns the subDataTable called '$name_$idSubTable' * * @param string $name * @param int $idSubTable optional id SubDataTable * @return Piwik_DataTable */ public function getDataTable($name, $idSubTable = null) { if (!is_null($idSubTable)) { $name .= "_{$idSubTable}"; } $this->setRequestedReport($name); $data = $this->get($name, 'blob'); $table = new Piwik_DataTable(); if ($data !== false) { $table->addRowsFromSerializedArray($data); } if ($data === false && $idSubTable !== null) { // This is not expected, but somehow happens in some unknown cases and very rarely. // Do not throw error in this case // throw new Exception("not expected"); return new Piwik_DataTable(); } return $table; }
/** * General tests that tries to test the normal behaviour of DataTable * * We create some tables, add rows, some of the rows link to sub tables * * Then we serialize everything, and we check that the unserialize give the same object back * * @group Core * @group DataTable */ public function testGeneral() { /* * create some fake tables to make sure that the serialized array of the first TABLE * does not take in consideration those tables */ $useless1 = new Piwik_DataTable(); $useless1->addRowFromArray(array(Piwik_DataTable_Row::COLUMNS => array(13))); /* * end fake tables */ /* * MAIN TABLE */ $table = new Piwik_DataTable(); $subtable = new Piwik_DataTable(); $idtable = $table->getId(); $idsubtable = $subtable->getId(); /* * create some fake tables to make sure that the serialized array of the first TABLE * does not take in consideration those tables * -> we check that the DataTable_Manager is not impacting DataTable */ $useless2 = new Piwik_DataTable(); $useless1->addRowFromArray(array(Piwik_DataTable_Row::COLUMNS => array(8487))); $useless3 = new Piwik_DataTable(); $useless3->addRowFromArray(array(Piwik_DataTable_Row::COLUMNS => array(8487))); /* * end fake tables */ $row = array(Piwik_DataTable_Row::COLUMNS => array(0 => 1554, 1 => 42, 2 => 657, 3 => 155744), Piwik_DataTable_Row::METADATA => array('logo' => 'test.png')); $row = new Piwik_DataTable_Row($row); $table->addRow($row); $table->addRowFromArray(array(Piwik_DataTable_Row::COLUMNS => array(0 => 1554, 1 => 42), Piwik_DataTable_Row::METADATA => array('url' => 'piwik.org'))); $table->addRowFromArray(array(Piwik_DataTable_Row::COLUMNS => array(0 => 787877888787.0), Piwik_DataTable_Row::METADATA => array('url' => 'OUPLA ADDED'), Piwik_DataTable_Row::DATATABLE_ASSOCIATED => $subtable)); /* * SUB TABLE */ $row = array(Piwik_DataTable_Row::COLUMNS => array(0 => 1554), Piwik_DataTable_Row::METADATA => array('searchengine' => 'google')); $subtable->addRowFromArray($row); $row = array(Piwik_DataTable_Row::COLUMNS => array(0 => 84894), Piwik_DataTable_Row::METADATA => array('searchengine' => 'yahoo')); $subtable->addRowFromArray($row); $row = array(Piwik_DataTable_Row::COLUMNS => array(0 => 4898978989.0), Piwik_DataTable_Row::METADATA => array('searchengine' => 'ask')); $subtable->addRowFromArray($row); /* * SUB SUB TABLE */ $subsubtable = new Piwik_DataTable(); $subsubtable->addRowFromArray(array(Piwik_DataTable_Row::COLUMNS => array(245), Piwik_DataTable_Row::METADATA => array('yes' => 'subsubmetadata1'))); $subsubtable->addRowFromArray(array(Piwik_DataTable_Row::COLUMNS => array(13), Piwik_DataTable_Row::METADATA => array('yes' => 'subsubmetadata2'))); $row = array(Piwik_DataTable_Row::COLUMNS => array(0 => 666666666666666.0), Piwik_DataTable_Row::METADATA => array('url' => 'NEW ROW ADDED'), Piwik_DataTable_Row::DATATABLE_ASSOCIATED => $subsubtable); $subtable->addRowFromArray($row); $idsubsubtable = $subsubtable->getId(); $serialized = $table->getSerialized(); $this->assertEquals(array_keys($serialized), array($idsubsubtable, $idsubtable, 0)); // In the next test we compare an unserialized datatable with its original instance. // The unserialized datatable rows will have positive DATATABLE_ASSOCIATED ids. // Positive DATATABLE_ASSOCIATED ids mean that the associated sub-datatables are not loaded in memory. // In this case, this is NOT true: we know that the sub-datatable is loaded in memory. // HOWEVER, because of datatable id conflicts happening in the datatable manager, it is not yet // possible to know, after unserializing a datatable, if its sub-datatables are loaded in memory. $expectedTableRows = array(); foreach ($table->getRows() as $currentRow) { $expectedTableRow = clone $currentRow; $currentRowAssociatedDatatableId = $currentRow->c[Piwik_DataTable_Row::DATATABLE_ASSOCIATED]; if ($currentRowAssociatedDatatableId != null) { // making DATATABLE_ASSOCIATED ids positive $expectedTableRow->c[Piwik_DataTable_Row::DATATABLE_ASSOCIATED] = -1 * $currentRowAssociatedDatatableId; } $expectedTableRows[] = $expectedTableRow; } $tableAfter = new Piwik_DataTable(); $tableAfter->addRowsFromSerializedArray($serialized[0]); $this->assertEquals($expectedTableRows, $tableAfter->getRows()); $subsubtableAfter = new Piwik_DataTable(); $subsubtableAfter->addRowsFromSerializedArray($serialized[$idsubsubtable]); $this->assertEquals($subsubtable->getRows(), $subsubtableAfter->getRows()); $this->assertEquals($table, Piwik_DataTable_Manager::getInstance()->getTable($idtable)); $this->assertEquals($subsubtable, Piwik_DataTable_Manager::getInstance()->getTable($idsubsubtable)); }
/** * Returns a DataTable that has the name '$name' from the current Archive. * If $idSubTable is specified, returns the subDataTable called '$name_$idSubTable' * * @param string $name * @param int $idSubTable optional id SubDataTable * @return Piwik_DataTable */ public function getDataTable($name, $idSubTable = null) { if (!is_null($idSubTable)) { $name .= "_{$idSubTable}"; } $data = $this->get($name, 'blob'); $table = new Piwik_DataTable(); if ($data !== false) { $table->addRowsFromSerializedArray($data); } if ($data === false && $idSubTable !== null) { throw new Exception("You are requesting a precise subTable but there is not such data in the Archive."); } return $table; }
/** * General tests that tries to test the normal behaviour of DataTable * * We create some tables, add rows, some of the rows link to sub tables * * Then we serialize everything, and we check that the unserialize give the same object back */ function test_general() { /* * create some fake tables to make sure that the serialized array of the first TABLE * does not take in consideration those tables */ $useless1 = new Piwik_DataTable(); $useless1->addRowFromArray(array(Piwik_DataTable_Row::COLUMNS => array(13))); /* * end fake tables */ /* * MAIN TABLE */ $table = new Piwik_DataTable(); $subtable = new Piwik_DataTable(); $idtable = $table->getId(); $idsubtable = $subtable->getId(); /* * create some fake tables to make sure that the serialized array of the first TABLE * does not take in consideration those tables * -> we check that the DataTable_Manager is not impacting DataTable */ $useless2 = new Piwik_DataTable(); $useless1->addRowFromArray(array(Piwik_DataTable_Row::COLUMNS => array(8487))); $useless3 = new Piwik_DataTable(); $useless3->addRowFromArray(array(Piwik_DataTable_Row::COLUMNS => array(8487))); /* * end fake tables */ $row = array(Piwik_DataTable_Row::COLUMNS => array(0 => 1554, 1 => 42, 2 => 657, 3 => 155744), Piwik_DataTable_Row::METADATA => array('logo' => 'test.png')); $row = new Piwik_DataTable_Row($row); $table->addRow($row); $table->addRowFromArray(array(Piwik_DataTable_Row::COLUMNS => array(0 => 1554, 1 => 42), Piwik_DataTable_Row::METADATA => array('url' => 'piwik.org'))); $table->addRowFromArray(array(Piwik_DataTable_Row::COLUMNS => array(0 => 787877888787), Piwik_DataTable_Row::METADATA => array('url' => 'OUPLA ADDED'), Piwik_DataTable_Row::DATATABLE_ASSOCIATED => $subtable)); /* * SUB TABLE */ $row = array(Piwik_DataTable_Row::COLUMNS => array(0 => 1554), Piwik_DataTable_Row::METADATA => array('searchengine' => 'google')); $subtable->addRowFromArray($row); $row = array(Piwik_DataTable_Row::COLUMNS => array(0 => 84894), Piwik_DataTable_Row::METADATA => array('searchengine' => 'yahoo')); $subtable->addRowFromArray($row); $row = array(Piwik_DataTable_Row::COLUMNS => array(0 => 4898978989), Piwik_DataTable_Row::METADATA => array('searchengine' => 'ask')); $subtable->addRowFromArray($row); /* * SUB SUB TABLE */ $subsubtable = new Piwik_DataTable(); $subsubtable->addRowFromArray(array(Piwik_DataTable_Row::COLUMNS => array(245), Piwik_DataTable_Row::METADATA => array('yes' => 'subsubmetadata1'))); $subsubtable->addRowFromArray(array(Piwik_DataTable_Row::COLUMNS => array(13), Piwik_DataTable_Row::METADATA => array('yes' => 'subsubmetadata2'))); $row = array(Piwik_DataTable_Row::COLUMNS => array(0 => 666666666666666), Piwik_DataTable_Row::METADATA => array('url' => 'NEW ROW ADDED'), Piwik_DataTable_Row::DATATABLE_ASSOCIATED => $subsubtable); $subtable->addRowFromArray($row); $idsubsubtable = $subsubtable->getId(); $serialized = $table->getSerialized(); $this->assertEqual(array_keys($serialized), array($idsubsubtable, $idsubtable, 0)); $tableAfter = new Piwik_DataTable(); $tableAfter->addRowsFromSerializedArray($serialized[0]); $this->assertEqual($table->getRows(), $tableAfter->getRows()); $subsubtableAfter = new Piwik_DataTable(); $subsubtableAfter->addRowsFromSerializedArray($serialized[$idsubsubtable]); $this->assertEqual($subsubtable->getRows(), $subsubtableAfter->getRows()); $this->assertEqual($table, Piwik_DataTable_Manager::getInstance()->getTable($idtable)); $this->assertEqual($subsubtable, Piwik_DataTable_Manager::getInstance()->getTable($idsubsubtable)); }
/** * Utility function. Gets row count of a set of tables grouped by the 'name' column. * This is the implementation of the getRowCountsAndSizeBy... functions. */ private function getRowCountsByArchiveName($statuses, $getRowSizeMethod, $forceCache = false, $otherSelects = array(), $otherDataTableColumns = array()) { $extraCols = ''; if (!empty($otherSelects)) { $extraCols = ', ' . implode(', ', $otherSelects); } $cols = array_merge(array('row_count'), $otherDataTableColumns); $dataTable = new Piwik_DataTable(); foreach ($statuses as $status) { $dataTableOptionName = $this->getCachedOptionName($status['Name'], 'byArchiveName'); // if option exists && !$forceCache, use the cached data, otherwise create the $cachedData = Piwik_GetOption($dataTableOptionName); if ($cachedData !== false && !$forceCache) { $table = new Piwik_DataTable(); $table->addRowsFromSerializedArray($cachedData); } else { // otherwise, create data table & cache it $sql = "SELECT name as 'label', COUNT(*) as 'row_count'{$extraCols} FROM {$status['Name']} GROUP BY name"; $table = new Piwik_DataTable(); $table->addRowsFromSimpleArray(Piwik_FetchAll($sql)); $reduceArchiveRowName = array($this, 'reduceArchiveRowName'); $table->filter('GroupBy', array('label', $reduceArchiveRowName)); $serializedTables = $table->getSerialized(); $serializedTable = reset($serializedTables); Piwik_SetOption($dataTableOptionName, $serializedTable); } // add estimated_size column $getEstimatedSize = array($this, $getRowSizeMethod); $table->filter('ColumnCallbackAddColumn', array($cols, 'estimated_size', $getEstimatedSize, array($status))); $dataTable->addDataTable($table); destroy($table); } return $dataTable; }