mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-22 22:43:03 +01:00
Extend format of firebird configuration file with a set of additional parameters for any parameter.
Use traditional firebird configuration files format in all places (intl, trace, etc.). Add per-database configuration facility to aliases.conf (currently 15 parameters from firebird.conf).
This commit is contained in:
parent
d581d5384f
commit
e5017f1a12
@ -1,377 +1,377 @@
|
||||
<intl_module builtin>
|
||||
icu_versions default
|
||||
</intl_module>
|
||||
intl_module = builtin {
|
||||
icu_versions = default
|
||||
}
|
||||
|
||||
<intl_module fbintl>
|
||||
filename $(this)/fbintl
|
||||
icu_versions default
|
||||
</intl_module>
|
||||
intl_module = fbintl {
|
||||
filename = $(this)/fbintl
|
||||
icu_versions = default
|
||||
}
|
||||
|
||||
<charset SJIS_0208>
|
||||
intl_module fbintl
|
||||
collation SJIS_0208
|
||||
collation SJIS_0208_UNICODE
|
||||
</charset>
|
||||
charset = SJIS_0208 {
|
||||
intl_module = fbintl
|
||||
collation = SJIS_0208
|
||||
collation = SJIS_0208_UNICODE
|
||||
}
|
||||
|
||||
<charset EUCJ_0208>
|
||||
intl_module fbintl
|
||||
collation EUCJ_0208
|
||||
collation EUCJ_0208_UNICODE
|
||||
</charset>
|
||||
charset = EUCJ_0208 {
|
||||
intl_module = fbintl
|
||||
collation = EUCJ_0208
|
||||
collation = EUCJ_0208_UNICODE
|
||||
}
|
||||
|
||||
<charset DOS437>
|
||||
intl_module fbintl
|
||||
collation DOS437
|
||||
collation DOS437_UNICODE
|
||||
collation DB_DEU437
|
||||
collation DB_ESP437
|
||||
collation DB_FIN437
|
||||
collation DB_FRA437
|
||||
collation DB_ITA437
|
||||
collation DB_NLD437
|
||||
collation DB_SVE437
|
||||
collation DB_UK437
|
||||
collation DB_US437
|
||||
collation PDOX_ASCII
|
||||
collation PDOX_INTL
|
||||
collation PDOX_SWEDFIN
|
||||
</charset>
|
||||
charset = DOS437 {
|
||||
intl_module = fbintl
|
||||
collation = DOS437
|
||||
collation = DOS437_UNICODE
|
||||
collation = DB_DEU437
|
||||
collation = DB_ESP437
|
||||
collation = DB_FIN437
|
||||
collation = DB_FRA437
|
||||
collation = DB_ITA437
|
||||
collation = DB_NLD437
|
||||
collation = DB_SVE437
|
||||
collation = DB_UK437
|
||||
collation = DB_US437
|
||||
collation = PDOX_ASCII
|
||||
collation = PDOX_INTL
|
||||
collation = PDOX_SWEDFIN
|
||||
}
|
||||
|
||||
<charset DOS850>
|
||||
intl_module fbintl
|
||||
collation DOS850
|
||||
collation DOS850_UNICODE
|
||||
collation DB_DEU850
|
||||
collation DB_ESP850
|
||||
collation DB_FRA850
|
||||
collation DB_FRC850
|
||||
collation DB_ITA850
|
||||
collation DB_NLD850
|
||||
collation DB_PTB850
|
||||
collation DB_SVE850
|
||||
collation DB_UK850
|
||||
collation DB_US850
|
||||
</charset>
|
||||
charset = DOS850 {
|
||||
intl_module = fbintl
|
||||
collation = DOS850
|
||||
collation = DOS850_UNICODE
|
||||
collation = DB_DEU850
|
||||
collation = DB_ESP850
|
||||
collation = DB_FRA850
|
||||
collation = DB_FRC850
|
||||
collation = DB_ITA850
|
||||
collation = DB_NLD850
|
||||
collation = DB_PTB850
|
||||
collation = DB_SVE850
|
||||
collation = DB_UK850
|
||||
collation = DB_US850
|
||||
}
|
||||
|
||||
<charset DOS865>
|
||||
intl_module fbintl
|
||||
collation DOS865
|
||||
collation DOS865_UNICODE
|
||||
collation DB_DAN865
|
||||
collation DB_NOR865
|
||||
collation PDOX_NORDAN4
|
||||
</charset>
|
||||
charset = DOS865 {
|
||||
intl_module = fbintl
|
||||
collation = DOS865
|
||||
collation = DOS865_UNICODE
|
||||
collation = DB_DAN865
|
||||
collation = DB_NOR865
|
||||
collation = PDOX_NORDAN4
|
||||
}
|
||||
|
||||
<charset ISO8859_1>
|
||||
intl_module fbintl
|
||||
collation ISO8859_1
|
||||
collation ISO8859_1_UNICODE
|
||||
collation DA_DA
|
||||
collation DE_DE
|
||||
collation DU_NL
|
||||
collation EN_UK
|
||||
collation EN_US
|
||||
collation ES_ES
|
||||
collation ES_ES_CI_AI
|
||||
collation FI_FI
|
||||
collation FR_CA
|
||||
collation FR_FR
|
||||
collation IS_IS
|
||||
collation IT_IT
|
||||
collation NO_NO
|
||||
collation SV_SV
|
||||
collation PT_BR
|
||||
collation PT_PT
|
||||
</charset>
|
||||
charset = ISO8859_1 {
|
||||
intl_module = fbintl
|
||||
collation = ISO8859_1
|
||||
collation = ISO8859_1_UNICODE
|
||||
collation = DA_DA
|
||||
collation = DE_DE
|
||||
collation = DU_NL
|
||||
collation = EN_UK
|
||||
collation = EN_US
|
||||
collation = ES_ES
|
||||
collation = ES_ES_CI_AI
|
||||
collation = FI_FI
|
||||
collation = FR_CA
|
||||
collation = FR_FR
|
||||
collation = IS_IS
|
||||
collation = IT_IT
|
||||
collation = NO_NO
|
||||
collation = SV_SV
|
||||
collation = PT_BR
|
||||
collation = PT_PT
|
||||
}
|
||||
|
||||
<charset ISO8859_2>
|
||||
intl_module fbintl
|
||||
collation ISO8859_2
|
||||
collation ISO8859_2_UNICODE
|
||||
collation CS_CZ
|
||||
collation ISO_HUN
|
||||
collation ISO_PLK
|
||||
</charset>
|
||||
charset = ISO8859_2 {
|
||||
intl_module = fbintl
|
||||
collation = ISO8859_2
|
||||
collation = ISO8859_2_UNICODE
|
||||
collation = CS_CZ
|
||||
collation = ISO_HUN
|
||||
collation = ISO_PLK
|
||||
}
|
||||
|
||||
<charset ISO8859_3>
|
||||
intl_module fbintl
|
||||
collation ISO8859_3
|
||||
collation ISO8859_3_UNICODE
|
||||
</charset>
|
||||
charset = ISO8859_3 {
|
||||
intl_module = fbintl
|
||||
collation = ISO8859_3
|
||||
collation = ISO8859_3_UNICODE
|
||||
}
|
||||
|
||||
<charset ISO8859_4>
|
||||
intl_module fbintl
|
||||
collation ISO8859_4
|
||||
collation ISO8859_4_UNICODE
|
||||
</charset>
|
||||
charset = ISO8859_4 {
|
||||
intl_module = fbintl
|
||||
collation = ISO8859_4
|
||||
collation = ISO8859_4_UNICODE
|
||||
}
|
||||
|
||||
<charset ISO8859_5>
|
||||
intl_module fbintl
|
||||
collation ISO8859_5
|
||||
collation ISO8859_5_UNICODE
|
||||
</charset>
|
||||
charset = ISO8859_5 {
|
||||
intl_module = fbintl
|
||||
collation = ISO8859_5
|
||||
collation = ISO8859_5_UNICODE
|
||||
}
|
||||
|
||||
<charset ISO8859_6>
|
||||
intl_module fbintl
|
||||
collation ISO8859_6
|
||||
collation ISO8859_6_UNICODE
|
||||
</charset>
|
||||
charset = ISO8859_6 {
|
||||
intl_module = fbintl
|
||||
collation = ISO8859_6
|
||||
collation = ISO8859_6_UNICODE
|
||||
}
|
||||
|
||||
<charset ISO8859_7>
|
||||
intl_module fbintl
|
||||
collation ISO8859_7
|
||||
collation ISO8859_7_UNICODE
|
||||
</charset>
|
||||
charset = ISO8859_7 {
|
||||
intl_module = fbintl
|
||||
collation = ISO8859_7
|
||||
collation = ISO8859_7_UNICODE
|
||||
}
|
||||
|
||||
<charset ISO8859_8>
|
||||
intl_module fbintl
|
||||
collation ISO8859_8
|
||||
collation ISO8859_8_UNICODE
|
||||
</charset>
|
||||
charset = ISO8859_8 {
|
||||
intl_module = fbintl
|
||||
collation = ISO8859_8
|
||||
collation = ISO8859_8_UNICODE
|
||||
}
|
||||
|
||||
<charset ISO8859_9>
|
||||
intl_module fbintl
|
||||
collation ISO8859_9
|
||||
collation ISO8859_9_UNICODE
|
||||
</charset>
|
||||
charset = ISO8859_9 {
|
||||
intl_module = fbintl
|
||||
collation = ISO8859_9
|
||||
collation = ISO8859_9_UNICODE
|
||||
}
|
||||
|
||||
<charset ISO8859_13>
|
||||
intl_module fbintl
|
||||
collation ISO8859_13
|
||||
collation ISO8859_13_UNICODE
|
||||
collation LT_LT
|
||||
</charset>
|
||||
charset = ISO8859_13 {
|
||||
intl_module = fbintl
|
||||
collation = ISO8859_13
|
||||
collation = ISO8859_13_UNICODE
|
||||
collation = LT_LT
|
||||
}
|
||||
|
||||
<charset DOS852>
|
||||
intl_module fbintl
|
||||
collation DOS852
|
||||
collation DOS852_UNICODE
|
||||
collation DB_CSY
|
||||
collation DB_PLK
|
||||
collation DB_SLO
|
||||
collation PDOX_CSY
|
||||
collation PDOX_HUN
|
||||
collation PDOX_PLK
|
||||
collation PDOX_SLO
|
||||
</charset>
|
||||
charset = DOS852 {
|
||||
intl_module = fbintl
|
||||
collation = DOS852
|
||||
collation = DOS852_UNICODE
|
||||
collation = DB_CSY
|
||||
collation = DB_PLK
|
||||
collation = DB_SLO
|
||||
collation = PDOX_CSY
|
||||
collation = PDOX_HUN
|
||||
collation = PDOX_PLK
|
||||
collation = PDOX_SLO
|
||||
}
|
||||
|
||||
<charset DOS857>
|
||||
intl_module fbintl
|
||||
collation DOS857
|
||||
collation DOS857_UNICODE
|
||||
collation DB_TRK
|
||||
</charset>
|
||||
charset = DOS857 {
|
||||
intl_module = fbintl
|
||||
collation = DOS857
|
||||
collation = DOS857_UNICODE
|
||||
collation = DB_TRK
|
||||
}
|
||||
|
||||
<charset DOS860>
|
||||
intl_module fbintl
|
||||
collation DOS860
|
||||
collation DOS860_UNICODE
|
||||
collation DB_PTG860
|
||||
</charset>
|
||||
charset = DOS860 {
|
||||
intl_module = fbintl
|
||||
collation = DOS860
|
||||
collation = DOS860_UNICODE
|
||||
collation = DB_PTG860
|
||||
}
|
||||
|
||||
<charset DOS861>
|
||||
intl_module fbintl
|
||||
collation DOS861
|
||||
collation DOS861_UNICODE
|
||||
collation PDOX_ISL
|
||||
</charset>
|
||||
charset = DOS861 {
|
||||
intl_module = fbintl
|
||||
collation = DOS861
|
||||
collation = DOS861_UNICODE
|
||||
collation = PDOX_ISL
|
||||
}
|
||||
|
||||
<charset DOS863>
|
||||
intl_module fbintl
|
||||
collation DOS863
|
||||
collation DOS863_UNICODE
|
||||
collation DB_FRC863
|
||||
</charset>
|
||||
charset = DOS863 {
|
||||
intl_module = fbintl
|
||||
collation = DOS863
|
||||
collation = DOS863_UNICODE
|
||||
collation = DB_FRC863
|
||||
}
|
||||
|
||||
<charset CYRL>
|
||||
intl_module fbintl
|
||||
collation CYRL
|
||||
collation CYRL_UNICODE
|
||||
collation DB_RUS
|
||||
collation PDOX_CYRL
|
||||
</charset>
|
||||
charset = CYRL {
|
||||
intl_module = fbintl
|
||||
collation = CYRL
|
||||
collation = CYRL_UNICODE
|
||||
collation = DB_RUS
|
||||
collation = PDOX_CYRL
|
||||
}
|
||||
|
||||
<charset DOS737>
|
||||
intl_module fbintl
|
||||
collation DOS737
|
||||
collation DOS737_UNICODE
|
||||
</charset>
|
||||
charset = DOS737 {
|
||||
intl_module = fbintl
|
||||
collation = DOS737
|
||||
collation = DOS737_UNICODE
|
||||
}
|
||||
|
||||
<charset DOS775>
|
||||
intl_module fbintl
|
||||
collation DOS775
|
||||
collation DOS775_UNICODE
|
||||
</charset>
|
||||
charset = DOS775 {
|
||||
intl_module = fbintl
|
||||
collation = DOS775
|
||||
collation = DOS775_UNICODE
|
||||
}
|
||||
|
||||
<charset DOS858>
|
||||
intl_module fbintl
|
||||
collation DOS858
|
||||
collation DOS858_UNICODE
|
||||
</charset>
|
||||
charset = DOS858 {
|
||||
intl_module = fbintl
|
||||
collation = DOS858
|
||||
collation = DOS858_UNICODE
|
||||
}
|
||||
|
||||
<charset DOS862>
|
||||
intl_module fbintl
|
||||
collation DOS862
|
||||
collation DOS862_UNICODE
|
||||
</charset>
|
||||
charset = DOS862 {
|
||||
intl_module = fbintl
|
||||
collation = DOS862
|
||||
collation = DOS862_UNICODE
|
||||
}
|
||||
|
||||
<charset DOS864>
|
||||
intl_module fbintl
|
||||
collation DOS864
|
||||
collation DOS864_UNICODE
|
||||
</charset>
|
||||
charset = DOS864 {
|
||||
intl_module = fbintl
|
||||
collation = DOS864
|
||||
collation = DOS864_UNICODE
|
||||
}
|
||||
|
||||
<charset DOS866>
|
||||
intl_module fbintl
|
||||
collation DOS866
|
||||
collation DOS866_UNICODE
|
||||
</charset>
|
||||
charset = DOS866 {
|
||||
intl_module = fbintl
|
||||
collation = DOS866
|
||||
collation = DOS866_UNICODE
|
||||
}
|
||||
|
||||
<charset DOS869>
|
||||
intl_module fbintl
|
||||
collation DOS869
|
||||
collation DOS869_UNICODE
|
||||
</charset>
|
||||
charset = DOS869 {
|
||||
intl_module = fbintl
|
||||
collation = DOS869
|
||||
collation = DOS869_UNICODE
|
||||
}
|
||||
|
||||
<charset WIN1250>
|
||||
intl_module fbintl
|
||||
collation WIN1250
|
||||
collation WIN1250_UNICODE
|
||||
collation PXW_CSY
|
||||
collation PXW_HUN
|
||||
collation PXW_HUNDC
|
||||
collation PXW_PLK
|
||||
collation PXW_SLOV
|
||||
collation BS_BA
|
||||
collation WIN_CZ
|
||||
collation WIN_CZ_CI_AI
|
||||
</charset>
|
||||
charset = WIN1250 {
|
||||
intl_module = fbintl
|
||||
collation = WIN1250
|
||||
collation = WIN1250_UNICODE
|
||||
collation = PXW_CSY
|
||||
collation = PXW_HUN
|
||||
collation = PXW_HUNDC
|
||||
collation = PXW_PLK
|
||||
collation = PXW_SLOV
|
||||
collation = BS_BA
|
||||
collation = WIN_CZ
|
||||
collation = WIN_CZ_CI_AI
|
||||
}
|
||||
|
||||
<charset WIN1251>
|
||||
intl_module fbintl
|
||||
collation WIN1251
|
||||
collation WIN1251_UNICODE
|
||||
collation PXW_CYRL
|
||||
collation WIN1251_UA
|
||||
</charset>
|
||||
charset = WIN1251 {
|
||||
intl_module = fbintl
|
||||
collation = WIN1251
|
||||
collation = WIN1251_UNICODE
|
||||
collation = PXW_CYRL
|
||||
collation = WIN1251_UA
|
||||
}
|
||||
|
||||
<charset WIN1252>
|
||||
intl_module fbintl
|
||||
collation WIN1252
|
||||
collation WIN1252_UNICODE
|
||||
collation PXW_INTL
|
||||
collation PXW_INTL850
|
||||
collation PXW_NORDAN4
|
||||
collation WIN_PTBR
|
||||
collation PXW_SPAN
|
||||
collation PXW_SWEDFIN
|
||||
</charset>
|
||||
charset = WIN1252 {
|
||||
intl_module = fbintl
|
||||
collation = WIN1252
|
||||
collation = WIN1252_UNICODE
|
||||
collation = PXW_INTL
|
||||
collation = PXW_INTL850
|
||||
collation = PXW_NORDAN4
|
||||
collation = WIN_PTBR
|
||||
collation = PXW_SPAN
|
||||
collation = PXW_SWEDFIN
|
||||
}
|
||||
|
||||
<charset WIN1253>
|
||||
intl_module fbintl
|
||||
collation WIN1253
|
||||
collation WIN1253_UNICODE
|
||||
collation PXW_GREEK
|
||||
</charset>
|
||||
charset = WIN1253 {
|
||||
intl_module = fbintl
|
||||
collation = WIN1253
|
||||
collation = WIN1253_UNICODE
|
||||
collation = PXW_GREEK
|
||||
}
|
||||
|
||||
<charset WIN1254>
|
||||
intl_module fbintl
|
||||
collation WIN1254
|
||||
collation WIN1254_UNICODE
|
||||
collation PXW_TURK
|
||||
</charset>
|
||||
charset = WIN1254 {
|
||||
intl_module = fbintl
|
||||
collation = WIN1254
|
||||
collation = WIN1254_UNICODE
|
||||
collation = PXW_TURK
|
||||
}
|
||||
|
||||
<charset NEXT>
|
||||
intl_module fbintl
|
||||
collation NEXT
|
||||
collation NEXT_UNICODE
|
||||
collation NXT_DEU
|
||||
collation NXT_ESP
|
||||
collation NXT_FRA
|
||||
collation NXT_ITA
|
||||
collation NXT_US
|
||||
</charset>
|
||||
charset = NEXT {
|
||||
intl_module = fbintl
|
||||
collation = NEXT
|
||||
collation = NEXT_UNICODE
|
||||
collation = NXT_DEU
|
||||
collation = NXT_ESP
|
||||
collation = NXT_FRA
|
||||
collation = NXT_ITA
|
||||
collation = NXT_US
|
||||
}
|
||||
|
||||
<charset WIN1255>
|
||||
intl_module fbintl
|
||||
collation WIN1255
|
||||
collation WIN1255_UNICODE
|
||||
</charset>
|
||||
charset = WIN1255 {
|
||||
intl_module = fbintl
|
||||
collation = WIN1255
|
||||
collation = WIN1255_UNICODE
|
||||
}
|
||||
|
||||
<charset WIN1256>
|
||||
intl_module fbintl
|
||||
collation WIN1256
|
||||
collation WIN1256_UNICODE
|
||||
</charset>
|
||||
charset = WIN1256 {
|
||||
intl_module = fbintl
|
||||
collation = WIN1256
|
||||
collation = WIN1256_UNICODE
|
||||
}
|
||||
|
||||
<charset WIN1257>
|
||||
intl_module fbintl
|
||||
collation WIN1257
|
||||
collation WIN1257_UNICODE
|
||||
collation WIN1257_EE
|
||||
collation WIN1257_LT
|
||||
collation WIN1257_LV
|
||||
</charset>
|
||||
charset = WIN1257 {
|
||||
intl_module = fbintl
|
||||
collation = WIN1257
|
||||
collation = WIN1257_UNICODE
|
||||
collation = WIN1257_EE
|
||||
collation = WIN1257_LT
|
||||
collation = WIN1257_LV
|
||||
}
|
||||
|
||||
<charset KSC_5601>
|
||||
intl_module fbintl
|
||||
collation KSC_5601
|
||||
collation KSC_5601_UNICODE
|
||||
collation KSC_DICTIONARY
|
||||
</charset>
|
||||
charset = KSC_5601 {
|
||||
intl_module = fbintl
|
||||
collation = KSC_5601
|
||||
collation = KSC_5601_UNICODE
|
||||
collation = KSC_DICTIONARY
|
||||
}
|
||||
|
||||
<charset BIG_5>
|
||||
intl_module fbintl
|
||||
collation BIG_5
|
||||
collation BIG_5_UNICODE
|
||||
</charset>
|
||||
charset = BIG_5 {
|
||||
intl_module = fbintl
|
||||
collation = BIG_5
|
||||
collation = BIG_5_UNICODE
|
||||
}
|
||||
|
||||
<charset GB_2312>
|
||||
intl_module fbintl
|
||||
collation GB_2312
|
||||
collation GB_2312_UNICODE
|
||||
</charset>
|
||||
charset = GB_2312 {
|
||||
intl_module = fbintl
|
||||
collation = GB_2312
|
||||
collation = GB_2312_UNICODE
|
||||
}
|
||||
|
||||
<charset KOI8R>
|
||||
intl_module fbintl
|
||||
collation KOI8R
|
||||
collation KOI8R_UNICODE
|
||||
collation KOI8R_RU
|
||||
</charset>
|
||||
charset = KOI8R {
|
||||
intl_module = fbintl
|
||||
collation = KOI8R
|
||||
collation = KOI8R_UNICODE
|
||||
collation = KOI8R_RU
|
||||
}
|
||||
|
||||
<charset KOI8U>
|
||||
intl_module fbintl
|
||||
collation KOI8U
|
||||
collation KOI8U_UNICODE
|
||||
collation KOI8U_UA
|
||||
</charset>
|
||||
charset = KOI8U {
|
||||
intl_module = fbintl
|
||||
collation = KOI8U
|
||||
collation = KOI8U_UNICODE
|
||||
collation = KOI8U_UA
|
||||
}
|
||||
|
||||
<charset WIN1258>
|
||||
intl_module fbintl
|
||||
collation WIN1258
|
||||
collation WIN1258_UNICODE
|
||||
</charset>
|
||||
charset = WIN1258 {
|
||||
intl_module = fbintl
|
||||
collation = WIN1258
|
||||
collation = WIN1258_UNICODE
|
||||
}
|
||||
|
||||
<charset TIS620>
|
||||
intl_module fbintl
|
||||
collation TIS620
|
||||
collation TIS620_UNICODE
|
||||
</charset>
|
||||
charset = TIS620 {
|
||||
intl_module = fbintl
|
||||
collation = TIS620
|
||||
collation = TIS620_UNICODE
|
||||
}
|
||||
|
||||
<charset GBK>
|
||||
intl_module fbintl
|
||||
collation GBK
|
||||
collation GBK_UNICODE
|
||||
</charset>
|
||||
charset = GBK {
|
||||
intl_module = fbintl
|
||||
collation = GBK
|
||||
collation = GBK_UNICODE
|
||||
}
|
||||
|
||||
<charset CP943C>
|
||||
intl_module fbintl
|
||||
collation CP943C ibm-943_P15A-2003
|
||||
collation CP943C_UNICODE
|
||||
</charset>
|
||||
charset = CP943C {
|
||||
intl_module = fbintl
|
||||
collation = CP943C ibm-943_P15A-2003
|
||||
collation = CP943C_UNICODE
|
||||
}
|
||||
|
||||
<charset GB18030>
|
||||
intl_module fbintl
|
||||
collation GB18030
|
||||
collation GB18030_UNICODE
|
||||
</charset>
|
||||
charset = GB18030 {
|
||||
intl_module = fbintl
|
||||
collation = GB18030
|
||||
collation = GB18030_UNICODE
|
||||
}
|
||||
|
@ -105,6 +105,8 @@
|
||||
# paths (for Win32 this may be something like 'C:\ExternalTables',
|
||||
# for unix - '/db/extern;/mnt/extern').
|
||||
#
|
||||
# Per-database configurable.
|
||||
#
|
||||
# NOTE: THE EXTERNAL TABLE ENGINE FEATURE COULD BE USED TO COMPROMISE
|
||||
# THE SERVER/HOST AS WELL AS DATABASE SECURITY!!
|
||||
#
|
||||
@ -213,6 +215,8 @@
|
||||
# SuperServer allocates 2048 pages for each database and the classic
|
||||
# allocates 75 pages per client connection per database.
|
||||
#
|
||||
# Per-database configurable.
|
||||
#
|
||||
# Type: integer
|
||||
#
|
||||
#DefaultDbCachePages = 2048
|
||||
@ -228,6 +232,8 @@
|
||||
# default). To disable preallocation set DatabaseGrowthIncrement to zero.
|
||||
# Shadow database files are not preallocated.
|
||||
#
|
||||
# Per-database configurable.
|
||||
#
|
||||
# Type: integer
|
||||
#
|
||||
#DatabaseGrowthIncrement = 134217728
|
||||
@ -246,6 +252,8 @@
|
||||
#
|
||||
# Type: integer, measured in database pages
|
||||
#
|
||||
# Per-database configurable.
|
||||
#
|
||||
#FileSystemCacheThreshold = 65536
|
||||
|
||||
# ----------------------------
|
||||
@ -335,6 +343,8 @@
|
||||
# The smallest block size being allocated in the temporary storage.
|
||||
# This value reflects the allocation granularity.
|
||||
#
|
||||
# Per-database configurable.
|
||||
#
|
||||
# Type: integer
|
||||
#
|
||||
#TempBlockSize = 1048576
|
||||
@ -347,6 +357,8 @@
|
||||
# Although it can be increased, the value applies to each client
|
||||
# connection/server instance and thus consumes a lot of memory.
|
||||
#
|
||||
# Per-database configurable.
|
||||
#
|
||||
# Type: integer
|
||||
#
|
||||
#TempCacheLimit = 67108864
|
||||
@ -360,6 +372,8 @@
|
||||
# in all normal cases, so this value affects things only if something goes
|
||||
# wrong. Setting it too low may degrade system performance.
|
||||
#
|
||||
# Per-database configurable.
|
||||
#
|
||||
# Type: integer
|
||||
#
|
||||
#DeadlockTimeout = 10
|
||||
@ -374,6 +388,8 @@
|
||||
# flushed, at the next transaction commit. For non-Win32 ports,
|
||||
# the default value is -1 (Disabled)
|
||||
#
|
||||
# Per-database configurable.
|
||||
#
|
||||
# Type: integer
|
||||
#
|
||||
#MaxUnflushedWrites = 100
|
||||
@ -383,6 +399,8 @@
|
||||
# before they are flushed, at the next transaction commit. For non-Win32
|
||||
# ports, the default value is -1 (Disabled)
|
||||
#
|
||||
# Per-database configurable.
|
||||
#
|
||||
# Type: integer
|
||||
#
|
||||
#MaxUnflushedWriteTime = 5
|
||||
@ -549,6 +567,8 @@
|
||||
# table expands dynamically up to the limit of memory. In SuperServer, the
|
||||
# initial size is also the final size.
|
||||
#
|
||||
# Per-database configurable.
|
||||
#
|
||||
# Type: integer
|
||||
#
|
||||
#LockMemSize = 1048576
|
||||
@ -566,6 +586,8 @@
|
||||
# as soon as they are available; can result in lock request
|
||||
# starvation.
|
||||
#
|
||||
# Per-database configurable.
|
||||
#
|
||||
# Type: integer/boolean
|
||||
#
|
||||
#LockGrantOrder = 1
|
||||
@ -579,6 +601,8 @@
|
||||
# will be made conditionally. Zero value means unconditional mode.
|
||||
# Relevant only on SMP machines.
|
||||
#
|
||||
# Per-database configurable.
|
||||
#
|
||||
# Type: integer
|
||||
#
|
||||
#LockAcquireSpins = 0
|
||||
@ -587,6 +611,8 @@
|
||||
# Tune lock hash list; more hash slots mean shorter hash chains. Only
|
||||
# necessary under very high load. Prime number values are recommended.
|
||||
#
|
||||
# Per-database configurable.
|
||||
#
|
||||
# Type: integer
|
||||
#
|
||||
#LockHashSlots = 1009
|
||||
@ -595,6 +621,8 @@
|
||||
#
|
||||
# Bytes of shared memory allocated for event manager.
|
||||
#
|
||||
# Per-database configurable.
|
||||
#
|
||||
# Type: integer
|
||||
#
|
||||
#EventMemSize = 65536
|
||||
@ -660,6 +688,8 @@
|
||||
# Classic has by default "cooperative" policy.
|
||||
# Other values are ignored by classic server build
|
||||
#
|
||||
# Per-database configurable.
|
||||
#
|
||||
# Type: string (special format)
|
||||
#
|
||||
#GCPolicy = combined
|
||||
|
@ -40,7 +40,8 @@ include $(ROOT)/gen/make.shared.variables
|
||||
|
||||
|
||||
LOCKPRINT_Other_Sources = jrd/isc_sync.cpp jrd/isc.cpp jrd/db_alias.cpp \
|
||||
common/config/config.cpp common/config/config_file.cpp $(OS_SPECIFIC_Sources)
|
||||
common/config/config.cpp common/config/config_file.cpp common/config/ConfigCache.cpp \
|
||||
$(OS_SPECIFIC_Sources)
|
||||
LOCKPRINT_Files= print.cpp
|
||||
LOCKPRINT_Sources = $(addprefix lock/, $(LOCKPRINT_Files)) $(LOCKPRINT_Other_Sources)
|
||||
LOCKPRINT_Objects = $(addprefix $(OBJ)/, $(addsuffix .o, $(basename $(LOCKPRINT_Sources)))) \
|
||||
@ -59,7 +60,8 @@ CREATEDB_Objects = $(addprefix $(OBJ)/, $(addsuffix .o, $(basename $(CREATEDB_So
|
||||
|
||||
|
||||
DROP_Other_Sources = common/utils.cpp lock/lock.cpp jrd/isc_sync.cpp jrd/isc.cpp \
|
||||
common/config/config.cpp common/config/config_file.cpp $(OS_SPECIFIC_Sources)
|
||||
common/config/config.cpp common/config/config_file.cpp common/config/ConfigCache.cpp \
|
||||
$(OS_SPECIFIC_Sources)
|
||||
|
||||
DROP_Files= drop.cpp
|
||||
DROP_Sources = $(addprefix utilities/, $(DROP_Files)) $(DROP_Other_Sources)
|
||||
|
@ -62,7 +62,8 @@ CREATEDB_Objects = $(addprefix $(OBJ)/, $(addsuffix .o, $(basename $(CREATEDB_So
|
||||
|
||||
|
||||
DROP_Other_Sources += common/utils.cpp jrd/isc_sync.cpp jrd/isc.cpp \
|
||||
common/config/config.cpp common/config/config_file.cpp $(OS_SPECIFIC_Sources)
|
||||
common/config/config.cpp common/config/config_file.cpp common/config/ConfigCache.cpp \
|
||||
$(OS_SPECIFIC_Sources)
|
||||
|
||||
DROP_Files= drop.cpp
|
||||
DROP_Sources = $(addprefix utilities/, $(DROP_Files)) $(DROP_Other_Sources)
|
||||
@ -71,9 +72,8 @@ DROP_Objects = $(addprefix $(OBJ)/, $(addsuffix .o, $(basename $(DROP_Sources)))
|
||||
|
||||
GSEC_Other_Sources = jrd/enc.cpp jrd/sha.cpp jrd/guid.cpp \
|
||||
jrd/isc_file.cpp common/config/config.cpp common/config/config_file.cpp \
|
||||
common/config/dir_list.cpp \
|
||||
jrd/ThreadData.cpp \
|
||||
$(OS_SPECIFIC_Sources)
|
||||
common/config/ConfigCache.cpp common/config/dir_list.cpp \
|
||||
jrd/ThreadData.cpp $(OS_SPECIFIC_Sources)
|
||||
|
||||
GSEC_Files = gsec.cpp security.cpp call_service.cpp gsecMain.cpp
|
||||
GSEC_Sources = $(addprefix utilities/gsec/, $(GSEC_Files)) $(GSEC_Other_Sources)
|
||||
|
@ -32,8 +32,7 @@
|
||||
|
||||
|
||||
# Please don't use compiler/platform specific flags here - nmcc 02-Nov-2002
|
||||
WFLAGS:=-I$(SRC_ROOT)/include/gen -I$(SRC_ROOT)/include -I$(SRC_ROOT)/vulcan \
|
||||
-DNAMESPACE=Vulcan
|
||||
WFLAGS:=-I$(SRC_ROOT)/include/gen -I$(SRC_ROOT)/include
|
||||
|
||||
ifeq ($(STD_ICU),false)
|
||||
WFLAGS:= $(WFLAGS) -I$(ROOT)/extern/icu/source/common -I$(ROOT)/extern/icu/source/i18n
|
||||
|
@ -78,6 +78,7 @@ $(SRC_ROOT)/dsql/keywords.cpp: $(SRC_ROOT)/dsql/dsql.tab.h
|
||||
$(OBJ)/dsql/Parser.h: $(SRC_ROOT)/dsql/dsql.tab.h
|
||||
|
||||
$(OBJ)/dsql/StmtNodes.o: $(SRC_ROOT)/include/gen/blrtable.h
|
||||
$(OBJ)/dsql/AggNodes.o: $(SRC_ROOT)/include/gen/blrtable.h
|
||||
|
||||
# Special cases for building cpp from epp
|
||||
$(OBJ)/dsql/metd.cpp: $(SRC_ROOT)/dsql/metd.epp
|
||||
|
@ -217,7 +217,7 @@ FBCLASSES_Objects = $(FBCLASSES_ClientObjects) $(FBCLASSES_ServerObjects) $(FBCL
|
||||
#
|
||||
# common/config
|
||||
|
||||
FBCONFIG_ClientFiles=config.cpp config_file.cpp dir_list.cpp
|
||||
FBCONFIG_ClientFiles=config.cpp config_file.cpp dir_list.cpp ConfigCache.cpp
|
||||
FBCONFIG_ServerFiles=
|
||||
|
||||
FBCONFIG_Files= $(FBCONFIG_ClientFiles) $(FBCONFIG_ServerFiles)
|
||||
@ -229,10 +229,7 @@ FBCONFIG_Objects = $(addprefix $(OBJ)/, $(addsuffix .o, $(basename $(FBCONFIG_So
|
||||
#
|
||||
# config
|
||||
|
||||
CONFIG_ClientFiles=AdminException.cpp Args.cpp ArgsException.cpp \
|
||||
ConfObj.cpp ConfObject.cpp ConfigFile.cpp Configuration.cpp \
|
||||
Element.cpp FileName.cpp InputFile.cpp \
|
||||
InputStream.cpp Lex.cpp ScanDir.cpp Stream.cpp StreamSegment.cpp
|
||||
CONFIG_ClientFiles=ScanDir.cpp
|
||||
CONFIG_ServerFiles=
|
||||
|
||||
CONFIG_Files= $(CONFIG_ClientFiles) $(CONFIG_ServerFiles)
|
||||
@ -244,7 +241,7 @@ CONFIG_Objects = $(addprefix $(OBJ)/, $(addsuffix .o, $(basename $(CONFIG_Source
|
||||
#
|
||||
# vulcan
|
||||
|
||||
VULCAN_ClientFiles=PathName.cpp RefObject.cpp
|
||||
VULCAN_ClientFiles=
|
||||
VULCAN_ServerFiles=
|
||||
|
||||
VULCAN_Files= $(VULCAN_ClientFiles) $(VULCAN_ServerFiles)
|
||||
|
@ -114,7 +114,7 @@ LIB_LINK_SONAME=
|
||||
|
||||
OS_ServerFiles=inet_server.cpp
|
||||
INTL_Files2=common/utils.cpp \
|
||||
common/config/config.cpp common/config/config_file.cpp \
|
||||
common/config/config.cpp common/config/config_file.cpp common/config/ConfigCache.cpp \
|
||||
common/classes/MsgPrint.cpp common/classes/SafeArg.cpp \
|
||||
common/classes/BaseStream.cpp common/classes/fb_string.cpp \
|
||||
common/classes/TempFile.cpp \
|
||||
|
@ -154,12 +154,12 @@ namespace Firebird
|
||||
public:
|
||||
explicit Hash(MemoryPool&)
|
||||
{
|
||||
memset(data, 0, sizeof data);
|
||||
clean();
|
||||
}
|
||||
|
||||
Hash()
|
||||
{
|
||||
memset(data, 0, sizeof data);
|
||||
clean();
|
||||
}
|
||||
|
||||
~Hash()
|
||||
@ -232,6 +232,11 @@ namespace Firebird
|
||||
// disable use of default operator=
|
||||
Hash& operator= (const Hash&);
|
||||
|
||||
void clean()
|
||||
{
|
||||
memset(data, 0, sizeof data);
|
||||
}
|
||||
|
||||
public:
|
||||
class iterator
|
||||
{
|
||||
|
@ -60,12 +60,12 @@ public:
|
||||
MetaName(const char* s) { assign(s); }
|
||||
MetaName(const char* s, size_t l) { assign(s, l); }
|
||||
MetaName(const MetaName& m) { set(m); }
|
||||
MetaName(const string& s) { assign(s.c_str(), s.length()); }
|
||||
MetaName(const AbstractString& s) { assign(s.c_str(), s.length()); }
|
||||
explicit MetaName(MemoryPool&) { init(); count = 0; }
|
||||
MetaName(MemoryPool&, const char* s) { assign(s); }
|
||||
MetaName(MemoryPool&, const char* s, size_t l) { assign(s, l); }
|
||||
MetaName(MemoryPool&, const MetaName& m) { set(m); }
|
||||
MetaName(MemoryPool&, const string& s) { assign(s.c_str(), s.length()); }
|
||||
MetaName(MemoryPool&, const AbstractString& s) { assign(s.c_str(), s.length()); }
|
||||
|
||||
MetaName& assign(const char* s, size_t l);
|
||||
MetaName& assign(const char* s) { return assign(s, s ? strlen(s) : 0); }
|
||||
|
@ -154,6 +154,11 @@ namespace Firebird
|
||||
return ptr ? true : false;
|
||||
}*/
|
||||
|
||||
bool hasData() const
|
||||
{
|
||||
return ptr ? true : false;
|
||||
}
|
||||
|
||||
bool operator !() const
|
||||
{
|
||||
return !ptr;
|
||||
|
@ -83,6 +83,11 @@ public:
|
||||
return ptr;
|
||||
}
|
||||
|
||||
operator const Where*() const
|
||||
{
|
||||
return ptr;
|
||||
}
|
||||
|
||||
bool operator !() const
|
||||
{
|
||||
return !ptr;
|
||||
|
81
src/common/config/ConfigCache.cpp
Normal file
81
src/common/config/ConfigCache.cpp
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* PROGRAM: JRD Access Method
|
||||
* MODULE: ConfigCache.cpp
|
||||
* DESCRIPTION: Base for class, representing cached config file.
|
||||
*
|
||||
* 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 Alexander Peshkoff
|
||||
* for the Firebird Open Source RDBMS project.
|
||||
*
|
||||
* Copyright (c) 2010 Alexander Peshkoff <peshkoff@mail.ru>
|
||||
* and all contributors signed below.
|
||||
*
|
||||
* All Rights Reserved.
|
||||
* Contributor(s): ______________________________________.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "../common/config/ConfigCache.h"
|
||||
#include "../common/config/config_file.h"
|
||||
|
||||
#ifndef WIN_NT
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
ConfigCache::ConfigCache(Firebird::MemoryPool& p, const Firebird::PathName& fName)
|
||||
: PermanentStorage(p), fileName(getPool(), fName), fileTime(0)
|
||||
{ }
|
||||
|
||||
ConfigCache::~ConfigCache() { }
|
||||
|
||||
void ConfigCache::checkLoadConfig()
|
||||
{
|
||||
unsigned long newTime = getTime();
|
||||
if (fileTime == newTime)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Firebird::WriteLockGuard guard(rwLock);
|
||||
|
||||
// may be someone already reloaded?
|
||||
newTime = getTime();
|
||||
if (fileTime == newTime)
|
||||
{
|
||||
return;
|
||||
}
|
||||
fileTime = newTime;
|
||||
|
||||
loadConfig();
|
||||
}
|
||||
|
||||
#ifndef WIN_NT
|
||||
unsigned long ConfigCache::getTime()
|
||||
{
|
||||
struct stat st;
|
||||
if (stat(fileName.c_str(), &st) != 0)
|
||||
{
|
||||
if (errno == ENOENT)
|
||||
{
|
||||
// config file is missing, but this is not our problem
|
||||
return 0;
|
||||
}
|
||||
Firebird::system_call_failed::raise("stat");
|
||||
}
|
||||
return st.st_mtime;
|
||||
}
|
||||
#else // WIN_NT
|
||||
error: add getTime() for windows
|
||||
#endif // WIN_NT
|
57
src/common/config/ConfigCache.h
Normal file
57
src/common/config/ConfigCache.h
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* PROGRAM: JRD Access Method
|
||||
* MODULE: ConfigCache.h
|
||||
* DESCRIPTION: Base for class, representing cached config file.
|
||||
*
|
||||
* 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 Alexander Peshkoff
|
||||
* for the Firebird Open Source RDBMS project.
|
||||
*
|
||||
* Copyright (c) 2010 Alexander Peshkoff <peshkoff@mail.ru>
|
||||
* and all contributors signed below.
|
||||
*
|
||||
* All Rights Reserved.
|
||||
* Contributor(s): ______________________________________.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_CONFIG_CASHE_H
|
||||
#define CONFIG_CONFIG_CASHE_H
|
||||
|
||||
#include "../common/classes/alloc.h"
|
||||
#include "../common/classes/fb_string.h"
|
||||
#include "../common/classes/rwlock.h"
|
||||
|
||||
class ConfigCache : public Firebird::PermanentStorage
|
||||
{
|
||||
public:
|
||||
ConfigCache(Firebird::MemoryPool& p, const Firebird::PathName& fName);
|
||||
virtual ~ConfigCache();
|
||||
|
||||
void checkLoadConfig();
|
||||
|
||||
protected:
|
||||
virtual void loadConfig() = 0;
|
||||
|
||||
private:
|
||||
unsigned long getTime();
|
||||
|
||||
public:
|
||||
Firebird::RWLock rwLock;
|
||||
Firebird::PathName fileName;
|
||||
|
||||
private:
|
||||
unsigned long fileTime;
|
||||
};
|
||||
|
||||
#endif // CLASSES_HASH_H
|
@ -22,17 +22,78 @@
|
||||
|
||||
#include "firebird.h"
|
||||
|
||||
#include "../../common/config/config.h"
|
||||
#include "../../common/config/config_impl.h"
|
||||
#include "../../common/config/config_file.h"
|
||||
#include "../../common/classes/init.h"
|
||||
#include "../common/config/config.h"
|
||||
#include "../common/config/config_file.h"
|
||||
#include "../jrd/os/config_root.h"
|
||||
#include "../common/classes/init.h"
|
||||
#include "../jrd/os/fbsyslog.h"
|
||||
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
// config_file works with OS case-sensitivity
|
||||
typedef Firebird::PathName string;
|
||||
typedef Firebird::PathName String;
|
||||
|
||||
namespace {
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* firebird.conf implementation
|
||||
*/
|
||||
|
||||
class ConfigImpl : public ConfigRoot
|
||||
{
|
||||
public:
|
||||
explicit ConfigImpl(Firebird::MemoryPool& p) : ConfigRoot(p)
|
||||
{
|
||||
try
|
||||
{
|
||||
root_dir = getRootDirectory();
|
||||
|
||||
ConfigFile file(getConfigFilePath(), ConfigFile::EXCEPTION_ON_ERROR | ConfigFile::NO_MACRO);
|
||||
defaultConfig = new Config(file);
|
||||
}
|
||||
catch (const Firebird::fatal_exception& ex)
|
||||
{
|
||||
Firebird::Syslog::Record(Firebird::Syslog::Error, ex.what());
|
||||
(Firebird::Arg::Gds(isc_random) << "Problems with master configuration file - "
|
||||
"inform server admin please").raise();
|
||||
}
|
||||
}
|
||||
|
||||
/* void changeDefaultConfig(Config* newConfig)
|
||||
{
|
||||
defaultConfig = newConfig;
|
||||
}
|
||||
*/
|
||||
Firebird::RefPtr<Config> getDefaultConfig() const
|
||||
{
|
||||
return defaultConfig;
|
||||
}
|
||||
|
||||
const char* getCachedRootDir()
|
||||
{
|
||||
return root_dir;
|
||||
}
|
||||
|
||||
private:
|
||||
const char* root_dir;
|
||||
Firebird::RefPtr<Config> defaultConfig;
|
||||
|
||||
ConfigImpl(const ConfigImpl&);
|
||||
void operator=(const ConfigImpl&);
|
||||
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Static instance of the system configuration file
|
||||
*/
|
||||
|
||||
Firebird::InitInstance<ConfigImpl> firebirdConf;
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
@ -52,7 +113,7 @@ const char* AmNative = "native";
|
||||
const char* AmTrusted = "trusted";
|
||||
const char* AmMixed = "mixed";
|
||||
|
||||
const ConfigImpl::ConfigEntry ConfigImpl::entries[] =
|
||||
const Config::ConfigEntry Config::entries[MAX_CONFIG_KEY] =
|
||||
{
|
||||
{TYPE_STRING, "RootDirectory", (ConfigValue) 0},
|
||||
{TYPE_INTEGER, "TempBlockSize", (ConfigValue) 1048576}, // bytes
|
||||
@ -127,74 +188,77 @@ const ConfigImpl::ConfigEntry ConfigImpl::entries[] =
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Static instance of the system configuration file
|
||||
* Config routines
|
||||
*/
|
||||
|
||||
static Firebird::InitInstance<ConfigImpl> sysConfig;
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Implementation interface
|
||||
*/
|
||||
|
||||
ConfigImpl::ConfigImpl(MemoryPool& p) : ConfigRoot(p)
|
||||
Config::Config(const ConfigFile& file)
|
||||
{
|
||||
// Prepare some stuff
|
||||
|
||||
ConfigFile file(p, true);
|
||||
root_dir = getRootDirectory();
|
||||
const int size = FB_NELEM(entries);
|
||||
values = FB_NEW(p) ConfigValue[size];
|
||||
|
||||
//string val_sep = ",";
|
||||
file.setConfigFilePath(getConfigFilePath());
|
||||
|
||||
// Iterate through the known configuration entries
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
for (unsigned int i = 0; i < MAX_CONFIG_KEY; i++)
|
||||
{
|
||||
const ConfigEntry entry = entries[i];
|
||||
const string value = getValue(file, entries[i].key);
|
||||
values[i] = entries[i].default_value;
|
||||
}
|
||||
|
||||
if (!value.length())
|
||||
loadValues(file);
|
||||
}
|
||||
|
||||
Config::Config(const ConfigFile& file, const Config& base)
|
||||
{
|
||||
// Iterate through the known configuration entries
|
||||
|
||||
for (unsigned int i = 0; i < MAX_CONFIG_KEY; i++)
|
||||
{
|
||||
values[i] = base.values[i];
|
||||
}
|
||||
|
||||
loadValues(file);
|
||||
}
|
||||
|
||||
void Config::loadValues(const ConfigFile& file)
|
||||
{
|
||||
// Iterate through the known configuration entries
|
||||
|
||||
for (int i = 0; i < MAX_CONFIG_KEY; i++)
|
||||
{
|
||||
const ConfigEntry& entry = entries[i];
|
||||
const String value = getValue(file, entry.key);
|
||||
|
||||
if (value.length())
|
||||
{
|
||||
// Assign the default value
|
||||
// Assign the actual value
|
||||
|
||||
values[i] = entries[i].default_value;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Assign the actual value
|
||||
|
||||
switch (entry.data_type)
|
||||
{
|
||||
case TYPE_BOOLEAN:
|
||||
values[i] = (ConfigValue) asBoolean(value);
|
||||
break;
|
||||
case TYPE_INTEGER:
|
||||
values[i] = (ConfigValue) asInteger(value);
|
||||
break;
|
||||
case TYPE_STRING:
|
||||
switch (entry.data_type)
|
||||
{
|
||||
const char* src = asString(value);
|
||||
char* dst = FB_NEW(p) char[strlen(src) + 1];
|
||||
case TYPE_BOOLEAN:
|
||||
values[i] = (ConfigValue) asBoolean(value);
|
||||
break;
|
||||
case TYPE_INTEGER:
|
||||
values[i] = (ConfigValue) asInteger(value);
|
||||
break;
|
||||
case TYPE_STRING:
|
||||
values[i] = (ConfigValue) asString(value);
|
||||
break;
|
||||
//case TYPE_STRING_VECTOR:
|
||||
// break;
|
||||
}
|
||||
|
||||
if (entry.data_type == TYPE_STRING && values[i] != entry.default_value)
|
||||
{
|
||||
const char* src = (const char*) values[i];
|
||||
char* dst = FB_NEW(getPool()) char[strlen(src) + 1];
|
||||
strcpy(dst, src);
|
||||
values[i] = (ConfigValue) dst;
|
||||
}
|
||||
break;
|
||||
//case TYPE_STRING_VECTOR:
|
||||
// break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ConfigImpl::~ConfigImpl()
|
||||
Config::~Config()
|
||||
{
|
||||
const int size = FB_NELEM(entries);
|
||||
|
||||
// Free allocated memory
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
for (int i = 0; i < MAX_CONFIG_KEY; i++)
|
||||
{
|
||||
if (values[i] == entries[i].default_value)
|
||||
continue;
|
||||
@ -208,37 +272,48 @@ ConfigImpl::~ConfigImpl()
|
||||
// break;
|
||||
}
|
||||
}
|
||||
delete[] values;
|
||||
}
|
||||
|
||||
string ConfigImpl::getValue(ConfigFile& file, const ConfigKey key)
|
||||
String Config::getValue(const ConfigFile& file, ConfigName key)
|
||||
{
|
||||
return file.doesKeyExist(key) ? file.getString(key) : "";
|
||||
const ConfigFile::Parameter* p = file.findParameter(key);
|
||||
return p ? p->value : "";
|
||||
}
|
||||
|
||||
int ConfigImpl::asInteger(const string &value)
|
||||
int Config::asInteger(const String &value)
|
||||
{
|
||||
return atoi(value.data());
|
||||
}
|
||||
|
||||
bool ConfigImpl::asBoolean(const string &value)
|
||||
bool Config::asBoolean(const String &value)
|
||||
{
|
||||
return (atoi(value.data()) != 0);
|
||||
}
|
||||
|
||||
const char* ConfigImpl::asString(const string &value)
|
||||
const char* Config::asString(const String &value)
|
||||
{
|
||||
return value.c_str();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T Config::get(Config::ConfigKey key) const
|
||||
{
|
||||
return (T) values[key];
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Public interface
|
||||
*/
|
||||
|
||||
const Firebird::RefPtr<Config> Config::getDefaultConfig()
|
||||
{
|
||||
return firebirdConf().getDefaultConfig();
|
||||
}
|
||||
|
||||
const char* Config::getInstallDirectory()
|
||||
{
|
||||
return sysConfig().getInstallDirectory();
|
||||
return firebirdConf().getInstallDirectory();
|
||||
}
|
||||
|
||||
static Firebird::PathName* rootFromCommandLine = 0;
|
||||
@ -263,39 +338,39 @@ const char* Config::getRootDirectory()
|
||||
return rootFromCommandLine->c_str();
|
||||
}
|
||||
|
||||
const char* result = (char*) sysConfig().values[KEY_ROOT_DIRECTORY];
|
||||
return result ? result : sysConfig().root_dir;
|
||||
const char* result = (char*) getDefaultConfig()->values[KEY_ROOT_DIRECTORY];
|
||||
return result ? result : firebirdConf().getCachedRootDir();
|
||||
}
|
||||
|
||||
int Config::getTempBlockSize()
|
||||
int Config::getTempBlockSize() const
|
||||
{
|
||||
return (int) sysConfig().values[KEY_TEMP_BLOCK_SIZE];
|
||||
return get<int>(KEY_TEMP_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
int Config::getTempCacheLimit()
|
||||
int Config::getTempCacheLimit() const
|
||||
{
|
||||
int v = (int) sysConfig().values[KEY_TEMP_CACHE_LIMIT];
|
||||
int v = get<int>(KEY_TEMP_CACHE_LIMIT);
|
||||
return v < 0 ? 0 : v;
|
||||
}
|
||||
|
||||
bool Config::getRemoteFileOpenAbility()
|
||||
{
|
||||
return (bool) sysConfig().values[KEY_REMOTE_FILE_OPEN_ABILITY];
|
||||
return (bool) getDefaultConfig()->values[KEY_REMOTE_FILE_OPEN_ABILITY];
|
||||
}
|
||||
|
||||
int Config::getGuardianOption()
|
||||
{
|
||||
return (int) sysConfig().values[KEY_GUARDIAN_OPTION];
|
||||
return (int) getDefaultConfig()->values[KEY_GUARDIAN_OPTION];
|
||||
}
|
||||
|
||||
int Config::getCpuAffinityMask()
|
||||
{
|
||||
return (int) sysConfig().values[KEY_CPU_AFFINITY_MASK];
|
||||
return (int) getDefaultConfig()->values[KEY_CPU_AFFINITY_MASK];
|
||||
}
|
||||
|
||||
int Config::getTcpRemoteBufferSize()
|
||||
{
|
||||
int rc = (int) sysConfig().values[KEY_TCP_REMOTE_BUFFER_SIZE];
|
||||
int rc = (int) getDefaultConfig()->values[KEY_TCP_REMOTE_BUFFER_SIZE];
|
||||
if (rc < 1448)
|
||||
rc = 1448;
|
||||
if (rc > MAX_SSHORT)
|
||||
@ -305,57 +380,57 @@ int Config::getTcpRemoteBufferSize()
|
||||
|
||||
bool Config::getTcpNoNagle()
|
||||
{
|
||||
return (bool) sysConfig().values[KEY_TCP_NO_NAGLE];
|
||||
return (bool) getDefaultConfig()->values[KEY_TCP_NO_NAGLE];
|
||||
}
|
||||
|
||||
int Config::getDefaultDbCachePages()
|
||||
int Config::getDefaultDbCachePages() const
|
||||
{
|
||||
return (int) sysConfig().values[KEY_DEFAULT_DB_CACHE_PAGES];
|
||||
return get<int>(KEY_DEFAULT_DB_CACHE_PAGES);
|
||||
}
|
||||
|
||||
int Config::getConnectionTimeout()
|
||||
{
|
||||
return (int) sysConfig().values[KEY_CONNECTION_TIMEOUT];
|
||||
return (int) getDefaultConfig()->values[KEY_CONNECTION_TIMEOUT];
|
||||
}
|
||||
|
||||
int Config::getDummyPacketInterval()
|
||||
{
|
||||
return (int) sysConfig().values[KEY_DUMMY_PACKET_INTERVAL];
|
||||
return (int) getDefaultConfig()->values[KEY_DUMMY_PACKET_INTERVAL];
|
||||
}
|
||||
|
||||
int Config::getLockMemSize()
|
||||
int Config::getLockMemSize() const
|
||||
{
|
||||
return (int) sysConfig().values[KEY_LOCK_MEM_SIZE];
|
||||
return get<int>(KEY_LOCK_MEM_SIZE);
|
||||
}
|
||||
|
||||
bool Config::getLockGrantOrder()
|
||||
bool Config::getLockGrantOrder() const
|
||||
{
|
||||
return (bool) sysConfig().values[KEY_LOCK_GRANT_ORDER];
|
||||
return get<bool>(KEY_LOCK_GRANT_ORDER);
|
||||
}
|
||||
|
||||
int Config::getLockHashSlots()
|
||||
int Config::getLockHashSlots() const
|
||||
{
|
||||
return (int) sysConfig().values[KEY_LOCK_HASH_SLOTS];
|
||||
return get<int>(KEY_LOCK_HASH_SLOTS);
|
||||
}
|
||||
|
||||
int Config::getLockAcquireSpins()
|
||||
int Config::getLockAcquireSpins() const
|
||||
{
|
||||
return (int) sysConfig().values[KEY_LOCK_ACQUIRE_SPINS];
|
||||
return get<int>(KEY_LOCK_ACQUIRE_SPINS);
|
||||
}
|
||||
|
||||
int Config::getEventMemSize()
|
||||
int Config::getEventMemSize() const
|
||||
{
|
||||
return (int) sysConfig().values[KEY_EVENT_MEM_SIZE];
|
||||
return get<int>(KEY_EVENT_MEM_SIZE);
|
||||
}
|
||||
|
||||
int Config::getDeadlockTimeout()
|
||||
int Config::getDeadlockTimeout() const
|
||||
{
|
||||
return (int) sysConfig().values[KEY_DEADLOCK_TIMEOUT];
|
||||
return get<int>(KEY_DEADLOCK_TIMEOUT);
|
||||
}
|
||||
|
||||
int Config::getPrioritySwitchDelay()
|
||||
{
|
||||
int rc = (int) sysConfig().values[KEY_PRIORITY_SWITCH_DELAY];
|
||||
int rc = (int) getDefaultConfig()->values[KEY_PRIORITY_SWITCH_DELAY];
|
||||
if (rc < 1)
|
||||
rc = 1;
|
||||
return rc;
|
||||
@ -363,7 +438,7 @@ int Config::getPrioritySwitchDelay()
|
||||
|
||||
int Config::getPriorityBoost()
|
||||
{
|
||||
int rc = (int) sysConfig().values[KEY_PRIORITY_BOOST];
|
||||
int rc = (int) getDefaultConfig()->values[KEY_PRIORITY_BOOST];
|
||||
if (rc < 1)
|
||||
rc = 1;
|
||||
if (rc > 1000)
|
||||
@ -373,62 +448,62 @@ int Config::getPriorityBoost()
|
||||
|
||||
bool Config::getUsePriorityScheduler()
|
||||
{
|
||||
return (bool) sysConfig().values[KEY_USE_PRIORITY_SCHEDULER];
|
||||
return (bool) getDefaultConfig()->values[KEY_USE_PRIORITY_SCHEDULER];
|
||||
}
|
||||
|
||||
const char *Config::getRemoteServiceName()
|
||||
{
|
||||
return (const char*) sysConfig().values[KEY_REMOTE_SERVICE_NAME];
|
||||
return (const char*) getDefaultConfig()->values[KEY_REMOTE_SERVICE_NAME];
|
||||
}
|
||||
|
||||
unsigned short Config::getRemoteServicePort()
|
||||
{
|
||||
return (unsigned short) sysConfig().values[KEY_REMOTE_SERVICE_PORT];
|
||||
return (unsigned short) getDefaultConfig()->values[KEY_REMOTE_SERVICE_PORT];
|
||||
}
|
||||
|
||||
const char *Config::getRemotePipeName()
|
||||
{
|
||||
return (const char*) sysConfig().values[KEY_REMOTE_PIPE_NAME];
|
||||
return (const char*) getDefaultConfig()->values[KEY_REMOTE_PIPE_NAME];
|
||||
}
|
||||
|
||||
const char *Config::getIpcName()
|
||||
{
|
||||
return (const char*) sysConfig().values[KEY_IPC_NAME];
|
||||
return (const char*) getDefaultConfig()->values[KEY_IPC_NAME];
|
||||
}
|
||||
|
||||
int Config::getMaxUnflushedWrites()
|
||||
int Config::getMaxUnflushedWrites() const
|
||||
{
|
||||
return (int) sysConfig().values[KEY_MAX_UNFLUSHED_WRITES];
|
||||
return get<int>(KEY_MAX_UNFLUSHED_WRITES);
|
||||
}
|
||||
|
||||
int Config::getMaxUnflushedWriteTime()
|
||||
int Config::getMaxUnflushedWriteTime() const
|
||||
{
|
||||
return (int) sysConfig().values[KEY_MAX_UNFLUSHED_WRITE_TIME];
|
||||
return get<int>(KEY_MAX_UNFLUSHED_WRITE_TIME);
|
||||
}
|
||||
|
||||
int Config::getProcessPriorityLevel()
|
||||
{
|
||||
return (int) sysConfig().values[KEY_PROCESS_PRIORITY_LEVEL];
|
||||
return (int) getDefaultConfig()->values[KEY_PROCESS_PRIORITY_LEVEL];
|
||||
}
|
||||
|
||||
int Config::getRemoteAuxPort()
|
||||
{
|
||||
return (int) sysConfig().values[KEY_REMOTE_AUX_PORT];
|
||||
return (int) getDefaultConfig()->values[KEY_REMOTE_AUX_PORT];
|
||||
}
|
||||
|
||||
const char *Config::getRemoteBindAddress()
|
||||
{
|
||||
return (const char*) sysConfig().values[KEY_REMOTE_BIND_ADDRESS];
|
||||
return (const char*) getDefaultConfig()->values[KEY_REMOTE_BIND_ADDRESS];
|
||||
}
|
||||
|
||||
const char *Config::getExternalFileAccess()
|
||||
const char *Config::getExternalFileAccess() const
|
||||
{
|
||||
return (const char*) sysConfig().values[KEY_EXTERNAL_FILE_ACCESS];
|
||||
return get<const char*>(KEY_EXTERNAL_FILE_ACCESS);
|
||||
}
|
||||
|
||||
const char *Config::getDatabaseAccess()
|
||||
{
|
||||
return (const char*) sysConfig().values[KEY_DATABASE_ACCESS];
|
||||
return (const char*) getDefaultConfig()->values[KEY_DATABASE_ACCESS];
|
||||
}
|
||||
|
||||
const char *Config::getUdfAccess()
|
||||
@ -449,7 +524,7 @@ const char *Config::getUdfAccess()
|
||||
return value;
|
||||
}
|
||||
|
||||
const char* v = (const char*) sysConfig().values[KEY_UDF_ACCESS];
|
||||
const char* v = (const char*) getDefaultConfig()->values[KEY_UDF_ACCESS];
|
||||
if (CASE_SENSITIVITY ? (! strcmp(v, UDF_DEFAULT_CONFIG_VALUE) && FB_UDFDIR[0]) :
|
||||
(! fb_utils::stricmp(v, UDF_DEFAULT_CONFIG_VALUE) && FB_UDFDIR[0]))
|
||||
{
|
||||
@ -465,66 +540,66 @@ const char *Config::getUdfAccess()
|
||||
|
||||
const char *Config::getTempDirectories()
|
||||
{
|
||||
return (const char*) sysConfig().values[KEY_TEMP_DIRECTORIES];
|
||||
return (const char*) getDefaultConfig()->values[KEY_TEMP_DIRECTORIES];
|
||||
}
|
||||
|
||||
bool Config::getBugcheckAbort()
|
||||
{
|
||||
return (bool) sysConfig().values[KEY_BUGCHECK_ABORT];
|
||||
return (bool) getDefaultConfig()->values[KEY_BUGCHECK_ABORT];
|
||||
}
|
||||
|
||||
bool Config::getLegacyHash()
|
||||
{
|
||||
return (bool) sysConfig().values[KEY_LEGACY_HASH];
|
||||
return (bool) getDefaultConfig()->values[KEY_LEGACY_HASH];
|
||||
}
|
||||
|
||||
const char *Config::getGCPolicy()
|
||||
const char *Config::getGCPolicy() const
|
||||
{
|
||||
return (const char*) sysConfig().values[KEY_GC_POLICY];
|
||||
return get<const char*>(KEY_GC_POLICY);
|
||||
}
|
||||
|
||||
bool Config::getRedirection()
|
||||
{
|
||||
return (bool) sysConfig().values[KEY_REDIRECTION];
|
||||
return (bool) getDefaultConfig()->values[KEY_REDIRECTION];
|
||||
}
|
||||
|
||||
const char *Config::getAuthMethod()
|
||||
{
|
||||
return (const char*) sysConfig().values[KEY_AUTH_METHOD];
|
||||
return (const char*) getDefaultConfig()->values[KEY_AUTH_METHOD];
|
||||
}
|
||||
|
||||
int Config::getDatabaseGrowthIncrement()
|
||||
int Config::getDatabaseGrowthIncrement() const
|
||||
{
|
||||
return (int) sysConfig().values[KEY_DATABASE_GROWTH_INCREMENT];
|
||||
return get<int>(KEY_DATABASE_GROWTH_INCREMENT);
|
||||
}
|
||||
|
||||
int Config::getFileSystemCacheThreshold()
|
||||
int Config::getFileSystemCacheThreshold() const
|
||||
{
|
||||
int rc = (int) sysConfig().values[KEY_FILESYSTEM_CACHE_THRESHOLD];
|
||||
int rc = get<int>(KEY_FILESYSTEM_CACHE_THRESHOLD);
|
||||
return rc < 0 ? 0 : rc;
|
||||
}
|
||||
|
||||
bool Config::getRelaxedAliasChecking()
|
||||
{
|
||||
return (bool) sysConfig().values[KEY_RELAXED_ALIAS_CHECKING];
|
||||
return (bool) getDefaultConfig()->values[KEY_RELAXED_ALIAS_CHECKING];
|
||||
}
|
||||
|
||||
bool Config::getOldSetClauseSemantics()
|
||||
{
|
||||
return (bool) sysConfig().values[KEY_OLD_SET_CLAUSE_SEMANTICS];
|
||||
return (bool) getDefaultConfig()->values[KEY_OLD_SET_CLAUSE_SEMANTICS];
|
||||
}
|
||||
|
||||
int Config::getFileSystemCacheSize()
|
||||
{
|
||||
return (int) sysConfig().values[KEY_FILESYSTEM_CACHE_SIZE];
|
||||
return (int) getDefaultConfig()->values[KEY_FILESYSTEM_CACHE_SIZE];
|
||||
}
|
||||
|
||||
const char *Config::getAuditTraceConfigFile()
|
||||
{
|
||||
return (const char*) sysConfig().values[KEY_TRACE_CONFIG];
|
||||
return (const char*) getDefaultConfig()->values[KEY_TRACE_CONFIG];
|
||||
}
|
||||
|
||||
int Config::getMaxUserTraceLogSize()
|
||||
{
|
||||
return (int) sysConfig().values[KEY_MAX_TRACELOG_SIZE];
|
||||
return (int) getDefaultConfig()->values[KEY_MAX_TRACELOG_SIZE];
|
||||
}
|
||||
|
@ -23,8 +23,9 @@
|
||||
#ifndef COMMON_CONFIG_H
|
||||
#define COMMON_CONFIG_H
|
||||
|
||||
#include "../common/classes/alloc.h"
|
||||
#include "../common/classes/fb_string.h"
|
||||
#include "../jrd/os/path_utils.h"
|
||||
#include "../common/classes/RefCounted.h"
|
||||
|
||||
/**
|
||||
Since the original (isc.cpp) code wasn't able to provide powerful and
|
||||
@ -68,8 +69,13 @@ extern const char* AmMixed;
|
||||
|
||||
enum AmCache {AM_UNKNOWN, AM_DISABLED, AM_ENABLED};
|
||||
|
||||
class Config
|
||||
class ConfigFile;
|
||||
|
||||
class Config : public Firebird::RefCounted, public Firebird::GlobalStorage
|
||||
{
|
||||
public:
|
||||
typedef IPTR ConfigValue;
|
||||
|
||||
enum ConfigKey
|
||||
{
|
||||
KEY_ROOT_DIRECTORY,
|
||||
@ -116,13 +122,45 @@ class Config
|
||||
KEY_OLD_SET_CLAUSE_SEMANTICS,
|
||||
KEY_TRACE_CONFIG,
|
||||
KEY_MAX_TRACELOG_SIZE,
|
||||
KEY_FILESYSTEM_CACHE_SIZE
|
||||
KEY_FILESYSTEM_CACHE_SIZE,
|
||||
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 Firebird::PathName getValue(const ConfigFile&, ConfigName);
|
||||
|
||||
static int asInteger(const Firebird::PathName&);
|
||||
static bool asBoolean(const Firebird::PathName&);
|
||||
static const char* asString(const Firebird::PathName&);
|
||||
void loadValues(const ConfigFile& file);
|
||||
template <typename T> T get(Config::ConfigKey key) const;
|
||||
|
||||
static const ConfigEntry entries[MAX_CONFIG_KEY];
|
||||
ConfigValue values[MAX_CONFIG_KEY];
|
||||
|
||||
public:
|
||||
Config(const ConfigFile& file); // use to build default config
|
||||
Config(const ConfigFile& file, const Config& base); // use to build db-specific config
|
||||
~Config();
|
||||
|
||||
// Interface to support command line root specification.
|
||||
|
||||
// This ugly solution was required to make it possible to specify root
|
||||
// in command line to load firebird.conf from that root, though in other
|
||||
// cases firebird.conf may be also used to specify root.
|
||||
@ -130,6 +168,12 @@ public:
|
||||
static void setRootDirectoryFromCommandLine(const Firebird::PathName& newRoot);
|
||||
static const Firebird::PathName* getCommandLineRootDirectory();
|
||||
|
||||
// Master config - needed to provide per-database config
|
||||
static const Firebird::RefPtr<Config> getDefaultConfig();
|
||||
|
||||
// Static functions apply to instance-wide values,
|
||||
// non-static may be specified per database.
|
||||
|
||||
// Installation directory
|
||||
static const char* getInstallDirectory();
|
||||
|
||||
@ -137,10 +181,10 @@ public:
|
||||
static const char* getRootDirectory();
|
||||
|
||||
// Allocation chunk for the temporary spaces
|
||||
static int getTempBlockSize();
|
||||
int getTempBlockSize() const;
|
||||
|
||||
// Caching limit for the temporary data
|
||||
static int getTempCacheLimit();
|
||||
int getTempCacheLimit() const;
|
||||
|
||||
// Whether remote (NFS) files can be opened
|
||||
static bool getRemoteFileOpenAbility();
|
||||
@ -158,7 +202,7 @@ public:
|
||||
static bool getTcpNoNagle();
|
||||
|
||||
// Default database cache size
|
||||
static int getDefaultDbCachePages();
|
||||
int getDefaultDbCachePages() const;
|
||||
|
||||
// Connection timeout
|
||||
static int getConnectionTimeout();
|
||||
@ -167,22 +211,22 @@ public:
|
||||
static int getDummyPacketInterval();
|
||||
|
||||
// Lock manager memory size
|
||||
static int getLockMemSize();
|
||||
int getLockMemSize() const;
|
||||
|
||||
// Lock manager grant order
|
||||
static bool getLockGrantOrder();
|
||||
bool getLockGrantOrder() const;
|
||||
|
||||
// Lock manager hash slots
|
||||
static int getLockHashSlots();
|
||||
int getLockHashSlots() const;
|
||||
|
||||
// Lock manager acquire spins
|
||||
static int getLockAcquireSpins();
|
||||
int getLockAcquireSpins() const;
|
||||
|
||||
// Event manager memory size
|
||||
static int getEventMemSize();
|
||||
int getEventMemSize() const;
|
||||
|
||||
// Deadlock timeout
|
||||
static int getDeadlockTimeout();
|
||||
int getDeadlockTimeout() const;
|
||||
|
||||
// Priority switch delay
|
||||
static int getPrioritySwitchDelay();
|
||||
@ -206,10 +250,10 @@ public:
|
||||
static const char *getIpcName();
|
||||
|
||||
// Unflushed writes number
|
||||
static int getMaxUnflushedWrites();
|
||||
int getMaxUnflushedWrites() const;
|
||||
|
||||
// Unflushed write time
|
||||
static int getMaxUnflushedWriteTime();
|
||||
int getMaxUnflushedWriteTime() const;
|
||||
|
||||
// Process priority level
|
||||
static int getProcessPriorityLevel();
|
||||
@ -221,7 +265,7 @@ public:
|
||||
static const char *getRemoteBindAddress();
|
||||
|
||||
// Directory list for external tables
|
||||
static const char *getExternalFileAccess();
|
||||
const char *getExternalFileAccess() const;
|
||||
|
||||
// Directory list for databases
|
||||
static const char *getDatabaseAccess();
|
||||
@ -239,7 +283,7 @@ public:
|
||||
static bool getLegacyHash();
|
||||
|
||||
// GC policy
|
||||
static const char *getGCPolicy();
|
||||
const char *getGCPolicy() const;
|
||||
|
||||
// Redirection
|
||||
static bool getRedirection();
|
||||
@ -247,9 +291,9 @@ public:
|
||||
// Use native, trusted or mixed authentication
|
||||
static const char *getAuthMethod();
|
||||
|
||||
static int getDatabaseGrowthIncrement();
|
||||
int getDatabaseGrowthIncrement() const;
|
||||
|
||||
static int getFileSystemCacheThreshold();
|
||||
int getFileSystemCacheThreshold() const;
|
||||
|
||||
static int getFileSystemCacheSize();
|
||||
|
||||
|
@ -22,176 +22,371 @@
|
||||
|
||||
#include "firebird.h"
|
||||
|
||||
#include "../../common/classes/alloc.h"
|
||||
#include "../../common/classes/auto.h"
|
||||
#include "../../common/config/config_file.h"
|
||||
#include "../jrd/os/fbsyslog.h"
|
||||
#include "../common/classes/alloc.h"
|
||||
#include "../common/classes/auto.h"
|
||||
#include "../common/config/config_file.h"
|
||||
#include "../common/config/config.h"
|
||||
#include "../jrd/os/path_utils.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
// Invalid or missing CONF_FILE may lead to severe errors
|
||||
// in applications. That's why for regular SERVER builds
|
||||
// it's better to exit with appropriate diags rather continue
|
||||
// with missing / wrong configuration.
|
||||
#if (! defined(BOOT_BUILD)) && (! defined(EMBEDDED)) && (! defined(SUPERCLIENT))
|
||||
#define EXCEPTION_ON_NO_CONF
|
||||
#else
|
||||
#undef EXCEPTION_ON_NO_CONF
|
||||
#endif
|
||||
using namespace Firebird;
|
||||
|
||||
// config_file works with OS case-sensitivity
|
||||
typedef Firebird::PathName string;
|
||||
namespace {
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Strip any comments
|
||||
*/
|
||||
|
||||
bool ConfigFile::stripComments(string& s) const
|
||||
class MainStream : public ConfigFile::Stream
|
||||
{
|
||||
if (!parsingAliases)
|
||||
public:
|
||||
MainStream(const char* fname, bool fExceptionOnError)
|
||||
: file(fopen(fname, "rt")), l(0)
|
||||
{
|
||||
// Simple, fast processing for firebird.conf
|
||||
// Note that this is only a hack. It won't work in case inputLine
|
||||
// contains hash-marks embedded in quotes! Not that I know if we
|
||||
// should care about that case.
|
||||
const string::size_type commentPos = s.find('#');
|
||||
if (commentPos != string::npos)
|
||||
if ((!file) && fExceptionOnError)
|
||||
{
|
||||
s = s.substr(0, commentPos);
|
||||
// config file does not exist
|
||||
fatal_exception::raiseFmt("Missing configuration file: ", fname);
|
||||
}
|
||||
}
|
||||
|
||||
bool getLine(ConfigFile::String& input, unsigned int& line)
|
||||
{
|
||||
input = "";
|
||||
if (!file)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// this loop efficiently skips almost all comment lines
|
||||
do
|
||||
{
|
||||
if (feof(file))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
input.LoadFromFile(file);
|
||||
++l;
|
||||
input.alltrim(" \t\r");
|
||||
} while (input.isEmpty() || input[0] == '#');
|
||||
line = l;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Paranoid, slow processing for aliases.conf
|
||||
bool equalSeen = false, inString = false;
|
||||
const char* iter = s.begin();
|
||||
const char* end = s.end();
|
||||
private:
|
||||
AutoPtr<FILE, FileClose> file;
|
||||
unsigned int l;
|
||||
};
|
||||
|
||||
while (iter < end)
|
||||
class TextStream : public ConfigFile::Stream
|
||||
{
|
||||
public:
|
||||
TextStream(const char* configText)
|
||||
: s(configText), l(0)
|
||||
{
|
||||
switch (*iter)
|
||||
if (s && !*s)
|
||||
{
|
||||
case '"':
|
||||
if (!equalSeen) // quoted string to the left of = doesn't make sense
|
||||
return false;
|
||||
inString = !inString; // We don't support embedded quotes
|
||||
if (!inString) // we finished a quoted string
|
||||
s = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool getLine(ConfigFile::String& input, unsigned int& line)
|
||||
{
|
||||
do
|
||||
{
|
||||
if (!s)
|
||||
{
|
||||
// We don't want trash after closing the quoted string, except comments
|
||||
const string::size_type startPos = s.find_first_not_of(" \t\r", iter + 1 - s.begin());
|
||||
if (startPos == string::npos || s[startPos] == '#')
|
||||
input = "";
|
||||
return false;
|
||||
}
|
||||
const char* ptr = strchr(s, '\n');
|
||||
if (!ptr)
|
||||
{
|
||||
input.assign(s);
|
||||
s = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
input.assign(s, ptr - s);
|
||||
s = ptr + 1;
|
||||
if (!*s)
|
||||
{
|
||||
s = s.substr(0, iter + 1 - s.begin());
|
||||
return true;
|
||||
s = NULL;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case '=':
|
||||
equalSeen = true;
|
||||
break;
|
||||
case '#':
|
||||
if (!inString)
|
||||
{
|
||||
s = s.substr(0, iter - s.begin());
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
++l;
|
||||
input.alltrim(" \t\r");
|
||||
} while (input.isEmpty() || input[0] == '#');
|
||||
line = l;
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
const char* s;
|
||||
unsigned int l;
|
||||
};
|
||||
|
||||
class SubStream : public ConfigFile::Stream
|
||||
{
|
||||
public:
|
||||
SubStream()
|
||||
: cnt(0)
|
||||
{ }
|
||||
|
||||
bool getLine(ConfigFile::String& input, unsigned int& line)
|
||||
{
|
||||
if (cnt >= data.getCount())
|
||||
{
|
||||
input = "";
|
||||
return false;
|
||||
}
|
||||
|
||||
++iter;
|
||||
input = data[cnt].first;
|
||||
line = data[cnt].second;
|
||||
++cnt;
|
||||
return true;
|
||||
}
|
||||
|
||||
return !inString; // If we are still inside a string, it's error
|
||||
void putLine(const ConfigFile::String& input, unsigned int line)
|
||||
{
|
||||
data.push(Line(input, line));
|
||||
}
|
||||
|
||||
private:
|
||||
typedef Pair<Left<ConfigFile::String, unsigned int> > Line;
|
||||
ObjectsArray<Line> data;
|
||||
size_t cnt;
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
ConfigFile::ConfigFile(const ConfigFile::String& file, USHORT fl)
|
||||
: AutoStorage(), configFile(getPool(), file), parameters(getPool()), flags(fl)
|
||||
{
|
||||
MainStream s(configFile.c_str(), flags & EXCEPTION_ON_ERROR);
|
||||
parse(&s);
|
||||
}
|
||||
|
||||
ConfigFile::ConfigFile(const char* file, USHORT fl)
|
||||
: AutoStorage(), configFile(getPool(), String(file)), parameters(getPool()), flags(fl)
|
||||
{
|
||||
MainStream s(configFile.c_str(), flags & EXCEPTION_ON_ERROR);
|
||||
parse(&s);
|
||||
}
|
||||
|
||||
ConfigFile::ConfigFile(UseText, const char* configText, USHORT fl)
|
||||
: AutoStorage(), configFile(getPool()), parameters(getPool()), flags(fl)
|
||||
{
|
||||
TextStream s(configText);
|
||||
parse(&s);
|
||||
}
|
||||
|
||||
ConfigFile::ConfigFile(MemoryPool& p, ConfigFile::Stream* s, USHORT fl, const String& file)
|
||||
: AutoStorage(p), configFile(getPool(), file), parameters(getPool()), flags(fl)
|
||||
{
|
||||
parse(s);
|
||||
}
|
||||
|
||||
ConfigFile::Stream::~Stream() { }
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Parse line, taking quotes into an account
|
||||
*/
|
||||
|
||||
ConfigFile::LineType ConfigFile::parseLine(const String& input, String& key, String& value)
|
||||
{
|
||||
int inString = 0;
|
||||
String::size_type valStart = 0;
|
||||
String::size_type eol = String::npos;
|
||||
bool hasSub = false;
|
||||
|
||||
for (String::size_type n=0; n < input.length(); ++n)
|
||||
{
|
||||
switch (input[n])
|
||||
{
|
||||
case '"':
|
||||
if (key.isEmpty()) // quoted string to the left of = doesn't make sense
|
||||
return LINE_BAD;
|
||||
if (inString >= 2) // one more quote after quoted string doesn't make sense
|
||||
return LINE_BAD;
|
||||
inString++;
|
||||
break;
|
||||
|
||||
case '=':
|
||||
key = input.substr(0, n);
|
||||
key.rtrim(" \t\r");
|
||||
if (key.isEmpty()) // not good - no key
|
||||
return LINE_BAD;
|
||||
valStart = n + 1;
|
||||
break;
|
||||
|
||||
case '#':
|
||||
if (inString != 1)
|
||||
{
|
||||
eol = n;
|
||||
n = input.length(); // skip the rest of symbols
|
||||
}
|
||||
break;
|
||||
|
||||
case ' ':
|
||||
case '\t':
|
||||
case '\r':
|
||||
break;
|
||||
|
||||
case '{':
|
||||
case '}':
|
||||
if (flags & HAS_SUB_CONF)
|
||||
{
|
||||
if (inString != 1) {
|
||||
if (input[n] == '}') // Subconf close mark not expected
|
||||
{
|
||||
return LINE_BAD;
|
||||
}
|
||||
|
||||
hasSub = true;
|
||||
inString = 2;
|
||||
eol = n;
|
||||
}
|
||||
break;
|
||||
}
|
||||
// fall through ....
|
||||
|
||||
default:
|
||||
if (inString >= 2) // Something after the end of line
|
||||
return LINE_BAD;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (inString == 1) // If we are still inside a string, it's error
|
||||
return LINE_BAD;
|
||||
|
||||
if (key.isEmpty())
|
||||
{
|
||||
key = input.substr(0, eol);
|
||||
key.rtrim(" \t\r");
|
||||
}
|
||||
else
|
||||
{
|
||||
value = input.substr(valStart, eol - valStart);
|
||||
value.alltrim(" \t\r");
|
||||
value.alltrim("\"");
|
||||
}
|
||||
|
||||
// Now expand macros in value
|
||||
String::size_type subFrom;
|
||||
while ((subFrom = value.find("$(")) != String::npos)
|
||||
{
|
||||
String::size_type subTo = value.find(")", subFrom);
|
||||
if (subTo != String::npos)
|
||||
{
|
||||
String macro;
|
||||
String m = value.substr(subFrom + 2, subTo - (subFrom + 2));
|
||||
if (! translate(m, macro))
|
||||
{
|
||||
return LINE_BAD;
|
||||
}
|
||||
value.replace(subFrom, subTo + 1 - subFrom, macro);
|
||||
}
|
||||
else
|
||||
{
|
||||
return LINE_BAD;
|
||||
}
|
||||
}
|
||||
|
||||
return hasSub ? LINE_START_SUB : LINE_REGULAR;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Check whether the given key exists or not
|
||||
* Find macro value
|
||||
*/
|
||||
|
||||
bool ConfigFile::doesKeyExist(const string& key)
|
||||
bool ConfigFile::translate(const String& from, String& to)
|
||||
{
|
||||
checkLoadConfig();
|
||||
if (flags & NO_MACRO)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const string data = getString(key);
|
||||
if (from == "root")
|
||||
{
|
||||
to = Config::getRootDirectory();
|
||||
}
|
||||
else if (from == "install")
|
||||
{
|
||||
to = Config::getInstallDirectory();
|
||||
}
|
||||
else if (from == "this")
|
||||
{
|
||||
if (configFile.isEmpty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
PathName file;
|
||||
PathUtils::splitLastComponent(to, file, configFile);
|
||||
}
|
||||
/* else if (!substituteOneOfStandardFirebirdDirs(from, to))
|
||||
{
|
||||
return false;
|
||||
} */
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return !data.empty();
|
||||
return true;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Return string value corresponding the given key
|
||||
* Return parameter corresponding the given key
|
||||
*/
|
||||
|
||||
string ConfigFile::getString(const string& key)
|
||||
const ConfigFile::Parameter* ConfigFile::findParameter(const String& name) const
|
||||
{
|
||||
checkLoadConfig();
|
||||
|
||||
size_t pos;
|
||||
return parameters.find(key, pos) ? parameters[pos].second : string();
|
||||
return parameters.find(name, pos) ? ¶meters[pos] : NULL;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Parse key
|
||||
* Return parameter corresponding the given key and value
|
||||
*/
|
||||
|
||||
string ConfigFile::parseKeyFrom(const string& inputLine, string::size_type& endPos)
|
||||
const ConfigFile::Parameter* ConfigFile::findParameter(const String& name, const String& value) const
|
||||
{
|
||||
endPos = inputLine.find_first_of("=");
|
||||
if (endPos == string::npos)
|
||||
size_t pos;
|
||||
if (!parameters.find(name, pos))
|
||||
{
|
||||
return inputLine;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return inputLine.substr(0, endPos);
|
||||
while(pos < parameters.getCount() && parameters[pos].name == name)
|
||||
{
|
||||
if (parameters[pos].value == value)
|
||||
{
|
||||
return ¶meters[pos];
|
||||
}
|
||||
++pos;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Parse value
|
||||
* Take into an account fault line
|
||||
*/
|
||||
|
||||
string ConfigFile::parseValueFrom(string inputLine, string::size_type initialPos)
|
||||
void ConfigFile::badLine(const String& line)
|
||||
{
|
||||
if (initialPos == string::npos)
|
||||
if (flags & EXCEPTION_ON_ERROR)
|
||||
{
|
||||
return string();
|
||||
}
|
||||
|
||||
// skip leading white spaces
|
||||
const string::size_type startPos = inputLine.find_first_not_of("= \t", initialPos);
|
||||
if (startPos == string::npos)
|
||||
{
|
||||
return string();
|
||||
}
|
||||
|
||||
inputLine.rtrim(" \t\r");
|
||||
// stringComments demands paired quotes but trimming \r may render startPos invalid.
|
||||
if (parsingAliases && inputLine.length() > startPos + 1 &&
|
||||
inputLine[startPos] == '"' && inputLine.end()[-1] == '"')
|
||||
{
|
||||
return inputLine.substr(startPos + 1, inputLine.length() - startPos - 2);
|
||||
}
|
||||
|
||||
return inputLine.substr(startPos);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Load file, if necessary
|
||||
*/
|
||||
|
||||
void ConfigFile::checkLoadConfig()
|
||||
{
|
||||
if (!isLoadedFlg)
|
||||
{
|
||||
loadConfig();
|
||||
fatal_exception::raiseFmt("%s: illegal line <%s>" ,
|
||||
configFile.hasData() ? configFile.c_str() : "Passed text",
|
||||
line.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
@ -200,73 +395,61 @@ void ConfigFile::checkLoadConfig()
|
||||
* Load file immediately
|
||||
*/
|
||||
|
||||
void ConfigFile::loadConfig()
|
||||
void ConfigFile::parse(Stream* stream)
|
||||
{
|
||||
isLoadedFlg = true;
|
||||
String inputLine;
|
||||
Parameter* previous = NULL;
|
||||
unsigned int line;
|
||||
|
||||
parameters.clear();
|
||||
|
||||
Firebird::AutoPtr<FILE, Firebird::FileClose> ifile(fopen(configFile.c_str(), "rt"));
|
||||
|
||||
#ifdef EXCEPTION_ON_NO_CONF
|
||||
int BadLinesCount = 0;
|
||||
#endif
|
||||
if (!ifile)
|
||||
while (stream->getLine(inputLine, line))
|
||||
{
|
||||
// config file does not exist
|
||||
#ifdef EXCEPTION_ON_NO_CONF
|
||||
if (fExceptionOnError)
|
||||
Parameter current;
|
||||
current.line = line;
|
||||
|
||||
switch(parseLine(inputLine, current.name, current.value))
|
||||
{
|
||||
const Firebird::string msg =
|
||||
"Missing configuration file: " + configFile.ToString() + ", exiting";
|
||||
Firebird::Syslog::Record(Firebird::Syslog::Error, msg.c_str());
|
||||
Firebird::fatal_exception::raise(msg.c_str());
|
||||
case LINE_BAD:
|
||||
badLine(inputLine);
|
||||
break;
|
||||
|
||||
case LINE_REGULAR:
|
||||
if (current.name.isEmpty())
|
||||
{
|
||||
badLine(inputLine);
|
||||
break;
|
||||
}
|
||||
|
||||
previous = ¶meters[parameters.add(current)];
|
||||
break;
|
||||
|
||||
case LINE_START_SUB:
|
||||
if (current.name.hasData())
|
||||
{
|
||||
size_t n = parameters.add(current);
|
||||
previous = ¶meters[n];
|
||||
}
|
||||
{ // subconf scope
|
||||
SubStream subStream;
|
||||
while (stream->getLine(inputLine, line))
|
||||
{
|
||||
if (inputLine[0] == '}')
|
||||
{
|
||||
String s = inputLine.substr(1);
|
||||
s.ltrim(" \t\r");
|
||||
if (s.hasData() && s[0] != '#')
|
||||
{
|
||||
badLine(s);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
subStream.putLine(inputLine, line);
|
||||
}
|
||||
|
||||
previous->sub = FB_NEW(getPool()) ConfigFile(getPool(), &subStream,
|
||||
flags & ~HAS_SUB_CONF, configFile);
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif //EXCEPTION_ON_NO_CONF
|
||||
return;
|
||||
}
|
||||
string inputLine;
|
||||
|
||||
while (!feof(ifile))
|
||||
{
|
||||
inputLine.LoadFromFile(ifile);
|
||||
|
||||
const bool goodLine = stripComments(inputLine);
|
||||
inputLine.ltrim(" \t\r");
|
||||
|
||||
if (!inputLine.size())
|
||||
{
|
||||
continue; // comment-line or empty line
|
||||
}
|
||||
|
||||
if (!goodLine || inputLine.find('=') == string::npos)
|
||||
{
|
||||
const Firebird::string msg =
|
||||
(configFile + ": illegal line \"" + inputLine + "\"").ToString();
|
||||
Firebird::Syslog::Record(fExceptionOnError ?
|
||||
Firebird::Syslog::Error : Firebird::Syslog::Warning,
|
||||
msg.c_str());
|
||||
#ifdef EXCEPTION_ON_NO_CONF
|
||||
BadLinesCount++;
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
|
||||
string::size_type endPos;
|
||||
|
||||
string key = parseKeyFrom(inputLine, endPos);
|
||||
key.rtrim(" \t\r");
|
||||
// TODO: here we must check for correct parameter spelling !
|
||||
const string value = parseValueFrom(inputLine, endPos);
|
||||
|
||||
parameters.add(Parameter(getPool(), key, value));
|
||||
}
|
||||
#ifdef EXCEPTION_ON_NO_CONF
|
||||
if (BadLinesCount && fExceptionOnError)
|
||||
{
|
||||
Firebird::fatal_exception::raise("Bad lines in firebird.conf");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -23,10 +23,11 @@
|
||||
#ifndef CONFIG_CONFIG_FILE_H
|
||||
#define CONFIG_CONFIG_FILE_H
|
||||
|
||||
#include "../../common/classes/alloc.h"
|
||||
#include "../../common/classes/fb_pair.h"
|
||||
#include "../../common/classes/objects_array.h"
|
||||
#include "../common/classes/alloc.h"
|
||||
#include "../common/classes/fb_pair.h"
|
||||
#include "../common/classes/objects_array.h"
|
||||
#include "../common/classes/fb_string.h"
|
||||
#include "../common/classes/auto.h"
|
||||
|
||||
/**
|
||||
Since the original (isc.cpp) code wasn't able to provide powerful and
|
||||
@ -45,56 +46,82 @@
|
||||
(common/config/config.cpp) and server-side alias manager (jrd/db_alias.cpp).
|
||||
**/
|
||||
|
||||
class ConfigFile : public Firebird::AutoStorage
|
||||
class ConfigFile : public Firebird::AutoStorage, public Firebird::RefCounted
|
||||
{
|
||||
// config_file works with OS case-sensitivity
|
||||
typedef Firebird::PathName string;
|
||||
|
||||
typedef Firebird::Pair<Firebird::Full<string, string> > Parameter;
|
||||
|
||||
typedef Firebird::SortedObjectsArray <Parameter,
|
||||
Firebird::InlineStorage<Parameter *, 100>,
|
||||
string, Firebird::FirstPointerKey<Parameter> > mymap_t;
|
||||
|
||||
public:
|
||||
ConfigFile(MemoryPool& p, bool ExceptionOnError)
|
||||
: AutoStorage(p), isLoadedFlg(false),
|
||||
fExceptionOnError(ExceptionOnError), parsingAliases(false),
|
||||
parameters(getPool()) {}
|
||||
ConfigFile(bool ExceptionOnError, bool useForAliases)
|
||||
: AutoStorage(), isLoadedFlg(false),
|
||||
fExceptionOnError(ExceptionOnError), parsingAliases(useForAliases),
|
||||
parameters(getPool()) {}
|
||||
// flags for config file
|
||||
static const USHORT EXCEPTION_ON_ERROR = 0x01;
|
||||
static const USHORT HAS_SUB_CONF = 0x02;
|
||||
static const USHORT NO_MACRO = 0x04;
|
||||
|
||||
explicit ConfigFile(bool ExceptionOnError)
|
||||
: AutoStorage(), isLoadedFlg(false),
|
||||
fExceptionOnError(ExceptionOnError), parsingAliases(false),
|
||||
parameters(getPool()) {}
|
||||
// enum to distinguish ctors
|
||||
enum UseText {USE_TEXT};
|
||||
|
||||
// configuration file management
|
||||
const string getConfigFilePath() const { return configFile; }
|
||||
void setConfigFilePath(const string& newFile) { configFile = newFile; }
|
||||
// config_file works with OS case-sensitivity
|
||||
typedef Firebird::PathName String;
|
||||
|
||||
bool isLoaded() const { return isLoadedFlg; }
|
||||
class Stream
|
||||
{
|
||||
public:
|
||||
virtual ~Stream();
|
||||
virtual bool getLine(String&, unsigned int&) = 0;
|
||||
};
|
||||
|
||||
void loadConfig();
|
||||
void checkLoadConfig();
|
||||
struct Parameter : public AutoStorage
|
||||
{
|
||||
Parameter(MemoryPool& p, const Parameter& par)
|
||||
: AutoStorage(p), name(getPool(), par.name), value(getPool(), par.value),
|
||||
sub(par.sub), line(par.line)
|
||||
{ }
|
||||
Parameter()
|
||||
: AutoStorage(), name(getPool()), value(getPool()), sub(0), line(0)
|
||||
{ }
|
||||
|
||||
String name;
|
||||
String value;
|
||||
Firebird::RefPtr<ConfigFile> sub;
|
||||
unsigned int line;
|
||||
|
||||
// key and value management
|
||||
bool doesKeyExist(const string&);
|
||||
string getString(const string&);
|
||||
static const String* generate(const void* /*sender*/, const Parameter* item)
|
||||
{
|
||||
return &item->name;
|
||||
}
|
||||
};
|
||||
|
||||
typedef Firebird::SortedObjectsArray <Parameter, Firebird::InlineStorage<Parameter*, 100>,
|
||||
String, Parameter> Parameters;
|
||||
|
||||
// utilities
|
||||
bool stripComments(string&) const;
|
||||
static string parseKeyFrom(const string&, string::size_type&);
|
||||
string parseValueFrom(string, string::size_type);
|
||||
ConfigFile(const String& file, USHORT fl);
|
||||
ConfigFile(const char* file, USHORT fl);
|
||||
ConfigFile(UseText, const char* configText, USHORT fl);
|
||||
|
||||
private:
|
||||
string configFile;
|
||||
bool isLoadedFlg;
|
||||
const bool fExceptionOnError;
|
||||
const bool parsingAliases;
|
||||
mymap_t parameters;
|
||||
ConfigFile(MemoryPool& p, ConfigFile::Stream* s, USHORT fl, const String& file);
|
||||
|
||||
public:
|
||||
// key and value management
|
||||
const Parameter* findParameter(const String& name) const;
|
||||
const Parameter* findParameter(const String& name, const String& value) const;
|
||||
|
||||
// all parameters access
|
||||
const Parameters& getParameters() const
|
||||
{
|
||||
return parameters;
|
||||
}
|
||||
|
||||
private:
|
||||
enum LineType {LINE_BAD, LINE_REGULAR, LINE_START_SUB};
|
||||
|
||||
String configFile;
|
||||
Parameters parameters;
|
||||
USHORT flags;
|
||||
USHORT badLinesCount;
|
||||
|
||||
// utilities
|
||||
void parse(Stream* stream);
|
||||
LineType parseLine(const String& input, String& key, String& value);
|
||||
bool translate(const String& from, String& to);
|
||||
void badLine(const String& line);
|
||||
};
|
||||
|
||||
#endif // CONFIG_CONFIG_FILE_H
|
||||
|
@ -1,81 +0,0 @@
|
||||
/*
|
||||
* 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 Dmitry Yemanov
|
||||
* for the Firebird Open Source RDBMS project.
|
||||
*
|
||||
* Copyright (c) 2002 Dmitry Yemanov <dimitr@users.sf.net>
|
||||
* and all contributors signed below.
|
||||
*
|
||||
* All Rights Reserved.
|
||||
* Contributor(s): ______________________________________.
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_IMPL_H
|
||||
#define CONFIG_IMPL_H
|
||||
|
||||
#include "fb_types.h"
|
||||
#include "../../common/classes/fb_string.h"
|
||||
|
||||
#include "../../common/config/config.h"
|
||||
#include "../../common/config/config_file.h"
|
||||
#include "../jrd/os/config_root.h"
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Main implementation class
|
||||
*/
|
||||
|
||||
class ConfigImpl : public ConfigRoot
|
||||
{
|
||||
friend class Config;
|
||||
// config_file works with OS case-sensitivity
|
||||
typedef Firebird::PathName string;
|
||||
|
||||
enum ConfigType
|
||||
{
|
||||
TYPE_BOOLEAN,
|
||||
TYPE_INTEGER,
|
||||
TYPE_STRING
|
||||
//TYPE_STRING_VECTOR // CVC: Unused
|
||||
};
|
||||
|
||||
typedef const char* ConfigKey;
|
||||
typedef IPTR ConfigValue;
|
||||
|
||||
struct ConfigEntry
|
||||
{
|
||||
ConfigType data_type;
|
||||
ConfigKey key;
|
||||
ConfigValue default_value;
|
||||
};
|
||||
|
||||
public:
|
||||
explicit ConfigImpl(MemoryPool& p);
|
||||
~ConfigImpl();
|
||||
|
||||
static string getValue(ConfigFile&, const ConfigKey);
|
||||
|
||||
static int asInteger(const string&);
|
||||
static bool asBoolean(const string&);
|
||||
static const char* asString(const string&);
|
||||
|
||||
private:
|
||||
static const ConfigEntry entries[];
|
||||
const char *root_dir;
|
||||
ConfigValue *values;
|
||||
|
||||
ConfigImpl(const ConfigImpl&);
|
||||
void operator=(const ConfigImpl&);
|
||||
};
|
||||
|
||||
#endif // CONFIG_IMPL_H
|
@ -1,68 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* 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/idpl.html.
|
||||
*
|
||||
* Software distributed under the License is distributed on
|
||||
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
|
||||
* express or implied. See the License for the specific
|
||||
* language governing rights and limitations under the License.
|
||||
*
|
||||
* The contents of this file or any work derived from this file
|
||||
* may not be distributed under any other license whatsoever
|
||||
* without the express prior written permission of the original
|
||||
* author.
|
||||
*
|
||||
*
|
||||
* The Original Code was created by James A. Starkey for IBPhoenix.
|
||||
*
|
||||
* Copyright (c) 1997 - 2000, 2001, 2003 James A. Starkey
|
||||
* Copyright (c) 1997 - 2000, 2001, 2003 Netfrastructure, Inc.
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
|
||||
// AdminException.cpp: implementation of the AdminException class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "firebird.h"
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include "../common/classes/alloc.h"
|
||||
#include "AdminException.h"
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
AdminException::AdminException(const char* txt, ...) :
|
||||
text(getPool()), fileName(getPool())
|
||||
{
|
||||
va_list args;
|
||||
va_start (args, txt);
|
||||
text.vprintf(txt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
AdminException::~AdminException()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
const char* AdminException::getText() const
|
||||
{
|
||||
return text.c_str();
|
||||
}
|
||||
|
||||
void AdminException::setLocation(const Firebird::PathName& file, int lineNumber)
|
||||
{
|
||||
fileName = file;
|
||||
Firebird::string buffer;
|
||||
|
||||
buffer.printf("%s, line %d: %s", fileName.c_str(), lineNumber, text.c_str());
|
||||
text = buffer;
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* 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/idpl.html.
|
||||
*
|
||||
* Software distributed under the License is distributed on
|
||||
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
|
||||
* express or implied. See the License for the specific
|
||||
* language governing rights and limitations under the License.
|
||||
*
|
||||
* The contents of this file or any work derived from this file
|
||||
* may not be distributed under any other license whatsoever
|
||||
* without the express prior written permission of the original
|
||||
* author.
|
||||
*
|
||||
*
|
||||
* The Original Code was created by James A. Starkey for IBPhoenix.
|
||||
*
|
||||
* Copyright (c) 1997 - 2000, 2001, 2003 James A. Starkey
|
||||
* Copyright (c) 1997 - 2000, 2001, 2003 Netfrastructure, Inc.
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
|
||||
// AdminException.h: interface for the AdminException class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(AFX_ADMINEXCEPTION_H__ED22B745_F780_416D_8291_0A2D49EF5B43__INCLUDED_)
|
||||
#define AFX_ADMINEXCEPTION_H__ED22B745_F780_416D_8291_0A2D49EF5B43__INCLUDED_
|
||||
|
||||
#if defined _MSC_VER && _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
#include "../common/classes/fb_string.h"
|
||||
|
||||
class AdminException : public Firebird::GlobalStorage
|
||||
{
|
||||
public:
|
||||
AdminException(const char* txt, ...);
|
||||
virtual ~AdminException();
|
||||
void setLocation (const Firebird::PathName& fileName, int lineNumber);
|
||||
const char* getText() const;
|
||||
|
||||
private:
|
||||
Firebird::string text;
|
||||
Firebird::PathName fileName;
|
||||
};
|
||||
|
||||
#endif // !defined(AFX_ADMINEXCEPTION_H__ED22B745_F780_416D_8291_0A2D49EF5B43__INCLUDED_)
|
@ -1,262 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* 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/idpl.html.
|
||||
*
|
||||
* Software distributed under the License is distributed on
|
||||
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
|
||||
* express or implied. See the License for the specific
|
||||
* language governing rights and limitations under the License.
|
||||
*
|
||||
* The contents of this file or any work derived from this file
|
||||
* may not be distributed under any other license whatsoever
|
||||
* without the express prior written permission of the original
|
||||
* author.
|
||||
*
|
||||
*
|
||||
* The Original Code was created by James A. Starkey for IBPhoenix.
|
||||
*
|
||||
* Copyright (c) 1997 - 2000, 2001, 2003 James A. Starkey
|
||||
* Copyright (c) 1997 - 2000, 2001, 2003 Netfrastructure, Inc.
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
// Args.cpp: implementation of the Args class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <termios.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "firebird.h"
|
||||
#include "Args.h"
|
||||
#include "ArgsException.h"
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
class ConsoleNoEcho
|
||||
{
|
||||
public:
|
||||
ConsoleNoEcho();
|
||||
~ConsoleNoEcho();
|
||||
private:
|
||||
#ifdef _WIN32
|
||||
HANDLE m_stdin;
|
||||
DWORD m_orgSettings;
|
||||
#else
|
||||
termios m_orgSettings;
|
||||
#endif
|
||||
};
|
||||
|
||||
ConsoleNoEcho::ConsoleNoEcho()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
m_stdin = GetStdHandle(STD_INPUT_HANDLE);
|
||||
GetConsoleMode(m_stdin, &m_orgSettings);
|
||||
const DWORD newSettings = m_orgSettings & ~(ENABLE_ECHO_INPUT);
|
||||
SetConsoleMode(m_stdin, newSettings);
|
||||
#else
|
||||
tcgetattr(0, &m_orgSettings);
|
||||
termios newSettings = m_orgSettings;
|
||||
newSettings.c_lflag &= (~ECHO);
|
||||
tcsetattr(0, TCSANOW, &newSettings);
|
||||
#endif
|
||||
}
|
||||
|
||||
ConsoleNoEcho::~ConsoleNoEcho()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
SetConsoleMode(m_stdin, m_orgSettings);
|
||||
#else
|
||||
tcsetattr(0, TCSANOW, &m_orgSettings);
|
||||
#endif
|
||||
}
|
||||
} // namespace
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
Args::Args()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Args::~Args()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Args::parse(const Switches* switches, int argc, const char* const* argv)
|
||||
{
|
||||
const char* const* const end = argv + argc;
|
||||
while (argv < end)
|
||||
{
|
||||
const char* p = *argv++;
|
||||
const Switches* parameter = NULL;
|
||||
bool hit = false;
|
||||
for (const Switches* sw = switches; sw->string; ++sw)
|
||||
{
|
||||
if (strcmp (sw->string, p) == 0)
|
||||
{
|
||||
if (sw->boolean)
|
||||
*sw->boolean = true;
|
||||
if (sw->argument)
|
||||
{
|
||||
if (argv >= end)
|
||||
throw ArgsException ("an argument is required for \"%s\"", sw->string);
|
||||
*sw->argument = *argv++;
|
||||
}
|
||||
hit = true;
|
||||
break;
|
||||
}
|
||||
if (!sw->string [0])
|
||||
parameter = sw;
|
||||
}
|
||||
if (!hit)
|
||||
{
|
||||
if (parameter)
|
||||
{
|
||||
if (parameter->boolean)
|
||||
*parameter->boolean = true;
|
||||
if (parameter->argument)
|
||||
*parameter->argument = p;
|
||||
}
|
||||
else
|
||||
throw ArgsException ("invalid option \"%s\"", p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Args::init(const Switches* switches)
|
||||
{
|
||||
for (const Switches *sw = switches; sw->string; ++sw)
|
||||
{
|
||||
if (sw->boolean)
|
||||
*sw->boolean = false;
|
||||
if (sw->argument)
|
||||
*sw->argument = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void Args::printHelp(const char* helpText, const Switches* switches)
|
||||
{
|
||||
int switchLength = 0;
|
||||
int argLength = 0;
|
||||
const Switches *sw;
|
||||
|
||||
for (sw = switches; sw->string; ++sw)
|
||||
{
|
||||
if (sw->description)
|
||||
{
|
||||
int l = (int) strlen (sw->string);
|
||||
if (l > switchLength)
|
||||
switchLength = l;
|
||||
if (sw->argName)
|
||||
{
|
||||
l = (int) strlen (sw->argName);
|
||||
if (l > argLength)
|
||||
argLength = l;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (helpText)
|
||||
printf (helpText);
|
||||
|
||||
printf ("Options are:\n");
|
||||
|
||||
for (sw = switches; sw->string; ++sw)
|
||||
{
|
||||
if (sw->description)
|
||||
{
|
||||
const char *arg = (sw->argName) ? sw->argName : "";
|
||||
printf (" %-*s %-*s %s\n", switchLength, sw->string, argLength, arg, sw->description);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Args::readPasswords(const char *msg, char *pw1, int length)
|
||||
{
|
||||
ConsoleNoEcho instance;
|
||||
|
||||
char pw2 [100];
|
||||
bool hit = false;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (msg)
|
||||
printf (msg);
|
||||
printf ("New password: ");
|
||||
if (!fgets (pw1, length, stdin))
|
||||
break;
|
||||
char *p = strchr (pw1, '\n');
|
||||
if (p)
|
||||
*p = 0;
|
||||
// blanks not detected here, need something like trim()
|
||||
if (!pw1 [0])
|
||||
{
|
||||
printf ("\nPassword may not be null. Please re-enter.\n");
|
||||
continue;
|
||||
}
|
||||
printf ("\nRepeat new password: ");
|
||||
if (!fgets (pw2, sizeof (pw2), stdin))
|
||||
break;
|
||||
if (p = strchr (pw2, '\n'))
|
||||
*p = 0;
|
||||
if (strcmp (pw1, pw2) == 0)
|
||||
{
|
||||
hit = true;
|
||||
break;
|
||||
}
|
||||
printf ("\nPasswords do not match. Please re-enter.\n");
|
||||
}
|
||||
|
||||
printf ("\n");
|
||||
|
||||
return hit;
|
||||
}
|
||||
|
||||
bool Args::readPassword(const char *msg, char *pw1, int length)
|
||||
{
|
||||
ConsoleNoEcho instance;
|
||||
|
||||
bool hit = false;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (msg)
|
||||
printf (msg);
|
||||
if (!fgets (pw1, length, stdin))
|
||||
break;
|
||||
char *p = strchr (pw1, '\n');
|
||||
if (p)
|
||||
*p = 0;
|
||||
// blanks not detected here, need something like trim()
|
||||
if (pw1 [0])
|
||||
{
|
||||
hit = true;
|
||||
break;
|
||||
}
|
||||
printf ("\nPassword may not be null. Please re-enter.\n");
|
||||
}
|
||||
|
||||
printf ("\n");
|
||||
|
||||
return hit;
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* 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/idpl.html.
|
||||
*
|
||||
* Software distributed under the License is distributed on
|
||||
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
|
||||
* express or implied. See the License for the specific
|
||||
* language governing rights and limitations under the License.
|
||||
*
|
||||
* The contents of this file or any work derived from this file
|
||||
* may not be distributed under any other license whatsoever
|
||||
* without the express prior written permission of the original
|
||||
* author.
|
||||
*
|
||||
*
|
||||
* The Original Code was created by James A. Starkey for IBPhoenix.
|
||||
*
|
||||
* Copyright (c) 1997 - 2000, 2001, 2003 James A. Starkey
|
||||
* Copyright (c) 1997 - 2000, 2001, 2003 Netfrastructure, Inc.
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
// Args.h: interface for the Args class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(AFX_ARGS_H__7C584339_5A11_4040_889B_417B607C858B__INCLUDED_)
|
||||
#define AFX_ARGS_H__7C584339_5A11_4040_889B_417B607C858B__INCLUDED_
|
||||
|
||||
#if defined _MSC_VER && _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
#include "../common/classes/alloc.h"
|
||||
|
||||
|
||||
//#define WORD_ARG(value,name) "", NULL, &value, name, NULL,
|
||||
//#define ARG_ARG(sw,value,help) sw, NULL, &value, NULL, help,
|
||||
//#define SW_ARG(sw,value,help) sw, &value,NULL, NULL, help,
|
||||
|
||||
class Args : public Firebird::GlobalStorage
|
||||
{
|
||||
public:
|
||||
struct Switches
|
||||
{
|
||||
const char* string;
|
||||
bool* boolean;
|
||||
const char** argument;
|
||||
const char* argName;
|
||||
const char* description;
|
||||
};
|
||||
|
||||
Args();
|
||||
virtual ~Args();
|
||||
|
||||
static bool readPassword (const char* msg, char* pw1, int length);
|
||||
static bool readPasswords(const char* msg, char* pw1, int length);
|
||||
static void printHelp (const char* helpText, const Switches* switches);
|
||||
static void init (const Switches* switches);
|
||||
static void parse (const Switches* switches, int argc, const char* const* argv);
|
||||
};
|
||||
|
||||
#endif // !defined(AFX_ARGS_H__7C584339_5A11_4040_889B_417B607C858B__INCLUDED_)
|
@ -1,58 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* 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/idpl.html.
|
||||
*
|
||||
* Software distributed under the License is distributed on
|
||||
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
|
||||
* express or implied. See the License for the specific
|
||||
* language governing rights and limitations under the License.
|
||||
*
|
||||
* The contents of this file or any work derived from this file
|
||||
* may not be distributed under any other license whatsoever
|
||||
* without the express prior written permission of the original
|
||||
* author.
|
||||
*
|
||||
*
|
||||
* The Original Code was created by James A. Starkey for IBPhoenix.
|
||||
*
|
||||
* Copyright (c) 1997 - 2000, 2001, 2003 James A. Starkey
|
||||
* Copyright (c) 1997 - 2000, 2001, 2003 Netfrastructure, Inc.
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
|
||||
// ArgsException.cpp: implementation of the ArgsException class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include "firebird.h"
|
||||
#include "ArgsException.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
ArgsException::ArgsException(const char* txt, ...) :
|
||||
text(getPool())
|
||||
{
|
||||
va_list args;
|
||||
va_start (args, txt);
|
||||
text.vprintf(txt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
ArgsException::~ArgsException()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
const char* ArgsException::getText() const
|
||||
{
|
||||
return text.c_str();
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* 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/idpl.html.
|
||||
*
|
||||
* Software distributed under the License is distributed on
|
||||
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
|
||||
* express or implied. See the License for the specific
|
||||
* language governing rights and limitations under the License.
|
||||
*
|
||||
* The contents of this file or any work derived from this file
|
||||
* may not be distributed under any other license whatsoever
|
||||
* without the express prior written permission of the original
|
||||
* author.
|
||||
*
|
||||
*
|
||||
* The Original Code was created by James A. Starkey for IBPhoenix.
|
||||
*
|
||||
* Copyright (c) 1997 - 2000, 2001, 2003 James A. Starkey
|
||||
* Copyright (c) 1997 - 2000, 2001, 2003 Netfrastructure, Inc.
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
// ArgsException.h: interface for the ArgsException class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(AFX_ARGSEXCEPTION_H__0546C1B7_E895_4AC1_A951_AF1812A505B0__INCLUDED_)
|
||||
#define AFX_ARGSEXCEPTION_H__0546C1B7_E895_4AC1_A951_AF1812A505B0__INCLUDED_
|
||||
|
||||
#if defined _MSC_VER && _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
#include "../common/classes/fb_string.h"
|
||||
|
||||
class ArgsException : public Firebird::GlobalStorage
|
||||
{
|
||||
public:
|
||||
ArgsException(const char* txt, ...);
|
||||
virtual ~ArgsException();
|
||||
const char* getText() const;
|
||||
|
||||
private:
|
||||
Firebird::string text;
|
||||
};
|
||||
|
||||
#endif // !defined(AFX_ARGSEXCEPTION_H__0546C1B7_E895_4AC1_A951_AF1812A505B0__INCLUDED_)
|
@ -1,72 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* 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/idpl.html.
|
||||
*
|
||||
* Software distributed under the License is distributed on
|
||||
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
|
||||
* express or implied. See the License for the specific
|
||||
* language governing rights and limitations under the License.
|
||||
*
|
||||
* The contents of this file or any work derived from this file
|
||||
* may not be distributed under any other license whatsoever
|
||||
* without the express prior written permission of the original
|
||||
* author.
|
||||
*
|
||||
*
|
||||
* The Original Code was created by James A. Starkey for IBPhoenix.
|
||||
*
|
||||
* Copyright (c) 1997 - 2000, 2001, 2003 James A. Starkey
|
||||
* Copyright (c) 1997 - 2000, 2001, 2003 Netfrastructure, Inc.
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
|
||||
#include "firebird.h"
|
||||
#include "ConfObj.h"
|
||||
#include "ConfObject.h"
|
||||
|
||||
|
||||
ConfObj::ConfObj()
|
||||
{
|
||||
object = NULL;
|
||||
}
|
||||
|
||||
ConfObj::ConfObj(ConfObject* confObject)
|
||||
{
|
||||
if (object = confObject)
|
||||
object->addRef();
|
||||
}
|
||||
|
||||
ConfObj::ConfObj(ConfObj& source)
|
||||
{
|
||||
if (object = source.object)
|
||||
object->addRef();
|
||||
}
|
||||
|
||||
ConfObj::~ConfObj()
|
||||
{
|
||||
if (object)
|
||||
object->release();
|
||||
}
|
||||
|
||||
bool ConfObj::hasObject() const
|
||||
{
|
||||
return object != NULL;
|
||||
}
|
||||
|
||||
ConfObject* ConfObj::operator = (ConfObject* source)
|
||||
{
|
||||
if (object)
|
||||
object->release();
|
||||
|
||||
object = source;
|
||||
|
||||
if (object)
|
||||
object->addRef();
|
||||
|
||||
return object;
|
||||
}
|
||||
|
@ -1,57 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* 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/idpl.html.
|
||||
*
|
||||
* Software distributed under the License is distributed on
|
||||
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
|
||||
* express or implied. See the License for the specific
|
||||
* language governing rights and limitations under the License.
|
||||
*
|
||||
* The contents of this file or any work derived from this file
|
||||
* may not be distributed under any other license whatsoever
|
||||
* without the express prior written permission of the original
|
||||
* author.
|
||||
*
|
||||
*
|
||||
* The Original Code was created by James A. Starkey for IBPhoenix.
|
||||
*
|
||||
* Copyright (c) 1997 - 2000, 2001, 2003 James A. Starkey
|
||||
* Copyright (c) 1997 - 2000, 2001, 2003 Netfrastructure, Inc.
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CONFOBJ_H_
|
||||
#define _CONFOBJ_H_
|
||||
|
||||
#include "../common/classes/alloc.h"
|
||||
|
||||
START_NAMESPACE
|
||||
|
||||
class ConfObject;
|
||||
|
||||
class ConfObj : public Firebird::GlobalStorage
|
||||
{
|
||||
public:
|
||||
ConfObj();
|
||||
explicit ConfObj(ConfObject* confObject);
|
||||
ConfObj(ConfObj& source);
|
||||
~ConfObj();
|
||||
|
||||
operator ConfObject*() { return object; }
|
||||
ConfObject* operator -> () { return object; }
|
||||
const ConfObject* operator -> () const { return object; }
|
||||
ConfObject* operator = (ConfObject* source);
|
||||
|
||||
bool hasObject() const;
|
||||
|
||||
private:
|
||||
ConfObject *object;
|
||||
};
|
||||
|
||||
END_NAMESPACE
|
||||
|
||||
#endif
|
@ -1,384 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* 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/idpl.html.
|
||||
*
|
||||
* Software distributed under the License is distributed on
|
||||
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
|
||||
* express or implied. See the License for the specific
|
||||
* language governing rights and limitations under the License.
|
||||
*
|
||||
* The contents of this file or any work derived from this file
|
||||
* may not be distributed under any other license whatsoever
|
||||
* without the express prior written permission of the original
|
||||
* author.
|
||||
*
|
||||
*
|
||||
* The Original Code was created by James A. Starkey for IBPhoenix.
|
||||
*
|
||||
* Copyright (c) 1997 - 2000, 2001, 2003 James A. Starkey
|
||||
* Copyright (c) 1997 - 2000, 2001, 2003 Netfrastructure, Inc.
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <memory.h>
|
||||
#include "firebird.h"
|
||||
#include "../jrd/common.h"
|
||||
#include "ConfObject.h"
|
||||
#include "Element.h"
|
||||
#include "AdminException.h"
|
||||
#include "ConfigFile.h"
|
||||
#include "PathName.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifndef strcasecmp
|
||||
#define strcasecmp stricmp
|
||||
//#define strncasecmp strnicmp
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define IS_DIGIT(c) (c >= '0' && c <= '9')
|
||||
|
||||
struct BooleanName
|
||||
{
|
||||
const char *string;
|
||||
bool value;
|
||||
};
|
||||
|
||||
static const BooleanName booleanNames [] =
|
||||
{
|
||||
{"yes", true},
|
||||
{"true", true},
|
||||
{"false", false},
|
||||
{"no", false},
|
||||
{NULL}
|
||||
};
|
||||
|
||||
ConfObject::ConfObject(ConfigFile *confFile) :
|
||||
source(getPool()), tempValue(getPool())
|
||||
{
|
||||
configFile = confFile;
|
||||
configFile->addRef();
|
||||
object = NULL;
|
||||
chain = NULL;
|
||||
}
|
||||
|
||||
ConfObject::~ConfObject()
|
||||
{
|
||||
configFile->release();
|
||||
|
||||
if (chain)
|
||||
chain->release();
|
||||
}
|
||||
|
||||
bool ConfObject::matches(Element* element, const char* type, const char* string)
|
||||
{
|
||||
if (element->name != type)
|
||||
return false;
|
||||
|
||||
const Element *attribute = element->findAttribute (0);
|
||||
|
||||
if (!attribute)
|
||||
return false;
|
||||
|
||||
//const char *name = configFile->translate (attribute->name, attribute->name);
|
||||
const Firebird::string name = expand (attribute->name.c_str());
|
||||
numberStrings = 0;
|
||||
end = buffer + sizeof (buffer);
|
||||
next = buffer;
|
||||
|
||||
if (!match (0, name.c_str(), string))
|
||||
return false;
|
||||
|
||||
object = element;
|
||||
source = string;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ConfObject::putString(int position, const char* string, int stringLength)
|
||||
{
|
||||
if (position >= MAX_STRINGS)
|
||||
throw AdminException("ConfObject: string segments overflow");
|
||||
|
||||
strings [position] = next;
|
||||
|
||||
if (next + stringLength + 1 >= end)
|
||||
throw AdminException ("ConfObject: string overflow");
|
||||
|
||||
memcpy (next, string, stringLength);
|
||||
next [stringLength] = 0;
|
||||
next += stringLength + 1;
|
||||
|
||||
if (position >= numberStrings)
|
||||
numberStrings = position + 1;
|
||||
}
|
||||
|
||||
bool ConfObject::match(int position, const char* pattern, const char* string)
|
||||
{
|
||||
char c;
|
||||
const char *s = string;
|
||||
|
||||
for (const char *p = pattern; (c = *p++); ++s)
|
||||
{
|
||||
if (c == '*')
|
||||
{
|
||||
if (!*p)
|
||||
{
|
||||
putString (position, string, (int) strlen (string));
|
||||
return true;
|
||||
}
|
||||
for (; *s; ++s)
|
||||
{
|
||||
if (match (position + 1, pattern + 1, s))
|
||||
{
|
||||
putString (position, string, (int) (s - string));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!*s)
|
||||
return false;
|
||||
|
||||
if (c != '%' && c != *s)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (UPPER (c) == UPPER (*s))
|
||||
continue;
|
||||
if ((c == '/' || c == '\\') && (*s == '/' || *s == '\\'))
|
||||
continue;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (c || *s)
|
||||
return false;
|
||||
|
||||
putString (position, string, (int) strlen (string));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const char* ConfObject::getValue (const char* option, const char *defaultValue)
|
||||
{
|
||||
const Element *element = findAttribute (option);
|
||||
|
||||
if (!element)
|
||||
return defaultValue;
|
||||
|
||||
tempValue = expand (getValue (element));
|
||||
|
||||
return tempValue.c_str();
|
||||
}
|
||||
|
||||
|
||||
int ConfObject::getValue(const char* option, int defaultValue)
|
||||
{
|
||||
Element *element = findAttribute (option);
|
||||
|
||||
if (!element)
|
||||
return defaultValue;
|
||||
|
||||
const Firebird::string value (expand (getValue (element)));
|
||||
int n = 0;
|
||||
|
||||
for (const char *p = value.c_str(); *p;)
|
||||
{
|
||||
const char c = *p++;
|
||||
if (c >= '0' && c <= '9')
|
||||
n = n * 10 + c - '0';
|
||||
else
|
||||
throw AdminException ("expected numeric value for option \"%s\", got \"%s\"", option, value.c_str());
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
bool ConfObject::getValue(const char* option, bool defaultValue)
|
||||
{
|
||||
const Element *element = findAttribute (option);
|
||||
|
||||
if (!element)
|
||||
return defaultValue;
|
||||
|
||||
const Firebird::string value = expand (getValue (element));
|
||||
const char* valueName = value.c_str();
|
||||
|
||||
for (const BooleanName *name = booleanNames; name->string; ++name)
|
||||
{
|
||||
if (strcasecmp (name->string, valueName) == 0)
|
||||
return name->value;
|
||||
}
|
||||
|
||||
throw AdminException ("expected boolean value for option \"%s\", got \"%s\"", option, value.c_str());
|
||||
}
|
||||
|
||||
Firebird::string ConfObject::expand(const char* rawValue)
|
||||
{
|
||||
if (!rawValue)
|
||||
return "";
|
||||
|
||||
char temp [1024];
|
||||
char *p = temp;
|
||||
const char* const temp_end = temp + sizeof(temp) - 1;
|
||||
bool changed = false;
|
||||
|
||||
// FIX THIS: detect overflow instead of silenty truncating content, as it's done in ConfigFile::expand
|
||||
for (const char *s = rawValue; *s;)
|
||||
{
|
||||
char c = *s++;
|
||||
if (c == '$')
|
||||
{
|
||||
if (*s == '(')
|
||||
{
|
||||
++s;
|
||||
char name [256];
|
||||
char* n = name;
|
||||
while (*s && (c = *s++) != ')' && n < name + sizeof(name) - 1)
|
||||
*n++ = c;
|
||||
*n = 0;
|
||||
const char *subst = configFile->translate (name, object);
|
||||
if (!subst)
|
||||
throw AdminException ("can't substitute for \"%s\"", name);
|
||||
changed = true;
|
||||
for (const char *t = subst; *t && p < temp_end;)
|
||||
*p++ = *t++;
|
||||
}
|
||||
else
|
||||
{
|
||||
int n = 0;
|
||||
while (IS_DIGIT (*s))
|
||||
n = n * 10 + *s++ - '0';
|
||||
if (n > numberStrings)
|
||||
throw AdminException ("substitution index exceeds available segments");
|
||||
for (const char *t = (n == 0) ? source.c_str() : strings [n - 1]; *t && p < temp_end;)
|
||||
*p++ = *t++;
|
||||
}
|
||||
}
|
||||
else if (p < temp_end)
|
||||
*p++ = c;
|
||||
}
|
||||
|
||||
*p = 0;
|
||||
|
||||
if (!changed)
|
||||
return temp;
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
Firebird::string ConfObject::getValue(const char* attributeName)
|
||||
{
|
||||
const Element *attribute = findAttribute (attributeName);
|
||||
|
||||
if (!attribute)
|
||||
return "";
|
||||
|
||||
return expand (getValue (attribute));
|
||||
}
|
||||
|
||||
const char* ConfObject::getValue(int instanceNumber, const char* attributeName)
|
||||
{
|
||||
const Element *attribute = findAttribute (attributeName);
|
||||
|
||||
if (!attribute)
|
||||
return "";
|
||||
|
||||
const Element *val = attribute->findAttribute (instanceNumber);
|
||||
|
||||
if (!val)
|
||||
return "";
|
||||
|
||||
tempValue = expand (val->name.c_str());
|
||||
|
||||
return tempValue.c_str();
|
||||
}
|
||||
|
||||
const char* ConfObject::getConcatenatedValues(const char* attributeName)
|
||||
{
|
||||
const Element *attribute = findAttribute (attributeName);
|
||||
|
||||
if (!attribute)
|
||||
return "";
|
||||
|
||||
Firebird::string value;
|
||||
|
||||
for (const Element *att = attribute->getAttributes(); att; att = att->sibling)
|
||||
{
|
||||
if (value.hasData())
|
||||
value += " ";
|
||||
value += att->name;
|
||||
}
|
||||
|
||||
tempValue = value;
|
||||
|
||||
return tempValue.c_str();
|
||||
}
|
||||
|
||||
Element* ConfObject::findAttribute(const char* attributeName)
|
||||
{
|
||||
if (object)
|
||||
{
|
||||
Element *element = object->findChild (attributeName);
|
||||
if (element)
|
||||
return element;
|
||||
}
|
||||
|
||||
if (chain)
|
||||
return chain->findAttribute (attributeName);
|
||||
|
||||
return configFile->findGlobalAttribute (attributeName);
|
||||
}
|
||||
|
||||
ConfObject* ConfObject::getChain()
|
||||
{
|
||||
return chain;
|
||||
}
|
||||
|
||||
void ConfObject::setChain(ConfObject* obj)
|
||||
{
|
||||
if (chain)
|
||||
chain->release();
|
||||
|
||||
if (chain = obj)
|
||||
chain->addRef();
|
||||
}
|
||||
|
||||
const char* ConfObject::getValue(const Element* attribute)
|
||||
{
|
||||
if (!attribute)
|
||||
return NULL;
|
||||
|
||||
const Element *value = attribute->findAttribute (0);
|
||||
|
||||
if (!value)
|
||||
return NULL;
|
||||
|
||||
return value->name.c_str();
|
||||
}
|
||||
|
||||
const char* ConfObject::getName()
|
||||
{
|
||||
if (!object)
|
||||
return NULL;
|
||||
|
||||
const Element *attribute = object->findAttribute (0);
|
||||
|
||||
if (!attribute)
|
||||
return NULL;
|
||||
|
||||
return attribute->name.c_str();
|
||||
}
|
||||
|
||||
ConfObject* ConfObject::findObject(const char* objectType, const char* objectName)
|
||||
{
|
||||
return configFile->findObject(objectType, objectName);
|
||||
}
|
||||
|
@ -1,82 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* 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/idpl.html.
|
||||
*
|
||||
* Software distributed under the License is distributed on
|
||||
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
|
||||
* express or implied. See the License for the specific
|
||||
* language governing rights and limitations under the License.
|
||||
*
|
||||
* The contents of this file or any work derived from this file
|
||||
* may not be distributed under any other license whatsoever
|
||||
* without the express prior written permission of the original
|
||||
* author.
|
||||
*
|
||||
*
|
||||
* The Original Code was created by James A. Starkey for IBPhoenix.
|
||||
*
|
||||
* Copyright (c) 1997 - 2000, 2001, 2003 James A. Starkey
|
||||
* Copyright (c) 1997 - 2000, 2001, 2003 Netfrastructure, Inc.
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CONFOBJECT_H_
|
||||
#define _CONFOBJECT_H_
|
||||
|
||||
#include "../common/classes/fb_string.h"
|
||||
#include "../vulcan/RefObject.h"
|
||||
|
||||
START_NAMESPACE
|
||||
|
||||
class Element;
|
||||
class ConfigFile;
|
||||
|
||||
|
||||
class ConfObject : public RefObject, public Firebird::GlobalStorage
|
||||
{
|
||||
public:
|
||||
explicit ConfObject(ConfigFile *confFile);
|
||||
virtual ~ConfObject();
|
||||
|
||||
virtual const char* getValue(const char* option, const char *defaultValue);
|
||||
virtual int getValue(const char* option, int defaultValue);
|
||||
virtual bool getValue(const char* option, bool defaultValue);
|
||||
virtual const char* getValue(int instanceNumber, const char* attributeName);
|
||||
virtual bool matches(Element* element, const char* type, const char* string);
|
||||
virtual void setChain(ConfObject* object);
|
||||
virtual const char* getName();
|
||||
virtual const char* getConcatenatedValues(const char* attributeName);
|
||||
virtual Firebird::string expand(const char* rawValue);
|
||||
virtual ConfObject* findObject(const char* objectType, const char* objectName);
|
||||
virtual ConfObject* getChain();
|
||||
|
||||
protected:
|
||||
virtual void putString(int position, const char* string, int stringLength);
|
||||
virtual bool match(int position, const char* p1, const char* p2);
|
||||
virtual Firebird::string getValue(const char* attributeName);
|
||||
virtual Element* findAttribute(const char* attributeName);
|
||||
virtual const char* getValue(const Element* attribute);
|
||||
|
||||
public:
|
||||
Element* object;
|
||||
|
||||
private:
|
||||
enum { MAX_STRINGS = 32 };
|
||||
ConfObject* chain;
|
||||
ConfigFile* configFile;
|
||||
Firebird::string source;
|
||||
Firebird::string tempValue;
|
||||
int numberStrings;
|
||||
const char* strings [MAX_STRINGS];
|
||||
char buffer [1024];
|
||||
char* next;
|
||||
const char* end;
|
||||
};
|
||||
|
||||
END_NAMESPACE
|
||||
|
||||
#endif
|
@ -1,373 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* 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/idpl.html.
|
||||
*
|
||||
* Software distributed under the License is distributed on
|
||||
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
|
||||
* express or implied. See the License for the specific
|
||||
* language governing rights and limitations under the License.
|
||||
*
|
||||
* The contents of this file or any work derived from this file
|
||||
* may not be distributed under any other license whatsoever
|
||||
* without the express prior written permission of the original
|
||||
* author.
|
||||
*
|
||||
*
|
||||
* The Original Code was created by James A. Starkey for IBPhoenix.
|
||||
*
|
||||
* Copyright (c) 1997 - 2000, 2001, 2003 James A. Starkey
|
||||
* Copyright (c) 1997 - 2000, 2001, 2003 Netfrastructure, Inc.
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
|
||||
#include "firebird.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <memory.h>
|
||||
#include "../common/classes/alloc.h"
|
||||
#include "ConfigFile.h"
|
||||
#include "ConfObject.h"
|
||||
#include "InputFile.h"
|
||||
#include "Element.h"
|
||||
#include "AdminException.h"
|
||||
#include "ScanDir.h"
|
||||
#include "../common/config/config.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#include <windows.h>
|
||||
#define IS_SEPARATOR(c) (c == '\\' || c == '/')
|
||||
|
||||
#ifndef strcasecmp
|
||||
#define strcasecmp stricmp
|
||||
//#define strncasecmp strnicmp
|
||||
#endif
|
||||
|
||||
//#define KEY "SOFTWARE\\Firebird Project\\Firebird Server\\Instances"
|
||||
//#define SUB_KEY NULL
|
||||
//#define PATH_KEY "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\Firebird"
|
||||
|
||||
#else
|
||||
#define IS_SEPARATOR(c) (c == '/')
|
||||
|
||||
#endif
|
||||
|
||||
ConfigFile::ConfigFile(const LEX_flags configFlags) :
|
||||
Lex ("/<>=", configFlags),
|
||||
rootDirectory(getPool()), installDirectory(getPool()), currentDirectory(getPool())
|
||||
{
|
||||
init (configFlags);
|
||||
}
|
||||
|
||||
|
||||
ConfigFile::ConfigFile(const char* configFile, const LEX_flags configFlags) :
|
||||
Lex ("/<>=", configFlags),
|
||||
rootDirectory(getPool()), installDirectory(getPool()), currentDirectory(getPool())
|
||||
{
|
||||
init (configFlags);
|
||||
InputFile *inputFile = new InputFile;
|
||||
Firebird::PathName expandedFile (expand (configFile));
|
||||
|
||||
if (!inputFile->openInputFile(expandedFile.c_str()))
|
||||
{
|
||||
delete inputFile;
|
||||
throw AdminException ("can't open configuration file \"%s\"", configFile);
|
||||
}
|
||||
|
||||
pushStream (inputFile);
|
||||
parse();
|
||||
}
|
||||
|
||||
void ConfigFile::init(const LEX_flags configFlags)
|
||||
{
|
||||
flags = configFlags;
|
||||
setLineComment ("#");
|
||||
setContinuationChar ('\\');
|
||||
objects = NULL;
|
||||
memset (hashTable, 0, sizeof (hashTable));
|
||||
}
|
||||
|
||||
ConfigFile::~ConfigFile()
|
||||
{
|
||||
delete objects;
|
||||
|
||||
for (int n = 0; n < HASH_SIZE; ++n)
|
||||
{
|
||||
for (Element *element; element = hashTable [n];)
|
||||
{
|
||||
hashTable [n] = element->sibling;
|
||||
delete element;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
InputFile* ConfigFile::openConfigFile()
|
||||
{
|
||||
fb_assert(false);
|
||||
// Vulcan specific code removed
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ConfigFile::addText(const char* text)
|
||||
{
|
||||
InputStream *stream = new InputStream(text);
|
||||
pushStream(stream);
|
||||
}
|
||||
|
||||
void ConfigFile::parse()
|
||||
{
|
||||
objects = new Element ("ConfObjects");
|
||||
getToken();
|
||||
|
||||
while (tokenType != END_OF_STREAM)
|
||||
{
|
||||
while (match ("include"))
|
||||
{
|
||||
Firebird::PathName fileName = expand (reparseFilename());
|
||||
if (fileName.find('*') != Firebird::PathName::npos)
|
||||
wildCardInclude(fileName.c_str());
|
||||
else
|
||||
pushStream (new InputFile (fileName.c_str()));
|
||||
getToken();
|
||||
}
|
||||
if (match ("<"))
|
||||
objects->addChild (parseObject());
|
||||
else
|
||||
{
|
||||
Element *element = parseAttribute();
|
||||
const int slot = element->name.hash (HASH_SIZE);
|
||||
element->sibling = hashTable [slot];
|
||||
hashTable [slot] = element;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Element* ConfigFile::parseObject()
|
||||
{
|
||||
const Firebird::string name = getName();
|
||||
Element *element = new Element (name);
|
||||
element->setSource (priorLineNumber, priorInputStream);
|
||||
|
||||
while (!match (">"))
|
||||
{
|
||||
element->addAttribute (new Element (reparseFilename().ToString()));
|
||||
getToken();
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (match ("<"))
|
||||
{
|
||||
if (match ("/"))
|
||||
{
|
||||
if (!match (element->name.c_str()))
|
||||
syntaxError ("closing element");
|
||||
if (!match (">"))
|
||||
syntaxError ("\">\"");
|
||||
element->numberLines = priorLineNumber - element->lineNumber + 1;
|
||||
return element;
|
||||
}
|
||||
element->addChild (parseObject());
|
||||
}
|
||||
else
|
||||
element->addChild (parseAttribute());
|
||||
}
|
||||
}
|
||||
|
||||
Element* ConfigFile::parseAttribute()
|
||||
{
|
||||
Element *element = new Element (getName());
|
||||
element->setSource (priorLineNumber, priorInputStream);
|
||||
match ("=");
|
||||
|
||||
while (!eol)
|
||||
{
|
||||
element->addAttribute (new Element (reparseFilename().ToString()));
|
||||
getToken();
|
||||
}
|
||||
|
||||
element->numberLines = priorLineNumber - element->lineNumber + 1;
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
ConfObject* ConfigFile::findObject(const char* objectType, const char* objectName)
|
||||
{
|
||||
if (!objects)
|
||||
return NULL;
|
||||
|
||||
ConfObject *object = new ConfObject (this);
|
||||
|
||||
for (Element *child = objects->children; child; child = child->sibling)
|
||||
{
|
||||
if (object->matches (child, objectType, objectName))
|
||||
return object;
|
||||
}
|
||||
|
||||
object->release();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char* ConfigFile::getRootDirectory()
|
||||
{
|
||||
return Config::getRootDirectory();
|
||||
}
|
||||
|
||||
ConfObject* ConfigFile::getObject(const char* /*objectType*/)
|
||||
{
|
||||
return new ConfObject (this);
|
||||
}
|
||||
|
||||
Element* ConfigFile::findGlobalAttribute(const char *attributeName)
|
||||
{
|
||||
for (Element *element = hashTable [Firebird::string::hash (attributeName, HASH_SIZE)]; element; element = element->sibling)
|
||||
{
|
||||
if (element->name == attributeName)
|
||||
return element;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char* ConfigFile::getInstallDirectory()
|
||||
{
|
||||
return Config::getInstallDirectory();
|
||||
}
|
||||
|
||||
Firebird::PathName ConfigFile::expand(const Firebird::PathName& rawString)
|
||||
{
|
||||
const char* const errstr = "filename expansion reached implementation limit at %d";
|
||||
char temp [1024];
|
||||
char* p = temp;
|
||||
const char* const temp_end = temp + sizeof(temp) - 1;
|
||||
bool change = false;
|
||||
|
||||
for (const char *s = rawString.c_str(); *s;)
|
||||
{
|
||||
char c = *s++;
|
||||
if (c == '$')
|
||||
{
|
||||
if (*s == '(')
|
||||
{
|
||||
++s;
|
||||
change = true;
|
||||
char name [256];
|
||||
const char* const name_end = name + sizeof(name) - 1;
|
||||
char* n = name;
|
||||
bool overflow = false;
|
||||
while (*s && (c = *s++) != ')' && !overflow)
|
||||
{
|
||||
if (n < name_end)
|
||||
*n++ = c;
|
||||
else
|
||||
overflow = true;
|
||||
}
|
||||
*n = 0;
|
||||
if (overflow)
|
||||
{
|
||||
n[-3] = n[-2] = n[-1] = '.';
|
||||
throw AdminException("name to be substituted \"%s\" is too long", name);
|
||||
}
|
||||
const char *subst = translate (name, NULL);
|
||||
if (!subst)
|
||||
throw AdminException ("can't substitute for \"%s\"", name);
|
||||
for (const char *t = subst; *t;)
|
||||
{
|
||||
if (p < temp_end)
|
||||
*p++ = *t++;
|
||||
else
|
||||
throw AdminException(errstr, sizeof(temp) - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (p < temp_end)
|
||||
*p++ = c;
|
||||
else
|
||||
throw AdminException(errstr, sizeof(temp) - 1);
|
||||
}
|
||||
|
||||
if (!change)
|
||||
return rawString;
|
||||
|
||||
*p = 0;
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
const char* ConfigFile::translate(const char* value, const Element* object)
|
||||
{
|
||||
if (strcasecmp (value, "root") == 0)
|
||||
return getRootDirectory();
|
||||
|
||||
if (strcasecmp (value, "install") == 0)
|
||||
return getInstallDirectory();
|
||||
|
||||
if (strcasecmp (value, "this") == 0)
|
||||
{
|
||||
const char *source = NULL;
|
||||
|
||||
if (object && object->inputStream)
|
||||
source = object->inputStream->getFileName();
|
||||
|
||||
if (!source && inputStream)
|
||||
source = inputStream->getFileName();
|
||||
|
||||
if (!source)
|
||||
throw AdminException("no context for $(this)");
|
||||
|
||||
const Firebird::PathName currentFile = expand (source);
|
||||
const char *fileName = currentFile.c_str();
|
||||
const char *p = NULL;
|
||||
|
||||
for (const char *q = fileName; *q; ++q)
|
||||
{
|
||||
if (IS_SEPARATOR(*q))
|
||||
p = q;
|
||||
}
|
||||
|
||||
if (p)
|
||||
currentDirectory = Firebird::PathName(fileName, p - fileName);
|
||||
else
|
||||
currentDirectory = ".";
|
||||
|
||||
return currentDirectory.c_str();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void ConfigFile::wildCardInclude(const char* fileName)
|
||||
{
|
||||
char directory [256];
|
||||
|
||||
if (strlen(fileName) >= sizeof(directory))
|
||||
throw AdminException("Too long filename in wildCardInclude()");
|
||||
|
||||
strcpy (directory, fileName);
|
||||
const char *wildcard = fileName;
|
||||
char *p = strrchr (directory, '/');
|
||||
|
||||
if (p)
|
||||
{
|
||||
*p = 0;
|
||||
wildcard = p + 1;
|
||||
}
|
||||
else
|
||||
directory [0] = 0;
|
||||
|
||||
// OK, expand wildcard
|
||||
|
||||
ScanDir scanDir (directory, wildcard);
|
||||
|
||||
while (scanDir.next())
|
||||
pushStream (new InputFile (scanDir.getFilePath()));
|
||||
}
|
@ -1,83 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* 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/idpl.html.
|
||||
*
|
||||
* Software distributed under the License is distributed on
|
||||
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
|
||||
* express or implied. See the License for the specific
|
||||
* language governing rights and limitations under the License.
|
||||
*
|
||||
* The contents of this file or any work derived from this file
|
||||
* may not be distributed under any other license whatsoever
|
||||
* without the express prior written permission of the original
|
||||
* author.
|
||||
*
|
||||
*
|
||||
* The Original Code was created by James A. Starkey for IBPhoenix.
|
||||
*
|
||||
* Copyright (c) 1997 - 2000, 2001, 2003 James A. Starkey
|
||||
* Copyright (c) 1997 - 2000, 2001, 2003 Netfrastructure, Inc.
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _ConfigFile_h_
|
||||
#define _ConfigFile_h_
|
||||
|
||||
#include "../config/Lex.h"
|
||||
#include "../vulcan/RefObject.h"
|
||||
#include "../common/classes/fb_string.h"
|
||||
|
||||
//static const int CONFIG_trace = 1;
|
||||
//static const int CONFIG_list = 2;
|
||||
//static const int CONFIG_verbose = 4;
|
||||
|
||||
START_NAMESPACE
|
||||
class InputFile;
|
||||
class Element;
|
||||
class ConfObject;
|
||||
|
||||
class ConfigFile : public Lex, public RefObject
|
||||
{
|
||||
public:
|
||||
explicit ConfigFile(const LEX_flags configFlags);
|
||||
ConfigFile(const char* configFile, const LEX_flags configFlags);
|
||||
|
||||
//protected:
|
||||
virtual ~ConfigFile();
|
||||
|
||||
public:
|
||||
InputFile* openConfigFile();
|
||||
void addText(const char* text);
|
||||
|
||||
void parse();
|
||||
Element* parseObject();
|
||||
Element* parseAttribute();
|
||||
ConfObject* findObject(const char* objectType, const char* objectName);
|
||||
const char* getRootDirectory();
|
||||
ConfObject* getObject(const char* objectType);
|
||||
Element* findGlobalAttribute(const char *attributeName);
|
||||
const char* getInstallDirectory();
|
||||
virtual Firebird::PathName expand(const Firebird::PathName& rawString);
|
||||
|
||||
const char* translate(const char* value, const Element* object);
|
||||
void wildCardInclude(const char* fileName);
|
||||
const Element* getObjects() const { return objects; }
|
||||
|
||||
private:
|
||||
enum { HASH_SIZE = 101 };
|
||||
void init(const LEX_flags configFlags);
|
||||
Element* objects;
|
||||
Firebird::PathName rootDirectory;
|
||||
Firebird::PathName installDirectory;
|
||||
Firebird::PathName currentDirectory;
|
||||
Element* hashTable [HASH_SIZE];
|
||||
|
||||
};
|
||||
END_NAMESPACE
|
||||
|
||||
#endif
|
||||
|
@ -1,96 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* 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/idpl.html.
|
||||
*
|
||||
* Software distributed under the License is distributed on
|
||||
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
|
||||
* express or implied. See the License for the specific
|
||||
* language governing rights and limitations under the License.
|
||||
*
|
||||
* The contents of this file or any work derived from this file
|
||||
* may not be distributed under any other license whatsoever
|
||||
* without the express prior written permission of the original
|
||||
* author.
|
||||
*
|
||||
*
|
||||
* The Original Code was created by James A. Starkey for IBPhoenix.
|
||||
*
|
||||
* Copyright (c) 1997 - 2000, 2001, 2003 James A. Starkey
|
||||
* Copyright (c) 1997 - 2000, 2001, 2003 Netfrastructure, Inc.
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
|
||||
#include "firebird.h"
|
||||
#include "../common/classes/alloc.h"
|
||||
#include "Configuration.h"
|
||||
#include "ConfigFile.h"
|
||||
|
||||
// This var could be a static member of the class.
|
||||
static ConfigFile* configFile;
|
||||
|
||||
// Non MT-safe code follows, maybe it was intended?
|
||||
|
||||
Configuration::Configuration()
|
||||
{
|
||||
fb_assert(!configFile); // only one instance of Configuration at a given time.
|
||||
configFile = NULL;
|
||||
}
|
||||
|
||||
Configuration::~Configuration()
|
||||
{
|
||||
if (configFile)
|
||||
{
|
||||
configFile->release();
|
||||
configFile = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
ConfObject* Configuration::findObject(const char* objectType, const char* objectName)
|
||||
{
|
||||
if (!configFile)
|
||||
loadConfigFile();
|
||||
|
||||
return configFile->findObject (objectType, objectName);
|
||||
}
|
||||
|
||||
const char* Configuration::getRootDirectory()
|
||||
{
|
||||
if (!configFile)
|
||||
loadConfigFile();
|
||||
|
||||
return configFile->getRootDirectory();
|
||||
}
|
||||
|
||||
void Configuration::loadConfigFile()
|
||||
{
|
||||
if (!configFile)
|
||||
configFile = new ConfigFile (ConfigFile::LEX_none);
|
||||
}
|
||||
|
||||
void Configuration::setConfigFilePath(const char* filename)
|
||||
{
|
||||
if (!configFile)
|
||||
configFile = new ConfigFile (filename, ConfigFile::LEX_none);
|
||||
}
|
||||
|
||||
ConfObject* Configuration::getObject(const char* objectType)
|
||||
{
|
||||
if (!configFile)
|
||||
loadConfigFile();
|
||||
|
||||
return configFile->getObject (objectType);
|
||||
}
|
||||
|
||||
ConfObject* Configuration::getObject(const char* objectType, const char* objectName)
|
||||
{
|
||||
ConfObject* object = findObject (objectType, objectName);
|
||||
|
||||
if (!object)
|
||||
object = getObject (objectType);
|
||||
|
||||
return object;
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* 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/idpl.html.
|
||||
*
|
||||
* Software distributed under the License is distributed on
|
||||
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
|
||||
* express or implied. See the License for the specific
|
||||
* language governing rights and limitations under the License.
|
||||
*
|
||||
* The contents of this file or any work derived from this file
|
||||
* may not be distributed under any other license whatsoever
|
||||
* without the express prior written permission of the original
|
||||
* author.
|
||||
*
|
||||
*
|
||||
* The Original Code was created by James A. Starkey for IBPhoenix.
|
||||
*
|
||||
* Copyright (c) 1997 - 2000, 2001, 2003 James A. Starkey
|
||||
* Copyright (c) 1997 - 2000, 2001, 2003 Netfrastructure, Inc.
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CONFIGURATION_H_
|
||||
#define _CONFIGURATION_H_
|
||||
|
||||
#include "../common/classes/alloc.h"
|
||||
|
||||
START_NAMESPACE
|
||||
|
||||
class ConfigFile;
|
||||
class ConfObject;
|
||||
|
||||
class Configuration : public Firebird::GlobalStorage
|
||||
{
|
||||
public:
|
||||
Configuration();
|
||||
virtual ~Configuration();
|
||||
|
||||
static ConfObject* findObject(const char* objectType, const char* objectName);
|
||||
static const char* getRootDirectory();
|
||||
static void loadConfigFile();
|
||||
static void setConfigFilePath(const char* filename);
|
||||
static ConfObject* getObject(const char* objectType);
|
||||
static ConfObject* getObject(const char* objectType, const char* objectName);
|
||||
};
|
||||
END_NAMESPACE
|
||||
|
||||
#endif
|
||||
|
@ -1,497 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* 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/idpl.html.
|
||||
*
|
||||
* Software distributed under the License is distributed on
|
||||
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
|
||||
* express or implied. See the License for the specific
|
||||
* language governing rights and limitations under the License.
|
||||
*
|
||||
* The contents of this file or any work derived from this file
|
||||
* may not be distributed under any other license whatsoever
|
||||
* without the express prior written permission of the original
|
||||
* author.
|
||||
*
|
||||
*
|
||||
* The Original Code was created by James A. Starkey for IBPhoenix.
|
||||
*
|
||||
* Copyright (c) 1997 - 2000, 2001, 2003 James A. Starkey
|
||||
* Copyright (c) 1997 - 2000, 2001, 2003 Netfrastructure, Inc.
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
|
||||
// Element.cpp: implementation of the Element class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
//#include <stdlib.h>
|
||||
//#include "Engine.h"
|
||||
#include "firebird.h"
|
||||
#include "../common/classes/alloc.h"
|
||||
#include "Element.h"
|
||||
#include "Stream.h"
|
||||
#include "InputStream.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
static const int quoted = 1;
|
||||
static const int illegal = 2;
|
||||
|
||||
static int charTable [256];
|
||||
|
||||
inline void setCharTable(UCHAR pos, int val)
|
||||
{
|
||||
charTable[pos] = val;
|
||||
}
|
||||
|
||||
static int init();
|
||||
static int foo = init();
|
||||
|
||||
int init()
|
||||
{
|
||||
setCharTable('<', quoted);
|
||||
setCharTable('>', quoted);
|
||||
setCharTable('&', quoted);
|
||||
|
||||
for (int n = 0; n < 10; ++n)
|
||||
charTable[n] = illegal;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
Element::Element(const Firebird::string& elementName) :
|
||||
name(getPool()), value(getPool()), innerText(getPool())
|
||||
{
|
||||
init (elementName);
|
||||
}
|
||||
|
||||
Element::Element(const Firebird::string& elementName, const Firebird::string& elementValue) :
|
||||
name(getPool()), value(getPool()), innerText(getPool())
|
||||
{
|
||||
init (elementName);
|
||||
value = elementValue;
|
||||
}
|
||||
|
||||
|
||||
void Element::init(const Firebird::string& elementName)
|
||||
{
|
||||
name = elementName;
|
||||
attributes = NULL;
|
||||
sibling = NULL;
|
||||
children = NULL;
|
||||
parent = NULL;
|
||||
lineNumber = 0;
|
||||
numberLines = 0;
|
||||
inputStream = NULL;
|
||||
}
|
||||
|
||||
Element::~Element()
|
||||
{
|
||||
Element *child;
|
||||
|
||||
while (child = children)
|
||||
{
|
||||
children = child->sibling;
|
||||
delete child;
|
||||
}
|
||||
|
||||
while (child = attributes)
|
||||
{
|
||||
attributes = child->sibling;
|
||||
delete child;
|
||||
}
|
||||
|
||||
if (inputStream)
|
||||
inputStream->release();
|
||||
}
|
||||
|
||||
|
||||
void Element::addChild(Element *child)
|
||||
{
|
||||
child->parent = this;
|
||||
child->sibling = NULL;
|
||||
Element** ptr = &children;
|
||||
while (*ptr)
|
||||
ptr = &(*ptr)->sibling;
|
||||
|
||||
*ptr = child;
|
||||
}
|
||||
|
||||
Element* Element::addChild(const Firebird::string& childName)
|
||||
{
|
||||
Element *element = new Element (childName);
|
||||
addChild (element);
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
void Element::addAttribute(Element *child)
|
||||
{
|
||||
child->parent = this;
|
||||
child->sibling = NULL;
|
||||
Element** ptr = &attributes;
|
||||
while (*ptr)
|
||||
ptr = &(*ptr)->sibling;
|
||||
|
||||
*ptr = child;
|
||||
}
|
||||
|
||||
void Element::addAttribute(const Firebird::string& attributeName)
|
||||
{
|
||||
addAttribute (new Element (attributeName));
|
||||
}
|
||||
|
||||
Element* Element::addAttribute(const Firebird::string& attributeName, const Firebird::string& attributeValue)
|
||||
{
|
||||
Element *attribute = new Element (attributeName, attributeValue);
|
||||
addAttribute (attribute);
|
||||
|
||||
return attribute;
|
||||
}
|
||||
|
||||
Element* Element::addAttribute(const Firebird::string& attributeName, int attributeValue)
|
||||
{
|
||||
Firebird::string buffer;
|
||||
buffer.printf ("%d", attributeValue);
|
||||
|
||||
return addAttribute (attributeName, buffer);
|
||||
}
|
||||
|
||||
void Element::print(int level) const
|
||||
{
|
||||
printf ("%*s%s", level * 3, "", name.c_str());
|
||||
const Element *element;
|
||||
|
||||
for (element = attributes; element; element = element->sibling)
|
||||
{
|
||||
printf (" %s", element->name.c_str());
|
||||
if (element->value != "")
|
||||
printf ("=%s", (const char*) element->value.c_str());
|
||||
}
|
||||
|
||||
printf ("\n");
|
||||
++level;
|
||||
for (element = children; element; element = element->sibling)
|
||||
element->print (level);
|
||||
}
|
||||
|
||||
Element* Element::findChild(const char *childName)
|
||||
{
|
||||
for (Element *child = children; child; child = child->sibling)
|
||||
{
|
||||
if (child->name == childName)
|
||||
return child;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const Element* Element::findChild(const char *childName) const
|
||||
{
|
||||
for (const Element *child = children; child; child = child->sibling)
|
||||
{
|
||||
if (child->name == childName)
|
||||
return child;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Element* Element::findAttribute(const char *childName)
|
||||
{
|
||||
for (Element *child = attributes; child; child = child->sibling)
|
||||
{
|
||||
if (child->name == childName)
|
||||
return child;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const Element* Element::findAttribute(const char *childName) const
|
||||
{
|
||||
for (const Element *child = attributes; child; child = child->sibling)
|
||||
{
|
||||
if (child->name == childName)
|
||||
return child;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Element* Element::findAttribute(int seq)
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
for (Element *attribute = attributes; attribute; attribute = attribute->sibling)
|
||||
{
|
||||
if (n++ == seq)
|
||||
return attribute;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const Element* Element::findAttribute(int seq) const
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
for (const Element *attribute = attributes; attribute; attribute = attribute->sibling)
|
||||
{
|
||||
if (n++ == seq)
|
||||
return attribute;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void Element::genXML(int level, Stream *stream) const
|
||||
{
|
||||
indent (level, stream);
|
||||
stream->putCharacter ('<');
|
||||
stream->putSegment (name.c_str());
|
||||
|
||||
for (const Element *attribute = attributes; attribute; attribute = attribute->sibling)
|
||||
{
|
||||
stream->putCharacter (' ');
|
||||
stream->putSegment (attribute->name.c_str());
|
||||
stream->putSegment ("=\"");
|
||||
for (const char *p = attribute->value.c_str(); *p; ++p)
|
||||
{
|
||||
switch (*p)
|
||||
{
|
||||
case '"': stream->putSegment ("""); break;
|
||||
case '\'': stream->putSegment ("'"); break;
|
||||
case '&': stream->putSegment ("&"); break;
|
||||
case '<': stream->putSegment ("<"); break;
|
||||
case '>': stream->putSegment (">"); break;
|
||||
default: stream->putCharacter (*p); break;
|
||||
}
|
||||
}
|
||||
//stream->putSegment (attribute->value);
|
||||
stream->putCharacter ('"');
|
||||
}
|
||||
|
||||
if (innerText.hasData())
|
||||
{
|
||||
stream->putCharacter('>');
|
||||
putQuotedText(innerText.c_str(), stream);
|
||||
}
|
||||
else if (!children)
|
||||
{
|
||||
if (name.at(0) == '?')
|
||||
stream->putSegment ("?>\n");
|
||||
else
|
||||
stream->putSegment ("/>\n");
|
||||
return;
|
||||
}
|
||||
else
|
||||
stream->putSegment (">\n");
|
||||
|
||||
++level;
|
||||
|
||||
for (const Element *child = children; child; child = child->sibling)
|
||||
child->genXML (level, stream);
|
||||
|
||||
if (innerText.isEmpty())
|
||||
indent (level - 1, stream);
|
||||
|
||||
stream->putSegment ("</");
|
||||
stream->putSegment (name.c_str());
|
||||
stream->putSegment (">\n");
|
||||
}
|
||||
|
||||
void Element::indent(int level, Stream *stream) const
|
||||
{
|
||||
int count = level * 3;
|
||||
|
||||
for (int n = 0; n < count; ++n)
|
||||
stream->putCharacter (' ');
|
||||
}
|
||||
|
||||
Element* Element::findChildIgnoreCase(const char *childName)
|
||||
{
|
||||
for (Element *child = children; child; child = child->sibling)
|
||||
{
|
||||
if (child->name.equalsNoCase (childName))
|
||||
return child;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char* Element::getAttributeName(int position) const
|
||||
{
|
||||
const Element *element = findAttribute (position);
|
||||
|
||||
if (!element)
|
||||
return NULL;
|
||||
|
||||
return element->name.c_str();
|
||||
}
|
||||
|
||||
const char* Element::getAttributeValue(const char *attributeName)
|
||||
{
|
||||
return getAttributeValue (attributeName, NULL);
|
||||
}
|
||||
|
||||
const char* Element::getAttributeValue(const char *attributeName, const char *defaultValue)
|
||||
{
|
||||
Element *attribute = findAttribute (attributeName);
|
||||
|
||||
if (!attribute)
|
||||
return defaultValue;
|
||||
|
||||
return attribute->value.c_str();
|
||||
}
|
||||
|
||||
void Element::setSource(int line, InputStream *stream)
|
||||
{
|
||||
lineNumber = line;
|
||||
inputStream = stream;
|
||||
inputStream->addRef();
|
||||
}
|
||||
|
||||
void Element::gen(int level, Stream *stream) const
|
||||
{
|
||||
for (int n = 0; n < level; ++n)
|
||||
stream->putSegment (" ");
|
||||
|
||||
if (children)
|
||||
stream->putCharacter ('<');
|
||||
|
||||
stream->putSegment (name.c_str());
|
||||
const Element *element;
|
||||
|
||||
for (element = attributes; element; element = element->sibling)
|
||||
{
|
||||
stream->putCharacter (' ');
|
||||
stream->putSegment (element->name.c_str());
|
||||
if (element->value != "")
|
||||
{
|
||||
stream->putCharacter ('=');
|
||||
stream->putSegment (element->value.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
if (!children)
|
||||
{
|
||||
stream->putCharacter ('\n');
|
||||
return;
|
||||
}
|
||||
|
||||
stream->putSegment (">\n");
|
||||
++level;
|
||||
|
||||
for (element = children; element; element = element->sibling)
|
||||
element->gen (level, stream);
|
||||
|
||||
stream->putSegment ("</");
|
||||
stream->putSegment (name.c_str());
|
||||
stream->putSegment (">\n");
|
||||
}
|
||||
|
||||
Element* Element::findChild(const char *childName, const char *attribute, const char *attributeValue)
|
||||
{
|
||||
for (Element *child = children; child; child = child->sibling)
|
||||
{
|
||||
if (child->name == childName)
|
||||
{
|
||||
const char *p = child->getAttributeValue (attribute, NULL);
|
||||
if (p && strcmp (p, attributeValue) == 0)
|
||||
return child;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int Element::analyseText(const char* text)
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
for (const char *p = text; *p; p++)
|
||||
{
|
||||
const int n = charTable[(UCHAR) *p];
|
||||
|
||||
if (n)
|
||||
{
|
||||
if (n & illegal)
|
||||
return -1;
|
||||
|
||||
++count;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
void Element::putQuotedText(const char* text, Stream* stream) const
|
||||
{
|
||||
const char *start = text;
|
||||
const char *p;
|
||||
|
||||
for (p = text; *p; p++)
|
||||
{
|
||||
if (charTable[(UCHAR) *p])
|
||||
{
|
||||
const char* escape = NULL;
|
||||
switch (*p)
|
||||
{
|
||||
case '>':
|
||||
escape = ">";
|
||||
break;
|
||||
case '<':
|
||||
escape = "<";
|
||||
break;
|
||||
case '&':
|
||||
escape = "&";
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
if (p > start)
|
||||
stream->putSegment(p - start, start, true);
|
||||
|
||||
stream->putSegment(escape);
|
||||
start = p + 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (p > start)
|
||||
stream->putSegment(p - start, start, true);
|
||||
}
|
||||
|
||||
int Element::analyzeData(const UCHAR* bytes)
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
for (const UCHAR *p = bytes; *p; p++)
|
||||
{
|
||||
const int n = charTable[*p];
|
||||
|
||||
if (n)
|
||||
{
|
||||
if (n & illegal)
|
||||
return -1;
|
||||
|
||||
++count;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
@ -1,99 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* 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/idpl.html.
|
||||
*
|
||||
* Software distributed under the License is distributed on
|
||||
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
|
||||
* express or implied. See the License for the specific
|
||||
* language governing rights and limitations under the License.
|
||||
*
|
||||
* The contents of this file or any work derived from this file
|
||||
* may not be distributed under any other license whatsoever
|
||||
* without the express prior written permission of the original
|
||||
* author.
|
||||
*
|
||||
*
|
||||
* The Original Code was created by James A. Starkey for IBPhoenix.
|
||||
*
|
||||
* Copyright (c) 1997 - 2000, 2001, 2003 James A. Starkey
|
||||
* Copyright (c) 1997 - 2000, 2001, 2003 Netfrastructure, Inc.
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
|
||||
// Element.h: interface for the Element class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(AFX_ELEMENT_H__36AF5EE7_6842_4000_B3C5_DB8DECEC79B7__INCLUDED_)
|
||||
#define AFX_ELEMENT_H__36AF5EE7_6842_4000_B3C5_DB8DECEC79B7__INCLUDED_
|
||||
|
||||
#if defined _MSC_VER && _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
#include "../common/classes/fb_string.h"
|
||||
|
||||
START_NAMESPACE
|
||||
|
||||
class Stream;
|
||||
class InputStream;
|
||||
|
||||
class Element : public Firebird::GlobalStorage
|
||||
{
|
||||
public:
|
||||
explicit Element(const Firebird::string& elementName);
|
||||
Element (const Firebird::string& elementName, const Firebird::string& elementValue);
|
||||
virtual ~Element();
|
||||
|
||||
void addChild (Element *child);
|
||||
Element* addChild (const Firebird::string& name);
|
||||
|
||||
void addAttribute (Element *child);
|
||||
void addAttribute (const Firebird::string& name);
|
||||
Element* addAttribute (const Firebird::string& name, const Firebird::string& value);
|
||||
Element* addAttribute (const Firebird::string& name, int value);
|
||||
|
||||
Element* findChild (const char *name, const char *attribute, const char *value);
|
||||
void gen (int level, Stream *stream) const;
|
||||
void setSource (int line, InputStream *stream);
|
||||
const char* getAttributeValue (const char *name, const char *defaultValue);
|
||||
const char* getAttributeValue (const char *name);
|
||||
const char* getAttributeName (int position) const;
|
||||
Element* findChildIgnoreCase (const char *name);
|
||||
void indent (int level, Stream *stream) const;
|
||||
void genXML (int level, Stream *stream) const;
|
||||
Element* findAttribute (const char *name);
|
||||
const Element* findAttribute (const char *name) const;
|
||||
Element* findAttribute (int seq);
|
||||
const Element* findAttribute (int seq) const;
|
||||
Element* findChild (const char *name);
|
||||
const Element* findChild (const char *name) const;
|
||||
void print (int level) const;
|
||||
const Element* getAttributes() const { return attributes; }
|
||||
|
||||
Firebird::string name;
|
||||
Firebird::string value;
|
||||
|
||||
Element *sibling;
|
||||
Element *children;
|
||||
|
||||
int lineNumber;
|
||||
int numberLines;
|
||||
InputStream *inputStream;
|
||||
static int analyseText(const char* text);
|
||||
void putQuotedText(const char* text, Stream* stream) const;
|
||||
static int analyzeData(const UCHAR* data);
|
||||
private:
|
||||
void init(const Firebird::string& elementName);
|
||||
Firebird::string innerText;
|
||||
Element *parent; // assigned but never used.
|
||||
Element *attributes;
|
||||
};
|
||||
|
||||
END_NAMESPACE
|
||||
|
||||
#endif // !defined(AFX_ELEMENT_H__36AF5EE7_6842_4000_B3C5_DB8DECEC79B7__INCLUDED_)
|
@ -1,45 +0,0 @@
|
||||
#include "firebird.h"
|
||||
#include "FileName.h"
|
||||
|
||||
#ifdef WIN_NT
|
||||
#define IS_SLASH(c) (c == '/' || c == '\\')
|
||||
#else
|
||||
#define IS_SLASH(c) (c == '/')
|
||||
#endif
|
||||
|
||||
FileName::FileName(const Firebird::PathName& name) :
|
||||
pathName(getPool()), directory(getPool()), root(getPool()), extension(getPool())
|
||||
{
|
||||
pathName = name;
|
||||
const char* const start = pathName.c_str();
|
||||
const char* slash = NULL;
|
||||
const char* dot = NULL;
|
||||
const char* rootName = start;
|
||||
absolute = IS_SLASH (start [0]);
|
||||
|
||||
for (const char* p = start; *p; ++p)
|
||||
{
|
||||
if (!dot && IS_SLASH (*p))
|
||||
slash = p;
|
||||
else if (*p == '.')
|
||||
dot = p;
|
||||
}
|
||||
|
||||
if (slash)
|
||||
{
|
||||
directory.assign (start, (int) (slash - rootName));
|
||||
rootName = slash + 1;
|
||||
}
|
||||
|
||||
if (dot)
|
||||
{
|
||||
extension = dot + 1;
|
||||
root.assign (rootName, (int) (dot - rootName));
|
||||
}
|
||||
else
|
||||
root = rootName;
|
||||
}
|
||||
|
||||
FileName::~FileName()
|
||||
{
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
#ifndef _FILENAME_H_
|
||||
#define _FILENAME_H_
|
||||
|
||||
#include "../common/classes/fb_string.h"
|
||||
|
||||
class FileName : public Firebird::GlobalStorage
|
||||
{
|
||||
public:
|
||||
explicit FileName(const Firebird::PathName& name);
|
||||
~FileName();
|
||||
|
||||
Firebird::PathName pathName;
|
||||
Firebird::PathName directory;
|
||||
Firebird::PathName root;
|
||||
Firebird::PathName extension;
|
||||
bool isAbsolute() const { return absolute; }
|
||||
private:
|
||||
bool absolute;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,235 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* 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/idpl.html.
|
||||
*
|
||||
* Software distributed under the License is distributed on
|
||||
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
|
||||
* express or implied. See the License for the specific
|
||||
* language governing rights and limitations under the License.
|
||||
*
|
||||
* The contents of this file or any work derived from this file
|
||||
* may not be distributed under any other license whatsoever
|
||||
* without the express prior written permission of the original
|
||||
* author.
|
||||
*
|
||||
*
|
||||
* The Original Code was created by James A. Starkey for IBPhoenix.
|
||||
*
|
||||
* Copyright (c) 1997 - 2000, 2001, 2003 James A. Starkey
|
||||
* Copyright (c) 1997 - 2000, 2001, 2003 Netfrastructure, Inc.
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
|
||||
// InputFile.cpp: implementation of the InputFile class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_IO_H
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "firebird.h"
|
||||
#include "../common/classes/alloc.h"
|
||||
#include "InputFile.h"
|
||||
#include "AdminException.h"
|
||||
|
||||
#define ISLOWER(c) (c >= 'a' && c <= 'z')
|
||||
//#define ISUPPER(c) (c >= 'A' && c <= 'Z')
|
||||
//#define ISDIGIT(c) (c >= '0' && c <= '9')
|
||||
|
||||
#ifndef UPPER
|
||||
#define UPPER(c) ((ISLOWER (c)) ? c - 'a' + 'A' : c)
|
||||
#endif
|
||||
|
||||
static const int BACKUP_FILES = 5;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
InputFile::InputFile(const char *name) : fileName(getPool())
|
||||
{
|
||||
changes = NULL;
|
||||
file = NULL;
|
||||
|
||||
if (!openInputFile (name))
|
||||
throw AdminException ("can't open file \"%s\"", name);
|
||||
}
|
||||
|
||||
InputFile::InputFile() : fileName(getPool())
|
||||
{
|
||||
changes = NULL;
|
||||
file = NULL;
|
||||
}
|
||||
|
||||
InputFile::~InputFile()
|
||||
{
|
||||
close();
|
||||
|
||||
for (FileChange *change; change = changes;)
|
||||
{
|
||||
changes = change->next;
|
||||
delete change;
|
||||
}
|
||||
}
|
||||
|
||||
void InputFile::close()
|
||||
{
|
||||
if (file)
|
||||
{
|
||||
fclose ((FILE*) file);
|
||||
file = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
const char* InputFile::getSegment()
|
||||
{
|
||||
if (!file)
|
||||
throw AdminException ("file has been closed");
|
||||
|
||||
if (!fgets (buffer, sizeof (buffer), (FILE*) file))
|
||||
return NULL;
|
||||
|
||||
//++lineNumber;
|
||||
segmentLength = (int) strlen (buffer);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
const char* InputFile::getFileName() const
|
||||
{
|
||||
return fileName.c_str();
|
||||
}
|
||||
|
||||
InputFile* InputFile::getInputFile()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
void InputFile::postChange(int line, int skip, const Firebird::string& insertion)
|
||||
{
|
||||
FileChange *change = new FileChange;
|
||||
change->lineNumber = line;
|
||||
change->linesSkipped = skip;
|
||||
change->insertion = insertion;
|
||||
|
||||
for (FileChange **p = &changes;; p = &(*p)->next)
|
||||
{
|
||||
FileChange *next = *p;
|
||||
if (!next || next->lineNumber > change->lineNumber)
|
||||
{
|
||||
change->next = *p;
|
||||
*p = change;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Commented out by Alex as unused and problematic.
|
||||
void InputFile::rewrite()
|
||||
{
|
||||
FILE *input = fopen (fileName.c_str(), "r");
|
||||
|
||||
if (!input)
|
||||
throw AdminException ("can't open \"%s\" for input", fileName.c_str());
|
||||
|
||||
Firebird::PathName tempName;
|
||||
tempName.printf("%.*s.tmp", MAXPATHLEN - 5, fileName.c_str());
|
||||
FILE *output = fopen (tempName.c_str(), "w");
|
||||
|
||||
if (!output)
|
||||
throw AdminException ("can't open \"%s\" for output", tempName.c_str());
|
||||
|
||||
char temp [1024];
|
||||
int line = 0;
|
||||
|
||||
for (FileChange *change = changes; change; change = change->next)
|
||||
{
|
||||
for (; line < change->lineNumber; ++line)
|
||||
{
|
||||
if (fgets (temp, sizeof (temp), input))
|
||||
fputs (temp, output);
|
||||
}
|
||||
//fputs ("#insertion starts here\n", output);
|
||||
fputs (change->insertion.c_str(), output);
|
||||
//fputs ("#insertion end here\n", output);
|
||||
for (int n = 0; n < change->linesSkipped; ++n)
|
||||
fgets (temp, sizeof (temp), input);
|
||||
line += change->linesSkipped;
|
||||
}
|
||||
|
||||
while (fgets (temp, sizeof (temp), input))
|
||||
fputs (temp, output);
|
||||
|
||||
fclose (input);
|
||||
fclose (output);
|
||||
Firebird::PathName filename1, filename2;
|
||||
|
||||
fb_assert(BACKUP_FILES < 10); // assumption to avoid too long filenames
|
||||
|
||||
for (int n = BACKUP_FILES; n >= 0; --n)
|
||||
{
|
||||
filename1.printf("%.*s.%d", MAXPATHLEN - 3, fileName.c_str(), n);
|
||||
if (n)
|
||||
filename2.printf("%.*s.%d", MAXPATHLEN - 3, fileName.c_str(), n - 1);
|
||||
else
|
||||
filename2 = fileName; // limited to correct length in openInputFile
|
||||
if (n == BACKUP_FILES)
|
||||
unlink (filename1.c_str());
|
||||
rename (filename2.c_str(), filename1.c_str());
|
||||
}
|
||||
|
||||
if (rename (tempName.c_str(), fileName.c_str()))
|
||||
perror ("rename");
|
||||
}
|
||||
*/
|
||||
|
||||
bool InputFile::pathEqual(const char *path1, const char *path2)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
for (; *path1 && *path2; ++path1, ++path2)
|
||||
{
|
||||
if (*path1 != *path2 &&
|
||||
UPPER (*path1) != UPPER (*path2) &&
|
||||
!((*path1 == '/' || *path1 == '\\') &&
|
||||
(*path2 == '/' || *path2 == '\\')))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#else
|
||||
for (; *path1 && *path2; ++path1, ++path2)
|
||||
{
|
||||
if (*path1 != *path2)
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return *path1 == 0 && *path2 == 0;
|
||||
}
|
||||
|
||||
bool InputFile::openInputFile(const char* name)
|
||||
{
|
||||
// It's good idea to keep file names limited to meet OS requirements
|
||||
if (!name || strlen(name) >= MAXPATHLEN)
|
||||
return false;
|
||||
|
||||
if (!(file = fopen (name, "r")))
|
||||
return false;
|
||||
|
||||
fileName = name;
|
||||
segment = buffer;
|
||||
changes = NULL;
|
||||
|
||||
return true;
|
||||
}
|
@ -1,78 +0,0 @@
|
||||
// InputFile.h: interface for the InputFile class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(AFX_INPUTFILE_H__8FAAB146_720E_43EE_A79B_262761DD0921__INCLUDED_)
|
||||
/*
|
||||
*
|
||||
* 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/idpl.html.
|
||||
*
|
||||
* Software distributed under the License is distributed on
|
||||
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
|
||||
* express or implied. See the License for the specific
|
||||
* language governing rights and limitations under the License.
|
||||
*
|
||||
* The contents of this file or any work derived from this file
|
||||
* may not be distributed under any other license whatsoever
|
||||
* without the express prior written permission of the original
|
||||
* author.
|
||||
*
|
||||
*
|
||||
* The Original Code was created by James A. Starkey for IBPhoenix.
|
||||
*
|
||||
* Copyright (c) 1997 - 2000, 2001, 2003 James A. Starkey
|
||||
* Copyright (c) 1997 - 2000, 2001, 2003 Netfrastructure, Inc.
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
|
||||
#define AFX_INPUTFILE_H__8FAAB146_720E_43EE_A79B_262761DD0921__INCLUDED_
|
||||
|
||||
#if defined _MSC_VER && _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
#include "InputStream.h"
|
||||
#include "../common/classes/fb_string.h"
|
||||
|
||||
START_NAMESPACE
|
||||
|
||||
class InputFile : public InputStream
|
||||
{
|
||||
public:
|
||||
explicit InputFile(const char* name);
|
||||
InputFile();
|
||||
virtual ~InputFile();
|
||||
|
||||
static bool pathEqual(const char *path1, const char *path2);
|
||||
// void rewrite();
|
||||
void postChange (int lineNumber, int skip, const Firebird::string& insertion);
|
||||
virtual InputFile* getInputFile();
|
||||
virtual const char* getFileName() const;
|
||||
virtual const char* getSegment();
|
||||
virtual void close();
|
||||
|
||||
bool openInputFile(const char* fileName); // caller is ConfigFile.cpp
|
||||
private:
|
||||
struct FileChange : public Firebird::GlobalStorage
|
||||
{
|
||||
FileChange *next;
|
||||
int lineNumber;
|
||||
int linesSkipped;
|
||||
Firebird::string insertion;
|
||||
public:
|
||||
FileChange() : insertion(getPool()) { }
|
||||
};
|
||||
|
||||
void *file;
|
||||
char buffer [1024];
|
||||
Firebird::PathName fileName;
|
||||
FileChange* changes;
|
||||
};
|
||||
|
||||
END_NAMESPACE
|
||||
|
||||
#endif // !defined(AFX_INPUTFILE_H__8FAAB146_720E_43EE_A79B_262761DD0921__INCLUDED_)
|
@ -1,113 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* 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/idpl.html.
|
||||
*
|
||||
* Software distributed under the License is distributed on
|
||||
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
|
||||
* express or implied. See the License for the specific
|
||||
* language governing rights and limitations under the License.
|
||||
*
|
||||
* The contents of this file or any work derived from this file
|
||||
* may not be distributed under any other license whatsoever
|
||||
* without the express prior written permission of the original
|
||||
* author.
|
||||
*
|
||||
*
|
||||
* The Original Code was created by James A. Starkey for IBPhoenix.
|
||||
*
|
||||
* Copyright (c) 1997 - 2000, 2001, 2003 James A. Starkey
|
||||
* Copyright (c) 1997 - 2000, 2001, 2003 Netfrastructure, Inc.
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
|
||||
// InputStream.cpp: implementation of the InputStream class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "firebird.h"
|
||||
#include "../jrd/common.h"
|
||||
#include "InputStream.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
InputStream::InputStream()
|
||||
{
|
||||
init();
|
||||
segmentLength = 0;
|
||||
}
|
||||
|
||||
InputStream::InputStream(const char* stuff)
|
||||
{
|
||||
init();
|
||||
segment = stuff;
|
||||
segmentLength = (int) strlen (segment);
|
||||
}
|
||||
|
||||
InputStream::~InputStream()
|
||||
{
|
||||
}
|
||||
|
||||
void InputStream::init()
|
||||
{
|
||||
prior = NULL;
|
||||
ptr = segment;
|
||||
useCount = 1;
|
||||
lineNumber = 0;
|
||||
segment = NULL;
|
||||
segmentOffset = 0;
|
||||
}
|
||||
|
||||
const char* InputStream::getSegment()
|
||||
{
|
||||
if (segmentOffset)
|
||||
return NULL;
|
||||
|
||||
segmentOffset = 1;
|
||||
|
||||
return segment;
|
||||
}
|
||||
|
||||
int InputStream::getOffset(const char* pointer)
|
||||
{
|
||||
return (int) (segmentOffset + pointer - segment);
|
||||
}
|
||||
|
||||
const char* InputStream::getEnd()
|
||||
{
|
||||
return segment + segmentLength;
|
||||
}
|
||||
|
||||
void InputStream::close()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
void InputStream::addRef()
|
||||
{
|
||||
++useCount;
|
||||
}
|
||||
|
||||
void InputStream::release()
|
||||
{
|
||||
if (--useCount == 0)
|
||||
delete this;
|
||||
}
|
||||
|
||||
const char* InputStream::getFileName() const
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
InputFile* InputStream::getInputFile()
|
||||
{
|
||||
return NULL;
|
||||
}
|
@ -1,75 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* 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/idpl.html.
|
||||
*
|
||||
* Software distributed under the License is distributed on
|
||||
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
|
||||
* express or implied. See the License for the specific
|
||||
* language governing rights and limitations under the License.
|
||||
*
|
||||
* The contents of this file or any work derived from this file
|
||||
* may not be distributed under any other license whatsoever
|
||||
* without the express prior written permission of the original
|
||||
* author.
|
||||
*
|
||||
*
|
||||
* The Original Code was created by James A. Starkey for IBPhoenix.
|
||||
*
|
||||
* Copyright (c) 1997 - 2000, 2001, 2003 James A. Starkey
|
||||
* Copyright (c) 1997 - 2000, 2001, 2003 Netfrastructure, Inc.
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
|
||||
// InputStream.h: interface for the InputStream class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(AFX_INPUTSTREAM_H__63114A0E_18FF_41F4_85A4_CCB8711487C7__INCLUDED_)
|
||||
#define AFX_INPUTSTREAM_H__63114A0E_18FF_41F4_85A4_CCB8711487C7__INCLUDED_
|
||||
|
||||
#if defined _MSC_VER && _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
#include "../common/classes/alloc.h"
|
||||
|
||||
START_NAMESPACE
|
||||
|
||||
class InputFile;
|
||||
|
||||
class InputStream : public Firebird::GlobalStorage
|
||||
{
|
||||
public:
|
||||
explicit InputStream (const char* stuff);
|
||||
InputStream();
|
||||
virtual ~InputStream();
|
||||
|
||||
virtual InputFile* getInputFile();
|
||||
virtual const char* getFileName() const;
|
||||
void init();
|
||||
void release();
|
||||
virtual void addRef();
|
||||
|
||||
virtual void close();
|
||||
virtual const char* getEnd();
|
||||
virtual int getOffset (const char* ptr);
|
||||
virtual const char* getSegment();
|
||||
|
||||
int lineNumber;
|
||||
const char* segment;
|
||||
const char* ptr;
|
||||
InputStream* prior;
|
||||
protected:
|
||||
int segmentLength; // used by InputFile
|
||||
private:
|
||||
int segmentOffset;
|
||||
int useCount;
|
||||
};
|
||||
|
||||
END_NAMESPACE
|
||||
|
||||
#endif // !defined(AFX_INPUTSTREAM_H__63114A0E_18FF_41F4_85A4_CCB8711487C7__INCLUDED_)
|
@ -1,400 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* 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/idpl.html.
|
||||
*
|
||||
* Software distributed under the License is distributed on
|
||||
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
|
||||
* express or implied. See the License for the specific
|
||||
* language governing rights and limitations under the License.
|
||||
*
|
||||
* The contents of this file or any work derived from this file
|
||||
* may not be distributed under any other license whatsoever
|
||||
* without the express prior written permission of the original
|
||||
* author.
|
||||
*
|
||||
*
|
||||
* The Original Code was created by James A. Starkey for IBPhoenix.
|
||||
*
|
||||
* Copyright (c) 1997 - 2000, 2001, 2003 James A. Starkey
|
||||
* Copyright (c) 1997 - 2000, 2001, 2003 Netfrastructure, Inc.
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
|
||||
// Lex.cpp: implementation of the Lex class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <memory.h>
|
||||
#include "firebird.h"
|
||||
#include "Lex.h"
|
||||
#include "AdminException.h"
|
||||
#include "InputStream.h"
|
||||
|
||||
#define WHITE_SPACE " \t\n\r"
|
||||
//#define PUNCTUATION_CHARS "<>="
|
||||
//#define MULTI_CHARS "" //"+=*/%!~<>~^|&="
|
||||
//#define MAX_TOKEN 1024
|
||||
#define UPCASE(c) ((c >= 'a' && c <= 'z') ? c - 'a' + 'A' : c)
|
||||
|
||||
const int TYPE_WHITE = 1;
|
||||
const int TYPE_PUNCT = 2;
|
||||
//const int TYPE_MULTI_CHAR = 4;
|
||||
const int TYPE_DIGIT = 8;
|
||||
//#define TERM (TYPE_WHITE | TYPE_PUNCT)
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
Lex::Lex(const char* punctuation, const LEX_flags debugFlags)
|
||||
{
|
||||
lineComment = NULL;
|
||||
commentStart = NULL;
|
||||
memset (charTableArray, 0, sizeof (charTableArray));
|
||||
setCharacters (TYPE_PUNCT, punctuation);
|
||||
setCharacters (TYPE_WHITE, WHITE_SPACE);
|
||||
setCharacters (TYPE_DIGIT, "0123456789");
|
||||
ptr = end = NULL;
|
||||
inputStream = NULL;
|
||||
tokenType = TT_NONE;
|
||||
lineNumber = 0;
|
||||
continuationChar = 0;
|
||||
captureStart = captureEnd = 0;
|
||||
flags = debugFlags;
|
||||
}
|
||||
|
||||
Lex::~Lex()
|
||||
{
|
||||
if (inputStream)
|
||||
inputStream->release();
|
||||
}
|
||||
|
||||
void Lex::skipWhite()
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
while (ptr >= end)
|
||||
{
|
||||
if (!getSegment())
|
||||
return;
|
||||
}
|
||||
while (ptr < end)
|
||||
{
|
||||
if (lineComment && lineComment [0] == *ptr && match (lineComment, ptr))
|
||||
{
|
||||
while (ptr < end && *ptr++ != '\n')
|
||||
;
|
||||
++inputStream->lineNumber;
|
||||
}
|
||||
else if (commentStart && commentStart [0] == *ptr && match (commentStart, ptr))
|
||||
{
|
||||
ptr += strlen (commentStart);
|
||||
while (ptr < end)
|
||||
{
|
||||
if (commentEnd [0] == *ptr && match (commentEnd, ptr))
|
||||
{
|
||||
ptr += strlen (commentEnd);
|
||||
break;
|
||||
}
|
||||
|
||||
if (*ptr++ == '\n')
|
||||
++inputStream->lineNumber;
|
||||
}
|
||||
}
|
||||
else if (*ptr == continuationChar && ptr [1] == '\n')
|
||||
{
|
||||
ptr += 2;
|
||||
++inputStream->lineNumber;
|
||||
}
|
||||
else if (charTable(*ptr) & TYPE_WHITE)
|
||||
{
|
||||
if (*ptr++ == '\n')
|
||||
{
|
||||
eol = true;
|
||||
++inputStream->lineNumber;
|
||||
}
|
||||
}
|
||||
else
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Just another custom memcmp-like routine.
|
||||
bool Lex::match(const char *pattern, const char *string)
|
||||
{
|
||||
while (*pattern && *string)
|
||||
{
|
||||
if (*pattern++ != *string++)
|
||||
return false;
|
||||
}
|
||||
|
||||
return *pattern == 0;
|
||||
}
|
||||
|
||||
void Lex::getToken()
|
||||
{
|
||||
priorInputStream = tokenInputStream;
|
||||
priorLineNumber = tokenLineNumber;
|
||||
|
||||
if (tokenType == END_OF_STREAM)
|
||||
throw AdminException ("expected token, got end-of-file");
|
||||
|
||||
eol = false;
|
||||
skipWhite();
|
||||
|
||||
if (tokenInputStream = inputStream)
|
||||
tokenLineNumber = inputStream->lineNumber;
|
||||
|
||||
if (ptr >= end)
|
||||
{
|
||||
tokenType = END_OF_STREAM;
|
||||
strcpy (token, "-end-of-file-");
|
||||
return;
|
||||
}
|
||||
|
||||
tokenOffset = inputStream->getOffset (ptr);
|
||||
char *p = token;
|
||||
const char* const endToken = token + sizeof(token) - 1; // take into account the '\0'
|
||||
const char c = *p++ = *ptr++;
|
||||
|
||||
if (charTable(c) & TYPE_PUNCT)
|
||||
tokenType = TT_PUNCT;
|
||||
else if (c == '\'' || c == '"')
|
||||
{
|
||||
p = token;
|
||||
for (;;)
|
||||
{
|
||||
if (ptr >= end)
|
||||
{
|
||||
if (!getSegment())
|
||||
throw AdminException ("end of file in quoted string");
|
||||
}
|
||||
else if (*ptr == c)
|
||||
break;
|
||||
else
|
||||
{
|
||||
if (p >= endToken)
|
||||
throw AdminException ("token overflow in quoted string");
|
||||
*p++ = *ptr++;
|
||||
}
|
||||
}
|
||||
++ptr;
|
||||
tokenType = (c == '"') ? QUOTED_STRING : SINGLE_QUOTED_STRING;
|
||||
}
|
||||
else if (charTable(c) & TYPE_DIGIT)
|
||||
{
|
||||
tokenType = TT_NUMBER;
|
||||
while (ptr < end && (charTable(*ptr) & TYPE_DIGIT))
|
||||
{
|
||||
if (p >= endToken)
|
||||
throw AdminException ("token overflow in number");
|
||||
*p++ = *ptr++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tokenType = TT_NAME;
|
||||
if (flags & LEX_upcase)
|
||||
{
|
||||
p [-1] = UPCASE(c);
|
||||
while (ptr < end && !(charTable(*ptr) & (TYPE_WHITE | TYPE_PUNCT)))
|
||||
{
|
||||
if (p >= endToken)
|
||||
throw AdminException ("token overflow in name (uppercase)");
|
||||
const char c2 = *ptr++;
|
||||
*p++ = UPCASE(c2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (ptr < end && !(charTable(*ptr) & (TYPE_WHITE | TYPE_PUNCT)))
|
||||
{
|
||||
if (p >= endToken)
|
||||
throw AdminException ("token overflow in name");
|
||||
*p++ = *ptr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*p = 0;
|
||||
}
|
||||
|
||||
void Lex::setCharacters(int type, const char *characters)
|
||||
{
|
||||
for (const char *p = characters; *p; ++p)
|
||||
charTable(*p) |= type;
|
||||
}
|
||||
|
||||
/***
|
||||
void Lex::openFile(const char *fileName)
|
||||
{
|
||||
inputStream = new InputFile (fileName, inputStream);
|
||||
}
|
||||
***/
|
||||
|
||||
void Lex::setLineComment(const char *string)
|
||||
{
|
||||
lineComment = string;
|
||||
}
|
||||
|
||||
void Lex::setCommentString(const char *start, const char *cend)
|
||||
{
|
||||
commentStart = start;
|
||||
commentEnd = cend;
|
||||
}
|
||||
|
||||
|
||||
bool Lex::isKeyword(const char *word) const
|
||||
{
|
||||
return strcmp (token, word) == 0;
|
||||
}
|
||||
|
||||
bool Lex::match(const char *word)
|
||||
{
|
||||
if (!isKeyword (word))
|
||||
return false;
|
||||
|
||||
if (*word == captureStart)
|
||||
captureStuff();
|
||||
|
||||
getToken();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Firebird::PathName Lex::reparseFilename()
|
||||
{
|
||||
char *p = token;
|
||||
|
||||
while (*p)
|
||||
++p;
|
||||
|
||||
while (ptr < end && *ptr != '>' && !(charTable(*ptr) & TYPE_WHITE))
|
||||
*p++ = *ptr++;
|
||||
|
||||
*p = 0;
|
||||
const Firebird::PathName string = token;
|
||||
//getToken();
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
Firebird::string Lex::getName()
|
||||
{
|
||||
if (tokenType != TT_NAME)
|
||||
syntaxError ("name");
|
||||
|
||||
const Firebird::string name = token;
|
||||
getToken();
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
void Lex::syntaxError(const char *expected)
|
||||
{
|
||||
AdminException exception ("expected %s, got \"%s\"", expected, token);
|
||||
|
||||
if (tokenInputStream)
|
||||
exception.setLocation (tokenInputStream->getFileName(), tokenLineNumber);
|
||||
|
||||
throw exception;
|
||||
}
|
||||
|
||||
/***
|
||||
InputFile* Lex::pushFile(const char *fileName)
|
||||
{
|
||||
if (inputStream)
|
||||
inputStream->ptr = ptr;
|
||||
|
||||
InputFile *inputFile = new InputFile (fileName, inputStream);
|
||||
inputStream = inputFile;
|
||||
ptr = end = NULL;
|
||||
tokenType = TT_NONE;
|
||||
|
||||
return inputFile;
|
||||
}
|
||||
***/
|
||||
|
||||
void Lex::setContinuationChar(char c)
|
||||
{
|
||||
continuationChar = c;
|
||||
}
|
||||
|
||||
void Lex::pushStream(InputStream *stream)
|
||||
{
|
||||
stream->addRef();
|
||||
|
||||
if (flags & LEX_trace)
|
||||
{
|
||||
const char *fileName = stream->getFileName();
|
||||
if (fileName)
|
||||
printf ("Opening %s\n", fileName);
|
||||
}
|
||||
|
||||
if (inputStream)
|
||||
inputStream->ptr = ptr;
|
||||
|
||||
stream->prior = inputStream;
|
||||
inputStream = stream;
|
||||
ptr = end = NULL;
|
||||
tokenType = TT_NONE;
|
||||
}
|
||||
|
||||
bool Lex::getSegment()
|
||||
{
|
||||
if (!inputStream)
|
||||
{
|
||||
tokenType = END_OF_STREAM;
|
||||
eol = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(ptr = inputStream->getSegment()))
|
||||
{
|
||||
end = ptr;
|
||||
InputStream *prior = inputStream->prior;
|
||||
inputStream->close();
|
||||
inputStream->release();
|
||||
if (!(inputStream = prior))
|
||||
return false;
|
||||
ptr = inputStream->ptr;
|
||||
}
|
||||
|
||||
end = ptr ? inputStream->getEnd() : NULL;
|
||||
|
||||
if (end && (flags & LEX_list))
|
||||
printf (" %s", ptr);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Lex::captureStuff()
|
||||
{
|
||||
stuff.clear();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (ptr >= end)
|
||||
{
|
||||
if (!getSegment())
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
if (*ptr == captureEnd)
|
||||
return;
|
||||
stuff.putCharacter (*ptr++);
|
||||
}
|
||||
}
|
||||
|
||||
int& Lex::charTable(int ch)
|
||||
{
|
||||
return charTableArray [static_cast<UCHAR>(ch)];
|
||||
}
|
114
src/config/Lex.h
114
src/config/Lex.h
@ -1,114 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* 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/idpl.html.
|
||||
*
|
||||
* Software distributed under the License is distributed on
|
||||
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
|
||||
* express or implied. See the License for the specific
|
||||
* language governing rights and limitations under the License.
|
||||
*
|
||||
* The contents of this file or any work derived from this file
|
||||
* may not be distributed under any other license whatsoever
|
||||
* without the express prior written permission of the original
|
||||
* author.
|
||||
*
|
||||
*
|
||||
* The Original Code was created by James A. Starkey for IBPhoenix.
|
||||
*
|
||||
* Copyright (c) 1997 - 2000, 2001, 2003 James A. Starkey
|
||||
* Copyright (c) 1997 - 2000, 2001, 2003 Netfrastructure, Inc.
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
|
||||
// Lex.h: interface for the Lex class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(AFX_LEX_H__89737590_2C93_4F77_99AD_4C3881906C96__INCLUDED_)
|
||||
#define AFX_LEX_H__89737590_2C93_4F77_99AD_4C3881906C96__INCLUDED_
|
||||
|
||||
#if defined _MSC_VER && _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
#include "Stream.h"
|
||||
#include "../common/classes/alloc.h"
|
||||
|
||||
START_NAMESPACE
|
||||
|
||||
class InputStream;
|
||||
class InputFile;
|
||||
class Stream;
|
||||
|
||||
class Lex : public Firebird::GlobalStorage
|
||||
{
|
||||
public:
|
||||
enum LEX_flags { LEX_none = 0, LEX_trace = 1, LEX_list = 2, /* LEX_verbose = 4, */ LEX_upcase = 8 };
|
||||
|
||||
enum TokenType
|
||||
{
|
||||
END_OF_STREAM,
|
||||
TT_PUNCT,
|
||||
TT_NAME,
|
||||
//QUOTED_NAME,
|
||||
TT_NUMBER,
|
||||
//TT_END,
|
||||
QUOTED_STRING,
|
||||
SINGLE_QUOTED_STRING,
|
||||
//DECIMAL_NUMBER,
|
||||
//IP_ADDRESS,
|
||||
TT_NONE
|
||||
};
|
||||
|
||||
Lex(const char* punctuation, const LEX_flags debugFlags);
|
||||
virtual ~Lex();
|
||||
|
||||
void captureStuff();
|
||||
int& charTable(int ch);
|
||||
bool getSegment();
|
||||
void pushStream (InputStream *stream);
|
||||
void setContinuationChar (char c);
|
||||
virtual void syntaxError (const char* expected);
|
||||
Firebird::string getName();
|
||||
Firebird::PathName reparseFilename();
|
||||
bool match (const char *word);
|
||||
bool isKeyword (const char *word) const;
|
||||
void setCommentString (const char *start, const char *end);
|
||||
void setLineComment (const char *string);
|
||||
void setCharacters (int type, const char *characters);
|
||||
void getToken();
|
||||
static bool match (const char *pattern, const char *string);
|
||||
void skipWhite();
|
||||
protected:
|
||||
LEX_flags flags;
|
||||
TokenType tokenType;
|
||||
int priorLineNumber;
|
||||
bool eol;
|
||||
InputStream* inputStream;
|
||||
InputStream* priorInputStream;
|
||||
private:
|
||||
enum { MAXTOKEN = 4096 };
|
||||
InputStream* tokenInputStream;
|
||||
Stream stuff;
|
||||
int tokenOffset;
|
||||
char captureStart;
|
||||
char captureEnd;
|
||||
char token [MAXTOKEN];
|
||||
int lineNumber;
|
||||
int tokenLineNumber;
|
||||
const char* ptr;
|
||||
const char* end;
|
||||
const char* lineComment;
|
||||
const char* commentStart;
|
||||
const char* commentEnd;
|
||||
char continuationChar;
|
||||
int charTableArray [256]; // Don't use directly. Use through charTable.
|
||||
};
|
||||
|
||||
END_NAMESPACE
|
||||
|
||||
#endif // !defined(AFX_LEX_H__89737590_2C93_4F77_99AD_4C3881906C96__INCLUDED_)
|
@ -1,77 +0,0 @@
|
||||
|
||||
#ifndef STR_PARAMETER
|
||||
#define STR_PARAMETER(name, value) static const char* name = #name; static const char* name##Value = value;
|
||||
#define INT_PARAMETER(name, value) static const char* name = #name; static int name##Value = value;
|
||||
#define BOOL_PARAMETER(name, value) static const char* name = #name; static bool name##Value = value;
|
||||
#endif
|
||||
|
||||
STR_PARAMETER (RootDirectory, 0)
|
||||
INT_PARAMETER (SortMemBlockSize, 1048576) // bytes
|
||||
#ifdef SUPERSERVER
|
||||
INT_PARAMETER (SortMemUpperLimit, 67108864) // bytes
|
||||
#elif defined(WIN_NT) // win32 CS
|
||||
INT_PARAMETER (SortMemUpperLimit, 8388608) // bytes
|
||||
#else // non-win32 CS
|
||||
INT_PARAMETER (SortMemUpperLimit, 0) // bytes
|
||||
#endif
|
||||
BOOL_PARAMETER (RemoteFileOpenAbility, false)
|
||||
INT_PARAMETER (GuardianOption, 1)
|
||||
INT_PARAMETER (CpuAffinityMask, 1)
|
||||
BOOL_PARAMETER (OldParameterOrdering, false)
|
||||
INT_PARAMETER (TcpRemoteBufferSize, 8192) // bytes
|
||||
BOOL_PARAMETER (TcpNoNagle, false)
|
||||
INT_PARAMETER (IpcMapSize, 4096) // bytes
|
||||
#ifdef SUPERSERVER
|
||||
INT_PARAMETER (DefaultDbCachePages, 2048) // pages
|
||||
#else
|
||||
INT_PARAMETER (DefaultDbCachePages, 75) // pages
|
||||
#endif
|
||||
INT_PARAMETER (ConnectionTimeout, 180) // seconds
|
||||
INT_PARAMETER (DummyPacketInterval, 0) // seconds
|
||||
#if defined(WIN_NT) && !defined(SUPERSERVER)
|
||||
INT_PARAMETER (LockMemSize, 1048576) // bytes
|
||||
#else
|
||||
INT_PARAMETER (LockMemSize, 262144) // bytes
|
||||
#endif
|
||||
INT_PARAMETER (LockSemCount, 32) // semaphores
|
||||
INT_PARAMETER (LockSignal, 16) // signal #
|
||||
BOOL_PARAMETER (LockGrantOrder, true)
|
||||
INT_PARAMETER (LockHashSlots, 101) // slots
|
||||
INT_PARAMETER (LockAcquireSpins, 0)
|
||||
INT_PARAMETER (EventMemSize, 65536) // bytes
|
||||
INT_PARAMETER (DeadlockTimeout, 10) // seconds
|
||||
INT_PARAMETER (SolarisStallValue, 60) // seconds
|
||||
BOOL_PARAMETER (TraceMemoryPools, false) // for internal use only
|
||||
INT_PARAMETER (PrioritySwitchDelay, 100) // milliseconds
|
||||
INT_PARAMETER (DeadThreadsCollection, 50) // number of PrioritySwitchDelay cycles before dead threads collection
|
||||
INT_PARAMETER (PriorityBoost, 5) // ratio oh high- to low-priority thread ticks in jrd.cpp
|
||||
#ifdef FB_SERVICE_NAME
|
||||
STR_PARAMETER (RemoteServiceName, FB_SERVICE_NAME)
|
||||
INT_PARAMETER (RemoteServicePort, 0)
|
||||
STR_PARAMETER (RemotePipeName, FB_PIPE_NAME)
|
||||
STR_PARAMETER (IpcName, FB_IPC_NAME)
|
||||
#endif
|
||||
#ifdef WIN_NT
|
||||
INT_PARAMETER (MaxUnflushedWrites, 100)
|
||||
INT_PARAMETER (MaxUnflushedWriteTime, 5)
|
||||
#else
|
||||
INT_PARAMETER (MaxUnflushedWrites, -1)
|
||||
INT_PARAMETER (MaxUnflushedWriteTime, -1)
|
||||
#endif
|
||||
INT_PARAMETER (ProcessPriorityLevel, 0)
|
||||
BOOL_PARAMETER (CreateInternalWindow, true)
|
||||
BOOL_PARAMETER (CompleteBooleanEvaluation, false)
|
||||
INT_PARAMETER (RemoteAuxPort, 0)
|
||||
STR_PARAMETER (RemoteBindAddress, 0)
|
||||
STR_PARAMETER (ExternalFileAccess, "None") // location(s) of external files for tables
|
||||
STR_PARAMETER (DatabaseAccess, "Full") // location(s) of databases
|
||||
STR_PARAMETER (UdfAccess, "Restrict UDF") // location(s) of UDFs
|
||||
STR_PARAMETER (TempDirectories, 0)
|
||||
//INT_PARAMETER (TraceDSQL, 0} // bitmask
|
||||
STR_PARAMETER (LockFileName, 0)
|
||||
STR_PARAMETER (SecurityDatabase, "None")
|
||||
BOOL_PARAMETER (DatabaseFileShared, false)
|
||||
INT_PARAMETER (TraceFlags, 0)
|
||||
STR_PARAMETER (SecurityManager, "SecurityDb")
|
||||
INT_PARAMETER (CommitInterval, 200)
|
||||
|
@ -47,7 +47,7 @@
|
||||
|
||||
#include "../common/classes/fb_string.h"
|
||||
|
||||
class ScanDir : public Firebird::GlobalStorage
|
||||
class ScanDir : public Firebird::AutoStorage
|
||||
{
|
||||
public:
|
||||
ScanDir(const char *dir, const char *pattern);
|
||||
|
@ -1,625 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* 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/idpl.html.
|
||||
*
|
||||
* Software distributed under the License is distributed on
|
||||
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
|
||||
* express or implied. See the License for the specific
|
||||
* language governing rights and limitations under the License.
|
||||
*
|
||||
* The contents of this file or any work derived from this file
|
||||
* may not be distributed under any other license whatsoever
|
||||
* without the express prior written permission of the original
|
||||
* author.
|
||||
*
|
||||
*
|
||||
* The Original Code was created by James A. Starkey for IBPhoenix.
|
||||
*
|
||||
* Copyright (c) 1997 - 2000, 2001, 2003 James A. Starkey
|
||||
* Copyright (c) 1997 - 2000, 2001, 2003 Netfrastructure, Inc.
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
|
||||
// Stream.cpp: implementation of the Stream class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <memory.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include "firebird.h"
|
||||
#include "../common/classes/alloc.h"
|
||||
#include "Stream.h"
|
||||
#include "StreamSegment.h"
|
||||
|
||||
|
||||
// CVC: The logic in this module seems to overwrite constant params passed into the
|
||||
// address field of the Segment structure. This includes literal strings (see Element.cpp).
|
||||
|
||||
#ifndef MAX
|
||||
#define MAX(a, b) ((a > b) ? a : b)
|
||||
#define MIN(a, b) ((a < b) ? a : b)
|
||||
#endif
|
||||
|
||||
#ifdef _DEBUG
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
Stream::Stream(int minSegmentSize)
|
||||
{
|
||||
segments = NULL;
|
||||
current = NULL;
|
||||
totalLength = 0;
|
||||
minSegment = minSegmentSize;
|
||||
copyFlag = true;
|
||||
}
|
||||
|
||||
Stream::~Stream()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
void Stream::putCharacter(char c)
|
||||
{
|
||||
if (!segments || current->length >= currentLength)
|
||||
allocSegment (MAX (100, minSegment));
|
||||
|
||||
current->address [current->length] = c;
|
||||
++current->length;
|
||||
++totalLength;
|
||||
}
|
||||
|
||||
void Stream::putSegment(int length, const char *ptr, bool copy)
|
||||
{
|
||||
#ifdef ENGINE
|
||||
ASSERT (length >= 0);
|
||||
#endif
|
||||
if (length == 0)
|
||||
return;
|
||||
|
||||
const char *address = ptr;
|
||||
totalLength += length;
|
||||
|
||||
if (!segments)
|
||||
{
|
||||
if (copyFlag = copy)
|
||||
{
|
||||
allocSegment (MAX (length, minSegment));
|
||||
current->length = length;
|
||||
memcpy (current->address, address, length);
|
||||
}
|
||||
else
|
||||
{
|
||||
//copyFlag = copy;
|
||||
current = segments = &first;
|
||||
current->length = length;
|
||||
current->address = (char*) address;
|
||||
current->next = NULL;
|
||||
}
|
||||
}
|
||||
else if (copyFlag)
|
||||
{
|
||||
int l = currentLength - current->length;
|
||||
if (l > 0)
|
||||
{
|
||||
const int l2 = MIN (l, length);
|
||||
memcpy (current->address + current->length, address, l2);
|
||||
current->length += l2;
|
||||
length -= l2;
|
||||
address += l2;
|
||||
}
|
||||
if (length)
|
||||
{
|
||||
allocSegment (MAX (length, minSegment));
|
||||
current->length = length;
|
||||
memcpy (current->address, address, length);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
allocSegment (0);
|
||||
current->address = (char*) address;
|
||||
current->length = length;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int Stream::getSegment(int offset, int len, void* ptr) const
|
||||
{
|
||||
int n = 0;
|
||||
int length = len;
|
||||
char* address = static_cast<char*>(ptr);
|
||||
|
||||
for (const Segment *segment = segments; segment; n += segment->length, segment = segment->next)
|
||||
{
|
||||
if (n + segment->length >= offset)
|
||||
{
|
||||
const int off = offset - n;
|
||||
const int l = MIN (length, segment->length - off);
|
||||
memcpy (address, segment->address + off, l);
|
||||
address += l;
|
||||
length -= l;
|
||||
offset += l;
|
||||
if (!length)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return len - length;
|
||||
}
|
||||
|
||||
void Stream::setSegment(Segment * segment, int length, void* address)
|
||||
{
|
||||
segment->length = length;
|
||||
totalLength += length;
|
||||
|
||||
if (copyFlag)
|
||||
{
|
||||
segment->address = new char [length];
|
||||
memcpy (segment->address, address, length);
|
||||
}
|
||||
else
|
||||
segment->address = (char*) address;
|
||||
}
|
||||
|
||||
|
||||
void Stream::setMinSegment(int length)
|
||||
{
|
||||
minSegment = length;
|
||||
}
|
||||
|
||||
Stream::Segment* Stream::allocSegment(int tail)
|
||||
{
|
||||
fb_assert(tail >= 0);
|
||||
|
||||
Segment *segment;
|
||||
int length = tail;
|
||||
|
||||
if (!current && tail <= FIXED_SEGMENT_SIZE)
|
||||
{
|
||||
segment = &first;
|
||||
length = FIXED_SEGMENT_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// CVC: What do we do here in the release build if tail is smaller than FIXED_SEGMENT_SIZE?
|
||||
fb_assert(tail >= FIXED_SEGMENT_SIZE);
|
||||
segment = (Segment*) new char [sizeof(Segment) + tail - FIXED_SEGMENT_SIZE];
|
||||
}
|
||||
|
||||
segment->address = segment->tail;
|
||||
segment->next = NULL;
|
||||
segment->length = 0;
|
||||
currentLength = length;
|
||||
|
||||
if (current)
|
||||
{
|
||||
current->next = segment;
|
||||
current = segment;
|
||||
}
|
||||
else
|
||||
segments = current = segment;
|
||||
|
||||
return segment;
|
||||
}
|
||||
|
||||
int Stream::getSegment(int offset, int len, void * ptr, char delimiter) const
|
||||
{
|
||||
int n = 0;
|
||||
int length = len;
|
||||
char *address = static_cast<char*>(ptr);
|
||||
|
||||
for (const Segment *segment = segments; segment; n += segment->length, segment = segment->next)
|
||||
{
|
||||
if (n + segment->length >= offset)
|
||||
{
|
||||
const int off = offset - n;
|
||||
const int l = MIN (length, segment->length - off);
|
||||
const char *p = segment->address + off;
|
||||
for (const char *end = p + l; p < end;)
|
||||
{
|
||||
const char c = *address++ = *p++;
|
||||
--length;
|
||||
if (c == delimiter)
|
||||
return len - length;
|
||||
}
|
||||
if (!length)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return len - length;
|
||||
}
|
||||
|
||||
void Stream::putSegment(const char * string)
|
||||
{
|
||||
if (string [0])
|
||||
putSegment ((int) strlen (string), string, true);
|
||||
}
|
||||
|
||||
char* Stream::getString()
|
||||
{
|
||||
char* const string = new char [totalLength + 1];
|
||||
getSegment (0, totalLength, string);
|
||||
string [totalLength] = 0;
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
#ifdef ENGINE
|
||||
void Stream::compress(int length, const void * address)
|
||||
{
|
||||
//printShorts ("Original data", (length + 1) / 2, (short*) address);
|
||||
Segment *segment = allocSegment (length + 5);
|
||||
short *q = (short*) segment->address;
|
||||
const short *p = (short*) address;
|
||||
const short* const end = p + (length + 1) / 2;
|
||||
const short* const yellow = end - 2;
|
||||
*q++ = length;
|
||||
|
||||
while (p < end)
|
||||
{
|
||||
short *start = ++q;
|
||||
while (p < end && (p >= yellow || p[0] != p[1] || p[1] != p[2]))
|
||||
*q++ = *p++;
|
||||
int n = q - start;
|
||||
if (n)
|
||||
start [-1] = -n;
|
||||
else
|
||||
--q;
|
||||
if (p >= end)
|
||||
break;
|
||||
const short* start2 = p++;
|
||||
while (p < end && *p == *start2)
|
||||
++p;
|
||||
n = p - start2;
|
||||
*q++ = n;
|
||||
*q++ = *start2;
|
||||
}
|
||||
|
||||
totalLength = segment->length = (char*) q - segment->address;
|
||||
}
|
||||
|
||||
char* Stream::decompress(int tableId, int recordNumber)
|
||||
{
|
||||
char *data;
|
||||
short *q, *limit;
|
||||
int run = 0;
|
||||
decompressedLength = 0;
|
||||
|
||||
for (Segment *segment = segments; segment; segment = segment->next)
|
||||
{
|
||||
if (segment->length == 0)
|
||||
continue;
|
||||
const short* p = (short*) segment->address;
|
||||
const short* end = (short*) (segment->address + segment->length);
|
||||
if (decompressedLength == 0)
|
||||
{
|
||||
decompressedLength = *p++;
|
||||
if (decompressedLength <= 0)
|
||||
{
|
||||
Log::log ("corrupted record, table %d, record %d, decompressed length %d\n",
|
||||
tableId, recordNumber, decompressedLength);
|
||||
throw SQLEXCEPTION (RUNTIME_ERROR, "corrupted record, table %d, record %d, decompressed length %d",
|
||||
tableId, recordNumber, decompressedLength);
|
||||
}
|
||||
int len = ((decompressedLength + 1) / 2) * 2;
|
||||
//data = new char [len];
|
||||
data = ALLOCATE_RECORD (len);
|
||||
limit = (short*) (data + decompressedLength);
|
||||
if (decompressedLength & 1)
|
||||
++limit;
|
||||
q = (short*) data;
|
||||
}
|
||||
while (p < end)
|
||||
{
|
||||
const short n = *p++;
|
||||
//#ifdef ENGINE
|
||||
if (n == 0 && run == 0)
|
||||
{
|
||||
Log::log ("corrupted record (zero run), table %d, record %d\n", tableId, recordNumber);
|
||||
printShorts ("Zero run", (segment->length + 1) / 2, (short*) segment->address);
|
||||
printChars ("Zero run", segment->length, segment->address);
|
||||
}
|
||||
//#endif
|
||||
if (run > 0)
|
||||
{
|
||||
for (; run; --run)
|
||||
*q++ = n;
|
||||
}
|
||||
else if (run < 0)
|
||||
{
|
||||
*q++ = n;
|
||||
++run;
|
||||
}
|
||||
else
|
||||
{
|
||||
run = n;
|
||||
if (q + run > limit)
|
||||
{
|
||||
//#ifdef ENGINE
|
||||
Log::log ("corrupted record (overrun), table %d, record %d\n", tableId, recordNumber);
|
||||
printShorts ("Compressed", (segment->length + 1)/2, (short*) segment->address);
|
||||
printChars ("Compressed", segment->length, segment->address);
|
||||
//#endif
|
||||
if (q == limit)
|
||||
return data;
|
||||
throw SQLEXCEPTION (RUNTIME_ERROR, "corrupted record, table %d, record %d", tableId, recordNumber);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//printShorts ("Decompressed", (decompressedLength + 1) / 2, (short*) data);
|
||||
return data;
|
||||
}
|
||||
|
||||
void Stream::printShorts(const char * msg, int length, short * data)
|
||||
{
|
||||
Log::debug ("%s", msg);
|
||||
|
||||
for (int n = 0; n < length; ++n)
|
||||
{
|
||||
if (n % 10 == 0)
|
||||
Log::debug ("\n ");
|
||||
Log::debug ("%d, ", data [n]);
|
||||
}
|
||||
|
||||
Log::debug ("\n");
|
||||
}
|
||||
|
||||
void Stream::printChars(const char * msg, int length, const char * data)
|
||||
{
|
||||
Log::debug ("%s", msg);
|
||||
|
||||
for (int n = 0; n < length; ++n)
|
||||
{
|
||||
if (n % 50 == 0)
|
||||
Log::debug ("\n ");
|
||||
const char c = data [n];
|
||||
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9'))
|
||||
putchar (c);
|
||||
else
|
||||
putchar ('.');
|
||||
}
|
||||
|
||||
Log::debug ("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
void Stream::clear()
|
||||
{
|
||||
Segment *segment;
|
||||
|
||||
while (segment = segments)
|
||||
{
|
||||
segments = segment->next;
|
||||
if (segment != &first)
|
||||
delete[] (char*) segment;
|
||||
}
|
||||
|
||||
current = NULL;
|
||||
totalLength = 0;
|
||||
}
|
||||
|
||||
void Stream::putSegment(int length, const unsigned short *chars)
|
||||
{
|
||||
if (length == 0)
|
||||
return;
|
||||
|
||||
totalLength += length;
|
||||
const unsigned short *wc = chars;
|
||||
|
||||
if (!segments)
|
||||
{
|
||||
allocSegment (MAX (length, minSegment));
|
||||
current->length = length;
|
||||
}
|
||||
else
|
||||
{
|
||||
int l = currentLength - current->length;
|
||||
if (l > 0)
|
||||
{
|
||||
const int l2 = MIN (l, length);
|
||||
char *p = current->address + current->length;
|
||||
for (int n = 0; n < l2; ++n)
|
||||
*p++ = (char) *wc++;
|
||||
//memcpy (current->address + current->length, address, l2);
|
||||
current->length += l2;
|
||||
length -= l2;
|
||||
//address += l2;
|
||||
}
|
||||
if (length)
|
||||
{
|
||||
allocSegment (MAX (length, minSegment));
|
||||
current->length = length;
|
||||
//memcpy (current->address, address, length);
|
||||
}
|
||||
}
|
||||
|
||||
char *p = current->address;
|
||||
|
||||
for (int n = 0; n < length; ++n)
|
||||
*p++ = (char) *wc++;
|
||||
|
||||
}
|
||||
|
||||
int Stream::getLength() const
|
||||
{
|
||||
return totalLength;
|
||||
}
|
||||
|
||||
|
||||
int Stream::getSegmentLength(int offset) const
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
for (const Segment *segment = segments; segment; segment = segment->next)
|
||||
{
|
||||
if (offset >= n && offset < n + segment->length)
|
||||
return n + segment->length - offset;
|
||||
n += segment->length;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* Stream::getSegment(int offset)
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
for (Segment *segment = segments; segment; segment = segment->next)
|
||||
{
|
||||
if (offset >= n && offset < n + segment->length)
|
||||
return segment->address + offset - n;
|
||||
n += segment->length;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const void* Stream::getSegment(int offset) const
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
for (const Segment *segment = segments; segment; segment = segment->next)
|
||||
{
|
||||
if (offset >= n && offset < n + segment->length)
|
||||
return segment->address + offset - n;
|
||||
n += segment->length;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void Stream::putSegment(Stream * stream)
|
||||
{
|
||||
/***
|
||||
for (Segment *segment = stream->segments; segment; segment = segment->next)
|
||||
putSegment (segment->length, segment->address, true);
|
||||
***/
|
||||
|
||||
if (stream->totalLength == 0)
|
||||
return;
|
||||
|
||||
StreamSegment seg(stream);
|
||||
|
||||
if (current)
|
||||
{
|
||||
for (int len = currentLength - current->length; len && seg.available;)
|
||||
{
|
||||
const int l = MIN (len, seg.available);
|
||||
putSegment (l, seg.data, true);
|
||||
seg.advance (l);
|
||||
len -= l;
|
||||
}
|
||||
}
|
||||
|
||||
if (seg.remaining)
|
||||
seg.copy (alloc (seg.remaining), seg.remaining);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Firebird::string Stream::getFBString() const
|
||||
{
|
||||
Firebird::string string;
|
||||
char *p = string.getBuffer (totalLength);
|
||||
|
||||
for (const Segment *segment = segments; segment; segment = segment->next)
|
||||
{
|
||||
memcpy (p, segment->address, segment->length);
|
||||
p += segment->length;
|
||||
}
|
||||
|
||||
fb_assert(p - string.begin() == totalLength);
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
char* Stream::alloc(int length)
|
||||
{
|
||||
totalLength += length;
|
||||
|
||||
if (!current || length > currentLength - current->length)
|
||||
allocSegment (length);
|
||||
|
||||
char* const p = current->tail + current->length;
|
||||
current->length += length;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
void Stream::format(const char *pattern, ...)
|
||||
{
|
||||
Firebird::string temp;
|
||||
|
||||
va_list args;
|
||||
va_start (args, pattern);
|
||||
temp.vprintf(pattern, args);
|
||||
va_end(args);
|
||||
|
||||
putSegment (temp.c_str());
|
||||
}
|
||||
|
||||
void Stream::truncate(int length)
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
for (Segment *segment = segments; segment; segment = segment->next)
|
||||
{
|
||||
if (length >= n && length < n + segment->length)
|
||||
{
|
||||
current = segment;
|
||||
current->length = length - n;
|
||||
totalLength = length;
|
||||
while (segment = current->next)
|
||||
{
|
||||
current->next = segment->next;
|
||||
delete[] (char*) segment; // Was deallocation bug
|
||||
}
|
||||
return;
|
||||
}
|
||||
n += segment->length;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int Stream::compare(const Stream *stream) const
|
||||
{
|
||||
for (int offset = 0;;)
|
||||
{
|
||||
const int length1 = getSegmentLength(offset);
|
||||
const int length2 = stream->getSegmentLength(offset);
|
||||
if (length1 == 0)
|
||||
{
|
||||
if (length2)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
if (length2 == 0)
|
||||
return 1;
|
||||
const int length = MIN (length1, length2);
|
||||
const char *p1 = (const char*) getSegment (offset);
|
||||
const char *p2 = (const char*) stream->getSegment (offset);
|
||||
for (const char *end = p1 + length; p1 < end;)
|
||||
{
|
||||
int n = *p1++ - *p2++;
|
||||
if (n)
|
||||
return n;
|
||||
}
|
||||
offset += length;
|
||||
}
|
||||
}
|
@ -1,97 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* 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/idpl.html.
|
||||
*
|
||||
* Software distributed under the License is distributed on
|
||||
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
|
||||
* express or implied. See the License for the specific
|
||||
* language governing rights and limitations under the License.
|
||||
*
|
||||
* The contents of this file or any work derived from this file
|
||||
* may not be distributed under any other license whatsoever
|
||||
* without the express prior written permission of the original
|
||||
* author.
|
||||
*
|
||||
*
|
||||
* The Original Code was created by James A. Starkey for IBPhoenix.
|
||||
*
|
||||
* Copyright (c) 1997 - 2000, 2001, 2003 James A. Starkey
|
||||
* Copyright (c) 1997 - 2000, 2001, 2003 Netfrastructure, Inc.
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
|
||||
// Stream.h: interface for the Stream class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(AFX_STREAM_H__02AD6A53_A433_11D2_AB5B_0000C01D2301__INCLUDED_)
|
||||
#define AFX_STREAM_H__02AD6A53_A433_11D2_AB5B_0000C01D2301__INCLUDED_
|
||||
|
||||
#if defined _MSC_VER && _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
|
||||
#include "../common/classes/fb_string.h"
|
||||
|
||||
START_NAMESPACE
|
||||
|
||||
class Stream : public Firebird::GlobalStorage
|
||||
{
|
||||
public:
|
||||
enum { FIXED_SEGMENT_SIZE = 1024 };
|
||||
|
||||
struct Segment
|
||||
{
|
||||
int length;
|
||||
char *address;
|
||||
Segment *next;
|
||||
char tail [FIXED_SEGMENT_SIZE];
|
||||
};
|
||||
|
||||
explicit Stream (int minSegmentSize = FIXED_SEGMENT_SIZE);
|
||||
virtual ~Stream();
|
||||
|
||||
int compare (const Stream *stream) const;
|
||||
void truncate (int length);
|
||||
void format (const char *pattern, ...);
|
||||
void putSegment (int length, const unsigned short *chars);
|
||||
void putSegment (Stream *stream);
|
||||
virtual void putSegment (const char *string);
|
||||
virtual void putSegment (int length, const char *address, bool copy);
|
||||
void putCharacter (char c);
|
||||
|
||||
virtual void setSegment (Segment *segment, int length, void* address);
|
||||
virtual int getSegment (int offset, int len, void* ptr) const;
|
||||
virtual int getSegment (int offset, int len, void *ptr, char delimiter) const;
|
||||
void* getSegment (int offset);
|
||||
const void* getSegment (int offset) const;
|
||||
int getSegmentLength(int offset) const;
|
||||
|
||||
Firebird::string getFBString() const;
|
||||
virtual char* getString();
|
||||
void clear();
|
||||
virtual int getLength() const;
|
||||
virtual char* alloc (int length);
|
||||
|
||||
Segment* allocSegment (int tail);
|
||||
void setMinSegment (int length);
|
||||
|
||||
int totalLength;
|
||||
//int useCount;
|
||||
Segment *segments; // used by StreamSegment::setStream
|
||||
private:
|
||||
int minSegment;
|
||||
int currentLength;
|
||||
int decompressedLength;
|
||||
bool copyFlag;
|
||||
Segment first;
|
||||
Segment *current;
|
||||
};
|
||||
|
||||
END_NAMESPACE
|
||||
|
||||
#endif // !defined(AFX_STREAM_H__02AD6A53_A433_11D2_AB5B_0000C01D2301__INCLUDED_)
|
@ -1,112 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* 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/idpl.html.
|
||||
*
|
||||
* Software distributed under the License is distributed on
|
||||
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
|
||||
* express or implied. See the License for the specific
|
||||
* language governing rights and limitations under the License.
|
||||
*
|
||||
* The contents of this file or any work derived from this file
|
||||
* may not be distributed under any other license whatsoever
|
||||
* without the express prior written permission of the original
|
||||
* author.
|
||||
*
|
||||
*
|
||||
* The Original Code was created by James A. Starkey for IBPhoenix.
|
||||
*
|
||||
* Copyright (c) 1997 - 2000, 2001, 2003 James A. Starkey
|
||||
* Copyright (c) 1997 - 2000, 2001, 2003 Netfrastructure, Inc.
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
|
||||
// StreamSegment.cpp: implementation of the StreamSegment class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <memory.h>
|
||||
#include "firebird.h"
|
||||
#include "../jrd/common.h"
|
||||
#include "StreamSegment.h"
|
||||
#include "Stream.h"
|
||||
|
||||
#ifndef MAX
|
||||
//#define MAX(a, b) ((a > b) ? a : b)
|
||||
#define MIN(a, b) ((a < b) ? a : b)
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
StreamSegment::StreamSegment(Stream *stream)
|
||||
{
|
||||
setStream (stream);
|
||||
}
|
||||
|
||||
StreamSegment::~StreamSegment()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void StreamSegment::setStream(Stream *stream)
|
||||
{
|
||||
remaining = stream->totalLength;
|
||||
|
||||
if (segment = stream->segments)
|
||||
{
|
||||
data = segment->address;
|
||||
available = segment->length;
|
||||
}
|
||||
else
|
||||
{
|
||||
data = NULL;
|
||||
available = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void StreamSegment::advance()
|
||||
{
|
||||
advance (available);
|
||||
}
|
||||
|
||||
void StreamSegment::advance(int size)
|
||||
{
|
||||
for (int len = size; len;)
|
||||
{
|
||||
const int l = MIN (available, len);
|
||||
available -= l;
|
||||
remaining -= l;
|
||||
len -= size;
|
||||
if (remaining == 0)
|
||||
return;
|
||||
if (available)
|
||||
data += l;
|
||||
else
|
||||
{
|
||||
segment = segment->next;
|
||||
data = segment->address;
|
||||
available = segment->length;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char* StreamSegment::copy(void *target, int length)
|
||||
{
|
||||
char* targ = static_cast<char*>(target);
|
||||
|
||||
for (int len = length; len;)
|
||||
{
|
||||
const int l = MIN (len, available);
|
||||
memcpy (targ, data, l);
|
||||
targ += l;
|
||||
len -= l;
|
||||
advance (l);
|
||||
}
|
||||
|
||||
return targ;
|
||||
}
|
@ -1,65 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* 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/idpl.html.
|
||||
*
|
||||
* Software distributed under the License is distributed on
|
||||
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
|
||||
* express or implied. See the License for the specific
|
||||
* language governing rights and limitations under the License.
|
||||
*
|
||||
* The contents of this file or any work derived from this file
|
||||
* may not be distributed under any other license whatsoever
|
||||
* without the express prior written permission of the original
|
||||
* author.
|
||||
*
|
||||
*
|
||||
* The Original Code was created by James A. Starkey for IBPhoenix.
|
||||
*
|
||||
* Copyright (c) 1997 - 2000, 2001, 2003 James A. Starkey
|
||||
* Copyright (c) 1997 - 2000, 2001, 2003 Netfrastructure, Inc.
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
|
||||
// StreamSegment.h: interface for the StreamSegment class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(AFX_STREAMSEGMENT_H__11469FBB_A55A_4BB1_A96B_D95A4C75F0C7__INCLUDED_)
|
||||
#define AFX_STREAMSEGMENT_H__11469FBB_A55A_4BB1_A96B_D95A4C75F0C7__INCLUDED_
|
||||
|
||||
#if defined _MSC_VER && _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
#include "../common/classes/alloc.h"
|
||||
#include "Stream.h"
|
||||
|
||||
START_NAMESPACE
|
||||
|
||||
|
||||
class StreamSegment : public Firebird::GlobalStorage
|
||||
{
|
||||
public:
|
||||
explicit StreamSegment(Stream *stream);
|
||||
virtual ~StreamSegment();
|
||||
|
||||
char* copy (void *target, int length);
|
||||
void advance (int size);
|
||||
void advance();
|
||||
void setStream (Stream *stream);
|
||||
|
||||
private:
|
||||
friend class Stream; // for "available" and "remaining"
|
||||
int available;
|
||||
int remaining;
|
||||
char* data;
|
||||
Stream::Segment* segment;
|
||||
};
|
||||
|
||||
END_NAMESPACE
|
||||
|
||||
#endif // !defined(AFX_STREAMSEGMENT_H__11469FBB_A55A_4BB1_A96B_D95A4C75F0C7__INCLUDED_)
|
@ -63,6 +63,7 @@
|
||||
#include "../jrd/os/thd_priority.h"
|
||||
#include "../jrd/event_proto.h"
|
||||
#include "../lock/lock_proto.h"
|
||||
#include "../common/config/config.h"
|
||||
|
||||
class CharSetContainer;
|
||||
|
||||
@ -77,6 +78,7 @@ namespace Jrd
|
||||
class TxPageCache;
|
||||
class BackupManager;
|
||||
class vcl;
|
||||
class ExternalFileDirectoryList;
|
||||
|
||||
typedef Firebird::ObjectsArray<Trigger> trig_vec;
|
||||
|
||||
@ -455,6 +457,8 @@ public:
|
||||
Firebird::Array<Function*> dbb_functions; // User defined functions
|
||||
Firebird::GenericMap<Firebird::Pair<Firebird::Left<
|
||||
Firebird::MetaName, USHORT> > > dbb_charset_ids; // Character set ids
|
||||
ExternalFileDirectoryList* dbb_external_file_directory_list;
|
||||
Firebird::RefPtr<Config> dbb_config;
|
||||
|
||||
// returns true if primary file is located on raw device
|
||||
bool onRawDevice() const;
|
||||
@ -489,7 +493,8 @@ private:
|
||||
dbb_charsets(*p),
|
||||
dbb_creation_date(Firebird::TimeStamp::getCurrentTimeStamp()),
|
||||
dbb_functions(*p),
|
||||
dbb_charset_ids(*p)
|
||||
dbb_charset_ids(*p),
|
||||
dbb_external_file_directory_list(NULL)
|
||||
{
|
||||
dbb_pools.add(p);
|
||||
dbb_internal.grow(irq_MAX);
|
||||
|
@ -623,7 +623,7 @@ RecordBuffer* DatabaseSnapshot::allocBuffer(thread_db* tdbb, MemoryPool& pool, i
|
||||
Format* format = MET_current(tdbb, relation);
|
||||
fb_assert(format);
|
||||
|
||||
RecordBuffer* buffer = FB_NEW(pool) RecordBuffer(pool, format);
|
||||
RecordBuffer* buffer = FB_NEW(pool) RecordBuffer(pool, format, tdbb->getDatabase()->dbb_config);
|
||||
RelationData data = {relation->rel_id, buffer};
|
||||
snapshot.add(data);
|
||||
|
||||
|
@ -45,18 +45,13 @@
|
||||
#include "../jrd/mov_proto.h"
|
||||
#include "../jrd/thread_proto.h"
|
||||
#include "../jrd/Function.h"
|
||||
#include "../jrd/isc_proto.h"
|
||||
#include "../common/classes/auto.h"
|
||||
#include "../common/classes/fb_string.h"
|
||||
#include "../common/classes/init.h"
|
||||
#include "../common/classes/objects_array.h"
|
||||
#include "../common/config/config.h"
|
||||
|
||||
#include "../config/ConfigFile.h"
|
||||
#include "../config/ConfObj.h"
|
||||
#include "../config/ConfObject.h"
|
||||
#include "../config/Element.h"
|
||||
#include "../config/ScanDir.h"
|
||||
#include "../config/AdminException.h"
|
||||
|
||||
using namespace Firebird;
|
||||
|
||||
@ -313,7 +308,7 @@ void ExtEngineManager::ExternalContextImpl::setTransaction(thread_db* tdbb)
|
||||
transaction = FB_NEW(*internalAttachment->att_pool) TransactionImpl(traHandle);
|
||||
}
|
||||
|
||||
ExternalEngine* ExtEngineManager::ExternalContextImpl::getEngine(Firebird::Error* /*error*/)
|
||||
ExternalEngine* ExtEngineManager::ExternalContextImpl::getEngine(Error* /*error*/)
|
||||
{
|
||||
return engine;
|
||||
}
|
||||
@ -336,7 +331,7 @@ Firebird::Transaction* FB_CALL ExtEngineManager::ExternalContextImpl::getTransac
|
||||
}
|
||||
|
||||
|
||||
const Firebird::Utf8* FB_CALL ExtEngineManager::ExternalContextImpl::getClientCharSet()
|
||||
const Utf8* FB_CALL ExtEngineManager::ExternalContextImpl::getClientCharSet()
|
||||
{
|
||||
return clientCharSet.c_str();
|
||||
}
|
||||
@ -368,14 +363,14 @@ void* FB_CALL ExtEngineManager::ExternalContextImpl::setInfo(int code, void* val
|
||||
//---------------------
|
||||
|
||||
|
||||
static InitInstance<GenericMap<Pair<Full<MetaName, string> > > > enginesModules;
|
||||
static InitInstance<GenericMap<Pair<Full<MetaName, PathName> > > > enginesModules;
|
||||
|
||||
|
||||
//---------------------
|
||||
|
||||
|
||||
ExtEngineManager::Function::Function(thread_db* tdbb, ExtEngineManager* aExtManager,
|
||||
ExternalEngine* aEngine, Firebird::ExternalFunction* aFunction,
|
||||
ExternalEngine* aEngine, ExternalFunction* aFunction,
|
||||
const Jrd::Function* aUdf)
|
||||
: extManager(aExtManager),
|
||||
engine(aEngine),
|
||||
@ -405,7 +400,7 @@ void ExtEngineManager::Function::execute(thread_db* tdbb, jrd_nod* args, impure_
|
||||
MemoryPool& pool = *tdbb->getDefaultPool();
|
||||
ValueImpl result(pool, &impure->vlu_desc, "", true);
|
||||
|
||||
Firebird::HalfStaticArray<impure_value, 32> impureArgs;
|
||||
HalfStaticArray<impure_value, 32> impureArgs;
|
||||
|
||||
impure_value* impureArgsPtr = impureArgs.getBuffer(args->nod_count);
|
||||
try
|
||||
@ -470,7 +465,7 @@ void ExtEngineManager::Function::execute(thread_db* tdbb, jrd_nod* args, impure_
|
||||
|
||||
|
||||
ExtEngineManager::Procedure::Procedure(thread_db* tdbb, ExtEngineManager* aExtManager,
|
||||
ExternalEngine* aEngine, Firebird::ExternalProcedure* aProcedure,
|
||||
ExternalEngine* aEngine, ExternalProcedure* aProcedure,
|
||||
const jrd_prc* aPrc)
|
||||
: extManager(aExtManager),
|
||||
engine(aEngine),
|
||||
@ -552,7 +547,7 @@ bool ExtEngineManager::ResultSet::fetch(thread_db* tdbb)
|
||||
|
||||
|
||||
ExtEngineManager::Trigger::Trigger(thread_db* tdbb, ExtEngineManager* aExtManager,
|
||||
ExternalEngine* aEngine, Firebird::ExternalTrigger* aTrigger,
|
||||
ExternalEngine* aEngine, ExternalTrigger* aTrigger,
|
||||
const Jrd::Trigger* aTrg)
|
||||
: extManager(aExtManager),
|
||||
engine(aEngine),
|
||||
@ -568,7 +563,7 @@ ExtEngineManager::Trigger::~Trigger()
|
||||
}
|
||||
|
||||
|
||||
void ExtEngineManager::Trigger::execute(thread_db* tdbb, Firebird::ExternalTrigger::Action action,
|
||||
void ExtEngineManager::Trigger::execute(thread_db* tdbb, ExternalTrigger::Action action,
|
||||
record_param* oldRpb, record_param* newRpb)
|
||||
{
|
||||
EngineAttachmentInfo* attInfo = extManager->getEngineAttachment(tdbb, engine);
|
||||
@ -675,22 +670,26 @@ ExtEngineManager::~ExtEngineManager()
|
||||
|
||||
void ExtEngineManager::initialize()
|
||||
{
|
||||
Firebird::PathName pluginsPath = PluginManager::getPluginsDirectory();
|
||||
PathName pluginsPath = PluginManager::getPluginsDirectory();
|
||||
|
||||
ScanDir dir(pluginsPath.c_str(), "*.conf");
|
||||
|
||||
try
|
||||
{
|
||||
SortedObjectsArray<MetaName> conflicts(*getDefaultMemoryPool());
|
||||
SortedArray<MetaName> conflicts;
|
||||
|
||||
while (dir.next())
|
||||
{
|
||||
Vulcan::ConfigFile configFile(dir.getFilePath(), Vulcan::ConfigFile::LEX_none);
|
||||
ConfigFile configFile(dir.getFilePath(),
|
||||
ConfigFile::EXCEPTION_ON_ERROR | ConfigFile::HAS_SUB_CONF);
|
||||
|
||||
for (Element* el = configFile.getObjects()->children; el; el = el->sibling)
|
||||
const ConfigFile::Parameters& params = configFile.getParameters();
|
||||
for (size_t n = 0; n < params.getCount(); ++n)
|
||||
{
|
||||
const ConfigFile::Parameter* el = ¶ms[n];
|
||||
if (el->name == "external_engine")
|
||||
{
|
||||
MetaName name = el->getAttributeName(0);
|
||||
MetaName name(el->value);
|
||||
|
||||
if (enginesModules().exist(name) || conflicts.exist(name))
|
||||
{
|
||||
@ -702,22 +701,23 @@ void ExtEngineManager::initialize()
|
||||
continue;
|
||||
}
|
||||
|
||||
Element* plugin = el->findChild("plugin_module");
|
||||
const ConfigFile::Parameter* plugin = el->sub->findParameter("plugin_module");
|
||||
|
||||
if (plugin)
|
||||
enginesModules().put(name, plugin->getAttributeName(0));
|
||||
enginesModules().put(name, plugin->value);
|
||||
else
|
||||
conflicts.add(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (AdminException& ex)
|
||||
catch (const Exception& ex)
|
||||
{
|
||||
string s;
|
||||
s.printf("Error in plugin config file '%s': %s'", dir.getFilePath(), ex.getText());
|
||||
gds__log(s.c_str());
|
||||
s.printf("Error in plugin config file '%s':", dir.getFilePath());
|
||||
iscLogException(s.c_str(), ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -751,8 +751,8 @@ void ExtEngineManager::closeAttachment(thread_db* tdbb, Attachment* /*attachment
|
||||
|
||||
|
||||
ExtEngineManager::Function* ExtEngineManager::makeFunction(thread_db* tdbb, const Jrd::Function* udf,
|
||||
const Firebird::MetaName& engine, const Firebird::string& entryPoint,
|
||||
const Firebird::string& body)
|
||||
const MetaName& engine, const string& entryPoint,
|
||||
const string& body)
|
||||
{
|
||||
string entryPointTrimmed = entryPoint;
|
||||
entryPointTrimmed.trim();
|
||||
@ -794,8 +794,8 @@ ExtEngineManager::Function* ExtEngineManager::makeFunction(thread_db* tdbb, cons
|
||||
|
||||
|
||||
ExtEngineManager::Procedure* ExtEngineManager::makeProcedure(thread_db* tdbb, const jrd_prc* prc,
|
||||
const Firebird::MetaName& engine, const Firebird::string& entryPoint,
|
||||
const Firebird::string& body)
|
||||
const MetaName& engine, const string& entryPoint,
|
||||
const string& body)
|
||||
{
|
||||
string entryPointTrimmed = entryPoint;
|
||||
entryPointTrimmed.trim();
|
||||
@ -837,8 +837,8 @@ ExtEngineManager::Procedure* ExtEngineManager::makeProcedure(thread_db* tdbb, co
|
||||
|
||||
|
||||
ExtEngineManager::Trigger* ExtEngineManager::makeTrigger(thread_db* tdbb, const Jrd::Trigger* trg,
|
||||
const Firebird::MetaName& engine, const Firebird::string& entryPoint,
|
||||
const Firebird::string& body, Firebird::ExternalTrigger::Type type)
|
||||
const MetaName& engine, const string& entryPoint,
|
||||
const string& body, ExternalTrigger::Type type)
|
||||
{
|
||||
string entryPointTrimmed = entryPoint;
|
||||
entryPointTrimmed.trim();
|
||||
@ -880,7 +880,7 @@ ExtEngineManager::Trigger* ExtEngineManager::makeTrigger(thread_db* tdbb, const
|
||||
}
|
||||
|
||||
|
||||
ExternalEngine* ExtEngineManager::getEngine(thread_db* tdbb, const Firebird::MetaName& name)
|
||||
ExternalEngine* ExtEngineManager::getEngine(thread_db* tdbb, const MetaName& name)
|
||||
{
|
||||
ReadLockGuard readGuard(enginesLock);
|
||||
ExternalEngine* engine = NULL;
|
||||
@ -892,7 +892,7 @@ ExternalEngine* ExtEngineManager::getEngine(thread_db* tdbb, const Firebird::Met
|
||||
|
||||
if (!engines.get(name, engine))
|
||||
{
|
||||
string pluginName;
|
||||
PathName pluginName;
|
||||
if (enginesModules().get(name, pluginName))
|
||||
{
|
||||
PluginImpl* plugin = PluginManager::getPlugin(pluginName);
|
||||
@ -958,7 +958,7 @@ ExternalEngine* ExtEngineManager::getEngine(thread_db* tdbb, const Firebird::Met
|
||||
|
||||
|
||||
ExtEngineManager::EngineAttachmentInfo* ExtEngineManager::getEngineAttachment(
|
||||
thread_db* tdbb, const Firebird::MetaName& name)
|
||||
thread_db* tdbb, const MetaName& name)
|
||||
{
|
||||
ExternalEngine* engine = getEngine(tdbb, name);
|
||||
return getEngineAttachment(tdbb, engine);
|
||||
@ -1007,7 +1007,7 @@ ExtEngineManager::EngineAttachmentInfo* ExtEngineManager::getEngineAttachment(
|
||||
}
|
||||
|
||||
|
||||
void ExtEngineManager::setupAdminCharSet(thread_db* tdbb, Firebird::ExternalEngine* engine,
|
||||
void ExtEngineManager::setupAdminCharSet(thread_db* tdbb, ExternalEngine* engine,
|
||||
EngineAttachmentInfo* attInfo)
|
||||
{
|
||||
ContextManager<ExternalFunction> ctxManager(tdbb, attInfo, CS_UTF8);
|
||||
|
@ -29,18 +29,15 @@
|
||||
#include "../jrd/os/mod_loader.h"
|
||||
#include "../jrd/intlobj_new.h"
|
||||
#include "../jrd/intl_proto.h"
|
||||
#include "../jrd/isc_proto.h"
|
||||
#include "../common/config/config.h"
|
||||
#include "../common/classes/GenericMap.h"
|
||||
#include "../common/classes/objects_array.h"
|
||||
#include "../common/classes/fb_string.h"
|
||||
#include "../common/classes/init.h"
|
||||
|
||||
#include "../config/ConfigFile.h"
|
||||
#include "../config/ConfObj.h"
|
||||
#include "../config/ConfObject.h"
|
||||
#include "../config/Element.h"
|
||||
#include "../config/ScanDir.h"
|
||||
#include "../config/AdminException.h"
|
||||
#include "../common/config/config_file.h"
|
||||
|
||||
using namespace Firebird;
|
||||
|
||||
@ -421,7 +418,7 @@ const IntlManager::CollationDefinition IntlManager::defaultCollations[] =
|
||||
bool IntlManager::initialize()
|
||||
{
|
||||
bool ok = true;
|
||||
ObjectsArray<string> conflicts;
|
||||
ObjectsArray<ConfigFile::String> conflicts;
|
||||
string builtinConfig;
|
||||
|
||||
Firebird::PathName intlPath = fb_utils::getPrefix(fb_utils::FB_DIR_INTL, "");
|
||||
@ -432,94 +429,122 @@ bool IntlManager::initialize()
|
||||
{
|
||||
while (dir.next())
|
||||
{
|
||||
ConfigFile configFile(dir.getFilePath(), ConfigFile::LEX_none);
|
||||
ConfigFile configFile(dir.getFilePath(), ConfigFile::HAS_SUB_CONF);
|
||||
|
||||
ConfObj builtinModule(configFile.findObject("intl_module", "builtin"));
|
||||
const ConfigFile::Parameter* builtinModule = configFile.findParameter("intl_module", "builtin");
|
||||
string s = getConfigInfo(builtinModule);
|
||||
if (s.hasData())
|
||||
builtinConfig = s;
|
||||
|
||||
for (const Element* el = configFile.getObjects()->children; el; el = el->sibling)
|
||||
const ConfigFile::Parameters& params = configFile.getParameters();
|
||||
for (size_t n = 0; n < params.getCount(); ++n)
|
||||
{
|
||||
if (el->name == "charset")
|
||||
const ConfigFile::Parameter* ch = ¶ms[n];
|
||||
if (ch->name != "charset")
|
||||
{
|
||||
const string charSetName = el->getAttributeName(0);
|
||||
PathName filename;
|
||||
string configInfo;
|
||||
continue;
|
||||
}
|
||||
if (!ch->sub)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const Element* module = el->findChild("intl_module");
|
||||
if (module)
|
||||
const ConfigFile::String charSetName = ch->value;
|
||||
PathName filename;
|
||||
string configInfo;
|
||||
|
||||
const ConfigFile::Parameter* module = ch->sub->findParameter("intl_module");
|
||||
const ConfigFile::Parameter* objModule;
|
||||
if (module &&
|
||||
(objModule = configFile.findParameter("intl_module", module->value.c_str())))
|
||||
{
|
||||
if (!objModule->sub)
|
||||
{
|
||||
const Firebird::string moduleName(module->getAttributeName(0));
|
||||
ConfObj objModule(configFile.findObject("intl_module", moduleName.c_str()));
|
||||
filename = objModule->getValue("filename", "");
|
||||
configInfo = getConfigInfo(objModule);
|
||||
fatal_exception::raiseFmt("Missing parameters for intl_module %s\n", module->value.c_str());
|
||||
}
|
||||
const ConfigFile::Parameter* fname = objModule->sub->findParameter("filename");
|
||||
if (!fname)
|
||||
{
|
||||
fatal_exception::raiseFmt("Missing parameter 'filename' for intl_module %s\n", module->value.c_str());
|
||||
}
|
||||
filename = fname->value;
|
||||
configInfo = getConfigInfo(objModule);
|
||||
|
||||
if (!modules->exist(filename))
|
||||
if (!modules->exist(filename))
|
||||
{
|
||||
ModuleLoader::Module* mod = ModuleLoader::loadModule(filename);
|
||||
if (!mod)
|
||||
{
|
||||
ModuleLoader::Module* mod = ModuleLoader::loadModule(filename);
|
||||
if (!mod)
|
||||
{
|
||||
ModuleLoader::doctorModuleExtension(filename);
|
||||
mod = ModuleLoader::loadModule(filename);
|
||||
}
|
||||
if (mod)
|
||||
{
|
||||
// Negotiate version
|
||||
pfn_INTL_version versionFunction;
|
||||
USHORT version;
|
||||
ModuleLoader::doctorModuleExtension(filename);
|
||||
mod = ModuleLoader::loadModule(filename);
|
||||
}
|
||||
if (mod)
|
||||
{
|
||||
// Negotiate version
|
||||
pfn_INTL_version versionFunction;
|
||||
USHORT version;
|
||||
|
||||
if (mod->findSymbol(STRINGIZE(INTL_VERSION_ENTRYPOINT), versionFunction))
|
||||
{
|
||||
version = INTL_VERSION_2;
|
||||
versionFunction(&version);
|
||||
}
|
||||
else
|
||||
version = INTL_VERSION_1;
|
||||
|
||||
if (version != INTL_VERSION_1 && version != INTL_VERSION_2)
|
||||
{
|
||||
string err_msg;
|
||||
err_msg.printf("INTL module '%s' is of incompatible version number %d",
|
||||
filename.c_str(), version);
|
||||
gds__log(err_msg.c_str());
|
||||
ok = false;
|
||||
}
|
||||
else
|
||||
modules->put(filename, mod);
|
||||
if (mod->findSymbol(STRINGIZE(INTL_VERSION_ENTRYPOINT), versionFunction))
|
||||
{
|
||||
version = INTL_VERSION_2;
|
||||
versionFunction(&version);
|
||||
}
|
||||
else
|
||||
version = INTL_VERSION_1;
|
||||
|
||||
if (version != INTL_VERSION_1 && version != INTL_VERSION_2)
|
||||
{
|
||||
gds__log((string("Can't load INTL module '") +
|
||||
filename.c_str() + "'").c_str());
|
||||
string err_msg;
|
||||
err_msg.printf("INTL module '%s' is of incompatible version number %d",
|
||||
filename.c_str(), version);
|
||||
gds__log(err_msg.c_str());
|
||||
ok = false;
|
||||
}
|
||||
else
|
||||
modules->put(filename, mod);
|
||||
}
|
||||
else
|
||||
{
|
||||
gds__log((string("Can't load INTL module '") +
|
||||
filename.c_str() + "'").c_str());
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const Element* el2 = el->children; el2; el2 = el2->sibling)
|
||||
const ConfigFile::Parameters& sub = ch->sub->getParameters();
|
||||
for (size_t coll = 0; coll < sub.getCount(); ++coll)
|
||||
{
|
||||
if (sub[coll].name != "collation")
|
||||
{
|
||||
if (el2->name == "collation")
|
||||
{
|
||||
const string collationName = el2->getAttributeName(0);
|
||||
const string charSetCollation = charSetName + ":" + collationName;
|
||||
const char* externalName = el2->getAttributeName(1);
|
||||
continue;
|
||||
}
|
||||
ConfigFile::String collationName = sub[coll].value;
|
||||
ConfigFile::String externalName;
|
||||
size_t pos = collationName.find(' ');
|
||||
if (pos != ConfigFile::String::npos)
|
||||
{
|
||||
externalName = collationName.substr(pos);
|
||||
externalName.ltrim(" \t");
|
||||
collationName = collationName.substr(0, pos);
|
||||
}
|
||||
const ConfigFile::String charSetCollation = charSetName + ":" + collationName;
|
||||
|
||||
if (!registerCharSetCollation(charSetCollation, filename,
|
||||
(externalName ? externalName : collationName), configInfo))
|
||||
{
|
||||
conflicts.add(charSetCollation);
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
if (!registerCharSetCollation(charSetCollation.ToString(), filename,
|
||||
(externalName.hasData() ? externalName : collationName).ToString(), configInfo))
|
||||
{
|
||||
conflicts.add(charSetCollation);
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (AdminException& ex)
|
||||
catch (const Exception& ex)
|
||||
{
|
||||
gds__log((string("Error in INTL plugin config file '") + dir.getFilePath() + "': " + ex.getText()).c_str());
|
||||
string message = "Error in INTL plugin config file ";
|
||||
message += dir.getFilePath();
|
||||
iscLogException(message.c_str(), ex);
|
||||
ok = false;
|
||||
}
|
||||
|
||||
@ -538,8 +563,8 @@ bool IntlManager::initialize()
|
||||
registerCharSetCollation("UTF32:UCS_BASIC", "", "UCS_BASIC", builtinConfig);
|
||||
#endif
|
||||
|
||||
for (ObjectsArray<string>::const_iterator name(conflicts.begin()); name != conflicts.end(); ++name)
|
||||
charSetCollations->remove(*name);
|
||||
for (ObjectsArray<ConfigFile::String>::const_iterator name(conflicts.begin()); name != conflicts.end(); ++name)
|
||||
charSetCollations->remove(name->ToString());
|
||||
|
||||
return ok;
|
||||
}
|
||||
@ -683,31 +708,28 @@ bool IntlManager::setupCollationAttributes(
|
||||
}
|
||||
|
||||
|
||||
Firebird::string IntlManager::getConfigInfo(const ConfObj& confObj)
|
||||
Firebird::string IntlManager::getConfigInfo(const ConfigFile::Parameter* confObj)
|
||||
{
|
||||
if (!confObj.hasObject())
|
||||
return "";
|
||||
|
||||
string configInfo;
|
||||
|
||||
for (const Element* el = confObj->object->children; el; el = el->sibling)
|
||||
if (!confObj || !confObj->sub)
|
||||
{
|
||||
string values;
|
||||
|
||||
for (int i = 0; el->getAttributeName(i); ++i)
|
||||
{
|
||||
if (i > 0)
|
||||
values.append(" ");
|
||||
|
||||
values.append(el->getAttributeName(i));
|
||||
}
|
||||
|
||||
if (configInfo.hasData())
|
||||
configInfo.append(";");
|
||||
configInfo.append(string(el->name.c_str()) + "=" + values);
|
||||
return "";
|
||||
}
|
||||
|
||||
return configInfo;
|
||||
ConfigFile::String configInfo;
|
||||
const ConfigFile::Parameters& all = confObj->sub->getParameters();
|
||||
|
||||
for (size_t n = 0; n < all.getCount(); ++n)
|
||||
{
|
||||
const ConfigFile::Parameter& par = all[n];
|
||||
|
||||
if (configInfo.hasData())
|
||||
{
|
||||
configInfo.append(";");
|
||||
}
|
||||
configInfo.append(par.name + "=" + par.value);
|
||||
}
|
||||
|
||||
return configInfo.ToString();
|
||||
}
|
||||
|
||||
|
||||
|
@ -28,7 +28,7 @@
|
||||
#define JRD_INTLMANAGER_H
|
||||
|
||||
#include "../common/classes/fb_string.h"
|
||||
#include "../config/ConfObj.h"
|
||||
#include "../common/config/config_file.h"
|
||||
|
||||
struct charset;
|
||||
struct texttype;
|
||||
@ -84,7 +84,7 @@ public:
|
||||
const static CollationDefinition defaultCollations[];
|
||||
|
||||
private:
|
||||
static Firebird::string getConfigInfo(const ConfObj& confObj);
|
||||
static Firebird::string getConfigInfo(const ConfigFile::Parameter* par);
|
||||
|
||||
static bool registerCharSetCollation(const Firebird::string& name,
|
||||
const Firebird::PathName& filename, const Firebird::string& externalName,
|
||||
|
@ -28,15 +28,12 @@
|
||||
#include "../jrd/ErrorImpl.h"
|
||||
#include "../jrd/os/path_utils.h"
|
||||
#include "../jrd/err_proto.h"
|
||||
#include "../jrd/isc_proto.h"
|
||||
#include "../common/classes/fb_string.h"
|
||||
#include "../common/classes/init.h"
|
||||
#include "../common/config/config.h"
|
||||
#include "../config/ConfigFile.h"
|
||||
#include "../config/ConfObj.h"
|
||||
#include "../config/ConfObject.h"
|
||||
#include "../config/Element.h"
|
||||
#include "../common/config/config_file.h"
|
||||
#include "../config/ScanDir.h"
|
||||
#include "../config/AdminException.h"
|
||||
|
||||
using namespace Firebird;
|
||||
using Firebird::uint;
|
||||
@ -46,11 +43,11 @@ namespace Jrd {
|
||||
|
||||
namespace
|
||||
{
|
||||
class PluginsMap : public GenericMap<Pair<Left<string, PluginImpl*> > >
|
||||
class PluginsMap : public GenericMap<Pair<Left<PathName, PluginImpl*> > >
|
||||
{
|
||||
public:
|
||||
explicit PluginsMap(MemoryPool& p)
|
||||
: GenericMap<Pair<Left<string, PluginImpl*> > >(p)
|
||||
: GenericMap<Pair<Left<PathName, PluginImpl*> > >(p)
|
||||
{
|
||||
}
|
||||
|
||||
@ -91,68 +88,74 @@ void PluginManager::initialize()
|
||||
|
||||
try
|
||||
{
|
||||
SortedObjectsArray<string> conflicts(*getDefaultMemoryPool());
|
||||
SortedObjectsArray<ConfigFile::String> conflicts(*getDefaultMemoryPool());
|
||||
|
||||
while (dir.next())
|
||||
{
|
||||
Vulcan::ConfigFile configFile(dir.getFilePath(), Vulcan::ConfigFile::LEX_none);
|
||||
ConfigFile configFile(dir.getFilePath(),
|
||||
ConfigFile::HAS_SUB_CONF | ConfigFile::EXCEPTION_ON_ERROR);
|
||||
|
||||
for (Element* el = configFile.getObjects()->children; el; el = el->sibling)
|
||||
const ConfigFile::Parameters& params = configFile.getParameters();
|
||||
for (size_t n = 0; n < params.getCount(); ++n)
|
||||
{
|
||||
if (el->name == "plugin_module")
|
||||
const ConfigFile::Parameter* pm = ¶ms[n];
|
||||
if (pm->name != "plugin_module")
|
||||
{
|
||||
AutoPtr<PluginImpl> plugin(new PluginImpl);
|
||||
plugin->name = el->getAttributeName(0);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (plugins->exist(plugin->name) || conflicts.exist(plugin->name))
|
||||
AutoPtr<PluginImpl> plugin(new PluginImpl);
|
||||
plugin->name = pm->value;
|
||||
if (plugins->exist(plugin->name) || conflicts.exist(plugin->name))
|
||||
{
|
||||
gds__log("Plugin %s defined more than once.", plugin->name.c_str());
|
||||
conflicts.add(plugin->name);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!pm->sub)
|
||||
{
|
||||
fatal_exception::raiseFmt("Missing required parameters for plugin %s",
|
||||
plugin->name.c_str());
|
||||
}
|
||||
const ConfigFile::Parameter* par = pm->sub->findParameter("filename");
|
||||
|
||||
if (!par)
|
||||
{
|
||||
fatal_exception::raiseFmt("Missing required parameter 'filename' for plugin %s",
|
||||
plugin->name.c_str());
|
||||
}
|
||||
plugin->filename = par->value;
|
||||
|
||||
par = pm->sub->findParameter("plugin_config");
|
||||
if (par)
|
||||
{
|
||||
par = configFile.findParameter("plugin_config", par->value);
|
||||
if (!par)
|
||||
{
|
||||
string s;
|
||||
s.printf("Plugin %s defined more than once.", plugin->name.c_str());
|
||||
gds__log(s.c_str());
|
||||
|
||||
conflicts.add(plugin->name);
|
||||
continue;
|
||||
fatal_exception::raiseFmt("Missing required config for plugin %s",
|
||||
plugin->name.c_str());
|
||||
}
|
||||
|
||||
ConfObj objModule(configFile.findObject("plugin_module", plugin->name.c_str()));
|
||||
plugin->filename = objModule->getValue("filename", "");
|
||||
|
||||
Element* config = el->findChild("plugin_config");
|
||||
if (config)
|
||||
if (par->sub)
|
||||
{
|
||||
string configName(config->getAttributeName(0));
|
||||
ConfObj objConfig(configFile.findObject("plugin_config",
|
||||
configName.c_str()));
|
||||
|
||||
for (Element* elConfig = objConfig->object->children;
|
||||
elConfig; elConfig = elConfig->sibling)
|
||||
const ConfigFile::Parameters& all = par->sub->getParameters();
|
||||
for (size_t n = 0; n < all.getCount(); ++n)
|
||||
{
|
||||
const string key = elConfig->name;
|
||||
string value;
|
||||
const char* attribute;
|
||||
|
||||
for (int i = 0; (attribute = elConfig->getAttributeName(i)); ++i)
|
||||
{
|
||||
if (i != 0)
|
||||
value += PathUtils::dir_list_sep;
|
||||
value += objConfig->expand(attribute);
|
||||
}
|
||||
|
||||
plugin->configInfo.add(ConfigEntry(*getDefaultMemoryPool(), key, value));
|
||||
plugin->configInfo.add(ConfigEntry(*getDefaultMemoryPool(), all[n].name, all[n].value));
|
||||
}
|
||||
|
||||
PluginImpl* p = plugin.release();
|
||||
plugins->put(p->name, p);
|
||||
}
|
||||
}
|
||||
|
||||
PluginImpl* p = plugin.release();
|
||||
plugins->put(p->name, p);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (AdminException& ex)
|
||||
catch (const Exception& ex)
|
||||
{
|
||||
string s;
|
||||
s.printf("Error in plugin config file '%s': %s'", dir.getFilePath(), ex.getText());
|
||||
gds__log(s.c_str());
|
||||
s.printf("Error in plugin config file '%s'", dir.getFilePath());
|
||||
iscLogException(s.c_str(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
@ -165,7 +168,7 @@ PathName PluginManager::getPluginsDirectory()
|
||||
}
|
||||
|
||||
|
||||
PluginImpl* PluginManager::getPlugin(const string& name)
|
||||
PluginImpl* PluginManager::getPlugin(const PathName& name)
|
||||
{
|
||||
PluginImpl* plugin;
|
||||
|
||||
|
@ -37,7 +37,7 @@
|
||||
namespace Jrd {
|
||||
|
||||
|
||||
typedef Firebird::Pair<Firebird::Full<Firebird::string, Firebird::string> > ConfigEntry;
|
||||
typedef Firebird::Pair<Firebird::Full<Firebird::PathName, Firebird::PathName> > ConfigEntry;
|
||||
|
||||
class PluginImpl : public Firebird::Plugin, public Firebird::GlobalStorage
|
||||
{
|
||||
@ -66,12 +66,12 @@ public:
|
||||
Firebird::ExternalEngineFactory* getExternalEngineFactory();
|
||||
|
||||
private:
|
||||
Firebird::string name;
|
||||
Firebird::PathName name;
|
||||
Firebird::PathName filename;
|
||||
Firebird::SortedObjectsArray<
|
||||
ConfigEntry,
|
||||
Firebird::EmptyStorage<ConfigEntry*>,
|
||||
Firebird::string, Firebird::FirstPointerKey<ConfigEntry>
|
||||
Firebird::PathName, Firebird::FirstPointerKey<ConfigEntry>
|
||||
> configInfo;
|
||||
Firebird::AutoPtr<ModuleLoader::Module> module;
|
||||
Firebird::ExternalEngineFactory* externalEngineFactory;
|
||||
@ -83,7 +83,7 @@ class PluginManager
|
||||
public:
|
||||
static void initialize();
|
||||
static Firebird::PathName getPluginsDirectory();
|
||||
static PluginImpl* getPlugin(const Firebird::string& name);
|
||||
static PluginImpl* getPlugin(const Firebird::PathName& name);
|
||||
};
|
||||
|
||||
|
||||
|
@ -31,10 +31,10 @@ const char* const SCRATCH = "fb_recbuf_";
|
||||
|
||||
using namespace Jrd;
|
||||
|
||||
RecordBuffer::RecordBuffer(MemoryPool& pool, const Format* format)
|
||||
RecordBuffer::RecordBuffer(MemoryPool& pool, const Format* format, Firebird::RefPtr<Config> conf)
|
||||
: length(format->fmt_length), count(0), filled(false)
|
||||
{
|
||||
space = FB_NEW(pool) TempSpace(pool, SCRATCH);
|
||||
space = FB_NEW(pool) TempSpace(pool, SCRATCH, conf);
|
||||
|
||||
record = FB_NEW_RPT(pool, length) Record(pool);
|
||||
record->rec_format = format;
|
||||
|
@ -31,7 +31,7 @@ namespace Jrd {
|
||||
class RecordBuffer
|
||||
{
|
||||
public:
|
||||
RecordBuffer(MemoryPool&, const Format*);
|
||||
RecordBuffer(MemoryPool&, const Format*, Firebird::RefPtr<Config> conf);
|
||||
~RecordBuffer();
|
||||
|
||||
size_t getCount() const
|
||||
|
@ -137,8 +137,8 @@ size_t TempSpace::FileBlock::write(offset_t offset, const void* buffer, size_t l
|
||||
// Constructor
|
||||
//
|
||||
|
||||
TempSpace::TempSpace(MemoryPool& p, const Firebird::PathName& prefix)
|
||||
: pool(p), filePrefix(p, prefix),
|
||||
TempSpace::TempSpace(MemoryPool& p, const Firebird::PathName& prefix, Firebird::RefPtr<Config> conf)
|
||||
: pool(p), filePrefix(p, prefix), config(conf),
|
||||
logicalSize(0), physicalSize(0), localCacheUsage(0),
|
||||
head(NULL), tail(NULL), tempFiles(p),
|
||||
freeSegments(NULL), notUsedSegments(NULL)
|
||||
@ -150,7 +150,7 @@ TempSpace::TempSpace(MemoryPool& p, const Firebird::PathName& prefix)
|
||||
{
|
||||
MemoryPool& def_pool = *getDefaultMemoryPool();
|
||||
tempDirs = FB_NEW(def_pool) Firebird::TempDirectoryList(def_pool);
|
||||
minBlockSize = Config::getTempBlockSize();
|
||||
minBlockSize = config->getTempBlockSize();
|
||||
|
||||
if (minBlockSize < MIN_TEMP_BLOCK_SIZE)
|
||||
minBlockSize = MIN_TEMP_BLOCK_SIZE;
|
||||
@ -284,7 +284,7 @@ void TempSpace::extend(size_t size)
|
||||
|
||||
Block* block = NULL;
|
||||
|
||||
if (globalCacheUsage + size <= size_t(Config::getTempCacheLimit()))
|
||||
if (globalCacheUsage + size <= size_t(config->getTempCacheLimit()))
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -29,11 +29,12 @@
|
||||
#include "../common/classes/TempFile.h"
|
||||
#include "../common/config/dir_list.h"
|
||||
#include "../common/classes/init.h"
|
||||
#include "../common/config/config.h"
|
||||
|
||||
class TempSpace : public Firebird::File
|
||||
{
|
||||
public:
|
||||
TempSpace(MemoryPool& pool, const Firebird::PathName& prefix);
|
||||
TempSpace(MemoryPool& pool, const Firebird::PathName& prefix, Firebird::RefPtr<Config> conf);
|
||||
virtual ~TempSpace();
|
||||
|
||||
size_t read(offset_t offset, void* buffer, size_t length);
|
||||
@ -163,6 +164,7 @@ private:
|
||||
|
||||
MemoryPool& pool;
|
||||
Firebird::PathName filePrefix;
|
||||
Firebird::RefPtr<Config> config;
|
||||
offset_t logicalSize;
|
||||
offset_t physicalSize;
|
||||
offset_t localCacheUsage;
|
||||
|
@ -1221,8 +1221,8 @@ void CCH_flush(thread_db* tdbb, USHORT flush_flag, SLONG tra_number)
|
||||
//
|
||||
// Check if flush needed
|
||||
//
|
||||
const int max_unflushed_writes = Config::getMaxUnflushedWrites();
|
||||
const time_t max_unflushed_write_time = Config::getMaxUnflushedWriteTime();
|
||||
const int max_unflushed_writes = dbb->dbb_config->getMaxUnflushedWrites();
|
||||
const time_t max_unflushed_write_time = dbb->dbb_config->getMaxUnflushedWriteTime();
|
||||
bool max_num = (max_unflushed_writes >= 0);
|
||||
bool max_time = (max_unflushed_write_time >= 0);
|
||||
|
||||
|
@ -24,10 +24,16 @@
|
||||
#include "../common/classes/init.h"
|
||||
#include "../common/config/config.h"
|
||||
#include "../common/config/config_file.h"
|
||||
#include "../common/config/ConfigCache.h"
|
||||
#include "../common/config/dir_list.h"
|
||||
#include "../jrd/os/path_utils.h"
|
||||
#include "../jrd/gds_proto.h"
|
||||
#include "../jrd/isc_proto.h"
|
||||
#include "../jrd/Database.h"
|
||||
#include "../common/utils_proto.h"
|
||||
#include "../common/classes/Hash.h"
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
using namespace Firebird;
|
||||
|
||||
@ -63,50 +69,254 @@ namespace
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct PathHash
|
||||
{
|
||||
static const PathName& generate(const void* /*sender*/, const T& item)
|
||||
{
|
||||
return item.name;
|
||||
}
|
||||
|
||||
static size_t hash(const PathName& value, size_t hashSize)
|
||||
{
|
||||
return hash(value.c_str(), value.length(), hashSize);
|
||||
}
|
||||
|
||||
static void upcpy(size_t* toPar, const char* from, size_t length)
|
||||
{
|
||||
char* to = reinterpret_cast<char*>(toPar);
|
||||
while (length--)
|
||||
{
|
||||
if (CASE_SENSITIVITY)
|
||||
{
|
||||
*to++ = *from++;
|
||||
}
|
||||
else
|
||||
{
|
||||
*to++ = toupper(*from++);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static size_t hash(const char* value, size_t length, size_t hashSize)
|
||||
{
|
||||
size_t sum = 0;
|
||||
size_t val;
|
||||
|
||||
while (length >= sizeof(size_t))
|
||||
{
|
||||
upcpy(&val, value, sizeof(size_t));
|
||||
sum += val;
|
||||
value += sizeof(size_t);
|
||||
length -= sizeof(size_t);
|
||||
}
|
||||
|
||||
if (length)
|
||||
{
|
||||
val = 0;
|
||||
upcpy(&val, value, length);
|
||||
sum += val;
|
||||
}
|
||||
|
||||
size_t rc = 0;
|
||||
while (sum)
|
||||
{
|
||||
rc += (sum % hashSize);
|
||||
sum /= hashSize;
|
||||
}
|
||||
|
||||
return rc % hashSize;
|
||||
}
|
||||
};
|
||||
|
||||
struct DbName;
|
||||
typedef Hash<DbName, 127, PathName, PathHash<DbName>, PathHash<DbName> > DbHash;
|
||||
struct DbName : public DbHash::Entry
|
||||
{
|
||||
DbName(MemoryPool& p, const PathName& db)
|
||||
: name(p, db) { }
|
||||
|
||||
DbName* get()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
bool isEqual(const PathName& val) const
|
||||
{
|
||||
return val == name;
|
||||
}
|
||||
|
||||
PathName name;
|
||||
RefPtr<Config> config;
|
||||
};
|
||||
|
||||
struct AliasName;
|
||||
typedef Hash<AliasName, 251, PathName, PathHash<AliasName>, PathHash<AliasName> > AliasHash;
|
||||
struct AliasName : public AliasHash::Entry
|
||||
{
|
||||
AliasName(MemoryPool& p, const PathName& al, DbName* db)
|
||||
: name(p, al), database(db) { }
|
||||
|
||||
AliasName* get()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
bool isEqual(const PathName& val) const
|
||||
{
|
||||
return val == name;
|
||||
}
|
||||
|
||||
PathName name;
|
||||
DbName* database;
|
||||
};
|
||||
|
||||
class AliasesConf : public ConfigCache
|
||||
{
|
||||
public:
|
||||
explicit AliasesConf(MemoryPool& p)
|
||||
: ConfigCache(p, fb_utils::getPrefix(fb_utils::FB_DIR_CONF, ALIAS_FILE)),
|
||||
databases(getPool()), aliases(getPool())
|
||||
{ }
|
||||
|
||||
void loadConfig()
|
||||
{
|
||||
size_t n;
|
||||
|
||||
// clean old data
|
||||
for (n = 0; n < aliases.getCount(); ++n)
|
||||
{
|
||||
delete aliases[n];
|
||||
}
|
||||
aliases.clear();
|
||||
for (n = 0; n < databases.getCount(); ++n)
|
||||
{
|
||||
delete databases[n];
|
||||
}
|
||||
databases.clear();
|
||||
|
||||
ConfigFile aliasConfig(fileName, ConfigFile::HAS_SUB_CONF);
|
||||
const ConfigFile::Parameters& params = aliasConfig.getParameters();
|
||||
|
||||
for (n = 0; n < params.getCount(); ++n)
|
||||
{
|
||||
const ConfigFile::Parameter* par = ¶ms[n];
|
||||
|
||||
PathName file(par->value);
|
||||
replace_dir_sep(file);
|
||||
if (PathUtils::isRelative(file))
|
||||
{
|
||||
gds__log("Value %s configured for alias %s "
|
||||
"is not a fully qualified path name, ignored",
|
||||
file.c_str(), par->name.c_str());
|
||||
continue;
|
||||
}
|
||||
DbName* db = dbHash.lookup(file);
|
||||
if (! db)
|
||||
{
|
||||
db = FB_NEW(getPool()) DbName(getPool(), file);
|
||||
databases.add(db);
|
||||
dbHash.add(db);
|
||||
}
|
||||
else
|
||||
{
|
||||
// check for duplicated config
|
||||
if (par->sub && db->config.hasData())
|
||||
{
|
||||
fatal_exception::raiseFmt("Duplicated configuration for database %s\n",
|
||||
file.c_str());
|
||||
}
|
||||
}
|
||||
if (par->sub)
|
||||
{
|
||||
// load per-database configuration
|
||||
db->config = new Config(*par->sub, *Config::getDefaultConfig());
|
||||
}
|
||||
|
||||
PathName correctedAlias(par->name);
|
||||
AliasName* alias = aliasHash.lookup(correctedAlias);
|
||||
if (alias)
|
||||
{
|
||||
fatal_exception::raiseFmt("Duplicated alias %s\n", correctedAlias.c_str());
|
||||
}
|
||||
alias = FB_NEW(getPool()) AliasName(getPool(), correctedAlias, db);
|
||||
aliases.add(alias);
|
||||
aliasHash.add(alias);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
HalfStaticArray<DbName*, 100> databases;
|
||||
HalfStaticArray<AliasName*, 200> aliases;
|
||||
|
||||
public:
|
||||
DbHash dbHash;
|
||||
AliasHash aliasHash;
|
||||
};
|
||||
|
||||
InitInstance<AliasesConf> aliasesConf;
|
||||
}
|
||||
|
||||
bool ResolveDatabaseAlias(const PathName& alias, PathName& database)
|
||||
bool ResolveDatabaseAlias(const PathName& alias, PathName& file, RefPtr<Config>* config)
|
||||
{
|
||||
PathName alias_filename = fb_utils::getPrefix(fb_utils::FB_DIR_CONF, ALIAS_FILE);
|
||||
ConfigFile aliasConfig(false, true);
|
||||
aliasConfig.setConfigFilePath(alias_filename);
|
||||
try
|
||||
{
|
||||
aliasesConf().checkLoadConfig();
|
||||
}
|
||||
catch (const fatal_exception& ex)
|
||||
{
|
||||
gds__log("File aliases.conf contains bad data: %s", ex.what());
|
||||
(Arg::Gds(isc_random) << "Server misconfigured - contact administrator please").raise();
|
||||
}
|
||||
|
||||
ReadLockGuard guard(aliasesConf().rwLock);
|
||||
|
||||
PathName corrected_alias = alias;
|
||||
replace_dir_sep(corrected_alias);
|
||||
|
||||
database = aliasConfig.getString(corrected_alias);
|
||||
|
||||
if (!database.empty())
|
||||
bool rc = true;
|
||||
AliasName* a = aliasesConf().aliasHash.lookup(corrected_alias);
|
||||
DbName* db = a ? a->database : NULL;
|
||||
if (db)
|
||||
{
|
||||
replace_dir_sep(database);
|
||||
if (PathUtils::isRelative(database))
|
||||
file = db->name;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If file_name has no path part, expand it in DatabasesPath
|
||||
PathName path, name;
|
||||
PathUtils::splitLastComponent(path, name, corrected_alias);
|
||||
|
||||
// if path component not present in file_name
|
||||
if (path.isEmpty())
|
||||
{
|
||||
gds__log("Value %s configured for alias %s "
|
||||
"is not a fully qualified path name, ignored",
|
||||
database.c_str(), alias.c_str());
|
||||
return false;
|
||||
// try to expand to existing file
|
||||
if (!databaseDirectoryList().expandFileName(file, name))
|
||||
{
|
||||
// try to use default path
|
||||
if (!databaseDirectoryList().defaultName(file, name))
|
||||
{
|
||||
rc = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
else
|
||||
{
|
||||
rc = false;
|
||||
}
|
||||
|
||||
if (! rc)
|
||||
{
|
||||
file = corrected_alias;
|
||||
}
|
||||
db = aliasesConf().dbHash.lookup(file);
|
||||
}
|
||||
|
||||
// If file_name has no path part, expand it in DatabasesPath
|
||||
Firebird::PathName path, name;
|
||||
PathUtils::splitLastComponent(path, name, corrected_alias);
|
||||
|
||||
// if path component not present in file_name
|
||||
if (path.isEmpty())
|
||||
if (config)
|
||||
{
|
||||
// try to expand to existing file
|
||||
if (databaseDirectoryList().expandFileName(database, name))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
// try to use default path
|
||||
if (databaseDirectoryList().defaultName(database, name))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
*config = (db && db->config.hasData()) ? db->config : Config::getDefaultConfig();
|
||||
}
|
||||
|
||||
return false;
|
||||
return rc;
|
||||
}
|
||||
|
@ -24,6 +24,11 @@
|
||||
#define JRD_DB_ALIAS_H
|
||||
|
||||
#include "../common/classes/fb_string.h"
|
||||
#include "../common/classes/RefCounted.h"
|
||||
|
||||
bool ResolveDatabaseAlias(const Firebird::PathName& alias, Firebird::PathName& database);
|
||||
class Config;
|
||||
|
||||
bool ResolveDatabaseAlias(const Firebird::PathName& alias,
|
||||
Firebird::PathName& file,
|
||||
Firebird::RefPtr<Config>* config);
|
||||
#endif // JRD_DB_ALIAS_H
|
||||
|
@ -85,7 +85,7 @@ void EventManager::init(Database* dbb)
|
||||
EventManager* eventMgr = NULL;
|
||||
if (!g_emMap->get(id, eventMgr))
|
||||
{
|
||||
eventMgr = new EventManager(id);
|
||||
eventMgr = new EventManager(id, dbb->dbb_config);
|
||||
}
|
||||
|
||||
fb_assert(eventMgr);
|
||||
@ -95,12 +95,13 @@ void EventManager::init(Database* dbb)
|
||||
}
|
||||
|
||||
|
||||
EventManager::EventManager(const Firebird::string& id)
|
||||
EventManager::EventManager(const Firebird::string& id, Firebird::RefPtr<Config> conf)
|
||||
: PID(getpid()),
|
||||
m_header(NULL),
|
||||
m_process(NULL),
|
||||
m_processOffset(0),
|
||||
m_dbId(getPool(), id),
|
||||
m_config(conf),
|
||||
m_sharedFileCreated(false),
|
||||
m_exiting(false)
|
||||
{
|
||||
@ -170,7 +171,7 @@ void EventManager::attach_shared_file()
|
||||
if (!(m_header = (evh*) ISC_map_file(localStatus,
|
||||
name.c_str(),
|
||||
init_shmem, this,
|
||||
Config::getEventMemSize(),
|
||||
m_config->getEventMemSize(),
|
||||
&m_shmemData)))
|
||||
{
|
||||
localStatus.raise();
|
||||
@ -618,7 +619,7 @@ frb* EventManager::alloc_global(UCHAR type, ULONG length, bool recurse)
|
||||
if (!best && !recurse)
|
||||
{
|
||||
const ULONG old_length = m_shmemData.sh_mem_length_mapped;
|
||||
const ULONG ev_length = old_length + Config::getEventMemSize();
|
||||
const ULONG ev_length = old_length + m_config->getEventMemSize();
|
||||
|
||||
evh* header = NULL;
|
||||
|
||||
|
@ -31,6 +31,8 @@
|
||||
#include "../jrd/ThreadData.h"
|
||||
#include "../jrd/event.h"
|
||||
|
||||
class Config;
|
||||
|
||||
namespace Jrd {
|
||||
|
||||
class Database;
|
||||
@ -47,7 +49,7 @@ class EventManager : public Firebird::RefCounted, public Firebird::GlobalStorage
|
||||
public:
|
||||
static void init(Database*);
|
||||
|
||||
explicit EventManager(const Firebird::string&);
|
||||
EventManager(const Firebird::string& id, Firebird::RefPtr<Config> conf);
|
||||
~EventManager();
|
||||
|
||||
SLONG createSession();
|
||||
@ -108,6 +110,7 @@ private:
|
||||
sh_mem m_shmemData;
|
||||
|
||||
Firebird::string m_dbId;
|
||||
Firebird::RefPtr<Config> m_config;
|
||||
|
||||
Firebird::Semaphore m_startupSemaphore;
|
||||
Firebird::Semaphore m_cleanupSemaphore;
|
||||
|
@ -74,9 +74,36 @@ __int64 __cdecl _ftelli64(FILE*);
|
||||
#define FSEEK64 fseeko
|
||||
#endif
|
||||
|
||||
using namespace Jrd;
|
||||
using namespace Firebird;
|
||||
|
||||
namespace Jrd {
|
||||
class ExternalFileDirectoryList : public Firebird::DirectoryList
|
||||
{
|
||||
private:
|
||||
const Firebird::PathName getConfigString() const
|
||||
{
|
||||
return Firebird::PathName(config->getExternalFileAccess());
|
||||
}
|
||||
public:
|
||||
ExternalFileDirectoryList(const Database* dbb)
|
||||
: DirectoryList(*dbb->dbb_permanent), config(dbb->dbb_config)
|
||||
{
|
||||
initialize();
|
||||
}
|
||||
static void create(Database* dbb)
|
||||
{
|
||||
if (!dbb->dbb_external_file_directory_list)
|
||||
{
|
||||
dbb->dbb_external_file_directory_list =
|
||||
FB_NEW(*dbb->dbb_permanent) ExternalFileDirectoryList(dbb);
|
||||
}
|
||||
}
|
||||
private:
|
||||
Firebird::RefPtr<Config> config;
|
||||
};
|
||||
}
|
||||
|
||||
using namespace Jrd;
|
||||
|
||||
namespace {
|
||||
|
||||
@ -87,29 +114,12 @@ namespace {
|
||||
#endif
|
||||
static const char* const FOPEN_READ_ONLY = "rb";
|
||||
|
||||
FILE *ext_fopen(Database* dbb, ExternalFile* ext_file);
|
||||
|
||||
class ExternalFileDirectoryList : public Firebird::DirectoryList
|
||||
{
|
||||
private:
|
||||
const Firebird::PathName getConfigString() const
|
||||
{
|
||||
return Firebird::PathName(Config::getExternalFileAccess());
|
||||
}
|
||||
public:
|
||||
explicit ExternalFileDirectoryList(MemoryPool& p)
|
||||
: DirectoryList(p)
|
||||
{
|
||||
initialize();
|
||||
}
|
||||
};
|
||||
Firebird::InitInstance<ExternalFileDirectoryList> iExternalFileDirectoryList;
|
||||
|
||||
FILE *ext_fopen(Database* dbb, ExternalFile* ext_file)
|
||||
{
|
||||
const char* file_name = ext_file->ext_filename;
|
||||
|
||||
if (!iExternalFileDirectoryList().isPathInList(file_name))
|
||||
ExternalFileDirectoryList::create(dbb);
|
||||
if (!dbb->dbb_external_file_directory_list->isPathInList(file_name))
|
||||
{
|
||||
ERR_post(Arg::Gds(isc_conf_access_denied) << Arg::Str("external file") <<
|
||||
Arg::Str(file_name));
|
||||
@ -190,9 +200,10 @@ ExternalFile* EXT_file(jrd_rel* relation, const TEXT* file_name) //, bid* descri
|
||||
if (Path.length() == 0)
|
||||
{
|
||||
// path component not present in file_name
|
||||
if (!(iExternalFileDirectoryList().expandFileName(Path, Name)))
|
||||
ExternalFileDirectoryList::create(dbb);
|
||||
if (!(dbb->dbb_external_file_directory_list->expandFileName(Path, Name)))
|
||||
{
|
||||
iExternalFileDirectoryList().defaultName(Path, Name);
|
||||
dbb->dbb_external_file_directory_list->defaultName(Path, Name);
|
||||
}
|
||||
file_name = Path.c_str();
|
||||
}
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "../common/config/config.h"
|
||||
#include "../jrd/os/path_utils.h"
|
||||
#include "../jrd/common.h"
|
||||
#include "../jrd/jrd.h"
|
||||
#include "../jrd/val.h"
|
||||
|
@ -486,8 +486,22 @@ public:
|
||||
memset(this, 0,
|
||||
reinterpret_cast<char*>(&this->dpb_sys_user_name) - reinterpret_cast<char*>(this));
|
||||
}
|
||||
|
||||
void get(const UCHAR*, USHORT, bool&);
|
||||
|
||||
void setBuffers(Firebird::RefPtr<Config> config)
|
||||
{
|
||||
if (dpb_buffers == 0)
|
||||
{
|
||||
dpb_buffers = config->getDefaultDbCachePages();
|
||||
|
||||
if (dpb_buffers < MIN_PAGE_BUFFERS)
|
||||
dpb_buffers = MIN_PAGE_BUFFERS;
|
||||
if (dpb_buffers > MAX_PAGE_BUFFERS)
|
||||
dpb_buffers = MAX_PAGE_BUFFERS;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void getPath(ClumpletReader& reader, PathName& s)
|
||||
{
|
||||
@ -561,7 +575,7 @@ static ISC_STATUS unwindAttach(thread_db* tdbb, const Exception& ex, ISC_STATUS*
|
||||
static void ExtractDriveLetter(const TEXT*, ULONG*);
|
||||
#endif
|
||||
|
||||
static Database* init(thread_db*, const PathName&, bool);
|
||||
static Database* init(thread_db*, const PathName&, Firebird::RefPtr<Config>, bool);
|
||||
static void prepare(thread_db*, jrd_tra*, USHORT, const UCHAR*);
|
||||
static void start_multiple(thread_db* tdbb, bool transliterate, jrd_tra** tra_handle,
|
||||
USHORT count, TEB* vector, FB_API_HANDLE public_handle = 0);
|
||||
@ -902,6 +916,7 @@ ISC_STATUS GDS_ATTACH_DATABASE(ISC_STATUS* user_status,
|
||||
|
||||
UserId userId;
|
||||
DatabaseOptions options;
|
||||
Firebird::RefPtr<Config> config;
|
||||
bool invalid_client_SQL_dialect = false;
|
||||
PathName file_name, expanded_name;
|
||||
bool is_alias = false;
|
||||
@ -926,7 +941,7 @@ ISC_STATUS GDS_ATTACH_DATABASE(ISC_STATUS* user_status,
|
||||
ISC_utf8ToSystem(file_name);
|
||||
|
||||
// Resolve given alias name
|
||||
is_alias = ResolveDatabaseAlias(file_name, expanded_name);
|
||||
is_alias = ResolveDatabaseAlias(file_name, expanded_name, &config);
|
||||
if (is_alias)
|
||||
{
|
||||
ISC_systemToUtf8(expanded_name);
|
||||
@ -975,7 +990,7 @@ ISC_STATUS GDS_ATTACH_DATABASE(ISC_STATUS* user_status,
|
||||
try
|
||||
{
|
||||
// Unless we're already attached, do some initialization
|
||||
dbb = init(tdbb, expanded_name, true);
|
||||
dbb = init(tdbb, expanded_name, config, true);
|
||||
}
|
||||
catch (const Exception& ex)
|
||||
{
|
||||
@ -1096,7 +1111,7 @@ ISC_STATUS GDS_ATTACH_DATABASE(ISC_STATUS* user_status,
|
||||
pageSpace->file = PIO_open(dbb, expanded_name, file_name, false);
|
||||
|
||||
// Initialize the lock manager
|
||||
dbb->dbb_lock_mgr = LockManager::create(dbb->getUniqueFileId());
|
||||
dbb->dbb_lock_mgr = LockManager::create(dbb->getUniqueFileId(), dbb->dbb_config);
|
||||
|
||||
LCK_init(tdbb, LCK_OWNER_database);
|
||||
dbb->dbb_flags |= DBB_lck_init_done;
|
||||
@ -1124,6 +1139,7 @@ ISC_STATUS GDS_ATTACH_DATABASE(ISC_STATUS* user_status,
|
||||
dbb->dbb_page_buffers = options.dpb_page_buffers;
|
||||
}
|
||||
|
||||
options.setBuffers(dbb->dbb_config);
|
||||
CCH_init(tdbb, options.dpb_buffers);
|
||||
|
||||
// Initialize backup difference subsystem. This must be done before WAL and shadowing
|
||||
@ -1980,6 +1996,7 @@ ISC_STATUS GDS_CREATE_DATABASE(ISC_STATUS* user_status,
|
||||
DatabaseOptions options;
|
||||
PathName file_name, expanded_name;
|
||||
bool is_alias = false;
|
||||
Firebird::RefPtr<Config> config;
|
||||
|
||||
try
|
||||
{
|
||||
@ -2005,7 +2022,7 @@ ISC_STATUS GDS_CREATE_DATABASE(ISC_STATUS* user_status,
|
||||
ISC_utf8ToSystem(file_name);
|
||||
|
||||
// Resolve given alias name
|
||||
is_alias = ResolveDatabaseAlias(file_name, expanded_name);
|
||||
is_alias = ResolveDatabaseAlias(file_name, expanded_name, &config);
|
||||
if (is_alias)
|
||||
{
|
||||
ISC_systemToUtf8(expanded_name);
|
||||
@ -2054,7 +2071,7 @@ ISC_STATUS GDS_CREATE_DATABASE(ISC_STATUS* user_status,
|
||||
|
||||
try
|
||||
{
|
||||
dbb = init(tdbb, expanded_name, false);
|
||||
dbb = init(tdbb, expanded_name, config, false);
|
||||
}
|
||||
catch (const Exception& ex)
|
||||
{
|
||||
@ -2188,7 +2205,7 @@ ISC_STATUS GDS_CREATE_DATABASE(ISC_STATUS* user_status,
|
||||
const jrd_file* const first_dbb_file = pageSpace->file;
|
||||
|
||||
// Initialize the lock manager
|
||||
dbb->dbb_lock_mgr = LockManager::create(dbb->getUniqueFileId());
|
||||
dbb->dbb_lock_mgr = LockManager::create(dbb->getUniqueFileId(), dbb->dbb_config);
|
||||
|
||||
LCK_init(tdbb, LCK_OWNER_database);
|
||||
dbb->dbb_flags |= DBB_lck_init_done;
|
||||
@ -2208,14 +2225,15 @@ ISC_STATUS GDS_CREATE_DATABASE(ISC_STATUS* user_status,
|
||||
if (options.dpb_set_page_buffers)
|
||||
dbb->dbb_page_buffers = options.dpb_page_buffers;
|
||||
|
||||
CCH_init(tdbb, options.dpb_buffers);
|
||||
|
||||
#ifdef WIN_NT
|
||||
dbb->dbb_filename.assign(first_dbb_file->fil_string);
|
||||
#else
|
||||
dbb->dbb_filename = expanded_name;
|
||||
#endif
|
||||
|
||||
options.setBuffers(dbb->dbb_config);
|
||||
CCH_init(tdbb, options.dpb_buffers);
|
||||
|
||||
// NS: Use alias as database ID only if accessing database using file name is not possible.
|
||||
//
|
||||
// This way we:
|
||||
@ -4740,13 +4758,7 @@ void DatabaseOptions::get(const UCHAR* dpb, USHORT dpb_length, bool& invalid_cli
|
||||
**************************************/
|
||||
SSHORT num_old_files = 0;
|
||||
|
||||
ULONG page_cache_size = Config::getDefaultDbCachePages();
|
||||
if (page_cache_size < MIN_PAGE_BUFFERS)
|
||||
page_cache_size = MIN_PAGE_BUFFERS;
|
||||
if (page_cache_size > MAX_PAGE_BUFFERS)
|
||||
page_cache_size = MAX_PAGE_BUFFERS;
|
||||
|
||||
dpb_buffers = page_cache_size;
|
||||
dpb_buffers = 0;
|
||||
dpb_sweep_interval = -1;
|
||||
dpb_overwrite = false;
|
||||
dpb_sql_dialect = 99;
|
||||
@ -5114,6 +5126,7 @@ static ISC_STATUS handle_error(ISC_STATUS* user_status, ISC_STATUS code)
|
||||
|
||||
static Database* init(thread_db* tdbb,
|
||||
const PathName& expanded_filename, // only for SS
|
||||
Firebird::RefPtr<Config> config,
|
||||
bool attach_flag) // only for SS
|
||||
{
|
||||
/**************************************
|
||||
@ -5163,6 +5176,7 @@ static Database* init(thread_db* tdbb,
|
||||
#endif
|
||||
|
||||
dbb = Database::create();
|
||||
dbb->dbb_config = config;
|
||||
tdbb->setDatabase(dbb);
|
||||
|
||||
dbb->dbb_bufferpool = dbb->createPool();
|
||||
@ -5182,7 +5196,7 @@ static Database* init(thread_db* tdbb,
|
||||
|
||||
if ((dbb->dbb_flags & (DBB_gc_cooperative | DBB_gc_background)) == 0)
|
||||
{
|
||||
string gc_policy = Config::getGCPolicy();
|
||||
string gc_policy = dbb->dbb_config->getGCPolicy();
|
||||
gc_policy.lower();
|
||||
if (gc_policy == GCPolicyCooperative) {
|
||||
dbb->dbb_flags |= DBB_gc_cooperative;
|
||||
|
@ -94,8 +94,6 @@ public:
|
||||
config_file = root_dir + string(CONFIG_FILE);
|
||||
}
|
||||
|
||||
virtual ~ConfigRoot() {}
|
||||
|
||||
const char* getInstallDirectory()
|
||||
{
|
||||
return install_dir.c_str();
|
||||
|
@ -1071,7 +1071,8 @@ void PAG_header(thread_db* tdbb, bool info)
|
||||
Arg::Str(attachment->att_filename));
|
||||
}
|
||||
|
||||
const bool useFSCache = dbb->dbb_bcb->bcb_count < ULONG(Config::getFileSystemCacheThreshold());
|
||||
const bool useFSCache = dbb->dbb_bcb->bcb_count <
|
||||
ULONG(dbb->dbb_config->getFileSystemCacheThreshold());
|
||||
|
||||
if ((header->hdr_flags & hdr_force_write) || !useFSCache)
|
||||
{
|
||||
@ -2046,13 +2047,13 @@ bool PageSpace::extend(thread_db* tdbb, const ULONG pageNum)
|
||||
* extend file(s)
|
||||
*
|
||||
**************************************/
|
||||
const int MAX_EXTEND_BYTES = Config::getDatabaseGrowthIncrement();
|
||||
fb_assert(dbb == tdbb->getDatabase())
|
||||
|
||||
const int MAX_EXTEND_BYTES = dbb->dbb_config->getDatabaseGrowthIncrement();
|
||||
|
||||
if (pageNum < maxPageNumber || MAX_EXTEND_BYTES < MIN_EXTEND_BYTES)
|
||||
return true;
|
||||
|
||||
fb_assert(dbb == tdbb->getDatabase())
|
||||
|
||||
if (pageNum >= maxAlloc())
|
||||
{
|
||||
const ULONG minExtendPages = MIN_EXTEND_BYTES / dbb->dbb_page_size;
|
||||
|
@ -117,7 +117,8 @@ void BufferedStream::open(thread_db* tdbb)
|
||||
|
||||
delete impure->irsb_buffer;
|
||||
MemoryPool& pool = *tdbb->getDefaultPool();
|
||||
impure->irsb_buffer = FB_NEW(pool) RecordBuffer(pool, m_format);
|
||||
impure->irsb_buffer = FB_NEW(pool) RecordBuffer(pool, m_format,
|
||||
tdbb->getDatabase()->dbb_config);
|
||||
|
||||
impure->irsb_position = 0;
|
||||
}
|
||||
|
@ -297,7 +297,8 @@ bool MergeJoin::getRecord(thread_db* tdbb)
|
||||
if (!mfb->mfb_space)
|
||||
{
|
||||
MemoryPool& pool = *getDefaultMemoryPool();
|
||||
mfb->mfb_space = FB_NEW(pool) TempSpace(pool, SCRATCH);
|
||||
mfb->mfb_space = FB_NEW(pool) TempSpace(pool, SCRATCH,
|
||||
tdbb->getDatabase()->dbb_config);
|
||||
}
|
||||
|
||||
SORT_write_block(mfb->mfb_space, mfb->mfb_block_size * mfb->mfb_current_block,
|
||||
@ -509,7 +510,8 @@ SLONG MergeJoin::getRecord(thread_db* tdbb, size_t index)
|
||||
if (!mfb->mfb_space)
|
||||
{
|
||||
MemoryPool& pool = *getDefaultMemoryPool();
|
||||
mfb->mfb_space = FB_NEW(pool) TempSpace(pool, SCRATCH);
|
||||
mfb->mfb_space = FB_NEW(pool) TempSpace(pool, SCRATCH,
|
||||
tdbb->getDatabase()->dbb_config);
|
||||
}
|
||||
|
||||
SORT_write_block(mfb->mfb_space, mfb->mfb_block_size * mfb->mfb_current_block,
|
||||
|
@ -382,7 +382,7 @@ sort_context* SORT_init(Database* dbb,
|
||||
|
||||
// Set up the temp space
|
||||
|
||||
scb->scb_space = FB_NEW(pool) TempSpace(pool, SCRATCH);
|
||||
scb->scb_space = FB_NEW(pool) TempSpace(pool, SCRATCH, dbb->dbb_config);
|
||||
|
||||
// Set up to receive the first record
|
||||
|
||||
|
@ -282,7 +282,7 @@ public:
|
||||
return tra_outer->getBlobSpace();
|
||||
|
||||
if (!tra_blob_space)
|
||||
tra_blob_space = FB_NEW(*tra_pool) TempSpace(*tra_pool, TRA_BLOB_SPACE);
|
||||
tra_blob_space = FB_NEW(*tra_pool) TempSpace(*tra_pool, TRA_BLOB_SPACE, tra_attachment->att_database->dbb_config);
|
||||
|
||||
return tra_blob_space;
|
||||
}
|
||||
@ -290,7 +290,7 @@ public:
|
||||
TempSpace* getUndoSpace()
|
||||
{
|
||||
if (!tra_undo_space)
|
||||
tra_undo_space = FB_NEW(*tra_pool) TempSpace(*tra_pool, TRA_UNDO_SPACE);
|
||||
tra_undo_space = FB_NEW(*tra_pool) TempSpace(*tra_pool, TRA_UNDO_SPACE, tra_attachment->att_database->dbb_config);
|
||||
|
||||
return tra_undo_space;
|
||||
}
|
||||
|
@ -165,14 +165,14 @@ Firebird::GlobalPtr<LockManager::DbLockMgrMap> LockManager::g_lmMap;
|
||||
Firebird::GlobalPtr<Firebird::Mutex> LockManager::g_mapMutex;
|
||||
|
||||
|
||||
LockManager* LockManager::create(const Firebird::string& id)
|
||||
LockManager* LockManager::create(const Firebird::string& id, Firebird::RefPtr<Config> conf)
|
||||
{
|
||||
Firebird::MutexLockGuard guard(g_mapMutex);
|
||||
|
||||
LockManager* lockMgr = NULL;
|
||||
if (!g_lmMap->get(id, lockMgr))
|
||||
{
|
||||
lockMgr = new LockManager(id);
|
||||
lockMgr = new LockManager(id, conf);
|
||||
}
|
||||
|
||||
fb_assert(lockMgr);
|
||||
@ -181,7 +181,7 @@ LockManager* LockManager::create(const Firebird::string& id)
|
||||
}
|
||||
|
||||
|
||||
LockManager::LockManager(const Firebird::string& id)
|
||||
LockManager::LockManager(const Firebird::string& id, Firebird::RefPtr<Config> conf)
|
||||
: PID(getpid()),
|
||||
m_bugcheck(false),
|
||||
m_sharedFileCreated(false),
|
||||
@ -189,8 +189,9 @@ LockManager::LockManager(const Firebird::string& id)
|
||||
m_process(NULL),
|
||||
m_processOffset(0),
|
||||
m_dbId(getPool(), id),
|
||||
m_acquireSpins(Config::getLockAcquireSpins()),
|
||||
m_memorySize(Config::getLockMemSize())
|
||||
m_config(conf),
|
||||
m_acquireSpins(m_config->getLockAcquireSpins()),
|
||||
m_memorySize(m_config->getLockMemSize())
|
||||
#ifdef USE_SHMEM_EXT
|
||||
, m_extents(getPool())
|
||||
#endif
|
||||
@ -2338,14 +2339,14 @@ void LockManager::initialize(sh_mem* shmem_data, bool initializeMemory)
|
||||
}
|
||||
#endif
|
||||
|
||||
int hash_slots = Config::getLockHashSlots();
|
||||
int hash_slots = m_config->getLockHashSlots();
|
||||
if (hash_slots < HASH_MIN_SLOTS)
|
||||
hash_slots = HASH_MIN_SLOTS;
|
||||
if (hash_slots > HASH_MAX_SLOTS)
|
||||
hash_slots = HASH_MAX_SLOTS;
|
||||
|
||||
m_header->lhb_hash_slots = (USHORT) hash_slots;
|
||||
m_header->lhb_scan_interval = Config::getDeadlockTimeout();
|
||||
m_header->lhb_scan_interval = m_config->getDeadlockTimeout();
|
||||
m_header->lhb_acquire_spins = m_acquireSpins;
|
||||
|
||||
// Initialize lock series data queues and lock hash chains
|
||||
@ -2363,7 +2364,7 @@ void LockManager::initialize(sh_mem* shmem_data, bool initializeMemory)
|
||||
|
||||
// Set lock_ordering flag for the first time
|
||||
|
||||
if (Config::getLockGrantOrder())
|
||||
if (m_config->getLockGrantOrder())
|
||||
m_header->lhb_flags |= LHB_lock_ordering;
|
||||
|
||||
const ULONG length = sizeof(lhb) + (m_header->lhb_hash_slots * sizeof(m_header->lhb_hash[0]));
|
||||
|
@ -307,6 +307,8 @@ namespace Firebird {
|
||||
class RWLock;
|
||||
}
|
||||
|
||||
class Config;
|
||||
|
||||
namespace Jrd {
|
||||
|
||||
class Database;
|
||||
@ -321,7 +323,7 @@ class LockManager : public Firebird::RefCounted, public Firebird::GlobalStorage
|
||||
const int PID;
|
||||
|
||||
public:
|
||||
static LockManager* create(const Firebird::string&);
|
||||
static LockManager* create(const Firebird::string&, Firebird::RefPtr<Config>);
|
||||
|
||||
bool initializeOwner(Firebird::Arg::StatusVector&, LOCK_OWNER_T, UCHAR, SRQ_PTR*);
|
||||
void shutdownOwner(Database*, SRQ_PTR*);
|
||||
@ -340,7 +342,7 @@ public:
|
||||
SLONG writeData(SRQ_PTR, SLONG);
|
||||
|
||||
private:
|
||||
explicit LockManager(const Firebird::string&);
|
||||
explicit LockManager(const Firebird::string&, Firebird::RefPtr<Config>);
|
||||
~LockManager();
|
||||
|
||||
bool lockOrdering() const
|
||||
@ -434,6 +436,7 @@ private:
|
||||
Firebird::Semaphore m_startupSemaphore;
|
||||
|
||||
Firebird::string m_dbId;
|
||||
Firebird::RefPtr<Config> m_config;
|
||||
|
||||
const ULONG m_acquireSpins;
|
||||
const ULONG m_memorySize;
|
||||
|
@ -386,7 +386,7 @@ int CLIB_ROUTINE main( int argc, char *argv[])
|
||||
{
|
||||
Firebird::PathName org_name = db_file;
|
||||
Firebird::PathName db_name;
|
||||
if (!ResolveDatabaseAlias(org_name, db_name))
|
||||
if (!ResolveDatabaseAlias(org_name, db_name, NULL))
|
||||
{
|
||||
db_name = org_name;
|
||||
}
|
||||
|
@ -557,7 +557,7 @@ int gstat(Firebird::UtilSvc* uSvc)
|
||||
}
|
||||
}
|
||||
|
||||
if (ResolveDatabaseAlias(fileName, tempStr)) {
|
||||
if (ResolveDatabaseAlias(fileName, tempStr, NULL)) {
|
||||
fileName = tempStr;
|
||||
}
|
||||
|
||||
|
@ -266,7 +266,7 @@ public:
|
||||
if (strncmp(db.c_str(), local_prefix, sizeof(local_prefix) - 1) == 0)
|
||||
db = db.substr(sizeof(local_prefix) - 1);
|
||||
|
||||
if (!ResolveDatabaseAlias(db, dbname))
|
||||
if (!ResolveDatabaseAlias(db, dbname, NULL))
|
||||
dbname = db;
|
||||
}
|
||||
|
||||
|
@ -47,14 +47,14 @@ void TraceCfgReader::readTraceConfiguration(const char* text,
|
||||
|
||||
#define PATH_PARAMETER(NAME, VALUE) \
|
||||
if (!found && el->name == #NAME) { \
|
||||
string temp; \
|
||||
ConfigFile::String temp; \
|
||||
expandPattern(el, temp); \
|
||||
m_config.NAME = temp.c_str(); \
|
||||
found = true; \
|
||||
}
|
||||
#define STR_PARAMETER(NAME, VALUE) \
|
||||
if (!found && el->name == #NAME) { \
|
||||
m_config.NAME = el->getAttributeName(0); \
|
||||
m_config.NAME = el->value; \
|
||||
found = true; \
|
||||
}
|
||||
#define BOOL_PARAMETER(NAME, VALUE) \
|
||||
@ -92,21 +92,8 @@ namespace
|
||||
|
||||
void TraceCfgReader::readConfig()
|
||||
{
|
||||
Firebird::AutoPtr<ConfigFile> cfgFile(new ConfigFile(Lex::LEX_none));
|
||||
cfgFile->addText(m_text);
|
||||
try
|
||||
{
|
||||
cfgFile->parse();
|
||||
}
|
||||
catch (const AdminException& ex)
|
||||
{
|
||||
fatal_exception::raiseFmt("error while parsing trace configuration\n\t%s",
|
||||
ex.getText());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
fatal_exception::raiseFmt("unknown error while parsing trace configuration");
|
||||
}
|
||||
ConfigFile cfgFile(ConfigFile::USE_TEXT, m_text,
|
||||
ConfigFile::HAS_SUB_CONF | ConfigFile::EXCEPTION_ON_ERROR);
|
||||
|
||||
m_subpatterns[0].start = 0;
|
||||
m_subpatterns[0].end = m_databaseName.length();
|
||||
@ -130,14 +117,16 @@ void TraceCfgReader::readConfig()
|
||||
Jrd::TextType textType(0, &tt, charSet);
|
||||
|
||||
bool defDB = false, defSvc = false, exactMatch = false;
|
||||
const Element* section = cfgFile->getObjects()->children;
|
||||
for (; section && !exactMatch; section = section->sibling)
|
||||
const ConfigFile::Parameters& params = cfgFile.getParameters();
|
||||
for (size_t n = 0; n < params.getCount() && !exactMatch; ++n)
|
||||
{
|
||||
const ConfigFile::Parameter* section = ¶ms[n];
|
||||
|
||||
const bool isDatabase = (section->name == "database");
|
||||
if (!isDatabase && section->name != "services")
|
||||
continue;
|
||||
|
||||
const string pattern = section->getAttributes() ? section->getAttributeName(0) : "";
|
||||
const ConfigFile::String pattern = section->value;
|
||||
bool match = false;
|
||||
if (pattern.empty())
|
||||
{
|
||||
@ -146,7 +135,7 @@ void TraceCfgReader::readConfig()
|
||||
if (defDB)
|
||||
{
|
||||
fatal_exception::raiseFmt("line %d: second default database section is not allowed",
|
||||
section->lineNumber + 1);
|
||||
section->line);
|
||||
}
|
||||
|
||||
match = !m_databaseName.empty();
|
||||
@ -157,7 +146,7 @@ void TraceCfgReader::readConfig()
|
||||
if (defSvc)
|
||||
{
|
||||
fatal_exception::raiseFmt("line %d: second default service section is not allowed",
|
||||
section->lineNumber + 1);
|
||||
section->line);
|
||||
}
|
||||
match = m_databaseName.empty();
|
||||
defSvc = true;
|
||||
@ -205,12 +194,12 @@ void TraceCfgReader::readConfig()
|
||||
if (regExpOk) {
|
||||
fatal_exception::raiseFmt(
|
||||
"line %d: error while processing string \"%s\" against regular expression \"%s\"",
|
||||
section->lineNumber + 1, m_databaseName.c_str(), pattern.c_str());
|
||||
section->line, m_databaseName.c_str(), pattern.c_str());
|
||||
}
|
||||
else {
|
||||
fatal_exception::raiseFmt(
|
||||
"line %d: error while compiling regular expression \"%s\"",
|
||||
section->lineNumber + 1, pattern.c_str());
|
||||
section->line, pattern.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -219,12 +208,15 @@ void TraceCfgReader::readConfig()
|
||||
if (!match)
|
||||
continue;
|
||||
|
||||
for (const Element* el = section->children; el; el = el->sibling)
|
||||
const ConfigFile::Parameters& elements = section->sub->getParameters();
|
||||
for (size_t p = 0; p < elements.getCount(); ++p)
|
||||
{
|
||||
if (!el->getAttributes())
|
||||
const ConfigFile::Parameter* el = &elements[p];
|
||||
|
||||
if (!el->value.hasData())
|
||||
{
|
||||
fatal_exception::raiseFmt("line %d: element \"%s\" have no attribute value set",
|
||||
el->lineNumber + 1, el->name.c_str());
|
||||
el->line, el->name.c_str());
|
||||
}
|
||||
|
||||
bool found = false;
|
||||
@ -244,7 +236,7 @@ void TraceCfgReader::readConfig()
|
||||
if (!found)
|
||||
{
|
||||
fatal_exception::raiseFmt("line %d: element \"%s\" is unknown",
|
||||
el->lineNumber + 1, el->name.c_str());
|
||||
el->line, el->name.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -255,10 +247,9 @@ void TraceCfgReader::readConfig()
|
||||
#undef BOOL_PARAMETER
|
||||
#undef UINT_PARAMETER
|
||||
|
||||
bool TraceCfgReader::parseBoolean(const Element* el) const
|
||||
bool TraceCfgReader::parseBoolean(const ConfigFile::Parameter* el) const
|
||||
{
|
||||
const char* value = el->getAttributeName(0);
|
||||
string tempValue(value);
|
||||
ConfigFile::String tempValue(el->value);
|
||||
tempValue.upper();
|
||||
|
||||
if (tempValue == "1" || tempValue == "ON" || tempValue == "YES" || tempValue == "TRUE")
|
||||
@ -267,24 +258,24 @@ bool TraceCfgReader::parseBoolean(const Element* el) const
|
||||
return false;
|
||||
|
||||
fatal_exception::raiseFmt("line %d, element \"%s\": \"%s\" is not a valid boolean value",
|
||||
el->lineNumber + 1, el->name.c_str(), value);
|
||||
el->line, el->name.c_str(), el->value.c_str());
|
||||
return false; // Silence the compiler
|
||||
}
|
||||
|
||||
ULONG TraceCfgReader::parseUInteger(const Element* el) const
|
||||
ULONG TraceCfgReader::parseUInteger(const ConfigFile::Parameter* el) const
|
||||
{
|
||||
const char *value = el->getAttributeName(0);
|
||||
const char *value = el->value.c_str();
|
||||
ULONG result = 0;
|
||||
if (!sscanf(value, "%"ULONGFORMAT, &result)) {
|
||||
fatal_exception::raiseFmt("line %d, element \"%s\": \"%s\" is not a valid integer value",
|
||||
el->lineNumber + 1, el->name.c_str(), value);
|
||||
el->line, el->name.c_str(), value);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void TraceCfgReader::expandPattern(const Element* el, string& valueToExpand)
|
||||
void TraceCfgReader::expandPattern(const ConfigFile::Parameter* el, ConfigFile::String& valueToExpand)
|
||||
{
|
||||
valueToExpand = el->getAttributeName(0);
|
||||
valueToExpand = el->value;
|
||||
string::size_type pos = 0;
|
||||
while (pos < valueToExpand.length())
|
||||
{
|
||||
@ -293,7 +284,7 @@ void TraceCfgReader::expandPattern(const Element* el, string& valueToExpand)
|
||||
{
|
||||
if (pos + 1 >= valueToExpand.length())
|
||||
fatal_exception::raiseFmt("line %d, element \"%s\": pattern is invalid\n\t %s",
|
||||
el->lineNumber + 1, el->name.c_str(), el->getAttributeName(0));
|
||||
el->line, el->name.c_str(), el->value.c_str());
|
||||
|
||||
c = valueToExpand[pos + 1];
|
||||
if (c == '\\')
|
||||
@ -321,7 +312,7 @@ void TraceCfgReader::expandPattern(const Element* el, string& valueToExpand)
|
||||
}
|
||||
|
||||
fatal_exception::raiseFmt("line %d, element \"%s\": pattern is invalid\n\t %s",
|
||||
el->lineNumber + 1, el->name.c_str(), el->getAttributeName(0));
|
||||
el->line, el->name.c_str(), el->value.c_str());
|
||||
}
|
||||
|
||||
pos++;
|
||||
|
@ -31,11 +31,7 @@
|
||||
#include "firebird.h"
|
||||
#include "../../common/classes/auto.h"
|
||||
#include "../../common/classes/fb_string.h"
|
||||
#include "../../config/ConfigFile.h"
|
||||
#include "../../config/ConfObj.h"
|
||||
#include "../../config/ConfObject.h"
|
||||
#include "../../config/Element.h"
|
||||
#include "../../config/AdminException.h"
|
||||
#include "../../common/config/config_file.h"
|
||||
#include "TracePluginConfig.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
@ -62,9 +58,9 @@ private:
|
||||
|
||||
void readConfig();
|
||||
|
||||
void expandPattern(const Element* el, Firebird::string& valueToExpand);
|
||||
bool parseBoolean(const Element* el) const;
|
||||
ULONG parseUInteger(const Element* el) const;
|
||||
void expandPattern(const ConfigFile::Parameter* el, Firebird::PathName& valueToExpand);
|
||||
bool parseBoolean(const ConfigFile::Parameter* el) const;
|
||||
ULONG parseUInteger(const ConfigFile::Parameter* el) const;
|
||||
|
||||
const char* const m_text;
|
||||
const Firebird::PathName& m_databaseName;
|
||||
|
@ -38,7 +38,7 @@ struct TracePluginConfig
|
||||
#define SERVICE_PARAMS
|
||||
|
||||
#define PATH_PARAMETER(NAME, VALUE) Firebird::PathName NAME;
|
||||
#define STR_PARAMETER(NAME, VALUE) Firebird::string NAME;
|
||||
#define STR_PARAMETER(NAME, VALUE) Firebird::PathName NAME;
|
||||
#define BOOL_PARAMETER(NAME, VALUE) bool NAME;
|
||||
#define UINT_PARAMETER(NAME, VALUE) ULONG NAME;
|
||||
#include "paramtable.h"
|
||||
|
@ -15,20 +15,20 @@
|
||||
# \\ is backslash.
|
||||
|
||||
|
||||
# default database section
|
||||
#
|
||||
<database>
|
||||
database
|
||||
{
|
||||
# Do we trace database events or not
|
||||
enabled false
|
||||
enabled = 0
|
||||
|
||||
|
||||
# Operations log file name. For use by system audit trace only
|
||||
#log_filename
|
||||
#log_filename = name
|
||||
|
||||
# Maximum size of log file (megabytes). Used by system audit trace for
|
||||
# log's rotation : when current log file reached this limit it is renamed
|
||||
# using current date and time and new log file is created. Value of zero
|
||||
# means that the log file size is unlimited and rotation will never happen.
|
||||
max_log_size 0
|
||||
#max_log_size 0
|
||||
|
||||
|
||||
# SQL query filters.
|
||||
@ -43,83 +43,83 @@
|
||||
|
||||
|
||||
# Put attach/detach log records
|
||||
log_connections false
|
||||
#log_connections = 0
|
||||
|
||||
# Trace only given connection id. If zero - trace all connections
|
||||
#connection_id 0
|
||||
#connection_id = 0
|
||||
|
||||
# Put transaction start/end records
|
||||
log_transactions false
|
||||
#log_transactions = 0
|
||||
|
||||
|
||||
# Put sql statement prepare records
|
||||
log_statement_prepare false
|
||||
#log_statement_prepare = 0
|
||||
|
||||
# Put sql statement free records
|
||||
log_statement_free false
|
||||
#log_statement_free = 0
|
||||
|
||||
# Put sql statement execution start records
|
||||
log_statement_start false
|
||||
#log_statement_start = 0
|
||||
|
||||
# Put sql statement execution finish\fetch to eof records
|
||||
log_statement_finish false
|
||||
#log_statement_finish = 0
|
||||
|
||||
# Put record when stored procedure is start execution
|
||||
log_procedure_start false
|
||||
#log_procedure_start = 0
|
||||
|
||||
# Put record when stored procedure is finish execution
|
||||
log_procedure_finish false
|
||||
#log_procedure_finish = 0
|
||||
|
||||
# Put trigger execute records
|
||||
log_trigger_start false
|
||||
#log_trigger_start = 0
|
||||
|
||||
# Put trigger execute records
|
||||
log_trigger_finish false
|
||||
#log_trigger_finish = 0
|
||||
|
||||
# Put context variable change records (RDB$SET_CONTEXT)
|
||||
#log_context false
|
||||
#log_context = 0
|
||||
|
||||
|
||||
# Print access path (plan) with sql statement
|
||||
print_plan false
|
||||
#print_plan = 0
|
||||
|
||||
# Print detailed performance info when applicable
|
||||
print_perf false
|
||||
#print_perf = 0
|
||||
|
||||
|
||||
# Put blr requests compile/execute records
|
||||
log_blr_requests false
|
||||
@log_blr_requests = 0
|
||||
|
||||
# Print blr requests or not
|
||||
print_blr false
|
||||
#print_blr = 0
|
||||
|
||||
# Put dyn requests execute records
|
||||
log_dyn_requests false
|
||||
#log_dyn_requests = 0
|
||||
|
||||
# Print dyn requests or not
|
||||
print_dyn false
|
||||
#print_dyn = 0
|
||||
|
||||
|
||||
# Put xxx_finish record only if its timing exceeds this number of milliseconds
|
||||
time_threshold 100
|
||||
#time_threshold = 100
|
||||
|
||||
# Maximum length of SQL string logged
|
||||
# Beware when adjusting max_xxx parameters! Maximum length of log record
|
||||
# for one event should never exceed 64K.
|
||||
max_sql_length 300
|
||||
#max_sql_length = 300
|
||||
|
||||
# Maximum length of blr request logged
|
||||
max_blr_length 500
|
||||
#max_blr_length = 500
|
||||
|
||||
# Maximum length of dyn request logged
|
||||
max_dyn_length 500
|
||||
#max_dyn_length = 500
|
||||
|
||||
# Maximum length of individual string argument we log
|
||||
max_arg_length 80
|
||||
#max_arg_length = 80
|
||||
|
||||
# Maximum number of query arguments to put in log
|
||||
max_arg_count 30
|
||||
</database>
|
||||
#max_arg_count = 30
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -147,16 +147,17 @@
|
||||
# Set Domain Admins Mapping to RDB$ADMIN
|
||||
# Drop Domain Admins Mapping to RDB$ADMIN
|
||||
#
|
||||
<services>
|
||||
services
|
||||
{
|
||||
# Do we trace services events or not
|
||||
enabled false
|
||||
#enabled =0
|
||||
|
||||
# Operations log file name. For use by system audit trace only
|
||||
#log_filename
|
||||
#log_filename name
|
||||
|
||||
# Maximum size of log file (megabytes). Used by system audit trace for
|
||||
# log's rotation
|
||||
max_log_size 0
|
||||
#max_log_size 0
|
||||
|
||||
# Services filters.
|
||||
#
|
||||
@ -169,27 +170,29 @@
|
||||
#exclude_filter
|
||||
|
||||
# Put service attach, detach and start records
|
||||
log_services false
|
||||
#log_services false
|
||||
|
||||
# Put service query records
|
||||
log_service_query false
|
||||
</services>
|
||||
#log_service_query false
|
||||
}
|
||||
|
||||
|
||||
# Example of trace customization:
|
||||
#
|
||||
# Enable logging for my_database.fdb in any folder
|
||||
#
|
||||
<database %[\\/]my_database.fdb>
|
||||
enabled true
|
||||
</database>
|
||||
database = %[\\/]my_database.fdb
|
||||
{
|
||||
enabled = 1
|
||||
}
|
||||
|
||||
|
||||
# Enable logging for test.fdb, azk2.fdb and rulez.fdb in any directory
|
||||
# into log file name matching database name - test.log, azk2.log and
|
||||
# rulez.log appropriately
|
||||
#
|
||||
<database %[\\/](test|azk2|rulez).fdb>
|
||||
database = %[\\/](test|azk2|rulez).fdb
|
||||
{
|
||||
enabled true
|
||||
log_filename \1.log
|
||||
</database>
|
||||
}
|
||||
|
@ -1,187 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* 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/idpl.html.
|
||||
*
|
||||
* Software distributed under the License is distributed on
|
||||
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
|
||||
* express or implied. See the License for the specific
|
||||
* language governing rights and limitations under the License.
|
||||
*
|
||||
* The contents of this file or any work derived from this file
|
||||
* may not be distributed under any other license whatsoever
|
||||
* without the express prior written permission of the original
|
||||
* author.
|
||||
*
|
||||
*
|
||||
* The Original Code was created by James A. Starkey for IBPhoenix.
|
||||
*
|
||||
* Copyright (c) 2004 James A. Starkey
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
#include "firebird.h"
|
||||
#include "../jrd/common.h"
|
||||
#include "../jrd/ibase.h"
|
||||
#include "PathName.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#define SEPARATOR '\\'
|
||||
#define IS_SEPARATOR(c) (c == '/' || c == '\\')
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_PWD_H
|
||||
#include <pwd.h>
|
||||
#endif
|
||||
|
||||
#ifndef SEPARATOR
|
||||
#define SEPARATOR '/'
|
||||
#define IS_SEPARATOR(c) (c == '/')
|
||||
#endif
|
||||
|
||||
#define IS_LETTER(c) ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
|
||||
//#define UPPER(c) ((c >= 'a' && c <= 'z') ? c - 'a' + 'A' : c)
|
||||
|
||||
PathName::PathName()
|
||||
{
|
||||
}
|
||||
|
||||
PathName::~PathName()
|
||||
{
|
||||
}
|
||||
|
||||
int PathName::merge(const char* fileName, const char* workingDirectory, int bufferLength, char* buffer)
|
||||
{
|
||||
const char* const endBuffer = buffer + bufferLength - 1;
|
||||
|
||||
if (isAbsolute (fileName))
|
||||
{
|
||||
char* rc = copyCanonical (fileName, buffer, endBuffer);
|
||||
return rc - buffer;
|
||||
}
|
||||
|
||||
// Copy working directory, making slashes canonical
|
||||
|
||||
char* q = copyCanonical (workingDirectory, buffer, endBuffer);
|
||||
|
||||
#ifdef _WIN32
|
||||
if (IS_SEPARATOR (fileName [0]))
|
||||
{
|
||||
for (q = buffer; *q && *q++ != ':';)
|
||||
;
|
||||
q = copyCanonical (fileName, q, endBuffer);
|
||||
return q - buffer;
|
||||
}
|
||||
#endif
|
||||
|
||||
// And add a trailing slash, if necessary
|
||||
|
||||
if (q == buffer || q [-1] != '/')
|
||||
*q++ = '/';
|
||||
|
||||
// Handle self relative segments
|
||||
|
||||
const char* p = fileName;
|
||||
while (*p == '.')
|
||||
{
|
||||
if (IS_SEPARATOR (p[1]))
|
||||
p += 2;
|
||||
else if (p [1] == '.' && IS_SEPARATOR (p [2]))
|
||||
{
|
||||
p += 3;
|
||||
q -= 1;
|
||||
while (q > buffer && q [-1] != '/')
|
||||
--q;
|
||||
if (q == buffer || q [-1] != '/')
|
||||
*q++ = '/';
|
||||
}
|
||||
else if (!p [1])
|
||||
++p;
|
||||
}
|
||||
|
||||
// skip over extra separators in the file name
|
||||
|
||||
while (IS_SEPARATOR (*p))
|
||||
++p;
|
||||
|
||||
// and move in the final filename
|
||||
|
||||
q = copyCanonical (p, q, endBuffer);
|
||||
|
||||
return q - buffer;
|
||||
}
|
||||
|
||||
bool PathName::isAbsolute(const char* fileName)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return (IS_LETTER (fileName [0]) &&
|
||||
fileName [1] == ':' && (fileName [2] == '/' || fileName [2] == '\\')) ||
|
||||
(fileName[0] == '/' && fileName[1] == '/') ||
|
||||
(fileName[0] == '\\' && fileName[1] == '\\');
|
||||
|
||||
|
||||
#else
|
||||
return fileName [0] == '/';
|
||||
#endif
|
||||
}
|
||||
|
||||
char* PathName::copyCanonical(const char* fileName, char* buffer, const char* endBuffer)
|
||||
{
|
||||
char* q = buffer;
|
||||
const char* p = fileName;
|
||||
|
||||
#ifdef _WIN32
|
||||
if (IS_SEPARATOR (*p))
|
||||
{
|
||||
*q++ = '/';
|
||||
++p;
|
||||
}
|
||||
#endif
|
||||
|
||||
while (*p && q < endBuffer)
|
||||
{
|
||||
char c = *p++;
|
||||
if (IS_SEPARATOR (c))
|
||||
{
|
||||
c = '/';
|
||||
while (IS_SEPARATOR (*p))
|
||||
++p;
|
||||
}
|
||||
*q++ = c;
|
||||
}
|
||||
|
||||
*q = 0;
|
||||
|
||||
return q;
|
||||
}
|
||||
|
||||
bool PathName::hasDirectory(const char* fileName)
|
||||
{
|
||||
for (const char* p = fileName; *p; ++p)
|
||||
{
|
||||
if (IS_SEPARATOR (*p))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PathName::pathsEquivalent(const char* path1, const char* path2)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return stricmp(path1, path2) == 0;
|
||||
#else
|
||||
return strcmp (path1, path2) == 0;
|
||||
#endif
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* 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/idpl.html.
|
||||
*
|
||||
* Software distributed under the License is distributed on
|
||||
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
|
||||
* express or implied. See the License for the specific
|
||||
* language governing rights and limitations under the License.
|
||||
*
|
||||
* The contents of this file or any work derived from this file
|
||||
* may not be distributed under any other license whatsoever
|
||||
* without the express prior written permission of the original
|
||||
* author.
|
||||
*
|
||||
*
|
||||
* The Original Code was created by James A. Starkey for IBPhoenix.
|
||||
*
|
||||
* Copyright (c) 2004 James A. Starkey
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
|
||||
#ifndef VULCAN_PATHNAME_H_
|
||||
#define VULCAN_PATHNAME_H_
|
||||
|
||||
#if defined _MSC_VER && _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
#include "../common/classes/fb_string.h"
|
||||
|
||||
|
||||
class PathName : public Firebird::GlobalStorage
|
||||
{
|
||||
public:
|
||||
PathName();
|
||||
virtual ~PathName();
|
||||
|
||||
static int merge(const char* fileName, const char* workingDirectory, int bufferLength, char* buffer);
|
||||
static bool isAbsolute(const char* fileName);
|
||||
static char* copyCanonical(const char* fileName, char* buffer, const char* endBuffer);
|
||||
static bool hasDirectory(const char* fileName);
|
||||
static bool pathsEquivalent(const char* path1, const char* path2);
|
||||
};
|
||||
|
||||
#endif // VULCAN_PATHNAME_H_
|
@ -1,57 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* 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/idpl.html.
|
||||
*
|
||||
* Software distributed under the License is distributed on
|
||||
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
|
||||
* express or implied. See the License for the specific
|
||||
* language governing rights and limitations under the License.
|
||||
*
|
||||
* The contents of this file or any work derived from this file
|
||||
* may not be distributed under any other license whatsoever
|
||||
* without the express prior written permission of the original
|
||||
* author.
|
||||
*
|
||||
*
|
||||
* The Original Code was created by James A. Starkey for IBPhoenix.
|
||||
*
|
||||
* Copyright (c) 1997 - 2000, 2001, 2003 James A. Starkey
|
||||
* Copyright (c) 1997 - 2000, 2001, 2003 Netfrastructure, Inc.
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
|
||||
// RefObject.cpp: implementation of the RefObject class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "firebird.h"
|
||||
#include "../common/classes/alloc.h"
|
||||
#include "RefObject.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
RefObject::RefObject()
|
||||
{
|
||||
useCount = 1;
|
||||
}
|
||||
|
||||
RefObject::~RefObject()
|
||||
{
|
||||
}
|
||||
|
||||
void RefObject::addRef()
|
||||
{
|
||||
++useCount;
|
||||
}
|
||||
|
||||
void RefObject::release()
|
||||
{
|
||||
if (--useCount == 0)
|
||||
delete this;
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* 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/idpl.html.
|
||||
*
|
||||
* Software distributed under the License is distributed on
|
||||
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
|
||||
* express or implied. See the License for the specific
|
||||
* language governing rights and limitations under the License.
|
||||
*
|
||||
* The contents of this file or any work derived from this file
|
||||
* may not be distributed under any other license whatsoever
|
||||
* without the express prior written permission of the original
|
||||
* author.
|
||||
*
|
||||
*
|
||||
* The Original Code was created by James A. Starkey for IBPhoenix.
|
||||
*
|
||||
* Copyright (c) 1997 - 2000, 2001, 2003 James A. Starkey
|
||||
* Copyright (c) 1997 - 2000, 2001, 2003 Netfrastructure, Inc.
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
|
||||
// RefObject.h: interface for the RefObject class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(AFX_REFOBJECT_H__B78AA20E_CBF1_4191_B648_177D9CE87E32__INCLUDED_)
|
||||
#define AFX_REFOBJECT_H__B78AA20E_CBF1_4191_B648_177D9CE87E32__INCLUDED_
|
||||
|
||||
#if defined _MSC_VER && _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
class RefObject
|
||||
{
|
||||
public:
|
||||
RefObject();
|
||||
virtual ~RefObject();
|
||||
virtual void addRef();
|
||||
virtual void release();
|
||||
private:
|
||||
int useCount;
|
||||
};
|
||||
|
||||
#endif // !defined(AFX_REFOBJECT_H__B78AA20E_CBF1_4191_B648_177D9CE87E32__INCLUDED_)
|
Loading…
Reference in New Issue
Block a user