wxSQLite3  5.0.1
Loading...
Searching...
No Matches
Migration Guide

This guide describes the source-level changes required when migrating existing applications from the previous wxSQLite3 API (version 4.x) to the modernized API.

The migration is primarily a matter of adapting class names and enumerations to the new C++ namespace and scoped-enumeration conventions. The underlying database API and its concepts remain largely unchanged.

1. Class names and the wxSQLite3 namespace

All wxSQLite3 classes are now contained in the wxSQLite3 namespace.

In previous versions, the namespace was effectively encoded in the class names using the wxSQLite3 prefix. The prefix has been replaced by the namespace qualifier.

For example:

wxSQLite3Database db;
wxSQLite3Statement stmt;
wxSQLite3ResultSet resultSet;

becomes:

Represents a SQLite3 database object.
Definition wxsqlite3.h:3266
Result set of a SQL query.
Definition wxsqlite3.h:1809
Represents a prepared SQL statement.
Definition wxsqlite3.h:2586

This change applies consistently to the wxSQLite3 classes.

Consequently, in most existing source code the required change is simply to replace the wxSQLite3 class-name prefix with wxSQLite3::.

For applications that use many wxSQLite3 classes, a namespace declaration can optionally be used to reduce the amount of qualification:

using namespace wxSQLite3;
Definition wxsqlite3.h:78

or, preferably when only selected types are required:

Using the namespace explicitly is generally recommended in headers and in code where avoiding name ambiguity is important.

2. Enumerations are now scoped enumerations

The wxSQLite3 API now consistently uses C++11 scoped enumerations (enum class) instead of unscoped enumerations.

As a consequence, enumeration values must normally be qualified with the corresponding enumeration type.

For example, code using an unscoped enumeration such as:

db.SetJournalMode(WXSQLITE_JOURNALMODE_WAL);
JournalMode SetJournalMode(JournalMode mode, const wxString &database=wxEmptyString)
Set SQLite journal mode.

must now use the scoped enumeration value:

@ JOURNALMODE_WAL
Use write-ahead logging.
Definition wxsqlite3.h:306

The exact enumeration type and value names depend on the API being used.

Renamed enumeration values

Enumeration values have also been renamed to make them more concise and consistent.

Prefixes that were previously required to distinguish enumeration values in the global namespace have been removed. For example, prefixes such as WXSQLITE_ are no longer part of the enumeration value names.

Similarly, values that previously used names such as SQLITE_... have been adapted to the new scoped-enumeration naming convention.

Therefore, migration of enumeration values generally requires two changes:

  1. Add the enumeration type as a qualifier.
  2. Adapt the enumeration value name to its new, shorter form.

For example:

old_enum_value

becomes conceptually:

EnumType::NewValue

The API documentation lists the current enumeration types and their available values.

Because enumeration values are now scoped, they no longer implicitly convert to integers. Code that relied on such implicit conversions may therefore require an explicit conversion, for example:

const int value = static_cast<int>(enumValue);

Where possible, however, it is preferable to keep values as their enumeration type rather than converting them to integers.

Tables with renaming rules

The following table shows the renaming rules for enumeration types:

Type name: Old NewValue: Old New
wxSQLite3CipherType
wxSQLite3::CipherType
WXSQLITE_CIPHER_*
CipherType::*
wxSQLite3TransactionType
wxSQLite3::TransactionType
WXSQLITE_TRANSACTION_*
TransactionType::TRANSACTION_*
wxSQLite3TransactionState
wxSQLite3::TransactionState
WXSQLITE_TRANSACTION_*
TransactionState::TRANSACTION_*
wxSQLite3LimitType
wxSQLite3::LimitType
WXSQLITE_LIMIT_*
LimitType::LIMIT_*
wxSQLite3JournalMode
wxSQLite3::JournalMode
WXSQLITE_JOURNALMODE_*
JournalMode::JOURNALMODE_*
wxSQLite3StatementStatus
wxSQLite3::StatementStatus
WXSQLITE_STMTSTATUS_*
StatementStatus::STMTSTATUS_*
wxSQLite3DbConfig
wxSQLite3::DbConfig
WXSQLITE_DBCONFIG_*
DbConfig::DBCONFIG_*
wxSQLite3Authorizer::wxAuthorizationCode
wxSQLite3::AuthorizationCode
SQLITE_*
AuthorizationCode::AUTH_*
wxSQLite3Hook::wxUpdateType
wxSQLite3::AuthorizationCode
SQLITE_*
AuthorizationCode::AUTH_*

Many symbols were defined via preprocessor symbols using the #define preprocessor statements. These symbols were mostly replaced by constexpr int expressions. In that course symbol names were shortened by removing prefixes like WXSQLITE or SQLITE. The following table shows the renaming rules for those symbols:

DescriptionSymbol: Old⇒ New
Result codesSQLITE_* wxSQLite3::RC_*
Data typesSQLITE_REAL wxSQLite3::TYPE_REAL
Open flagsWXSQLITE_OPEN_* wxSQLite3::OPEN_*
Checkpoint flagsWXSQLITE_CHECKPOINT_* wxSQLite3::CHECKPOINT_*
Function flagsWXSQLITE_* wxSQLite3::FUNC_*

3. Modern C++ features

Apart from the namespace and enumeration changes, the existing wxSQLite3 API remains largely compatible. The modernized API adds several optional ways of working with result sets and prepared statements.

These additions do not require existing code to be rewritten.

Template-based value access

Values can be retrieved from a result set using template-based Get<T>() methods. These methods use std::optional<T> to represent SQL NULL values.

For example:

const auto id = resultSet.Get<int>(0);
std::optional< T > Get(int columnIndex) const
Get a column as a std::optional value using the column index.
Definition wxsqlite3.h:2254

An empty std::optional indicates that the database value is SQL NULL.

Template-based parameter binding

Prepared-statement parameters can similarly be bound using the template-based Bind() methods. std::optional<T> can be used to bind either a value or SQL NULL.

auto id = std::optional<int>(4711);
auto name = std::optional<wxString>(std::nullopt);
stmt.Bind(1, id);
stmt.Bind(2, name);
void Bind(int paramIndex, const wxString &stringValue)
Bind parameter to a string value.

The existing type-specific methods remain available, so this is an optional modernization rather than a required migration step.

Tuple-based access and binding

GetTuple() and BindTuple() provide a convenient way to retrieve or bind several values as a group.

Both methods are available in two forms:

using consecutive column or parameter indices; using an array of explicitly specified indices.

These methods are also optional and can be introduced incrementally into existing code.

Iterator and range-based result-set processing

wxSQLite3::ResultSet can now be used with standard C++ iterators and range-based for loops.

Existing cursor-based code such as:

while (resultSet.NextRow())
{
// Process row
}
bool NextRow()
Retrieve next row of the result set.

can therefore be written as:

for (const auto& row : resultSet)
{
// Process row
}

The traditional cursor-based interface remains available, so existing result-set processing does not have to be changed as part of the migration.

Summary

For most applications, migration consists primarily of:

  1. Replacing the old wxSQLite3ClassName class names with wxSQLite3::ClassName.
  2. Qualifying enumeration values with their enum class type.
  3. Updating enumeration value names to their new, shorter names.
  4. Optionally adopting the new template-based, tuple-based, and iterator/range-based interfaces.

The first two changes are source-level compatibility changes. The modern C++ features are additions to the API and therefore do not require changes to existing code.