// Connection.h: interface for the CConnection class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_CONNECTION_H__035ED1A8_ECAE_4A7F_8CFE_44F22F9A2FDA__INCLUDED_) #define AFX_CONNECTION_H__035ED1A8_ECAE_4A7F_8CFE_44F22F9A2FDA__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 namespace scdriver { /// /// Supported ScimoreDB transaction isolation levels /// enum TRAN_ISOLATION_LEVEL { READ_COMMITTED = 0, /// Read only committed data. This level is the default. READ_REPEATABLE = 1, /// Read repeatable isolation level. The data view will not change, and the current transaction will always see the database in the state after the transaction has been started. SERIALIZE = 3 /// Serialize all transactions and execute on at the time }; /// /// Query language type /// enum CONNECTION_LANG { LANG_DQL = 0, /// Interpet the command text as DQL statements LANG_SQL = 1, /// Interpet the command text as SQL statements }; /// /// Connection callback events /// enum CONNECTION_EVENT { CONN_BROKEN = 1, /// Fire when connections has been terminated. CONN_ALTER = 2, /// Fire when DB cluster configuration has been altered. QUERY_DONE = 3, /// Fire when the query has been completed, usually used when query is executed asychronuosously. READ_SCHEMA = 4, /// Reserved for internal use. Do not set this event it will lead to crash! READ_PARAMETERS = 5 /// Read output parameter value. }; // forward declaration class CConnection; class CRecordset; class CFieldStream; class CCommand; class c_connector; /// /// Callback routine that will be fired when specified connection state event occurs. /// /// Connection instance pointer that fires the event /// User key, specified in SetConnectionCallback function typedef void (__stdcall CONNECTION_STATE_CALLBACK) (CConnection *conn, void *context); /// /// Manage connection, transaction, /// query execution and state callbacks /// #ifdef DELPHI class CConnection : public CAbstractConnection #else class __declspec( dllexport ) CConnection #endif { public: CConnection(); virtual ~CConnection(); /// /// Connects with TCP to the database server. The client uses internal connection pool. It will re-use /// released connection or establish new one. Connection becomes release after Close() call & can be reused. /// /// Host name or IP address /// The port, the databse is listening /// The parameter is used when connecting to distributed database. /// All Servers in the cluster has an unique instance id that can be acquired from system metadata: /// SELECT * from system.sysinstances. /// Default value -1, i.e. client will connect to the random server. /// If method fails, the node_exception exception, containing the error message, will be thrown void Connect(const char *host,const int port, const long inst_id = -1); /// /// Connects, using named pipes protocol (shared memory), to the embedded database engine. /// The embedded database can be loaded into client's process as dll or started in a separate /// process (rundll32). /// /// Host name or IP address /// True if database is loaded in host process /// If method fails, the ServerException, containing the error message, will be thrown void Connect(const char *embdb_id,const bool &in_process); /// /// If connection executes asynchronuos query, you can cancel it /// by calling Cancel method. /// /// If method fails, the node_exception exception, containing the error message, will be thrown void Cancel(); /// /// Close connection and release it to the poll of /// the available connections. If you need to query /// the database, call Connect() again. /// /// If method fails, the node_exception exception, containing the error message, will be thrown void Close(); /// /// The function call will block until database /// responded executed query status. If database returns an error /// the [node_exception] exception with an error message /// will be thrown. Otherwise, if defined, query events/callbacks will be /// fired. The callback event is set with SetConnectionStateCallback /// function. /// The GetCompletionStatus(), must always be called right after /// CConnection: Execute, CCommand::Execute/Open or CRecordset::Open, /// unless, the query is asynchronuos - in this case, call the function /// after completion event has been fired. /// /// If server sends back to the client the error, node_exception exception, containing the error message, will be thrown void GetCompletionStatus(); /// /// Return number of deleted, inserted or updated rows in the current transaction scope /// __int64 GetAffectedRows(); /// /// Start new transaction scope and sets AutoCommit to false. Followed data changes will be visible /// only by the current connection, until, Commit() is executed. Executing Rollback() will undo /// all changes that was made after begin current transaction. The behaviour is similiar to BEGIN TRANSACTION /// SQL statememnt. /// /// Set transaction supported isolation level. The default - read committed. /// If server sends back to the client the error, node_exception exception, containing the error message, will be thrown void BeginTransaction(const TRAN_ISOLATION_LEVEL iso_level = READ_COMMITTED); /// /// Abort/Rollback current transaction. The transaction must be started /// using BeginTransaction() function. /// /// If server sends back to the client the error, node_exception exception, containing the error message, will be thrown void AbortTransaction(); /// /// Commit current transaction's changes. The transaction must be started /// using BeginTransaction() function. /// /// If server sends back to the client the error, node_exception exception, containing the error message, will be thrown void CommitTransaction(); /// /// Execute SQL or DQL command. /// The command will set affected rows and receive the new values /// for the output parameter(s). /// /// SQL or DQL statement. By default, database interpret text as SQL, unless, SetLanguage function had set it to DQL. /// Reserved for internal use. /// Reserved for internal use. /// If server sends back to the client the error, node_exception exception with the error message, will be thrown void Execute(const char *cmd, byte *_recv = 0, const int _irecv = 8192); /// /// Return generated DQL statement from SQL. /// /// SQL statement. /// Pointer to the buffer that receives DQL /// Size of the DQL buffer. The DQL can be maximum 8KB /// If server sends back to the client the error, node_exception exception with the error message, will be thrown void ShowDQL(const char *sql,char *dql, int idql); /// /// Set query timeout value in seconds. If query being executed longer than /// timeout seconds, it will be cancelled. The timeout is only used for synchronuos /// queries. Asynchrounuos queries can be executed with ScimoreCommand::ExecuteAsynchronous /// method and cancelled using ScimoreCommand::Cancel. Default value is - 0xffffffff, i.e. the query /// never timeouts. /// void SetTimeout(const long Seconds); /// /// Set which language to execute. ScimoreDB supports SQL and DQL. DQL is text-based execution plan and used in rare cases, /// for example, if SQL optimizer generates incorrect or slow DQL plan. By default, Language is SQL. /// /// CONNECTION_LANG enum value specifying the language void SetLanguage(const CONNECTION_LANG tlang); /// /// Set callback function to be fired for the specified connection state. /// The callback routine must not use any DB functions, e.g. execute, read rows, etc.., /// it should do a quick operation like SetEvent()... /// NOTE: do not call GetCompletionStatus() inside any callback functions. /// /// Set QUERY_DONE event, which will be fired, when /// asynchronuos query completed /// Events callback routine address /// User defined key/value that will be passed to callback routine. void SetConnectionStateCallback(const CONNECTION_EVENT etype, CONNECTION_STATE_CALLBACK *pcallback, void *usercontext = 0); /// /// If you set callback routines, you need to reset them as well. /// Reset it in the inside callback routines or when you done with the query. /// /// Callback events type. void ResetConnectionStateCallback(const CONNECTION_EVENT etype); /************************************** * * function: get_class_size * ************************************** * * Functional description * * return the size of the class **************************************/ static int get_class_size(); friend class CRecordset; friend class CFieldStream; friend class CCommand; friend class CBulkExport; friend class CBulkImport; friend class c_connector; protected: /************************************** * * function: F i r e E v e n t * ************************************** * * Functional description * * call users callback functions **************************************/ void FireEvent(const CONNECTION_EVENT &etype); /************************************** * * function: g e t _ r e t u r n * ************************************** * * Functional description * **************************************/ byte *get_return(); /************************************** * * function: g e t _ d r i v e r * ************************************** * * Functional description * **************************************/ c_connector *get_driver(); private: /************************************** * * function: E x e c u t e S Q L * ************************************** * * Functional description * * execute SQL **************************************/ void ExecuteSQL(const char *sql, const int &isql, byte *recv); /************************************** * * function: E x e c u t e D Q L * ************************************** * * Functional description * * execute DQL **************************************/ void ExecuteDQL(const char *dql, byte *recv); /************************************** * * function: b a t c h _ s q l * ************************************** * * Functional description * * split SQL into max 8kb chunk. * Batching is allowed when SQL statement * ends with ';' * Return: true - if there is more than one batch * isql - size of sql block * sql updated pointer to the next sql batch begining **************************************/ bool batch_sql(const char *cmd, char *sql, int &isql); /************************************** * * function: r e s e t _ t r a n _ s c o p e * ************************************** * * Functional description * * when auto_commit == false and transaction fails * the server will rollback all changes made * by transaction's scope. And the client does not need to call * AbortTransaction anymore.The auto_commit flag will be reset * to TRUE as well **************************************/ void reset_tran_scope(); private: c_connector *m_driver; // connection enpoint instance used to communicate with the DB servers __int64 m_affected_rows;// number of affected rows by current executed command bool m_auto_commit; // auto commit flag: true - each succesfully executed command will commit data, false - modified data will not be committed until implicitly call conn->CommitTransactio() long m_timeout; // in seconds to wait for the qurty to complete CONNECTION_LANG m_language; // 1 - SQL or 0 - DQL command statement byte m_recv[8192]; protected: int m_irecv; private: // registered callback functions for each connection // state change event [CONNECTION_EVENT] CONNECTION_STATE_CALLBACK *m_pconn_broken; CONNECTION_STATE_CALLBACK *m_pconn_alter; CONNECTION_STATE_CALLBACK *m_pquery_done; CONNECTION_STATE_CALLBACK *m_pread_schema; CONNECTION_STATE_CALLBACK *m_pread_params; // user data ptr, which will be passed in callback function void *m_pconn_broken_context; void *m_pconn_alter_context; void *m_pquery_done_context; void *m_pread_schema_context; void *m_pread_params_context; }; } #endif // !defined(AFX_CONNECTION_H__035ED1A8_ECAE_4A7F_8CFE_44F22F9A2FDA__INCLUDED_)