mirror of
https://github.com/shtorm-7/sing-box-extended.git
synced 2026-07-17 13:21:06 +03:00
Fixes and improvements
This commit is contained in:
@@ -2,7 +2,7 @@ package postgresql
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
dbsql "database/sql"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"time"
|
||||
@@ -11,11 +11,12 @@ import (
|
||||
"github.com/huandu/go-sqlbuilder"
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
"github.com/sagernet/sing-box/common/sql"
|
||||
"github.com/sagernet/sing-box/service/manager/constant"
|
||||
"github.com/sagernet/sing/common/byteformats"
|
||||
)
|
||||
|
||||
var squadFilters, nodeFilters, userFilters, bandwidthLimiterFilters, connectionLimiterFilters, trafficLimiterFilters, rateLimiterFilters map[string]Filter
|
||||
var squadFilters, nodeFilters, userFilters, bandwidthLimiterFilters, connectionLimiterFilters, trafficLimiterFilters, rateLimiterFilters map[string]sql.Filter
|
||||
|
||||
type PostgreSQLRepository struct {
|
||||
db *pgxpool.Pool
|
||||
@@ -23,7 +24,7 @@ type PostgreSQLRepository struct {
|
||||
}
|
||||
|
||||
func NewPostgreSQLRepository(ctx context.Context, dsn string) (*PostgreSQLRepository, error) {
|
||||
db, err := sql.Open("postgres", dsn)
|
||||
db, err := dbsql.Open("postgres", dsn)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -91,8 +92,8 @@ func (r *PostgreSQLRepository) GetSquads(filters map[string][]string) ([]constan
|
||||
}
|
||||
}
|
||||
}
|
||||
sql, args := sb.Build()
|
||||
rows, err := r.db.Query(r.ctx, sql, args...)
|
||||
query, args := sb.Build()
|
||||
rows, err := r.db.Query(r.ctx, query, args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -124,9 +125,9 @@ func (r *PostgreSQLRepository) GetSquadsCount(filters map[string][]string) (int,
|
||||
}
|
||||
}
|
||||
}
|
||||
sql, args := sb.Build()
|
||||
query, args := sb.Build()
|
||||
var count int
|
||||
err := r.db.QueryRow(r.ctx, sql, args...).Scan(&count)
|
||||
err := r.db.QueryRow(r.ctx, query, args...).Scan(&count)
|
||||
return count, err
|
||||
}
|
||||
|
||||
@@ -396,8 +397,8 @@ func (r *PostgreSQLRepository) GetNodes(filters map[string][]string) ([]constant
|
||||
}
|
||||
}
|
||||
}
|
||||
sql, args := sb.Build()
|
||||
rows, err := r.db.Query(r.ctx, sql, args...)
|
||||
query, args := sb.Build()
|
||||
rows, err := r.db.Query(r.ctx, query, args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -430,9 +431,9 @@ func (r *PostgreSQLRepository) GetNodesCount(filters map[string][]string) (int,
|
||||
}
|
||||
}
|
||||
}
|
||||
sql, args := sb.Build()
|
||||
query, args := sb.Build()
|
||||
var count int
|
||||
err := r.db.QueryRow(r.ctx, sql, args...).Scan(&count)
|
||||
err := r.db.QueryRow(r.ctx, query, args...).Scan(&count)
|
||||
return count, err
|
||||
}
|
||||
|
||||
@@ -519,7 +520,7 @@ func (r *PostgreSQLRepository) CreateUser(user constant.UserCreate) (constant.Us
|
||||
if err != nil {
|
||||
return u, err
|
||||
}
|
||||
var authorizedKeys stringSliceJSON
|
||||
var authorizedKeys sql.SliceJSON[string]
|
||||
err = tx.QueryRow(
|
||||
r.ctx, `
|
||||
INSERT INTO users (
|
||||
@@ -629,8 +630,8 @@ func (r *PostgreSQLRepository) GetUsers(filters map[string][]string) ([]constant
|
||||
}
|
||||
}
|
||||
}
|
||||
sql, args := sb.Build()
|
||||
rows, err := r.db.Query(r.ctx, sql, args...)
|
||||
query, args := sb.Build()
|
||||
rows, err := r.db.Query(r.ctx, query, args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -671,9 +672,9 @@ func (r *PostgreSQLRepository) GetUsersCount(filters map[string][]string) (int,
|
||||
}
|
||||
}
|
||||
}
|
||||
sql, args := sb.Build()
|
||||
query, args := sb.Build()
|
||||
var count int
|
||||
err := r.db.QueryRow(r.ctx, sql, args...).Scan(&count)
|
||||
err := r.db.QueryRow(r.ctx, query, args...).Scan(&count)
|
||||
return count, err
|
||||
}
|
||||
|
||||
@@ -783,16 +784,33 @@ func (r *PostgreSQLRepository) UpdateUser(id int, user constant.UserUpdate) (con
|
||||
|
||||
func (r *PostgreSQLRepository) DeleteUser(id int) (constant.User, error) {
|
||||
var u constant.User
|
||||
err := r.db.QueryRow(r.ctx, `
|
||||
tx, err := r.db.Begin(r.ctx)
|
||||
if err != nil {
|
||||
return u, err
|
||||
}
|
||||
defer tx.Rollback(r.ctx)
|
||||
var squadIDs []int
|
||||
squadRows, err := tx.Query(r.ctx, `SELECT squad_id FROM user_to_squad WHERE user_id = $1`, id)
|
||||
if err != nil {
|
||||
return u, err
|
||||
}
|
||||
for squadRows.Next() {
|
||||
var squadID int
|
||||
if err = squadRows.Scan(&squadID); err != nil {
|
||||
squadRows.Close()
|
||||
return u, err
|
||||
}
|
||||
squadIDs = append(squadIDs, squadID)
|
||||
}
|
||||
squadRows.Close()
|
||||
if err = squadRows.Err(); err != nil {
|
||||
return u, err
|
||||
}
|
||||
err = tx.QueryRow(r.ctx, `
|
||||
DELETE FROM users
|
||||
WHERE id = $1
|
||||
RETURNING
|
||||
id,
|
||||
ARRAY(
|
||||
SELECT squad_id
|
||||
FROM user_to_squad
|
||||
WHERE user_to_squad.user_id = users.id
|
||||
) as squad_ids,
|
||||
username,
|
||||
inbound,
|
||||
type,
|
||||
@@ -806,7 +824,6 @@ func (r *PostgreSQLRepository) DeleteUser(id int) (constant.User, error) {
|
||||
updated_at
|
||||
`, id).Scan(
|
||||
&u.ID,
|
||||
&u.SquadIDs,
|
||||
&u.Username,
|
||||
&u.Inbound,
|
||||
&u.Type,
|
||||
@@ -819,7 +836,11 @@ func (r *PostgreSQLRepository) DeleteUser(id int) (constant.User, error) {
|
||||
&u.CreatedAt,
|
||||
&u.UpdatedAt,
|
||||
)
|
||||
return u, err
|
||||
if err != nil {
|
||||
return u, err
|
||||
}
|
||||
u.SquadIDs = squadIDs
|
||||
return u, tx.Commit(r.ctx)
|
||||
}
|
||||
|
||||
func (r *PostgreSQLRepository) CreateConnectionLimiter(limiter constant.ConnectionLimiterCreate) (constant.ConnectionLimiter, error) {
|
||||
@@ -924,8 +945,8 @@ func (r *PostgreSQLRepository) GetConnectionLimiters(filters map[string][]string
|
||||
}
|
||||
}
|
||||
}
|
||||
sql, args := sb.Build()
|
||||
rows, err := r.db.Query(r.ctx, sql, args...)
|
||||
query, args := sb.Build()
|
||||
rows, err := r.db.Query(r.ctx, query, args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -965,9 +986,9 @@ func (r *PostgreSQLRepository) GetConnectionLimitersCount(filters map[string][]s
|
||||
}
|
||||
}
|
||||
}
|
||||
sql, args := sb.Build()
|
||||
query, args := sb.Build()
|
||||
var count int
|
||||
err := r.db.QueryRow(r.ctx, sql, args...).Scan(&count)
|
||||
err := r.db.QueryRow(r.ctx, query, args...).Scan(&count)
|
||||
return count, err
|
||||
}
|
||||
|
||||
@@ -1057,16 +1078,33 @@ func (r *PostgreSQLRepository) UpdateConnectionLimiter(id int, limiter constant.
|
||||
|
||||
func (r *PostgreSQLRepository) DeleteConnectionLimiter(id int) (constant.ConnectionLimiter, error) {
|
||||
var cl constant.ConnectionLimiter
|
||||
err := r.db.QueryRow(r.ctx, `
|
||||
tx, err := r.db.Begin(r.ctx)
|
||||
if err != nil {
|
||||
return cl, err
|
||||
}
|
||||
defer tx.Rollback(r.ctx)
|
||||
var squadIDs []int
|
||||
squadRows, err := tx.Query(r.ctx, `SELECT squad_id FROM connection_limiter_to_squad WHERE connection_limiter_id = $1`, id)
|
||||
if err != nil {
|
||||
return cl, err
|
||||
}
|
||||
for squadRows.Next() {
|
||||
var squadID int
|
||||
if err = squadRows.Scan(&squadID); err != nil {
|
||||
squadRows.Close()
|
||||
return cl, err
|
||||
}
|
||||
squadIDs = append(squadIDs, squadID)
|
||||
}
|
||||
squadRows.Close()
|
||||
if err = squadRows.Err(); err != nil {
|
||||
return cl, err
|
||||
}
|
||||
err = tx.QueryRow(r.ctx, `
|
||||
DELETE FROM connection_limiters
|
||||
WHERE id=$1
|
||||
RETURNING
|
||||
id,
|
||||
ARRAY(
|
||||
SELECT squad_id
|
||||
FROM connection_limiter_to_squad
|
||||
WHERE connection_limiter_to_squad.connection_limiter_id = connection_limiters.id
|
||||
) as squad_ids,
|
||||
username,
|
||||
outbound,
|
||||
strategy,
|
||||
@@ -1077,7 +1115,6 @@ func (r *PostgreSQLRepository) DeleteConnectionLimiter(id int) (constant.Connect
|
||||
updated_at
|
||||
`, id).Scan(
|
||||
&cl.ID,
|
||||
&cl.SquadIDs,
|
||||
&cl.Username,
|
||||
&cl.Outbound,
|
||||
&cl.Strategy,
|
||||
@@ -1087,7 +1124,11 @@ func (r *PostgreSQLRepository) DeleteConnectionLimiter(id int) (constant.Connect
|
||||
&cl.CreatedAt,
|
||||
&cl.UpdatedAt,
|
||||
)
|
||||
return cl, err
|
||||
if err != nil {
|
||||
return cl, err
|
||||
}
|
||||
cl.SquadIDs = squadIDs
|
||||
return cl, tx.Commit(r.ctx)
|
||||
}
|
||||
|
||||
func (r *PostgreSQLRepository) CreateBandwidthLimiter(limiter constant.BandwidthLimiterCreate) (constant.BandwidthLimiter, error) {
|
||||
@@ -1109,7 +1150,7 @@ func (r *PostgreSQLRepository) CreateBandwidthLimiter(limiter constant.Bandwidth
|
||||
if err != nil {
|
||||
return bl, err
|
||||
}
|
||||
var flowKeys stringSliceJSON
|
||||
var flowKeys sql.SliceJSON[string]
|
||||
now := time.Now()
|
||||
err = tx.QueryRow(
|
||||
r.ctx, `
|
||||
@@ -1217,8 +1258,8 @@ func (r *PostgreSQLRepository) GetBandwidthLimiters(filters map[string][]string)
|
||||
}
|
||||
}
|
||||
}
|
||||
sql, args := sb.Build()
|
||||
rows, err := r.db.Query(r.ctx, sql, args...)
|
||||
query, args := sb.Build()
|
||||
rows, err := r.db.Query(r.ctx, query, args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1226,7 +1267,7 @@ func (r *PostgreSQLRepository) GetBandwidthLimiters(filters map[string][]string)
|
||||
var result []constant.BandwidthLimiter
|
||||
for rows.Next() {
|
||||
var bl constant.BandwidthLimiter
|
||||
var flowKeys stringSliceJSON
|
||||
var flowKeys sql.SliceJSON[string]
|
||||
if err := rows.Scan(
|
||||
&bl.ID,
|
||||
&bl.SquadIDs,
|
||||
@@ -1260,15 +1301,15 @@ func (r *PostgreSQLRepository) GetBandwidthLimitersCount(filters map[string][]st
|
||||
}
|
||||
}
|
||||
}
|
||||
sql, args := sb.Build()
|
||||
query, args := sb.Build()
|
||||
var count int
|
||||
err := r.db.QueryRow(r.ctx, sql, args...).Scan(&count)
|
||||
err := r.db.QueryRow(r.ctx, query, args...).Scan(&count)
|
||||
return count, err
|
||||
}
|
||||
|
||||
func (r *PostgreSQLRepository) GetBandwidthLimiter(id int) (constant.BandwidthLimiter, error) {
|
||||
var bl constant.BandwidthLimiter
|
||||
var flowKeys stringSliceJSON
|
||||
var flowKeys sql.SliceJSON[string]
|
||||
err := r.db.QueryRow(r.ctx, `
|
||||
SELECT
|
||||
id,
|
||||
@@ -1309,7 +1350,7 @@ func (r *PostgreSQLRepository) GetBandwidthLimiter(id int) (constant.BandwidthLi
|
||||
|
||||
func (r *PostgreSQLRepository) UpdateBandwidthLimiter(id int, limiter constant.BandwidthLimiterUpdate) (constant.BandwidthLimiter, error) {
|
||||
var bl constant.BandwidthLimiter
|
||||
var flowKeys stringSliceJSON
|
||||
var flowKeys sql.SliceJSON[string]
|
||||
bytesSpeed, err := json.Marshal(limiter.Speed)
|
||||
if err != nil {
|
||||
return bl, err
|
||||
@@ -1384,17 +1425,34 @@ func (r *PostgreSQLRepository) UpdateBandwidthLimiter(id int, limiter constant.B
|
||||
|
||||
func (r *PostgreSQLRepository) DeleteBandwidthLimiter(id int) (constant.BandwidthLimiter, error) {
|
||||
var bl constant.BandwidthLimiter
|
||||
var flowKeys stringSliceJSON
|
||||
err := r.db.QueryRow(r.ctx, `
|
||||
var flowKeys sql.SliceJSON[string]
|
||||
tx, err := r.db.Begin(r.ctx)
|
||||
if err != nil {
|
||||
return bl, err
|
||||
}
|
||||
defer tx.Rollback(r.ctx)
|
||||
var squadIDs []int
|
||||
squadRows, err := tx.Query(r.ctx, `SELECT squad_id FROM bandwidth_limiter_to_squad WHERE bandwidth_limiter_id = $1`, id)
|
||||
if err != nil {
|
||||
return bl, err
|
||||
}
|
||||
for squadRows.Next() {
|
||||
var squadID int
|
||||
if err = squadRows.Scan(&squadID); err != nil {
|
||||
squadRows.Close()
|
||||
return bl, err
|
||||
}
|
||||
squadIDs = append(squadIDs, squadID)
|
||||
}
|
||||
squadRows.Close()
|
||||
if err = squadRows.Err(); err != nil {
|
||||
return bl, err
|
||||
}
|
||||
err = tx.QueryRow(r.ctx, `
|
||||
DELETE FROM bandwidth_limiters
|
||||
WHERE id=$1
|
||||
RETURNING
|
||||
id,
|
||||
ARRAY(
|
||||
SELECT squad_id
|
||||
FROM bandwidth_limiter_to_squad
|
||||
WHERE bandwidth_limiter_to_squad.bandwidth_limiter_id = bandwidth_limiters.id
|
||||
) as squad_ids,
|
||||
username,
|
||||
outbound,
|
||||
strategy,
|
||||
@@ -1407,7 +1465,6 @@ func (r *PostgreSQLRepository) DeleteBandwidthLimiter(id int) (constant.Bandwidt
|
||||
updated_at
|
||||
`, id).Scan(
|
||||
&bl.ID,
|
||||
&bl.SquadIDs,
|
||||
&bl.Username,
|
||||
&bl.Outbound,
|
||||
&bl.Strategy,
|
||||
@@ -1419,8 +1476,12 @@ func (r *PostgreSQLRepository) DeleteBandwidthLimiter(id int) (constant.Bandwidt
|
||||
&bl.CreatedAt,
|
||||
&bl.UpdatedAt,
|
||||
)
|
||||
if err != nil {
|
||||
return bl, err
|
||||
}
|
||||
bl.SquadIDs = squadIDs
|
||||
bl.FlowKeys = []string(flowKeys)
|
||||
return bl, err
|
||||
return bl, tx.Commit(r.ctx)
|
||||
}
|
||||
|
||||
func (r *PostgreSQLRepository) CreateTrafficLimiter(limiter constant.TrafficLimiterCreate) (constant.TrafficLimiter, error) {
|
||||
@@ -1540,8 +1601,8 @@ func (r *PostgreSQLRepository) GetTrafficLimiters(filters map[string][]string) (
|
||||
}
|
||||
}
|
||||
}
|
||||
sql, args := sb.Build()
|
||||
rows, err := r.db.Query(r.ctx, sql, args...)
|
||||
query, args := sb.Build()
|
||||
rows, err := r.db.Query(r.ctx, query, args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1581,9 +1642,9 @@ func (r *PostgreSQLRepository) GetTrafficLimitersCount(filters map[string][]stri
|
||||
}
|
||||
}
|
||||
}
|
||||
sql, args := sb.Build()
|
||||
query, args := sb.Build()
|
||||
var count int
|
||||
err := r.db.QueryRow(r.ctx, sql, args...).Scan(&count)
|
||||
err := r.db.QueryRow(r.ctx, query, args...).Scan(&count)
|
||||
return count, err
|
||||
}
|
||||
|
||||
@@ -1740,16 +1801,33 @@ func (r *PostgreSQLRepository) UpdateTrafficLimiterUsed(id int, current uint64)
|
||||
|
||||
func (r *PostgreSQLRepository) DeleteTrafficLimiter(id int) (constant.TrafficLimiter, error) {
|
||||
var tl constant.TrafficLimiter
|
||||
err := r.db.QueryRow(r.ctx, `
|
||||
tx, err := r.db.Begin(r.ctx)
|
||||
if err != nil {
|
||||
return tl, err
|
||||
}
|
||||
defer tx.Rollback(r.ctx)
|
||||
var squadIDs []int
|
||||
squadRows, err := tx.Query(r.ctx, `SELECT squad_id FROM traffic_limiter_to_squad WHERE traffic_limiter_id = $1`, id)
|
||||
if err != nil {
|
||||
return tl, err
|
||||
}
|
||||
for squadRows.Next() {
|
||||
var squadID int
|
||||
if err = squadRows.Scan(&squadID); err != nil {
|
||||
squadRows.Close()
|
||||
return tl, err
|
||||
}
|
||||
squadIDs = append(squadIDs, squadID)
|
||||
}
|
||||
squadRows.Close()
|
||||
if err = squadRows.Err(); err != nil {
|
||||
return tl, err
|
||||
}
|
||||
err = tx.QueryRow(r.ctx, `
|
||||
DELETE FROM traffic_limiters
|
||||
WHERE id=$1
|
||||
RETURNING
|
||||
id,
|
||||
ARRAY(
|
||||
SELECT squad_id
|
||||
FROM traffic_limiter_to_squad
|
||||
WHERE traffic_limiter_to_squad.traffic_limiter_id = traffic_limiters.id
|
||||
) as squad_ids,
|
||||
username,
|
||||
outbound,
|
||||
strategy,
|
||||
@@ -1762,7 +1840,6 @@ func (r *PostgreSQLRepository) DeleteTrafficLimiter(id int) (constant.TrafficLim
|
||||
updated_at
|
||||
`, id).Scan(
|
||||
&tl.ID,
|
||||
&tl.SquadIDs,
|
||||
&tl.Username,
|
||||
&tl.Outbound,
|
||||
&tl.Strategy,
|
||||
@@ -1774,7 +1851,11 @@ func (r *PostgreSQLRepository) DeleteTrafficLimiter(id int) (constant.TrafficLim
|
||||
&tl.CreatedAt,
|
||||
&tl.UpdatedAt,
|
||||
)
|
||||
return tl, err
|
||||
if err != nil {
|
||||
return tl, err
|
||||
}
|
||||
tl.SquadIDs = squadIDs
|
||||
return tl, tx.Commit(r.ctx)
|
||||
}
|
||||
|
||||
func (r *PostgreSQLRepository) CreateRateLimiter(limiter constant.RateLimiterCreate) (constant.RateLimiter, error) {
|
||||
@@ -1880,8 +1961,8 @@ func (r *PostgreSQLRepository) GetRateLimiters(filters map[string][]string) ([]c
|
||||
}
|
||||
}
|
||||
}
|
||||
sql, args := sb.Build()
|
||||
rows, err := r.db.Query(r.ctx, sql, args...)
|
||||
query, args := sb.Build()
|
||||
rows, err := r.db.Query(r.ctx, query, args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1919,9 +2000,9 @@ func (r *PostgreSQLRepository) GetRateLimitersCount(filters map[string][]string)
|
||||
}
|
||||
}
|
||||
}
|
||||
sql, args := sb.Build()
|
||||
query, args := sb.Build()
|
||||
var count int
|
||||
err := r.db.QueryRow(r.ctx, sql, args...).Scan(&count)
|
||||
err := r.db.QueryRow(r.ctx, query, args...).Scan(&count)
|
||||
return count, err
|
||||
}
|
||||
|
||||
@@ -2015,16 +2096,33 @@ func (r *PostgreSQLRepository) UpdateRateLimiter(id int, limiter constant.RateLi
|
||||
|
||||
func (r *PostgreSQLRepository) DeleteRateLimiter(id int) (constant.RateLimiter, error) {
|
||||
var rl constant.RateLimiter
|
||||
err := r.db.QueryRow(r.ctx, `
|
||||
tx, err := r.db.Begin(r.ctx)
|
||||
if err != nil {
|
||||
return rl, err
|
||||
}
|
||||
defer tx.Rollback(r.ctx)
|
||||
var squadIDs []int
|
||||
squadRows, err := tx.Query(r.ctx, `SELECT squad_id FROM rate_limiter_to_squad WHERE rate_limiter_id = $1`, id)
|
||||
if err != nil {
|
||||
return rl, err
|
||||
}
|
||||
for squadRows.Next() {
|
||||
var squadID int
|
||||
if err = squadRows.Scan(&squadID); err != nil {
|
||||
squadRows.Close()
|
||||
return rl, err
|
||||
}
|
||||
squadIDs = append(squadIDs, squadID)
|
||||
}
|
||||
squadRows.Close()
|
||||
if err = squadRows.Err(); err != nil {
|
||||
return rl, err
|
||||
}
|
||||
err = tx.QueryRow(r.ctx, `
|
||||
DELETE FROM rate_limiters
|
||||
WHERE id=$1
|
||||
RETURNING
|
||||
id,
|
||||
ARRAY(
|
||||
SELECT squad_id
|
||||
FROM rate_limiter_to_squad
|
||||
WHERE rate_limiter_to_squad.rate_limiter_id = rate_limiters.id
|
||||
) as squad_ids,
|
||||
username,
|
||||
outbound,
|
||||
strategy,
|
||||
@@ -2035,7 +2133,6 @@ func (r *PostgreSQLRepository) DeleteRateLimiter(id int) (constant.RateLimiter,
|
||||
updated_at
|
||||
`, id).Scan(
|
||||
&rl.ID,
|
||||
&rl.SquadIDs,
|
||||
&rl.Username,
|
||||
&rl.Outbound,
|
||||
&rl.Strategy,
|
||||
@@ -2045,29 +2142,30 @@ func (r *PostgreSQLRepository) DeleteRateLimiter(id int) (constant.RateLimiter,
|
||||
&rl.CreatedAt,
|
||||
&rl.UpdatedAt,
|
||||
)
|
||||
return rl, err
|
||||
if err != nil {
|
||||
return rl, err
|
||||
}
|
||||
rl.SquadIDs = squadIDs
|
||||
return rl, tx.Commit(r.ctx)
|
||||
}
|
||||
|
||||
func init() {
|
||||
squadFilters = map[string]Filter{
|
||||
"id": EqualFilter("id"),
|
||||
"id_in": InFilter("id"),
|
||||
"pk": EqualFilter("id"),
|
||||
"name": EqualFilter("name"),
|
||||
"created_at_start": GreaterThanFilter("created_at"),
|
||||
"created_at_end": LessThanFilter("created_at"),
|
||||
"updated_at_start": GreaterThanFilter("updated_at"),
|
||||
"updated_at_end": LessThanFilter("updated_at"),
|
||||
"sort_asc": SortAscFilter([]string{"id", "name", "created_at", "updated_at"}),
|
||||
"sort_desc": SortDescFilter([]string{"id", "name", "created_at", "updated_at"}),
|
||||
"offset": OffsetFilter(),
|
||||
"limit": LimitFilter(),
|
||||
}
|
||||
nodeFilters = map[string]Filter{
|
||||
"uuid": EqualFilter("uuid"),
|
||||
"pk": EqualFilter("uuid"),
|
||||
"name": EqualFilter("name"),
|
||||
"squad_id_in": ExistsAndWhereInFilter(func() *sqlbuilder.SelectBuilder {
|
||||
squadFilters = map[string]sql.Filter{"id": sql.EqualFilter("id"),
|
||||
"id_in": sql.InFilter("id"),
|
||||
"pk": sql.EqualFilter("id"),
|
||||
"name": sql.EqualFilter("name"),
|
||||
"created_at_start": sql.GreaterThanFilter("created_at"),
|
||||
"created_at_end": sql.LessThanFilter("created_at"),
|
||||
"updated_at_start": sql.GreaterThanFilter("updated_at"),
|
||||
"updated_at_end": sql.LessThanFilter("updated_at"),
|
||||
"sort_asc": sql.SortAscFilter([]string{"id", "name", "created_at", "updated_at"}),
|
||||
"sort_desc": sql.SortDescFilter([]string{"id", "name", "created_at", "updated_at"}),
|
||||
"offset": sql.OffsetFilter(),
|
||||
"limit": sql.LimitFilter()}
|
||||
nodeFilters = map[string]sql.Filter{"uuid": sql.EqualFilter("uuid"),
|
||||
"pk": sql.EqualFilter("uuid"),
|
||||
"name": sql.EqualFilter("name"),
|
||||
"squad_id_in": sql.ExistsAndWhereInFilter(func() *sqlbuilder.SelectBuilder {
|
||||
return sqlbuilder.PostgreSQL.NewSelectBuilder().
|
||||
Select(
|
||||
"squad_id",
|
||||
@@ -2079,19 +2177,17 @@ func init() {
|
||||
"node_to_squad",
|
||||
)
|
||||
}, "node_to_squad.squad_id"),
|
||||
"created_at_start": GreaterThanFilter("created_at"),
|
||||
"created_at_end": LessThanFilter("created_at"),
|
||||
"updated_at_start": GreaterThanFilter("updated_at"),
|
||||
"updated_at_end": LessThanFilter("updated_at"),
|
||||
"sort_asc": SortAscFilter([]string{"uuid", "name", "created_at", "updated_at"}),
|
||||
"sort_desc": SortDescFilter([]string{"uuid", "name", "created_at", "updated_at"}),
|
||||
"offset": OffsetFilter(),
|
||||
"limit": LimitFilter(),
|
||||
}
|
||||
userFilters = map[string]Filter{
|
||||
"id": EqualFilter("id"),
|
||||
"pk": EqualFilter("id"),
|
||||
"squad_id_in": ExistsAndWhereInFilter(func() *sqlbuilder.SelectBuilder {
|
||||
"created_at_start": sql.GreaterThanFilter("created_at"),
|
||||
"created_at_end": sql.LessThanFilter("created_at"),
|
||||
"updated_at_start": sql.GreaterThanFilter("updated_at"),
|
||||
"updated_at_end": sql.LessThanFilter("updated_at"),
|
||||
"sort_asc": sql.SortAscFilter([]string{"uuid", "name", "created_at", "updated_at"}),
|
||||
"sort_desc": sql.SortDescFilter([]string{"uuid", "name", "created_at", "updated_at"}),
|
||||
"offset": sql.OffsetFilter(),
|
||||
"limit": sql.LimitFilter()}
|
||||
userFilters = map[string]sql.Filter{"id": sql.EqualFilter("id"),
|
||||
"pk": sql.EqualFilter("id"),
|
||||
"squad_id_in": sql.ExistsAndWhereInFilter(func() *sqlbuilder.SelectBuilder {
|
||||
return sqlbuilder.PostgreSQL.NewSelectBuilder().
|
||||
Select(
|
||||
"squad_id",
|
||||
@@ -2103,21 +2199,19 @@ func init() {
|
||||
"user_to_squad",
|
||||
)
|
||||
}, "user_to_squad.squad_id"),
|
||||
"username": EqualFilter("username"),
|
||||
"inbound": EqualFilter("inbound"),
|
||||
"created_at_start": GreaterThanFilter("created_at"),
|
||||
"created_at_end": LessThanFilter("created_at"),
|
||||
"updated_at_start": GreaterThanFilter("updated_at"),
|
||||
"updated_at_end": LessThanFilter("updated_at"),
|
||||
"sort_asc": SortAscFilter([]string{"id", "username", "inbound", "type", "created_at", "updated_at"}),
|
||||
"sort_desc": SortDescFilter([]string{"id", "username", "inbound", "type", "created_at", "updated_at"}),
|
||||
"offset": OffsetFilter(),
|
||||
"limit": LimitFilter(),
|
||||
}
|
||||
connectionLimiterFilters = map[string]Filter{
|
||||
"id": EqualFilter("id"),
|
||||
"pk": EqualFilter("id"),
|
||||
"squad_id_in": ExistsAndWhereInFilter(func() *sqlbuilder.SelectBuilder {
|
||||
"username": sql.EqualFilter("username"),
|
||||
"inbound": sql.EqualFilter("inbound"),
|
||||
"created_at_start": sql.GreaterThanFilter("created_at"),
|
||||
"created_at_end": sql.LessThanFilter("created_at"),
|
||||
"updated_at_start": sql.GreaterThanFilter("updated_at"),
|
||||
"updated_at_end": sql.LessThanFilter("updated_at"),
|
||||
"sort_asc": sql.SortAscFilter([]string{"id", "username", "inbound", "type", "created_at", "updated_at"}),
|
||||
"sort_desc": sql.SortDescFilter([]string{"id", "username", "inbound", "type", "created_at", "updated_at"}),
|
||||
"offset": sql.OffsetFilter(),
|
||||
"limit": sql.LimitFilter()}
|
||||
connectionLimiterFilters = map[string]sql.Filter{"id": sql.EqualFilter("id"),
|
||||
"pk": sql.EqualFilter("id"),
|
||||
"squad_id_in": sql.ExistsAndWhereInFilter(func() *sqlbuilder.SelectBuilder {
|
||||
return sqlbuilder.PostgreSQL.NewSelectBuilder().
|
||||
Select(
|
||||
"squad_id",
|
||||
@@ -2129,24 +2223,22 @@ func init() {
|
||||
"connection_limiter_to_squad",
|
||||
)
|
||||
}, "connection_limiter_to_squad.squad_id"),
|
||||
"strategy": EqualFilter("strategy"),
|
||||
"username": EqualFilter("username"),
|
||||
"outbound": EqualFilter("outbound"),
|
||||
"connection_type": EqualFilter("connection_type"),
|
||||
"lock_type": EqualFilter("lock_type"),
|
||||
"created_at_start": GreaterThanFilter("created_at"),
|
||||
"created_at_end": LessThanFilter("created_at"),
|
||||
"updated_at_start": GreaterThanFilter("updated_at"),
|
||||
"updated_at_end": LessThanFilter("updated_at"),
|
||||
"sort_asc": SortAscFilter([]string{"id", "username", "outbound", "strategy", "connection_type", "lock_type", "count", "created_at", "updated_at"}),
|
||||
"sort_desc": SortDescFilter([]string{"id", "username", "outbound", "strategy", "connection_type", "lock_type", "count", "created_at", "updated_at"}),
|
||||
"offset": OffsetFilter(),
|
||||
"limit": LimitFilter(),
|
||||
}
|
||||
bandwidthLimiterFilters = map[string]Filter{
|
||||
"id": EqualFilter("id"),
|
||||
"pk": EqualFilter("id"),
|
||||
"squad_id_in": ExistsAndWhereInFilter(func() *sqlbuilder.SelectBuilder {
|
||||
"strategy": sql.EqualFilter("strategy"),
|
||||
"username": sql.EqualFilter("username"),
|
||||
"outbound": sql.EqualFilter("outbound"),
|
||||
"connection_type": sql.EqualFilter("connection_type"),
|
||||
"lock_type": sql.EqualFilter("lock_type"),
|
||||
"created_at_start": sql.GreaterThanFilter("created_at"),
|
||||
"created_at_end": sql.LessThanFilter("created_at"),
|
||||
"updated_at_start": sql.GreaterThanFilter("updated_at"),
|
||||
"updated_at_end": sql.LessThanFilter("updated_at"),
|
||||
"sort_asc": sql.SortAscFilter([]string{"id", "username", "outbound", "strategy", "connection_type", "lock_type", "count", "created_at", "updated_at"}),
|
||||
"sort_desc": sql.SortDescFilter([]string{"id", "username", "outbound", "strategy", "connection_type", "lock_type", "count", "created_at", "updated_at"}),
|
||||
"offset": sql.OffsetFilter(),
|
||||
"limit": sql.LimitFilter()}
|
||||
bandwidthLimiterFilters = map[string]sql.Filter{"id": sql.EqualFilter("id"),
|
||||
"pk": sql.EqualFilter("id"),
|
||||
"squad_id_in": sql.ExistsAndWhereInFilter(func() *sqlbuilder.SelectBuilder {
|
||||
return sqlbuilder.PostgreSQL.NewSelectBuilder().
|
||||
Select(
|
||||
"squad_id",
|
||||
@@ -2158,28 +2250,22 @@ func init() {
|
||||
"bandwidth_limiter_to_squad",
|
||||
)
|
||||
}, "bandwidth_limiter_to_squad.squad_id"),
|
||||
"strategy": EqualFilter("strategy"),
|
||||
"mode": EqualFilter("mode"),
|
||||
"username": EqualFilter("username"),
|
||||
"created_at_start": GreaterThanFilter("created_at"),
|
||||
"created_at_end": LessThanFilter("created_at"),
|
||||
"updated_at_start": GreaterThanFilter("updated_at"),
|
||||
"updated_at_end": LessThanFilter("updated_at"),
|
||||
"sort_asc": ReplacedSortAscFilter(
|
||||
map[string]string{"speed": "raw_speed"},
|
||||
[]string{"id", "username", "outbound", "strategy", "connection_type", "mode", "raw_speed", "created_at", "updated_at"},
|
||||
),
|
||||
"sort_desc": ReplacedSortDescFilter(
|
||||
map[string]string{"speed": "raw_speed"},
|
||||
[]string{"id", "username", "outbound", "strategy", "connection_type", "mode", "raw_speed", "created_at", "updated_at"},
|
||||
),
|
||||
"offset": OffsetFilter(),
|
||||
"limit": LimitFilter(),
|
||||
}
|
||||
trafficLimiterFilters = map[string]Filter{
|
||||
"id": EqualFilter("id"),
|
||||
"pk": EqualFilter("id"),
|
||||
"squad_id_in": ExistsAndWhereInFilter(func() *sqlbuilder.SelectBuilder {
|
||||
"strategy": sql.EqualFilter("strategy"),
|
||||
"mode": sql.EqualFilter("mode"),
|
||||
"username": sql.EqualFilter("username"),
|
||||
"created_at_start": sql.GreaterThanFilter("created_at"),
|
||||
"created_at_end": sql.LessThanFilter("created_at"),
|
||||
"updated_at_start": sql.GreaterThanFilter("updated_at"),
|
||||
"updated_at_end": sql.LessThanFilter("updated_at"),
|
||||
"sort_asc": sql.ReplacedSortAscFilter(map[string]string{"speed": "raw_speed"},
|
||||
[]string{"id", "username", "outbound", "strategy", "connection_type", "mode", "raw_speed", "created_at", "updated_at"}),
|
||||
"sort_desc": sql.ReplacedSortDescFilter(map[string]string{"speed": "raw_speed"},
|
||||
[]string{"id", "username", "outbound", "strategy", "connection_type", "mode", "raw_speed", "created_at", "updated_at"}),
|
||||
"offset": sql.OffsetFilter(),
|
||||
"limit": sql.LimitFilter()}
|
||||
trafficLimiterFilters = map[string]sql.Filter{"id": sql.EqualFilter("id"),
|
||||
"pk": sql.EqualFilter("id"),
|
||||
"squad_id_in": sql.ExistsAndWhereInFilter(func() *sqlbuilder.SelectBuilder {
|
||||
return sqlbuilder.PostgreSQL.NewSelectBuilder().
|
||||
Select(
|
||||
"squad_id",
|
||||
@@ -2191,33 +2277,27 @@ func init() {
|
||||
"traffic_limiter_to_squad",
|
||||
)
|
||||
}, "traffic_limiter_to_squad.squad_id"),
|
||||
"username": EqualFilter("username"),
|
||||
"outbound": EqualFilter("outbound"),
|
||||
"strategy": EqualFilter("strategy"),
|
||||
"mode": EqualFilter("mode"),
|
||||
"used_start": SpeedGreaterEqualThanFilter("raw_used"),
|
||||
"used_end": SpeedLessEqualThanFilter("raw_used"),
|
||||
"quota_start": SpeedGreaterEqualThanFilter("raw_quota"),
|
||||
"quota_end": SpeedLessEqualThanFilter("raw_quota"),
|
||||
"created_at_start": GreaterThanFilter("created_at"),
|
||||
"created_at_end": LessThanFilter("created_at"),
|
||||
"updated_at_start": GreaterThanFilter("updated_at"),
|
||||
"updated_at_end": LessThanFilter("updated_at"),
|
||||
"sort_asc": ReplacedSortAscFilter(
|
||||
map[string]string{"used": "raw_used", "quota": "raw_quota"},
|
||||
[]string{"id", "username", "outbound", "strategy", "mode", "raw_used", "raw_quota", "created_at", "updated_at"},
|
||||
),
|
||||
"sort_desc": ReplacedSortDescFilter(
|
||||
map[string]string{"used": "raw_used", "quota": "raw_quota"},
|
||||
[]string{"id", "username", "outbound", "strategy", "mode", "raw_used", "raw_quota", "created_at", "updated_at"},
|
||||
),
|
||||
"offset": OffsetFilter(),
|
||||
"limit": LimitFilter(),
|
||||
}
|
||||
rateLimiterFilters = map[string]Filter{
|
||||
"id": EqualFilter("id"),
|
||||
"pk": EqualFilter("id"),
|
||||
"squad_id_in": ExistsAndWhereInFilter(func() *sqlbuilder.SelectBuilder {
|
||||
"username": sql.EqualFilter("username"),
|
||||
"outbound": sql.EqualFilter("outbound"),
|
||||
"strategy": sql.EqualFilter("strategy"),
|
||||
"mode": sql.EqualFilter("mode"),
|
||||
"used_start": sql.SpeedGreaterEqualThanFilter("raw_used"),
|
||||
"used_end": sql.SpeedLessEqualThanFilter("raw_used"),
|
||||
"quota_start": sql.SpeedGreaterEqualThanFilter("raw_quota"),
|
||||
"quota_end": sql.SpeedLessEqualThanFilter("raw_quota"),
|
||||
"created_at_start": sql.GreaterThanFilter("created_at"),
|
||||
"created_at_end": sql.LessThanFilter("created_at"),
|
||||
"updated_at_start": sql.GreaterThanFilter("updated_at"),
|
||||
"updated_at_end": sql.LessThanFilter("updated_at"),
|
||||
"sort_asc": sql.ReplacedSortAscFilter(map[string]string{"used": "raw_used", "quota": "raw_quota"},
|
||||
[]string{"id", "username", "outbound", "strategy", "mode", "raw_used", "raw_quota", "created_at", "updated_at"}),
|
||||
"sort_desc": sql.ReplacedSortDescFilter(map[string]string{"used": "raw_used", "quota": "raw_quota"},
|
||||
[]string{"id", "username", "outbound", "strategy", "mode", "raw_used", "raw_quota", "created_at", "updated_at"}),
|
||||
"offset": sql.OffsetFilter(),
|
||||
"limit": sql.LimitFilter()}
|
||||
rateLimiterFilters = map[string]sql.Filter{"id": sql.EqualFilter("id"),
|
||||
"pk": sql.EqualFilter("id"),
|
||||
"squad_id_in": sql.ExistsAndWhereInFilter(func() *sqlbuilder.SelectBuilder {
|
||||
return sqlbuilder.PostgreSQL.NewSelectBuilder().
|
||||
Select(
|
||||
"squad_id",
|
||||
@@ -2229,20 +2309,19 @@ func init() {
|
||||
"rate_limiter_to_squad",
|
||||
)
|
||||
}, "rate_limiter_to_squad.squad_id"),
|
||||
"strategy": EqualFilter("strategy"),
|
||||
"username": EqualFilter("username"),
|
||||
"outbound": EqualFilter("outbound"),
|
||||
"connection_type": EqualFilter("connection_type"),
|
||||
"interval": EqualFilter("interval"),
|
||||
"count_start": GreaterEqualThanFilter("count"),
|
||||
"count_end": LessEqualThanFilter("count"),
|
||||
"created_at_start": GreaterThanFilter("created_at"),
|
||||
"created_at_end": LessThanFilter("created_at"),
|
||||
"updated_at_start": GreaterThanFilter("updated_at"),
|
||||
"updated_at_end": LessThanFilter("updated_at"),
|
||||
"sort_asc": SortAscFilter([]string{"id", "username", "outbound", "strategy", "connection_type", "count", "interval", "created_at", "updated_at"}),
|
||||
"sort_desc": SortDescFilter([]string{"id", "username", "outbound", "strategy", "connection_type", "count", "interval", "created_at", "updated_at"}),
|
||||
"offset": OffsetFilter(),
|
||||
"limit": LimitFilter(),
|
||||
}
|
||||
"strategy": sql.EqualFilter("strategy"),
|
||||
"username": sql.EqualFilter("username"),
|
||||
"outbound": sql.EqualFilter("outbound"),
|
||||
"connection_type": sql.EqualFilter("connection_type"),
|
||||
"interval": sql.EqualFilter("interval"),
|
||||
"count_start": sql.GreaterEqualThanFilter("count"),
|
||||
"count_end": sql.LessEqualThanFilter("count"),
|
||||
"created_at_start": sql.GreaterThanFilter("created_at"),
|
||||
"created_at_end": sql.LessThanFilter("created_at"),
|
||||
"updated_at_start": sql.GreaterThanFilter("updated_at"),
|
||||
"updated_at_end": sql.LessThanFilter("updated_at"),
|
||||
"sort_asc": sql.SortAscFilter([]string{"id", "username", "outbound", "strategy", "connection_type", "count", "interval", "created_at", "updated_at"}),
|
||||
"sort_desc": sql.SortDescFilter([]string{"id", "username", "outbound", "strategy", "connection_type", "count", "interval", "created_at", "updated_at"}),
|
||||
"offset": sql.OffsetFilter(),
|
||||
"limit": sql.LimitFilter()}
|
||||
}
|
||||
12
service/manager/repository/main/postgresql/utils.go
Normal file
12
service/manager/repository/main/postgresql/utils.go
Normal file
@@ -0,0 +1,12 @@
|
||||
package postgresql
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
func marshalStringSlice(values []string) ([]byte, error) {
|
||||
if values == nil {
|
||||
values = []string{}
|
||||
}
|
||||
return json.Marshal(values)
|
||||
}
|
||||
@@ -2,27 +2,28 @@ package sqlite
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
dbsql "database/sql"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/golang-migrate/migrate/v4"
|
||||
"github.com/huandu/go-sqlbuilder"
|
||||
"github.com/sagernet/sing-box/common/sql"
|
||||
"github.com/sagernet/sing-box/service/manager/constant"
|
||||
"github.com/sagernet/sing/common/byteformats"
|
||||
_ "modernc.org/sqlite"
|
||||
)
|
||||
|
||||
var squadFilters, nodeFilters, userFilters, bandwidthLimiterFilters, connectionLimiterFilters, trafficLimiterFilters, rateLimiterFilters map[string]Filter
|
||||
var squadFilters, nodeFilters, userFilters, bandwidthLimiterFilters, connectionLimiterFilters, trafficLimiterFilters, rateLimiterFilters map[string]sql.Filter
|
||||
|
||||
type SQLiteRepository struct {
|
||||
db *sql.DB
|
||||
db *dbsql.DB
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
func NewSQLiteRepository(ctx context.Context, dsn string) (*SQLiteRepository, error) {
|
||||
db, err := sql.Open("sqlite", dsn)
|
||||
db, err := dbsql.Open("sqlite", dsn)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -34,7 +35,7 @@ func NewSQLiteRepository(ctx context.Context, dsn string) (*SQLiteRepository, er
|
||||
}
|
||||
|
||||
func notFoundErr(err error) error {
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
if errors.Is(err, dbsql.ErrNoRows) {
|
||||
return constant.ErrNotFound
|
||||
}
|
||||
return err
|
||||
@@ -397,7 +398,7 @@ func (r *SQLiteRepository) GetNodes(filters map[string][]string) ([]constant.Nod
|
||||
var result []constant.Node
|
||||
for rows.Next() {
|
||||
var n constant.Node
|
||||
var squadIDs intSliceJSON
|
||||
var squadIDs sql.SliceJSON[int]
|
||||
if err := rows.Scan(
|
||||
&n.UUID,
|
||||
&n.Name,
|
||||
@@ -432,7 +433,7 @@ func (r *SQLiteRepository) GetNodesCount(filters map[string][]string) (int, erro
|
||||
|
||||
func (r *SQLiteRepository) GetNode(uuid string) (constant.Node, error) {
|
||||
var n constant.Node
|
||||
var squadIDs intSliceJSON
|
||||
var squadIDs sql.SliceJSON[int]
|
||||
err := r.db.QueryRowContext(r.ctx, `
|
||||
SELECT
|
||||
uuid,
|
||||
@@ -514,7 +515,7 @@ func (r *SQLiteRepository) CreateUser(user constant.UserCreate) (constant.User,
|
||||
if err != nil {
|
||||
return u, err
|
||||
}
|
||||
var authorizedKeys stringSliceJSON
|
||||
var authorizedKeys sql.SliceJSON[string]
|
||||
err = tx.QueryRowContext(
|
||||
r.ctx, `
|
||||
INSERT INTO users (
|
||||
@@ -629,8 +630,8 @@ func (r *SQLiteRepository) GetUsers(filters map[string][]string) ([]constant.Use
|
||||
var result []constant.User
|
||||
for rows.Next() {
|
||||
var u constant.User
|
||||
var squadIDs intSliceJSON
|
||||
var authorizedKeys stringSliceJSON
|
||||
var squadIDs sql.SliceJSON[int]
|
||||
var authorizedKeys sql.SliceJSON[string]
|
||||
if err := rows.Scan(
|
||||
&u.ID,
|
||||
&squadIDs,
|
||||
@@ -674,8 +675,8 @@ func (r *SQLiteRepository) GetUsersCount(filters map[string][]string) (int, erro
|
||||
|
||||
func (r *SQLiteRepository) GetUser(id int) (constant.User, error) {
|
||||
var u constant.User
|
||||
var squadIDs intSliceJSON
|
||||
var authorizedKeys stringSliceJSON
|
||||
var squadIDs sql.SliceJSON[int]
|
||||
var authorizedKeys sql.SliceJSON[string]
|
||||
err := r.db.QueryRowContext(r.ctx, `
|
||||
SELECT
|
||||
id,
|
||||
@@ -719,8 +720,8 @@ func (r *SQLiteRepository) GetUser(id int) (constant.User, error) {
|
||||
|
||||
func (r *SQLiteRepository) UpdateUser(id int, user constant.UserUpdate) (constant.User, error) {
|
||||
var u constant.User
|
||||
var squadIDs intSliceJSON
|
||||
var authorizedKeys stringSliceJSON
|
||||
var squadIDs sql.SliceJSON[int]
|
||||
var authorizedKeys sql.SliceJSON[string]
|
||||
authorizedKeysJSON, err := marshalStringSlice(user.AuthorizedKeys)
|
||||
if err != nil {
|
||||
return u, err
|
||||
@@ -786,18 +787,34 @@ func (r *SQLiteRepository) UpdateUser(id int, user constant.UserUpdate) (constan
|
||||
|
||||
func (r *SQLiteRepository) DeleteUser(id int) (constant.User, error) {
|
||||
var u constant.User
|
||||
var squadIDs intSliceJSON
|
||||
var authorizedKeys stringSliceJSON
|
||||
err := r.db.QueryRowContext(r.ctx, `
|
||||
var authorizedKeys sql.SliceJSON[string]
|
||||
tx, err := r.db.BeginTx(r.ctx, nil)
|
||||
if err != nil {
|
||||
return u, err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
var squadIDs []int
|
||||
squadRows, err := tx.QueryContext(r.ctx, `SELECT squad_id FROM user_to_squad WHERE user_id = ?`, id)
|
||||
if err != nil {
|
||||
return u, err
|
||||
}
|
||||
for squadRows.Next() {
|
||||
var squadID int
|
||||
if err = squadRows.Scan(&squadID); err != nil {
|
||||
squadRows.Close()
|
||||
return u, err
|
||||
}
|
||||
squadIDs = append(squadIDs, squadID)
|
||||
}
|
||||
squadRows.Close()
|
||||
if err = squadRows.Err(); err != nil {
|
||||
return u, err
|
||||
}
|
||||
err = tx.QueryRowContext(r.ctx, `
|
||||
DELETE FROM users
|
||||
WHERE id = ?
|
||||
RETURNING
|
||||
id,
|
||||
(
|
||||
SELECT json_group_array(squad_id)
|
||||
FROM user_to_squad
|
||||
WHERE user_to_squad.user_id = users.id
|
||||
) as squad_ids,
|
||||
username,
|
||||
inbound,
|
||||
type,
|
||||
@@ -811,7 +828,6 @@ func (r *SQLiteRepository) DeleteUser(id int) (constant.User, error) {
|
||||
updated_at
|
||||
`, id).Scan(
|
||||
&u.ID,
|
||||
&squadIDs,
|
||||
&u.Username,
|
||||
&u.Inbound,
|
||||
&u.Type,
|
||||
@@ -824,9 +840,12 @@ func (r *SQLiteRepository) DeleteUser(id int) (constant.User, error) {
|
||||
&u.CreatedAt,
|
||||
&u.UpdatedAt,
|
||||
)
|
||||
u.SquadIDs = []int(squadIDs)
|
||||
if err != nil {
|
||||
return u, err
|
||||
}
|
||||
u.SquadIDs = squadIDs
|
||||
u.AuthorizedKeys = []string(authorizedKeys)
|
||||
return u, err
|
||||
return u, tx.Commit()
|
||||
}
|
||||
|
||||
func (r *SQLiteRepository) CreateConnectionLimiter(limiter constant.ConnectionLimiterCreate) (constant.ConnectionLimiter, error) {
|
||||
@@ -936,7 +955,7 @@ func (r *SQLiteRepository) GetConnectionLimiters(filters map[string][]string) ([
|
||||
var result []constant.ConnectionLimiter
|
||||
for rows.Next() {
|
||||
var cl constant.ConnectionLimiter
|
||||
var squadIDs intSliceJSON
|
||||
var squadIDs sql.SliceJSON[int]
|
||||
if err := rows.Scan(
|
||||
&cl.ID,
|
||||
&squadIDs,
|
||||
@@ -978,7 +997,7 @@ func (r *SQLiteRepository) GetConnectionLimitersCount(filters map[string][]strin
|
||||
|
||||
func (r *SQLiteRepository) GetConnectionLimiter(id int) (constant.ConnectionLimiter, error) {
|
||||
var cl constant.ConnectionLimiter
|
||||
var squadIDs intSliceJSON
|
||||
var squadIDs sql.SliceJSON[int]
|
||||
err := r.db.QueryRowContext(r.ctx, `
|
||||
SELECT
|
||||
id,
|
||||
@@ -1015,7 +1034,7 @@ func (r *SQLiteRepository) GetConnectionLimiter(id int) (constant.ConnectionLimi
|
||||
|
||||
func (r *SQLiteRepository) UpdateConnectionLimiter(id int, limiter constant.ConnectionLimiterUpdate) (constant.ConnectionLimiter, error) {
|
||||
var cl constant.ConnectionLimiter
|
||||
var squadIDs intSliceJSON
|
||||
var squadIDs sql.SliceJSON[int]
|
||||
err := r.db.QueryRowContext(
|
||||
r.ctx, `
|
||||
UPDATE connection_limiters
|
||||
@@ -1066,17 +1085,33 @@ func (r *SQLiteRepository) UpdateConnectionLimiter(id int, limiter constant.Conn
|
||||
|
||||
func (r *SQLiteRepository) DeleteConnectionLimiter(id int) (constant.ConnectionLimiter, error) {
|
||||
var cl constant.ConnectionLimiter
|
||||
var squadIDs intSliceJSON
|
||||
err := r.db.QueryRowContext(r.ctx, `
|
||||
tx, err := r.db.BeginTx(r.ctx, nil)
|
||||
if err != nil {
|
||||
return cl, err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
var squadIDs []int
|
||||
squadRows, err := tx.QueryContext(r.ctx, `SELECT squad_id FROM connection_limiter_to_squad WHERE connection_limiter_id = ?`, id)
|
||||
if err != nil {
|
||||
return cl, err
|
||||
}
|
||||
for squadRows.Next() {
|
||||
var squadID int
|
||||
if err = squadRows.Scan(&squadID); err != nil {
|
||||
squadRows.Close()
|
||||
return cl, err
|
||||
}
|
||||
squadIDs = append(squadIDs, squadID)
|
||||
}
|
||||
squadRows.Close()
|
||||
if err = squadRows.Err(); err != nil {
|
||||
return cl, err
|
||||
}
|
||||
err = tx.QueryRowContext(r.ctx, `
|
||||
DELETE FROM connection_limiters
|
||||
WHERE id=?
|
||||
RETURNING
|
||||
id,
|
||||
(
|
||||
SELECT json_group_array(squad_id)
|
||||
FROM connection_limiter_to_squad
|
||||
WHERE connection_limiter_to_squad.connection_limiter_id = connection_limiters.id
|
||||
) as squad_ids,
|
||||
username,
|
||||
outbound,
|
||||
strategy,
|
||||
@@ -1087,7 +1122,6 @@ func (r *SQLiteRepository) DeleteConnectionLimiter(id int) (constant.ConnectionL
|
||||
updated_at
|
||||
`, id).Scan(
|
||||
&cl.ID,
|
||||
&squadIDs,
|
||||
&cl.Username,
|
||||
&cl.Outbound,
|
||||
&cl.Strategy,
|
||||
@@ -1097,8 +1131,11 @@ func (r *SQLiteRepository) DeleteConnectionLimiter(id int) (constant.ConnectionL
|
||||
&cl.CreatedAt,
|
||||
&cl.UpdatedAt,
|
||||
)
|
||||
cl.SquadIDs = []int(squadIDs)
|
||||
return cl, err
|
||||
if err != nil {
|
||||
return cl, err
|
||||
}
|
||||
cl.SquadIDs = squadIDs
|
||||
return cl, tx.Commit()
|
||||
}
|
||||
|
||||
func (r *SQLiteRepository) CreateBandwidthLimiter(limiter constant.BandwidthLimiterCreate) (constant.BandwidthLimiter, error) {
|
||||
@@ -1120,7 +1157,7 @@ func (r *SQLiteRepository) CreateBandwidthLimiter(limiter constant.BandwidthLimi
|
||||
if err != nil {
|
||||
return bl, err
|
||||
}
|
||||
var flowKeys stringSliceJSON
|
||||
var flowKeys sql.SliceJSON[string]
|
||||
now := time.Now()
|
||||
err = tx.QueryRowContext(
|
||||
r.ctx, `
|
||||
@@ -1233,8 +1270,8 @@ func (r *SQLiteRepository) GetBandwidthLimiters(filters map[string][]string) ([]
|
||||
var result []constant.BandwidthLimiter
|
||||
for rows.Next() {
|
||||
var bl constant.BandwidthLimiter
|
||||
var squadIDs intSliceJSON
|
||||
var flowKeys stringSliceJSON
|
||||
var squadIDs sql.SliceJSON[int]
|
||||
var flowKeys sql.SliceJSON[string]
|
||||
if err := rows.Scan(
|
||||
&bl.ID,
|
||||
&squadIDs,
|
||||
@@ -1277,8 +1314,8 @@ func (r *SQLiteRepository) GetBandwidthLimitersCount(filters map[string][]string
|
||||
|
||||
func (r *SQLiteRepository) GetBandwidthLimiter(id int) (constant.BandwidthLimiter, error) {
|
||||
var bl constant.BandwidthLimiter
|
||||
var squadIDs intSliceJSON
|
||||
var flowKeys stringSliceJSON
|
||||
var squadIDs sql.SliceJSON[int]
|
||||
var flowKeys sql.SliceJSON[string]
|
||||
err := r.db.QueryRowContext(r.ctx, `
|
||||
SELECT
|
||||
id,
|
||||
@@ -1320,8 +1357,8 @@ func (r *SQLiteRepository) GetBandwidthLimiter(id int) (constant.BandwidthLimite
|
||||
|
||||
func (r *SQLiteRepository) UpdateBandwidthLimiter(id int, limiter constant.BandwidthLimiterUpdate) (constant.BandwidthLimiter, error) {
|
||||
var bl constant.BandwidthLimiter
|
||||
var squadIDs intSliceJSON
|
||||
var flowKeys stringSliceJSON
|
||||
var squadIDs sql.SliceJSON[int]
|
||||
var flowKeys sql.SliceJSON[string]
|
||||
bytesSpeed, err := json.Marshal(limiter.Speed)
|
||||
if err != nil {
|
||||
return bl, err
|
||||
@@ -1397,18 +1434,34 @@ func (r *SQLiteRepository) UpdateBandwidthLimiter(id int, limiter constant.Bandw
|
||||
|
||||
func (r *SQLiteRepository) DeleteBandwidthLimiter(id int) (constant.BandwidthLimiter, error) {
|
||||
var bl constant.BandwidthLimiter
|
||||
var squadIDs intSliceJSON
|
||||
var flowKeys stringSliceJSON
|
||||
err := r.db.QueryRowContext(r.ctx, `
|
||||
var flowKeys sql.SliceJSON[string]
|
||||
tx, err := r.db.BeginTx(r.ctx, nil)
|
||||
if err != nil {
|
||||
return bl, err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
var squadIDs []int
|
||||
squadRows, err := tx.QueryContext(r.ctx, `SELECT squad_id FROM bandwidth_limiter_to_squad WHERE bandwidth_limiter_id = ?`, id)
|
||||
if err != nil {
|
||||
return bl, err
|
||||
}
|
||||
for squadRows.Next() {
|
||||
var squadID int
|
||||
if err = squadRows.Scan(&squadID); err != nil {
|
||||
squadRows.Close()
|
||||
return bl, err
|
||||
}
|
||||
squadIDs = append(squadIDs, squadID)
|
||||
}
|
||||
squadRows.Close()
|
||||
if err = squadRows.Err(); err != nil {
|
||||
return bl, err
|
||||
}
|
||||
err = tx.QueryRowContext(r.ctx, `
|
||||
DELETE FROM bandwidth_limiters
|
||||
WHERE id=?
|
||||
RETURNING
|
||||
id,
|
||||
(
|
||||
SELECT json_group_array(squad_id)
|
||||
FROM bandwidth_limiter_to_squad
|
||||
WHERE bandwidth_limiter_to_squad.bandwidth_limiter_id = bandwidth_limiters.id
|
||||
) as squad_ids,
|
||||
username,
|
||||
outbound,
|
||||
strategy,
|
||||
@@ -1421,7 +1474,6 @@ func (r *SQLiteRepository) DeleteBandwidthLimiter(id int) (constant.BandwidthLim
|
||||
updated_at
|
||||
`, id).Scan(
|
||||
&bl.ID,
|
||||
&squadIDs,
|
||||
&bl.Username,
|
||||
&bl.Outbound,
|
||||
&bl.Strategy,
|
||||
@@ -1433,9 +1485,12 @@ func (r *SQLiteRepository) DeleteBandwidthLimiter(id int) (constant.BandwidthLim
|
||||
&bl.CreatedAt,
|
||||
&bl.UpdatedAt,
|
||||
)
|
||||
bl.SquadIDs = []int(squadIDs)
|
||||
if err != nil {
|
||||
return bl, err
|
||||
}
|
||||
bl.SquadIDs = squadIDs
|
||||
bl.FlowKeys = []string(flowKeys)
|
||||
return bl, err
|
||||
return bl, tx.Commit()
|
||||
}
|
||||
|
||||
func (r *SQLiteRepository) CreateTrafficLimiter(limiter constant.TrafficLimiterCreate) (constant.TrafficLimiter, error) {
|
||||
@@ -1560,7 +1615,7 @@ func (r *SQLiteRepository) GetTrafficLimiters(filters map[string][]string) ([]co
|
||||
var result []constant.TrafficLimiter
|
||||
for rows.Next() {
|
||||
var tl constant.TrafficLimiter
|
||||
var squadIDs intSliceJSON
|
||||
var squadIDs sql.SliceJSON[int]
|
||||
if err := rows.Scan(
|
||||
&tl.ID,
|
||||
&squadIDs,
|
||||
@@ -1602,7 +1657,7 @@ func (r *SQLiteRepository) GetTrafficLimitersCount(filters map[string][]string)
|
||||
|
||||
func (r *SQLiteRepository) GetTrafficLimiter(id int) (constant.TrafficLimiter, error) {
|
||||
var tl constant.TrafficLimiter
|
||||
var squadIDs intSliceJSON
|
||||
var squadIDs sql.SliceJSON[int]
|
||||
err := r.db.QueryRowContext(r.ctx, `
|
||||
SELECT
|
||||
id,
|
||||
@@ -1643,7 +1698,7 @@ func (r *SQLiteRepository) GetTrafficLimiter(id int) (constant.TrafficLimiter, e
|
||||
|
||||
func (r *SQLiteRepository) UpdateTrafficLimiter(id int, limiter constant.TrafficLimiterUpdate) (constant.TrafficLimiter, error) {
|
||||
var tl constant.TrafficLimiter
|
||||
var squadIDs intSliceJSON
|
||||
var squadIDs sql.SliceJSON[int]
|
||||
bytesQuota, err := json.Marshal(limiter.Quota)
|
||||
if err != nil {
|
||||
return tl, err
|
||||
@@ -1710,7 +1765,7 @@ func (r *SQLiteRepository) UpdateTrafficLimiter(id int, limiter constant.Traffic
|
||||
|
||||
func (r *SQLiteRepository) UpdateTrafficLimiterUsed(id int, current uint64) (constant.TrafficLimiter, error) {
|
||||
var tl constant.TrafficLimiter
|
||||
var squadIDs intSliceJSON
|
||||
var squadIDs sql.SliceJSON[int]
|
||||
err := r.db.QueryRowContext(
|
||||
r.ctx, `
|
||||
UPDATE traffic_limiters
|
||||
@@ -1759,17 +1814,33 @@ func (r *SQLiteRepository) UpdateTrafficLimiterUsed(id int, current uint64) (con
|
||||
|
||||
func (r *SQLiteRepository) DeleteTrafficLimiter(id int) (constant.TrafficLimiter, error) {
|
||||
var tl constant.TrafficLimiter
|
||||
var squadIDs intSliceJSON
|
||||
err := r.db.QueryRowContext(r.ctx, `
|
||||
tx, err := r.db.BeginTx(r.ctx, nil)
|
||||
if err != nil {
|
||||
return tl, err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
var squadIDs []int
|
||||
squadRows, err := tx.QueryContext(r.ctx, `SELECT squad_id FROM traffic_limiter_to_squad WHERE traffic_limiter_id = ?`, id)
|
||||
if err != nil {
|
||||
return tl, err
|
||||
}
|
||||
for squadRows.Next() {
|
||||
var squadID int
|
||||
if err = squadRows.Scan(&squadID); err != nil {
|
||||
squadRows.Close()
|
||||
return tl, err
|
||||
}
|
||||
squadIDs = append(squadIDs, squadID)
|
||||
}
|
||||
squadRows.Close()
|
||||
if err = squadRows.Err(); err != nil {
|
||||
return tl, err
|
||||
}
|
||||
err = tx.QueryRowContext(r.ctx, `
|
||||
DELETE FROM traffic_limiters
|
||||
WHERE id=?
|
||||
RETURNING
|
||||
id,
|
||||
(
|
||||
SELECT json_group_array(squad_id)
|
||||
FROM traffic_limiter_to_squad
|
||||
WHERE traffic_limiter_to_squad.traffic_limiter_id = traffic_limiters.id
|
||||
) as squad_ids,
|
||||
username,
|
||||
outbound,
|
||||
strategy,
|
||||
@@ -1782,7 +1853,6 @@ func (r *SQLiteRepository) DeleteTrafficLimiter(id int) (constant.TrafficLimiter
|
||||
updated_at
|
||||
`, id).Scan(
|
||||
&tl.ID,
|
||||
&squadIDs,
|
||||
&tl.Username,
|
||||
&tl.Outbound,
|
||||
&tl.Strategy,
|
||||
@@ -1794,8 +1864,11 @@ func (r *SQLiteRepository) DeleteTrafficLimiter(id int) (constant.TrafficLimiter
|
||||
&tl.CreatedAt,
|
||||
&tl.UpdatedAt,
|
||||
)
|
||||
tl.SquadIDs = []int(squadIDs)
|
||||
return tl, err
|
||||
if err != nil {
|
||||
return tl, err
|
||||
}
|
||||
tl.SquadIDs = squadIDs
|
||||
return tl, tx.Commit()
|
||||
}
|
||||
|
||||
func (r *SQLiteRepository) CreateRateLimiter(limiter constant.RateLimiterCreate) (constant.RateLimiter, error) {
|
||||
@@ -1906,7 +1979,7 @@ func (r *SQLiteRepository) GetRateLimiters(filters map[string][]string) ([]const
|
||||
var result []constant.RateLimiter
|
||||
for rows.Next() {
|
||||
var rl constant.RateLimiter
|
||||
var squadIDs intSliceJSON
|
||||
var squadIDs sql.SliceJSON[int]
|
||||
if err := rows.Scan(
|
||||
&rl.ID,
|
||||
&squadIDs,
|
||||
@@ -1946,7 +2019,7 @@ func (r *SQLiteRepository) GetRateLimitersCount(filters map[string][]string) (in
|
||||
|
||||
func (r *SQLiteRepository) GetRateLimiter(id int) (constant.RateLimiter, error) {
|
||||
var rl constant.RateLimiter
|
||||
var squadIDs intSliceJSON
|
||||
var squadIDs sql.SliceJSON[int]
|
||||
err := r.db.QueryRowContext(r.ctx, `
|
||||
SELECT
|
||||
id,
|
||||
@@ -1983,7 +2056,7 @@ func (r *SQLiteRepository) GetRateLimiter(id int) (constant.RateLimiter, error)
|
||||
|
||||
func (r *SQLiteRepository) UpdateRateLimiter(id int, limiter constant.RateLimiterUpdate) (constant.RateLimiter, error) {
|
||||
var rl constant.RateLimiter
|
||||
var squadIDs intSliceJSON
|
||||
var squadIDs sql.SliceJSON[int]
|
||||
err := r.db.QueryRowContext(
|
||||
r.ctx, `
|
||||
UPDATE rate_limiters
|
||||
@@ -2038,17 +2111,33 @@ func (r *SQLiteRepository) UpdateRateLimiter(id int, limiter constant.RateLimite
|
||||
|
||||
func (r *SQLiteRepository) DeleteRateLimiter(id int) (constant.RateLimiter, error) {
|
||||
var rl constant.RateLimiter
|
||||
var squadIDs intSliceJSON
|
||||
err := r.db.QueryRowContext(r.ctx, `
|
||||
tx, err := r.db.BeginTx(r.ctx, nil)
|
||||
if err != nil {
|
||||
return rl, err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
var squadIDs []int
|
||||
squadRows, err := tx.QueryContext(r.ctx, `SELECT squad_id FROM rate_limiter_to_squad WHERE rate_limiter_id = ?`, id)
|
||||
if err != nil {
|
||||
return rl, err
|
||||
}
|
||||
for squadRows.Next() {
|
||||
var squadID int
|
||||
if err = squadRows.Scan(&squadID); err != nil {
|
||||
squadRows.Close()
|
||||
return rl, err
|
||||
}
|
||||
squadIDs = append(squadIDs, squadID)
|
||||
}
|
||||
squadRows.Close()
|
||||
if err = squadRows.Err(); err != nil {
|
||||
return rl, err
|
||||
}
|
||||
err = tx.QueryRowContext(r.ctx, `
|
||||
DELETE FROM rate_limiters
|
||||
WHERE id=?
|
||||
RETURNING
|
||||
id,
|
||||
(
|
||||
SELECT json_group_array(squad_id)
|
||||
FROM rate_limiter_to_squad
|
||||
WHERE rate_limiter_to_squad.rate_limiter_id = rate_limiters.id
|
||||
) as squad_ids,
|
||||
username,
|
||||
outbound,
|
||||
strategy,
|
||||
@@ -2059,7 +2148,6 @@ func (r *SQLiteRepository) DeleteRateLimiter(id int) (constant.RateLimiter, erro
|
||||
updated_at
|
||||
`, id).Scan(
|
||||
&rl.ID,
|
||||
&squadIDs,
|
||||
&rl.Username,
|
||||
&rl.Outbound,
|
||||
&rl.Strategy,
|
||||
@@ -2069,30 +2157,30 @@ func (r *SQLiteRepository) DeleteRateLimiter(id int) (constant.RateLimiter, erro
|
||||
&rl.CreatedAt,
|
||||
&rl.UpdatedAt,
|
||||
)
|
||||
rl.SquadIDs = []int(squadIDs)
|
||||
return rl, err
|
||||
if err != nil {
|
||||
return rl, err
|
||||
}
|
||||
rl.SquadIDs = squadIDs
|
||||
return rl, tx.Commit()
|
||||
}
|
||||
|
||||
func init() {
|
||||
squadFilters = map[string]Filter{
|
||||
"id": EqualFilter("id"),
|
||||
"id_in": InFilter("id"),
|
||||
"pk": EqualFilter("id"),
|
||||
"name": EqualFilter("name"),
|
||||
"created_at_start": GreaterThanFilter("created_at"),
|
||||
"created_at_end": LessThanFilter("created_at"),
|
||||
"updated_at_start": GreaterThanFilter("updated_at"),
|
||||
"updated_at_end": LessThanFilter("updated_at"),
|
||||
"sort_asc": SortAscFilter([]string{"id", "name", "created_at", "updated_at"}),
|
||||
"sort_desc": SortDescFilter([]string{"id", "name", "created_at", "updated_at"}),
|
||||
"offset": OffsetFilter(),
|
||||
"limit": LimitFilter(),
|
||||
}
|
||||
nodeFilters = map[string]Filter{
|
||||
"uuid": EqualFilter("uuid"),
|
||||
"pk": EqualFilter("uuid"),
|
||||
"name": EqualFilter("name"),
|
||||
"squad_id_in": ExistsAndWhereInFilter(func() *sqlbuilder.SelectBuilder {
|
||||
squadFilters = map[string]sql.Filter{"id": sql.EqualFilter("id"),
|
||||
"id_in": sql.InFilter("id"),
|
||||
"pk": sql.EqualFilter("id"),
|
||||
"name": sql.EqualFilter("name"),
|
||||
"created_at_start": sql.GreaterThanFilter("created_at"),
|
||||
"created_at_end": sql.LessThanFilter("created_at"),
|
||||
"updated_at_start": sql.GreaterThanFilter("updated_at"),
|
||||
"updated_at_end": sql.LessThanFilter("updated_at"),
|
||||
"sort_asc": sql.SortAscFilter([]string{"id", "name", "created_at", "updated_at"}),
|
||||
"sort_desc": sql.SortDescFilter([]string{"id", "name", "created_at", "updated_at"}),
|
||||
"offset": sql.OffsetFilter(),
|
||||
"limit": sql.LimitFilter()}
|
||||
nodeFilters = map[string]sql.Filter{"uuid": sql.EqualFilter("uuid"),
|
||||
"pk": sql.EqualFilter("uuid"),
|
||||
"name": sql.EqualFilter("name"),
|
||||
"squad_id_in": sql.ExistsAndWhereInFilter(func() *sqlbuilder.SelectBuilder {
|
||||
return sqlbuilder.SQLite.NewSelectBuilder().
|
||||
Select(
|
||||
"squad_id",
|
||||
@@ -2104,19 +2192,17 @@ func init() {
|
||||
"node_to_squad",
|
||||
)
|
||||
}, "node_to_squad.squad_id"),
|
||||
"created_at_start": GreaterThanFilter("created_at"),
|
||||
"created_at_end": LessThanFilter("created_at"),
|
||||
"updated_at_start": GreaterThanFilter("updated_at"),
|
||||
"updated_at_end": LessThanFilter("updated_at"),
|
||||
"sort_asc": SortAscFilter([]string{"uuid", "name", "created_at", "updated_at"}),
|
||||
"sort_desc": SortDescFilter([]string{"uuid", "name", "created_at", "updated_at"}),
|
||||
"offset": OffsetFilter(),
|
||||
"limit": LimitFilter(),
|
||||
}
|
||||
userFilters = map[string]Filter{
|
||||
"id": EqualFilter("id"),
|
||||
"pk": EqualFilter("id"),
|
||||
"squad_id_in": ExistsAndWhereInFilter(func() *sqlbuilder.SelectBuilder {
|
||||
"created_at_start": sql.GreaterThanFilter("created_at"),
|
||||
"created_at_end": sql.LessThanFilter("created_at"),
|
||||
"updated_at_start": sql.GreaterThanFilter("updated_at"),
|
||||
"updated_at_end": sql.LessThanFilter("updated_at"),
|
||||
"sort_asc": sql.SortAscFilter([]string{"uuid", "name", "created_at", "updated_at"}),
|
||||
"sort_desc": sql.SortDescFilter([]string{"uuid", "name", "created_at", "updated_at"}),
|
||||
"offset": sql.OffsetFilter(),
|
||||
"limit": sql.LimitFilter()}
|
||||
userFilters = map[string]sql.Filter{"id": sql.EqualFilter("id"),
|
||||
"pk": sql.EqualFilter("id"),
|
||||
"squad_id_in": sql.ExistsAndWhereInFilter(func() *sqlbuilder.SelectBuilder {
|
||||
return sqlbuilder.SQLite.NewSelectBuilder().
|
||||
Select(
|
||||
"squad_id",
|
||||
@@ -2128,21 +2214,19 @@ func init() {
|
||||
"user_to_squad",
|
||||
)
|
||||
}, "user_to_squad.squad_id"),
|
||||
"username": EqualFilter("username"),
|
||||
"inbound": EqualFilter("inbound"),
|
||||
"created_at_start": GreaterThanFilter("created_at"),
|
||||
"created_at_end": LessThanFilter("created_at"),
|
||||
"updated_at_start": GreaterThanFilter("updated_at"),
|
||||
"updated_at_end": LessThanFilter("updated_at"),
|
||||
"sort_asc": SortAscFilter([]string{"id", "username", "inbound", "type", "created_at", "updated_at"}),
|
||||
"sort_desc": SortDescFilter([]string{"id", "username", "inbound", "type", "created_at", "updated_at"}),
|
||||
"offset": OffsetFilter(),
|
||||
"limit": LimitFilter(),
|
||||
}
|
||||
connectionLimiterFilters = map[string]Filter{
|
||||
"id": EqualFilter("id"),
|
||||
"pk": EqualFilter("id"),
|
||||
"squad_id_in": ExistsAndWhereInFilter(func() *sqlbuilder.SelectBuilder {
|
||||
"username": sql.EqualFilter("username"),
|
||||
"inbound": sql.EqualFilter("inbound"),
|
||||
"created_at_start": sql.GreaterThanFilter("created_at"),
|
||||
"created_at_end": sql.LessThanFilter("created_at"),
|
||||
"updated_at_start": sql.GreaterThanFilter("updated_at"),
|
||||
"updated_at_end": sql.LessThanFilter("updated_at"),
|
||||
"sort_asc": sql.SortAscFilter([]string{"id", "username", "inbound", "type", "created_at", "updated_at"}),
|
||||
"sort_desc": sql.SortDescFilter([]string{"id", "username", "inbound", "type", "created_at", "updated_at"}),
|
||||
"offset": sql.OffsetFilter(),
|
||||
"limit": sql.LimitFilter()}
|
||||
connectionLimiterFilters = map[string]sql.Filter{"id": sql.EqualFilter("id"),
|
||||
"pk": sql.EqualFilter("id"),
|
||||
"squad_id_in": sql.ExistsAndWhereInFilter(func() *sqlbuilder.SelectBuilder {
|
||||
return sqlbuilder.SQLite.NewSelectBuilder().
|
||||
Select(
|
||||
"squad_id",
|
||||
@@ -2154,24 +2238,22 @@ func init() {
|
||||
"connection_limiter_to_squad",
|
||||
)
|
||||
}, "connection_limiter_to_squad.squad_id"),
|
||||
"strategy": EqualFilter("strategy"),
|
||||
"username": EqualFilter("username"),
|
||||
"outbound": EqualFilter("outbound"),
|
||||
"connection_type": EqualFilter("connection_type"),
|
||||
"lock_type": EqualFilter("lock_type"),
|
||||
"created_at_start": GreaterThanFilter("created_at"),
|
||||
"created_at_end": LessThanFilter("created_at"),
|
||||
"updated_at_start": GreaterThanFilter("updated_at"),
|
||||
"updated_at_end": LessThanFilter("updated_at"),
|
||||
"sort_asc": SortAscFilter([]string{"id", "username", "outbound", "strategy", "connection_type", "lock_type", "count", "created_at", "updated_at"}),
|
||||
"sort_desc": SortDescFilter([]string{"id", "username", "outbound", "strategy", "connection_type", "lock_type", "count", "created_at", "updated_at"}),
|
||||
"offset": OffsetFilter(),
|
||||
"limit": LimitFilter(),
|
||||
}
|
||||
bandwidthLimiterFilters = map[string]Filter{
|
||||
"id": EqualFilter("id"),
|
||||
"pk": EqualFilter("id"),
|
||||
"squad_id_in": ExistsAndWhereInFilter(func() *sqlbuilder.SelectBuilder {
|
||||
"strategy": sql.EqualFilter("strategy"),
|
||||
"username": sql.EqualFilter("username"),
|
||||
"outbound": sql.EqualFilter("outbound"),
|
||||
"connection_type": sql.EqualFilter("connection_type"),
|
||||
"lock_type": sql.EqualFilter("lock_type"),
|
||||
"created_at_start": sql.GreaterThanFilter("created_at"),
|
||||
"created_at_end": sql.LessThanFilter("created_at"),
|
||||
"updated_at_start": sql.GreaterThanFilter("updated_at"),
|
||||
"updated_at_end": sql.LessThanFilter("updated_at"),
|
||||
"sort_asc": sql.SortAscFilter([]string{"id", "username", "outbound", "strategy", "connection_type", "lock_type", "count", "created_at", "updated_at"}),
|
||||
"sort_desc": sql.SortDescFilter([]string{"id", "username", "outbound", "strategy", "connection_type", "lock_type", "count", "created_at", "updated_at"}),
|
||||
"offset": sql.OffsetFilter(),
|
||||
"limit": sql.LimitFilter()}
|
||||
bandwidthLimiterFilters = map[string]sql.Filter{"id": sql.EqualFilter("id"),
|
||||
"pk": sql.EqualFilter("id"),
|
||||
"squad_id_in": sql.ExistsAndWhereInFilter(func() *sqlbuilder.SelectBuilder {
|
||||
return sqlbuilder.SQLite.NewSelectBuilder().
|
||||
Select(
|
||||
"squad_id",
|
||||
@@ -2183,28 +2265,22 @@ func init() {
|
||||
"bandwidth_limiter_to_squad",
|
||||
)
|
||||
}, "bandwidth_limiter_to_squad.squad_id"),
|
||||
"strategy": EqualFilter("strategy"),
|
||||
"mode": EqualFilter("mode"),
|
||||
"username": EqualFilter("username"),
|
||||
"created_at_start": GreaterThanFilter("created_at"),
|
||||
"created_at_end": LessThanFilter("created_at"),
|
||||
"updated_at_start": GreaterThanFilter("updated_at"),
|
||||
"updated_at_end": LessThanFilter("updated_at"),
|
||||
"sort_asc": ReplacedSortAscFilter(
|
||||
map[string]string{"speed": "raw_speed"},
|
||||
[]string{"id", "username", "outbound", "strategy", "connection_type", "mode", "raw_speed", "created_at", "updated_at"},
|
||||
),
|
||||
"sort_desc": ReplacedSortDescFilter(
|
||||
map[string]string{"speed": "raw_speed"},
|
||||
[]string{"id", "username", "outbound", "strategy", "connection_type", "mode", "raw_speed", "created_at", "updated_at"},
|
||||
),
|
||||
"offset": OffsetFilter(),
|
||||
"limit": LimitFilter(),
|
||||
}
|
||||
trafficLimiterFilters = map[string]Filter{
|
||||
"id": EqualFilter("id"),
|
||||
"pk": EqualFilter("id"),
|
||||
"squad_id_in": ExistsAndWhereInFilter(func() *sqlbuilder.SelectBuilder {
|
||||
"strategy": sql.EqualFilter("strategy"),
|
||||
"mode": sql.EqualFilter("mode"),
|
||||
"username": sql.EqualFilter("username"),
|
||||
"created_at_start": sql.GreaterThanFilter("created_at"),
|
||||
"created_at_end": sql.LessThanFilter("created_at"),
|
||||
"updated_at_start": sql.GreaterThanFilter("updated_at"),
|
||||
"updated_at_end": sql.LessThanFilter("updated_at"),
|
||||
"sort_asc": sql.ReplacedSortAscFilter(map[string]string{"speed": "raw_speed"},
|
||||
[]string{"id", "username", "outbound", "strategy", "connection_type", "mode", "raw_speed", "created_at", "updated_at"}),
|
||||
"sort_desc": sql.ReplacedSortDescFilter(map[string]string{"speed": "raw_speed"},
|
||||
[]string{"id", "username", "outbound", "strategy", "connection_type", "mode", "raw_speed", "created_at", "updated_at"}),
|
||||
"offset": sql.OffsetFilter(),
|
||||
"limit": sql.LimitFilter()}
|
||||
trafficLimiterFilters = map[string]sql.Filter{"id": sql.EqualFilter("id"),
|
||||
"pk": sql.EqualFilter("id"),
|
||||
"squad_id_in": sql.ExistsAndWhereInFilter(func() *sqlbuilder.SelectBuilder {
|
||||
return sqlbuilder.SQLite.NewSelectBuilder().
|
||||
Select(
|
||||
"squad_id",
|
||||
@@ -2216,33 +2292,27 @@ func init() {
|
||||
"traffic_limiter_to_squad",
|
||||
)
|
||||
}, "traffic_limiter_to_squad.squad_id"),
|
||||
"username": EqualFilter("username"),
|
||||
"outbound": EqualFilter("outbound"),
|
||||
"strategy": EqualFilter("strategy"),
|
||||
"mode": EqualFilter("mode"),
|
||||
"used_start": SpeedGreaterEqualThanFilter("raw_used"),
|
||||
"used_end": SpeedLessEqualThanFilter("raw_used"),
|
||||
"quota_start": SpeedGreaterEqualThanFilter("raw_quota"),
|
||||
"quota_end": SpeedLessEqualThanFilter("raw_quota"),
|
||||
"created_at_start": GreaterThanFilter("created_at"),
|
||||
"created_at_end": LessThanFilter("created_at"),
|
||||
"updated_at_start": GreaterThanFilter("updated_at"),
|
||||
"updated_at_end": LessThanFilter("updated_at"),
|
||||
"sort_asc": ReplacedSortAscFilter(
|
||||
map[string]string{"used": "raw_used", "quota": "raw_quota"},
|
||||
[]string{"id", "username", "outbound", "strategy", "mode", "raw_used", "raw_quota", "created_at", "updated_at"},
|
||||
),
|
||||
"sort_desc": ReplacedSortDescFilter(
|
||||
map[string]string{"used": "raw_used", "quota": "raw_quota"},
|
||||
[]string{"id", "username", "outbound", "strategy", "mode", "raw_used", "raw_quota", "created_at", "updated_at"},
|
||||
),
|
||||
"offset": OffsetFilter(),
|
||||
"limit": LimitFilter(),
|
||||
}
|
||||
rateLimiterFilters = map[string]Filter{
|
||||
"id": EqualFilter("id"),
|
||||
"pk": EqualFilter("id"),
|
||||
"squad_id_in": ExistsAndWhereInFilter(func() *sqlbuilder.SelectBuilder {
|
||||
"username": sql.EqualFilter("username"),
|
||||
"outbound": sql.EqualFilter("outbound"),
|
||||
"strategy": sql.EqualFilter("strategy"),
|
||||
"mode": sql.EqualFilter("mode"),
|
||||
"used_start": sql.SpeedGreaterEqualThanFilter("raw_used"),
|
||||
"used_end": sql.SpeedLessEqualThanFilter("raw_used"),
|
||||
"quota_start": sql.SpeedGreaterEqualThanFilter("raw_quota"),
|
||||
"quota_end": sql.SpeedLessEqualThanFilter("raw_quota"),
|
||||
"created_at_start": sql.GreaterThanFilter("created_at"),
|
||||
"created_at_end": sql.LessThanFilter("created_at"),
|
||||
"updated_at_start": sql.GreaterThanFilter("updated_at"),
|
||||
"updated_at_end": sql.LessThanFilter("updated_at"),
|
||||
"sort_asc": sql.ReplacedSortAscFilter(map[string]string{"used": "raw_used", "quota": "raw_quota"},
|
||||
[]string{"id", "username", "outbound", "strategy", "mode", "raw_used", "raw_quota", "created_at", "updated_at"}),
|
||||
"sort_desc": sql.ReplacedSortDescFilter(map[string]string{"used": "raw_used", "quota": "raw_quota"},
|
||||
[]string{"id", "username", "outbound", "strategy", "mode", "raw_used", "raw_quota", "created_at", "updated_at"}),
|
||||
"offset": sql.OffsetFilter(),
|
||||
"limit": sql.LimitFilter()}
|
||||
rateLimiterFilters = map[string]sql.Filter{"id": sql.EqualFilter("id"),
|
||||
"pk": sql.EqualFilter("id"),
|
||||
"squad_id_in": sql.ExistsAndWhereInFilter(func() *sqlbuilder.SelectBuilder {
|
||||
return sqlbuilder.SQLite.NewSelectBuilder().
|
||||
Select(
|
||||
"squad_id",
|
||||
@@ -2254,20 +2324,19 @@ func init() {
|
||||
"rate_limiter_to_squad",
|
||||
)
|
||||
}, "rate_limiter_to_squad.squad_id"),
|
||||
"strategy": EqualFilter("strategy"),
|
||||
"username": EqualFilter("username"),
|
||||
"outbound": EqualFilter("outbound"),
|
||||
"connection_type": EqualFilter("connection_type"),
|
||||
"interval": EqualFilter("interval"),
|
||||
"count_start": GreaterEqualThanFilter("count"),
|
||||
"count_end": LessEqualThanFilter("count"),
|
||||
"created_at_start": GreaterThanFilter("created_at"),
|
||||
"created_at_end": LessThanFilter("created_at"),
|
||||
"updated_at_start": GreaterThanFilter("updated_at"),
|
||||
"updated_at_end": LessThanFilter("updated_at"),
|
||||
"sort_asc": SortAscFilter([]string{"id", "username", "outbound", "strategy", "connection_type", "count", "interval", "created_at", "updated_at"}),
|
||||
"sort_desc": SortDescFilter([]string{"id", "username", "outbound", "strategy", "connection_type", "count", "interval", "created_at", "updated_at"}),
|
||||
"offset": OffsetFilter(),
|
||||
"limit": LimitFilter(),
|
||||
}
|
||||
"strategy": sql.EqualFilter("strategy"),
|
||||
"username": sql.EqualFilter("username"),
|
||||
"outbound": sql.EqualFilter("outbound"),
|
||||
"connection_type": sql.EqualFilter("connection_type"),
|
||||
"interval": sql.EqualFilter("interval"),
|
||||
"count_start": sql.GreaterEqualThanFilter("count"),
|
||||
"count_end": sql.LessEqualThanFilter("count"),
|
||||
"created_at_start": sql.GreaterThanFilter("created_at"),
|
||||
"created_at_end": sql.LessThanFilter("created_at"),
|
||||
"updated_at_start": sql.GreaterThanFilter("updated_at"),
|
||||
"updated_at_end": sql.LessThanFilter("updated_at"),
|
||||
"sort_asc": sql.SortAscFilter([]string{"id", "username", "outbound", "strategy", "connection_type", "count", "interval", "created_at", "updated_at"}),
|
||||
"sort_desc": sql.SortDescFilter([]string{"id", "username", "outbound", "strategy", "connection_type", "count", "interval", "created_at", "updated_at"}),
|
||||
"offset": sql.OffsetFilter(),
|
||||
"limit": sql.LimitFilter()}
|
||||
}
|
||||
16
service/manager/repository/main/sqlite/utils.go
Normal file
16
service/manager/repository/main/sqlite/utils.go
Normal file
@@ -0,0 +1,16 @@
|
||||
package sqlite
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
func marshalStringSlice(values []string) (string, error) {
|
||||
if values == nil {
|
||||
values = []string{}
|
||||
}
|
||||
data, err := json.Marshal(values)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(data), nil
|
||||
}
|
||||
@@ -1,195 +0,0 @@
|
||||
package postgresql
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"slices"
|
||||
"strconv"
|
||||
|
||||
"github.com/huandu/go-sqlbuilder"
|
||||
"github.com/sagernet/sing/common/byteformats"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
)
|
||||
|
||||
type Filter func(sb *sqlbuilder.SelectBuilder, value []string) error
|
||||
|
||||
func EqualFilter(field string) Filter {
|
||||
return func(sb *sqlbuilder.SelectBuilder, value []string) error {
|
||||
sb.Where(sb.Equal(field, value[0]))
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func EqualOrNullFilter(field string) Filter {
|
||||
return func(sb *sqlbuilder.SelectBuilder, value []string) error {
|
||||
sb.Where(sb.Or(sb.Equal(field, value[0]), sb.IsNull(field)))
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func GreaterThanFilter(field string) Filter {
|
||||
return func(sb *sqlbuilder.SelectBuilder, value []string) error {
|
||||
sb.Where(sb.GreaterThan(field, value[0]))
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func LessThanFilter(field string) Filter {
|
||||
return func(sb *sqlbuilder.SelectBuilder, value []string) error {
|
||||
sb.Where(sb.LessThan(field, value[0]))
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func GreaterEqualThanFilter(field string) Filter {
|
||||
return func(sb *sqlbuilder.SelectBuilder, value []string) error {
|
||||
sb.Where(sb.GreaterEqualThan(field, value[0]))
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func LessEqualThanFilter(field string) Filter {
|
||||
return func(sb *sqlbuilder.SelectBuilder, value []string) error {
|
||||
sb.Where(sb.LessEqualThan(field, value[0]))
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func SpeedGreaterEqualThanFilter(field string) Filter {
|
||||
return func(sb *sqlbuilder.SelectBuilder, value []string) error {
|
||||
bytesSpeed, err := json.Marshal(value[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
speed := &byteformats.NetworkBytesCompat{}
|
||||
err = speed.UnmarshalJSON(bytesSpeed)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sb.Where(sb.GreaterEqualThan(field, speed.Value()))
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func SpeedLessEqualThanFilter(field string) Filter {
|
||||
return func(sb *sqlbuilder.SelectBuilder, value []string) error {
|
||||
bytesSpeed, err := json.Marshal(value[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
speed := &byteformats.NetworkBytesCompat{}
|
||||
err = speed.UnmarshalJSON(bytesSpeed)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sb.Where(sb.LessEqualThan(field, speed.Value()))
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func ExistsAndWhereInFilter(subqueryFactory func() *sqlbuilder.SelectBuilder, field string) Filter {
|
||||
return func(sb *sqlbuilder.SelectBuilder, value []string) error {
|
||||
values := make([]interface{}, len(value))
|
||||
for i, v := range value {
|
||||
values[i] = v
|
||||
}
|
||||
subquery := subqueryFactory()
|
||||
subquery.Where(subquery.In(field, values...))
|
||||
sb.Where(sb.Exists(subquery))
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func InFilter(field string) Filter {
|
||||
return func(sb *sqlbuilder.SelectBuilder, value []string) error {
|
||||
if len(value) == 0 {
|
||||
return nil
|
||||
}
|
||||
values := make([]interface{}, len(value))
|
||||
for i, v := range value {
|
||||
values[i] = v
|
||||
}
|
||||
sb.Where(sb.In(field, values...))
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func SortAscFilter(columns []string) Filter {
|
||||
return func(sb *sqlbuilder.SelectBuilder, value []string) error {
|
||||
column, err := isValidSortColumn(value[0], columns)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sb.OrderByAsc(column)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func SortDescFilter(columns []string) Filter {
|
||||
return func(sb *sqlbuilder.SelectBuilder, value []string) error {
|
||||
column, err := isValidSortColumn(value[0], columns)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sb.OrderByDesc(column)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func ReplacedSortAscFilter(replace map[string]string, columns []string) Filter {
|
||||
return func(sb *sqlbuilder.SelectBuilder, value []string) error {
|
||||
column, ok := replace[value[0]]
|
||||
if !ok {
|
||||
column = value[0]
|
||||
}
|
||||
column, err := isValidSortColumn(column, columns)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sb.OrderByAsc(column)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func ReplacedSortDescFilter(replace map[string]string, columns []string) Filter {
|
||||
return func(sb *sqlbuilder.SelectBuilder, value []string) error {
|
||||
column, ok := replace[value[0]]
|
||||
if !ok {
|
||||
column = value[0]
|
||||
}
|
||||
column, err := isValidSortColumn(column, columns)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sb.OrderByDesc(column)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func LimitFilter() Filter {
|
||||
return func(sb *sqlbuilder.SelectBuilder, value []string) error {
|
||||
limit, err := strconv.Atoi(value[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sb.Limit(limit)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func OffsetFilter() Filter {
|
||||
return func(sb *sqlbuilder.SelectBuilder, value []string) error {
|
||||
offset, err := strconv.Atoi(value[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sb.Offset(offset)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func isValidSortColumn(column string, columns []string) (string, error) {
|
||||
if slices.Contains(columns, column) {
|
||||
return column, nil
|
||||
}
|
||||
return "", E.New("invalid sort column \"", column, "\"")
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
package postgresql
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type stringSliceJSON []string
|
||||
|
||||
func (s *stringSliceJSON) Scan(src interface{}) error {
|
||||
if src == nil {
|
||||
*s = nil
|
||||
return nil
|
||||
}
|
||||
var data []byte
|
||||
switch v := src.(type) {
|
||||
case []byte:
|
||||
data = v
|
||||
case string:
|
||||
data = []byte(v)
|
||||
default:
|
||||
return fmt.Errorf("stringSliceJSON.Scan: unsupported type %T", src)
|
||||
}
|
||||
if len(data) == 0 {
|
||||
*s = nil
|
||||
return nil
|
||||
}
|
||||
return json.Unmarshal(data, (*[]string)(s))
|
||||
}
|
||||
|
||||
func marshalStringSlice(values []string) ([]byte, error) {
|
||||
if values == nil {
|
||||
values = []string{}
|
||||
}
|
||||
return json.Marshal(values)
|
||||
}
|
||||
@@ -1,195 +0,0 @@
|
||||
package sqlite
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"slices"
|
||||
"strconv"
|
||||
|
||||
"github.com/huandu/go-sqlbuilder"
|
||||
"github.com/sagernet/sing/common/byteformats"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
)
|
||||
|
||||
type Filter func(sb *sqlbuilder.SelectBuilder, value []string) error
|
||||
|
||||
func EqualFilter(field string) Filter {
|
||||
return func(sb *sqlbuilder.SelectBuilder, value []string) error {
|
||||
sb.Where(sb.Equal(field, value[0]))
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func EqualOrNullFilter(field string) Filter {
|
||||
return func(sb *sqlbuilder.SelectBuilder, value []string) error {
|
||||
sb.Where(sb.Or(sb.Equal(field, value[0]), sb.IsNull(field)))
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func GreaterThanFilter(field string) Filter {
|
||||
return func(sb *sqlbuilder.SelectBuilder, value []string) error {
|
||||
sb.Where(sb.GreaterThan(field, value[0]))
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func LessThanFilter(field string) Filter {
|
||||
return func(sb *sqlbuilder.SelectBuilder, value []string) error {
|
||||
sb.Where(sb.LessThan(field, value[0]))
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func GreaterEqualThanFilter(field string) Filter {
|
||||
return func(sb *sqlbuilder.SelectBuilder, value []string) error {
|
||||
sb.Where(sb.GreaterEqualThan(field, value[0]))
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func LessEqualThanFilter(field string) Filter {
|
||||
return func(sb *sqlbuilder.SelectBuilder, value []string) error {
|
||||
sb.Where(sb.LessEqualThan(field, value[0]))
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func SpeedGreaterEqualThanFilter(field string) Filter {
|
||||
return func(sb *sqlbuilder.SelectBuilder, value []string) error {
|
||||
bytesSpeed, err := json.Marshal(value[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
speed := &byteformats.NetworkBytesCompat{}
|
||||
err = speed.UnmarshalJSON(bytesSpeed)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sb.Where(sb.GreaterEqualThan(field, speed.Value()))
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func SpeedLessEqualThanFilter(field string) Filter {
|
||||
return func(sb *sqlbuilder.SelectBuilder, value []string) error {
|
||||
bytesSpeed, err := json.Marshal(value[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
speed := &byteformats.NetworkBytesCompat{}
|
||||
err = speed.UnmarshalJSON(bytesSpeed)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sb.Where(sb.LessEqualThan(field, speed.Value()))
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func ExistsAndWhereInFilter(subqueryFactory func() *sqlbuilder.SelectBuilder, field string) Filter {
|
||||
return func(sb *sqlbuilder.SelectBuilder, value []string) error {
|
||||
values := make([]interface{}, len(value))
|
||||
for i, v := range value {
|
||||
values[i] = v
|
||||
}
|
||||
subquery := subqueryFactory()
|
||||
subquery.Where(subquery.In(field, values...))
|
||||
sb.Where(sb.Exists(subquery))
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func InFilter(field string) Filter {
|
||||
return func(sb *sqlbuilder.SelectBuilder, value []string) error {
|
||||
if len(value) == 0 {
|
||||
return nil
|
||||
}
|
||||
values := make([]interface{}, len(value))
|
||||
for i, v := range value {
|
||||
values[i] = v
|
||||
}
|
||||
sb.Where(sb.In(field, values...))
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func SortAscFilter(columns []string) Filter {
|
||||
return func(sb *sqlbuilder.SelectBuilder, value []string) error {
|
||||
column, err := isValidSortColumn(value[0], columns)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sb.OrderByAsc(column)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func SortDescFilter(columns []string) Filter {
|
||||
return func(sb *sqlbuilder.SelectBuilder, value []string) error {
|
||||
column, err := isValidSortColumn(value[0], columns)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sb.OrderByDesc(column)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func ReplacedSortAscFilter(replace map[string]string, columns []string) Filter {
|
||||
return func(sb *sqlbuilder.SelectBuilder, value []string) error {
|
||||
column, ok := replace[value[0]]
|
||||
if !ok {
|
||||
column = value[0]
|
||||
}
|
||||
column, err := isValidSortColumn(column, columns)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sb.OrderByAsc(column)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func ReplacedSortDescFilter(replace map[string]string, columns []string) Filter {
|
||||
return func(sb *sqlbuilder.SelectBuilder, value []string) error {
|
||||
column, ok := replace[value[0]]
|
||||
if !ok {
|
||||
column = value[0]
|
||||
}
|
||||
column, err := isValidSortColumn(column, columns)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sb.OrderByDesc(column)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func LimitFilter() Filter {
|
||||
return func(sb *sqlbuilder.SelectBuilder, value []string) error {
|
||||
limit, err := strconv.Atoi(value[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sb.Limit(limit)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func OffsetFilter() Filter {
|
||||
return func(sb *sqlbuilder.SelectBuilder, value []string) error {
|
||||
offset, err := strconv.Atoi(value[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sb.Offset(offset)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func isValidSortColumn(column string, columns []string) (string, error) {
|
||||
if slices.Contains(columns, column) {
|
||||
return column, nil
|
||||
}
|
||||
return "", E.New("invalid sort column \"", column, "\"")
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
package sqlite
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type intSliceJSON []int
|
||||
|
||||
func (s *intSliceJSON) Scan(src interface{}) error {
|
||||
if src == nil {
|
||||
*s = nil
|
||||
return nil
|
||||
}
|
||||
var data []byte
|
||||
switch v := src.(type) {
|
||||
case []byte:
|
||||
data = v
|
||||
case string:
|
||||
data = []byte(v)
|
||||
default:
|
||||
return fmt.Errorf("intSliceJSON.Scan: unsupported type %T", src)
|
||||
}
|
||||
if len(data) == 0 {
|
||||
*s = nil
|
||||
return nil
|
||||
}
|
||||
return json.Unmarshal(data, (*[]int)(s))
|
||||
}
|
||||
|
||||
type stringSliceJSON []string
|
||||
|
||||
func (s *stringSliceJSON) Scan(src interface{}) error {
|
||||
if src == nil {
|
||||
*s = nil
|
||||
return nil
|
||||
}
|
||||
var data []byte
|
||||
switch v := src.(type) {
|
||||
case []byte:
|
||||
data = v
|
||||
case string:
|
||||
data = []byte(v)
|
||||
default:
|
||||
return fmt.Errorf("stringSliceJSON.Scan: unsupported type %T", src)
|
||||
}
|
||||
if len(data) == 0 {
|
||||
*s = nil
|
||||
return nil
|
||||
}
|
||||
return json.Unmarshal(data, (*[]string)(s))
|
||||
}
|
||||
|
||||
func marshalStringSlice(values []string) (string, error) {
|
||||
if values == nil {
|
||||
values = []string{}
|
||||
}
|
||||
data, err := json.Marshal(values)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(data), nil
|
||||
}
|
||||
Reference in New Issue
Block a user