Files
Zakk ccfc5ca096 refactor(service): one apply-config path, NodeRef as a node's identity, typed SQLite stores
Three structural changes that share files, so one commit:

Settings, ports, DNS rules and custom inbounds each carried their own
copy of "store the new value, regenerate the core config, put the old
value back when that fails", and the outbound setting path had no
restore at all. ApplyCoreConfig takes a snapshot function and a store
function and does the sequence once for all five callers; the outbound
setting path restores like the others, and the error names which of
the three steps failed.

configure.Which was the persisted discriminator, the key that locates a
node, and the response row with its latency, link and selected flag at
once. NodeRef {type, id, sub, outbound} is the identity used by the
locator, EqualTo, the connected lists and the group operations; Which
embeds it and keeps the status fields. The JSON stays byte for byte
what it was (a test marshals a fixture before and after), stored
connected lists decode unchanged, and deduplication keys by identity
instead of by the whole row.

db.List* dispatched on "bucket/key" string literals to reach the
servers and subscriptions tables. The bodies are now Servers* and
Subscriptions* functions that configure calls directly; the List*
wrappers remain for the migration.
2026-09-20 09:59:29 +10:00

84 lines
1.7 KiB
Go

package controller
import (
"fmt"
"github.com/gin-gonic/gin"
"github.com/v2rayA/v2rayA/common"
"github.com/v2rayA/v2rayA/db/configure"
"github.com/v2rayA/v2rayA/pkg/util/log"
"github.com/v2rayA/v2rayA/server/service"
)
func PostConnection(ctx *gin.Context) {
release, ok := beginMutation(ctx)
if !ok {
return
}
defer release()
var which configure.NodeRef
err := ctx.ShouldBindJSON(&which)
if err != nil {
common.ResponseError(ctx, badRequest("server item", "request body must be a server item with _type, id, sub and outbound"))
return
}
err = service.Connect(&which)
if err != nil {
log.Warn("Connect request failed: %v", err)
common.ResponseError(ctx, logError(err))
return
}
getTouch(ctx)
}
func DeleteConnection(ctx *gin.Context) {
release, ok := beginMutation(ctx)
if !ok {
return
}
defer release()
var which configure.NodeRef
err := ctx.ShouldBindJSON(&which)
if err != nil {
common.ResponseError(ctx, badRequest("server item", "request body must be a server item with _type, id, sub and outbound"))
return
}
err = service.Disconnect(which, false)
if err != nil {
common.ResponseError(ctx, logError(err))
return
}
getTouch(ctx)
}
func PostV2ray(ctx *gin.Context) {
release, ok := beginMutation(ctx)
if !ok {
return
}
defer release()
err := service.StartV2ray()
if err != nil {
common.ResponseError(ctx, logError(fmt.Errorf("failed to start v2ray-core: %w", err)))
return
}
getTouch(ctx)
}
func DeleteV2ray(ctx *gin.Context) {
release, ok := beginMutation(ctx)
if !ok {
return
}
defer release()
err := service.StopV2ray()
if err != nil {
common.ResponseError(ctx, logError(fmt.Errorf("failed to stop v2ray-core: %w", err)))
return
}
getTouch(ctx)
}