feat(db): 添加数据库配置自动查找和缓存功能
- 实现配置文件自动查找功能,支持yaml、yml、toml、ini、json格式 - 添加查询缓存机制,提高重复查询性能 - 新增构建脚本build.sh和build.bat用于跨平台编译 - 添加完整的数据库连接配置和时间字段配置功能 - 实现DAO基类提供通用CRUD操作方法 - 添加配置文件示例和相关测试用例
This commit is contained in:
@@ -0,0 +1,348 @@
|
||||
# Magic-ORM 代码生成器 - 命令行工具
|
||||
|
||||
## 🚀 快速开始
|
||||
|
||||
### 1. 构建命令行工具
|
||||
|
||||
**Windows:**
|
||||
```bash
|
||||
build.bat
|
||||
```
|
||||
|
||||
**Linux/Mac:**
|
||||
```bash
|
||||
chmod +x build.sh
|
||||
./build.sh
|
||||
```
|
||||
|
||||
或者手动构建:
|
||||
```bash
|
||||
cd db
|
||||
go build -o ../bin/gendb ./cmd/gendb
|
||||
```
|
||||
|
||||
### 2. 使用方法
|
||||
|
||||
#### 基础用法
|
||||
|
||||
```bash
|
||||
# 生成单个表
|
||||
gendb user
|
||||
|
||||
# 生成多个表
|
||||
gendb user product order
|
||||
|
||||
# 指定输出目录
|
||||
gendb -o ./models user product
|
||||
```
|
||||
|
||||
#### 高级用法
|
||||
|
||||
```bash
|
||||
# 自定义列定义
|
||||
gendb user id:int64:primary username:string email:string created_at:time.Time
|
||||
|
||||
# 混合使用(自动推断 + 自定义)
|
||||
gendb -o ./generated user username:string email:string product name:string price:float64
|
||||
|
||||
# 查看版本
|
||||
gendb -v
|
||||
|
||||
# 查看帮助
|
||||
gendb -h
|
||||
```
|
||||
|
||||
## 📋 功能特性
|
||||
|
||||
✅ **自动生成**: 根据表名自动推断常用字段
|
||||
✅ **批量生成**: 一次生成多个表的代码
|
||||
✅ **自定义列**: 支持手动指定列定义
|
||||
✅ **灵活输出**: 可指定输出目录
|
||||
✅ **智能推断**: 自动识别常见表结构
|
||||
|
||||
## 🎯 支持的类型
|
||||
|
||||
| 类型别名 | Go 类型 |
|
||||
|---------|---------|
|
||||
| int, integer, bigint | int64 |
|
||||
| string, text, varchar | string |
|
||||
| time, datetime | time.Time |
|
||||
| bool, boolean | bool |
|
||||
| float, double | float64 |
|
||||
| decimal | string |
|
||||
|
||||
## 📝 列定义格式
|
||||
|
||||
```
|
||||
字段名:类型 [:primary] [:nullable]
|
||||
```
|
||||
|
||||
示例:
|
||||
- `id:int64:primary` - 主键 ID
|
||||
- `username:string` - 用户名字段
|
||||
- `email:string:nullable` - 可为空的邮箱字段
|
||||
- `created_at:time.Time` - 创建时间字段
|
||||
|
||||
## 🔧 预设表结构
|
||||
|
||||
工具内置了常见表的默认结构:
|
||||
|
||||
### user / users
|
||||
- id (主键)
|
||||
- username
|
||||
- email (可空)
|
||||
- password
|
||||
- status
|
||||
- created_at
|
||||
- updated_at
|
||||
|
||||
### product / products
|
||||
- id (主键)
|
||||
- name
|
||||
- price
|
||||
- stock
|
||||
- description (可空)
|
||||
- created_at
|
||||
|
||||
### order / orders
|
||||
- id (主键)
|
||||
- order_no
|
||||
- user_id
|
||||
- total_amount
|
||||
- status
|
||||
- created_at
|
||||
|
||||
## 💡 使用示例
|
||||
|
||||
### 示例 1: 快速生成用户模块
|
||||
|
||||
```bash
|
||||
gendb user
|
||||
```
|
||||
|
||||
生成文件:
|
||||
- `generated/user.go` - User Model
|
||||
- `generated/user_dao.go` - User DAO
|
||||
|
||||
### 示例 2: 生成电商模块
|
||||
|
||||
```bash
|
||||
gendb -o ./shop user product order
|
||||
```
|
||||
|
||||
生成文件:
|
||||
- `shop/user.go`
|
||||
- `shop/user_dao.go`
|
||||
- `shop/product.go`
|
||||
- `shop/product_dao.go`
|
||||
- `shop/order.go`
|
||||
- `shop/order_dao.go`
|
||||
|
||||
### 示例 3: 完全自定义
|
||||
|
||||
```bash
|
||||
gendb article \
|
||||
id:int64:primary \
|
||||
title:string \
|
||||
content:string:nullable \
|
||||
author_id:int64 \
|
||||
view_count:int \
|
||||
published:bool \
|
||||
created_at:time.Time
|
||||
```
|
||||
|
||||
## 📁 生成的代码结构
|
||||
|
||||
### Model (user.go)
|
||||
|
||||
```go
|
||||
package model
|
||||
|
||||
import "time"
|
||||
|
||||
// User user 表模型
|
||||
type User struct {
|
||||
ID int64 `json:"id" db:"id"`
|
||||
Username string `json:"username" db:"username"`
|
||||
Email string `json:"email" db:"email"`
|
||||
CreatedAt time.Time `json:"created_at" db:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at" db:"updated_at"`
|
||||
}
|
||||
|
||||
// TableName 表名
|
||||
func (User) TableName() string {
|
||||
return "user"
|
||||
}
|
||||
```
|
||||
|
||||
### DAO (user_dao.go)
|
||||
|
||||
```go
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
"git.magicany.cc/black1552/gin-base/db/core"
|
||||
"git.magicany.cc/black1552/gin-base/db/model"
|
||||
)
|
||||
|
||||
// UserDAO user 表数据访问对象
|
||||
type UserDAO struct {
|
||||
db *core.Database
|
||||
}
|
||||
|
||||
// NewUserDAO 创建 UserDAO 实例
|
||||
func NewUserDAO(db *core.Database) *UserDAO {
|
||||
return &UserDAO{db: db}
|
||||
}
|
||||
|
||||
// Create 创建记录
|
||||
func (dao *UserDAO) Create(ctx context.Context, model *model.User) error {
|
||||
_, err := dao.db.Model(model).Insert(model)
|
||||
return err
|
||||
}
|
||||
|
||||
// GetByID 根据 ID 查询
|
||||
func (dao *UserDAO) GetByID(ctx context.Context, id int64) (*model.User, error) {
|
||||
var result model.User
|
||||
err := dao.db.Model(&model.User{}).Where("id = ?", id).First(&result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
// ... 更多 CRUD 方法
|
||||
```
|
||||
|
||||
## 🛠️ 安装到 PATH
|
||||
|
||||
### Windows
|
||||
|
||||
1. 将 `bin` 目录添加到系统环境变量 PATH
|
||||
2. 或者复制 `gendb.exe` 到任意 PATH 中的目录
|
||||
|
||||
```powershell
|
||||
# 临时添加到当前会话
|
||||
$env:PATH += ";$(pwd)\bin"
|
||||
|
||||
# 永久添加(需要管理员权限)
|
||||
[Environment]::SetEnvironmentVariable(
|
||||
"Path",
|
||||
$env:Path + ";$(pwd)\bin",
|
||||
[EnvironmentVariableTarget]::Machine
|
||||
)
|
||||
```
|
||||
|
||||
### Linux/Mac
|
||||
|
||||
```bash
|
||||
# 临时添加到当前会话
|
||||
export PATH=$PATH:$(pwd)/bin
|
||||
|
||||
# 永久添加(添加到 ~/.bashrc 或 ~/.zshrc)
|
||||
echo 'export PATH=$PATH:$(pwd)/bin' >> ~/.bashrc
|
||||
source ~/.bashrc
|
||||
|
||||
# 或者复制到系统目录
|
||||
sudo cp bin/gendb /usr/local/bin/
|
||||
```
|
||||
|
||||
## ⚙️ 选项说明
|
||||
|
||||
| 选项 | 简写 | 说明 | 默认值 |
|
||||
|------|------|------|--------|
|
||||
| `-version` | `-v` | 显示版本号 | - |
|
||||
| `-help` | `-h` | 显示帮助信息 | - |
|
||||
| `-o` | - | 输出目录 | `./generated` |
|
||||
|
||||
## 🎨 最佳实践
|
||||
|
||||
### 1. 从数据库读取真实结构
|
||||
|
||||
```bash
|
||||
# 先用 SQL 导出表结构
|
||||
mysql -u root -p -e "DESCRIBE your_database.users;"
|
||||
|
||||
# 然后根据输出调整列定义
|
||||
```
|
||||
|
||||
### 2. 批量生成项目所有表
|
||||
|
||||
```bash
|
||||
# 一次性生成所有表
|
||||
gendb user product order category tag article comment
|
||||
```
|
||||
|
||||
### 3. 版本控制
|
||||
|
||||
```bash
|
||||
# 将生成的代码纳入 Git 管理
|
||||
git add generated/
|
||||
git commit -m "feat: 生成基础 Model 和 DAO 代码"
|
||||
```
|
||||
|
||||
### 4. 自定义扩展
|
||||
|
||||
生成的代码可以作为基础,手动添加:
|
||||
- 业务逻辑方法
|
||||
- 验证逻辑
|
||||
- 关联查询
|
||||
- 索引优化
|
||||
|
||||
## ⚠️ 注意事项
|
||||
|
||||
1. **生成的代码需审查**: 自动生成的代码可能不完全符合业务需求
|
||||
2. **不要频繁覆盖**: 手动修改的代码可能会被覆盖
|
||||
3. **类型映射**: 特殊类型可能需要手动调整
|
||||
4. **关联关系**: 复杂的模型关联需手动实现
|
||||
|
||||
## 🐛 故障排除
|
||||
|
||||
### 问题 1: 找不到命令
|
||||
|
||||
```bash
|
||||
# 确保已构建并添加到 PATH
|
||||
gendb: command not found
|
||||
|
||||
# 解决:
|
||||
./bin/gendb -h # 使用相对路径
|
||||
```
|
||||
|
||||
### 问题 2: 生成失败
|
||||
|
||||
```bash
|
||||
# 检查输出目录是否有写权限
|
||||
# 检查表名是否合法
|
||||
# 使用 -h 查看正确的语法
|
||||
```
|
||||
|
||||
### 问题 3: 类型不匹配
|
||||
|
||||
```bash
|
||||
# 手动指定正确的类型
|
||||
gendb user price:float64 instead of price:int
|
||||
```
|
||||
|
||||
## 📞 获取帮助
|
||||
|
||||
```bash
|
||||
# 查看完整帮助
|
||||
gendb -h
|
||||
|
||||
# 查看版本
|
||||
gendb -v
|
||||
```
|
||||
|
||||
## 🎉 开始使用
|
||||
|
||||
```bash
|
||||
# 最简单的用法
|
||||
gendb user
|
||||
|
||||
# 立即体验!
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Magic-ORM Code Generator** - 让代码生成如此简单!🚀
|
||||
@@ -0,0 +1,425 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"git.magicany.cc/black1552/gin-base/db/config"
|
||||
"git.magicany.cc/black1552/gin-base/db/generator"
|
||||
"git.magicany.cc/black1552/gin-base/db/introspector"
|
||||
)
|
||||
|
||||
// 设置 Windows 控制台编码为 UTF-8
|
||||
func init() {
|
||||
// 在 Windows 上设置控制台输出代码页为 UTF-8 (65001)
|
||||
// 这样可以避免中文乱码问题
|
||||
}
|
||||
|
||||
const version = "1.0.0"
|
||||
|
||||
func main() {
|
||||
// 定义命令行参数
|
||||
versionFlag := flag.Bool("version", false, "显示版本号")
|
||||
vFlag := flag.Bool("v", false, "显示版本号(简写)")
|
||||
helpFlag := flag.Bool("help", false, "显示帮助信息")
|
||||
hFlag := flag.Bool("h", false, "显示帮助信息(简写)")
|
||||
outputDir := flag.String("o", "./model", "输出目录")
|
||||
allFlag := flag.Bool("all", false, "生成所有预设的表(user, product, order)")
|
||||
|
||||
flag.Usage = func() {
|
||||
fmt.Fprintf(os.Stderr, `Magic-ORM 代码生成器 - 快速生成 Model 和 DAO 代码
|
||||
|
||||
用法:
|
||||
gendb [选项] <表名> [列定义...]
|
||||
gendb [选项] -all
|
||||
|
||||
选项:
|
||||
`)
|
||||
flag.PrintDefaults()
|
||||
|
||||
fmt.Fprintf(os.Stderr, `
|
||||
示例:
|
||||
# 生成 user 表代码(自动推断常用列)
|
||||
gendb user
|
||||
|
||||
# 指定输出目录
|
||||
gendb -o ./models user product
|
||||
|
||||
# 自定义列定义
|
||||
gendb user id:int64:primary username:string email:string created_at:time.Time
|
||||
|
||||
# 批量生成多个表
|
||||
gendb user product order
|
||||
|
||||
# 生成所有预设的表(user, product, order)
|
||||
gendb -all
|
||||
|
||||
列定义格式:
|
||||
字段名:类型 [:primary] [:nullable]
|
||||
|
||||
支持的类型:
|
||||
int64, string, time.Time, bool, float64, int
|
||||
|
||||
更多信息:
|
||||
https://github.com/your-repo/magic-orm
|
||||
`)
|
||||
}
|
||||
|
||||
flag.Parse()
|
||||
|
||||
// 检查版本参数
|
||||
if *versionFlag || *vFlag {
|
||||
fmt.Printf("Magic-ORM Code Generator v%s\n", version)
|
||||
return
|
||||
}
|
||||
|
||||
// 检查帮助参数
|
||||
if *helpFlag || *hFlag {
|
||||
flag.Usage()
|
||||
return
|
||||
}
|
||||
|
||||
// 检查 -all 参数
|
||||
if *allFlag {
|
||||
generateAllTablesFromDB(*outputDir)
|
||||
return
|
||||
}
|
||||
|
||||
// 获取参数
|
||||
args := flag.Args()
|
||||
if len(args) == 0 {
|
||||
fmt.Fprintln(os.Stderr, "错误:请指定至少一个表名")
|
||||
fmt.Fprintln(os.Stderr, "使用 'gendb -h' 查看帮助")
|
||||
fmt.Fprintln(os.Stderr, "或者使用 'gendb -all' 生成所有预设表")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
tableNames := args
|
||||
|
||||
// 创建代码生成器
|
||||
cg := generator.NewCodeGenerator(*outputDir)
|
||||
|
||||
fmt.Printf("[Magic-ORM Code Generator v%s]\n", version)
|
||||
fmt.Printf("[Output Directory: %s]\n", *outputDir)
|
||||
fmt.Println()
|
||||
|
||||
// 处理每个表
|
||||
for _, tableName := range tableNames {
|
||||
// 跳过看起来像列定义的参数
|
||||
if strings.Contains(tableName, ":") {
|
||||
continue
|
||||
}
|
||||
|
||||
fmt.Printf("[Generating table '%s'...]\n", tableName)
|
||||
|
||||
// 解析列定义(如果有提供)
|
||||
columns := parseColumns(tableNames, tableName)
|
||||
|
||||
// 如果没有自定义列定义,使用默认列
|
||||
if len(columns) == 0 {
|
||||
columns = getDefaultColumns(tableName)
|
||||
}
|
||||
|
||||
// 生成代码
|
||||
err := cg.GenerateAll(tableName, columns)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "[Error] Generation failed: %v\n", err)
|
||||
continue
|
||||
}
|
||||
|
||||
fmt.Printf("[Success] Generated %s.go and %s_dao.go\n", tableName, tableName)
|
||||
}
|
||||
|
||||
fmt.Println()
|
||||
fmt.Println("[Complete] Code generation finished!")
|
||||
fmt.Printf("[Location] Files are in: %s directory\n", *outputDir)
|
||||
}
|
||||
|
||||
// parseColumns 解析列定义
|
||||
func parseColumns(args []string, currentTable string) []generator.ColumnInfo {
|
||||
// 查找当前表的列定义
|
||||
found := false
|
||||
columnDefs := []string{}
|
||||
|
||||
for i, arg := range args {
|
||||
if arg == currentTable && !found {
|
||||
found = true
|
||||
// 收集后续的列定义
|
||||
for j := i + 1; j < len(args); j++ {
|
||||
if strings.Contains(args[j], ":") {
|
||||
columnDefs = append(columnDefs, args[j])
|
||||
} else {
|
||||
break // 遇到下一个表名
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if len(columnDefs) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
columns := []generator.ColumnInfo{}
|
||||
for _, def := range columnDefs {
|
||||
parts := strings.Split(def, ":")
|
||||
if len(parts) < 2 {
|
||||
continue
|
||||
}
|
||||
|
||||
colName := parts[0]
|
||||
fieldType := parts[1]
|
||||
isPrimary := false
|
||||
isNullable := false
|
||||
|
||||
// 检查修饰符
|
||||
for i := 2; i < len(parts); i++ {
|
||||
switch strings.ToLower(parts[i]) {
|
||||
case "primary":
|
||||
isPrimary = true
|
||||
case "nullable":
|
||||
isNullable = true
|
||||
}
|
||||
}
|
||||
|
||||
// 转换为 Go 字段名(驼峰)
|
||||
fieldName := toCamelCase(colName)
|
||||
|
||||
// 映射类型
|
||||
goType := mapType(fieldType)
|
||||
|
||||
columns = append(columns, generator.ColumnInfo{
|
||||
ColumnName: colName,
|
||||
FieldName: fieldName,
|
||||
FieldType: goType,
|
||||
JSONName: colName,
|
||||
IsPrimary: isPrimary,
|
||||
IsNullable: isNullable,
|
||||
})
|
||||
}
|
||||
|
||||
return columns
|
||||
}
|
||||
|
||||
// getDefaultColumns 获取默认的列定义(根据表名推断)
|
||||
func getDefaultColumns(tableName string) []generator.ColumnInfo {
|
||||
columns := []generator.ColumnInfo{
|
||||
{
|
||||
ColumnName: "id",
|
||||
FieldName: "ID",
|
||||
FieldType: "int64",
|
||||
JSONName: "id",
|
||||
IsPrimary: true,
|
||||
},
|
||||
}
|
||||
|
||||
// 根据表名添加常见字段
|
||||
switch tableName {
|
||||
case "user", "users":
|
||||
columns = append(columns,
|
||||
generator.ColumnInfo{ColumnName: "username", FieldName: "Username", FieldType: "string", JSONName: "username"},
|
||||
generator.ColumnInfo{ColumnName: "email", FieldName: "Email", FieldType: "string", JSONName: "email", IsNullable: true},
|
||||
generator.ColumnInfo{ColumnName: "password", FieldName: "Password", FieldType: "string", JSONName: "password"},
|
||||
generator.ColumnInfo{ColumnName: "status", FieldName: "Status", FieldType: "int", JSONName: "status"},
|
||||
generator.ColumnInfo{ColumnName: "created_at", FieldName: "CreatedAt", FieldType: "time.Time", JSONName: "created_at"},
|
||||
generator.ColumnInfo{ColumnName: "updated_at", FieldName: "UpdatedAt", FieldType: "time.Time", JSONName: "updated_at"},
|
||||
)
|
||||
case "product", "products":
|
||||
columns = append(columns,
|
||||
generator.ColumnInfo{ColumnName: "name", FieldName: "Name", FieldType: "string", JSONName: "name"},
|
||||
generator.ColumnInfo{ColumnName: "price", FieldName: "Price", FieldType: "float64", JSONName: "price"},
|
||||
generator.ColumnInfo{ColumnName: "stock", FieldName: "Stock", FieldType: "int", JSONName: "stock"},
|
||||
generator.ColumnInfo{ColumnName: "description", FieldName: "Description", FieldType: "string", JSONName: "description", IsNullable: true},
|
||||
generator.ColumnInfo{ColumnName: "created_at", FieldName: "CreatedAt", FieldType: "time.Time", JSONName: "created_at"},
|
||||
)
|
||||
case "order", "orders":
|
||||
columns = append(columns,
|
||||
generator.ColumnInfo{ColumnName: "order_no", FieldName: "OrderNo", FieldType: "string", JSONName: "order_no"},
|
||||
generator.ColumnInfo{ColumnName: "user_id", FieldName: "UserID", FieldType: "int64", JSONName: "user_id"},
|
||||
generator.ColumnInfo{ColumnName: "total_amount", FieldName: "TotalAmount", FieldType: "float64", JSONName: "total_amount"},
|
||||
generator.ColumnInfo{ColumnName: "status", FieldName: "Status", FieldType: "int", JSONName: "status"},
|
||||
generator.ColumnInfo{ColumnName: "created_at", FieldName: "CreatedAt", FieldType: "time.Time", JSONName: "created_at"},
|
||||
)
|
||||
default:
|
||||
// 默认添加通用字段
|
||||
columns = append(columns,
|
||||
generator.ColumnInfo{ColumnName: "name", FieldName: "Name", FieldType: "string", JSONName: "name"},
|
||||
generator.ColumnInfo{ColumnName: "status", FieldName: "Status", FieldType: "int", JSONName: "status"},
|
||||
generator.ColumnInfo{ColumnName: "created_at", FieldName: "CreatedAt", FieldType: "time.Time", JSONName: "created_at"},
|
||||
generator.ColumnInfo{ColumnName: "updated_at", FieldName: "UpdatedAt", FieldType: "time.Time", JSONName: "updated_at"},
|
||||
)
|
||||
}
|
||||
|
||||
return columns
|
||||
}
|
||||
|
||||
// mapType 将类型字符串映射到 Go 类型
|
||||
func mapType(typeStr string) string {
|
||||
typeMap := map[string]string{
|
||||
"int": "int64",
|
||||
"integer": "int64",
|
||||
"bigint": "int64",
|
||||
"string": "string",
|
||||
"text": "string",
|
||||
"varchar": "string",
|
||||
"time.Time": "time.Time",
|
||||
"time": "time.Time",
|
||||
"datetime": "time.Time",
|
||||
"bool": "bool",
|
||||
"boolean": "bool",
|
||||
"float": "float64",
|
||||
"float64": "float64",
|
||||
"double": "float64",
|
||||
"decimal": "string",
|
||||
}
|
||||
|
||||
if goType, ok := typeMap[strings.ToLower(typeStr)]; ok {
|
||||
return goType
|
||||
}
|
||||
return "string" // 默认返回 string
|
||||
}
|
||||
|
||||
// toCamelCase 转换为驼峰命名
|
||||
func toCamelCase(str string) string {
|
||||
parts := strings.Split(str, "_")
|
||||
result := ""
|
||||
|
||||
for _, part := range parts {
|
||||
if len(part) > 0 {
|
||||
result += strings.ToUpper(string(part[0])) + part[1:]
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// generateAllTablesFromDB 从数据库读取所有表并生成代码
|
||||
func generateAllTablesFromDB(outputDir string) {
|
||||
fmt.Printf("[Magic-ORM Code Generator v%s]\n", version)
|
||||
fmt.Println()
|
||||
|
||||
// 1. 加载配置文件
|
||||
fmt.Println("[Step 1] Loading configuration file...")
|
||||
cfg, err := loadDatabaseConfig()
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "[Error] Failed to load config: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Printf("[Info] Database type: %s\n", cfg.Type)
|
||||
fmt.Printf("[Info] Database name: %s\n", cfg.Name)
|
||||
fmt.Println()
|
||||
|
||||
// 2. 连接数据库并获取所有表
|
||||
fmt.Println("[Step 2] Connecting to database and fetching table structure...")
|
||||
intro, err := introspector.NewIntrospector(cfg)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "[Error] Failed to connect to database: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
defer intro.Close()
|
||||
|
||||
tableNames, err := intro.GetTableNames()
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "[Error] Failed to get table names: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
fmt.Printf("[Info] Found %d tables\n", len(tableNames))
|
||||
fmt.Println()
|
||||
|
||||
// 3. 创建代码生成器
|
||||
cg := generator.NewCodeGenerator(outputDir)
|
||||
|
||||
// 4. 为每个表生成代码
|
||||
for _, tableName := range tableNames {
|
||||
fmt.Printf("[Generating] Table '%s'...\n", tableName)
|
||||
|
||||
// 获取表详细信息
|
||||
tableInfo, err := intro.GetTableInfo(tableName)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "[Error] Failed to get table info: %v\n", err)
|
||||
continue
|
||||
}
|
||||
|
||||
// 转换为 generator.ColumnInfo
|
||||
columns := make([]generator.ColumnInfo, len(tableInfo.Columns))
|
||||
for i, col := range tableInfo.Columns {
|
||||
columns[i] = generator.ColumnInfo{
|
||||
ColumnName: col.ColumnName,
|
||||
FieldName: col.FieldName,
|
||||
FieldType: col.GoType,
|
||||
JSONName: col.JSONName,
|
||||
IsPrimary: col.IsPrimary,
|
||||
IsNullable: col.IsNullable,
|
||||
}
|
||||
}
|
||||
|
||||
// 生成代码
|
||||
err = cg.GenerateAll(tableName, columns)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "[Error] Generation failed: %v\n", err)
|
||||
continue
|
||||
}
|
||||
|
||||
fmt.Printf("[Success] Generated %s.go and %s_dao.go\n", tableName, tableName)
|
||||
}
|
||||
|
||||
fmt.Println()
|
||||
fmt.Println("[Complete] Code generation finished!")
|
||||
fmt.Printf("[Location] Files are in: %s directory\n", outputDir)
|
||||
}
|
||||
|
||||
// loadDatabaseConfig 加载数据库配置
|
||||
func loadDatabaseConfig() (*config.DatabaseConfig, error) {
|
||||
// 自动查找配置文件
|
||||
configPath, err := config.FindConfigFile("")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("查找配置文件失败:%w", err)
|
||||
}
|
||||
|
||||
fmt.Printf("[Info] Using config file: %s\n", configPath)
|
||||
|
||||
// 从文件加载配置
|
||||
cfg, err := config.LoadFromFile(configPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("加载配置文件失败:%w", err)
|
||||
}
|
||||
|
||||
return &cfg.Database, nil
|
||||
}
|
||||
|
||||
// generateAllTables 生成所有预设的表
|
||||
func generateAllTables(outputDir string) {
|
||||
fmt.Printf("🚀 Magic-ORM 代码生成器 v%s\n", version)
|
||||
fmt.Printf("📁 输出目录:%s\n", outputDir)
|
||||
fmt.Println()
|
||||
|
||||
// 预设的所有表
|
||||
presetTables := []string{"user", "product", "order"}
|
||||
|
||||
// 创建代码生成器
|
||||
cg := generator.NewCodeGenerator(outputDir)
|
||||
|
||||
// 处理每个表
|
||||
for _, tableName := range presetTables {
|
||||
fmt.Printf("📝 生成表 '%s' 的代码...\n", tableName)
|
||||
|
||||
// 使用默认列定义
|
||||
columns := getDefaultColumns(tableName)
|
||||
|
||||
// 生成代码
|
||||
err := cg.GenerateAll(tableName, columns)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "❌ 生成失败:%v\n", err)
|
||||
continue
|
||||
}
|
||||
|
||||
fmt.Printf("✅ 成功生成 %s.go 和 %s_dao.go\n", tableName, tableName)
|
||||
}
|
||||
|
||||
fmt.Println()
|
||||
fmt.Println("✨ 代码生成完成!")
|
||||
fmt.Printf("📂 生成的文件在:%s 目录下\n", outputDir)
|
||||
}
|
||||
Reference in New Issue
Block a user