mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-06-08 22:24:15 +00:00
fix: MariaDB JSON_EACH compatibility for subscription and traffic queries
Replace SQLite-only JSON_EACH with DB-type branching (JSON_TABLE for MariaDB) in subscription, client traffic, and migration queries. Bump version to v1.5.1.
This commit is contained in:
parent
eca9b219cf
commit
1a02ebb024
3 changed files with 76 additions and 25 deletions
|
|
@ -1 +1 @@
|
||||||
v1.4.6-beta
|
v1.5.1
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/goccy/go-json"
|
"github.com/goccy/go-json"
|
||||||
|
|
||||||
|
"github.com/mhsanaei/3x-ui/v2/config"
|
||||||
"github.com/mhsanaei/3x-ui/v2/database"
|
"github.com/mhsanaei/3x-ui/v2/database"
|
||||||
"github.com/mhsanaei/3x-ui/v2/database/model"
|
"github.com/mhsanaei/3x-ui/v2/database/model"
|
||||||
"github.com/mhsanaei/3x-ui/v2/logger"
|
"github.com/mhsanaei/3x-ui/v2/logger"
|
||||||
|
|
@ -115,14 +116,29 @@ func (s *SubService) GetSubs(subId string, host string) ([]string, int64, xray.C
|
||||||
func (s *SubService) getInboundsBySubId(subId string) ([]*model.Inbound, error) {
|
func (s *SubService) getInboundsBySubId(subId string) ([]*model.Inbound, error) {
|
||||||
db := database.GetDB()
|
db := database.GetDB()
|
||||||
var inbounds []*model.Inbound
|
var inbounds []*model.Inbound
|
||||||
err := db.Model(model.Inbound{}).Preload("ClientStats").Where(`id in (
|
|
||||||
|
var query string
|
||||||
|
if config.GetDBTypeFromJSON() == "mariadb" {
|
||||||
|
query = `id in (
|
||||||
|
SELECT DISTINCT inbounds.id
|
||||||
|
FROM inbounds,
|
||||||
|
JSON_TABLE(inbounds.settings, '$.clients[*]' COLUMNS(value JSON PATH '$')) AS client
|
||||||
|
WHERE
|
||||||
|
protocol in ('vmess','vless','trojan','shadowsocks')
|
||||||
|
AND JSON_EXTRACT(client.value, '$.subId') = ? AND enable = ?
|
||||||
|
)`
|
||||||
|
} else {
|
||||||
|
query = `id in (
|
||||||
SELECT DISTINCT inbounds.id
|
SELECT DISTINCT inbounds.id
|
||||||
FROM inbounds,
|
FROM inbounds,
|
||||||
JSON_EACH(JSON_EXTRACT(inbounds.settings, '$.clients')) AS client
|
JSON_EACH(JSON_EXTRACT(inbounds.settings, '$.clients')) AS client
|
||||||
WHERE
|
WHERE
|
||||||
protocol in ('vmess','vless','trojan','shadowsocks')
|
protocol in ('vmess','vless','trojan','shadowsocks')
|
||||||
AND JSON_EXTRACT(client.value, '$.subId') = ? AND enable = ?
|
AND JSON_EXTRACT(client.value, '$.subId') = ? AND enable = ?
|
||||||
)`, subId, true).Find(&inbounds).Error
|
)`
|
||||||
|
}
|
||||||
|
|
||||||
|
err := db.Model(model.Inbound{}).Preload("ClientStats").Where(query, subId, true).Find(&inbounds).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -141,9 +157,17 @@ func (s *SubService) getClientTraffics(traffics []xray.ClientTraffic, email stri
|
||||||
func (s *SubService) getFallbackMaster(dest string, streamSettings string) (string, int, string, error) {
|
func (s *SubService) getFallbackMaster(dest string, streamSettings string) (string, int, string, error) {
|
||||||
db := database.GetDB()
|
db := database.GetDB()
|
||||||
var inbound *model.Inbound
|
var inbound *model.Inbound
|
||||||
|
|
||||||
|
var jsonQuery string
|
||||||
|
if config.GetDBTypeFromJSON() == "mariadb" {
|
||||||
|
jsonQuery = "EXISTS (SELECT * FROM JSON_TABLE(settings, '$.fallbacks[*]' COLUMNS(value JSON PATH '$')) AS jt WHERE JSON_EXTRACT(jt.value, '$.dest') = ?)"
|
||||||
|
} else {
|
||||||
|
jsonQuery = "EXISTS (SELECT * FROM json_each(settings, '$.fallbacks') WHERE json_extract(value, '$.dest') = ?)"
|
||||||
|
}
|
||||||
|
|
||||||
err := db.Model(model.Inbound{}).
|
err := db.Model(model.Inbound{}).
|
||||||
Where("JSON_TYPE(settings, '$.fallbacks') = 'array'").
|
Where("JSON_TYPE(settings, '$.fallbacks') = 'array'").
|
||||||
Where("EXISTS (SELECT * FROM json_each(settings, '$.fallbacks') WHERE json_extract(value, '$.dest') = ?)", dest).
|
Where(jsonQuery, dest).
|
||||||
Find(&inbound).Error
|
Find(&inbound).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", 0, "", err
|
return "", 0, "", err
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/mhsanaei/3x-ui/v2/config"
|
||||||
"github.com/mhsanaei/3x-ui/v2/database"
|
"github.com/mhsanaei/3x-ui/v2/database"
|
||||||
"github.com/mhsanaei/3x-ui/v2/database/model"
|
"github.com/mhsanaei/3x-ui/v2/database/model"
|
||||||
"github.com/mhsanaei/3x-ui/v2/logger"
|
"github.com/mhsanaei/3x-ui/v2/logger"
|
||||||
|
|
@ -1525,14 +1526,27 @@ func (s *InboundService) GetInboundTags() (string, error) {
|
||||||
|
|
||||||
func (s *InboundService) MigrationRemoveOrphanedTraffics() {
|
func (s *InboundService) MigrationRemoveOrphanedTraffics() {
|
||||||
db := database.GetDB()
|
db := database.GetDB()
|
||||||
db.Exec(`
|
|
||||||
|
var query string
|
||||||
|
if config.GetDBTypeFromJSON() == "mariadb" {
|
||||||
|
query = `
|
||||||
|
DELETE FROM client_traffics
|
||||||
|
WHERE email NOT IN (
|
||||||
|
SELECT JSON_EXTRACT(client.value, '$.email')
|
||||||
|
FROM inbounds,
|
||||||
|
JSON_TABLE(inbounds.settings, '$.clients[*]' COLUMNS(value JSON PATH '$')) AS client
|
||||||
|
)`
|
||||||
|
} else {
|
||||||
|
query = `
|
||||||
DELETE FROM client_traffics
|
DELETE FROM client_traffics
|
||||||
WHERE email NOT IN (
|
WHERE email NOT IN (
|
||||||
SELECT JSON_EXTRACT(client.value, '$.email')
|
SELECT JSON_EXTRACT(client.value, '$.email')
|
||||||
FROM inbounds,
|
FROM inbounds,
|
||||||
JSON_EACH(JSON_EXTRACT(inbounds.settings, '$.clients')) AS client
|
JSON_EACH(JSON_EXTRACT(inbounds.settings, '$.clients')) AS client
|
||||||
)
|
)`
|
||||||
`)
|
}
|
||||||
|
|
||||||
|
db.Exec(query)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *InboundService) AddClientStat(tx *gorm.DB, inboundId int, client *model.Client) error {
|
func (s *InboundService) AddClientStat(tx *gorm.DB, inboundId int, client *model.Client) error {
|
||||||
|
|
@ -2327,13 +2341,26 @@ func (s *InboundService) GetClientTrafficByID(id string) ([]xray.ClientTraffic,
|
||||||
db := database.GetDB()
|
db := database.GetDB()
|
||||||
var traffics []xray.ClientTraffic
|
var traffics []xray.ClientTraffic
|
||||||
|
|
||||||
err := db.Model(xray.ClientTraffic{}).Where(`email IN(
|
var query string
|
||||||
|
if config.GetDBTypeFromJSON() == "mariadb" {
|
||||||
|
query = `email IN(
|
||||||
|
SELECT JSON_EXTRACT(client.value, '$.email') as email
|
||||||
|
FROM inbounds,
|
||||||
|
JSON_TABLE(inbounds.settings, '$.clients[*]' COLUMNS(value JSON PATH '$')) AS client
|
||||||
|
WHERE
|
||||||
|
JSON_EXTRACT(client.value, '$.id') in (?)
|
||||||
|
)`
|
||||||
|
} else {
|
||||||
|
query = `email IN(
|
||||||
SELECT JSON_EXTRACT(client.value, '$.email') as email
|
SELECT JSON_EXTRACT(client.value, '$.email') as email
|
||||||
FROM inbounds,
|
FROM inbounds,
|
||||||
JSON_EACH(JSON_EXTRACT(inbounds.settings, '$.clients')) AS client
|
JSON_EACH(JSON_EXTRACT(inbounds.settings, '$.clients')) AS client
|
||||||
WHERE
|
WHERE
|
||||||
JSON_EXTRACT(client.value, '$.id') in (?)
|
JSON_EXTRACT(client.value, '$.id') in (?)
|
||||||
)`, id).Find(&traffics).Error
|
)`
|
||||||
|
}
|
||||||
|
|
||||||
|
err := db.Model(xray.ClientTraffic{}).Where(query, id).Find(&traffics).Error
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Debug(err)
|
logger.Debug(err)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue