blob: c9c4cf3c1589d33485c9e76c13524b184de9c4b1 [file] [log] [blame]
dburgess82c46ff2011-10-07 02:40:51 +00001/*
2* Copyright 2009, 2010 Free Software Foundation, Inc.
3* Copyright 2010 Kestrel Signal Processing, Inc.
4*
5* This software is distributed under the terms of the GNU Affero Public License.
6* See the COPYING file in the main directory for details.
7*
8* This use of this software may be subject to additional restrictions.
9* See the LEGAL file in the main directory for details.
10
11 This program is free software: you can redistribute it and/or modify
12 it under the terms of the GNU Affero General Public License as published by
13 the Free Software Foundation, either version 3 of the License, or
14 (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU Affero General Public License for more details.
20
21 You should have received a copy of the GNU Affero General Public License
22 along with this program. If not, see <http://www.gnu.org/licenses/>.
23
24*/
25
26
27#ifndef CONFIGURATION_H
28#define CONFIGURATION_H
29
30
31#include "sqlite3util.h"
32
33#include <assert.h>
34#include <stdlib.h>
35
36#include <map>
37#include <vector>
38#include <string>
39#include <iostream>
40
41#include <Threads.h>
42#include <stdint.h>
43
44
45/** A class for configuration file errors. */
46class ConfigurationTableError {};
47
48/** An exception thrown when a given config key isn't found. */
49class ConfigurationTableKeyNotFound : public ConfigurationTableError {
50
51 private:
52
53 std::string mKey;
54
55 public:
56
57 ConfigurationTableKeyNotFound(const std::string& wKey)
58 :mKey(wKey)
59 { std::cerr << "cannot find configuration value " << mKey << std::endl; }
60
61 const std::string& key() const { return mKey; }
62
63};
64
65
66class ConfigurationRecord {
67
68 private:
69
70 std::string mValue;
71 long mNumber;
72 bool mDefined;
73
74 public:
75
76 ConfigurationRecord(bool wDefined=true):
77 mDefined(wDefined)
78 { }
79
80 ConfigurationRecord(const std::string& wValue):
81 mValue(wValue),
82 mNumber(strtol(wValue.c_str(),NULL,0)),
83 mDefined(true)
84 { }
85
86 ConfigurationRecord(const char* wValue):
87 mValue(std::string(wValue)),
88 mNumber(strtol(wValue,NULL,0)),
89 mDefined(true)
90 { }
91
92
93 const std::string& value() const { return mValue; }
94 long number() const { return mNumber; }
95 bool defined() const { return mDefined; }
96
97};
98
99
100/** A string class that uses a hash function for comparison. */
101class HashString : public std::string {
102
103
104 protected:
105
106 uint64_t mHash;
107
108 void computeHash();
109
110
111 public:
112
113 HashString(const char* src)
114 :std::string(src)
115 {
116 computeHash();
117 }
118
119 HashString(const std::string& src)
120 :std::string(src)
121 {
122 computeHash();
123 }
124
125 HashString()
126 {
127 mHash=0;
128 }
129
130 HashString& operator=(std::string& src)
131 {
132 std::string::operator=(src);
133 computeHash();
134 return *this;
135 }
136
137 HashString& operator=(const char* src)
138 {
139 std::string::operator=(src);
140 computeHash();
141 return *this;
142 }
143
144 bool operator==(const HashString& other)
145 {
146 return mHash==other.mHash;
147 }
148
149 bool operator<(const HashString& other)
150 {
151 return mHash<other.mHash;
152 }
153
154 bool operator>(const HashString& other)
155 {
156 return mHash<other.mHash;
157 }
158
159 uint64_t hash() const { return mHash; }
160
161};
162
163
164typedef std::map<HashString, ConfigurationRecord> ConfigurationMap;
165
166
167/**
168 A class for maintaining a configuration key-value table,
169 based on sqlite3 and a local map-based cache.
170 Thread-safe, too.
171*/
172class ConfigurationTable {
173
174 private:
175
176 sqlite3* mDB; ///< database connection
177 ConfigurationMap mCache; ///< cache of recently access configuration values
178 mutable Mutex mLock; ///< control for multithreaded access to the cache
179
180 public:
181
182
183 ConfigurationTable(const char* filename = ":memory:");
184
185 /** Return true if the key is used in the table. */
186 bool defines(const std::string& key);
187
188 /** Return true if this key is identified as static. */
189 bool isStatic(const std::string& key) const;
190
191 /** Return true if this key is identified as required (!optional). */
192 bool isRequired(const std::string& key) const;
193
194 /**
195 Get a string parameter from the table.
196 Throw ConfigurationTableKeyNotFound if not found.
197 */
198 std::string getStr(const std::string& key);
199
200
201 /**
202 Get a string parameter from the table.
203 Define the parameter to the default value if not found.
204 */
205 std::string getStr(const std::string& key, const char* defaultValue);
206
207
208 /**
209 Get a numeric parameter from the table.
210 Throw ConfigurationTableKeyNotFound if not found.
211 */
212 long getNum(const std::string& key);
213
214 /**
215 Get a numeric parameter from the table.
216 Define the parameter to the default value if not found.
217 */
218 long getNum(const std::string& key, long defaultValue);
219
220 /**
221 Get a numeric vector from the table.
222 */
223 std::vector<unsigned> getVector(const std::string& key);
224
225 /** Get length of a vector */
226 unsigned getVectorLength(const std::string &key)
227 { return getVector(key).size(); }
228
229 /** Set or change a value in the table. */
230 bool set(const std::string& key, const std::string& value);
231
232 /** Set or change a value in the table. */
233 bool set(const std::string& key, long value);
234
235 /** Create an entry in the table, no value though. */
236 bool set(const std::string& key);
237
238 /**
239 Remove a key from the table.
240 Will not remove static or required values.
241 @param key The key of the item to be deleted.
242 @return true if anything was actually removed.
243 */
244 bool unset(const std::string& key);
245
246 /** Search the table, dumping to a stream. */
247 void find(const std::string& pattern, std::ostream&) const;
248
249 /** Define the callback to purge the cache whenever the database changes. */
250 void setUpdateHook(void(*)(void *,int ,char const *,char const *,sqlite3_int64));
251
252 /** purege cache if it exceeds a certain age */
253 void checkCacheAge();
254
255 /** Delete all records from the cache. */
256 void purge();
257
258
259 private:
260
261 /**
262 Attempt to lookup a record, cache if needed.
263 Throw ConfigurationTableKeyNotFound if not found.
264 Caller should hold mLock because the returned reference points into the cache.
265 */
266 const ConfigurationRecord& lookup(const std::string& key);
267
268};
269
270
271
272#endif
273
274
275// vim: ts=4 sw=4