public function setUp() { $request = new Request(); $data = new DataTable(); $data->addColumn(new ColumnDescription('date', ValueType::DATE)); $data->addColumn(new ColumnDescription('name', ValueType::STRING)); $data->addColumn(new ColumnDescription('count', ValueType::NUMBER)); $row = new TableRow(); $row->addCell(new TableCell(new DateValue(new Date('2013-10-19')))); $row->addCell(new TableCell(new TextValue('eleven'))); $row->addCell(new TableCell(new NumberValue(11))); $data->addRow($row); $row = new TableRow(); $row->addCell(new TableCell(new DateValue(new Date('2013-01-01')))); $row->addCell(new TableCell(new TextValue('twenty_three'))); $row->addCell(new TableCell(new NumberValue(23))); $data->addRow($row); // A row with a NULL value in the middle $row = new TableRow(); $row->addCell(new TableCell(new DateValue(new Date('2013-07-01')))); $row->addCell(new TableCell(new TextValue(null))); $row->addCell(new TableCell(new NumberValue(35))); $data->addRow($row); // A row with a NULL value in the last cell $row = new TableRow(); $row->addCell(new TableCell(new DateValue(new Date('1999-12-31')))); $row->addCell(new TableCell(new TextValue('null_value'))); $row->addCell(new TableCell(new NumberValue(null))); $data->addRow($row); $this->dataTable = $data; $this->response = new Response($request); $this->response->setDataTable($data); }
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 addOutputRows(DataTable &$dataOut) { $dataIn =& $this->pivotDescription->getDataTable(); $columns = $dataOut->getColumnDescriptions(); foreach ($this->table as $rk => $rowTable) { $row = new TableRow(); foreach ($columns as $column) { $ck = $column->getCustomProperty('columnKeyId'); if ($ck === null) { $rowKey = $this->rowKeyIndex->getKeyRefByHash($rk); $firstRowIndex = $rowKey->getFirstRowIndex(); $rowFieldIndex = $column->getCustomProperty('rowFieldIndex'); $cell = $dataIn->getRow($firstRowIndex)->getCell($rowFieldIndex); $row->addCell($cell); } else { // This is a computed data field $di = $column->getCustomProperty('dataFieldIndex'); if (isset($this->table[$rk][$ck][$di])) { $dataContainer = $this->table[$rk][$ck][$di]; $value = $dataContainer->getComputedValue(); } else { $value = ValueFactory::constructNull($column->getType()); } $row->addCell($value); } } $dataOut->addRow($row); } }
/** * @param TableRow $row * @throws ColumnCountMismatchException * @throws Exception * @throws NotImplementedException * @throws ValueTypeMismatchException */ public function addRow(TableRow $row) { if ($this->columnCount == 0) { throw new Exception("You must add columns to a DataTable before you add rows"); } // Check to make sure the number of columns in the row // matches the number of columns in our table $rowCellCount = $row->getNumberOfCells(); if ($rowCellCount != $this->columnCount) { throw new ColumnCountMismatchException($this->columnCount, $rowCellCount); } // Check the data type of each cell to ensure it matches // the data type we expect for that column $cells = $row->getCells(); for ($i = 0; $i < $this->columnCount; $i++) { $columnDataType = $this->columns[$i]->getType(); $cellValue = $cells[$i]->getValue(); $cellValueType = $cellValue->getType(); if ($columnDataType->getCode() != $cellValueType->getCode()) { $castedCell = false; if ($cellValue->isNull()) { // Create a new null cell of the appropriate type $castedCell = clone $cells[$i]; $castedCell->setValue(ValueFactory::constructNull($columnDataType)); } else { if ($columnDataType->getCode() == ValueType::BOOLEAN) { switch ($cellValueType->getCode()) { case ValueType::STRING: $bool = $cellValue->getRawValue() === 'true'; $castedCell = clone $cells[$i]; $castedCell->setValue(new BooleanValue($bool)); break; default: break; } } else { if ($columnDataType->getCode() == ValueType::NUMBER) { switch ($cellValueType->getCode()) { case ValueType::STRING: $castedCell = clone $cells[$i]; $castedCell->setValue(new NumberValue($cellValue->getRawValue())); break; default: break; } } else { if ($columnDataType->isDateValue()) { // This column is supposed to have a date, be pretty flexible // what kind of input data we have. // // Cast from whatever types we can to the date type. This may be // casting from a string to a date, or casting from one type of // date value to another. $castedCell = clone $cells[$i]; $rawValue = $cellValue->getRawValue(); switch ($columnDataType->getCode()) { case ValueType::DATE: $castedCell->setValue(new DateValue($rawValue)); break; case ValueType::DATETIME: $castedCell->setValue(new DateTimeValue($rawValue)); break; case ValueType::TIMEOFDAY: $castedCell->setValue(new TimeOfDayValue($rawValue)); break; default: throw new NotImplementedException("Not Implemented: Some sort of new date type?"); break; } } } } } // If no new cell was created that has been casted to the appropriate // type, there is a ValueType mismatch exception if (!$castedCell) { throw new ValueTypeMismatchException($columnDataType, $i); } // Assign the casted cell to the row $row->setCell($i, $castedCell); } } // Add the row to the table $this->rows[] = $row; $this->rowCount++; }
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"); }
public function testSetCellInvalidIndex() { $row = new TableRow(); $this->setExpectedException('\\Vube\\GoogleVisualization\\DataSource\\Exception\\IndexOutOfBoundsException'); $row->setCell(0, 'value'); }