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 function testSetDataTable()
 {
     $request = new Request();
     $data = new DataTable();
     $data->addColumn(new ColumnDescription('textfield', ValueType::STRING));
     $data->addColumn(new ColumnDescription('intfield', ValueType::NUMBER));
     $response = new Response($request);
     $response->setDataTable($data);
     $getRequest = $response->getRequest();
     $getDataTable = $response->getDataTable();
     $this->assertEquals($request, $getRequest, "Request must match");
     $this->assertEquals($data, $getDataTable, "DataTable must match");
 }
 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');
 }
 /**
  * @param int $rowIndex
  * @return PivotKey reference
  */
 public function &getKeyRefByRowIndex($rowIndex)
 {
     $row = $this->dataTable->getRow($rowIndex);
     $columnValues = array();
     foreach ($this->columnIndexes as $ci) {
         $columnValues[] = $row->getCell($ci)->getValue()->getRawValue();
     }
     $hash = PivotKey::hash($columnValues);
     if (!isset($this->keys[$hash])) {
         $this->keys[$hash] = new PivotKey($columnValues);
     }
     $key =& $this->keys[$hash];
     return $key;
 }
 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;
 }
 /**
  * @param array $fields List of field ids
  * @param string $typeName
  * @throws InvalidFieldNameException if one of the fields does not exist
  */
 public function verifyTheseFieldsExist($fields, $typeName)
 {
     foreach ($fields as $field) {
         try {
             $this->dataTable->getColumnDescriptionById($field);
         } catch (NoSuchColumnIdException $e) {
             throw new InvalidFieldNameException($field, $typeName, 0, $e);
         }
     }
 }
 /**
  * @param Request $request
  * @return DataTable
  */
 public function &getDataTable(Request $request)
 {
     $data = new DataTable();
     $data->addColumn(new ColumnDescription('date', ValueType::DATE, 'Date'));
     $data->addColumn(new ColumnDescription('income', ValueType::NUMBER, 'Gross Income'));
     $data->addColumn(new ColumnDescription('expense', ValueType::NUMBER, 'Expenses'));
     $data->addColumn(new ColumnDescription('net', ValueType::NUMBER, 'Net Income'));
     for ($i = 0; $i < 10; $i++) {
         $date = "2013-01-" . sprintf("%02d", 1 + $i);
         $income = 1000 + rand(0, (1 + $i) * 10);
         $expense = -800 - rand(0, (1 + $i) * 10);
         $data->addRow(new TableRow(array(new Date($date), $income, $expense, $income + $expense)));
     }
     return $data;
 }
 public function setUp()
 {
     $data = new DataTable();
     // DO NOT change the order of this stuff it will break the tests
     $data->addColumn(new ColumnDescription('day', ValueType::DATE, 'Date'));
     $data->addColumn(new ColumnDescription('country', ValueType::STRING, 'Country'));
     $data->addColumn(new ColumnDescription('region', ValueType::STRING, 'Region'));
     $data->addColumn(new ColumnDescription('income', ValueType::NUMBER, 'Income'));
     $data->addColumn(new ColumnDescription('expense', ValueType::NUMBER, 'Expense'));
     // DO NOT change the order of this stuff it will break the tests
     $this->rawData = array(array(new Date('2013-10-01'), 'US', 'TX', 1000, 900), array(new Date('2013-10-01'), 'US', 'CA', 1000, 900), array(new Date('2013-10-01'), 'US', 'WA', 1000, 900), array(new Date('2013-10-02'), 'US', 'TX', 1000, 900), array(new Date('2013-10-02'), 'US', 'WA', 1000, 900), array(new Date('2013-10-03'), 'US', 'TX', 1000, 900), array(new Date('2013-10-03'), 'US', 'WA', 1000, 900));
     foreach ($this->rawData as $row) {
         $data->addRow(new TableRow($row));
     }
     $this->dataTable = $data;
 }
 /**
  * Render the DataTable as a string
  *
  * This may result in different output depending on the
  * output type in the request.
  */
 public function __toString()
 {
     try {
         $renderer = $this->getRenderer();
         // If there were any warnings generating this DataTable, we must send them
         // in the response and set the response status to WARNING
         $responseStatus = $this->responseStatus;
         if ($responseStatus === null) {
             if ($this->data->getNumberOfWarnings() > 0) {
                 $responseStatus = new ResponseStatus(new StatusType(StatusType::WARNING));
             }
         }
         $output = $renderer->render($this, $responseStatus);
         return $output;
     } catch (\Exception $e) {
         throw new RenderFailureException($e);
     }
 }
 /**
  * @param Request $request
  * @return DataTable
  */
 public function &getDataTable(Request $request)
 {
     $data = new DataTable();
     $data->addColumn(new ColumnDescription('date', ValueType::DATE, 'Date'));
     $data->addColumn(new ColumnDescription('country', ValueType::STRING, 'Country'));
     $data->addColumn(new ColumnDescription('region', ValueType::STRING, 'Region'));
     $data->addColumn(new ColumnDescription('income', ValueType::NUMBER, 'Income'));
     $data->addColumn(new ColumnDescription('expense', ValueType::NUMBER, 'Expense'));
     $countryRegions = array('US' => array('TX', 'CA', 'WA'), 'CA' => array(null));
     for ($i = 0; $i < 10; $i++) {
         $date = "2013-01-" . sprintf("%02d", 1 + $i);
         foreach ($countryRegions as $country => $regions) {
             foreach ($regions as $region) {
                 $income = 1000 + rand(0, (1 + $i) * 10);
                 $expense = -800 - rand(0, (1 + $i) * 10);
                 $row = new TableRow(array(new Date($date), $country, $region, $income, $expense));
                 $data->addRow($row);
             }
         }
     }
     return $data;
 }
 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 testGetCustomNonexistentProperty()
 {
     $data = new DataTable('first', ValueType::STRING);
     $this->assertNull($data->getCustomProperty('no-such-property'), "Expect null return for no-such-property");
 }
 /**
  * @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;
 }
 public function testVerifyFieldNamesDoesNotThrowForValidNames()
 {
     $pivot = new PivotDescription($this->dataTable);
     $allColumnIds = $pivot->getAllColumnIds($this->dataTable->getColumnDescriptions());
     $pivot->verifyTheseFieldsExist($allColumnIds, 'test');
 }