@@ -43,12 +43,14 @@ type birthdayBase struct {
43
43
}
44
44
45
45
type birthdayEntry struct {
46
- ID uint64 `database:"id"`
47
- Day int `database:"day"`
48
- Month int `database:"month"`
49
- Year int `database:"year"`
50
- Visible bool `database:"visible"`
51
- time time.Time
46
+ ID uint64 `database:"id"`
47
+ Day int `database:"day"`
48
+ Month int `database:"month"`
49
+ Year int `database:"year"`
50
+ Visible bool `database:"visible"`
51
+ time time.Time
52
+ GuildIDsRaw string `database:"guilds"`
53
+ GuildIDs []string
52
54
}
53
55
54
56
// Returns a readable Form of the date
@@ -108,15 +110,75 @@ func (b birthdayEntry) Age() int {
108
110
return b .Next ().Year () - b .Year - 1
109
111
}
110
112
113
+ // ParseGuildIDs splits the guild IDs into a slice and stores them in b.GuildIDs.
114
+ func (b * birthdayEntry ) ParseGuildIDs () {
115
+ b .GuildIDs = strings .Split (b .GuildIDsRaw , "," )
116
+ }
117
+
118
+ // IsInGuild returns true if the guildID is in b.GuildIDs.
119
+ // If guildID is empty, IsInGuild returns true.
120
+ func (b birthdayEntry ) IsInGuild (guildID string ) bool {
121
+ if guildID == "" {
122
+ return true
123
+ }
124
+ return util .ContainsString (b .GuildIDs , guildID )
125
+ }
126
+
127
+ // SetGuild sets the guildID in the birthday entry.
128
+ func (b * birthdayEntry ) SetGuild (guildID string ) {
129
+ b .GuildIDsRaw += guildID
130
+ b .ParseGuildIDs ()
131
+ }
132
+
133
+ // AddGuild adds the guildID to the birthday entry.
134
+ func (b * birthdayEntry ) AddGuild (guildID string ) error {
135
+ if util .ContainsString (b .GuildIDs , guildID ) {
136
+ return nil
137
+ } else if len (b .GuildIDs ) >= 3 {
138
+ return fmt .Errorf ("this entry already has %d guilds" , len (b .GuildIDs ))
139
+ }
140
+ b .GuildIDsRaw += "," + guildID
141
+ b .GuildIDsRaw = strings .Trim (b .GuildIDsRaw , ", " )
142
+ b .ParseGuildIDs ()
143
+ return nil
144
+ }
145
+
146
+ // IsEqual returns true if b and b2 are equal.
147
+ //
148
+ // That is, if all of the following are true
149
+ // 1. They have the same user ID.
150
+ // 2. They are on the same date.
151
+ // 3. They have the same visibility.
152
+ // 4. They have the same guilds in (any order).
153
+ func (b birthdayEntry ) IsEqual (b2 birthdayEntry ) bool {
154
+ if b .ID != b2 .ID || b .Day != b2 .Day || b .Month != b2 .Month || b .Year != b2 .Year || b .Visible != b2 .Visible {
155
+ return false
156
+ }
157
+
158
+ // check for same guilds in any order
159
+ for _ , guildID := range b .GuildIDs {
160
+ if ! util .ContainsString (b2 .GuildIDs , guildID ) {
161
+ return false
162
+ }
163
+ }
164
+ for _ , guildID := range b2 .GuildIDs {
165
+ if ! util .ContainsString (b .GuildIDs , guildID ) {
166
+ return false
167
+ }
168
+ }
169
+ return true
170
+ }
171
+
111
172
// getBirthday copies all birthday fields into the struct pointed at by b.
112
173
//
113
174
// If the user from b.ID is not found it returns sql.ErrNoRows.
114
175
func (cmd birthdayBase ) getBirthday (b * birthdayEntry ) (err error ) {
115
- row := database .QueryRow ("SELECT day,month,year,visible FROM birthdays WHERE id=?" , b .ID )
116
- err = row .Scan (& b .Day , & b .Month , & b .Year , & b .Visible )
176
+ row := database .QueryRow ("SELECT day,month,year,visible,guilds FROM birthdays WHERE id=?" , b .ID )
177
+ err = row .Scan (& b .Day , & b .Month , & b .Year , & b .Visible , & b . GuildIDsRaw )
117
178
if err != nil {
118
179
return err
119
180
}
181
+ b .ParseGuildIDs ()
120
182
return b .ParseTime ()
121
183
}
122
184
@@ -127,27 +189,36 @@ func (cmd birthdayBase) hasBirthday(id uint64) (hasBirthday bool, err error) {
127
189
}
128
190
129
191
// setBirthday inserts a new database entry with the values from b.
130
- func (cmd birthdayBase ) setBirthday (b birthdayEntry ) error {
131
- _ , err := database .Exec ("INSERT INTO birthdays(id,day,month,year,visible) VALUES(?,?,?,?,?);" , b .ID , b .Day , b .Month , b .Year , b .Visible )
192
+ func (cmd birthdayBase ) setBirthday (b * birthdayEntry ) (err error ) {
193
+ b .SetGuild (cmd .Interaction .GuildID )
194
+ _ , err = database .Exec ("INSERT INTO birthdays(id,day,month,year,visible,guilds) VALUES(?,?,?,?,?);" , b .ID , b .Day , b .Month , b .Year , b .Visible , b .GuildIDsRaw )
132
195
return err
133
196
}
134
197
135
198
// updateBirthday updates an existing database entry with the values from b.
136
- func (cmd birthdayBase ) updateBirthday (b birthdayEntry ) (before birthdayEntry , err error ) {
137
- err = b .ParseTime ()
138
- if err != nil {
139
- return birthdayEntry {}, err
140
- }
199
+ func (cmd birthdayBase ) updateBirthday (b * birthdayEntry ) (before birthdayEntry , err error ) {
141
200
before .ID = b .ID
142
201
if err = cmd .getBirthday (& before ); err != nil {
143
202
return birthdayEntry {}, fmt .Errorf ("trying to get old birthday: %v" , err )
144
203
}
204
+ b .GuildIDsRaw = before .GuildIDsRaw
205
+ b .ParseGuildIDs ()
206
+
207
+ err = b .AddGuild (cmd .Interaction .GuildID )
208
+ if err != nil {
209
+ return birthdayEntry {}, fmt .Errorf ("adding guild '%s' to birthday entry: %v" , cmd .Interaction .GuildID , err )
210
+ }
211
+
212
+ // early return if nothing changed
213
+ if b .IsEqual (before ) {
214
+ return before , nil
215
+ }
145
216
146
217
var (
147
218
updateNames []string
148
219
updateVars []any
149
220
oldV reflect.Value = reflect .ValueOf (before )
150
- v reflect.Value = reflect .ValueOf (b )
221
+ v reflect.Value = reflect .ValueOf (* b )
151
222
)
152
223
for i := 0 ; i < v .NumField (); i ++ {
153
224
var (
@@ -160,11 +231,11 @@ func (cmd birthdayBase) updateBirthday(b birthdayEntry) (before birthdayEntry, e
160
231
continue
161
232
}
162
233
234
+ tag := v .Type ().Field (i ).Tag .Get ("database" )
235
+ if tag == "" {
236
+ continue
237
+ }
163
238
if f .Interface () != oldF .Interface () {
164
- tag := v .Type ().Field (i ).Tag .Get ("database" )
165
- if tag == "" {
166
- continue
167
- }
168
239
updateNames = append (updateNames , tag )
169
240
updateVars = append (updateVars , f .Interface ())
170
241
}
@@ -193,8 +264,8 @@ func (cmd birthdayBase) removeBirthday(id uint64) (birthdayEntry, error) {
193
264
return b , err
194
265
}
195
266
196
- // getBirthdaysMonth return a sorted slice of birthday entries that matches the given month.
197
- func (cmd birthdayBase ) getBirthdaysMonth (month int ) (birthdays []birthdayEntry , err error ) {
267
+ // getBirthdaysMonth return a sorted slice of birthday entries that matches the given guildID and month.
268
+ func (cmd birthdayBase ) getBirthdaysMonth (guildID string , month int ) (birthdays []birthdayEntry , err error ) {
198
269
var numOfEntries int64
199
270
err = database .QueryRow ("SELECT COUNT(*) FROM birthdays WHERE month=?" , month ).Scan (& numOfEntries )
200
271
if err != nil {
@@ -206,20 +277,21 @@ func (cmd birthdayBase) getBirthdaysMonth(month int) (birthdays []birthdayEntry,
206
277
return birthdays , nil
207
278
}
208
279
209
- rows , err := database .Query ("SELECT id,day,year,visible FROM birthdays WHERE month=?" , month )
280
+ rows , err := database .Query ("SELECT id,day,year,visible,guilds FROM birthdays WHERE month=?" , month )
210
281
if err != nil {
211
282
return birthdays , err
212
283
}
213
284
defer rows .Close ()
214
285
215
286
for rows .Next () {
216
287
b := birthdayEntry {Month : month }
217
- err = rows .Scan (& b .ID , & b .Day , & b .Year , & b .Visible )
288
+ err = rows .Scan (& b .ID , & b .Day , & b .Year , & b .Visible , & b . GuildIDsRaw )
218
289
if err != nil {
219
290
return birthdays , err
220
291
}
292
+ b .ParseGuildIDs ()
221
293
222
- if ! b .Visible {
294
+ if ! b .Visible || ! b . IsInGuild ( guildID ) {
223
295
continue
224
296
}
225
297
@@ -238,8 +310,8 @@ func (cmd birthdayBase) getBirthdaysMonth(month int) (birthdays []birthdayEntry,
238
310
return birthdays , nil
239
311
}
240
312
241
- // getBirthdaysDate return a slice of birthday entries that matches the given date.
242
- func getBirthdaysDate (day int , month int ) (birthdays []birthdayEntry , err error ) {
313
+ // getBirthdaysDate return a slice of birthday entries that matches the given guildID and date.
314
+ func getBirthdaysDate (guildID string , day int , month int ) (birthdays []birthdayEntry , err error ) {
243
315
var numOfEntries int64
244
316
err = database .QueryRow ("SELECT COUNT(*) FROM birthdays WHERE day=? AND month=?" , day , month ).Scan (& numOfEntries )
245
317
if err != nil {
@@ -251,20 +323,21 @@ func getBirthdaysDate(day int, month int) (birthdays []birthdayEntry, err error)
251
323
return birthdays , nil
252
324
}
253
325
254
- rows , err := database .Query ("SELECT id,year,visible FROM birthdays WHERE day=? AND month=?" , day , month )
326
+ rows , err := database .Query ("SELECT id,year,visible,guilds FROM birthdays WHERE day=? AND month=?" , day , month )
255
327
if err != nil {
256
328
return birthdays , err
257
329
}
258
330
defer rows .Close ()
259
331
260
332
for rows .Next () {
261
333
b := birthdayEntry {Day : day , Month : month }
262
- err = rows .Scan (& b .ID , & b .Year , & b .Visible )
334
+ err = rows .Scan (& b .ID , & b .Year , & b .Visible , & b . GuildIDsRaw )
263
335
if err != nil {
264
336
return birthdays , err
265
337
}
338
+ b .ParseGuildIDs ()
266
339
267
- if ! b .Visible {
340
+ if ! b .Visible || ! b . IsInGuild ( guildID ) {
268
341
continue
269
342
}
270
343
0 commit comments