Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
直接コマンドでは確認用 Prompt が省略されます。実行前にソースを確認してください。
npx skills add https://github.com/voidvec/fulla --skill orm-genコマンドは1行のまま表示されます。コピー前に横へスクロールして全体を確認してください。
ローカルで確認しますか?SkillsMP が現在取得できるファイルをダウンロードできます。
SKILL.md を表示中
| name | orm-gen |
| description | 重新生成 Drogon ORM 模型类(基于当前数据库表结构) |
| disable-model-invocation | true |
重新生成 Drogon ORM 模型类以匹配最新的数据库表结构。
通过用户调用:/orm-gen
# 1. 检查 PostgreSQL 服务是否运行
pg_isready -h localhost -p 5432 || echo "❌ PostgreSQL not running"
# 2. 检查数据库是否存在
export PGPASSWORD='123456'
psql -h localhost -U fulla_user -d fulla_db -c "SELECT 1;" || echo "❌ Database fulla_db not found"
# 3. 检查 drogon_ctl 工具是否安装
which drogon_ctl || echo "❌ drogon_ctl not found"
drogon_ctl version || echo "❌ drogon_ctl not working"
# 4. 检查 models 目录是否存在
ls libs/storage-postgres/src/models/model.json || echo "❌ model.json not found"
# 查看当前数据库中的所有表
export PGPASSWORD='123456'
psql -h localhost -U fulla_user -d fulla_db -c "\dt"
# 预期输出应包含全部19个表:
# - organizations, users, roles, permissions
# - user_roles, role_permissions
# - oauth2_clients, oauth2_codes, oauth2_access_tokens, oauth2_refresh_tokens
# - oauth2_scopes, oauth2_client_scopes, oauth2_user_consents
# - oauth2_subject_mappings, audit_logs
# - email_verification_tokens, password_reset_tokens
# - oauth2_device_codes, webauthn_credentials
# 查看当前 ORM 生成配置
cat libs/storage-postgres/src/models/model.json
标准配置:
{
"rdbms": "postgresql",
"host": "127.0.0.1",
"port": 5432,
"dbname": "fulla_db",
"user": "fulla_user",
"passwd": "123456",
"tables": [
"organizations", "users", "roles", "permissions",
"user_roles", "role_permissions",
"oauth2_clients", "oauth2_codes", "oauth2_access_tokens", "oauth2_refresh_tokens",
"oauth2_scopes", "oauth2_client_scopes", "oauth2_user_consents",
"oauth2_subject_mappings",
# Windows PowerShell
cd apps/server
$timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
$backupDir = "models_backup_$timestamp"
New-Item -ItemType Directory -Path $backupDir | Out-Null
# 备份模型文件(如果存在)
if (Test-Path "model.json") {
Copy-Item model.json $backupDir\
}
if (Test-Path "models") {
Copy-Item models\*.h, models\*.cc $backupDir\ 2>$null
}
Write-Host "✅ Models backed up to $backupDir"
# Linux/macOS
cd apps/server
timestamp=$(date +%Y%m%d_%H%M%S)
backup_dir="models_backup_$timestamp"
mkdir -p $backup_dir
# 备份模型文件
cp model.json $backup_dir/ 2>/dev/null || true
cp models/*.h models/*.cc $backup_dir/ 2>/dev/null || true
echo "✅ Models backed up to $backup_dir"
# Windows PowerShell
# 进入 ORM 模型源码目录(.cc 所在)
cd d:\work\development\Repos\cpp\projects\fulla\libs\storage-postgres\src\models
# 创建 models 目录(如果不存在)
if (!(Test-Path "models")) {
New-Item -ItemType Directory -Path "models" | Out-Null
Write-Host "✅ Created models directory"
}
# 进入 models 目录
cd models
# Linux/macOS
cd /path/to/fulla/libs/storage-postgres/src/models
# 创建 models 目录(如果不存在)
mkdir -p models
echo "✅ Created models directory"
# 进入 models 目录
cd models
# Windows PowerShell
Get-ChildItem -Filter "*.h" | Where-Object { $_.Name -ne "orm_compat.h" } | Remove-Item
Get-ChildItem -Filter "*.cc" | Remove-Item
Write-Host "✅ Old model files removed"
# Linux/macOS
rm -f *.h *.cc # src/models 下的 .cc
rm -f ../../include/fulla/storage/postgres/models/*.h # 对应的 .h
echo "✅ Old model files removed"
# Windows PowerShell - 使用专项脚本
scripts/backend/generate_models.bat -y
# 此脚本会自动完成:
# 1. 检查数据库连接
# 2. 验证 model.json 配置
# 3. 备份现有模型文件
# 4. 执行 drogon_ctl 生成
# 5. 验证生成结果
# 6. 返回到项目根目录
# 确保在正确的目录
cd libs/storage-postgres/src/models
# 执行 drogon_ctl 生成命令
drogon_ctl create model ../
预期输出:
Generating models for tables:
- organizations
- users
- roles
- permissions
- user_roles
- role_permissions
- oauth2_clients
- oauth2_codes
- oauth2_access_tokens
- oauth2_refresh_tokens
- oauth2_scopes
- oauth2_client_scopes
- oauth2_user_consents
- oauth2_subject_mappings
- audit_logs
- email_verification_tokens
- password_reset_tokens
- oauth2_device_codes
- webauthn_credentials
Models generated successfully!
# Windows PowerShell
Write-Host "`n=== Generated Files ==="
Get-ChildItem *.h, *.cc | Select-Object Name, LastWriteTime | Format-Table -AutoSize
# 验证关键文件
$requiredFiles = @(
"Organizations.h", "Organizations.cc",
"Users.h", "Users.cc",
"Roles.h", "Roles.cc",
"Permissions.h", "Permissions.cc",
"UserRoles.h", "UserRoles.cc",
"RolePermissions.h", "RolePermissions.cc",
"Oauth2Clients.h", "Oauth2Clients.cc",
"Oauth2Codes.h", "Oauth2Codes.cc",
"Oauth2AccessTokens.h", "Oauth2AccessTokens.cc",
"Oauth2RefreshTokens.h", "Oauth2RefreshTokens.cc",
"Oauth2Scopes.h", "Oauth2Scopes.cc",
"Oauth2ClientScopes.h", "Oauth2ClientScopes.cc",
"Oauth2UserConsents.h", "Oauth2UserConsents.cc",
"Oauth2SubjectMappings.h", "Oauth2SubjectMappings.cc",
"AuditLogs.h", "AuditLogs.cc",
"EmailVerificationTokens.h", "EmailVerificationTokens.cc",
"PasswordResetTokens.h", "PasswordResetTokens.cc",
"Oauth2DeviceCodes.h", "Oauth2DeviceCodes.cc",
"WebauthnCredentials.h", "WebauthnCredentials.cc"
)
$missingFiles = @()
foreach ($file in $requiredFiles) {
if (!(Test-Path $file)) {
$missingFiles += $file
}
}
if ($missingFiles.Count -gt 0) {
Write-Host "❌ Missing files: $($missingFiles -join ', ')" -ForegroundColor Red
exit 1
} else {
Write-Host "✅ All required model files generated" -ForegroundColor Green
}
# Linux/macOS
echo "=== Generated Files ==="
ls -lh *.h *.cc | awk '{print $9, $6, $7, $8}'
# 验证关键文件
required_files=(
"Organizations.h" "Organizations.cc"
"Users.h" "Users.cc"
"Roles.h" "Roles.cc"
"Permissions.h" "Permissions.cc"
"UserRoles.h" "UserRoles.cc"
"RolePermissions.h" "RolePermissions.cc"
"Oauth2Clients.h" "Oauth2Clients.cc"
"Oauth2Codes.h" "Oauth2Codes.cc"
"Oauth2AccessTokens.h" "Oauth2AccessTokens.cc"
"Oauth2RefreshTokens.h" "Oauth2RefreshTokens.cc"
"Oauth2Scopes.h" "Oauth2Scopes.cc"
"Oauth2ClientScopes.h" "Oauth2ClientScopes.cc"
"Oauth2UserConsents.h" "Oauth2UserConsents.cc"
"Oauth2SubjectMappings.h" "Oauth2SubjectMappings.cc"
"AuditLogs.h" "AuditLogs.cc"
"EmailVerificationTokens.h" "EmailVerificationTokens.cc"
"PasswordResetTokens.h" "PasswordResetTokens.cc"
"Oauth2DeviceCodes.h" "Oauth2DeviceCodes.cc"
"WebauthnCredentials.h" "WebauthnCredentials.cc"
)
missing_files=()
for file in ;
[ ! -f ];
missing_files+=()
[ -gt 0 ];
1
# 随机抽查一个文件,确认生成正确
head -20 Oauth2Clients.h
# 应该包含:
# - 自动生成的注释:"DO NOT EDIT. This file is generated by drogon_ctl"
# - 类定义继承 Drogon ORM 基类
# - Getter/Setter 方法
# Windows PowerShell - 新的构建路径
cd build/<preset>
cmake --build . --parallel --config Release
if ($LASTEXITCODE -eq 0) {
Write-Host "✅ Build successful" -ForegroundColor Green
} else {
Write-Host "❌ Build failed" -ForegroundColor Red
exit 1
}
# Linux/macOS
cd build/<preset>
cmake --build . --parallel
if [ $? -eq 0 ]; then
echo "✅ Build successful"
else
echo "❌ Build failed"
exit 1
fi
# 运行测试确保 ORM 模型工作正常
cd build/<preset>
ctest --output-on-failure -C Release
| 配置项 | 值 | 说明 |
|---|---|---|
| 主机 | 127.0.0.1 / localhost | 本地连接 |
| 端口 | 5432 | PostgreSQL 默认端口 |
| 数据库 | fulla_db | OAuth2 测试数据库 |
| 用户名 | fulla_user | 测试用户(与 model.json / config.dev.json 一致) |
| 密码 | 123456 | 测试密码 |
| 表名 | 头文件 | 源文件 | 说明 |
|---|---|---|---|
| organizations | Organizations.h | Organizations.cc | 组织/租户表 |
| users | Users.h | Users.cc | 用户账号表 |
| roles | Roles.h | Roles.cc | 角色表 |
| permissions | Permissions.h | Permissions.cc | 权限表 |
| user_roles | UserRoles.h | UserRoles.cc | 用户-角色关联表 |
| role_permissions | RolePermissions.h | RolePermissions.cc | 角色-权限关联表 |
| oauth2_clients | Oauth2Clients.h | Oauth2Clients.cc | OAuth2 客户端表 |
| oauth2_codes | Oauth2Codes.h | Oauth2Codes.cc | OAuth2 授权码表 |
| oauth2_access_tokens | Oauth2AccessTokens.h | Oauth2AccessTokens.cc | OAuth2 访问令牌表 |
| oauth2_refresh_tokens | Oauth2RefreshTokens.h | Oauth2RefreshTokens.cc | OAuth2 刷新令牌表 |
| oauth2_scopes | Oauth2Scopes.h | Oauth2Scopes.cc | OAuth2 作用域表 |
| oauth2_client_scopes | Oauth2ClientScopes.h | Oauth2ClientScopes.cc | 客户端-作用域关联表 |
| oauth2_user_consents | Oauth2UserConsents.h | Oauth2UserConsents.cc | 用户授权同意表 |
| oauth2_subject_mappings | Oauth2SubjectMappings.h | Oauth2SubjectMappings.cc | OAuth2 subject-内部用户映射表 |
| audit_logs | AuditLogs.h | AuditLogs.cc | 审计日志表 |
| email_verification_tokens | EmailVerificationTokens.h | EmailVerificationTokens.cc | 邮箱验证令牌表 |
| password_reset_tokens | PasswordResetTokens.h | PasswordResetTokens.cc | 密码重置令牌表 |
| oauth2_device_codes | Oauth2DeviceCodes.h | Oauth2DeviceCodes.cc | OAuth2 设备授权码表 |
| webauthn_credentials | WebauthnCredentials.h | WebauthnCredentials.cc | WebAuthn/Passkey 凭证表 |
症状: drogon_ctl: command not found
解决方案:
# 检查 Drogon 安装
which drogon_ctl
# 如果未找到,重新安装 Drogon
# 使用 Conan
conan install drogon/[>=1.8.4]
# 或使用系统包管理器
# Ubuntu/Debian
sudo apt-get install drogon
# macOS
brew install drogon
症状: failed to connect to database 或 connection refused
解决方案:
# 检查 PostgreSQL 服务
pg_isready -h localhost -p 5432
# 启动 PostgreSQL
# Windows
Start-Service postgresql*
# Linux
sudo systemctl start postgresql
# macOS
brew services start postgresql
# 验证数据库凭据
export PGPASSWORD='123456'
psql -h localhost -U fulla_user -d fulla_db -c "SELECT 1;"
症状: ERROR: relation "xxx" does not exist
解决方案:
# 先重置数据库
/db-reset
# 然后验证表是否存在
export PGPASSWORD='123456'
psql -h localhost -U fulla_user -d fulla_db -c "\dt"
症状: 部分模型文件缺失或为空
解决方案:
# 检查 model.json 配置
cat libs/storage-postgres/src/models/model.json
# 确保 tables 数组包含所有需要的表
# 手动添加缺失的表名
# 重新执行生成
cd apps/server
drogon_ctl create model .
症状: 生成后编译失败,提示语法错误
解决方案:
# 检查 Drogon 版本
drogon_ctl version
# 确保 Drogon 版本 >= 1.8.0
# 如果版本过旧,更新 Drogon
# 检查生成的文件内容
head -50 Oauth2Clients.h
# 确认文件开头有正确的注释:
# "DO NOT EDIT. This file is generated by drogon_ctl"
症状: 运行时错误,提示字段类型与数据库不符
解决方案:
# 查看数据库表结构
export PGPASSWORD='123456'
psql -h localhost -U fulla_user -d fulla_db -c "\d oauth2_clients"
# 如果表结构已更改,先删除旧表
# 然后重新执行 SQL 脚本
/db-reset
# 最后重新生成模型
/orm-gen
# 1. 修改 migration SQL 脚本
vim apps/server/migrations/V002__oauth2_core.sql
# 2. 重置数据库
/db-reset
# 3. 重新生成 ORM 模型
/orm-gen
# 4. 重新编译项目
/build-and-test
# 5. 运行测试验证
cd build/<preset> && ctest --output-on-failure
# 每次生成前自动备份
timestamp=$(date +%Y%m%d_%H%M%S)
backup_dir="models_backup_$timestamp"
mkdir -p $backup_dir
cp libs/storage-postgres/src/models/*.h libs/storage-postgres/src/models/*.cc $backup_dir/
# 保留最近 5 次备份
ls -td models_backup_* | tail -n +6 | xargs rm -rf
# .github/workflows/ci.yml
- name: Reset Database
run: /db-reset
- name: Generate ORM Models
run: /orm-gen
- name: Build Project
run: /build-and-test
- name: Run Tests
run: ctest --output-on-failure
# .gitignore 配置
# 自动生成的模型文件可以提交到版本控制
libs/storage-postgres/src/models/*.h
libs/storage-postgres/src/models/*.cc
# 但备份文件应该忽略
models_backup_*/
# model.json 应该提交
libs/storage-postgres/src/models/model.json
生成模型后,需要检查:
⚠️ 重要提示:
/db-reset - 重置数据库(表结构变更前)/build-and-test - 生成后编译和测试/e2e-test - 端到端测试验证 ORM 模型✅ 成功执行后应看到:
✅ Old model files removed
Models generated successfully!
✅ All required model files generated
✅ Build successful
✅ Tests passed
且 ls 应显示所有 19 张表对应的模型文件(38 个文件:19 个 .h + 19 个 .cc)
每个生成的模型类包含:
#include "models/Oauth2Clients.h"
using namespace drogon::orm;
using namespace drogon_model::fulla_db;
// 查询客户端
Mapper<Oauth2Clients> mapper(dbClient);
mapper.findOne(
Criteria(Oauth2Clients::Cols::_client_id, CompareOperator::EQ, "test_client"),
[](const Oauth2Clients &client) {
std::string clientId = client.getValueOfClientId();
std::string secret = client.getValueOfClientSecret();
// 使用客户端数据...
},
[](const DrogonDbException &e) {
// 错误处理...
});