From 1bdeddab2cbda01117fac756367f76526b14bb9e Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Tue, 23 Feb 2016 16:20:09 -0800 Subject: [core] Fix subtle bug in OfflineDatabase with updated resources SQLite REPLACE is *not* UPSERT. If a conflict occurs, it first deletes the existing row, then inserts a new row. This means that AUTOINCREMENT primary keys change. This will break foreign keys to that value, which we use. Instead we must try an UPDATE, and fall back to an INSERT if the UPDATE changes zero rows. --- platform/default/sqlite3.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'platform/default/sqlite3.cpp') diff --git a/platform/default/sqlite3.cpp b/platform/default/sqlite3.cpp index 72296c6843..bf0bbfc683 100644 --- a/platform/default/sqlite3.cpp +++ b/platform/default/sqlite3.cpp @@ -292,6 +292,24 @@ template <> std::chrono::system_clock::time_point Statement::get(int offset) { return std::chrono::system_clock::from_time_t(sqlite3_column_int64(stmt, offset)); } +template <> optional Statement::get(int offset) { + assert(stmt); + if (sqlite3_column_type(stmt, offset) == SQLITE_NULL) { + return optional(); + } else { + return get(offset); + } +} + +template <> optional Statement::get(int offset) { + assert(stmt); + if (sqlite3_column_type(stmt, offset) == SQLITE_NULL) { + return optional(); + } else { + return get(offset); + } +} + template <> optional Statement::get(int offset) { assert(stmt); if (sqlite3_column_type(stmt, offset) == SQLITE_NULL) { -- cgit v1.2.1