cinchdb 0.1.0__py3-none-any.whl → 0.1.2__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/branch.py +9 -0
- cinchdb/cli/commands/database.py +9 -0
- cinchdb/cli/commands/tenant.py +17 -0
- cinchdb/managers/branch.py +5 -0
- cinchdb/managers/tenant.py +13 -0
- cinchdb/models/branch.py +9 -1
- cinchdb/models/database.py +9 -1
- cinchdb/models/tenant.py +9 -1
- cinchdb/utils/__init__.py +11 -1
- cinchdb/utils/name_validator.py +129 -0
- {cinchdb-0.1.0.dist-info → cinchdb-0.1.2.dist-info}/METADATA +17 -19
- {cinchdb-0.1.0.dist-info → cinchdb-0.1.2.dist-info}/RECORD +15 -30
- {cinchdb-0.1.0.dist-info → cinchdb-0.1.2.dist-info}/entry_points.txt +0 -1
- cinchdb/api/__init__.py +0 -5
- cinchdb/api/app.py +0 -76
- cinchdb/api/auth.py +0 -290
- cinchdb/api/main.py +0 -137
- cinchdb/api/routers/__init__.py +0 -25
- cinchdb/api/routers/auth.py +0 -135
- cinchdb/api/routers/branches.py +0 -368
- cinchdb/api/routers/codegen.py +0 -164
- cinchdb/api/routers/columns.py +0 -290
- cinchdb/api/routers/data.py +0 -479
- cinchdb/api/routers/databases.py +0 -177
- cinchdb/api/routers/projects.py +0 -133
- cinchdb/api/routers/query.py +0 -156
- cinchdb/api/routers/tables.py +0 -349
- cinchdb/api/routers/tenants.py +0 -216
- cinchdb/api/routers/views.py +0 -219
- {cinchdb-0.1.0.dist-info → cinchdb-0.1.2.dist-info}/WHEEL +0 -0
- {cinchdb-0.1.0.dist-info → cinchdb-0.1.2.dist-info}/licenses/LICENSE +0 -0
cinchdb/api/routers/tenants.py
DELETED
@@ -1,216 +0,0 @@
|
|
1
|
-
"""Tenants router for CinchDB API."""
|
2
|
-
|
3
|
-
from typing import List
|
4
|
-
from fastapi import APIRouter, Depends, HTTPException, Query
|
5
|
-
from pydantic import BaseModel
|
6
|
-
|
7
|
-
from cinchdb.core.database import CinchDB
|
8
|
-
from cinchdb.api.auth import (
|
9
|
-
AuthContext,
|
10
|
-
require_write_permission,
|
11
|
-
require_read_permission,
|
12
|
-
)
|
13
|
-
|
14
|
-
|
15
|
-
router = APIRouter()
|
16
|
-
|
17
|
-
|
18
|
-
class TenantInfo(BaseModel):
|
19
|
-
"""Tenant information."""
|
20
|
-
|
21
|
-
name: str
|
22
|
-
size_bytes: int
|
23
|
-
is_protected: bool
|
24
|
-
|
25
|
-
|
26
|
-
class CreateTenantRequest(BaseModel):
|
27
|
-
"""Request to create a tenant."""
|
28
|
-
|
29
|
-
name: str
|
30
|
-
|
31
|
-
|
32
|
-
class RenameTenantRequest(BaseModel):
|
33
|
-
"""Request to rename a tenant."""
|
34
|
-
|
35
|
-
new_name: str
|
36
|
-
|
37
|
-
|
38
|
-
class CopyTenantRequest(BaseModel):
|
39
|
-
"""Request to copy a tenant."""
|
40
|
-
|
41
|
-
source: str
|
42
|
-
target: str
|
43
|
-
copy_data: bool = True
|
44
|
-
|
45
|
-
|
46
|
-
@router.get("/", response_model=List[TenantInfo])
|
47
|
-
async def list_tenants(
|
48
|
-
database: str = Query(..., description="Database name"),
|
49
|
-
branch: str = Query(..., description="Branch name"),
|
50
|
-
auth: AuthContext = Depends(require_read_permission),
|
51
|
-
):
|
52
|
-
"""List all tenants in a branch."""
|
53
|
-
db_name = database
|
54
|
-
branch_name = branch
|
55
|
-
|
56
|
-
# Check branch permissions
|
57
|
-
await require_read_permission(auth, branch_name)
|
58
|
-
|
59
|
-
try:
|
60
|
-
db = CinchDB(
|
61
|
-
database=db_name,
|
62
|
-
branch=branch_name,
|
63
|
-
tenant="main",
|
64
|
-
project_dir=auth.project_dir,
|
65
|
-
)
|
66
|
-
tenants = db.tenants.list_tenants()
|
67
|
-
|
68
|
-
result = []
|
69
|
-
for tenant in tenants:
|
70
|
-
# Get tenant size
|
71
|
-
db_path = (
|
72
|
-
auth.project_dir
|
73
|
-
/ ".cinchdb"
|
74
|
-
/ "databases"
|
75
|
-
/ db_name
|
76
|
-
/ "branches"
|
77
|
-
/ branch_name
|
78
|
-
/ "tenants"
|
79
|
-
/ f"{tenant.name}.db"
|
80
|
-
)
|
81
|
-
size = db_path.stat().st_size if db_path.exists() else 0
|
82
|
-
|
83
|
-
result.append(
|
84
|
-
TenantInfo(name=tenant.name, size_bytes=size, is_protected=tenant.is_main)
|
85
|
-
)
|
86
|
-
|
87
|
-
return result
|
88
|
-
|
89
|
-
except ValueError as e:
|
90
|
-
raise HTTPException(status_code=404, detail=str(e))
|
91
|
-
|
92
|
-
|
93
|
-
@router.post("/")
|
94
|
-
async def create_tenant(
|
95
|
-
request: CreateTenantRequest,
|
96
|
-
database: str = Query(..., description="Database name"),
|
97
|
-
branch: str = Query(..., description="Branch name"),
|
98
|
-
auth: AuthContext = Depends(require_write_permission),
|
99
|
-
):
|
100
|
-
"""Create a new tenant."""
|
101
|
-
db_name = database
|
102
|
-
branch_name = branch
|
103
|
-
|
104
|
-
# Check branch permissions
|
105
|
-
await require_write_permission(auth, branch_name)
|
106
|
-
|
107
|
-
try:
|
108
|
-
db = CinchDB(
|
109
|
-
database=db_name,
|
110
|
-
branch=branch_name,
|
111
|
-
tenant="main",
|
112
|
-
project_dir=auth.project_dir,
|
113
|
-
)
|
114
|
-
db.tenants.create_tenant(request.name)
|
115
|
-
|
116
|
-
return {"message": f"Created tenant '{request.name}'"}
|
117
|
-
|
118
|
-
except ValueError as e:
|
119
|
-
raise HTTPException(status_code=400, detail=str(e))
|
120
|
-
|
121
|
-
|
122
|
-
@router.delete("/{name}")
|
123
|
-
async def delete_tenant(
|
124
|
-
name: str,
|
125
|
-
database: str = Query(..., description="Database name"),
|
126
|
-
branch: str = Query(..., description="Branch name"),
|
127
|
-
auth: AuthContext = Depends(require_write_permission),
|
128
|
-
):
|
129
|
-
"""Delete a tenant."""
|
130
|
-
if name == "main":
|
131
|
-
raise HTTPException(status_code=400, detail="Cannot delete the main tenant")
|
132
|
-
|
133
|
-
db_name = database
|
134
|
-
branch_name = branch
|
135
|
-
|
136
|
-
# Check branch permissions
|
137
|
-
await require_write_permission(auth, branch_name)
|
138
|
-
|
139
|
-
try:
|
140
|
-
db = CinchDB(
|
141
|
-
database=db_name,
|
142
|
-
branch=branch_name,
|
143
|
-
tenant="main",
|
144
|
-
project_dir=auth.project_dir,
|
145
|
-
)
|
146
|
-
db.tenants.delete_tenant(name)
|
147
|
-
|
148
|
-
return {"message": f"Deleted tenant '{name}'"}
|
149
|
-
|
150
|
-
except ValueError as e:
|
151
|
-
raise HTTPException(status_code=404, detail=str(e))
|
152
|
-
|
153
|
-
|
154
|
-
@router.put("/{name}/rename")
|
155
|
-
async def rename_tenant(
|
156
|
-
name: str,
|
157
|
-
request: RenameTenantRequest,
|
158
|
-
database: str = Query(..., description="Database name"),
|
159
|
-
branch: str = Query(..., description="Branch name"),
|
160
|
-
auth: AuthContext = Depends(require_write_permission),
|
161
|
-
):
|
162
|
-
"""Rename a tenant."""
|
163
|
-
if name == "main":
|
164
|
-
raise HTTPException(status_code=400, detail="Cannot rename the main tenant")
|
165
|
-
|
166
|
-
db_name = database
|
167
|
-
branch_name = branch
|
168
|
-
|
169
|
-
# Check branch permissions
|
170
|
-
await require_write_permission(auth, branch_name)
|
171
|
-
|
172
|
-
try:
|
173
|
-
db = CinchDB(
|
174
|
-
database=db_name,
|
175
|
-
branch=branch_name,
|
176
|
-
tenant="main",
|
177
|
-
project_dir=auth.project_dir,
|
178
|
-
)
|
179
|
-
db.tenants.rename_tenant(name, request.new_name)
|
180
|
-
|
181
|
-
return {"message": f"Renamed tenant '{name}' to '{request.new_name}'"}
|
182
|
-
|
183
|
-
except ValueError as e:
|
184
|
-
raise HTTPException(status_code=400, detail=str(e))
|
185
|
-
|
186
|
-
|
187
|
-
@router.post("/copy")
|
188
|
-
async def copy_tenant(
|
189
|
-
request: CopyTenantRequest,
|
190
|
-
database: str = Query(..., description="Database name"),
|
191
|
-
branch: str = Query(..., description="Branch name"),
|
192
|
-
auth: AuthContext = Depends(require_write_permission),
|
193
|
-
):
|
194
|
-
"""Copy a tenant to a new tenant."""
|
195
|
-
db_name = database
|
196
|
-
branch_name = branch
|
197
|
-
|
198
|
-
# Check branch permissions
|
199
|
-
await require_write_permission(auth, branch_name)
|
200
|
-
|
201
|
-
try:
|
202
|
-
db = CinchDB(
|
203
|
-
database=db_name,
|
204
|
-
branch=branch_name,
|
205
|
-
tenant="main",
|
206
|
-
project_dir=auth.project_dir,
|
207
|
-
)
|
208
|
-
db.tenants.copy_tenant(request.source, request.target, request.copy_data)
|
209
|
-
|
210
|
-
data_msg = "with data" if request.copy_data else "without data"
|
211
|
-
return {
|
212
|
-
"message": f"Copied tenant '{request.source}' to '{request.target}' {data_msg}"
|
213
|
-
}
|
214
|
-
|
215
|
-
except ValueError as e:
|
216
|
-
raise HTTPException(status_code=400, detail=str(e))
|
cinchdb/api/routers/views.py
DELETED
@@ -1,219 +0,0 @@
|
|
1
|
-
"""Views router for CinchDB API."""
|
2
|
-
|
3
|
-
from typing import List, Optional
|
4
|
-
from fastapi import APIRouter, Depends, HTTPException, Query
|
5
|
-
from pydantic import BaseModel
|
6
|
-
|
7
|
-
from cinchdb.core.database import CinchDB
|
8
|
-
from cinchdb.managers.change_applier import ChangeApplier
|
9
|
-
from cinchdb.api.auth import (
|
10
|
-
AuthContext,
|
11
|
-
require_write_permission,
|
12
|
-
require_read_permission,
|
13
|
-
)
|
14
|
-
|
15
|
-
|
16
|
-
router = APIRouter()
|
17
|
-
|
18
|
-
|
19
|
-
class ViewInfo(BaseModel):
|
20
|
-
"""View information."""
|
21
|
-
|
22
|
-
name: str
|
23
|
-
sql_statement: str
|
24
|
-
sql_length: int
|
25
|
-
description: Optional[str]
|
26
|
-
|
27
|
-
|
28
|
-
class CreateViewRequest(BaseModel):
|
29
|
-
"""Request to create a view."""
|
30
|
-
|
31
|
-
name: str
|
32
|
-
sql: str
|
33
|
-
description: Optional[str] = None
|
34
|
-
|
35
|
-
|
36
|
-
class UpdateViewRequest(BaseModel):
|
37
|
-
"""Request to update a view."""
|
38
|
-
|
39
|
-
sql: str
|
40
|
-
description: Optional[str] = None
|
41
|
-
|
42
|
-
|
43
|
-
@router.get("/", response_model=List[ViewInfo])
|
44
|
-
async def list_views(
|
45
|
-
database: str = Query(..., description="Database name"),
|
46
|
-
branch: str = Query(..., description="Branch name"),
|
47
|
-
auth: AuthContext = Depends(require_read_permission),
|
48
|
-
):
|
49
|
-
"""List all views in a branch."""
|
50
|
-
db_name = database
|
51
|
-
branch_name = branch
|
52
|
-
|
53
|
-
# Check branch permissions
|
54
|
-
await require_read_permission(auth, branch_name)
|
55
|
-
|
56
|
-
try:
|
57
|
-
db = CinchDB(
|
58
|
-
database=db_name,
|
59
|
-
branch=branch_name,
|
60
|
-
tenant="main",
|
61
|
-
project_dir=auth.project_dir,
|
62
|
-
)
|
63
|
-
views = db.views.list_views()
|
64
|
-
|
65
|
-
result = []
|
66
|
-
for view in views:
|
67
|
-
result.append(
|
68
|
-
ViewInfo(
|
69
|
-
name=view.name,
|
70
|
-
sql_statement=view.sql_statement,
|
71
|
-
sql_length=len(view.sql_statement) if view.sql_statement else 0,
|
72
|
-
description=view.description,
|
73
|
-
)
|
74
|
-
)
|
75
|
-
|
76
|
-
return result
|
77
|
-
|
78
|
-
except ValueError as e:
|
79
|
-
raise HTTPException(status_code=404, detail=str(e))
|
80
|
-
|
81
|
-
|
82
|
-
@router.post("/")
|
83
|
-
async def create_view(
|
84
|
-
request: CreateViewRequest,
|
85
|
-
database: str = Query(..., description="Database name"),
|
86
|
-
branch: str = Query(..., description="Branch name"),
|
87
|
-
apply: bool = Query(True, description="Apply changes to all tenants"),
|
88
|
-
auth: AuthContext = Depends(require_write_permission),
|
89
|
-
):
|
90
|
-
"""Create a new view."""
|
91
|
-
db_name = database
|
92
|
-
branch_name = branch
|
93
|
-
|
94
|
-
# Check branch permissions
|
95
|
-
await require_write_permission(auth, branch_name)
|
96
|
-
|
97
|
-
try:
|
98
|
-
db = CinchDB(
|
99
|
-
database=db_name,
|
100
|
-
branch=branch_name,
|
101
|
-
tenant="main",
|
102
|
-
project_dir=auth.project_dir,
|
103
|
-
)
|
104
|
-
db.views.create_view(request.name, request.sql, request.description)
|
105
|
-
|
106
|
-
# Apply to all tenants if requested
|
107
|
-
if apply:
|
108
|
-
applier = ChangeApplier(auth.project_dir, db_name, branch_name)
|
109
|
-
applier.apply_all_unapplied()
|
110
|
-
|
111
|
-
return {"message": f"Created view '{request.name}'"}
|
112
|
-
|
113
|
-
except ValueError as e:
|
114
|
-
raise HTTPException(status_code=400, detail=str(e))
|
115
|
-
|
116
|
-
|
117
|
-
@router.put("/{name}")
|
118
|
-
async def update_view(
|
119
|
-
name: str,
|
120
|
-
request: UpdateViewRequest,
|
121
|
-
database: str = Query(..., description="Database name"),
|
122
|
-
branch: str = Query(..., description="Branch name"),
|
123
|
-
apply: bool = Query(True, description="Apply changes to all tenants"),
|
124
|
-
auth: AuthContext = Depends(require_write_permission),
|
125
|
-
):
|
126
|
-
"""Update an existing view."""
|
127
|
-
db_name = database
|
128
|
-
branch_name = branch
|
129
|
-
|
130
|
-
# Check branch permissions
|
131
|
-
await require_write_permission(auth, branch_name)
|
132
|
-
|
133
|
-
try:
|
134
|
-
db = CinchDB(
|
135
|
-
database=db_name,
|
136
|
-
branch=branch_name,
|
137
|
-
tenant="main",
|
138
|
-
project_dir=auth.project_dir,
|
139
|
-
)
|
140
|
-
db.views.update_view(name, request.sql, request.description)
|
141
|
-
|
142
|
-
# Apply to all tenants if requested
|
143
|
-
if apply:
|
144
|
-
applier = ChangeApplier(auth.project_dir, db_name, branch_name)
|
145
|
-
applier.apply_all_unapplied()
|
146
|
-
|
147
|
-
return {"message": f"Updated view '{name}'"}
|
148
|
-
|
149
|
-
except ValueError as e:
|
150
|
-
raise HTTPException(status_code=400, detail=str(e))
|
151
|
-
|
152
|
-
|
153
|
-
@router.delete("/{name}")
|
154
|
-
async def delete_view(
|
155
|
-
name: str,
|
156
|
-
database: str = Query(..., description="Database name"),
|
157
|
-
branch: str = Query(..., description="Branch name"),
|
158
|
-
apply: bool = Query(True, description="Apply changes to all tenants"),
|
159
|
-
auth: AuthContext = Depends(require_write_permission),
|
160
|
-
):
|
161
|
-
"""Delete a view."""
|
162
|
-
db_name = database
|
163
|
-
branch_name = branch
|
164
|
-
|
165
|
-
# Check branch permissions
|
166
|
-
await require_write_permission(auth, branch_name)
|
167
|
-
|
168
|
-
try:
|
169
|
-
db = CinchDB(
|
170
|
-
database=db_name,
|
171
|
-
branch=branch_name,
|
172
|
-
tenant="main",
|
173
|
-
project_dir=auth.project_dir,
|
174
|
-
)
|
175
|
-
db.views.delete_view(name)
|
176
|
-
|
177
|
-
# Apply to all tenants if requested
|
178
|
-
if apply:
|
179
|
-
applier = ChangeApplier(auth.project_dir, db_name, branch_name)
|
180
|
-
applier.apply_all_unapplied()
|
181
|
-
|
182
|
-
return {"message": f"Deleted view '{name}'"}
|
183
|
-
|
184
|
-
except ValueError as e:
|
185
|
-
raise HTTPException(status_code=404, detail=str(e))
|
186
|
-
|
187
|
-
|
188
|
-
@router.get("/{name}")
|
189
|
-
async def get_view_info(
|
190
|
-
name: str,
|
191
|
-
database: str = Query(..., description="Database name"),
|
192
|
-
branch: str = Query(..., description="Branch name"),
|
193
|
-
auth: AuthContext = Depends(require_read_permission),
|
194
|
-
) -> ViewInfo:
|
195
|
-
"""Get information about a specific view."""
|
196
|
-
db_name = database
|
197
|
-
branch_name = branch
|
198
|
-
|
199
|
-
# Check branch permissions
|
200
|
-
await require_read_permission(auth, branch_name)
|
201
|
-
|
202
|
-
try:
|
203
|
-
db = CinchDB(
|
204
|
-
database=db_name,
|
205
|
-
branch=branch_name,
|
206
|
-
tenant="main",
|
207
|
-
project_dir=auth.project_dir,
|
208
|
-
)
|
209
|
-
view = db.views.get_view(name)
|
210
|
-
|
211
|
-
return ViewInfo(
|
212
|
-
name=view.name,
|
213
|
-
sql_statement=view.sql_statement,
|
214
|
-
sql_length=len(view.sql_statement) if view.sql_statement else 0,
|
215
|
-
description=view.description,
|
216
|
-
)
|
217
|
-
|
218
|
-
except ValueError as e:
|
219
|
-
raise HTTPException(status_code=404, detail=str(e))
|
File without changes
|
File without changes
|