Diff for /parser3/src/main/Attic/pa_db_connection.C between versions 1.12 and 1.19

version 1.12, 2001/10/26 07:07:01 version 1.19, 2001/10/27 13:00:09
Line 8 Line 8
 */  */
   
 #include "pa_config_includes.h"  #include "pa_config_includes.h"
 #ifdef HAVE_LIBDB  #ifdef DB2
   
 #include "pa_db_connection.h"  #include "pa_db_connection.h"
 #include "pa_db_table.h"  #include "pa_db_table.h"
Line 17 Line 17
 #include "pa_stack.h"  #include "pa_stack.h"
 #include "pa_common.h"  #include "pa_common.h"
   
   // defines
   
   #define DB_ERROR_PREFIX "db_err: "
   #define DB_EXCEPTION_NO_LOG_MESSAGE1 DB_ERROR_PREFIX"Ignoring log file"
   #define DB_EXCEPTION_NO_LOG_MESSAGE2 DB_ERROR_PREFIX"log_get: unable to find checkpoint record"
   
 // consts  // consts
   
   /// @test increase
   const int DB_CHECKPOINT_MINUTES=1; 
   
 const int EXPIRE_UNUSED_TABLE_SECONDS=60;  const int EXPIRE_UNUSED_TABLE_SECONDS=60;
 const int CHECK_EXPIRED_TABLES_SECONDS=EXPIRE_UNUSED_TABLE_SECONDS*2;  const int CHECK_EXPIRED_TABLES_SECONDS=EXPIRE_UNUSED_TABLE_SECONDS*2;
   
 const char *DB_WARNING1="Finding last valid log LSN";  
   
 // callbacks  // callbacks
   
 static void db_paniccall(DB_ENV *dbenv, int error) {  static void db_paniccall(DB_ENV *dbenv, int error) {
Line 34  static void db_paniccall(DB_ENV *dbenv, Line 41  static void db_paniccall(DB_ENV *dbenv,
 }  }
   
 static void db_errcall(const char *, char *buffer) {  static void db_errcall(const char *, char *buffer) {
         // were it warning?  
         if(strncmp(buffer, DB_WARNING1, strlen(DB_WARNING1))==0)  
                 return;  
   
         throw Exception(0, 0,           throw Exception(0, 0, 
                 0,                   0, 
                 "db_err: %s",                   DB_ERROR_PREFIX "%s", 
                 buffer);                  buffer);
 }  }
   
 static void expire_table(Array::Item *value, void *info) {  static void expire_table(const Hash::Key& key, Hash::Val *& value, void *info) {
         DB_Table& table=*static_cast<DB_Table *>(value);          DB_Connection& table=*static_cast<DB_Connection *>(value);
         time_t older_dies=reinterpret_cast<time_t>(info);          time_t older_dies=reinterpret_cast<time_t>(info);
   
         if(table.connected() && table.expired(older_dies))          if(table.expired(older_dies)) {
                 table.disconnect();                  table.~DB_Connection();  value=0;
 }          }
 static void expire_tables(const Hash::Key& key, Hash::Val *value, void *info) {  
         Stack& stack=*static_cast<Stack *>(value);  
         for(int i=0; i<=stack.top_index(); i++)  
                 expire_table(stack.get(i), info);  
 }  }
   
 // DB_Connection  // DB_Connection
   
 DB_Connection::DB_Connection(Pool& pool, const String& adb_home) : Pooled(pool),  DB_Connection::DB_Connection(Pool& apool, const String& adb_home) : Pooled(apool),
         time_used(0), fservices_pool(0)          time_used(0),
         fdb_home(adb_home), fconnected(false), errors(0),          fdb_home(adb_home), 
         table_cache(pool),          table_cache(apool),
         prev_expiration_pass_time(0) {          prev_expiration_pass_time(0) {
 }  
   
 void DB_Connection::connect() {  
         //_asm  int 3;          //_asm  int 3;
         memset(&dbenv, 0, sizeof(dbenv));  
         dbenv.db_paniccall=db_paniccall;  
         dbenv.db_errcall=db_errcall;  
   
         char DB_DATA_DIR__VALUE[MAX_STRING];          char DB_DATA_DIR__VALUE[MAX_STRING];
         char DB_LOG_DIR__VALUE[MAX_STRING];          char DB_LOG_DIR__VALUE[MAX_STRING];
         char DB_TMP_DIR__VALUE[MAX_STRING];          char DB_TMP_DIR__VALUE[MAX_STRING];
Line 90  void DB_Connection::connect() { Line 82  void DB_Connection::connect() {
         };          };
   
         u_int32_t flags=          u_int32_t flags=
                 DB_CREATE                   DB_THREAD
                   | DB_CREATE 
                 | DB_INIT_MPOOL | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_TXN;                  | DB_INIT_MPOOL | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_TXN;
   
 /*      try {          // trying to open with SOFT RECOVER option set
                 // 1: trying to open with SOFT RECOVER option set          memset(&dbenv, 0, sizeof(dbenv));
                 check("db_appinit soft recover", &fdb_home, db_appinit(          
                         db_home_cstr,          // error handlers
                         db_config,           dbenv.db_paniccall=db_paniccall;
                         &dbenv,           dbenv.db_errcall=db_errcall;
                         flags | DB_RECOVER  
                 ));  
         } catch(...) {  
                 try {*/  
                         // 2: trying to open WITHOUT SOFT RECOVER option set  
                         check("db_appinit no recover", &fdb_home, db_appinit(  
                                 db_home_cstr,  
                                 db_config,   
                                 &dbenv,   
                                 flags  
                         ));  
 /*              } catch(...) {  
                         // 3: trying to open with FATAL RECOVER option set  
                         check("db_appinit fatal recover", &fdb_home, db_appinit(  
                                 db_home_cstr,  
                                 db_config,   
                                 &dbenv,   
                                 flags | DB_RECOVER_FATAL  
                         ));  
                 }  
         }*/  
   
         fconnected=true;          // init
           check("db_appinit", &fdb_home, db_appinit(
                   db_home_cstr,
                   db_config, 
                   &dbenv, 
                   flags
                   ));
 }  }
   
 void DB_Connection::disconnect() {  DB_Connection::~DB_Connection() {
         // close tables          // close tables
         table_cache.for_each(expire_tables,           table_cache.for_each(expire_table, 
                 reinterpret_cast<void *>(0/* =in the past = expire[close] all*/));                  reinterpret_cast<void *>(0/* =in the past = expire[close] all*/));
                   
         // destroy connection data          // destroy connection data
         check("db_appexit", &fdb_home, db_appexit(&dbenv));  fconnected=false;          check("db_appexit", &fdb_home, db_appexit(&dbenv));
 }  }
   
   
Line 141  void DB_Connection::check(const char *op Line 119  void DB_Connection::check(const char *op
                 break;                   break; 
                   
         default:          default:
                 errors++;  
                 throw Exception(0, 0,                   throw Exception(0, 0, 
                         source,                           source, 
                         "db %s error: %s (%d)",                           "db %s error: %s (%d)", 
Line 149  void DB_Connection::check(const char *op Line 126  void DB_Connection::check(const char *op
         }          }
 }  }
   
 DB_Table& DB_Connection::get_table(const String& request_file_name,  DB_Table_ptr DB_Connection::get_table_ptr(const String& request_file_name, const String *source) {
                                                                                                    const String& request_origin) {          // checkpoint
         Pool& pool=request_origin.pool(); // request pool                                                                                                    check("checkpoint", source, 
                   txn_checkpoint(dbenv.tx_info, 0/*kbyte*/, DB_CHECKPOINT_MINUTES/*min*/));
   
         // first trying to get cached table          // first trying to get cached table
         DB_Table *result=get_table_from_cache(request_file_name);          DB_Table *result=get_table_from_cache(request_file_name);
         if(result && !result->ping()) { // we have some cached table, is it pingable?          if(!result) { // no cached table
                 result->disconnect(); // kill unpingabe=dead table  
                 result=0;  
         }  
   
         char *request_file_name_cstr;  
         if(result)  
                 request_file_name_cstr=0; // calm, compiler  
         else { // no cached table  
                 // make global_file_name C-string on global pool                  // make global_file_name C-string on global pool
                 request_file_name_cstr=request_file_name.cstr(String::UL_AS_IS);                  const char *request_file_name_cstr=request_file_name.cstr(String::UL_AS_IS);
                 char *global_file_name_cstr=(char *)malloc(strlen(request_file_name_cstr)+1);                  char *global_file_name_cstr=(char *)malloc(strlen(request_file_name_cstr)+1);
                 strcpy(global_file_name_cstr, request_file_name_cstr);                  strcpy(global_file_name_cstr, request_file_name_cstr);
                 // make global_file_name string on global pool                  // make global_file_name string on global pool
Line 175  DB_Table& DB_Connection::get_table(const Line 145  DB_Table& DB_Connection::get_table(const
                 // associate with services[request]                  // associate with services[request]
                 // NOTE: never freed up!                  // NOTE: never freed up!
                 result=new(this->pool()) DB_Table(this->pool(), global_file_name, *this);                  result=new(this->pool()) DB_Table(this->pool(), global_file_name, *this);
                   // cache it
                   put_table_to_cache(global_file_name, *result);
         }          }
   
         // associate with services[request]  (deassociates at close)          // return auto-it
         result->set_services(&pool);           return DB_Table_ptr(result);
         // if not connected yet, do that now, when result has services  
         if(!result->connected())  
                 result->connect();  
         // return it  
         return *result;  
 }  
 void DB_Connection::clear_dbfile(const String& file_name) {  
         // open&clear  
         DB *db;  
         DB_INFO dbinfo;  
         memset(&dbinfo, 0, sizeof(dbinfo));  
         check("open(clear)", &file_name, db_open(  
                 file_name.cstr(String::UL_FILE_SPEC),   
                 PA_DB_ACCESS_METHOD,   
                 DB_CREATE | DB_TRUNCATE/* used in single thread, no need for |DB_THREAD*/,  
                 0666,   
                 &dbenv, &dbinfo, &db));  
   
         check("close", &file_name, db->close(db, 0/*flags*/));  db=0;   
 }  
   
 void DB_Connection::close_table(const String& file_name,   
                                                                                   DB_Table& table) {  
         // deassociate from services[request]  
         table.set_services(0);  
         put_table_to_cache(file_name, table);  
 }  }
   
   
 // table cache  // table cache
 /// @todo get rid of memory spending Stack [zeros deep inside got accumulated]  /// @todo get rid of memory spending Stack [zeros deep inside got accumulated]
 DB_Table *DB_Connection::get_table_from_cache(const String& file_name) {   DB_Table *DB_Connection::get_table_from_cache(const String& file_name) { 
Line 215  DB_Table *DB_Connection::get_table_from_ Line 160  DB_Table *DB_Connection::get_table_from_
   
         maybe_expire_table_cache();          maybe_expire_table_cache();
   
         if(Stack *tables=static_cast<Stack *>(table_cache.get(file_name)))          return static_cast<DB_Table *>(table_cache.get(file_name));
                 while(tables->top_index()>=0) { // there are cached tables to that 'file_name'  
                         DB_Table *result=static_cast<DB_Table *>(tables->pop());  
                         if(result->connected()) // not expired?  
                                 return result;  
                 }  
   
         return 0;  
 }  }
   
 void DB_Connection::put_table_to_cache(const String& file_name,   void DB_Connection::put_table_to_cache(const String& file_name, DB_Table& table) { 
                                                                                                  DB_Table& table) {   
         SYNCHRONIZED;          SYNCHRONIZED;
   
         Stack *tables=static_cast<Stack *>(table_cache.get(file_name));          table_cache.put(file_name, &table);
         if(!tables) { // there are no cached tables to that 'file_name' yet?  
                 tables=NEW Stack(pool()); // NOTE: never freed up!  
                 table_cache.put(file_name, tables);  
         }         
         tables->push(&table);  
 }  }
   
 void DB_Connection::maybe_expire_table_cache() {  void DB_Connection::maybe_expire_table_cache() {
         time_t now=time(0);          time_t now=time(0);
   
         if(prev_expiration_pass_time<now-CHECK_EXPIRED_TABLES_SECONDS) {          if(prev_expiration_pass_time<now-CHECK_EXPIRED_TABLES_SECONDS) {
                 table_cache.for_each(expire_tables,                   table_cache.for_each(expire_table, 
                         reinterpret_cast<void *>(now-EXPIRE_UNUSED_TABLE_SECONDS));                          reinterpret_cast<void *>(now-EXPIRE_UNUSED_TABLE_SECONDS));
   
                 prev_expiration_pass_time=now;                  prev_expiration_pass_time=now;

Removed from v.1.12  
changed lines
  Added in v.1.19


E-mail: