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');
 }