Skip to content

Commit 301e77e

Browse files
Antony BaileyAntony Bailey
authored andcommitted
move database to factory
1 parent b3a5ce2 commit 301e77e

7 files changed

Lines changed: 147 additions & 97 deletions

File tree

BaseDBConnector.py

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,13 @@
1+
from IDBConnector import IDBConnector
12
from SQLYExecutionError import SQLYExecutionError
23
from SQLYUtils import SQLYUtils
34

4-
5-
class BaseDBConnector:
5+
class BaseDBConnector(IDBConnector):
66
"""
77
A base class for database connectors that provides methods to execute SQL queries.
88
99
Attributes:
1010
connection: A database connection object.
11-
12-
Methods:
13-
execute_query(query: dict):
14-
Translates a query dictionary to SQL and executes it.
15-
16-
_execute(sql, params):
17-
Executes a given SQL statement with parameters and handles the result.
1811
"""
1912
def __init__(self, connection):
2013
"""
@@ -36,9 +29,9 @@ def execute_query(self, query: dict):
3629
Any: The result of the executed query.
3730
"""
3831
sql, params = SQLYUtils.translate_to_sql(query)
39-
return self._execute(sql, params)
32+
return self.execute(sql, params)
4033

41-
def _execute(self, sql, params):
34+
def execute(self, sql, params):
4235
"""
4336
Executes a given SQL statement with the provided parameters.
4437

DBConnectorFactory.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
from SQLYExecutionError import SQLYExecutionError
2+
3+
# Import connectors
4+
from SQLiteConnector import SQLiteConnector
5+
from MariaDBConnector import MariaDBConnector
6+
from PostgresConnector import PostgresConnector
7+
from OracleConnector import OracleConnector
8+
from MSSQLConnector import MSSQLConnector
9+
10+
11+
class DBConnectorFactory:
12+
"""
13+
Factory class for creating database connectors based on database type.
14+
15+
This class implements the Factory Pattern to create the appropriate
16+
database connector instance based on the database type.
17+
"""
18+
19+
@staticmethod
20+
def create_connector(db_type, connection):
21+
"""
22+
Creates and returns a database connector instance based on the specified database type.
23+
24+
Args:
25+
db_type (str): The type of the database (e.g., "sqlite", "mariadb", "postgres", "oracle", "mssql").
26+
connection: The connection object or parameters required to establish the database connection.
27+
28+
Returns:
29+
An instance of the corresponding database connector class.
30+
31+
Raises:
32+
SQLYExecutionError: If the specified database type is not supported.
33+
"""
34+
connectors = {
35+
"sqlite": SQLiteConnector,
36+
"mariadb": MariaDBConnector,
37+
"postgres": PostgresConnector,
38+
"oracle": OracleConnector,
39+
"mssql": MSSQLConnector,
40+
}
41+
if db_type not in connectors:
42+
raise SQLYExecutionError("Unsupported database type: " + db_type)
43+
return connectors[db_type](connection)

DatabaseConnector.py

Lines changed: 32 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,59 @@
1-
from MSSQLConnector import MSSQLConnector
2-
from MariaDBConnector import MariaDBConnector
3-
from OracleConnector import OracleConnector
4-
from PostgresConnector import PostgresConnector
1+
from DBConnectorFactory import DBConnectorFactory
52
from SQLYExecutionError import SQLYExecutionError
6-
from SQLYUtils import SQLYUtils
7-
from SQLiteConnector import SQLiteConnector
83

94

105
class DatabaseConnector:
116
"""
12-
DatabaseConnector is a utility class that provides a method to obtain a specific
13-
database connector instance based on the database type.
14-
15-
Methods:
16-
get_connector(db_type: str, connection: Any) -> Any:
17-
Returns an instance of the appropriate database connector class based on
18-
the provided database type.
19-
20-
Parameters:
21-
db_type (str): The type of the database (e.g., 'sqlite', 'mariadb', 'postgres', 'oracle', 'mssql').
22-
connection (Any): The connection object or connection string required to establish a connection to the database.
23-
24-
Returns:
25-
An instance of the corresponding database connector class.
26-
27-
Raises:
28-
SQLYExecutionError: If the provided database type is not supported.
7+
DatabaseConnector is a utility class that provides methods to connect to
8+
and execute queries against different types of databases.
299
"""
30-
@staticmethod
31-
def get_connector(db_type, connection):
10+
def __init__(self, db_type, connection):
3211
"""
33-
Returns a database connector instance based on the specified database type.
12+
Initializes the DatabaseConnector with the database type and connection information.
3413
3514
Args:
3615
db_type (str): The type of the database (e.g., "sqlite", "mariadb", "postgres", "oracle", "mssql").
3716
connection: The connection object or parameters required to establish the database connection.
17+
"""
18+
self.db_type = db_type
19+
self.connection = connection
20+
self.connector = None
3821

39-
Returns:
40-
An instance of the corresponding database connector class.
22+
def _ensure_connector(self):
23+
"""
24+
Ensures that a connector instance exists, creating it if necessary.
4125
42-
Raises:
43-
SQLYExecutionError: If the specified database type is not supported.
26+
Returns:
27+
The database connector instance.
4428
"""
45-
connectors = {
46-
"sqlite": SQLiteConnector,
47-
"mariadb": MariaDBConnector,
48-
"postgres": PostgresConnector,
49-
"oracle": OracleConnector,
50-
"mssql": MSSQLConnector,
51-
}
52-
if db_type not in connectors:
53-
raise SQLYExecutionError("Unsupported database type: " + db_type)
54-
return connectors[db_type](connection)
29+
if self.connector is None:
30+
self.connector = DBConnectorFactory.create_connector(self.db_type, self.connection)
31+
return self.connector
5532

56-
def execute_query(self, query: dict, db_type: str, connection: Any):
33+
def execute_query(self, query: dict, db_type=None, connection=None):
5734
"""
5835
Executes a SQLY query against a specified database.
5936
6037
Args:
6138
query (dict): The query dictionary"
62-
db_type (str): The type of the database (e.g., "sqlite", "mariadb", "postgres", "oracle", "mssql").
63-
connection: The connection object or parameters required to establish the database connection.
39+
db_type (str, optional): The type of the database. Defaults to the instance's db_type.
40+
connection (optional): The connection object or parameters. Defaults to the instance's connection.
6441
6542
Returns:
6643
The result of the executed query.
6744
6845
Raises:
6946
SQLYExecutionError: If the query is invalid or an error occurs during execution.
7047
"""
71-
db_connector = DatabaseConnector.get_connector(db_type, connection)
72-
sql, params = SQLYUtils.translate_to_sql(query)
73-
return db_connector.execute(sql, params)
48+
# Use provided values or fall back to instance attributes
49+
db_type = db_type or self.db_type
50+
connection = connection or self.connection
51+
52+
if db_type != self.db_type or connection != self.connection:
53+
# If parameters differ from instance attributes, create a new connector
54+
connector = DBConnectorFactory.create_connector(db_type, connection)
55+
else:
56+
connector = self._ensure_connector()
57+
58+
# Execute the query using the appropriate connector
59+
return connector.execute_query(query)

IDBConnector.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
from abc import ABC, abstractmethod
2+
3+
4+
class IDBConnector(ABC):
5+
"""
6+
Interface for database connectors.
7+
8+
This abstract class defines the interface for database connectors, providing
9+
a standardized way to interact with different database systems.
10+
11+
Classes inheriting from IDBConnector must implement the execute method.
12+
13+
Attributes
14+
None
15+
16+
Methods
17+
execute(sql, params)
18+
"""
19+
20+
@abstractmethod
21+
def execute(self, sql, params):
22+
"""
23+
Execute a SQL query with parameters.
24+
This method executes a SQL query with the provided parameters against the database.
25+
Parameters
26+
----------
27+
sql : str
28+
The SQL query to execute.
29+
params : tuple or dict
30+
The parameters to be used in the SQL query. Can be a tuple for positional
31+
parameters or a dictionary for named parameters.
32+
Returns
33+
-------
34+
Any
35+
The result of the query execution, which depends on the specific database implementation.
36+
Raises
37+
------
38+
DatabaseError
39+
If the query execution fails.
40+
"""
41+
42+
pass

SQLYExecutor.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from SQLYParser import SQLYParser
22
from SQLYExecutionError import SQLYExecutionError
33
from SQLYUtils import SQLYUtils
4+
from DatabaseConnector import DatabaseConnector
45

56

67
class SQLYExecutor:
@@ -10,6 +11,7 @@ class SQLYExecutor:
1011
Attributes:
1112
datasource: The data source against which the queries will be executed.
1213
db_type: The type of the database (optional).
14+
db_connector: The database connector instance.
1315
1416
Methods:
1517
execute(query: str):
@@ -30,6 +32,7 @@ def __init__(self, datasource, db_type=None):
3032
"""
3133
self.datasource = datasource
3234
self.db_type = db_type
35+
self.db_connector = DatabaseConnector(db_type, datasource) if db_type else None
3336

3437
def execute(self, query: str):
3538
"""
@@ -66,6 +69,9 @@ def _run_query(self, parsed_query: dict):
6669
SQLYExecutionError: If there is an error during query execution.
6770
"""
6871
try:
69-
return SQLYUtils.execute_query(parsed_query, self.datasource, self.db_type)
72+
if not self.db_connector:
73+
raise SQLYExecutionError("Database type not specified for the executor.")
74+
75+
return self.db_connector.execute_query(parsed_query)
7076
except Exception as e:
7177
raise SQLYExecutionError("Query execution error: " + str(e)) from e

SQLYUtils.py

Lines changed: 3 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,14 @@
33

44
class SQLYUtils:
55
"""
6-
SQLYUtils is a utility class that provides static methods for validating and executing SQLY queries.
6+
SQLYUtils is a utility class that provides static methods for validating and translating SQLY queries.
77
88
Methods:
99
validate_query(query: dict) -> bool:
1010
Checks if the provided query dictionary contains the necessary fields for a SQLY query.
11-
Args:
12-
query (dict): The query dictionary to validate.
13-
Returns:
14-
bool: True if the query contains the "select" and "from" fields, False otherwise.
1511
16-
execute_query(query: dict, datasource, db_type):
17-
Executes a SQLY query against a specified database.
18-
Args:
19-
query (dict): The query dictionary to execute.
20-
datasource: The data source to connect to.
21-
db_type: The type of the database (e.g., MySQL, PostgreSQL).
22-
Returns:
23-
The result of the executed query.
12+
translate_to_sql(query: dict) -> tuple[str, list]:
13+
Translates a dictionary query representation into a SQL query and its parameters.
2414
"""
2515
@staticmethod
2616
def validate_query(query: dict) -> bool:
@@ -35,22 +25,6 @@ def validate_query(query: dict) -> bool:
3525
"""
3626
return isinstance(query, dict) and "select" in query and "from" in query
3727

38-
@staticmethod
39-
def execute_query(query: dict, datasource, db_type):
40-
"""
41-
Executes a SQLY query against a database.
42-
43-
Args:
44-
query (dict): The SQLY query to be executed.
45-
datasource: The data source to connect to.
46-
db_type: The type of the database (e.g., MySQL, PostgreSQL).
47-
48-
Returns:
49-
The result of the executed query.
50-
"""
51-
db_connector = DatabaseConnector.DatabaseConnector(db_type, datasource)
52-
return db_connector.execute_query(query, db_type, datasource)
53-
5428
@staticmethod
5529
def translate_to_sql(query: dict) -> tuple[str, list]:
5630
"""

__init__.py

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,21 @@
1-
from SQLYParser import SQLYParser
2-
from SQLYExecutor import SQLYExecutor
3-
from SQLYError import SQLYError
4-
from SQLYParseError import SQLYParseError
5-
from SQLYExecutionError import SQLYExecutionError
6-
from SQLiteConnector import SQLiteConnector
7-
from MariaDBConnector import MariaDBConnector
8-
from PostgresConnector import PostgresConnector
9-
from OracleConnector import OracleConnector
10-
from MSSQLConnector import MSSQLConnector
1+
from .IDBConnector import IDBConnector
2+
from .SQLYParser import SQLYParser
3+
from .SQLYExecutor import SQLYExecutor
4+
from .SQLYError import SQLYError
5+
from .SQLYParseError import SQLYParseError
6+
from .SQLYExecutionError import SQLYExecutionError
7+
from .SQLYUtils import SQLYUtils
8+
from .BaseDBConnector import BaseDBConnector
9+
from .DatabaseConnector import DatabaseConnector
10+
from .DBConnectorFactory import DBConnectorFactory
11+
from .SQLiteConnector import SQLiteConnector
12+
from .MariaDBConnector import MariaDBConnector
13+
from .PostgresConnector import PostgresConnector
14+
from .OracleConnector import OracleConnector
15+
from .MSSQLConnector import MSSQLConnector
1116

1217
__all__ = [
1318
"SQLYParser", "SQLYExecutor", "SQLYError", "SQLYParseError", "SQLYExecutionError",
19+
"SQLYUtils", "BaseDBConnector", "IDBConnector", "DatabaseConnector", "DBConnectorFactory",
1420
"SQLiteConnector", "MariaDBConnector", "PostgresConnector", "OracleConnector", "MSSQLConnector"
1521
]

0 commit comments

Comments
 (0)