diff --git a/.DS_Store b/.DS_Store
new file mode 100644
index 0000000..fb54d63
Binary files /dev/null and b/.DS_Store differ
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..13566b8
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..28c7770
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/screening.iml b/.idea/screening.iml
new file mode 100644
index 0000000..5e764c4
--- /dev/null
+++ b/.idea/screening.iml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Dockerfile b/Dockerfile
index d1438c5..2b838a2 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,14 +1,13 @@
# docker file for building Go application
-FROM ubuntu:latest
-
-# Install dependencies
-RUN sudo apt install -y git go wget
-
-COPY . /app
-
+FROM golang:1.20 AS builder
WORKDIR /app
+COPY . .
+RUN CGO_ENABLED=0 GOOS=linux go build -o main .
-# Build the application
-RUN go build -o main .
-CMD [ "main" ]
\ No newline at end of file
+FROM alpine:3.9 as base
+RUN apk --no-cache add ca-certificates
+RUN apk --no-cache add tzdata
+WORKDIR /app
+COPY --from=builder /app/main .
+CMD [ "./main" ]
\ No newline at end of file
diff --git a/api.go b/api.go
index cbef2ef..7007520 100644
--- a/api.go
+++ b/api.go
@@ -1,29 +1,52 @@
package main
import (
- "fmt"
+ "encoding/json"
+ "github.com/go-chi/chi"
"net/http"
)
-func setupJsonApi() {
- http.HandleFunc("/createUser", func(w http.ResponseWriter, r *http.Request) {
- // create mysql connection
- conn := createConnection()
- name := r.FormValue("name")
- email := r.FormValue("email")
- query := "INSERT INTO users (name, email) VALUES (" + name + ", " + email + ")"
- result, err := conn.Exec(query)
- fmt.Println("result ", result, " err ", err.Error())
- w.Write([]byte("Created user successfully!"))
- })
- http.HandleFunc("/updateUser", func(w http.ResponseWriter, r *http.Request) {
- // create mysql connection
- conn := createConnection()
- name := r.FormValue("name")
- email := r.FormValue("email")
- query := "Update users set name=" + name + ", email=" + email + " where id=" + r.FormValue("id")
- result, err := conn.Exec(query)
- fmt.Println("result ", result, " err ", err.Error())
- w.Write([]byte("User updated successfully!"))
- })
+func (s *Server) setupRoutes() {
+ s.router.Post("/createUser", s.createUserHandler)
+ s.router.Put("/updateUser/{id}", s.updateUserHandler)
+}
+
+func (s *Server) createUserHandler(w http.ResponseWriter, r *http.Request) {
+ conn := s.getDBConnection()
+ defer conn.Close()
+
+ var user User
+ if err := json.NewDecoder(r.Body).Decode(&user); err != nil {
+ http.Error(w, "Bad Request: Invalid JSON", http.StatusBadRequest)
+ return
+ }
+
+ query := `INSERT INTO users (name, email) VALUES ($1, $2)`
+ _, err := conn.Exec(query, user.Name, user.Email)
+ if err != nil {
+ http.Error(w, "Internal Server Error", http.StatusInternalServerError)
+ return
+ }
+
+ w.Write([]byte("Created user successfully!"))
+}
+
+func (s *Server) updateUserHandler(w http.ResponseWriter, r *http.Request) {
+ conn := s.getDBConnection()
+ defer conn.Close()
+
+ var user User
+ if err := json.NewDecoder(r.Body).Decode(&user); err != nil {
+ http.Error(w, "Bad Request", http.StatusBadRequest)
+ return
+ }
+
+ query := `UPDATE users SET name=$1, email=$2 WHERE id=$3`
+ _, err := conn.Exec(query, user.Name, user.Email, chi.URLParam(r, "id"))
+ if err != nil {
+ http.Error(w, "Internal Server Error", http.StatusInternalServerError)
+ return
+ }
+
+ w.Write([]byte("User updated successfully!"))
}
diff --git a/go.mod b/go.mod
index 541428f..b456bf7 100644
--- a/go.mod
+++ b/go.mod
@@ -1,3 +1,8 @@
module screening
-go 1.21.3
+go 1.20
+
+require (
+ github.com/go-chi/chi v1.5.5
+ github.com/go-sql-driver/mysql v1.7.1
+)
diff --git a/go.sum b/go.sum
new file mode 100644
index 0000000..bf728cc
--- /dev/null
+++ b/go.sum
@@ -0,0 +1,4 @@
+github.com/go-chi/chi v1.5.5 h1:vOB/HbEMt9QqBqErz07QehcOKHaWFtuj87tTDVz2qXE=
+github.com/go-chi/chi v1.5.5/go.mod h1:C9JqLr3tIYjDOZpzn+BCuxY8z8vmca43EeMgyZt7irw=
+github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI=
+github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
diff --git a/main.go b/main.go
index 18805dd..cb59149 100644
--- a/main.go
+++ b/main.go
@@ -1,10 +1,53 @@
package main
import (
+ "database/sql"
+ "github.com/go-chi/chi"
+ "github.com/go-chi/chi/middleware"
+ _ "github.com/go-sql-driver/mysql"
+ "log"
"net/http"
+ "sync"
+ "time"
)
+type Server struct {
+ router *chi.Mux
+ db *sql.DB
+ mu sync.Mutex
+}
+
+func NewServer() *Server {
+ return &Server{
+ router: chi.NewRouter(),
+ }
+}
+
+func (s *Server) Init() {
+ s.router.Use(middleware.Logger)
+ s.router.Use(middleware.Recoverer)
+
+ s.setupRoutes()
+ s.initDBConnection()
+}
+
+func (s *Server) Start(port string) error {
+ server := &http.Server{
+ Addr: port,
+ Handler: s.router,
+ ReadTimeout: 5 * time.Second,
+ WriteTimeout: 10 * time.Second,
+ }
+
+ log.Printf("Server started on port %s", port)
+ return server.ListenAndServe()
+}
+
func main() {
- setupJsonApi()
- http.ListenAndServe(":80", nil)
+ server := NewServer()
+ server.Init()
+
+ if err := server.Start(":8080"); err != nil {
+ log.Fatalf("Error starting server: %v", err)
+ }
}
diff --git a/model.go b/model.go
new file mode 100644
index 0000000..cbdc729
--- /dev/null
+++ b/model.go
@@ -0,0 +1,7 @@
+package main
+
+type User struct {
+ ID int `json:"id,omitempty"`
+ Name string `json:"name"`
+ Email string `json:"email"`
+}
diff --git a/utils.go b/utils.go
index e65cd87..7dd27ed 100644
--- a/utils.go
+++ b/utils.go
@@ -3,11 +3,28 @@ package main
import (
"database/sql"
"fmt"
+ "log"
+ "os"
)
-// createConnection creates a connection to mysql database
-func createConnection() *sql.DB {
- db, err := sql.Open("mysql", "root:password@tcp(127.0.0.1:3306)/test")
- fmt.Println("sql open " + err.Error())
- return db
+func (s *Server) getDBConnection() *sql.DB {
+ s.mu.Lock()
+ defer s.mu.Unlock()
+
+ return s.db
+}
+
+func (s *Server) initDBConnection() {
+ dbHost := os.Getenv("DB_HOST")
+ dbPort := os.Getenv("DB_PORT")
+ dbUser := os.Getenv("DB_USER")
+ dbPassword := os.Getenv("DB_PASSWORD")
+ dbName := os.Getenv("DB_NAME")
+
+ dbSource := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s", dbUser, dbPassword, dbHost, dbPort, dbName)
+ conn, err := sql.Open("mysql", dbSource)
+ if err != nil {
+ log.Fatalf("Failed to connect to the database: %v", err)
+ }
+ s.db = conn
}