/**
  * @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 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);
     }
 }
 public function testNullTimeOfDay()
 {
     $value = ValueFactory::constructNull(ValueType::TIMEOFDAY);
     $this->assertTrue($value instanceof TimeOfDayValue);
 }