8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-22 16:43:03 +01:00

Refactor internal representation of configuration entries table.

Trivial getXXX methods now automatically generated with help of new macros.
It allows to guarantee correct method declaration and impl. details in correspondence of parameter globality.
Most getXXX methods are trivial and moved into class declaration now.
RDB$CONFIG filling code now get values of global parameters using default config instance.
This commit is contained in:
hvlad 2020-11-24 14:40:54 +02:00
parent f3c95a5927
commit 974a641d8e
3 changed files with 456 additions and 664 deletions

View File

@ -22,7 +22,7 @@ Only ones mentioned in this document could be used, but as necessities appears,
- [rvalue references](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2027.html)
- [strongly-typed enum](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2347.pdf)
- [atomic types and operations](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2427.html)
- [static_assert](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1720.html)
- [decltype](https://en.cppreference.com/w/cpp/language/decltype)
- [std::is_convertible](https://en.cppreference.com/w/cpp/types/is_convertible)
- [final specifier](https://en.cppreference.com/w/cpp/language/final)
- [constexpr](https://en.cppreference.com/w/cpp/language/constexpr)

View File

@ -141,100 +141,7 @@ const char* GCPolicyCooperative = "cooperative";
const char* GCPolicyBackground = "background";
const char* GCPolicyCombined = "combined";
Config::ConfigEntry Config::entries[MAX_CONFIG_KEY] =
{
{TYPE_INTEGER, "TempBlockSize", ConfigValue(1048576)}, // bytes
{TYPE_INTEGER, "TempCacheLimit", ConfigValue(-1)}, // bytes
{TYPE_BOOLEAN, "RemoteFileOpenAbility", ConfigValue(false)},
{TYPE_INTEGER, "GuardianOption", ConfigValue(1)},
{TYPE_INTEGER, "CpuAffinityMask", ConfigValue(0)},
{TYPE_INTEGER, "TcpRemoteBufferSize", ConfigValue(8192)}, // bytes
{TYPE_BOOLEAN, "TcpNoNagle", ConfigValue(true)},
{TYPE_BOOLEAN, "TcpLoopbackFastPath", ConfigValue(true)},
{TYPE_INTEGER, "DefaultDbCachePages", ConfigValue(-1)}, // pages
{TYPE_INTEGER, "ConnectionTimeout", ConfigValue(180)}, // seconds
{TYPE_INTEGER, "DummyPacketInterval", ConfigValue(0)}, // seconds
{TYPE_STRING, "DefaultTimeZone", ConfigValue(nullptr)},
{TYPE_INTEGER, "LockMemSize", ConfigValue(1048576)}, // bytes
{TYPE_INTEGER, "LockHashSlots", ConfigValue(8191)}, // slots
{TYPE_INTEGER, "LockAcquireSpins", ConfigValue(0)},
{TYPE_INTEGER, "EventMemSize", ConfigValue(65536)}, // bytes
{TYPE_INTEGER, "DeadlockTimeout", ConfigValue(10)}, // seconds
{TYPE_STRING, "RemoteServiceName", ConfigValue(FB_SERVICE_NAME)},
{TYPE_INTEGER, "RemoteServicePort", ConfigValue(0)},
{TYPE_STRING, "RemotePipeName", ConfigValue(FB_PIPE_NAME)},
{TYPE_STRING, "IpcName", ConfigValue(FB_IPC_NAME)},
#ifdef WIN_NT
{TYPE_INTEGER, "MaxUnflushedWrites", ConfigValue(100)},
{TYPE_INTEGER, "MaxUnflushedWriteTime", ConfigValue(5)},
#else
{TYPE_INTEGER, "MaxUnflushedWrites", ConfigValue(-1)},
{TYPE_INTEGER, "MaxUnflushedWriteTime", ConfigValue(-1)},
#endif
{TYPE_INTEGER, "ProcessPriorityLevel", ConfigValue(0)},
{TYPE_INTEGER, "RemoteAuxPort", ConfigValue(0)},
{TYPE_STRING, "RemoteBindAddress", ConfigValue(0)},
{TYPE_STRING, "ExternalFileAccess", ConfigValue("None")}, // location(s) of external files for tables
{TYPE_STRING, "DatabaseAccess", ConfigValue("Full")}, // location(s) of databases
{TYPE_STRING, "UdfAccess", ConfigValue("None")}, // location(s) of UDFs
{TYPE_STRING, "TempDirectories", ConfigValue(0)},
#ifdef DEV_BUILD
{TYPE_BOOLEAN, "BugcheckAbort", ConfigValue(true)}, // whether to abort() engine when internal error is found
#else
{TYPE_BOOLEAN, "BugcheckAbort", ConfigValue(false)}, // whether to abort() engine when internal error is found
#endif
{TYPE_INTEGER, "TraceDSQL", ConfigValue(0)}, // bitmask
{TYPE_BOOLEAN, "LegacyHash", ConfigValue(true)}, // let use old passwd hash verification
{TYPE_STRING, "GCPolicy", ConfigValue(nullptr)}, // garbage collection policy
{TYPE_BOOLEAN, "Redirection", ConfigValue(false)},
{TYPE_INTEGER, "DatabaseGrowthIncrement", ConfigValue(128 * 1048576)}, // bytes
{TYPE_INTEGER, "FileSystemCacheThreshold", ConfigValue(65536)}, // page buffers
{TYPE_BOOLEAN, "RelaxedAliasChecking", ConfigValue(false)}, // if true relax strict alias checking rules in DSQL a bit
{TYPE_STRING, "AuditTraceConfigFile", ConfigValue("")}, // location of audit trace configuration file
{TYPE_INTEGER, "MaxUserTraceLogSize", ConfigValue(10)}, // maximum size of user session trace log
{TYPE_INTEGER, "FileSystemCacheSize", ConfigValue(0)}, // percent
{TYPE_STRING, "Providers", ConfigValue("Remote, " CURRENT_ENGINE ", Loopback")},
{TYPE_STRING, "AuthServer", ConfigValue("Srp256")},
#ifdef WIN_NT
{TYPE_STRING, "AuthClient", ConfigValue("Srp256, Srp, Win_Sspi, Legacy_Auth")},
#else
{TYPE_STRING, "AuthClient", ConfigValue("Srp256, Srp, Legacy_Auth")},
#endif
{TYPE_STRING, "UserManager", ConfigValue("Srp")},
{TYPE_STRING, "TracePlugin", ConfigValue("fbtrace")},
{TYPE_STRING, "SecurityDatabase", ConfigValue(nullptr)}, // sec/db alias - rely on ConfigManager::getDefaultSecurityDb()
{TYPE_STRING, "ServerMode", ConfigValue(nullptr)}, // actual value differs in boot/regular cases and set at setupDefaultConfig()
{TYPE_STRING, "WireCrypt", ConfigValue(nullptr)},
{TYPE_STRING, "WireCryptPlugin", ConfigValue("ChaCha, Arc4")},
{TYPE_STRING, "KeyHolderPlugin", ConfigValue("")},
{TYPE_BOOLEAN, "RemoteAccess", ConfigValue(true)},
{TYPE_BOOLEAN, "IPv6V6Only", ConfigValue(false)},
{TYPE_BOOLEAN, "WireCompression", ConfigValue(false)},
{TYPE_INTEGER, "MaxIdentifierByteLength", ConfigValue(MAX_SQL_IDENTIFIER_LEN)},
{TYPE_INTEGER, "MaxIdentifierCharLength", ConfigValue(METADATA_IDENTIFIER_CHAR_LEN)},
{TYPE_BOOLEAN, "AllowEncryptedSecurityDatabase", ConfigValue(false)},
{TYPE_INTEGER, "StatementTimeout", ConfigValue(0)},
{TYPE_INTEGER, "ConnectionIdleTimeout", ConfigValue(0)},
{TYPE_INTEGER, "ClientBatchBuffer", ConfigValue((128 * 1024))},
#ifdef DEV_BUILD
{TYPE_STRING, "OutputRedirectionFile", ConfigValue("-")},
#else
#ifdef WIN_NT
{TYPE_STRING, "OutputRedirectionFile", ConfigValue("nul")},
#else
{TYPE_STRING, "OutputRedirectionFile", ConfigValue("/dev/null")},
#endif
#endif
{TYPE_INTEGER, "ExtConnPoolSize", ConfigValue(0)},
{TYPE_INTEGER, "ExtConnPoolLifeTime", ConfigValue(7200)},
{TYPE_INTEGER, "SnapshotsMemSize", ConfigValue(65536)}, // bytes
{TYPE_INTEGER, "TipCacheBlockSize", ConfigValue(4194304)}, // bytes
{TYPE_BOOLEAN, "ReadConsistency", ConfigValue(true)},
{TYPE_BOOLEAN, "ClearGTTAtRetaining", ConfigValue(false)},
{TYPE_STRING, "DataTypeCompatibility", ConfigValue(nullptr)},
{TYPE_BOOLEAN, "UseFileSystemCache", ConfigValue(true)}
};
ConfigValue Config::defaults[MAX_CONFIG_KEY];
/******************************************************************************
*
@ -244,7 +151,8 @@ Config::ConfigEntry Config::entries[MAX_CONFIG_KEY] =
Config::Config(const ConfigFile& file)
: notifyDatabase(*getDefaultMemoryPool()),
valuesSource(*getDefaultMemoryPool()),
serverMode(-1)
serverMode(-1),
defaultConfig(false)
{
memset(sourceIdx, 0, sizeof(sourceIdx));
valuesSource.add(NULL);
@ -258,7 +166,7 @@ Config::Config(const ConfigFile& file)
// Iterate through the known configuration entries
for (unsigned int i = 0; i < MAX_CONFIG_KEY; i++)
{
values[i] = entries[i].default_value;
values[i] = defaults[i];
if (entries[i].data_type == TYPE_STRING && values[i].strVal)
{
ConfigFile::String expand(values[i].strVal);
@ -277,7 +185,8 @@ Config::Config(const ConfigFile& file)
Config::Config(const ConfigFile& file, const char* srcName, const Config& base, const PathName& notify)
: notifyDatabase(*getDefaultMemoryPool()),
valuesSource(*getDefaultMemoryPool()),
serverMode(-1)
serverMode(-1),
defaultConfig(false)
{
memset(sourceIdx, 0, sizeof(sourceIdx));
valuesSource.add(NULL);
@ -332,20 +241,21 @@ void Config::loadValues(const ConfigFile& file, const char* srcName)
const ConfigEntry& entry = entries[i];
const ConfigFile::Parameter* par = file.findParameter(entry.key);
if (par)
// Don't assign values to the global keys at non-default config
if (par && (defaultConfig || !entry.is_global))
{
// Assign the actual value
switch (entry.data_type)
{
case TYPE_BOOLEAN:
values[i] = (ConfigValue) par->asBoolean();
values[i].boolVal = par->asBoolean();
break;
case TYPE_INTEGER:
values[i] = (ConfigValue) par->asInteger();
values[i].intVal = par->asInteger();
break;
case TYPE_STRING:
values[i] = (ConfigValue) par->value.c_str();
values[i].strVal = par->value.c_str();
break;
//case TYPE_STRING_VECTOR:
// break;
@ -363,7 +273,7 @@ void Config::loadValues(const ConfigFile& file, const char* srcName)
sourceIdx[i] = srcIdx;
}
if (entry.data_type == TYPE_STRING && values[i] != entry.default_value)
if (entry.data_type == TYPE_STRING && values[i] != defaults[i])
{
const char* src = values[i].strVal;
char* dst = FB_NEW_POOL(getPool()) char[strlen(src) + 1];
@ -384,23 +294,28 @@ static const char* txtServerModes[6] =
void Config::setupDefaultConfig()
{
defaultConfig = true;
for (unsigned i = 0; i < MAX_CONFIG_KEY; i++)
defaults[i] = entries[i].default_value;
const bool bootBuild = fb_utils::bootBuild();
ConfigValue* pDefault = &entries[KEY_SERVER_MODE].default_value;
ConfigValue* pDefault = &defaults[KEY_SERVER_MODE];
serverMode = bootBuild ? MODE_CLASSIC : MODE_SUPER;
pDefault->strVal = txtServerModes[2 * serverMode];
pDefault = &entries[KEY_TEMP_CACHE_LIMIT].default_value;
pDefault = &defaults[KEY_TEMP_CACHE_LIMIT];
if (pDefault->intVal < 0)
pDefault->intVal = (serverMode != MODE_SUPER) ? 8388608 : 67108864; // bytes
entries[KEY_REMOTE_FILE_OPEN_ABILITY].default_value.boolVal = bootBuild;
defaults[KEY_REMOTE_FILE_OPEN_ABILITY].boolVal = bootBuild;
pDefault = &entries[KEY_DEFAULT_DB_CACHE_PAGES].default_value;
pDefault = &defaults[KEY_DEFAULT_DB_CACHE_PAGES];
if (pDefault->intVal < 0)
pDefault->intVal = (serverMode != MODE_SUPER) ? 256 : 2048; // pages
pDefault = &entries[KEY_GC_POLICY].default_value;
pDefault = &defaults[KEY_GC_POLICY];
if (!pDefault->strVal)
{
pDefault->strVal = (serverMode == MODE_SUPER) ? GCPolicyCombined : GCPolicyCooperative;
@ -416,14 +331,14 @@ void Config::checkIntForLoBound(ConfigKey key, SINT64 loBound, bool setDefault)
{
fb_assert(entries[key].data_type == TYPE_INTEGER);
if (values[key].intVal < loBound)
values[key].intVal = setDefault ? entries[key].default_value.intVal : loBound;
values[key].intVal = setDefault ? defaults[key].intVal : loBound;
}
void Config::checkIntForHiBound(ConfigKey key, SINT64 hiBound, bool setDefault)
{
fb_assert(entries[key].data_type == TYPE_INTEGER);
if (values[key].intVal > hiBound)
values[key].intVal = setDefault ? entries[key].default_value.intVal : hiBound;
values[key].intVal = setDefault ? defaults[key].intVal : hiBound;
}
void Config::checkValues()
@ -446,7 +361,7 @@ void Config::checkValues()
gcPolicy != GCPolicyCombined)
{
// user-provided value is invalid - fail to default
values[KEY_GC_POLICY] = entries[KEY_GC_POLICY].default_value;
values[KEY_GC_POLICY] = defaults[KEY_GC_POLICY];
}
}
@ -457,7 +372,7 @@ void Config::checkValues()
if (wireCrypt != "DISABLED" && wireCrypt != "ENABLED" && wireCrypt != "REQUIRED")
{
// user-provided value is invalid - fail to default
values[KEY_WIRE_CRYPT] = entries[KEY_WIRE_CRYPT].default_value;
values[KEY_WIRE_CRYPT] = defaults[KEY_WIRE_CRYPT];
}
}
@ -477,7 +392,7 @@ void Config::checkValues()
}
if (!found)
values[KEY_SERVER_MODE] = entries[KEY_SERVER_MODE].default_value;
values[KEY_SERVER_MODE] = defaults[KEY_SERVER_MODE];
}
checkIntForLoBound(KEY_FILESYSTEM_CACHE_THRESHOLD, 0, true);
@ -502,7 +417,7 @@ Config::~Config()
for (int i = 0; i < MAX_CONFIG_KEY; i++)
{
if (values[i] == entries[i].default_value)
if (values[i] == defaults[i])
continue;
switch (entries[i].data_type)
@ -606,11 +521,11 @@ bool Config::valueAsString(ConfigValue val, ConfigType type, string& str)
{
switch (type)
{
case Config::TYPE_INTEGER:
case TYPE_INTEGER:
str.printf("%" SQUADFORMAT, val.intVal);
break;
case Config::TYPE_STRING:
case TYPE_STRING:
{
if (val.strVal == NULL)
return false;
@ -619,7 +534,7 @@ bool Config::valueAsString(ConfigValue val, ConfigType type, string& str)
}
break;
case Config::TYPE_BOOLEAN:
case TYPE_BOOLEAN:
str = val.boolVal ? "true" : "false";
break;
}
@ -627,12 +542,41 @@ bool Config::valueAsString(ConfigValue val, ConfigType type, string& str)
return true;
}
const char* Config::getKeyName(unsigned int key)
{
if (key >= MAX_CONFIG_KEY)
return nullptr;
return entries[key].key;
}
ConfigValue Config::specialProcessing(ConfigKey key, ConfigValue val)
{
// irregular case
switch (key)
{
case KEY_SECURITY_DATABASE:
if (!val.strVal)
{
val.strVal = MasterInterfacePtr()->getConfigManager()->getDefaultSecurityDb();
if (!val.strVal)
val.strVal = "security.db";
}
break;
}
return val;
}
bool Config::getValue(unsigned int key, string& str) const
{
if (key >= MAX_CONFIG_KEY)
return false;
return valueAsString(specialProcessing(static_cast<ConfigKey>(key), values[key]), entries[key].data_type, str);
const ConfigValue& val = entries[key].is_global ?
getDefaultConfig()->values[key] : values[key];
return valueAsString(specialProcessing(static_cast<ConfigKey>(key), val), entries[key].data_type, str);
}
bool Config::getDefaultValue(unsigned int key, string& str)
@ -640,275 +584,119 @@ bool Config::getDefaultValue(unsigned int key, string& str)
if (key >= MAX_CONFIG_KEY)
return false;
if (key == KEY_WIRE_CRYPT && !entries[key].default_value.strVal)
if (key == KEY_WIRE_CRYPT && !defaults[key].strVal)
{
str = "Required"; // see getWireCrypt(WC_SERVER)
return true;
}
return valueAsString(specialProcessing(static_cast<ConfigKey>(key), entries[key].default_value), entries[key].data_type, str);
return valueAsString(specialProcessing(static_cast<ConfigKey>(key), defaults[key]), entries[key].data_type, str);
}
int Config::getTempBlockSize()
{
return (int) getDefaultConfig()->getInt(KEY_TEMP_BLOCK_SIZE);
}
FB_UINT64 Config::getTempCacheLimit() const
{
return getInt(KEY_TEMP_CACHE_LIMIT);
}
// Macros below helps to implement non-trivial Config::getXXX functions :
// - checks for correct[non-]static function declaration,
// - declare and initialize local vars "key" and "config" (correct Config
// instance to get values from).
bool Config::getRemoteFileOpenAbility()
{
return getDefaultConfig()->getBool(KEY_REMOTE_FILE_OPEN_ABILITY);
}
#define DECLARE_GLOBAL_KEY(KEY) \
static_assert(entries[KEY].is_global, "Requires global key"); \
const ConfigKey key = KEY; \
const Config* config = getDefaultConfig();
int Config::getGuardianOption()
{
return getDefaultConfig()->getInt(KEY_GUARDIAN_OPTION);
}
FB_UINT64 Config::getCpuAffinityMask()
{
return getDefaultConfig()->getInt(KEY_CPU_AFFINITY_MASK);
}
int Config::getTcpRemoteBufferSize()
{
return getDefaultConfig()->getInt(KEY_TCP_REMOTE_BUFFER_SIZE);
}
bool Config::getTcpNoNagle() const
{
return getBool(KEY_TCP_NO_NAGLE);
}
bool Config::getTcpLoopbackFastPath() const
{
return getBool(KEY_TCP_LOOPBACK_FAST_PATH);
}
bool Config::getIPv6V6Only() const
{
return getBool(KEY_IPV6_V6ONLY);
}
int Config::getDefaultDbCachePages() const
{
return getInt(KEY_DEFAULT_DB_CACHE_PAGES);
}
int Config::getConnectionTimeout() const
{
return getInt(KEY_CONNECTION_TIMEOUT);
}
int Config::getDummyPacketInterval() const
{
return getInt(KEY_DUMMY_PACKET_INTERVAL);
}
const char* Config::getDefaultTimeZone()
{
return getDefaultConfig()->getStr(KEY_DEFAULT_TIME_ZONE);
}
int Config::getLockMemSize() const
{
return getInt(KEY_LOCK_MEM_SIZE);
}
int Config::getLockHashSlots() const
{
return getInt(KEY_LOCK_HASH_SLOTS);
}
int Config::getLockAcquireSpins() const
{
return getInt(KEY_LOCK_ACQUIRE_SPINS);
}
int Config::getEventMemSize() const
{
return getInt(KEY_EVENT_MEM_SIZE);
}
int Config::getDeadlockTimeout() const
{
return getInt(KEY_DEADLOCK_TIMEOUT);
}
const char *Config::getRemoteServiceName() const
{
return getStr(KEY_REMOTE_SERVICE_NAME);
}
unsigned short Config::getRemoteServicePort() const
{
return getInt(KEY_REMOTE_SERVICE_PORT);
}
const char *Config::getRemotePipeName() const
{
return getStr(KEY_REMOTE_PIPE_NAME);
}
const char *Config::getIpcName() const
{
return getStr(KEY_IPC_NAME);
}
int Config::getMaxUnflushedWrites() const
{
return getInt(KEY_MAX_UNFLUSHED_WRITES);
}
int Config::getMaxUnflushedWriteTime() const
{
return getInt(KEY_MAX_UNFLUSHED_WRITE_TIME);
}
int Config::getProcessPriorityLevel()
{
return getDefaultConfig()->getInt(KEY_PROCESS_PRIORITY_LEVEL);
}
int Config::getRemoteAuxPort() const
{
return getInt(KEY_REMOTE_AUX_PORT);
}
const char *Config::getRemoteBindAddress()
{
return getDefaultConfig()->getStr(KEY_REMOTE_BIND_ADDRESS);
}
const char *Config::getExternalFileAccess() const
{
return getStr(KEY_EXTERNAL_FILE_ACCESS);
}
const char *Config::getDatabaseAccess()
{
return getDefaultConfig()->getStr(KEY_DATABASE_ACCESS);
}
const char *Config::getUdfAccess()
{
return getDefaultConfig()->getStr(KEY_UDF_ACCESS);
}
const char *Config::getTempDirectories()
{
return getDefaultConfig()->getStr(KEY_TEMP_DIRECTORIES);
}
bool Config::getBugcheckAbort()
{
return getDefaultConfig()->getBool(KEY_BUGCHECK_ABORT);
}
int Config::getTraceDSQL()
{
return getDefaultConfig()->getInt(KEY_TRACE_DSQL);
}
bool Config::getLegacyHash()
{
return getDefaultConfig()->getBool(KEY_LEGACY_HASH);
}
const char *Config::getGCPolicy() const
{
return getStr(KEY_GC_POLICY);
}
bool Config::getRedirection()
{
return getDefaultConfig()->getBool(KEY_REDIRECTION);
}
int Config::getDatabaseGrowthIncrement() const
{
return getInt(KEY_DATABASE_GROWTH_INCREMENT);
}
int Config::getFileSystemCacheThreshold() const
{
return getInt(KEY_FILESYSTEM_CACHE_THRESHOLD);
}
bool Config::getRelaxedAliasChecking()
{
return getDefaultConfig()->getBool(KEY_RELAXED_ALIAS_CHECKING);
}
FB_UINT64 Config::getFileSystemCacheSize()
{
return (FB_UINT64) getDefaultConfig()->getInt(KEY_FILESYSTEM_CACHE_SIZE);
}
const char *Config::getAuditTraceConfigFile()
{
return getDefaultConfig()->getStr(KEY_TRACE_CONFIG);
}
FB_UINT64 Config::getMaxUserTraceLogSize()
{
return (FB_UINT64) getDefaultConfig()->getInt(KEY_MAX_TRACELOG_SIZE);
}
int Config::getServerMode()
{
return getDefaultConfig()->serverMode;
}
ULONG Config::getSnapshotsMemSize() const
{
return getInt(KEY_SNAPSHOTS_MEM_SIZE);
}
ULONG Config::getTipCacheBlockSize() const
{
return getInt(KEY_TIP_CACHE_BLOCK_SIZE);
}
#define DECLARE_PER_DB_KEY(KEY) \
static_assert(!entries[KEY].is_global, "Requires per-database key"); \
const ConfigKey key = KEY; \
const Config* config = this;
const char* Config::getPlugins(unsigned int type) const
{
ConfigKey key;
ConfigKey _key;
switch (type)
{
case IPluginManager::TYPE_PROVIDER:
key = KEY_PLUG_PROVIDERS;
{
DECLARE_PER_DB_KEY(KEY_PLUG_PROVIDERS);
_key = key;
break;
}
case IPluginManager::TYPE_AUTH_SERVER:
key = KEY_PLUG_AUTH_SERVER;
{
DECLARE_PER_DB_KEY(KEY_PLUG_AUTH_SERVER);
_key = key;
break;
}
case IPluginManager::TYPE_AUTH_CLIENT:
key = KEY_PLUG_AUTH_CLIENT;
{
DECLARE_PER_DB_KEY(KEY_PLUG_AUTH_CLIENT);
_key = key;
break;
}
case IPluginManager::TYPE_AUTH_USER_MANAGEMENT:
key = KEY_PLUG_AUTH_MANAGE;
{
DECLARE_PER_DB_KEY(KEY_PLUG_AUTH_MANAGE);
_key = key;
break;
}
case IPluginManager::TYPE_TRACE:
key = KEY_PLUG_TRACE;
{
DECLARE_PER_DB_KEY(KEY_PLUG_TRACE);
_key = key;
break;
}
case IPluginManager::TYPE_WIRE_CRYPT:
key = KEY_PLUG_WIRE_CRYPT;
{
DECLARE_PER_DB_KEY(KEY_PLUG_WIRE_CRYPT);
_key = key;
break;
}
case IPluginManager::TYPE_KEY_HOLDER:
key = KEY_PLUG_KEY_HOLDER;
{
DECLARE_PER_DB_KEY(KEY_PLUG_KEY_HOLDER);
_key = key;
break;
}
default:
(Arg::Gds(isc_random) << "Internal error in Config::getPlugins(): unknown plugin type requested").raise();
}
return getStr(key);
return getStr(_key);
}
int Config::getWireCrypt(WireCryptMode wcMode) const
{
DECLARE_PER_DB_KEY(KEY_WIRE_CRYPT);
bool present;
const char* wc = getStr(key, &present);
if (present && wc)
{
NoCaseString wireCrypt(wc);
if (wireCrypt == "DISABLED")
return WIRE_CRYPT_DISABLED;
if (wireCrypt == "ENABLED")
return WIRE_CRYPT_ENABLED;
if (wireCrypt == "REQUIRED")
return WIRE_CRYPT_REQUIRED;
// wrong user value, fail to default
// should not happens, see checkValues()
fb_assert(false);
}
return wcMode == WC_CLIENT ? WIRE_CRYPT_ENABLED : WIRE_CRYPT_REQUIRED;
}
bool Config::getUseFileSystemCache(bool* pPresent) const
{
DECLARE_PER_DB_KEY(KEY_USE_FILESYSTEM_CACHE);
return getBool(key, pPresent);
}
/// class FirebirdConf
// array format: major, minor, release, build
static unsigned short fileVerNumber[4] = {FILE_VER_NUMBER};
@ -964,124 +752,4 @@ FB_BOOLEAN FirebirdConf::asBoolean(unsigned int key)
return config->getBoolean(key);
}
const char* Config::getSecurityDatabase() const
{
return getStr(KEY_SECURITY_DATABASE);
}
Config::ConfigValue Config::specialProcessing(ConfigKey key, ConfigValue val)
{
// irregular case
switch(key)
{
case KEY_SECURITY_DATABASE:
if (!val.strVal)
{
val.strVal = MasterInterfacePtr()->getConfigManager()->getDefaultSecurityDb();
if (!val.strVal)
val.strVal = "security.db";
}
break;
}
return val;
}
int Config::getWireCrypt(WireCryptMode wcMode) const
{
bool present;
const char* wc = getStr(KEY_WIRE_CRYPT, &present);
if (present && wc)
{
NoCaseString wireCrypt(wc);
if (wireCrypt == "DISABLED")
return WIRE_CRYPT_DISABLED;
if (wireCrypt == "ENABLED")
return WIRE_CRYPT_ENABLED;
if (wireCrypt == "REQUIRED")
return WIRE_CRYPT_REQUIRED;
// wrong user value, fail to default
// should not happens, see checkValues()
fb_assert(false);
}
return wcMode == WC_CLIENT ? WIRE_CRYPT_ENABLED : WIRE_CRYPT_REQUIRED;
}
bool Config::getRemoteAccess() const
{
return getBool(KEY_REMOTE_ACCESS);
}
bool Config::getWireCompression() const
{
return getBool(KEY_WIRE_COMPRESSION);
}
int Config::getMaxIdentifierByteLength() const
{
return getInt(KEY_MAX_IDENTIFIER_BYTE_LENGTH);
}
int Config::getMaxIdentifierCharLength() const
{
return getInt(KEY_MAX_IDENTIFIER_CHAR_LENGTH);
}
bool Config::getCryptSecurityDatabase() const
{
return getBool(KEY_ENCRYPT_SECURITY_DATABASE);
}
unsigned int Config::getStatementTimeout() const
{
return getInt(KEY_STMT_TIMEOUT);
}
unsigned int Config::getConnIdleTimeout() const
{
return getInt(KEY_CONN_IDLE_TIMEOUT);
}
unsigned int Config::getClientBatchBuffer() const
{
return getInt(KEY_CLIENT_BATCH_BUFFER);
}
const char* Config::getOutputRedirectionFile()
{
return getDefaultConfig()->getStr(KEY_OUTPUT_REDIRECTION_FILE);
}
int Config::getExtConnPoolSize()
{
return getDefaultConfig()->getInt(KEY_EXT_CONN_POOL_SIZE);
}
int Config::getExtConnPoolLifeTime()
{
return getDefaultConfig()->getInt(KEY_EXT_CONN_POOL_LIFETIME);
}
bool Config::getReadConsistency() const
{
return getBool(KEY_READ_CONSISTENCY);
}
bool Config::getClearGTTAtRetaining() const
{
return getBool(KEY_CLEAR_GTT_RETAINING);
}
const char* Config::getDataTypeCompatibility() const
{
return getStr(KEY_DATA_TYPE_COMPATIBILITY);
}
bool Config::getUseFileSystemCache(bool* pPresent) const
{
return getBool(KEY_USE_FILESYSTEM_CACHE, pPresent);
}
} // namespace Firebird

View File

@ -28,6 +28,7 @@
#include "../common/classes/RefCounted.h"
#include "../common/config/config_file.h"
#include "../common/classes/ImplementHelper.h"
#include "../jrd/constants.h"
/**
Since the original (isc.cpp) code wasn't able to provide powerful and
@ -52,17 +53,20 @@
To add new configuration item, you have to take the following steps:
1. Add key description to Config::entries[] array (config.cpp)
2. Add logical key to Config::ConfigKey enumeration (config.h)
1. Add logical key to ConfigKey enumeration (config.h)
2. Add key description to entries[] array (config.h)
(note: both physical and logical keys MUST have the same ordinal
position within appropriate structures)
3. Add member function to Config class (config.h) and implement it
in config.cpp module.
in config.h or config.cpp module.
4. For per-database configurable parameters, please use
type getParameterName() const;
form, for world-wide parameters:
form, for world-wide (global) parameters
static type getParameterName();
should be used.
should be used. Also, for world-wide parameters, values of default
config instance (see getDefaultConfig()) should be used.
5. Macros CONFIG_GET_GLOBAL_XXX and CONFIG_GET_PER_DB_XXX helps to
declare and implement trivial getXXX functions and to enforce rule (4).
**/
namespace Firebird
@ -84,131 +88,225 @@ const int MODE_CLASSIC = 2;
const char* const CONFIG_FILE = "firebird.conf";
struct ConfigValue
{
ConfigValue() : intVal(0) {};
constexpr ConfigValue(const char* val) : strVal(val) {};
constexpr ConfigValue(bool val) : boolVal(val) {};
constexpr ConfigValue(int val) : intVal(val) {};
union
{
const char* strVal;
bool boolVal;
SINT64 intVal;
};
// simple bitwise comparison
bool operator== (const ConfigValue& other) const
{
return this->intVal == other.intVal;
}
bool operator!= (const ConfigValue& other) const
{
return !(*this == other);
}
};
enum ConfigKey
{
KEY_TEMP_BLOCK_SIZE,
KEY_TEMP_CACHE_LIMIT,
KEY_REMOTE_FILE_OPEN_ABILITY,
KEY_GUARDIAN_OPTION,
KEY_CPU_AFFINITY_MASK,
KEY_TCP_REMOTE_BUFFER_SIZE,
KEY_TCP_NO_NAGLE,
KEY_TCP_LOOPBACK_FAST_PATH,
KEY_DEFAULT_DB_CACHE_PAGES,
KEY_CONNECTION_TIMEOUT,
KEY_DUMMY_PACKET_INTERVAL,
KEY_DEFAULT_TIME_ZONE,
KEY_LOCK_MEM_SIZE,
KEY_LOCK_HASH_SLOTS,
KEY_LOCK_ACQUIRE_SPINS,
KEY_EVENT_MEM_SIZE,
KEY_DEADLOCK_TIMEOUT,
KEY_REMOTE_SERVICE_NAME,
KEY_REMOTE_SERVICE_PORT,
KEY_REMOTE_PIPE_NAME,
KEY_IPC_NAME,
KEY_MAX_UNFLUSHED_WRITES,
KEY_MAX_UNFLUSHED_WRITE_TIME,
KEY_PROCESS_PRIORITY_LEVEL,
KEY_REMOTE_AUX_PORT,
KEY_REMOTE_BIND_ADDRESS,
KEY_EXTERNAL_FILE_ACCESS,
KEY_DATABASE_ACCESS,
KEY_UDF_ACCESS,
KEY_TEMP_DIRECTORIES,
KEY_BUGCHECK_ABORT,
KEY_TRACE_DSQL,
KEY_LEGACY_HASH,
KEY_GC_POLICY,
KEY_REDIRECTION,
KEY_DATABASE_GROWTH_INCREMENT,
KEY_FILESYSTEM_CACHE_THRESHOLD,
KEY_RELAXED_ALIAS_CHECKING,
KEY_TRACE_CONFIG,
KEY_MAX_TRACELOG_SIZE,
KEY_FILESYSTEM_CACHE_SIZE,
KEY_PLUG_PROVIDERS,
KEY_PLUG_AUTH_SERVER,
KEY_PLUG_AUTH_CLIENT,
KEY_PLUG_AUTH_MANAGE,
KEY_PLUG_TRACE,
KEY_SECURITY_DATABASE,
KEY_SERVER_MODE,
KEY_WIRE_CRYPT,
KEY_PLUG_WIRE_CRYPT,
KEY_PLUG_KEY_HOLDER,
KEY_REMOTE_ACCESS,
KEY_IPV6_V6ONLY,
KEY_WIRE_COMPRESSION,
KEY_MAX_IDENTIFIER_BYTE_LENGTH,
KEY_MAX_IDENTIFIER_CHAR_LENGTH,
KEY_ENCRYPT_SECURITY_DATABASE,
KEY_STMT_TIMEOUT,
KEY_CONN_IDLE_TIMEOUT,
KEY_CLIENT_BATCH_BUFFER,
KEY_OUTPUT_REDIRECTION_FILE,
KEY_EXT_CONN_POOL_SIZE,
KEY_EXT_CONN_POOL_LIFETIME,
KEY_SNAPSHOTS_MEM_SIZE,
KEY_TIP_CACHE_BLOCK_SIZE,
KEY_READ_CONSISTENCY,
KEY_CLEAR_GTT_RETAINING,
KEY_DATA_TYPE_COMPATIBILITY,
KEY_USE_FILESYSTEM_CACHE,
MAX_CONFIG_KEY // keep it last
};
enum ConfigType
{
TYPE_BOOLEAN,
TYPE_INTEGER,
TYPE_STRING
//TYPE_STRING_VECTOR // CVC: Unused
};
typedef const char* ConfigName;
struct ConfigEntry
{
ConfigType data_type;
ConfigName key;
bool is_global;
ConfigValue default_value;
};
constexpr ConfigEntry entries[MAX_CONFIG_KEY] =
{
{TYPE_INTEGER, "TempBlockSize", true, 1048576}, // bytes
{TYPE_INTEGER, "TempCacheLimit", false, -1}, // bytes
{TYPE_BOOLEAN, "RemoteFileOpenAbility", true, false},
{TYPE_INTEGER, "GuardianOption", true, true},
{TYPE_INTEGER, "CpuAffinityMask", true, 0},
{TYPE_INTEGER, "TcpRemoteBufferSize", true, 8192}, // bytes
{TYPE_BOOLEAN, "TcpNoNagle", false, true},
{TYPE_BOOLEAN, "TcpLoopbackFastPath", false, true},
{TYPE_INTEGER, "DefaultDbCachePages", false, -1}, // pages
{TYPE_INTEGER, "ConnectionTimeout", false, 180}, // seconds
{TYPE_INTEGER, "DummyPacketInterval", false, 0}, // seconds
{TYPE_STRING, "DefaultTimeZone", true, nullptr},
{TYPE_INTEGER, "LockMemSize", false, 1048576}, // bytes
{TYPE_INTEGER, "LockHashSlots", false, 8191}, // slots
{TYPE_INTEGER, "LockAcquireSpins", false, 0},
{TYPE_INTEGER, "EventMemSize", false, 65536}, // bytes
{TYPE_INTEGER, "DeadlockTimeout", false, 10}, // seconds
{TYPE_STRING, "RemoteServiceName", false, FB_SERVICE_NAME},
{TYPE_INTEGER, "RemoteServicePort", false, 0},
{TYPE_STRING, "RemotePipeName", false, FB_PIPE_NAME},
{TYPE_STRING, "IpcName", false, FB_IPC_NAME},
#ifdef WIN_NT
{TYPE_INTEGER, "MaxUnflushedWrites", false, 100},
{TYPE_INTEGER, "MaxUnflushedWriteTime", false, 5},
#else
{TYPE_INTEGER, "MaxUnflushedWrites", false, -1},
{TYPE_INTEGER, "MaxUnflushedWriteTime", false, -1},
#endif
{TYPE_INTEGER, "ProcessPriorityLevel", true, 0},
{TYPE_INTEGER, "RemoteAuxPort", false, 0},
{TYPE_STRING, "RemoteBindAddress", true, 0},
{TYPE_STRING, "ExternalFileAccess", false, "None"}, // locations of external files for tables
{TYPE_STRING, "DatabaseAccess", true, "Full"}, // locations of databases
{TYPE_STRING, "UdfAccess", true, "None"}, // locations of UDFs
{TYPE_STRING, "TempDirectories", true, 0},
#ifdef DEV_BUILD
{TYPE_BOOLEAN, "BugcheckAbort", true, true}, // whether to abort engine when internal error is found
#else
{TYPE_BOOLEAN, "BugcheckAbort", true, false}, // whether to abort engine when internal error is found
#endif
{TYPE_INTEGER, "TraceDSQL", true, 0}, // bitmask
{TYPE_BOOLEAN, "LegacyHash", true, true}, // let use old passwd hash verification
{TYPE_STRING, "GCPolicy", false, nullptr}, // garbage collection policy
{TYPE_BOOLEAN, "Redirection", true, false},
{TYPE_INTEGER, "DatabaseGrowthIncrement", false, 128 * 1048576}, // bytes
{TYPE_INTEGER, "FileSystemCacheThreshold", false, 65536}, // page buffers
{TYPE_BOOLEAN, "RelaxedAliasChecking", true, false}, // if true relax strict alias checking rules in DSQL a bit
{TYPE_STRING, "AuditTraceConfigFile", true, ""}, // location of audit trace configuration file
{TYPE_INTEGER, "MaxUserTraceLogSize", true, 10}, // maximum size of user session trace log
{TYPE_INTEGER, "FileSystemCacheSize", true, 0}, // percent
{TYPE_STRING, "Providers", false, "Remote, " CURRENT_ENGINE ", Loopback"},
{TYPE_STRING, "AuthServer", false, "Srp256"},
#ifdef WIN_NT
{TYPE_STRING, "AuthClient", false, "Srp256"},
#else
{TYPE_STRING, "AuthClient", false, "Srp256, Srp, Win_Sspi, Legacy_Auth"},
#endif
{TYPE_STRING, "UserManager", false, "Srp"},
{TYPE_STRING, "TracePlugin", false, "fbtrace"},
{TYPE_STRING, "SecurityDatabase", false, nullptr}, // sec/db alias - rely on ConfigManager::getDefaultSecurityDb(
{TYPE_STRING, "ServerMode", true, nullptr}, // actual value differs in boot/regular cases and set at setupDefaultConfig(
{TYPE_STRING, "WireCrypt", false, nullptr},
{TYPE_STRING, "WireCryptPlugin", false, "ChaCha, Arc4"},
{TYPE_STRING, "KeyHolderPlugin", false, ""},
{TYPE_BOOLEAN, "RemoteAccess", false, true},
{TYPE_BOOLEAN, "IPv6V6Only", false, false},
{TYPE_BOOLEAN, "WireCompression", false, false},
{TYPE_INTEGER, "MaxIdentifierByteLength", false, (int)MAX_SQL_IDENTIFIER_LEN},
{TYPE_INTEGER, "MaxIdentifierCharLength", false, (int)METADATA_IDENTIFIER_CHAR_LEN},
{TYPE_BOOLEAN, "AllowEncryptedSecurityDatabase", false, false},
{TYPE_INTEGER, "StatementTimeout", false, 0},
{TYPE_INTEGER, "ConnectionIdleTimeout", false, 0},
{TYPE_INTEGER, "ClientBatchBuffer", false, 128 * 1024},
#ifdef DEV_BUILD
{TYPE_STRING, "OutputRedirectionFile", true, "-"},
#else
#ifdef WIN_NT
{TYPE_STRING, "OutputRedirectionFile", true, "nul"},
#else
{TYPE_STRING, "OutputRedirectionFile", true, "/dev/null"},
#endif
#endif
{TYPE_INTEGER, "ExtConnPoolSize", true, 0},
{TYPE_INTEGER, "ExtConnPoolLifeTime", true, 7200},
{TYPE_INTEGER, "SnapshotsMemSize", false, 65536}, // bytes,
{TYPE_INTEGER, "TipCacheBlockSize", false, 4194304}, // bytes,
{TYPE_BOOLEAN, "ReadConsistency", false, true},
{TYPE_BOOLEAN, "ClearGTTAtRetaining", false, false},
{TYPE_STRING, "DataTypeCompatibility", false, nullptr},
{TYPE_BOOLEAN, "UseFileSystemCache", false, true}
};
class Config : public RefCounted, public GlobalStorage
{
public:
//typedef IPTR ConfigValue;
struct ConfigValue
{
ConfigValue() : intVal(0) {};
explicit ConfigValue(const char* val) : strVal(val) {};
explicit ConfigValue(bool val) : boolVal(val) {};
explicit ConfigValue(SINT64 val) : intVal(val) {};
explicit ConfigValue(unsigned val) : intVal(val) {};
explicit ConfigValue(int val) : intVal(val) {};
union
{
const char* strVal;
bool boolVal;
SINT64 intVal;
};
// simple bitwise comparison
bool operator== (const ConfigValue& other) const
{
return this->intVal == other.intVal;
}
bool operator!= (const ConfigValue& other) const
{
return !(*this == other);
}
};
enum ConfigKey
{
KEY_TEMP_BLOCK_SIZE,
KEY_TEMP_CACHE_LIMIT,
KEY_REMOTE_FILE_OPEN_ABILITY,
KEY_GUARDIAN_OPTION,
KEY_CPU_AFFINITY_MASK,
KEY_TCP_REMOTE_BUFFER_SIZE,
KEY_TCP_NO_NAGLE,
KEY_TCP_LOOPBACK_FAST_PATH,
KEY_DEFAULT_DB_CACHE_PAGES,
KEY_CONNECTION_TIMEOUT,
KEY_DUMMY_PACKET_INTERVAL,
KEY_DEFAULT_TIME_ZONE,
KEY_LOCK_MEM_SIZE,
KEY_LOCK_HASH_SLOTS,
KEY_LOCK_ACQUIRE_SPINS,
KEY_EVENT_MEM_SIZE,
KEY_DEADLOCK_TIMEOUT,
KEY_REMOTE_SERVICE_NAME,
KEY_REMOTE_SERVICE_PORT,
KEY_REMOTE_PIPE_NAME,
KEY_IPC_NAME,
KEY_MAX_UNFLUSHED_WRITES,
KEY_MAX_UNFLUSHED_WRITE_TIME,
KEY_PROCESS_PRIORITY_LEVEL,
KEY_REMOTE_AUX_PORT,
KEY_REMOTE_BIND_ADDRESS,
KEY_EXTERNAL_FILE_ACCESS,
KEY_DATABASE_ACCESS,
KEY_UDF_ACCESS,
KEY_TEMP_DIRECTORIES,
KEY_BUGCHECK_ABORT,
KEY_TRACE_DSQL,
KEY_LEGACY_HASH,
KEY_GC_POLICY,
KEY_REDIRECTION,
KEY_DATABASE_GROWTH_INCREMENT,
KEY_FILESYSTEM_CACHE_THRESHOLD,
KEY_RELAXED_ALIAS_CHECKING,
KEY_TRACE_CONFIG,
KEY_MAX_TRACELOG_SIZE,
KEY_FILESYSTEM_CACHE_SIZE,
KEY_PLUG_PROVIDERS,
KEY_PLUG_AUTH_SERVER,
KEY_PLUG_AUTH_CLIENT,
KEY_PLUG_AUTH_MANAGE,
KEY_PLUG_TRACE,
KEY_SECURITY_DATABASE,
KEY_SERVER_MODE,
KEY_WIRE_CRYPT,
KEY_PLUG_WIRE_CRYPT,
KEY_PLUG_KEY_HOLDER,
KEY_REMOTE_ACCESS,
KEY_IPV6_V6ONLY,
KEY_WIRE_COMPRESSION,
KEY_MAX_IDENTIFIER_BYTE_LENGTH,
KEY_MAX_IDENTIFIER_CHAR_LENGTH,
KEY_ENCRYPT_SECURITY_DATABASE,
KEY_STMT_TIMEOUT,
KEY_CONN_IDLE_TIMEOUT,
KEY_CLIENT_BATCH_BUFFER,
KEY_OUTPUT_REDIRECTION_FILE,
KEY_EXT_CONN_POOL_SIZE,
KEY_EXT_CONN_POOL_LIFETIME,
KEY_SNAPSHOTS_MEM_SIZE,
KEY_TIP_CACHE_BLOCK_SIZE,
KEY_READ_CONSISTENCY,
KEY_CLEAR_GTT_RETAINING,
KEY_DATA_TYPE_COMPATIBILITY,
KEY_USE_FILESYSTEM_CACHE,
MAX_CONFIG_KEY // keep it last
};
private:
enum ConfigType
{
TYPE_BOOLEAN,
TYPE_INTEGER,
TYPE_STRING
//TYPE_STRING_VECTOR // CVC: Unused
};
typedef const char* ConfigName;
struct ConfigEntry
{
ConfigType data_type;
ConfigName key;
ConfigValue default_value;
};
static ConfigValue specialProcessing(ConfigKey key, ConfigValue val);
void loadValues(const ConfigFile& file, const char* srcName);
@ -245,8 +343,7 @@ private:
static bool valueAsString(ConfigValue val, ConfigType type, string& str);
static ConfigEntry entries[MAX_CONFIG_KEY];
static ConfigValue defaults[MAX_CONFIG_KEY];
ConfigValue values[MAX_CONFIG_KEY];
// Array of value source names, NULL item is for default value
@ -265,6 +362,7 @@ private:
// set in default config only
int serverMode;
bool defaultConfig;
public:
explicit Config(const ConfigFile& file); // use to build default config
@ -306,13 +404,7 @@ public:
return MAX_CONFIG_KEY;
}
static const char* getKeyName(unsigned int key)
{
if (key >= MAX_CONFIG_KEY)
return nullptr;
return entries[key].key;
}
static const char* getKeyName(unsigned int key);
// false if value is null or key is not exists
bool getValue(unsigned int key, string& str) const;
@ -334,165 +426,197 @@ public:
// Root directory of current installation
static const char* getRootDirectory();
// CONFIG_GET_GLOBAL_XXX (CONFIG_GET_PER_DB_XXX) set of macros helps to
// create trivial static (non-static) getXXX functions.
// Correctness of declaration and implementation is enforced with help
// of entries[XXX].is_global.
#define CONFIG_GET_GLOBAL_KEY(T, FN, KEY, SUBFN) \
static T FN() \
{ \
static_assert(entries[KEY].is_global, "Requires global key"); \
static_assert(!std::is_member_function_pointer<decltype(&Config::FN)>::value, "Must be a static function"); \
return (T) getDefaultConfig()->SUBFN(KEY); \
}
#define CONFIG_GET_PER_DB_KEY(T, FN, KEY, SUBFN) \
T FN() const \
{ \
static_assert(!entries[KEY].is_global, "Requires per-database key"); \
static_assert(std::is_member_function_pointer<decltype(&Config::FN)>::value, "Must be a non-static function"); \
return (T) this->SUBFN(KEY); \
}
#define CONFIG_GET_GLOBAL_INT(FN, KEY) CONFIG_GET_GLOBAL_KEY(int, FN, KEY, getInt)
#define CONFIG_GET_GLOBAL_STR(FN, KEY) CONFIG_GET_GLOBAL_KEY(const char*, FN, KEY, getStr)
#define CONFIG_GET_GLOBAL_BOOL(FN, KEY) CONFIG_GET_GLOBAL_KEY(bool, FN, KEY, getBool)
#define CONFIG_GET_PER_DB_INT(FN, KEY) CONFIG_GET_PER_DB_KEY(int, FN, KEY, getInt)
#define CONFIG_GET_PER_DB_STR(FN, KEY) CONFIG_GET_PER_DB_KEY(const char*, FN, KEY, getStr)
#define CONFIG_GET_PER_DB_BOOL(FN, KEY) CONFIG_GET_PER_DB_KEY(bool, FN, KEY, getBool)
// Allocation chunk for the temporary spaces
static int getTempBlockSize();
CONFIG_GET_GLOBAL_INT(getTempBlockSize, KEY_TEMP_BLOCK_SIZE);
// Caching limit for the temporary data
FB_UINT64 getTempCacheLimit() const;
CONFIG_GET_PER_DB_KEY(FB_UINT64, getTempCacheLimit, KEY_TEMP_CACHE_LIMIT, getInt);
// Whether remote (NFS) files can be opened
static bool getRemoteFileOpenAbility();
CONFIG_GET_GLOBAL_BOOL(getRemoteFileOpenAbility, KEY_REMOTE_FILE_OPEN_ABILITY);
// Startup option for the guardian
static int getGuardianOption();
CONFIG_GET_GLOBAL_INT(getGuardianOption, KEY_GUARDIAN_OPTION);
// CPU affinity mask
static FB_UINT64 getCpuAffinityMask();
CONFIG_GET_GLOBAL_KEY(FB_UINT64, getCpuAffinityMask, KEY_CPU_AFFINITY_MASK, getInt);
// XDR buffer size
static int getTcpRemoteBufferSize();
CONFIG_GET_GLOBAL_INT(getTcpRemoteBufferSize, KEY_TCP_REMOTE_BUFFER_SIZE);
// Disable Nagle algorithm
bool getTcpNoNagle() const;
CONFIG_GET_PER_DB_BOOL(getTcpNoNagle, KEY_TCP_NO_NAGLE);
// Enable or disable the TCP Loopback Fast Path option
bool getTcpLoopbackFastPath() const;
CONFIG_GET_PER_DB_BOOL(getTcpLoopbackFastPath, KEY_TCP_LOOPBACK_FAST_PATH);
// Let IPv6 socket accept only IPv6 packets
bool getIPv6V6Only() const;
CONFIG_GET_PER_DB_BOOL(getIPv6V6Only, KEY_IPV6_V6ONLY);
// Default database cache size
int getDefaultDbCachePages() const;
CONFIG_GET_PER_DB_INT(getDefaultDbCachePages, KEY_DEFAULT_DB_CACHE_PAGES);
// Connection timeout
int getConnectionTimeout() const;
CONFIG_GET_PER_DB_INT(getConnectionTimeout, KEY_CONNECTION_TIMEOUT);
// Dummy packet interval
int getDummyPacketInterval() const;
CONFIG_GET_PER_DB_INT(getDummyPacketInterval, KEY_DUMMY_PACKET_INTERVAL);
static const char* getDefaultTimeZone();
CONFIG_GET_GLOBAL_STR(getDefaultTimeZone, KEY_DEFAULT_TIME_ZONE);
// Lock manager memory size
int getLockMemSize() const;
CONFIG_GET_PER_DB_INT(getLockMemSize, KEY_LOCK_MEM_SIZE);
// Lock manager hash slots
int getLockHashSlots() const;
CONFIG_GET_PER_DB_INT(getLockHashSlots, KEY_LOCK_HASH_SLOTS);
// Lock manager acquire spins
int getLockAcquireSpins() const;
CONFIG_GET_PER_DB_INT(getLockAcquireSpins, KEY_LOCK_ACQUIRE_SPINS);
// Event manager memory size
int getEventMemSize() const;
CONFIG_GET_PER_DB_INT(getEventMemSize, KEY_EVENT_MEM_SIZE);
// Deadlock timeout
int getDeadlockTimeout() const;
CONFIG_GET_PER_DB_INT(getDeadlockTimeout, KEY_DEADLOCK_TIMEOUT);
// Service name for remote protocols
const char* getRemoteServiceName() const;
CONFIG_GET_PER_DB_STR(getRemoteServiceName, KEY_REMOTE_SERVICE_NAME);
// Service port for INET
unsigned short getRemoteServicePort() const;
CONFIG_GET_PER_DB_KEY(unsigned short, getRemoteServicePort, KEY_REMOTE_SERVICE_PORT, getInt);
// Pipe name for WNET
const char* getRemotePipeName() const;
CONFIG_GET_PER_DB_STR(getRemotePipeName, KEY_REMOTE_PIPE_NAME);
// Name for IPC-related objects
const char* getIpcName() const;
CONFIG_GET_PER_DB_STR(getIpcName, KEY_IPC_NAME);
// Unflushed writes number
int getMaxUnflushedWrites() const;
CONFIG_GET_PER_DB_INT(getMaxUnflushedWrites, KEY_MAX_UNFLUSHED_WRITES);
// Unflushed write time
int getMaxUnflushedWriteTime() const;
CONFIG_GET_PER_DB_INT(getMaxUnflushedWriteTime, KEY_MAX_UNFLUSHED_WRITE_TIME);
// Process priority level
static int getProcessPriorityLevel();
CONFIG_GET_GLOBAL_INT(getProcessPriorityLevel, KEY_PROCESS_PRIORITY_LEVEL);
// Port for event processing
int getRemoteAuxPort() const;
CONFIG_GET_PER_DB_INT(getRemoteAuxPort, KEY_REMOTE_AUX_PORT);
// Server binding NIC address
static const char* getRemoteBindAddress();
CONFIG_GET_GLOBAL_STR(getRemoteBindAddress, KEY_REMOTE_BIND_ADDRESS);
// Directory list for external tables
const char* getExternalFileAccess() const;
CONFIG_GET_PER_DB_STR(getExternalFileAccess, KEY_EXTERNAL_FILE_ACCESS);
// Directory list for databases
static const char* getDatabaseAccess();
CONFIG_GET_GLOBAL_STR(getDatabaseAccess, KEY_DATABASE_ACCESS);
// Directory list for UDF libraries
static const char* getUdfAccess();
CONFIG_GET_GLOBAL_STR(getUdfAccess, KEY_UDF_ACCESS);
// Temporary directories list
static const char* getTempDirectories();
CONFIG_GET_GLOBAL_STR(getTempDirectories, KEY_TEMP_DIRECTORIES);
// DSQL trace bitmask
static int getTraceDSQL();
CONFIG_GET_GLOBAL_INT(getTraceDSQL, KEY_TRACE_DSQL);
// Abort on BUGCHECK and structured exceptions
static bool getBugcheckAbort();
CONFIG_GET_GLOBAL_BOOL(getBugcheckAbort, KEY_BUGCHECK_ABORT);
// Let use of des hash to verify passwords
static bool getLegacyHash();
CONFIG_GET_GLOBAL_BOOL(getLegacyHash, KEY_LEGACY_HASH);
// GC policy
const char* getGCPolicy() const;
CONFIG_GET_PER_DB_STR(getGCPolicy, KEY_GC_POLICY);
// Redirection
static bool getRedirection();
CONFIG_GET_GLOBAL_BOOL(getRedirection, KEY_REDIRECTION);
int getDatabaseGrowthIncrement() const;
CONFIG_GET_PER_DB_INT(getDatabaseGrowthIncrement, KEY_DATABASE_GROWTH_INCREMENT);
int getFileSystemCacheThreshold() const;
CONFIG_GET_PER_DB_INT(getFileSystemCacheThreshold, KEY_FILESYSTEM_CACHE_THRESHOLD);
static FB_UINT64 getFileSystemCacheSize();
CONFIG_GET_GLOBAL_KEY(FB_UINT64, getFileSystemCacheSize, KEY_FILESYSTEM_CACHE_SIZE, getInt);
static bool getRelaxedAliasChecking();
CONFIG_GET_GLOBAL_BOOL(getRelaxedAliasChecking, KEY_RELAXED_ALIAS_CHECKING);
static const char* getAuditTraceConfigFile();
CONFIG_GET_GLOBAL_STR(getAuditTraceConfigFile, KEY_TRACE_CONFIG);
static FB_UINT64 getMaxUserTraceLogSize();
CONFIG_GET_GLOBAL_KEY(FB_UINT64, getMaxUserTraceLogSize, KEY_MAX_TRACELOG_SIZE, getInt);
static int getServerMode();
CONFIG_GET_GLOBAL_INT(getServerMode, KEY_SERVER_MODE);
const char* getPlugins(unsigned int type) const;
const char* getSecurityDatabase() const;
CONFIG_GET_PER_DB_STR(getSecurityDatabase, KEY_SECURITY_DATABASE);
int getWireCrypt(WireCryptMode wcMode) const;
bool getRemoteAccess() const;
CONFIG_GET_PER_DB_BOOL(getRemoteAccess, KEY_REMOTE_ACCESS);
bool getWireCompression() const;
CONFIG_GET_PER_DB_BOOL(getWireCompression, KEY_WIRE_COMPRESSION);
int getMaxIdentifierByteLength() const;
CONFIG_GET_PER_DB_INT(getMaxIdentifierByteLength, KEY_MAX_IDENTIFIER_BYTE_LENGTH);
int getMaxIdentifierCharLength() const;
CONFIG_GET_PER_DB_INT(getMaxIdentifierCharLength, KEY_MAX_IDENTIFIER_CHAR_LENGTH);
bool getCryptSecurityDatabase() const;
CONFIG_GET_PER_DB_BOOL(getCryptSecurityDatabase, KEY_ENCRYPT_SECURITY_DATABASE);
// set in seconds
unsigned int getStatementTimeout() const;
CONFIG_GET_PER_DB_KEY(unsigned int, getStatementTimeout, KEY_STMT_TIMEOUT, getInt);
// set in minutes
unsigned int getConnIdleTimeout() const;
CONFIG_GET_PER_DB_KEY(unsigned int, getConnIdleTimeout, KEY_CONN_IDLE_TIMEOUT, getInt);
unsigned int getClientBatchBuffer() const;
CONFIG_GET_PER_DB_KEY(unsigned int, getClientBatchBuffer, KEY_CLIENT_BATCH_BUFFER, getInt);
static const char* getOutputRedirectionFile();
CONFIG_GET_GLOBAL_STR(getOutputRedirectionFile, KEY_OUTPUT_REDIRECTION_FILE);
static int getExtConnPoolSize();
CONFIG_GET_GLOBAL_INT(getExtConnPoolSize, KEY_EXT_CONN_POOL_SIZE);
static int getExtConnPoolLifeTime();
CONFIG_GET_GLOBAL_INT(getExtConnPoolLifeTime, KEY_EXT_CONN_POOL_LIFETIME);
ULONG getSnapshotsMemSize() const;
CONFIG_GET_PER_DB_KEY(ULONG, getSnapshotsMemSize, KEY_SNAPSHOTS_MEM_SIZE, getInt);
ULONG getTipCacheBlockSize() const;
CONFIG_GET_PER_DB_KEY(ULONG, getTipCacheBlockSize, KEY_TIP_CACHE_BLOCK_SIZE, getInt);
bool getReadConsistency() const;
CONFIG_GET_PER_DB_BOOL(getReadConsistency, KEY_READ_CONSISTENCY);
bool getClearGTTAtRetaining() const;
CONFIG_GET_PER_DB_BOOL(getClearGTTAtRetaining, KEY_CLEAR_GTT_RETAINING);
const char* getDataTypeCompatibility() const;
CONFIG_GET_PER_DB_STR(getDataTypeCompatibility, KEY_DATA_TYPE_COMPATIBILITY);
bool getUseFileSystemCache(bool* pPresent = nullptr) const;
};