-
Notifications
You must be signed in to change notification settings - Fork 73
/
db.go
130 lines (117 loc) · 4.3 KB
/
db.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package database
import (
"database/sql"
"errors"
"sync"
"github.com/DavidHuie/gomigrate"
"github.com/getsentry/sentry-go"
_ "github.com/lib/pq" // postgres driver
"github.com/sirupsen/logrus"
"github.com/t2bot/matrix-media-repo/common/config"
"github.com/t2bot/matrix-media-repo/common/logging"
)
type Database struct {
conn *sql.DB
Media *mediaTableStatements
ExpiringMedia *expiringMediaTableStatements
UserStats *userStatsTableStatements
ReservedMedia *reservedMediaTableStatements
MetadataView *metadataVirtualTableStatements
HeldMedia *heldMediaTableStatements
Thumbnails *thumbnailsTableStatements
LastAccess *lastAccessTableStatements
UrlPreviews *urlPreviewsTableStatements
MediaAttributes *mediaAttributesTableStatements
Tasks *tasksTableStatements
Exports *exportsTableStatements
ExportParts *exportPartsTableStatements
}
var instance *Database
var singleton = &sync.Once{}
func GetInstance() *Database {
if instance == nil {
singleton.Do(func() {
if err := openDatabase(
config.Get().Database.Postgres,
config.Get().Database.Pool.MaxConnections,
config.Get().Database.Pool.MaxIdle,
); err != nil {
logrus.Fatal("Failed to set up database: ", err)
}
})
}
return instance
}
func Reload() {
if instance != nil {
if err := instance.conn.Close(); err != nil {
logrus.Error(err)
sentry.CaptureException(err)
}
}
instance = nil
singleton = &sync.Once{}
GetInstance()
}
func GetAccessorForTests() *sql.DB {
return GetInstance().conn
}
func openDatabase(connectionString string, maxConns int, maxIdleConns int) error {
d := &Database{}
var err error
if d.conn, err = sql.Open("postgres", connectionString); err != nil {
return errors.New("error connecting to db: " + err.Error())
}
d.conn.SetMaxOpenConns(maxConns)
d.conn.SetMaxIdleConns(maxIdleConns)
// Run migrations
var migrator *gomigrate.Migrator
if migrator, err = gomigrate.NewMigratorWithLogger(d.conn, gomigrate.Postgres{}, config.Runtime.MigrationsPath, &logging.SendToDebugLogger{}); err != nil {
return errors.New("error setting up migrator: " + err.Error())
}
if err = migrator.Migrate(); err != nil {
return errors.New("error running migrations: " + err.Error())
}
// Prepare the table accessors
if d.Media, err = prepareMediaTables(d.conn); err != nil {
return errors.New("failed to create media table accessor: " + err.Error())
}
if d.ExpiringMedia, err = prepareExpiringMediaTables(d.conn); err != nil {
return errors.New("failed to create expiring media table accessor: " + err.Error())
}
if d.UserStats, err = prepareUserStatsTables(d.conn); err != nil {
return errors.New("failed to create user stats table accessor: " + err.Error())
}
if d.ReservedMedia, err = prepareReservedMediaTables(d.conn); err != nil {
return errors.New("failed to create reserved media table accessor: " + err.Error())
}
if d.MetadataView, err = prepareMetadataVirtualTables(d.conn); err != nil {
return errors.New("failed to create metadata virtual table accessor: " + err.Error())
}
if d.HeldMedia, err = prepareHeldMediaTables(d.conn); err != nil {
return errors.New("failed to create held media table accessor: " + err.Error())
}
if d.Thumbnails, err = prepareThumbnailsTables(d.conn); err != nil {
return errors.New("failed to create thumbnails table accessor: " + err.Error())
}
if d.LastAccess, err = prepareLastAccessTables(d.conn); err != nil {
return errors.New("failed to create last access table accessor: " + err.Error())
}
if d.UrlPreviews, err = prepareUrlPreviewsTables(d.conn); err != nil {
return errors.New("failed to create url previews table accessor: " + err.Error())
}
if d.MediaAttributes, err = prepareMediaAttributesTables(d.conn); err != nil {
return errors.New("failed to create media attributes table accessor: " + err.Error())
}
if d.Tasks, err = prepareTasksTables(d.conn); err != nil {
return errors.New("failed to create tasks table accessor: " + err.Error())
}
if d.Exports, err = prepareExportsTables(d.conn); err != nil {
return errors.New("failed to create exports table accessor: " + err.Error())
}
if d.ExportParts, err = prepareExportPartsTables(d.conn); err != nil {
return errors.New("failed to create export parts table accessor: " + err.Error())
}
instance = d
return nil
}