mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-22 21:23:04 +01:00
Reworked Config: correct work with 64-bit integer in 32-bit code, refactor config values checks and defaults,
remove some type casts. Introduce new virtual table RDB$CONFIG. Implement CORE-6332 : Get rid of FileSystemCacheThreshold parameter new boolean setting UseFileSystemCache overrides legacy FileSystemCacheThreshold, FileSystemCacheThreshold will be removed in the next major Firebird release.
This commit is contained in:
parent
3089a2d0cb
commit
7e61b9f698
@ -79,6 +79,7 @@
|
|||||||
<ClCompile Include="..\..\..\src\jrd\extds\IscDS.cpp" />
|
<ClCompile Include="..\..\..\src\jrd\extds\IscDS.cpp" />
|
||||||
<ClCompile Include="..\..\..\src\jrd\extds\ValidatePassword.cpp" />
|
<ClCompile Include="..\..\..\src\jrd\extds\ValidatePassword.cpp" />
|
||||||
<ClCompile Include="..\..\..\src\jrd\ExtEngineManager.cpp" />
|
<ClCompile Include="..\..\..\src\jrd\ExtEngineManager.cpp" />
|
||||||
|
<ClCompile Include="..\..\..\src\jrd\FBConfigTable.cpp" />
|
||||||
<ClCompile Include="..\..\..\src\jrd\filters.cpp" />
|
<ClCompile Include="..\..\..\src\jrd\filters.cpp" />
|
||||||
<ClCompile Include="..\..\..\src\jrd\flu.cpp" />
|
<ClCompile Include="..\..\..\src\jrd\flu.cpp" />
|
||||||
<ClCompile Include="..\..\..\src\jrd\GarbageCollector.cpp" />
|
<ClCompile Include="..\..\..\src\jrd\GarbageCollector.cpp" />
|
||||||
@ -248,6 +249,7 @@
|
|||||||
<ClInclude Include="..\..\..\src\jrd\extds\ValidatePassword.h" />
|
<ClInclude Include="..\..\..\src\jrd\extds\ValidatePassword.h" />
|
||||||
<ClInclude Include="..\..\..\src\jrd\ExtEngineManager.h" />
|
<ClInclude Include="..\..\..\src\jrd\ExtEngineManager.h" />
|
||||||
<ClInclude Include="..\..\..\src\jrd\ext_proto.h" />
|
<ClInclude Include="..\..\..\src\jrd\ext_proto.h" />
|
||||||
|
<ClInclude Include="..\..\..\src\jrd\FBConfigTable.h" />
|
||||||
<ClInclude Include="..\..\..\src\jrd\fields.h" />
|
<ClInclude Include="..\..\..\src\jrd\fields.h" />
|
||||||
<ClInclude Include="..\..\..\src\jrd\filte_proto.h" />
|
<ClInclude Include="..\..\..\src\jrd\filte_proto.h" />
|
||||||
<ClInclude Include="..\..\..\src\jrd\flags.h" />
|
<ClInclude Include="..\..\..\src\jrd\flags.h" />
|
||||||
|
@ -498,6 +498,9 @@
|
|||||||
<ClCompile Include="..\..\..\src\jrd\MetaName.cpp">
|
<ClCompile Include="..\..\..\src\jrd\MetaName.cpp">
|
||||||
<Filter>JRD files</Filter>
|
<Filter>JRD files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\..\src\jrd\FBConfigTable.cpp">
|
||||||
|
<Filter>JRD files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\..\..\src\jrd\recsrc\RecordSource.h">
|
<ClInclude Include="..\..\..\src\jrd\recsrc\RecordSource.h">
|
||||||
@ -1037,6 +1040,9 @@
|
|||||||
<ClInclude Include="..\..\..\src\jrd\QualifiedName.h">
|
<ClInclude Include="..\..\..\src\jrd\QualifiedName.h">
|
||||||
<Filter>Header files</Filter>
|
<Filter>Header files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\..\src\jrd\FBConfigTable.h">
|
||||||
|
<Filter>Header files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="..\..\..\src\dsql\DdlNodes.epp">
|
<None Include="..\..\..\src\dsql\DdlNodes.epp">
|
||||||
|
@ -142,97 +142,98 @@ const char* GCPolicyBackground = "background";
|
|||||||
const char* GCPolicyCombined = "combined";
|
const char* GCPolicyCombined = "combined";
|
||||||
|
|
||||||
|
|
||||||
const Config::ConfigEntry Config::entries[MAX_CONFIG_KEY] =
|
Config::ConfigEntry Config::entries[MAX_CONFIG_KEY] =
|
||||||
{
|
{
|
||||||
{TYPE_INTEGER, "TempBlockSize", (ConfigValue) 1048576}, // bytes
|
{TYPE_INTEGER, "TempBlockSize", 1048576}, // bytes
|
||||||
{TYPE_INTEGER, "TempCacheLimit", (ConfigValue) -1}, // bytes
|
{TYPE_INTEGER, "TempCacheLimit", -1}, // bytes
|
||||||
{TYPE_BOOLEAN, "RemoteFileOpenAbility", (ConfigValue) false},
|
{TYPE_BOOLEAN, "RemoteFileOpenAbility", false},
|
||||||
{TYPE_INTEGER, "GuardianOption", (ConfigValue) 1},
|
{TYPE_INTEGER, "GuardianOption", 1},
|
||||||
{TYPE_INTEGER, "CpuAffinityMask", (ConfigValue) 0},
|
{TYPE_INTEGER, "CpuAffinityMask", 0},
|
||||||
{TYPE_INTEGER, "TcpRemoteBufferSize", (ConfigValue) 8192}, // bytes
|
{TYPE_INTEGER, "TcpRemoteBufferSize", 8192}, // bytes
|
||||||
{TYPE_BOOLEAN, "TcpNoNagle", (ConfigValue) true},
|
{TYPE_BOOLEAN, "TcpNoNagle", true},
|
||||||
{TYPE_BOOLEAN, "TcpLoopbackFastPath", (ConfigValue) true},
|
{TYPE_BOOLEAN, "TcpLoopbackFastPath", true},
|
||||||
{TYPE_INTEGER, "DefaultDbCachePages", (ConfigValue) -1}, // pages
|
{TYPE_INTEGER, "DefaultDbCachePages", -1}, // pages
|
||||||
{TYPE_INTEGER, "ConnectionTimeout", (ConfigValue) 180}, // seconds
|
{TYPE_INTEGER, "ConnectionTimeout", 180}, // seconds
|
||||||
{TYPE_INTEGER, "DummyPacketInterval", (ConfigValue) 0}, // seconds
|
{TYPE_INTEGER, "DummyPacketInterval", 0}, // seconds
|
||||||
{TYPE_STRING, "DefaultTimeZone", (ConfigValue) ""},
|
{TYPE_STRING, "DefaultTimeZone", NULL},
|
||||||
{TYPE_INTEGER, "LockMemSize", (ConfigValue) 1048576}, // bytes
|
{TYPE_INTEGER, "LockMemSize", 1048576}, // bytes
|
||||||
{TYPE_INTEGER, "LockHashSlots", (ConfigValue) 8191}, // slots
|
{TYPE_INTEGER, "LockHashSlots", 8191}, // slots
|
||||||
{TYPE_INTEGER, "LockAcquireSpins", (ConfigValue) 0},
|
{TYPE_INTEGER, "LockAcquireSpins", 0},
|
||||||
{TYPE_INTEGER, "EventMemSize", (ConfigValue) 65536}, // bytes
|
{TYPE_INTEGER, "EventMemSize", 65536}, // bytes
|
||||||
{TYPE_INTEGER, "DeadlockTimeout", (ConfigValue) 10}, // seconds
|
{TYPE_INTEGER, "DeadlockTimeout", 10}, // seconds
|
||||||
{TYPE_STRING, "RemoteServiceName", (ConfigValue) FB_SERVICE_NAME},
|
{TYPE_STRING, "RemoteServiceName", FB_SERVICE_NAME},
|
||||||
{TYPE_INTEGER, "RemoteServicePort", (ConfigValue) 0},
|
{TYPE_INTEGER, "RemoteServicePort", 0},
|
||||||
{TYPE_STRING, "RemotePipeName", (ConfigValue) FB_PIPE_NAME},
|
{TYPE_STRING, "RemotePipeName", FB_PIPE_NAME},
|
||||||
{TYPE_STRING, "IpcName", (ConfigValue) FB_IPC_NAME},
|
{TYPE_STRING, "IpcName", FB_IPC_NAME},
|
||||||
#ifdef WIN_NT
|
#ifdef WIN_NT
|
||||||
{TYPE_INTEGER, "MaxUnflushedWrites", (ConfigValue) 100},
|
{TYPE_INTEGER, "MaxUnflushedWrites", 100},
|
||||||
{TYPE_INTEGER, "MaxUnflushedWriteTime", (ConfigValue) 5},
|
{TYPE_INTEGER, "MaxUnflushedWriteTime", 5},
|
||||||
#else
|
#else
|
||||||
{TYPE_INTEGER, "MaxUnflushedWrites", (ConfigValue) -1},
|
{TYPE_INTEGER, "MaxUnflushedWrites", -1},
|
||||||
{TYPE_INTEGER, "MaxUnflushedWriteTime", (ConfigValue) -1},
|
{TYPE_INTEGER, "MaxUnflushedWriteTime", -1},
|
||||||
#endif
|
#endif
|
||||||
{TYPE_INTEGER, "ProcessPriorityLevel", (ConfigValue) 0},
|
{TYPE_INTEGER, "ProcessPriorityLevel", 0},
|
||||||
{TYPE_INTEGER, "RemoteAuxPort", (ConfigValue) 0},
|
{TYPE_INTEGER, "RemoteAuxPort", 0},
|
||||||
{TYPE_STRING, "RemoteBindAddress", (ConfigValue) 0},
|
{TYPE_STRING, "RemoteBindAddress", 0},
|
||||||
{TYPE_STRING, "ExternalFileAccess", (ConfigValue) "None"}, // location(s) of external files for tables
|
{TYPE_STRING, "ExternalFileAccess", "None"}, // location(s) of external files for tables
|
||||||
{TYPE_STRING, "DatabaseAccess", (ConfigValue) "Full"}, // location(s) of databases
|
{TYPE_STRING, "DatabaseAccess", "Full"}, // location(s) of databases
|
||||||
{TYPE_STRING, "UdfAccess", (ConfigValue) "None"}, // location(s) of UDFs
|
{TYPE_STRING, "UdfAccess", "None"}, // location(s) of UDFs
|
||||||
{TYPE_STRING, "TempDirectories", (ConfigValue) 0},
|
{TYPE_STRING, "TempDirectories", 0},
|
||||||
#ifdef DEV_BUILD
|
#ifdef DEV_BUILD
|
||||||
{TYPE_BOOLEAN, "BugcheckAbort", (ConfigValue) true}, // whether to abort() engine when internal error is found
|
{TYPE_BOOLEAN, "BugcheckAbort", true}, // whether to abort() engine when internal error is found
|
||||||
#else
|
#else
|
||||||
{TYPE_BOOLEAN, "BugcheckAbort", (ConfigValue) false}, // whether to abort() engine when internal error is found
|
{TYPE_BOOLEAN, "BugcheckAbort", false}, // whether to abort() engine when internal error is found
|
||||||
#endif
|
#endif
|
||||||
{TYPE_INTEGER, "TraceDSQL", (ConfigValue) 0}, // bitmask
|
{TYPE_INTEGER, "TraceDSQL", 0}, // bitmask
|
||||||
{TYPE_BOOLEAN, "LegacyHash", (ConfigValue) true}, // let use old passwd hash verification
|
{TYPE_BOOLEAN, "LegacyHash", true}, // let use old passwd hash verification
|
||||||
{TYPE_STRING, "GCPolicy", (ConfigValue) NULL}, // garbage collection policy
|
{TYPE_STRING, "GCPolicy", NULL}, // garbage collection policy
|
||||||
{TYPE_BOOLEAN, "Redirection", (ConfigValue) false},
|
{TYPE_BOOLEAN, "Redirection", false},
|
||||||
{TYPE_INTEGER, "DatabaseGrowthIncrement", (ConfigValue) 128 * 1048576}, // bytes
|
{TYPE_INTEGER, "DatabaseGrowthIncrement", 128 * 1048576}, // bytes
|
||||||
{TYPE_INTEGER, "FileSystemCacheThreshold", (ConfigValue) 65536}, // page buffers
|
{TYPE_INTEGER, "FileSystemCacheThreshold", 65536}, // page buffers
|
||||||
{TYPE_BOOLEAN, "RelaxedAliasChecking", (ConfigValue) false}, // if true relax strict alias checking rules in DSQL a bit
|
{TYPE_BOOLEAN, "RelaxedAliasChecking", false}, // if true relax strict alias checking rules in DSQL a bit
|
||||||
{TYPE_STRING, "AuditTraceConfigFile", (ConfigValue) ""}, // location of audit trace configuration file
|
{TYPE_STRING, "AuditTraceConfigFile", ""}, // location of audit trace configuration file
|
||||||
{TYPE_INTEGER, "MaxUserTraceLogSize", (ConfigValue) 10}, // maximum size of user session trace log
|
{TYPE_INTEGER, "MaxUserTraceLogSize", 10}, // maximum size of user session trace log
|
||||||
{TYPE_INTEGER, "FileSystemCacheSize", (ConfigValue) 0}, // percent
|
{TYPE_INTEGER, "FileSystemCacheSize", 0}, // percent
|
||||||
{TYPE_STRING, "Providers", (ConfigValue) "Remote, " CURRENT_ENGINE ", Loopback"},
|
{TYPE_STRING, "Providers", "Remote, " CURRENT_ENGINE ", Loopback"},
|
||||||
{TYPE_STRING, "AuthServer", (ConfigValue) "Srp256"},
|
{TYPE_STRING, "AuthServer", "Srp256"},
|
||||||
#ifdef WIN_NT
|
#ifdef WIN_NT
|
||||||
{TYPE_STRING, "AuthClient", (ConfigValue) "Srp256, Srp, Win_Sspi, Legacy_Auth"},
|
{TYPE_STRING, "AuthClient", "Srp256, Srp, Win_Sspi, Legacy_Auth"},
|
||||||
#else
|
#else
|
||||||
{TYPE_STRING, "AuthClient", (ConfigValue) "Srp256, Srp, Legacy_Auth"},
|
{TYPE_STRING, "AuthClient", "Srp256, Srp, Legacy_Auth"},
|
||||||
#endif
|
#endif
|
||||||
{TYPE_STRING, "UserManager", (ConfigValue) "Srp"},
|
{TYPE_STRING, "UserManager", "Srp"},
|
||||||
{TYPE_STRING, "TracePlugin", (ConfigValue) "fbtrace"},
|
{TYPE_STRING, "TracePlugin", "fbtrace"},
|
||||||
{TYPE_STRING, "SecurityDatabase", (ConfigValue) NULL}, // sec/db alias - rely on ConfigManager::getDefaultSecurityDb()
|
{TYPE_STRING, "SecurityDatabase", NULL}, // sec/db alias - rely on ConfigManager::getDefaultSecurityDb()
|
||||||
{TYPE_STRING, "ServerMode", (ConfigValue) ""}, // actual value differs in boot/regular cases
|
{TYPE_STRING, "ServerMode", NULL}, // actual value differs in boot/regular cases and set at setupDefaultConfig()
|
||||||
{TYPE_STRING, "WireCrypt", (ConfigValue) NULL},
|
{TYPE_STRING, "WireCrypt", NULL},
|
||||||
{TYPE_STRING, "WireCryptPlugin", (ConfigValue) "ChaCha, Arc4"},
|
{TYPE_STRING, "WireCryptPlugin", "ChaCha, Arc4"},
|
||||||
{TYPE_STRING, "KeyHolderPlugin", (ConfigValue) ""},
|
{TYPE_STRING, "KeyHolderPlugin", ""},
|
||||||
{TYPE_BOOLEAN, "RemoteAccess", (ConfigValue) true},
|
{TYPE_BOOLEAN, "RemoteAccess", true},
|
||||||
{TYPE_BOOLEAN, "IPv6V6Only", (ConfigValue) false},
|
{TYPE_BOOLEAN, "IPv6V6Only", false},
|
||||||
{TYPE_BOOLEAN, "WireCompression", (ConfigValue) false},
|
{TYPE_BOOLEAN, "WireCompression", false},
|
||||||
{TYPE_INTEGER, "MaxIdentifierByteLength", (ConfigValue) -1},
|
{TYPE_INTEGER, "MaxIdentifierByteLength", -1},
|
||||||
{TYPE_INTEGER, "MaxIdentifierCharLength", (ConfigValue) -1},
|
{TYPE_INTEGER, "MaxIdentifierCharLength", -1},
|
||||||
{TYPE_BOOLEAN, "AllowEncryptedSecurityDatabase", (ConfigValue) false},
|
{TYPE_BOOLEAN, "AllowEncryptedSecurityDatabase", false},
|
||||||
{TYPE_INTEGER, "StatementTimeout", (ConfigValue) 0},
|
{TYPE_INTEGER, "StatementTimeout", 0},
|
||||||
{TYPE_INTEGER, "ConnectionIdleTimeout", (ConfigValue) 0},
|
{TYPE_INTEGER, "ConnectionIdleTimeout", 0},
|
||||||
{TYPE_INTEGER, "ClientBatchBuffer", (ConfigValue) (128 * 1024)},
|
{TYPE_INTEGER, "ClientBatchBuffer", (128 * 1024)},
|
||||||
#ifdef DEV_BUILD
|
#ifdef DEV_BUILD
|
||||||
{TYPE_STRING, "OutputRedirectionFile", (ConfigValue) "-"},
|
{TYPE_STRING, "OutputRedirectionFile", "-"},
|
||||||
#else
|
#else
|
||||||
#ifdef WIN_NT
|
#ifdef WIN_NT
|
||||||
{TYPE_STRING, "OutputRedirectionFile", (ConfigValue) "nul"},
|
{TYPE_STRING, "OutputRedirectionFile", "nul"},
|
||||||
#else
|
#else
|
||||||
{TYPE_STRING, "OutputRedirectionFile", (ConfigValue) "/dev/null"},
|
{TYPE_STRING, "OutputRedirectionFile", "/dev/null"},
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
{TYPE_INTEGER, "ExtConnPoolSize", (ConfigValue) 0},
|
{TYPE_INTEGER, "ExtConnPoolSize", 0},
|
||||||
{TYPE_INTEGER, "ExtConnPoolLifeTime", (ConfigValue) 7200},
|
{TYPE_INTEGER, "ExtConnPoolLifeTime", 7200},
|
||||||
{TYPE_INTEGER, "SnapshotsMemSize", (ConfigValue) 65536}, // bytes
|
{TYPE_INTEGER, "SnapshotsMemSize", 65536}, // bytes
|
||||||
{TYPE_INTEGER, "TipCacheBlockSize", (ConfigValue) 4194304}, // bytes
|
{TYPE_INTEGER, "TipCacheBlockSize", 4194304}, // bytes
|
||||||
{TYPE_BOOLEAN, "ReadConsistency", (ConfigValue) true},
|
{TYPE_BOOLEAN, "ReadConsistency", true},
|
||||||
{TYPE_BOOLEAN, "ClearGTTAtRetaining", (ConfigValue) false},
|
{TYPE_BOOLEAN, "ClearGTTAtRetaining", false},
|
||||||
{TYPE_STRING, "DataTypeCompatibility", (ConfigValue) NULL}
|
{TYPE_STRING, "DataTypeCompatibility", NULL},
|
||||||
|
{TYPE_BOOLEAN, "UseFileSystemCache", true}
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
@ -241,8 +242,13 @@ const Config::ConfigEntry Config::entries[MAX_CONFIG_KEY] =
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
Config::Config(const ConfigFile& file)
|
Config::Config(const ConfigFile& file)
|
||||||
: notifyDatabase(*getDefaultMemoryPool())
|
: notifyDatabase(*getDefaultMemoryPool()),
|
||||||
|
serverMode(-1)
|
||||||
{
|
{
|
||||||
|
memset(bits, 0, sizeof(bits));
|
||||||
|
|
||||||
|
setupDefaultConfig();
|
||||||
|
|
||||||
// Array to save string temporarily
|
// Array to save string temporarily
|
||||||
// Will be finally saved by loadValues() in the end of ctor
|
// Will be finally saved by loadValues() in the end of ctor
|
||||||
ObjectsArray<ConfigFile::String> tempStrings(getPool());
|
ObjectsArray<ConfigFile::String> tempStrings(getPool());
|
||||||
@ -251,10 +257,10 @@ Config::Config(const ConfigFile& file)
|
|||||||
for (unsigned int i = 0; i < MAX_CONFIG_KEY; i++)
|
for (unsigned int i = 0; i < MAX_CONFIG_KEY; i++)
|
||||||
{
|
{
|
||||||
values[i] = entries[i].default_value;
|
values[i] = entries[i].default_value;
|
||||||
if (entries[i].data_type == TYPE_STRING && values[i])
|
if (entries[i].data_type == TYPE_STRING && values[i].strVal)
|
||||||
{
|
{
|
||||||
ConfigFile::String expand((const char*)values[i]);
|
ConfigFile::String expand(values[i].strVal);
|
||||||
if (file.macroParse(expand, NULL) && expand != (const char*) values[i])
|
if (file.macroParse(expand, NULL) && expand != values[i].strVal)
|
||||||
{
|
{
|
||||||
ConfigFile::String& saved(tempStrings.add());
|
ConfigFile::String& saved(tempStrings.add());
|
||||||
saved = expand;
|
saved = expand;
|
||||||
@ -267,26 +273,36 @@ Config::Config(const ConfigFile& file)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Config::Config(const ConfigFile& file, const Config& base)
|
Config::Config(const ConfigFile& file, const Config& base)
|
||||||
: notifyDatabase(*getDefaultMemoryPool())
|
: notifyDatabase(*getDefaultMemoryPool()),
|
||||||
|
serverMode(-1)
|
||||||
{
|
{
|
||||||
|
memset(bits, 0, sizeof(bits));
|
||||||
|
|
||||||
// Iterate through the known configuration entries
|
// Iterate through the known configuration entries
|
||||||
|
|
||||||
for (unsigned int i = 0; i < MAX_CONFIG_KEY; i++)
|
for (unsigned int i = 0; i < MAX_CONFIG_KEY; i++)
|
||||||
{
|
{
|
||||||
values[i] = base.values[i];
|
values[i] = base.values[i];
|
||||||
|
if (base.testKey(i))
|
||||||
|
setKey(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
loadValues(file);
|
loadValues(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
Config::Config(const ConfigFile& file, const Config& base, const PathName& notify)
|
Config::Config(const ConfigFile& file, const Config& base, const PathName& notify)
|
||||||
: notifyDatabase(*getDefaultMemoryPool())
|
: notifyDatabase(*getDefaultMemoryPool()),
|
||||||
|
serverMode(-1)
|
||||||
{
|
{
|
||||||
|
memset(bits, 0, sizeof(bits));
|
||||||
|
|
||||||
// Iterate through the known configuration entries
|
// Iterate through the known configuration entries
|
||||||
|
|
||||||
for (unsigned int i = 0; i < MAX_CONFIG_KEY; i++)
|
for (unsigned int i = 0; i < MAX_CONFIG_KEY; i++)
|
||||||
{
|
{
|
||||||
values[i] = base.values[i];
|
values[i] = base.values[i];
|
||||||
|
if (base.testKey(i))
|
||||||
|
setKey(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
loadValues(file);
|
loadValues(file);
|
||||||
@ -338,18 +354,146 @@ void Config::loadValues(const ConfigFile& file)
|
|||||||
//case TYPE_STRING_VECTOR:
|
//case TYPE_STRING_VECTOR:
|
||||||
// break;
|
// break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setKey(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entry.data_type == TYPE_STRING && values[i] != entry.default_value)
|
if (entry.data_type == TYPE_STRING && values[i] != entry.default_value)
|
||||||
{
|
{
|
||||||
const char* src = (const char*) values[i];
|
const char* src = values[i].strVal;
|
||||||
char* dst = FB_NEW_POOL(getPool()) char[strlen(src) + 1];
|
char* dst = FB_NEW_POOL(getPool()) char[strlen(src) + 1];
|
||||||
strcpy(dst, src);
|
strcpy(dst, src);
|
||||||
values[i] = (ConfigValue) dst;
|
values[i] = (ConfigValue) dst;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
checkValues();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char* txtServerModes[6] =
|
||||||
|
{
|
||||||
|
"Super", "ThreadedDedicated",
|
||||||
|
"SuperClassic", "ThreadedShared",
|
||||||
|
"Classic", "MultiProcess"
|
||||||
|
};
|
||||||
|
|
||||||
|
void Config::setupDefaultConfig()
|
||||||
|
{
|
||||||
|
const bool bootBuild = fb_utils::bootBuild();
|
||||||
|
|
||||||
|
ConfigValue* pDefault = &entries[KEY_SERVER_MODE].default_value;
|
||||||
|
serverMode = bootBuild ? MODE_CLASSIC : MODE_SUPER;
|
||||||
|
pDefault->strVal = txtServerModes[2 * serverMode];
|
||||||
|
|
||||||
|
pDefault = &entries[KEY_TEMP_CACHE_LIMIT].default_value;
|
||||||
|
if (pDefault->intVal < 0)
|
||||||
|
pDefault->intVal = (serverMode != MODE_SUPER) ? 8388608 : 67108864; // bytes
|
||||||
|
|
||||||
|
entries[KEY_REMOTE_FILE_OPEN_ABILITY].default_value.boolVal = bootBuild;
|
||||||
|
|
||||||
|
pDefault = &entries[KEY_DEFAULT_DB_CACHE_PAGES].default_value;
|
||||||
|
if (pDefault->intVal < 0)
|
||||||
|
pDefault->intVal = (serverMode != MODE_SUPER) ? 256 : 2048; // pages
|
||||||
|
|
||||||
|
pDefault = &entries[KEY_GC_POLICY].default_value;
|
||||||
|
if (!pDefault->strVal)
|
||||||
|
{
|
||||||
|
pDefault->strVal = (serverMode == MODE_SUPER) ? GCPolicyCombined : GCPolicyCooperative;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//pDefault = &entries[KEY_SECURITY_DATABASE].default_value;
|
||||||
|
|
||||||
|
//pDefault = &entries[KEY_WIRE_CRYPT].default_value;
|
||||||
|
// if (!*pDefault)
|
||||||
|
// *pDefault == (ConfigValue) (xxx == WC_CLIENT) ? WIRE_CRYPT_ENABLED : WIRE_CRYPT_REQUIRED;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Config::checkValues()
|
||||||
|
{
|
||||||
|
checkIntForLoBound(KEY_TEMP_CACHE_LIMIT, 0, true);
|
||||||
|
|
||||||
|
checkIntForLoBound(KEY_TCP_REMOTE_BUFFER_SIZE, 1448, false);
|
||||||
|
checkIntForHiBound(KEY_TCP_REMOTE_BUFFER_SIZE, MAX_SSHORT, false);
|
||||||
|
|
||||||
|
checkIntForLoBound(KEY_DEFAULT_DB_CACHE_PAGES, 0, true);
|
||||||
|
|
||||||
|
checkIntForLoBound(KEY_LOCK_MEM_SIZE, 64 * 1024, false);
|
||||||
|
|
||||||
|
const char* strVal = values[KEY_GC_POLICY].strVal;
|
||||||
|
if (strVal)
|
||||||
|
{
|
||||||
|
NoCaseString gcPolicy(strVal);
|
||||||
|
if (gcPolicy != GCPolicyCooperative &&
|
||||||
|
gcPolicy != GCPolicyBackground &&
|
||||||
|
gcPolicy != GCPolicyCombined)
|
||||||
|
{
|
||||||
|
// user-provided value is invalid - fail to default
|
||||||
|
values[KEY_GC_POLICY] = entries[KEY_GC_POLICY].default_value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
strVal = values[KEY_WIRE_CRYPT].strVal;
|
||||||
|
if (strVal)
|
||||||
|
{
|
||||||
|
NoCaseString wireCrypt(strVal);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
strVal = values[KEY_SERVER_MODE].strVal;
|
||||||
|
if (strVal && !fb_utils::bootBuild())
|
||||||
|
{
|
||||||
|
bool found = false;
|
||||||
|
NoCaseString mode(strVal);
|
||||||
|
for (int x = 0; x < 6; ++x)
|
||||||
|
{
|
||||||
|
if (mode == txtServerModes[x])
|
||||||
|
{
|
||||||
|
serverMode = x / 2;
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found)
|
||||||
|
values[KEY_SERVER_MODE] = entries[KEY_SERVER_MODE].default_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
checkIntForLoBound(KEY_FILESYSTEM_CACHE_THRESHOLD, 0, true);
|
||||||
|
|
||||||
|
checkIntForLoBound(KEY_MAX_IDENTIFIER_BYTE_LENGTH, 1, true);
|
||||||
|
checkIntForHiBound(KEY_MAX_IDENTIFIER_BYTE_LENGTH, MAX_SQL_IDENTIFIER_LEN, true);
|
||||||
|
|
||||||
|
checkIntForLoBound(KEY_MAX_IDENTIFIER_CHAR_LENGTH, 1, true);
|
||||||
|
checkIntForHiBound(KEY_MAX_IDENTIFIER_CHAR_LENGTH, METADATA_IDENTIFIER_CHAR_LEN, true);
|
||||||
|
|
||||||
|
checkIntForLoBound(KEY_SNAPSHOTS_MEM_SIZE, 1, true);
|
||||||
|
checkIntForHiBound(KEY_SNAPSHOTS_MEM_SIZE, MAX_ULONG, true);
|
||||||
|
|
||||||
|
checkIntForLoBound(KEY_TIP_CACHE_BLOCK_SIZE, 1, true);
|
||||||
|
checkIntForHiBound(KEY_TIP_CACHE_BLOCK_SIZE, MAX_ULONG, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Config::~Config()
|
Config::~Config()
|
||||||
{
|
{
|
||||||
// Free allocated memory
|
// Free allocated memory
|
||||||
@ -362,7 +506,7 @@ Config::~Config()
|
|||||||
switch (entries[i].data_type)
|
switch (entries[i].data_type)
|
||||||
{
|
{
|
||||||
case TYPE_STRING:
|
case TYPE_STRING:
|
||||||
delete[] (char*) values[i];
|
delete[] values[i].strVal;
|
||||||
break;
|
break;
|
||||||
//case TYPE_STRING_VECTOR:
|
//case TYPE_STRING_VECTOR:
|
||||||
// break;
|
// break;
|
||||||
@ -435,7 +579,7 @@ SINT64 Config::getInt(unsigned int key) const
|
|||||||
{
|
{
|
||||||
if (key >= MAX_CONFIG_KEY)
|
if (key >= MAX_CONFIG_KEY)
|
||||||
return 0;
|
return 0;
|
||||||
return get<SINT64>(static_cast<ConfigKey>(key));
|
return getInt(static_cast<ConfigKey>(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* Config::getString(unsigned int key) const
|
const char* Config::getString(unsigned int key) const
|
||||||
@ -450,330 +594,315 @@ const char* Config::getString(unsigned int key) const
|
|||||||
return getSecurityDatabase();
|
return getSecurityDatabase();
|
||||||
}
|
}
|
||||||
|
|
||||||
return get<const char*>(static_cast<ConfigKey>(key));
|
return getStr(static_cast<ConfigKey>(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Config::getBoolean(unsigned int key) const
|
bool Config::getBoolean(unsigned int key) const
|
||||||
{
|
{
|
||||||
if (key >= MAX_CONFIG_KEY)
|
if (key >= MAX_CONFIG_KEY)
|
||||||
return false;
|
return false;
|
||||||
return get<bool>(static_cast<ConfigKey>(key));
|
return getBool(static_cast<ConfigKey>(key));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Config::valueAsString(ConfigValue val, ConfigType type, string& str)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case Config::TYPE_INTEGER:
|
||||||
|
str.printf("%" SQUADFORMAT, val.intVal);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Config::TYPE_STRING:
|
||||||
|
{
|
||||||
|
if (val == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
str = val.strVal;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Config::TYPE_BOOLEAN:
|
||||||
|
str = val.boolVal ? "true" : "false";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Config::getValue(unsigned int key, string& str) const
|
||||||
|
{
|
||||||
|
if (key >= MAX_CONFIG_KEY)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return valueAsString(values[key], entries[key].data_type, str);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Config::getDefaultValue(unsigned int key, string& str)
|
||||||
|
{
|
||||||
|
if (key >= MAX_CONFIG_KEY)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return valueAsString(entries[key].default_value, entries[key].data_type, str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int Config::getTempBlockSize()
|
int Config::getTempBlockSize()
|
||||||
{
|
{
|
||||||
return (int) getDefaultConfig()->values[KEY_TEMP_BLOCK_SIZE];
|
return (int) getDefaultConfig()->values[KEY_TEMP_BLOCK_SIZE].intVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
FB_UINT64 Config::getTempCacheLimit() const
|
FB_UINT64 Config::getTempCacheLimit() const
|
||||||
{
|
{
|
||||||
SINT64 v = get<SINT64>(KEY_TEMP_CACHE_LIMIT);
|
return getInt(KEY_TEMP_CACHE_LIMIT);
|
||||||
if (v < 0)
|
|
||||||
{
|
|
||||||
v = getServerMode() != MODE_SUPER ? 8388608 : 67108864; // bytes
|
|
||||||
}
|
|
||||||
return v;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Config::getRemoteFileOpenAbility()
|
bool Config::getRemoteFileOpenAbility()
|
||||||
{
|
{
|
||||||
return fb_utils::bootBuild() ? true : ((bool) getDefaultConfig()->values[KEY_REMOTE_FILE_OPEN_ABILITY]);
|
return getDefaultConfig()->getBool(KEY_REMOTE_FILE_OPEN_ABILITY);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Config::getGuardianOption()
|
int Config::getGuardianOption()
|
||||||
{
|
{
|
||||||
return (int) getDefaultConfig()->values[KEY_GUARDIAN_OPTION];
|
return getDefaultConfig()->getInt(KEY_GUARDIAN_OPTION);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Config::getCpuAffinityMask()
|
FB_UINT64 Config::getCpuAffinityMask()
|
||||||
{
|
{
|
||||||
return (int) getDefaultConfig()->values[KEY_CPU_AFFINITY_MASK];
|
return getDefaultConfig()->getInt(KEY_CPU_AFFINITY_MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Config::getTcpRemoteBufferSize()
|
int Config::getTcpRemoteBufferSize()
|
||||||
{
|
{
|
||||||
int rc = (int) getDefaultConfig()->values[KEY_TCP_REMOTE_BUFFER_SIZE];
|
return getDefaultConfig()->getInt(KEY_TCP_REMOTE_BUFFER_SIZE);
|
||||||
if (rc < 1448)
|
|
||||||
rc = 1448;
|
|
||||||
if (rc > MAX_SSHORT)
|
|
||||||
rc = MAX_SSHORT;
|
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Config::getTcpNoNagle() const
|
bool Config::getTcpNoNagle() const
|
||||||
{
|
{
|
||||||
return get<bool>(KEY_TCP_NO_NAGLE);
|
return getBool(KEY_TCP_NO_NAGLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Config::getTcpLoopbackFastPath() const
|
bool Config::getTcpLoopbackFastPath() const
|
||||||
{
|
{
|
||||||
return get<bool>(KEY_TCP_LOOPBACK_FAST_PATH);
|
return getBool(KEY_TCP_LOOPBACK_FAST_PATH);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Config::getIPv6V6Only() const
|
bool Config::getIPv6V6Only() const
|
||||||
{
|
{
|
||||||
return get<bool>(KEY_IPV6_V6ONLY);
|
return getBool(KEY_IPV6_V6ONLY);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Config::getDefaultDbCachePages() const
|
int Config::getDefaultDbCachePages() const
|
||||||
{
|
{
|
||||||
int rc = get<int>(KEY_DEFAULT_DB_CACHE_PAGES);
|
return getInt(KEY_DEFAULT_DB_CACHE_PAGES);
|
||||||
if (rc < 0)
|
|
||||||
{
|
|
||||||
rc = getServerMode() != MODE_SUPER ? 256 : 2048; // pages
|
|
||||||
}
|
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int Config::getConnectionTimeout() const
|
int Config::getConnectionTimeout() const
|
||||||
{
|
{
|
||||||
return get<int>(KEY_CONNECTION_TIMEOUT);
|
return getInt(KEY_CONNECTION_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Config::getDummyPacketInterval() const
|
int Config::getDummyPacketInterval() const
|
||||||
{
|
{
|
||||||
return get<int>(KEY_DUMMY_PACKET_INTERVAL);
|
return getInt(KEY_DUMMY_PACKET_INTERVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* Config::getDefaultTimeZone()
|
const char* Config::getDefaultTimeZone()
|
||||||
{
|
{
|
||||||
return getDefaultConfig()->get<const char*>(KEY_DEFAULT_TIME_ZONE);
|
return getDefaultConfig()->getStr(KEY_DEFAULT_TIME_ZONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Config::getLockMemSize() const
|
int Config::getLockMemSize() const
|
||||||
{
|
{
|
||||||
int size = get<int>(KEY_LOCK_MEM_SIZE);
|
return getInt(KEY_LOCK_MEM_SIZE);
|
||||||
if (size < 64 * 1024)
|
|
||||||
size = 64 * 1024;
|
|
||||||
return size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int Config::getLockHashSlots() const
|
int Config::getLockHashSlots() const
|
||||||
{
|
{
|
||||||
return get<int>(KEY_LOCK_HASH_SLOTS);
|
return getInt(KEY_LOCK_HASH_SLOTS);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Config::getLockAcquireSpins() const
|
int Config::getLockAcquireSpins() const
|
||||||
{
|
{
|
||||||
return get<int>(KEY_LOCK_ACQUIRE_SPINS);
|
return getInt(KEY_LOCK_ACQUIRE_SPINS);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Config::getEventMemSize() const
|
int Config::getEventMemSize() const
|
||||||
{
|
{
|
||||||
return get<int>(KEY_EVENT_MEM_SIZE);
|
return getInt(KEY_EVENT_MEM_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Config::getDeadlockTimeout() const
|
int Config::getDeadlockTimeout() const
|
||||||
{
|
{
|
||||||
return get<int>(KEY_DEADLOCK_TIMEOUT);
|
return getInt(KEY_DEADLOCK_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *Config::getRemoteServiceName() const
|
const char *Config::getRemoteServiceName() const
|
||||||
{
|
{
|
||||||
return get<const char*>(KEY_REMOTE_SERVICE_NAME);
|
return getStr(KEY_REMOTE_SERVICE_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned short Config::getRemoteServicePort() const
|
unsigned short Config::getRemoteServicePort() const
|
||||||
{
|
{
|
||||||
return get<unsigned short>(KEY_REMOTE_SERVICE_PORT);
|
return getInt(KEY_REMOTE_SERVICE_PORT);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *Config::getRemotePipeName() const
|
const char *Config::getRemotePipeName() const
|
||||||
{
|
{
|
||||||
return get<const char*>(KEY_REMOTE_PIPE_NAME);
|
return getStr(KEY_REMOTE_PIPE_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *Config::getIpcName() const
|
const char *Config::getIpcName() const
|
||||||
{
|
{
|
||||||
return get<const char*>(KEY_IPC_NAME);
|
return getStr(KEY_IPC_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Config::getMaxUnflushedWrites() const
|
int Config::getMaxUnflushedWrites() const
|
||||||
{
|
{
|
||||||
return get<int>(KEY_MAX_UNFLUSHED_WRITES);
|
return getInt(KEY_MAX_UNFLUSHED_WRITES);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Config::getMaxUnflushedWriteTime() const
|
int Config::getMaxUnflushedWriteTime() const
|
||||||
{
|
{
|
||||||
return get<int>(KEY_MAX_UNFLUSHED_WRITE_TIME);
|
return getInt(KEY_MAX_UNFLUSHED_WRITE_TIME);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Config::getProcessPriorityLevel()
|
int Config::getProcessPriorityLevel()
|
||||||
{
|
{
|
||||||
return (int) getDefaultConfig()->values[KEY_PROCESS_PRIORITY_LEVEL];
|
return getDefaultConfig()->getInt(KEY_PROCESS_PRIORITY_LEVEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Config::getRemoteAuxPort() const
|
int Config::getRemoteAuxPort() const
|
||||||
{
|
{
|
||||||
return get<int>(KEY_REMOTE_AUX_PORT);
|
return getInt(KEY_REMOTE_AUX_PORT);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *Config::getRemoteBindAddress()
|
const char *Config::getRemoteBindAddress()
|
||||||
{
|
{
|
||||||
return (const char*) getDefaultConfig()->values[KEY_REMOTE_BIND_ADDRESS];
|
return getDefaultConfig()->getStr(KEY_REMOTE_BIND_ADDRESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *Config::getExternalFileAccess() const
|
const char *Config::getExternalFileAccess() const
|
||||||
{
|
{
|
||||||
return get<const char*>(KEY_EXTERNAL_FILE_ACCESS);
|
return getStr(KEY_EXTERNAL_FILE_ACCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *Config::getDatabaseAccess()
|
const char *Config::getDatabaseAccess()
|
||||||
{
|
{
|
||||||
return (const char*) getDefaultConfig()->values[KEY_DATABASE_ACCESS];
|
return getDefaultConfig()->getStr(KEY_DATABASE_ACCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *Config::getUdfAccess()
|
const char *Config::getUdfAccess()
|
||||||
{
|
{
|
||||||
return (const char*) getDefaultConfig()->values[KEY_UDF_ACCESS];
|
return getDefaultConfig()->getStr(KEY_UDF_ACCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *Config::getTempDirectories()
|
const char *Config::getTempDirectories()
|
||||||
{
|
{
|
||||||
return (const char*) getDefaultConfig()->values[KEY_TEMP_DIRECTORIES];
|
return getDefaultConfig()->getStr(KEY_TEMP_DIRECTORIES);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Config::getBugcheckAbort()
|
bool Config::getBugcheckAbort()
|
||||||
{
|
{
|
||||||
return (bool) getDefaultConfig()->values[KEY_BUGCHECK_ABORT];
|
return getDefaultConfig()->getBool(KEY_BUGCHECK_ABORT);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Config::getTraceDSQL()
|
int Config::getTraceDSQL()
|
||||||
{
|
{
|
||||||
return (int) getDefaultConfig()->values[KEY_TRACE_DSQL];
|
return getDefaultConfig()->getInt(KEY_TRACE_DSQL);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Config::getLegacyHash()
|
bool Config::getLegacyHash()
|
||||||
{
|
{
|
||||||
return (bool) getDefaultConfig()->values[KEY_LEGACY_HASH];
|
return getDefaultConfig()->getBool(KEY_LEGACY_HASH);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *Config::getGCPolicy() const
|
const char *Config::getGCPolicy() const
|
||||||
{
|
{
|
||||||
const char* rc = get<const char*>(KEY_GC_POLICY);
|
return getStr(KEY_GC_POLICY);
|
||||||
|
|
||||||
if (rc)
|
|
||||||
{
|
|
||||||
if (strcmp(rc, GCPolicyCooperative) != 0 &&
|
|
||||||
strcmp(rc, GCPolicyBackground) != 0 &&
|
|
||||||
strcmp(rc, GCPolicyCombined) != 0)
|
|
||||||
{
|
|
||||||
// user-provided value is invalid - fail to default
|
|
||||||
rc = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! rc)
|
|
||||||
{
|
|
||||||
rc = getServerMode() == MODE_SUPER ? GCPolicyCombined : GCPolicyCooperative;
|
|
||||||
}
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Config::getRedirection()
|
bool Config::getRedirection()
|
||||||
{
|
{
|
||||||
return (bool) getDefaultConfig()->values[KEY_REDIRECTION];
|
return getDefaultConfig()->getBool(KEY_REDIRECTION);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Config::getDatabaseGrowthIncrement() const
|
int Config::getDatabaseGrowthIncrement() const
|
||||||
{
|
{
|
||||||
return get<int>(KEY_DATABASE_GROWTH_INCREMENT);
|
return getInt(KEY_DATABASE_GROWTH_INCREMENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Config::getFileSystemCacheThreshold() const
|
int Config::getFileSystemCacheThreshold() const
|
||||||
{
|
{
|
||||||
int rc = get<int>(KEY_FILESYSTEM_CACHE_THRESHOLD);
|
return getInt(KEY_FILESYSTEM_CACHE_THRESHOLD);
|
||||||
return rc < 0 ? 0 : rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Config::getRelaxedAliasChecking()
|
bool Config::getRelaxedAliasChecking()
|
||||||
{
|
{
|
||||||
return (bool) getDefaultConfig()->values[KEY_RELAXED_ALIAS_CHECKING];
|
return getDefaultConfig()->getBool(KEY_RELAXED_ALIAS_CHECKING);
|
||||||
}
|
}
|
||||||
|
|
||||||
FB_UINT64 Config::getFileSystemCacheSize()
|
FB_UINT64 Config::getFileSystemCacheSize()
|
||||||
{
|
{
|
||||||
return (FB_UINT64)(SINT64) getDefaultConfig()->values[KEY_FILESYSTEM_CACHE_SIZE];
|
return (FB_UINT64) getDefaultConfig()->getInt(KEY_FILESYSTEM_CACHE_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *Config::getAuditTraceConfigFile()
|
const char *Config::getAuditTraceConfigFile()
|
||||||
{
|
{
|
||||||
return (const char*) getDefaultConfig()->values[KEY_TRACE_CONFIG];
|
return getDefaultConfig()->getStr(KEY_TRACE_CONFIG);
|
||||||
}
|
}
|
||||||
|
|
||||||
FB_UINT64 Config::getMaxUserTraceLogSize()
|
FB_UINT64 Config::getMaxUserTraceLogSize()
|
||||||
{
|
{
|
||||||
return (FB_UINT64)(SINT64) getDefaultConfig()->values[KEY_MAX_TRACELOG_SIZE];
|
return (FB_UINT64) getDefaultConfig()->getInt(KEY_MAX_TRACELOG_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Config::getServerMode()
|
int Config::getServerMode()
|
||||||
{
|
{
|
||||||
static int rc = -1;
|
return getDefaultConfig()->serverMode;
|
||||||
if (rc >= 0)
|
|
||||||
return rc;
|
|
||||||
|
|
||||||
const char* textMode = (const char*) (getDefaultConfig()->values[KEY_SERVER_MODE]);
|
|
||||||
const char* modes[6] =
|
|
||||||
{"Super", "ThreadedDedicated", "SuperClassic", "ThreadedShared", "Classic", "MultiProcess"};
|
|
||||||
|
|
||||||
for (int x = 0; x < 6; ++x)
|
|
||||||
{
|
|
||||||
if (fb_utils::stricmp(textMode, modes[x]) == 0)
|
|
||||||
{
|
|
||||||
rc = x / 2;
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// use default
|
|
||||||
rc = fb_utils::bootBuild() ? MODE_CLASSIC : MODE_SUPER;
|
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG Config::getSnapshotsMemSize() const
|
ULONG Config::getSnapshotsMemSize() const
|
||||||
{
|
{
|
||||||
SINT64 rc = get<SINT64>(KEY_SNAPSHOTS_MEM_SIZE);
|
return getInt(KEY_SNAPSHOTS_MEM_SIZE);
|
||||||
if (rc <= 0 || rc > MAX_ULONG)
|
|
||||||
{
|
|
||||||
rc = 65536;
|
|
||||||
}
|
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG Config::getTipCacheBlockSize() const
|
ULONG Config::getTipCacheBlockSize() const
|
||||||
{
|
{
|
||||||
SINT64 rc = get<SINT64>(KEY_TIP_CACHE_BLOCK_SIZE);
|
return getInt(KEY_TIP_CACHE_BLOCK_SIZE);
|
||||||
if (rc <= 0 || rc > MAX_ULONG)
|
|
||||||
{
|
|
||||||
rc = 4194304;
|
|
||||||
}
|
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* Config::getPlugins(unsigned int type) const
|
const char* Config::getPlugins(unsigned int type) const
|
||||||
{
|
{
|
||||||
|
ConfigKey key;
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case IPluginManager::TYPE_PROVIDER:
|
case IPluginManager::TYPE_PROVIDER:
|
||||||
return (const char*) values[KEY_PLUG_PROVIDERS];
|
key = KEY_PLUG_PROVIDERS;
|
||||||
|
break;
|
||||||
case IPluginManager::TYPE_AUTH_SERVER:
|
case IPluginManager::TYPE_AUTH_SERVER:
|
||||||
return (const char*) values[KEY_PLUG_AUTH_SERVER];
|
key = KEY_PLUG_AUTH_SERVER;
|
||||||
|
break;
|
||||||
case IPluginManager::TYPE_AUTH_CLIENT:
|
case IPluginManager::TYPE_AUTH_CLIENT:
|
||||||
return (const char*) values[KEY_PLUG_AUTH_CLIENT];
|
key = KEY_PLUG_AUTH_CLIENT;
|
||||||
|
break;
|
||||||
case IPluginManager::TYPE_AUTH_USER_MANAGEMENT:
|
case IPluginManager::TYPE_AUTH_USER_MANAGEMENT:
|
||||||
return (const char*) values[KEY_PLUG_AUTH_MANAGE];
|
key = KEY_PLUG_AUTH_MANAGE;
|
||||||
|
break;
|
||||||
case IPluginManager::TYPE_TRACE:
|
case IPluginManager::TYPE_TRACE:
|
||||||
return (const char*) values[KEY_PLUG_TRACE];
|
key = KEY_PLUG_TRACE;
|
||||||
|
break;
|
||||||
case IPluginManager::TYPE_WIRE_CRYPT:
|
case IPluginManager::TYPE_WIRE_CRYPT:
|
||||||
return (const char*) values[KEY_PLUG_WIRE_CRYPT];
|
key = KEY_PLUG_WIRE_CRYPT;
|
||||||
|
break;
|
||||||
case IPluginManager::TYPE_KEY_HOLDER:
|
case IPluginManager::TYPE_KEY_HOLDER:
|
||||||
return (const char*) values[KEY_PLUG_KEY_HOLDER];
|
key = KEY_PLUG_KEY_HOLDER;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
(Arg::Gds(isc_random) << "Internal error in Config::getPlugins(): unknown plugin type requested").raise();
|
||||||
}
|
}
|
||||||
|
|
||||||
(Arg::Gds(isc_random) << "Internal error in Config::getPlugins(): unknown plugin type requested").raise();
|
return getStr(key);
|
||||||
return NULL; // compiler warning silencer
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -844,7 +973,7 @@ int FirebirdConf::release()
|
|||||||
|
|
||||||
const char* Config::getSecurityDatabase() const
|
const char* Config::getSecurityDatabase() const
|
||||||
{
|
{
|
||||||
const char* strVal = get<const char*>(KEY_SECURITY_DATABASE);
|
const char* strVal = getStr(KEY_SECURITY_DATABASE);
|
||||||
if (!strVal)
|
if (!strVal)
|
||||||
{
|
{
|
||||||
strVal = MasterInterfacePtr()->getConfigManager()->getDefaultSecurityDb();
|
strVal = MasterInterfacePtr()->getConfigManager()->getDefaultSecurityDb();
|
||||||
@ -857,101 +986,96 @@ const char* Config::getSecurityDatabase() const
|
|||||||
|
|
||||||
int Config::getWireCrypt(WireCryptMode wcMode) const
|
int Config::getWireCrypt(WireCryptMode wcMode) const
|
||||||
{
|
{
|
||||||
const char* wc = get<const char*>(KEY_WIRE_CRYPT);
|
bool present;
|
||||||
if (!wc)
|
const char* wc = getStr(KEY_WIRE_CRYPT, &present);
|
||||||
|
if (present && wc)
|
||||||
{
|
{
|
||||||
return wcMode == WC_CLIENT ? WIRE_CRYPT_ENABLED : WIRE_CRYPT_REQUIRED;
|
NoCaseString wireCrypt(wc);
|
||||||
|
if (wireCrypt == "DISABLED")
|
||||||
|
return WIRE_CRYPT_DISABLED;
|
||||||
|
if (wireCrypt == "ENABLED")
|
||||||
|
return WIRE_CRYPT_ENABLED;
|
||||||
|
|
||||||
|
// the safest choice
|
||||||
|
return WIRE_CRYPT_REQUIRED;
|
||||||
}
|
}
|
||||||
|
|
||||||
NoCaseString wireCrypt(wc);
|
return wcMode == WC_CLIENT ? WIRE_CRYPT_ENABLED : WIRE_CRYPT_REQUIRED;
|
||||||
if (wireCrypt == "DISABLED")
|
|
||||||
return WIRE_CRYPT_DISABLED;
|
|
||||||
if (wireCrypt == "ENABLED")
|
|
||||||
return WIRE_CRYPT_ENABLED;
|
|
||||||
|
|
||||||
// the safest choice
|
|
||||||
return WIRE_CRYPT_REQUIRED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Config::getRemoteAccess() const
|
bool Config::getRemoteAccess() const
|
||||||
{
|
{
|
||||||
return get<bool>(KEY_REMOTE_ACCESS);
|
return getBool(KEY_REMOTE_ACCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Config::getWireCompression() const
|
bool Config::getWireCompression() const
|
||||||
{
|
{
|
||||||
return get<bool>(KEY_WIRE_COMPRESSION);
|
return getBool(KEY_WIRE_COMPRESSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Config::getMaxIdentifierByteLength() const
|
int Config::getMaxIdentifierByteLength() const
|
||||||
{
|
{
|
||||||
int rc = get<int>(KEY_MAX_IDENTIFIER_BYTE_LENGTH);
|
return getInt(KEY_MAX_IDENTIFIER_BYTE_LENGTH);
|
||||||
|
|
||||||
if (rc < 0)
|
|
||||||
rc = MAX_SQL_IDENTIFIER_LEN;
|
|
||||||
|
|
||||||
return MIN(MAX(rc, 1), MAX_SQL_IDENTIFIER_LEN);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int Config::getMaxIdentifierCharLength() const
|
int Config::getMaxIdentifierCharLength() const
|
||||||
{
|
{
|
||||||
int rc = get<int>(KEY_MAX_IDENTIFIER_CHAR_LENGTH);
|
return getInt(KEY_MAX_IDENTIFIER_CHAR_LENGTH);
|
||||||
|
|
||||||
if (rc < 0)
|
|
||||||
rc = METADATA_IDENTIFIER_CHAR_LEN;
|
|
||||||
|
|
||||||
return MIN(MAX(rc, 1), METADATA_IDENTIFIER_CHAR_LEN);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Config::getCryptSecurityDatabase() const
|
bool Config::getCryptSecurityDatabase() const
|
||||||
{
|
{
|
||||||
return get<bool>(KEY_ENCRYPT_SECURITY_DATABASE);
|
return getBool(KEY_ENCRYPT_SECURITY_DATABASE);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int Config::getStatementTimeout() const
|
unsigned int Config::getStatementTimeout() const
|
||||||
{
|
{
|
||||||
return get<unsigned int>(KEY_STMT_TIMEOUT);
|
return getInt(KEY_STMT_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int Config::getConnIdleTimeout() const
|
unsigned int Config::getConnIdleTimeout() const
|
||||||
{
|
{
|
||||||
return get<unsigned int>(KEY_CONN_IDLE_TIMEOUT);
|
return getInt(KEY_CONN_IDLE_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int Config::getClientBatchBuffer() const
|
unsigned int Config::getClientBatchBuffer() const
|
||||||
{
|
{
|
||||||
return get<unsigned int>(KEY_CLIENT_BATCH_BUFFER);
|
return getInt(KEY_CLIENT_BATCH_BUFFER);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* Config::getOutputRedirectionFile()
|
const char* Config::getOutputRedirectionFile()
|
||||||
{
|
{
|
||||||
const char* file = (const char*) (getDefaultConfig()->values[KEY_OUTPUT_REDIRECTION_FILE]);
|
return getDefaultConfig()->getStr(KEY_OUTPUT_REDIRECTION_FILE);
|
||||||
return file;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int Config::getExtConnPoolSize()
|
int Config::getExtConnPoolSize()
|
||||||
{
|
{
|
||||||
return getDefaultConfig()->get<int>(KEY_EXT_CONN_POOL_SIZE);
|
return getDefaultConfig()->getInt(KEY_EXT_CONN_POOL_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Config::getExtConnPoolLifeTime()
|
int Config::getExtConnPoolLifeTime()
|
||||||
{
|
{
|
||||||
return getDefaultConfig()->get<int>(KEY_EXT_CONN_POOL_LIFETIME);
|
return getDefaultConfig()->getInt(KEY_EXT_CONN_POOL_LIFETIME);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Config::getReadConsistency() const
|
bool Config::getReadConsistency() const
|
||||||
{
|
{
|
||||||
return get<bool>(KEY_READ_CONSISTENCY);
|
return getBool(KEY_READ_CONSISTENCY);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Config::getClearGTTAtRetaining() const
|
bool Config::getClearGTTAtRetaining() const
|
||||||
{
|
{
|
||||||
return get<bool>(KEY_CLEAR_GTT_RETAINING);
|
return getBool(KEY_CLEAR_GTT_RETAINING);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* Config::getDataTypeCompatibility() const
|
const char* Config::getDataTypeCompatibility() const
|
||||||
{
|
{
|
||||||
return get<const char*>(KEY_DATA_TYPE_COMPATIBILITY);
|
return getStr(KEY_DATA_TYPE_COMPATIBILITY);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Config::getUseFileSystemCache(bool* pPresent) const
|
||||||
|
{
|
||||||
|
return getBool(KEY_USE_FILESYSTEM_CACHE, pPresent);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Firebird
|
} // namespace Firebird
|
||||||
|
@ -87,7 +87,33 @@ const char* const CONFIG_FILE = "firebird.conf";
|
|||||||
class Config : public RefCounted, public GlobalStorage
|
class Config : public RefCounted, public GlobalStorage
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef IPTR ConfigValue;
|
//typedef IPTR ConfigValue;
|
||||||
|
struct ConfigValue
|
||||||
|
{
|
||||||
|
ConfigValue() : intVal(0) {};
|
||||||
|
ConfigValue(const char* val) : strVal(val) {};
|
||||||
|
ConfigValue(bool val) : boolVal(val) {};
|
||||||
|
ConfigValue(SINT64 val) : intVal(val) {};
|
||||||
|
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
|
enum ConfigKey
|
||||||
{
|
{
|
||||||
@ -159,6 +185,7 @@ public:
|
|||||||
KEY_READ_CONSISTENCY,
|
KEY_READ_CONSISTENCY,
|
||||||
KEY_CLEAR_GTT_RETAINING,
|
KEY_CLEAR_GTT_RETAINING,
|
||||||
KEY_DATA_TYPE_COMPATIBILITY,
|
KEY_DATA_TYPE_COMPATIBILITY,
|
||||||
|
KEY_USE_FILESYSTEM_CACHE,
|
||||||
MAX_CONFIG_KEY // keep it last
|
MAX_CONFIG_KEY // keep it last
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -182,21 +209,67 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
void loadValues(const ConfigFile& file);
|
void loadValues(const ConfigFile& file);
|
||||||
|
void setupDefaultConfig();
|
||||||
|
void checkValues();
|
||||||
|
|
||||||
template <typename T> T get(Config::ConfigKey key) const
|
// helper check-value functions
|
||||||
|
void checkIntForLoBound(ConfigKey key, SINT64 loBound, bool setDefault);
|
||||||
|
void checkIntForHiBound(ConfigKey key, SINT64 hiBound, bool setDefault);
|
||||||
|
|
||||||
|
const char* getStr(ConfigKey key, bool* pPresent = nullptr) const
|
||||||
{
|
{
|
||||||
return (T) values[key];
|
if (pPresent)
|
||||||
|
*pPresent = testKey(key);
|
||||||
|
|
||||||
|
return values[key].strVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const ConfigEntry entries[MAX_CONFIG_KEY];
|
bool getBool(ConfigKey key, bool* pPresent = nullptr) const
|
||||||
|
{
|
||||||
|
if (pPresent)
|
||||||
|
*pPresent = testKey(key);
|
||||||
|
|
||||||
|
return values[key].boolVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
SINT64 getInt(ConfigKey key, bool* pPresent = nullptr) const
|
||||||
|
{
|
||||||
|
if (pPresent)
|
||||||
|
*pPresent = testKey(key);
|
||||||
|
|
||||||
|
return values[key].intVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool valueAsString(ConfigValue val, ConfigType type, string& str);
|
||||||
|
|
||||||
|
static ConfigEntry entries[MAX_CONFIG_KEY];
|
||||||
|
|
||||||
ConfigValue values[MAX_CONFIG_KEY];
|
ConfigValue values[MAX_CONFIG_KEY];
|
||||||
|
|
||||||
|
// One bit per key: bit is set if corresponding key value was set in config
|
||||||
|
ULONG bits[MAX_CONFIG_KEY / BITS_PER_LONG + 1];
|
||||||
|
|
||||||
|
// test if given key value was set in config
|
||||||
|
bool testKey(unsigned int key) const
|
||||||
|
{
|
||||||
|
return bits[key / BITS_PER_LONG] & (1ul << key % BITS_PER_LONG);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set bit of given key that was set in config
|
||||||
|
void setKey(unsigned int key)
|
||||||
|
{
|
||||||
|
bits[key / BITS_PER_LONG] |= (1ul << key % BITS_PER_LONG);
|
||||||
|
}
|
||||||
|
|
||||||
mutable PathName notifyDatabase;
|
mutable PathName notifyDatabase;
|
||||||
|
|
||||||
|
// set in default config only
|
||||||
|
int serverMode;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit Config(const ConfigFile& file); // use to build default config
|
explicit Config(const ConfigFile& file); // use to build default config
|
||||||
Config(const ConfigFile& file, const Config& base); // use to build db-specific config
|
Config(const ConfigFile& file, const Config& base); // use to build db-specific config
|
||||||
Config(const ConfigFile& file, const Config& base, const PathName& notify); // use to build db-specific config with notifucation
|
Config(const ConfigFile& file, const Config& base, const PathName& notify); // use to build db-specific config with notification
|
||||||
~Config();
|
~Config();
|
||||||
|
|
||||||
// Call it when database with given config is created
|
// Call it when database with given config is created
|
||||||
@ -228,6 +301,21 @@ public:
|
|||||||
const char* getString(unsigned int key) const;
|
const char* getString(unsigned int key) const;
|
||||||
bool getBoolean(unsigned int key) const;
|
bool getBoolean(unsigned int key) const;
|
||||||
|
|
||||||
|
// Number of known keys
|
||||||
|
static unsigned int getKeyCount() { return MAX_CONFIG_KEY; };
|
||||||
|
static const char* getKeyName(unsigned int key)
|
||||||
|
{
|
||||||
|
if (key >= MAX_CONFIG_KEY)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return entries[key].key;
|
||||||
|
}
|
||||||
|
// false if value is null or key is not exists
|
||||||
|
bool getValue(unsigned int key, string& str) const;
|
||||||
|
static bool getDefaultValue(unsigned int key, string& str);
|
||||||
|
// return true if value is set at some level
|
||||||
|
bool getIsSet(unsigned int key) const { return testKey(key); }
|
||||||
|
|
||||||
// Static functions apply to instance-wide values,
|
// Static functions apply to instance-wide values,
|
||||||
// non-static may be specified per database.
|
// non-static may be specified per database.
|
||||||
|
|
||||||
@ -250,7 +338,7 @@ public:
|
|||||||
static int getGuardianOption();
|
static int getGuardianOption();
|
||||||
|
|
||||||
// CPU affinity mask
|
// CPU affinity mask
|
||||||
static int getCpuAffinityMask();
|
static FB_UINT64 getCpuAffinityMask();
|
||||||
|
|
||||||
// XDR buffer size
|
// XDR buffer size
|
||||||
static int getTcpRemoteBufferSize();
|
static int getTcpRemoteBufferSize();
|
||||||
@ -396,6 +484,8 @@ public:
|
|||||||
bool getClearGTTAtRetaining() const;
|
bool getClearGTTAtRetaining() const;
|
||||||
|
|
||||||
const char* getDataTypeCompatibility() const;
|
const char* getDataTypeCompatibility() const;
|
||||||
|
|
||||||
|
bool getUseFileSystemCache(bool* pPresent = nullptr) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Implementation of interface to access master configuration file
|
// Implementation of interface to access master configuration file
|
||||||
|
120
src/jrd/FBConfigTable.cpp
Normal file
120
src/jrd/FBConfigTable.cpp
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
/*
|
||||||
|
* The contents of this file are subject to the Initial
|
||||||
|
* Developer's Public License Version 1.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the
|
||||||
|
* License. You may obtain a copy of the License at
|
||||||
|
* http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl.
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed AS IS,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing rights
|
||||||
|
* and limitations under the License.
|
||||||
|
*
|
||||||
|
* The Original Code was created by Vladyslav Khorsun
|
||||||
|
* for the Firebird Open Source RDBMS project.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 Vladyslav Khorsun <hvlad@users.sf.net>
|
||||||
|
* and all contributors signed below.
|
||||||
|
*
|
||||||
|
* All Rights Reserved.
|
||||||
|
* Contributor(s): ______________________________________.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "../jrd/FBConfigTable.h"
|
||||||
|
#include "../jrd/ini.h"
|
||||||
|
#include "../jrd/ids.h"
|
||||||
|
|
||||||
|
using namespace Jrd;
|
||||||
|
using namespace Firebird;
|
||||||
|
|
||||||
|
|
||||||
|
/// class FBConfigTable
|
||||||
|
|
||||||
|
FBConfigTable::FBConfigTable(MemoryPool& pool, const Config* conf) :
|
||||||
|
SnapshotData(pool),
|
||||||
|
m_conf(conf)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
RecordBuffer* FBConfigTable::getRecords(thread_db* tdbb, jrd_rel* relation)
|
||||||
|
{
|
||||||
|
fb_assert(relation);
|
||||||
|
fb_assert(relation->rel_id == rel_cfg_table);
|
||||||
|
|
||||||
|
RecordBuffer* recordBuffer = getData(relation);
|
||||||
|
if (recordBuffer)
|
||||||
|
return recordBuffer;
|
||||||
|
|
||||||
|
recordBuffer = allocBuffer(tdbb, *tdbb->getDefaultPool(), relation->rel_id);
|
||||||
|
|
||||||
|
// Check privileges to see RDB$CONFIG
|
||||||
|
const Attachment* att = tdbb->getAttachment();
|
||||||
|
if (!att->att_user->locksmith(tdbb, SELECT_ANY_OBJECT_IN_DATABASE))
|
||||||
|
return recordBuffer;
|
||||||
|
|
||||||
|
for (unsigned int key = 0; key < Config::getKeyCount(); key++)
|
||||||
|
{
|
||||||
|
Record* rec = recordBuffer->getTempRecord();
|
||||||
|
rec->nullify();
|
||||||
|
|
||||||
|
putField(tdbb, rec, DumpField(f_cfg_id, VALUE_INTEGER, sizeof(key), &key));
|
||||||
|
|
||||||
|
const char* name = Config::getKeyName(key);
|
||||||
|
putField(tdbb, rec, DumpField(f_cfg_name, VALUE_STRING, strlen(name), name));
|
||||||
|
|
||||||
|
string str;
|
||||||
|
if (m_conf->getValue(key, str))
|
||||||
|
putField(tdbb, rec, DumpField(f_cfg_value, VALUE_STRING, str.length(), str.c_str()));
|
||||||
|
|
||||||
|
if (m_conf->getDefaultValue(key, str))
|
||||||
|
putField(tdbb, rec, DumpField(f_cfg_default, VALUE_STRING, str.length(), str.c_str()));
|
||||||
|
|
||||||
|
char set = m_conf->getIsSet(key) ? 1 : 0;
|
||||||
|
putField(tdbb, rec, DumpField(f_cfg_is_set, VALUE_BOOLEAN, 1, &set));
|
||||||
|
|
||||||
|
recordBuffer->store(rec);
|
||||||
|
}
|
||||||
|
|
||||||
|
return recordBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// class FBConfigTableScan
|
||||||
|
|
||||||
|
void FBConfigTableScan::close(thread_db* tdbb) const
|
||||||
|
{
|
||||||
|
jrd_req* const request = tdbb->getRequest();
|
||||||
|
Impure* const impure = request->getImpure<Impure>(m_impure);
|
||||||
|
|
||||||
|
delete impure->table;
|
||||||
|
impure->table = nullptr;
|
||||||
|
|
||||||
|
VirtualTableScan::close(tdbb);
|
||||||
|
}
|
||||||
|
|
||||||
|
const Format* FBConfigTableScan::getFormat(thread_db* tdbb, jrd_rel* relation) const
|
||||||
|
{
|
||||||
|
RecordBuffer* records = getRecords(tdbb, relation);
|
||||||
|
return records->getFormat();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FBConfigTableScan::retrieveRecord(thread_db* tdbb, jrd_rel* relation,
|
||||||
|
FB_UINT64 position, Record* record) const
|
||||||
|
{
|
||||||
|
RecordBuffer* records = getRecords(tdbb, relation);
|
||||||
|
return records->fetch(position, record);
|
||||||
|
}
|
||||||
|
|
||||||
|
RecordBuffer* FBConfigTableScan::getRecords(thread_db* tdbb, jrd_rel* relation) const
|
||||||
|
{
|
||||||
|
jrd_req* const request = tdbb->getRequest();
|
||||||
|
Impure* const impure = request->getImpure<Impure>(m_impure);
|
||||||
|
|
||||||
|
if (!impure->table)
|
||||||
|
{
|
||||||
|
MemoryPool* pool = tdbb->getDefaultPool();
|
||||||
|
impure->table = FB_NEW_POOL(*pool) FBConfigTable(*pool, tdbb->getDatabase()->dbb_config);
|
||||||
|
}
|
||||||
|
|
||||||
|
return impure->table->getRecords(tdbb, relation);
|
||||||
|
}
|
79
src/jrd/FBConfigTable.h
Normal file
79
src/jrd/FBConfigTable.h
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
* The contents of this file are subject to the Initial
|
||||||
|
* Developer's Public License Version 1.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the
|
||||||
|
* License. You may obtain a copy of the License at
|
||||||
|
* http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl.
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed AS IS,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing rights
|
||||||
|
* and limitations under the License.
|
||||||
|
*
|
||||||
|
* The Original Code was created by Vladyslav Khorsun
|
||||||
|
* for the Firebird Open Source RDBMS project.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 Vladyslav Khorsun <hvlad@users.sf.net>
|
||||||
|
* and all contributors signed below.
|
||||||
|
*
|
||||||
|
* All Rights Reserved.
|
||||||
|
* Contributor(s): ______________________________________.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef JRD_FBCONFIG_TABLE_H
|
||||||
|
#define JRD_FBCONFIG_TABLE_H
|
||||||
|
|
||||||
|
#include "firebird.h"
|
||||||
|
#include "../common/classes/fb_string.h"
|
||||||
|
#include "../jrd/Monitoring.h"
|
||||||
|
#include "../jrd/recsrc/RecordSource.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace Jrd
|
||||||
|
{
|
||||||
|
|
||||||
|
class FBConfigTable : public SnapshotData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FBConfigTable(MemoryPool& pool, const Firebird::Config* conf);
|
||||||
|
|
||||||
|
// return data for RDB$CONFIG
|
||||||
|
RecordBuffer* getRecords(thread_db* tdbb, jrd_rel* relation);
|
||||||
|
|
||||||
|
private:
|
||||||
|
const Firebird::Config* m_conf;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class FBConfigTableScan : public VirtualTableScan
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FBConfigTableScan(CompilerScratch* csb, const Firebird::string& alias,
|
||||||
|
StreamType stream, jrd_rel* relation)
|
||||||
|
: VirtualTableScan(csb, alias, stream, relation)
|
||||||
|
{
|
||||||
|
m_impure = csb->allocImpure<Impure>();
|
||||||
|
}
|
||||||
|
|
||||||
|
void close(thread_db* tdbb) const override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
const Format* getFormat(thread_db* tdbb, jrd_rel* relation) const override;
|
||||||
|
|
||||||
|
bool retrieveRecord(thread_db* tdbb, jrd_rel* relation, FB_UINT64 position,
|
||||||
|
Record* record) const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct Impure
|
||||||
|
{
|
||||||
|
FBConfigTable* table;
|
||||||
|
};
|
||||||
|
|
||||||
|
RecordBuffer* getRecords(thread_db* tdbb, jrd_rel* relation) const;
|
||||||
|
|
||||||
|
ULONG m_impure;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Jrd
|
||||||
|
|
||||||
|
#endif // JRD_FBCONFIG_TABLE_H
|
@ -213,3 +213,9 @@
|
|||||||
|
|
||||||
FIELD(fld_pub_name , nam_pub_name , dtype_text , MAX_SQL_IDENTIFIER_LEN , dsc_text_type_metadata , NULL , false)
|
FIELD(fld_pub_name , nam_pub_name , dtype_text , MAX_SQL_IDENTIFIER_LEN , dsc_text_type_metadata , NULL , false)
|
||||||
FIELD(fld_file_id , nam_file_id , dtype_varying , 255 , dsc_text_type_ascii , NULL , false)
|
FIELD(fld_file_id , nam_file_id , dtype_varying , 255 , dsc_text_type_ascii , NULL , false)
|
||||||
|
|
||||||
|
FIELD(fld_cfg_id , nam_cfg_id , dtype_long , sizeof(SLONG) , 0 , NULL , false)
|
||||||
|
FIELD(fld_cfg_name , nam_cfg_name , dtype_varying , MAX_SQL_IDENTIFIER_LEN , dsc_text_type_metadata , NULL , false)
|
||||||
|
FIELD(fld_cfg_value , nam_cfg_value , dtype_varying , 255 * METADATA_BYTES_PER_CHAR, dsc_text_type_metadata , NULL , true)
|
||||||
|
FIELD(fld_cfg_default , nam_cfg_default , dtype_varying , 255 * METADATA_BYTES_PER_CHAR, dsc_text_type_metadata , NULL , true)
|
||||||
|
FIELD(fld_cfg_is_set , nam_cfg_is_set , dtype_boolean , 1 , 0 , NULL , false)
|
||||||
|
@ -441,3 +441,10 @@ NAME("MON$FILE_ID", nam_mon_file_id)
|
|||||||
NAME("MON$GUID", nam_mon_guid)
|
NAME("MON$GUID", nam_mon_guid)
|
||||||
NAME("MON$NEXT_ATTACHMENT", nam_mon_na)
|
NAME("MON$NEXT_ATTACHMENT", nam_mon_na)
|
||||||
NAME("MON$NEXT_STATEMENT", nam_mon_ns)
|
NAME("MON$NEXT_STATEMENT", nam_mon_ns)
|
||||||
|
|
||||||
|
NAME("RDB$CONFIG", nam_cfg_table)
|
||||||
|
NAME("RDB$CONFIG_ID", nam_cfg_id)
|
||||||
|
NAME("RDB$CONFIG_NAME", nam_cfg_name)
|
||||||
|
NAME("RDB$CONFIG_VALUE", nam_cfg_value)
|
||||||
|
NAME("RDB$CONFIG_DEFAULT", nam_cfg_default)
|
||||||
|
NAME("RDB$CONFIG_IS_SET", nam_cfg_is_set)
|
||||||
|
@ -92,6 +92,7 @@
|
|||||||
#include "../dsql/BoolNodes.h"
|
#include "../dsql/BoolNodes.h"
|
||||||
#include "../dsql/ExprNodes.h"
|
#include "../dsql/ExprNodes.h"
|
||||||
#include "../dsql/StmtNodes.h"
|
#include "../dsql/StmtNodes.h"
|
||||||
|
#include "../jrd/FBConfigTable.h"
|
||||||
|
|
||||||
using namespace Jrd;
|
using namespace Jrd;
|
||||||
using namespace Firebird;
|
using namespace Firebird;
|
||||||
@ -2297,6 +2298,10 @@ static RecordSource* gen_retrieval(thread_db* tdbb,
|
|||||||
rsb = FB_NEW_POOL(*tdbb->getDefaultPool()) TimeZonesTableScan(csb, alias, stream, relation);
|
rsb = FB_NEW_POOL(*tdbb->getDefaultPool()) TimeZonesTableScan(csb, alias, stream, relation);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case rel_cfg_table:
|
||||||
|
rsb = FB_NEW_POOL(*tdbb->getDefaultPool()) FBConfigTableScan(csb, alias, stream, relation);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
rsb = FB_NEW_POOL(*tdbb->getDefaultPool()) MonitoringTableScan(csb, alias, stream, relation);
|
rsb = FB_NEW_POOL(*tdbb->getDefaultPool()) MonitoringTableScan(csb, alias, stream, relation);
|
||||||
break;
|
break;
|
||||||
|
@ -1164,8 +1164,15 @@ void PAG_header(thread_db* tdbb, bool info)
|
|||||||
Arg::Str(attachment->att_filename));
|
Arg::Str(attachment->att_filename));
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool useFSCache = dbb->dbb_bcb->bcb_count <
|
|
||||||
ULONG(dbb->dbb_config->getFileSystemCacheThreshold());
|
bool present;
|
||||||
|
bool useFSCache = dbb->dbb_config->getUseFileSystemCache(&present);
|
||||||
|
|
||||||
|
if (!present)
|
||||||
|
{
|
||||||
|
useFSCache = dbb->dbb_bcb->bcb_count <
|
||||||
|
ULONG(dbb->dbb_config->getFileSystemCacheThreshold());
|
||||||
|
}
|
||||||
|
|
||||||
if ((header->hdr_flags & hdr_force_write) || !useFSCache)
|
if ((header->hdr_flags & hdr_force_write) || !useFSCache)
|
||||||
{
|
{
|
||||||
|
@ -723,3 +723,12 @@ RELATION(nam_pub_tables, rel_pub_tables, ODS_13_0, rel_persistent)
|
|||||||
FIELD(f_pubtab_pub_name, nam_pub_name, fld_pub_name, 1, ODS_13_0)
|
FIELD(f_pubtab_pub_name, nam_pub_name, fld_pub_name, 1, ODS_13_0)
|
||||||
FIELD(f_pubtab_tab_name, nam_tab_name, fld_r_name, 1, ODS_13_0)
|
FIELD(f_pubtab_tab_name, nam_tab_name, fld_r_name, 1, ODS_13_0)
|
||||||
END_RELATION
|
END_RELATION
|
||||||
|
|
||||||
|
// Relation 53 (RDB$CONFIG)
|
||||||
|
RELATION(nam_cfg_table, rel_cfg_table, ODS_13_0, rel_virtual)
|
||||||
|
FIELD(f_cfg_id, nam_cfg_id, fld_cfg_id, 0, ODS_13_0)
|
||||||
|
FIELD(f_cfg_name, nam_cfg_name, fld_cfg_name, 0, ODS_13_0)
|
||||||
|
FIELD(f_cfg_value, nam_cfg_value, fld_cfg_value, 0, ODS_13_0)
|
||||||
|
FIELD(f_cfg_default, nam_cfg_default, fld_cfg_default, 0, ODS_13_0)
|
||||||
|
FIELD(f_cfg_is_set, nam_cfg_is_set, fld_cfg_is_set, 0, ODS_13_0)
|
||||||
|
END_RELATION
|
||||||
|
Loading…
Reference in New Issue
Block a user