thoth-dbmanager 0.4.0__tar.gz → 0.4.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. {thoth_dbmanager-0.4.0/thoth_dbmanager.egg-info → thoth_dbmanager-0.4.2}/PKG-INFO +9 -6
  2. {thoth_dbmanager-0.4.0 → thoth_dbmanager-0.4.2}/pyproject.toml +9 -7
  3. thoth_dbmanager-0.4.2/thoth_dbmanager/ThothDbManager.py +459 -0
  4. thoth_dbmanager-0.4.2/thoth_dbmanager/__init__.py +136 -0
  5. thoth_dbmanager-0.4.2/thoth_dbmanager/adapters/__init__.py +21 -0
  6. thoth_dbmanager-0.4.2/thoth_dbmanager/adapters/mariadb.py +165 -0
  7. thoth_dbmanager-0.4.2/thoth_dbmanager/adapters/mysql.py +165 -0
  8. thoth_dbmanager-0.4.2/thoth_dbmanager/adapters/oracle.py +554 -0
  9. thoth_dbmanager-0.4.2/thoth_dbmanager/adapters/postgresql.py +444 -0
  10. thoth_dbmanager-0.4.2/thoth_dbmanager/adapters/qdrant.py +189 -0
  11. thoth_dbmanager-0.4.2/thoth_dbmanager/adapters/sqlite.py +385 -0
  12. thoth_dbmanager-0.4.2/thoth_dbmanager/adapters/sqlserver.py +583 -0
  13. thoth_dbmanager-0.4.2/thoth_dbmanager/adapters/supabase.py +249 -0
  14. thoth_dbmanager-0.4.2/thoth_dbmanager/core/__init__.py +13 -0
  15. thoth_dbmanager-0.4.2/thoth_dbmanager/core/factory.py +272 -0
  16. thoth_dbmanager-0.4.2/thoth_dbmanager/core/interfaces.py +271 -0
  17. thoth_dbmanager-0.4.2/thoth_dbmanager/core/registry.py +220 -0
  18. thoth_dbmanager-0.4.2/thoth_dbmanager/documents.py +155 -0
  19. thoth_dbmanager-0.4.2/thoth_dbmanager/dynamic_imports.py +250 -0
  20. thoth_dbmanager-0.4.2/thoth_dbmanager/helpers/__init__.py +0 -0
  21. thoth_dbmanager-0.4.2/thoth_dbmanager/helpers/multi_db_generator.py +508 -0
  22. thoth_dbmanager-0.4.2/thoth_dbmanager/helpers/preprocess_values.py +159 -0
  23. thoth_dbmanager-0.4.2/thoth_dbmanager/helpers/schema.py +376 -0
  24. thoth_dbmanager-0.4.2/thoth_dbmanager/helpers/search.py +117 -0
  25. thoth_dbmanager-0.4.2/thoth_dbmanager/lsh/__init__.py +21 -0
  26. thoth_dbmanager-0.4.2/thoth_dbmanager/lsh/core.py +182 -0
  27. thoth_dbmanager-0.4.2/thoth_dbmanager/lsh/factory.py +76 -0
  28. thoth_dbmanager-0.4.2/thoth_dbmanager/lsh/manager.py +170 -0
  29. thoth_dbmanager-0.4.2/thoth_dbmanager/lsh/storage.py +96 -0
  30. thoth_dbmanager-0.4.2/thoth_dbmanager/plugins/__init__.py +23 -0
  31. thoth_dbmanager-0.4.2/thoth_dbmanager/plugins/mariadb.py +436 -0
  32. thoth_dbmanager-0.4.2/thoth_dbmanager/plugins/mysql.py +408 -0
  33. thoth_dbmanager-0.4.2/thoth_dbmanager/plugins/oracle.py +150 -0
  34. thoth_dbmanager-0.4.2/thoth_dbmanager/plugins/postgresql.py +145 -0
  35. thoth_dbmanager-0.4.2/thoth_dbmanager/plugins/qdrant.py +41 -0
  36. thoth_dbmanager-0.4.2/thoth_dbmanager/plugins/sqlite.py +170 -0
  37. thoth_dbmanager-0.4.2/thoth_dbmanager/plugins/sqlserver.py +149 -0
  38. thoth_dbmanager-0.4.2/thoth_dbmanager/plugins/supabase.py +224 -0
  39. {thoth_dbmanager-0.4.0 → thoth_dbmanager-0.4.2/thoth_dbmanager.egg-info}/PKG-INFO +9 -6
  40. thoth_dbmanager-0.4.2/thoth_dbmanager.egg-info/SOURCES.txt +58 -0
  41. {thoth_dbmanager-0.4.0 → thoth_dbmanager-0.4.2}/thoth_dbmanager.egg-info/requires.txt +4 -0
  42. thoth_dbmanager-0.4.2/thoth_dbmanager.egg-info/top_level.txt +2 -0
  43. thoth_dbmanager-0.4.0/thoth_dbmanager.egg-info/SOURCES.txt +0 -22
  44. thoth_dbmanager-0.4.0/thoth_dbmanager.egg-info/top_level.txt +0 -1
  45. {thoth_dbmanager-0.4.0 → thoth_dbmanager-0.4.2}/LICENSE +0 -0
  46. {thoth_dbmanager-0.4.0 → thoth_dbmanager-0.4.2}/MANIFEST.in +0 -0
  47. {thoth_dbmanager-0.4.0 → thoth_dbmanager-0.4.2}/README.md +0 -0
  48. {thoth_dbmanager-0.4.0 → thoth_dbmanager-0.4.2}/setup.cfg +0 -0
  49. {thoth_dbmanager-0.4.0 → thoth_dbmanager-0.4.2}/tests/test_integration_new_architecture.py +0 -0
  50. {thoth_dbmanager-0.4.0 → thoth_dbmanager-0.4.2}/tests/test_lsh_query.py +0 -0
  51. {thoth_dbmanager-0.4.0 → thoth_dbmanager-0.4.2}/tests/test_new_architecture.py +0 -0
  52. {thoth_dbmanager-0.4.0 → thoth_dbmanager-0.4.2}/tests/test_parameter_validation.py +0 -0
  53. {thoth_dbmanager-0.4.0 → thoth_dbmanager-0.4.2}/tests/test_thoth_db_manager_base.py +0 -0
  54. {thoth_dbmanager-0.4.0 → thoth_dbmanager-0.4.2}/tests/test_thoth_informix_manager.py +0 -0
  55. {thoth_dbmanager-0.4.0 → thoth_dbmanager-0.4.2}/tests/test_thoth_mariadb_manager.py +0 -0
  56. {thoth_dbmanager-0.4.0 → thoth_dbmanager-0.4.2}/tests/test_thoth_mysql_manager.py +0 -0
  57. {thoth_dbmanager-0.4.0 → thoth_dbmanager-0.4.2}/tests/test_thoth_oracle_manager.py +0 -0
  58. {thoth_dbmanager-0.4.0 → thoth_dbmanager-0.4.2}/tests/test_thoth_pg_manager.py +0 -0
  59. {thoth_dbmanager-0.4.0 → thoth_dbmanager-0.4.2}/tests/test_thoth_sqlite_manager.py +0 -0
  60. {thoth_dbmanager-0.4.0 → thoth_dbmanager-0.4.2}/tests/test_thoth_sqlserver_manager.py +0 -0
  61. {thoth_dbmanager-0.4.0 → thoth_dbmanager-0.4.2}/tests/test_thoth_supabase_manager.py +0 -0
  62. {thoth_dbmanager-0.4.0 → thoth_dbmanager-0.4.2}/thoth_dbmanager.egg-info/dependency_links.txt +0 -0
@@ -1,13 +1,13 @@
1
1
  Metadata-Version: 2.4
2
- Name: thoth-dbmanager
3
- Version: 0.4.0
2
+ Name: thoth_dbmanager
3
+ Version: 0.4.2
4
4
  Summary: A Python library for managing SQL databases with support for multiple database types, LSH-based similarity search, and a modern plugin architecture.
5
5
  Author-email: Marco Pancotti <mp@tylconsulting.it>
6
6
  License: MIT
7
- Project-URL: Homepage, https://github.com/mptyl/thoth-dbmanager
8
- Project-URL: Bug Tracker, https://github.com/mptyl/thoth-dbmanager/issues
9
- Project-URL: Documentation, https://github.com/mptyl/thoth-dbmanager#readme
10
- Project-URL: Source Code, https://github.com/mptyl/thoth-dbmanager
7
+ Project-URL: Homepage, https://github.com/mptyl/thoth_dbmanager
8
+ Project-URL: Bug Tracker, https://github.com/mptyl/thoth_dbmanager/issues
9
+ Project-URL: Documentation, https://github.com/mptyl/thoth_dbmanager#readme
10
+ Project-URL: Source Code, https://github.com/mptyl/thoth_dbmanager
11
11
  Keywords: database,sql,lsh,similarity-search,orm
12
12
  Classifier: Programming Language :: Python :: 3
13
13
  Classifier: Programming Language :: Python :: 3.8
@@ -45,6 +45,8 @@ Requires-Dist: supabase>=2.0.0; extra == "supabase"
45
45
  Requires-Dist: postgrest-py>=0.16.0; extra == "supabase"
46
46
  Requires-Dist: gotrue-py>=2.0.0; extra == "supabase"
47
47
  Provides-Extra: sqlite
48
+ Provides-Extra: qdrant
49
+ Requires-Dist: qdrant-client>=1.7.0; extra == "qdrant"
48
50
  Provides-Extra: all
49
51
  Requires-Dist: psycopg2-binary>=2.9.0; extra == "all"
50
52
  Requires-Dist: mysql-connector-python>=8.0.0; extra == "all"
@@ -55,6 +57,7 @@ Requires-Dist: informixdb>=2.2.0; extra == "all"
55
57
  Requires-Dist: supabase>=2.0.0; extra == "all"
56
58
  Requires-Dist: postgrest-py>=0.16.0; extra == "all"
57
59
  Requires-Dist: gotrue-py>=2.0.0; extra == "all"
60
+ Requires-Dist: qdrant-client>=1.7.0; extra == "all"
58
61
  Provides-Extra: dev
59
62
  Requires-Dist: pytest>=7.0.0; extra == "dev"
60
63
  Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
@@ -3,8 +3,8 @@ requires = ["setuptools>=61.0"]
3
3
  build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
- name = "thoth-dbmanager"
7
- version = "0.4.0"
6
+ name = "thoth_dbmanager"
7
+ version = "0.4.2"
8
8
  authors = [
9
9
  { name="Marco Pancotti", email="mp@tylconsulting.it" },
10
10
  ]
@@ -43,6 +43,7 @@ oracle = ["cx_Oracle>=8.3.0"]
43
43
  informix = ["informixdb>=2.2.0"]
44
44
  supabase = ["supabase>=2.0.0", "postgrest-py>=0.16.0", "gotrue-py>=2.0.0"]
45
45
  sqlite = [] # Built into Python
46
+ qdrant = ["qdrant-client>=1.7.0"]
46
47
 
47
48
  # Convenience groups
48
49
  all = [
@@ -54,7 +55,8 @@ all = [
54
55
  "informixdb>=2.2.0",
55
56
  "supabase>=2.0.0",
56
57
  "postgrest-py>=0.16.0",
57
- "gotrue-py>=2.0.0"
58
+ "gotrue-py>=2.0.0",
59
+ "qdrant-client>=1.7.0"
58
60
  ]
59
61
 
60
62
  # Development dependencies
@@ -72,10 +74,10 @@ test-postgresql = ["pytest>=7.0.0", "psycopg2-binary>=2.9.0"]
72
74
  test-mysql = ["pytest>=7.0.0", "mysql-connector-python>=8.0.0"]
73
75
 
74
76
  [project.urls]
75
- "Homepage" = "https://github.com/mptyl/thoth-dbmanager"
76
- "Bug Tracker" = "https://github.com/mptyl/thoth-dbmanager/issues"
77
- "Documentation" = "https://github.com/mptyl/thoth-dbmanager#readme"
78
- "Source Code" = "https://github.com/mptyl/thoth-dbmanager"
77
+ "Homepage" = "https://github.com/mptyl/thoth_dbmanager"
78
+ "Bug Tracker" = "https://github.com/mptyl/thoth_dbmanager/issues"
79
+ "Documentation" = "https://github.com/mptyl/thoth_dbmanager#readme"
80
+ "Source Code" = "https://github.com/mptyl/thoth_dbmanager"
79
81
 
80
82
  [tool.setuptools.packages.find]
81
83
  where = ["."]
@@ -0,0 +1,459 @@
1
+ import pickle
2
+ import logging
3
+ from abc import ABC, abstractmethod
4
+ from pathlib import Path
5
+ from threading import Lock
6
+ from typing import Any, Dict, List, Optional, Union, ClassVar, Type, TypeVar
7
+
8
+ from .lsh.manager import LshManager
9
+ from .core.factory import ThothDbFactory
10
+ from .core.interfaces import DbPlugin
11
+
12
+ # Import plugins to register them
13
+ from .plugins.postgresql import PostgreSQLPlugin
14
+ from .plugins.sqlite import SQLitePlugin
15
+
16
+ T = TypeVar('T', bound='ThothDbManager')
17
+
18
+ class ThothDbManager(ABC):
19
+ """
20
+ This class provides methods for interacting with a database.
21
+ It follows a singleton pattern for each unique set of connection parameters.
22
+
23
+ This class now serves as a compatibility layer over the new plugin architecture.
24
+ """
25
+ _instances: ClassVar[Dict[tuple, Any]] = {}
26
+ _lock: ClassVar[Lock] = Lock()
27
+
28
+ @classmethod
29
+ def get_instance(cls: Type[T], db_type: str, **kwargs) -> T:
30
+ """
31
+ Get or create a singleton instance based on the database type.
32
+ This acts as a factory for different database manager implementations.
33
+
34
+ Now uses the new plugin architecture while maintaining backward compatibility.
35
+
36
+ Args:
37
+ db_type (str): The type of database (e.g., 'postgresql', 'sqlite', 'mysql').
38
+ **kwargs: Connection parameters specific to the database implementation.
39
+
40
+ Returns:
41
+ An instance of the appropriate database manager.
42
+
43
+ Raises:
44
+ ValueError: If the database type is unsupported or required parameters are missing.
45
+ """
46
+ # Try new plugin architecture first
47
+ try:
48
+ if db_type in ["postgresql", "sqlite"]: # Currently supported by new architecture
49
+ # Extract required parameters
50
+ db_root_path = kwargs.get('db_root_path')
51
+ db_mode = kwargs.get('db_mode', 'dev')
52
+
53
+ if not db_root_path:
54
+ raise ValueError("db_root_path is required")
55
+
56
+ # Remove extracted parameters from kwargs to avoid duplicate parameter errors
57
+ kwargs_clean = kwargs.copy()
58
+ kwargs_clean.pop('db_root_path', None)
59
+ kwargs_clean.pop('db_mode', None)
60
+
61
+ # Create plugin instance using factory
62
+ plugin = ThothDbFactory.create_manager(db_type, db_root_path, db_mode, **kwargs_clean)
63
+
64
+ # Wrap plugin in compatibility adapter
65
+ return ThothDbManagerAdapter(plugin)
66
+
67
+ except Exception as e:
68
+ logging.warning(f"Failed to use new plugin architecture for {db_type}: {e}. Falling back to legacy implementation.")
69
+
70
+ # Use unified plugin system for all database types
71
+ try:
72
+ # Import all plugins to ensure they're registered
73
+ from . import plugins
74
+
75
+ # Create plugin instance using factory
76
+ plugin = ThothDbFactory.create_manager(db_type, **kwargs)
77
+
78
+ # Wrap plugin in compatibility adapter
79
+ return ThothDbManagerAdapter(plugin)
80
+
81
+ except Exception as e:
82
+ logging.error(f"Failed to create {db_type} manager: {e}")
83
+ raise ValueError(f"Unsupported database type '{db_type}' or invalid parameters: {e}")
84
+
85
+ def __init__(self, db_root_path: str, db_mode: str = "dev", db_type: Optional[str] = None, **kwargs) -> None:
86
+ """
87
+ Initialize the database manager.
88
+
89
+ Args:
90
+ db_root_path (str): Path to the database root directory.
91
+ db_mode (str, optional): Database mode (dev, prod, etc.). Defaults to "dev".
92
+ db_type (Optional[str], optional): Type of database. Defaults to None.
93
+ **kwargs: Additional parameters specific to the database implementation.
94
+ """
95
+ self._validate_common_params(db_root_path, db_mode)
96
+
97
+ self.db_root_path = db_root_path
98
+ self.db_mode = db_mode
99
+ self.db_type = db_type
100
+
101
+ # These will be set by subclasses
102
+ self.engine = None
103
+ self.db_id = None
104
+ self.db_directory_path = None
105
+
106
+ # LSH related attributes (for backward compatibility)
107
+ self.lsh = None
108
+ self.minhashes = None
109
+ self.vector_db = None
110
+
111
+ # New LSH manager (lazy initialization)
112
+ self._lsh_manager = None
113
+
114
+ # Flag to track initialization
115
+ self._initialized = False
116
+
117
+ def _validate_common_params(self, db_root_path: str, db_mode: str) -> None:
118
+ """
119
+ Validate common parameters for all database implementations.
120
+
121
+ Args:
122
+ db_root_path (str): Path to the database root directory.
123
+ db_mode (str): Database mode (dev, prod, etc.).
124
+
125
+ Raises:
126
+ ValueError: If parameters are invalid.
127
+ """
128
+ if not db_root_path:
129
+ raise ValueError("db_root_path is required")
130
+
131
+ if not isinstance(db_mode, str):
132
+ raise TypeError("db_mode must be a string")
133
+
134
+ def _setup_directory_path(self, db_id: str) -> None:
135
+ """
136
+ Set up the database directory path.
137
+
138
+ Args:
139
+ db_id (str): Database identifier.
140
+ """
141
+ if isinstance(self.db_root_path, str):
142
+ self.db_root_path = Path(self.db_root_path)
143
+
144
+ self.db_directory_path = self.db_root_path / f"{self.db_mode}_databases" / db_id
145
+ self.db_id = db_id
146
+
147
+ # Reset LSH manager when directory path changes
148
+ self._lsh_manager = None
149
+
150
+ @property
151
+ def lsh_manager(self) -> Optional[LshManager]:
152
+ """
153
+ Lazy load LSH manager.
154
+
155
+ Returns:
156
+ LshManager instance if db_directory_path is set, None otherwise
157
+ """
158
+ if self._lsh_manager is None and self.db_directory_path:
159
+ self._lsh_manager = LshManager(self.db_directory_path)
160
+ return self._lsh_manager
161
+
162
+ @abstractmethod
163
+ def execute_sql(self,
164
+ sql: str,
165
+ params: Optional[Dict] = None,
166
+ fetch: Union[str, int] = "all",
167
+ timeout: int = 60) -> Any:
168
+ """
169
+ Abstract method to execute SQL queries.
170
+
171
+ Args:
172
+ sql (str): The SQL query to execute.
173
+ params (Optional[Dict]): Parameters for the SQL query.
174
+ fetch (Union[str, int]): Specifies how to fetch the results.
175
+ timeout (int): Timeout for the query execution.
176
+
177
+ Returns:
178
+ Any: The result of the SQL query execution.
179
+ """
180
+ pass
181
+
182
+ @abstractmethod
183
+ def get_unique_values(self) -> Dict[str, Dict[str, List[str]]]:
184
+ """
185
+ Get unique values from the database.
186
+
187
+ Returns:
188
+ Dict[str, Dict[str, List[str]]]: Dictionary where:
189
+ - outer key is table name
190
+ - inner key is column name
191
+ - value is list of unique values
192
+ """
193
+ pass
194
+
195
+ @abstractmethod
196
+ def get_tables(self) -> List[Dict[str, str]]:
197
+ """
198
+ Abstract method to get a list of tables in the database.
199
+
200
+ Returns:
201
+ List[Dict[str, str]]: A list of dictionaries, where each dictionary
202
+ represents a table with 'name' and 'comment' keys.
203
+ """
204
+ pass
205
+
206
+ @abstractmethod
207
+ def get_columns(self, table_name: str) -> List[Dict[str, Any]]:
208
+ """
209
+ Abstract method to get a list of columns for a given table.
210
+
211
+ Args:
212
+ table_name (str): The name of the table.
213
+
214
+ Returns:
215
+ List[Dict[str, Any]]: A list of dictionaries, where each dictionary
216
+ represents a column with 'name', 'data_type',
217
+ 'comment', and 'is_pk' keys.
218
+ """
219
+ pass
220
+
221
+ @abstractmethod
222
+ def get_foreign_keys(self) -> List[Dict[str, str]]:
223
+ """
224
+ Abstract method to get a list of foreign key relationships in the database.
225
+
226
+ Returns:
227
+ List[Dict[str, str]]: A list of dictionaries, where each dictionary
228
+ represents a foreign key relationship with
229
+ 'source_table_name', 'source_column_name',
230
+ 'target_table_name', and 'target_column_name' keys.
231
+ """
232
+ pass
233
+
234
+ @abstractmethod
235
+ def get_example_data(self, table_name: str, number_of_rows: int = 30) -> Dict[str, List[Any]]:
236
+ """
237
+ Abstract method to get example data (most frequent values) for each column in a table.
238
+
239
+ Args:
240
+ table_name (str): The name of the table.
241
+ number_of_rows (int, optional): Maximum number of example values to return per column. Defaults to 30.
242
+
243
+ Returns:
244
+ Dict[str, List[Any]]: A dictionary mapping column names to lists of example values.
245
+ """
246
+ pass
247
+
248
+ def set_lsh(self) -> str:
249
+ """
250
+ Sets the LSH and minhashes attributes by loading from storage.
251
+
252
+ This method maintains backward compatibility while using the new LSH manager.
253
+ """
254
+ with self._lock:
255
+ if self.lsh is None:
256
+ try:
257
+ # Use the new LSH manager
258
+ if self.lsh_manager and self.lsh_manager.load_lsh():
259
+ # Set backward compatibility attributes
260
+ self.lsh = self.lsh_manager.lsh
261
+ self.minhashes = self.lsh_manager.minhashes
262
+ return "success"
263
+ else:
264
+ # Fallback to old method for compatibility
265
+ lsh_path = self.db_directory_path / "preprocessed" / f"{self.db_id}_lsh.pkl"
266
+ minhashes_path = self.db_directory_path / "preprocessed" / f"{self.db_id}_minhashes.pkl"
267
+
268
+ if not lsh_path.exists() or not minhashes_path.exists():
269
+ raise FileNotFoundError(f"LSH or MinHashes file not found for {self.db_id}")
270
+
271
+ with lsh_path.open("rb") as file:
272
+ self.lsh = pickle.load(file)
273
+ with minhashes_path.open("rb") as file:
274
+ self.minhashes = pickle.load(file)
275
+ return "success"
276
+ except Exception as e:
277
+ logging.error(f"Error loading LSH: {str(e)}")
278
+ self.lsh = "error"
279
+ self.minhashes = "error"
280
+ return "error"
281
+ elif self.lsh == "error":
282
+ return "error"
283
+ else:
284
+ return "success"
285
+
286
+ def query_lsh(self,
287
+ keyword: str,
288
+ signature_size: int = 30,
289
+ n_gram: int = 3,
290
+ top_n: int = 10) -> Dict[str, Dict[str, List[str]]]:
291
+ """
292
+ Queries the LSH for similar values to the given keyword.
293
+
294
+ Args:
295
+ keyword (str): The keyword to search for.
296
+ signature_size (int, optional): The size of the MinHash signature. Defaults to 30.
297
+ n_gram (int, optional): The n-gram size for the MinHash. Defaults to 3.
298
+ top_n (int, optional): The number of top results to return. Defaults to 10.
299
+
300
+ Returns:
301
+ Dict[str, Dict[str, List[str]]]: Dictionary where:
302
+ - outer key is table name
303
+ - inner key is column name
304
+ - value is list of similar strings
305
+ """
306
+ # Try using the new LSH manager first
307
+ if self.lsh_manager:
308
+ try:
309
+ return self.lsh_manager.query(
310
+ keyword=keyword,
311
+ signature_size=signature_size,
312
+ n_gram=n_gram,
313
+ top_n=top_n
314
+ )
315
+ except Exception as e:
316
+ logging.warning(f"LSH manager query failed, falling back to old method: {e}")
317
+
318
+ # Fallback to old method for backward compatibility
319
+ lsh_status = self.set_lsh()
320
+ if lsh_status == "success":
321
+ # Import here to avoid circular imports
322
+ from .helpers.search import _query_lsh
323
+ return _query_lsh(self.lsh, self.minhashes, keyword, signature_size, n_gram, top_n)
324
+ else:
325
+ raise Exception(f"Error loading LSH for {self.db_id}")
326
+
327
+
328
+ class ThothDbManagerAdapter(ThothDbManager):
329
+ """
330
+ Adapter class that wraps the new plugin architecture to provide backward compatibility
331
+ with the original ThothDbManager interface.
332
+ """
333
+
334
+ def __init__(self, plugin: DbPlugin):
335
+ """
336
+ Initialize the adapter with a plugin instance.
337
+
338
+ Args:
339
+ plugin: Database plugin instance
340
+ """
341
+ self.plugin = plugin
342
+
343
+ # Copy plugin attributes for backward compatibility
344
+ self.db_root_path = plugin.db_root_path
345
+ self.db_mode = plugin.db_mode
346
+ self.db_type = plugin.supported_db_types[0] if plugin.supported_db_types else "unknown"
347
+ self.db_id = getattr(plugin, 'db_id', None)
348
+ self.db_directory_path = getattr(plugin, 'db_directory_path', None)
349
+
350
+ # Engine and connection (delegated to adapter)
351
+ self.engine = getattr(plugin.adapter, 'engine', None) if plugin.adapter else None
352
+
353
+ # LSH related attributes (for backward compatibility)
354
+ self.lsh = None
355
+ self.minhashes = None
356
+ self.vector_db = None
357
+
358
+ # Flag to track initialization
359
+ self._initialized = plugin._initialized
360
+
361
+ @property
362
+ def lsh_manager(self):
363
+ """Access LSH manager through plugin"""
364
+ return getattr(self.plugin, 'lsh_manager', None)
365
+
366
+ def execute_sql(self, sql: str, params: Optional[Dict] = None, fetch: Union[str, int] = "all", timeout: int = 60) -> Any:
367
+ """Execute SQL queries through plugin"""
368
+ return self.plugin.execute_sql(sql, params, fetch, timeout)
369
+
370
+ def get_unique_values(self) -> Dict[str, Dict[str, List[str]]]:
371
+ """Get unique values through plugin"""
372
+ return self.plugin.get_unique_values()
373
+
374
+ def get_tables(self) -> List[Dict[str, str]]:
375
+ """Get tables through plugin"""
376
+ return self.plugin.get_tables()
377
+
378
+ def get_columns(self, table_name: str) -> List[Dict[str, Any]]:
379
+ """Get columns through plugin"""
380
+ return self.plugin.get_columns(table_name)
381
+
382
+ def get_foreign_keys(self) -> List[Dict[str, str]]:
383
+ """Get foreign keys through plugin"""
384
+ return self.plugin.get_foreign_keys()
385
+
386
+ def set_lsh(self) -> str:
387
+ """Set LSH through plugin"""
388
+ if hasattr(self.plugin, 'set_lsh'):
389
+ result = self.plugin.set_lsh()
390
+
391
+ # Update backward compatibility attributes
392
+ if result == "success" and self.lsh_manager:
393
+ self.lsh = getattr(self.lsh_manager, 'lsh', None)
394
+ self.minhashes = getattr(self.lsh_manager, 'minhashes', None)
395
+
396
+ return result
397
+ else:
398
+ # Fallback to original implementation
399
+ return super().set_lsh()
400
+
401
+ def query_lsh(self, keyword: str, signature_size: int = 30, n_gram: int = 3, top_n: int = 10) -> Dict[str, Dict[str, List[str]]]:
402
+ """Query LSH through plugin"""
403
+ if hasattr(self.plugin, 'query_lsh'):
404
+ return self.plugin.query_lsh(keyword, signature_size, n_gram, top_n)
405
+ else:
406
+ # Fallback to original implementation
407
+ return super().query_lsh(keyword, signature_size, n_gram, top_n)
408
+
409
+ # Document-based methods (new functionality)
410
+ def get_tables_as_documents(self):
411
+ """Get tables as document objects"""
412
+ if self.plugin.adapter:
413
+ return self.plugin.adapter.get_tables_as_documents()
414
+ return []
415
+
416
+ def get_columns_as_documents(self, table_name: str):
417
+ """Get columns as document objects"""
418
+ if self.plugin.adapter:
419
+ return self.plugin.adapter.get_columns_as_documents(table_name)
420
+ return []
421
+
422
+ def get_foreign_keys_as_documents(self):
423
+ """Get foreign keys as document objects"""
424
+ if self.plugin.adapter:
425
+ return self.plugin.adapter.get_foreign_keys_as_documents()
426
+ return []
427
+
428
+ def get_schemas_as_documents(self):
429
+ """Get schemas as document objects"""
430
+ if self.plugin.adapter:
431
+ return self.plugin.adapter.get_schemas_as_documents()
432
+ return []
433
+
434
+ def get_indexes_as_documents(self, table_name: Optional[str] = None):
435
+ """Get indexes as document objects"""
436
+ if self.plugin.adapter:
437
+ return self.plugin.adapter.get_indexes_as_documents(table_name)
438
+ return []
439
+
440
+ def get_connection_info(self) -> Dict[str, Any]:
441
+ """Get connection information"""
442
+ if hasattr(self.plugin, 'get_connection_info'):
443
+ return self.plugin.get_connection_info()
444
+ return {}
445
+
446
+ def health_check(self) -> bool:
447
+ """Check database health"""
448
+ if self.plugin.adapter:
449
+ return self.plugin.adapter.health_check()
450
+ return False
451
+
452
+ def get_example_data(self, table_name: str, number_of_rows: int = 30) -> Dict[str, List[Any]]:
453
+ """Get example data through plugin"""
454
+ if hasattr(self.plugin, 'get_example_data'):
455
+ return self.plugin.get_example_data(table_name, number_of_rows)
456
+ elif self.plugin.adapter:
457
+ return self.plugin.adapter.get_example_data(table_name, number_of_rows)
458
+ else:
459
+ raise RuntimeError("Plugin not initialized or doesn't support get_example_data")
@@ -0,0 +1,136 @@
1
+ """
2
+ Thoth Database Manager - A unified interface for multiple database systems.
3
+
4
+ This package provides database-agnostic operations, LSH similarity search,
5
+ and an extensible plugin architecture for managing SQL databases.
6
+ """
7
+
8
+ # Core classes - always available
9
+ from .ThothDbManager import ThothDbManager
10
+ from .core.factory import ThothDbFactory
11
+ from .core.interfaces import DbPlugin, DbAdapter
12
+ from .core.registry import DbPluginRegistry
13
+
14
+ # Document models
15
+ from .documents import (
16
+ BaseThothDbDocument,
17
+ TableDocument,
18
+ ColumnDocument,
19
+ QueryDocument,
20
+ SchemaDocument,
21
+ ForeignKeyDocument,
22
+ IndexDocument,
23
+ ThothDbType,
24
+ create_document
25
+ )
26
+
27
+ # Export LSH functionality for backward compatibility
28
+ from .lsh.factory import make_db_lsh
29
+ from .lsh import LshManager, LshFactory
30
+
31
+ # Dynamic import system
32
+ from .dynamic_imports import (
33
+ import_manager,
34
+ import_adapter,
35
+ import_plugin,
36
+ get_available_databases,
37
+ import_database_components,
38
+ DatabaseImportError,
39
+ # Convenience functions
40
+ import_postgresql,
41
+ import_mysql,
42
+ import_sqlite,
43
+ import_sqlserver,
44
+ import_oracle,
45
+ import_mariadb,
46
+ import_informix,
47
+ import_supabase,
48
+ )
49
+
50
+ # Legacy API - will be dynamically imported when accessed
51
+ def __getattr__(name: str):
52
+ """Dynamic attribute access for database managers."""
53
+ if name == 'ThothPgManager':
54
+ return import_manager('postgresql')
55
+ elif name == 'ThothSqliteManager':
56
+ return import_manager('sqlite')
57
+ elif name == 'ThothMySqlManager':
58
+ return import_manager('mysql')
59
+ elif name == 'ThothMariaDbManager':
60
+ return import_manager('mariadb')
61
+ elif name == 'ThothSqlServerManager':
62
+ return import_manager('sqlserver')
63
+ elif name == 'ThothOracleManager':
64
+ return import_manager('oracle')
65
+ elif name == 'ThothInformixManager':
66
+ return import_manager('informix')
67
+ elif name == 'ThothSupabaseManager':
68
+ return import_manager('supabase')
69
+
70
+ raise AttributeError(f"module 'thoth_dbmanager' has no attribute '{name}'")
71
+
72
+ # Public API
73
+ __all__ = [
74
+ # Legacy API
75
+ "ThothDbManager",
76
+ "ThothPgManager",
77
+ "ThothSqliteManager",
78
+ "ThothMySqlManager",
79
+ "ThothMariaDbManager",
80
+ "ThothSqlServerManager",
81
+ "ThothOracleManager",
82
+ "ThothInformixManager",
83
+ "ThothSupabaseManager",
84
+
85
+ # New architecture
86
+ "ThothDbFactory",
87
+ "DbPluginRegistry",
88
+ "DbPlugin",
89
+ "DbAdapter",
90
+
91
+ # Document models
92
+ "BaseThothDbDocument",
93
+ "TableDocument",
94
+ "ColumnDocument",
95
+ "QueryDocument",
96
+ "SchemaDocument",
97
+ "ForeignKeyDocument",
98
+ "IndexDocument",
99
+ "ThothDbType",
100
+ "create_document",
101
+
102
+ # Plugins
103
+ "PostgreSQLPlugin",
104
+ "SQLitePlugin",
105
+ "MySQLPlugin",
106
+ "MariaDBPlugin",
107
+ "SQLServerPlugin",
108
+ "OraclePlugin",
109
+ "InformixPlugin",
110
+ "SupabasePlugin",
111
+
112
+ # Adapters
113
+ "PostgreSQLAdapter",
114
+ "SQLiteAdapter",
115
+ "MySQLAdapter",
116
+ "MariaDBAdapter",
117
+ "SQLServerAdapter",
118
+ "OracleAdapter",
119
+ "InformixAdapter",
120
+ "SupabaseAdapter",
121
+
122
+ # LSH functionality
123
+ "make_db_lsh",
124
+ "LshManager",
125
+ "LshFactory",
126
+
127
+ # Dynamic import system
128
+ "import_manager",
129
+ "import_adapter",
130
+ "import_plugin",
131
+ "get_available_databases",
132
+ "import_database_components",
133
+ "DatabaseImportError",
134
+ ]
135
+
136
+ __version__ = "0.4.0"
@@ -0,0 +1,21 @@
1
+ """
2
+ Database adapters for Thoth SQL Database Manager.
3
+ """
4
+
5
+ from .postgresql import PostgreSQLAdapter
6
+ from .sqlite import SQLiteAdapter
7
+ from .supabase import SupabaseAdapter
8
+ from .mysql import MySQLAdapter
9
+ from .mariadb import MariaDBAdapter
10
+ from .sqlserver import SQLServerAdapter
11
+ from .oracle import OracleAdapter
12
+
13
+ __all__ = [
14
+ "PostgreSQLAdapter",
15
+ "SQLiteAdapter",
16
+ "SupabaseAdapter",
17
+ "MySQLAdapter",
18
+ "MariaDBAdapter",
19
+ "SQLServerAdapter",
20
+ "OracleAdapter",
21
+ ]