1 #include "sqlstorage.h" 10 #include "logging/logging.h" 11 #include "sql_utils.h" 12 #include "utilities/utils.h" 18 db.beginTransaction();
20 auto statement = db.prepareStatement<int, int,
int>(
21 "SELECT meta FROM meta WHERE (repo=? AND meta_type=? AND version=?);",
static_cast<int>(repo), role.ToInt(), -1);
23 int result = statement.step();
25 if (result == SQLITE_DONE) {
26 LOG_TRACE <<
"meta with role " << role.ToString() <<
" in repo " << repo.toString() <<
" not present in db";
28 }
else if (result != SQLITE_ROW) {
29 LOG_ERROR <<
"Can't get meta: " << db.errmsg();
32 std::string meta = std::string(reinterpret_cast<const char*>(sqlite3_column_blob(statement.get(), 0)));
34 int version = Uptane::extractVersionUntrusted(meta);
36 LOG_ERROR <<
"Corrupted metadata";
41 statement = db.prepareStatement<int, int,
int>(
"DELETE FROM meta WHERE (repo=? AND meta_type=? AND version=?);",
42 static_cast<int>(repo), role.ToInt(), version);
44 if (statement.step() != SQLITE_DONE) {
45 LOG_ERROR <<
"Can't clear metadata: " << db.errmsg();
49 statement = db.prepareStatement<int, int, int,
int>(
50 "UPDATE meta SET version = ? WHERE (repo=? AND meta_type=? AND version=?);", version,
static_cast<int>(repo),
53 if (statement.step() != SQLITE_DONE) {
54 LOG_ERROR <<
"Can't update metadata: " << db.errmsg();
58 db.commitTransaction();
61 SQLStorage::SQLStorage(
const StorageConfig& config,
bool readonly)
62 :
SQLStorageBase(config.sqldb_path.get(config.path), readonly, libaktualizr_schema_migrations,
63 libaktualizr_schema_rollback_migrations, libaktualizr_current_schema,
64 libaktualizr_current_schema_version),
67 cleanMetaVersion(Uptane::RepositoryType::Director(), Uptane::Role::Root());
68 cleanMetaVersion(Uptane::RepositoryType::Image(), Uptane::Role::Root());
70 LOG_ERROR <<
"SQLite database metadata version migration failed";
74 void SQLStorage::storePrimaryKeys(
const std::string& public_key,
const std::string& private_key) {
77 auto statement = db.prepareStatement<std::string>(
78 "INSERT OR REPLACE INTO primary_keys(unique_mark,public,private) VALUES (0,?,?);", public_key, private_key);
79 if (statement.step() != SQLITE_DONE) {
80 LOG_ERROR <<
"Can't set Primary keys: " << db.errmsg();
85 bool SQLStorage::loadPrimaryKeys(std::string* public_key, std::string* private_key)
const {
86 return loadPrimaryPublic(public_key) && loadPrimaryPrivate(private_key);
89 bool SQLStorage::loadPrimaryPublic(std::string* public_key)
const {
92 auto statement = db.prepareStatement(
"SELECT public FROM primary_keys LIMIT 1;");
94 int result = statement.step();
95 if (result == SQLITE_DONE) {
96 LOG_TRACE <<
"No public key in db";
98 }
else if (result != SQLITE_ROW) {
99 LOG_ERROR <<
"Can't get public key: " << db.errmsg();
103 auto pub = statement.get_result_col_str(0);
104 if (pub == boost::none) {
108 if (public_key !=
nullptr) {
109 *public_key = std::move(pub.value());
115 bool SQLStorage::loadPrimaryPrivate(std::string* private_key)
const {
118 auto statement = db.prepareStatement(
"SELECT private FROM primary_keys LIMIT 1;");
120 int result = statement.step();
121 if (result == SQLITE_DONE) {
122 LOG_TRACE <<
"No private key in db";
124 }
else if (result != SQLITE_ROW) {
125 LOG_ERROR <<
"Can't get private key: " << db.errmsg();
129 auto priv = statement.get_result_col_str(0);
130 if (priv == boost::none) {
134 if (private_key !=
nullptr) {
135 *private_key = std::move(priv.value());
141 void SQLStorage::clearPrimaryKeys() {
144 if (db.exec(
"DELETE FROM primary_keys;",
nullptr,
nullptr) != SQLITE_OK) {
145 LOG_ERROR <<
"Can't clear Primary keys: " << db.errmsg();
150 void SQLStorage::saveSecondaryInfo(
const Uptane::EcuSerial& ecu_serial,
const std::string& sec_type,
154 std::stringstream key_type_ss;
155 key_type_ss << public_key.Type();
156 std::string key_type_str;
157 key_type_str = key_type_ss.str();
158 key_type_str.erase(std::remove(key_type_str.begin(), key_type_str.end(),
'"'), key_type_str.end());
160 db.beginTransaction();
163 db.prepareStatement<std::string>(
"SELECT count(*) FROM secondary_ecus WHERE serial = ?;", ecu_serial.ToString());
164 if (statement.step() != SQLITE_ROW) {
165 throw std::runtime_error(db.errmsg().insert(0,
"Can't get count of secondary_ecus table: "));
169 if (statement.get_result_col_int(0) != 0) {
170 req =
"UPDATE secondary_ecus SET sec_type = ?, public_key_type = ?, public_key = ? WHERE serial = ?;";
173 "INSERT INTO secondary_ecus (serial, sec_type, public_key_type, public_key) SELECT " 174 "serial,?,?,? FROM ecus WHERE (serial = ? AND is_primary = 0);";
177 statement = db.prepareStatement<std::string, std::string, std::string, std::string>(
178 req, sec_type, key_type_str, public_key.Value(), ecu_serial.ToString());
179 if (statement.step() != SQLITE_DONE || sqlite3_changes(db.get()) != 1) {
180 throw std::runtime_error(db.errmsg().insert(0,
"Can't save Secondary key: "));
183 db.commitTransaction();
189 db.beginTransaction();
192 db.prepareStatement<std::string>(
"SELECT count(*) FROM secondary_ecus WHERE serial = ?;", ecu_serial.ToString());
193 if (statement.step() != SQLITE_ROW) {
194 throw std::runtime_error(db.errmsg().insert(0,
"Can't get count of secondary_ecus table: "));
198 if (statement.get_result_col_int(0) != 0) {
199 req =
"UPDATE secondary_ecus SET extra = ? WHERE serial = ?;";
201 req =
"INSERT INTO secondary_ecus (extra, serial) VALUES (?,?);";
204 statement = db.prepareStatement<std::string, std::string>(req, data, ecu_serial.ToString());
205 if (statement.step() != SQLITE_DONE || sqlite3_changes(db.get()) != 1) {
206 throw std::runtime_error(db.errmsg().insert(0,
"Can't save Secondary data: "));
209 db.commitTransaction();
217 auto statement = db.prepareStatement<std::string>(
218 "SELECT serial, hardware_id, sec_type, public_key_type, public_key, extra FROM ecus LEFT JOIN secondary_ecus " 220 "(serial) WHERE (serial = ? AND is_primary = 0);",
221 ecu_serial.ToString());
222 int statement_state = statement.step();
223 if (statement_state == SQLITE_DONE) {
224 LOG_TRACE <<
"Secondary ECU " << ecu_serial <<
" not found";
226 }
else if (statement_state != SQLITE_ROW) {
227 LOG_ERROR <<
"Cannot load Secondary info: " << db.errmsg();
234 std::string sec_type = statement.get_result_col_str(2).value_or(
"");
235 std::string kt_str = statement.get_result_col_str(3).value_or(
"");
239 std::stringstream(kt_str) >> key_type;
240 key =
PublicKey(statement.get_result_col_str(4).value_or(
""), key_type);
242 std::string extra = statement.get_result_col_str(5).value_or(
"");
243 new_sec =
SecondaryInfo{serial, hw_id, sec_type, key, extra};
244 }
catch (
const boost::bad_optional_access&) {
248 if (secondary !=
nullptr) {
249 *secondary = std::move(new_sec);
255 bool SQLStorage::loadSecondariesInfo(std::vector<SecondaryInfo>* secondaries)
const {
258 std::vector<SecondaryInfo> new_secs;
263 auto statement = db.prepareStatement(
264 "SELECT serial, hardware_id, sec_type, public_key_type, public_key, extra FROM ecus LEFT JOIN secondary_ecus " 266 "(serial) WHERE is_primary = 0 ORDER BY ecus.id;");
267 while ((statement_state = statement.step()) == SQLITE_ROW) {
271 std::string sec_type = statement.get_result_col_str(2).value_or(
"");
272 std::string kt_str = statement.get_result_col_str(3).value_or(
"");
276 std::stringstream(kt_str) >> key_type;
277 key =
PublicKey(statement.get_result_col_str(4).value_or(
""), key_type);
279 std::string extra = statement.get_result_col_str(5).value_or(
"");
280 new_secs.emplace_back(
SecondaryInfo{serial, hw_id, sec_type, key, extra});
282 }
catch (
const boost::bad_optional_access&) {
286 if (statement_state != SQLITE_DONE) {
287 LOG_ERROR <<
"Can't load Secondary info" << db.errmsg();
290 if (secondaries !=
nullptr) {
291 *secondaries = std::move(new_secs);
297 void SQLStorage::storeTlsCreds(
const std::string& ca,
const std::string& cert,
const std::string& pkey) {
303 void SQLStorage::storeTlsCa(
const std::string& ca) {
306 db.beginTransaction();
308 auto statement = db.prepareStatement(
"SELECT count(*) FROM tls_creds;");
309 if (statement.step() != SQLITE_ROW) {
310 LOG_ERROR <<
"Can't get count of tls_creds table: " << db.errmsg();
315 if (statement.get_result_col_int(0) != 0) {
316 req =
"UPDATE OR REPLACE tls_creds SET ca_cert = ?;";
318 req =
"INSERT INTO tls_creds(ca_cert) VALUES (?);";
322 if (statement.step() != SQLITE_DONE) {
323 LOG_ERROR <<
"Can't set ca_cert: " << db.errmsg();
327 db.commitTransaction();
330 void SQLStorage::storeTlsCert(
const std::string& cert) {
333 db.beginTransaction();
335 auto statement = db.prepareStatement(
"SELECT count(*) FROM tls_creds;");
336 if (statement.step() != SQLITE_ROW) {
337 LOG_ERROR <<
"Can't get count of tls_creds table: " << db.errmsg();
342 if (statement.get_result_col_int(0) != 0) {
343 req =
"UPDATE OR REPLACE tls_creds SET client_cert = ?;";
345 req =
"INSERT INTO tls_creds(client_cert) VALUES (?);";
349 if (statement.step() != SQLITE_DONE) {
350 LOG_ERROR <<
"Can't set client_cert: " << db.errmsg();
354 db.commitTransaction();
357 void SQLStorage::storeTlsPkey(
const std::string& pkey) {
360 db.beginTransaction();
362 auto statement = db.prepareStatement(
"SELECT count(*) FROM tls_creds;");
363 if (statement.step() != SQLITE_ROW) {
364 LOG_ERROR <<
"Can't get count of tls_creds table: " << db.errmsg();
369 if (statement.get_result_col_int(0) != 0) {
370 req =
"UPDATE OR REPLACE tls_creds SET client_pkey = ?;";
372 req =
"INSERT INTO tls_creds(client_pkey) VALUES (?);";
376 if (statement.step() != SQLITE_DONE) {
377 LOG_ERROR <<
"Can't set client_pkey: " << db.errmsg();
381 db.commitTransaction();
384 bool SQLStorage::loadTlsCreds(std::string* ca, std::string* cert, std::string* pkey)
const {
387 auto statement = db.prepareStatement(
"SELECT ca_cert, client_cert, client_pkey FROM tls_creds LIMIT 1;");
389 int result = statement.step();
390 if (result == SQLITE_DONE) {
391 LOG_TRACE <<
"Tls creds not present";
393 }
else if (result != SQLITE_ROW) {
394 LOG_ERROR <<
"Can't get tls_creds: " << db.errmsg();
402 ca_v = statement.get_result_col_str(0).value();
403 cert_v = statement.get_result_col_str(1).value();
404 pkey_v = statement.get_result_col_str(2).value();
405 }
catch (
const boost::bad_optional_access&) {
410 *ca = std::move(ca_v);
412 if (cert !=
nullptr) {
413 *cert = std::move(cert_v);
415 if (pkey !=
nullptr) {
416 *pkey = std::move(pkey_v);
422 void SQLStorage::clearTlsCreds() {
425 if (db.exec(
"DELETE FROM tls_creds;",
nullptr,
nullptr) != SQLITE_OK) {
426 LOG_ERROR <<
"Can't clear tls_creds: " << db.errmsg();
431 bool SQLStorage::loadTlsCa(std::string* ca)
const {
434 auto statement = db.prepareStatement(
"SELECT ca_cert FROM tls_creds LIMIT 1;");
436 int result = statement.step();
437 if (result == SQLITE_DONE) {
438 LOG_TRACE <<
"ca_cert not present";
440 }
else if (result != SQLITE_ROW) {
441 LOG_ERROR <<
"Can't get ca_cert: " << db.errmsg();
445 auto ca_r = statement.get_result_col_str(0);
446 if (ca_r == boost::none) {
451 *ca = std::move(ca_r.value());
457 bool SQLStorage::loadTlsCert(std::string* cert)
const {
460 auto statement = db.prepareStatement(
"SELECT client_cert FROM tls_creds LIMIT 1;");
462 int result = statement.step();
463 if (result == SQLITE_DONE) {
464 LOG_TRACE <<
"client_cert not present in db";
466 }
else if (result != SQLITE_ROW) {
467 LOG_ERROR <<
"Can't get client_cert: " << db.errmsg();
471 auto cert_r = statement.get_result_col_str(0);
472 if (cert_r == boost::none) {
476 if (cert !=
nullptr) {
477 *cert = std::move(cert_r.value());
483 bool SQLStorage::loadTlsPkey(std::string* pkey)
const {
486 auto statement = db.prepareStatement(
"SELECT client_pkey FROM tls_creds LIMIT 1;");
488 int result = statement.step();
489 if (result == SQLITE_DONE) {
490 LOG_TRACE <<
"client_pkey not present in db";
492 }
else if (result != SQLITE_ROW) {
493 LOG_ERROR <<
"Can't get client_pkey: " << db.errmsg();
497 auto pkey_r = statement.get_result_col_str(0);
498 if (pkey_r == boost::none) {
502 if (pkey !=
nullptr) {
503 *pkey = std::move(pkey_r.value());
512 db.beginTransaction();
515 db.prepareStatement<int, int,
int>(
"DELETE FROM meta WHERE (repo=? AND meta_type=? AND version=?);",
516 static_cast<int>(repo), Uptane::Role::Root().ToInt(), version.version());
518 if (del_statement.step() != SQLITE_DONE) {
519 LOG_ERROR <<
"Can't clear Root metadata: " << db.errmsg();
523 auto ins_statement = db.prepareStatement<
SQLBlob, int, int,
int>(
"INSERT INTO meta VALUES (?, ?, ?, ?);",
524 SQLBlob(data),
static_cast<int>(repo),
525 Uptane::Role::Root().ToInt(), version.version());
527 if (ins_statement.step() != SQLITE_DONE) {
528 LOG_ERROR <<
"Can't add metadata: " << db.errmsg();
532 db.commitTransaction();
538 db.beginTransaction();
540 auto del_statement = db.prepareStatement<int,
int>(
"DELETE FROM meta WHERE (repo=? AND meta_type=?);",
541 static_cast<int>(repo), role.ToInt());
543 if (del_statement.step() != SQLITE_DONE) {
544 LOG_ERROR <<
"Can't clear " << role.ToString() <<
" metadata: " << db.errmsg();
549 db.prepareStatement<
SQLBlob, int, int,
int>(
"INSERT INTO meta VALUES (?, ?, ?, ?);",
SQLBlob(data),
552 if (ins_statement.step() != SQLITE_DONE) {
553 LOG_ERROR <<
"Can't add " << role.ToString() <<
"metadata: " << db.errmsg();
557 db.commitTransaction();
564 if (version.version() < 0) {
565 auto statement = db.prepareStatement<int,
int>(
566 "SELECT meta FROM meta WHERE (repo=? AND meta_type=?) ORDER BY version DESC LIMIT 1;",
static_cast<int>(repo),
567 Uptane::Role::Root().ToInt());
568 int result = statement.step();
570 if (result == SQLITE_DONE) {
571 LOG_TRACE <<
"Root metadata not present";
573 }
else if (result != SQLITE_ROW) {
574 LOG_ERROR <<
"Can't get Root metadata: " << db.errmsg();
577 if (data !=
nullptr) {
578 *data = std::string(reinterpret_cast<const char*>(sqlite3_column_blob(statement.get(), 0)));
582 db.prepareStatement<int, int,
int>(
"SELECT meta FROM meta WHERE (repo=? AND meta_type=? AND version=?);",
583 static_cast<int>(repo), Uptane::Role::Root().ToInt(), version.version());
585 int result = statement.step();
587 if (result == SQLITE_DONE) {
588 LOG_TRACE <<
"Root metadata not present";
590 }
else if (result != SQLITE_ROW) {
591 LOG_ERROR <<
"Can't get Root metadata: " << db.errmsg();
595 const auto blob =
reinterpret_cast<const char*
>(sqlite3_column_blob(statement.get(), 0));
596 if (blob ==
nullptr) {
597 LOG_ERROR <<
"Can't get Root metadata: " << db.errmsg();
601 if (data !=
nullptr) {
602 *data = std::string(blob);
612 auto statement = db.prepareStatement<int,
int>(
613 "SELECT meta FROM meta WHERE (repo=? AND meta_type=?) ORDER BY version DESC LIMIT 1;",
static_cast<int>(repo),
615 int result = statement.step();
617 if (result == SQLITE_DONE) {
618 LOG_TRACE << role.ToString() <<
" metadata not present";
620 }
else if (result != SQLITE_ROW) {
621 LOG_ERROR <<
"Can't get " << role.ToString() <<
" metadata: " << db.errmsg();
624 if (data !=
nullptr) {
625 *data = std::string(reinterpret_cast<const char*>(sqlite3_column_blob(statement.get(), 0)));
635 db.prepareStatement<
int>(
"DELETE FROM meta WHERE (repo=? AND meta_type != 0);",
static_cast<int>(repo));
637 if (del_statement.step() != SQLITE_DONE) {
638 LOG_ERROR <<
"Can't clear metadata: " << db.errmsg();
642 void SQLStorage::clearMetadata() {
645 if (db.exec(
"DELETE FROM meta;",
nullptr,
nullptr) != SQLITE_OK) {
646 LOG_ERROR <<
"Can't clear metadata: " << db.errmsg();
651 void SQLStorage::storeDelegation(
const std::string& data,
const Uptane::Role role) {
654 auto statement = db.prepareStatement<
SQLBlob, std::string>(
"INSERT OR REPLACE INTO delegations VALUES (?, ?);",
655 SQLBlob(data), role.ToString());
656 if (statement.step() != SQLITE_DONE) {
657 LOG_ERROR <<
"Can't add delegation metadata: " << db.errmsg();
662 bool SQLStorage::loadDelegation(std::string* data,
const Uptane::Role role)
const {
666 db.prepareStatement<std::string>(
"SELECT meta FROM delegations WHERE role_name=? LIMIT 1;", role.ToString());
667 int result = statement.step();
669 if (result == SQLITE_DONE) {
670 LOG_TRACE <<
"Delegations metadata not present";
672 }
else if (result != SQLITE_ROW) {
673 LOG_ERROR <<
"Can't get delegations metadata: " << db.errmsg();
676 if (data !=
nullptr) {
677 *data = std::string(reinterpret_cast<const char*>(sqlite3_column_blob(statement.get(), 0)));
683 bool SQLStorage::loadAllDelegations(std::vector<std::pair<Uptane::Role, std::string>>& data)
const {
689 auto statement = db.prepareStatement(
"SELECT meta, role_name FROM delegations;");
690 auto statement_state = statement.step();
692 if (statement_state == SQLITE_DONE) {
693 LOG_TRACE <<
"Delegations metadata are not present";
695 }
else if (statement_state != SQLITE_ROW) {
696 LOG_ERROR <<
"Can't get delegations metadata: " << db.errmsg();
701 data.emplace_back(Uptane::Role::Delegation(statement.get_result_col_str(1).value()),
702 statement.get_result_col_blob(0).value());
703 }
while ((statement_state = statement.step()) == SQLITE_ROW);
706 }
catch (
const std::exception& exc) {
707 LOG_ERROR <<
"Failed to fetch records from `delegations` table: " << exc.what();
713 void SQLStorage::deleteDelegation(
const Uptane::Role role) {
716 auto statement = db.prepareStatement<std::string>(
"DELETE FROM delegations WHERE role_name=?;", role.ToString());
720 void SQLStorage::clearDelegations() {
723 if (db.exec(
"DELETE FROM delegations;",
nullptr,
nullptr) != SQLITE_OK) {
724 LOG_ERROR <<
"Can't clear delegations metadata: " << db.errmsg();
728 void SQLStorage::storeDeviceId(
const std::string& device_id) {
731 auto statement = db.prepareStatement<std::string>(
732 "INSERT OR REPLACE INTO device_info(unique_mark,device_id,is_registered) VALUES(0,?,0);", device_id);
733 if (statement.step() != SQLITE_DONE) {
734 LOG_ERROR <<
"Can't set device ID: " << db.errmsg();
739 bool SQLStorage::loadDeviceId(std::string* device_id)
const {
742 auto statement = db.prepareStatement(
"SELECT device_id FROM device_info LIMIT 1;");
744 int result = statement.step();
745 if (result == SQLITE_DONE) {
746 LOG_TRACE <<
"device_id not present in db";
748 }
else if (result != SQLITE_ROW) {
749 LOG_ERROR <<
"Can't get device ID: " << db.errmsg();
753 auto did = statement.get_result_col_str(0);
754 if (did == boost::none) {
755 LOG_ERROR <<
"Empty device ID" << db.errmsg();
759 if (device_id !=
nullptr) {
760 *device_id = std::move(did.value());
766 void SQLStorage::clearDeviceId() {
769 if (db.exec(
"DELETE FROM device_info;",
nullptr,
nullptr) != SQLITE_OK) {
770 LOG_ERROR <<
"Can't clear device ID: " << db.errmsg();
775 void SQLStorage::storeEcuRegistered() {
778 db.beginTransaction();
780 auto statement = db.prepareStatement(
"SELECT count(*) FROM device_info;");
781 if (statement.step() != SQLITE_ROW) {
782 throw std::runtime_error(
"Could not get device_info count");
784 if (statement.get_result_col_int(0) != 1) {
785 throw std::runtime_error(
"Cannot set ECU registered if no device_info set");
788 std::string req =
"UPDATE device_info SET is_registered = 1";
789 if (db.exec(req.c_str(),
nullptr,
nullptr) != SQLITE_OK) {
790 LOG_ERROR <<
"Can't set is_registered: " << db.errmsg();
794 db.commitTransaction();
797 bool SQLStorage::loadEcuRegistered()
const {
800 auto statement = db.prepareStatement(
"SELECT is_registered FROM device_info LIMIT 1;");
802 int result = statement.step();
803 if (result == SQLITE_DONE) {
805 }
else if (result != SQLITE_ROW) {
806 LOG_ERROR <<
"Can't get is_registered in device_info " << db.errmsg();
810 return statement.get_result_col_int(0) != 0;
813 void SQLStorage::clearEcuRegistered() {
817 std::string req =
"UPDATE device_info SET is_registered = 0";
818 if (db.exec(req.c_str(),
nullptr,
nullptr) != SQLITE_OK) {
819 LOG_ERROR <<
"Can't set is_registered: " << db.errmsg();
824 void SQLStorage::storeNeedReboot() {
827 auto statement = db.prepareStatement<
int>(
"INSERT OR REPLACE INTO need_reboot(unique_mark,flag) VALUES(0,?);", 1);
828 if (statement.step() != SQLITE_DONE) {
829 LOG_ERROR <<
"Can't set need_reboot: " << db.errmsg();
834 bool SQLStorage::loadNeedReboot(
bool* need_reboot)
const {
837 auto statement = db.prepareStatement(
"SELECT flag FROM need_reboot LIMIT 1;");
839 int result = statement.step();
840 if (result == SQLITE_DONE) {
841 if (need_reboot !=
nullptr) {
842 *need_reboot =
false;
845 }
else if (result != SQLITE_ROW) {
846 LOG_ERROR <<
"Can't get need_reboot: " << db.errmsg();
850 auto flag =
static_cast<bool>(statement.get_result_col_int(0));
851 if (need_reboot !=
nullptr) {
858 void SQLStorage::clearNeedReboot() {
861 if (db.exec(
"DELETE FROM need_reboot;",
nullptr,
nullptr) != SQLITE_OK) {
862 LOG_ERROR <<
"Can't clear need_reboot: " << db.errmsg();
867 void SQLStorage::storeEcuSerials(
const EcuSerials& serials) {
868 if (serials.size() >= 1) {
871 db.beginTransaction();
873 if (db.exec(
"DELETE FROM ecus;",
nullptr,
nullptr) != SQLITE_OK) {
874 LOG_ERROR <<
"Can't clear ecus: " << db.errmsg();
879 std::string serial = serials[0].first.ToString();
880 std::string hwid = serials[0].second.ToString();
882 auto statement = db.prepareStatement<std::string, std::string>(
883 "INSERT INTO ecus(id, serial,hardware_id,is_primary) VALUES (0, ?,?,1);", serial, hwid);
884 if (statement.step() != SQLITE_DONE) {
885 LOG_ERROR <<
"Can't set ecu_serial: " << db.errmsg();
890 auto statement_ivupdate = db.prepareStatement<std::string>(
891 "UPDATE installed_versions SET ecu_serial = ? WHERE ecu_serial = '';", serial);
893 if (statement_ivupdate.step() != SQLITE_DONE) {
894 LOG_ERROR <<
"Can't set ecu_serial: " << db.errmsg();
899 for (
auto it = serials.cbegin() + 1; it != serials.cend(); it++) {
900 auto statement = db.prepareStatement<int64_t, std::string, std::string>(
901 "INSERT INTO ecus(id,serial,hardware_id) VALUES (?,?,?);", it - serials.cbegin(), it->first.ToString(),
902 it->second.ToString());
904 if (statement.step() != SQLITE_DONE) {
905 LOG_ERROR <<
"Can't set ecu_serial: " << db.errmsg();
910 db.commitTransaction();
914 bool SQLStorage::loadEcuSerials(EcuSerials* serials)
const {
918 auto statement = db.prepareStatement(
"SELECT serial, hardware_id FROM ecus ORDER BY id;");
921 EcuSerials new_serials;
923 while ((statement_state = statement.step()) == SQLITE_ROW) {
925 new_serials.emplace_back(
Uptane::EcuSerial(statement.get_result_col_str(0).value()),
928 }
catch (
const boost::bad_optional_access&) {
933 if (statement_state != SQLITE_DONE) {
934 LOG_ERROR <<
"Can't get ECU serials: " << db.errmsg();
938 if (serials !=
nullptr) {
939 *serials = std::move(new_serials);
945 void SQLStorage::clearEcuSerials() {
948 db.beginTransaction();
950 if (db.exec(
"DELETE FROM ecus;",
nullptr,
nullptr) != SQLITE_OK) {
951 LOG_ERROR <<
"Can't clear ECUs: " << db.errmsg();
955 if (db.exec(
"DELETE FROM secondary_ecus;",
nullptr,
nullptr) != SQLITE_OK) {
956 LOG_ERROR <<
"Can't clear Secondary ECUs: " << db.errmsg();
960 db.commitTransaction();
963 void SQLStorage::storeCachedEcuManifest(
const Uptane::EcuSerial& ecu_serial,
const std::string& manifest) {
966 auto statement = db.prepareStatement<std::string, std::string>(
967 "UPDATE secondary_ecus SET manifest = ? WHERE (serial = ?);", manifest, ecu_serial.ToString());
968 if (statement.step() != SQLITE_DONE || sqlite3_changes(db.get()) != 1) {
969 LOG_ERROR <<
"Can't save Secondary manifest: " << db.errmsg();
974 bool SQLStorage::loadCachedEcuManifest(
const Uptane::EcuSerial& ecu_serial, std::string* manifest)
const {
977 std::string stmanifest;
981 auto statement = db.prepareStatement<std::string>(
"SELECT manifest FROM secondary_ecus WHERE (serial = ?);",
982 ecu_serial.ToString());
984 if (statement.step() != SQLITE_ROW) {
985 LOG_WARNING <<
"Could not find manifest for ECU " << ecu_serial;
988 stmanifest = statement.get_result_col_str(0).value_or(
"");
990 empty = stmanifest ==
"";
993 if (manifest !=
nullptr) {
994 *manifest = std::move(stmanifest);
1003 auto statement = db.prepareStatement<std::string, std::string,
int>(
1004 "INSERT OR REPLACE INTO misconfigured_ecus VALUES (?,?,?);", ecu.serial.ToString(), ecu.hardware_id.ToString(),
1005 static_cast<int>(ecu.state));
1006 if (statement.step() != SQLITE_DONE) {
1007 throw std::runtime_error(db.errmsg().insert(0,
"Can't save misconfigured_ecus: "));
1011 bool SQLStorage::loadMisconfiguredEcus(std::vector<MisconfiguredEcu>* ecus)
const {
1014 auto statement = db.prepareStatement(
"SELECT serial, hardware_id, state FROM misconfigured_ecus;");
1015 int statement_state;
1017 std::vector<MisconfiguredEcu> new_ecus;
1019 while ((statement_state = statement.step()) == SQLITE_ROW) {
1021 new_ecus.emplace_back(
Uptane::EcuSerial(statement.get_result_col_str(0).value()),
1023 static_cast<EcuState>(statement.get_result_col_int(2)));
1025 }
catch (
const boost::bad_optional_access&) {
1030 if (statement_state != SQLITE_DONE) {
1031 LOG_ERROR <<
"Can't get misconfigured_ecus: " << db.errmsg();
1035 if (ecus !=
nullptr) {
1036 *ecus = std::move(new_ecus);
1042 void SQLStorage::clearMisconfiguredEcus() {
1045 if (db.exec(
"DELETE FROM misconfigured_ecus;",
nullptr,
nullptr) != SQLITE_OK) {
1046 LOG_ERROR <<
"Can't clear misconfigured_ecus: " << db.errmsg();
1051 void SQLStorage::saveInstalledVersion(
const std::string& ecu_serial,
const Uptane::Target& target,
1052 InstalledVersionUpdateMode update_mode) {
1055 db.beginTransaction();
1060 std::string ecu_serial_real = ecu_serial;
1061 if (ecu_serial_real.empty()) {
1062 auto statement = db.prepareStatement(
"SELECT serial FROM ecus WHERE is_primary = 1;");
1063 if (statement.step() == SQLITE_ROW) {
1064 ecu_serial_real = statement.get_result_col_str(0).value();
1066 LOG_WARNING <<
"Could not find Primary ECU serial, set to lazy init mode";
1070 std::string hashes_encoded = Hash::encodeVector(target.hashes());
1073 boost::optional<int64_t> old_id;
1074 bool old_was_installed =
false;
1076 auto statement = db.prepareStatement<std::string>(
1077 "SELECT id, sha256, name, was_installed FROM installed_versions WHERE ecu_serial = ? ORDER BY id DESC " 1081 if (statement.step() == SQLITE_ROW) {
1082 int64_t rid = statement.get_result_col_int(0);
1083 std::string rsha256 = statement.get_result_col_str(1).value_or(
"");
1084 std::string rname = statement.get_result_col_str(2).value_or(
"");
1085 bool rwasi = statement.get_result_col_int(3) == 1;
1087 if (rsha256 == target.sha256Hash() && rname == target.filename()) {
1089 old_was_installed = rwasi;
1094 if (update_mode == InstalledVersionUpdateMode::kCurrent) {
1096 auto statement = db.prepareStatement<std::string>(
1097 "UPDATE installed_versions SET is_current = 0, is_pending = 0 WHERE ecu_serial = ?", ecu_serial_real);
1098 if (statement.step() != SQLITE_DONE) {
1099 LOG_ERROR <<
"Can't set installed_versions: " << db.errmsg();
1102 }
else if (update_mode == InstalledVersionUpdateMode::kPending) {
1104 auto statement = db.prepareStatement<std::string>(
1105 "UPDATE installed_versions SET is_pending = 0 WHERE ecu_serial = ?", ecu_serial_real);
1106 if (statement.step() != SQLITE_DONE) {
1107 LOG_ERROR <<
"Can't set installed_versions: " << db.errmsg();
1113 auto statement = db.prepareStatement<std::string, int, int, int64_t>(
1114 "UPDATE installed_versions SET correlation_id = ?, is_current = ?, is_pending = ?, was_installed = ? WHERE id " 1116 target.correlation_id(),
static_cast<int>(update_mode == InstalledVersionUpdateMode::kCurrent),
1117 static_cast<int>(update_mode == InstalledVersionUpdateMode::kPending),
1118 static_cast<int>(update_mode == InstalledVersionUpdateMode::kCurrent || old_was_installed), old_id.value());
1120 if (statement.step() != SQLITE_DONE) {
1121 LOG_ERROR <<
"Can't set installed_versions: " << db.errmsg();
1125 std::string custom = Utils::jsonToCanonicalStr(target.custom_data());
1126 auto statement = db.prepareStatement<std::string, std::string, std::string, std::string, int64_t, std::string,
1127 std::string, int,
int>(
1128 "INSERT INTO installed_versions(ecu_serial, sha256, name, hashes, length, custom_meta, correlation_id, " 1129 "is_current, is_pending, was_installed) VALUES (?,?,?,?,?,?,?,?,?,?);",
1130 ecu_serial_real, target.sha256Hash(), target.filename(), hashes_encoded,
static_cast<int64_t
>(target.length()),
1131 custom, target.correlation_id(),
static_cast<int>(update_mode == InstalledVersionUpdateMode::kCurrent),
1132 static_cast<int>(update_mode == InstalledVersionUpdateMode::kPending),
1133 static_cast<int>(update_mode == InstalledVersionUpdateMode::kCurrent));
1135 if (statement.step() != SQLITE_DONE) {
1136 LOG_ERROR <<
"Can't set installed_versions: " << db.errmsg();
1141 db.commitTransaction();
1144 static void loadEcuMap(
SQLite3Guard& db, std::string& ecu_serial, Uptane::EcuMap& ecu_map) {
1147 if (ecu_serial.empty()) {
1148 auto statement = db.prepareStatement(
"SELECT serial FROM ecus WHERE is_primary = 1;");
1149 if (statement.step() == SQLITE_ROW) {
1150 ecu_serial = statement.get_result_col_str(0).value();
1151 }
else if (statement.step() == SQLITE_DONE) {
1152 LOG_DEBUG <<
"No serial found in database for this ECU, defaulting to empty serial";
1154 LOG_ERROR <<
"Error getting serial for this ECU, defaulting to empty serial: " << db.errmsg();
1158 if (!ecu_serial.empty()) {
1159 auto statement = db.prepareStatement<std::string>(
"SELECT hardware_id FROM ecus WHERE serial = ?;", ecu_serial);
1160 if (statement.step() == SQLITE_ROW) {
1163 }
else if (statement.step() == SQLITE_DONE) {
1164 LOG_DEBUG <<
"No hardware ID found in database for ECU serial " << ecu_serial;
1166 LOG_ERROR <<
"Error getting hardware ID for ECU serial " << ecu_serial <<
": " << db.errmsg();
1171 bool SQLStorage::loadInstallationLog(
const std::string& ecu_serial, std::vector<Uptane::Target>* log,
1172 bool only_installed)
const {
1175 std::string ecu_serial_real = ecu_serial;
1176 Uptane::EcuMap ecu_map;
1177 loadEcuMap(db, ecu_serial_real, ecu_map);
1180 "SELECT id, sha256, name, hashes, length, correlation_id, custom_meta FROM installed_versions WHERE " 1181 "ecu_serial = ? ORDER BY id;";
1182 if (only_installed) {
1184 "SELECT id, sha256, name, hashes, length, correlation_id, custom_meta FROM installed_versions WHERE " 1185 "ecu_serial = ? AND was_installed = 1 ORDER BY id;";
1188 auto statement = db.prepareStatement<std::string>(query, ecu_serial_real);
1189 int statement_state;
1191 std::vector<Uptane::Target> new_log;
1192 std::map<int64_t, size_t> ids_map;
1194 while ((statement_state = statement.step()) == SQLITE_ROW) {
1196 auto id = statement.get_result_col_int(0);
1197 auto sha256 = statement.get_result_col_str(1).value();
1198 auto filename = statement.get_result_col_str(2).value();
1199 auto hashes_str = statement.get_result_col_str(3).value();
1200 auto length = statement.get_result_col_int(4);
1201 auto correlation_id = statement.get_result_col_str(5).value();
1202 auto custom_str = statement.get_result_col_str(6).value();
1206 std::vector<Hash> hashes = Hash::decodeVector(hashes_str);
1209 std::find_if(hashes.cbegin(), hashes.cend(), [](
const Hash& h) {
return h.type() == Hash::Type::kSha256; });
1210 if (find_sha256 == hashes.cend()) {
1211 LOG_WARNING <<
"No sha256 in hashes list";
1212 hashes.emplace_back(Hash::Type::kSha256, sha256);
1215 Uptane::Target t(filename, ecu_map, hashes, static_cast<uint64_t>(length), correlation_id);
1216 if (!custom_str.empty()) {
1217 std::istringstream css(custom_str);
1220 if (Json::parseFromStream(Json::CharReaderBuilder(), css, &custom,
nullptr)) {
1221 t.updateCustom(custom);
1223 LOG_ERROR <<
"Unable to parse custom data: " << errs;
1226 new_log.emplace_back(t);
1230 }
catch (
const boost::bad_optional_access&) {
1231 LOG_ERROR <<
"Incompleted installed version, keeping old one";
1236 if (statement_state != SQLITE_DONE) {
1237 LOG_ERROR <<
"Can't get installed_versions: " << db.errmsg();
1241 if (log ==
nullptr) {
1245 *log = std::move(new_log);
1250 bool SQLStorage::loadInstalledVersions(
const std::string& ecu_serial, boost::optional<Uptane::Target>* current_version,
1251 boost::optional<Uptane::Target>* pending_version)
const {
1254 std::string ecu_serial_real = ecu_serial;
1255 Uptane::EcuMap ecu_map;
1256 loadEcuMap(db, ecu_serial_real, ecu_map);
1259 auto sha256 = statement.get_result_col_str(0).value();
1260 auto filename = statement.get_result_col_str(1).value();
1261 auto hashes_str = statement.get_result_col_str(2).value();
1262 auto length = statement.get_result_col_int(3);
1263 auto correlation_id = statement.get_result_col_str(4).value();
1264 auto custom_str = statement.get_result_col_str(5).value();
1268 std::vector<Hash> hashes = Hash::decodeVector(hashes_str);
1271 std::find_if(hashes.cbegin(), hashes.cend(), [](
const Hash& h) {
return h.type() == Hash::Type::kSha256; });
1272 if (find_sha256 == hashes.cend()) {
1273 LOG_WARNING <<
"No sha256 in hashes list";
1274 hashes.emplace_back(Hash::Type::kSha256, sha256);
1276 Uptane::Target t(filename, ecu_map, hashes, static_cast<uint64_t>(length), correlation_id);
1277 if (!custom_str.empty()) {
1278 std::istringstream css(custom_str);
1281 if (Json::parseFromStream(Json::CharReaderBuilder(), css, &custom, &errs)) {
1282 t.updateCustom(custom);
1284 LOG_ERROR <<
"Unable to parse custom data: " << errs;
1291 if (current_version !=
nullptr) {
1292 auto statement = db.prepareStatement<std::string>(
1293 "SELECT sha256, name, hashes, length, correlation_id, custom_meta FROM installed_versions WHERE " 1294 "ecu_serial = ? AND is_current = 1 LIMIT 1;",
1297 if (statement.step() == SQLITE_ROW) {
1299 *current_version = read_target(statement);
1300 }
catch (
const boost::bad_optional_access&) {
1301 LOG_ERROR <<
"Could not read current installed version";
1305 LOG_TRACE <<
"Cannot get current installed version: " << db.errmsg();
1306 *current_version = boost::none;
1310 if (pending_version !=
nullptr) {
1311 auto statement = db.prepareStatement<std::string>(
1312 "SELECT sha256, name, hashes, length, correlation_id, custom_meta FROM installed_versions WHERE " 1313 "ecu_serial = ? AND is_pending = 1 LIMIT 1;",
1316 if (statement.step() == SQLITE_ROW) {
1318 *pending_version = read_target(statement);
1319 }
catch (
const boost::bad_optional_access&) {
1320 LOG_ERROR <<
"Could not read pending installed version";
1324 LOG_TRACE <<
"Cannot get pending installed version: " << db.errmsg();
1325 *pending_version = boost::none;
1332 bool SQLStorage::hasPendingInstall() {
1335 auto statement = db.prepareStatement(
"SELECT count(*) FROM installed_versions where is_pending = 1");
1336 if (statement.step() != SQLITE_ROW) {
1337 LOG_ERROR <<
"Can't get tables count: " << db.errmsg();
1338 throw std::runtime_error(
"Could not count pending installations");
1341 return statement.get_result_col_int(0) > 0;
1344 void SQLStorage::getPendingEcus(std::vector<std::pair<Uptane::EcuSerial, Hash>>* pendingEcus) {
1347 auto statement = db.prepareStatement(
"SELECT ecu_serial, sha256 FROM installed_versions where is_pending = 1");
1348 int statement_result = statement.step();
1349 if (statement_result != SQLITE_DONE && statement_result != SQLITE_ROW) {
1350 throw std::runtime_error(
"Failed to get ECUs with a pending target installation: " + db.errmsg());
1353 std::vector<std::pair<Uptane::EcuSerial, Hash>> ecu_res;
1355 if (statement_result == SQLITE_DONE) {
1360 for (; statement_result != SQLITE_DONE; statement_result = statement.step()) {
1361 std::string ecu_serial = statement.get_result_col_str(0).value();
1362 std::string hash = statement.get_result_col_str(1).value();
1363 ecu_res.emplace_back(std::make_pair(
Uptane::EcuSerial(ecu_serial),
Hash(Hash::Type::kSha256, hash)));
1366 if (pendingEcus !=
nullptr) {
1367 *pendingEcus = std::move(ecu_res);
1371 void SQLStorage::clearInstalledVersions() {
1374 if (db.exec(
"DELETE FROM installed_versions;",
nullptr,
nullptr) != SQLITE_OK) {
1375 LOG_ERROR <<
"Can't clear installed_versions: " << db.errmsg();
1384 auto statement = db.prepareStatement<std::string, int, std::string, std::string>(
1385 "INSERT OR REPLACE INTO ecu_installation_results (ecu_serial, success, result_code, description) VALUES " 1387 ecu_serial.ToString(),
static_cast<int>(result.success), result.result_code.toRepr(), result.description);
1388 if (statement.step() != SQLITE_DONE) {
1389 LOG_ERROR <<
"Can't set ECU installation result: " << db.errmsg();
1394 bool SQLStorage::loadEcuInstallationResults(
1395 std::vector<std::pair<Uptane::EcuSerial, data::InstallationResult>>* results)
const {
1398 std::vector<std::pair<Uptane::EcuSerial, data::InstallationResult>> ecu_res;
1401 auto statement = db.prepareStatement(
1402 "SELECT ecu_serial, success, result_code, description FROM ecu_installation_results INNER JOIN ecus ON " 1403 "ecus.serial = ecu_serial ORDER BY ecus.id;");
1404 int statement_result = statement.step();
1405 if (statement_result != SQLITE_DONE && statement_result != SQLITE_ROW) {
1406 LOG_ERROR <<
"Can't get ecu_installation_results: " << db.errmsg();
1410 if (statement_result == SQLITE_DONE) {
1415 for (; statement_result != SQLITE_DONE; statement_result = statement.step()) {
1417 std::string ecu_serial = statement.get_result_col_str(0).value();
1418 auto success =
static_cast<bool>(statement.get_result_col_int(1));
1419 data::ResultCode result_code = data::ResultCode::fromRepr(statement.get_result_col_str(2).value());
1420 std::string description = statement.get_result_col_str(3).value();
1423 }
catch (
const boost::bad_optional_access&) {
1428 if (results !=
nullptr) {
1429 *results = std::move(ecu_res);
1435 void SQLStorage::storeDeviceInstallationResult(
const data::InstallationResult& result,
const std::string& raw_report,
1436 const std::string& correlation_id) {
1439 auto statement = db.prepareStatement<int, std::string, std::string, std::string, std::string>(
1440 "INSERT OR REPLACE INTO device_installation_result (unique_mark, success, result_code, description, raw_report, " 1442 "VALUES (0,?,?,?,?,?);",
1443 static_cast<int>(result.success), result.result_code.toRepr(), result.description, raw_report, correlation_id);
1444 if (statement.step() != SQLITE_DONE) {
1445 LOG_ERROR <<
"Can't set device installation result: " << db.errmsg();
1450 bool SQLStorage::storeDeviceInstallationRawReport(
const std::string& raw_report) {
1452 auto statement = db.prepareStatement<std::string>(
"UPDATE device_installation_result SET raw_report=?;", raw_report);
1453 if (statement.step() != SQLITE_DONE || sqlite3_changes(db.get()) != 1) {
1454 LOG_ERROR <<
"Can't set device raw report result: " << db.errmsg();
1461 std::string* correlation_id)
const {
1465 std::string raw_report_res;
1466 std::string corrid_res;
1468 auto statement = db.prepareStatement(
1469 "SELECT success, result_code, description, raw_report, correlation_id FROM device_installation_result;");
1470 int statement_result = statement.step();
1471 if (statement_result == SQLITE_DONE) {
1472 LOG_TRACE <<
"No device installation result in db";
1474 }
else if (statement_result != SQLITE_ROW) {
1475 LOG_ERROR <<
"Can't get device_installation_result: " << db.errmsg();
1480 auto success =
static_cast<bool>(statement.get_result_col_int(0));
1481 data::ResultCode result_code = data::ResultCode::fromRepr(statement.get_result_col_str(1).value());
1482 std::string description = statement.get_result_col_str(2).value();
1483 raw_report_res = statement.get_result_col_str(3).value();
1484 corrid_res = statement.get_result_col_str(4).value();
1487 }
catch (
const boost::bad_optional_access&) {
1491 if (result !=
nullptr) {
1492 *result = std::move(dev_res);
1495 if (raw_report !=
nullptr) {
1496 *raw_report = std::move(raw_report_res);
1499 if (correlation_id !=
nullptr) {
1500 *correlation_id = std::move(corrid_res);
1506 void SQLStorage::saveEcuReportCounter(
const Uptane::EcuSerial& ecu_serial,
const int64_t counter) {
1509 auto statement = db.prepareStatement<std::string, int64_t>(
1510 "INSERT OR REPLACE INTO ecu_report_counter (ecu_serial, counter) VALUES " 1512 ecu_serial.ToString(), counter);
1513 if (statement.step() != SQLITE_DONE) {
1514 LOG_ERROR <<
"Can't set ECU counter: " << db.errmsg();
1519 bool SQLStorage::loadEcuReportCounter(std::vector<std::pair<Uptane::EcuSerial, int64_t>>* results)
const {
1522 std::vector<std::pair<Uptane::EcuSerial, int64_t>> ecu_cnt;
1525 auto statement = db.prepareStatement(
1526 "SELECT ecu_serial, counter FROM ecu_report_counter INNER JOIN ecus ON " 1527 "ecus.serial = ecu_serial ORDER BY ecus.id;");
1528 int statement_result = statement.step();
1529 if (statement_result != SQLITE_DONE && statement_result != SQLITE_ROW) {
1530 LOG_ERROR <<
"Can't get ecu_report_counter: " << db.errmsg();
1534 if (statement_result == SQLITE_DONE) {
1539 for (; statement_result != SQLITE_DONE; statement_result = statement.step()) {
1541 std::string ecu_serial = statement.get_result_col_str(0).value();
1542 int64_t counter = statement.get_result_col_int(1);
1545 }
catch (
const boost::bad_optional_access&) {
1550 if (results !=
nullptr) {
1551 *results = std::move(ecu_cnt);
1557 void SQLStorage::saveReportEvent(
const Json::Value& json_value) {
1558 std::string json_string = Utils::jsonToCanonicalStr(json_value);
1560 auto statement = db.prepareStatement<std::string>(
1561 "INSERT INTO report_events SELECT MAX(id) + 1, ? FROM report_events", json_string);
1562 if (statement.step() != SQLITE_DONE) {
1563 LOG_ERROR <<
"Can't save report event: " << db.errmsg();
1568 bool SQLStorage::loadReportEvents(Json::Value* report_array, int64_t* id_max)
const {
1570 auto statement = db.prepareStatement(
"SELECT id, json_string FROM report_events;");
1571 int statement_result = statement.step();
1572 if (statement_result != SQLITE_DONE && statement_result != SQLITE_ROW) {
1573 LOG_ERROR <<
"Can't get report_events: " << db.errmsg();
1576 if (statement_result == SQLITE_DONE) {
1581 for (; statement_result != SQLITE_DONE; statement_result = statement.step()) {
1583 int64_t
id = statement.get_result_col_int(0);
1584 std::string json_string = statement.get_result_col_str(1).value();
1585 std::istringstream jss(json_string);
1586 Json::Value event_json;
1588 if (Json::parseFromStream(Json::CharReaderBuilder(), jss, &event_json, &errs)) {
1589 report_array->append(event_json);
1590 *id_max = (*id_max) >
id ? (*id_max) : id;
1592 LOG_ERROR <<
"Unable to parse event data: " << errs;
1594 }
catch (
const boost::bad_optional_access&) {
1602 void SQLStorage::deleteReportEvents(int64_t id_max) {
1605 auto statement = db.prepareStatement<int64_t>(
"DELETE FROM report_events WHERE id <= ?;", id_max);
1606 if (statement.step() != SQLITE_DONE) {
1607 LOG_ERROR <<
"Can't delete report_events";
1611 void SQLStorage::clearInstallationResults() {
1614 db.beginTransaction();
1616 if (db.exec(
"DELETE FROM device_installation_result;",
nullptr,
nullptr) != SQLITE_OK) {
1617 LOG_ERROR <<
"Can't clear device_installation_result: " << db.errmsg();
1621 if (db.exec(
"DELETE FROM ecu_installation_results;",
nullptr,
nullptr) != SQLITE_OK) {
1622 LOG_ERROR <<
"Can't clear ecu_installation_results: " << db.errmsg();
1626 db.commitTransaction();
1629 void SQLStorage::storeDeviceDataHash(
const std::string& data_type,
const std::string& hash) {
1632 auto statement = db.prepareStatement<std::string, std::string>(
1633 "INSERT OR REPLACE INTO device_data(data_type,hash) VALUES (?,?);", data_type, hash);
1634 if (statement.step() != SQLITE_DONE) {
1635 LOG_ERROR <<
"Can't set " << data_type <<
" hash: " << db.errmsg();
1636 throw std::runtime_error(
"Can't set " + data_type +
" hash: " + db.errmsg());
1640 bool SQLStorage::loadDeviceDataHash(
const std::string& data_type, std::string* hash)
const {
1644 db.prepareStatement<std::string>(
"SELECT hash FROM device_data WHERE data_type = ? LIMIT 1;", data_type);
1646 int result = statement.step();
1647 if (result == SQLITE_DONE) {
1648 LOG_TRACE << data_type <<
" hash not present in db";
1650 }
else if (result != SQLITE_ROW) {
1651 LOG_ERROR <<
"Can't get " << data_type <<
" hash: " << db.errmsg();
1655 if (hash !=
nullptr) {
1656 *hash = statement.get_result_col_str(0).value();
1662 void SQLStorage::clearDeviceData() {
1665 if (db.exec(
"DELETE FROM device_data;",
nullptr,
nullptr) != SQLITE_OK) {
1666 LOG_ERROR <<
"Can't clear device_data: " << db.errmsg();
1671 void SQLStorage::storeTargetFilename(
const std::string& targetname,
const std::string& filename)
const {
1673 auto statement = db.prepareStatement<std::string, std::string>(
1674 "INSERT OR REPLACE INTO target_images (targetname, filename) VALUES (?, ?);", targetname, filename);
1676 if (statement.step() != SQLITE_DONE) {
1677 LOG_ERROR <<
"Statement step failure: " << db.errmsg();
1678 throw std::runtime_error(
"Could not write to db");
1682 std::string SQLStorage::getTargetFilename(
const std::string& targetname)
const {
1686 db.prepareStatement<std::string>(
"SELECT filename FROM target_images WHERE targetname = ?;", targetname);
1688 switch (statement.step()) {
1690 return statement.get_result_col_str(0).value();
1694 throw std::runtime_error(db.errmsg().insert(0,
"Error reading target filename from db: "));
1698 std::vector<std::string> SQLStorage::getAllTargetNames()
const {
1701 auto statement = db.prepareStatement<>(
"SELECT targetname FROM target_images;");
1703 std::vector<std::string> names;
1705 int result = statement.step();
1706 while (result != SQLITE_DONE) {
1707 if (result != SQLITE_ROW) {
1708 LOG_ERROR <<
"Statement step failure: " << db.errmsg();
1709 throw std::runtime_error(
"Error getting target files");
1711 names.push_back(statement.get_result_col_str(0).value());
1712 result = statement.step();
1717 void SQLStorage::deleteTargetInfo(
const std::string& targetname)
const {
1720 auto statement = db.prepareStatement<std::string>(
"DELETE FROM target_images WHERE targetname=?;", targetname);
1722 if (statement.step() != SQLITE_DONE) {
1723 LOG_ERROR <<
"Statement step failure: " << db.errmsg();
1724 throw std::runtime_error(
"Could not remove target file");
1728 void SQLStorage::cleanUp() { boost::filesystem::remove_all(dbPath()); }
Metadata version numbers.
The Hash class The hash of a file or Uptane metadata.
Results of libaktualizr API calls.