Synchronize notmuch mail across machines
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

sql_db.h 4.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. // -*- C++ -*-
  2. #ifndef _SQL_DB_H
  3. #define _SQL_DB_H 1
  4. /** \file sql_db.h
  5. * \brief Data structures representing information in SQL database.
  6. */
  7. #include <exception>
  8. #include <iosfwd>
  9. #include <fstream>
  10. #include <string>
  11. #include <unordered_map>
  12. #include <unordered_set>
  13. #include <vector>
  14. #include "sqlstmt.h"
  15. using std::string;
  16. extern const char dbvers[];
  17. /** Writestamp is the pair (replica-id, version-number). */
  18. using writestamp = std::pair<i64,i64>;
  19. std::istream &read_writestamp (std::istream &in, writestamp &ws);
  20. /** A version vector is a set of ::writestamps with distinct
  21. * replica-ids.
  22. */
  23. using versvector = std::unordered_map<i64,i64>;
  24. string show_sync_vector (const versvector &vv);
  25. std::istream &read_sync_vector (std::istream &sb, versvector &vv);
  26. versvector get_sync_vector (sqlite3 *db);
  27. /** Open the SQL database containing muchsync state.
  28. *
  29. * If the file does not exist, it is created and initialized with a
  30. * fresh database.
  31. */
  32. sqlite3 *dbopen (const char *path, bool exclusive = false);
  33. /** Retrieve a configuration value from the database.
  34. *
  35. * Example: `getconfig<i64>(db, "key")`
  36. */
  37. template<typename T> T
  38. getconfig (sqlite3 *db, const string &key)
  39. {
  40. static const char query[] = "SELECT value FROM configuration WHERE key = ?;";
  41. return sqlstmt_t(db, query).param(key).step().template column<T>(0);
  42. }
  43. /** Set a configuration value in database. */
  44. template<typename T> void
  45. setconfig (sqlite3 *db, const string &key, const T &value)
  46. {
  47. static const char query[] =
  48. "INSERT OR REPLACE INTO configuration VALUES (?, ?);";
  49. sqlstmt_t(db, query).param(key, value).step();
  50. }
  51. /** Structure representing all occurences of a file with a particular
  52. * content hash in the maildir. */
  53. struct hash_info {
  54. string hash;
  55. i64 size = -1;
  56. string message_id;
  57. writestamp hash_stamp = {0, 0};
  58. std::unordered_map<string,i64> dirs;
  59. };
  60. /** Pre-formatted queries for looking up ::hash_info structures in
  61. * database. */
  62. class hash_lookup {
  63. sqlstmt_t gethash_;
  64. sqlstmt_t getlinks_;
  65. sqlstmt_t makehash_;
  66. bool ok_ = false;
  67. hash_info hi_;
  68. i64 hash_id_;
  69. std::vector<std::pair<string,string>> links_;
  70. std::ifstream content_;
  71. i64 docid_;
  72. public:
  73. const string maildir;
  74. hash_lookup(const string &maildir, sqlite3 *db);
  75. bool lookup(const string &hash);
  76. void create(const hash_info &info);
  77. bool ok() const { return ok_; }
  78. i64 hash_id() const { assert (ok()); return hash_id_; }
  79. const hash_info &info() const { assert (ok()); return hi_; }
  80. const std::vector<std::pair<string,string>> &links() const {
  81. assert (ok());
  82. return links_;
  83. }
  84. i64 docid() const { assert (nlinks()); return docid_; }
  85. int nlinks() const { return links().size(); }
  86. string link_path(int i) const {
  87. auto &lnk = links().at(i);
  88. return maildir + "/" + lnk.first + "/" + lnk.second;
  89. }
  90. bool get_pathname(string *path, bool *from_trash = nullptr) const;
  91. std::streambuf *content();
  92. };
  93. /** Structure representing all the tags associated with a particular
  94. * message ID in the database.
  95. *
  96. * Note that multiple content hashes may contain the same message ID.
  97. */
  98. struct tag_info {
  99. string message_id;
  100. writestamp tag_stamp = {0, 0};
  101. std::unordered_set<string> tags;
  102. };
  103. /** Pre-formatted queries for looking up ::tag_info structures in
  104. * database. */
  105. class tag_lookup {
  106. sqlstmt_t getmsg_;
  107. sqlstmt_t gettags_;
  108. bool ok_ = false;
  109. tag_info ti_;
  110. i64 docid_;
  111. public:
  112. tag_lookup (sqlite3 *db);
  113. bool lookup(const string &msgid);
  114. bool ok() const { return ok_; }
  115. i64 docid() const { assert (ok()); return docid_; }
  116. const tag_info &info() const { assert (ok()); return ti_; }
  117. };
  118. std::ostream &operator<< (std::ostream &os, const hash_info &hi);
  119. std::istream &operator>> (std::istream &is, hash_info &hi);
  120. std::ostream &operator<< (std::ostream &os, const tag_info &ti);
  121. std::istream &operator>> (std::istream &is, tag_info &ti);
  122. string trashname (const string &maildir, const string &hash);
  123. string permissive_percent_encode (const string &raw);
  124. i64 create_random_id ();
  125. #endif /* !_SQL_DB_H */