You've already forked speedtest-go
							
							Migrate code from Go branch to new repo
This commit is contained in:
		
							
								
								
									
										84
									
								
								database/bolt/bolt.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								database/bolt/bolt.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,84 @@
 | 
			
		||||
package bolt
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"errors"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"go.etcd.io/bbolt"
 | 
			
		||||
 | 
			
		||||
	"github.com/librespeed/speedtest/database/schema"
 | 
			
		||||
 | 
			
		||||
	_ "github.com/go-sql-driver/mysql"
 | 
			
		||||
	log "github.com/sirupsen/logrus"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	bucketName = `speedtest`
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type Bolt struct {
 | 
			
		||||
	db *bbolt.DB
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Open(databaseFile string) *Bolt {
 | 
			
		||||
	db, err := bbolt.Open(databaseFile, 0666, nil)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Fatalf("Cannot open BoltDB database file: %s", err)
 | 
			
		||||
	}
 | 
			
		||||
	return &Bolt{db: db}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *Bolt) Insert(data *schema.TelemetryData) error {
 | 
			
		||||
	return p.db.Update(func(tx *bbolt.Tx) error {
 | 
			
		||||
		data.Timestamp = time.Now()
 | 
			
		||||
		b, _ := json.Marshal(data)
 | 
			
		||||
		bucket, err := tx.CreateBucketIfNotExists([]byte(bucketName))
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
		return bucket.Put([]byte(data.UUID), b)
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *Bolt) FetchByUUID(uuid string) (*schema.TelemetryData, error) {
 | 
			
		||||
	var record schema.TelemetryData
 | 
			
		||||
	err := p.db.View(func(tx *bbolt.Tx) error {
 | 
			
		||||
		bucket := tx.Bucket([]byte(bucketName))
 | 
			
		||||
		if bucket == nil {
 | 
			
		||||
			return errors.New("data bucket doesn't exist yet")
 | 
			
		||||
		}
 | 
			
		||||
		b := bucket.Get([]byte(uuid))
 | 
			
		||||
		return json.Unmarshal(b, &record)
 | 
			
		||||
	})
 | 
			
		||||
	return &record, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *Bolt) FetchLast100() ([]schema.TelemetryData, error) {
 | 
			
		||||
	var records []schema.TelemetryData
 | 
			
		||||
	err := p.db.View(func(tx *bbolt.Tx) error {
 | 
			
		||||
		var record schema.TelemetryData
 | 
			
		||||
		bucket := tx.Bucket([]byte(bucketName))
 | 
			
		||||
		if bucket == nil {
 | 
			
		||||
			return errors.New("data bucket doesn't exist yet")
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		cursor := bucket.Cursor()
 | 
			
		||||
		_, b := cursor.Last()
 | 
			
		||||
 | 
			
		||||
		for len(records) < 100 {
 | 
			
		||||
			if err := json.Unmarshal(b, &record); err != nil {
 | 
			
		||||
				return err
 | 
			
		||||
			}
 | 
			
		||||
			records = append(records, record)
 | 
			
		||||
 | 
			
		||||
			_, b = cursor.Prev()
 | 
			
		||||
			if b == nil {
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return nil
 | 
			
		||||
	})
 | 
			
		||||
	return records, err
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										30
									
								
								database/database.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								database/database.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
			
		||||
package database
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/librespeed/speedtest/config"
 | 
			
		||||
	"github.com/librespeed/speedtest/database/bolt"
 | 
			
		||||
	"github.com/librespeed/speedtest/database/mysql"
 | 
			
		||||
	"github.com/librespeed/speedtest/database/postgresql"
 | 
			
		||||
	"github.com/librespeed/speedtest/database/schema"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	DB DataAccess
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type DataAccess interface {
 | 
			
		||||
	Insert(*schema.TelemetryData) error
 | 
			
		||||
	FetchByUUID(string) (*schema.TelemetryData, error)
 | 
			
		||||
	FetchLast100() ([]schema.TelemetryData, error)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func SetDBInfo(conf *config.Config) {
 | 
			
		||||
	switch conf.DatabaseType {
 | 
			
		||||
	case "postgresql":
 | 
			
		||||
		DB = postgresql.Open(conf.DatabaseHostname, conf.DatabaseUsername, conf.DatabasePassword, conf.DatabaseName)
 | 
			
		||||
	case "mysql":
 | 
			
		||||
		DB = mysql.Open(conf.DatabaseHostname, conf.DatabaseUsername, conf.DatabasePassword, conf.DatabaseName)
 | 
			
		||||
	case "bolt":
 | 
			
		||||
		DB = bolt.Open(conf.DatabaseFile)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										66
									
								
								database/mysql/mysql.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								database/mysql/mysql.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,66 @@
 | 
			
		||||
package mysql
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"database/sql"
 | 
			
		||||
	"fmt"
 | 
			
		||||
 | 
			
		||||
	"github.com/librespeed/speedtest/database/schema"
 | 
			
		||||
 | 
			
		||||
	_ "github.com/go-sql-driver/mysql"
 | 
			
		||||
	log "github.com/sirupsen/logrus"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	connectionStringTemplate = `%s:%s@%s/%s`
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type MySQL struct {
 | 
			
		||||
	db *sql.DB
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Open(hostname, username, password, database string) *MySQL {
 | 
			
		||||
	connStr := fmt.Sprintf(connectionStringTemplate, username, password, hostname, database)
 | 
			
		||||
	conn, err := sql.Open("mysql", connStr)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Fatalf("Cannot open MySQL database: %s", err)
 | 
			
		||||
	}
 | 
			
		||||
	return &MySQL{db: conn}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *MySQL) Insert(data *schema.TelemetryData) error {
 | 
			
		||||
	stmt := `INSERT INTO speedtest_users (ip, ispinfo, extra, ua, lang, dl, ul, ping, jitter, log, uuid) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);`
 | 
			
		||||
	_, err := p.db.Exec(stmt, data.IPAddress, data.ISPInfo, data.Extra, data.UserAgent, data.Language, data.Download, data.Upload, data.Ping, data.Jitter, data.Log, data.UUID)
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *MySQL) FetchByUUID(uuid string) (*schema.TelemetryData, error) {
 | 
			
		||||
	var record schema.TelemetryData
 | 
			
		||||
	row := p.db.QueryRow(`SELECT * FROM speedtest_users WHERE uuid = ?`, uuid)
 | 
			
		||||
	if row != nil {
 | 
			
		||||
		var id string
 | 
			
		||||
		if err := row.Scan(&id, &record.Timestamp, &record.IPAddress, &record.ISPInfo, &record.Extra, &record.UserAgent, &record.Language, &record.Download, &record.Upload, &record.Ping, &record.Jitter, &record.Log, &record.UUID); err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return &record, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *MySQL) FetchLast100() ([]schema.TelemetryData, error) {
 | 
			
		||||
	var records []schema.TelemetryData
 | 
			
		||||
	rows, err := p.db.Query(`SELECT * FROM speedtest_users ORDER BY "timestamp" DESC LIMIT 100;`)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	if rows != nil {
 | 
			
		||||
		var id string
 | 
			
		||||
 | 
			
		||||
		for rows.Next() {
 | 
			
		||||
			var record schema.TelemetryData
 | 
			
		||||
			if err := rows.Scan(&id, &record.Timestamp, &record.IPAddress, &record.ISPInfo, &record.Extra, &record.UserAgent, &record.Language, &record.Download, &record.Upload, &record.Ping, &record.Jitter, &record.Log, &record.UUID); err != nil {
 | 
			
		||||
				return nil, err
 | 
			
		||||
			}
 | 
			
		||||
			records = append(records, record)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return records, nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										60
									
								
								database/mysql/telemetry_mysql.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								database/mysql/telemetry_mysql.sql
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,60 @@
 | 
			
		||||
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
 | 
			
		||||
SET AUTOCOMMIT = 0;
 | 
			
		||||
START TRANSACTION;
 | 
			
		||||
SET time_zone = "+00:00";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
 | 
			
		||||
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
 | 
			
		||||
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
 | 
			
		||||
/*!40101 SET NAMES utf8mb4 */;
 | 
			
		||||
 | 
			
		||||
--
 | 
			
		||||
-- Database: `speedtest_telemetry`
 | 
			
		||||
--
 | 
			
		||||
 | 
			
		||||
-- --------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
--
 | 
			
		||||
-- Table structure for table `speedtest_users`
 | 
			
		||||
--
 | 
			
		||||
 | 
			
		||||
CREATE TABLE `speedtest_users` (
 | 
			
		||||
  `id` int(11) NOT NULL,
 | 
			
		||||
  `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
 | 
			
		||||
  `ip` text NOT NULL,
 | 
			
		||||
  `ispinfo` text,
 | 
			
		||||
  `extra` text,
 | 
			
		||||
  `ua` text NOT NULL,
 | 
			
		||||
  `lang` text NOT NULL,
 | 
			
		||||
  `dl` text,
 | 
			
		||||
  `ul` text,
 | 
			
		||||
  `ping` text,
 | 
			
		||||
  `jitter` text,
 | 
			
		||||
  `log` longtext,
 | 
			
		||||
  `uuid` text
 | 
			
		||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 | 
			
		||||
 | 
			
		||||
--
 | 
			
		||||
-- Indexes for dumped tables
 | 
			
		||||
--
 | 
			
		||||
 | 
			
		||||
--
 | 
			
		||||
-- Indexes for table `speedtest_users`
 | 
			
		||||
--
 | 
			
		||||
ALTER TABLE `speedtest_users`
 | 
			
		||||
  ADD PRIMARY KEY (`id`);
 | 
			
		||||
 | 
			
		||||
--
 | 
			
		||||
-- AUTO_INCREMENT for dumped tables
 | 
			
		||||
--
 | 
			
		||||
 | 
			
		||||
--
 | 
			
		||||
-- AUTO_INCREMENT for table `speedtest_users`
 | 
			
		||||
--
 | 
			
		||||
ALTER TABLE `speedtest_users`
 | 
			
		||||
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;COMMIT;
 | 
			
		||||
 | 
			
		||||
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
 | 
			
		||||
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
 | 
			
		||||
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
 | 
			
		||||
							
								
								
									
										66
									
								
								database/postgresql/postgresql.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								database/postgresql/postgresql.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,66 @@
 | 
			
		||||
package postgresql
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"database/sql"
 | 
			
		||||
	"fmt"
 | 
			
		||||
 | 
			
		||||
	"github.com/librespeed/speedtest/database/schema"
 | 
			
		||||
 | 
			
		||||
	_ "github.com/lib/pq"
 | 
			
		||||
	log "github.com/sirupsen/logrus"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	connectionStringTemplate = `postgres://%s:%s@%s/%s?sslmode=disable`
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type PostgreSQL struct {
 | 
			
		||||
	db *sql.DB
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Open(hostname, username, password, database string) *PostgreSQL {
 | 
			
		||||
	connStr := fmt.Sprintf(connectionStringTemplate, username, password, hostname, database)
 | 
			
		||||
	conn, err := sql.Open("postgres", connStr)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Fatalf("Cannot open PostgreSQL database: %s", err)
 | 
			
		||||
	}
 | 
			
		||||
	return &PostgreSQL{db: conn}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *PostgreSQL) Insert(data *schema.TelemetryData) error {
 | 
			
		||||
	stmt := `INSERT INTO speedtest_users (ip, ispinfo, extra, ua, lang, dl, ul, ping, jitter, log, uuid) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) RETURNING id;`
 | 
			
		||||
	_, err := p.db.Exec(stmt, data.IPAddress, data.ISPInfo, data.Extra, data.UserAgent, data.Language, data.Download, data.Upload, data.Ping, data.Jitter, data.Log, data.UUID)
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *PostgreSQL) FetchByUUID(uuid string) (*schema.TelemetryData, error) {
 | 
			
		||||
	var record schema.TelemetryData
 | 
			
		||||
	row := p.db.QueryRow(`SELECT * FROM speedtest_users WHERE uuid = $1`, uuid)
 | 
			
		||||
	if row != nil {
 | 
			
		||||
		var id string
 | 
			
		||||
		if err := row.Scan(&id, &record.Timestamp, &record.IPAddress, &record.ISPInfo, &record.Extra, &record.UserAgent, &record.Language, &record.Download, &record.Upload, &record.Ping, &record.Jitter, &record.Log, &record.UUID); err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return &record, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *PostgreSQL) FetchLast100() ([]schema.TelemetryData, error) {
 | 
			
		||||
	var records []schema.TelemetryData
 | 
			
		||||
	rows, err := p.db.Query(`SELECT * FROM speedtest_users ORDER BY "timestamp" DESC LIMIT 100;`)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	if rows != nil {
 | 
			
		||||
		var id string
 | 
			
		||||
 | 
			
		||||
		for rows.Next() {
 | 
			
		||||
			var record schema.TelemetryData
 | 
			
		||||
			if err := rows.Scan(&id, &record.Timestamp, &record.IPAddress, &record.ISPInfo, &record.Extra, &record.UserAgent, &record.Language, &record.Download, &record.Upload, &record.Ping, &record.Jitter, &record.Log, &record.UUID); err != nil {
 | 
			
		||||
				return nil, err
 | 
			
		||||
			}
 | 
			
		||||
			records = append(records, record)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return records, nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										114
									
								
								database/postgresql/telemetry_postgresql.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								database/postgresql/telemetry_postgresql.sql
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,114 @@
 | 
			
		||||
--
 | 
			
		||||
-- PostgreSQL database dump
 | 
			
		||||
--
 | 
			
		||||
 | 
			
		||||
-- Dumped from database version 9.6.3
 | 
			
		||||
-- Dumped by pg_dump version 9.6.5
 | 
			
		||||
 | 
			
		||||
SET statement_timeout = 0;
 | 
			
		||||
SET lock_timeout = 0;
 | 
			
		||||
SET idle_in_transaction_session_timeout = 0;
 | 
			
		||||
SET client_encoding = 'UTF8';
 | 
			
		||||
SET standard_conforming_strings = on;
 | 
			
		||||
SET check_function_bodies = false;
 | 
			
		||||
SET client_min_messages = warning;
 | 
			
		||||
SET row_security = off;
 | 
			
		||||
 | 
			
		||||
--
 | 
			
		||||
-- Name: plpgsql; Type: EXTENSION; Schema: -; Owner: 
 | 
			
		||||
--
 | 
			
		||||
 | 
			
		||||
CREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
--
 | 
			
		||||
-- Name: EXTENSION plpgsql; Type: COMMENT; Schema: -; Owner: 
 | 
			
		||||
--
 | 
			
		||||
 | 
			
		||||
COMMENT ON EXTENSION plpgsql IS 'PL/pgSQL procedural language';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
SET search_path = public, pg_catalog;
 | 
			
		||||
 | 
			
		||||
SET default_tablespace = '';
 | 
			
		||||
 | 
			
		||||
SET default_with_oids = false;
 | 
			
		||||
 | 
			
		||||
--
 | 
			
		||||
-- Name: speedtest_users; Type: TABLE; Schema: public; Owner: speedtest
 | 
			
		||||
--
 | 
			
		||||
 | 
			
		||||
CREATE TABLE speedtest_users (
 | 
			
		||||
    id integer NOT NULL,
 | 
			
		||||
    "timestamp" timestamp without time zone DEFAULT now() NOT NULL,
 | 
			
		||||
    ip text NOT NULL,
 | 
			
		||||
	ispinfo text,
 | 
			
		||||
	extra text,
 | 
			
		||||
    ua text NOT NULL,
 | 
			
		||||
    lang text NOT NULL,
 | 
			
		||||
    dl text,
 | 
			
		||||
    ul text,
 | 
			
		||||
    ping text,
 | 
			
		||||
    jitter text,
 | 
			
		||||
    log text,
 | 
			
		||||
    uuid text
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
-- Commented out the following line because it assumes the user of the speedtest server, @bplower
 | 
			
		||||
-- ALTER TABLE speedtest_users OWNER TO speedtest;
 | 
			
		||||
 | 
			
		||||
--
 | 
			
		||||
-- Name: speedtest_users_id_seq; Type: SEQUENCE; Schema: public; Owner: speedtest
 | 
			
		||||
--
 | 
			
		||||
 | 
			
		||||
CREATE SEQUENCE speedtest_users_id_seq
 | 
			
		||||
    START WITH 1
 | 
			
		||||
    INCREMENT BY 1
 | 
			
		||||
    NO MINVALUE
 | 
			
		||||
    NO MAXVALUE
 | 
			
		||||
    CACHE 1;
 | 
			
		||||
 | 
			
		||||
-- Commented out the following line because it assumes the user of the speedtest server, @bplower
 | 
			
		||||
-- ALTER TABLE speedtest_users_id_seq OWNER TO speedtest; 
 | 
			
		||||
 | 
			
		||||
--
 | 
			
		||||
-- Name: speedtest_users_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: speedtest
 | 
			
		||||
--
 | 
			
		||||
 | 
			
		||||
ALTER SEQUENCE speedtest_users_id_seq OWNED BY speedtest_users.id;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
--
 | 
			
		||||
-- Name: speedtest_users id; Type: DEFAULT; Schema: public; Owner: speedtest
 | 
			
		||||
--
 | 
			
		||||
 | 
			
		||||
ALTER TABLE ONLY speedtest_users ALTER COLUMN id SET DEFAULT nextval('speedtest_users_id_seq'::regclass);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
--
 | 
			
		||||
-- Data for Name: speedtest_users; Type: TABLE DATA; Schema: public; Owner: speedtest
 | 
			
		||||
--
 | 
			
		||||
 | 
			
		||||
COPY speedtest_users (id, "timestamp", ip, ua, lang, dl, ul, ping, jitter, log, uuid) FROM stdin;
 | 
			
		||||
\.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
--
 | 
			
		||||
-- Name: speedtest_users_id_seq; Type: SEQUENCE SET; Schema: public; Owner: speedtest
 | 
			
		||||
--
 | 
			
		||||
 | 
			
		||||
SELECT pg_catalog.setval('speedtest_users_id_seq', 1, true);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
--
 | 
			
		||||
-- Name: speedtest_users speedtest_users_pkey; Type: CONSTRAINT; Schema: public; Owner: speedtest
 | 
			
		||||
--
 | 
			
		||||
 | 
			
		||||
ALTER TABLE ONLY speedtest_users
 | 
			
		||||
    ADD CONSTRAINT speedtest_users_pkey PRIMARY KEY (id);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
--
 | 
			
		||||
-- PostgreSQL database dump complete
 | 
			
		||||
--
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										20
									
								
								database/schema/schema.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								database/schema/schema.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
			
		||||
package schema
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type TelemetryData struct {
 | 
			
		||||
	Timestamp time.Time
 | 
			
		||||
	IPAddress string
 | 
			
		||||
	ISPInfo   string
 | 
			
		||||
	Extra     string
 | 
			
		||||
	UserAgent string
 | 
			
		||||
	Language  string
 | 
			
		||||
	Download  string
 | 
			
		||||
	Upload    string
 | 
			
		||||
	Ping      string
 | 
			
		||||
	Jitter    string
 | 
			
		||||
	Log       string
 | 
			
		||||
	UUID      string
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user