20#ifndef KICAD_ACE_BACKEND_H
21#define KICAD_ACE_BACKEND_H
45 using CLOCK = std::chrono::steady_clock;
89 ACE_BACKEND( std::string aPath, std::string aPassword,
int aTimeoutSeconds );
99 bool ListTables( std::vector<std::string>& aTables )
override;
101 std::optional<DB_TABLE_INFO>
DescribeTable(
const std::string& aTable )
override;
104 std::vector<std::string>& aLabels,
const DB_ROW_SINK& aSink )
override;
127 std::vector<std::string>& aLabels,
const DB_ROW_SINK& aSink,
189 std::optional<PASS_DIGEST>
readPass( uint64_t aSession,
const std::string& aSql,
const std::string& aUnorderedSql,
190 size_t aMaxRows, std::vector<std::string>& aLabels,
const DB_ROW_SINK* aSink,
191 std::optional<ACE_ENGINE_OP::CLOCK::time_point> aDeadline = std::nullopt );
196 std::optional<uint64_t>
freshSession(
const std::string& aTable, ACE_ENGINE_OP::CLOCK::time_point aDeadline,
197 const std::function<
bool()>& aMayStart );
214 template <
typename R>
216 std::shared_ptr<ACE_ENGINE_OP> aOp =
nullptr,
217 std::optional<std::chrono::milliseconds> aProgressBound = std::nullopt );
222 void dropConnection( std::shared_ptr<ACE_ENGINE_OP> aOp =
nullptr,
bool aForExit =
false );
226 bool closeOnWorker( std::vector<uint64_t> aIds, std::shared_ptr<ACE_ENGINE_OP> aOp,
227 std::optional<std::chrono::milliseconds> aBound = std::nullopt );
232 std::shared_ptr<ACE_ENGINE_OP>
newOp()
const;
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.
void dropConnection(std::shared_ptr< ACE_ENGINE_OP > aOp=nullptr, bool aForExit=false)
Forgets the connection and the cycle's sessions and closes them on the worker thread,...
std::shared_ptr< ACE_ENGINE_OP > newOp() const
ACE_BACKEND(std::string aPath, std::string aPassword, int aTimeoutSeconds)
std::unique_ptr< DB_WORKER_THREAD > m_worker
bool readVerified(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)
The verified read itself, inside a load cycle.
static PROVIDER_STATE ProviderState()
Tells whether the ACE OLE DB provider is installed and loads.
bool IsConnected() const override
bool ListTables(std::vector< std::string > &aTables) override
Lists the tables and views, sorted by name.
DB_STOP_CHECK m_cycleStop
Set by the outermost load cycle, which a verified read checks before every open and pass.
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) override
A verified read.
std::optional< PASS_DIGEST > readPass(uint64_t aSession, const std::string &aSql, const std::string &aUnorderedSql, size_t aMaxRows, std::vector< std::string > &aLabels, const DB_ROW_SINK *aSink, std::optional< ACE_ENGINE_OP::CLOCK::time_point > aDeadline=std::nullopt)
Runs one pass of aSql on aSession, recording a failure as the backend's.
std::vector< CYCLE_SESSION > m_cycleSessions
void BeginLoadCycle(const DB_STOP_CHECK &aStopped) override
Brackets a load cycle, in which the caller reads each table once.
bool pauseUnlessStopped(std::chrono::milliseconds aWait)
Sleeps for aWait; false if the cycle's stop check came true first.
static constexpr size_t MAX_CYCLE_SESSIONS
The most sessions a load cycle holds at once.
void failStopped(const std::string &aTable)
void EndLoadCycle() override
Closes the sessions the cycle opened, on the worker thread.
bool closeOnWorker(std::vector< uint64_t > aIds, std::shared_ptr< ACE_ENGINE_OP > aOp, std::optional< std::chrono::milliseconds > aBound=std::nullopt)
Closes aIds on the worker thread under aOp, recording a close that lost the engine lock; false if the...
void fail(DB_FAILURE aFailure, std::string aError)
std::wstring m_progId
The provider that opened the connection, which the cycle's sessions use too.
std::optional< DB_TABLE_INFO > DescribeTable(const std::string &aTable) override
int m_cycleDepth
How many load cycles are open; the sessions are closed when the last one ends.
std::optional< R > runOnWorker(std::function< R(DB_JOB_CONTEXT &)> aJob, const DB_ROW_SINK *aSink, std::shared_ptr< ACE_ENGINE_OP > aOp=nullptr, std::optional< std::chrono::milliseconds > aProgressBound=std::nullopt)
Runs aJob on the worker, recording why it did not finish as the failure.
bool requireConnection()
Fails with a message and returns false unless a connection is open.
std::string GetLastError() const override
std::optional< uint64_t > freshSession(const std::string &aTable, ACE_ENGINE_OP::CLOCK::time_point aDeadline, const std::function< bool()> &aMayStart)
A session of the cycle that has not read aTable, now marked as having read it, or nullopt if one coul...
std::atomic< bool > m_connected
bool closeSpentSessions(ACE_ENGINE_OP::CLOCK::time_point aDeadline)
Closes the oldest sessions of the cycle, which have all read the current table, so that one more fits...
void Disconnect() override
uint64_t m_session
Names this backend's connection among those the worker thread holds.
DB_FAILURE GetLastFailure() const override
@ BUSY
The check could not start because the engine lock stayed out of reach.
@ PENDING
The check has not finished, so nothing is known yet.
static std::string ProviderMissingMessage()
The message for a source that needs the provider when ProviderState() is MISSING.
bool cycleStopped() const
static std::string ProviderPendingMessage()
The message for a source whose provider check has not finished.
std::shared_ptr< ACE_ENGINE_OP > m_lastOp
The operation the caller last ran, which a failure that drops the connection continues.
void failCall(DB_FAILURE aFailure, std::string aMessage)
Records a failure of a call that ran, and drops the connection if the failure means it cannot be trus...
A read-only source of tables.
What a job running on a DB_WORKER_THREAD uses to hand rows to the caller.
std::function< bool()> DB_STOP_CHECK
True once the caller no longer wants what a read would deliver.
std::function< void(std::vector< DB_VALUE > &&)> DB_ROW_SINK
Receives one row at a time, in the order of the labels the read produced.
DB_FAILURE
Why a connection attempt failed, as far as the backend's report tells.
std::function< void()> DB_RESTART_SINK
Told that the rows delivered so far are void, because the read starts the table again from its first ...
A session opened for one load cycle, and the tables it has read, which it never reads again.
std::set< std::string > tables
What one complete pass over a table returned, as a verified read compares it.
bool operator==(const PASS_DIGEST &aOther) const
std::vector< std::string > labels
std::chrono::steady_clock CLOCK
std::atomic< STATE > state
@ WAITING
A job is blocked on the engine lock.
@ ACQUIRED
The job took the lock.
@ EXPIRED
The deadline passed first; never cleared.
ACE_ENGINE_OP(CLOCK::time_point aDeadline)
bool Busy() const
True if the operation is waiting for the engine lock or gave up on it.
const CLOCK::time_point deadline