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.
@@ -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))
@@ -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))