Annotation of parser3/src/main/pa_db_connection.C, revision 1.4

1.1       parser      1: /** @file
                      2:        Parser: Charset connection implementation.
                      3: 
                      4:        Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com)
                      5:        Author: Alexander Petrosyan <paf@design.ru> (http://design.ru/paf)
                      6: 
1.4     ! parser      7:        $Id: pa_db_connection.C,v 1.3 2001/10/23 14:43:44 parser Exp $
1.1       parser      8: */
                      9: 
                     10: #include "pa_config_includes.h"
                     11: #ifdef HAVE_LIBDB
                     12: 
                     13: #include "pa_db_connection.h"
                     14: #include "pa_exception.h"
                     15: 
1.3       parser     16: // DB_Connection
                     17: 
1.1       parser     18: void DB_Connection::check(const char *operation, const String *source, int error) {
                     19:        switch(error) {
                     20:        case 0: 
                     21:                // no error
                     22:                break; 
                     23:        
                     24:        case DB_KEYEXIST:
                     25:                // DB_KEYEXIST is a "normal" return, so should not be
                     26:                // thrown as an error
                     27:                break; 
                     28: 
                     29:        case DB_RUNRECOVERY:
                     30:                // mark as unsafe, so not to cache it
                     31:                needs_recovery=true;
                     32:                throw Exception(0, 0, 
1.3       parser     33:                        source,
                     34:                        "action failed, RUN RECOVERY UTILITY. db %s error, real filename '%s'", 
                     35:                        operation, file_spec_cstr);
1.1       parser     36:                
                     37:        default:
                     38:                throw Exception(0, 0, 
1.3       parser     39:                        source, 
                     40:                        "action failed. db %s error: %s (%d), real filename '%s'", 
                     41:                        operation, strerror(error), error, file_spec_cstr);
1.1       parser     42:        }
                     43: }
                     44: 
1.4     ! parser     45: void DB_Connection::key_string_to_dbt(const String& key_string, DBT& key_result) {
        !            46:        memset(&key_result, 0, sizeof(key_result));
        !            47:        key_result.data=key_string.cstr(String::UL_AS_IS);
        !            48:        key_result.size=key_string.size();
        !            49: }
        !            50: 
        !            51: void DB_Connection::key_dbt_to_string(const DBT& key_dbt, String& key_result) {
        !            52:        if(key_dbt.size) {
        !            53:                char *request_data=(char *)malloc(key_dbt.size);
        !            54:                memcpy(request_data, key_dbt.data, key_dbt.size);
        !            55:                key_result.APPEND_TAINTED(request_data, key_dbt.size, file_spec_cstr, 0/*line*/);
        !            56:        }
        !            57: }
        !            58: 
        !            59: void DB_Connection::data_string_to_dbt(const String& data_string, DBT& data_result) {
        !            60:        memset(&data_result, 0, sizeof(data_result));
        !            61:        data_string.serialize(sizeof(time_t), data_result.data, data_result.size);
        !            62: }
        !            63: 
        !            64: void DB_Connection::data_dbt_to_string(const DBT& data_dbt, String& data_result) {
        !            65:        data_result.deserialize(sizeof(time_t), data_dbt.data, data_dbt.size, file_spec_cstr);
        !            66: }
        !            67: 
1.1       parser     68: DB_Connection::DB_Connection(Pool& pool, const String& afile_spec, DB_ENV& adbenv) : Pooled(pool),
                     69:        fdbenv(adbenv),
1.3       parser     70:        ffile_spec(afile_spec), file_spec_cstr(afile_spec.cstr(String::UL_FILE_SPEC)),
1.2       parser     71:        fservices_pool(0), db(0), ftid(0), needs_recovery(false), 
1.1       parser     72:        time_used(0) {
                     73: }
                     74: 
                     75: void DB_Connection::connect() { 
                     76:        // open
                     77:        DB_INFO dbinfo;
                     78:        memset(&dbinfo, 0, sizeof(dbinfo));
                     79:        check("open/create", &ffile_spec, db_open(
1.3       parser     80:                file_spec_cstr, 
1.1       parser     81:                PA_DB_ACCESS_METHOD, 
1.2       parser     82:                DB_CREATE /* used in single thread, no need for |DB_THREAD*/,
1.1       parser     83:                0666, 
                     84:                &fdbenv, &dbinfo, &db));
                     85: }
1.2       parser     86: /// @todo this one of reasons of not having ^try for now
                     87: void DB_Connection::disconnect() { 
                     88:        check("close", &ffile_spec, db->close(db, 0/*flags*/));  db=0; 
                     89: }
1.1       parser     90: 
                     91: ///    @test string pieces [get/put preserve lang]
                     92: void DB_Connection::put(const String& key, const String& data) {
1.4     ! parser     93:        DBT dbt_key;  key_string_to_dbt(key, dbt_key);
        !            94:        DBT dbt_data;  data_string_to_dbt(data, dbt_data);
1.2       parser     95:        check("put", &key, db->put(db, ftid, &dbt_key, &dbt_data, 0/*flags*/));
1.1       parser     96: }
                     97: 
                     98: String *DB_Connection::get(const String& key) {
1.4     ! parser     99:        DBT dbt_key;  key_string_to_dbt(key, dbt_key);
1.1       parser    100:        // data
                    101:        DBT dbt_data={0}; // must be zeroed
1.2       parser    102:        int error=db->get(db, ftid, &dbt_key, &dbt_data, 0/*flags*/);
                    103:        if(error==DB_NOTFOUND)
                    104:                return 0;
                    105:        else {
                    106:                check("get", &key, error);
                    107: 
1.3       parser    108:                String *result=new(*fservices_pool) String(*fservices_pool);
1.4     ! parser    109:                data_dbt_to_string(dbt_data, *result);
1.3       parser    110:                return result;
1.2       parser    111:        }               
                    112: }
                    113: 
                    114: void DB_Connection::_delete(const String& key) {
1.4     ! parser    115:        DBT dbt_key;  key_string_to_dbt(key, dbt_key);
1.1       parser    116: 
1.2       parser    117:        int error=db->del(db, ftid, &dbt_key, 0/*flags*/);
                    118:        if(error!=DB_NOTFOUND)
                    119:                check("del", &key, error);
1.3       parser    120: }
                    121: 
                    122: DB_Cursor DB_Connection::cursor(const String *source) {
                    123:        return DB_Cursor(*this, source);
                    124: }
                    125: 
                    126: // DB_Cursor
                    127: 
                    128: DB_Cursor::DB_Cursor(
                    129:                                         DB_Connection& aconnection, 
                    130:                                         const String *asource) : fsource(asource), fconnection(aconnection), cursor(0) {
                    131:        check("cursor", fsource, fconnection.db->cursor(fconnection.db,
                    132:                fconnection.ftid, &cursor, 0/*flags*/));
                    133: }
                    134: 
                    135: DB_Cursor::~DB_Cursor() {
                    136:        if(cursor) {
                    137:                check("c_close", fsource, cursor->c_close(cursor));  cursor=0;
                    138:        }
                    139: }
                    140: 
                    141: bool DB_Cursor::get(String& key, String& data, u_int32_t flags) {
                    142:        DBT dbt_key={0}; // must be zeroed
                    143:        DBT dbt_data={0}; // must be zeroed
                    144:        
                    145:        int error=cursor->c_get(cursor, &dbt_key, &dbt_data, flags);
                    146:        if(error==DB_NOTFOUND)
                    147:                return false;
                    148: 
                    149:        check("c_get", fsource, error);
                    150: 
1.4     ! parser    151:        key_dbt_to_string(dbt_key, key);
        !           152:        data_dbt_to_string(dbt_data, data);
1.3       parser    153:        return true;
1.1       parser    154: }
                    155: 
                    156: #endif

E-mail: