28 #include <unordered_map>
36 class WriteStreamSQLite :
public WriteStream {
64 default: value =
tuple[
i];
break;
67 #if RAM_DOMAIN_SIZE == 64
72 throwError(
"SQLite error in sqlite3_bind_text: ");
84 assert(
db &&
"Database connection is closed");
86 char* errorMessage =
nullptr;
88 int rc = sqlite3_exec(
db, sql.c_str(),
nullptr,
nullptr, &errorMessage);
89 if (rc != SQLITE_OK) {
90 std::stringstream error;
91 error <<
"SQLite error in sqlite3_exec: " << sqlite3_errmsg(
db) <<
"\n";
92 error <<
"SQL error: " << errorMessage <<
"\n";
93 error <<
"SQL: " << sql <<
"\n";
94 sqlite3_free(errorMessage);
95 throw std::invalid_argument(error.str());
100 std::stringstream error;
101 error << message << sqlite3_errmsg(
db) <<
"\n";
102 throw std::invalid_argument(error.str());
107 SQLITE_TRANSIENT) != SQLITE_OK) {
108 throwError(
"SQLite error in sqlite3_bind_text: ");
124 SQLITE_TRANSIENT) != SQLITE_OK) {
125 throwError(
"SQLite error in sqlite3_bind_text: ");
133 rowid = sqlite3_last_insert_rowid(
db);
143 if (sqlite3_open(
dbFilename.c_str(), &
db) != SQLITE_OK) {
146 sqlite3_extended_result_codes(
db, 1);
157 std::stringstream insertSQL;
159 insertSQL <<
" VALUES(null,@V0);";
162 throwError(
"SQLite error in sqlite3_prepare_v2: ");
167 std::stringstream selectSQL;
169 selectSQL <<
" WHERE symbol = @V0;";
172 throwError(
"SQLite error in sqlite3_prepare_v2: ");
177 std::stringstream insertSQL;
178 insertSQL <<
"INSERT INTO '_" <<
relationName <<
"' VALUES ";
181 insertSQL <<
",@V" <<
i;
184 const char*
tail =
nullptr;
186 throwError(
"SQLite error in sqlite3_prepare_v2: ");
197 std::stringstream createTableText;
198 createTableText <<
"CREATE TABLE IF NOT EXISTS '_" <<
relationName <<
"' (";
200 createTableText <<
"'0' INTEGER";
201 for (
unsigned int i = 1;
i <
arity;
i++) {
202 createTableText <<
",'" << std::to_string(
i) <<
"' ";
203 createTableText <<
"INTEGER";
206 createTableText <<
");";
213 std::stringstream createViewText;
214 createViewText <<
"CREATE VIEW IF NOT EXISTS '" <<
relationName <<
"' AS ";
215 std::stringstream projectionClause;
216 std::stringstream fromClause;
218 std::stringstream whereClause;
219 bool firstWhere =
true;
220 for (
unsigned int i = 0;
i <
arity;
i++) {
221 std::string columnName = std::to_string(
i);
223 projectionClause <<
",";
226 projectionClause <<
"'_symtab_" << columnName <<
"'.symbol AS '" << columnName <<
"'";
227 fromClause <<
",'" <<
symbolTableName <<
"' AS '_symtab_" << columnName <<
"'";
229 whereClause <<
" AND ";
233 whereClause <<
"'_" <<
relationName <<
"'.'" << columnName <<
"' = "
234 <<
"'_symtab_" << columnName <<
"'.id";
236 projectionClause <<
"'_" <<
relationName <<
"'.'" << columnName <<
"'";
239 createViewText <<
"SELECT " << projectionClause.str() <<
" FROM " << fromClause.str();
241 createViewText <<
" WHERE " << whereClause.str();
243 createViewText <<
";";
247 std::stringstream createTableText;
248 createTableText <<
"CREATE TABLE IF NOT EXISTS '" <<
symbolTableName <<
"' ";
249 createTableText <<
"(id INTEGER PRIMARY KEY, symbol TEXT UNIQUE);";
260 static std::string
getFileName(
const std::map<std::string, std::string>& rwOperation) {
263 auto name =
getOr(rwOperation,
"dbname", rwOperation.at(
"name") +
".sqlite");
264 name =
getOr(rwOperation,
"filename", name);
266 if (name.front() !=
'/') {
267 name =
getOr(rwOperation,
"output-dir",
".") +
"/" + name;
280 sqlite3*
db =
nullptr;
285 Own<WriteStream> getWriter(
const std::map<std::string, std::string>& rwOperation,
290 const std::string& getName()
const override {
291 static const std::string name =
"sqlite";