db.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. package main
  2. import (
  3. "database/sql"
  4. "strings"
  5. "time"
  6. "github.com/emersion/go-imap"
  7. _ "github.com/mattn/go-sqlite3"
  8. )
  9. func migrate() (*sql.DB, error) {
  10. db, err := open()
  11. _, err = db.Exec(`create table tyr_knownAddresses(address_from text, address_to text, ban boolean, unique(address, direction))`)
  12. if err != nil && err.Error() != "table tyr_knownAddresses already exists" {
  13. return nil, err
  14. }
  15. _, err = db.Exec(`create table tyr_locks(address text unique, token text, date date)`)
  16. if err != nil && err.Error() != "table tyr_locks already exists" {
  17. return nil, err
  18. }
  19. _, err = db.Exec(`create table mimir_archive(message_id text primary key, subject text, body text, date datetime, in_reply_to text, dkim_status bool, sender text, recipients text, root_id text, foreign key(in_reply_to) references mimir_archive(message_id))`)
  20. if err != nil && err.Error() != "table mimir_archive already exists" {
  21. return nil, err
  22. }
  23. return db, nil
  24. }
  25. func open() (*sql.DB, error) {
  26. db, err := sql.Open("sqlite3", "asgard.db")
  27. if err != nil {
  28. return nil, err
  29. }
  30. return db, nil
  31. }
  32. func getAddressLock(db *sql.DB, address string) (Lock, error) {
  33. address = strings.ToLower(address)
  34. lock := Lock{
  35. address: address,
  36. }
  37. row := db.QueryRow(`select token, date from tyr_locks where address = ?`, address)
  38. err := row.Scan(&lock.token, &lock.date)
  39. if err == sql.ErrNoRows {
  40. return Lock{}, nil
  41. } else {
  42. return lock, err
  43. }
  44. }
  45. func getLock(db *sql.DB, token string) (Lock, error) {
  46. lock := Lock{
  47. token: token,
  48. }
  49. row := db.QueryRow(`select address, date from tyr_locks where token = ?`, token)
  50. err := row.Scan(&lock.address, &lock.date)
  51. if err == sql.ErrNoRows {
  52. return Lock{}, nil
  53. } else {
  54. return lock, err
  55. }
  56. }
  57. func listLocks(db *sql.DB) ([]Lock, error) {
  58. locks := []Lock{}
  59. rows, err := db.Query(`select address, token from tyr_locks`)
  60. if err != nil {
  61. return locks, err
  62. }
  63. for rows.Next() {
  64. lock := Lock{}
  65. err := rows.Scan(&lock.address, &lock.token)
  66. if err != nil {
  67. return locks, err
  68. }
  69. locks = append(locks, lock)
  70. }
  71. return locks, nil
  72. }
  73. func insertLock(db *sql.DB, lock Lock) error {
  74. _, err := db.Exec(`insert into tyr_locks values(?, ?, ?) on
  75. conflict(address) do nothing`,
  76. lock.address, lock.token, lock.date)
  77. return err
  78. }
  79. func deleteLock(db *sql.DB, lock Lock) error {
  80. _, err := db.Exec(`delete from tyr_locks where address = ?`, lock.address)
  81. return err
  82. }
  83. func updateLock(db *sql.DB, lock Lock) error {
  84. _, err := db.Exec(`update tyr_locks set date = ? where address = ?`, lock.date, lock.address)
  85. return err
  86. }
  87. func getKnownAddress(db *sql.DB, address string) ([]KnownAddress, error) {
  88. knownAddresses := []KnownAddress{}
  89. rows, err := db.Query(`select address_from, address_to, ban from tyr_knownAddresses where address_from = ?`, address)
  90. if err != nil {
  91. return []KnownAddress{}, err
  92. }
  93. for rows.Next() {
  94. knownAddress := KnownAddress{}
  95. err := rows.Scan(&knownAddress.addressFrom, &knownAddress.addressTo, &knownAddress.ban)
  96. if err != nil {
  97. return []KnownAddress{}, err
  98. }
  99. knownAddresses = append(knownAddresses, knownAddress)
  100. }
  101. return knownAddresses, nil
  102. }
  103. func insertKnownAddress(db *sql.DB, address KnownAddress) error {
  104. _, err := db.Exec(`insert into tyr_knownAddresses values(?, ?, ?) on
  105. conflict(address_to, address_from) do nothing`,
  106. address.addressFrom, address.addressTo, address.ban)
  107. return err
  108. }
  109. func addArchiveEntry(db *sql.DB, messageID, category, subject string, body []byte, date time.Time, inReplyTo string, dkim bool, sender *imap.Address, recipients []*imap.Address) error {
  110. recipientsAddresses := []string{}
  111. for _, recipient := range recipients {
  112. recipientsAddresses = append(recipientsAddresses, recipient.Address())
  113. }
  114. recipientsJoined := strings.Join(recipientsAddresses, ", ")
  115. var rootID string
  116. row := db.QueryRow(`select root_id from mimir_archive where message_id = ?`, inReplyTo)
  117. err := row.Scan(&rootID)
  118. if err != nil {
  119. if err == (sql.ErrNoRows) {
  120. rootID = messageID
  121. } else {
  122. return err
  123. }
  124. }
  125. db.Exec(`insert inti mimir_archive values(?, ?, ?, ?, ?, ?, ?, ?, ?)`, messageID, subject, body, date, inReplyTo, dkim, sender, recipientsJoined, rootID)
  126. return nil
  127. }