2019-02-14 21:55:21 +00:00
// Copyright (C) 2019 Storj Labs, Inc.
// See LICENSE for copying information.
package satellitedb
import (
"database/sql"
"strconv"
"github.com/golang/protobuf/proto"
"github.com/zeebo/errs"
"go.uber.org/zap"
2019-05-14 16:13:18 +01:00
"storj.io/storj/internal/dbutil/pgutil"
2019-02-14 21:55:21 +00:00
"storj.io/storj/internal/migrate"
"storj.io/storj/pkg/pb"
"storj.io/storj/satellite/console"
2019-06-06 16:16:14 +01:00
"storj.io/storj/satellite/satellitedb/pbold"
2019-02-14 21:55:21 +00:00
)
2019-07-23 18:58:43 +01:00
var (
// ErrMigrate is for tracking migration errors
ErrMigrate = errs . Class ( "migrate" )
)
2019-02-14 21:55:21 +00:00
// CreateTables is a method for creating all tables for database
func ( db * DB ) CreateTables ( ) error {
switch db . driver {
case "postgres" :
2019-05-14 16:13:18 +01:00
schema , err := pgutil . ParseSchemaFromConnstr ( db . source )
if err != nil {
return errs . New ( "error parsing schema: %+v" , err )
}
if schema != "" {
err = db . CreateSchema ( schema )
if err != nil {
return errs . New ( "error creating schema: %+v" , err )
}
}
2019-02-14 21:55:21 +00:00
migration := db . PostgresMigration ( )
2019-09-10 20:42:23 +01:00
return migration . Run ( db . log . Named ( "migrate" ) )
2019-02-14 21:55:21 +00:00
default :
return migrate . Create ( "database" , db . db )
}
}
2019-11-02 20:09:07 +00:00
// CheckVersion confirms confirms the database is at the desired version
func ( db * DB ) CheckVersion ( ) error {
switch db . driver {
case "postgres" :
migration := db . PostgresMigration ( )
return migration . ValidateVersions ( db . log )
default :
return nil
}
}
2019-02-14 21:55:21 +00:00
// PostgresMigration returns steps needed for migrating postgres database.
func ( db * DB ) PostgresMigration ( ) * migrate . Migration {
return & migrate . Migration {
Table : "versions" ,
Steps : [ ] * migrate . Step {
{
// some databases may have already this done, although the version may not match
2019-09-10 20:42:23 +01:00
DB : db . db ,
2019-02-14 21:55:21 +00:00
Description : "Initial setup" ,
Version : 0 ,
Action : migrate . SQL {
` CREATE TABLE IF NOT EXISTS accounting_raws (
id bigserial NOT NULL ,
node_id bytea NOT NULL ,
interval_end_time timestamp with time zone NOT NULL ,
data_total double precision NOT NULL ,
data_type integer NOT NULL ,
created_at timestamp with time zone NOT NULL ,
PRIMARY KEY ( id )
) ` ,
` CREATE TABLE IF NOT EXISTS accounting_rollups (
id bigserial NOT NULL ,
node_id bytea NOT NULL ,
start_time timestamp with time zone NOT NULL ,
put_total bigint NOT NULL ,
get_total bigint NOT NULL ,
get_audit_total bigint NOT NULL ,
get_repair_total bigint NOT NULL ,
put_repair_total bigint NOT NULL ,
at_rest_total double precision NOT NULL ,
PRIMARY KEY ( id )
) ` ,
` CREATE TABLE IF NOT EXISTS accounting_timestamps (
name text NOT NULL ,
value timestamp with time zone NOT NULL ,
PRIMARY KEY ( name )
) ` ,
` CREATE TABLE IF NOT EXISTS bwagreements (
serialnum text NOT NULL ,
data bytea NOT NULL ,
storage_node bytea NOT NULL ,
action bigint NOT NULL ,
total bigint NOT NULL ,
created_at timestamp with time zone NOT NULL ,
expires_at timestamp with time zone NOT NULL ,
PRIMARY KEY ( serialnum )
) ` ,
` CREATE TABLE IF NOT EXISTS injuredsegments (
id bigserial NOT NULL ,
info bytea NOT NULL ,
PRIMARY KEY ( id )
) ` ,
` CREATE TABLE IF NOT EXISTS irreparabledbs (
segmentpath bytea NOT NULL ,
segmentdetail bytea NOT NULL ,
pieces_lost_count bigint NOT NULL ,
seg_damaged_unix_sec bigint NOT NULL ,
repair_attempt_count bigint NOT NULL ,
PRIMARY KEY ( segmentpath )
) ` ,
` CREATE TABLE IF NOT EXISTS nodes (
id bytea NOT NULL ,
audit_success_count bigint NOT NULL ,
total_audit_count bigint NOT NULL ,
audit_success_ratio double precision NOT NULL ,
uptime_success_count bigint NOT NULL ,
total_uptime_count bigint NOT NULL ,
uptime_ratio double precision NOT NULL ,
created_at timestamp with time zone NOT NULL ,
updated_at timestamp with time zone NOT NULL ,
PRIMARY KEY ( id )
) ` ,
` CREATE TABLE IF NOT EXISTS overlay_cache_nodes (
node_id bytea NOT NULL ,
node_type integer NOT NULL ,
address text NOT NULL ,
protocol integer NOT NULL ,
operator_email text NOT NULL ,
operator_wallet text NOT NULL ,
free_bandwidth bigint NOT NULL ,
free_disk bigint NOT NULL ,
latency_90 bigint NOT NULL ,
audit_success_ratio double precision NOT NULL ,
audit_uptime_ratio double precision NOT NULL ,
audit_count bigint NOT NULL ,
audit_success_count bigint NOT NULL ,
uptime_count bigint NOT NULL ,
uptime_success_count bigint NOT NULL ,
PRIMARY KEY ( node_id ) ,
UNIQUE ( node_id )
) ` ,
` CREATE TABLE IF NOT EXISTS projects (
id bytea NOT NULL ,
name text NOT NULL ,
description text NOT NULL ,
created_at timestamp with time zone NOT NULL ,
PRIMARY KEY ( id )
) ` ,
` CREATE TABLE IF NOT EXISTS users (
id bytea NOT NULL ,
first_name text NOT NULL ,
last_name text NOT NULL ,
email text NOT NULL ,
password_hash bytea NOT NULL ,
status integer NOT NULL ,
created_at timestamp with time zone NOT NULL ,
PRIMARY KEY ( id )
) ` ,
` CREATE TABLE IF NOT EXISTS api_keys (
id bytea NOT NULL ,
project_id bytea NOT NULL REFERENCES projects ( id ) ON DELETE CASCADE ,
key bytea NOT NULL ,
name text NOT NULL ,
created_at timestamp with time zone NOT NULL ,
PRIMARY KEY ( id ) ,
UNIQUE ( key ) ,
UNIQUE ( name , project_id )
) ` ,
` CREATE TABLE IF NOT EXISTS project_members (
member_id bytea NOT NULL REFERENCES users ( id ) ON DELETE CASCADE ,
project_id bytea NOT NULL REFERENCES projects ( id ) ON DELETE CASCADE ,
created_at timestamp with time zone NOT NULL ,
PRIMARY KEY ( member_id , project_id )
) ` ,
} ,
} ,
{
// some databases may have already this done, although the version may not match
2019-09-10 20:42:23 +01:00
DB : db . db ,
2019-02-14 21:55:21 +00:00
Description : "Adjust table naming" ,
Version : 1 ,
Action : migrate . Func ( func ( log * zap . Logger , db migrate . DB , tx * sql . Tx ) error {
hasStorageNodeID , err := postgresHasColumn ( tx , "bwagreements" , "storage_node_id" )
if err != nil {
return ErrMigrate . Wrap ( err )
}
if ! hasStorageNodeID {
// - storage_node bytea NOT NULL,
// + storage_node_id bytea NOT NULL,
_ , err := tx . Exec ( ` ALTER TABLE bwagreements RENAME COLUMN storage_node TO storage_node_id; ` )
if err != nil {
return ErrMigrate . Wrap ( err )
}
}
hasUplinkID , err := postgresHasColumn ( tx , "bwagreements" , "uplink_id" )
if err != nil {
return ErrMigrate . Wrap ( err )
}
if ! hasUplinkID {
// + uplink_id bytea NOT NULL,
_ , err := tx . Exec ( `
ALTER TABLE bwagreements ADD COLUMN uplink_id BYTEA ;
` )
if err != nil {
return ErrMigrate . Wrap ( err )
}
err = func ( ) error {
_ , err = tx . Exec ( `
DECLARE bwagreements_cursor CURSOR FOR
SELECT serialnum , data FROM bwagreements
FOR UPDATE ` )
if err != nil {
return ErrMigrate . Wrap ( err )
}
defer func ( ) {
_ , closeErr := tx . Exec ( ` CLOSE bwagreements_cursor ` )
err = errs . Combine ( err , closeErr )
} ( )
for {
var serialnum , data [ ] byte
err := tx . QueryRow ( ` FETCH NEXT FROM bwagreements_cursor ` ) . Scan ( & serialnum , & data )
if err != nil {
if err == sql . ErrNoRows {
break
}
return ErrMigrate . Wrap ( err )
}
2019-06-06 16:16:14 +01:00
var rba pbold . Order
2019-02-14 21:55:21 +00:00
if err := proto . Unmarshal ( data , & rba ) ; err != nil {
return ErrMigrate . Wrap ( err )
}
_ , err = tx . Exec ( `
UPDATE bwagreements SET uplink_id = $ 1
WHERE CURRENT OF bwagreements_cursor ` , rba . PayerAllocation . UplinkId . Bytes ( ) )
if err != nil {
return ErrMigrate . Wrap ( err )
}
}
return nil
} ( )
if err != nil {
return err
}
_ , err = tx . Exec ( `
ALTER TABLE bwagreements ALTER COLUMN uplink_id SET NOT NULL ;
ALTER TABLE bwagreements DROP COLUMN data ;
` )
if err != nil {
return ErrMigrate . Wrap ( err )
}
}
return nil
} ) ,
} ,
{
// some databases may have already this done, although the version may not match
2019-09-10 20:42:23 +01:00
DB : db . db ,
2019-02-14 21:55:21 +00:00
Description : "Remove bucket infos" ,
Version : 2 ,
Action : migrate . SQL {
` DROP TABLE IF EXISTS bucket_infos CASCADE ` ,
} ,
} ,
{
// some databases may have already this done, although the version may not match
2019-09-10 20:42:23 +01:00
DB : db . db ,
2019-02-14 21:55:21 +00:00
Description : "Add certificates table" ,
Version : 3 ,
Action : migrate . SQL {
` CREATE TABLE IF NOT EXISTS certRecords (
publickey bytea NOT NULL ,
id bytea NOT NULL ,
update_at timestamp with time zone NOT NULL ,
PRIMARY KEY ( id )
) ` ,
} ,
} ,
{
// some databases may have already this done, although the version may not match
2019-09-10 20:42:23 +01:00
DB : db . db ,
2019-02-14 21:55:21 +00:00
Description : "Adjust users table" ,
Version : 4 ,
Action : migrate . Func ( func ( log * zap . Logger , db migrate . DB , tx * sql . Tx ) error {
// - email text,
// + email text NOT NULL,
emailNullable , err := postgresColumnNullability ( tx , "users" , "email" )
if err != nil {
return ErrMigrate . Wrap ( err )
}
if emailNullable {
_ , err := tx . Exec ( `
ALTER TABLE users ALTER COLUMN email SET NOT NULL ;
` )
if err != nil {
return ErrMigrate . Wrap ( err )
}
}
// + status integer NOT NULL,
hasStatus , err := postgresHasColumn ( tx , "users" , "status" )
if err != nil {
return ErrMigrate . Wrap ( err )
}
if ! hasStatus {
_ , err := tx . Exec ( `
ALTER TABLE users ADD COLUMN status INTEGER ;
UPDATE users SET status = ` + strconv.Itoa(int(console.Active)) + ` ;
ALTER TABLE users ALTER COLUMN status SET NOT NULL ;
` )
if err != nil {
return ErrMigrate . Wrap ( err )
}
}
// - UNIQUE ( email )
_ , err = tx . Exec ( `
ALTER TABLE users DROP CONSTRAINT IF EXISTS users_email_key ;
` )
if err != nil {
return ErrMigrate . Wrap ( err )
}
return nil
} ) ,
} ,
2019-03-01 17:46:34 +00:00
{
2019-09-10 20:42:23 +01:00
DB : db . db ,
2019-03-01 17:46:34 +00:00
Description : "Add wallet column" ,
Version : 5 ,
Action : migrate . SQL {
` ALTER TABLE nodes ADD wallet TEXT ;
ALTER TABLE nodes ADD email TEXT ;
UPDATE nodes SET wallet = ' ' ;
UPDATE nodes SET email = ' ' ;
ALTER TABLE nodes ALTER COLUMN wallet SET NOT NULL ;
ALTER TABLE nodes ALTER COLUMN email SET NOT NULL ; ` ,
} ,
} ,
2019-03-06 15:54:48 +00:00
{
2019-09-10 20:42:23 +01:00
DB : db . db ,
2019-03-06 15:54:48 +00:00
Description : "Add bucket usage rollup table" ,
Version : 6 ,
Action : migrate . SQL {
` CREATE TABLE bucket_usages (
id bytea NOT NULL ,
bucket_id bytea NOT NULL ,
rollup_end_time timestamp with time zone NOT NULL ,
remote_stored_data bigint NOT NULL ,
inline_stored_data bigint NOT NULL ,
remote_segments integer NOT NULL ,
inline_segments integer NOT NULL ,
objects integer NOT NULL ,
metadata_size bigint NOT NULL ,
repair_egress bigint NOT NULL ,
get_egress bigint NOT NULL ,
audit_egress bigint NOT NULL ,
PRIMARY KEY ( id ) ,
2019-04-02 19:21:18 +01:00
UNIQUE ( rollup_end_time , bucket_id )
2019-03-06 15:54:48 +00:00
) ` ,
} ,
} ,
2019-03-11 06:09:50 +00:00
{
2019-09-10 20:42:23 +01:00
DB : db . db ,
2019-03-11 06:09:50 +00:00
Description : "Add index on bwagreements" ,
Version : 7 ,
Action : migrate . SQL {
` CREATE INDEX IF NOT EXISTS bwa_created_at ON bwagreements (created_at) ` ,
} ,
} ,
2019-03-19 17:55:43 +00:00
{
2019-09-10 20:42:23 +01:00
DB : db . db ,
2019-03-19 17:55:43 +00:00
Description : "Add registration_tokens table" ,
Version : 8 ,
Action : migrate . SQL {
` CREATE TABLE registration_tokens (
secret bytea NOT NULL ,
owner_id bytea ,
project_limit integer NOT NULL ,
created_at timestamp with time zone NOT NULL ,
PRIMARY KEY ( secret ) ,
UNIQUE ( owner_id )
) ` ,
} ,
} ,
2019-03-22 18:54:22 +00:00
{
2019-09-10 20:42:23 +01:00
DB : db . db ,
2019-03-22 18:54:22 +00:00
Description : "Add new tables for tracking used serials, bandwidth and storage" ,
Version : 9 ,
Action : migrate . SQL {
` CREATE TABLE serial_numbers (
id serial NOT NULL ,
serial_number bytea NOT NULL ,
bucket_id bytea NOT NULL ,
expires_at timestamp NOT NULL ,
2019-03-26 10:34:30 +00:00
PRIMARY KEY ( id )
2019-03-22 18:54:22 +00:00
) ` ,
` CREATE INDEX serial_numbers_expires_at_index ON serial_numbers ( expires_at ) ` ,
2019-03-26 10:34:30 +00:00
` CREATE UNIQUE INDEX serial_number_index ON serial_numbers ( serial_number ) ` ,
2019-03-22 18:54:22 +00:00
` CREATE TABLE used_serials (
serial_number_id integer NOT NULL REFERENCES serial_numbers ( id ) ON DELETE CASCADE ,
storage_node_id bytea NOT NULL ,
2019-03-26 10:34:30 +00:00
PRIMARY KEY ( serial_number_id , storage_node_id )
2019-03-22 18:54:22 +00:00
) ` ,
` CREATE TABLE storagenode_bandwidth_rollups (
storagenode_id bytea NOT NULL ,
interval_start timestamp NOT NULL ,
interval_seconds integer NOT NULL ,
action integer NOT NULL ,
allocated bigint NOT NULL ,
settled bigint NOT NULL ,
2019-03-26 10:34:30 +00:00
PRIMARY KEY ( storagenode_id , interval_start , action )
) ` ,
` CREATE INDEX storagenode_id_interval_start_interval_seconds_index ON storagenode_bandwidth_rollups (
storagenode_id ,
interval_start ,
interval_seconds
2019-03-22 18:54:22 +00:00
) ` ,
` CREATE TABLE storagenode_storage_rollups (
storagenode_id bytea NOT NULL ,
interval_start timestamp NOT NULL ,
interval_seconds integer NOT NULL ,
total bigint NOT NULL ,
2019-03-26 10:34:30 +00:00
PRIMARY KEY ( storagenode_id , interval_start )
2019-03-22 18:54:22 +00:00
) ` ,
` CREATE TABLE bucket_bandwidth_rollups (
bucket_id bytea NOT NULL ,
interval_start timestamp NOT NULL ,
interval_seconds integer NOT NULL ,
action integer NOT NULL ,
inline bigint NOT NULL ,
allocated bigint NOT NULL ,
settled bigint NOT NULL ,
2019-03-26 10:34:30 +00:00
PRIMARY KEY ( bucket_id , interval_start , action )
) ` ,
` CREATE INDEX bucket_id_interval_start_interval_seconds_index ON bucket_bandwidth_rollups (
bucket_id ,
interval_start ,
interval_seconds
2019-03-22 18:54:22 +00:00
) ` ,
` CREATE TABLE bucket_storage_rollups (
bucket_id bytea NOT NULL ,
interval_start timestamp NOT NULL ,
interval_seconds integer NOT NULL ,
inline bigint NOT NULL ,
remote bigint NOT NULL ,
2019-03-26 10:34:30 +00:00
PRIMARY KEY ( bucket_id , interval_start )
2019-03-22 18:54:22 +00:00
) ` ,
2019-03-26 10:34:30 +00:00
` ALTER TABLE bucket_usages DROP CONSTRAINT bucket_usages_rollup_end_time_bucket_id_key ` ,
2019-04-10 07:04:24 +01:00
` CREATE UNIQUE INDEX bucket_id_rollup_end_time_index ON bucket_usages (
2019-03-26 10:34:30 +00:00
bucket_id ,
rollup_end_time ) ` ,
2019-03-22 18:54:22 +00:00
} ,
} ,
2019-03-27 12:33:32 +00:00
{
2019-09-10 20:42:23 +01:00
DB : db . db ,
2019-03-27 12:33:32 +00:00
Description : "users first_name to full_name, last_name to short_name" ,
Version : 10 ,
Action : migrate . SQL {
` ALTER TABLE users RENAME COLUMN first_name TO full_name ;
2019-03-29 08:53:43 +00:00
ALTER TABLE users ALTER COLUMN last_name DROP NOT NULL ;
ALTER TABLE users RENAME COLUMN last_name TO short_name ; ` ,
2019-03-27 12:33:32 +00:00
} ,
} ,
2019-03-28 02:46:49 +00:00
{
2019-09-10 20:42:23 +01:00
DB : db . db ,
2019-03-28 02:46:49 +00:00
Description : "drops interval seconds from storage_rollups, renames x_storage_rollups to x_storage_tallies, adds fields to bucket_storage_tallies" ,
Version : 11 ,
Action : migrate . SQL {
` ALTER TABLE storagenode_storage_rollups RENAME TO storagenode_storage_tallies ` ,
` ALTER TABLE bucket_storage_rollups RENAME TO bucket_storage_tallies ` ,
` ALTER TABLE storagenode_storage_tallies DROP COLUMN interval_seconds ` ,
` ALTER TABLE bucket_storage_tallies DROP COLUMN interval_seconds ` ,
` ALTER TABLE bucket_storage_tallies ADD remote_segments_count integer ;
UPDATE bucket_storage_tallies SET remote_segments_count = 0 ;
ALTER TABLE bucket_storage_tallies ALTER COLUMN remote_segments_count SET NOT NULL ; ` ,
` ALTER TABLE bucket_storage_tallies ADD inline_segments_count integer ;
UPDATE bucket_storage_tallies SET inline_segments_count = 0 ;
ALTER TABLE bucket_storage_tallies ALTER COLUMN inline_segments_count SET NOT NULL ; ` ,
` ALTER TABLE bucket_storage_tallies ADD object_count integer ;
UPDATE bucket_storage_tallies SET object_count = 0 ;
ALTER TABLE bucket_storage_tallies ALTER COLUMN object_count SET NOT NULL ; ` ,
` ALTER TABLE bucket_storage_tallies ADD metadata_size bigint ;
UPDATE bucket_storage_tallies SET metadata_size = 0 ;
ALTER TABLE bucket_storage_tallies ALTER COLUMN metadata_size SET NOT NULL ; ` ,
} ,
} ,
2019-03-29 08:53:43 +00:00
{
2019-09-10 20:42:23 +01:00
DB : db . db ,
2019-03-29 08:53:43 +00:00
Description : "Merge overlay_cache_nodes into nodes table" ,
Version : 12 ,
Action : migrate . SQL {
// Add the new columns to the nodes table
` ALTER TABLE nodes ADD address TEXT NOT NULL DEFAULT ' ' ;
ALTER TABLE nodes ADD protocol INTEGER NOT NULL DEFAULT 0 ;
ALTER TABLE nodes ADD type INTEGER NOT NULL DEFAULT 2 ;
ALTER TABLE nodes ADD free_bandwidth BIGINT NOT NULL DEFAULT - 1 ;
ALTER TABLE nodes ADD free_disk BIGINT NOT NULL DEFAULT - 1 ;
ALTER TABLE nodes ADD latency_90 BIGINT NOT NULL DEFAULT 0 ;
ALTER TABLE nodes ADD last_contact_success TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT ' epoch ' ;
ALTER TABLE nodes ADD last_contact_failure TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT ' epoch ' ; ` ,
// Copy data from overlay_cache_nodes to nodes
` UPDATE nodes
SET address = overlay . address ,
protocol = overlay . protocol ,
type = overlay . node_type ,
free_bandwidth = overlay . free_bandwidth ,
free_disk = overlay . free_disk ,
latency_90 = overlay . latency_90
FROM ( SELECT node_id , node_type , address , protocol , free_bandwidth , free_disk , latency_90
FROM overlay_cache_nodes ) AS overlay
WHERE nodes . id = overlay . node_id ; ` ,
// Delete the overlay cache_nodes table
` DROP TABLE overlay_cache_nodes CASCADE; ` ,
} ,
} ,
2019-04-02 19:21:18 +01:00
{
2019-09-10 20:42:23 +01:00
DB : db . db ,
2019-04-02 19:21:18 +01:00
Description : "Change bucket_id to bucket_name and project_id" ,
Version : 13 ,
Action : migrate . SQL {
// Modify columns: bucket_id --> bucket_name + project_id for table bucket_storage_tallies
` ALTER TABLE bucket_storage_tallies ADD project_id bytea; ` ,
` UPDATE bucket_storage_tallies SET project_id=SUBSTRING(bucket_id FROM 1 FOR 16); ` ,
` ALTER TABLE bucket_storage_tallies ALTER COLUMN project_id SET NOT NULL; ` ,
` ALTER TABLE bucket_storage_tallies RENAME COLUMN bucket_id TO bucket_name; ` ,
` UPDATE bucket_storage_tallies SET bucket_name=SUBSTRING(bucket_name from 18); ` ,
// Update the primary key for bucket_storage_tallies
` ALTER TABLE bucket_storage_tallies DROP CONSTRAINT bucket_storage_rollups_pkey; ` ,
` ALTER TABLE bucket_storage_tallies ADD CONSTRAINT bucket_storage_tallies_pk PRIMARY KEY (bucket_name, project_id, interval_start); ` ,
// Modify columns: bucket_id --> bucket_name + project_id for table bucket_bandwidth_rollups
` ALTER TABLE bucket_bandwidth_rollups ADD project_id bytea; ` ,
` UPDATE bucket_bandwidth_rollups SET project_id=SUBSTRING(bucket_id FROM 1 FOR 16); ` ,
` ALTER TABLE bucket_bandwidth_rollups ALTER COLUMN project_id SET NOT NULL; ` ,
` ALTER TABLE bucket_bandwidth_rollups RENAME COLUMN bucket_id TO bucket_name; ` ,
` UPDATE bucket_bandwidth_rollups SET bucket_name=SUBSTRING(bucket_name from 18); ` ,
// Update index for bucket_bandwidth_rollups
` DROP INDEX IF EXISTS bucket_id_interval_start_interval_seconds_index; ` ,
` CREATE INDEX bucket_name_project_id_interval_start_interval_seconds ON bucket_bandwidth_rollups (
bucket_name ,
project_id ,
interval_start ,
interval_seconds
) ; ` ,
// Update the primary key for bucket_bandwidth_rollups
` ALTER TABLE bucket_bandwidth_rollups DROP CONSTRAINT bucket_bandwidth_rollups_pkey; ` ,
` ALTER TABLE bucket_bandwidth_rollups ADD CONSTRAINT bucket_bandwidth_rollups_pk PRIMARY KEY (bucket_name, project_id, interval_start, action); ` ,
} ,
} ,
2019-04-10 07:04:24 +01:00
{
2019-09-10 20:42:23 +01:00
DB : db . db ,
2019-04-10 07:04:24 +01:00
Description : "Add new Columns to store version information" ,
Version : 14 ,
Action : migrate . SQL {
` ALTER TABLE nodes ADD major bigint NOT NULL DEFAULT 0 ;
ALTER TABLE nodes ADD minor bigint NOT NULL DEFAULT 1 ;
ALTER TABLE nodes ADD patch bigint NOT NULL DEFAULT 0 ;
ALTER TABLE nodes ADD hash TEXT NOT NULL DEFAULT ' ' ;
ALTER TABLE nodes ADD timestamp TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT ' epoch ' ;
ALTER TABLE nodes ADD release bool NOT NULL DEFAULT FALSE ; ` ,
} ,
} ,
2019-04-12 14:30:19 +01:00
{
2019-09-10 20:42:23 +01:00
DB : db . db ,
2019-04-12 14:30:19 +01:00
Description : "Default Node Type should be invalid" ,
Version : 15 ,
Action : migrate . SQL {
` ALTER TABLE nodes ALTER COLUMN type SET DEFAULT 0; ` ,
} ,
} ,
2019-04-16 19:14:09 +01:00
{
2019-09-10 20:42:23 +01:00
DB : db . db ,
2019-04-16 19:14:09 +01:00
Description : "Add path to injuredsegment to prevent duplicates" ,
Version : 16 ,
Action : migrate . Func ( func ( log * zap . Logger , db migrate . DB , tx * sql . Tx ) error {
_ , err := tx . Exec ( `
ALTER TABLE injuredsegments ADD path text ;
ALTER TABLE injuredsegments RENAME COLUMN info TO data ;
ALTER TABLE injuredsegments ADD attempted timestamp ;
ALTER TABLE injuredsegments DROP CONSTRAINT IF EXISTS id_pkey ; ` )
if err != nil {
return ErrMigrate . Wrap ( err )
}
// add 'path' using a cursor
err = func ( ) error {
_ , err = tx . Exec ( ` DECLARE injured_cursor CURSOR FOR SELECT data FROM injuredsegments FOR UPDATE ` )
if err != nil {
return ErrMigrate . Wrap ( err )
}
defer func ( ) {
_ , closeErr := tx . Exec ( ` CLOSE injured_cursor ` )
err = errs . Combine ( err , closeErr )
} ( )
for {
var seg pb . InjuredSegment
err := tx . QueryRow ( ` FETCH NEXT FROM injured_cursor ` ) . Scan ( & seg )
if err != nil {
if err == sql . ErrNoRows {
break
}
return ErrMigrate . Wrap ( err )
}
_ , err = tx . Exec ( ` UPDATE injuredsegments SET path = $1 WHERE CURRENT OF injured_cursor ` , seg . Path )
if err != nil {
return ErrMigrate . Wrap ( err )
}
}
return nil
} ( )
if err != nil {
return err
}
// keep changing
_ , err = tx . Exec ( `
2019-04-22 19:55:48 +01:00
DELETE FROM injuredsegments a USING injuredsegments b WHERE a . id < b . id AND a . path = b . path ;
2019-04-16 19:14:09 +01:00
ALTER TABLE injuredsegments DROP COLUMN id ;
ALTER TABLE injuredsegments ALTER COLUMN path SET NOT NULL ;
ALTER TABLE injuredsegments ADD PRIMARY KEY ( path ) ; ` )
if err != nil {
return ErrMigrate . Wrap ( err )
}
return nil
} ) ,
} ,
2019-05-07 15:23:08 +01:00
{
2019-09-10 20:42:23 +01:00
DB : db . db ,
2019-05-07 15:23:08 +01:00
Description : "Fix audit and uptime ratios for new nodes" ,
Version : 17 ,
Action : migrate . SQL { `
UPDATE nodes SET audit_success_ratio = 1 WHERE total_audit_count = 0 ;
UPDATE nodes SET uptime_ratio = 1 WHERE total_uptime_count = 0 ; ` ,
} ,
} ,
2019-05-10 20:05:42 +01:00
{
2019-09-10 20:42:23 +01:00
DB : db . db ,
2019-05-10 20:05:42 +01:00
Description : "Drops storagenode_storage_tally table, Renames accounting_raws to storagenode_storage_tally, and Drops data_type and created_at columns" ,
Version : 18 ,
Action : migrate . SQL {
` DROP TABLE storagenode_storage_tallies CASCADE ` ,
` ALTER TABLE accounting_raws RENAME TO storagenode_storage_tallies ` ,
` ALTER TABLE storagenode_storage_tallies DROP COLUMN data_type ` ,
` ALTER TABLE storagenode_storage_tallies DROP COLUMN created_at ` ,
} ,
} ,
2019-05-13 16:53:52 +01:00
{
2019-09-10 20:42:23 +01:00
DB : db . db ,
2019-05-13 16:53:52 +01:00
Description : "Added new table to store reset password tokens" ,
Version : 19 ,
Action : migrate . SQL { `
CREATE TABLE reset_password_tokens (
secret bytea NOT NULL ,
owner_id bytea NOT NULL ,
created_at timestamp with time zone NOT NULL ,
PRIMARY KEY ( secret ) ,
UNIQUE ( owner_id )
) ; ` ,
} ,
} ,
2019-05-16 15:11:15 +01:00
{
2019-09-10 20:42:23 +01:00
DB : db . db ,
2019-05-16 15:11:15 +01:00
Description : "Adds pending_audits table, adds 'contained' column to nodes table" ,
Version : 20 ,
Action : migrate . SQL {
` ALTER TABLE nodes ADD contained boolean ;
UPDATE nodes SET contained = false ;
ALTER TABLE nodes ALTER COLUMN contained SET NOT NULL ; ` ,
` CREATE TABLE pending_audits (
node_id bytea NOT NULL ,
piece_id bytea NOT NULL ,
stripe_index bigint NOT NULL ,
share_size bigint NOT NULL ,
expected_share_hash bytea NOT NULL ,
reverify_count bigint NOT NULL ,
PRIMARY KEY ( node_id )
) ; ` ,
} ,
} ,
2019-05-22 21:06:27 +01:00
{
2019-09-10 20:42:23 +01:00
DB : db . db ,
2019-05-22 21:06:27 +01:00
Description : "Add last_ip column and index" ,
Version : 21 ,
Action : migrate . SQL {
` ALTER TABLE nodes ADD last_ip TEXT ;
UPDATE nodes SET last_ip = ' ' ;
ALTER TABLE nodes ALTER COLUMN last_ip SET NOT NULL ;
CREATE INDEX IF NOT EXISTS node_last_ip ON nodes ( last_ip ) ` ,
} ,
} ,
2019-05-22 22:41:55 +01:00
{
2019-09-10 20:42:23 +01:00
DB : db . db ,
2019-05-22 22:41:55 +01:00
Description : "Create new tables for free credits program" ,
Version : 22 ,
Action : migrate . SQL { `
CREATE TABLE offers (
id serial NOT NULL ,
name text NOT NULL ,
description text NOT NULL ,
type integer NOT NULL ,
credit_in_cents integer NOT NULL ,
award_credit_duration_days integer NOT NULL ,
invitee_credit_duration_days integer NOT NULL ,
redeemable_cap integer NOT NULL ,
num_redeemed integer NOT NULL ,
expires_at timestamp with time zone ,
created_at timestamp with time zone NOT NULL ,
status integer NOT NULL ,
PRIMARY KEY ( id )
) ; ` ,
} ,
} ,
2019-05-24 17:51:27 +01:00
{
2019-09-10 20:42:23 +01:00
DB : db . db ,
2019-05-24 17:51:27 +01:00
Description : "Drops and recreates api key table to handle macaroons and adds revocation table" ,
Version : 23 ,
Action : migrate . SQL {
` DROP TABLE api_keys CASCADE ` ,
` CREATE TABLE api_keys (
id bytea NOT NULL ,
project_id bytea NOT NULL REFERENCES projects ( id ) ON DELETE CASCADE ,
head bytea NOT NULL ,
name text NOT NULL ,
secret bytea NOT NULL ,
created_at timestamp with time zone NOT NULL ,
PRIMARY KEY ( id ) ,
UNIQUE ( head ) ,
UNIQUE ( name , project_id )
) ; ` ,
} ,
} ,
2019-05-28 16:36:52 +01:00
{
2019-09-10 20:42:23 +01:00
DB : db . db ,
2019-05-28 16:36:52 +01:00
Description : "Add usage_limit column to projects table" ,
Version : 24 ,
Action : migrate . SQL {
` ALTER TABLE projects ADD usage_limit bigint NOT NULL DEFAULT 0; ` ,
} ,
} ,
2019-05-30 22:38:23 +01:00
{
2019-09-10 20:42:23 +01:00
DB : db . db ,
2019-05-30 22:38:23 +01:00
Description : "Add disqualified column to nodes table" ,
Version : 25 ,
Action : migrate . SQL {
` ALTER TABLE nodes ADD disqualified boolean NOT NULL DEFAULT false; ` ,
} ,
} ,
2019-06-04 20:17:01 +01:00
{
2019-09-10 20:42:23 +01:00
DB : db . db ,
2019-06-04 20:17:01 +01:00
Description : "Add invitee_credit_in_gb and award_credit_in_gb columns, delete type and credit_in_cents columns" ,
Version : 26 ,
Action : migrate . SQL {
` ALTER TABLE offers DROP COLUMN credit_in_cents; ` ,
` ALTER TABLE offers ADD COLUMN award_credit_in_cents integer NOT NULL DEFAULT 0; ` ,
` ALTER TABLE offers ADD COLUMN invitee_credit_in_cents integer NOT NULL DEFAULT 0; ` ,
` ALTER TABLE offers ALTER COLUMN expires_at SET NOT NULL; ` ,
} ,
} ,
2019-06-05 17:06:14 +01:00
{
2019-09-10 20:42:23 +01:00
DB : db . db ,
2019-06-05 17:06:14 +01:00
Description : "Create value attribution table" ,
Version : 27 ,
Action : migrate . SQL {
` CREATE TABLE value_attributions (
bucket_id bytea NOT NULL ,
partner_id bytea NOT NULL ,
last_updated timestamp NOT NULL ,
PRIMARY KEY ( bucket_id )
) ` ,
} ,
} ,
2019-06-06 14:57:58 +01:00
{
2019-09-10 20:42:23 +01:00
DB : db . db ,
2019-06-06 14:57:58 +01:00
Description : "Remove agreements table" ,
Version : 28 ,
Action : migrate . SQL {
` DROP TABLE bwagreements ` ,
} ,
} ,
2019-06-06 17:07:14 +01:00
{
2019-09-10 20:42:23 +01:00
DB : db . db ,
2019-06-06 17:07:14 +01:00
Description : "Add userpaymentinfos, projectpaymentinfos, projectinvoicestamps" ,
Version : 29 ,
Action : migrate . SQL {
` CREATE TABLE user_payments (
user_id bytea NOT NULL REFERENCES users ( id ) ON DELETE CASCADE ,
customer_id bytea NOT NULL ,
created_at timestamp with time zone NOT NULL ,
PRIMARY KEY ( user_id ) ,
UNIQUE ( customer_id )
) ; ` ,
` CREATE TABLE project_payments (
project_id bytea NOT NULL REFERENCES projects ( id ) ON DELETE CASCADE ,
payer_id bytea NOT NULL REFERENCES user_payments ( user_id ) ON DELETE CASCADE ,
payment_method_id bytea NOT NULL ,
created_at timestamp with time zone NOT NULL ,
PRIMARY KEY ( project_id )
) ; ` ,
` CREATE TABLE project_invoice_stamps (
project_id bytea NOT NULL REFERENCES projects ( id ) ON DELETE CASCADE ,
invoice_id bytea NOT NULL ,
start_date timestamp with time zone NOT NULL ,
end_date timestamp with time zone NOT NULL ,
created_at timestamp with time zone NOT NULL ,
PRIMARY KEY ( project_id , start_date , end_date ) ,
UNIQUE ( invoice_id )
) ; ` ,
} ,
} ,
2019-06-13 13:28:55 +01:00
{
2019-09-10 20:42:23 +01:00
DB : db . db ,
2019-06-13 13:28:55 +01:00
Description : "Alter value attribution table. Remove bucket_id. Add project_id and bucket_name as primary key" ,
Version : 30 ,
Action : migrate . SQL {
` ALTER TABLE value_attributions DROP CONSTRAINT value_attributions_pkey; ` ,
` ALTER TABLE value_attributions ADD project_id bytea; ` ,
` UPDATE value_attributions SET project_id=SUBSTRING(bucket_id FROM 1 FOR 16); ` ,
` ALTER TABLE value_attributions ALTER COLUMN project_id SET NOT NULL; ` ,
` ALTER TABLE value_attributions RENAME COLUMN bucket_id TO bucket_name; ` ,
` UPDATE value_attributions SET bucket_name=SUBSTRING(bucket_name from 18); ` ,
` ALTER TABLE value_attributions ADD PRIMARY KEY (project_id, bucket_name); ` ,
} ,
} ,
2019-06-13 14:52:33 +01:00
{
2019-09-10 20:42:23 +01:00
DB : db . db ,
2019-06-13 14:52:33 +01:00
Description : "Add user_credit table" ,
Version : 31 ,
Action : migrate . SQL {
` CREATE TABLE user_credits (
id serial NOT NULL ,
user_id bytea NOT NULL REFERENCES users ( id ) ,
offer_id integer NOT NULL REFERENCES offers ( id ) ,
referred_by bytea REFERENCES users ( id ) ,
credits_earned_in_cents integer NOT NULL ,
credits_used_in_cents integer NOT NULL ,
expires_at timestamp with time zone NOT NULL ,
created_at timestamp with time zone NOT NULL ,
PRIMARY KEY ( id )
) ; ` ,
} ,
} ,
2019-06-18 10:14:31 +01:00
{
2019-09-10 20:42:23 +01:00
DB : db . db ,
2019-06-18 10:14:31 +01:00
Description : "Change type of disqualified column of nodes table to timestamp" ,
Version : 32 ,
Action : migrate . SQL {
` ALTER TABLE nodes
ALTER COLUMN disqualified DROP DEFAULT ,
ALTER COLUMN disqualified DROP NOT NULL ,
ALTER COLUMN disqualified TYPE timestamp with time zone USING
CASE disqualified
WHEN true THEN TIMESTAMP WITH TIME ZONE ' 2019 - 06 - 15 00 : 00 : 00 + 00 '
ELSE NULL
END ` ,
} ,
} ,
2019-06-18 14:45:02 +01:00
{
2019-09-10 20:42:23 +01:00
DB : db . db ,
2019-06-18 14:45:02 +01:00
Description : "Add alpha and beta columns for reputations" ,
Version : 33 ,
Action : migrate . SQL {
` ALTER TABLE nodes ADD COLUMN audit_reputation_alpha double precision NOT NULL DEFAULT 1; ` ,
` ALTER TABLE nodes ADD COLUMN audit_reputation_beta double precision NOT NULL DEFAULT 0; ` ,
` ALTER TABLE nodes ADD COLUMN uptime_reputation_alpha double precision NOT NULL DEFAULT 1; ` ,
` ALTER TABLE nodes ADD COLUMN uptime_reputation_beta double precision NOT NULL DEFAULT 0; ` ,
} ,
} ,
2019-06-21 18:14:53 +01:00
{
2019-09-10 20:42:23 +01:00
DB : db . db ,
2019-06-21 18:14:53 +01:00
Description : "Remove ratio columns from node reputations" ,
Version : 34 ,
Action : migrate . SQL {
` ALTER TABLE nodes DROP COLUMN audit_success_ratio; ` ,
` ALTER TABLE nodes DROP COLUMN uptime_ratio; ` ,
} ,
} ,
2019-06-23 02:18:54 +01:00
{
2019-09-10 20:42:23 +01:00
DB : db . db ,
2019-06-23 02:18:54 +01:00
Description : "Fix reputations to preserve a baseline" ,
Version : 35 ,
Action : migrate . SQL {
` UPDATE nodes SET audit_reputation_alpha = GREATEST(audit_success_count, 50); ` ,
` UPDATE nodes SET audit_reputation_beta = total_audit_count - audit_success_count; ` ,
` UPDATE nodes SET uptime_reputation_alpha = GREATEST(uptime_success_count, 100); ` ,
` UPDATE nodes SET uptime_reputation_beta = total_uptime_count - uptime_success_count; ` ,
} ,
} ,
2019-06-24 16:33:18 +01:00
{
2019-09-10 20:42:23 +01:00
DB : db . db ,
2019-06-24 16:33:18 +01:00
Description : "Update Last_IP column to be masked" ,
Version : 36 ,
Action : migrate . SQL {
` UPDATE nodes SET last_ip = host(network(set_masklen(last_ip::INET, 24))) WHERE last_ip <> '' AND family(last_ip::INET) = 4; ` ,
` UPDATE nodes SET last_ip = host(network(set_masklen(last_ip::INET, 64))) WHERE last_ip <> '' AND family(last_ip::INET) = 16; ` ,
` ALTER TABLE nodes RENAME last_ip TO last_net; ` ,
} ,
} ,
2019-06-25 20:21:34 +01:00
{
2019-09-10 20:42:23 +01:00
DB : db . db ,
2019-06-25 20:21:34 +01:00
Description : "Update project_id column from 36 byte string based UUID to 16 byte UUID" ,
Version : 37 ,
Action : migrate . SQL {
2019-07-04 20:25:34 +01:00
`
update bucket_bandwidth_rollups as a
set allocated = a . allocated + b . allocated ,
settled = a . settled + b . settled
from bucket_bandwidth_rollups as b
where a . interval_start = b . interval_start
and a . bucket_name = b . bucket_name
and a . action = b . action
2019-07-23 18:58:43 +01:00
and a . project_id = decode ( replace ( encode ( b . project_id , ' escape ' ) , '-' , ' ' ) , ' hex ' )
2019-07-04 20:25:34 +01:00
and length ( b . project_id ) = 36
and length ( a . project_id ) = 16
; ` ,
`
delete from bucket_bandwidth_rollups as b
using bucket_bandwidth_rollups as a
where a . interval_start = b . interval_start
and a . bucket_name = b . bucket_name
and a . action = b . action
2019-07-23 18:58:43 +01:00
and a . project_id = decode ( replace ( encode ( b . project_id , ' escape ' ) , '-' , ' ' ) , ' hex ' )
2019-07-04 20:25:34 +01:00
and length ( b . project_id ) = 36
and length ( a . project_id ) = 16
; ` ,
2019-06-25 20:21:34 +01:00
` UPDATE bucket_storage_tallies SET project_id = decode(replace(encode(project_id, 'escape'), '-', ''), 'hex') WHERE length(project_id) = 36; ` ,
` UPDATE bucket_bandwidth_rollups SET project_id = decode(replace(encode(project_id, 'escape'), '-', ''), 'hex') WHERE length(project_id) = 36; ` ,
} ,
} ,
2019-07-01 21:45:21 +01:00
{
2019-09-10 20:42:23 +01:00
DB : db . db ,
2019-07-01 21:45:21 +01:00
Description : "Add bucket metadata table" ,
Version : 38 ,
Action : migrate . SQL {
2019-07-03 23:03:56 +01:00
` CREATE TABLE bucket_metainfos (
2019-07-01 21:45:21 +01:00
id bytea NOT NULL ,
project_id bytea NOT NULL REFERENCES projects ( id ) ,
name bytea NOT NULL ,
path_cipher integer NOT NULL ,
2019-07-03 23:03:56 +01:00
created_at timestamp with time zone NOT NULL ,
2019-07-01 21:45:21 +01:00
default_segment_size integer NOT NULL ,
default_encryption_cipher_suite integer NOT NULL ,
default_encryption_block_size integer NOT NULL ,
default_redundancy_algorithm integer NOT NULL ,
default_redundancy_share_size integer NOT NULL ,
default_redundancy_required_shares integer NOT NULL ,
default_redundancy_repair_shares integer NOT NULL ,
default_redundancy_optimal_shares integer NOT NULL ,
default_redundancy_total_shares integer NOT NULL ,
PRIMARY KEY ( id ) ,
UNIQUE ( name , project_id )
) ; ` ,
} ,
} ,
2019-07-02 09:39:36 +01:00
{
2019-09-10 20:42:23 +01:00
DB : db . db ,
2019-07-02 09:39:36 +01:00
Description : "Remove disqualification flag for failing uptime checks" ,
Version : 39 ,
Action : migrate . SQL {
` UPDATE nodes SET disqualified=NULL WHERE disqualified IS NOT NULL AND audit_reputation_alpha / (audit_reputation_alpha + audit_reputation_beta) >= 0.6; ` ,
} ,
} ,
2019-07-10 21:29:26 +01:00
{
2019-09-10 20:42:23 +01:00
DB : db . db ,
2019-07-10 21:29:26 +01:00
Description : "Add unique id for project payments. Add is_default property" ,
Version : 40 ,
Action : migrate . SQL {
` DROP TABLE project_payments CASCADE ` ,
` CREATE TABLE project_payments (
id bytea NOT NULL ,
project_id bytea NOT NULL REFERENCES projects ( id ) ON DELETE CASCADE ,
payer_id bytea NOT NULL REFERENCES user_payments ( user_id ) ON DELETE CASCADE ,
payment_method_id bytea NOT NULL ,
is_default boolean NOT NULL ,
created_at timestamp with time zone NOT NULL ,
PRIMARY KEY ( id )
) ; ` ,
} ,
} ,
2019-07-11 18:26:07 +01:00
{
2019-09-10 20:42:23 +01:00
DB : db . db ,
2019-07-11 18:26:07 +01:00
Description : "Move InjuredSegment path from string to bytes" ,
Version : 41 ,
Action : migrate . SQL {
` ALTER TABLE injuredsegments RENAME COLUMN path TO path_old; ` ,
` ALTER TABLE injuredsegments ADD COLUMN path bytea; ` ,
` UPDATE injuredsegments SET path = decode(path_old, 'escape'); ` ,
` ALTER TABLE injuredsegments ALTER COLUMN path SET NOT NULL; ` ,
` ALTER TABLE injuredsegments DROP COLUMN path_old; ` ,
` ALTER TABLE injuredsegments ADD CONSTRAINT injuredsegments_pk PRIMARY KEY (path); ` ,
} ,
} ,
2019-07-12 14:19:18 +01:00
{
2019-09-10 20:42:23 +01:00
DB : db . db ,
2019-07-12 14:19:18 +01:00
Description : "Remove num_redeemed column in offers table" ,
Version : 42 ,
Action : migrate . SQL {
` ALTER TABLE offers DROP num_redeemed; ` ,
} ,
} ,
2019-07-12 15:19:38 +01:00
{
2019-09-10 20:42:23 +01:00
DB : db . db ,
2019-07-12 15:19:38 +01:00
Description : "Set default offer for each offer type in offers table" ,
Version : 43 ,
Action : migrate . SQL {
` ALTER TABLE offers
ALTER COLUMN redeemable_cap DROP NOT NULL ,
ALTER COLUMN invitee_credit_duration_days DROP NOT NULL ,
ALTER COLUMN award_credit_duration_days DROP NOT NULL
` ,
` INSERT INTO offers (
name ,
description ,
award_credit_in_cents ,
invitee_credit_in_cents ,
expires_at ,
created_at ,
status ,
type )
VALUES (
' Default referral offer ' ,
' Is active when no other active referral offer ' ,
300 ,
600 ,
' 2119 - 03 - 14 0 8 : 28 : 24.636949 + 00 ' ,
' 2019 - 07 - 14 0 8 : 28 : 24.636949 + 00 ' ,
1 ,
2
) ,
(
' Default free credit offer ' ,
' Is active when no active free credit offer ' ,
300 ,
0 ,
' 2119 - 03 - 14 0 8 : 28 : 24.636949 + 00 ' ,
' 2019 - 07 - 14 0 8 : 28 : 24.636949 + 00 ' ,
1 ,
1
) ON CONFLICT DO NOTHING ; ` ,
} ,
} ,
2019-07-12 18:35:20 +01:00
{
2019-09-10 20:42:23 +01:00
DB : db . db ,
2019-07-12 18:35:20 +01:00
Description : "Add index on InjuredSegments attempted column" ,
Version : 44 ,
Action : migrate . SQL {
` CREATE INDEX injuredsegments_attempted_index ON injuredsegments ( attempted ); ` ,
} ,
} ,
2019-07-12 18:59:19 +01:00
{
2019-09-10 20:42:23 +01:00
DB : db . db ,
2019-07-12 18:59:19 +01:00
Description : "Add partner id field to support OSPP" ,
Version : 45 ,
Action : migrate . SQL {
` ALTER TABLE projects ADD COLUMN partner_id BYTEA ` ,
` ALTER TABLE users ADD COLUMN partner_id BYTEA ` ,
` ALTER TABLE api_keys ADD COLUMN partner_id BYTEA ` ,
` ALTER TABLE bucket_metainfos ADD COLUMN partner_id BYTEA ` ,
} ,
} ,
2019-07-18 19:08:15 +01:00
{
2019-09-10 20:42:23 +01:00
DB : db . db ,
2019-07-18 19:08:15 +01:00
Description : "Add pending audit path" ,
Version : 46 ,
Action : migrate . SQL {
` DELETE FROM pending_audits; ` , // clearing pending_audits is the least-bad choice to deal with the added 'path' column
` ALTER TABLE pending_audits ADD COLUMN path bytea NOT NULL; ` ,
` UPDATE nodes SET contained = false; ` ,
} ,
} ,
2019-07-19 19:22:10 +01:00
{
2019-09-10 20:42:23 +01:00
DB : db . db ,
2019-07-19 19:22:10 +01:00
Description : "Modify default offers configuration" ,
Version : 47 ,
Action : migrate . SQL {
` UPDATE offers SET
award_credit_duration_days = 365 ,
invitee_credit_duration_days = 14
WHERE type = 2 AND status = 1 AND id = 1 ` ,
` UPDATE offers SET
invitee_credit_duration_days = 14 ,
award_credit_duration_days = NULL ,
award_credit_in_cents = 0 ,
invitee_credit_in_cents = 300
WHERE type = 1 AND status = 1 AND id = 2 ; ` ,
} ,
} ,
2019-07-30 14:21:00 +01:00
{
// This partial unique index enforces uniqueness among (id, offer_id) pairs for users that have signed up
// but are not yet activated (credits_earned_in_cents=0).
// Among users that are activated, uniqueness of (id, offer_id) pairs is not required or desirable.
2019-09-10 20:42:23 +01:00
DB : db . db ,
2019-07-30 14:21:00 +01:00
Description : "Create partial index for user_credits table" ,
Version : 48 ,
Action : migrate . SQL {
` CREATE UNIQUE INDEX credits_earned_user_id_offer_id ON user_credits ( id , offer_id )
WHERE credits_earned_in_cents = 0 ; ` ,
} ,
} ,
2019-08-01 18:46:33 +01:00
{
2019-09-10 20:42:23 +01:00
DB : db . db ,
2019-08-01 18:46:33 +01:00
Description : "Add cascade to user_id for deleting an account" ,
Version : 49 ,
Action : migrate . SQL {
` ALTER TABLE user_credits DROP CONSTRAINT user_credits_referred_by_fkey ;
ALTER TABLE user_credits ADD CONSTRAINT user_credits_referred_by_fkey
FOREIGN KEY ( referred_by ) REFERENCES users ( id ) ON DELETE SET NULL ;
ALTER TABLE user_credits DROP CONSTRAINT user_credits_user_id_fkey ;
ALTER TABLE user_credits ADD CONSTRAINT user_credits_user_id_fkey
FOREIGN KEY ( user_id ) REFERENCES users ( id ) ON DELETE CASCADE ;
ALTER TABLE user_credits ADD COLUMN type text ;
UPDATE user_credits SET type = ' invalid ' ;
ALTER TABLE user_credits ALTER COLUMN type SET NOT NULL ; ` ,
} ,
} ,
2019-08-02 18:47:35 +01:00
{
2019-09-10 20:42:23 +01:00
DB : db . db ,
2019-08-02 18:47:35 +01:00
Description : "Changing the primary key constraint" ,
Version : 50 ,
Action : migrate . SQL {
` ALTER TABLE certRecords DROP CONSTRAINT certrecords_pkey ;
ALTER TABLE certRecords ADD CONSTRAINT certrecords_pkey PRIMARY KEY ( publickey ) ;
CREATE INDEX certrecord_id_update_at ON certRecords ( id , update_at ) ; ` ,
} ,
} ,
2019-08-07 13:28:13 +01:00
{
// Creating owner_id column for project.
// Removing projects without project members
// And populating this column with first project member id
2019-09-10 20:42:23 +01:00
DB : db . db ,
2019-08-07 13:28:13 +01:00
Description : "Creating owner_id column for projects table" ,
Version : 51 ,
Action : migrate . SQL {
` ALTER TABLE projects
ADD COLUMN owner_id BYTEA ; ` ,
` UPDATE projects as proj
SET owner_id = (
SELECT member_id
FROM project_members
WHERE project_id = proj . id
ORDER BY created_at ASC
LIMIT 1
) ; ` ,
` DELETE FROM bucket_metainfos
WHERE project_id in (
SELECT id
FROM projects
WHERE owner_id is null
) ; ` ,
` DELETE FROM projects
WHERE owner_id is null ; ` ,
` ALTER TABLE projects
ALTER COLUMN owner_id SET NOT NULL ; ` ,
} ,
} ,
2019-08-12 15:41:34 +01:00
{
2019-09-10 20:42:23 +01:00
DB : db . db ,
2019-08-12 15:41:34 +01:00
Description : "Remove certRecords table" ,
Version : 52 ,
Action : migrate . SQL {
` DROP TABLE certRecords CASCADE ` ,
} ,
} ,
2019-08-19 11:58:13 +01:00
{
2019-09-10 20:42:23 +01:00
DB : db . db ,
2019-08-19 11:58:13 +01:00
Description : "Add piece_count column to nodes table" ,
Version : 53 ,
Action : migrate . SQL {
` ALTER TABLE nodes ADD piece_count BIGINT NOT NULL DEFAULT 0; ` ,
} ,
} ,
2019-08-26 17:49:42 +01:00
{
2019-09-10 20:42:23 +01:00
DB : db . db ,
2019-08-26 17:49:42 +01:00
Description : "Add Peer Identities table" ,
Version : 54 ,
Action : migrate . SQL {
` CREATE TABLE peer_identities (
node_id bytea NOT NULL ,
leaf_serial_number bytea NOT NULL ,
chain bytea NOT NULL ,
updated_at timestamp with time zone NOT NULL ,
PRIMARY KEY ( node_id )
) ; ` ,
} ,
} ,
2019-09-10 15:00:33 +01:00
{
2019-09-10 20:42:23 +01:00
DB : db . db ,
2019-09-10 15:00:33 +01:00
Description : "Added normalized_email column to users table" ,
Version : 55 ,
Action : migrate . SQL {
` ALTER TABLE users ADD normalized_email TEXT; ` ,
` UPDATE users SET normalized_email=UPPER(email); ` ,
` ALTER TABLE users ALTER COLUMN normalized_email SET NOT NULL; ` ,
} ,
} ,
2019-09-13 17:57:32 +01:00
{
DB : db . db ,
Description : "Add Graceful Exit tables and update nodes table" ,
Version : 56 ,
Action : migrate . SQL {
` ALTER TABLE nodes ADD COLUMN exit_loop_completed_at timestamp with time zone; ` ,
` ALTER TABLE nodes ADD COLUMN exit_initiated_at timestamp with time zone; ` ,
` ALTER TABLE nodes ADD COLUMN exit_finished_at timestamp with time zone; ` ,
` CREATE TABLE graceful_exit_progress (
node_id bytea NOT NULL ,
bytes_transferred bigint NOT NULL ,
updated_at timestamp with time zone NOT NULL ,
PRIMARY KEY ( node_id )
) ; ` ,
` CREATE TABLE graceful_exit_transfer_queue (
node_id bytea NOT NULL ,
path bytea NOT NULL ,
piece_num integer NOT NULL ,
durability_ratio double precision NOT NULL ,
queued_at timestamp with time zone NOT NULL ,
requested_at timestamp with time zone ,
last_failed_at timestamp with time zone ,
last_failed_code integer ,
failed_count integer ,
finished_at timestamp with time zone ,
PRIMARY KEY ( node_id , path )
) ; ` ,
} ,
} ,
2019-09-19 19:37:31 +01:00
{
DB : db . db ,
Description : "Add defaults to nodes table" ,
Version : 57 ,
Action : migrate . SQL {
` ALTER TABLE nodes ALTER COLUMN contained SET DEFAULT false; ` ,
` ALTER TABLE nodes ALTER COLUMN piece_count SET DEFAULT 0; ` ,
` ALTER TABLE nodes ALTER COLUMN major SET DEFAULT 0; ` ,
` ALTER TABLE nodes ALTER COLUMN minor SET DEFAULT 0; ` ,
` ALTER TABLE nodes ALTER COLUMN audit_success_count SET DEFAULT 0; ` ,
` ALTER TABLE nodes ALTER COLUMN total_audit_count SET DEFAULT 0; ` ,
` ALTER TABLE nodes ALTER COLUMN patch SET DEFAULT 0; ` ,
` ALTER TABLE nodes ALTER COLUMN hash SET DEFAULT ''; ` ,
` ALTER TABLE nodes ALTER COLUMN release SET DEFAULT false; ` ,
` ALTER TABLE nodes ALTER COLUMN latency_90 SET DEFAULT 0; ` ,
` ALTER TABLE nodes ALTER COLUMN timestamp SET DEFAULT '0001-01-01 00:00:00+00'; ` ,
` ALTER TABLE nodes ALTER COLUMN created_at SET DEFAULT current_timestamp; ` ,
` ALTER TABLE nodes ALTER COLUMN updated_at SET DEFAULT current_timestamp; ` ,
} ,
} ,
2019-09-25 18:12:44 +01:00
{
DB : db . db ,
Description : "Remove timezone from Graceful Exit dates" ,
Version : 58 ,
Action : migrate . SQL {
` UPDATE nodes set exit_initiated_at = TIMEZONE ( ' UTC ' , exit_initiated_at ) , exit_loop_completed_at = TIMEZONE ( ' UTC ' , exit_loop_completed_at ) ,
exit_finished_at = TIMEZONE ( ' UTC ' , exit_finished_at ) ; ` ,
` ALTER TABLE nodes ALTER COLUMN exit_initiated_at TYPE timestamp; ` ,
` ALTER TABLE nodes ALTER COLUMN exit_loop_completed_at TYPE timestamp; ` ,
` ALTER TABLE nodes ALTER COLUMN exit_finished_at TYPE timestamp; ` ,
` UPDATE graceful_exit_progress set updated_at = TIMEZONE('UTC', updated_at); ` ,
` ALTER TABLE graceful_exit_progress ADD COLUMN pieces_transferred bigint NOT NULL DEFAULT 0; ` ,
` ALTER TABLE graceful_exit_progress ADD COLUMN pieces_failed bigint NOT NULL DEFAULT 0; ` ,
` ALTER TABLE graceful_exit_progress ALTER COLUMN updated_at TYPE timestamp; ` ,
` UPDATE graceful_exit_transfer_queue set queued_at = TIMEZONE ( ' UTC ' , queued_at ) , requested_at = TIMEZONE ( ' UTC ' , requested_at ) ,
last_failed_at = TIMEZONE ( ' UTC ' , last_failed_at ) , finished_at = TIMEZONE ( ' UTC ' , finished_at ) ; ` ,
` ALTER TABLE graceful_exit_transfer_queue ALTER COLUMN queued_at TYPE timestamp; ` ,
` ALTER TABLE graceful_exit_transfer_queue ALTER COLUMN requested_at TYPE timestamp; ` ,
` ALTER TABLE graceful_exit_transfer_queue ALTER COLUMN last_failed_at TYPE timestamp; ` ,
` ALTER TABLE graceful_exit_transfer_queue ALTER COLUMN finished_at TYPE timestamp; ` ,
} ,
} ,
2019-10-10 18:12:23 +01:00
{
DB : db . db ,
Description : "Add table for storing stripe customers" ,
Version : 59 ,
Action : migrate . SQL {
` DROP TABLE project_payments CASCADE ` ,
` DROP TABLE user_payments CASCADE ` ,
` CREATE TABLE stripe_customers (
user_id bytea NOT NULL ,
customer_id text NOT NULL ,
created_at timestamp with time zone NOT NULL ,
PRIMARY KEY ( user_id ) ,
UNIQUE ( customer_id )
) ; ` ,
} ,
} ,
2019-10-17 15:04:50 +01:00
{
DB : db . db ,
Description : "Add coinpayments_transactions table" ,
Version : 60 ,
Action : migrate . SQL {
` CREATE TABLE coinpayments_transactions (
id text NOT NULL ,
user_id bytea NOT NULL ,
address text NOT NULL ,
amount bytea NOT NULL ,
received bytea NOT NULL ,
status integer NOT NULL ,
key text NOT NULL ,
created_at timestamp with time zone NOT NULL ,
PRIMARY KEY ( id )
) ; ` ,
} ,
} ,
2019-10-17 16:01:39 +01:00
{
DB : db . db ,
Description : "Add graceful exit success column to nodes table" ,
Version : 61 ,
Action : migrate . SQL {
` ALTER TABLE nodes ADD COLUMN exit_success boolean NOT NULL DEFAULT FALSE ` ,
} ,
} ,
2019-10-28 15:08:33 +00:00
{
DB : db . db ,
Description : "Alter graceful_exit_transfer_queue to have the piece_num as part of the primary key since it is possible for a node to have 2 pieces for a given segment." ,
Version : 62 ,
Action : migrate . SQL {
` ALTER TABLE graceful_exit_transfer_queue DROP CONSTRAINT graceful_exit_transfer_queue_pkey; ` ,
` ALTER TABLE graceful_exit_transfer_queue ADD PRIMARY KEY ( node_id, path, piece_num ); ` ,
} ,
} ,
2019-10-29 16:04:34 +00:00
{
DB : db . db ,
Description : "Add payments update balance intents" ,
Version : 63 ,
Action : migrate . SQL {
` CREATE TABLE stripecoinpayments_apply_balance_intents (
tx_id text NOT NULL REFERENCES coinpayments_transactions ( id ) ON DELETE CASCADE ,
state integer NOT NULL ,
created_at timestamp with time zone NOT NULL ,
PRIMARY KEY ( tx_id )
) ; ` ,
} ,
} ,
2019-11-04 14:37:39 +00:00
{
DB : db . db ,
Description : "Removing unused bucket_usages table" ,
Version : 64 ,
Action : migrate . SQL {
` DROP TABLE bucket_usages CASCADE; ` ,
} ,
} ,
2019-11-05 13:16:02 +00:00
{
DB : db . db ,
Description : "Add stripecoinpayments_invoice_project_records" ,
Version : 65 ,
Action : migrate . SQL {
` CREATE TABLE stripecoinpayments_invoice_project_records (
id bytea NOT NULL ,
project_id bytea NOT NULL ,
storage double precision NOT NULL ,
egress bigint NOT NULL ,
objects bigint NOT NULL ,
period_start timestamp with time zone NOT NULL ,
period_end timestamp with time zone NOT NULL ,
state integer NOT NULL ,
created_at timestamp with time zone NOT NULL ,
PRIMARY KEY ( id ) ,
UNIQUE ( project_id , period_start , period_end )
) ; ` ,
} ,
} ,
2019-11-07 16:13:05 +00:00
{
DB : db . db ,
Description : "Alter graceful_exit_transfer_queue to add root_piece_id." ,
Version : 66 ,
Action : migrate . SQL {
` ALTER TABLE graceful_exit_transfer_queue ADD COLUMN root_piece_id bytea; ` ,
} ,
} ,
2019-02-14 21:55:21 +00:00
} ,
}
}
func postgresHasColumn ( tx * sql . Tx , table , column string ) ( bool , error ) {
var columnName string
err := tx . QueryRow ( `
2019-04-10 07:04:24 +01:00
SELECT column_name FROM information_schema . COLUMNS
2019-02-14 21:55:21 +00:00
WHERE table_schema = CURRENT_SCHEMA
AND table_name = $ 1
AND column_name = $ 2
` , table , column ) . Scan ( & columnName )
if err == sql . ErrNoRows {
return false , nil
}
if err != nil {
return false , ErrMigrate . Wrap ( err )
}
return columnName == column , nil
}
func postgresColumnNullability ( tx * sql . Tx , table , column string ) ( bool , error ) {
var nullability string
err := tx . QueryRow ( `
2019-04-10 07:04:24 +01:00
SELECT is_nullable FROM information_schema . COLUMNS
2019-02-14 21:55:21 +00:00
WHERE table_schema = CURRENT_SCHEMA
AND table_name = $ 1
AND column_name = $ 2
` , table , column ) . Scan ( & nullability )
if err != nil {
return false , ErrMigrate . Wrap ( err )
}
return nullability == "YES" , nil
}