Skip to content

Commit

Permalink
issue #158: province functions module
Browse files Browse the repository at this point in the history
  • Loading branch information
k-allagbe committed Oct 14, 2024
1 parent a9bae09 commit 7c539c8
Show file tree
Hide file tree
Showing 9 changed files with 291 additions and 160 deletions.
93 changes: 0 additions & 93 deletions fertiscan/db/queries/organization/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,6 @@ class OrganizationUpdateError(Exception):
pass


class ProvinceCreationError(Exception):
pass


class ProvinceNotFoundError(Exception):
pass


def new_organization(cursor, information_id, location_id=None):
"""
This function create a new organization in the database.
Expand Down Expand Up @@ -386,88 +378,3 @@ def get_full_organization(cursor, org_id):
return cursor.fetchone()
except Exception as e:
raise Exception("Datastore organization unhandeled error" + e.__str__())


def new_province(cursor, name):
"""
This function create a new province in the database.
Parameters:
- cursor (cursor): The cursor of the database.
- name (str): The name of the province.
Returns:
- str: The UUID of the province
"""
try:
query = """
INSERT INTO
province (
name
)
VALUES
(%s)
RETURNING
id
"""
cursor.execute(query, (name,))
return cursor.fetchone()[0]
except Exception as e:
raise ProvinceCreationError("Datastore province unhandeled error" + e.__str__())


def get_province(cursor, province_id):
"""
This function get a province from the database.
Parameters:
- cursor (cursor): The cursor of the database.
- province_id (int): The UUID of the province.
Returns:
- dict: The province
"""
try:
query = """
SELECT
name
FROM
province
WHERE
id = %s
"""
cursor.execute(query, (province_id,))
res = cursor.fetchone()
if res is None:
raise ProvinceNotFoundError
return res
except ProvinceNotFoundError:
raise ProvinceNotFoundError(
"province not found with province_id: " + str(province_id)
)
except Exception as e:
raise Exception("Datastore organization unhandeled error" + e.__str__())


def get_all_province(cursor):
"""
This function get all province from the database.
Parameters:
- cursor (cursor): The cursor of the database.
Returns:
- dict: The province
"""
try:
query = """
SELECT
id,
name
FROM
province
"""
cursor.execute(query)
return cursor.fetchall()
except Exception as e:
raise Exception("Datastore organization unhandeled error" + e.__str__())
127 changes: 127 additions & 0 deletions fertiscan/db/queries/province/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
from psycopg import Cursor
from psycopg.rows import dict_row
from psycopg.sql import SQL


def create_province(cursor: Cursor, name: str) -> dict | None:
"""
Inserts a new province record into the database.
Args:
cursor: Database cursor object.
name: Name of the province.
Returns:
The inserted province record as a dictionary, or None if failed.
"""
query = SQL("""
INSERT INTO province (name)
VALUES (%s)
RETURNING *;
""")
with cursor.connection.cursor(row_factory=dict_row) as new_cur:
new_cur.execute(query, (name,))
return new_cur.fetchone()


def read_province(cursor: Cursor, province_id: int) -> dict | None:
"""
Retrieves a province record by ID.
Args:
cursor: Database cursor object.
province_id: ID of the province.
Returns:
The province record as a dictionary, or None if not found.
"""
query = SQL("SELECT * FROM province WHERE id = %s;")
with cursor.connection.cursor(row_factory=dict_row) as new_cur:
new_cur.execute(query, (province_id,))
return new_cur.fetchone()


def read_all_provinces(cursor: Cursor) -> list[dict]:
"""
Retrieves all province records from the database.
Args:
cursor: Database cursor object.
Returns:
A list of all province records as dictionaries.
"""
query = SQL("SELECT * FROM province;")
with cursor.connection.cursor(row_factory=dict_row) as new_cur:
new_cur.execute(query)
return new_cur.fetchall()


def update_province(cursor: Cursor, province_id: int, name: str) -> dict | None:
"""
Updates an existing province record by ID.
Args:
cursor: Database cursor object.
province_id: ID of the province.
name: New name of the province.
Returns:
The updated province record as a dictionary, or None if not found.
"""
query = SQL("""
UPDATE province
SET name = %s
WHERE id = %s
RETURNING *;
""")
with cursor.connection.cursor(row_factory=dict_row) as new_cur:
new_cur.execute(query, (name, province_id))
return new_cur.fetchone()


def delete_province(cursor: Cursor, province_id: int) -> dict | None:
"""
Deletes a province record by ID.
Args:
cursor: Database cursor object.
province_id: ID of the province.
Returns:
The deleted province record as a dictionary, or None if not found.
"""
query = SQL("""
DELETE FROM province
WHERE id = %s
RETURNING *;
""")
with cursor.connection.cursor(row_factory=dict_row) as new_cur:
new_cur.execute(query, (province_id,))
return new_cur.fetchone()


def query_provinces(cursor: Cursor, name: str | None = None) -> list[dict]:
"""
Queries provinces based on optional filter criteria.
Args:
cursor: Database cursor object.
name: Optional name to filter provinces.
Returns:
A list of province records matching the filter criteria as dictionaries.
"""
conditions = []
parameters = []

if name is not None:
conditions.append("name = %s")
parameters.append(name)

where_clause = " WHERE " + " AND ".join(conditions) if conditions else ""
query = SQL(f"SELECT * FROM province{where_clause};")

with cursor.connection.cursor(row_factory=dict_row) as new_cur:
new_cur.execute(query, parameters)
return new_cur.fetchall()
14 changes: 6 additions & 8 deletions tests/fertiscan/db/queries/test_fertilizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from psycopg import Connection, connect

from datastore.db.queries.user import register_user
from fertiscan.db.models import Fertilizer, Location, Region
from fertiscan.db.models import Fertilizer, Location, Province, Region
from fertiscan.db.queries.fertilizer import (
create_fertilizer,
delete_fertilizer,
Expand All @@ -19,11 +19,8 @@
)
from fertiscan.db.queries.inspection import new_inspection
from fertiscan.db.queries.location import create_location
from fertiscan.db.queries.organization import (
new_organization,
new_organization_info,
new_province,
)
from fertiscan.db.queries.organization import new_organization, new_organization_info
from fertiscan.db.queries.province import create_province
from fertiscan.db.queries.region import create_region

load_dotenv()
Expand Down Expand Up @@ -51,8 +48,9 @@ def setUp(self):
self.inspector_id = register_user(
self.cursor, f"{uuid.uuid4().hex}@example.com"
)
self.province_id = new_province(self.cursor, "a-test-province")
self.region = create_region(self.cursor, "test-region", self.province_id)
self.province = create_province(self.cursor, "a-test-province")
self.province = Province.model_validate(self.province)
self.region = create_region(self.cursor, "test-region", self.province.id)
self.region = Region.model_validate(self.region)
self.location = create_location(
self.cursor, "test-location", "test-address", self.region.id
Expand Down
19 changes: 9 additions & 10 deletions tests/fertiscan/db/queries/test_location.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from psycopg import Connection, connect

from datastore.db.queries.user import register_user
from fertiscan.db.models import FullLocation, Location, Region
from fertiscan.db.models import FullLocation, Location, Province, Region
from fertiscan.db.queries.location import (
create_location,
delete_location,
Expand All @@ -16,11 +16,8 @@
update_location,
upsert_location,
)
from fertiscan.db.queries.organization import (
new_organization,
new_organization_info,
new_province,
)
from fertiscan.db.queries.organization import new_organization, new_organization_info
from fertiscan.db.queries.province import create_province
from fertiscan.db.queries.region import create_region

load_dotenv()
Expand All @@ -45,8 +42,9 @@ def setUp(self):
self.cursor = self.conn.cursor()

# Create necessary records for testing
self.province_id = new_province(self.cursor, uuid.uuid4().hex)
self.region = create_region(self.cursor, "Test Region", self.province_id)
self.province = create_province(self.cursor, uuid.uuid4().hex)
self.province = Province.model_validate(self.province)
self.region = create_region(self.cursor, "Test Region", self.province.id)
self.region = Region.model_validate(self.region)

self.inspector_id = register_user(self.cursor, "[email protected]")
Expand Down Expand Up @@ -270,8 +268,9 @@ def test_get_full_location_with_region_and_province(self):
# Create province and region
province_name = uuid.uuid4().hex
region_name = "Test Region"
province_id = new_province(self.cursor, province_name)
region = create_region(self.cursor, region_name, province_id)
province = create_province(self.cursor, province_name)
province = Province.model_validate(province)
region = create_region(self.cursor, region_name, province.id)
region = Region.model_validate(region)

# Create a location with the new region
Expand Down
48 changes: 8 additions & 40 deletions tests/fertiscan/db/queries/test_organization.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@

import datastore.db as db
from datastore.db.metadata import validator
from fertiscan.db.models import Location, Region
from fertiscan.db.models import Location, Province, Region
from fertiscan.db.queries import label, organization
from fertiscan.db.queries.location import create_location, query_locations
from fertiscan.db.queries.province import create_province
from fertiscan.db.queries.region import create_region

DB_CONNECTION_STRING = os.environ.get("FERTISCAN_DB_URL")
Expand All @@ -23,40 +24,6 @@
raise ValueError("FERTISCAN_SCHEMA_TESTING is not set")


class test_province(unittest.TestCase):
def setUp(self):
self.con = db.connect_db(DB_CONNECTION_STRING, DB_SCHEMA)
self.cursor = self.con.cursor()
db.create_search_path(self.con, self.cursor, DB_SCHEMA)

self.name = "test-province"

def tearDown(self):
self.con.rollback()
db.end_query(self.con, self.cursor)

def test_new_province(self):
province_id = organization.new_province(self.cursor, self.name)
self.assertIsInstance(province_id, int)

def test_get_province(self):
province_id = organization.new_province(self.cursor, self.name)
province_data = organization.get_province(self.cursor, province_id)
self.assertEqual(province_data[0], self.name)

def test_get_province_not_found(self):
with self.assertRaises(organization.ProvinceNotFoundError):
organization.get_province(self.cursor, 0)

def test_get_all_province(self):
province_id = organization.new_province(self.cursor, self.name)
province_2_id = organization.new_province(self.cursor, "test-province-2")
province_data = organization.get_all_province(self.cursor)
self.assertEqual(len(province_data), 2)
self.assertEqual(province_data[0][0], province_id)
self.assertEqual(province_data[1][0], province_2_id)


class test_organization_information(unittest.TestCase):
def setUp(self):
self.con = db.connect_db(DB_CONNECTION_STRING, DB_SCHEMA)
Expand All @@ -69,9 +36,9 @@ def setUp(self):
self.phone = "123456789"
self.location_name = "test-location"
self.location_address = "test-address"
self.province_id = organization.new_province(self.cursor, self.province_name)

self.region = create_region(self.cursor, self.region_name, self.province_id)
self.province = create_province(self.cursor, self.province_name)
self.province = Province.model_validate(self.province)
self.region = create_region(self.cursor, self.region_name, self.province.id)
self.region = Region.model_validate(self.region)

self.location = create_location(
Expand Down Expand Up @@ -235,8 +202,9 @@ def setUp(self):
self.phone = "123456789"
self.location_name = "test-location"
self.location_address = "test-address"
self.province_id = organization.new_province(self.cursor, self.province_name)
self.region = create_region(self.cursor, self.region_name, self.province_id)
self.province = create_province(self.cursor, self.province_name)
self.province = Province.model_validate(self.province)
self.region = create_region(self.cursor, self.region_name, self.province.id)
self.region = Region.model_validate(self.region)
self.location = create_location(
self.cursor, self.location_name, self.location_address, self.region.id
Expand Down
Loading

0 comments on commit 7c539c8

Please sign in to comment.