mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-22 20:43:02 +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 }}
|
runs-on: ${{ matrix.os }}
|
||||||
container: ${{ matrix.container }}
|
container: ${{ matrix.container }}
|
||||||
env:
|
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:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os:
|
os:
|
||||||
- windows-2016
|
|
||||||
- windows-2019
|
- windows-2019
|
||||||
platform: [x64, x86]
|
platform: [x64, x86]
|
||||||
include:
|
include:
|
||||||
|
@ -155,7 +155,6 @@ endif()
|
|||||||
set(FB_PREFIX ${CMAKE_INSTALL_PREFIX}/${PROJECT_NAME})
|
set(FB_PREFIX ${CMAKE_INSTALL_PREFIX}/${PROJECT_NAME})
|
||||||
set(FB_IPC_NAME "FirebirdIPI")
|
set(FB_IPC_NAME "FirebirdIPI")
|
||||||
set(FB_LOGFILENAME "firebird.log")
|
set(FB_LOGFILENAME "firebird.log")
|
||||||
set(FB_PIPE_NAME "interbas")
|
|
||||||
set(FB_SERVICE_NAME "gds_db")
|
set(FB_SERVICE_NAME "gds_db")
|
||||||
set(FB_SERVICE_PORT 3050)
|
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("ISQL files\\${GEN_TXT}" "${BSRC}/isql/${GEN}")
|
||||||
source_group("JRD files" "${SSRC}/jrd/${CPP}")
|
source_group("JRD files" "${SSRC}/jrd/${CPP}")
|
||||||
source_group("JRD files\\Data Access" "${SSRC}/jrd/recsrc/${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\\EXTDS" "${SSRC}/jrd/extds/${CPP}")
|
||||||
source_group("JRD files\\${EPP_TXT}" "${SSRC}/jrd/${EPP}")
|
source_group("JRD files\\${EPP_TXT}" "${SSRC}/jrd/${EPP}")
|
||||||
source_group("JRD files\\${GEN_TXT}" "${BSRC}/jrd/${GEN}")
|
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
|
#endif
|
||||||
|
|
||||||
;Only register Firebird if we are installing AND configuring
|
;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 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
|
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;
|
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
|
;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.
|
;Clean up Invalid registry entries from previous installs.
|
||||||
Root: HKLM; Subkey: "SOFTWARE\FirebirdSQL"; ValueType: none; Flags: deletekey;
|
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}\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}\ib_util.dll; DestDir: {app}; Components: ServerComponent; Flags: sharedfile ignoreversion
|
||||||
Source: {#FilesDir}\instclient.exe; DestDir: {app}; Components: ClientComponent; 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}\instsvc.exe; DestDir: {app}; Components: ServerComponent; MinVersion: {#MinVer}; Flags: sharedfile ignoreversion
|
||||||
Source: {#FilesDir}\isql.exe; DestDir: {app}; Components: DevAdminComponent; Flags: ignoreversion
|
Source: {#FilesDir}\isql.exe; DestDir: {app}; Components: DevAdminComponent; Flags: ignoreversion
|
||||||
Source: {#FilesDir}\nbackup.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}\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}
|
Source: {#WOW64Dir}\instclient.exe; DestDir: {app}\WOW64; Components: ClientComponent; Flags: sharedfile ignoreversion {#SkipFileIfDevStatus}
|
||||||
#endif
|
#endif
|
||||||
Source: {#FilesDir}\icuuc??.dll; 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: ServerComponent; Flags: sharedfile ignoreversion
|
Source: {#FilesDir}\icuin??.dll; DestDir: {app}; Components: ClientComponent; Flags: sharedfile ignoreversion
|
||||||
Source: {#FilesDir}\icudt??.dll; DestDir: {app}; Components: ServerComponent; Flags: sharedfile ignoreversion
|
Source: {#FilesDir}\icudt??.dll; DestDir: {app}; Components: ClientComponent; Flags: sharedfile ignoreversion
|
||||||
Source: {#FilesDir}\icudt*.dat; DestDir: {app}; Components: ServerComponent; 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"
|
#if PlatformTarget =="Win32"
|
||||||
Source: {#FilesDir}\fbrmclib.dll; DestDir: {app}; Components: ServerComponent; Flags: sharedfile ignoreversion
|
Source: {#FilesDir}\fbrmclib.dll; DestDir: {app}; Components: ServerComponent; Flags: sharedfile ignoreversion
|
||||||
#endif
|
#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
|
;Rules for installation of MS runtimes are simplified with MSVC10
|
||||||
;We just install the runtimes into the install dir.
|
;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}\UDF\*.txt; DestDir: {app}\UDF; Components: ServerComponent; Flags: ignoreversion;
|
||||||
|
|
||||||
Source: {#FilesDir}\plugins.conf; DestDir: {app}; 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\*.conf; DestDir: {app}\plugins; Components: ServerComponent; Flags: ignoreversion;
|
||||||
Source: {#FilesDir}\plugins\udr\*.*; DestDir: {app}\plugins\udr; 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 ;
|
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 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
|
Filename: {app}\wow64\instclient.exe; Parameters: " remove fbclient"; StatusMsg: {cm:instclientDecLibCountFbClient}; MinVersion: {#MinVer}; Flags: runminimized 32bit; RunOnceId: RemoveFbClientx86
|
||||||
#endif
|
#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]
|
[UninstallDelete]
|
||||||
Type: files; Name: "{app}\*.lck"
|
Type: files; Name: "{app}\*.lck"
|
||||||
|
@ -890,9 +890,40 @@ begin
|
|||||||
end;
|
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;
|
function ConfigureFirebird: boolean;
|
||||||
begin
|
begin
|
||||||
result := (InstallAndConfigure AND Configure) = Configure;
|
if IsNotServerInstall then
|
||||||
|
Result := False
|
||||||
|
else
|
||||||
|
Result := (InstallAndConfigure AND Configure) = Configure;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
|
|
||||||
|
|
||||||
Firebird Binary Installer Test Harness HELP (Designed with TABS=4 and console width=120)
|
Firebird Binary Installer Test Harness HELP (Designed with TABS=4 and console width=120)
|
||||||
|
|
||||||
fbit {PARAM [...]]
|
fbit {PARAM [...]]
|
||||||
@ -11,15 +9,22 @@
|
|||||||
will clean up from previous broken installs. CLEAN must the first parameter
|
will clean up from previous broken installs. CLEAN must the first parameter
|
||||||
and subsequent parameters are ignored. Note: - It will run silently.
|
and subsequent parameters are ignored. Note: - It will run silently.
|
||||||
|
|
||||||
|
|
||||||
By default fbit installs Firebird according to the parameters passed and then
|
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.
|
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
|
FBIT Specific Parameters
|
||||||
========================
|
========================
|
||||||
Param Name Value Passed Comment
|
Param Name Value Passed to fbit Comment
|
||||||
---------- ------------ -------
|
---------- -------------------- -------
|
||||||
HELP - Displays this screen
|
HELP - Displays this screen
|
||||||
DRYRUN - Show what will be done. No changes are made
|
DRYRUN - Show what will be done. No changes are made
|
||||||
NOARCHIVE - Disables copying of install dir to %USERPROFILE%\fbit
|
NOARCHIVE - Disables copying of install dir to %USERPROFILE%\fbit
|
||||||
@ -28,61 +33,74 @@
|
|||||||
SCRIPTED - Sets VERYSILENT, SP and NOMSG
|
SCRIPTED - Sets VERYSILENT, SP and NOMSG
|
||||||
TESTNAME NameOfTestRun Optional. No spaces allowed. Used for storing test run details.
|
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.
|
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
|
INTERACTIVE True SCRIPTED
|
||||||
INSTALLTYPE ServerInstall CLIENT or DEVINST
|
INSTALLTYPE ServerInstall CLIENT or DEVINST
|
||||||
SERVICE_TASK True APPTASK
|
SERVICE_TASK True APPTASK
|
||||||
SUPERSERVER True CLASSICSERVER or SUPERCLASSIC
|
SUPERSERVER True CLASSICSERVER or SUPERCLASSIC
|
||||||
|
|
||||||
|
|
||||||
Firebird Installer specific Parameters
|
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
|
COPYGDSLIB CopyFbClientAsGds32Task Copy fbclient to <SYS> and rename to gds32
|
||||||
FORCE FORCE Force installation
|
FORCE FORCE Force installation
|
||||||
NOAUTOSTART NULL Does not set AutoStartTask
|
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
|
PASSWORD /SYSDBAPASSWORD=%ISC_PASSWORD% Changes SYSDBA password from masterkey
|
||||||
See :SET_GLOBAL_ENV
|
See :SET_GLOBAL_ENV
|
||||||
|
|
||||||
Installation Tasks
|
Installation Tasks
|
||||||
==================
|
==================
|
||||||
Param Name Value passed Comment
|
Param Name Value passed to /TASKS Comment
|
||||||
------------- ------------ ---------------
|
------------- ---------------------- ---------------
|
||||||
APPTASK UseApplicationTask Will not install as a service
|
APPTASK UseApplicationTask Will not install as a service
|
||||||
CLASSICSERVER UseClassicServerTask Will configure classic server
|
CLASSICSERVER UseClassicServerTask Will configure classic server
|
||||||
SUPERCLASSIC UseSuperClassicTask Will configure super classic
|
SUPERCLASSIC UseSuperClassicTask Will configure super classic
|
||||||
|
|
||||||
|
|
||||||
Installation Types
|
Installation Types
|
||||||
==================
|
==================
|
||||||
Param Name Value passed Comment
|
Param Name Value passed to /TYPE Comment
|
||||||
------------ ------------ -------
|
------------ --------------------- -------
|
||||||
CLIENT ClientInstall Minimal working client install
|
CLIENT ClientInstall Minimal working client install
|
||||||
DEVINST DeveloperInstall Everything but the server.
|
DEVINST DeveloperInstall Everything but the server.
|
||||||
|
SERVER_INSTALL ServerInstall
|
||||||
|
|
||||||
Uninstallation
|
Uninstallation
|
||||||
==============
|
==============
|
||||||
Param Name Value passed Comment
|
Param Name Value passed to uninstaller Comment
|
||||||
-------------- ------------ -------
|
-------------- --------------------------- -------
|
||||||
CLEAN CLEAN Completely remove the firebird install
|
CLEAN CLEAN Completely remove the firebird install
|
||||||
Reset list of shared dll's in the registry
|
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
|
Generic InnoSetup parameters
|
||||||
============================
|
============================
|
||||||
Param Name Value passed Comment
|
Param Name Value passed to installer Comment
|
||||||
---------- ------------ -------
|
---------- ------------------------- -------
|
||||||
NOMSG SUPPRESSMSGBOXES Suppress message boxes
|
NOMSG SUPPRESSMSGBOXES Suppress message boxes
|
||||||
NOCANCEL NOCANCEL Prevents user cancelling install
|
NOCANCEL NOCANCEL Prevents user cancelling install
|
||||||
SILENT SILENT
|
SILENT SILENT
|
||||||
SP SP- Disables the This will install... prompt
|
SP SP- Disables the This will install... prompt
|
||||||
VERYSILENT VERYSILENT
|
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 ----------------------------------------
|
-------------------------- End of Fbit Help Screen ----------------------------------------
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
:: scripted install of Firebird. It is designed to test almost all possible
|
:: scripted install of Firebird. It is designed to test almost all possible
|
||||||
:: scriptable combinations and is thus far more complicated than a typical
|
:: 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
|
:: 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.
|
:: log of the install run.
|
||||||
|
|
||||||
@goto :MAIN %*
|
@goto :MAIN %*
|
||||||
@ -27,26 +27,32 @@
|
|||||||
::=======================================================
|
::=======================================================
|
||||||
:SET_GLOBAL_ENV
|
:SET_GLOBAL_ENV
|
||||||
@call :SET_VERBOSE_IF_DEBUG_ON
|
@call :SET_VERBOSE_IF_DEBUG_ON
|
||||||
|
::@call :SET_VERBOSE
|
||||||
@if defined DEBUG @echo Entering %0
|
@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...
|
:: Set this to the location of the firebird installer you want to test.
|
||||||
if not defined FBINST_EXEC (
|
::@set FBINST_EXEC=%USERPROFILE%\Desktop\Firebird-5.0.0.0000_x64.exe
|
||||||
rem - if we have just built firebird we can test the install immediately
|
|
||||||
if defined FBBUILD_FILE_ID (
|
:: if we have just built firebird we can test the install immediately
|
||||||
|
if defined FBBUILD_FILE_ID (
|
||||||
if defined FBBUILD_FILENAME_SUFFIX (
|
if defined FBBUILD_FILENAME_SUFFIX (
|
||||||
@set FBINST_EXEC=%FBBUILD_INSTALL_IMAGES%\Firebird-%FBBUILD_FILE_ID%%FBBUILD_FILENAME_SUFFIX%.exe
|
@set FBINST_EXEC=%FBBUILD_INSTALL_IMAGES%\Firebird-%FBBUILD_FILE_ID%%FBBUILD_FILENAME_SUFFIX%.exe
|
||||||
) else (
|
) else (
|
||||||
@set FBINST_EXEC=%FBBUILD_INSTALL_IMAGES%\Firebird-%FBBUILD_FILE_ID%.exe
|
@set FBINST_EXEC=%FBBUILD_INSTALL_IMAGES%\Firebird-%FBBUILD_FILE_ID%.exe
|
||||||
)
|
)
|
||||||
)
|
|
||||||
) else (
|
) 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.
|
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.
|
:: 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
|
:: It is possible that successive installs into the same directory may
|
||||||
:: generate different uninstallers but for now we hard code the default.
|
:: generate different uninstallers but for now we hard code the default.
|
||||||
@ -73,14 +79,16 @@ if not defined FBINST_EXEC (
|
|||||||
:: to read.
|
:: to read.
|
||||||
@set SHOW_FINAL_CMD=
|
@set SHOW_FINAL_CMD=
|
||||||
|
|
||||||
:: change as reqd, or comment out if ISC_PASSWORD is already set in your env
|
:: change as reqd
|
||||||
@set ISC_PASSWORD="secret"
|
@if not defined ISC_PASSWORD (
|
||||||
|
@set ISC_PASSWORD="secret"
|
||||||
|
)
|
||||||
|
|
||||||
@set TAB= &
|
@set TAB= &
|
||||||
|
|
||||||
@if not defined DRYRUN (
|
@if not defined DRYRUN (
|
||||||
if not exist %FBINSTALLLOGDIR% @mkdir %FBINSTALLLOGDIR% >nul 2>nul
|
if not exist %FBINSTALLLOGDIR% ( @mkdir %FBINSTALLLOGDIR% >nul 2>nul )
|
||||||
if not exist %FBINSTALLCOPYDIR% @mkdir %FBINSTALLCOPYDIR% >nul 2>nul
|
if not exist %FBINSTALLCOPYDIR% ( @mkdir %FBINSTALLCOPYDIR% >nul 2>nul )
|
||||||
)
|
)
|
||||||
|
|
||||||
@if defined DEBUG @echo Leaving %0
|
@if defined DEBUG @echo Leaving %0
|
||||||
@ -92,7 +100,8 @@ if not defined FBINST_EXEC (
|
|||||||
::=======================================================
|
::=======================================================
|
||||||
:GET_OPTS
|
:GET_OPTS
|
||||||
@call :SET_VERBOSE_IF_DEBUG_ON
|
@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
|
:: Automatically parse the commandline and place all valid options into ENV VARS
|
||||||
:: Courtesy of this link:
|
:: Courtesy of this link:
|
||||||
@ -111,22 +120,22 @@ if defined DEBUG @echo Entering %0
|
|||||||
:: will end up as
|
:: will end up as
|
||||||
:: flagwithdefault=flag
|
:: flagwithdefault=flag
|
||||||
:: Basically all this means that these variables should not be passed to runtime:
|
:: 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"
|
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
|
@if defined VERBOSE @echo on
|
||||||
for %%O in (%options%) do (
|
for %%O in (%options%) do (
|
||||||
for /f "tokens=1,* delims=:" %%A in ("%%O") do (
|
for /f "tokens=1,* delims=:" %%A in ("%%O") do (
|
||||||
set "%%A=%%~B"
|
set "%%A=%%~B"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
if defined VERBOSE (
|
@if defined VERBOSE (
|
||||||
call :PRINT_VARS
|
@call :PRINT_VARS
|
||||||
if NOT defined DEBUG pause
|
if NOT defined DEBUG pause
|
||||||
)
|
)
|
||||||
|
|
||||||
:loop
|
:loop
|
||||||
if not "%~1"=="" (
|
@if not "%~1"=="" (
|
||||||
set "test=!options:*%~1:=! "
|
set "test=!options:*%~1:=! "
|
||||||
if "!test!"=="!options! " (
|
if "!test!"=="!options! " (
|
||||||
echo Error: Invalid option %~1
|
echo Error: Invalid option %~1
|
||||||
@ -144,7 +153,8 @@ if not "%~1"=="" (
|
|||||||
goto :loop
|
goto :loop
|
||||||
)
|
)
|
||||||
|
|
||||||
if defined DEBUG @echo Leaving %0
|
@if defined VERBOSE ( @call :PRINT_VARS )
|
||||||
|
@if defined DEBUG @echo Leaving %0
|
||||||
@call :UNSET_VERBOSE
|
@call :UNSET_VERBOSE
|
||||||
@goto :EOF
|
@goto :EOF
|
||||||
::=======================================================
|
::=======================================================
|
||||||
@ -198,46 +208,100 @@ rem We now have everything we need for uninstall so jump to the end
|
|||||||
goto :SET_CMD_PARAMS
|
goto :SET_CMD_PARAMS
|
||||||
)
|
)
|
||||||
|
|
||||||
:: Fix up any incompatible assignments
|
:: Fix up any incompatible assignments :::::::::::::::::::::::::::::::::::::::::
|
||||||
|
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||||
|
|
||||||
@if defined CLASSICSERVER ( set SUPERSERVER=& set SUPERCLASSIC=)
|
@if defined CLIENT (
|
||||||
@if defined SUPERCLASSIC ( set SUPERSERVER=& set CLASSICSERVER=)
|
set INSTALLTYPE=ClientInstall
|
||||||
:: Theoretically this next line is redundant
|
set DEVINST=
|
||||||
@if defined SUPERSERVER ( set SUPERCLASSIC=& set CLASSICSERVER=)
|
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
|
:: 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
|
:: Now build our task list
|
||||||
|
|
||||||
@if defined CLASSICSERVER ( set TASK_LIST=UseClassicServerTask)
|
:: At this stage, if TASK_LIST is not defined then we are not doing a server install
|
||||||
@if defined SUPERCLASSIC ( set TASK_LIST=UseSuperClassicTask)
|
@if defined TASK_LIST (
|
||||||
:: Theoretically this next line is redundant
|
if defined APPTASK (
|
||||||
@if defined SUPERSERVER ( set TASK_LIST=UseSuperServerTask)
|
|
||||||
|
|
||||||
@if defined APPTASK (
|
|
||||||
set TASK_LIST=!TASK_LIST!,UseApplicationTask
|
set TASK_LIST=!TASK_LIST!,UseApplicationTask
|
||||||
) else (
|
set INSTALLTYPE=CustomInstall
|
||||||
|
) else (
|
||||||
set TASK_LIST=!TASK_LIST!,UseServiceTask
|
set TASK_LIST=!TASK_LIST!,UseServiceTask
|
||||||
)
|
)
|
||||||
|
|
||||||
@if NOT defined NOAUTOSTART (
|
if NOT defined NOAUTOSTART (
|
||||||
set TASK_LIST=!TASK_LIST!,AutoStartTask
|
set TASK_LIST=!TASK_LIST!,AutoStartTask
|
||||||
set INSTALLTYPE=CustomInstall
|
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 TASK_LIST=!TASK_LIST!,CopyFbClientToSysTask
|
||||||
|
)
|
||||||
set INSTALLTYPE=CustomInstall
|
set INSTALLTYPE=CustomInstall
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@if defined COPYGDSLIB (
|
@if defined COPYGDSLIB (
|
||||||
|
if not defined TASK_LIST (
|
||||||
|
set TASK_LIST=CopyFbClientAsGds32Task
|
||||||
|
) else (
|
||||||
set TASK_LIST=!TASK_LIST!,CopyFbClientAsGds32Task
|
set TASK_LIST=!TASK_LIST!,CopyFbClientAsGds32Task
|
||||||
|
)
|
||||||
set INSTALLTYPE=CustomInstall
|
set INSTALLTYPE=CustomInstall
|
||||||
)
|
)
|
||||||
|
@call :PRINT_VARS In %0 - End of set TASK_LIST
|
||||||
|
|
||||||
|
|
||||||
:SET_CMD_PARAMS
|
:SET_CMD_PARAMS
|
||||||
:: set up the CMD_PARAMS variable we will use
|
:: 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
|
:: Setting PASSWORD is only relevant for a server install
|
||||||
@if defined PASSWORD (
|
@if defined PASSWORD (
|
||||||
@if defined SERVER (
|
if defined SERVER_INSTALL (
|
||||||
set SYSDBAPASSWORD=%ISC_PASSWORD%
|
set SYSDBAPASSWORD=%ISC_PASSWORD%
|
||||||
set CMD_PARAMS=!CMD_PARAMS! /SYSDBAPASSWORD=%SYSDBAPASSWORD%
|
set CMD_PARAMS=!CMD_PARAMS! /SYSDBAPASSWORD=%SYSDBAPASSWORD%
|
||||||
set INSTALLTYPE=CustomInstall
|
set INSTALLTYPE=CustomInstall
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
if defined NOMSG set CMD_PARAMS=!CMD_PARAMS! /SUPPRESSMSGBOXES
|
@if defined NOMSG set CMD_PARAMS=!CMD_PARAMS! /SUPPRESSMSGBOXES
|
||||||
if defined SILENT set CMD_PARAMS=!CMD_PARAMS! /SILENT
|
@if defined SILENT set CMD_PARAMS=!CMD_PARAMS! /SILENT
|
||||||
if defined SP set CMD_PARAMS=!CMD_PARAMS! /SP-
|
@if defined SP set CMD_PARAMS=!CMD_PARAMS! /SP-
|
||||||
if defined VERYSILENT set CMD_PARAMS=!CMD_PARAMS! /VERYSILENT
|
@if defined VERYSILENT set CMD_PARAMS=!CMD_PARAMS! /VERYSILENT
|
||||||
|
|
||||||
:: Setting CustomInstall clears the default COMPONENTS list so we
|
:: Setting CustomInstall clears the default COMPONENTS list so we
|
||||||
:: must define it manually
|
:: must define it manually
|
||||||
@if /I %INSTALLTYPE% == "CustomInstall" (
|
::echo INSTALLTYPE %INSTALLTYPE%
|
||||||
@if defined CLIENT ( set COMPONENTS=ClientComponent)
|
@if /I "%INSTALLTYPE%" == "CustomInstall" (
|
||||||
@if defined DEVINST ( set COMPONENTS=DevAdminComponent,ClientComponent)
|
if defined CLIENT ( set COMPONENTS=ClientComponent)
|
||||||
|
if defined DEVINST ( set COMPONENTS=DevAdminComponent,ClientComponent)
|
||||||
|
if defined SERVER_INSTALL ( set COMPONENTS=ServerComponent,DevAdminComponent,ClientComponent)
|
||||||
) else (
|
) else (
|
||||||
set COMPONENTS=ServerComponent,DevAdminComponent,ClientComponent
|
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!
|
set FULL_CMD=/TYPE=!INSTALLTYPE! /TASKS="!TASK_LIST!" /COMPONENTS="!COMPONENTS!" !CMD_PARAMS!
|
||||||
|
) else (
|
||||||
|
set FULL_CMD=/TYPE=!INSTALLTYPE! /COMPONENTS="!COMPONENTS!" !CMD_PARAMS!
|
||||||
|
)
|
||||||
) else (
|
) else (
|
||||||
set FULL_CMD=!CMD_PARAMS!
|
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
|
@if defined DEBUG @echo Leaving %0
|
||||||
@call :UNSET_VERBOSE
|
@call :UNSET_VERBOSE
|
||||||
@goto :EOF
|
@goto :EOF
|
||||||
@ -288,8 +355,10 @@ if defined INSTALL (
|
|||||||
:PRINT_VARS
|
:PRINT_VARS
|
||||||
:: if a variable is not defined we don't print it, except for critical
|
:: if a variable is not defined we don't print it, except for critical
|
||||||
:: variables such as FINALCMD that MUST be defined.
|
:: 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:
|
@echo Variables set during script execution are:
|
||||||
@set ADIRNAME
|
@set ADIRNAME 2>nul
|
||||||
@set APPTASK 2>nul
|
@set APPTASK 2>nul
|
||||||
@set CLASSICSERVER 2>nul
|
@set CLASSICSERVER 2>nul
|
||||||
@set CLEAN 2>nul
|
@set CLEAN 2>nul
|
||||||
@ -299,12 +368,15 @@ if defined INSTALL (
|
|||||||
@set COPYGDSLIB 2>nul
|
@set COPYGDSLIB 2>nul
|
||||||
@set DEVINST 2>nul
|
@set DEVINST 2>nul
|
||||||
@set DRYRUN 2>nul
|
@set DRYRUN 2>nul
|
||||||
@set FBINST_EXEC
|
@set FBINST_EXEC 2>nul
|
||||||
|
@set FIREBIRD 2>nul
|
||||||
@set FINALCMD 2>nul
|
@set FINALCMD 2>nul
|
||||||
@set FULL_CMD
|
@set FULL_CMD 2>nul
|
||||||
@set FORCE 2>nul
|
@set FORCE 2>nul
|
||||||
@set INTERACTIVE 2>nul
|
@set INTERACTIVE 2>nul
|
||||||
@set INSTALL 2>nul
|
@set INSTALL 2>nul
|
||||||
|
@set ISC_USER 2>nul
|
||||||
|
@set ISC_PASSWORD 2>nul
|
||||||
@set MERGE_TASKS 2>nul
|
@set MERGE_TASKS 2>nul
|
||||||
@set NOARCHIVE= 2>nul
|
@set NOARCHIVE= 2>nul
|
||||||
@set NOAUTOSTART 2>nul
|
@set NOAUTOSTART 2>nul
|
||||||
@ -315,8 +387,7 @@ if defined INSTALL (
|
|||||||
@set PASSWORD 2>nul
|
@set PASSWORD 2>nul
|
||||||
@set RUN_TIMESTAMP 2>nul
|
@set RUN_TIMESTAMP 2>nul
|
||||||
@set SCRIPTED 2>nul
|
@set SCRIPTED 2>nul
|
||||||
@set SERVICE_TASK 2>nul
|
@set SERVER_INSTALL 2>nul
|
||||||
@set SERVER 2>nul
|
|
||||||
@set SERVICE_TASK 2>nul
|
@set SERVICE_TASK 2>nul
|
||||||
@set SILENT 2>nul
|
@set SILENT 2>nul
|
||||||
@set SP 2>nul
|
@set SP 2>nul
|
||||||
@ -327,7 +398,7 @@ if defined INSTALL (
|
|||||||
@set UNINSTALL 2>nul
|
@set UNINSTALL 2>nul
|
||||||
@set VERYSILENT 2>nul
|
@set VERYSILENT 2>nul
|
||||||
@echo.
|
@echo.
|
||||||
|
@if NOT defined DEBUG pause
|
||||||
@goto :EOF
|
@goto :EOF
|
||||||
::=======================================================
|
::=======================================================
|
||||||
|
|
||||||
@ -336,56 +407,65 @@ if defined INSTALL (
|
|||||||
@echo.
|
@echo.
|
||||||
@echo.
|
@echo.
|
||||||
@call :SET_VERBOSE_IF_DEBUG_ON
|
@call :SET_VERBOSE_IF_DEBUG_ON
|
||||||
if defined DEBUG @echo Entering %0 %*
|
@if defined DEBUG @echo Entering %~0 %*
|
||||||
::@call :CHECK_ENV || (@echo Check the values in SET_ENV & goto :EOF )
|
|
||||||
@call :CHECK_ENV
|
@call :CHECK_ENV
|
||||||
::@call :RESET_INSTALL_ENV
|
@if defined _err ( goto :EOF)
|
||||||
|
|
||||||
@call :GET_OPTS %*
|
@call :GET_OPTS %*
|
||||||
@call :SET_PARAMS %*
|
@call :SET_PARAMS %*
|
||||||
::@call :SET_VERBOSE
|
::@call :SET_VERBOSE
|
||||||
@if defined VERBOSE @echo on
|
|
||||||
@if defined VERBOSE @echo FULL_CMD is %FULL_CMD%
|
@if defined VERBOSE @echo FULL_CMD is %FULL_CMD%
|
||||||
@if defined VERBOSE ( if NOT defined DEBUG pause )
|
@if defined VERBOSE ( if NOT defined DEBUG pause )
|
||||||
@call :TIMESTAMP
|
@call :TIMESTAMP
|
||||||
|
@if defined DEBUG echo After call TIMESTAMP
|
||||||
@set RUN_TIMESTAMP=%TIMESTAMP%
|
@set RUN_TIMESTAMP=%TIMESTAMP%
|
||||||
@set INSTALL_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%
|
@echo DRYRUN - Not executing call %FINALCMD%
|
||||||
) else (
|
) else (
|
||||||
@if defined SHOW_FINAL_CMD @echo Executing %FINALCMD%
|
@if defined DEBUG @echo DRYRUN not set
|
||||||
call %FINALCMD%
|
@if defined SHOW_FINAL_CMD (@echo Executing %FINALCMD%)
|
||||||
|
@call %FINALCMD%
|
||||||
|
|
||||||
@if errorlevel 1 (
|
@if ERRORLEVEL 1 (
|
||||||
rem @echo Calling %FBINST_EXEC% failed with %ERRORLEVEL%
|
rem @echo Calling %FBINST_EXEC% failed with %ERRORLEVEL%
|
||||||
set _err=%ERRORLEVEL%
|
set _err=%ERRORLEVEL%
|
||||||
call :ISS_ERROR %_err% %FBINST_EXEC% %FULL_CMD%
|
@call :ISS_ERROR %_err% %FBINST_EXEC% %FULL_CMD%
|
||||||
set /A XRESULT+=1
|
set /A XRESULT+=1
|
||||||
|
@goto :EOF
|
||||||
) else (
|
) else (
|
||||||
@echo Calling %FBINST_EXEC%......................SUCCESS!
|
@echo Calling %FBINST_EXEC%......................SUCCESS!
|
||||||
)
|
)
|
||||||
|
|
||||||
@echo.
|
@echo.
|
||||||
@echo Now checking system state...
|
@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
|
call :CHECKFILEEXISTS c:\windows\system32\fbclient.dll good bad err_is_fail
|
||||||
) else (
|
) else (
|
||||||
call :CHECKFILEEXISTS c:\windows\system32\fbclient.dll bad good no_err_is_fail
|
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
|
call :CHECKFILEEXISTS c:\windows\system32\gds32.dll bad good no_err_is_fail
|
||||||
) else (
|
) else (
|
||||||
call :CHECKFILEEXISTS c:\windows\system32\gds32.dll good bad err_is_fail
|
call :CHECKFILEEXISTS c:\windows\system32\gds32.dll good bad err_is_fail
|
||||||
)
|
)
|
||||||
@echo.
|
@echo Calling COPY_INSTALL
|
||||||
@call :COPY_INSTALL
|
@call :COPY_INSTALL
|
||||||
@echo.
|
@echo.
|
||||||
)
|
)
|
||||||
@echo.
|
@echo.
|
||||||
@echo %0 completed with %XRESULT% errors
|
@echo %0 completed with %XRESULT% errors
|
||||||
@set XRESULT=0
|
@set XRESULT=0
|
||||||
|
|
||||||
@if defined DEBUG @echo Leaving %0
|
@if defined DEBUG @echo Leaving %0
|
||||||
@call :UNSET_VERBOSE
|
@call :UNSET_VERBOSE
|
||||||
@echo.
|
@echo.
|
||||||
@ -401,12 +481,14 @@ if defined DRYRUN (
|
|||||||
@call :SET_VERBOSE_IF_DEBUG_ON
|
@call :SET_VERBOSE_IF_DEBUG_ON
|
||||||
::@call :SET_VERBOSE
|
::@call :SET_VERBOSE
|
||||||
@if defined DEBUG @echo Entering %0 %*
|
@if defined DEBUG @echo Entering %0 %*
|
||||||
|
@if defined NOUNINSTALL ( echo NOUNINSTALL set. Not running uninstaller & exit /b 1)
|
||||||
|
|
||||||
::@call :RESET_INSTALL_ENV
|
::@call :RESET_INSTALL_ENV
|
||||||
@call :GET_OPTS %* UNINSTALL
|
@call :GET_OPTS %* UNINSTALL
|
||||||
@call :SET_PARAMS
|
@call :SET_PARAMS
|
||||||
::@call :SET_VERBOSE
|
::@call :SET_VERBOSE
|
||||||
@if defined VERBOSE @echo on
|
@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 VERBOSE @echo FULL_CMD is %FULL_CMD%
|
||||||
@if defined NOUNINSTALL (
|
@if defined NOUNINSTALL (
|
||||||
@echo NOUNINSTALL was passed. Exiting %0.
|
@echo NOUNINSTALL was passed. Exiting %0.
|
||||||
@ -418,14 +500,14 @@ if defined DRYRUN (
|
|||||||
@if defined VERBOSE ( if NOT defined DEBUG (pause) )
|
@if defined VERBOSE ( if NOT defined DEBUG (pause) )
|
||||||
@if defined DRYRUN (
|
@if defined DRYRUN (
|
||||||
echo DRYRUN - Not executing call %FINALCMD%
|
echo DRYRUN - Not executing call %FINALCMD%
|
||||||
if defined DEBUG @echo Leaving %0
|
@if defined DEBUG @echo Leaving %0
|
||||||
@call :UNSET_VERBOSE
|
@call :UNSET_VERBOSE
|
||||||
@echo.
|
@echo.
|
||||||
@echo.
|
@echo.
|
||||||
goto :EOF
|
goto :EOF
|
||||||
)
|
)
|
||||||
@if defined SHOW_FINAL_CMD @echo Executing %FINALCMD%
|
@if defined SHOW_FINAL_CMD @echo Executing %FINALCMD%
|
||||||
call %FINALCMD% 2>nul
|
@call %FINALCMD% 2>nul
|
||||||
if errorlevel 1 (
|
if errorlevel 1 (
|
||||||
set _err=%ERRORLEVEL%
|
set _err=%ERRORLEVEL%
|
||||||
) else (
|
) else (
|
||||||
@ -433,7 +515,7 @@ if defined DRYRUN (
|
|||||||
)
|
)
|
||||||
if %_err% GEQ 1 (
|
if %_err% GEQ 1 (
|
||||||
set _err=%ERRORLEVEL%
|
set _err=%ERRORLEVEL%
|
||||||
call :ISS_ERROR %_err% %UNINSTALLEXE% %FULL_CMD%
|
@call :ISS_ERROR %_err% %UNINSTALLEXE% %FULL_CMD%
|
||||||
set /A XRESULT+=1
|
set /A XRESULT+=1
|
||||||
) else (
|
) else (
|
||||||
echo Calling %FIREBIRD%\%UNINSTALLEXE% ................SUCCESS!
|
echo Calling %FIREBIRD%\%UNINSTALLEXE% ................SUCCESS!
|
||||||
@ -452,23 +534,23 @@ if defined DRYRUN (
|
|||||||
|
|
||||||
echo.
|
echo.
|
||||||
echo Now checking system state...
|
echo Now checking system state...
|
||||||
call :CHECKFILEEXISTS c:\windows\system32\fbclient.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
|
@call :CHECKFILEEXISTS c:\windows\system32\gds32.dll bad good no_err_is_fail
|
||||||
|
|
||||||
if defined CLEAN (
|
if defined CLEAN (
|
||||||
call :CHECKSHAREDDLLS
|
@call :CHECKSHAREDDLLS
|
||||||
call :CHECKFILEEXISTS %FIREBIRD% bad good no_err_is_fail
|
@call :CHECKFILEEXISTS %FIREBIRD% bad good no_err_is_fail
|
||||||
)
|
)
|
||||||
echo.
|
echo.
|
||||||
call :COPY_INSTALL
|
@call :COPY_INSTALL
|
||||||
echo.
|
echo.
|
||||||
)
|
)
|
||||||
echo.
|
echo.
|
||||||
|
|
||||||
echo %0 completed with %XRESULT% errors
|
echo %0 completed with %XRESULT% errors
|
||||||
set XRESULT=0
|
set XRESULT=0
|
||||||
if defined DEBUG @echo Leaving %0
|
@if defined DEBUG @echo Leaving %0
|
||||||
call :UNSET_VERBOSE
|
@call :UNSET_VERBOSE
|
||||||
@echo.
|
@echo.
|
||||||
@echo.
|
@echo.
|
||||||
@goto :EOF
|
@goto :EOF
|
||||||
@ -477,7 +559,7 @@ call :UNSET_VERBOSE
|
|||||||
|
|
||||||
::=====================================
|
::=====================================
|
||||||
:CHECKFILEEXISTS
|
:CHECKFILEEXISTS
|
||||||
if defined DEBUG @echo Entering %0
|
@if defined DEBUG @echo Entering %0
|
||||||
@call :SET_VERBOSE_IF_DEBUG_ON
|
@call :SET_VERBOSE_IF_DEBUG_ON
|
||||||
|
|
||||||
:: DIR returns an error if file not found and zero if file is returned so we
|
:: 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
|
:: - %3 - string to output if DIR throws an error
|
||||||
:: - %4 - flag to indicate if 0 is an error or not
|
:: - %4 - flag to indicate if 0 is an error or not
|
||||||
::@call :SET_VERBOSE
|
::@call :SET_VERBOSE
|
||||||
if defined VERBOSE @echo on
|
@if defined VERBOSE @echo on
|
||||||
if defined VERBOSE @echo %*
|
@if defined VERBOSE @echo %*
|
||||||
dir %1 >nul 2>nul
|
dir %1 >nul 2>nul
|
||||||
if errorlevel 1 (
|
@if errorlevel 1 (
|
||||||
set _err=%ERRORLEVEL%
|
set _err=%ERRORLEVEL%
|
||||||
) else (
|
) else (
|
||||||
set _err=0
|
set _err=0
|
||||||
)
|
)
|
||||||
if %_err% EQU 0 (
|
@if %_err% EQU 0 (
|
||||||
@echo %TAB% %1 exists - %2 !
|
@echo %TAB% %1 exists - %2 !
|
||||||
) else (
|
) else (
|
||||||
@echo %TAB% %1 not found - %3 !
|
@echo %TAB% %1 not found - %3 !
|
||||||
)
|
)
|
||||||
|
|
||||||
if "%4"=="err_is_fail" (
|
@if "%4"=="err_is_fail" (
|
||||||
if %_err% GTR 0 (
|
if %_err% GTR 0 (
|
||||||
set /A XRESULT+=1
|
set /A XRESULT+=1
|
||||||
@echo XRESULT++
|
@echo XRESULT++
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
if "%4"=="no_err_is_fail" (
|
@if "%4"=="no_err_is_fail" (
|
||||||
if %_err% EQU 0 (
|
if %_err% EQU 0 (
|
||||||
set /A XRESULT+=1
|
set /A XRESULT+=1
|
||||||
@echo XRESULT++
|
@echo XRESULT++
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
call :RESET_ERRORLEVEL
|
@call :RESET_ERRORLEVEL
|
||||||
@call :UNSET_VERBOSE
|
@call :UNSET_VERBOSE
|
||||||
if defined DEBUG @echo Leaving %0
|
@if defined DEBUG @echo Leaving %0
|
||||||
@goto :EOF
|
@goto :EOF
|
||||||
::===CHECKFILEEXISTS==================================
|
::===CHECKFILEEXISTS==================================
|
||||||
|
|
||||||
|
|
||||||
::=====================================
|
::=====================================
|
||||||
:CHECKSHAREDDLLS
|
:CHECKSHAREDDLLS
|
||||||
if defined DEBUG @echo Entering %0
|
@if defined DEBUG @echo Entering %0
|
||||||
@call :SET_VERBOSE_IF_DEBUG_ON
|
@call :SET_VERBOSE_IF_DEBUG_ON
|
||||||
@reg query HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDLLs > %TEMP%\shareddlls.txt
|
@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
|
set /p SHAREDDLLSCOUNT= < %TEMP%\shareddllscount.txt
|
||||||
if NOT defined DEBUG del /q %TEMP%\shareddll*.txt
|
@if NOT defined DEBUG del /q %TEMP%\shareddll*.txt
|
||||||
if %SHAREDDLLSCOUNT% GTR 0 (
|
@if %SHAREDDLLSCOUNT% GTR 0 (
|
||||||
@echo %TAB% Oops - residue in HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDLLs
|
@echo %TAB% Oops - residue in HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDLLs
|
||||||
set /A XRESULT+=1
|
set /A XRESULT+=1
|
||||||
@echo XRESULT++
|
@echo XRESULT++
|
||||||
)
|
)
|
||||||
call :RESET_ERRORLEVEL
|
@call :RESET_ERRORLEVEL
|
||||||
if defined DEBUG @echo Leaving %0
|
@if defined DEBUG @echo Leaving %0
|
||||||
@call :UNSET_VERBOSE
|
@call :UNSET_VERBOSE
|
||||||
@goto :EOF
|
@goto :EOF
|
||||||
::===CHECKSHAREDDLLS===================
|
::===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
|
:COPY_INSTALL
|
||||||
@call :SET_VERBOSE_IF_DEBUG_ON
|
@call :SET_VERBOSE_IF_DEBUG_ON
|
||||||
if defined DEBUG @echo Entering %0
|
@if defined DEBUG @echo Entering %0
|
||||||
::@call :SET_VERBOSE
|
::@call :SET_VERBOSE
|
||||||
if defined VERBOSE @echo on
|
@if defined VERBOSE @echo on
|
||||||
|
|
||||||
:: ADIRNAME should normally be set during install and persist for uninstall
|
:: ADIRNAME should normally be set during install and persist for uninstall
|
||||||
@if not defined ADIRNAME (
|
@if not defined ADIRNAME (
|
||||||
@ -590,10 +714,13 @@ if defined VERBOSE @echo on
|
|||||||
:CHECK_ENV
|
:CHECK_ENV
|
||||||
:: TODO - add more checks for the environment declared in SET_GLOBAL_ENV
|
:: TODO - add more checks for the environment declared in SET_GLOBAL_ENV
|
||||||
if not exist %FBINST_EXEC% (
|
if not exist %FBINST_EXEC% (
|
||||||
|
echo %~0 failed
|
||||||
echo Cannot find %FBINST_EXEC%
|
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=========================
|
::===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
|
:: 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
|
:: arbitrary command that cannot fail if we want to really reset the internal
|
||||||
:: variable.
|
:: variable.
|
||||||
|
@set _err=
|
||||||
@ver > nul
|
@ver > nul
|
||||||
@goto :EOF
|
@goto :EOF
|
||||||
::===RESET_ERRORLEVEL==================
|
::===RESET_ERRORLEVEL==================
|
||||||
@ -620,12 +748,15 @@ if not exist %FBINST_EXEC% (
|
|||||||
@goto :EOF
|
@goto :EOF
|
||||||
::===SET_VERBOSE_IF_DEBUG_ON================
|
::===SET_VERBOSE_IF_DEBUG_ON================
|
||||||
|
|
||||||
|
|
||||||
::=====================================
|
::=====================================
|
||||||
:SET_VERBOSE
|
:SET_VERBOSE
|
||||||
@set VERBOSE=1
|
@set VERBOSE=1
|
||||||
|
@echo on
|
||||||
@goto :EOF
|
@goto :EOF
|
||||||
::===SET_VERBOSE================
|
::===SET_VERBOSE================
|
||||||
|
|
||||||
|
|
||||||
::=====================================
|
::=====================================
|
||||||
:UNSET_VERBOSE
|
:UNSET_VERBOSE
|
||||||
:: Unset VERBOSE before exiting each sub-routine.
|
:: Unset VERBOSE before exiting each sub-routine.
|
||||||
@ -651,50 +782,131 @@ goto :EOF
|
|||||||
:ISS_ERROR
|
:ISS_ERROR
|
||||||
@echo.
|
@echo.
|
||||||
@echo InnoSetup ErrorCode %1 from calling %~2 %~3 %~4 %~5 %~6 %~7 %~8 %~9
|
@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.
|
@echo.
|
||||||
@goto :EOF
|
@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
|
:GET_DATE
|
||||||
if NOT defined DEBUG @echo off
|
@if NOT defined DEBUG @echo off
|
||||||
echo. | date | FIND "(mm" > NUL
|
@echo. | date | FIND "(mm" > NUL
|
||||||
if errorlevel 1 ((set MD=0) & call :ParseDate DD MM) else ((set MD=1) & call :ParseDate MM DD)
|
@if errorlevel 1 ((set MD=0) & call :ParseDate DD MM) else ((set MD=1) & call :ParseDate MM DD)
|
||||||
@goto :EOF
|
@goto :EOF
|
||||||
:ParseDate
|
:ParseDate
|
||||||
for /f "tokens=1-3 delims=/.- " %%a in ("%DATE%") do (
|
@for /f "tokens=1-3 delims=/.- " %%a in ("%DATE%") do (
|
||||||
set %1=%%a
|
@set %1=%%a
|
||||||
set %2=%%b
|
@set %2=%%b
|
||||||
set YYYY=%%c
|
@set YYYY=%%c
|
||||||
@goto:EOF)
|
@goto:EOF)
|
||||||
::=====================================
|
::=====================================
|
||||||
|
|
||||||
::=====================================
|
::=====================================
|
||||||
:GET_TIME
|
:GET_TIME
|
||||||
if NOT defined DEBUG @echo off
|
@if NOT defined DEBUG @echo off
|
||||||
for /f "tokens=1-4 delims=:. " %%a in ("%TIME%") do (
|
@for /f "tokens=1-4 delims=:. " %%a in ("%TIME%") do (
|
||||||
set hh=%%a
|
@set hh=%%a
|
||||||
set nn=%%b
|
@set nn=%%b
|
||||||
set ss=%%c
|
@set ss=%%c
|
||||||
set ms=%%d
|
@set ms=%%d
|
||||||
@goto :EOF)
|
@goto :EOF)
|
||||||
::=====================================
|
::=====================================
|
||||||
|
|
||||||
::=====================================
|
::=====================================
|
||||||
:CLEAR_DT_VARS
|
:CLEAR_DT_VARS
|
||||||
if NOT defined DEBUG @echo off
|
@if NOT defined DEBUG @echo off
|
||||||
set MM=
|
@set MM=
|
||||||
set DD=
|
@set DD=
|
||||||
set YYYY=
|
@set YYYY=
|
||||||
set hh=
|
@set hh=
|
||||||
set nn=
|
@set nn=
|
||||||
set ss=
|
@set ss=
|
||||||
set ms=
|
@set ms=
|
||||||
|
@if defined DEBUG @echo Leaving CLEAR_DT_VARS
|
||||||
@goto :EOF
|
@goto :EOF
|
||||||
::=====================================
|
::=====================================
|
||||||
|
|
||||||
@ -703,8 +915,8 @@ set ms=
|
|||||||
@call :GET_DATE
|
@call :GET_DATE
|
||||||
@call :GET_TIME
|
@call :GET_TIME
|
||||||
@set TIMESTAMP=%YYYY%%MM%%DD%%hh%%nn%%ss%
|
@set TIMESTAMP=%YYYY%%MM%%DD%%hh%%nn%%ss%
|
||||||
if defined DEBUG (@echo Timestamp set to %TIMESTAMP%)
|
@if defined DEBUG (@echo Timestamp set to %TIMESTAMP%)
|
||||||
call :CLEAR_DT_VARS
|
@call :CLEAR_DT_VARS
|
||||||
@goto :EOF
|
@goto :EOF
|
||||||
::=====================================
|
::=====================================
|
||||||
|
|
||||||
@ -724,25 +936,22 @@ call :CLEAR_DT_VARS
|
|||||||
|
|
||||||
:: sometimes it is useful to just tidy up!
|
:: sometimes it is useful to just tidy up!
|
||||||
@if /I "%1"=="clean" (
|
@if /I "%1"=="clean" (
|
||||||
@call :RUN_UNINSTALLER SCRIPTED CLEAN
|
@set NOUNINSTALL=
|
||||||
@goto :EOF
|
call :RUN_UNINSTALLER SCRIPTED CLEAN
|
||||||
|
goto :EOF
|
||||||
)
|
)
|
||||||
|
|
||||||
@call :RUN_INSTALLER %*
|
@call :RUN_INSTALLER %*
|
||||||
|
@if defined _err ( echo _err is %_err% - quitting. && @goto :EOF)
|
||||||
|
|
||||||
@call :RUN_UNINSTALLER %*
|
@call :RUN_UNINSTALLER %*
|
||||||
|
|
||||||
|
|
||||||
@if defined DEBUG @echo Leaving %0
|
@if defined DEBUG @echo Leaving %0
|
||||||
@call :UNSET_VERBOSE
|
@call :UNSET_VERBOSE
|
||||||
@goto :EOF
|
@goto :EOF
|
||||||
::===MAIN==============================
|
::===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===========
|
:: NOTHING BEYOND THIS POINT===========
|
||||||
|
@ -41,9 +41,8 @@
|
|||||||
#
|
#
|
||||||
# String
|
# String
|
||||||
# ------
|
# ------
|
||||||
# Strings are also what they sound like, strings. Examples:
|
# Strings are also what they sound like, strings. Example:
|
||||||
# RemoteServiceName = gds_db
|
# RemoteServiceName = gds_db
|
||||||
# RemotePipeName = pipe47
|
|
||||||
#
|
#
|
||||||
# Scopes
|
# Scopes
|
||||||
# ------
|
# ------
|
||||||
@ -612,6 +611,18 @@
|
|||||||
#ConnectionIdleTimeout = 0
|
#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
|
# How often the pages are flushed on disk
|
||||||
@ -1020,6 +1031,19 @@
|
|||||||
#GCPolicy = combined
|
#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
|
# Security database
|
||||||
#
|
#
|
||||||
@ -1083,18 +1107,6 @@
|
|||||||
#
|
#
|
||||||
#IpcName = FIREBIRD
|
#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
|
# Settings for Unix/Linux platforms
|
||||||
# ============================
|
# ============================
|
||||||
|
@ -4881,16 +4881,6 @@
|
|||||||
path = old_proto.h;
|
path = old_proto.h;
|
||||||
refType = 4;
|
refType = 4;
|
||||||
};
|
};
|
||||||
F616C66F0200B0CF01EF0ADE = {
|
|
||||||
isa = PBXFileReference;
|
|
||||||
path = opt.cpp;
|
|
||||||
refType = 4;
|
|
||||||
};
|
|
||||||
F616C6700200B0CF01EF0ADE = {
|
|
||||||
isa = PBXFileReference;
|
|
||||||
path = opt_proto.h;
|
|
||||||
refType = 4;
|
|
||||||
};
|
|
||||||
F616C6710200B0CF01EF0ADE = {
|
F616C6710200B0CF01EF0ADE = {
|
||||||
children = (
|
children = (
|
||||||
F616C6720200B0CF01EF0ADE,
|
F616C6720200B0CF01EF0ADE,
|
||||||
@ -5133,11 +5123,6 @@
|
|||||||
path = rse.cpp;
|
path = rse.cpp;
|
||||||
refType = 4;
|
refType = 4;
|
||||||
};
|
};
|
||||||
F616C6A70200B0D001EF0ADE = {
|
|
||||||
isa = PBXFileReference;
|
|
||||||
path = rse.h;
|
|
||||||
refType = 4;
|
|
||||||
};
|
|
||||||
F616C6A80200B0D001EF0ADE = {
|
F616C6A80200B0D001EF0ADE = {
|
||||||
isa = PBXFileReference;
|
isa = PBXFileReference;
|
||||||
path = rse_proto.h;
|
path = rse_proto.h;
|
||||||
@ -6767,16 +6752,6 @@
|
|||||||
path = winvx.cpp;
|
path = winvx.cpp;
|
||||||
refType = 4;
|
refType = 4;
|
||||||
};
|
};
|
||||||
F616C8C00200B0D001EF0ADE = {
|
|
||||||
isa = PBXFileReference;
|
|
||||||
path = wnet.cpp;
|
|
||||||
refType = 4;
|
|
||||||
};
|
|
||||||
F616C8C10200B0D001EF0ADE = {
|
|
||||||
isa = PBXFileReference;
|
|
||||||
path = wnet_proto.h;
|
|
||||||
refType = 4;
|
|
||||||
};
|
|
||||||
F616C8C20200B0D001EF0ADE = {
|
F616C8C20200B0D001EF0ADE = {
|
||||||
isa = PBXFileReference;
|
isa = PBXFileReference;
|
||||||
path = xdr.cpp;
|
path = xdr.cpp;
|
||||||
|
@ -124,6 +124,9 @@ $(EXAMPLES_FB)/README:
|
|||||||
$(CP) $(ROOT)/examples/stat/*.* $(EXAMPLES_FB)/stat/
|
$(CP) $(ROOT)/examples/stat/*.* $(EXAMPLES_FB)/stat/
|
||||||
$(CP) $(ROOT)/examples/udf/*.* $(EXAMPLES_FB)/udf/
|
$(CP) $(ROOT)/examples/udf/*.* $(EXAMPLES_FB)/udf/
|
||||||
$(CP) $(ROOT)/examples/udr/*.* $(EXAMPLES_FB)/udr/
|
$(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) intlemp.fdb $(EXAMPLES_FB)/empbuild/
|
||||||
$(CP) $(ROOT)/examples/readme $(EXAMPLES_FB)/README
|
$(CP) $(ROOT)/examples/readme $(EXAMPLES_FB)/README
|
||||||
$(CP) $(ROOT)/examples/empbuild/employe2.sql $(EXAMPLES_FB)/empbuild/
|
$(CP) $(ROOT)/examples/empbuild/employe2.sql $(EXAMPLES_FB)/empbuild/
|
||||||
|
@ -27,5 +27,6 @@
|
|||||||
|
|
||||||
LD_lookup_charset
|
LD_lookup_charset
|
||||||
LD_lookup_texttype
|
LD_lookup_texttype
|
||||||
|
LD_lookup_texttype_with_status
|
||||||
LD_setup_attributes
|
LD_setup_attributes
|
||||||
LD_version
|
LD_version
|
||||||
|
@ -77,7 +77,7 @@ AllObjects += $(Chacha_Objects)
|
|||||||
|
|
||||||
# Engine
|
# Engine
|
||||||
Engine_Objects:= $(call dirObjects,jrd) $(call dirObjects,dsql) $(call dirObjects,jrd/extds) \
|
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)
|
$(call makeObjects,lock,lock.cpp)
|
||||||
|
|
||||||
AllObjects += $(Engine_Objects)
|
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\ClumpletWriter.h" />
|
||||||
<ClInclude Include="..\..\..\src\common\classes\condition.h" />
|
<ClInclude Include="..\..\..\src\common\classes\condition.h" />
|
||||||
<ClInclude Include="..\..\..\src\common\classes\DbImplementation.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_atomic.h" />
|
||||||
<ClInclude Include="..\..\..\src\common\classes\fb_pair.h" />
|
<ClInclude Include="..\..\..\src\common\classes\fb_pair.h" />
|
||||||
<ClInclude Include="..\..\..\src\common\classes\fb_string.h" />
|
<ClInclude Include="..\..\..\src\common\classes\fb_string.h" />
|
||||||
|
@ -392,6 +392,9 @@
|
|||||||
<ClInclude Include="..\..\..\src\common\classes\DbImplementation.h">
|
<ClInclude Include="..\..\..\src\common\classes\DbImplementation.h">
|
||||||
<Filter>headers</Filter>
|
<Filter>headers</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\..\src\common\classes\DoublyLinkedList.h">
|
||||||
|
<Filter>headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\..\src\common\classes\fb_atomic.h">
|
<ClInclude Include="..\..\..\src\common\classes\fb_atomic.h">
|
||||||
<Filter>headers</Filter>
|
<Filter>headers</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
@ -41,6 +41,9 @@
|
|||||||
<ClCompile Include="..\..\..\src\dsql\DsqlCompilerScratch.cpp" />
|
<ClCompile Include="..\..\..\src\dsql\DsqlCompilerScratch.cpp" />
|
||||||
<ClCompile Include="..\..\..\src\dsql\DsqlCursor.cpp" />
|
<ClCompile Include="..\..\..\src\dsql\DsqlCursor.cpp" />
|
||||||
<ClCompile Include="..\..\..\src\dsql\DSqlDataTypeUtil.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\errd.cpp" />
|
||||||
<ClCompile Include="..\..\..\src\dsql\ExprNodes.cpp" />
|
<ClCompile Include="..\..\..\src\dsql\ExprNodes.cpp" />
|
||||||
<ClCompile Include="..\..\..\src\dsql\gen.cpp" />
|
<ClCompile Include="..\..\..\src\dsql\gen.cpp" />
|
||||||
@ -90,7 +93,6 @@
|
|||||||
<ClCompile Include="..\..\..\src\jrd\IntlManager.cpp" />
|
<ClCompile Include="..\..\..\src\jrd\IntlManager.cpp" />
|
||||||
<ClCompile Include="..\..\..\src\jrd\intl_builtin.cpp" />
|
<ClCompile Include="..\..\..\src\jrd\intl_builtin.cpp" />
|
||||||
<ClCompile Include="..\..\..\src\jrd\jrd.cpp" />
|
<ClCompile Include="..\..\..\src\jrd\jrd.cpp" />
|
||||||
<ClCompile Include="..\..\..\src\jrd\JrdStatement.cpp" />
|
|
||||||
<ClCompile Include="..\..\..\src\jrd\KeywordsTable.cpp" />
|
<ClCompile Include="..\..\..\src\jrd\KeywordsTable.cpp" />
|
||||||
<ClCompile Include="..\..\..\src\jrd\lck.cpp" />
|
<ClCompile Include="..\..\..\src\jrd\lck.cpp" />
|
||||||
<ClCompile Include="..\..\..\src\jrd\Mapping.cpp" />
|
<ClCompile Include="..\..\..\src\jrd\Mapping.cpp" />
|
||||||
@ -100,8 +102,9 @@
|
|||||||
<ClCompile Include="..\..\..\src\jrd\nbak.cpp" />
|
<ClCompile Include="..\..\..\src\jrd\nbak.cpp" />
|
||||||
<ClCompile Include="..\..\..\src\jrd\nodebug.cpp" />
|
<ClCompile Include="..\..\..\src\jrd\nodebug.cpp" />
|
||||||
<ClCompile Include="..\..\..\src\jrd\ods.cpp" />
|
<ClCompile Include="..\..\..\src\jrd\ods.cpp" />
|
||||||
<ClCompile Include="..\..\..\src\jrd\opt.cpp" />
|
<ClCompile Include="..\..\..\src\jrd\optimizer\Optimizer.cpp" />
|
||||||
<ClCompile Include="..\..\..\src\jrd\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\os\win32\winnt.cpp" />
|
||||||
<ClCompile Include="..\..\..\src\jrd\pag.cpp" />
|
<ClCompile Include="..\..\..\src\jrd\pag.cpp" />
|
||||||
<ClCompile Include="..\..\..\src\jrd\par.cpp" />
|
<ClCompile Include="..\..\..\src\jrd\par.cpp" />
|
||||||
@ -152,6 +155,7 @@
|
|||||||
<ClCompile Include="..\..\..\src\jrd\shut.cpp" />
|
<ClCompile Include="..\..\..\src\jrd\shut.cpp" />
|
||||||
<ClCompile Include="..\..\..\src\jrd\sort.cpp" />
|
<ClCompile Include="..\..\..\src\jrd\sort.cpp" />
|
||||||
<ClCompile Include="..\..\..\src\jrd\sqz.cpp" />
|
<ClCompile Include="..\..\..\src\jrd\sqz.cpp" />
|
||||||
|
<ClCompile Include="..\..\..\src\jrd\Statement.cpp" />
|
||||||
<ClCompile Include="..\..\..\src\jrd\svc.cpp" />
|
<ClCompile Include="..\..\..\src\jrd\svc.cpp" />
|
||||||
<ClCompile Include="..\..\..\src\jrd\SysFunction.cpp" />
|
<ClCompile Include="..\..\..\src\jrd\SysFunction.cpp" />
|
||||||
<ClCompile Include="..\..\..\src\jrd\SystemPackages.cpp" />
|
<ClCompile Include="..\..\..\src\jrd\SystemPackages.cpp" />
|
||||||
@ -186,6 +190,9 @@
|
|||||||
<ClInclude Include="..\..\..\src\dsql\DsqlCompilerScratch.h" />
|
<ClInclude Include="..\..\..\src\dsql\DsqlCompilerScratch.h" />
|
||||||
<ClInclude Include="..\..\..\src\dsql\DsqlCursor.h" />
|
<ClInclude Include="..\..\..\src\dsql\DsqlCursor.h" />
|
||||||
<ClInclude Include="..\..\..\src\dsql\DSqlDataTypeUtil.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\dsql_proto.h" />
|
||||||
<ClInclude Include="..\..\..\src\dsql\errd_proto.h" />
|
<ClInclude Include="..\..\..\src\dsql\errd_proto.h" />
|
||||||
<ClInclude Include="..\..\..\src\dsql\ExprNodes.h" />
|
<ClInclude Include="..\..\..\src\dsql\ExprNodes.h" />
|
||||||
@ -275,7 +282,6 @@
|
|||||||
<ClInclude Include="..\..\..\src\jrd\irq.h" />
|
<ClInclude Include="..\..\..\src\jrd\irq.h" />
|
||||||
<ClInclude Include="..\..\..\src\jrd\isc_version.h" />
|
<ClInclude Include="..\..\..\src\jrd\isc_version.h" />
|
||||||
<ClInclude Include="..\..\..\src\jrd\jrd.h" />
|
<ClInclude Include="..\..\..\src\jrd\jrd.h" />
|
||||||
<ClInclude Include="..\..\..\src\jrd\JrdStatement.h" />
|
|
||||||
<ClInclude Include="..\..\..\src\jrd\jrd_proto.h" />
|
<ClInclude Include="..\..\..\src\jrd\jrd_proto.h" />
|
||||||
<ClInclude Include="..\..\..\src\jrd\KeywordsTable.h" />
|
<ClInclude Include="..\..\..\src\jrd\KeywordsTable.h" />
|
||||||
<ClInclude Include="..\..\..\src\jrd\lck.h" />
|
<ClInclude Include="..\..\..\src\jrd\lck.h" />
|
||||||
@ -296,8 +302,7 @@
|
|||||||
<ClInclude Include="..\..\..\src\jrd\obj.h" />
|
<ClInclude Include="..\..\..\src\jrd\obj.h" />
|
||||||
<ClInclude Include="..\..\..\src\jrd\ods.h" />
|
<ClInclude Include="..\..\..\src\jrd\ods.h" />
|
||||||
<ClInclude Include="..\..\..\src\jrd\ods_proto.h" />
|
<ClInclude Include="..\..\..\src\jrd\ods_proto.h" />
|
||||||
<ClInclude Include="..\..\..\src\jrd\Optimizer.h" />
|
<ClInclude Include="..\..\..\src\jrd\optimizer\Optimizer.h" />
|
||||||
<ClInclude Include="..\..\..\src\jrd\opt_proto.h" />
|
|
||||||
<ClInclude Include="..\..\..\src\jrd\pag.h" />
|
<ClInclude Include="..\..\..\src\jrd\pag.h" />
|
||||||
<ClInclude Include="..\..\..\src\jrd\pag_proto.h" />
|
<ClInclude Include="..\..\..\src\jrd\pag_proto.h" />
|
||||||
<ClInclude Include="..\..\..\src\jrd\par_proto.h" />
|
<ClInclude Include="..\..\..\src\jrd\par_proto.h" />
|
||||||
@ -317,7 +322,6 @@
|
|||||||
<ClInclude Include="..\..\..\src\jrd\rlck_proto.h" />
|
<ClInclude Include="..\..\..\src\jrd\rlck_proto.h" />
|
||||||
<ClInclude Include="..\..\..\src\jrd\Routine.h" />
|
<ClInclude Include="..\..\..\src\jrd\Routine.h" />
|
||||||
<ClInclude Include="..\..\..\src\jrd\rpb_chain.h" />
|
<ClInclude Include="..\..\..\src\jrd\rpb_chain.h" />
|
||||||
<ClInclude Include="..\..\..\src\jrd\rse.h" />
|
|
||||||
<ClInclude Include="..\..\..\src\jrd\RuntimeStatistics.h" />
|
<ClInclude Include="..\..\..\src\jrd\RuntimeStatistics.h" />
|
||||||
<ClInclude Include="..\..\..\src\jrd\sbm.h" />
|
<ClInclude Include="..\..\..\src\jrd\sbm.h" />
|
||||||
<ClInclude Include="..\..\..\src\jrd\scl.h" />
|
<ClInclude Include="..\..\..\src\jrd\scl.h" />
|
||||||
@ -327,6 +331,7 @@
|
|||||||
<ClInclude Include="..\..\..\src\jrd\shut_proto.h" />
|
<ClInclude Include="..\..\..\src\jrd\shut_proto.h" />
|
||||||
<ClInclude Include="..\..\..\src\jrd\sort.h" />
|
<ClInclude Include="..\..\..\src\jrd\sort.h" />
|
||||||
<ClInclude Include="..\..\..\src\jrd\sqz.h" />
|
<ClInclude Include="..\..\..\src\jrd\sqz.h" />
|
||||||
|
<ClInclude Include="..\..\..\src\jrd\Statement.h" />
|
||||||
<ClInclude Include="..\..\..\src\jrd\status.h" />
|
<ClInclude Include="..\..\..\src\jrd\status.h" />
|
||||||
<ClInclude Include="..\..\..\src\jrd\svc.h" />
|
<ClInclude Include="..\..\..\src\jrd\svc.h" />
|
||||||
<ClInclude Include="..\..\..\src\jrd\svc_undoc.h" />
|
<ClInclude Include="..\..\..\src\jrd\svc_undoc.h" />
|
||||||
|
@ -43,6 +43,9 @@
|
|||||||
<Filter Include="Replication">
|
<Filter Include="Replication">
|
||||||
<UniqueIdentifier>{686cba10-1e4f-44f7-b044-972ef8327197}</UniqueIdentifier>
|
<UniqueIdentifier>{686cba10-1e4f-44f7-b044-972ef8327197}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter Include="Optimizer">
|
||||||
|
<UniqueIdentifier>{4acc7c23-ac25-4311-a075-813ed730cb40}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="..\..\..\src\jrd\recsrc\WindowedStream.cpp">
|
<ClCompile Include="..\..\..\src\jrd\recsrc\WindowedStream.cpp">
|
||||||
@ -138,6 +141,15 @@
|
|||||||
<ClCompile Include="..\..\..\src\dsql\DSqlDataTypeUtil.cpp">
|
<ClCompile Include="..\..\..\src\dsql\DSqlDataTypeUtil.cpp">
|
||||||
<Filter>DSQL</Filter>
|
<Filter>DSQL</Filter>
|
||||||
</ClCompile>
|
</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">
|
<ClCompile Include="..\..\..\src\dsql\errd.cpp">
|
||||||
<Filter>DSQL</Filter>
|
<Filter>DSQL</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@ -288,9 +300,6 @@
|
|||||||
<ClCompile Include="..\..\..\src\jrd\jrd.cpp">
|
<ClCompile Include="..\..\..\src\jrd\jrd.cpp">
|
||||||
<Filter>JRD files</Filter>
|
<Filter>JRD files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\..\src\jrd\JrdStatement.cpp">
|
|
||||||
<Filter>JRD files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\..\src\jrd\KeywordsTable.cpp">
|
<ClCompile Include="..\..\..\src\jrd\KeywordsTable.cpp">
|
||||||
<Filter>JRD files</Filter>
|
<Filter>JRD files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@ -312,12 +321,6 @@
|
|||||||
<ClCompile Include="..\..\..\src\jrd\ods.cpp">
|
<ClCompile Include="..\..\..\src\jrd\ods.cpp">
|
||||||
<Filter>JRD files</Filter>
|
<Filter>JRD files</Filter>
|
||||||
</ClCompile>
|
</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">
|
<ClCompile Include="..\..\..\src\jrd\pag.cpp">
|
||||||
<Filter>JRD files</Filter>
|
<Filter>JRD files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@ -363,6 +366,9 @@
|
|||||||
<ClCompile Include="..\..\..\src\jrd\sqz.cpp">
|
<ClCompile Include="..\..\..\src\jrd\sqz.cpp">
|
||||||
<Filter>JRD files</Filter>
|
<Filter>JRD files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\..\src\jrd\Statement.cpp">
|
||||||
|
<Filter>JRD files</Filter>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\..\src\jrd\svc.cpp">
|
<ClCompile Include="..\..\..\src\jrd\svc.cpp">
|
||||||
<Filter>JRD files</Filter>
|
<Filter>JRD files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@ -507,6 +513,15 @@
|
|||||||
<ClCompile Include="..\..\..\src\jrd\MetaName.cpp">
|
<ClCompile Include="..\..\..\src\jrd\MetaName.cpp">
|
||||||
<Filter>JRD files</Filter>
|
<Filter>JRD files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\..\src\jrd\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>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\..\..\src\jrd\recsrc\RecordSource.h">
|
<ClInclude Include="..\..\..\src\jrd\recsrc\RecordSource.h">
|
||||||
@ -545,6 +560,15 @@
|
|||||||
<ClInclude Include="..\..\..\src\dsql\DSqlDataTypeUtil.h">
|
<ClInclude Include="..\..\..\src\dsql\DSqlDataTypeUtil.h">
|
||||||
<Filter>Header files</Filter>
|
<Filter>Header files</Filter>
|
||||||
</ClInclude>
|
</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">
|
<ClInclude Include="..\..\..\src\dsql\errd_proto.h">
|
||||||
<Filter>Header files</Filter>
|
<Filter>Header files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
@ -827,9 +851,6 @@
|
|||||||
<ClInclude Include="..\..\..\src\jrd\jrd_proto.h">
|
<ClInclude Include="..\..\..\src\jrd\jrd_proto.h">
|
||||||
<Filter>Header files</Filter>
|
<Filter>Header files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\..\src\jrd\JrdStatement.h">
|
|
||||||
<Filter>Header files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\..\src\jrd\KeywordsTable.h">
|
<ClInclude Include="..\..\..\src\jrd\KeywordsTable.h">
|
||||||
<Filter>Header files</Filter>
|
<Filter>Header files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
@ -878,10 +899,7 @@
|
|||||||
<ClInclude Include="..\..\..\src\jrd\ods_proto.h">
|
<ClInclude Include="..\..\..\src\jrd\ods_proto.h">
|
||||||
<Filter>Header files</Filter>
|
<Filter>Header files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\..\src\jrd\opt_proto.h">
|
<ClInclude Include="..\..\..\src\jrd\optimizer\Optimizer.h">
|
||||||
<Filter>Header files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\..\src\jrd\Optimizer.h">
|
|
||||||
<Filter>Header files</Filter>
|
<Filter>Header files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\..\src\jrd\pag.h">
|
<ClInclude Include="..\..\..\src\jrd\pag.h">
|
||||||
@ -932,9 +950,6 @@
|
|||||||
<ClInclude Include="..\..\..\src\jrd\rpb_chain.h">
|
<ClInclude Include="..\..\..\src\jrd\rpb_chain.h">
|
||||||
<Filter>Header files</Filter>
|
<Filter>Header files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\..\src\jrd\rse.h">
|
|
||||||
<Filter>Header files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\..\src\jrd\RuntimeStatistics.h">
|
<ClInclude Include="..\..\..\src\jrd\RuntimeStatistics.h">
|
||||||
<Filter>Header files</Filter>
|
<Filter>Header files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
@ -962,6 +977,9 @@
|
|||||||
<ClInclude Include="..\..\..\src\jrd\sqz.h">
|
<ClInclude Include="..\..\..\src\jrd\sqz.h">
|
||||||
<Filter>Header files</Filter>
|
<Filter>Header files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\..\src\jrd\Statement.h">
|
||||||
|
<Filter>Header files</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\..\src\jrd\status.h">
|
<ClInclude Include="..\..\..\src\jrd\status.h">
|
||||||
<Filter>Header files</Filter>
|
<Filter>Header files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
@ -157,7 +157,6 @@
|
|||||||
<ClCompile Include="..\..\..\src\remote\parser.cpp" />
|
<ClCompile Include="..\..\..\src\remote\parser.cpp" />
|
||||||
<ClCompile Include="..\..\..\src\remote\protocol.cpp" />
|
<ClCompile Include="..\..\..\src\remote\protocol.cpp" />
|
||||||
<ClCompile Include="..\..\..\src\remote\remote.cpp" />
|
<ClCompile Include="..\..\..\src\remote\remote.cpp" />
|
||||||
<ClCompile Include="..\..\..\src\remote\os\win32\wnet.cpp" />
|
|
||||||
<ClCompile Include="..\..\..\src\auth\trusted\AuthSspi.cpp" />
|
<ClCompile Include="..\..\..\src\auth\trusted\AuthSspi.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@ -165,7 +164,6 @@
|
|||||||
<ClInclude Include="..\..\..\src\auth\SecureRemotePassword\srp.h" />
|
<ClInclude Include="..\..\..\src\auth\SecureRemotePassword\srp.h" />
|
||||||
<ClInclude Include="..\..\..\src\remote\inet_proto.h" />
|
<ClInclude Include="..\..\..\src\remote\inet_proto.h" />
|
||||||
<ClInclude Include="..\..\..\src\remote\merge_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.h" />
|
||||||
<ClInclude Include="..\..\..\src\remote\os\win32\xnet_proto.h" />
|
<ClInclude Include="..\..\..\src\remote\os\win32\xnet_proto.h" />
|
||||||
<ClInclude Include="..\..\..\src\remote\parse_proto.h" />
|
<ClInclude Include="..\..\..\src\remote\parse_proto.h" />
|
||||||
|
@ -29,9 +29,6 @@
|
|||||||
<ClCompile Include="..\..\..\src\remote\remote.cpp">
|
<ClCompile Include="..\..\..\src\remote\remote.cpp">
|
||||||
<Filter>REMOTE files</Filter>
|
<Filter>REMOTE files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\..\src\remote\os\win32\wnet.cpp">
|
|
||||||
<Filter>REMOTE files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\..\src\auth\trusted\AuthSspi.cpp">
|
<ClCompile Include="..\..\..\src\auth\trusted\AuthSspi.cpp">
|
||||||
<Filter>AUTH files</Filter>
|
<Filter>AUTH files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@ -64,9 +61,6 @@
|
|||||||
<ClInclude Include="..\..\..\src\remote\remote.h">
|
<ClInclude Include="..\..\..\src\remote\remote.h">
|
||||||
<Filter>Header files</Filter>
|
<Filter>Header files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\..\src\remote\os\win32\wnet_proto.h">
|
|
||||||
<Filter>Header files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\..\src\remote\os\win32\xnet.h">
|
<ClInclude Include="..\..\..\src\remote\os\win32\xnet.h">
|
||||||
<Filter>Header files</Filter>
|
<Filter>Header files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
39
configure.ac
39
configure.ac
@ -86,6 +86,20 @@ dnl Test for special ar options?
|
|||||||
AR_OPT_CHECK=false
|
AR_OPT_CHECK=false
|
||||||
|
|
||||||
case "$build" in
|
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*)
|
x*64-*-darwin*)
|
||||||
MAKEFILE_PREFIX=darwin_x86_64
|
MAKEFILE_PREFIX=darwin_x86_64
|
||||||
MAKEFILE_POSTFIX=darwin
|
MAKEFILE_POSTFIX=darwin
|
||||||
@ -1049,7 +1063,7 @@ AC_MSG_CHECKING(for working sem_init())
|
|||||||
AC_RUN_IFELSE([AC_LANG_SOURCE([[#include <semaphore.h>
|
AC_RUN_IFELSE([AC_LANG_SOURCE([[#include <semaphore.h>
|
||||||
main () {
|
main () {
|
||||||
sem_t s;
|
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_DEFINE(WORKING_SEM_INIT,1,[Define this if sem_init() works on the platform])
|
||||||
AC_MSG_RESULT(yes)],[AC_MSG_RESULT(no)
|
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_MSG_CHECKING(for native large file support)
|
||||||
AC_RUN_IFELSE([AC_LANG_SOURCE([[#include <unistd.h>
|
AC_RUN_IFELSE([AC_LANG_SOURCE([[#include <unistd.h>
|
||||||
main () {
|
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_cv_sys_file_offset_bits=64; AC_DEFINE(_FILE_OFFSET_BITS,64)
|
||||||
AC_MSG_RESULT(yes)],[AC_MSG_RESULT(no)],[])
|
AC_MSG_RESULT(yes)],[AC_MSG_RESULT(no)],[])
|
||||||
fi
|
fi
|
||||||
@ -1140,7 +1154,7 @@ main () {
|
|||||||
char a;
|
char a;
|
||||||
union { long long x; sem_t y; } b;
|
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_cv_c_alignment=$ac_status],[ac_cv_c_alignment=$ac_status],[])
|
||||||
AC_MSG_RESULT($ac_cv_c_alignment)
|
AC_MSG_RESULT($ac_cv_c_alignment)
|
||||||
AC_DEFINE_UNQUOTED(FB_ALIGNMENT, $ac_cv_c_alignment, [Alignment of long])
|
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;
|
char a;
|
||||||
double b;
|
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_cv_c_double_align=$ac_status],[ac_cv_c_double_align=$ac_status],[])
|
||||||
AC_MSG_RESULT($ac_cv_c_double_align)
|
AC_MSG_RESULT($ac_cv_c_double_align)
|
||||||
AC_DEFINE_UNQUOTED(FB_DOUBLE_ALIGN, $ac_cv_c_double_align, [Alignment of double])
|
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;
|
return n1 == n2 ? 0 : n1 < n2 ? 1 : -1;
|
||||||
}
|
}
|
||||||
int main() {
|
int main() {
|
||||||
exit (abs64Compare(-9223372036854775808, 3652058) == 1 ? 0 : 1);
|
return abs64Compare(-9223372036854775808, 3652058) == 1 ? 0 : 1;
|
||||||
}]])],[ac_cv_compare_failed=0
|
}]])],[ac_cv_compare_failed=0
|
||||||
ac_cv_compare_result=success])
|
ac_cv_compare_result=success])
|
||||||
CFLAGS="$savedflags"
|
CFLAGS="$savedflags"
|
||||||
@ -1222,15 +1236,6 @@ case "$PLATFORM" in
|
|||||||
;;
|
;;
|
||||||
|
|
||||||
win32)
|
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)
|
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/extauth
|
||||||
mkdir -p gen/\$fb_tgt/firebird/examples/include
|
mkdir -p gen/\$fb_tgt/firebird/examples/include
|
||||||
mkdir -p gen/\$fb_tgt/firebird/examples/interfaces
|
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/package
|
||||||
mkdir -p gen/\$fb_tgt/firebird/examples/stat
|
mkdir -p gen/\$fb_tgt/firebird/examples/stat
|
||||||
mkdir -p gen/\$fb_tgt/firebird/examples/udf
|
mkdir -p gen/\$fb_tgt/firebird/examples/udf
|
||||||
@ -1503,10 +1510,6 @@ esac
|
|||||||
echo " Service name : $FB_SERVICE_NAME"
|
echo " Service name : $FB_SERVICE_NAME"
|
||||||
echo " Service port : $FB_SERVICE_PORT"
|
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 " GPRE modules : c_cxx.cpp$GPRE_LANGUAGE_MODULES"
|
||||||
echo
|
echo
|
||||||
|
|
||||||
|
@ -94,9 +94,8 @@ you only use 0/1
|
|||||||
|
|
||||||
String
|
String
|
||||||
------
|
------
|
||||||
Strings are also what they sound like, strings. Examples:
|
Strings are also what they sound like, strings. Example:
|
||||||
RootDirectory = /opt/firebird
|
RootDirectory = /opt/firebird
|
||||||
RemotePipeName = "pipe47"
|
|
||||||
|
|
||||||
|
|
||||||
Configuration options
|
Configuration options
|
||||||
@ -144,8 +143,7 @@ DeadThreadsCollection integer default 50
|
|||||||
PriorityBoost integer default 5
|
PriorityBoost integer default 5
|
||||||
RemoteServiceName string default gds_db
|
RemoteServiceName string default gds_db
|
||||||
RemoteServicePort integer default 3050 (TCP port number)
|
RemoteServicePort integer default 3050 (TCP port number)
|
||||||
RemotePipeName string default "interbas" (Windows only?)
|
IpcName string default "FIREBIRD" (Windows only)
|
||||||
IpcName string default "FirebirdIPI" (Windows only)
|
|
||||||
|
|
||||||
MaxUnflushedWrites integer
|
MaxUnflushedWrites integer
|
||||||
# of writes before file writes are forcibly synched.
|
# 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>
|
<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:
|
For local connections as simple as:
|
||||||
|
|
||||||
<file path to database or alias>
|
<file path to database or alias>
|
||||||
@ -55,11 +51,6 @@ Examples:
|
|||||||
myserver/fb_db:mydb
|
myserver/fb_db:mydb
|
||||||
localhost/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:
|
Local connection:
|
||||||
|
|
||||||
/db/mydb.fdb
|
/db/mydb.fdb
|
||||||
@ -71,8 +62,7 @@ connection strings:
|
|||||||
|
|
||||||
[ <protocol> : // [ <host> [ : <port> ] ] ] / <file path to database or alias>
|
[ <protocol> : // [ <host> [ : <port> ] ] ] / <file path to database or alias>
|
||||||
|
|
||||||
Where protocol is one of: INET (means TCP), WNET (means named pipes) or XNET
|
Where protocol is one of: INET (means TCP) or XNET (means shared memory).
|
||||||
(means shared memory).
|
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
|
|
||||||
@ -114,22 +104,12 @@ Examples:
|
|||||||
inet4://myserver/mydb
|
inet4://myserver/mydb
|
||||||
inet6://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:
|
Loopback connection via TCP:
|
||||||
|
|
||||||
inet:///db/mydb.fdb
|
inet:///db/mydb.fdb
|
||||||
inet://C:\db\mydb.fdb
|
inet://C:\db\mydb.fdb
|
||||||
inet://mydb
|
inet://mydb
|
||||||
|
|
||||||
Loopback connection via named pipes:
|
|
||||||
|
|
||||||
wnet://C:\db\mydb.fdb
|
|
||||||
wnet://mydb
|
|
||||||
|
|
||||||
Local connection via shared memory:
|
Local connection via shared memory:
|
||||||
|
|
||||||
xnet://C:\db\mydb.fdb
|
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>
|
inet://<file path to database or alias>
|
||||||
or
|
or
|
||||||
wnet://<file path to database or alias>
|
|
||||||
or
|
|
||||||
xnet://<file path to database or alias>
|
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
|
minimum case the function should register module and all factories in
|
||||||
plugin manager:</font></p>
|
plugin manager:</font></p>
|
||||||
<p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">extern
|
<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>
|
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">{</font></p>
|
||||||
<p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">IPluginManager*
|
<p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">IPluginManager*
|
||||||
|
@ -48,7 +48,7 @@ Usage:
|
|||||||
Variable name Value
|
Variable name Value
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
NETWORK_PROTOCOL | The network protocol used by client to connect. Currently
|
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.
|
WIRE_COMPRESSED | Compression status of current connection.
|
||||||
| If connection is compressed - returns "TRUE", if it is
|
| If connection is compressed - returns "TRUE", if it is
|
||||||
|
@ -11,7 +11,7 @@ Description:
|
|||||||
|
|
||||||
Syntax:
|
Syntax:
|
||||||
<declaration item> ::=
|
<declaration item> ::=
|
||||||
DECLARE [VARIABLE] <variable name> <data type> [ := <value> ];
|
DECLARE [VARIABLE] <variable name> <data type> [ = <value> ];
|
||||||
|
|
|
|
||||||
DECLARE [VARIABLE] CURSOR <cursor name> FOR (<query>);
|
DECLARE [VARIABLE] CURSOR <cursor name> FOR (<query>);
|
||||||
|
|
|
|
||||||
@ -46,8 +46,11 @@ Syntax:
|
|||||||
Limitations:
|
Limitations:
|
||||||
1) Subroutines may not be nested in another subroutine. They are only supported in the main
|
1) Subroutines may not be nested in another subroutine. They are only supported in the main
|
||||||
routine.
|
routine.
|
||||||
2) Currently, a subroutine may not directly access or use variables or cursors of the
|
2) Currently, a subroutine may not directly access cursors of the main routine/block.
|
||||||
main statements. This may be allowed in the future.
|
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:
|
Notes:
|
||||||
1) Starting in FB 4, subroutines may be recursive or call others subroutines.
|
1) Starting in FB 4, subroutines may be recursive or call others subroutines.
|
||||||
|
@ -298,7 +298,7 @@ Factory factory;
|
|||||||
|
|
||||||
} // anonymous namespace
|
} // 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;
|
master = m;
|
||||||
IPluginManager* pluginManager = master->getPluginManager();
|
IPluginManager* pluginManager = master->getPluginManager();
|
||||||
|
@ -266,7 +266,7 @@ Factory factory;
|
|||||||
|
|
||||||
} // anonymous namespace
|
} // 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();
|
IPluginManager* pluginManager = master->getPluginManager();
|
||||||
|
|
||||||
|
@ -435,13 +435,7 @@ Factory<ExtAuthServer> serverFactory;
|
|||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
|
|
||||||
#if defined(_WIN32)
|
extern "C" FB_DLL_EXPORT void FB_PLUGIN_ENTRY_POINT(IMaster* m)
|
||||||
#define FB_DLL_EXPORT __declspec(dllexport)
|
|
||||||
#else
|
|
||||||
#define FB_DLL_EXPORT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern "C" void FB_DLL_EXPORT FB_PLUGIN_ENTRY_POINT(IMaster* m)
|
|
||||||
{
|
{
|
||||||
master = m;
|
master = m;
|
||||||
IPluginManager* pluginManager = master->getPluginManager();
|
IPluginManager* pluginManager = master->getPluginManager();
|
||||||
|
@ -105,9 +105,9 @@
|
|||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<ConformanceMode>true</ConformanceMode>
|
<ConformanceMode>false</ConformanceMode>
|
||||||
<AdditionalIncludeDirectories>..\..\..\src\include\;..\..\..\extern\libtomcrypt\src\headers\</AdditionalIncludeDirectories>
|
<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>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
@ -121,9 +121,9 @@
|
|||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<ConformanceMode>true</ConformanceMode>
|
<ConformanceMode>false</ConformanceMode>
|
||||||
<AdditionalIncludeDirectories>..\..\..\src\include\;..\..\..\extern\libtomcrypt\src\headers\</AdditionalIncludeDirectories>
|
<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>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
@ -139,9 +139,9 @@
|
|||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<ConformanceMode>true</ConformanceMode>
|
<ConformanceMode>false</ConformanceMode>
|
||||||
<AdditionalIncludeDirectories>..\..\..\src\include\;..\..\..\extern\libtomcrypt\src\headers\</AdditionalIncludeDirectories>
|
<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>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
@ -159,9 +159,9 @@
|
|||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<ConformanceMode>true</ConformanceMode>
|
<ConformanceMode>false</ConformanceMode>
|
||||||
<AdditionalIncludeDirectories>..\..\..\src\include\;..\..\..\extern\libtomcrypt\src\headers\</AdditionalIncludeDirectories>
|
<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>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
|
@ -83,31 +83,31 @@
|
|||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<OutDir>..\..\prebuilt\$(Platform)\$(Configuration)\bin\</OutDir>
|
<OutDir>..\..\prebuilt\$(Platform)\$(Configuration)\bin\</OutDir>
|
||||||
<IntDir>..\..\..\temp\$(PlatformName)\$(Configuration)\examples\$(ProjectName)\</IntDir>
|
<IntDir>..\..\..\temp\$(PlatformName)\$(Configuration)\examples\$(ProjectName)\</IntDir>
|
||||||
<TargetName>fbSampleExtAuthKeygen </TargetName>
|
<TargetName>fbSampleExtAuthKeygen</TargetName>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<OutDir>..\..\prebuilt\$(Platform)\$(Configuration)\bin\</OutDir>
|
<OutDir>..\..\prebuilt\$(Platform)\$(Configuration)\bin\</OutDir>
|
||||||
<IntDir>..\..\..\temp\$(PlatformName)\$(Configuration)\examples\$(ProjectName)\</IntDir>
|
<IntDir>..\..\..\temp\$(PlatformName)\$(Configuration)\examples\$(ProjectName)\</IntDir>
|
||||||
<TargetName>fbSampleExtAuthKeygen </TargetName>
|
<TargetName>fbSampleExtAuthKeygen</TargetName>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
<OutDir>..\..\prebuilt\$(Platform)\$(Configuration)\bin\</OutDir>
|
<OutDir>..\..\prebuilt\$(Platform)\$(Configuration)\bin\</OutDir>
|
||||||
<IntDir>..\..\..\temp\$(PlatformName)\$(Configuration)\examples\$(ProjectName)\</IntDir>
|
<IntDir>..\..\..\temp\$(PlatformName)\$(Configuration)\examples\$(ProjectName)\</IntDir>
|
||||||
<TargetName>fbSampleExtAuthKeygen </TargetName>
|
<TargetName>fbSampleExtAuthKeygen</TargetName>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
<OutDir>..\..\prebuilt\$(Platform)\$(Configuration)\bin\</OutDir>
|
<OutDir>..\..\prebuilt\$(Platform)\$(Configuration)\bin\</OutDir>
|
||||||
<IntDir>..\..\..\temp\$(PlatformName)\$(Configuration)\examples\$(ProjectName)\</IntDir>
|
<IntDir>..\..\..\temp\$(PlatformName)\$(Configuration)\examples\$(ProjectName)\</IntDir>
|
||||||
<TargetName>fbSampleExtAuthKeygen </TargetName>
|
<TargetName>fbSampleExtAuthKeygen</TargetName>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<ConformanceMode>true</ConformanceMode>
|
<ConformanceMode>false</ConformanceMode>
|
||||||
<AdditionalIncludeDirectories>..\..\..\src\include\;..\..\..\extern\libtomcrypt\src\headers\</AdditionalIncludeDirectories>
|
<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>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
@ -120,9 +120,9 @@
|
|||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<ConformanceMode>true</ConformanceMode>
|
<ConformanceMode>false</ConformanceMode>
|
||||||
<AdditionalIncludeDirectories>..\..\..\src\include\;..\..\..\extern\libtomcrypt\src\headers\</AdditionalIncludeDirectories>
|
<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>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
@ -137,9 +137,9 @@
|
|||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<ConformanceMode>true</ConformanceMode>
|
<ConformanceMode>false</ConformanceMode>
|
||||||
<AdditionalIncludeDirectories>..\..\..\src\include\;..\..\..\extern\libtomcrypt\src\headers\</AdditionalIncludeDirectories>
|
<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>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
@ -156,9 +156,9 @@
|
|||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<ConformanceMode>true</ConformanceMode>
|
<ConformanceMode>false</ConformanceMode>
|
||||||
<AdditionalIncludeDirectories>..\..\..\src\include\;..\..\..\extern\libtomcrypt\src\headers\</AdditionalIncludeDirectories>
|
<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>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
|
@ -145,7 +145,7 @@ int main()
|
|||||||
/*IProvider* prov = master->getDispatcher();
|
/*IProvider* prov = master->getDispatcher();
|
||||||
IAttachment* att = NULL;*/
|
IAttachment* att = NULL;*/
|
||||||
IUtil* utl = master->getUtilInterface();
|
IUtil* utl = master->getUtilInterface();
|
||||||
IStatement* statemt = NULL;
|
IStatement* statement = NULL;
|
||||||
ITransaction* tra = NULL;
|
ITransaction* tra = NULL;
|
||||||
IBatch* batch = NULL;
|
IBatch* batch = NULL;
|
||||||
IBatchCompletionState* cs = NULL;
|
IBatchCompletionState* cs = NULL;
|
||||||
@ -185,7 +185,7 @@ int main()
|
|||||||
if (isc_dsql_prepare(st, &tr, &stmt, 0, sqlStmt1, 3, NULL))
|
if (isc_dsql_prepare(st, &tr, &stmt, 0, sqlStmt1, 3, NULL))
|
||||||
raiseError(status, st);
|
raiseError(status, st);
|
||||||
// and get it's interface
|
// and get it's interface
|
||||||
if (fb_get_statement_interface(st, &statemt, &stmt))
|
if (fb_get_statement_interface(st, &statement, &stmt))
|
||||||
raiseError(status, st);
|
raiseError(status, st);
|
||||||
|
|
||||||
// Message to store in a table
|
// Message to store in a table
|
||||||
@ -202,7 +202,7 @@ int main()
|
|||||||
pb->insertInt(&status, IBatch::TAG_RECORD_COUNTS, 1);
|
pb->insertInt(&status, IBatch::TAG_RECORD_COUNTS, 1);
|
||||||
|
|
||||||
// create batch
|
// create batch
|
||||||
batch = statemt->createBatch(&status, meta,
|
batch = statement->createBatch(&status, meta,
|
||||||
pb->getBufferLength(&status), pb->getBuffer(&status));
|
pb->getBufferLength(&status), pb->getBuffer(&status));
|
||||||
|
|
||||||
// fill batch with data record by record
|
// fill batch with data record by record
|
||||||
@ -223,8 +223,8 @@ int main()
|
|||||||
batch = NULL;
|
batch = NULL;
|
||||||
|
|
||||||
// unprepare statement
|
// unprepare statement
|
||||||
statemt->release();
|
statement->release();
|
||||||
statemt = NULL;
|
statement = NULL;
|
||||||
if (isc_dsql_free_statement(st, &stmt, DSQL_unprepare))
|
if (isc_dsql_free_statement(st, &stmt, DSQL_unprepare))
|
||||||
raiseError(status, st);
|
raiseError(status, st);
|
||||||
|
|
||||||
@ -237,7 +237,7 @@ int main()
|
|||||||
if (isc_dsql_prepare(st, &tr, &stmt, 0, sqlStmt2, 3, NULL))
|
if (isc_dsql_prepare(st, &tr, &stmt, 0, sqlStmt2, 3, NULL))
|
||||||
raiseError(status, st);
|
raiseError(status, st);
|
||||||
// and get it's interface
|
// and get it's interface
|
||||||
if (fb_get_statement_interface(st, &statemt, &stmt))
|
if (fb_get_statement_interface(st, &statement, &stmt))
|
||||||
raiseError(status, st);
|
raiseError(status, st);
|
||||||
|
|
||||||
// Message to store in a table
|
// Message to store in a table
|
||||||
@ -255,7 +255,7 @@ int main()
|
|||||||
pb->insertInt(&status, IBatch::TAG_BLOB_POLICY, IBatch::BLOB_ID_ENGINE);
|
pb->insertInt(&status, IBatch::TAG_BLOB_POLICY, IBatch::BLOB_ID_ENGINE);
|
||||||
|
|
||||||
// create batch
|
// create batch
|
||||||
batch = statemt->createBatch(&status, meta,
|
batch = statement->createBatch(&status, meta,
|
||||||
pb->getBufferLength(&status), pb->getBuffer(&status));
|
pb->getBufferLength(&status), pb->getBuffer(&status));
|
||||||
|
|
||||||
// create blob
|
// create blob
|
||||||
@ -283,8 +283,8 @@ int main()
|
|||||||
batch = NULL;
|
batch = NULL;
|
||||||
|
|
||||||
// unprepare statement
|
// unprepare statement
|
||||||
statemt->release();
|
statement->release();
|
||||||
statemt = NULL;
|
statement = NULL;
|
||||||
if (isc_dsql_free_statement(st, &stmt, DSQL_drop))
|
if (isc_dsql_free_statement(st, &stmt, DSQL_drop))
|
||||||
raiseError(status, st);
|
raiseError(status, st);
|
||||||
|
|
||||||
@ -312,8 +312,8 @@ int main()
|
|||||||
batch->release();
|
batch->release();
|
||||||
if (tra)
|
if (tra)
|
||||||
tra->release();
|
tra->release();
|
||||||
if (statemt)
|
if (statement)
|
||||||
statemt->release();
|
statement->release();
|
||||||
|
|
||||||
// close handles if not closed
|
// close handles if not closed
|
||||||
if (blb)
|
if (blb)
|
||||||
|
@ -37,14 +37,6 @@ typedef int FbSampleAtomic;
|
|||||||
|
|
||||||
#include <firebird/Interface.h>
|
#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;
|
using namespace Firebird;
|
||||||
|
|
||||||
#define SAMPLES_DIALECT SQL_DIALECT_V6
|
#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
|
- Open select.lpr as a project
|
||||||
- When prompted choose 'Simple Program' as the project template
|
- When prompted choose 'Simple Program' as the project template
|
||||||
- Go into Project options and add the following paths:
|
- Go into Project options and add the following paths:
|
||||||
/opt/firebird/include/Firebird
|
```
|
||||||
|
/usr/include/Firebird
|
||||||
common
|
common
|
||||||
|
```
|
||||||
You can then compile and run the example through the debugger.
|
You can then compile and run the example through the debugger.
|
||||||
|
|
||||||
|
|
||||||
|
@ -100,14 +100,7 @@ public:
|
|||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
#if defined(__WIN32__)
|
FB_DLL_EXPORT void FB_PLUGIN_ENTRY_POINT(IMaster* m)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
master = m;
|
master = m;
|
||||||
IPluginManager* pm = m->getPluginManager();
|
IPluginManager* pm = m->getPluginManager();
|
||||||
|
@ -234,8 +234,6 @@ FB_UDR_BEGIN_TRIGGER(replicate_persons)
|
|||||||
"select data_source from replicate_config where name = ?",
|
"select data_source from replicate_config where name = ?",
|
||||||
SQL_DIALECT_CURRENT, NULL), status, statusVector);
|
SQL_DIALECT_CURRENT, NULL), status, statusVector);
|
||||||
|
|
||||||
const char* table = metadata->getTriggerTable(status);
|
|
||||||
|
|
||||||
// Skip the first exclamation point, separating the module name and entry point.
|
// Skip the first exclamation point, separating the module name and entry point.
|
||||||
const char* info = strchr(metadata->getEntryPoint(status), '!');
|
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
|
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:
|
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"
|
"dsql/*.cpp"
|
||||||
"jrd/*.cpp"
|
"jrd/*.cpp"
|
||||||
"jrd/extds/*.cpp"
|
"jrd/extds/*.cpp"
|
||||||
|
"jrd/optimizer/*.cpp"
|
||||||
"jrd/recsrc/*.cpp"
|
"jrd/recsrc/*.cpp"
|
||||||
"jrd/replication/*.cpp"
|
"jrd/replication/*.cpp"
|
||||||
"jrd/trace/*.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 block: used to store info about a multi-database transaction.
|
||||||
// Transaction Description Record
|
// Transaction Description Record
|
||||||
|
|
||||||
@ -114,10 +105,10 @@ struct tdr : public pool_alloc<alice_type_tdr>
|
|||||||
{
|
{
|
||||||
tdr* tdr_next; // next sub-transaction
|
tdr* tdr_next; // next sub-transaction
|
||||||
TraNumber tdr_id; // database-specific transaction id
|
TraNumber tdr_id; // database-specific transaction id
|
||||||
alice_str* tdr_fullpath; // full (possibly) remote pathname
|
Firebird::string tdr_fullpath; // full (possibly) remote pathname
|
||||||
const TEXT* tdr_filename; // filename within full pathname
|
Firebird::string tdr_filename; // filename
|
||||||
alice_str* tdr_host_site; // host for transaction
|
Firebird::string tdr_host_site; // host for transaction
|
||||||
alice_str* tdr_remote_site; // site for remote transaction
|
Firebird::string tdr_remote_site; // site for remote transaction
|
||||||
FB_API_HANDLE tdr_handle; // reconnected transaction handle
|
FB_API_HANDLE tdr_handle; // reconnected transaction handle
|
||||||
FB_API_HANDLE tdr_db_handle; // re-attached database handle
|
FB_API_HANDLE tdr_db_handle; // re-attached database handle
|
||||||
USHORT tdr_db_caps; // capabilities of database
|
USHORT tdr_db_caps; // capabilities of database
|
||||||
|
@ -39,6 +39,7 @@
|
|||||||
#include "../common/classes/UserBlob.h"
|
#include "../common/classes/UserBlob.h"
|
||||||
#include "../alice/alice_proto.h"
|
#include "../alice/alice_proto.h"
|
||||||
#include "../common/utils_proto.h"
|
#include "../common/utils_proto.h"
|
||||||
|
#include "../common/isc_f_proto.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@ -54,7 +55,7 @@ DATABASE DB = STATIC FILENAME "yachts.lnk";
|
|||||||
|
|
||||||
typedef Firebird::HalfStaticArray<TEXT, 1024> TextBuffer;
|
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 USHORT get_capabilities(ISC_STATUS*);
|
||||||
static tdr* get_description(ISC_QUAD*);
|
static tdr* get_description(ISC_QUAD*);
|
||||||
static void parse_fullpath(tdr*);
|
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.
|
* 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();
|
AliceGlobals* tdgbl = AliceGlobals::getSpecific();
|
||||||
|
|
||||||
const TEXT* p = *ptr;
|
const TEXT* p = *ptr;
|
||||||
|
|
||||||
const USHORT length = (USHORT) *p++;
|
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;
|
*ptr = p + length;
|
||||||
|
|
||||||
return string;
|
str.assign(p, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -319,8 +316,8 @@ static tdr* get_description(ISC_QUAD* blob_id)
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
tdr* trans = NULL;
|
tdr* trans = NULL;
|
||||||
alice_str* host_site = NULL;
|
Firebird::string host_site;
|
||||||
alice_str* database_path = NULL;
|
Firebird::string database_path;
|
||||||
|
|
||||||
const TEXT* p = buffer.begin();
|
const TEXT* p = buffer.begin();
|
||||||
|
|
||||||
@ -336,11 +333,11 @@ static tdr* get_description(ISC_QUAD* blob_id)
|
|||||||
switch (*p++)
|
switch (*p++)
|
||||||
{
|
{
|
||||||
case TDR_HOST_SITE:
|
case TDR_HOST_SITE:
|
||||||
host_site = alloc_string(&p);
|
get_string(&p, host_site);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TDR_DATABASE_PATH:
|
case TDR_DATABASE_PATH:
|
||||||
database_path = alloc_string(&p);
|
get_string(&p, database_path);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TDR_TRANSACTION_ID:
|
case TDR_TRANSACTION_ID:
|
||||||
@ -359,7 +356,7 @@ static tdr* get_description(ISC_QUAD* blob_id)
|
|||||||
ptr->tdr_fullpath = database_path;
|
ptr->tdr_fullpath = database_path;
|
||||||
parse_fullpath(ptr);
|
parse_fullpath(ptr);
|
||||||
ptr->tdr_id = id;
|
ptr->tdr_id = id;
|
||||||
database_path = NULL;
|
database_path.clear();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -382,73 +379,17 @@ static tdr* get_description(ISC_QUAD* blob_id)
|
|||||||
|
|
||||||
static void parse_fullpath(tdr* trans)
|
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;
|
while (ISC_analyze_tcp(filename, hostname))
|
||||||
const TEXT* const start = p;
|
trans->tdr_remote_site = hostname.c_str();
|
||||||
while (*p)
|
|
||||||
p++;
|
|
||||||
const TEXT* const end = p;
|
|
||||||
|
|
||||||
// Check for a named pipes name - \\node\path\db or //node/path/db
|
// At this point the filename is clear from any remote nodes
|
||||||
while (p > start && !(*p == '/' && p[-1] == '/') && !(*p == '\\' && p[-1] == '\\'))
|
|
||||||
{
|
|
||||||
--p;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p > start)
|
trans->tdr_filename = filename.c_str();
|
||||||
{
|
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -472,7 +472,7 @@ bool TDR_reconnect_multiple(FB_API_HANDLE handle, TraNumber id, const TEXT* name
|
|||||||
{
|
{
|
||||||
if (ptr->tdr_state == TRA_limbo)
|
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();
|
AliceGlobals* tdgbl = AliceGlobals::getSpecific();
|
||||||
|
|
||||||
if (!trans)
|
if (!trans)
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
if (!tdgbl->uSvc->isService())
|
if (!tdgbl->uSvc->isService())
|
||||||
{
|
|
||||||
ALICE_print(92); // msg 92: Multidatabase transaction:
|
ALICE_print(92); // msg 92: Multidatabase transaction:
|
||||||
}
|
|
||||||
|
|
||||||
bool prepared_seen = false;
|
bool prepared_seen = false;
|
||||||
for (const tdr* ptr = trans; ptr; ptr = ptr->tdr_next)
|
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())
|
if (!tdgbl->uSvc->isService())
|
||||||
{
|
{
|
||||||
// msg 93: Host Site: %s
|
// 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)
|
if (ptr->tdr_id)
|
||||||
@ -586,28 +581,26 @@ static void print_description(const tdr* trans)
|
|||||||
break;
|
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())
|
if (!tdgbl->uSvc->isService())
|
||||||
{
|
{
|
||||||
// msg 101: Remote Site: %s
|
// 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())
|
if (!tdgbl->uSvc->isService())
|
||||||
{
|
{
|
||||||
// msg 102: Database Path: %s
|
// 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()
|
static SINT64 ask()
|
||||||
{
|
{
|
||||||
AliceGlobals* tdgbl = AliceGlobals::getSpecific();
|
AliceGlobals* tdgbl = AliceGlobals::getSpecific();
|
||||||
|
|
||||||
if (tdgbl->uSvc->isService())
|
if (tdgbl->uSvc->isService())
|
||||||
{
|
|
||||||
return ~SINT64(0);
|
return ~SINT64(0);
|
||||||
}
|
|
||||||
|
|
||||||
char response[32];
|
char response[32];
|
||||||
SINT64 switches = 0;
|
SINT64 switches = 0;
|
||||||
@ -694,79 +686,56 @@ static SINT64 ask()
|
|||||||
static void reattach_database(tdr* trans)
|
static void reattach_database(tdr* trans)
|
||||||
{
|
{
|
||||||
ISC_STATUS_ARRAY status_vector;
|
ISC_STATUS_ARRAY status_vector;
|
||||||
char buffer[1024];
|
char buffer[BUFFER_LARGE];
|
||||||
// sizeof(buffer) - 1 => leave space for the terminator.
|
// sizeof(buffer) - 1 => leave space for the terminator.
|
||||||
const char* const end = buffer + sizeof(buffer) - 1;
|
const char* const end = buffer + sizeof(buffer) - 1;
|
||||||
AliceGlobals* tdgbl = AliceGlobals::getSpecific();
|
AliceGlobals* tdgbl = AliceGlobals::getSpecific();
|
||||||
|
|
||||||
ISC_get_host(buffer, sizeof(buffer));
|
if (trans->tdr_fullpath.hasData())
|
||||||
|
|
||||||
if (trans->tdr_fullpath)
|
|
||||||
{
|
{
|
||||||
|
Firebird::string hostname;
|
||||||
|
ISC_get_host(hostname);
|
||||||
|
|
||||||
// if this is being run from the same host,
|
// if this is being run from the same host,
|
||||||
// try to reconnect using the same pathname
|
// try to reconnect using the same pathname
|
||||||
|
|
||||||
if (!strcmp(buffer, reinterpret_cast<const char*>(trans->tdr_host_site->str_data)))
|
if (trans->tdr_host_site == hostname)
|
||||||
{
|
|
||||||
if (TDR_attach_database(status_vector, trans,
|
|
||||||
reinterpret_cast<char*>(trans->tdr_fullpath->str_data)))
|
|
||||||
{
|
{
|
||||||
|
if (TDR_attach_database(status_vector, trans, trans->tdr_fullpath.c_str()))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
else if (trans->tdr_host_site.hasData())
|
||||||
else if (trans->tdr_host_site)
|
|
||||||
{
|
{
|
||||||
// try going through the previous host with all available
|
// try going through the previous host with all available
|
||||||
// protocols, using chaining to try the same method of
|
// protocols, using chaining to try the same method of
|
||||||
// attachment originally used from that host
|
// attachment originally used from that host
|
||||||
char* p = buffer;
|
const Firebird::string pathname = trans->tdr_host_site + ':' + trans->tdr_fullpath;
|
||||||
const UCHAR* q = trans->tdr_host_site->str_data;
|
if (TDR_attach_database(status_vector, trans, pathname.c_str()))
|
||||||
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))
|
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// attaching using the old method didn't work;
|
// attaching using the old method didn't work;
|
||||||
// try attaching to the remote node directly
|
// try attaching to the remote node directly
|
||||||
|
|
||||||
if (trans->tdr_remote_site)
|
if (trans->tdr_remote_site.hasData())
|
||||||
{
|
|
||||||
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))
|
|
||||||
{
|
{
|
||||||
|
const Firebird::string pathname = trans->tdr_remote_site + ':' + trans->tdr_filename;
|
||||||
|
if (TDR_attach_database(status_vector, trans, pathname.c_str()))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// we have failed to reattach; notify the user
|
// we have failed to reattach; notify the user
|
||||||
// and let them try to succeed where we have failed
|
// and let them try to succeed where we have failed
|
||||||
|
|
||||||
ALICE_print(86, SafeArg() << trans->tdr_id);
|
ALICE_print(86, SafeArg() << trans->tdr_id);
|
||||||
// msg 86: Could not reattach to database for transaction %ld.
|
// 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
|
// msg 87: Original path: %s
|
||||||
|
|
||||||
if (tdgbl->uSvc->isService())
|
if (tdgbl->uSvc->isService())
|
||||||
{
|
|
||||||
ALICE_exit(FINI_ERROR, tdgbl);
|
ALICE_exit(FINI_ERROR, tdgbl);
|
||||||
}
|
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
@ -782,12 +751,8 @@ static void reattach_database(tdr* trans)
|
|||||||
++p;
|
++p;
|
||||||
if (TDR_attach_database(status_vector, trans, p))
|
if (TDR_attach_database(status_vector, trans, p))
|
||||||
{
|
{
|
||||||
const size_t p_len = strlen(p);
|
trans->tdr_fullpath.assign(p);
|
||||||
alice_str* string = FB_NEW_RPT(*tdgbl->getDefaultPool(), p_len + 1) alice_str;
|
trans->tdr_filename = trans->tdr_fullpath;
|
||||||
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;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ALICE_print(89); // msg 89: Attach unsuccessful.
|
ALICE_print(89); // msg 89: Attach unsuccessful.
|
||||||
|
@ -38,7 +38,7 @@
|
|||||||
static Firebird::SimpleFactory<Auth::DebugClient> clientFactory;
|
static Firebird::SimpleFactory<Auth::DebugClient> clientFactory;
|
||||||
static Firebird::SimpleFactory<Auth::DebugServer> serverFactory;
|
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);
|
Firebird::CachedMasterInterface::set(master);
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ namespace Auth {
|
|||||||
// The idea of debug plugin is to send some data from server to client,
|
// 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
|
// 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 Firebird::StdPlugin<Firebird::IServerImpl<DebugServer, Firebird::CheckStatusWrapper> >
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -61,7 +61,7 @@ private:
|
|||||||
Firebird::RefPtr<Firebird::IConfig> config;
|
Firebird::RefPtr<Firebird::IConfig> config;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DebugClient FB_FINAL :
|
class DebugClient final :
|
||||||
public Firebird::StdPlugin<Firebird::IClientImpl<DebugClient, Firebird::CheckStatusWrapper> >
|
public Firebird::StdPlugin<Firebird::IClientImpl<DebugClient, Firebird::CheckStatusWrapper> >
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -55,7 +55,7 @@ public:
|
|||||||
|
|
||||||
class PluginDatabases;
|
class PluginDatabases;
|
||||||
|
|
||||||
class CachedSecurityDatabase FB_FINAL
|
class CachedSecurityDatabase final
|
||||||
: public Firebird::RefCntIface<Firebird::ITimerImpl<CachedSecurityDatabase, Firebird::CheckStatusWrapper> >
|
: public Firebird::RefCntIface<Firebird::ITimerImpl<CachedSecurityDatabase, Firebird::CheckStatusWrapper> >
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -59,7 +59,7 @@ protected:
|
|||||||
virtual RemotePassword* remotePasswordFactory() = 0;
|
virtual RemotePassword* remotePasswordFactory() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class SHA> class SrpClientImpl FB_FINAL : public SrpClient
|
template <class SHA> class SrpClientImpl final : public SrpClient
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit SrpClientImpl<SHA>(IPluginConfig* ipc)
|
explicit SrpClientImpl<SHA>(IPluginConfig* ipc)
|
||||||
|
@ -38,14 +38,6 @@
|
|||||||
#include "../common/classes/auto.h"
|
#include "../common/classes/auto.h"
|
||||||
#include "../common/classes/ParsedList.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 {
|
namespace {
|
||||||
|
|
||||||
const unsigned int SZ_LOGIN = 31;
|
const unsigned int SZ_LOGIN = 31;
|
||||||
@ -60,7 +52,7 @@ Firebird::GlobalPtr<Firebird::ConfigKeys> keys;
|
|||||||
|
|
||||||
namespace Auth {
|
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:
|
public:
|
||||||
explicit SrpManagement(Firebird::IPluginConfig* par)
|
explicit SrpManagement(Firebird::IPluginConfig* par)
|
||||||
@ -540,12 +532,9 @@ public:
|
|||||||
assignField(active, user->active());
|
assignField(active, user->active());
|
||||||
setField(login, user->userName());
|
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);
|
stmt->execute(status, mainTra, up.getMetadata(), up.getBuffer(), NULL, NULL);
|
||||||
check(status);
|
check(status);
|
||||||
|
if (recordsCount(status, stmt, isc_info_req_update_count) != 1)
|
||||||
if (!checkCount(status, stmt, &count, isc_info_req_update_count))
|
|
||||||
{
|
{
|
||||||
stmt->release();
|
stmt->release();
|
||||||
return GsecMsg22;
|
return GsecMsg22;
|
||||||
@ -581,12 +570,9 @@ public:
|
|||||||
Varfield login(dl);
|
Varfield login(dl);
|
||||||
setField(login, user->userName());
|
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);
|
stmt->execute(status, mainTra, dl.getMetadata(), dl.getBuffer(), NULL, NULL);
|
||||||
check(status);
|
check(status);
|
||||||
|
if (recordsCount(status, stmt, isc_info_req_delete_count) != 1)
|
||||||
if (!checkCount(status, stmt, &count, isc_info_req_delete_count))
|
|
||||||
{
|
{
|
||||||
stmt->release();
|
stmt->release();
|
||||||
return GsecMsg22;
|
return GsecMsg22;
|
||||||
@ -739,7 +725,7 @@ private:
|
|||||||
|
|
||||||
RemotePasswordImpl<Firebird::Sha1> server;
|
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];
|
UCHAR buffer[33];
|
||||||
const UCHAR count_info[] = { isc_info_sql_records };
|
const UCHAR count_info[] = { isc_info_sql_records };
|
||||||
@ -755,17 +741,12 @@ private:
|
|||||||
const SSHORT len = gds__vax_integer(p, 2);
|
const SSHORT len = gds__vax_integer(p, 2);
|
||||||
p += 2;
|
p += 2;
|
||||||
if (count_is == item)
|
if (count_is == item)
|
||||||
{
|
return gds__vax_integer(p, len);
|
||||||
int newCount = gds__vax_integer(p, len);
|
|
||||||
int oldCount = *count;
|
|
||||||
*count = newCount;
|
|
||||||
return newCount == oldCount + 1;
|
|
||||||
}
|
|
||||||
p += len;
|
p += len;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void check(Firebird::CheckStatusWrapper* status)
|
static void check(Firebird::CheckStatusWrapper* status)
|
||||||
@ -986,7 +967,7 @@ static Firebird::SimpleFactory<Auth::SrpManagement> factory;
|
|||||||
|
|
||||||
} // namespace Auth
|
} // 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::CachedMasterInterface::set(master);
|
||||||
Firebird::PluginManagerInterfacePtr()->registerPluginFactory(Firebird::IPluginManager::TYPE_AUTH_USER_MANAGEMENT, Auth::RemotePassword::plugName, &Auth::factory);
|
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:
|
public:
|
||||||
explicit SrpServerImpl<SHA>(IPluginConfig* ipc)
|
explicit SrpServerImpl<SHA>(IPluginConfig* ipc)
|
||||||
|
@ -35,7 +35,7 @@ namespace Auth {
|
|||||||
// Required to stop analyzing rest of plugins before first roundtrip to server
|
// Required to stop analyzing rest of plugins before first roundtrip to server
|
||||||
// if legacy login is present in DPB
|
// if legacy login is present in DPB
|
||||||
|
|
||||||
class SecurityDatabaseClient FB_FINAL :
|
class SecurityDatabaseClient final :
|
||||||
public Firebird::StdPlugin<Firebird::IClientImpl<SecurityDatabaseClient, Firebird::CheckStatusWrapper> >
|
public Firebird::StdPlugin<Firebird::IClientImpl<SecurityDatabaseClient, Firebird::CheckStatusWrapper> >
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -762,7 +762,7 @@ int SecurityDatabaseManagement::execute(Firebird::CheckStatusWrapper* st, Firebi
|
|||||||
// register plugin
|
// register plugin
|
||||||
static Firebird::SimpleFactory<Auth::SecurityDatabaseManagement> factory;
|
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::CachedMasterInterface::set(master);
|
||||||
Firebird::PluginManagerInterfacePtr()->registerPluginFactory(
|
Firebird::PluginManagerInterfacePtr()->registerPluginFactory(
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
|
|
||||||
namespace Auth {
|
namespace Auth {
|
||||||
|
|
||||||
class SecurityDatabaseManagement FB_FINAL :
|
class SecurityDatabaseManagement final :
|
||||||
public Firebird::StdPlugin<Firebird::IManagementImpl<SecurityDatabaseManagement, Firebird::CheckStatusWrapper> >
|
public Firebird::StdPlugin<Firebird::IManagementImpl<SecurityDatabaseManagement, Firebird::CheckStatusWrapper> >
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -125,7 +125,7 @@ namespace Auth {
|
|||||||
GlobalPtr<PluginDatabases> instances;
|
GlobalPtr<PluginDatabases> instances;
|
||||||
|
|
||||||
|
|
||||||
class SecurityDatabaseServer FB_FINAL :
|
class SecurityDatabaseServer final :
|
||||||
public StdPlugin<IServerImpl<SecurityDatabaseServer, CheckStatusWrapper> >
|
public StdPlugin<IServerImpl<SecurityDatabaseServer, CheckStatusWrapper> >
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -411,7 +411,7 @@ void registerLegacyServer(IPluginManager* iPlugin)
|
|||||||
|
|
||||||
#ifdef PLUG_MODULE
|
#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);
|
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.
|
// We can't honor operating systems that allow longer file names.
|
||||||
if (len >= MAX_FILE_NAME_SIZE)
|
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
|
// msg 343: text for attribute @1 is too large in @2, truncating to @3 bytes
|
||||||
len = MAX_FILE_NAME_SIZE - 1;
|
len = MAX_FILE_NAME_SIZE - 1;
|
||||||
}
|
}
|
||||||
@ -1961,6 +1961,7 @@ void put_boolean(att_type attribute, const FB_BOOLEAN value)
|
|||||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||||
|
|
||||||
put(tdgbl, attribute);
|
put(tdgbl, attribute);
|
||||||
|
put(tdgbl, (UCHAR) 1);
|
||||||
put(tdgbl, value ? 1u : 0u);
|
put(tdgbl, value ? 1u : 0u);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -252,8 +252,9 @@ enum att_type {
|
|||||||
att_SQL_dialect, // SQL dialect that it speaks
|
att_SQL_dialect, // SQL dialect that it speaks
|
||||||
att_db_read_only, // Is the database ReadOnly?
|
att_db_read_only, // Is the database ReadOnly?
|
||||||
att_database_linger, // Disconnection timeout
|
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_replica_mode, // replica mode
|
||||||
|
att_database_sql_security, // default sql security value
|
||||||
|
|
||||||
// Relation attributes
|
// Relation attributes
|
||||||
|
|
||||||
@ -275,6 +276,7 @@ enum att_type {
|
|||||||
att_relation_flags,
|
att_relation_flags,
|
||||||
att_relation_ext_file_name, // name of file for external tables
|
att_relation_ext_file_name, // name of file for external tables
|
||||||
att_relation_type,
|
att_relation_type,
|
||||||
|
att_relation_sql_security_deprecated, // can be removed later
|
||||||
att_relation_sql_security,
|
att_relation_sql_security,
|
||||||
|
|
||||||
// Field attributes (used for both global and local fields)
|
// Field attributes (used for both global and local fields)
|
||||||
@ -409,6 +411,7 @@ enum att_type {
|
|||||||
att_trig_engine_name,
|
att_trig_engine_name,
|
||||||
att_trig_entrypoint,
|
att_trig_entrypoint,
|
||||||
att_trig_type2,
|
att_trig_type2,
|
||||||
|
att_trig_sql_security_deprecated, // can be removed later
|
||||||
att_trig_sql_security,
|
att_trig_sql_security,
|
||||||
|
|
||||||
// Function attributes
|
// Function attributes
|
||||||
@ -433,6 +436,7 @@ enum att_type {
|
|||||||
att_function_owner_name,
|
att_function_owner_name,
|
||||||
att_function_legacy_flag,
|
att_function_legacy_flag,
|
||||||
att_function_deterministic_flag,
|
att_function_deterministic_flag,
|
||||||
|
att_function_sql_security_deprecated, // can be removed later
|
||||||
att_function_sql_security,
|
att_function_sql_security,
|
||||||
|
|
||||||
// Function argument attributes
|
// Function argument attributes
|
||||||
@ -529,6 +533,7 @@ enum att_type {
|
|||||||
att_procedure_entrypoint,
|
att_procedure_entrypoint,
|
||||||
att_procedure_package_name,
|
att_procedure_package_name,
|
||||||
att_procedure_private_flag,
|
att_procedure_private_flag,
|
||||||
|
att_procedure_sql_security_deprecated, // can be removed later
|
||||||
att_procedure_sql_security,
|
att_procedure_sql_security,
|
||||||
|
|
||||||
// Stored procedure parameter attributes
|
// Stored procedure parameter attributes
|
||||||
@ -630,6 +635,7 @@ enum att_type {
|
|||||||
att_package_security_class,
|
att_package_security_class,
|
||||||
att_package_owner_name,
|
att_package_owner_name,
|
||||||
att_package_description,
|
att_package_description,
|
||||||
|
att_package_sql_security_deprecated, // can be removed later
|
||||||
att_package_sql_security,
|
att_package_sql_security,
|
||||||
|
|
||||||
// Database creators
|
// Database creators
|
||||||
|
@ -134,7 +134,7 @@ static ULONG unzip_read_block(BurpGlobals*, UCHAR*, FB_SIZE_T);
|
|||||||
// Portion of data passed to crypt plugin
|
// Portion of data passed to crypt plugin
|
||||||
const ULONG CRYPT_STEP = 256;
|
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:
|
public:
|
||||||
DbInfo(BurpGlobals* bg)
|
DbInfo(BurpGlobals* bg)
|
||||||
|
@ -192,8 +192,13 @@ static inline UCHAR get(BurpGlobals* tdgbl)
|
|||||||
return tdgbl->get();
|
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;
|
return get(tdgbl) ? FB_TRUE : FB_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5142,10 +5147,11 @@ bool get_function(BurpGlobals* tdgbl)
|
|||||||
bad_attribute(scan_next_attr, attribute, 89);
|
bad_attribute(scan_next_attr, attribute, 89);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case att_function_sql_security_deprecated:
|
||||||
case att_function_sql_security:
|
case att_function_sql_security:
|
||||||
if (tdgbl->RESTORE_format >= 11)
|
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;
|
X.RDB$SQL_SECURITY.NULL = FALSE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -5274,9 +5280,10 @@ bool get_function(BurpGlobals* tdgbl)
|
|||||||
bad_attribute(scan_next_attr, attribute, 89);
|
bad_attribute(scan_next_attr, attribute, 89);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case att_function_sql_security_deprecated:
|
||||||
case att_function_sql_security:
|
case att_function_sql_security:
|
||||||
if (tdgbl->RESTORE_format >= 11)
|
if (tdgbl->RESTORE_format >= 11)
|
||||||
get_boolean(tdgbl);
|
get_boolean(tdgbl, attribute == att_function_sql_security_deprecated);
|
||||||
else
|
else
|
||||||
bad_attribute(scan_next_attr, attribute, 89);
|
bad_attribute(scan_next_attr, attribute, 89);
|
||||||
break;
|
break;
|
||||||
@ -7417,10 +7424,11 @@ bool get_package(BurpGlobals* tdgbl)
|
|||||||
X.RDB$DESCRIPTION.NULL = FALSE;
|
X.RDB$DESCRIPTION.NULL = FALSE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case att_package_sql_security_deprecated:
|
||||||
case att_package_sql_security:
|
case att_package_sql_security:
|
||||||
if (tdgbl->RESTORE_format >= 11)
|
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;
|
X.RDB$SQL_SECURITY.NULL = FALSE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -7634,10 +7642,11 @@ bool get_procedure(BurpGlobals* tdgbl)
|
|||||||
bad_attribute(scan_next_attr, attribute, 290);
|
bad_attribute(scan_next_attr, attribute, 290);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case att_procedure_sql_security_deprecated:
|
||||||
case att_procedure_sql_security:
|
case att_procedure_sql_security:
|
||||||
if (tdgbl->RESTORE_format >= 11)
|
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;
|
X.RDB$SQL_SECURITY.NULL = FALSE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -7759,9 +7768,10 @@ bool get_procedure(BurpGlobals* tdgbl)
|
|||||||
bad_attribute(scan_next_attr, attribute, 290);
|
bad_attribute(scan_next_attr, attribute, 290);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case att_procedure_sql_security_deprecated:
|
||||||
case att_procedure_sql_security:
|
case att_procedure_sql_security:
|
||||||
if (tdgbl->RESTORE_format >= 11)
|
if (tdgbl->RESTORE_format >= 11)
|
||||||
get_boolean(tdgbl);
|
get_boolean(tdgbl, attribute == att_procedure_sql_security_deprecated);
|
||||||
else
|
else
|
||||||
bad_attribute(scan_next_attr, attribute, 290);
|
bad_attribute(scan_next_attr, attribute, 290);
|
||||||
break;
|
break;
|
||||||
@ -8443,9 +8453,10 @@ bool get_relation(BurpGlobals* tdgbl)
|
|||||||
bad_attribute(scan_next_attr, attribute, 111);
|
bad_attribute(scan_next_attr, attribute, 111);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case att_relation_sql_security_deprecated:
|
||||||
case att_relation_sql_security:
|
case att_relation_sql_security:
|
||||||
sql_security_null = false;
|
sql_security_null = false;
|
||||||
sql_security = get_boolean(tdgbl);
|
sql_security = get_boolean(tdgbl, attribute == att_relation_sql_security_deprecated);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -9784,10 +9795,11 @@ bool get_trigger(BurpGlobals* tdgbl)
|
|||||||
bad_attribute(scan_next_attr, attribute, 134);
|
bad_attribute(scan_next_attr, attribute, 134);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case att_trig_sql_security_deprecated:
|
||||||
case att_trig_sql_security:
|
case att_trig_sql_security:
|
||||||
if (tdgbl->RESTORE_format >= 11)
|
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;
|
X.RDB$SQL_SECURITY.NULL = FALSE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -9930,9 +9942,10 @@ bool get_trigger(BurpGlobals* tdgbl)
|
|||||||
bad_attribute(scan_next_attr, attribute, 134);
|
bad_attribute(scan_next_attr, attribute, 134);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case att_trig_sql_security_deprecated:
|
||||||
case att_trig_sql_security:
|
case att_trig_sql_security:
|
||||||
if (tdgbl->RESTORE_format >= 11)
|
if (tdgbl->RESTORE_format >= 11)
|
||||||
get_boolean(tdgbl);
|
get_boolean(tdgbl, attribute == att_trig_sql_security_deprecated);
|
||||||
else
|
else
|
||||||
bad_attribute(scan_next_attr, attribute, 134);
|
bad_attribute(scan_next_attr, attribute, 134);
|
||||||
break;
|
break;
|
||||||
@ -10226,6 +10239,8 @@ bool get_user_privilege(BurpGlobals* tdgbl)
|
|||||||
case att_priv_obj_type:
|
case att_priv_obj_type:
|
||||||
flags |= USER_PRIV_OBJECT_TYPE;
|
flags |= USER_PRIV_OBJECT_TYPE;
|
||||||
object_type = (USHORT) get_int32(tdgbl);
|
object_type = (USHORT) get_int32(tdgbl);
|
||||||
|
if ( (tdgbl->RESTORE_format < 11) && (object_type > 19) ) // FB 4 has a shift :(
|
||||||
|
object_type++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -10297,9 +10312,6 @@ bool get_user_privilege(BurpGlobals* tdgbl)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case obj_database:
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
exists = true;
|
exists = true;
|
||||||
break;
|
break;
|
||||||
@ -11009,6 +11021,7 @@ bool restore(BurpGlobals* tdgbl, Firebird::IProvider* provider, const TEXT* file
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case att_database_sql_security_deprecated:
|
||||||
case att_database_sql_security:
|
case att_database_sql_security:
|
||||||
if (tdgbl->RESTORE_format >= 11)
|
if (tdgbl->RESTORE_format >= 11)
|
||||||
{
|
{
|
||||||
@ -11017,7 +11030,7 @@ bool restore(BurpGlobals* tdgbl, Firebird::IProvider* provider, const TEXT* file
|
|||||||
FOR (REQUEST_HANDLE req_handle5)
|
FOR (REQUEST_HANDLE req_handle5)
|
||||||
X IN RDB$DATABASE
|
X IN RDB$DATABASE
|
||||||
MODIFY X USING
|
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;
|
END_MODIFY;
|
||||||
ON_ERROR
|
ON_ERROR
|
||||||
general_on_error();
|
general_on_error();
|
||||||
@ -11028,7 +11041,7 @@ bool restore(BurpGlobals* tdgbl, Firebird::IProvider* provider, const TEXT* file
|
|||||||
END_ERROR;
|
END_ERROR;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
get_boolean(tdgbl);
|
get_boolean(tdgbl, attribute == att_database_sql_security_deprecated);
|
||||||
}
|
}
|
||||||
else
|
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,
|
bool IntlUtil::setupIcuAttributes(charset* cs, const string& specificAttributes,
|
||||||
const string& configInfo, string& newSpecificAttributes)
|
const string& configInfo, string& newSpecificAttributes)
|
||||||
{
|
{
|
||||||
@ -681,10 +681,19 @@ bool IntlUtil::setupIcuAttributes(charset* cs, const string& specificAttributes,
|
|||||||
map.get("ICU-VERSION", icuVersion);
|
map.get("ICU-VERSION", icuVersion);
|
||||||
|
|
||||||
string collVersion;
|
string collVersion;
|
||||||
if (!UnicodeUtil::getCollVersion(icuVersion, configInfo, collVersion))
|
auto icu = UnicodeUtil::getCollVersion(icuVersion, configInfo, collVersion);
|
||||||
|
|
||||||
|
if (!icu)
|
||||||
return false;
|
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");
|
map.remove("COLL-VERSION");
|
||||||
|
|
||||||
if (collVersion.hasData())
|
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)
|
static void unicodeDestroy(texttype* tt)
|
||||||
{
|
{
|
||||||
delete[] const_cast<ASCII*>(tt->texttype_name);
|
delete[] const_cast<ASCII*>(tt->texttype_name);
|
||||||
|
@ -94,7 +94,6 @@ public:
|
|||||||
|
|
||||||
static bool setupIcuAttributes(charset* cs, const string& specificAttributes,
|
static bool setupIcuAttributes(charset* cs, const string& specificAttributes,
|
||||||
const string& configInfo, string& newSpecificAttributes);
|
const string& configInfo, string& newSpecificAttributes);
|
||||||
static void getDefaultCollationAttributes(UCharBuffer& collAttributes, charset& cs);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static string escapeAttribute(Jrd::CharSet* cs, const string& s);
|
static string escapeAttribute(Jrd::CharSet* cs, const string& s);
|
||||||
|
@ -310,7 +310,7 @@ public:
|
|||||||
RefPtr<RefCounted> attachment;
|
RefPtr<RefCounted> attachment;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MetadataBuilder FB_FINAL :
|
class MetadataBuilder final :
|
||||||
public RefCntIface<IMetadataBuilderImpl<MetadataBuilder, CheckStatusWrapper> >
|
public RefCntIface<IMetadataBuilderImpl<MetadataBuilder, CheckStatusWrapper> >
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// The content of this file is generated with help of update-ids utility Do not edit.
|
// 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!
|
// 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[] = {
|
static const char* BUILTIN_TIME_ZONE_LIST[] = {
|
||||||
|
@ -34,7 +34,7 @@ namespace Firebird {
|
|||||||
virtual void transliterate(IStatus* status) = 0;
|
virtual void transliterate(IStatus* status) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class BatchCompletionState FB_FINAL :
|
class BatchCompletionState final :
|
||||||
public DisposeIface<IBatchCompletionStateImpl<BatchCompletionState, CheckStatusWrapper> >
|
public DisposeIface<IBatchCompletionStateImpl<BatchCompletionState, CheckStatusWrapper> >
|
||||||
{
|
{
|
||||||
public:
|
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;
|
virtual void finish(dsc& result) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class WeakHashContext FB_FINAL : public HashContext
|
class WeakHashContext final : public HashContext
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual void update(const void* data, FB_SIZE_T length);
|
virtual void update(const void* data, FB_SIZE_T length);
|
||||||
@ -389,31 +389,31 @@ namespace Firebird
|
|||||||
UCharBuffer buffer;
|
UCharBuffer buffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Md5HashContext FB_FINAL : public LibTomCryptHashContext
|
class Md5HashContext final : public LibTomCryptHashContext
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Md5HashContext(MemoryPool& pool);
|
Md5HashContext(MemoryPool& pool);
|
||||||
};
|
};
|
||||||
|
|
||||||
class Sha1HashContext FB_FINAL : public LibTomCryptHashContext
|
class Sha1HashContext final : public LibTomCryptHashContext
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Sha1HashContext(MemoryPool& pool);
|
Sha1HashContext(MemoryPool& pool);
|
||||||
};
|
};
|
||||||
|
|
||||||
class Sha256HashContext FB_FINAL : public LibTomCryptHashContext
|
class Sha256HashContext final : public LibTomCryptHashContext
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Sha256HashContext(MemoryPool& pool);
|
Sha256HashContext(MemoryPool& pool);
|
||||||
};
|
};
|
||||||
|
|
||||||
class Sha512HashContext FB_FINAL : public LibTomCryptHashContext
|
class Sha512HashContext final : public LibTomCryptHashContext
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Sha512HashContext(MemoryPool& pool);
|
Sha512HashContext(MemoryPool& pool);
|
||||||
};
|
};
|
||||||
|
|
||||||
class Crc32HashContext FB_FINAL : public HashContext
|
class Crc32HashContext final : public HashContext
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Crc32HashContext(MemoryPool& pool);
|
Crc32HashContext(MemoryPool& pool);
|
||||||
|
@ -293,7 +293,7 @@ public:
|
|||||||
// when yvalve is starting fb_shutdown(). This causes almost unavoidable segfault.
|
// when yvalve is starting fb_shutdown(). This causes almost unavoidable segfault.
|
||||||
// To avoid it this class is added - it detects spontaneous (not by PluginManager)
|
// To avoid it this class is added - it detects spontaneous (not by PluginManager)
|
||||||
// module unload and notifies PluginManager about this said fact.
|
// module unload and notifies PluginManager about this said fact.
|
||||||
class UnloadDetectorHelper FB_FINAL :
|
class UnloadDetectorHelper final :
|
||||||
public VersionedIface<IPluginModuleImpl<UnloadDetectorHelper, CheckStatusWrapper> >
|
public VersionedIface<IPluginModuleImpl<UnloadDetectorHelper, CheckStatusWrapper> >
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -1850,6 +1850,11 @@ public:
|
|||||||
// Create memory pool instance
|
// Create memory pool instance
|
||||||
static MemPool* createPool(MemPool* parent, MemoryStats& stats);
|
static MemPool* createPool(MemPool* parent, MemoryStats& stats);
|
||||||
|
|
||||||
|
MemoryStats& getStatsGroup() noexcept
|
||||||
|
{
|
||||||
|
return *stats;
|
||||||
|
}
|
||||||
|
|
||||||
// Set statistics group for pool. Usage counters will be decremented from
|
// Set statistics group for pool. Usage counters will be decremented from
|
||||||
// previously set group and added to new
|
// previously set group and added to new
|
||||||
void setStatsGroup(MemoryStats& stats) noexcept;
|
void setStatsGroup(MemoryStats& stats) noexcept;
|
||||||
@ -2262,6 +2267,11 @@ void MemPool::setStatsGroup(MemoryStats& newStats) noexcept
|
|||||||
stats->increment_usage(sav_used_memory);
|
stats->increment_usage(sav_used_memory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MemoryStats& MemoryPool::getStatsGroup() noexcept
|
||||||
|
{
|
||||||
|
return pool->getStatsGroup();
|
||||||
|
}
|
||||||
|
|
||||||
void MemoryPool::setStatsGroup(MemoryStats& newStats) noexcept
|
void MemoryPool::setStatsGroup(MemoryStats& newStats) noexcept
|
||||||
{
|
{
|
||||||
pool->setStatsGroup(newStats);
|
pool->setStatsGroup(newStats);
|
||||||
|
@ -57,6 +57,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#ifdef DEBUG_GDS_ALLOC
|
#ifdef DEBUG_GDS_ALLOC
|
||||||
#define FB_NEW new(*getDefaultMemoryPool(), __FILE__, __LINE__)
|
#define FB_NEW new(*getDefaultMemoryPool(), __FILE__, __LINE__)
|
||||||
@ -212,6 +213,8 @@ public:
|
|||||||
// Get context pool for current thread of execution
|
// Get context pool for current thread of execution
|
||||||
static MemoryPool* getContextPool();
|
static MemoryPool* getContextPool();
|
||||||
|
|
||||||
|
MemoryStats& getStatsGroup() noexcept;
|
||||||
|
|
||||||
// Set statistics group for pool. Usage counters will be decremented from
|
// Set statistics group for pool. Usage counters will be decremented from
|
||||||
// previously set group and added to new
|
// previously set group and added to new
|
||||||
void setStatsGroup(MemoryStats& stats) noexcept;
|
void setStatsGroup(MemoryStats& stats) noexcept;
|
||||||
@ -456,7 +459,166 @@ namespace Firebird
|
|||||||
|
|
||||||
typedef AutoPtr<MemoryPool> AutoMemoryPool;
|
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
|
} // 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
|
#endif // CLASSES_ALLOC_H
|
||||||
|
@ -110,6 +110,12 @@ public:
|
|||||||
ensureCapacity(InitialCapacity);
|
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)
|
Array(const Array<T, Storage>& source)
|
||||||
: Storage(), count(0), capacity(this->getStorageSize()), data(this->getStorage())
|
: Storage(), count(0), capacity(this->getStorageSize()), data(this->getStorage())
|
||||||
{
|
{
|
||||||
|
@ -483,6 +483,13 @@ namespace Firebird
|
|||||||
ObjectCmp> >()
|
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
|
bool find(const ObjectKey& item, size_type& pos) const
|
||||||
{
|
{
|
||||||
const ObjectKey* const pItem = &item;
|
const ObjectKey* const pItem = &item;
|
||||||
|
@ -230,6 +230,10 @@
|
|||||||
#ifdef ARM
|
#ifdef ARM
|
||||||
#define FB_CPU CpuArm
|
#define FB_CPU CpuArm
|
||||||
#endif /* ARM */
|
#endif /* ARM */
|
||||||
|
#ifdef ARM64
|
||||||
|
#define DARWIN64
|
||||||
|
#define FB_CPU CpuArm64
|
||||||
|
#endif /* ARM64 */
|
||||||
#ifdef __ppc__
|
#ifdef __ppc__
|
||||||
#define powerpc
|
#define powerpc
|
||||||
#define FB_CPU CpuPowerPc
|
#define FB_CPU CpuPowerPc
|
||||||
@ -252,8 +256,6 @@
|
|||||||
|
|
||||||
#define API_ROUTINE __attribute__((visibility("default")))
|
#define API_ROUTINE __attribute__((visibility("default")))
|
||||||
#define API_ROUTINE_VARARG API_ROUTINE
|
#define API_ROUTINE_VARARG API_ROUTINE
|
||||||
#define INTERNAL_API_ROUTINE API_ROUTINE
|
|
||||||
#define FB_EXPORTED __attribute__((visibility("default")))
|
|
||||||
|
|
||||||
#define O_DIRECT F_NOCACHE
|
#define O_DIRECT F_NOCACHE
|
||||||
#endif /* Darwin Platforms */
|
#endif /* Darwin Platforms */
|
||||||
@ -603,10 +605,6 @@ extern "C" int remove(const char* path);
|
|||||||
#define CLIB_ROUTINE
|
#define CLIB_ROUTINE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef FB_EXPORTED
|
|
||||||
#define FB_EXPORTED
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAS_NOEXCEPT
|
#ifdef HAS_NOEXCEPT
|
||||||
#define NOEXCEPT noexcept
|
#define NOEXCEPT noexcept
|
||||||
#define NOEXCEPT_ARG(X) noexcept((X))
|
#define NOEXCEPT_ARG(X) noexcept((X))
|
||||||
@ -886,21 +884,6 @@ void GDS_breakpoint(int);
|
|||||||
#define FB_CONST64(a) (a##LL)
|
#define FB_CONST64(a) (a##LL)
|
||||||
#endif
|
#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(value) do { if (value) {} } while (false)
|
||||||
#define FB_UNUSED_VAR(value) (void) value
|
#define FB_UNUSED_VAR(value) (void) value
|
||||||
|
|
||||||
|
@ -410,6 +410,8 @@ void Config::checkValues()
|
|||||||
checkIntForHiBound(KEY_TIP_CACHE_BLOCK_SIZE, MAX_ULONG, true);
|
checkIntForHiBound(KEY_TIP_CACHE_BLOCK_SIZE, MAX_ULONG, true);
|
||||||
|
|
||||||
checkIntForLoBound(KEY_INLINE_SORT_THRESHOLD, 0, 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_DEADLOCK_TIMEOUT,
|
||||||
KEY_REMOTE_SERVICE_NAME,
|
KEY_REMOTE_SERVICE_NAME,
|
||||||
KEY_REMOTE_SERVICE_PORT,
|
KEY_REMOTE_SERVICE_PORT,
|
||||||
KEY_REMOTE_PIPE_NAME,
|
|
||||||
KEY_IPC_NAME,
|
KEY_IPC_NAME,
|
||||||
KEY_MAX_UNFLUSHED_WRITES,
|
KEY_MAX_UNFLUSHED_WRITES,
|
||||||
KEY_MAX_UNFLUSHED_WRITE_TIME,
|
KEY_MAX_UNFLUSHED_WRITE_TIME,
|
||||||
@ -177,6 +176,7 @@ enum ConfigKey
|
|||||||
KEY_ENCRYPT_SECURITY_DATABASE,
|
KEY_ENCRYPT_SECURITY_DATABASE,
|
||||||
KEY_STMT_TIMEOUT,
|
KEY_STMT_TIMEOUT,
|
||||||
KEY_CONN_IDLE_TIMEOUT,
|
KEY_CONN_IDLE_TIMEOUT,
|
||||||
|
KEY_ON_DISCONNECT_TRIG_TIMEOUT,
|
||||||
KEY_CLIENT_BATCH_BUFFER,
|
KEY_CLIENT_BATCH_BUFFER,
|
||||||
KEY_OUTPUT_REDIRECTION_FILE,
|
KEY_OUTPUT_REDIRECTION_FILE,
|
||||||
KEY_EXT_CONN_POOL_SIZE,
|
KEY_EXT_CONN_POOL_SIZE,
|
||||||
@ -189,6 +189,7 @@ enum ConfigKey
|
|||||||
KEY_USE_FILESYSTEM_CACHE,
|
KEY_USE_FILESYSTEM_CACHE,
|
||||||
KEY_INLINE_SORT_THRESHOLD,
|
KEY_INLINE_SORT_THRESHOLD,
|
||||||
KEY_TEMP_PAGESPACE_DIR,
|
KEY_TEMP_PAGESPACE_DIR,
|
||||||
|
KEY_MAX_STATEMENT_CACHE_SIZE,
|
||||||
MAX_CONFIG_KEY // keep it last
|
MAX_CONFIG_KEY // keep it last
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -232,7 +233,6 @@ constexpr ConfigEntry entries[MAX_CONFIG_KEY] =
|
|||||||
{TYPE_INTEGER, "DeadlockTimeout", false, 10}, // seconds
|
{TYPE_INTEGER, "DeadlockTimeout", false, 10}, // seconds
|
||||||
{TYPE_STRING, "RemoteServiceName", false, FB_SERVICE_NAME},
|
{TYPE_STRING, "RemoteServiceName", false, FB_SERVICE_NAME},
|
||||||
{TYPE_INTEGER, "RemoteServicePort", false, 0},
|
{TYPE_INTEGER, "RemoteServicePort", false, 0},
|
||||||
{TYPE_STRING, "RemotePipeName", false, FB_PIPE_NAME},
|
|
||||||
{TYPE_STRING, "IpcName", false, FB_IPC_NAME},
|
{TYPE_STRING, "IpcName", false, FB_IPC_NAME},
|
||||||
#ifdef WIN_NT
|
#ifdef WIN_NT
|
||||||
{TYPE_INTEGER, "MaxUnflushedWrites", false, 100},
|
{TYPE_INTEGER, "MaxUnflushedWrites", false, 100},
|
||||||
@ -285,6 +285,7 @@ constexpr ConfigEntry entries[MAX_CONFIG_KEY] =
|
|||||||
{TYPE_BOOLEAN, "AllowEncryptedSecurityDatabase", false, false},
|
{TYPE_BOOLEAN, "AllowEncryptedSecurityDatabase", false, false},
|
||||||
{TYPE_INTEGER, "StatementTimeout", false, 0},
|
{TYPE_INTEGER, "StatementTimeout", false, 0},
|
||||||
{TYPE_INTEGER, "ConnectionIdleTimeout", false, 0},
|
{TYPE_INTEGER, "ConnectionIdleTimeout", false, 0},
|
||||||
|
{TYPE_INTEGER, "OnDisconnectTriggerTimeout", false, 180},
|
||||||
{TYPE_INTEGER, "ClientBatchBuffer", false, 128 * 1024},
|
{TYPE_INTEGER, "ClientBatchBuffer", false, 128 * 1024},
|
||||||
#ifdef DEV_BUILD
|
#ifdef DEV_BUILD
|
||||||
{TYPE_STRING, "OutputRedirectionFile", true, "-"},
|
{TYPE_STRING, "OutputRedirectionFile", true, "-"},
|
||||||
@ -304,7 +305,8 @@ constexpr ConfigEntry entries[MAX_CONFIG_KEY] =
|
|||||||
{TYPE_STRING, "DataTypeCompatibility", false, nullptr},
|
{TYPE_STRING, "DataTypeCompatibility", false, nullptr},
|
||||||
{TYPE_BOOLEAN, "UseFileSystemCache", false, true},
|
{TYPE_BOOLEAN, "UseFileSystemCache", false, true},
|
||||||
{TYPE_INTEGER, "InlineSortThreshold", false, 1000}, // bytes
|
{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
|
// Service port for INET
|
||||||
CONFIG_GET_PER_DB_KEY(unsigned short, getRemoteServicePort, KEY_REMOTE_SERVICE_PORT, getInt);
|
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
|
// Name for IPC-related objects
|
||||||
CONFIG_GET_PER_DB_STR(getIpcName, KEY_IPC_NAME);
|
CONFIG_GET_PER_DB_STR(getIpcName, KEY_IPC_NAME);
|
||||||
|
|
||||||
@ -606,6 +605,9 @@ public:
|
|||||||
// set in minutes
|
// set in minutes
|
||||||
CONFIG_GET_PER_DB_KEY(unsigned int, getConnIdleTimeout, KEY_CONN_IDLE_TIMEOUT, getInt);
|
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_PER_DB_KEY(unsigned int, getClientBatchBuffer, KEY_CLIENT_BATCH_BUFFER, getInt);
|
||||||
|
|
||||||
CONFIG_GET_GLOBAL_STR(getOutputRedirectionFile, KEY_OUTPUT_REDIRECTION_FILE);
|
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_KEY(ULONG, getInlineSortThreshold, KEY_INLINE_SORT_THRESHOLD, getInt);
|
||||||
|
|
||||||
CONFIG_GET_PER_DB_STR(getTempPageSpaceDirectory, KEY_TEMP_PAGESPACE_DIR);
|
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
|
// Implementation of interface to access master configuration file
|
||||||
class FirebirdConf FB_FINAL :
|
class FirebirdConf final :
|
||||||
public RefCntIface<IFirebirdConfImpl<FirebirdConf, CheckStatusWrapper> >
|
public RefCntIface<IFirebirdConfImpl<FirebirdConf, CheckStatusWrapper> >
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -81,7 +81,7 @@ public:
|
|||||||
sub(par.sub), line(par.line)
|
sub(par.sub), line(par.line)
|
||||||
{ }
|
{ }
|
||||||
Parameter()
|
Parameter()
|
||||||
: AutoStorage(), name(getPool()), value(getPool()), sub(0), line(0)
|
: AutoStorage(), name(getPool()), value(getPool()), line(0)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
SINT64 asInteger() const;
|
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_SORT 0 /* Full sort key */
|
||||||
#define INTL_KEY_PARTIAL 1 /* Starting portion of sort key for equality class */
|
#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_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
|
/* Returned value of INTL_BAD_KEY_LENGTH means that key error happened during
|
||||||
key construction. When partial key is requested returned string should
|
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,
|
(char, case, accent) which is case-insensitive,
|
||||||
but accent-sensitive */
|
but accent-sensitive */
|
||||||
|
|
||||||
|
#define TEXTTYPE_MULTI_STARTING_KEY 8 /* Supports INTL_KEY_MULTI_STARTING */
|
||||||
|
|
||||||
|
|
||||||
struct texttype
|
struct texttype
|
||||||
{
|
{
|
||||||
@ -346,6 +354,20 @@ typedef INTL_BOOL (*pfn_INTL_lookup_texttype) (
|
|||||||
const ASCII* config_info
|
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 for charset lookup entry-point */
|
||||||
typedef INTL_BOOL (*pfn_INTL_lookup_charset) (
|
typedef INTL_BOOL (*pfn_INTL_lookup_charset) (
|
||||||
charset* cs,
|
charset* cs,
|
||||||
@ -371,6 +393,7 @@ typedef ULONG (*pfn_INTL_setup_attributes) (
|
|||||||
|
|
||||||
|
|
||||||
#define TEXTTYPE_ENTRYPOINT LD_lookup_texttype
|
#define TEXTTYPE_ENTRYPOINT LD_lookup_texttype
|
||||||
|
#define TEXTTYPE_WITH_STATUS_ENTRYPOINT LD_lookup_texttype_with_status
|
||||||
#define CHARSET_ENTRYPOINT LD_lookup_charset
|
#define CHARSET_ENTRYPOINT LD_lookup_charset
|
||||||
#define INTL_VERSION_ENTRYPOINT LD_version
|
#define INTL_VERSION_ENTRYPOINT LD_version
|
||||||
#define INTL_SETUP_ATTRIBUTES_ENTRYPOINT LD_setup_attributes
|
#define INTL_SETUP_ATTRIBUTES_ENTRYPOINT LD_setup_attributes
|
||||||
|
@ -30,13 +30,15 @@
|
|||||||
#include "../common/classes/fb_string.h"
|
#include "../common/classes/fb_string.h"
|
||||||
#include "../common/common.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
|
#ifndef NO_NFS
|
||||||
bool ISC_analyze_nfs(Firebird::PathName&, Firebird::PathName&);
|
bool ISC_analyze_nfs(Firebird::PathName&, Firebird::PathName&);
|
||||||
#endif
|
#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&);
|
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_analyze_tcp(Firebird::PathName&, Firebird::PathName&, bool = true);
|
||||||
bool ISC_check_if_remote(const Firebird::PathName&, bool);
|
bool ISC_check_if_remote(const Firebird::PathName&, bool);
|
||||||
iscProtocol ISC_extract_host(Firebird::PathName&, 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
|
#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,
|
bool ISC_analyze_protocol(const char* protocol, tstring& expanded_name, tstring& node_name,
|
||||||
const char* separator, bool need_file)
|
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)
|
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
|
// Always check for an explicit TCP node name
|
||||||
|
|
||||||
if (ISC_analyze_tcp(file_name, host_name))
|
if (ISC_analyze_tcp(file_name, host_name))
|
||||||
{
|
|
||||||
return ISC_PROTOCOL_TCPIP;
|
return ISC_PROTOCOL_TCPIP;
|
||||||
}
|
|
||||||
#ifndef NO_NFS
|
|
||||||
if (implicit_flag)
|
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;
|
return ISC_PROTOCOL_TCPIP;
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(WIN_NT)
|
#ifndef NO_NFS
|
||||||
// Check for an explicit named pipe node name
|
if (ISC_analyze_nfs(file_name, host_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))
|
|
||||||
{
|
|
||||||
return ISC_PROTOCOL_TCPIP;
|
return ISC_PROTOCOL_TCPIP;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
if (ISC_analyze_pclan(file_name, host_name))
|
|
||||||
{
|
|
||||||
return ISC_PROTOCOL_WLAN;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif // WIN_NT
|
|
||||||
|
|
||||||
return ISC_PROTOCOL_LOCAL;
|
return ISC_PROTOCOL_LOCAL;
|
||||||
}
|
}
|
||||||
|
@ -73,7 +73,7 @@ public:
|
|||||||
const Firebird::PathName fileName;
|
const Firebird::PathName fileName;
|
||||||
|
|
||||||
#ifdef LINUX
|
#ifdef LINUX
|
||||||
virtual bool getRealPath(Firebird::PathName& realPath) = 0;
|
virtual bool getRealPath(Firebird::PathName& path) = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -46,18 +46,16 @@
|
|||||||
class DlfcnModule : public ModuleLoader::Module
|
class DlfcnModule : public ModuleLoader::Module
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DlfcnModule(MemoryPool& pool, const Firebird::PathName& aFileName, void* m)
|
DlfcnModule(MemoryPool& pool, const Firebird::PathName& aFileName, void* m);
|
||||||
: ModuleLoader::Module(pool, aFileName),
|
|
||||||
module(m)
|
|
||||||
{}
|
|
||||||
|
|
||||||
~DlfcnModule();
|
~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:
|
private:
|
||||||
void* module;
|
void* module;
|
||||||
|
Firebird::PathName realPath;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void makeErrorStatus(ISC_STATUS* status, const char* text)
|
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);
|
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()
|
DlfcnModule::~DlfcnModule()
|
||||||
{
|
{
|
||||||
if (module)
|
if (module)
|
||||||
@ -165,7 +204,7 @@ void* DlfcnModule::findSymbol(ISC_STATUS* status, const Firebird::string& symNam
|
|||||||
void* result = dlsym(module, symName.c_str());
|
void* result = dlsym(module, symName.c_str());
|
||||||
if (!result)
|
if (!result)
|
||||||
{
|
{
|
||||||
Firebird::string newSym ='_' + symName;
|
Firebird::string newSym = '_' + symName;
|
||||||
result = dlsym(module, newSym.c_str());
|
result = dlsym(module, newSym.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,20 +222,28 @@ void* DlfcnModule::findSymbol(ISC_STATUS* status, const Firebird::string& symNam
|
|||||||
return NULL;
|
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";
|
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
|
// check only name (not path) of the library
|
||||||
Firebird::PathName dummyDir, nm1, nm2;
|
Firebird::PathName dummyDir, nm1, nm2;
|
||||||
PathUtils::splitLastComponent(dummyDir, nm1, fileName);
|
PathUtils::splitLastComponent(dummyDir, nm1, libraryPath);
|
||||||
PathUtils::splitLastComponent(dummyDir, nm2, info.dli_fname);
|
PathUtils::splitLastComponent(dummyDir, nm2, symbolPath);
|
||||||
if (nm1 != nm2)
|
if (nm1 != nm2)
|
||||||
{
|
{
|
||||||
makeErrorStatus(status, errText);
|
makeErrorStatus(status, errText);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (fileName != info.dli_fname)
|
else if (libraryPath != symbolPath)
|
||||||
{
|
{
|
||||||
makeErrorStatus(status, errText);
|
makeErrorStatus(status, errText);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -206,38 +253,11 @@ void* DlfcnModule::findSymbol(ISC_STATUS* status, const Firebird::string& symNam
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DlfcnModule::getRealPath(Firebird::PathName& realPath)
|
bool DlfcnModule::getRealPath(Firebird::PathName& path)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_DLINFO
|
if (realPath.isEmpty())
|
||||||
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
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
path = realPath;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -87,26 +87,34 @@ public:
|
|||||||
memset(&ackd, 0, sizeof(ackd));
|
memset(&ackd, 0, sizeof(ackd));
|
||||||
ackd.cbSize = 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 CRT already present in some activation context then nothing to do
|
||||||
if ((*mFindActCtxSectionString)
|
if ((*mFindActCtxSectionString)
|
||||||
(0, NULL,
|
(0, NULL,
|
||||||
ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION,
|
ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION,
|
||||||
#if _MSC_VER == 1400
|
crtDll, &ackd))
|
||||||
"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))
|
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -232,7 +232,7 @@ public:
|
|||||||
IntField u, g;
|
IntField u, g;
|
||||||
};
|
};
|
||||||
|
|
||||||
class StackUserData FB_FINAL : public UserData
|
class StackUserData final : public UserData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void* operator new(size_t, void* memory) throw()
|
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:
|
public:
|
||||||
#ifdef DEBUG_GDS_ALLOC
|
#ifdef DEBUG_GDS_ALLOC
|
||||||
|
@ -92,22 +92,24 @@ public:
|
|||||||
// System-wide ICU have no version number at entries names
|
// System-wide ICU have no version number at entries names
|
||||||
if (!majorVersion)
|
if (!majorVersion)
|
||||||
{
|
{
|
||||||
|
fb_assert(false); // ASF: I don't think this code path is correct.
|
||||||
|
|
||||||
if (module->findSymbol(NULL, name, ptr))
|
if (module->findSymbol(NULL, name, ptr))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// ICU has several schemas for entries names
|
// 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;
|
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))
|
if (module->findSymbol(NULL, symbol, ptr))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -272,8 +274,10 @@ public:
|
|||||||
USet* (U_EXPORT2 *usetOpen)(UChar32 start, UChar32 end);
|
USet* (U_EXPORT2 *usetOpen)(UChar32 start, UChar32 end);
|
||||||
|
|
||||||
void (U_EXPORT2 *ucolClose)(UCollator* coll);
|
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);
|
const UChar* (U_EXPORT2 *ucolGetRules)(const UCollator* coll, int32_t* length);
|
||||||
|
|
||||||
int32_t (U_EXPORT2 *ucolGetSortKey)(const UCollator* coll, const UChar* source,
|
int32_t (U_EXPORT2 *ucolGetSortKey)(const UCollator* coll, const UChar* source,
|
||||||
int32_t sourceLength, uint8_t* result, int32_t resultLength);
|
int32_t sourceLength, uint8_t* result, int32_t resultLength);
|
||||||
UCollator* (U_EXPORT2 *ucolOpen)(const char* loc, UErrorCode* status);
|
UCollator* (U_EXPORT2 *ucolOpen)(const char* loc, UErrorCode* status);
|
||||||
@ -321,6 +325,7 @@ private:
|
|||||||
getEntryPoint("ucnv_open", module, ucnv_open);
|
getEntryPoint("ucnv_open", module, ucnv_open);
|
||||||
getEntryPoint("ucnv_close", module, ucnv_close);
|
getEntryPoint("ucnv_close", module, ucnv_close);
|
||||||
getEntryPoint("ucnv_fromUChars", module, ucnv_fromUChars);
|
getEntryPoint("ucnv_fromUChars", module, ucnv_fromUChars);
|
||||||
|
getEntryPoint("u_getVersion", module, u_getVersion);
|
||||||
getEntryPoint("u_tolower", module, u_tolower);
|
getEntryPoint("u_tolower", module, u_tolower);
|
||||||
getEntryPoint("u_toupper", module, u_toupper);
|
getEntryPoint("u_toupper", module, u_toupper);
|
||||||
getEntryPoint("u_strCompare", module, u_strCompare);
|
getEntryPoint("u_strCompare", module, u_strCompare);
|
||||||
@ -379,8 +384,11 @@ public:
|
|||||||
|
|
||||||
if (o)
|
if (o)
|
||||||
{
|
{
|
||||||
o->vMajor = majorVersion;
|
UVersionInfo versionInfo;
|
||||||
o->vMinor = minorVersion;
|
o->u_getVersion(versionInfo);
|
||||||
|
|
||||||
|
o->vMajor = versionInfo[0];
|
||||||
|
o->vMinor = versionInfo[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
return o;
|
return o;
|
||||||
@ -507,15 +515,20 @@ static ModuleLoader::Module* formatAndLoad(const char* templateName,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// ICU has several schemas for placing version into file name
|
// 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;
|
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());
|
filename.printf(templateName, s.c_str());
|
||||||
|
|
||||||
module = ModuleLoader::fixAndLoadModule(NULL, filename);
|
module = ModuleLoader::fixAndLoadModule(NULL, filename);
|
||||||
@ -523,7 +536,9 @@ static ModuleLoader::Module* formatAndLoad(const char* templateName,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef WIN_NT
|
||||||
// There is no sence to try pattern "%d" for different minor versions
|
// 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)
|
if (!module && minorVersion == 0)
|
||||||
{
|
{
|
||||||
s.printf("%d", majorVersion);
|
s.printf("%d", majorVersion);
|
||||||
@ -531,6 +546,7 @@ static ModuleLoader::Module* formatAndLoad(const char* templateName,
|
|||||||
|
|
||||||
module = ModuleLoader::fixAndLoadModule(NULL, filename);
|
module = ModuleLoader::fixAndLoadModule(NULL, filename);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return module;
|
return module;
|
||||||
@ -1169,7 +1185,7 @@ UnicodeUtil::ICU* UnicodeUtil::loadICU(const string& icuVersion, const string& c
|
|||||||
getVersions(configInfo, versions);
|
getVersions(configInfo, versions);
|
||||||
|
|
||||||
if (versions.isEmpty())
|
if (versions.isEmpty())
|
||||||
gds__log("No versions");
|
gds__log("No ICU versions specified");
|
||||||
|
|
||||||
string version = icuVersion.isEmpty() ? versions[0] : icuVersion;
|
string version = icuVersion.isEmpty() ? versions[0] : icuVersion;
|
||||||
if (version == "default")
|
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("uset_open", icu->ucModule, icu->usetOpen);
|
||||||
|
|
||||||
icu->getEntryPoint("ucol_close", icu->inModule, icu->ucolClose);
|
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_getRules", icu->inModule, icu->ucolGetRules);
|
||||||
icu->getEntryPoint("ucol_getSortKey", icu->inModule, icu->ucolGetSortKey);
|
icu->getEntryPoint("ucol_getSortKey", icu->inModule, icu->ucolGetSortKey);
|
||||||
icu->getEntryPoint("ucol_open", icu->inModule, icu->ucolOpen);
|
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()
|
UnicodeUtil::ConversionICU& UnicodeUtil::getConversionICU()
|
||||||
{
|
{
|
||||||
if (convIcu)
|
if (convIcu)
|
||||||
@ -1311,7 +1335,7 @@ UnicodeUtil::ConversionICU& UnicodeUtil::getConversionICU()
|
|||||||
|
|
||||||
// Try "favorite" (distributed on windows) version first
|
// Try "favorite" (distributed on windows) version first
|
||||||
const int favMaj = 63;
|
const int favMaj = 63;
|
||||||
const int favMin = 0;
|
const int favMin = 1;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if ((convIcu = ImplementConversionICU::create(favMaj, favMin)))
|
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)
|
const Firebird::string& configInfo, Firebird::string& collVersion)
|
||||||
{
|
{
|
||||||
ICU* icu = loadICU(icuVersion, configInfo);
|
ICU* icu = loadICU(icuVersion, configInfo);
|
||||||
|
|
||||||
if (!icu)
|
if (!icu)
|
||||||
return false;
|
return nullptr;
|
||||||
|
|
||||||
char version[U_MAX_VERSION_STRING_LENGTH];
|
char version[U_MAX_VERSION_STRING_LENGTH];
|
||||||
icu->uVersionToString(icu->collVersion, version);
|
icu->uVersionToString(icu->collVersion, version);
|
||||||
@ -1424,7 +1448,7 @@ bool UnicodeUtil::getCollVersion(const Firebird::string& icuVersion,
|
|||||||
else
|
else
|
||||||
collVersion = version;
|
collVersion = version;
|
||||||
|
|
||||||
return true;
|
return icu;
|
||||||
}
|
}
|
||||||
|
|
||||||
UnicodeUtil::Utf16Collation* UnicodeUtil::Utf16Collation::create(
|
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;
|
tt->texttype_pad_option = (attributes & TEXTTYPE_ATTR_PAD_SPACE) ? true : false;
|
||||||
|
|
||||||
ICU* icu = loadICU(collVersion, locale, configInfo);
|
string icuVersion;
|
||||||
if (!icu)
|
if (specificAttributes.get(IntlUtil::convertAsciiToUtf16("ICU-VERSION"), icuVersion))
|
||||||
{
|
icuVersion = IntlUtil::convertUtf16ToAscii(icuVersion, &error);
|
||||||
gds__log("loadICU failed");
|
|
||||||
return NULL;
|
const auto icu = loadICU(icuVersion, collVersion, locale, configInfo);
|
||||||
}
|
|
||||||
|
|
||||||
UErrorCode status = U_ZERO_ERROR;
|
UErrorCode status = U_ZERO_ERROR;
|
||||||
HalfStaticArray<UChar, BUFFER_TINY> rulesBuffer;
|
HalfStaticArray<UChar, BUFFER_TINY> rulesBuffer;
|
||||||
@ -1617,35 +1640,145 @@ UnicodeUtil::Utf16Collation* UnicodeUtil::Utf16Collation::create(
|
|||||||
|
|
||||||
USet* contractions = icu->usetOpen(1, 0);
|
USet* contractions = icu->usetOpen(1, 0);
|
||||||
// status not verified here.
|
// status not verified here.
|
||||||
icu->ucolGetContractions(partialCollator, contractions, &status);
|
icu->ucolGetContractionsAndExpansions(partialCollator, contractions, nullptr, false, &status);
|
||||||
|
|
||||||
int contractionsCount = icu->usetGetItemCount(contractions);
|
int contractionsCount = icu->usetGetItemCount(contractions);
|
||||||
|
|
||||||
for (int contractionIndex = 0; contractionIndex < contractionsCount; ++contractionIndex)
|
for (int contractionIndex = 0; contractionIndex < contractionsCount; ++contractionIndex)
|
||||||
{
|
{
|
||||||
UChar str[10];
|
UChar strChars[10];
|
||||||
UChar32 start, end;
|
UChar32 start, end;
|
||||||
|
|
||||||
status = U_ZERO_ERROR;
|
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)
|
if (len >= 2)
|
||||||
{
|
{
|
||||||
obj->maxContractionsPrefixLength = len - 1 > obj->maxContractionsPrefixLength ?
|
obj->maxContractionsPrefixLength = len - 1 > obj->maxContractionsPrefixLength ?
|
||||||
len - 1 : obj->maxContractionsPrefixLength;
|
len - 1 : obj->maxContractionsPrefixLength;
|
||||||
|
|
||||||
for (int currentLen = 1; currentLen < len; ++currentLen)
|
UCHAR key[100];
|
||||||
{
|
int keyLen = icu->ucolGetSortKey(partialCollator, strChars, len, key, sizeof(key));
|
||||||
string s(reinterpret_cast<const char*>(str), currentLen * 2);
|
|
||||||
|
|
||||||
if (!obj->contractionsPrefix.exist(s))
|
for (int prefixLen = 1; prefixLen < len; ++prefixLen)
|
||||||
obj->contractionsPrefix.push(s);
|
{
|
||||||
|
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);
|
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;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1696,41 +1829,17 @@ USHORT UnicodeUtil::Utf16Collation::stringToKey(USHORT srcLen, const USHORT* src
|
|||||||
srcLenLong = pad - src + 1;
|
srcLenLong = pad - src + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (srcLenLong == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
HalfStaticArray<USHORT, BUFFER_SMALL / 2> buffer;
|
HalfStaticArray<USHORT, BUFFER_SMALL / 2> buffer;
|
||||||
const UCollator* coll = NULL;
|
const UCollator* coll = NULL;
|
||||||
|
|
||||||
switch (key_type)
|
switch (key_type)
|
||||||
{
|
{
|
||||||
case INTL_KEY_PARTIAL:
|
case INTL_KEY_PARTIAL:
|
||||||
|
case INTL_KEY_MULTI_STARTING:
|
||||||
coll = partialCollator;
|
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;
|
break;
|
||||||
|
|
||||||
case INTL_KEY_UNIQUE:
|
case INTL_KEY_UNIQUE:
|
||||||
@ -1749,11 +1858,100 @@ USHORT UnicodeUtil::Utf16Collation::stringToKey(USHORT srcLen, const USHORT* src
|
|||||||
return INTL_BAD_KEY_LENGTH;
|
return INTL_BAD_KEY_LENGTH;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (srcLenLong == 0)
|
if (key_type == INTL_KEY_MULTI_STARTING)
|
||||||
return 0;
|
{
|
||||||
|
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);
|
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(
|
UnicodeUtil::ICU* UnicodeUtil::Utf16Collation::loadICU(
|
||||||
const Firebird::string& collVersion, const Firebird::string& locale,
|
const string& icuVersion, const string& collVersion,
|
||||||
const Firebird::string& configInfo)
|
const string& locale, const string& configInfo)
|
||||||
{
|
{
|
||||||
ObjectsArray<string> versions;
|
ObjectsArray<string> versions;
|
||||||
getVersions(configInfo, versions);
|
getVersions(configInfo, versions);
|
||||||
@ -1866,7 +2064,26 @@ UnicodeUtil::ICU* UnicodeUtil::Utf16Collation::loadICU(
|
|||||||
return icu;
|
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 "intlobj_new.h"
|
||||||
#include "../common/IntlUtil.h"
|
#include "../common/IntlUtil.h"
|
||||||
#include "../common/os/mod_loader.h"
|
#include "../common/os/mod_loader.h"
|
||||||
|
#include "../common/classes/array.h"
|
||||||
#include "../common/classes/fb_string.h"
|
#include "../common/classes/fb_string.h"
|
||||||
|
#include "../common/classes/GenericMap.h"
|
||||||
#include "../common/classes/objects_array.h"
|
#include "../common/classes/objects_array.h"
|
||||||
#include <unicode/ucnv.h>
|
#include <unicode/ucnv.h>
|
||||||
#include <unicode/ucal.h>
|
#include <unicode/ucal.h>
|
||||||
@ -56,6 +58,7 @@ public:
|
|||||||
const UChar *src, int32_t srcLength,
|
const UChar *src, int32_t srcLength,
|
||||||
UErrorCode *pErrorCode);
|
UErrorCode *pErrorCode);
|
||||||
|
|
||||||
|
void (U_EXPORT2* u_getVersion) (UVersionInfo versionArray);
|
||||||
UChar32 (U_EXPORT2* u_tolower) (UChar32 c);
|
UChar32 (U_EXPORT2* u_tolower) (UChar32 c);
|
||||||
UChar32 (U_EXPORT2* u_toupper) (UChar32 c);
|
UChar32 (U_EXPORT2* u_toupper) (UChar32 c);
|
||||||
int32_t (U_EXPORT2* u_strCompare) (const UChar* s1, int32_t length1,
|
int32_t (U_EXPORT2* u_strCompare) (const UChar* s1, int32_t length1,
|
||||||
@ -175,7 +178,8 @@ public:
|
|||||||
|
|
||||||
static ConversionICU& getConversionICU();
|
static ConversionICU& getConversionICU();
|
||||||
static ICU* loadICU(const Firebird::string& icuVersion, const Firebird::string& configInfo);
|
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);
|
const Firebird::string& configInfo, Firebird::string& collVersion);
|
||||||
|
|
||||||
class Utf16Collation
|
class Utf16Collation
|
||||||
@ -200,8 +204,47 @@ public:
|
|||||||
ULONG canonical(ULONG srcLen, const USHORT* src, ULONG dstLen, ULONG* dst, const ULONG* exceptions);
|
ULONG canonical(ULONG srcLen, const USHORT* src, ULONG dstLen, ULONG* dst, const ULONG* exceptions);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static ICU* loadICU(const Firebird::string& collVersion, const Firebird::string& locale,
|
template <typename T>
|
||||||
const Firebird::string& configInfo);
|
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,
|
void normalize(ULONG* strLen, const USHORT** str, bool forNumericSort,
|
||||||
Firebird::HalfStaticArray<USHORT, BUFFER_SMALL / 2>& buffer) const;
|
Firebird::HalfStaticArray<USHORT, BUFFER_SMALL / 2>& buffer) const;
|
||||||
@ -212,7 +255,7 @@ public:
|
|||||||
UCollator* compareCollator;
|
UCollator* compareCollator;
|
||||||
UCollator* partialCollator;
|
UCollator* partialCollator;
|
||||||
UCollator* sortCollator;
|
UCollator* sortCollator;
|
||||||
Firebird::SortedObjectsArray<Firebird::string> contractionsPrefix; // UTF-16 string
|
ContractionsPrefixMap contractionsPrefix;
|
||||||
unsigned maxContractionsPrefixLength; // number of characters
|
unsigned maxContractionsPrefixLength; // number of characters
|
||||||
bool numericSort;
|
bool numericSort;
|
||||||
};
|
};
|
||||||
|
@ -1143,7 +1143,7 @@ Firebird::PathName getPrefix(unsigned int prefType, const char* name)
|
|||||||
|
|
||||||
if (s.hasData() && name[0])
|
if (s.hasData() && name[0])
|
||||||
{
|
{
|
||||||
s += '/';
|
s += PathUtils::dir_sep;
|
||||||
}
|
}
|
||||||
s += name;
|
s += name;
|
||||||
gds__prefix(tmp, s.c_str());
|
gds__prefix(tmp, s.c_str());
|
||||||
@ -1613,6 +1613,13 @@ bool containsErrorCode(const ISC_STATUS* v, ISC_STATUS code)
|
|||||||
return false;
|
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)
|
const char* dpbItemUpper(const char* s, FB_SIZE_T l, Firebird::string& buf)
|
||||||
{
|
{
|
||||||
if (l && (s[0] == '"' || s[0] == '\''))
|
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 (s[i] == end_quote)
|
||||||
{
|
{
|
||||||
if (++i >= l || s[i] != end_quote)
|
if (++i >= l)
|
||||||
break; // delimited quote, done processing
|
{
|
||||||
|
|
||||||
// skipped the escape quote, continue processing
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s[i] & 0x80)
|
|
||||||
ascii = false;
|
|
||||||
buf += s[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ascii && s[0] == '\'')
|
if (ascii && s[0] == '\'')
|
||||||
buf.upper();
|
buf.upper();
|
||||||
|
|
||||||
return buf.c_str();
|
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
|
// non-quoted string - try to uppercase
|
||||||
for (FB_SIZE_T i = 0; i < l; ++i)
|
for (FB_SIZE_T i = 0; i < l; ++i)
|
||||||
{
|
{
|
||||||
if (!(s[i] & 0x80))
|
if (!sqlSymbolChar(s[i], i == 0))
|
||||||
buf += toupper(s[i]);
|
|
||||||
else
|
|
||||||
return NULL; // contains non-ascii data
|
return NULL; // contains non-ascii data
|
||||||
|
buf += toupper(s[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return buf.c_str();
|
return buf.c_str();
|
||||||
|
@ -356,7 +356,7 @@ AggNode* AggNode::pass2(thread_db* tdbb, CompilerScratch* csb)
|
|||||||
return this;
|
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_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset);
|
||||||
impure->vlux_count = 0;
|
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;
|
dsc* desc = NULL;
|
||||||
|
|
||||||
@ -435,7 +435,7 @@ bool AggNode::aggPass(thread_db* tdbb, jrd_req* request) const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AggNode::aggFinish(thread_db* /*tdbb*/, jrd_req* request) const
|
void AggNode::aggFinish(thread_db* /*tdbb*/, Request* request) const
|
||||||
{
|
{
|
||||||
if (asb)
|
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);
|
impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset);
|
||||||
|
|
||||||
@ -685,7 +685,7 @@ string AvgAggNode::internalPrint(NodePrinter& printer) const
|
|||||||
return "AvgAggNode";
|
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);
|
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);
|
impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset);
|
||||||
if (impure->vlux_count++ == 0) // first call to aggPass()
|
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);
|
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);
|
impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset);
|
||||||
|
|
||||||
@ -848,7 +848,7 @@ string ListAggNode::internalPrint(NodePrinter& printer) const
|
|||||||
return "ListAggNode";
|
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);
|
AggNode::aggInit(tdbb, request);
|
||||||
|
|
||||||
@ -859,7 +859,7 @@ void ListAggNode::aggInit(thread_db* tdbb, jrd_req* request) const
|
|||||||
impure->vlu_desc.dsc_dtype = 0;
|
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);
|
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);
|
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);
|
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.
|
//// 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);
|
AggNode::aggInit(tdbb, request);
|
||||||
|
|
||||||
@ -1008,7 +1008,7 @@ void CountAggNode::aggInit(thread_db* tdbb, jrd_req* request) const
|
|||||||
impure->make_int64(0);
|
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);
|
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;
|
++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);
|
impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset);
|
||||||
|
|
||||||
@ -1253,7 +1253,7 @@ string SumAggNode::internalPrint(NodePrinter& printer) const
|
|||||||
return "SumAggNode";
|
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);
|
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_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset);
|
||||||
++impure->vlux_count;
|
++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);
|
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);
|
impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset);
|
||||||
|
|
||||||
@ -1345,7 +1345,7 @@ string MaxMinAggNode::internalPrint(NodePrinter& printer) const
|
|||||||
return "MaxMinAggNode";
|
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);
|
AggNode::aggInit(tdbb, request);
|
||||||
|
|
||||||
@ -1353,7 +1353,7 @@ void MaxMinAggNode::aggInit(thread_db* tdbb, jrd_req* request) const
|
|||||||
impure->vlu_desc.dsc_dtype = 0;
|
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_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset);
|
||||||
++impure->vlux_count;
|
++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);
|
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);
|
impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset);
|
||||||
|
|
||||||
@ -1472,7 +1472,7 @@ string StdDevAggNode::internalPrint(NodePrinter& printer) const
|
|||||||
return "StdDevAggNode";
|
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);
|
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_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset);
|
||||||
++impure->vlux_count;
|
++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);
|
impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset);
|
||||||
StdDevImpure* impure2 = request->getImpure<StdDevImpure>(impure2Offset);
|
StdDevImpure* impure2 = request->getImpure<StdDevImpure>(impure2Offset);
|
||||||
@ -1681,7 +1681,7 @@ string CorrAggNode::internalPrint(NodePrinter& printer) const
|
|||||||
return "CorrAggNode";
|
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);
|
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);
|
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;
|
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);
|
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);
|
impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset);
|
||||||
CorrImpure* impure2 = request->getImpure<CorrImpure>(impure2Offset);
|
CorrImpure* impure2 = request->getImpure<CorrImpure>(impure2Offset);
|
||||||
@ -1957,7 +1957,7 @@ string RegrAggNode::internalPrint(NodePrinter& printer) const
|
|||||||
return "RegrAggNode";
|
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);
|
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);
|
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;
|
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);
|
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);
|
impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset);
|
||||||
|
|
||||||
@ -2226,7 +2226,7 @@ string RegrCountAggNode::internalPrint(NodePrinter& printer) const
|
|||||||
return "RegrCountAggNode";
|
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);
|
AggNode::aggInit(tdbb, request);
|
||||||
|
|
||||||
@ -2234,7 +2234,7 @@ void RegrCountAggNode::aggInit(thread_db* tdbb, jrd_req* request) const
|
|||||||
impure->make_int64(0);
|
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);
|
EVL_expr(tdbb, request, arg);
|
||||||
if (request->req_flags & req_null)
|
if (request->req_flags & req_null)
|
||||||
@ -2250,12 +2250,12 @@ bool RegrCountAggNode::aggPass(thread_db* tdbb, jrd_req* request) const
|
|||||||
return true;
|
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);
|
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);
|
impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset);
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
namespace Jrd {
|
namespace Jrd {
|
||||||
|
|
||||||
|
|
||||||
class AvgAggNode : public AggNode
|
class AvgAggNode final : public AggNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit AvgAggNode(MemoryPool& pool, bool aDistinct, bool aDialect1, ValueExprNode* aArg = NULL);
|
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 ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const;
|
||||||
virtual AggNode* pass2(thread_db* tdbb, CompilerScratch* csb);
|
virtual AggNode* pass2(thread_db* tdbb, CompilerScratch* csb);
|
||||||
|
|
||||||
virtual void aggInit(thread_db* tdbb, jrd_req* request) const;
|
virtual void aggInit(thread_db* tdbb, Request* request) const;
|
||||||
virtual void aggPass(thread_db* tdbb, jrd_req* request, dsc* desc) const;
|
virtual void aggPass(thread_db* tdbb, Request* request, dsc* desc) const;
|
||||||
virtual dsc* aggExecute(thread_db* tdbb, jrd_req* request) const;
|
virtual dsc* aggExecute(thread_db* tdbb, Request* request) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual AggNode* dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/;
|
virtual AggNode* dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/;
|
||||||
@ -65,7 +65,7 @@ private:
|
|||||||
ULONG tempImpure;
|
ULONG tempImpure;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ListAggNode : public AggNode
|
class ListAggNode final : public AggNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit ListAggNode(MemoryPool& pool, bool aDistinct, ValueExprNode* aArg = NULL,
|
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 void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc);
|
||||||
virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const;
|
virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const;
|
||||||
|
|
||||||
virtual void aggInit(thread_db* tdbb, jrd_req* request) const;
|
virtual void aggInit(thread_db* tdbb, Request* request) const;
|
||||||
virtual void aggPass(thread_db* tdbb, jrd_req* request, dsc* desc) const;
|
virtual void aggPass(thread_db* tdbb, Request* request, dsc* desc) const;
|
||||||
virtual dsc* aggExecute(thread_db* tdbb, jrd_req* request) const;
|
virtual dsc* aggExecute(thread_db* tdbb, Request* request) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual AggNode* dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/;
|
virtual AggNode* dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/;
|
||||||
@ -102,7 +102,7 @@ private:
|
|||||||
NestConst<ValueExprNode> delimiter;
|
NestConst<ValueExprNode> delimiter;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CountAggNode : public AggNode
|
class CountAggNode final : public AggNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit CountAggNode(MemoryPool& pool, bool aDistinct, bool aDialect1, ValueExprNode* aArg = NULL);
|
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 void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc);
|
||||||
virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const;
|
virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const;
|
||||||
|
|
||||||
virtual void aggInit(thread_db* tdbb, jrd_req* request) const;
|
virtual void aggInit(thread_db* tdbb, Request* request) const;
|
||||||
virtual void aggPass(thread_db* tdbb, jrd_req* request, dsc* desc) const;
|
virtual void aggPass(thread_db* tdbb, Request* request, dsc* desc) const;
|
||||||
virtual dsc* aggExecute(thread_db* tdbb, jrd_req* request) const;
|
virtual dsc* aggExecute(thread_db* tdbb, Request* request) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual AggNode* dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/;
|
virtual AggNode* dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SumAggNode : public AggNode
|
class SumAggNode final : public AggNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit SumAggNode(MemoryPool& pool, bool aDistinct, bool aDialect1, ValueExprNode* aArg = NULL);
|
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 void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc);
|
||||||
virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const;
|
virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const;
|
||||||
|
|
||||||
virtual void aggInit(thread_db* tdbb, jrd_req* request) const;
|
virtual void aggInit(thread_db* tdbb, Request* request) const;
|
||||||
virtual void aggPass(thread_db* tdbb, jrd_req* request, dsc* desc) const;
|
virtual void aggPass(thread_db* tdbb, Request* request, dsc* desc) const;
|
||||||
virtual dsc* aggExecute(thread_db* tdbb, jrd_req* request) const;
|
virtual dsc* aggExecute(thread_db* tdbb, Request* request) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual AggNode* dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/;
|
virtual AggNode* dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MaxMinAggNode : public AggNode
|
class MaxMinAggNode final : public AggNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum MaxMinType
|
enum MaxMinType
|
||||||
@ -181,9 +181,9 @@ public:
|
|||||||
virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc);
|
virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc);
|
||||||
virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const;
|
virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const;
|
||||||
|
|
||||||
virtual void aggInit(thread_db* tdbb, jrd_req* request) const;
|
virtual void aggInit(thread_db* tdbb, Request* request) const;
|
||||||
virtual void aggPass(thread_db* tdbb, jrd_req* request, dsc* desc) const;
|
virtual void aggPass(thread_db* tdbb, Request* request, dsc* desc) const;
|
||||||
virtual dsc* aggExecute(thread_db* tdbb, jrd_req* request) const;
|
virtual dsc* aggExecute(thread_db* tdbb, Request* request) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual AggNode* dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/;
|
virtual AggNode* dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/;
|
||||||
@ -192,7 +192,7 @@ public:
|
|||||||
const MaxMinType type;
|
const MaxMinType type;
|
||||||
};
|
};
|
||||||
|
|
||||||
class StdDevAggNode : public AggNode
|
class StdDevAggNode final : public AggNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum StdDevType
|
enum StdDevType
|
||||||
@ -230,9 +230,9 @@ public:
|
|||||||
virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const;
|
virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const;
|
||||||
virtual AggNode* pass2(thread_db* tdbb, CompilerScratch* csb);
|
virtual AggNode* pass2(thread_db* tdbb, CompilerScratch* csb);
|
||||||
|
|
||||||
virtual void aggInit(thread_db* tdbb, jrd_req* request) const;
|
virtual void aggInit(thread_db* tdbb, Request* request) const;
|
||||||
virtual void aggPass(thread_db* tdbb, jrd_req* request, dsc* desc) const;
|
virtual void aggPass(thread_db* tdbb, Request* request, dsc* desc) const;
|
||||||
virtual dsc* aggExecute(thread_db* tdbb, jrd_req* request) const;
|
virtual dsc* aggExecute(thread_db* tdbb, Request* request) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual AggNode* dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/;
|
virtual AggNode* dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/;
|
||||||
@ -244,7 +244,7 @@ private:
|
|||||||
ULONG impure2Offset;
|
ULONG impure2Offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CorrAggNode : public AggNode
|
class CorrAggNode final : public AggNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum CorrType
|
enum CorrType
|
||||||
@ -288,10 +288,10 @@ public:
|
|||||||
virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const;
|
virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const;
|
||||||
virtual AggNode* pass2(thread_db* tdbb, CompilerScratch* csb);
|
virtual AggNode* pass2(thread_db* tdbb, CompilerScratch* csb);
|
||||||
|
|
||||||
virtual void aggInit(thread_db* tdbb, jrd_req* request) const;
|
virtual void aggInit(thread_db* tdbb, Request* request) const;
|
||||||
virtual bool aggPass(thread_db* tdbb, jrd_req* request) const;
|
virtual bool aggPass(thread_db* tdbb, Request* request) const;
|
||||||
virtual void aggPass(thread_db* tdbb, jrd_req* request, dsc* desc) const;
|
virtual void aggPass(thread_db* tdbb, Request* request, dsc* desc) const;
|
||||||
virtual dsc* aggExecute(thread_db* tdbb, jrd_req* request) const;
|
virtual dsc* aggExecute(thread_db* tdbb, Request* request) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual AggNode* dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/;
|
virtual AggNode* dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/;
|
||||||
@ -304,7 +304,7 @@ private:
|
|||||||
ULONG impure2Offset;
|
ULONG impure2Offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
class RegrAggNode : public AggNode
|
class RegrAggNode final : public AggNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum RegrType
|
enum RegrType
|
||||||
@ -353,10 +353,10 @@ public:
|
|||||||
virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const;
|
virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const;
|
||||||
virtual AggNode* pass2(thread_db* tdbb, CompilerScratch* csb);
|
virtual AggNode* pass2(thread_db* tdbb, CompilerScratch* csb);
|
||||||
|
|
||||||
virtual void aggInit(thread_db* tdbb, jrd_req* request) const;
|
virtual void aggInit(thread_db* tdbb, Request* request) const;
|
||||||
virtual bool aggPass(thread_db* tdbb, jrd_req* request) const;
|
virtual bool aggPass(thread_db* tdbb, Request* request) const;
|
||||||
virtual void aggPass(thread_db* tdbb, jrd_req* request, dsc* desc) const;
|
virtual void aggPass(thread_db* tdbb, Request* request, dsc* desc) const;
|
||||||
virtual dsc* aggExecute(thread_db* tdbb, jrd_req* request) const;
|
virtual dsc* aggExecute(thread_db* tdbb, Request* request) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual AggNode* dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/;
|
virtual AggNode* dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/;
|
||||||
@ -369,7 +369,7 @@ private:
|
|||||||
ULONG impure2Offset;
|
ULONG impure2Offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
class RegrCountAggNode : public AggNode
|
class RegrCountAggNode final : public AggNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit RegrCountAggNode(MemoryPool& pool,
|
explicit RegrCountAggNode(MemoryPool& pool,
|
||||||
@ -393,10 +393,10 @@ public:
|
|||||||
virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc);
|
virtual void getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc);
|
||||||
virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const;
|
virtual ValueExprNode* copy(thread_db* tdbb, NodeCopier& copier) const;
|
||||||
|
|
||||||
virtual void aggInit(thread_db* tdbb, jrd_req* request) const;
|
virtual void aggInit(thread_db* tdbb, Request* request) const;
|
||||||
virtual bool aggPass(thread_db* tdbb, jrd_req* request) const;
|
virtual bool aggPass(thread_db* tdbb, Request* request) const;
|
||||||
virtual void aggPass(thread_db* tdbb, jrd_req* request, dsc* desc) const;
|
virtual void aggPass(thread_db* tdbb, Request* request, dsc* desc) const;
|
||||||
virtual dsc* aggExecute(thread_db* tdbb, jrd_req* request) const;
|
virtual dsc* aggExecute(thread_db* tdbb, Request* request) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual AggNode* dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/;
|
virtual AggNode* dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/;
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
#include "../jrd/tra.h"
|
#include "../jrd/tra.h"
|
||||||
#include "../jrd/recsrc/RecordSource.h"
|
#include "../jrd/recsrc/RecordSource.h"
|
||||||
#include "../jrd/recsrc/Cursor.h"
|
#include "../jrd/recsrc/Cursor.h"
|
||||||
#include "../jrd/Optimizer.h"
|
#include "../jrd/optimizer/Optimizer.h"
|
||||||
#include "../jrd/blb_proto.h"
|
#include "../jrd/blb_proto.h"
|
||||||
#include "../jrd/cmp_proto.h"
|
#include "../jrd/cmp_proto.h"
|
||||||
#include "../jrd/evl_proto.h"
|
#include "../jrd/evl_proto.h"
|
||||||
@ -170,7 +170,7 @@ BoolExprNode* BinaryBoolNode::copy(thread_db* tdbb, NodeCopier& copier) const
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BinaryBoolNode::execute(thread_db* tdbb, jrd_req* request) const
|
bool BinaryBoolNode::execute(thread_db* tdbb, Request* request) const
|
||||||
{
|
{
|
||||||
switch (blrOp)
|
switch (blrOp)
|
||||||
{
|
{
|
||||||
@ -185,7 +185,7 @@ bool BinaryBoolNode::execute(thread_db* tdbb, jrd_req* request) const
|
|||||||
return false;
|
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 either operand is false, then the result is false;
|
||||||
// If both are true, the result is true;
|
// If both are true, the result is true;
|
||||||
@ -231,7 +231,7 @@ bool BinaryBoolNode::executeAnd(thread_db* tdbb, jrd_req* request) const
|
|||||||
return false;
|
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 either operand is true, then the result is true;
|
||||||
// If both are false, the result is false;
|
// 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};
|
dsc* desc[2] = {NULL, NULL};
|
||||||
bool computed_invariant = false;
|
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.
|
// 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
|
dsc* desc2, bool computedInvariant) const
|
||||||
{
|
{
|
||||||
SET_TDBB(tdbb);
|
SET_TDBB(tdbb);
|
||||||
@ -1023,7 +1023,7 @@ bool ComparativeBoolNode::stringBoolean(thread_db* tdbb, jrd_req* request, dsc*
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Execute SLEUTH operator.
|
// 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
|
const dsc* desc2) const
|
||||||
{
|
{
|
||||||
SET_TDBB(tdbb);
|
SET_TDBB(tdbb);
|
||||||
@ -1223,7 +1223,7 @@ void MissingBoolNode::pass2Boolean2(thread_db* tdbb, CompilerScratch* csb)
|
|||||||
arg->getDesc(tdbb, csb, &descriptor_a);
|
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);
|
EVL_expr(tdbb, request, arg);
|
||||||
|
|
||||||
@ -1298,7 +1298,7 @@ BoolExprNode* NotBoolNode::pass1(thread_db* tdbb, CompilerScratch* csb)
|
|||||||
return BoolExprNode::pass1(tdbb, 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);
|
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);
|
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;
|
USHORT* invariant_flags;
|
||||||
impure_value* impure;
|
impure_value* impure;
|
||||||
|
@ -31,7 +31,7 @@ namespace Jrd {
|
|||||||
class SubQuery;
|
class SubQuery;
|
||||||
|
|
||||||
|
|
||||||
class BinaryBoolNode : public TypedNode<BoolExprNode, ExprNode::TYPE_BINARY_BOOL>
|
class BinaryBoolNode final : public TypedNode<BoolExprNode, ExprNode::TYPE_BINARY_BOOL>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
BinaryBoolNode(MemoryPool& pool, UCHAR aBlrOp, BoolExprNode* aArg1 = NULL,
|
BinaryBoolNode(MemoryPool& pool, UCHAR aBlrOp, BoolExprNode* aArg1 = NULL,
|
||||||
@ -54,11 +54,11 @@ public:
|
|||||||
virtual BoolExprNode* copy(thread_db* tdbb, NodeCopier& copier) const;
|
virtual BoolExprNode* copy(thread_db* tdbb, NodeCopier& copier) const;
|
||||||
virtual bool dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, bool ignoreMapCast) const;
|
virtual bool dsqlMatch(DsqlCompilerScratch* dsqlScratch, const ExprNode* other, bool ignoreMapCast) const;
|
||||||
virtual bool sameAs(const ExprNode* other, bool ignoreStreams) 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:
|
private:
|
||||||
virtual bool executeAnd(thread_db* tdbb, jrd_req* request) const;
|
virtual bool executeAnd(thread_db* tdbb, Request* request) const;
|
||||||
virtual bool executeOr(thread_db* tdbb, jrd_req* request) const;
|
virtual bool executeOr(thread_db* tdbb, Request* request) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
UCHAR blrOp;
|
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:
|
public:
|
||||||
enum DsqlFlag : UCHAR
|
enum DsqlFlag : UCHAR
|
||||||
@ -106,12 +106,12 @@ public:
|
|||||||
virtual BoolExprNode* pass1(thread_db* tdbb, CompilerScratch* csb);
|
virtual BoolExprNode* pass1(thread_db* tdbb, CompilerScratch* csb);
|
||||||
virtual void pass2Boolean1(thread_db* tdbb, CompilerScratch* csb);
|
virtual void pass2Boolean1(thread_db* tdbb, CompilerScratch* csb);
|
||||||
virtual void pass2Boolean2(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:
|
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 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);
|
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:
|
public:
|
||||||
explicit MissingBoolNode(MemoryPool& pool, ValueExprNode* aArg = NULL, bool aDsqlUnknown = false);
|
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* copy(thread_db* tdbb, NodeCopier& copier) const;
|
||||||
virtual BoolExprNode* pass1(thread_db* tdbb, CompilerScratch* csb);
|
virtual BoolExprNode* pass1(thread_db* tdbb, CompilerScratch* csb);
|
||||||
virtual void pass2Boolean2(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:
|
public:
|
||||||
bool dsqlUnknown;
|
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:
|
public:
|
||||||
explicit NotBoolNode(MemoryPool& pool, BoolExprNode* aArg = NULL);
|
explicit NotBoolNode(MemoryPool& pool, BoolExprNode* aArg = NULL);
|
||||||
@ -183,7 +183,7 @@ public:
|
|||||||
|
|
||||||
virtual BoolExprNode* copy(thread_db* tdbb, NodeCopier& copier) const;
|
virtual BoolExprNode* copy(thread_db* tdbb, NodeCopier& copier) const;
|
||||||
virtual BoolExprNode* pass1(thread_db* tdbb, CompilerScratch* csb);
|
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:
|
private:
|
||||||
BoolExprNode* process(DsqlCompilerScratch* dsqlScratch, bool invert);
|
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:
|
public:
|
||||||
RseBoolNode(MemoryPool& pool, UCHAR aBlrOp, RecordSourceNode* aDsqlRse = NULL);
|
RseBoolNode(MemoryPool& pool, UCHAR aBlrOp, RecordSourceNode* aDsqlRse = NULL);
|
||||||
@ -235,7 +235,7 @@ public:
|
|||||||
virtual BoolExprNode* pass1(thread_db* tdbb, CompilerScratch* csb);
|
virtual BoolExprNode* pass1(thread_db* tdbb, CompilerScratch* csb);
|
||||||
virtual void pass2Boolean1(thread_db* tdbb, CompilerScratch* csb);
|
virtual void pass2Boolean1(thread_db* tdbb, CompilerScratch* csb);
|
||||||
virtual void pass2Boolean2(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:
|
private:
|
||||||
BoolExprNode* convertNeqAllToNotAny(thread_db* tdbb, CompilerScratch* csb);
|
BoolExprNode* convertNeqAllToNotAny(thread_db* tdbb, CompilerScratch* csb);
|
||||||
|
@ -985,7 +985,7 @@ void DdlNode::executeDdlTrigger(thread_db* tdbb, DsqlCompilerScratch* dsqlScratc
|
|||||||
const MetaName& oldNewObjectName)
|
const MetaName& oldNewObjectName)
|
||||||
{
|
{
|
||||||
executeDdlTrigger(tdbb, transaction, when, action, objectName, 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,
|
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)
|
switch (objType)
|
||||||
{
|
{
|
||||||
case obj_schema:
|
|
||||||
case obj_database:
|
case obj_database:
|
||||||
SCL_check_database(tdbb, SCL_alter);
|
SCL_check_database(tdbb, SCL_alter);
|
||||||
break;
|
break;
|
||||||
@ -1577,12 +1576,6 @@ void CommentOnNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
|
|||||||
status << Arg::Gds(isc_dyn_package_not_found) << Arg::Str(objNameStr);
|
status << Arg::Gds(isc_dyn_package_not_found) << Arg::Str(objNameStr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case obj_schema:
|
|
||||||
tableClause = "rdb$schemas";
|
|
||||||
columnClause = "rdb$schema_name";
|
|
||||||
status << Arg::Gds(isc_dyn_schema_not_found) << Arg::Str(objNameStr);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
fb_assert(false);
|
fb_assert(false);
|
||||||
return;
|
return;
|
||||||
@ -1741,7 +1734,7 @@ void CreateAlterFunctionNode::checkPermission(thread_db* tdbb, jrd_tra* transact
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SCL_check_create_access(tdbb, SCL_object_function);
|
SCL_check_create_access(tdbb, obj_functions);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CreateAlterFunctionNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
|
void CreateAlterFunctionNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
|
||||||
@ -2342,6 +2335,8 @@ void CreateAlterFunctionNode::compile(thread_db* /*tdbb*/, DsqlCompilerScratch*
|
|||||||
dsqlScratch->cursorNumber = 0;
|
dsqlScratch->cursorNumber = 0;
|
||||||
|
|
||||||
StmtNode* stmtNode = body->dsqlPass(dsqlScratch);
|
StmtNode* stmtNode = body->dsqlPass(dsqlScratch);
|
||||||
|
|
||||||
|
dsqlScratch->putOuterMaps();
|
||||||
GEN_hidden_variables(dsqlScratch);
|
GEN_hidden_variables(dsqlScratch);
|
||||||
|
|
||||||
dsqlScratch->appendUChar(blr_stall);
|
dsqlScratch->appendUChar(blr_stall);
|
||||||
@ -2352,7 +2347,7 @@ void CreateAlterFunctionNode::compile(thread_db* /*tdbb*/, DsqlCompilerScratch*
|
|||||||
|
|
||||||
stmtNode->genBlr(dsqlScratch);
|
stmtNode->genBlr(dsqlScratch);
|
||||||
|
|
||||||
dsqlScratch->getStatement()->setType(DsqlCompiledStatement::TYPE_DDL);
|
dsqlScratch->getDsqlStatement()->setType(DsqlStatement::TYPE_DDL);
|
||||||
dsqlScratch->appendUChar(blr_end);
|
dsqlScratch->appendUChar(blr_end);
|
||||||
dsqlScratch->genReturn(false);
|
dsqlScratch->genReturn(false);
|
||||||
dsqlScratch->appendUChar(blr_end);
|
dsqlScratch->appendUChar(blr_end);
|
||||||
@ -2747,7 +2742,7 @@ void CreateAlterProcedureNode::checkPermission(thread_db* tdbb, jrd_tra* transac
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SCL_check_create_access(tdbb, SCL_object_procedure);
|
SCL_check_create_access(tdbb, obj_procedures);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CreateAlterProcedureNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
|
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);
|
AutoCacheRequest requestHandle(tdbb, drq_m_prcs2, DYN_REQUESTS);
|
||||||
bool modified = false;
|
bool modified = false;
|
||||||
|
|
||||||
DsqlCompiledStatement* statement = dsqlScratch->getStatement();
|
DsqlStatement* statement = dsqlScratch->getDsqlStatement();
|
||||||
|
|
||||||
FOR (REQUEST_HANDLE requestHandle TRANSACTION_HANDLE transaction)
|
FOR (REQUEST_HANDLE requestHandle TRANSACTION_HANDLE transaction)
|
||||||
P IN RDB$PROCEDURES
|
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.NULL = FALSE;
|
||||||
P.RDB$PROCEDURE_TYPE = (USHORT)
|
P.RDB$PROCEDURE_TYPE = (USHORT)
|
||||||
(statement->getFlags() & DsqlCompiledStatement::FLAG_SELECTABLE ?
|
(statement->getFlags() & DsqlStatement::FLAG_SELECTABLE ?
|
||||||
prc_selectable : prc_executable);
|
prc_selectable : prc_executable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3235,6 +3230,8 @@ void CreateAlterProcedureNode::compile(thread_db* /*tdbb*/, DsqlCompilerScratch*
|
|||||||
dsqlScratch->cursorNumber = 0;
|
dsqlScratch->cursorNumber = 0;
|
||||||
|
|
||||||
StmtNode* stmtNode = body->dsqlPass(dsqlScratch);
|
StmtNode* stmtNode = body->dsqlPass(dsqlScratch);
|
||||||
|
|
||||||
|
dsqlScratch->putOuterMaps();
|
||||||
GEN_hidden_variables(dsqlScratch);
|
GEN_hidden_variables(dsqlScratch);
|
||||||
|
|
||||||
dsqlScratch->appendUChar(blr_stall);
|
dsqlScratch->appendUChar(blr_stall);
|
||||||
@ -3245,7 +3242,7 @@ void CreateAlterProcedureNode::compile(thread_db* /*tdbb*/, DsqlCompilerScratch*
|
|||||||
|
|
||||||
stmtNode->genBlr(dsqlScratch);
|
stmtNode->genBlr(dsqlScratch);
|
||||||
|
|
||||||
dsqlScratch->getStatement()->setType(DsqlCompiledStatement::TYPE_DDL);
|
dsqlScratch->getDsqlStatement()->setType(DsqlStatement::TYPE_DDL);
|
||||||
dsqlScratch->appendUChar(blr_end);
|
dsqlScratch->appendUChar(blr_end);
|
||||||
dsqlScratch->genReturn(true);
|
dsqlScratch->genReturn(true);
|
||||||
dsqlScratch->appendUChar(blr_end);
|
dsqlScratch->appendUChar(blr_end);
|
||||||
@ -3751,6 +3748,8 @@ void CreateAlterTriggerNode::compile(thread_db* /*tdbb*/, DsqlCompilerScratch* d
|
|||||||
dsqlScratch->scopeLevel++;
|
dsqlScratch->scopeLevel++;
|
||||||
|
|
||||||
StmtNode* stmtNode = body->dsqlPass(dsqlScratch);
|
StmtNode* stmtNode = body->dsqlPass(dsqlScratch);
|
||||||
|
|
||||||
|
dsqlScratch->putOuterMaps();
|
||||||
GEN_hidden_variables(dsqlScratch);
|
GEN_hidden_variables(dsqlScratch);
|
||||||
|
|
||||||
// dimitr: I see no reason to deny EXIT command in triggers,
|
// 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 statement type may have been set incorrectly when parsing
|
||||||
// the trigger actions, so reset it to reflect the fact that this
|
// the trigger actions, so reset it to reflect the fact that this
|
||||||
// is a data definition statement; also reset the ddl node.
|
// is a data definition statement; also reset the ddl node.
|
||||||
dsqlScratch->getStatement()->setType(DsqlCompiledStatement::TYPE_DDL);
|
dsqlScratch->getDsqlStatement()->setType(DsqlStatement::TYPE_DDL);
|
||||||
}
|
}
|
||||||
|
|
||||||
invalid = false;
|
invalid = false;
|
||||||
@ -3944,7 +3943,7 @@ string CreateCollationNode::internalPrint(NodePrinter& printer) const
|
|||||||
|
|
||||||
void CreateCollationNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
|
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,
|
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)
|
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,
|
void CreateDomainNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
|
||||||
@ -5450,7 +5449,7 @@ void CreateAlterExceptionNode::checkPermission(thread_db* tdbb, jrd_tra* transac
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SCL_check_create_access(tdbb, SCL_object_exception);
|
SCL_check_create_access(tdbb, obj_exceptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CreateAlterExceptionNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
|
void CreateAlterExceptionNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
|
||||||
@ -5657,7 +5656,7 @@ void CreateAlterSequenceNode::checkPermission(thread_db* tdbb, jrd_tra* transact
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SCL_check_create_access(tdbb, SCL_object_generator);
|
SCL_check_create_access(tdbb, obj_generators);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CreateAlterSequenceNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
|
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()
|
WITH GEN.RDB$GENERATOR_NAME EQ name.c_str()
|
||||||
{
|
{
|
||||||
ERASE GEN;
|
ERASE GEN;
|
||||||
|
|
||||||
|
if (!GEN.RDB$SECURITY_CLASS.NULL)
|
||||||
|
deleteSecurityClass(tdbb, transaction, GEN.RDB$SECURITY_CLASS);
|
||||||
}
|
}
|
||||||
END_FOR
|
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;
|
definition.unique = constraint.type != Constraint::TYPE_FK;
|
||||||
if (constraint.index->descending)
|
if (constraint.index->descending)
|
||||||
definition.descending = true;
|
definition.descending = true;
|
||||||
|
definition.inactive = false;
|
||||||
definition.columns = constraint.columns;
|
definition.columns = constraint.columns;
|
||||||
definition.refRelation = constraint.refRelation;
|
definition.refRelation = constraint.refRelation;
|
||||||
definition.refColumns = constraint.refColumns;
|
definition.refColumns = constraint.refColumns;
|
||||||
@ -7389,7 +7394,7 @@ string CreateRelationNode::internalPrint(NodePrinter& printer) const
|
|||||||
|
|
||||||
void CreateRelationNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
|
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,
|
void CreateRelationNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
|
||||||
@ -8669,7 +8674,7 @@ void CreateAlterViewNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SCL_check_create_access(tdbb, SCL_object_view);
|
SCL_check_create_access(tdbb, obj_views);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CreateAlterViewNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
|
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.relation = relation->dsqlName;
|
||||||
definition.unique = unique;
|
definition.unique = unique;
|
||||||
definition.descending = descending;
|
definition.descending = descending;
|
||||||
|
definition.inactive = false;
|
||||||
|
|
||||||
if (columns)
|
if (columns)
|
||||||
{
|
{
|
||||||
@ -10090,7 +10096,7 @@ string CreateFilterNode::internalPrint(NodePrinter& printer) const
|
|||||||
|
|
||||||
void CreateFilterNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
|
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.
|
// Define a blob filter.
|
||||||
@ -10346,7 +10352,7 @@ string CreateAlterRoleNode::internalPrint(NodePrinter& printer) const
|
|||||||
void CreateAlterRoleNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
|
void CreateAlterRoleNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
|
||||||
{
|
{
|
||||||
if (createFlag)
|
if (createFlag)
|
||||||
SCL_check_create_access(tdbb, SCL_object_role);
|
SCL_check_create_access(tdbb, obj_roles);
|
||||||
else
|
else
|
||||||
SCL_check_role(tdbb, name, SCL_alter);
|
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();
|
(Arg::Gds(isc_adm_task_denied) << Arg::Gds(isc_miss_prvlg) << "CHANGE_MAPPING_RULES").raise();
|
||||||
|
|
||||||
if (from)
|
if (from)
|
||||||
fromUtf8 = from->toUtf8(dsqlScratch);
|
fromUtf8 = from->toUtf8(transaction);
|
||||||
|
|
||||||
if (global)
|
if (global)
|
||||||
{
|
{
|
||||||
@ -11512,10 +11518,10 @@ void GrantRevokeNode::grantRevoke(thread_db* tdbb, jrd_tra* transaction, const G
|
|||||||
const GranteeClause* userNod, const char* privs,
|
const GranteeClause* userNod, const char* privs,
|
||||||
MetaName field, int options)
|
MetaName field, int options)
|
||||||
{
|
{
|
||||||
SSHORT userType = userNod->first;
|
ObjectType userType = userNod->first;
|
||||||
MetaName user(userNod->second);
|
MetaName user(userNod->second);
|
||||||
MetaName dummyName;
|
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 : "");
|
const MetaName objName(object ? object->second : "");
|
||||||
bool crdb = false;
|
bool crdb = false;
|
||||||
|
|
||||||
@ -11667,7 +11673,7 @@ void GrantRevokeNode::grantRevoke(thread_db* tdbb, jrd_tra* transaction, const G
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
fb_assert(object == NULL || objType >= obj_database);
|
fb_assert(object == NULL || isDdlObject(objType));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options == 1) // with grant option
|
if (options == 1) // with grant option
|
||||||
@ -11871,10 +11877,8 @@ void GrantRevokeNode::grantRevoke(thread_db* tdbb, jrd_tra* transaction, const G
|
|||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (objType >= obj_database)
|
if (isDdlObject(objType))
|
||||||
{
|
|
||||||
checkGrantorCanGrantDdl(tdbb, transaction, currentUser.c_str(), priv, objName);
|
checkGrantorCanGrantDdl(tdbb, transaction, currentUser.c_str(), priv, objName);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
fb_assert(false);
|
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
|
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$USER_TYPE = obj_user) OR (PRV.RDB$USER_TYPE = obj_sql_role)) AND
|
||||||
PRV.RDB$RELATION_NAME EQ objName.c_str() 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
|
PRV.RDB$PRIVILEGE EQ privilege
|
||||||
{
|
{
|
||||||
if ( (PRV.RDB$USER_TYPE == obj_sql_role) && !attachment->att_user->roleInUse(tdbb, PRV.RDB$USER))
|
if ( (PRV.RDB$USER_TYPE == obj_sql_role) && !attachment->att_user->roleInUse(tdbb, PRV.RDB$USER))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
// Double check if the object is DDL one.
|
||||||
|
if (!isDdlObject(PRV.RDB$OBJECT_TYPE))
|
||||||
|
continue;
|
||||||
|
|
||||||
if (PRV.RDB$GRANT_OPTION == WITH_GRANT_OPTION)
|
if (PRV.RDB$GRANT_OPTION == WITH_GRANT_OPTION)
|
||||||
{
|
{
|
||||||
grantable = true;
|
grantable = true;
|
||||||
|
@ -1129,8 +1129,8 @@ public:
|
|||||||
|
|
||||||
virtual DdlNode* dsqlPass(DsqlCompilerScratch* dsqlScratch)
|
virtual DdlNode* dsqlPass(DsqlCompilerScratch* dsqlScratch)
|
||||||
{
|
{
|
||||||
dsqlScratch->getStatement()->setType(
|
dsqlScratch->getDsqlStatement()->setType(
|
||||||
legacy ? DsqlCompiledStatement::TYPE_SET_GENERATOR : DsqlCompiledStatement::TYPE_DDL);
|
legacy ? DsqlStatement::TYPE_SET_GENERATOR : DsqlStatement::TYPE_DDL);
|
||||||
return this;
|
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<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
|
class GrantRevokeNode : public PrivilegesNode, private ExecInSecurityDb
|
||||||
{
|
{
|
||||||
@ -2417,8 +2417,8 @@ public:
|
|||||||
public:
|
public:
|
||||||
virtual DdlNode* dsqlPass(DsqlCompilerScratch* dsqlScratch)
|
virtual DdlNode* dsqlPass(DsqlCompilerScratch* dsqlScratch)
|
||||||
{
|
{
|
||||||
dsqlScratch->getStatement()->setType(
|
dsqlScratch->getDsqlStatement()->setType(
|
||||||
create ? DsqlCompiledStatement::TYPE_CREATE_DB : DsqlCompiledStatement::TYPE_DDL);
|
create ? DsqlStatement::TYPE_CREATE_DB : DsqlStatement::TYPE_DDL);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,15 +60,15 @@ namespace {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
DsqlBatch::DsqlBatch(dsql_req* req, const dsql_msg* /*message*/, IMessageMetadata* inMeta, ClumpletReader& pb)
|
DsqlBatch::DsqlBatch(DsqlDmlRequest* req, const dsql_msg* /*message*/, IMessageMetadata* inMeta, ClumpletReader& pb)
|
||||||
: m_request(req),
|
: m_dsqlRequest(req),
|
||||||
m_batch(NULL),
|
m_batch(NULL),
|
||||||
m_meta(inMeta),
|
m_meta(inMeta),
|
||||||
m_messages(m_request->getPool()),
|
m_messages(m_dsqlRequest->getPool()),
|
||||||
m_blobs(m_request->getPool()),
|
m_blobs(m_dsqlRequest->getPool()),
|
||||||
m_blobMap(m_request->getPool()),
|
m_blobMap(m_dsqlRequest->getPool()),
|
||||||
m_blobMeta(m_request->getPool()),
|
m_blobMeta(m_dsqlRequest->getPool()),
|
||||||
m_defaultBpb(m_request->getPool()),
|
m_defaultBpb(m_dsqlRequest->getPool()),
|
||||||
m_messageSize(0),
|
m_messageSize(0),
|
||||||
m_alignedMessage(0),
|
m_alignedMessage(0),
|
||||||
m_alignment(0),
|
m_alignment(0),
|
||||||
@ -168,13 +168,13 @@ DsqlBatch::~DsqlBatch()
|
|||||||
{
|
{
|
||||||
if (m_batch)
|
if (m_batch)
|
||||||
m_batch->resetHandle();
|
m_batch->resetHandle();
|
||||||
if (m_request)
|
if (m_dsqlRequest)
|
||||||
m_request->req_batch = NULL;
|
m_dsqlRequest->req_batch = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Attachment* DsqlBatch::getAttachment() const
|
Attachment* DsqlBatch::getAttachment() const
|
||||||
{
|
{
|
||||||
return m_request->req_dbb->dbb_attachment;
|
return m_dsqlRequest->req_dbb->dbb_attachment;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DsqlBatch::setInterfacePtr(JBatch* interfacePtr) throw()
|
void DsqlBatch::setInterfacePtr(JBatch* interfacePtr) throw()
|
||||||
@ -183,7 +183,7 @@ void DsqlBatch::setInterfacePtr(JBatch* interfacePtr) throw()
|
|||||||
m_batch = interfacePtr;
|
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)
|
unsigned parLength, const UCHAR* par)
|
||||||
{
|
{
|
||||||
SET_TDBB(tdbb);
|
SET_TDBB(tdbb);
|
||||||
@ -205,15 +205,15 @@ DsqlBatch* DsqlBatch::open(thread_db* tdbb, dsql_req* req, IMessageMetadata* inM
|
|||||||
|
|
||||||
// Sanity checks before creating batch
|
// Sanity checks before creating batch
|
||||||
|
|
||||||
if (!req->req_request)
|
if (!req->getRequest())
|
||||||
{
|
{
|
||||||
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-504) <<
|
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-504) <<
|
||||||
Arg::Gds(isc_unprepared_stmt));
|
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) <<
|
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-901) <<
|
||||||
Arg::Gds(isc_bad_req_handle));
|
Arg::Gds(isc_bad_req_handle));
|
||||||
@ -221,11 +221,11 @@ DsqlBatch* DsqlBatch::open(thread_db* tdbb, dsql_req* req, IMessageMetadata* inM
|
|||||||
|
|
||||||
switch (statement->getType())
|
switch (statement->getType())
|
||||||
{
|
{
|
||||||
case DsqlCompiledStatement::TYPE_INSERT:
|
case DsqlStatement::TYPE_INSERT:
|
||||||
case DsqlCompiledStatement::TYPE_DELETE:
|
case DsqlStatement::TYPE_DELETE:
|
||||||
case DsqlCompiledStatement::TYPE_UPDATE:
|
case DsqlStatement::TYPE_UPDATE:
|
||||||
case DsqlCompiledStatement::TYPE_EXEC_PROCEDURE:
|
case DsqlStatement::TYPE_EXEC_PROCEDURE:
|
||||||
case DsqlCompiledStatement::TYPE_EXEC_BLOCK:
|
case DsqlStatement::TYPE_EXEC_BLOCK:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -451,7 +451,7 @@ Firebird::IBatchCompletionState* DsqlBatch::execute(thread_db* tdbb)
|
|||||||
jrd_tra* transaction = tdbb->getTransaction();
|
jrd_tra* transaction = tdbb->getTransaction();
|
||||||
|
|
||||||
// execution timer
|
// 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
|
// sync internal buffers
|
||||||
m_messages.done();
|
m_messages.done();
|
||||||
@ -651,20 +651,20 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// execute request
|
// execute request
|
||||||
m_request->req_transaction = transaction;
|
m_dsqlRequest->req_transaction = transaction;
|
||||||
jrd_req* req = m_request->req_request;
|
Request* req = m_dsqlRequest->getRequest();
|
||||||
fb_assert(req);
|
fb_assert(req);
|
||||||
|
|
||||||
// prepare completion interface
|
// prepare completion interface
|
||||||
AutoPtr<BatchCompletionState, SimpleDispose> completionState
|
AutoPtr<BatchCompletionState, SimpleDispose> completionState
|
||||||
(FB_NEW BatchCompletionState(m_flags & (1 << IBatch::TAG_RECORD_COUNTS), m_detailed));
|
(FB_NEW BatchCompletionState(m_flags & (1 << IBatch::TAG_RECORD_COUNTS), m_detailed));
|
||||||
AutoSetRestore<bool> batchFlag(&req->req_batch_mode, true);
|
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 startRequest = true;
|
||||||
|
|
||||||
bool isExecBlock = m_request->getStatement()->getType() == DsqlCompiledStatement::TYPE_EXEC_BLOCK;
|
bool isExecBlock = m_dsqlRequest->getDsqlStatement()->getType() == DsqlStatement::TYPE_EXEC_BLOCK;
|
||||||
const auto receiveMessage = isExecBlock ? m_request->getStatement()->getReceiveMsg() : nullptr;
|
const auto receiveMessage = isExecBlock ? m_dsqlRequest->getDsqlStatement()->getReceiveMsg() : nullptr;
|
||||||
auto receiveMsgBuffer = isExecBlock ? m_request->req_msg_buffers[receiveMessage->msg_buffer_number] : nullptr;
|
auto receiveMsgBuffer = isExecBlock ? m_dsqlRequest->req_msg_buffers[receiveMessage->msg_buffer_number] : nullptr;
|
||||||
|
|
||||||
// process messages
|
// process messages
|
||||||
ULONG remains;
|
ULONG remains;
|
||||||
@ -720,11 +720,11 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// map message to internal engine format
|
// 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;
|
data += m_messageSize;
|
||||||
remains -= 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
|
try
|
||||||
{
|
{
|
||||||
// runsend data to request and collect stats
|
// runsend data to request and collect stats
|
||||||
|
@ -41,7 +41,7 @@ class ClumpletReader;
|
|||||||
|
|
||||||
namespace Jrd {
|
namespace Jrd {
|
||||||
|
|
||||||
class dsql_req;
|
class DsqlDmlRequest;
|
||||||
class dsql_msg;
|
class dsql_msg;
|
||||||
class thread_db;
|
class thread_db;
|
||||||
class JBatch;
|
class JBatch;
|
||||||
@ -50,7 +50,7 @@ class Attachment;
|
|||||||
class DsqlBatch
|
class DsqlBatch
|
||||||
{
|
{
|
||||||
public:
|
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);
|
Firebird::ClumpletReader& pb);
|
||||||
~DsqlBatch();
|
~DsqlBatch();
|
||||||
|
|
||||||
@ -61,7 +61,7 @@ public:
|
|||||||
static const ULONG SIZEOF_BLOB_HEAD = sizeof(ISC_QUAD) + 2 * sizeof(ULONG);
|
static const ULONG SIZEOF_BLOB_HEAD = sizeof(ISC_QUAD) + 2 * sizeof(ULONG);
|
||||||
static const unsigned BLOB_STREAM_ALIGN = 4;
|
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);
|
unsigned parLength, const UCHAR* par);
|
||||||
|
|
||||||
Attachment* getAttachment() const;
|
Attachment* getAttachment() const;
|
||||||
@ -101,7 +101,7 @@ private:
|
|||||||
m_flags &= ~(1 << bit);
|
m_flags &= ~(1 << bit);
|
||||||
}
|
}
|
||||||
|
|
||||||
dsql_req* const m_request;
|
DsqlDmlRequest* const m_dsqlRequest;
|
||||||
JBatch* m_batch;
|
JBatch* m_batch;
|
||||||
Firebird::IMessageMetadata* m_meta;
|
Firebird::IMessageMetadata* m_meta;
|
||||||
|
|
||||||
|
@ -345,30 +345,24 @@ void DsqlCompilerScratch::putLocalVariables(CompoundStmtNode* parameters, USHORT
|
|||||||
if (!(flags & DsqlCompilerScratch::FLAG_SUB_ROUTINE))
|
if (!(flags & DsqlCompilerScratch::FLAG_SUB_ROUTINE))
|
||||||
{
|
{
|
||||||
// Check not implemented sub-functions.
|
// Check not implemented sub-functions.
|
||||||
|
for (const auto& funcPair : subFunctions)
|
||||||
GenericMap<Left<MetaName, DeclareSubFuncNode*> >::ConstAccessor funcAccessor(&subFunctions);
|
|
||||||
|
|
||||||
for (bool found = funcAccessor.getFirst(); found; found = funcAccessor.getNext())
|
|
||||||
{
|
{
|
||||||
if (!funcAccessor.current()->second->dsqlBlock)
|
if (!funcPair.second->dsqlBlock)
|
||||||
{
|
{
|
||||||
status_exception::raise(
|
status_exception::raise(
|
||||||
Arg::Gds(isc_subfunc_not_impl) <<
|
Arg::Gds(isc_subfunc_not_impl) <<
|
||||||
funcAccessor.current()->first.c_str());
|
funcPair.first.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check not implemented sub-procedures.
|
// Check not implemented sub-procedures.
|
||||||
|
for (const auto& procPair : subProcedures)
|
||||||
GenericMap<Left<MetaName, DeclareSubProcNode*> >::ConstAccessor procAccessor(&subProcedures);
|
|
||||||
|
|
||||||
for (bool found = procAccessor.getFirst(); found; found = procAccessor.getNext())
|
|
||||||
{
|
{
|
||||||
if (!procAccessor.current()->second->dsqlBlock)
|
if (!procPair.second->dsqlBlock)
|
||||||
{
|
{
|
||||||
status_exception::raise(
|
status_exception::raise(
|
||||||
Arg::Gds(isc_subproc_not_impl) <<
|
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;
|
++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.
|
// Make a variable.
|
||||||
dsql_var* DsqlCompilerScratch::makeVariable(dsql_fld* field, const char* name,
|
dsql_var* DsqlCompilerScratch::makeVariable(dsql_fld* field, const char* name,
|
||||||
const dsql_var::Type type, USHORT msgNumber, USHORT itemNumber, USHORT localNumber)
|
const dsql_var::Type type, USHORT msgNumber, USHORT itemNumber, USHORT localNumber)
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
#include "../jrd/jrd.h"
|
#include "../jrd/jrd.h"
|
||||||
#include "../dsql/dsql.h"
|
#include "../dsql/dsql.h"
|
||||||
|
#include "../dsql/DsqlStatements.h"
|
||||||
#include "../dsql/BlrDebugWriter.h"
|
#include "../dsql/BlrDebugWriter.h"
|
||||||
#include "../common/classes/array.h"
|
#include "../common/classes/array.h"
|
||||||
#include "../jrd/MetaName.h"
|
#include "../jrd/MetaName.h"
|
||||||
@ -73,14 +74,13 @@ public:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
DsqlCompilerScratch(MemoryPool& p, dsql_dbb* aDbb, jrd_tra* aTransaction,
|
DsqlCompilerScratch(MemoryPool& p, dsql_dbb* aDbb, jrd_tra* aTransaction,
|
||||||
DsqlCompiledStatement* aStatement, DsqlCompilerScratch* aMainScratch = NULL)
|
DsqlStatement* aDsqlStatement = nullptr, DsqlCompilerScratch* aMainScratch = nullptr)
|
||||||
: BlrDebugWriter(p),
|
: BlrDebugWriter(p),
|
||||||
dbb(aDbb),
|
dbb(aDbb),
|
||||||
transaction(aTransaction),
|
transaction(aTransaction),
|
||||||
statement(aStatement),
|
dsqlStatement(aDsqlStatement),
|
||||||
flags(0),
|
flags(0),
|
||||||
nestingLevel(0),
|
nestingLevel(0),
|
||||||
ports(p),
|
|
||||||
relation(NULL),
|
relation(NULL),
|
||||||
mainContext(p),
|
mainContext(p),
|
||||||
context(&mainContext),
|
context(&mainContext),
|
||||||
@ -117,10 +117,12 @@ public:
|
|||||||
outputVariables(p),
|
outputVariables(p),
|
||||||
returningClause(nullptr),
|
returningClause(nullptr),
|
||||||
currCteAlias(NULL),
|
currCteAlias(NULL),
|
||||||
|
mainScratch(aMainScratch),
|
||||||
|
outerMessagesMap(p),
|
||||||
|
outerVarsMap(p),
|
||||||
ctes(p),
|
ctes(p),
|
||||||
cteAliases(p),
|
cteAliases(p),
|
||||||
psql(false),
|
psql(false),
|
||||||
mainScratch(aMainScratch),
|
|
||||||
subFunctions(p),
|
subFunctions(p),
|
||||||
subProcedures(p)
|
subProcedures(p)
|
||||||
{
|
{
|
||||||
@ -142,7 +144,7 @@ public:
|
|||||||
public:
|
public:
|
||||||
virtual bool isVersion4()
|
virtual bool isVersion4()
|
||||||
{
|
{
|
||||||
return statement->getBlrVersion() == 4;
|
return dsqlStatement->getBlrVersion() == 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
MemoryPool& getPool()
|
MemoryPool& getPool()
|
||||||
@ -165,14 +167,14 @@ public:
|
|||||||
transaction = value;
|
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);
|
void putBlrMarkers(ULONG marks);
|
||||||
@ -181,6 +183,7 @@ public:
|
|||||||
void putLocalVariables(CompoundStmtNode* parameters, USHORT locals);
|
void putLocalVariables(CompoundStmtNode* parameters, USHORT locals);
|
||||||
void putLocalVariable(dsql_var* variable, const DeclareVariableNode* hostParam,
|
void putLocalVariable(dsql_var* variable, const DeclareVariableNode* hostParam,
|
||||||
const MetaName& collationName);
|
const MetaName& collationName);
|
||||||
|
void putOuterMaps();
|
||||||
dsql_var* makeVariable(dsql_fld*, const char*, const dsql_var::Type type, USHORT,
|
dsql_var* makeVariable(dsql_fld*, const char*, const dsql_var::Type type, USHORT,
|
||||||
USHORT, USHORT);
|
USHORT, USHORT);
|
||||||
dsql_var* resolveVariable(const MetaName& varName);
|
dsql_var* resolveVariable(const MetaName& varName);
|
||||||
@ -269,12 +272,11 @@ private:
|
|||||||
|
|
||||||
dsql_dbb* dbb; // DSQL attachment
|
dsql_dbb* dbb; // DSQL attachment
|
||||||
jrd_tra* transaction; // Transaction
|
jrd_tra* transaction; // Transaction
|
||||||
DsqlCompiledStatement* statement; // Compiled statement
|
DsqlStatement* dsqlStatement; // DSQL statement
|
||||||
|
|
||||||
public:
|
public:
|
||||||
unsigned flags; // flags
|
unsigned flags; // flags
|
||||||
unsigned nestingLevel; // begin...end nesting level
|
unsigned nestingLevel; // begin...end nesting level
|
||||||
Firebird::Array<dsql_msg*> ports; // Port messages
|
|
||||||
dsql_rel* relation; // relation created by this request (for DDL)
|
dsql_rel* relation; // relation created by this request (for DDL)
|
||||||
DsqlContextStack mainContext;
|
DsqlContextStack mainContext;
|
||||||
DsqlContextStack* context;
|
DsqlContextStack* context;
|
||||||
@ -313,14 +315,16 @@ public:
|
|||||||
Firebird::Array<dsql_var*> outputVariables;
|
Firebird::Array<dsql_var*> outputVariables;
|
||||||
ReturningClause* returningClause;
|
ReturningClause* returningClause;
|
||||||
const Firebird::string* const* currCteAlias;
|
const Firebird::string* const* currCteAlias;
|
||||||
|
DsqlCompilerScratch* mainScratch;
|
||||||
|
Firebird::NonPooledMap<USHORT, USHORT> outerMessagesMap; // <outer, inner>
|
||||||
|
Firebird::NonPooledMap<USHORT, USHORT> outerVarsMap; // <outer, inner>
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Firebird::HalfStaticArray<SelectExprNode*, 4> ctes; // common table expressions
|
Firebird::HalfStaticArray<SelectExprNode*, 4> ctes; // common table expressions
|
||||||
Firebird::HalfStaticArray<const Firebird::string*, 4> cteAliases; // CTE aliases in recursive members
|
Firebird::HalfStaticArray<const Firebird::string*, 4> cteAliases; // CTE aliases in recursive members
|
||||||
bool psql;
|
bool psql;
|
||||||
DsqlCompilerScratch* mainScratch;
|
Firebird::LeftPooledMap<MetaName, DeclareSubFuncNode*> subFunctions;
|
||||||
Firebird::GenericMap<Firebird::Left<MetaName, DeclareSubFuncNode*> > subFunctions;
|
Firebird::LeftPooledMap<MetaName, DeclareSubProcNode*> subProcedures;
|
||||||
Firebird::GenericMap<Firebird::Left<MetaName, DeclareSubProcNode*> > subProcedures;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class PsqlChanger
|
class PsqlChanger
|
||||||
|
@ -35,13 +35,13 @@ using namespace Jrd;
|
|||||||
static const char* const SCRATCH = "fb_cursor_";
|
static const char* const SCRATCH = "fb_cursor_";
|
||||||
static const ULONG PREFETCH_SIZE = 65536; // 64 KB
|
static const ULONG PREFETCH_SIZE = 65536; // 64 KB
|
||||||
|
|
||||||
DsqlCursor::DsqlCursor(dsql_req* req, ULONG flags)
|
DsqlCursor::DsqlCursor(DsqlDmlRequest* req, ULONG flags)
|
||||||
: m_request(req), m_message(req->getStatement()->getReceiveMsg()),
|
: m_dsqlRequest(req), m_message(req->getDsqlStatement()->getReceiveMsg()),
|
||||||
m_resultSet(NULL), m_flags(flags),
|
m_resultSet(NULL), m_flags(flags),
|
||||||
m_space(req->getPool(), SCRATCH),
|
m_space(req->getPool(), SCRATCH),
|
||||||
m_state(BOS), m_eof(false), m_position(0), m_cachedCount(0)
|
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()
|
DsqlCursor::~DsqlCursor()
|
||||||
@ -52,12 +52,12 @@ DsqlCursor::~DsqlCursor()
|
|||||||
|
|
||||||
jrd_tra* DsqlCursor::getTransaction() const
|
jrd_tra* DsqlCursor::getTransaction() const
|
||||||
{
|
{
|
||||||
return m_request->req_transaction;
|
return m_dsqlRequest->req_transaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
Attachment* DsqlCursor::getAttachment() const
|
Attachment* DsqlCursor::getAttachment() const
|
||||||
{
|
{
|
||||||
return m_request->req_dbb->dbb_attachment;
|
return m_dsqlRequest->req_dbb->dbb_attachment;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DsqlCursor::setInterfacePtr(JResultSet* interfacePtr) throw()
|
void DsqlCursor::setInterfacePtr(JResultSet* interfacePtr) throw()
|
||||||
@ -71,35 +71,35 @@ void DsqlCursor::close(thread_db* tdbb, DsqlCursor* cursor)
|
|||||||
if (!cursor)
|
if (!cursor)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Jrd::Attachment* const attachment = cursor->getAttachment();
|
const auto attachment = cursor->getAttachment();
|
||||||
dsql_req* const request = cursor->m_request;
|
const auto dsqlRequest = cursor->m_dsqlRequest;
|
||||||
|
|
||||||
if (request->req_request)
|
if (dsqlRequest->getRequest())
|
||||||
{
|
{
|
||||||
ThreadStatusGuard status_vector(tdbb);
|
ThreadStatusGuard status_vector(tdbb);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Report some remaining fetches if any
|
// 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);
|
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);
|
TraceManager::event_dsql_free(attachment, &stmt, DSQL_close);
|
||||||
}
|
}
|
||||||
|
|
||||||
JRD_unwind_request(tdbb, request->req_request);
|
JRD_unwind_request(tdbb, dsqlRequest->getRequest());
|
||||||
}
|
}
|
||||||
catch (Firebird::Exception&)
|
catch (Firebird::Exception&)
|
||||||
{} // no-op
|
{} // no-op
|
||||||
}
|
}
|
||||||
|
|
||||||
request->req_cursor = NULL;
|
dsqlRequest->req_cursor = NULL;
|
||||||
TRA_unlink_cursor(request->req_transaction, cursor);
|
TRA_unlink_cursor(dsqlRequest->req_transaction, cursor);
|
||||||
delete cursor;
|
delete cursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,7 +107,7 @@ int DsqlCursor::fetchNext(thread_db* tdbb, UCHAR* buffer)
|
|||||||
{
|
{
|
||||||
if (!(m_flags & IStatement::CURSOR_TYPE_SCROLLABLE))
|
if (!(m_flags & IStatement::CURSOR_TYPE_SCROLLABLE))
|
||||||
{
|
{
|
||||||
m_eof = !m_request->fetch(tdbb, buffer);
|
m_eof = !m_dsqlRequest->fetch(tdbb, buffer);
|
||||||
|
|
||||||
if (m_eof)
|
if (m_eof)
|
||||||
{
|
{
|
||||||
@ -300,13 +300,13 @@ int DsqlCursor::fetchFromCache(thread_db* tdbb, UCHAR* buffer, FB_UINT64 positio
|
|||||||
|
|
||||||
fb_assert(position < m_cachedCount);
|
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 offset = position * m_message->msg_length;
|
||||||
const FB_UINT64 readBytes = m_space.read(offset, msgBuffer, m_message->msg_length);
|
const FB_UINT64 readBytes = m_space.read(offset, msgBuffer, m_message->msg_length);
|
||||||
fb_assert(readBytes == 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_position = position;
|
||||||
m_state = POSITIONED;
|
m_state = POSITIONED;
|
||||||
@ -318,13 +318,13 @@ bool DsqlCursor::cacheInput(thread_db* tdbb, FB_UINT64 position)
|
|||||||
fb_assert(!m_eof);
|
fb_assert(!m_eof);
|
||||||
|
|
||||||
const ULONG prefetchCount = MAX(PREFETCH_SIZE / m_message->msg_length, 1);
|
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)
|
while (position >= m_cachedCount)
|
||||||
{
|
{
|
||||||
for (ULONG count = 0; count < prefetchCount; count++)
|
for (ULONG count = 0; count < prefetchCount; count++)
|
||||||
{
|
{
|
||||||
if (!m_request->fetch(tdbb, NULL))
|
if (!m_dsqlRequest->fetch(tdbb, NULL))
|
||||||
{
|
{
|
||||||
m_eof = true;
|
m_eof = true;
|
||||||
break;
|
break;
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
namespace Jrd {
|
namespace Jrd {
|
||||||
|
|
||||||
class dsql_req;
|
class DsqlDmlRequest;
|
||||||
class JResultSet;
|
class JResultSet;
|
||||||
|
|
||||||
class DsqlCursor
|
class DsqlCursor
|
||||||
@ -35,7 +35,7 @@ class DsqlCursor
|
|||||||
enum State { BOS, POSITIONED, EOS };
|
enum State { BOS, POSITIONED, EOS };
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DsqlCursor(dsql_req* req, ULONG flags);
|
DsqlCursor(DsqlDmlRequest* req, ULONG flags);
|
||||||
~DsqlCursor();
|
~DsqlCursor();
|
||||||
|
|
||||||
jrd_tra* getTransaction() const;
|
jrd_tra* getTransaction() const;
|
||||||
@ -69,7 +69,7 @@ private:
|
|||||||
int fetchFromCache(thread_db* tdbb, UCHAR* buffer, FB_UINT64 position);
|
int fetchFromCache(thread_db* tdbb, UCHAR* buffer, FB_UINT64 position);
|
||||||
bool cacheInput(thread_db* tdbb, FB_UINT64 position = MAX_UINT64);
|
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;
|
const dsql_msg* const m_message;
|
||||||
JResultSet* m_resultSet;
|
JResultSet* m_resultSet;
|
||||||
const ULONG m_flags;
|
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