mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-06-06 21:24:10 +00:00
Lets operators with large client counts or multi-node setups pick PostgreSQL at install time without breaking the existing SQLite default. Backend is selected at runtime via XUI_DB_TYPE/XUI_DB_DSN, a small dialect layer keeps the five JSON_EXTRACT/JSON_EACH queries portable, and a new `x-ui migrate-db` subcommand copies SQLite data into PostgreSQL in FK-aware order.
26 lines
1.1 KiB
Go
26 lines
1.1 KiB
Go
package database
|
|
|
|
import "fmt"
|
|
|
|
// JSONClientsFromInbound returns the FROM clause that yields one row per element
|
|
// of inbounds.settings -> clients, with a column named `client.value` whose text
|
|
// fields can be read with JSONFieldText("client.value", "<key>").
|
|
func JSONClientsFromInbound() string {
|
|
if IsPostgres() {
|
|
return "FROM inbounds, jsonb_array_elements(inbounds.settings::jsonb -> 'clients') AS client(value)"
|
|
}
|
|
return "FROM inbounds, JSON_EACH(JSON_EXTRACT(inbounds.settings, '$.clients')) AS client"
|
|
}
|
|
|
|
// JSONFieldText returns a SQL expression that extracts the textual value of <key>
|
|
// from a JSON expression. On both backends the result is the raw (unquoted) string,
|
|
// so callers do NOT need to trim surrounding quotes.
|
|
func JSONFieldText(expr, key string) string {
|
|
if IsPostgres() {
|
|
return fmt.Sprintf("(%s ->> '%s')", expr, key)
|
|
}
|
|
// SQLite's JSON_EXTRACT on a text value returns the JSON-encoded form
|
|
// (with surrounding quotes). Wrap it in json_extract(json_quote(...)) trick
|
|
// is fragile; simpler: unwrap quotes with TRIM(BOTH '"').
|
|
return fmt.Sprintf("TRIM(JSON_EXTRACT(%s, '$.%s'), '\"')", expr, key)
|
|
}
|