123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231 |
- package dbstore
- import (
- "context"
- "database/sql"
- "fmt"
- "git.linuxforward.com/byop/byop-engine/models"
- "github.com/pkg/errors"
- )
- // Deployment operations
- func (s *SQLiteStore) CreateDeployment(ctx context.Context, deployment models.Deployment) (int, error) {
- query := `INSERT INTO deployments (app_id, client_id, name, description, environment, status, url, config, deployed_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`
- deployedAt := sql.NullTime{}
- if !deployment.DeployedAt.IsZero() {
- deployedAt.Time = deployment.DeployedAt
- deployedAt.Valid = true
- }
- result, err := s.db.ExecContext(ctx, query, deployment.AppId, deployment.ClientID, deployment.Name, deployment.Description, deployment.Environment, deployment.Status, deployment.URL, deployment.Config, deployedAt)
- if err != nil {
- return 0, models.NewErrInternalServer("failed to create deployment", err)
- }
- id, err := result.LastInsertId()
- if err != nil {
- return 0, models.NewErrInternalServer("failed to get last insert ID for deployment", err)
- }
- return int(id), nil
- }
- func (s *SQLiteStore) GetDeploymentsByAppID(ctx context.Context, appID int) ([]*models.Deployment, error) {
- query := `SELECT id, app_id, client_id, name, description, environment, status, url, config, deployed_at, created_at, updated_at FROM deployments WHERE app_id = ?`
- rows, err := s.db.QueryContext(ctx, query, appID)
- if err != nil {
- return nil, models.NewErrInternalServer(fmt.Sprintf("failed to query deployments for app ID %d", appID), err)
- }
- defer rows.Close()
- var deployments []*models.Deployment
- for rows.Next() {
- var deployment models.Deployment
- var deployedAt sql.NullTime
- err := rows.Scan(&deployment.ID, &deployment.AppId, &deployment.ClientID, &deployment.Name, &deployment.Description, &deployment.Environment, &deployment.Status, &deployment.URL, &deployment.Config, &deployedAt, &deployment.CreatedAt, &deployment.UpdatedAt)
- if err != nil {
- return nil, models.NewErrInternalServer("failed to scan deployment row", err)
- }
- if deployedAt.Valid {
- deployment.DeployedAt = deployedAt.Time
- }
- deployments = append(deployments, &deployment)
- }
- if err = rows.Err(); err != nil {
- return nil, models.NewErrInternalServer(fmt.Sprintf("error iterating deployment rows for app ID %d", appID), err)
- }
- return deployments, nil
- }
- func (s *SQLiteStore) GetAllDeployments(ctx context.Context) ([]*models.Deployment, error) {
- query := `SELECT id, app_id, client_id, name, description, environment, status, url, config, deployed_at, created_at, updated_at FROM deployments`
- rows, err := s.db.QueryContext(ctx, query)
- if err != nil {
- return nil, models.NewErrInternalServer("failed to query all deployments", err)
- }
- defer rows.Close()
- var deployments []*models.Deployment
- for rows.Next() {
- var deployment models.Deployment
- var deployedAt sql.NullTime
- err := rows.Scan(&deployment.ID, &deployment.AppId, &deployment.ClientID, &deployment.Name, &deployment.Description, &deployment.Environment, &deployment.Status, &deployment.URL, &deployment.Config, &deployedAt, &deployment.CreatedAt, &deployment.UpdatedAt)
- if err != nil {
- return nil, models.NewErrInternalServer("failed to scan deployment row", err)
- }
- if deployedAt.Valid {
- deployment.DeployedAt = deployedAt.Time
- }
- deployments = append(deployments, &deployment)
- }
- if err = rows.Err(); err != nil {
- return nil, models.NewErrInternalServer("error iterating all deployment rows", err)
- }
- return deployments, nil
- }
- func (s *SQLiteStore) GetDeploymentByID(ctx context.Context, id int) (*models.Deployment, error) {
- var deployment models.Deployment
- var deployedAt sql.NullTime
- query := `SELECT id, app_id, client_id, name, description, environment, status, url, config, deployed_at, created_at, updated_at FROM deployments WHERE id = ?`
- err := s.db.QueryRowContext(ctx, query, id).Scan(&deployment.ID, &deployment.AppId, &deployment.ClientID, &deployment.Name, &deployment.Description, &deployment.Environment, &deployment.Status, &deployment.URL, &deployment.Config, &deployedAt, &deployment.CreatedAt, &deployment.UpdatedAt)
- if err != nil {
- if errors.Is(err, sql.ErrNoRows) {
- return nil, models.NewErrNotFound(fmt.Sprintf("deployment with ID %d not found", id), err)
- }
- return nil, models.NewErrInternalServer(fmt.Sprintf("failed to get deployment with ID %d", id), err)
- }
- if deployedAt.Valid {
- deployment.DeployedAt = deployedAt.Time
- }
- return &deployment, nil
- }
- func (s *SQLiteStore) UpdateDeployment(ctx context.Context, deployment *models.Deployment) error {
- deployedAt := sql.NullTime{}
- if !deployment.DeployedAt.IsZero() {
- deployedAt.Time = deployment.DeployedAt
- deployedAt.Valid = true
- }
- query := `UPDATE deployments SET app_id = ?, client_id = ?, name = ?, description = ?, environment = ?, status = ?, url = ?, config = ?, deployed_at = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?`
- result, err := s.db.ExecContext(ctx, query, deployment.AppId, deployment.ClientID, deployment.Name, deployment.Description, deployment.Environment, deployment.Status, deployment.URL, deployment.Config, deployedAt, deployment.ID)
- if err != nil {
- return models.NewErrInternalServer(fmt.Sprintf("failed to update deployment with ID %d", deployment.ID), err)
- }
- rowsAffected, err := result.RowsAffected()
- if err != nil {
- return models.NewErrInternalServer(fmt.Sprintf("failed to get rows affected for deployment update ID %d", deployment.ID), err)
- }
- if rowsAffected == 0 {
- return models.NewErrNotFound(fmt.Sprintf("deployment with ID %d not found for update", deployment.ID), nil)
- }
- return nil
- }
- // DeleteDeployment deletes a deployment by ID with verification checks
- func (s *SQLiteStore) DeleteDeployment(ctx context.Context, id int) error {
- // First check if the deployment exists
- deployment, err := s.GetDeploymentByID(ctx, id)
- if err != nil {
- return err // GetDeploymentByID already returns custom errors
- }
- // Check if deployment is currently running
- if deployment.Status == "running" || deployment.Status == "deploying" {
- return models.NewErrConflict(fmt.Sprintf("cannot delete deployment: it is currently %s. Please stop the deployment first", deployment.Status), nil)
- }
- // Proceed with deletion
- query := `DELETE FROM deployments WHERE id = ?`
- result, err := s.db.ExecContext(ctx, query, id)
- if err != nil {
- return models.NewErrInternalServer(fmt.Sprintf("failed to delete deployment with ID %d", id), err)
- }
- rowsAffected, err := result.RowsAffected()
- if err != nil {
- return models.NewErrInternalServer(fmt.Sprintf("failed to get rows affected for deployment deletion ID %d", id), err)
- }
- if rowsAffected == 0 {
- // This case should ideally be caught by GetDeploymentByID earlier, but as a safeguard:
- return models.NewErrNotFound(fmt.Sprintf("deployment with ID %d not found for deletion", id), nil)
- }
- return nil
- }
- // GetDeploymentsByClientID retrieves all deployments for a given client ID
- func (s *SQLiteStore) GetDeploymentsByClientID(ctx context.Context, clientID int) ([]*models.Deployment, error) {
- query := `SELECT id, app_id, client_id, name, description, environment, status, url, config, deployed_at, created_at, updated_at FROM deployments WHERE client_id = ?`
- rows, err := s.db.QueryContext(ctx, query, clientID)
- if err != nil {
- return nil, models.NewErrInternalServer(fmt.Sprintf("failed to query deployments for client ID %d", clientID), err)
- }
- defer rows.Close()
- var deployments []*models.Deployment
- for rows.Next() {
- var deployment models.Deployment
- var deployedAt sql.NullTime
- err := rows.Scan(&deployment.ID, &deployment.AppId, &deployment.ClientID, &deployment.Name, &deployment.Description, &deployment.Environment, &deployment.Status, &deployment.URL, &deployment.Config, &deployedAt, &deployment.CreatedAt, &deployment.UpdatedAt)
- if err != nil {
- return nil, models.NewErrInternalServer("failed to scan deployment row for client", err)
- }
- if deployedAt.Valid {
- deployment.DeployedAt = deployedAt.Time
- }
- deployments = append(deployments, &deployment)
- }
- if err = rows.Err(); err != nil {
- return nil, models.NewErrInternalServer(fmt.Sprintf("error iterating deployment rows for client ID %d", clientID), err)
- }
- return deployments, nil
- }
- // GetDeploymentsByUserID retrieves all deployments for a given user ID
- // This assumes a link between deployments and users, which might not be direct.
- // If deployments are linked via apps, and apps via users, this query would need to be more complex
- // or a direct user_id column added to deployments.
- // For now, assuming a direct user_id on deployments or this is handled via a join in a more complex setup.
- // If UserID is not directly on the deployments table, this will need adjustment.
- // For this example, let's assume there's a user_id on the apps table, and we join through it.
- // This requires an `apps` table with `user_id` and `id` (app_id in deployments).
- func (s *SQLiteStore) GetDeploymentsByUserID(ctx context.Context, userID int) ([]*models.Deployment, error) {
- // This query assumes deployments are linked to users via the 'apps' table.
- // Adjust if your schema is different (e.g., direct user_id on deployments).
- query := `
- SELECT d.id, d.app_id, d.client_id, d.name, d.description, d.environment, d.status, d.url, d.config, d.deployed_at, d.created_at, d.updated_at
- FROM deployments d
- INNER JOIN apps a ON d.app_id = a.id
- WHERE a.user_id = ?`
- rows, err := s.db.QueryContext(ctx, query, userID)
- if err != nil {
- return nil, models.NewErrInternalServer(fmt.Sprintf("failed to query deployments for user ID %d", userID), err)
- }
- defer rows.Close()
- var deployments []*models.Deployment
- for rows.Next() {
- var deployment models.Deployment
- var deployedAt sql.NullTime
- err := rows.Scan(&deployment.ID, &deployment.AppId, &deployment.ClientID, &deployment.Name, &deployment.Description, &deployment.Environment, &deployment.Status, &deployment.URL, &deployment.Config, &deployedAt, &deployment.CreatedAt, &deployment.UpdatedAt)
- if err != nil {
- return nil, models.NewErrInternalServer("failed to scan deployment row for user", err)
- }
- if deployedAt.Valid {
- deployment.DeployedAt = deployedAt.Time
- }
- deployments = append(deployments, &deployment)
- }
- if err = rows.Err(); err != nil {
- return nil, models.NewErrInternalServer(fmt.Sprintf("error iterating deployment rows for user ID %d", userID), err)
- }
- return deployments, nil
- }
|