second commit

This commit is contained in:
lulz1 2024-10-10 16:20:08 +08:00
parent 2aed21477f
commit 5f75ebb02c
6 changed files with 250 additions and 0 deletions

View File

@ -1,9 +1,11 @@
package main
import (
_ "awesomeProject/internal/store"
"awesomeProject/server"
"awesomeProject/store/factory"
"context"
"fmt"
"log"
"os"
"os/signal"
@ -11,6 +13,38 @@ import (
"time"
)
func sendOddNum(cn chan<- int) {
number := 1
for {
cn <- number
number += 2 // 生成下一个奇数
fmt.Println("inside:", number)
time.Sleep(1 * time.Second) // 每 1 秒发送一次
}
}
func sendEvenNum(cn chan<- int) {
number := 2
for {
cn <- number
number += 2
fmt.Println("inside:", number)
time.Sleep(1 * time.Second)
}
}
//func main() {
// cn := make(chan int, 10)
// go sendOddNum(cn)
// go sendEvenNum(cn)
//
// for {
// num := <-cn
// time.Sleep(5 * time.Second)
// fmt.Println("Received:", num)
// }
//}
func main() {
s, err := factory.New("mem") // 创建图书数据存储模块实例
if err != nil {

4
go.mod
View File

@ -1 +1,5 @@
module awesomeProject
go 1.23.2
require github.com/gorilla/mux v1.8.1

View File

@ -1 +1,63 @@
package store
import (
mystore "awesomeProject/store"
factory "awesomeProject/store/factory"
"errors"
"sync"
)
func init() {
factory.Register("mem", &MemStore{
books: make(map[string]*mystore.Book),
})
}
type MemStore struct {
sync.RWMutex
books map[string]*mystore.Book
}
func (m *MemStore) Create(book *mystore.Book) error {
if _, ok := m.books[book.Id]; ok {
return errors.New("book is existed")
}
m.books[book.Id] = book
return nil
}
func (m *MemStore) Update(book *mystore.Book) error {
oldBook, ok := m.books[book.Id]
if !ok {
return errors.New("book not found")
}
oldBook.Name = book.Name
oldBook.Authors = book.Authors
oldBook.Press = book.Press
return nil
}
func (m *MemStore) Get(s string) (mystore.Book, error) {
oldBook, ok := m.books[s]
if !ok {
return mystore.Book{}, errors.New("book not found")
} else {
return *oldBook, nil
}
}
func (m *MemStore) GetAll() ([]mystore.Book, error) {
books := make([]mystore.Book, 0, len(m.books)) // 初始化切片,预分配容量
for _, book := range m.books {
books = append(books, *book) // 解引用并添加到切片中
}
return books, nil // 返回所有书籍
}
func (m *MemStore) Delete(s string) error {
if _, ok := m.books[s]; !ok {
return errors.New("book not found") // 如果书籍未找到,返回错误
}
delete(m.books, s) // 从 map 中删除书籍
return nil // 删除成功,返回 nil
}

View File

@ -1 +1,30 @@
package middleware
import (
"log"
"mime"
"net/http"
)
func Logging(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
log.Printf("recv a %s request from %s", req.Method, req.RemoteAddr)
next.ServeHTTP(w, req)
})
}
func Validating(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
contentType := req.Header.Get("Content-Type")
mediatype, _, err := mime.ParseMediaType(contentType)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
if mediatype != "application/json" {
http.Error(w, "invalid Content-Type", http.StatusUnsupportedMediaType)
return
}
next.ServeHTTP(w, req)
})
}

View File

@ -1 +1,121 @@
package server
import (
"awesomeProject/server/middleware"
"awesomeProject/store"
"context"
"encoding/json"
"github.com/gorilla/mux"
"net/http"
"time"
)
type BookStoreServer struct {
s store.Store
srv *http.Server
}
func NewBookStoreServer(addr string, s store.Store) *BookStoreServer {
srv := &BookStoreServer{s: s, srv: &http.Server{Addr: addr}}
router := mux.NewRouter()
router.HandleFunc("/book", srv.createBookHandler).Methods("POST")
router.HandleFunc("/book/{id}", srv.updateBookHandler).Methods("POST")
router.HandleFunc("/book/{id}", srv.getBookHandler).Methods("GET")
router.HandleFunc("/book", srv.getAllBooksHandler).Methods("GET")
router.HandleFunc("/book/{id}", srv.delBookHandler).Methods("DELETE")
srv.srv.Handler = middleware.Logging(middleware.Validating(router))
return srv
}
func (bs *BookStoreServer) Shutdown(ctx context.Context) error {
return bs.srv.Shutdown(ctx)
}
func (bs *BookStoreServer) createBookHandler(w http.ResponseWriter, req *http.Request) {
dec := json.NewDecoder(req.Body)
var book store.Book
if err := dec.Decode(&book); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
if err := bs.s.Create(&book); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
}
func (bs *BookStoreServer) updateBookHandler(w http.ResponseWriter, req *http.Request) {
dec := json.NewDecoder(req.Body)
var book store.Book
if err := dec.Decode(&book); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
if err := bs.s.Update(&book); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
}
func (bs *BookStoreServer) getAllBooksHandler(w http.ResponseWriter, req *http.Request) {
books, err := bs.s.GetAll()
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
response(w, books)
}
func (bs *BookStoreServer) getBookHandler(w http.ResponseWriter, req *http.Request) {
id, ok := mux.Vars(req)["id"]
if !ok {
http.Error(w, "no id found in request", http.StatusBadRequest)
return
}
err := bs.s.Delete(id)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
}
func (bs *BookStoreServer) delBookHandler(w http.ResponseWriter, req *http.Request) {
id, ok := mux.Vars(req)["id"]
if !ok {
http.Error(w, "no id found in request", http.StatusBadRequest)
return
}
book, err := bs.s.Get(id)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
response(w, book)
}
func response(w http.ResponseWriter, v interface{}) {
data, err := json.Marshal(v)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
if _, err := w.Write(data); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}
func (bs *BookStoreServer) ListenAndServe() (<-chan error, error) {
var err error
errChan := make(chan error)
go func() {
err = bs.srv.ListenAndServe()
errChan <- err
}()
select {
case err = <-errChan:
return nil, err
case <-time.After(time.Second):
return errChan, nil
}
}

View File

@ -22,6 +22,7 @@ func Register(name string, p store.Store) {
}
providers[name] = p
}
func New(providerName string) (store.Store, error) {
providersMu.RLock()
p, ok := providers[providerName]