-
Notifications
You must be signed in to change notification settings - Fork 80
/
Copy pathdb.go
136 lines (123 loc) · 4.57 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
131
132
133
134
135
136
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
RestrictedMedia *restrictedMediaTableStatements
}
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()
}
// GetAccessorForTests
// Deprecated: For tests only.
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())
}
if d.RestrictedMedia, err = prepareRestrictedMediaTables(d.conn); err != nil {
return errors.New("failed to create restricted media table accessor: " + err.Error())
}
instance = d
return nil
}