Completed changes for new models

This commit is contained in:
Peter Yefi 2023-02-22 22:45:33 -05:00
parent a06eced6f4
commit 0ab96ec226
9 changed files with 87 additions and 52 deletions

View File

@ -4,7 +4,7 @@ SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group Copyright © 2022 Concordia CERC group
Project CoderPeter Yefi peteryefi@gmail.com Project CoderPeter Yefi peteryefi@gmail.com
""" """
from hub.persistence import UserRepo from hub.persistence import User
class UserFactory: class UserFactory:
@ -13,19 +13,21 @@ class UserFactory:
""" """
def __init__(self, db_name, app_env, dotenv_path): def __init__(self, db_name, app_env, dotenv_path):
self._user_repo = UserRepo(db_name=db_name, app_env=app_env, dotenv_path=dotenv_path) self._user_repo = User(db_name=db_name, app_env=app_env, dotenv_path=dotenv_path)
def login_user(self, email: str, password: str): def login_user(self, name: str, password: str, application_id: int):
""" """
Retrieve a single city from postgres Retrieve a single city from postgres
:param email: the email of the user :param name: the email of the user
:param password: the password of the user :param password: the password of the user
:param application_id: the id of the application accessing hub
""" """
return self._user_repo.get_user_by_email_and_password(email, password) return self._user_repo.get_by_name_application_and_password(name, password, application_id)
def get_user_by_email(self, email): def get_by_name_and_application(self, name: str, application: int):
""" """
Retrieve a single user Retrieve a single user
:param email: the email of the user to get :param name: user name
:param application: application accessing hub
""" """
return self._user_repo.get_by_email(email) return self._user_repo.get_by_name_and_application(name, application)

View File

@ -6,6 +6,7 @@ log_dir = (Path(__file__).parent.parent / 'logs').resolve()
log_file = (log_dir / 'hub.log').resolve() log_file = (log_dir / 'hub.log').resolve()
try: try:
if not os.path.isfile(log_file): if not os.path.isfile(log_file):
if not os.path.exists:
os.mkdir(log_dir) os.mkdir(log_dir)
with open(log_file, 'x'): with open(log_file, 'x'):
pass pass

View File

@ -7,6 +7,7 @@ Project CoderPeter Yefi peteryefi@gmail.com
from hub.city_model_structure.city import City from hub.city_model_structure.city import City
from hub.persistence import City as CityRepository from hub.persistence import City as CityRepository
from hub.persistence import SimulationResults from hub.persistence import SimulationResults
from hub.persistence import Application
class DBFactory: class DBFactory:
@ -17,6 +18,7 @@ class DBFactory:
def __init__(self, db_name, dotenv_path, app_env): def __init__(self, db_name, dotenv_path, app_env):
self._city_repository = CityRepository(db_name=db_name, dotenv_path=dotenv_path, app_env=app_env) self._city_repository = CityRepository(db_name=db_name, dotenv_path=dotenv_path, app_env=app_env)
self._simulation_results = SimulationResults(db_name=db_name, dotenv_path=dotenv_path, app_env=app_env) self._simulation_results = SimulationResults(db_name=db_name, dotenv_path=dotenv_path, app_env=app_env)
self._application = Application(db_name=db_name, dotenv_path=dotenv_path, app_env=app_env)
def persist_city(self, city: City, pickle_path, application_id: int, user_id: int): def persist_city(self, city: City, pickle_path, application_id: int, user_id: int):
""" """
@ -36,6 +38,24 @@ class DBFactory:
""" """
return self._city_repository.update(city_id, city) return self._city_repository.update(city_id, city)
def persist_application(self, name: str, description: str, application_uuid: str):
"""
Creates an application
:param name: name of application
:param description: the description of the application
:param application_uuid: the uuid of the application to be created
"""
return self._application.insert(name, description, application_uuid)
def update_application(self, name: str, description: str, application_uuid: str):
"""
Update an application
:param name: name of application
:param description: the description of the application
:param application_uuid: the uuid of the application to be created
"""
return self._application.update(application_uuid, name, description)
def delete_city(self, city_id): def delete_city(self, city_id):
""" """
Deletes a single city from postgres Deletes a single city from postgres
@ -43,6 +63,13 @@ class DBFactory:
""" """
self._city_repository.delete(city_id) self._city_repository.delete(city_id)
def delete_application(self, application_uuid):
"""
Deletes a single application from postgres
:param application_uuid: the id of the application to get
"""
self._application.delete(application_uuid)
def add_simulation_results(self, name, values, city_id=None, city_object_id=None): def add_simulation_results(self, name, values, city_id=None, city_object_id=None):
""" """
Add simulation results to the city or to the city_object Add simulation results to the city or to the city_object

View File

@ -4,7 +4,7 @@ SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group Copyright © 2022 Concordia CERC group
Project CoderPeter Yefi peteryefi@gmail.com Project CoderPeter Yefi peteryefi@gmail.com
""" """
from hub.persistence import UserRepo from hub.persistence import User as UserRepository
from hub.persistence import UserRoles from hub.persistence import UserRoles
@ -14,19 +14,19 @@ class UserFactory:
""" """
def __init__(self, db_name, app_env, dotenv_path): def __init__(self, db_name, app_env, dotenv_path):
self._user_repo = UserRepo(db_name=db_name, app_env=app_env, dotenv_path=dotenv_path) self._user_repo = UserRepository(db_name=db_name, app_env=app_env, dotenv_path=dotenv_path)
def create_user(self, name: str, email: str, password: str, role: UserRoles): def create_user(self, name: str, application_id: int, password: str, role: UserRoles):
""" """
Creates a new user Creates a new user
:param name: the name of the user :param name: the name of the user
:param email: the email of the user :param application_id: the application id of the user
:param password: the password of the user :param password: the password of the user
:param role: the role of the user :param role: the role of the user
""" """
return self._user_repo.insert(name, email, password, role) return self._user_repo.insert(name, password, role, application_id)
def update_user(self, user_id: int, name: str, email: str, password: str, role: UserRoles): def update_user(self, user_id: int, name: str, password: str, role: UserRoles):
""" """
Creates a new user Creates a new user
:param user_id: the id of the user :param user_id: the id of the user
@ -35,11 +35,11 @@ class UserFactory:
:param password: the password of the user :param password: the password of the user
:param role: the role of the user :param role: the role of the user
""" """
return self._user_repo.update(user_id, name, email, password, role) return self._user_repo.update(user_id, name, password, role)
def delete_user(self, user_id): def delete_user(self, user_id):
""" """
Retrieve a single user Retrieve a single user
:param user_id: the id of the user to delete :param user_id: the id of the user to delete
""" """
return self._user_repo.delete_user(user_id) return self._user_repo.delete(user_id)

View File

@ -12,6 +12,7 @@ from sqlalchemy import DateTime
from sqlalchemy.dialects.postgresql import JSONB from sqlalchemy.dialects.postgresql import JSONB
from hub.persistence.configuration import Models from hub.persistence.configuration import Models
class SimulationResults(Models): class SimulationResults(Models):
""" """
A model representation of an application A model representation of an application

View File

@ -42,6 +42,7 @@ class Application(Repository):
if application is None: if application is None:
try: try:
application = Model(name=name, description=description, application_uuid=application_uuid) application = Model(name=name, description=description, application_uuid=application_uuid)
self.session.add(application) self.session.add(application)
self.session.commit() self.session.commit()
return application return application

View File

@ -6,7 +6,6 @@ Project Coder Peter Yefi peteryefi@gmail.com
""" """
import datetime import datetime
import pickle
from typing import Union, Dict from typing import Union, Dict
from sqlalchemy import select from sqlalchemy import select
@ -60,6 +59,7 @@ class City(Repository):
for building in city.buildings: for building in city.buildings:
object_usage = '' object_usage = ''
for internal_zone in building.internal_zones: for internal_zone in building.internal_zones:
if internal_zone.usages is not None:
for usage in internal_zone.usages: for usage in internal_zone.usages:
object_usage = f'{object_usage}{usage.name}_{usage.percentage} ' object_usage = f'{object_usage}{usage.name}_{usage.percentage} '
object_usage = object_usage.rstrip() object_usage = object_usage.rstrip()
@ -101,6 +101,7 @@ class City(Repository):
:return: a city :return: a city
""" """
try: try:
self.session.query(CityObject).filter(CityObject.city_id == city_id).delete()
self.session.query(Model).filter(Model.id == city_id).delete() self.session.query(Model).filter(Model.id == city_id).delete()
self.session.commit() self.session.commit()
except SQLAlchemyError as err: except SQLAlchemyError as err:

View File

@ -9,12 +9,12 @@ from hub.imports.geometry_factory import GeometryFactory
from hub.imports.db_factory import DBFactory from hub.imports.db_factory import DBFactory
from hub.imports.user_factory import UserFactory from hub.imports.user_factory import UserFactory
from hub.exports.db_factory import DBFactory as ExportDBFactory from hub.exports.db_factory import DBFactory as ExportDBFactory
from hub.persistence.base_repo import BaseRepo from hub.persistence.repository import Repository
from sqlalchemy import create_engine from sqlalchemy import create_engine
from hub.persistence.models import City from hub.persistence.models import City, Application, CityObject
from hub.persistence.models import User, UserRoles from hub.persistence.models import User, UserRoles
from pickle import loads
from sqlalchemy.exc import ProgrammingError from sqlalchemy.exc import ProgrammingError
import uuid
class TestDBFactory(TestCase): class TestDBFactory(TestCase):
@ -29,8 +29,8 @@ class TestDBFactory(TestCase):
:return: None :return: None
""" """
# Create test database # Create test database
repo = BaseRepo(db_name='test_db', app_env='TEST', dotenv_path='/usr/local/etc/hub/.env') repo = Repository(db_name='test_db', app_env='TEST', dotenv_path='/usr/local/etc/hub/.env')
eng = create_engine(f'postgresql://{repo.config.get_db_user()}@/{repo.config.get_db_user()}') eng = create_engine(f'postgresql://{repo.configuration.get_db_user()}@/{repo.configuration.get_db_user()}')
try: try:
# delete test database if it exists # delete test database if it exists
@ -45,56 +45,58 @@ class TestDBFactory(TestCase):
cnn.execute('commit') cnn.execute('commit')
cnn.execute("CREATE DATABASE test_db") cnn.execute("CREATE DATABASE test_db")
cnn.close() cnn.close()
Application.__table__.create(bind=repo.engine, checkfirst=True)
User.__table__.create(bind=repo.engine, checkfirst=True) User.__table__.create(bind=repo.engine, checkfirst=True)
City.__table__.create(bind=repo.engine, checkfirst=True) City.__table__.create(bind=repo.engine, checkfirst=True)
CityObject.__table__.create(bind=repo.engine, checkfirst=True)
city_file = "tests_data/C40_Final.gml" city_file = "tests_data/C40_Final.gml"
cls.city = GeometryFactory('citygml', city_file).city cls.city = GeometryFactory('citygml', city_file).city
cls._db_factory = DBFactory(db_name='test_db', app_env='TEST', dotenv_path='../.env') cls._db_factory = DBFactory(db_name='test_db', app_env='TEST', dotenv_path='../.env')
cls._export_db_factory = ExportDBFactory(db_name='test_db', app_env='TEST', dotenv_path='../.env') cls._export_db_factory = ExportDBFactory(db_name='test_db', app_env='TEST', dotenv_path='../.env')
user_factory = UserFactory(db_name='test_db', app_env='TEST', dotenv_path='../.env') user_factory = UserFactory(db_name='test_db', app_env='TEST', dotenv_path='../.env')
cls._user = user_factory.create_user("Admin", "admin@hub.com", "Admin@123", UserRoles.Admin) cls.unique_id = str(uuid.uuid4())
cls.application = cls._db_factory.persist_application("test", "test application", cls.unique_id)
cls._user = user_factory.create_user("Admin", cls.application.id, "Admin@123", UserRoles.Admin)
cls.pickle_path = 'tests_data/pickle_path.bz2'
def test_save_application(self):
self.assertEqual(self.application.name, "test")
self.assertEqual(self.application.description, "test application")
self.assertEqual(str(self.application.application_uuid), self.unique_id)
def test_save_city(self): def test_save_city(self):
saved_city = self._db_factory.persist_city(self._user.id, self.city) self.city.name = "Montréal"
saved_city = self._db_factory.persist_city(self.city, self.pickle_path, self.application.id, self._user.id)
self.assertEqual(saved_city.name, 'Montréal') self.assertEqual(saved_city.name, 'Montréal')
pickled_city = loads(saved_city.city) self.assertEqual(saved_city.pickle_path, self.pickle_path)
self.assertEqual(len(pickled_city.buildings), 10) self.assertEqual(saved_city.level_of_detail, self.city.level_of_detail.geometry)
self.assertEqual(pickled_city.buildings[0].floor_area, 1990.9913970530033)
self._db_factory.delete_city(saved_city.id) self._db_factory.delete_city(saved_city.id)
def test_save_same_city_with_same_hub_version(self):
first_city = self._db_factory.persist_city(self._user.id, self.city)
second_city = self._db_factory.persist_city(self._user.id, self.city)
self.assertEqual(second_city['message'], f'Same version of {self.city.name} exist')
self.assertEqual(first_city.name, 'Montréal')
self.assertEqual(first_city.country_code, 'ca')
self._db_factory.delete_city(first_city.id)
def test_get_city_by_name(self): def test_get_city_by_name(self):
city = self._db_factory.persist_city(self._user.id, self.city) city = self._db_factory.persist_city(self.city, self.pickle_path, self.application.id, self._user.id)
retrieved_city = self._export_db_factory.get_city_by_name(city.name) retrieved_city = self._export_db_factory.get_city_by_name(city.name)
self.assertEqual(retrieved_city[0].lower_corner[0], 610610.7547462888) self.assertEqual(retrieved_city[0].application_id, 1)
self._db_factory.delete_city(city.id)
def test_get_city_by_user(self):
city = self._db_factory.persist_city(self._user.id, self.city)
retrieved_city = self._export_db_factory.get_city_by_user(self._user.id)
self.assertEqual(retrieved_city[0].user_id, self._user.id) self.assertEqual(retrieved_city[0].user_id, self._user.id)
self._db_factory.delete_city(city.id) self._db_factory.delete_city(city.id)
def test_get_city_by_user(self):
city = self._db_factory.persist_city(self.city, self.pickle_path, self.application.id, self._user.id)
retrieved_city = self._export_db_factory.get_city_by_user(self._user.id)
self.assertEqual(retrieved_city[0].pickle_path, self.pickle_path)
self._db_factory.delete_city(city.id)
def test_get_city_by_id(self): def test_get_city_by_id(self):
city = self._db_factory.persist_city(self._user.id, self.city) city = self._db_factory.persist_city(self.city, self.pickle_path, self.application.id, self._user.id)
retrieved_city = self._export_db_factory.get_city(city.id) retrieved_city = self._export_db_factory.get_city(city.id)
self.assertEqual(retrieved_city.upper_corner[0], 610818.6731258357) self.assertEqual(retrieved_city.level_of_detail, self.city.level_of_detail.geometry)
self._db_factory.delete_city(city.id) self._db_factory.delete_city(city.id)
def test_get_update_city(self): def test_get_update_city(self):
city = self._db_factory.persist_city(self._user.id, self.city) city = self._db_factory.persist_city(self.city, self.pickle_path, self.application.id, self._user.id)
self.city.longitude = 1.43589 self.city.name = "Ottawa"
self.city.latitude = -9.38928339
self._db_factory.update_city(city.id, self.city) self._db_factory.update_city(city.id, self.city)
updated_city = self._export_db_factory.get_city(city.id) updated_city = self._export_db_factory.get_city(city.id)
self.assertEqual(updated_city.longitude, 1.43589) self.assertEqual(updated_city.name, self.city.name)
self.assertEqual(updated_city.latitude, -9.38928339)
self._db_factory.delete_city(city.id) self._db_factory.delete_city(city.id)

Binary file not shown.