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