@qwestn1x
Nedo coder C/Go/pituhon and Linux user

Golang web, массив с базы данных на html шаблон?

Нужно как то выводить на шаблон html страницы все notes с БД
я это решил через одно место - мы просто при каждом обращении пользователя создаем slice со структурой Note
и в него циклом закидываем все записи но это костыль ибо в срезы при append добавляются не только значения но и некий буфер для будущих значений да и каждый раз создавать slice это ваще не правильно.
Как решить эту задачу максимально оптимизировано?

package main

import (
	"database/sql"
	"fmt"
	"html/template"
	"net/http"
	"os"

	_ "github.com/mattn/go-sqlite3"
)

type Note struct {
	Id    int
	Title string
	Query string
}

const fname = "./notes.db"

func main() {
	file, err := os.Open(fname)
	var db *sql.DB
	if err != nil {
		db, err = sql.Open("sqlite3", fname)
		db.Exec(`CREATE TABLE "notes" (
			"Id"	INTEGER NOT NULL UNIQUE,
			"Title"	TEXT,
			"Query"	TEXT,
			PRIMARY KEY("id" AUTOINCREMENT)
		);`)
	} else {
file.Close()
		db, err = sql.Open("sqlite3", fname)
	}
	if err != nil {
		panic(err)
	}
	defer db.Close()

	http.HandleFunc("/", func(rw http.ResponseWriter, r *http.Request) {
		tmpl, err := template.ParseFiles("./templates/index.html")
		if err != nil {
			panic(err)
		}

		Notes := []Note{}
		TempNote := Note{}

		rows, err := db.Query("select * from notes order by id desc")
		if err != nil {
			panic(err)
		}

		for rows.Next() {
			err := rows.Scan(&TempNote.Id, &TempNote.Title, &TempNote.Query)
			if err != nil {
				break
			}
			Notes = append(Notes, TempNote)

		}

		tmpl.Execute(rw, Notes)
	})

	http.HandleFunc("/addnote", func(rw http.ResponseWriter, r *http.Request) {
		title, query := r.FormValue("title"), r.FormValue("query")

		if title == "" || query == "" {
			fmt.Fprint(rw, "<p style=\"color: red;\">title or query not found.<br><a href=\"/\">back</a></p>")
		} else {
			db.Exec("insert into notes (title, query) values ($1, $2)", title, query)
			fmt.Fprint(rw, "<p style=\"color: green;\">your note was added.<br><a href=\"/\">back</a></p>")
		}
		// http.Redirect(rw, r, "/", 200)
	})

	fmt.Fprintln(os.Stdout, "Server is listening...")
	http.ListenAndServe(":8080", nil)
}


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Simple web notepad</title>
</head>
<body style="background-color: dimgray; color: white;">

    <p>add note</p>
    <form action="/addnote" method="post" class="form-add">
        <input type="text" name="title" class="form-add-title" placeholder="title">
        <br>
        <textarea name="query" class="form-add-query" cols="30" rows="10" placeholder="query"></textarea>
        <br>
        <button type="submit">add</button>
    </form>
    
   <div class="notes">
       {{range .}}
    <div class="note">
        <h3 class="note-id-title"><p>{{ .Id}}</p>: {{ .Title}}</h3>
        <p class="note-query">{{ .Query}}</p>
        <!-- <form action="/deletenote" method="post">
            <input type="hidden" name="id", value="{{ .Id}}">
            <button type="submit">delete</button>
        </form> -->
    </div>
    {{else}}
    <h4>Notes not found.</h4>
    {{end}}

   </div>

</body>
</html>
  • Вопрос задан
  • 122 просмотра
Решения вопроса 1
uvelichitel
@uvelichitel Куратор тега Go
habrahabr.ru/users/uvelichitel
Если уж вас так раздражают последовательные аллокации при append(), то вместо
Notes := []Note{}
вы можете прикинуть количество записей в таблице
var count int
row :=  db.QueryRow("select count(*) from notes")
err := row.Scan(*count)
и сделать одну предварительную аллокацию
Notes := make([]Note, 0, count)
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы