forked from ethereum/aleth
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDBFactory.cpp
More file actions
166 lines (142 loc) · 3.93 KB
/
Copy pathDBFactory.cpp
File metadata and controls
166 lines (142 loc) · 3.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
// Aleth: Ethereum C++ client, tools and libraries.
// Copyright 2018-2019 Aleth Authors.
// Licensed under the GNU General Public License, Version 3.
#include "DBFactory.h"
#include "FileSystem.h"
#include "LevelDB.h"
#include "MemoryDB.h"
#include "libethcore/Exceptions.h"
#if ALETH_ROCKSDB
#include "RocksDB.h"
#endif
namespace dev
{
namespace db
{
namespace fs = boost::filesystem;
namespace po = boost::program_options;
auto g_kind = DatabaseKind::LevelDB;
fs::path g_dbPath;
/// A helper type to build the table of DB implementations.
///
/// More readable than std::tuple.
/// Fields are not initialized to allow usage of construction with initializer lists {}.
struct DBKindTableEntry
{
DatabaseKind kind;
char const* name;
};
/// The table of available DB implementations.
///
/// We don't use a map to avoid complex dynamic initialization. This list will never be long,
/// so linear search only to parse command line arguments is not a problem.
DBKindTableEntry dbKindsTable[] = {
{DatabaseKind::LevelDB, "leveldb"},
#if ALETH_ROCKSDB
{DatabaseKind::RocksDB, "rocksdb"},
#endif
{DatabaseKind::MemoryDB, "memorydb"},
};
void setDatabaseKindByName(std::string const& _name)
{
for (auto& entry : dbKindsTable)
{
if (_name == entry.name)
{
g_kind = entry.kind;
return;
}
}
BOOST_THROW_EXCEPTION(
eth::InvalidDatabaseKind() << errinfo_comment("invalid database name supplied: " + _name));
}
void setDatabaseKind(DatabaseKind _kind)
{
g_kind = _kind;
}
void setDatabasePath(std::string const& _path)
{
g_dbPath = fs::path(_path);
}
bool isDiskDatabase()
{
switch (g_kind)
{
case DatabaseKind::LevelDB:
case DatabaseKind::RocksDB:
return true;
default:
return false;
}
}
DatabaseKind databaseKind()
{
return g_kind;
}
fs::path databasePath()
{
return g_dbPath.empty() ? getDataDir() : g_dbPath;
}
po::options_description databaseProgramOptions(unsigned _lineLength)
{
// It must be a static object because boost expects const char*.
static std::string const description = [] {
std::string names;
for (auto const& entry : dbKindsTable)
{
if (!names.empty())
names += ", ";
names += entry.name;
}
return "Select database implementation. Available options are: " + names + ".";
}();
po::options_description opts("DATABASE OPTIONS", _lineLength);
auto add = opts.add_options();
add("db",
po::value<std::string>()->value_name("<name>")->default_value("leveldb")->notifier(
setDatabaseKindByName),
description.data());
add("db-path",
po::value<std::string>()
->value_name("<path>")
->default_value(getDataDir().string())
->notifier(setDatabasePath),
"Database path (for non-memory database options)\n");
return opts;
}
std::unique_ptr<DatabaseFace> DBFactory::create()
{
return create(databasePath());
}
std::unique_ptr<DatabaseFace> DBFactory::create(fs::path const& _path)
{
return create(g_kind, _path);
}
std::unique_ptr<DatabaseFace> DBFactory::create(DatabaseKind _kind)
{
return create(_kind, databasePath());
}
std::unique_ptr<DatabaseFace> DBFactory::create(DatabaseKind _kind, fs::path const& _path)
{
switch (_kind)
{
case DatabaseKind::LevelDB:
return std::unique_ptr<DatabaseFace>(new LevelDB(_path));
break;
#if ALETH_ROCKSDB
case DatabaseKind::RocksDB:
return std::unique_ptr<DatabaseFace>(new RocksDB(_path));
break;
#endif
case DatabaseKind::MemoryDB:
// Silently ignore path since the concept of a db path doesn't make sense
// when using an in-memory database
return std::unique_ptr<DatabaseFace>(new MemoryDB());
break;
default:
assert(false);
return {};
}
}
} // namespace db
} // namespace dev