Annotation of parser3/src/types/pa_vhashfile.C, revision 1.27
1.1 parser 1: /** @file
2: Parser: @b table class.
3:
1.20 paf 4: Copyright(c) 2001, 2002 ArtLebedev Group (http://www.artlebedev.com)
1.19 paf 5: Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
1.1 parser 6: */
7:
1.27 ! paf 8: static const char* IDENT="$Date: 2003/11/06 11:12:44 $";
1.1 parser 9:
10: #include "pa_vtable.h"
11: #include "pa_vstring.h"
12: #include "pa_vhashfile.h"
13: #include "pa_threads.h"
1.8 parser 14: #include "pa_globals.h"
1.1 parser 15:
16: // methods
17:
1.22 paf 18: void check(const char *step, apr_status_t status) {
19: if(status==APR_SUCCESS)
20: return;
21:
22: throw Exception("todo.todo",
23: 0,
24: "%s error: %d", step, status);
25: }
26:
27: void VHashfile::open(const String& afile_name) {
1.27 ! paf 28: check("apr_sdbm_open(shared)", apr_sdbm_open(&db, file_name=afile_name.cstr(String::L_FILE_SPEC),
! 29: APR_CREATE|APR_READ|APR_SHARELOCK,
1.22 paf 30: 0664, 0));
31: }
32:
1.27 ! paf 33: void VHashfile::make_writable() {
! 34: if(db && apr_sdbm_rdonly(db)) {
! 35: check("apr_sdbm_close", apr_sdbm_close(db));
! 36: check("apr_sdbm_open(exclusive)", apr_sdbm_open(&db, file_name,
! 37: APR_WRITE,
! 38: 0664, 0));
! 39: }
! 40: }
! 41:
1.22 paf 42: VHashfile::~VHashfile() {
43: if(db)
44: check("apr_sdbm_close", apr_sdbm_close(db));
45: }
46:
1.27 ! paf 47: void VHashfile::put_field(const String& aname, Value *avalue) {
! 48: make_writable();
1.22 paf 49:
1.8 parser 50: time_t time_to_die=0;
51: const String *value_string;
52:
1.23 paf 53: if(HashStringValue *hash=avalue->get_hash()) {
54: if(Value *value_value=hash->get(value_name)) {
1.9 parser 55: if(value_value->get_junction())
1.23 paf 56: throw Exception(0,
57: 0,
58: VALUE_NAME" must not be code");
1.8 parser 59:
60: value_string=&value_value->as_string();
61:
1.23 paf 62: if(Value *expires_value=hash->get(expires_name))
1.8 parser 63: time_to_die=time(0)+(time_t)expires_value->as_double();
64: } else
1.23 paf 65: throw Exception(0,
1.8 parser 66: &aname,
1.23 paf 67: "put hash value must contain ."VALUE_NAME);
1.8 parser 68: } else
69: value_string=&avalue->as_string();
1.5 parser 70:
1.23 paf 71: // get_table_ptr(&aname)->put(aname, *value_string, time_to_die);
72:
73: apr_sdbm_datum_t key;
74: key.dptr=const_cast<char*>(aname.cstr());
1.24 paf 75: key.dsize=aname.length();
1.23 paf 76:
77: apr_sdbm_datum_t value;
78: value.dptr=const_cast<char*>(value_string->cstr());
1.24 paf 79: value.dsize=value_string->length();
1.23 paf 80:
81: // * APR_SDBM_INSERT return an error if the record exists
82: check("apr_sdbm_store", apr_sdbm_store(db, key, value, APR_SDBM_REPLACE));
1.1 parser 83: }
84:
1.11 paf 85: Value *VHashfile::get_field(const String& aname) {
1.23 paf 86: apr_sdbm_datum_t key;
87: key.dptr=const_cast<char*>(aname.cstr());
1.24 paf 88: key.dsize=aname.length();
1.23 paf 89:
90: apr_sdbm_datum_t value;
91:
92: check("apr_sdbm_fetch", apr_sdbm_fetch(db, &value, key));
93:
94: if(value.dptr)
1.26 paf 95: return new VString(*new String(pa_strdup(value.dptr, value.dsize), true));
1.3 parser 96: else
97: return 0;
1.24 paf 98: }
99:
100: void VHashfile::remove(const String& aname) {
1.27 ! paf 101: make_writable();
! 102:
1.24 paf 103: apr_sdbm_datum_t key;
104: key.dptr=const_cast<char*>(aname.cstr());
105: key.dsize=aname.length();
106:
107: check("apr_sdbm_delete", apr_sdbm_delete(db, key));
1.1 parser 108: }
109:
1.27 ! paf 110: void VHashfile::for_each(void callback(apr_sdbm_datum_t, void*), void* info) const {
1.25 paf 111: check("apr_sdbm_lock", apr_sdbm_lock(db, APR_FLOCK_SHARED));
112: try {
113: apr_sdbm_datum_t apkey;
114: if(apr_sdbm_firstkey(db, &apkey)==APR_SUCCESS)
115: do {
1.27 ! paf 116: callback(apkey, info);
1.25 paf 117: } while(apr_sdbm_nextkey(db, &apkey)==APR_SUCCESS);
118: } catch(...) {
119: check("apr_sdbm_unlock", apr_sdbm_unlock(db));
120: rethrow;
1.4 parser 121: }
122:
1.25 paf 123: check("apr_sdbm_unlock", apr_sdbm_unlock(db));
1.26 paf 124: }
1.27 ! paf 125:
! 126: #ifndef DOXYGEN
! 127: struct For_each_string_callback_info {
! 128: apr_sdbm_t *db;
! 129: void* nested_info;
! 130: void (*nested_callback)(const String::Body, const String&, void*);
! 131: };
! 132: #endif
! 133: static void for_each_string_callback(apr_sdbm_datum_t apkey, void* ainfo) {
! 134: For_each_string_callback_info& info=*static_cast<For_each_string_callback_info *>(ainfo);
! 135:
! 136: apr_sdbm_datum_t apvalue;
! 137: check("apr_sdbm_fetch", apr_sdbm_fetch(info.db, &apvalue, apkey));
! 138:
! 139: const char *clkey=pa_strdup(apkey.dptr, apkey.dsize);
! 140: const char *clvalue=pa_strdup(apvalue.dptr, apvalue.dsize);
! 141: const String& svalue=*new String(clvalue, true);
! 142: info.nested_callback(clkey, svalue, info.nested_info);
! 143: }
! 144: void VHashfile::for_each(void callback(const String::Body, const String&, void*), void* ainfo) const {
! 145: For_each_string_callback_info info;
! 146:
! 147: info.db=db;
! 148: info.nested_info=ainfo;
! 149: info.nested_callback=callback;
! 150:
! 151: for_each(for_each_string_callback, &info);
! 152: }
! 153:
! 154: void clear_callback(apr_sdbm_datum_t key, void* adb) {
! 155: check("apr_sdbm_delete", apr_sdbm_delete(static_cast<apr_sdbm_t *>(adb), key));
! 156: }
! 157:
! 158: void VHashfile::clear() {
! 159: make_writable();
! 160:
! 161: for_each(clear_callback, db);
! 162: }
! 163:
1.26 paf 164:
165: static void get_hash__put(const String::Body key, const String& value, void* aresult) {
166: static_cast<HashStringValue*>(aresult)->put(key, new VString(value));
167: }
168:
169: HashStringValue *VHashfile::get_hash() {
170: HashStringValue& result=*new HashStringValue();
171:
172: for_each(get_hash__put, &result);
173: return &result;
1.1 parser 174: }
E-mail: