#ifndef QUERY_H_7CC5284C #define QUERY_H_7CC5284C #include #include #include #include #include #include #include "statement.h" #include "binding.h" namespace verbly { class database_error : public std::logic_error { public: database_error(std::string msg, std::string sqlMsg) : std::logic_error(msg + " (" + sqlMsg + ")") { } }; template class query { public: query(const database& db, sqlite3* ppdb, filter queryFilter, bool random, int limit) : db_(&db) { statement stmt(Object::objectType, std::move(queryFilter)); std::string queryString = stmt.getQueryString(Object::select, random, limit); std::list bindings = stmt.getBindings(); std::cout << queryString << std::endl; if (sqlite3_prepare_v2(ppdb, queryString.c_str(), queryString.length(), &ppstmt_, NULL) != SQLITE_OK) { std::string errorMsg = sqlite3_errmsg(ppdb); sqlite3_finalize(ppstmt_); throw database_error("Error preparing query", errorMsg); } int i = 1; for (const binding& value : bindings) { switch (value.getType()) { case binding::type::integer: { if (sqlite3_bind_int(ppstmt_, i, value.getInteger()) != SQLITE_OK) { std::string errorMsg = sqlite3_errmsg(ppdb); sqlite3_finalize(ppstmt_); throw database_error("Error binding value to query", errorMsg); } break; } case binding::type::string: { if (sqlite3_bind_text(ppstmt_, i, value.getString().c_str(), value.getString().length(), SQLITE_TRANSIENT) != SQLITE_OK) { std::string errorMsg = sqlite3_errmsg(ppdb); sqlite3_finalize(ppstmt_); throw database_error("Error binding value to query", errorMsg); } break; } case binding::type::invalid: { throw std::logic_error("Cannot use invalid bindings"); } } i++; } } ~query() { sqlite3_finalize(ppstmt_); } std::vector all() const { std::vector result; while (sqlite3_step(ppstmt_) == SQLITE_ROW) { result.emplace_back(*db_, ppstmt_); } sqlite3_reset(ppstmt_); return result; } Object first() const { std::vector results = all(); if (!results.empty()) { return results.front(); } else { throw std::logic_error("query returned empty dataset"); } } private: const database* db_; sqlite3_stmt* ppstmt_; }; }; #endif /* end of include guard: QUERY_H_7CC5284C */ rm>
blob: 491847643cba9b4e26a4ee167c72abc4490477b2 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
name: "Puzzle Room"
panels {
  name: "LIONESS"
  path: "Panels/entry_1"
  clue: "lioness"
  answer: "lion"
  symbols: GENDER
}
panels {
  name: "QUEEN"
  path: "Panels/entry_2"
  clue: "queen"
  answer: "king"
  symbols: GENDER
}
panels {
  name: "SOPRANO"
  path: "Panels/entry_3"
  clue: "soprano"
  answer: "tenor"
  symbols: GENDER
}
panels {
  name: "AUNT"
  path: "Panels/entry_4"
  clue: "aunt"
  answer: "uncle"
  symbols: GENDER
}
panels {
  name: "SON"
  path: "Panels/entry_5"
  clue: "son"
  answer: "daughter"
  symbols: GENDER
}
panels {
  name: "BASS"
  path: "Panels/entry_6"
  clue: "bass"
  answer: "alto"
  symbols: GENDER
}
panels {
  name: "FATHER"
  path: "Panels/entry_7"
  clue: "father"
  answer: "mother"
  symbols: GENDER
}
panels {
  name: "ROOSTER"
  path: "Panels/entry_8"
  clue: "rooster"
  answer: "hen"
  symbols: GENDER
}
ports {
  name: "BETWEEN"
  display_name: "Entrance"
  path: "Components/Warps/worldport"
  destination { x: 0 y: 0 z: 6.5 }
  rotation: 0
}