|
|
1.1 parser 1: /** @file
2: Parser: @b table class.
3:
4: Copyright(c) 2001 ArtLebedev Group(http://www.artlebedev.com)
5: Author: Alexander Petrosyan <paf@design.ru>(http://design.ru/paf)
6:
1.2 ! parser 7: $Id: pa_vhashfile.C,v 1.1 2001/10/22 12:30:24 parser Exp $
1.1 parser 8: */
9:
10: #include "pa_config_includes.h"
11: #ifdef HAVE_LIBDB
12:
13: #include "pa_vtable.h"
14: #include "pa_vstring.h"
15: #include "pa_vhashfile.h"
16: #include "pa_threads.h"
17:
18:
19: #ifdef HAVE_DB_H
20: # include <db.h>
21: #endif
22:
23: // defines
24:
25: #define PA_DB_ACCESS_METHOD DB_BTREE
26:
27: // methods
28:
29: void VHashfile::check(const char *operation, const String *source, int error) {
30: switch(error) {
31: case 0:
32: // no error
33: break;
34:
35: case DB_KEYEXIST:
36: // DB_KEYEXIST is a "normal" return, so should not be
37: // thrown as an error
38: break;
39:
40: case DB_RUNRECOVERY:
41: throw Exception(0, 0,
42: &get_file_spec(source),
43: "db %s error, run recovery utility",
44: operation);
45:
46: default:
47: throw Exception(0, 0,
48: &get_file_spec(source),
49: "db %s error: %s (%d)",
50: operation, strerror(errno), errno);
51: }
52: }
53:
54: /**
55: @test some caching manager of opened files
56: @test string pieces [get/put preserve lang]
57: */
58: void VHashfile::put_field(const String& name, Value *value) {
59: DB *db;
60: // open
61: DB_INFO dbinfo;
62: memset(&dbinfo, 0, sizeof(dbinfo));
63: check("open/create", &name, db_open(
64: get_file_spec_cstr(&name),
1.2 ! parser 65: PA_DB_ACCESS_METHOD,
1.1 parser 66: DB_CREATE /*| DB_THREAD*/,
67: 0666,
68: 0, &dbinfo, &db));
69:
70: try {
71: // put
72:
73: // key
74: const char *cstr_key=name.cstr(String::UL_AS_IS);
75: DBT key={
76: (void *)cstr_key,
77: name.size()
78: };
79:
80: // data
81: const String& string=value->as_string();
82: const char *cstr_data=string.cstr(String::UL_AS_IS);
83: DBT data={
84: (void *)cstr_data,
85: string.size()
86: };
87: check("put", &name, db->put(db, 0/*DB_TXN*/, &key, &data, 0/*flags*/));
88:
89: } catch(...) {
90: check("close", &name, db->close(db, 0));
91: /*re*/throw;
92: }
93:
94: // close
95: check("close", &name, db->close(db, 0));
96: }
97:
98: Value *VHashfile::get_field(const String& name) {
99: Value *result=0;
100:
101: DB *db;
102: // open
103: DB_INFO dbinfo;
104: memset(&dbinfo, 0, sizeof(dbinfo));
105: check("open", &name, db_open(
106: get_file_spec_cstr(&name),
1.2 ! parser 107: PA_DB_ACCESS_METHOD,
1.1 parser 108: 0 /*| DB_THREAD*/,
109: 0,
110: 0, &dbinfo, &db));
111:
112: try {
113: // get
114:
115: // key
116: const char *cstr_key=name.cstr(String::UL_AS_IS);
117: DBT key={
118: (void *)cstr_key,
119: name.size()
120: };
121:
122: // data
123: DBT data={0}; // must be zeroed
124: check("get", &name, db->get(db, 0/*DB_TXN*/, &key, &data, 0/*flags*/));
125:
126: char *request_data=(char *)malloc(data.size);
127: memcpy(request_data, data.data, data.size);
128: result=NEW VString(*NEW String(pool(), request_data, data.size, true/*tainted*/));
129:
130: } catch(...) {
131: check("close", &name, db->close(db, 0));
132: /*re*/throw;
133: }
134:
135: // close
136: check("close", &name, db->close(db, 0));
137:
138: // return
139: return result;
140: }
141:
142: Hash *VHashfile::get_hash() {
143: return 0;
144: }
145:
146: #endif