mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-22 17:23:03 +01:00
Merge remote-tracking branch 'origin/master' into cursor-info
This commit is contained in:
commit
4c8f31fc73
3
.github/workflows/main.yml
vendored
3
.github/workflows/main.yml
vendored
@ -7,13 +7,12 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
container: ${{ matrix.container }}
|
||||
env:
|
||||
VS_VERSION: ${{ matrix.os == 'windows-2016' && '2017' || (matrix.os == 'windows-2019' && '2019' || (matrix.os == 'windows-2022' && '2022' || '')) }}
|
||||
VS_VERSION: ${{ (matrix.os == 'windows-2019' && '2019' || (matrix.os == 'windows-2022' && '2022' || '')) }}
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os:
|
||||
- windows-2016
|
||||
- windows-2019
|
||||
platform: [x64, x86]
|
||||
include:
|
||||
|
@ -155,7 +155,6 @@ endif()
|
||||
set(FB_PREFIX ${CMAKE_INSTALL_PREFIX}/${PROJECT_NAME})
|
||||
set(FB_IPC_NAME "FirebirdIPI")
|
||||
set(FB_LOGFILENAME "firebird.log")
|
||||
set(FB_PIPE_NAME "interbas")
|
||||
set(FB_SERVICE_NAME "gds_db")
|
||||
set(FB_SERVICE_PORT 3050)
|
||||
|
||||
|
@ -42,6 +42,8 @@ source_group("ISQL files\\${EPP_TXT}" "${SSRC}/isql/${EPP}")
|
||||
source_group("ISQL files\\${GEN_TXT}" "${BSRC}/isql/${GEN}")
|
||||
source_group("JRD files" "${SSRC}/jrd/${CPP}")
|
||||
source_group("JRD files\\Data Access" "${SSRC}/jrd/recsrc/${CPP}")
|
||||
source_group("JRD files\\Optimizer" "${SSRC}/jrd/optimizer/${CPP}")
|
||||
source_group("JRD files\\Replication" "${SSRC}/jrd/replication/${CPP}")
|
||||
source_group("JRD files\\EXTDS" "${SSRC}/jrd/extds/${CPP}")
|
||||
source_group("JRD files\\${EPP_TXT}" "${SSRC}/jrd/${EPP}")
|
||||
source_group("JRD files\\${GEN_TXT}" "${BSRC}/jrd/${GEN}")
|
||||
|
@ -384,7 +384,7 @@ Filename: msiexec.exe; Parameters: "/qn /norestart /i ""{tmp}\vccrt{#msvc_runtim
|
||||
#endif
|
||||
|
||||
;Only register Firebird if we are installing AND configuring
|
||||
Filename: {app}\instreg.exe; Parameters: "install "; StatusMsg: {cm:instreg}; MinVersion: {#MinVer}; Components: ClientComponent; Flags: runminimized; Check: ConfigureFirebird;
|
||||
Filename: {app}\instreg.exe; Parameters: "install "; StatusMsg: {cm:instreg}; MinVersion: {#MinVer}; Components: ServerComponent; Flags: runminimized; Check: ConfigureFirebird;
|
||||
|
||||
Filename: {app}\instclient.exe; Parameters: "install fbclient"; StatusMsg: {cm:instclientCopyFbClient}; MinVersion: {#MinVer}; Components: ClientComponent; Flags: runminimized; Check: CopyFBClientLib;
|
||||
Filename: {app}\instclient.exe; Parameters: "install gds32"; StatusMsg: {cm:instclientGenGds32}; MinVersion: {#MinVer}; Components: ClientComponent; Flags: runminimized; Check: CopyGds32
|
||||
@ -410,7 +410,7 @@ Filename: "{#MyAppURL}/afterinstall"; Description: "After installation - What Ne
|
||||
Root: HKLM; Subkey: SOFTWARE\Microsoft\Windows\CurrentVersion\Run; ValueType: string; ValueName: Firebird; ValueData: ; Flags: uninsdeletevalue; Tasks: UseApplicationTask; Check: ConfigureFirebird;
|
||||
|
||||
;This doesn't seem to get cleared automatically by instreg on uninstall, so lets make sure of it
|
||||
Root: HKLM; Subkey: "SOFTWARE\Firebird Project"; Flags: uninsdeletekeyifempty; Components: ClientComponent DevAdminComponent ServerComponent
|
||||
Root: HKLM; Subkey: "SOFTWARE\Firebird Project"; Flags: uninsdeletekeyifempty; Components: ServerComponent
|
||||
|
||||
;Clean up Invalid registry entries from previous installs.
|
||||
Root: HKLM; Subkey: "SOFTWARE\FirebirdSQL"; ValueType: none; Flags: deletekey;
|
||||
@ -476,7 +476,7 @@ Source: {#FilesDir}\firebird.exe; DestDir: {app}; Components: ServerComponent; F
|
||||
Source: {#FilesDir}\fb_lock_print.exe; DestDir: {app}; Components: ServerComponent; Flags: sharedfile ignoreversion
|
||||
Source: {#FilesDir}\ib_util.dll; DestDir: {app}; Components: ServerComponent; Flags: sharedfile ignoreversion
|
||||
Source: {#FilesDir}\instclient.exe; DestDir: {app}; Components: ClientComponent; Flags: sharedfile ignoreversion
|
||||
Source: {#FilesDir}\instreg.exe; DestDir: {app}; Components: ClientComponent; Flags: sharedfile ignoreversion
|
||||
Source: {#FilesDir}\instreg.exe; DestDir: {app}; Components: ServerComponent; Flags: sharedfile ignoreversion
|
||||
Source: {#FilesDir}\instsvc.exe; DestDir: {app}; Components: ServerComponent; MinVersion: {#MinVer}; Flags: sharedfile ignoreversion
|
||||
Source: {#FilesDir}\isql.exe; DestDir: {app}; Components: DevAdminComponent; Flags: ignoreversion
|
||||
Source: {#FilesDir}\nbackup.exe; DestDir: {app}; Components: DevAdminComponent; Flags: ignoreversion
|
||||
@ -487,14 +487,25 @@ Source: {#FilesDir}\fbclient.dll; DestDir: {app}; Components: ClientComponent; F
|
||||
Source: {#WOW64Dir}\fbclient.dll; DestDir: {app}\WOW64; Components: ClientComponent; Flags: overwritereadonly sharedfile promptifolder {#SkipFileIfDevStatus}
|
||||
Source: {#WOW64Dir}\instclient.exe; DestDir: {app}\WOW64; Components: ClientComponent; Flags: sharedfile ignoreversion {#SkipFileIfDevStatus}
|
||||
#endif
|
||||
Source: {#FilesDir}\icuuc??.dll; DestDir: {app}; Components: ServerComponent; Flags: sharedfile ignoreversion
|
||||
Source: {#FilesDir}\icuin??.dll; DestDir: {app}; Components: ServerComponent; Flags: sharedfile ignoreversion
|
||||
Source: {#FilesDir}\icudt??.dll; DestDir: {app}; Components: ServerComponent; Flags: sharedfile ignoreversion
|
||||
Source: {#FilesDir}\icudt*.dat; DestDir: {app}; Components: ServerComponent; Flags: sharedfile ignoreversion
|
||||
Source: {#FilesDir}\icuuc??.dll; DestDir: {app}; Components: ClientComponent; Flags: sharedfile ignoreversion
|
||||
Source: {#FilesDir}\icuin??.dll; DestDir: {app}; Components: ClientComponent; Flags: sharedfile ignoreversion
|
||||
Source: {#FilesDir}\icudt??.dll; DestDir: {app}; Components: ClientComponent; Flags: sharedfile ignoreversion
|
||||
Source: {#FilesDir}\icudt*.dat; DestDir: {app}; Components: ClientComponent; Flags: sharedfile ignoreversion
|
||||
#if PlatformTarget == "x64"
|
||||
Source: {#WOW64Dir}\icuuc??.dll; DestDir: {app}\WOW64; Components: ClientComponent; Flags: sharedfile ignoreversion
|
||||
Source: {#WOW64Dir}\icuin??.dll; DestDir: {app}\WOW64; Components: ClientComponent; Flags: sharedfile ignoreversion
|
||||
Source: {#WOW64Dir}\icudt??.dll; DestDir: {app}\WOW64; Components: ClientComponent; Flags: sharedfile ignoreversion
|
||||
Source: {#WOW64Dir}\icudt*.dat; DestDir: {app}\WOW64; Components: ClientComponent; Flags: sharedfile ignoreversion
|
||||
#endif
|
||||
|
||||
#if PlatformTarget =="Win32"
|
||||
Source: {#FilesDir}\fbrmclib.dll; DestDir: {app}; Components: ServerComponent; Flags: sharedfile ignoreversion
|
||||
#endif
|
||||
Source: {#FilesDir}\zlib1.dll; DestDir: {app}; Components: ServerComponent; Flags: sharedfile ignoreversion
|
||||
|
||||
Source: {#FilesDir}\zlib1.dll; DestDir: {app}; Components: ClientComponent; Flags: sharedfile ignoreversion
|
||||
#if PlatformTarget == "x64"
|
||||
Source: {#WOW64Dir}\zlib1.dll; DestDir: {app}\WOW64; Components: ClientComponent; Flags: sharedfile ignoreversion
|
||||
#endif
|
||||
|
||||
;Rules for installation of MS runtimes are simplified with MSVC10
|
||||
;We just install the runtimes into the install dir.
|
||||
@ -542,9 +553,13 @@ Source: {#WOW64Dir}\lib\*.lib; DestDir: {app}\WOW64\lib; Components: DevAdminCom
|
||||
;Source: {#FilesDir}\UDF\*.txt; DestDir: {app}\UDF; Components: ServerComponent; Flags: ignoreversion;
|
||||
|
||||
Source: {#FilesDir}\plugins.conf; DestDir: {app}; Components: ServerComponent; Flags: ignoreversion;
|
||||
Source: {#FilesDir}\plugins\*.dll; DestDir: {app}\plugins; Components: ServerComponent; Flags: ignoreversion;
|
||||
Source: {#FilesDir}\plugins\*.dll; DestDir: {app}\plugins; Components: ServerComponent; Flags: ignoreversion; Check: IsServerInstall;
|
||||
Source: {#FilesDir}\plugins\chacha.dll; DestDir: {app}\plugins; Components: ClientComponent; Flags: ignoreversion; Check: IsNotServerInstall;
|
||||
Source: {#FilesDir}\plugins\*.conf; DestDir: {app}\plugins; Components: ServerComponent; Flags: ignoreversion;
|
||||
Source: {#FilesDir}\plugins\udr\*.*; DestDir: {app}\plugins\udr; Components: ServerComponent; Flags: ignoreversion;
|
||||
#if PlatformTarget == "x64"
|
||||
Source: {#WOW64Dir}\plugins\chacha*.dll; DestDir: {app}\WOW64\plugins; Components: ClientComponent; Flags: ignoreversion;
|
||||
#endif
|
||||
|
||||
Source: {#FilesDir}\misc\*.*; DestDir: {app}\misc; Components: ServerComponent; Flags: ignoreversion createallsubdirs recursesubdirs ;
|
||||
|
||||
@ -575,7 +590,7 @@ Filename: {app}\instclient.exe; Parameters: " remove fbclient"; StatusMsg: {cm:i
|
||||
Filename: {app}\wow64\instclient.exe; Parameters: " remove gds32"; StatusMsg: {cm:instclientDecLibCountGds32}; MinVersion: {#MinVer}; Flags: runminimized 32bit; RunOnceId: RemoveGDS32x86
|
||||
Filename: {app}\wow64\instclient.exe; Parameters: " remove fbclient"; StatusMsg: {cm:instclientDecLibCountFbClient}; MinVersion: {#MinVer}; Flags: runminimized 32bit; RunOnceId: RemoveFbClientx86
|
||||
#endif
|
||||
Filename: {app}\instreg.exe; Parameters: " remove"; StatusMsg: {cm:instreg}; MinVersion: {#MinVer}; Flags: runminimized; RunOnceId: RemoveRegistryEntry
|
||||
Filename: {app}\instreg.exe; Parameters: " remove"; StatusMsg: {cm:instreg}; MinVersion: {#MinVer}; Components: ServerComponent; Flags: runminimized; RunOnceId: RemoveRegistryEntry
|
||||
|
||||
[UninstallDelete]
|
||||
Type: files; Name: "{app}\*.lck"
|
||||
|
@ -890,9 +890,40 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
function IsServerInstall: Boolean;
|
||||
var
|
||||
SetupType: String;
|
||||
begin
|
||||
|
||||
// DOC NOTE - WizardSetupType is not well documented. If parameter is set to
|
||||
// True the Description of the setup type is returned. (This is useless for us
|
||||
// as our descriptions are I18n'ised. ) If set False the string declared in
|
||||
// the TYPES section is returned. BUT LOWERCASED! Aargh!!
|
||||
// To protect against future changes each side is the comparison is lowercased.
|
||||
|
||||
SetupType := WizardSetupType ( false );
|
||||
if LowerCase( SetupType ) = LowerCase( 'ServerInstall' ) then
|
||||
Result := true
|
||||
else
|
||||
Result := False;
|
||||
end;
|
||||
|
||||
|
||||
function IsNotServerInstall: Boolean;
|
||||
begin
|
||||
if IsServerInstall then
|
||||
Result := False
|
||||
else
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
|
||||
function ConfigureFirebird: boolean;
|
||||
begin
|
||||
result := (InstallAndConfigure AND Configure) = Configure;
|
||||
if IsNotServerInstall then
|
||||
Result := False
|
||||
else
|
||||
Result := (InstallAndConfigure AND Configure) = Configure;
|
||||
end;
|
||||
|
||||
|
||||
|
@ -1,5 +1,3 @@
|
||||
|
||||
|
||||
Firebird Binary Installer Test Harness HELP (Designed with TABS=4 and console width=120)
|
||||
|
||||
fbit {PARAM [...]]
|
||||
@ -11,15 +9,22 @@
|
||||
will clean up from previous broken installs. CLEAN must the first parameter
|
||||
and subsequent parameters are ignored. Note: - It will run silently.
|
||||
|
||||
|
||||
By default fbit installs Firebird according to the parameters passed and then
|
||||
immediately uninstalls it. A copy of the install is made, along with the install and uninstall logs.
|
||||
|
||||
REQUIREMENTS
|
||||
============
|
||||
The script will attempt to detect if the current cmd session has just built firebird.
|
||||
If not you must set FBINST_EXEC in the environment prior to running this script.
|
||||
|
||||
Be sure to check :SET_GLOBAL_ENV for hard-coded settings
|
||||
Some knowledge of InnoSetup will be useful. See %FIREBIRD%/doc/installation_scripted.txt for more info.
|
||||
|
||||
|
||||
FBIT Specific Parameters
|
||||
========================
|
||||
Param Name Value Passed Comment
|
||||
---------- ------------ -------
|
||||
Param Name Value Passed to fbit Comment
|
||||
---------- -------------------- -------
|
||||
HELP - Displays this screen
|
||||
DRYRUN - Show what will be done. No changes are made
|
||||
NOARCHIVE - Disables copying of install dir to %USERPROFILE%\fbit
|
||||
@ -28,61 +33,74 @@
|
||||
SCRIPTED - Sets VERYSILENT, SP and NOMSG
|
||||
TESTNAME NameOfTestRun Optional. No spaces allowed. Used for storing test run details.
|
||||
|
||||
|
||||
The following parameters are set by default. They are unset automatically when a conflicting parameter is passed.
|
||||
|
||||
Default Param Value Unset by
|
||||
------------- ------------- ----------
|
||||
Default Param Default Value set by fbit Unset by
|
||||
------------- ------------------------- ----------
|
||||
INTERACTIVE True SCRIPTED
|
||||
INSTALLTYPE ServerInstall CLIENT or DEVINST
|
||||
SERVICE_TASK True APPTASK
|
||||
SUPERSERVER True CLASSICSERVER or SUPERCLASSIC
|
||||
|
||||
|
||||
Firebird Installer specific Parameters
|
||||
======================================
|
||||
Param Name Value passed Action when set
|
||||
Param Name Value passed to installer Action when set
|
||||
---------- ------------------------- ---------------
|
||||
COPYGDSLIB CopyFbClientAsGds32Task Copy fbclient to <SYS> and rename to gds32
|
||||
FORCE FORCE Force installation
|
||||
NOAUTOSTART NULL Does not set AutoStartTask
|
||||
NOCOPYFBLIB CopyFbClientToSysTask Does not copy fbclient to <SYS>
|
||||
NOCOPYFBLIB - Does not copy fbclient to <SYS>
|
||||
PASSWORD /SYSDBAPASSWORD=%ISC_PASSWORD% Changes SYSDBA password from masterkey
|
||||
See :SET_GLOBAL_ENV
|
||||
|
||||
Installation Tasks
|
||||
==================
|
||||
Param Name Value passed Comment
|
||||
------------- ------------ ---------------
|
||||
Param Name Value passed to /TASKS Comment
|
||||
------------- ---------------------- ---------------
|
||||
APPTASK UseApplicationTask Will not install as a service
|
||||
CLASSICSERVER UseClassicServerTask Will configure classic server
|
||||
SUPERCLASSIC UseSuperClassicTask Will configure super classic
|
||||
|
||||
|
||||
Installation Types
|
||||
==================
|
||||
Param Name Value passed Comment
|
||||
------------ ------------ -------
|
||||
Param Name Value passed to /TYPE Comment
|
||||
------------ --------------------- -------
|
||||
CLIENT ClientInstall Minimal working client install
|
||||
DEVINST DeveloperInstall Everything but the server.
|
||||
|
||||
SERVER_INSTALL ServerInstall
|
||||
|
||||
Uninstallation
|
||||
==============
|
||||
Param Name Value passed Comment
|
||||
-------------- ------------ -------
|
||||
Param Name Value passed to uninstaller Comment
|
||||
-------------- --------------------------- -------
|
||||
CLEAN CLEAN Completely remove the firebird install
|
||||
Reset list of shared dll's in the registry
|
||||
|
||||
Assumes installed version of Firebird matches %FIREBIRD_BASE_VER% set in fbit script.
|
||||
|
||||
Generic InnoSetup parameters
|
||||
============================
|
||||
Param Name Value passed Comment
|
||||
---------- ------------ -------
|
||||
Param Name Value passed to installer Comment
|
||||
---------- ------------------------- -------
|
||||
NOMSG SUPPRESSMSGBOXES Suppress message boxes
|
||||
NOCANCEL NOCANCEL Prevents user cancelling install
|
||||
SILENT SILENT
|
||||
SP SP- Disables the This will install... prompt
|
||||
VERYSILENT VERYSILENT
|
||||
|
||||
|
||||
Examples
|
||||
========
|
||||
|
||||
o Run a scripted server install:
|
||||
|
||||
fbit SCRIPTED
|
||||
|
||||
o Clean up previous firebird install:
|
||||
|
||||
fbit CLEAN
|
||||
|
||||
o Test install of firebird client:
|
||||
|
||||
fbit SCRIPTED CLIENT
|
||||
|
||||
-------------------------- End of Fbit Help Screen ----------------------------------------
|
||||
|
@ -18,7 +18,7 @@
|
||||
:: scripted install of Firebird. It is designed to test almost all possible
|
||||
:: scriptable combinations and is thus far more complicated than a typical
|
||||
:: install script need be. However, it can be used for testing. Note that chosen
|
||||
:: settings :: used for each test run are saved into an .inf file, along with a
|
||||
:: settings used for each test run are saved into an .inf file, along with a
|
||||
:: log of the install run.
|
||||
|
||||
@goto :MAIN %*
|
||||
@ -27,26 +27,32 @@
|
||||
::=======================================================
|
||||
:SET_GLOBAL_ENV
|
||||
@call :SET_VERBOSE_IF_DEBUG_ON
|
||||
::@call :SET_VERBOSE
|
||||
@if defined DEBUG @echo Entering %0
|
||||
|
||||
:: Uncomment this if the default command prompt takes up too much space
|
||||
::@PROMPT=fbit_prompt$G
|
||||
|
||||
:: FBINST_EXEC must point to the package we want to test...
|
||||
if not defined FBINST_EXEC (
|
||||
rem - if we have just built firebird we can test the install immediately
|
||||
if defined FBBUILD_FILE_ID (
|
||||
:: Set this to the location of the firebird installer you want to test.
|
||||
::@set FBINST_EXEC=%USERPROFILE%\Desktop\Firebird-5.0.0.0000_x64.exe
|
||||
|
||||
:: if we have just built firebird we can test the install immediately
|
||||
if defined FBBUILD_FILE_ID (
|
||||
if defined FBBUILD_FILENAME_SUFFIX (
|
||||
@set FBINST_EXEC=%FBBUILD_INSTALL_IMAGES%\Firebird-%FBBUILD_FILE_ID%%FBBUILD_FILENAME_SUFFIX%.exe
|
||||
) else (
|
||||
@set FBINST_EXEC=%FBBUILD_INSTALL_IMAGES%\Firebird-%FBBUILD_FILE_ID%.exe
|
||||
)
|
||||
)
|
||||
) else (
|
||||
rem FBINST_EXEC must point to the package we want to test...
|
||||
if not defined FBINST_EXEC (
|
||||
rem Set the actual path and filename here - or set it in the environment before running fbit.
|
||||
@set FBINST_EXEC=%USERPROFILE%\Desktop\Firebird-4.0.0.2311_0_x64_RC1.exe
|
||||
set FBINST_EXEC=%USERPROFILE%\Desktop\Firebird-5.0.0.0000_0_x64_RC1.exe
|
||||
)
|
||||
)
|
||||
|
||||
:: This should be set dynamically, perhaps. But for now it is hard-coded.
|
||||
@set FIREBIRD_BASE_VER=Firebird_4_0
|
||||
@set FIREBIRD_BASE_VER=Firebird_5_0
|
||||
|
||||
:: It is possible that successive installs into the same directory may
|
||||
:: generate different uninstallers but for now we hard code the default.
|
||||
@ -73,14 +79,16 @@ if not defined FBINST_EXEC (
|
||||
:: to read.
|
||||
@set SHOW_FINAL_CMD=
|
||||
|
||||
:: change as reqd, or comment out if ISC_PASSWORD is already set in your env
|
||||
@set ISC_PASSWORD="secret"
|
||||
:: change as reqd
|
||||
@if not defined ISC_PASSWORD (
|
||||
@set ISC_PASSWORD="secret"
|
||||
)
|
||||
|
||||
@set TAB= &
|
||||
|
||||
@if not defined DRYRUN (
|
||||
if not exist %FBINSTALLLOGDIR% @mkdir %FBINSTALLLOGDIR% >nul 2>nul
|
||||
if not exist %FBINSTALLCOPYDIR% @mkdir %FBINSTALLCOPYDIR% >nul 2>nul
|
||||
if not exist %FBINSTALLLOGDIR% ( @mkdir %FBINSTALLLOGDIR% >nul 2>nul )
|
||||
if not exist %FBINSTALLCOPYDIR% ( @mkdir %FBINSTALLCOPYDIR% >nul 2>nul )
|
||||
)
|
||||
|
||||
@if defined DEBUG @echo Leaving %0
|
||||
@ -92,7 +100,8 @@ if not defined FBINST_EXEC (
|
||||
::=======================================================
|
||||
:GET_OPTS
|
||||
@call :SET_VERBOSE_IF_DEBUG_ON
|
||||
if defined DEBUG @echo Entering %0
|
||||
::@call :SET_VERBOSE
|
||||
@if defined DEBUG @echo Entering %0
|
||||
|
||||
:: Automatically parse the commandline and place all valid options into ENV VARS
|
||||
:: Courtesy of this link:
|
||||
@ -111,22 +120,22 @@ if defined DEBUG @echo Entering %0
|
||||
:: will end up as
|
||||
:: flagwithdefault=flag
|
||||
:: Basically all this means that these variables should not be passed to runtime:
|
||||
:: INTERACTIVE INSTALL INSTALLTYPE SERVER SERVICE_TASK SUPERSERVER
|
||||
:: INTERACTIVE INSTALL INSTALLTYPE SERVER_INSTALL SERVICE_TASK SUPERSERVER
|
||||
|
||||
set "options=APPTASK: CLASSICSERVER: CLEAN: CLIENT: CMD_PARAMS: COMPONENTS: COPYGDSLIB: DEVINST: DRYRUN: FINALCMD: FULL_CMD: FORCE: HELP: INTERACTIVE:1 INSTALL:1 INSTALLTYPE:ServerInstall NOARCHIVE: NOAUTOSTART: NOCANCEL: NOCOPYFBLIB: NOMSG: NOUNINSTALL: PASSWORD: RUN_TIMESTAMP: SCRIPTED: SERVER:1 SILENT: SP: SERVICE_TASK:1 SUPERCLASSIC: SUPERSERVER:1 TASK_LIST:UseSuperServerTask TESTNAME:"" UNINSTALL: VERYSILENT: XRESULT:0"
|
||||
if defined VERBOSE @echo on
|
||||
set "options=APPTASK: CLASSICSERVER: CLEAN: CLIENT: CMD_PARAMS: COMPONENTS: COPYGDSLIB: DEVINST: DRYRUN: FINALCMD: FULL_CMD: FORCE: HELP: INTERACTIVE:1 INSTALL:1 INSTALLTYPE:ServerInstall NOARCHIVE: NOAUTOSTART: NOCANCEL: NOCOPYFBLIB: NOMSG: NOUNINSTALL: PASSWORD: RUN_TIMESTAMP: SCRIPTED: SERVER_INSTALL:1 SILENT: SP: SERVICE_TASK: SUPERCLASSIC: SUPERSERVER: TASK_LIST: TESTNAME:"" UNINSTALL: VERYSILENT: XRESULT:0"
|
||||
@if defined VERBOSE @echo on
|
||||
for %%O in (%options%) do (
|
||||
for /f "tokens=1,* delims=:" %%A in ("%%O") do (
|
||||
set "%%A=%%~B"
|
||||
)
|
||||
)
|
||||
if defined VERBOSE (
|
||||
call :PRINT_VARS
|
||||
@if defined VERBOSE (
|
||||
@call :PRINT_VARS
|
||||
if NOT defined DEBUG pause
|
||||
)
|
||||
|
||||
:loop
|
||||
if not "%~1"=="" (
|
||||
@if not "%~1"=="" (
|
||||
set "test=!options:*%~1:=! "
|
||||
if "!test!"=="!options! " (
|
||||
echo Error: Invalid option %~1
|
||||
@ -144,7 +153,8 @@ if not "%~1"=="" (
|
||||
goto :loop
|
||||
)
|
||||
|
||||
if defined DEBUG @echo Leaving %0
|
||||
@if defined VERBOSE ( @call :PRINT_VARS )
|
||||
@if defined DEBUG @echo Leaving %0
|
||||
@call :UNSET_VERBOSE
|
||||
@goto :EOF
|
||||
::=======================================================
|
||||
@ -198,46 +208,100 @@ rem We now have everything we need for uninstall so jump to the end
|
||||
goto :SET_CMD_PARAMS
|
||||
)
|
||||
|
||||
:: Fix up any incompatible assignments
|
||||
:: Fix up any incompatible assignments :::::::::::::::::::::::::::::::::::::::::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
|
||||
@if defined CLASSICSERVER ( set SUPERSERVER=& set SUPERCLASSIC=)
|
||||
@if defined SUPERCLASSIC ( set SUPERSERVER=& set CLASSICSERVER=)
|
||||
:: Theoretically this next line is redundant
|
||||
@if defined SUPERSERVER ( set SUPERCLASSIC=& set CLASSICSERVER=)
|
||||
@if defined CLIENT (
|
||||
set INSTALLTYPE=ClientInstall
|
||||
set DEVINST=
|
||||
set SERVER_INSTALL=
|
||||
set TASK_LIST=
|
||||
set SERVICE_TASK=
|
||||
set CLASSICSERVER=
|
||||
set SUPERCLASSIC=
|
||||
set SUPERSERVER=
|
||||
|
||||
)
|
||||
|
||||
@if defined DEVINST (
|
||||
set INSTALLTYPE=DeveloperInstall
|
||||
set CLIENT=
|
||||
set SERVER_INSTALL=
|
||||
set TASK_LIST=
|
||||
set SERVICE_TASK=
|
||||
set CLASSICSERVER=
|
||||
set SUPERCLASSIC=
|
||||
set SUPERSERVER=
|
||||
)
|
||||
|
||||
@if defined CLIENT ( set INSTALLTYPE=ClientInstall & set DEVINST=& set SERVER=)
|
||||
@if defined DEVINST (set INSTALLTYPE=DeveloperInstall & set SERVER=)
|
||||
:: Theoretically this next line is redundant
|
||||
@if defined SERVER (set INSTALLTYPE=ServerInstall )
|
||||
@if defined SERVER_INSTALL (
|
||||
|
||||
set INSTALLTYPE=ServerInstall
|
||||
set CLIENT=
|
||||
set DEVINST=
|
||||
|
||||
@if defined CLASSICSERVER (
|
||||
set SUPERSERVER=
|
||||
set SUPERCLASSIC=
|
||||
set TASK_LIST=UseClassicServerTask
|
||||
) else (
|
||||
@if defined SUPERCLASSIC (
|
||||
set SUPERSERVER=
|
||||
set CLASSICSERVER=
|
||||
set TASK_LIST=UseSuperClassicTask
|
||||
) else (
|
||||
rem @if defined SUPERSERVER (
|
||||
set SUPERCLASSIC=
|
||||
set CLASSICSERVER=
|
||||
set SUPERSERVER=1
|
||||
set TASK_LIST=UseSuperServerTask
|
||||
)
|
||||
)
|
||||
)
|
||||
::@call :SET_VERBOSE
|
||||
@call :PRINT_VARS In %0 - End of Fixup
|
||||
:::::::::: End Fix Up incompatible assignments :::::::::::::::::::::::::::::::::
|
||||
|
||||
|
||||
:: Now build our task list
|
||||
|
||||
@if defined CLASSICSERVER ( set TASK_LIST=UseClassicServerTask)
|
||||
@if defined SUPERCLASSIC ( set TASK_LIST=UseSuperClassicTask)
|
||||
:: Theoretically this next line is redundant
|
||||
@if defined SUPERSERVER ( set TASK_LIST=UseSuperServerTask)
|
||||
|
||||
@if defined APPTASK (
|
||||
:: At this stage, if TASK_LIST is not defined then we are not doing a server install
|
||||
@if defined TASK_LIST (
|
||||
if defined APPTASK (
|
||||
set TASK_LIST=!TASK_LIST!,UseApplicationTask
|
||||
) else (
|
||||
set INSTALLTYPE=CustomInstall
|
||||
) else (
|
||||
set TASK_LIST=!TASK_LIST!,UseServiceTask
|
||||
)
|
||||
)
|
||||
|
||||
@if NOT defined NOAUTOSTART (
|
||||
if NOT defined NOAUTOSTART (
|
||||
set TASK_LIST=!TASK_LIST!,AutoStartTask
|
||||
set INSTALLTYPE=CustomInstall
|
||||
)
|
||||
)
|
||||
|
||||
if NOT defined NOCOPYFBLIB (
|
||||
|
||||
@if NOT defined NOCOPYFBLIB (
|
||||
if not defined TASK_LIST (
|
||||
set TASK_LIST=CopyFbClientToSysTask
|
||||
) else (
|
||||
set TASK_LIST=!TASK_LIST!,CopyFbClientToSysTask
|
||||
)
|
||||
set INSTALLTYPE=CustomInstall
|
||||
)
|
||||
|
||||
|
||||
@if defined COPYGDSLIB (
|
||||
if not defined TASK_LIST (
|
||||
set TASK_LIST=CopyFbClientAsGds32Task
|
||||
) else (
|
||||
set TASK_LIST=!TASK_LIST!,CopyFbClientAsGds32Task
|
||||
)
|
||||
set INSTALLTYPE=CustomInstall
|
||||
)
|
||||
@call :PRINT_VARS In %0 - End of set TASK_LIST
|
||||
|
||||
|
||||
:SET_CMD_PARAMS
|
||||
:: set up the CMD_PARAMS variable we will use
|
||||
@ -248,37 +312,40 @@ if NOT defined NOCOPYFBLIB (
|
||||
|
||||
:: Setting PASSWORD is only relevant for a server install
|
||||
@if defined PASSWORD (
|
||||
@if defined SERVER (
|
||||
if defined SERVER_INSTALL (
|
||||
set SYSDBAPASSWORD=%ISC_PASSWORD%
|
||||
set CMD_PARAMS=!CMD_PARAMS! /SYSDBAPASSWORD=%SYSDBAPASSWORD%
|
||||
set INSTALLTYPE=CustomInstall
|
||||
)
|
||||
)
|
||||
|
||||
if defined NOMSG set CMD_PARAMS=!CMD_PARAMS! /SUPPRESSMSGBOXES
|
||||
if defined SILENT set CMD_PARAMS=!CMD_PARAMS! /SILENT
|
||||
if defined SP set CMD_PARAMS=!CMD_PARAMS! /SP-
|
||||
if defined VERYSILENT set CMD_PARAMS=!CMD_PARAMS! /VERYSILENT
|
||||
@if defined NOMSG set CMD_PARAMS=!CMD_PARAMS! /SUPPRESSMSGBOXES
|
||||
@if defined SILENT set CMD_PARAMS=!CMD_PARAMS! /SILENT
|
||||
@if defined SP set CMD_PARAMS=!CMD_PARAMS! /SP-
|
||||
@if defined VERYSILENT set CMD_PARAMS=!CMD_PARAMS! /VERYSILENT
|
||||
|
||||
:: Setting CustomInstall clears the default COMPONENTS list so we
|
||||
:: must define it manually
|
||||
@if /I %INSTALLTYPE% == "CustomInstall" (
|
||||
@if defined CLIENT ( set COMPONENTS=ClientComponent)
|
||||
@if defined DEVINST ( set COMPONENTS=DevAdminComponent,ClientComponent)
|
||||
::echo INSTALLTYPE %INSTALLTYPE%
|
||||
@if /I "%INSTALLTYPE%" == "CustomInstall" (
|
||||
if defined CLIENT ( set COMPONENTS=ClientComponent)
|
||||
if defined DEVINST ( set COMPONENTS=DevAdminComponent,ClientComponent)
|
||||
if defined SERVER_INSTALL ( set COMPONENTS=ServerComponent,DevAdminComponent,ClientComponent)
|
||||
) else (
|
||||
set COMPONENTS=ServerComponent,DevAdminComponent,ClientComponent
|
||||
)
|
||||
|
||||
if defined INSTALL (
|
||||
@if defined INSTALL (
|
||||
if defined TASK_LIST (
|
||||
set FULL_CMD=/TYPE=!INSTALLTYPE! /TASKS="!TASK_LIST!" /COMPONENTS="!COMPONENTS!" !CMD_PARAMS!
|
||||
) else (
|
||||
set FULL_CMD=/TYPE=!INSTALLTYPE! /COMPONENTS="!COMPONENTS!" !CMD_PARAMS!
|
||||
)
|
||||
) else (
|
||||
set FULL_CMD=!CMD_PARAMS!
|
||||
)
|
||||
@call :PRINT_VARS In %0 - After setting COMPONENTS and FULL_CMD
|
||||
|
||||
@if defined VERBOSE (
|
||||
@call :PRINT_VARS
|
||||
if NOT defined DEBUG pause
|
||||
)
|
||||
@if defined DEBUG @echo Leaving %0
|
||||
@call :UNSET_VERBOSE
|
||||
@goto :EOF
|
||||
@ -288,8 +355,10 @@ if defined INSTALL (
|
||||
:PRINT_VARS
|
||||
:: if a variable is not defined we don't print it, except for critical
|
||||
:: variables such as FINALCMD that MUST be defined.
|
||||
@if not defined VERBOSE goto :EOF
|
||||
@if not "%~1" == "" ( echo %* )
|
||||
@echo Variables set during script execution are:
|
||||
@set ADIRNAME
|
||||
@set ADIRNAME 2>nul
|
||||
@set APPTASK 2>nul
|
||||
@set CLASSICSERVER 2>nul
|
||||
@set CLEAN 2>nul
|
||||
@ -299,12 +368,15 @@ if defined INSTALL (
|
||||
@set COPYGDSLIB 2>nul
|
||||
@set DEVINST 2>nul
|
||||
@set DRYRUN 2>nul
|
||||
@set FBINST_EXEC
|
||||
@set FBINST_EXEC 2>nul
|
||||
@set FIREBIRD 2>nul
|
||||
@set FINALCMD 2>nul
|
||||
@set FULL_CMD
|
||||
@set FULL_CMD 2>nul
|
||||
@set FORCE 2>nul
|
||||
@set INTERACTIVE 2>nul
|
||||
@set INSTALL 2>nul
|
||||
@set ISC_USER 2>nul
|
||||
@set ISC_PASSWORD 2>nul
|
||||
@set MERGE_TASKS 2>nul
|
||||
@set NOARCHIVE= 2>nul
|
||||
@set NOAUTOSTART 2>nul
|
||||
@ -315,8 +387,7 @@ if defined INSTALL (
|
||||
@set PASSWORD 2>nul
|
||||
@set RUN_TIMESTAMP 2>nul
|
||||
@set SCRIPTED 2>nul
|
||||
@set SERVICE_TASK 2>nul
|
||||
@set SERVER 2>nul
|
||||
@set SERVER_INSTALL 2>nul
|
||||
@set SERVICE_TASK 2>nul
|
||||
@set SILENT 2>nul
|
||||
@set SP 2>nul
|
||||
@ -327,7 +398,7 @@ if defined INSTALL (
|
||||
@set UNINSTALL 2>nul
|
||||
@set VERYSILENT 2>nul
|
||||
@echo.
|
||||
|
||||
@if NOT defined DEBUG pause
|
||||
@goto :EOF
|
||||
::=======================================================
|
||||
|
||||
@ -336,56 +407,65 @@ if defined INSTALL (
|
||||
@echo.
|
||||
@echo.
|
||||
@call :SET_VERBOSE_IF_DEBUG_ON
|
||||
if defined DEBUG @echo Entering %0 %*
|
||||
::@call :CHECK_ENV || (@echo Check the values in SET_ENV & goto :EOF )
|
||||
@if defined DEBUG @echo Entering %~0 %*
|
||||
@call :CHECK_ENV
|
||||
::@call :RESET_INSTALL_ENV
|
||||
@if defined _err ( goto :EOF)
|
||||
|
||||
@call :GET_OPTS %*
|
||||
@call :SET_PARAMS %*
|
||||
::@call :SET_VERBOSE
|
||||
@if defined VERBOSE @echo on
|
||||
@if defined VERBOSE @echo FULL_CMD is %FULL_CMD%
|
||||
@if defined VERBOSE ( if NOT defined DEBUG pause )
|
||||
@call :TIMESTAMP
|
||||
@if defined DEBUG echo After call TIMESTAMP
|
||||
@set RUN_TIMESTAMP=%TIMESTAMP%
|
||||
@set INSTALL_TIMESTAMP=%TIMESTAMP%
|
||||
@if defined DEBUG echo Before set FINALCMD
|
||||
@set FINALCMD=%FBINST_EXEC% %FULL_CMD% /DIR=%FIREBIRD% /LOG=%FBINSTALLLOGDIR%\install%RUN_TIMESTAMP%.log /SAVEINF=%FBINSTALLLOGDIR%\install%RUN_TIMESTAMP%-saved.inf
|
||||
@if defined DEBUG echo After set FINALCMD
|
||||
|
||||
set FINALCMD=%FBINST_EXEC% %FULL_CMD% /DIR=%FIREBIRD% /LOG=%FBINSTALLLOGDIR%\install%RUN_TIMESTAMP%.log /SAVEINF=%FBINSTALLLOGDIR%\install%RUN_TIMESTAMP%-saved.inf
|
||||
if defined DRYRUN (
|
||||
@if defined DRYRUN (
|
||||
@echo DRYRUN - Not executing call %FINALCMD%
|
||||
) else (
|
||||
@if defined SHOW_FINAL_CMD @echo Executing %FINALCMD%
|
||||
call %FINALCMD%
|
||||
@if defined DEBUG @echo DRYRUN not set
|
||||
@if defined SHOW_FINAL_CMD (@echo Executing %FINALCMD%)
|
||||
@call %FINALCMD%
|
||||
|
||||
@if errorlevel 1 (
|
||||
@if ERRORLEVEL 1 (
|
||||
rem @echo Calling %FBINST_EXEC% failed with %ERRORLEVEL%
|
||||
set _err=%ERRORLEVEL%
|
||||
call :ISS_ERROR %_err% %FBINST_EXEC% %FULL_CMD%
|
||||
@call :ISS_ERROR %_err% %FBINST_EXEC% %FULL_CMD%
|
||||
set /A XRESULT+=1
|
||||
@goto :EOF
|
||||
) else (
|
||||
@echo Calling %FBINST_EXEC%......................SUCCESS!
|
||||
)
|
||||
|
||||
@echo.
|
||||
@echo Now checking system state...
|
||||
if not defined NOCOPYFBLIB (
|
||||
|
||||
@if defined SERVER_INSTALL (
|
||||
call :CHECKSERVICECONFIGURED
|
||||
call :CHECKSERVICEINSTALLED
|
||||
)
|
||||
@if not defined NOCOPYFBLIB (
|
||||
call :CHECKFILEEXISTS c:\windows\system32\fbclient.dll good bad err_is_fail
|
||||
) else (
|
||||
call :CHECKFILEEXISTS c:\windows\system32\fbclient.dll bad good no_err_is_fail
|
||||
)
|
||||
|
||||
if not defined COPYGDSLIB (
|
||||
@if not defined COPYGDSLIB (
|
||||
call :CHECKFILEEXISTS c:\windows\system32\gds32.dll bad good no_err_is_fail
|
||||
) else (
|
||||
call :CHECKFILEEXISTS c:\windows\system32\gds32.dll good bad err_is_fail
|
||||
)
|
||||
@echo.
|
||||
@echo Calling COPY_INSTALL
|
||||
@call :COPY_INSTALL
|
||||
@echo.
|
||||
)
|
||||
@echo.
|
||||
@echo.
|
||||
@echo %0 completed with %XRESULT% errors
|
||||
@set XRESULT=0
|
||||
|
||||
@if defined DEBUG @echo Leaving %0
|
||||
@call :UNSET_VERBOSE
|
||||
@echo.
|
||||
@ -401,12 +481,14 @@ if defined DRYRUN (
|
||||
@call :SET_VERBOSE_IF_DEBUG_ON
|
||||
::@call :SET_VERBOSE
|
||||
@if defined DEBUG @echo Entering %0 %*
|
||||
@if defined NOUNINSTALL ( echo NOUNINSTALL set. Not running uninstaller & exit /b 1)
|
||||
|
||||
::@call :RESET_INSTALL_ENV
|
||||
@call :GET_OPTS %* UNINSTALL
|
||||
@call :SET_PARAMS
|
||||
::@call :SET_VERBOSE
|
||||
@if defined VERBOSE @echo on
|
||||
@if defined VERBOSE call :PRINT_VARS
|
||||
@if defined VERBOSE @call :PRINT_VARS
|
||||
@if defined VERBOSE @echo FULL_CMD is %FULL_CMD%
|
||||
@if defined NOUNINSTALL (
|
||||
@echo NOUNINSTALL was passed. Exiting %0.
|
||||
@ -418,14 +500,14 @@ if defined DRYRUN (
|
||||
@if defined VERBOSE ( if NOT defined DEBUG (pause) )
|
||||
@if defined DRYRUN (
|
||||
echo DRYRUN - Not executing call %FINALCMD%
|
||||
if defined DEBUG @echo Leaving %0
|
||||
@if defined DEBUG @echo Leaving %0
|
||||
@call :UNSET_VERBOSE
|
||||
@echo.
|
||||
@echo.
|
||||
goto :EOF
|
||||
)
|
||||
@if defined SHOW_FINAL_CMD @echo Executing %FINALCMD%
|
||||
call %FINALCMD% 2>nul
|
||||
@call %FINALCMD% 2>nul
|
||||
if errorlevel 1 (
|
||||
set _err=%ERRORLEVEL%
|
||||
) else (
|
||||
@ -433,7 +515,7 @@ if defined DRYRUN (
|
||||
)
|
||||
if %_err% GEQ 1 (
|
||||
set _err=%ERRORLEVEL%
|
||||
call :ISS_ERROR %_err% %UNINSTALLEXE% %FULL_CMD%
|
||||
@call :ISS_ERROR %_err% %UNINSTALLEXE% %FULL_CMD%
|
||||
set /A XRESULT+=1
|
||||
) else (
|
||||
echo Calling %FIREBIRD%\%UNINSTALLEXE% ................SUCCESS!
|
||||
@ -452,23 +534,23 @@ if defined DRYRUN (
|
||||
|
||||
echo.
|
||||
echo Now checking system state...
|
||||
call :CHECKFILEEXISTS c:\windows\system32\fbclient.dll bad good no_err_is_fail
|
||||
call :CHECKFILEEXISTS c:\windows\system32\gds32.dll bad good no_err_is_fail
|
||||
@call :CHECKFILEEXISTS c:\windows\system32\fbclient.dll bad good no_err_is_fail
|
||||
@call :CHECKFILEEXISTS c:\windows\system32\gds32.dll bad good no_err_is_fail
|
||||
|
||||
if defined CLEAN (
|
||||
call :CHECKSHAREDDLLS
|
||||
call :CHECKFILEEXISTS %FIREBIRD% bad good no_err_is_fail
|
||||
@call :CHECKSHAREDDLLS
|
||||
@call :CHECKFILEEXISTS %FIREBIRD% bad good no_err_is_fail
|
||||
)
|
||||
echo.
|
||||
call :COPY_INSTALL
|
||||
@call :COPY_INSTALL
|
||||
echo.
|
||||
)
|
||||
echo.
|
||||
|
||||
echo %0 completed with %XRESULT% errors
|
||||
set XRESULT=0
|
||||
if defined DEBUG @echo Leaving %0
|
||||
call :UNSET_VERBOSE
|
||||
@if defined DEBUG @echo Leaving %0
|
||||
@call :UNSET_VERBOSE
|
||||
@echo.
|
||||
@echo.
|
||||
@goto :EOF
|
||||
@ -477,7 +559,7 @@ call :UNSET_VERBOSE
|
||||
|
||||
::=====================================
|
||||
:CHECKFILEEXISTS
|
||||
if defined DEBUG @echo Entering %0
|
||||
@if defined DEBUG @echo Entering %0
|
||||
@call :SET_VERBOSE_IF_DEBUG_ON
|
||||
|
||||
:: DIR returns an error if file not found and zero if file is returned so we
|
||||
@ -491,66 +573,108 @@ if defined DEBUG @echo Entering %0
|
||||
:: - %3 - string to output if DIR throws an error
|
||||
:: - %4 - flag to indicate if 0 is an error or not
|
||||
::@call :SET_VERBOSE
|
||||
if defined VERBOSE @echo on
|
||||
if defined VERBOSE @echo %*
|
||||
@if defined VERBOSE @echo on
|
||||
@if defined VERBOSE @echo %*
|
||||
dir %1 >nul 2>nul
|
||||
if errorlevel 1 (
|
||||
@if errorlevel 1 (
|
||||
set _err=%ERRORLEVEL%
|
||||
) else (
|
||||
set _err=0
|
||||
)
|
||||
if %_err% EQU 0 (
|
||||
@if %_err% EQU 0 (
|
||||
@echo %TAB% %1 exists - %2 !
|
||||
) else (
|
||||
@echo %TAB% %1 not found - %3 !
|
||||
)
|
||||
|
||||
if "%4"=="err_is_fail" (
|
||||
@if "%4"=="err_is_fail" (
|
||||
if %_err% GTR 0 (
|
||||
set /A XRESULT+=1
|
||||
@echo XRESULT++
|
||||
)
|
||||
)
|
||||
if "%4"=="no_err_is_fail" (
|
||||
@if "%4"=="no_err_is_fail" (
|
||||
if %_err% EQU 0 (
|
||||
set /A XRESULT+=1
|
||||
@echo XRESULT++
|
||||
)
|
||||
)
|
||||
|
||||
call :RESET_ERRORLEVEL
|
||||
@call :RESET_ERRORLEVEL
|
||||
@call :UNSET_VERBOSE
|
||||
if defined DEBUG @echo Leaving %0
|
||||
@if defined DEBUG @echo Leaving %0
|
||||
@goto :EOF
|
||||
::===CHECKFILEEXISTS==================================
|
||||
|
||||
|
||||
::=====================================
|
||||
:CHECKSHAREDDLLS
|
||||
if defined DEBUG @echo Entering %0
|
||||
@if defined DEBUG @echo Entering %0
|
||||
@call :SET_VERBOSE_IF_DEBUG_ON
|
||||
@reg query HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDLLs > %TEMP%\shareddlls.txt
|
||||
@grep --ignore-case --count firebird %TEMP%\shareddlls.txt > %TEMP%\shareddllscount.txt
|
||||
::@grep --ignore-case --count firebird %TEMP%\shareddlls.txt > %TEMP%\shareddllscount.txt
|
||||
type %TEMP%\shareddlls.txt | find /C /I "firebird" > %TEMP%\shareddllscount.txt
|
||||
set /p SHAREDDLLSCOUNT= < %TEMP%\shareddllscount.txt
|
||||
if NOT defined DEBUG del /q %TEMP%\shareddll*.txt
|
||||
if %SHAREDDLLSCOUNT% GTR 0 (
|
||||
@if NOT defined DEBUG del /q %TEMP%\shareddll*.txt
|
||||
@if %SHAREDDLLSCOUNT% GTR 0 (
|
||||
@echo %TAB% Oops - residue in HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDLLs
|
||||
set /A XRESULT+=1
|
||||
@echo XRESULT++
|
||||
)
|
||||
call :RESET_ERRORLEVEL
|
||||
if defined DEBUG @echo Leaving %0
|
||||
@call :RESET_ERRORLEVEL
|
||||
@if defined DEBUG @echo Leaving %0
|
||||
@call :UNSET_VERBOSE
|
||||
@goto :EOF
|
||||
::===CHECKSHAREDDLLS===================
|
||||
|
||||
|
||||
::=====================================
|
||||
:CHECKSERVICECONFIGURED
|
||||
@if defined DEBUG @echo Entering %0
|
||||
@call :SET_VERBOSE_IF_DEBUG_ON
|
||||
|
||||
:: Add test for server arch set in firebird.conf
|
||||
|
||||
if defined CLASSICSERVER ( set STR_TO_TEST="servermode = classic" )
|
||||
if defined SUPERCLASSIC ( set STR_TO_TEST="servermode = superclassic" )
|
||||
if defined SUPERSERVER ( set STR_TO_TEST="servermode = super" )
|
||||
|
||||
call :CHECKSTRING %STR_TO_TEST% %FIREBIRD%\\firebird.conf
|
||||
if ERRORLEVEL 1 (
|
||||
@echo %TAB% %STR_TO_TEST% not set in %FIREBIRD%\\firebird.conf
|
||||
set /A XRESULT+=1
|
||||
@echo XRESULT++
|
||||
)
|
||||
|
||||
@call :RESET_ERRORLEVEL
|
||||
@if defined DEBUG @echo Leaving %0
|
||||
@call :UNSET_VERBOSE
|
||||
@goto :EOF
|
||||
::===CHECKSERVICECONFIGURED===================
|
||||
|
||||
|
||||
|
||||
::=====================================
|
||||
:CHECKSERVICEINSTALLED
|
||||
@if defined DEBUG @echo Entering %0
|
||||
@call :SET_VERBOSE_IF_DEBUG_ON
|
||||
|
||||
%FIREBIRD%\\instsvc.exe q
|
||||
|
||||
|
||||
@call :RESET_ERRORLEVEL
|
||||
@if defined DEBUG @echo Leaving %0
|
||||
@call :UNSET_VERBOSE
|
||||
@goto :EOF
|
||||
::===CHECKSERVICEINSTALLED===================
|
||||
|
||||
|
||||
::=====================================
|
||||
:COPY_INSTALL
|
||||
@call :SET_VERBOSE_IF_DEBUG_ON
|
||||
if defined DEBUG @echo Entering %0
|
||||
@if defined DEBUG @echo Entering %0
|
||||
::@call :SET_VERBOSE
|
||||
if defined VERBOSE @echo on
|
||||
@if defined VERBOSE @echo on
|
||||
|
||||
:: ADIRNAME should normally be set during install and persist for uninstall
|
||||
@if not defined ADIRNAME (
|
||||
@ -590,10 +714,13 @@ if defined VERBOSE @echo on
|
||||
:CHECK_ENV
|
||||
:: TODO - add more checks for the environment declared in SET_GLOBAL_ENV
|
||||
if not exist %FBINST_EXEC% (
|
||||
echo %~0 failed
|
||||
echo Cannot find %FBINST_EXEC%
|
||||
exit /b 1
|
||||
echo Check the setting of FBINST_EXEC
|
||||
set _err=1
|
||||
exit /b %_err%
|
||||
)
|
||||
@goto :EOF
|
||||
goto :EOF
|
||||
::===CHECK_ENV=========================
|
||||
|
||||
::=====================================
|
||||
@ -604,6 +731,7 @@ if not exist %FBINST_EXEC% (
|
||||
:: not have the same value as the internal ERRORLEVEL. We have to execute an
|
||||
:: arbitrary command that cannot fail if we want to really reset the internal
|
||||
:: variable.
|
||||
@set _err=
|
||||
@ver > nul
|
||||
@goto :EOF
|
||||
::===RESET_ERRORLEVEL==================
|
||||
@ -620,12 +748,15 @@ if not exist %FBINST_EXEC% (
|
||||
@goto :EOF
|
||||
::===SET_VERBOSE_IF_DEBUG_ON================
|
||||
|
||||
|
||||
::=====================================
|
||||
:SET_VERBOSE
|
||||
@set VERBOSE=1
|
||||
@echo on
|
||||
@goto :EOF
|
||||
::===SET_VERBOSE================
|
||||
|
||||
|
||||
::=====================================
|
||||
:UNSET_VERBOSE
|
||||
:: Unset VERBOSE before exiting each sub-routine.
|
||||
@ -651,50 +782,131 @@ goto :EOF
|
||||
:ISS_ERROR
|
||||
@echo.
|
||||
@echo InnoSetup ErrorCode %1 from calling %~2 %~3 %~4 %~5 %~6 %~7 %~8 %~9
|
||||
@echo Definition of Innosetup errorcode %1 is to be added later
|
||||
@echo.
|
||||
@if "%1"=="1" (
|
||||
@echo Setup failed to initialize.
|
||||
@echo.
|
||||
@goto :EOF
|
||||
)
|
||||
|
||||
@if "%1"=="2" (
|
||||
@echo The user clicked Cancel in the wizard before the actual installation
|
||||
@echo started, or chose 'No' on the opening 'This will install...' message box.
|
||||
@echo.
|
||||
@goto :EOF
|
||||
)
|
||||
|
||||
@if "%1" == "3" (
|
||||
@echo A fatal error occurred while preparing to move to the next
|
||||
@echo installation phase (for example, from displaying the pre-installation
|
||||
@echo wizard pages to the actual installation process). This should never
|
||||
@echo happen except under the most unusual of circumstances, such as
|
||||
@echo running out of memory or Windows resources.
|
||||
@echo.
|
||||
@goto :EOF
|
||||
)
|
||||
|
||||
@if "%1" == "4" (
|
||||
@echo A fatal error occurred during the actual installation process.
|
||||
@echo.
|
||||
@goto :EOF
|
||||
)
|
||||
|
||||
@if "%1" == "5" (
|
||||
@echo The user clicked Cancel during the actual installation process,
|
||||
@echo or chose Abort at an Abort-Retry-Ignore box.
|
||||
@echo.
|
||||
@goto :EOF
|
||||
)
|
||||
|
||||
@if "%1" == "6" (
|
||||
@echo The Setup process was forcefully terminated by the debugger
|
||||
@echo (Run | Terminate was used in the Compiler IDE).
|
||||
@echo.
|
||||
@goto :EOF
|
||||
)
|
||||
|
||||
@if "%1" == "7" (
|
||||
@echo The Preparing to Install stage determined that Setup cannot proceed
|
||||
@echo with installation. (First introduced in Inno Setup 5.4.1.)
|
||||
@echo.
|
||||
@goto :EOF
|
||||
)
|
||||
|
||||
@if "%1" == "8" (
|
||||
@echo The Preparing to Install stage determined that Setup cannot proceed
|
||||
@echo with installation, and that the system needs to be restarted in
|
||||
@echo order to correct the problem. (First introduced in Inno Setup 5.4.1.)
|
||||
@echo.
|
||||
@goto :EOF
|
||||
)
|
||||
@echo.
|
||||
@goto :EOF
|
||||
::======================================
|
||||
|
||||
::================================================================================================================
|
||||
:: GENERIC SUPPORT ROUTINES FROM HERE TO END ======================================================================
|
||||
::================================================================================================================
|
||||
::==============================================================================
|
||||
:: GENERIC SUPPORT ROUTINES FROM HERE TO END ==================================
|
||||
::==============================================================================
|
||||
|
||||
|
||||
::=====================================
|
||||
:CHECKSTRING
|
||||
@if defined DEBUG @echo Entering %0
|
||||
@call :SET_VERBOSE_IF_DEBUG_ON
|
||||
::@if defined VERBOSE echo %0 - %*
|
||||
for %%v in ( %* ) do (
|
||||
if /I "%%v"=="" ( @goto :EOF )
|
||||
)
|
||||
:: === NOTE ====
|
||||
:: We use the /x flag here for an exact match!
|
||||
@if defined VERBOSE echo calling findstr /x /c:%1 /i %2
|
||||
:: findstr /x /c:"servermode = superclassic" /i Firebird_4_0\firebird.conf
|
||||
findstr /x /c:%1 /i %2
|
||||
|
||||
@call :RESET_ERRORLEVEL
|
||||
@if defined DEBUG @echo Leaving %0
|
||||
@call :UNSET_VERBOSE
|
||||
@goto :EOF
|
||||
::===CHECKSTRING===================
|
||||
|
||||
|
||||
|
||||
::=====================================
|
||||
:GET_DATE
|
||||
if NOT defined DEBUG @echo off
|
||||
echo. | date | FIND "(mm" > NUL
|
||||
if errorlevel 1 ((set MD=0) & call :ParseDate DD MM) else ((set MD=1) & call :ParseDate MM DD)
|
||||
@if NOT defined DEBUG @echo off
|
||||
@echo. | date | FIND "(mm" > NUL
|
||||
@if errorlevel 1 ((set MD=0) & call :ParseDate DD MM) else ((set MD=1) & call :ParseDate MM DD)
|
||||
@goto :EOF
|
||||
:ParseDate
|
||||
for /f "tokens=1-3 delims=/.- " %%a in ("%DATE%") do (
|
||||
set %1=%%a
|
||||
set %2=%%b
|
||||
set YYYY=%%c
|
||||
@for /f "tokens=1-3 delims=/.- " %%a in ("%DATE%") do (
|
||||
@set %1=%%a
|
||||
@set %2=%%b
|
||||
@set YYYY=%%c
|
||||
@goto:EOF)
|
||||
::=====================================
|
||||
|
||||
::=====================================
|
||||
:GET_TIME
|
||||
if NOT defined DEBUG @echo off
|
||||
for /f "tokens=1-4 delims=:. " %%a in ("%TIME%") do (
|
||||
set hh=%%a
|
||||
set nn=%%b
|
||||
set ss=%%c
|
||||
set ms=%%d
|
||||
@if NOT defined DEBUG @echo off
|
||||
@for /f "tokens=1-4 delims=:. " %%a in ("%TIME%") do (
|
||||
@set hh=%%a
|
||||
@set nn=%%b
|
||||
@set ss=%%c
|
||||
@set ms=%%d
|
||||
@goto :EOF)
|
||||
::=====================================
|
||||
|
||||
::=====================================
|
||||
:CLEAR_DT_VARS
|
||||
if NOT defined DEBUG @echo off
|
||||
set MM=
|
||||
set DD=
|
||||
set YYYY=
|
||||
set hh=
|
||||
set nn=
|
||||
set ss=
|
||||
set ms=
|
||||
@if NOT defined DEBUG @echo off
|
||||
@set MM=
|
||||
@set DD=
|
||||
@set YYYY=
|
||||
@set hh=
|
||||
@set nn=
|
||||
@set ss=
|
||||
@set ms=
|
||||
@if defined DEBUG @echo Leaving CLEAR_DT_VARS
|
||||
@goto :EOF
|
||||
::=====================================
|
||||
|
||||
@ -703,8 +915,8 @@ set ms=
|
||||
@call :GET_DATE
|
||||
@call :GET_TIME
|
||||
@set TIMESTAMP=%YYYY%%MM%%DD%%hh%%nn%%ss%
|
||||
if defined DEBUG (@echo Timestamp set to %TIMESTAMP%)
|
||||
call :CLEAR_DT_VARS
|
||||
@if defined DEBUG (@echo Timestamp set to %TIMESTAMP%)
|
||||
@call :CLEAR_DT_VARS
|
||||
@goto :EOF
|
||||
::=====================================
|
||||
|
||||
@ -724,25 +936,22 @@ call :CLEAR_DT_VARS
|
||||
|
||||
:: sometimes it is useful to just tidy up!
|
||||
@if /I "%1"=="clean" (
|
||||
@call :RUN_UNINSTALLER SCRIPTED CLEAN
|
||||
@goto :EOF
|
||||
@set NOUNINSTALL=
|
||||
call :RUN_UNINSTALLER SCRIPTED CLEAN
|
||||
goto :EOF
|
||||
)
|
||||
|
||||
@call :RUN_INSTALLER %*
|
||||
@if defined _err ( echo _err is %_err% - quitting. && @goto :EOF)
|
||||
|
||||
@call :RUN_UNINSTALLER %*
|
||||
|
||||
|
||||
@if defined DEBUG @echo Leaving %0
|
||||
@call :UNSET_VERBOSE
|
||||
@goto :EOF
|
||||
::===MAIN==============================
|
||||
|
||||
:: CONTINUE with
|
||||
:: - look at setting up different test recipes and naming them.
|
||||
:: - Integrate innosetup exit codes and look at error handling
|
||||
:: - Tidy up the relationship between DEBUG and VERBOSE.
|
||||
:: - DEBUG should turn on VERBOSE?
|
||||
:: - VERBOSE should be routine specific.?
|
||||
:: - DEBUG should persist for entire script run?
|
||||
|
||||
|
||||
:: NOTHING BEYOND THIS POINT===========
|
||||
|
@ -41,9 +41,8 @@
|
||||
#
|
||||
# String
|
||||
# ------
|
||||
# Strings are also what they sound like, strings. Examples:
|
||||
# Strings are also what they sound like, strings. Example:
|
||||
# RemoteServiceName = gds_db
|
||||
# RemotePipeName = pipe47
|
||||
#
|
||||
# Scopes
|
||||
# ------
|
||||
@ -612,6 +611,18 @@
|
||||
#ConnectionIdleTimeout = 0
|
||||
|
||||
|
||||
# ----------------------------
|
||||
#
|
||||
# Set number of seconds after which ON DISCONNECT trigger execution will be
|
||||
# automatically cancelled by the engine. Zero means no timeout is set.
|
||||
#
|
||||
# Per-database configurable.
|
||||
#
|
||||
# Type: integer
|
||||
#
|
||||
#OnDisconnectTriggerTimeout = 180
|
||||
|
||||
|
||||
# ----------------------------
|
||||
#
|
||||
# How often the pages are flushed on disk
|
||||
@ -1020,6 +1031,19 @@
|
||||
#GCPolicy = combined
|
||||
|
||||
|
||||
# ----------------------------
|
||||
# Maximum statement cache size
|
||||
#
|
||||
# The maximum amount of RAM used to cache unused DSQL compiled statements.
|
||||
# If set to 0 (zero), statement cache is disabled.
|
||||
#
|
||||
# Per-database configurable.
|
||||
#
|
||||
# Type: integer
|
||||
#
|
||||
#MaxStatementCacheSize = 2M
|
||||
|
||||
|
||||
# ----------------------------
|
||||
# Security database
|
||||
#
|
||||
@ -1083,18 +1107,6 @@
|
||||
#
|
||||
#IpcName = FIREBIRD
|
||||
|
||||
#
|
||||
# The name of the pipe used as a transport channel in NetBEUI protocol.
|
||||
# Has the same meaning as a port number for TCP/IP. The default value is
|
||||
# compatible with IB/FB1.
|
||||
#
|
||||
# Per-connection configurable.
|
||||
#
|
||||
# Type: string
|
||||
#
|
||||
#RemotePipeName = interbas
|
||||
|
||||
|
||||
# ============================
|
||||
# Settings for Unix/Linux platforms
|
||||
# ============================
|
||||
|
@ -4881,16 +4881,6 @@
|
||||
path = old_proto.h;
|
||||
refType = 4;
|
||||
};
|
||||
F616C66F0200B0CF01EF0ADE = {
|
||||
isa = PBXFileReference;
|
||||
path = opt.cpp;
|
||||
refType = 4;
|
||||
};
|
||||
F616C6700200B0CF01EF0ADE = {
|
||||
isa = PBXFileReference;
|
||||
path = opt_proto.h;
|
||||
refType = 4;
|
||||
};
|
||||
F616C6710200B0CF01EF0ADE = {
|
||||
children = (
|
||||
F616C6720200B0CF01EF0ADE,
|
||||
@ -5133,11 +5123,6 @@
|
||||
path = rse.cpp;
|
||||
refType = 4;
|
||||
};
|
||||
F616C6A70200B0D001EF0ADE = {
|
||||
isa = PBXFileReference;
|
||||
path = rse.h;
|
||||
refType = 4;
|
||||
};
|
||||
F616C6A80200B0D001EF0ADE = {
|
||||
isa = PBXFileReference;
|
||||
path = rse_proto.h;
|
||||
@ -6767,16 +6752,6 @@
|
||||
path = winvx.cpp;
|
||||
refType = 4;
|
||||
};
|
||||
F616C8C00200B0D001EF0ADE = {
|
||||
isa = PBXFileReference;
|
||||
path = wnet.cpp;
|
||||
refType = 4;
|
||||
};
|
||||
F616C8C10200B0D001EF0ADE = {
|
||||
isa = PBXFileReference;
|
||||
path = wnet_proto.h;
|
||||
refType = 4;
|
||||
};
|
||||
F616C8C20200B0D001EF0ADE = {
|
||||
isa = PBXFileReference;
|
||||
path = xdr.cpp;
|
||||
|
@ -124,6 +124,9 @@ $(EXAMPLES_FB)/README:
|
||||
$(CP) $(ROOT)/examples/stat/*.* $(EXAMPLES_FB)/stat/
|
||||
$(CP) $(ROOT)/examples/udf/*.* $(EXAMPLES_FB)/udf/
|
||||
$(CP) $(ROOT)/examples/udr/*.* $(EXAMPLES_FB)/udr/
|
||||
$(CP) $(ROOT)/examples/object_pascal/*.* $(EXAMPLES_FB)/object_pascal/
|
||||
$(CP) $(ROOT)/examples/object_pascal/[mM]ake* $(EXAMPLES_FB)/object_pascal/
|
||||
$(CP) $(ROOT)/examples/object_pascal/common/*.* $(EXAMPLES_FB)/object_pascal/common/
|
||||
# $(CP) intlemp.fdb $(EXAMPLES_FB)/empbuild/
|
||||
$(CP) $(ROOT)/examples/readme $(EXAMPLES_FB)/README
|
||||
$(CP) $(ROOT)/examples/empbuild/employe2.sql $(EXAMPLES_FB)/empbuild/
|
||||
|
@ -27,5 +27,6 @@
|
||||
|
||||
LD_lookup_charset
|
||||
LD_lookup_texttype
|
||||
LD_lookup_texttype_with_status
|
||||
LD_setup_attributes
|
||||
LD_version
|
||||
|
@ -77,7 +77,7 @@ AllObjects += $(Chacha_Objects)
|
||||
|
||||
# Engine
|
||||
Engine_Objects:= $(call dirObjects,jrd) $(call dirObjects,dsql) $(call dirObjects,jrd/extds) \
|
||||
$(call dirObjects,jrd/recsrc) $(call dirObjects,jrd/replication) $(call dirObjects,jrd/trace) \
|
||||
$(call dirObjects,jrd/optimizer) $(call dirObjects,jrd/recsrc) $(call dirObjects,jrd/replication) $(call dirObjects,jrd/trace) \
|
||||
$(call makeObjects,lock,lock.cpp)
|
||||
|
||||
AllObjects += $(Engine_Objects)
|
||||
|
49
builds/posix/prefix.darwin_aarch64
Normal file
49
builds/posix/prefix.darwin_aarch64
Normal file
@ -0,0 +1,49 @@
|
||||
# The contents of this file are subject to the Interbase 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.Inprise.com/IPL.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 Original Code was created by Inprise Corporation
|
||||
# and its predecessors. Portions created by Inprise Corporation are
|
||||
#
|
||||
# Copyright (C) 2000 Inprise Corporation
|
||||
# All Rights Reserved.
|
||||
# Contributor(s): ______________________________________.
|
||||
# Start of file prefix.darwin: $(VERSION) @PLATFORM@
|
||||
# 2 Oct 2002, Nickolay Samofatov - Major Cleanup
|
||||
#
|
||||
# Default build from 10.9 using Clang
|
||||
#
|
||||
# Build instructions
|
||||
# set CFLAGS='-I (ICUDIR)/icu/source/common' (ucnv.h)
|
||||
# set LDFLAGS='-L(ICUDIR)/icu/source/lib' (-licuuc)
|
||||
# set CXXFLAGS='-I (ICUDIR)/icu/source/common -I ICUDIR/icu/source/i18n'
|
||||
# where ICUDIR is where you installed ICU
|
||||
# configure using --with-builtin-tommath
|
||||
# or add the relevant -I, -L for an installed version of libtommath
|
||||
|
||||
#DYLD_PRINT_ENV=1
|
||||
#export DYLD_PRINT_ENV
|
||||
|
||||
#DYLD_PRINT_LIBRARIES=1
|
||||
#export DYLD_PRINT_LIBRARIES
|
||||
|
||||
MACOSX_DEPLOYMENT_TARGET=12.0
|
||||
export MACOSX_DEPLOYMENT_TARGET
|
||||
|
||||
PROD_FLAGS=-DDARWIN -DARM64 -pipe -O2 -MMD -fPIC -fno-common -mmacosx-version-min=12.0
|
||||
DEV_FLAGS=-ggdb -DDARWIN -DARM64 -pipe -MMD -fPIC -fno-omit-frame-pointer -fno-common -Wall -fno-optimize-sibling-calls -mmacosx-version-min=12.0 -Wno-non-virtual-dtor
|
||||
CXXFLAGS:=$(CXXFLAGS) -fvisibility-inlines-hidden -fvisibility=hidden -stdlib=libc++
|
||||
|
||||
UNDEF_PLATFORM=
|
||||
|
||||
LINK_LIBS+=-liconv
|
||||
#MATHLIB=$(ROOT)/extern/libtommath/.libs/libtommath.a
|
||||
SO_LINK_LIBS+=-liconv
|
||||
|
||||
include $(ROOT)/gen/darwin.defaults
|
@ -124,6 +124,7 @@
|
||||
<ClInclude Include="..\..\..\src\common\classes\ClumpletWriter.h" />
|
||||
<ClInclude Include="..\..\..\src\common\classes\condition.h" />
|
||||
<ClInclude Include="..\..\..\src\common\classes\DbImplementation.h" />
|
||||
<ClInclude Include="..\..\..\src\common\classes\DoublyLinkedList.h" />
|
||||
<ClInclude Include="..\..\..\src\common\classes\fb_atomic.h" />
|
||||
<ClInclude Include="..\..\..\src\common\classes\fb_pair.h" />
|
||||
<ClInclude Include="..\..\..\src\common\classes\fb_string.h" />
|
||||
|
@ -392,6 +392,9 @@
|
||||
<ClInclude Include="..\..\..\src\common\classes\DbImplementation.h">
|
||||
<Filter>headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\src\common\classes\DoublyLinkedList.h">
|
||||
<Filter>headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\src\common\classes\fb_atomic.h">
|
||||
<Filter>headers</Filter>
|
||||
</ClInclude>
|
||||
|
@ -41,6 +41,9 @@
|
||||
<ClCompile Include="..\..\..\src\dsql\DsqlCompilerScratch.cpp" />
|
||||
<ClCompile Include="..\..\..\src\dsql\DsqlCursor.cpp" />
|
||||
<ClCompile Include="..\..\..\src\dsql\DSqlDataTypeUtil.cpp" />
|
||||
<ClCompile Include="..\..\..\src\dsql\DsqlRequests.cpp" />
|
||||
<ClCompile Include="..\..\..\src\dsql\DsqlStatementCache.cpp" />
|
||||
<ClCompile Include="..\..\..\src\dsql\DsqlStatements.cpp" />
|
||||
<ClCompile Include="..\..\..\src\dsql\errd.cpp" />
|
||||
<ClCompile Include="..\..\..\src\dsql\ExprNodes.cpp" />
|
||||
<ClCompile Include="..\..\..\src\dsql\gen.cpp" />
|
||||
@ -90,7 +93,6 @@
|
||||
<ClCompile Include="..\..\..\src\jrd\IntlManager.cpp" />
|
||||
<ClCompile Include="..\..\..\src\jrd\intl_builtin.cpp" />
|
||||
<ClCompile Include="..\..\..\src\jrd\jrd.cpp" />
|
||||
<ClCompile Include="..\..\..\src\jrd\JrdStatement.cpp" />
|
||||
<ClCompile Include="..\..\..\src\jrd\KeywordsTable.cpp" />
|
||||
<ClCompile Include="..\..\..\src\jrd\lck.cpp" />
|
||||
<ClCompile Include="..\..\..\src\jrd\Mapping.cpp" />
|
||||
@ -100,8 +102,9 @@
|
||||
<ClCompile Include="..\..\..\src\jrd\nbak.cpp" />
|
||||
<ClCompile Include="..\..\..\src\jrd\nodebug.cpp" />
|
||||
<ClCompile Include="..\..\..\src\jrd\ods.cpp" />
|
||||
<ClCompile Include="..\..\..\src\jrd\opt.cpp" />
|
||||
<ClCompile Include="..\..\..\src\jrd\Optimizer.cpp" />
|
||||
<ClCompile Include="..\..\..\src\jrd\optimizer\Optimizer.cpp" />
|
||||
<ClCompile Include="..\..\..\src\jrd\optimizer\Retrieval.cpp" />
|
||||
<ClCompile Include="..\..\..\src\jrd\optimizer\InnerJoin.cpp" />
|
||||
<ClCompile Include="..\..\..\src\jrd\os\win32\winnt.cpp" />
|
||||
<ClCompile Include="..\..\..\src\jrd\pag.cpp" />
|
||||
<ClCompile Include="..\..\..\src\jrd\par.cpp" />
|
||||
@ -152,6 +155,7 @@
|
||||
<ClCompile Include="..\..\..\src\jrd\shut.cpp" />
|
||||
<ClCompile Include="..\..\..\src\jrd\sort.cpp" />
|
||||
<ClCompile Include="..\..\..\src\jrd\sqz.cpp" />
|
||||
<ClCompile Include="..\..\..\src\jrd\Statement.cpp" />
|
||||
<ClCompile Include="..\..\..\src\jrd\svc.cpp" />
|
||||
<ClCompile Include="..\..\..\src\jrd\SysFunction.cpp" />
|
||||
<ClCompile Include="..\..\..\src\jrd\SystemPackages.cpp" />
|
||||
@ -186,6 +190,9 @@
|
||||
<ClInclude Include="..\..\..\src\dsql\DsqlCompilerScratch.h" />
|
||||
<ClInclude Include="..\..\..\src\dsql\DsqlCursor.h" />
|
||||
<ClInclude Include="..\..\..\src\dsql\DSqlDataTypeUtil.h" />
|
||||
<ClInclude Include="..\..\..\src\dsql\DsqlRequests.h" />
|
||||
<ClInclude Include="..\..\..\src\dsql\DsqlStatementCache.h" />
|
||||
<ClInclude Include="..\..\..\src\dsql\DsqlStatements.h" />
|
||||
<ClInclude Include="..\..\..\src\dsql\dsql_proto.h" />
|
||||
<ClInclude Include="..\..\..\src\dsql\errd_proto.h" />
|
||||
<ClInclude Include="..\..\..\src\dsql\ExprNodes.h" />
|
||||
@ -275,7 +282,6 @@
|
||||
<ClInclude Include="..\..\..\src\jrd\irq.h" />
|
||||
<ClInclude Include="..\..\..\src\jrd\isc_version.h" />
|
||||
<ClInclude Include="..\..\..\src\jrd\jrd.h" />
|
||||
<ClInclude Include="..\..\..\src\jrd\JrdStatement.h" />
|
||||
<ClInclude Include="..\..\..\src\jrd\jrd_proto.h" />
|
||||
<ClInclude Include="..\..\..\src\jrd\KeywordsTable.h" />
|
||||
<ClInclude Include="..\..\..\src\jrd\lck.h" />
|
||||
@ -296,8 +302,7 @@
|
||||
<ClInclude Include="..\..\..\src\jrd\obj.h" />
|
||||
<ClInclude Include="..\..\..\src\jrd\ods.h" />
|
||||
<ClInclude Include="..\..\..\src\jrd\ods_proto.h" />
|
||||
<ClInclude Include="..\..\..\src\jrd\Optimizer.h" />
|
||||
<ClInclude Include="..\..\..\src\jrd\opt_proto.h" />
|
||||
<ClInclude Include="..\..\..\src\jrd\optimizer\Optimizer.h" />
|
||||
<ClInclude Include="..\..\..\src\jrd\pag.h" />
|
||||
<ClInclude Include="..\..\..\src\jrd\pag_proto.h" />
|
||||
<ClInclude Include="..\..\..\src\jrd\par_proto.h" />
|
||||
@ -317,7 +322,6 @@
|
||||
<ClInclude Include="..\..\..\src\jrd\rlck_proto.h" />
|
||||
<ClInclude Include="..\..\..\src\jrd\Routine.h" />
|
||||
<ClInclude Include="..\..\..\src\jrd\rpb_chain.h" />
|
||||
<ClInclude Include="..\..\..\src\jrd\rse.h" />
|
||||
<ClInclude Include="..\..\..\src\jrd\RuntimeStatistics.h" />
|
||||
<ClInclude Include="..\..\..\src\jrd\sbm.h" />
|
||||
<ClInclude Include="..\..\..\src\jrd\scl.h" />
|
||||
@ -327,6 +331,7 @@
|
||||
<ClInclude Include="..\..\..\src\jrd\shut_proto.h" />
|
||||
<ClInclude Include="..\..\..\src\jrd\sort.h" />
|
||||
<ClInclude Include="..\..\..\src\jrd\sqz.h" />
|
||||
<ClInclude Include="..\..\..\src\jrd\Statement.h" />
|
||||
<ClInclude Include="..\..\..\src\jrd\status.h" />
|
||||
<ClInclude Include="..\..\..\src\jrd\svc.h" />
|
||||
<ClInclude Include="..\..\..\src\jrd\svc_undoc.h" />
|
||||
|
@ -43,6 +43,9 @@
|
||||
<Filter Include="Replication">
|
||||
<UniqueIdentifier>{686cba10-1e4f-44f7-b044-972ef8327197}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Optimizer">
|
||||
<UniqueIdentifier>{4acc7c23-ac25-4311-a075-813ed730cb40}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\..\src\jrd\recsrc\WindowedStream.cpp">
|
||||
@ -138,6 +141,15 @@
|
||||
<ClCompile Include="..\..\..\src\dsql\DSqlDataTypeUtil.cpp">
|
||||
<Filter>DSQL</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\src\dsql\DsqlRequests.cpp">
|
||||
<Filter>DSQL</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\src\dsql\DsqlStatementCache.cpp">
|
||||
<Filter>DSQL</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\src\dsql\DsqlStatements.cpp">
|
||||
<Filter>DSQL</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\src\dsql\errd.cpp">
|
||||
<Filter>DSQL</Filter>
|
||||
</ClCompile>
|
||||
@ -288,9 +300,6 @@
|
||||
<ClCompile Include="..\..\..\src\jrd\jrd.cpp">
|
||||
<Filter>JRD files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\src\jrd\JrdStatement.cpp">
|
||||
<Filter>JRD files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\src\jrd\KeywordsTable.cpp">
|
||||
<Filter>JRD files</Filter>
|
||||
</ClCompile>
|
||||
@ -312,12 +321,6 @@
|
||||
<ClCompile Include="..\..\..\src\jrd\ods.cpp">
|
||||
<Filter>JRD files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\src\jrd\opt.cpp">
|
||||
<Filter>JRD files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\src\jrd\Optimizer.cpp">
|
||||
<Filter>JRD files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\src\jrd\pag.cpp">
|
||||
<Filter>JRD files</Filter>
|
||||
</ClCompile>
|
||||
@ -363,6 +366,9 @@
|
||||
<ClCompile Include="..\..\..\src\jrd\sqz.cpp">
|
||||
<Filter>JRD files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\src\jrd\Statement.cpp">
|
||||
<Filter>JRD files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\src\jrd\svc.cpp">
|
||||
<Filter>JRD files</Filter>
|
||||
</ClCompile>
|
||||
@ -507,6 +513,15 @@
|
||||
<ClCompile Include="..\..\..\src\jrd\MetaName.cpp">
|
||||
<Filter>JRD files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\src\jrd\optimizer\InnerJoin.cpp">
|
||||
<Filter>Optimizer</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\src\jrd\optimizer\Optimizer.cpp">
|
||||
<Filter>Optimizer</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\src\jrd\optimizer\Retrieval.cpp">
|
||||
<Filter>Optimizer</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\..\src\jrd\recsrc\RecordSource.h">
|
||||
@ -545,6 +560,15 @@
|
||||
<ClInclude Include="..\..\..\src\dsql\DSqlDataTypeUtil.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\src\dsql\DsqlRequests.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\src\dsql\DsqlStatementCache.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\src\dsql\DsqlStatements.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\src\dsql\errd_proto.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
@ -827,9 +851,6 @@
|
||||
<ClInclude Include="..\..\..\src\jrd\jrd_proto.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\src\jrd\JrdStatement.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\src\jrd\KeywordsTable.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
@ -878,10 +899,7 @@
|
||||
<ClInclude Include="..\..\..\src\jrd\ods_proto.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\src\jrd\opt_proto.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\src\jrd\Optimizer.h">
|
||||
<ClInclude Include="..\..\..\src\jrd\optimizer\Optimizer.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\src\jrd\pag.h">
|
||||
@ -932,9 +950,6 @@
|
||||
<ClInclude Include="..\..\..\src\jrd\rpb_chain.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\src\jrd\rse.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\src\jrd\RuntimeStatistics.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
@ -962,6 +977,9 @@
|
||||
<ClInclude Include="..\..\..\src\jrd\sqz.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\src\jrd\Statement.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\src\jrd\status.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
|
@ -157,7 +157,6 @@
|
||||
<ClCompile Include="..\..\..\src\remote\parser.cpp" />
|
||||
<ClCompile Include="..\..\..\src\remote\protocol.cpp" />
|
||||
<ClCompile Include="..\..\..\src\remote\remote.cpp" />
|
||||
<ClCompile Include="..\..\..\src\remote\os\win32\wnet.cpp" />
|
||||
<ClCompile Include="..\..\..\src\auth\trusted\AuthSspi.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@ -165,7 +164,6 @@
|
||||
<ClInclude Include="..\..\..\src\auth\SecureRemotePassword\srp.h" />
|
||||
<ClInclude Include="..\..\..\src\remote\inet_proto.h" />
|
||||
<ClInclude Include="..\..\..\src\remote\merge_proto.h" />
|
||||
<ClInclude Include="..\..\..\src\remote\os\win32\wnet_proto.h" />
|
||||
<ClInclude Include="..\..\..\src\remote\os\win32\xnet.h" />
|
||||
<ClInclude Include="..\..\..\src\remote\os\win32\xnet_proto.h" />
|
||||
<ClInclude Include="..\..\..\src\remote\parse_proto.h" />
|
||||
|
@ -29,9 +29,6 @@
|
||||
<ClCompile Include="..\..\..\src\remote\remote.cpp">
|
||||
<Filter>REMOTE files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\src\remote\os\win32\wnet.cpp">
|
||||
<Filter>REMOTE files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\src\auth\trusted\AuthSspi.cpp">
|
||||
<Filter>AUTH files</Filter>
|
||||
</ClCompile>
|
||||
@ -64,9 +61,6 @@
|
||||
<ClInclude Include="..\..\..\src\remote\remote.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\src\remote\os\win32\wnet_proto.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\src\remote\os\win32\xnet.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
|
39
configure.ac
39
configure.ac
@ -86,6 +86,20 @@ dnl Test for special ar options?
|
||||
AR_OPT_CHECK=false
|
||||
|
||||
case "$build" in
|
||||
aarch64-*-darwin*)
|
||||
MAKEFILE_PREFIX=darwin_aarch64
|
||||
MAKEFILE_POSTFIX=darwin
|
||||
PLATFORM=DARWIN
|
||||
INSTALL_PREFIX=darwin
|
||||
AC_DEFINE(DARWIN, 1, [Define this if OS is DARWIN])
|
||||
XE_APPEND(-framework CoreFoundation,LIBS)
|
||||
EDITLINE_FLG=Y
|
||||
SHRLIB_EXT=dylib
|
||||
CPU_TYPE=ARM64
|
||||
EXPORT_SYMBOLS_STYLE=darwin
|
||||
RAW_DEVICES_FLG=N
|
||||
;;
|
||||
|
||||
x*64-*-darwin*)
|
||||
MAKEFILE_PREFIX=darwin_x86_64
|
||||
MAKEFILE_POSTFIX=darwin
|
||||
@ -1049,7 +1063,7 @@ AC_MSG_CHECKING(for working sem_init())
|
||||
AC_RUN_IFELSE([AC_LANG_SOURCE([[#include <semaphore.h>
|
||||
main () {
|
||||
sem_t s;
|
||||
exit(sem_init(&s,0,0));
|
||||
return sem_init(&s,0,0);
|
||||
}
|
||||
]])],[AC_DEFINE(WORKING_SEM_INIT,1,[Define this if sem_init() works on the platform])
|
||||
AC_MSG_RESULT(yes)],[AC_MSG_RESULT(no)
|
||||
@ -1089,7 +1103,7 @@ if test "$ac_cv_sys_file_offset_bits" = "no"; then
|
||||
AC_MSG_CHECKING(for native large file support)
|
||||
AC_RUN_IFELSE([AC_LANG_SOURCE([[#include <unistd.h>
|
||||
main () {
|
||||
exit(!(sizeof(off_t) == 8));
|
||||
return !(sizeof(off_t) == 8);
|
||||
}]])],[ac_cv_sys_file_offset_bits=64; AC_DEFINE(_FILE_OFFSET_BITS,64)
|
||||
AC_MSG_RESULT(yes)],[AC_MSG_RESULT(no)],[])
|
||||
fi
|
||||
@ -1140,7 +1154,7 @@ main () {
|
||||
char a;
|
||||
union { long long x; sem_t y; } b;
|
||||
};
|
||||
exit((int)&((struct s*)0)->b);
|
||||
return (int)&((struct s*)0)->b;
|
||||
}]])],[ac_cv_c_alignment=$ac_status],[ac_cv_c_alignment=$ac_status],[])
|
||||
AC_MSG_RESULT($ac_cv_c_alignment)
|
||||
AC_DEFINE_UNQUOTED(FB_ALIGNMENT, $ac_cv_c_alignment, [Alignment of long])
|
||||
@ -1151,7 +1165,7 @@ AC_RUN_IFELSE([AC_LANG_SOURCE([[main () {
|
||||
char a;
|
||||
double b;
|
||||
};
|
||||
exit((int)&((struct s*)0)->b);
|
||||
return (int)&((struct s*)0)->b;
|
||||
}]])],[ac_cv_c_double_align=$ac_status],[ac_cv_c_double_align=$ac_status],[])
|
||||
AC_MSG_RESULT($ac_cv_c_double_align)
|
||||
AC_DEFINE_UNQUOTED(FB_DOUBLE_ALIGN, $ac_cv_c_double_align, [Alignment of double])
|
||||
@ -1168,7 +1182,7 @@ static int abs64Compare(SINT64 n1, SINT64 n2) {
|
||||
return n1 == n2 ? 0 : n1 < n2 ? 1 : -1;
|
||||
}
|
||||
int main() {
|
||||
exit (abs64Compare(-9223372036854775808, 3652058) == 1 ? 0 : 1);
|
||||
return abs64Compare(-9223372036854775808, 3652058) == 1 ? 0 : 1;
|
||||
}]])],[ac_cv_compare_failed=0
|
||||
ac_cv_compare_result=success])
|
||||
CFLAGS="$savedflags"
|
||||
@ -1222,15 +1236,6 @@ case "$PLATFORM" in
|
||||
;;
|
||||
|
||||
win32)
|
||||
FB_PIPE_NAME=interbas
|
||||
AC_ARG_WITH(pipe-name,
|
||||
[ --with-pipe-name specify wnet pipe name (default=interbas)],
|
||||
[FB_PIPE_NAME=${withval}])
|
||||
AH_VERBATIM(FB_PIPE_NAME,
|
||||
[/* Wnet pipe name */
|
||||
#define FB_PIPE_NAME "interbas"])
|
||||
AC_DEFINE_UNQUOTED(FB_PIPE_NAME,"$FB_PIPE_NAME")
|
||||
AC_SUBST(FB_PIPE_NAME)
|
||||
XE_PREPEND( -mthreads -lmpr -lversion -lws2_32 -lole32,LIBS)
|
||||
;;
|
||||
|
||||
@ -1294,6 +1299,8 @@ dnl # output
|
||||
mkdir -p gen/\$fb_tgt/firebird/examples/extauth
|
||||
mkdir -p gen/\$fb_tgt/firebird/examples/include
|
||||
mkdir -p gen/\$fb_tgt/firebird/examples/interfaces
|
||||
mkdir -p gen/\$fb_tgt/firebird/examples/object_pascal
|
||||
mkdir -p gen/\$fb_tgt/firebird/examples/object_pascal/common
|
||||
mkdir -p gen/\$fb_tgt/firebird/examples/package
|
||||
mkdir -p gen/\$fb_tgt/firebird/examples/stat
|
||||
mkdir -p gen/\$fb_tgt/firebird/examples/udf
|
||||
@ -1503,10 +1510,6 @@ esac
|
||||
echo " Service name : $FB_SERVICE_NAME"
|
||||
echo " Service port : $FB_SERVICE_PORT"
|
||||
|
||||
case "$PLATFORM" in
|
||||
win32) echo " Pipe name : $FB_PIPE_NAME";;
|
||||
esac
|
||||
|
||||
echo " GPRE modules : c_cxx.cpp$GPRE_LANGUAGE_MODULES"
|
||||
echo
|
||||
|
||||
|
@ -94,9 +94,8 @@ you only use 0/1
|
||||
|
||||
String
|
||||
------
|
||||
Strings are also what they sound like, strings. Examples:
|
||||
Strings are also what they sound like, strings. Example:
|
||||
RootDirectory = /opt/firebird
|
||||
RemotePipeName = "pipe47"
|
||||
|
||||
|
||||
Configuration options
|
||||
@ -144,8 +143,7 @@ DeadThreadsCollection integer default 50
|
||||
PriorityBoost integer default 5
|
||||
RemoteServiceName string default gds_db
|
||||
RemoteServicePort integer default 3050 (TCP port number)
|
||||
RemotePipeName string default "interbas" (Windows only?)
|
||||
IpcName string default "FirebirdIPI" (Windows only)
|
||||
IpcName string default "FIREBIRD" (Windows only)
|
||||
|
||||
MaxUnflushedWrites integer
|
||||
# of writes before file writes are forcibly synched.
|
||||
|
@ -10,10 +10,6 @@ For TCP (aka INET) protocol:
|
||||
|
||||
<host> [ / <port>] : <file path to database or alias>
|
||||
|
||||
For named pipes (aka NetBEUI, aka WNET) protocol:
|
||||
|
||||
\\ <host> [ @ <port>] \ <file path to database or alias>
|
||||
|
||||
For local connections as simple as:
|
||||
|
||||
<file path to database or alias>
|
||||
@ -55,11 +51,6 @@ Examples:
|
||||
myserver/fb_db:mydb
|
||||
localhost/fb_db:mydb
|
||||
|
||||
Connect via named pipes:
|
||||
|
||||
\\myserver\C:\db\mydb.fdb
|
||||
\\myserver@fb_db\C:\db\mydb.fdb
|
||||
|
||||
Local connection:
|
||||
|
||||
/db/mydb.fdb
|
||||
@ -71,8 +62,7 @@ connection strings:
|
||||
|
||||
[ <protocol> : // [ <host> [ : <port> ] ] ] / <file path to database or alias>
|
||||
|
||||
Where protocol is one of: INET (means TCP), WNET (means named pipes) or XNET
|
||||
(means shared memory).
|
||||
Where protocol is one of: INET (means TCP) or XNET (means shared memory).
|
||||
|
||||
Examples:
|
||||
|
||||
@ -114,22 +104,12 @@ Examples:
|
||||
inet4://myserver/mydb
|
||||
inet6://myserver/mydb
|
||||
|
||||
Connect via named pipes:
|
||||
|
||||
wnet://myserver/C:\db\mydb.fdb
|
||||
wnet://myserver:fb_db/C:\db\mydb.fdb
|
||||
|
||||
Loopback connection via TCP:
|
||||
|
||||
inet:///db/mydb.fdb
|
||||
inet://C:\db\mydb.fdb
|
||||
inet://mydb
|
||||
|
||||
Loopback connection via named pipes:
|
||||
|
||||
wnet://C:\db\mydb.fdb
|
||||
wnet://mydb
|
||||
|
||||
Local connection via shared memory:
|
||||
|
||||
xnet://C:\db\mydb.fdb
|
||||
@ -155,9 +135,7 @@ to connect locally using a specific transport protocol, please specify:
|
||||
|
||||
inet://<file path to database or alias>
|
||||
or
|
||||
wnet://<file path to database or alias>
|
||||
or
|
||||
xnet://<file path to database or alias>
|
||||
|
||||
Note: WNET (named pipes) and XNET (shared memory) protocols are available on Windows only.
|
||||
Note: XNET (shared memory) protocol is available on Windows only.
|
||||
|
||||
|
@ -1673,7 +1673,7 @@ only for some specific OS you can make this place a bit simpler. In
|
||||
minimum case the function should register module and all factories in
|
||||
plugin manager:</font></p>
|
||||
<p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">extern
|
||||
"C" void FB_DLL_EXPORT FB_PLUGIN_ENTRY_POINT(IMaster*
|
||||
"C" FB_DLL_EXPORT void FB_PLUGIN_ENTRY_POINT(IMaster*
|
||||
master)</font></p>
|
||||
<p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">{</font></p>
|
||||
<p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">IPluginManager*
|
||||
|
@ -48,7 +48,7 @@ Usage:
|
||||
Variable name Value
|
||||
------------------------------------------------------------------------------
|
||||
NETWORK_PROTOCOL | The network protocol used by client to connect. Currently
|
||||
| used values: "TCPv4", "TCPv6", "WNET", "XNET" and NULL.
|
||||
| used values: "TCPv4", "TCPv6", "XNET" and NULL.
|
||||
|
|
||||
WIRE_COMPRESSED | Compression status of current connection.
|
||||
| If connection is compressed - returns "TRUE", if it is
|
||||
|
@ -11,7 +11,7 @@ Description:
|
||||
|
||||
Syntax:
|
||||
<declaration item> ::=
|
||||
DECLARE [VARIABLE] <variable name> <data type> [ := <value> ];
|
||||
DECLARE [VARIABLE] <variable name> <data type> [ = <value> ];
|
||||
|
|
||||
DECLARE [VARIABLE] CURSOR <cursor name> FOR (<query>);
|
||||
|
|
||||
@ -46,8 +46,11 @@ Syntax:
|
||||
Limitations:
|
||||
1) Subroutines may not be nested in another subroutine. They are only supported in the main
|
||||
routine.
|
||||
2) Currently, a subroutine may not directly access or use variables or cursors of the
|
||||
main statements. This may be allowed in the future.
|
||||
2) Currently, a subroutine may not directly access cursors of the main routine/block.
|
||||
This may be allowed in the future.
|
||||
3) Since FB 5 subroutines may use variables and parameters from the main routine/block.
|
||||
4) Variables and parameters that are accessed by subroutines may have a small performance
|
||||
penalty (even in the main routine) when being read.
|
||||
|
||||
Notes:
|
||||
1) Starting in FB 4, subroutines may be recursive or call others subroutines.
|
||||
|
@ -298,7 +298,7 @@ Factory factory;
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
extern "C" void FB_DLL_EXPORT FB_PLUGIN_ENTRY_POINT(IMaster* m)
|
||||
extern "C" FB_DLL_EXPORT void FB_PLUGIN_ENTRY_POINT(IMaster* m)
|
||||
{
|
||||
master = m;
|
||||
IPluginManager* pluginManager = master->getPluginManager();
|
||||
|
@ -266,7 +266,7 @@ Factory factory;
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
extern "C" void FB_DLL_EXPORT FB_PLUGIN_ENTRY_POINT(IMaster* master)
|
||||
extern "C" FB_DLL_EXPORT void FB_PLUGIN_ENTRY_POINT(IMaster* master)
|
||||
{
|
||||
IPluginManager* pluginManager = master->getPluginManager();
|
||||
|
||||
|
@ -435,13 +435,7 @@ Factory<ExtAuthServer> serverFactory;
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
#if defined(_WIN32)
|
||||
#define FB_DLL_EXPORT __declspec(dllexport)
|
||||
#else
|
||||
#define FB_DLL_EXPORT
|
||||
#endif
|
||||
|
||||
extern "C" void FB_DLL_EXPORT FB_PLUGIN_ENTRY_POINT(IMaster* m)
|
||||
extern "C" FB_DLL_EXPORT void FB_PLUGIN_ENTRY_POINT(IMaster* m)
|
||||
{
|
||||
master = m;
|
||||
IPluginManager* pluginManager = master->getPluginManager();
|
||||
|
@ -105,9 +105,9 @@
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<ConformanceMode>false</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>..\..\..\src\include\;..\..\..\extern\libtomcrypt\src\headers\</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;LTM_DESC</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;LTM_DESC;WIN32</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@ -121,9 +121,9 @@
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<ConformanceMode>false</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>..\..\..\src\include\;..\..\..\extern\libtomcrypt\src\headers\</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;LTM_DESC</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;LTM_DESC;WIN32</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@ -139,9 +139,9 @@
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<ConformanceMode>false</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>..\..\..\src\include\;..\..\..\extern\libtomcrypt\src\headers\</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;LTM_DESC</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;LTM_DESC;WIN32</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@ -159,9 +159,9 @@
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<ConformanceMode>false</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>..\..\..\src\include\;..\..\..\extern\libtomcrypt\src\headers\</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;LTM_DESC</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;LTM_DESC;WIN32</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
|
@ -83,31 +83,31 @@
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<OutDir>..\..\prebuilt\$(Platform)\$(Configuration)\bin\</OutDir>
|
||||
<IntDir>..\..\..\temp\$(PlatformName)\$(Configuration)\examples\$(ProjectName)\</IntDir>
|
||||
<TargetName>fbSampleExtAuthKeygen </TargetName>
|
||||
<TargetName>fbSampleExtAuthKeygen</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<OutDir>..\..\prebuilt\$(Platform)\$(Configuration)\bin\</OutDir>
|
||||
<IntDir>..\..\..\temp\$(PlatformName)\$(Configuration)\examples\$(ProjectName)\</IntDir>
|
||||
<TargetName>fbSampleExtAuthKeygen </TargetName>
|
||||
<TargetName>fbSampleExtAuthKeygen</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<OutDir>..\..\prebuilt\$(Platform)\$(Configuration)\bin\</OutDir>
|
||||
<IntDir>..\..\..\temp\$(PlatformName)\$(Configuration)\examples\$(ProjectName)\</IntDir>
|
||||
<TargetName>fbSampleExtAuthKeygen </TargetName>
|
||||
<TargetName>fbSampleExtAuthKeygen</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<OutDir>..\..\prebuilt\$(Platform)\$(Configuration)\bin\</OutDir>
|
||||
<IntDir>..\..\..\temp\$(PlatformName)\$(Configuration)\examples\$(ProjectName)\</IntDir>
|
||||
<TargetName>fbSampleExtAuthKeygen </TargetName>
|
||||
<TargetName>fbSampleExtAuthKeygen</TargetName>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<ConformanceMode>false</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>..\..\..\src\include\;..\..\..\extern\libtomcrypt\src\headers\</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;LTM_DESC</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;LTM_DESC;WIN32</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@ -120,9 +120,9 @@
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<ConformanceMode>false</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>..\..\..\src\include\;..\..\..\extern\libtomcrypt\src\headers\</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;LTM_DESC</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;LTM_DESC;WIN32</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@ -137,9 +137,9 @@
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<ConformanceMode>false</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>..\..\..\src\include\;..\..\..\extern\libtomcrypt\src\headers\</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;LTM_DESC</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;LTM_DESC;WIN32</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@ -156,9 +156,9 @@
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<ConformanceMode>false</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>..\..\..\src\include\;..\..\..\extern\libtomcrypt\src\headers\</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;LTM_DESC</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;LTM_DESC;WIN32</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
|
@ -145,7 +145,7 @@ int main()
|
||||
/*IProvider* prov = master->getDispatcher();
|
||||
IAttachment* att = NULL;*/
|
||||
IUtil* utl = master->getUtilInterface();
|
||||
IStatement* statemt = NULL;
|
||||
IStatement* statement = NULL;
|
||||
ITransaction* tra = NULL;
|
||||
IBatch* batch = NULL;
|
||||
IBatchCompletionState* cs = NULL;
|
||||
@ -185,7 +185,7 @@ int main()
|
||||
if (isc_dsql_prepare(st, &tr, &stmt, 0, sqlStmt1, 3, NULL))
|
||||
raiseError(status, st);
|
||||
// and get it's interface
|
||||
if (fb_get_statement_interface(st, &statemt, &stmt))
|
||||
if (fb_get_statement_interface(st, &statement, &stmt))
|
||||
raiseError(status, st);
|
||||
|
||||
// Message to store in a table
|
||||
@ -202,7 +202,7 @@ int main()
|
||||
pb->insertInt(&status, IBatch::TAG_RECORD_COUNTS, 1);
|
||||
|
||||
// create batch
|
||||
batch = statemt->createBatch(&status, meta,
|
||||
batch = statement->createBatch(&status, meta,
|
||||
pb->getBufferLength(&status), pb->getBuffer(&status));
|
||||
|
||||
// fill batch with data record by record
|
||||
@ -223,8 +223,8 @@ int main()
|
||||
batch = NULL;
|
||||
|
||||
// unprepare statement
|
||||
statemt->release();
|
||||
statemt = NULL;
|
||||
statement->release();
|
||||
statement = NULL;
|
||||
if (isc_dsql_free_statement(st, &stmt, DSQL_unprepare))
|
||||
raiseError(status, st);
|
||||
|
||||
@ -237,7 +237,7 @@ int main()
|
||||
if (isc_dsql_prepare(st, &tr, &stmt, 0, sqlStmt2, 3, NULL))
|
||||
raiseError(status, st);
|
||||
// and get it's interface
|
||||
if (fb_get_statement_interface(st, &statemt, &stmt))
|
||||
if (fb_get_statement_interface(st, &statement, &stmt))
|
||||
raiseError(status, st);
|
||||
|
||||
// Message to store in a table
|
||||
@ -255,7 +255,7 @@ int main()
|
||||
pb->insertInt(&status, IBatch::TAG_BLOB_POLICY, IBatch::BLOB_ID_ENGINE);
|
||||
|
||||
// create batch
|
||||
batch = statemt->createBatch(&status, meta,
|
||||
batch = statement->createBatch(&status, meta,
|
||||
pb->getBufferLength(&status), pb->getBuffer(&status));
|
||||
|
||||
// create blob
|
||||
@ -283,8 +283,8 @@ int main()
|
||||
batch = NULL;
|
||||
|
||||
// unprepare statement
|
||||
statemt->release();
|
||||
statemt = NULL;
|
||||
statement->release();
|
||||
statement = NULL;
|
||||
if (isc_dsql_free_statement(st, &stmt, DSQL_drop))
|
||||
raiseError(status, st);
|
||||
|
||||
@ -312,8 +312,8 @@ int main()
|
||||
batch->release();
|
||||
if (tra)
|
||||
tra->release();
|
||||
if (statemt)
|
||||
statemt->release();
|
||||
if (statement)
|
||||
statement->release();
|
||||
|
||||
// close handles if not closed
|
||||
if (blb)
|
||||
|
@ -37,14 +37,6 @@ typedef int FbSampleAtomic;
|
||||
|
||||
#include <firebird/Interface.h>
|
||||
|
||||
#if defined(_WIN32)
|
||||
#define FB_DLL_EXPORT __declspec(dllexport)
|
||||
#elif defined(__APPLE__)
|
||||
#define FB_DLL_EXPORT __attribute__((visibility("default")))
|
||||
#else
|
||||
#define FB_DLL_EXPORT
|
||||
#endif
|
||||
|
||||
using namespace Firebird;
|
||||
|
||||
#define SAMPLES_DIALECT SQL_DIALECT_V6
|
||||
|
@ -40,9 +40,10 @@ you would do the following to create a project from 03.select.pas:
|
||||
- Open select.lpr as a project
|
||||
- When prompted choose 'Simple Program' as the project template
|
||||
- Go into Project options and add the following paths:
|
||||
/opt/firebird/include/Firebird
|
||||
```
|
||||
/usr/include/Firebird
|
||||
common
|
||||
|
||||
```
|
||||
You can then compile and run the example through the debugger.
|
||||
|
||||
|
||||
|
@ -100,14 +100,7 @@ public:
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#if defined(__WIN32__)
|
||||
void __declspec(dllexport) FB_PLUGIN_ENTRY_POINT(IMaster* m);
|
||||
#else
|
||||
void FB_PLUGIN_ENTRY_POINT(IMaster* m)
|
||||
__attribute__((visibility("default")));
|
||||
#endif // __WIN32__
|
||||
|
||||
void FB_PLUGIN_ENTRY_POINT(IMaster* m)
|
||||
FB_DLL_EXPORT void FB_PLUGIN_ENTRY_POINT(IMaster* m)
|
||||
{
|
||||
master = m;
|
||||
IPluginManager* pm = m->getPluginManager();
|
||||
|
@ -234,8 +234,6 @@ FB_UDR_BEGIN_TRIGGER(replicate_persons)
|
||||
"select data_source from replicate_config where name = ?",
|
||||
SQL_DIALECT_CURRENT, NULL), status, statusVector);
|
||||
|
||||
const char* table = metadata->getTriggerTable(status);
|
||||
|
||||
// Skip the first exclamation point, separating the module name and entry point.
|
||||
const char* info = strchr(metadata->getEntryPoint(status), '!');
|
||||
|
||||
|
BIN
extern/icu/tzdata/be.zip
vendored
BIN
extern/icu/tzdata/be.zip
vendored
Binary file not shown.
BIN
extern/icu/tzdata/le.zip
vendored
BIN
extern/icu/tzdata/le.zip
vendored
Binary file not shown.
2
extern/icu/tzdata/version.txt
vendored
2
extern/icu/tzdata/version.txt
vendored
@ -1 +1 @@
|
||||
2021a4
|
||||
2022a
|
||||
|
2
extern/zlib/Readme.txt
vendored
2
extern/zlib/Readme.txt
vendored
@ -4,7 +4,7 @@ architectures.
|
||||
|
||||
The source code of zlib library was downloaded from
|
||||
|
||||
http://zlib.net/zlib1211.zip
|
||||
http://zlib.net/zlib1212.zip
|
||||
|
||||
It was built with MSVC17 compilers using commands specified at win32/Makefile.msc:
|
||||
|
||||
|
BIN
extern/zlib/zlib.exe
vendored
BIN
extern/zlib/zlib.exe
vendored
Binary file not shown.
@ -448,6 +448,7 @@ file(GLOB engine_src
|
||||
"dsql/*.cpp"
|
||||
"jrd/*.cpp"
|
||||
"jrd/extds/*.cpp"
|
||||
"jrd/optimizer/*.cpp"
|
||||
"jrd/recsrc/*.cpp"
|
||||
"jrd/replication/*.cpp"
|
||||
"jrd/trace/*.cpp"
|
||||
|
@ -98,15 +98,6 @@ struct user_action
|
||||
|
||||
|
||||
|
||||
// String block: used to store a string of constant length.
|
||||
|
||||
class alice_str : public pool_alloc_rpt<UCHAR, alice_type_str>
|
||||
{
|
||||
public:
|
||||
USHORT str_length;
|
||||
UCHAR str_data[2];
|
||||
};
|
||||
|
||||
// Transaction block: used to store info about a multi-database transaction.
|
||||
// Transaction Description Record
|
||||
|
||||
@ -114,10 +105,10 @@ struct tdr : public pool_alloc<alice_type_tdr>
|
||||
{
|
||||
tdr* tdr_next; // next sub-transaction
|
||||
TraNumber tdr_id; // database-specific transaction id
|
||||
alice_str* tdr_fullpath; // full (possibly) remote pathname
|
||||
const TEXT* tdr_filename; // filename within full pathname
|
||||
alice_str* tdr_host_site; // host for transaction
|
||||
alice_str* tdr_remote_site; // site for remote transaction
|
||||
Firebird::string tdr_fullpath; // full (possibly) remote pathname
|
||||
Firebird::string tdr_filename; // filename
|
||||
Firebird::string tdr_host_site; // host for transaction
|
||||
Firebird::string tdr_remote_site; // site for remote transaction
|
||||
FB_API_HANDLE tdr_handle; // reconnected transaction handle
|
||||
FB_API_HANDLE tdr_db_handle; // re-attached database handle
|
||||
USHORT tdr_db_caps; // capabilities of database
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include "../common/classes/UserBlob.h"
|
||||
#include "../alice/alice_proto.h"
|
||||
#include "../common/utils_proto.h"
|
||||
#include "../common/isc_f_proto.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
@ -54,7 +55,7 @@ DATABASE DB = STATIC FILENAME "yachts.lnk";
|
||||
|
||||
typedef Firebird::HalfStaticArray<TEXT, 1024> TextBuffer;
|
||||
|
||||
static alice_str* alloc_string(const TEXT**);
|
||||
static void get_string(const TEXT**, Firebird::string&);
|
||||
static USHORT get_capabilities(ISC_STATUS*);
|
||||
static tdr* get_description(ISC_QUAD*);
|
||||
static void parse_fullpath(tdr*);
|
||||
@ -242,19 +243,15 @@ void MET_set_capabilities(ISC_STATUS* user_status, tdr* trans)
|
||||
* Eat a string with a byte-encoded length.
|
||||
*/
|
||||
|
||||
static alice_str* alloc_string(const TEXT** ptr)
|
||||
static void get_string(const TEXT** ptr, Firebird::string& str)
|
||||
{
|
||||
AliceGlobals* tdgbl = AliceGlobals::getSpecific();
|
||||
|
||||
const TEXT* p = *ptr;
|
||||
|
||||
const USHORT length = (USHORT) *p++;
|
||||
alice_str* string = FB_NEW_RPT(*tdgbl->getDefaultPool(), length + 1) alice_str;
|
||||
memcpy(string->str_data, p, length);
|
||||
string->str_data[length] = 0;
|
||||
*ptr = p + length;
|
||||
|
||||
return string;
|
||||
str.assign(p, length);
|
||||
}
|
||||
|
||||
|
||||
@ -319,8 +316,8 @@ static tdr* get_description(ISC_QUAD* blob_id)
|
||||
return NULL;
|
||||
|
||||
tdr* trans = NULL;
|
||||
alice_str* host_site = NULL;
|
||||
alice_str* database_path = NULL;
|
||||
Firebird::string host_site;
|
||||
Firebird::string database_path;
|
||||
|
||||
const TEXT* p = buffer.begin();
|
||||
|
||||
@ -336,11 +333,11 @@ static tdr* get_description(ISC_QUAD* blob_id)
|
||||
switch (*p++)
|
||||
{
|
||||
case TDR_HOST_SITE:
|
||||
host_site = alloc_string(&p);
|
||||
get_string(&p, host_site);
|
||||
break;
|
||||
|
||||
case TDR_DATABASE_PATH:
|
||||
database_path = alloc_string(&p);
|
||||
get_string(&p, database_path);
|
||||
break;
|
||||
|
||||
case TDR_TRANSACTION_ID:
|
||||
@ -359,7 +356,7 @@ static tdr* get_description(ISC_QUAD* blob_id)
|
||||
ptr->tdr_fullpath = database_path;
|
||||
parse_fullpath(ptr);
|
||||
ptr->tdr_id = id;
|
||||
database_path = NULL;
|
||||
database_path.clear();
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -382,73 +379,17 @@ static tdr* get_description(ISC_QUAD* blob_id)
|
||||
|
||||
static void parse_fullpath(tdr* trans)
|
||||
{
|
||||
AliceGlobals* tdgbl = AliceGlobals::getSpecific();
|
||||
Firebird::PathName filename = trans->tdr_fullpath.c_str();
|
||||
Firebird::PathName hostname;
|
||||
|
||||
// start at the end of the full pathname
|
||||
// Find the last remote node in the path
|
||||
|
||||
const TEXT* p = (TEXT*) trans->tdr_fullpath->str_data;
|
||||
const TEXT* const start = p;
|
||||
while (*p)
|
||||
p++;
|
||||
const TEXT* const end = p;
|
||||
while (ISC_analyze_tcp(filename, hostname))
|
||||
trans->tdr_remote_site = hostname.c_str();
|
||||
|
||||
// Check for a named pipes name - \\node\path\db or //node/path/db
|
||||
while (p > start && !(*p == '/' && p[-1] == '/') && !(*p == '\\' && p[-1] == '\\'))
|
||||
{
|
||||
--p;
|
||||
}
|
||||
// At this point the filename is clear from any remote nodes
|
||||
|
||||
if (p > start)
|
||||
{
|
||||
// Increment p past slash, & search forward for end of node name
|
||||
p = p + 1;
|
||||
const TEXT* q = p;
|
||||
|
||||
while (*q && *q != '/' && *q != '\\')
|
||||
q++;
|
||||
if (*q)
|
||||
{
|
||||
trans->tdr_filename = q + 1;
|
||||
|
||||
trans->tdr_remote_site = FB_NEW_RPT(*tdgbl->getDefaultPool(), q - p + 1) alice_str;
|
||||
fb_utils::copy_terminate((char*) trans->tdr_remote_site->str_data, (char*) p, q - p + 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
p = end;
|
||||
|
||||
// If not named pipes, check the other protocols
|
||||
// work backwards until we find a remote protocol specifier
|
||||
|
||||
|
||||
while (p >= start && (*p != '^' && *p != ':' && *p != '@'))
|
||||
p--;
|
||||
// dimitr: make sure that the remote path is parsed correctly
|
||||
// for win32 servers, i.e. the drive separator is taken into account
|
||||
if ((p - 2 >= start) && p[-2] == ':' && (p[0] == ':'))
|
||||
p -= 2;
|
||||
trans->tdr_filename = p + 1;
|
||||
|
||||
// now find the last remote node in the chain
|
||||
|
||||
while (p > start && (*p == ':' || *p == '^' || *p == '@'))
|
||||
p--;
|
||||
|
||||
USHORT length = 0;
|
||||
for (; p >= start && (*p != '^' && *p != ':' && *p != '@'); ++length)
|
||||
--p;
|
||||
++p;
|
||||
|
||||
if (length)
|
||||
{
|
||||
trans->tdr_remote_site = FB_NEW_RPT(*tdgbl->getDefaultPool(), length + 1) alice_str;
|
||||
TEXT* q = (TEXT *) trans->tdr_remote_site->str_data;
|
||||
while (length--)
|
||||
*q++ = *p++;
|
||||
*q = 0;
|
||||
}
|
||||
}
|
||||
trans->tdr_filename = filename.c_str();
|
||||
}
|
||||
|
||||
|
||||
|
@ -472,7 +472,7 @@ bool TDR_reconnect_multiple(FB_API_HANDLE handle, TraNumber id, const TEXT* name
|
||||
{
|
||||
if (ptr->tdr_state == TRA_limbo)
|
||||
{
|
||||
reconnect(ptr->tdr_db_handle, ptr->tdr_id, ptr->tdr_filename, switches);
|
||||
reconnect(ptr->tdr_db_handle, ptr->tdr_id, ptr->tdr_filename.c_str(), switches);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -504,28 +504,23 @@ static void print_description(const tdr* trans)
|
||||
AliceGlobals* tdgbl = AliceGlobals::getSpecific();
|
||||
|
||||
if (!trans)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!tdgbl->uSvc->isService())
|
||||
{
|
||||
ALICE_print(92); // msg 92: Multidatabase transaction:
|
||||
}
|
||||
|
||||
bool prepared_seen = false;
|
||||
for (const tdr* ptr = trans; ptr; ptr = ptr->tdr_next)
|
||||
{
|
||||
if (ptr->tdr_host_site)
|
||||
const auto host_site = ptr->tdr_host_site.nullStr();
|
||||
if (host_site)
|
||||
{
|
||||
const char* pszHostSize = reinterpret_cast<const char*>(ptr->tdr_host_site->str_data);
|
||||
|
||||
if (!tdgbl->uSvc->isService())
|
||||
{
|
||||
// msg 93: Host Site: %s
|
||||
ALICE_print(93, SafeArg() << pszHostSize);
|
||||
ALICE_print(93, SafeArg() << host_site);
|
||||
}
|
||||
tdgbl->uSvc->putLine(isc_spb_tra_host_site, pszHostSize);
|
||||
tdgbl->uSvc->putLine(isc_spb_tra_host_site, host_site);
|
||||
}
|
||||
|
||||
if (ptr->tdr_id)
|
||||
@ -586,28 +581,26 @@ static void print_description(const tdr* trans)
|
||||
break;
|
||||
}
|
||||
|
||||
if (ptr->tdr_remote_site)
|
||||
const auto remote_site = ptr->tdr_remote_site.nullStr();
|
||||
if (remote_site)
|
||||
{
|
||||
const char* pszRemoteSite = reinterpret_cast<const char*>(ptr->tdr_remote_site->str_data);
|
||||
|
||||
if (!tdgbl->uSvc->isService())
|
||||
{
|
||||
// msg 101: Remote Site: %s
|
||||
ALICE_print(101, SafeArg() << pszRemoteSite);
|
||||
ALICE_print(101, SafeArg() << remote_site);
|
||||
}
|
||||
tdgbl->uSvc->putLine(isc_spb_tra_remote_site, pszRemoteSite);
|
||||
tdgbl->uSvc->putLine(isc_spb_tra_remote_site, remote_site);
|
||||
}
|
||||
|
||||
if (ptr->tdr_fullpath)
|
||||
const auto fullpath = ptr->tdr_fullpath.nullStr();
|
||||
if (fullpath)
|
||||
{
|
||||
const char* pszFullpath = reinterpret_cast<const char*>(ptr->tdr_fullpath->str_data);
|
||||
|
||||
if (!tdgbl->uSvc->isService())
|
||||
{
|
||||
// msg 102: Database Path: %s
|
||||
ALICE_print(102, SafeArg() << pszFullpath);
|
||||
ALICE_print(102, SafeArg() << fullpath);
|
||||
}
|
||||
tdgbl->uSvc->putLine(isc_spb_tra_db_path, pszFullpath);
|
||||
tdgbl->uSvc->putLine(isc_spb_tra_db_path, fullpath);
|
||||
}
|
||||
}
|
||||
|
||||
@ -649,10 +642,9 @@ static void print_description(const tdr* trans)
|
||||
static SINT64 ask()
|
||||
{
|
||||
AliceGlobals* tdgbl = AliceGlobals::getSpecific();
|
||||
|
||||
if (tdgbl->uSvc->isService())
|
||||
{
|
||||
return ~SINT64(0);
|
||||
}
|
||||
|
||||
char response[32];
|
||||
SINT64 switches = 0;
|
||||
@ -694,79 +686,56 @@ static SINT64 ask()
|
||||
static void reattach_database(tdr* trans)
|
||||
{
|
||||
ISC_STATUS_ARRAY status_vector;
|
||||
char buffer[1024];
|
||||
char buffer[BUFFER_LARGE];
|
||||
// sizeof(buffer) - 1 => leave space for the terminator.
|
||||
const char* const end = buffer + sizeof(buffer) - 1;
|
||||
AliceGlobals* tdgbl = AliceGlobals::getSpecific();
|
||||
|
||||
ISC_get_host(buffer, sizeof(buffer));
|
||||
|
||||
if (trans->tdr_fullpath)
|
||||
if (trans->tdr_fullpath.hasData())
|
||||
{
|
||||
Firebird::string hostname;
|
||||
ISC_get_host(hostname);
|
||||
|
||||
// if this is being run from the same host,
|
||||
// try to reconnect using the same pathname
|
||||
|
||||
if (!strcmp(buffer, reinterpret_cast<const char*>(trans->tdr_host_site->str_data)))
|
||||
{
|
||||
if (TDR_attach_database(status_vector, trans,
|
||||
reinterpret_cast<char*>(trans->tdr_fullpath->str_data)))
|
||||
if (trans->tdr_host_site == hostname)
|
||||
{
|
||||
if (TDR_attach_database(status_vector, trans, trans->tdr_fullpath.c_str()))
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (trans->tdr_host_site)
|
||||
else if (trans->tdr_host_site.hasData())
|
||||
{
|
||||
// try going through the previous host with all available
|
||||
// protocols, using chaining to try the same method of
|
||||
// attachment originally used from that host
|
||||
char* p = buffer;
|
||||
const UCHAR* q = trans->tdr_host_site->str_data;
|
||||
while (*q && p < end)
|
||||
*p++ = *q++;
|
||||
*p++ = ':';
|
||||
q = trans->tdr_fullpath->str_data;
|
||||
while (*q && p < end)
|
||||
*p++ = *q++;
|
||||
*p = 0;
|
||||
if (TDR_attach_database(status_vector, trans, buffer))
|
||||
{
|
||||
const Firebird::string pathname = trans->tdr_host_site + ':' + trans->tdr_fullpath;
|
||||
if (TDR_attach_database(status_vector, trans, pathname.c_str()))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// attaching using the old method didn't work;
|
||||
// try attaching to the remote node directly
|
||||
|
||||
if (trans->tdr_remote_site)
|
||||
{
|
||||
char* p = buffer;
|
||||
const UCHAR* q = trans->tdr_remote_site->str_data;
|
||||
while (*q && p < end)
|
||||
*p++ = *q++;
|
||||
*p++ = ':';
|
||||
q = reinterpret_cast<const UCHAR*>(trans->tdr_filename);
|
||||
while (*q && p < end)
|
||||
*p++ = *q++;
|
||||
*p = 0;
|
||||
if (TDR_attach_database (status_vector, trans, buffer))
|
||||
if (trans->tdr_remote_site.hasData())
|
||||
{
|
||||
const Firebird::string pathname = trans->tdr_remote_site + ':' + trans->tdr_filename;
|
||||
if (TDR_attach_database(status_vector, trans, pathname.c_str()))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// we have failed to reattach; notify the user
|
||||
// and let them try to succeed where we have failed
|
||||
|
||||
ALICE_print(86, SafeArg() << trans->tdr_id);
|
||||
// msg 86: Could not reattach to database for transaction %ld.
|
||||
ALICE_print(87, SafeArg() << (trans->tdr_fullpath ? (char*)(trans->tdr_fullpath->str_data) : "is unknown"));
|
||||
ALICE_print(87, SafeArg() << (trans->tdr_fullpath.hasData() ? trans->tdr_fullpath.c_str() : "unknown"));
|
||||
// msg 87: Original path: %s
|
||||
|
||||
if (tdgbl->uSvc->isService())
|
||||
{
|
||||
ALICE_exit(FINI_ERROR, tdgbl);
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
@ -782,12 +751,8 @@ static void reattach_database(tdr* trans)
|
||||
++p;
|
||||
if (TDR_attach_database(status_vector, trans, p))
|
||||
{
|
||||
const size_t p_len = strlen(p);
|
||||
alice_str* string = FB_NEW_RPT(*tdgbl->getDefaultPool(), p_len + 1) alice_str;
|
||||
strcpy(reinterpret_cast<char*>(string->str_data), p);
|
||||
string->str_length = static_cast<USHORT>(p_len);
|
||||
trans->tdr_fullpath = string;
|
||||
trans->tdr_filename = (TEXT *) string->str_data;
|
||||
trans->tdr_fullpath.assign(p);
|
||||
trans->tdr_filename = trans->tdr_fullpath;
|
||||
return;
|
||||
}
|
||||
ALICE_print(89); // msg 89: Attach unsuccessful.
|
||||
|
@ -38,7 +38,7 @@
|
||||
static Firebird::SimpleFactory<Auth::DebugClient> clientFactory;
|
||||
static Firebird::SimpleFactory<Auth::DebugServer> serverFactory;
|
||||
|
||||
extern "C" void FB_PLUGIN_ENTRY_POINT(Firebird::IMaster* master)
|
||||
extern "C" FB_DLL_EXPORT void FB_PLUGIN_ENTRY_POINT(Firebird::IMaster* master)
|
||||
{
|
||||
Firebird::CachedMasterInterface::set(master);
|
||||
|
||||
|
@ -46,7 +46,7 @@ namespace Auth {
|
||||
// The idea of debug plugin is to send some data from server to client,
|
||||
// modify them on client and return result (which becomes login name) to the server
|
||||
|
||||
class DebugServer FB_FINAL :
|
||||
class DebugServer final :
|
||||
public Firebird::StdPlugin<Firebird::IServerImpl<DebugServer, Firebird::CheckStatusWrapper> >
|
||||
{
|
||||
public:
|
||||
@ -61,7 +61,7 @@ private:
|
||||
Firebird::RefPtr<Firebird::IConfig> config;
|
||||
};
|
||||
|
||||
class DebugClient FB_FINAL :
|
||||
class DebugClient final :
|
||||
public Firebird::StdPlugin<Firebird::IClientImpl<DebugClient, Firebird::CheckStatusWrapper> >
|
||||
{
|
||||
public:
|
||||
|
@ -55,7 +55,7 @@ public:
|
||||
|
||||
class PluginDatabases;
|
||||
|
||||
class CachedSecurityDatabase FB_FINAL
|
||||
class CachedSecurityDatabase final
|
||||
: public Firebird::RefCntIface<Firebird::ITimerImpl<CachedSecurityDatabase, Firebird::CheckStatusWrapper> >
|
||||
{
|
||||
public:
|
||||
|
@ -59,7 +59,7 @@ protected:
|
||||
virtual RemotePassword* remotePasswordFactory() = 0;
|
||||
};
|
||||
|
||||
template <class SHA> class SrpClientImpl FB_FINAL : public SrpClient
|
||||
template <class SHA> class SrpClientImpl final : public SrpClient
|
||||
{
|
||||
public:
|
||||
explicit SrpClientImpl<SHA>(IPluginConfig* ipc)
|
||||
|
@ -38,14 +38,6 @@
|
||||
#include "../common/classes/auto.h"
|
||||
#include "../common/classes/ParsedList.h"
|
||||
|
||||
#ifndef FB_EXPORTED
|
||||
#if defined(DARWIN)
|
||||
#define FB_EXPORTED __attribute__((visibility("default")))
|
||||
#else
|
||||
#define FB_EXPORTED
|
||||
#endif // OS choice (DARWIN)
|
||||
#endif // FB_EXPORTED
|
||||
|
||||
namespace {
|
||||
|
||||
const unsigned int SZ_LOGIN = 31;
|
||||
@ -60,7 +52,7 @@ Firebird::GlobalPtr<Firebird::ConfigKeys> keys;
|
||||
|
||||
namespace Auth {
|
||||
|
||||
class SrpManagement FB_FINAL : public Firebird::StdPlugin<Firebird::IManagementImpl<SrpManagement, Firebird::CheckStatusWrapper> >
|
||||
class SrpManagement final : public Firebird::StdPlugin<Firebird::IManagementImpl<SrpManagement, Firebird::CheckStatusWrapper> >
|
||||
{
|
||||
public:
|
||||
explicit SrpManagement(Firebird::IPluginConfig* par)
|
||||
@ -540,12 +532,9 @@ public:
|
||||
assignField(active, user->active());
|
||||
setField(login, user->userName());
|
||||
|
||||
int count = 0;
|
||||
checkCount(status, stmt, &count, isc_info_req_update_count);
|
||||
stmt->execute(status, mainTra, up.getMetadata(), up.getBuffer(), NULL, NULL);
|
||||
check(status);
|
||||
|
||||
if (!checkCount(status, stmt, &count, isc_info_req_update_count))
|
||||
if (recordsCount(status, stmt, isc_info_req_update_count) != 1)
|
||||
{
|
||||
stmt->release();
|
||||
return GsecMsg22;
|
||||
@ -581,12 +570,9 @@ public:
|
||||
Varfield login(dl);
|
||||
setField(login, user->userName());
|
||||
|
||||
int count = 0;
|
||||
checkCount(status, stmt, &count, isc_info_req_delete_count);
|
||||
stmt->execute(status, mainTra, dl.getMetadata(), dl.getBuffer(), NULL, NULL);
|
||||
check(status);
|
||||
|
||||
if (!checkCount(status, stmt, &count, isc_info_req_delete_count))
|
||||
if (recordsCount(status, stmt, isc_info_req_delete_count) != 1)
|
||||
{
|
||||
stmt->release();
|
||||
return GsecMsg22;
|
||||
@ -739,7 +725,7 @@ private:
|
||||
|
||||
RemotePasswordImpl<Firebird::Sha1> server;
|
||||
|
||||
bool checkCount(Firebird::CheckStatusWrapper* status, Firebird::IStatement* stmt, int* count, UCHAR item)
|
||||
int recordsCount(Firebird::CheckStatusWrapper* status, Firebird::IStatement* stmt, UCHAR item)
|
||||
{
|
||||
UCHAR buffer[33];
|
||||
const UCHAR count_info[] = { isc_info_sql_records };
|
||||
@ -755,17 +741,12 @@ private:
|
||||
const SSHORT len = gds__vax_integer(p, 2);
|
||||
p += 2;
|
||||
if (count_is == item)
|
||||
{
|
||||
int newCount = gds__vax_integer(p, len);
|
||||
int oldCount = *count;
|
||||
*count = newCount;
|
||||
return newCount == oldCount + 1;
|
||||
}
|
||||
return gds__vax_integer(p, len);
|
||||
p += len;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void check(Firebird::CheckStatusWrapper* status)
|
||||
@ -986,7 +967,7 @@ static Firebird::SimpleFactory<Auth::SrpManagement> factory;
|
||||
|
||||
} // namespace Auth
|
||||
|
||||
extern "C" void FB_EXPORTED FB_PLUGIN_ENTRY_POINT(Firebird::IMaster* master)
|
||||
extern "C" FB_DLL_EXPORT void FB_PLUGIN_ENTRY_POINT(Firebird::IMaster* master)
|
||||
{
|
||||
Firebird::CachedMasterInterface::set(master);
|
||||
Firebird::PluginManagerInterfacePtr()->registerPluginFactory(Firebird::IPluginManager::TYPE_AUTH_USER_MANAGEMENT, Auth::RemotePassword::plugName, &Auth::factory);
|
||||
|
@ -244,7 +244,7 @@ private:
|
||||
};
|
||||
|
||||
|
||||
template <class SHA> class SrpServerImpl FB_FINAL : public SrpServer
|
||||
template <class SHA> class SrpServerImpl final : public SrpServer
|
||||
{
|
||||
public:
|
||||
explicit SrpServerImpl<SHA>(IPluginConfig* ipc)
|
||||
|
@ -35,7 +35,7 @@ namespace Auth {
|
||||
// Required to stop analyzing rest of plugins before first roundtrip to server
|
||||
// if legacy login is present in DPB
|
||||
|
||||
class SecurityDatabaseClient FB_FINAL :
|
||||
class SecurityDatabaseClient final :
|
||||
public Firebird::StdPlugin<Firebird::IClientImpl<SecurityDatabaseClient, Firebird::CheckStatusWrapper> >
|
||||
{
|
||||
public:
|
||||
|
@ -762,7 +762,7 @@ int SecurityDatabaseManagement::execute(Firebird::CheckStatusWrapper* st, Firebi
|
||||
// register plugin
|
||||
static Firebird::SimpleFactory<Auth::SecurityDatabaseManagement> factory;
|
||||
|
||||
extern "C" void FB_PLUGIN_ENTRY_POINT(Firebird::IMaster* master)
|
||||
extern "C" FB_DLL_EXPORT void FB_PLUGIN_ENTRY_POINT(Firebird::IMaster* master)
|
||||
{
|
||||
Firebird::CachedMasterInterface::set(master);
|
||||
Firebird::PluginManagerInterfacePtr()->registerPluginFactory(
|
||||
|
@ -33,7 +33,7 @@
|
||||
|
||||
namespace Auth {
|
||||
|
||||
class SecurityDatabaseManagement FB_FINAL :
|
||||
class SecurityDatabaseManagement final :
|
||||
public Firebird::StdPlugin<Firebird::IManagementImpl<SecurityDatabaseManagement, Firebird::CheckStatusWrapper> >
|
||||
{
|
||||
public:
|
||||
|
@ -125,7 +125,7 @@ namespace Auth {
|
||||
GlobalPtr<PluginDatabases> instances;
|
||||
|
||||
|
||||
class SecurityDatabaseServer FB_FINAL :
|
||||
class SecurityDatabaseServer final :
|
||||
public StdPlugin<IServerImpl<SecurityDatabaseServer, CheckStatusWrapper> >
|
||||
{
|
||||
public:
|
||||
@ -411,7 +411,7 @@ void registerLegacyServer(IPluginManager* iPlugin)
|
||||
|
||||
#ifdef PLUG_MODULE
|
||||
|
||||
extern "C" void FB_EXPORTED FB_PLUGIN_ENTRY_POINT(IMaster* master)
|
||||
extern "C" FB_DLL_EXPORT void FB_PLUGIN_ENTRY_POINT(IMaster* master)
|
||||
{
|
||||
CachedMasterInterface::set(master);
|
||||
|
||||
|
@ -1140,7 +1140,7 @@ void put_asciz( const att_type attribute, const TEXT* string)
|
||||
// We can't honor operating systems that allow longer file names.
|
||||
if (len >= MAX_FILE_NAME_SIZE)
|
||||
{
|
||||
BURP_print(true, 343, SafeArg() << int(attribute) << "put_asciz()" << (MAX_FILE_NAME_SIZE - 1));
|
||||
BURP_print(false, 343, SafeArg() << int(attribute) << "put_asciz()" << (MAX_FILE_NAME_SIZE - 1));
|
||||
// msg 343: text for attribute @1 is too large in @2, truncating to @3 bytes
|
||||
len = MAX_FILE_NAME_SIZE - 1;
|
||||
}
|
||||
@ -1961,6 +1961,7 @@ void put_boolean(att_type attribute, const FB_BOOLEAN value)
|
||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||
|
||||
put(tdgbl, attribute);
|
||||
put(tdgbl, (UCHAR) 1);
|
||||
put(tdgbl, value ? 1u : 0u);
|
||||
}
|
||||
|
||||
|
@ -252,8 +252,9 @@ enum att_type {
|
||||
att_SQL_dialect, // SQL dialect that it speaks
|
||||
att_db_read_only, // Is the database ReadOnly?
|
||||
att_database_linger, // Disconnection timeout
|
||||
att_database_sql_security,// default sql security value
|
||||
att_database_sql_security_deprecated, // can be removed later
|
||||
att_replica_mode, // replica mode
|
||||
att_database_sql_security, // default sql security value
|
||||
|
||||
// Relation attributes
|
||||
|
||||
@ -275,6 +276,7 @@ enum att_type {
|
||||
att_relation_flags,
|
||||
att_relation_ext_file_name, // name of file for external tables
|
||||
att_relation_type,
|
||||
att_relation_sql_security_deprecated, // can be removed later
|
||||
att_relation_sql_security,
|
||||
|
||||
// Field attributes (used for both global and local fields)
|
||||
@ -409,6 +411,7 @@ enum att_type {
|
||||
att_trig_engine_name,
|
||||
att_trig_entrypoint,
|
||||
att_trig_type2,
|
||||
att_trig_sql_security_deprecated, // can be removed later
|
||||
att_trig_sql_security,
|
||||
|
||||
// Function attributes
|
||||
@ -433,6 +436,7 @@ enum att_type {
|
||||
att_function_owner_name,
|
||||
att_function_legacy_flag,
|
||||
att_function_deterministic_flag,
|
||||
att_function_sql_security_deprecated, // can be removed later
|
||||
att_function_sql_security,
|
||||
|
||||
// Function argument attributes
|
||||
@ -529,6 +533,7 @@ enum att_type {
|
||||
att_procedure_entrypoint,
|
||||
att_procedure_package_name,
|
||||
att_procedure_private_flag,
|
||||
att_procedure_sql_security_deprecated, // can be removed later
|
||||
att_procedure_sql_security,
|
||||
|
||||
// Stored procedure parameter attributes
|
||||
@ -630,6 +635,7 @@ enum att_type {
|
||||
att_package_security_class,
|
||||
att_package_owner_name,
|
||||
att_package_description,
|
||||
att_package_sql_security_deprecated, // can be removed later
|
||||
att_package_sql_security,
|
||||
|
||||
// Database creators
|
||||
|
@ -134,7 +134,7 @@ static ULONG unzip_read_block(BurpGlobals*, UCHAR*, FB_SIZE_T);
|
||||
// Portion of data passed to crypt plugin
|
||||
const ULONG CRYPT_STEP = 256;
|
||||
|
||||
class DbInfo FB_FINAL : public Firebird::RefCntIface<Firebird::IDbCryptInfoImpl<DbInfo, Firebird::CheckStatusWrapper> >
|
||||
class DbInfo final : public Firebird::RefCntIface<Firebird::IDbCryptInfoImpl<DbInfo, Firebird::CheckStatusWrapper> >
|
||||
{
|
||||
public:
|
||||
DbInfo(BurpGlobals* bg)
|
||||
|
@ -192,8 +192,13 @@ static inline UCHAR get(BurpGlobals* tdgbl)
|
||||
return tdgbl->get();
|
||||
}
|
||||
|
||||
static inline FB_BOOLEAN get_boolean(BurpGlobals* tdgbl)
|
||||
static inline FB_BOOLEAN get_boolean(BurpGlobals* tdgbl, bool deprecated)
|
||||
{
|
||||
if (!deprecated)
|
||||
{
|
||||
const UCHAR length = get(tdgbl);
|
||||
fb_assert(length == 1);
|
||||
}
|
||||
return get(tdgbl) ? FB_TRUE : FB_FALSE;
|
||||
}
|
||||
|
||||
@ -5142,10 +5147,11 @@ bool get_function(BurpGlobals* tdgbl)
|
||||
bad_attribute(scan_next_attr, attribute, 89);
|
||||
break;
|
||||
|
||||
case att_function_sql_security_deprecated:
|
||||
case att_function_sql_security:
|
||||
if (tdgbl->RESTORE_format >= 11)
|
||||
{
|
||||
X.RDB$SQL_SECURITY = get_boolean(tdgbl);
|
||||
X.RDB$SQL_SECURITY = get_boolean(tdgbl, attribute == att_function_sql_security_deprecated);
|
||||
X.RDB$SQL_SECURITY.NULL = FALSE;
|
||||
}
|
||||
else
|
||||
@ -5274,9 +5280,10 @@ bool get_function(BurpGlobals* tdgbl)
|
||||
bad_attribute(scan_next_attr, attribute, 89);
|
||||
break;
|
||||
|
||||
case att_function_sql_security_deprecated:
|
||||
case att_function_sql_security:
|
||||
if (tdgbl->RESTORE_format >= 11)
|
||||
get_boolean(tdgbl);
|
||||
get_boolean(tdgbl, attribute == att_function_sql_security_deprecated);
|
||||
else
|
||||
bad_attribute(scan_next_attr, attribute, 89);
|
||||
break;
|
||||
@ -7417,10 +7424,11 @@ bool get_package(BurpGlobals* tdgbl)
|
||||
X.RDB$DESCRIPTION.NULL = FALSE;
|
||||
break;
|
||||
|
||||
case att_package_sql_security_deprecated:
|
||||
case att_package_sql_security:
|
||||
if (tdgbl->RESTORE_format >= 11)
|
||||
{
|
||||
X.RDB$SQL_SECURITY = get_boolean(tdgbl);
|
||||
X.RDB$SQL_SECURITY = get_boolean(tdgbl, attribute == att_package_sql_security_deprecated);
|
||||
X.RDB$SQL_SECURITY.NULL = FALSE;
|
||||
}
|
||||
else
|
||||
@ -7634,10 +7642,11 @@ bool get_procedure(BurpGlobals* tdgbl)
|
||||
bad_attribute(scan_next_attr, attribute, 290);
|
||||
break;
|
||||
|
||||
case att_procedure_sql_security_deprecated:
|
||||
case att_procedure_sql_security:
|
||||
if (tdgbl->RESTORE_format >= 11)
|
||||
{
|
||||
X.RDB$SQL_SECURITY = get_boolean(tdgbl);
|
||||
X.RDB$SQL_SECURITY = get_boolean(tdgbl, attribute == att_procedure_sql_security_deprecated);
|
||||
X.RDB$SQL_SECURITY.NULL = FALSE;
|
||||
}
|
||||
else
|
||||
@ -7759,9 +7768,10 @@ bool get_procedure(BurpGlobals* tdgbl)
|
||||
bad_attribute(scan_next_attr, attribute, 290);
|
||||
break;
|
||||
|
||||
case att_procedure_sql_security_deprecated:
|
||||
case att_procedure_sql_security:
|
||||
if (tdgbl->RESTORE_format >= 11)
|
||||
get_boolean(tdgbl);
|
||||
get_boolean(tdgbl, attribute == att_procedure_sql_security_deprecated);
|
||||
else
|
||||
bad_attribute(scan_next_attr, attribute, 290);
|
||||
break;
|
||||
@ -8443,9 +8453,10 @@ bool get_relation(BurpGlobals* tdgbl)
|
||||
bad_attribute(scan_next_attr, attribute, 111);
|
||||
break;
|
||||
|
||||
case att_relation_sql_security_deprecated:
|
||||
case att_relation_sql_security:
|
||||
sql_security_null = false;
|
||||
sql_security = get_boolean(tdgbl);
|
||||
sql_security = get_boolean(tdgbl, attribute == att_relation_sql_security_deprecated);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -9784,10 +9795,11 @@ bool get_trigger(BurpGlobals* tdgbl)
|
||||
bad_attribute(scan_next_attr, attribute, 134);
|
||||
break;
|
||||
|
||||
case att_trig_sql_security_deprecated:
|
||||
case att_trig_sql_security:
|
||||
if (tdgbl->RESTORE_format >= 11)
|
||||
{
|
||||
X.RDB$SQL_SECURITY = get_boolean(tdgbl);
|
||||
X.RDB$SQL_SECURITY = get_boolean(tdgbl, attribute == att_trig_sql_security_deprecated);
|
||||
X.RDB$SQL_SECURITY.NULL = FALSE;
|
||||
}
|
||||
else
|
||||
@ -9930,9 +9942,10 @@ bool get_trigger(BurpGlobals* tdgbl)
|
||||
bad_attribute(scan_next_attr, attribute, 134);
|
||||
break;
|
||||
|
||||
case att_trig_sql_security_deprecated:
|
||||
case att_trig_sql_security:
|
||||
if (tdgbl->RESTORE_format >= 11)
|
||||
get_boolean(tdgbl);
|
||||
get_boolean(tdgbl, attribute == att_trig_sql_security_deprecated);
|
||||
else
|
||||
bad_attribute(scan_next_attr, attribute, 134);
|
||||
break;
|
||||
@ -10226,6 +10239,8 @@ bool get_user_privilege(BurpGlobals* tdgbl)
|
||||
case att_priv_obj_type:
|
||||
flags |= USER_PRIV_OBJECT_TYPE;
|
||||
object_type = (USHORT) get_int32(tdgbl);
|
||||
if ( (tdgbl->RESTORE_format < 11) && (object_type > 19) ) // FB 4 has a shift :(
|
||||
object_type++;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -10297,9 +10312,6 @@ bool get_user_privilege(BurpGlobals* tdgbl)
|
||||
}
|
||||
break;
|
||||
|
||||
case obj_database:
|
||||
break;
|
||||
|
||||
default:
|
||||
exists = true;
|
||||
break;
|
||||
@ -11009,6 +11021,7 @@ bool restore(BurpGlobals* tdgbl, Firebird::IProvider* provider, const TEXT* file
|
||||
}
|
||||
break;
|
||||
|
||||
case att_database_sql_security_deprecated:
|
||||
case att_database_sql_security:
|
||||
if (tdgbl->RESTORE_format >= 11)
|
||||
{
|
||||
@ -11017,7 +11030,7 @@ bool restore(BurpGlobals* tdgbl, Firebird::IProvider* provider, const TEXT* file
|
||||
FOR (REQUEST_HANDLE req_handle5)
|
||||
X IN RDB$DATABASE
|
||||
MODIFY X USING
|
||||
X.RDB$SQL_SECURITY = get_boolean(tdgbl);
|
||||
X.RDB$SQL_SECURITY = get_boolean(tdgbl, attribute == att_database_sql_security_deprecated);
|
||||
END_MODIFY;
|
||||
ON_ERROR
|
||||
general_on_error();
|
||||
@ -11028,7 +11041,7 @@ bool restore(BurpGlobals* tdgbl, Firebird::IProvider* provider, const TEXT* file
|
||||
END_ERROR;
|
||||
}
|
||||
else
|
||||
get_boolean(tdgbl);
|
||||
get_boolean(tdgbl, attribute == att_database_sql_security_deprecated);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -664,7 +664,7 @@ bool IntlUtil::readOneChar(Jrd::CharSet* cs, const UCHAR** s, const UCHAR* end,
|
||||
}
|
||||
|
||||
|
||||
// Transform ICU-VERSION attribute (given by the user) in COLL-VERSION (to be stored).
|
||||
// Add COLL-VERSION attribute.
|
||||
bool IntlUtil::setupIcuAttributes(charset* cs, const string& specificAttributes,
|
||||
const string& configInfo, string& newSpecificAttributes)
|
||||
{
|
||||
@ -681,10 +681,19 @@ bool IntlUtil::setupIcuAttributes(charset* cs, const string& specificAttributes,
|
||||
map.get("ICU-VERSION", icuVersion);
|
||||
|
||||
string collVersion;
|
||||
if (!UnicodeUtil::getCollVersion(icuVersion, configInfo, collVersion))
|
||||
auto icu = UnicodeUtil::getCollVersion(icuVersion, configInfo, collVersion);
|
||||
|
||||
if (!icu)
|
||||
return false;
|
||||
|
||||
map.remove("ICU-VERSION");
|
||||
if (icuVersion.isEmpty())
|
||||
{
|
||||
int majorVersion, minorVersion;
|
||||
UnicodeUtil::getICUVersion(icu, majorVersion, minorVersion);
|
||||
icuVersion.printf("%d.%d", majorVersion, minorVersion);
|
||||
map.put("ICU-VERSION", icuVersion);
|
||||
}
|
||||
|
||||
map.remove("COLL-VERSION");
|
||||
|
||||
if (collVersion.hasData())
|
||||
@ -781,16 +790,6 @@ bool IntlUtil::readAttributeChar(Jrd::CharSet* cs, const UCHAR** s, const UCHAR*
|
||||
}
|
||||
|
||||
|
||||
void IntlUtil::getDefaultCollationAttributes(UCharBuffer& collAttributes, charset& cs)
|
||||
{
|
||||
string attributes("ICU-VERSION=");
|
||||
attributes += Jrd::UnicodeUtil::getDefaultIcuVersion();
|
||||
setupIcuAttributes(&cs, attributes, "", attributes);
|
||||
|
||||
collAttributes.push(reinterpret_cast<const UCHAR*>(attributes.c_str()), attributes.length());
|
||||
}
|
||||
|
||||
|
||||
static void unicodeDestroy(texttype* tt)
|
||||
{
|
||||
delete[] const_cast<ASCII*>(tt->texttype_name);
|
||||
|
@ -94,7 +94,6 @@ public:
|
||||
|
||||
static bool setupIcuAttributes(charset* cs, const string& specificAttributes,
|
||||
const string& configInfo, string& newSpecificAttributes);
|
||||
static void getDefaultCollationAttributes(UCharBuffer& collAttributes, charset& cs);
|
||||
|
||||
private:
|
||||
static string escapeAttribute(Jrd::CharSet* cs, const string& s);
|
||||
|
@ -310,7 +310,7 @@ public:
|
||||
RefPtr<RefCounted> attachment;
|
||||
};
|
||||
|
||||
class MetadataBuilder FB_FINAL :
|
||||
class MetadataBuilder final :
|
||||
public RefCntIface<IMetadataBuilderImpl<MetadataBuilder, CheckStatusWrapper> >
|
||||
{
|
||||
public:
|
||||
|
@ -1,6 +1,6 @@
|
||||
// The content of this file is generated with help of update-ids utility Do not edit.
|
||||
|
||||
static const char* BUILTIN_TIME_ZONE_VERSION = "2021a4";
|
||||
static const char* BUILTIN_TIME_ZONE_VERSION = "2022a";
|
||||
|
||||
// Do not change order of items in this array! The index corresponds to a TimeZone ID, which must be fixed!
|
||||
static const char* BUILTIN_TIME_ZONE_LIST[] = {
|
||||
|
@ -34,7 +34,7 @@ namespace Firebird {
|
||||
virtual void transliterate(IStatus* status) = 0;
|
||||
};
|
||||
|
||||
class BatchCompletionState FB_FINAL :
|
||||
class BatchCompletionState final :
|
||||
public DisposeIface<IBatchCompletionStateImpl<BatchCompletionState, CheckStatusWrapper> >
|
||||
{
|
||||
public:
|
||||
|
149
src/common/classes/DoublyLinkedList.h
Normal file
149
src/common/classes/DoublyLinkedList.h
Normal file
@ -0,0 +1,149 @@
|
||||
/*
|
||||
* 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 Adriano dos Santos Fernandes
|
||||
* for the Firebird Open Source RDBMS project.
|
||||
*
|
||||
* Copyright (c) 2022 Adriano dos Santos Fernandes <adrianosf@gmail.com>
|
||||
* and all contributors signed below.
|
||||
*
|
||||
* All Rights Reserved.
|
||||
* Contributor(s): ______________________________________.
|
||||
*/
|
||||
|
||||
#ifndef CLASSES_DOUBLY_LINKED_LIST_H
|
||||
#define CLASSES_DOUBLY_LINKED_LIST_H
|
||||
|
||||
#include "../common/classes/alloc.h"
|
||||
#include <list>
|
||||
#include <utility>
|
||||
|
||||
|
||||
namespace Firebird
|
||||
{
|
||||
|
||||
template <typename T>
|
||||
class DoublyLinkedList
|
||||
{
|
||||
private:
|
||||
using StdList = std::list<T, PoolAllocator<T>>;
|
||||
|
||||
public:
|
||||
using Iterator = typename StdList::iterator;
|
||||
using ConstIterator = typename StdList::const_iterator;
|
||||
|
||||
public:
|
||||
explicit DoublyLinkedList(MemoryPool& p)
|
||||
: stdList(p)
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
constexpr T& front() noexcept
|
||||
{
|
||||
return stdList.front();
|
||||
}
|
||||
|
||||
constexpr const T& front() const noexcept
|
||||
{
|
||||
return stdList.front();
|
||||
}
|
||||
|
||||
constexpr T& back() noexcept
|
||||
{
|
||||
return stdList.back();
|
||||
}
|
||||
|
||||
constexpr const T& back() const noexcept
|
||||
{
|
||||
return stdList.back();
|
||||
}
|
||||
|
||||
constexpr Iterator begin() noexcept
|
||||
{
|
||||
return stdList.begin();
|
||||
}
|
||||
|
||||
constexpr ConstIterator begin() const noexcept
|
||||
{
|
||||
return stdList.begin();
|
||||
}
|
||||
|
||||
constexpr ConstIterator cbegin() const noexcept
|
||||
{
|
||||
return stdList.cbegin();
|
||||
}
|
||||
|
||||
constexpr Iterator end() noexcept
|
||||
{
|
||||
return stdList.end();
|
||||
}
|
||||
|
||||
constexpr ConstIterator end() const noexcept
|
||||
{
|
||||
return stdList.end();
|
||||
}
|
||||
|
||||
constexpr ConstIterator cend() const noexcept
|
||||
{
|
||||
return stdList.cend();
|
||||
}
|
||||
|
||||
constexpr bool isEmpty() const noexcept
|
||||
{
|
||||
return stdList.empty();
|
||||
}
|
||||
|
||||
constexpr void clear() noexcept
|
||||
{
|
||||
stdList.clear();
|
||||
}
|
||||
|
||||
constexpr void erase(Iterator pos)
|
||||
{
|
||||
stdList.erase(pos);
|
||||
}
|
||||
|
||||
constexpr void erase(ConstIterator pos)
|
||||
{
|
||||
stdList.erase(pos);
|
||||
}
|
||||
|
||||
constexpr void pushBack(const T& value)
|
||||
{
|
||||
stdList.push_back(value);
|
||||
}
|
||||
|
||||
constexpr void pushBack(T&& value)
|
||||
{
|
||||
stdList.push_back(std::move(value));
|
||||
}
|
||||
|
||||
constexpr void splice(ConstIterator pos, DoublyLinkedList<T>& other, ConstIterator it)
|
||||
{
|
||||
fb_assert(stdList.get_allocator() == other.stdList.get_allocator());
|
||||
stdList.splice(pos, other.stdList, it);
|
||||
}
|
||||
|
||||
constexpr void splice(ConstIterator pos, DoublyLinkedList<T>&& other, ConstIterator it)
|
||||
{
|
||||
fb_assert(stdList.get_allocator() == other.stdList.get_allocator());
|
||||
stdList.splice(pos, std::move(other.stdList), it);
|
||||
}
|
||||
|
||||
private:
|
||||
StdList stdList;
|
||||
};
|
||||
|
||||
} // namespace Firebird
|
||||
|
||||
#endif // CLASSES_DOUBLY_LINKED_LIST_H
|
@ -355,7 +355,7 @@ namespace Firebird
|
||||
virtual void finish(dsc& result) = 0;
|
||||
};
|
||||
|
||||
class WeakHashContext FB_FINAL : public HashContext
|
||||
class WeakHashContext final : public HashContext
|
||||
{
|
||||
public:
|
||||
virtual void update(const void* data, FB_SIZE_T length);
|
||||
@ -389,31 +389,31 @@ namespace Firebird
|
||||
UCharBuffer buffer;
|
||||
};
|
||||
|
||||
class Md5HashContext FB_FINAL : public LibTomCryptHashContext
|
||||
class Md5HashContext final : public LibTomCryptHashContext
|
||||
{
|
||||
public:
|
||||
Md5HashContext(MemoryPool& pool);
|
||||
};
|
||||
|
||||
class Sha1HashContext FB_FINAL : public LibTomCryptHashContext
|
||||
class Sha1HashContext final : public LibTomCryptHashContext
|
||||
{
|
||||
public:
|
||||
Sha1HashContext(MemoryPool& pool);
|
||||
};
|
||||
|
||||
class Sha256HashContext FB_FINAL : public LibTomCryptHashContext
|
||||
class Sha256HashContext final : public LibTomCryptHashContext
|
||||
{
|
||||
public:
|
||||
Sha256HashContext(MemoryPool& pool);
|
||||
};
|
||||
|
||||
class Sha512HashContext FB_FINAL : public LibTomCryptHashContext
|
||||
class Sha512HashContext final : public LibTomCryptHashContext
|
||||
{
|
||||
public:
|
||||
Sha512HashContext(MemoryPool& pool);
|
||||
};
|
||||
|
||||
class Crc32HashContext FB_FINAL : public HashContext
|
||||
class Crc32HashContext final : public HashContext
|
||||
{
|
||||
public:
|
||||
Crc32HashContext(MemoryPool& pool);
|
||||
|
@ -293,7 +293,7 @@ public:
|
||||
// when yvalve is starting fb_shutdown(). This causes almost unavoidable segfault.
|
||||
// To avoid it this class is added - it detects spontaneous (not by PluginManager)
|
||||
// module unload and notifies PluginManager about this said fact.
|
||||
class UnloadDetectorHelper FB_FINAL :
|
||||
class UnloadDetectorHelper final :
|
||||
public VersionedIface<IPluginModuleImpl<UnloadDetectorHelper, CheckStatusWrapper> >
|
||||
{
|
||||
public:
|
||||
|
@ -1850,6 +1850,11 @@ public:
|
||||
// Create memory pool instance
|
||||
static MemPool* createPool(MemPool* parent, MemoryStats& stats);
|
||||
|
||||
MemoryStats& getStatsGroup() noexcept
|
||||
{
|
||||
return *stats;
|
||||
}
|
||||
|
||||
// Set statistics group for pool. Usage counters will be decremented from
|
||||
// previously set group and added to new
|
||||
void setStatsGroup(MemoryStats& stats) noexcept;
|
||||
@ -2262,6 +2267,11 @@ void MemPool::setStatsGroup(MemoryStats& newStats) noexcept
|
||||
stats->increment_usage(sav_used_memory);
|
||||
}
|
||||
|
||||
MemoryStats& MemoryPool::getStatsGroup() noexcept
|
||||
{
|
||||
return pool->getStatsGroup();
|
||||
}
|
||||
|
||||
void MemoryPool::setStatsGroup(MemoryStats& newStats) noexcept
|
||||
{
|
||||
pool->setStatsGroup(newStats);
|
||||
|
@ -57,6 +57,7 @@
|
||||
#endif
|
||||
|
||||
#include <memory.h>
|
||||
#include <memory>
|
||||
|
||||
#ifdef DEBUG_GDS_ALLOC
|
||||
#define FB_NEW new(*getDefaultMemoryPool(), __FILE__, __LINE__)
|
||||
@ -212,6 +213,8 @@ public:
|
||||
// Get context pool for current thread of execution
|
||||
static MemoryPool* getContextPool();
|
||||
|
||||
MemoryStats& getStatsGroup() noexcept;
|
||||
|
||||
// Set statistics group for pool. Usage counters will be decremented from
|
||||
// previously set group and added to new
|
||||
void setStatsGroup(MemoryStats& stats) noexcept;
|
||||
@ -456,7 +459,166 @@ namespace Firebird
|
||||
|
||||
typedef AutoPtr<MemoryPool> AutoMemoryPool;
|
||||
|
||||
template <typename T>
|
||||
class PoolAllocator
|
||||
{
|
||||
template <typename> friend class PoolAllocator;
|
||||
|
||||
public:
|
||||
using value_type = T;
|
||||
using size_type = size_t;
|
||||
using pointer = T*;
|
||||
using const_pointer = const T*;
|
||||
using reference = T&;
|
||||
using const_reference = const T&;
|
||||
using void_pointer = void* ;
|
||||
using const_void_pointer = const void*;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using is_always_equal = std::true_type;
|
||||
|
||||
template <typename U>
|
||||
struct rebind
|
||||
{
|
||||
typedef PoolAllocator<U> other;
|
||||
};
|
||||
|
||||
public:
|
||||
PoolAllocator(MemoryPool& aPool) noexcept
|
||||
: pool(aPool)
|
||||
{}
|
||||
|
||||
PoolAllocator(const PoolAllocator& o) noexcept
|
||||
: pool(o.pool)
|
||||
{}
|
||||
|
||||
template <class U>
|
||||
PoolAllocator(const PoolAllocator<U>& o) noexcept
|
||||
: pool(o.pool)
|
||||
{}
|
||||
|
||||
~PoolAllocator() noexcept
|
||||
{}
|
||||
|
||||
public:
|
||||
constexpr pointer allocate(size_type n, const void* hint = nullptr)
|
||||
{
|
||||
return static_cast<T*>(pool.allocate(n * sizeof(T) ALLOC_ARGS));
|
||||
}
|
||||
|
||||
constexpr void deallocate(pointer p, size_type n)
|
||||
{
|
||||
pool.deallocate(p);
|
||||
}
|
||||
|
||||
constexpr size_type max_size() const noexcept
|
||||
{
|
||||
return size_t(-1) / sizeof(T);
|
||||
}
|
||||
|
||||
/* C++17
|
||||
template <typename U, typename... Args>
|
||||
constexpr void construct(U* ptr, Args&&... args)
|
||||
{
|
||||
if constexpr (std::is_constructible<U, MemoryPool&, Args...>::value)
|
||||
new ((void*) ptr) U(pool, std::forward<Args>(args)...);
|
||||
else
|
||||
new ((void*) ptr) U(std::forward<Args>(args)...);
|
||||
}
|
||||
*/
|
||||
|
||||
template <
|
||||
typename U,
|
||||
typename... Args,
|
||||
std::enable_if_t<std::is_constructible<U, MemoryPool&, Args...>::value, bool> = true
|
||||
>
|
||||
constexpr void construct(U* ptr, Args&&... args)
|
||||
{
|
||||
new ((void*) ptr) U(pool, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <
|
||||
typename U,
|
||||
typename... Args,
|
||||
std::enable_if_t<!std::is_constructible<U, MemoryPool&, Args...>::value, bool> = true
|
||||
>
|
||||
constexpr void construct(U* ptr, Args&&... args)
|
||||
{
|
||||
new ((void*) ptr) U(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
constexpr void destroy(U* ptr)
|
||||
{
|
||||
ptr->~U();
|
||||
}
|
||||
|
||||
constexpr bool operator==(const PoolAllocator<T>& o) const noexcept
|
||||
{
|
||||
return &pool == &o.pool;
|
||||
}
|
||||
|
||||
constexpr bool operator!=(const PoolAllocator<T>& o) const noexcept
|
||||
{
|
||||
return &pool != &o.pool;
|
||||
}
|
||||
|
||||
private:
|
||||
MemoryPool& pool;
|
||||
};
|
||||
} // namespace Firebird
|
||||
|
||||
|
||||
template <typename TAlloc>
|
||||
struct std::allocator_traits<Firebird::PoolAllocator<TAlloc>>
|
||||
{
|
||||
using Alloc = Firebird::PoolAllocator<TAlloc>;
|
||||
|
||||
using allocator_type = Alloc;
|
||||
using value_type = typename Alloc::value_type;
|
||||
using pointer = typename Alloc::pointer;
|
||||
using const_pointer = typename Alloc::const_pointer;
|
||||
using void_pointer = typename Alloc::void_pointer;
|
||||
using const_void_pointer = typename Alloc::const_void_pointer;
|
||||
using size_type = typename Alloc::size_type;
|
||||
using difference_type = typename Alloc::difference_type;
|
||||
using reference = value_type&;
|
||||
using const_reference = const value_type&;
|
||||
|
||||
using is_always_equal = typename Alloc::is_always_equal;
|
||||
|
||||
template <typename T>
|
||||
using rebind_alloc = typename Alloc::template rebind<T>::other;
|
||||
|
||||
template <typename T>
|
||||
using rebind_traits = allocator_traits<rebind_alloc<T>>;
|
||||
|
||||
static constexpr pointer allocate(Alloc& alloc, size_type size)
|
||||
{
|
||||
return alloc.allocate(size);
|
||||
}
|
||||
|
||||
static constexpr void deallocate(Alloc& alloc, pointer ptr, size_type size)
|
||||
{
|
||||
alloc.deallocate(ptr, size);
|
||||
}
|
||||
|
||||
template <typename T, typename... Args>
|
||||
static constexpr void construct(Alloc& alloc, T* ptr, Args&&... args)
|
||||
{
|
||||
alloc.construct(ptr, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static constexpr void destroy(Alloc& alloc, T* ptr)
|
||||
{
|
||||
alloc.destroy(ptr);
|
||||
}
|
||||
|
||||
static constexpr size_type max_size(const Alloc& alloc) noexcept
|
||||
{
|
||||
return alloc.max_size();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif // CLASSES_ALLOC_H
|
||||
|
@ -110,6 +110,12 @@ public:
|
||||
ensureCapacity(InitialCapacity);
|
||||
}
|
||||
|
||||
Array(const T* items, const size_type itemsCount)
|
||||
: Storage(), count(0), capacity(this->getStorageSize()), data(this->getStorage())
|
||||
{
|
||||
add(items, itemsCount);
|
||||
}
|
||||
|
||||
Array(const Array<T, Storage>& source)
|
||||
: Storage(), count(0), capacity(this->getStorageSize()), data(this->getStorage())
|
||||
{
|
||||
|
@ -483,6 +483,13 @@ namespace Firebird
|
||||
ObjectCmp> >()
|
||||
{ }
|
||||
|
||||
explicit SortedObjectsArray(MemoryPool& p, const SortedObjectsArray& o) :
|
||||
ObjectsArray <ObjectValue, SortedArray<ObjectValue*,
|
||||
ObjectStorage, const ObjectKey*, ObjectKeyOfValue,
|
||||
ObjectCmp> >(p, o)
|
||||
{
|
||||
}
|
||||
|
||||
bool find(const ObjectKey& item, size_type& pos) const
|
||||
{
|
||||
const ObjectKey* const pItem = &item;
|
||||
|
@ -230,6 +230,10 @@
|
||||
#ifdef ARM
|
||||
#define FB_CPU CpuArm
|
||||
#endif /* ARM */
|
||||
#ifdef ARM64
|
||||
#define DARWIN64
|
||||
#define FB_CPU CpuArm64
|
||||
#endif /* ARM64 */
|
||||
#ifdef __ppc__
|
||||
#define powerpc
|
||||
#define FB_CPU CpuPowerPc
|
||||
@ -252,8 +256,6 @@
|
||||
|
||||
#define API_ROUTINE __attribute__((visibility("default")))
|
||||
#define API_ROUTINE_VARARG API_ROUTINE
|
||||
#define INTERNAL_API_ROUTINE API_ROUTINE
|
||||
#define FB_EXPORTED __attribute__((visibility("default")))
|
||||
|
||||
#define O_DIRECT F_NOCACHE
|
||||
#endif /* Darwin Platforms */
|
||||
@ -603,10 +605,6 @@ extern "C" int remove(const char* path);
|
||||
#define CLIB_ROUTINE
|
||||
#endif
|
||||
|
||||
#ifndef FB_EXPORTED
|
||||
#define FB_EXPORTED
|
||||
#endif
|
||||
|
||||
#ifdef HAS_NOEXCEPT
|
||||
#define NOEXCEPT noexcept
|
||||
#define NOEXCEPT_ARG(X) noexcept((X))
|
||||
@ -886,21 +884,6 @@ void GDS_breakpoint(int);
|
||||
#define FB_CONST64(a) (a##LL)
|
||||
#endif
|
||||
|
||||
// Check for "final" keyword support
|
||||
#ifdef CPP_11
|
||||
#define FB_FINAL final
|
||||
#else
|
||||
#ifdef __GNUC__
|
||||
#if ((__GNUC__ == 4 && __GNUC_MINOR__ >= 7) || (__GNUC__ >= 5))
|
||||
#define FB_FINAL __final
|
||||
#endif
|
||||
#endif
|
||||
// Please add support for other compilers here
|
||||
#ifndef FB_FINAL
|
||||
#define FB_FINAL
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define FB_UNUSED(value) do { if (value) {} } while (false)
|
||||
#define FB_UNUSED_VAR(value) (void) value
|
||||
|
||||
|
@ -410,6 +410,8 @@ void Config::checkValues()
|
||||
checkIntForHiBound(KEY_TIP_CACHE_BLOCK_SIZE, MAX_ULONG, true);
|
||||
|
||||
checkIntForLoBound(KEY_INLINE_SORT_THRESHOLD, 0, true);
|
||||
|
||||
checkIntForLoBound(KEY_MAX_STATEMENT_CACHE_SIZE, 0, true);
|
||||
}
|
||||
|
||||
|
||||
|
@ -137,7 +137,6 @@ enum ConfigKey
|
||||
KEY_DEADLOCK_TIMEOUT,
|
||||
KEY_REMOTE_SERVICE_NAME,
|
||||
KEY_REMOTE_SERVICE_PORT,
|
||||
KEY_REMOTE_PIPE_NAME,
|
||||
KEY_IPC_NAME,
|
||||
KEY_MAX_UNFLUSHED_WRITES,
|
||||
KEY_MAX_UNFLUSHED_WRITE_TIME,
|
||||
@ -177,6 +176,7 @@ enum ConfigKey
|
||||
KEY_ENCRYPT_SECURITY_DATABASE,
|
||||
KEY_STMT_TIMEOUT,
|
||||
KEY_CONN_IDLE_TIMEOUT,
|
||||
KEY_ON_DISCONNECT_TRIG_TIMEOUT,
|
||||
KEY_CLIENT_BATCH_BUFFER,
|
||||
KEY_OUTPUT_REDIRECTION_FILE,
|
||||
KEY_EXT_CONN_POOL_SIZE,
|
||||
@ -189,6 +189,7 @@ enum ConfigKey
|
||||
KEY_USE_FILESYSTEM_CACHE,
|
||||
KEY_INLINE_SORT_THRESHOLD,
|
||||
KEY_TEMP_PAGESPACE_DIR,
|
||||
KEY_MAX_STATEMENT_CACHE_SIZE,
|
||||
MAX_CONFIG_KEY // keep it last
|
||||
};
|
||||
|
||||
@ -232,7 +233,6 @@ constexpr ConfigEntry entries[MAX_CONFIG_KEY] =
|
||||
{TYPE_INTEGER, "DeadlockTimeout", false, 10}, // seconds
|
||||
{TYPE_STRING, "RemoteServiceName", false, FB_SERVICE_NAME},
|
||||
{TYPE_INTEGER, "RemoteServicePort", false, 0},
|
||||
{TYPE_STRING, "RemotePipeName", false, FB_PIPE_NAME},
|
||||
{TYPE_STRING, "IpcName", false, FB_IPC_NAME},
|
||||
#ifdef WIN_NT
|
||||
{TYPE_INTEGER, "MaxUnflushedWrites", false, 100},
|
||||
@ -285,6 +285,7 @@ constexpr ConfigEntry entries[MAX_CONFIG_KEY] =
|
||||
{TYPE_BOOLEAN, "AllowEncryptedSecurityDatabase", false, false},
|
||||
{TYPE_INTEGER, "StatementTimeout", false, 0},
|
||||
{TYPE_INTEGER, "ConnectionIdleTimeout", false, 0},
|
||||
{TYPE_INTEGER, "OnDisconnectTriggerTimeout", false, 180},
|
||||
{TYPE_INTEGER, "ClientBatchBuffer", false, 128 * 1024},
|
||||
#ifdef DEV_BUILD
|
||||
{TYPE_STRING, "OutputRedirectionFile", true, "-"},
|
||||
@ -304,7 +305,8 @@ constexpr ConfigEntry entries[MAX_CONFIG_KEY] =
|
||||
{TYPE_STRING, "DataTypeCompatibility", false, nullptr},
|
||||
{TYPE_BOOLEAN, "UseFileSystemCache", false, true},
|
||||
{TYPE_INTEGER, "InlineSortThreshold", false, 1000}, // bytes
|
||||
{TYPE_STRING, "TempTableDirectory", false, ""}
|
||||
{TYPE_STRING, "TempTableDirectory", false, ""},
|
||||
{TYPE_INTEGER, "MaxStatementCacheSize", false, 2 * 1048576} // bytes
|
||||
};
|
||||
|
||||
|
||||
@ -522,9 +524,6 @@ public:
|
||||
// Service port for INET
|
||||
CONFIG_GET_PER_DB_KEY(unsigned short, getRemoteServicePort, KEY_REMOTE_SERVICE_PORT, getInt);
|
||||
|
||||
// Pipe name for WNET
|
||||
CONFIG_GET_PER_DB_STR(getRemotePipeName, KEY_REMOTE_PIPE_NAME);
|
||||
|
||||
// Name for IPC-related objects
|
||||
CONFIG_GET_PER_DB_STR(getIpcName, KEY_IPC_NAME);
|
||||
|
||||
@ -606,6 +605,9 @@ public:
|
||||
// set in minutes
|
||||
CONFIG_GET_PER_DB_KEY(unsigned int, getConnIdleTimeout, KEY_CONN_IDLE_TIMEOUT, getInt);
|
||||
|
||||
// set in seconds
|
||||
CONFIG_GET_PER_DB_KEY(unsigned int, getOnDisconnectTrigTimeout, KEY_ON_DISCONNECT_TRIG_TIMEOUT, getInt);
|
||||
|
||||
CONFIG_GET_PER_DB_KEY(unsigned int, getClientBatchBuffer, KEY_CLIENT_BATCH_BUFFER, getInt);
|
||||
|
||||
CONFIG_GET_GLOBAL_STR(getOutputRedirectionFile, KEY_OUTPUT_REDIRECTION_FILE);
|
||||
@ -629,10 +631,12 @@ public:
|
||||
CONFIG_GET_PER_DB_KEY(ULONG, getInlineSortThreshold, KEY_INLINE_SORT_THRESHOLD, getInt);
|
||||
|
||||
CONFIG_GET_PER_DB_STR(getTempPageSpaceDirectory, KEY_TEMP_PAGESPACE_DIR);
|
||||
|
||||
CONFIG_GET_PER_DB_INT(getMaxStatementCacheSize, KEY_MAX_STATEMENT_CACHE_SIZE);
|
||||
};
|
||||
|
||||
// Implementation of interface to access master configuration file
|
||||
class FirebirdConf FB_FINAL :
|
||||
class FirebirdConf final :
|
||||
public RefCntIface<IFirebirdConfImpl<FirebirdConf, CheckStatusWrapper> >
|
||||
{
|
||||
public:
|
||||
|
@ -81,7 +81,7 @@ public:
|
||||
sub(par.sub), line(par.line)
|
||||
{ }
|
||||
Parameter()
|
||||
: AutoStorage(), name(getPool()), value(getPool()), sub(0), line(0)
|
||||
: AutoStorage(), name(getPool()), value(getPool()), line(0)
|
||||
{ }
|
||||
|
||||
SINT64 asInteger() const;
|
||||
|
@ -60,6 +60,12 @@ typedef USHORT (*pfn_INTL_keylength) (texttype* tt, USHORT len);
|
||||
#define INTL_KEY_SORT 0 /* Full sort key */
|
||||
#define INTL_KEY_PARTIAL 1 /* Starting portion of sort key for equality class */
|
||||
#define INTL_KEY_UNIQUE 2 /* Full key for the equality class of the string */
|
||||
#define INTL_KEY_MULTI_STARTING 3 /* Multiple starting keys */
|
||||
|
||||
/* INTL_KEY_MULTI_STARTING format:
|
||||
key ::= { <key_length> <key_bytes> }...
|
||||
key_length ::= <key length least significant byte> <key length most significant byte>
|
||||
*/
|
||||
|
||||
/* Returned value of INTL_BAD_KEY_LENGTH means that key error happened during
|
||||
key construction. When partial key is requested returned string should
|
||||
@ -130,6 +136,8 @@ typedef void (*pfn_INTL_tt_destroy) (texttype* tt);
|
||||
(char, case, accent) which is case-insensitive,
|
||||
but accent-sensitive */
|
||||
|
||||
#define TEXTTYPE_MULTI_STARTING_KEY 8 /* Supports INTL_KEY_MULTI_STARTING */
|
||||
|
||||
|
||||
struct texttype
|
||||
{
|
||||
@ -346,6 +354,20 @@ typedef INTL_BOOL (*pfn_INTL_lookup_texttype) (
|
||||
const ASCII* config_info
|
||||
);
|
||||
|
||||
/* typedef for texttype lookup entry-point - with status buffer */
|
||||
typedef INTL_BOOL (*pfn_INTL_lookup_texttype_with_status) (
|
||||
char* status_buffer,
|
||||
ULONG status_buffer_length,
|
||||
texttype* tt,
|
||||
const ASCII* texttype_name,
|
||||
const ASCII* charset_name,
|
||||
USHORT attributes,
|
||||
const UCHAR* specific_attributes,
|
||||
ULONG specific_attributes_length,
|
||||
INTL_BOOL ignore_attributes,
|
||||
const ASCII* config_info
|
||||
);
|
||||
|
||||
/* typedef for charset lookup entry-point */
|
||||
typedef INTL_BOOL (*pfn_INTL_lookup_charset) (
|
||||
charset* cs,
|
||||
@ -371,6 +393,7 @@ typedef ULONG (*pfn_INTL_setup_attributes) (
|
||||
|
||||
|
||||
#define TEXTTYPE_ENTRYPOINT LD_lookup_texttype
|
||||
#define TEXTTYPE_WITH_STATUS_ENTRYPOINT LD_lookup_texttype_with_status
|
||||
#define CHARSET_ENTRYPOINT LD_lookup_charset
|
||||
#define INTL_VERSION_ENTRYPOINT LD_version
|
||||
#define INTL_SETUP_ATTRIBUTES_ENTRYPOINT LD_setup_attributes
|
||||
|
@ -30,13 +30,15 @@
|
||||
#include "../common/classes/fb_string.h"
|
||||
#include "../common/common.h"
|
||||
|
||||
enum iscProtocol {ISC_PROTOCOL_LOCAL, ISC_PROTOCOL_TCPIP, ISC_PROTOCOL_WLAN};
|
||||
enum iscProtocol {ISC_PROTOCOL_LOCAL, ISC_PROTOCOL_TCPIP};
|
||||
|
||||
#ifndef NO_NFS
|
||||
bool ISC_analyze_nfs(Firebird::PathName&, Firebird::PathName&);
|
||||
#endif
|
||||
bool ISC_analyze_protocol(const char*, Firebird::PathName&, Firebird::PathName&, const char*, bool needFile);
|
||||
#ifdef WIN_NT
|
||||
bool ISC_analyze_pclan(Firebird::PathName&, Firebird::PathName&);
|
||||
#endif
|
||||
bool ISC_analyze_protocol(const char*, Firebird::PathName&, Firebird::PathName&, const char*, bool needFile);
|
||||
bool ISC_analyze_tcp(Firebird::PathName&, Firebird::PathName&, bool = true);
|
||||
bool ISC_check_if_remote(const Firebird::PathName&, bool);
|
||||
iscProtocol ISC_extract_host(Firebird::PathName&, Firebird::PathName&, bool);
|
||||
|
@ -346,6 +346,47 @@ bool ISC_analyze_nfs(tstring& expanded_filename, tstring& node_name)
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(WIN_NT)
|
||||
bool ISC_analyze_pclan(tstring& expanded_name, tstring& node_name)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
* I S C _ a n a l y z e _ p c l a n
|
||||
*
|
||||
**************************************
|
||||
*
|
||||
* Functional description
|
||||
* Check a file name for a SMB mount point. If so,
|
||||
* decompose into node name and remote file name.
|
||||
*
|
||||
**************************************/
|
||||
ISC_expand_share(expanded_name);
|
||||
|
||||
if (expanded_name.length() < 2 ||
|
||||
(expanded_name[0] != '\\' && expanded_name[0] != '/') ||
|
||||
(expanded_name[1] != '\\' && expanded_name[1] != '/'))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const size p = expanded_name.find_first_of("\\/", 2);
|
||||
if (p == npos)
|
||||
return false;
|
||||
|
||||
if (Config::getRemoteFileOpenAbility())
|
||||
{
|
||||
if (expanded_name.find(':', p + 1) == npos)
|
||||
return false;
|
||||
}
|
||||
|
||||
node_name = expanded_name.substr(2, p - 2);
|
||||
expanded_name.erase(0, p + 1);
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
bool ISC_analyze_protocol(const char* protocol, tstring& expanded_name, tstring& node_name,
|
||||
const char* separator, bool need_file)
|
||||
{
|
||||
@ -403,57 +444,6 @@ bool ISC_analyze_protocol(const char* protocol, tstring& expanded_name, tstring&
|
||||
}
|
||||
|
||||
|
||||
#if defined(WIN_NT)
|
||||
bool ISC_analyze_pclan(tstring& expanded_name, tstring& node_name)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
* I S C _ a n a l y z e _ p c l a n
|
||||
*
|
||||
**************************************
|
||||
*
|
||||
* Functional description
|
||||
* Analyze a filename for a named pipe node name on the front.
|
||||
* If one is found, extract the node name, compute the residual
|
||||
* file name, and return true. Otherwise return false.
|
||||
*
|
||||
**************************************/
|
||||
node_name.erase();
|
||||
if (expanded_name.length() < 2 ||
|
||||
(expanded_name[0] != '\\' && expanded_name[0] != '/') ||
|
||||
(expanded_name[1] != '\\' && expanded_name[1] != '/'))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const size p = expanded_name.find_first_of("\\/", 2);
|
||||
if (p == npos)
|
||||
return false;
|
||||
|
||||
if (Config::getRemoteFileOpenAbility())
|
||||
{
|
||||
if (expanded_name.find(':', p + 1) == npos)
|
||||
return false;
|
||||
}
|
||||
|
||||
node_name = "\\\\";
|
||||
node_name += expanded_name.substr(2, p - 2);
|
||||
|
||||
// If this is a loopback, substitute "." for the host name. Otherwise,
|
||||
// the CreateFile on the pipe will fail.
|
||||
TEXT localhost[MAXHOSTLEN];
|
||||
ISC_get_host(localhost, sizeof(localhost));
|
||||
if (node_name.substr(2, npos) == localhost)
|
||||
{
|
||||
node_name.replace(2, npos, ".");
|
||||
}
|
||||
|
||||
expanded_name.erase(0, p + 1);
|
||||
return true;
|
||||
}
|
||||
#endif // WIN_NT
|
||||
|
||||
|
||||
bool ISC_analyze_tcp(tstring& file_name, tstring& node_name, bool need_file)
|
||||
{
|
||||
/**************************************
|
||||
@ -564,46 +554,22 @@ iscProtocol ISC_extract_host(Firebird::PathName& file_name,
|
||||
// Always check for an explicit TCP node name
|
||||
|
||||
if (ISC_analyze_tcp(file_name, host_name))
|
||||
{
|
||||
return ISC_PROTOCOL_TCPIP;
|
||||
}
|
||||
#ifndef NO_NFS
|
||||
|
||||
if (implicit_flag)
|
||||
{
|
||||
// Check for a file on an NFS mounted device
|
||||
// Check for a file on a network mount
|
||||
|
||||
if (ISC_analyze_nfs(file_name, host_name))
|
||||
{
|
||||
#ifdef WIN_NT
|
||||
if (ISC_analyze_pclan(file_name, host_name))
|
||||
return ISC_PROTOCOL_TCPIP;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(WIN_NT)
|
||||
// Check for an explicit named pipe node name
|
||||
|
||||
if (ISC_analyze_pclan(file_name, host_name))
|
||||
{
|
||||
return ISC_PROTOCOL_WLAN;
|
||||
}
|
||||
|
||||
if (implicit_flag)
|
||||
{
|
||||
// Check for a file on a shared drive. First try to expand
|
||||
// the path. Then check the expanded path for a TCP or named pipe.
|
||||
|
||||
ISC_expand_share(file_name);
|
||||
if (ISC_analyze_tcp(file_name, host_name))
|
||||
{
|
||||
#ifndef NO_NFS
|
||||
if (ISC_analyze_nfs(file_name, host_name))
|
||||
return ISC_PROTOCOL_TCPIP;
|
||||
#endif
|
||||
}
|
||||
if (ISC_analyze_pclan(file_name, host_name))
|
||||
{
|
||||
return ISC_PROTOCOL_WLAN;
|
||||
}
|
||||
|
||||
}
|
||||
#endif // WIN_NT
|
||||
|
||||
return ISC_PROTOCOL_LOCAL;
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ public:
|
||||
const Firebird::PathName fileName;
|
||||
|
||||
#ifdef LINUX
|
||||
virtual bool getRealPath(Firebird::PathName& realPath) = 0;
|
||||
virtual bool getRealPath(Firebird::PathName& path) = 0;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
|
@ -46,18 +46,16 @@
|
||||
class DlfcnModule : public ModuleLoader::Module
|
||||
{
|
||||
public:
|
||||
DlfcnModule(MemoryPool& pool, const Firebird::PathName& aFileName, void* m)
|
||||
: ModuleLoader::Module(pool, aFileName),
|
||||
module(m)
|
||||
{}
|
||||
|
||||
DlfcnModule(MemoryPool& pool, const Firebird::PathName& aFileName, void* m);
|
||||
~DlfcnModule();
|
||||
void* findSymbol(ISC_STATUS*, const Firebird::string&);
|
||||
|
||||
bool getRealPath(Firebird::PathName& realPath);
|
||||
void* findSymbol(ISC_STATUS*, const Firebird::string&) override;
|
||||
|
||||
bool getRealPath(Firebird::PathName& path) override;
|
||||
|
||||
private:
|
||||
void* module;
|
||||
Firebird::PathName realPath;
|
||||
};
|
||||
|
||||
static void makeErrorStatus(ISC_STATUS* status, const char* text)
|
||||
@ -154,6 +152,47 @@ ModuleLoader::Module* ModuleLoader::loadModule(ISC_STATUS* status, const Firebir
|
||||
return FB_NEW_POOL(*getDefaultMemoryPool()) DlfcnModule(*getDefaultMemoryPool(), linkPath, module);
|
||||
}
|
||||
|
||||
DlfcnModule::DlfcnModule(MemoryPool& pool, const Firebird::PathName& aFileName, void* m)
|
||||
: ModuleLoader::Module(pool, aFileName),
|
||||
module(m),
|
||||
realPath(pool)
|
||||
{
|
||||
#ifdef HAVE_DLINFO
|
||||
char b[PATH_MAX];
|
||||
|
||||
#ifdef HAVE_RTLD_DI_ORIGIN
|
||||
if (dlinfo(module, RTLD_DI_ORIGIN, b) == 0)
|
||||
{
|
||||
realPath = b;
|
||||
realPath += '/';
|
||||
realPath += fileName;
|
||||
|
||||
if (realpath(realPath.c_str(), b))
|
||||
{
|
||||
realPath = b;
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_RTLD_DI_LINKMAP
|
||||
struct link_map* lm;
|
||||
if (dlinfo(module, RTLD_DI_LINKMAP, &lm) == 0)
|
||||
{
|
||||
if (realpath(lm->l_name, b))
|
||||
{
|
||||
realPath = b;
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
// Error getting real path.
|
||||
realPath.clear();
|
||||
}
|
||||
|
||||
DlfcnModule::~DlfcnModule()
|
||||
{
|
||||
if (module)
|
||||
@ -165,7 +204,7 @@ void* DlfcnModule::findSymbol(ISC_STATUS* status, const Firebird::string& symNam
|
||||
void* result = dlsym(module, symName.c_str());
|
||||
if (!result)
|
||||
{
|
||||
Firebird::string newSym ='_' + symName;
|
||||
Firebird::string newSym = '_' + symName;
|
||||
result = dlsym(module, newSym.c_str());
|
||||
}
|
||||
|
||||
@ -183,20 +222,28 @@ void* DlfcnModule::findSymbol(ISC_STATUS* status, const Firebird::string& symNam
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const auto& libraryPath = realPath.isEmpty() ? fileName : realPath;
|
||||
|
||||
char symbolPathBuffer[PATH_MAX];
|
||||
const char* symbolPath = symbolPathBuffer;
|
||||
|
||||
if (!realpath(info.dli_fname, symbolPathBuffer))
|
||||
symbolPath = info.dli_fname;
|
||||
|
||||
const char* errText = "Actual module name does not match requested";
|
||||
if (PathUtils::isRelative(fileName) || PathUtils::isRelative(info.dli_fname))
|
||||
if (PathUtils::isRelative(libraryPath) || PathUtils::isRelative(symbolPath))
|
||||
{
|
||||
// check only name (not path) of the library
|
||||
Firebird::PathName dummyDir, nm1, nm2;
|
||||
PathUtils::splitLastComponent(dummyDir, nm1, fileName);
|
||||
PathUtils::splitLastComponent(dummyDir, nm2, info.dli_fname);
|
||||
PathUtils::splitLastComponent(dummyDir, nm1, libraryPath);
|
||||
PathUtils::splitLastComponent(dummyDir, nm2, symbolPath);
|
||||
if (nm1 != nm2)
|
||||
{
|
||||
makeErrorStatus(status, errText);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else if (fileName != info.dli_fname)
|
||||
else if (libraryPath != symbolPath)
|
||||
{
|
||||
makeErrorStatus(status, errText);
|
||||
return NULL;
|
||||
@ -206,38 +253,11 @@ void* DlfcnModule::findSymbol(ISC_STATUS* status, const Firebird::string& symNam
|
||||
return result;
|
||||
}
|
||||
|
||||
bool DlfcnModule::getRealPath(Firebird::PathName& realPath)
|
||||
bool DlfcnModule::getRealPath(Firebird::PathName& path)
|
||||
{
|
||||
#ifdef HAVE_DLINFO
|
||||
char b[PATH_MAX];
|
||||
|
||||
#ifdef HAVE_RTLD_DI_ORIGIN
|
||||
if (dlinfo(module, RTLD_DI_ORIGIN, b) == 0)
|
||||
{
|
||||
realPath = b;
|
||||
realPath += '/';
|
||||
realPath += fileName;
|
||||
|
||||
if (realpath(realPath.c_str(), b))
|
||||
{
|
||||
realPath = b;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_RTLD_DI_LINKMAP
|
||||
struct link_map* lm;
|
||||
if (dlinfo(module, RTLD_DI_LINKMAP, &lm) == 0)
|
||||
{
|
||||
if (realpath(lm->l_name, b))
|
||||
{
|
||||
realPath = b;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
if (realPath.isEmpty())
|
||||
return false;
|
||||
|
||||
path = realPath;
|
||||
return true;
|
||||
}
|
||||
|
@ -87,26 +87,34 @@ public:
|
||||
memset(&ackd, 0, sizeof(ackd));
|
||||
ackd.cbSize = sizeof(ackd);
|
||||
|
||||
const char* crtDll =
|
||||
#if _MSC_VER == 1400
|
||||
"msvcr80.dll";
|
||||
#elif _MSC_VER == 1500
|
||||
"msvcr90.dll";
|
||||
#elif _MSC_VER == 1600
|
||||
"msvcr100.dll";
|
||||
#elif _MSC_VER == 1700
|
||||
"msvcr110.dll";
|
||||
#elif _MSC_VER == 1800
|
||||
"msvcr120.dll";
|
||||
#elif _MSC_VER >= 1900 && _MSC_VER < 2000
|
||||
"vcruntime140.dll";
|
||||
#else
|
||||
"";
|
||||
|
||||
#define TO_STR(x) #x
|
||||
#define ERRSTR(x) "Unknown " #x " value: " TO_STR(x) ". Specify CRT DLL name here !"
|
||||
|
||||
static_assert(false, ERRSTR(_MSC_VER));
|
||||
// #error Specify CRT DLL name here !
|
||||
#endif
|
||||
|
||||
// if CRT already present in some activation context then nothing to do
|
||||
if ((*mFindActCtxSectionString)
|
||||
(0, NULL,
|
||||
ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION,
|
||||
#if _MSC_VER == 1400
|
||||
"msvcr80.dll",
|
||||
#elif _MSC_VER == 1500
|
||||
"msvcr90.dll",
|
||||
#elif _MSC_VER == 1600
|
||||
"msvcr100.dll",
|
||||
#elif _MSC_VER == 1700
|
||||
"msvcr110.dll",
|
||||
#elif _MSC_VER == 1800
|
||||
"msvcr120.dll",
|
||||
#elif _MSC_VER >= 1900 && _MSC_VER <= 1930
|
||||
"vcruntime140.dll",
|
||||
#else
|
||||
#error Specify CRT DLL name here !
|
||||
#endif
|
||||
&ackd))
|
||||
crtDll, &ackd))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -232,7 +232,7 @@ public:
|
||||
IntField u, g;
|
||||
};
|
||||
|
||||
class StackUserData FB_FINAL : public UserData
|
||||
class StackUserData final : public UserData
|
||||
{
|
||||
public:
|
||||
void* operator new(size_t, void* memory) throw()
|
||||
@ -241,7 +241,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class DynamicUserData FB_FINAL : public UserData
|
||||
class DynamicUserData final : public UserData
|
||||
{
|
||||
public:
|
||||
#ifdef DEBUG_GDS_ALLOC
|
||||
|
@ -92,22 +92,24 @@ public:
|
||||
// System-wide ICU have no version number at entries names
|
||||
if (!majorVersion)
|
||||
{
|
||||
fb_assert(false); // ASF: I don't think this code path is correct.
|
||||
|
||||
if (module->findSymbol(NULL, name, ptr))
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// ICU has several schemas for entries names
|
||||
const char* patterns[] =
|
||||
const char* const patterns[] =
|
||||
{
|
||||
"%s_%d", "%s_%d_%d", "%s_%d%d", "%s", NULL
|
||||
"%s_%d", "%s_%d_%d", "%s_%d%d", "%s"
|
||||
};
|
||||
|
||||
string symbol;
|
||||
|
||||
for (const char** p = patterns; *p; ++p)
|
||||
for (auto pattern : patterns)
|
||||
{
|
||||
symbol.printf(*p, name, majorVersion, minorVersion);
|
||||
symbol.printf(pattern, name, majorVersion, minorVersion);
|
||||
if (module->findSymbol(NULL, symbol, ptr))
|
||||
return;
|
||||
}
|
||||
@ -272,8 +274,10 @@ public:
|
||||
USet* (U_EXPORT2 *usetOpen)(UChar32 start, UChar32 end);
|
||||
|
||||
void (U_EXPORT2 *ucolClose)(UCollator* coll);
|
||||
int32_t (U_EXPORT2 *ucolGetContractions)(const UCollator* coll, USet* conts, UErrorCode* status);
|
||||
int32_t (U_EXPORT2 *ucolGetContractionsAndExpansions)(const UCollator* coll, USet* contractions, USet* expansions,
|
||||
UBool addPrefixes, UErrorCode* status);
|
||||
const UChar* (U_EXPORT2 *ucolGetRules)(const UCollator* coll, int32_t* length);
|
||||
|
||||
int32_t (U_EXPORT2 *ucolGetSortKey)(const UCollator* coll, const UChar* source,
|
||||
int32_t sourceLength, uint8_t* result, int32_t resultLength);
|
||||
UCollator* (U_EXPORT2 *ucolOpen)(const char* loc, UErrorCode* status);
|
||||
@ -321,6 +325,7 @@ private:
|
||||
getEntryPoint("ucnv_open", module, ucnv_open);
|
||||
getEntryPoint("ucnv_close", module, ucnv_close);
|
||||
getEntryPoint("ucnv_fromUChars", module, ucnv_fromUChars);
|
||||
getEntryPoint("u_getVersion", module, u_getVersion);
|
||||
getEntryPoint("u_tolower", module, u_tolower);
|
||||
getEntryPoint("u_toupper", module, u_toupper);
|
||||
getEntryPoint("u_strCompare", module, u_strCompare);
|
||||
@ -379,8 +384,11 @@ public:
|
||||
|
||||
if (o)
|
||||
{
|
||||
o->vMajor = majorVersion;
|
||||
o->vMinor = minorVersion;
|
||||
UVersionInfo versionInfo;
|
||||
o->u_getVersion(versionInfo);
|
||||
|
||||
o->vMajor = versionInfo[0];
|
||||
o->vMinor = versionInfo[1];
|
||||
}
|
||||
|
||||
return o;
|
||||
@ -507,15 +515,20 @@ static ModuleLoader::Module* formatAndLoad(const char* templateName,
|
||||
else
|
||||
{
|
||||
// ICU has several schemas for placing version into file name
|
||||
const char* patterns[] =
|
||||
const char* const patterns[] =
|
||||
{
|
||||
"%d_%d", "%d%d", NULL
|
||||
#ifdef WIN_NT
|
||||
"%d",
|
||||
#endif
|
||||
"%d_%d",
|
||||
"%d.%d",
|
||||
"%d%d"
|
||||
};
|
||||
|
||||
PathName s, filename;
|
||||
for (const char** p = patterns; *p; ++p)
|
||||
for (auto pattern : patterns)
|
||||
{
|
||||
s.printf(*p, majorVersion, minorVersion);
|
||||
s.printf(pattern, majorVersion, minorVersion);
|
||||
filename.printf(templateName, s.c_str());
|
||||
|
||||
module = ModuleLoader::fixAndLoadModule(NULL, filename);
|
||||
@ -523,7 +536,9 @@ static ModuleLoader::Module* formatAndLoad(const char* templateName,
|
||||
break;
|
||||
}
|
||||
|
||||
#ifndef WIN_NT
|
||||
// There is no sence to try pattern "%d" for different minor versions
|
||||
// ASF: In Windows ICU 63.1 libraries use 63.dll suffix. This is handled in 'patterns' above.
|
||||
if (!module && minorVersion == 0)
|
||||
{
|
||||
s.printf("%d", majorVersion);
|
||||
@ -531,6 +546,7 @@ static ModuleLoader::Module* formatAndLoad(const char* templateName,
|
||||
|
||||
module = ModuleLoader::fixAndLoadModule(NULL, filename);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return module;
|
||||
@ -1169,7 +1185,7 @@ UnicodeUtil::ICU* UnicodeUtil::loadICU(const string& icuVersion, const string& c
|
||||
getVersions(configInfo, versions);
|
||||
|
||||
if (versions.isEmpty())
|
||||
gds__log("No versions");
|
||||
gds__log("No ICU versions specified");
|
||||
|
||||
string version = icuVersion.isEmpty() ? versions[0] : icuVersion;
|
||||
if (version == "default")
|
||||
@ -1241,7 +1257,8 @@ UnicodeUtil::ICU* UnicodeUtil::loadICU(const string& icuVersion, const string& c
|
||||
icu->getEntryPoint("uset_open", icu->ucModule, icu->usetOpen);
|
||||
|
||||
icu->getEntryPoint("ucol_close", icu->inModule, icu->ucolClose);
|
||||
icu->getEntryPoint("ucol_getContractions", icu->inModule, icu->ucolGetContractions);
|
||||
icu->getEntryPoint("ucol_getContractionsAndExpansions", icu->inModule,
|
||||
icu->ucolGetContractionsAndExpansions);
|
||||
icu->getEntryPoint("ucol_getRules", icu->inModule, icu->ucolGetRules);
|
||||
icu->getEntryPoint("ucol_getSortKey", icu->inModule, icu->ucolGetSortKey);
|
||||
icu->getEntryPoint("ucol_open", icu->inModule, icu->ucolOpen);
|
||||
@ -1295,6 +1312,13 @@ UnicodeUtil::ICU* UnicodeUtil::loadICU(const string& icuVersion, const string& c
|
||||
}
|
||||
|
||||
|
||||
void UnicodeUtil::getICUVersion(ICU* icu, int& majorVersion, int& minorVersion)
|
||||
{
|
||||
majorVersion = icu->majorVersion;
|
||||
minorVersion = icu->minorVersion;
|
||||
}
|
||||
|
||||
|
||||
UnicodeUtil::ConversionICU& UnicodeUtil::getConversionICU()
|
||||
{
|
||||
if (convIcu)
|
||||
@ -1311,7 +1335,7 @@ UnicodeUtil::ConversionICU& UnicodeUtil::getConversionICU()
|
||||
|
||||
// Try "favorite" (distributed on windows) version first
|
||||
const int favMaj = 63;
|
||||
const int favMin = 0;
|
||||
const int favMin = 1;
|
||||
try
|
||||
{
|
||||
if ((convIcu = ImplementConversionICU::create(favMaj, favMin)))
|
||||
@ -1408,13 +1432,13 @@ string UnicodeUtil::getDefaultIcuVersion()
|
||||
}
|
||||
|
||||
|
||||
bool UnicodeUtil::getCollVersion(const Firebird::string& icuVersion,
|
||||
UnicodeUtil::ICU* UnicodeUtil::getCollVersion(const Firebird::string& icuVersion,
|
||||
const Firebird::string& configInfo, Firebird::string& collVersion)
|
||||
{
|
||||
ICU* icu = loadICU(icuVersion, configInfo);
|
||||
|
||||
if (!icu)
|
||||
return false;
|
||||
return nullptr;
|
||||
|
||||
char version[U_MAX_VERSION_STRING_LENGTH];
|
||||
icu->uVersionToString(icu->collVersion, version);
|
||||
@ -1424,7 +1448,7 @@ bool UnicodeUtil::getCollVersion(const Firebird::string& icuVersion,
|
||||
else
|
||||
collVersion = version;
|
||||
|
||||
return true;
|
||||
return icu;
|
||||
}
|
||||
|
||||
UnicodeUtil::Utf16Collation* UnicodeUtil::Utf16Collation::create(
|
||||
@ -1499,12 +1523,11 @@ UnicodeUtil::Utf16Collation* UnicodeUtil::Utf16Collation::create(
|
||||
|
||||
tt->texttype_pad_option = (attributes & TEXTTYPE_ATTR_PAD_SPACE) ? true : false;
|
||||
|
||||
ICU* icu = loadICU(collVersion, locale, configInfo);
|
||||
if (!icu)
|
||||
{
|
||||
gds__log("loadICU failed");
|
||||
return NULL;
|
||||
}
|
||||
string icuVersion;
|
||||
if (specificAttributes.get(IntlUtil::convertAsciiToUtf16("ICU-VERSION"), icuVersion))
|
||||
icuVersion = IntlUtil::convertUtf16ToAscii(icuVersion, &error);
|
||||
|
||||
const auto icu = loadICU(icuVersion, collVersion, locale, configInfo);
|
||||
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
HalfStaticArray<UChar, BUFFER_TINY> rulesBuffer;
|
||||
@ -1617,35 +1640,145 @@ UnicodeUtil::Utf16Collation* UnicodeUtil::Utf16Collation::create(
|
||||
|
||||
USet* contractions = icu->usetOpen(1, 0);
|
||||
// status not verified here.
|
||||
icu->ucolGetContractions(partialCollator, contractions, &status);
|
||||
icu->ucolGetContractionsAndExpansions(partialCollator, contractions, nullptr, false, &status);
|
||||
|
||||
int contractionsCount = icu->usetGetItemCount(contractions);
|
||||
|
||||
for (int contractionIndex = 0; contractionIndex < contractionsCount; ++contractionIndex)
|
||||
{
|
||||
UChar str[10];
|
||||
UChar strChars[10];
|
||||
UChar32 start, end;
|
||||
|
||||
status = U_ZERO_ERROR;
|
||||
int len = icu->usetGetItem(contractions, contractionIndex, &start, &end, str, sizeof(str), &status);
|
||||
int len = icu->usetGetItem(contractions, contractionIndex, &start, &end, strChars, sizeof(strChars), &status);
|
||||
|
||||
if (len >= 2)
|
||||
{
|
||||
obj->maxContractionsPrefixLength = len - 1 > obj->maxContractionsPrefixLength ?
|
||||
len - 1 : obj->maxContractionsPrefixLength;
|
||||
|
||||
for (int currentLen = 1; currentLen < len; ++currentLen)
|
||||
{
|
||||
string s(reinterpret_cast<const char*>(str), currentLen * 2);
|
||||
UCHAR key[100];
|
||||
int keyLen = icu->ucolGetSortKey(partialCollator, strChars, len, key, sizeof(key));
|
||||
|
||||
if (!obj->contractionsPrefix.exist(s))
|
||||
obj->contractionsPrefix.push(s);
|
||||
for (int prefixLen = 1; prefixLen < len; ++prefixLen)
|
||||
{
|
||||
const Array<USHORT> str(reinterpret_cast<USHORT*>(strChars), prefixLen);
|
||||
auto keySet = obj->contractionsPrefix.get(str);
|
||||
|
||||
if (!keySet)
|
||||
{
|
||||
keySet = obj->contractionsPrefix.put(str);
|
||||
|
||||
UCHAR prefixKey[100];
|
||||
int prefixKeyLen = icu->ucolGetSortKey(partialCollator,
|
||||
strChars, prefixLen, prefixKey, sizeof(prefixKey));
|
||||
|
||||
keySet->add(Array<UCHAR>(prefixKey, prefixKeyLen));
|
||||
}
|
||||
|
||||
keySet->add(Array<UCHAR>(key, keyLen));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
icu->usetClose(contractions);
|
||||
|
||||
ContractionsPrefixMap::Accessor accessor(&obj->contractionsPrefix);
|
||||
|
||||
for (bool found = accessor.getFirst(); found; found = accessor.getNext())
|
||||
{
|
||||
auto& keySet = accessor.current()->second;
|
||||
|
||||
if (keySet.getCount() <= 1)
|
||||
continue;
|
||||
|
||||
fb_assert(accessor.current()->first.hasData());
|
||||
USHORT ch = accessor.current()->first[0];
|
||||
|
||||
if (ch >= 0xFDD0 && ch <= 0xFDEF)
|
||||
{
|
||||
keySet.clear();
|
||||
keySet.add(Array<UCHAR>());
|
||||
continue;
|
||||
}
|
||||
|
||||
auto firstKeyIt = keySet.begin();
|
||||
auto lastKeyIt = --keySet.end();
|
||||
|
||||
const UCHAR* firstKeyDataIt = firstKeyIt->begin();
|
||||
const UCHAR* lastKeyDataIt = lastKeyIt->begin();
|
||||
const UCHAR* firstKeyDataEnd = firstKeyIt->end();
|
||||
const UCHAR* lastKeyDataEnd = lastKeyIt->end();
|
||||
|
||||
if (*firstKeyDataIt == *lastKeyDataIt)
|
||||
{
|
||||
unsigned common = 0;
|
||||
|
||||
do
|
||||
{
|
||||
++common;
|
||||
} while (++firstKeyDataIt != firstKeyDataEnd && ++lastKeyDataIt != lastKeyDataEnd &&
|
||||
*firstKeyDataIt == *lastKeyDataIt);
|
||||
|
||||
Array<UCHAR> commonKey(firstKeyIt->begin(), common);
|
||||
keySet.clear();
|
||||
keySet.add(commonKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto secondKeyIt = ++keySet.begin();
|
||||
const UCHAR* secondKeyDataIt = secondKeyIt->begin();
|
||||
const UCHAR* secondKeyDataEnd = secondKeyIt->end();
|
||||
|
||||
ObjectsArray<Array<UCHAR> > commonKeys;
|
||||
commonKeys.add(*firstKeyIt);
|
||||
|
||||
while (secondKeyIt != keySet.end())
|
||||
{
|
||||
unsigned common = 0;
|
||||
|
||||
while (firstKeyDataIt != firstKeyDataEnd && secondKeyDataIt != secondKeyDataEnd &&
|
||||
*firstKeyDataIt == *secondKeyDataIt)
|
||||
{
|
||||
++common;
|
||||
++firstKeyDataIt;
|
||||
++secondKeyDataIt;
|
||||
}
|
||||
|
||||
unsigned backSize = commonKeys.back()->getCount();
|
||||
|
||||
if (common > backSize)
|
||||
commonKeys.back()->append(secondKeyIt->begin() + backSize, common - backSize);
|
||||
else if (common < backSize)
|
||||
{
|
||||
if (common == 0)
|
||||
commonKeys.push(*secondKeyIt);
|
||||
else
|
||||
commonKeys.back()->resize(common);
|
||||
}
|
||||
|
||||
if (++secondKeyIt != keySet.end())
|
||||
{
|
||||
++firstKeyIt;
|
||||
|
||||
firstKeyDataIt = firstKeyIt->begin();
|
||||
secondKeyDataIt = secondKeyIt->begin();
|
||||
|
||||
firstKeyDataEnd = firstKeyIt->end();
|
||||
secondKeyDataEnd = secondKeyIt->end();
|
||||
}
|
||||
}
|
||||
|
||||
keySet.clear();
|
||||
|
||||
for (auto ck : commonKeys)
|
||||
keySet.add(ck);
|
||||
}
|
||||
}
|
||||
|
||||
if (obj->maxContractionsPrefixLength)
|
||||
tt->texttype_flags |= TEXTTYPE_MULTI_STARTING_KEY;
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
@ -1696,41 +1829,17 @@ USHORT UnicodeUtil::Utf16Collation::stringToKey(USHORT srcLen, const USHORT* src
|
||||
srcLenLong = pad - src + 1;
|
||||
}
|
||||
|
||||
if (srcLenLong == 0)
|
||||
return 0;
|
||||
|
||||
HalfStaticArray<USHORT, BUFFER_SMALL / 2> buffer;
|
||||
const UCollator* coll = NULL;
|
||||
|
||||
switch (key_type)
|
||||
{
|
||||
case INTL_KEY_PARTIAL:
|
||||
case INTL_KEY_MULTI_STARTING:
|
||||
coll = partialCollator;
|
||||
|
||||
// Remove last bytes of key if they are start of a contraction
|
||||
// to correctly find in the index.
|
||||
|
||||
for (int i = MIN(maxContractionsPrefixLength, srcLenLong); i > 0; --i)
|
||||
{
|
||||
if (contractionsPrefix.exist(string(reinterpret_cast<const char*>(src + srcLenLong - i), i * 2)))
|
||||
{
|
||||
srcLenLong -= i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (numericSort)
|
||||
{
|
||||
// ASF: Wee need to remove trailing numbers to return sub key that
|
||||
// matches full key. Example: "abc1" becomes "abc" to match "abc10".
|
||||
const USHORT* p = src + srcLenLong - 1;
|
||||
|
||||
for (; p >= src; --p)
|
||||
{
|
||||
if (!(*p >= '0' && *p <= '9'))
|
||||
break;
|
||||
}
|
||||
|
||||
srcLenLong = p - src + 1;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case INTL_KEY_UNIQUE:
|
||||
@ -1749,11 +1858,100 @@ USHORT UnicodeUtil::Utf16Collation::stringToKey(USHORT srcLen, const USHORT* src
|
||||
return INTL_BAD_KEY_LENGTH;
|
||||
}
|
||||
|
||||
if (srcLenLong == 0)
|
||||
return 0;
|
||||
if (key_type == INTL_KEY_MULTI_STARTING)
|
||||
{
|
||||
bool trailingNumbersRemoved = false;
|
||||
|
||||
return icu->ucolGetSortKey(coll,
|
||||
if (numericSort)
|
||||
{
|
||||
// ASF: Wee need to remove trailing numbers to return sub key that
|
||||
// matches full key. Example: "abc1" becomes "abc" to match "abc10".
|
||||
const USHORT* p = src + srcLenLong - 1;
|
||||
|
||||
for (; p >= src; --p)
|
||||
{
|
||||
if (!(*p >= '0' && *p <= '9'))
|
||||
break;
|
||||
|
||||
trailingNumbersRemoved = true;
|
||||
}
|
||||
|
||||
srcLenLong = p - src + 1;
|
||||
}
|
||||
|
||||
if (!trailingNumbersRemoved)
|
||||
{
|
||||
for (int i = MIN(maxContractionsPrefixLength, srcLenLong); i > 0; --i)
|
||||
{
|
||||
auto keys = contractionsPrefix.get(Array<USHORT>(src + srcLenLong - i, i));
|
||||
|
||||
if (keys)
|
||||
{
|
||||
const UCHAR* dstStart = dst;
|
||||
ULONG prefixLen;
|
||||
|
||||
srcLenLong -= i;
|
||||
|
||||
if (srcLenLong != 0)
|
||||
{
|
||||
prefixLen = icu->ucolGetSortKey(coll,
|
||||
reinterpret_cast<const UChar*>(src), srcLenLong, dst + 2, dstLen - 2);
|
||||
|
||||
if (prefixLen == 0 || prefixLen > dstLen - 2 || prefixLen > MAX_USHORT)
|
||||
return INTL_BAD_KEY_LENGTH;
|
||||
|
||||
fb_assert(dst[2 + prefixLen - 1] == '\0');
|
||||
--prefixLen;
|
||||
dstLen -= 2 + prefixLen;
|
||||
}
|
||||
else
|
||||
prefixLen = 0;
|
||||
|
||||
for (const auto& keyIt : *keys)
|
||||
{
|
||||
const ULONG keyLen = prefixLen + keyIt.getCount();
|
||||
|
||||
if (keyLen > dstLen - 2 || keyLen > MAX_USHORT)
|
||||
return INTL_BAD_KEY_LENGTH;
|
||||
|
||||
dst[0] = UCHAR(keyLen & 0xFF);
|
||||
dst[1] = UCHAR(keyLen >> 8);
|
||||
|
||||
if (dst != dstStart)
|
||||
memcpy(dst + 2, dstStart + 2, prefixLen);
|
||||
|
||||
memcpy(dst + 2 + prefixLen, keyIt.begin(), keyIt.getCount());
|
||||
dst += 2 + keyLen;
|
||||
dstLen -= 2 + keyLen;
|
||||
}
|
||||
|
||||
return dst - dstStart;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ULONG keyLen = icu->ucolGetSortKey(coll,
|
||||
reinterpret_cast<const UChar*>(src), srcLenLong, dst + 2, dstLen - 3);
|
||||
|
||||
if (keyLen == 0 || keyLen > dstLen - 3 || keyLen > MAX_USHORT)
|
||||
return INTL_BAD_KEY_LENGTH;
|
||||
|
||||
fb_assert(dst[2 + keyLen - 1] == '\0');
|
||||
--keyLen;
|
||||
|
||||
dst[0] = UCHAR(keyLen & 0xFF);
|
||||
dst[1] = UCHAR(keyLen >> 8);
|
||||
|
||||
return keyLen + 2;
|
||||
}
|
||||
|
||||
const ULONG keyLen = icu->ucolGetSortKey(coll,
|
||||
reinterpret_cast<const UChar*>(src), srcLenLong, dst, dstLen);
|
||||
|
||||
if (keyLen == 0 || keyLen > dstLen || keyLen > MAX_USHORT)
|
||||
return INTL_BAD_KEY_LENGTH;
|
||||
|
||||
return keyLen;
|
||||
}
|
||||
|
||||
|
||||
@ -1822,8 +2020,8 @@ ULONG UnicodeUtil::Utf16Collation::canonical(ULONG srcLen, const USHORT* src, UL
|
||||
|
||||
|
||||
UnicodeUtil::ICU* UnicodeUtil::Utf16Collation::loadICU(
|
||||
const Firebird::string& collVersion, const Firebird::string& locale,
|
||||
const Firebird::string& configInfo)
|
||||
const string& icuVersion, const string& collVersion,
|
||||
const string& locale, const string& configInfo)
|
||||
{
|
||||
ObjectsArray<string> versions;
|
||||
getVersions(configInfo, versions);
|
||||
@ -1866,7 +2064,26 @@ UnicodeUtil::ICU* UnicodeUtil::Utf16Collation::loadICU(
|
||||
return icu;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
string errorMsg;
|
||||
|
||||
if (icuVersion.isEmpty())
|
||||
{
|
||||
errorMsg.printf(
|
||||
"An ICU library with collation version %s is required but was not found. "
|
||||
"You may try to install another ICU version with this collation version "
|
||||
"or look for 'gfix -icu' in Firebird documentation.",
|
||||
collVersion.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
errorMsg.printf(
|
||||
"An ICU library with collation version %s is required but was not found. "
|
||||
"You may try to install ICU version %s, used to register the collation in this database "
|
||||
"or look for 'gfix -icu' in Firebird documentation.",
|
||||
collVersion.c_str(), icuVersion.c_str());
|
||||
}
|
||||
|
||||
(Arg::Gds(isc_random) << errorMsg).raise();
|
||||
}
|
||||
|
||||
|
||||
|
@ -30,7 +30,9 @@
|
||||
#include "intlobj_new.h"
|
||||
#include "../common/IntlUtil.h"
|
||||
#include "../common/os/mod_loader.h"
|
||||
#include "../common/classes/array.h"
|
||||
#include "../common/classes/fb_string.h"
|
||||
#include "../common/classes/GenericMap.h"
|
||||
#include "../common/classes/objects_array.h"
|
||||
#include <unicode/ucnv.h>
|
||||
#include <unicode/ucal.h>
|
||||
@ -56,6 +58,7 @@ public:
|
||||
const UChar *src, int32_t srcLength,
|
||||
UErrorCode *pErrorCode);
|
||||
|
||||
void (U_EXPORT2* u_getVersion) (UVersionInfo versionArray);
|
||||
UChar32 (U_EXPORT2* u_tolower) (UChar32 c);
|
||||
UChar32 (U_EXPORT2* u_toupper) (UChar32 c);
|
||||
int32_t (U_EXPORT2* u_strCompare) (const UChar* s1, int32_t length1,
|
||||
@ -175,7 +178,8 @@ public:
|
||||
|
||||
static ConversionICU& getConversionICU();
|
||||
static ICU* loadICU(const Firebird::string& icuVersion, const Firebird::string& configInfo);
|
||||
static bool getCollVersion(const Firebird::string& icuVersion,
|
||||
static void getICUVersion(ICU* icu, int& majorVersion, int& minorVersion);
|
||||
static ICU* getCollVersion(const Firebird::string& icuVersion,
|
||||
const Firebird::string& configInfo, Firebird::string& collVersion);
|
||||
|
||||
class Utf16Collation
|
||||
@ -200,8 +204,47 @@ public:
|
||||
ULONG canonical(ULONG srcLen, const USHORT* src, ULONG dstLen, ULONG* dst, const ULONG* exceptions);
|
||||
|
||||
private:
|
||||
static ICU* loadICU(const Firebird::string& collVersion, const Firebird::string& locale,
|
||||
const Firebird::string& configInfo);
|
||||
template <typename T>
|
||||
class ArrayComparator
|
||||
{
|
||||
public:
|
||||
static bool greaterThan(const Firebird::Array<T>& i1, const Firebird::Array<T>& i2)
|
||||
{
|
||||
FB_SIZE_T minCount = MIN(i1.getCount(), i2.getCount());
|
||||
int cmp = memcmp(i1.begin(), i2.begin(), minCount * sizeof(T));
|
||||
|
||||
if (cmp != 0)
|
||||
return cmp > 0;
|
||||
|
||||
return i1.getCount() > i2.getCount();
|
||||
}
|
||||
|
||||
static bool greaterThan(const Firebird::Array<T>* i1, const Firebird::Array<T>* i2)
|
||||
{
|
||||
return greaterThan(*i1, *i2);
|
||||
}
|
||||
};
|
||||
|
||||
typedef Firebird::SortedObjectsArray<
|
||||
Firebird::Array<UCHAR>,
|
||||
Firebird::InlineStorage<Firebird::Array<UCHAR>*, 3>,
|
||||
Firebird::Array<UCHAR>,
|
||||
Firebird::DefaultKeyValue<const Firebird::Array<UCHAR>*>,
|
||||
ArrayComparator<UCHAR>
|
||||
> SortKeyArray;
|
||||
|
||||
typedef Firebird::GenericMap<
|
||||
Firebird::Pair<
|
||||
Firebird::Full<
|
||||
Firebird::Array<USHORT>, // UTF-16 string
|
||||
SortKeyArray // sort keys
|
||||
>
|
||||
>,
|
||||
ArrayComparator<USHORT>
|
||||
> ContractionsPrefixMap;
|
||||
|
||||
static ICU* loadICU(const Firebird::string& icuVersion, const Firebird::string& collVersion,
|
||||
const Firebird::string& locale, const Firebird::string& configInfo);
|
||||
|
||||
void normalize(ULONG* strLen, const USHORT** str, bool forNumericSort,
|
||||
Firebird::HalfStaticArray<USHORT, BUFFER_SMALL / 2>& buffer) const;
|
||||
@ -212,7 +255,7 @@ public:
|
||||
UCollator* compareCollator;
|
||||
UCollator* partialCollator;
|
||||
UCollator* sortCollator;
|
||||
Firebird::SortedObjectsArray<Firebird::string> contractionsPrefix; // UTF-16 string
|
||||
ContractionsPrefixMap contractionsPrefix;
|
||||
unsigned maxContractionsPrefixLength; // number of characters
|
||||
bool numericSort;
|
||||
};
|
||||
|
@ -1143,7 +1143,7 @@ Firebird::PathName getPrefix(unsigned int prefType, const char* name)
|
||||
|
||||
if (s.hasData() && name[0])
|
||||
{
|
||||
s += '/';
|
||||
s += PathUtils::dir_sep;
|
||||
}
|
||||
s += name;
|
||||
gds__prefix(tmp, s.c_str());
|
||||
@ -1613,6 +1613,13 @@ bool containsErrorCode(const ISC_STATUS* v, ISC_STATUS code)
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool sqlSymbolChar(char c, bool first)
|
||||
{
|
||||
if (c & 0x80)
|
||||
return false;
|
||||
return (isdigit(c) && !first) || isalpha(c) || c == '_' || c == '$';
|
||||
}
|
||||
|
||||
const char* dpbItemUpper(const char* s, FB_SIZE_T l, Firebird::string& buf)
|
||||
{
|
||||
if (l && (s[0] == '"' || s[0] == '\''))
|
||||
@ -1625,30 +1632,38 @@ const char* dpbItemUpper(const char* s, FB_SIZE_T l, Firebird::string& buf)
|
||||
{
|
||||
if (s[i] == end_quote)
|
||||
{
|
||||
if (++i >= l || s[i] != end_quote)
|
||||
break; // delimited quote, done processing
|
||||
|
||||
// skipped the escape quote, continue processing
|
||||
}
|
||||
|
||||
if (s[i] & 0x80)
|
||||
ascii = false;
|
||||
buf += s[i];
|
||||
}
|
||||
|
||||
if (++i >= l)
|
||||
{
|
||||
if (ascii && s[0] == '\'')
|
||||
buf.upper();
|
||||
|
||||
return buf.c_str();
|
||||
}
|
||||
|
||||
if (s[i] != end_quote)
|
||||
{
|
||||
buf.assign(&s[i], l - i);
|
||||
(Firebird::Arg::Gds(isc_quoted_str_bad) << buf).raise();
|
||||
}
|
||||
|
||||
// skipped the escape quote, continue processing
|
||||
}
|
||||
else if (!sqlSymbolChar(s[i], i == 1))
|
||||
ascii = false;
|
||||
|
||||
buf += s[i];
|
||||
}
|
||||
|
||||
buf.assign(1, s[0]);
|
||||
(Firebird::Arg::Gds(isc_quoted_str_miss) << buf).raise();
|
||||
}
|
||||
|
||||
// non-quoted string - try to uppercase
|
||||
for (FB_SIZE_T i = 0; i < l; ++i)
|
||||
{
|
||||
if (!(s[i] & 0x80))
|
||||
buf += toupper(s[i]);
|
||||
else
|
||||
if (!sqlSymbolChar(s[i], i == 0))
|
||||
return NULL; // contains non-ascii data
|
||||
buf += toupper(s[i]);
|
||||
}
|
||||
|
||||
return buf.c_str();
|
||||
|
@ -356,7 +356,7 @@ AggNode* AggNode::pass2(thread_db* tdbb, CompilerScratch* csb)
|
||||
return this;
|
||||
}
|
||||
|
||||
void AggNode::aggInit(thread_db* tdbb, jrd_req* request) const
|
||||
void AggNode::aggInit(thread_db* tdbb, Request* request) const
|
||||
{
|
||||
impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset);
|
||||
impure->vlux_count = 0;
|
||||
@ -378,7 +378,7 @@ void AggNode::aggInit(thread_db* tdbb, jrd_req* request) const
|
||||
}
|
||||
}
|
||||
|
||||
bool AggNode::aggPass(thread_db* tdbb, jrd_req* request) const
|
||||
bool AggNode::aggPass(thread_db* tdbb, Request* request) const
|
||||
{
|
||||
dsc* desc = NULL;
|
||||
|
||||
@ -435,7 +435,7 @@ bool AggNode::aggPass(thread_db* tdbb, jrd_req* request) const
|
||||
return true;
|
||||
}
|
||||
|
||||
void AggNode::aggFinish(thread_db* /*tdbb*/, jrd_req* request) const
|
||||
void AggNode::aggFinish(thread_db* /*tdbb*/, Request* request) const
|
||||
{
|
||||
if (asb)
|
||||
{
|
||||
@ -445,7 +445,7 @@ void AggNode::aggFinish(thread_db* /*tdbb*/, jrd_req* request) const
|
||||
}
|
||||
}
|
||||
|
||||
dsc* AggNode::execute(thread_db* tdbb, jrd_req* request) const
|
||||
dsc* AggNode::execute(thread_db* tdbb, Request* request) const
|
||||
{
|
||||
impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset);
|
||||
|
||||
@ -685,7 +685,7 @@ string AvgAggNode::internalPrint(NodePrinter& printer) const
|
||||
return "AvgAggNode";
|
||||
}
|
||||
|
||||
void AvgAggNode::aggInit(thread_db* tdbb, jrd_req* request) const
|
||||
void AvgAggNode::aggInit(thread_db* tdbb, Request* request) const
|
||||
{
|
||||
AggNode::aggInit(tdbb, request);
|
||||
|
||||
@ -704,7 +704,7 @@ void AvgAggNode::aggInit(thread_db* tdbb, jrd_req* request) const
|
||||
}
|
||||
}
|
||||
|
||||
void AvgAggNode::aggPass(thread_db* tdbb, jrd_req* request, dsc* desc) const
|
||||
void AvgAggNode::aggPass(thread_db* tdbb, Request* request, dsc* desc) const
|
||||
{
|
||||
impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset);
|
||||
if (impure->vlux_count++ == 0) // first call to aggPass()
|
||||
@ -720,7 +720,7 @@ void AvgAggNode::aggPass(thread_db* tdbb, jrd_req* request, dsc* desc) const
|
||||
ArithmeticNode::add2(tdbb, desc, impure, this, blr_add);
|
||||
}
|
||||
|
||||
dsc* AvgAggNode::aggExecute(thread_db* tdbb, jrd_req* request) const
|
||||
dsc* AvgAggNode::aggExecute(thread_db* tdbb, Request* request) const
|
||||
{
|
||||
impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset);
|
||||
|
||||
@ -848,7 +848,7 @@ string ListAggNode::internalPrint(NodePrinter& printer) const
|
||||
return "ListAggNode";
|
||||
}
|
||||
|
||||
void ListAggNode::aggInit(thread_db* tdbb, jrd_req* request) const
|
||||
void ListAggNode::aggInit(thread_db* tdbb, Request* request) const
|
||||
{
|
||||
AggNode::aggInit(tdbb, request);
|
||||
|
||||
@ -859,7 +859,7 @@ void ListAggNode::aggInit(thread_db* tdbb, jrd_req* request) const
|
||||
impure->vlu_desc.dsc_dtype = 0;
|
||||
}
|
||||
|
||||
void ListAggNode::aggPass(thread_db* tdbb, jrd_req* request, dsc* desc) const
|
||||
void ListAggNode::aggPass(thread_db* tdbb, Request* request, dsc* desc) const
|
||||
{
|
||||
impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset);
|
||||
|
||||
@ -897,7 +897,7 @@ void ListAggNode::aggPass(thread_db* tdbb, jrd_req* request, dsc* desc) const
|
||||
impure->vlu_blob->BLB_put_data(tdbb, temp, len);
|
||||
}
|
||||
|
||||
dsc* ListAggNode::aggExecute(thread_db* tdbb, jrd_req* request) const
|
||||
dsc* ListAggNode::aggExecute(thread_db* tdbb, Request* request) const
|
||||
{
|
||||
impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset);
|
||||
|
||||
@ -1000,7 +1000,7 @@ string CountAggNode::internalPrint(NodePrinter& printer) const
|
||||
}
|
||||
|
||||
//// TODO: Improve count(*) in local tables.
|
||||
void CountAggNode::aggInit(thread_db* tdbb, jrd_req* request) const
|
||||
void CountAggNode::aggInit(thread_db* tdbb, Request* request) const
|
||||
{
|
||||
AggNode::aggInit(tdbb, request);
|
||||
|
||||
@ -1008,7 +1008,7 @@ void CountAggNode::aggInit(thread_db* tdbb, jrd_req* request) const
|
||||
impure->make_int64(0);
|
||||
}
|
||||
|
||||
void CountAggNode::aggPass(thread_db* /*tdbb*/, jrd_req* request, dsc* /*desc*/) const
|
||||
void CountAggNode::aggPass(thread_db* /*tdbb*/, Request* request, dsc* /*desc*/) const
|
||||
{
|
||||
impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset);
|
||||
|
||||
@ -1018,7 +1018,7 @@ void CountAggNode::aggPass(thread_db* /*tdbb*/, jrd_req* request, dsc* /*desc*/)
|
||||
++impure->vlu_misc.vlu_int64;
|
||||
}
|
||||
|
||||
dsc* CountAggNode::aggExecute(thread_db* /*tdbb*/, jrd_req* request) const
|
||||
dsc* CountAggNode::aggExecute(thread_db* /*tdbb*/, Request* request) const
|
||||
{
|
||||
impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset);
|
||||
|
||||
@ -1253,7 +1253,7 @@ string SumAggNode::internalPrint(NodePrinter& printer) const
|
||||
return "SumAggNode";
|
||||
}
|
||||
|
||||
void SumAggNode::aggInit(thread_db* tdbb, jrd_req* request) const
|
||||
void SumAggNode::aggInit(thread_db* tdbb, Request* request) const
|
||||
{
|
||||
AggNode::aggInit(tdbb, request);
|
||||
|
||||
@ -1269,7 +1269,7 @@ void SumAggNode::aggInit(thread_db* tdbb, jrd_req* request) const
|
||||
}
|
||||
}
|
||||
|
||||
void SumAggNode::aggPass(thread_db* tdbb, jrd_req* request, dsc* desc) const
|
||||
void SumAggNode::aggPass(thread_db* tdbb, Request* request, dsc* desc) const
|
||||
{
|
||||
impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset);
|
||||
++impure->vlux_count;
|
||||
@ -1280,7 +1280,7 @@ void SumAggNode::aggPass(thread_db* tdbb, jrd_req* request, dsc* desc) const
|
||||
ArithmeticNode::add2(tdbb, desc, impure, this, blr_add);
|
||||
}
|
||||
|
||||
dsc* SumAggNode::aggExecute(thread_db* /*tdbb*/, jrd_req* request) const
|
||||
dsc* SumAggNode::aggExecute(thread_db* /*tdbb*/, Request* request) const
|
||||
{
|
||||
impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset);
|
||||
|
||||
@ -1345,7 +1345,7 @@ string MaxMinAggNode::internalPrint(NodePrinter& printer) const
|
||||
return "MaxMinAggNode";
|
||||
}
|
||||
|
||||
void MaxMinAggNode::aggInit(thread_db* tdbb, jrd_req* request) const
|
||||
void MaxMinAggNode::aggInit(thread_db* tdbb, Request* request) const
|
||||
{
|
||||
AggNode::aggInit(tdbb, request);
|
||||
|
||||
@ -1353,7 +1353,7 @@ void MaxMinAggNode::aggInit(thread_db* tdbb, jrd_req* request) const
|
||||
impure->vlu_desc.dsc_dtype = 0;
|
||||
}
|
||||
|
||||
void MaxMinAggNode::aggPass(thread_db* tdbb, jrd_req* request, dsc* desc) const
|
||||
void MaxMinAggNode::aggPass(thread_db* tdbb, Request* request, dsc* desc) const
|
||||
{
|
||||
impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset);
|
||||
++impure->vlux_count;
|
||||
@ -1370,7 +1370,7 @@ void MaxMinAggNode::aggPass(thread_db* tdbb, jrd_req* request, dsc* desc) const
|
||||
EVL_make_value(tdbb, desc, impure);
|
||||
}
|
||||
|
||||
dsc* MaxMinAggNode::aggExecute(thread_db* /*tdbb*/, jrd_req* request) const
|
||||
dsc* MaxMinAggNode::aggExecute(thread_db* /*tdbb*/, Request* request) const
|
||||
{
|
||||
impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset);
|
||||
|
||||
@ -1472,7 +1472,7 @@ string StdDevAggNode::internalPrint(NodePrinter& printer) const
|
||||
return "StdDevAggNode";
|
||||
}
|
||||
|
||||
void StdDevAggNode::aggInit(thread_db* tdbb, jrd_req* request) const
|
||||
void StdDevAggNode::aggInit(thread_db* tdbb, Request* request) const
|
||||
{
|
||||
AggNode::aggInit(tdbb, request);
|
||||
|
||||
@ -1491,7 +1491,7 @@ void StdDevAggNode::aggInit(thread_db* tdbb, jrd_req* request) const
|
||||
}
|
||||
}
|
||||
|
||||
void StdDevAggNode::aggPass(thread_db* tdbb, jrd_req* request, dsc* desc) const
|
||||
void StdDevAggNode::aggPass(thread_db* tdbb, Request* request, dsc* desc) const
|
||||
{
|
||||
impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset);
|
||||
++impure->vlux_count;
|
||||
@ -1514,7 +1514,7 @@ void StdDevAggNode::aggPass(thread_db* tdbb, jrd_req* request, dsc* desc) const
|
||||
}
|
||||
}
|
||||
|
||||
dsc* StdDevAggNode::aggExecute(thread_db* tdbb, jrd_req* request) const
|
||||
dsc* StdDevAggNode::aggExecute(thread_db* tdbb, Request* request) const
|
||||
{
|
||||
impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset);
|
||||
StdDevImpure* impure2 = request->getImpure<StdDevImpure>(impure2Offset);
|
||||
@ -1681,7 +1681,7 @@ string CorrAggNode::internalPrint(NodePrinter& printer) const
|
||||
return "CorrAggNode";
|
||||
}
|
||||
|
||||
void CorrAggNode::aggInit(thread_db* tdbb, jrd_req* request) const
|
||||
void CorrAggNode::aggInit(thread_db* tdbb, Request* request) const
|
||||
{
|
||||
AggNode::aggInit(tdbb, request);
|
||||
|
||||
@ -1700,7 +1700,7 @@ void CorrAggNode::aggInit(thread_db* tdbb, jrd_req* request) const
|
||||
}
|
||||
}
|
||||
|
||||
bool CorrAggNode::aggPass(thread_db* tdbb, jrd_req* request) const
|
||||
bool CorrAggNode::aggPass(thread_db* tdbb, Request* request) const
|
||||
{
|
||||
impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset);
|
||||
|
||||
@ -1744,12 +1744,12 @@ bool CorrAggNode::aggPass(thread_db* tdbb, jrd_req* request) const
|
||||
return true;
|
||||
}
|
||||
|
||||
void CorrAggNode::aggPass(thread_db* /*tdbb*/, jrd_req* /*request*/, dsc* /*desc*/) const
|
||||
void CorrAggNode::aggPass(thread_db* /*tdbb*/, Request* /*request*/, dsc* /*desc*/) const
|
||||
{
|
||||
fb_assert(false);
|
||||
}
|
||||
|
||||
dsc* CorrAggNode::aggExecute(thread_db* tdbb, jrd_req* request) const
|
||||
dsc* CorrAggNode::aggExecute(thread_db* tdbb, Request* request) const
|
||||
{
|
||||
impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset);
|
||||
CorrImpure* impure2 = request->getImpure<CorrImpure>(impure2Offset);
|
||||
@ -1957,7 +1957,7 @@ string RegrAggNode::internalPrint(NodePrinter& printer) const
|
||||
return "RegrAggNode";
|
||||
}
|
||||
|
||||
void RegrAggNode::aggInit(thread_db* tdbb, jrd_req* request) const
|
||||
void RegrAggNode::aggInit(thread_db* tdbb, Request* request) const
|
||||
{
|
||||
AggNode::aggInit(tdbb, request);
|
||||
|
||||
@ -1976,7 +1976,7 @@ void RegrAggNode::aggInit(thread_db* tdbb, jrd_req* request) const
|
||||
}
|
||||
}
|
||||
|
||||
bool RegrAggNode::aggPass(thread_db* tdbb, jrd_req* request) const
|
||||
bool RegrAggNode::aggPass(thread_db* tdbb, Request* request) const
|
||||
{
|
||||
impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset);
|
||||
|
||||
@ -2021,12 +2021,12 @@ bool RegrAggNode::aggPass(thread_db* tdbb, jrd_req* request) const
|
||||
return true;
|
||||
}
|
||||
|
||||
void RegrAggNode::aggPass(thread_db* /*tdbb*/, jrd_req* /*request*/, dsc* /*desc*/) const
|
||||
void RegrAggNode::aggPass(thread_db* /*tdbb*/, Request* /*request*/, dsc* /*desc*/) const
|
||||
{
|
||||
fb_assert(false);
|
||||
}
|
||||
|
||||
dsc* RegrAggNode::aggExecute(thread_db* tdbb, jrd_req* request) const
|
||||
dsc* RegrAggNode::aggExecute(thread_db* tdbb, Request* request) const
|
||||
{
|
||||
impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset);
|
||||
|
||||
@ -2226,7 +2226,7 @@ string RegrCountAggNode::internalPrint(NodePrinter& printer) const
|
||||
return "RegrCountAggNode";
|
||||
}
|
||||
|
||||
void RegrCountAggNode::aggInit(thread_db* tdbb, jrd_req* request) const
|
||||
void RegrCountAggNode::aggInit(thread_db* tdbb, Request* request) const
|
||||
{
|
||||
AggNode::aggInit(tdbb, request);
|
||||
|
||||
@ -2234,7 +2234,7 @@ void RegrCountAggNode::aggInit(thread_db* tdbb, jrd_req* request) const
|
||||
impure->make_int64(0);
|
||||
}
|
||||
|
||||
bool RegrCountAggNode::aggPass(thread_db* tdbb, jrd_req* request) const
|
||||
bool RegrCountAggNode::aggPass(thread_db* tdbb, Request* request) const
|
||||
{
|
||||
EVL_expr(tdbb, request, arg);
|
||||
if (request->req_flags & req_null)
|
||||
@ -2250,12 +2250,12 @@ bool RegrCountAggNode::aggPass(thread_db* tdbb, jrd_req* request) const
|
||||
return true;
|
||||
}
|
||||
|
||||
void RegrCountAggNode::aggPass(thread_db* /*tdbb*/, jrd_req* /*request*/, dsc* /*desc*/) const
|
||||
void RegrCountAggNode::aggPass(thread_db* /*tdbb*/, Request* /*request*/, dsc* /*desc*/) const
|
||||
{
|
||||
fb_assert(false);
|
||||
}
|
||||
|
||||
dsc* RegrCountAggNode::aggExecute(thread_db* tdbb, jrd_req* request) const
|
||||
dsc* RegrCountAggNode::aggExecute(thread_db* tdbb, Request* request) const
|
||||
{
|
||||
impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset);
|
||||
|
||||
|
@ -30,7 +30,7 @@
|
||||
namespace Jrd {
|
||||
|
||||
|
||||
class AvgAggNode : public AggNode
|
||||
class AvgAggNode final : public AggNode
|
||||
{
|
||||
public:
|
||||
explicit AvgAggNode(MemoryPool& pool, bool aDistinct, bool aDialect1, ValueExprNode* aArg = NULL);
|
||||
@ -53,9 +53,9 @@ public:
|
||||
virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const;
|
||||
virtual AggNode* pass2(thread_db* tdbb, CompilerScratch* csb);
|
||||
|
||||
virtual void aggInit(thread_db* tdbb, jrd_req* request) const;
|
||||
virtual void aggPass(thread_db* tdbb, jrd_req* request, dsc* desc) const;
|
||||
virtual dsc* aggExecute(thread_db* tdbb, jrd_req* request) const;
|
||||
virtual void aggInit(thread_db* tdbb, Request* request) const;
|
||||
virtual void aggPass(thread_db* tdbb, Request* request, dsc* desc) const;
|
||||
virtual dsc* aggExecute(thread_db* tdbb, Request* request) const;
|
||||
|
||||
protected:
|
||||
virtual AggNode* dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/;
|
||||
@ -65,7 +65,7 @@ private:
|
||||
ULONG tempImpure;
|
||||
};
|
||||
|
||||
class ListAggNode : public AggNode
|
||||
class ListAggNode final : public AggNode
|
||||
{
|
||||
public:
|
||||
explicit ListAggNode(MemoryPool& pool, bool aDistinct, ValueExprNode* aArg = NULL,
|
||||
@ -91,9 +91,9 @@ public:
|
||||
virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc);
|
||||
virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const;
|
||||
|
||||
virtual void aggInit(thread_db* tdbb, jrd_req* request) const;
|
||||
virtual void aggPass(thread_db* tdbb, jrd_req* request, dsc* desc) const;
|
||||
virtual dsc* aggExecute(thread_db* tdbb, jrd_req* request) const;
|
||||
virtual void aggInit(thread_db* tdbb, Request* request) const;
|
||||
virtual void aggPass(thread_db* tdbb, Request* request, dsc* desc) const;
|
||||
virtual dsc* aggExecute(thread_db* tdbb, Request* request) const;
|
||||
|
||||
protected:
|
||||
virtual AggNode* dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/;
|
||||
@ -102,7 +102,7 @@ private:
|
||||
NestConst<ValueExprNode> delimiter;
|
||||
};
|
||||
|
||||
class CountAggNode : public AggNode
|
||||
class CountAggNode final : public AggNode
|
||||
{
|
||||
public:
|
||||
explicit CountAggNode(MemoryPool& pool, bool aDistinct, bool aDialect1, ValueExprNode* aArg = NULL);
|
||||
@ -120,15 +120,15 @@ public:
|
||||
virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc);
|
||||
virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const;
|
||||
|
||||
virtual void aggInit(thread_db* tdbb, jrd_req* request) const;
|
||||
virtual void aggPass(thread_db* tdbb, jrd_req* request, dsc* desc) const;
|
||||
virtual dsc* aggExecute(thread_db* tdbb, jrd_req* request) const;
|
||||
virtual void aggInit(thread_db* tdbb, Request* request) const;
|
||||
virtual void aggPass(thread_db* tdbb, Request* request, dsc* desc) const;
|
||||
virtual dsc* aggExecute(thread_db* tdbb, Request* request) const;
|
||||
|
||||
protected:
|
||||
virtual AggNode* dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/;
|
||||
};
|
||||
|
||||
class SumAggNode : public AggNode
|
||||
class SumAggNode final : public AggNode
|
||||
{
|
||||
public:
|
||||
explicit SumAggNode(MemoryPool& pool, bool aDistinct, bool aDialect1, ValueExprNode* aArg = NULL);
|
||||
@ -150,15 +150,15 @@ public:
|
||||
virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc);
|
||||
virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const;
|
||||
|
||||
virtual void aggInit(thread_db* tdbb, jrd_req* request) const;
|
||||
virtual void aggPass(thread_db* tdbb, jrd_req* request, dsc* desc) const;
|
||||
virtual dsc* aggExecute(thread_db* tdbb, jrd_req* request) const;
|
||||
virtual void aggInit(thread_db* tdbb, Request* request) const;
|
||||
virtual void aggPass(thread_db* tdbb, Request* request, dsc* desc) const;
|
||||
virtual dsc* aggExecute(thread_db* tdbb, Request* request) const;
|
||||
|
||||
protected:
|
||||
virtual AggNode* dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/;
|
||||
};
|
||||
|
||||
class MaxMinAggNode : public AggNode
|
||||
class MaxMinAggNode final : public AggNode
|
||||
{
|
||||
public:
|
||||
enum MaxMinType
|
||||
@ -181,9 +181,9 @@ public:
|
||||
virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc);
|
||||
virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const;
|
||||
|
||||
virtual void aggInit(thread_db* tdbb, jrd_req* request) const;
|
||||
virtual void aggPass(thread_db* tdbb, jrd_req* request, dsc* desc) const;
|
||||
virtual dsc* aggExecute(thread_db* tdbb, jrd_req* request) const;
|
||||
virtual void aggInit(thread_db* tdbb, Request* request) const;
|
||||
virtual void aggPass(thread_db* tdbb, Request* request, dsc* desc) const;
|
||||
virtual dsc* aggExecute(thread_db* tdbb, Request* request) const;
|
||||
|
||||
protected:
|
||||
virtual AggNode* dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/;
|
||||
@ -192,7 +192,7 @@ public:
|
||||
const MaxMinType type;
|
||||
};
|
||||
|
||||
class StdDevAggNode : public AggNode
|
||||
class StdDevAggNode final : public AggNode
|
||||
{
|
||||
public:
|
||||
enum StdDevType
|
||||
@ -230,9 +230,9 @@ public:
|
||||
virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const;
|
||||
virtual AggNode* pass2(thread_db* tdbb, CompilerScratch* csb);
|
||||
|
||||
virtual void aggInit(thread_db* tdbb, jrd_req* request) const;
|
||||
virtual void aggPass(thread_db* tdbb, jrd_req* request, dsc* desc) const;
|
||||
virtual dsc* aggExecute(thread_db* tdbb, jrd_req* request) const;
|
||||
virtual void aggInit(thread_db* tdbb, Request* request) const;
|
||||
virtual void aggPass(thread_db* tdbb, Request* request, dsc* desc) const;
|
||||
virtual dsc* aggExecute(thread_db* tdbb, Request* request) const;
|
||||
|
||||
protected:
|
||||
virtual AggNode* dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/;
|
||||
@ -244,7 +244,7 @@ private:
|
||||
ULONG impure2Offset;
|
||||
};
|
||||
|
||||
class CorrAggNode : public AggNode
|
||||
class CorrAggNode final : public AggNode
|
||||
{
|
||||
public:
|
||||
enum CorrType
|
||||
@ -288,10 +288,10 @@ public:
|
||||
virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const;
|
||||
virtual AggNode* pass2(thread_db* tdbb, CompilerScratch* csb);
|
||||
|
||||
virtual void aggInit(thread_db* tdbb, jrd_req* request) const;
|
||||
virtual bool aggPass(thread_db* tdbb, jrd_req* request) const;
|
||||
virtual void aggPass(thread_db* tdbb, jrd_req* request, dsc* desc) const;
|
||||
virtual dsc* aggExecute(thread_db* tdbb, jrd_req* request) const;
|
||||
virtual void aggInit(thread_db* tdbb, Request* request) const;
|
||||
virtual bool aggPass(thread_db* tdbb, Request* request) const;
|
||||
virtual void aggPass(thread_db* tdbb, Request* request, dsc* desc) const;
|
||||
virtual dsc* aggExecute(thread_db* tdbb, Request* request) const;
|
||||
|
||||
protected:
|
||||
virtual AggNode* dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/;
|
||||
@ -304,7 +304,7 @@ private:
|
||||
ULONG impure2Offset;
|
||||
};
|
||||
|
||||
class RegrAggNode : public AggNode
|
||||
class RegrAggNode final : public AggNode
|
||||
{
|
||||
public:
|
||||
enum RegrType
|
||||
@ -353,10 +353,10 @@ public:
|
||||
virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const;
|
||||
virtual AggNode* pass2(thread_db* tdbb, CompilerScratch* csb);
|
||||
|
||||
virtual void aggInit(thread_db* tdbb, jrd_req* request) const;
|
||||
virtual bool aggPass(thread_db* tdbb, jrd_req* request) const;
|
||||
virtual void aggPass(thread_db* tdbb, jrd_req* request, dsc* desc) const;
|
||||
virtual dsc* aggExecute(thread_db* tdbb, jrd_req* request) const;
|
||||
virtual void aggInit(thread_db* tdbb, Request* request) const;
|
||||
virtual bool aggPass(thread_db* tdbb, Request* request) const;
|
||||
virtual void aggPass(thread_db* tdbb, Request* request, dsc* desc) const;
|
||||
virtual dsc* aggExecute(thread_db* tdbb, Request* request) const;
|
||||
|
||||
protected:
|
||||
virtual AggNode* dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/;
|
||||
@ -369,7 +369,7 @@ private:
|
||||
ULONG impure2Offset;
|
||||
};
|
||||
|
||||
class RegrCountAggNode : public AggNode
|
||||
class RegrCountAggNode final : public AggNode
|
||||
{
|
||||
public:
|
||||
explicit RegrCountAggNode(MemoryPool& pool,
|
||||
@ -393,10 +393,10 @@ public:
|
||||
virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc);
|
||||
virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const;
|
||||
|
||||
virtual void aggInit(thread_db* tdbb, jrd_req* request) const;
|
||||
virtual bool aggPass(thread_db* tdbb, jrd_req* request) const;
|
||||
virtual void aggPass(thread_db* tdbb, jrd_req* request, dsc* desc) const;
|
||||
virtual dsc* aggExecute(thread_db* tdbb, jrd_req* request) const;
|
||||
virtual void aggInit(thread_db* tdbb, Request* request) const;
|
||||
virtual bool aggPass(thread_db* tdbb, Request* request) const;
|
||||
virtual void aggPass(thread_db* tdbb, Request* request, dsc* desc) const;
|
||||
virtual dsc* aggExecute(thread_db* tdbb, Request* request) const;
|
||||
|
||||
protected:
|
||||
virtual AggNode* dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/;
|
||||
|
@ -28,7 +28,7 @@
|
||||
#include "../jrd/tra.h"
|
||||
#include "../jrd/recsrc/RecordSource.h"
|
||||
#include "../jrd/recsrc/Cursor.h"
|
||||
#include "../jrd/Optimizer.h"
|
||||
#include "../jrd/optimizer/Optimizer.h"
|
||||
#include "../jrd/blb_proto.h"
|
||||
#include "../jrd/cmp_proto.h"
|
||||
#include "../jrd/evl_proto.h"
|
||||
@ -170,7 +170,7 @@ BoolExprNode* BinaryBoolNode::copy(thread_db* tdbb, NodeCopier& copier) const
|
||||
return node;
|
||||
}
|
||||
|
||||
bool BinaryBoolNode::execute(thread_db* tdbb, jrd_req* request) const
|
||||
bool BinaryBoolNode::execute(thread_db* tdbb, Request* request) const
|
||||
{
|
||||
switch (blrOp)
|
||||
{
|
||||
@ -185,7 +185,7 @@ bool BinaryBoolNode::execute(thread_db* tdbb, jrd_req* request) const
|
||||
return false;
|
||||
}
|
||||
|
||||
bool BinaryBoolNode::executeAnd(thread_db* tdbb, jrd_req* request) const
|
||||
bool BinaryBoolNode::executeAnd(thread_db* tdbb, Request* request) const
|
||||
{
|
||||
// If either operand is false, then the result is false;
|
||||
// If both are true, the result is true;
|
||||
@ -231,7 +231,7 @@ bool BinaryBoolNode::executeAnd(thread_db* tdbb, jrd_req* request) const
|
||||
return false;
|
||||
}
|
||||
|
||||
bool BinaryBoolNode::executeOr(thread_db* tdbb, jrd_req* request) const
|
||||
bool BinaryBoolNode::executeOr(thread_db* tdbb, Request* request) const
|
||||
{
|
||||
// If either operand is true, then the result is true;
|
||||
// If both are false, the result is false;
|
||||
@ -643,7 +643,7 @@ void ComparativeBoolNode::pass2Boolean2(thread_db* tdbb, CompilerScratch* csb)
|
||||
}
|
||||
}
|
||||
|
||||
bool ComparativeBoolNode::execute(thread_db* tdbb, jrd_req* request) const
|
||||
bool ComparativeBoolNode::execute(thread_db* tdbb, Request* request) const
|
||||
{
|
||||
dsc* desc[2] = {NULL, NULL};
|
||||
bool computed_invariant = false;
|
||||
@ -817,7 +817,7 @@ bool ComparativeBoolNode::execute(thread_db* tdbb, jrd_req* request) const
|
||||
}
|
||||
|
||||
// Perform one of the complex string functions CONTAINING, MATCHES, or STARTS WITH.
|
||||
bool ComparativeBoolNode::stringBoolean(thread_db* tdbb, jrd_req* request, dsc* desc1,
|
||||
bool ComparativeBoolNode::stringBoolean(thread_db* tdbb, Request* request, dsc* desc1,
|
||||
dsc* desc2, bool computedInvariant) const
|
||||
{
|
||||
SET_TDBB(tdbb);
|
||||
@ -1023,7 +1023,7 @@ bool ComparativeBoolNode::stringBoolean(thread_db* tdbb, jrd_req* request, dsc*
|
||||
}
|
||||
|
||||
// Execute SLEUTH operator.
|
||||
bool ComparativeBoolNode::sleuth(thread_db* tdbb, jrd_req* request, const dsc* desc1,
|
||||
bool ComparativeBoolNode::sleuth(thread_db* tdbb, Request* request, const dsc* desc1,
|
||||
const dsc* desc2) const
|
||||
{
|
||||
SET_TDBB(tdbb);
|
||||
@ -1223,7 +1223,7 @@ void MissingBoolNode::pass2Boolean2(thread_db* tdbb, CompilerScratch* csb)
|
||||
arg->getDesc(tdbb, csb, &descriptor_a);
|
||||
}
|
||||
|
||||
bool MissingBoolNode::execute(thread_db* tdbb, jrd_req* request) const
|
||||
bool MissingBoolNode::execute(thread_db* tdbb, Request* request) const
|
||||
{
|
||||
EVL_expr(tdbb, request, arg);
|
||||
|
||||
@ -1298,7 +1298,7 @@ BoolExprNode* NotBoolNode::pass1(thread_db* tdbb, CompilerScratch* csb)
|
||||
return BoolExprNode::pass1(tdbb, csb);
|
||||
}
|
||||
|
||||
bool NotBoolNode::execute(thread_db* tdbb, jrd_req* request) const
|
||||
bool NotBoolNode::execute(thread_db* tdbb, Request* request) const
|
||||
{
|
||||
bool value = arg->execute(tdbb, request);
|
||||
|
||||
@ -1612,7 +1612,7 @@ void RseBoolNode::pass2Boolean2(thread_db* tdbb, CompilerScratch* csb)
|
||||
subQuery = FB_NEW_POOL(*tdbb->getDefaultPool()) SubQuery(rsb, rse->rse_invariants);
|
||||
}
|
||||
|
||||
bool RseBoolNode::execute(thread_db* tdbb, jrd_req* request) const
|
||||
bool RseBoolNode::execute(thread_db* tdbb, Request* request) const
|
||||
{
|
||||
USHORT* invariant_flags;
|
||||
impure_value* impure;
|
||||
|
@ -31,7 +31,7 @@ namespace Jrd {
|
||||
class SubQuery;
|
||||
|
||||
|
||||
class BinaryBoolNode : public TypedNode<BoolExprNode, ExprNode::TYPE_BINARY_BOOL>
|
||||
class BinaryBoolNode final : public TypedNode<BoolExprNode, ExprNode::TYPE_BINARY_BOOL>
|
||||
{
|
||||
public:
|
||||
BinaryBoolNode(MemoryPool& pool, UCHAR aBlrOp, BoolExprNode* aArg1 = NULL,
|
||||
@ -54,11 +54,11 @@ public:
|
||||
virtual BoolExprNode* copy(thread_db* tdbb, NodeCopier& copier) const;
|
||||
virtual bool dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, bool ignoreMapCast) const;
|
||||
virtual bool sameAs(const ExprNode* other, bool ignoreStreams) const;
|
||||
virtual bool execute(thread_db* tdbb, jrd_req* request) const;
|
||||
virtual bool execute(thread_db* tdbb, Request* request) const;
|
||||
|
||||
private:
|
||||
virtual bool executeAnd(thread_db* tdbb, jrd_req* request) const;
|
||||
virtual bool executeOr(thread_db* tdbb, jrd_req* request) const;
|
||||
virtual bool executeAnd(thread_db* tdbb, Request* request) const;
|
||||
virtual bool executeOr(thread_db* tdbb, Request* request) const;
|
||||
|
||||
public:
|
||||
UCHAR blrOp;
|
||||
@ -67,7 +67,7 @@ public:
|
||||
};
|
||||
|
||||
|
||||
class ComparativeBoolNode : public TypedNode<BoolExprNode, ExprNode::TYPE_COMPARATIVE_BOOL>
|
||||
class ComparativeBoolNode final : public TypedNode<BoolExprNode, ExprNode::TYPE_COMPARATIVE_BOOL>
|
||||
{
|
||||
public:
|
||||
enum DsqlFlag : UCHAR
|
||||
@ -106,12 +106,12 @@ public:
|
||||
virtual BoolExprNode* pass1(thread_db* tdbb, CompilerScratch* csb);
|
||||
virtual void pass2Boolean1(thread_db* tdbb, CompilerScratch* csb);
|
||||
virtual void pass2Boolean2(thread_db* tdbb, CompilerScratch* csb);
|
||||
virtual bool execute(thread_db* tdbb, jrd_req* request) const;
|
||||
virtual bool execute(thread_db* tdbb, Request* request) const;
|
||||
|
||||
private:
|
||||
bool stringBoolean(thread_db* tdbb, jrd_req* request, dsc* desc1, dsc* desc2,
|
||||
bool stringBoolean(thread_db* tdbb, Request* request, dsc* desc1, dsc* desc2,
|
||||
bool computedInvariant) const;
|
||||
bool sleuth(thread_db* tdbb, jrd_req* request, const dsc* desc1, const dsc* desc2) const;
|
||||
bool sleuth(thread_db* tdbb, Request* request, const dsc* desc1, const dsc* desc2) const;
|
||||
|
||||
BoolExprNode* createRseNode(DsqlCompilerScratch* dsqlScratch, UCHAR rseBlrOp);
|
||||
|
||||
@ -126,7 +126,7 @@ public:
|
||||
};
|
||||
|
||||
|
||||
class MissingBoolNode : public TypedNode<BoolExprNode, ExprNode::TYPE_MISSING_BOOL>
|
||||
class MissingBoolNode final : public TypedNode<BoolExprNode, ExprNode::TYPE_MISSING_BOOL>
|
||||
{
|
||||
public:
|
||||
explicit MissingBoolNode(MemoryPool& pool, ValueExprNode* aArg = NULL, bool aDsqlUnknown = false);
|
||||
@ -151,7 +151,7 @@ public:
|
||||
virtual BoolExprNode* copy(thread_db* tdbb, NodeCopier& copier) const;
|
||||
virtual BoolExprNode* pass1(thread_db* tdbb, CompilerScratch* csb);
|
||||
virtual void pass2Boolean2(thread_db* tdbb, CompilerScratch* csb);
|
||||
virtual bool execute(thread_db* tdbb, jrd_req* request) const;
|
||||
virtual bool execute(thread_db* tdbb, Request* request) const;
|
||||
|
||||
public:
|
||||
bool dsqlUnknown;
|
||||
@ -159,7 +159,7 @@ public:
|
||||
};
|
||||
|
||||
|
||||
class NotBoolNode : public TypedNode<BoolExprNode, ExprNode::TYPE_NOT_BOOL>
|
||||
class NotBoolNode final : public TypedNode<BoolExprNode, ExprNode::TYPE_NOT_BOOL>
|
||||
{
|
||||
public:
|
||||
explicit NotBoolNode(MemoryPool& pool, BoolExprNode* aArg = NULL);
|
||||
@ -183,7 +183,7 @@ public:
|
||||
|
||||
virtual BoolExprNode* copy(thread_db* tdbb, NodeCopier& copier) const;
|
||||
virtual BoolExprNode* pass1(thread_db* tdbb, CompilerScratch* csb);
|
||||
virtual bool execute(thread_db* tdbb, jrd_req* request) const;
|
||||
virtual bool execute(thread_db* tdbb, Request* request) const;
|
||||
|
||||
private:
|
||||
BoolExprNode* process(DsqlCompilerScratch* dsqlScratch, bool invert);
|
||||
@ -193,7 +193,7 @@ public:
|
||||
};
|
||||
|
||||
|
||||
class RseBoolNode : public TypedNode<BoolExprNode, ExprNode::TYPE_RSE_BOOL>
|
||||
class RseBoolNode final : public TypedNode<BoolExprNode, ExprNode::TYPE_RSE_BOOL>
|
||||
{
|
||||
public:
|
||||
RseBoolNode(MemoryPool& pool, UCHAR aBlrOp, RecordSourceNode* aDsqlRse = NULL);
|
||||
@ -235,7 +235,7 @@ public:
|
||||
virtual BoolExprNode* pass1(thread_db* tdbb, CompilerScratch* csb);
|
||||
virtual void pass2Boolean1(thread_db* tdbb, CompilerScratch* csb);
|
||||
virtual void pass2Boolean2(thread_db* tdbb, CompilerScratch* csb);
|
||||
virtual bool execute(thread_db* tdbb, jrd_req* request) const;
|
||||
virtual bool execute(thread_db* tdbb, Request* request) const;
|
||||
|
||||
private:
|
||||
BoolExprNode* convertNeqAllToNotAny(thread_db* tdbb, CompilerScratch* csb);
|
||||
|
@ -985,7 +985,7 @@ void DdlNode::executeDdlTrigger(thread_db* tdbb, DsqlCompilerScratch* dsqlScratc
|
||||
const MetaName& oldNewObjectName)
|
||||
{
|
||||
executeDdlTrigger(tdbb, transaction, when, action, objectName, oldNewObjectName,
|
||||
*dsqlScratch->getStatement()->getSqlText());
|
||||
*dsqlScratch->getDsqlStatement()->getSqlText());
|
||||
}
|
||||
|
||||
void DdlNode::storeGlobalField(thread_db* tdbb, jrd_tra* transaction, MetaName& name,
|
||||
@ -1354,7 +1354,6 @@ void CommentOnNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
|
||||
|
||||
switch (objType)
|
||||
{
|
||||
case obj_schema:
|
||||
case obj_database:
|
||||
SCL_check_database(tdbb, SCL_alter);
|
||||
break;
|
||||
@ -1577,12 +1576,6 @@ void CommentOnNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
|
||||
status << Arg::Gds(isc_dyn_package_not_found) << Arg::Str(objNameStr);
|
||||
break;
|
||||
|
||||
case obj_schema:
|
||||
tableClause = "rdb$schemas";
|
||||
columnClause = "rdb$schema_name";
|
||||
status << Arg::Gds(isc_dyn_schema_not_found) << Arg::Str(objNameStr);
|
||||
break;
|
||||
|
||||
default:
|
||||
fb_assert(false);
|
||||
return;
|
||||
@ -1741,7 +1734,7 @@ void CreateAlterFunctionNode::checkPermission(thread_db* tdbb, jrd_tra* transact
|
||||
return;
|
||||
}
|
||||
|
||||
SCL_check_create_access(tdbb, SCL_object_function);
|
||||
SCL_check_create_access(tdbb, obj_functions);
|
||||
}
|
||||
|
||||
void CreateAlterFunctionNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
|
||||
@ -2342,6 +2335,8 @@ void CreateAlterFunctionNode::compile(thread_db* /*tdbb*/, DsqlCompilerScratch*
|
||||
dsqlScratch->cursorNumber = 0;
|
||||
|
||||
StmtNode* stmtNode = body->dsqlPass(dsqlScratch);
|
||||
|
||||
dsqlScratch->putOuterMaps();
|
||||
GEN_hidden_variables(dsqlScratch);
|
||||
|
||||
dsqlScratch->appendUChar(blr_stall);
|
||||
@ -2352,7 +2347,7 @@ void CreateAlterFunctionNode::compile(thread_db* /*tdbb*/, DsqlCompilerScratch*
|
||||
|
||||
stmtNode->genBlr(dsqlScratch);
|
||||
|
||||
dsqlScratch->getStatement()->setType(DsqlCompiledStatement::TYPE_DDL);
|
||||
dsqlScratch->getDsqlStatement()->setType(DsqlStatement::TYPE_DDL);
|
||||
dsqlScratch->appendUChar(blr_end);
|
||||
dsqlScratch->genReturn(false);
|
||||
dsqlScratch->appendUChar(blr_end);
|
||||
@ -2747,7 +2742,7 @@ void CreateAlterProcedureNode::checkPermission(thread_db* tdbb, jrd_tra* transac
|
||||
return;
|
||||
}
|
||||
|
||||
SCL_check_create_access(tdbb, SCL_object_procedure);
|
||||
SCL_check_create_access(tdbb, obj_procedures);
|
||||
}
|
||||
|
||||
void CreateAlterProcedureNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
|
||||
@ -2877,7 +2872,7 @@ bool CreateAlterProcedureNode::executeAlter(thread_db* tdbb, DsqlCompilerScratch
|
||||
AutoCacheRequest requestHandle(tdbb, drq_m_prcs2, DYN_REQUESTS);
|
||||
bool modified = false;
|
||||
|
||||
DsqlCompiledStatement* statement = dsqlScratch->getStatement();
|
||||
DsqlStatement* statement = dsqlScratch->getDsqlStatement();
|
||||
|
||||
FOR (REQUEST_HANDLE requestHandle TRANSACTION_HANDLE transaction)
|
||||
P IN RDB$PROCEDURES
|
||||
@ -2971,7 +2966,7 @@ bool CreateAlterProcedureNode::executeAlter(thread_db* tdbb, DsqlCompilerScratch
|
||||
|
||||
P.RDB$PROCEDURE_TYPE.NULL = FALSE;
|
||||
P.RDB$PROCEDURE_TYPE = (USHORT)
|
||||
(statement->getFlags() & DsqlCompiledStatement::FLAG_SELECTABLE ?
|
||||
(statement->getFlags() & DsqlStatement::FLAG_SELECTABLE ?
|
||||
prc_selectable : prc_executable);
|
||||
}
|
||||
}
|
||||
@ -3235,6 +3230,8 @@ void CreateAlterProcedureNode::compile(thread_db* /*tdbb*/, DsqlCompilerScratch*
|
||||
dsqlScratch->cursorNumber = 0;
|
||||
|
||||
StmtNode* stmtNode = body->dsqlPass(dsqlScratch);
|
||||
|
||||
dsqlScratch->putOuterMaps();
|
||||
GEN_hidden_variables(dsqlScratch);
|
||||
|
||||
dsqlScratch->appendUChar(blr_stall);
|
||||
@ -3245,7 +3242,7 @@ void CreateAlterProcedureNode::compile(thread_db* /*tdbb*/, DsqlCompilerScratch*
|
||||
|
||||
stmtNode->genBlr(dsqlScratch);
|
||||
|
||||
dsqlScratch->getStatement()->setType(DsqlCompiledStatement::TYPE_DDL);
|
||||
dsqlScratch->getDsqlStatement()->setType(DsqlStatement::TYPE_DDL);
|
||||
dsqlScratch->appendUChar(blr_end);
|
||||
dsqlScratch->genReturn(true);
|
||||
dsqlScratch->appendUChar(blr_end);
|
||||
@ -3751,6 +3748,8 @@ void CreateAlterTriggerNode::compile(thread_db* /*tdbb*/, DsqlCompilerScratch* d
|
||||
dsqlScratch->scopeLevel++;
|
||||
|
||||
StmtNode* stmtNode = body->dsqlPass(dsqlScratch);
|
||||
|
||||
dsqlScratch->putOuterMaps();
|
||||
GEN_hidden_variables(dsqlScratch);
|
||||
|
||||
// dimitr: I see no reason to deny EXIT command in triggers,
|
||||
@ -3774,7 +3773,7 @@ void CreateAlterTriggerNode::compile(thread_db* /*tdbb*/, DsqlCompilerScratch* d
|
||||
// The statement type may have been set incorrectly when parsing
|
||||
// the trigger actions, so reset it to reflect the fact that this
|
||||
// is a data definition statement; also reset the ddl node.
|
||||
dsqlScratch->getStatement()->setType(DsqlCompiledStatement::TYPE_DDL);
|
||||
dsqlScratch->getDsqlStatement()->setType(DsqlStatement::TYPE_DDL);
|
||||
}
|
||||
|
||||
invalid = false;
|
||||
@ -3944,7 +3943,7 @@ string CreateCollationNode::internalPrint(NodePrinter& printer) const
|
||||
|
||||
void CreateCollationNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
|
||||
{
|
||||
SCL_check_create_access(tdbb, SCL_object_collation);
|
||||
SCL_check_create_access(tdbb, obj_collations);
|
||||
}
|
||||
|
||||
void CreateCollationNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
|
||||
@ -4312,7 +4311,7 @@ string CreateDomainNode::internalPrint(NodePrinter& printer) const
|
||||
|
||||
void CreateDomainNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
|
||||
{
|
||||
SCL_check_create_access(tdbb, SCL_object_domain);
|
||||
SCL_check_create_access(tdbb, obj_domains);
|
||||
}
|
||||
|
||||
void CreateDomainNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
|
||||
@ -5450,7 +5449,7 @@ void CreateAlterExceptionNode::checkPermission(thread_db* tdbb, jrd_tra* transac
|
||||
return;
|
||||
}
|
||||
|
||||
SCL_check_create_access(tdbb, SCL_object_exception);
|
||||
SCL_check_create_access(tdbb, obj_exceptions);
|
||||
}
|
||||
|
||||
void CreateAlterExceptionNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
|
||||
@ -5657,7 +5656,7 @@ void CreateAlterSequenceNode::checkPermission(thread_db* tdbb, jrd_tra* transact
|
||||
return;
|
||||
}
|
||||
|
||||
SCL_check_create_access(tdbb, SCL_object_generator);
|
||||
SCL_check_create_access(tdbb, obj_generators);
|
||||
}
|
||||
|
||||
void CreateAlterSequenceNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
|
||||
@ -5976,8 +5975,13 @@ void DropSequenceNode::deleteIdentity(thread_db* tdbb, jrd_tra* transaction, con
|
||||
WITH GEN.RDB$GENERATOR_NAME EQ name.c_str()
|
||||
{
|
||||
ERASE GEN;
|
||||
|
||||
if (!GEN.RDB$SECURITY_CLASS.NULL)
|
||||
deleteSecurityClass(tdbb, transaction, GEN.RDB$SECURITY_CLASS);
|
||||
}
|
||||
END_FOR
|
||||
|
||||
deletePrivilegesByRelName(tdbb, transaction, name, obj_generator);
|
||||
}
|
||||
|
||||
|
||||
@ -6746,6 +6750,7 @@ void RelationNode::defineConstraint(thread_db* tdbb, DsqlCompilerScratch* dsqlSc
|
||||
definition.unique = constraint.type != Constraint::TYPE_FK;
|
||||
if (constraint.index->descending)
|
||||
definition.descending = true;
|
||||
definition.inactive = false;
|
||||
definition.columns = constraint.columns;
|
||||
definition.refRelation = constraint.refRelation;
|
||||
definition.refColumns = constraint.refColumns;
|
||||
@ -7389,7 +7394,7 @@ string CreateRelationNode::internalPrint(NodePrinter& printer) const
|
||||
|
||||
void CreateRelationNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
|
||||
{
|
||||
SCL_check_create_access(tdbb, SCL_object_table);
|
||||
SCL_check_create_access(tdbb, obj_relations);
|
||||
}
|
||||
|
||||
void CreateRelationNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
|
||||
@ -8669,7 +8674,7 @@ void CreateAlterViewNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
|
||||
return;
|
||||
}
|
||||
|
||||
SCL_check_create_access(tdbb, SCL_object_view);
|
||||
SCL_check_create_access(tdbb, obj_views);
|
||||
}
|
||||
|
||||
void CreateAlterViewNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
|
||||
@ -9830,6 +9835,7 @@ void CreateIndexNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
|
||||
definition.relation = relation->dsqlName;
|
||||
definition.unique = unique;
|
||||
definition.descending = descending;
|
||||
definition.inactive = false;
|
||||
|
||||
if (columns)
|
||||
{
|
||||
@ -10090,7 +10096,7 @@ string CreateFilterNode::internalPrint(NodePrinter& printer) const
|
||||
|
||||
void CreateFilterNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
|
||||
{
|
||||
SCL_check_create_access(tdbb, SCL_object_filter);
|
||||
SCL_check_create_access(tdbb, obj_filters);
|
||||
}
|
||||
|
||||
// Define a blob filter.
|
||||
@ -10346,7 +10352,7 @@ string CreateAlterRoleNode::internalPrint(NodePrinter& printer) const
|
||||
void CreateAlterRoleNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
|
||||
{
|
||||
if (createFlag)
|
||||
SCL_check_create_access(tdbb, SCL_object_role);
|
||||
SCL_check_create_access(tdbb, obj_roles);
|
||||
else
|
||||
SCL_check_role(tdbb, name, SCL_alter);
|
||||
}
|
||||
@ -10734,7 +10740,7 @@ void MappingNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd
|
||||
(Arg::Gds(isc_adm_task_denied) << Arg::Gds(isc_miss_prvlg) << "CHANGE_MAPPING_RULES").raise();
|
||||
|
||||
if (from)
|
||||
fromUtf8 = from->toUtf8(dsqlScratch);
|
||||
fromUtf8 = from->toUtf8(transaction);
|
||||
|
||||
if (global)
|
||||
{
|
||||
@ -11512,10 +11518,10 @@ void GrantRevokeNode::grantRevoke(thread_db* tdbb, jrd_tra* transaction, const G
|
||||
const GranteeClause* userNod, const char* privs,
|
||||
MetaName field, int options)
|
||||
{
|
||||
SSHORT userType = userNod->first;
|
||||
ObjectType userType = userNod->first;
|
||||
MetaName user(userNod->second);
|
||||
MetaName dummyName;
|
||||
const SSHORT objType = object ? object->first : obj_type_MAX;
|
||||
const ObjectType objType = object ? object->first : obj_type_MAX;
|
||||
const MetaName objName(object ? object->second : "");
|
||||
bool crdb = false;
|
||||
|
||||
@ -11667,7 +11673,7 @@ void GrantRevokeNode::grantRevoke(thread_db* tdbb, jrd_tra* transaction, const G
|
||||
break;
|
||||
|
||||
default:
|
||||
fb_assert(object == NULL || objType >= obj_database);
|
||||
fb_assert(object == NULL || isDdlObject(objType));
|
||||
}
|
||||
|
||||
if (options == 1) // with grant option
|
||||
@ -11871,10 +11877,8 @@ void GrantRevokeNode::grantRevoke(thread_db* tdbb, jrd_tra* transaction, const G
|
||||
}
|
||||
|
||||
default:
|
||||
if (objType >= obj_database)
|
||||
{
|
||||
if (isDdlObject(objType))
|
||||
checkGrantorCanGrantDdl(tdbb, transaction, currentUser.c_str(), priv, objName);
|
||||
}
|
||||
else
|
||||
fb_assert(false);
|
||||
}
|
||||
@ -12296,12 +12300,16 @@ void GrantRevokeNode::checkGrantorCanGrantDdl(thread_db* tdbb, jrd_tra* transact
|
||||
WITH ((PRV.RDB$USER = UPPERCASE(grantor.c_str()) AND
|
||||
PRV.RDB$USER_TYPE = obj_user) OR (PRV.RDB$USER_TYPE = obj_sql_role)) AND
|
||||
PRV.RDB$RELATION_NAME EQ objName.c_str() AND
|
||||
PRV.RDB$OBJECT_TYPE >= obj_database AND
|
||||
PRV.RDB$OBJECT_TYPE >= obj_database AND // it might be deleted but I believe it's more efficient
|
||||
PRV.RDB$PRIVILEGE EQ privilege
|
||||
{
|
||||
if ( (PRV.RDB$USER_TYPE == obj_sql_role) && !attachment->att_user->roleInUse(tdbb, PRV.RDB$USER))
|
||||
continue;
|
||||
|
||||
// Double check if the object is DDL one.
|
||||
if (!isDdlObject(PRV.RDB$OBJECT_TYPE))
|
||||
continue;
|
||||
|
||||
if (PRV.RDB$GRANT_OPTION == WITH_GRANT_OPTION)
|
||||
{
|
||||
grantable = true;
|
||||
|
@ -1129,8 +1129,8 @@ public:
|
||||
|
||||
virtual DdlNode* dsqlPass(DsqlCompilerScratch* dsqlScratch)
|
||||
{
|
||||
dsqlScratch->getStatement()->setType(
|
||||
legacy ? DsqlCompiledStatement::TYPE_SET_GENERATOR : DsqlCompiledStatement::TYPE_DDL);
|
||||
dsqlScratch->getDsqlStatement()->setType(
|
||||
legacy ? DsqlStatement::TYPE_SET_GENERATOR : DsqlStatement::TYPE_DDL);
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -2279,7 +2279,7 @@ typedef RecreateNode<CreateAlterUserNode, DropUserNode, isc_dsql_recreate_user_f
|
||||
|
||||
|
||||
typedef Firebird::Pair<Firebird::NonPooled<char, ValueListNode*> > PrivilegeClause;
|
||||
typedef Firebird::Pair<Firebird::NonPooled<SSHORT, MetaName> > GranteeClause;
|
||||
typedef Firebird::Pair<Firebird::NonPooled<ObjectType, MetaName> > GranteeClause;
|
||||
|
||||
class GrantRevokeNode : public PrivilegesNode, private ExecInSecurityDb
|
||||
{
|
||||
@ -2417,8 +2417,8 @@ public:
|
||||
public:
|
||||
virtual DdlNode* dsqlPass(DsqlCompilerScratch* dsqlScratch)
|
||||
{
|
||||
dsqlScratch->getStatement()->setType(
|
||||
create ? DsqlCompiledStatement::TYPE_CREATE_DB : DsqlCompiledStatement::TYPE_DDL);
|
||||
dsqlScratch->getDsqlStatement()->setType(
|
||||
create ? DsqlStatement::TYPE_CREATE_DB : DsqlStatement::TYPE_DDL);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -60,15 +60,15 @@ namespace {
|
||||
};
|
||||
}
|
||||
|
||||
DsqlBatch::DsqlBatch(dsql_req* req, const dsql_msg* /*message*/, IMessageMetadata* inMeta, ClumpletReader& pb)
|
||||
: m_request(req),
|
||||
DsqlBatch::DsqlBatch(DsqlDmlRequest* req, const dsql_msg* /*message*/, IMessageMetadata* inMeta, ClumpletReader& pb)
|
||||
: m_dsqlRequest(req),
|
||||
m_batch(NULL),
|
||||
m_meta(inMeta),
|
||||
m_messages(m_request->getPool()),
|
||||
m_blobs(m_request->getPool()),
|
||||
m_blobMap(m_request->getPool()),
|
||||
m_blobMeta(m_request->getPool()),
|
||||
m_defaultBpb(m_request->getPool()),
|
||||
m_messages(m_dsqlRequest->getPool()),
|
||||
m_blobs(m_dsqlRequest->getPool()),
|
||||
m_blobMap(m_dsqlRequest->getPool()),
|
||||
m_blobMeta(m_dsqlRequest->getPool()),
|
||||
m_defaultBpb(m_dsqlRequest->getPool()),
|
||||
m_messageSize(0),
|
||||
m_alignedMessage(0),
|
||||
m_alignment(0),
|
||||
@ -168,13 +168,13 @@ DsqlBatch::~DsqlBatch()
|
||||
{
|
||||
if (m_batch)
|
||||
m_batch->resetHandle();
|
||||
if (m_request)
|
||||
m_request->req_batch = NULL;
|
||||
if (m_dsqlRequest)
|
||||
m_dsqlRequest->req_batch = NULL;
|
||||
}
|
||||
|
||||
Attachment* DsqlBatch::getAttachment() const
|
||||
{
|
||||
return m_request->req_dbb->dbb_attachment;
|
||||
return m_dsqlRequest->req_dbb->dbb_attachment;
|
||||
}
|
||||
|
||||
void DsqlBatch::setInterfacePtr(JBatch* interfacePtr) throw()
|
||||
@ -183,7 +183,7 @@ void DsqlBatch::setInterfacePtr(JBatch* interfacePtr) throw()
|
||||
m_batch = interfacePtr;
|
||||
}
|
||||
|
||||
DsqlBatch* DsqlBatch::open(thread_db* tdbb, dsql_req* req, IMessageMetadata* inMetadata,
|
||||
DsqlBatch* DsqlBatch::open(thread_db* tdbb, DsqlDmlRequest* req, IMessageMetadata* inMetadata,
|
||||
unsigned parLength, const UCHAR* par)
|
||||
{
|
||||
SET_TDBB(tdbb);
|
||||
@ -205,15 +205,15 @@ DsqlBatch* DsqlBatch::open(thread_db* tdbb, dsql_req* req, IMessageMetadata* inM
|
||||
|
||||
// Sanity checks before creating batch
|
||||
|
||||
if (!req->req_request)
|
||||
if (!req->getRequest())
|
||||
{
|
||||
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-504) <<
|
||||
Arg::Gds(isc_unprepared_stmt));
|
||||
}
|
||||
|
||||
const DsqlCompiledStatement* statement = req->getStatement();
|
||||
const auto statement = req->getDsqlStatement();
|
||||
|
||||
if (statement->getFlags() & DsqlCompiledStatement::FLAG_ORPHAN)
|
||||
if (statement->getFlags() & DsqlStatement::FLAG_ORPHAN)
|
||||
{
|
||||
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-901) <<
|
||||
Arg::Gds(isc_bad_req_handle));
|
||||
@ -221,11 +221,11 @@ DsqlBatch* DsqlBatch::open(thread_db* tdbb, dsql_req* req, IMessageMetadata* inM
|
||||
|
||||
switch (statement->getType())
|
||||
{
|
||||
case DsqlCompiledStatement::TYPE_INSERT:
|
||||
case DsqlCompiledStatement::TYPE_DELETE:
|
||||
case DsqlCompiledStatement::TYPE_UPDATE:
|
||||
case DsqlCompiledStatement::TYPE_EXEC_PROCEDURE:
|
||||
case DsqlCompiledStatement::TYPE_EXEC_BLOCK:
|
||||
case DsqlStatement::TYPE_INSERT:
|
||||
case DsqlStatement::TYPE_DELETE:
|
||||
case DsqlStatement::TYPE_UPDATE:
|
||||
case DsqlStatement::TYPE_EXEC_PROCEDURE:
|
||||
case DsqlStatement::TYPE_EXEC_BLOCK:
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -451,7 +451,7 @@ Firebird::IBatchCompletionState* DsqlBatch::execute(thread_db* tdbb)
|
||||
jrd_tra* transaction = tdbb->getTransaction();
|
||||
|
||||
// execution timer
|
||||
thread_db::TimerGuard timerGuard(tdbb, m_request->setupTimer(tdbb), true);
|
||||
thread_db::TimerGuard timerGuard(tdbb, m_dsqlRequest->setupTimer(tdbb), true);
|
||||
|
||||
// sync internal buffers
|
||||
m_messages.done();
|
||||
@ -651,20 +651,20 @@ private:
|
||||
}
|
||||
|
||||
// execute request
|
||||
m_request->req_transaction = transaction;
|
||||
jrd_req* req = m_request->req_request;
|
||||
m_dsqlRequest->req_transaction = transaction;
|
||||
Request* req = m_dsqlRequest->getRequest();
|
||||
fb_assert(req);
|
||||
|
||||
// prepare completion interface
|
||||
AutoPtr<BatchCompletionState, SimpleDispose> completionState
|
||||
(FB_NEW BatchCompletionState(m_flags & (1 << IBatch::TAG_RECORD_COUNTS), m_detailed));
|
||||
AutoSetRestore<bool> batchFlag(&req->req_batch_mode, true);
|
||||
const dsql_msg* message = m_request->getStatement()->getSendMsg();
|
||||
const dsql_msg* message = m_dsqlRequest->getDsqlStatement()->getSendMsg();
|
||||
bool startRequest = true;
|
||||
|
||||
bool isExecBlock = m_request->getStatement()->getType() == DsqlCompiledStatement::TYPE_EXEC_BLOCK;
|
||||
const auto receiveMessage = isExecBlock ? m_request->getStatement()->getReceiveMsg() : nullptr;
|
||||
auto receiveMsgBuffer = isExecBlock ? m_request->req_msg_buffers[receiveMessage->msg_buffer_number] : nullptr;
|
||||
bool isExecBlock = m_dsqlRequest->getDsqlStatement()->getType() == DsqlStatement::TYPE_EXEC_BLOCK;
|
||||
const auto receiveMessage = isExecBlock ? m_dsqlRequest->getDsqlStatement()->getReceiveMsg() : nullptr;
|
||||
auto receiveMsgBuffer = isExecBlock ? m_dsqlRequest->req_msg_buffers[receiveMessage->msg_buffer_number] : nullptr;
|
||||
|
||||
// process messages
|
||||
ULONG remains;
|
||||
@ -720,11 +720,11 @@ private:
|
||||
}
|
||||
|
||||
// map message to internal engine format
|
||||
m_request->mapInOut(tdbb, false, message, m_meta, NULL, data);
|
||||
m_dsqlRequest->mapInOut(tdbb, false, message, m_meta, NULL, data);
|
||||
data += m_messageSize;
|
||||
remains -= m_messageSize;
|
||||
|
||||
UCHAR* msgBuffer = m_request->req_msg_buffers[message->msg_buffer_number];
|
||||
UCHAR* msgBuffer = m_dsqlRequest->req_msg_buffers[message->msg_buffer_number];
|
||||
try
|
||||
{
|
||||
// runsend data to request and collect stats
|
||||
|
@ -41,7 +41,7 @@ class ClumpletReader;
|
||||
|
||||
namespace Jrd {
|
||||
|
||||
class dsql_req;
|
||||
class DsqlDmlRequest;
|
||||
class dsql_msg;
|
||||
class thread_db;
|
||||
class JBatch;
|
||||
@ -50,7 +50,7 @@ class Attachment;
|
||||
class DsqlBatch
|
||||
{
|
||||
public:
|
||||
DsqlBatch(dsql_req* req, const dsql_msg* message, Firebird::IMessageMetadata* inMetadata,
|
||||
DsqlBatch(DsqlDmlRequest* req, const dsql_msg* message, Firebird::IMessageMetadata* inMetadata,
|
||||
Firebird::ClumpletReader& pb);
|
||||
~DsqlBatch();
|
||||
|
||||
@ -61,7 +61,7 @@ public:
|
||||
static const ULONG SIZEOF_BLOB_HEAD = sizeof(ISC_QUAD) + 2 * sizeof(ULONG);
|
||||
static const unsigned BLOB_STREAM_ALIGN = 4;
|
||||
|
||||
static DsqlBatch* open(thread_db* tdbb, dsql_req* req, Firebird::IMessageMetadata* inMetadata,
|
||||
static DsqlBatch* open(thread_db* tdbb, DsqlDmlRequest* req, Firebird::IMessageMetadata* inMetadata,
|
||||
unsigned parLength, const UCHAR* par);
|
||||
|
||||
Attachment* getAttachment() const;
|
||||
@ -101,7 +101,7 @@ private:
|
||||
m_flags &= ~(1 << bit);
|
||||
}
|
||||
|
||||
dsql_req* const m_request;
|
||||
DsqlDmlRequest* const m_dsqlRequest;
|
||||
JBatch* m_batch;
|
||||
Firebird::IMessageMetadata* m_meta;
|
||||
|
||||
|
@ -345,30 +345,24 @@ void DsqlCompilerScratch::putLocalVariables(CompoundStmtNode* parameters, USHORT
|
||||
if (!(flags & DsqlCompilerScratch::FLAG_SUB_ROUTINE))
|
||||
{
|
||||
// Check not implemented sub-functions.
|
||||
|
||||
GenericMap<Left<MetaName, DeclareSubFuncNode*> >::ConstAccessor funcAccessor(&subFunctions);
|
||||
|
||||
for (bool found = funcAccessor.getFirst(); found; found = funcAccessor.getNext())
|
||||
for (const auto& funcPair : subFunctions)
|
||||
{
|
||||
if (!funcAccessor.current()->second->dsqlBlock)
|
||||
if (!funcPair.second->dsqlBlock)
|
||||
{
|
||||
status_exception::raise(
|
||||
Arg::Gds(isc_subfunc_not_impl) <<
|
||||
funcAccessor.current()->first.c_str());
|
||||
funcPair.first.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
// Check not implemented sub-procedures.
|
||||
|
||||
GenericMap<Left<MetaName, DeclareSubProcNode*> >::ConstAccessor procAccessor(&subProcedures);
|
||||
|
||||
for (bool found = procAccessor.getFirst(); found; found = procAccessor.getNext())
|
||||
for (const auto& procPair : subProcedures)
|
||||
{
|
||||
if (!procAccessor.current()->second->dsqlBlock)
|
||||
if (!procPair.second->dsqlBlock)
|
||||
{
|
||||
status_exception::raise(
|
||||
Arg::Gds(isc_subproc_not_impl) <<
|
||||
procAccessor.current()->first.c_str());
|
||||
procPair.first.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -430,6 +424,31 @@ void DsqlCompilerScratch::putLocalVariable(dsql_var* variable, const DeclareVari
|
||||
++hiddenVarsNumber;
|
||||
}
|
||||
|
||||
// Put maps in subroutines for outer variables/parameters usage.
|
||||
void DsqlCompilerScratch::putOuterMaps()
|
||||
{
|
||||
if (!outerMessagesMap.count() && !outerVarsMap.count())
|
||||
return;
|
||||
|
||||
appendUChar(blr_outer_map);
|
||||
|
||||
for (auto& pair : outerVarsMap)
|
||||
{
|
||||
appendUChar(blr_outer_map_variable);
|
||||
appendUShort(pair.first);
|
||||
appendUShort(pair.second);
|
||||
}
|
||||
|
||||
for (auto& pair : outerMessagesMap)
|
||||
{
|
||||
appendUChar(blr_outer_map_message);
|
||||
appendUShort(pair.first);
|
||||
appendUShort(pair.second);
|
||||
}
|
||||
|
||||
appendUChar(blr_end);
|
||||
}
|
||||
|
||||
// Make a variable.
|
||||
dsql_var* DsqlCompilerScratch::makeVariable(dsql_fld* field, const char* name,
|
||||
const dsql_var::Type type, USHORT msgNumber, USHORT itemNumber, USHORT localNumber)
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
#include "../jrd/jrd.h"
|
||||
#include "../dsql/dsql.h"
|
||||
#include "../dsql/DsqlStatements.h"
|
||||
#include "../dsql/BlrDebugWriter.h"
|
||||
#include "../common/classes/array.h"
|
||||
#include "../jrd/MetaName.h"
|
||||
@ -73,14 +74,13 @@ public:
|
||||
|
||||
public:
|
||||
DsqlCompilerScratch(MemoryPool& p, dsql_dbb* aDbb, jrd_tra* aTransaction,
|
||||
DsqlCompiledStatement* aStatement, DsqlCompilerScratch* aMainScratch = NULL)
|
||||
DsqlStatement* aDsqlStatement = nullptr, DsqlCompilerScratch* aMainScratch = nullptr)
|
||||
: BlrDebugWriter(p),
|
||||
dbb(aDbb),
|
||||
transaction(aTransaction),
|
||||
statement(aStatement),
|
||||
dsqlStatement(aDsqlStatement),
|
||||
flags(0),
|
||||
nestingLevel(0),
|
||||
ports(p),
|
||||
relation(NULL),
|
||||
mainContext(p),
|
||||
context(&mainContext),
|
||||
@ -117,10 +117,12 @@ public:
|
||||
outputVariables(p),
|
||||
returningClause(nullptr),
|
||||
currCteAlias(NULL),
|
||||
mainScratch(aMainScratch),
|
||||
outerMessagesMap(p),
|
||||
outerVarsMap(p),
|
||||
ctes(p),
|
||||
cteAliases(p),
|
||||
psql(false),
|
||||
mainScratch(aMainScratch),
|
||||
subFunctions(p),
|
||||
subProcedures(p)
|
||||
{
|
||||
@ -142,7 +144,7 @@ public:
|
||||
public:
|
||||
virtual bool isVersion4()
|
||||
{
|
||||
return statement->getBlrVersion() == 4;
|
||||
return dsqlStatement->getBlrVersion() == 4;
|
||||
}
|
||||
|
||||
MemoryPool& getPool()
|
||||
@ -165,14 +167,14 @@ public:
|
||||
transaction = value;
|
||||
}
|
||||
|
||||
DsqlCompiledStatement* getStatement()
|
||||
DsqlStatement* getDsqlStatement() const
|
||||
{
|
||||
return statement;
|
||||
return dsqlStatement;
|
||||
}
|
||||
|
||||
DsqlCompiledStatement* getStatement() const
|
||||
void setDsqlStatement(DsqlStatement* aDsqlStatement)
|
||||
{
|
||||
return statement;
|
||||
dsqlStatement = aDsqlStatement;
|
||||
}
|
||||
|
||||
void putBlrMarkers(ULONG marks);
|
||||
@ -181,6 +183,7 @@ public:
|
||||
void putLocalVariables(CompoundStmtNode* parameters, USHORT locals);
|
||||
void putLocalVariable(dsql_var* variable, const DeclareVariableNode* hostParam,
|
||||
const MetaName& collationName);
|
||||
void putOuterMaps();
|
||||
dsql_var* makeVariable(dsql_fld*, const char*, const dsql_var::Type type, USHORT,
|
||||
USHORT, USHORT);
|
||||
dsql_var* resolveVariable(const MetaName& varName);
|
||||
@ -269,12 +272,11 @@ private:
|
||||
|
||||
dsql_dbb* dbb; // DSQL attachment
|
||||
jrd_tra* transaction; // Transaction
|
||||
DsqlCompiledStatement* statement; // Compiled statement
|
||||
DsqlStatement* dsqlStatement; // DSQL statement
|
||||
|
||||
public:
|
||||
unsigned flags; // flags
|
||||
unsigned nestingLevel; // begin...end nesting level
|
||||
Firebird::Array<dsql_msg*> ports; // Port messages
|
||||
dsql_rel* relation; // relation created by this request (for DDL)
|
||||
DsqlContextStack mainContext;
|
||||
DsqlContextStack* context;
|
||||
@ -313,14 +315,16 @@ public:
|
||||
Firebird::Array<dsql_var*> outputVariables;
|
||||
ReturningClause* returningClause;
|
||||
const Firebird::string* const* currCteAlias;
|
||||
DsqlCompilerScratch* mainScratch;
|
||||
Firebird::NonPooledMap<USHORT, USHORT> outerMessagesMap; // <outer, inner>
|
||||
Firebird::NonPooledMap<USHORT, USHORT> outerVarsMap; // <outer, inner>
|
||||
|
||||
private:
|
||||
Firebird::HalfStaticArray<SelectExprNode*, 4> ctes; // common table expressions
|
||||
Firebird::HalfStaticArray<const Firebird::string*, 4> cteAliases; // CTE aliases in recursive members
|
||||
bool psql;
|
||||
DsqlCompilerScratch* mainScratch;
|
||||
Firebird::GenericMap<Firebird::Left<MetaName, DeclareSubFuncNode*> > subFunctions;
|
||||
Firebird::GenericMap<Firebird::Left<MetaName, DeclareSubProcNode*> > subProcedures;
|
||||
Firebird::LeftPooledMap<MetaName, DeclareSubFuncNode*> subFunctions;
|
||||
Firebird::LeftPooledMap<MetaName, DeclareSubProcNode*> subProcedures;
|
||||
};
|
||||
|
||||
class PsqlChanger
|
||||
|
@ -35,13 +35,13 @@ using namespace Jrd;
|
||||
static const char* const SCRATCH = "fb_cursor_";
|
||||
static const ULONG PREFETCH_SIZE = 65536; // 64 KB
|
||||
|
||||
DsqlCursor::DsqlCursor(dsql_req* req, ULONG flags)
|
||||
: m_request(req), m_message(req->getStatement()->getReceiveMsg()),
|
||||
DsqlCursor::DsqlCursor(DsqlDmlRequest* req, ULONG flags)
|
||||
: m_dsqlRequest(req), m_message(req->getDsqlStatement()->getReceiveMsg()),
|
||||
m_resultSet(NULL), m_flags(flags),
|
||||
m_space(req->getPool(), SCRATCH),
|
||||
m_state(BOS), m_eof(false), m_position(0), m_cachedCount(0)
|
||||
{
|
||||
TRA_link_cursor(m_request->req_transaction, this);
|
||||
TRA_link_cursor(m_dsqlRequest->req_transaction, this);
|
||||
}
|
||||
|
||||
DsqlCursor::~DsqlCursor()
|
||||
@ -52,12 +52,12 @@ DsqlCursor::~DsqlCursor()
|
||||
|
||||
jrd_tra* DsqlCursor::getTransaction() const
|
||||
{
|
||||
return m_request->req_transaction;
|
||||
return m_dsqlRequest->req_transaction;
|
||||
}
|
||||
|
||||
Attachment* DsqlCursor::getAttachment() const
|
||||
{
|
||||
return m_request->req_dbb->dbb_attachment;
|
||||
return m_dsqlRequest->req_dbb->dbb_attachment;
|
||||
}
|
||||
|
||||
void DsqlCursor::setInterfacePtr(JResultSet* interfacePtr) throw()
|
||||
@ -71,35 +71,35 @@ void DsqlCursor::close(thread_db* tdbb, DsqlCursor* cursor)
|
||||
if (!cursor)
|
||||
return;
|
||||
|
||||
Jrd::Attachment* const attachment = cursor->getAttachment();
|
||||
dsql_req* const request = cursor->m_request;
|
||||
const auto attachment = cursor->getAttachment();
|
||||
const auto dsqlRequest = cursor->m_dsqlRequest;
|
||||
|
||||
if (request->req_request)
|
||||
if (dsqlRequest->getRequest())
|
||||
{
|
||||
ThreadStatusGuard status_vector(tdbb);
|
||||
try
|
||||
{
|
||||
// Report some remaining fetches if any
|
||||
if (request->req_fetch_baseline)
|
||||
if (dsqlRequest->req_fetch_baseline)
|
||||
{
|
||||
TraceDSQLFetch trace(attachment, request);
|
||||
TraceDSQLFetch trace(attachment, dsqlRequest);
|
||||
trace.fetch(true, ITracePlugin::RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
if (request->req_traced && TraceManager::need_dsql_free(attachment))
|
||||
if (dsqlRequest->req_traced && TraceManager::need_dsql_free(attachment))
|
||||
{
|
||||
TraceSQLStatementImpl stmt(request, NULL);
|
||||
TraceSQLStatementImpl stmt(dsqlRequest, NULL);
|
||||
TraceManager::event_dsql_free(attachment, &stmt, DSQL_close);
|
||||
}
|
||||
|
||||
JRD_unwind_request(tdbb, request->req_request);
|
||||
JRD_unwind_request(tdbb, dsqlRequest->getRequest());
|
||||
}
|
||||
catch (Firebird::Exception&)
|
||||
{} // no-op
|
||||
}
|
||||
|
||||
request->req_cursor = NULL;
|
||||
TRA_unlink_cursor(request->req_transaction, cursor);
|
||||
dsqlRequest->req_cursor = NULL;
|
||||
TRA_unlink_cursor(dsqlRequest->req_transaction, cursor);
|
||||
delete cursor;
|
||||
}
|
||||
|
||||
@ -107,7 +107,7 @@ int DsqlCursor::fetchNext(thread_db* tdbb, UCHAR* buffer)
|
||||
{
|
||||
if (!(m_flags & IStatement::CURSOR_TYPE_SCROLLABLE))
|
||||
{
|
||||
m_eof = !m_request->fetch(tdbb, buffer);
|
||||
m_eof = !m_dsqlRequest->fetch(tdbb, buffer);
|
||||
|
||||
if (m_eof)
|
||||
{
|
||||
@ -300,13 +300,13 @@ int DsqlCursor::fetchFromCache(thread_db* tdbb, UCHAR* buffer, FB_UINT64 positio
|
||||
|
||||
fb_assert(position < m_cachedCount);
|
||||
|
||||
UCHAR* const msgBuffer = m_request->req_msg_buffers[m_message->msg_buffer_number];
|
||||
UCHAR* const msgBuffer = m_dsqlRequest->req_msg_buffers[m_message->msg_buffer_number];
|
||||
|
||||
const FB_UINT64 offset = position * m_message->msg_length;
|
||||
const FB_UINT64 readBytes = m_space.read(offset, msgBuffer, m_message->msg_length);
|
||||
fb_assert(readBytes == m_message->msg_length);
|
||||
|
||||
m_request->mapInOut(tdbb, true, m_message, NULL, buffer);
|
||||
m_dsqlRequest->mapInOut(tdbb, true, m_message, NULL, buffer);
|
||||
|
||||
m_position = position;
|
||||
m_state = POSITIONED;
|
||||
@ -318,13 +318,13 @@ bool DsqlCursor::cacheInput(thread_db* tdbb, FB_UINT64 position)
|
||||
fb_assert(!m_eof);
|
||||
|
||||
const ULONG prefetchCount = MAX(PREFETCH_SIZE / m_message->msg_length, 1);
|
||||
const UCHAR* const msgBuffer = m_request->req_msg_buffers[m_message->msg_buffer_number];
|
||||
const UCHAR* const msgBuffer = m_dsqlRequest->req_msg_buffers[m_message->msg_buffer_number];
|
||||
|
||||
while (position >= m_cachedCount)
|
||||
{
|
||||
for (ULONG count = 0; count < prefetchCount; count++)
|
||||
{
|
||||
if (!m_request->fetch(tdbb, NULL))
|
||||
if (!m_dsqlRequest->fetch(tdbb, NULL))
|
||||
{
|
||||
m_eof = true;
|
||||
break;
|
||||
|
@ -27,7 +27,7 @@
|
||||
|
||||
namespace Jrd {
|
||||
|
||||
class dsql_req;
|
||||
class DsqlDmlRequest;
|
||||
class JResultSet;
|
||||
|
||||
class DsqlCursor
|
||||
@ -35,7 +35,7 @@ class DsqlCursor
|
||||
enum State { BOS, POSITIONED, EOS };
|
||||
|
||||
public:
|
||||
DsqlCursor(dsql_req* req, ULONG flags);
|
||||
DsqlCursor(DsqlDmlRequest* req, ULONG flags);
|
||||
~DsqlCursor();
|
||||
|
||||
jrd_tra* getTransaction() const;
|
||||
@ -69,7 +69,7 @@ private:
|
||||
int fetchFromCache(thread_db* tdbb, UCHAR* buffer, FB_UINT64 position);
|
||||
bool cacheInput(thread_db* tdbb, FB_UINT64 position = MAX_UINT64);
|
||||
|
||||
dsql_req* const m_request;
|
||||
DsqlDmlRequest* const m_dsqlRequest;
|
||||
const dsql_msg* const m_message;
|
||||
JResultSet* m_resultSet;
|
||||
const ULONG m_flags;
|
||||
|
1125
src/dsql/DsqlRequests.cpp
Normal file
1125
src/dsql/DsqlRequests.cpp
Normal file
File diff suppressed because it is too large
Load Diff
261
src/dsql/DsqlRequests.h
Normal file
261
src/dsql/DsqlRequests.h
Normal file
@ -0,0 +1,261 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Interbase 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.Inprise.com/IPL.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 Original Code was created by Inprise Corporation
|
||||
* and its predecessors. Portions created by Inprise Corporation are
|
||||
* Copyright (C) Inprise Corporation.
|
||||
*
|
||||
* All Rights Reserved.
|
||||
* Contributor(s): ______________________________________.
|
||||
*
|
||||
* 2022.02.07 Adriano dos Santos Fernandes: Refactored from dsql.h
|
||||
*/
|
||||
|
||||
#ifndef DSQL_REQUESTS_H
|
||||
#define DSQL_REQUESTS_H
|
||||
|
||||
#include "firebird/Interface.h"
|
||||
#include "../common/StatusArg.h"
|
||||
#include "../common/classes/alloc.h"
|
||||
#include "../common/classes/array.h"
|
||||
#include "../common/classes/fb_string.h"
|
||||
#include "../common/classes/NestConst.h"
|
||||
#include "../common/classes/RefCounted.h"
|
||||
#include "../jrd/jrd.h"
|
||||
|
||||
namespace Jrd {
|
||||
|
||||
|
||||
class DdlNode;
|
||||
class dsql_dbb;
|
||||
class DsqlStatement;
|
||||
class DsqlCompilerScratch;
|
||||
class DsqlCursor;
|
||||
class DsqlDmlStatement;
|
||||
class dsql_par;
|
||||
class Request;
|
||||
class jrd_tra;
|
||||
class Statement;
|
||||
class SessionManagementNode;
|
||||
class TransactionNode;
|
||||
|
||||
|
||||
class DsqlRequest : public Firebird::PermanentStorage
|
||||
{
|
||||
public:
|
||||
DsqlRequest(MemoryPool& pool, dsql_dbb* dbb, DsqlStatement* aStatement);
|
||||
virtual ~DsqlRequest();
|
||||
|
||||
public:
|
||||
jrd_tra* getTransaction()
|
||||
{
|
||||
return req_transaction;
|
||||
}
|
||||
|
||||
Firebird::RefPtr<DsqlStatement> getDsqlStatement()
|
||||
{
|
||||
return dsqlStatement;
|
||||
}
|
||||
|
||||
virtual Statement* getStatement() const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
virtual Request* getRequest() const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
virtual DsqlCursor* openCursor(thread_db* tdbb, jrd_tra** traHandle,
|
||||
Firebird::IMessageMetadata* inMeta, const UCHAR* inMsg,
|
||||
Firebird::IMessageMetadata* outMeta, ULONG flags)
|
||||
{
|
||||
Firebird::Arg::Gds(isc_no_cursor).raise();
|
||||
}
|
||||
|
||||
virtual DsqlBatch* openBatch(thread_db* tdbb, Firebird::IMessageMetadata* inMetadata,
|
||||
unsigned parLength, const UCHAR* par)
|
||||
{
|
||||
(Firebird::Arg::Gds(isc_sqlerr) <<
|
||||
Firebird::Arg::Num(-504) <<
|
||||
Firebird::Arg::Gds(isc_unprepared_stmt)
|
||||
).raise();
|
||||
}
|
||||
|
||||
virtual void execute(thread_db* tdbb, jrd_tra** traHandle,
|
||||
Firebird::IMessageMetadata* inMetadata, const UCHAR* inMsg,
|
||||
Firebird::IMessageMetadata* outMetadata, UCHAR* outMsg,
|
||||
bool singleton) = 0;
|
||||
|
||||
virtual void setCursor(thread_db* tdbb, const TEXT* name);
|
||||
|
||||
virtual bool fetch(thread_db* tdbb, UCHAR* buffer);
|
||||
|
||||
virtual void setDelayedFormat(thread_db* tdbb, Firebird::IMessageMetadata* metadata);
|
||||
|
||||
// Get session-level timeout, milliseconds
|
||||
unsigned int getTimeout();
|
||||
|
||||
// Set session-level timeout, milliseconds
|
||||
void setTimeout(unsigned int timeOut);
|
||||
|
||||
// Get actual timeout, milliseconds
|
||||
unsigned int getActualTimeout();
|
||||
|
||||
// Evaluate actual timeout value, consider config- and session-level timeout values,
|
||||
// setup and start timer
|
||||
TimeoutTimer* setupTimer(thread_db* tdbb);
|
||||
|
||||
USHORT parseMetadata(Firebird::IMessageMetadata* meta, const Firebird::Array<dsql_par*>& parameters_list);
|
||||
|
||||
static void destroy(thread_db* tdbb, DsqlRequest* request);
|
||||
|
||||
public:
|
||||
dsql_dbb* req_dbb; // DSQL attachment
|
||||
Firebird::RefPtr<DsqlStatement> dsqlStatement;
|
||||
Firebird::Array<DsqlDmlStatement*> cursors{getPool()}; // Cursor update statements
|
||||
|
||||
jrd_tra* req_transaction = nullptr; // JRD transaction
|
||||
|
||||
Firebird::string req_cursor_name{getPool()}; // Cursor name, if any
|
||||
DsqlCursor* req_cursor = nullptr; // Open cursor, if any
|
||||
DsqlBatch* req_batch = nullptr; // Active batch, if any
|
||||
Firebird::NonPooledMap<const dsql_par*, dsc> req_user_descs{getPool()}; // SQLDA data type
|
||||
|
||||
Firebird::AutoPtr<Jrd::RuntimeStatistics> req_fetch_baseline; // State of request performance counters when we reported it last time
|
||||
SINT64 req_fetch_elapsed = 0; // Number of clock ticks spent while fetching rows for this request since we reported it last time
|
||||
SINT64 req_fetch_rowcount = 0; // Total number of rows returned by this request
|
||||
bool req_traced = false; // request is traced via TraceAPI
|
||||
|
||||
protected:
|
||||
unsigned int req_timeout = 0; // query timeout in milliseconds, set by the user
|
||||
Firebird::RefPtr<TimeoutTimer> req_timer; // timeout timer
|
||||
};
|
||||
|
||||
|
||||
class DsqlDmlRequest final : public DsqlRequest
|
||||
{
|
||||
public:
|
||||
DsqlDmlRequest(thread_db* tdbb, MemoryPool& pool, dsql_dbb* dbb, DsqlStatement* aDsqlStatement);
|
||||
|
||||
// Reintroduce method to fake covariant return type with RefPtr.
|
||||
auto getDsqlStatement()
|
||||
{
|
||||
return Firebird::RefPtr<DsqlDmlStatement>((DsqlDmlStatement*) dsqlStatement.getPtr());
|
||||
}
|
||||
|
||||
Statement* getStatement() const override;
|
||||
|
||||
Request* getRequest() const override
|
||||
{
|
||||
return request;
|
||||
}
|
||||
|
||||
DsqlCursor* openCursor(thread_db* tdbb, jrd_tra** traHandle,
|
||||
Firebird::IMessageMetadata* inMeta, const UCHAR* inMsg,
|
||||
Firebird::IMessageMetadata* outMeta, ULONG flags) override;
|
||||
|
||||
DsqlBatch* openBatch(thread_db* tdbb, Firebird::IMessageMetadata* inMetadata,
|
||||
unsigned parLength, const UCHAR* par) override;
|
||||
|
||||
void execute(thread_db* tdbb, jrd_tra** traHandle,
|
||||
Firebird::IMessageMetadata* inMetadata, const UCHAR* inMsg,
|
||||
Firebird::IMessageMetadata* outMetadata, UCHAR* outMsg,
|
||||
bool singleton) override;
|
||||
|
||||
void setCursor(thread_db* tdbb, const TEXT* name) override;
|
||||
|
||||
bool fetch(thread_db* tdbb, UCHAR* buffer) override;
|
||||
|
||||
void setDelayedFormat(thread_db* tdbb, Firebird::IMessageMetadata* metadata) override;
|
||||
|
||||
void mapInOut(Jrd::thread_db* tdbb, bool toExternal, const dsql_msg* message, Firebird::IMessageMetadata* meta,
|
||||
UCHAR* dsql_msg_buf, const UCHAR* in_dsql_msg_buf = nullptr);
|
||||
|
||||
private:
|
||||
// True, if request could be restarted
|
||||
bool needRestarts();
|
||||
|
||||
void doExecute(thread_db* tdbb, jrd_tra** traHandle,
|
||||
Firebird::IMessageMetadata* outMetadata, UCHAR* outMsg,
|
||||
bool singleton);
|
||||
|
||||
// [Re]start part of "request restarts" algorithm
|
||||
void executeReceiveWithRestarts(thread_db* tdbb, jrd_tra** traHandle,
|
||||
Firebird::IMessageMetadata* outMetadata, UCHAR* outMsg,
|
||||
bool singleton, bool exec, bool fetch);
|
||||
|
||||
public:
|
||||
Firebird::Array<UCHAR*> req_msg_buffers;
|
||||
|
||||
private:
|
||||
Firebird::RefPtr<Firebird::IMessageMetadata> delayedFormat;
|
||||
Request* request = nullptr;
|
||||
bool needDelayedFormat = false;
|
||||
bool firstRowFetched = false;
|
||||
};
|
||||
|
||||
|
||||
class DsqlDdlRequest final : public DsqlRequest
|
||||
{
|
||||
public:
|
||||
DsqlDdlRequest(MemoryPool& pool, dsql_dbb* dbb, DsqlCompilerScratch* aInternalScratch, DdlNode* aNode);
|
||||
|
||||
void execute(thread_db* tdbb, jrd_tra** traHandle,
|
||||
Firebird::IMessageMetadata* inMetadata, const UCHAR* inMsg,
|
||||
Firebird::IMessageMetadata* outMetadata, UCHAR* outMsg,
|
||||
bool singleton) override;
|
||||
|
||||
private:
|
||||
DsqlCompilerScratch* internalScratch;
|
||||
NestConst<DdlNode> node;
|
||||
};
|
||||
|
||||
|
||||
class DsqlTransactionRequest final : public DsqlRequest
|
||||
{
|
||||
public:
|
||||
DsqlTransactionRequest(MemoryPool& pool, dsql_dbb* dbb, DsqlStatement* aStatement, TransactionNode* aNode);
|
||||
|
||||
void execute(thread_db* tdbb, jrd_tra** traHandle,
|
||||
Firebird::IMessageMetadata* inMetadata, const UCHAR* inMsg,
|
||||
Firebird::IMessageMetadata* outMetadata, UCHAR* outMsg,
|
||||
bool singleton) override;
|
||||
|
||||
private:
|
||||
NestConst<TransactionNode> node;
|
||||
};
|
||||
|
||||
|
||||
class DsqlSessionManagementRequest final : public DsqlRequest
|
||||
{
|
||||
public:
|
||||
DsqlSessionManagementRequest(MemoryPool& pool, dsql_dbb* dbb, DsqlStatement* aStatement,
|
||||
SessionManagementNode* aNode)
|
||||
: DsqlRequest(pool, dbb, aStatement),
|
||||
node(aNode)
|
||||
{
|
||||
}
|
||||
|
||||
void execute(thread_db* tdbb, jrd_tra** traHandle,
|
||||
Firebird::IMessageMetadata* inMetadata, const UCHAR* inMsg,
|
||||
Firebird::IMessageMetadata* outMetadata, UCHAR* outMsg,
|
||||
bool singleton) override;
|
||||
|
||||
private:
|
||||
NestConst<SessionManagementNode> node;
|
||||
};
|
||||
|
||||
|
||||
} // namespace Jrd
|
||||
|
||||
#endif // DSQL_REQUESTS_H
|
285
src/dsql/DsqlStatementCache.cpp
Normal file
285
src/dsql/DsqlStatementCache.cpp
Normal file
@ -0,0 +1,285 @@
|
||||
/*
|
||||
* 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 Adriano dos Santos Fernandes
|
||||
* for the Firebird Open Source RDBMS project.
|
||||
*
|
||||
* Copyright (c) 2022 Adriano dos Santos Fernandes <adrianosf@gmail.com>
|
||||
* and all contributors signed below.
|
||||
*
|
||||
* All Rights Reserved.
|
||||
* Contributor(s): ______________________________________.
|
||||
*/
|
||||
|
||||
#include "firebird.h"
|
||||
#include "../dsql/DsqlStatementCache.h"
|
||||
#include "../dsql/DsqlStatements.h"
|
||||
#include "../jrd/Attachment.h"
|
||||
#include "../jrd/Statement.h"
|
||||
#include "../jrd/lck.h"
|
||||
#include "../jrd/lck_proto.h"
|
||||
|
||||
using namespace Firebird;
|
||||
using namespace Jrd;
|
||||
|
||||
|
||||
// Class DsqlStatementCache
|
||||
|
||||
DsqlStatementCache::DsqlStatementCache(MemoryPool& o, Attachment* attachment)
|
||||
: PermanentStorage(o),
|
||||
map(o),
|
||||
activeStatementList(o),
|
||||
inactiveStatementList(o)
|
||||
{
|
||||
const auto dbb = attachment->att_database;
|
||||
maxCacheSize = dbb->dbb_config->getMaxStatementCacheSize();
|
||||
}
|
||||
|
||||
DsqlStatementCache::~DsqlStatementCache()
|
||||
{
|
||||
purge(JRD_get_thread_data());
|
||||
}
|
||||
|
||||
int DsqlStatementCache::blockingAst(void* astObject)
|
||||
{
|
||||
#ifdef DSQL_STATEMENT_CACHE_DEBUG
|
||||
printf("DsqlStatementCache::blockingAst()\n");
|
||||
#endif
|
||||
|
||||
const auto self = static_cast<DsqlStatementCache*>(astObject);
|
||||
|
||||
try
|
||||
{
|
||||
const auto dbb = self->lock->lck_dbb;
|
||||
AsyncContextHolder tdbb(dbb, FB_FUNCTION, self->lock);
|
||||
|
||||
self->purge(tdbb);
|
||||
}
|
||||
catch (const Exception&)
|
||||
{} // no-op
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
RefPtr<DsqlStatement> DsqlStatementCache::getStatement(thread_db* tdbb, const string& text, USHORT clientDialect,
|
||||
bool isInternalRequest)
|
||||
{
|
||||
RefStrPtr key;
|
||||
buildStatementKey(tdbb, key, text, clientDialect, isInternalRequest);
|
||||
|
||||
if (const auto entryPtr = map.get(key))
|
||||
{
|
||||
const auto entry = *entryPtr;
|
||||
auto dsqlStatement(entry->dsqlStatement);
|
||||
|
||||
string verifyKey;
|
||||
buildVerifyKey(tdbb, verifyKey, isInternalRequest);
|
||||
|
||||
FB_SIZE_T verifyPos;
|
||||
if (!entry->verifyCache.find(verifyKey, verifyPos))
|
||||
{
|
||||
dsqlStatement->getStatement()->verifyAccess(tdbb);
|
||||
entry->verifyCache.insert(verifyPos, verifyKey);
|
||||
}
|
||||
|
||||
if (!entry->active)
|
||||
{
|
||||
entry->dsqlStatement->setCacheKey(key);
|
||||
// Active statement has cacheKey and will tell us when it's going to be released.
|
||||
entry->dsqlStatement->release();
|
||||
|
||||
entry->active = true;
|
||||
|
||||
cacheSize -= entry->size;
|
||||
|
||||
activeStatementList.splice(activeStatementList.end(), inactiveStatementList, entry);
|
||||
}
|
||||
|
||||
#ifdef DSQL_STATEMENT_CACHE_DEBUG
|
||||
dump();
|
||||
#endif
|
||||
|
||||
return dsqlStatement;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
void DsqlStatementCache::putStatement(thread_db* tdbb, const string& text, USHORT clientDialect,
|
||||
bool isInternalRequest, RefPtr<DsqlStatement> dsqlStatement)
|
||||
{
|
||||
fb_assert(dsqlStatement->isDml());
|
||||
|
||||
const unsigned statementSize = dsqlStatement->getSize();
|
||||
|
||||
RefStrPtr key;
|
||||
buildStatementKey(tdbb, key, text, clientDialect, isInternalRequest);
|
||||
|
||||
StatementEntry newStatement(getPool());
|
||||
newStatement.key = key;
|
||||
newStatement.size = statementSize;
|
||||
newStatement.dsqlStatement = std::move(dsqlStatement);
|
||||
newStatement.active = true;
|
||||
|
||||
string verifyKey;
|
||||
buildVerifyKey(tdbb, verifyKey, isInternalRequest);
|
||||
newStatement.verifyCache.add(verifyKey);
|
||||
|
||||
newStatement.dsqlStatement->setCacheKey(key);
|
||||
// Active statement has cacheKey and will tell us when it's going to be released.
|
||||
newStatement.dsqlStatement->release();
|
||||
|
||||
activeStatementList.pushBack(std::move(newStatement));
|
||||
map.put(key, --activeStatementList.end());
|
||||
|
||||
if (!lock)
|
||||
{
|
||||
lock = FB_NEW_RPT(getPool(), 0) Lock(tdbb, 0, LCK_dsql_statement_cache, this, blockingAst);
|
||||
LCK_lock(tdbb, lock, LCK_SR, LCK_WAIT);
|
||||
}
|
||||
|
||||
#ifdef DSQL_STATEMENT_CACHE_DEBUG
|
||||
dump();
|
||||
#endif
|
||||
}
|
||||
|
||||
void DsqlStatementCache::statementGoingInactive(Firebird::RefStrPtr& key)
|
||||
{
|
||||
const auto entryPtr = map.get(key);
|
||||
|
||||
if (!entryPtr)
|
||||
{
|
||||
fb_assert(false);
|
||||
return;
|
||||
}
|
||||
|
||||
const auto entry = *entryPtr;
|
||||
|
||||
fb_assert(entry->active);
|
||||
entry->active = false;
|
||||
entry->size = entry->dsqlStatement->getSize(); // update size
|
||||
|
||||
inactiveStatementList.splice(inactiveStatementList.end(), activeStatementList, entry);
|
||||
|
||||
cacheSize += entry->size;
|
||||
|
||||
if (cacheSize > maxCacheSize)
|
||||
shrink();
|
||||
}
|
||||
|
||||
void DsqlStatementCache::purge(thread_db* tdbb)
|
||||
{
|
||||
for (auto& entry : activeStatementList)
|
||||
{
|
||||
entry.dsqlStatement->addRef();
|
||||
entry.dsqlStatement->resetCacheKey();
|
||||
}
|
||||
|
||||
map.clear();
|
||||
activeStatementList.clear();
|
||||
inactiveStatementList.clear();
|
||||
|
||||
cacheSize = 0;
|
||||
|
||||
if (lock)
|
||||
{
|
||||
LCK_release(tdbb, lock);
|
||||
lock.reset();
|
||||
}
|
||||
}
|
||||
|
||||
void DsqlStatementCache::purgeAllAttachments(thread_db* tdbb)
|
||||
{
|
||||
if (lock)
|
||||
LCK_convert(tdbb, lock, LCK_EX, LCK_WAIT);
|
||||
else
|
||||
{
|
||||
lock = FB_NEW_RPT(getPool(), 0) Lock(tdbb, 0, LCK_dsql_statement_cache, this, blockingAst);
|
||||
LCK_lock(tdbb, lock, LCK_EX, LCK_WAIT);
|
||||
}
|
||||
|
||||
purge(tdbb);
|
||||
}
|
||||
|
||||
void DsqlStatementCache::buildStatementKey(thread_db* tdbb, RefStrPtr& key, const string& text, USHORT clientDialect,
|
||||
bool isInternalRequest)
|
||||
{
|
||||
const auto attachment = tdbb->getAttachment();
|
||||
|
||||
const SSHORT charSetId = isInternalRequest ? CS_METADATA : attachment->att_charset;
|
||||
|
||||
key = FB_NEW_POOL(getPool()) RefString(getPool());
|
||||
|
||||
key->resize(1 + sizeof(charSetId) + text.length());
|
||||
char* p = key->begin();
|
||||
*p = (clientDialect << 1) | int(isInternalRequest);
|
||||
memcpy(p + 1, &charSetId, sizeof(charSetId));
|
||||
memcpy(p + 1 + sizeof(charSetId), text.c_str(), text.length());
|
||||
}
|
||||
|
||||
void DsqlStatementCache::buildVerifyKey(thread_db* tdbb, string& key, bool isInternalRequest)
|
||||
{
|
||||
key.clear();
|
||||
|
||||
const auto attachment = tdbb->getAttachment();
|
||||
|
||||
if (isInternalRequest || !attachment->att_user)
|
||||
return;
|
||||
|
||||
const auto& roles = attachment->att_user->getGrantedRoles(tdbb);
|
||||
|
||||
string roleStr;
|
||||
|
||||
for (const auto& role : roles)
|
||||
{
|
||||
roleStr.printf("%d,%s,", int(role.length()), role.c_str());
|
||||
key += roleStr;
|
||||
}
|
||||
}
|
||||
|
||||
void DsqlStatementCache::shrink()
|
||||
{
|
||||
#ifdef DSQL_STATEMENT_CACHE_DEBUG
|
||||
printf("DsqlStatementCache::shrink() - cacheSize: %u, maxCacheSize: %u\n\n", cacheSize, maxCacheSize);
|
||||
#endif
|
||||
|
||||
while (cacheSize > maxCacheSize && !inactiveStatementList.isEmpty())
|
||||
{
|
||||
const auto& front = inactiveStatementList.front();
|
||||
map.remove(front.key);
|
||||
cacheSize -= front.size;
|
||||
inactiveStatementList.erase(inactiveStatementList.begin());
|
||||
}
|
||||
|
||||
#ifdef DSQL_STATEMENT_CACHE_DEBUG
|
||||
dump();
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef DSQL_STATEMENT_CACHE_DEBUG
|
||||
void DsqlStatementCache::dump()
|
||||
{
|
||||
printf("DsqlStatementCache::dump() - cacheSize: %u, maxCacheSize: %u\n\n", cacheSize, maxCacheSize);
|
||||
|
||||
printf("\tactive:\n");
|
||||
|
||||
for (auto& entry : activeStatementList)
|
||||
printf("\t\tsize: %u; text: %s\n", entry.size, entry.dsqlStatement->getSqlText()->c_str());
|
||||
|
||||
printf("\n\tinactive:\n");
|
||||
|
||||
for (auto& entry : inactiveStatementList)
|
||||
printf("\t\tsize: %u; text: %s\n", entry.size, entry.dsqlStatement->getSqlText()->c_str());
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
137
src/dsql/DsqlStatementCache.h
Normal file
137
src/dsql/DsqlStatementCache.h
Normal file
@ -0,0 +1,137 @@
|
||||
/*
|
||||
* 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 Adriano dos Santos Fernandes
|
||||
* for the Firebird Open Source RDBMS project.
|
||||
*
|
||||
* Copyright (c) 2022 Adriano dos Santos Fernandes <adrianosf@gmail.com>
|
||||
* and all contributors signed below.
|
||||
*
|
||||
* All Rights Reserved.
|
||||
* Contributor(s): ______________________________________.
|
||||
*/
|
||||
|
||||
#ifndef DSQL_STATEMENT_CACHE_H
|
||||
#define DSQL_STATEMENT_CACHE_H
|
||||
|
||||
///#define DSQL_STATEMENT_CACHE_DEBUG 1
|
||||
|
||||
#include "../common/classes/alloc.h"
|
||||
#include "../common/classes/DoublyLinkedList.h"
|
||||
#include "../common/classes/fb_string.h"
|
||||
#include "../common/classes/GenericMap.h"
|
||||
#include "../common/classes/objects_array.h"
|
||||
#include "../common/classes/RefCounted.h"
|
||||
|
||||
namespace Jrd {
|
||||
|
||||
|
||||
class Attachment;
|
||||
class DsqlStatement;
|
||||
class Lock;
|
||||
class thread_db;
|
||||
|
||||
|
||||
class DsqlStatementCache final : public Firebird::PermanentStorage
|
||||
{
|
||||
private:
|
||||
struct StatementEntry
|
||||
{
|
||||
explicit StatementEntry(MemoryPool& p)
|
||||
: verifyCache(p)
|
||||
{
|
||||
}
|
||||
|
||||
StatementEntry(MemoryPool& p, StatementEntry&& o)
|
||||
: key(std::move(o.key)),
|
||||
dsqlStatement(std::move(o.dsqlStatement)),
|
||||
verifyCache(p, std::move(o.verifyCache)),
|
||||
size(o.size),
|
||||
active(o.active)
|
||||
{
|
||||
}
|
||||
|
||||
StatementEntry(const StatementEntry&) = delete;
|
||||
StatementEntry& operator=(const StatementEntry&) = delete;
|
||||
|
||||
Firebird::RefStrPtr key;
|
||||
Firebird::RefPtr<DsqlStatement> dsqlStatement;
|
||||
Firebird::SortedObjectsArray<Firebird::string> verifyCache;
|
||||
unsigned size = 0;
|
||||
bool active = true;
|
||||
};
|
||||
|
||||
class RefStrPtrComparator
|
||||
{
|
||||
public:
|
||||
static bool greaterThan(const Firebird::RefStrPtr& i1, const Firebird::RefStrPtr& i2)
|
||||
{
|
||||
return *i1 > *i2;
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
explicit DsqlStatementCache(MemoryPool& o, Attachment* attachment);
|
||||
~DsqlStatementCache();
|
||||
|
||||
DsqlStatementCache(const DsqlStatementCache&) = delete;
|
||||
DsqlStatementCache& operator=(const DsqlStatementCache&) = delete;
|
||||
|
||||
private:
|
||||
static int blockingAst(void* astObject);
|
||||
|
||||
public:
|
||||
bool isActive() const
|
||||
{
|
||||
return maxCacheSize > 0;
|
||||
}
|
||||
|
||||
Firebird::RefPtr<DsqlStatement> getStatement(thread_db* tdbb, const Firebird::string& text,
|
||||
USHORT clientDialect, bool isInternalRequest);
|
||||
|
||||
void putStatement(thread_db* tdbb, const Firebird::string& text, USHORT clientDialect, bool isInternalRequest,
|
||||
Firebird::RefPtr<DsqlStatement> dsqlStatement);
|
||||
|
||||
void statementGoingInactive(Firebird::RefStrPtr& key);
|
||||
|
||||
void purge(thread_db* tdbb);
|
||||
void purgeAllAttachments(thread_db* tdbb);
|
||||
|
||||
private:
|
||||
void buildStatementKey(thread_db* tdbb, Firebird::RefStrPtr& key, const Firebird::string& text,
|
||||
USHORT clientDialect, bool isInternalRequest);
|
||||
|
||||
void buildVerifyKey(thread_db* tdbb, Firebird::string& key, bool isInternalRequest);
|
||||
|
||||
void shrink();
|
||||
|
||||
#ifdef DSQL_STATEMENT_CACHE_DEBUG
|
||||
void dump();
|
||||
#endif
|
||||
|
||||
private:
|
||||
Firebird::NonPooledMap<
|
||||
Firebird::RefStrPtr,
|
||||
Firebird::DoublyLinkedList<StatementEntry>::Iterator,
|
||||
RefStrPtrComparator
|
||||
> map;
|
||||
Firebird::DoublyLinkedList<StatementEntry> activeStatementList;
|
||||
Firebird::DoublyLinkedList<StatementEntry> inactiveStatementList;
|
||||
Firebird::AutoPtr<Lock> lock;
|
||||
unsigned maxCacheSize = 0;
|
||||
unsigned cacheSize = 0;
|
||||
};
|
||||
|
||||
|
||||
} // namespace Jrd
|
||||
|
||||
#endif // DSQL_STATEMENT_CACHE_H
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user