cinchdb 0.1.17__py3-none-any.whl → 0.1.18__py3-none-any.whl
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.
- cinchdb/cli/commands/tenant.py +50 -2
- cinchdb/core/connection.py +55 -18
- cinchdb/core/database.py +24 -9
- cinchdb/core/initializer.py +25 -40
- cinchdb/core/path_utils.py +192 -17
- cinchdb/managers/change_applier.py +1 -1
- cinchdb/managers/codegen.py +372 -15
- cinchdb/managers/column.py +7 -4
- cinchdb/managers/data.py +16 -13
- cinchdb/managers/query.py +8 -5
- cinchdb/managers/table.py +8 -5
- cinchdb/managers/tenant.py +227 -71
- cinchdb/utils/name_validator.py +22 -12
- {cinchdb-0.1.17.dist-info → cinchdb-0.1.18.dist-info}/METADATA +35 -1
- {cinchdb-0.1.17.dist-info → cinchdb-0.1.18.dist-info}/RECORD +18 -18
- {cinchdb-0.1.17.dist-info → cinchdb-0.1.18.dist-info}/WHEEL +0 -0
- {cinchdb-0.1.17.dist-info → cinchdb-0.1.18.dist-info}/entry_points.txt +0 -0
- {cinchdb-0.1.17.dist-info → cinchdb-0.1.18.dist-info}/licenses/LICENSE +0 -0
cinchdb/managers/column.py
CHANGED
@@ -18,7 +18,8 @@ class ColumnManager:
|
|
18
18
|
PROTECTED_COLUMNS = {"id", "created_at", "updated_at"}
|
19
19
|
|
20
20
|
def __init__(
|
21
|
-
self, project_root: Path, database: str, branch: str, tenant: str = "main"
|
21
|
+
self, project_root: Path, database: str, branch: str, tenant: str = "main",
|
22
|
+
encryption_manager=None
|
22
23
|
):
|
23
24
|
"""Initialize column manager.
|
24
25
|
|
@@ -27,14 +28,16 @@ class ColumnManager:
|
|
27
28
|
database: Database name
|
28
29
|
branch: Branch name
|
29
30
|
tenant: Tenant name (default: main)
|
31
|
+
encryption_manager: EncryptionManager instance for encrypted connections
|
30
32
|
"""
|
31
33
|
self.project_root = Path(project_root)
|
32
34
|
self.database = database
|
33
35
|
self.branch = branch
|
34
36
|
self.tenant = tenant
|
37
|
+
self.encryption_manager = encryption_manager
|
35
38
|
self.db_path = get_tenant_db_path(project_root, database, branch, tenant)
|
36
39
|
self.change_tracker = ChangeTracker(project_root, database, branch)
|
37
|
-
self.table_manager = TableManager(project_root, database, branch, tenant)
|
40
|
+
self.table_manager = TableManager(project_root, database, branch, tenant, encryption_manager)
|
38
41
|
|
39
42
|
def list_columns(self, table_name: str) -> List[Column]:
|
40
43
|
"""List all columns in a table.
|
@@ -415,7 +418,7 @@ class ColumnManager:
|
|
415
418
|
|
416
419
|
create_sql = f"CREATE TABLE {temp_table} ({', '.join(col_defs)})"
|
417
420
|
|
418
|
-
with DatabaseConnection(self.db_path) as conn:
|
421
|
+
with DatabaseConnection(self.db_path, tenant_id=self.tenant, encryption_manager=self.encryption_manager) as conn:
|
419
422
|
# Create new table
|
420
423
|
conn.execute(create_sql)
|
421
424
|
|
@@ -488,7 +491,7 @@ class ColumnManager:
|
|
488
491
|
|
489
492
|
# If making NOT NULL, check for NULL values
|
490
493
|
if not nullable:
|
491
|
-
with DatabaseConnection(self.db_path) as conn:
|
494
|
+
with DatabaseConnection(self.db_path, tenant_id=self.tenant, encryption_manager=self.encryption_manager) as conn:
|
492
495
|
cursor = conn.execute(
|
493
496
|
f"SELECT COUNT(*) FROM {table_name} WHERE {column_name} IS NULL"
|
494
497
|
)
|
cinchdb/managers/data.py
CHANGED
@@ -20,7 +20,8 @@ class DataManager:
|
|
20
20
|
"""Manages data operations within a database tenant."""
|
21
21
|
|
22
22
|
def __init__(
|
23
|
-
self, project_root: Path, database: str, branch: str, tenant: str = "main"
|
23
|
+
self, project_root: Path, database: str, branch: str, tenant: str = "main",
|
24
|
+
encryption_manager=None
|
24
25
|
):
|
25
26
|
"""Initialize data manager.
|
26
27
|
|
@@ -29,14 +30,16 @@ class DataManager:
|
|
29
30
|
database: Database name
|
30
31
|
branch: Branch name
|
31
32
|
tenant: Tenant name (default: main)
|
33
|
+
encryption_manager: EncryptionManager instance for encrypted connections
|
32
34
|
"""
|
33
35
|
self.project_root = Path(project_root)
|
34
36
|
self.database = database
|
35
37
|
self.branch = branch
|
36
38
|
self.tenant = tenant
|
39
|
+
self.encryption_manager = encryption_manager
|
37
40
|
self.db_path = get_tenant_db_path(project_root, database, branch, tenant)
|
38
|
-
self.table_manager = TableManager(project_root, database, branch, tenant)
|
39
|
-
self.query_manager = QueryManager(project_root, database, branch, tenant)
|
41
|
+
self.table_manager = TableManager(project_root, database, branch, tenant, encryption_manager)
|
42
|
+
self.query_manager = QueryManager(project_root, database, branch, tenant, encryption_manager)
|
40
43
|
|
41
44
|
def select(
|
42
45
|
self,
|
@@ -73,7 +76,7 @@ class DataManager:
|
|
73
76
|
if offset:
|
74
77
|
query += f" OFFSET {offset}"
|
75
78
|
|
76
|
-
with DatabaseConnection(self.db_path) as conn:
|
79
|
+
with DatabaseConnection(self.db_path, tenant_id=self.tenant, encryption_manager=self.encryption_manager) as conn:
|
77
80
|
cursor = conn.execute(query, params)
|
78
81
|
rows = cursor.fetchall()
|
79
82
|
|
@@ -130,7 +133,7 @@ class DataManager:
|
|
130
133
|
VALUES ({", ".join(placeholders)})
|
131
134
|
"""
|
132
135
|
|
133
|
-
with DatabaseConnection(self.db_path) as conn:
|
136
|
+
with DatabaseConnection(self.db_path, tenant_id=self.tenant, encryption_manager=self.encryption_manager) as conn:
|
134
137
|
try:
|
135
138
|
conn.execute(query, record_data)
|
136
139
|
conn.commit()
|
@@ -233,7 +236,7 @@ class DataManager:
|
|
233
236
|
|
234
237
|
params = {**update_data, "id": data["id"]}
|
235
238
|
|
236
|
-
with DatabaseConnection(self.db_path) as conn:
|
239
|
+
with DatabaseConnection(self.db_path, tenant_id=self.tenant, encryption_manager=self.encryption_manager) as conn:
|
237
240
|
try:
|
238
241
|
conn.execute(query, params)
|
239
242
|
conn.commit()
|
@@ -273,7 +276,7 @@ class DataManager:
|
|
273
276
|
|
274
277
|
query = f"DELETE FROM {table_name} WHERE {where_clause}"
|
275
278
|
|
276
|
-
with DatabaseConnection(self.db_path) as conn:
|
279
|
+
with DatabaseConnection(self.db_path, tenant_id=self.tenant, encryption_manager=self.encryption_manager) as conn:
|
277
280
|
try:
|
278
281
|
cursor = conn.execute(query, params)
|
279
282
|
deleted_count = cursor.rowcount
|
@@ -320,7 +323,7 @@ class DataManager:
|
|
320
323
|
table_name = self._get_table_name(type(instances[0]))
|
321
324
|
created_instances = []
|
322
325
|
|
323
|
-
with DatabaseConnection(self.db_path) as conn:
|
326
|
+
with DatabaseConnection(self.db_path, tenant_id=self.tenant, encryption_manager=self.encryption_manager) as conn:
|
324
327
|
try:
|
325
328
|
for instance in instances:
|
326
329
|
data = instance.model_dump()
|
@@ -370,7 +373,7 @@ class DataManager:
|
|
370
373
|
if where_clause:
|
371
374
|
query += f" WHERE {where_clause}"
|
372
375
|
|
373
|
-
with DatabaseConnection(self.db_path) as conn:
|
376
|
+
with DatabaseConnection(self.db_path, tenant_id=self.tenant, encryption_manager=self.encryption_manager) as conn:
|
374
377
|
cursor = conn.execute(query, params)
|
375
378
|
result = cursor.fetchone()
|
376
379
|
return result["count"] if result else 0
|
@@ -521,7 +524,7 @@ class DataManager:
|
|
521
524
|
|
522
525
|
sql = f"DELETE FROM {table} WHERE {where_clause}"
|
523
526
|
|
524
|
-
with DatabaseConnection(self.db_path) as conn:
|
527
|
+
with DatabaseConnection(self.db_path, tenant_id=self.tenant, encryption_manager=self.encryption_manager) as conn:
|
525
528
|
cursor = conn.execute(sql, params)
|
526
529
|
conn.commit()
|
527
530
|
return cursor.rowcount
|
@@ -585,7 +588,7 @@ class DataManager:
|
|
585
588
|
|
586
589
|
sql = f"UPDATE {table} SET {', '.join(set_clauses)} WHERE {where_clause}"
|
587
590
|
|
588
|
-
with DatabaseConnection(self.db_path) as conn:
|
591
|
+
with DatabaseConnection(self.db_path, tenant_id=self.tenant, encryption_manager=self.encryption_manager) as conn:
|
589
592
|
cursor = conn.execute(sql, all_params)
|
590
593
|
conn.commit()
|
591
594
|
return cursor.rowcount
|
@@ -616,7 +619,7 @@ class DataManager:
|
|
616
619
|
sql = f"UPDATE {table} SET {set_clause} WHERE id = ?"
|
617
620
|
params.append(record_id)
|
618
621
|
|
619
|
-
with DatabaseConnection(self.db_path) as conn:
|
622
|
+
with DatabaseConnection(self.db_path, tenant_id=self.tenant, encryption_manager=self.encryption_manager) as conn:
|
620
623
|
cursor = conn.execute(sql, params)
|
621
624
|
conn.commit()
|
622
625
|
|
@@ -645,7 +648,7 @@ class DataManager:
|
|
645
648
|
"""
|
646
649
|
sql = f"DELETE FROM {table} WHERE id = ?"
|
647
650
|
|
648
|
-
with DatabaseConnection(self.db_path) as conn:
|
651
|
+
with DatabaseConnection(self.db_path, tenant_id=self.tenant, encryption_manager=self.encryption_manager) as conn:
|
649
652
|
cursor = conn.execute(sql, [record_id])
|
650
653
|
conn.commit()
|
651
654
|
return cursor.rowcount > 0
|
cinchdb/managers/query.py
CHANGED
@@ -16,7 +16,8 @@ class QueryManager:
|
|
16
16
|
"""Manages SQL query execution with support for typed returns."""
|
17
17
|
|
18
18
|
def __init__(
|
19
|
-
self, project_root: Path, database: str, branch: str, tenant: str = "main"
|
19
|
+
self, project_root: Path, database: str, branch: str, tenant: str = "main",
|
20
|
+
encryption_manager=None
|
20
21
|
):
|
21
22
|
"""Initialize query manager.
|
22
23
|
|
@@ -25,13 +26,15 @@ class QueryManager:
|
|
25
26
|
database: Database name
|
26
27
|
branch: Branch name
|
27
28
|
tenant: Tenant name (default: main)
|
29
|
+
encryption_manager: EncryptionManager instance for encrypted connections
|
28
30
|
"""
|
29
31
|
self.project_root = Path(project_root)
|
30
32
|
self.database = database
|
31
33
|
self.branch = branch
|
32
34
|
self.tenant = tenant
|
35
|
+
self.encryption_manager = encryption_manager
|
33
36
|
# Initialize tenant manager for lazy tenant handling
|
34
|
-
self.tenant_manager = TenantManager(project_root, database, branch)
|
37
|
+
self.tenant_manager = TenantManager(project_root, database, branch, encryption_manager)
|
35
38
|
|
36
39
|
def _is_write_query(self, sql: str) -> bool:
|
37
40
|
"""Check if a SQL query is a write operation.
|
@@ -84,7 +87,7 @@ class QueryManager:
|
|
84
87
|
self.tenant, is_write=False
|
85
88
|
)
|
86
89
|
|
87
|
-
with DatabaseConnection(db_path) as conn:
|
90
|
+
with DatabaseConnection(db_path, tenant_id=self.tenant, encryption_manager=self.encryption_manager) as conn:
|
88
91
|
cursor = conn.execute(sql, params)
|
89
92
|
rows = cursor.fetchall()
|
90
93
|
return [dict(row) for row in rows]
|
@@ -214,7 +217,7 @@ class QueryManager:
|
|
214
217
|
self.tenant, is_write=True
|
215
218
|
)
|
216
219
|
|
217
|
-
with DatabaseConnection(db_path) as conn:
|
220
|
+
with DatabaseConnection(db_path, tenant_id=self.tenant, encryption_manager=self.encryption_manager) as conn:
|
218
221
|
cursor = conn.execute(sql, params)
|
219
222
|
affected_rows = cursor.rowcount
|
220
223
|
conn.commit()
|
@@ -243,7 +246,7 @@ class QueryManager:
|
|
243
246
|
self.tenant, is_write=is_write
|
244
247
|
)
|
245
248
|
|
246
|
-
with DatabaseConnection(db_path) as conn:
|
249
|
+
with DatabaseConnection(db_path, tenant_id=self.tenant, encryption_manager=self.encryption_manager) as conn:
|
247
250
|
try:
|
248
251
|
for params in params_list:
|
249
252
|
cursor = conn.execute(sql, params)
|
cinchdb/managers/table.py
CHANGED
@@ -24,7 +24,8 @@ class TableManager:
|
|
24
24
|
PROTECTED_TABLE_PREFIXES = ("__", "sqlite_")
|
25
25
|
|
26
26
|
def __init__(
|
27
|
-
self, project_root: Path, database: str, branch: str, tenant: str = "main"
|
27
|
+
self, project_root: Path, database: str, branch: str, tenant: str = "main",
|
28
|
+
encryption_manager=None
|
28
29
|
):
|
29
30
|
"""Initialize table manager.
|
30
31
|
|
@@ -33,14 +34,16 @@ class TableManager:
|
|
33
34
|
database: Database name
|
34
35
|
branch: Branch name
|
35
36
|
tenant: Tenant name (default: main)
|
37
|
+
encryption_manager: EncryptionManager instance for encrypted connections
|
36
38
|
"""
|
37
39
|
self.project_root = Path(project_root)
|
38
40
|
self.database = database
|
39
41
|
self.branch = branch
|
40
42
|
self.tenant = tenant
|
43
|
+
self.encryption_manager = encryption_manager
|
41
44
|
self.db_path = get_tenant_db_path(project_root, database, branch, tenant)
|
42
45
|
self.change_tracker = ChangeTracker(project_root, database, branch)
|
43
|
-
self.tenant_manager = TenantManager(project_root, database, branch)
|
46
|
+
self.tenant_manager = TenantManager(project_root, database, branch, encryption_manager)
|
44
47
|
|
45
48
|
def list_tables(self) -> List[Table]:
|
46
49
|
"""List all tables in the tenant.
|
@@ -50,7 +53,7 @@ class TableManager:
|
|
50
53
|
"""
|
51
54
|
tables = []
|
52
55
|
|
53
|
-
with DatabaseConnection(self.db_path) as conn:
|
56
|
+
with DatabaseConnection(self.db_path, tenant_id=self.tenant, encryption_manager=self.encryption_manager) as conn:
|
54
57
|
# Get all tables first, then filter in Python (more reliable than SQL LIKE)
|
55
58
|
cursor = conn.execute(
|
56
59
|
"""
|
@@ -230,7 +233,7 @@ class TableManager:
|
|
230
233
|
columns = []
|
231
234
|
foreign_keys = {}
|
232
235
|
|
233
|
-
with DatabaseConnection(self.db_path) as conn:
|
236
|
+
with DatabaseConnection(self.db_path, tenant_id=self.tenant, encryption_manager=self.encryption_manager) as conn:
|
234
237
|
# Get foreign key information first
|
235
238
|
fk_cursor = conn.execute(f"PRAGMA foreign_key_list({table_name})")
|
236
239
|
for fk_row in fk_cursor.fetchall():
|
@@ -423,7 +426,7 @@ class TableManager:
|
|
423
426
|
Returns:
|
424
427
|
True if table exists
|
425
428
|
"""
|
426
|
-
with DatabaseConnection(self.db_path) as conn:
|
429
|
+
with DatabaseConnection(self.db_path, tenant_id=self.tenant, encryption_manager=self.encryption_manager) as conn:
|
427
430
|
cursor = conn.execute(
|
428
431
|
"SELECT name FROM sqlite_master WHERE type='table' AND name=?",
|
429
432
|
(table_name,),
|