Začneme tím, že někdy je potřeba vytvářet aplikace s připojením k databázi. Dělá se to proto, abychom se příliš nezabývali backendovým vývojem a mohli se soustředit na frontend, zejména když chybí ruce a dovednosti. Neberu na sebe tvrdit, že mé řešení bude bezpečné, ale funguje.
Jelikož nemám rád placení za hosting, využil jsem síť na své práci, kde je bílá IP. Tady je její struktura:

Mám přístup k několika počítačům, konkrétně k 192.168.1.2 (což je 192.168.0.2), kde běží Linux, a k 192.168.0.3 s Windows. Pro svou aplikaci jsem zvolil mysql a zjistil, co je v Linuxu. Byla tam již nainstalována, ale nikdo neznal heslo, a ti, kdo ho znali, zapomněli (ti, kdo pracovali před mnou). Zjistil jsem, že ji nikdo nepotřebuje, a tak jsem ji odstranil a pokusil se ji nainstalovat znovu. Paměť nestačila a protože bych musel připojit monitor a klávesnici s myší, abych tuto chybu opravil, rozhodl jsem se to vzdát. Navíc je stroj se systémem Windows mnohem výkonnější a mám ji navíc i na domácím notebooku. V zásadě se nebudu rozepisovat o instalaci, existuje spousta manuálů a videí na toto téma. Po instalaci mysql na stroj s Windows jsem se rozhodl udělat zálohu tabulek z notebooku na pracovní stanici.
Dělá se to takto (v mém případě):
mysqldump -uroot -p your_base > dump_file.sql
Dále v nové databázi vytvoříme databázi a obnovíme zálohu na „novém“ stroji.
mysql -h localhost -u root -p
create database your_base;
use your_base;
mysql -uroot -p your_base < dump_file.sql
show tables;
Soubor se zálohou je třeba vložit do nového stroje a pokud není v adresáři s utilitou, tak je potřeba uvést i úplnou cestu k němu. (Jednoduše jsem zálohu nahrál na GitHub a naklonoval ji na nový stroj). Přidal bych, jak se tvoří samotné tabulky, ale nesmyslím screenshoty, a myslím, že to není ani složité pro studenta 2. nebo 3. ročníku.
Když jsem obnovil všechny tabulky, přišel čas udělat vzdálený přístup k db. V podstatě tyto příkazy k úspěchu nevedly (dala jen právo na čtení select)
create user 'client'@'%' IDENTIFIED by 'client';
grant select on your_base . * to 'client'@'%';
flush privileges;
Přesněji jsem se mohl k databázi připojit pouze příkazem,
mysql -h localhost -u client -pclient
ale to už nešlo
mysql -h 192.168.0.3 -u client -pclient
to mi nevyhovovalo, stejně jsem se nemohl připojit skrze tuto adresu ani jako root.
Program mysql workbench pomohla, stačí v nastavení změnit localhost na % a vše funguje, i když klient to nepomohlo. Nyní se můžete připojit k databázi z konzole nebo z kódu z jakékoli adresy.

Ještě je potřeba vytvořit domácí nebo podnikovou síť a vypnout firewall Windows, jinak nebudete schopni ani pingnout tuto mašinu (ne že byste se mohli připojit k databázi).
Polovina práce je hotová, teď potřebuji, abych se mohl připojit k databázi z domova.
Jak je vidět z diagramu sítě, musíme projít cestu od 192.168.0.3 k 192.168.1.1 (router) a poté jdeme naopak. Nastavíme trasu od 192.168.1.1 k 192.168.1.2 následujícím způsobem:

Celkově, obraz se nezobrazuje — napíšu to ručně:
route add 192.168.0.0 mask 255.255.255.0 gateway 192.168.1.2
To lze provést pouze v jedné podsíti, tedy nelze současně přesměrovat na adresu 192.168.0.2 nebo 192.168.0.3.
Je to potřeba, aby router věděl, kde se nachází podsíť 192.168.0.0/24 (naučte se základy sítí, je to užitečné).
Nyní přidáme přesměrování portu 3306 (výchozí port mysql (pokud jste ho při instalaci nezměnili)) na adresu 192.168.1.2.

Nyní zbývá udělat to nejtěžší, a to překlad na linuxovém stroji (na něm jsou dvě síťové karty 192.168.1.2 (rozhraní enp3s1) a 192.168.0.2 (rozhraní enp3s0), aby síťové karty věděly, co přesměrovat z 192.168.1.2 na 192.168.0.2, a pak na naši Windows mašinu s MySql.
sudo iptables -A FORWARD -i enp3s1 -o enp3s0 -p tcp --syn --dport 3306 -m conntrack --ctstate NEW -j ACCEPT
sudo iptables -A FORWARD -i enp3s1 -o enp3s0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
sudo iptables -A FORWARD -i enp3s0 -o enp3s1 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
sudo iptables -t nat -A PREROUTING -i enp3s1 -p tcp --dport 3306 -j DNAT --to-destination 192.168.0.3
sudo iptables -t nat -A POSTROUTING -o enp3s0 -p tcp --dport 3306 -d 192.168.0.3 -j SNAT --to-source 192.168.1.2
A poslední řádek ukládá zadané příkazy, aby se při restartu OS neztratily
sudo service iptables-persistent save
Tedy, první řádek znamená, že přijímáme první spojení, druhý a třetí říkají, že můžeme posílat pakety oběma směry, čtvrtý a pátý znamenají změnu adresy cíle a zdroje. A voilà, můžete se připojit z domova přes mysql. A nakonec můj kód v c++, který to dělá:
//DataBaseConnection.cpp
#include "DataBaseConnection.h"
DataBaseConnection::DataBaseConnection()
{
}
void DataBaseConnection::Connect()
{
// Получаем дескриптор соединения
conn = mysql_init(NULL);
if (conn == NULL)
{
// Если дескриптор не получен – выводим сообщение об ошибке
fprintf(stderr, "Error: can'tcreate MySQL-descriptorn");
//exit(1); //Если используется оконное приложение
}
// Подключаемся к serveru
if (!mysql_real_connect(conn, "192.168.0.3", "root", "password", "your_base", NULL, NULL, 0))
{
// Pokud není možné navázat spojení s serverem
// базы данных выводим сообщение об ошибке
fprintf(stderr, "Error: can't connect to database: %sn", mysql_error(conn));
}
else
{
// Если соединение успешно установлено выводим фразу - "Success!"
fprintf(stdout, "Success!n");
}
}
std::vector<std::string> DataBaseConnection::Query()
{
vectordrum.clear();
std::string query = "SELECT * FROM drum where id=0";
const char * q = query.c_str();
qstate = mysql_query(conn, q);
if (!qstate)
{
res = mysql_store_result(conn);
while (row = mysql_fetch_row(res))
{
//printf("ID: %s,Position: %s, Image: %sn", row[0], row[1], row[2]);
vectordrum.push_back(row[2]);
}
}
else
{
std::cout << "Query failed:" << mysql_error(conn) << std::endl;
}
return vectordrum;
}
void DataBaseConnection::Close()
{
// Закрываем соединение с сервером базы данных
mysql_close(conn);
}
DataBaseConnection::~DataBaseConnection()
{
vectordrum.clear();
}
//DataBaseConnection.h
#pragma once
#include <iostream>
#include <mysql.h>
#include <vector>
#pragma comment(lib,"mysqlcppconn.lib")
#pragma comment(lib,"libmysql.lib")
class DataBaseConnection
{
public:
DataBaseConnection();
void Connect();
std::vector<std::string> Query();
void Close();
~DataBaseConnection();
MYSQL *conn;
MYSQL_ROW row;
MYSQL_RES *res;
int qstate;
std::vector<std::string> vectordrum;
};
Nyní mohu tuto aplikaci bez obav sdílet s kýmkoli, a není potřeba ji přepisovat, aby fungovala lokálně.
Zdroj: habr.com
