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: