Group api, logging fixes

This commit is contained in:
2025-03-13 22:24:05 +01:00
parent 8963bc1e5d
commit 31a091cb52
10 changed files with 152 additions and 18 deletions
+1
View File
@@ -1,3 +1,4 @@
/vendor/
/*.phar
/*.yaml
/*.deb
+12
View File
@@ -0,0 +1,12 @@
FROM php:8.4-cli-alpine
COPY --from=mlocati/php-extension-installer /usr/bin/install-php-extensions /usr/local/bin/
RUN apk add --no-cache tini
ENTRYPOINT [ "/sbin/tini", "--" ]
RUN install-php-extensions pcntl posix mbstring sodium
WORKDIR /app
COPY ./slotdbd.phar /app/slotdbd
CMD [ "/app/slotdbd" ]
+10 -4
View File
@@ -1,14 +1,20 @@
.PHONY: help all phar docker
.PHONY: help all phar deb docker
help:
@echo "\e[1mTargets:\e[0m"
@echo " \e[3mall\e[0m — build everything\n \e[3mphar\e[0m — build the phar\n \e[3mdocker\e[0m — build container image"
@echo " \e[3mall\e[0m — build everything\n \e[3mphar\e[0m — build the phar\n \e[3mdeb\e[0m — build deb package\n \e[3mdocker\e[0m — build container image"
all: phar
phar:
box compile
echo "<?php return [ 'version' => '$(shell git describe --tags)', 'builddate' => '$(shell date)' ];" > src/build.php \
&& box compile \
&& echo "yay"
rm -f src/build.php
mv bin/slotdbd.phar ./slotdbd.phar
docker: phar
deb:
dpack build --type deb
docker:
docker build -t dev.noccylabs.info/slotdb/slotdb:latest .
+22
View File
@@ -0,0 +1,22 @@
dpack:
version: '1.0'
package:
package: slotdb
priority: optional
section: misc
maintainer: 'NoccyLabs <labs@noccy.com>'
architecture: all
version:
from: git-tag
depends: [ php-cli, php-sqlite3 ]
summary: 'A database to manage properties on a fixed set of slots'
description: Experimental.
files:
./slotdbd.phar:
target: /usr/bin/slotdbd
chmod: '0744'
build:
- 'make phar'
./doc/slotdbd.1.md:
target: /usr/share/man/man1/slotdbd.1.gz
type: manpage
+32
View File
@@ -0,0 +1,32 @@
% slotdbd(1) 1.0.0 | slotdbd 0.1.0
% Christopher Vagnetoft <labs@noccy.com>
% January 2025
# NAME
slotdbd - SlotDB database daemon
# SYNOPSIS
**slotdbd** [*OPTIONS*]\
**slotdbd** \-h
# DESCRIPTION
**slotdbd** is a database daemon.
# OPTIONS
**\-h**, **\-\-help**
: Display help
# EXAMPLES
**slotdbd**
: Start the daemon with default settings
# EXIT VALUES
**0**
: Success
# BUGS
Probably
# COPYRIGHT
Copyright (c) 2025, NoccyLabs. Licensed under GPL version 3 or later.
+27 -4
View File
@@ -27,7 +27,7 @@ class Group implements IteratorAggregate, JsonSerializable
#[ORM\Column(type: 'string', length: 96)]
private string $name;
#[ORM\Column(type: 'simple_array')]
#[ORM\Column(type: 'json')]
private array $props = [];
#[ORM\OneToMany(targetEntity: Slot::class, mappedBy: 'group')]
@@ -41,6 +41,7 @@ class Group implements IteratorAggregate, JsonSerializable
$this->groupId = $groupId;
$this->name = $name;
$this->slots = new ArrayCollection();
$this->props = [];
}
public function getName(): string
@@ -48,17 +49,39 @@ class Group implements IteratorAggregate, JsonSerializable
return $this->name;
}
public function getGroupId(): string
{
return $this->groupId;
}
public function getIterator(): Traversable
{
return new ArrayIterator($this->props);
}
public function setProperties(array $properties): self
{
$this->props = $properties;
return $this;
}
public function getProperties(): array
{
return $this->props;
}
public function getSlots(): Collection
{
return $this->slots;
}
public function jsonSerialize(): mixed
{
return [
'id' => $this->id,
'name' => $this->name,
'props' => (object)$this->props,
'_id' => $this->id,
'_group' => $this->groupId,
'_name' => $this->name,
...$this->props,
];
}
}
+9 -2
View File
@@ -9,10 +9,14 @@ class GroupRepository extends EntityRepository
public function createGroup(string $id, ?string $name): Group
{
return new Group(
$group = new Group(
groupId: $id,
name: $name??$id,
);
$group->setProperties([]);
$this->getEntityManager()->persist($group);
$this->getEntityManager()->flush();
return $group;
}
public function findGroup(string $id): Group
@@ -23,6 +27,9 @@ class GroupRepository extends EntityRepository
public function findGroups(): array
{
return [];
return $this->createQueryBuilder('g')
->orderBy('g.groupId', 'asc')
->getQuery()
->getResult();
}
}
+6 -1
View File
@@ -41,6 +41,11 @@ class Slot implements IteratorAggregate, JsonSerializable
$this->props = [];
}
public function getSlotId(): string
{
return $this->slotId;
}
public function getIterator(): Traversable
{
return new ArrayIterator($this->props);
@@ -52,7 +57,7 @@ class Slot implements IteratorAggregate, JsonSerializable
'_id' => $this->id,
'_slot' => $this->slotId,
'_name' => $this->name,
'_group' => $this->group?->getName(),
'_group' => $this->group?->getGroupId(),
...$this->props,
];
}
+26 -6
View File
@@ -7,7 +7,7 @@ use Psr\Http\Message\ServerRequestInterface;
use React\Http\Message\Response;
use SlotDb\SlotDb\Data\Group\Group;
use SlotDb\SlotDb\Data\Group\GroupRepository;
use SlotDb\SlotDb\Data\Slot\Slot;
class GroupsController extends Controller
{
@@ -22,7 +22,7 @@ class GroupsController extends Controller
#[Route(path:"/api/slotdb/v1/groups", methods:["GET"])]
public function findGroups(ServerRequestInterface $request)
{
$slots = $this->groups->findSlots();
$slots = $this->groups->findGroups();
return Response::json($slots);
}
@@ -34,19 +34,39 @@ class GroupsController extends Controller
foreach ($data as $item) {
$groupId = $item->id;
$groupName = $item->name??null;
$groups[] = $this->groups->createSlot($groupId, $groupName);
$groups[] = $this->groups->createGroup($groupId, $groupName);
}
return Response::json($groups);
}
#[Route(path:"/api/slotdb/v1/group/{group}", methods:["GET"])]
#[Route(path:"/api/slotdb/v1/group/:group", methods:["GET"])]
public function queryGroup(ServerRequestInterface $request, string $group)
{
return Response::json(true);
$groupObj = $this->groups->findGroup($group);
$groupProps = $groupObj->getProperties();
return Response::json([
'_group' => $groupObj->getGroupId(),
'_name' => $groupObj->getName(),
'_members' => array_map(
fn(Slot $slot) => $slot->getSlotId(),
iterator_to_array($groupObj->getSlots())
),
...$groupProps
]);
}
#[Route(path:"/api/slotdb/v1/group/{group}", methods:["POST"])]
#[Route(path:"/api/slotdb/v1/group/:group/members", methods:["GET"])]
public function queryGroupMembers(ServerRequestInterface $request, string $group)
{
$groupObj = $this->groups->findGroup($group);
return Response::json(iterator_to_array($groupObj->getSlots()));
}
#[Route(path:"/api/slotdb/v1/group/:group", methods:["POST"])]
public function updateGroup(ServerRequestInterface $request, string $group)
{
$data = $this->groups->findGroup($group);
+7 -1
View File
@@ -99,11 +99,14 @@ $httpLog = $config->httpLog
?? null ));
$consoleHandler = new Monolog\Handler\StreamHandler(STDOUT);
$logFormat = "[%datetime%] %channel%.%level_name%: %message%\n";
$consoleHandler->setFormatter(new LineFormatter($logFormat, 'H:i:s'));
$consoleHandler->setLevel($verbose ? LogLevel::DEBUG : LogLevel::INFO);
$logHandlers = [ $consoleHandler ];
$httpLogHandlers = [];
if ($httpLog) {
$httpLogFile = new StreamHandler(fopen($httpLog, "a+"));
// $httpLogFile->pushProcessor(function ($log) {
@@ -112,7 +115,10 @@ if ($httpLog) {
$httpLogFile->setFormatter(new JsonFormatter());
$httpLogHandlers[] = $httpLogFile;
}
if ($verbose) $httpLogHandlers[] = $consoleHandler;
if ($verbose) {
$httpLogHandlers[] = $consoleHandler;
}
$logger = new Monolog\Logger("main", $logHandlers);
$httpLogger = new Monolog\Logger("http", $httpLogHandlers);