mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-22 20:43:02 +01:00
Merge branch 'master' into ExternalConnectionsPool
This commit is contained in:
commit
2930edb9c0
3
.gitignore
vendored
3
.gitignore
vendored
@ -15,6 +15,7 @@ libtool
|
||||
*.log
|
||||
*.bak
|
||||
*.tmp
|
||||
*.d
|
||||
src/dsql/parse.cpp
|
||||
.vscode/.browse.VC.db
|
||||
extern/decNumber/libdecFloat.a
|
||||
extern/decNumber/libdecFloat*.a
|
||||
|
@ -811,6 +811,17 @@
|
||||
#
|
||||
#EventMemSize = 64K
|
||||
|
||||
# ----------------------------
|
||||
#
|
||||
# File to redirect stdout and stderr output of server
|
||||
#
|
||||
# Default '/dev/null' for *nix and 'nul' for Windows
|
||||
# Empty value or '-' keeps stdout and stderr as is.
|
||||
#
|
||||
# Type: string
|
||||
#
|
||||
#OutputRedirectionFile = /dev/null
|
||||
|
||||
|
||||
# ===========================
|
||||
# Engine Settings
|
||||
|
@ -228,6 +228,8 @@ checkLibraries() {
|
||||
then
|
||||
checkLibrary tomcrypt
|
||||
fi
|
||||
|
||||
checkLibrary icudata
|
||||
}
|
||||
|
||||
|
||||
@ -237,7 +239,7 @@ checkLibraries() {
|
||||
grepProcess() {
|
||||
processList=$1
|
||||
eol=\$
|
||||
ps $psOptions | egrep "\<($processList)($eol|[[:space:]])" | grep -v grep
|
||||
ps $psOptions | egrep "\<($processList)($eol|[[:space:]])" | grep -v grep | grep -v -w '\-path'
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
# install - install a program, script, or datafile
|
||||
|
||||
scriptversion=2013-12-25.23; # UTC
|
||||
scriptversion=2016-01-11.22; # UTC
|
||||
|
||||
# This originates from X11R5 (mit/util/scripts/install.sh), which was
|
||||
# later released in X11R6 (xc/config/util/install.sh) with the
|
||||
@ -496,6 +496,6 @@ done
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC"
|
||||
# time-stamp-time-zone: "UTC0"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
||||
|
@ -35,12 +35,18 @@
|
||||
|
||||
ROOT=$(shell cd ..; pwd)
|
||||
|
||||
ifeq ($(CROSS_OUT), Y)
|
||||
export CROSS:=CrossBuild
|
||||
endif
|
||||
|
||||
include make.defaults
|
||||
|
||||
ifeq ($(CROSS_OUT), Y)
|
||||
include make.crossPlatform
|
||||
else
|
||||
include make.platform
|
||||
endif
|
||||
|
||||
include make.rules
|
||||
include make.shared.variables
|
||||
|
||||
@ -185,7 +191,11 @@ $(TOMMATH_LIB): $(TOM_Objs)
|
||||
|
||||
.PHONY: tomcrypt
|
||||
TOMCRYPT_LIB=$(LIB)/libtomcrypt.a
|
||||
TOM_Objs=$(addprefix ../extern/libtomcrypt/,$(call doObjects,$(call dirFiles,../extern/libtomcrypt)))
|
||||
|
||||
TOM_Src:=hashes/md5.c hashes/sha1.c hashes/sha2/sha256.c hashes/sha2/sha512.c misc/crypt/crypt_argchk.c
|
||||
TOM_Src:=$(addprefix ../extern/libtomcrypt/src/, $(TOM_Src))
|
||||
|
||||
TOM_Objs=$(call doObjects,$(TOM_Src))
|
||||
|
||||
tomcrypt: $(TOMCRYPT_LIB)
|
||||
|
||||
@ -194,10 +204,10 @@ $(TOMCRYPT_LIB): $(TOM_Objs)
|
||||
$(STATICLIB_LINK) $@ $^
|
||||
|
||||
#___________________________________________________________________________
|
||||
# main build target for both debug abd release builds
|
||||
# main build target for both debug and release builds
|
||||
#
|
||||
|
||||
.PHONY: cross1 cross2 boot yvalve engine fbintl gpre utilities plugins rest codes ids examples cross_rest
|
||||
.PHONY: cross1 cross2 boot yvalve engine fbintl gpre utilities plugins rest codes ids examples cross_rest preliminaryCheck
|
||||
|
||||
master_process:
|
||||
ln -sf $(SRC_ROOT)/include/gen/autoconfig.auto $(SRC_ROOT)/include/gen/autoconfig.h
|
||||
@ -205,6 +215,7 @@ master_process:
|
||||
$(MAKE) export_lists
|
||||
$(MAKE) external
|
||||
$(MAKE) updateCloopInterfaces
|
||||
$(MAKE) preliminaryCheck
|
||||
$(MAKE) boot
|
||||
$(MAKE) yvalve
|
||||
ifeq ($(IsDeveloper), Y)
|
||||
@ -264,6 +275,8 @@ cross2:
|
||||
$(MAKE) prerequisites
|
||||
$(MAKE) tommath
|
||||
$(MAKE) tomcrypt
|
||||
$(MAKE) -C $(ROOT)/extern/decNumber
|
||||
ln -sf $(ROOT)/extern/decNumber/libdecFloat$(CROSS).a $(LIB)
|
||||
$(MAKE) yvalve
|
||||
$(MAKE) engine
|
||||
$(MAKE) fbintl
|
||||
@ -273,6 +286,26 @@ cross2:
|
||||
$(MAKE) -f Makefile.plugins_examples
|
||||
$(MAKE) cross_rest
|
||||
|
||||
|
||||
#___________________________________________________________________________
|
||||
# preliminary checks - make sure platform is OK to build FB
|
||||
#
|
||||
|
||||
STD_SIZES:=$(SRC_ROOT)/misc/ods.txt
|
||||
RUN_SIZES:=$(GEN_ROOT)/ods.txt
|
||||
ODS_H:=$(SRC_ROOT)/jrd/ods.h
|
||||
ODS_AWK:=$(SRC_ROOT)/misc/ods.awk
|
||||
ODS_TEST_CPP:=$(GEN_ROOT)/odstest.cpp
|
||||
ODS_TEST:=$(GEN_ROOT)/odstest$(EXEC_EXT)
|
||||
|
||||
preliminaryCheck: $(STD_SIZES) $(RUN_SIZES)
|
||||
diff -u $^
|
||||
|
||||
$(RUN_SIZES): $(ODS_H) $(ODS_AWK)
|
||||
awk -f $(ODS_AWK) <$(ODS_H) >$(ODS_TEST_CPP)
|
||||
$(CXX) -o $(ODS_TEST) $(WCXXFLAGS) $(ODS_TEST_CPP)
|
||||
$(ODS_TEST) >$(RUN_SIZES)
|
||||
|
||||
#___________________________________________________________________________
|
||||
# static library - various common code, used in different FB projects
|
||||
#
|
||||
@ -535,7 +568,7 @@ udf_compat: $(UDF_BACKWARD_COMPATIBILITY) $(COMPAT_SQL)
|
||||
|
||||
$(UDF_BACKWARD_COMPATIBILITY): $(COMPAT_Objects)
|
||||
$(LIB_LINK) $(LIB_LINK_OPTIONS) $(call LIB_LINK_SONAME,$(UDF_BACKWARD_COMPATIBILITY_BASENAME)) \
|
||||
$(LINK_UDR_PLUGIN_SYMBOLS) $(LIB_PATH_OPTS) $(UNDEF_FLAGS) -o $@ $^ $(THR_LIBS)
|
||||
$(LINK_UDR_PLUGIN_SYMBOLS) $(LIB_PATH_OPTS) $(UNDEF_FLAGS) -o $@ $^ $(THR_LIBS) $(UDR_SUPPORT_LIBS)
|
||||
|
||||
$(COMPAT_SQL): $(SRC_COMPAT_SQL)
|
||||
cp $^ $@
|
||||
|
@ -20,7 +20,10 @@ HOST_TAG64:=linux-x86
|
||||
endif
|
||||
NDK_TOOLCHAIN_VERSION:=$(shell echo $(TOOLCHAIN_DIR) | awk -F - '{print $$NF;}')
|
||||
|
||||
CROSS_PLATFORM:=$(NDK)/platforms/android-24/arch-arm
|
||||
CROSS_PLATFORM:=$(NDK)/platforms
|
||||
ALEVEL:=$(shell for i in `seq 256`; do [ -d $(CROSS_PLATFORM)/android-$${i} ] && adir=$${i}; done; echo $${adir})
|
||||
CROSS_PLATFORM:=$(CROSS_PLATFORM)/android-$(ALEVEL)/arch-arm
|
||||
|
||||
CROSS_PREFIX:=$(NDK)/toolchains/$(TOOLCHAIN_DIR)/prebuilt/$(HOST_TAG64)/bin/arm-linux-androideabi-
|
||||
|
||||
CXX:=$(CROSS_PREFIX)g++
|
||||
@ -34,12 +37,20 @@ OBJDUMP:=$(CROSS_PREFIX)objdump
|
||||
RANLIB:=$(CROSS_PREFIX)ranlib
|
||||
STRIP:=$(CROSS_PREFIX)strip
|
||||
|
||||
COMMON_FLAGS=-ggdb -DFB_SEND_FLAGS=MSG_NOSIGNAL -DLINUX -DANDROID -DARM -pipe -MMD -fPIC -fmessage-length=0 \
|
||||
-I$(ROOT)/extern/libtommath --sysroot=$(CROSS_PLATFORM) \
|
||||
-I$(CROSS_PLATFORM)/usr/include -I$(ROOT)/gen/cross \
|
||||
-I$(NDK)/sources/cxx-stl/gnu-libstdc++/$(NDK_TOOLCHAIN_VERSION)/include \
|
||||
-I$(NDK)/sources/cxx-stl/gnu-libstdc++/$(NDK_TOOLCHAIN_VERSION)/libs/armeabi/include
|
||||
export CXX
|
||||
export CC
|
||||
export AR
|
||||
|
||||
CROSS_FLAGS=--sysroot=$(CROSS_PLATFORM) \
|
||||
-I$(CROSS_PLATFORM)/usr/include -I$(ROOT)/gen/cross \
|
||||
-I$(NDK)/sources/cxx-stl/gnu-libstdc++/$(NDK_TOOLCHAIN_VERSION)/include \
|
||||
-I$(NDK)/sources/cxx-stl/gnu-libstdc++/$(NDK_TOOLCHAIN_VERSION)/libs/armeabi/include
|
||||
|
||||
export CROSS_FLAGS
|
||||
|
||||
COMMON_FLAGS=-ggdb -DFB_SEND_FLAGS=MSG_NOSIGNAL -DLINUX -DANDROID -DARM -pipe -MMD -fPIC -fmessage-length=0 \
|
||||
-I$(ROOT)/extern/libtommath -I$(ROOT)/extern/libtomcrypt/src/headers \
|
||||
$(CROSS_FLAGS)
|
||||
|
||||
OPTIMIZE_FLAGS=-fno-omit-frame-pointer
|
||||
WARN_FLAGS=-Wall -Wno-switch -Wno-parentheses -Wno-unknown-pragmas -Wno-unused-variable
|
||||
@ -53,7 +64,8 @@ CROSS_CONFIG=android.arme
|
||||
|
||||
LDFLAGS += --sysroot=$(CROSS_PLATFORM) -L$(NDK)/sources/cxx-stl/gnu-libstdc++/$(NDK_TOOLCHAIN_VERSION)/libs/armeabi \
|
||||
-L$(NDK)/sources/cxx-stl/gnu-libstdc++/libs/armeabi
|
||||
DroidLibs := -lm -ldl -lsupc++
|
||||
DroidLibs := -lm -ldl -lsupc++ $(DECLIB)
|
||||
UDR_SUPPORT_LIBS := -lgnustl_shared
|
||||
|
||||
LINK_LIBS = $(DroidLibs)
|
||||
SO_LINK_LIBS = $(DroidLibs)
|
||||
|
@ -133,7 +133,7 @@ CAS_OPTIONS=@CAS_OPTIONS@
|
||||
|
||||
# multiple-precision integer library
|
||||
MATHLIB=@MATHLIB@
|
||||
DECLIB=-ldecFloat
|
||||
DECLIB=-ldecFloat$(CROSS)
|
||||
|
||||
# crypt library
|
||||
CRYPTLIB=@CRYPTLIB@
|
||||
@ -291,6 +291,7 @@ LINK_UDR_PLUGIN_SYMBOLS = $(call LIB_LINK_MAPFILE,$(UDR_PLUGIN_VERS))
|
||||
LINK_EMPTY_SYMBOLS = $(call LIB_LINK_MAPFILE,$(EMPTY_VERS))
|
||||
LINK_PLUGIN_SYMBOLS = $(call LIB_LINK_MAPFILE,$(PLUGIN_VERS))
|
||||
LINK_EXEC_EXPORT=-rdynamic
|
||||
UDR_SUPPORT_LIBS=
|
||||
|
||||
LIB_PLATFORM_RPATH = -Wl,-rpath,$(1)
|
||||
|
||||
|
@ -74,7 +74,7 @@ WCXXFLAGS = $(WFLAGS) $(THR_FLAGS) $(RTTI_FLAG) $(CXXFLAGS) $(GLOB_OPTIONS)
|
||||
|
||||
GPRE_FLAGS= -m -z -n
|
||||
JRD_GPRE_FLAGS = -n -z -gds_cxx -ids
|
||||
ISQL_GPRE_FLAGS = -m -z -n -ocxx
|
||||
OBJECT_GPRE_FLAGS = -m -z -n -ocxx
|
||||
|
||||
|
||||
.SUFFIXES: .c .e .epp .cpp
|
||||
@ -87,7 +87,10 @@ $(OBJ)/jrd/%.cpp: $(SRC_ROOT)/jrd/%.epp
|
||||
$(GPRE_CURRENT) $(JRD_GPRE_FLAGS) $(firstword $<) $@
|
||||
|
||||
$(OBJ)/isql/%.cpp: $(SRC_ROOT)/isql/%.epp
|
||||
$(GPRE_CURRENT) $(ISQL_GPRE_FLAGS) $< $@
|
||||
$(GPRE_CURRENT) $(OBJECT_GPRE_FLAGS) $< $@
|
||||
|
||||
$(OBJ)/burp/%.cpp: $(SRC_ROOT)/burp/%.epp
|
||||
$(GPRE_CURRENT) $(OBJECT_GPRE_FLAGS) $< $@
|
||||
|
||||
$(OBJ)/%.cpp: $(SRC_ROOT)/%.epp
|
||||
$(GPRE_CURRENT) $(GPRE_FLAGS) $(firstword $<) $@
|
||||
|
@ -20,10 +20,9 @@
|
||||
|
||||
#LD=@CXX@
|
||||
|
||||
#PROD_FLAGS=-ggdb -O3 -fno-omit-frame-pointer -DLINUX -pipe -MMD -fPIC
|
||||
#DEV_FLAGS=-ggdb -DLINUX -DDEBUG_GDS_ALLOC -pipe -MMD -p -fPIC -Wall -Wno-switch
|
||||
COMMON_FLAGS=-DLINUX -DARM -pipe -MMD -fPIC -fsigned-char -fmessage-length=0 -DFB_SEND_FLAGS=MSG_NOSIGNAL
|
||||
|
||||
PROD_FLAGS=-O3 -DLINUX -DARM -pipe -p -MMD -fPIC -fsigned-char -fmessage-length=0
|
||||
DEV_FLAGS=-ggdb -DLINUX -DARM -pipe -p -MMD -fPIC -Wall -fsigned-char -fmessage-length=0 -Wno-non-virtual-dtor
|
||||
PROD_FLAGS=$(COMMON_FLAGS) -O3
|
||||
DEV_FLAGS=$(COMMON_FLAGS) -p -ggdb -Wall -Wno-non-virtual-dtor
|
||||
|
||||
CXXFLAGS := $(CXXFLAGS) -std=c++11
|
||||
|
@ -25,6 +25,7 @@
|
||||
<ClCompile Include="..\..\..\src\common\CharSet.cpp" />
|
||||
<ClCompile Include="..\..\..\src\common\classes\alloc.cpp" />
|
||||
<ClCompile Include="..\..\..\src\common\classes\BaseStream.cpp" />
|
||||
<ClCompile Include="..\..\..\src\common\classes\BlobWrapper.cpp" />
|
||||
<ClCompile Include="..\..\..\src\common\classes\BlrWriter.cpp" />
|
||||
<ClCompile Include="..\..\..\src\common\classes\ClumpletReader.cpp" />
|
||||
<ClCompile Include="..\..\..\src\common\classes\ClumpletWriter.cpp" />
|
||||
@ -110,6 +111,7 @@
|
||||
<ClInclude Include="..\..\..\src\common\classes\auto.h" />
|
||||
<ClInclude Include="..\..\..\src\common\classes\BaseStream.h" />
|
||||
<ClInclude Include="..\..\..\src\common\classes\BatchCompletionState.h" />
|
||||
<ClInclude Include="..\..\..\src\common\classes\BlobWrapper.h" />
|
||||
<ClInclude Include="..\..\..\src\common\classes\BlrReader.h" />
|
||||
<ClInclude Include="..\..\..\src\common\classes\BlrWriter.h" />
|
||||
<ClInclude Include="..\..\..\src\common\classes\ByteChunk.h" />
|
||||
|
@ -222,6 +222,9 @@
|
||||
<ClCompile Include="..\..\..\src\common\classes\TomCryptHash.cpp">
|
||||
<Filter>classes</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\src\common\classes\BlobWrapper.cpp">
|
||||
<Filter>classes</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\..\src\common\xdr_proto.h">
|
||||
@ -542,5 +545,8 @@
|
||||
<ClInclude Include="..\..\..\src\common\classes\BatchCompletionState.h">
|
||||
<Filter>headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\src\common\classes\BlobWrapper.h">
|
||||
<Filter>headers</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -25,6 +25,7 @@
|
||||
<ClCompile Include="..\..\..\src\common\CharSet.cpp" />
|
||||
<ClCompile Include="..\..\..\src\common\classes\alloc.cpp" />
|
||||
<ClCompile Include="..\..\..\src\common\classes\BaseStream.cpp" />
|
||||
<ClCompile Include="..\..\..\src\common\classes\BlobWrapper.cpp" />
|
||||
<ClCompile Include="..\..\..\src\common\classes\BlrWriter.cpp" />
|
||||
<ClCompile Include="..\..\..\src\common\classes\ClumpletReader.cpp" />
|
||||
<ClCompile Include="..\..\..\src\common\classes\ClumpletWriter.cpp" />
|
||||
@ -106,6 +107,7 @@
|
||||
<ClInclude Include="..\..\..\src\common\classes\auto.h" />
|
||||
<ClInclude Include="..\..\..\src\common\classes\BaseStream.h" />
|
||||
<ClInclude Include="..\..\..\src\common\classes\BatchCompletionState.h" />
|
||||
<ClInclude Include="..\..\..\src\common\classes\BlobWrapper.h" />
|
||||
<ClInclude Include="..\..\..\src\common\classes\BlrReader.h" />
|
||||
<ClInclude Include="..\..\..\src\common\classes\BlrWriter.h" />
|
||||
<ClInclude Include="..\..\..\src\common\classes\ByteChunk.h" />
|
||||
|
@ -222,6 +222,9 @@
|
||||
<ClCompile Include="..\..\..\src\common\classes\TomCryptHash.cpp">
|
||||
<Filter>classes</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\src\common\classes\BlobWrapper.cpp">
|
||||
<Filter>classes</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\..\src\common\xdr_proto.h">
|
||||
@ -542,5 +545,8 @@
|
||||
<ClInclude Include="..\..\..\src\common\classes\BatchCompletionState.h">
|
||||
<Filter>headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\src\common\classes\BlobWrapper.h">
|
||||
<Filter>headers</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -25,6 +25,7 @@
|
||||
<ClCompile Include="..\..\..\src\common\CharSet.cpp" />
|
||||
<ClCompile Include="..\..\..\src\common\classes\alloc.cpp" />
|
||||
<ClCompile Include="..\..\..\src\common\classes\BaseStream.cpp" />
|
||||
<ClCompile Include="..\..\..\src\common\classes\BlobWrapper.cpp" />
|
||||
<ClCompile Include="..\..\..\src\common\classes\BlrWriter.cpp" />
|
||||
<ClCompile Include="..\..\..\src\common\classes\ClumpletReader.cpp" />
|
||||
<ClCompile Include="..\..\..\src\common\classes\ClumpletWriter.cpp" />
|
||||
@ -106,6 +107,7 @@
|
||||
<ClInclude Include="..\..\..\src\common\classes\auto.h" />
|
||||
<ClInclude Include="..\..\..\src\common\classes\BaseStream.h" />
|
||||
<ClInclude Include="..\..\..\src\common\classes\BatchCompletionState.h" />
|
||||
<ClInclude Include="..\..\..\src\common\classes\BlobWrapper.h" />
|
||||
<ClInclude Include="..\..\..\src\common\classes\BlrReader.h" />
|
||||
<ClInclude Include="..\..\..\src\common\classes\BlrWriter.h" />
|
||||
<ClInclude Include="..\..\..\src\common\classes\ByteChunk.h" />
|
||||
|
@ -222,6 +222,9 @@
|
||||
<ClCompile Include="..\..\..\src\common\classes\TomCryptHash.cpp">
|
||||
<Filter>classes</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\src\common\classes\BlobWrapper.cpp">
|
||||
<Filter>classes</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\..\src\common\xdr_proto.h">
|
||||
@ -542,5 +545,8 @@
|
||||
<ClInclude Include="..\..\..\src\common\classes\BatchCompletionState.h">
|
||||
<Filter>headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\src\common\classes\BlobWrapper.h">
|
||||
<Filter>headers</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -55,10 +55,7 @@ goto :EOF
|
||||
:BOOT_PROCESS
|
||||
@echo.
|
||||
@set GPRE=%FB_BIN_DIR%\gpre_boot -lang_internal
|
||||
@for %%i in (array, blob) do @call :PREPROCESS yvalve %%i
|
||||
@for %%i in (metd, DdlNodes, PackageNodes) do @call :PREPROCESS dsql %%i -gds_cxx
|
||||
@for %%i in (gpre_meta) do @call :PREPROCESS gpre/std %%i
|
||||
@for %%i in (backup, restore, OdsDetection) do @call :PREPROCESS burp %%i
|
||||
@for %%i in (backup, restore, OdsDetection) do @call :PREPROCESS burp %%i -ocxx -m
|
||||
@for %%i in (extract, isql, show) do @call :PREPROCESS isql %%i -ocxx
|
||||
@for %%i in (dba) do @call :PREPROCESS utilities/gstat %%i
|
||||
|
||||
@ -76,7 +73,7 @@ goto :EOF
|
||||
@set GPRE=%FB_BIN_DIR%\gpre
|
||||
@for %%i in (alice_meta) do @call :PREPROCESS alice %%i
|
||||
@for %%i in (LegacyManagement) do @call :PREPROCESS auth/SecurityDatabase %%i
|
||||
@for %%i in (backup, restore, OdsDetection) do @call :PREPROCESS burp %%i
|
||||
@for %%i in (backup, restore, OdsDetection) do @call :PREPROCESS burp %%i -ocxx -m
|
||||
@for %%i in (array, blob) do @call :PREPROCESS yvalve %%i
|
||||
@for %%i in (metd) do @call :PREPROCESS dsql %%i -gds_cxx
|
||||
@for %%i in (DdlNodes, PackageNodes) do @call :PREPROCESS dsql %%i -gds_cxx
|
||||
|
18
configure.ac
18
configure.ac
@ -249,6 +249,18 @@ dnl CPU_TYPE=ppc64
|
||||
libdir=/usr/lib64
|
||||
;;
|
||||
|
||||
riscv64*-*-linux*)
|
||||
MAKEFILE_PREFIX=linux_riscv64
|
||||
INSTALL_PREFIX=linux
|
||||
PLATFORM=LINUX
|
||||
AC_DEFINE(LINUX, 1, [Define this if OS is Linux])
|
||||
EDITLINE_FLG=Y
|
||||
SHRLIB_EXT=so
|
||||
STD_EDITLINE=true
|
||||
STD_ICU=true
|
||||
libdir=/usr/lib64
|
||||
;;
|
||||
|
||||
powerpc64le-*-linux*)
|
||||
MAKEFILE_PREFIX=linux_powerpc64el
|
||||
INSTALL_PREFIX=linux
|
||||
@ -1211,7 +1223,6 @@ dnl ### GEN ### directories for databases and misc
|
||||
dnl # output
|
||||
mkdir -p gen/\$fb_tgt/include
|
||||
mkdir -p gen/\$fb_tgt/intl
|
||||
mkdir -p gen/\$fb_tgt/firebird/UDF
|
||||
mkdir -p gen/\$fb_tgt/firebird/bin
|
||||
mkdir -p gen/\$fb_tgt/firebird/plugins
|
||||
mkdir -p gen/\$fb_tgt/firebird/examples/api
|
||||
@ -1238,11 +1249,6 @@ dnl ### TEMP ### directories for generated .cpp, .o and .d by module name
|
||||
done
|
||||
|
||||
src/misc/writeBuildNum.sh createMakeVersion gen/Make.Version
|
||||
|
||||
dnl # sql files for UDF declarations
|
||||
for sql_file in ib_udf.sql fbudf/fbudf.sql ib_udf2.sql; do
|
||||
cp src/extlib/\$sql_file gen/\$fb_tgt/firebird/UDF
|
||||
done
|
||||
done
|
||||
|
||||
dnl # rebuild version header if needed
|
||||
|
@ -3,27 +3,16 @@
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
|
||||
<title></title>
|
||||
<meta name="generator" content="LibreOffice 5.2.7.2 (Linux)"/>
|
||||
<meta name="generator" content="LibreOffice 5.4.5.1 (Linux)"/>
|
||||
<meta name="author" content="alex "/>
|
||||
<meta name="created" content="00:00:00"/>
|
||||
<meta name="changed" content="2017-10-19T18:08:13.851823604"/>
|
||||
<meta name="created" content="2013-05-31T00:00:00.010003100"/>
|
||||
<meta name="changed" content="2018-05-10T18:16:59.126724786"/>
|
||||
<meta name="created" content="00:00:00">
|
||||
<meta name="created" content="00:00:00">
|
||||
<meta name="changed" content="2017-10-12T20:21:46.080329427">
|
||||
<meta name="created" content="00:00:00">
|
||||
<meta name="changed" content="2017-10-10T12:13:42.449014488">
|
||||
<meta name="created" content="00:00:00">
|
||||
<meta name="changed" content="2017-07-27T13:17:58.205479048">
|
||||
<meta name="created" content="00:00:00">
|
||||
<meta name="changed" content="2017-07-26T10:39:38.045248271">
|
||||
<meta name="changed" content="2017-10-16T18:57:56.725603578"/>
|
||||
<meta name="created" content="00:00:00">
|
||||
<meta name="changed" content="2017-02-02T17:00:07.121995034">
|
||||
<meta name="created" content="2013-05-31T00:00:00.010003100">
|
||||
<meta name="changed" content="2017-01-31T17:08:57.272616325">
|
||||
<meta name="CHANGEDBY" content="Alex Peshkoff">
|
||||
<meta name="CHANGEDBY" content="Alex Peshkoff">
|
||||
<meta name="CHANGEDBY" content="Alex Peshkoff">
|
||||
<meta name="CHANGEDBY" content="Alex Peshkoff">
|
||||
<style type="text/css">
|
||||
@page { size: 21.59cm 27.94cm; margin: 2.01cm }
|
||||
h1 { color: #000000 }
|
||||
@ -44,10 +33,9 @@ independent</b></font> – <font size="4" style="font-size: 14pt">that
|
||||
means that to define/use them one need not use language specific
|
||||
constructions like </font><font size="4" style="font-size: 14pt"><i>class</i></font>
|
||||
<font size="4" style="font-size: 14pt">in C++, interface may be
|
||||
defined using any language </font><font size="4" style="font-size: 14pt">able
|
||||
to call functions using C calling conventions and </font><font size="4" style="font-size: 14pt">having
|
||||
concepts of array and pointer to procedure/function. Next interfaces
|
||||
are </font><span style="font-variant: normal"><font size="4" style="font-size: 14pt"><span style="font-style: normal"><b>versioned</b></span></font></span>
|
||||
defined using any language able to call functions using C calling
|
||||
conventions and having concepts of array and pointer to
|
||||
procedure/function. Next interfaces are </font><span style="font-variant: normal"><font size="4" style="font-size: 14pt"><span style="font-style: normal"><b>versioned</b></span></font></span>
|
||||
– <font size="4" style="font-size: 14pt">i.e. we support different
|
||||
versions of same interface. Binary layout of interfaces is designed
|
||||
to support that features very efficient (there is no need in
|
||||
@ -1326,13 +1314,12 @@ implementation into dynamic library (.dll in windows or .so in linux)
|
||||
later referenced as </font><font size="4" style="font-size: 14pt"><i>plugin
|
||||
module</i></font> <font size="4" style="font-size: 14pt">or just
|
||||
</font><font size="4" style="font-size: 14pt"><i>module</i></font><font size="4" style="font-size: 14pt">.
|
||||
In most cases single plugin is place</font><font size="4" style="font-size: 14pt">d</font><font size="4" style="font-size: 14pt">
|
||||
in</font><font size="4" style="font-size: 14pt">to</font><font size="4" style="font-size: 14pt">
|
||||
dynamic library but in common case </font><font size="4" style="font-size: 14pt">multiple
|
||||
plugins may coexist in single dynamic library</font><font size="4" style="font-size: 14pt">.
|
||||
One of that interfaces – <a href="#PluginModule">IPluginModule</a>
|
||||
– is module-wide (as more or less clear from it's name), others are
|
||||
per plugin. Also each plugin module should contain special exported
|
||||
In most cases single plugin is placed</font> <font size="4" style="font-size: 14pt">into</font>
|
||||
<font size="4" style="font-size: 14pt">dynamic library but in common
|
||||
case multiple plugins may coexist in single dynamic library. One of
|
||||
that interfaces – <a href="#PluginModule">IPluginModule</a> – is
|
||||
module-wide (as more or less clear from it's name), others are per
|
||||
plugin. Also each plugin module should contain special exported
|
||||
entrypoint firebird_plugin() which name is defined in include file
|
||||
firebird/Interfaces.h as FB_PLUGIN_ENTRY_POINT.</font></p>
|
||||
<p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">In
|
||||
@ -1844,17 +1831,15 @@ parameters in single statement execution.</font></p>
|
||||
<li/>
|
||||
<p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
|
||||
addBlob(StatusType* status, unsigned</font> <font size="4" style="font-size: 14pt">length,
|
||||
const void* inBuffer, ISC_QUAD* blobId, </font><font size="4" style="font-size: 14pt">unsigned
|
||||
bpbLength, const unsigned char* bpb</font><font size="4" style="font-size: 14pt">)
|
||||
– adds single blob having length bytes from inBuffer to the batch,
|
||||
blob identifier is located at blobId address. </font><font size="4" style="font-size: 14pt">If
|
||||
blob should be created with non-default parameters BPB may be passed
|
||||
(format matches one used in <a href="#Attachment">Attachment</a>::createBlob).</font><font size="4" style="font-size: 14pt">Total
|
||||
size of inline blobs that can be added to the batch </font><font size="4" style="font-size: 14pt">(including
|
||||
const void* inBuffer, ISC_QUAD* blobId, unsigned bpbLength, const
|
||||
unsigned char* bpb) – adds single blob having length bytes from
|
||||
inBuffer to the batch, blob identifier is located at blobId address.
|
||||
If blob should be created with non-default parameters BPB may be
|
||||
passed (format matches one used in <a href="#Attachment">Attachment</a>::createBlob).Total
|
||||
size of inline blobs that can be added to the batch (including
|
||||
optional BPBs, blob headers, segment sizes and taking into an
|
||||
accoount alignment) </font><font size="4" style="font-size: 14pt">is
|
||||
limited by BUFFER_BYTES_SIZE <a href="#Batch_PB">parameter</a> of
|
||||
batch creation (affects all blob-oriented methods except
|
||||
accoount alignment) is limited by BUFFER_BYTES_SIZE <a href="#Batch_PB">parameter</a>
|
||||
of batch creation (affects all blob-oriented methods except
|
||||
registerBlob()). </font>
|
||||
</p>
|
||||
<li/>
|
||||
@ -2381,7 +2366,7 @@ with execution of SQL statements.</font></p>
|
||||
<li/>
|
||||
<p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">unsigned
|
||||
getMessageLength(StatusType* status) - returns length of message
|
||||
buffer (use it to allocate memory for the buffer).</font></font></p>
|
||||
buffer (use it to allocate memory for the buffer).</font></p>
|
||||
<li/>
|
||||
<p><font face="Liberation Serif, serif"><font size="4" style="font-size: 14pt"><span style="background: #ffffff">unsigned
|
||||
getAlignment(StatusType* status) – returns alignment required for
|
||||
@ -2780,7 +2765,7 @@ interface – replaces (partially) isc_stmt_handle.</font></p>
|
||||
outMetadata, void* outBuffer) – executes any SQL statement except
|
||||
returning multiple rows of data. Partial analogue of
|
||||
isc_dsql_execute2() - in and out XSLQDAs replaced with input and
|
||||
output messages with appropriate buffers.</font></font></p>
|
||||
output messages with appropriate buffers.</font></p>
|
||||
<li/>
|
||||
<p style="margin-bottom: 0cm"><font face="Liberation Serif, serif"><font size="4" style="font-size: 14pt">IResultSet*
|
||||
openCursor(StatusType* status, ITransaction* transaction,
|
||||
@ -3771,7 +3756,9 @@ interface is main interface of database crypt key holder plugin.</font></p>
|
||||
interface (if provided by user with <a href="#Provider">Provider</a>::setDbCryptCallback()
|
||||
call). This call is always performed at database attach moment, and
|
||||
some holders may reject attachment if satisfactory key was not
|
||||
provided.</font></p>
|
||||
provided. </font><font size="4" style="font-size: 14pt">Return value
|
||||
of 0 means that key holder can not provide a key to crypt plugin,
|
||||
non-zero – can.</font></p>
|
||||
<li/>
|
||||
<p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">ICryptKeyCallback*
|
||||
keyHandle(StatusType* status, const char* keyName) – is intended
|
||||
@ -3787,12 +3774,12 @@ interface is main interface of database crypt key holder plugin.</font></p>
|
||||
<li/>
|
||||
<p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">FB_BOOLEAN
|
||||
useOnlyOwnKeys(StatusType* status) – informs firebird engine
|
||||
whether a key, provided by key holder, can be used in other attachments.
|
||||
Makes sense only for SuperServer – only it can share database crypt keys
|
||||
between attachments. Returning FB_TRUE from this method enforces
|
||||
firebird to make sure that this particular key holder (and therefore
|
||||
in turn attachment related to it) provides correct crypt key for
|
||||
any other attachment to this database.</font></p>
|
||||
whether a key, provided by key holder, can be used in other
|
||||
attachments. Makes sense only for SuperServer – only it can share
|
||||
database crypt keys between attachments. Returning FB_TRUE from this
|
||||
method enforces firebird to make sure that this particular key
|
||||
holder (and therefore in turn attachment related to it) provides
|
||||
correct crypt key for any other attachment to this database.</font></p>
|
||||
<li/>
|
||||
<p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">ICryptKeyCallback*
|
||||
chainHandle(StatusType* status) – support of a chain of key
|
||||
|
@ -116,23 +116,25 @@ DECFLOAT (FB 4.0)
|
||||
Alex Peshkoff <peshkoff@mail.ru>
|
||||
|
||||
Syntax rules:
|
||||
DECFLOAT
|
||||
DECFLOAT(16)
|
||||
DECFLOAT(34)
|
||||
|
||||
Storage:
|
||||
64-bit / 128-bit, format according to IEEE 754.
|
||||
64-bit / 128-bit, format according to IEEE 754 Decimal64/Decimal128
|
||||
|
||||
Example(s):
|
||||
1. DECLARE VARIABLE VAR1 DECFLOAT(34);
|
||||
2. CREATE TABLE TABLE1 (FIELD1 DECFLOAT(16));
|
||||
|
||||
Note(s):
|
||||
1. A number of standard functions can be used with DECFLOAT datatype. It is:
|
||||
1. If no precision has been specified in the type declaration, the precision is 34.
|
||||
2. A number of standard functions can be used with DECFLOAT datatype. It is:
|
||||
ABS, CEILING, EXP, FLOOR, LN, LOG, LOG10, POWER, SIGN, SQRT.
|
||||
Agregate functions SUM, AVG, MAX and MIN also work with DECFLOAT data.
|
||||
All statistics aggregates (like but not limited to STDDEV or CORR) work with DECFLOAT data.
|
||||
|
||||
2. Firebird supports four functions, specially designed to support DECFLOAT data:
|
||||
3. Firebird supports four functions, specially designed to support DECFLOAT data:
|
||||
- COMPARE_DECFLOAT - compares two DECFLOAT values to be equal, different or unordered.
|
||||
Returns SMALLINT value which can be as follows:
|
||||
0 - values are equal
|
||||
@ -155,18 +157,18 @@ DECFLOAT (FB 4.0)
|
||||
DECFLOAT values are ordered as follows:
|
||||
-nan < -snan < -inf < -0.1 < -0.10 < -0 < 0 < 0.10 < 0.1 < inf < snan < nan
|
||||
|
||||
3. Firebird supports new session control operator SET DECFLOAT. It has following forms:
|
||||
4. Firebird supports new session control operator SET DECFLOAT. It has following forms:
|
||||
SET DECFLOAT ROUND <mode> - controls rounding mode used in operations with DECFLOAT
|
||||
values. Valid modes are: CEILING (towards +infinity), UP (away from 0), HALF_UP
|
||||
(to nearest, if equidistant - up), HALF_EVEN (to nearest, if equidistant - ensure
|
||||
last digit in the result to be even), HALF_DOWN (to nearest, if equidistant - down),
|
||||
DOWN (towards 0), FLOOR (towards -infinity), REROUND (up if digit to be rounded is
|
||||
0 or 5, down in other cases).
|
||||
0 or 5, down in other cases). HALF_UP rounding is used by default.
|
||||
|
||||
SET DECFLOAT TRAPS TO <comma-separated traps list - may be empty> - controls which
|
||||
exceptional conditions cause a trap. Valid traps are: Division_by_zero, Inexact,
|
||||
Invalid_operation, Overflow and Underflow. By default traps are set to:
|
||||
Division_by_zero, Invalid_operation, Overflow, Underflow.
|
||||
Division_by_zero, Invalid_operation, Overflow.
|
||||
|
||||
SET DECFLOAT BIND <bind-type> - controls how are DECFLOAT values represented in outer
|
||||
world (i.e. in messages or in XSQLDA). Valid binding types are: NATIVE (use IEEE754
|
||||
@ -177,10 +179,11 @@ DECFLOAT (FB 4.0)
|
||||
native format. One can choose between strings (ideal precision, but poor support
|
||||
for further processing), floating point values (ideal support for further processing
|
||||
but poor precision) or scaled integers (good support for further processing and
|
||||
required precision but range of values is very limited). When using is a tool like
|
||||
generic purporse GUI client choice of CHAR binding is OK in most cases.
|
||||
required precision but range of values is very limited). When using in a tool like
|
||||
generic purporse GUI client choice of CHAR binding is OK in most cases. By default
|
||||
NATIVE binding is used.
|
||||
|
||||
4. The length of DECFLOAT literals are limited to 1024 characters. For longer values, you will
|
||||
5. The length of DECFLOAT literals are limited to 1024 characters. For longer values, you will
|
||||
need to use the scientific notation. For example, the 0.0<1020 zeroes>11 cannot be used
|
||||
as a literal, instead you can use the equivalent in scientific notation: 1.1E-1022.
|
||||
Similarly 10<1022 zeroes>0 can be presented as 1.0E1024.
|
||||
|
@ -2,21 +2,24 @@
|
||||
SQL keywords introduced in different server versions
|
||||
----------------------------------------------------
|
||||
|
||||
An asterisk (*) mark shows that a keyword doesn't exist in the SQL specification
|
||||
and hence should be considered a non-standard language extention.
|
||||
Deviations from the standard:
|
||||
* : keyword does not exist in the SQL:2016 specification and should be
|
||||
considered a non-standard language extention.
|
||||
(1) : reserved word in SQL:2016, non-reserved in Firebird
|
||||
(2) : non-reserved word in SQL:2016, reserved word in Firebird
|
||||
|
||||
Firebird 1.0
|
||||
------------
|
||||
|
||||
Added as reserved words:
|
||||
|
||||
CURRENT_USER
|
||||
CURRENT_ROLE
|
||||
BREAK *
|
||||
DESCRIPTOR
|
||||
FIRST
|
||||
CURRENT_ROLE
|
||||
CURRENT_USER
|
||||
DESCRIPTOR (2)
|
||||
FIRST (2)
|
||||
RECREATE *
|
||||
SKIP *
|
||||
SKIP
|
||||
SUBSTRING
|
||||
|
||||
Firebird 1.5
|
||||
@ -24,42 +27,42 @@ Firebird 1.5
|
||||
|
||||
Added as reserved words:
|
||||
|
||||
CURRENT_CONNECTION *
|
||||
CURRENT_TRANSACTION *
|
||||
BIGINT
|
||||
CASE
|
||||
CURRENT_CONNECTION *
|
||||
CURRENT_TRANSACTION *
|
||||
RELEASE
|
||||
ROW_COUNT
|
||||
SAVEPOINT
|
||||
|
||||
Added as non-reserved words:
|
||||
|
||||
COALESCE
|
||||
COALESCE (1)
|
||||
DELETING *
|
||||
INSERTING *
|
||||
LAST
|
||||
LEAVE
|
||||
LEAVE *
|
||||
LOCK *
|
||||
NULLIF
|
||||
NULLIF (1)
|
||||
NULLS
|
||||
STATEMENT
|
||||
UPDATING *
|
||||
USING
|
||||
USING (1)
|
||||
|
||||
Moved from reserved words to non-reserved:
|
||||
|
||||
BREAK *
|
||||
DESCRIPTOR
|
||||
FIRST
|
||||
SKIP *
|
||||
SUBSTRING
|
||||
SKIP (1)
|
||||
SUBSTRING (1)
|
||||
|
||||
Firebird 2.0
|
||||
------------
|
||||
|
||||
Added as reserved words:
|
||||
|
||||
BIT_LENGTH
|
||||
BIT_LENGTH *
|
||||
BOTH
|
||||
CHAR_LENGTH
|
||||
CHARACTER_LENGTH
|
||||
@ -90,7 +93,7 @@ Firebird 2.0
|
||||
SCALAR_ARRAY *
|
||||
SEQUENCE
|
||||
RESTART
|
||||
RETURNING *
|
||||
RETURNING
|
||||
|
||||
Moved from reserved words to non-reserved:
|
||||
|
||||
@ -129,49 +132,49 @@ Firebird 2.1
|
||||
|
||||
Added as non-reserved words:
|
||||
|
||||
ABS
|
||||
ABS (1)
|
||||
ACCENT *
|
||||
ACOS *
|
||||
ALWAYS *
|
||||
ACOS (1)
|
||||
ALWAYS
|
||||
ASCII_CHAR *
|
||||
ASCII_VAL *
|
||||
ASIN *
|
||||
ATAN *
|
||||
ASIN (1)
|
||||
ATAN (1)
|
||||
ATAN2 *
|
||||
BIN_AND *
|
||||
BIN_OR *
|
||||
BIN_SHL *
|
||||
BIN_SHR *
|
||||
BIN_XOR *
|
||||
CEIL
|
||||
CEILING
|
||||
COS *
|
||||
COSH *
|
||||
CEIL (1)
|
||||
CEILING (1)
|
||||
COS (1)
|
||||
COSH (1)
|
||||
COT *
|
||||
DATEADD *
|
||||
DATEDIFF *
|
||||
DECODE *
|
||||
EXP
|
||||
FLOOR
|
||||
EXP (1)
|
||||
FLOOR (1)
|
||||
GEN_UUID *
|
||||
GENERATED
|
||||
HASH *
|
||||
LIST *
|
||||
LN
|
||||
LOG *
|
||||
LOG10 *
|
||||
LN (1)
|
||||
LOG (1)
|
||||
LOG10 (1)
|
||||
LPAD *
|
||||
MATCHED
|
||||
MATCHING *
|
||||
MAXVALUE *
|
||||
MAXVALUE
|
||||
MILLISECOND *
|
||||
MINVALUE *
|
||||
MOD
|
||||
OVERLAY
|
||||
MINVALUE
|
||||
MOD (1)
|
||||
OVERLAY (1)
|
||||
PAD
|
||||
PI *
|
||||
PLACING
|
||||
POWER
|
||||
POWER (1)
|
||||
PRESERVE
|
||||
RAND *
|
||||
REPLACE *
|
||||
@ -179,12 +182,12 @@ Firebird 2.1
|
||||
ROUND *
|
||||
RPAD *
|
||||
SIGN *
|
||||
SIN *
|
||||
SINH *
|
||||
SIN (1)
|
||||
SINH (1)
|
||||
SPACE
|
||||
SQRT
|
||||
TAN *
|
||||
TANH *
|
||||
SQRT (1)
|
||||
TAN (1)
|
||||
TANH (1)
|
||||
TEMPORARY
|
||||
TRUNC *
|
||||
WEEK *
|
||||
@ -210,11 +213,10 @@ Firebird 2.5
|
||||
MIDDLENAME *
|
||||
MAPPING *
|
||||
OS_NAME *
|
||||
SOURCE *
|
||||
SOURCE
|
||||
TWO_PHASE *
|
||||
UUID_TO_CHAR *
|
||||
|
||||
|
||||
Firebird 3.0
|
||||
------------
|
||||
|
||||
@ -224,10 +226,8 @@ Firebird 3.0
|
||||
CORR
|
||||
COVAR_POP
|
||||
COVAR_SAMP
|
||||
DELETING *
|
||||
DETERMINISTIC
|
||||
FALSE
|
||||
INSERTING *
|
||||
OFFSET
|
||||
OVER
|
||||
RDB$RECORD_VERSION *
|
||||
@ -243,15 +243,22 @@ Firebird 3.0
|
||||
RETURN
|
||||
ROW
|
||||
SCROLL
|
||||
SQLSTATE *
|
||||
SQLSTATE
|
||||
STDDEV_POP
|
||||
STDDEV_SAMP
|
||||
TRUE
|
||||
UNKNOWN
|
||||
UPDATING *
|
||||
VAR_POP
|
||||
VAR_SAMP
|
||||
|
||||
Moved from non-reserved words to reserved:
|
||||
|
||||
DELETING *
|
||||
INSERTING *
|
||||
RDB$GET_CONTEXT *
|
||||
RDB$SET_CONTEXT *
|
||||
UPDATING *
|
||||
|
||||
Added as non-reserved words:
|
||||
|
||||
ABSOLUTE
|
||||
@ -262,53 +269,72 @@ Firebird 3.0
|
||||
CONTINUE
|
||||
DDL *
|
||||
DECRYPT *
|
||||
DENSE_RANK
|
||||
DENSE_RANK (1)
|
||||
ENCRYPT *
|
||||
ENGINE *
|
||||
FIRST_VALUE
|
||||
IDENTITY
|
||||
FIRST_VALUE (1)
|
||||
IDENTITY (1)
|
||||
INCREMENT
|
||||
LAST_VALUE
|
||||
LAG
|
||||
LEAD
|
||||
LAST_VALUE (1)
|
||||
LAG (1)
|
||||
LEAD (1)
|
||||
LINGER *
|
||||
NAME
|
||||
NTH_VALUE
|
||||
NTH_VALUE (1)
|
||||
PACKAGE *
|
||||
PARTITION
|
||||
PARTITION (1)
|
||||
PLUGIN *
|
||||
PRIOR
|
||||
RANK
|
||||
RANK (1)
|
||||
RELATIVE
|
||||
ROW_NUMBER
|
||||
ROW_NUMBER (1)
|
||||
SERVERWIDE *
|
||||
TAGS *
|
||||
TRUSTED *
|
||||
USAGE
|
||||
|
||||
|
||||
Firebird 4.0
|
||||
------------
|
||||
|
||||
Added as reserved words:
|
||||
|
||||
UNBOUNDED
|
||||
WINDOW
|
||||
BINARY
|
||||
DECFLOAT
|
||||
RDB$ERROR *
|
||||
RDB$ROLE_IN_USE *
|
||||
RDB$SYSTEM_PRIVILEGE *
|
||||
UNBOUNDED (2)
|
||||
VARBINARY
|
||||
WINDOW
|
||||
|
||||
Added as non-reserved words:
|
||||
|
||||
CUME_DIST *
|
||||
BIND *
|
||||
COMPARE_DECFLOAT *
|
||||
CUME_DIST (1)
|
||||
DEFINER
|
||||
EXCLUDE
|
||||
FIRST_DAY *
|
||||
FOLLOWING
|
||||
NTILE *
|
||||
IDLE *
|
||||
INVOKER
|
||||
LAST_DAY *
|
||||
MESSAGE *
|
||||
NATIVE *
|
||||
NORMALIZE_DECFLOAT *
|
||||
NTILE (1)
|
||||
OTHERS
|
||||
PERCENT_RANK *
|
||||
OVERRIDING
|
||||
PERCENT_RANK (1)
|
||||
PRECEDING
|
||||
PRIVILEGE *
|
||||
RANGE *
|
||||
RDB$ROLE_IN_USE *
|
||||
RDB$SYSTEM_PRIVILEGE *
|
||||
SYSTEM *
|
||||
QUANTIZE *
|
||||
RANGE (1)
|
||||
RESET *
|
||||
SECURITY
|
||||
SESSION
|
||||
SQL (1)
|
||||
SYSTEM (1)
|
||||
TIES
|
||||
TOTALORDER *
|
||||
TRAPS *
|
||||
|
@ -56,6 +56,8 @@ public:
|
||||
pluginManager = NULL;
|
||||
}
|
||||
|
||||
void threadDetach() {};
|
||||
|
||||
private:
|
||||
IPluginManager* pluginManager;
|
||||
};
|
||||
|
@ -58,6 +58,8 @@ public:
|
||||
pluginManager = NULL;
|
||||
}
|
||||
|
||||
void threadDetach() {};
|
||||
|
||||
private:
|
||||
IPluginManager* pluginManager;
|
||||
};
|
||||
|
@ -47,6 +47,7 @@ Type
|
||||
|
||||
// TPluginModule implementation
|
||||
procedure doClean; override;
|
||||
procedure threadDetach; override;
|
||||
end;
|
||||
|
||||
TMyCrypt = class(IDbCryptPluginImpl)
|
||||
@ -71,6 +72,7 @@ Type
|
||||
procedure setKey(status: IStatus; length: Cardinal; sources: IKeyHolderPluginPtr; keyName: PAnsiChar); override;
|
||||
procedure encrypt(status: IStatus; length: Cardinal; src, dst: Pointer); override;
|
||||
procedure decrypt(status: IStatus; length: Cardinal; src, dst: Pointer); override;
|
||||
procedure setInfo(status: IStatus; info: IDbCryptInfo); override;
|
||||
|
||||
private
|
||||
procedure pxor(length: Cardinal; mem: Pointer);
|
||||
@ -114,6 +116,10 @@ begin
|
||||
FRegistered := False;
|
||||
end;
|
||||
|
||||
procedure TMyPluginModule.threadDetach;
|
||||
begin
|
||||
end;
|
||||
|
||||
procedure TMyPluginModule.registerMe;
|
||||
begin
|
||||
if not FRegistered then
|
||||
@ -179,6 +185,13 @@ begin
|
||||
Result := FOwner;
|
||||
end;
|
||||
|
||||
procedure TMyCrypt.setInfo(status: IStatus; info: IDbCryptInfo);
|
||||
begin
|
||||
status.init;
|
||||
|
||||
// do nothing in this trivial sample
|
||||
end;
|
||||
|
||||
procedure TMyCrypt.decrypt(status: IStatus; length: Cardinal; src, dst: Pointer);
|
||||
begin
|
||||
status.init;
|
||||
|
@ -153,6 +153,91 @@ FB_UDR_BEGIN_FUNCTION(sum_args)
|
||||
FB_UDR_END_FUNCTION
|
||||
|
||||
|
||||
/***
|
||||
create function mult (
|
||||
a decfloat(34) not null,
|
||||
b decimal(34,6) not null
|
||||
) returns decfloat(34) not null
|
||||
external name 'udrcpp_example!mult'
|
||||
engine udr;
|
||||
***/
|
||||
FB_UDR_BEGIN_FUNCTION(mult)
|
||||
// Without InMessage/OutMessage definitions, messages will be byte-based.
|
||||
|
||||
FB_UDR_CONSTRUCTOR
|
||||
{
|
||||
AutoRelease<IMessageMetadata> inMetadata(metadata->getInputMetadata(status));
|
||||
aOffset = inMetadata->getOffset(status, 0);
|
||||
bOffset = inMetadata->getOffset(status, 1);
|
||||
|
||||
AutoRelease<IMessageMetadata> outMetadata(metadata->getOutputMetadata(status));
|
||||
outOffset = outMetadata->getOffset(status, 0);
|
||||
outNullOffset = outMetadata->getNullOffset(status, 0);
|
||||
|
||||
df34 = master->getUtilInterface()->getDecFloat34(status);
|
||||
}
|
||||
|
||||
// This function requires the INTEGER parameters and return value, otherwise it will crash.
|
||||
// Metadata is inspected dynamically (in execute). This is not the fastest method.
|
||||
FB_UDR_EXECUTE_FUNCTION
|
||||
{
|
||||
struct ExampleBCD
|
||||
{
|
||||
unsigned char bcd[IDecFloat34::BCD_SIZE];
|
||||
int sign, exp;
|
||||
|
||||
void load(void* from, IDecFloat34* df34)
|
||||
{
|
||||
df34->toBcd((FB_DEC34*) from, &sign, bcd, &exp);
|
||||
}
|
||||
|
||||
void store(void* to, IDecFloat34* df34) const
|
||||
{
|
||||
df34->fromBcd(sign, bcd, exp, (FB_DEC34*) to);
|
||||
}
|
||||
};
|
||||
|
||||
ExampleBCD a, b, rc;
|
||||
a.load(in + aOffset, df34);
|
||||
b.load(in + bOffset, df34);
|
||||
|
||||
// multiply (trivial example - a lot of features are missing)
|
||||
rc.sign = a.sign ^ b.sign;
|
||||
rc.exp = a.exp + b.exp;
|
||||
|
||||
unsigned char buf[2 * IDecFloat34::BCD_SIZE + 1];
|
||||
memset(buf, 0, sizeof(buf));
|
||||
|
||||
for (unsigned i = IDecFloat34::BCD_SIZE; i--;)
|
||||
{
|
||||
for (unsigned j = IDecFloat34::BCD_SIZE; j--;)
|
||||
{
|
||||
unsigned char v = a.bcd[i] * b.bcd[j] + buf[i + j + 1];
|
||||
buf[i + j + 1] = v % 10;
|
||||
buf[i + j] += v / 10;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned offset = 0;
|
||||
|
||||
for (; offset < IDecFloat34::BCD_SIZE; ++offset)
|
||||
{
|
||||
if (buf[offset])
|
||||
break;
|
||||
}
|
||||
|
||||
memcpy(rc.bcd, buf + offset, sizeof rc.bcd);
|
||||
rc.exp += (IDecFloat34::BCD_SIZE - offset);
|
||||
|
||||
rc.store(out + outOffset, df34);
|
||||
*(ISC_SHORT*) (out + outNullOffset) = FB_FALSE;
|
||||
}
|
||||
|
||||
unsigned aOffset, bOffset, outOffset, outNullOffset;
|
||||
IDecFloat34* df34;
|
||||
FB_UDR_END_FUNCTION
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
2
extern/cloop/src/cloop/Generator.cpp
vendored
2
extern/cloop/src/cloop/Generator.cpp
vendored
@ -882,6 +882,8 @@ void PascalGenerator::generate()
|
||||
{
|
||||
fprintf(out, "{ %s }\n\n", AUTOGEN_MSG);
|
||||
|
||||
fprintf(out, "{$IFDEF FPC}\n{$MODE DELPHI}\n{$OBJECTCHECKS OFF}\n{$ENDIF}\n\n");
|
||||
|
||||
fprintf(out, "unit %s;\n\n", unitName.c_str());
|
||||
fprintf(out, "interface\n\n");
|
||||
fprintf(out, "uses Classes");
|
||||
|
@ -1,5 +1,10 @@
|
||||
{ This file was autogenerated by cloop - Cross Language Object Oriented Programming }
|
||||
|
||||
{$IFDEF FPC}
|
||||
{$MODE DELPHI}
|
||||
{$OBJECTCHECKS OFF}
|
||||
{$ENDIF}
|
||||
|
||||
unit CalcPascalApi;
|
||||
|
||||
interface
|
||||
|
6
extern/decNumber/Makefile
vendored
6
extern/decNumber/Makefile
vendored
@ -1,11 +1,11 @@
|
||||
LIBRARY=libdecFloat.a
|
||||
LIBRARY=libdecFloat$(CROSS).a
|
||||
|
||||
$(LIBRARY): $(wildcard *.c) $(wildcard *.h) Makefile
|
||||
$(RM) -f *.o
|
||||
$(CC) -c -O3 -fPIC $(subst decCommon.c,,$(subst decBasic.c,,$(wildcard *.c)))
|
||||
$(CC) $(CROSS_FLAGS) -c -O3 -fPIC $(subst decCommon.c,,$(subst decBasic.c,,$(wildcard *.c)))
|
||||
$(AR) crs $(LIBRARY) *.o
|
||||
$(RM) -f *.o
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
$(RM) -f *.o $(LIBRARY)
|
||||
$(RM) -f *.o *.a
|
||||
|
1
extern/libtommath/.gitignore
vendored
1
extern/libtommath/.gitignore
vendored
@ -1,5 +1,6 @@
|
||||
lib/
|
||||
temp/
|
||||
*.o
|
||||
*.d
|
||||
*.l*
|
||||
.libs/
|
||||
|
@ -1820,6 +1820,8 @@ C --
|
||||
PARAMETER (GDS__vld_plugins = 335545203)
|
||||
INTEGER*4 GDS__db_crypt_key
|
||||
PARAMETER (GDS__db_crypt_key = 335545204)
|
||||
INTEGER*4 GDS__no_keyholder_plugin
|
||||
PARAMETER (GDS__no_keyholder_plugin = 335545205)
|
||||
INTEGER*4 GDS__gfix_db_name
|
||||
PARAMETER (GDS__gfix_db_name = 335740929)
|
||||
INTEGER*4 GDS__gfix_invalid_sw
|
||||
|
@ -1815,6 +1815,8 @@ const
|
||||
gds_vld_plugins = 335545203;
|
||||
isc_db_crypt_key = 335545204;
|
||||
gds_db_crypt_key = 335545204;
|
||||
isc_no_keyholder_plugin = 335545205;
|
||||
gds_no_keyholder_plugin = 335545205;
|
||||
isc_gfix_db_name = 335740929;
|
||||
gds_gfix_db_name = 335740929;
|
||||
isc_gfix_invalid_sw = 335740930;
|
||||
|
@ -29,7 +29,6 @@ set(epp_boot_internal_files
|
||||
burp/backup.epp
|
||||
burp/restore.epp
|
||||
burp/OdsDetection.epp
|
||||
utilities/gstat/dba.epp
|
||||
)
|
||||
set(epp_boot_ocxx_files
|
||||
isql/extract.epp
|
||||
@ -42,6 +41,7 @@ set(epp_boot_files
|
||||
utilities/stats.epp
|
||||
yvalve/array.epp
|
||||
yvalve/blob.epp
|
||||
utilities/gstat/dba.epp
|
||||
)
|
||||
set(epp_boot_gds_files
|
||||
dsql/metd.epp
|
||||
@ -69,12 +69,12 @@ set(epp_master_files
|
||||
|
||||
if (NOT CMAKE_CROSSCOMPILING)
|
||||
|
||||
epp_process(boot epp_boot_internal_files ${GPRE_BOOT_CMD} -lang_internal -n -m)
|
||||
epp_process(boot epp_boot_internal_files ${GPRE_BOOT_CMD} -lang_internal -n -ids -ocxx -m)
|
||||
epp_process(boot epp_boot_ocxx_files ${GPRE_BOOT_CMD} -lang_internal -n -ids -ocxx)
|
||||
epp_process(boot epp_boot_files ${GPRE_BOOT_CMD} -n -m)
|
||||
epp_process(boot epp_boot_gds_files ${GPRE_BOOT_CMD} -n -ids -gds_cxx)
|
||||
|
||||
epp_process(master epp_boot_internal_files ${BOOT_GPRE_CMD} -n -m)
|
||||
epp_process(master epp_boot_internal_files ${BOOT_GPRE_CMD} -n -m -ids -ocxx -m)
|
||||
epp_process(master epp_boot_ocxx_files ${BOOT_GPRE_CMD} -n -ids -ocxx)
|
||||
epp_process(master epp_boot_files ${BOOT_GPRE_CMD} -n -m)
|
||||
epp_process(master epp_boot_gds_files ${BOOT_GPRE_CMD} -n -ids -gds_cxx)
|
||||
|
@ -199,7 +199,7 @@ private:
|
||||
}
|
||||
else
|
||||
{
|
||||
sql.printf("GRANT %s TO \"%s\"", ADMIN_ROLE, userName.c_str());
|
||||
sql.printf("GRANT DEFAULT %s TO \"%s\"", ADMIN_ROLE, userName.c_str());
|
||||
}
|
||||
|
||||
att->execute(&statusWrapper, tra, sql.length(), sql.c_str(),
|
||||
|
@ -64,8 +64,11 @@ namespace
|
||||
DATABASE DB = STATIC FILENAME "yachts.lnk";
|
||||
|
||||
#define DB tdgbl->db_handle
|
||||
#define fbTrans tdgbl->tr_handle
|
||||
#define gds_trans tdgbl->tr_handle
|
||||
#define isc_status tdgbl->status_vector
|
||||
#define fbStatus (&tdgbl->status_vector)
|
||||
#define isc_status (&tdgbl->status_vector)
|
||||
#define gds_status (&tdgbl->status_vector)
|
||||
|
||||
|
||||
void detectRuntimeODS()
|
||||
@ -91,7 +94,7 @@ void detectRuntimeODS()
|
||||
// and rdb$field_name = 'RDB$SYSTEM_FLAG';
|
||||
|
||||
int count = 0;
|
||||
isc_req_handle req_handle = 0;
|
||||
Firebird::IRequest* req_handle = nullptr;
|
||||
FOR (REQUEST_HANDLE req_handle)
|
||||
RFR IN RDB$RELATION_FIELDS
|
||||
WITH (RFR.RDB$RELATION_NAME = 'RDB$RELATIONS' OR RFR.RDB$RELATION_NAME = 'RDB$RELATION_FIELDS')
|
||||
@ -106,7 +109,7 @@ void detectRuntimeODS()
|
||||
if (count != 2)
|
||||
return;
|
||||
|
||||
isc_req_handle req_handle2 = 0;
|
||||
Firebird::IRequest* req_handle2 = nullptr;
|
||||
for (const rel_field_t* rel = relations; rel->relation; ++rel)
|
||||
{
|
||||
FOR (REQUEST_HANDLE req_handle2)
|
||||
@ -125,7 +128,7 @@ void detectRuntimeODS()
|
||||
if (tdgbl->runtimeODS < DB_VERSION_DDL8)
|
||||
return;
|
||||
|
||||
isc_req_handle req_handle3 = 0;
|
||||
Firebird::IRequest* req_handle3 = nullptr;
|
||||
for (const rel_field_t* rf = rel_fields; rf->relation; ++rf)
|
||||
{
|
||||
FOR (REQUEST_HANDLE req_handle3)
|
||||
|
@ -57,11 +57,12 @@
|
||||
#include "../common/prett_proto.h"
|
||||
#endif
|
||||
|
||||
#include "../common/classes/UserBlob.h"
|
||||
#include "../common/classes/BlobWrapper.h"
|
||||
#include "../common/classes/MsgPrint.h"
|
||||
#include "../burp/OdsDetection.h"
|
||||
|
||||
using MsgFormat::SafeArg;
|
||||
using Firebird::FbLocalStatus;
|
||||
|
||||
|
||||
// For service APIs the follow DB handle is a value stored
|
||||
@ -72,8 +73,11 @@ using MsgFormat::SafeArg;
|
||||
DATABASE DB = STATIC FILENAME "yachts.lnk" RUNTIME * dbb_file;
|
||||
|
||||
#define DB tdgbl->db_handle
|
||||
#define fbTrans tdgbl->tr_handle
|
||||
#define gds_trans tdgbl->tr_handle
|
||||
#define isc_status tdgbl->status_vector
|
||||
#define fbStatus (&tdgbl->status_vector)
|
||||
#define isc_status (&tdgbl->status_vector)
|
||||
#define gds_status (&tdgbl->status_vector)
|
||||
|
||||
namespace // unnamed, private
|
||||
{
|
||||
@ -84,18 +88,12 @@ namespace // unnamed, private
|
||||
|
||||
inline void put(BurpGlobals* tdgbl, const UCHAR c)
|
||||
{
|
||||
if (--(tdgbl->io_cnt) >= 0)
|
||||
*(tdgbl->io_ptr)++ = c;
|
||||
else
|
||||
MVOL_write(c, &tdgbl->io_cnt, &tdgbl->io_ptr);
|
||||
tdgbl->put(c);
|
||||
}
|
||||
|
||||
inline void put(BurpGlobals* tdgbl, const att_type c)
|
||||
{
|
||||
if (--tdgbl->io_cnt >= 0)
|
||||
*(tdgbl->io_ptr)++ = UCHAR(c);
|
||||
else
|
||||
MVOL_write(UCHAR(c), &tdgbl->io_cnt, &tdgbl->io_ptr);
|
||||
put(tdgbl, UCHAR(c));
|
||||
}
|
||||
|
||||
inline const UCHAR* put_block(BurpGlobals* tdgbl, const UCHAR* p, ULONG n)
|
||||
@ -173,7 +171,7 @@ const UCHAR source_items[] =
|
||||
isc_info_blob_total_length,
|
||||
isc_info_blob_num_segments
|
||||
};
|
||||
const SCHAR db_info_items[] =
|
||||
const UCHAR db_info_items[] =
|
||||
{
|
||||
isc_info_db_sql_dialect,
|
||||
isc_info_page_size,
|
||||
@ -184,12 +182,12 @@ const SCHAR db_info_items[] =
|
||||
isc_info_db_read_only,
|
||||
isc_info_end
|
||||
};
|
||||
const SCHAR limbo_tpb[] =
|
||||
const UCHAR limbo_tpb[] =
|
||||
{
|
||||
isc_tpb_version1,
|
||||
isc_tpb_ignore_limbo
|
||||
};
|
||||
const SCHAR limbo_nau_tpb[] =
|
||||
const UCHAR limbo_nau_tpb[] =
|
||||
{
|
||||
isc_tpb_version1,
|
||||
isc_tpb_ignore_limbo,
|
||||
@ -211,17 +209,12 @@ int BACKUP_backup(const TEXT* dbb_file, const TEXT* file_name)
|
||||
* Backup a database.
|
||||
*
|
||||
**************************************/
|
||||
ISC_STATUS_ARRAY status_vector;
|
||||
FbLocalStatus status_vector;
|
||||
|
||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||
|
||||
tdgbl->gbl_database_file_name = dbb_file;
|
||||
|
||||
tdgbl->io_ptr = NULL;
|
||||
tdgbl->io_cnt = 0;
|
||||
tdgbl->relations = NULL;
|
||||
tdgbl->runtimeODS = 0;
|
||||
|
||||
gds_trans = 0;
|
||||
|
||||
BURP_verbose(130);
|
||||
@ -229,23 +222,23 @@ int BACKUP_backup(const TEXT* dbb_file, const TEXT* file_name)
|
||||
|
||||
if (tdgbl->gbl_sw_ignore_limbo)
|
||||
{
|
||||
if (isc_start_transaction(status_vector, &gds_trans, 1, &DB,
|
||||
sizeof(limbo_nau_tpb), limbo_nau_tpb))
|
||||
gds_trans = DB->startTransaction(&status_vector, sizeof(limbo_nau_tpb), limbo_nau_tpb);
|
||||
if (status_vector->getState() & Firebird::IStatus::STATE_ERRORS)
|
||||
{
|
||||
isc_start_transaction(status_vector, &gds_trans, 1, &DB, sizeof(limbo_tpb), limbo_tpb);
|
||||
gds_trans = DB->startTransaction(&status_vector, sizeof(limbo_tpb), limbo_tpb);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
EXEC SQL SET TRANSACTION NO_AUTO_UNDO;
|
||||
if (isc_status[1])
|
||||
if (isc_status->getState() & Firebird::IStatus::STATE_ERRORS)
|
||||
EXEC SQL SET TRANSACTION;
|
||||
}
|
||||
|
||||
if (!gds_trans)
|
||||
{
|
||||
EXEC SQL SET TRANSACTION NAME gds_trans NO_AUTO_UNDO;
|
||||
if (isc_status[1])
|
||||
if (isc_status->getState() & Firebird::IStatus::STATE_ERRORS)
|
||||
EXEC SQL SET TRANSACTION NAME gds_trans;
|
||||
}
|
||||
|
||||
@ -276,7 +269,7 @@ int BACKUP_backup(const TEXT* dbb_file, const TEXT* file_name)
|
||||
tdgbl->action->act_file = tdgbl->gbl_sw_files;
|
||||
}
|
||||
|
||||
MVOL_init_write(file_name, &tdgbl->io_cnt, &tdgbl->io_ptr);
|
||||
MVOL_init_write(file_name);
|
||||
|
||||
// Write database record
|
||||
|
||||
@ -412,7 +405,7 @@ int BACKUP_backup(const TEXT* dbb_file, const TEXT* file_name)
|
||||
// Finish up
|
||||
|
||||
put(tdgbl, (UCHAR) rec_end);
|
||||
FB_UINT64 cumul_count = MVOL_fini_write(&tdgbl->io_cnt, &tdgbl->io_ptr);
|
||||
FB_UINT64 cumul_count = MVOL_fini_write();
|
||||
tdgbl->action->act_action = ACT_backup_fini;
|
||||
BURP_verbose(176, SafeArg() << cumul_count);
|
||||
// msg 176 closing file, committing, and finishing. %ld bytes written
|
||||
@ -465,7 +458,7 @@ void compress(const UCHAR* data, ULONG length)
|
||||
{
|
||||
for (q = p + 2; q < end && (q[-2] != q[-1] || q[-1] != q[0]); q++)
|
||||
;
|
||||
USHORT run = (q < end) ? q - p - 2 : end - p;
|
||||
ULONG run = (q < end) ? q - p - 2 : end - p;
|
||||
if (run)
|
||||
{
|
||||
for (; run > 127; run -= 127)
|
||||
@ -827,125 +820,34 @@ SINT64 get_gen_id( const TEXT* name, SSHORT name_len)
|
||||
* Read id for a generator;
|
||||
*
|
||||
**************************************/
|
||||
UCHAR blr_buffer[100]; // enough to fit blr
|
||||
|
||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||
|
||||
FB_API_HANDLE gen_id_reqh = 0;
|
||||
UCHAR* blr = blr_buffer;
|
||||
|
||||
// If this is ODS 10 (IB version 6.0) or greater, build BLR to retrieve
|
||||
// the 64-bit value of the generator. If not, build BLR to retrieve the
|
||||
// 32-bit value, which we will cast to the expected INT64 format.
|
||||
|
||||
if (tdgbl->runtimeODS >= DB_VERSION_DDL10)
|
||||
try
|
||||
{
|
||||
// build the blr with the right relation name and 64-bit results.
|
||||
add_byte(blr, blr_version5);
|
||||
add_byte(blr, blr_begin);
|
||||
add_byte(blr, blr_message);
|
||||
add_byte(blr, 0);
|
||||
add_word(blr, 1);
|
||||
add_byte(blr, blr_int64);
|
||||
add_byte(blr, 0);
|
||||
add_byte(blr, blr_send);
|
||||
add_byte(blr, 0);
|
||||
add_byte(blr, blr_assignment);
|
||||
add_byte(blr, blr_gen_id);
|
||||
add_byte(blr, name_len);
|
||||
while (name_len--)
|
||||
{
|
||||
const UCHAR c = *name++;
|
||||
add_byte(blr, c);
|
||||
}
|
||||
add_byte(blr, blr_literal);
|
||||
add_byte(blr, blr_long);
|
||||
add_byte(blr, 0);
|
||||
add_word(blr, 0);
|
||||
add_word(blr, 0);
|
||||
add_byte(blr, blr_parameter);
|
||||
add_byte(blr, 0);
|
||||
add_word(blr, 0);
|
||||
add_byte(blr, blr_end);
|
||||
add_byte(blr, blr_eoc);
|
||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||
|
||||
Firebird::string nm, sql;
|
||||
nm.assign(name, name_len);
|
||||
BURP_makeSymbol(tdgbl, nm);
|
||||
sql = "select first(1) gen_id(" + nm + ", 0) from rdb$database";
|
||||
|
||||
BurpSql getGenerator(tdgbl, sql.c_str());
|
||||
FB_MESSAGE(GetGen, Firebird::ThrowStatusWrapper, (FB_BIGINT, id));
|
||||
GetGen getGen(&tdgbl->throwStatus, Firebird::MasterInterfacePtr());
|
||||
|
||||
getGenerator.singleSelect(tdgbl->tr_handle, &getGen);
|
||||
return getGen->id;
|
||||
}
|
||||
else
|
||||
catch (const Firebird::FbException& ex)
|
||||
{
|
||||
// build the blr with the right relation name and 32-bit results
|
||||
add_byte(blr, blr_version4);
|
||||
add_byte(blr, blr_begin);
|
||||
add_byte(blr, blr_message);
|
||||
add_byte(blr, 0);
|
||||
add_word(blr, 1);
|
||||
add_byte(blr, blr_long);
|
||||
add_byte(blr, 0);
|
||||
add_byte(blr, blr_send);
|
||||
add_byte(blr, 0);
|
||||
add_byte(blr, blr_assignment);
|
||||
add_byte(blr, blr_gen_id);
|
||||
add_byte(blr, name_len);
|
||||
while (name_len--)
|
||||
{
|
||||
const UCHAR c = *name++;
|
||||
add_byte(blr, c);
|
||||
}
|
||||
add_byte(blr, blr_literal);
|
||||
add_byte(blr, blr_long);
|
||||
add_byte(blr, 0);
|
||||
add_word(blr, 0);
|
||||
add_word(blr, 0);
|
||||
add_byte(blr, blr_parameter);
|
||||
add_byte(blr, 0);
|
||||
add_word(blr, 0);
|
||||
add_byte(blr, blr_end);
|
||||
add_byte(blr, blr_eoc);
|
||||
}
|
||||
Firebird::IStatus* st = ex.getStatus();
|
||||
|
||||
const SSHORT blr_length = blr - blr_buffer;
|
||||
|
||||
#ifdef DEBUG
|
||||
if (debug_on)
|
||||
fb_print_blr(blr_buffer, blr_length, NULL, NULL, 0);
|
||||
#endif
|
||||
|
||||
ISC_STATUS_ARRAY status_vector;
|
||||
if (isc_compile_request(status_vector, &DB, &gen_id_reqh, blr_length, (const char*) blr_buffer))
|
||||
{
|
||||
// if there's no gen_id, never mind ...
|
||||
return 0;
|
||||
}
|
||||
if (st->getErrors()[1] == isc_dsql_error)
|
||||
return 0;
|
||||
|
||||
// use the same gds_trans generated by gpre
|
||||
if (isc_start_request(status_vector, &gen_id_reqh, &gds_trans, 0))
|
||||
{
|
||||
BURP_error_redirect(status_vector, 25);
|
||||
BURP_error_redirect(st, 25);
|
||||
// msg 25 Failed in put_blr_gen_id
|
||||
}
|
||||
|
||||
|
||||
SINT64 read_msg1;
|
||||
if (tdgbl->runtimeODS >= DB_VERSION_DDL10)
|
||||
{
|
||||
if (isc_receive(status_vector, &gen_id_reqh, 0, sizeof(read_msg1), &read_msg1, 0))
|
||||
{
|
||||
BURP_error_redirect(status_vector, 25);
|
||||
// msg 25 Failed in put_blr_gen_id
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SLONG read_msg0;
|
||||
if (isc_receive(status_vector, &gen_id_reqh, 0, sizeof(read_msg0), &read_msg0, 0))
|
||||
{
|
||||
BURP_error_redirect(status_vector, 25);
|
||||
// msg 25 Failed in put_blr_gen_id
|
||||
}
|
||||
read_msg1 = (SINT64) read_msg0;
|
||||
}
|
||||
|
||||
isc_release_request(status_vector, &gen_id_reqh);
|
||||
|
||||
return read_msg1;
|
||||
return 0; // warning silencer
|
||||
}
|
||||
|
||||
|
||||
@ -1107,16 +1009,16 @@ void put_array( burp_fld* field, burp_rel* relation, ISC_QUAD* blob_id)
|
||||
xdr_buffer.lstr_allocated = xdr_buffer.lstr_length;
|
||||
}
|
||||
|
||||
ISC_STATUS_ARRAY status_vector;
|
||||
ULONG return_length = 0;
|
||||
if (isc_get_slice(status_vector, &DB, &gds_trans, blob_id, blr_length, (const char*) blr_buffer,
|
||||
0, // param length for subset of an array handling
|
||||
NULL, // param for subset of an array handling
|
||||
slice_length, slice, (SLONG*) &return_length))
|
||||
FbLocalStatus status_vector;
|
||||
unsigned return_length = DB->getSlice(&status_vector, gds_trans, blob_id, blr_length, blr_buffer,
|
||||
0, nullptr, // parameters for subset of an array handling
|
||||
slice_length, slice);
|
||||
|
||||
if (!status_vector.isSuccess())
|
||||
{
|
||||
BURP_print(false, 81, field->fld_name);
|
||||
// msg 81 error accessing blob field %s -- continuing
|
||||
BURP_print_status(false, status_vector);
|
||||
BURP_print_status(false, &status_vector);
|
||||
#ifdef DEBUG
|
||||
PRETTY_print_sdl(blr_buffer, NULL, NULL, 0);
|
||||
#endif
|
||||
@ -1179,7 +1081,7 @@ void put_array( burp_fld* field, burp_rel* relation, ISC_QUAD* blob_id)
|
||||
lstring xdr_slice;
|
||||
xdr_slice.lstr_allocated = xdr_slice.lstr_length = return_length;
|
||||
xdr_slice.lstr_address = slice;
|
||||
return_length = CAN_slice(&xdr_buffer, &xdr_slice, TRUE, /*blr_length,*/ blr_buffer);
|
||||
return_length = CAN_slice(&xdr_buffer, &xdr_slice, true, blr_buffer);
|
||||
put(tdgbl, att_xdr_array);
|
||||
put(tdgbl, (UCHAR) (return_length));
|
||||
put(tdgbl, (UCHAR) (return_length >> 8));
|
||||
@ -1244,31 +1146,31 @@ void put_blob( burp_fld* field, ISC_QUAD& blob_id)
|
||||
* This is for user data blobs.
|
||||
*
|
||||
**************************************/
|
||||
ISC_STATUS_ARRAY status_vector;
|
||||
FbLocalStatus status_vector;
|
||||
|
||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||
|
||||
// If the blob is null, don't store it. It will be restored as null.
|
||||
|
||||
if (UserBlob::blobIsNull(blob_id))
|
||||
if (BlobWrapper::blobIsNull(blob_id))
|
||||
return;
|
||||
|
||||
// Open the blob and get it's vital statistics
|
||||
|
||||
UserBlob blob(status_vector);
|
||||
BlobWrapper blob(&status_vector);
|
||||
|
||||
if (!blob.open(DB, gds_trans, blob_id))
|
||||
{
|
||||
BURP_print(false, 81, field->fld_name);
|
||||
// msg 81 error accessing blob field %s -- continuing
|
||||
BURP_print_status(false, status_vector);
|
||||
BURP_print_status(false, &status_vector);
|
||||
return;
|
||||
}
|
||||
|
||||
UCHAR blob_info[32];
|
||||
if (!blob.getInfo(sizeof(blob_items), blob_items, sizeof(blob_info), blob_info))
|
||||
{
|
||||
BURP_error_redirect(status_vector, 20);
|
||||
BURP_error_redirect(&status_vector, 20);
|
||||
// msg 20 isc_blob_info failed
|
||||
}
|
||||
|
||||
@ -1342,13 +1244,9 @@ void put_blob( burp_fld* field, ISC_QUAD& blob_id)
|
||||
while (segments > 0)
|
||||
{
|
||||
FB_SIZE_T segment_length;
|
||||
blob.getSegment(max_segment, buffer, segment_length);
|
||||
|
||||
const ISC_STATUS status = blob.getCode();
|
||||
// Handle the errors. For stream blob isc_segment is not error here.
|
||||
if (status && (status != isc_segment || blob_type == 0))
|
||||
if (!blob.getSegment(max_segment, buffer, segment_length))
|
||||
{
|
||||
BURP_error_redirect(status_vector, 22);
|
||||
BURP_error_redirect(&status_vector, 22);
|
||||
// msg 22 isc_get_segment failed
|
||||
}
|
||||
|
||||
@ -1362,7 +1260,7 @@ void put_blob( burp_fld* field, ISC_QUAD& blob_id)
|
||||
}
|
||||
|
||||
if (!blob.close())
|
||||
BURP_error_redirect(status_vector, 23);
|
||||
BURP_error_redirect(&status_vector, 23);
|
||||
// msg 23 isc_close_blob failed
|
||||
|
||||
if (buffer != static_buffer)
|
||||
@ -1383,28 +1281,28 @@ bool put_blr_blob( att_type attribute, ISC_QUAD& blob_id)
|
||||
* Return true if the blob was present, false otherwise.
|
||||
*
|
||||
**************************************/
|
||||
ISC_STATUS_ARRAY status_vector;
|
||||
FbLocalStatus status_vector;
|
||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||
|
||||
// If the blob is null, don't store it. It will be restored as null.
|
||||
|
||||
if (UserBlob::blobIsNull(blob_id))
|
||||
if (BlobWrapper::blobIsNull(blob_id))
|
||||
return false;
|
||||
|
||||
// Open the blob and get it's vital statistics
|
||||
|
||||
UserBlob blob(status_vector);
|
||||
BlobWrapper blob(&status_vector);
|
||||
|
||||
if (!blob.open(DB, gds_trans, blob_id))
|
||||
{
|
||||
BURP_error_redirect(status_vector, 24);
|
||||
BURP_error_redirect(&status_vector, 24);
|
||||
// msg 24 isc_open_blob failed
|
||||
}
|
||||
|
||||
UCHAR blob_info[32];
|
||||
if (!blob.getInfo(sizeof(blr_items), blr_items, sizeof(blob_info), blob_info))
|
||||
{
|
||||
BURP_error_redirect(status_vector, 20);
|
||||
BURP_error_redirect(&status_vector, 20);
|
||||
// msg 20 isc_blob_info failed
|
||||
}
|
||||
|
||||
@ -1433,7 +1331,7 @@ bool put_blr_blob( att_type attribute, ISC_QUAD& blob_id)
|
||||
BURP_print(true, 79, SafeArg() << int(item));
|
||||
// msg 79 don't understand blob info item %ld
|
||||
if (!blob.close())
|
||||
BURP_error_redirect(status_vector, 23);
|
||||
BURP_error_redirect(&status_vector, 23);
|
||||
// msg 23 isc_close_blob failed
|
||||
return false;
|
||||
}
|
||||
@ -1442,7 +1340,7 @@ bool put_blr_blob( att_type attribute, ISC_QUAD& blob_id)
|
||||
if (!length)
|
||||
{
|
||||
if (!blob.close())
|
||||
BURP_error_redirect(status_vector, 23);
|
||||
BURP_error_redirect(&status_vector, 23);
|
||||
// msg 23 isc_close_blob failed
|
||||
return false;
|
||||
}
|
||||
@ -1475,7 +1373,7 @@ bool put_blr_blob( att_type attribute, ISC_QUAD& blob_id)
|
||||
|
||||
if (!blob.close())
|
||||
{
|
||||
BURP_error_redirect(status_vector, 23);
|
||||
BURP_error_redirect(&status_vector, 23);
|
||||
// msg 23 isc_close_blob failed
|
||||
}
|
||||
|
||||
@ -1498,17 +1396,9 @@ void put_data(burp_rel* relation)
|
||||
* Write relation meta-data and data.
|
||||
*
|
||||
**************************************/
|
||||
burp_fld* field;
|
||||
ISC_STATUS_ARRAY status_vector;
|
||||
|
||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||
|
||||
// CVC: A signed short isn't enough if the engine allows near 32K fields,
|
||||
// each being char(1) ASCII in the worst case. Looking at BLR generation
|
||||
// below, it's clear an extreme case won't compile => blr_length >= 32K.
|
||||
// However, SSHORT is the limit for request_length in isc_compile_request.
|
||||
SSHORT field_count = 1;
|
||||
|
||||
USHORT field_count = 1; // eof field
|
||||
burp_fld* field;
|
||||
for (field = relation->rel_fields; field; field = field->fld_next)
|
||||
{
|
||||
if (!(field->fld_flags & FLD_computed))
|
||||
@ -1529,7 +1419,7 @@ void put_data(burp_rel* relation)
|
||||
add_word(blr, field_count); // Number of fields, counting eof
|
||||
|
||||
RCRD_OFFSET offset = 0;
|
||||
SSHORT count = 0; // This is param count.
|
||||
USHORT count = 0; // This is param count.
|
||||
|
||||
for (field = relation->rel_fields; field; field = field->fld_next)
|
||||
{
|
||||
@ -1665,7 +1555,7 @@ void put_data(burp_rel* relation)
|
||||
RCRD_OFFSET record_length = offset;
|
||||
RCRD_OFFSET eof_offset = FB_ALIGN(offset, sizeof(SSHORT));
|
||||
// To be used later for the buffer size to receive data
|
||||
const FLD_LENGTH length = (USHORT) (eof_offset + sizeof(SSHORT));
|
||||
const RCRD_LENGTH length = (RCRD_LENGTH) (eof_offset + sizeof(SSHORT));
|
||||
|
||||
// Build FOR loop, body, and eof handler
|
||||
|
||||
@ -1719,7 +1609,7 @@ void put_data(burp_rel* relation)
|
||||
add_byte(blr, blr_end);
|
||||
add_byte(blr, blr_eoc);
|
||||
|
||||
SSHORT blr_length = blr - blr_buffer;
|
||||
unsigned blr_length = blr - blr_buffer;
|
||||
|
||||
#ifdef DEBUG
|
||||
if (debug_on)
|
||||
@ -1728,10 +1618,11 @@ void put_data(burp_rel* relation)
|
||||
|
||||
// Compile request
|
||||
|
||||
FB_API_HANDLE request = 0;
|
||||
if (isc_compile_request(status_vector, &DB, &request, blr_length, (const SCHAR*) blr_buffer))
|
||||
FbLocalStatus status_vector;
|
||||
Firebird::IRequest* request = DB->compileRequest(&status_vector, blr_length, blr_buffer);
|
||||
if (!status_vector.isSuccess())
|
||||
{
|
||||
BURP_error_redirect(status_vector, 27);
|
||||
BURP_error_redirect(&status_vector, 27);
|
||||
// msg 27 isc_compile_request failed
|
||||
fb_print_blr(blr_buffer, blr_length, NULL, NULL, 0);
|
||||
}
|
||||
@ -1741,9 +1632,10 @@ void put_data(burp_rel* relation)
|
||||
BURP_verbose(142, relation->rel_name);
|
||||
// msg 142 writing data for relation %s
|
||||
|
||||
if (isc_start_request(status_vector, &request, &gds_trans, 0))
|
||||
request->start(&status_vector, gds_trans, 0);
|
||||
if (!status_vector.isSuccess())
|
||||
{
|
||||
BURP_error_redirect(status_vector, 28);
|
||||
BURP_error_redirect(&status_vector, 28);
|
||||
// msg 28 isc_start_request failed
|
||||
}
|
||||
|
||||
@ -1766,9 +1658,10 @@ void put_data(burp_rel* relation)
|
||||
ULONG records = 0;
|
||||
while (true)
|
||||
{
|
||||
if (isc_receive(status_vector, &request, 0, length, buffer, 0))
|
||||
request->receive(&status_vector, 0, 0, length, buffer);
|
||||
if (!status_vector.isSuccess())
|
||||
{
|
||||
BURP_error_redirect(status_vector, 29);
|
||||
BURP_error_redirect(&status_vector, 29);
|
||||
// msg 29 isc_receive failed
|
||||
}
|
||||
if (!*eof)
|
||||
@ -1783,7 +1676,7 @@ void put_data(burp_rel* relation)
|
||||
const UCHAR* p;
|
||||
if (tdgbl->gbl_sw_transportable)
|
||||
{
|
||||
record_length = CAN_encode_decode(relation, &xdr_buffer, buffer, TRUE);
|
||||
record_length = CAN_encode_decode(relation, &xdr_buffer, buffer, true);
|
||||
put_int32(att_xdr_length, record_length);
|
||||
p = xdr_buffer.lstr_address;
|
||||
}
|
||||
@ -1825,8 +1718,9 @@ void put_data(burp_rel* relation)
|
||||
BURP_verbose(108, SafeArg() << records);
|
||||
// msg 108 %ld records written
|
||||
|
||||
if (isc_release_request(status_vector, &request))
|
||||
BURP_error_redirect(status_vector, 30);
|
||||
request->free(&status_vector);
|
||||
if (!status_vector.isSuccess())
|
||||
BURP_error_redirect(&status_vector, 30);
|
||||
// msg 30 isc_release_request failed
|
||||
}
|
||||
|
||||
@ -2255,12 +2149,12 @@ bool put_source_blob(att_type attribute, att_type old_attribute, ISC_QUAD& blob_
|
||||
* Include the NULL character to separate each segment.
|
||||
*
|
||||
**************************************/
|
||||
ISC_STATUS_ARRAY status_vector;
|
||||
FbLocalStatus status_vector;
|
||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||
|
||||
// If the blob is null, don't store it. It will be restored as null.
|
||||
|
||||
if (UserBlob::blobIsNull(blob_id))
|
||||
if (BlobWrapper::blobIsNull(blob_id))
|
||||
return false;
|
||||
|
||||
if (tdgbl->gbl_sw_old_descriptions && attribute != att_field_query_header)
|
||||
@ -2268,18 +2162,18 @@ bool put_source_blob(att_type attribute, att_type old_attribute, ISC_QUAD& blob_
|
||||
|
||||
// Open the blob and get it's vital statistics
|
||||
|
||||
UserBlob blob(status_vector);
|
||||
BlobWrapper blob(&status_vector);
|
||||
|
||||
if (!blob.open(DB, gds_trans, blob_id))
|
||||
{
|
||||
BURP_error_redirect(status_vector, 24);
|
||||
BURP_error_redirect(&status_vector, 24);
|
||||
// msg 24 isc_open_blob failed
|
||||
}
|
||||
|
||||
UCHAR blob_info[48];
|
||||
if (!blob.getInfo(sizeof(source_items), source_items, sizeof(blob_info), blob_info))
|
||||
{
|
||||
BURP_error_redirect(status_vector, 20);
|
||||
BURP_error_redirect(&status_vector, 20);
|
||||
// msg 20 isc_blob_info failed
|
||||
}
|
||||
|
||||
@ -2314,7 +2208,7 @@ bool put_source_blob(att_type attribute, att_type old_attribute, ISC_QUAD& blob_
|
||||
// msg 79 don't understand blob info item %ld
|
||||
if (!blob.close())
|
||||
{
|
||||
BURP_error_redirect(status_vector, 23);
|
||||
BURP_error_redirect(&status_vector, 23);
|
||||
// msg 23 isc_close_blob failed
|
||||
}
|
||||
return false;
|
||||
@ -2325,7 +2219,7 @@ bool put_source_blob(att_type attribute, att_type old_attribute, ISC_QUAD& blob_
|
||||
{
|
||||
if (!blob.close())
|
||||
{
|
||||
BURP_error_redirect(status_vector, 23);
|
||||
BURP_error_redirect(&status_vector, 23);
|
||||
// msg 23 isc_close_blob failed
|
||||
}
|
||||
return false;
|
||||
@ -2360,7 +2254,7 @@ bool put_source_blob(att_type attribute, att_type old_attribute, ISC_QUAD& blob_
|
||||
}
|
||||
|
||||
if (!blob.close())
|
||||
BURP_error_redirect(status_vector, 23);
|
||||
BURP_error_redirect(&status_vector, 23);
|
||||
// msg 23 isc_close_blob failed
|
||||
|
||||
if (buffer != static_buffer)
|
||||
@ -2420,7 +2314,7 @@ void write_character_sets()
|
||||
* each user defined character set.
|
||||
*
|
||||
**************************************/
|
||||
isc_req_handle req_handle1 = 0;
|
||||
Firebird::IRequest* req_handle1 = nullptr;
|
||||
|
||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||
|
||||
@ -2518,7 +2412,7 @@ void write_check_constraints()
|
||||
* each check constraint.
|
||||
*
|
||||
**************************************/
|
||||
isc_req_handle req_handle1 = 0;
|
||||
Firebird::IRequest* req_handle1 = nullptr;
|
||||
|
||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||
|
||||
@ -2552,7 +2446,7 @@ void write_collations()
|
||||
* each user defined collation
|
||||
*
|
||||
**************************************/
|
||||
isc_req_handle req_handle1 = 0;
|
||||
Firebird::IRequest* req_handle1 = nullptr;
|
||||
|
||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||
|
||||
@ -2652,28 +2546,29 @@ void write_database( const TEXT* dbb_file)
|
||||
* the database itself.
|
||||
*
|
||||
**************************************/
|
||||
ISC_STATUS_ARRAY status_vector;
|
||||
SCHAR buffer[256];
|
||||
isc_req_handle req_handle1 = 0;
|
||||
FbLocalStatus status_vector;
|
||||
UCHAR buffer[256];
|
||||
Firebird::IRequest* req_handle1 = nullptr;
|
||||
|
||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||
|
||||
put(tdgbl, (UCHAR) rec_physical_db);
|
||||
|
||||
if (isc_database_info(status_vector, &DB, sizeof(db_info_items), db_info_items,
|
||||
sizeof(buffer), buffer))
|
||||
DB->getInfo(&status_vector, sizeof(db_info_items), db_info_items,
|
||||
sizeof(buffer), buffer);
|
||||
if (!status_vector.isSuccess())
|
||||
{
|
||||
BURP_error_redirect(status_vector, 31);
|
||||
BURP_error_redirect(&status_vector, 31);
|
||||
// msg 31 isc_database_info failed
|
||||
}
|
||||
|
||||
USHORT page_size = 0, forced_writes, no_reserve, SQL_dialect, db_read_only;
|
||||
ULONG sweep_interval, page_buffers;
|
||||
USHORT length = 0;
|
||||
for (const SCHAR* d = buffer; *d != isc_info_end; d += length)
|
||||
for (const UCHAR* d = buffer; *d != isc_info_end; d += length)
|
||||
{
|
||||
const UCHAR item = *d++;
|
||||
length = (USHORT) isc_vax_integer(d, 2);
|
||||
length = (USHORT) gds__vax_integer(d, 2);
|
||||
d += 2;
|
||||
switch (item)
|
||||
{
|
||||
@ -2681,27 +2576,27 @@ void write_database( const TEXT* dbb_file)
|
||||
break;
|
||||
|
||||
case isc_info_page_size:
|
||||
page_size = (USHORT) isc_vax_integer(d, length);
|
||||
page_size = (USHORT) gds__vax_integer(d, length);
|
||||
put_int32(att_page_size, page_size);
|
||||
break;
|
||||
|
||||
case isc_info_sweep_interval:
|
||||
sweep_interval = isc_vax_integer(d, length);
|
||||
sweep_interval = gds__vax_integer(d, length);
|
||||
put_int32(att_sweep_interval, sweep_interval);
|
||||
break;
|
||||
|
||||
case isc_info_forced_writes:
|
||||
forced_writes = (USHORT) isc_vax_integer(d, length);
|
||||
forced_writes = (USHORT) gds__vax_integer(d, length);
|
||||
put_int32(att_forced_writes, forced_writes);
|
||||
break;
|
||||
|
||||
case isc_info_no_reserve:
|
||||
if (no_reserve = (USHORT) isc_vax_integer(d, length))
|
||||
if (no_reserve = (USHORT) gds__vax_integer(d, length))
|
||||
put_int32(att_no_reserve, no_reserve);
|
||||
break;
|
||||
|
||||
case isc_info_set_page_buffers:
|
||||
if (page_buffers = isc_vax_integer(d, length))
|
||||
if (page_buffers = gds__vax_integer(d, length))
|
||||
put_int32(att_page_buffers, page_buffers);
|
||||
break;
|
||||
|
||||
@ -2709,17 +2604,17 @@ void write_database( const TEXT* dbb_file)
|
||||
break; // parameter and returns isc_info_error. skip it
|
||||
|
||||
case isc_info_db_sql_dialect:
|
||||
SQL_dialect = (USHORT) isc_vax_integer(d, length);
|
||||
SQL_dialect = (USHORT) gds__vax_integer(d, length);
|
||||
put_int32(att_SQL_dialect, SQL_dialect);
|
||||
break;
|
||||
|
||||
case isc_info_db_read_only:
|
||||
if (db_read_only = (USHORT) isc_vax_integer(d, length))
|
||||
if (db_read_only = (USHORT) gds__vax_integer(d, length))
|
||||
put_int32(att_db_read_only, db_read_only);
|
||||
break;
|
||||
|
||||
default:
|
||||
BURP_error_redirect(status_vector, 31);
|
||||
BURP_error_redirect(&status_vector, 31);
|
||||
// msg 31 isc_database_info failed
|
||||
break;
|
||||
}
|
||||
@ -2787,7 +2682,7 @@ void write_exceptions()
|
||||
*
|
||||
**************************************/
|
||||
TEXT temp[GDS_NAME_LEN];
|
||||
isc_req_handle req_handle1 = 0;
|
||||
Firebird::IRequest* req_handle1 = nullptr;
|
||||
|
||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||
|
||||
@ -2851,7 +2746,7 @@ void write_field_dimensions()
|
||||
* each array field dimension.
|
||||
*
|
||||
**************************************/
|
||||
isc_req_handle req_handle1 = 0;
|
||||
Firebird::IRequest* req_handle1 = nullptr;
|
||||
|
||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||
|
||||
@ -2886,7 +2781,7 @@ void write_filters()
|
||||
*
|
||||
**************************************/
|
||||
TEXT temp[GDS_NAME_LEN];
|
||||
isc_req_handle req_handle1 = 0;
|
||||
Firebird::IRequest* req_handle1 = nullptr;
|
||||
|
||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||
|
||||
@ -2928,7 +2823,7 @@ void write_functions()
|
||||
**************************************/
|
||||
GDS_NAME func;
|
||||
TEXT temp[GDS_NAME_LEN * 2];
|
||||
isc_req_handle req_handle1 = 0;
|
||||
Firebird::IRequest* req_handle1 = nullptr;
|
||||
|
||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||
|
||||
@ -3182,7 +3077,7 @@ void write_generators()
|
||||
* Write any defined generators.
|
||||
*
|
||||
**************************************/
|
||||
isc_req_handle req_handle1 = 0;
|
||||
Firebird::IRequest* req_handle1 = nullptr;
|
||||
TEXT temp[GDS_NAME_LEN];
|
||||
|
||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||
@ -3291,7 +3186,7 @@ void write_global_fields()
|
||||
*
|
||||
**************************************/
|
||||
TEXT temp[GDS_NAME_LEN];
|
||||
isc_req_handle req_handle1 = 0;
|
||||
Firebird::IRequest* req_handle1 = nullptr;
|
||||
|
||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||
|
||||
@ -3522,7 +3417,7 @@ void write_packages()
|
||||
*
|
||||
**************************************/
|
||||
TEXT temp[GDS_NAME_LEN];
|
||||
isc_req_handle req_handle1 = 0;
|
||||
Firebird::IRequest* req_handle1 = nullptr;
|
||||
|
||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||
|
||||
@ -3589,7 +3484,7 @@ void write_procedures()
|
||||
**************************************/
|
||||
GDS_NAME proc;
|
||||
TEXT temp[GDS_NAME_LEN * 2];
|
||||
isc_req_handle req_handle1 = 0;
|
||||
Firebird::IRequest* req_handle1 = nullptr;
|
||||
|
||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||
|
||||
@ -3779,7 +3674,7 @@ void write_ref_constraints()
|
||||
* each referential constraint.
|
||||
*
|
||||
**************************************/
|
||||
isc_req_handle req_handle1 = 0;
|
||||
Firebird::IRequest* req_handle1 = nullptr;
|
||||
|
||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||
|
||||
@ -3815,7 +3710,7 @@ void write_rel_constraints()
|
||||
*
|
||||
**************************************/
|
||||
TEXT temp[GDS_NAME_LEN];
|
||||
isc_req_handle req_handle1 = 0;
|
||||
Firebird::IRequest* req_handle1 = nullptr;
|
||||
|
||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||
|
||||
@ -3859,7 +3754,7 @@ void write_relations()
|
||||
*
|
||||
**************************************/
|
||||
TEXT temp[GDS_NAME_LEN];
|
||||
isc_req_handle req_handle1 = 0;
|
||||
Firebird::IRequest* req_handle1 = nullptr;
|
||||
|
||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||
|
||||
@ -3989,7 +3884,7 @@ void write_relations()
|
||||
void write_secclasses()
|
||||
{
|
||||
TEXT temp[GDS_NAME_LEN];
|
||||
isc_req_handle req_handle1 = 0;
|
||||
Firebird::IRequest* req_handle1 = nullptr;
|
||||
|
||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||
|
||||
@ -4025,7 +3920,7 @@ void write_shadow_files()
|
||||
*
|
||||
**************************************/
|
||||
BASED ON RDB$FILES.RDB$FILE_NAME temp;
|
||||
isc_req_handle req_handle1 = 0;
|
||||
Firebird::IRequest* req_handle1 = nullptr;
|
||||
|
||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||
|
||||
@ -4066,7 +3961,7 @@ void write_sql_roles()
|
||||
* each SQL roles.
|
||||
*
|
||||
**************************************/
|
||||
isc_req_handle req_handle1 = 0;
|
||||
Firebird::IRequest* req_handle1 = nullptr;
|
||||
TEXT temp[GDS_NAME_LEN];
|
||||
|
||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||
@ -4135,7 +4030,7 @@ void write_mapping()
|
||||
* each names mapping.
|
||||
*
|
||||
**************************************/
|
||||
isc_req_handle req_handle = 0;
|
||||
Firebird::IRequest* req_handle = nullptr;
|
||||
TEXT temp[GDS_NAME_LEN];
|
||||
|
||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||
@ -4218,7 +4113,7 @@ void write_triggers()
|
||||
*
|
||||
**************************************/
|
||||
TEXT temp[GDS_NAME_LEN];
|
||||
isc_req_handle req_handle1 = 0;
|
||||
Firebird::IRequest* req_handle1 = nullptr;
|
||||
|
||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||
|
||||
@ -4335,7 +4230,7 @@ void write_trigger_messages()
|
||||
*
|
||||
**************************************/
|
||||
TEXT temp[GDS_NAME_LEN];
|
||||
isc_req_handle req_handle1 = 0;
|
||||
Firebird::IRequest* req_handle1 = nullptr;
|
||||
|
||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||
|
||||
@ -4374,7 +4269,7 @@ void write_types()
|
||||
* each type.
|
||||
*
|
||||
**************************************/
|
||||
isc_req_handle req_handle1 = 0;
|
||||
Firebird::IRequest* req_handle1 = nullptr;
|
||||
|
||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||
|
||||
@ -4414,7 +4309,7 @@ void write_user_privileges()
|
||||
*
|
||||
**************************************/
|
||||
TEXT temp[GDS_NAME_LEN];
|
||||
isc_req_handle req_handle1 = 0;
|
||||
Firebird::IRequest* req_handle1 = nullptr;
|
||||
|
||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||
|
||||
|
@ -65,6 +65,7 @@
|
||||
#include <ctype.h>
|
||||
#endif
|
||||
#include "../common/utils_proto.h"
|
||||
#include "../common/status.h"
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
@ -82,6 +83,7 @@
|
||||
#endif
|
||||
|
||||
using MsgFormat::SafeArg;
|
||||
using Firebird::FbLocalStatus;
|
||||
|
||||
const char* fopen_write_type = "w";
|
||||
const char* fopen_read_type = "r";
|
||||
@ -102,7 +104,7 @@ enum gbak_action
|
||||
//FDESC = 3 // CVC: Unused
|
||||
};
|
||||
|
||||
static void close_out_transaction(gbak_action, isc_tr_handle*);
|
||||
static void close_out_transaction(gbak_action, Firebird::ITransaction**);
|
||||
//static void enable_signals();
|
||||
//static void excp_handler();
|
||||
static SLONG get_number(const SCHAR*);
|
||||
@ -272,8 +274,8 @@ static int svc_api_gbak(Firebird::UtilSvc* uSvc, const Switches& switches)
|
||||
|
||||
const Firebird::string* dbName = flag_restore ? &files[1] : &files[0];
|
||||
|
||||
ISC_STATUS_ARRAY status;
|
||||
FB_API_HANDLE svc_handle = 0;
|
||||
FbLocalStatus status;
|
||||
Firebird::IService* svc_handle = nullptr;
|
||||
|
||||
try
|
||||
{
|
||||
@ -317,21 +319,22 @@ static int svc_api_gbak(Firebird::UtilSvc* uSvc, const Switches& switches)
|
||||
|
||||
spb.insertString(isc_spb_command_line, options);
|
||||
|
||||
if (isc_service_attach(status, 0, service.c_str(), &svc_handle,
|
||||
spb.getBufferLength(), reinterpret_cast<const char*>(spb.getBuffer())))
|
||||
svc_handle = Firebird::DispatcherPtr()->attachServiceManager(&status, service.c_str(),
|
||||
spb.getBufferLength(), spb.getBuffer());
|
||||
if (!status.isSuccess())
|
||||
{
|
||||
BURP_print_status(true, status);
|
||||
BURP_print_status(true, &status);
|
||||
BURP_print(true, 83);
|
||||
// msg 83 Exiting before completion due to errors
|
||||
return FINI_ERROR;
|
||||
}
|
||||
|
||||
char thd[10];
|
||||
UCHAR thd[10];
|
||||
// 'isc_action_svc_restore/isc_action_svc_backup'
|
||||
// 'isc_spb_verbose'
|
||||
// 'isc_spb_verbint'
|
||||
|
||||
char* thd_ptr = thd;
|
||||
UCHAR* thd_ptr = thd;
|
||||
if (flag_restore)
|
||||
*thd_ptr++ = isc_action_svc_restore;
|
||||
else
|
||||
@ -344,41 +347,43 @@ static int svc_api_gbak(Firebird::UtilSvc* uSvc, const Switches& switches)
|
||||
{
|
||||
*thd_ptr++ = isc_spb_verbint;
|
||||
//stream verbint_val into a SPB
|
||||
put_vax_long(reinterpret_cast<UCHAR*>(thd_ptr), verbint_val);
|
||||
put_vax_long(thd_ptr, verbint_val);
|
||||
thd_ptr += sizeof(SLONG);
|
||||
}
|
||||
|
||||
const USHORT thdlen = thd_ptr - thd;
|
||||
fb_assert(thdlen <= sizeof(thd));
|
||||
|
||||
if (isc_service_start(status, &svc_handle, NULL, thdlen, thd))
|
||||
svc_handle->start(&status, thdlen, thd);
|
||||
if (!status.isSuccess())
|
||||
{
|
||||
BURP_print_status(true, status);
|
||||
isc_service_detach(status, &svc_handle);
|
||||
BURP_print_status(true, &status);
|
||||
svc_handle->release();
|
||||
BURP_print(true, 83); // msg 83 Exiting before completion due to errors
|
||||
return FINI_ERROR;
|
||||
}
|
||||
|
||||
const char sendbuf[] = { isc_info_svc_line };
|
||||
char respbuf[1024];
|
||||
const char* sl;
|
||||
const UCHAR sendbuf[] = { isc_info_svc_line };
|
||||
UCHAR respbuf[1024];
|
||||
const UCHAR* sl;
|
||||
do {
|
||||
if (isc_service_query(status, &svc_handle, NULL, 0, NULL,
|
||||
sizeof(sendbuf), sendbuf,
|
||||
sizeof(respbuf), respbuf))
|
||||
svc_handle->query(&status, 0, NULL,
|
||||
sizeof(sendbuf), sendbuf,
|
||||
sizeof(respbuf), respbuf);
|
||||
if (!status.isSuccess())
|
||||
{
|
||||
BURP_print_status(true, status);
|
||||
isc_service_detach(status, &svc_handle);
|
||||
BURP_print_status(true, &status);
|
||||
svc_handle->release();
|
||||
BURP_print(true, 83); // msg 83 Exiting before completion due to errors
|
||||
return FINI_ERROR;
|
||||
}
|
||||
|
||||
char* p = respbuf;
|
||||
UCHAR* p = respbuf;
|
||||
sl = p;
|
||||
|
||||
if (*p++ == isc_info_svc_line)
|
||||
{
|
||||
const ISC_USHORT len = (ISC_USHORT) isc_vax_integer(p, sizeof(ISC_USHORT));
|
||||
const ISC_USHORT len = (ISC_USHORT) gds__vax_integer(p, sizeof(ISC_USHORT));
|
||||
p += sizeof(ISC_USHORT);
|
||||
if (!len)
|
||||
{
|
||||
@ -395,18 +400,16 @@ static int svc_api_gbak(Firebird::UtilSvc* uSvc, const Switches& switches)
|
||||
}
|
||||
} while (*sl == isc_info_svc_line);
|
||||
|
||||
isc_service_detach(status, &svc_handle);
|
||||
svc_handle->release();
|
||||
return FINI_OK;
|
||||
}
|
||||
catch (const Firebird::Exception& e)
|
||||
{
|
||||
Firebird::StaticStatusVector s;
|
||||
e.stuffException(s);
|
||||
BURP_print_status(true, s.begin());
|
||||
FbLocalStatus s;
|
||||
e.stuffException(&s);
|
||||
BURP_print_status(true, &s);
|
||||
if (svc_handle)
|
||||
{
|
||||
isc_service_detach(status, &svc_handle);
|
||||
}
|
||||
svc_handle->release();
|
||||
BURP_print(true, 83); // msg 83 Exiting before completion due to errors
|
||||
return FINI_ERROR;
|
||||
}
|
||||
@ -723,6 +726,41 @@ int gbak(Firebird::UtilSvc* uSvc)
|
||||
}
|
||||
tdgbl->gbl_sw_sql_role = argv[itr];
|
||||
break;
|
||||
case IN_SW_BURP_KEYHOLD:
|
||||
if (++itr >= argc)
|
||||
{
|
||||
BURP_error(381, true);
|
||||
// KeyHolder parameter missing
|
||||
}
|
||||
if (tdgbl->gbl_sw_keyholder)
|
||||
BURP_error(334, true, SafeArg() << in_sw_tab->in_sw_name);
|
||||
tdgbl->gbl_sw_keyholder = argv[itr];
|
||||
break;
|
||||
case IN_SW_BURP_CRYPT:
|
||||
if (++itr >= argc)
|
||||
{
|
||||
BURP_error(377, true);
|
||||
// CryptPlugin parameter missing
|
||||
}
|
||||
if (tdgbl->gbl_sw_crypt)
|
||||
BURP_error(334, true, SafeArg() << in_sw_tab->in_sw_name);
|
||||
tdgbl->gbl_sw_crypt = argv[itr];
|
||||
break;
|
||||
case IN_SW_BURP_KEYNAME:
|
||||
if (++itr >= argc)
|
||||
{
|
||||
BURP_error(375, true);
|
||||
// Key name parameter missing
|
||||
}
|
||||
if (tdgbl->gbl_sw_keyname)
|
||||
BURP_error(334, true, SafeArg() << in_sw_tab->in_sw_name);
|
||||
tdgbl->gbl_sw_keyname = argv[itr];
|
||||
break;
|
||||
case IN_SW_BURP_ZIP:
|
||||
if (tdgbl->gbl_sw_zip)
|
||||
BURP_error(334, true, SafeArg() << in_sw_tab->in_sw_name);
|
||||
tdgbl->gbl_sw_zip = true;
|
||||
break;
|
||||
case IN_SW_BURP_FA:
|
||||
if (tdgbl->gbl_sw_blk_factor)
|
||||
BURP_error(333, true, SafeArg() << in_sw_tab->in_sw_name << tdgbl->gbl_sw_blk_factor);
|
||||
@ -1199,6 +1237,8 @@ int gbak(Firebird::UtilSvc* uSvc)
|
||||
}
|
||||
else if (tdgbl->gbl_sw_old_descriptions)
|
||||
errNum = IN_SW_BURP_OL;
|
||||
else if (tdgbl->gbl_sw_zip)
|
||||
errNum = IN_SW_BURP_ZIP;
|
||||
|
||||
if (errNum != IN_SW_BURP_0)
|
||||
{
|
||||
@ -1285,10 +1325,8 @@ int gbak(Firebird::UtilSvc* uSvc)
|
||||
{
|
||||
// Non-burp exception was caught
|
||||
tdgbl->burp_throw = false;
|
||||
Firebird::StaticStatusVector s;
|
||||
e.stuffException(s);
|
||||
fb_utils::copyStatus(tdgbl->status_vector, ISC_STATUS_LENGTH, s.begin(), s.getCount());
|
||||
BURP_print_status(true, tdgbl->status_vector);
|
||||
e.stuffException(&tdgbl->status_vector);
|
||||
BURP_print_status(true, &tdgbl->status_vector);
|
||||
if (! tdgbl->uSvc->isService())
|
||||
{
|
||||
BURP_print(true, 83); // msg 83 Exiting before completion due to errors
|
||||
@ -1315,14 +1353,17 @@ int gbak(Firebird::UtilSvc* uSvc)
|
||||
}
|
||||
|
||||
// Detach from database to release system resources
|
||||
if (tdgbl->db_handle != 0)
|
||||
if (tdgbl->db_handle)
|
||||
{
|
||||
close_out_transaction(action, &tdgbl->tr_handle);
|
||||
close_out_transaction(action, &tdgbl->global_trans);
|
||||
if (isc_detach_database(tdgbl->status_vector, &tdgbl->db_handle))
|
||||
{
|
||||
BURP_print_status(true, tdgbl->status_vector);
|
||||
}
|
||||
|
||||
tdgbl->db_handle->detach(&tdgbl->status_vector);
|
||||
|
||||
if (tdgbl->status_vector->getState() & Firebird::IStatus::STATE_ERRORS)
|
||||
BURP_print_status(true, &tdgbl->status_vector);
|
||||
else
|
||||
tdgbl->db_handle = NULL;
|
||||
}
|
||||
|
||||
// Close the status output file
|
||||
@ -1428,7 +1469,7 @@ void BURP_error(USHORT errcode, bool abort, const char* str)
|
||||
}
|
||||
|
||||
|
||||
void BURP_error_redirect(const ISC_STATUS* status_vector, USHORT errcode, const SafeArg& arg)
|
||||
void BURP_error_redirect(Firebird::IStatus* status_vector, USHORT errcode, const SafeArg& arg)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
@ -1516,26 +1557,24 @@ void BURP_msg_get(USHORT number, TEXT* output_msg, const SafeArg& arg)
|
||||
strcpy(output_msg, buffer);
|
||||
}
|
||||
|
||||
|
||||
void BURP_output_version(void* arg1, const TEXT* arg2)
|
||||
void OutputVersion::callback(Firebird::CheckStatusWrapper* status, const char* text)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
* B U R P _ o u t p u t _ v e r s i o n
|
||||
* O u t p u t V e r s i o n :: c a l l b a c k
|
||||
*
|
||||
**************************************
|
||||
*
|
||||
* Functional description
|
||||
* Callback routine for access method
|
||||
* printing (specifically show version);
|
||||
* printing (specifically show version)
|
||||
* will accept.
|
||||
*
|
||||
**************************************/
|
||||
|
||||
burp_output(false, static_cast<const char*>(arg1), arg2);
|
||||
burp_output(false, format, text);
|
||||
}
|
||||
|
||||
|
||||
void BURP_print(bool err, USHORT number, const SafeArg& arg)
|
||||
{
|
||||
/**************************************
|
||||
@ -1577,7 +1616,7 @@ void BURP_print(bool err, USHORT number, const char* str)
|
||||
}
|
||||
|
||||
|
||||
void BURP_print_status(bool err, const ISC_STATUS* status_vector)
|
||||
void BURP_print_status(bool err, Firebird::IStatus* status_vector)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
@ -1592,7 +1631,7 @@ void BURP_print_status(bool err, const ISC_STATUS* status_vector)
|
||||
**************************************/
|
||||
if (status_vector)
|
||||
{
|
||||
const ISC_STATUS* vector = status_vector;
|
||||
const ISC_STATUS* vector = status_vector->getErrors();
|
||||
|
||||
if (err)
|
||||
{
|
||||
@ -1622,7 +1661,7 @@ void BURP_print_status(bool err, const ISC_STATUS* status_vector)
|
||||
}
|
||||
|
||||
|
||||
void BURP_print_warning(const ISC_STATUS* status_vector)
|
||||
void BURP_print_warning(Firebird::IStatus* status)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
@ -1635,14 +1674,10 @@ void BURP_print_warning(const ISC_STATUS* status_vector)
|
||||
* to allow redirecting output.
|
||||
*
|
||||
**************************************/
|
||||
if (status_vector)
|
||||
if (status && (status->getState() & Firebird::IStatus::STATE_WARNINGS))
|
||||
{
|
||||
// skip the error, assert that one does not exist
|
||||
fb_assert(status_vector[0] == isc_arg_gds);
|
||||
fb_assert(status_vector[1] == 0);
|
||||
|
||||
// print the warning message
|
||||
const ISC_STATUS* vector = &status_vector[2];
|
||||
const ISC_STATUS* vector = status->getWarnings();
|
||||
SCHAR s[1024];
|
||||
|
||||
if (fb_interpret(s, sizeof(s), &vector))
|
||||
@ -1716,7 +1751,7 @@ void BURP_verbose(USHORT number, const char* str)
|
||||
}
|
||||
|
||||
|
||||
static void close_out_transaction(gbak_action action, isc_tr_handle* handle)
|
||||
static void close_out_transaction(gbak_action action, Firebird::ITransaction** tPtr)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
@ -1731,31 +1766,38 @@ static void close_out_transaction(gbak_action action, isc_tr_handle* handle)
|
||||
* returned to the system.
|
||||
*
|
||||
**************************************/
|
||||
if (*handle != 0)
|
||||
if (*tPtr)
|
||||
{
|
||||
ISC_STATUS_ARRAY status_vector;
|
||||
FbLocalStatus status_vector;
|
||||
if (action == RESTORE)
|
||||
{
|
||||
// Even if the restore failed, commit the transaction so that
|
||||
// a partial database is at least recovered.
|
||||
isc_commit_transaction(status_vector, handle);
|
||||
if (status_vector[1])
|
||||
(*tPtr)->commit(&status_vector);
|
||||
if (!status_vector.isSuccess())
|
||||
{
|
||||
// If we can't commit - have to roll it back, as
|
||||
// we need to close all outstanding transactions before
|
||||
// we can detach from the database.
|
||||
isc_rollback_transaction(status_vector, handle);
|
||||
if (status_vector[1])
|
||||
BURP_print_status(false, status_vector);
|
||||
(*tPtr)->rollback(&status_vector);
|
||||
if (!status_vector.isSuccess())
|
||||
BURP_print_status(false, &status_vector);
|
||||
else
|
||||
*tPtr = nullptr;
|
||||
}
|
||||
else
|
||||
*tPtr = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
// A backup shouldn't touch any data - we ensure that
|
||||
// by never writing data during a backup, but let's double
|
||||
// ensure it by doing a rollback
|
||||
if (isc_rollback_transaction(status_vector, handle))
|
||||
BURP_print_status(false, status_vector);
|
||||
(*tPtr)->rollback(&status_vector);
|
||||
if (!status_vector.isSuccess())
|
||||
BURP_print_status(false, &status_vector);
|
||||
else
|
||||
*tPtr = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1810,40 +1852,102 @@ static gbak_action open_files(const TEXT* file1,
|
||||
*
|
||||
**************************************/
|
||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||
ISC_STATUS_ARRAY temp_status;
|
||||
ISC_STATUS* status_vector = temp_status;
|
||||
FbLocalStatus status_vector;
|
||||
|
||||
// try to attach the database using the first file_name
|
||||
|
||||
if (sw_replace != IN_SW_BURP_C && sw_replace != IN_SW_BURP_R)
|
||||
{
|
||||
if (!isc_attach_database(status_vector,
|
||||
(SSHORT) 0, file1,
|
||||
&tdgbl->db_handle,
|
||||
dpb.getBufferLength(),
|
||||
reinterpret_cast<const char*>(dpb.getBuffer())))
|
||||
Firebird::DispatcherPtr provider;
|
||||
|
||||
// provide crypt key(s) for engine
|
||||
|
||||
if (tdgbl->gbl_sw_keyholder)
|
||||
{
|
||||
tdgbl->gbl_database_file_name = file1;
|
||||
provider->setDbCryptCallback(&status_vector, MVOL_get_crypt(tdgbl));
|
||||
if (!status_vector.isSuccess())
|
||||
{
|
||||
BURP_print_status(true, &status_vector);
|
||||
return QUIT;
|
||||
}
|
||||
}
|
||||
|
||||
tdgbl->db_handle = provider->attachDatabase(&status_vector, file1,
|
||||
dpb.getBufferLength(), dpb.getBuffer());
|
||||
|
||||
if (!(status_vector->getState() & Firebird::IStatus::STATE_ERRORS))
|
||||
{
|
||||
if (sw_replace != IN_SW_BURP_B)
|
||||
{
|
||||
// msg 13 REPLACE specified, but the first file %s is a database
|
||||
BURP_error(13, true, file1);
|
||||
if (isc_detach_database(status_vector, &tdgbl->db_handle)) {
|
||||
BURP_print_status(true, status_vector);
|
||||
}
|
||||
tdgbl->db_handle->detach(&status_vector);
|
||||
|
||||
if (status_vector->getState() & Firebird::IStatus::STATE_ERRORS)
|
||||
BURP_print_status(true, &status_vector);
|
||||
else
|
||||
tdgbl->db_handle = NULL;
|
||||
|
||||
return QUIT;
|
||||
}
|
||||
if (tdgbl->gbl_sw_version)
|
||||
{
|
||||
// msg 139 Version(s) for database "%s"
|
||||
BURP_print(false, 139, file1);
|
||||
isc_version(&tdgbl->db_handle, BURP_output_version, (void*) "\t%s\n");
|
||||
OutputVersion outputVersion("\t%s\n");
|
||||
Firebird::UtilInterfacePtr()->getFbVersion(&status_vector, tdgbl->db_handle, &outputVersion);
|
||||
}
|
||||
BURP_verbose(166, file1); // msg 166: readied database %s for backup
|
||||
|
||||
if (tdgbl->gbl_sw_keyholder)
|
||||
{
|
||||
unsigned char info[] = {fb_info_crypt_key, fb_info_crypt_plugin};
|
||||
unsigned char buffer[(1 + 2 + MAX_SQL_IDENTIFIER_SIZE) * 2 + 2];
|
||||
unsigned int len;
|
||||
|
||||
tdgbl->db_handle->getInfo(&status_vector, sizeof(info), info, sizeof(buffer), buffer);
|
||||
|
||||
UCHAR* p = buffer;
|
||||
while(p)
|
||||
{
|
||||
switch(*p++)
|
||||
{
|
||||
case fb_info_crypt_key:
|
||||
len = gds__vax_integer(p, 2);
|
||||
if (len < sizeof(tdgbl->gbl_hdr_keybuffer))
|
||||
{
|
||||
memcpy(tdgbl->gbl_hdr_keybuffer, p + 2, len);
|
||||
tdgbl->gbl_hdr_keybuffer[len] = 0;
|
||||
if (!tdgbl->gbl_sw_keyname)
|
||||
tdgbl->gbl_sw_keyname = tdgbl->gbl_hdr_keybuffer;
|
||||
}
|
||||
break;
|
||||
|
||||
case fb_info_crypt_plugin:
|
||||
len = gds__vax_integer(p, 2);
|
||||
if (len < sizeof(tdgbl->gbl_hdr_cryptbuffer))
|
||||
{
|
||||
memcpy(tdgbl->gbl_hdr_cryptbuffer, p + 2, len);
|
||||
tdgbl->gbl_hdr_cryptbuffer[len] = 0;
|
||||
if (!tdgbl->gbl_sw_crypt)
|
||||
tdgbl->gbl_sw_crypt = tdgbl->gbl_hdr_cryptbuffer;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
p = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
p += (2 + len);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (sw_replace == IN_SW_BURP_B ||
|
||||
(status_vector[1] != isc_io_error && status_vector[1] != isc_bad_db_format))
|
||||
(status_vector->getErrors()[1] != isc_io_error && status_vector->getErrors()[1] != isc_bad_db_format))
|
||||
{
|
||||
BURP_print_status(true, status_vector);
|
||||
BURP_print_status(true, &status_vector);
|
||||
return QUIT;
|
||||
}
|
||||
}
|
||||
@ -1919,7 +2023,7 @@ static gbak_action open_files(const TEXT* file1,
|
||||
{
|
||||
Firebird::string nm = tdgbl->toSystem(fil->fil_name);
|
||||
#ifdef WIN_NT
|
||||
if ((fil->fil_fd = MVOL_open(nm.c_str(), MODE_WRITE, CREATE_ALWAYS)) ==
|
||||
if ((fil->fil_fd = NT_tape_open(nm.c_str(), MODE_WRITE, CREATE_ALWAYS)) ==
|
||||
INVALID_HANDLE_VALUE)
|
||||
#else
|
||||
if ((fil->fil_fd = os_utils::open(nm.c_str(), MODE_WRITE, open_mask)) == -1)
|
||||
@ -1965,10 +2069,12 @@ static gbak_action open_files(const TEXT* file1,
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isc_detach_database(status_vector, &tdgbl->db_handle))
|
||||
{
|
||||
BURP_print_status(false, status_vector);
|
||||
}
|
||||
tdgbl->db_handle->detach(&status_vector);
|
||||
|
||||
if (status_vector->getState() & Firebird::IStatus::STATE_ERRORS)
|
||||
BURP_print_status(true, &status_vector);
|
||||
else
|
||||
tdgbl->db_handle = NULL;
|
||||
}
|
||||
|
||||
return flag;
|
||||
@ -2027,7 +2133,7 @@ static gbak_action open_files(const TEXT* file1,
|
||||
// open first file
|
||||
Firebird::string nm = tdgbl->toSystem(fil->fil_name);
|
||||
#ifdef WIN_NT
|
||||
if ((fil->fil_fd = MVOL_open(nm.c_str(), MODE_READ, OPEN_EXISTING)) ==
|
||||
if ((fil->fil_fd = NT_tape_open(nm.c_str(), MODE_READ, OPEN_EXISTING)) ==
|
||||
INVALID_HANDLE_VALUE)
|
||||
#else
|
||||
if ((fil->fil_fd = os_utils::open(nm.c_str(), MODE_READ)) == INVALID_HANDLE_VALUE)
|
||||
@ -2073,7 +2179,7 @@ static gbak_action open_files(const TEXT* file1,
|
||||
tdgbl->action->act_file = fil;
|
||||
Firebird::string nm = tdgbl->toSystem(fil->fil_name);
|
||||
#ifdef WIN_NT
|
||||
if ((fil->fil_fd = MVOL_open(nm.c_str(), MODE_READ, OPEN_EXISTING)) ==
|
||||
if ((fil->fil_fd = NT_tape_open(nm.c_str(), MODE_READ, OPEN_EXISTING)) ==
|
||||
INVALID_HANDLE_VALUE)
|
||||
#else
|
||||
if ((fil->fil_fd = os_utils::open(nm.c_str(), MODE_READ)) == INVALID_HANDLE_VALUE)
|
||||
@ -2139,49 +2245,71 @@ static gbak_action open_files(const TEXT* file1,
|
||||
BURP_error(262, true, *file2);
|
||||
// msg 262 size specification either missing or incorrect for file %s
|
||||
|
||||
if ((sw_replace == IN_SW_BURP_C || sw_replace == IN_SW_BURP_R) &&
|
||||
!isc_attach_database(status_vector,
|
||||
(SSHORT) 0, *file2,
|
||||
&tdgbl->db_handle,
|
||||
dpb.getBufferLength(),
|
||||
reinterpret_cast<const char*>(dpb.getBuffer())))
|
||||
if (sw_replace == IN_SW_BURP_C || sw_replace == IN_SW_BURP_R)
|
||||
{
|
||||
if (sw_replace == IN_SW_BURP_C)
|
||||
Firebird::DispatcherPtr provider;
|
||||
|
||||
// provide crypt key(s) for engine
|
||||
|
||||
if (tdgbl->gbl_sw_keyholder)
|
||||
{
|
||||
if (isc_detach_database(status_vector, &tdgbl->db_handle)) {
|
||||
BURP_print_status(true, status_vector);
|
||||
}
|
||||
BURP_error(14, true, *file2);
|
||||
// msg 14 database %s already exists. To replace it, use the -R switch
|
||||
}
|
||||
else
|
||||
{
|
||||
isc_drop_database(status_vector, &tdgbl->db_handle);
|
||||
if (tdgbl->db_handle)
|
||||
tdgbl->gbl_database_file_name = *file2;
|
||||
provider->setDbCryptCallback(&status_vector, MVOL_get_crypt(tdgbl));
|
||||
if (!status_vector.isSuccess())
|
||||
{
|
||||
ISC_STATUS_ARRAY status_vector2;
|
||||
if (isc_detach_database(status_vector2, &tdgbl->db_handle)) {
|
||||
BURP_print_status(false, status_vector2);
|
||||
}
|
||||
|
||||
// Complain only if the drop database entrypoint is available.
|
||||
// If it isn't, the database will simply be overwritten.
|
||||
|
||||
if (status_vector[1] != isc_unavailable)
|
||||
BURP_error(233, true, *file2);
|
||||
// msg 233 Cannot drop database %s, might be in use
|
||||
BURP_print_status(true, &status_vector);
|
||||
return QUIT;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sw_replace == IN_SW_BURP_R && status_vector[1] == isc_adm_task_denied)
|
||||
{
|
||||
// if we got an error from attach database and we have replace switch set
|
||||
// then look for error from attach returned due to not owner, if we are
|
||||
// not owner then return the error status back up
|
||||
|
||||
BURP_error(274, true);
|
||||
// msg # 274 : Cannot restore over current database, must be sysdba
|
||||
// or owner of the existing database.
|
||||
tdgbl->db_handle = provider->attachDatabase(&status_vector, *file2,
|
||||
dpb.getBufferLength(), dpb.getBuffer());
|
||||
|
||||
if (!(status_vector->getState() & Firebird::IStatus::STATE_ERRORS))
|
||||
{
|
||||
if (sw_replace == IN_SW_BURP_C)
|
||||
{
|
||||
tdgbl->db_handle->detach(&status_vector);
|
||||
|
||||
if (status_vector->getState() & Firebird::IStatus::STATE_ERRORS)
|
||||
BURP_print_status(true, &status_vector);
|
||||
else
|
||||
tdgbl->db_handle = NULL;
|
||||
|
||||
BURP_error(14, true, *file2);
|
||||
// msg 14 database %s already exists. To replace it, use the -R switch
|
||||
}
|
||||
else
|
||||
{
|
||||
tdgbl->db_handle->dropDatabase(&status_vector);
|
||||
|
||||
if (status_vector->getState() & Firebird::IStatus::STATE_ERRORS)
|
||||
{
|
||||
Firebird::FbLocalStatus status2;
|
||||
tdgbl->db_handle->detach(&status2);
|
||||
|
||||
if (status2->getState() & Firebird::IStatus::STATE_ERRORS)
|
||||
BURP_print_status(true, &status2);
|
||||
else
|
||||
tdgbl->db_handle = NULL;
|
||||
|
||||
BURP_error(233, true, *file2);
|
||||
// msg 233 Cannot drop database %s, might be in use
|
||||
}
|
||||
else
|
||||
tdgbl->db_handle = NULL;
|
||||
}
|
||||
}
|
||||
else if (sw_replace == IN_SW_BURP_R && status_vector->getErrors()[1] == isc_adm_task_denied)
|
||||
{
|
||||
// if we got an error from attach database and we have replace switch set
|
||||
// then look for error from attach returned due to not owner, if we are
|
||||
// not owner then return the error status back up
|
||||
|
||||
BURP_error(274, true);
|
||||
// msg # 274 : Cannot restore over current database, must be sysdba
|
||||
// or owner of the existing database.
|
||||
}
|
||||
}
|
||||
|
||||
// check the file size specification
|
||||
@ -2458,18 +2586,18 @@ void BurpGlobals::read_stats(SINT64* stats)
|
||||
if (!db_handle)
|
||||
return;
|
||||
|
||||
const char info[] =
|
||||
const UCHAR info[] =
|
||||
{
|
||||
isc_info_reads,
|
||||
isc_info_writes
|
||||
};
|
||||
|
||||
ISC_STATUS_ARRAY status = {0};
|
||||
char buffer[sizeof(info) * (1 + 2 + 8) + 2];
|
||||
FbLocalStatus status;
|
||||
UCHAR buffer[sizeof(info) * (1 + 2 + 8) + 2];
|
||||
|
||||
isc_database_info(status, &db_handle, sizeof(info), info, sizeof(buffer), buffer);
|
||||
db_handle->getInfo(&status, sizeof(info), info, sizeof(buffer), buffer);
|
||||
|
||||
char* p = buffer, *const e = buffer + sizeof(buffer);
|
||||
UCHAR* p = buffer, *const e = buffer + sizeof(buffer);
|
||||
while (p < e)
|
||||
{
|
||||
int flag = -1;
|
||||
@ -2490,7 +2618,7 @@ void BurpGlobals::read_stats(SINT64* stats)
|
||||
|
||||
if (flag != -1)
|
||||
{
|
||||
const int len = isc_vax_integer(p + 1, 2);
|
||||
const int len = gds__vax_integer(p + 1, 2);
|
||||
stats[flag] = isc_portable_integer((ISC_UCHAR*) p + 1 + 2, len);
|
||||
p += len + 3;
|
||||
}
|
||||
@ -2603,3 +2731,21 @@ UnicodeCollationHolder::~UnicodeCollationHolder()
|
||||
// cs should be deleted by texttype_fn_destroy call above
|
||||
delete tt;
|
||||
}
|
||||
|
||||
void BURP_makeSymbol(BurpGlobals* tdgbl, Firebird::string& name) // add double quotes to string
|
||||
{
|
||||
if (tdgbl->gbl_dialect < SQL_DIALECT_V6)
|
||||
return;
|
||||
|
||||
const char dq = '"';
|
||||
for (unsigned p = 0; p < name.length(); ++p)
|
||||
{
|
||||
if (name[p] == dq)
|
||||
{
|
||||
name.insert(p, 1, dq);
|
||||
++p;
|
||||
}
|
||||
}
|
||||
name.insert(0u, 1, dq);
|
||||
name += dq;
|
||||
}
|
||||
|
238
src/burp/burp.h
238
src/burp/burp.h
@ -31,8 +31,11 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include "../jrd/ibase.h"
|
||||
#include "firebird/Interface.h"
|
||||
#include "firebird/Message.h"
|
||||
#include "../common/dsc.h"
|
||||
#include "../burp/misc_proto.h"
|
||||
#include "../burp/mvol_proto.h"
|
||||
#include "../yvalve/gds_proto.h"
|
||||
#include "../common/ThreadData.h"
|
||||
#include "../common/UtilSvc.h"
|
||||
@ -40,6 +43,9 @@
|
||||
#include "../common/classes/fb_pair.h"
|
||||
#include "../common/classes/MetaName.h"
|
||||
#include "../../jrd/SimilarToMatcher.h"
|
||||
#include "../common/status.h"
|
||||
#include "../common/sha.h"
|
||||
#include "../common/classes/ImplementHelper.h"
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
@ -49,6 +55,14 @@
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_ZLIB_H)
|
||||
#define WIRE_COMPRESS_SUPPORT 1
|
||||
#endif
|
||||
|
||||
#ifdef WIRE_COMPRESS_SUPPORT
|
||||
#include <zlib.h>
|
||||
//#define COMPRESS_DEBUG 1
|
||||
#endif // WIRE_COMPRESS_SUPPORT
|
||||
|
||||
static inline UCHAR* BURP_alloc(ULONG size)
|
||||
{
|
||||
@ -204,10 +218,6 @@ Version 11: FB4.0.
|
||||
|
||||
const int ATT_BACKUP_FORMAT = 11;
|
||||
|
||||
// format version number for ranges for arrays
|
||||
|
||||
//const int GDS_NDA_VERSION = 1; // Not used
|
||||
|
||||
// max array dimension
|
||||
|
||||
const int MAX_DIMENSION = 16;
|
||||
@ -230,6 +240,10 @@ enum att_type {
|
||||
att_backup_blksize, // backup block size
|
||||
att_backup_file, // database file name
|
||||
att_backup_volume, // backup volume number
|
||||
att_backup_keyname, // name of crypt key
|
||||
att_backup_zip, // zipped backup file
|
||||
att_backup_hash, // hash of crypt key
|
||||
att_backup_crypt, // name of crypt plugin
|
||||
|
||||
// Database attributes
|
||||
|
||||
@ -660,12 +674,14 @@ struct burp_fld
|
||||
SSHORT fld_type;
|
||||
SSHORT fld_sub_type;
|
||||
FLD_LENGTH fld_length;
|
||||
FLD_LENGTH fld_total_len; // including additional 2 bytes for VARYING CHAR
|
||||
SSHORT fld_scale;
|
||||
SSHORT fld_position;
|
||||
SSHORT fld_parameter;
|
||||
SSHORT fld_missing_parameter;
|
||||
SSHORT fld_id;
|
||||
RCRD_OFFSET fld_offset;
|
||||
RCRD_OFFSET fld_missing_offset;
|
||||
RCRD_OFFSET fld_old_offset;
|
||||
SSHORT fld_number;
|
||||
SSHORT fld_system_flag;
|
||||
@ -694,6 +710,8 @@ struct burp_fld
|
||||
ISC_QUAD fld_default_source;
|
||||
SSHORT fld_character_set_id;
|
||||
SSHORT fld_collation_id;
|
||||
RCRD_OFFSET fld_sql;
|
||||
RCRD_OFFSET fld_null;
|
||||
};
|
||||
|
||||
enum fld_flags_vals {
|
||||
@ -913,6 +931,8 @@ public:
|
||||
|
||||
// Global switches and data
|
||||
|
||||
struct BurpCrypt;
|
||||
|
||||
class BurpGlobals : public Firebird::ThreadData
|
||||
{
|
||||
public:
|
||||
@ -928,7 +948,6 @@ public:
|
||||
// this is VERY dirty hack to keep current behaviour
|
||||
memset (&gbl_database_file_name, 0,
|
||||
&veryEnd - reinterpret_cast<char*>(&gbl_database_file_name));
|
||||
memset(status_vector, 0, sizeof(status_vector));
|
||||
|
||||
gbl_stat_flags = 0;
|
||||
gbl_stat_header = false;
|
||||
@ -955,6 +974,7 @@ public:
|
||||
bool gbl_sw_deactivate_indexes;
|
||||
bool gbl_sw_kill;
|
||||
USHORT gbl_sw_blk_factor;
|
||||
USHORT gbl_dialect;
|
||||
const SCHAR* gbl_sw_fix_fss_data;
|
||||
USHORT gbl_sw_fix_fss_data_id;
|
||||
const SCHAR* gbl_sw_fix_fss_metadata;
|
||||
@ -965,6 +985,12 @@ public:
|
||||
bool gbl_sw_mode;
|
||||
bool gbl_sw_mode_val;
|
||||
bool gbl_sw_overwrite;
|
||||
bool gbl_sw_zip;
|
||||
const SCHAR* gbl_sw_keyholder;
|
||||
const SCHAR* gbl_sw_crypt;
|
||||
const SCHAR* gbl_sw_keyname;
|
||||
SCHAR gbl_hdr_keybuffer[MAX_SQL_IDENTIFIER_SIZE + 1];
|
||||
SCHAR gbl_hdr_cryptbuffer[MAX_SQL_IDENTIFIER_SIZE + 1];
|
||||
const SCHAR* gbl_sw_sql_role;
|
||||
const SCHAR* gbl_sw_user;
|
||||
const SCHAR* gbl_sw_password;
|
||||
@ -973,12 +999,44 @@ public:
|
||||
burp_fil* gbl_sw_files;
|
||||
burp_fil* gbl_sw_backup_files;
|
||||
gfld* gbl_global_fields;
|
||||
unsigned gbl_network_protocol;
|
||||
burp_act* action;
|
||||
BurpCrypt* gbl_crypt;
|
||||
ULONG io_buffer_size;
|
||||
redirect_vals sw_redirect;
|
||||
bool burp_throw;
|
||||
UCHAR* io_ptr;
|
||||
int io_cnt;
|
||||
|
||||
UCHAR* blk_io_ptr;
|
||||
int blk_io_cnt;
|
||||
|
||||
void put(const UCHAR c)
|
||||
{
|
||||
if (gbl_io_cnt <= 0)
|
||||
MVOL_write(this);
|
||||
|
||||
--gbl_io_cnt;
|
||||
*gbl_io_ptr++ = c;
|
||||
}
|
||||
|
||||
UCHAR get()
|
||||
{
|
||||
if (gbl_io_cnt <= 0)
|
||||
MVOL_read(this);
|
||||
|
||||
--gbl_io_cnt;
|
||||
return *gbl_io_ptr++;
|
||||
}
|
||||
|
||||
#ifdef WIRE_COMPRESS_SUPPORT
|
||||
z_stream gbl_stream;
|
||||
#endif
|
||||
UCHAR* gbl_io_ptr;
|
||||
int gbl_io_cnt;
|
||||
UCHAR* gbl_compress_buffer;
|
||||
UCHAR* gbl_crypt_buffer;
|
||||
ULONG gbl_crypt_left;
|
||||
UCHAR* gbl_decompress;
|
||||
|
||||
burp_rel* relations;
|
||||
burp_pkg* packages;
|
||||
burp_prc* procedures;
|
||||
@ -1001,11 +1059,15 @@ public:
|
||||
SCHAR mvol_old_file [MAX_FILE_NAME_SIZE];
|
||||
int mvol_volume_count;
|
||||
bool mvol_empty_file;
|
||||
isc_db_handle db_handle;
|
||||
isc_tr_handle tr_handle;
|
||||
isc_tr_handle global_trans;
|
||||
TEXT mvol_keyname_buffer[MAX_FILE_NAME_SIZE];
|
||||
const TEXT* mvol_keyname;
|
||||
TEXT mvol_crypt_buffer[MAX_FILE_NAME_SIZE];
|
||||
const TEXT* mvol_crypt;
|
||||
TEXT gbl_key_hash[(Firebird::Sha1::HASH_SIZE + 1) * 4 / 3 + 1]; // take into an account base64
|
||||
Firebird::IAttachment* db_handle;
|
||||
Firebird::ITransaction* tr_handle;
|
||||
Firebird::ITransaction* global_trans;
|
||||
DESC file_desc;
|
||||
ISC_STATUS_ARRAY status_vector;
|
||||
int exit_code;
|
||||
UCHAR* head_of_mem_list;
|
||||
FILE* output_file;
|
||||
@ -1015,59 +1077,61 @@ public:
|
||||
// burp_fld* v3_cvt_fld_list;
|
||||
|
||||
// The handles_get... are for restore.
|
||||
isc_req_handle handles_get_character_sets_req_handle1;
|
||||
isc_req_handle handles_get_chk_constraint_req_handle1;
|
||||
isc_req_handle handles_get_collation_req_handle1;
|
||||
isc_req_handle handles_get_exception_req_handle1;
|
||||
isc_req_handle handles_get_field_dimensions_req_handle1;
|
||||
isc_req_handle handles_get_field_req_handle1;
|
||||
isc_req_handle handles_get_fields_req_handle1;
|
||||
isc_req_handle handles_get_fields_req_handle2;
|
||||
isc_req_handle handles_get_fields_req_handle3;
|
||||
isc_req_handle handles_get_fields_req_handle4;
|
||||
isc_req_handle handles_get_fields_req_handle5;
|
||||
isc_req_handle handles_get_fields_req_handle6;
|
||||
isc_req_handle handles_get_files_req_handle1;
|
||||
isc_req_handle handles_get_filter_req_handle1;
|
||||
isc_req_handle handles_get_function_arg_req_handle1;
|
||||
isc_req_handle handles_get_function_req_handle1;
|
||||
isc_req_handle handles_get_global_field_req_handle1;
|
||||
isc_req_handle handles_get_index_req_handle1;
|
||||
isc_req_handle handles_get_index_req_handle2;
|
||||
isc_req_handle handles_get_index_req_handle3;
|
||||
isc_req_handle handles_get_index_req_handle4;
|
||||
isc_req_handle handles_get_package_req_handle1;
|
||||
isc_req_handle handles_get_procedure_prm_req_handle1;
|
||||
isc_req_handle handles_get_procedure_req_handle1;
|
||||
isc_req_handle handles_get_ranges_req_handle1;
|
||||
isc_req_handle handles_get_ref_constraint_req_handle1;
|
||||
isc_req_handle handles_get_rel_constraint_req_handle1;
|
||||
isc_req_handle handles_get_relation_req_handle1;
|
||||
isc_req_handle handles_get_security_class_req_handle1;
|
||||
isc_req_handle handles_get_sql_roles_req_handle1;
|
||||
isc_req_handle handles_get_mapping_req_handle1;
|
||||
isc_req_handle handles_get_trigger_message_req_handle1;
|
||||
isc_req_handle handles_get_trigger_message_req_handle2;
|
||||
isc_req_handle handles_get_trigger_old_req_handle1;
|
||||
isc_req_handle handles_get_trigger_req_handle1;
|
||||
isc_req_handle handles_get_type_req_handle1;
|
||||
isc_req_handle handles_get_user_privilege_req_handle1;
|
||||
isc_req_handle handles_get_view_req_handle1;
|
||||
Firebird::IRequest* handles_get_character_sets_req_handle1;
|
||||
Firebird::IRequest* handles_get_chk_constraint_req_handle1;
|
||||
Firebird::IRequest* handles_get_collation_req_handle1;
|
||||
Firebird::IRequest* handles_get_exception_req_handle1;
|
||||
Firebird::IRequest* handles_get_field_dimensions_req_handle1;
|
||||
Firebird::IRequest* handles_get_field_req_handle1;
|
||||
Firebird::IRequest* handles_get_fields_req_handle1;
|
||||
Firebird::IRequest* handles_get_fields_req_handle2;
|
||||
Firebird::IRequest* handles_get_fields_req_handle3;
|
||||
Firebird::IRequest* handles_get_fields_req_handle4;
|
||||
Firebird::IRequest* handles_get_fields_req_handle5;
|
||||
Firebird::IRequest* handles_get_fields_req_handle6;
|
||||
Firebird::IRequest* handles_get_files_req_handle1;
|
||||
Firebird::IRequest* handles_get_filter_req_handle1;
|
||||
Firebird::IRequest* handles_get_function_arg_req_handle1;
|
||||
Firebird::IRequest* handles_get_function_req_handle1;
|
||||
Firebird::IRequest* handles_get_global_field_req_handle1;
|
||||
Firebird::IRequest* handles_get_index_req_handle1;
|
||||
Firebird::IRequest* handles_get_index_req_handle2;
|
||||
Firebird::IRequest* handles_get_index_req_handle3;
|
||||
Firebird::IRequest* handles_get_index_req_handle4;
|
||||
Firebird::IRequest* handles_get_package_req_handle1;
|
||||
Firebird::IRequest* handles_get_procedure_prm_req_handle1;
|
||||
Firebird::IRequest* handles_get_procedure_req_handle1;
|
||||
Firebird::IRequest* handles_get_ranges_req_handle1;
|
||||
Firebird::IRequest* handles_get_ref_constraint_req_handle1;
|
||||
Firebird::IRequest* handles_get_rel_constraint_req_handle1;
|
||||
Firebird::IRequest* handles_get_relation_req_handle1;
|
||||
Firebird::IRequest* handles_get_security_class_req_handle1;
|
||||
Firebird::IRequest* handles_get_sql_roles_req_handle1;
|
||||
Firebird::IRequest* handles_get_mapping_req_handle1;
|
||||
Firebird::IRequest* handles_get_trigger_message_req_handle1;
|
||||
Firebird::IRequest* handles_get_trigger_message_req_handle2;
|
||||
Firebird::IRequest* handles_get_trigger_old_req_handle1;
|
||||
Firebird::IRequest* handles_get_trigger_req_handle1;
|
||||
Firebird::IRequest* handles_get_type_req_handle1;
|
||||
Firebird::IRequest* handles_get_user_privilege_req_handle1;
|
||||
Firebird::IRequest* handles_get_view_req_handle1;
|
||||
|
||||
// The handles_put.. are for backup.
|
||||
isc_req_handle handles_put_index_req_handle1;
|
||||
isc_req_handle handles_put_index_req_handle2;
|
||||
isc_req_handle handles_put_index_req_handle3;
|
||||
isc_req_handle handles_put_index_req_handle4;
|
||||
isc_req_handle handles_put_index_req_handle5;
|
||||
isc_req_handle handles_put_index_req_handle6;
|
||||
isc_req_handle handles_put_index_req_handle7;
|
||||
isc_req_handle handles_put_relation_req_handle1;
|
||||
isc_req_handle handles_put_relation_req_handle2;
|
||||
isc_req_handle handles_store_blr_gen_id_req_handle1;
|
||||
isc_req_handle handles_write_function_args_req_handle1;
|
||||
isc_req_handle handles_write_function_args_req_handle2;
|
||||
isc_req_handle handles_write_procedure_prms_req_handle1;
|
||||
isc_req_handle handles_fix_security_class_name_req_handle1;
|
||||
Firebird::IRequest* handles_put_index_req_handle1;
|
||||
Firebird::IRequest* handles_put_index_req_handle2;
|
||||
Firebird::IRequest* handles_put_index_req_handle3;
|
||||
Firebird::IRequest* handles_put_index_req_handle4;
|
||||
Firebird::IRequest* handles_put_index_req_handle5;
|
||||
Firebird::IRequest* handles_put_index_req_handle6;
|
||||
Firebird::IRequest* handles_put_index_req_handle7;
|
||||
Firebird::IRequest* handles_put_relation_req_handle1;
|
||||
Firebird::IRequest* handles_put_relation_req_handle2;
|
||||
Firebird::IRequest* handles_store_blr_gen_id_req_handle1;
|
||||
Firebird::IRequest* handles_write_function_args_req_handle1;
|
||||
Firebird::IRequest* handles_write_function_args_req_handle2;
|
||||
Firebird::IRequest* handles_write_procedure_prms_req_handle1;
|
||||
Firebird::IRequest* handles_fix_security_class_name_req_handle1;
|
||||
|
||||
bool hdr_forced_writes;
|
||||
TEXT database_security_class[GDS_NAME_LEN]; // To save database security class for deferred update
|
||||
|
||||
@ -1089,6 +1153,9 @@ public:
|
||||
char veryEnd;
|
||||
//starting after this members must be initialized in constructor explicitly
|
||||
|
||||
Firebird::FbLocalStatus status_vector;
|
||||
Firebird::ThrowLocalStatus throwStatus;
|
||||
|
||||
Firebird::Array<Firebird::Pair<Firebird::NonPooled<Firebird::MetaName, Firebird::MetaName> > >
|
||||
defaultCollations;
|
||||
Firebird::UtilSvc* uSvc;
|
||||
@ -1162,4 +1229,49 @@ enum burp_messages_vals {
|
||||
// BLOB buffer
|
||||
typedef Firebird::HalfStaticArray<UCHAR, 1024> BlobBuffer;
|
||||
|
||||
class BurpSql : public Firebird::AutoStorage
|
||||
{
|
||||
public:
|
||||
BurpSql(BurpGlobals* g, const char* sql)
|
||||
: Firebird::AutoStorage(),
|
||||
tdgbl(g), stmt(nullptr)
|
||||
{
|
||||
stmt = tdgbl->db_handle->prepare(&tdgbl->throwStatus, tdgbl->tr_handle, 0, sql, 3, 0);
|
||||
}
|
||||
|
||||
template <typename M>
|
||||
void singleSelect(Firebird::ITransaction* trans, M* msg)
|
||||
{
|
||||
stmt->execute(&tdgbl->throwStatus, tdgbl->tr_handle, nullptr, nullptr, msg->getMetadata(), msg->getData());
|
||||
}
|
||||
|
||||
template <typename M>
|
||||
void execute(Firebird::ITransaction* trans, M* msg)
|
||||
{
|
||||
stmt->execute(&tdgbl->throwStatus, tdgbl->tr_handle, msg->getMetadata(), msg->getData(), nullptr, nullptr);
|
||||
}
|
||||
|
||||
void execute(Firebird::ITransaction* trans)
|
||||
{
|
||||
stmt->execute(&tdgbl->throwStatus, tdgbl->tr_handle, nullptr, nullptr, nullptr, nullptr);
|
||||
}
|
||||
|
||||
private:
|
||||
BurpGlobals* tdgbl;
|
||||
Firebird::IStatement* stmt;
|
||||
};
|
||||
|
||||
class OutputVersion : public Firebird::IVersionCallbackImpl<OutputVersion, Firebird::CheckStatusWrapper>
|
||||
{
|
||||
public:
|
||||
OutputVersion(const char* printFormat)
|
||||
: format(printFormat)
|
||||
{ }
|
||||
|
||||
void callback(Firebird::CheckStatusWrapper* status, const char* text);
|
||||
|
||||
private:
|
||||
const char* format;
|
||||
};
|
||||
|
||||
#endif // BURP_BURP_H
|
||||
|
@ -26,15 +26,19 @@
|
||||
|
||||
#include "../common/ThreadData.h"
|
||||
#include "../common/classes/MsgPrint.h"
|
||||
#include "../common/classes/fb_string.h"
|
||||
#include "../common/UtilSvc.h"
|
||||
|
||||
class BurpGlobals;
|
||||
|
||||
int BURP_main(Firebird::UtilSvc*);
|
||||
int gbak(Firebird::UtilSvc*);
|
||||
|
||||
void BURP_abort();
|
||||
void BURP_error(USHORT, bool, const MsgFormat::SafeArg& arg = MsgFormat::SafeArg());
|
||||
void BURP_error(USHORT, bool, const char* str);
|
||||
void BURP_error_redirect(const ISC_STATUS*, USHORT, const MsgFormat::SafeArg& arg = MsgFormat::SafeArg());
|
||||
void BURP_error_redirect(Firebird::IStatus*, USHORT, const MsgFormat::SafeArg& arg = MsgFormat::SafeArg());
|
||||
void BURP_makeSymbol(BurpGlobals*, Firebird::string&);
|
||||
void BURP_msg_partial(bool, USHORT, const MsgFormat::SafeArg& arg = MsgFormat::SafeArg());
|
||||
void BURP_msg_put(bool, USHORT, const MsgFormat::SafeArg& arg);
|
||||
const int BURP_MSG_GET_SIZE = 128; // Use it for buffers passed to this function.
|
||||
@ -42,8 +46,8 @@ void BURP_msg_get(USHORT, TEXT*, const MsgFormat::SafeArg& arg = MsgFormat::Safe
|
||||
void BURP_output_version(void*, const TEXT*);
|
||||
void BURP_print(bool err, USHORT, const MsgFormat::SafeArg& arg = MsgFormat::SafeArg());
|
||||
void BURP_print(bool err, USHORT, const char* str);
|
||||
void BURP_print_status(bool err, const ISC_STATUS* status);
|
||||
void BURP_print_warning(const ISC_STATUS*);
|
||||
void BURP_print_status(bool err, Firebird::IStatus* status);
|
||||
void BURP_print_warning(Firebird::IStatus* status);
|
||||
void BURP_verbose(USHORT, const MsgFormat::SafeArg& arg = MsgFormat::SafeArg());
|
||||
void BURP_verbose(USHORT, const char* str);
|
||||
|
||||
|
@ -91,8 +91,12 @@ const int IN_SW_BURP_FETCHPASS = 45; // fetch default password from file to us
|
||||
const int IN_SW_BURP_VERBINT = 46; // verbose but with specific interval
|
||||
const int IN_SW_BURP_STATS = 47; // print statistics
|
||||
|
||||
const int IN_SW_BURP_ZIP = 48; // backup file in .zip format
|
||||
const int IN_SW_BURP_KEYHOLD = 49; // name of KeyHolder plugin
|
||||
const int IN_SW_BURP_KEYNAME = 50; // name of crypt key
|
||||
const int IN_SW_BURP_CRYPT = 51; // name of crypt plugin
|
||||
|
||||
/**************************************************************************/
|
||||
// used 0BCDEFGILMNOPRSTUVYZ available AHJQWX
|
||||
|
||||
static const char* const BURP_SW_MODE_RO = "READ_ONLY";
|
||||
static const char* const BURP_SW_MODE_RW = "READ_WRITE";
|
||||
@ -111,6 +115,8 @@ static const Switches::in_sw_tab_t reference_burp_in_sw_table[] =
|
||||
// msg 73: @1CREATE_DATABASE create database from backup file
|
||||
{IN_SW_BURP_CO, isc_spb_bkp_convert, "CONVERT", 0, 0, 0, false, true, 254, 2, NULL, boBackup},
|
||||
// msg 254: @1CO(NVERT) backup external files as tables
|
||||
{IN_SW_BURP_CRYPT, isc_spb_bkp_crypt, "CRYPT", 0, 0, 0, false, false, 373, 3, NULL, boGeneral},
|
||||
// msg 373:@1CRY(PT) plugin name
|
||||
{IN_SW_BURP_E, isc_spb_bkp_expand, "EXPAND", 0, 0, 0, false, true, 97, 1, NULL, boBackup},
|
||||
// msg 97: @1EXPAND no data compression
|
||||
{IN_SW_BURP_FA, isc_spb_bkp_factor, "FACTOR", 0, 0, 0, false, false, 181, 2, NULL, boBackup},
|
||||
@ -125,10 +131,14 @@ static const Switches::in_sw_tab_t reference_burp_in_sw_table[] =
|
||||
// msg 303: @1FIX_FSS_METADATA fix malformed UNICODE_FSS metadata
|
||||
{IN_SW_BURP_G, isc_spb_bkp_no_garbage_collect, "GARBAGE_COLLECT", 0, 0, 0, false, true, 177, 1, NULL, boBackup},
|
||||
// msg 177:@1GARBAGE_COLLECT inhibit garbage collection
|
||||
{IN_SW_BURP_I, isc_spb_res_deactivate_idx, "INACTIVE", 0, 0, 0, false, true, 78, 1, NULL, boRestore},
|
||||
{IN_SW_BURP_I, isc_spb_res_deactivate_idx, "INACTIVE", 0, 0, 0, false, true, 78, 1, NULL, boRestore},
|
||||
// msg 78:@1INACTIVE deactivate indexes during restore
|
||||
{IN_SW_BURP_IG, isc_spb_bkp_ignore_checksums, "IGNORE", 0, 0, 0, false, true, 178, 2, NULL, boBackup},
|
||||
{IN_SW_BURP_IG, isc_spb_bkp_ignore_checksums, "IGNORE", 0, 0, 0, false, true, 178, 2, NULL, boBackup},
|
||||
// msg 178:@1IGNORE ignore bad checksums
|
||||
{IN_SW_BURP_KEYHOLD, isc_spb_bkp_keyholder, "KEYHOLDER", 0, 0, 0, false, false, 382, 4, NULL, boGeneral},
|
||||
// msg 382:@1KEYHOLDER name of a key holder plugin
|
||||
{IN_SW_BURP_KEYNAME, isc_spb_bkp_keyname, "KEYNAME", 0, 0, 0, false, false, 372, 4, NULL, boGeneral},
|
||||
// msg 372:@1KEYNAME name of a key to be used for encryption
|
||||
{IN_SW_BURP_K, isc_spb_res_no_shadow, "KILL", 0, 0, 0, false, true, 172, 1, NULL, boRestore},
|
||||
// msg 172:@1KILL restore without creating shadows
|
||||
{IN_SW_BURP_L, isc_spb_bkp_ignore_limbo, "LIMBO", 0, 0, 0, false, true, 98, 1, NULL, boBackup},
|
||||
@ -167,13 +177,13 @@ static const Switches::in_sw_tab_t reference_burp_in_sw_table[] =
|
||||
// msg 355: @1SKIP_DATA skip data for table
|
||||
{IN_SW_BURP_STATS, isc_spb_bkp_stat, "STATISTICS", 0, 0, 0, false, false, 361, 2, NULL, boGeneral},
|
||||
// msg 361: @1ST(ATISTICS) TDRW show statistics:
|
||||
{-1, 0, " ", 0, 0, 0, false, false, 362, 0, NULL, boGeneral},
|
||||
{-1, 0, " ", 0, 0, 0, false, false, 362, 0, NULL, boGeneral},
|
||||
// msg 362: T time from start
|
||||
{-1, 0, " ", 0, 0, 0, false, false, 363, 0, NULL, boGeneral},
|
||||
{-1, 0, " ", 0, 0, 0, false, false, 363, 0, NULL, boGeneral},
|
||||
// msg 363: D delta time
|
||||
{-1, 0, " ", 0, 0, 0, false, false, 364, 0, NULL, boGeneral},
|
||||
{-1, 0, " ", 0, 0, 0, false, false, 364, 0, NULL, boGeneral},
|
||||
// msg 364: R page reads
|
||||
{-1, 0, " ", 0, 0, 0, false, false, 365, 0, NULL, boGeneral},
|
||||
{-1, 0, " ", 0, 0, 0, false, false, 365, 0, NULL, boGeneral},
|
||||
// msg 365: W page writes
|
||||
{IN_SW_BURP_T, 0, "TRANSPORTABLE", 0, 0, 0, false, false, 175, 1, NULL, boBackup},
|
||||
// msg 175: @1TRANSPORTABLE transportable backup -- data in XDR format
|
||||
@ -197,6 +207,8 @@ static const Switches::in_sw_tab_t reference_burp_in_sw_table[] =
|
||||
// msg 109: @1Y redirect/suppress output (file path or OUTPUT_SUPPRESS)
|
||||
{IN_SW_BURP_Z, 0, "Z", 0, 0, 0, false, false, 104, 1, NULL, boGeneral},
|
||||
// msg 104: @1Z print version number
|
||||
{IN_SW_BURP_ZIP, isc_spb_bkp_zip, "ZIP", 0, 0, 0, false, true, 374, 3, NULL, boBackup},
|
||||
// msg 104: @1ZIP backup file is in zip compressed format
|
||||
/**************************************************************************/
|
||||
// The next two 'virtual' switches are hidden from user and are needed
|
||||
// for services API
|
||||
|
@ -24,8 +24,8 @@
|
||||
#ifndef BURP_CANON_PROTO_H
|
||||
#define BURP_CANON_PROTO_H
|
||||
|
||||
ULONG CAN_encode_decode (burp_rel*, lstring*, UCHAR*, int);
|
||||
ULONG CAN_slice (lstring*, lstring*, int, /*USHORT,*/ UCHAR*);
|
||||
ULONG CAN_encode_decode (burp_rel* relation, lstring* buffer, UCHAR* data, bool direction, bool useMissingOffset = false);
|
||||
ULONG CAN_slice (lstring* buffer, lstring* slice, bool direction, UCHAR* sdl);
|
||||
|
||||
#endif // BURP_CANON_PROTO_H
|
||||
|
||||
|
@ -42,11 +42,11 @@
|
||||
#include "../common/xdr_proto.h"
|
||||
#include "../common/gdsassert.h"
|
||||
#include "../common/StatusHolder.h"
|
||||
#include "../common/status.h"
|
||||
#include "fb_types.h"
|
||||
|
||||
// TMN: Currently we can't include remote/remote.h because we'd get
|
||||
// conflicting blk_t definitions (we are gonna fix this, in due time).
|
||||
|
||||
using Firebird::FbLocalStatus;
|
||||
|
||||
static bool_t burp_getbytes(XDR*, SCHAR *, u_int);
|
||||
static bool_t burp_putbytes(XDR*, const SCHAR*, u_int);
|
||||
@ -63,7 +63,7 @@ static xdr_t::xdr_ops burp_ops =
|
||||
const int increment = 1024;
|
||||
|
||||
|
||||
ULONG CAN_encode_decode(burp_rel* relation, lstring* buffer, UCHAR* data, bool_t direction)
|
||||
ULONG CAN_encode_decode(burp_rel* relation, lstring* buffer, UCHAR* data, bool direction, bool useMissingOffset)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
@ -203,17 +203,21 @@ ULONG CAN_encode_decode(burp_rel* relation, lstring* buffer, UCHAR* data, bool_t
|
||||
{
|
||||
if (field->fld_flags & FLD_computed)
|
||||
continue;
|
||||
offset = FB_ALIGN(offset, sizeof(SSHORT));
|
||||
UCHAR* p = data + offset;
|
||||
UCHAR* p = data + field->fld_missing_offset;
|
||||
if (!useMissingOffset)
|
||||
{
|
||||
offset = FB_ALIGN(offset, sizeof(SSHORT));
|
||||
p = data + offset;
|
||||
offset += sizeof(SSHORT);
|
||||
}
|
||||
if (!xdr_short(xdrs, (SSHORT*) p))
|
||||
return FALSE;
|
||||
offset += sizeof(SSHORT);
|
||||
}
|
||||
return (xdrs->x_private - xdrs->x_base);
|
||||
}
|
||||
|
||||
|
||||
ULONG CAN_slice(lstring* buffer, lstring* slice, bool_t direction, /*USHORT sdl_length,*/ UCHAR* sdl)
|
||||
ULONG CAN_slice(lstring* buffer, lstring* slice, bool direction, UCHAR* sdl)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
@ -422,8 +426,7 @@ static bool_t xdr_slice(XDR* xdrs, lstring* slice, /*USHORT sdl_length,*/ const
|
||||
|
||||
sdl_info info;
|
||||
{
|
||||
Firebird::LocalStatus ls;
|
||||
Firebird::CheckStatusWrapper s(&ls);
|
||||
FbLocalStatus s;
|
||||
if (SDL_info(&s, sdl, &info, 0))
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -119,12 +119,12 @@ void MISC_free_burp( void *free)
|
||||
// in a function visible to all gbak components.
|
||||
// Given a request, if it's non-zero (compiled), deallocate it but
|
||||
// without caring about a possible error.
|
||||
void MISC_release_request_silent(isc_req_handle& req_handle)
|
||||
void MISC_release_request_silent(Firebird::IRequest*& req_handle)
|
||||
{
|
||||
if (req_handle)
|
||||
{
|
||||
ISC_STATUS_ARRAY req_status;
|
||||
isc_release_request(req_status, &req_handle);
|
||||
req_handle->release();
|
||||
req_handle = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,7 @@
|
||||
|
||||
UCHAR* MISC_alloc_burp(ULONG);
|
||||
void MISC_free_burp(void*);
|
||||
void MISC_release_request_silent(isc_req_handle& req_handle);
|
||||
void MISC_release_request_silent(Firebird::IRequest*& req_handle);
|
||||
int MISC_symbol_length(const TEXT*, ULONG);
|
||||
void MISC_terminate(const TEXT*, TEXT*, ULONG, ULONG);
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -24,24 +24,27 @@
|
||||
#ifndef BURP_MVOL_PROTO_H
|
||||
#define BURP_MVOL_PROTO_H
|
||||
|
||||
#include "../burp/burp.h"
|
||||
#include "firebird/Interface.h"
|
||||
#include "std_desc.h"
|
||||
|
||||
class BurpGlobals;
|
||||
|
||||
FB_UINT64 MVOL_fini_read();
|
||||
FB_UINT64 MVOL_fini_write(int*, UCHAR**);
|
||||
FB_UINT64 MVOL_fini_write();
|
||||
void MVOL_init(ULONG);
|
||||
void MVOL_init_read(const char*, USHORT*, int*, UCHAR**);
|
||||
void MVOL_init_write(const char*, int*, UCHAR**);
|
||||
void MVOL_init_read(const char*, USHORT*);
|
||||
void MVOL_init_write(const char*);
|
||||
bool MVOL_split_hdr_write();
|
||||
bool MVOL_split_hdr_read();
|
||||
int MVOL_read(int*, UCHAR**);
|
||||
void MVOL_read(BurpGlobals*);
|
||||
UCHAR* MVOL_read_block(BurpGlobals*, UCHAR*, ULONG);
|
||||
void MVOL_skip_block(BurpGlobals*, ULONG);
|
||||
UCHAR MVOL_write(const UCHAR, int*, UCHAR**);
|
||||
void MVOL_write(BurpGlobals*);
|
||||
const UCHAR* MVOL_write_block(BurpGlobals*, const UCHAR*, ULONG);
|
||||
Firebird::ICryptKeyCallback* MVOL_get_crypt(BurpGlobals*);
|
||||
|
||||
#if defined WIN_NT
|
||||
DESC MVOL_open(const char*, ULONG, ULONG);
|
||||
DESC NT_tape_open(const char*, ULONG, ULONG);
|
||||
#endif
|
||||
|
||||
|
||||
|
1403
src/burp/restore.epp
1403
src/burp/restore.epp
File diff suppressed because it is too large
Load Diff
@ -33,21 +33,23 @@
|
||||
#include "CsConvert.h"
|
||||
#include "IntlUtil.h"
|
||||
|
||||
namespace Firebird {
|
||||
|
||||
template <>
|
||||
inline void SimpleDelete<charset>::clear(charset* cs)
|
||||
{
|
||||
Firebird::IntlUtil::finiCharset(cs);
|
||||
delete cs;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
namespace Jrd {
|
||||
|
||||
class CharSet
|
||||
{
|
||||
public:
|
||||
class Delete
|
||||
{
|
||||
public:
|
||||
static void clear(charset* cs)
|
||||
{
|
||||
Firebird::IntlUtil::finiCharset(cs);
|
||||
delete cs;
|
||||
}
|
||||
};
|
||||
|
||||
static CharSet* createInstance(Firebird::MemoryPool& pool, USHORT id, charset* cs);
|
||||
|
||||
protected:
|
||||
|
@ -45,6 +45,9 @@ extern "C"
|
||||
|
||||
using namespace Firebird;
|
||||
|
||||
const DecimalStatus DecimalStatus::DEFAULT(FB_DEC_Errors);
|
||||
const DecimalBinding DecimalBinding::DEFAULT;
|
||||
|
||||
namespace {
|
||||
|
||||
struct Dec2fb
|
||||
@ -359,7 +362,9 @@ Decimal64 Decimal64::floor(DecimalStatus decSt) const
|
||||
|
||||
int Decimal64::compare(DecimalStatus decSt, Decimal64 tgt) const
|
||||
{
|
||||
DecimalContext context(this, decSt);
|
||||
DecimalStatus cmpStatus(decSt);
|
||||
cmpStatus.decExtFlag &= ~DEC_IEEE_754_Invalid_operation;
|
||||
DecimalContext context(this, cmpStatus);
|
||||
decDouble r;
|
||||
decDoubleCompare(&r, &dec, &tgt.dec, &context);
|
||||
return decDoubleToInt32(&r, &context, DEC_ROUND_HALF_UP);
|
||||
|
@ -55,6 +55,8 @@ struct DecimalStatus
|
||||
: decExtFlag(exc), roundingMode(DEC_ROUND_HALF_UP)
|
||||
{ }
|
||||
|
||||
static const DecimalStatus DEFAULT;
|
||||
|
||||
USHORT decExtFlag, roundingMode;
|
||||
};
|
||||
|
||||
@ -64,12 +66,15 @@ struct DecimalBinding
|
||||
: bind(DEC_NATIVE), numScale(0)
|
||||
{ }
|
||||
|
||||
static const DecimalBinding DEFAULT;
|
||||
|
||||
enum Bind { DEC_NATIVE, DEC_TEXT, DEC_DOUBLE, DEC_NUMERIC };
|
||||
|
||||
Bind bind;
|
||||
SCHAR numScale;
|
||||
};
|
||||
|
||||
|
||||
class DecimalFixed;
|
||||
|
||||
class Decimal64
|
||||
@ -132,6 +137,8 @@ public:
|
||||
UCHAR* getBytes();
|
||||
int compare(DecimalStatus decSt, Decimal128Base tgt) const;
|
||||
|
||||
void setScale(DecimalStatus decSt, int scale);
|
||||
|
||||
bool isInf() const;
|
||||
bool isNan() const;
|
||||
int sign() const;
|
||||
@ -146,8 +153,6 @@ public:
|
||||
#endif
|
||||
|
||||
private:
|
||||
void setScale(DecimalStatus decSt, int scale);
|
||||
|
||||
decQuad dec;
|
||||
};
|
||||
|
||||
|
@ -98,7 +98,7 @@ THREAD_ENTRY_DECLARE threadStart(THREAD_ENTRY_PARAM arg)
|
||||
|
||||
#ifdef USE_POSIX_THREADS
|
||||
#define START_THREAD
|
||||
void Thread::start(ThreadEntryPoint* routine, void* arg, int priority_arg, Handle* p_handle)
|
||||
ThreadId Thread::start(ThreadEntryPoint* routine, void* arg, int priority_arg, Handle* p_handle)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
@ -180,6 +180,8 @@ void Thread::start(ThreadEntryPoint* routine, void* arg, int priority_arg, Handl
|
||||
#endif
|
||||
*p_handle = thread;
|
||||
}
|
||||
|
||||
return getId();
|
||||
}
|
||||
|
||||
void Thread::waitForCompletion(Handle& thread)
|
||||
@ -208,6 +210,11 @@ ThreadId Thread::getId()
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Thread::isCurrent(const ThreadId threadId)
|
||||
{
|
||||
return getId() == threadId;
|
||||
}
|
||||
|
||||
void Thread::sleep(unsigned milliseconds)
|
||||
{
|
||||
#if defined(HAVE_NANOSLEEP)
|
||||
@ -252,7 +259,7 @@ void Thread::yield()
|
||||
|
||||
#ifdef WIN_NT
|
||||
#define START_THREAD
|
||||
void Thread::start(ThreadEntryPoint* routine, void* arg, int priority_arg, Handle* p_handle)
|
||||
ThreadId Thread::start(ThreadEntryPoint* routine, void* arg, int priority_arg, Handle* p_handle)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
@ -316,6 +323,8 @@ void Thread::start(ThreadEntryPoint* routine, void* arg, int priority_arg, Handl
|
||||
{
|
||||
CloseHandle(handle);
|
||||
}
|
||||
|
||||
return thread_id;
|
||||
}
|
||||
|
||||
void Thread::waitForCompletion(Handle& handle)
|
||||
@ -342,6 +351,11 @@ ThreadId Thread::getId()
|
||||
return GetCurrentThreadId();
|
||||
}
|
||||
|
||||
bool Thread::isCurrent(const ThreadId threadId)
|
||||
{
|
||||
return GetCurrentThreadId() == threadId;
|
||||
}
|
||||
|
||||
void Thread::sleep(unsigned milliseconds)
|
||||
{
|
||||
SleepEx(milliseconds, FALSE);
|
||||
@ -356,7 +370,7 @@ void Thread::yield()
|
||||
|
||||
|
||||
#ifndef START_THREAD
|
||||
void Thread::start(ThreadEntryPoint* routine, void* arg, int priority_arg, Handle* p_handle)
|
||||
ThreadId Thread::start(ThreadEntryPoint* routine, void* arg, int priority_arg, Handle* p_handle)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
@ -368,7 +382,8 @@ void Thread::start(ThreadEntryPoint* routine, void* arg, int priority_arg, Handl
|
||||
* Wrong attempt to start a new thread.
|
||||
*
|
||||
**************************************/
|
||||
|
||||
fb_assert(false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Thread::waitForCompletion(Handle&)
|
||||
|
@ -75,9 +75,10 @@ public:
|
||||
typedef pthread_t Handle;
|
||||
#endif
|
||||
|
||||
static void start(ThreadEntryPoint* routine, void* arg, int priority_arg, Handle* p_handle = NULL);
|
||||
static ThreadId start(ThreadEntryPoint* routine, void* arg, int priority_arg, Handle* p_handle = NULL);
|
||||
static void waitForCompletion(Handle& handle);
|
||||
static void kill(Handle& handle);
|
||||
static bool isCurrent(const ThreadId threadId);
|
||||
|
||||
static ThreadId getId();
|
||||
|
||||
|
@ -145,6 +145,7 @@ public:
|
||||
virtual bool finished() { return false; }
|
||||
virtual void initStatus() { }
|
||||
virtual bool utf8FileNames() { return false; }
|
||||
virtual Firebird::ICryptKeyCallback* getCryptCallback() { return NULL; }
|
||||
};
|
||||
|
||||
|
||||
|
@ -30,6 +30,8 @@
|
||||
#ifndef FB_UTILFACE
|
||||
#define FB_UTILFACE
|
||||
|
||||
#include "firebird/Interface.h"
|
||||
|
||||
#include "../common/classes/alloc.h"
|
||||
#include "../common/classes/array.h"
|
||||
#include "../common/classes/fb_string.h"
|
||||
@ -74,6 +76,7 @@ public:
|
||||
virtual bool finished() = 0;
|
||||
virtual unsigned int getAuthBlock(const unsigned char** bytes) = 0;
|
||||
virtual bool utf8FileNames() = 0;
|
||||
virtual Firebird::ICryptKeyCallback* getCryptCallback() = 0;
|
||||
|
||||
void setDataMode(bool value)
|
||||
{
|
||||
|
271
src/common/classes/BlobWrapper.cpp
Normal file
271
src/common/classes/BlobWrapper.cpp
Normal file
@ -0,0 +1,271 @@
|
||||
/*
|
||||
* 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 Claudio Valderrama on 16-Mar-2007
|
||||
* for the Firebird Open Source RDBMS project.
|
||||
*
|
||||
* Copyright (c) 2007 Claudio Valderrama
|
||||
* and all contributors signed below.
|
||||
*
|
||||
* All Rights Reserved.
|
||||
* Contributor(s): ______________________________________.
|
||||
* Alex Peshkoff, 2017
|
||||
*
|
||||
*/
|
||||
|
||||
#include "firebird.h"
|
||||
#include "BlobWrapper.h"
|
||||
#include "../jrd/ibase.h"
|
||||
#include "firebird/Interface.h"
|
||||
|
||||
static const USHORT SEGMENT_LIMIT = 65535;
|
||||
|
||||
using namespace Firebird;
|
||||
|
||||
bool BlobWrapper::open(IAttachment* db, ITransaction* trans, ISC_QUAD& blobid,
|
||||
USHORT bpb_len, const UCHAR* bpb)
|
||||
{
|
||||
if (m_direction != dir_none)
|
||||
return false;
|
||||
|
||||
if (bpb_len > 0 && !bpb || blobIsNull(blobid))
|
||||
return false;
|
||||
|
||||
m_blob = db->openBlob(m_status, trans, &blobid, bpb_len, bpb);
|
||||
if (m_status->isEmpty())
|
||||
{
|
||||
m_direction = dir_read;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool BlobWrapper::create(IAttachment* db, ITransaction* trans, ISC_QUAD& blobid,
|
||||
USHORT bpb_len, const UCHAR* bpb)
|
||||
{
|
||||
if (m_direction != dir_none)
|
||||
return false;
|
||||
|
||||
if (bpb_len > 0 && !bpb)
|
||||
return false;
|
||||
|
||||
blobid.gds_quad_high = blobid.gds_quad_low = 0;
|
||||
m_blob = db->createBlob(m_status, trans, &blobid, bpb_len, bpb);
|
||||
if (m_status->isEmpty())
|
||||
{
|
||||
m_direction = dir_write;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool BlobWrapper::close(bool force_internal_SV)
|
||||
{
|
||||
bool rc = false;
|
||||
if (m_blob)
|
||||
{
|
||||
m_blob->close(force_internal_SV ? &m_default_status : m_status);
|
||||
rc = (force_internal_SV ? &m_default_status : m_status)->isEmpty();
|
||||
if (rc)
|
||||
m_blob = nullptr;
|
||||
m_direction = dir_none;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
bool BlobWrapper::getSegment(FB_SIZE_T len, void* buffer, FB_SIZE_T& real_len)
|
||||
{
|
||||
real_len = 0;
|
||||
|
||||
if (!m_blob || m_direction != dir_read)
|
||||
return false;
|
||||
|
||||
if (len && !buffer)
|
||||
return false;
|
||||
|
||||
unsigned ilen = len > SEGMENT_LIMIT ? SEGMENT_LIMIT : static_cast<unsigned>(len);
|
||||
unsigned olen = 0;
|
||||
bool eof = m_blob->getSegment(m_status, ilen, buffer, &olen) == Firebird::IStatus::RESULT_NO_DATA;
|
||||
if (m_status->isEmpty() && !eof)
|
||||
{
|
||||
real_len = olen;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool BlobWrapper::getData(FB_SIZE_T len, void* buffer, FB_SIZE_T& real_len,
|
||||
bool use_sep, const UCHAR separator)
|
||||
{
|
||||
#ifdef DEV_BUILD
|
||||
if (!m_blob || m_direction != dir_read)
|
||||
return false;
|
||||
|
||||
if (!len || !buffer)
|
||||
return false;
|
||||
#endif
|
||||
|
||||
bool rc = false;
|
||||
real_len = 0;
|
||||
char* buf2 = static_cast<char*>(buffer);
|
||||
while (len)
|
||||
{
|
||||
unsigned olen = 0;
|
||||
bool eof = m_blob->getSegment(m_status, len, buf2, &olen) == Firebird::IStatus::RESULT_NO_DATA;
|
||||
if (m_status->isEmpty() && !eof)
|
||||
{
|
||||
len -= olen;
|
||||
buf2 += olen;
|
||||
real_len += olen;
|
||||
|
||||
if (len && use_sep) // Append the segment separator.
|
||||
{
|
||||
--len;
|
||||
*buf2++ = separator;
|
||||
++real_len;
|
||||
}
|
||||
|
||||
rc = true;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
bool BlobWrapper::putSegment(FB_SIZE_T len, const void* buffer)
|
||||
{
|
||||
#ifdef DEV_BUILD
|
||||
if (!m_blob || m_direction != dir_write)
|
||||
return false;
|
||||
|
||||
if (len > 0 && !buffer)
|
||||
return false;
|
||||
#endif
|
||||
|
||||
unsigned ilen = len > SEGMENT_LIMIT ? SEGMENT_LIMIT : static_cast<unsigned>(len);
|
||||
m_blob->putSegment(m_status, ilen, buffer);
|
||||
return m_status->isEmpty();
|
||||
}
|
||||
|
||||
bool BlobWrapper::putSegment(FB_SIZE_T len, const void* buffer, FB_SIZE_T& real_len)
|
||||
{
|
||||
#ifdef DEV_BUILD
|
||||
if (!m_blob || m_direction == dir_read)
|
||||
return false;
|
||||
|
||||
if (len > 0 && !buffer)
|
||||
return false;
|
||||
#endif
|
||||
|
||||
real_len = 0;
|
||||
unsigned ilen = len > SEGMENT_LIMIT ? SEGMENT_LIMIT : static_cast<unsigned>(len);
|
||||
m_blob->putSegment(m_status, ilen, buffer);
|
||||
|
||||
if (!m_status->isEmpty())
|
||||
return false;
|
||||
|
||||
real_len = ilen;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BlobWrapper::putData(FB_SIZE_T len, const void* buffer, FB_SIZE_T& real_len)
|
||||
{
|
||||
if (!m_blob || m_direction == dir_read)
|
||||
return false;
|
||||
|
||||
if (len > 0 && !buffer)
|
||||
return false;
|
||||
|
||||
real_len = 0;
|
||||
m_blob->putSegment(m_status, len, buffer);
|
||||
|
||||
if (!m_status->isEmpty())
|
||||
return false;
|
||||
|
||||
real_len = len;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BlobWrapper::getInfo(FB_SIZE_T items_size, const UCHAR* items,
|
||||
FB_SIZE_T info_size, UCHAR* blob_info) const
|
||||
{
|
||||
if (!m_blob || m_direction != dir_read)
|
||||
return false;
|
||||
|
||||
m_blob->getInfo(m_status, items_size, items, info_size, blob_info);
|
||||
|
||||
return m_status->isEmpty();
|
||||
}
|
||||
|
||||
bool BlobWrapper::getSize(SLONG* size, SLONG* seg_count, SLONG* max_seg) const
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
* g e t B l o b S i z e
|
||||
*
|
||||
**************************************
|
||||
*
|
||||
* Functional description
|
||||
* Get the size, number of segments, and max
|
||||
* segment length of a blob. Return true
|
||||
* if it happens to succeed.
|
||||
* This is a clone of gds__blob_size.
|
||||
*
|
||||
**************************************/
|
||||
static const UCHAR blob_items[] =
|
||||
{
|
||||
isc_info_blob_max_segment,
|
||||
isc_info_blob_num_segments,
|
||||
isc_info_blob_total_length
|
||||
};
|
||||
|
||||
UCHAR buffer[64];
|
||||
|
||||
if (!getInfo(sizeof(blob_items), blob_items, sizeof(buffer), buffer))
|
||||
return false;
|
||||
|
||||
const UCHAR* p = buffer;
|
||||
const UCHAR* const end = buffer + sizeof(buffer);
|
||||
|
||||
for (UCHAR item = *p++; item != isc_info_end && p < end; item = *p++)
|
||||
{
|
||||
const USHORT l = gds__vax_integer(p, 2);
|
||||
p += 2;
|
||||
const SLONG n = gds__vax_integer(p, l);
|
||||
p += l;
|
||||
|
||||
switch (item)
|
||||
{
|
||||
case isc_info_blob_max_segment:
|
||||
if (max_seg)
|
||||
*max_seg = n;
|
||||
break;
|
||||
|
||||
case isc_info_blob_num_segments:
|
||||
if (seg_count)
|
||||
*seg_count = n;
|
||||
break;
|
||||
|
||||
case isc_info_blob_total_length:
|
||||
if (size)
|
||||
*size = n;
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
95
src/common/classes/BlobWrapper.h
Normal file
95
src/common/classes/BlobWrapper.h
Normal file
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* 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 Claudio Valderrama on 16-Mar-2007
|
||||
* for the Firebird Open Source RDBMS project.
|
||||
*
|
||||
* Copyright (c) 2007 Claudio Valderrama
|
||||
* and all contributors signed below.
|
||||
*
|
||||
* All Rights Reserved.
|
||||
* Contributor(s): ______________________________________.
|
||||
* Alex Peshkoff, 2017
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef FB_USER_BLOB_H
|
||||
#define FB_USER_BLOB_H
|
||||
|
||||
#include "firebird/Interface.h"
|
||||
#include <memory.h>
|
||||
#include "../common/status.h"
|
||||
|
||||
class BlobWrapper
|
||||
{
|
||||
public:
|
||||
explicit BlobWrapper(Firebird::CheckStatusWrapper* status)
|
||||
: m_status(status ? status : &m_default_status), m_blob(nullptr), m_direction(dir_none)
|
||||
{ }
|
||||
|
||||
~BlobWrapper()
|
||||
{
|
||||
close(true);
|
||||
}
|
||||
|
||||
bool open(Firebird::IAttachment* db, Firebird::ITransaction* trans, ISC_QUAD& blobid,
|
||||
USHORT bpb_len = 0, const UCHAR* bpb = nullptr);
|
||||
bool create(Firebird::IAttachment* db, Firebird::ITransaction* trans, ISC_QUAD& blobid,
|
||||
USHORT bpb_len = 0, const UCHAR* bpb = nullptr);
|
||||
bool close(bool force_internal_SV = false);
|
||||
bool getSegment(FB_SIZE_T len, void* buffer, FB_SIZE_T& real_len);
|
||||
bool getData(FB_SIZE_T len, void* buffer, FB_SIZE_T& real_len, bool use_sep = false, const UCHAR separator = '\0');
|
||||
bool putSegment(FB_SIZE_T len, const void* buffer);
|
||||
bool putSegment(FB_SIZE_T len, const void* buffer, FB_SIZE_T& real_len);
|
||||
bool putData(FB_SIZE_T len, const void* buffer, FB_SIZE_T& real_len);
|
||||
bool putData(FB_SIZE_T len, const void* buffer)
|
||||
{
|
||||
FB_SIZE_T dummy;
|
||||
return putData(len, buffer, dummy);
|
||||
}
|
||||
|
||||
bool isOpen() const
|
||||
{
|
||||
return m_blob != 0 && m_direction != dir_none;
|
||||
}
|
||||
|
||||
ISC_STATUS getCode() const
|
||||
{
|
||||
return m_status->getErrors()[1];
|
||||
}
|
||||
|
||||
bool getInfo(FB_SIZE_T items_size, const UCHAR* items, FB_SIZE_T info_size, UCHAR* blob_info) const;
|
||||
bool getSize(SLONG* size, SLONG* seg_count, SLONG* max_seg) const;
|
||||
|
||||
static bool blobIsNull(const ISC_QUAD& blobid)
|
||||
{
|
||||
return blobid.gds_quad_high == 0 && blobid.gds_quad_low == 0;
|
||||
}
|
||||
|
||||
private:
|
||||
enum b_direction
|
||||
{
|
||||
dir_none,
|
||||
dir_read,
|
||||
dir_write
|
||||
};
|
||||
|
||||
Firebird::FbLocalStatus m_default_status;
|
||||
Firebird::CheckStatusWrapper* const m_status;
|
||||
Firebird::IBlob* m_blob;
|
||||
b_direction m_direction;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // FB_USER_BLOB_H
|
||||
|
@ -334,7 +334,9 @@ ClumpletReader::ClumpletType ClumpletReader::getClumpletType(UCHAR tag) const
|
||||
case isc_spb_res_fix_fss_metadata:
|
||||
case isc_spb_bkp_stat:
|
||||
case isc_spb_bkp_skip_data:
|
||||
//case isc_spb_res_skip_data: // same value
|
||||
case isc_spb_bkp_keyholder:
|
||||
case isc_spb_bkp_keyname:
|
||||
case isc_spb_bkp_crypt:
|
||||
return StringSpb;
|
||||
case isc_spb_bkp_factor:
|
||||
case isc_spb_bkp_length:
|
||||
|
@ -49,6 +49,7 @@ static const UCHAR CpuAlpha = 14;
|
||||
static const UCHAR CpuArm64 = 15;
|
||||
static const UCHAR CpuPowerPc64el = 16;
|
||||
static const UCHAR CpuM68k = 17;
|
||||
static const UCHAR CpuRiscV64 = 18;
|
||||
|
||||
static const UCHAR OsWindows = 0;
|
||||
static const UCHAR OsLinux = 1;
|
||||
@ -89,7 +90,8 @@ const char* hardware[] = {
|
||||
"Alpha",
|
||||
"ARM64",
|
||||
"PowerPC64el",
|
||||
"M68k"
|
||||
"M68k",
|
||||
"RiscV64"
|
||||
};
|
||||
|
||||
const char* operatingSystem[] = {
|
||||
@ -116,22 +118,23 @@ const char* compiler[] = {
|
||||
// This table lists pre-fb3 implementation codes
|
||||
const UCHAR backwardTable[FB_NELEM(hardware) * FB_NELEM(operatingSystem)] =
|
||||
{
|
||||
// Intel AMD Sparc PPC PPC64 MIPSEL MIPS ARM IA64 s390 s390x SH SHEB HPPA Alpha ARM64 PowerPC64el
|
||||
/* Windows */ 50, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* Linux */ 60, 66, 65, 69, 86, 71, 72, 75, 76, 79, 78, 80, 81, 82, 83, 84, 85,
|
||||
/* Darwin */ 70, 73, 0, 63, 77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* Solaris */ 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* HPUX */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0,
|
||||
/* AIX */ 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* MVS */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* FreeBSD */ 61, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* NetBSD */ 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
// Intel AMD Sparc PPC PPC64 MIPSEL MIPS ARM IA64 s390 s390x SH SHEB HPPA Alpha ARM64 PPC64el M68k RiscV64
|
||||
/* Windows */ 50, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* Linux */ 60, 66, 65, 69, 86, 71, 72, 75, 76, 79, 78, 80, 81, 82, 83, 84, 85, 87, 88,
|
||||
/* Darwin */ 70, 73, 0, 63, 77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* Solaris */ 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* HPUX */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 0, 0,
|
||||
/* AIX */ 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* MVS */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* FreeBSD */ 61, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* NetBSD */ 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
|
||||
const UCHAR backEndianess[FB_NELEM(hardware)] =
|
||||
{
|
||||
// Intel AMD Sparc PPC PPC64 MIPSEL MIPS ARM IA64 s390 s390x SH SHEB HPPA Alpha ARM64 PowerPC64el M68k
|
||||
0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1
|
||||
// Intel AMD Sparc PPC PPC64 MIPSEL MIPS ARM IA64 s390 s390x SH SHEB HPPA Alpha ARM64 PPC64el M68k RiscV64
|
||||
0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0,
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
@ -41,7 +41,6 @@ public:
|
||||
DbImplementation (UCHAR p_cpu, UCHAR p_os, UCHAR p_cc, UCHAR p_flags)
|
||||
: di_cpu(p_cpu), di_os(p_os), di_cc(p_cc), di_flags(p_flags)
|
||||
{ }
|
||||
DbImplementation (UCHAR p_compatImpl);
|
||||
~DbImplementation() { }
|
||||
|
||||
private:
|
||||
|
@ -222,14 +222,6 @@ inline bool isinf(double x)
|
||||
{
|
||||
return (!_finite (x) && !isnan(x));
|
||||
}
|
||||
#else
|
||||
#ifndef isinf
|
||||
template <typename F>
|
||||
inline bool isinf(F x)
|
||||
{
|
||||
return !isnan(x) && isnan(x - x);
|
||||
}
|
||||
#endif // isinf
|
||||
#endif // WIN_NT
|
||||
|
||||
namespace Firebird {
|
||||
|
@ -30,6 +30,7 @@
|
||||
#define FB_COMMON_CLASSES_GET_PLUGINS
|
||||
|
||||
#include "../common/classes/ImplementHelper.h"
|
||||
#include "../common/classes/auto.h"
|
||||
#include "../common/config/config.h"
|
||||
#include "../common/StatusHolder.h"
|
||||
|
||||
@ -142,6 +143,28 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
// template required to use AutoPtr for plugins
|
||||
|
||||
template <typename P>
|
||||
class ReleasePlugin
|
||||
{
|
||||
public:
|
||||
static void clear(P* ptr)
|
||||
{
|
||||
if (ptr)
|
||||
PluginManagerInterfacePtr()->releasePlugin(ptr);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename P>
|
||||
class AutoPlugin : public AutoPtr<P, ReleasePlugin>
|
||||
{
|
||||
public:
|
||||
AutoPlugin(P* p = nullptr)
|
||||
: AutoPtr<P, ReleasePlugin>(p)
|
||||
{ }
|
||||
};
|
||||
|
||||
} // namespace Firebird
|
||||
|
||||
|
||||
|
@ -313,7 +313,7 @@ public:
|
||||
typedef void VoidNoParam();
|
||||
|
||||
explicit UnloadDetectorHelper(MemoryPool&)
|
||||
: cleanup(NULL), flagOsUnload(false)
|
||||
: cleanup(NULL), thdDetach(NULL), flagOsUnload(false)
|
||||
{ }
|
||||
|
||||
void registerMe()
|
||||
@ -348,6 +348,11 @@ public:
|
||||
cleanup = function;
|
||||
}
|
||||
|
||||
void setThreadDetach(VoidNoParam* function)
|
||||
{
|
||||
thdDetach = function;
|
||||
}
|
||||
|
||||
void doClean()
|
||||
{
|
||||
flagOsUnload = false;
|
||||
@ -359,8 +364,15 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void threadDetach()
|
||||
{
|
||||
if (thdDetach)
|
||||
thdDetach();
|
||||
}
|
||||
|
||||
private:
|
||||
VoidNoParam* cleanup;
|
||||
VoidNoParam* thdDetach;
|
||||
bool flagOsUnload;
|
||||
};
|
||||
|
||||
|
@ -130,6 +130,13 @@ namespace Firebird
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void moveFrom(RefPtr& r)
|
||||
{
|
||||
assign(NULL);
|
||||
ptr = r.ptr;
|
||||
r.ptr = NULL;
|
||||
}
|
||||
|
||||
T* operator=(T* p)
|
||||
{
|
||||
return assign(p);
|
||||
|
@ -31,6 +31,7 @@
|
||||
|
||||
#include "firebird.h"
|
||||
#include "fb_tls.h"
|
||||
#include "init.h"
|
||||
#include "../ThreadStart.h"
|
||||
#include "SyncObject.h"
|
||||
#include "Synchronize.h"
|
||||
@ -182,6 +183,37 @@ void Synchronize::shutdown()
|
||||
}
|
||||
|
||||
|
||||
class ThreadSyncInstance : public ThreadSync
|
||||
{
|
||||
typedef InstanceControl::InstanceLink<ThreadSyncInstance, InstanceControl::PRIORITY_REGULAR> Link;
|
||||
|
||||
public:
|
||||
ThreadSyncInstance(const char* desc)
|
||||
: ThreadSync(desc)
|
||||
{
|
||||
m_link = FB_NEW Link(this);
|
||||
}
|
||||
|
||||
virtual ~ThreadSyncInstance()
|
||||
{
|
||||
if (m_link)
|
||||
{
|
||||
m_link->remove();
|
||||
delete m_link;
|
||||
}
|
||||
}
|
||||
|
||||
// Used at InstanceControl::dtor
|
||||
void dtor()
|
||||
{
|
||||
m_link = nullptr;
|
||||
delete this;
|
||||
}
|
||||
|
||||
private:
|
||||
Link* m_link;
|
||||
};
|
||||
|
||||
/// ThreadSync
|
||||
|
||||
TLS_DECLARE(ThreadSync*, threadIndex);
|
||||
@ -210,7 +242,7 @@ ThreadSync* ThreadSync::getThread(const char* desc)
|
||||
|
||||
if (!thread)
|
||||
{
|
||||
thread = FB_NEW ThreadSync(desc);
|
||||
thread = FB_NEW ThreadSyncInstance(desc);
|
||||
|
||||
fb_assert(thread == findThread());
|
||||
}
|
||||
@ -220,6 +252,12 @@ ThreadSync* ThreadSync::getThread(const char* desc)
|
||||
|
||||
void ThreadSync::setThread(ThreadSync* thread)
|
||||
{
|
||||
if (thread != NULL)
|
||||
{
|
||||
ThreadSync* other = findThread();
|
||||
fb_assert(other == NULL);
|
||||
}
|
||||
|
||||
TLS_SET(threadIndex, thread);
|
||||
}
|
||||
|
||||
|
@ -224,12 +224,6 @@ public:
|
||||
// previously set group and added to new
|
||||
void setStatsGroup(MemoryStats& stats) FB_NOTHROW;
|
||||
|
||||
// Just a helper for AutoPtr.
|
||||
static void clear(MemoryPool* pool)
|
||||
{
|
||||
deletePool(pool);
|
||||
}
|
||||
|
||||
// Initialize and finalize global memory pool
|
||||
static void init();
|
||||
static void cleanup();
|
||||
@ -451,7 +445,14 @@ namespace Firebird
|
||||
explicit AutoStorage(MemoryPool& p) : PermanentStorage(p) { }
|
||||
};
|
||||
|
||||
typedef AutoPtr<MemoryPool, MemoryPool> AutoMemoryPool;
|
||||
template <>
|
||||
inline void SimpleDelete<MemoryPool>::clear(MemoryPool* pool)
|
||||
{
|
||||
if (pool)
|
||||
MemoryPool::deletePool(pool);
|
||||
}
|
||||
|
||||
typedef AutoPtr<MemoryPool> AutoMemoryPool;
|
||||
|
||||
} // namespace Firebird
|
||||
|
||||
|
@ -46,6 +46,15 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
inline void SimpleDelete<FILE>::clear(FILE* f)
|
||||
{
|
||||
if (f) {
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <typename What>
|
||||
class ArrayDelete
|
||||
{
|
||||
@ -56,6 +65,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename T>
|
||||
class SimpleRelease
|
||||
{
|
||||
@ -84,24 +94,24 @@ public:
|
||||
};
|
||||
|
||||
|
||||
template <typename Where, typename Clear = SimpleDelete<Where> >
|
||||
template <typename Where, template <typename W> class Clear = SimpleDelete >
|
||||
class AutoPtr
|
||||
{
|
||||
private:
|
||||
Where* ptr;
|
||||
public:
|
||||
AutoPtr<Where, Clear>(Where* v = NULL)
|
||||
AutoPtr(Where* v = NULL)
|
||||
: ptr(v)
|
||||
{}
|
||||
|
||||
~AutoPtr()
|
||||
{
|
||||
Clear::clear(ptr);
|
||||
Clear<Where>::clear(ptr);
|
||||
}
|
||||
|
||||
AutoPtr<Where, Clear>& operator= (Where* v)
|
||||
AutoPtr& operator= (Where* v)
|
||||
{
|
||||
Clear::clear(ptr);
|
||||
Clear<Where>::clear(ptr);
|
||||
ptr = v;
|
||||
return *this;
|
||||
}
|
||||
@ -157,14 +167,24 @@ public:
|
||||
{
|
||||
if (v != ptr)
|
||||
{
|
||||
Clear::clear(ptr);
|
||||
Clear<Where>::clear(ptr);
|
||||
ptr = v;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
AutoPtr<Where, Clear>(AutoPtr<Where, Clear>&);
|
||||
void operator=(AutoPtr<Where, Clear>&);
|
||||
AutoPtr(AutoPtr&);
|
||||
void operator=(AutoPtr&);
|
||||
};
|
||||
|
||||
|
||||
template <typename Where>
|
||||
class AutoDispose : public AutoPtr<Where, SimpleDispose>
|
||||
{
|
||||
public:
|
||||
AutoDispose(Where* v = nullptr)
|
||||
: AutoPtr<Where, SimpleDispose>(v)
|
||||
{ }
|
||||
};
|
||||
|
||||
|
||||
@ -259,19 +279,6 @@ private:
|
||||
};
|
||||
|
||||
|
||||
// One more typical class for AutoPtr cleanup
|
||||
class FileClose
|
||||
{
|
||||
public:
|
||||
static void clear(FILE *f)
|
||||
{
|
||||
if (f) {
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} //namespace Firebird
|
||||
|
||||
#endif // CLASSES_AUTO_PTR_H
|
||||
|
@ -93,7 +93,7 @@ namespace
|
||||
return;
|
||||
|
||||
#ifdef DEBUG_GDS_ALLOC
|
||||
Firebird::AutoPtr<FILE, Firebird::FileClose> file;
|
||||
Firebird::AutoPtr<FILE> file;
|
||||
|
||||
{ // scope
|
||||
Firebird::PathName name = "memdebug.log";
|
||||
@ -227,12 +227,37 @@ namespace Firebird
|
||||
{
|
||||
MutexLockGuard guard(*StaticMutex::mutex, "InstanceControl::InstanceList::InstanceList");
|
||||
next = instanceList;
|
||||
prev = nullptr;
|
||||
if (instanceList)
|
||||
instanceList->prev = this;
|
||||
instanceList = this;
|
||||
}
|
||||
|
||||
InstanceControl::InstanceList::~InstanceList()
|
||||
{
|
||||
delete next;
|
||||
fb_assert(next == nullptr);
|
||||
fb_assert(prev == nullptr);
|
||||
}
|
||||
|
||||
void InstanceControl::InstanceList::remove()
|
||||
{
|
||||
MutexLockGuard guard(*StaticMutex::mutex, FB_FUNCTION);
|
||||
unlist();
|
||||
}
|
||||
|
||||
void InstanceControl::InstanceList::unlist()
|
||||
{
|
||||
if (instanceList == this)
|
||||
instanceList = next;
|
||||
|
||||
if (next)
|
||||
next->prev = this->prev;
|
||||
|
||||
if (prev)
|
||||
prev->next = this->next;
|
||||
|
||||
prev = nullptr;
|
||||
next = nullptr;
|
||||
}
|
||||
|
||||
void InstanceControl::destructors()
|
||||
@ -299,8 +324,13 @@ namespace Firebird
|
||||
}
|
||||
} while (nextPriority != currentPriority);
|
||||
|
||||
delete instanceList;
|
||||
instanceList = 0;
|
||||
|
||||
while (instanceList)
|
||||
{
|
||||
InstanceList* item = instanceList;
|
||||
item->unlist();
|
||||
delete item;
|
||||
}
|
||||
}
|
||||
|
||||
void InstanceControl::registerGdsCleanup(FPTR_VOID cleanup)
|
||||
|
@ -71,10 +71,16 @@ public:
|
||||
virtual ~InstanceList();
|
||||
static void destructors();
|
||||
|
||||
// remove self from common list under StaticMutex protection
|
||||
void remove();
|
||||
|
||||
private:
|
||||
InstanceList* next;
|
||||
DtorPriority priority;
|
||||
virtual void dtor() = 0;
|
||||
void unlist();
|
||||
|
||||
InstanceList* next;
|
||||
InstanceList* prev;
|
||||
DtorPriority priority;
|
||||
};
|
||||
|
||||
template <typename T, InstanceControl::DtorPriority P = InstanceControl::PRIORITY_REGULAR>
|
||||
@ -90,6 +96,11 @@ public:
|
||||
fb_assert(link);
|
||||
}
|
||||
|
||||
void remove()
|
||||
{
|
||||
InstanceList::remove();
|
||||
}
|
||||
|
||||
void dtor()
|
||||
{
|
||||
fb_assert(link);
|
||||
|
@ -296,7 +296,7 @@ public:
|
||||
const bool at_begin = (m_begin == m_curr);
|
||||
m_curr++;
|
||||
|
||||
while (Marker::isMarked(m_curr) && m_curr < m_end)
|
||||
while (m_curr < m_end && Marker::isMarked(m_curr))
|
||||
m_curr++;
|
||||
|
||||
if (m_curr == m_end)
|
||||
|
@ -139,6 +139,10 @@
|
||||
#define FB_CPU CpuArm64
|
||||
#endif /* ARM64 */
|
||||
|
||||
#ifdef RISCV64
|
||||
#define FB_CPU CpuRiscV64
|
||||
#endif /* RISCV64 */
|
||||
|
||||
#ifdef sparc
|
||||
#define FB_CPU CpuUltraSparc
|
||||
#define RISC_ALIGNMENT
|
||||
|
@ -203,6 +203,15 @@ const Config::ConfigEntry Config::entries[MAX_CONFIG_KEY] =
|
||||
{TYPE_INTEGER, "StatementTimeout", (ConfigValue) 0},
|
||||
{TYPE_INTEGER, "ConnectionIdleTimeout", (ConfigValue) 0},
|
||||
{TYPE_INTEGER, "ClientBatchBuffer", (ConfigValue) (128 * 1024)},
|
||||
#ifdef DEV_BUILD
|
||||
{TYPE_STRING, "OutputRedirectionFile", (ConfigValue) "-"},
|
||||
#else
|
||||
#ifdef WIN_NT
|
||||
{TYPE_STRING, "OutputRedirectionFile", (ConfigValue) "nul"},
|
||||
#else
|
||||
{TYPE_STRING, "OutputRedirectionFile", (ConfigValue) "/dev/null"},
|
||||
#endif
|
||||
#endif
|
||||
{TYPE_INTEGER, "ExtConnPoolSize", (ConfigValue) 0},
|
||||
{TYPE_INTEGER, "ExtConnPoolLifeTime", (ConfigValue) 7200}
|
||||
};
|
||||
@ -841,6 +850,12 @@ unsigned int Config::getClientBatchBuffer() const
|
||||
return get<unsigned int>(KEY_CLIENT_BATCH_BUFFER);
|
||||
}
|
||||
|
||||
const char* Config::getOutputRedirectionFile()
|
||||
{
|
||||
const char* file = (const char*) (getDefaultConfig()->values[KEY_OUTPUT_REDIRECTION_FILE]);
|
||||
return file;
|
||||
}
|
||||
|
||||
int Config::getExtConnPoolSize()
|
||||
{
|
||||
return getDefaultConfig()->get<int>(KEY_EXT_CONN_POOL_SIZE);
|
||||
|
@ -146,6 +146,7 @@ public:
|
||||
KEY_STMT_TIMEOUT,
|
||||
KEY_CONN_IDLE_TIMEOUT,
|
||||
KEY_CLIENT_BATCH_BUFFER,
|
||||
KEY_OUTPUT_REDIRECTION_FILE,
|
||||
KEY_EXT_CONN_POOL_SIZE,
|
||||
KEY_EXT_CONN_POOL_LIFETIME,
|
||||
MAX_CONFIG_KEY // keep it last
|
||||
@ -365,6 +366,8 @@ public:
|
||||
|
||||
unsigned int getClientBatchBuffer() const;
|
||||
|
||||
static const char* getOutputRedirectionFile();
|
||||
|
||||
static int getExtConnPoolSize();
|
||||
|
||||
static int getExtConnPoolLifeTime();
|
||||
|
@ -109,7 +109,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
AutoPtr<FILE, FileClose> file;
|
||||
AutoPtr<FILE> file;
|
||||
Firebird::PathName fileName;
|
||||
unsigned int l;
|
||||
};
|
||||
|
@ -1466,6 +1466,8 @@ void dsc::getSqlInfo(SLONG* sqlLength, SLONG* sqlSubType, SLONG* sqlScale, SLONG
|
||||
case dtype_dec_fixed:
|
||||
*sqlType = SQL_DEC_FIXED;
|
||||
*sqlScale = dsc_scale;
|
||||
if (dsc_sub_type)
|
||||
*sqlSubType = dsc_sub_type;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -173,7 +173,7 @@ typedef struct dsc
|
||||
|
||||
bool isDecOrInt() const
|
||||
{
|
||||
return isDecFloat() || isExact();
|
||||
return isDecFloat() || isDecFixed() || isExact();
|
||||
}
|
||||
|
||||
bool isApprox() const
|
||||
|
@ -2207,12 +2207,14 @@ SharedMemoryBase::SharedMemoryBase(const TEXT* filename, ULONG length, IpcObject
|
||||
|
||||
if (file_handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if ((err == ERROR_SHARING_VIOLATION))
|
||||
if ((err == ERROR_SHARING_VIOLATION) || (err == ERROR_ACCESS_DENIED))
|
||||
{
|
||||
if (!init_flag) {
|
||||
CloseHandle(event_handle);
|
||||
}
|
||||
goto retry;
|
||||
|
||||
if (retry_count < 200) // 2 sec
|
||||
goto retry;
|
||||
}
|
||||
|
||||
CloseHandle(event_handle);
|
||||
|
@ -101,7 +101,7 @@ public:
|
||||
"msvcr110.dll",
|
||||
#elif _MSC_VER == 1800
|
||||
"msvcr120.dll",
|
||||
#elif _MSC_VER >= 1900 && _MSC_VER <= 1912
|
||||
#elif _MSC_VER >= 1900 && _MSC_VER < 1920
|
||||
"vcruntime140.dll",
|
||||
#else
|
||||
#error Specify CRT DLL name here !
|
||||
|
116
src/common/status.h
Normal file
116
src/common/status.h
Normal file
@ -0,0 +1,116 @@
|
||||
/*
|
||||
* PROGRAM: Firebird exceptions classes
|
||||
* MODULE: status.h
|
||||
* DESCRIPTION: Status vector filling and parsing.
|
||||
*
|
||||
* 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 Mike Nordell
|
||||
* for the Firebird Open Source RDBMS project.
|
||||
*
|
||||
* Copyright (c) 2001 Mike Nordell <tamlin at algonet.se>
|
||||
* and all contributors signed below.
|
||||
*
|
||||
* All Rights Reserved.
|
||||
* Contributor(s): ______________________________________.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef COMMON_STATUS_H
|
||||
#define COMMON_STATUS_H
|
||||
|
||||
#include "../common/StatusHolder.h"
|
||||
#include "../common/utils_proto.h"
|
||||
|
||||
const int MAX_ERRMSG_LEN = 128;
|
||||
const int MAX_ERRSTR_LEN = 1024;
|
||||
|
||||
namespace Firebird
|
||||
{
|
||||
template <class SW>
|
||||
class LocalStatusWrapper
|
||||
{
|
||||
public:
|
||||
LocalStatusWrapper()
|
||||
: localStatusVector(&localStatus)
|
||||
{ }
|
||||
|
||||
explicit LocalStatusWrapper(Firebird::MemoryPool& p)
|
||||
: localStatus(p), localStatusVector(&localStatus)
|
||||
{ }
|
||||
|
||||
SW* operator->()
|
||||
{
|
||||
return &localStatusVector;
|
||||
}
|
||||
|
||||
SW* operator&()
|
||||
{
|
||||
return &localStatusVector;
|
||||
}
|
||||
|
||||
ISC_STATUS operator[](unsigned n) const
|
||||
{
|
||||
fb_assert(n < fb_utils::statusLength(localStatusVector.getErrors()));
|
||||
return localStatusVector.getErrors()[n];
|
||||
}
|
||||
|
||||
const SW* operator->() const
|
||||
{
|
||||
return &localStatusVector;
|
||||
}
|
||||
|
||||
const SW* operator&() const
|
||||
{
|
||||
return &localStatusVector;
|
||||
}
|
||||
|
||||
void check() const
|
||||
{
|
||||
if (localStatusVector.isDirty())
|
||||
{
|
||||
if (localStatus.getState() & Firebird::IStatus::STATE_ERRORS)
|
||||
raise();
|
||||
}
|
||||
}
|
||||
|
||||
void copyTo(SW* to) const
|
||||
{
|
||||
fb_utils::copyStatus(to, &localStatusVector);
|
||||
}
|
||||
|
||||
void raise() const
|
||||
{
|
||||
Firebird::status_exception::raise(&localStatus);
|
||||
}
|
||||
|
||||
bool isEmpty() const
|
||||
{
|
||||
return localStatusVector.isEmpty();
|
||||
}
|
||||
|
||||
bool isSuccess() const
|
||||
{
|
||||
return localStatusVector.isEmpty();
|
||||
}
|
||||
|
||||
private:
|
||||
Firebird::LocalStatus localStatus;
|
||||
SW localStatusVector;
|
||||
};
|
||||
|
||||
typedef LocalStatusWrapper<CheckStatusWrapper> FbLocalStatus;
|
||||
typedef LocalStatusWrapper<ThrowStatusWrapper> ThrowLocalStatus;
|
||||
}
|
||||
|
||||
#endif // COMMON_STATUS_H
|
@ -50,9 +50,6 @@
|
||||
# include <unicode/utf_old.h>
|
||||
#endif
|
||||
|
||||
// The next major ICU version after 4.8 is 49.
|
||||
#define ICU_NEW_VERSION_MEANING 49
|
||||
|
||||
|
||||
using namespace Firebird;
|
||||
|
||||
@ -121,7 +118,7 @@ public:
|
||||
|
||||
namespace Jrd {
|
||||
|
||||
static void formatFilename(PathName& filename, const char* templateName,
|
||||
static ModuleLoader::Module* formatAndLoad(const char* templateName,
|
||||
int majorVersion, int minorVersion);
|
||||
|
||||
|
||||
@ -229,10 +226,7 @@ private:
|
||||
ImplementConversionICU(int aMajorVersion, int aMinorVersion)
|
||||
: BaseICU(aMajorVersion, aMinorVersion)
|
||||
{
|
||||
PathName filename;
|
||||
formatFilename(filename, ucTemplate, aMajorVersion, aMinorVersion);
|
||||
|
||||
module = ModuleLoader::fixAndLoadModule(filename);
|
||||
module = formatAndLoad(ucTemplate, aMajorVersion, aMinorVersion);
|
||||
if (!module)
|
||||
return;
|
||||
|
||||
@ -342,16 +336,27 @@ static const char* const COLL_30_VERSION = "41.128.4.4"; // ICU 3.0 collator ver
|
||||
static GlobalPtr<UnicodeUtil::ICUModules> icuModules;
|
||||
|
||||
|
||||
static void formatFilename(PathName& filename, const char* templateName,
|
||||
static ModuleLoader::Module* formatAndLoad(const char* templateName,
|
||||
int majorVersion, int minorVersion)
|
||||
{
|
||||
string s;
|
||||
if (majorVersion >= ICU_NEW_VERSION_MEANING)
|
||||
s.printf("%d", majorVersion);
|
||||
else
|
||||
s.printf("%d%d", majorVersion, minorVersion);
|
||||
// ICU has several schemas for placing version into file name
|
||||
const char* patterns[] =
|
||||
{
|
||||
"%d", "%d_%d", "%d%d", NULL
|
||||
};
|
||||
|
||||
filename.printf(templateName, s.c_str());
|
||||
PathName s, filename;
|
||||
for (const char** p = patterns; *p; ++p)
|
||||
{
|
||||
s.printf(*p, majorVersion, minorVersion);
|
||||
filename.printf(templateName, s.c_str());
|
||||
|
||||
ModuleLoader::Module* module = ModuleLoader::fixAndLoadModule(filename);
|
||||
if (module)
|
||||
return module;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@ -974,17 +979,14 @@ UnicodeUtil::ICU* UnicodeUtil::loadICU(const string& icuVersion, const string& c
|
||||
continue;
|
||||
|
||||
string configVersion;
|
||||
|
||||
if (majorVersion >= ICU_NEW_VERSION_MEANING)
|
||||
configVersion.printf("%d.%d", majorVersion, minorVersion);
|
||||
if (version != configVersion)
|
||||
{
|
||||
minorVersion = 0;
|
||||
configVersion.printf("%d", majorVersion);
|
||||
if (version != configVersion)
|
||||
continue;
|
||||
}
|
||||
else
|
||||
configVersion.printf("%d.%d", majorVersion, minorVersion);
|
||||
|
||||
if (version != configVersion)
|
||||
continue;
|
||||
|
||||
ReadLockGuard readGuard(icuModules->lock, "UnicodeUtil::loadICU");
|
||||
|
||||
@ -992,27 +994,20 @@ UnicodeUtil::ICU* UnicodeUtil::loadICU(const string& icuVersion, const string& c
|
||||
if (icuModules->modules.get(version, icu))
|
||||
return icu;
|
||||
|
||||
PathName filename;
|
||||
formatFilename(filename, ucTemplate, majorVersion, minorVersion);
|
||||
|
||||
icu = FB_NEW_POOL(*getDefaultMemoryPool()) ICU(majorVersion, minorVersion);
|
||||
|
||||
icu->ucModule = ModuleLoader::fixAndLoadModule(filename);
|
||||
|
||||
icu->ucModule = formatAndLoad(ucTemplate, majorVersion, minorVersion);
|
||||
if (!icu->ucModule)
|
||||
{
|
||||
gds__log("failed to load module %s", filename.c_str());
|
||||
gds__log("failed to load UC icu module version %s", configVersion.c_str());
|
||||
delete icu;
|
||||
continue;
|
||||
}
|
||||
|
||||
formatFilename(filename, inTemplate, majorVersion, minorVersion);
|
||||
|
||||
icu->inModule = ModuleLoader::fixAndLoadModule(filename);
|
||||
|
||||
icu->inModule = formatAndLoad(inTemplate, majorVersion, minorVersion);
|
||||
if (!icu->inModule)
|
||||
{
|
||||
gds__log("failed to load module %s", filename.c_str());
|
||||
gds__log("failed to load IN icu module version %s", configVersion.c_str());
|
||||
delete icu;
|
||||
continue;
|
||||
}
|
||||
@ -1137,26 +1132,25 @@ UnicodeUtil::ConversionICU& UnicodeUtil::getConversionICU()
|
||||
LocalStatus ls;
|
||||
CheckStatusWrapper lastError(&ls);
|
||||
string version;
|
||||
const int majorArray[] = {5, 4, 3, 6, 0};
|
||||
|
||||
for (const int* major = majorArray; *major; ++major)
|
||||
for (int major = 4; major <= 79; ++major)
|
||||
{
|
||||
for (int minor = 20; minor--; ) // from 19 down to 0
|
||||
{
|
||||
if ((*major == favMaj) && (minor == favMin))
|
||||
if ((major == favMaj) && (minor == favMin))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if ((convIcu = ImplementConversionICU::create(*major, minor)))
|
||||
if ((convIcu = ImplementConversionICU::create(major, minor)))
|
||||
return *convIcu;
|
||||
}
|
||||
catch (const Exception& ex)
|
||||
{
|
||||
ex.stuffException(&lastError);
|
||||
version.printf("Error loading ICU library version %d.%d", *major, minor);
|
||||
version.printf("Error loading ICU library version %d.%d", major, minor);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1176,7 +1170,7 @@ string UnicodeUtil::getDefaultIcuVersion()
|
||||
string rc;
|
||||
UnicodeUtil::ConversionICU& icu(UnicodeUtil::getConversionICU());
|
||||
|
||||
if (icu.vMajor >= ICU_NEW_VERSION_MEANING)
|
||||
if (icu.vMajor >= 10 && icu.vMinor == 0)
|
||||
rc.printf("%d", icu.vMajor);
|
||||
else
|
||||
rc.printf("%d.%d", icu.vMajor, icu.vMinor);
|
||||
|
@ -90,7 +90,7 @@ static bool isItSqlRole(thread_db* tdbb, jrd_tra* transaction, const MetaName& i
|
||||
static int getGrantorOption(thread_db* tdbb, jrd_tra* transaction, const MetaName& grantor,
|
||||
int grantorType, const MetaName& roleName);
|
||||
static MetaName getIndexRelationName(thread_db* tdbb, jrd_tra* transaction,
|
||||
const MetaName& indexName);
|
||||
const MetaName& indexName, bool& systemIndex);
|
||||
static const char* getRelationScopeName(const rel_t type);
|
||||
static void makeRelationScopeName(string& to, const MetaName& name, const rel_t type);
|
||||
static void checkRelationType(const rel_t type, const MetaName& name);
|
||||
@ -539,14 +539,17 @@ static void makeRelationScopeName(string& to, const MetaName& name, const rel_t
|
||||
|
||||
// Get relation name of an index.
|
||||
static MetaName getIndexRelationName(thread_db* tdbb, jrd_tra* transaction,
|
||||
const MetaName& indexName)
|
||||
const MetaName& indexName, bool& systemIndex)
|
||||
{
|
||||
systemIndex = false;
|
||||
|
||||
AutoCacheRequest request(tdbb, drq_l_index_relname, DYN_REQUESTS);
|
||||
|
||||
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE transaction)
|
||||
IDX IN RDB$INDICES
|
||||
WITH IDX.RDB$INDEX_NAME EQ indexName.c_str()
|
||||
{
|
||||
systemIndex = IDX.RDB$SYSTEM_FLAG == 1;
|
||||
return IDX.RDB$RELATION_NAME;
|
||||
}
|
||||
END_FOR
|
||||
@ -849,6 +852,12 @@ static void updateRdbFields(const TypeClause* type,
|
||||
fieldSubTypeNull = FALSE;
|
||||
fieldSubType = type->subType;
|
||||
}
|
||||
|
||||
if (DTYPE_IS_DECFLOAT(type->dtype))
|
||||
{
|
||||
fieldPrecisionNull = FALSE;
|
||||
fieldPrecision = type->precision;
|
||||
}
|
||||
}
|
||||
|
||||
if (type->dtype == dtype_varying)
|
||||
@ -1361,9 +1370,10 @@ bool CommentOnNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
|
||||
break;
|
||||
|
||||
case obj_index:
|
||||
relationName = getIndexRelationName(tdbb, transaction, objName.identifier);
|
||||
bool systemIndex;
|
||||
relationName = getIndexRelationName(tdbb, transaction, objName.identifier, systemIndex);
|
||||
dscName.makeText(relationName.length(), CS_METADATA, (UCHAR*) relationName.c_str());
|
||||
SCL_check_relation(tdbb, &dscName, SCL_alter);
|
||||
SCL_check_relation(tdbb, &dscName, SCL_alter, systemIndex);
|
||||
break;
|
||||
|
||||
case obj_sql_role:
|
||||
@ -1873,6 +1883,7 @@ bool CreateAlterFunctionNode::executeAlter(thread_db* tdbb, DsqlCompilerScratch*
|
||||
|
||||
FUN.RDB$DETERMINISTIC_FLAG.NULL = FALSE;
|
||||
FUN.RDB$DETERMINISTIC_FLAG = deterministic ? TRUE : FALSE;
|
||||
FUN.RDB$RETURN_ARGUMENT = 0;
|
||||
|
||||
if (ssDefiner.specified)
|
||||
{
|
||||
@ -3566,6 +3577,26 @@ DdlNode* CreateAlterTriggerNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
|
||||
|
||||
bool CreateAlterTriggerNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
|
||||
{
|
||||
if (!create)
|
||||
{
|
||||
AutoRequest requestHandle;
|
||||
|
||||
FOR (REQUEST_HANDLE requestHandle TRANSACTION_HANDLE transaction)
|
||||
TRG IN RDB$TRIGGERS
|
||||
WITH TRG.RDB$TRIGGER_NAME EQ name.c_str()
|
||||
{
|
||||
if (!type.specified && !TRG.RDB$TRIGGER_TYPE.NULL)
|
||||
type = TRG.RDB$TRIGGER_TYPE;
|
||||
|
||||
if (relationName.isEmpty() && !TRG.RDB$RELATION_NAME.NULL)
|
||||
relationName = TRG.RDB$RELATION_NAME;
|
||||
}
|
||||
END_FOR
|
||||
|
||||
if (!type.specified)
|
||||
status_exception::raise(Arg::Gds(isc_dyn_trig_not_found) << Arg::Str(name));
|
||||
}
|
||||
|
||||
if (relationName.hasData())
|
||||
{
|
||||
dsc dscName;
|
||||
@ -3590,26 +3621,6 @@ void CreateAlterTriggerNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlS
|
||||
// run all statements under savepoint control
|
||||
AutoSavePoint savePoint(tdbb, transaction);
|
||||
|
||||
if (!create)
|
||||
{
|
||||
AutoRequest requestHandle;
|
||||
|
||||
FOR (REQUEST_HANDLE requestHandle TRANSACTION_HANDLE transaction)
|
||||
TRG IN RDB$TRIGGERS
|
||||
WITH TRG.RDB$TRIGGER_NAME EQ name.c_str()
|
||||
{
|
||||
if (!type.specified && !TRG.RDB$TRIGGER_TYPE.NULL)
|
||||
type = TRG.RDB$TRIGGER_TYPE;
|
||||
|
||||
if (relationName.isEmpty() && !TRG.RDB$RELATION_NAME.NULL)
|
||||
relationName = TRG.RDB$RELATION_NAME;
|
||||
}
|
||||
END_FOR
|
||||
|
||||
if (!type.specified)
|
||||
status_exception::raise(Arg::Gds(isc_dyn_trig_not_found) << Arg::Str(name));
|
||||
}
|
||||
|
||||
compile(tdbb, dsqlScratch);
|
||||
|
||||
blrData = dsqlScratch->getBlrData();
|
||||
@ -9674,7 +9685,7 @@ bool CreateIndexNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
|
||||
dsc dscName;
|
||||
const MetaName &relationName = relation->dsqlName;
|
||||
dscName.makeText(relationName.length(), CS_METADATA, (UCHAR*) relationName.c_str());
|
||||
SCL_check_relation(tdbb, &dscName, SCL_alter);
|
||||
SCL_check_relation(tdbb, &dscName, SCL_alter, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -9742,12 +9753,13 @@ string AlterIndexNode::internalPrint(NodePrinter& printer) const
|
||||
|
||||
bool AlterIndexNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
|
||||
{
|
||||
MetaName relationName = getIndexRelationName(tdbb, transaction, name);
|
||||
bool systemIndex;
|
||||
MetaName relationName = getIndexRelationName(tdbb, transaction, name, systemIndex);
|
||||
|
||||
dsc dscName;
|
||||
dscName.makeText(relationName.length(), CS_METADATA, (UCHAR*) relationName.c_str());
|
||||
|
||||
SCL_check_relation(tdbb, &dscName, SCL_alter);
|
||||
SCL_check_relation(tdbb, &dscName, SCL_alter, systemIndex);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -9804,7 +9816,8 @@ string SetStatisticsNode::internalPrint(NodePrinter& printer) const
|
||||
|
||||
bool SetStatisticsNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
|
||||
{
|
||||
MetaName relationName = getIndexRelationName(tdbb, transaction, name);
|
||||
bool systemIndex;
|
||||
MetaName relationName = getIndexRelationName(tdbb, transaction, name, systemIndex);
|
||||
|
||||
dsc dscName;
|
||||
dscName.makeText(relationName.length(), CS_METADATA, (UCHAR*) relationName.c_str());
|
||||
@ -9885,12 +9898,13 @@ string DropIndexNode::internalPrint(NodePrinter& printer) const
|
||||
|
||||
bool DropIndexNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
|
||||
{
|
||||
MetaName relationName = getIndexRelationName(tdbb, transaction, name);
|
||||
bool systemIndex;
|
||||
MetaName relationName = getIndexRelationName(tdbb, transaction, name, systemIndex);
|
||||
|
||||
dsc dscName;
|
||||
dscName.makeText(relationName.length(), CS_METADATA, (UCHAR*) relationName.c_str());
|
||||
|
||||
SCL_check_relation(tdbb, &dscName, SCL_alter);
|
||||
SCL_check_relation(tdbb, &dscName, SCL_alter, systemIndex);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -11362,12 +11376,22 @@ void GrantRevokeNode::grantRevoke(thread_db* tdbb, jrd_tra* transaction, const G
|
||||
ERRD_post(Arg::Gds(isc_dsql_cant_grant_option) << Arg::Str("system privileges"));
|
||||
break;
|
||||
|
||||
case obj_udf:
|
||||
ERRD_post(Arg::Gds(isc_dsql_cant_grant_option) << Arg::Str("functions"));
|
||||
break;
|
||||
|
||||
case obj_package_header:
|
||||
ERRD_post(Arg::Gds(isc_dsql_cant_grant_option) << Arg::Str("packages"));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (grantor && !tdbb->getAttachment()->locksmith(tdbb, USE_GRANTED_BY_CLAUSE))
|
||||
const Attachment* attachment = tdbb->getAttachment();
|
||||
|
||||
if (grantor && !attachment->locksmith(tdbb, USE_GRANTED_BY_CLAUSE))
|
||||
{
|
||||
const Firebird::MetaName& owner(tdbb->getDatabase()->dbb_owner);
|
||||
|
||||
@ -11377,7 +11401,7 @@ void GrantRevokeNode::grantRevoke(thread_db* tdbb, jrd_tra* transaction, const G
|
||||
(Arg::PrivateDyn(295) << DBA_USER_NAME << owner).raise();
|
||||
}
|
||||
|
||||
MetaName currentUser(tdbb->getAttachment()->att_user->getUserName());
|
||||
MetaName currentUser(attachment->att_user->getUserName());
|
||||
MetaName grantorRevoker(grantor ? *grantor : currentUser);
|
||||
|
||||
if (!isGrant && !privs) // REVOKE ALL ON ALL
|
||||
@ -11393,7 +11417,7 @@ void GrantRevokeNode::grantRevoke(thread_db* tdbb, jrd_tra* transaction, const G
|
||||
PRIV.RDB$USER_TYPE = userType AND
|
||||
PRIV.RDB$GRANTOR NOT MISSING
|
||||
{
|
||||
if (tdbb->getAttachment()->att_user->locksmith(tdbb, GRANT_REVOKE_ON_ANY_OBJECT) ||
|
||||
if (attachment->att_user->locksmith(tdbb, GRANT_REVOKE_ON_ANY_OBJECT) ||
|
||||
grantorRevoker == PRIV.RDB$GRANTOR)
|
||||
{
|
||||
ERASE PRIV;
|
||||
@ -11446,6 +11470,8 @@ void GrantRevokeNode::grantRevoke(thread_db* tdbb, jrd_tra* transaction, const G
|
||||
for (const char* pr = privileges; *pr; ++pr)
|
||||
{
|
||||
bool duplicate = false;
|
||||
MetaName newField = field;
|
||||
int newOptions = options;
|
||||
priv[0] = *pr;
|
||||
|
||||
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE transaction)
|
||||
@ -11459,23 +11485,22 @@ void GrantRevokeNode::grantRevoke(thread_db* tdbb, jrd_tra* transaction, const G
|
||||
(PRIV.RDB$FIELD_NAME EQUIV NULLIF(field.c_str(), '') OR
|
||||
(PRIV.RDB$OBJECT_TYPE EQ obj_sql_role))
|
||||
{
|
||||
if (PRIV.RDB$GRANT_OPTION.NULL ||
|
||||
PRIV.RDB$GRANT_OPTION ||
|
||||
PRIV.RDB$GRANT_OPTION == options)
|
||||
{
|
||||
duplicate = true;
|
||||
}
|
||||
else if (!PRIV.RDB$FIELD_NAME.NULL)
|
||||
field = PRIV.RDB$FIELD_NAME; // Keep DEFAULT ROLE while adding ADMIN OPTION
|
||||
// It means we have such privilege without grant option but
|
||||
// user grants it with grant option. We should re-grant existing privilege.
|
||||
const bool addGrantOption = (!PRIV.RDB$GRANT_OPTION.NULL && !PRIV.RDB$GRANT_OPTION &&
|
||||
PRIV.RDB$GRANT_OPTION != options);
|
||||
|
||||
if (duplicate && objType == obj_sql_role && field == "D" &&
|
||||
PRIV.RDB$FIELD_NAME.NULL)
|
||||
{
|
||||
// We have to reset duplicate to add DEFAULT ROLE and keep options to prevent reset of ADMIN OPTION
|
||||
duplicate = false;
|
||||
options = PRIV.RDB$GRANT_OPTION;
|
||||
}
|
||||
// It means we have such granted role but without DEFAULT but user grants with DEFAULT.
|
||||
// We should re-grant it.
|
||||
const bool addDefaultRole = (objType == obj_sql_role && field == "D" && PRIV.RDB$FIELD_NAME.NULL);
|
||||
|
||||
if (addGrantOption && !addDefaultRole) // Save DEFAULT option for re-grant
|
||||
newField = PRIV.RDB$FIELD_NAME;
|
||||
|
||||
if (addDefaultRole && !addGrantOption) // Add grant option was requested
|
||||
newOptions = PRIV.RDB$GRANT_OPTION;
|
||||
|
||||
duplicate = !addGrantOption && !addDefaultRole;
|
||||
|
||||
if (!duplicate)
|
||||
ERASE PRIV;
|
||||
@ -11515,38 +11540,55 @@ void GrantRevokeNode::grantRevoke(thread_db* tdbb, jrd_tra* transaction, const G
|
||||
// As long as only locksmith can use GRANTED BY, no need specially checking
|
||||
// for privileges of current user. AP-2008
|
||||
|
||||
if (objType == 0)
|
||||
switch (objType)
|
||||
{
|
||||
// Relation or view because we cannot distinguish at this point.
|
||||
checkGrantorCanGrant(tdbb, transaction,
|
||||
tdbb->getAttachment()->att_user->getUserName().c_str(), priv, objName,
|
||||
field, true);
|
||||
}
|
||||
else if (objType >= obj_database)
|
||||
{
|
||||
checkGrantorCanGrantDdl(tdbb, transaction,
|
||||
tdbb->getAttachment()->att_user->getUserName().c_str(), priv, objName);
|
||||
case obj_relation:
|
||||
{
|
||||
// Relation or view because we cannot distinguish at this point.
|
||||
checkGrantorCanGrantRelation(tdbb, transaction, currentUser.c_str(), priv, objName,
|
||||
field, true);
|
||||
break;
|
||||
}
|
||||
|
||||
case obj_exception:
|
||||
case obj_generator:
|
||||
{
|
||||
checkGrantorCanGrantObject(tdbb, transaction, currentUser.c_str(), priv, objName, objType);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
if (objType >= obj_database)
|
||||
{
|
||||
checkGrantorCanGrantDdl(tdbb, transaction, currentUser.c_str(), priv, objName);
|
||||
}
|
||||
// Prevent silent eating checks. In this case we can remove RDB$TRIGGER_9 (trigger1)
|
||||
// but add every object type above in switch
|
||||
// else
|
||||
// fb_assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
storePrivilege(tdbb, transaction, objName, user, field, pr, userType, objType,
|
||||
options, grantorRevoker);
|
||||
storePrivilege(tdbb, transaction, objName, user, newField, pr, userType, objType,
|
||||
newOptions, grantorRevoker);
|
||||
}
|
||||
}
|
||||
else // REVOKE
|
||||
{
|
||||
const bool revokeRoleDefault = (objType == obj_sql_role) && field.hasData();
|
||||
MetaName curField;
|
||||
int curOptions = options;
|
||||
const bool revokeDefaultRole = (objType == obj_sql_role) && field.hasData();
|
||||
const bool revokeGrantOption = options;
|
||||
|
||||
AutoCacheRequest request(tdbb, (field.hasData() ? drq_e_grant1 : drq_e_grant2), DYN_REQUESTS);
|
||||
// This var must be identical for request (1) and if below (2)
|
||||
const bool withField = field.hasData() && objType != obj_sql_role;
|
||||
|
||||
AutoCacheRequest request(tdbb, (withField ? drq_e_grant1 : drq_e_grant2), DYN_REQUESTS); // (1)
|
||||
|
||||
for (const char* pr = privileges; (priv[0] = *pr); ++pr)
|
||||
{
|
||||
bool grantErased = false;
|
||||
bool badGrantor = false;
|
||||
|
||||
if (field.hasData() && objType != obj_sql_role)
|
||||
if (withField) // (2)
|
||||
{
|
||||
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE transaction)
|
||||
PRIV IN RDB$USER_PRIVILEGES
|
||||
@ -11560,8 +11602,21 @@ void GrantRevokeNode::grantRevoke(thread_db* tdbb, jrd_tra* transaction, const G
|
||||
{
|
||||
if (grantorRevoker == PRIV.RDB$GRANTOR)
|
||||
{
|
||||
MetaName newField = NULL;
|
||||
int newOptions = 0;
|
||||
if (!revokeGrantOption && !PRIV.RDB$GRANT_OPTION.NULL)
|
||||
newOptions = PRIV.RDB$GRANT_OPTION;
|
||||
if (!revokeDefaultRole && !PRIV.RDB$FIELD_NAME.NULL)
|
||||
newField = PRIV.RDB$FIELD_NAME;
|
||||
|
||||
ERASE PRIV;
|
||||
grantErased = true;
|
||||
|
||||
if (revokeDefaultRole || revokeGrantOption)
|
||||
{
|
||||
storePrivilege(tdbb, transaction, objName, user, newField, pr, userType, objType,
|
||||
newOptions, grantorRevoker);
|
||||
}
|
||||
}
|
||||
else
|
||||
badGrantor = true;
|
||||
@ -11588,14 +11643,25 @@ void GrantRevokeNode::grantRevoke(thread_db* tdbb, jrd_tra* transaction, const G
|
||||
((objType == obj_sql_role) && (PRIV.RDB$PRIVILEGE[0] == 'M') && // This is ROLE to USER grant
|
||||
(currentUser != user) && // And current user does not revoke his own grant
|
||||
((isItSqlRole(tdbb, transaction, objName, owner) && // Pick up role owner name
|
||||
(tdbb->getAttachment()->locksmith(tdbb, GRANT_REVOKE_ON_ANY_OBJECT) || // God-like check
|
||||
(attachment->locksmith(tdbb, GRANT_REVOKE_ON_ANY_OBJECT) || // God-like check
|
||||
(owner == currentUser))) || // Current user is role owner
|
||||
(getGrantorOption(tdbb, transaction, currentUser, obj_user, objName) == 2)))) // or has ADMIN option
|
||||
{
|
||||
curOptions = PRIV.RDB$GRANT_OPTION;
|
||||
curField = PRIV.RDB$FIELD_NAME;
|
||||
MetaName newField = NULL;
|
||||
int newOptions = 0;
|
||||
if (!revokeGrantOption && !PRIV.RDB$GRANT_OPTION.NULL)
|
||||
newOptions = PRIV.RDB$GRANT_OPTION;
|
||||
if (!revokeDefaultRole && !PRIV.RDB$FIELD_NAME.NULL)
|
||||
newField = PRIV.RDB$FIELD_NAME;
|
||||
|
||||
ERASE PRIV;
|
||||
grantErased = true;
|
||||
|
||||
if (revokeDefaultRole || revokeGrantOption)
|
||||
{
|
||||
storePrivilege(tdbb, transaction, objName, user, newField, pr, userType, objType,
|
||||
newOptions, grantorRevoker);
|
||||
}
|
||||
}
|
||||
else
|
||||
badGrantor = true;
|
||||
@ -11603,25 +11669,7 @@ void GrantRevokeNode::grantRevoke(thread_db* tdbb, jrd_tra* transaction, const G
|
||||
END_FOR
|
||||
}
|
||||
|
||||
if (grantErased)
|
||||
{
|
||||
if (revokeRoleDefault)
|
||||
{
|
||||
// Add role grant again without default
|
||||
storePrivilege(tdbb, transaction, objName, user, NULL, pr, userType, objType,
|
||||
curOptions, grantorRevoker);
|
||||
}
|
||||
else if (options)
|
||||
{
|
||||
// Add the privilege without the grant option. There is a modify trigger on the
|
||||
// rdb$user_privileges which disallows the table from being updated. It would have
|
||||
// to be changed such that only the grant_option field can be updated.
|
||||
|
||||
storePrivilege(tdbb, transaction, objName, user, curField, pr, userType, objType,
|
||||
0, grantorRevoker);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (!grantErased)
|
||||
{
|
||||
if (badGrantor)
|
||||
{
|
||||
@ -11641,7 +11689,7 @@ void GrantRevokeNode::grantRevoke(thread_db* tdbb, jrd_tra* transaction, const G
|
||||
}
|
||||
|
||||
// Check if the grantor has grant privilege on the relation/field.
|
||||
void GrantRevokeNode::checkGrantorCanGrant(thread_db* tdbb, jrd_tra* transaction,
|
||||
void GrantRevokeNode::checkGrantorCanGrantRelation(thread_db* tdbb, jrd_tra* transaction,
|
||||
const char* grantor, const char* privilege, const MetaName& relationName,
|
||||
const MetaName& fieldName, bool topLevel)
|
||||
{
|
||||
@ -11825,13 +11873,13 @@ void GrantRevokeNode::checkGrantorCanGrant(thread_db* tdbb, jrd_tra* transaction
|
||||
{
|
||||
if (fieldName == G_FLD.RDB$FIELD_NAME)
|
||||
{
|
||||
checkGrantorCanGrant(tdbb, transaction, grantor, privilege,
|
||||
checkGrantorCanGrantRelation(tdbb, transaction, grantor, privilege,
|
||||
G_VIEW.RDB$RELATION_NAME, G_FLD.RDB$BASE_FIELD, false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
checkGrantorCanGrant(tdbb, transaction, grantor, privilege,
|
||||
checkGrantorCanGrantRelation(tdbb, transaction, grantor, privilege,
|
||||
G_VIEW.RDB$RELATION_NAME, G_FLD.RDB$BASE_FIELD, false);
|
||||
}
|
||||
}
|
||||
@ -11919,7 +11967,9 @@ void GrantRevokeNode::checkGrantorCanGrantRole(thread_db* tdbb, jrd_tra* transac
|
||||
void GrantRevokeNode::checkGrantorCanGrantDdl(thread_db* tdbb, jrd_tra* transaction,
|
||||
const MetaName& grantor, const char* privilege, const MetaName& objName)
|
||||
{
|
||||
if (tdbb->getAttachment()->locksmith(tdbb, GRANT_REVOKE_ANY_DDL_RIGHT))
|
||||
const Attachment* attachment = tdbb->getAttachment();
|
||||
|
||||
if (attachment->locksmith(tdbb, GRANT_REVOKE_ANY_DDL_RIGHT))
|
||||
return;
|
||||
|
||||
AutoCacheRequest request(tdbb, drq_l_grant_option, DYN_REQUESTS);
|
||||
@ -11927,23 +11977,62 @@ void GrantRevokeNode::checkGrantorCanGrantDdl(thread_db* tdbb, jrd_tra* transact
|
||||
|
||||
FOR (REQUEST_HANDLE request TRANSACTION_HANDLE transaction)
|
||||
PRV IN RDB$USER_PRIVILEGES
|
||||
WITH PRV.RDB$USER = UPPERCASE(grantor.c_str()) AND
|
||||
PRV.RDB$USER_TYPE = obj_user 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$RELATION_NAME EQ objName.c_str() AND
|
||||
PRV.RDB$OBJECT_TYPE >= obj_database AND
|
||||
PRV.RDB$PRIVILEGE EQ privilege
|
||||
{
|
||||
grantable = PRV.RDB$GRANT_OPTION == WITH_GRANT_OPTION;
|
||||
if ( (PRV.RDB$USER_TYPE == obj_sql_role) && !attachment->att_user->roleInUse(tdbb, PRV.RDB$USER))
|
||||
continue;
|
||||
if (PRV.RDB$GRANT_OPTION == WITH_GRANT_OPTION)
|
||||
grantable = true;
|
||||
}
|
||||
END_FOR
|
||||
|
||||
if (!grantable)
|
||||
{
|
||||
// no .. privilege with grant option on DDL ..
|
||||
status_exception::raise(Arg::PrivateDyn(174) << privilege << objName.c_str());
|
||||
// no @1 privilege with grant option on DDL @2
|
||||
status_exception::raise(Arg::PrivateDyn(299) << privilege << objName.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Check if the grantor has grant option on generator privilege
|
||||
void GrantRevokeNode::checkGrantorCanGrantObject(thread_db* tdbb, jrd_tra* transaction, const char* grantor,
|
||||
const char* privilege, const Firebird::MetaName& objName, SSHORT objType)
|
||||
{
|
||||
const Attachment* attachment = tdbb->getAttachment();
|
||||
|
||||
if (attachment->locksmith(tdbb, GRANT_REVOKE_ON_ANY_OBJECT))
|
||||
return;
|
||||
|
||||
AutoCacheRequest request(tdbb, drq_l_grant_object, DYN_REQUESTS);
|
||||
bool grantable = false;
|
||||
|
||||
FOR (REQUEST_HANDLE request TRANSACTION_HANDLE transaction)
|
||||
PRV IN RDB$USER_PRIVILEGES
|
||||
WITH ((PRV.RDB$USER = UPPERCASE(grantor) AND
|
||||
PRV.RDB$USER_TYPE = obj_user) OR (PRV.RDB$USER_TYPE = obj_sql_role)) AND
|
||||
PRV.RDB$RELATION_NAME EQ objName.c_str() AND
|
||||
PRV.RDB$OBJECT_TYPE = objType AND
|
||||
PRV.RDB$PRIVILEGE EQ privilege
|
||||
{
|
||||
if ( (PRV.RDB$USER_TYPE == obj_sql_role) && !attachment->att_user->roleInUse(tdbb, PRV.RDB$USER))
|
||||
continue;
|
||||
if (PRV.RDB$GRANT_OPTION == WITH_GRANT_OPTION)
|
||||
grantable = true;
|
||||
}
|
||||
END_FOR
|
||||
|
||||
if (!grantable)
|
||||
{
|
||||
// no @1 privilege with grant option on object @2
|
||||
status_exception::raise(Arg::PrivateDyn(300) << privilege << objName.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GrantRevokeNode::storePrivilege(thread_db* tdbb, jrd_tra* transaction, const MetaName& object,
|
||||
const MetaName& user, const MetaName& field, const TEXT* privilege, SSHORT userType,
|
||||
SSHORT objType, int option, const MetaName& grantor)
|
||||
|
@ -2269,13 +2269,15 @@ private:
|
||||
void modifyPrivileges(thread_db* tdbb, jrd_tra* transaction, SSHORT option, const GranteeClause* user);
|
||||
void grantRevoke(thread_db* tdbb, jrd_tra* transaction, const GranteeClause* object,
|
||||
const GranteeClause* userNod, const char* privs, Firebird::MetaName field, int options);
|
||||
static void checkGrantorCanGrant(thread_db* tdbb, jrd_tra* transaction, const char* grantor,
|
||||
static void checkGrantorCanGrantRelation(thread_db* tdbb, jrd_tra* transaction, const char* grantor,
|
||||
const char* privilege, const Firebird::MetaName& relationName,
|
||||
const Firebird::MetaName& fieldName, bool topLevel);
|
||||
static void checkGrantorCanGrantRole(thread_db* tdbb, jrd_tra* transaction,
|
||||
const Firebird::MetaName& grantor, const Firebird::MetaName& roleName);
|
||||
static void checkGrantorCanGrantDdl(thread_db* tdbb, jrd_tra* transaction,
|
||||
const Firebird::MetaName& grantor, const char* privilege, const Firebird::MetaName& objName);
|
||||
static void checkGrantorCanGrantObject(thread_db* tdbb, jrd_tra* transaction, const char* grantor,
|
||||
const char* privilege, const Firebird::MetaName& objName, SSHORT objType);
|
||||
static void storePrivilege(thread_db* tdbb, jrd_tra* transaction,
|
||||
const Firebird::MetaName& object, const Firebird::MetaName& user,
|
||||
const Firebird::MetaName& field, const TEXT* privilege, SSHORT userType,
|
||||
|
@ -87,12 +87,6 @@ DsqlBatch::DsqlBatch(dsql_req* req, const dsql_msg* /*message*/, IMessageMetadat
|
||||
m_alignment = m_meta->getAlignment(&st);
|
||||
check(&st);
|
||||
|
||||
if (m_messageSize > RAM_BATCH) // hops - message does not fit in our buffer
|
||||
{
|
||||
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-104) <<
|
||||
Arg::Gds(isc_batch_msg_long) << Arg::Num(m_messageSize) << Arg::Num(RAM_BATCH));
|
||||
}
|
||||
|
||||
for (pb.rewind(); !pb.isEof(); pb.moveNext())
|
||||
{
|
||||
UCHAR t = pb.getClumpTag();
|
||||
@ -146,7 +140,6 @@ DsqlBatch::DsqlBatch(dsql_req* req, const dsql_msg* /*message*/, IMessageMetadat
|
||||
switch (t)
|
||||
{
|
||||
case SQL_BLOB:
|
||||
case SQL_ARRAY:
|
||||
{
|
||||
BlobMeta bm;
|
||||
bm.offset = m_meta->getOffset(&st, i);
|
||||
@ -160,9 +153,9 @@ DsqlBatch::DsqlBatch(dsql_req* req, const dsql_msg* /*message*/, IMessageMetadat
|
||||
}
|
||||
|
||||
// allocate data buffers
|
||||
m_messages.setBuf(m_bufferSize);
|
||||
m_messages.setBuf(m_bufferSize, MAX(m_alignedMessage * 2, RAM_BATCH));
|
||||
if (m_blobMeta.hasData())
|
||||
m_blobs.setBuf(m_bufferSize);
|
||||
m_blobs.setBuf(m_bufferSize, RAM_BATCH);
|
||||
|
||||
// assign initial default BPB
|
||||
setDefBpb(FB_NELEM(initBlobParameters), initBlobParameters);
|
||||
@ -270,6 +263,7 @@ void DsqlBatch::add(thread_db* tdbb, ULONG count, const void* inBuffer)
|
||||
return;
|
||||
m_messages.align(m_alignment);
|
||||
m_messages.put(inBuffer, (count - 1) * m_alignedMessage + m_messageSize);
|
||||
DEB_BATCH(fprintf(stderr, "Put to batch %d messages\n", count));
|
||||
}
|
||||
|
||||
void DsqlBatch::blobCheckMeta()
|
||||
@ -419,6 +413,7 @@ void DsqlBatch::addBlobStream(thread_db* tdbb, unsigned length, const void* inBu
|
||||
m_lastBlob = MAX_ULONG;
|
||||
|
||||
// store stream for further processing
|
||||
DEB_BATCH(fprintf(stderr, "Store stream %d\n", length));
|
||||
fb_assert(m_blobs.getSize() % BLOB_STREAM_ALIGN == 0);
|
||||
m_blobs.put(inBuffer, length);
|
||||
}
|
||||
@ -539,13 +534,13 @@ private:
|
||||
|
||||
// parse blob header
|
||||
fb_assert(intptr_t(flow.data) % BLOB_STREAM_ALIGN == 0);
|
||||
ISC_QUAD* batchBlobId = reinterpret_cast<ISC_QUAD*>(flow.data);
|
||||
ISC_QUAD batchBlobId = *reinterpret_cast<ISC_QUAD*>(flow.data);
|
||||
ULONG* blobSize = reinterpret_cast<ULONG*>(flow.data + sizeof(ISC_QUAD));
|
||||
ULONG* bpbSize = reinterpret_cast<ULONG*>(flow.data + sizeof(ISC_QUAD) + sizeof(ULONG));
|
||||
flow.newHdr(*blobSize);
|
||||
ULONG currentBpbSize = *bpbSize;
|
||||
|
||||
if (batchBlobId->gds_quad_high == 0 && batchBlobId->gds_quad_low == 0)
|
||||
if (batchBlobId.gds_quad_high == 0 && batchBlobId.gds_quad_low == 0)
|
||||
{
|
||||
// Sanity check
|
||||
if (*bpbSize)
|
||||
@ -591,7 +586,9 @@ private:
|
||||
bid engineBlobId;
|
||||
blob = blb::create2(tdbb, transaction, &engineBlobId, bpb->getCount(),
|
||||
bpb->begin(), true);
|
||||
registerBlob(reinterpret_cast<ISC_QUAD*>(&engineBlobId), batchBlobId);
|
||||
|
||||
//DEB_BATCH(fprintf(stderr, "B-ID: (%x,%x)\n", batchBlobId.gds_quad_high, batchBlobId.gds_quad_low));
|
||||
registerBlob(reinterpret_cast<ISC_QUAD*>(&engineBlobId), &batchBlobId);
|
||||
}
|
||||
}
|
||||
|
||||
@ -657,7 +654,7 @@ private:
|
||||
fb_assert(req);
|
||||
|
||||
// prepare completion interface
|
||||
AutoPtr<BatchCompletionState, SimpleDispose<BatchCompletionState> > completionState
|
||||
AutoPtr<BatchCompletionState, SimpleDispose> completionState
|
||||
(FB_NEW BatchCompletionState(m_flags & (1 << IBatch::TAG_RECORD_COUNTS), m_detailed));
|
||||
AutoSetRestore<bool> batchFlag(&req->req_batch, true);
|
||||
const dsql_msg* message = m_request->getStatement()->getSendMsg();
|
||||
@ -702,6 +699,9 @@ private:
|
||||
continue;
|
||||
|
||||
ISC_QUAD* id = reinterpret_cast<ISC_QUAD*>(&data[m_blobMeta[i].offset]);
|
||||
if (id->gds_quad_high == 0 && id->gds_quad_low == 0)
|
||||
continue;
|
||||
|
||||
ISC_QUAD newId;
|
||||
if (!m_blobMap.get(*id, newId))
|
||||
{
|
||||
@ -719,9 +719,9 @@ private:
|
||||
remains -= m_messageSize;
|
||||
|
||||
UCHAR* msgBuffer = m_request->req_msg_buffers[message->msg_buffer_number];
|
||||
DEB_BATCH(fprintf(stderr, "\n\n+++ Send\n\n"));
|
||||
try
|
||||
{
|
||||
// runsend data to request and collect stats
|
||||
ULONG before = req->req_records_inserted + req->req_records_updated +
|
||||
req->req_records_deleted;
|
||||
EXE_send(tdbb, req, message->msg_number, message->msg_length, msgBuffer);
|
||||
@ -753,6 +753,15 @@ private:
|
||||
m_messages.remained(remains, alignedData - data);
|
||||
}
|
||||
|
||||
DEB_BATCH(fprintf(stderr, "Sent %d messages\n", completionState->getSize(tdbb->tdbb_status_vector)));
|
||||
|
||||
// make sure all blobs were used in messages
|
||||
if (m_blobMap.count())
|
||||
{
|
||||
DEB_BATCH(fprintf(stderr, "BLOBs %d were not used in messages\n", m_blobMap.count()));
|
||||
ERR_post_warning(Arg::Warning(isc_random) << "m_blobMap.count() BLOBs were not used in messages"); // !!!!!!! new warning
|
||||
}
|
||||
|
||||
// reset to initial state
|
||||
cancel(tdbb);
|
||||
|
||||
@ -762,14 +771,11 @@ private:
|
||||
void DsqlBatch::cancel(thread_db* tdbb)
|
||||
{
|
||||
m_messages.clear();
|
||||
if (m_blobMeta.hasData())
|
||||
{
|
||||
m_blobs.clear();
|
||||
m_setBlobSize = false;
|
||||
m_lastBlob = MAX_ULONG;
|
||||
memset(&m_genId, 0, sizeof(m_genId));
|
||||
m_blobMap.clear();
|
||||
}
|
||||
m_blobs.clear();
|
||||
m_setBlobSize = false;
|
||||
m_lastBlob = MAX_ULONG;
|
||||
memset(&m_genId, 0, sizeof(m_genId));
|
||||
m_blobMap.clear();
|
||||
}
|
||||
|
||||
void DsqlBatch::genBlobId(ISC_QUAD* blobId)
|
||||
@ -779,13 +785,13 @@ void DsqlBatch::genBlobId(ISC_QUAD* blobId)
|
||||
memcpy(blobId, &m_genId, sizeof(m_genId));
|
||||
}
|
||||
|
||||
void DsqlBatch::DataCache::setBuf(ULONG size)
|
||||
void DsqlBatch::DataCache::setBuf(ULONG size, ULONG cacheCapacity)
|
||||
{
|
||||
m_limit = size;
|
||||
|
||||
// create ram cache
|
||||
fb_assert(!m_cache);
|
||||
m_cache = FB_NEW_POOL(getPool()) Cache;
|
||||
fb_assert(m_cacheCapacity == 0);
|
||||
fb_assert(cacheCapacity >= RAM_BATCH);
|
||||
m_cacheCapacity = cacheCapacity;
|
||||
}
|
||||
|
||||
void DsqlBatch::DataCache::put3(const void* data, ULONG dataSize, ULONG offset)
|
||||
@ -797,9 +803,9 @@ void DsqlBatch::DataCache::put3(const void* data, ULONG dataSize, ULONG offset)
|
||||
if (offset >= m_used)
|
||||
{
|
||||
// data in cache
|
||||
UCHAR* to = m_cache->begin();
|
||||
UCHAR* to = m_cache.begin();
|
||||
to += (offset - m_used);
|
||||
fb_assert(to < m_cache->end());
|
||||
fb_assert(to < m_cache.end());
|
||||
memcpy(to, data, dataSize);
|
||||
}
|
||||
else
|
||||
@ -811,7 +817,7 @@ void DsqlBatch::DataCache::put3(const void* data, ULONG dataSize, ULONG offset)
|
||||
|
||||
void DsqlBatch::DataCache::put(const void* d, ULONG dataSize)
|
||||
{
|
||||
if (m_used + (m_cache ? m_cache->getCount() : 0) + dataSize > m_limit)
|
||||
if (m_limit && (m_used + m_cache.getCount() + dataSize > m_limit))
|
||||
{
|
||||
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-104) <<
|
||||
Arg::Gds(isc_batch_too_big));
|
||||
@ -823,17 +829,17 @@ void DsqlBatch::DataCache::put(const void* d, ULONG dataSize)
|
||||
const ULONG K = 4;
|
||||
|
||||
// ensure ram cache presence
|
||||
fb_assert(m_cache);
|
||||
fb_assert(m_cacheCapacity);
|
||||
|
||||
// swap to secondary cache if needed
|
||||
if (m_cache->getCount() + dataSize > m_cache->getCapacity())
|
||||
if (m_cache.getCount() + dataSize > m_cacheCapacity)
|
||||
{
|
||||
// store data in the end of ram cache if needed
|
||||
// avoid copy in case of huge buffer passed
|
||||
ULONG delta = m_cache->getCapacity() - m_cache->getCount();
|
||||
if (dataSize - delta < m_cache->getCapacity() / K)
|
||||
ULONG delta = m_cacheCapacity - m_cache.getCount();
|
||||
if (dataSize - delta < m_cacheCapacity / K)
|
||||
{
|
||||
m_cache->append(data, delta);
|
||||
m_cache.append(data, delta);
|
||||
data += delta;
|
||||
dataSize -= delta;
|
||||
}
|
||||
@ -842,13 +848,13 @@ void DsqlBatch::DataCache::put(const void* d, ULONG dataSize)
|
||||
if (!m_space)
|
||||
m_space = FB_NEW_POOL(getPool()) TempSpace(getPool(), TEMP_NAME);
|
||||
|
||||
const FB_UINT64 writtenBytes = m_space->write(m_used, m_cache->begin(), m_cache->getCount());
|
||||
fb_assert(writtenBytes == m_cache->getCount());
|
||||
m_used += m_cache->getCount();
|
||||
m_cache->clear();
|
||||
const FB_UINT64 writtenBytes = m_space->write(m_used, m_cache.begin(), m_cache.getCount());
|
||||
fb_assert(writtenBytes == m_cache.getCount());
|
||||
m_used += m_cache.getCount();
|
||||
m_cache.clear();
|
||||
|
||||
// in a case of huge buffer write directly to tempspace
|
||||
if (dataSize > m_cache->getCapacity() / K)
|
||||
if (dataSize > m_cacheCapacity / K)
|
||||
{
|
||||
const FB_UINT64 writtenBytes = m_space->write(m_used, data, dataSize);
|
||||
fb_assert(writtenBytes == dataSize);
|
||||
@ -857,7 +863,7 @@ void DsqlBatch::DataCache::put(const void* d, ULONG dataSize)
|
||||
}
|
||||
}
|
||||
|
||||
m_cache->append(data, dataSize);
|
||||
m_cache.append(data, dataSize);
|
||||
}
|
||||
|
||||
void DsqlBatch::DataCache::align(ULONG alignment)
|
||||
@ -873,16 +879,14 @@ void DsqlBatch::DataCache::align(ULONG alignment)
|
||||
|
||||
void DsqlBatch::DataCache::done()
|
||||
{
|
||||
fb_assert(m_cache);
|
||||
|
||||
if (m_cache->getCount() && m_used)
|
||||
if (m_cache.getCount() && m_used)
|
||||
{
|
||||
fb_assert(m_space);
|
||||
|
||||
const FB_UINT64 writtenBytes = m_space->write(m_used, m_cache->begin(), m_cache->getCount());
|
||||
fb_assert(writtenBytes == m_cache->getCount());
|
||||
m_used += m_cache->getCount();
|
||||
m_cache->clear();
|
||||
const FB_UINT64 writtenBytes = m_space->write(m_used, m_cache.begin(), m_cache.getCount());
|
||||
fb_assert(writtenBytes == m_cache.getCount());
|
||||
m_used += m_cache.getCount();
|
||||
m_cache.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@ -891,26 +895,26 @@ ULONG DsqlBatch::DataCache::get(UCHAR** buffer)
|
||||
if (m_used > m_got)
|
||||
{
|
||||
// get data from tempspace
|
||||
ULONG dlen = m_cache->getCount();
|
||||
ULONG delta = m_cache->getCapacity() - dlen;
|
||||
ULONG dlen = m_cache.getCount();
|
||||
ULONG delta = m_cacheCapacity - dlen;
|
||||
if (delta > m_used - m_got)
|
||||
delta = m_used - m_got;
|
||||
UCHAR* buf = m_cache->getBuffer(dlen + delta);
|
||||
UCHAR* buf = m_cache.getBuffer(dlen + delta);
|
||||
buf += dlen;
|
||||
const FB_UINT64 readBytes = m_space->read(m_got, buf, delta);
|
||||
fb_assert(readBytes == delta);
|
||||
m_got += delta;
|
||||
}
|
||||
|
||||
if (m_cache->getCount())
|
||||
if (m_cache.getCount())
|
||||
{
|
||||
if (m_shift)
|
||||
m_cache->removeCount(0, m_shift);
|
||||
m_cache.removeCount(0, m_shift);
|
||||
|
||||
// return buffer full of data
|
||||
*buffer = m_cache->begin();
|
||||
*buffer = m_cache.begin();
|
||||
fb_assert(intptr_t(*buffer) % FB_ALIGNMENT == 0);
|
||||
return m_cache->getCount();
|
||||
return m_cache.getCount();
|
||||
}
|
||||
|
||||
// no more data
|
||||
@ -926,9 +930,9 @@ ULONG DsqlBatch::DataCache::reget(ULONG remains, UCHAR** buffer, ULONG alignment
|
||||
a = alignment - a;
|
||||
remains += a;
|
||||
}
|
||||
fb_assert(remains < m_cache->getCount());
|
||||
fb_assert(remains < m_cache.getCount());
|
||||
|
||||
m_cache->removeCount(0, m_cache->getCount() - remains);
|
||||
m_cache.removeCount(0, m_cache.getCount() - remains);
|
||||
ULONG size = get(buffer);
|
||||
size -= a;
|
||||
*buffer += a;
|
||||
@ -949,25 +953,25 @@ void DsqlBatch::DataCache::remained(ULONG size, ULONG alignment)
|
||||
}
|
||||
|
||||
if (!size)
|
||||
m_cache->clear();
|
||||
m_cache.clear();
|
||||
else
|
||||
m_cache->removeCount(0, m_cache->getCount() - size);
|
||||
m_cache.removeCount(0, m_cache.getCount() - size);
|
||||
|
||||
m_shift = alignment;
|
||||
}
|
||||
|
||||
ULONG DsqlBatch::DataCache::getSize() const
|
||||
{
|
||||
if(!m_cache)
|
||||
if (!m_cacheCapacity)
|
||||
return 0;
|
||||
|
||||
fb_assert((MAX_ULONG - 1) - m_used > m_cache->getCount());
|
||||
return m_used + m_cache->getCount();
|
||||
fb_assert((MAX_ULONG - 1) - m_used > m_cache.getCount());
|
||||
return m_used + m_cache.getCount();
|
||||
}
|
||||
|
||||
void DsqlBatch::DataCache::clear()
|
||||
{
|
||||
m_cache->clear();
|
||||
m_cache.clear();
|
||||
if (m_space && m_used)
|
||||
m_space->releaseSpace(0, m_used);
|
||||
m_used = m_got = m_shift = 0;
|
||||
|
@ -107,11 +107,11 @@ private:
|
||||
{
|
||||
public:
|
||||
DataCache(MemoryPool& p)
|
||||
: PermanentStorage(p),
|
||||
m_used(0), m_got(0), m_limit(0), m_shift(0)
|
||||
: PermanentStorage(p), m_cache(getPool()),
|
||||
m_used(0), m_got(0), m_limit(0), m_shift(0), m_cacheCapacity(0)
|
||||
{ }
|
||||
|
||||
void setBuf(ULONG size);
|
||||
void setBuf(ULONG size, ULONG cacheCapacity);
|
||||
|
||||
void put(const void* data, ULONG dataSize);
|
||||
void put3(const void* data, ULONG dataSize, ULONG offset);
|
||||
@ -124,10 +124,10 @@ private:
|
||||
void clear();
|
||||
|
||||
private:
|
||||
typedef Firebird::Vector<UCHAR, DsqlBatch::RAM_BATCH, SINT64> Cache;
|
||||
Firebird::AutoPtr<Cache> m_cache;
|
||||
typedef Firebird::Array<UCHAR> Cache;
|
||||
Cache m_cache;
|
||||
Firebird::AutoPtr<TempSpace> m_space;
|
||||
ULONG m_used, m_got, m_limit, m_shift;
|
||||
ULONG m_used, m_got, m_limit, m_shift, m_cacheCapacity;
|
||||
};
|
||||
|
||||
struct BlobMeta
|
||||
|
@ -1397,18 +1397,6 @@ void ArithmeticNode::getDescDialect1(thread_db* /*tdbb*/, dsc* desc, dsc& desc1,
|
||||
break;
|
||||
|
||||
case blr_divide:
|
||||
/***
|
||||
if (desc1.isDecOrInt() && desc2.isDecOrInt())
|
||||
{
|
||||
desc->dsc_dtype = dtype_dec128;
|
||||
desc->dsc_length = sizeof(Decimal128);
|
||||
desc->dsc_scale = 0;
|
||||
desc->dsc_sub_type = 0;
|
||||
desc->dsc_flags = 0;
|
||||
return;
|
||||
}
|
||||
***/
|
||||
|
||||
// for compatibility with older versions of the product, we accept
|
||||
// text types for division in blr_version4 (dialect <= 1) only
|
||||
if (!(DTYPE_IS_NUMERIC(desc1.dsc_dtype) || DTYPE_IS_TEXT(desc1.dsc_dtype)))
|
||||
@ -7342,7 +7330,15 @@ bool LiteralNode::sameAs(CompilerScratch* csb, const ExprNode* other, bool ignor
|
||||
fb_assert(otherNode);
|
||||
thread_db* tdbb = JRD_get_thread_data();
|
||||
|
||||
return !MOV_compare(tdbb, &litDesc, &otherNode->litDesc);
|
||||
try
|
||||
{
|
||||
return MOV_compare(tdbb, &litDesc, &otherNode->litDesc) == 0;
|
||||
}
|
||||
catch (const status_exception&)
|
||||
{
|
||||
fb_utils::init_status(tdbb->tdbb_status_vector);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
ValueExprNode* LiteralNode::pass2(thread_db* tdbb, CompilerScratch* csb)
|
||||
|
@ -329,17 +329,12 @@ bool Parser::yylexSkipSpaces()
|
||||
if (lex.ptr >= lex.end)
|
||||
return false;
|
||||
|
||||
c = *lex.ptr++;
|
||||
if (yylexSkipEol())
|
||||
continue;
|
||||
|
||||
// Process comments
|
||||
|
||||
if (c == '\n')
|
||||
{
|
||||
lex.lines++;
|
||||
lex.line_start = lex.ptr;
|
||||
continue;
|
||||
}
|
||||
|
||||
c = *lex.ptr++;
|
||||
if (c == '-' && lex.ptr < lex.end && *lex.ptr == '-')
|
||||
{
|
||||
// single-line
|
||||
@ -347,12 +342,9 @@ bool Parser::yylexSkipSpaces()
|
||||
lex.ptr++;
|
||||
while (lex.ptr < lex.end)
|
||||
{
|
||||
if ((c = *lex.ptr++) == '\n')
|
||||
{
|
||||
lex.lines++;
|
||||
lex.line_start = lex.ptr; // + 1; // CVC: +1 left out.
|
||||
if (yylexSkipEol())
|
||||
break;
|
||||
}
|
||||
lex.ptr++;
|
||||
}
|
||||
if (lex.ptr >= lex.end)
|
||||
return false;
|
||||
@ -367,17 +359,14 @@ bool Parser::yylexSkipSpaces()
|
||||
lex.ptr++;
|
||||
while (lex.ptr < lex.end)
|
||||
{
|
||||
if (yylexSkipEol())
|
||||
continue;
|
||||
|
||||
if ((c = *lex.ptr++) == '*')
|
||||
{
|
||||
if (*lex.ptr == '/')
|
||||
break;
|
||||
}
|
||||
if (c == '\n')
|
||||
{
|
||||
lex.lines++;
|
||||
lex.line_start = lex.ptr; // + 1; // CVC: +1 left out.
|
||||
|
||||
}
|
||||
}
|
||||
if (lex.ptr >= lex.end)
|
||||
{
|
||||
@ -401,6 +390,35 @@ bool Parser::yylexSkipSpaces()
|
||||
}
|
||||
|
||||
|
||||
bool Parser::yylexSkipEol()
|
||||
{
|
||||
bool eol = false;
|
||||
const TEXT c = *lex.ptr;
|
||||
|
||||
if (c == '\r')
|
||||
{
|
||||
lex.ptr++;
|
||||
if (lex.ptr < lex.end && *lex.ptr == '\n')
|
||||
lex.ptr++;
|
||||
|
||||
eol = true;
|
||||
}
|
||||
else if (c == '\n')
|
||||
{
|
||||
lex.ptr++;
|
||||
eol = true;
|
||||
}
|
||||
|
||||
if (eol)
|
||||
{
|
||||
lex.lines++;
|
||||
lex.line_start = lex.ptr; // + 1; // CVC: +1 left out.
|
||||
}
|
||||
|
||||
return eol;
|
||||
}
|
||||
|
||||
|
||||
int Parser::yylexAux()
|
||||
{
|
||||
thread_db* tdbb = JRD_get_thread_data();
|
||||
|
@ -241,6 +241,7 @@ private:
|
||||
|
||||
int yylex();
|
||||
bool yylexSkipSpaces();
|
||||
bool yylexSkipEol(); // returns true if EOL is detected and skipped
|
||||
int yylexAux();
|
||||
|
||||
void yyerror(const TEXT* error_string);
|
||||
@ -271,7 +272,7 @@ private:
|
||||
clause = value;
|
||||
}
|
||||
|
||||
template <typename T, typename Delete>
|
||||
template <typename T, template <typename C> class Delete>
|
||||
void setClause(Firebird::AutoPtr<T, Delete>& clause, const char* duplicateMsg, T* value)
|
||||
{
|
||||
checkDuplicateClause(clause, duplicateMsg);
|
||||
|
@ -1241,10 +1241,14 @@ const StmtNode* CursorStmtNode::execute(thread_db* tdbb, jrd_req* request, ExeSt
|
||||
|
||||
static RegisterNode<DeclareCursorNode> regDeclareCursorNode(blr_dcl_cursor);
|
||||
|
||||
DmlNode* DeclareCursorNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR /*blrOp*/)
|
||||
DmlNode* DeclareCursorNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp)
|
||||
{
|
||||
DeclareCursorNode* node = FB_NEW_POOL(pool) DeclareCursorNode(pool);
|
||||
|
||||
fb_assert(blrOp == blr_dcl_cursor);
|
||||
if (blrOp == blr_dcl_cursor)
|
||||
node->dsqlCursorType = CUR_TYPE_EXPLICIT;
|
||||
|
||||
node->cursorNumber = csb->csb_blr_reader.getWord();
|
||||
node->rse = PAR_rse(tdbb, csb);
|
||||
|
||||
@ -1349,11 +1353,14 @@ DeclareCursorNode* DeclareCursorNode::pass2(thread_db* tdbb, CompilerScratch* cs
|
||||
|
||||
// Activate cursor streams to allow index usage for <cursor>.<field> references, see CORE-4675.
|
||||
// It's also useful for correlated sub-queries in the select list, see CORE-4379.
|
||||
// Mark cursor streams as unstable, see CORE-5773.
|
||||
|
||||
for (StreamList::const_iterator i = cursorStreams.begin(); i != cursorStreams.end(); ++i)
|
||||
{
|
||||
csb->csb_rpt[*i].csb_cursor_number = cursorNumber;
|
||||
csb->csb_rpt[*i].activate();
|
||||
if (dsqlCursorType == CUR_TYPE_EXPLICIT)
|
||||
csb->csb_rpt[*i].csb_flags |= csb_unstable;
|
||||
}
|
||||
|
||||
return this;
|
||||
@ -8087,6 +8094,17 @@ void SetTransactionNode::genTableLock(DsqlCompilerScratch* dsqlScratch,
|
||||
//--------------------
|
||||
|
||||
|
||||
void SessionResetNode::execute(thread_db* tdbb, dsql_req* request) const
|
||||
{
|
||||
SET_TDBB(tdbb);
|
||||
Attachment* const attachment = tdbb->getAttachment();
|
||||
attachment->resetSession(tdbb);
|
||||
}
|
||||
|
||||
|
||||
//--------------------
|
||||
|
||||
|
||||
void SetRoleNode::execute(thread_db* tdbb, dsql_req* request) const
|
||||
{
|
||||
SET_TDBB(tdbb);
|
||||
|
@ -1569,6 +1569,26 @@ public:
|
||||
};
|
||||
|
||||
|
||||
class SessionResetNode : public SessionManagementNode
|
||||
{
|
||||
public:
|
||||
explicit SessionResetNode(MemoryPool& pool)
|
||||
: SessionManagementNode(pool)
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
virtual Firebird::string internalPrint(NodePrinter& printer) const
|
||||
{
|
||||
SessionManagementNode::internalPrint(printer);
|
||||
|
||||
return "SessionResetNode";
|
||||
}
|
||||
|
||||
virtual void execute(thread_db* tdbb, dsql_req* request) const;
|
||||
};
|
||||
|
||||
|
||||
class SetRoleNode : public SessionManagementNode
|
||||
{
|
||||
public:
|
||||
|
@ -1142,7 +1142,7 @@ void dsql_req::mapInOut(thread_db* tdbb, bool toExternal, const dsql_msg* messag
|
||||
desc.dsc_address = dsql_msg_buf + (IPTR) desc.dsc_address;
|
||||
|
||||
if (notNull)
|
||||
MOVD_move(tdbb, &parDesc, &desc);
|
||||
MOVD_move(tdbb, &parDesc, &desc, toExternal);
|
||||
else
|
||||
memset(desc.dsc_address, 0, desc.dsc_length);
|
||||
}
|
||||
@ -1150,7 +1150,7 @@ void dsql_req::mapInOut(thread_db* tdbb, bool toExternal, const dsql_msg* messag
|
||||
{
|
||||
// Safe cast because desc is used as source only.
|
||||
desc.dsc_address = const_cast<UCHAR*>(in_dsql_msg_buf) + (IPTR) desc.dsc_address;
|
||||
MOVD_move(tdbb, &desc, &parDesc);
|
||||
MOVD_move(tdbb, &desc, &parDesc, toExternal);
|
||||
}
|
||||
else
|
||||
memset(parDesc.dsc_address, 0, parDesc.dsc_length);
|
||||
@ -1185,7 +1185,7 @@ void dsql_req::mapInOut(thread_db* tdbb, bool toExternal, const dsql_msg* messag
|
||||
dsc desc = parameter->par_desc;
|
||||
desc.dsc_address = msgBuffer + (IPTR) desc.dsc_address;
|
||||
|
||||
MOVD_move(tdbb, &parentDesc, &desc);
|
||||
MOVD_move(tdbb, &parentDesc, &desc, false);
|
||||
|
||||
dsql_par* null_ind = parameter->par_null;
|
||||
if (null_ind != NULL)
|
||||
@ -1215,7 +1215,7 @@ void dsql_req::mapInOut(thread_db* tdbb, bool toExternal, const dsql_msg* messag
|
||||
dsc desc = parameter->par_desc;
|
||||
desc.dsc_address = msgBuffer + (IPTR) desc.dsc_address;
|
||||
|
||||
MOVD_move(tdbb, &parentDesc, &desc);
|
||||
MOVD_move(tdbb, &parentDesc, &desc, false);
|
||||
|
||||
dsql_par* null_ind = parameter->par_null;
|
||||
if (null_ind != NULL)
|
||||
|
@ -33,11 +33,11 @@ using namespace Firebird;
|
||||
|
||||
|
||||
// Move (and possible convert) something to something else.
|
||||
void MOVD_move(thread_db* tdbb, dsc* from, dsc* to)
|
||||
void MOVD_move(thread_db* tdbb, dsc* from, dsc* to, bool toExternal)
|
||||
{
|
||||
try
|
||||
{
|
||||
MOV_move(tdbb, from, to);
|
||||
MOV_move_ext(tdbb, from, to, toExternal);
|
||||
}
|
||||
catch (const status_exception& ex)
|
||||
{
|
||||
|
@ -24,6 +24,6 @@
|
||||
#ifndef DSQL_MOVD_PROTO_H
|
||||
#define DSQL_MOVD_PROTO_H
|
||||
|
||||
void MOVD_move(Jrd::thread_db* tdbb, dsc*, dsc*);
|
||||
void MOVD_move(Jrd::thread_db* tdbb, dsc*, dsc*, bool toExternal);
|
||||
|
||||
#endif // DSQL_MOVD_PROTO_H
|
||||
|
@ -618,6 +618,7 @@ using namespace Firebird;
|
||||
%token <metaNamePtr> RDB_ERROR
|
||||
%token <metaNamePtr> RDB_ROLE_IN_USE
|
||||
%token <metaNamePtr> RDB_SYSTEM_PRIVILEGE
|
||||
%token <metaNamePtr> RESET
|
||||
%token <metaNamePtr> SECURITY
|
||||
%token <metaNamePtr> SESSION
|
||||
%token <metaNamePtr> SQL
|
||||
@ -784,6 +785,7 @@ using namespace Firebird;
|
||||
Jrd::SetRoundNode* setRoundNode;
|
||||
Jrd::SetTrapsNode* setTrapsNode;
|
||||
Jrd::SetBindNode* setBindNode;
|
||||
Jrd::SessionResetNode* sessionResetNode;
|
||||
}
|
||||
|
||||
%include types.y
|
||||
@ -846,6 +848,7 @@ mng_statement
|
||||
| set_bind { $$ = $1; }
|
||||
| session_statement { $$ = $1; }
|
||||
| set_role { $$ = $1; }
|
||||
| session_reset { $$ = $1; }
|
||||
;
|
||||
|
||||
|
||||
@ -4166,7 +4169,8 @@ keyword_or_column
|
||||
| UPDATING
|
||||
| VAR_SAMP
|
||||
| VAR_POP
|
||||
| UNBOUNDED // added in FB 4.0
|
||||
| DECFLOAT // added in FB 4.0
|
||||
| UNBOUNDED
|
||||
| WINDOW
|
||||
;
|
||||
|
||||
@ -4830,15 +4834,17 @@ varbinary_character_keyword
|
||||
|
||||
%type <legacyField> decfloat_type
|
||||
decfloat_type
|
||||
: DECFLOAT '(' signed_long_integer ')'
|
||||
: DECFLOAT precision_opt_nz
|
||||
{
|
||||
if ($3 != 16 && $3 != 34)
|
||||
yyabandon(YYPOSNARG(3), -842, isc_decprecision_err); // DecFloat precision must be 16 or 34.
|
||||
SLONG precision = $2;
|
||||
|
||||
if (precision != 0 && precision != 16 && precision != 34)
|
||||
yyabandon(YYPOSNARG(2), -842, isc_decprecision_err); // DecFloat precision must be 16 or 34.
|
||||
|
||||
$$ = newNode<dsql_fld>();
|
||||
$$->precision = $3;
|
||||
$$->dtype = $3 == 16 ? dtype_dec64 : dtype_dec128;
|
||||
$$->length = $3 == 16 ? sizeof(Decimal64) : sizeof(Decimal128);
|
||||
$$->precision = precision == 0 ? 34 : (USHORT) precision;
|
||||
$$->dtype = precision == 16 ? dtype_dec64 : dtype_dec128;
|
||||
$$->length = precision == 16 ? sizeof(Decimal64) : sizeof(Decimal128);
|
||||
}
|
||||
;
|
||||
|
||||
@ -5040,6 +5046,12 @@ precision_opt
|
||||
| '(' nonneg_short_integer ')' { $$ = $2; }
|
||||
;
|
||||
|
||||
// alternative to precision_opt that does not allow zero
|
||||
%type <int32Val> precision_opt_nz
|
||||
precision_opt_nz
|
||||
: /* nothing */ { $$ = 0; }
|
||||
| '(' pos_short_integer ')' { $$ = $2; }
|
||||
;
|
||||
|
||||
// transaction statements
|
||||
|
||||
@ -5130,6 +5142,12 @@ set_transaction
|
||||
{ $$ = $3; }
|
||||
;
|
||||
|
||||
%type <sessionResetNode> session_reset
|
||||
session_reset
|
||||
: ALTER SESSION RESET
|
||||
{ $$ = newNode<SessionResetNode>(); }
|
||||
;
|
||||
|
||||
%type <setRoleNode> set_role
|
||||
set_role
|
||||
: SET ROLE valid_symbol_name
|
||||
@ -8513,7 +8531,6 @@ non_reserved_word
|
||||
| BIND // added in FB 4.0
|
||||
| COMPARE_DECFLOAT
|
||||
| CUME_DIST
|
||||
| DECFLOAT
|
||||
| DEFINER
|
||||
| EXCLUDE
|
||||
| FIRST_DAY
|
||||
@ -8532,6 +8549,7 @@ non_reserved_word
|
||||
| PRIVILEGE
|
||||
| QUANTIZE
|
||||
| RANGE
|
||||
| RESET
|
||||
| SECURITY
|
||||
| SESSION
|
||||
| SQL
|
||||
|
@ -1075,10 +1075,9 @@ static void gen_blob_open( const act* action, USHORT column)
|
||||
endp(column);
|
||||
if (gpreGlob.sw_auto)
|
||||
column -= INDENT;
|
||||
set_sqlcode(action, column);
|
||||
if (action->act_type == ACT_blob_create)
|
||||
{
|
||||
printa(column, "if (!SQLCODE)");
|
||||
printa(column, "if (!(%s->getErrors() & Firebird::IStatus::STATE_ERRORS))", global_status_name);
|
||||
align(column + INDENT);
|
||||
fprintf(gpreGlob.out_file, "%s = %s;", reference->ref_value, s);
|
||||
}
|
||||
@ -2235,6 +2234,8 @@ static void gen_finish( const act* action, int column)
|
||||
db = ready->rdy_database;
|
||||
printa(column, "%s->detach(%s);",
|
||||
db->dbb_name->sym_string, status_vector(action));
|
||||
success(column, true, status_vector(action));
|
||||
printa(column + INDENT, "%s = 0;", db->dbb_name->sym_string);
|
||||
}
|
||||
// no hanbdles, so we finish all known databases
|
||||
|
||||
@ -2250,6 +2251,8 @@ static void gen_finish( const act* action, int column)
|
||||
printa(column, "if (%s)", db->dbb_name->sym_string);
|
||||
printa(column + INDENT, "%s->detach(%s);",
|
||||
db->dbb_name->sym_string, status_vector(action));
|
||||
success(column, true, status_vector(action));
|
||||
printa(column + INDENT, "%s = 0;", db->dbb_name->sym_string);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3357,8 +3360,6 @@ static void gen_t_start( const act* action, int column)
|
||||
|
||||
printa(column, "}\t\t// end fbComponents scope\n");
|
||||
}
|
||||
|
||||
set_sqlcode(action, column);
|
||||
}
|
||||
|
||||
|
||||
@ -3435,9 +3436,10 @@ static void gen_trans( const act* action, int column)
|
||||
(action->act_type == ACT_commit) ?
|
||||
"commit" : (action->act_type == ACT_rollback) ? "rollback" : "prepare",
|
||||
status_vector(action));
|
||||
success(column, true, status_vector(action));
|
||||
printa(column + INDENT, "%s = 0;", tranText);
|
||||
break;
|
||||
}
|
||||
|
||||
set_sqlcode(action, column);
|
||||
}
|
||||
|
||||
|
||||
|
@ -347,7 +347,7 @@
|
||||
#define isc_info_svc_capabilities 57 /* Retrieves a bitmask representing the server's capabilities */
|
||||
#define isc_info_svc_user_dbpath 58 /* Retrieves the path to the security database in use by the server */
|
||||
#define isc_info_svc_get_env 59 /* Retrieves the setting of $FIREBIRD */
|
||||
#define isc_info_svc_get_env_lock 60 /* Retrieves the setting of $FIREBIRD_LCK */
|
||||
#define isc_info_svc_get_env_lock 60 /* Retrieves the setting of $FIREBIRD_LOCK */
|
||||
#define isc_info_svc_get_env_msg 61 /* Retrieves the setting of $FIREBIRD_MSG */
|
||||
#define isc_info_svc_line 62 /* Retrieves 1 line of service output per call */
|
||||
#define isc_info_svc_to_eof 63 /* Retrieves as much of the server output as will fit in the supplied buffer */
|
||||
@ -393,6 +393,9 @@
|
||||
#define isc_spb_bkp_length 7
|
||||
#define isc_spb_bkp_skip_data 8
|
||||
#define isc_spb_bkp_stat 15
|
||||
#define isc_spb_bkp_keyholder 16
|
||||
#define isc_spb_bkp_keyname 17
|
||||
#define isc_spb_bkp_crypt 18
|
||||
#define isc_spb_bkp_ignore_checksums 0x01
|
||||
#define isc_spb_bkp_ignore_limbo 0x02
|
||||
#define isc_spb_bkp_metadata_only 0x04
|
||||
@ -402,6 +405,7 @@
|
||||
#define isc_spb_bkp_convert 0x40
|
||||
#define isc_spb_bkp_expand 0x80
|
||||
#define isc_spb_bkp_no_triggers 0x8000
|
||||
#define isc_spb_bkp_zip 0x010000
|
||||
|
||||
/********************************************
|
||||
* Parameters for isc_action_svc_properties *
|
||||
@ -505,6 +509,9 @@
|
||||
#define isc_spb_res_access_mode 12
|
||||
#define isc_spb_res_fix_fss_data 13
|
||||
#define isc_spb_res_fix_fss_metadata 14
|
||||
#define isc_spb_res_keyholder isc_spb_bkp_keyholder
|
||||
#define isc_spb_res_keyname isc_spb_bkp_keyname
|
||||
#define isc_spb_res_crypt isc_spb_bkp_crypt
|
||||
#define isc_spb_res_stat isc_spb_bkp_stat
|
||||
#define isc_spb_res_metadata_only isc_spb_bkp_metadata_only
|
||||
#define isc_spb_res_deactivate_idx 0x0100
|
||||
|
@ -206,6 +206,9 @@
|
||||
/* Define to 1 if you have the `gmtime_r' function. */
|
||||
#define HAVE_GMTIME_R 1
|
||||
|
||||
/* Define to 1 if you have the `ctime_r' function. */
|
||||
#define HAVE_CTIME_R 1
|
||||
|
||||
/* Define to 1 if you have the <grp.h> header file. */
|
||||
#define HAVE_GRP_H 1
|
||||
|
||||
|
@ -212,6 +212,9 @@
|
||||
/* Define to 1 if you have the `gmtime_r' function. */
|
||||
#define HAVE_GMTIME_R 1
|
||||
|
||||
/* Define to 1 if you have the `ctime_r' function. */
|
||||
#define HAVE_CTIME_R 1
|
||||
|
||||
/* Define to 1 if you have the <grp.h> header file. */
|
||||
#define HAVE_GRP_H 1
|
||||
|
||||
|
@ -206,6 +206,9 @@
|
||||
/* Define to 1 if you have the `gmtime_r' function. */
|
||||
#define HAVE_GMTIME_R 1
|
||||
|
||||
/* Define to 1 if you have the `ctime_r' function. */
|
||||
#define HAVE_CTIME_R 1
|
||||
|
||||
/* Define to 1 if you have the <grp.h> header file. */
|
||||
#define HAVE_GRP_H 1
|
||||
|
||||
|
@ -206,6 +206,9 @@
|
||||
/* Define to 1 if you have the `gmtime_r' function. */
|
||||
#define HAVE_GMTIME_R 1
|
||||
|
||||
/* Define to 1 if you have the `ctime_r' function. */
|
||||
#define HAVE_CTIME_R 1
|
||||
|
||||
/* Define to 1 if you have the <grp.h> header file. */
|
||||
#define HAVE_GRP_H 1
|
||||
|
||||
|
@ -125,6 +125,7 @@ typedef void (*ErrorFunction) (const Firebird::Arg::StatusVector& v);
|
||||
typedef void (*FPTR_ERROR) (ISC_STATUS, ...);
|
||||
|
||||
typedef ULONG RCRD_OFFSET;
|
||||
typedef ULONG RCRD_LENGTH;
|
||||
typedef USHORT FLD_LENGTH;
|
||||
/* CVC: internal usage. I suspect the only reason to return int is that
|
||||
vmslock.cpp:LOCK_convert() calls VMS' sys$enq that may require this signature,
|
||||
|
@ -31,7 +31,6 @@ typedef ISC_QUAD;
|
||||
typedef ISC_TIME;
|
||||
typedef FB_DEC16;
|
||||
typedef FB_DEC34;
|
||||
typedef FB_DEC_FIXED;
|
||||
|
||||
// Versioned interface - base for all FB interfaces
|
||||
interface Versioned
|
||||
@ -214,6 +213,10 @@ interface PluginFactory : Versioned
|
||||
interface PluginModule : Versioned
|
||||
{
|
||||
void doClean();
|
||||
|
||||
version: // 3.0.3 => 3.0.4
|
||||
// Used to release resources allocated per-thread
|
||||
void threadDetach();
|
||||
}
|
||||
|
||||
// Interface to deal with plugins here and there, returned by master interface
|
||||
@ -514,15 +517,15 @@ interface Pipe : ReferenceCounted
|
||||
interface Request : ReferenceCounted
|
||||
{
|
||||
void receive(Status status, int level, uint msgType,
|
||||
uint length, uchar* message);
|
||||
uint length, void* message);
|
||||
void send(Status status, int level, uint msgType,
|
||||
uint length, const uchar* message);
|
||||
uint length, const void* message);
|
||||
void getInfo(Status status, int level,
|
||||
uint itemsLength, const uchar* items,
|
||||
uint bufferLength, uchar* buffer);
|
||||
void start(Status status, Transaction tra, int level);
|
||||
void startAndSend(Status status, Transaction tra, int level, uint msgType,
|
||||
uint length, const uchar* message);
|
||||
uint length, const void* message);
|
||||
void unwind(Status status, int level);
|
||||
void free(Status status);
|
||||
}
|
||||
@ -599,6 +602,7 @@ version: // 3.0 => 4.0
|
||||
// Batch API
|
||||
Batch createBatch(Status status, Transaction transaction, uint stmtLength, const string sqlStmt,
|
||||
uint dialect, MessageMetadata inMetadata, uint parLength, const uchar* par);
|
||||
|
||||
/*
|
||||
Pipe createPipe(Status status, uint stmtLength, const string sqlStmt, uint dialect,
|
||||
Transaction transaction, MessageMetadata inMetadata, void* inBuffer,
|
||||
@ -1061,7 +1065,6 @@ version: // 3.0 => 4.0
|
||||
EventBlock createEventBlock(Status status, const string* events);
|
||||
DecFloat16 getDecFloat16(Status status);
|
||||
DecFloat34 getDecFloat34(Status status);
|
||||
DecFixed getDecFixed(Status status);
|
||||
}
|
||||
|
||||
interface OffsetsCallback : Versioned
|
||||
@ -1467,13 +1470,3 @@ interface DecFloat34 : Versioned
|
||||
void fromBcd(int sign, const uchar* bcd, int exp, FB_DEC34* to);
|
||||
void fromString(Status status, const string from, FB_DEC34* to);
|
||||
}
|
||||
|
||||
interface DecFixed : Versioned
|
||||
{
|
||||
const uint BCD_SIZE = 34;
|
||||
const uint STRING_SIZE = 41; // may include exponent not more than 3 digits
|
||||
void toBcd(const FB_DEC_FIXED* from, int* sign, uchar* bcd);
|
||||
void toString(Status status, const FB_DEC_FIXED* from, int scale, uint bufferLength, string buffer);
|
||||
void fromBcd(int sign, const uchar* bcd, FB_DEC_FIXED* to);
|
||||
void fromString(Status status, const string from, int scale, FB_DEC_FIXED* to);
|
||||
}
|
||||
|
@ -115,7 +115,6 @@ namespace Firebird
|
||||
class IUdrPlugin;
|
||||
class IDecFloat16;
|
||||
class IDecFloat34;
|
||||
class IDecFixed;
|
||||
|
||||
// Interfaces declarations
|
||||
|
||||
@ -737,6 +736,7 @@ namespace Firebird
|
||||
struct VTable : public IVersioned::VTable
|
||||
{
|
||||
void (CLOOP_CARG *doClean)(IPluginModule* self) throw();
|
||||
void (CLOOP_CARG *threadDetach)(IPluginModule* self) throw();
|
||||
};
|
||||
|
||||
protected:
|
||||
@ -750,12 +750,21 @@ namespace Firebird
|
||||
}
|
||||
|
||||
public:
|
||||
static const unsigned VERSION = 2;
|
||||
static const unsigned VERSION = 3;
|
||||
|
||||
void doClean()
|
||||
{
|
||||
static_cast<VTable*>(this->cloopVTable)->doClean(this);
|
||||
}
|
||||
|
||||
void threadDetach()
|
||||
{
|
||||
if (cloopVTable->version < 3)
|
||||
{
|
||||
return;
|
||||
}
|
||||
static_cast<VTable*>(this->cloopVTable)->threadDetach(this);
|
||||
}
|
||||
};
|
||||
|
||||
class IPluginManager : public IVersioned
|
||||
@ -1931,11 +1940,11 @@ namespace Firebird
|
||||
public:
|
||||
struct VTable : public IReferenceCounted::VTable
|
||||
{
|
||||
void (CLOOP_CARG *receive)(IRequest* self, IStatus* status, int level, unsigned msgType, unsigned length, unsigned char* message) throw();
|
||||
void (CLOOP_CARG *send)(IRequest* self, IStatus* status, int level, unsigned msgType, unsigned length, const unsigned char* message) throw();
|
||||
void (CLOOP_CARG *receive)(IRequest* self, IStatus* status, int level, unsigned msgType, unsigned length, void* message) throw();
|
||||
void (CLOOP_CARG *send)(IRequest* self, IStatus* status, int level, unsigned msgType, unsigned length, const void* message) throw();
|
||||
void (CLOOP_CARG *getInfo)(IRequest* self, IStatus* status, int level, unsigned itemsLength, const unsigned char* items, unsigned bufferLength, unsigned char* buffer) throw();
|
||||
void (CLOOP_CARG *start)(IRequest* self, IStatus* status, ITransaction* tra, int level) throw();
|
||||
void (CLOOP_CARG *startAndSend)(IRequest* self, IStatus* status, ITransaction* tra, int level, unsigned msgType, unsigned length, const unsigned char* message) throw();
|
||||
void (CLOOP_CARG *startAndSend)(IRequest* self, IStatus* status, ITransaction* tra, int level, unsigned msgType, unsigned length, const void* message) throw();
|
||||
void (CLOOP_CARG *unwind)(IRequest* self, IStatus* status, int level) throw();
|
||||
void (CLOOP_CARG *free)(IRequest* self, IStatus* status) throw();
|
||||
};
|
||||
@ -1953,14 +1962,14 @@ namespace Firebird
|
||||
public:
|
||||
static const unsigned VERSION = 3;
|
||||
|
||||
template <typename StatusType> void receive(StatusType* status, int level, unsigned msgType, unsigned length, unsigned char* message)
|
||||
template <typename StatusType> void receive(StatusType* status, int level, unsigned msgType, unsigned length, void* message)
|
||||
{
|
||||
StatusType::clearException(status);
|
||||
static_cast<VTable*>(this->cloopVTable)->receive(this, status, level, msgType, length, message);
|
||||
StatusType::checkException(status);
|
||||
}
|
||||
|
||||
template <typename StatusType> void send(StatusType* status, int level, unsigned msgType, unsigned length, const unsigned char* message)
|
||||
template <typename StatusType> void send(StatusType* status, int level, unsigned msgType, unsigned length, const void* message)
|
||||
{
|
||||
StatusType::clearException(status);
|
||||
static_cast<VTable*>(this->cloopVTable)->send(this, status, level, msgType, length, message);
|
||||
@ -1981,7 +1990,7 @@ namespace Firebird
|
||||
StatusType::checkException(status);
|
||||
}
|
||||
|
||||
template <typename StatusType> void startAndSend(StatusType* status, ITransaction* tra, int level, unsigned msgType, unsigned length, const unsigned char* message)
|
||||
template <typename StatusType> void startAndSend(StatusType* status, ITransaction* tra, int level, unsigned msgType, unsigned length, const void* message)
|
||||
{
|
||||
StatusType::clearException(status);
|
||||
static_cast<VTable*>(this->cloopVTable)->startAndSend(this, status, tra, level, msgType, length, message);
|
||||
@ -3938,7 +3947,6 @@ namespace Firebird
|
||||
IEventBlock* (CLOOP_CARG *createEventBlock)(IUtil* self, IStatus* status, const char** events) throw();
|
||||
IDecFloat16* (CLOOP_CARG *getDecFloat16)(IUtil* self, IStatus* status) throw();
|
||||
IDecFloat34* (CLOOP_CARG *getDecFloat34)(IUtil* self, IStatus* status) throw();
|
||||
IDecFixed* (CLOOP_CARG *getDecFixed)(IUtil* self, IStatus* status) throw();
|
||||
};
|
||||
|
||||
protected:
|
||||
@ -4081,20 +4089,6 @@ namespace Firebird
|
||||
StatusType::checkException(status);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename StatusType> IDecFixed* getDecFixed(StatusType* status)
|
||||
{
|
||||
if (cloopVTable->version < 3)
|
||||
{
|
||||
StatusType::setVersionError(status, "IUtil", cloopVTable->version, 3);
|
||||
StatusType::checkException(status);
|
||||
return 0;
|
||||
}
|
||||
StatusType::clearException(status);
|
||||
IDecFixed* ret = static_cast<VTable*>(this->cloopVTable)->getDecFixed(this, status);
|
||||
StatusType::checkException(status);
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
class IOffsetsCallback : public IVersioned
|
||||
@ -5676,58 +5670,6 @@ namespace Firebird
|
||||
}
|
||||
};
|
||||
|
||||
class IDecFixed : public IVersioned
|
||||
{
|
||||
public:
|
||||
struct VTable : public IVersioned::VTable
|
||||
{
|
||||
void (CLOOP_CARG *toBcd)(IDecFixed* self, const FB_DEC_FIXED* from, int* sign, unsigned char* bcd) throw();
|
||||
void (CLOOP_CARG *toString)(IDecFixed* self, IStatus* status, const FB_DEC_FIXED* from, int scale, unsigned bufferLength, char* buffer) throw();
|
||||
void (CLOOP_CARG *fromBcd)(IDecFixed* self, int sign, const unsigned char* bcd, FB_DEC_FIXED* to) throw();
|
||||
void (CLOOP_CARG *fromString)(IDecFixed* self, IStatus* status, const char* from, int scale, FB_DEC_FIXED* to) throw();
|
||||
};
|
||||
|
||||
protected:
|
||||
IDecFixed(DoNotInherit)
|
||||
: IVersioned(DoNotInherit())
|
||||
{
|
||||
}
|
||||
|
||||
~IDecFixed()
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
static const unsigned VERSION = 2;
|
||||
|
||||
static const unsigned BCD_SIZE = 34;
|
||||
static const unsigned STRING_SIZE = 41;
|
||||
|
||||
void toBcd(const FB_DEC_FIXED* from, int* sign, unsigned char* bcd)
|
||||
{
|
||||
static_cast<VTable*>(this->cloopVTable)->toBcd(this, from, sign, bcd);
|
||||
}
|
||||
|
||||
template <typename StatusType> void toString(StatusType* status, const FB_DEC_FIXED* from, int scale, unsigned bufferLength, char* buffer)
|
||||
{
|
||||
StatusType::clearException(status);
|
||||
static_cast<VTable*>(this->cloopVTable)->toString(this, status, from, scale, bufferLength, buffer);
|
||||
StatusType::checkException(status);
|
||||
}
|
||||
|
||||
void fromBcd(int sign, const unsigned char* bcd, FB_DEC_FIXED* to)
|
||||
{
|
||||
static_cast<VTable*>(this->cloopVTable)->fromBcd(this, sign, bcd, to);
|
||||
}
|
||||
|
||||
template <typename StatusType> void fromString(StatusType* status, const char* from, int scale, FB_DEC_FIXED* to)
|
||||
{
|
||||
StatusType::clearException(status);
|
||||
static_cast<VTable*>(this->cloopVTable)->fromString(this, status, from, scale, to);
|
||||
StatusType::checkException(status);
|
||||
}
|
||||
};
|
||||
|
||||
// Interfaces implementations
|
||||
|
||||
template <typename Name, typename StatusType, typename Base>
|
||||
@ -7072,6 +7014,7 @@ namespace Firebird
|
||||
{
|
||||
this->version = Base::VERSION;
|
||||
this->doClean = &Name::cloopdoCleanDispatcher;
|
||||
this->threadDetach = &Name::cloopthreadDetachDispatcher;
|
||||
}
|
||||
} vTable;
|
||||
|
||||
@ -7089,6 +7032,18 @@ namespace Firebird
|
||||
StatusType::catchException(0);
|
||||
}
|
||||
}
|
||||
|
||||
static void CLOOP_CARG cloopthreadDetachDispatcher(IPluginModule* self) throw()
|
||||
{
|
||||
try
|
||||
{
|
||||
static_cast<Name*>(self)->Name::threadDetach();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
StatusType::catchException(0);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Name, typename StatusType, typename Base = IVersionedImpl<Name, StatusType, Inherit<IPluginModule> > >
|
||||
@ -7105,6 +7060,7 @@ namespace Firebird
|
||||
}
|
||||
|
||||
virtual void doClean() = 0;
|
||||
virtual void threadDetach() = 0;
|
||||
};
|
||||
|
||||
template <typename Name, typename StatusType, typename Base>
|
||||
@ -9401,7 +9357,7 @@ namespace Firebird
|
||||
this->cloopVTable = &vTable;
|
||||
}
|
||||
|
||||
static void CLOOP_CARG cloopreceiveDispatcher(IRequest* self, IStatus* status, int level, unsigned msgType, unsigned length, unsigned char* message) throw()
|
||||
static void CLOOP_CARG cloopreceiveDispatcher(IRequest* self, IStatus* status, int level, unsigned msgType, unsigned length, void* message) throw()
|
||||
{
|
||||
StatusType status2(status);
|
||||
|
||||
@ -9415,7 +9371,7 @@ namespace Firebird
|
||||
}
|
||||
}
|
||||
|
||||
static void CLOOP_CARG cloopsendDispatcher(IRequest* self, IStatus* status, int level, unsigned msgType, unsigned length, const unsigned char* message) throw()
|
||||
static void CLOOP_CARG cloopsendDispatcher(IRequest* self, IStatus* status, int level, unsigned msgType, unsigned length, const void* message) throw()
|
||||
{
|
||||
StatusType status2(status);
|
||||
|
||||
@ -9457,7 +9413,7 @@ namespace Firebird
|
||||
}
|
||||
}
|
||||
|
||||
static void CLOOP_CARG cloopstartAndSendDispatcher(IRequest* self, IStatus* status, ITransaction* tra, int level, unsigned msgType, unsigned length, const unsigned char* message) throw()
|
||||
static void CLOOP_CARG cloopstartAndSendDispatcher(IRequest* self, IStatus* status, ITransaction* tra, int level, unsigned msgType, unsigned length, const void* message) throw()
|
||||
{
|
||||
StatusType status2(status);
|
||||
|
||||
@ -9538,11 +9494,11 @@ namespace Firebird
|
||||
{
|
||||
}
|
||||
|
||||
virtual void receive(StatusType* status, int level, unsigned msgType, unsigned length, unsigned char* message) = 0;
|
||||
virtual void send(StatusType* status, int level, unsigned msgType, unsigned length, const unsigned char* message) = 0;
|
||||
virtual void receive(StatusType* status, int level, unsigned msgType, unsigned length, void* message) = 0;
|
||||
virtual void send(StatusType* status, int level, unsigned msgType, unsigned length, const void* message) = 0;
|
||||
virtual void getInfo(StatusType* status, int level, unsigned itemsLength, const unsigned char* items, unsigned bufferLength, unsigned char* buffer) = 0;
|
||||
virtual void start(StatusType* status, ITransaction* tra, int level) = 0;
|
||||
virtual void startAndSend(StatusType* status, ITransaction* tra, int level, unsigned msgType, unsigned length, const unsigned char* message) = 0;
|
||||
virtual void startAndSend(StatusType* status, ITransaction* tra, int level, unsigned msgType, unsigned length, const void* message) = 0;
|
||||
virtual void unwind(StatusType* status, int level) = 0;
|
||||
virtual void free(StatusType* status) = 0;
|
||||
};
|
||||
@ -13809,7 +13765,6 @@ namespace Firebird
|
||||
this->createEventBlock = &Name::cloopcreateEventBlockDispatcher;
|
||||
this->getDecFloat16 = &Name::cloopgetDecFloat16Dispatcher;
|
||||
this->getDecFloat34 = &Name::cloopgetDecFloat34Dispatcher;
|
||||
this->getDecFixed = &Name::cloopgetDecFixedDispatcher;
|
||||
}
|
||||
} vTable;
|
||||
|
||||
@ -14037,21 +13992,6 @@ namespace Firebird
|
||||
return static_cast<IDecFloat34*>(0);
|
||||
}
|
||||
}
|
||||
|
||||
static IDecFixed* CLOOP_CARG cloopgetDecFixedDispatcher(IUtil* self, IStatus* status) throw()
|
||||
{
|
||||
StatusType status2(status);
|
||||
|
||||
try
|
||||
{
|
||||
return static_cast<Name*>(self)->Name::getDecFixed(&status2);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
StatusType::catchException(&status2);
|
||||
return static_cast<IDecFixed*>(0);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Name, typename StatusType, typename Base = IVersionedImpl<Name, StatusType, Inherit<IUtil> > >
|
||||
@ -14083,7 +14023,6 @@ namespace Firebird
|
||||
virtual IEventBlock* createEventBlock(StatusType* status, const char** events) = 0;
|
||||
virtual IDecFloat16* getDecFloat16(StatusType* status) = 0;
|
||||
virtual IDecFloat34* getDecFloat34(StatusType* status) = 0;
|
||||
virtual IDecFixed* getDecFixed(StatusType* status) = 0;
|
||||
};
|
||||
|
||||
template <typename Name, typename StatusType, typename Base>
|
||||
@ -17481,101 +17420,6 @@ namespace Firebird
|
||||
virtual void fromBcd(int sign, const unsigned char* bcd, int exp, FB_DEC34* to) = 0;
|
||||
virtual void fromString(StatusType* status, const char* from, FB_DEC34* to) = 0;
|
||||
};
|
||||
|
||||
template <typename Name, typename StatusType, typename Base>
|
||||
class IDecFixedBaseImpl : public Base
|
||||
{
|
||||
public:
|
||||
typedef IDecFixed Declaration;
|
||||
|
||||
IDecFixedBaseImpl(DoNotInherit = DoNotInherit())
|
||||
{
|
||||
static struct VTableImpl : Base::VTable
|
||||
{
|
||||
VTableImpl()
|
||||
{
|
||||
this->version = Base::VERSION;
|
||||
this->toBcd = &Name::clooptoBcdDispatcher;
|
||||
this->toString = &Name::clooptoStringDispatcher;
|
||||
this->fromBcd = &Name::cloopfromBcdDispatcher;
|
||||
this->fromString = &Name::cloopfromStringDispatcher;
|
||||
}
|
||||
} vTable;
|
||||
|
||||
this->cloopVTable = &vTable;
|
||||
}
|
||||
|
||||
static void CLOOP_CARG clooptoBcdDispatcher(IDecFixed* self, const FB_DEC_FIXED* from, int* sign, unsigned char* bcd) throw()
|
||||
{
|
||||
try
|
||||
{
|
||||
static_cast<Name*>(self)->Name::toBcd(from, sign, bcd);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
StatusType::catchException(0);
|
||||
}
|
||||
}
|
||||
|
||||
static void CLOOP_CARG clooptoStringDispatcher(IDecFixed* self, IStatus* status, const FB_DEC_FIXED* from, int scale, unsigned bufferLength, char* buffer) throw()
|
||||
{
|
||||
StatusType status2(status);
|
||||
|
||||
try
|
||||
{
|
||||
static_cast<Name*>(self)->Name::toString(&status2, from, scale, bufferLength, buffer);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
StatusType::catchException(&status2);
|
||||
}
|
||||
}
|
||||
|
||||
static void CLOOP_CARG cloopfromBcdDispatcher(IDecFixed* self, int sign, const unsigned char* bcd, FB_DEC_FIXED* to) throw()
|
||||
{
|
||||
try
|
||||
{
|
||||
static_cast<Name*>(self)->Name::fromBcd(sign, bcd, to);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
StatusType::catchException(0);
|
||||
}
|
||||
}
|
||||
|
||||
static void CLOOP_CARG cloopfromStringDispatcher(IDecFixed* self, IStatus* status, const char* from, int scale, FB_DEC_FIXED* to) throw()
|
||||
{
|
||||
StatusType status2(status);
|
||||
|
||||
try
|
||||
{
|
||||
static_cast<Name*>(self)->Name::fromString(&status2, from, scale, to);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
StatusType::catchException(&status2);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Name, typename StatusType, typename Base = IVersionedImpl<Name, StatusType, Inherit<IDecFixed> > >
|
||||
class IDecFixedImpl : public IDecFixedBaseImpl<Name, StatusType, Base>
|
||||
{
|
||||
protected:
|
||||
IDecFixedImpl(DoNotInherit = DoNotInherit())
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
virtual ~IDecFixedImpl()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void toBcd(const FB_DEC_FIXED* from, int* sign, unsigned char* bcd) = 0;
|
||||
virtual void toString(StatusType* status, const FB_DEC_FIXED* from, int scale, unsigned bufferLength, char* buffer) = 0;
|
||||
virtual void fromBcd(int sign, const unsigned char* bcd, FB_DEC_FIXED* to) = 0;
|
||||
virtual void fromString(StatusType* status, const char* from, int scale, FB_DEC_FIXED* to) = 0;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
@ -141,11 +141,6 @@
|
||||
builder->setType(status, index, SQL_DEC34); \
|
||||
builder->setLength(status, index, sizeof(FB_DEC34));
|
||||
|
||||
#define FB__META_FB_DEC_FIXED(scale) \
|
||||
builder->setType(status, index, SQL_DEC_FIXED); \
|
||||
builder->setLength(status, index, sizeof(FB_DEC_FIXED)); \
|
||||
builder->setScale(status, index, scale);
|
||||
|
||||
#define FB__META_FB_BLOB \
|
||||
builder->setType(status, index, SQL_BLOB); \
|
||||
builder->setLength(status, index, sizeof(ISC_QUAD));
|
||||
@ -200,7 +195,6 @@
|
||||
#define FB__TYPE_FB_DOUBLE double
|
||||
#define FB__TYPE_FB_DECFLOAT16 FB_DEC16
|
||||
#define FB__TYPE_FB_DECFLOAT34 FB_DEC34
|
||||
#define FB__TYPE_FB_DEC_FIXED FB_DEC_FIXED
|
||||
#define FB__TYPE_FB_BLOB ISC_QUAD
|
||||
#define FB__TYPE_FB_BOOLEAN ISC_UCHAR
|
||||
#define FB__TYPE_FB_DATE ::Firebird::FbDate
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user