Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
陈曦
sub2api
Commits
0170d19f
Commit
0170d19f
authored
Feb 02, 2026
by
song
Browse files
merge upstream main
parent
7ade9baa
Changes
319
Expand all
Show whitespace changes
Inline
Side-by-side
.github/workflows/backend-ci.yml
View file @
0170d19f
...
...
@@ -19,7 +19,7 @@ jobs:
cache
:
true
-
name
:
Verify Go version
run
:
|
go version | grep -q 'go1.25.
5
'
go version | grep -q 'go1.25.
6
'
-
name
:
Unit tests
working-directory
:
backend
run
:
make test-unit
...
...
@@ -38,7 +38,7 @@ jobs:
cache
:
true
-
name
:
Verify Go version
run
:
|
go version | grep -q 'go1.25.
5
'
go version | grep -q 'go1.25.
6
'
-
name
:
golangci-lint
uses
:
golangci/golangci-lint-action@v9
with
:
...
...
.github/workflows/release.yml
View file @
0170d19f
...
...
@@ -115,7 +115,7 @@ jobs:
-
name
:
Verify Go version
run
:
|
go version | grep -q 'go1.25.
5
'
go version | grep -q 'go1.25.
6
'
# Docker setup for GoReleaser
-
name
:
Set up QEMU
...
...
@@ -222,8 +222,9 @@ jobs:
REPO="${{ github.repository }}"
GHCR_IMAGE="ghcr.io/${REPO,,}" # ${,,} converts to lowercase
# 获取 tag message 内容
# 获取 tag message 内容
并转义 Markdown 特殊字符
TAG_MESSAGE='${{ steps.tag_message.outputs.message }}'
TAG_MESSAGE=$(echo "$TAG_MESSAGE" | sed 's/\([_*`\[]\)/\\\1/g')
# 限制消息长度(Telegram 消息限制 4096 字符,预留空间给头尾固定内容)
if [ ${#TAG_MESSAGE} -gt 3500 ]; then
...
...
.github/workflows/security-scan.yml
View file @
0170d19f
...
...
@@ -22,7 +22,7 @@ jobs:
cache-dependency-path
:
backend/go.sum
-
name
:
Verify Go version
run
:
|
go version | grep -q 'go1.25.
5
'
go version | grep -q 'go1.25.
6
'
-
name
:
Run govulncheck
working-directory
:
backend
run
:
|
...
...
Dockerfile
View file @
0170d19f
...
...
@@ -7,7 +7,7 @@
# =============================================================================
ARG
NODE_IMAGE=node:24-alpine
ARG
GOLANG_IMAGE=golang:1.25.
5
-alpine
ARG
GOLANG_IMAGE=golang:1.25.
6
-alpine
ARG
ALPINE_IMAGE=alpine:3.20
ARG
GOPROXY=https://goproxy.cn,direct
ARG
GOSUMDB=sum.golang.google.cn
...
...
README.md
View file @
0170d19f
...
...
@@ -18,7 +18,7 @@ English | [中文](README_CN.md)
## Demo
Try Sub2API online:
**https://
v2.pincc.ai
/**
Try Sub2API online:
**https://
demo.sub2api.org
/**
Demo credentials (shared demo environment;
**not**
created automatically for self-hosted installs):
...
...
@@ -128,7 +128,7 @@ curl -sSL https://raw.githubusercontent.com/Wei-Shaw/sub2api/main/deploy/install
---
### Method 2: Docker Compose
### Method 2: Docker Compose
(Recommended)
Deploy with Docker Compose, including PostgreSQL and Redis containers.
...
...
@@ -137,87 +137,157 @@ Deploy with Docker Compose, including PostgreSQL and Redis containers.
-
Docker 20.10+
-
Docker Compose v2+
#### Installation Steps
#### Quick Start (One-Click Deployment)
Use the automated deployment script for easy setup:
```
bash
# Create deployment directory
mkdir
-p
sub2api-deploy
&&
cd
sub2api-deploy
# Download and run deployment preparation script
curl
-sSL
https://raw.githubusercontent.com/Wei-Shaw/sub2api/main/deploy/docker-deploy.sh | bash
# Start services
docker-compose
-f
docker-compose.local.yml up
-d
# View logs
docker-compose
-f
docker-compose.local.yml logs
-f
sub2api
```
**What the script does:**
-
Downloads
`docker-compose.local.yml`
and
`.env.example`
-
Generates secure credentials (JWT_SECRET, TOTP_ENCRYPTION_KEY, POSTGRES_PASSWORD)
-
Creates
`.env`
file with auto-generated secrets
-
Creates data directories (uses local directories for easy backup/migration)
-
Displays generated credentials for your reference
#### Manual Deployment
If you prefer manual setup:
```
bash
# 1. Clone the repository
git clone https://github.com/Wei-Shaw/sub2api.git
cd
sub2api
# 2. Enter the deploy directory
cd
deploy
cd
sub2api/deploy
#
3
. Copy environment configuration
#
2
. Copy environment configuration
cp
.env.example .env
#
4
. Edit configuration (
set yo
ur passwords)
#
3
. Edit configuration (
generate sec
ur
e
passwords)
nano .env
```
**Required configuration in `.env`:**
```
bash
# PostgreSQL password (REQUIRED
- change this!
)
# PostgreSQL password (REQUIRED)
POSTGRES_PASSWORD
=
your_secure_password_here
# JWT Secret (RECOMMENDED - keeps users logged in after restart)
JWT_SECRET
=
your_jwt_secret_here
# TOTP Encryption Key (RECOMMENDED - preserves 2FA after restart)
TOTP_ENCRYPTION_KEY
=
your_totp_key_here
# Optional: Admin account
ADMIN_EMAIL
=
admin@example.com
ADMIN_PASSWORD
=
your_admin_password
# Optional: Custom port
SERVER_PORT
=
8080
```
# Optional: Security configuration
# Enable URL allowlist validation (false to skip allowlist checks, only basic format validation)
SECURITY_URL_ALLOWLIST_ENABLED
=
false
**Generate secure secrets:**
```
bash
# Generate JWT_SECRET
openssl rand
-hex
32
# Generate TOTP_ENCRYPTION_KEY
openssl rand
-hex
32
# Allow insecure HTTP URLs when allowlist is disabled (default: false, requires https)
# ⚠️ WARNING: Enabling this allows HTTP (plaintext) URLs which can expose API keys
# Only recommended for:
# - Development/testing environments
# - Internal networks with trusted endpoints
# - When using local test servers (http://localhost)
# PRODUCTION: Keep this false or use HTTPS URLs only
SECURITY_URL_ALLOWLIST_ALLOW_INSECURE_HTTP
=
false
# Allow private IP addresses for upstream/pricing/CRS (for internal deployments)
SECURITY_URL_ALLOWLIST_ALLOW_PRIVATE_HOSTS
=
false
# Generate POSTGRES_PASSWORD
openssl rand
-hex
32
```
```
bash
# 4. Create data directories (for local version)
mkdir
-p
data postgres_data redis_data
# 5. Start all services
# Option A: Local directory version (recommended - easy migration)
docker-compose
-f
docker-compose.local.yml up
-d
# Option B: Named volumes version (simple setup)
docker-compose up
-d
# 6. Check status
docker-compose ps
docker-compose
-f
docker-compose.local.yml
ps
# 7. View logs
docker-compose logs
-f
sub2api
docker-compose
-f
docker-compose.local.yml
logs
-f
sub2api
```
#### Deployment Versions
| Version | Data Storage | Migration | Best For |
|---------|-------------|-----------|----------|
|
**docker-compose.local.yml**
| Local directories | ✅ Easy (tar entire directory) | Production, frequent backups |
|
**docker-compose.yml**
| Named volumes | ⚠️ Requires docker commands | Simple setup |
**Recommendation:**
Use
`docker-compose.local.yml`
(deployed by script) for easier data management.
#### Access
Open
`http://YOUR_SERVER_IP:8080`
in your browser.
If admin password was auto-generated, find it in logs:
```
bash
docker-compose
-f
docker-compose.local.yml logs sub2api |
grep
"admin password"
```
#### Upgrade
```
bash
# Pull latest image and recreate container
docker-compose pull
docker-compose up
-d
docker-compose
-f
docker-compose.local.yml pull
docker-compose
-f
docker-compose.local.yml up
-d
```
#### Easy Migration (Local Directory Version)
When using
`docker-compose.local.yml`
, migrate to a new server easily:
```
bash
# On source server
docker-compose
-f
docker-compose.local.yml down
cd
..
tar
czf sub2api-complete.tar.gz sub2api-deploy/
# Transfer to new server
scp sub2api-complete.tar.gz user@new-server:/path/
# On new server
tar
xzf sub2api-complete.tar.gz
cd
sub2api-deploy/
docker-compose
-f
docker-compose.local.yml up
-d
```
#### Useful Commands
```
bash
# Stop all services
docker-compose down
docker-compose
-f
docker-compose.local.yml
down
# Restart
docker-compose restart
docker-compose
-f
docker-compose.local.yml
restart
# View all logs
docker-compose logs
-f
docker-compose
-f
docker-compose.local.yml logs
-f
# Remove all data (caution!)
docker-compose
-f
docker-compose.local.yml down
rm
-rf
data/ postgres_data/ redis_data/
```
---
...
...
README_CN.md
View file @
0170d19f
...
...
@@ -135,7 +135,7 @@ curl -sSL https://raw.githubusercontent.com/Wei-Shaw/sub2api/main/deploy/install
---
### 方式二:Docker Compose
### 方式二:Docker Compose
(推荐)
使用 Docker Compose 部署,包含 PostgreSQL 和 Redis 容器。
...
...
@@ -144,87 +144,157 @@ curl -sSL https://raw.githubusercontent.com/Wei-Shaw/sub2api/main/deploy/install
-
Docker 20.10+
-
Docker Compose v2+
#### 安装步骤
#### 快速开始(一键部署)
使用自动化部署脚本快速搭建:
```
bash
# 创建部署目录
mkdir
-p
sub2api-deploy
&&
cd
sub2api-deploy
# 下载并运行部署准备脚本
curl
-sSL
https://raw.githubusercontent.com/Wei-Shaw/sub2api/main/deploy/docker-deploy.sh | bash
# 启动服务
docker-compose
-f
docker-compose.local.yml up
-d
# 查看日志
docker-compose
-f
docker-compose.local.yml logs
-f
sub2api
```
**脚本功能:**
-
下载
`docker-compose.local.yml`
和
`.env.example`
-
自动生成安全凭证(JWT_SECRET、TOTP_ENCRYPTION_KEY、POSTGRES_PASSWORD)
-
创建
`.env`
文件并填充自动生成的密钥
-
创建数据目录(使用本地目录,便于备份和迁移)
-
显示生成的凭证供你记录
#### 手动部署
如果你希望手动配置:
```
bash
# 1. 克隆仓库
git clone https://github.com/Wei-Shaw/sub2api.git
cd
sub2api
# 2. 进入 deploy 目录
cd
deploy
cd
sub2api/deploy
#
3
. 复制环境配置文件
#
2
. 复制环境配置文件
cp
.env.example .env
#
4
. 编辑配置(
设置
密码
等
)
#
3
. 编辑配置(
生成安全
密码)
nano .env
```
**`.env` 必须配置项:**
```
bash
# PostgreSQL 密码(必
须修改!
)
# PostgreSQL 密码(必
需
)
POSTGRES_PASSWORD
=
your_secure_password_here
# JWT 密钥(推荐 - 重启后保持用户登录状态)
JWT_SECRET
=
your_jwt_secret_here
# TOTP 加密密钥(推荐 - 重启后保留双因素认证)
TOTP_ENCRYPTION_KEY
=
your_totp_key_here
# 可选:管理员账号
ADMIN_EMAIL
=
admin@example.com
ADMIN_PASSWORD
=
your_admin_password
# 可选:自定义端口
SERVER_PORT
=
8080
```
# 可选:安全配置
# 启用 URL 白名单验证(false 则跳过白名单检查,仅做基本格式校验)
SECURITY_URL_ALLOWLIST_ENABLED
=
false
**生成安全密钥:**
```
bash
# 生成 JWT_SECRET
openssl rand
-hex
32
# 生成 TOTP_ENCRYPTION_KEY
openssl rand
-hex
32
# 关闭白名单时,是否允许 http:// URL(默认 false,只允许 https://)
# ⚠️ 警告:允许 HTTP 会暴露 API 密钥(明文传输)
# 仅建议在以下场景使用:
# - 开发/测试环境
# - 内部可信网络
# - 本地测试服务器(http://localhost)
# 生产环境:保持 false 或仅使用 HTTPS URL
SECURITY_URL_ALLOWLIST_ALLOW_INSECURE_HTTP
=
false
# 是否允许私有 IP 地址用于上游/定价/CRS(内网部署时使用)
SECURITY_URL_ALLOWLIST_ALLOW_PRIVATE_HOSTS
=
false
# 生成 POSTGRES_PASSWORD
openssl rand
-hex
32
```
```
bash
# 4. 创建数据目录(本地版)
mkdir
-p
data postgres_data redis_data
# 5. 启动所有服务
# 选项 A:本地目录版(推荐 - 易于迁移)
docker-compose
-f
docker-compose.local.yml up
-d
# 选项 B:命名卷版(简单设置)
docker-compose up
-d
# 6. 查看状态
docker-compose ps
docker-compose
-f
docker-compose.local.yml
ps
# 7. 查看日志
docker-compose logs
-f
sub2api
docker-compose
-f
docker-compose.local.yml
logs
-f
sub2api
```
#### 部署版本对比
| 版本 | 数据存储 | 迁移便利性 | 适用场景 |
|------|---------|-----------|---------|
|
**docker-compose.local.yml**
| 本地目录 | ✅ 简单(打包整个目录) | 生产环境、频繁备份 |
|
**docker-compose.yml**
| 命名卷 | ⚠️ 需要 docker 命令 | 简单设置 |
**推荐:**
使用
`docker-compose.local.yml`
(脚本部署)以便更轻松地管理数据。
#### 访问
在浏览器中打开
`http://你的服务器IP:8080`
如果管理员密码是自动生成的,在日志中查找:
```
bash
docker-compose
-f
docker-compose.local.yml logs sub2api |
grep
"admin password"
```
#### 升级
```
bash
# 拉取最新镜像并重建容器
docker-compose pull
docker-compose up
-d
docker-compose
-f
docker-compose.local.yml pull
docker-compose
-f
docker-compose.local.yml up
-d
```
#### 轻松迁移(本地目录版)
使用
`docker-compose.local.yml`
时,可以轻松迁移到新服务器:
```
bash
# 源服务器
docker-compose
-f
docker-compose.local.yml down
cd
..
tar
czf sub2api-complete.tar.gz sub2api-deploy/
# 传输到新服务器
scp sub2api-complete.tar.gz user@new-server:/path/
# 新服务器
tar
xzf sub2api-complete.tar.gz
cd
sub2api-deploy/
docker-compose
-f
docker-compose.local.yml up
-d
```
#### 常用命令
```
bash
# 停止所有服务
docker-compose down
docker-compose
-f
docker-compose.local.yml
down
# 重启
docker-compose restart
docker-compose
-f
docker-compose.local.yml
restart
# 查看所有日志
docker-compose logs
-f
docker-compose
-f
docker-compose.local.yml logs
-f
# 删除所有数据(谨慎!)
docker-compose
-f
docker-compose.local.yml down
rm
-rf
data/ postgres_data/ redis_data/
```
---
...
...
backend/cmd/server/VERSION
View file @
0170d19f
0.1.
4
6
0.1.6
1
backend/cmd/server/main.go
View file @
0170d19f
...
...
@@ -8,6 +8,7 @@ import (
"errors"
"flag"
"log"
"log/slog"
"net/http"
"os"
"os/signal"
...
...
@@ -44,7 +45,25 @@ func init() {
}
}
// initLogger configures the default slog handler based on gin.Mode().
// In non-release mode, Debug level logs are enabled.
func
initLogger
()
{
var
level
slog
.
Level
if
gin
.
Mode
()
==
gin
.
ReleaseMode
{
level
=
slog
.
LevelInfo
}
else
{
level
=
slog
.
LevelDebug
}
handler
:=
slog
.
NewTextHandler
(
os
.
Stderr
,
&
slog
.
HandlerOptions
{
Level
:
level
,
})
slog
.
SetDefault
(
slog
.
New
(
handler
))
}
func
main
()
{
// Initialize slog logger based on gin mode
initLogger
()
// Parse command line flags
setupMode
:=
flag
.
Bool
(
"setup"
,
false
,
"Run setup wizard in CLI mode"
)
showVersion
:=
flag
.
Bool
(
"version"
,
false
,
"Show version information"
)
...
...
backend/cmd/server/wire.go
View file @
0170d19f
...
...
@@ -70,6 +70,8 @@ func provideCleanup(
schedulerSnapshot
*
service
.
SchedulerSnapshotService
,
tokenRefresh
*
service
.
TokenRefreshService
,
accountExpiry
*
service
.
AccountExpiryService
,
subscriptionExpiry
*
service
.
SubscriptionExpiryService
,
usageCleanup
*
service
.
UsageCleanupService
,
pricing
*
service
.
PricingService
,
emailQueue
*
service
.
EmailQueueService
,
billingCache
*
service
.
BillingCacheService
,
...
...
@@ -123,6 +125,12 @@ func provideCleanup(
}
return
nil
}},
{
"UsageCleanupService"
,
func
()
error
{
if
usageCleanup
!=
nil
{
usageCleanup
.
Stop
()
}
return
nil
}},
{
"TokenRefreshService"
,
func
()
error
{
tokenRefresh
.
Stop
()
return
nil
...
...
@@ -131,6 +139,10 @@ func provideCleanup(
accountExpiry
.
Stop
()
return
nil
}},
{
"SubscriptionExpiryService"
,
func
()
error
{
subscriptionExpiry
.
Stop
()
return
nil
}},
{
"PricingService"
,
func
()
error
{
pricing
.
Stop
()
return
nil
...
...
backend/cmd/server/wire_gen.go
View file @
0170d19f
...
...
@@ -63,7 +63,13 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) {
promoService
:=
service
.
NewPromoService
(
promoCodeRepository
,
userRepository
,
billingCacheService
,
client
,
apiKeyAuthCacheInvalidator
)
authService
:=
service
.
NewAuthService
(
userRepository
,
configConfig
,
settingService
,
emailService
,
turnstileService
,
emailQueueService
,
promoService
)
userService
:=
service
.
NewUserService
(
userRepository
,
apiKeyAuthCacheInvalidator
)
authHandler
:=
handler
.
NewAuthHandler
(
configConfig
,
authService
,
userService
,
settingService
,
promoService
)
secretEncryptor
,
err
:=
repository
.
NewAESEncryptor
(
configConfig
)
if
err
!=
nil
{
return
nil
,
err
}
totpCache
:=
repository
.
NewTotpCache
(
redisClient
)
totpService
:=
service
.
NewTotpService
(
userRepository
,
secretEncryptor
,
totpCache
,
settingService
,
emailService
,
emailQueueService
)
authHandler
:=
handler
.
NewAuthHandler
(
configConfig
,
authService
,
userService
,
settingService
,
promoService
,
totpService
)
userHandler
:=
handler
.
NewUserHandler
(
userService
)
apiKeyHandler
:=
handler
.
NewAPIKeyHandler
(
apiKeyService
)
usageLogRepository
:=
repository
.
NewUsageLogRepository
(
client
,
db
)
...
...
@@ -75,6 +81,10 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) {
redeemService
:=
service
.
NewRedeemService
(
redeemCodeRepository
,
userRepository
,
subscriptionService
,
redeemCache
,
billingCacheService
,
client
,
apiKeyAuthCacheInvalidator
)
redeemHandler
:=
handler
.
NewRedeemHandler
(
redeemService
)
subscriptionHandler
:=
handler
.
NewSubscriptionHandler
(
subscriptionService
)
announcementRepository
:=
repository
.
NewAnnouncementRepository
(
client
)
announcementReadRepository
:=
repository
.
NewAnnouncementReadRepository
(
client
)
announcementService
:=
service
.
NewAnnouncementService
(
announcementRepository
,
announcementReadRepository
,
userRepository
,
userSubscriptionRepository
)
announcementHandler
:=
handler
.
NewAnnouncementHandler
(
announcementService
)
dashboardAggregationRepository
:=
repository
.
NewDashboardAggregationRepository
(
db
)
dashboardStatsCache
:=
repository
.
NewDashboardCache
(
redisClient
,
configConfig
)
dashboardService
:=
service
.
NewDashboardService
(
usageLogRepository
,
dashboardAggregationRepository
,
dashboardStatsCache
,
configConfig
)
...
...
@@ -84,7 +94,8 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) {
}
dashboardAggregationService
:=
service
.
ProvideDashboardAggregationService
(
dashboardAggregationRepository
,
timingWheelService
,
configConfig
)
dashboardHandler
:=
admin
.
NewDashboardHandler
(
dashboardService
,
dashboardAggregationService
)
accountRepository
:=
repository
.
NewAccountRepository
(
client
,
db
)
schedulerCache
:=
repository
.
NewSchedulerCache
(
redisClient
)
accountRepository
:=
repository
.
NewAccountRepository
(
client
,
db
,
schedulerCache
)
proxyRepository
:=
repository
.
NewProxyRepository
(
client
,
db
)
proxyExitInfoProber
:=
repository
.
NewProxyExitInfoProber
(
configConfig
)
proxyLatencyCache
:=
repository
.
NewProxyLatencyCache
(
redisClient
)
...
...
@@ -105,21 +116,23 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) {
geminiTokenCache
:=
repository
.
NewGeminiTokenCache
(
redisClient
)
compositeTokenCacheInvalidator
:=
service
.
NewCompositeTokenCacheInvalidator
(
geminiTokenCache
)
rateLimitService
:=
service
.
ProvideRateLimitService
(
accountRepository
,
usageLogRepository
,
configConfig
,
geminiQuotaService
,
tempUnschedCache
,
timeoutCounterCache
,
settingService
,
compositeTokenCacheInvalidator
)
claudeUsageFetcher
:=
repository
.
NewClaudeUsageFetcher
()
httpUpstream
:=
repository
.
NewHTTPUpstream
(
configConfig
)
claudeUsageFetcher
:=
repository
.
NewClaudeUsageFetcher
(
httpUpstream
)
antigravityQuotaFetcher
:=
service
.
NewAntigravityQuotaFetcher
(
proxyRepository
)
usageCache
:=
service
.
NewUsageCache
()
accountUsageService
:=
service
.
NewAccountUsageService
(
accountRepository
,
usageLogRepository
,
claudeUsageFetcher
,
geminiQuotaService
,
antigravityQuotaFetcher
,
usageCache
)
identityCache
:=
repository
.
NewIdentityCache
(
redisClient
)
accountUsageService
:=
service
.
NewAccountUsageService
(
accountRepository
,
usageLogRepository
,
claudeUsageFetcher
,
geminiQuotaService
,
antigravityQuotaFetcher
,
usageCache
,
identityCache
)
geminiTokenProvider
:=
service
.
NewGeminiTokenProvider
(
accountRepository
,
geminiTokenCache
,
geminiOAuthService
)
gatewayCache
:=
repository
.
NewGatewayCache
(
redisClient
)
antigravityTokenProvider
:=
service
.
NewAntigravityTokenProvider
(
accountRepository
,
geminiTokenCache
,
antigravityOAuthService
)
httpUpstream
:=
repository
.
NewHTTPUpstream
(
configConfig
)
antigravityGatewayService
:=
service
.
NewAntigravityGatewayService
(
accountRepository
,
gatewayCache
,
antigravityTokenProvider
,
rateLimitService
,
httpUpstream
,
settingService
)
accountTestService
:=
service
.
NewAccountTestService
(
accountRepository
,
geminiTokenProvider
,
antigravityGatewayService
,
httpUpstream
,
configConfig
)
concurrencyCache
:=
repository
.
ProvideConcurrencyCache
(
redisClient
,
configConfig
)
concurrencyService
:=
service
.
ProvideConcurrencyService
(
concurrencyCache
,
accountRepository
,
configConfig
)
crsSyncService
:=
service
.
NewCRSSyncService
(
accountRepository
,
proxyRepository
,
oAuthService
,
openAIOAuthService
,
geminiOAuthService
,
configConfig
)
sessionLimitCache
:=
repository
.
ProvideSessionLimitCache
(
redisClient
,
configConfig
)
accountHandler
:=
admin
.
NewAccountHandler
(
adminService
,
oAuthService
,
openAIOAuthService
,
geminiOAuthService
,
antigravityOAuthService
,
rateLimitService
,
accountUsageService
,
accountTestService
,
concurrencyService
,
crsSyncService
,
sessionLimitCache
)
accountHandler
:=
admin
.
NewAccountHandler
(
adminService
,
oAuthService
,
openAIOAuthService
,
geminiOAuthService
,
antigravityOAuthService
,
rateLimitService
,
accountUsageService
,
accountTestService
,
concurrencyService
,
crsSyncService
,
sessionLimitCache
,
compositeTokenCacheInvalidator
)
adminAnnouncementHandler
:=
admin
.
NewAnnouncementHandler
(
announcementService
)
oAuthHandler
:=
admin
.
NewOAuthHandler
(
oAuthService
)
openAIOAuthHandler
:=
admin
.
NewOpenAIOAuthHandler
(
openAIOAuthService
,
adminService
)
geminiOAuthHandler
:=
admin
.
NewGeminiOAuthHandler
(
geminiOAuthService
)
...
...
@@ -128,7 +141,6 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) {
adminRedeemHandler
:=
admin
.
NewRedeemHandler
(
adminService
)
promoHandler
:=
admin
.
NewPromoHandler
(
promoService
)
opsRepository
:=
repository
.
NewOpsRepository
(
db
)
schedulerCache
:=
repository
.
NewSchedulerCache
(
redisClient
)
schedulerOutboxRepository
:=
repository
.
NewSchedulerOutboxRepository
(
db
)
schedulerSnapshotService
:=
service
.
ProvideSchedulerSnapshotService
(
schedulerCache
,
schedulerOutboxRepository
,
accountRepository
,
groupRepository
,
configConfig
)
pricingRemoteClient
:=
repository
.
ProvidePricingRemoteClient
(
configConfig
)
...
...
@@ -137,7 +149,6 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) {
return
nil
,
err
}
billingService
:=
service
.
NewBillingService
(
configConfig
,
pricingService
)
identityCache
:=
repository
.
NewIdentityCache
(
redisClient
)
identityService
:=
service
.
NewIdentityService
(
identityCache
)
deferredService
:=
service
.
ProvideDeferredService
(
accountRepository
,
timingWheelService
)
claudeTokenProvider
:=
service
.
NewClaudeTokenProvider
(
accountRepository
,
geminiTokenCache
,
oAuthService
)
...
...
@@ -154,16 +165,19 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) {
updateService
:=
service
.
ProvideUpdateService
(
updateCache
,
gitHubReleaseClient
,
serviceBuildInfo
)
systemHandler
:=
handler
.
ProvideSystemHandler
(
updateService
)
adminSubscriptionHandler
:=
admin
.
NewSubscriptionHandler
(
subscriptionService
)
adminUsageHandler
:=
admin
.
NewUsageHandler
(
usageService
,
apiKeyService
,
adminService
)
usageCleanupRepository
:=
repository
.
NewUsageCleanupRepository
(
client
,
db
)
usageCleanupService
:=
service
.
ProvideUsageCleanupService
(
usageCleanupRepository
,
timingWheelService
,
dashboardAggregationService
,
configConfig
)
adminUsageHandler
:=
admin
.
NewUsageHandler
(
usageService
,
apiKeyService
,
adminService
,
usageCleanupService
)
userAttributeDefinitionRepository
:=
repository
.
NewUserAttributeDefinitionRepository
(
client
)
userAttributeValueRepository
:=
repository
.
NewUserAttributeValueRepository
(
client
)
userAttributeService
:=
service
.
NewUserAttributeService
(
userAttributeDefinitionRepository
,
userAttributeValueRepository
)
userAttributeHandler
:=
admin
.
NewUserAttributeHandler
(
userAttributeService
)
adminHandlers
:=
handler
.
ProvideAdminHandlers
(
dashboardHandler
,
adminUserHandler
,
groupHandler
,
accountHandler
,
oAuthHandler
,
openAIOAuthHandler
,
geminiOAuthHandler
,
antigravityOAuthHandler
,
proxyHandler
,
adminRedeemHandler
,
promoHandler
,
settingHandler
,
opsHandler
,
systemHandler
,
adminSubscriptionHandler
,
adminUsageHandler
,
userAttributeHandler
)
gatewayHandler
:=
handler
.
NewGatewayHandler
(
gatewayService
,
geminiMessagesCompatService
,
antigravityGatewayService
,
userService
,
concurrencyService
,
billingCacheService
,
configConfig
)
adminHandlers
:=
handler
.
ProvideAdminHandlers
(
dashboardHandler
,
adminUserHandler
,
groupHandler
,
accountHandler
,
adminAnnouncementHandler
,
oAuthHandler
,
openAIOAuthHandler
,
geminiOAuthHandler
,
antigravityOAuthHandler
,
proxyHandler
,
adminRedeemHandler
,
promoHandler
,
settingHandler
,
opsHandler
,
systemHandler
,
adminSubscriptionHandler
,
adminUsageHandler
,
userAttributeHandler
)
gatewayHandler
:=
handler
.
NewGatewayHandler
(
gatewayService
,
geminiMessagesCompatService
,
antigravityGatewayService
,
userService
,
concurrencyService
,
billingCacheService
,
usageService
,
configConfig
)
openAIGatewayHandler
:=
handler
.
NewOpenAIGatewayHandler
(
openAIGatewayService
,
concurrencyService
,
billingCacheService
,
configConfig
)
handlerSettingHandler
:=
handler
.
ProvideSettingHandler
(
settingService
,
buildInfo
)
handlers
:=
handler
.
ProvideHandlers
(
authHandler
,
userHandler
,
apiKeyHandler
,
usageHandler
,
redeemHandler
,
subscriptionHandler
,
adminHandlers
,
gatewayHandler
,
openAIGatewayHandler
,
handlerSettingHandler
)
totpHandler
:=
handler
.
NewTotpHandler
(
totpService
)
handlers
:=
handler
.
ProvideHandlers
(
authHandler
,
userHandler
,
apiKeyHandler
,
usageHandler
,
redeemHandler
,
subscriptionHandler
,
announcementHandler
,
adminHandlers
,
gatewayHandler
,
openAIGatewayHandler
,
handlerSettingHandler
,
totpHandler
)
jwtAuthMiddleware
:=
middleware
.
NewJWTAuthMiddleware
(
authService
,
userService
)
adminAuthMiddleware
:=
middleware
.
NewAdminAuthMiddleware
(
authService
,
userService
,
settingService
)
apiKeyAuthMiddleware
:=
middleware
.
NewAPIKeyAuthMiddleware
(
apiKeyService
,
subscriptionService
,
configConfig
)
...
...
@@ -174,9 +188,10 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) {
opsAlertEvaluatorService
:=
service
.
ProvideOpsAlertEvaluatorService
(
opsService
,
opsRepository
,
emailService
,
redisClient
,
configConfig
)
opsCleanupService
:=
service
.
ProvideOpsCleanupService
(
opsRepository
,
db
,
redisClient
,
configConfig
)
opsScheduledReportService
:=
service
.
ProvideOpsScheduledReportService
(
opsService
,
userService
,
emailService
,
redisClient
,
configConfig
)
tokenRefreshService
:=
service
.
ProvideTokenRefreshService
(
accountRepository
,
oAuthService
,
openAIOAuthService
,
geminiOAuthService
,
antigravityOAuthService
,
compositeTokenCacheInvalidator
,
configConfig
)
tokenRefreshService
:=
service
.
ProvideTokenRefreshService
(
accountRepository
,
oAuthService
,
openAIOAuthService
,
geminiOAuthService
,
antigravityOAuthService
,
compositeTokenCacheInvalidator
,
schedulerCache
,
configConfig
)
accountExpiryService
:=
service
.
ProvideAccountExpiryService
(
accountRepository
)
v
:=
provideCleanup
(
client
,
redisClient
,
opsMetricsCollector
,
opsAggregationService
,
opsAlertEvaluatorService
,
opsCleanupService
,
opsScheduledReportService
,
schedulerSnapshotService
,
tokenRefreshService
,
accountExpiryService
,
pricingService
,
emailQueueService
,
billingCacheService
,
oAuthService
,
openAIOAuthService
,
geminiOAuthService
,
antigravityOAuthService
)
subscriptionExpiryService
:=
service
.
ProvideSubscriptionExpiryService
(
userSubscriptionRepository
)
v
:=
provideCleanup
(
client
,
redisClient
,
opsMetricsCollector
,
opsAggregationService
,
opsAlertEvaluatorService
,
opsCleanupService
,
opsScheduledReportService
,
schedulerSnapshotService
,
tokenRefreshService
,
accountExpiryService
,
subscriptionExpiryService
,
usageCleanupService
,
pricingService
,
emailQueueService
,
billingCacheService
,
oAuthService
,
openAIOAuthService
,
geminiOAuthService
,
antigravityOAuthService
)
application
:=
&
Application
{
Server
:
httpServer
,
Cleanup
:
v
,
...
...
@@ -209,6 +224,8 @@ func provideCleanup(
schedulerSnapshot
*
service
.
SchedulerSnapshotService
,
tokenRefresh
*
service
.
TokenRefreshService
,
accountExpiry
*
service
.
AccountExpiryService
,
subscriptionExpiry
*
service
.
SubscriptionExpiryService
,
usageCleanup
*
service
.
UsageCleanupService
,
pricing
*
service
.
PricingService
,
emailQueue
*
service
.
EmailQueueService
,
billingCache
*
service
.
BillingCacheService
,
...
...
@@ -261,6 +278,12 @@ func provideCleanup(
}
return
nil
}},
{
"UsageCleanupService"
,
func
()
error
{
if
usageCleanup
!=
nil
{
usageCleanup
.
Stop
()
}
return
nil
}},
{
"TokenRefreshService"
,
func
()
error
{
tokenRefresh
.
Stop
()
return
nil
...
...
@@ -269,6 +292,10 @@ func provideCleanup(
accountExpiry
.
Stop
()
return
nil
}},
{
"SubscriptionExpiryService"
,
func
()
error
{
subscriptionExpiry
.
Stop
()
return
nil
}},
{
"PricingService"
,
func
()
error
{
pricing
.
Stop
()
return
nil
...
...
backend/ent/announcement.go
0 → 100644
View file @
0170d19f
// Code generated by ent, DO NOT EDIT.
package
ent
import
(
"encoding/json"
"fmt"
"strings"
"time"
"entgo.io/ent"
"entgo.io/ent/dialect/sql"
"github.com/Wei-Shaw/sub2api/ent/announcement"
"github.com/Wei-Shaw/sub2api/internal/domain"
)
// Announcement is the model entity for the Announcement schema.
type
Announcement
struct
{
config
`json:"-"`
// ID of the ent.
ID
int64
`json:"id,omitempty"`
// 公告标题
Title
string
`json:"title,omitempty"`
// 公告内容(支持 Markdown)
Content
string
`json:"content,omitempty"`
// 状态: draft, active, archived
Status
string
`json:"status,omitempty"`
// 展示条件(JSON 规则)
Targeting
domain
.
AnnouncementTargeting
`json:"targeting,omitempty"`
// 开始展示时间(为空表示立即生效)
StartsAt
*
time
.
Time
`json:"starts_at,omitempty"`
// 结束展示时间(为空表示永久生效)
EndsAt
*
time
.
Time
`json:"ends_at,omitempty"`
// 创建人用户ID(管理员)
CreatedBy
*
int64
`json:"created_by,omitempty"`
// 更新人用户ID(管理员)
UpdatedBy
*
int64
`json:"updated_by,omitempty"`
// CreatedAt holds the value of the "created_at" field.
CreatedAt
time
.
Time
`json:"created_at,omitempty"`
// UpdatedAt holds the value of the "updated_at" field.
UpdatedAt
time
.
Time
`json:"updated_at,omitempty"`
// Edges holds the relations/edges for other nodes in the graph.
// The values are being populated by the AnnouncementQuery when eager-loading is set.
Edges
AnnouncementEdges
`json:"edges"`
selectValues
sql
.
SelectValues
}
// AnnouncementEdges holds the relations/edges for other nodes in the graph.
type
AnnouncementEdges
struct
{
// Reads holds the value of the reads edge.
Reads
[]
*
AnnouncementRead
`json:"reads,omitempty"`
// loadedTypes holds the information for reporting if a
// type was loaded (or requested) in eager-loading or not.
loadedTypes
[
1
]
bool
}
// ReadsOrErr returns the Reads value or an error if the edge
// was not loaded in eager-loading.
func
(
e
AnnouncementEdges
)
ReadsOrErr
()
([]
*
AnnouncementRead
,
error
)
{
if
e
.
loadedTypes
[
0
]
{
return
e
.
Reads
,
nil
}
return
nil
,
&
NotLoadedError
{
edge
:
"reads"
}
}
// scanValues returns the types for scanning values from sql.Rows.
func
(
*
Announcement
)
scanValues
(
columns
[]
string
)
([]
any
,
error
)
{
values
:=
make
([]
any
,
len
(
columns
))
for
i
:=
range
columns
{
switch
columns
[
i
]
{
case
announcement
.
FieldTargeting
:
values
[
i
]
=
new
([]
byte
)
case
announcement
.
FieldID
,
announcement
.
FieldCreatedBy
,
announcement
.
FieldUpdatedBy
:
values
[
i
]
=
new
(
sql
.
NullInt64
)
case
announcement
.
FieldTitle
,
announcement
.
FieldContent
,
announcement
.
FieldStatus
:
values
[
i
]
=
new
(
sql
.
NullString
)
case
announcement
.
FieldStartsAt
,
announcement
.
FieldEndsAt
,
announcement
.
FieldCreatedAt
,
announcement
.
FieldUpdatedAt
:
values
[
i
]
=
new
(
sql
.
NullTime
)
default
:
values
[
i
]
=
new
(
sql
.
UnknownType
)
}
}
return
values
,
nil
}
// assignValues assigns the values that were returned from sql.Rows (after scanning)
// to the Announcement fields.
func
(
_m
*
Announcement
)
assignValues
(
columns
[]
string
,
values
[]
any
)
error
{
if
m
,
n
:=
len
(
values
),
len
(
columns
);
m
<
n
{
return
fmt
.
Errorf
(
"mismatch number of scan values: %d != %d"
,
m
,
n
)
}
for
i
:=
range
columns
{
switch
columns
[
i
]
{
case
announcement
.
FieldID
:
value
,
ok
:=
values
[
i
]
.
(
*
sql
.
NullInt64
)
if
!
ok
{
return
fmt
.
Errorf
(
"unexpected type %T for field id"
,
value
)
}
_m
.
ID
=
int64
(
value
.
Int64
)
case
announcement
.
FieldTitle
:
if
value
,
ok
:=
values
[
i
]
.
(
*
sql
.
NullString
);
!
ok
{
return
fmt
.
Errorf
(
"unexpected type %T for field title"
,
values
[
i
])
}
else
if
value
.
Valid
{
_m
.
Title
=
value
.
String
}
case
announcement
.
FieldContent
:
if
value
,
ok
:=
values
[
i
]
.
(
*
sql
.
NullString
);
!
ok
{
return
fmt
.
Errorf
(
"unexpected type %T for field content"
,
values
[
i
])
}
else
if
value
.
Valid
{
_m
.
Content
=
value
.
String
}
case
announcement
.
FieldStatus
:
if
value
,
ok
:=
values
[
i
]
.
(
*
sql
.
NullString
);
!
ok
{
return
fmt
.
Errorf
(
"unexpected type %T for field status"
,
values
[
i
])
}
else
if
value
.
Valid
{
_m
.
Status
=
value
.
String
}
case
announcement
.
FieldTargeting
:
if
value
,
ok
:=
values
[
i
]
.
(
*
[]
byte
);
!
ok
{
return
fmt
.
Errorf
(
"unexpected type %T for field targeting"
,
values
[
i
])
}
else
if
value
!=
nil
&&
len
(
*
value
)
>
0
{
if
err
:=
json
.
Unmarshal
(
*
value
,
&
_m
.
Targeting
);
err
!=
nil
{
return
fmt
.
Errorf
(
"unmarshal field targeting: %w"
,
err
)
}
}
case
announcement
.
FieldStartsAt
:
if
value
,
ok
:=
values
[
i
]
.
(
*
sql
.
NullTime
);
!
ok
{
return
fmt
.
Errorf
(
"unexpected type %T for field starts_at"
,
values
[
i
])
}
else
if
value
.
Valid
{
_m
.
StartsAt
=
new
(
time
.
Time
)
*
_m
.
StartsAt
=
value
.
Time
}
case
announcement
.
FieldEndsAt
:
if
value
,
ok
:=
values
[
i
]
.
(
*
sql
.
NullTime
);
!
ok
{
return
fmt
.
Errorf
(
"unexpected type %T for field ends_at"
,
values
[
i
])
}
else
if
value
.
Valid
{
_m
.
EndsAt
=
new
(
time
.
Time
)
*
_m
.
EndsAt
=
value
.
Time
}
case
announcement
.
FieldCreatedBy
:
if
value
,
ok
:=
values
[
i
]
.
(
*
sql
.
NullInt64
);
!
ok
{
return
fmt
.
Errorf
(
"unexpected type %T for field created_by"
,
values
[
i
])
}
else
if
value
.
Valid
{
_m
.
CreatedBy
=
new
(
int64
)
*
_m
.
CreatedBy
=
value
.
Int64
}
case
announcement
.
FieldUpdatedBy
:
if
value
,
ok
:=
values
[
i
]
.
(
*
sql
.
NullInt64
);
!
ok
{
return
fmt
.
Errorf
(
"unexpected type %T for field updated_by"
,
values
[
i
])
}
else
if
value
.
Valid
{
_m
.
UpdatedBy
=
new
(
int64
)
*
_m
.
UpdatedBy
=
value
.
Int64
}
case
announcement
.
FieldCreatedAt
:
if
value
,
ok
:=
values
[
i
]
.
(
*
sql
.
NullTime
);
!
ok
{
return
fmt
.
Errorf
(
"unexpected type %T for field created_at"
,
values
[
i
])
}
else
if
value
.
Valid
{
_m
.
CreatedAt
=
value
.
Time
}
case
announcement
.
FieldUpdatedAt
:
if
value
,
ok
:=
values
[
i
]
.
(
*
sql
.
NullTime
);
!
ok
{
return
fmt
.
Errorf
(
"unexpected type %T for field updated_at"
,
values
[
i
])
}
else
if
value
.
Valid
{
_m
.
UpdatedAt
=
value
.
Time
}
default
:
_m
.
selectValues
.
Set
(
columns
[
i
],
values
[
i
])
}
}
return
nil
}
// Value returns the ent.Value that was dynamically selected and assigned to the Announcement.
// This includes values selected through modifiers, order, etc.
func
(
_m
*
Announcement
)
Value
(
name
string
)
(
ent
.
Value
,
error
)
{
return
_m
.
selectValues
.
Get
(
name
)
}
// QueryReads queries the "reads" edge of the Announcement entity.
func
(
_m
*
Announcement
)
QueryReads
()
*
AnnouncementReadQuery
{
return
NewAnnouncementClient
(
_m
.
config
)
.
QueryReads
(
_m
)
}
// Update returns a builder for updating this Announcement.
// Note that you need to call Announcement.Unwrap() before calling this method if this Announcement
// was returned from a transaction, and the transaction was committed or rolled back.
func
(
_m
*
Announcement
)
Update
()
*
AnnouncementUpdateOne
{
return
NewAnnouncementClient
(
_m
.
config
)
.
UpdateOne
(
_m
)
}
// Unwrap unwraps the Announcement entity that was returned from a transaction after it was closed,
// so that all future queries will be executed through the driver which created the transaction.
func
(
_m
*
Announcement
)
Unwrap
()
*
Announcement
{
_tx
,
ok
:=
_m
.
config
.
driver
.
(
*
txDriver
)
if
!
ok
{
panic
(
"ent: Announcement is not a transactional entity"
)
}
_m
.
config
.
driver
=
_tx
.
drv
return
_m
}
// String implements the fmt.Stringer.
func
(
_m
*
Announcement
)
String
()
string
{
var
builder
strings
.
Builder
builder
.
WriteString
(
"Announcement("
)
builder
.
WriteString
(
fmt
.
Sprintf
(
"id=%v, "
,
_m
.
ID
))
builder
.
WriteString
(
"title="
)
builder
.
WriteString
(
_m
.
Title
)
builder
.
WriteString
(
", "
)
builder
.
WriteString
(
"content="
)
builder
.
WriteString
(
_m
.
Content
)
builder
.
WriteString
(
", "
)
builder
.
WriteString
(
"status="
)
builder
.
WriteString
(
_m
.
Status
)
builder
.
WriteString
(
", "
)
builder
.
WriteString
(
"targeting="
)
builder
.
WriteString
(
fmt
.
Sprintf
(
"%v"
,
_m
.
Targeting
))
builder
.
WriteString
(
", "
)
if
v
:=
_m
.
StartsAt
;
v
!=
nil
{
builder
.
WriteString
(
"starts_at="
)
builder
.
WriteString
(
v
.
Format
(
time
.
ANSIC
))
}
builder
.
WriteString
(
", "
)
if
v
:=
_m
.
EndsAt
;
v
!=
nil
{
builder
.
WriteString
(
"ends_at="
)
builder
.
WriteString
(
v
.
Format
(
time
.
ANSIC
))
}
builder
.
WriteString
(
", "
)
if
v
:=
_m
.
CreatedBy
;
v
!=
nil
{
builder
.
WriteString
(
"created_by="
)
builder
.
WriteString
(
fmt
.
Sprintf
(
"%v"
,
*
v
))
}
builder
.
WriteString
(
", "
)
if
v
:=
_m
.
UpdatedBy
;
v
!=
nil
{
builder
.
WriteString
(
"updated_by="
)
builder
.
WriteString
(
fmt
.
Sprintf
(
"%v"
,
*
v
))
}
builder
.
WriteString
(
", "
)
builder
.
WriteString
(
"created_at="
)
builder
.
WriteString
(
_m
.
CreatedAt
.
Format
(
time
.
ANSIC
))
builder
.
WriteString
(
", "
)
builder
.
WriteString
(
"updated_at="
)
builder
.
WriteString
(
_m
.
UpdatedAt
.
Format
(
time
.
ANSIC
))
builder
.
WriteByte
(
')'
)
return
builder
.
String
()
}
// Announcements is a parsable slice of Announcement.
type
Announcements
[]
*
Announcement
backend/ent/announcement/announcement.go
0 → 100644
View file @
0170d19f
// Code generated by ent, DO NOT EDIT.
package
announcement
import
(
"time"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
)
const
(
// Label holds the string label denoting the announcement type in the database.
Label
=
"announcement"
// FieldID holds the string denoting the id field in the database.
FieldID
=
"id"
// FieldTitle holds the string denoting the title field in the database.
FieldTitle
=
"title"
// FieldContent holds the string denoting the content field in the database.
FieldContent
=
"content"
// FieldStatus holds the string denoting the status field in the database.
FieldStatus
=
"status"
// FieldTargeting holds the string denoting the targeting field in the database.
FieldTargeting
=
"targeting"
// FieldStartsAt holds the string denoting the starts_at field in the database.
FieldStartsAt
=
"starts_at"
// FieldEndsAt holds the string denoting the ends_at field in the database.
FieldEndsAt
=
"ends_at"
// FieldCreatedBy holds the string denoting the created_by field in the database.
FieldCreatedBy
=
"created_by"
// FieldUpdatedBy holds the string denoting the updated_by field in the database.
FieldUpdatedBy
=
"updated_by"
// FieldCreatedAt holds the string denoting the created_at field in the database.
FieldCreatedAt
=
"created_at"
// FieldUpdatedAt holds the string denoting the updated_at field in the database.
FieldUpdatedAt
=
"updated_at"
// EdgeReads holds the string denoting the reads edge name in mutations.
EdgeReads
=
"reads"
// Table holds the table name of the announcement in the database.
Table
=
"announcements"
// ReadsTable is the table that holds the reads relation/edge.
ReadsTable
=
"announcement_reads"
// ReadsInverseTable is the table name for the AnnouncementRead entity.
// It exists in this package in order to avoid circular dependency with the "announcementread" package.
ReadsInverseTable
=
"announcement_reads"
// ReadsColumn is the table column denoting the reads relation/edge.
ReadsColumn
=
"announcement_id"
)
// Columns holds all SQL columns for announcement fields.
var
Columns
=
[]
string
{
FieldID
,
FieldTitle
,
FieldContent
,
FieldStatus
,
FieldTargeting
,
FieldStartsAt
,
FieldEndsAt
,
FieldCreatedBy
,
FieldUpdatedBy
,
FieldCreatedAt
,
FieldUpdatedAt
,
}
// ValidColumn reports if the column name is valid (part of the table columns).
func
ValidColumn
(
column
string
)
bool
{
for
i
:=
range
Columns
{
if
column
==
Columns
[
i
]
{
return
true
}
}
return
false
}
var
(
// TitleValidator is a validator for the "title" field. It is called by the builders before save.
TitleValidator
func
(
string
)
error
// ContentValidator is a validator for the "content" field. It is called by the builders before save.
ContentValidator
func
(
string
)
error
// DefaultStatus holds the default value on creation for the "status" field.
DefaultStatus
string
// StatusValidator is a validator for the "status" field. It is called by the builders before save.
StatusValidator
func
(
string
)
error
// DefaultCreatedAt holds the default value on creation for the "created_at" field.
DefaultCreatedAt
func
()
time
.
Time
// DefaultUpdatedAt holds the default value on creation for the "updated_at" field.
DefaultUpdatedAt
func
()
time
.
Time
// UpdateDefaultUpdatedAt holds the default value on update for the "updated_at" field.
UpdateDefaultUpdatedAt
func
()
time
.
Time
)
// OrderOption defines the ordering options for the Announcement queries.
type
OrderOption
func
(
*
sql
.
Selector
)
// ByID orders the results by the id field.
func
ByID
(
opts
...
sql
.
OrderTermOption
)
OrderOption
{
return
sql
.
OrderByField
(
FieldID
,
opts
...
)
.
ToFunc
()
}
// ByTitle orders the results by the title field.
func
ByTitle
(
opts
...
sql
.
OrderTermOption
)
OrderOption
{
return
sql
.
OrderByField
(
FieldTitle
,
opts
...
)
.
ToFunc
()
}
// ByContent orders the results by the content field.
func
ByContent
(
opts
...
sql
.
OrderTermOption
)
OrderOption
{
return
sql
.
OrderByField
(
FieldContent
,
opts
...
)
.
ToFunc
()
}
// ByStatus orders the results by the status field.
func
ByStatus
(
opts
...
sql
.
OrderTermOption
)
OrderOption
{
return
sql
.
OrderByField
(
FieldStatus
,
opts
...
)
.
ToFunc
()
}
// ByStartsAt orders the results by the starts_at field.
func
ByStartsAt
(
opts
...
sql
.
OrderTermOption
)
OrderOption
{
return
sql
.
OrderByField
(
FieldStartsAt
,
opts
...
)
.
ToFunc
()
}
// ByEndsAt orders the results by the ends_at field.
func
ByEndsAt
(
opts
...
sql
.
OrderTermOption
)
OrderOption
{
return
sql
.
OrderByField
(
FieldEndsAt
,
opts
...
)
.
ToFunc
()
}
// ByCreatedBy orders the results by the created_by field.
func
ByCreatedBy
(
opts
...
sql
.
OrderTermOption
)
OrderOption
{
return
sql
.
OrderByField
(
FieldCreatedBy
,
opts
...
)
.
ToFunc
()
}
// ByUpdatedBy orders the results by the updated_by field.
func
ByUpdatedBy
(
opts
...
sql
.
OrderTermOption
)
OrderOption
{
return
sql
.
OrderByField
(
FieldUpdatedBy
,
opts
...
)
.
ToFunc
()
}
// ByCreatedAt orders the results by the created_at field.
func
ByCreatedAt
(
opts
...
sql
.
OrderTermOption
)
OrderOption
{
return
sql
.
OrderByField
(
FieldCreatedAt
,
opts
...
)
.
ToFunc
()
}
// ByUpdatedAt orders the results by the updated_at field.
func
ByUpdatedAt
(
opts
...
sql
.
OrderTermOption
)
OrderOption
{
return
sql
.
OrderByField
(
FieldUpdatedAt
,
opts
...
)
.
ToFunc
()
}
// ByReadsCount orders the results by reads count.
func
ByReadsCount
(
opts
...
sql
.
OrderTermOption
)
OrderOption
{
return
func
(
s
*
sql
.
Selector
)
{
sqlgraph
.
OrderByNeighborsCount
(
s
,
newReadsStep
(),
opts
...
)
}
}
// ByReads orders the results by reads terms.
func
ByReads
(
term
sql
.
OrderTerm
,
terms
...
sql
.
OrderTerm
)
OrderOption
{
return
func
(
s
*
sql
.
Selector
)
{
sqlgraph
.
OrderByNeighborTerms
(
s
,
newReadsStep
(),
append
([]
sql
.
OrderTerm
{
term
},
terms
...
)
...
)
}
}
func
newReadsStep
()
*
sqlgraph
.
Step
{
return
sqlgraph
.
NewStep
(
sqlgraph
.
From
(
Table
,
FieldID
),
sqlgraph
.
To
(
ReadsInverseTable
,
FieldID
),
sqlgraph
.
Edge
(
sqlgraph
.
O2M
,
false
,
ReadsTable
,
ReadsColumn
),
)
}
backend/ent/announcement/where.go
0 → 100644
View file @
0170d19f
This diff is collapsed.
Click to expand it.
backend/ent/announcement_create.go
0 → 100644
View file @
0170d19f
This diff is collapsed.
Click to expand it.
backend/ent/announcement_delete.go
0 → 100644
View file @
0170d19f
// Code generated by ent, DO NOT EDIT.
package
ent
import
(
"context"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
"entgo.io/ent/schema/field"
"github.com/Wei-Shaw/sub2api/ent/announcement"
"github.com/Wei-Shaw/sub2api/ent/predicate"
)
// AnnouncementDelete is the builder for deleting a Announcement entity.
type
AnnouncementDelete
struct
{
config
hooks
[]
Hook
mutation
*
AnnouncementMutation
}
// Where appends a list predicates to the AnnouncementDelete builder.
func
(
_d
*
AnnouncementDelete
)
Where
(
ps
...
predicate
.
Announcement
)
*
AnnouncementDelete
{
_d
.
mutation
.
Where
(
ps
...
)
return
_d
}
// Exec executes the deletion query and returns how many vertices were deleted.
func
(
_d
*
AnnouncementDelete
)
Exec
(
ctx
context
.
Context
)
(
int
,
error
)
{
return
withHooks
(
ctx
,
_d
.
sqlExec
,
_d
.
mutation
,
_d
.
hooks
)
}
// ExecX is like Exec, but panics if an error occurs.
func
(
_d
*
AnnouncementDelete
)
ExecX
(
ctx
context
.
Context
)
int
{
n
,
err
:=
_d
.
Exec
(
ctx
)
if
err
!=
nil
{
panic
(
err
)
}
return
n
}
func
(
_d
*
AnnouncementDelete
)
sqlExec
(
ctx
context
.
Context
)
(
int
,
error
)
{
_spec
:=
sqlgraph
.
NewDeleteSpec
(
announcement
.
Table
,
sqlgraph
.
NewFieldSpec
(
announcement
.
FieldID
,
field
.
TypeInt64
))
if
ps
:=
_d
.
mutation
.
predicates
;
len
(
ps
)
>
0
{
_spec
.
Predicate
=
func
(
selector
*
sql
.
Selector
)
{
for
i
:=
range
ps
{
ps
[
i
](
selector
)
}
}
}
affected
,
err
:=
sqlgraph
.
DeleteNodes
(
ctx
,
_d
.
driver
,
_spec
)
if
err
!=
nil
&&
sqlgraph
.
IsConstraintError
(
err
)
{
err
=
&
ConstraintError
{
msg
:
err
.
Error
(),
wrap
:
err
}
}
_d
.
mutation
.
done
=
true
return
affected
,
err
}
// AnnouncementDeleteOne is the builder for deleting a single Announcement entity.
type
AnnouncementDeleteOne
struct
{
_d
*
AnnouncementDelete
}
// Where appends a list predicates to the AnnouncementDelete builder.
func
(
_d
*
AnnouncementDeleteOne
)
Where
(
ps
...
predicate
.
Announcement
)
*
AnnouncementDeleteOne
{
_d
.
_d
.
mutation
.
Where
(
ps
...
)
return
_d
}
// Exec executes the deletion query.
func
(
_d
*
AnnouncementDeleteOne
)
Exec
(
ctx
context
.
Context
)
error
{
n
,
err
:=
_d
.
_d
.
Exec
(
ctx
)
switch
{
case
err
!=
nil
:
return
err
case
n
==
0
:
return
&
NotFoundError
{
announcement
.
Label
}
default
:
return
nil
}
}
// ExecX is like Exec, but panics if an error occurs.
func
(
_d
*
AnnouncementDeleteOne
)
ExecX
(
ctx
context
.
Context
)
{
if
err
:=
_d
.
Exec
(
ctx
);
err
!=
nil
{
panic
(
err
)
}
}
backend/ent/announcement_query.go
0 → 100644
View file @
0170d19f
// Code generated by ent, DO NOT EDIT.
package
ent
import
(
"context"
"database/sql/driver"
"fmt"
"math"
"entgo.io/ent"
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
"entgo.io/ent/schema/field"
"github.com/Wei-Shaw/sub2api/ent/announcement"
"github.com/Wei-Shaw/sub2api/ent/announcementread"
"github.com/Wei-Shaw/sub2api/ent/predicate"
)
// AnnouncementQuery is the builder for querying Announcement entities.
type
AnnouncementQuery
struct
{
config
ctx
*
QueryContext
order
[]
announcement
.
OrderOption
inters
[]
Interceptor
predicates
[]
predicate
.
Announcement
withReads
*
AnnouncementReadQuery
modifiers
[]
func
(
*
sql
.
Selector
)
// intermediate query (i.e. traversal path).
sql
*
sql
.
Selector
path
func
(
context
.
Context
)
(
*
sql
.
Selector
,
error
)
}
// Where adds a new predicate for the AnnouncementQuery builder.
func
(
_q
*
AnnouncementQuery
)
Where
(
ps
...
predicate
.
Announcement
)
*
AnnouncementQuery
{
_q
.
predicates
=
append
(
_q
.
predicates
,
ps
...
)
return
_q
}
// Limit the number of records to be returned by this query.
func
(
_q
*
AnnouncementQuery
)
Limit
(
limit
int
)
*
AnnouncementQuery
{
_q
.
ctx
.
Limit
=
&
limit
return
_q
}
// Offset to start from.
func
(
_q
*
AnnouncementQuery
)
Offset
(
offset
int
)
*
AnnouncementQuery
{
_q
.
ctx
.
Offset
=
&
offset
return
_q
}
// Unique configures the query builder to filter duplicate records on query.
// By default, unique is set to true, and can be disabled using this method.
func
(
_q
*
AnnouncementQuery
)
Unique
(
unique
bool
)
*
AnnouncementQuery
{
_q
.
ctx
.
Unique
=
&
unique
return
_q
}
// Order specifies how the records should be ordered.
func
(
_q
*
AnnouncementQuery
)
Order
(
o
...
announcement
.
OrderOption
)
*
AnnouncementQuery
{
_q
.
order
=
append
(
_q
.
order
,
o
...
)
return
_q
}
// QueryReads chains the current query on the "reads" edge.
func
(
_q
*
AnnouncementQuery
)
QueryReads
()
*
AnnouncementReadQuery
{
query
:=
(
&
AnnouncementReadClient
{
config
:
_q
.
config
})
.
Query
()
query
.
path
=
func
(
ctx
context
.
Context
)
(
fromU
*
sql
.
Selector
,
err
error
)
{
if
err
:=
_q
.
prepareQuery
(
ctx
);
err
!=
nil
{
return
nil
,
err
}
selector
:=
_q
.
sqlQuery
(
ctx
)
if
err
:=
selector
.
Err
();
err
!=
nil
{
return
nil
,
err
}
step
:=
sqlgraph
.
NewStep
(
sqlgraph
.
From
(
announcement
.
Table
,
announcement
.
FieldID
,
selector
),
sqlgraph
.
To
(
announcementread
.
Table
,
announcementread
.
FieldID
),
sqlgraph
.
Edge
(
sqlgraph
.
O2M
,
false
,
announcement
.
ReadsTable
,
announcement
.
ReadsColumn
),
)
fromU
=
sqlgraph
.
SetNeighbors
(
_q
.
driver
.
Dialect
(),
step
)
return
fromU
,
nil
}
return
query
}
// First returns the first Announcement entity from the query.
// Returns a *NotFoundError when no Announcement was found.
func
(
_q
*
AnnouncementQuery
)
First
(
ctx
context
.
Context
)
(
*
Announcement
,
error
)
{
nodes
,
err
:=
_q
.
Limit
(
1
)
.
All
(
setContextOp
(
ctx
,
_q
.
ctx
,
ent
.
OpQueryFirst
))
if
err
!=
nil
{
return
nil
,
err
}
if
len
(
nodes
)
==
0
{
return
nil
,
&
NotFoundError
{
announcement
.
Label
}
}
return
nodes
[
0
],
nil
}
// FirstX is like First, but panics if an error occurs.
func
(
_q
*
AnnouncementQuery
)
FirstX
(
ctx
context
.
Context
)
*
Announcement
{
node
,
err
:=
_q
.
First
(
ctx
)
if
err
!=
nil
&&
!
IsNotFound
(
err
)
{
panic
(
err
)
}
return
node
}
// FirstID returns the first Announcement ID from the query.
// Returns a *NotFoundError when no Announcement ID was found.
func
(
_q
*
AnnouncementQuery
)
FirstID
(
ctx
context
.
Context
)
(
id
int64
,
err
error
)
{
var
ids
[]
int64
if
ids
,
err
=
_q
.
Limit
(
1
)
.
IDs
(
setContextOp
(
ctx
,
_q
.
ctx
,
ent
.
OpQueryFirstID
));
err
!=
nil
{
return
}
if
len
(
ids
)
==
0
{
err
=
&
NotFoundError
{
announcement
.
Label
}
return
}
return
ids
[
0
],
nil
}
// FirstIDX is like FirstID, but panics if an error occurs.
func
(
_q
*
AnnouncementQuery
)
FirstIDX
(
ctx
context
.
Context
)
int64
{
id
,
err
:=
_q
.
FirstID
(
ctx
)
if
err
!=
nil
&&
!
IsNotFound
(
err
)
{
panic
(
err
)
}
return
id
}
// Only returns a single Announcement entity found by the query, ensuring it only returns one.
// Returns a *NotSingularError when more than one Announcement entity is found.
// Returns a *NotFoundError when no Announcement entities are found.
func
(
_q
*
AnnouncementQuery
)
Only
(
ctx
context
.
Context
)
(
*
Announcement
,
error
)
{
nodes
,
err
:=
_q
.
Limit
(
2
)
.
All
(
setContextOp
(
ctx
,
_q
.
ctx
,
ent
.
OpQueryOnly
))
if
err
!=
nil
{
return
nil
,
err
}
switch
len
(
nodes
)
{
case
1
:
return
nodes
[
0
],
nil
case
0
:
return
nil
,
&
NotFoundError
{
announcement
.
Label
}
default
:
return
nil
,
&
NotSingularError
{
announcement
.
Label
}
}
}
// OnlyX is like Only, but panics if an error occurs.
func
(
_q
*
AnnouncementQuery
)
OnlyX
(
ctx
context
.
Context
)
*
Announcement
{
node
,
err
:=
_q
.
Only
(
ctx
)
if
err
!=
nil
{
panic
(
err
)
}
return
node
}
// OnlyID is like Only, but returns the only Announcement ID in the query.
// Returns a *NotSingularError when more than one Announcement ID is found.
// Returns a *NotFoundError when no entities are found.
func
(
_q
*
AnnouncementQuery
)
OnlyID
(
ctx
context
.
Context
)
(
id
int64
,
err
error
)
{
var
ids
[]
int64
if
ids
,
err
=
_q
.
Limit
(
2
)
.
IDs
(
setContextOp
(
ctx
,
_q
.
ctx
,
ent
.
OpQueryOnlyID
));
err
!=
nil
{
return
}
switch
len
(
ids
)
{
case
1
:
id
=
ids
[
0
]
case
0
:
err
=
&
NotFoundError
{
announcement
.
Label
}
default
:
err
=
&
NotSingularError
{
announcement
.
Label
}
}
return
}
// OnlyIDX is like OnlyID, but panics if an error occurs.
func
(
_q
*
AnnouncementQuery
)
OnlyIDX
(
ctx
context
.
Context
)
int64
{
id
,
err
:=
_q
.
OnlyID
(
ctx
)
if
err
!=
nil
{
panic
(
err
)
}
return
id
}
// All executes the query and returns a list of Announcements.
func
(
_q
*
AnnouncementQuery
)
All
(
ctx
context
.
Context
)
([]
*
Announcement
,
error
)
{
ctx
=
setContextOp
(
ctx
,
_q
.
ctx
,
ent
.
OpQueryAll
)
if
err
:=
_q
.
prepareQuery
(
ctx
);
err
!=
nil
{
return
nil
,
err
}
qr
:=
querierAll
[[]
*
Announcement
,
*
AnnouncementQuery
]()
return
withInterceptors
[[]
*
Announcement
](
ctx
,
_q
,
qr
,
_q
.
inters
)
}
// AllX is like All, but panics if an error occurs.
func
(
_q
*
AnnouncementQuery
)
AllX
(
ctx
context
.
Context
)
[]
*
Announcement
{
nodes
,
err
:=
_q
.
All
(
ctx
)
if
err
!=
nil
{
panic
(
err
)
}
return
nodes
}
// IDs executes the query and returns a list of Announcement IDs.
func
(
_q
*
AnnouncementQuery
)
IDs
(
ctx
context
.
Context
)
(
ids
[]
int64
,
err
error
)
{
if
_q
.
ctx
.
Unique
==
nil
&&
_q
.
path
!=
nil
{
_q
.
Unique
(
true
)
}
ctx
=
setContextOp
(
ctx
,
_q
.
ctx
,
ent
.
OpQueryIDs
)
if
err
=
_q
.
Select
(
announcement
.
FieldID
)
.
Scan
(
ctx
,
&
ids
);
err
!=
nil
{
return
nil
,
err
}
return
ids
,
nil
}
// IDsX is like IDs, but panics if an error occurs.
func
(
_q
*
AnnouncementQuery
)
IDsX
(
ctx
context
.
Context
)
[]
int64
{
ids
,
err
:=
_q
.
IDs
(
ctx
)
if
err
!=
nil
{
panic
(
err
)
}
return
ids
}
// Count returns the count of the given query.
func
(
_q
*
AnnouncementQuery
)
Count
(
ctx
context
.
Context
)
(
int
,
error
)
{
ctx
=
setContextOp
(
ctx
,
_q
.
ctx
,
ent
.
OpQueryCount
)
if
err
:=
_q
.
prepareQuery
(
ctx
);
err
!=
nil
{
return
0
,
err
}
return
withInterceptors
[
int
](
ctx
,
_q
,
querierCount
[
*
AnnouncementQuery
](),
_q
.
inters
)
}
// CountX is like Count, but panics if an error occurs.
func
(
_q
*
AnnouncementQuery
)
CountX
(
ctx
context
.
Context
)
int
{
count
,
err
:=
_q
.
Count
(
ctx
)
if
err
!=
nil
{
panic
(
err
)
}
return
count
}
// Exist returns true if the query has elements in the graph.
func
(
_q
*
AnnouncementQuery
)
Exist
(
ctx
context
.
Context
)
(
bool
,
error
)
{
ctx
=
setContextOp
(
ctx
,
_q
.
ctx
,
ent
.
OpQueryExist
)
switch
_
,
err
:=
_q
.
FirstID
(
ctx
);
{
case
IsNotFound
(
err
)
:
return
false
,
nil
case
err
!=
nil
:
return
false
,
fmt
.
Errorf
(
"ent: check existence: %w"
,
err
)
default
:
return
true
,
nil
}
}
// ExistX is like Exist, but panics if an error occurs.
func
(
_q
*
AnnouncementQuery
)
ExistX
(
ctx
context
.
Context
)
bool
{
exist
,
err
:=
_q
.
Exist
(
ctx
)
if
err
!=
nil
{
panic
(
err
)
}
return
exist
}
// Clone returns a duplicate of the AnnouncementQuery builder, including all associated steps. It can be
// used to prepare common query builders and use them differently after the clone is made.
func
(
_q
*
AnnouncementQuery
)
Clone
()
*
AnnouncementQuery
{
if
_q
==
nil
{
return
nil
}
return
&
AnnouncementQuery
{
config
:
_q
.
config
,
ctx
:
_q
.
ctx
.
Clone
(),
order
:
append
([]
announcement
.
OrderOption
{},
_q
.
order
...
),
inters
:
append
([]
Interceptor
{},
_q
.
inters
...
),
predicates
:
append
([]
predicate
.
Announcement
{},
_q
.
predicates
...
),
withReads
:
_q
.
withReads
.
Clone
(),
// clone intermediate query.
sql
:
_q
.
sql
.
Clone
(),
path
:
_q
.
path
,
}
}
// WithReads tells the query-builder to eager-load the nodes that are connected to
// the "reads" edge. The optional arguments are used to configure the query builder of the edge.
func
(
_q
*
AnnouncementQuery
)
WithReads
(
opts
...
func
(
*
AnnouncementReadQuery
))
*
AnnouncementQuery
{
query
:=
(
&
AnnouncementReadClient
{
config
:
_q
.
config
})
.
Query
()
for
_
,
opt
:=
range
opts
{
opt
(
query
)
}
_q
.
withReads
=
query
return
_q
}
// GroupBy is used to group vertices by one or more fields/columns.
// It is often used with aggregate functions, like: count, max, mean, min, sum.
//
// Example:
//
// var v []struct {
// Title string `json:"title,omitempty"`
// Count int `json:"count,omitempty"`
// }
//
// client.Announcement.Query().
// GroupBy(announcement.FieldTitle).
// Aggregate(ent.Count()).
// Scan(ctx, &v)
func
(
_q
*
AnnouncementQuery
)
GroupBy
(
field
string
,
fields
...
string
)
*
AnnouncementGroupBy
{
_q
.
ctx
.
Fields
=
append
([]
string
{
field
},
fields
...
)
grbuild
:=
&
AnnouncementGroupBy
{
build
:
_q
}
grbuild
.
flds
=
&
_q
.
ctx
.
Fields
grbuild
.
label
=
announcement
.
Label
grbuild
.
scan
=
grbuild
.
Scan
return
grbuild
}
// Select allows the selection one or more fields/columns for the given query,
// instead of selecting all fields in the entity.
//
// Example:
//
// var v []struct {
// Title string `json:"title,omitempty"`
// }
//
// client.Announcement.Query().
// Select(announcement.FieldTitle).
// Scan(ctx, &v)
func
(
_q
*
AnnouncementQuery
)
Select
(
fields
...
string
)
*
AnnouncementSelect
{
_q
.
ctx
.
Fields
=
append
(
_q
.
ctx
.
Fields
,
fields
...
)
sbuild
:=
&
AnnouncementSelect
{
AnnouncementQuery
:
_q
}
sbuild
.
label
=
announcement
.
Label
sbuild
.
flds
,
sbuild
.
scan
=
&
_q
.
ctx
.
Fields
,
sbuild
.
Scan
return
sbuild
}
// Aggregate returns a AnnouncementSelect configured with the given aggregations.
func
(
_q
*
AnnouncementQuery
)
Aggregate
(
fns
...
AggregateFunc
)
*
AnnouncementSelect
{
return
_q
.
Select
()
.
Aggregate
(
fns
...
)
}
func
(
_q
*
AnnouncementQuery
)
prepareQuery
(
ctx
context
.
Context
)
error
{
for
_
,
inter
:=
range
_q
.
inters
{
if
inter
==
nil
{
return
fmt
.
Errorf
(
"ent: uninitialized interceptor (forgotten import ent/runtime?)"
)
}
if
trv
,
ok
:=
inter
.
(
Traverser
);
ok
{
if
err
:=
trv
.
Traverse
(
ctx
,
_q
);
err
!=
nil
{
return
err
}
}
}
for
_
,
f
:=
range
_q
.
ctx
.
Fields
{
if
!
announcement
.
ValidColumn
(
f
)
{
return
&
ValidationError
{
Name
:
f
,
err
:
fmt
.
Errorf
(
"ent: invalid field %q for query"
,
f
)}
}
}
if
_q
.
path
!=
nil
{
prev
,
err
:=
_q
.
path
(
ctx
)
if
err
!=
nil
{
return
err
}
_q
.
sql
=
prev
}
return
nil
}
func
(
_q
*
AnnouncementQuery
)
sqlAll
(
ctx
context
.
Context
,
hooks
...
queryHook
)
([]
*
Announcement
,
error
)
{
var
(
nodes
=
[]
*
Announcement
{}
_spec
=
_q
.
querySpec
()
loadedTypes
=
[
1
]
bool
{
_q
.
withReads
!=
nil
,
}
)
_spec
.
ScanValues
=
func
(
columns
[]
string
)
([]
any
,
error
)
{
return
(
*
Announcement
)
.
scanValues
(
nil
,
columns
)
}
_spec
.
Assign
=
func
(
columns
[]
string
,
values
[]
any
)
error
{
node
:=
&
Announcement
{
config
:
_q
.
config
}
nodes
=
append
(
nodes
,
node
)
node
.
Edges
.
loadedTypes
=
loadedTypes
return
node
.
assignValues
(
columns
,
values
)
}
if
len
(
_q
.
modifiers
)
>
0
{
_spec
.
Modifiers
=
_q
.
modifiers
}
for
i
:=
range
hooks
{
hooks
[
i
](
ctx
,
_spec
)
}
if
err
:=
sqlgraph
.
QueryNodes
(
ctx
,
_q
.
driver
,
_spec
);
err
!=
nil
{
return
nil
,
err
}
if
len
(
nodes
)
==
0
{
return
nodes
,
nil
}
if
query
:=
_q
.
withReads
;
query
!=
nil
{
if
err
:=
_q
.
loadReads
(
ctx
,
query
,
nodes
,
func
(
n
*
Announcement
)
{
n
.
Edges
.
Reads
=
[]
*
AnnouncementRead
{}
},
func
(
n
*
Announcement
,
e
*
AnnouncementRead
)
{
n
.
Edges
.
Reads
=
append
(
n
.
Edges
.
Reads
,
e
)
});
err
!=
nil
{
return
nil
,
err
}
}
return
nodes
,
nil
}
func
(
_q
*
AnnouncementQuery
)
loadReads
(
ctx
context
.
Context
,
query
*
AnnouncementReadQuery
,
nodes
[]
*
Announcement
,
init
func
(
*
Announcement
),
assign
func
(
*
Announcement
,
*
AnnouncementRead
))
error
{
fks
:=
make
([]
driver
.
Value
,
0
,
len
(
nodes
))
nodeids
:=
make
(
map
[
int64
]
*
Announcement
)
for
i
:=
range
nodes
{
fks
=
append
(
fks
,
nodes
[
i
]
.
ID
)
nodeids
[
nodes
[
i
]
.
ID
]
=
nodes
[
i
]
if
init
!=
nil
{
init
(
nodes
[
i
])
}
}
if
len
(
query
.
ctx
.
Fields
)
>
0
{
query
.
ctx
.
AppendFieldOnce
(
announcementread
.
FieldAnnouncementID
)
}
query
.
Where
(
predicate
.
AnnouncementRead
(
func
(
s
*
sql
.
Selector
)
{
s
.
Where
(
sql
.
InValues
(
s
.
C
(
announcement
.
ReadsColumn
),
fks
...
))
}))
neighbors
,
err
:=
query
.
All
(
ctx
)
if
err
!=
nil
{
return
err
}
for
_
,
n
:=
range
neighbors
{
fk
:=
n
.
AnnouncementID
node
,
ok
:=
nodeids
[
fk
]
if
!
ok
{
return
fmt
.
Errorf
(
`unexpected referenced foreign-key "announcement_id" returned %v for node %v`
,
fk
,
n
.
ID
)
}
assign
(
node
,
n
)
}
return
nil
}
func
(
_q
*
AnnouncementQuery
)
sqlCount
(
ctx
context
.
Context
)
(
int
,
error
)
{
_spec
:=
_q
.
querySpec
()
if
len
(
_q
.
modifiers
)
>
0
{
_spec
.
Modifiers
=
_q
.
modifiers
}
_spec
.
Node
.
Columns
=
_q
.
ctx
.
Fields
if
len
(
_q
.
ctx
.
Fields
)
>
0
{
_spec
.
Unique
=
_q
.
ctx
.
Unique
!=
nil
&&
*
_q
.
ctx
.
Unique
}
return
sqlgraph
.
CountNodes
(
ctx
,
_q
.
driver
,
_spec
)
}
func
(
_q
*
AnnouncementQuery
)
querySpec
()
*
sqlgraph
.
QuerySpec
{
_spec
:=
sqlgraph
.
NewQuerySpec
(
announcement
.
Table
,
announcement
.
Columns
,
sqlgraph
.
NewFieldSpec
(
announcement
.
FieldID
,
field
.
TypeInt64
))
_spec
.
From
=
_q
.
sql
if
unique
:=
_q
.
ctx
.
Unique
;
unique
!=
nil
{
_spec
.
Unique
=
*
unique
}
else
if
_q
.
path
!=
nil
{
_spec
.
Unique
=
true
}
if
fields
:=
_q
.
ctx
.
Fields
;
len
(
fields
)
>
0
{
_spec
.
Node
.
Columns
=
make
([]
string
,
0
,
len
(
fields
))
_spec
.
Node
.
Columns
=
append
(
_spec
.
Node
.
Columns
,
announcement
.
FieldID
)
for
i
:=
range
fields
{
if
fields
[
i
]
!=
announcement
.
FieldID
{
_spec
.
Node
.
Columns
=
append
(
_spec
.
Node
.
Columns
,
fields
[
i
])
}
}
}
if
ps
:=
_q
.
predicates
;
len
(
ps
)
>
0
{
_spec
.
Predicate
=
func
(
selector
*
sql
.
Selector
)
{
for
i
:=
range
ps
{
ps
[
i
](
selector
)
}
}
}
if
limit
:=
_q
.
ctx
.
Limit
;
limit
!=
nil
{
_spec
.
Limit
=
*
limit
}
if
offset
:=
_q
.
ctx
.
Offset
;
offset
!=
nil
{
_spec
.
Offset
=
*
offset
}
if
ps
:=
_q
.
order
;
len
(
ps
)
>
0
{
_spec
.
Order
=
func
(
selector
*
sql
.
Selector
)
{
for
i
:=
range
ps
{
ps
[
i
](
selector
)
}
}
}
return
_spec
}
func
(
_q
*
AnnouncementQuery
)
sqlQuery
(
ctx
context
.
Context
)
*
sql
.
Selector
{
builder
:=
sql
.
Dialect
(
_q
.
driver
.
Dialect
())
t1
:=
builder
.
Table
(
announcement
.
Table
)
columns
:=
_q
.
ctx
.
Fields
if
len
(
columns
)
==
0
{
columns
=
announcement
.
Columns
}
selector
:=
builder
.
Select
(
t1
.
Columns
(
columns
...
)
...
)
.
From
(
t1
)
if
_q
.
sql
!=
nil
{
selector
=
_q
.
sql
selector
.
Select
(
selector
.
Columns
(
columns
...
)
...
)
}
if
_q
.
ctx
.
Unique
!=
nil
&&
*
_q
.
ctx
.
Unique
{
selector
.
Distinct
()
}
for
_
,
m
:=
range
_q
.
modifiers
{
m
(
selector
)
}
for
_
,
p
:=
range
_q
.
predicates
{
p
(
selector
)
}
for
_
,
p
:=
range
_q
.
order
{
p
(
selector
)
}
if
offset
:=
_q
.
ctx
.
Offset
;
offset
!=
nil
{
// limit is mandatory for offset clause. We start
// with default value, and override it below if needed.
selector
.
Offset
(
*
offset
)
.
Limit
(
math
.
MaxInt32
)
}
if
limit
:=
_q
.
ctx
.
Limit
;
limit
!=
nil
{
selector
.
Limit
(
*
limit
)
}
return
selector
}
// ForUpdate locks the selected rows against concurrent updates, and prevent them from being
// updated, deleted or "selected ... for update" by other sessions, until the transaction is
// either committed or rolled-back.
func
(
_q
*
AnnouncementQuery
)
ForUpdate
(
opts
...
sql
.
LockOption
)
*
AnnouncementQuery
{
if
_q
.
driver
.
Dialect
()
==
dialect
.
Postgres
{
_q
.
Unique
(
false
)
}
_q
.
modifiers
=
append
(
_q
.
modifiers
,
func
(
s
*
sql
.
Selector
)
{
s
.
ForUpdate
(
opts
...
)
})
return
_q
}
// ForShare behaves similarly to ForUpdate, except that it acquires a shared mode lock
// on any rows that are read. Other sessions can read the rows, but cannot modify them
// until your transaction commits.
func
(
_q
*
AnnouncementQuery
)
ForShare
(
opts
...
sql
.
LockOption
)
*
AnnouncementQuery
{
if
_q
.
driver
.
Dialect
()
==
dialect
.
Postgres
{
_q
.
Unique
(
false
)
}
_q
.
modifiers
=
append
(
_q
.
modifiers
,
func
(
s
*
sql
.
Selector
)
{
s
.
ForShare
(
opts
...
)
})
return
_q
}
// AnnouncementGroupBy is the group-by builder for Announcement entities.
type
AnnouncementGroupBy
struct
{
selector
build
*
AnnouncementQuery
}
// Aggregate adds the given aggregation functions to the group-by query.
func
(
_g
*
AnnouncementGroupBy
)
Aggregate
(
fns
...
AggregateFunc
)
*
AnnouncementGroupBy
{
_g
.
fns
=
append
(
_g
.
fns
,
fns
...
)
return
_g
}
// Scan applies the selector query and scans the result into the given value.
func
(
_g
*
AnnouncementGroupBy
)
Scan
(
ctx
context
.
Context
,
v
any
)
error
{
ctx
=
setContextOp
(
ctx
,
_g
.
build
.
ctx
,
ent
.
OpQueryGroupBy
)
if
err
:=
_g
.
build
.
prepareQuery
(
ctx
);
err
!=
nil
{
return
err
}
return
scanWithInterceptors
[
*
AnnouncementQuery
,
*
AnnouncementGroupBy
](
ctx
,
_g
.
build
,
_g
,
_g
.
build
.
inters
,
v
)
}
func
(
_g
*
AnnouncementGroupBy
)
sqlScan
(
ctx
context
.
Context
,
root
*
AnnouncementQuery
,
v
any
)
error
{
selector
:=
root
.
sqlQuery
(
ctx
)
.
Select
()
aggregation
:=
make
([]
string
,
0
,
len
(
_g
.
fns
))
for
_
,
fn
:=
range
_g
.
fns
{
aggregation
=
append
(
aggregation
,
fn
(
selector
))
}
if
len
(
selector
.
SelectedColumns
())
==
0
{
columns
:=
make
([]
string
,
0
,
len
(
*
_g
.
flds
)
+
len
(
_g
.
fns
))
for
_
,
f
:=
range
*
_g
.
flds
{
columns
=
append
(
columns
,
selector
.
C
(
f
))
}
columns
=
append
(
columns
,
aggregation
...
)
selector
.
Select
(
columns
...
)
}
selector
.
GroupBy
(
selector
.
Columns
(
*
_g
.
flds
...
)
...
)
if
err
:=
selector
.
Err
();
err
!=
nil
{
return
err
}
rows
:=
&
sql
.
Rows
{}
query
,
args
:=
selector
.
Query
()
if
err
:=
_g
.
build
.
driver
.
Query
(
ctx
,
query
,
args
,
rows
);
err
!=
nil
{
return
err
}
defer
rows
.
Close
()
return
sql
.
ScanSlice
(
rows
,
v
)
}
// AnnouncementSelect is the builder for selecting fields of Announcement entities.
type
AnnouncementSelect
struct
{
*
AnnouncementQuery
selector
}
// Aggregate adds the given aggregation functions to the selector query.
func
(
_s
*
AnnouncementSelect
)
Aggregate
(
fns
...
AggregateFunc
)
*
AnnouncementSelect
{
_s
.
fns
=
append
(
_s
.
fns
,
fns
...
)
return
_s
}
// Scan applies the selector query and scans the result into the given value.
func
(
_s
*
AnnouncementSelect
)
Scan
(
ctx
context
.
Context
,
v
any
)
error
{
ctx
=
setContextOp
(
ctx
,
_s
.
ctx
,
ent
.
OpQuerySelect
)
if
err
:=
_s
.
prepareQuery
(
ctx
);
err
!=
nil
{
return
err
}
return
scanWithInterceptors
[
*
AnnouncementQuery
,
*
AnnouncementSelect
](
ctx
,
_s
.
AnnouncementQuery
,
_s
,
_s
.
inters
,
v
)
}
func
(
_s
*
AnnouncementSelect
)
sqlScan
(
ctx
context
.
Context
,
root
*
AnnouncementQuery
,
v
any
)
error
{
selector
:=
root
.
sqlQuery
(
ctx
)
aggregation
:=
make
([]
string
,
0
,
len
(
_s
.
fns
))
for
_
,
fn
:=
range
_s
.
fns
{
aggregation
=
append
(
aggregation
,
fn
(
selector
))
}
switch
n
:=
len
(
*
_s
.
selector
.
flds
);
{
case
n
==
0
&&
len
(
aggregation
)
>
0
:
selector
.
Select
(
aggregation
...
)
case
n
!=
0
&&
len
(
aggregation
)
>
0
:
selector
.
AppendSelect
(
aggregation
...
)
}
rows
:=
&
sql
.
Rows
{}
query
,
args
:=
selector
.
Query
()
if
err
:=
_s
.
driver
.
Query
(
ctx
,
query
,
args
,
rows
);
err
!=
nil
{
return
err
}
defer
rows
.
Close
()
return
sql
.
ScanSlice
(
rows
,
v
)
}
backend/ent/announcement_update.go
0 → 100644
View file @
0170d19f
This diff is collapsed.
Click to expand it.
backend/ent/announcementread.go
0 → 100644
View file @
0170d19f
// Code generated by ent, DO NOT EDIT.
package
ent
import
(
"fmt"
"strings"
"time"
"entgo.io/ent"
"entgo.io/ent/dialect/sql"
"github.com/Wei-Shaw/sub2api/ent/announcement"
"github.com/Wei-Shaw/sub2api/ent/announcementread"
"github.com/Wei-Shaw/sub2api/ent/user"
)
// AnnouncementRead is the model entity for the AnnouncementRead schema.
type
AnnouncementRead
struct
{
config
`json:"-"`
// ID of the ent.
ID
int64
`json:"id,omitempty"`
// AnnouncementID holds the value of the "announcement_id" field.
AnnouncementID
int64
`json:"announcement_id,omitempty"`
// UserID holds the value of the "user_id" field.
UserID
int64
`json:"user_id,omitempty"`
// 用户首次已读时间
ReadAt
time
.
Time
`json:"read_at,omitempty"`
// CreatedAt holds the value of the "created_at" field.
CreatedAt
time
.
Time
`json:"created_at,omitempty"`
// Edges holds the relations/edges for other nodes in the graph.
// The values are being populated by the AnnouncementReadQuery when eager-loading is set.
Edges
AnnouncementReadEdges
`json:"edges"`
selectValues
sql
.
SelectValues
}
// AnnouncementReadEdges holds the relations/edges for other nodes in the graph.
type
AnnouncementReadEdges
struct
{
// Announcement holds the value of the announcement edge.
Announcement
*
Announcement
`json:"announcement,omitempty"`
// User holds the value of the user edge.
User
*
User
`json:"user,omitempty"`
// loadedTypes holds the information for reporting if a
// type was loaded (or requested) in eager-loading or not.
loadedTypes
[
2
]
bool
}
// AnnouncementOrErr returns the Announcement value or an error if the edge
// was not loaded in eager-loading, or loaded but was not found.
func
(
e
AnnouncementReadEdges
)
AnnouncementOrErr
()
(
*
Announcement
,
error
)
{
if
e
.
Announcement
!=
nil
{
return
e
.
Announcement
,
nil
}
else
if
e
.
loadedTypes
[
0
]
{
return
nil
,
&
NotFoundError
{
label
:
announcement
.
Label
}
}
return
nil
,
&
NotLoadedError
{
edge
:
"announcement"
}
}
// UserOrErr returns the User value or an error if the edge
// was not loaded in eager-loading, or loaded but was not found.
func
(
e
AnnouncementReadEdges
)
UserOrErr
()
(
*
User
,
error
)
{
if
e
.
User
!=
nil
{
return
e
.
User
,
nil
}
else
if
e
.
loadedTypes
[
1
]
{
return
nil
,
&
NotFoundError
{
label
:
user
.
Label
}
}
return
nil
,
&
NotLoadedError
{
edge
:
"user"
}
}
// scanValues returns the types for scanning values from sql.Rows.
func
(
*
AnnouncementRead
)
scanValues
(
columns
[]
string
)
([]
any
,
error
)
{
values
:=
make
([]
any
,
len
(
columns
))
for
i
:=
range
columns
{
switch
columns
[
i
]
{
case
announcementread
.
FieldID
,
announcementread
.
FieldAnnouncementID
,
announcementread
.
FieldUserID
:
values
[
i
]
=
new
(
sql
.
NullInt64
)
case
announcementread
.
FieldReadAt
,
announcementread
.
FieldCreatedAt
:
values
[
i
]
=
new
(
sql
.
NullTime
)
default
:
values
[
i
]
=
new
(
sql
.
UnknownType
)
}
}
return
values
,
nil
}
// assignValues assigns the values that were returned from sql.Rows (after scanning)
// to the AnnouncementRead fields.
func
(
_m
*
AnnouncementRead
)
assignValues
(
columns
[]
string
,
values
[]
any
)
error
{
if
m
,
n
:=
len
(
values
),
len
(
columns
);
m
<
n
{
return
fmt
.
Errorf
(
"mismatch number of scan values: %d != %d"
,
m
,
n
)
}
for
i
:=
range
columns
{
switch
columns
[
i
]
{
case
announcementread
.
FieldID
:
value
,
ok
:=
values
[
i
]
.
(
*
sql
.
NullInt64
)
if
!
ok
{
return
fmt
.
Errorf
(
"unexpected type %T for field id"
,
value
)
}
_m
.
ID
=
int64
(
value
.
Int64
)
case
announcementread
.
FieldAnnouncementID
:
if
value
,
ok
:=
values
[
i
]
.
(
*
sql
.
NullInt64
);
!
ok
{
return
fmt
.
Errorf
(
"unexpected type %T for field announcement_id"
,
values
[
i
])
}
else
if
value
.
Valid
{
_m
.
AnnouncementID
=
value
.
Int64
}
case
announcementread
.
FieldUserID
:
if
value
,
ok
:=
values
[
i
]
.
(
*
sql
.
NullInt64
);
!
ok
{
return
fmt
.
Errorf
(
"unexpected type %T for field user_id"
,
values
[
i
])
}
else
if
value
.
Valid
{
_m
.
UserID
=
value
.
Int64
}
case
announcementread
.
FieldReadAt
:
if
value
,
ok
:=
values
[
i
]
.
(
*
sql
.
NullTime
);
!
ok
{
return
fmt
.
Errorf
(
"unexpected type %T for field read_at"
,
values
[
i
])
}
else
if
value
.
Valid
{
_m
.
ReadAt
=
value
.
Time
}
case
announcementread
.
FieldCreatedAt
:
if
value
,
ok
:=
values
[
i
]
.
(
*
sql
.
NullTime
);
!
ok
{
return
fmt
.
Errorf
(
"unexpected type %T for field created_at"
,
values
[
i
])
}
else
if
value
.
Valid
{
_m
.
CreatedAt
=
value
.
Time
}
default
:
_m
.
selectValues
.
Set
(
columns
[
i
],
values
[
i
])
}
}
return
nil
}
// Value returns the ent.Value that was dynamically selected and assigned to the AnnouncementRead.
// This includes values selected through modifiers, order, etc.
func
(
_m
*
AnnouncementRead
)
Value
(
name
string
)
(
ent
.
Value
,
error
)
{
return
_m
.
selectValues
.
Get
(
name
)
}
// QueryAnnouncement queries the "announcement" edge of the AnnouncementRead entity.
func
(
_m
*
AnnouncementRead
)
QueryAnnouncement
()
*
AnnouncementQuery
{
return
NewAnnouncementReadClient
(
_m
.
config
)
.
QueryAnnouncement
(
_m
)
}
// QueryUser queries the "user" edge of the AnnouncementRead entity.
func
(
_m
*
AnnouncementRead
)
QueryUser
()
*
UserQuery
{
return
NewAnnouncementReadClient
(
_m
.
config
)
.
QueryUser
(
_m
)
}
// Update returns a builder for updating this AnnouncementRead.
// Note that you need to call AnnouncementRead.Unwrap() before calling this method if this AnnouncementRead
// was returned from a transaction, and the transaction was committed or rolled back.
func
(
_m
*
AnnouncementRead
)
Update
()
*
AnnouncementReadUpdateOne
{
return
NewAnnouncementReadClient
(
_m
.
config
)
.
UpdateOne
(
_m
)
}
// Unwrap unwraps the AnnouncementRead entity that was returned from a transaction after it was closed,
// so that all future queries will be executed through the driver which created the transaction.
func
(
_m
*
AnnouncementRead
)
Unwrap
()
*
AnnouncementRead
{
_tx
,
ok
:=
_m
.
config
.
driver
.
(
*
txDriver
)
if
!
ok
{
panic
(
"ent: AnnouncementRead is not a transactional entity"
)
}
_m
.
config
.
driver
=
_tx
.
drv
return
_m
}
// String implements the fmt.Stringer.
func
(
_m
*
AnnouncementRead
)
String
()
string
{
var
builder
strings
.
Builder
builder
.
WriteString
(
"AnnouncementRead("
)
builder
.
WriteString
(
fmt
.
Sprintf
(
"id=%v, "
,
_m
.
ID
))
builder
.
WriteString
(
"announcement_id="
)
builder
.
WriteString
(
fmt
.
Sprintf
(
"%v"
,
_m
.
AnnouncementID
))
builder
.
WriteString
(
", "
)
builder
.
WriteString
(
"user_id="
)
builder
.
WriteString
(
fmt
.
Sprintf
(
"%v"
,
_m
.
UserID
))
builder
.
WriteString
(
", "
)
builder
.
WriteString
(
"read_at="
)
builder
.
WriteString
(
_m
.
ReadAt
.
Format
(
time
.
ANSIC
))
builder
.
WriteString
(
", "
)
builder
.
WriteString
(
"created_at="
)
builder
.
WriteString
(
_m
.
CreatedAt
.
Format
(
time
.
ANSIC
))
builder
.
WriteByte
(
')'
)
return
builder
.
String
()
}
// AnnouncementReads is a parsable slice of AnnouncementRead.
type
AnnouncementReads
[]
*
AnnouncementRead
backend/ent/announcementread/announcementread.go
0 → 100644
View file @
0170d19f
// Code generated by ent, DO NOT EDIT.
package
announcementread
import
(
"time"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
)
const
(
// Label holds the string label denoting the announcementread type in the database.
Label
=
"announcement_read"
// FieldID holds the string denoting the id field in the database.
FieldID
=
"id"
// FieldAnnouncementID holds the string denoting the announcement_id field in the database.
FieldAnnouncementID
=
"announcement_id"
// FieldUserID holds the string denoting the user_id field in the database.
FieldUserID
=
"user_id"
// FieldReadAt holds the string denoting the read_at field in the database.
FieldReadAt
=
"read_at"
// FieldCreatedAt holds the string denoting the created_at field in the database.
FieldCreatedAt
=
"created_at"
// EdgeAnnouncement holds the string denoting the announcement edge name in mutations.
EdgeAnnouncement
=
"announcement"
// EdgeUser holds the string denoting the user edge name in mutations.
EdgeUser
=
"user"
// Table holds the table name of the announcementread in the database.
Table
=
"announcement_reads"
// AnnouncementTable is the table that holds the announcement relation/edge.
AnnouncementTable
=
"announcement_reads"
// AnnouncementInverseTable is the table name for the Announcement entity.
// It exists in this package in order to avoid circular dependency with the "announcement" package.
AnnouncementInverseTable
=
"announcements"
// AnnouncementColumn is the table column denoting the announcement relation/edge.
AnnouncementColumn
=
"announcement_id"
// UserTable is the table that holds the user relation/edge.
UserTable
=
"announcement_reads"
// UserInverseTable is the table name for the User entity.
// It exists in this package in order to avoid circular dependency with the "user" package.
UserInverseTable
=
"users"
// UserColumn is the table column denoting the user relation/edge.
UserColumn
=
"user_id"
)
// Columns holds all SQL columns for announcementread fields.
var
Columns
=
[]
string
{
FieldID
,
FieldAnnouncementID
,
FieldUserID
,
FieldReadAt
,
FieldCreatedAt
,
}
// ValidColumn reports if the column name is valid (part of the table columns).
func
ValidColumn
(
column
string
)
bool
{
for
i
:=
range
Columns
{
if
column
==
Columns
[
i
]
{
return
true
}
}
return
false
}
var
(
// DefaultReadAt holds the default value on creation for the "read_at" field.
DefaultReadAt
func
()
time
.
Time
// DefaultCreatedAt holds the default value on creation for the "created_at" field.
DefaultCreatedAt
func
()
time
.
Time
)
// OrderOption defines the ordering options for the AnnouncementRead queries.
type
OrderOption
func
(
*
sql
.
Selector
)
// ByID orders the results by the id field.
func
ByID
(
opts
...
sql
.
OrderTermOption
)
OrderOption
{
return
sql
.
OrderByField
(
FieldID
,
opts
...
)
.
ToFunc
()
}
// ByAnnouncementID orders the results by the announcement_id field.
func
ByAnnouncementID
(
opts
...
sql
.
OrderTermOption
)
OrderOption
{
return
sql
.
OrderByField
(
FieldAnnouncementID
,
opts
...
)
.
ToFunc
()
}
// ByUserID orders the results by the user_id field.
func
ByUserID
(
opts
...
sql
.
OrderTermOption
)
OrderOption
{
return
sql
.
OrderByField
(
FieldUserID
,
opts
...
)
.
ToFunc
()
}
// ByReadAt orders the results by the read_at field.
func
ByReadAt
(
opts
...
sql
.
OrderTermOption
)
OrderOption
{
return
sql
.
OrderByField
(
FieldReadAt
,
opts
...
)
.
ToFunc
()
}
// ByCreatedAt orders the results by the created_at field.
func
ByCreatedAt
(
opts
...
sql
.
OrderTermOption
)
OrderOption
{
return
sql
.
OrderByField
(
FieldCreatedAt
,
opts
...
)
.
ToFunc
()
}
// ByAnnouncementField orders the results by announcement field.
func
ByAnnouncementField
(
field
string
,
opts
...
sql
.
OrderTermOption
)
OrderOption
{
return
func
(
s
*
sql
.
Selector
)
{
sqlgraph
.
OrderByNeighborTerms
(
s
,
newAnnouncementStep
(),
sql
.
OrderByField
(
field
,
opts
...
))
}
}
// ByUserField orders the results by user field.
func
ByUserField
(
field
string
,
opts
...
sql
.
OrderTermOption
)
OrderOption
{
return
func
(
s
*
sql
.
Selector
)
{
sqlgraph
.
OrderByNeighborTerms
(
s
,
newUserStep
(),
sql
.
OrderByField
(
field
,
opts
...
))
}
}
func
newAnnouncementStep
()
*
sqlgraph
.
Step
{
return
sqlgraph
.
NewStep
(
sqlgraph
.
From
(
Table
,
FieldID
),
sqlgraph
.
To
(
AnnouncementInverseTable
,
FieldID
),
sqlgraph
.
Edge
(
sqlgraph
.
M2O
,
true
,
AnnouncementTable
,
AnnouncementColumn
),
)
}
func
newUserStep
()
*
sqlgraph
.
Step
{
return
sqlgraph
.
NewStep
(
sqlgraph
.
From
(
Table
,
FieldID
),
sqlgraph
.
To
(
UserInverseTable
,
FieldID
),
sqlgraph
.
Edge
(
sqlgraph
.
M2O
,
true
,
UserTable
,
UserColumn
),
)
}
backend/ent/announcementread/where.go
0 → 100644
View file @
0170d19f
// Code generated by ent, DO NOT EDIT.
package
announcementread
import
(
"time"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
"github.com/Wei-Shaw/sub2api/ent/predicate"
)
// ID filters vertices based on their ID field.
func
ID
(
id
int64
)
predicate
.
AnnouncementRead
{
return
predicate
.
AnnouncementRead
(
sql
.
FieldEQ
(
FieldID
,
id
))
}
// IDEQ applies the EQ predicate on the ID field.
func
IDEQ
(
id
int64
)
predicate
.
AnnouncementRead
{
return
predicate
.
AnnouncementRead
(
sql
.
FieldEQ
(
FieldID
,
id
))
}
// IDNEQ applies the NEQ predicate on the ID field.
func
IDNEQ
(
id
int64
)
predicate
.
AnnouncementRead
{
return
predicate
.
AnnouncementRead
(
sql
.
FieldNEQ
(
FieldID
,
id
))
}
// IDIn applies the In predicate on the ID field.
func
IDIn
(
ids
...
int64
)
predicate
.
AnnouncementRead
{
return
predicate
.
AnnouncementRead
(
sql
.
FieldIn
(
FieldID
,
ids
...
))
}
// IDNotIn applies the NotIn predicate on the ID field.
func
IDNotIn
(
ids
...
int64
)
predicate
.
AnnouncementRead
{
return
predicate
.
AnnouncementRead
(
sql
.
FieldNotIn
(
FieldID
,
ids
...
))
}
// IDGT applies the GT predicate on the ID field.
func
IDGT
(
id
int64
)
predicate
.
AnnouncementRead
{
return
predicate
.
AnnouncementRead
(
sql
.
FieldGT
(
FieldID
,
id
))
}
// IDGTE applies the GTE predicate on the ID field.
func
IDGTE
(
id
int64
)
predicate
.
AnnouncementRead
{
return
predicate
.
AnnouncementRead
(
sql
.
FieldGTE
(
FieldID
,
id
))
}
// IDLT applies the LT predicate on the ID field.
func
IDLT
(
id
int64
)
predicate
.
AnnouncementRead
{
return
predicate
.
AnnouncementRead
(
sql
.
FieldLT
(
FieldID
,
id
))
}
// IDLTE applies the LTE predicate on the ID field.
func
IDLTE
(
id
int64
)
predicate
.
AnnouncementRead
{
return
predicate
.
AnnouncementRead
(
sql
.
FieldLTE
(
FieldID
,
id
))
}
// AnnouncementID applies equality check predicate on the "announcement_id" field. It's identical to AnnouncementIDEQ.
func
AnnouncementID
(
v
int64
)
predicate
.
AnnouncementRead
{
return
predicate
.
AnnouncementRead
(
sql
.
FieldEQ
(
FieldAnnouncementID
,
v
))
}
// UserID applies equality check predicate on the "user_id" field. It's identical to UserIDEQ.
func
UserID
(
v
int64
)
predicate
.
AnnouncementRead
{
return
predicate
.
AnnouncementRead
(
sql
.
FieldEQ
(
FieldUserID
,
v
))
}
// ReadAt applies equality check predicate on the "read_at" field. It's identical to ReadAtEQ.
func
ReadAt
(
v
time
.
Time
)
predicate
.
AnnouncementRead
{
return
predicate
.
AnnouncementRead
(
sql
.
FieldEQ
(
FieldReadAt
,
v
))
}
// CreatedAt applies equality check predicate on the "created_at" field. It's identical to CreatedAtEQ.
func
CreatedAt
(
v
time
.
Time
)
predicate
.
AnnouncementRead
{
return
predicate
.
AnnouncementRead
(
sql
.
FieldEQ
(
FieldCreatedAt
,
v
))
}
// AnnouncementIDEQ applies the EQ predicate on the "announcement_id" field.
func
AnnouncementIDEQ
(
v
int64
)
predicate
.
AnnouncementRead
{
return
predicate
.
AnnouncementRead
(
sql
.
FieldEQ
(
FieldAnnouncementID
,
v
))
}
// AnnouncementIDNEQ applies the NEQ predicate on the "announcement_id" field.
func
AnnouncementIDNEQ
(
v
int64
)
predicate
.
AnnouncementRead
{
return
predicate
.
AnnouncementRead
(
sql
.
FieldNEQ
(
FieldAnnouncementID
,
v
))
}
// AnnouncementIDIn applies the In predicate on the "announcement_id" field.
func
AnnouncementIDIn
(
vs
...
int64
)
predicate
.
AnnouncementRead
{
return
predicate
.
AnnouncementRead
(
sql
.
FieldIn
(
FieldAnnouncementID
,
vs
...
))
}
// AnnouncementIDNotIn applies the NotIn predicate on the "announcement_id" field.
func
AnnouncementIDNotIn
(
vs
...
int64
)
predicate
.
AnnouncementRead
{
return
predicate
.
AnnouncementRead
(
sql
.
FieldNotIn
(
FieldAnnouncementID
,
vs
...
))
}
// UserIDEQ applies the EQ predicate on the "user_id" field.
func
UserIDEQ
(
v
int64
)
predicate
.
AnnouncementRead
{
return
predicate
.
AnnouncementRead
(
sql
.
FieldEQ
(
FieldUserID
,
v
))
}
// UserIDNEQ applies the NEQ predicate on the "user_id" field.
func
UserIDNEQ
(
v
int64
)
predicate
.
AnnouncementRead
{
return
predicate
.
AnnouncementRead
(
sql
.
FieldNEQ
(
FieldUserID
,
v
))
}
// UserIDIn applies the In predicate on the "user_id" field.
func
UserIDIn
(
vs
...
int64
)
predicate
.
AnnouncementRead
{
return
predicate
.
AnnouncementRead
(
sql
.
FieldIn
(
FieldUserID
,
vs
...
))
}
// UserIDNotIn applies the NotIn predicate on the "user_id" field.
func
UserIDNotIn
(
vs
...
int64
)
predicate
.
AnnouncementRead
{
return
predicate
.
AnnouncementRead
(
sql
.
FieldNotIn
(
FieldUserID
,
vs
...
))
}
// ReadAtEQ applies the EQ predicate on the "read_at" field.
func
ReadAtEQ
(
v
time
.
Time
)
predicate
.
AnnouncementRead
{
return
predicate
.
AnnouncementRead
(
sql
.
FieldEQ
(
FieldReadAt
,
v
))
}
// ReadAtNEQ applies the NEQ predicate on the "read_at" field.
func
ReadAtNEQ
(
v
time
.
Time
)
predicate
.
AnnouncementRead
{
return
predicate
.
AnnouncementRead
(
sql
.
FieldNEQ
(
FieldReadAt
,
v
))
}
// ReadAtIn applies the In predicate on the "read_at" field.
func
ReadAtIn
(
vs
...
time
.
Time
)
predicate
.
AnnouncementRead
{
return
predicate
.
AnnouncementRead
(
sql
.
FieldIn
(
FieldReadAt
,
vs
...
))
}
// ReadAtNotIn applies the NotIn predicate on the "read_at" field.
func
ReadAtNotIn
(
vs
...
time
.
Time
)
predicate
.
AnnouncementRead
{
return
predicate
.
AnnouncementRead
(
sql
.
FieldNotIn
(
FieldReadAt
,
vs
...
))
}
// ReadAtGT applies the GT predicate on the "read_at" field.
func
ReadAtGT
(
v
time
.
Time
)
predicate
.
AnnouncementRead
{
return
predicate
.
AnnouncementRead
(
sql
.
FieldGT
(
FieldReadAt
,
v
))
}
// ReadAtGTE applies the GTE predicate on the "read_at" field.
func
ReadAtGTE
(
v
time
.
Time
)
predicate
.
AnnouncementRead
{
return
predicate
.
AnnouncementRead
(
sql
.
FieldGTE
(
FieldReadAt
,
v
))
}
// ReadAtLT applies the LT predicate on the "read_at" field.
func
ReadAtLT
(
v
time
.
Time
)
predicate
.
AnnouncementRead
{
return
predicate
.
AnnouncementRead
(
sql
.
FieldLT
(
FieldReadAt
,
v
))
}
// ReadAtLTE applies the LTE predicate on the "read_at" field.
func
ReadAtLTE
(
v
time
.
Time
)
predicate
.
AnnouncementRead
{
return
predicate
.
AnnouncementRead
(
sql
.
FieldLTE
(
FieldReadAt
,
v
))
}
// CreatedAtEQ applies the EQ predicate on the "created_at" field.
func
CreatedAtEQ
(
v
time
.
Time
)
predicate
.
AnnouncementRead
{
return
predicate
.
AnnouncementRead
(
sql
.
FieldEQ
(
FieldCreatedAt
,
v
))
}
// CreatedAtNEQ applies the NEQ predicate on the "created_at" field.
func
CreatedAtNEQ
(
v
time
.
Time
)
predicate
.
AnnouncementRead
{
return
predicate
.
AnnouncementRead
(
sql
.
FieldNEQ
(
FieldCreatedAt
,
v
))
}
// CreatedAtIn applies the In predicate on the "created_at" field.
func
CreatedAtIn
(
vs
...
time
.
Time
)
predicate
.
AnnouncementRead
{
return
predicate
.
AnnouncementRead
(
sql
.
FieldIn
(
FieldCreatedAt
,
vs
...
))
}
// CreatedAtNotIn applies the NotIn predicate on the "created_at" field.
func
CreatedAtNotIn
(
vs
...
time
.
Time
)
predicate
.
AnnouncementRead
{
return
predicate
.
AnnouncementRead
(
sql
.
FieldNotIn
(
FieldCreatedAt
,
vs
...
))
}
// CreatedAtGT applies the GT predicate on the "created_at" field.
func
CreatedAtGT
(
v
time
.
Time
)
predicate
.
AnnouncementRead
{
return
predicate
.
AnnouncementRead
(
sql
.
FieldGT
(
FieldCreatedAt
,
v
))
}
// CreatedAtGTE applies the GTE predicate on the "created_at" field.
func
CreatedAtGTE
(
v
time
.
Time
)
predicate
.
AnnouncementRead
{
return
predicate
.
AnnouncementRead
(
sql
.
FieldGTE
(
FieldCreatedAt
,
v
))
}
// CreatedAtLT applies the LT predicate on the "created_at" field.
func
CreatedAtLT
(
v
time
.
Time
)
predicate
.
AnnouncementRead
{
return
predicate
.
AnnouncementRead
(
sql
.
FieldLT
(
FieldCreatedAt
,
v
))
}
// CreatedAtLTE applies the LTE predicate on the "created_at" field.
func
CreatedAtLTE
(
v
time
.
Time
)
predicate
.
AnnouncementRead
{
return
predicate
.
AnnouncementRead
(
sql
.
FieldLTE
(
FieldCreatedAt
,
v
))
}
// HasAnnouncement applies the HasEdge predicate on the "announcement" edge.
func
HasAnnouncement
()
predicate
.
AnnouncementRead
{
return
predicate
.
AnnouncementRead
(
func
(
s
*
sql
.
Selector
)
{
step
:=
sqlgraph
.
NewStep
(
sqlgraph
.
From
(
Table
,
FieldID
),
sqlgraph
.
Edge
(
sqlgraph
.
M2O
,
true
,
AnnouncementTable
,
AnnouncementColumn
),
)
sqlgraph
.
HasNeighbors
(
s
,
step
)
})
}
// HasAnnouncementWith applies the HasEdge predicate on the "announcement" edge with a given conditions (other predicates).
func
HasAnnouncementWith
(
preds
...
predicate
.
Announcement
)
predicate
.
AnnouncementRead
{
return
predicate
.
AnnouncementRead
(
func
(
s
*
sql
.
Selector
)
{
step
:=
newAnnouncementStep
()
sqlgraph
.
HasNeighborsWith
(
s
,
step
,
func
(
s
*
sql
.
Selector
)
{
for
_
,
p
:=
range
preds
{
p
(
s
)
}
})
})
}
// HasUser applies the HasEdge predicate on the "user" edge.
func
HasUser
()
predicate
.
AnnouncementRead
{
return
predicate
.
AnnouncementRead
(
func
(
s
*
sql
.
Selector
)
{
step
:=
sqlgraph
.
NewStep
(
sqlgraph
.
From
(
Table
,
FieldID
),
sqlgraph
.
Edge
(
sqlgraph
.
M2O
,
true
,
UserTable
,
UserColumn
),
)
sqlgraph
.
HasNeighbors
(
s
,
step
)
})
}
// HasUserWith applies the HasEdge predicate on the "user" edge with a given conditions (other predicates).
func
HasUserWith
(
preds
...
predicate
.
User
)
predicate
.
AnnouncementRead
{
return
predicate
.
AnnouncementRead
(
func
(
s
*
sql
.
Selector
)
{
step
:=
newUserStep
()
sqlgraph
.
HasNeighborsWith
(
s
,
step
,
func
(
s
*
sql
.
Selector
)
{
for
_
,
p
:=
range
preds
{
p
(
s
)
}
})
})
}
// And groups predicates with the AND operator between them.
func
And
(
predicates
...
predicate
.
AnnouncementRead
)
predicate
.
AnnouncementRead
{
return
predicate
.
AnnouncementRead
(
sql
.
AndPredicates
(
predicates
...
))
}
// Or groups predicates with the OR operator between them.
func
Or
(
predicates
...
predicate
.
AnnouncementRead
)
predicate
.
AnnouncementRead
{
return
predicate
.
AnnouncementRead
(
sql
.
OrPredicates
(
predicates
...
))
}
// Not applies the not operator on the given predicate.
func
Not
(
p
predicate
.
AnnouncementRead
)
predicate
.
AnnouncementRead
{
return
predicate
.
AnnouncementRead
(
sql
.
NotPredicates
(
p
))
}
Prev
1
2
3
4
5
…
16
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment