Skip to content

Commit

Permalink
close #9 - added interfaces for working with resources, adding / dele…
Browse files Browse the repository at this point in the history
…ting
  • Loading branch information
OriHoch committed May 11, 2017
1 parent ab947af commit 1157c31
Show file tree
Hide file tree
Showing 3 changed files with 157 additions and 1 deletion.
19 changes: 18 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use frictionlessdata\datapackage;
// get a datapackage object
$datapackage = datapackage\Factory::datapackage("tests/fixtures/multi_data_datapackage.json");

// iterate over the data
// iterate over the data - it will raise exceptions in case of any problems
foreach ($datapackage as $resource) {
print("-- ".$resource->name()." --");
$i = 0;
Expand All @@ -45,6 +45,23 @@ if (count($validationErrors) == 0) {
} else {
print(datapackage\Validators\DatapackageValidationError::getErrorMessages($validationErrors));
}

// get and manipulate resources
$resources = $datapackage->resources();
$resources["resource-name"]->name() == "resource-name"
$resources["another-resource-name"] // BaseResource based object (e.g. DefaultResource / TabularResource)

// get a single resource by name
$datapackage->resource("resource-name")

// delete a resource by name - will raise exception in case of validation failure for the new descriptor
$datapackage->deleteResource("resource-name");

// add a resource - will raise exception in case of validation error for the new descriptor
$resource = Factory::resource((object)[
"name" => "new-resource", "data" => ["tests/fixtures/foo.txt", "tests/fixtures/baz.txt"]
])
$datapackage->addResource($resource);
```


Expand Down
43 changes: 43 additions & 0 deletions src/Datapackages/BaseDatapackage.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ public function __construct($descriptor, $basePath=null)
{
$this->descriptor = $descriptor;
$this->basePath = $basePath;
$this->revalidate();
}

public function revalidate()
{
$this->rewind();
$validationErrors = $this->datapackageValidate();
if (count($validationErrors) > 0) {
throw new DatapackageValidationFailedException($validationErrors);
Expand All @@ -32,6 +38,43 @@ public function descriptor()
return $this->descriptor;
}

public function resources()
{
$resources = [];
foreach ($this as $resource) {
$resources[$resource->name()] = $resource;
}
return $resources;
}

public function resource($name)
{
return $this->resources()[$name];
}

public function deleteResource($name)
{
$resourceDescriptors = [];
foreach ($this->descriptor->resources as $resourceDescriptor) {
if ($resourceDescriptor->name != $name) {
$resourceDescriptors[] = $resourceDescriptor;
}
}
$this->descriptor->resources = $resourceDescriptors;
$this->revalidate();
}

public function addResource($resource)
{
$resourceDescriptors = [];
foreach ($this->descriptor->resources as $resourceDescriptor) {
$resourceDescriptors[] = $resourceDescriptor;
}
$resourceDescriptors[] = $resource->descriptor();
$this->descriptor->resources = $resourceDescriptors;
$this->revalidate();
}

// standard iterator functions - to iterate over the resources
public function rewind() {$this->currentResourcePosition = 0;}
public function current() { return $this->initResource($this->descriptor()->resources[$this->currentResourcePosition]); }
Expand Down
96 changes: 96 additions & 0 deletions tests/DatapackageTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
use frictionlessdata\datapackage\Datapackages\DefaultDatapackage;
use frictionlessdata\datapackage\Exceptions;
use frictionlessdata\datapackage\Factory;
use frictionlessdata\tableschema\InferSchema;
use frictionlessdata\tableschema\Table;
use frictionlessdata\tableschema\DataSources\CsvDataSource;

class DatapackageTest extends TestCase
{
Expand Down Expand Up @@ -210,6 +213,99 @@ public function testTabularResourceInvalidData()
);
}

public function testDatapackageResources()
{
// prepare the desriptor, schema and datapackage
$dataSource = new CsvDataSource("tests/fixtures/simple_tabular_data.csv");
$schema = new InferSchema();
Table::validate($dataSource, $schema, 1);
$descriptor = (object)[
"name" => "datapackage-name",
"resources" => [
(object)[
"name" => "resource-name", "data" => ["foo.txt", "baz.txt"]
],
(object)[
"name" => "another-resource-name",
"profile" => "tabular-data-resource",
"data" => ["simple_tabular_data.csv"],
"schema" => $schema->fullDescriptor()
],
]
];
$basePath = "tests/fixtures";
$datapackage = new DefaultDatapackage($descriptor, $basePath);
// test accessing resources
$resources = $datapackage->resources();
$this->assertTrue(is_a(
$resources["resource-name"],
"frictionlessdata\\datapackage\\Resources\\DefaultResource"
));
$this->assertTrue(is_a(
$resources["another-resource-name"],
"frictionlessdata\\datapackage\\Resources\\TabularResource"
));
// accessing resource by name
$this->assertTrue(is_a(
$datapackage->resource("another-resource-name"),
"frictionlessdata\\datapackage\\Resources\\TabularResource"
));
$this->assertTrue(is_a(
$datapackage->resource("resource-name"),
"frictionlessdata\\datapackage\\Resources\\DefaultResource"
));
// delete resource
$this->assertCount(2, $datapackage->resources());
$datapackage->deleteResource("resource-name");
$this->assertCount(1, $datapackage->resources());
$i = 0;
foreach ($datapackage as $resource) { $i++; };
$this->assertEquals(1, $i);
$this->assertEquals((object)[
"name" => "datapackage-name",
"resources" => [
(object)[
"name" => "another-resource-name",
"profile" => "tabular-data-resource",
"data" => ["simple_tabular_data.csv"],
"schema" => $schema->fullDescriptor()
],
]
], $datapackage->descriptor());

// add a resource
$this->assertCount(1, $datapackage->resources());
$datapackage->addResource(Factory::resource((object)[
"name" => "new-resource", "data" => ["tests/fixtures/foo.txt", "tests/fixtures/baz.txt"]
]));
$this->assertCount(2, $datapackage->resources());
$this->assertEquals((object)[
"name" => "datapackage-name",
"resources" => [
(object)[
"name" => "another-resource-name",
"profile" => "tabular-data-resource",
"data" => ["simple_tabular_data.csv"],
"schema" => $schema->fullDescriptor()
],
(object)[
"name" => "new-resource", "data" => ["tests/fixtures/foo.txt", "tests/fixtures/baz.txt"]
]
]
], $datapackage->descriptor());
$rows = [];
foreach ($datapackage as $resource) {
if ($resource->name() == "new-resource") {
foreach ($resource as $dataStream) {
foreach ($dataStream as $row) {
$rows[] = $row;
}
}
}
}
$this->assertEquals(['foo', "בזבזבז\n", 'זבזבזב'], $rows);
}

protected function assertDatapackageValidation($expectedMessages, $source, $basePath=null)
{
$validationErrors = Factory::validate($source, $basePath);
Expand Down

0 comments on commit 1157c31

Please sign in to comment.