package main import ( "database/sql" _ "embed" "errors" _ "github.com/glebarez/go-sqlite" "log" "os" ) const dbFileName = "healthr.db" const driverName = "sqlite" type Database interface { Initialize() error GetAllStatus() ([]Service, error) Get(serviceName string) *Service Update(service Service) error } type SqliteDatabase struct { } //go:embed sql_queries/init-db.sql var initDbQuery string func (sqldb *SqliteDatabase) Initialize() error { fileInfo, err := os.Stat(dbFileName) if fileInfo != nil && fileInfo.IsDir() { return errors.New(dbFileName + " is exists, but is a directory instead of a file") } if err == nil { return nil } db, err := sql.Open(driverName, dbFileName) if err != nil { log.Fatal(err.Error()) } defer db.Close() db.Exec(initDbQuery) log.Default().Println("Database initialized!") return nil } //go:embed sql_queries/get-service.sql var getServiceQuery string func (sqldb *SqliteDatabase) Get(serviceName string) *Service { db, err := sql.Open(driverName, dbFileName) if err != nil { log.Fatal(err.Error()) } defer db.Close() rows, err := db.Query(getServiceQuery, serviceName) if err != nil { log.Fatal(err.Error()) } defer rows.Close() hasItem := rows.Next() if !hasItem { return nil } var service Service err = rows.Scan(&service.Name, &service.Healthy) if err != nil { log.Fatal(err.Error()) return nil } return &service } //go:embed sql_queries/get-all.sql var getAllQuery string func (sqldb *SqliteDatabase) GetAllStatus() ([]Service, error) { db, err := sql.Open(driverName, dbFileName) if err != nil { log.Fatal(err) } defer db.Close() rows, err := db.Query(getAllQuery) if err != nil { log.Fatal(err) } defer rows.Close() services := make([]Service, 0) for rows.Next() { var service Service if err := rows.Scan(&service.Name, &service.Healthy); err != nil { log.Default().Print("Error while parsing row", err) } services = append(services, service) } return services, nil } func (sqldb *SqliteDatabase) Update(service Service) error { sqldb.Get(service.Name) existingService := sqldb.Get(service.Name) if existingService == nil { return sqldb.insert(service) } else { return sqldb.update(service) } } //go:embed sql_queries/insert-service.sql var insertQuery string func (sqldb *SqliteDatabase) insert(service Service) error { db, err := sql.Open(driverName, dbFileName) if err != nil { log.Fatal(err.Error()) } defer db.Close() _, err = db.Exec(insertQuery, service.Name, service.Healthy) if err != nil { println("ERROR", err.Error()) return err } return nil } //go:embed sql_queries/update-service.sql var updateQuery string func (sqldb *SqliteDatabase) update(service Service) error { db, err := sql.Open(driverName, dbFileName) if err != nil { log.Fatal(err.Error()) } defer db.Close() _, err = db.Exec(updateQuery, service.Name, service.Healthy, service.Name) if err != nil { println("ERROR", err.Error()) return err } return nil }