HW12 completed
parent
acc97b1ac9
commit
73a669ab90
|
@ -3,6 +3,7 @@ package app
|
|||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/internal/logger"
|
||||
store "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/internal/storage"
|
||||
|
@ -40,7 +41,18 @@ func (a *App) Handler(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
func (a *App) LoggingMiddleware(next http.HandlerFunc) http.HandlerFunc {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
a.Logger.Infof("receive %s request from IP %s", r.Method, r.RemoteAddr)
|
||||
start := time.Now()
|
||||
defer func() {
|
||||
var path, useragent string
|
||||
if r.URL != nil {
|
||||
path = r.URL.Path
|
||||
}
|
||||
if len(r.UserAgent()) > 0 {
|
||||
useragent = r.UserAgent()
|
||||
}
|
||||
latency := time.Since(start)
|
||||
a.Logger.Infof("receive %s request from IP: %s on path: %s, duration: %s useragent: %s ", r.Method, r.RemoteAddr, path, latency, useragent)
|
||||
}()
|
||||
next.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -66,11 +66,6 @@ func (l *Logger) Fatalf(format string, args ...interface{}) {
|
|||
}
|
||||
|
||||
func validLevel(level string) bool {
|
||||
l := []string{"debug", "info", "warn", "error", "fatal"}
|
||||
for _, v := range l {
|
||||
if strings.ToLower(level) == v {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
var l = map[string]int{"debug": 1, "info": 1, "warn": 1, "error": 1, "fatal": 1}
|
||||
return l[strings.ToLower(level)] == 1
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package http
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
"net/http"
|
||||
|
||||
|
@ -11,13 +10,10 @@ import (
|
|||
type Server struct {
|
||||
server *http.Server
|
||||
app app.App
|
||||
ctx context.Context
|
||||
cancel context.CancelFunc
|
||||
}
|
||||
|
||||
func NewServer(app *app.App, address string, port string) *Server {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
return &Server{server: &http.Server{Addr: net.JoinHostPort(address, port), Handler: app.LoggingMiddleware(app.Handler)}, app: *app, ctx: ctx, cancel: cancel}
|
||||
return &Server{server: &http.Server{Addr: net.JoinHostPort(address, port), Handler: app.LoggingMiddleware(app.Handler)}, app: *app}
|
||||
}
|
||||
|
||||
func (s *Server) Start() error {
|
||||
|
|
|
@ -1,6 +1,14 @@
|
|||
package event
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type Event struct {
|
||||
Title string
|
||||
Date string
|
||||
Title string
|
||||
Date time.Time
|
||||
Latency time.Duration
|
||||
Note string
|
||||
UserID int64
|
||||
NotifyTime time.Duration
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package memorystorage
|
||||
package memory
|
||||
|
||||
import (
|
||||
"sync"
|
|
@ -0,0 +1,60 @@
|
|||
package memory
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/internal/storage/event"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
const dateTimeLayout = "2006-01-02 15:04:00 -0700"
|
||||
|
||||
func TestMemoryStorage(t *testing.T) {
|
||||
s := New()
|
||||
dateParced1, _ := time.Parse(dateTimeLayout, "11.11.1111")
|
||||
dateParced2, _ := time.Parse(dateTimeLayout, "22.11.22222")
|
||||
|
||||
t.Run("Empty storage", func(t *testing.T) {
|
||||
require.Equal(t, 0, len(s.Events))
|
||||
})
|
||||
id, err := s.Create(event.Event{Title: "event1", Date: dateParced1})
|
||||
|
||||
t.Run("Create events", func(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 1, len(s.Events))
|
||||
require.Equal(t, event.Event{Title: "event1", Date: dateParced1}, s.Events[id])
|
||||
})
|
||||
|
||||
t.Run("Update event", func(t *testing.T) {
|
||||
err := s.Update(id, event.Event{Title: "event1_modifyed", Date: dateParced2})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 1, len(s.Events))
|
||||
require.Equal(t, event.Event{Title: "event1_modifyed", Date: dateParced2}, s.Events[id])
|
||||
})
|
||||
|
||||
t.Run("List event", func(t *testing.T) {
|
||||
res, err := s.List()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 1, len(res))
|
||||
require.Equal(t, event.Event{Title: "event1_modifyed", Date: dateParced2}, res[id])
|
||||
})
|
||||
|
||||
t.Run("Get event by ID", func(t *testing.T) {
|
||||
res, ok := s.GetByID(id)
|
||||
require.Equal(t, ok, true)
|
||||
require.Equal(t, event.Event{Title: "event1_modifyed", Date: dateParced2}, res)
|
||||
})
|
||||
|
||||
t.Run("Get event by fake ID", func(t *testing.T) {
|
||||
res, ok := s.GetByID(53663)
|
||||
require.Equal(t, ok, false)
|
||||
require.Equal(t, event.Event{}, res)
|
||||
})
|
||||
|
||||
t.Run("Delete event", func(t *testing.T) {
|
||||
err := s.Delete(id)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 0, len(s.Events))
|
||||
})
|
||||
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
package memorystorage
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/internal/storage/event"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMemoryStorage(t *testing.T) {
|
||||
s := New()
|
||||
|
||||
t.Run("Empty storage", func(t *testing.T) {
|
||||
require.Equal(t,0, len(s.Events))
|
||||
})
|
||||
|
||||
id,err:=s.Create(event.Event{ Title:"event1",Date:"11.11.1111" })
|
||||
|
||||
t.Run("Create events", func(t *testing.T) {
|
||||
require.NoError(t,err)
|
||||
require.Equal(t,1, len(s.Events))
|
||||
require.Equal(t,event.Event{ Title:"event1",Date:"11.11.1111" }, s.Events[id])
|
||||
})
|
||||
|
||||
t.Run("Update event", func(t *testing.T) {
|
||||
err:=s.Update(id,event.Event{ Title:"event1_modifyed",Date:"22.11.22222" })
|
||||
require.NoError(t,err)
|
||||
require.Equal(t,1, len(s.Events))
|
||||
require.Equal(t,event.Event{ Title:"event1_modifyed",Date:"22.11.22222" }, s.Events[id])
|
||||
})
|
||||
|
||||
t.Run("List event", func(t *testing.T) {
|
||||
res,err:=s.List()
|
||||
require.NoError(t,err)
|
||||
require.Equal(t,1, len(res))
|
||||
require.Equal(t,event.Event{ Title:"event1_modifyed",Date:"22.11.22222" }, res[id])
|
||||
})
|
||||
|
||||
t.Run("Get event by ID", func(t *testing.T) {
|
||||
res,ok := s.GetByID(id)
|
||||
require.Equal(t,ok,true)
|
||||
require.Equal(t,event.Event{ Title:"event1_modifyed",Date:"22.11.22222" }, res)
|
||||
})
|
||||
|
||||
t.Run("Get event by fake ID", func(t *testing.T) {
|
||||
res,ok := s.GetByID(53663)
|
||||
require.Equal(t,ok,false)
|
||||
require.Equal(t,event.Event{}, res)
|
||||
})
|
||||
|
||||
t.Run("Delete event", func(t *testing.T) {
|
||||
err := s.Delete(id)
|
||||
require.NoError(t,err)
|
||||
require.Equal(t,0, len(s.Events))
|
||||
})
|
||||
|
||||
}
|
|
@ -1,11 +1,14 @@
|
|||
package sqlstorage
|
||||
package sql
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"time"
|
||||
|
||||
"github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/internal/storage/event"
|
||||
)
|
||||
|
||||
const dateTimeLayout = "2006-01-02 15:04:00 -0700"
|
||||
|
||||
type Config struct {
|
||||
User string
|
||||
Pass string
|
||||
|
@ -37,9 +40,15 @@ func (s *Storage) Close() error {
|
|||
|
||||
func (s *Storage) Create(event event.Event) (int64, error) {
|
||||
res, err := s.db.Exec(
|
||||
`INSERT INTO events (title, date) VALUES ($1, $2)`,
|
||||
`INSERT INTO events
|
||||
(title, date, latency, note, userID, notifyTime) VALUES
|
||||
($1, $2, $3, $4, $5, $6)`,
|
||||
event.Title,
|
||||
event.Date,
|
||||
event.Date.Format(dateTimeLayout),
|
||||
event.Latency,
|
||||
event.Note,
|
||||
event.UserID,
|
||||
event.NotifyTime,
|
||||
)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
|
@ -49,9 +58,15 @@ func (s *Storage) Create(event event.Event) (int64, error) {
|
|||
|
||||
func (s *Storage) Update(id int64, event event.Event) error {
|
||||
_, err := s.db.Exec(
|
||||
`UPDATE events set title=$1, date=$2 where id=$3`,
|
||||
`UPDATE events set
|
||||
title=$1, date=$2, latency=$3, note=$4, userID=$5, notifyTime=$6
|
||||
where id=$7`,
|
||||
event.Title,
|
||||
event.Date,
|
||||
event.Date.Format(dateTimeLayout),
|
||||
event.Latency,
|
||||
event.Note,
|
||||
event.UserID,
|
||||
event.NotifyTime,
|
||||
id,
|
||||
)
|
||||
return err
|
||||
|
@ -68,32 +83,43 @@ func (s *Storage) Delete(id int64) error {
|
|||
func (s *Storage) List() (map[int64]event.Event, error) {
|
||||
res := make(map[int64]event.Event)
|
||||
results, err := s.db.Query(
|
||||
`SELECT (id,title,date) from events ORDER BY id`)
|
||||
if err != nil || results.Err() != nil {
|
||||
return res, err
|
||||
`SELECT (id,title,date,latency,note,userID,notifyTime) from events ORDER BY id`)
|
||||
if err != nil {
|
||||
return map[int64]event.Event{}, err
|
||||
}
|
||||
defer results.Close()
|
||||
for results.Next() {
|
||||
var tmp struct {
|
||||
id int64
|
||||
title string
|
||||
date string
|
||||
}
|
||||
err = results.Scan(&tmp.id, &tmp.title, &tmp.date)
|
||||
var id int64
|
||||
var evt event.Event
|
||||
var dateRaw string
|
||||
err = results.Scan(&id, &evt.Title, &dateRaw, &evt.Latency, &evt.Note, &evt.UserID, &evt.NotifyTime)
|
||||
if err != nil {
|
||||
return res, err
|
||||
return map[int64]event.Event{}, err
|
||||
}
|
||||
res[tmp.id] = event.Event{Title: tmp.title, Date: tmp.date}
|
||||
evt.Date, err = time.Parse(dateTimeLayout, dateRaw)
|
||||
if err != nil {
|
||||
return map[int64]event.Event{}, err
|
||||
}
|
||||
res[id] = evt
|
||||
}
|
||||
if results.Err() != nil {
|
||||
return map[int64]event.Event{}, results.Err()
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (s *Storage) GetByID(id int64) (event.Event, bool) {
|
||||
var res event.Event
|
||||
var dateRaw string
|
||||
err := s.db.QueryRow(
|
||||
`SELECT (title,date) from events where id=$1`, id).Scan(res.Title, res.Date)
|
||||
`SELECT (id,title,date,latency,note,userID,notifyTime) from events where id=$1`, id).Scan(res.Title, dateRaw, res.Latency, res.Note, res.UserID, res.NotifyTime)
|
||||
if err != nil {
|
||||
return res, false
|
||||
}
|
||||
dateParced, err := time.Parse(dateTimeLayout, dateRaw)
|
||||
if err != nil {
|
||||
return res, false
|
||||
}
|
||||
res.Date = dateParced
|
||||
return res, true
|
||||
}
|
|
@ -3,7 +3,11 @@
|
|||
CREATE TABLE events (
|
||||
id int(16) NOT NULL AUTO_INCREMENT,
|
||||
title varchar(255) NOT NULL,
|
||||
date varchar(255) NOT NULL,
|
||||
date datetime NOT NULL,
|
||||
latency int(16) NOT NULL,
|
||||
note text,
|
||||
userID int(16),
|
||||
notifyTime int(16)
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;;
|
||||
-- +goose StatementEnd
|
||||
|
@ -11,4 +15,4 @@ CREATE TABLE events (
|
|||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
DROP TABLE events;
|
||||
-- +goose StatementEnd
|
||||
-- +goose StatementEnd
|
||||
|
|
Loading…
Reference in New Issue