Group api, logging fixes
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
/vendor/
|
||||
/*.phar
|
||||
/*.yaml
|
||||
/*.deb
|
||||
|
||||
+12
@@ -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" ]
|
||||
@@ -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 .
|
||||
|
||||
@@ -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
|
||||
@@ -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,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,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();
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user