xmr-remote-nodes/internal/database/schema.go
ditatompel 48fe09c1cb
Adding table tbl_fee
This table used to store majority fee of monero nettype.
By calculating majority fee via "cron" every 300s, the function to
get majority fee for nettypes can be done with single query.

The frontend majority static data in the frontend removed and
now use `/api/v1/fees` endpoint to get majority fee value.

Note: Don't know if it works well with `onload` method or not. Let see.
2024-05-31 16:28:21 +07:00

253 lines
6.4 KiB
Go

package database
import (
"fmt"
"log/slog"
)
type migrateFn func(*DB) error
var dbMigrate = [...]migrateFn{v1, v2}
func MigrateDb(db *DB) error {
version := getSchemaVersion(db)
if version < 0 {
return fmt.Errorf("[DB] can't get database schema version")
} else if version == 0 {
slog.Warn("[DB] No database schema version found, creating schema version 1")
} else {
slog.Info(fmt.Sprintf("[DB] Current database schema version: %d", version))
}
for ; version < len(dbMigrate); version++ {
tx, err := db.Begin()
if err != nil {
return err
}
migrateFn := dbMigrate[version]
slog.Info(fmt.Sprintf("[DB] Migrating database schema version %d", version+1))
if err := migrateFn(db); err != nil {
if err := tx.Rollback(); err != nil {
return err
}
return err
}
if err := setSchemaVersion(db, version+1); err != nil {
return err
}
if err := tx.Commit(); err != nil {
return err
}
}
return nil
}
func getSchemaVersion(db *DB) int {
_, err := db.Exec(`
CREATE TABLE IF NOT EXISTS tbl_schema_ver (
version INT(5) UNSIGNED NOT NULL
)`)
if err != nil {
return -1
}
version := 0
if err := db.Get(&version, `SELECT version FROM tbl_schema_ver`); err != nil {
return -1
}
return version
}
func setSchemaVersion(db *DB, version int) error {
_, err := db.Exec(`DELETE FROM tbl_schema_ver`)
if err != nil {
return err
}
_, err = db.Exec(`INSERT INTO tbl_schema_ver (version) VALUES (?)`, version)
return err
}
func v1(db *DB) error {
slog.Debug("[DB] Migrating database schema version 1")
// table: tbl_cron
slog.Debug("[DB] Creating table: tbl_cron")
_, err := db.Exec(`
CREATE TABLE tbl_cron (
id INT(8) UNSIGNED NOT NULL AUTO_INCREMENT,
title VARCHAR(255) NOT NULL DEFAULT '',
slug VARCHAR(255) NOT NULL DEFAULT '',
description VARCHAR(255) NOT NULL DEFAULT '',
run_every INT(8) UNSIGNED NOT NULL DEFAULT 60 COMMENT 'in seconds',
last_run INT(11) UNSIGNED NOT NULL DEFAULT 0,
next_run INT(11) UNSIGNED NOT NULL DEFAULT 0,
run_time FLOAT(7,3) UNSIGNED NOT NULL DEFAULT 0.000,
cron_state TINYINT(1) UNSIGNED NOT NULL DEFAULT 0,
is_enabled TINYINT(1) UNSIGNED NOT NULL DEFAULT 1,
PRIMARY KEY (id)
)`)
if err != nil {
return err
}
slog.Debug("[DB] Adding default cron jobs to table: tbl_cron")
_, err = db.Exec(`
INSERT INTO tbl_cron (
title,
slug,
description,
run_every
) VALUES (
'Delete old probe logs',
'delete_old_probe_logs',
'Delete old probe log from the database',
120
);`)
if err != nil {
return err
}
// table: tbl_node
slog.Debug("[DB] Creating table: tbl_node")
_, err = db.Exec(`
CREATE TABLE tbl_node (
id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
protocol VARCHAR(6) NOT NULL DEFAULT 'http' COMMENT 'http | https',
hostname VARCHAR(255) NOT NULL,
port INT(6) UNSIGNED NOT NULL DEFAULT 0,
is_tor TINYINT(1) UNSIGNED NOT NULL DEFAULT 0,
is_available TINYINT(1) UNSIGNED NOT NULL DEFAULT 0,
nettype VARCHAR(100) NOT NULL COMMENT 'mainnet | stagenet | testnet',
height BIGINT(20) UNSIGNED NOT NULL DEFAULT 0,
adjusted_time BIGINT(20) UNSIGNED NOT NULL DEFAULT 0,
database_size BIGINT(20) UNSIGNED NOT NULL DEFAULT 0,
difficulty BIGINT(20) UNSIGNED NOT NULL DEFAULT 0,
version VARCHAR(200) NOT NULL DEFAULT '',
uptime float(5,2) UNSIGNED NOT NULL DEFAULT 0.00,
estimate_fee INT(9) UNSIGNED NOT NULL DEFAULT 0,
ip_addr VARCHAR(200) NOT NULL,
asn INT(9) UNSIGNED NOT NULL DEFAULT 0,
asn_name VARCHAR(255) NOT NULL DEFAULT '',
country VARCHAR(100) NOT NULL DEFAULT '',
country_name VARCHAR(255) NOT NULL DEFAULT '',
city VARCHAR(255) NOT NULL DEFAULT '',
lat FLOAT NOT NULL DEFAULT 0 COMMENT 'latitude',
lon FLOAT NOT NULL DEFAULT 0 COMMENT 'longitude',
date_entered INT(11) UNSIGNED NOT NULL DEFAULT 0,
last_checked INT(11) UNSIGNED NOT NULL DEFAULT 0,
last_check_status TEXT DEFAULT NULL,
cors_capable TINYINT(1) UNSIGNED NOT NULL DEFAULT 0,
PRIMARY KEY (id)
)`)
if err != nil {
return err
}
// table: tbl_prober
slog.Debug("[DB] Creating table: tbl_prober")
_, err = db.Exec(`
CREATE TABLE tbl_prober (
id INT(9) UNSIGNED NOT NULL AUTO_INCREMENT,
name VARCHAR(255) NOT NULL,
api_key VARCHAR(36) NOT NULL,
last_submit_ts INT(11) UNSIGNED NOT NULL DEFAULT 0,
PRIMARY KEY (id)
)`)
if err != nil {
return err
}
slog.Debug("[DB] Adding unique key to table: tbl_prober")
_, err = db.Exec(`ALTER TABLE tbl_prober ADD UNIQUE KEY (api_key)`)
if err != nil {
return err
}
// table: tbl_probe_log
slog.Debug("[DB] Creating table: tbl_probe_log")
_, err = db.Exec(`
CREATE TABLE tbl_probe_log (
id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
node_id INT(11) UNSIGNED NOT NULL DEFAULT 0,
prober_id INT(9) UNSIGNED NOT NULL DEFAULT 0,
is_available TINYINT(1) UNSIGNED NOT NULL DEFAULT 0,
height BIGINT(20) UNSIGNED NOT NULL DEFAULT 0,
adjusted_time BIGINT(20) UNSIGNED NOT NULL DEFAULT 0,
database_size BIGINT(20) UNSIGNED NOT NULL DEFAULT 0,
difficulty BIGINT(20) UNSIGNED NOT NULL DEFAULT 0,
estimate_fee INT(9) UNSIGNED NOT NULL DEFAULT 0,
date_checked INT(11) UNSIGNED NOT NULL DEFAULT 0,
failed_reason TEXT NOT NULL DEFAULT '',
fetch_runtime FLOAT(5,2) UNSIGNED NOT NULL DEFAULT 0.00,
PRIMARY KEY (id)
)`)
if err != nil {
return err
}
slog.Debug("[DB] Adding key to table: tbl_probe_log")
_, err = db.Exec(`ALTER TABLE tbl_probe_log ADD KEY (node_id)`)
if err != nil {
return err
}
return nil
}
func v2(db *DB) error {
slog.Debug("[DB] Migrating database schema version 2")
// table: tbl_fee
slog.Debug("[DB] Creating table: tbl_fee")
_, err := db.Exec(`
CREATE TABLE tbl_fee (
nettype VARCHAR(100) NOT NULL DEFAULT '',
estimate_fee INT(9) UNSIGNED NOT NULL DEFAULT 0,
node_count INT(9) UNSIGNED NOT NULL DEFAULT 0,
PRIMARY KEY (nettype)
)`)
if err != nil {
return err
}
slog.Debug("[DB] Adding default fee to table: tbl_fee")
_, err = db.Exec(`
INSERT INTO tbl_fee (
nettype,
estimate_fee,
node_count
) VALUES (
'mainnet',
0,
0
), (
'stagenet',
0,
0
), (
'testnet',
0,
0
);`)
if err != nil {
return err
}
slog.Debug("[DB] Adding majority fee cron jobs to table: tbl_cron")
_, err = db.Exec(`
INSERT INTO tbl_cron (
title,
slug,
description,
run_every
) VALUES (
'Calculate majority fee',
'calculate_majority_fee',
'Calculate majority Monero fee',
300
);`)
if err != nil {
return err
}
return nil
}