8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-02-02 09:20:39 +01:00

Merge pull request #295 from FirebirdSQL/config

Config
This commit is contained in:
Vlad Khorsun 2020-11-12 22:33:18 +02:00 committed by GitHub
commit 95f96a18f6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 827 additions and 292 deletions

View File

@ -261,6 +261,18 @@
#
#DatabaseGrowthIncrement = 128M
# ----------------------------
# File system cache usage
#
# Determines whether Firebird will use file system cache for database files or
# not.
#
# Type: boolean
#
# Per-database configurable.
#
#UseFileSystemCache = true
# ----------------------------
# File system cache threshold
#
@ -273,6 +285,15 @@
# To bypass file system cache for all databases set FileSystemCacheThreshold to
# zero.
#
# CAUTION!
# This setting is deprecated and will be removed in future Firebird versions.
# Consider using "UseFileSystemCache" setting instead.
# If "UseFileSystemCache" is set, then value of "FileSystemCacheThreshold" is
# ignored.
# If "UseFileSystemCache" is not set, and "FileSystemCacheThreshold" is set
# then value of "FileSystemCacheThreshold" is in use and accounted by the
# engine.
#
# Type: integer, measured in database pages
#
# Per-database configurable.

View File

@ -62,6 +62,7 @@
<ClCompile Include="..\..\..\src\jrd\cmp.cpp" />
<ClCompile Include="..\..\..\src\jrd\Coercion.cpp" />
<ClCompile Include="..\..\..\src\jrd\Collation.cpp" />
<ClCompile Include="..\..\..\src\jrd\ConfigTable.cpp" />
<ClCompile Include="..\..\..\src\jrd\CryptoManager.cpp" />
<ClCompile Include="..\..\..\src\jrd\cvt.cpp" />
<ClCompile Include="..\..\..\src\jrd\cvt2.cpp" />
@ -219,6 +220,7 @@
<ClInclude Include="..\..\..\src\jrd\cmp_proto.h" />
<ClInclude Include="..\..\..\src\jrd\Coercion.h" />
<ClInclude Include="..\..\..\src\jrd\Collation.h" />
<ClInclude Include="..\..\..\src\jrd\ConfigTable.h" />
<ClInclude Include="..\..\..\src\jrd\constants.h" />
<ClInclude Include="..\..\..\src\jrd\CryptoManager.h" />
<ClInclude Include="..\..\..\src\jrd\cvt2_proto.h" />

View File

@ -222,6 +222,9 @@
<ClCompile Include="..\..\..\src\jrd\Collation.cpp">
<Filter>JRD files</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\jrd\ConfigTable.cpp">
<Filter>JRD files</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\jrd\cvt2.cpp">
<Filter>JRD files</Filter>
</ClCompile>
@ -671,6 +674,9 @@
<ClInclude Include="..\..\..\src\jrd\Collation.h">
<Filter>Header files</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\jrd\ConfigTable.h">
<Filter>Header files</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\jrd\constants.h">
<Filter>Header files</Filter>
</ClInclude>

View File

@ -62,6 +62,7 @@
<ClCompile Include="..\..\..\src\jrd\cmp.cpp" />
<ClCompile Include="..\..\..\src\jrd\Coercion.cpp" />
<ClCompile Include="..\..\..\src\jrd\Collation.cpp" />
<ClCompile Include="..\..\..\src\jrd\ConfigTable.cpp" />
<ClCompile Include="..\..\..\src\jrd\CryptoManager.cpp" />
<ClCompile Include="..\..\..\src\jrd\cvt.cpp" />
<ClCompile Include="..\..\..\src\jrd\cvt2.cpp" />
@ -220,6 +221,7 @@
<ClInclude Include="..\..\..\src\jrd\cmp_proto.h" />
<ClInclude Include="..\..\..\src\jrd\Coercion.h" />
<ClInclude Include="..\..\..\src\jrd\Collation.h" />
<ClInclude Include="..\..\..\src\jrd\ConfigTable.h" />
<ClInclude Include="..\..\..\src\jrd\constants.h" />
<ClInclude Include="..\..\..\src\jrd\CryptoManager.h" />
<ClInclude Include="..\..\..\src\jrd\cvt2_proto.h" />

View File

@ -222,6 +222,9 @@
<ClCompile Include="..\..\..\src\jrd\Collation.cpp">
<Filter>JRD files</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\jrd\ConfigTable.cpp">
<Filter>JRD files</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\jrd\cvt2.cpp">
<Filter>JRD files</Filter>
</ClCompile>
@ -674,6 +677,9 @@
<ClInclude Include="..\..\..\src\jrd\Collation.h">
<Filter>Header files</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\jrd\ConfigTable.h">
<Filter>Header files</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\jrd\constants.h">
<Filter>Header files</Filter>
</ClInclude>

View File

@ -62,6 +62,7 @@
<ClCompile Include="..\..\..\src\jrd\cmp.cpp" />
<ClCompile Include="..\..\..\src\jrd\Coercion.cpp" />
<ClCompile Include="..\..\..\src\jrd\Collation.cpp" />
<ClCompile Include="..\..\..\src\jrd\ConfigTable.cpp" />
<ClCompile Include="..\..\..\src\jrd\CryptoManager.cpp" />
<ClCompile Include="..\..\..\src\jrd\cvt.cpp" />
<ClCompile Include="..\..\..\src\jrd\cvt2.cpp" />
@ -220,6 +221,7 @@
<ClInclude Include="..\..\..\src\jrd\cmp_proto.h" />
<ClInclude Include="..\..\..\src\jrd\Coercion.h" />
<ClInclude Include="..\..\..\src\jrd\Collation.h" />
<ClInclude Include="..\..\..\src\jrd\ConfigTable.h" />
<ClInclude Include="..\..\..\src\jrd\constants.h" />
<ClInclude Include="..\..\..\src\jrd\CryptoManager.h" />
<ClInclude Include="..\..\..\src\jrd\cvt2_proto.h" />

View File

@ -222,6 +222,9 @@
<ClCompile Include="..\..\..\src\jrd\Collation.cpp">
<Filter>JRD files</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\jrd\ConfigTable.cpp">
<Filter>JRD files</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\jrd\cvt2.cpp">
<Filter>JRD files</Filter>
</ClCompile>
@ -674,6 +677,9 @@
<ClInclude Include="..\..\..\src\jrd\Collation.h">
<Filter>Header files</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\jrd\ConfigTable.h">
<Filter>Header files</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\jrd\constants.h">
<Filter>Header files</Filter>
</ClInclude>

File diff suppressed because it is too large Load Diff

View File

@ -87,7 +87,34 @@ const char* const CONFIG_FILE = "firebird.conf";
class Config : public RefCounted, public GlobalStorage
{
public:
typedef IPTR ConfigValue;
//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
{
@ -159,6 +186,7 @@ public:
KEY_READ_CONSISTENCY,
KEY_CLEAR_GTT_RETAINING,
KEY_DATA_TYPE_COMPATIBILITY,
KEY_USE_FILESYSTEM_CACHE,
MAX_CONFIG_KEY // keep it last
};
@ -181,22 +209,66 @@ private:
ConfigValue default_value;
};
void loadValues(const ConfigFile& file);
static ConfigValue specialProcessing(ConfigKey key, ConfigValue val);
template <typename T> T get(Config::ConfigKey key) const
void loadValues(const ConfigFile& file, const char* srcName);
void setupDefaultConfig();
void checkValues();
// 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 specialProcessing(key, values[key]).strVal;
}
static const ConfigEntry entries[MAX_CONFIG_KEY];
bool getBool(ConfigKey key, bool* pPresent = nullptr) const
{
if (pPresent)
*pPresent = testKey(key);
return specialProcessing(key, values[key]).boolVal;
}
SINT64 getInt(ConfigKey key, bool* pPresent = nullptr) const
{
if (pPresent)
*pPresent = testKey(key);
return specialProcessing(key, values[key]).intVal;
}
static bool valueAsString(ConfigValue val, ConfigType type, string& str);
static ConfigEntry entries[MAX_CONFIG_KEY];
ConfigValue values[MAX_CONFIG_KEY];
// Array of value source names, NULL item is for default value
HalfStaticArray<const char*, 4> valuesSource;
// Index of value source, zero if not set
UCHAR sourceIdx[MAX_CONFIG_KEY];
// test if given key value was set in config
bool testKey(unsigned int key) const
{
return sourceIdx[key] != 0;
}
mutable PathName notifyDatabase;
// set in default config only
int serverMode;
public:
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, const PathName& notify); // use to build db-specific config with notifucation
Config(const ConfigFile& file, const char* srcName, const Config& base, const PathName& notify = ""); // use to build db-specific config with notification
~Config();
// Call it when database with given config is created
@ -228,6 +300,31 @@ public:
const char* getString(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); }
const char* getValueSource(unsigned int key) const
{
return valuesSource[sourceIdx[key]];
}
// Static functions apply to instance-wide values,
// non-static may be specified per database.
@ -250,7 +347,7 @@ public:
static int getGuardianOption();
// CPU affinity mask
static int getCpuAffinityMask();
static FB_UINT64 getCpuAffinityMask();
// XDR buffer size
static int getTcpRemoteBufferSize();
@ -396,6 +493,8 @@ public:
bool getClearGTTAtRetaining() const;
const char* getDataTypeCompatibility() const;
bool getUseFileSystemCache(bool* pPresent = nullptr) const;
};
// Implementation of interface to access master configuration file

View File

@ -276,6 +276,13 @@ namespace
{
clear();
PathName confName = getFileName();
const char* rootDir = Config::getRootDirectory();
const FB_SIZE_T rootLen = strlen(rootDir);
if ((confName.length() > rootLen) && (confName.compare(0, rootLen, rootDir, rootLen) == 0))
confName.erase(0, rootLen);
ConfigFile aliasConfig(getFileName(), ConfigFile::HAS_SUB_CONF, this);
const ConfigFile::Parameters& params = aliasConfig.getParameters();
@ -330,9 +337,9 @@ namespace
db->config =
#ifdef HAVE_ID_BY_NAME
(!db->id) ?
FB_NEW Config(*par->sub, *Config::getDefaultConfig(), db->name) :
FB_NEW Config(*par->sub, confName.c_str(), *Config::getDefaultConfig(), db->name) :
#endif
FB_NEW Config(*par->sub, *Config::getDefaultConfig());
FB_NEW Config(*par->sub, confName.c_str(), *Config::getDefaultConfig());
}
PathName correctedAlias(par->name.ToPathName());

125
src/jrd/ConfigTable.cpp Normal file
View File

@ -0,0 +1,125 @@
/*
* 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/ConfigTable.h"
#include "../jrd/ini.h"
#include "../jrd/ids.h"
using namespace Jrd;
using namespace Firebird;
/// class ConfigTable
ConfigTable::ConfigTable(MemoryPool& pool, const Config* conf) :
SnapshotData(pool),
m_conf(conf)
{
}
RecordBuffer* ConfigTable::getRecords(thread_db* tdbb, jrd_rel* relation)
{
fb_assert(relation);
fb_assert(relation->rel_id == rel_config);
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();
SINT64 id = key;
putField(tdbb, rec, DumpField(f_cfg_id, VALUE_INTEGER, sizeof(id), &id));
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));
const char* valSrc = m_conf->getValueSource(key);
if (valSrc)
putField(tdbb, rec, DumpField(f_cfg_source, VALUE_STRING, strlen(valSrc), valSrc));
recordBuffer->store(rec);
}
return recordBuffer;
}
/// class ConfigTableScan
void ConfigTableScan::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* ConfigTableScan::getFormat(thread_db* tdbb, jrd_rel* relation) const
{
RecordBuffer* records = getRecords(tdbb, relation);
return records->getFormat();
}
bool ConfigTableScan::retrieveRecord(thread_db* tdbb, jrd_rel* relation,
FB_UINT64 position, Record* record) const
{
RecordBuffer* records = getRecords(tdbb, relation);
return records->fetch(position, record);
}
RecordBuffer* ConfigTableScan::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) ConfigTable(*pool, tdbb->getDatabase()->dbb_config);
}
return impure->table->getRecords(tdbb, relation);
}

79
src/jrd/ConfigTable.h Normal file
View 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_CONFIG_TABLE_H
#define JRD_CONFIG_TABLE_H
#include "firebird.h"
#include "../common/classes/fb_string.h"
#include "../jrd/Monitoring.h"
#include "../jrd/recsrc/RecordSource.h"
namespace Jrd
{
class ConfigTable : public SnapshotData
{
public:
ConfigTable(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 ConfigTableScan : public VirtualTableScan
{
public:
ConfigTableScan(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
{
ConfigTable* table;
};
RecordBuffer* getRecords(thread_db* tdbb, jrd_rel* relation) const;
ULONG m_impure;
};
} // namespace Jrd
#endif // JRD_CONFIG_TABLE_H

View File

@ -81,8 +81,7 @@ namespace EDS {
GlobalPtr<Manager> Manager::manager;
Mutex Manager::m_mutex;
Provider* Manager::m_providers = NULL;
volatile bool Manager::m_initialized = false;
ConnectionsPool* Manager::m_connPool;
ConnectionsPool* Manager::m_connPool = NULL;
const ULONG MIN_CONNPOOL_SIZE = 0;
const ULONG MAX_CONNPOOL_SIZE = 1000;
@ -93,12 +92,12 @@ const ULONG MAX_LIFE_TIME = 60 * 60 * 24; // one day
Manager::Manager(MemoryPool& pool) :
PermanentStorage(pool)
{
m_connPool = FB_NEW_POOL(pool) ConnectionsPool(pool);
//m_connPool = FB_NEW_POOL(pool) ConnectionsPool(pool);
}
Manager::~Manager()
{
fb_assert(m_connPool->getAllCount() == 0);
fb_assert(!m_connPool || m_connPool->getAllCount() == 0);
ThreadContextHolder tdbb;
@ -111,6 +110,7 @@ Manager::~Manager()
}
delete m_connPool;
m_connPool = NULL;
}
void Manager::addProvider(Provider* provider)
@ -209,6 +209,9 @@ Connection* Manager::getConnection(thread_db* tdbb, const string& dataSource,
// if could be pooled, ask connections pool
if (!m_connPool)
m_connPool = FB_NEW_POOL(manager->getPool()) ConnectionsPool(manager->getPool());
ULONG hash = 0;
if (!isCurrent)
@ -256,7 +259,8 @@ int Manager::shutdown()
FbLocalStatus status;
ThreadContextHolder tdbb(&status);
m_connPool->clear(tdbb);
if (m_connPool)
m_connPool->clear(tdbb);
for (Provider* prv = m_providers; prv; prv = prv->m_next) {
prv->cancelConnections();

View File

@ -92,7 +92,6 @@ private:
static Firebird::GlobalPtr<Manager> manager;
static Firebird::Mutex m_mutex;
static Provider* m_providers;
static volatile bool m_initialized;
static ConnectionsPool* m_connPool;
};

View File

@ -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_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)

View File

@ -441,3 +441,11 @@ NAME("MON$FILE_ID", nam_mon_file_id)
NAME("MON$GUID", nam_mon_guid)
NAME("MON$NEXT_ATTACHMENT", nam_mon_na)
NAME("MON$NEXT_STATEMENT", nam_mon_ns)
NAME("RDB$CONFIG", nam_config)
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)
NAME("RDB$CONFIG_SOURCE", nam_cfg_source)

View File

@ -92,6 +92,7 @@
#include "../dsql/BoolNodes.h"
#include "../dsql/ExprNodes.h"
#include "../dsql/StmtNodes.h"
#include "../jrd/ConfigTable.h"
using namespace Jrd;
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);
break;
case rel_config:
rsb = FB_NEW_POOL(*tdbb->getDefaultPool()) ConfigTableScan(csb, alias, stream, relation);
break;
default:
rsb = FB_NEW_POOL(*tdbb->getDefaultPool()) MonitoringTableScan(csb, alias, stream, relation);
break;

View File

@ -1164,8 +1164,15 @@ void PAG_header(thread_db* tdbb, bool info)
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)
{

View File

@ -723,3 +723,13 @@ 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_tab_name, nam_tab_name, fld_r_name, 1, ODS_13_0)
END_RELATION
// Relation 53 (RDB$CONFIG)
RELATION(nam_config, rel_config, 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)
FIELD(f_cfg_source, nam_cfg_source, fld_file_name2, 0, ODS_13_0)
END_RELATION

View File

@ -471,7 +471,7 @@ int gsec(Firebird::UtilSvc* uSvc)
databaseText.printf("SecurityDatabase = %s\n", databaseName.c_str());
ConfigFile gsecDatabase(ConfigFile::USE_TEXT, databaseText.c_str());
Firebird::RefPtr<const Firebird::Config> defaultConfig(Firebird::Config::getDefaultConfig());
Firebird::RefPtr<const Firebird::Config> pseudoConfig(FB_NEW Firebird::Config(gsecDatabase, *defaultConfig));
Firebird::RefPtr<const Firebird::Config> pseudoConfig(FB_NEW Firebird::Config(gsecDatabase, "<gsec DPB>", *defaultConfig));
uSvc->checkService();