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

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.3     ! parser      7:        $Id: pa_db_connection.C,v 1.2 2001/10/23 12:41:05 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: 
                     45: DB_Connection::DB_Connection(Pool& pool, const String& afile_spec, DB_ENV& adbenv) : Pooled(pool),
                     46:        fdbenv(adbenv),
1.3     ! parser     47:        ffile_spec(afile_spec), file_spec_cstr(afile_spec.cstr(String::UL_FILE_SPEC)),
1.2       parser     48:        fservices_pool(0), db(0), ftid(0), needs_recovery(false), 
1.1       parser     49:        time_used(0) {
                     50: }
                     51: 
                     52: void DB_Connection::connect() { 
                     53:        // open
                     54:        DB_INFO dbinfo;
                     55:        memset(&dbinfo, 0, sizeof(dbinfo));
                     56:        check("open/create", &ffile_spec, db_open(
1.3     ! parser     57:                file_spec_cstr, 
1.1       parser     58:                PA_DB_ACCESS_METHOD, 
1.2       parser     59:                DB_CREATE /* used in single thread, no need for |DB_THREAD*/,
1.1       parser     60:                0666, 
                     61:                &fdbenv, &dbinfo, &db));
                     62: }
1.2       parser     63: /// @todo this one of reasons of not having ^try for now
                     64: void DB_Connection::disconnect() { 
                     65:        check("close", &ffile_spec, db->close(db, 0/*flags*/));  db=0; 
                     66: }
1.1       parser     67: 
                     68: ///    @test string pieces [get/put preserve lang]
                     69: void DB_Connection::put(const String& key, const String& data) {
                     70:        // key
                     71:        const char *cstr_key=key.cstr(String::UL_AS_IS);
                     72:        DBT dbt_key={
                     73:                (void *)cstr_key,
                     74:                key.size()
                     75:        };
                     76: 
                     77:        // data
                     78:        const char *cstr_data=data.cstr(String::UL_AS_IS);
                     79:        DBT dbt_data={
                     80:                (void *)cstr_data,
                     81:                data.size()
                     82:        };
1.2       parser     83:        check("put", &key, db->put(db, ftid, &dbt_key, &dbt_data, 0/*flags*/));
1.1       parser     84: }
                     85: 
                     86: String *DB_Connection::get(const String& key) {
                     87:        // key
                     88:        const char *cstr_key=key.cstr(String::UL_AS_IS);
                     89:        DBT dbt_key={
                     90:                (void *)cstr_key,
                     91:                key.size()
                     92:        };
                     93: 
                     94:        // data
                     95:        DBT dbt_data={0}; // must be zeroed
1.2       parser     96:        int error=db->get(db, ftid, &dbt_key, &dbt_data, 0/*flags*/);
                     97:        if(error==DB_NOTFOUND)
                     98:                return 0;
                     99:        else {
                    100:                check("get", &key, error);
                    101: 
1.3     ! parser    102:                String *result=new(*fservices_pool) String(*fservices_pool);
        !           103:                dbt_to_string(dbt_data, *result);
        !           104:                return result;
1.2       parser    105:        }               
                    106: }
                    107: 
                    108: void DB_Connection::_delete(const String& key) {
                    109:        // key
                    110:        const char *cstr_key=key.cstr(String::UL_AS_IS);
                    111:        DBT dbt_key={
                    112:                (void *)cstr_key,
                    113:                key.size()
                    114:        };
1.1       parser    115: 
1.2       parser    116:        int error=db->del(db, ftid, &dbt_key, 0/*flags*/);
                    117:        if(error!=DB_NOTFOUND)
                    118:                check("del", &key, error);
1.3     ! parser    119: }
        !           120: 
        !           121: DB_Cursor DB_Connection::cursor(const String *source) {
        !           122:        return DB_Cursor(*this, source);
        !           123: }
        !           124: 
        !           125: void DB_Connection::dbt_to_string(DBT& dbt, String& result) {
        !           126:        if(dbt.size) {
        !           127:                char *request_data=(char *)malloc(dbt.size);
        !           128:                memcpy(request_data, dbt.data, dbt.size);
        !           129:                result.APPEND_TAINTED(request_data, dbt.size, file_spec_cstr, 0/*line*/);
        !           130:        }
        !           131: }
        !           132: 
        !           133: // DB_Cursor
        !           134: 
        !           135: DB_Cursor::DB_Cursor(
        !           136:                                         DB_Connection& aconnection, 
        !           137:                                         const String *asource) : fsource(asource), fconnection(aconnection), cursor(0) {
        !           138:        check("cursor", fsource, fconnection.db->cursor(fconnection.db,
        !           139:                fconnection.ftid, &cursor, 0/*flags*/));
        !           140: }
        !           141: 
        !           142: DB_Cursor::~DB_Cursor() {
        !           143:        if(cursor) {
        !           144:                check("c_close", fsource, cursor->c_close(cursor));  cursor=0;
        !           145:        }
        !           146: }
        !           147: 
        !           148: bool DB_Cursor::get(String& key, String& data, u_int32_t flags) {
        !           149:        DBT dbt_key={0}; // must be zeroed
        !           150:        DBT dbt_data={0}; // must be zeroed
        !           151:        
        !           152:        int error=cursor->c_get(cursor, &dbt_key, &dbt_data, flags);
        !           153:        if(error==DB_NOTFOUND)
        !           154:                return false;
        !           155: 
        !           156:        check("c_get", fsource, error);
        !           157: 
        !           158:        dbt_to_string(dbt_key, key);
        !           159:        dbt_to_string(dbt_data, data);
        !           160:        return true;
1.1       parser    161: }
                    162: 
                    163: #endif

E-mail: