Commits (2)
...@@ -11,6 +11,9 @@ ...@@ -11,6 +11,9 @@
# Output of the go coverage tool, specifically when used with LiteIDE # Output of the go coverage tool, specifically when used with LiteIDE
*.out *.out
# Database files
*.db
# Dependency directories (remove the comment below to include it) # Dependency directories (remove the comment below to include it)
# vendor/ # vendor/
......
{
"serverPort": ":8080",
"dbPath": "comments.db"
}
\ No newline at end of file
...@@ -4,10 +4,51 @@ package main ...@@ -4,10 +4,51 @@ package main
import ( import (
"log" "log"
"os" "os"
"encoding/json"
"os/signal" "os/signal"
db "BackEnd/db" db "BackEnd/db"
) )
var (
serverPort string
dbPath string
)
type Config struct {
ServerPort string `json:"serverPort"`
DbPath string `json:"dbPath"`
}
func readConfig(filePath string) (*Config, error) {
file, err := os.Open(filePath)
if err != nil {
return nil, err
}
defer file.Close()
var config Config
decoder := json.NewDecoder(file)
if err := decoder.Decode(&config); err != nil {
return nil, err
}
return &config, nil
}
func loadConfig() {
config, err := readConfig("config.json")
if err != nil {
log.Fatalf("Failed to read config file: %v", err)
}
if config.ServerPort != "" {
serverPort = config.ServerPort
}
if config.DbPath != "" {
dbPath = config.DbPath
}
log.Printf("Loaded configuration: ServerPort=%s, DbPath=%s", serverPort, dbPath)
}
func main() { func main() {
...@@ -15,7 +56,8 @@ func main() { ...@@ -15,7 +56,8 @@ func main() {
log.Println("INTERN PROJECT - COMMENT SERVICE") log.Println("INTERN PROJECT - COMMENT SERVICE")
log.Println("Press Ctrl+C to exit") log.Println("Press Ctrl+C to exit")
db.InitDB("./comments.db") loadConfig()
db.InitDB(dbPath)
quit := make(chan os.Signal, 1) quit := make(chan os.Signal, 1)
signal.Notify(quit, os.Interrupt) signal.Notify(quit, os.Interrupt)
...@@ -24,8 +66,8 @@ func main() { ...@@ -24,8 +66,8 @@ func main() {
<-quit <-quit
log.Println("Shutting down server...") log.Println("Shutting down server...")
db.CloseDB() db.CloseDB()
os.Exit(0) os.Exit(0)
}() }()
initServer() initServer(serverPort)
} }
\ No newline at end of file
...@@ -5,7 +5,6 @@ import ( ...@@ -5,7 +5,6 @@ import (
"log" "log"
"net/http" "net/http"
"strconv" "strconv"
db "BackEnd/db" db "BackEnd/db"
) )
...@@ -78,7 +77,7 @@ func getCommentHandler(w http.ResponseWriter, r *http.Request) { ...@@ -78,7 +77,7 @@ func getCommentHandler(w http.ResponseWriter, r *http.Request) {
if size == -1 { if size == -1 {
sendResponse(w, 0, "success", CommentList{ sendResponse(w, 0, "success", CommentList{
Total: total, Total: total,
Comments: db.GetComments(), Comments: db.GetAllComments(),
}) })
return return
} }
...@@ -142,8 +141,15 @@ func addCommentHandler(w http.ResponseWriter, r *http.Request) { ...@@ -142,8 +141,15 @@ func addCommentHandler(w http.ResponseWriter, r *http.Request) {
return return
} }
comment, err := db.AddComment(req.Name, req.Content)
if err != nil {
log.Printf("Error adding comment: %v", err)
sendResponse(w, 4, "Failed to add comment", nil)
return
}
// 返回新创建的评论 // 返回新创建的评论
sendResponse(w, 0, "Comment added", db.AddComment(req.Name, req.Content)) sendResponse(w, 0, "Comment added", comment)
} }
// 删除评论处理函数 // 删除评论处理函数
...@@ -187,15 +193,15 @@ func deleteCommentHandler(w http.ResponseWriter, r *http.Request) { ...@@ -187,15 +193,15 @@ func deleteCommentHandler(w http.ResponseWriter, r *http.Request) {
} }
func initServer() { func initServer(serverPort string) {
// 注册路由 // 注册路由
http.HandleFunc("/comment/get", getCommentHandler) http.HandleFunc("/comment/get", getCommentHandler)
http.HandleFunc("/comment/add", addCommentHandler) http.HandleFunc("/comment/add", addCommentHandler)
http.HandleFunc("/comment/delete", deleteCommentHandler) http.HandleFunc("/comment/delete", deleteCommentHandler)
// 启动服务器 // 启动服务器
log.Println("Server starting on http://localhost:8080") log.Println("Server starting on http://localhost" + serverPort)
if err := http.ListenAndServe(":8080", nil); err != nil { if err := http.ListenAndServe(serverPort, nil); err != nil {
log.Fatal("Server failed to start: ", err) log.Fatal("Server failed to start: ", err)
} }
} }
\ No newline at end of file
...@@ -2,39 +2,25 @@ package db ...@@ -2,39 +2,25 @@ package db
import ( import (
//"fmt"
"log" "log"
//"gorm.io/driver/sqlite" "gorm.io/driver/sqlite"
"gorm.io/gorm" "gorm.io/gorm"
"sync"
) )
type Comment struct { type Comment struct {
ID int `json:"id" gorm:"primaryKey;autoIncrement"` // 评论ID ID int `json:"id" gorm:"primaryKey;autoIncrement"` // 评论ID
Name string `json:"name" gorm:"not null"` // 评论者名字 Name string `json:"name" gorm:"type:text;not null"` // 评论者名字
Content string `json:"content" gorm:"not null"` // 评论内容 Content string `json:"content" gorm:"type:text;not null"` // 评论内容
} }
var ( var (
DB *gorm.DB DB *gorm.DB
//once sync.Once once sync.Once
) )
func InitDB(dbPath string) { func InitDB(dbPath string) {
//TODO
AddComment("Alice", "First comment!")
AddComment("Bob", "Great work!")
log.Println("Database initialized successfully.")
}
func CloseDB() {
//TODO
log.Println("Database closed successfully.")
}
/*
func InitDB(dbPath string) {
once.Do(func() { once.Do(func() {
var err error var err error
DB, err = gorm.Open(sqlite.Open(dbPath), &gorm.Config{}) DB, err = gorm.Open(sqlite.Open(dbPath), &gorm.Config{})
...@@ -42,28 +28,24 @@ func InitDB(dbPath string) { ...@@ -42,28 +28,24 @@ func InitDB(dbPath string) {
log.Fatalf("Failed to open database: %v", err) log.Fatalf("Failed to open database: %v", err)
} }
// 创建评论表 err = DB.AutoMigrate(&Comment{})
createTable := ` if err != nil {
CREATE TABLE IF NOT EXISTS comments ( log.Fatalf("Failed to migrate database: %v", err)
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
content TEXT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);`
if err := DB.Exec(createTable).Error; err != nil {
log.Fatalf("Failed to create table: %v", err)
} }
log.Println("Database initialized successfully") log.Printf("Database %s initialized successfully.", dbPath)
}) })
} }
// 关闭数据库连接
func CloseDB() { func CloseDB() {
if DB != nil { if DB != nil {
DB.Close() sqlDB, err := DB.DB()
if err != nil {
log.Fatalf("Failed to get database connection: %v", err)
return
}
sqlDB.Close()
} }
} log.Println("Database closed successfully.")
}
*/ \ No newline at end of file
\ No newline at end of file
package db package db
import ( import (
"sync" "log"
"gorm.io/gorm"
) )
var (
mutex = &sync.RWMutex{}
comments []Comment // 内存存储的评论列表
incrementID int = 1 // 自增ID计数器
)
// GetComments 返回当前请求的评论列表 func GetAllComments() []Comment {
func GetComments() []Comment { return GetCommentsDB(DB)
mutex.RLock()
defer mutex.RUnlock()
return comments
} }
func GetCommentsSlice(Begin int, End int) []Comment { func GetCommentsSlice(Begin int, End int) []Comment {
mutex.RLock() return GetCommentsSliceDB(DB, Begin, End)
defer mutex.RUnlock()
if Begin < 0 || End > len(comments) || Begin > End {
return []Comment{}
}
return comments[Begin:End]
} }
func GetCommentCount() int { func GetCommentCount() int {
mutex.RLock() return GetCommentCountDB(DB)
defer mutex.RUnlock() }
return len(comments)
func AddComment(Name string, Content string) (Comment, error) {
return AddCommentDB(DB, Name, Content)
}
func DeleteComment(Id int) bool {
return DeleteCommentDB(DB, Id)
} }
func AddComment(Name string, Content string) Comment {
mutex.Lock()
defer mutex.Unlock()
func GetCommentsDB(db *gorm.DB) []Comment {
var comments []Comment
if err := db.Find(&comments).Error; err != nil {
log.Printf("GetComments error: %v", err)
return nil
}
return comments
}
func GetCommentCountDB(db *gorm.DB) int {
var total int64
if err := db.Model(&Comment{}).Count(&total).Error; err != nil {
log.Printf("GetCommentCount error: %v", err)
return 0
}
return int(total)
}
func GetCommentsSliceDB(db *gorm.DB, Begin int, End int) []Comment {
var comments []Comment
// 计算总记录数
var total int = GetCommentCountDB(db)
if total == 0 {
return []Comment{} // 如果没有评论,返回空切片
}
// 检查边界条件
if Begin < 0 || total < Begin || total < End || Begin > End {
return []Comment{}
}
// 查询指定范围的评论
if err := db.Limit(End - Begin).Offset(Begin).Find(&comments).Error; err != nil {
log.Printf("GetCommentsSlice find error: %v", err)
return nil
}
return comments
}
func AddCommentDB(db *gorm.DB, Name string, Content string) (Comment, error) {
newComment := Comment{ newComment := Comment{
ID: incrementID,
Name: Name, Name: Name,
Content: Content, Content: Content,
} }
incrementID++ // 使用事务来确保数据一致性
comments = append(comments, newComment) tx := db.Begin()
if err := tx.Create(&newComment).Error; err != nil {
return newComment tx.Rollback()
log.Printf("AddComment error: %v", err)
return Comment{}, err
}
tx.Commit()
return newComment, nil
} }
func DeleteComment(Id int) bool { func DeleteCommentDB(db *gorm.DB, Id int) bool {
mutex.Lock() // 写锁定
defer mutex.Unlock() // 函数返回时解锁
// 查找并删除评论 // 查找并删除评论
found := false if err := db.Delete(&Comment{}, uint(Id)).Error; err != nil {
for i, comment := range comments { log.Printf("DeleteComment error: %v", err)
if comment.ID == Id { return false
// 从切片中删除元素
comments = append(comments[:i], comments[i+1:]...)
found = true
break
}
} }
return found return true
} }
\ No newline at end of file