Implement all tests, collection, key and value deletion

This commit is contained in:
2024-09-27 17:19:47 +02:00
parent 588dba2730
commit 5ec45a5dec
5 changed files with 167 additions and 7 deletions

View File

@ -85,7 +85,7 @@ function http_get(string $url, array $headers) {
return $http->get("http://{$opts->server}/{$url}", $headers);
}
function http_post(string $url, array $headers, string $body) {
function http_post(string $url, array $headers, ?string $body = null) {
global $opts,$http;
return $http->post("http://{$opts->server}/{$url}", $headers, $body);
}
@ -119,6 +119,36 @@ function action_show(object $opts) {
}
);
}
function action_delete(object $opts) {
$collection = array_shift($opts->args);
if (!$collection) {
exit_error("Missing collection. Expected: delete {collection} {keys|ids}*");
}
$body = json_encode($opts->args);
http_post($collection."/delete", [ 'content-type' => 'application/json' ], $body)->then(
function ($response) {
echo $response->getBody()->getContents();
},
function ($error) {
echo $error->getMessage()."\n";
}
);
}
function action_purge(object $opts) {
$collection = array_shift($opts->args);
if (!$collection) {
exit_error("Missing collection. Expected: purge {collection}");
}
http_post($collection."/delete", [], null)->then(
function ($response) {
echo $response->getBody()->getContents();
},
function ($error) {
echo $error->getMessage()."\n";
}
);
}
function action_set(object $opts) {
$collection = array_shift($opts->args);
@ -137,7 +167,17 @@ function action_set(object $opts) {
} else {
$op['key'] = $key;
}
$op['value'] = $opts->json ? json_decode($value) : $value;
if ($opts->json) {
$json = json_decode($value);
if ($json === null && $value !== 'null') {
$op['value'] = $value;
} else {
$op['value'] = $json;
}
} else {
$op['value'] = $value;
}
if ($opts->from || $opts->until) {
$vfrom = $opts->from ? [ 'from' => $opts->from->format('Y-m-d H:i:s P') ] : null;
$vuntil = $opts->until ? [ 'until' => $opts->until->format('Y-m-d H:i:s P') ] : null;
@ -170,5 +210,17 @@ switch ($action) {
case 'set':
action_set($opts);
break;
case 'delete':
action_delete($opts);
break;
case 'purge':
action_purge($opts);
break;
default:
print_help();
exit(0);
}

View File

@ -73,6 +73,7 @@ class Daemon
$collectionOp = array_shift($paths);
switch ($collectionOp) {
case null:
if ($request->getMethod() == 'GET') {
try {
@ -85,7 +86,7 @@ class Daemon
$this->opCollectionSet($request, $collectionName);
return Response::json(true);
}
throw new \Exception("Invalid request method");
return Response::json([ 'error' => "Invalid request method" ]);
case 'all':
try {
@ -94,6 +95,31 @@ class Daemon
return Response::json([ 'error' => "No such collection" ])->withStatus(404);
}
return Response::json($result);
case 'delete':
if ($request->getMethod() != 'POST') {
return Response::json([ 'error' => "Invalid request method" ]);
}
try {
$ids = json_decode($request->getBody()->getContents(), true);
$this->opCollectionDelete($collectionName, $ids);
} catch (\Exception $e) {
return Response::json([ 'error' => "No such collection" ])->withStatus(404);
}
return Response::json(true);
case 'purge':
if ($request->getMethod() != 'POST') {
return Response::json([ 'error' => "Invalid request method" ]);
}
try {
$ids = json_decode($request->getBody()->getContents(), true);
$this->opCollectionPurge($collectionName);
} catch (\Exception $e) {
return Response::json([ 'error' => "No such collection" ])->withStatus(404);
}
return Response::json(true);
}
return Response::json([ 'error'=>"Not Found" ])->withStatus(404);
@ -124,6 +150,33 @@ class Daemon
return $result;
}
private function opCollectionDelete(string $collectionName, array $ids): void
{
try {
$collection = $this->db->getCollection($collectionName);
foreach ($ids as $id) {
if (is_int($id)) {
$collection->deleteValue(intval($id));
} else {
$collection->deleteKey($id);
}
}
}
catch (\Throwable $t) {
throw new \Exception("No such collection");
}
}
private function opCollectionPurge(string $collectionName): void
{
try {
$this->db->deleteCollection($collectionName);
}
catch (\Throwable $t) {
throw new \Exception("No such collection");
}
}
private function opCollectionSet(ServerRequestInterface $request, string $collectionName): void
{

View File

@ -85,7 +85,22 @@ class Database
public function deleteCollection(string $name): void
{
$collectionQuery = $this->pdo->prepare("SELECT * FROM collections WHERE name=:name");
$collectionQuery->execute([ 'name' => $name ]);
if (!($collection = $collectionQuery->fetch(PDO::FETCH_ASSOC))) {
return;
}
$collectionId = $collection['id'];
$keyQuery = $this->pdo->prepare("SELECT * FROM keys WHERE collection_id=:cid");
$keyQuery->execute([ 'cid' => $collectionId ]);
while ($key = $keyQuery->fetch(PDO::FETCH_ASSOC)) {
$this->pdo->prepare("DELETE FROM vals WHERE key_id=:kid")
->execute([ "kid" => $key['id'] ]);
$this->pdo->prepare("DELETE FROM keys WHERE id=:kid")
->execute([ "kid" => $key['id'] ]);
}
$this->pdo->prepare("DELETE FROM collections WHERE id=:cid")
->execute([ "cid" => $collectionId ]);
}
}

View File

@ -75,12 +75,44 @@ class DaemonTest extends \PHPUnit\Framework\TestCase
public function testHandlingDeleteRequest()
{
$this->markTestSkipped();
$body = json_encode([ 'first' ]);
$request = new ServerRequest("POST", "/test/delete", [ "content-type"=>"application/json" ], $body);
$response = $this->daemon->onRequest($request);
$this->assertEquals(200, $response->getStatusCode());
$request = new ServerRequest("GET", "/test");
$response = $this->daemon->onRequest($request);
$this->assertEquals(200, $response->getStatusCode());
$resolved = json_decode($response->getBody()->getContents(), true);
$expect = [
'second' => 'c',
];
$this->assertEquals($expect, $resolved);
$body = json_encode([ 5, 6, 7, 8 ]);
$request = new ServerRequest("POST", "/test/delete", [ "content-type"=>"application/json" ], $body);
$response = $this->daemon->onRequest($request);
$this->assertEquals(200, $response->getStatusCode());
$request = new ServerRequest("GET", "/test");
$response = $this->daemon->onRequest($request);
$this->assertEquals(200, $response->getStatusCode());
$resolved = json_decode($response->getBody()->getContents(), true);
$expect = [
];
$this->assertEquals($expect, $resolved);
}
public function testHandlingPurgeRequest()
{
$this->markTestSkipped();
$request = new ServerRequest("POST", "/test/purge");
$response = $this->daemon->onRequest($request);
$this->assertEquals(200, $response->getStatusCode());
$request = new ServerRequest("GET", "/test");
$response = $this->daemon->onRequest($request);
$this->assertEquals(404, $response->getStatusCode());
}
private function insertTestData(Collection $collection, array $data)

View File

@ -34,7 +34,15 @@ class DatabaseTest extends \PHPUnit\Framework\TestCase
public function testPurgingCollection()
{
$this->markTestSkipped();
$database = new Database(":memory:");
$collection = $database->createCollection("test");
$database->deleteCollection("test");
$this->expectException(\Exception::class);
$collection = $database->getCollection("test");
}
public function testExceptionsIfCollectionNotExists()