1
0
mirror of https://github.com/VCMP-SqMod/SqMod.git synced 2024-11-12 18:57:16 +01:00
SqMod/source/Library/SQLite/Shared.hpp
2015-11-03 04:22:21 +02:00

416 lines
14 KiB
C++

#ifndef _LIBRARY_SQLITE_SHARED_HPP_
#define _LIBRARY_SQLITE_SHARED_HPP_
// ------------------------------------------------------------------------------------------------
#include "Common.hpp"
#include "Library/LongInt.hpp"
// ------------------------------------------------------------------------------------------------
#include <sqlite3.h>
// ------------------------------------------------------------------------------------------------
#include <queue>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
namespace SQLite {
// ------------------------------------------------------------------------------------------------
class Connection;
class Statement;
class Result;
/* ------------------------------------------------------------------------------------------------
* A managed handle to a shared SQLite connection.
*/
class ConnectionHandle
{
// --------------------------------------------------------------------------------------------
friend class Connection;
protected:
/* --------------------------------------------------------------------------------------------
* Helper class responsible for managing the handle to an SQLite connection resource.
*/
struct Handle
{
friend class ConnectionHandle;
/* ----------------------------------------------------------------------------------------
* The type of container used to queue queries for group execution.
*/
typedef std::queue< String > QueryList;
/* ----------------------------------------------------------------------------------------
* The amount of references to this handle instance.
*/
mutable SQUint32 Ref;
/* ----------------------------------------------------------------------------------------
* The handle to the managed SQLite connection resource.
*/
sqlite3* Ptr;
/* ----------------------------------------------------------------------------------------
* The flags used to create the SQLite connection handle.
*/
SQInt32 Flags;
/* ----------------------------------------------------------------------------------------
* The specified path to be used as the database file.
*/
String Path;
/* ----------------------------------------------------------------------------------------
* The specified virtual file system.
*/
String VFS;
/* ----------------------------------------------------------------------------------------
* The last status code of this connection handle.
*/
SQInt32 Status;
/* ----------------------------------------------------------------------------------------
* A queue of queries to be executed in groups in order to reduce lag.
*/
QueryList Queue;
/* ----------------------------------------------------------------------------------------
* The global tag associated with this resource.
*/
SqTag Tag;
/* ----------------------------------------------------------------------------------------
* The global data associated with this resource.
*/
SqObj Data;
/* ----------------------------------------------------------------------------------------
* Whether the database exists in memory and not disk.
*/
bool Memory;
/* ----------------------------------------------------------------------------------------
* Whether tracing was activated on the database.
*/
bool Trace;
/* ----------------------------------------------------------------------------------------
* Whether profiling was activated on the database.
*/
bool Profile;
private:
/* ----------------------------------------------------------------------------------------
* Handle constructor.
*/
Handle(const String & path, SQInt32 flags, const String & vfs)
: Ref(1), Ptr(NULL), Flags(flags), Path(path), VFS(vfs)
, Status(SQLITE_OK), Queue(), Tag(), Data()
, Memory(path == ":memory:"), Trace(false), Profile(false)
{
/* ... */
}
/* ----------------------------------------------------------------------------------------
* Copy constructor (disabled)
*/
Handle(const Handle &) = delete;
/* ----------------------------------------------------------------------------------------
* Move constructor (disabled)
*/
Handle(Handle &&) = delete;
/* ----------------------------------------------------------------------------------------
* Handle destructor.
*/
~Handle()
{
// If a valid handle exists then attempt to release it
if (Ptr != NULL && (Status = sqlite3_close(Ptr)) != SQLITE_OK)
{
LogErr("Unable to <close database connection> because : %s", sqlite3_errmsg(Ptr));
}
}
/* ----------------------------------------------------------------------------------------
* Copy assignment operator (disabled)
*/
Handle & operator = (const Handle &) = delete;
/* ----------------------------------------------------------------------------------------
* Move assignment operator (disabled)
*/
Handle & operator = (Handle &&) = delete;
};
/* --------------------------------------------------------------------------------------------
* Acquire a strong reference to the resource handle.
*/
void Grab()
{
// If a valid handle exists then grab a reference to it
if (Hnd != nullptr)
{
++(Hnd->Ref);
}
}
/* --------------------------------------------------------------------------------------------
* Release the handle reference and therefore the handle it self if no more references exist.
*/
void Drop()
{
// If a valid handle exists then delete it if this is the last released reference
if (Hnd != nullptr && --(Hnd->Ref) == 0)
{
delete Hnd;
}
// Explicitly make sure the handle is null
Hnd = nullptr;
}
public:
/* --------------------------------------------------------------------------------------------
* The handle instance that manages the SQLite resource.
*/
Handle * Hnd;
/* --------------------------------------------------------------------------------------------
* Default constructor (invalid).
*/
ConnectionHandle();
/* --------------------------------------------------------------------------------------------
* Open a connection to a database using the specified path, flags and vfs.
*/
ConnectionHandle(const SQChar * path, SQInt32 flags, const SQChar * vfs);
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
ConnectionHandle(const ConnectionHandle & o);
/* --------------------------------------------------------------------------------------------
* Move constructor.
*/
ConnectionHandle(ConnectionHandle && o);
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~ConnectionHandle();
/* --------------------------------------------------------------------------------------------
* Copy assignment operator.
*/
ConnectionHandle & operator = (const ConnectionHandle & o);
/* --------------------------------------------------------------------------------------------
* Move assignment operator.
*/
ConnectionHandle & operator = (ConnectionHandle && o);
/* --------------------------------------------------------------------------------------------
* Implicit conversion to boolean.
*/
operator bool () const
{
return (Hnd != nullptr) && (Hnd->Ptr != NULL);
}
/* --------------------------------------------------------------------------------------------
* Negation operator.
*/
operator ! () const
{
return (Hnd == nullptr) || (Hnd->Ptr == NULL);
}
/* --------------------------------------------------------------------------------------------
* Implicit conversion to raw SQLite connection handle.
*/
operator sqlite3 * () const
{
return (Hnd != nullptr) ? Hnd->Ptr : NULL;
}
/* --------------------------------------------------------------------------------------------
* Implicit conversion to integer status code.
*/
operator SQInt32 () const
{
return (Hnd != nullptr) ? Hnd->Status : 0;
}
/* --------------------------------------------------------------------------------------------
* Member of pointer operator.
*/
Handle * operator -> () const
{
return Hnd;
}
/* --------------------------------------------------------------------------------------------
* Indirection operator.
*/
Handle & operator * () const
{
return *Hnd;
}
/* --------------------------------------------------------------------------------------------
* Equality operator.
*/
bool operator == (const ConnectionHandle & o) const
{
return (Hnd == o.Hnd);
}
/* --------------------------------------------------------------------------------------------
* Inequality operator.
*/
bool operator != (const ConnectionHandle & o) const
{
return (Hnd != o.Hnd);
}
/* --------------------------------------------------------------------------------------------
* Reset this handle and release the internal reference.
*/
void Release()
{
Drop();
}
/* --------------------------------------------------------------------------------------------
* Retrieve the number of active references to this handle.
*/
SQUint32 Count() const
{
return (Hnd != nullptr) ? Hnd->Ref : 0;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the error message associated with the value in status.
*/
const SQChar * ErrStr() const
{
return sqlite3_errstr(Hnd->Status);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the error message associated with the connection.
*/
const SQChar * ErrMsg() const
{
return sqlite3_errmsg(Hnd->Ptr);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the error code associated with the connection.
*/
SQInt32 ErrNo() const
{
return sqlite3_errcode(Hnd->Ptr);
}
};
/* ------------------------------------------------------------------------------------------------
* RAII encapsulation of a SQLite Transaction.
*/
class Transaction
{
public:
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
Transaction(const Connection & db);
/* --------------------------------------------------------------------------------------------
* Copy constructor (disabled).
*/
Transaction(const Transaction & o) = delete;
/* --------------------------------------------------------------------------------------------
* Move constructor (disabled).
*/
Transaction(Transaction && o) = delete;
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~Transaction();
/* --------------------------------------------------------------------------------------------
* Copy assignment operator (disabled).
*/
Transaction & operator = (const Transaction & o) = delete;
/* --------------------------------------------------------------------------------------------
* Move assignment operator (disabled).
*/
Transaction & operator = (Transaction && o) = delete;
/* --------------------------------------------------------------------------------------------
* Commit the transaction.
*/
void Commit();
/* --------------------------------------------------------------------------------------------
* See whether the transaction was committed.
*/
bool Commited() const
{
return m_Commited;
}
protected:
// --------------------------------------------------------------------------------------------
private:
/* --------------------------------------------------------------------------------------------
* The SQLite connection associated with this transaction.
*/
ConnectionHandle m_Connection;
/* --------------------------------------------------------------------------------------------
* Whether the changes were committed.
*/
bool m_Commited;
};
/* ------------------------------------------------------------------------------------------------
* Places a "soft" limit on the amount of heap memory that may be allocated by SQLite.
*/
void SetSoftHeapLimit(SQInt32 limit);
/* ------------------------------------------------------------------------------------------------
* Attempts to free N bytes of heap memory by deallocating non-essential memory allocations
* held by the database library.
*/
SQInt32 ReleaseMemory(SQInt32 bytes);
/* ------------------------------------------------------------------------------------------------
* Returns the number of bytes of memory currently outstanding (malloced but not freed).
*/
SLongInt GetMemoryUsage();
/* ------------------------------------------------------------------------------------------------
* Returns the maximum value of used bytes since the high-water mark was last reset.
*/
SLongInt GetMemoryHighwaterMark(bool reset);
} // Namespace:: SQLite
} // Namespace:: SqMod
#endif // _LIBRARY_SQLITE_SHARED_HPP_