@@ -178,6 +178,12 @@ def get_instance(cls):
178178 return None
179179 return DataBase .wadas_db
180180
181+ @classmethod
182+ def get_enabled_db (cls ):
183+ """Method that returns the db instance if enabled"""
184+
185+ return db if (db := cls .get_instance ()) and db .enabled else None
186+
181187 @classmethod
182188 def destroy_instance (cls ):
183189 """Destroy the current database instance and release resources."""
@@ -380,17 +386,23 @@ def update_detection_event(cls, detection_event: DetectionEvent):
380386
381387 @classmethod
382388 def update_camera (cls , camera , delete_camera = False ):
383- """Method to reflect camera fields update in db. """
389+ """Method to reflect camera fields update in db given a camera object """
384390
385- logger .debug ("Updating camera db entry..." )
386- camera_db_id = cls .get_camera_id (camera .id )
387- enabled = camera .enabled
388-
389- if not camera_db_id :
391+ if not cls .update_camera_by_db_id (
392+ cls .get_camera_id (camera .id ), camera .enabled , delete_camera
393+ ):
390394 logger .error (
391395 "Unable to update camera. Camera ID %s not found or already deleted." , camera .id
392396 )
393- return
397+
398+ @classmethod
399+ def update_camera_by_db_id (cls , camera_db_id , enabled , delete_camera = False ):
400+ """Method to reflect camera fields update in db given a camera id"""
401+
402+ logger .debug ("Updating camera db entry..." )
403+
404+ if not camera_db_id :
405+ return False
394406
395407 if delete_camera :
396408 deletion_date_time = get_precise_timestamp ()
@@ -408,21 +420,28 @@ def update_camera(cls, camera, delete_camera=False):
408420 else :
409421 stmt = update (ORMCamera ).where (ORMCamera .db_id == camera_db_id ).values (enabled = enabled )
410422 cls .run_query (stmt )
423+ return True
411424
412425 @classmethod
413426 def update_actuator (cls , actuator , delete_actuator = False ):
414- """Method to reflect actuator fields update in db."""
415-
416- logger .debug ("Updating actuator db entry..." )
417- actuator_db_id = cls .get_actuator_id (actuator .id )
418- enabled = actuator .enabled
427+ """Method to reflect actuator fields update in db given an actuator object"""
419428
420- if not actuator_db_id :
429+ if not cls .update_actuator_by_db_id (
430+ cls .get_actuator_id (actuator .id ), actuator .enabled , delete_actuator
431+ ):
421432 logger .error (
422433 "Unable to update actuator. Actuator ID %s not found or already deleted." ,
423434 actuator .id ,
424435 )
425- return
436+
437+ @classmethod
438+ def update_actuator_by_db_id (cls , actuator_db_id , enabled , delete_actuator = False ):
439+ """Method to reflect actuator fields update in db given an actuator id."""
440+
441+ logger .debug ("Updating actuator db entry..." )
442+
443+ if not actuator_db_id :
444+ return False
426445
427446 if delete_actuator :
428447 deletion_date_time = get_precise_timestamp ()
@@ -444,6 +463,7 @@ def update_actuator(cls, actuator, delete_actuator=False):
444463 .values (enabled = enabled )
445464 )
446465 cls .run_query (stmt )
466+ return True
447467
448468 @classmethod
449469 def add_actuator_to_camera (cls , camera , actuator ):
@@ -687,6 +707,95 @@ def populate_db(cls, uuid):
687707 for camera in cameras :
688708 cls .insert_into_db (camera )
689709
710+ @classmethod
711+ def sanitize_db (cls ):
712+ """Method to align db tables with domain model"""
713+
714+ if session := cls .create_session ():
715+ # Check if actuators in model are reflected into db
716+ for actuator_id in Actuator .actuators :
717+ cur_actuator = Actuator .actuators [actuator_id ]
718+ if actuator_db_id := cls .get_actuator_id (actuator_id ):
719+ # Check actuator attributes type, enabled
720+ db_actuator = (
721+ session .query (ORMActuator ).filter (ORMActuator .db_id == actuator_db_id ).one ()
722+ )
723+ if db_actuator .type != cur_actuator .type :
724+ # If type does not match, set to deleted the one in db
725+ cls .update_actuator_by_db_id (actuator_db_id , db_actuator .enabled , True )
726+ # Insert new actuator into db
727+ cls .insert_into_db (cur_actuator )
728+ if db_actuator .enabled != cur_actuator .enabled :
729+ cls .update_actuator (cur_actuator , False )
730+ else :
731+ cls .insert_into_db (cur_actuator )
732+
733+ # Check if cameras in model are reflected into db
734+ for camera in cameras :
735+ if camera_db_id := cls .get_camera_id (camera .id ):
736+ db_camera = (
737+ session .query (ORMCamera ).filter (ORMCamera .db_id == camera_db_id ).one ()
738+ )
739+ if camera .type != db_camera .type :
740+ cls .update_camera_by_db_id (camera_db_id , db_camera .enabled , True )
741+ cls .insert_into_db (camera )
742+ if camera .enabled != db_camera .enabled :
743+ cls .update_camera (camera , False )
744+ if camera .actuators != db_camera .actuators :
745+ # Delete all associations for camera
746+ stmt = delete (camera_actuator_association ).where (
747+ camera_actuator_association .c .camera_id == camera_db_id
748+ )
749+ cls .run_query (stmt )
750+ # Pristine associations for camera
751+ for actuator in camera .actuators :
752+ actuator_db_id = cls .get_actuator_id (actuator .id )
753+ stmt = camera_actuator_association .insert ().values (
754+ camera_id = camera_db_id , actuator_id = actuator_db_id
755+ )
756+ cls .run_query (stmt )
757+ else :
758+ cls .insert_into_db (camera )
759+
760+ # Check if actuators in db match the ones in domain
761+ actuator_ids = session .query (ORMActuator .actuator_id ).all ()
762+ actuator_ids_from_db = {actuator_id [0 ] for actuator_id in actuator_ids }
763+ db_extra_actuators_ids = actuator_ids_from_db - Actuator .actuators .keys ()
764+ for extra_actuator_id in db_extra_actuators_ids :
765+ deletion_date_time = get_precise_timestamp ()
766+ actuator_db_id = cls .get_actuator_id (extra_actuator_id )
767+ stmt = (
768+ update (ORMActuator )
769+ .where (ORMActuator .db_id == actuator_db_id )
770+ .values (deletion_date = deletion_date_time )
771+ )
772+ cls .run_query (stmt )
773+ # Delete camera association with actuators, if any
774+ stmt = delete (camera_actuator_association ).where (
775+ camera_actuator_association .c .actuator_id == extra_actuator_id
776+ )
777+ cls .run_query (stmt )
778+
779+ # Check if cameras in db match the ones in domain
780+ camera_ids = session .query (ORMCamera .camera_id ).all ()
781+ camera_ids_from_db = {camera_id [0 ] for camera_id in camera_ids }
782+ camera_id_from_domain = {camera .id for camera in cameras }
783+ db_extra_camera_ids = camera_ids_from_db - camera_id_from_domain
784+ for extra_camera_id in db_extra_camera_ids :
785+ deletion_date_time = get_precise_timestamp ()
786+ camera_db_id = cls .get_camera_id (extra_camera_id )
787+ stmt = (
788+ update (ORMCamera )
789+ .where (ORMCamera .db_id == camera_db_id )
790+ .values (deletion_date = deletion_date_time )
791+ )
792+ cls .run_query (stmt )
793+ # Delete camera association with actuators, if any
794+ stmt = delete (camera_actuator_association ).where (
795+ camera_actuator_association .c .camera_id == extra_camera_id
796+ )
797+ cls .run_query (stmt )
798+
690799 @abstractmethod
691800 def get_connection_string (self ):
692801 """Generate the connection string based on the database type."""
0 commit comments