Подключение к базе успешное, но активного пользователя нет
Только изучаю программирование на Go. Написал код для подключения к базе данных(PostgreSQL) для пользователя test. При отправке запроса на подключение проверка подключения проходит. После этого я смотрю список активных пользователей в базе, но там висит только postgres. Если после подключения сделать GET запросы, то они крашат сервер, сыпится гора ошибок и консоль зависает.
type User struct {
User string `json:"user"`
Password string `json:"password"`
DBName string `json:"dbname"`
}
var db *sql.DB
func connectHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
return
}
// Чтение данных из запроса
var conectionInfo User
err := json.NewDecoder(r.Body).Decode(&conectionInfo)
if err != nil {
log.Printf("JSON decode error: %v", err)
http.Error(w, "Invalid input", http.StatusBadRequest)
return
}
//Строка подключения
connectionString := fmt.Sprintf("user=%s password=%s dbname=%s sslmode=disable", conectionInfo.User, conectionInfo.Password, conectionInfo.DBName)
db, err = sql.Open("postgres", connectionString)
if err != nil {
log.Printf("Failed to connect to database: %v", err)
return
}
// Проверка подключения
if err := db.Ping(); err != nil {
log.Printf("failed to ping database: %v", err)
return
}
// Отправка ответа клиенту
w.WriteHeader(http.StatusOK)
w.Write([]byte("Successfully connected to the database!"))
}
func main() {
// Настройка маршрутов
http.HandleFunc("/connect", connectHandler)
http.HandleFunc("/api/v1/tasks", handlers.GetAllTasksHandler(db))
http.HandleFunc("/api/v1/task", handlers.GetIdTaskHandler(db))
http.HandleFunc("/api/v1/task/create", handlers.CreateTaskHandler(db))
http.HandleFunc("/api/v1/task/update", handlers.UpdateTaskHandler(db))
http.HandleFunc("/api/v1/task/delete", handlers.DeleteTaskHandler(db))
// Запуск сервера
log.Println("Server is running on port 8081...")
err := http.ListenAndServe(":8081", nil)
if err != nil {
log.Fatalf("Failed to start server: %v", err)
}
}
Ошибки:
C:/Program Files/Go/src/net/http/server.go:1898 +0xbe
panic({0x598b80?, 0x844c10?})
C:/Program Files/Go/src/runtime/panic.go:770 +0x132
database/sql.(*DB).conn(0x0, {0x6721a0, 0x8dc6c0}, 0x1)
C:/Program Files/Go/src/database/sql/sql.go:1310 +0x54
database/sql.(*DB).query(0x0, {0x6721a0, 0x8dc6c0}, {0x5ebedb, 0x13}, {0x0, 0x0, 0x0}, 0xe0?)
C:/Program Files/Go/src/database/sql/sql.go:1749 +0x57
database/sql.(*DB).QueryContext.func1(0xe9?)
C:/Program Files/Go/src/database/sql/sql.go:1732 +0x4f
database/sql.(*DB).retry(0x7?, 0xc00002d850)
C:/Program Files/Go/src/database/sql/sql.go:1566 +0x42
database/sql.(*DB).QueryContext(0x3135ea?, {0x6721a0?, 0x8dc6c0?}, {0x5ebedb?, 0x5967e0?}, {0x0?, 0xc0000ca124?, 0xd?})
C:/Program Files/Go/src/database/sql/sql.go:1731 +0xc5
database/sql.(*DB).Query(...)
C:/Program Files/Go/src/database/sql/sql.go:1745
github.com/apelsinkoo09/task-manager/internal/models.ReadAll(0x0?)
C:/Users/Maksim/YandexDisk/Task-manager/internal/models/task.go:24 +0x6d
main.main.GetAllTasksHandler.func1({0x671bc0, 0xc0000bc0e0}, 0xc00002db30?)
C:/Users/Maksim/YandexDisk/Task-manager/internal/handlers/taskHandler.go:18 +0x28
net/http.HandlerFunc.ServeHTTP(0x8572d0?, {0x671bc0?, 0xc0000bc0e0?}, 0x51e17a?)
C:/Program Files/Go/src/net/http/server.go:2166 +0x29
net/http.(*ServeMux).ServeHTTP(0x3256f9?, {0x671bc0, 0xc0000bc0e0}, 0xc0000a2240)
C:/Program Files/Go/src/net/http/server.go:2683 +0x1ad
net/http.serverHandler.ServeHTTP({0xc000090120?}, {0x671bc0?, 0xc0000bc0e0?}, 0x6?)
C:/Program Files/Go/src/net/http/server.go:3137 +0x8e
net/http.(*conn).serve(0xc0000aa000, {0x6722b8, 0xc000022f30})
C:/Program Files/Go/src/net/http/server.go:2039 +0x5e8
created by net/http.(*Server).Serve in goroutine 1
C:/Program Files/Go/src/net/http/server.go:3285 +0x4b4
exit status 0xc000013a
Обработчик:
func GetAllTasksHandler(db *sql.DB) http.HandlerFunc { //db - соединение с базой
return func(w http.ResponseWriter, r *http.Request) { // хендлер
// w http.ResponseWriter - интерфейс для записи ответа клиенту
// r *http.Request - структура принимаемого запроса от клиента
tasks, err := models.ReadAll(db)
if err != nil {
http.Error(w, "Unable to retrieve tasks", http.StatusInternalServerError)
// Сообщение клиенту об ошибке
// http.StatusInternalServerError - 500 статус
return
}
w.Header().Set("Content-Type", "application/json") // установка заголовка http ответа в формате ключ, значения, запись в карту. Формат отправляемых значений json
json.NewEncoder(w).Encode(tasks) // кодирование в формат json
}
}
Выражение:
type Task struct {
Id int64 `json:"id"`
Title string `json:"title"`
Description string `json:"description"`
Status string `json:"status"`
Priority int `json:"priority"`
Created_at time.Time `json:"created_at"`
Updated_at time.Time `json:"updated_at"`
User_id int `json:"user_id"`
}
func ReadAll(db *sql.DB) ([]Task, error) {
result, err := db.Query("select * from tasks") //Query возвращает итерратор, надо пройти по всем!!! строчкам
if err != nil {
log.Println(err)
}
defer result.Close()
var tasks []Task
for result.Next() { // next() подготавливает следующую строку для чтения с помощью метода scan()
var task Task
err := result.Scan( // проверка на ошибки в конкретной строке. Scan сканирует строки и назначает им переменные соответствующего типа
&task.Id,
&task.Title,
&task.Description,
&task.Status,
&task.Priority,
&task.Created_at,
&task.Updated_at,
&task.User_id,
)
if err != nil {
log.Printf("failed to scan row: %v", err)
}
tasks = append(tasks, task)
log.Printf("Task: %+v\n", task)
}
err = result.Err() // поиск общих ошибок
if err != nil {
log.Println(err)
}
return tasks, nil
}
Ответы (1 шт):
Автор решения: Максим Магерамов
→ Ссылка
Решение оказалось до безобразия простое. Необходимо для каждого маршрутизатора сделать проверку на существование подключения к базе и внутри тела функции вызывать хандлер:
http.HandleFunc("/api/v1/tasks", func(w http.ResponseWriter, r *http.Request) {
if db == nil {
http.Error(w, "Database not connected", http.StatusInternalServerError)
return
}
GetAllTasksHandler(db)(w, r)
})