mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-09-29 14:06:36 +08:00
943818f7d4
将 OpenFlare 与平台业务的数据访问从 model 与 apps 直连迁入 repository, model 仅保留实体与无 IO 规则;补充 code-check 架构守卫与开发规范。
168 lines
5.0 KiB
Go
168 lines
5.0 KiB
Go
// Copyright 2026 Arctel.net
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package repository
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"time"
|
|
|
|
"gorm.io/gorm"
|
|
|
|
db "github.com/Rain-kl/Wavelet/internal/infra/persistence"
|
|
"github.com/Rain-kl/Wavelet/internal/model"
|
|
)
|
|
|
|
const (
|
|
openFlareNodeStatusOnline = "online"
|
|
openFlareApplyResultSuccess = "success"
|
|
)
|
|
|
|
// ListOpenFlareNodes returns all nodes ordered by id desc.
|
|
func ListOpenFlareNodes(ctx context.Context) ([]model.OpenFlareNode, error) {
|
|
conn := db.DB(ctx)
|
|
if conn == nil {
|
|
return nil, errors.New(errDatabaseNotInitialized)
|
|
}
|
|
var nodes []model.OpenFlareNode
|
|
if err := conn.Order("id desc").Find(&nodes).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
return nodes, nil
|
|
}
|
|
|
|
// ListOpenFlareNodesByNodeIDs returns nodes matching the given node ids.
|
|
func ListOpenFlareNodesByNodeIDs(ctx context.Context, nodeIDs []string) ([]model.OpenFlareNode, error) {
|
|
if len(nodeIDs) == 0 {
|
|
return []model.OpenFlareNode{}, nil
|
|
}
|
|
conn := db.DB(ctx)
|
|
if conn == nil {
|
|
return nil, errors.New(errDatabaseNotInitialized)
|
|
}
|
|
var nodes []model.OpenFlareNode
|
|
if err := conn.Where("node_id IN ?", nodeIDs).Find(&nodes).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
return nodes, nil
|
|
}
|
|
|
|
// GetOpenFlareNodeByID returns a node by primary key.
|
|
func GetOpenFlareNodeByID(ctx context.Context, id uint) (*model.OpenFlareNode, error) {
|
|
conn := db.DB(ctx)
|
|
if conn == nil {
|
|
return nil, errors.New(errDatabaseNotInitialized)
|
|
}
|
|
var node model.OpenFlareNode
|
|
if err := conn.First(&node, id).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
return &node, nil
|
|
}
|
|
|
|
// GetOpenFlareNodeByNodeID returns a node by node_id.
|
|
func GetOpenFlareNodeByNodeID(ctx context.Context, nodeID string) (*model.OpenFlareNode, error) {
|
|
conn := db.DB(ctx)
|
|
if conn == nil {
|
|
return nil, errors.New(errDatabaseNotInitialized)
|
|
}
|
|
var node model.OpenFlareNode
|
|
if err := conn.Where("node_id = ?", nodeID).First(&node).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
return &node, nil
|
|
}
|
|
|
|
// GetOpenFlareNodeByAccessToken returns a node by access token.
|
|
func GetOpenFlareNodeByAccessToken(ctx context.Context, token string) (*model.OpenFlareNode, error) {
|
|
conn := db.DB(ctx)
|
|
if conn == nil {
|
|
return nil, errors.New(errDatabaseNotInitialized)
|
|
}
|
|
var node model.OpenFlareNode
|
|
if err := conn.Where("access_token = ?", token).First(&node).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
return &node, nil
|
|
}
|
|
|
|
// CreateOpenFlareNode inserts a new node.
|
|
func CreateOpenFlareNode(ctx context.Context, node *model.OpenFlareNode) error {
|
|
conn := db.DB(ctx)
|
|
if conn == nil {
|
|
return errors.New(errDatabaseNotInitialized)
|
|
}
|
|
return conn.Create(node).Error
|
|
}
|
|
|
|
// SaveOpenFlareNode persists node changes.
|
|
func SaveOpenFlareNode(ctx context.Context, node *model.OpenFlareNode) error {
|
|
conn := db.DB(ctx)
|
|
if conn == nil {
|
|
return errors.New(errDatabaseNotInitialized)
|
|
}
|
|
return conn.Save(node).Error
|
|
}
|
|
|
|
// UpdateOpenFlareNodeFields updates selected columns for a node.
|
|
func UpdateOpenFlareNodeFields(ctx context.Context, node *model.OpenFlareNode, fields ...string) error {
|
|
conn := db.DB(ctx)
|
|
if conn == nil {
|
|
return errors.New(errDatabaseNotInitialized)
|
|
}
|
|
if len(fields) == 0 {
|
|
return conn.Save(node).Error
|
|
}
|
|
return conn.Model(node).Select(fields).Updates(node).Error
|
|
}
|
|
|
|
// UpdateOpenFlareNodeColumns updates node columns from a map of column values.
|
|
// Empty maps are no-ops.
|
|
func UpdateOpenFlareNodeColumns(ctx context.Context, node *model.OpenFlareNode, changes map[string]any) error {
|
|
if node == nil || len(changes) == 0 {
|
|
return nil
|
|
}
|
|
conn := db.DB(ctx)
|
|
if conn == nil {
|
|
return errors.New(errDatabaseNotInitialized)
|
|
}
|
|
return conn.Model(node).Updates(changes).Error
|
|
}
|
|
|
|
// UpdateOpenFlareNodeFromApplyResult updates node status, last_seen, version and last_error after an apply report.
|
|
// When applyResult is "success", current_version is set and last_error is cleared; otherwise last_error is set to message.
|
|
func UpdateOpenFlareNodeFromApplyResult(ctx context.Context, nodeID, applyResult, version, message string, now time.Time) error {
|
|
conn := db.DB(ctx)
|
|
if conn == nil {
|
|
return errors.New(errDatabaseNotInitialized)
|
|
}
|
|
return updateOpenFlareNodeFromApplyResultTx(conn, nodeID, applyResult, version, message, now)
|
|
}
|
|
|
|
func updateOpenFlareNodeFromApplyResultTx(tx *gorm.DB, nodeID, applyResult, version, message string, now time.Time) error {
|
|
record := &model.OpenFlareNode{}
|
|
if err := tx.Where("node_id = ?", nodeID).First(record).Error; err != nil {
|
|
return err
|
|
}
|
|
record.Status = openFlareNodeStatusOnline
|
|
lastSeen := now
|
|
record.LastSeenAt = &lastSeen
|
|
if applyResult == openFlareApplyResultSuccess {
|
|
record.CurrentVersion = version
|
|
record.LastError = ""
|
|
} else {
|
|
record.LastError = message
|
|
}
|
|
return tx.Model(record).Select("status", "last_seen_at", "current_version", "last_error").Updates(record).Error
|
|
}
|
|
|
|
// DeleteOpenFlareNode removes a node by primary key.
|
|
func DeleteOpenFlareNode(ctx context.Context, id uint) error {
|
|
conn := db.DB(ctx)
|
|
if conn == nil {
|
|
return errors.New(errDatabaseNotInitialized)
|
|
}
|
|
return conn.Delete(&model.OpenFlareNode{}, id).Error
|
|
}
|