add persistency for mailserver topics (#1597)

This commit is contained in:
Adam Babik 2019-09-04 20:23:17 +02:00 committed by GitHub
parent b27779aa4e
commit 9df64efe2c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 170 additions and 29 deletions

View file

@ -1,7 +1,7 @@
// Code generated by go-bindata. DO NOT EDIT.
// sources:
// 0001_app.down.sql (314B)
// 0001_app.up.sql (2.528kB)
// 0001_app.down.sql (344B)
// 0001_app.up.sql (2.701kB)
// doc.go (74B)
package migrations
@ -71,7 +71,7 @@ func (fi bindataFileInfo) Sys() interface{} {
return nil
}
var __0001_appDownSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x74\xce\xbf\x0e\x82\x40\x0c\xc7\xf1\x9d\xa7\xe0\x3d\x98\x34\x30\x98\x18\x35\xc6\xc1\xad\xa9\x47\x85\x46\xb8\x9e\x6d\xf1\xcf\xdb\x3b\xca\x45\x5c\x3f\xfd\xe5\x9b\xd6\xc7\xfd\xa1\x3c\xad\xd6\xdb\xa6\x34\x72\xe7\xd8\x59\x55\xcc\x10\x43\x90\x29\x7a\x8e\x17\x95\xa7\x91\x2e\x23\xf4\x6c\x2e\xfa\xce\x8e\x2d\xa6\x94\xcf\x13\xe9\xc8\x66\x2c\x31\x77\x57\x8c\x76\xfd\x89\x0f\x12\x6e\xcb\x9f\x81\x0b\x2c\x9c\x47\xe4\xc1\x48\x1f\xdf\xd2\x66\x57\x37\xe7\x99\x83\xd2\x7d\x22\x73\xe8\x30\x19\x84\x1e\x1d\xb8\x05\x6e\x5f\x7f\x3a\xd9\xbe\x2a\x3e\x01\x00\x00\xff\xff\x07\x9e\x75\xc1\x3a\x01\x00\x00")
var __0001_appDownSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x74\xce\xbd\x0e\xc2\x30\x0c\x04\xe0\xbd\x4f\xd1\xf7\xe8\x04\x6a\x07\x24\x04\x08\x31\xb0\x59\x21\x35\xad\x45\x1b\x07\xdb\xe5\xe7\xed\xd9\x80\x40\xba\x7e\x77\x3a\x5d\xbd\xdf\xee\xca\xc3\x62\xb9\x6e\x4a\x45\x33\x0a\x9d\x56\xc5\x17\x3a\xef\x79\x0a\x96\xe2\x49\xf8\xae\x28\x79\x84\x9e\xd4\x58\x9e\x49\xd8\xba\x18\xd3\x7a\x44\x19\x49\x95\x38\xa4\x6e\xe2\x82\x9e\xff\xc6\x07\xf6\x97\xfc\x33\x30\x86\x4c\x3c\x3a\x1a\x14\xe5\xf6\xbb\xf4\x71\x10\xbc\x4e\xa8\x06\x9d\x7b\x7f\x5b\x6d\xea\xe6\x38\xd7\x01\xdf\x3b\x03\x6a\x81\xda\xc7\xdc\xa6\x71\x24\xaf\x55\xf1\x0a\x00\x00\xff\xff\x89\xe0\x6b\xf0\x58\x01\x00\x00")
func _0001_appDownSqlBytes() ([]byte, error) {
return bindataRead(
@ -86,12 +86,12 @@ func _0001_appDownSql() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "0001_app.down.sql", size: 314, mode: os.FileMode(0644), modTime: time.Unix(1567586064, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x86, 0x70, 0x13, 0xfb, 0x14, 0x28, 0x91, 0x3f, 0x97, 0x54, 0x9b, 0xab, 0x17, 0xb0, 0xdd, 0x3c, 0xa9, 0x40, 0x72, 0x45, 0xec, 0xf6, 0x16, 0x47, 0xbc, 0xd2, 0x30, 0x5d, 0x14, 0x0, 0x50, 0x19}}
info := bindataFileInfo{name: "0001_app.down.sql", size: 344, mode: os.FileMode(0644), modTime: time.Unix(1567620215, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xa0, 0x74, 0x22, 0xcd, 0xfd, 0xf3, 0xf1, 0x2a, 0xa0, 0xc1, 0x37, 0x66, 0x32, 0x93, 0x2c, 0x75, 0x21, 0xd6, 0xd7, 0xb2, 0x37, 0x7c, 0x2, 0x4c, 0xab, 0xab, 0x4c, 0x5d, 0x55, 0x6c, 0x77, 0xf2}}
return a, nil
}
var __0001_appUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xa4\x56\xdf\x72\xba\x38\x18\xbd\xcf\x53\x7c\x97\x3a\xc3\x1b\xf4\x0a\x35\x5a\x66\x59\xd8\x45\xdc\xb6\x57\x99\x28\x51\x19\x81\xa4\x49\xac\xf5\xed\x77\x42\xf8\xa7\x02\xb6\xf3\xbb\x23\xc9\xc9\xf1\x9c\x93\x2f\x5f\x9c\x47\xd8\x8d\x31\xc4\xee\xcc\xc7\xe0\x2d\x21\x08\x63\xc0\xef\xde\x3a\x5e\x83\x62\x5a\xa7\xc5\x41\xc1\x04\xe9\xab\x60\xf0\x9f\x1b\xcd\x5f\xdd\x08\xfe\x89\xbc\xbf\xdd\xe8\x03\xfe\xc2\x1f\x0e\xfa\xa2\xd9\x99\xc1\xcc\x0f\x67\x68\x0a\x6f\x5e\xfc\x1a\x6e\x62\x88\xc2\x37\x6f\xf1\x82\xd0\x08\x39\xdd\xed\xf8\xb9\xd0\x86\x9c\x26\x89\x64\x4a\xf5\xf3\x5f\x68\x96\x31\x0d\xb3\x30\xf4\xb1\x1b\x38\x68\x77\xa4\x9d\x51\xa9\x2b\xc6\xef\xb1\x83\x94\xe6\x92\x1e\xea\x91\x38\x6f\x4f\xec\x5a\xea\x72\x90\xa0\xfa\x58\xcd\x17\x34\xaf\x21\x3b\x9e\x71\x59\x7e\x0f\x2b\xdf\x04\xde\xbf\x1b\x0c\x5e\xb0\xc0\xef\x70\x2e\xd2\xcf\x33\x23\x56\x11\xa9\x55\x87\x41\xc7\x8b\x5d\x9b\xc2\xdb\x2b\x8e\x70\x33\x7c\x19\xa3\x33\x86\xfa\xc9\xcc\x4a\x43\x55\x0e\xc6\x23\xdd\x4a\x7e\x51\x4c\x9a\x48\xd3\xa4\x34\x76\x1b\x65\xe3\xbd\xdc\x14\x6c\x7c\xdf\x41\x3a\xcd\x99\xd2\x34\x17\xb0\x59\xaf\xbc\x55\x80\x17\x30\xf3\x56\x5e\x10\x3b\x28\xa1\x42\xd4\x49\xc3\x02\x2f\xdd\x8d\x1f\xc3\x9e\x66\x8a\x39\xe8\x98\x9a\xb8\xaf\x5e\x91\xb0\x6f\xd8\x04\x6b\xbb\xd3\x0b\x46\xa2\x1c\x53\x4c\x2a\x3e\x98\xa0\x6a\x8a\xd4\x0e\x5a\xa9\x35\xc6\x9e\xde\x32\x8c\xb0\xb7\x0a\x8c\xb3\x49\xbb\x67\x0a\x11\x5e\xe2\x08\x07\x73\xdc\xb2\x4f\xcc\x7c\x68\x3c\xf8\x38\xc6\x30\x77\xd7\x73\x77\x81\xd1\x93\x34\x8d\x7d\x13\x65\x9b\x5a\x27\xcc\xdf\xd9\x14\x4c\xe6\xa9\x52\x29\x2f\x0c\xa1\x21\x26\x7d\x67\xd1\xc2\xee\x57\xba\x66\x9b\xed\x37\x5e\x4b\xb5\x13\x3b\xdd\x6f\x75\x4c\xa0\x96\xb4\x50\x7b\x5b\x3a\x05\xd3\x17\x2e\x4f\xe6\x00\x9a\x83\xb5\x25\xd1\x3d\x0b\xaa\x8e\xcd\x7d\x6d\xa7\xef\x6f\x72\xbb\xb2\xcd\x4e\x64\x60\x93\xfe\xae\xae\xa9\x62\x45\xc2\x64\x0f\x42\xb2\x1d\x4b\x85\xae\x60\x19\x3f\x54\x5f\x37\x5d\xa9\x3f\xad\xd6\x8d\x53\x4b\xb8\xad\x91\x8c\xef\x4e\xaa\x0b\xb3\x90\x87\x0c\x1d\x34\x0f\x83\x75\x1c\xb9\x26\x88\xea\xea\xd6\xb1\x11\xc1\x64\x7d\x85\xcb\xef\x8a\xae\xbe\xef\x13\xc3\xe9\x54\x00\xa7\xfd\xad\xe9\xb3\x1a\xb4\xea\xfe\xf0\x50\x8a\x73\xbe\x65\xf2\x11\xde\xb9\xfa\xc3\x94\x8c\x26\x65\x0f\x68\x1a\xc0\xd2\xf5\xd7\xbd\x61\x94\x5a\x7b\xdd\xdf\x87\x3b\xb8\xd9\x2a\x7d\xc6\x61\x51\x4f\xb3\xab\xfb\x28\xd1\x9c\xfc\x2e\xc7\xf1\x2a\x1e\x8a\x53\x5d\x8b\x1d\x94\x8d\x73\xa4\xfe\x2a\xed\xe3\x15\x58\x83\x7e\x54\x83\x39\x15\x22\x2d\x0e\x64\xcf\x25\xa9\x2c\x37\x8e\x7b\x93\xac\xcb\xb0\x95\xf3\x9b\x8a\xcc\x69\x9a\x29\x26\xbf\x6c\xaf\x00\x00\x48\x93\xfe\x87\xdb\xac\x95\x5d\xee\x31\x46\xb3\x34\x1c\xb2\x59\x15\x54\xa9\x0b\x97\x0d\xb5\x9d\xdd\x67\x8c\xe9\x87\x1d\x3f\x97\x4c\x24\xfb\x3c\x33\xa5\xc9\x81\x0a\x2b\xff\x40\x05\xd9\x4b\x9e\xdf\xbc\x61\x78\x85\x6f\xf5\x18\x94\xe6\xe3\x98\xde\x17\x17\xa0\x7c\xdd\xef\xdf\x32\x04\x30\xf8\x7e\xd8\xff\x06\x03\x9a\x49\x45\x47\xd2\xe4\xdb\x94\xc7\xa0\xb5\x0a\x37\x7d\x41\xff\x07\x00\x00\xff\xff\x84\xe7\x47\xce\xe0\x09\x00\x00")
var __0001_appUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xa4\x56\xc1\x92\xaa\x3a\x10\xdd\xf3\x15\xbd\xd4\x2a\x36\x6f\x3d\x2b\xd4\xe8\x50\x8f\x07\xef\x22\xde\x99\x59\xa5\x22\x44\xa5\x04\x92\x49\xe2\x38\xfe\xfd\xad\x00\x01\x54\xc0\xb1\xee\x8e\xa4\x3b\xc7\x73\x4e\x77\x3a\xce\x43\xe4\x44\x08\x22\x67\xe6\x21\x70\x97\xe0\x07\x11\xa0\x77\x77\x1d\xad\x41\x52\xa5\xd2\x62\x2f\x61\x62\xa9\x0b\xa7\xf0\xdb\x09\xe7\xaf\x4e\x08\xff\x87\xee\x7f\x4e\xf8\x01\xff\xa2\x0f\xdb\xfa\x22\xd9\x89\xc2\xcc\x0b\x66\xd6\x14\xde\xdc\xe8\x35\xd8\x44\x10\x06\x6f\xee\xe2\xc5\xb2\x46\xc0\x49\x1c\xb3\x53\xa1\x34\x38\x49\x12\x41\xa5\xec\xc7\x3f\x93\x2c\xa3\x0a\x66\x41\xe0\x21\xc7\xb7\xad\xf8\x40\x3a\xab\x92\x57\x84\xde\x23\xdb\x92\x8a\x09\xb2\x37\x2b\x7e\xda\x1e\xe9\xa5\xe4\x65\x5b\x9c\xa8\x43\xbd\x5f\x90\xdc\xa4\xc4\x2c\x63\xa2\xfc\x1e\x66\xbe\xf1\xdd\x5f\x1b\x04\xae\xbf\x40\xef\x70\x2a\xd2\xcf\x13\xc5\x15\x23\x6c\x58\x07\x7e\x47\x4b\x15\x9b\xc2\xdb\x2b\x0a\x51\xb3\x7c\x19\x83\xd3\x82\xfa\xc1\x74\xa4\x81\x2a\x17\xe3\x96\x6e\x05\x3b\x4b\x2a\xb4\xa5\x69\x52\x0a\xbb\xb6\xb2\xd1\x5e\x1e\xf2\x37\x9e\x67\x5b\x2a\xcd\xa9\x54\x24\xe7\xb0\x59\xaf\xdc\x95\x8f\x16\x30\x73\x57\xae\x1f\xd9\x56\x42\x38\x37\x4e\xc3\x02\x2d\x9d\x8d\x17\xc1\x8e\x64\x92\xda\xd6\x21\xd5\x76\x5f\xdc\x22\xa1\xdf\xb0\xf1\xd7\xd5\x49\xd7\x1f\xb1\x72\x8c\x31\xae\xf1\x60\x62\xd5\x5b\xd8\x28\x68\xa9\x9a\x9c\xaa\x7a\xcb\x20\x44\xee\xca\xd7\xca\x26\xed\x99\x29\x84\x68\x89\x42\xe4\xcf\x51\x8b\x3e\xd1\xfb\x81\xd6\xe0\xa1\x08\xc1\xdc\x59\xcf\x9d\x05\xb2\x1e\xb8\xa9\xe5\x6b\x2b\x5b\xd7\x3a\x66\x3e\x27\x93\x53\x91\xa7\x52\xa6\xac\xd0\x80\x1a\x18\xf7\xd5\xa2\x4d\xbb\x8d\x74\xc5\x36\xc7\xaf\xb4\x96\x6c\x27\xd5\x76\xbf\xd4\x31\x82\x4a\x90\x42\xee\xaa\xd6\x29\xa8\x3a\x33\x71\xd4\x05\x68\x0a\x5b\xb5\x44\xb7\x16\x44\x1e\x9a\xfb\xda\x6e\xdf\xde\xe4\x36\xb2\xcd\x8e\x78\xe0\x90\xfa\xae\xaf\xa9\xa4\x45\x42\x45\x4f\x86\xa0\x31\x4d\xb9\xaa\xd3\x32\xb6\xaf\xbf\xae\xa6\x52\xbf\x5b\xad\x1a\xdb\x50\xb8\xee\x91\x8c\xc5\x47\xd9\x4d\xab\x52\xee\x3c\xb4\xad\x79\xe0\xaf\xa3\xd0\xd1\x46\xd4\x57\xd7\xd8\x86\x39\x15\xe6\x0a\x97\xdf\x35\x9c\xb9\xef\x13\x8d\x69\xd7\x09\x76\xfb\x5b\xd3\x47\x3d\x58\xb1\xfb\xcb\xa2\x14\xa7\x7c\x4b\xc5\x7d\x7a\xe7\xea\x0f\x43\x52\x92\x94\x33\xa0\x19\x00\x4b\xc7\x5b\xf7\x9a\x51\x72\xed\x55\x7f\x6b\xee\xe0\xe1\x8a\xe9\x23\x8c\x2a\xeb\xa1\x77\x66\x8e\x62\xc5\xf0\x73\x3e\x8e\x77\xf1\x90\x9d\xf2\x52\xc4\x50\x0e\xce\x91\xfe\xab\xb9\x8f\x77\xa0\x49\xfa\x51\x0f\xe6\x84\xf3\xb4\xd8\xe3\x1d\x13\xb8\x96\xdc\x28\xee\x75\xd2\xb4\x61\x4b\xe7\x99\x8e\xcc\x49\x9a\x49\x2a\xbe\xaa\x59\x01\x00\x90\x26\xfd\x0f\xb7\x8e\x95\x53\xee\xde\x46\x1d\x1a\x36\x59\x47\x39\x91\xf2\xcc\x44\x03\x5d\xed\xee\x32\x4a\xd5\xdd\x89\xe7\x66\x71\x2b\x00\x0b\xfa\x79\xa2\x52\xe1\x3d\xe1\x46\xcc\x9e\x70\xbc\x13\x2c\xbf\x7a\xd3\xd0\x0a\xdd\xf2\xd3\x79\x8a\x3d\xca\xea\x7d\x85\x75\xa0\x7c\xf3\x6f\x5f\xb8\x61\x1d\xd5\xff\x85\x01\xe6\xb8\x06\xc3\x69\xf2\xad\x5b\x66\x50\x60\x9d\xf7\xe3\x02\x63\xc5\x78\x1a\x1b\x67\xca\xc5\x70\xa5\x6b\x70\x79\x5d\xb0\x8c\x48\x65\x58\x34\x1e\x99\x49\xf2\xcf\xbd\xe0\x3f\x01\x00\x00\xff\xff\xa9\x9c\x70\x28\x8d\x0a\x00\x00")
func _0001_appUpSqlBytes() ([]byte, error) {
return bindataRead(
@ -106,8 +106,8 @@ func _0001_appUpSql() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "0001_app.up.sql", size: 2528, mode: os.FileMode(0644), modTime: time.Unix(1567586073, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x54, 0xe5, 0x59, 0x10, 0xba, 0x9c, 0x1b, 0xb7, 0x11, 0x7a, 0x4d, 0xe4, 0x4c, 0xc3, 0x8f, 0xab, 0x5, 0x1b, 0xcc, 0x80, 0x4a, 0xea, 0x35, 0xbd, 0x13, 0xed, 0xe1, 0x92, 0xd9, 0x25, 0xf3, 0xa9}}
info := bindataFileInfo{name: "0001_app.up.sql", size: 2701, mode: os.FileMode(0644), modTime: time.Unix(1567620191, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x36, 0xdf, 0xa0, 0x6b, 0x3f, 0x6a, 0x1, 0xa, 0x8, 0xae, 0x78, 0xe5, 0xea, 0x9c, 0x51, 0xcf, 0xef, 0x46, 0x16, 0xad, 0xa0, 0xc6, 0x98, 0xb4, 0xd1, 0xd2, 0xbd, 0x18, 0x1f, 0xe0, 0x16, 0x8f}}
return a, nil
}
@ -126,7 +126,7 @@ func docGo() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "doc.go", size: 74, mode: os.FileMode(0644), modTime: time.Unix(1566455715, 0)}
info := bindataFileInfo{name: "doc.go", size: 74, mode: os.FileMode(0644), modTime: time.Unix(1566753968, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xde, 0x7c, 0x28, 0xcd, 0x47, 0xf2, 0xfa, 0x7c, 0x51, 0x2d, 0xd8, 0x38, 0xb, 0xb0, 0x34, 0x9d, 0x4c, 0x62, 0xa, 0x9e, 0x28, 0xc3, 0x31, 0x23, 0xd9, 0xbb, 0x89, 0x9f, 0xa0, 0x89, 0x1f, 0xe8}}
return a, nil
}

View file

@ -8,5 +8,6 @@ DROP TABLE transfers;
DROP TABLE blocks;
DROP TABLE accounts_to_blocks;
DROP TABLE mailservers;
DROP INDEX mailserver_request_gaps_chat_id_idx;
DROP TABLE mailserver_request_gaps;
DROP INDEX mailserver_request_gaps_chat_id_idx;
DROP TABLE mailserver_topics;

View file

@ -82,13 +82,19 @@ CREATE TABLE IF NOT EXISTS mailservers (
address VARCHAR NOT NULL,
password VARCHAR,
fleet VARCHAR NOT NULL
);
) WITHOUT ROWID;
CREATE TABLE IF NOT EXISTS mailserver_request_gaps (
gap_from UNSIGNED INTEGER NOT NULL,
gap_to UNSIGNED INTEGER NOT NULL,
id TEXT PRIMARY KEY,
chat_id TEXT NOT NULL
) WITHOUT ROWID;
gap_from UNSIGNED INTEGER NOT NULL,
gap_to UNSIGNED INTEGER NOT NULL,
id TEXT PRIMARY KEY,
chat_id TEXT NOT NULL
) WITHOUT ROWID;
CREATE INDEX mailserver_request_gaps_chat_id_idx ON mailserver_request_gaps (chat_id);
CREATE TABLE IF NOT EXISTS mailserver_topics (
topic VARCHAR PRIMARY KEY,
chat_ids VARCHAR,
last_request INTEGER DEFAULT 1
) WITHOUT ROWID;

View file

@ -24,15 +24,14 @@ Enabling service will expose three additional methods:
#### mailservers_addMailserver
Stores `Mailserver` in the database.
All fields are specified below:
```json
{
"id": "1",
"name": "my mailserver",
"address": "enode://...",
"password": "some-pass",
"fleet": "beta"
"id": "1",
"name": "my mailserver",
"address": "enode://...",
"password": "some-pass",
"fleet": "beta"
}
```
@ -79,3 +78,22 @@ Deletes all MailserverRequestGaps specified by IDs.
#### mailservers_deleteMailserverRequestGapsByChatID
Deletes all MailserverRequestGaps specified by chatID.
#### mailservers_addMailserverTopic
Stores `MailserverTopic` in the database.
```json
{
"topic": "topic-as-string",
"chat-ids": ["a", "list", "of", "chatIDs"],
"last-request": 1
}
```
#### mailservers_getMailserverTopics
Reads all saved mailserver topics.
#### mailservers_deleteMailserverTopic
Deletes a mailserver topic using `topic` as an identifier.

View file

@ -28,7 +28,7 @@ func (a *API) AddMailserverRequestGaps(ctx context.Context, gaps []MailserverReq
}
func (a *API) GetMailserverRequestGaps(ctx context.Context, chatID string) ([]MailserverRequestGap, error) {
return a.db.MailserverRequestGaps(chatID)
return a.db.RequestGaps(chatID)
}
func (a *API) DeleteMailserverRequestGaps(ctx context.Context, ids []string) error {
@ -38,3 +38,15 @@ func (a *API) DeleteMailserverRequestGaps(ctx context.Context, ids []string) err
func (a *API) DeleteMailserverRequestGapsByChatID(ctx context.Context, chatID string) error {
return a.db.DeleteGapsByChatID(chatID)
}
func (a *API) AddMailserverTopic(ctx context.Context, topic MailserverTopic) error {
return a.db.AddTopic(topic)
}
func (a *API) GetMailserverTopics(ctx context.Context) ([]MailserverTopic, error) {
return a.db.Topics()
}
func (a *API) DeleteMailserverTopic(ctx context.Context, topic string) error {
return a.db.DeleteTopic(topic)
}

View file

@ -103,3 +103,31 @@ func TestAddGetDeleteMailserverRequestGap(t *testing.T) {
require.NoError(t, err)
require.Len(t, actualGaps, 0)
}
func TestAddGetDeleteMailserverTopics(t *testing.T) {
db, close := setupTestDB(t)
defer close()
api := &API{db: db}
testTopic := MailserverTopic{
Topic: "topic-001",
ChatIDs: []string{"chatID01", "chatID02"},
LastRequest: 10,
}
err := api.AddMailserverTopic(context.Background(), testTopic)
require.NoError(t, err)
// Verify topics were added.
topics, err := api.GetMailserverTopics(context.Background())
require.NoError(t, err)
require.EqualValues(t, []MailserverTopic{testTopic}, topics)
err = api.DeleteMailserverTopic(context.Background(), testTopic.Topic)
require.NoError(t, err)
topics, err = api.GetMailserverTopics(context.Background())
require.NoError(t, err)
require.EqualValues(t, ([]MailserverTopic)(nil), topics)
// Delete non-existing topic.
err = api.DeleteMailserverTopic(context.Background(), "non-existing-topic")
require.NoError(t, err)
}

View file

@ -2,6 +2,9 @@ package mailservers
import (
"database/sql"
"database/sql/driver"
"encoding/json"
"errors"
"fmt"
"strings"
)
@ -14,6 +17,14 @@ type Mailserver struct {
Fleet string `json:"fleet"`
}
func (m Mailserver) nullablePassword() (val sql.NullString) {
if m.Password != "" {
val.String = m.Password
val.Valid = true
}
return
}
type MailserverRequestGap struct {
ID string `json:"id"`
ChatID string `json:"chatId"`
@ -21,12 +32,31 @@ type MailserverRequestGap struct {
To uint64 `json:"to"`
}
func (m Mailserver) nullablePassword() (val sql.NullString) {
if m.Password != "" {
val.String = m.Password
val.Valid = true
type MailserverTopic struct {
Topic string `json:"topic"`
ChatIDs []string `json:"chat-ids"`
LastRequest int `json:"last-request"` // default is 1
}
// sqlStringSlice helps to serialize a slice of strings into a single column using JSON serialization.
type sqlStringSlice []string
// Scan implements the Scanner interface.
func (ss *sqlStringSlice) Scan(value interface{}) error {
if value == nil {
*ss = nil
return nil
}
return
src, ok := value.([]byte)
if !ok {
return errors.New("invalid value type, expected byte slice")
}
return json.Unmarshal(src, ss)
}
// Value implements the driver Valuer interface.
func (ss sqlStringSlice) Value() (driver.Value, error) {
return json.Marshal(ss)
}
// Database sql wrapper for operations with mailserver objects.
@ -126,7 +156,7 @@ func (d *Database) AddGaps(gaps []MailserverRequestGap) error {
return nil
}
func (d *Database) MailserverRequestGaps(chatID string) ([]MailserverRequestGap, error) {
func (d *Database) RequestGaps(chatID string) ([]MailserverRequestGap, error) {
var result []MailserverRequestGap
rows, err := d.db.Query(`SELECT id, chat_id, gap_from, gap_to FROM mailserver_request_gaps WHERE chat_id = ?`, chatID)
@ -170,3 +200,49 @@ func (d *Database) DeleteGapsByChatID(chatID string) error {
_, err := d.db.Exec(`DELETE FROM mailserver_request_gaps WHERE chat_id = ?`, chatID)
return err
}
func (d *Database) AddTopic(topic MailserverTopic) error {
chatIDs := sqlStringSlice(topic.ChatIDs)
_, err := d.db.Exec(`INSERT OR REPLACE INTO mailserver_topics(
topic,
chat_ids,
last_request
) VALUES (?, ?, ?)`,
topic.Topic,
chatIDs,
topic.LastRequest,
)
return err
}
func (d *Database) Topics() ([]MailserverTopic, error) {
var result []MailserverTopic
rows, err := d.db.Query(`SELECT topic, chat_ids, last_request FROM mailserver_topics`)
if err != nil {
return nil, err
}
for rows.Next() {
var (
t MailserverTopic
chatIDs sqlStringSlice
)
if err := rows.Scan(
&t.Topic,
&chatIDs,
&t.LastRequest,
); err != nil {
return nil, err
}
t.ChatIDs = chatIDs
result = append(result, t)
}
return result, nil
}
func (d *Database) DeleteTopic(topic string) error {
_, err := d.db.Exec(`DELETE FROM mailserver_topics WHERE topic = ?`, topic)
return err
}