Created
May 13, 2023 13:11
-
-
Save EvilFreelancer/7da51129f992ab71c21784cf6a35cc78 to your computer and use it in GitHub Desktop.
Простейшее CRUD приложение Go (вариант 2)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
func getProducts() ([]Product, error) { | |
rows, err := db.Query("SELECT id, name, price FROM products") | |
if err != nil { | |
return nil, err | |
} | |
defer rows.Close() | |
var products []Product | |
for rows.Next() { | |
var p Product | |
if err := rows.Scan(&p.ID, &p.Name, &p.Price); err != nil { | |
return nil, err | |
} | |
products = append(products, p) | |
} | |
return products, rows.Err() | |
} | |
func getProduct(id int) (Product, error) { | |
var p Product | |
row := db.QueryRow("SELECT id, name, price FROM products WHERE id = ?", id) | |
if err := row.Scan(&p.ID, &p.Name, &p.Price); err != nil { | |
return p, err | |
} | |
return p, nil | |
} | |
func createProduct(p Product) (int, error) { | |
result, err := db.Exec( | |
"INSERT INTO products (name, price) VALUES (?, ?)", | |
p.Name, p.Price, | |
) | |
if err != nil { | |
return 0, err | |
} | |
id, err := result.LastInsertId() | |
if err != nil { | |
return 0, err | |
} | |
return int(id), nil | |
} | |
func updateProduct(id int, p Product) error { | |
_, err := db.Exec( | |
"UPDATE products SET name = ?, price = ? WHERE id = ?", | |
p.Name, p.Price, id, | |
) | |
return err | |
} | |
func deleteProduct(id int) error { | |
_, err := db.Exec("DELETE FROM products WHERE id = ?", id) | |
return err | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"database/sql" | |
"encoding/json" | |
"fmt" | |
"log" | |
"net/http" | |
"strconv" | |
_ "github.com/go-sql-driver/mysql" | |
) | |
var db *sql.DB | |
func main() { | |
var err error | |
db, err = sql.Open("mysql", "user:password@/dbname") | |
if err != nil { | |
log.Fatal(err) | |
} | |
defer db.Close() | |
http.HandleFunc("/products", productsHandler) | |
http.HandleFunc("/product/", productHandler) | |
// Тут указано 8080 потому, что приложениям запущенным от обычного пользователя | |
// на уровне операционной системы запрещено работать с портами, номер которых | |
// меньше чем 1024 | |
log.Fatal(http.ListenAndServe(":8080", nil)) | |
} | |
func productsHandler(w http.ResponseWriter, r *http.Request) { | |
if r.Method == http.MethodGet { | |
products, err := getProducts() | |
if err != nil { | |
http.Error(w, err.Error(), http.StatusInternalServerError) | |
return | |
} | |
json.NewEncoder(w).Encode(products) | |
} else if r.Method == http.MethodPost { | |
var p Product | |
err := json.NewDecoder(r.Body).Decode(&p) | |
if err != nil { | |
http.Error(w, err.Error(), http.StatusBadRequest) | |
return | |
} | |
id, err := createProduct(p) | |
if err != nil { | |
http.Error(w, err.Error(), http.StatusInternalServerError) | |
return | |
} | |
fmt.Fprintf(w, "New product ID: %d", id) | |
} else { | |
http.Error(w, "Invalid request method", http.StatusMethodNotAllowed) | |
} | |
} | |
func productHandler(w http.ResponseWriter, r *http.Request) { | |
id, err := strconv.Atoi(r.URL.Path[len("/product/"):]) | |
if err != nil { | |
http.Error(w, err.Error(), http.StatusBadRequest) | |
return | |
} | |
switch r.Method { | |
case http.MethodGet: | |
p, err := getProduct(id) | |
if err != nil { | |
http.Error(w, err.Error(), http.StatusInternalServerError) | |
return | |
} | |
json.NewEncoder(w).Encode(p) | |
case http.MethodPut: | |
var p Product | |
err := json.NewDecoder(r.Body).Decode(&p) | |
if err != nil { | |
http.Error(w, err.Error(), http.StatusBadRequest) | |
return | |
} | |
err = updateProduct(id, p) | |
if err != nil { | |
http.Error(w, err.Error(), http.StatusInternalServerError) | |
return | |
} | |
fmt.Fprintf(w, "Product ID: %d updated", id) | |
case http.MethodDelete: | |
err := deleteProduct(id) | |
if err != nil { | |
http.Error(w, err.Error(), http.StatusInternalServerError) | |
return | |
} | |
fmt.Fprintf(w, "Product ID: %d deleted", id) | |
default: | |
http.Error(w, "Invalid request method", http.StatusMethodNotAllowed) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
type Product struct { | |
ID int `json:"id"` | |
Name string `json:"name"` | |
Price float64 `json:"price"` | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment