|
|
| version 1.1, 2001/10/22 16:44:42 | version 1.20, 2002/02/08 07:27:43 |
|---|---|
| Line 1 | Line 1 |
| /** @file | /** @file |
| Parser: sql db decl. | Parser: sql driver connection decl. |
| global sql driver connection, must be thread-safe | |
| Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com) | Copyright (c) 2001, 2002 ArtLebedev Group (http://www.artlebedev.com) |
| Author: Alexander Petrosyan <paf@design.ru> (http://design.ru/paf) | Author: Alexander Petrosyan <paf@design.ru> (http://paf.design.ru) |
| $Id$ | $Id$ |
| */ | */ |
| Line 10 | Line 11 |
| #ifndef PA_DB_CONNECTION_H | #ifndef PA_DB_CONNECTION_H |
| #define PA_DB_CONNECTION_H | #define PA_DB_CONNECTION_H |
| #include "pa_config_includes.h" | |
| #include "pa_pool.h" | #include "pa_pool.h" |
| #include "pa_db_manager.h" | #include "pa_hash.h" |
| #include "pa_globals.h" | #include "pa_db_table.h" |
| #include "pa_value.h" | |
| #ifdef HAVE_DB_H | |
| # include <db.h> | |
| #endif | |
| // defines | // defines |
| #define PA_DB_ACCESS_METHOD DB_BTREE | // forwards |
| // class | class DB_Table; |
| class DB_Connection_ptr; | |
| /// DB connection. handy wrapper around low level DB_Driver | /// sql driver connection |
| class DB_Connection : public Pooled { | class DB_Connection : public Pooled { |
| friend class DB_Table; | |
| friend class DB_Connection_ptr; | |
| public: | public: |
| DB_Connection(Pool& pool, const String& afile_spec, DB_ENV& adbenv); | DB_Connection(Pool& apool, const String& db_home); |
| ~DB_Connection(); | |
| //const String& url() { return ffile_spec; } | |
| void set_services(Pool *aservices_pool) { | |
| time_used=time(0); // they started to use at this time | |
| fservices_pool=aservices_pool; | |
| } | |
| bool expired(time_t older_dies) { | bool expired(time_t older_dies) { |
| return time_used<older_dies; | return !used && time_used<older_dies; |
| } | } |
| const String& db_home() { return fdb_home; } | |
| time_t get_time_used() { return time_used; } | |
| int get_users_count() { return used; } | |
| void close() { | /** |
| DB_manager->close_connection(ffile_spec, *this); | connect to specified file_name |
| } | */ |
| DB_Table_ptr get_table_ptr(const String& file_name, const String *source); | |
| bool connected() { return db!=0; } | private: // connection usage methods |
| void connect(); | |
| /// @todo this one of reasons of not having ^try for now | void use() { |
| void DB_Connection::disconnect() { | time_used=time(0); // they started to use at this time |
| check("close", &ffile_spec, db->close(db, 0/*flags*/)); db=0; | used++; |
| } | |
| void commit() { | |
| if(tid) { | |
| check("txn_commit", &ffile_spec, txn_commit(tid)); tid=0; | |
| } | |
| } | |
| void rollback() { | |
| if(tid) { | |
| check("txn_abort", &ffile_spec, txn_abort(tid)); tid=0; | |
| } | |
| } | } |
| void unuse() { | |
| void txn_begin() { | used--; |
| check("txn_begin", &ffile_spec, ::txn_begin(fdbenv.tx_info, 0/*parent*/, &tid)); | |
| } | } |
| bool ping() { return !needs_recovery; } | |
| void put(const String& key, const String& data); | private: // connection usage data |
| String *get(const String& key); | |
| int used; | |
| private: // table cache | |
| DB_Table *get_table_from_cache(const String& file_name); | |
| void put_table_to_cache(const String& file_name, DB_Table& table); | |
| void maybe_expire_table_cache(); | |
| private: | |
| time_t prev_expiration_pass_time; | |
| private: // for DB_Table | |
| /// caches table | |
| void close_table(const String& file_name, DB_Table& table); | |
| private: | private: |
| DB_ENV& fdbenv; | |
| const String& ffile_spec; | |
| Pool *fservices_pool; | |
| DB *db; | |
| bool needs_recovery; | |
| DB_TXN *tid; | |
| time_t time_used; | time_t time_used; |
| const String& fdb_home; | |
| DB_ENV dbenv; | |
| Hash table_cache; | |
| private: | private: |
| void check(const char *operation, const String *source, int error); | void check(const char *operation, const String *source, int error); |
| void *malloc(size_t size) { return fservices_pool->malloc(size); } | |
| void *calloc(size_t size) { return fservices_pool->calloc(size); } | public: |
| Value& get_status(Pool& pool, const String *source); | |
| }; | |
| /// Auto-object used to track DB_Connection usage | |
| class DB_Connection_ptr { | |
| DB_Connection *fconnection; | |
| public: | |
| explicit DB_Connection_ptr(DB_Connection *aconnection) : fconnection(aconnection) { | |
| fconnection->use(); | |
| } | |
| ~DB_Connection_ptr() { | |
| fconnection->unuse(); | |
| } | |
| DB_Connection* operator->() { | |
| return fconnection; | |
| } | |
| // copying | |
| DB_Connection_ptr(const DB_Connection_ptr& src) : fconnection(src.fconnection) { | |
| fconnection->use(); | |
| } | |
| DB_Connection_ptr& operator =(const DB_Connection_ptr& src) { | |
| // may do without this=src check | |
| fconnection->unuse(); | |
| fconnection=src.fconnection; | |
| fconnection->use(); | |
| return *this; | |
| } | |
| }; | }; |
| #endif | #endif |