|
|
|
@@ -0,0 +1,72 @@ |
|
|
|
import json |
|
|
|
from typing import List, Dict, Any, Optional |
|
|
|
|
|
|
|
from fastapi.encoders import jsonable_encoder |
|
|
|
|
|
|
|
from schemas.reslevis import ZoneAreaDefinitionItem |
|
|
|
from .config import ZONE_AREA_DEFINITION_JSON_PATH |
|
|
|
from .gateway import _LockedFile, _atomic_write, _norm_str |
|
|
|
|
|
|
|
|
|
|
|
class ZoneAreaDefinitionJsonRepository: |
|
|
|
def __init__(self, json_path: str = ZONE_AREA_DEFINITION_JSON_PATH): |
|
|
|
self.path = json_path |
|
|
|
|
|
|
|
def _read_all(self) -> List[Dict[str, Any]]: |
|
|
|
with _LockedFile(self.path, "r") as fp: |
|
|
|
try: |
|
|
|
fp.seek(0) |
|
|
|
data = fp.read().strip() |
|
|
|
return json.loads(data) if data else [] |
|
|
|
except json.JSONDecodeError: |
|
|
|
return [] |
|
|
|
|
|
|
|
def _write_all(self, rows: List[Dict[str, Any]]) -> None: |
|
|
|
payload = json.dumps(rows, ensure_ascii=False, indent=2) |
|
|
|
_atomic_write(self.path, payload) |
|
|
|
|
|
|
|
def _index_by_uuid(self, rows: List[Dict[str, Any]], item_uuid: str) -> Optional[int]: |
|
|
|
target = _norm_str(item_uuid) |
|
|
|
for idx, row in enumerate(rows): |
|
|
|
if _norm_str(row.get("UUID")) == target: |
|
|
|
return idx |
|
|
|
return None |
|
|
|
|
|
|
|
def list(self, item_uuid: Optional[str] = None) -> List[Dict[str, Any]]: |
|
|
|
rows = self._read_all() |
|
|
|
if item_uuid: |
|
|
|
idx = self._index_by_uuid(rows, item_uuid) |
|
|
|
return [rows[idx]] if idx is not None else [] |
|
|
|
return rows |
|
|
|
|
|
|
|
def add(self, item: ZoneAreaDefinitionItem) -> None: |
|
|
|
rows = self._read_all() |
|
|
|
obj = jsonable_encoder(item) |
|
|
|
obj_uuid = _norm_str(obj.get("UUID")) |
|
|
|
|
|
|
|
if self._index_by_uuid(rows, obj_uuid) is not None: |
|
|
|
raise ValueError(f"ZoneAreaDefinition con UUID '{obj_uuid}' già presente") |
|
|
|
|
|
|
|
rows.append(obj) |
|
|
|
self._write_all(rows) |
|
|
|
|
|
|
|
def update(self, item: ZoneAreaDefinitionItem) -> None: |
|
|
|
rows = self._read_all() |
|
|
|
obj = jsonable_encoder(item) |
|
|
|
obj_uuid = _norm_str(obj.get("UUID")) |
|
|
|
|
|
|
|
idx = self._index_by_uuid(rows, obj_uuid) |
|
|
|
if idx is None: |
|
|
|
raise ValueError(f"ZoneAreaDefinition con UUID '{obj_uuid}' non trovato") |
|
|
|
|
|
|
|
rows[idx] = obj |
|
|
|
self._write_all(rows) |
|
|
|
|
|
|
|
def remove(self, item_uuid: str) -> None: |
|
|
|
rows = self._read_all() |
|
|
|
idx = self._index_by_uuid(rows, item_uuid) |
|
|
|
if idx is None: |
|
|
|
raise ValueError(f"ZoneAreaDefinition con UUID '{item_uuid}' non trovato") |
|
|
|
|
|
|
|
del rows[idx] |
|
|
|
self._write_all(rows) |