db-sdk 1.1.0__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.
- db_sdk-1.1.0/PKG-INFO +175 -0
- db_sdk-1.1.0/README.md +157 -0
- db_sdk-1.1.0/db_sdk/__init__.py +19 -0
- db_sdk-1.1.0/db_sdk/config/__init__.py +19 -0
- db_sdk-1.1.0/db_sdk/config/settings.py +0 -0
- db_sdk-1.1.0/db_sdk/connectors/__init__.py +0 -0
- db_sdk-1.1.0/db_sdk/connectors/mongodb.py +15 -0
- db_sdk-1.1.0/db_sdk/connectors/mysql.py +20 -0
- db_sdk-1.1.0/db_sdk/connectors/postgres.py +20 -0
- db_sdk-1.1.0/db_sdk/connectors/redis.py +20 -0
- db_sdk-1.1.0/db_sdk/core/__init__.py +0 -0
- db_sdk-1.1.0/db_sdk/core/base_connector.py +11 -0
- db_sdk-1.1.0/db_sdk/core/exceptions.py +18 -0
- db_sdk-1.1.0/db_sdk/core/factory.py +30 -0
- db_sdk-1.1.0/db_sdk/query/__init__.py +3 -0
- db_sdk-1.1.0/db_sdk/query/builder.py +55 -0
- db_sdk-1.1.0/db_sdk/query/executor.py +127 -0
- db_sdk-1.1.0/db_sdk/test_connection.py +15 -0
- db_sdk-1.1.0/db_sdk.egg-info/PKG-INFO +175 -0
- db_sdk-1.1.0/db_sdk.egg-info/SOURCES.txt +26 -0
- db_sdk-1.1.0/db_sdk.egg-info/dependency_links.txt +1 -0
- db_sdk-1.1.0/db_sdk.egg-info/requires.txt +4 -0
- db_sdk-1.1.0/db_sdk.egg-info/top_level.txt +1 -0
- db_sdk-1.1.0/setup.cfg +4 -0
- db_sdk-1.1.0/setup.py +22 -0
- db_sdk-1.1.0/tests/test_connection.py +15 -0
- db_sdk-1.1.0/tests/test_connection_1.py +37 -0
- db_sdk-1.1.0/tests/test_query_builder.py +431 -0
db_sdk-1.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: db_sdk
|
|
3
|
+
Version: 1.1.0
|
|
4
|
+
Summary: A unified database connector SDK for Python
|
|
5
|
+
Author: Neha
|
|
6
|
+
Requires-Python: >=3.8
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
Requires-Dist: mysql-connector-python>=8.3.0
|
|
9
|
+
Requires-Dist: psycopg2-binary>=2.9.0
|
|
10
|
+
Requires-Dist: pymongo>=4.0.0
|
|
11
|
+
Requires-Dist: redis>=4.0.0
|
|
12
|
+
Dynamic: author
|
|
13
|
+
Dynamic: description
|
|
14
|
+
Dynamic: description-content-type
|
|
15
|
+
Dynamic: requires-dist
|
|
16
|
+
Dynamic: requires-python
|
|
17
|
+
Dynamic: summary
|
|
18
|
+
|
|
19
|
+
# 🗄️ Universal DB SDK
|
|
20
|
+
|
|
21
|
+
A lightweight, plug-and-play Python SDK for connecting to multiple databases
|
|
22
|
+
(MySQL, PostgreSQL, MongoDB, Redis) through a single unified interface.
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## 📦 Installation
|
|
27
|
+
```bash
|
|
28
|
+
pip install db-sdk
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Install only the drivers you need:
|
|
32
|
+
```bash
|
|
33
|
+
pip install mysql-connector-python # MySQL
|
|
34
|
+
pip install psycopg2-binary # PostgreSQL
|
|
35
|
+
pip install pymongo # MongoDB
|
|
36
|
+
pip install redis # Redis
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## ✨ Features
|
|
42
|
+
|
|
43
|
+
- **One interface** for MySQL, PostgreSQL, MongoDB, and Redis
|
|
44
|
+
- **No boilerplate** — one function call returns a live connection
|
|
45
|
+
- **Easy to extend** — add a new database in minutes
|
|
46
|
+
- **Clean error handling** — typed exceptions for every failure mode
|
|
47
|
+
- **Zero framework dependency** — works with FastAPI, Django, Flask, or plain Python
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## 🚀 Quick Start
|
|
52
|
+
```python
|
|
53
|
+
from db_sdk.core.factory import ConnectionFactory
|
|
54
|
+
|
|
55
|
+
conn = ConnectionFactory.create_connection("mysql", {
|
|
56
|
+
"host": "localhost",
|
|
57
|
+
"user": "root",
|
|
58
|
+
"password": "yourpassword",
|
|
59
|
+
"database": "mydb",
|
|
60
|
+
"port": 3306
|
|
61
|
+
})
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
That's it. `conn` is a live, ready-to-use connection object.
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## 🔌 Supported Databases
|
|
69
|
+
|
|
70
|
+
| Database | Type string | Driver used |
|
|
71
|
+
|------------|--------------|------------------------------|
|
|
72
|
+
| MySQL | `"mysql"` | `mysql-connector-python` |
|
|
73
|
+
| PostgreSQL | `"postgres"` | `psycopg2` |
|
|
74
|
+
| MongoDB | `"mongodb"` | `pymongo` |
|
|
75
|
+
| Redis | `"redis"` | `redis` |
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## ⚙️ Configuration Reference
|
|
80
|
+
|
|
81
|
+
### MySQL
|
|
82
|
+
```python
|
|
83
|
+
conn = ConnectionFactory.create_connection("mysql", {
|
|
84
|
+
"host": "localhost",
|
|
85
|
+
"user": "root",
|
|
86
|
+
"password": "yourpassword",
|
|
87
|
+
"database": "mydb",
|
|
88
|
+
"port": 3306 # optional, defaults to 3306
|
|
89
|
+
})
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### PostgreSQL
|
|
93
|
+
```python
|
|
94
|
+
conn = ConnectionFactory.create_connection("postgres", {
|
|
95
|
+
"host": "localhost",
|
|
96
|
+
"user": "postgres",
|
|
97
|
+
"password": "yourpassword",
|
|
98
|
+
"database": "mydb",
|
|
99
|
+
"port": 5432 # optional, defaults to 5432
|
|
100
|
+
})
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### MongoDB
|
|
104
|
+
```python
|
|
105
|
+
conn = ConnectionFactory.create_connection("mongodb", {
|
|
106
|
+
"uri": "mongodb://user:password@localhost:27017/mydb"
|
|
107
|
+
})
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
> MongoDB uses a URI string instead of separate fields.
|
|
111
|
+
> Format: `mongodb://user:password@host:port/database`
|
|
112
|
+
|
|
113
|
+
### Redis
|
|
114
|
+
```python
|
|
115
|
+
conn = ConnectionFactory.create_connection("redis", {
|
|
116
|
+
"host": "localhost",
|
|
117
|
+
"port": 6379 # optional, defaults to 6379
|
|
118
|
+
})
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## 🏗️ Project Structure
|
|
124
|
+
```
|
|
125
|
+
db_sdk/
|
|
126
|
+
├── __init__.py
|
|
127
|
+
├── settings.py
|
|
128
|
+
├── core/
|
|
129
|
+
│ ├── base_connector.py # Abstract base all connectors inherit from
|
|
130
|
+
│ ├── exceptions.py # All SDK exception types
|
|
131
|
+
│ └── factory.py # ConnectionFactory — the main entry point
|
|
132
|
+
└── connectors/
|
|
133
|
+
├── mysql.py # MySQL connector
|
|
134
|
+
├── postgres.py # PostgreSQL connector
|
|
135
|
+
├── mongodb.py # MongoDB connector
|
|
136
|
+
└── redis.py # Redis connector
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## ⚠️ Error Handling
|
|
142
|
+
|
|
143
|
+
The SDK raises typed exceptions so you can handle failures precisely:
|
|
144
|
+
```python
|
|
145
|
+
from db_sdk.core.factory import ConnectionFactory
|
|
146
|
+
from db_sdk.core.exceptions import (
|
|
147
|
+
DatabaseConnectionError,
|
|
148
|
+
UnsupportedDatabaseError,
|
|
149
|
+
ConfigurationError,
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
try:
|
|
153
|
+
conn = ConnectionFactory.create_connection("mysql", config)
|
|
154
|
+
|
|
155
|
+
except DatabaseConnectionError as e:
|
|
156
|
+
# Connection failed — wrong password, DB offline, network issue
|
|
157
|
+
print(f"Could not connect: {e}")
|
|
158
|
+
|
|
159
|
+
except UnsupportedDatabaseError as e:
|
|
160
|
+
# db_type string not recognised
|
|
161
|
+
print(f"Unknown database type: {e}")
|
|
162
|
+
|
|
163
|
+
except ConfigurationError as e:
|
|
164
|
+
# Missing or invalid keys in the config dict
|
|
165
|
+
print(f"Bad config: {e}")
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Exception Hierarchy
|
|
169
|
+
```
|
|
170
|
+
UniversalDBException ← catch this for any SDK error
|
|
171
|
+
├── DatabaseConnectionError
|
|
172
|
+
├── UnsupportedDatabaseError
|
|
173
|
+
└── ConfigurationError
|
|
174
|
+
```
|
|
175
|
+
|
db_sdk-1.1.0/README.md
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
# 🗄️ Universal DB SDK
|
|
2
|
+
|
|
3
|
+
A lightweight, plug-and-play Python SDK for connecting to multiple databases
|
|
4
|
+
(MySQL, PostgreSQL, MongoDB, Redis) through a single unified interface.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## 📦 Installation
|
|
9
|
+
```bash
|
|
10
|
+
pip install db-sdk
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Install only the drivers you need:
|
|
14
|
+
```bash
|
|
15
|
+
pip install mysql-connector-python # MySQL
|
|
16
|
+
pip install psycopg2-binary # PostgreSQL
|
|
17
|
+
pip install pymongo # MongoDB
|
|
18
|
+
pip install redis # Redis
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## ✨ Features
|
|
24
|
+
|
|
25
|
+
- **One interface** for MySQL, PostgreSQL, MongoDB, and Redis
|
|
26
|
+
- **No boilerplate** — one function call returns a live connection
|
|
27
|
+
- **Easy to extend** — add a new database in minutes
|
|
28
|
+
- **Clean error handling** — typed exceptions for every failure mode
|
|
29
|
+
- **Zero framework dependency** — works with FastAPI, Django, Flask, or plain Python
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## 🚀 Quick Start
|
|
34
|
+
```python
|
|
35
|
+
from db_sdk.core.factory import ConnectionFactory
|
|
36
|
+
|
|
37
|
+
conn = ConnectionFactory.create_connection("mysql", {
|
|
38
|
+
"host": "localhost",
|
|
39
|
+
"user": "root",
|
|
40
|
+
"password": "yourpassword",
|
|
41
|
+
"database": "mydb",
|
|
42
|
+
"port": 3306
|
|
43
|
+
})
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
That's it. `conn` is a live, ready-to-use connection object.
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## 🔌 Supported Databases
|
|
51
|
+
|
|
52
|
+
| Database | Type string | Driver used |
|
|
53
|
+
|------------|--------------|------------------------------|
|
|
54
|
+
| MySQL | `"mysql"` | `mysql-connector-python` |
|
|
55
|
+
| PostgreSQL | `"postgres"` | `psycopg2` |
|
|
56
|
+
| MongoDB | `"mongodb"` | `pymongo` |
|
|
57
|
+
| Redis | `"redis"` | `redis` |
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## ⚙️ Configuration Reference
|
|
62
|
+
|
|
63
|
+
### MySQL
|
|
64
|
+
```python
|
|
65
|
+
conn = ConnectionFactory.create_connection("mysql", {
|
|
66
|
+
"host": "localhost",
|
|
67
|
+
"user": "root",
|
|
68
|
+
"password": "yourpassword",
|
|
69
|
+
"database": "mydb",
|
|
70
|
+
"port": 3306 # optional, defaults to 3306
|
|
71
|
+
})
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### PostgreSQL
|
|
75
|
+
```python
|
|
76
|
+
conn = ConnectionFactory.create_connection("postgres", {
|
|
77
|
+
"host": "localhost",
|
|
78
|
+
"user": "postgres",
|
|
79
|
+
"password": "yourpassword",
|
|
80
|
+
"database": "mydb",
|
|
81
|
+
"port": 5432 # optional, defaults to 5432
|
|
82
|
+
})
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### MongoDB
|
|
86
|
+
```python
|
|
87
|
+
conn = ConnectionFactory.create_connection("mongodb", {
|
|
88
|
+
"uri": "mongodb://user:password@localhost:27017/mydb"
|
|
89
|
+
})
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
> MongoDB uses a URI string instead of separate fields.
|
|
93
|
+
> Format: `mongodb://user:password@host:port/database`
|
|
94
|
+
|
|
95
|
+
### Redis
|
|
96
|
+
```python
|
|
97
|
+
conn = ConnectionFactory.create_connection("redis", {
|
|
98
|
+
"host": "localhost",
|
|
99
|
+
"port": 6379 # optional, defaults to 6379
|
|
100
|
+
})
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## 🏗️ Project Structure
|
|
106
|
+
```
|
|
107
|
+
db_sdk/
|
|
108
|
+
├── __init__.py
|
|
109
|
+
├── settings.py
|
|
110
|
+
├── core/
|
|
111
|
+
│ ├── base_connector.py # Abstract base all connectors inherit from
|
|
112
|
+
│ ├── exceptions.py # All SDK exception types
|
|
113
|
+
│ └── factory.py # ConnectionFactory — the main entry point
|
|
114
|
+
└── connectors/
|
|
115
|
+
├── mysql.py # MySQL connector
|
|
116
|
+
├── postgres.py # PostgreSQL connector
|
|
117
|
+
├── mongodb.py # MongoDB connector
|
|
118
|
+
└── redis.py # Redis connector
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## ⚠️ Error Handling
|
|
124
|
+
|
|
125
|
+
The SDK raises typed exceptions so you can handle failures precisely:
|
|
126
|
+
```python
|
|
127
|
+
from db_sdk.core.factory import ConnectionFactory
|
|
128
|
+
from db_sdk.core.exceptions import (
|
|
129
|
+
DatabaseConnectionError,
|
|
130
|
+
UnsupportedDatabaseError,
|
|
131
|
+
ConfigurationError,
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
try:
|
|
135
|
+
conn = ConnectionFactory.create_connection("mysql", config)
|
|
136
|
+
|
|
137
|
+
except DatabaseConnectionError as e:
|
|
138
|
+
# Connection failed — wrong password, DB offline, network issue
|
|
139
|
+
print(f"Could not connect: {e}")
|
|
140
|
+
|
|
141
|
+
except UnsupportedDatabaseError as e:
|
|
142
|
+
# db_type string not recognised
|
|
143
|
+
print(f"Unknown database type: {e}")
|
|
144
|
+
|
|
145
|
+
except ConfigurationError as e:
|
|
146
|
+
# Missing or invalid keys in the config dict
|
|
147
|
+
print(f"Bad config: {e}")
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Exception Hierarchy
|
|
151
|
+
```
|
|
152
|
+
UniversalDBException ← catch this for any SDK error
|
|
153
|
+
├── DatabaseConnectionError
|
|
154
|
+
├── UnsupportedDatabaseError
|
|
155
|
+
└── ConfigurationError
|
|
156
|
+
```
|
|
157
|
+
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from .core.factory import ConnectionFactory
|
|
2
|
+
from .core.exceptions import (
|
|
3
|
+
UniversalDBException,
|
|
4
|
+
UnsupportedDatabaseError,
|
|
5
|
+
DatabaseConnectionError,
|
|
6
|
+
ConfigurationError,
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
__version__ = "1.0.0"
|
|
10
|
+
__author__ = "Neha"
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
__all__ = [
|
|
14
|
+
"ConnectionFactory",
|
|
15
|
+
"UniversalDBException",
|
|
16
|
+
"UnsupportedDatabaseError",
|
|
17
|
+
"DatabaseConnectionError",
|
|
18
|
+
"ConfigurationError",
|
|
19
|
+
]
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from db_sdk.core.exceptions import ConfigurationError
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def load_config_from_env():
|
|
6
|
+
db_type = os.getenv("DB_TYPE")
|
|
7
|
+
|
|
8
|
+
if not db_type:
|
|
9
|
+
raise ConfigurationError("DB_TYPE environment variable not set.")
|
|
10
|
+
|
|
11
|
+
return {
|
|
12
|
+
"db_type": db_type,
|
|
13
|
+
"host": os.getenv("DB_HOST"),
|
|
14
|
+
"user": os.getenv("DB_USER"),
|
|
15
|
+
"password": os.getenv("DB_PASSWORD"),
|
|
16
|
+
"database": os.getenv("DB_NAME"),
|
|
17
|
+
"port": os.getenv("DB_PORT"),
|
|
18
|
+
"uri": os.getenv("DB_URI"),
|
|
19
|
+
}
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from pymongo import MongoClient
|
|
2
|
+
from ..core.base_connector import BaseConnector
|
|
3
|
+
from ..core.exceptions import DatabaseConnectionError
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class MongoConnector(BaseConnector):
|
|
7
|
+
|
|
8
|
+
def connect(self):
|
|
9
|
+
try:
|
|
10
|
+
uri = self.config.get("uri")
|
|
11
|
+
client = MongoClient(uri)
|
|
12
|
+
return client
|
|
13
|
+
|
|
14
|
+
except Exception as e:
|
|
15
|
+
raise DatabaseConnectionError(f"MongoDB connection failed: {e}")
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import mysql.connector
|
|
2
|
+
from ..core.base_connector import BaseConnector
|
|
3
|
+
from ..core.exceptions import DatabaseConnectionError
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class MySQLConnector(BaseConnector):
|
|
7
|
+
|
|
8
|
+
def connect(self):
|
|
9
|
+
try:
|
|
10
|
+
connection = mysql.connector.connect(
|
|
11
|
+
host=self.config.get("host"),
|
|
12
|
+
user=self.config.get("user"),
|
|
13
|
+
password=self.config.get("password"),
|
|
14
|
+
database=self.config.get("database"),
|
|
15
|
+
port=self.config.get("port", 3306),
|
|
16
|
+
)
|
|
17
|
+
return connection
|
|
18
|
+
|
|
19
|
+
except mysql.connector.Error as e:
|
|
20
|
+
raise DatabaseConnectionError(f"MySQL connection failed: {e}")
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import psycopg2
|
|
2
|
+
from ..core.base_connector import BaseConnector
|
|
3
|
+
from ..core.exceptions import DatabaseConnectionError
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class PostgresConnector(BaseConnector):
|
|
7
|
+
|
|
8
|
+
def connect(self):
|
|
9
|
+
try:
|
|
10
|
+
connection = psycopg2.connect(
|
|
11
|
+
host=self.config.get("host"),
|
|
12
|
+
user=self.config.get("user"),
|
|
13
|
+
password=self.config.get("password"),
|
|
14
|
+
dbname=self.config.get("database"),
|
|
15
|
+
port=self.config.get("port", 5432),
|
|
16
|
+
)
|
|
17
|
+
return connection
|
|
18
|
+
|
|
19
|
+
except psycopg2.Error as e:
|
|
20
|
+
raise DatabaseConnectionError(f"PostgreSQL connection failed: {e}")
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import redis
|
|
2
|
+
from ..core.base_connector import BaseConnector
|
|
3
|
+
from ..core.exceptions import DatabaseConnectionError
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class RedisConnector(BaseConnector):
|
|
7
|
+
|
|
8
|
+
def connect(self):
|
|
9
|
+
try:
|
|
10
|
+
connection = redis.Redis(
|
|
11
|
+
host=self.config.get("host"),
|
|
12
|
+
port=self.config.get("port", 6379),
|
|
13
|
+
password=self.config.get("password"),
|
|
14
|
+
decode_responses=True,
|
|
15
|
+
)
|
|
16
|
+
connection.ping() # Test connection
|
|
17
|
+
return connection
|
|
18
|
+
|
|
19
|
+
except redis.RedisError as e:
|
|
20
|
+
raise DatabaseConnectionError(f"Redis connection failed: {e}")
|
|
File without changes
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
class BaseConnector:
|
|
2
|
+
"""
|
|
3
|
+
Base connector class.
|
|
4
|
+
All database connectors must inherit from this.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
def __init__(self, config: dict):
|
|
8
|
+
self.config = config
|
|
9
|
+
|
|
10
|
+
def connect(self):
|
|
11
|
+
raise NotImplementedError("Connect method must be implemented by subclass.")
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
class UniversalDBException(Exception):
|
|
2
|
+
"""Base exception for Universal DB SDK."""
|
|
3
|
+
pass
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class UnsupportedDatabaseError(UniversalDBException):
|
|
7
|
+
"""Raised when unsupported database type is provided."""
|
|
8
|
+
pass
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class DatabaseConnectionError(UniversalDBException):
|
|
12
|
+
"""Raised when connection fails."""
|
|
13
|
+
pass
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class ConfigurationError(UniversalDBException):
|
|
17
|
+
"""Raised when configuration is invalid."""
|
|
18
|
+
pass
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
from db_sdk.connectors.mysql import MySQLConnector
|
|
2
|
+
from db_sdk.connectors.postgres import PostgresConnector
|
|
3
|
+
from db_sdk.connectors.mongodb import MongoConnector
|
|
4
|
+
from db_sdk.connectors.redis import RedisConnector
|
|
5
|
+
# from db_sdk.core.exceptions import UnsupportedDatabaseError
|
|
6
|
+
from .exceptions import UnsupportedDatabaseError
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class ConnectionFactory:
|
|
10
|
+
|
|
11
|
+
CONNECTOR_MAPPING = {
|
|
12
|
+
"mysql": MySQLConnector,
|
|
13
|
+
"postgres": PostgresConnector,
|
|
14
|
+
"mongodb": MongoConnector,
|
|
15
|
+
"redis": RedisConnector,
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
@staticmethod
|
|
19
|
+
def create_connection(db_type: str, config: dict):
|
|
20
|
+
db_type = db_type.lower()
|
|
21
|
+
|
|
22
|
+
if db_type not in ConnectionFactory.CONNECTOR_MAPPING:
|
|
23
|
+
raise UnsupportedDatabaseError(
|
|
24
|
+
f"Unsupported database type: {db_type}"
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
connector_class = ConnectionFactory.CONNECTOR_MAPPING[db_type]
|
|
28
|
+
connector = connector_class(config)
|
|
29
|
+
|
|
30
|
+
return connector.connect()
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# db_sdk/query/builder.py
|
|
2
|
+
|
|
3
|
+
class QueryBuilder:
|
|
4
|
+
|
|
5
|
+
def __init__(self, conn, db_type: str = "mysql"):
|
|
6
|
+
self._conn = conn
|
|
7
|
+
self._db_type = db_type # ← pass this to executor
|
|
8
|
+
self._table = None
|
|
9
|
+
self._fields = ["*"]
|
|
10
|
+
self._filters = []
|
|
11
|
+
self._values = []
|
|
12
|
+
self._limit = None
|
|
13
|
+
self._order = None
|
|
14
|
+
self._action = "select"
|
|
15
|
+
self._data = {}
|
|
16
|
+
|
|
17
|
+
def table(self, name: str) -> "QueryBuilder":
|
|
18
|
+
self._table = name
|
|
19
|
+
return self
|
|
20
|
+
|
|
21
|
+
def select(self, *fields) -> "QueryBuilder":
|
|
22
|
+
self._fields = list(fields) if fields else ["*"]
|
|
23
|
+
self._action = "select"
|
|
24
|
+
return self
|
|
25
|
+
|
|
26
|
+
def where(self, column: str, value) -> "QueryBuilder":
|
|
27
|
+
self._filters.append(f"{column} = %s")
|
|
28
|
+
self._values.append(value)
|
|
29
|
+
return self
|
|
30
|
+
|
|
31
|
+
def order_by(self, column: str, direction: str = "ASC") -> "QueryBuilder":
|
|
32
|
+
self._order = f"{column} {direction.upper()}"
|
|
33
|
+
return self
|
|
34
|
+
|
|
35
|
+
def limit(self, n: int) -> "QueryBuilder":
|
|
36
|
+
self._limit = n
|
|
37
|
+
return self
|
|
38
|
+
|
|
39
|
+
def insert(self, data: dict) -> "QueryBuilder":
|
|
40
|
+
self._action = "insert"
|
|
41
|
+
self._data = data
|
|
42
|
+
return self
|
|
43
|
+
|
|
44
|
+
def update(self, data: dict) -> "QueryBuilder":
|
|
45
|
+
self._action = "update"
|
|
46
|
+
self._data = data
|
|
47
|
+
return self
|
|
48
|
+
|
|
49
|
+
def delete(self) -> "QueryBuilder":
|
|
50
|
+
self._action = "delete"
|
|
51
|
+
return self
|
|
52
|
+
|
|
53
|
+
def execute(self):
|
|
54
|
+
from db_sdk.query.executor import Executor
|
|
55
|
+
return Executor(self._conn, self._db_type).run(self)
|