Recentemente iniciei alguns estudos sobre a linguagem de programação Go, comumente chamada de GoLang. Nesta empreitada tenho me deparado com algumas pequenos obstáculos, que para as minhas limitações de hobista com programação acabam gerando algumas dores de cabeça. Este texto tem como objetivo documentar o problema e a resolução que vim a empregar.

Uma das dificuldades está na implementação de um código de acesso a um banco de dados MySql. O problema nem mesmo é com a linguagem, mas alguns detalhes da configuração das contas no MySql no meu Pop_OS.

Este pequeno tutorial vai partir da premissa de que está usando um sistema Debian-like, tal com o Pop_OS, em um sistema limpo.

O Problema

A ideia aqui é implementar um código em Go para abrir uma conexão ao mySql para um usuário “joao”, com autenticação “123456” e imprimir a versão do mySql.

Instalar e configurar o MySql

A primeira tarefa é instalar o mysql-server e o golang no seu sistema operacional. Para isto execute a apt install a seguir como usuário root:

Bash

alves@suzail:~$ sudo apt install golang mysql-server

Com os dois instalados vamos criar o usuário para o banco de dados. Para isto entre no MySql, ainda com o comando sudo.

Bash

alves@suzail:~$ sudo mysql -uroot
[sudo] password for rudson:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 11
Server version: 8.0.28-0ubuntu0.21.10.3 (Ubuntu)

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

Isto é necessário pois o usuário root do mysql somente pode ser acessado pela conta do super usuário neste momento. Para criar a conta para o usuário joao execute os comandos a seguir no prompt do mysql:

Bash

user@computer:~$ CREATE USER 'joao'@'localhost' IDENTIFIED BY '123456';
Query OK, 0 rows affected (0.04 sec)


Em seguida, para garantir todos os privilégios do banco de dados para o usuário e efetivar as mudanças com um flush dos privilégios, execute os comandos a seguir:

Bash
 
user@computer:~$ GRANT ALL PRIVILEGES ON * . * TO 'joao'@'localhost';
Query OK, 0 rows affected (0.01 sec)
user@computer:~$ FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.03 sec)


Para finalizar cheque seu usuário com a consulta abaixo:

Bash
 
user@computer:~$ SELECT user, host, plugin FROM mysql.user;
+------------------+-----------+-----------------------+
| user | host | plugin |
+------------------+-----------+-----------------------+

| debian-sys-maint | localhost | caching_sha2_password |
| joao | localhost | caching_sha2_password |
| mysql.infoschema | localhost | caching_sha2_password |
| mysql.session | localhost | caching_sha2_password |
| mysql.sys | localhost | caching_sha2_password |
| root | localhost | auth_socket |
+------------------+-----------+-----------------------+


O importante aqui é a segunda linha, o usuário joao usando o “plugin caching_sha2_password” para gerenciar o seu password.

Para um teste final, acesse o mysql com o usuário joao e a senha 123456. Se tudo correr bem você deve acessar o mysql sem problemas.

Bash
 
alves@suzail:~/$ mysql -ujoao -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 9 Server version: 8.0.28-0ubuntu0.21.10.3 (Ubuntu)

Copyright (c) 2000, 2022, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> quit;


mySql no GoLang

Antes de iniciar a programação faça alguns ajustes finais a instalação do Go, para ajustar a sua Workspace. Ajuste as variáveis GOPATH para apontar para o path onde as extensões, como a do mysql que será instalada em breve, e demais aplicativos do go podem ser encontradas. De praxe o diretório padrão é o $HOME/go. Para isto execute as linhas abaixo:

Bash

alves@suzail:~/$ echo 'export GOPATH=$HOME/go' >> ~/.bashrc
alves@suzail:~/$ echo 'export PATH=$PATH:$GOPATH/bin' >> ~/.bashrc


Tenha cuidado com o duplo maior, >>, ele é fundamental para que o texto entre aspas seja acrescentado ao final do script ~/.bashrc, e não sobrescrito. Para finalizar você deve executar estes exports no terminal, ou abra um novo terminal par continuar.

Bash

alves@suzail:~/$ export GOPATH=$HOME/go
alves@suzail:~/$ export PATH=$PATH:$GOPATH/bin


Na sequência vamos criar o diretório ~/go/src

Bash

alves@suzail:~/$ mkdir -p ~/go/{bin,pkg,src}
alves@suzail:~/$ cd ~/go/src/


Observe que o último comando foi uma mudança de diretório para a pasta ~/go/src. Isto é necessário para o passo seguinte. Por fim, instale a extensão do mySql para o Go com o comando a seguir:

Bash

alves@suzail:~/go/src/$ go get -u github.com/go-sql-driver/mysql


Isto vai instalar no diretório ~/go/src os arquivos do módulo para acessar o mySql pelo GoLang., além da biblioteca compilada, mysql.a, na pasta ~/go/pkg/...

ATENÇÃO: Esta instalação deve ser feita de dentro da pasta ~/go/src/, para que toda as fontes sejam baixadas e assim poder ser empregadas em outros programas.

O comando tree pode ser instalado pelo “apt install tree“, caso não o encontre.

O código Go

O código Go pode ser criado em qualquer pasta, mas aconselho se acostumar a desenvolver em uma pasta dentro do ~/go/src, como por exemplo “~/go/src/go/mysql/version“, ou alguma outra de sua escolha.

Bash

alves@suzail:~/$ mkdir -p ~/go/src/go/mysql/version
alves@suzail:~/$ cd ~/go/src/go/mysql/version/
alves@suzail:~/$ gedit version.go


Por fim acrescente o código a seguir num editor de texto de sua escolha (aqui usei o gedit):

package main

import (
	"database/sql"
	"fmt"

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

func main() {
	db, err := sql.Open("mysql", "joao:123456@/")
	if err != nil {
		panic(err)
	}

	var version string
	err = db.QueryRow("SELECT VERSION()").Scan(&version)
	if err != nil {
		panic(err)
	}

	fmt.Println(version)
	defer db.Close()
}

Este é um código bem básico, apenas para abrir uma conexão ao mysql, linha 11, e ler a versão, linha 17. Os "ifs" das linhas 12 e 18 verificam se ocorreu algum erro na abertura da conexão ao mysql e no envio do “SELECT VERSION()“, o que gera um
O defer db.Close() é necessário para fechar a conexão ao mysql, aberto na linha 11. Em princípio ele pode ser colocado logo após a linha 11, já que o comando defer somente executará o db.Close() no momento de fechar o programa Go, ao alcançar a linha 24.

Módulos no Go

Neste texto não pretendo estender sobre módulos, mas é necessário um pequeno adendo para poder executar o programa acima. A partir do Go 1.11 foi introduzido um novo conceito de módulos em Go com uma alternativa as limitação do GOPATH com suporte integrado a versionamento e distribuição de pacotes. Em virtude disto programas que importam pacotes externos necessitam que sejam criados no diretório os arquivos go.mod e go.sum.

Esta característica pode ser burlada alterando a variável GO111MODULE para auto com o comando a seguir:

Bash

alves@suzail:version/$ go env -w GO111MODULE=auto


Passando o parâmetro “GO111MODULE=auto” o recurso de Módulos do Go recurso fica em automático, dispensando a criação do go.mod e do go.sum na pasta em que foi criado. No entanto, se desejar criar, basta executar os comandos a seguir a cada novo pasta com programas *.go:

Bash

alves@suzail:version/$ go mod init version
go: creating new go.mod: module version
go: to add module requirements and sums:
go mod tidy
alves@suzail:version/$ go mod tidy
go: finding module for package github.com/go-sql-driver/mysql
go: downloading github.com/go-sql-driver/mysql v1.6.0
go: found github.com/go-sql-driver/mysql in github.com/go-sql-driver/mysql v1.6.0


Executando o Programa

Com a questão do módulo resolvido, execute o version.go com o comando a seguir.

Bash

alves@suzail:version/$ go run version.go
8.0.28-0ubuntu0.21.10.3


Se tudo estiver ok ele deve retornar a versão do MySql em execução.