Skip to content

Commit

Permalink
[PSL-1186] add ticket store db
Browse files Browse the repository at this point in the history
  • Loading branch information
j-rafique committed Jun 10, 2024
1 parent e8c331e commit fc0d47b
Show file tree
Hide file tree
Showing 6 changed files with 365 additions and 0 deletions.
53 changes: 53 additions & 0 deletions common/storage/ticketstore/activation_attempts.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package ticketstore

import (
"github.com/pastelnetwork/gonode/common/types"
)

type ActivationAttemptsQueries interface {
UpsertActivationAttempt(attempt types.ActivationAttempt) error
GetActivationAttemptByID(id string) (*types.ActivationAttempt, error)
}

// UpsertActivationAttempt upsert a new activation attempt into the activation_attempts table
func (s *TicketStore) UpsertActivationAttempt(attempt types.ActivationAttempt) error {
const upsertQuery = `
INSERT INTO activation_attempts (
id, file_id, activation_attempt_at, is_successful, error_message
) VALUES (?, ?, ?, ?, ?)
ON CONFLICT(id)
DO UPDATE SET
file_id = excluded.file_id,
activation_attempt_at = excluded.activation_attempt_at,
is_successful = excluded.is_successful,
error_message = excluded.error_message;`

_, err := s.db.Exec(upsertQuery,
attempt.ID, attempt.FileID, attempt.ActivationAttemptAt,
attempt.IsSuccessful, attempt.ErrorMessage)
if err != nil {
return err
}

return nil
}

// GetActivationAttemptByID retrieves an activation attempt by its ID from the activation_attempts table
func (s *TicketStore) GetActivationAttemptByID(id string) (*types.ActivationAttempt, error) {
const selectQuery = `
SELECT id, file_id, activation_attempt_at, is_successful, error_message
FROM activation_attempts
WHERE id = ?;`

row := s.db.QueryRow(selectQuery, id)

var attempt types.ActivationAttempt
err := row.Scan(
&attempt.ID, &attempt.FileID, &attempt.ActivationAttemptAt,
&attempt.IsSuccessful, &attempt.ErrorMessage)
if err != nil {
return nil, err
}

return &attempt, nil
}
86 changes: 86 additions & 0 deletions common/storage/ticketstore/files.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package ticketstore

import (
"github.com/pastelnetwork/gonode/common/types"
)

type FilesQueries interface {
UpsertFile(file types.File) error
GetFileByID(fileID string) (*types.File, error)
}

// UpsertFile inserts a new file into the files table
func (s *TicketStore) UpsertFile(file types.File) error {
const upsertQuery = `
INSERT INTO files (
file_id, upload_timestamp, path, index, base_file_id, task_id,
reg_txid, activation_txid, req_burn_txn_amount, burn_txn_id,
req_amount, is_concluded, cascade_metadata_ticket_id, uuid_key,
hash_of_original_big_file, name_of_original_big_file_with_ext,
size_of_original_big_file, data_type_of_original_big_file,
start_block, done_block
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
ON CONFLICT(file_id)
DO UPDATE SET
upload_timestamp = excluded.upload_timestamp,
path = excluded.path,
index = excluded.index,
base_file_id = excluded.base_file_id,
task_id = excluded.task_id,
reg_txid = excluded.reg_txid,
activation_txid = excluded.activation_txid,
req_burn_txn_amount = excluded.req_burn_txn_amount,
burn_txn_id = excluded.burn_txn_id,
req_amount = excluded.req_amount,
is_concluded = excluded.is_concluded,
cascade_metadata_ticket_id = excluded.cascade_metadata_ticket_id,
uuid_key = excluded.uuid_key,
hash_of_original_big_file = excluded.hash_of_original_big_file,
name_of_original_big_file_with_ext = excluded.name_of_original_big_file_with_ext,
size_of_original_big_file = excluded.size_of_original_big_file,
data_type_of_original_big_file = excluded.data_type_of_original_big_file,
start_block = excluded.start_block,
done_block = excluded.done_block;`

_, err := s.db.Exec(upsertQuery,
file.FileID, file.UploadTimestamp, file.Path, file.Index, file.BaseFileID, file.TaskID,
file.RegTxid, file.ActivationTxid, file.ReqBurnTxnAmount, file.BurnTxnID,
file.ReqAmount, file.IsConcluded, file.CascadeMetadataTicketID, file.UUIDKey,
file.HashOfOriginalBigFile, file.NameOfOriginalBigFileWithExt,
file.SizeOfOriginalBigFile, file.DataTypeOfOriginalBigFile,
file.StartBlock, file.DoneBlock)
if err != nil {
return err
}

return nil
}

// GetFileByID retrieves a file by its ID from the files table
func (s *TicketStore) GetFileByID(fileID string) (*types.File, error) {
const selectQuery = `
SELECT file_id, upload_timestamp, path, index, base_file_id, task_id,
reg_txid, activation_txid, req_burn_txn_amount, burn_txn_id,
req_amount, is_concluded, cascade_metadata_ticket_id, uuid_key,
hash_of_original_big_file, name_of_original_big_file_with_ext,
size_of_original_big_file, data_type_of_original_big_file,
start_block, done_block
FROM files
WHERE file_id = ?;`

row := s.db.QueryRow(selectQuery, fileID)

var file types.File
err := row.Scan(
&file.FileID, &file.UploadTimestamp, &file.Path, &file.Index, &file.BaseFileID, &file.TaskID,
&file.RegTxid, &file.ActivationTxid, &file.ReqBurnTxnAmount, &file.BurnTxnID,
&file.ReqAmount, &file.IsConcluded, &file.CascadeMetadataTicketID, &file.UUIDKey,
&file.HashOfOriginalBigFile, &file.NameOfOriginalBigFileWithExt,
&file.SizeOfOriginalBigFile, &file.DataTypeOfOriginalBigFile,
&file.StartBlock, &file.DoneBlock)
if err != nil {
return nil, err
}

return &file, nil
}
10 changes: 10 additions & 0 deletions common/storage/ticketstore/local.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package ticketstore

import (
"context"
)

// TicketStorageInterface is interface for queries ticket sqlite store
type TicketStorageInterface interface {
CloseTicketDB(ctx context.Context)
}
56 changes: 56 additions & 0 deletions common/storage/ticketstore/registration_attempts.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package ticketstore

import (
"github.com/pastelnetwork/gonode/common/types"
)

type RegistrationAttemptsQueries interface {
UpsertRegistrationAttempt(attempt types.RegistrationAttempt) error
GetRegistrationAttemptByID(id int) (*types.RegistrationAttempt, error)
}

// UpsertRegistrationAttempt upsert a new registration attempt into the registration_attempts table
func (s *TicketStore) UpsertRegistrationAttempt(attempt types.RegistrationAttempt) error {
const upsertQuery = `
INSERT INTO registration_attempts (
id, file_id, reg_started_at, processor_sns, finished_at, is_successful, error_message
) VALUES (?, ?, ?, ?, ?, ?, ?)
ON CONFLICT(id)
DO UPDATE SET
file_id = excluded.file_id,
reg_started_at = excluded.reg_started_at,
processor_sns = excluded.processor_sns,
finished_at = excluded.finished_at,
is_successful = excluded.is_successful,
error_message = excluded.error_message;`

_, err := s.db.Exec(upsertQuery,
attempt.ID, attempt.FileID, attempt.RegStartedAt, attempt.ProcessorSNS,
attempt.FinishedAt, attempt.IsSuccessful, attempt.ErrorMessage)
if err != nil {
return err
}

return nil
}

// GetRegistrationAttemptByID retrieves a registration attempt by its ID from the registration_attempts table
func (s *TicketStore) GetRegistrationAttemptByID(id int) (*types.RegistrationAttempt, error) {
const selectQuery = `
SELECT id, file_id, reg_started_at, processor_sns, finished_at,
is_successful, error_message
FROM registration_attempts
WHERE id = ?;`

row := s.db.QueryRow(selectQuery, id)

var attempt types.RegistrationAttempt
err := row.Scan(
&attempt.ID, &attempt.FileID, &attempt.RegStartedAt, &attempt.ProcessorSNS,
&attempt.FinishedAt, &attempt.IsSuccessful, &attempt.ErrorMessage)
if err != nil {
return nil, err
}

return &attempt, nil
}
114 changes: 114 additions & 0 deletions common/storage/ticketstore/store.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
package ticketstore

import (
"context"
"fmt"
"github.com/jmoiron/sqlx"
"github.com/pastelnetwork/gonode/common/configurer"
"github.com/pastelnetwork/gonode/common/log"
"path/filepath"
)

const createFilesTable string = `
CREATE TABLE IF NOT EXISTS files (
file_id TEXT NOT NULL PRIMARY KEY,
upload_timestamp DATETIME,
path TEXT,
index TEXT,
base_file_id TEXT,
task_id TEXT,
reg_txid TEXT,
activation_txid TEXT,
req_burn_txn_amount TEXT,
burn_txn_id TEXT,
req_amount TEXT,
is_concluded BOOLEAN,
cascade_metadata_ticket_id TEXT,
uuid_key TEXT,
hash_of_original_big_file TEXT,
name_of_original_big_file_with_ext TEXT,
size_of_original_big_file TEXT,
data_type_of_original_big_file TEXT,
start_block INTEGER,
done_block INTEGER,
FOREIGN KEY (base_file_id) REFERENCES files(file_id)
);
`

const createRegistrationAttemptsTable string = `
CREATE TABLE IF NOT EXISTS registration_attempts (
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
file_id TEXT NOT NULL,
reg_started_at DATETIME,
processor_sns TEXT,
finished_at DATETIME,
is_successful BOOLEAN,
error_message TEXT,
FOREIGN KEY (file_id) REFERENCES files(file_id)
);
`

const createActivationAttemptsTable string = `
CREATE TABLE IF NOT EXISTS activation_attempts (
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
file_id TEXT NOT NULL,
activation_attempt_at DATETIME,
is_successful BOOLEAN,
error_message TEXT,
FOREIGN KEY (file_id) REFERENCES files(file_id)
);
`

const (
ticketDBName = "ticket.db"
)

// TicketStore handles sqlite ops for tickets
type TicketStore struct {
db *sqlx.DB
}

// CloseTicketDB closes ticket database
func (s *TicketStore) CloseTicketDB(ctx context.Context) {
if err := s.db.Close(); err != nil {
log.WithContext(ctx).WithError(err).Error("error closing ticket db")
}
}

// OpenTicketingDb opens ticket DB
func OpenTicketingDb() (TicketStorageInterface, error) {
dbFile := filepath.Join(configurer.DefaultPath(), ticketDBName)
db, err := sqlx.Connect("sqlite3", dbFile)
if err != nil {
return nil, fmt.Errorf("cannot open sqlite database: %w", err)
}

if _, err := db.Exec(createFilesTable); err != nil {
return nil, fmt.Errorf("cannot create table(s): %w", err)
}

if _, err := db.Exec(createRegistrationAttemptsTable); err != nil {
return nil, fmt.Errorf("cannot create table(s): %w", err)
}

if _, err := db.Exec(createActivationAttemptsTable); err != nil {
return nil, fmt.Errorf("cannot create table(s): %w", err)
}

pragmas := []string{
"PRAGMA synchronous=NORMAL;",
"PRAGMA cache_size=-262144;",
"PRAGMA busy_timeout=120000;",
"PRAGMA journal_mode=WAL;",
}

for _, pragma := range pragmas {
if _, err := db.Exec(pragma); err != nil {
return nil, fmt.Errorf("cannot set sqlite database parameter: %w", err)
}
}

return &TicketStore{
db: db,
}, nil
}
46 changes: 46 additions & 0 deletions common/types/ticket.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package types

import (
"time"
)

type File struct {
FileID string
UploadTimestamp time.Time
Path string
Index string
BaseFileID string
TaskID string
RegTxid string
ActivationTxid string
ReqBurnTxnAmount string
BurnTxnID string
ReqAmount string
IsConcluded bool
CascadeMetadataTicketID string
UUIDKey string
HashOfOriginalBigFile string
NameOfOriginalBigFileWithExt string
SizeOfOriginalBigFile string
DataTypeOfOriginalBigFile string
StartBlock int
DoneBlock int
}

type RegistrationAttempt struct {
ID int
FileID string
RegStartedAt time.Time
ProcessorSNS string
FinishedAt time.Time
IsSuccessful bool
ErrorMessage string
}

type ActivationAttempt struct {
ID string
FileID string
ActivationAttemptAt time.Time
IsSuccessful bool
ErrorMessage string
}

0 comments on commit fc0d47b

Please sign in to comment.