Skip to content

Instantly share code, notes, and snippets.

@M0nteCarl0
Last active October 18, 2023 18:50
Show Gist options
  • Save M0nteCarl0/71ba4bda2bf90eb0ecf38373a97eb027 to your computer and use it in GitHub Desktop.
Save M0nteCarl0/71ba4bda2bf90eb0ecf38373a97eb027 to your computer and use it in GitHub Desktop.
SQL requests_Redis cache
package cache
import (
"context"
"database/sql"
"encoding/json"
"fmt"
"time"
"github.com/go-redis/redis/v8"
)
type Cache struct {
redisClient *redis.Client
db *sql.DB
}
func NewCache(redisClient *redis.Client, db *sql.DB) *Cache {
return &Cache{
redisClient: redisClient,
db: db,
}
}
func (c *Cache) GetFromCacheOrDB(ctx context.Context, key string, query string, args ...interface{}) ([]byte, error) {
// Проверяем наличие данных в Redis по ключу
cacheData, err := c.redisClient.HGet(ctx, "cache", key).Bytes()
if err == nil {
// Данные найдены в Redis
return cacheData, nil
}
// Если данных нет в Redis, выполняем SQL запрос
rows, err := c.db.QueryContext(ctx, query, args...)
if err != nil {
return nil, fmt.Errorf("failed to execute SQL query: %w", err)
}
defer rows.Close()
// Получаем данные из результата запроса
var data []interface{}
for rows.Next() {
var row interface{}
err := rows.Scan(&row)
if err != nil {
return nil, fmt.Errorf("failed to scan SQL row: %w", err)
}
data = append(data, row)
}
// Кэшируем данные в Redis на 5 минут
cacheData, err = json.Marshal(data)
if err != nil {
return nil, fmt.Errorf("failed to marshal data to JSON: %w", err)
}
err = c.redisClient.HSet(ctx, "cache", key, cacheData).Err()
if err != nil {
return nil, fmt.Errorf("failed to set data in Redis: %w", err)
}
err = c.redisClient.Expire(ctx, "cache", 5*time.Minute).Err()
if err != nil {
return nil, fmt.Errorf("failed to set expiration for cache: %w", err)
}
return cacheData, nil
}
package cache
import (
"context"
"database/sql"
"encoding/json"
"fmt"
"time"
"github.com/go-redis/redis/v8"
)
type Cache struct {
redisClient *redis.Client
db *sql.DB
}
func NewCache(redisClient *redis.Client, db *sql.DB) *Cache {
return &Cache{
redisClient: redisClient,
db: db,
}
}
func (c *Cache) GetFromCacheOrDB(ctx context.Context, key string, query string, args ...interface{}) ([]byte, error) {
// Проверяем наличие данных в Redis по ключу
cacheData, err := c.redisClient.Get(ctx, key).Bytes()
if err == nil {
// Данные найдены в Redis
return cacheData, nil
}
// Если данных нет в Redis, выполняем SQL запрос
rows, err := c.db.QueryContext(ctx, query, args...)
if err != nil {
return nil, fmt.Errorf("failed to execute SQL query: %w", err)
}
defer rows.Close()
// Получаем данные из результата запроса
var data []interface{}
for rows.Next() {
var row interface{}
err := rows.Scan(&row)
if err != nil {
return nil, fmt.Errorf("failed to scan SQL row: %w", err)
}
data = append(data, row)
}
// Кэшируем данные в Redis на 5 минут
cacheData, err = json.Marshal(data)
if err != nil {
return nil, fmt.Errorf("failed to marshal data to JSON: %w", err)
}
err = c.redisClient.Set(ctx, key, cacheData, 5*time.Minute).Err()
if err != nil {
return nil, fmt.Errorf("failed to set data in Redis: %w", err)
}
return cacheData, nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment