|
@@ -25,7 +25,7 @@ const (
|
25
|
25
|
MaxTargetLength = 64
|
26
|
26
|
|
27
|
27
|
// latest schema of the db
|
28
|
|
- latestDbSchema = "1"
|
|
28
|
+ latestDbSchema = "2"
|
29
|
29
|
keySchemaVersion = "db.version"
|
30
|
30
|
cleanupRowLimit = 50
|
31
|
31
|
cleanupPauseTime = 10 * time.Minute
|
|
@@ -144,11 +144,11 @@ func (mysql *MySQL) createTables() (err error) {
|
144
|
144
|
|
145
|
145
|
_, err = mysql.db.Exec(fmt.Sprintf(`CREATE TABLE conversations (
|
146
|
146
|
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
147
|
|
- lower_target VARBINARY(%[1]d) NOT NULL,
|
148
|
|
- upper_target VARBINARY(%[1]d) NOT NULL,
|
|
147
|
+ target VARBINARY(%[1]d) NOT NULL,
|
|
148
|
+ correspondent VARBINARY(%[1]d) NOT NULL,
|
149
|
149
|
nanotime BIGINT UNSIGNED NOT NULL,
|
150
|
150
|
history_id BIGINT NOT NULL,
|
151
|
|
- KEY (lower_target, upper_target, nanotime),
|
|
151
|
+ KEY (target, correspondent, nanotime),
|
152
|
152
|
KEY (history_id)
|
153
|
153
|
) CHARSET=ascii COLLATE=ascii_bin;`, MaxTargetLength))
|
154
|
154
|
if err != nil {
|
|
@@ -278,7 +278,7 @@ func (mysql *MySQL) prepareStatements() (err error) {
|
278
|
278
|
return
|
279
|
279
|
}
|
280
|
280
|
mysql.insertConversation, err = mysql.db.Prepare(`INSERT INTO conversations
|
281
|
|
- (lower_target, upper_target, nanotime, history_id) VALUES (?, ?, ?, ?);`)
|
|
281
|
+ (target, correspondent, nanotime, history_id) VALUES (?, ?, ?, ?);`)
|
282
|
282
|
if err != nil {
|
283
|
283
|
return
|
284
|
284
|
}
|
|
@@ -315,19 +315,18 @@ func (mysql *MySQL) AddChannelItem(target string, item history.Item) (err error)
|
315
|
315
|
return
|
316
|
316
|
}
|
317
|
317
|
|
318
|
|
- err = mysql.insertSequenceEntry(ctx, target, item.Message.Time, id)
|
|
318
|
+ err = mysql.insertSequenceEntry(ctx, target, item.Message.Time.UnixNano(), id)
|
319
|
319
|
return
|
320
|
320
|
}
|
321
|
321
|
|
322
|
|
-func (mysql *MySQL) insertSequenceEntry(ctx context.Context, target string, messageTime time.Time, id int64) (err error) {
|
323
|
|
- _, err = mysql.insertSequence.ExecContext(ctx, target, messageTime.UnixNano(), id)
|
|
322
|
+func (mysql *MySQL) insertSequenceEntry(ctx context.Context, target string, messageTime int64, id int64) (err error) {
|
|
323
|
+ _, err = mysql.insertSequence.ExecContext(ctx, target, messageTime, id)
|
324
|
324
|
mysql.logError("could not insert sequence entry", err)
|
325
|
325
|
return
|
326
|
326
|
}
|
327
|
327
|
|
328
|
|
-func (mysql *MySQL) insertConversationEntry(ctx context.Context, sender, recipient string, messageTime time.Time, id int64) (err error) {
|
329
|
|
- lower, higher := stringMinMax(sender, recipient)
|
330
|
|
- _, err = mysql.insertConversation.ExecContext(ctx, lower, higher, messageTime.UnixNano(), id)
|
|
328
|
+func (mysql *MySQL) insertConversationEntry(ctx context.Context, target, correspondent string, messageTime int64, id int64) (err error) {
|
|
329
|
+ _, err = mysql.insertConversation.ExecContext(ctx, target, correspondent, messageTime, id)
|
331
|
330
|
mysql.logError("could not insert conversations entry", err)
|
332
|
331
|
return
|
333
|
332
|
}
|
|
@@ -355,20 +354,12 @@ func (mysql *MySQL) insertBase(ctx context.Context, item history.Item) (id int64
|
355
|
354
|
return
|
356
|
355
|
}
|
357
|
356
|
|
358
|
|
-func stringMinMax(first, second string) (min, max string) {
|
359
|
|
- if first < second {
|
360
|
|
- return first, second
|
361
|
|
- } else {
|
362
|
|
- return second, first
|
363
|
|
- }
|
364
|
|
-}
|
365
|
|
-
|
366
|
|
-func (mysql *MySQL) AddDirectMessage(sender, recipient string, senderPersistent, recipientPersistent bool, item history.Item) (err error) {
|
|
357
|
+func (mysql *MySQL) AddDirectMessage(sender, senderAccount, recipient, recipientAccount string, item history.Item) (err error) {
|
367
|
358
|
if mysql.db == nil {
|
368
|
359
|
return
|
369
|
360
|
}
|
370
|
361
|
|
371
|
|
- if !(senderPersistent || recipientPersistent) {
|
|
362
|
+ if senderAccount == "" && recipientAccount == "" {
|
372
|
363
|
return
|
373
|
364
|
}
|
374
|
365
|
|
|
@@ -384,22 +375,30 @@ func (mysql *MySQL) AddDirectMessage(sender, recipient string, senderPersistent,
|
384
|
375
|
return
|
385
|
376
|
}
|
386
|
377
|
|
387
|
|
- if senderPersistent {
|
388
|
|
- mysql.insertSequenceEntry(ctx, sender, item.Message.Time, id)
|
|
378
|
+ nanotime := item.Message.Time.UnixNano()
|
|
379
|
+
|
|
380
|
+ if senderAccount != "" {
|
|
381
|
+ err = mysql.insertSequenceEntry(ctx, senderAccount, nanotime, id)
|
|
382
|
+ if err != nil {
|
|
383
|
+ return
|
|
384
|
+ }
|
|
385
|
+ err = mysql.insertConversationEntry(ctx, senderAccount, recipient, nanotime, id)
|
389
|
386
|
if err != nil {
|
390
|
387
|
return
|
391
|
388
|
}
|
392
|
389
|
}
|
393
|
390
|
|
394
|
|
- if recipientPersistent && sender != recipient {
|
395
|
|
- err = mysql.insertSequenceEntry(ctx, recipient, item.Message.Time, id)
|
|
391
|
+ if recipientAccount != "" && sender != recipient {
|
|
392
|
+ err = mysql.insertSequenceEntry(ctx, recipientAccount, nanotime, id)
|
|
393
|
+ if err != nil {
|
|
394
|
+ return
|
|
395
|
+ }
|
|
396
|
+ err = mysql.insertConversationEntry(ctx, recipientAccount, sender, nanotime, id)
|
396
|
397
|
if err != nil {
|
397
|
398
|
return
|
398
|
399
|
}
|
399
|
400
|
}
|
400
|
401
|
|
401
|
|
- err = mysql.insertConversationEntry(ctx, sender, recipient, item.Message.Time, id)
|
402
|
|
-
|
403
|
402
|
return
|
404
|
403
|
}
|
405
|
404
|
|
|
@@ -453,14 +452,8 @@ func (mysql *MySQL) selectItems(ctx context.Context, query string, args ...inter
|
453
|
452
|
return
|
454
|
453
|
}
|
455
|
454
|
|
456
|
|
-func (mysql *MySQL) betweenTimestamps(ctx context.Context, sender, recipient string, after, before, cutoff time.Time, limit int) (results []history.Item, err error) {
|
457
|
|
- useSequence := true
|
458
|
|
- var lowerTarget, upperTarget string
|
459
|
|
- if sender != "" {
|
460
|
|
- lowerTarget, upperTarget = stringMinMax(sender, recipient)
|
461
|
|
- useSequence = false
|
462
|
|
- }
|
463
|
|
-
|
|
455
|
+func (mysql *MySQL) betweenTimestamps(ctx context.Context, target, correspondent string, after, before, cutoff time.Time, limit int) (results []history.Item, err error) {
|
|
456
|
+ useSequence := correspondent == ""
|
464
|
457
|
table := "sequence"
|
465
|
458
|
if !useSequence {
|
466
|
459
|
table = "conversations"
|
|
@@ -479,11 +472,11 @@ func (mysql *MySQL) betweenTimestamps(ctx context.Context, sender, recipient str
|
479
|
472
|
"SELECT history.data from history INNER JOIN %[1]s ON history.id = %[1]s.history_id WHERE", table)
|
480
|
473
|
if useSequence {
|
481
|
474
|
fmt.Fprintf(&queryBuf, " sequence.target = ?")
|
482
|
|
- args = append(args, recipient)
|
|
475
|
+ args = append(args, target)
|
483
|
476
|
} else {
|
484
|
|
- fmt.Fprintf(&queryBuf, " conversations.lower_target = ? AND conversations.upper_target = ?")
|
485
|
|
- args = append(args, lowerTarget)
|
486
|
|
- args = append(args, upperTarget)
|
|
477
|
+ fmt.Fprintf(&queryBuf, " conversations.target = ? AND conversations.correspondent = ?")
|
|
478
|
+ args = append(args, target)
|
|
479
|
+ args = append(args, correspondent)
|
487
|
480
|
}
|
488
|
481
|
if !after.IsZero() {
|
489
|
482
|
fmt.Fprintf(&queryBuf, " AND %s.nanotime > ?", table)
|
|
@@ -514,10 +507,10 @@ func (mysql *MySQL) Close() {
|
514
|
507
|
// implements history.Sequence, emulating a single history buffer (for a channel,
|
515
|
508
|
// a single user's DMs, or a DM conversation)
|
516
|
509
|
type mySQLHistorySequence struct {
|
517
|
|
- mysql *MySQL
|
518
|
|
- sender string
|
519
|
|
- recipient string
|
520
|
|
- cutoff time.Time
|
|
510
|
+ mysql *MySQL
|
|
511
|
+ target string
|
|
512
|
+ correspondent string
|
|
513
|
+ cutoff time.Time
|
521
|
514
|
}
|
522
|
515
|
|
523
|
516
|
func (s *mySQLHistorySequence) Between(start, end history.Selector, limit int) (results []history.Item, complete bool, err error) {
|
|
@@ -539,7 +532,7 @@ func (s *mySQLHistorySequence) Between(start, end history.Selector, limit int) (
|
539
|
532
|
}
|
540
|
533
|
}
|
541
|
534
|
|
542
|
|
- results, err = s.mysql.betweenTimestamps(ctx, s.sender, s.recipient, startTime, endTime, s.cutoff, limit)
|
|
535
|
+ results, err = s.mysql.betweenTimestamps(ctx, s.target, s.correspondent, startTime, endTime, s.cutoff, limit)
|
543
|
536
|
return results, (err == nil), err
|
544
|
537
|
}
|
545
|
538
|
|
|
@@ -547,11 +540,11 @@ func (s *mySQLHistorySequence) Around(start history.Selector, limit int) (result
|
547
|
540
|
return history.GenericAround(s, start, limit)
|
548
|
541
|
}
|
549
|
542
|
|
550
|
|
-func (mysql *MySQL) MakeSequence(sender, recipient string, cutoff time.Time) history.Sequence {
|
|
543
|
+func (mysql *MySQL) MakeSequence(target, correspondent string, cutoff time.Time) history.Sequence {
|
551
|
544
|
return &mySQLHistorySequence{
|
552
|
|
- sender: sender,
|
553
|
|
- recipient: recipient,
|
554
|
|
- mysql: mysql,
|
555
|
|
- cutoff: cutoff,
|
|
545
|
+ target: target,
|
|
546
|
+ correspondent: correspondent,
|
|
547
|
+ mysql: mysql,
|
|
548
|
+ cutoff: cutoff,
|
556
|
549
|
}
|
557
|
550
|
}
|