162 lines
4.5 KiB
Go
162 lines
4.5 KiB
Go
package repository
|
|
|
|
import (
|
|
"context"
|
|
"sub2api/internal/model"
|
|
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type ProxyRepository struct {
|
|
db *gorm.DB
|
|
}
|
|
|
|
func NewProxyRepository(db *gorm.DB) *ProxyRepository {
|
|
return &ProxyRepository{db: db}
|
|
}
|
|
|
|
func (r *ProxyRepository) Create(ctx context.Context, proxy *model.Proxy) error {
|
|
return r.db.WithContext(ctx).Create(proxy).Error
|
|
}
|
|
|
|
func (r *ProxyRepository) GetByID(ctx context.Context, id int64) (*model.Proxy, error) {
|
|
var proxy model.Proxy
|
|
err := r.db.WithContext(ctx).First(&proxy, id).Error
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &proxy, nil
|
|
}
|
|
|
|
func (r *ProxyRepository) Update(ctx context.Context, proxy *model.Proxy) error {
|
|
return r.db.WithContext(ctx).Save(proxy).Error
|
|
}
|
|
|
|
func (r *ProxyRepository) Delete(ctx context.Context, id int64) error {
|
|
return r.db.WithContext(ctx).Delete(&model.Proxy{}, id).Error
|
|
}
|
|
|
|
func (r *ProxyRepository) List(ctx context.Context, params PaginationParams) ([]model.Proxy, *PaginationResult, error) {
|
|
return r.ListWithFilters(ctx, params, "", "", "")
|
|
}
|
|
|
|
// ListWithFilters lists proxies with optional filtering by protocol, status, and search query
|
|
func (r *ProxyRepository) ListWithFilters(ctx context.Context, params PaginationParams, protocol, status, search string) ([]model.Proxy, *PaginationResult, error) {
|
|
var proxies []model.Proxy
|
|
var total int64
|
|
|
|
db := r.db.WithContext(ctx).Model(&model.Proxy{})
|
|
|
|
// Apply filters
|
|
if protocol != "" {
|
|
db = db.Where("protocol = ?", protocol)
|
|
}
|
|
if status != "" {
|
|
db = db.Where("status = ?", status)
|
|
}
|
|
if search != "" {
|
|
searchPattern := "%" + search + "%"
|
|
db = db.Where("name ILIKE ?", searchPattern)
|
|
}
|
|
|
|
if err := db.Count(&total).Error; err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
if err := db.Offset(params.Offset()).Limit(params.Limit()).Order("id DESC").Find(&proxies).Error; err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
pages := int(total) / params.Limit()
|
|
if int(total)%params.Limit() > 0 {
|
|
pages++
|
|
}
|
|
|
|
return proxies, &PaginationResult{
|
|
Total: total,
|
|
Page: params.Page,
|
|
PageSize: params.Limit(),
|
|
Pages: pages,
|
|
}, nil
|
|
}
|
|
|
|
func (r *ProxyRepository) ListActive(ctx context.Context) ([]model.Proxy, error) {
|
|
var proxies []model.Proxy
|
|
err := r.db.WithContext(ctx).Where("status = ?", model.StatusActive).Find(&proxies).Error
|
|
return proxies, err
|
|
}
|
|
|
|
// ExistsByHostPortAuth checks if a proxy with the same host, port, username, and password exists
|
|
func (r *ProxyRepository) ExistsByHostPortAuth(ctx context.Context, host string, port int, username, password string) (bool, error) {
|
|
var count int64
|
|
err := r.db.WithContext(ctx).Model(&model.Proxy{}).
|
|
Where("host = ? AND port = ? AND username = ? AND password = ?", host, port, username, password).
|
|
Count(&count).Error
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
return count > 0, nil
|
|
}
|
|
|
|
// CountAccountsByProxyID returns the number of accounts using a specific proxy
|
|
func (r *ProxyRepository) CountAccountsByProxyID(ctx context.Context, proxyID int64) (int64, error) {
|
|
var count int64
|
|
err := r.db.WithContext(ctx).Model(&model.Account{}).
|
|
Where("proxy_id = ?", proxyID).
|
|
Count(&count).Error
|
|
return count, err
|
|
}
|
|
|
|
// GetAccountCountsForProxies returns a map of proxy ID to account count for all proxies
|
|
func (r *ProxyRepository) GetAccountCountsForProxies(ctx context.Context) (map[int64]int64, error) {
|
|
type result struct {
|
|
ProxyID int64 `gorm:"column:proxy_id"`
|
|
Count int64 `gorm:"column:count"`
|
|
}
|
|
var results []result
|
|
err := r.db.WithContext(ctx).
|
|
Model(&model.Account{}).
|
|
Select("proxy_id, COUNT(*) as count").
|
|
Where("proxy_id IS NOT NULL").
|
|
Group("proxy_id").
|
|
Scan(&results).Error
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
counts := make(map[int64]int64)
|
|
for _, r := range results {
|
|
counts[r.ProxyID] = r.Count
|
|
}
|
|
return counts, nil
|
|
}
|
|
|
|
// ListActiveWithAccountCount returns all active proxies with account count, sorted by creation time descending
|
|
func (r *ProxyRepository) ListActiveWithAccountCount(ctx context.Context) ([]model.ProxyWithAccountCount, error) {
|
|
var proxies []model.Proxy
|
|
err := r.db.WithContext(ctx).
|
|
Where("status = ?", model.StatusActive).
|
|
Order("created_at DESC").
|
|
Find(&proxies).Error
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Get account counts
|
|
counts, err := r.GetAccountCountsForProxies(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Build result with account counts
|
|
result := make([]model.ProxyWithAccountCount, len(proxies))
|
|
for i, proxy := range proxies {
|
|
result[i] = model.ProxyWithAccountCount{
|
|
Proxy: proxy,
|
|
AccountCount: counts[proxy.ID],
|
|
}
|
|
}
|
|
|
|
return result, nil
|
|
}
|