HW12 completed

pull/13/head
Andrey Ivanov 2020-09-25 11:20:26 +03:00 committed by Andrey Ivanov
parent acc97b1ac9
commit 73a669ab90
9 changed files with 136 additions and 91 deletions

View File

@ -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)
})
}

View File

@ -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
}

View File

@ -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 {

View File

@ -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
}

View File

@ -1,4 +1,4 @@
package memorystorage
package memory
import (
"sync"

View File

@ -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))
})
}

View File

@ -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))
})
}

View File

@ -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
}

View File

@ -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