Getting wrong values from the query or can't properly store received data from the database to a variable

Hi. Just started learning golang and wanted to develop a website that will work similar to Wikipedia. First, I have to work with the database to store and query for subpages, but I can’t get it right and getting wrong values from the query or can’t properly store received data to a variable. My output looks like this:

$ go run main.go
DB connected!
0  []

My code:

I checked the same query:
image

Please have a look at my code and help me find it. Thank you.

Hey there, I don’t actually see your code. Your link is to Compiler Explorer. Did you mean to link a github repo or paste in code? Welcome to the forum BTW. :slight_smile:

Hi Dean!
My code should be under the link, but I will also paste it here:

package main

import (
	"fmt"
	"log"
	"net/http"
	"os"

	"github.com/rm46627/wiki/db"
)

func main() {

	err := db.Initialize()
	if err != nil {
		fmt.Fprintf(os.Stderr, "%v\n", err.Error())
		os.Exit(1)
	}

	p, err := db.PageByTitle("test")
    if err != nil {
		fmt.Fprintf(os.Stderr, "%v\n", err.Error())
		os.Exit(1)
	}
	fmt.Println(p.ID, p.Title, p.Body)
}
package db

import (
	"database/sql"
	"fmt"

	_ "github.com/go-sql-driver/mysql"
)

type Page struct {
	ID    int64
	Title string
	Body  []byte
}

var Database *sql.DB

func Initialize() error {
	var err error
	Database, err = sql.Open("mysql", "root:password@tcp(127.0.0.1:3306)/wiki")
	if err != nil {
		return fmt.Errorf("error during opening database: %v", err)
	}
	defer Database.Close()

	err = Database.Ping()
	if err != nil {
		return fmt.Errorf("error during verifying connection to the database: %v", err)
	}

	fmt.Println("DB connected!")
	return nil
}

func PageByTitle(title string) (*Page, error) {
	var p Page
	row := Database.QueryRow("SELECT * FROM pages WHERE title = ?", title)
	if err := row.Scan(&p.ID, &p.Title, &p.Body); err != nil {
		return &p, fmt.Errorf("page title:%s scan error: %v", title, err)
	}
	return &p, nil
}

Ahhh. The problem is in Initialize. Specifically with how you are closing the database in that function:

func Initialize() error {
	...
	// As soon as initialize completes, we are closing the database.
	// subsequent calls thus fail as db is closed.
	defer Database.Close()
	...
}

You probably want to close it when main exits instead. To do this, you could add this to your db package:

// in package db
func Close() {
	Database.Close()
}

… and in main you close the db connection:

err := db.Initialize()
if err != nil {
	fmt.Fprintf(os.Stderr, "%v\n", err.Error())
	os.Exit(1)
}
defer db.Close()
2 Likes

thanks for the awesome informaton.