Application superstructure (or supersingleton, if you want).
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
Got rid of context thing which misleads due to existance of stdlib's context package. Also fixed golangci-lint configuration. Fixes #20.
This commit is contained in:
@@ -46,7 +46,7 @@ type Database struct {
|
||||
// a subject of change in future.
|
||||
func (db *Database) cleanup() {
|
||||
for {
|
||||
ctx.Logger.Info().Msg("Starting pastes cleanup procedure...")
|
||||
app.Log.Info().Msg("Starting pastes cleanup procedure...")
|
||||
|
||||
pages := db.db.GetPastesPages()
|
||||
|
||||
@@ -55,7 +55,7 @@ func (db *Database) cleanup() {
|
||||
for i := 0; i < pages; i++ {
|
||||
pastes, err := db.db.GetPagedPastes(i)
|
||||
if err != nil {
|
||||
ctx.Logger.Error().Err(err).Int("page", i).Msg("Failed to perform database cleanup")
|
||||
app.Log.Error().Err(err).Int("page", i).Msg("Failed to perform database cleanup")
|
||||
}
|
||||
|
||||
for _, paste := range pastes {
|
||||
@@ -68,11 +68,11 @@ func (db *Database) cleanup() {
|
||||
for _, pasteID := range pasteIDsToRemove {
|
||||
err := db.DeletePaste(pasteID)
|
||||
if err != nil {
|
||||
ctx.Logger.Error().Err(err).Int("paste", pasteID).Msg("Failed to delete paste!")
|
||||
app.Log.Error().Err(err).Int("paste", pasteID).Msg("Failed to delete paste!")
|
||||
}
|
||||
}
|
||||
|
||||
ctx.Logger.Info().Msg("Pastes cleanup done.")
|
||||
app.Log.Info().Msg("Pastes cleanup done.")
|
||||
|
||||
time.Sleep(time.Hour)
|
||||
}
|
||||
@@ -107,16 +107,16 @@ func (db *Database) GetPastesPages() int {
|
||||
|
||||
// Initialize initializes connection to database.
|
||||
func (db *Database) Initialize() {
|
||||
ctx.Logger.Info().Msg("Initializing database connection...")
|
||||
app.Log.Info().Msg("Initializing database connection...")
|
||||
|
||||
if ctx.Config.Database.Type == "mysql" {
|
||||
mysql.New(ctx)
|
||||
} else if ctx.Config.Database.Type == flatfiles.FlatFileDialect {
|
||||
flatfiles.New(ctx)
|
||||
} else if ctx.Config.Database.Type == "postgresql" {
|
||||
postgresql.New(ctx)
|
||||
if app.Config.Database.Type == "mysql" {
|
||||
mysql.New(app)
|
||||
} else if app.Config.Database.Type == flatfiles.FlatFileDialect {
|
||||
flatfiles.New(app)
|
||||
} else if app.Config.Database.Type == "postgresql" {
|
||||
postgresql.New(app)
|
||||
} else {
|
||||
ctx.Logger.Fatal().Str("type", ctx.Config.Database.Type).Msg("Unknown database type")
|
||||
app.Log.Fatal().Str("type", app.Config.Database.Type).Msg("Unknown database type")
|
||||
}
|
||||
|
||||
go db.cleanup()
|
||||
|
@@ -25,21 +25,21 @@
|
||||
package flatfiles
|
||||
|
||||
import (
|
||||
"go.dev.pztrn.name/fastpastebin/internal/context"
|
||||
"go.dev.pztrn.name/fastpastebin/internal/application"
|
||||
dialectinterface "go.dev.pztrn.name/fastpastebin/internal/database/dialects/interface"
|
||||
)
|
||||
|
||||
const FlatFileDialect = "flatfiles"
|
||||
|
||||
var (
|
||||
ctx *context.Context
|
||||
app *application.Application
|
||||
flf *FlatFiles
|
||||
)
|
||||
|
||||
func New(cc *context.Context) {
|
||||
ctx = cc
|
||||
func New(cc *application.Application) {
|
||||
app = cc
|
||||
//nolint:exhaustruct
|
||||
flf = &FlatFiles{}
|
||||
|
||||
ctx.Database.RegisterDialect(dialectinterface.Interface(Handler{}))
|
||||
app.Database.RegisterDialect(dialectinterface.Interface(Handler{}))
|
||||
}
|
||||
|
@@ -48,7 +48,7 @@ func (ff *FlatFiles) DeletePaste(pasteID int) error {
|
||||
// Delete from disk.
|
||||
err := os.Remove(filepath.Join(ff.path, "pastes", strconv.Itoa(pasteID)+".json"))
|
||||
if err != nil {
|
||||
ctx.Logger.Error().Err(err).Msg("Failed to delete paste!")
|
||||
app.Log.Error().Err(err).Msg("Failed to delete paste!")
|
||||
|
||||
//nolint:wrapcheck
|
||||
return err
|
||||
@@ -82,17 +82,17 @@ func (ff *FlatFiles) GetDatabaseConnection() *sql.DB {
|
||||
func (ff *FlatFiles) GetPaste(pasteID int) (*structs.Paste, error) {
|
||||
ff.writeMutex.Lock()
|
||||
pastePath := filepath.Join(ff.path, "pastes", strconv.Itoa(pasteID)+".json")
|
||||
ctx.Logger.Debug().Str("path", pastePath).Msg("Trying to load paste data")
|
||||
app.Log.Debug().Str("path", pastePath).Msg("Trying to load paste data")
|
||||
|
||||
pasteInBytes, err := os.ReadFile(pastePath)
|
||||
if err != nil {
|
||||
ctx.Logger.Debug().Err(err).Msg("Failed to read paste from storage")
|
||||
app.Log.Debug().Err(err).Msg("Failed to read paste from storage")
|
||||
|
||||
//nolint:wrapcheck
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ctx.Logger.Debug().Int("paste bytes", len(pasteInBytes)).Msg("Loaded paste")
|
||||
app.Log.Debug().Int("paste bytes", len(pasteInBytes)).Msg("Loaded paste")
|
||||
ff.writeMutex.Unlock()
|
||||
|
||||
//nolint:exhaustruct
|
||||
@@ -100,7 +100,7 @@ func (ff *FlatFiles) GetPaste(pasteID int) (*structs.Paste, error) {
|
||||
|
||||
err1 := json.Unmarshal(pasteInBytes, paste)
|
||||
if err1 != nil {
|
||||
ctx.Logger.Error().Err(err1).Msgf("Failed to parse paste")
|
||||
app.Log.Error().Err(err1).Msgf("Failed to parse paste")
|
||||
|
||||
//nolint:wrapcheck
|
||||
return nil, err1
|
||||
@@ -113,7 +113,7 @@ func (ff *FlatFiles) GetPagedPastes(page int) ([]structs.Paste, error) {
|
||||
// Pagination.
|
||||
startPagination := 0
|
||||
if page > 1 {
|
||||
startPagination = (page - 1) * ctx.Config.Pastes.Pagination
|
||||
startPagination = (page - 1) * app.Config.Pastes.Pagination
|
||||
}
|
||||
|
||||
// Iteration one - get only public pastes.
|
||||
@@ -129,23 +129,23 @@ func (ff *FlatFiles) GetPagedPastes(page int) ([]structs.Paste, error) {
|
||||
pastesData := make([]structs.Paste, 0)
|
||||
|
||||
for idx, paste := range publicPastes {
|
||||
if len(pastesData) == ctx.Config.Pastes.Pagination {
|
||||
if len(pastesData) == app.Config.Pastes.Pagination {
|
||||
break
|
||||
}
|
||||
|
||||
if idx < startPagination {
|
||||
ctx.Logger.Debug().Int("paste index", idx).Msg("Paste isn't in pagination query: too low index")
|
||||
app.Log.Debug().Int("paste index", idx).Msg("Paste isn't in pagination query: too low index")
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
if (idx-1 >= startPagination && page > 1 && idx > startPagination+((page-1)*ctx.Config.Pastes.Pagination)) || (idx-1 >= startPagination && page == 1 && idx > startPagination+(page*ctx.Config.Pastes.Pagination)) {
|
||||
ctx.Logger.Debug().Int("paste index", idx).Msg("Paste isn't in pagination query: too high index")
|
||||
if (idx-1 >= startPagination && page > 1 && idx > startPagination+((page-1)*app.Config.Pastes.Pagination)) || (idx-1 >= startPagination && page == 1 && idx > startPagination+(page*app.Config.Pastes.Pagination)) {
|
||||
app.Log.Debug().Int("paste index", idx).Msg("Paste isn't in pagination query: too high index")
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
ctx.Logger.Debug().Int("ID", paste.ID).Int("index", idx).Msg("Getting paste data")
|
||||
app.Log.Debug().Int("ID", paste.ID).Int("index", idx).Msg("Getting paste data")
|
||||
|
||||
// Get paste data.
|
||||
//nolint:exhaustruct
|
||||
@@ -153,14 +153,14 @@ func (ff *FlatFiles) GetPagedPastes(page int) ([]structs.Paste, error) {
|
||||
|
||||
pasteRawData, err := os.ReadFile(filepath.Join(ff.path, "pastes", strconv.Itoa(paste.ID)+".json"))
|
||||
if err != nil {
|
||||
ctx.Logger.Error().Err(err).Msg("Failed to read paste data")
|
||||
app.Log.Error().Err(err).Msg("Failed to read paste data")
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
err1 := json.Unmarshal(pasteRawData, pasteData)
|
||||
if err1 != nil {
|
||||
ctx.Logger.Error().Err(err1).Msg("Failed to parse paste data")
|
||||
app.Log.Error().Err(err1).Msg("Failed to parse paste data")
|
||||
|
||||
continue
|
||||
}
|
||||
@@ -184,9 +184,9 @@ func (ff *FlatFiles) GetPastesPages() int {
|
||||
ff.writeMutex.Unlock()
|
||||
|
||||
// Calculate pages.
|
||||
pages := len(publicPastes) / ctx.Config.Pastes.Pagination
|
||||
pages := len(publicPastes) / app.Config.Pastes.Pagination
|
||||
// Check if we have any remainder. Add 1 to pages count if so.
|
||||
if len(publicPastes)%ctx.Config.Pastes.Pagination > 0 {
|
||||
if len(publicPastes)%app.Config.Pastes.Pagination > 0 {
|
||||
pages++
|
||||
}
|
||||
|
||||
@@ -194,14 +194,14 @@ func (ff *FlatFiles) GetPastesPages() int {
|
||||
}
|
||||
|
||||
func (ff *FlatFiles) Initialize() {
|
||||
ctx.Logger.Info().Msg("Initializing flatfiles storage...")
|
||||
app.Log.Info().Msg("Initializing flatfiles storage...")
|
||||
|
||||
path := ctx.Config.Database.Path
|
||||
path := app.Config.Database.Path
|
||||
// Get proper paste file path.
|
||||
if strings.Contains(ctx.Config.Database.Path, "~") {
|
||||
if strings.Contains(app.Config.Database.Path, "~") {
|
||||
curUser, err := user.Current()
|
||||
if err != nil {
|
||||
ctx.Logger.Error().Msg("Failed to get current user. Will replace '~' for '/' in storage path!")
|
||||
app.Log.Error().Msg("Failed to get current user. Will replace '~' for '/' in storage path!")
|
||||
|
||||
path = strings.Replace(path, "~", "/", -1)
|
||||
}
|
||||
@@ -212,40 +212,40 @@ func (ff *FlatFiles) Initialize() {
|
||||
path, _ = filepath.Abs(path)
|
||||
ff.path = path
|
||||
|
||||
ctx.Logger.Debug().Msgf("Storage path is now: %s", ff.path)
|
||||
app.Log.Debug().Msgf("Storage path is now: %s", ff.path)
|
||||
|
||||
// Create directory if necessary.
|
||||
if _, err := os.Stat(ff.path); err != nil {
|
||||
ctx.Logger.Debug().Str("directory", ff.path).Msg("Directory does not exist, creating...")
|
||||
app.Log.Debug().Str("directory", ff.path).Msg("Directory does not exist, creating...")
|
||||
_ = os.MkdirAll(ff.path, os.ModePerm)
|
||||
} else {
|
||||
ctx.Logger.Debug().Str("directory", ff.path).Msg("Directory already exists")
|
||||
app.Log.Debug().Str("directory", ff.path).Msg("Directory already exists")
|
||||
}
|
||||
|
||||
// Create directory for pastes.
|
||||
if _, err := os.Stat(filepath.Join(ff.path, "pastes")); err != nil {
|
||||
ctx.Logger.Debug().Str("directory", ff.path).Msg("Directory does not exist, creating...")
|
||||
app.Log.Debug().Str("directory", ff.path).Msg("Directory does not exist, creating...")
|
||||
_ = os.MkdirAll(filepath.Join(ff.path, "pastes"), os.ModePerm)
|
||||
} else {
|
||||
ctx.Logger.Debug().Str("directory", ff.path).Msg("Directory already exists")
|
||||
app.Log.Debug().Str("directory", ff.path).Msg("Directory already exists")
|
||||
}
|
||||
|
||||
// Load pastes index.
|
||||
ff.pastesIndex = []Index{}
|
||||
if _, err := os.Stat(filepath.Join(ff.path, "pastes", "index.json")); err != nil {
|
||||
ctx.Logger.Warn().Msg("Pastes index file does not exist, will create new one")
|
||||
app.Log.Warn().Msg("Pastes index file does not exist, will create new one")
|
||||
} else {
|
||||
indexData, err := os.ReadFile(filepath.Join(ff.path, "pastes", "index.json"))
|
||||
if err != nil {
|
||||
ctx.Logger.Fatal().Msg("Failed to read contents of index file!")
|
||||
app.Log.Fatal().Msg("Failed to read contents of index file!")
|
||||
}
|
||||
|
||||
err1 := json.Unmarshal(indexData, &ff.pastesIndex)
|
||||
if err1 != nil {
|
||||
ctx.Logger.Error().Err(err1).Msg("Failed to parse index file contents from JSON into internal structure. Will create new index file. All of your previous pastes will became unavailable.")
|
||||
app.Log.Error().Err(err1).Msg("Failed to parse index file contents from JSON into internal structure. Will create new index file. All of your previous pastes will became unavailable.")
|
||||
}
|
||||
|
||||
ctx.Logger.Debug().Int("pastes count", len(ff.pastesIndex)).Msg("Parsed pastes index")
|
||||
app.Log.Debug().Int("pastes count", len(ff.pastesIndex)).Msg("Parsed pastes index")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -256,7 +256,7 @@ func (ff *FlatFiles) SavePaste(paste *structs.Paste) (int64, error) {
|
||||
pasteID := len(filesOnDisk) + 1
|
||||
paste.ID = pasteID
|
||||
|
||||
ctx.Logger.Debug().Int("new paste ID", pasteID).Msg("Writing paste to disk")
|
||||
app.Log.Debug().Int("new paste ID", pasteID).Msg("Writing paste to disk")
|
||||
|
||||
data, err := json.Marshal(paste)
|
||||
if err != nil {
|
||||
@@ -286,18 +286,18 @@ func (ff *FlatFiles) SavePaste(paste *structs.Paste) (int64, error) {
|
||||
}
|
||||
|
||||
func (ff *FlatFiles) Shutdown() {
|
||||
ctx.Logger.Info().Msg("Saving indexes...")
|
||||
app.Log.Info().Msg("Saving indexes...")
|
||||
|
||||
indexData, err := json.Marshal(ff.pastesIndex)
|
||||
if err != nil {
|
||||
ctx.Logger.Error().Err(err).Msg("Failed to encode index data into JSON")
|
||||
app.Log.Error().Err(err).Msg("Failed to encode index data into JSON")
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
err1 := os.WriteFile(filepath.Join(ff.path, "pastes", "index.json"), indexData, 0o600)
|
||||
if err1 != nil {
|
||||
ctx.Logger.Error().Err(err1).Msg("Failed to write index data to file. Pretty sure that you've lost your pastes.")
|
||||
app.Log.Error().Err(err1).Msg("Failed to write index data to file. Pretty sure that you've lost your pastes.")
|
||||
|
||||
return
|
||||
}
|
||||
|
@@ -25,19 +25,19 @@
|
||||
package mysql
|
||||
|
||||
import (
|
||||
"go.dev.pztrn.name/fastpastebin/internal/context"
|
||||
"go.dev.pztrn.name/fastpastebin/internal/application"
|
||||
dialectinterface "go.dev.pztrn.name/fastpastebin/internal/database/dialects/interface"
|
||||
)
|
||||
|
||||
var (
|
||||
ctx *context.Context
|
||||
app *application.Application
|
||||
dbAdapter *Database
|
||||
)
|
||||
|
||||
func New(cc *context.Context) {
|
||||
ctx = cc
|
||||
func New(cc *application.Application) {
|
||||
app = cc
|
||||
//nolint:exhaustruct
|
||||
dbAdapter = &Database{}
|
||||
|
||||
ctx.Database.RegisterDialect(dialectinterface.Interface(Handler{}))
|
||||
app.Database.RegisterDialect(dialectinterface.Interface(Handler{}))
|
||||
}
|
||||
|
@@ -26,19 +26,19 @@ package migrations
|
||||
|
||||
import (
|
||||
"github.com/pressly/goose"
|
||||
"go.dev.pztrn.name/fastpastebin/internal/context"
|
||||
"go.dev.pztrn.name/fastpastebin/internal/application"
|
||||
)
|
||||
|
||||
var ctx *context.Context
|
||||
var app *application.Application
|
||||
|
||||
// New initializes migrations.
|
||||
func New(cc *context.Context) {
|
||||
ctx = cc
|
||||
func New(cc *application.Application) {
|
||||
app = cc
|
||||
}
|
||||
|
||||
// Migrate launching migrations.
|
||||
func Migrate() {
|
||||
ctx.Logger.Info().Msg("Migrating database...")
|
||||
app.Log.Info().Msg("Migrating database...")
|
||||
|
||||
_ = goose.SetDialect("mysql")
|
||||
goose.AddNamedMigration("1_initial.go", InitialUp, nil)
|
||||
@@ -47,13 +47,13 @@ func Migrate() {
|
||||
goose.AddNamedMigration("4_passworded_pastes.go", PasswordedPastesUp, PasswordedPastesDown)
|
||||
// Add new migrations BEFORE this message.
|
||||
|
||||
dbConn := ctx.Database.GetDatabaseConnection()
|
||||
dbConn := app.Database.GetDatabaseConnection()
|
||||
if dbConn != nil {
|
||||
err := goose.Up(dbConn, ".")
|
||||
if err != nil {
|
||||
ctx.Logger.Panic().Msgf("Failed to migrate database to latest version: %s", err.Error())
|
||||
app.Log.Panic().Msgf("Failed to migrate database to latest version: %s", err.Error())
|
||||
}
|
||||
} else {
|
||||
ctx.Logger.Warn().Msg("Current database dialect isn't supporting migrations, skipping")
|
||||
app.Log.Warn().Msg("Current database dialect isn't supporting migrations, skipping")
|
||||
}
|
||||
}
|
||||
|
@@ -103,10 +103,10 @@ func (db *Database) GetPagedPastes(page int) ([]structs.Paste, error) {
|
||||
// Pagination.
|
||||
startPagination := 0
|
||||
if page > 1 {
|
||||
startPagination = (page - 1) * ctx.Config.Pastes.Pagination
|
||||
startPagination = (page - 1) * app.Config.Pastes.Pagination
|
||||
}
|
||||
|
||||
err := db.db.Select(&pastesRaw, db.db.Rebind("SELECT * FROM `pastes` WHERE private != true ORDER BY id DESC LIMIT ? OFFSET ?"), ctx.Config.Pastes.Pagination, startPagination)
|
||||
err := db.db.Select(&pastesRaw, db.db.Rebind("SELECT * FROM `pastes` WHERE private != true ORDER BY id DESC LIMIT ? OFFSET ?"), app.Config.Pastes.Pagination, startPagination)
|
||||
if err != nil {
|
||||
//nolint:wrapcheck
|
||||
return nil, err
|
||||
@@ -142,9 +142,9 @@ func (db *Database) GetPastesPages() int {
|
||||
}
|
||||
|
||||
// Calculate pages.
|
||||
pages := len(pastes) / ctx.Config.Pastes.Pagination
|
||||
pages := len(pastes) / app.Config.Pastes.Pagination
|
||||
// Check if we have any remainder. Add 1 to pages count if so.
|
||||
if len(pastes)%ctx.Config.Pastes.Pagination > 0 {
|
||||
if len(pastes)%app.Config.Pastes.Pagination > 0 {
|
||||
pages++
|
||||
}
|
||||
|
||||
@@ -153,23 +153,23 @@ func (db *Database) GetPastesPages() int {
|
||||
|
||||
// Initialize initializes MySQL/MariaDB connection.
|
||||
func (db *Database) Initialize() {
|
||||
ctx.Logger.Info().Msg("Initializing database connection...")
|
||||
app.Log.Info().Msg("Initializing database connection...")
|
||||
|
||||
// There might be only user, without password. MySQL/MariaDB driver
|
||||
// in DSN wants "user" or "user:password", "user:" is invalid.
|
||||
var userpass string
|
||||
if ctx.Config.Database.Password == "" {
|
||||
userpass = ctx.Config.Database.Username
|
||||
if app.Config.Database.Password == "" {
|
||||
userpass = app.Config.Database.Username
|
||||
} else {
|
||||
userpass = ctx.Config.Database.Username + ":" + ctx.Config.Database.Password
|
||||
userpass = app.Config.Database.Username + ":" + app.Config.Database.Password
|
||||
}
|
||||
|
||||
dbConnString := fmt.Sprintf("%s@tcp(%s:%s)/%s?parseTime=true&collation=utf8mb4_unicode_ci&charset=utf8mb4", userpass, ctx.Config.Database.Address, ctx.Config.Database.Port, ctx.Config.Database.Database)
|
||||
ctx.Logger.Debug().Str("DSN", dbConnString).Msgf("Database connection string composed")
|
||||
dbConnString := fmt.Sprintf("%s@tcp(%s:%s)/%s?parseTime=true&collation=utf8mb4_unicode_ci&charset=utf8mb4", userpass, app.Config.Database.Address, app.Config.Database.Port, app.Config.Database.Database)
|
||||
app.Log.Debug().Str("DSN", dbConnString).Msgf("Database connection string composed")
|
||||
|
||||
dbConn, err := sqlx.Connect("mysql", dbConnString)
|
||||
if err != nil {
|
||||
ctx.Logger.Error().Err(err).Msg("Failed to connect to database")
|
||||
app.Log.Error().Err(err).Msg("Failed to connect to database")
|
||||
|
||||
return
|
||||
}
|
||||
@@ -177,12 +177,12 @@ func (db *Database) Initialize() {
|
||||
// Force UTC for current connection.
|
||||
_ = dbConn.MustExec("SET @@session.time_zone='+00:00';")
|
||||
|
||||
ctx.Logger.Info().Msg("Database connection established")
|
||||
app.Log.Info().Msg("Database connection established")
|
||||
|
||||
db.db = dbConn
|
||||
|
||||
// Perform migrations.
|
||||
migrations.New(ctx)
|
||||
migrations.New(app)
|
||||
migrations.Migrate()
|
||||
}
|
||||
|
||||
@@ -208,7 +208,7 @@ func (db *Database) Shutdown() {
|
||||
if db.db != nil {
|
||||
err := db.db.Close()
|
||||
if err != nil {
|
||||
ctx.Logger.Error().Err(err).Msg("Failed to close database connection")
|
||||
app.Log.Error().Err(err).Msg("Failed to close database connection")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -25,19 +25,19 @@
|
||||
package postgresql
|
||||
|
||||
import (
|
||||
"go.dev.pztrn.name/fastpastebin/internal/context"
|
||||
"go.dev.pztrn.name/fastpastebin/internal/application"
|
||||
dialectinterface "go.dev.pztrn.name/fastpastebin/internal/database/dialects/interface"
|
||||
)
|
||||
|
||||
var (
|
||||
ctx *context.Context
|
||||
app *application.Application
|
||||
dbAdapter *Database
|
||||
)
|
||||
|
||||
func New(cc *context.Context) {
|
||||
ctx = cc
|
||||
func New(cc *application.Application) {
|
||||
app = cc
|
||||
//nolint:exhaustruct
|
||||
dbAdapter = &Database{}
|
||||
|
||||
ctx.Database.RegisterDialect(dialectinterface.Interface(Handler{}))
|
||||
app.Database.RegisterDialect(dialectinterface.Interface(Handler{}))
|
||||
}
|
||||
|
@@ -26,19 +26,19 @@ package migrations
|
||||
|
||||
import (
|
||||
"github.com/pressly/goose"
|
||||
"go.dev.pztrn.name/fastpastebin/internal/context"
|
||||
"go.dev.pztrn.name/fastpastebin/internal/application"
|
||||
)
|
||||
|
||||
var ctx *context.Context
|
||||
var app *application.Application
|
||||
|
||||
// New initializes migrations.
|
||||
func New(cc *context.Context) {
|
||||
ctx = cc
|
||||
func New(cc *application.Application) {
|
||||
app = cc
|
||||
}
|
||||
|
||||
// Migrate launching migrations.
|
||||
func Migrate() {
|
||||
ctx.Logger.Info().Msg("Migrating database...")
|
||||
app.Log.Info().Msg("Migrating database...")
|
||||
|
||||
_ = goose.SetDialect("postgres")
|
||||
goose.AddNamedMigration("1_initial.go", InitialUp, nil)
|
||||
@@ -47,14 +47,14 @@ func Migrate() {
|
||||
goose.AddNamedMigration("4_passworded_pastes.go", PasswordedPastesUp, PasswordedPastesDown)
|
||||
// Add new migrations BEFORE this message.
|
||||
|
||||
dbConn := ctx.Database.GetDatabaseConnection()
|
||||
dbConn := app.Database.GetDatabaseConnection()
|
||||
if dbConn != nil {
|
||||
err := goose.Up(dbConn, ".")
|
||||
if err != nil {
|
||||
ctx.Logger.Info().Msgf("%+v", err)
|
||||
ctx.Logger.Panic().Msgf("Failed to migrate database to latest version: %s", err.Error())
|
||||
app.Log.Info().Msgf("%+v", err)
|
||||
app.Log.Panic().Msgf("Failed to migrate database to latest version: %s", err.Error())
|
||||
}
|
||||
} else {
|
||||
ctx.Logger.Warn().Msg("Current database dialect isn't supporting migrations, skipping")
|
||||
app.Log.Warn().Msg("Current database dialect isn't supporting migrations, skipping")
|
||||
}
|
||||
}
|
||||
|
@@ -114,10 +114,10 @@ func (db *Database) GetPagedPastes(page int) ([]structs.Paste, error) {
|
||||
// Pagination.
|
||||
startPagination := 0
|
||||
if page > 1 {
|
||||
startPagination = (page - 1) * ctx.Config.Pastes.Pagination
|
||||
startPagination = (page - 1) * app.Config.Pastes.Pagination
|
||||
}
|
||||
|
||||
err := db.db.Select(&pastesRaw, db.db.Rebind("SELECT * FROM pastes WHERE private != true ORDER BY id DESC LIMIT $1 OFFSET $2"), ctx.Config.Pastes.Pagination, startPagination)
|
||||
err := db.db.Select(&pastesRaw, db.db.Rebind("SELECT * FROM pastes WHERE private != true ORDER BY id DESC LIMIT $1 OFFSET $2"), app.Config.Pastes.Pagination, startPagination)
|
||||
if err != nil {
|
||||
//nolint:wrapcheck
|
||||
return nil, err
|
||||
@@ -159,9 +159,9 @@ func (db *Database) GetPastesPages() int {
|
||||
}
|
||||
|
||||
// Calculate pages.
|
||||
pages := len(pastes) / ctx.Config.Pastes.Pagination
|
||||
pages := len(pastes) / app.Config.Pastes.Pagination
|
||||
// Check if we have any remainder. Add 1 to pages count if so.
|
||||
if len(pastes)%ctx.Config.Pastes.Pagination > 0 {
|
||||
if len(pastes)%app.Config.Pastes.Pagination > 0 {
|
||||
pages++
|
||||
}
|
||||
|
||||
@@ -170,31 +170,31 @@ func (db *Database) GetPastesPages() int {
|
||||
|
||||
// Initialize initializes MySQL/MariaDB connection.
|
||||
func (db *Database) Initialize() {
|
||||
ctx.Logger.Info().Msg("Initializing database connection...")
|
||||
app.Log.Info().Msg("Initializing database connection...")
|
||||
|
||||
var userpass string
|
||||
if ctx.Config.Database.Password == "" {
|
||||
userpass = ctx.Config.Database.Username
|
||||
if app.Config.Database.Password == "" {
|
||||
userpass = app.Config.Database.Username
|
||||
} else {
|
||||
userpass = ctx.Config.Database.Username + ":" + ctx.Config.Database.Password
|
||||
userpass = app.Config.Database.Username + ":" + app.Config.Database.Password
|
||||
}
|
||||
|
||||
dbConnString := fmt.Sprintf("postgres://%s@%s/%s?connect_timeout=10&fallback_application_name=fastpastebin&sslmode=disable", userpass, net.JoinHostPort(ctx.Config.Database.Address, ctx.Config.Database.Port), ctx.Config.Database.Database)
|
||||
ctx.Logger.Debug().Str("DSN", dbConnString).Msg("Database connection string composed")
|
||||
dbConnString := fmt.Sprintf("postgres://%s@%s/%s?connect_timeout=10&fallback_application_name=fastpastebin&sslmode=disable", userpass, net.JoinHostPort(app.Config.Database.Address, app.Config.Database.Port), app.Config.Database.Database)
|
||||
app.Log.Debug().Str("DSN", dbConnString).Msg("Database connection string composed")
|
||||
|
||||
dbConn, err := sqlx.Connect("postgres", dbConnString)
|
||||
if err != nil {
|
||||
ctx.Logger.Error().Err(err).Msg("Failed to connect to database")
|
||||
app.Log.Error().Err(err).Msg("Failed to connect to database")
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Logger.Info().Msg("Database connection established")
|
||||
app.Log.Info().Msg("Database connection established")
|
||||
|
||||
db.db = dbConn
|
||||
|
||||
// Perform migrations.
|
||||
migrations.New(ctx)
|
||||
migrations.New(app)
|
||||
migrations.Migrate()
|
||||
}
|
||||
|
||||
@@ -222,7 +222,7 @@ func (db *Database) Shutdown() {
|
||||
if db.db != nil {
|
||||
err := db.db.Close()
|
||||
if err != nil {
|
||||
ctx.Logger.Error().Err(err).Msg("Failed to close database connection")
|
||||
app.Log.Error().Err(err).Msg("Failed to close database connection")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -25,20 +25,20 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"go.dev.pztrn.name/fastpastebin/internal/context"
|
||||
"go.dev.pztrn.name/fastpastebin/internal/application"
|
||||
databaseinterface "go.dev.pztrn.name/fastpastebin/internal/database/interface"
|
||||
)
|
||||
|
||||
var (
|
||||
ctx *context.Context
|
||||
app *application.Application
|
||||
dbAdapter *Database
|
||||
)
|
||||
|
||||
// New initializes database structure.
|
||||
func New(cc *context.Context) {
|
||||
ctx = cc
|
||||
func New(cc *application.Application) {
|
||||
app = cc
|
||||
//nolint:exhaustruct
|
||||
dbAdapter = &Database{}
|
||||
|
||||
ctx.RegisterDatabaseInterface(databaseinterface.Interface(Handler{}))
|
||||
app.Database = databaseinterface.Interface(Handler{})
|
||||
}
|
||||
|
Reference in New Issue
Block a user