/
db.go
144 lines (114 loc) · 3.44 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
137
138
139
140
141
142
143
144
/*Package enpsql .
Currently there is no automated schema management
so schema updates will have to be applied manually for each module
when making a module that makes use of this
please make a dedicated sql schema for each module as to avoid conflicts between modules
avoid using the public schema for anything in any modules
THIS PACKAGE DOES NOT ENFORCE SQL SCHEMA BOUNDRIES
you will need to ensure you manually specify the schema by namespacing table names
the public schema should only be used internally for this psql package
*/
package enpsql
import (
"bytes"
"fmt"
"log"
"time"
"codeberg.org/eviedelta/drc"
"github.com/bwmarrin/discordgo"
"github.com/eviedelta/openjishia/module"
"github.com/eviedelta/openjishia/wlog"
"github.com/gocraft/dbr/v2"
"github.com/pelletier/go-toml"
"github.com/pkg/errors"
// Import postgresql for database stuff
_ "github.com/lib/pq"
)
var table = struct {
Schemas string
// BotConfig string // possibile future feature, managed config
}{
Schemas: "public.schemas",
// BotConfig: "public.bot_config",
}
var dbc *dbr.Connection
var ses *dbr.Session
func GetSession() *dbr.Session {
return dbc.NewSession(nil)
}
func Ping() (time.Duration, error) {
if dbc == nil {
return 0, errors.New("database isn't connected yet")
}
t := time.Now()
if err := dbc.Ping(); err != nil {
return 0, err
}
return time.Now().Sub(t), nil
}
// Config is the config that contains global config stuff, i mean it is named config so what else would it be
var Config = &localConfig{}
type localConfig struct {
Auth struct {
Database, Username, Password, Hostname string
}
External struct {
BackupCommand string // it will call this command (exactly as given) before doing a schema update
}
}
// Module contains the module, i mean what else would it contain
// being this is the database its probably a good idea to put this first in the module list
var Module = &module.Module{
Name: "enpsql",
DgoHandlers: []interface{}{},
Commands: []*drc.Command{},
Config: Config,
InitFunc: func(mod *module.Module) error {
if !mod.ConfigFound {
b := bytes.NewBuffer([]byte{})
e := toml.NewEncoder(b)
err := e.Encode(mod.Config)
if err != nil {
return err
}
fmt.Println(b.String())
return fmt.Errorf("Config not found, database config data mandatory")
}
return nil
},
OpenFunc: openFunc,
CloseFunc: closeFunc,
}
func onReady(s *discordgo.Session, e *discordgo.Ready) {
err := dbc.Ping()
if err != nil {
wlog.Err.Print(err)
}
}
// OpenFunc contains some the initialisation functions for this module per the terms of the pre-alpha attempt at modularisation this is built off of
func openFunc(mod *module.Module) error {
dsn := fmt.Sprintf("dbname=%v user=%v password='%v' host='%v' sslmode=disable",
Config.Auth.Database, Config.Auth.Username, Config.Auth.Password, Config.Auth.Hostname)
conn, err := dbr.Open("postgres", dsn, nil)
if err != nil {
return errors.Wrap(err, "DB Connect")
}
if err := conn.Ping(); err != nil {
return errors.Wrap(err, "DB Ping")
}
dbc = conn
ses = GetSession()
err = initialCheck()
if err != nil {
return errors.Wrap(err, "DB schema core")
}
err = updateAll()
if err != nil {
return errors.Wrap(err, "DB update schemas")
}
return nil
}
// CloseFunc contains the closing functions for this module per the terms of the pre-alpha attempt at modularisation this is built off of
func closeFunc(mod *module.Module) {
log.Println(dbc.Close())
}