Skip to content

Commit b454bcc

Browse files
Merge branch 'main' into feature/bigquery-adapter
2 parents d841aa0 + 5bba9a9 commit b454bcc

15 files changed

Lines changed: 1652 additions & 112 deletions

File tree

pyproject.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,11 @@ mysql = [
8383
"sqlglot>=27.20.0",
8484
]
8585

86+
oracle = [
87+
"oracledb>=2.0.0",
88+
"sqlglot>=27.20.0",
89+
]
90+
8691
streamlit = [
8792
"streamlit==1.50.0",
8893
"pyngrok==7.4.0",

src/intugle/adapters/factory.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,14 @@ def import_module(name: str) -> ModuleInterface:
1818
return importlib.import_module(name) # type: ignore
1919

2020

21+
# --- the new helper function ---
22+
def is_safe_plugin_name(plugin_name: str) -> bool:
23+
"""
24+
Checks if the plugin belongs to the safe 'intugle.adapters.types' namespace.
25+
"""
26+
return plugin_name.startswith("intugle.adapters.types.")
27+
28+
2129
DEFAULT_PLUGINS = [
2230
"intugle.adapters.types.pandas.pandas",
2331
"intugle.adapters.types.duckdb.duckdb",
@@ -28,6 +36,7 @@ def import_module(name: str) -> ModuleInterface:
2836
"intugle.adapters.types.sqlserver.sqlserver",
2937
"intugle.adapters.types.sqlite.sqlite",
3038
"intugle.adapters.types.bigquery.bigquery",
39+
"intugle.adapters.types.oracle.oracle",
3140
]
3241

3342

@@ -44,7 +53,7 @@ def __init__(self, plugins: list[dict] = None):
4453

4554
for _plugin in plugins:
4655
# Security check: Ensure the plugin is in the correct namespace
47-
if not _plugin.startswith("intugle.adapters.types."):
56+
if not is_safe_plugin_name(_plugin):
4857
print(f"Warning: Skipping potentially unsafe plugin '{_plugin}'.")
4958
continue
5059
try:

src/intugle/adapters/models.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,13 @@ def get_dataset_data_type() -> type:
2222
from intugle.adapters.types.bigquery.models import BigQueryConfig
2323
from intugle.adapters.types.databricks.models import DatabricksConfig
2424
from intugle.adapters.types.duckdb.models import DuckdbConfig
25+
from intugle.adapters.types.oracle.models import OracleConfig
2526
from intugle.adapters.types.postgres.models import PostgresConfig
2627
from intugle.adapters.types.snowflake.models import SnowflakeConfig
2728
from intugle.adapters.types.sqlite.models import SqliteConfig
2829
from intugle.adapters.types.sqlserver.models import SQLServerConfig
2930

30-
DataSetData = pd.DataFrame | DuckdbConfig | SnowflakeConfig | DatabricksConfig | PostgresConfig | SQLServerConfig | SqliteConfig | BigQueryConfig
31+
DataSetData = pd.DataFrame | DuckdbConfig | SnowflakeConfig | DatabricksConfig | PostgresConfig | SQLServerConfig | SqliteConfig | OracleConfig | BigQueryConfig
3132
else:
3233
# At runtime, this is dynamically determined
3334
DataSetData = Any

src/intugle/adapters/types/oracle/__init__.py

Whitespace-only changes.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
from typing import Literal, Optional
2+
3+
from pydantic import Field
4+
5+
from intugle.common.schema import SchemaBase
6+
7+
8+
class OracleConnectionConfig(SchemaBase):
9+
user: str
10+
password: str
11+
host: str
12+
port: int = 1521
13+
service_name: Optional[str] = None
14+
sid: Optional[str] = None
15+
schema_: Optional[str] = Field(None, alias="schema")
16+
17+
def model_post_init(self, __context):
18+
if not self.service_name and not self.sid:
19+
raise ValueError("Either 'service_name' or 'sid' must be provided.")
20+
21+
22+
class OracleConfig(SchemaBase):
23+
identifier: str
24+
type: Literal["oracle"] = "oracle"

0 commit comments

Comments
 (0)