|
KiCad PCB EDA Suite
|
Reads a database through an ODBC data source or connection string. More...
#include <odbc_backend.h>
Classes | |
| struct | COLUMN_INFO |
| ODBC description of a column, so a lookup key can be bound with the type the driver expects. More... | |
| struct | DATA_SOURCE |
| A data source configured in the ODBC driver manager. More... | |
| struct | KEY_PARAMETER |
| How ReadRow describes its key parameter to the driver. More... | |
| struct | SELECTOR |
| The keyword ODBC uses to choose where a connection string connects. More... | |
Public Types | |
| using | DSN_LOOKUP = std::function<std::optional<std::string>( const std::string& )> |
| Resolves a data source name to its driver, or nullopt if it is unknown. | |
Public Member Functions | |
| ODBC_BACKEND (std::string aDsn, std::string aUser, std::string aPass, std::string aConnectionString, long aTimeout) | |
| ~ODBC_BACKEND () override | |
| bool | Connect () override |
| void | Disconnect () override |
| bool | IsConnected () const override |
| bool | ListTables (std::vector< std::string > &aTables) override |
| Lists the tables and views, sorted by name. | |
| std::optional< DB_TABLE_INFO > | DescribeTable (const std::string &aTable) override |
| bool | ListColumns (const std::string &aTable, std::vector< std::string > &aColumns) override |
| Lists the column names of a table as the catalog reports them, empty if it has none, false if the catalog failed. | |
| bool | ReadTable (const DB_TABLE_INFO &aTable, const std::vector< std::string > &aColumns, size_t aMaxRows, std::vector< std::string > &aLabels, const DB_ROW_SINK &aSink) override |
| Reads rows of a table, handing each to aSink. | |
| std::optional< bool > | ReadRow (const DB_TABLE_INFO &aTable, const std::vector< std::string > &aColumns, const std::string &aKeyColumn, const std::string &aKey, std::vector< std::string > &aLabels, std::vector< DB_VALUE > &aRow) override |
| Runs a prepared query whose key parameter is described with the key column's catalog type. | |
| std::string | GetLastError () const override |
| DB_FAILURE | GetLastFailure () const override |
| virtual bool | ReadAllRows (const DB_TABLE_INFO &aTable, const std::vector< std::string > &aColumns, std::vector< std::string > &aLabels, const DB_ROW_SINK &aSink, const DB_RESTART_SINK &aRestart) |
| Reads every row of a table for a caller that keeps them, handing each to aSink. | |
| virtual void | BeginLoadCycle (const DB_STOP_CHECK &aStopped) |
| Brackets a load cycle, in which the caller reads each table once. | |
| virtual void | EndLoadCycle () |
Static Public Member Functions | |
| static std::vector< DATA_SOURCE > | ListDataSourceDetails () |
| static std::vector< std::string > | ListDrivers () |
| static SELECTOR | FirstSelector (const std::string &aConnectionString) |
| static bool | NeedsDriverLock (const std::string &aDsn, const std::string &aConnectionString, const DSN_LOOKUP &aLookup) |
| Decides whether connecting must be serialized because the effective driver is, or may be, the Microsoft Access driver. | |
| static bool | IsAccessDriver (const std::string &aDriverName) |
| static bool | IsAccessFileInUse (const std::string &aLowerMessage) |
| static DB_FAILURE | ClassifyFailure (const std::string &aState, const std::string &aMessage) |
| Classifies a driver error from its SQLSTATE, falling back to its text since drivers disagree on states. | |
| static KEY_PARAMETER | DescribeKeyParameter (int aColumnType, long aColumnSize, short aColumnScale, const std::string &aKey) |
| Chooses the parameter description for a lookup key from its column's cached ODBC description. | |
| static DB_BACKEND_RESULT | Create (const DATABASE_SOURCE &aSource, const wxString &aBasePath) |
| Builds the backend for a source. | |
Static Public Attributes | |
| static constexpr size_t | ALL_ROWS = std::numeric_limits<size_t>::max() |
| Passed as ReadTable()'s row limit to read every row. | |
Private Member Functions | |
| bool | getQuoteChar () |
| bool | takeAccessDriverLock (std::unique_lock< std::timed_mutex > &aLock) |
| Takes the lock that keeps the Access driver from initializing or unloading on two threads at once. | |
| void | disconnectLocked () |
| Closes the connection with the driver lock held by the caller. | |
| std::string | quoted (const std::string &aIdentifier) const |
| Wraps an identifier in the driver's quote character, doubling any it contains. | |
| std::string | escapePattern (const std::string &aName) const |
| Escapes catalog search pattern characters so a name matches only itself. | |
| std::string | columnList (const std::vector< std::string > &aColumns) const |
Private Attributes | |
| std::unique_ptr< nanodbc::connection > | m_conn |
| std::string | m_dsn |
| std::string | m_user |
| std::string | m_pass |
| std::string | m_connectionString |
| bool | m_accessDriver = false |
| std::optional< std::chrono::steady_clock::time_point > | m_engineDeadline |
| When the wait for the Access driver lock ends, fixed by the first step that finds the lock busy and never renewed, so it stays spent until the next Connect. | |
| std::string | m_lastError |
| DB_FAILURE | m_lastFailure = DB_FAILURE::UNKNOWN |
| std::map< std::string, std::map< std::string, COLUMN_INFO > > | m_columnInfo |
| Map of table -> map of column name -> column description. | |
| long | m_timeout |
| char | m_quoteChar = '"' |
| std::string | m_patternEscape |
Reads a database through an ODBC data source or connection string.
Definition at line 43 of file odbc_backend.h.
| using ODBC_BACKEND::DSN_LOOKUP = std::function<std::optional<std::string>( const std::string& )> |
Resolves a data source name to its driver, or nullopt if it is unknown.
Definition at line 112 of file odbc_backend.h.
| ODBC_BACKEND::ODBC_BACKEND | ( | std::string | aDsn, |
| std::string | aUser, | ||
| std::string | aPass, | ||
| std::string | aConnectionString, | ||
| long | aTimeout ) |
| aDsn | the data source name, ignored when aConnectionString is set |
| aConnectionString | a full ODBC connection string, or empty to use the data source name |
| aTimeout | the login timeout and query timeout in seconds |
Definition at line 141 of file odbc_backend.cpp.
References ListDataSourceDetails(), m_accessDriver, m_connectionString, m_dsn, m_pass, m_timeout, m_user, move, NeedsDriverLock(), and source.
|
override |
Definition at line 185 of file odbc_backend.cpp.
References disconnectLocked(), m_conn, MarkAccessWorkerAbandoned(), and takeAccessDriverLock().
|
inlinevirtualinherited |
Brackets a load cycle, in which the caller reads each table once.
A backend may keep what it opens for the cycle's reads until the cycle ends. Cycles may nest, and only the outermost begin and end count. Nesting is backend-wide and may cross threads, as when a lookup on one thread reads a table while a refresh on another has a cycle open. The nested read keeps the stop check and sessions of the outermost cycle.
| aStopped | may be empty; a backend that retries a read gives up when it returns true |
Reimplemented in ACE_BACKEND.
Definition at line 161 of file database_backend.h.
|
static |
Classifies a driver error from its SQLSTATE, falling back to its text since drivers disagree on states.
Definition at line 993 of file odbc_backend.cpp.
References FILE_IN_USE, IsAccessFileInUse(), LOGIN, message, NO_DRIVER, NO_DSN, TIMEOUT, UNKNOWN, and UNREACHABLE.
Referenced by Connect().
|
private |
Definition at line 602 of file odbc_backend.cpp.
References quoted().
Referenced by ReadRow(), and ReadTable().
|
overridevirtual |
Implements DATABASE_BACKEND.
Definition at line 350 of file odbc_backend.cpp.
References AccessEngineBusyMessage(), ClassifyFailure(), cs, fromUTF8(), getQuoteChar(), IsConnected(), m_conn, m_connectionString, m_dsn, m_engineDeadline, m_lastError, m_lastFailure, m_pass, m_patternEscape, m_timeout, m_user, takeAccessDriverLock(), TIMEOUT, toUTF8(), traceDatabase, and UNKNOWN.
|
staticinherited |
Builds the backend for a source.
| aSource | the source as configured; ${CWD} is expanded in its connection string and path |
| aBasePath | the directory ${CWD} stands for |
Definition at line 34 of file database_backend.cpp.
References _, ACCESS, DATABASE_SOURCE::Expanded(), INVALID, INVALID_TYPE, ACE_BACKEND::MISSING, NOT_SUPPORTED_ON_PLATFORM, ODBC, PROVIDER_MISSING, ACE_BACKEND::ProviderMissingMessage(), ACE_BACKEND::ProviderState(), source, SQLITE, UNKNOWN, and utf8().
Referenced by SCH_IO_DATABASE::connectOnce(), and SCH_IO_DATABASE::CreateConnection().
|
static |
Chooses the parameter description for a lookup key from its column's cached ODBC description.
Strict drivers (Microsoft Access) reject a key whose type does not match the column.
| aColumnType | is the ODBC SQL data type of the key column |
| aColumnSize | is its character length or numeric precision, zero or negative when unknown |
| aColumnScale | is its number of digits right of the decimal point |
| aKey | is the key text |
Definition at line 626 of file odbc_backend.cpp.
References DEFAULT_KEY_CHAR_SIZE, DEFAULT_KEY_DECIMAL_SIZE, DEFAULT_KEY_INTEGER_SIZE, end, and MAX_KEY_CHAR_SIZE.
Referenced by ReadRow().
|
overridevirtual |
Implements DATABASE_BACKEND.
Definition at line 457 of file odbc_backend.cpp.
References escapePattern(), fromUTF8(), info, m_columnInfo, m_conn, m_lastError, m_lastFailure, name, toUTF8(), traceDatabase, and UNKNOWN.
|
overridevirtual |
Implements DATABASE_BACKEND.
Definition at line 414 of file odbc_backend.cpp.
References AccessEngineBusyMessage(), disconnectLocked(), m_conn, m_lastError, m_lastFailure, takeAccessDriverLock(), TIMEOUT, and traceDatabase.
Referenced by ReadRow(), and ReadTable().
|
private |
Closes the connection with the driver lock held by the caller.
Definition at line 435 of file odbc_backend.cpp.
References m_conn, and traceDatabase.
Referenced by Disconnect(), and ~ODBC_BACKEND().
|
inlinevirtualinherited |
Reimplemented in ACE_BACKEND.
Definition at line 163 of file database_backend.h.
|
private |
Escapes catalog search pattern characters so a name matches only itself.
Definition at line 582 of file odbc_backend.cpp.
References m_patternEscape.
Referenced by DescribeTable(), ListColumns(), and ListTables().
|
static |
Definition at line 238 of file odbc_backend.cpp.
References ODBC_BACKEND::SELECTOR::DRIVER, ODBC_BACKEND::SELECTOR::DSN, end, and ODBC_BACKEND::SELECTOR::FILE_DSN.
Referenced by NeedsDriverLock().
|
inlineoverridevirtual |
|
inlineoverridevirtual |
Implements DATABASE_BACKEND.
Definition at line 78 of file odbc_backend.h.
References m_lastFailure.
|
private |
Definition at line 544 of file odbc_backend.cpp.
References m_conn, m_lastError, m_quoteChar, toUTF8(), and traceDatabase.
Referenced by Connect().
|
static |
Definition at line 344 of file odbc_backend.cpp.
Referenced by NeedsDriverLock().
|
static |
Definition at line 968 of file odbc_backend.cpp.
Referenced by ClassifyFailure().
|
overridevirtual |
Implements DATABASE_BACKEND.
Definition at line 448 of file odbc_backend.cpp.
References m_conn.
Referenced by Connect().
|
overridevirtual |
Lists the column names of a table as the catalog reports them, empty if it has none, false if the catalog failed.
Reimplemented from DATABASE_BACKEND.
Definition at line 517 of file odbc_backend.cpp.
References escapePattern(), fromUTF8(), m_conn, m_lastError, toUTF8(), and traceDatabase.
|
static |
Definition at line 932 of file odbc_backend.cpp.
References source, toUTF8(), and traceDatabase.
Referenced by DIALOG_DATABASE_LIB_SETTINGS::loadDataSources(), and ODBC_BACKEND().
|
static |
Definition at line 950 of file odbc_backend.cpp.
References toUTF8(), and traceDatabase.
Referenced by DIALOG_DATABASE_LIB_SETTINGS::TransferDataToWindow().
|
overridevirtual |
Lists the tables and views, sorted by name.
Implements DATABASE_BACKEND.
Definition at line 880 of file odbc_backend.cpp.
References escapePattern(), fromUTF8(), m_conn, m_lastError, toUTF8(), and traceDatabase.
|
static |
Decides whether connecting must be serialized because the effective driver is, or may be, the Microsoft Access driver.
Anything that cannot be resolved without loading a driver is serialized.
| aDsn | is the data source name, used when the connection string is empty |
| aLookup | resolves a data source name to its driver |
Definition at line 314 of file odbc_backend.cpp.
References ODBC_BACKEND::SELECTOR::DRIVER, ODBC_BACKEND::SELECTOR::DSN, ODBC_BACKEND::SELECTOR::FILE_DSN, FirstSelector(), IsAccessDriver(), and ODBC_BACKEND::SELECTOR::NONE.
Referenced by ODBC_BACKEND().
|
private |
Wraps an identifier in the driver's quote character, doubling any it contains.
Definition at line 571 of file odbc_backend.cpp.
References m_quoteChar.
Referenced by columnList(), ReadRow(), and ReadTable().
|
inlinevirtualinherited |
Reads every row of a table for a caller that keeps them, handing each to aSink.
A backend that checks one read against another may deliver the table more than once, and calls aRestart before every delivery after the first, so the caller drops the rows it already took. The default reads once.
| aLabels | is filled with the result-column labels before each delivery's first call to aSink |
Reimplemented in ACE_BACKEND.
Definition at line 146 of file database_backend.h.
References ALL_ROWS, and ReadTable().
|
overridevirtual |
Runs a prepared query whose key parameter is described with the key column's catalog type.
Reimplemented from DATABASE_BACKEND.
Definition at line 676 of file odbc_backend.cpp.
References ODBC_BACKEND::KEY_PARAMETER::asInteger, columnList(), decodeRow(), DescribeKeyParameter(), Disconnect(), fromUTF8(), ODBC_BACKEND::KEY_PARAMETER::integerValue, m_columnInfo, m_conn, m_lastError, PROF_TIMER::msecs(), DB_TABLE_INFO::name, quoted(), resultColumns(), ODBC_BACKEND::COLUMN_INFO::scale, ODBC_BACKEND::KEY_PARAMETER::scale, ODBC_BACKEND::COLUMN_INFO::size, ODBC_BACKEND::KEY_PARAMETER::size, PROF_TIMER::Stop(), table, toUTF8(), traceDatabase, ODBC_BACKEND::COLUMN_INFO::type, and ODBC_BACKEND::KEY_PARAMETER::type.
|
overridevirtual |
Reads rows of a table, handing each to aSink.
| aColumns | the columns to read; empty reads all of them |
| aMaxRows | stops after this many rows; zero fills aLabels and fetches no rows. A bounded read is ordered by the first column where the backend can. |
| aLabels | is filled with the result-column labels as the source spells them, before the first call to aSink |
Implements DATABASE_BACKEND.
Definition at line 795 of file odbc_backend.cpp.
References DATABASE_BACKEND::ALL_ROWS, columnList(), decodeRow(), Disconnect(), fromUTF8(), m_conn, m_lastError, m_timeout, PROF_TIMER::msecs(), DB_TABLE_INFO::name, quoted(), resultColumns(), rows, PROF_TIMER::Stop(), and traceDatabase.
|
private |
Takes the lock that keeps the Access driver from initializing or unloading on two threads at once.
The lock is not taken for any other driver, and never off Windows. Connect, Disconnect and destruction share one deadline while the lock stays out of reach, so a stalled Access worker costs one wait.
Definition at line 210 of file odbc_backend.cpp.
References AccessEngineMutex(), DB_WORKER_THREAD::CallerBound(), LockAccessEngine(), m_accessDriver, m_engineDeadline, m_timeout, and traceDatabase.
Referenced by Connect(), Disconnect(), and ~ODBC_BACKEND().
|
staticconstexprinherited |
Passed as ReadTable()'s row limit to read every row.
Definition at line 106 of file database_backend.h.
Referenced by ReadAllRows(), ACE_BACKEND::ReadTable(), ODBC_BACKEND::ReadTable(), SQLITE_BACKEND::ReadTable(), and ACE_BACKEND::readVerified().
|
private |
Definition at line 186 of file odbc_backend.h.
Referenced by ODBC_BACKEND(), and takeAccessDriverLock().
|
private |
Map of table -> map of column name -> column description.
Definition at line 204 of file odbc_backend.h.
Referenced by DescribeTable(), and ReadRow().
|
private |
Definition at line 179 of file odbc_backend.h.
Referenced by Connect(), DescribeTable(), Disconnect(), disconnectLocked(), getQuoteChar(), IsConnected(), ListColumns(), ListTables(), ReadRow(), ReadTable(), and ~ODBC_BACKEND().
|
private |
Definition at line 184 of file odbc_backend.h.
Referenced by Connect(), and ODBC_BACKEND().
|
private |
Definition at line 181 of file odbc_backend.h.
Referenced by Connect(), and ODBC_BACKEND().
|
private |
When the wait for the Access driver lock ends, fixed by the first step that finds the lock busy and never renewed, so it stays spent until the next Connect.
Definition at line 190 of file odbc_backend.h.
Referenced by Connect(), and takeAccessDriverLock().
|
private |
Definition at line 192 of file odbc_backend.h.
Referenced by Connect(), DescribeTable(), Disconnect(), GetLastError(), getQuoteChar(), ListColumns(), ListTables(), ReadRow(), and ReadTable().
|
private |
Definition at line 193 of file odbc_backend.h.
Referenced by Connect(), DescribeTable(), Disconnect(), and GetLastFailure().
|
private |
Definition at line 183 of file odbc_backend.h.
Referenced by Connect(), and ODBC_BACKEND().
|
private |
Definition at line 210 of file odbc_backend.h.
Referenced by Connect(), and escapePattern().
|
private |
Definition at line 208 of file odbc_backend.h.
Referenced by getQuoteChar(), and quoted().
|
private |
Definition at line 206 of file odbc_backend.h.
Referenced by Connect(), ODBC_BACKEND(), ReadTable(), and takeAccessDriverLock().
|
private |
Definition at line 182 of file odbc_backend.h.
Referenced by Connect(), and ODBC_BACKEND().