From 5c398acfd30c2bf19343372838020195b6dc0979 Mon Sep 17 00:00:00 2001 From: Arjuna Date: Sun, 8 Feb 2026 18:04:13 +0700 Subject: [PATCH 1/2] feat: fe integration with the creating table and adding col logic --- Internal/adapters/repository/dynamicDBRepo.go | 2 +- Internal/api/Routes/routev1.go | 1 + Internal/api/handlers/dynamicDBHandler.go | 43 ++- Internal/core/domain/projectdb.go | 14 +- Internal/core/services/dynamicDBService.go | 36 ++- .../project/components/ProjectSidebar.tsx | 9 + .../project/pages/ProjectDatabase.tsx | 270 ++++++++++++++++++ .../project/services/dynamicDBService.ts | 23 ++ Lb-web/src/main.tsx | 5 + 9 files changed, 390 insertions(+), 13 deletions(-) create mode 100644 Lb-web/src/features/project/pages/ProjectDatabase.tsx create mode 100644 Lb-web/src/features/project/services/dynamicDBService.ts diff --git a/Internal/adapters/repository/dynamicDBRepo.go b/Internal/adapters/repository/dynamicDBRepo.go index d7ae243..66cc15d 100644 --- a/Internal/adapters/repository/dynamicDBRepo.go +++ b/Internal/adapters/repository/dynamicDBRepo.go @@ -8,7 +8,7 @@ func NewDynamicDB(db *DBContainer) *DynamicDBRepo { return &DynamicDBRepo{DB: db} } -func (dr *DynamicDBRepo) CreateDynamicDB(query string) error { +func (dr *DynamicDBRepo) RunDynamicQuery(query string) error { _, err := dr.DB.Sqlx.Exec(query) if err != nil { return err diff --git a/Internal/api/Routes/routev1.go b/Internal/api/Routes/routev1.go index 7db3f07..b164423 100644 --- a/Internal/api/Routes/routev1.go +++ b/Internal/api/Routes/routev1.go @@ -59,6 +59,7 @@ func SetupRouterV1(r *gin.Engine, deps Deps) { manage.POST("/invite/:projectid", deps.Project.InviteProjectHandler) manage.DELETE("/remove/:projuserid", deps.Project.RemoveProjectUserHandler) manage.POST("/create/table/:projectid", deps.DynamicDB.CreateDynamicDBHandler) + manage.POST("/create/col/:projectid", deps.DynamicDB.AddDynamicColHandler) } } } diff --git a/Internal/api/handlers/dynamicDBHandler.go b/Internal/api/handlers/dynamicDBHandler.go index 42db287..ba1ad2d 100644 --- a/Internal/api/handlers/dynamicDBHandler.go +++ b/Internal/api/handlers/dynamicDBHandler.go @@ -25,24 +25,61 @@ func (dh *DynamicDBHandler) CreateDynamicDBHandler(c *gin.Context) { }) return } - var input services.CreateTableReq - if err := c.ShouldBindJSON(&input); err != nil { + var input services.DDLTableReq + if err = c.ShouldBindJSON(&input); err != nil { c.JSON(400, gin.H{ "message": "Invalid json body", "error": err.Error(), }) return } - if err := dh.Serv.CreateDynamicTable(uint(projectID), input); nil != err { + if err = dh.Serv.CreateDynamicTable(uint(projectID), input); nil != err { c.JSON(500, gin.H{ "message": "Failed to create dynamic table", "error": err.Error(), }) return } + if err = dh.Serv.CreateDynamicCols(uint(projectID), input); nil != err { + c.JSON(500, gin.H{ + "message": "Failed to create dynamic cols", + "error": err.Error(), + }) + return + } c.JSON(200, gin.H{ "message": "Successfully created dynamic table", "data": nil, }) +} +func (dh *DynamicDBHandler) AddDynamicColHandler(c *gin.Context) { + projectIDStr := c.Param("projectid") + projectID, err := strconv.Atoi(projectIDStr) + if err != nil { + c.JSON(400, gin.H{ + "message": "Project ID not valid", + "error": err.Error(), + }) + return + } + var input services.DDLTableReq + if err = c.ShouldBindJSON(&input); err != nil { + c.JSON(400, gin.H{ + "message": "Invalid json body", + "error": err.Error(), + }) + return + } + if err = dh.Serv.CreateDynamicCols(uint(projectID), input); nil != err { + c.JSON(500, gin.H{ + "message": "Failed to create dynamic cols", + "error": err.Error(), + }) + return + } + c.JSON(200, gin.H{ + "message": "Successfully added dynamic col", + "data": nil, + }) } diff --git a/Internal/core/domain/projectdb.go b/Internal/core/domain/projectdb.go index cd6be9e..d0c1679 100644 --- a/Internal/core/domain/projectdb.go +++ b/Internal/core/domain/projectdb.go @@ -21,4 +21,16 @@ type ProjectUser struct { CreatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"created_at"` } -//Changes last savepoint +type DynTableDef struct { + ID uint `gorm:"primaryKey;autoIncrement" json:"id"` + ProjectID uint `gorm:"not null" json:"project_id"` + Name string `gorm:"size:255;not null" json:"name"` + Alias string `gorm:"size:255;not null" json:"alias"` +} + +type DynColDef struct { + ID uint `gorm:"primaryKey;autoIncrement" json:"id"` + DynTableDefID uint `gorm:"not null" json:"dyn_table_def_id"` + Name string `gorm:"size:255;not null" json:"name"` + DataType string `gorm:"size:255;not null" json:"data_type"` +} diff --git a/Internal/core/services/dynamicDBService.go b/Internal/core/services/dynamicDBService.go index 364301c..06a10ef 100644 --- a/Internal/core/services/dynamicDBService.go +++ b/Internal/core/services/dynamicDBService.go @@ -21,7 +21,7 @@ type ColumnReq struct { Type string `json:"type"` } -type CreateTableReq struct { +type DDLTableReq struct { TableName string `json:"table_name"` Columns []ColumnReq `json:"columns"` } @@ -34,7 +34,7 @@ func sanitizeInput(input string) string { return result } -func (ds *DynamicDBService) CreateDynamicTable(projectID uint, req CreateTableReq) error { +func (ds *DynamicDBService) CreateDynamicTable(projectID uint, req DDLTableReq) error { safeTableName := fmt.Sprintf("proj_%d_%s", projectID, sanitizeInput(req.TableName)) var queryBuilder strings.Builder @@ -42,17 +42,37 @@ func (ds *DynamicDBService) CreateDynamicTable(projectID uint, req CreateTableRe queryBuilder.WriteString("id SERIAL PRIMARY KEY, ") queryBuilder.WriteString("created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, ") - for _, col := range req.Columns { - safeColName := sanitizeInput(col.Name) - queryBuilder.WriteString(fmt.Sprintf("%s %s, ", safeColName, col.Type)) - } - query := queryBuilder.String() query = strings.TrimSuffix(query, ", ") query += ");" fmt.Println(query) - if err := ds.Repo.CreateDynamicDB(query); err != nil { + if err := ds.Repo.RunDynamicQuery(query); err != nil { + return err + } + return nil +} + +func (ds *DynamicDBService) CreateDynamicCols(projectID uint, req DDLTableReq) error { + safeTableName := fmt.Sprintf("proj_%d_%s", projectID, sanitizeInput(req.TableName)) + + if len(req.Columns) == 0 { + return fmt.Errorf("no columns specified") + } + var queryBuilder strings.Builder + queryBuilder.WriteString(fmt.Sprintf("ALTER TABLE %s ", safeTableName)) + + for i, col := range req.Columns { + safeColName := sanitizeInput(col.Name) + queryBuilder.WriteString(fmt.Sprintf("ADD COLUMN %s %s", safeColName, col.Type)) + if i != len(req.Columns)-1 { + queryBuilder.WriteString(", ") + } + } + queryBuilder.WriteString(";") + query := queryBuilder.String() + + if err := ds.Repo.RunDynamicQuery(query); err != nil { return err } return nil diff --git a/Lb-web/src/features/project/components/ProjectSidebar.tsx b/Lb-web/src/features/project/components/ProjectSidebar.tsx index 45916ea..87b7878 100644 --- a/Lb-web/src/features/project/components/ProjectSidebar.tsx +++ b/Lb-web/src/features/project/components/ProjectSidebar.tsx @@ -44,6 +44,15 @@ export function ProjectSidebar({ project }: ProjectSidebarProps) { Dashboard + + + + + + + Create New Table + + Define the table name and its initial columns. ID and Created_At are added automatically. + + + +
+
+ + setTableName(e.target.value)} + className="border-sky-200 focus-visible:ring-sky-400" + /> +
+ +
+
+ + +
+ + {newColumns.length === 0 && ( +
+ No additional columns. Table will only have 'id' and 'created_at'. +
+ )} + + {newColumns.map((col, idx) => ( +
+
+ + handleColumnChange(idx, "name", e.target.value)} + placeholder="col_name" + className="h-8 text-sm" + /> +
+
+ + +
+ +
+ ))} +
+ + {createError && ( +
+ {createError} +
+ )} +
+ + + + +
+ + + + {/* Tables List / Grid */} +
+ {tables.length > 0 ? ( + tables.map((t, i) => ( +
+
+
+ +
+
+

{t}

+

+ Click to manage columns and data (Coming Soon) +

+
+ )) + ) : ( +
+
+ +
+

No tables found

+

+ Create your first table to start storing data in your project. +

+
+ )} +
+ + {/* Info Note */} +
+ Note: Table management is currently in beta. You can create tables and add columns. +
+ + + + + ); +} diff --git a/Lb-web/src/features/project/services/dynamicDBService.ts b/Lb-web/src/features/project/services/dynamicDBService.ts new file mode 100644 index 0000000..25805a0 --- /dev/null +++ b/Lb-web/src/features/project/services/dynamicDBService.ts @@ -0,0 +1,23 @@ +import api from "@/services/api"; + +export interface ColumnReq { + name: string; + type: string; +} + +export interface DDLTableReq { + table_name: string; + columns: ColumnReq[]; +} + +export const dynamicDBService = { + createTable: async (projectId: number, data: DDLTableReq) => { + const response = await api.post(`/protected/project/manage/create/table/${projectId}`, data); + return response.data; + }, + + addColumn: async (projectId: number, data: DDLTableReq) => { + const response = await api.post(`/protected/project/manage/create/col/${projectId}`, data); + return response.data; + } +}; diff --git a/Lb-web/src/main.tsx b/Lb-web/src/main.tsx index b901da2..fdc13bb 100644 --- a/Lb-web/src/main.tsx +++ b/Lb-web/src/main.tsx @@ -13,6 +13,7 @@ import UserManagement from './features/admin-setting/pages/UserManagement.tsx' import Appearance from './features/admin-setting/pages/Appearance.tsx' import ProjectDashboard from './features/project/pages/ProjectDashboard.tsx' import ProjectUserManagement from './features/project/pages/ProjectUserManagement.tsx' +import ProjectDatabase from './features/project/pages/ProjectDatabase.tsx' const router = createBrowserRouter([ { @@ -73,6 +74,10 @@ const router = createBrowserRouter([ { path: 'settings/members', element: + }, + { + path: 'database', + element: } ] } From dc6a1f7756c1e465ceb5607ee79b630bff8c6e64 Mon Sep 17 00:00:00 2001 From: Arjuna Date: Sun, 8 Feb 2026 22:16:54 +0700 Subject: [PATCH 2/2] feat: database ddl complete with fe integration --- Internal/adapters/repository/dynamicDBRepo.go | 34 ++- Internal/adapters/repository/postgres.go | 2 + Internal/api/Routes/routev1.go | 3 +- Internal/api/handlers/dynamicDBHandler.go | 40 ++- Internal/core/domain/projectdb.go | 9 +- Internal/core/services/dynamicDBService.go | 67 ++++- .../project/components/ProjectSidebar.tsx | 7 +- .../project/pages/ProjectDatabase.tsx | 282 +++++++++++++++--- .../project/services/dynamicDBService.ts | 24 +- cmd/server/main.go | 2 +- 10 files changed, 402 insertions(+), 68 deletions(-) diff --git a/Internal/adapters/repository/dynamicDBRepo.go b/Internal/adapters/repository/dynamicDBRepo.go index 66cc15d..36f0081 100644 --- a/Internal/adapters/repository/dynamicDBRepo.go +++ b/Internal/adapters/repository/dynamicDBRepo.go @@ -1,5 +1,10 @@ package repository +import ( + "github.com/Arjuna-Ragil/Localbase/Internal/core/domain" + "gorm.io/gorm" +) + type DynamicDBRepo struct { DB *DBContainer } @@ -8,10 +13,33 @@ func NewDynamicDB(db *DBContainer) *DynamicDBRepo { return &DynamicDBRepo{DB: db} } -func (dr *DynamicDBRepo) RunDynamicQuery(query string) error { - _, err := dr.DB.Sqlx.Exec(query) - if err != nil { +func (dr *DynamicDBRepo) RunDynamicQuery(tx *gorm.DB, query string) error { + if err := tx.Exec(query).Error; err != nil { return err } return nil } + +// Dynamic database note + +func (dr *DynamicDBRepo) CreateDynTable(tx *gorm.DB, dynTable *domain.DynTableDef) (*domain.DynTableDef, error) { + if err := tx.Create(&dynTable).Error; err != nil { + return nil, err + } + return dynTable, nil +} + +func (dr *DynamicDBRepo) CreateDynCol(tx *gorm.DB, dynCol *domain.DynColDef) error { + if err := tx.Create(&dynCol).Error; err != nil { + return err + } + return nil +} + +func (dr *DynamicDBRepo) GetTables(projectID uint) ([]domain.DynTableDef, error) { + var tables []domain.DynTableDef + if err := dr.DB.Gorm.Preload("Columns").Where("project_id = ?", projectID).Find(&tables).Error; err != nil { + return nil, err + } + return tables, nil +} diff --git a/Internal/adapters/repository/postgres.go b/Internal/adapters/repository/postgres.go index a6a2f28..3ba08a8 100644 --- a/Internal/adapters/repository/postgres.go +++ b/Internal/adapters/repository/postgres.go @@ -43,6 +43,8 @@ func (db *DBContainer) Migrate() error { &domain.Invitation{}, &domain.Project{}, &domain.ProjectUser{}, + &domain.DynTableDef{}, + &domain.DynColDef{}, ) if err != nil { log.Fatalf("Failed to migrate users: %v", err) diff --git a/Internal/api/Routes/routev1.go b/Internal/api/Routes/routev1.go index b164423..d1e070f 100644 --- a/Internal/api/Routes/routev1.go +++ b/Internal/api/Routes/routev1.go @@ -53,13 +53,14 @@ func SetupRouterV1(r *gin.Engine, deps Deps) { { project.GET("/projects", deps.Project.GetAllProjectHandler) project.GET("/:projectid", deps.Project.GetProjectHandler) + project.GET("/:projectid/tables", deps.DynamicDB.GetDynTablesHandler) manage := project.Group("/manage") { manage.POST("/invite/:projectid", deps.Project.InviteProjectHandler) manage.DELETE("/remove/:projuserid", deps.Project.RemoveProjectUserHandler) manage.POST("/create/table/:projectid", deps.DynamicDB.CreateDynamicDBHandler) - manage.POST("/create/col/:projectid", deps.DynamicDB.AddDynamicColHandler) + manage.POST("/create/col/:projectid/:tableid", deps.DynamicDB.AddDynamicColHandler) } } } diff --git a/Internal/api/handlers/dynamicDBHandler.go b/Internal/api/handlers/dynamicDBHandler.go index ba1ad2d..493999a 100644 --- a/Internal/api/handlers/dynamicDBHandler.go +++ b/Internal/api/handlers/dynamicDBHandler.go @@ -33,14 +33,15 @@ func (dh *DynamicDBHandler) CreateDynamicDBHandler(c *gin.Context) { }) return } - if err = dh.Serv.CreateDynamicTable(uint(projectID), input); nil != err { + DynTable, err := dh.Serv.CreateDynamicTable(uint(projectID), input) + if nil != err { c.JSON(500, gin.H{ "message": "Failed to create dynamic table", "error": err.Error(), }) return } - if err = dh.Serv.CreateDynamicCols(uint(projectID), input); nil != err { + if err = dh.Serv.CreateDynamicCols(DynTable.ID, uint(projectID), input); nil != err { c.JSON(500, gin.H{ "message": "Failed to create dynamic cols", "error": err.Error(), @@ -63,6 +64,15 @@ func (dh *DynamicDBHandler) AddDynamicColHandler(c *gin.Context) { }) return } + tableIDStr := c.Param("tableid") + tableID, err := strconv.Atoi(tableIDStr) + if err != nil { + c.JSON(400, gin.H{ + "message": "Table ID not valid", + "error": err.Error(), + }) + return + } var input services.DDLTableReq if err = c.ShouldBindJSON(&input); err != nil { c.JSON(400, gin.H{ @@ -71,7 +81,7 @@ func (dh *DynamicDBHandler) AddDynamicColHandler(c *gin.Context) { }) return } - if err = dh.Serv.CreateDynamicCols(uint(projectID), input); nil != err { + if err = dh.Serv.CreateDynamicCols(uint(tableID), uint(projectID), input); nil != err { c.JSON(500, gin.H{ "message": "Failed to create dynamic cols", "error": err.Error(), @@ -83,3 +93,27 @@ func (dh *DynamicDBHandler) AddDynamicColHandler(c *gin.Context) { "data": nil, }) } + +func (dh *DynamicDBHandler) GetDynTablesHandler(c *gin.Context) { + projectIDStr := c.Param("projectid") + projectID, err := strconv.Atoi(projectIDStr) + if err != nil { + c.JSON(400, gin.H{ + "message": "Project ID not valid", + "error": err.Error(), + }) + return + } + tables, err := dh.Serv.GetDynamicTables(uint(projectID)) + if err != nil { + c.JSON(500, gin.H{ + "message": "Failed to get dynamic table", + "error": err.Error(), + }) + return + } + c.JSON(200, gin.H{ + "message": "Successfully get dynamic table", + "data": tables, + }) +} diff --git a/Internal/core/domain/projectdb.go b/Internal/core/domain/projectdb.go index d0c1679..081e42d 100644 --- a/Internal/core/domain/projectdb.go +++ b/Internal/core/domain/projectdb.go @@ -22,10 +22,11 @@ type ProjectUser struct { } type DynTableDef struct { - ID uint `gorm:"primaryKey;autoIncrement" json:"id"` - ProjectID uint `gorm:"not null" json:"project_id"` - Name string `gorm:"size:255;not null" json:"name"` - Alias string `gorm:"size:255;not null" json:"alias"` + ID uint `gorm:"primaryKey;autoIncrement" json:"id"` + ProjectID uint `gorm:"not null" json:"project_id"` + Name string `gorm:"size:255;not null" json:"name"` + Alias string `gorm:"size:255;not null" json:"alias"` + Columns []DynColDef `gorm:"foreignKey:DynTableDefID" json:"columns"` } type DynColDef struct { diff --git a/Internal/core/services/dynamicDBService.go b/Internal/core/services/dynamicDBService.go index 06a10ef..f0f8166 100644 --- a/Internal/core/services/dynamicDBService.go +++ b/Internal/core/services/dynamicDBService.go @@ -6,14 +6,16 @@ import ( "strings" "github.com/Arjuna-Ragil/Localbase/Internal/adapters/repository" + "github.com/Arjuna-Ragil/Localbase/Internal/core/domain" ) type DynamicDBService struct { Repo *repository.DynamicDBRepo + DB *repository.DBContainer } -func NewDynamicDBService(repo *repository.DynamicDBRepo) *DynamicDBService { - return &DynamicDBService{Repo: repo} +func NewDynamicDBService(repo *repository.DynamicDBRepo, db *repository.DBContainer) *DynamicDBService { + return &DynamicDBService{Repo: repo, DB: db} } type ColumnReq struct { @@ -34,9 +36,29 @@ func sanitizeInput(input string) string { return result } -func (ds *DynamicDBService) CreateDynamicTable(projectID uint, req DDLTableReq) error { +func (ds *DynamicDBService) CreateDynamicTable(projectID uint, req DDLTableReq) (*domain.DynTableDef, error) { + tx := ds.DB.Gorm.Begin() + + defer func() { + if r := recover(); r != nil { + tx.Rollback() + } + }() + safeTableName := fmt.Sprintf("proj_%d_%s", projectID, sanitizeInput(req.TableName)) + tableDef := domain.DynTableDef{ + ProjectID: projectID, + Name: safeTableName, + Alias: req.TableName, + } + + DynTable, err := ds.Repo.CreateDynTable(tx, &tableDef) + if err != nil { + tx.Rollback() + return nil, err + } + var queryBuilder strings.Builder queryBuilder.WriteString(fmt.Sprintf("CREATE TABLE %s (", safeTableName)) queryBuilder.WriteString("id SERIAL PRIMARY KEY, ") @@ -47,13 +69,22 @@ func (ds *DynamicDBService) CreateDynamicTable(projectID uint, req DDLTableReq) query += ");" fmt.Println(query) - if err := ds.Repo.RunDynamicQuery(query); err != nil { - return err + if err = ds.Repo.RunDynamicQuery(tx, query); err != nil { + tx.Rollback() + return nil, err } - return nil + return DynTable, tx.Commit().Error } -func (ds *DynamicDBService) CreateDynamicCols(projectID uint, req DDLTableReq) error { +func (ds *DynamicDBService) CreateDynamicCols(tableID uint, projectID uint, req DDLTableReq) error { + tx := ds.DB.Gorm.Begin() + + defer func() { + if r := recover(); r != nil { + tx.Rollback() + } + }() + safeTableName := fmt.Sprintf("proj_%d_%s", projectID, sanitizeInput(req.TableName)) if len(req.Columns) == 0 { @@ -64,6 +95,16 @@ func (ds *DynamicDBService) CreateDynamicCols(projectID uint, req DDLTableReq) e for i, col := range req.Columns { safeColName := sanitizeInput(col.Name) + coldef := domain.DynColDef{ + DynTableDefID: tableID, + Name: col.Name, + DataType: col.Type, + } + if err := ds.Repo.CreateDynCol(tx, &coldef); err != nil { + tx.Rollback() + return err + } + queryBuilder.WriteString(fmt.Sprintf("ADD COLUMN %s %s", safeColName, col.Type)) if i != len(req.Columns)-1 { queryBuilder.WriteString(", ") @@ -72,8 +113,16 @@ func (ds *DynamicDBService) CreateDynamicCols(projectID uint, req DDLTableReq) e queryBuilder.WriteString(";") query := queryBuilder.String() - if err := ds.Repo.RunDynamicQuery(query); err != nil { + if err := ds.Repo.RunDynamicQuery(tx, query); err != nil { return err } - return nil + return tx.Commit().Error +} + +func (ds *DynamicDBService) GetDynamicTables(projectID uint) ([]domain.DynTableDef, error) { + tables, err := ds.Repo.GetTables(projectID) + if err != nil { + return nil, err + } + return tables, nil } diff --git a/Lb-web/src/features/project/components/ProjectSidebar.tsx b/Lb-web/src/features/project/components/ProjectSidebar.tsx index 87b7878..6f804bc 100644 --- a/Lb-web/src/features/project/components/ProjectSidebar.tsx +++ b/Lb-web/src/features/project/components/ProjectSidebar.tsx @@ -12,7 +12,10 @@ interface ProjectSidebarProps { export function ProjectSidebar({ project }: ProjectSidebarProps) { const location = useLocation(); - const isActive = (path: string) => { + const isActive = (path: string, exact = false) => { + if (exact) { + return location.pathname === path; + } return location.pathname === path || location.pathname.startsWith(`${path}/`); }; @@ -38,7 +41,7 @@ export function ProjectSidebar({ project }: ProjectSidebarProps) { + + {colsToAdd.map((col, idx) => ( +
+
+ + handleColChange_Add(idx, "name", e.target.value)} + placeholder="col_name" + className="h-8 text-sm" + /> +
+
+ + +
+ +
+ ))} -

{t}

-

- Click to manage columns and data (Coming Soon) -

- )) - ) : ( -
-
- + + + + + +
+ + {/* Tables List */} + {loadingTables ? ( +
+ +
+ ) : tables.length > 0 ? ( +
+ {tables.map((t) => ( +
+
toggleTableExpand(t.id)} + > +
+
+ +
+
+

{t.alias}

+

{t.name}

+
+
+
+ + {expandedTables[t.id] ? : } +
+
+ + {/* Columns View */} + {expandedTables[t.id] && ( +
+
+ {t.columns?.map((col) => ( +
+
+ + {col.name} +
+ {col.data_type} +
+ ))} + {(!t.columns || t.columns.length === 0) && ( +
+ No custom columns defined. +
+ )} +
+
+ )}
-

No tables found

-

- Create your first table to start storing data in your project. -

+ ))} +
+ ) : ( +
+
+
- )} -
+

No tables found

+

+ Create your first table to start storing data in your project. +

+
+ )} {/* Info Note */}
diff --git a/Lb-web/src/features/project/services/dynamicDBService.ts b/Lb-web/src/features/project/services/dynamicDBService.ts index 25805a0..c317213 100644 --- a/Lb-web/src/features/project/services/dynamicDBService.ts +++ b/Lb-web/src/features/project/services/dynamicDBService.ts @@ -16,8 +16,28 @@ export const dynamicDBService = { return response.data; }, - addColumn: async (projectId: number, data: DDLTableReq) => { - const response = await api.post(`/protected/project/manage/create/col/${projectId}`, data); + addColumn: async (projectId: number, tableId: number, data: DDLTableReq) => { + const response = await api.post(`/protected/project/manage/create/col/${projectId}/${tableId}`, data); return response.data; + }, + + getTables: async (projectId: number): Promise => { + const response = await api.get(`/protected/project/${projectId}/tables`); + return response.data.data; } }; + +export interface DynColDef { + id: number; + dyn_table_def_id: number; + name: string; + data_type: string; +} + +export interface DynTableDef { + id: number; + project_id: number; + name: string; + alias: string; + columns: DynColDef[]; +} diff --git a/cmd/server/main.go b/cmd/server/main.go index b6393a4..c363732 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -65,7 +65,7 @@ func SetupApp(db *repository.DBContainer, cfg *config.Config) Routes.Deps { projectHandler := handlers.NewProjectHandler(projectService) dynamicDBRepo := repository.NewDynamicDB(db) - dynamicDBService := services.NewDynamicDBService(dynamicDBRepo) + dynamicDBService := services.NewDynamicDBService(dynamicDBRepo, db) dynamicDBHandler := handlers.NewDynamicDBHandler(dynamicDBService) return Routes.Deps{