feat: 初始提交 - Code Server Bridge完整实现
- OAuth认证系统(Gitea + Lua扩展) - Git自动化操作(本地/SSH远程) - 实时进度WebSocket推送 - 现代化Tab界面UI - Cobra CLI命令行(init/version/serve) - 完整构建系统(Makefile + Taskfile) - UPX压缩支持(体积减少70%)
This commit is contained in:
10
internal/db/connect.go
Normal file
10
internal/db/connect.go
Normal file
@@ -0,0 +1,10 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"github.com/glebarez/sqlite"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func connectSQLite(filepath string) gorm.Dialector {
|
||||
return sqlite.Open(filepath + "?cache=shared&_fk=1&_driver=modernc.org/sqlite")
|
||||
}
|
||||
50
internal/db/db.go
Normal file
50
internal/db/db.go
Normal file
@@ -0,0 +1,50 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"cs-bridge/internal/config"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/logger"
|
||||
)
|
||||
|
||||
var db *gorm.DB
|
||||
|
||||
func init() {
|
||||
if _, err := os.Stat("./data"); os.IsNotExist(err) {
|
||||
_ = os.Mkdir("./data", os.ModePerm)
|
||||
}
|
||||
}
|
||||
|
||||
func GetDB() *gorm.DB {
|
||||
if db == nil {
|
||||
panic("数据库未初始化,请先调用 db.InitDB()")
|
||||
}
|
||||
return db
|
||||
}
|
||||
|
||||
func InitDB(cfg config.Database, log *zap.Logger) {
|
||||
go func() {
|
||||
if err := recover(); err != nil {
|
||||
panic(fmt.Sprintf("Init DB Error: %v", err))
|
||||
}
|
||||
}()
|
||||
|
||||
fmt.Println(cfg.SqliteDbPath)
|
||||
dialector := connectSQLite(cfg.SqliteDbPath)
|
||||
|
||||
var err error
|
||||
db, err = gorm.Open(dialector, &gorm.Config{
|
||||
Logger: NewZapGormLogger(log).LogMode(logger.Info),
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// 自动迁移数据库模型
|
||||
if err := db.AutoMigrate(&WorkspaceToken{}); err != nil {
|
||||
panic(fmt.Sprintf("Failed to migrate WorkspaceToken model: %v", err))
|
||||
}
|
||||
}
|
||||
81
internal/db/gorm_logger.go
Normal file
81
internal/db/gorm_logger.go
Normal file
@@ -0,0 +1,81 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"gorm.io/gorm/logger"
|
||||
"gorm.io/gorm/utils"
|
||||
)
|
||||
|
||||
type ZapGormLogger struct {
|
||||
ZapLogger *zap.Logger
|
||||
LogLevel logger.LogLevel
|
||||
SlowThreshold time.Duration
|
||||
}
|
||||
|
||||
func NewZapGormLogger(zapLogger *zap.Logger) *ZapGormLogger {
|
||||
return &ZapGormLogger{
|
||||
ZapLogger: zapLogger,
|
||||
LogLevel: logger.Info,
|
||||
SlowThreshold: time.Second, // 1s 慢查询阈值
|
||||
}
|
||||
}
|
||||
|
||||
func (l *ZapGormLogger) LogMode(level logger.LogLevel) logger.Interface {
|
||||
newlogger := *l
|
||||
newlogger.LogLevel = level
|
||||
return &newlogger
|
||||
}
|
||||
|
||||
func (l *ZapGormLogger) Info(ctx context.Context, msg string, data ...interface{}) {
|
||||
if l.LogLevel >= logger.Info {
|
||||
l.ZapLogger.Sugar().Infof(msg, data...)
|
||||
}
|
||||
}
|
||||
|
||||
func (l *ZapGormLogger) Warn(ctx context.Context, msg string, data ...interface{}) {
|
||||
if l.LogLevel >= logger.Warn {
|
||||
l.ZapLogger.Sugar().Warnf(msg, data...)
|
||||
}
|
||||
}
|
||||
|
||||
func (l *ZapGormLogger) Error(ctx context.Context, msg string, data ...interface{}) {
|
||||
if l.LogLevel >= logger.Error {
|
||||
l.ZapLogger.Sugar().Errorf(msg, data...)
|
||||
}
|
||||
}
|
||||
|
||||
func (l *ZapGormLogger) Trace(ctx context.Context, begin time.Time, fc func() (sql string, rowsAffected int64), err error) {
|
||||
if l.LogLevel <= logger.Silent {
|
||||
return
|
||||
}
|
||||
elapsed := time.Since(begin)
|
||||
sql, rows := fc()
|
||||
|
||||
switch {
|
||||
case err != nil && l.LogLevel >= logger.Error:
|
||||
l.ZapLogger.Error("SQL Error",
|
||||
zap.Error(err),
|
||||
zap.String("sql", sql),
|
||||
zap.Int64("rows", rows),
|
||||
zap.Duration("elapsed", elapsed),
|
||||
zap.String("file", utils.FileWithLineNum()),
|
||||
)
|
||||
case elapsed > l.SlowThreshold && l.SlowThreshold != 0 && l.LogLevel >= logger.Warn:
|
||||
l.ZapLogger.Warn("Slow SQL",
|
||||
zap.Duration("elapsed", elapsed),
|
||||
zap.String("sql", sql),
|
||||
zap.Int64("rows", rows),
|
||||
zap.String("file", utils.FileWithLineNum()),
|
||||
)
|
||||
case l.LogLevel >= logger.Info:
|
||||
l.ZapLogger.Info("SQL",
|
||||
zap.String("sql", sql),
|
||||
zap.Int64("rows", rows),
|
||||
zap.Duration("elapsed", elapsed),
|
||||
zap.String("file", utils.FileWithLineNum()),
|
||||
)
|
||||
}
|
||||
}
|
||||
16
internal/db/workspace_token.go
Normal file
16
internal/db/workspace_token.go
Normal file
@@ -0,0 +1,16 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// WorkspaceToken 工作区访问令牌模型
|
||||
// 用于存储一次性/限时的workspace访问token
|
||||
type WorkspaceToken struct {
|
||||
ID uint `gorm:"primarykey"`
|
||||
Token string `gorm:"uniqueIndex;not null"` // Token哈希值
|
||||
WorkspacePath string `gorm:"not null"` // 工作区路径
|
||||
CreatedAt time.Time // 创建时间
|
||||
ExpiresAt time.Time `gorm:"index"` // 过期时间
|
||||
Used bool `gorm:"default:false;index"` // 是否已使用
|
||||
}
|
||||
Reference in New Issue
Block a user