public function testDataReductionWithPivot() { $text = 'select sum(income) pivot country'; $query = Query::constructFromString($text); $result =& QueryEngine::reduceData($query, $this->dataTable); $this->assertNotSame($result, $this->dataTable, "Expect new DataTable when selection is narrowed"); $this->assertSame(2, $result->getNumberOfColumns(), "Expect there are only 2 columns in the result"); $this->assertSame($this->dataTable->getNumberOfRows(), $result->getNumberOfRows(), "Expect the number of rows stays the same"); // Make sure the income column exists (exception is thrown otherwise) $result->getColumnDescriptionById('income'); // Make sure the country column exists (exception is thrown otherwise) $result->getColumnDescriptionById('country'); }
public static function &reduceData(Query $query, DataTable &$data) { // If we aren't narrowing the selection, return the source data $select = $query->getSelect(); if ($select === null) { return $data; } // Get a list of the fields we want to select $selectFieldIds = $select->getAllColumnIds(); $neededFieldIds = $selectFieldIds; // If we're going to pivot, we also need to preserve any/all // of the pivot fields. $pivot = $query->getPivot(); if ($pivot !== null) { $neededFieldIds = array_merge($neededFieldIds, $pivot->getAllColumnIds()); } // Keep just the unique field ids we need $neededFieldIds = array_unique($neededFieldIds); // If the number of unique selected fields equals the number of // input columns, we need all the data in the source table, so // just return the source table itself. $numInputColumns = $data->getNumberOfColumns(); if (count($neededFieldIds) == $numInputColumns) { return $data; } // We're removing at least one column from the source table $result = new DataTable(); // Copy the columns we're saving $preservedColumnIndexes = array(); for ($ci = 0; $ci < $numInputColumns; $ci++) { $column = $data->getColumnDescription($ci); if (!in_array($column->getId(), $neededFieldIds)) { continue; } $result->addColumn($column); $preservedColumnIndexes[] = $ci; } // For each row, copy the cells from the columns we're saving $numInputRows = $data->getNumberOfRows(); for ($ri = 0; $ri < $numInputRows; $ri++) { $inputRow = $data->getRow($ri); // Copy just the columns we're saving $row = new TableRow(); foreach ($preservedColumnIndexes as $ci) { $row->addCell($inputRow->getCell($ci)); } $result->addRow($row); } return $result; }
public function testNullCellTypeCast() { $data = new DataTable(); // a number column $data->addColumn(new ColumnDescription('val', ValueType::NUMBER)); // add a NULL string value to the number column $row = new TableRow(); $row->addCell(new TextValue(null)); $data->addRow($row); // It should have been casted to a NULL number value $value = $data->getRow(0)->getCell(0)->getValue(); $this->assertSame(1, $data->getNumberOfRows(), "row count must match"); $this->assertTrue($value instanceof NumberValue, "expect a TimeOfDayValue in the table"); $this->assertTrue($value->isNull(), "expect value->isNull == true"); }
/** * @param DataTable $dataTable * @param bool $includeValues [optional] * @param bool $includeFormatting [optional] * @param bool $renderDateAsDateConstructor [optional] * @return string JSON encoded string describing $dataTable */ public function renderDataTable(DataTable $dataTable, $includeValues = true, $includeFormatting = true, $renderDateAsDateConstructor = true) { $numColumns = $dataTable->getNumberOfColumns(); $columns = $dataTable->getColumnDescriptions(); $output = "{"; $output .= "\"cols\":["; for ($i = 0; $i < $numColumns; $i++) { $column = $columns[$i]; $output .= $this->renderColumnDescriptionJson($column); if ($i + 1 < $numColumns) { $output .= ","; } } $output .= "]"; if ($includeValues) { $numRows = $dataTable->getNumberOfRows(); $output .= ",\"rows\":["; for ($ri = 0; $ri < $numRows; $ri++) { $row = $dataTable->getRow($ri); $numCells = $row->getNumberOfCells(); $output .= "{\"c\":["; for ($ci = 0; $ci < $numCells; $ci++) { $cell = $row->getCell($ci); if ($ci + 1 < $numCells) { // For fields that are NOT the last field, renderCellJson() may return // an empty string if the value is NULL // @see https://code.google.com/p/google-visualization-java/source/browse/trunk/src/main/java/com/google/visualization/datasource/render/JsonRenderer.java $cellOutput = $this->renderCellJson($cell, $includeFormatting, $this->optimizeNullValues, $renderDateAsDateConstructor); $cellOutput .= ","; } else { // For fields that ARE the last field, a JSON string is returned // even for NULL values $cellOutput = $this->renderCellJson($cell, $includeFormatting, false, $renderDateAsDateConstructor); } $output .= $cellOutput; } $output .= "]"; // Row properties $customProperties = $this->renderCustomPropertiesString($row->getCustomProperties()); if ($customProperties !== null) { $output .= ",\"p\":" . $customProperties; } $output .= "}"; if ($ri + 1 < $numRows) { $output .= ","; } } $output .= "]"; } // Table properties $customProperties = $this->renderCustomPropertiesString($dataTable->getCustomProperties()); if ($customProperties !== null) { $output .= ",\"p\":" . $customProperties; } $output .= "}"; return $output; }