Initial commit
This commit is contained in:
@@ -0,0 +1,198 @@
|
||||
import os
|
||||
from typing import Dict, Any
|
||||
from modules.logger_tool import initialise_logger
|
||||
import modules.database.tools.neo4j_driver_tools as driver_tools
|
||||
import modules.database.tools.neo4j_session_tools as session_tools
|
||||
|
||||
class Neo4jService:
|
||||
"""Service for managing Neo4j database operations"""
|
||||
|
||||
def __init__(self):
|
||||
self.logger = initialise_logger(__name__, os.getenv("LOG_LEVEL"), os.getenv("LOG_PATH"), 'default', True)
|
||||
self.driver = driver_tools.get_driver()
|
||||
|
||||
def check_database_exists(self, database_name: str) -> Dict[str, Any]:
|
||||
"""Check if a Neo4j database exists
|
||||
|
||||
Args:
|
||||
database_name (str): Name of the database to check
|
||||
|
||||
Returns:
|
||||
Dict[str, Any]: Result containing existence status and operation status
|
||||
"""
|
||||
try:
|
||||
with self.driver.session() as session:
|
||||
result = session.run(
|
||||
"SHOW DATABASES YIELD name WHERE name = $name",
|
||||
name=database_name
|
||||
)
|
||||
exists = bool(result.single())
|
||||
return {
|
||||
"exists": exists,
|
||||
"status": "success"
|
||||
}
|
||||
except Exception as e:
|
||||
self.logger.error(f"Error checking database {database_name}: {str(e)}")
|
||||
return {
|
||||
"exists": False,
|
||||
"status": "error",
|
||||
"message": str(e)
|
||||
}
|
||||
|
||||
def create_database(self, db_name: str) -> Dict[str, Any]:
|
||||
"""Creates a Neo4j database with the given name
|
||||
|
||||
Args:
|
||||
db_name (str): Name of the database to create
|
||||
|
||||
Returns:
|
||||
Dict[str, Any]: Result containing operation status and message
|
||||
"""
|
||||
try:
|
||||
# First check if database exists
|
||||
exists_result = self.check_database_exists(db_name)
|
||||
if exists_result["status"] == "error":
|
||||
return exists_result
|
||||
|
||||
if not exists_result["exists"]:
|
||||
with self.driver.session() as session:
|
||||
session_tools.create_database(session, db_name)
|
||||
self.logger.info(f"Created database {db_name}")
|
||||
return {
|
||||
"status": "success",
|
||||
"message": f"Database {db_name} created successfully"
|
||||
}
|
||||
else:
|
||||
self.logger.info(f"Database {db_name} already exists")
|
||||
return {
|
||||
"status": "success",
|
||||
"message": f"Database {db_name} already exists"
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f"Error creating database {db_name}: {str(e)}")
|
||||
return {"status": "error", "message": str(e)}
|
||||
|
||||
def initialize_schema(self, database_name: str) -> Dict[str, Any]:
|
||||
"""Initialize Neo4j schema (constraints and indexes) for a database
|
||||
|
||||
Args:
|
||||
database_name (str): Name of the database to initialize schema for
|
||||
|
||||
Returns:
|
||||
Dict[str, Any]: Result containing operation status and message
|
||||
"""
|
||||
try:
|
||||
with self.driver.session(database=database_name) as session:
|
||||
# Create constraints
|
||||
constraints = [
|
||||
"CREATE CONSTRAINT IF NOT EXISTS FOR (n:School) REQUIRE n.unique_id IS UNIQUE",
|
||||
"CREATE CONSTRAINT IF NOT EXISTS FOR (n:Department) REQUIRE n.unique_id IS UNIQUE",
|
||||
"CREATE CONSTRAINT IF NOT EXISTS FOR (n:Subject) REQUIRE n.unique_id IS UNIQUE",
|
||||
"CREATE CONSTRAINT IF NOT EXISTS FOR (n:YearGroup) REQUIRE n.unique_id IS UNIQUE",
|
||||
"CREATE CONSTRAINT IF NOT EXISTS FOR (n:Class) REQUIRE n.unique_id IS UNIQUE",
|
||||
"CREATE CONSTRAINT IF NOT EXISTS FOR (n:Teacher) REQUIRE n.unique_id IS UNIQUE",
|
||||
"CREATE CONSTRAINT IF NOT EXISTS FOR (n:Student) REQUIRE n.unique_id IS UNIQUE",
|
||||
"CREATE CONSTRAINT IF NOT EXISTS FOR (n:Calendar) REQUIRE n.unique_id IS UNIQUE",
|
||||
"CREATE CONSTRAINT IF NOT EXISTS FOR (n:Term) REQUIRE n.unique_id IS UNIQUE",
|
||||
"CREATE CONSTRAINT IF NOT EXISTS FOR (n:Week) REQUIRE n.unique_id IS UNIQUE",
|
||||
"CREATE CONSTRAINT IF NOT EXISTS FOR (n:Day) REQUIRE n.unique_id IS UNIQUE",
|
||||
"CREATE CONSTRAINT IF NOT EXISTS FOR (n:Period) REQUIRE n.unique_id IS UNIQUE"
|
||||
]
|
||||
|
||||
# Create indexes
|
||||
indexes = [
|
||||
"CREATE INDEX IF NOT EXISTS FOR (n:School) ON (n.urn)",
|
||||
"CREATE INDEX IF NOT EXISTS FOR (n:Department) ON (n.department_name)",
|
||||
"CREATE INDEX IF NOT EXISTS FOR (n:Subject) ON (n.subject_name)",
|
||||
"CREATE INDEX IF NOT EXISTS FOR (n:YearGroup) ON (n.year_group)",
|
||||
"CREATE INDEX IF NOT EXISTS FOR (n:Class) ON (n.class_name)",
|
||||
"CREATE INDEX IF NOT EXISTS FOR (n:Teacher) ON (n.email)",
|
||||
"CREATE INDEX IF NOT EXISTS FOR (n:Student) ON (n.email)",
|
||||
"CREATE INDEX IF NOT EXISTS FOR (n:Calendar) ON (n.calendar_name)",
|
||||
"CREATE INDEX IF NOT EXISTS FOR (n:Term) ON (n.term_name)",
|
||||
"CREATE INDEX IF NOT EXISTS FOR (n:Week) ON (n.week_number)",
|
||||
"CREATE INDEX IF NOT EXISTS FOR (n:Day) ON (n.date)",
|
||||
"CREATE INDEX IF NOT EXISTS FOR (n:Period) ON (n.period_name)"
|
||||
]
|
||||
|
||||
# Execute all constraints
|
||||
for constraint in constraints:
|
||||
session.run(constraint)
|
||||
|
||||
# Execute all indexes
|
||||
for index in indexes:
|
||||
session.run(index)
|
||||
|
||||
self.logger.info(f"Successfully initialized schema for database {database_name}")
|
||||
return {
|
||||
"status": "success",
|
||||
"message": f"Schema initialized successfully for database {database_name}"
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f"Error initializing schema for database {database_name}: {str(e)}")
|
||||
return {
|
||||
"status": "error",
|
||||
"message": str(e)
|
||||
}
|
||||
|
||||
def delete_database(self, db_name: str) -> Dict[str, Any]:
|
||||
"""Deletes a Neo4j database
|
||||
|
||||
Args:
|
||||
db_name (str): Name of the database to delete
|
||||
|
||||
Returns:
|
||||
Dict[str, Any]: Result containing operation status and message
|
||||
"""
|
||||
try:
|
||||
exists_result = self.check_database_exists(db_name)
|
||||
if exists_result["status"] == "error":
|
||||
return exists_result
|
||||
|
||||
if exists_result["exists"]:
|
||||
with self.driver.session() as session:
|
||||
session_tools.reset_database_in_session(session)
|
||||
self.logger.info(f"Deleted database {db_name}")
|
||||
return {
|
||||
"status": "success",
|
||||
"message": f"Database {db_name} deleted successfully"
|
||||
}
|
||||
else:
|
||||
return {
|
||||
"status": "success",
|
||||
"message": f"Database {db_name} does not exist"
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f"Error deleting database {db_name}: {str(e)}")
|
||||
return {"status": "error", "message": str(e)}
|
||||
|
||||
def check_node_exists(self, database_name: str, node_label: str) -> Dict[str, Any]:
|
||||
"""Check if any nodes with the given label exist in the specified database
|
||||
|
||||
Args:
|
||||
database_name (str): Name of the database to check
|
||||
node_label (str): Label of the node type to check for
|
||||
|
||||
Returns:
|
||||
Dict[str, Any]: Result containing count and operation status
|
||||
"""
|
||||
try:
|
||||
with self.driver.session(database=database_name) as session:
|
||||
nodes = session_tools.find_nodes_by_label(session, node_label)
|
||||
count = len(nodes)
|
||||
return {
|
||||
"exists": count > 0,
|
||||
"count": count,
|
||||
"status": "success"
|
||||
}
|
||||
except Exception as e:
|
||||
self.logger.error(f"Error checking for {node_label} nodes in database {database_name}: {str(e)}")
|
||||
return {
|
||||
"exists": False,
|
||||
"count": 0,
|
||||
"status": "error",
|
||||
"message": str(e)
|
||||
}
|
||||
Reference in New Issue
Block a user