sqlite.hh 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. #pragma once
  2. #include <functional>
  3. #include <string>
  4. #include "types.hh"
  5. class sqlite3;
  6. class sqlite3_stmt;
  7. namespace nix {
  8. /* RAII wrapper to close a SQLite database automatically. */
  9. struct SQLite
  10. {
  11. sqlite3 * db;
  12. SQLite() { db = 0; }
  13. ~SQLite();
  14. operator sqlite3 * () { return db; }
  15. };
  16. /* RAII wrapper to create and destroy SQLite prepared statements. */
  17. struct SQLiteStmt
  18. {
  19. sqlite3 * db = 0;
  20. sqlite3_stmt * stmt = 0;
  21. SQLiteStmt() { }
  22. void create(sqlite3 * db, const std::string & s);
  23. ~SQLiteStmt();
  24. operator sqlite3_stmt * () { return stmt; }
  25. /* Helper for binding / executing statements. */
  26. class Use
  27. {
  28. friend struct SQLiteStmt;
  29. private:
  30. SQLiteStmt & stmt;
  31. unsigned int curArg = 1;
  32. Use(SQLiteStmt & stmt);
  33. public:
  34. ~Use();
  35. /* Bind the next parameter. */
  36. Use & operator () (const std::string & value, bool notNull = true);
  37. Use & operator () (int64_t value, bool notNull = true);
  38. Use & bind(); // null
  39. int step();
  40. /* Execute a statement that does not return rows. */
  41. void exec();
  42. /* For statements that return 0 or more rows. Returns true iff
  43. a row is available. */
  44. bool next();
  45. std::string getStr(int col);
  46. int64_t getInt(int col);
  47. };
  48. Use use()
  49. {
  50. return Use(*this);
  51. }
  52. };
  53. /* RAII helper that ensures transactions are aborted unless explicitly
  54. committed. */
  55. struct SQLiteTxn
  56. {
  57. bool active = false;
  58. sqlite3 * db;
  59. SQLiteTxn(sqlite3 * db);
  60. void commit();
  61. ~SQLiteTxn();
  62. };
  63. MakeError(SQLiteError, Error);
  64. MakeError(SQLiteBusy, SQLiteError);
  65. [[noreturn]] void throwSQLiteError(sqlite3 * db, const format & f);
  66. /* Convenience function for retrying a SQLite transaction when the
  67. database is busy. */
  68. template<typename T>
  69. T retrySQLite(std::function<T()> fun)
  70. {
  71. while (true) {
  72. try {
  73. return fun();
  74. } catch (SQLiteBusy & e) {
  75. }
  76. }
  77. }
  78. }