sql: Remove const qualifier from Statement::Column*() methods.
The sql::Statement::Column*() methods are currently const, which
suggests no internal state changes.
This is incorrect for the following reasons.
1. GetColumnType()'s comment indicates that Column*() perform SQLite
type conversion. So, the methods appear to change the underlying
SQLite state.
2. In general, the methods call into SQLite, and we can't guarantee that
SQLite state doesn't change.
This CL fixes the problem by removing the const qualifier from the
impacted methods.
Bug: 1229420
Change-Id: Id7a22d334130efb482455383e9ee6d0ee8400b2a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3028806
Reviewed-by: Marijn Kruisselbrink <mek@chromium.org>
Reviewed-by: Colin Blundell <blundell@chromium.org>
Commit-Queue: Colin Blundell <blundell@chromium.org>
Auto-Submit: Victor Costan <pwnall@chromium.org>
Cr-Commit-Position: refs/heads/master@{#901938}
diff --git a/chrome/browser/browsing_data/access_context_audit_database.cc b/chrome/browser/browsing_data/access_context_audit_database.cc
index 9a9427f..bce53c4 100644
--- a/chrome/browser/browsing_data/access_context_audit_database.cc
+++ b/chrome/browser/browsing_data/access_context_audit_database.cc
@@ -650,7 +650,7 @@
namespace {
AccessContextAuditDatabase::AccessRecord StorageAccessRecordFromStatement(
- const sql::Statement& statement) {
+ sql::Statement& statement) {
return AccessContextAuditDatabase::AccessRecord(
// If the top-frame origin is empty string, that means we deleted the
// top_frame_origin of a cross-site access record. In this case we set the
diff --git a/components/autofill/core/browser/webdata/autofill_table.cc b/components/autofill/core/browser/webdata/autofill_table.cc
index fcf3a73..0040feb 100644
--- a/components/autofill/core/browser/webdata/autofill_table.cc
+++ b/components/autofill/core/browser/webdata/autofill_table.cc
@@ -109,7 +109,7 @@
s->BindBool(index++, profile.disallow_settings_visible_updates());
}
-void AddAutofillProfileDetailsFromStatement(const sql::Statement& s,
+void AddAutofillProfileDetailsFromStatement(sql::Statement& s,
AutofillProfile* profile) {
int index = 1; // 0 is for the guid.
profile->SetRawInfo(COMPANY_NAME, s.ColumnString16(index++));
@@ -164,7 +164,7 @@
}
std::u16string UnencryptedCardFromColumn(
- const sql::Statement& s,
+ sql::Statement& s,
int column_index,
const AutofillTableEncryptor& encryptor) {
std::u16string credit_card_number;
@@ -180,7 +180,7 @@
}
std::unique_ptr<CreditCard> CreditCardFromStatement(
- const sql::Statement& s,
+ sql::Statement& s,
const AutofillTableEncryptor& encryptor) {
std::unique_ptr<CreditCard> credit_card(new CreditCard);
diff --git a/components/favicon/core/favicon_database.cc b/components/favicon/core/favicon_database.cc
index fda4982..f074a55 100644
--- a/components/favicon/core/favicon_database.cc
+++ b/components/favicon/core/favicon_database.cc
@@ -103,8 +103,8 @@
const int kCompatibleVersionNumber = 8;
const int kDeprecatedVersionNumber = 6; // and earlier.
-void FillIconMapping(const sql::Statement& statement,
- const GURL& page_url,
+void FillIconMapping(const GURL& page_url,
+ sql::Statement& statement,
IconMapping* icon_mapping) {
icon_mapping->mapping_id = statement.ColumnInt64(0);
icon_mapping->icon_id = statement.ColumnInt64(1);
@@ -241,7 +241,7 @@
IconMapping* icon_mapping) {
if (!statement_.Step())
return false;
- FillIconMapping(statement_, GURL(statement_.ColumnString(4)), icon_mapping);
+ FillIconMapping(GURL(statement_.ColumnString(4)), statement_, icon_mapping);
return true;
}
@@ -778,7 +778,7 @@
return result;
IconMapping icon_mapping;
- FillIconMapping(statement, page_url, &icon_mapping);
+ FillIconMapping(page_url, statement, &icon_mapping);
mapping_data->push_back(icon_mapping);
}
return result;
diff --git a/components/history/core/browser/url_database.cc b/components/history/core/browser/url_database.cc
index 4e02e88..afb3701 100644
--- a/components/history/core/browser/url_database.cc
+++ b/components/history/core/browser/url_database.cc
@@ -48,7 +48,7 @@
// Convenience to fill a URLRow. Must be in sync with the fields in
// kURLRowFields.
-void URLDatabase::FillURLRow(const sql::Statement& s, URLRow* i) {
+void URLDatabase::FillURLRow(sql::Statement& s, URLRow* i) {
DCHECK(i);
i->set_id(s.ColumnInt64(0));
i->set_url(GURL(s.ColumnString(1)));
diff --git a/components/history/core/browser/url_database.h b/components/history/core/browser/url_database.h
index 827b1ec..4c4ff99 100644
--- a/components/history/core/browser/url_database.h
+++ b/components/history/core/browser/url_database.h
@@ -293,7 +293,7 @@
// Convenience to fill a URLRow. Must be in sync with the fields in
// kHistoryURLRowFields.
- static void FillURLRow(const sql::Statement& s, URLRow* i);
+ static void FillURLRow(sql::Statement& s, URLRow* i);
// Returns the database for the functions in this interface. The descendant of
// this class implements these functions to return its objects.
diff --git a/components/history/core/browser/visit_annotations_database.cc b/components/history/core/browser/visit_annotations_database.cc
index 5874b6d..8762a31af 100644
--- a/components/history/core/browser/visit_annotations_database.cc
+++ b/components/history/core/browser/visit_annotations_database.cc
@@ -142,8 +142,7 @@
// Convenience to construct a `AnnotatedVisitRow`. Assumes the visit values are
// bound starting at index 0.
-AnnotatedVisitRow StatementToAnnotatedVisitRow(
- const sql::Statement& statement) {
+AnnotatedVisitRow StatementToAnnotatedVisitRow(sql::Statement& statement) {
return {statement.ColumnInt64(0),
ConstructContextAnnotationsWithFlags(
statement.ColumnInt64(1),
diff --git a/components/history/core/browser/visit_database.cc b/components/history/core/browser/visit_database.cc
index 5d42dd1..2c4aba0d 100644
--- a/components/history/core/browser/visit_database.cc
+++ b/components/history/core/browser/visit_database.cc
@@ -126,8 +126,7 @@
// Must be in sync with HISTORY_VISIT_ROW_FIELDS.
// static
-void VisitDatabase::FillVisitRow(const sql::Statement& statement,
- VisitRow* visit) {
+void VisitDatabase::FillVisitRow(sql::Statement& statement, VisitRow* visit) {
visit->visit_id = statement.ColumnInt64(0);
visit->url_id = statement.ColumnInt64(1);
visit->visit_time = base::Time::FromInternalValue(statement.ColumnInt64(2));
diff --git a/components/history/core/browser/visit_database.h b/components/history/core/browser/visit_database.h
index 42485f4..e251d9c2 100644
--- a/components/history/core/browser/visit_database.h
+++ b/components/history/core/browser/visit_database.h
@@ -229,7 +229,7 @@
// Convenience to fill a VisitRow. Assumes the visit values are bound starting
// at index 0.
- static void FillVisitRow(const sql::Statement& statement, VisitRow* visit);
+ static void FillVisitRow(sql::Statement& statement, VisitRow* visit);
// Convenience to fill a VisitVector. Assumes that statement.step()
// hasn't happened yet.
diff --git a/components/offline_pages/core/background/request_queue_store.cc b/components/offline_pages/core/background/request_queue_store.cc
index 68f58de1..bfad3cfe 100644
--- a/components/offline_pages/core/background/request_queue_store.cc
+++ b/components/offline_pages/core/background/request_queue_store.cc
@@ -217,7 +217,7 @@
// Create a save page request from the first row of an SQL result. The result
// must have the exact columns from the |REQUEST_QUEUE_FIELDS| macro.
std::unique_ptr<SavePageRequest> MakeSavePageRequest(
- const sql::Statement& statement) {
+ sql::Statement& statement) {
const int64_t id = statement.ColumnInt64(0);
const base::Time creation_time =
store_utils::FromDatabaseTime(statement.ColumnInt64(1));
diff --git a/components/offline_pages/core/model/get_pages_task.cc b/components/offline_pages/core/model/get_pages_task.cc
index 340a427..b3d3327 100644
--- a/components/offline_pages/core/model/get_pages_task.cc
+++ b/components/offline_pages/core/model/get_pages_task.cc
@@ -34,13 +34,13 @@
"file_path,title,original_url,request_origin,digest," \
"snippet,attribution"
-ClientId OfflinePageClientId(const sql::Statement& statement) {
+ClientId OfflinePageClientId(sql::Statement& statement) {
return ClientId(statement.ColumnString(7), statement.ColumnString(8));
}
// Create an offline page item from a SQL result.
// Expects the order of columns as defined by OFFLINE_PAGE_PROJECTION macro.
-OfflinePageItem MakeOfflinePageItem(const sql::Statement& statement) {
+OfflinePageItem MakeOfflinePageItem(sql::Statement& statement) {
OfflinePageItem item;
item.offline_id = statement.ColumnInt64(0);
item.creation_time = store_utils::FromDatabaseTime(statement.ColumnInt64(1));
diff --git a/components/offline_pages/core/prefetch/store/prefetch_store_test_util.cc b/components/offline_pages/core/prefetch/store/prefetch_store_test_util.cc
index 3fd64fe6..7883830 100644
--- a/components/offline_pages/core/prefetch/store/prefetch_store_test_util.cc
+++ b/components/offline_pages/core/prefetch/store/prefetch_store_test_util.cc
@@ -102,7 +102,7 @@
// Populates the PrefetchItem with the data from the current row of the passed
// in statement following the natural column ordering.
-absl::optional<PrefetchItem> ReadPrefetchItem(const sql::Statement& statement) {
+absl::optional<PrefetchItem> ReadPrefetchItem(sql::Statement& statement) {
PrefetchItem item;
DCHECK_EQ(23, statement.ColumnCount());
diff --git a/components/password_manager/core/browser/login_database.cc b/components/password_manager/core/browser/login_database.cc
index 3453aaa..da060e22 100644
--- a/components/password_manager/core/browser/login_database.cc
+++ b/components/password_manager/core/browser/login_database.cc
@@ -641,7 +641,7 @@
#if defined(OS_MAC)
// Fills |form| with necessary data required to be removed from the database
// and returns it.
-PasswordForm GetFormForRemoval(const sql::Statement& statement) {
+PasswordForm GetFormForRemoval(sql::Statement& statement) {
PasswordForm form;
form.url = GURL(statement.ColumnString(COLUMN_ORIGIN_URL));
form.username_element = statement.ColumnString16(COLUMN_USERNAME_ELEMENT);
@@ -1474,7 +1474,7 @@
}
LoginDatabase::EncryptionResult LoginDatabase::InitPasswordFormFromStatement(
- const sql::Statement& s,
+ sql::Statement& s,
bool decrypt_and_fill_password_value,
int* primary_key,
PasswordForm* form) const {
diff --git a/components/password_manager/core/browser/login_database.h b/components/password_manager/core/browser/login_database.h
index 2de9177fd..8108f17 100644
--- a/components/password_manager/core/browser/login_database.h
+++ b/components/password_manager/core/browser/login_database.h
@@ -283,7 +283,7 @@
// |decrypt_and_fill_password_value| is set to false, it always returns
// ENCRYPTION_RESULT_SUCCESS.
EncryptionResult InitPasswordFormFromStatement(
- const sql::Statement& s,
+ sql::Statement& s,
bool decrypt_and_fill_password_value,
int* primary_key,
PasswordForm* form) const WARN_UNUSED_RESULT;
diff --git a/components/password_manager/core/browser/login_database_unittest.cc b/components/password_manager/core/browser/login_database_unittest.cc
index 1cb17f05..c1634b9f 100644
--- a/components/password_manager/core/browser/login_database_unittest.cc
+++ b/components/password_manager/core/browser/login_database_unittest.cc
@@ -120,18 +120,18 @@
};
template <class T>
-T GetFirstColumn(const sql::Statement& s) {
+T GetFirstColumn(sql::Statement& s) {
static_assert(must_be_specialized<T>::is_specialized,
"Implement a specialization.");
}
template <>
-int64_t GetFirstColumn(const sql::Statement& s) {
+int64_t GetFirstColumn(sql::Statement& s) {
return s.ColumnInt64(0);
}
template <>
-std::string GetFirstColumn(const sql::Statement& s) {
+std::string GetFirstColumn(sql::Statement& s) {
return s.ColumnString(0);
}
diff --git a/components/search_engines/keyword_table.cc b/components/search_engines/keyword_table.cc
index 097582a..35f4a1e 100644
--- a/components/search_engines/keyword_table.cc
+++ b/components/search_engines/keyword_table.cc
@@ -454,7 +454,7 @@
}
// static
-bool KeywordTable::GetKeywordDataFromStatement(const sql::Statement& s,
+bool KeywordTable::GetKeywordDataFromStatement(sql::Statement& s,
TemplateURLData* data) {
DCHECK(data);
diff --git a/components/search_engines/keyword_table.h b/components/search_engines/keyword_table.h
index 7891e0d..94855eb 100644
--- a/components/search_engines/keyword_table.h
+++ b/components/search_engines/keyword_table.h
@@ -144,7 +144,7 @@
// Fills |data| with the data in |s|. Returns false if we couldn't fill
// |data| for some reason, e.g. |s| tried to set one of the fields to an
// illegal value.
- static bool GetKeywordDataFromStatement(const sql::Statement& s,
+ static bool GetKeywordDataFromStatement(sql::Statement& s,
TemplateURLData* data);
// Adds a new keyword, updating the id field on success.
diff --git a/content/browser/appcache/appcache_database.cc b/content/browser/appcache/appcache_database.cc
index e24c51f4..6293d8e 100644
--- a/content/browser/appcache/appcache_database.cc
+++ b/content/browser/appcache/appcache_database.cc
@@ -991,8 +991,8 @@
return statement.Succeeded();
}
-void AppCacheDatabase::ReadGroupRecord(
- const sql::Statement& statement, GroupRecord* record) {
+void AppCacheDatabase::ReadGroupRecord(sql::Statement& statement,
+ GroupRecord* record) {
record->group_id = statement.ColumnInt64(0);
record->origin = url::Origin::Create(GURL(statement.ColumnString(1)));
record->manifest_url = GURL(statement.ColumnString(2));
@@ -1015,8 +1015,8 @@
base::Time::FromInternalValue(statement.ColumnInt64(7));
}
-void AppCacheDatabase::ReadCacheRecord(
- const sql::Statement& statement, CacheRecord* record) {
+void AppCacheDatabase::ReadCacheRecord(sql::Statement& statement,
+ CacheRecord* record) {
record->cache_id = statement.ColumnInt64(0);
record->group_id = statement.ColumnInt64(1);
record->online_wildcard = statement.ColumnBool(2);
@@ -1030,8 +1030,8 @@
base::Time::FromInternalValue(statement.ColumnInt64(8));
}
-void AppCacheDatabase::ReadEntryRecord(
- const sql::Statement& statement, EntryRecord* record) {
+void AppCacheDatabase::ReadEntryRecord(sql::Statement& statement,
+ EntryRecord* record) {
record->cache_id = statement.ColumnInt64(0);
record->url = GURL(statement.ColumnString(1));
record->flags = statement.ColumnInt(2);
@@ -1056,8 +1056,8 @@
}
}
-void AppCacheDatabase::ReadNamespaceRecord(
- const sql::Statement* statement, NamespaceRecord* record) {
+void AppCacheDatabase::ReadNamespaceRecord(sql::Statement* statement,
+ NamespaceRecord* record) {
record->cache_id = statement->ColumnInt64(0);
record->origin = url::Origin::Create(GURL(statement->ColumnString(1)));
record->namespace_.type =
@@ -1071,7 +1071,7 @@
base::Time::FromInternalValue(statement->ColumnInt64(5));
}
-void AppCacheDatabase::ReadOnlineSafeListRecord(const sql::Statement& statement,
+void AppCacheDatabase::ReadOnlineSafeListRecord(sql::Statement& statement,
OnlineSafeListRecord* record) {
record->cache_id = statement.ColumnInt64(0);
record->namespace_url = GURL(statement.ColumnString(1));
diff --git a/content/browser/appcache/appcache_database.h b/content/browser/appcache/appcache_database.h
index 2ff711d6..f3072d9 100644
--- a/content/browser/appcache/appcache_database.h
+++ b/content/browser/appcache/appcache_database.h
@@ -229,16 +229,15 @@
std::set<int64_t>* ids_set);
// Record retrieval helpers
- void ReadGroupRecord(const sql::Statement& statement, GroupRecord* record);
- void ReadCacheRecord(const sql::Statement& statement, CacheRecord* record);
- void ReadEntryRecord(const sql::Statement& statement, EntryRecord* record);
+ void ReadGroupRecord(sql::Statement& statement, GroupRecord* record);
+ void ReadCacheRecord(sql::Statement& statement, CacheRecord* record);
+ void ReadEntryRecord(sql::Statement& statement, EntryRecord* record);
void ReadNamespaceRecords(
sql::Statement* statement,
NamespaceRecordVector* intercepts,
NamespaceRecordVector* fallbacks);
- void ReadNamespaceRecord(
- const sql::Statement* statement, NamespaceRecord* record);
- void ReadOnlineSafeListRecord(const sql::Statement& statement,
+ void ReadNamespaceRecord(sql::Statement* statement, NamespaceRecord* record);
+ void ReadOnlineSafeListRecord(sql::Statement& statement,
OnlineSafeListRecord* record);
// Database creation
diff --git a/sql/statement.cc b/sql/statement.cc
index e69c931..c3b55c3 100644
--- a/sql/statement.cc
+++ b/sql/statement.cc
@@ -402,7 +402,7 @@
static_assert(static_cast<int>(ColumnType::kNull) == SQLITE_NULL,
"NULL mismatch");
-ColumnType Statement::GetColumnType(int col) const {
+ColumnType Statement::GetColumnType(int col) {
#if !defined(OS_ANDROID) // TODO(crbug.com/866218): Remove this conditional
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
#endif // OS_ANDROID
@@ -415,14 +415,14 @@
return static_cast<enum ColumnType>(sqlite3_column_type(ref_->stmt(), col));
}
-bool Statement::ColumnBool(int column_index) const {
+bool Statement::ColumnBool(int column_index) {
#if !defined(OS_ANDROID) // TODO(crbug.com/866218): Remove this conditional
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
#endif // OS_ANDROID
return static_cast<bool>(ColumnInt64(column_index));
}
-int Statement::ColumnInt(int column_index) const {
+int Statement::ColumnInt(int column_index) {
#if !defined(OS_ANDROID) // TODO(crbug.com/866218): Remove this conditional
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
#endif // OS_ANDROID
@@ -441,7 +441,7 @@
return sqlite3_column_int(ref_->stmt(), column_index);
}
-int64_t Statement::ColumnInt64(int column_index) const {
+int64_t Statement::ColumnInt64(int column_index) {
#if !defined(OS_ANDROID) // TODO(crbug.com/866218): Remove this conditional
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
#endif // OS_ANDROID
@@ -460,7 +460,7 @@
return sqlite3_column_int64(ref_->stmt(), column_index);
}
-double Statement::ColumnDouble(int column_index) const {
+double Statement::ColumnDouble(int column_index) {
#if !defined(OS_ANDROID) // TODO(crbug.com/866218): Remove this conditional
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
#endif // OS_ANDROID
@@ -479,7 +479,7 @@
return sqlite3_column_double(ref_->stmt(), column_index);
}
-base::Time Statement::ColumnTime(int column_index) const {
+base::Time Statement::ColumnTime(int column_index) {
#if !defined(OS_ANDROID) // TODO(crbug.com/866218): Remove this conditional
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
#endif // OS_ANDROID
@@ -500,7 +500,7 @@
base::TimeDelta::FromMicroseconds(int_value));
}
-std::string Statement::ColumnString(int column_index) const {
+std::string Statement::ColumnString(int column_index) {
#if !defined(OS_ANDROID) // TODO(crbug.com/866218): Remove this conditional
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
#endif // OS_ANDROID
@@ -526,7 +526,7 @@
return result;
}
-std::u16string Statement::ColumnString16(int column_index) const {
+std::u16string Statement::ColumnString16(int column_index) {
#if !defined(OS_ANDROID) // TODO(crbug.com/866218): Remove this conditional
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
#endif // OS_ANDROID
@@ -546,7 +546,7 @@
return string.empty() ? std::u16string() : base::UTF8ToUTF16(string);
}
-int Statement::ColumnByteLength(int column_index) const {
+int Statement::ColumnByteLength(int column_index) {
#if !defined(OS_ANDROID) // TODO(crbug.com/866218): Remove this conditional
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
#endif // OS_ANDROID
@@ -565,7 +565,7 @@
return sqlite3_column_bytes(ref_->stmt(), column_index);
}
-const void* Statement::ColumnBlob(int column_index) const {
+const void* Statement::ColumnBlob(int column_index) {
#if !defined(OS_ANDROID) // TODO(crbug.com/866218): Remove this conditional
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
#endif // OS_ANDROID
@@ -584,8 +584,7 @@
return sqlite3_column_blob(ref_->stmt(), column_index);
}
-bool Statement::ColumnBlobAsString(int column_index,
- std::string* result) const {
+bool Statement::ColumnBlobAsString(int column_index, std::string* result) {
#if !defined(OS_ANDROID) // TODO(crbug.com/866218): Remove this conditional
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
#endif // OS_ANDROID
@@ -612,7 +611,7 @@
}
bool Statement::ColumnBlobAsVector(int column_index,
- std::vector<char>* result) const {
+ std::vector<char>* result) {
#if !defined(OS_ANDROID) // TODO(crbug.com/866218): Remove this conditional
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
#endif // OS_ANDROID
@@ -642,7 +641,7 @@
}
bool Statement::ColumnBlobAsVector(int column_index,
- std::vector<uint8_t>* result) const {
+ std::vector<uint8_t>* result) {
#if !defined(OS_ANDROID) // TODO(crbug.com/866218): Remove this conditional
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
#endif // OS_ANDROID
diff --git a/sql/statement.h b/sql/statement.h
index c664ab8..91871fc 100644
--- a/sql/statement.h
+++ b/sql/statement.h
@@ -162,15 +162,15 @@
// "type conversion." This means requesting the value of a column of a type
// where that type is not the native type. For safety, call ColumnType only
// on a column before getting the value out in any way.
- ColumnType GetColumnType(int col) const;
+ ColumnType GetColumnType(int col);
// These all take a 0-based argument index.
- bool ColumnBool(int column_index) const;
- int ColumnInt(int column_index) const;
- int64_t ColumnInt64(int column_index) const;
- double ColumnDouble(int column_index) const;
- std::string ColumnString(int column_index) const;
- std::u16string ColumnString16(int column_index) const;
+ bool ColumnBool(int column_index);
+ int ColumnInt(int column_index);
+ int64_t ColumnInt64(int column_index);
+ double ColumnDouble(int column_index);
+ std::string ColumnString(int column_index);
+ std::u16string ColumnString16(int column_index);
// Conforms with base::Time serialization recommendations.
//
@@ -181,16 +181,16 @@
//
// TODO(crbug.com/1195962): Migrate all time serialization to this method, and
// then remove the migration details above.
- base::Time ColumnTime(int column_index) const;
+ base::Time ColumnTime(int column_index);
// When reading a blob, you can get a raw pointer to the underlying data,
// along with the length, or you can just ask us to copy the blob into a
// vector. Danger! ColumnBlob may return nullptr if there is no data!
- int ColumnByteLength(int column_index) const;
- const void* ColumnBlob(int column_index) const;
- bool ColumnBlobAsString(int column_index, std::string* result) const;
- bool ColumnBlobAsVector(int column_index, std::vector<char>* result) const;
- bool ColumnBlobAsVector(int column_index, std::vector<uint8_t>* result) const;
+ int ColumnByteLength(int column_index);
+ const void* ColumnBlob(int column_index);
+ bool ColumnBlobAsString(int column_index, std::string* result);
+ bool ColumnBlobAsVector(int column_index, std::vector<char>* result);
+ bool ColumnBlobAsVector(int column_index, std::vector<uint8_t>* result);
// Diagnostics --------------------------------------------------------------