Skip to content

Commit

Permalink
feat: added db util support to account and alert
Browse files Browse the repository at this point in the history
  • Loading branch information
AvineshTripathi committed Apr 22, 2024
1 parent 38d4a02 commit 98c966e
Show file tree
Hide file tree
Showing 5 changed files with 195 additions and 27 deletions.
24 changes: 14 additions & 10 deletions handlers/accounts_handler.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package handlers

import (
"context"
"database/sql"
"encoding/json"
"fmt"
Expand Down Expand Up @@ -31,14 +30,15 @@ func (handler *ApiHandler) IsOnboardedHandler(c *gin.Context) {
Status: "COMPLETE",
}

if handler.db == nil {
if handler.dbHandler.Db == nil {
output.Status = "PENDING_DATABASE"
c.JSON(http.StatusOK, output)
return
}

accounts := make([]models.Account, 0)
err := handler.db.NewRaw("SELECT * FROM accounts").Scan(handler.ctx, &accounts)

_, err := models.HandleQuery(handler.db, handler.ctx, "LIST", &accounts, nil)
if err != nil {
log.WithError(err).Error("scan failed")
c.JSON(http.StatusInternalServerError, gin.H{"error": "scan failed"})
Expand All @@ -62,7 +62,7 @@ func (handler *ApiHandler) ListCloudAccountsHandler(c *gin.Context) {
return
}

err := handler.db.NewRaw("SELECT * FROM accounts").Scan(handler.ctx, &accounts)
_, err := models.HandleQuery(handler.db, handler.ctx, "LIST", &accounts, nil)
if err != nil {
log.WithError(err).Error("scan failed")
c.JSON(http.StatusInternalServerError, gin.H{"error": "scan failed"})
Expand All @@ -73,8 +73,10 @@ func (handler *ApiHandler) ListCloudAccountsHandler(c *gin.Context) {
output := struct {
Total int `bun:"total" json:"total"`
}{}
err = handler.db.NewRaw(fmt.Sprintf("SELECT COUNT(*) as total FROM resources WHERE provider='%s' AND account='%s'", account.Provider, account.Name)).Scan(handler.ctx, &output)

_, err := models.HandleQuery(handler.db, handler.ctx, "RESOURCE_COUNT", &output, map[string]string{"provider": account.Provider, "account": account.Name})
if err != nil {
fmt.Println(err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "scan failed"})
return
}
Expand Down Expand Up @@ -104,12 +106,12 @@ func (handler *ApiHandler) NewCloudAccountHandler(c *gin.Context) {

unsavedAccounts = append(unsavedAccounts, account)
} else {
result, err := handler.db.NewInsert().Model(&account).Exec(context.Background())

result, err := models.HandleQuery(handler.db, handler.ctx, "INSERT", &account, nil)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}

accountId, _ := result.LastInsertId()
account.Id = accountId

Expand Down Expand Up @@ -152,7 +154,8 @@ func (handler *ApiHandler) ReScanAccount(c *gin.Context) {
accountId := c.Param("id")

account := new(models.Account)
res, err := handler.db.NewUpdate().Model(account).Set("status = ? ", "SCANNING").Where("id = ?", accountId).Where("status = ?", "CONNECTED").Returning("*").Exec(handler.ctx)
account.Status = "SCANNING"
res, err := models.HandleQuery(handler.db, handler.ctx, "RE_SCAN_ACCOUNT", account, map[string]string{"id": accountId, "status": "CONNECTED"})
if err != nil {
log.Error("Couldn't set status", err)
return
Expand All @@ -169,11 +172,12 @@ func (handler *ApiHandler) DeleteCloudAccountHandler(c *gin.Context) {
accountId := c.Param("id")

account := new(models.Account)
_, err := handler.db.NewDelete().Model(account).Where("id = ?", accountId).Exec(handler.ctx)
_, err := models.HandleQuery(handler.db, handler.ctx, "DELETE", account, map[string]string{"id": accountId})
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}


c.JSON(http.StatusOK, gin.H{"message": "account has been deleted"})
}
Expand All @@ -188,7 +192,7 @@ func (handler *ApiHandler) UpdateCloudAccountHandler(c *gin.Context) {
return
}

_, err = handler.db.NewUpdate().Model(&account).Column("name", "provider", "credentials").Where("id = ?", accountId).Exec(handler.ctx)
_, err = models.HandleQuery(handler.db, handler.ctx, "UPDATE_ACCOUNT", &account, map[string]string{"id": accountId})
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
Expand Down
7 changes: 3 additions & 4 deletions handlers/alerts_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package handlers

import (
"bytes"
"context"
"encoding/json"
"net/http"
"time"
Expand Down Expand Up @@ -33,7 +32,7 @@ func (handler *ApiHandler) NewAlertHandler(c *gin.Context) {
return
}

result, err := handler.db.NewInsert().Model(&alert).Exec(context.Background())
result, err := models.HandleQuery(handler.db, handler.ctx, "INSERT", &alert, nil)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
Expand Down Expand Up @@ -62,7 +61,7 @@ func (handler *ApiHandler) UpdateAlertHandler(c *gin.Context) {
return
}

_, err = handler.db.NewUpdate().Model(&alert).Column("name", "type", "budget", "usage", "endpoint", "secret").Where("id = ?", alertId).Exec(handler.ctx)
_, err = models.HandleQuery(handler.db, handler.ctx, "UPDATE_ALERT",&alert, map[string]string{"id": alertId})
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
Expand All @@ -75,7 +74,7 @@ func (handler *ApiHandler) DeleteAlertHandler(c *gin.Context) {
alertId := c.Param("id")

alert := new(models.Alert)
_, err := handler.db.NewDelete().Model(alert).Where("id = ?", alertId).Exec(handler.ctx)
_, err := models.HandleQuery(handler.db,handler.ctx, "DELETE", alert, map[string]string{"id": alertId})
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
Expand Down
28 changes: 15 additions & 13 deletions handlers/resources_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,24 +18,26 @@ import (
)

type ApiHandler struct {
db *bun.DB
ctx context.Context
telemetry bool
cfg models.Config
db *bun.DB
dbHandler DbHandler
ctx context.Context
telemetry bool
cfg models.Config
configPath string
analytics utils.Analytics
accounts []models.Account
analytics utils.Analytics
accounts []models.Account
}

func NewApiHandler(ctx context.Context, telemetry bool, analytics utils.Analytics, db *bun.DB, cfg models.Config, configPath string, accounts []models.Account) *ApiHandler {
handler := ApiHandler{
db: db,
ctx: ctx,
telemetry: telemetry,
cfg: cfg,
db: db,
dbHandler: NewDbHandler(db),
ctx: ctx,
telemetry: telemetry,
cfg: cfg,
configPath: configPath,
analytics: analytics,
accounts: accounts,
analytics: analytics,
accounts: accounts,
}
return &handler
}
Expand Down Expand Up @@ -428,7 +430,7 @@ func (handler *ApiHandler) RelationStatsHandler(c *gin.Context) {
Provider: ele.Provider,
})
}

c.JSON(http.StatusOK, out)

}
Expand Down
134 changes: 134 additions & 0 deletions models/execution.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
package models

import (
"context"
"database/sql"
"fmt"

"github.com/uptrace/bun"
)

type QueryType string

const (
RAW QueryType = "RAW"
SELECT QueryType = "SELECT"
INSERT QueryType = "INSERT"
DELETE QueryType = "DELETE"
UPDATE QueryType = "UPDATE"
)

type DbHandler struct {
Db *bun.DB
}

func NewDbHandler(db *bun.DB) DbHandler {
return DbHandler{
Db: db,
}
}

type Object struct {
Query string `json:"query"`
Type QueryType `json:"type"`
Params []string `json:"params"`
}

type Data map[string]Object

func HandleQuery(db *bun.DB, ctx context.Context, queryTitle string, schema interface{}, additionals map[string]string) (sql.Result, error) {
var resp sql.Result
var err error
switch Queries[queryTitle].Type {
case RAW:
err = executeRaw(db, ctx, Queries[queryTitle].Query, schema, additionals)
if err != nil {
return resp, err
}
case SELECT:
err = executeSelect(db, ctx, Queries[queryTitle].Query, schema, additionals)
if err != nil {
return resp, err
}
case INSERT:
resp, err = executeInsert(db, ctx, schema, additionals)
if err != nil {
return resp, err
}
case DELETE:
resp, err = executeDelete(db, ctx, schema, Queries[queryTitle].Query, additionals)
if err != nil {
return resp, err
}
case UPDATE:
resp, err = executeUpdate(db, ctx, schema, Queries[queryTitle].Query, Queries[queryTitle].Params, additionals)
if err != nil {
return resp, err
}
}
return resp, nil
}

func executeRaw(db *bun.DB, ctx context.Context, query string, schema interface{}, additionals map[string]string) error {
if len(additionals) > 0 {
query = fmt.Sprintf("%s where", query)
}

for key, value := range additionals {
query = fmt.Sprintf("%s %s = '%s' and", query, key, value)
}

if len(additionals) > 0 {
query = query[:len(query)-4]
}

err := db.NewRaw(query).Scan(ctx, schema)
if err != nil {
return err
}
return nil
}

func executeSelect(db *bun.DB, ctx context.Context, query string, schema interface{}, additionals map[string]string) error {
updatedQuery := db.NewSelect().Model(schema)
for key, value := range additionals {
updatedQuery = updatedQuery.Where(fmt.Sprintf("%s = ?", key), value)
}

err := updatedQuery.Scan(ctx, schema)
if err != nil {
return err
}
return nil
}

func executeInsert(db *bun.DB, ctx context.Context, schema interface{}, additionals map[string]string) (sql.Result, error) {
resp, err := db.NewInsert().Model(schema).Exec(ctx)
if err != nil {
return resp, err
}
return resp, nil
}

func executeDelete(db *bun.DB, ctx context.Context, schema interface{}, query string, additionals map[string]string) (sql.Result, error) {
resp, err := db.NewDelete().Model(schema).Where("id = ?", additionals["id"]).Exec(ctx)
if err != nil {
return resp, err
}
return resp, nil
}

func executeUpdate(db *bun.DB, ctx context.Context, schema interface{}, query string, columns []string, additionals map[string]string) (sql.Result, error) {
updatedQuery := db.NewUpdate().Model(schema).Column(columns...)

for key, value := range additionals {
updatedQuery = updatedQuery.Where(fmt.Sprintf("%s = ?", key), value)
}

updatedQuery = updatedQuery.Returning("*")
resp, err := updatedQuery.Exec(ctx)
if err != nil {
return resp, err
}
return resp, nil
}
29 changes: 29 additions & 0 deletions models/queries.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package models

var Queries = Data{
"LIST": Object{
Type: SELECT,
},
"INSERT": Object{
Type: INSERT,
},
"DELETE": Object{
Type: DELETE,
},
"UPDATE_ACCOUNT": Object{
Type: UPDATE,
Params: []string{"name", "provider", "credentials"},
},
"UPDATE_ALERT": Object{
Type: UPDATE,
Params: []string{"name", "type", "budget", "usage", "endpoint", "secret"},
},
"RE_SCAN_ACCOUNT": Object{
Type: UPDATE,
Params: []string{"status"},
},
"RESOURCE_COUNT": Object{
Query: "SELECT COUNT(*) as total FROM resources",
Type: RAW,
},
}

0 comments on commit 98c966e

Please sign in to comment.