cinchdb 0.1.1__py3-none-any.whl → 0.1.3__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/utils/name_validator.py +6 -6
- {cinchdb-0.1.1.dist-info → cinchdb-0.1.3.dist-info}/METADATA +16 -18
- {cinchdb-0.1.1.dist-info → cinchdb-0.1.3.dist-info}/RECORD +6 -22
- {cinchdb-0.1.1.dist-info → cinchdb-0.1.3.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 -184
- 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.1.dist-info → cinchdb-0.1.3.dist-info}/WHEEL +0 -0
- {cinchdb-0.1.1.dist-info → cinchdb-0.1.3.dist-info}/licenses/LICENSE +0 -0
cinchdb/api/routers/codegen.py
DELETED
@@ -1,164 +0,0 @@
|
|
1
|
-
"""Code generation router for CinchDB API."""
|
2
|
-
|
3
|
-
import tempfile
|
4
|
-
from typing import List, Dict
|
5
|
-
from pathlib import Path
|
6
|
-
from fastapi import APIRouter, Depends, HTTPException, Query
|
7
|
-
from pydantic import BaseModel
|
8
|
-
|
9
|
-
from cinchdb.core.database import CinchDB
|
10
|
-
from cinchdb.api.auth import AuthContext, require_read_permission
|
11
|
-
|
12
|
-
|
13
|
-
router = APIRouter()
|
14
|
-
|
15
|
-
|
16
|
-
class CodegenLanguage(BaseModel):
|
17
|
-
"""Supported language for code generation."""
|
18
|
-
|
19
|
-
name: str
|
20
|
-
description: str
|
21
|
-
|
22
|
-
|
23
|
-
class GenerateModelsRequest(BaseModel):
|
24
|
-
"""Request to generate models."""
|
25
|
-
|
26
|
-
language: str
|
27
|
-
include_tables: bool = True
|
28
|
-
include_views: bool = True
|
29
|
-
|
30
|
-
|
31
|
-
@router.get("/languages", response_model=List[CodegenLanguage])
|
32
|
-
async def list_supported_languages():
|
33
|
-
"""List supported code generation languages."""
|
34
|
-
# Using a temporary CinchDB to get supported languages
|
35
|
-
# This doesn't require specific database/branch so we use dummy values
|
36
|
-
temp_project = Path(tempfile.mkdtemp())
|
37
|
-
try:
|
38
|
-
db = CinchDB(
|
39
|
-
database="dummy", branch="dummy", tenant="dummy", project_dir=temp_project
|
40
|
-
)
|
41
|
-
languages = db.codegen.get_supported_languages()
|
42
|
-
|
43
|
-
# Map languages to descriptions
|
44
|
-
language_info = {
|
45
|
-
"python": "Python Pydantic models with full CRUD operations",
|
46
|
-
"typescript": "TypeScript interfaces and classes (planned)",
|
47
|
-
}
|
48
|
-
|
49
|
-
return [
|
50
|
-
CodegenLanguage(
|
51
|
-
name=lang, description=language_info.get(lang, f"{lang.title()} models")
|
52
|
-
)
|
53
|
-
for lang in languages
|
54
|
-
]
|
55
|
-
finally:
|
56
|
-
# Clean up temp directory
|
57
|
-
import shutil
|
58
|
-
|
59
|
-
shutil.rmtree(temp_project, ignore_errors=True)
|
60
|
-
|
61
|
-
|
62
|
-
@router.post("/generate/files", response_model=Dict[str, str])
|
63
|
-
async def generate_model_files_content(
|
64
|
-
request: GenerateModelsRequest,
|
65
|
-
database: str = Query(..., description="Database name"),
|
66
|
-
branch: str = Query(..., description="Branch name"),
|
67
|
-
auth: AuthContext = Depends(require_read_permission),
|
68
|
-
):
|
69
|
-
"""Generate model files and return their content as JSON (alternative to ZIP download)."""
|
70
|
-
db_name = database
|
71
|
-
branch_name = branch
|
72
|
-
|
73
|
-
# Check branch permissions
|
74
|
-
await require_read_permission(auth, branch_name)
|
75
|
-
|
76
|
-
try:
|
77
|
-
# Create temporary directory for generation
|
78
|
-
temp_dir = Path(tempfile.mkdtemp())
|
79
|
-
output_dir = temp_dir / "generated_models"
|
80
|
-
|
81
|
-
# Initialize CinchDB and get codegen manager
|
82
|
-
db = CinchDB(
|
83
|
-
database=db_name,
|
84
|
-
branch=branch_name,
|
85
|
-
tenant="main",
|
86
|
-
project_dir=auth.project_dir,
|
87
|
-
)
|
88
|
-
codegen_mgr = db.codegen
|
89
|
-
|
90
|
-
# Generate models
|
91
|
-
results = codegen_mgr.generate_models(
|
92
|
-
language=request.language,
|
93
|
-
output_dir=output_dir,
|
94
|
-
include_tables=request.include_tables,
|
95
|
-
include_views=request.include_views,
|
96
|
-
)
|
97
|
-
|
98
|
-
# Read generated files and return their content
|
99
|
-
file_contents = {}
|
100
|
-
|
101
|
-
for file_name in results["files_generated"]:
|
102
|
-
file_path = output_dir / file_name
|
103
|
-
if file_path.exists():
|
104
|
-
with open(file_path, "r", encoding="utf-8") as f:
|
105
|
-
file_contents[file_name] = f.read()
|
106
|
-
|
107
|
-
# Clean up temp directory
|
108
|
-
import shutil
|
109
|
-
|
110
|
-
shutil.rmtree(temp_dir, ignore_errors=True)
|
111
|
-
|
112
|
-
return file_contents
|
113
|
-
|
114
|
-
except ValueError as e:
|
115
|
-
raise HTTPException(status_code=400, detail=str(e))
|
116
|
-
except Exception as e:
|
117
|
-
raise HTTPException(status_code=500, detail=f"Code generation failed: {str(e)}")
|
118
|
-
|
119
|
-
|
120
|
-
@router.get("/info")
|
121
|
-
async def get_codegen_info(
|
122
|
-
database: str = Query(..., description="Database name"),
|
123
|
-
branch: str = Query(..., description="Branch name"),
|
124
|
-
auth: AuthContext = Depends(require_read_permission),
|
125
|
-
):
|
126
|
-
"""Get information about what can be generated for the current database/branch."""
|
127
|
-
db_name = database
|
128
|
-
branch_name = branch
|
129
|
-
|
130
|
-
# Check branch permissions
|
131
|
-
await require_read_permission(auth, branch_name)
|
132
|
-
|
133
|
-
try:
|
134
|
-
# Initialize CinchDB and get codegen manager
|
135
|
-
db = CinchDB(
|
136
|
-
database=db_name,
|
137
|
-
branch=branch_name,
|
138
|
-
tenant="main",
|
139
|
-
project_dir=auth.project_dir,
|
140
|
-
)
|
141
|
-
codegen_mgr = db.codegen
|
142
|
-
|
143
|
-
# Get available tables and views using CinchDB
|
144
|
-
db = CinchDB(
|
145
|
-
database=db_name,
|
146
|
-
branch=branch_name,
|
147
|
-
tenant="main",
|
148
|
-
project_dir=auth.project_dir,
|
149
|
-
)
|
150
|
-
tables = db.tables.list_tables()
|
151
|
-
views = db.views.list_views()
|
152
|
-
|
153
|
-
return {
|
154
|
-
"database": db_name,
|
155
|
-
"branch": branch_name,
|
156
|
-
"tenant": "main",
|
157
|
-
"supported_languages": codegen_mgr.get_supported_languages(),
|
158
|
-
"available_tables": [table.name for table in tables],
|
159
|
-
"available_views": [view.name for view in views],
|
160
|
-
"total_entities": len(tables) + len(views),
|
161
|
-
}
|
162
|
-
|
163
|
-
except ValueError as e:
|
164
|
-
raise HTTPException(status_code=404, detail=str(e))
|
cinchdb/api/routers/columns.py
DELETED
@@ -1,290 +0,0 @@
|
|
1
|
-
"""Columns router for CinchDB API."""
|
2
|
-
|
3
|
-
from typing import List, Optional, Any
|
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.models import Column
|
10
|
-
from cinchdb.api.auth import (
|
11
|
-
AuthContext,
|
12
|
-
require_write_permission,
|
13
|
-
require_read_permission,
|
14
|
-
)
|
15
|
-
|
16
|
-
|
17
|
-
router = APIRouter()
|
18
|
-
|
19
|
-
|
20
|
-
class ColumnInfo(BaseModel):
|
21
|
-
"""Column information."""
|
22
|
-
|
23
|
-
name: str
|
24
|
-
type: str
|
25
|
-
nullable: bool
|
26
|
-
default: Optional[str]
|
27
|
-
primary_key: bool
|
28
|
-
unique: bool
|
29
|
-
|
30
|
-
|
31
|
-
class AddColumnRequest(BaseModel):
|
32
|
-
"""Request to add a column."""
|
33
|
-
|
34
|
-
name: str
|
35
|
-
type: str
|
36
|
-
nullable: bool = True
|
37
|
-
default: Optional[str] = None
|
38
|
-
|
39
|
-
|
40
|
-
class RenameColumnRequest(BaseModel):
|
41
|
-
"""Request to rename a column."""
|
42
|
-
|
43
|
-
old_name: str
|
44
|
-
new_name: str
|
45
|
-
|
46
|
-
|
47
|
-
class AlterNullableRequest(BaseModel):
|
48
|
-
"""Request to alter column nullable constraint."""
|
49
|
-
|
50
|
-
nullable: bool
|
51
|
-
fill_value: Optional[Any] = None
|
52
|
-
|
53
|
-
|
54
|
-
@router.get("/{table}/columns", response_model=List[ColumnInfo])
|
55
|
-
async def list_columns(
|
56
|
-
table: str,
|
57
|
-
database: str = Query(..., description="Database name"),
|
58
|
-
branch: str = Query(..., description="Branch name"),
|
59
|
-
auth: AuthContext = Depends(require_read_permission),
|
60
|
-
):
|
61
|
-
"""List all columns in a table."""
|
62
|
-
db_name = database
|
63
|
-
branch_name = branch
|
64
|
-
|
65
|
-
# Check branch permissions
|
66
|
-
await require_read_permission(auth, branch_name)
|
67
|
-
|
68
|
-
try:
|
69
|
-
db = CinchDB(
|
70
|
-
database=db_name,
|
71
|
-
branch=branch_name,
|
72
|
-
tenant="main",
|
73
|
-
project_dir=auth.project_dir,
|
74
|
-
)
|
75
|
-
columns = db.columns.list_columns(table)
|
76
|
-
|
77
|
-
result = []
|
78
|
-
for col in columns:
|
79
|
-
result.append(
|
80
|
-
ColumnInfo(
|
81
|
-
name=col.name,
|
82
|
-
type=col.type,
|
83
|
-
nullable=col.nullable,
|
84
|
-
default=col.default,
|
85
|
-
primary_key=col.primary_key,
|
86
|
-
unique=col.unique,
|
87
|
-
)
|
88
|
-
)
|
89
|
-
|
90
|
-
return result
|
91
|
-
|
92
|
-
except ValueError as e:
|
93
|
-
raise HTTPException(status_code=404, detail=str(e))
|
94
|
-
|
95
|
-
|
96
|
-
@router.post("/{table}/columns")
|
97
|
-
async def add_column(
|
98
|
-
table: str,
|
99
|
-
request: AddColumnRequest,
|
100
|
-
database: str = Query(..., description="Database name"),
|
101
|
-
branch: str = Query(..., description="Branch name"),
|
102
|
-
apply: bool = Query(True, description="Apply changes to all tenants"),
|
103
|
-
auth: AuthContext = Depends(require_write_permission),
|
104
|
-
):
|
105
|
-
"""Add a new column to a table."""
|
106
|
-
db_name = database
|
107
|
-
branch_name = branch
|
108
|
-
|
109
|
-
# Check branch permissions
|
110
|
-
await require_write_permission(auth, branch_name)
|
111
|
-
|
112
|
-
# Validate type
|
113
|
-
if request.type.upper() not in ["TEXT", "INTEGER", "REAL", "BLOB", "NUMERIC"]:
|
114
|
-
raise HTTPException(
|
115
|
-
status_code=400, detail=f"Invalid column type: {request.type}"
|
116
|
-
)
|
117
|
-
|
118
|
-
try:
|
119
|
-
db = CinchDB(
|
120
|
-
database=db_name,
|
121
|
-
branch=branch_name,
|
122
|
-
tenant="main",
|
123
|
-
project_dir=auth.project_dir,
|
124
|
-
)
|
125
|
-
column = Column(
|
126
|
-
name=request.name,
|
127
|
-
type=request.type.upper(),
|
128
|
-
nullable=request.nullable,
|
129
|
-
default=request.default,
|
130
|
-
)
|
131
|
-
db.columns.add_column(table, column)
|
132
|
-
|
133
|
-
# Apply to all tenants if requested
|
134
|
-
if apply:
|
135
|
-
applier = ChangeApplier(auth.project_dir, db_name, branch_name)
|
136
|
-
applier.apply_all_unapplied()
|
137
|
-
|
138
|
-
return {"message": f"Added column '{request.name}' to table '{table}'"}
|
139
|
-
|
140
|
-
except ValueError as e:
|
141
|
-
raise HTTPException(status_code=400, detail=str(e))
|
142
|
-
|
143
|
-
|
144
|
-
@router.delete("/{table}/columns/{column}")
|
145
|
-
async def drop_column(
|
146
|
-
table: str,
|
147
|
-
column: str,
|
148
|
-
database: str = Query(..., description="Database name"),
|
149
|
-
branch: str = Query(..., description="Branch name"),
|
150
|
-
apply: bool = Query(True, description="Apply changes to all tenants"),
|
151
|
-
auth: AuthContext = Depends(require_write_permission),
|
152
|
-
):
|
153
|
-
"""Drop a column from a table."""
|
154
|
-
db_name = database
|
155
|
-
branch_name = branch
|
156
|
-
|
157
|
-
# Check branch permissions
|
158
|
-
await require_write_permission(auth, branch_name)
|
159
|
-
|
160
|
-
try:
|
161
|
-
db = CinchDB(
|
162
|
-
database=db_name,
|
163
|
-
branch=branch_name,
|
164
|
-
tenant="main",
|
165
|
-
project_dir=auth.project_dir,
|
166
|
-
)
|
167
|
-
db.columns.drop_column(table, column)
|
168
|
-
|
169
|
-
# Apply to all tenants if requested
|
170
|
-
if apply:
|
171
|
-
applier = ChangeApplier(auth.project_dir, db_name, branch_name)
|
172
|
-
applier.apply_all_unapplied()
|
173
|
-
|
174
|
-
return {"message": f"Dropped column '{column}' from table '{table}'"}
|
175
|
-
|
176
|
-
except ValueError as e:
|
177
|
-
raise HTTPException(status_code=400, detail=str(e))
|
178
|
-
|
179
|
-
|
180
|
-
@router.put("/{table}/columns/rename")
|
181
|
-
async def rename_column(
|
182
|
-
table: str,
|
183
|
-
request: RenameColumnRequest,
|
184
|
-
database: str = Query(..., description="Database name"),
|
185
|
-
branch: str = Query(..., description="Branch name"),
|
186
|
-
apply: bool = Query(True, description="Apply changes to all tenants"),
|
187
|
-
auth: AuthContext = Depends(require_write_permission),
|
188
|
-
):
|
189
|
-
"""Rename a column in a table."""
|
190
|
-
db_name = database
|
191
|
-
branch_name = branch
|
192
|
-
|
193
|
-
# Check branch permissions
|
194
|
-
await require_write_permission(auth, branch_name)
|
195
|
-
|
196
|
-
try:
|
197
|
-
db = CinchDB(
|
198
|
-
database=db_name,
|
199
|
-
branch=branch_name,
|
200
|
-
tenant="main",
|
201
|
-
project_dir=auth.project_dir,
|
202
|
-
)
|
203
|
-
db.columns.rename_column(table, request.old_name, request.new_name)
|
204
|
-
|
205
|
-
# Apply to all tenants if requested
|
206
|
-
if apply:
|
207
|
-
applier = ChangeApplier(auth.project_dir, db_name, branch_name)
|
208
|
-
applier.apply_all_unapplied()
|
209
|
-
|
210
|
-
return {
|
211
|
-
"message": f"Renamed column '{request.old_name}' to '{request.new_name}' in table '{table}'"
|
212
|
-
}
|
213
|
-
|
214
|
-
except ValueError as e:
|
215
|
-
raise HTTPException(status_code=400, detail=str(e))
|
216
|
-
|
217
|
-
|
218
|
-
@router.get("/{table}/columns/{column}")
|
219
|
-
async def get_column_info(
|
220
|
-
table: str,
|
221
|
-
column: str,
|
222
|
-
database: str = Query(..., description="Database name"),
|
223
|
-
branch: str = Query(..., description="Branch name"),
|
224
|
-
auth: AuthContext = Depends(require_read_permission),
|
225
|
-
) -> ColumnInfo:
|
226
|
-
"""Get information about a specific column."""
|
227
|
-
db_name = database
|
228
|
-
branch_name = branch
|
229
|
-
|
230
|
-
# Check branch permissions
|
231
|
-
await require_read_permission(auth, branch_name)
|
232
|
-
|
233
|
-
try:
|
234
|
-
db = CinchDB(
|
235
|
-
database=db_name,
|
236
|
-
branch=branch_name,
|
237
|
-
tenant="main",
|
238
|
-
project_dir=auth.project_dir,
|
239
|
-
)
|
240
|
-
col = db.columns.get_column_info(table, column)
|
241
|
-
|
242
|
-
return ColumnInfo(
|
243
|
-
name=col.name,
|
244
|
-
type=col.type,
|
245
|
-
nullable=col.nullable,
|
246
|
-
default=col.default,
|
247
|
-
primary_key=col.primary_key,
|
248
|
-
unique=col.unique,
|
249
|
-
)
|
250
|
-
|
251
|
-
except ValueError as e:
|
252
|
-
raise HTTPException(status_code=404, detail=str(e))
|
253
|
-
|
254
|
-
|
255
|
-
@router.put("/{table}/columns/{column}/nullable")
|
256
|
-
async def alter_column_nullable(
|
257
|
-
table: str,
|
258
|
-
column: str,
|
259
|
-
request: AlterNullableRequest,
|
260
|
-
database: str = Query(..., description="Database name"),
|
261
|
-
branch: str = Query(..., description="Branch name"),
|
262
|
-
apply: bool = Query(True, description="Apply changes to all tenants"),
|
263
|
-
auth: AuthContext = Depends(require_write_permission),
|
264
|
-
):
|
265
|
-
"""Change the nullable constraint on a column."""
|
266
|
-
db_name = database
|
267
|
-
branch_name = branch
|
268
|
-
|
269
|
-
# Check branch permissions
|
270
|
-
await require_write_permission(auth, branch_name)
|
271
|
-
|
272
|
-
try:
|
273
|
-
db = CinchDB(
|
274
|
-
database=db_name,
|
275
|
-
branch=branch_name,
|
276
|
-
tenant="main",
|
277
|
-
project_dir=auth.project_dir,
|
278
|
-
)
|
279
|
-
db.columns.alter_column_nullable(table, column, request.nullable, request.fill_value)
|
280
|
-
|
281
|
-
# Apply to all tenants if requested
|
282
|
-
if apply:
|
283
|
-
applier = ChangeApplier(auth.project_dir, db_name, branch_name)
|
284
|
-
applier.apply_all_unapplied()
|
285
|
-
|
286
|
-
action = "nullable" if request.nullable else "NOT NULL"
|
287
|
-
return {"message": f"Made column '{column}' {action} in table '{table}'"}
|
288
|
-
|
289
|
-
except ValueError as e:
|
290
|
-
raise HTTPException(status_code=400, detail=str(e))
|