|
|
| version 1.2, 2001/10/23 12:41:05 | version 1.4, 2001/10/24 09:03:42 |
|---|---|
| Line 13 | Line 13 |
| #include "pa_db_connection.h" | #include "pa_db_connection.h" |
| #include "pa_exception.h" | #include "pa_exception.h" |
| // DB_Connection | |
| void DB_Connection::check(const char *operation, const String *source, int error) { | void DB_Connection::check(const char *operation, const String *source, int error) { |
| switch(error) { | switch(error) { |
| case 0: | case 0: |
| Line 28 void DB_Connection::check(const char *op | Line 30 void DB_Connection::check(const char *op |
| // mark as unsafe, so not to cache it | // mark as unsafe, so not to cache it |
| needs_recovery=true; | needs_recovery=true; |
| throw Exception(0, 0, | throw Exception(0, 0, |
| &ffile_spec, | source, |
| "db %s error, run recovery utility", | "action failed, RUN RECOVERY UTILITY. db %s error, real filename '%s'", |
| operation); | operation, file_spec_cstr); |
| default: | default: |
| throw Exception(0, 0, | throw Exception(0, 0, |
| &ffile_spec, | source, |
| "db %s error: %s (%d)", | "action failed. db %s error: %s (%d), real filename '%s'", |
| operation, strerror(error), error); | operation, strerror(error), error, file_spec_cstr); |
| } | } |
| } | } |
| void DB_Connection::key_string_to_dbt(const String& key_string, DBT& key_result) { | |
| memset(&key_result, 0, sizeof(key_result)); | |
| key_result.data=key_string.cstr(String::UL_AS_IS); | |
| key_result.size=key_string.size(); | |
| } | |
| void DB_Connection::key_dbt_to_string(const DBT& key_dbt, String& key_result) { | |
| if(key_dbt.size) { | |
| char *request_data=(char *)malloc(key_dbt.size); | |
| memcpy(request_data, key_dbt.data, key_dbt.size); | |
| key_result.APPEND_TAINTED(request_data, key_dbt.size, file_spec_cstr, 0/*line*/); | |
| } | |
| } | |
| void DB_Connection::data_string_to_dbt(const String& data_string, DBT& data_result) { | |
| memset(&data_result, 0, sizeof(data_result)); | |
| data_string.serialize(sizeof(time_t), data_result.data, data_result.size); | |
| } | |
| void DB_Connection::data_dbt_to_string(const DBT& data_dbt, String& data_result) { | |
| data_result.deserialize(sizeof(time_t), data_dbt.data, data_dbt.size, file_spec_cstr); | |
| } | |
| DB_Connection::DB_Connection(Pool& pool, const String& afile_spec, DB_ENV& adbenv) : Pooled(pool), | DB_Connection::DB_Connection(Pool& pool, const String& afile_spec, DB_ENV& adbenv) : Pooled(pool), |
| fdbenv(adbenv), | fdbenv(adbenv), |
| ffile_spec(afile_spec), | ffile_spec(afile_spec), file_spec_cstr(afile_spec.cstr(String::UL_FILE_SPEC)), |
| fservices_pool(0), db(0), ftid(0), needs_recovery(false), | fservices_pool(0), db(0), ftid(0), needs_recovery(false), |
| time_used(0) { | time_used(0) { |
| } | } |
| Line 52 void DB_Connection::connect() { | Line 77 void DB_Connection::connect() { |
| DB_INFO dbinfo; | DB_INFO dbinfo; |
| memset(&dbinfo, 0, sizeof(dbinfo)); | memset(&dbinfo, 0, sizeof(dbinfo)); |
| check("open/create", &ffile_spec, db_open( | check("open/create", &ffile_spec, db_open( |
| ffile_spec.cstr(String::UL_FILE_SPEC), | file_spec_cstr, |
| PA_DB_ACCESS_METHOD, | PA_DB_ACCESS_METHOD, |
| DB_CREATE /* used in single thread, no need for |DB_THREAD*/, | DB_CREATE /* used in single thread, no need for |DB_THREAD*/, |
| 0666, | 0666, |
| Line 65 void DB_Connection::disconnect() { | Line 90 void DB_Connection::disconnect() { |
| /// @test string pieces [get/put preserve lang] | /// @test string pieces [get/put preserve lang] |
| void DB_Connection::put(const String& key, const String& data) { | void DB_Connection::put(const String& key, const String& data) { |
| // key | DBT dbt_key; key_string_to_dbt(key, dbt_key); |
| const char *cstr_key=key.cstr(String::UL_AS_IS); | DBT dbt_data; data_string_to_dbt(data, dbt_data); |
| DBT dbt_key={ | |
| (void *)cstr_key, | |
| key.size() | |
| }; | |
| // data | |
| const char *cstr_data=data.cstr(String::UL_AS_IS); | |
| DBT dbt_data={ | |
| (void *)cstr_data, | |
| data.size() | |
| }; | |
| check("put", &key, db->put(db, ftid, &dbt_key, &dbt_data, 0/*flags*/)); | check("put", &key, db->put(db, ftid, &dbt_key, &dbt_data, 0/*flags*/)); |
| } | } |
| String *DB_Connection::get(const String& key) { | String *DB_Connection::get(const String& key) { |
| // key | DBT dbt_key; key_string_to_dbt(key, dbt_key); |
| const char *cstr_key=key.cstr(String::UL_AS_IS); | |
| DBT dbt_key={ | |
| (void *)cstr_key, | |
| key.size() | |
| }; | |
| // data | // data |
| DBT dbt_data={0}; // must be zeroed | DBT dbt_data={0}; // must be zeroed |
| int error=db->get(db, ftid, &dbt_key, &dbt_data, 0/*flags*/); | int error=db->get(db, ftid, &dbt_key, &dbt_data, 0/*flags*/); |
| Line 97 String *DB_Connection::get(const String& | Line 105 String *DB_Connection::get(const String& |
| else { | else { |
| check("get", &key, error); | check("get", &key, error); |
| if(dbt_data.size) { | String *result=new(*fservices_pool) String(*fservices_pool); |
| char *request_data=(char *)malloc(dbt_data.size); | data_dbt_to_string(dbt_data, *result); |
| memcpy(request_data, dbt_data.data, dbt_data.size); | return result; |
| return NEW String(pool(), request_data, dbt_data.size, true/*tainted*/); | |
| } else | |
| return NEW String(pool()); | |
| } | } |
| } | } |
| void DB_Connection::_delete(const String& key) { | void DB_Connection::_delete(const String& key) { |
| // key | DBT dbt_key; key_string_to_dbt(key, dbt_key); |
| const char *cstr_key=key.cstr(String::UL_AS_IS); | |
| DBT dbt_key={ | |
| (void *)cstr_key, | |
| key.size() | |
| }; | |
| int error=db->del(db, ftid, &dbt_key, 0/*flags*/); | int error=db->del(db, ftid, &dbt_key, 0/*flags*/); |
| if(error!=DB_NOTFOUND) | if(error!=DB_NOTFOUND) |
| check("del", &key, error); | check("del", &key, error); |
| } | } |
| DB_Cursor DB_Connection::cursor(const String *source) { | |
| return DB_Cursor(*this, source); | |
| } | |
| // DB_Cursor | |
| DB_Cursor::DB_Cursor( | |
| DB_Connection& aconnection, | |
| const String *asource) : fsource(asource), fconnection(aconnection), cursor(0) { | |
| check("cursor", fsource, fconnection.db->cursor(fconnection.db, | |
| fconnection.ftid, &cursor, 0/*flags*/)); | |
| } | |
| DB_Cursor::~DB_Cursor() { | |
| if(cursor) { | |
| check("c_close", fsource, cursor->c_close(cursor)); cursor=0; | |
| } | |
| } | |
| bool DB_Cursor::get(String& key, String& data, u_int32_t flags) { | |
| DBT dbt_key={0}; // must be zeroed | |
| DBT dbt_data={0}; // must be zeroed | |
| int error=cursor->c_get(cursor, &dbt_key, &dbt_data, flags); | |
| if(error==DB_NOTFOUND) | |
| return false; | |
| check("c_get", fsource, error); | |
| key_dbt_to_string(dbt_key, key); | |
| data_dbt_to_string(dbt_data, data); | |
| return true; | |
| } | |
| #endif | #endif |