From 47e7d8847e89e73792d7af1323ce58f4ee7385a2 Mon Sep 17 00:00:00 2001 From: Andrey Ivanov Date: Tue, 1 Sep 2020 12:21:21 +0300 Subject: [PATCH 01/11] HW12 config & logger is completed --- hw12_13_14_15_calendar/cmd/calendar/config.go | 14 ---- hw12_13_14_15_calendar/cmd/calendar/main.go | 25 ++++--- hw12_13_14_15_calendar/configs/config.toml | 10 ++- hw12_13_14_15_calendar/go.mod | 11 ++- hw12_13_14_15_calendar/internal/app/app.go | 7 +- .../internal/config/config.go | 35 +++++++++ .../internal/config/config_test.go | 54 +++++++++++++ .../internal/logger/logger.go | 75 +++++++++++++++++-- .../internal/logger/logger_test.go | 56 +++++++++++++- .../internal/server/http/server.go | 6 +- .../internal/storage/sql/storage.go | 2 + 11 files changed, 253 insertions(+), 42 deletions(-) delete mode 100644 hw12_13_14_15_calendar/cmd/calendar/config.go create mode 100644 hw12_13_14_15_calendar/internal/config/config.go create mode 100644 hw12_13_14_15_calendar/internal/config/config_test.go diff --git a/hw12_13_14_15_calendar/cmd/calendar/config.go b/hw12_13_14_15_calendar/cmd/calendar/config.go deleted file mode 100644 index 1d35a47..0000000 --- a/hw12_13_14_15_calendar/cmd/calendar/config.go +++ /dev/null @@ -1,14 +0,0 @@ -package main - -// При желании конфигурацию можно вынести в internal/config. -// Организация конфига в main принуждает нас сужать API компонентов, использовать -// при их конструировании только необходимые параметры, а также уменьшает вероятность циклической зависимости. -type Config struct { - // TODO -} - -func NewConfig() Config { - return Config{} -} - -// TODO diff --git a/hw12_13_14_15_calendar/cmd/calendar/main.go b/hw12_13_14_15_calendar/cmd/calendar/main.go index ceaa900..91a04dc 100644 --- a/hw12_13_14_15_calendar/cmd/calendar/main.go +++ b/hw12_13_14_15_calendar/cmd/calendar/main.go @@ -2,27 +2,32 @@ package main import ( "flag" + oslog "log" "os" "os/signal" - - "github.com/fixme_my_friend/hw12_13_14_15_calendar/internal/app" - "github.com/fixme_my_friend/hw12_13_14_15_calendar/internal/logger" - internalhttp "github.com/fixme_my_friend/hw12_13_14_15_calendar/internal/server/http" - memorystorage "github.com/fixme_my_friend/hw12_13_14_15_calendar/internal/storage/memory" + "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/internal/config" + "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/internal/app" + "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/internal/logger" + internalhttp "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/internal/server/http" + memorystorage "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/internal/storage/memory" ) var configFile string func init() { flag.StringVar(&configFile, "config", "/etc/calendar/config.toml", "Path to configuration file") + flag.Parse() } func main() { - config := NewConfig() - logg := logger.New(config.Logger.Level) + conf, err := config.NewConfig(configFile) + if err != nil { oslog.Fatal("не удалось открыть файл конфигурации:", err.Error())} + + log, err := logger.New(conf) + if err != nil { oslog.Fatal("не удалось запустить логер:", err.Error())} storage := memorystorage.New() - calendar := app.New(logg, storage) + calendar := app.New(log, storage) server := internalhttp.NewServer(calendar) @@ -34,12 +39,12 @@ func main() { signal.Stop(signals) if err := server.Stop(); err != nil { - logger.Error("failed to stop http server: " + err.String()) + log.Error("failed to stop http server: " + err.Error()) } }() if err := server.Start(); err != nil { - logger.Error("failed to start http server: " + err.String()) + log.Error("failed to start http server: " + err.Error()) os.Exit(1) } } diff --git a/hw12_13_14_15_calendar/configs/config.toml b/hw12_13_14_15_calendar/configs/config.toml index 5b33eb0..dc28273 100644 --- a/hw12_13_14_15_calendar/configs/config.toml +++ b/hw12_13_14_15_calendar/configs/config.toml @@ -1,5 +1,11 @@ [logger] +file = "./calendar.log" level = "INFO" -# TODO -# ... +[storage] +in_memory = false +sql_host = "localhost" +sql_port = "5432" +sql_dbase = "calendar" +sql_user = "calendar" +sql_pass = "12345678" \ No newline at end of file diff --git a/hw12_13_14_15_calendar/go.mod b/hw12_13_14_15_calendar/go.mod index 3eb18a3..db45e6a 100644 --- a/hw12_13_14_15_calendar/go.mod +++ b/hw12_13_14_15_calendar/go.mod @@ -1,3 +1,12 @@ -module github.com/fixme_my_friend/hw12_13_14_15_calendar +module github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar go 1.14 + +require ( + github.com/BurntSushi/toml v0.3.1 + github.com/amitrai48/logger v0.0.0-20190214092904-448001c055ec + github.com/stretchr/testify v1.4.0 + go.uber.org/zap v1.15.0 + golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5 + gopkg.in/yaml.v2 v2.3.0 // indirect +) diff --git a/hw12_13_14_15_calendar/internal/app/app.go b/hw12_13_14_15_calendar/internal/app/app.go index bbbdaea..e34970b 100644 --- a/hw12_13_14_15_calendar/internal/app/app.go +++ b/hw12_13_14_15_calendar/internal/app/app.go @@ -2,8 +2,6 @@ package app import ( "context" - - "github.com/fixme_my_friend/hw12_13_14_15_calendar/internal/storage" ) type App struct { @@ -22,8 +20,9 @@ func New(logger Logger, storage Storage) *App { return &App{} } -func (a *App) CreateEvent(ctx context.Context, id string, title string) error { - return a.storage.CreateEvent(storage.Event{ID: id, Title: title}) +func (a *App) CreateEvent(ctx context.Context, id string, title string) (err error) { + //err = a.storage.CreateEvent(storage.Event{ID: id, Title: title}) + return err } // TODO diff --git a/hw12_13_14_15_calendar/internal/config/config.go b/hw12_13_14_15_calendar/internal/config/config.go new file mode 100644 index 0000000..d876311 --- /dev/null +++ b/hw12_13_14_15_calendar/internal/config/config.go @@ -0,0 +1,35 @@ +package config + +import ( + "github.com/BurntSushi/toml" + "io/ioutil" + "os" +) + +type Config struct { + Logger struct{ + File string + Level string + MuteStdout bool + } + Storage struct { + In_memory bool + Sql_host string + Sql_port string + Sql_dbase string + Sql_user string + Sql_pass string + } +} + +// Confita может быти и хороша, но она не возвращает ошибки, если не может распарсить файл в структуру. Мне не нравится такая "молчаливость" +func NewConfig(configFile string) (Config, error) { + f,err:= os.Open(configFile) + if err != nil {return Config{}, err} + defer f.Close() + s,err := ioutil.ReadAll(f) + if err != nil {return Config{}, err} + var config Config + _, err = toml.Decode(string(s), &config) + return config, err +} diff --git a/hw12_13_14_15_calendar/internal/config/config_test.go b/hw12_13_14_15_calendar/internal/config/config_test.go new file mode 100644 index 0000000..9d9d14c --- /dev/null +++ b/hw12_13_14_15_calendar/internal/config/config_test.go @@ -0,0 +1,54 @@ +package config + +import ( + "github.com/stretchr/testify/require" + "io/ioutil" + oslog "log" + "os" + "testing" +) + +var _ = func() bool { + testing.Init() + return true +}() + +func TestNewConfig(t *testing.T) { + + badfile, err := ioutil.TempFile("", "conf.") + if err != nil { oslog.Fatal(err) } + defer os.Remove(badfile.Name()) + badfile.WriteString(`aefSD +sadfg +RFABND FYGUMG +V`) + badfile.Sync() + + goodfile, err := ioutil.TempFile("", "conf.") + if err != nil { oslog.Fatal(err) } + defer os.Remove(goodfile.Name()) + goodfile.WriteString(`[storage] +in_memory = true +sql_host = "localhost"`) + goodfile.Sync() + + t.Run("No such file", func(t *testing.T) { + c,e := NewConfig("adfergdth") + require.Equal(t,Config{},c) + require.Error(t,e) + }) + + t.Run("Bad file", func(t *testing.T) { + c,e := NewConfig(badfile.Name()) + require.Equal(t,Config{},c) + require.Error(t,e) + }) + + t.Run("TOML reading", func(t *testing.T) { + c,e := NewConfig(goodfile.Name()) + require.Equal(t,true,c.Storage.In_memory) + require.Equal(t,"localhost",c.Storage.Sql_host) + require.NoError(t,e) + }) + +} diff --git a/hw12_13_14_15_calendar/internal/logger/logger.go b/hw12_13_14_15_calendar/internal/logger/logger.go index bdba951..459c010 100644 --- a/hw12_13_14_15_calendar/internal/logger/logger.go +++ b/hw12_13_14_15_calendar/internal/logger/logger.go @@ -1,11 +1,76 @@ package logger -type Logger struct { - // TODO +import ( + "errors" + amitralog "github.com/amitrai48/logger" + "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/internal/config" + "log" + "os" + "strings" +) + +type Logger interface { + Debug(msg string) + Info(msg string) + Warn(msg string) + Error(msg string) + Fatal(msg string) } -func New(level string) *Logger { - return &Logger{} +type Log struct { + Logger amitralog.Logger } -// TODO +func New(conf config.Config) (Log, error) { + + if conf.Logger.File=="" || !validLevel(conf.Logger.Level) { + return Log{}, errors.New("invalid logger config") + } + + c := amitralog.Configuration{ + EnableConsole: !conf.Logger.MuteStdout, + ConsoleLevel: amitralog.Fatal, + ConsoleJSONFormat: false, + EnableFile: true, + FileLevel: strings.ToLower(conf.Logger.Level), + FileJSONFormat: true, + FileLocation: conf.Logger.File, + } + + if err := amitralog.NewLogger(c, amitralog.InstanceZapLogger); err != nil { + log.Fatalf("Could not instantiate log %s", err.Error()) + } + l := amitralog.WithFields(amitralog.Fields{"hw": "12"}) + return Log{Logger: l}, nil +} + +func (l Log) Debug(format string, args ...interface{}) { + l.Logger.Debugf(format, args) +} + +func (l *Log) Info(format string, args ...interface{}) { + l.Logger.Infof(format, args) +} + +func (l *Log) Warn(format string, args ...interface{}) { + l.Logger.Warnf(format, args) +} + +func (l *Log) Error(format string, args ...interface{}) { + l.Logger.Errorf(format, args) +} + +func (l *Log) Fatal(format string, args ...interface{}) { + l.Logger.Fatalf(format, args) + os.Exit(2) +} + +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 +} \ No newline at end of file diff --git a/hw12_13_14_15_calendar/internal/logger/logger_test.go b/hw12_13_14_15_calendar/internal/logger/logger_test.go index 34bb72c..f7dd5fb 100644 --- a/hw12_13_14_15_calendar/internal/logger/logger_test.go +++ b/hw12_13_14_15_calendar/internal/logger/logger_test.go @@ -1,7 +1,57 @@ package logger -import "testing" +import ( + "github.com/stretchr/testify/require" + "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/internal/config" + "io/ioutil" + oslog "log" + "os" + "strings" + "testing" +) -func TestLogger(t *testing.T) { - // TODO +func TestLoggerLogic(t *testing.T) { + tmpfile, err := ioutil.TempFile("", "log.") + if err != nil { oslog.Fatal(err) } + defer os.Remove(tmpfile.Name()) + + conf := config.Config{Logger: struct { + File string + Level string + MuteStdout bool + }{File: tmpfile.Name(), Level: "warn", MuteStdout: false}} + log, err := New(conf) + if err != nil { oslog.Fatal(err) } + + t.Run("Messages arround the level", func(t *testing.T) { + log.Debug("debug message") + log.Error("error message") + + res,err := ioutil.ReadAll(tmpfile) + if err != nil { oslog.Fatal(err) } + require.Less(t,strings.Index(string(res),"debug message"),0) + require.Greater(t,strings.Index(string(res),"error message"),0) + }) } + +func TestLoggerNegative(t *testing.T) { + t.Run("Bad file name", func(t *testing.T) { + conf := config.Config{Logger: struct { + File string + Level string + MuteStdout bool + }{File: "", Level: "debug", MuteStdout: true}} + _, err := New(conf) + require.Error(t,err, "invalid logger config") + }) + + t.Run("Bad level", func(t *testing.T) { + conf := config.Config{Logger: struct { + File string + Level string + MuteStdout bool + }{File: "asdafad", Level: "wegretryjt", MuteStdout: true}} + _, err := New(conf) + require.Error(t,err,"invalid logger config") + }) +} \ No newline at end of file diff --git a/hw12_13_14_15_calendar/internal/server/http/server.go b/hw12_13_14_15_calendar/internal/server/http/server.go index cdbefb8..b94faf3 100644 --- a/hw12_13_14_15_calendar/internal/server/http/server.go +++ b/hw12_13_14_15_calendar/internal/server/http/server.go @@ -1,7 +1,5 @@ package internalhttp -import "context" - type Server struct { // TODO } @@ -16,11 +14,13 @@ func NewServer(app Application) *Server { func (s *Server) Start() error { // TODO + return nil } func (s *Server) Stop() error { - ctx, cancel := context.WithTimeout(context.Background(), shutdownTimeout) + //ctx, cancel := context.WithTimeout(context.Background(), shutdownTimeout) // TODO + return nil } // TODO diff --git a/hw12_13_14_15_calendar/internal/storage/sql/storage.go b/hw12_13_14_15_calendar/internal/storage/sql/storage.go index 5845045..550e449 100644 --- a/hw12_13_14_15_calendar/internal/storage/sql/storage.go +++ b/hw12_13_14_15_calendar/internal/storage/sql/storage.go @@ -12,8 +12,10 @@ func New() *Storage { func (s *Storage) Connect(ctx context.Context) error { // TODO + return nil } func (s *Storage) Close(ctx context.Context) error { // TODO + return nil } From 5c07ac5193b5c4573f0b59965ee13ac4cc003826 Mon Sep 17 00:00:00 2001 From: Andrey Ivanov Date: Tue, 1 Sep 2020 15:37:15 +0300 Subject: [PATCH 02/11] HW12 mutim storages --- hw12_13_14_15_calendar/Makefile | 4 +- .../internal/storage/memory/storage.go | 14 ----- .../internal/storage/memory/storage_test.go | 7 --- .../internal/storage/sql/storage.go | 21 -------- .../{internal => src}/app/app.go | 0 .../{internal => src}/config/config.go | 26 ++++++---- .../{internal => src}/config/config_test.go | 28 +++++----- .../{internal => src}/logger/logger.go | 12 ++--- .../{internal => src}/logger/logger_test.go | 26 ++++++---- .../{cmd/calendar => src}/main.go | 26 ++++++---- .../server/http/middleware.go | 0 .../{internal => src}/server/http/server.go | 0 .../storage => src/storage/event}/event.go | 4 +- .../src/storage/memory/memorystorage.go | 35 +++++++++++++ .../src/storage/sql/sqlstorage.go | 51 +++++++++++++++++++ hw12_13_14_15_calendar/src/storage/store.go | 24 +++++++++ 16 files changed, 184 insertions(+), 94 deletions(-) delete mode 100644 hw12_13_14_15_calendar/internal/storage/memory/storage.go delete mode 100644 hw12_13_14_15_calendar/internal/storage/memory/storage_test.go delete mode 100644 hw12_13_14_15_calendar/internal/storage/sql/storage.go rename hw12_13_14_15_calendar/{internal => src}/app/app.go (100%) rename hw12_13_14_15_calendar/{internal => src}/config/config.go (67%) rename hw12_13_14_15_calendar/{internal => src}/config/config_test.go (61%) rename hw12_13_14_15_calendar/{internal => src}/logger/logger.go (85%) rename hw12_13_14_15_calendar/{internal => src}/logger/logger_test.go (69%) rename hw12_13_14_15_calendar/{cmd/calendar => src}/main.go (51%) rename hw12_13_14_15_calendar/{internal => src}/server/http/middleware.go (100%) rename hw12_13_14_15_calendar/{internal => src}/server/http/server.go (100%) rename hw12_13_14_15_calendar/{internal/storage => src/storage/event}/event.go (64%) create mode 100644 hw12_13_14_15_calendar/src/storage/memory/memorystorage.go create mode 100644 hw12_13_14_15_calendar/src/storage/sql/sqlstorage.go create mode 100644 hw12_13_14_15_calendar/src/storage/store.go diff --git a/hw12_13_14_15_calendar/Makefile b/hw12_13_14_15_calendar/Makefile index 733d4d1..60ddfd8 100644 --- a/hw12_13_14_15_calendar/Makefile +++ b/hw12_13_14_15_calendar/Makefile @@ -1,8 +1,8 @@ build: - go build -o ./bin/calendar ./cmd/calendar + go build -o ./bin/calendar ./src test: - go test -race ./internal/... ./pkg/... + go test -race ./src/... install-lint-deps: (which golangci-lint > /dev/null) || curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.30.0 diff --git a/hw12_13_14_15_calendar/internal/storage/memory/storage.go b/hw12_13_14_15_calendar/internal/storage/memory/storage.go deleted file mode 100644 index bbc033d..0000000 --- a/hw12_13_14_15_calendar/internal/storage/memory/storage.go +++ /dev/null @@ -1,14 +0,0 @@ -package memorystorage - -import "sync" - -type Storage struct { - // TODO - mu sync.RWMutex -} - -func New() *Storage { - return &Storage{} -} - -// TODO diff --git a/hw12_13_14_15_calendar/internal/storage/memory/storage_test.go b/hw12_13_14_15_calendar/internal/storage/memory/storage_test.go deleted file mode 100644 index 7e303bc..0000000 --- a/hw12_13_14_15_calendar/internal/storage/memory/storage_test.go +++ /dev/null @@ -1,7 +0,0 @@ -package memorystorage - -import "testing" - -func TestStorage(t *testing.T) { - // TODO -} diff --git a/hw12_13_14_15_calendar/internal/storage/sql/storage.go b/hw12_13_14_15_calendar/internal/storage/sql/storage.go deleted file mode 100644 index 550e449..0000000 --- a/hw12_13_14_15_calendar/internal/storage/sql/storage.go +++ /dev/null @@ -1,21 +0,0 @@ -package sqlstorage - -import "context" - -type Storage struct { - // TODO -} - -func New() *Storage { - return &Storage{} -} - -func (s *Storage) Connect(ctx context.Context) error { - // TODO - return nil -} - -func (s *Storage) Close(ctx context.Context) error { - // TODO - return nil -} diff --git a/hw12_13_14_15_calendar/internal/app/app.go b/hw12_13_14_15_calendar/src/app/app.go similarity index 100% rename from hw12_13_14_15_calendar/internal/app/app.go rename to hw12_13_14_15_calendar/src/app/app.go diff --git a/hw12_13_14_15_calendar/internal/config/config.go b/hw12_13_14_15_calendar/src/config/config.go similarity index 67% rename from hw12_13_14_15_calendar/internal/config/config.go rename to hw12_13_14_15_calendar/src/config/config.go index d876311..9a94e24 100644 --- a/hw12_13_14_15_calendar/internal/config/config.go +++ b/hw12_13_14_15_calendar/src/config/config.go @@ -7,28 +7,32 @@ import ( ) type Config struct { - Logger struct{ - File string - Level string + Logger struct { + File string + Level string MuteStdout bool } Storage struct { In_memory bool - Sql_host string - Sql_port string + Sql_host string + Sql_port string Sql_dbase string - Sql_user string - Sql_pass string + Sql_user string + Sql_pass string } } // Confita может быти и хороша, но она не возвращает ошибки, если не может распарсить файл в структуру. Мне не нравится такая "молчаливость" func NewConfig(configFile string) (Config, error) { - f,err:= os.Open(configFile) - if err != nil {return Config{}, err} + f, err := os.Open(configFile) + if err != nil { + return Config{}, err + } defer f.Close() - s,err := ioutil.ReadAll(f) - if err != nil {return Config{}, err} + s, err := ioutil.ReadAll(f) + if err != nil { + return Config{}, err + } var config Config _, err = toml.Decode(string(s), &config) return config, err diff --git a/hw12_13_14_15_calendar/internal/config/config_test.go b/hw12_13_14_15_calendar/src/config/config_test.go similarity index 61% rename from hw12_13_14_15_calendar/internal/config/config_test.go rename to hw12_13_14_15_calendar/src/config/config_test.go index 9d9d14c..a9fb374 100644 --- a/hw12_13_14_15_calendar/internal/config/config_test.go +++ b/hw12_13_14_15_calendar/src/config/config_test.go @@ -16,7 +16,9 @@ var _ = func() bool { func TestNewConfig(t *testing.T) { badfile, err := ioutil.TempFile("", "conf.") - if err != nil { oslog.Fatal(err) } + if err != nil { + oslog.Fatal(err) + } defer os.Remove(badfile.Name()) badfile.WriteString(`aefSD sadfg @@ -25,7 +27,9 @@ V`) badfile.Sync() goodfile, err := ioutil.TempFile("", "conf.") - if err != nil { oslog.Fatal(err) } + if err != nil { + oslog.Fatal(err) + } defer os.Remove(goodfile.Name()) goodfile.WriteString(`[storage] in_memory = true @@ -33,22 +37,22 @@ sql_host = "localhost"`) goodfile.Sync() t.Run("No such file", func(t *testing.T) { - c,e := NewConfig("adfergdth") - require.Equal(t,Config{},c) - require.Error(t,e) + c, e := NewConfig("adfergdth") + require.Equal(t, Config{}, c) + require.Error(t, e) }) t.Run("Bad file", func(t *testing.T) { - c,e := NewConfig(badfile.Name()) - require.Equal(t,Config{},c) - require.Error(t,e) + c, e := NewConfig(badfile.Name()) + require.Equal(t, Config{}, c) + require.Error(t, e) }) t.Run("TOML reading", func(t *testing.T) { - c,e := NewConfig(goodfile.Name()) - require.Equal(t,true,c.Storage.In_memory) - require.Equal(t,"localhost",c.Storage.Sql_host) - require.NoError(t,e) + c, e := NewConfig(goodfile.Name()) + require.Equal(t, true, c.Storage.In_memory) + require.Equal(t, "localhost", c.Storage.Sql_host) + require.NoError(t, e) }) } diff --git a/hw12_13_14_15_calendar/internal/logger/logger.go b/hw12_13_14_15_calendar/src/logger/logger.go similarity index 85% rename from hw12_13_14_15_calendar/internal/logger/logger.go rename to hw12_13_14_15_calendar/src/logger/logger.go index 459c010..a4f2642 100644 --- a/hw12_13_14_15_calendar/internal/logger/logger.go +++ b/hw12_13_14_15_calendar/src/logger/logger.go @@ -3,7 +3,7 @@ package logger import ( "errors" amitralog "github.com/amitrai48/logger" - "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/internal/config" + "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/src/config" "log" "os" "strings" @@ -23,7 +23,7 @@ type Log struct { func New(conf config.Config) (Log, error) { - if conf.Logger.File=="" || !validLevel(conf.Logger.Level) { + if conf.Logger.File == "" || !validLevel(conf.Logger.Level) { return Log{}, errors.New("invalid logger config") } @@ -66,11 +66,11 @@ func (l *Log) Fatal(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 { + l := []string{"debug", "info", "warn", "error", "fatal"} + for _, v := range l { + if strings.ToLower(level) == v { return true } } return false -} \ No newline at end of file +} diff --git a/hw12_13_14_15_calendar/internal/logger/logger_test.go b/hw12_13_14_15_calendar/src/logger/logger_test.go similarity index 69% rename from hw12_13_14_15_calendar/internal/logger/logger_test.go rename to hw12_13_14_15_calendar/src/logger/logger_test.go index f7dd5fb..14288ec 100644 --- a/hw12_13_14_15_calendar/internal/logger/logger_test.go +++ b/hw12_13_14_15_calendar/src/logger/logger_test.go @@ -2,7 +2,7 @@ package logger import ( "github.com/stretchr/testify/require" - "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/internal/config" + "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/src/config" "io/ioutil" oslog "log" "os" @@ -12,7 +12,9 @@ import ( func TestLoggerLogic(t *testing.T) { tmpfile, err := ioutil.TempFile("", "log.") - if err != nil { oslog.Fatal(err) } + if err != nil { + oslog.Fatal(err) + } defer os.Remove(tmpfile.Name()) conf := config.Config{Logger: struct { @@ -21,16 +23,20 @@ func TestLoggerLogic(t *testing.T) { MuteStdout bool }{File: tmpfile.Name(), Level: "warn", MuteStdout: false}} log, err := New(conf) - if err != nil { oslog.Fatal(err) } + if err != nil { + oslog.Fatal(err) + } t.Run("Messages arround the level", func(t *testing.T) { log.Debug("debug message") log.Error("error message") - res,err := ioutil.ReadAll(tmpfile) - if err != nil { oslog.Fatal(err) } - require.Less(t,strings.Index(string(res),"debug message"),0) - require.Greater(t,strings.Index(string(res),"error message"),0) + res, err := ioutil.ReadAll(tmpfile) + if err != nil { + oslog.Fatal(err) + } + require.Less(t, strings.Index(string(res), "debug message"), 0) + require.Greater(t, strings.Index(string(res), "error message"), 0) }) } @@ -42,7 +48,7 @@ func TestLoggerNegative(t *testing.T) { MuteStdout bool }{File: "", Level: "debug", MuteStdout: true}} _, err := New(conf) - require.Error(t,err, "invalid logger config") + require.Error(t, err, "invalid logger config") }) t.Run("Bad level", func(t *testing.T) { @@ -52,6 +58,6 @@ func TestLoggerNegative(t *testing.T) { MuteStdout bool }{File: "asdafad", Level: "wegretryjt", MuteStdout: true}} _, err := New(conf) - require.Error(t,err,"invalid logger config") + require.Error(t, err, "invalid logger config") }) -} \ No newline at end of file +} diff --git a/hw12_13_14_15_calendar/cmd/calendar/main.go b/hw12_13_14_15_calendar/src/main.go similarity index 51% rename from hw12_13_14_15_calendar/cmd/calendar/main.go rename to hw12_13_14_15_calendar/src/main.go index 91a04dc..09ef456 100644 --- a/hw12_13_14_15_calendar/cmd/calendar/main.go +++ b/hw12_13_14_15_calendar/src/main.go @@ -2,14 +2,14 @@ package main import ( "flag" + "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/src/app" + "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/src/config" + "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/src/logger" + internalhttp "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/src/server/http" + store "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/src/storage" oslog "log" "os" "os/signal" - "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/internal/config" - "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/internal/app" - "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/internal/logger" - internalhttp "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/internal/server/http" - memorystorage "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/internal/storage/memory" ) var configFile string @@ -21,13 +21,21 @@ func init() { func main() { conf, err := config.NewConfig(configFile) - if err != nil { oslog.Fatal("не удалось открыть файл конфигурации:", err.Error())} + if err != nil { + oslog.Fatal("не удалось открыть файл конфигурации:", err.Error()) + } log, err := logger.New(conf) - if err != nil { oslog.Fatal("не удалось запустить логер:", err.Error())} + if err != nil { + oslog.Fatal("не удалось запустить логер:", err.Error()) + } - storage := memorystorage.New() - calendar := app.New(log, storage) + st := store.NewStore(conf) + if err != nil { + oslog.Fatal("не удалось инициализировать хранилище:", err.Error()) + } + + calendar := app.New(log, st) server := internalhttp.NewServer(calendar) diff --git a/hw12_13_14_15_calendar/internal/server/http/middleware.go b/hw12_13_14_15_calendar/src/server/http/middleware.go similarity index 100% rename from hw12_13_14_15_calendar/internal/server/http/middleware.go rename to hw12_13_14_15_calendar/src/server/http/middleware.go diff --git a/hw12_13_14_15_calendar/internal/server/http/server.go b/hw12_13_14_15_calendar/src/server/http/server.go similarity index 100% rename from hw12_13_14_15_calendar/internal/server/http/server.go rename to hw12_13_14_15_calendar/src/server/http/server.go diff --git a/hw12_13_14_15_calendar/internal/storage/event.go b/hw12_13_14_15_calendar/src/storage/event/event.go similarity index 64% rename from hw12_13_14_15_calendar/internal/storage/event.go rename to hw12_13_14_15_calendar/src/storage/event/event.go index 39b2d1a..eb9e0eb 100644 --- a/hw12_13_14_15_calendar/internal/storage/event.go +++ b/hw12_13_14_15_calendar/src/storage/event/event.go @@ -1,7 +1,7 @@ -package storage +package event type Event struct { ID string Title string - // TODO + Date string } diff --git a/hw12_13_14_15_calendar/src/storage/memory/memorystorage.go b/hw12_13_14_15_calendar/src/storage/memory/memorystorage.go new file mode 100644 index 0000000..9e3567a --- /dev/null +++ b/hw12_13_14_15_calendar/src/storage/memory/memorystorage.go @@ -0,0 +1,35 @@ +package memorystorage + +import ( + "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/src/storage/event" + "sync" +) + +type Storage struct { + events []event.Event + mu sync.RWMutex +} + +func New() *Storage { + return &Storage{} +} + +func (s Storage) Save(event event.Event) error { + return nil +} + +func (s Storage) Update(event event.Event) error { + return nil +} + +func (s Storage) Delete(event event.Event) error { + return nil +} + +func (s Storage) List() []event.Event { + return []event.Event{} +} + +func (s Storage) Get(id string) (event.Event, bool) { + return event.Event{}, false +} diff --git a/hw12_13_14_15_calendar/src/storage/sql/sqlstorage.go b/hw12_13_14_15_calendar/src/storage/sql/sqlstorage.go new file mode 100644 index 0000000..cbb1714 --- /dev/null +++ b/hw12_13_14_15_calendar/src/storage/sql/sqlstorage.go @@ -0,0 +1,51 @@ +package sqlstorage + +import ( + "context" + "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/src/storage/event" + "sync" +) + +type Storage struct { + Events []event.Event + Mu sync.RWMutex +} + +func New() *Storage { + return &Storage{} +} + +func (s *Storage) Connect(ctx context.Context) error { + // TODO + return nil +} + +func (s *Storage) Close(ctx context.Context) error { + // TODO + return nil +} + +func (s Storage) Save(e event.Event) error { + if _, ok := s.Get(e.ID); !ok { + s.Mu.Lock() + s.Events = append(s.Events, e) + s.Mu.Unlock() + } + return nil +} + +func (s Storage) Update(event event.Event) error { + return nil +} + +func (s Storage) Delete(event event.Event) error { + return nil +} + +func (s Storage) List() []event.Event { + return []event.Event{} +} + +func (s Storage) Get(id string) (event.Event, bool) { + return event.Event{}, false +} diff --git a/hw12_13_14_15_calendar/src/storage/store.go b/hw12_13_14_15_calendar/src/storage/store.go new file mode 100644 index 0000000..44e75bc --- /dev/null +++ b/hw12_13_14_15_calendar/src/storage/store.go @@ -0,0 +1,24 @@ +package store + +import ( + "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/src/config" + "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/src/storage/event" + memorystorage "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/src/storage/memory" + sqlstorage "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/src/storage/sql" +) + +type StoreInterface interface { + Save(event event.Event) error + Update(event event.Event) error + Delete(event event.Event) error + List() []event.Event + Get(id string) (event.Event, bool) +} + +func NewStore(config config.Config) StoreInterface { + if config.Storage.In_memory { + st := memorystorage.New() + return st + } + return sqlstorage.New() +} From 195c5ec84a623766af33b604ac0f1afb43f10cf4 Mon Sep 17 00:00:00 2001 From: Andrey Ivanov Date: Tue, 1 Sep 2020 15:52:51 +0300 Subject: [PATCH 03/11] =?UTF-8?q?HW12=20=D0=B8=D0=B7=D0=BC=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=BB=20=D1=81=D1=82=D1=80=D1=83=D0=BA=D1=82=D1=83=D1=80?= =?UTF-8?q?=D1=83=20=D0=BF=D1=80=D0=BE=D0=B5=D0=BA=D1=82=D0=B0=20=D0=BD?= =?UTF-8?q?=D0=B0=20=D0=B1=D0=BE=D0=BB=D0=B5=D0=B5=20=D0=BF=D1=80=D0=B8?= =?UTF-8?q?=D0=B2=D1=8B=D1=87=D0=BD=D1=83=D1=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hw12_13_14_15_calendar/configs/config.toml | 20 +++++++------- hw12_13_14_15_calendar/src/config/config.go | 17 ++++++------ .../src/config/config_test.go | 8 +++--- hw12_13_14_15_calendar/src/logger/logger.go | 26 +++++++++---------- .../src/logger/logger_test.go | 4 +-- hw12_13_14_15_calendar/src/main.go | 11 ++++---- .../src/server/http/middleware.go | 14 ++++------ .../src/storage/memory/memorystorage.go | 15 +++++------ .../src/storage/sql/sqlstorage.go | 13 +++++----- hw12_13_14_15_calendar/src/storage/store.go | 6 ++--- 10 files changed, 66 insertions(+), 68 deletions(-) diff --git a/hw12_13_14_15_calendar/configs/config.toml b/hw12_13_14_15_calendar/configs/config.toml index dc28273..7abae37 100644 --- a/hw12_13_14_15_calendar/configs/config.toml +++ b/hw12_13_14_15_calendar/configs/config.toml @@ -1,11 +1,11 @@ -[logger] -file = "./calendar.log" -level = "INFO" +[Logger] +File = "./calendar.log" +Level = "INFO" -[storage] -in_memory = false -sql_host = "localhost" -sql_port = "5432" -sql_dbase = "calendar" -sql_user = "calendar" -sql_pass = "12345678" \ No newline at end of file +[Storage] +inMemory = false +SQLHost = "localhost" +SQLPort = "5432" +SQLDbase = "calendar" +SQLUser = "calendar" +SQLPass = "12345678" \ No newline at end of file diff --git a/hw12_13_14_15_calendar/src/config/config.go b/hw12_13_14_15_calendar/src/config/config.go index 9a94e24..3478a5d 100644 --- a/hw12_13_14_15_calendar/src/config/config.go +++ b/hw12_13_14_15_calendar/src/config/config.go @@ -1,9 +1,10 @@ package config import ( - "github.com/BurntSushi/toml" "io/ioutil" "os" + + "github.com/BurntSushi/toml" ) type Config struct { @@ -13,16 +14,16 @@ type Config struct { MuteStdout bool } Storage struct { - In_memory bool - Sql_host string - Sql_port string - Sql_dbase string - Sql_user string - Sql_pass string + InMemory bool + SQLHost string + SQLPort string + SQLDbase string + SQLUser string + SQLPass string } } -// Confita может быти и хороша, но она не возвращает ошибки, если не может распарсить файл в структуру. Мне не нравится такая "молчаливость" +// Confita может быти и хороша, но она не возвращает ошибки, если не может распарсить файл в структуру. Мне не нравится такая "молчаливость". func NewConfig(configFile string) (Config, error) { f, err := os.Open(configFile) if err != nil { diff --git a/hw12_13_14_15_calendar/src/config/config_test.go b/hw12_13_14_15_calendar/src/config/config_test.go index a9fb374..3fdd126 100644 --- a/hw12_13_14_15_calendar/src/config/config_test.go +++ b/hw12_13_14_15_calendar/src/config/config_test.go @@ -32,8 +32,8 @@ V`) } defer os.Remove(goodfile.Name()) goodfile.WriteString(`[storage] -in_memory = true -sql_host = "localhost"`) +inMemory = true +SQLHost = "localhost"`) goodfile.Sync() t.Run("No such file", func(t *testing.T) { @@ -50,8 +50,8 @@ sql_host = "localhost"`) t.Run("TOML reading", func(t *testing.T) { c, e := NewConfig(goodfile.Name()) - require.Equal(t, true, c.Storage.In_memory) - require.Equal(t, "localhost", c.Storage.Sql_host) + require.Equal(t, true, c.Storage.InMemory) + require.Equal(t, "localhost", c.Storage.SQLHost) require.NoError(t, e) }) diff --git a/hw12_13_14_15_calendar/src/logger/logger.go b/hw12_13_14_15_calendar/src/logger/logger.go index a4f2642..616cc11 100644 --- a/hw12_13_14_15_calendar/src/logger/logger.go +++ b/hw12_13_14_15_calendar/src/logger/logger.go @@ -2,19 +2,20 @@ package logger import ( "errors" - amitralog "github.com/amitrai48/logger" - "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/src/config" "log" "os" "strings" + + amitralog "github.com/amitrai48/logger" + "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/src/config" ) type Logger interface { - Debug(msg string) - Info(msg string) - Warn(msg string) - Error(msg string) - Fatal(msg string) + Debugf(format string, args ...interface{}) + Infof(format string, args ...interface{}) + Warnf(format string, args ...interface{}) + Errorf(format string, args ...interface{}) + Fatalf(format string, args ...interface{}) } type Log struct { @@ -22,7 +23,6 @@ type Log struct { } func New(conf config.Config) (Log, error) { - if conf.Logger.File == "" || !validLevel(conf.Logger.Level) { return Log{}, errors.New("invalid logger config") } @@ -44,23 +44,23 @@ func New(conf config.Config) (Log, error) { return Log{Logger: l}, nil } -func (l Log) Debug(format string, args ...interface{}) { +func (l Log) Debugf(format string, args ...interface{}) { l.Logger.Debugf(format, args) } -func (l *Log) Info(format string, args ...interface{}) { +func (l *Log) Infof(format string, args ...interface{}) { l.Logger.Infof(format, args) } -func (l *Log) Warn(format string, args ...interface{}) { +func (l *Log) Warnf(format string, args ...interface{}) { l.Logger.Warnf(format, args) } -func (l *Log) Error(format string, args ...interface{}) { +func (l *Log) Errorf(format string, args ...interface{}) { l.Logger.Errorf(format, args) } -func (l *Log) Fatal(format string, args ...interface{}) { +func (l *Log) Fatalf(format string, args ...interface{}) { l.Logger.Fatalf(format, args) os.Exit(2) } diff --git a/hw12_13_14_15_calendar/src/logger/logger_test.go b/hw12_13_14_15_calendar/src/logger/logger_test.go index 14288ec..b2adf61 100644 --- a/hw12_13_14_15_calendar/src/logger/logger_test.go +++ b/hw12_13_14_15_calendar/src/logger/logger_test.go @@ -28,8 +28,8 @@ func TestLoggerLogic(t *testing.T) { } t.Run("Messages arround the level", func(t *testing.T) { - log.Debug("debug message") - log.Error("error message") + log.Debugf("debug message") + log.Errorf("error message") res, err := ioutil.ReadAll(tmpfile) if err != nil { diff --git a/hw12_13_14_15_calendar/src/main.go b/hw12_13_14_15_calendar/src/main.go index 09ef456..f1b4268 100644 --- a/hw12_13_14_15_calendar/src/main.go +++ b/hw12_13_14_15_calendar/src/main.go @@ -2,14 +2,15 @@ package main import ( "flag" + oslog "log" + "os" + "os/signal" + "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/src/app" "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/src/config" "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/src/logger" internalhttp "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/src/server/http" store "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/src/storage" - oslog "log" - "os" - "os/signal" ) var configFile string @@ -47,12 +48,12 @@ func main() { signal.Stop(signals) if err := server.Stop(); err != nil { - log.Error("failed to stop http server: " + err.Error()) + log.Errorf("failed to stop http server: " + err.Error()) } }() if err := server.Start(); err != nil { - log.Error("failed to start http server: " + err.Error()) + log.Errorf("failed to start http server: " + err.Error()) os.Exit(1) } } diff --git a/hw12_13_14_15_calendar/src/server/http/middleware.go b/hw12_13_14_15_calendar/src/server/http/middleware.go index 803cade..48654a3 100644 --- a/hw12_13_14_15_calendar/src/server/http/middleware.go +++ b/hw12_13_14_15_calendar/src/server/http/middleware.go @@ -1,11 +1,7 @@ package internalhttp -import ( - "net/http" -) - -func loggingMiddleware(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - // TODO - }) -} +//func loggingMiddleware(next http.Handler) http.Handler { +// return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { +// TODO +// }) +//} diff --git a/hw12_13_14_15_calendar/src/storage/memory/memorystorage.go b/hw12_13_14_15_calendar/src/storage/memory/memorystorage.go index 9e3567a..8316fae 100644 --- a/hw12_13_14_15_calendar/src/storage/memory/memorystorage.go +++ b/hw12_13_14_15_calendar/src/storage/memory/memorystorage.go @@ -2,34 +2,33 @@ package memorystorage import ( "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/src/storage/event" - "sync" ) type Storage struct { - events []event.Event - mu sync.RWMutex + //events []event.Event + //mu sync.RWMutex } func New() *Storage { return &Storage{} } -func (s Storage) Save(event event.Event) error { +func (s *Storage) Save(event event.Event) error { return nil } -func (s Storage) Update(event event.Event) error { +func (s *Storage) Update(event event.Event) error { return nil } -func (s Storage) Delete(event event.Event) error { +func (s *Storage) Delete(event event.Event) error { return nil } -func (s Storage) List() []event.Event { +func (s *Storage) List() []event.Event { return []event.Event{} } -func (s Storage) Get(id string) (event.Event, bool) { +func (s *Storage) Get(id string) (event.Event, bool) { return event.Event{}, false } diff --git a/hw12_13_14_15_calendar/src/storage/sql/sqlstorage.go b/hw12_13_14_15_calendar/src/storage/sql/sqlstorage.go index cbb1714..3c544d5 100644 --- a/hw12_13_14_15_calendar/src/storage/sql/sqlstorage.go +++ b/hw12_13_14_15_calendar/src/storage/sql/sqlstorage.go @@ -2,8 +2,9 @@ package sqlstorage import ( "context" - "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/src/storage/event" "sync" + + "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/src/storage/event" ) type Storage struct { @@ -25,7 +26,7 @@ func (s *Storage) Close(ctx context.Context) error { return nil } -func (s Storage) Save(e event.Event) error { +func (s *Storage) Save(e event.Event) error { if _, ok := s.Get(e.ID); !ok { s.Mu.Lock() s.Events = append(s.Events, e) @@ -34,18 +35,18 @@ func (s Storage) Save(e event.Event) error { return nil } -func (s Storage) Update(event event.Event) error { +func (s *Storage) Update(event event.Event) error { return nil } -func (s Storage) Delete(event event.Event) error { +func (s *Storage) Delete(event event.Event) error { return nil } -func (s Storage) List() []event.Event { +func (s *Storage) List() []event.Event { return []event.Event{} } -func (s Storage) Get(id string) (event.Event, bool) { +func (s *Storage) Get(id string) (event.Event, bool) { return event.Event{}, false } diff --git a/hw12_13_14_15_calendar/src/storage/store.go b/hw12_13_14_15_calendar/src/storage/store.go index 44e75bc..05fb7d4 100644 --- a/hw12_13_14_15_calendar/src/storage/store.go +++ b/hw12_13_14_15_calendar/src/storage/store.go @@ -7,7 +7,7 @@ import ( sqlstorage "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/src/storage/sql" ) -type StoreInterface interface { +type Interface interface { Save(event event.Event) error Update(event event.Event) error Delete(event event.Event) error @@ -15,8 +15,8 @@ type StoreInterface interface { Get(id string) (event.Event, bool) } -func NewStore(config config.Config) StoreInterface { - if config.Storage.In_memory { +func NewStore(config config.Config) Interface { + if config.Storage.InMemory { st := memorystorage.New() return st } From 24985e49f87160e9f0bee1f20aec9678cc6bdd5d Mon Sep 17 00:00:00 2001 From: Andrey Ivanov Date: Fri, 4 Sep 2020 11:28:50 +0300 Subject: [PATCH 04/11] =?UTF-8?q?HW12=20=D1=81=D0=BE=D0=B7=D0=B4=D0=B0?= =?UTF-8?q?=D0=BB=20server=20=D0=B8=20app?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hw12_13_14_15_calendar/configs/config.toml | 4 +++ hw12_13_14_15_calendar/src/app/app.go | 36 ++++++++++++------- hw12_13_14_15_calendar/src/config/config.go | 4 +++ hw12_13_14_15_calendar/src/logger/logger.go | 20 +++++------ hw12_13_14_15_calendar/src/main.go | 15 ++++---- .../src/server/http/server.go | 27 +++++++------- .../src/storage/memory/memorystorage.go | 13 +++++-- .../src/storage/sql/sqlstorage.go | 25 +++++++------ hw12_13_14_15_calendar/src/storage/store.go | 27 ++++++++++---- 9 files changed, 108 insertions(+), 63 deletions(-) diff --git a/hw12_13_14_15_calendar/configs/config.toml b/hw12_13_14_15_calendar/configs/config.toml index 7abae37..af65fa9 100644 --- a/hw12_13_14_15_calendar/configs/config.toml +++ b/hw12_13_14_15_calendar/configs/config.toml @@ -1,3 +1,7 @@ +[Server] +Address = "localhost" +Port = "8080" + [Logger] File = "./calendar.log" Level = "INFO" diff --git a/hw12_13_14_15_calendar/src/app/app.go b/hw12_13_14_15_calendar/src/app/app.go index e34970b..50d4809 100644 --- a/hw12_13_14_15_calendar/src/app/app.go +++ b/hw12_13_14_15_calendar/src/app/app.go @@ -2,27 +2,37 @@ package app import ( "context" + "net/http" + + "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/src/logger" + store "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/src/storage" + "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/src/storage/event" ) +type Interface interface { + CreateEvent(ctx context.Context, id string, title string) (err error) + Handler(w http.ResponseWriter, r *http.Request) +} + type App struct { - // TODO + storage store.StorageInterface + logger logger.Interface } -type Logger interface { - // TODO -} - -type Storage interface { - // TODO -} - -func New(logger Logger, storage Storage) *App { - return &App{} +func New(logger logger.Interface, storage store.StorageInterface) *App { + return &App{logger: logger, storage: storage} } func (a *App) CreateEvent(ctx context.Context, id string, title string) (err error) { - //err = a.storage.CreateEvent(storage.Event{ID: id, Title: title}) + err = a.storage.Create(event.Event{ID: id, Title: title}) + if err != nil { + a.logger.Errorf("can not create event") + } + a.logger.Infof("event created") return err } -// TODO +func (a *App) Handler(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(200) + _, _ = w.Write([]byte("Hello! I'm calendar app!")) +} diff --git a/hw12_13_14_15_calendar/src/config/config.go b/hw12_13_14_15_calendar/src/config/config.go index 3478a5d..fbf34fd 100644 --- a/hw12_13_14_15_calendar/src/config/config.go +++ b/hw12_13_14_15_calendar/src/config/config.go @@ -8,6 +8,10 @@ import ( ) type Config struct { + Server struct { + Address string + Port string + } Logger struct { File string Level string diff --git a/hw12_13_14_15_calendar/src/logger/logger.go b/hw12_13_14_15_calendar/src/logger/logger.go index 616cc11..1b37f89 100644 --- a/hw12_13_14_15_calendar/src/logger/logger.go +++ b/hw12_13_14_15_calendar/src/logger/logger.go @@ -10,7 +10,7 @@ import ( "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/src/config" ) -type Logger interface { +type Interface interface { Debugf(format string, args ...interface{}) Infof(format string, args ...interface{}) Warnf(format string, args ...interface{}) @@ -18,13 +18,13 @@ type Logger interface { Fatalf(format string, args ...interface{}) } -type Log struct { +type Logger struct { Logger amitralog.Logger } -func New(conf config.Config) (Log, error) { +func New(conf config.Config) (Interface, error) { if conf.Logger.File == "" || !validLevel(conf.Logger.Level) { - return Log{}, errors.New("invalid logger config") + return nil, errors.New("invalid logger config") } c := amitralog.Configuration{ @@ -41,26 +41,26 @@ func New(conf config.Config) (Log, error) { log.Fatalf("Could not instantiate log %s", err.Error()) } l := amitralog.WithFields(amitralog.Fields{"hw": "12"}) - return Log{Logger: l}, nil + return l, nil } -func (l Log) Debugf(format string, args ...interface{}) { +func (l *Logger) Debugf(format string, args ...interface{}) { l.Logger.Debugf(format, args) } -func (l *Log) Infof(format string, args ...interface{}) { +func (l *Logger) Infof(format string, args ...interface{}) { l.Logger.Infof(format, args) } -func (l *Log) Warnf(format string, args ...interface{}) { +func (l *Logger) Warnf(format string, args ...interface{}) { l.Logger.Warnf(format, args) } -func (l *Log) Errorf(format string, args ...interface{}) { +func (l *Logger) Errorf(format string, args ...interface{}) { l.Logger.Errorf(format, args) } -func (l *Log) Fatalf(format string, args ...interface{}) { +func (l *Logger) Fatalf(format string, args ...interface{}) { l.Logger.Fatalf(format, args) os.Exit(2) } diff --git a/hw12_13_14_15_calendar/src/main.go b/hw12_13_14_15_calendar/src/main.go index f1b4268..20cdfdb 100644 --- a/hw12_13_14_15_calendar/src/main.go +++ b/hw12_13_14_15_calendar/src/main.go @@ -25,20 +25,23 @@ func main() { if err != nil { oslog.Fatal("не удалось открыть файл конфигурации:", err.Error()) } - log, err := logger.New(conf) if err != nil { oslog.Fatal("не удалось запустить логер:", err.Error()) } - - st := store.NewStore(conf) - if err != nil { - oslog.Fatal("не удалось инициализировать хранилище:", err.Error()) + storeConf := store.Config{ + InMemory: conf.Storage.InMemory, + SQLHost: conf.Storage.SQLHost, + SQLPort: conf.Storage.SQLPort, + SQLDbase: conf.Storage.SQLDbase, + SQLUser: conf.Storage.SQLUser, + SQLPass: conf.Storage.SQLPass, } + st := store.NewStore(storeConf) calendar := app.New(log, st) - server := internalhttp.NewServer(calendar) + server := internalhttp.NewServer(calendar, conf.Server.Address, conf.Server.Port) go func() { signals := make(chan os.Signal, 1) diff --git a/hw12_13_14_15_calendar/src/server/http/server.go b/hw12_13_14_15_calendar/src/server/http/server.go index b94faf3..ef74e19 100644 --- a/hw12_13_14_15_calendar/src/server/http/server.go +++ b/hw12_13_14_15_calendar/src/server/http/server.go @@ -1,26 +1,25 @@ package internalhttp +import ( + "net" + "net/http" + + "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/src/app" +) + type Server struct { - // TODO + server *http.Server + app app.Interface } -type Application interface { - // TODO -} - -func NewServer(app Application) *Server { - return &Server{} +func NewServer(app app.Interface, address string, port string) *Server { + return &Server{server: &http.Server{Addr: net.JoinHostPort(address, port), Handler: http.HandlerFunc(app.Handler)}, app: app} } func (s *Server) Start() error { - // TODO - return nil + return s.server.ListenAndServe() } func (s *Server) Stop() error { - //ctx, cancel := context.WithTimeout(context.Background(), shutdownTimeout) - // TODO - return nil + return s.server.Close() } - -// TODO diff --git a/hw12_13_14_15_calendar/src/storage/memory/memorystorage.go b/hw12_13_14_15_calendar/src/storage/memory/memorystorage.go index 8316fae..7578070 100644 --- a/hw12_13_14_15_calendar/src/storage/memory/memorystorage.go +++ b/hw12_13_14_15_calendar/src/storage/memory/memorystorage.go @@ -1,19 +1,26 @@ package memorystorage import ( + "sync" + "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/src/storage/event" ) type Storage struct { - //events []event.Event - //mu sync.RWMutex + Events []event.Event + Mu sync.RWMutex } func New() *Storage { return &Storage{} } -func (s *Storage) Save(event event.Event) error { +func (s *Storage) Create(event event.Event) error { + if _, ok := s.Get(event.ID); !ok { + s.Mu.Lock() + s.Events = append(s.Events, event) + s.Mu.Unlock() + } return nil } diff --git a/hw12_13_14_15_calendar/src/storage/sql/sqlstorage.go b/hw12_13_14_15_calendar/src/storage/sql/sqlstorage.go index 3c544d5..3c509cc 100644 --- a/hw12_13_14_15_calendar/src/storage/sql/sqlstorage.go +++ b/hw12_13_14_15_calendar/src/storage/sql/sqlstorage.go @@ -2,17 +2,24 @@ package sqlstorage import ( "context" - "sync" "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/src/storage/event" ) -type Storage struct { - Events []event.Event - Mu sync.RWMutex +type Config struct { + Host string + Port string + Dbase string + User string + Pass string } -func New() *Storage { +type Storage struct { + //Events []event.Event + //Mu sync.RWMutex +} + +func New(conf Config) *Storage { return &Storage{} } @@ -26,12 +33,8 @@ func (s *Storage) Close(ctx context.Context) error { return nil } -func (s *Storage) Save(e event.Event) error { - if _, ok := s.Get(e.ID); !ok { - s.Mu.Lock() - s.Events = append(s.Events, e) - s.Mu.Unlock() - } +func (s *Storage) Create(e event.Event) error { + // TODO return nil } diff --git a/hw12_13_14_15_calendar/src/storage/store.go b/hw12_13_14_15_calendar/src/storage/store.go index 05fb7d4..5629f8e 100644 --- a/hw12_13_14_15_calendar/src/storage/store.go +++ b/hw12_13_14_15_calendar/src/storage/store.go @@ -1,24 +1,39 @@ package store import ( - "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/src/config" "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/src/storage/event" memorystorage "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/src/storage/memory" sqlstorage "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/src/storage/sql" ) -type Interface interface { - Save(event event.Event) error +type Config struct { + InMemory bool + SQLHost string + SQLPort string + SQLDbase string + SQLUser string + SQLPass string +} + +type StorageInterface interface { + Create(event event.Event) error Update(event event.Event) error Delete(event event.Event) error List() []event.Event Get(id string) (event.Event, bool) } -func NewStore(config config.Config) Interface { - if config.Storage.InMemory { +func NewStore(conf Config) StorageInterface { + if conf.InMemory { st := memorystorage.New() return st } - return sqlstorage.New() + sqlConf := sqlstorage.Config{ + Host: conf.SQLHost, + Port: conf.SQLPort, + Dbase: conf.SQLDbase, + User: conf.SQLUser, + Pass: conf.SQLPass, + } + return sqlstorage.New(sqlConf) } From 96a69e9833cb7dd07ee7e8f80d6e2431932c4dc7 Mon Sep 17 00:00:00 2001 From: Andrey Ivanov Date: Fri, 4 Sep 2020 11:40:33 +0300 Subject: [PATCH 05/11] =?UTF-8?q?HW12=20=D0=BF=D0=BE=D0=BF=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=D0=B8=D0=BB=20Makefile?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hw12_13_14_15_calendar/Makefile | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/hw12_13_14_15_calendar/Makefile b/hw12_13_14_15_calendar/Makefile index 60ddfd8..3751e6c 100644 --- a/hw12_13_14_15_calendar/Makefile +++ b/hw12_13_14_15_calendar/Makefile @@ -1,13 +1,16 @@ build: go build -o ./bin/calendar ./src +run: + go run ./src/calendar/main.go -config ./configs/config.toml + test: go test -race ./src/... -install-lint-deps: - (which golangci-lint > /dev/null) || curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.30.0 - lint: install-lint-deps golangci-lint run ./... -.PHONY: build test lint +install-lint-deps: + go install github.com/golangci/golangci-lint/cmd/golangci-lint + +.PHONY: build run test lint \ No newline at end of file From 1fe653c9bd5de069e33821138e278474af838c6b Mon Sep 17 00:00:00 2001 From: Andrey Ivanov Date: Thu, 24 Sep 2020 16:10:24 +0300 Subject: [PATCH 06/11] =?UTF-8?q?HW12=20=D1=80=D0=B5=D0=B0=D0=BB=D0=B8?= =?UTF-8?q?=D0=B7=D0=BE=D0=B2=D0=B0=D0=BB=20=D0=B2=D1=80=D0=BE=D0=B4=D0=B5?= =?UTF-8?q?=20=D0=B1=D1=8B=20=D0=B2=D1=81=D0=B5,=20=D1=87=D1=82=D0=BE=20?= =?UTF-8?q?=D0=BD=D1=83=D0=B6=D0=BD=D0=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hw12_13_14_15_calendar/Makefile | 8 +- .../{src => cmd/calendar}/main.go | 11 ++- hw12_13_14_15_calendar/go.mod | 5 +- hw12_13_14_15_calendar/internal/app/app.go | 46 +++++++++ .../{src => internal}/config/config.go | 0 .../{src => internal}/config/config_test.go | 0 .../{src => internal}/logger/logger.go | 2 +- .../{src => internal}/logger/logger_test.go | 2 +- .../internal/server/http/middleware.go | 9 ++ .../internal/server/http/server.go | 37 +++++++ .../{src => internal}/storage/event/event.go | 1 - .../internal/storage/memory/memorystorage.go | 50 ++++++++++ .../internal/storage/sql/sqlstorage.go | 99 +++++++++++++++++++ .../{src => internal}/storage/store.go | 16 +-- .../migrations/20200924000000_init.sql | 14 +++ hw12_13_14_15_calendar/src/app/app.go | 38 ------- .../src/server/http/middleware.go | 7 -- .../src/server/http/server.go | 25 ----- .../src/storage/memory/memorystorage.go | 41 -------- .../src/storage/sql/sqlstorage.go | 55 ----------- 20 files changed, 278 insertions(+), 188 deletions(-) rename hw12_13_14_15_calendar/{src => cmd/calendar}/main.go (78%) create mode 100644 hw12_13_14_15_calendar/internal/app/app.go rename hw12_13_14_15_calendar/{src => internal}/config/config.go (100%) rename hw12_13_14_15_calendar/{src => internal}/config/config_test.go (100%) rename hw12_13_14_15_calendar/{src => internal}/logger/logger.go (96%) rename hw12_13_14_15_calendar/{src => internal}/logger/logger_test.go (95%) create mode 100644 hw12_13_14_15_calendar/internal/server/http/middleware.go create mode 100644 hw12_13_14_15_calendar/internal/server/http/server.go rename hw12_13_14_15_calendar/{src => internal}/storage/event/event.go (82%) create mode 100644 hw12_13_14_15_calendar/internal/storage/memory/memorystorage.go create mode 100644 hw12_13_14_15_calendar/internal/storage/sql/sqlstorage.go rename hw12_13_14_15_calendar/{src => internal}/storage/store.go (65%) create mode 100644 hw12_13_14_15_calendar/migrations/20200924000000_init.sql delete mode 100644 hw12_13_14_15_calendar/src/app/app.go delete mode 100644 hw12_13_14_15_calendar/src/server/http/middleware.go delete mode 100644 hw12_13_14_15_calendar/src/server/http/server.go delete mode 100644 hw12_13_14_15_calendar/src/storage/memory/memorystorage.go delete mode 100644 hw12_13_14_15_calendar/src/storage/sql/sqlstorage.go diff --git a/hw12_13_14_15_calendar/Makefile b/hw12_13_14_15_calendar/Makefile index 3751e6c..3467137 100644 --- a/hw12_13_14_15_calendar/Makefile +++ b/hw12_13_14_15_calendar/Makefile @@ -2,15 +2,15 @@ build: go build -o ./bin/calendar ./src run: - go run ./src/calendar/main.go -config ./configs/config.toml + go run ./cmd/calendar/main.go -config ./configs/config.toml test: - go test -race ./src/... + go test -race ./internal/... lint: install-lint-deps - golangci-lint run ./... + golangci-lint run .cmd/... ./internal/... install-lint-deps: - go install github.com/golangci/golangci-lint/cmd/golangci-lint + (which golangci-lint > /dev/null) || curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(shell go env GOPATH)/bin v1.30.0 .PHONY: build run test lint \ No newline at end of file diff --git a/hw12_13_14_15_calendar/src/main.go b/hw12_13_14_15_calendar/cmd/calendar/main.go similarity index 78% rename from hw12_13_14_15_calendar/src/main.go rename to hw12_13_14_15_calendar/cmd/calendar/main.go index 20cdfdb..ecef853 100644 --- a/hw12_13_14_15_calendar/src/main.go +++ b/hw12_13_14_15_calendar/cmd/calendar/main.go @@ -6,11 +6,12 @@ import ( "os" "os/signal" - "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/src/app" - "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/src/config" - "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/src/logger" - internalhttp "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/src/server/http" - store "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/src/storage" + _ "github.com/go-sql-driver/mysql" + "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/internal/app" + "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/internal/config" + "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/internal/logger" + internalhttp "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/internal/server/http" + store "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/internal/storage" ) var configFile string diff --git a/hw12_13_14_15_calendar/go.mod b/hw12_13_14_15_calendar/go.mod index db45e6a..60e7d9b 100644 --- a/hw12_13_14_15_calendar/go.mod +++ b/hw12_13_14_15_calendar/go.mod @@ -5,8 +5,9 @@ go 1.14 require ( github.com/BurntSushi/toml v0.3.1 github.com/amitrai48/logger v0.0.0-20190214092904-448001c055ec + github.com/go-sql-driver/mysql v1.5.0 + github.com/mattn/go-shellwords v1.0.10 // indirect github.com/stretchr/testify v1.4.0 - go.uber.org/zap v1.15.0 - golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5 + go.uber.org/zap v1.15.0 // indirect gopkg.in/yaml.v2 v2.3.0 // indirect ) diff --git a/hw12_13_14_15_calendar/internal/app/app.go b/hw12_13_14_15_calendar/internal/app/app.go new file mode 100644 index 0000000..dd06169 --- /dev/null +++ b/hw12_13_14_15_calendar/internal/app/app.go @@ -0,0 +1,46 @@ +package app + +import ( + "context" + "net/http" + + "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" + "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/internal/storage/event" +) + +type Interface interface { + CreateEvent(ctx context.Context, title string) (err error) + Handler(w http.ResponseWriter, r *http.Request) + LoggingMiddleware(next http.HandlerFunc) http.HandlerFunc +} + +type App struct { + Storage store.StorageInterface + Logger logger.Interface +} + +func New(logger logger.Interface, storage store.StorageInterface) *App { + return &App{Logger: logger, Storage: storage} +} + +func (a *App) CreateEvent(ctx context.Context, title string) (err error) { + _, err = a.Storage.Create(event.Event{Title: title}) + if err != nil { + a.Logger.Errorf("can not create event") + } + a.Logger.Infof("event created") + return err +} + +func (a *App) Handler(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(200) + _, _ = w.Write([]byte("Hello! I'm calendar app!")) +} + +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) + next.ServeHTTP(w, r) + }) +} diff --git a/hw12_13_14_15_calendar/src/config/config.go b/hw12_13_14_15_calendar/internal/config/config.go similarity index 100% rename from hw12_13_14_15_calendar/src/config/config.go rename to hw12_13_14_15_calendar/internal/config/config.go diff --git a/hw12_13_14_15_calendar/src/config/config_test.go b/hw12_13_14_15_calendar/internal/config/config_test.go similarity index 100% rename from hw12_13_14_15_calendar/src/config/config_test.go rename to hw12_13_14_15_calendar/internal/config/config_test.go diff --git a/hw12_13_14_15_calendar/src/logger/logger.go b/hw12_13_14_15_calendar/internal/logger/logger.go similarity index 96% rename from hw12_13_14_15_calendar/src/logger/logger.go rename to hw12_13_14_15_calendar/internal/logger/logger.go index 1b37f89..4eac1a6 100644 --- a/hw12_13_14_15_calendar/src/logger/logger.go +++ b/hw12_13_14_15_calendar/internal/logger/logger.go @@ -7,7 +7,7 @@ import ( "strings" amitralog "github.com/amitrai48/logger" - "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/src/config" + "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/internal/config" ) type Interface interface { diff --git a/hw12_13_14_15_calendar/src/logger/logger_test.go b/hw12_13_14_15_calendar/internal/logger/logger_test.go similarity index 95% rename from hw12_13_14_15_calendar/src/logger/logger_test.go rename to hw12_13_14_15_calendar/internal/logger/logger_test.go index b2adf61..3efbd7d 100644 --- a/hw12_13_14_15_calendar/src/logger/logger_test.go +++ b/hw12_13_14_15_calendar/internal/logger/logger_test.go @@ -2,7 +2,7 @@ package logger import ( "github.com/stretchr/testify/require" - "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/src/config" + "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/internal/config" "io/ioutil" oslog "log" "os" diff --git a/hw12_13_14_15_calendar/internal/server/http/middleware.go b/hw12_13_14_15_calendar/internal/server/http/middleware.go new file mode 100644 index 0000000..5b5cec1 --- /dev/null +++ b/hw12_13_14_15_calendar/internal/server/http/middleware.go @@ -0,0 +1,9 @@ +package http + +/* +func loggingMiddleware(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + + }) +} +*/ diff --git a/hw12_13_14_15_calendar/internal/server/http/server.go b/hw12_13_14_15_calendar/internal/server/http/server.go new file mode 100644 index 0000000..8c25f46 --- /dev/null +++ b/hw12_13_14_15_calendar/internal/server/http/server.go @@ -0,0 +1,37 @@ +package http + +import ( + "context" + "net" + "net/http" + + "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/internal/app" +) + +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} +} + +func (s *Server) Start() error { + if err := s.server.ListenAndServe(); err != nil { + return err + } + s.app.Logger.Infof("Server starting") + return nil +} + +func (s *Server) Stop() error { + if err := s.server.Close(); err != nil { + return err + } + s.app.Logger.Infof("Server starting") + return nil +} diff --git a/hw12_13_14_15_calendar/src/storage/event/event.go b/hw12_13_14_15_calendar/internal/storage/event/event.go similarity index 82% rename from hw12_13_14_15_calendar/src/storage/event/event.go rename to hw12_13_14_15_calendar/internal/storage/event/event.go index eb9e0eb..f1897f0 100644 --- a/hw12_13_14_15_calendar/src/storage/event/event.go +++ b/hw12_13_14_15_calendar/internal/storage/event/event.go @@ -1,7 +1,6 @@ package event type Event struct { - ID string Title string Date string } diff --git a/hw12_13_14_15_calendar/internal/storage/memory/memorystorage.go b/hw12_13_14_15_calendar/internal/storage/memory/memorystorage.go new file mode 100644 index 0000000..07280b8 --- /dev/null +++ b/hw12_13_14_15_calendar/internal/storage/memory/memorystorage.go @@ -0,0 +1,50 @@ +package memorystorage + +import ( + "sync" + + "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/internal/storage/event" +) + +type Storage struct { + Events map[int64]event.Event + lastID int64 + Mu sync.RWMutex +} + +func New() *Storage { + return &Storage{} +} + +func (s *Storage) Create(event event.Event) (int64, error) { + s.Mu.Lock() + s.lastID++ + s.Events[s.lastID] = event + s.Mu.Unlock() + return s.lastID, nil +} + +func (s *Storage) Update(id int64, event event.Event) error { + s.Mu.Lock() + s.Events[id] = event + s.Mu.Unlock() + return nil +} + +func (s *Storage) Delete(id int64) error { + s.Mu.Lock() + delete(s.Events, id) + s.Mu.Unlock() + return nil +} + +func (s *Storage) List() (map[int64]event.Event, error) { + return s.Events, nil +} + +func (s *Storage) GetByID(id int64) (event.Event, bool) { + if s.Events[id].Title == "" { + return event.Event{}, false + } + return s.Events[id], false +} diff --git a/hw12_13_14_15_calendar/internal/storage/sql/sqlstorage.go b/hw12_13_14_15_calendar/internal/storage/sql/sqlstorage.go new file mode 100644 index 0000000..ad54229 --- /dev/null +++ b/hw12_13_14_15_calendar/internal/storage/sql/sqlstorage.go @@ -0,0 +1,99 @@ +package sqlstorage + +import ( + "database/sql" + + "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/internal/storage/event" +) + +type Config struct { + User string + Pass string + Host string + Port string + Dbase string +} + +type Storage struct { + db *sql.DB +} + +func New(conf Config) *Storage { + return &Storage{} +} + +func (s *Storage) Connect(config Config) error { + var err error + s.db, err = sql.Open("mysql", config.User+":"+config.Pass+"@tcp("+config.Host+":"+config.Port+")/"+config.Dbase) + if err != nil { + return err + } + return nil +} + +func (s *Storage) Close() error { + return s.db.Close() +} + +func (s *Storage) Create(event event.Event) (int64, error) { + res, err := s.db.Exec( + `INSERT INTO events (title, date) VALUES ($1, $2)`, + event.Title, + event.Date, + ) + if err != nil { + return -1, err + } + return res.LastInsertId() +} + +func (s *Storage) Update(id int64, event event.Event) error { + _, err := s.db.Exec( + `UPDATE events set title=$1, date=$2 where id=$3`, + event.Title, + event.Date, + id, + ) + return err +} + +func (s *Storage) Delete(id int64) error { + _, err := s.db.Exec( + `DELETE from events where id=$1`, + id, + ) + return err +} + +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 + } + defer results.Close() + for results.Next() { + var tmp struct { + id int64 + title string + date string + } + err = results.Scan(&tmp.id, &tmp.title, &tmp.date) + if err != nil { + return res, err + } + res[tmp.id] = event.Event{Title: tmp.title, Date: tmp.date} + } + return res, nil +} + +func (s *Storage) GetByID(id int64) (event.Event, bool) { + var res event.Event + err := s.db.QueryRow( + `SELECT (title,date) from events where id=$1`, id).Scan(res.Title, res.Date) + if err != nil { + return res, false + } + return res, true +} diff --git a/hw12_13_14_15_calendar/src/storage/store.go b/hw12_13_14_15_calendar/internal/storage/store.go similarity index 65% rename from hw12_13_14_15_calendar/src/storage/store.go rename to hw12_13_14_15_calendar/internal/storage/store.go index 5629f8e..5017a41 100644 --- a/hw12_13_14_15_calendar/src/storage/store.go +++ b/hw12_13_14_15_calendar/internal/storage/store.go @@ -1,9 +1,9 @@ package store import ( - "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/src/storage/event" - memorystorage "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/src/storage/memory" - sqlstorage "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/src/storage/sql" + "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/internal/storage/event" + memorystorage "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/internal/storage/memory" + sqlstorage "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/internal/storage/sql" ) type Config struct { @@ -16,11 +16,11 @@ type Config struct { } type StorageInterface interface { - Create(event event.Event) error - Update(event event.Event) error - Delete(event event.Event) error - List() []event.Event - Get(id string) (event.Event, bool) + Create(event event.Event) (int64, error) + Update(id int64, event event.Event) error + Delete(id int64) error + List() (map[int64]event.Event, error) + GetByID(id int64) (event.Event, bool) } func NewStore(conf Config) StorageInterface { diff --git a/hw12_13_14_15_calendar/migrations/20200924000000_init.sql b/hw12_13_14_15_calendar/migrations/20200924000000_init.sql new file mode 100644 index 0000000..6599b88 --- /dev/null +++ b/hw12_13_14_15_calendar/migrations/20200924000000_init.sql @@ -0,0 +1,14 @@ +-- +goose Up +-- +goose StatementBegin +CREATE TABLE events ( + id int(16) NOT NULL AUTO_INCREMENT, + title varchar(255) NOT NULL, + date varchar(255) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8;; +-- +goose StatementEnd + +-- +goose Down +-- +goose StatementBegin +DROP TABLE events; +-- +goose StatementEnd \ No newline at end of file diff --git a/hw12_13_14_15_calendar/src/app/app.go b/hw12_13_14_15_calendar/src/app/app.go deleted file mode 100644 index 50d4809..0000000 --- a/hw12_13_14_15_calendar/src/app/app.go +++ /dev/null @@ -1,38 +0,0 @@ -package app - -import ( - "context" - "net/http" - - "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/src/logger" - store "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/src/storage" - "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/src/storage/event" -) - -type Interface interface { - CreateEvent(ctx context.Context, id string, title string) (err error) - Handler(w http.ResponseWriter, r *http.Request) -} - -type App struct { - storage store.StorageInterface - logger logger.Interface -} - -func New(logger logger.Interface, storage store.StorageInterface) *App { - return &App{logger: logger, storage: storage} -} - -func (a *App) CreateEvent(ctx context.Context, id string, title string) (err error) { - err = a.storage.Create(event.Event{ID: id, Title: title}) - if err != nil { - a.logger.Errorf("can not create event") - } - a.logger.Infof("event created") - return err -} - -func (a *App) Handler(w http.ResponseWriter, r *http.Request) { - w.WriteHeader(200) - _, _ = w.Write([]byte("Hello! I'm calendar app!")) -} diff --git a/hw12_13_14_15_calendar/src/server/http/middleware.go b/hw12_13_14_15_calendar/src/server/http/middleware.go deleted file mode 100644 index 48654a3..0000000 --- a/hw12_13_14_15_calendar/src/server/http/middleware.go +++ /dev/null @@ -1,7 +0,0 @@ -package internalhttp - -//func loggingMiddleware(next http.Handler) http.Handler { -// return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { -// TODO -// }) -//} diff --git a/hw12_13_14_15_calendar/src/server/http/server.go b/hw12_13_14_15_calendar/src/server/http/server.go deleted file mode 100644 index ef74e19..0000000 --- a/hw12_13_14_15_calendar/src/server/http/server.go +++ /dev/null @@ -1,25 +0,0 @@ -package internalhttp - -import ( - "net" - "net/http" - - "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/src/app" -) - -type Server struct { - server *http.Server - app app.Interface -} - -func NewServer(app app.Interface, address string, port string) *Server { - return &Server{server: &http.Server{Addr: net.JoinHostPort(address, port), Handler: http.HandlerFunc(app.Handler)}, app: app} -} - -func (s *Server) Start() error { - return s.server.ListenAndServe() -} - -func (s *Server) Stop() error { - return s.server.Close() -} diff --git a/hw12_13_14_15_calendar/src/storage/memory/memorystorage.go b/hw12_13_14_15_calendar/src/storage/memory/memorystorage.go deleted file mode 100644 index 7578070..0000000 --- a/hw12_13_14_15_calendar/src/storage/memory/memorystorage.go +++ /dev/null @@ -1,41 +0,0 @@ -package memorystorage - -import ( - "sync" - - "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/src/storage/event" -) - -type Storage struct { - Events []event.Event - Mu sync.RWMutex -} - -func New() *Storage { - return &Storage{} -} - -func (s *Storage) Create(event event.Event) error { - if _, ok := s.Get(event.ID); !ok { - s.Mu.Lock() - s.Events = append(s.Events, event) - s.Mu.Unlock() - } - return nil -} - -func (s *Storage) Update(event event.Event) error { - return nil -} - -func (s *Storage) Delete(event event.Event) error { - return nil -} - -func (s *Storage) List() []event.Event { - return []event.Event{} -} - -func (s *Storage) Get(id string) (event.Event, bool) { - return event.Event{}, false -} diff --git a/hw12_13_14_15_calendar/src/storage/sql/sqlstorage.go b/hw12_13_14_15_calendar/src/storage/sql/sqlstorage.go deleted file mode 100644 index 3c509cc..0000000 --- a/hw12_13_14_15_calendar/src/storage/sql/sqlstorage.go +++ /dev/null @@ -1,55 +0,0 @@ -package sqlstorage - -import ( - "context" - - "github.com/tiburon-777/HW_OTUS/hw12_13_14_15_calendar/src/storage/event" -) - -type Config struct { - Host string - Port string - Dbase string - User string - Pass string -} - -type Storage struct { - //Events []event.Event - //Mu sync.RWMutex -} - -func New(conf Config) *Storage { - return &Storage{} -} - -func (s *Storage) Connect(ctx context.Context) error { - // TODO - return nil -} - -func (s *Storage) Close(ctx context.Context) error { - // TODO - return nil -} - -func (s *Storage) Create(e event.Event) error { - // TODO - return nil -} - -func (s *Storage) Update(event event.Event) error { - return nil -} - -func (s *Storage) Delete(event event.Event) error { - return nil -} - -func (s *Storage) List() []event.Event { - return []event.Event{} -} - -func (s *Storage) Get(id string) (event.Event, bool) { - return event.Event{}, false -} From bc91e45c8b1b048b5bd43372f84219ae4b9210a0 Mon Sep 17 00:00:00 2001 From: Andrey Ivanov Date: Thu, 24 Sep 2020 16:15:00 +0300 Subject: [PATCH 07/11] =?UTF-8?q?HW12=20Makefile=20=D0=BF=D0=BE=D0=BF?= =?UTF-8?q?=D1=80=D0=B0=D0=B2=D0=B8=D0=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hw12_13_14_15_calendar/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw12_13_14_15_calendar/Makefile b/hw12_13_14_15_calendar/Makefile index 3467137..93a3436 100644 --- a/hw12_13_14_15_calendar/Makefile +++ b/hw12_13_14_15_calendar/Makefile @@ -1,5 +1,5 @@ build: - go build -o ./bin/calendar ./src + go build -o ./bin/calendar ./cmd/calendar/main.go run: go run ./cmd/calendar/main.go -config ./configs/config.toml From 72ecf8fb02d1e4533547022bb22bac2178b4ad99 Mon Sep 17 00:00:00 2001 From: Andrey Ivanov Date: Thu, 24 Sep 2020 17:58:39 +0300 Subject: [PATCH 08/11] HW12 completed --- .../internal/server/http/middleware.go | 9 --- .../internal/server/http/server.go | 2 +- .../internal/storage/memory/memorystorage.go | 4 +- .../storage/memory/memorystorage_test.go | 56 +++++++++++++++++++ 4 files changed, 59 insertions(+), 12 deletions(-) delete mode 100644 hw12_13_14_15_calendar/internal/server/http/middleware.go create mode 100644 hw12_13_14_15_calendar/internal/storage/memory/memorystorage_test.go diff --git a/hw12_13_14_15_calendar/internal/server/http/middleware.go b/hw12_13_14_15_calendar/internal/server/http/middleware.go deleted file mode 100644 index 5b5cec1..0000000 --- a/hw12_13_14_15_calendar/internal/server/http/middleware.go +++ /dev/null @@ -1,9 +0,0 @@ -package http - -/* -func loggingMiddleware(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - - }) -} -*/ diff --git a/hw12_13_14_15_calendar/internal/server/http/server.go b/hw12_13_14_15_calendar/internal/server/http/server.go index 8c25f46..0043c8f 100644 --- a/hw12_13_14_15_calendar/internal/server/http/server.go +++ b/hw12_13_14_15_calendar/internal/server/http/server.go @@ -32,6 +32,6 @@ func (s *Server) Stop() error { if err := s.server.Close(); err != nil { return err } - s.app.Logger.Infof("Server starting") + s.app.Logger.Infof("Server stoped") return nil } diff --git a/hw12_13_14_15_calendar/internal/storage/memory/memorystorage.go b/hw12_13_14_15_calendar/internal/storage/memory/memorystorage.go index 07280b8..ffd31dd 100644 --- a/hw12_13_14_15_calendar/internal/storage/memory/memorystorage.go +++ b/hw12_13_14_15_calendar/internal/storage/memory/memorystorage.go @@ -13,7 +13,7 @@ type Storage struct { } func New() *Storage { - return &Storage{} + return &Storage{Events: make(map[int64]event.Event)} } func (s *Storage) Create(event event.Event) (int64, error) { @@ -46,5 +46,5 @@ func (s *Storage) GetByID(id int64) (event.Event, bool) { if s.Events[id].Title == "" { return event.Event{}, false } - return s.Events[id], false + return s.Events[id], true } diff --git a/hw12_13_14_15_calendar/internal/storage/memory/memorystorage_test.go b/hw12_13_14_15_calendar/internal/storage/memory/memorystorage_test.go new file mode 100644 index 0000000..8a7a2de --- /dev/null +++ b/hw12_13_14_15_calendar/internal/storage/memory/memorystorage_test.go @@ -0,0 +1,56 @@ +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)) + }) + +} \ No newline at end of file From 73a669ab90acd0e36455f72384025724f984b975 Mon Sep 17 00:00:00 2001 From: Andrey Ivanov Date: Fri, 25 Sep 2020 11:20:26 +0300 Subject: [PATCH 09/11] HW12 completed --- hw12_13_14_15_calendar/internal/app/app.go | 14 ++++- .../internal/logger/logger.go | 9 +-- .../internal/server/http/server.go | 6 +- .../internal/storage/event/event.go | 12 +++- .../memory/{memorystorage.go => memory.go} | 2 +- .../internal/storage/memory/memory_test.go | 60 +++++++++++++++++++ .../storage/memory/memorystorage_test.go | 56 ----------------- .../storage/sql/{sqlstorage.go => sql.go} | 60 +++++++++++++------ .../migrations/20200924000000_init.sql | 8 ++- 9 files changed, 136 insertions(+), 91 deletions(-) rename hw12_13_14_15_calendar/internal/storage/memory/{memorystorage.go => memory.go} (97%) create mode 100644 hw12_13_14_15_calendar/internal/storage/memory/memory_test.go delete mode 100644 hw12_13_14_15_calendar/internal/storage/memory/memorystorage_test.go rename hw12_13_14_15_calendar/internal/storage/sql/{sqlstorage.go => sql.go} (50%) diff --git a/hw12_13_14_15_calendar/internal/app/app.go b/hw12_13_14_15_calendar/internal/app/app.go index dd06169..ffed7f0 100644 --- a/hw12_13_14_15_calendar/internal/app/app.go +++ b/hw12_13_14_15_calendar/internal/app/app.go @@ -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) }) } diff --git a/hw12_13_14_15_calendar/internal/logger/logger.go b/hw12_13_14_15_calendar/internal/logger/logger.go index 4eac1a6..b2482dc 100644 --- a/hw12_13_14_15_calendar/internal/logger/logger.go +++ b/hw12_13_14_15_calendar/internal/logger/logger.go @@ -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 } diff --git a/hw12_13_14_15_calendar/internal/server/http/server.go b/hw12_13_14_15_calendar/internal/server/http/server.go index 0043c8f..3ae6cd2 100644 --- a/hw12_13_14_15_calendar/internal/server/http/server.go +++ b/hw12_13_14_15_calendar/internal/server/http/server.go @@ -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 { diff --git a/hw12_13_14_15_calendar/internal/storage/event/event.go b/hw12_13_14_15_calendar/internal/storage/event/event.go index f1897f0..51e25e7 100644 --- a/hw12_13_14_15_calendar/internal/storage/event/event.go +++ b/hw12_13_14_15_calendar/internal/storage/event/event.go @@ -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 } diff --git a/hw12_13_14_15_calendar/internal/storage/memory/memorystorage.go b/hw12_13_14_15_calendar/internal/storage/memory/memory.go similarity index 97% rename from hw12_13_14_15_calendar/internal/storage/memory/memorystorage.go rename to hw12_13_14_15_calendar/internal/storage/memory/memory.go index ffd31dd..f348371 100644 --- a/hw12_13_14_15_calendar/internal/storage/memory/memorystorage.go +++ b/hw12_13_14_15_calendar/internal/storage/memory/memory.go @@ -1,4 +1,4 @@ -package memorystorage +package memory import ( "sync" diff --git a/hw12_13_14_15_calendar/internal/storage/memory/memory_test.go b/hw12_13_14_15_calendar/internal/storage/memory/memory_test.go new file mode 100644 index 0000000..5735453 --- /dev/null +++ b/hw12_13_14_15_calendar/internal/storage/memory/memory_test.go @@ -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)) + }) + +} diff --git a/hw12_13_14_15_calendar/internal/storage/memory/memorystorage_test.go b/hw12_13_14_15_calendar/internal/storage/memory/memorystorage_test.go deleted file mode 100644 index 8a7a2de..0000000 --- a/hw12_13_14_15_calendar/internal/storage/memory/memorystorage_test.go +++ /dev/null @@ -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)) - }) - -} \ No newline at end of file diff --git a/hw12_13_14_15_calendar/internal/storage/sql/sqlstorage.go b/hw12_13_14_15_calendar/internal/storage/sql/sql.go similarity index 50% rename from hw12_13_14_15_calendar/internal/storage/sql/sqlstorage.go rename to hw12_13_14_15_calendar/internal/storage/sql/sql.go index ad54229..358acfa 100644 --- a/hw12_13_14_15_calendar/internal/storage/sql/sqlstorage.go +++ b/hw12_13_14_15_calendar/internal/storage/sql/sql.go @@ -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 } diff --git a/hw12_13_14_15_calendar/migrations/20200924000000_init.sql b/hw12_13_14_15_calendar/migrations/20200924000000_init.sql index 6599b88..c048c95 100644 --- a/hw12_13_14_15_calendar/migrations/20200924000000_init.sql +++ b/hw12_13_14_15_calendar/migrations/20200924000000_init.sql @@ -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 \ No newline at end of file +-- +goose StatementEnd From 6fd369434abb5e486631a80c949a1d185eaab81f Mon Sep 17 00:00:00 2001 From: Andrey Ivanov Date: Fri, 25 Sep 2020 12:24:06 +0300 Subject: [PATCH 10/11] HW12 completed --- .../internal/logger/logger.go | 10 ++--- .../internal/storage/event/event.go | 2 + .../internal/storage/memory/memory.go | 16 ++++---- .../internal/storage/sql/sql.go | 37 ++++++++++--------- .../internal/storage/store.go | 10 ++--- 5 files changed, 39 insertions(+), 36 deletions(-) diff --git a/hw12_13_14_15_calendar/internal/logger/logger.go b/hw12_13_14_15_calendar/internal/logger/logger.go index b2482dc..172ae8d 100644 --- a/hw12_13_14_15_calendar/internal/logger/logger.go +++ b/hw12_13_14_15_calendar/internal/logger/logger.go @@ -44,23 +44,23 @@ func New(conf config.Config) (Interface, error) { return l, nil } -func (l *Logger) Debugf(format string, args ...interface{}) { +func (l Logger) Debugf(format string, args ...interface{}) { l.Logger.Debugf(format, args) } -func (l *Logger) Infof(format string, args ...interface{}) { +func (l Logger) Infof(format string, args ...interface{}) { l.Logger.Infof(format, args) } -func (l *Logger) Warnf(format string, args ...interface{}) { +func (l Logger) Warnf(format string, args ...interface{}) { l.Logger.Warnf(format, args) } -func (l *Logger) Errorf(format string, args ...interface{}) { +func (l Logger) Errorf(format string, args ...interface{}) { l.Logger.Errorf(format, args) } -func (l *Logger) Fatalf(format string, args ...interface{}) { +func (l Logger) Fatalf(format string, args ...interface{}) { l.Logger.Fatalf(format, args) os.Exit(2) } diff --git a/hw12_13_14_15_calendar/internal/storage/event/event.go b/hw12_13_14_15_calendar/internal/storage/event/event.go index 51e25e7..1c4b4a8 100644 --- a/hw12_13_14_15_calendar/internal/storage/event/event.go +++ b/hw12_13_14_15_calendar/internal/storage/event/event.go @@ -4,6 +4,8 @@ import ( "time" ) +type ID int64 + type Event struct { Title string Date time.Time diff --git a/hw12_13_14_15_calendar/internal/storage/memory/memory.go b/hw12_13_14_15_calendar/internal/storage/memory/memory.go index f348371..48ad73a 100644 --- a/hw12_13_14_15_calendar/internal/storage/memory/memory.go +++ b/hw12_13_14_15_calendar/internal/storage/memory/memory.go @@ -7,16 +7,16 @@ import ( ) type Storage struct { - Events map[int64]event.Event - lastID int64 + Events map[event.ID]event.Event + lastID event.ID Mu sync.RWMutex } func New() *Storage { - return &Storage{Events: make(map[int64]event.Event)} + return &Storage{Events: make(map[event.ID]event.Event)} } -func (s *Storage) Create(event event.Event) (int64, error) { +func (s *Storage) Create(event event.Event) (event.ID, error) { s.Mu.Lock() s.lastID++ s.Events[s.lastID] = event @@ -24,25 +24,25 @@ func (s *Storage) Create(event event.Event) (int64, error) { return s.lastID, nil } -func (s *Storage) Update(id int64, event event.Event) error { +func (s *Storage) Update(id event.ID, event event.Event) error { s.Mu.Lock() s.Events[id] = event s.Mu.Unlock() return nil } -func (s *Storage) Delete(id int64) error { +func (s *Storage) Delete(id event.ID) error { s.Mu.Lock() delete(s.Events, id) s.Mu.Unlock() return nil } -func (s *Storage) List() (map[int64]event.Event, error) { +func (s *Storage) List() (map[event.ID]event.Event, error) { return s.Events, nil } -func (s *Storage) GetByID(id int64) (event.Event, bool) { +func (s *Storage) GetByID(id event.ID) (event.Event, bool) { if s.Events[id].Title == "" { return event.Event{}, false } diff --git a/hw12_13_14_15_calendar/internal/storage/sql/sql.go b/hw12_13_14_15_calendar/internal/storage/sql/sql.go index 358acfa..4476f30 100644 --- a/hw12_13_14_15_calendar/internal/storage/sql/sql.go +++ b/hw12_13_14_15_calendar/internal/storage/sql/sql.go @@ -38,25 +38,26 @@ func (s *Storage) Close() error { return s.db.Close() } -func (s *Storage) Create(event event.Event) (int64, error) { +func (s *Storage) Create(ev event.Event) (event.ID, error) { res, err := s.db.Exec( `INSERT INTO events (title, date, latency, note, userID, notifyTime) VALUES ($1, $2, $3, $4, $5, $6)`, - event.Title, - event.Date.Format(dateTimeLayout), - event.Latency, - event.Note, - event.UserID, - event.NotifyTime, + ev.Title, + ev.Date.Format(dateTimeLayout), + ev.Latency, + ev.Note, + ev.UserID, + ev.NotifyTime, ) if err != nil { return -1, err } - return res.LastInsertId() + idint64, err := res.LastInsertId() + return event.ID(idint64), err } -func (s *Storage) Update(id int64, event event.Event) error { +func (s *Storage) Update(id event.ID, event event.Event) error { _, err := s.db.Exec( `UPDATE events set title=$1, date=$2, latency=$3, note=$4, userID=$5, notifyTime=$6 @@ -72,7 +73,7 @@ func (s *Storage) Update(id int64, event event.Event) error { return err } -func (s *Storage) Delete(id int64) error { +func (s *Storage) Delete(id event.ID) error { _, err := s.db.Exec( `DELETE from events where id=$1`, id, @@ -80,35 +81,35 @@ func (s *Storage) Delete(id int64) error { return err } -func (s *Storage) List() (map[int64]event.Event, error) { - res := make(map[int64]event.Event) +func (s *Storage) List() (map[event.ID]event.Event, error) { + res := make(map[event.ID]event.Event) results, err := s.db.Query( `SELECT (id,title,date,latency,note,userID,notifyTime) from events ORDER BY id`) if err != nil { - return map[int64]event.Event{}, err + return map[event.ID]event.Event{}, err } defer results.Close() for results.Next() { - var id int64 + var id event.ID 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 map[int64]event.Event{}, err + return map[event.ID]event.Event{}, err } evt.Date, err = time.Parse(dateTimeLayout, dateRaw) if err != nil { - return map[int64]event.Event{}, err + return map[event.ID]event.Event{}, err } res[id] = evt } if results.Err() != nil { - return map[int64]event.Event{}, results.Err() + return map[event.ID]event.Event{}, results.Err() } return res, nil } -func (s *Storage) GetByID(id int64) (event.Event, bool) { +func (s *Storage) GetByID(id event.ID) (event.Event, bool) { var res event.Event var dateRaw string err := s.db.QueryRow( diff --git a/hw12_13_14_15_calendar/internal/storage/store.go b/hw12_13_14_15_calendar/internal/storage/store.go index 5017a41..5341c20 100644 --- a/hw12_13_14_15_calendar/internal/storage/store.go +++ b/hw12_13_14_15_calendar/internal/storage/store.go @@ -16,11 +16,11 @@ type Config struct { } type StorageInterface interface { - Create(event event.Event) (int64, error) - Update(id int64, event event.Event) error - Delete(id int64) error - List() (map[int64]event.Event, error) - GetByID(id int64) (event.Event, bool) + Create(event event.Event) (event.ID, error) + Update(id event.ID, event event.Event) error + Delete(id event.ID) error + List() (map[event.ID]event.Event, error) + GetByID(id event.ID) (event.Event, bool) } func NewStore(conf Config) StorageInterface { From 5eab3cad6255b7cc86496964b719029a343c6c8d Mon Sep 17 00:00:00 2001 From: Andrey Ivanov Date: Fri, 25 Sep 2020 13:28:49 +0300 Subject: [PATCH 11/11] HW12 completed --- hw12_13_14_15_calendar/internal/logger/logger.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/hw12_13_14_15_calendar/internal/logger/logger.go b/hw12_13_14_15_calendar/internal/logger/logger.go index 172ae8d..b2482dc 100644 --- a/hw12_13_14_15_calendar/internal/logger/logger.go +++ b/hw12_13_14_15_calendar/internal/logger/logger.go @@ -44,23 +44,23 @@ func New(conf config.Config) (Interface, error) { return l, nil } -func (l Logger) Debugf(format string, args ...interface{}) { +func (l *Logger) Debugf(format string, args ...interface{}) { l.Logger.Debugf(format, args) } -func (l Logger) Infof(format string, args ...interface{}) { +func (l *Logger) Infof(format string, args ...interface{}) { l.Logger.Infof(format, args) } -func (l Logger) Warnf(format string, args ...interface{}) { +func (l *Logger) Warnf(format string, args ...interface{}) { l.Logger.Warnf(format, args) } -func (l Logger) Errorf(format string, args ...interface{}) { +func (l *Logger) Errorf(format string, args ...interface{}) { l.Logger.Errorf(format, args) } -func (l Logger) Fatalf(format string, args ...interface{}) { +func (l *Logger) Fatalf(format string, args ...interface{}) { l.Logger.Fatalf(format, args) os.Exit(2) }