From 0daad653e001e808261b022dce60da9f9899e055 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sabine=20Schr=C3=B6der?= <s.schroeder@fz-juelich.de>
Date: Wed, 7 Oct 2020 19:17:21 +0200
Subject: [PATCH] #17: REST APIs to changelog tables are build; #9: patch API
 for stationmeta creates a separate changelog entry for every field changed in
 the metadata

---
 toardb/stationmeta/crud.py        | 19 ++++++++++++++-----
 toardb/stationmeta/stationmeta.py |  5 +++++
 toardb/timeseries/crud.py         |  4 ++++
 toardb/timeseries/timeseries.py   |  5 +++++
 4 files changed, 28 insertions(+), 5 deletions(-)

diff --git a/toardb/stationmeta/crud.py b/toardb/stationmeta/crud.py
index 2c036cf..8691370 100644
--- a/toardb/stationmeta/crud.py
+++ b/toardb/stationmeta/crud.py
@@ -62,6 +62,10 @@ def get_all_stationmeta(db: Session, skip : int = 0, limit: int = None):
     return db_objects
 
 
+def get_stationmeta_changelog(db: Session, station_id: int):
+    return db.query(models.StationmetaChangelog).filter(models.StationmetaChangelog.station_id == station_id).all()
+
+
 # is this internal, or should this also go to public REST api?
 def get_unique_stationmeta_role(db: Session, role: int, contact_id: int, status: int):
     db_object = db.query(models.StationmetaRole).filter(models.StationmetaRole.role == role) \
@@ -189,8 +193,6 @@ def patch_stationmeta(db: Session, description: str, station_id: int, stationmet
     aux_urls_data      = stationmeta_dict.pop('aux_urls', None)
     globalmeta_data    = stationmeta_dict.pop('globalmeta', None)
     globalservice_data = stationmeta_dict.pop('globalservice', None)
-    # prepare changelog entry/entries
-    db_changelog = StationmetaChangelog(description=description, station_id=station_id, author_id=1, type_of_change=1)
     # there's a mismatch with coordinates --> how to automatically switch back and forth?!
     # ==> the following two commands are not working
     # ==> workaround
@@ -202,14 +204,21 @@ def patch_stationmeta(db: Session, description: str, station_id: int, stationmet
     db_stationmeta.coordinates = get_geom_from_coordinates(db_stationmeta.coordinates)
     for k, v in stationmeta_dict.items():
         if v is not None:
+            # prepare changelog entry/entries
+            db_changelog = StationmetaChangelog(description=description, station_id=station_id, author_id=1, type_of_change=1)
             db_changelog.old_value=str(getattr(db_stationmeta,k))
             setattr(db_stationmeta,k,stationmeta_dict[k])
             db_changelog.new_value=str(getattr(db_stationmeta,k))
-    result = db.commit()
+            db_changelog.description=description + f"; field: {k}"
+            db.add(db_changelog)
+            result = db.commit()
     db.refresh(db_stationmeta)
     # store roles and update association table
     if roles_data:
         for r in roles_data:
+            # prepare changelog entry/entries
+            db_changelog = StationmetaChangelog(description=description, station_id=station_id, author_id=1, type_of_change=1)
+            db_changelog.old_value=str(getattr(db_stationmeta,"roles"))
             db_role = models.StationmetaRole(**r)
             db_role.role = get_value_from_str(RC_enum,db_role.role)
             db_role.status = get_value_from_str(RS_enum,db_role.status)
@@ -223,6 +232,8 @@ def patch_stationmeta(db: Session, description: str, station_id: int, stationmet
                 db.refresh(db_role)
                 role_id = db_role.id
             db.execute(insert(stationmeta_core_stationmeta_roles_table).values(station_id=station_id, role_id=role_id))
+            db_changelog.new_value=str(r)
+            db.add(db_changelog)
             db.commit()
     # store annotations and update association table
     if annotations_data:
@@ -279,8 +290,6 @@ def patch_stationmeta(db: Session, description: str, station_id: int, stationmet
         db.add(db_globalservice)
         db.commit()
         db.refresh(db_globalservice)
-    # add patch to changelog table
-    db.add(db_changelog)
     db.commit()
     # there's a mismatch with coordinates --> how to automatically switch back and forth?!
     db_stationmeta.coordinates = tmp_coordinates
diff --git a/toardb/stationmeta/stationmeta.py b/toardb/stationmeta/stationmeta.py
index ddc5261..e212141 100644
--- a/toardb/stationmeta/stationmeta.py
+++ b/toardb/stationmeta/stationmeta.py
@@ -42,6 +42,11 @@ def get_stationmeta(station_code: str, db: Session = Depends(get_db)):
         raise HTTPException(status_code=404, detail="Data not found.")
     return db_stationmeta
 
+@router.get('/stationmeta_changelog/{station_id}', response_model=List[schemas.StationmetaChangelog])
+def get_stationmeta_changelog(station_id: int, db: Session = Depends(get_db)):
+    db_changelog = crud.get_stationmeta_changelog(db, station_id=station_id)
+    return db_changelog
+
 #some more gets to be tested:
 # - get stationmeta_global
 # - get stationmeta_aux
diff --git a/toardb/timeseries/crud.py b/toardb/timeseries/crud.py
index 526f63e..9e30fb5 100644
--- a/toardb/timeseries/crud.py
+++ b/toardb/timeseries/crud.py
@@ -58,6 +58,10 @@ def get_timeseries_by_unique_constraints(db: Session, station_id: int, variable_
     return db_object
 
 
+def get_timeseries_changelog(db: Session, timeseries_id: int):
+    return db.query(models.TimeseriesChangelog).filter(models.TimeseriesChangelog.timeseries_id == timeseries_id).all()
+
+
 # is this internal, or should this also go to public REST api?
 # do we need this at all?
 def get_role_ids_of_timeseries(db: Session, timeseries_id: int):
diff --git a/toardb/timeseries/timeseries.py b/toardb/timeseries/timeseries.py
index 0b9880e..df051c2 100644
--- a/toardb/timeseries/timeseries.py
+++ b/toardb/timeseries/timeseries.py
@@ -27,6 +27,11 @@ def get_timeseries(timeseries_id: int, db: Session = Depends(get_db)):
         raise HTTPException(status_code=404, detail="Timeseries not found.")
     return db_timeseries
 
+@router.get('/timeseries_changelog/{timeseries_id}', response_model=List[schemas.TimeseriesChangelog])
+def get_timeseries_changelog(timeseries_id: int, db: Session = Depends(get_db)):
+    db_changelog = crud.get_timeseries_changelog(db, timeseries_id=timeseries_id)
+    return db_changelog
+
 #some more gets to be tested:
 #
 #
-- 
GitLab