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: