Commit 929e32a4 authored by Volker Krause's avatar Volker Krause
Browse files

Add REST API for sample data import

parent e4a6e145
......@@ -102,6 +102,19 @@ public function get_data($productName)
echo(Sample::dataAsJson($db, $product));
}
/** Import data for a product. */
public function post_data($productName)
{
$db = new DataStore();
$db->beginTransaction();
$product = Product::productByName($db, $productName);
if (is_null($product))
throw RESTException('Unknown product.', 404);
Sample::import($db, file_get_contents('php://input'), $product);
$db->commit();
echo('Data imported.');
}
/** List all surveys for a product. */
public function get_surveys($productName)
{
......
......@@ -112,6 +112,28 @@ class Sample
}
}
/** Insert a array of samples previously exported for @p product.
* Unlike Sample::insert, this will preserve ids and timestamps.
*/
public static function import(DataStore $db, $jsonData, Product $product)
{
$jsonArray = json_decode($jsonData);
if (!is_array($jsonArray))
throw new RESTException('Invalid sample data format.', 400);
foreach ($jsonArray as $sampleObj) {
if (!property_exists($sampleObj, 'id') || !property_exists($sampleObj, 'timestamp'))
throw new RESTException('Invalid sample data.', 400);
self::insertScalar($db, $sampleObj, $product);
foreach ($product->schema as $entry) {
if ($entry->isScalar())
continue;
self::insertNonScalar($db, $sampleObj, $entry, $sampleObj->id);
}
}
}
/** Insert scalar data for @p product.
* @return The sample id for use in non-scalar data tables.
*/
......@@ -121,6 +143,17 @@ class Sample
$binds = array();
$values = array();
if (property_exists($jsonObj, 'id')) {
array_push($columns, 'id');
array_push($binds, ':id');
array_push($values, intval($jsonObj->id));
}
if (property_exists($jsonObj, 'timestamp')) {
array_push($columns, 'timestamp');
array_push($binds, ':timestamp');
array_push($values, $jsonObj->timestamp);
}
foreach ($product->schema as $entry) {
if (!$entry->isScalar())
continue;
......
......@@ -132,4 +132,52 @@ class SurveyTest extends PHPUnit_Extensions_Database_TestCase
Sample::insert(self::$db, $input, $p);
}
public function testImport()
{
$p = Product::productByName(self::$db, 'org.kde.UnitTest');
$this->assertNotNull($p);
$p->name = 'org.kde.MyCleanProduct';
$p->insert(self::$db);
$input = '[{
"id": 42,
"timestamp": "2016-12-18 12:42:35",
"entry1": { "element11": "firstString" },
"entry2": [ { "element21": 12 } ]
}, {
"id": 43,
"timestamp": "2016-12-19 15:12:10",
"entry1": { "element12": true },
"entry2": [ { "element22": 1.3 } ]
}]';
Sample::import(self::$db, $input, $p);
$output = Sample::dataAsJson(self::$db, $p);
$this->assertJsonStringEqualsJsonString($input, $output);
}
public function testInvalidImport_data()
{
return [
'nothing' => [ '' ],
'empty' => [ '{}' ],
'object' => [ '{ "id": 42, "timestamp": "2016-12-18 12:42:35" }' ],
'missing id' => [ '{ "timestamp": "2016-12-18 12:42:35" }' ],
'missing timestamp' => [ '{ "id": 42 }' ]
];
}
/**
* @dataProvider testInvalidImport_data
* @expectedException RESTException
* @exceptedExceptionCode 400
*/
public function testInvalidImport($input)
{
$p = Product::productByName(self::$db, 'org.kde.UnitTest');
$this->assertNotNull($p);
Sample::import(self::$db, $input, $p);
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment