Untitled
unknown
plain_text
5 months ago
7.2 kB
4
Indexable
database.go: package config import ( "log" "gorm.io/driver/mysql" "gorm.io/gorm" ) var DB *gorm.DB func ConnectDatabase() { dsn := "user:Password@1@tcp(127.0.0.1:3306)/choice_db?charset=utf8mb4&parseTime=True&loc=Local" database, err := gorm.Open(mysql.Open(dsn), &gorm.Config{}) if err != nil { log.Fatal("Failed to connect to database!", err) } DB = database log.Println("Database connected successfully!") } redis.go: package config import ( "context" "fmt" "log" "time" "github.com/go-redis/redis/v8" ) var ( RDB *redis.Client Ctx = context.Background() ) // ConnectRedis initializes the Redis client connection func ConnectRedis() { RDB = redis.NewClient(&redis.Options{ Addr: "localhost:6379", Password: "", DB: 0, }) _, err := RDB.Ping(Ctx).Result() if err != nil { log.Fatal("Failed to connect to Redis!", err) } log.Println("Redis connected successfully!") } // ToDo: Test: SetKeyWithTTL sets a Redis key with a 5-minute TTL func SetKeyWithTTL(key, value string) error { err := RDB.Set(Ctx, key, value, 5*time.Minute).Err() if err != nil { return fmt.Errorf("failed to set key with TTL: %v", err) } log.Printf("Key '%s' set with a TTL of 5 minutes\n", key) return nil } // ToDo: Test: CheckTTL retrieves the TTL of a key in Redis func CheckTTL(key string) error { ttl, err := RDB.TTL(Ctx, key).Result() if err != nil { return fmt.Errorf("failed to retrieve TTL: %v", err) } log.Printf("Key '%s' TTL: %v\n", key, ttl) return nil } employees.go: package models import ( "time" ) type Employee struct { ID uint `gorm:"primaryKey"` Name string `gorm:"type:varchar(255)"` Age int Position string `gorm:"type:varchar(255)"` Department string `gorm:"type:varchar(255)"` Salary float64 `gorm:"type:decimal(10,2)"` CreatedAt time.Time UpdatedAt time.Time } routes.go: package routes package routes import ( "golang-assignment/config" "golang-assignment/services" "github.com/gin-gonic/gin" ) func SetupRoutes(r *gin.Engine) { r.POST("/upload", services.UploadExcel) r.GET("/employees", services.GetEmployees) r.PUT("/employee/:id", services.UpdateEmployee) r.DELETE("/employee/:id", services.DeleteEmployee) //ToDo : Verify this r.GET("/set-key", func(c *gin.Context) { key := "imported_data" value := "test data" if err := config.SetKeyWithTTL(key, value); err != nil { c.JSON(500, gin.H{"error": err.Error()}) return } c.JSON(200, gin.H{"message": "Key set in Redis with TTL"}) }) //ToDo : Verify this r.GET("/check-ttl", func(c *gin.Context) { key := "imported_data" if err := config.CheckTTL(key); err != nil { c.JSON(500, gin.H{"error": err.Error()}) return } c.JSON(200, gin.H{"message": "TTL checked in logs"}) }) } delete.go: package services import ( "golang-assignment/config" "golang-assignment/models" "net/http" "github.com/gin-gonic/gin" ) // DeleteEmployee deletes a specific employee record func DeleteEmployee(c *gin.Context) { id := c.Param("id") var employee models.Employee if err := config.DB.First(&employee, id).Error; err != nil { c.JSON(http.StatusNotFound, gin.H{"error": "Employee not found"}) return } config.DB.Delete(&employee) c.JSON(http.StatusOK, gin.H{"message": "Employee deleted successfully"}) } get.go: package services import ( "encoding/json" "golang-assignment/config" "golang-assignment/models" "net/http" "time" "github.com/gin-gonic/gin" ) // GetEmployees retrieves employees data func GetEmployees(c *gin.Context) { var employees []models.Employee cachedData, err := config.RDB.Get(config.Ctx, "employees_cache").Result() if err == nil { // If cache hit, return cached data var cachedEmployees []models.Employee json.Unmarshal([]byte(cachedData), &cachedEmployees) c.JSON(http.StatusOK, cachedEmployees) return } // Fallback to MySQL if Redis has no data config.DB.Find(&employees) // Cache the fetched data in Redis for 5 minutes jsonData, _ := json.Marshal(employees) config.RDB.Set(config.Ctx, "employees_cache", jsonData, 5*time.Minute) c.JSON(http.StatusOK, employees) } update.go: package services import ( "golang-assignment/config" "golang-assignment/models" "net/http" "github.com/gin-gonic/gin" ) // UpdateEmployee updates a specific employee record func UpdateEmployee(c *gin.Context) { id := c.Param("id") var employee models.Employee if err := config.DB.First(&employee, id).Error; err != nil { c.JSON(http.StatusNotFound, gin.H{"error": "Employee not found"}) return } if err := c.ShouldBindJSON(&employee); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid input"}) return } config.DB.Save(&employee) c.JSON(http.StatusOK, gin.H{"message": "Employee updated successfully"}) } upload.go: package services import ( "encoding/json" "golang-assignment/config" "golang-assignment/models" "net/http" "strconv" "time" "github.com/gin-gonic/gin" "github.com/xuri/excelize/v2" ) // UploadExcel handles the upload and parsing of Excel data func UploadExcel(c *gin.Context) { file, err := c.FormFile("file") if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "File upload failed"}) return } filePath := "./" + file.Filename if err := c.SaveUploadedFile(file, filePath); err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to save file"}) return } f, err := excelize.OpenFile(filePath) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid Excel file"}) return } defer f.Close() var employees []models.Employee rows, err := f.GetRows("uk-500") if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to read rows"}) return } for _, row := range rows[1:] { if len(row) < 5 { continue } employee := models.Employee{ Name: row[0], Age: parseAge(row[1]), Position: row[2], Department: row[3], Salary: parseSalary(row[4]), } employees = append(employees, employee) } // Insert data into MySQL if err := config.DB.Create(&employees).Error; err != nil { c.JSON(http.StatusInternalServerError, gin.H{ "error": "Failed to insert data into database", "details": err.Error(), }) return } // Cache data in Redis jsonData, _ := json.Marshal(employees) config.RDB.Set(config.Ctx, "employees_cache", jsonData, 5*time.Minute) c.JSON(http.StatusOK, gin.H{"message": "File uploaded and data imported successfully"}) } // Helper function to parse age as an integer, returns 0 if conversion fails func parseAge(ageStr string) int { age, err := strconv.Atoi(ageStr) if err != nil { return 0 } return age } func parseSalary(salaryStr string) float64 { salary, err := strconv.ParseFloat(salaryStr, 64) if err != nil { return 0.0 } return salary } main.go: package main import ( "golang-assignment/config" "golang-assignment/routes" "log" "github.com/gin-gonic/gin" ) func main() { config.ConnectDatabase() config.ConnectRedis() r := gin.Default() routes.SetupRoutes(r) if err := r.Run(":8081"); err != nil { log.Fatal("Failed to start server:", err) } }
Editor is loading...
Leave a Comment