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
|
*.log
|
||||||
*.bak
|
*.bak
|
||||||
*.tmp
|
*.tmp
|
||||||
|
*.d
|
||||||
src/dsql/parse.cpp
|
src/dsql/parse.cpp
|
||||||
.vscode/.browse.VC.db
|
.vscode/.browse.VC.db
|
||||||
extern/decNumber/libdecFloat.a
|
extern/decNumber/libdecFloat*.a
|
||||||
|
@ -811,6 +811,17 @@
|
|||||||
#
|
#
|
||||||
#EventMemSize = 64K
|
#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
|
# Engine Settings
|
||||||
|
@ -228,6 +228,8 @@ checkLibraries() {
|
|||||||
then
|
then
|
||||||
checkLibrary tomcrypt
|
checkLibrary tomcrypt
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
checkLibrary icudata
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -237,7 +239,7 @@ checkLibraries() {
|
|||||||
grepProcess() {
|
grepProcess() {
|
||||||
processList=$1
|
processList=$1
|
||||||
eol=\$
|
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
|
#!/bin/sh
|
||||||
# install - install a program, script, or datafile
|
# 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
|
# This originates from X11R5 (mit/util/scripts/install.sh), which was
|
||||||
# later released in X11R6 (xc/config/util/install.sh) with the
|
# later released in X11R6 (xc/config/util/install.sh) with the
|
||||||
@ -496,6 +496,6 @@ done
|
|||||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||||
# time-stamp-start: "scriptversion="
|
# time-stamp-start: "scriptversion="
|
||||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||||
# time-stamp-time-zone: "UTC"
|
# time-stamp-time-zone: "UTC0"
|
||||||
# time-stamp-end: "; # UTC"
|
# time-stamp-end: "; # UTC"
|
||||||
# End:
|
# End:
|
||||||
|
@ -35,12 +35,18 @@
|
|||||||
|
|
||||||
ROOT=$(shell cd ..; pwd)
|
ROOT=$(shell cd ..; pwd)
|
||||||
|
|
||||||
|
ifeq ($(CROSS_OUT), Y)
|
||||||
|
export CROSS:=CrossBuild
|
||||||
|
endif
|
||||||
|
|
||||||
include make.defaults
|
include make.defaults
|
||||||
|
|
||||||
ifeq ($(CROSS_OUT), Y)
|
ifeq ($(CROSS_OUT), Y)
|
||||||
include make.crossPlatform
|
include make.crossPlatform
|
||||||
else
|
else
|
||||||
include make.platform
|
include make.platform
|
||||||
endif
|
endif
|
||||||
|
|
||||||
include make.rules
|
include make.rules
|
||||||
include make.shared.variables
|
include make.shared.variables
|
||||||
|
|
||||||
@ -185,7 +191,11 @@ $(TOMMATH_LIB): $(TOM_Objs)
|
|||||||
|
|
||||||
.PHONY: tomcrypt
|
.PHONY: tomcrypt
|
||||||
TOMCRYPT_LIB=$(LIB)/libtomcrypt.a
|
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)
|
tomcrypt: $(TOMCRYPT_LIB)
|
||||||
|
|
||||||
@ -194,10 +204,10 @@ $(TOMCRYPT_LIB): $(TOM_Objs)
|
|||||||
$(STATICLIB_LINK) $@ $^
|
$(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:
|
master_process:
|
||||||
ln -sf $(SRC_ROOT)/include/gen/autoconfig.auto $(SRC_ROOT)/include/gen/autoconfig.h
|
ln -sf $(SRC_ROOT)/include/gen/autoconfig.auto $(SRC_ROOT)/include/gen/autoconfig.h
|
||||||
@ -205,6 +215,7 @@ master_process:
|
|||||||
$(MAKE) export_lists
|
$(MAKE) export_lists
|
||||||
$(MAKE) external
|
$(MAKE) external
|
||||||
$(MAKE) updateCloopInterfaces
|
$(MAKE) updateCloopInterfaces
|
||||||
|
$(MAKE) preliminaryCheck
|
||||||
$(MAKE) boot
|
$(MAKE) boot
|
||||||
$(MAKE) yvalve
|
$(MAKE) yvalve
|
||||||
ifeq ($(IsDeveloper), Y)
|
ifeq ($(IsDeveloper), Y)
|
||||||
@ -264,6 +275,8 @@ cross2:
|
|||||||
$(MAKE) prerequisites
|
$(MAKE) prerequisites
|
||||||
$(MAKE) tommath
|
$(MAKE) tommath
|
||||||
$(MAKE) tomcrypt
|
$(MAKE) tomcrypt
|
||||||
|
$(MAKE) -C $(ROOT)/extern/decNumber
|
||||||
|
ln -sf $(ROOT)/extern/decNumber/libdecFloat$(CROSS).a $(LIB)
|
||||||
$(MAKE) yvalve
|
$(MAKE) yvalve
|
||||||
$(MAKE) engine
|
$(MAKE) engine
|
||||||
$(MAKE) fbintl
|
$(MAKE) fbintl
|
||||||
@ -273,6 +286,26 @@ cross2:
|
|||||||
$(MAKE) -f Makefile.plugins_examples
|
$(MAKE) -f Makefile.plugins_examples
|
||||||
$(MAKE) cross_rest
|
$(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
|
# 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)
|
$(UDF_BACKWARD_COMPATIBILITY): $(COMPAT_Objects)
|
||||||
$(LIB_LINK) $(LIB_LINK_OPTIONS) $(call LIB_LINK_SONAME,$(UDF_BACKWARD_COMPATIBILITY_BASENAME)) \
|
$(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)
|
$(COMPAT_SQL): $(SRC_COMPAT_SQL)
|
||||||
cp $^ $@
|
cp $^ $@
|
||||||
|
@ -20,7 +20,10 @@ HOST_TAG64:=linux-x86
|
|||||||
endif
|
endif
|
||||||
NDK_TOOLCHAIN_VERSION:=$(shell echo $(TOOLCHAIN_DIR) | awk -F - '{print $$NF;}')
|
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-
|
CROSS_PREFIX:=$(NDK)/toolchains/$(TOOLCHAIN_DIR)/prebuilt/$(HOST_TAG64)/bin/arm-linux-androideabi-
|
||||||
|
|
||||||
CXX:=$(CROSS_PREFIX)g++
|
CXX:=$(CROSS_PREFIX)g++
|
||||||
@ -34,12 +37,20 @@ OBJDUMP:=$(CROSS_PREFIX)objdump
|
|||||||
RANLIB:=$(CROSS_PREFIX)ranlib
|
RANLIB:=$(CROSS_PREFIX)ranlib
|
||||||
STRIP:=$(CROSS_PREFIX)strip
|
STRIP:=$(CROSS_PREFIX)strip
|
||||||
|
|
||||||
COMMON_FLAGS=-ggdb -DFB_SEND_FLAGS=MSG_NOSIGNAL -DLINUX -DANDROID -DARM -pipe -MMD -fPIC -fmessage-length=0 \
|
export CXX
|
||||||
-I$(ROOT)/extern/libtommath --sysroot=$(CROSS_PLATFORM) \
|
export CC
|
||||||
-I$(CROSS_PLATFORM)/usr/include -I$(ROOT)/gen/cross \
|
export AR
|
||||||
-I$(NDK)/sources/cxx-stl/gnu-libstdc++/$(NDK_TOOLCHAIN_VERSION)/include \
|
|
||||||
-I$(NDK)/sources/cxx-stl/gnu-libstdc++/$(NDK_TOOLCHAIN_VERSION)/libs/armeabi/include
|
|
||||||
|
|
||||||
|
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
|
OPTIMIZE_FLAGS=-fno-omit-frame-pointer
|
||||||
WARN_FLAGS=-Wall -Wno-switch -Wno-parentheses -Wno-unknown-pragmas -Wno-unused-variable
|
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 \
|
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
|
-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)
|
LINK_LIBS = $(DroidLibs)
|
||||||
SO_LINK_LIBS = $(DroidLibs)
|
SO_LINK_LIBS = $(DroidLibs)
|
||||||
|
@ -133,7 +133,7 @@ CAS_OPTIONS=@CAS_OPTIONS@
|
|||||||
|
|
||||||
# multiple-precision integer library
|
# multiple-precision integer library
|
||||||
MATHLIB=@MATHLIB@
|
MATHLIB=@MATHLIB@
|
||||||
DECLIB=-ldecFloat
|
DECLIB=-ldecFloat$(CROSS)
|
||||||
|
|
||||||
# crypt library
|
# crypt library
|
||||||
CRYPTLIB=@CRYPTLIB@
|
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_EMPTY_SYMBOLS = $(call LIB_LINK_MAPFILE,$(EMPTY_VERS))
|
||||||
LINK_PLUGIN_SYMBOLS = $(call LIB_LINK_MAPFILE,$(PLUGIN_VERS))
|
LINK_PLUGIN_SYMBOLS = $(call LIB_LINK_MAPFILE,$(PLUGIN_VERS))
|
||||||
LINK_EXEC_EXPORT=-rdynamic
|
LINK_EXEC_EXPORT=-rdynamic
|
||||||
|
UDR_SUPPORT_LIBS=
|
||||||
|
|
||||||
LIB_PLATFORM_RPATH = -Wl,-rpath,$(1)
|
LIB_PLATFORM_RPATH = -Wl,-rpath,$(1)
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ WCXXFLAGS = $(WFLAGS) $(THR_FLAGS) $(RTTI_FLAG) $(CXXFLAGS) $(GLOB_OPTIONS)
|
|||||||
|
|
||||||
GPRE_FLAGS= -m -z -n
|
GPRE_FLAGS= -m -z -n
|
||||||
JRD_GPRE_FLAGS = -n -z -gds_cxx -ids
|
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
|
.SUFFIXES: .c .e .epp .cpp
|
||||||
@ -87,7 +87,10 @@ $(OBJ)/jrd/%.cpp: $(SRC_ROOT)/jrd/%.epp
|
|||||||
$(GPRE_CURRENT) $(JRD_GPRE_FLAGS) $(firstword $<) $@
|
$(GPRE_CURRENT) $(JRD_GPRE_FLAGS) $(firstword $<) $@
|
||||||
|
|
||||||
$(OBJ)/isql/%.cpp: $(SRC_ROOT)/isql/%.epp
|
$(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
|
$(OBJ)/%.cpp: $(SRC_ROOT)/%.epp
|
||||||
$(GPRE_CURRENT) $(GPRE_FLAGS) $(firstword $<) $@
|
$(GPRE_CURRENT) $(GPRE_FLAGS) $(firstword $<) $@
|
||||||
|
@ -20,10 +20,9 @@
|
|||||||
|
|
||||||
#LD=@CXX@
|
#LD=@CXX@
|
||||||
|
|
||||||
#PROD_FLAGS=-ggdb -O3 -fno-omit-frame-pointer -DLINUX -pipe -MMD -fPIC
|
COMMON_FLAGS=-DLINUX -DARM -pipe -MMD -fPIC -fsigned-char -fmessage-length=0 -DFB_SEND_FLAGS=MSG_NOSIGNAL
|
||||||
#DEV_FLAGS=-ggdb -DLINUX -DDEBUG_GDS_ALLOC -pipe -MMD -p -fPIC -Wall -Wno-switch
|
|
||||||
|
|
||||||
PROD_FLAGS=-O3 -DLINUX -DARM -pipe -p -MMD -fPIC -fsigned-char -fmessage-length=0
|
PROD_FLAGS=$(COMMON_FLAGS) -O3
|
||||||
DEV_FLAGS=-ggdb -DLINUX -DARM -pipe -p -MMD -fPIC -Wall -fsigned-char -fmessage-length=0 -Wno-non-virtual-dtor
|
DEV_FLAGS=$(COMMON_FLAGS) -p -ggdb -Wall -Wno-non-virtual-dtor
|
||||||
|
|
||||||
CXXFLAGS := $(CXXFLAGS) -std=c++11
|
CXXFLAGS := $(CXXFLAGS) -std=c++11
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
<ClCompile Include="..\..\..\src\common\CharSet.cpp" />
|
<ClCompile Include="..\..\..\src\common\CharSet.cpp" />
|
||||||
<ClCompile Include="..\..\..\src\common\classes\alloc.cpp" />
|
<ClCompile Include="..\..\..\src\common\classes\alloc.cpp" />
|
||||||
<ClCompile Include="..\..\..\src\common\classes\BaseStream.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\BlrWriter.cpp" />
|
||||||
<ClCompile Include="..\..\..\src\common\classes\ClumpletReader.cpp" />
|
<ClCompile Include="..\..\..\src\common\classes\ClumpletReader.cpp" />
|
||||||
<ClCompile Include="..\..\..\src\common\classes\ClumpletWriter.cpp" />
|
<ClCompile Include="..\..\..\src\common\classes\ClumpletWriter.cpp" />
|
||||||
@ -110,6 +111,7 @@
|
|||||||
<ClInclude Include="..\..\..\src\common\classes\auto.h" />
|
<ClInclude Include="..\..\..\src\common\classes\auto.h" />
|
||||||
<ClInclude Include="..\..\..\src\common\classes\BaseStream.h" />
|
<ClInclude Include="..\..\..\src\common\classes\BaseStream.h" />
|
||||||
<ClInclude Include="..\..\..\src\common\classes\BatchCompletionState.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\BlrReader.h" />
|
||||||
<ClInclude Include="..\..\..\src\common\classes\BlrWriter.h" />
|
<ClInclude Include="..\..\..\src\common\classes\BlrWriter.h" />
|
||||||
<ClInclude Include="..\..\..\src\common\classes\ByteChunk.h" />
|
<ClInclude Include="..\..\..\src\common\classes\ByteChunk.h" />
|
||||||
|
@ -222,6 +222,9 @@
|
|||||||
<ClCompile Include="..\..\..\src\common\classes\TomCryptHash.cpp">
|
<ClCompile Include="..\..\..\src\common\classes\TomCryptHash.cpp">
|
||||||
<Filter>classes</Filter>
|
<Filter>classes</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\..\src\common\classes\BlobWrapper.cpp">
|
||||||
|
<Filter>classes</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\..\..\src\common\xdr_proto.h">
|
<ClInclude Include="..\..\..\src\common\xdr_proto.h">
|
||||||
@ -542,5 +545,8 @@
|
|||||||
<ClInclude Include="..\..\..\src\common\classes\BatchCompletionState.h">
|
<ClInclude Include="..\..\..\src\common\classes\BatchCompletionState.h">
|
||||||
<Filter>headers</Filter>
|
<Filter>headers</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\..\src\common\classes\BlobWrapper.h">
|
||||||
|
<Filter>headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
@ -25,6 +25,7 @@
|
|||||||
<ClCompile Include="..\..\..\src\common\CharSet.cpp" />
|
<ClCompile Include="..\..\..\src\common\CharSet.cpp" />
|
||||||
<ClCompile Include="..\..\..\src\common\classes\alloc.cpp" />
|
<ClCompile Include="..\..\..\src\common\classes\alloc.cpp" />
|
||||||
<ClCompile Include="..\..\..\src\common\classes\BaseStream.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\BlrWriter.cpp" />
|
||||||
<ClCompile Include="..\..\..\src\common\classes\ClumpletReader.cpp" />
|
<ClCompile Include="..\..\..\src\common\classes\ClumpletReader.cpp" />
|
||||||
<ClCompile Include="..\..\..\src\common\classes\ClumpletWriter.cpp" />
|
<ClCompile Include="..\..\..\src\common\classes\ClumpletWriter.cpp" />
|
||||||
@ -106,6 +107,7 @@
|
|||||||
<ClInclude Include="..\..\..\src\common\classes\auto.h" />
|
<ClInclude Include="..\..\..\src\common\classes\auto.h" />
|
||||||
<ClInclude Include="..\..\..\src\common\classes\BaseStream.h" />
|
<ClInclude Include="..\..\..\src\common\classes\BaseStream.h" />
|
||||||
<ClInclude Include="..\..\..\src\common\classes\BatchCompletionState.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\BlrReader.h" />
|
||||||
<ClInclude Include="..\..\..\src\common\classes\BlrWriter.h" />
|
<ClInclude Include="..\..\..\src\common\classes\BlrWriter.h" />
|
||||||
<ClInclude Include="..\..\..\src\common\classes\ByteChunk.h" />
|
<ClInclude Include="..\..\..\src\common\classes\ByteChunk.h" />
|
||||||
|
@ -222,6 +222,9 @@
|
|||||||
<ClCompile Include="..\..\..\src\common\classes\TomCryptHash.cpp">
|
<ClCompile Include="..\..\..\src\common\classes\TomCryptHash.cpp">
|
||||||
<Filter>classes</Filter>
|
<Filter>classes</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\..\src\common\classes\BlobWrapper.cpp">
|
||||||
|
<Filter>classes</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\..\..\src\common\xdr_proto.h">
|
<ClInclude Include="..\..\..\src\common\xdr_proto.h">
|
||||||
@ -542,5 +545,8 @@
|
|||||||
<ClInclude Include="..\..\..\src\common\classes\BatchCompletionState.h">
|
<ClInclude Include="..\..\..\src\common\classes\BatchCompletionState.h">
|
||||||
<Filter>headers</Filter>
|
<Filter>headers</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\..\src\common\classes\BlobWrapper.h">
|
||||||
|
<Filter>headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
@ -25,6 +25,7 @@
|
|||||||
<ClCompile Include="..\..\..\src\common\CharSet.cpp" />
|
<ClCompile Include="..\..\..\src\common\CharSet.cpp" />
|
||||||
<ClCompile Include="..\..\..\src\common\classes\alloc.cpp" />
|
<ClCompile Include="..\..\..\src\common\classes\alloc.cpp" />
|
||||||
<ClCompile Include="..\..\..\src\common\classes\BaseStream.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\BlrWriter.cpp" />
|
||||||
<ClCompile Include="..\..\..\src\common\classes\ClumpletReader.cpp" />
|
<ClCompile Include="..\..\..\src\common\classes\ClumpletReader.cpp" />
|
||||||
<ClCompile Include="..\..\..\src\common\classes\ClumpletWriter.cpp" />
|
<ClCompile Include="..\..\..\src\common\classes\ClumpletWriter.cpp" />
|
||||||
@ -106,6 +107,7 @@
|
|||||||
<ClInclude Include="..\..\..\src\common\classes\auto.h" />
|
<ClInclude Include="..\..\..\src\common\classes\auto.h" />
|
||||||
<ClInclude Include="..\..\..\src\common\classes\BaseStream.h" />
|
<ClInclude Include="..\..\..\src\common\classes\BaseStream.h" />
|
||||||
<ClInclude Include="..\..\..\src\common\classes\BatchCompletionState.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\BlrReader.h" />
|
||||||
<ClInclude Include="..\..\..\src\common\classes\BlrWriter.h" />
|
<ClInclude Include="..\..\..\src\common\classes\BlrWriter.h" />
|
||||||
<ClInclude Include="..\..\..\src\common\classes\ByteChunk.h" />
|
<ClInclude Include="..\..\..\src\common\classes\ByteChunk.h" />
|
||||||
|
@ -222,6 +222,9 @@
|
|||||||
<ClCompile Include="..\..\..\src\common\classes\TomCryptHash.cpp">
|
<ClCompile Include="..\..\..\src\common\classes\TomCryptHash.cpp">
|
||||||
<Filter>classes</Filter>
|
<Filter>classes</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\..\src\common\classes\BlobWrapper.cpp">
|
||||||
|
<Filter>classes</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\..\..\src\common\xdr_proto.h">
|
<ClInclude Include="..\..\..\src\common\xdr_proto.h">
|
||||||
@ -542,5 +545,8 @@
|
|||||||
<ClInclude Include="..\..\..\src\common\classes\BatchCompletionState.h">
|
<ClInclude Include="..\..\..\src\common\classes\BatchCompletionState.h">
|
||||||
<Filter>headers</Filter>
|
<Filter>headers</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\..\src\common\classes\BlobWrapper.h">
|
||||||
|
<Filter>headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
@ -55,10 +55,7 @@ goto :EOF
|
|||||||
:BOOT_PROCESS
|
:BOOT_PROCESS
|
||||||
@echo.
|
@echo.
|
||||||
@set GPRE=%FB_BIN_DIR%\gpre_boot -lang_internal
|
@set GPRE=%FB_BIN_DIR%\gpre_boot -lang_internal
|
||||||
@for %%i in (array, blob) do @call :PREPROCESS yvalve %%i
|
@for %%i in (backup, restore, OdsDetection) do @call :PREPROCESS burp %%i -ocxx -m
|
||||||
@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 (extract, isql, show) do @call :PREPROCESS isql %%i -ocxx
|
@for %%i in (extract, isql, show) do @call :PREPROCESS isql %%i -ocxx
|
||||||
@for %%i in (dba) do @call :PREPROCESS utilities/gstat %%i
|
@for %%i in (dba) do @call :PREPROCESS utilities/gstat %%i
|
||||||
|
|
||||||
@ -76,7 +73,7 @@ goto :EOF
|
|||||||
@set GPRE=%FB_BIN_DIR%\gpre
|
@set GPRE=%FB_BIN_DIR%\gpre
|
||||||
@for %%i in (alice_meta) do @call :PREPROCESS alice %%i
|
@for %%i in (alice_meta) do @call :PREPROCESS alice %%i
|
||||||
@for %%i in (LegacyManagement) do @call :PREPROCESS auth/SecurityDatabase %%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 (array, blob) do @call :PREPROCESS yvalve %%i
|
||||||
@for %%i in (metd) do @call :PREPROCESS dsql %%i -gds_cxx
|
@for %%i in (metd) do @call :PREPROCESS dsql %%i -gds_cxx
|
||||||
@for %%i in (DdlNodes, PackageNodes) 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
|
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*)
|
powerpc64le-*-linux*)
|
||||||
MAKEFILE_PREFIX=linux_powerpc64el
|
MAKEFILE_PREFIX=linux_powerpc64el
|
||||||
INSTALL_PREFIX=linux
|
INSTALL_PREFIX=linux
|
||||||
@ -1211,7 +1223,6 @@ dnl ### GEN ### directories for databases and misc
|
|||||||
dnl # output
|
dnl # output
|
||||||
mkdir -p gen/\$fb_tgt/include
|
mkdir -p gen/\$fb_tgt/include
|
||||||
mkdir -p gen/\$fb_tgt/intl
|
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/bin
|
||||||
mkdir -p gen/\$fb_tgt/firebird/plugins
|
mkdir -p gen/\$fb_tgt/firebird/plugins
|
||||||
mkdir -p gen/\$fb_tgt/firebird/examples/api
|
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
|
done
|
||||||
|
|
||||||
src/misc/writeBuildNum.sh createMakeVersion gen/Make.Version
|
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
|
done
|
||||||
|
|
||||||
dnl # rebuild version header if needed
|
dnl # rebuild version header if needed
|
||||||
|
@ -3,27 +3,16 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
|
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
|
||||||
<title></title>
|
<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="author" content="alex "/>
|
||||||
<meta name="created" content="00:00:00"/>
|
<meta name="created" content="2013-05-31T00:00:00.010003100"/>
|
||||||
<meta name="changed" content="2017-10-19T18:08:13.851823604"/>
|
<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="created" content="00:00:00">
|
||||||
<meta name="changed" content="2017-10-12T20:21:46.080329427">
|
|
||||||
<meta name="created" content="00:00:00">
|
<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="created" content="00:00:00">
|
||||||
<meta name="changed" content="2017-07-27T13:17:58.205479048">
|
|
||||||
<meta name="created" content="00:00:00">
|
<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="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">
|
<style type="text/css">
|
||||||
@page { size: 21.59cm 27.94cm; margin: 2.01cm }
|
@page { size: 21.59cm 27.94cm; margin: 2.01cm }
|
||||||
h1 { color: #000000 }
|
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
|
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>
|
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
|
<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
|
defined using any language able to call functions using C calling
|
||||||
to call functions using C calling conventions and </font><font size="4" style="font-size: 14pt">having
|
conventions and having concepts of array and pointer to
|
||||||
concepts of array and pointer to procedure/function. Next interfaces
|
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>
|
||||||
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
|
– <font size="4" style="font-size: 14pt">i.e. we support different
|
||||||
versions of same interface. Binary layout of interfaces is designed
|
versions of same interface. Binary layout of interfaces is designed
|
||||||
to support that features very efficient (there is no need in
|
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
|
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
|
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">.
|
</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 most cases single plugin is placed</font> <font size="4" style="font-size: 14pt">into</font>
|
||||||
in</font><font size="4" style="font-size: 14pt">to</font><font size="4" style="font-size: 14pt">
|
<font size="4" style="font-size: 14pt">dynamic library but in common
|
||||||
dynamic library but in common case </font><font size="4" style="font-size: 14pt">multiple
|
case multiple plugins may coexist in single dynamic library. One of
|
||||||
plugins may coexist in single dynamic library</font><font size="4" style="font-size: 14pt">.
|
that interfaces – <a href="#PluginModule">IPluginModule</a> – is
|
||||||
One of that interfaces – <a href="#PluginModule">IPluginModule</a>
|
module-wide (as more or less clear from it's name), others are per
|
||||||
– is module-wide (as more or less clear from it's name), others are
|
plugin. Also each plugin module should contain special exported
|
||||||
per plugin. Also each plugin module should contain special exported
|
|
||||||
entrypoint firebird_plugin() which name is defined in include file
|
entrypoint firebird_plugin() which name is defined in include file
|
||||||
firebird/Interfaces.h as FB_PLUGIN_ENTRY_POINT.</font></p>
|
firebird/Interfaces.h as FB_PLUGIN_ENTRY_POINT.</font></p>
|
||||||
<p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">In
|
<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/>
|
<li/>
|
||||||
<p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">void
|
<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,
|
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
|
const void* inBuffer, ISC_QUAD* blobId, unsigned bpbLength, const
|
||||||
bpbLength, const unsigned char* bpb</font><font size="4" style="font-size: 14pt">)
|
unsigned char* bpb) – adds single blob having length bytes from
|
||||||
– adds single blob having length bytes from inBuffer to the batch,
|
inBuffer to the batch, blob identifier is located at blobId address.
|
||||||
blob identifier is located at blobId address. </font><font size="4" style="font-size: 14pt">If
|
If blob should be created with non-default parameters BPB may be
|
||||||
blob should be created with non-default parameters BPB may be passed
|
passed (format matches one used in <a href="#Attachment">Attachment</a>::createBlob).Total
|
||||||
(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 (including
|
||||||
size of inline blobs that can be added to the batch </font><font size="4" style="font-size: 14pt">(including
|
|
||||||
optional BPBs, blob headers, segment sizes and taking into an
|
optional BPBs, blob headers, segment sizes and taking into an
|
||||||
accoount alignment) </font><font size="4" style="font-size: 14pt">is
|
accoount alignment) is limited by BUFFER_BYTES_SIZE <a href="#Batch_PB">parameter</a>
|
||||||
limited by BUFFER_BYTES_SIZE <a href="#Batch_PB">parameter</a> of
|
of batch creation (affects all blob-oriented methods except
|
||||||
batch creation (affects all blob-oriented methods except
|
|
||||||
registerBlob()). </font>
|
registerBlob()). </font>
|
||||||
</p>
|
</p>
|
||||||
<li/>
|
<li/>
|
||||||
@ -2381,7 +2366,7 @@ with execution of SQL statements.</font></p>
|
|||||||
<li/>
|
<li/>
|
||||||
<p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">unsigned
|
<p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">unsigned
|
||||||
getMessageLength(StatusType* status) - returns length of message
|
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/>
|
<li/>
|
||||||
<p><font face="Liberation Serif, serif"><font size="4" style="font-size: 14pt"><span style="background: #ffffff">unsigned
|
<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
|
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
|
outMetadata, void* outBuffer) – executes any SQL statement except
|
||||||
returning multiple rows of data. Partial analogue of
|
returning multiple rows of data. Partial analogue of
|
||||||
isc_dsql_execute2() - in and out XSLQDAs replaced with input and
|
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/>
|
<li/>
|
||||||
<p style="margin-bottom: 0cm"><font face="Liberation Serif, serif"><font size="4" style="font-size: 14pt">IResultSet*
|
<p style="margin-bottom: 0cm"><font face="Liberation Serif, serif"><font size="4" style="font-size: 14pt">IResultSet*
|
||||||
openCursor(StatusType* status, ITransaction* transaction,
|
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()
|
interface (if provided by user with <a href="#Provider">Provider</a>::setDbCryptCallback()
|
||||||
call). This call is always performed at database attach moment, and
|
call). This call is always performed at database attach moment, and
|
||||||
some holders may reject attachment if satisfactory key was not
|
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/>
|
<li/>
|
||||||
<p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">ICryptKeyCallback*
|
<p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">ICryptKeyCallback*
|
||||||
keyHandle(StatusType* status, const char* keyName) – is intended
|
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/>
|
<li/>
|
||||||
<p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">FB_BOOLEAN
|
<p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">FB_BOOLEAN
|
||||||
useOnlyOwnKeys(StatusType* status) – informs firebird engine
|
useOnlyOwnKeys(StatusType* status) – informs firebird engine
|
||||||
whether a key, provided by key holder, can be used in other attachments.
|
whether a key, provided by key holder, can be used in other
|
||||||
Makes sense only for SuperServer – only it can share database crypt keys
|
attachments. Makes sense only for SuperServer – only it can share
|
||||||
between attachments. Returning FB_TRUE from this method enforces
|
database crypt keys between attachments. Returning FB_TRUE from this
|
||||||
firebird to make sure that this particular key holder (and therefore
|
method enforces firebird to make sure that this particular key
|
||||||
in turn attachment related to it) provides correct crypt key for
|
holder (and therefore in turn attachment related to it) provides
|
||||||
any other attachment to this database.</font></p>
|
correct crypt key for any other attachment to this database.</font></p>
|
||||||
<li/>
|
<li/>
|
||||||
<p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">ICryptKeyCallback*
|
<p style="margin-bottom: 0cm"><font size="4" style="font-size: 14pt">ICryptKeyCallback*
|
||||||
chainHandle(StatusType* status) – support of a chain of key
|
chainHandle(StatusType* status) – support of a chain of key
|
||||||
|
@ -116,23 +116,25 @@ DECFLOAT (FB 4.0)
|
|||||||
Alex Peshkoff <peshkoff@mail.ru>
|
Alex Peshkoff <peshkoff@mail.ru>
|
||||||
|
|
||||||
Syntax rules:
|
Syntax rules:
|
||||||
|
DECFLOAT
|
||||||
DECFLOAT(16)
|
DECFLOAT(16)
|
||||||
DECFLOAT(34)
|
DECFLOAT(34)
|
||||||
|
|
||||||
Storage:
|
Storage:
|
||||||
64-bit / 128-bit, format according to IEEE 754.
|
64-bit / 128-bit, format according to IEEE 754 Decimal64/Decimal128
|
||||||
|
|
||||||
Example(s):
|
Example(s):
|
||||||
1. DECLARE VARIABLE VAR1 DECFLOAT(34);
|
1. DECLARE VARIABLE VAR1 DECFLOAT(34);
|
||||||
2. CREATE TABLE TABLE1 (FIELD1 DECFLOAT(16));
|
2. CREATE TABLE TABLE1 (FIELD1 DECFLOAT(16));
|
||||||
|
|
||||||
Note(s):
|
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.
|
ABS, CEILING, EXP, FLOOR, LN, LOG, LOG10, POWER, SIGN, SQRT.
|
||||||
Agregate functions SUM, AVG, MAX and MIN also work with DECFLOAT data.
|
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.
|
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.
|
- COMPARE_DECFLOAT - compares two DECFLOAT values to be equal, different or unordered.
|
||||||
Returns SMALLINT value which can be as follows:
|
Returns SMALLINT value which can be as follows:
|
||||||
0 - values are equal
|
0 - values are equal
|
||||||
@ -155,18 +157,18 @@ DECFLOAT (FB 4.0)
|
|||||||
DECFLOAT values are ordered as follows:
|
DECFLOAT values are ordered as follows:
|
||||||
-nan < -snan < -inf < -0.1 < -0.10 < -0 < 0 < 0.10 < 0.1 < inf < snan < nan
|
-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
|
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
|
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
|
(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),
|
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
|
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
|
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,
|
exceptional conditions cause a trap. Valid traps are: Division_by_zero, Inexact,
|
||||||
Invalid_operation, Overflow and Underflow. By default traps are set to:
|
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
|
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
|
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
|
native format. One can choose between strings (ideal precision, but poor support
|
||||||
for further processing), floating point values (ideal support for further processing
|
for further processing), floating point values (ideal support for further processing
|
||||||
but poor precision) or scaled integers (good support for further processing and
|
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
|
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.
|
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
|
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.
|
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.
|
Similarly 10<1022 zeroes>0 can be presented as 1.0E1024.
|
||||||
|
@ -2,21 +2,24 @@
|
|||||||
SQL keywords introduced in different server versions
|
SQL keywords introduced in different server versions
|
||||||
----------------------------------------------------
|
----------------------------------------------------
|
||||||
|
|
||||||
An asterisk (*) mark shows that a keyword doesn't exist in the SQL specification
|
Deviations from the standard:
|
||||||
and hence should be considered a non-standard language extention.
|
* : 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
|
Firebird 1.0
|
||||||
------------
|
------------
|
||||||
|
|
||||||
Added as reserved words:
|
Added as reserved words:
|
||||||
|
|
||||||
CURRENT_USER
|
|
||||||
CURRENT_ROLE
|
|
||||||
BREAK *
|
BREAK *
|
||||||
DESCRIPTOR
|
CURRENT_ROLE
|
||||||
FIRST
|
CURRENT_USER
|
||||||
|
DESCRIPTOR (2)
|
||||||
|
FIRST (2)
|
||||||
RECREATE *
|
RECREATE *
|
||||||
SKIP *
|
SKIP
|
||||||
SUBSTRING
|
SUBSTRING
|
||||||
|
|
||||||
Firebird 1.5
|
Firebird 1.5
|
||||||
@ -24,42 +27,42 @@ Firebird 1.5
|
|||||||
|
|
||||||
Added as reserved words:
|
Added as reserved words:
|
||||||
|
|
||||||
CURRENT_CONNECTION *
|
|
||||||
CURRENT_TRANSACTION *
|
|
||||||
BIGINT
|
BIGINT
|
||||||
CASE
|
CASE
|
||||||
|
CURRENT_CONNECTION *
|
||||||
|
CURRENT_TRANSACTION *
|
||||||
RELEASE
|
RELEASE
|
||||||
ROW_COUNT
|
ROW_COUNT
|
||||||
SAVEPOINT
|
SAVEPOINT
|
||||||
|
|
||||||
Added as non-reserved words:
|
Added as non-reserved words:
|
||||||
|
|
||||||
COALESCE
|
COALESCE (1)
|
||||||
DELETING *
|
DELETING *
|
||||||
INSERTING *
|
INSERTING *
|
||||||
LAST
|
LAST
|
||||||
LEAVE
|
LEAVE *
|
||||||
LOCK *
|
LOCK *
|
||||||
NULLIF
|
NULLIF (1)
|
||||||
NULLS
|
NULLS
|
||||||
STATEMENT
|
STATEMENT
|
||||||
UPDATING *
|
UPDATING *
|
||||||
USING
|
USING (1)
|
||||||
|
|
||||||
Moved from reserved words to non-reserved:
|
Moved from reserved words to non-reserved:
|
||||||
|
|
||||||
BREAK *
|
BREAK *
|
||||||
DESCRIPTOR
|
DESCRIPTOR
|
||||||
FIRST
|
FIRST
|
||||||
SKIP *
|
SKIP (1)
|
||||||
SUBSTRING
|
SUBSTRING (1)
|
||||||
|
|
||||||
Firebird 2.0
|
Firebird 2.0
|
||||||
------------
|
------------
|
||||||
|
|
||||||
Added as reserved words:
|
Added as reserved words:
|
||||||
|
|
||||||
BIT_LENGTH
|
BIT_LENGTH *
|
||||||
BOTH
|
BOTH
|
||||||
CHAR_LENGTH
|
CHAR_LENGTH
|
||||||
CHARACTER_LENGTH
|
CHARACTER_LENGTH
|
||||||
@ -90,7 +93,7 @@ Firebird 2.0
|
|||||||
SCALAR_ARRAY *
|
SCALAR_ARRAY *
|
||||||
SEQUENCE
|
SEQUENCE
|
||||||
RESTART
|
RESTART
|
||||||
RETURNING *
|
RETURNING
|
||||||
|
|
||||||
Moved from reserved words to non-reserved:
|
Moved from reserved words to non-reserved:
|
||||||
|
|
||||||
@ -129,49 +132,49 @@ Firebird 2.1
|
|||||||
|
|
||||||
Added as non-reserved words:
|
Added as non-reserved words:
|
||||||
|
|
||||||
ABS
|
ABS (1)
|
||||||
ACCENT *
|
ACCENT *
|
||||||
ACOS *
|
ACOS (1)
|
||||||
ALWAYS *
|
ALWAYS
|
||||||
ASCII_CHAR *
|
ASCII_CHAR *
|
||||||
ASCII_VAL *
|
ASCII_VAL *
|
||||||
ASIN *
|
ASIN (1)
|
||||||
ATAN *
|
ATAN (1)
|
||||||
ATAN2 *
|
ATAN2 *
|
||||||
BIN_AND *
|
BIN_AND *
|
||||||
BIN_OR *
|
BIN_OR *
|
||||||
BIN_SHL *
|
BIN_SHL *
|
||||||
BIN_SHR *
|
BIN_SHR *
|
||||||
BIN_XOR *
|
BIN_XOR *
|
||||||
CEIL
|
CEIL (1)
|
||||||
CEILING
|
CEILING (1)
|
||||||
COS *
|
COS (1)
|
||||||
COSH *
|
COSH (1)
|
||||||
COT *
|
COT *
|
||||||
DATEADD *
|
DATEADD *
|
||||||
DATEDIFF *
|
DATEDIFF *
|
||||||
DECODE *
|
DECODE *
|
||||||
EXP
|
EXP (1)
|
||||||
FLOOR
|
FLOOR (1)
|
||||||
GEN_UUID *
|
GEN_UUID *
|
||||||
GENERATED
|
GENERATED
|
||||||
HASH *
|
HASH *
|
||||||
LIST *
|
LIST *
|
||||||
LN
|
LN (1)
|
||||||
LOG *
|
LOG (1)
|
||||||
LOG10 *
|
LOG10 (1)
|
||||||
LPAD *
|
LPAD *
|
||||||
MATCHED
|
MATCHED
|
||||||
MATCHING *
|
MATCHING *
|
||||||
MAXVALUE *
|
MAXVALUE
|
||||||
MILLISECOND *
|
MILLISECOND *
|
||||||
MINVALUE *
|
MINVALUE
|
||||||
MOD
|
MOD (1)
|
||||||
OVERLAY
|
OVERLAY (1)
|
||||||
PAD
|
PAD
|
||||||
PI *
|
PI *
|
||||||
PLACING
|
PLACING
|
||||||
POWER
|
POWER (1)
|
||||||
PRESERVE
|
PRESERVE
|
||||||
RAND *
|
RAND *
|
||||||
REPLACE *
|
REPLACE *
|
||||||
@ -179,12 +182,12 @@ Firebird 2.1
|
|||||||
ROUND *
|
ROUND *
|
||||||
RPAD *
|
RPAD *
|
||||||
SIGN *
|
SIGN *
|
||||||
SIN *
|
SIN (1)
|
||||||
SINH *
|
SINH (1)
|
||||||
SPACE
|
SPACE
|
||||||
SQRT
|
SQRT (1)
|
||||||
TAN *
|
TAN (1)
|
||||||
TANH *
|
TANH (1)
|
||||||
TEMPORARY
|
TEMPORARY
|
||||||
TRUNC *
|
TRUNC *
|
||||||
WEEK *
|
WEEK *
|
||||||
@ -210,11 +213,10 @@ Firebird 2.5
|
|||||||
MIDDLENAME *
|
MIDDLENAME *
|
||||||
MAPPING *
|
MAPPING *
|
||||||
OS_NAME *
|
OS_NAME *
|
||||||
SOURCE *
|
SOURCE
|
||||||
TWO_PHASE *
|
TWO_PHASE *
|
||||||
UUID_TO_CHAR *
|
UUID_TO_CHAR *
|
||||||
|
|
||||||
|
|
||||||
Firebird 3.0
|
Firebird 3.0
|
||||||
------------
|
------------
|
||||||
|
|
||||||
@ -224,10 +226,8 @@ Firebird 3.0
|
|||||||
CORR
|
CORR
|
||||||
COVAR_POP
|
COVAR_POP
|
||||||
COVAR_SAMP
|
COVAR_SAMP
|
||||||
DELETING *
|
|
||||||
DETERMINISTIC
|
DETERMINISTIC
|
||||||
FALSE
|
FALSE
|
||||||
INSERTING *
|
|
||||||
OFFSET
|
OFFSET
|
||||||
OVER
|
OVER
|
||||||
RDB$RECORD_VERSION *
|
RDB$RECORD_VERSION *
|
||||||
@ -243,15 +243,22 @@ Firebird 3.0
|
|||||||
RETURN
|
RETURN
|
||||||
ROW
|
ROW
|
||||||
SCROLL
|
SCROLL
|
||||||
SQLSTATE *
|
SQLSTATE
|
||||||
STDDEV_POP
|
STDDEV_POP
|
||||||
STDDEV_SAMP
|
STDDEV_SAMP
|
||||||
TRUE
|
TRUE
|
||||||
UNKNOWN
|
UNKNOWN
|
||||||
UPDATING *
|
|
||||||
VAR_POP
|
VAR_POP
|
||||||
VAR_SAMP
|
VAR_SAMP
|
||||||
|
|
||||||
|
Moved from non-reserved words to reserved:
|
||||||
|
|
||||||
|
DELETING *
|
||||||
|
INSERTING *
|
||||||
|
RDB$GET_CONTEXT *
|
||||||
|
RDB$SET_CONTEXT *
|
||||||
|
UPDATING *
|
||||||
|
|
||||||
Added as non-reserved words:
|
Added as non-reserved words:
|
||||||
|
|
||||||
ABSOLUTE
|
ABSOLUTE
|
||||||
@ -262,53 +269,72 @@ Firebird 3.0
|
|||||||
CONTINUE
|
CONTINUE
|
||||||
DDL *
|
DDL *
|
||||||
DECRYPT *
|
DECRYPT *
|
||||||
DENSE_RANK
|
DENSE_RANK (1)
|
||||||
ENCRYPT *
|
ENCRYPT *
|
||||||
ENGINE *
|
ENGINE *
|
||||||
FIRST_VALUE
|
FIRST_VALUE (1)
|
||||||
IDENTITY
|
IDENTITY (1)
|
||||||
INCREMENT
|
INCREMENT
|
||||||
LAST_VALUE
|
LAST_VALUE (1)
|
||||||
LAG
|
LAG (1)
|
||||||
LEAD
|
LEAD (1)
|
||||||
LINGER *
|
LINGER *
|
||||||
NAME
|
NAME
|
||||||
NTH_VALUE
|
NTH_VALUE (1)
|
||||||
PACKAGE *
|
PACKAGE *
|
||||||
PARTITION
|
PARTITION (1)
|
||||||
PLUGIN *
|
PLUGIN *
|
||||||
PRIOR
|
PRIOR
|
||||||
RANK
|
RANK (1)
|
||||||
RELATIVE
|
RELATIVE
|
||||||
ROW_NUMBER
|
ROW_NUMBER (1)
|
||||||
SERVERWIDE *
|
SERVERWIDE *
|
||||||
TAGS *
|
TAGS *
|
||||||
TRUSTED *
|
TRUSTED *
|
||||||
USAGE
|
USAGE
|
||||||
|
|
||||||
|
|
||||||
Firebird 4.0
|
Firebird 4.0
|
||||||
------------
|
------------
|
||||||
|
|
||||||
Added as reserved words:
|
Added as reserved words:
|
||||||
|
|
||||||
UNBOUNDED
|
|
||||||
WINDOW
|
|
||||||
BINARY
|
BINARY
|
||||||
|
DECFLOAT
|
||||||
|
RDB$ERROR *
|
||||||
|
RDB$ROLE_IN_USE *
|
||||||
|
RDB$SYSTEM_PRIVILEGE *
|
||||||
|
UNBOUNDED (2)
|
||||||
VARBINARY
|
VARBINARY
|
||||||
|
WINDOW
|
||||||
|
|
||||||
Added as non-reserved words:
|
Added as non-reserved words:
|
||||||
|
|
||||||
CUME_DIST *
|
BIND *
|
||||||
|
COMPARE_DECFLOAT *
|
||||||
|
CUME_DIST (1)
|
||||||
|
DEFINER
|
||||||
EXCLUDE
|
EXCLUDE
|
||||||
|
FIRST_DAY *
|
||||||
FOLLOWING
|
FOLLOWING
|
||||||
NTILE *
|
IDLE *
|
||||||
|
INVOKER
|
||||||
|
LAST_DAY *
|
||||||
|
MESSAGE *
|
||||||
|
NATIVE *
|
||||||
|
NORMALIZE_DECFLOAT *
|
||||||
|
NTILE (1)
|
||||||
OTHERS
|
OTHERS
|
||||||
PERCENT_RANK *
|
OVERRIDING
|
||||||
|
PERCENT_RANK (1)
|
||||||
PRECEDING
|
PRECEDING
|
||||||
PRIVILEGE *
|
PRIVILEGE *
|
||||||
RANGE *
|
QUANTIZE *
|
||||||
RDB$ROLE_IN_USE *
|
RANGE (1)
|
||||||
RDB$SYSTEM_PRIVILEGE *
|
RESET *
|
||||||
SYSTEM *
|
SECURITY
|
||||||
|
SESSION
|
||||||
|
SQL (1)
|
||||||
|
SYSTEM (1)
|
||||||
TIES
|
TIES
|
||||||
|
TOTALORDER *
|
||||||
|
TRAPS *
|
||||||
|
@ -56,6 +56,8 @@ public:
|
|||||||
pluginManager = NULL;
|
pluginManager = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void threadDetach() {};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
IPluginManager* pluginManager;
|
IPluginManager* pluginManager;
|
||||||
};
|
};
|
||||||
|
@ -58,6 +58,8 @@ public:
|
|||||||
pluginManager = NULL;
|
pluginManager = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void threadDetach() {};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
IPluginManager* pluginManager;
|
IPluginManager* pluginManager;
|
||||||
};
|
};
|
||||||
|
@ -47,6 +47,7 @@ Type
|
|||||||
|
|
||||||
// TPluginModule implementation
|
// TPluginModule implementation
|
||||||
procedure doClean; override;
|
procedure doClean; override;
|
||||||
|
procedure threadDetach; override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
TMyCrypt = class(IDbCryptPluginImpl)
|
TMyCrypt = class(IDbCryptPluginImpl)
|
||||||
@ -71,6 +72,7 @@ Type
|
|||||||
procedure setKey(status: IStatus; length: Cardinal; sources: IKeyHolderPluginPtr; keyName: PAnsiChar); override;
|
procedure setKey(status: IStatus; length: Cardinal; sources: IKeyHolderPluginPtr; keyName: PAnsiChar); override;
|
||||||
procedure encrypt(status: IStatus; length: Cardinal; src, dst: Pointer); override;
|
procedure encrypt(status: IStatus; length: Cardinal; src, dst: Pointer); override;
|
||||||
procedure decrypt(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
|
private
|
||||||
procedure pxor(length: Cardinal; mem: Pointer);
|
procedure pxor(length: Cardinal; mem: Pointer);
|
||||||
@ -114,6 +116,10 @@ begin
|
|||||||
FRegistered := False;
|
FRegistered := False;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TMyPluginModule.threadDetach;
|
||||||
|
begin
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TMyPluginModule.registerMe;
|
procedure TMyPluginModule.registerMe;
|
||||||
begin
|
begin
|
||||||
if not FRegistered then
|
if not FRegistered then
|
||||||
@ -179,6 +185,13 @@ begin
|
|||||||
Result := FOwner;
|
Result := FOwner;
|
||||||
end;
|
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);
|
procedure TMyCrypt.decrypt(status: IStatus; length: Cardinal; src, dst: Pointer);
|
||||||
begin
|
begin
|
||||||
status.init;
|
status.init;
|
||||||
|
@ -153,6 +153,91 @@ FB_UDR_BEGIN_FUNCTION(sum_args)
|
|||||||
FB_UDR_END_FUNCTION
|
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, "{ %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, "unit %s;\n\n", unitName.c_str());
|
||||||
fprintf(out, "interface\n\n");
|
fprintf(out, "interface\n\n");
|
||||||
fprintf(out, "uses Classes");
|
fprintf(out, "uses Classes");
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
{ This file was autogenerated by cloop - Cross Language Object Oriented Programming }
|
{ This file was autogenerated by cloop - Cross Language Object Oriented Programming }
|
||||||
|
|
||||||
|
{$IFDEF FPC}
|
||||||
|
{$MODE DELPHI}
|
||||||
|
{$OBJECTCHECKS OFF}
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
unit CalcPascalApi;
|
unit CalcPascalApi;
|
||||||
|
|
||||||
interface
|
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
|
$(LIBRARY): $(wildcard *.c) $(wildcard *.h) Makefile
|
||||||
$(RM) -f *.o
|
$(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
|
$(AR) crs $(LIBRARY) *.o
|
||||||
$(RM) -f *.o
|
$(RM) -f *.o
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
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/
|
lib/
|
||||||
temp/
|
temp/
|
||||||
*.o
|
*.o
|
||||||
|
*.d
|
||||||
*.l*
|
*.l*
|
||||||
.libs/
|
.libs/
|
||||||
|
@ -1820,6 +1820,8 @@ C --
|
|||||||
PARAMETER (GDS__vld_plugins = 335545203)
|
PARAMETER (GDS__vld_plugins = 335545203)
|
||||||
INTEGER*4 GDS__db_crypt_key
|
INTEGER*4 GDS__db_crypt_key
|
||||||
PARAMETER (GDS__db_crypt_key = 335545204)
|
PARAMETER (GDS__db_crypt_key = 335545204)
|
||||||
|
INTEGER*4 GDS__no_keyholder_plugin
|
||||||
|
PARAMETER (GDS__no_keyholder_plugin = 335545205)
|
||||||
INTEGER*4 GDS__gfix_db_name
|
INTEGER*4 GDS__gfix_db_name
|
||||||
PARAMETER (GDS__gfix_db_name = 335740929)
|
PARAMETER (GDS__gfix_db_name = 335740929)
|
||||||
INTEGER*4 GDS__gfix_invalid_sw
|
INTEGER*4 GDS__gfix_invalid_sw
|
||||||
|
@ -1815,6 +1815,8 @@ const
|
|||||||
gds_vld_plugins = 335545203;
|
gds_vld_plugins = 335545203;
|
||||||
isc_db_crypt_key = 335545204;
|
isc_db_crypt_key = 335545204;
|
||||||
gds_db_crypt_key = 335545204;
|
gds_db_crypt_key = 335545204;
|
||||||
|
isc_no_keyholder_plugin = 335545205;
|
||||||
|
gds_no_keyholder_plugin = 335545205;
|
||||||
isc_gfix_db_name = 335740929;
|
isc_gfix_db_name = 335740929;
|
||||||
gds_gfix_db_name = 335740929;
|
gds_gfix_db_name = 335740929;
|
||||||
isc_gfix_invalid_sw = 335740930;
|
isc_gfix_invalid_sw = 335740930;
|
||||||
|
@ -29,7 +29,6 @@ set(epp_boot_internal_files
|
|||||||
burp/backup.epp
|
burp/backup.epp
|
||||||
burp/restore.epp
|
burp/restore.epp
|
||||||
burp/OdsDetection.epp
|
burp/OdsDetection.epp
|
||||||
utilities/gstat/dba.epp
|
|
||||||
)
|
)
|
||||||
set(epp_boot_ocxx_files
|
set(epp_boot_ocxx_files
|
||||||
isql/extract.epp
|
isql/extract.epp
|
||||||
@ -42,6 +41,7 @@ set(epp_boot_files
|
|||||||
utilities/stats.epp
|
utilities/stats.epp
|
||||||
yvalve/array.epp
|
yvalve/array.epp
|
||||||
yvalve/blob.epp
|
yvalve/blob.epp
|
||||||
|
utilities/gstat/dba.epp
|
||||||
)
|
)
|
||||||
set(epp_boot_gds_files
|
set(epp_boot_gds_files
|
||||||
dsql/metd.epp
|
dsql/metd.epp
|
||||||
@ -53,7 +53,7 @@ set(epp_boot_gds_files
|
|||||||
jrd/fun.epp
|
jrd/fun.epp
|
||||||
jrd/grant.epp
|
jrd/grant.epp
|
||||||
jrd/ini.epp
|
jrd/ini.epp
|
||||||
jrd/met.epp
|
jrd/met.epp
|
||||||
jrd/scl.epp
|
jrd/scl.epp
|
||||||
jrd/Function.epp
|
jrd/Function.epp
|
||||||
)
|
)
|
||||||
@ -69,12 +69,12 @@ set(epp_master_files
|
|||||||
|
|
||||||
if (NOT CMAKE_CROSSCOMPILING)
|
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_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_files ${GPRE_BOOT_CMD} -n -m)
|
||||||
epp_process(boot epp_boot_gds_files ${GPRE_BOOT_CMD} -n -ids -gds_cxx)
|
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_ocxx_files ${BOOT_GPRE_CMD} -n -ids -ocxx)
|
||||||
epp_process(master epp_boot_files ${BOOT_GPRE_CMD} -n -m)
|
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)
|
epp_process(master epp_boot_gds_files ${BOOT_GPRE_CMD} -n -ids -gds_cxx)
|
||||||
@ -469,9 +469,9 @@ set(engine_src ${engine_src}
|
|||||||
lock/lock.cpp
|
lock/lock.cpp
|
||||||
utilities/gsec/gsec.cpp
|
utilities/gsec/gsec.cpp
|
||||||
utilities/gstat/ppg.cpp
|
utilities/gstat/ppg.cpp
|
||||||
utilities/nbackup/nbackup.cpp
|
utilities/nbackup/nbackup.cpp
|
||||||
# parse
|
# parse
|
||||||
${GENERATED_DIR}/dsql/parse.cpp
|
${GENERATED_DIR}/dsql/parse.cpp
|
||||||
)
|
)
|
||||||
add_src_apple(engine_src
|
add_src_apple(engine_src
|
||||||
jrd/os/posix/unix.cpp
|
jrd/os/posix/unix.cpp
|
||||||
@ -487,7 +487,7 @@ set(engine_generated_src
|
|||||||
jrd/Function.epp
|
jrd/Function.epp
|
||||||
jrd/grant.epp
|
jrd/grant.epp
|
||||||
jrd/ini.epp
|
jrd/ini.epp
|
||||||
jrd/met.epp
|
jrd/met.epp
|
||||||
jrd/scl.epp
|
jrd/scl.epp
|
||||||
utilities/gstat/dba.epp
|
utilities/gstat/dba.epp
|
||||||
)
|
)
|
||||||
@ -910,7 +910,7 @@ add_custom_target(copy_files
|
|||||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${GENERATED_DIR}/security.fdb ${output_dir}/security4.fdb
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${GENERATED_DIR}/security.fdb ${output_dir}/security4.fdb
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${GENERATED_DIR}/help.fdb ${output_dir}/help/help.fdb
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${GENERATED_DIR}/help.fdb ${output_dir}/help/help.fdb
|
||||||
# configs, text files
|
# configs, text files
|
||||||
COMMAND sed "/@UDF_COMMENT@/d" < ${CMAKE_SOURCE_DIR}/builds/install/misc/firebird.conf.in > ${output_dir}/firebird.conf
|
COMMAND sed "/@UDF_COMMENT@/d" < ${CMAKE_SOURCE_DIR}/builds/install/misc/firebird.conf.in > ${output_dir}/firebird.conf
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/builds/install/misc/databases.conf.in ${output_dir}/databases.conf
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/builds/install/misc/databases.conf.in ${output_dir}/databases.conf
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/builds/install/misc/fbintl.conf ${output_dir}/intl/fbintl.conf
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/builds/install/misc/fbintl.conf ${output_dir}/intl/fbintl.conf
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/builds/install/misc/plugins.conf ${output_dir}/plugins.conf
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/builds/install/misc/plugins.conf ${output_dir}/plugins.conf
|
||||||
@ -934,7 +934,7 @@ add_custom_target(copy_files
|
|||||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/examples/udr ${output_dir}/examples/udr
|
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/examples/udr ${output_dir}/examples/udr
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/examples/stat ${output_dir}/examples/stat
|
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/examples/stat ${output_dir}/examples/stat
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/examples/functions.c ${output_dir}/examples/functions.c
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/examples/functions.c ${output_dir}/examples/functions.c
|
||||||
# headers
|
# headers
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/src/extlib/ib_util.h ${output_dir}/include/ib_util.h
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/src/extlib/ib_util.h ${output_dir}/include/ib_util.h
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/src/include/gen/iberror.h ${output_dir}/include/iberror.h
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/src/include/gen/iberror.h ${output_dir}/include/iberror.h
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/src/yvalve/perf.h ${output_dir}/include/perf.h
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/src/yvalve/perf.h ${output_dir}/include/perf.h
|
||||||
@ -986,7 +986,7 @@ if (WIN32)
|
|||||||
# installers
|
# installers
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/builds/install/arch-specific/win32/install_classic.bat ${output_dir}/install_classic.bat
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/builds/install/arch-specific/win32/install_classic.bat ${output_dir}/install_classic.bat
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/builds/install/arch-specific/win32/install_super.bat ${output_dir}/install_super.bat
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/builds/install/arch-specific/win32/install_super.bat ${output_dir}/install_super.bat
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/builds/install/arch-specific/win32/uninstall.bat ${output_dir}/uninstall.bat
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/builds/install/arch-specific/win32/uninstall.bat ${output_dir}/uninstall.bat
|
||||||
# examples
|
# examples
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/examples/build_unix ${output_dir}/examples/build_unix
|
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/examples/build_unix ${output_dir}/examples/build_unix
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/examples/build_win32 ${output_dir}/examples/build_win32
|
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/examples/build_win32 ${output_dir}/examples/build_win32
|
||||||
@ -995,7 +995,7 @@ if (WIN32)
|
|||||||
COMMAND echo "#pragma message(\"Non-production version of ibase.h.\")" > ${output_dir}/include/ibase.tmp
|
COMMAND echo "#pragma message(\"Non-production version of ibase.h.\")" > ${output_dir}/include/ibase.tmp
|
||||||
COMMAND echo "#pragma message(\"Using raw, unprocessed concatenation of header files.\")" >> ${output_dir}/include/ibase.tmp
|
COMMAND echo "#pragma message(\"Using raw, unprocessed concatenation of header files.\")" >> ${output_dir}/include/ibase.tmp
|
||||||
)
|
)
|
||||||
set(files
|
set(files
|
||||||
${CMAKE_SOURCE_DIR}/src/misc/ibase_header.txt
|
${CMAKE_SOURCE_DIR}/src/misc/ibase_header.txt
|
||||||
${CMAKE_SOURCE_DIR}/src/include/types_pub.h
|
${CMAKE_SOURCE_DIR}/src/include/types_pub.h
|
||||||
${CMAKE_SOURCE_DIR}/src/common/dsc_pub.h
|
${CMAKE_SOURCE_DIR}/src/common/dsc_pub.h
|
||||||
|
@ -199,7 +199,7 @@ private:
|
|||||||
}
|
}
|
||||||
else
|
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(),
|
att->execute(&statusWrapper, tra, sql.length(), sql.c_str(),
|
||||||
|
@ -64,8 +64,11 @@ namespace
|
|||||||
DATABASE DB = STATIC FILENAME "yachts.lnk";
|
DATABASE DB = STATIC FILENAME "yachts.lnk";
|
||||||
|
|
||||||
#define DB tdgbl->db_handle
|
#define DB tdgbl->db_handle
|
||||||
|
#define fbTrans tdgbl->tr_handle
|
||||||
#define gds_trans 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()
|
void detectRuntimeODS()
|
||||||
@ -91,7 +94,7 @@ void detectRuntimeODS()
|
|||||||
// and rdb$field_name = 'RDB$SYSTEM_FLAG';
|
// and rdb$field_name = 'RDB$SYSTEM_FLAG';
|
||||||
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
isc_req_handle req_handle = 0;
|
Firebird::IRequest* req_handle = nullptr;
|
||||||
FOR (REQUEST_HANDLE req_handle)
|
FOR (REQUEST_HANDLE req_handle)
|
||||||
RFR IN RDB$RELATION_FIELDS
|
RFR IN RDB$RELATION_FIELDS
|
||||||
WITH (RFR.RDB$RELATION_NAME = 'RDB$RELATIONS' OR RFR.RDB$RELATION_NAME = '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)
|
if (count != 2)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
isc_req_handle req_handle2 = 0;
|
Firebird::IRequest* req_handle2 = nullptr;
|
||||||
for (const rel_field_t* rel = relations; rel->relation; ++rel)
|
for (const rel_field_t* rel = relations; rel->relation; ++rel)
|
||||||
{
|
{
|
||||||
FOR (REQUEST_HANDLE req_handle2)
|
FOR (REQUEST_HANDLE req_handle2)
|
||||||
@ -125,7 +128,7 @@ void detectRuntimeODS()
|
|||||||
if (tdgbl->runtimeODS < DB_VERSION_DDL8)
|
if (tdgbl->runtimeODS < DB_VERSION_DDL8)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
isc_req_handle req_handle3 = 0;
|
Firebird::IRequest* req_handle3 = nullptr;
|
||||||
for (const rel_field_t* rf = rel_fields; rf->relation; ++rf)
|
for (const rel_field_t* rf = rel_fields; rf->relation; ++rf)
|
||||||
{
|
{
|
||||||
FOR (REQUEST_HANDLE req_handle3)
|
FOR (REQUEST_HANDLE req_handle3)
|
||||||
|
@ -57,11 +57,12 @@
|
|||||||
#include "../common/prett_proto.h"
|
#include "../common/prett_proto.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "../common/classes/UserBlob.h"
|
#include "../common/classes/BlobWrapper.h"
|
||||||
#include "../common/classes/MsgPrint.h"
|
#include "../common/classes/MsgPrint.h"
|
||||||
#include "../burp/OdsDetection.h"
|
#include "../burp/OdsDetection.h"
|
||||||
|
|
||||||
using MsgFormat::SafeArg;
|
using MsgFormat::SafeArg;
|
||||||
|
using Firebird::FbLocalStatus;
|
||||||
|
|
||||||
|
|
||||||
// For service APIs the follow DB handle is a value stored
|
// 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;
|
DATABASE DB = STATIC FILENAME "yachts.lnk" RUNTIME * dbb_file;
|
||||||
|
|
||||||
#define DB tdgbl->db_handle
|
#define DB tdgbl->db_handle
|
||||||
|
#define fbTrans tdgbl->tr_handle
|
||||||
#define gds_trans 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
|
namespace // unnamed, private
|
||||||
{
|
{
|
||||||
@ -84,18 +88,12 @@ namespace // unnamed, private
|
|||||||
|
|
||||||
inline void put(BurpGlobals* tdgbl, const UCHAR c)
|
inline void put(BurpGlobals* tdgbl, const UCHAR c)
|
||||||
{
|
{
|
||||||
if (--(tdgbl->io_cnt) >= 0)
|
tdgbl->put(c);
|
||||||
*(tdgbl->io_ptr)++ = c;
|
|
||||||
else
|
|
||||||
MVOL_write(c, &tdgbl->io_cnt, &tdgbl->io_ptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void put(BurpGlobals* tdgbl, const att_type c)
|
inline void put(BurpGlobals* tdgbl, const att_type c)
|
||||||
{
|
{
|
||||||
if (--tdgbl->io_cnt >= 0)
|
put(tdgbl, UCHAR(c));
|
||||||
*(tdgbl->io_ptr)++ = UCHAR(c);
|
|
||||||
else
|
|
||||||
MVOL_write(UCHAR(c), &tdgbl->io_cnt, &tdgbl->io_ptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const UCHAR* put_block(BurpGlobals* tdgbl, const UCHAR* p, ULONG n)
|
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_total_length,
|
||||||
isc_info_blob_num_segments
|
isc_info_blob_num_segments
|
||||||
};
|
};
|
||||||
const SCHAR db_info_items[] =
|
const UCHAR db_info_items[] =
|
||||||
{
|
{
|
||||||
isc_info_db_sql_dialect,
|
isc_info_db_sql_dialect,
|
||||||
isc_info_page_size,
|
isc_info_page_size,
|
||||||
@ -184,12 +182,12 @@ const SCHAR db_info_items[] =
|
|||||||
isc_info_db_read_only,
|
isc_info_db_read_only,
|
||||||
isc_info_end
|
isc_info_end
|
||||||
};
|
};
|
||||||
const SCHAR limbo_tpb[] =
|
const UCHAR limbo_tpb[] =
|
||||||
{
|
{
|
||||||
isc_tpb_version1,
|
isc_tpb_version1,
|
||||||
isc_tpb_ignore_limbo
|
isc_tpb_ignore_limbo
|
||||||
};
|
};
|
||||||
const SCHAR limbo_nau_tpb[] =
|
const UCHAR limbo_nau_tpb[] =
|
||||||
{
|
{
|
||||||
isc_tpb_version1,
|
isc_tpb_version1,
|
||||||
isc_tpb_ignore_limbo,
|
isc_tpb_ignore_limbo,
|
||||||
@ -211,17 +209,12 @@ int BACKUP_backup(const TEXT* dbb_file, const TEXT* file_name)
|
|||||||
* Backup a database.
|
* Backup a database.
|
||||||
*
|
*
|
||||||
**************************************/
|
**************************************/
|
||||||
ISC_STATUS_ARRAY status_vector;
|
FbLocalStatus status_vector;
|
||||||
|
|
||||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||||
|
|
||||||
tdgbl->gbl_database_file_name = dbb_file;
|
tdgbl->gbl_database_file_name = dbb_file;
|
||||||
|
|
||||||
tdgbl->io_ptr = NULL;
|
|
||||||
tdgbl->io_cnt = 0;
|
|
||||||
tdgbl->relations = NULL;
|
|
||||||
tdgbl->runtimeODS = 0;
|
|
||||||
|
|
||||||
gds_trans = 0;
|
gds_trans = 0;
|
||||||
|
|
||||||
BURP_verbose(130);
|
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 (tdgbl->gbl_sw_ignore_limbo)
|
||||||
{
|
{
|
||||||
if (isc_start_transaction(status_vector, &gds_trans, 1, &DB,
|
gds_trans = DB->startTransaction(&status_vector, sizeof(limbo_nau_tpb), limbo_nau_tpb);
|
||||||
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
|
else
|
||||||
{
|
{
|
||||||
EXEC SQL SET TRANSACTION NO_AUTO_UNDO;
|
EXEC SQL SET TRANSACTION NO_AUTO_UNDO;
|
||||||
if (isc_status[1])
|
if (isc_status->getState() & Firebird::IStatus::STATE_ERRORS)
|
||||||
EXEC SQL SET TRANSACTION;
|
EXEC SQL SET TRANSACTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gds_trans)
|
if (!gds_trans)
|
||||||
{
|
{
|
||||||
EXEC SQL SET TRANSACTION NAME gds_trans NO_AUTO_UNDO;
|
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;
|
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;
|
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
|
// Write database record
|
||||||
|
|
||||||
@ -412,7 +405,7 @@ int BACKUP_backup(const TEXT* dbb_file, const TEXT* file_name)
|
|||||||
// Finish up
|
// Finish up
|
||||||
|
|
||||||
put(tdgbl, (UCHAR) rec_end);
|
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;
|
tdgbl->action->act_action = ACT_backup_fini;
|
||||||
BURP_verbose(176, SafeArg() << cumul_count);
|
BURP_verbose(176, SafeArg() << cumul_count);
|
||||||
// msg 176 closing file, committing, and finishing. %ld bytes written
|
// 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++)
|
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)
|
if (run)
|
||||||
{
|
{
|
||||||
for (; run > 127; run -= 127)
|
for (; run > 127; run -= 127)
|
||||||
@ -827,125 +820,34 @@ SINT64 get_gen_id( const TEXT* name, SSHORT name_len)
|
|||||||
* Read id for a generator;
|
* Read id for a generator;
|
||||||
*
|
*
|
||||||
**************************************/
|
**************************************/
|
||||||
UCHAR blr_buffer[100]; // enough to fit blr
|
try
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
// build the blr with the right relation name and 64-bit results.
|
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||||
add_byte(blr, blr_version5);
|
|
||||||
add_byte(blr, blr_begin);
|
Firebird::string nm, sql;
|
||||||
add_byte(blr, blr_message);
|
nm.assign(name, name_len);
|
||||||
add_byte(blr, 0);
|
BURP_makeSymbol(tdgbl, nm);
|
||||||
add_word(blr, 1);
|
sql = "select first(1) gen_id(" + nm + ", 0) from rdb$database";
|
||||||
add_byte(blr, blr_int64);
|
|
||||||
add_byte(blr, 0);
|
BurpSql getGenerator(tdgbl, sql.c_str());
|
||||||
add_byte(blr, blr_send);
|
FB_MESSAGE(GetGen, Firebird::ThrowStatusWrapper, (FB_BIGINT, id));
|
||||||
add_byte(blr, 0);
|
GetGen getGen(&tdgbl->throwStatus, Firebird::MasterInterfacePtr());
|
||||||
add_byte(blr, blr_assignment);
|
|
||||||
add_byte(blr, blr_gen_id);
|
getGenerator.singleSelect(tdgbl->tr_handle, &getGen);
|
||||||
add_byte(blr, name_len);
|
return getGen->id;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
else
|
catch (const Firebird::FbException& ex)
|
||||||
{
|
{
|
||||||
// build the blr with the right relation name and 32-bit results
|
Firebird::IStatus* st = ex.getStatus();
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
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 ...
|
// 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
|
BURP_error_redirect(st, 25);
|
||||||
if (isc_start_request(status_vector, &gen_id_reqh, &gds_trans, 0))
|
|
||||||
{
|
|
||||||
BURP_error_redirect(status_vector, 25);
|
|
||||||
// msg 25 Failed in put_blr_gen_id
|
// msg 25 Failed in put_blr_gen_id
|
||||||
}
|
}
|
||||||
|
return 0; // warning silencer
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -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;
|
xdr_buffer.lstr_allocated = xdr_buffer.lstr_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
ISC_STATUS_ARRAY status_vector;
|
FbLocalStatus status_vector;
|
||||||
ULONG return_length = 0;
|
unsigned return_length = DB->getSlice(&status_vector, gds_trans, blob_id, blr_length, blr_buffer,
|
||||||
if (isc_get_slice(status_vector, &DB, &gds_trans, blob_id, blr_length, (const char*) blr_buffer,
|
0, nullptr, // parameters for subset of an array handling
|
||||||
0, // param length for subset of an array handling
|
slice_length, slice);
|
||||||
NULL, // param for subset of an array handling
|
|
||||||
slice_length, slice, (SLONG*) &return_length))
|
if (!status_vector.isSuccess())
|
||||||
{
|
{
|
||||||
BURP_print(false, 81, field->fld_name);
|
BURP_print(false, 81, field->fld_name);
|
||||||
// msg 81 error accessing blob field %s -- continuing
|
// msg 81 error accessing blob field %s -- continuing
|
||||||
BURP_print_status(false, status_vector);
|
BURP_print_status(false, &status_vector);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
PRETTY_print_sdl(blr_buffer, NULL, NULL, 0);
|
PRETTY_print_sdl(blr_buffer, NULL, NULL, 0);
|
||||||
#endif
|
#endif
|
||||||
@ -1179,7 +1081,7 @@ void put_array( burp_fld* field, burp_rel* relation, ISC_QUAD* blob_id)
|
|||||||
lstring xdr_slice;
|
lstring xdr_slice;
|
||||||
xdr_slice.lstr_allocated = xdr_slice.lstr_length = return_length;
|
xdr_slice.lstr_allocated = xdr_slice.lstr_length = return_length;
|
||||||
xdr_slice.lstr_address = slice;
|
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, att_xdr_array);
|
||||||
put(tdgbl, (UCHAR) (return_length));
|
put(tdgbl, (UCHAR) (return_length));
|
||||||
put(tdgbl, (UCHAR) (return_length >> 8));
|
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.
|
* This is for user data blobs.
|
||||||
*
|
*
|
||||||
**************************************/
|
**************************************/
|
||||||
ISC_STATUS_ARRAY status_vector;
|
FbLocalStatus status_vector;
|
||||||
|
|
||||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||||
|
|
||||||
// If the blob is null, don't store it. It will be restored as null.
|
// 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;
|
return;
|
||||||
|
|
||||||
// Open the blob and get it's vital statistics
|
// 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))
|
if (!blob.open(DB, gds_trans, blob_id))
|
||||||
{
|
{
|
||||||
BURP_print(false, 81, field->fld_name);
|
BURP_print(false, 81, field->fld_name);
|
||||||
// msg 81 error accessing blob field %s -- continuing
|
// msg 81 error accessing blob field %s -- continuing
|
||||||
BURP_print_status(false, status_vector);
|
BURP_print_status(false, &status_vector);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
UCHAR blob_info[32];
|
UCHAR blob_info[32];
|
||||||
if (!blob.getInfo(sizeof(blob_items), blob_items, sizeof(blob_info), blob_info))
|
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
|
// msg 20 isc_blob_info failed
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1342,13 +1244,9 @@ void put_blob( burp_fld* field, ISC_QUAD& blob_id)
|
|||||||
while (segments > 0)
|
while (segments > 0)
|
||||||
{
|
{
|
||||||
FB_SIZE_T segment_length;
|
FB_SIZE_T segment_length;
|
||||||
blob.getSegment(max_segment, buffer, segment_length);
|
if (!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))
|
|
||||||
{
|
{
|
||||||
BURP_error_redirect(status_vector, 22);
|
BURP_error_redirect(&status_vector, 22);
|
||||||
// msg 22 isc_get_segment failed
|
// msg 22 isc_get_segment failed
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1362,7 +1260,7 @@ void put_blob( burp_fld* field, ISC_QUAD& blob_id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!blob.close())
|
if (!blob.close())
|
||||||
BURP_error_redirect(status_vector, 23);
|
BURP_error_redirect(&status_vector, 23);
|
||||||
// msg 23 isc_close_blob failed
|
// msg 23 isc_close_blob failed
|
||||||
|
|
||||||
if (buffer != static_buffer)
|
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.
|
* Return true if the blob was present, false otherwise.
|
||||||
*
|
*
|
||||||
**************************************/
|
**************************************/
|
||||||
ISC_STATUS_ARRAY status_vector;
|
FbLocalStatus status_vector;
|
||||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||||
|
|
||||||
// If the blob is null, don't store it. It will be restored as null.
|
// 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;
|
return false;
|
||||||
|
|
||||||
// Open the blob and get it's vital statistics
|
// 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))
|
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
|
// msg 24 isc_open_blob failed
|
||||||
}
|
}
|
||||||
|
|
||||||
UCHAR blob_info[32];
|
UCHAR blob_info[32];
|
||||||
if (!blob.getInfo(sizeof(blr_items), blr_items, sizeof(blob_info), blob_info))
|
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
|
// 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));
|
BURP_print(true, 79, SafeArg() << int(item));
|
||||||
// msg 79 don't understand blob info item %ld
|
// msg 79 don't understand blob info item %ld
|
||||||
if (!blob.close())
|
if (!blob.close())
|
||||||
BURP_error_redirect(status_vector, 23);
|
BURP_error_redirect(&status_vector, 23);
|
||||||
// msg 23 isc_close_blob failed
|
// msg 23 isc_close_blob failed
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1442,7 +1340,7 @@ bool put_blr_blob( att_type attribute, ISC_QUAD& blob_id)
|
|||||||
if (!length)
|
if (!length)
|
||||||
{
|
{
|
||||||
if (!blob.close())
|
if (!blob.close())
|
||||||
BURP_error_redirect(status_vector, 23);
|
BURP_error_redirect(&status_vector, 23);
|
||||||
// msg 23 isc_close_blob failed
|
// msg 23 isc_close_blob failed
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1475,7 +1373,7 @@ bool put_blr_blob( att_type attribute, ISC_QUAD& blob_id)
|
|||||||
|
|
||||||
if (!blob.close())
|
if (!blob.close())
|
||||||
{
|
{
|
||||||
BURP_error_redirect(status_vector, 23);
|
BURP_error_redirect(&status_vector, 23);
|
||||||
// msg 23 isc_close_blob failed
|
// msg 23 isc_close_blob failed
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1498,17 +1396,9 @@ void put_data(burp_rel* relation)
|
|||||||
* Write relation meta-data and data.
|
* Write relation meta-data and data.
|
||||||
*
|
*
|
||||||
**************************************/
|
**************************************/
|
||||||
burp_fld* field;
|
|
||||||
ISC_STATUS_ARRAY status_vector;
|
|
||||||
|
|
||||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||||
|
USHORT field_count = 1; // eof field
|
||||||
// CVC: A signed short isn't enough if the engine allows near 32K fields,
|
burp_fld* field;
|
||||||
// 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;
|
|
||||||
|
|
||||||
for (field = relation->rel_fields; field; field = field->fld_next)
|
for (field = relation->rel_fields; field; field = field->fld_next)
|
||||||
{
|
{
|
||||||
if (!(field->fld_flags & FLD_computed))
|
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
|
add_word(blr, field_count); // Number of fields, counting eof
|
||||||
|
|
||||||
RCRD_OFFSET offset = 0;
|
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)
|
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 record_length = offset;
|
||||||
RCRD_OFFSET eof_offset = FB_ALIGN(offset, sizeof(SSHORT));
|
RCRD_OFFSET eof_offset = FB_ALIGN(offset, sizeof(SSHORT));
|
||||||
// To be used later for the buffer size to receive data
|
// 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
|
// 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_end);
|
||||||
add_byte(blr, blr_eoc);
|
add_byte(blr, blr_eoc);
|
||||||
|
|
||||||
SSHORT blr_length = blr - blr_buffer;
|
unsigned blr_length = blr - blr_buffer;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (debug_on)
|
if (debug_on)
|
||||||
@ -1728,10 +1618,11 @@ void put_data(burp_rel* relation)
|
|||||||
|
|
||||||
// Compile request
|
// Compile request
|
||||||
|
|
||||||
FB_API_HANDLE request = 0;
|
FbLocalStatus status_vector;
|
||||||
if (isc_compile_request(status_vector, &DB, &request, blr_length, (const SCHAR*) blr_buffer))
|
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
|
// msg 27 isc_compile_request failed
|
||||||
fb_print_blr(blr_buffer, blr_length, NULL, NULL, 0);
|
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);
|
BURP_verbose(142, relation->rel_name);
|
||||||
// msg 142 writing data for relation %s
|
// 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
|
// msg 28 isc_start_request failed
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1766,9 +1658,10 @@ void put_data(burp_rel* relation)
|
|||||||
ULONG records = 0;
|
ULONG records = 0;
|
||||||
while (true)
|
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
|
// msg 29 isc_receive failed
|
||||||
}
|
}
|
||||||
if (!*eof)
|
if (!*eof)
|
||||||
@ -1783,7 +1676,7 @@ void put_data(burp_rel* relation)
|
|||||||
const UCHAR* p;
|
const UCHAR* p;
|
||||||
if (tdgbl->gbl_sw_transportable)
|
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);
|
put_int32(att_xdr_length, record_length);
|
||||||
p = xdr_buffer.lstr_address;
|
p = xdr_buffer.lstr_address;
|
||||||
}
|
}
|
||||||
@ -1825,8 +1718,9 @@ void put_data(burp_rel* relation)
|
|||||||
BURP_verbose(108, SafeArg() << records);
|
BURP_verbose(108, SafeArg() << records);
|
||||||
// msg 108 %ld records written
|
// msg 108 %ld records written
|
||||||
|
|
||||||
if (isc_release_request(status_vector, &request))
|
request->free(&status_vector);
|
||||||
BURP_error_redirect(status_vector, 30);
|
if (!status_vector.isSuccess())
|
||||||
|
BURP_error_redirect(&status_vector, 30);
|
||||||
// msg 30 isc_release_request failed
|
// 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.
|
* Include the NULL character to separate each segment.
|
||||||
*
|
*
|
||||||
**************************************/
|
**************************************/
|
||||||
ISC_STATUS_ARRAY status_vector;
|
FbLocalStatus status_vector;
|
||||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||||
|
|
||||||
// If the blob is null, don't store it. It will be restored as null.
|
// 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;
|
return false;
|
||||||
|
|
||||||
if (tdgbl->gbl_sw_old_descriptions && attribute != att_field_query_header)
|
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
|
// 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))
|
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
|
// msg 24 isc_open_blob failed
|
||||||
}
|
}
|
||||||
|
|
||||||
UCHAR blob_info[48];
|
UCHAR blob_info[48];
|
||||||
if (!blob.getInfo(sizeof(source_items), source_items, sizeof(blob_info), blob_info))
|
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
|
// 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
|
// msg 79 don't understand blob info item %ld
|
||||||
if (!blob.close())
|
if (!blob.close())
|
||||||
{
|
{
|
||||||
BURP_error_redirect(status_vector, 23);
|
BURP_error_redirect(&status_vector, 23);
|
||||||
// msg 23 isc_close_blob failed
|
// msg 23 isc_close_blob failed
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -2325,7 +2219,7 @@ bool put_source_blob(att_type attribute, att_type old_attribute, ISC_QUAD& blob_
|
|||||||
{
|
{
|
||||||
if (!blob.close())
|
if (!blob.close())
|
||||||
{
|
{
|
||||||
BURP_error_redirect(status_vector, 23);
|
BURP_error_redirect(&status_vector, 23);
|
||||||
// msg 23 isc_close_blob failed
|
// msg 23 isc_close_blob failed
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -2360,7 +2254,7 @@ bool put_source_blob(att_type attribute, att_type old_attribute, ISC_QUAD& blob_
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!blob.close())
|
if (!blob.close())
|
||||||
BURP_error_redirect(status_vector, 23);
|
BURP_error_redirect(&status_vector, 23);
|
||||||
// msg 23 isc_close_blob failed
|
// msg 23 isc_close_blob failed
|
||||||
|
|
||||||
if (buffer != static_buffer)
|
if (buffer != static_buffer)
|
||||||
@ -2420,7 +2314,7 @@ void write_character_sets()
|
|||||||
* each user defined character set.
|
* each user defined character set.
|
||||||
*
|
*
|
||||||
**************************************/
|
**************************************/
|
||||||
isc_req_handle req_handle1 = 0;
|
Firebird::IRequest* req_handle1 = nullptr;
|
||||||
|
|
||||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||||
|
|
||||||
@ -2518,7 +2412,7 @@ void write_check_constraints()
|
|||||||
* each check constraint.
|
* each check constraint.
|
||||||
*
|
*
|
||||||
**************************************/
|
**************************************/
|
||||||
isc_req_handle req_handle1 = 0;
|
Firebird::IRequest* req_handle1 = nullptr;
|
||||||
|
|
||||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||||
|
|
||||||
@ -2552,7 +2446,7 @@ void write_collations()
|
|||||||
* each user defined collation
|
* each user defined collation
|
||||||
*
|
*
|
||||||
**************************************/
|
**************************************/
|
||||||
isc_req_handle req_handle1 = 0;
|
Firebird::IRequest* req_handle1 = nullptr;
|
||||||
|
|
||||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||||
|
|
||||||
@ -2652,28 +2546,29 @@ void write_database( const TEXT* dbb_file)
|
|||||||
* the database itself.
|
* the database itself.
|
||||||
*
|
*
|
||||||
**************************************/
|
**************************************/
|
||||||
ISC_STATUS_ARRAY status_vector;
|
FbLocalStatus status_vector;
|
||||||
SCHAR buffer[256];
|
UCHAR buffer[256];
|
||||||
isc_req_handle req_handle1 = 0;
|
Firebird::IRequest* req_handle1 = nullptr;
|
||||||
|
|
||||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||||
|
|
||||||
put(tdgbl, (UCHAR) rec_physical_db);
|
put(tdgbl, (UCHAR) rec_physical_db);
|
||||||
|
|
||||||
if (isc_database_info(status_vector, &DB, sizeof(db_info_items), db_info_items,
|
DB->getInfo(&status_vector, sizeof(db_info_items), db_info_items,
|
||||||
sizeof(buffer), buffer))
|
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
|
// msg 31 isc_database_info failed
|
||||||
}
|
}
|
||||||
|
|
||||||
USHORT page_size = 0, forced_writes, no_reserve, SQL_dialect, db_read_only;
|
USHORT page_size = 0, forced_writes, no_reserve, SQL_dialect, db_read_only;
|
||||||
ULONG sweep_interval, page_buffers;
|
ULONG sweep_interval, page_buffers;
|
||||||
USHORT length = 0;
|
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++;
|
const UCHAR item = *d++;
|
||||||
length = (USHORT) isc_vax_integer(d, 2);
|
length = (USHORT) gds__vax_integer(d, 2);
|
||||||
d += 2;
|
d += 2;
|
||||||
switch (item)
|
switch (item)
|
||||||
{
|
{
|
||||||
@ -2681,27 +2576,27 @@ void write_database( const TEXT* dbb_file)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case isc_info_page_size:
|
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);
|
put_int32(att_page_size, page_size);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case isc_info_sweep_interval:
|
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);
|
put_int32(att_sweep_interval, sweep_interval);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case isc_info_forced_writes:
|
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);
|
put_int32(att_forced_writes, forced_writes);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case isc_info_no_reserve:
|
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);
|
put_int32(att_no_reserve, no_reserve);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case isc_info_set_page_buffers:
|
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);
|
put_int32(att_page_buffers, page_buffers);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -2709,17 +2604,17 @@ void write_database( const TEXT* dbb_file)
|
|||||||
break; // parameter and returns isc_info_error. skip it
|
break; // parameter and returns isc_info_error. skip it
|
||||||
|
|
||||||
case isc_info_db_sql_dialect:
|
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);
|
put_int32(att_SQL_dialect, SQL_dialect);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case isc_info_db_read_only:
|
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);
|
put_int32(att_db_read_only, db_read_only);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
BURP_error_redirect(status_vector, 31);
|
BURP_error_redirect(&status_vector, 31);
|
||||||
// msg 31 isc_database_info failed
|
// msg 31 isc_database_info failed
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2787,7 +2682,7 @@ void write_exceptions()
|
|||||||
*
|
*
|
||||||
**************************************/
|
**************************************/
|
||||||
TEXT temp[GDS_NAME_LEN];
|
TEXT temp[GDS_NAME_LEN];
|
||||||
isc_req_handle req_handle1 = 0;
|
Firebird::IRequest* req_handle1 = nullptr;
|
||||||
|
|
||||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||||
|
|
||||||
@ -2851,7 +2746,7 @@ void write_field_dimensions()
|
|||||||
* each array field dimension.
|
* each array field dimension.
|
||||||
*
|
*
|
||||||
**************************************/
|
**************************************/
|
||||||
isc_req_handle req_handle1 = 0;
|
Firebird::IRequest* req_handle1 = nullptr;
|
||||||
|
|
||||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||||
|
|
||||||
@ -2886,7 +2781,7 @@ void write_filters()
|
|||||||
*
|
*
|
||||||
**************************************/
|
**************************************/
|
||||||
TEXT temp[GDS_NAME_LEN];
|
TEXT temp[GDS_NAME_LEN];
|
||||||
isc_req_handle req_handle1 = 0;
|
Firebird::IRequest* req_handle1 = nullptr;
|
||||||
|
|
||||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||||
|
|
||||||
@ -2928,7 +2823,7 @@ void write_functions()
|
|||||||
**************************************/
|
**************************************/
|
||||||
GDS_NAME func;
|
GDS_NAME func;
|
||||||
TEXT temp[GDS_NAME_LEN * 2];
|
TEXT temp[GDS_NAME_LEN * 2];
|
||||||
isc_req_handle req_handle1 = 0;
|
Firebird::IRequest* req_handle1 = nullptr;
|
||||||
|
|
||||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||||
|
|
||||||
@ -3182,7 +3077,7 @@ void write_generators()
|
|||||||
* Write any defined generators.
|
* Write any defined generators.
|
||||||
*
|
*
|
||||||
**************************************/
|
**************************************/
|
||||||
isc_req_handle req_handle1 = 0;
|
Firebird::IRequest* req_handle1 = nullptr;
|
||||||
TEXT temp[GDS_NAME_LEN];
|
TEXT temp[GDS_NAME_LEN];
|
||||||
|
|
||||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||||
@ -3291,7 +3186,7 @@ void write_global_fields()
|
|||||||
*
|
*
|
||||||
**************************************/
|
**************************************/
|
||||||
TEXT temp[GDS_NAME_LEN];
|
TEXT temp[GDS_NAME_LEN];
|
||||||
isc_req_handle req_handle1 = 0;
|
Firebird::IRequest* req_handle1 = nullptr;
|
||||||
|
|
||||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||||
|
|
||||||
@ -3522,7 +3417,7 @@ void write_packages()
|
|||||||
*
|
*
|
||||||
**************************************/
|
**************************************/
|
||||||
TEXT temp[GDS_NAME_LEN];
|
TEXT temp[GDS_NAME_LEN];
|
||||||
isc_req_handle req_handle1 = 0;
|
Firebird::IRequest* req_handle1 = nullptr;
|
||||||
|
|
||||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||||
|
|
||||||
@ -3589,7 +3484,7 @@ void write_procedures()
|
|||||||
**************************************/
|
**************************************/
|
||||||
GDS_NAME proc;
|
GDS_NAME proc;
|
||||||
TEXT temp[GDS_NAME_LEN * 2];
|
TEXT temp[GDS_NAME_LEN * 2];
|
||||||
isc_req_handle req_handle1 = 0;
|
Firebird::IRequest* req_handle1 = nullptr;
|
||||||
|
|
||||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||||
|
|
||||||
@ -3779,7 +3674,7 @@ void write_ref_constraints()
|
|||||||
* each referential constraint.
|
* each referential constraint.
|
||||||
*
|
*
|
||||||
**************************************/
|
**************************************/
|
||||||
isc_req_handle req_handle1 = 0;
|
Firebird::IRequest* req_handle1 = nullptr;
|
||||||
|
|
||||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||||
|
|
||||||
@ -3815,7 +3710,7 @@ void write_rel_constraints()
|
|||||||
*
|
*
|
||||||
**************************************/
|
**************************************/
|
||||||
TEXT temp[GDS_NAME_LEN];
|
TEXT temp[GDS_NAME_LEN];
|
||||||
isc_req_handle req_handle1 = 0;
|
Firebird::IRequest* req_handle1 = nullptr;
|
||||||
|
|
||||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||||
|
|
||||||
@ -3859,7 +3754,7 @@ void write_relations()
|
|||||||
*
|
*
|
||||||
**************************************/
|
**************************************/
|
||||||
TEXT temp[GDS_NAME_LEN];
|
TEXT temp[GDS_NAME_LEN];
|
||||||
isc_req_handle req_handle1 = 0;
|
Firebird::IRequest* req_handle1 = nullptr;
|
||||||
|
|
||||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||||
|
|
||||||
@ -3989,7 +3884,7 @@ void write_relations()
|
|||||||
void write_secclasses()
|
void write_secclasses()
|
||||||
{
|
{
|
||||||
TEXT temp[GDS_NAME_LEN];
|
TEXT temp[GDS_NAME_LEN];
|
||||||
isc_req_handle req_handle1 = 0;
|
Firebird::IRequest* req_handle1 = nullptr;
|
||||||
|
|
||||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||||
|
|
||||||
@ -4025,7 +3920,7 @@ void write_shadow_files()
|
|||||||
*
|
*
|
||||||
**************************************/
|
**************************************/
|
||||||
BASED ON RDB$FILES.RDB$FILE_NAME temp;
|
BASED ON RDB$FILES.RDB$FILE_NAME temp;
|
||||||
isc_req_handle req_handle1 = 0;
|
Firebird::IRequest* req_handle1 = nullptr;
|
||||||
|
|
||||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||||
|
|
||||||
@ -4066,7 +3961,7 @@ void write_sql_roles()
|
|||||||
* each SQL roles.
|
* each SQL roles.
|
||||||
*
|
*
|
||||||
**************************************/
|
**************************************/
|
||||||
isc_req_handle req_handle1 = 0;
|
Firebird::IRequest* req_handle1 = nullptr;
|
||||||
TEXT temp[GDS_NAME_LEN];
|
TEXT temp[GDS_NAME_LEN];
|
||||||
|
|
||||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||||
@ -4135,7 +4030,7 @@ void write_mapping()
|
|||||||
* each names mapping.
|
* each names mapping.
|
||||||
*
|
*
|
||||||
**************************************/
|
**************************************/
|
||||||
isc_req_handle req_handle = 0;
|
Firebird::IRequest* req_handle = nullptr;
|
||||||
TEXT temp[GDS_NAME_LEN];
|
TEXT temp[GDS_NAME_LEN];
|
||||||
|
|
||||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||||
@ -4218,7 +4113,7 @@ void write_triggers()
|
|||||||
*
|
*
|
||||||
**************************************/
|
**************************************/
|
||||||
TEXT temp[GDS_NAME_LEN];
|
TEXT temp[GDS_NAME_LEN];
|
||||||
isc_req_handle req_handle1 = 0;
|
Firebird::IRequest* req_handle1 = nullptr;
|
||||||
|
|
||||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||||
|
|
||||||
@ -4335,7 +4230,7 @@ void write_trigger_messages()
|
|||||||
*
|
*
|
||||||
**************************************/
|
**************************************/
|
||||||
TEXT temp[GDS_NAME_LEN];
|
TEXT temp[GDS_NAME_LEN];
|
||||||
isc_req_handle req_handle1 = 0;
|
Firebird::IRequest* req_handle1 = nullptr;
|
||||||
|
|
||||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||||
|
|
||||||
@ -4374,7 +4269,7 @@ void write_types()
|
|||||||
* each type.
|
* each type.
|
||||||
*
|
*
|
||||||
**************************************/
|
**************************************/
|
||||||
isc_req_handle req_handle1 = 0;
|
Firebird::IRequest* req_handle1 = nullptr;
|
||||||
|
|
||||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||||
|
|
||||||
@ -4414,7 +4309,7 @@ void write_user_privileges()
|
|||||||
*
|
*
|
||||||
**************************************/
|
**************************************/
|
||||||
TEXT temp[GDS_NAME_LEN];
|
TEXT temp[GDS_NAME_LEN];
|
||||||
isc_req_handle req_handle1 = 0;
|
Firebird::IRequest* req_handle1 = nullptr;
|
||||||
|
|
||||||
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||||
|
|
||||||
|
@ -65,6 +65,7 @@
|
|||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#endif
|
#endif
|
||||||
#include "../common/utils_proto.h"
|
#include "../common/utils_proto.h"
|
||||||
|
#include "../common/status.h"
|
||||||
|
|
||||||
#ifdef HAVE_UNISTD_H
|
#ifdef HAVE_UNISTD_H
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -82,6 +83,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
using MsgFormat::SafeArg;
|
using MsgFormat::SafeArg;
|
||||||
|
using Firebird::FbLocalStatus;
|
||||||
|
|
||||||
const char* fopen_write_type = "w";
|
const char* fopen_write_type = "w";
|
||||||
const char* fopen_read_type = "r";
|
const char* fopen_read_type = "r";
|
||||||
@ -102,7 +104,7 @@ enum gbak_action
|
|||||||
//FDESC = 3 // CVC: Unused
|
//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 enable_signals();
|
||||||
//static void excp_handler();
|
//static void excp_handler();
|
||||||
static SLONG get_number(const SCHAR*);
|
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];
|
const Firebird::string* dbName = flag_restore ? &files[1] : &files[0];
|
||||||
|
|
||||||
ISC_STATUS_ARRAY status;
|
FbLocalStatus status;
|
||||||
FB_API_HANDLE svc_handle = 0;
|
Firebird::IService* svc_handle = nullptr;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -317,21 +319,22 @@ static int svc_api_gbak(Firebird::UtilSvc* uSvc, const Switches& switches)
|
|||||||
|
|
||||||
spb.insertString(isc_spb_command_line, options);
|
spb.insertString(isc_spb_command_line, options);
|
||||||
|
|
||||||
if (isc_service_attach(status, 0, service.c_str(), &svc_handle,
|
svc_handle = Firebird::DispatcherPtr()->attachServiceManager(&status, service.c_str(),
|
||||||
spb.getBufferLength(), reinterpret_cast<const char*>(spb.getBuffer())))
|
spb.getBufferLength(), spb.getBuffer());
|
||||||
|
if (!status.isSuccess())
|
||||||
{
|
{
|
||||||
BURP_print_status(true, status);
|
BURP_print_status(true, &status);
|
||||||
BURP_print(true, 83);
|
BURP_print(true, 83);
|
||||||
// msg 83 Exiting before completion due to errors
|
// msg 83 Exiting before completion due to errors
|
||||||
return FINI_ERROR;
|
return FINI_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
char thd[10];
|
UCHAR thd[10];
|
||||||
// 'isc_action_svc_restore/isc_action_svc_backup'
|
// 'isc_action_svc_restore/isc_action_svc_backup'
|
||||||
// 'isc_spb_verbose'
|
// 'isc_spb_verbose'
|
||||||
// 'isc_spb_verbint'
|
// 'isc_spb_verbint'
|
||||||
|
|
||||||
char* thd_ptr = thd;
|
UCHAR* thd_ptr = thd;
|
||||||
if (flag_restore)
|
if (flag_restore)
|
||||||
*thd_ptr++ = isc_action_svc_restore;
|
*thd_ptr++ = isc_action_svc_restore;
|
||||||
else
|
else
|
||||||
@ -344,41 +347,43 @@ static int svc_api_gbak(Firebird::UtilSvc* uSvc, const Switches& switches)
|
|||||||
{
|
{
|
||||||
*thd_ptr++ = isc_spb_verbint;
|
*thd_ptr++ = isc_spb_verbint;
|
||||||
//stream verbint_val into a SPB
|
//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);
|
thd_ptr += sizeof(SLONG);
|
||||||
}
|
}
|
||||||
|
|
||||||
const USHORT thdlen = thd_ptr - thd;
|
const USHORT thdlen = thd_ptr - thd;
|
||||||
fb_assert(thdlen <= sizeof(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);
|
BURP_print_status(true, &status);
|
||||||
isc_service_detach(status, &svc_handle);
|
svc_handle->release();
|
||||||
BURP_print(true, 83); // msg 83 Exiting before completion due to errors
|
BURP_print(true, 83); // msg 83 Exiting before completion due to errors
|
||||||
return FINI_ERROR;
|
return FINI_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char sendbuf[] = { isc_info_svc_line };
|
const UCHAR sendbuf[] = { isc_info_svc_line };
|
||||||
char respbuf[1024];
|
UCHAR respbuf[1024];
|
||||||
const char* sl;
|
const UCHAR* sl;
|
||||||
do {
|
do {
|
||||||
if (isc_service_query(status, &svc_handle, NULL, 0, NULL,
|
svc_handle->query(&status, 0, NULL,
|
||||||
sizeof(sendbuf), sendbuf,
|
sizeof(sendbuf), sendbuf,
|
||||||
sizeof(respbuf), respbuf))
|
sizeof(respbuf), respbuf);
|
||||||
|
if (!status.isSuccess())
|
||||||
{
|
{
|
||||||
BURP_print_status(true, status);
|
BURP_print_status(true, &status);
|
||||||
isc_service_detach(status, &svc_handle);
|
svc_handle->release();
|
||||||
BURP_print(true, 83); // msg 83 Exiting before completion due to errors
|
BURP_print(true, 83); // msg 83 Exiting before completion due to errors
|
||||||
return FINI_ERROR;
|
return FINI_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* p = respbuf;
|
UCHAR* p = respbuf;
|
||||||
sl = p;
|
sl = p;
|
||||||
|
|
||||||
if (*p++ == isc_info_svc_line)
|
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);
|
p += sizeof(ISC_USHORT);
|
||||||
if (!len)
|
if (!len)
|
||||||
{
|
{
|
||||||
@ -395,18 +400,16 @@ static int svc_api_gbak(Firebird::UtilSvc* uSvc, const Switches& switches)
|
|||||||
}
|
}
|
||||||
} while (*sl == isc_info_svc_line);
|
} while (*sl == isc_info_svc_line);
|
||||||
|
|
||||||
isc_service_detach(status, &svc_handle);
|
svc_handle->release();
|
||||||
return FINI_OK;
|
return FINI_OK;
|
||||||
}
|
}
|
||||||
catch (const Firebird::Exception& e)
|
catch (const Firebird::Exception& e)
|
||||||
{
|
{
|
||||||
Firebird::StaticStatusVector s;
|
FbLocalStatus s;
|
||||||
e.stuffException(s);
|
e.stuffException(&s);
|
||||||
BURP_print_status(true, s.begin());
|
BURP_print_status(true, &s);
|
||||||
if (svc_handle)
|
if (svc_handle)
|
||||||
{
|
svc_handle->release();
|
||||||
isc_service_detach(status, &svc_handle);
|
|
||||||
}
|
|
||||||
BURP_print(true, 83); // msg 83 Exiting before completion due to errors
|
BURP_print(true, 83); // msg 83 Exiting before completion due to errors
|
||||||
return FINI_ERROR;
|
return FINI_ERROR;
|
||||||
}
|
}
|
||||||
@ -723,6 +726,41 @@ int gbak(Firebird::UtilSvc* uSvc)
|
|||||||
}
|
}
|
||||||
tdgbl->gbl_sw_sql_role = argv[itr];
|
tdgbl->gbl_sw_sql_role = argv[itr];
|
||||||
break;
|
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:
|
case IN_SW_BURP_FA:
|
||||||
if (tdgbl->gbl_sw_blk_factor)
|
if (tdgbl->gbl_sw_blk_factor)
|
||||||
BURP_error(333, true, SafeArg() << in_sw_tab->in_sw_name << 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)
|
else if (tdgbl->gbl_sw_old_descriptions)
|
||||||
errNum = IN_SW_BURP_OL;
|
errNum = IN_SW_BURP_OL;
|
||||||
|
else if (tdgbl->gbl_sw_zip)
|
||||||
|
errNum = IN_SW_BURP_ZIP;
|
||||||
|
|
||||||
if (errNum != IN_SW_BURP_0)
|
if (errNum != IN_SW_BURP_0)
|
||||||
{
|
{
|
||||||
@ -1285,10 +1325,8 @@ int gbak(Firebird::UtilSvc* uSvc)
|
|||||||
{
|
{
|
||||||
// Non-burp exception was caught
|
// Non-burp exception was caught
|
||||||
tdgbl->burp_throw = false;
|
tdgbl->burp_throw = false;
|
||||||
Firebird::StaticStatusVector s;
|
e.stuffException(&tdgbl->status_vector);
|
||||||
e.stuffException(s);
|
BURP_print_status(true, &tdgbl->status_vector);
|
||||||
fb_utils::copyStatus(tdgbl->status_vector, ISC_STATUS_LENGTH, s.begin(), s.getCount());
|
|
||||||
BURP_print_status(true, tdgbl->status_vector);
|
|
||||||
if (! tdgbl->uSvc->isService())
|
if (! tdgbl->uSvc->isService())
|
||||||
{
|
{
|
||||||
BURP_print(true, 83); // msg 83 Exiting before completion due to errors
|
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
|
// 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->tr_handle);
|
||||||
close_out_transaction(action, &tdgbl->global_trans);
|
close_out_transaction(action, &tdgbl->global_trans);
|
||||||
if (isc_detach_database(tdgbl->status_vector, &tdgbl->db_handle))
|
|
||||||
{
|
tdgbl->db_handle->detach(&tdgbl->status_vector);
|
||||||
BURP_print_status(true, 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
|
// 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);
|
strcpy(output_msg, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OutputVersion::callback(Firebird::CheckStatusWrapper* status, const char* text)
|
||||||
void BURP_output_version(void* arg1, const TEXT* arg2)
|
|
||||||
{
|
{
|
||||||
/**************************************
|
/**************************************
|
||||||
*
|
*
|
||||||
* 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
|
* Functional description
|
||||||
* Callback routine for access method
|
* Callback routine for access method
|
||||||
* printing (specifically show version);
|
* printing (specifically show version)
|
||||||
* will accept.
|
* 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)
|
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)
|
if (status_vector)
|
||||||
{
|
{
|
||||||
const ISC_STATUS* vector = status_vector;
|
const ISC_STATUS* vector = status_vector->getErrors();
|
||||||
|
|
||||||
if (err)
|
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.
|
* 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
|
// print the warning message
|
||||||
const ISC_STATUS* vector = &status_vector[2];
|
const ISC_STATUS* vector = status->getWarnings();
|
||||||
SCHAR s[1024];
|
SCHAR s[1024];
|
||||||
|
|
||||||
if (fb_interpret(s, sizeof(s), &vector))
|
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.
|
* returned to the system.
|
||||||
*
|
*
|
||||||
**************************************/
|
**************************************/
|
||||||
if (*handle != 0)
|
if (*tPtr)
|
||||||
{
|
{
|
||||||
ISC_STATUS_ARRAY status_vector;
|
FbLocalStatus status_vector;
|
||||||
if (action == RESTORE)
|
if (action == RESTORE)
|
||||||
{
|
{
|
||||||
// Even if the restore failed, commit the transaction so that
|
// Even if the restore failed, commit the transaction so that
|
||||||
// a partial database is at least recovered.
|
// a partial database is at least recovered.
|
||||||
isc_commit_transaction(status_vector, handle);
|
(*tPtr)->commit(&status_vector);
|
||||||
if (status_vector[1])
|
if (!status_vector.isSuccess())
|
||||||
{
|
{
|
||||||
// If we can't commit - have to roll it back, as
|
// If we can't commit - have to roll it back, as
|
||||||
// we need to close all outstanding transactions before
|
// we need to close all outstanding transactions before
|
||||||
// we can detach from the database.
|
// we can detach from the database.
|
||||||
isc_rollback_transaction(status_vector, handle);
|
(*tPtr)->rollback(&status_vector);
|
||||||
if (status_vector[1])
|
if (!status_vector.isSuccess())
|
||||||
BURP_print_status(false, status_vector);
|
BURP_print_status(false, &status_vector);
|
||||||
|
else
|
||||||
|
*tPtr = nullptr;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
*tPtr = nullptr;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// A backup shouldn't touch any data - we ensure that
|
// A backup shouldn't touch any data - we ensure that
|
||||||
// by never writing data during a backup, but let's double
|
// by never writing data during a backup, but let's double
|
||||||
// ensure it by doing a rollback
|
// ensure it by doing a rollback
|
||||||
if (isc_rollback_transaction(status_vector, handle))
|
(*tPtr)->rollback(&status_vector);
|
||||||
BURP_print_status(false, 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();
|
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
|
||||||
ISC_STATUS_ARRAY temp_status;
|
FbLocalStatus status_vector;
|
||||||
ISC_STATUS* status_vector = temp_status;
|
|
||||||
|
|
||||||
// try to attach the database using the first file_name
|
// try to attach the database using the first file_name
|
||||||
|
|
||||||
if (sw_replace != IN_SW_BURP_C && sw_replace != IN_SW_BURP_R)
|
if (sw_replace != IN_SW_BURP_C && sw_replace != IN_SW_BURP_R)
|
||||||
{
|
{
|
||||||
if (!isc_attach_database(status_vector,
|
Firebird::DispatcherPtr provider;
|
||||||
(SSHORT) 0, file1,
|
|
||||||
&tdgbl->db_handle,
|
// provide crypt key(s) for engine
|
||||||
dpb.getBufferLength(),
|
|
||||||
reinterpret_cast<const char*>(dpb.getBuffer())))
|
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)
|
if (sw_replace != IN_SW_BURP_B)
|
||||||
{
|
{
|
||||||
// msg 13 REPLACE specified, but the first file %s is a database
|
// msg 13 REPLACE specified, but the first file %s is a database
|
||||||
BURP_error(13, true, file1);
|
BURP_error(13, true, file1);
|
||||||
if (isc_detach_database(status_vector, &tdgbl->db_handle)) {
|
tdgbl->db_handle->detach(&status_vector);
|
||||||
BURP_print_status(true, status_vector);
|
|
||||||
}
|
if (status_vector->getState() & Firebird::IStatus::STATE_ERRORS)
|
||||||
|
BURP_print_status(true, &status_vector);
|
||||||
|
else
|
||||||
|
tdgbl->db_handle = NULL;
|
||||||
|
|
||||||
return QUIT;
|
return QUIT;
|
||||||
}
|
}
|
||||||
if (tdgbl->gbl_sw_version)
|
if (tdgbl->gbl_sw_version)
|
||||||
{
|
{
|
||||||
// msg 139 Version(s) for database "%s"
|
// msg 139 Version(s) for database "%s"
|
||||||
BURP_print(false, 139, file1);
|
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
|
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 ||
|
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;
|
return QUIT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1919,7 +2023,7 @@ static gbak_action open_files(const TEXT* file1,
|
|||||||
{
|
{
|
||||||
Firebird::string nm = tdgbl->toSystem(fil->fil_name);
|
Firebird::string nm = tdgbl->toSystem(fil->fil_name);
|
||||||
#ifdef WIN_NT
|
#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)
|
INVALID_HANDLE_VALUE)
|
||||||
#else
|
#else
|
||||||
if ((fil->fil_fd = os_utils::open(nm.c_str(), MODE_WRITE, open_mask)) == -1)
|
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
|
else
|
||||||
{
|
{
|
||||||
if (isc_detach_database(status_vector, &tdgbl->db_handle))
|
tdgbl->db_handle->detach(&status_vector);
|
||||||
{
|
|
||||||
BURP_print_status(false, status_vector);
|
if (status_vector->getState() & Firebird::IStatus::STATE_ERRORS)
|
||||||
}
|
BURP_print_status(true, &status_vector);
|
||||||
|
else
|
||||||
|
tdgbl->db_handle = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return flag;
|
return flag;
|
||||||
@ -2027,7 +2133,7 @@ static gbak_action open_files(const TEXT* file1,
|
|||||||
// open first file
|
// open first file
|
||||||
Firebird::string nm = tdgbl->toSystem(fil->fil_name);
|
Firebird::string nm = tdgbl->toSystem(fil->fil_name);
|
||||||
#ifdef WIN_NT
|
#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)
|
INVALID_HANDLE_VALUE)
|
||||||
#else
|
#else
|
||||||
if ((fil->fil_fd = os_utils::open(nm.c_str(), MODE_READ)) == INVALID_HANDLE_VALUE)
|
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;
|
tdgbl->action->act_file = fil;
|
||||||
Firebird::string nm = tdgbl->toSystem(fil->fil_name);
|
Firebird::string nm = tdgbl->toSystem(fil->fil_name);
|
||||||
#ifdef WIN_NT
|
#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)
|
INVALID_HANDLE_VALUE)
|
||||||
#else
|
#else
|
||||||
if ((fil->fil_fd = os_utils::open(nm.c_str(), MODE_READ)) == INVALID_HANDLE_VALUE)
|
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);
|
BURP_error(262, true, *file2);
|
||||||
// msg 262 size specification either missing or incorrect for file %s
|
// msg 262 size specification either missing or incorrect for file %s
|
||||||
|
|
||||||
if ((sw_replace == IN_SW_BURP_C || sw_replace == IN_SW_BURP_R) &&
|
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)
|
Firebird::DispatcherPtr provider;
|
||||||
|
|
||||||
|
// provide crypt key(s) for engine
|
||||||
|
|
||||||
|
if (tdgbl->gbl_sw_keyholder)
|
||||||
{
|
{
|
||||||
if (isc_detach_database(status_vector, &tdgbl->db_handle)) {
|
tdgbl->gbl_database_file_name = *file2;
|
||||||
BURP_print_status(true, status_vector);
|
provider->setDbCryptCallback(&status_vector, MVOL_get_crypt(tdgbl));
|
||||||
}
|
if (!status_vector.isSuccess())
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
ISC_STATUS_ARRAY status_vector2;
|
BURP_print_status(true, &status_vector);
|
||||||
if (isc_detach_database(status_vector2, &tdgbl->db_handle)) {
|
return QUIT;
|
||||||
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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
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);
|
tdgbl->db_handle = provider->attachDatabase(&status_vector, *file2,
|
||||||
// msg # 274 : Cannot restore over current database, must be sysdba
|
dpb.getBufferLength(), dpb.getBuffer());
|
||||||
// or owner of the existing database.
|
|
||||||
|
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
|
// check the file size specification
|
||||||
@ -2458,18 +2586,18 @@ void BurpGlobals::read_stats(SINT64* stats)
|
|||||||
if (!db_handle)
|
if (!db_handle)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const char info[] =
|
const UCHAR info[] =
|
||||||
{
|
{
|
||||||
isc_info_reads,
|
isc_info_reads,
|
||||||
isc_info_writes
|
isc_info_writes
|
||||||
};
|
};
|
||||||
|
|
||||||
ISC_STATUS_ARRAY status = {0};
|
FbLocalStatus status;
|
||||||
char buffer[sizeof(info) * (1 + 2 + 8) + 2];
|
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)
|
while (p < e)
|
||||||
{
|
{
|
||||||
int flag = -1;
|
int flag = -1;
|
||||||
@ -2490,7 +2618,7 @@ void BurpGlobals::read_stats(SINT64* stats)
|
|||||||
|
|
||||||
if (flag != -1)
|
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);
|
stats[flag] = isc_portable_integer((ISC_UCHAR*) p + 1 + 2, len);
|
||||||
p += len + 3;
|
p += len + 3;
|
||||||
}
|
}
|
||||||
@ -2603,3 +2731,21 @@ UnicodeCollationHolder::~UnicodeCollationHolder()
|
|||||||
// cs should be deleted by texttype_fn_destroy call above
|
// cs should be deleted by texttype_fn_destroy call above
|
||||||
delete tt;
|
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 <stdio.h>
|
||||||
#include "../jrd/ibase.h"
|
#include "../jrd/ibase.h"
|
||||||
|
#include "firebird/Interface.h"
|
||||||
|
#include "firebird/Message.h"
|
||||||
#include "../common/dsc.h"
|
#include "../common/dsc.h"
|
||||||
#include "../burp/misc_proto.h"
|
#include "../burp/misc_proto.h"
|
||||||
|
#include "../burp/mvol_proto.h"
|
||||||
#include "../yvalve/gds_proto.h"
|
#include "../yvalve/gds_proto.h"
|
||||||
#include "../common/ThreadData.h"
|
#include "../common/ThreadData.h"
|
||||||
#include "../common/UtilSvc.h"
|
#include "../common/UtilSvc.h"
|
||||||
@ -40,6 +43,9 @@
|
|||||||
#include "../common/classes/fb_pair.h"
|
#include "../common/classes/fb_pair.h"
|
||||||
#include "../common/classes/MetaName.h"
|
#include "../common/classes/MetaName.h"
|
||||||
#include "../../jrd/SimilarToMatcher.h"
|
#include "../../jrd/SimilarToMatcher.h"
|
||||||
|
#include "../common/status.h"
|
||||||
|
#include "../common/sha.h"
|
||||||
|
#include "../common/classes/ImplementHelper.h"
|
||||||
|
|
||||||
#ifdef HAVE_UNISTD_H
|
#ifdef HAVE_UNISTD_H
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -49,6 +55,14 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#endif
|
#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)
|
static inline UCHAR* BURP_alloc(ULONG size)
|
||||||
{
|
{
|
||||||
@ -204,10 +218,6 @@ Version 11: FB4.0.
|
|||||||
|
|
||||||
const int ATT_BACKUP_FORMAT = 11;
|
const int ATT_BACKUP_FORMAT = 11;
|
||||||
|
|
||||||
// format version number for ranges for arrays
|
|
||||||
|
|
||||||
//const int GDS_NDA_VERSION = 1; // Not used
|
|
||||||
|
|
||||||
// max array dimension
|
// max array dimension
|
||||||
|
|
||||||
const int MAX_DIMENSION = 16;
|
const int MAX_DIMENSION = 16;
|
||||||
@ -230,6 +240,10 @@ enum att_type {
|
|||||||
att_backup_blksize, // backup block size
|
att_backup_blksize, // backup block size
|
||||||
att_backup_file, // database file name
|
att_backup_file, // database file name
|
||||||
att_backup_volume, // backup volume number
|
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
|
// Database attributes
|
||||||
|
|
||||||
@ -660,12 +674,14 @@ struct burp_fld
|
|||||||
SSHORT fld_type;
|
SSHORT fld_type;
|
||||||
SSHORT fld_sub_type;
|
SSHORT fld_sub_type;
|
||||||
FLD_LENGTH fld_length;
|
FLD_LENGTH fld_length;
|
||||||
|
FLD_LENGTH fld_total_len; // including additional 2 bytes for VARYING CHAR
|
||||||
SSHORT fld_scale;
|
SSHORT fld_scale;
|
||||||
SSHORT fld_position;
|
SSHORT fld_position;
|
||||||
SSHORT fld_parameter;
|
SSHORT fld_parameter;
|
||||||
SSHORT fld_missing_parameter;
|
SSHORT fld_missing_parameter;
|
||||||
SSHORT fld_id;
|
SSHORT fld_id;
|
||||||
RCRD_OFFSET fld_offset;
|
RCRD_OFFSET fld_offset;
|
||||||
|
RCRD_OFFSET fld_missing_offset;
|
||||||
RCRD_OFFSET fld_old_offset;
|
RCRD_OFFSET fld_old_offset;
|
||||||
SSHORT fld_number;
|
SSHORT fld_number;
|
||||||
SSHORT fld_system_flag;
|
SSHORT fld_system_flag;
|
||||||
@ -694,6 +710,8 @@ struct burp_fld
|
|||||||
ISC_QUAD fld_default_source;
|
ISC_QUAD fld_default_source;
|
||||||
SSHORT fld_character_set_id;
|
SSHORT fld_character_set_id;
|
||||||
SSHORT fld_collation_id;
|
SSHORT fld_collation_id;
|
||||||
|
RCRD_OFFSET fld_sql;
|
||||||
|
RCRD_OFFSET fld_null;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum fld_flags_vals {
|
enum fld_flags_vals {
|
||||||
@ -913,6 +931,8 @@ public:
|
|||||||
|
|
||||||
// Global switches and data
|
// Global switches and data
|
||||||
|
|
||||||
|
struct BurpCrypt;
|
||||||
|
|
||||||
class BurpGlobals : public Firebird::ThreadData
|
class BurpGlobals : public Firebird::ThreadData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -928,7 +948,6 @@ public:
|
|||||||
// this is VERY dirty hack to keep current behaviour
|
// this is VERY dirty hack to keep current behaviour
|
||||||
memset (&gbl_database_file_name, 0,
|
memset (&gbl_database_file_name, 0,
|
||||||
&veryEnd - reinterpret_cast<char*>(&gbl_database_file_name));
|
&veryEnd - reinterpret_cast<char*>(&gbl_database_file_name));
|
||||||
memset(status_vector, 0, sizeof(status_vector));
|
|
||||||
|
|
||||||
gbl_stat_flags = 0;
|
gbl_stat_flags = 0;
|
||||||
gbl_stat_header = false;
|
gbl_stat_header = false;
|
||||||
@ -955,6 +974,7 @@ public:
|
|||||||
bool gbl_sw_deactivate_indexes;
|
bool gbl_sw_deactivate_indexes;
|
||||||
bool gbl_sw_kill;
|
bool gbl_sw_kill;
|
||||||
USHORT gbl_sw_blk_factor;
|
USHORT gbl_sw_blk_factor;
|
||||||
|
USHORT gbl_dialect;
|
||||||
const SCHAR* gbl_sw_fix_fss_data;
|
const SCHAR* gbl_sw_fix_fss_data;
|
||||||
USHORT gbl_sw_fix_fss_data_id;
|
USHORT gbl_sw_fix_fss_data_id;
|
||||||
const SCHAR* gbl_sw_fix_fss_metadata;
|
const SCHAR* gbl_sw_fix_fss_metadata;
|
||||||
@ -965,6 +985,12 @@ public:
|
|||||||
bool gbl_sw_mode;
|
bool gbl_sw_mode;
|
||||||
bool gbl_sw_mode_val;
|
bool gbl_sw_mode_val;
|
||||||
bool gbl_sw_overwrite;
|
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_sql_role;
|
||||||
const SCHAR* gbl_sw_user;
|
const SCHAR* gbl_sw_user;
|
||||||
const SCHAR* gbl_sw_password;
|
const SCHAR* gbl_sw_password;
|
||||||
@ -973,12 +999,44 @@ public:
|
|||||||
burp_fil* gbl_sw_files;
|
burp_fil* gbl_sw_files;
|
||||||
burp_fil* gbl_sw_backup_files;
|
burp_fil* gbl_sw_backup_files;
|
||||||
gfld* gbl_global_fields;
|
gfld* gbl_global_fields;
|
||||||
|
unsigned gbl_network_protocol;
|
||||||
burp_act* action;
|
burp_act* action;
|
||||||
|
BurpCrypt* gbl_crypt;
|
||||||
ULONG io_buffer_size;
|
ULONG io_buffer_size;
|
||||||
redirect_vals sw_redirect;
|
redirect_vals sw_redirect;
|
||||||
bool burp_throw;
|
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_rel* relations;
|
||||||
burp_pkg* packages;
|
burp_pkg* packages;
|
||||||
burp_prc* procedures;
|
burp_prc* procedures;
|
||||||
@ -1001,11 +1059,15 @@ public:
|
|||||||
SCHAR mvol_old_file [MAX_FILE_NAME_SIZE];
|
SCHAR mvol_old_file [MAX_FILE_NAME_SIZE];
|
||||||
int mvol_volume_count;
|
int mvol_volume_count;
|
||||||
bool mvol_empty_file;
|
bool mvol_empty_file;
|
||||||
isc_db_handle db_handle;
|
TEXT mvol_keyname_buffer[MAX_FILE_NAME_SIZE];
|
||||||
isc_tr_handle tr_handle;
|
const TEXT* mvol_keyname;
|
||||||
isc_tr_handle global_trans;
|
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;
|
DESC file_desc;
|
||||||
ISC_STATUS_ARRAY status_vector;
|
|
||||||
int exit_code;
|
int exit_code;
|
||||||
UCHAR* head_of_mem_list;
|
UCHAR* head_of_mem_list;
|
||||||
FILE* output_file;
|
FILE* output_file;
|
||||||
@ -1015,59 +1077,61 @@ public:
|
|||||||
// burp_fld* v3_cvt_fld_list;
|
// burp_fld* v3_cvt_fld_list;
|
||||||
|
|
||||||
// The handles_get... are for restore.
|
// The handles_get... are for restore.
|
||||||
isc_req_handle handles_get_character_sets_req_handle1;
|
Firebird::IRequest* handles_get_character_sets_req_handle1;
|
||||||
isc_req_handle handles_get_chk_constraint_req_handle1;
|
Firebird::IRequest* handles_get_chk_constraint_req_handle1;
|
||||||
isc_req_handle handles_get_collation_req_handle1;
|
Firebird::IRequest* handles_get_collation_req_handle1;
|
||||||
isc_req_handle handles_get_exception_req_handle1;
|
Firebird::IRequest* handles_get_exception_req_handle1;
|
||||||
isc_req_handle handles_get_field_dimensions_req_handle1;
|
Firebird::IRequest* handles_get_field_dimensions_req_handle1;
|
||||||
isc_req_handle handles_get_field_req_handle1;
|
Firebird::IRequest* handles_get_field_req_handle1;
|
||||||
isc_req_handle handles_get_fields_req_handle1;
|
Firebird::IRequest* handles_get_fields_req_handle1;
|
||||||
isc_req_handle handles_get_fields_req_handle2;
|
Firebird::IRequest* handles_get_fields_req_handle2;
|
||||||
isc_req_handle handles_get_fields_req_handle3;
|
Firebird::IRequest* handles_get_fields_req_handle3;
|
||||||
isc_req_handle handles_get_fields_req_handle4;
|
Firebird::IRequest* handles_get_fields_req_handle4;
|
||||||
isc_req_handle handles_get_fields_req_handle5;
|
Firebird::IRequest* handles_get_fields_req_handle5;
|
||||||
isc_req_handle handles_get_fields_req_handle6;
|
Firebird::IRequest* handles_get_fields_req_handle6;
|
||||||
isc_req_handle handles_get_files_req_handle1;
|
Firebird::IRequest* handles_get_files_req_handle1;
|
||||||
isc_req_handle handles_get_filter_req_handle1;
|
Firebird::IRequest* handles_get_filter_req_handle1;
|
||||||
isc_req_handle handles_get_function_arg_req_handle1;
|
Firebird::IRequest* handles_get_function_arg_req_handle1;
|
||||||
isc_req_handle handles_get_function_req_handle1;
|
Firebird::IRequest* handles_get_function_req_handle1;
|
||||||
isc_req_handle handles_get_global_field_req_handle1;
|
Firebird::IRequest* handles_get_global_field_req_handle1;
|
||||||
isc_req_handle handles_get_index_req_handle1;
|
Firebird::IRequest* handles_get_index_req_handle1;
|
||||||
isc_req_handle handles_get_index_req_handle2;
|
Firebird::IRequest* handles_get_index_req_handle2;
|
||||||
isc_req_handle handles_get_index_req_handle3;
|
Firebird::IRequest* handles_get_index_req_handle3;
|
||||||
isc_req_handle handles_get_index_req_handle4;
|
Firebird::IRequest* handles_get_index_req_handle4;
|
||||||
isc_req_handle handles_get_package_req_handle1;
|
Firebird::IRequest* handles_get_package_req_handle1;
|
||||||
isc_req_handle handles_get_procedure_prm_req_handle1;
|
Firebird::IRequest* handles_get_procedure_prm_req_handle1;
|
||||||
isc_req_handle handles_get_procedure_req_handle1;
|
Firebird::IRequest* handles_get_procedure_req_handle1;
|
||||||
isc_req_handle handles_get_ranges_req_handle1;
|
Firebird::IRequest* handles_get_ranges_req_handle1;
|
||||||
isc_req_handle handles_get_ref_constraint_req_handle1;
|
Firebird::IRequest* handles_get_ref_constraint_req_handle1;
|
||||||
isc_req_handle handles_get_rel_constraint_req_handle1;
|
Firebird::IRequest* handles_get_rel_constraint_req_handle1;
|
||||||
isc_req_handle handles_get_relation_req_handle1;
|
Firebird::IRequest* handles_get_relation_req_handle1;
|
||||||
isc_req_handle handles_get_security_class_req_handle1;
|
Firebird::IRequest* handles_get_security_class_req_handle1;
|
||||||
isc_req_handle handles_get_sql_roles_req_handle1;
|
Firebird::IRequest* handles_get_sql_roles_req_handle1;
|
||||||
isc_req_handle handles_get_mapping_req_handle1;
|
Firebird::IRequest* handles_get_mapping_req_handle1;
|
||||||
isc_req_handle handles_get_trigger_message_req_handle1;
|
Firebird::IRequest* handles_get_trigger_message_req_handle1;
|
||||||
isc_req_handle handles_get_trigger_message_req_handle2;
|
Firebird::IRequest* handles_get_trigger_message_req_handle2;
|
||||||
isc_req_handle handles_get_trigger_old_req_handle1;
|
Firebird::IRequest* handles_get_trigger_old_req_handle1;
|
||||||
isc_req_handle handles_get_trigger_req_handle1;
|
Firebird::IRequest* handles_get_trigger_req_handle1;
|
||||||
isc_req_handle handles_get_type_req_handle1;
|
Firebird::IRequest* handles_get_type_req_handle1;
|
||||||
isc_req_handle handles_get_user_privilege_req_handle1;
|
Firebird::IRequest* handles_get_user_privilege_req_handle1;
|
||||||
isc_req_handle handles_get_view_req_handle1;
|
Firebird::IRequest* handles_get_view_req_handle1;
|
||||||
|
|
||||||
// The handles_put.. are for backup.
|
// The handles_put.. are for backup.
|
||||||
isc_req_handle handles_put_index_req_handle1;
|
Firebird::IRequest* handles_put_index_req_handle1;
|
||||||
isc_req_handle handles_put_index_req_handle2;
|
Firebird::IRequest* handles_put_index_req_handle2;
|
||||||
isc_req_handle handles_put_index_req_handle3;
|
Firebird::IRequest* handles_put_index_req_handle3;
|
||||||
isc_req_handle handles_put_index_req_handle4;
|
Firebird::IRequest* handles_put_index_req_handle4;
|
||||||
isc_req_handle handles_put_index_req_handle5;
|
Firebird::IRequest* handles_put_index_req_handle5;
|
||||||
isc_req_handle handles_put_index_req_handle6;
|
Firebird::IRequest* handles_put_index_req_handle6;
|
||||||
isc_req_handle handles_put_index_req_handle7;
|
Firebird::IRequest* handles_put_index_req_handle7;
|
||||||
isc_req_handle handles_put_relation_req_handle1;
|
Firebird::IRequest* handles_put_relation_req_handle1;
|
||||||
isc_req_handle handles_put_relation_req_handle2;
|
Firebird::IRequest* handles_put_relation_req_handle2;
|
||||||
isc_req_handle handles_store_blr_gen_id_req_handle1;
|
Firebird::IRequest* handles_store_blr_gen_id_req_handle1;
|
||||||
isc_req_handle handles_write_function_args_req_handle1;
|
Firebird::IRequest* handles_write_function_args_req_handle1;
|
||||||
isc_req_handle handles_write_function_args_req_handle2;
|
Firebird::IRequest* handles_write_function_args_req_handle2;
|
||||||
isc_req_handle handles_write_procedure_prms_req_handle1;
|
Firebird::IRequest* handles_write_procedure_prms_req_handle1;
|
||||||
isc_req_handle handles_fix_security_class_name_req_handle1;
|
Firebird::IRequest* handles_fix_security_class_name_req_handle1;
|
||||||
|
|
||||||
bool hdr_forced_writes;
|
bool hdr_forced_writes;
|
||||||
TEXT database_security_class[GDS_NAME_LEN]; // To save database security class for deferred update
|
TEXT database_security_class[GDS_NAME_LEN]; // To save database security class for deferred update
|
||||||
|
|
||||||
@ -1089,6 +1153,9 @@ public:
|
|||||||
char veryEnd;
|
char veryEnd;
|
||||||
//starting after this members must be initialized in constructor explicitly
|
//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> > >
|
Firebird::Array<Firebird::Pair<Firebird::NonPooled<Firebird::MetaName, Firebird::MetaName> > >
|
||||||
defaultCollations;
|
defaultCollations;
|
||||||
Firebird::UtilSvc* uSvc;
|
Firebird::UtilSvc* uSvc;
|
||||||
@ -1162,4 +1229,49 @@ enum burp_messages_vals {
|
|||||||
// BLOB buffer
|
// BLOB buffer
|
||||||
typedef Firebird::HalfStaticArray<UCHAR, 1024> BlobBuffer;
|
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
|
#endif // BURP_BURP_H
|
||||||
|
@ -26,15 +26,19 @@
|
|||||||
|
|
||||||
#include "../common/ThreadData.h"
|
#include "../common/ThreadData.h"
|
||||||
#include "../common/classes/MsgPrint.h"
|
#include "../common/classes/MsgPrint.h"
|
||||||
|
#include "../common/classes/fb_string.h"
|
||||||
#include "../common/UtilSvc.h"
|
#include "../common/UtilSvc.h"
|
||||||
|
|
||||||
|
class BurpGlobals;
|
||||||
|
|
||||||
int BURP_main(Firebird::UtilSvc*);
|
int BURP_main(Firebird::UtilSvc*);
|
||||||
int gbak(Firebird::UtilSvc*);
|
int gbak(Firebird::UtilSvc*);
|
||||||
|
|
||||||
void BURP_abort();
|
void BURP_abort();
|
||||||
void BURP_error(USHORT, bool, const MsgFormat::SafeArg& arg = MsgFormat::SafeArg());
|
void BURP_error(USHORT, bool, const MsgFormat::SafeArg& arg = MsgFormat::SafeArg());
|
||||||
void BURP_error(USHORT, bool, const char* str);
|
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_partial(bool, USHORT, const MsgFormat::SafeArg& arg = MsgFormat::SafeArg());
|
||||||
void BURP_msg_put(bool, USHORT, const MsgFormat::SafeArg& arg);
|
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.
|
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_output_version(void*, const TEXT*);
|
||||||
void BURP_print(bool err, USHORT, const MsgFormat::SafeArg& arg = MsgFormat::SafeArg());
|
void BURP_print(bool err, USHORT, const MsgFormat::SafeArg& arg = MsgFormat::SafeArg());
|
||||||
void BURP_print(bool err, USHORT, const char* str);
|
void BURP_print(bool err, USHORT, const char* str);
|
||||||
void BURP_print_status(bool err, const ISC_STATUS* status);
|
void BURP_print_status(bool err, Firebird::IStatus* status);
|
||||||
void BURP_print_warning(const ISC_STATUS*);
|
void BURP_print_warning(Firebird::IStatus* status);
|
||||||
void BURP_verbose(USHORT, const MsgFormat::SafeArg& arg = MsgFormat::SafeArg());
|
void BURP_verbose(USHORT, const MsgFormat::SafeArg& arg = MsgFormat::SafeArg());
|
||||||
void BURP_verbose(USHORT, const char* str);
|
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_VERBINT = 46; // verbose but with specific interval
|
||||||
const int IN_SW_BURP_STATS = 47; // print statistics
|
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_RO = "READ_ONLY";
|
||||||
static const char* const BURP_SW_MODE_RW = "READ_WRITE";
|
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
|
// 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},
|
{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
|
// 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},
|
{IN_SW_BURP_E, isc_spb_bkp_expand, "EXPAND", 0, 0, 0, false, true, 97, 1, NULL, boBackup},
|
||||||
// msg 97: @1EXPAND no data compression
|
// msg 97: @1EXPAND no data compression
|
||||||
{IN_SW_BURP_FA, isc_spb_bkp_factor, "FACTOR", 0, 0, 0, false, false, 181, 2, NULL, boBackup},
|
{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
|
// 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},
|
{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
|
// 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
|
// 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
|
// 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},
|
{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
|
// 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},
|
{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
|
// 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},
|
{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:
|
// 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
|
// 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
|
// 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
|
// 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
|
// msg 365: W page writes
|
||||||
{IN_SW_BURP_T, 0, "TRANSPORTABLE", 0, 0, 0, false, false, 175, 1, NULL, boBackup},
|
{IN_SW_BURP_T, 0, "TRANSPORTABLE", 0, 0, 0, false, false, 175, 1, NULL, boBackup},
|
||||||
// msg 175: @1TRANSPORTABLE transportable backup -- data in XDR format
|
// 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)
|
// 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},
|
{IN_SW_BURP_Z, 0, "Z", 0, 0, 0, false, false, 104, 1, NULL, boGeneral},
|
||||||
// msg 104: @1Z print version number
|
// 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
|
// The next two 'virtual' switches are hidden from user and are needed
|
||||||
// for services API
|
// for services API
|
||||||
|
@ -24,8 +24,8 @@
|
|||||||
#ifndef BURP_CANON_PROTO_H
|
#ifndef BURP_CANON_PROTO_H
|
||||||
#define BURP_CANON_PROTO_H
|
#define BURP_CANON_PROTO_H
|
||||||
|
|
||||||
ULONG CAN_encode_decode (burp_rel*, lstring*, UCHAR*, int);
|
ULONG CAN_encode_decode (burp_rel* relation, lstring* buffer, UCHAR* data, bool direction, bool useMissingOffset = false);
|
||||||
ULONG CAN_slice (lstring*, lstring*, int, /*USHORT,*/ UCHAR*);
|
ULONG CAN_slice (lstring* buffer, lstring* slice, bool direction, UCHAR* sdl);
|
||||||
|
|
||||||
#endif // BURP_CANON_PROTO_H
|
#endif // BURP_CANON_PROTO_H
|
||||||
|
|
||||||
|
@ -42,11 +42,11 @@
|
|||||||
#include "../common/xdr_proto.h"
|
#include "../common/xdr_proto.h"
|
||||||
#include "../common/gdsassert.h"
|
#include "../common/gdsassert.h"
|
||||||
#include "../common/StatusHolder.h"
|
#include "../common/StatusHolder.h"
|
||||||
|
#include "../common/status.h"
|
||||||
#include "fb_types.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_getbytes(XDR*, SCHAR *, u_int);
|
||||||
static bool_t burp_putbytes(XDR*, const 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;
|
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)
|
if (field->fld_flags & FLD_computed)
|
||||||
continue;
|
continue;
|
||||||
offset = FB_ALIGN(offset, sizeof(SSHORT));
|
UCHAR* p = data + field->fld_missing_offset;
|
||||||
UCHAR* p = data + offset;
|
if (!useMissingOffset)
|
||||||
|
{
|
||||||
|
offset = FB_ALIGN(offset, sizeof(SSHORT));
|
||||||
|
p = data + offset;
|
||||||
|
offset += sizeof(SSHORT);
|
||||||
|
}
|
||||||
if (!xdr_short(xdrs, (SSHORT*) p))
|
if (!xdr_short(xdrs, (SSHORT*) p))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
offset += sizeof(SSHORT);
|
|
||||||
}
|
}
|
||||||
return (xdrs->x_private - xdrs->x_base);
|
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;
|
sdl_info info;
|
||||||
{
|
{
|
||||||
Firebird::LocalStatus ls;
|
FbLocalStatus s;
|
||||||
Firebird::CheckStatusWrapper s(&ls);
|
|
||||||
if (SDL_info(&s, sdl, &info, 0))
|
if (SDL_info(&s, sdl, &info, 0))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -119,12 +119,12 @@ void MISC_free_burp( void *free)
|
|||||||
// in a function visible to all gbak components.
|
// in a function visible to all gbak components.
|
||||||
// Given a request, if it's non-zero (compiled), deallocate it but
|
// Given a request, if it's non-zero (compiled), deallocate it but
|
||||||
// without caring about a possible error.
|
// 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)
|
if (req_handle)
|
||||||
{
|
{
|
||||||
ISC_STATUS_ARRAY req_status;
|
req_handle->release();
|
||||||
isc_release_request(req_status, &req_handle);
|
req_handle = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
|
|
||||||
UCHAR* MISC_alloc_burp(ULONG);
|
UCHAR* MISC_alloc_burp(ULONG);
|
||||||
void MISC_free_burp(void*);
|
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);
|
int MISC_symbol_length(const TEXT*, ULONG);
|
||||||
void MISC_terminate(const TEXT*, TEXT*, ULONG, 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
|
#ifndef BURP_MVOL_PROTO_H
|
||||||
#define 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_read();
|
||||||
FB_UINT64 MVOL_fini_write(int*, UCHAR**);
|
FB_UINT64 MVOL_fini_write();
|
||||||
void MVOL_init(ULONG);
|
void MVOL_init(ULONG);
|
||||||
void MVOL_init_read(const char*, USHORT*, int*, UCHAR**);
|
void MVOL_init_read(const char*, USHORT*);
|
||||||
void MVOL_init_write(const char*, int*, UCHAR**);
|
void MVOL_init_write(const char*);
|
||||||
bool MVOL_split_hdr_write();
|
bool MVOL_split_hdr_write();
|
||||||
bool MVOL_split_hdr_read();
|
bool MVOL_split_hdr_read();
|
||||||
int MVOL_read(int*, UCHAR**);
|
void MVOL_read(BurpGlobals*);
|
||||||
UCHAR* MVOL_read_block(BurpGlobals*, UCHAR*, ULONG);
|
UCHAR* MVOL_read_block(BurpGlobals*, UCHAR*, ULONG);
|
||||||
void MVOL_skip_block(BurpGlobals*, 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);
|
const UCHAR* MVOL_write_block(BurpGlobals*, const UCHAR*, ULONG);
|
||||||
|
Firebird::ICryptKeyCallback* MVOL_get_crypt(BurpGlobals*);
|
||||||
|
|
||||||
#if defined WIN_NT
|
#if defined WIN_NT
|
||||||
DESC MVOL_open(const char*, ULONG, ULONG);
|
DESC NT_tape_open(const char*, ULONG, ULONG);
|
||||||
#endif
|
#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 "CsConvert.h"
|
||||||
#include "IntlUtil.h"
|
#include "IntlUtil.h"
|
||||||
|
|
||||||
|
namespace Firebird {
|
||||||
|
|
||||||
|
template <>
|
||||||
|
inline void SimpleDelete<charset>::clear(charset* cs)
|
||||||
|
{
|
||||||
|
Firebird::IntlUtil::finiCharset(cs);
|
||||||
|
delete cs;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
namespace Jrd {
|
namespace Jrd {
|
||||||
|
|
||||||
class CharSet
|
class CharSet
|
||||||
{
|
{
|
||||||
public:
|
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);
|
static CharSet* createInstance(Firebird::MemoryPool& pool, USHORT id, charset* cs);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -45,6 +45,9 @@ extern "C"
|
|||||||
|
|
||||||
using namespace Firebird;
|
using namespace Firebird;
|
||||||
|
|
||||||
|
const DecimalStatus DecimalStatus::DEFAULT(FB_DEC_Errors);
|
||||||
|
const DecimalBinding DecimalBinding::DEFAULT;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
struct Dec2fb
|
struct Dec2fb
|
||||||
@ -359,7 +362,9 @@ Decimal64 Decimal64::floor(DecimalStatus decSt) const
|
|||||||
|
|
||||||
int Decimal64::compare(DecimalStatus decSt, Decimal64 tgt) 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;
|
decDouble r;
|
||||||
decDoubleCompare(&r, &dec, &tgt.dec, &context);
|
decDoubleCompare(&r, &dec, &tgt.dec, &context);
|
||||||
return decDoubleToInt32(&r, &context, DEC_ROUND_HALF_UP);
|
return decDoubleToInt32(&r, &context, DEC_ROUND_HALF_UP);
|
||||||
|
@ -55,6 +55,8 @@ struct DecimalStatus
|
|||||||
: decExtFlag(exc), roundingMode(DEC_ROUND_HALF_UP)
|
: decExtFlag(exc), roundingMode(DEC_ROUND_HALF_UP)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
static const DecimalStatus DEFAULT;
|
||||||
|
|
||||||
USHORT decExtFlag, roundingMode;
|
USHORT decExtFlag, roundingMode;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -64,12 +66,15 @@ struct DecimalBinding
|
|||||||
: bind(DEC_NATIVE), numScale(0)
|
: bind(DEC_NATIVE), numScale(0)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
static const DecimalBinding DEFAULT;
|
||||||
|
|
||||||
enum Bind { DEC_NATIVE, DEC_TEXT, DEC_DOUBLE, DEC_NUMERIC };
|
enum Bind { DEC_NATIVE, DEC_TEXT, DEC_DOUBLE, DEC_NUMERIC };
|
||||||
|
|
||||||
Bind bind;
|
Bind bind;
|
||||||
SCHAR numScale;
|
SCHAR numScale;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class DecimalFixed;
|
class DecimalFixed;
|
||||||
|
|
||||||
class Decimal64
|
class Decimal64
|
||||||
@ -132,6 +137,8 @@ public:
|
|||||||
UCHAR* getBytes();
|
UCHAR* getBytes();
|
||||||
int compare(DecimalStatus decSt, Decimal128Base tgt) const;
|
int compare(DecimalStatus decSt, Decimal128Base tgt) const;
|
||||||
|
|
||||||
|
void setScale(DecimalStatus decSt, int scale);
|
||||||
|
|
||||||
bool isInf() const;
|
bool isInf() const;
|
||||||
bool isNan() const;
|
bool isNan() const;
|
||||||
int sign() const;
|
int sign() const;
|
||||||
@ -146,8 +153,6 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setScale(DecimalStatus decSt, int scale);
|
|
||||||
|
|
||||||
decQuad dec;
|
decQuad dec;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -98,7 +98,7 @@ THREAD_ENTRY_DECLARE threadStart(THREAD_ENTRY_PARAM arg)
|
|||||||
|
|
||||||
#ifdef USE_POSIX_THREADS
|
#ifdef USE_POSIX_THREADS
|
||||||
#define START_THREAD
|
#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
|
#endif
|
||||||
*p_handle = thread;
|
*p_handle = thread;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Thread::waitForCompletion(Handle& thread)
|
void Thread::waitForCompletion(Handle& thread)
|
||||||
@ -208,6 +210,11 @@ ThreadId Thread::getId()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Thread::isCurrent(const ThreadId threadId)
|
||||||
|
{
|
||||||
|
return getId() == threadId;
|
||||||
|
}
|
||||||
|
|
||||||
void Thread::sleep(unsigned milliseconds)
|
void Thread::sleep(unsigned milliseconds)
|
||||||
{
|
{
|
||||||
#if defined(HAVE_NANOSLEEP)
|
#if defined(HAVE_NANOSLEEP)
|
||||||
@ -252,7 +259,7 @@ void Thread::yield()
|
|||||||
|
|
||||||
#ifdef WIN_NT
|
#ifdef WIN_NT
|
||||||
#define START_THREAD
|
#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);
|
CloseHandle(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return thread_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Thread::waitForCompletion(Handle& handle)
|
void Thread::waitForCompletion(Handle& handle)
|
||||||
@ -342,6 +351,11 @@ ThreadId Thread::getId()
|
|||||||
return GetCurrentThreadId();
|
return GetCurrentThreadId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Thread::isCurrent(const ThreadId threadId)
|
||||||
|
{
|
||||||
|
return GetCurrentThreadId() == threadId;
|
||||||
|
}
|
||||||
|
|
||||||
void Thread::sleep(unsigned milliseconds)
|
void Thread::sleep(unsigned milliseconds)
|
||||||
{
|
{
|
||||||
SleepEx(milliseconds, FALSE);
|
SleepEx(milliseconds, FALSE);
|
||||||
@ -356,7 +370,7 @@ void Thread::yield()
|
|||||||
|
|
||||||
|
|
||||||
#ifndef START_THREAD
|
#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.
|
* Wrong attempt to start a new thread.
|
||||||
*
|
*
|
||||||
**************************************/
|
**************************************/
|
||||||
|
fb_assert(false);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Thread::waitForCompletion(Handle&)
|
void Thread::waitForCompletion(Handle&)
|
||||||
|
@ -75,9 +75,10 @@ public:
|
|||||||
typedef pthread_t Handle;
|
typedef pthread_t Handle;
|
||||||
#endif
|
#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 waitForCompletion(Handle& handle);
|
||||||
static void kill(Handle& handle);
|
static void kill(Handle& handle);
|
||||||
|
static bool isCurrent(const ThreadId threadId);
|
||||||
|
|
||||||
static ThreadId getId();
|
static ThreadId getId();
|
||||||
|
|
||||||
|
@ -145,6 +145,7 @@ public:
|
|||||||
virtual bool finished() { return false; }
|
virtual bool finished() { return false; }
|
||||||
virtual void initStatus() { }
|
virtual void initStatus() { }
|
||||||
virtual bool utf8FileNames() { return false; }
|
virtual bool utf8FileNames() { return false; }
|
||||||
|
virtual Firebird::ICryptKeyCallback* getCryptCallback() { return NULL; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -30,6 +30,8 @@
|
|||||||
#ifndef FB_UTILFACE
|
#ifndef FB_UTILFACE
|
||||||
#define FB_UTILFACE
|
#define FB_UTILFACE
|
||||||
|
|
||||||
|
#include "firebird/Interface.h"
|
||||||
|
|
||||||
#include "../common/classes/alloc.h"
|
#include "../common/classes/alloc.h"
|
||||||
#include "../common/classes/array.h"
|
#include "../common/classes/array.h"
|
||||||
#include "../common/classes/fb_string.h"
|
#include "../common/classes/fb_string.h"
|
||||||
@ -74,6 +76,7 @@ public:
|
|||||||
virtual bool finished() = 0;
|
virtual bool finished() = 0;
|
||||||
virtual unsigned int getAuthBlock(const unsigned char** bytes) = 0;
|
virtual unsigned int getAuthBlock(const unsigned char** bytes) = 0;
|
||||||
virtual bool utf8FileNames() = 0;
|
virtual bool utf8FileNames() = 0;
|
||||||
|
virtual Firebird::ICryptKeyCallback* getCryptCallback() = 0;
|
||||||
|
|
||||||
void setDataMode(bool value)
|
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_res_fix_fss_metadata:
|
||||||
case isc_spb_bkp_stat:
|
case isc_spb_bkp_stat:
|
||||||
case isc_spb_bkp_skip_data:
|
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;
|
return StringSpb;
|
||||||
case isc_spb_bkp_factor:
|
case isc_spb_bkp_factor:
|
||||||
case isc_spb_bkp_length:
|
case isc_spb_bkp_length:
|
||||||
|
@ -49,6 +49,7 @@ static const UCHAR CpuAlpha = 14;
|
|||||||
static const UCHAR CpuArm64 = 15;
|
static const UCHAR CpuArm64 = 15;
|
||||||
static const UCHAR CpuPowerPc64el = 16;
|
static const UCHAR CpuPowerPc64el = 16;
|
||||||
static const UCHAR CpuM68k = 17;
|
static const UCHAR CpuM68k = 17;
|
||||||
|
static const UCHAR CpuRiscV64 = 18;
|
||||||
|
|
||||||
static const UCHAR OsWindows = 0;
|
static const UCHAR OsWindows = 0;
|
||||||
static const UCHAR OsLinux = 1;
|
static const UCHAR OsLinux = 1;
|
||||||
@ -89,7 +90,8 @@ const char* hardware[] = {
|
|||||||
"Alpha",
|
"Alpha",
|
||||||
"ARM64",
|
"ARM64",
|
||||||
"PowerPC64el",
|
"PowerPC64el",
|
||||||
"M68k"
|
"M68k",
|
||||||
|
"RiscV64"
|
||||||
};
|
};
|
||||||
|
|
||||||
const char* operatingSystem[] = {
|
const char* operatingSystem[] = {
|
||||||
@ -116,22 +118,23 @@ const char* compiler[] = {
|
|||||||
// This table lists pre-fb3 implementation codes
|
// This table lists pre-fb3 implementation codes
|
||||||
const UCHAR backwardTable[FB_NELEM(hardware) * FB_NELEM(operatingSystem)] =
|
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
|
// 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,
|
/* 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,
|
/* 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,
|
/* 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,
|
/* 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,
|
/* 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,
|
/* 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,
|
/* 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,
|
/* 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
|
/* 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)] =
|
const UCHAR backEndianess[FB_NELEM(hardware)] =
|
||||||
{
|
{
|
||||||
// Intel AMD Sparc PPC PPC64 MIPSEL MIPS ARM IA64 s390 s390x SH SHEB HPPA Alpha ARM64 PowerPC64el M68k
|
// 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, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
@ -41,7 +41,6 @@ public:
|
|||||||
DbImplementation (UCHAR p_cpu, UCHAR p_os, UCHAR p_cc, UCHAR p_flags)
|
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)
|
: di_cpu(p_cpu), di_os(p_os), di_cc(p_cc), di_flags(p_flags)
|
||||||
{ }
|
{ }
|
||||||
DbImplementation (UCHAR p_compatImpl);
|
|
||||||
~DbImplementation() { }
|
~DbImplementation() { }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -222,14 +222,6 @@ inline bool isinf(double x)
|
|||||||
{
|
{
|
||||||
return (!_finite (x) && !isnan(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
|
#endif // WIN_NT
|
||||||
|
|
||||||
namespace Firebird {
|
namespace Firebird {
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#define FB_COMMON_CLASSES_GET_PLUGINS
|
#define FB_COMMON_CLASSES_GET_PLUGINS
|
||||||
|
|
||||||
#include "../common/classes/ImplementHelper.h"
|
#include "../common/classes/ImplementHelper.h"
|
||||||
|
#include "../common/classes/auto.h"
|
||||||
#include "../common/config/config.h"
|
#include "../common/config/config.h"
|
||||||
#include "../common/StatusHolder.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
|
} // namespace Firebird
|
||||||
|
|
||||||
|
|
||||||
|
@ -313,7 +313,7 @@ public:
|
|||||||
typedef void VoidNoParam();
|
typedef void VoidNoParam();
|
||||||
|
|
||||||
explicit UnloadDetectorHelper(MemoryPool&)
|
explicit UnloadDetectorHelper(MemoryPool&)
|
||||||
: cleanup(NULL), flagOsUnload(false)
|
: cleanup(NULL), thdDetach(NULL), flagOsUnload(false)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
void registerMe()
|
void registerMe()
|
||||||
@ -348,6 +348,11 @@ public:
|
|||||||
cleanup = function;
|
cleanup = function;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setThreadDetach(VoidNoParam* function)
|
||||||
|
{
|
||||||
|
thdDetach = function;
|
||||||
|
}
|
||||||
|
|
||||||
void doClean()
|
void doClean()
|
||||||
{
|
{
|
||||||
flagOsUnload = false;
|
flagOsUnload = false;
|
||||||
@ -359,8 +364,15 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void threadDetach()
|
||||||
|
{
|
||||||
|
if (thdDetach)
|
||||||
|
thdDetach();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VoidNoParam* cleanup;
|
VoidNoParam* cleanup;
|
||||||
|
VoidNoParam* thdDetach;
|
||||||
bool flagOsUnload;
|
bool flagOsUnload;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -130,6 +130,13 @@ namespace Firebird
|
|||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void moveFrom(RefPtr& r)
|
||||||
|
{
|
||||||
|
assign(NULL);
|
||||||
|
ptr = r.ptr;
|
||||||
|
r.ptr = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
T* operator=(T* p)
|
T* operator=(T* p)
|
||||||
{
|
{
|
||||||
return assign(p);
|
return assign(p);
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
|
|
||||||
#include "firebird.h"
|
#include "firebird.h"
|
||||||
#include "fb_tls.h"
|
#include "fb_tls.h"
|
||||||
|
#include "init.h"
|
||||||
#include "../ThreadStart.h"
|
#include "../ThreadStart.h"
|
||||||
#include "SyncObject.h"
|
#include "SyncObject.h"
|
||||||
#include "Synchronize.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
|
/// ThreadSync
|
||||||
|
|
||||||
TLS_DECLARE(ThreadSync*, threadIndex);
|
TLS_DECLARE(ThreadSync*, threadIndex);
|
||||||
@ -210,7 +242,7 @@ ThreadSync* ThreadSync::getThread(const char* desc)
|
|||||||
|
|
||||||
if (!thread)
|
if (!thread)
|
||||||
{
|
{
|
||||||
thread = FB_NEW ThreadSync(desc);
|
thread = FB_NEW ThreadSyncInstance(desc);
|
||||||
|
|
||||||
fb_assert(thread == findThread());
|
fb_assert(thread == findThread());
|
||||||
}
|
}
|
||||||
@ -220,6 +252,12 @@ ThreadSync* ThreadSync::getThread(const char* desc)
|
|||||||
|
|
||||||
void ThreadSync::setThread(ThreadSync* thread)
|
void ThreadSync::setThread(ThreadSync* thread)
|
||||||
{
|
{
|
||||||
|
if (thread != NULL)
|
||||||
|
{
|
||||||
|
ThreadSync* other = findThread();
|
||||||
|
fb_assert(other == NULL);
|
||||||
|
}
|
||||||
|
|
||||||
TLS_SET(threadIndex, thread);
|
TLS_SET(threadIndex, thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,12 +224,6 @@ public:
|
|||||||
// previously set group and added to new
|
// previously set group and added to new
|
||||||
void setStatsGroup(MemoryStats& stats) FB_NOTHROW;
|
void setStatsGroup(MemoryStats& stats) FB_NOTHROW;
|
||||||
|
|
||||||
// Just a helper for AutoPtr.
|
|
||||||
static void clear(MemoryPool* pool)
|
|
||||||
{
|
|
||||||
deletePool(pool);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize and finalize global memory pool
|
// Initialize and finalize global memory pool
|
||||||
static void init();
|
static void init();
|
||||||
static void cleanup();
|
static void cleanup();
|
||||||
@ -451,7 +445,14 @@ namespace Firebird
|
|||||||
explicit AutoStorage(MemoryPool& p) : PermanentStorage(p) { }
|
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
|
} // namespace Firebird
|
||||||
|
|
||||||
|
@ -46,6 +46,15 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
inline void SimpleDelete<FILE>::clear(FILE* f)
|
||||||
|
{
|
||||||
|
if (f) {
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template <typename What>
|
template <typename What>
|
||||||
class ArrayDelete
|
class ArrayDelete
|
||||||
{
|
{
|
||||||
@ -56,6 +65,7 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class SimpleRelease
|
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
|
class AutoPtr
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
Where* ptr;
|
Where* ptr;
|
||||||
public:
|
public:
|
||||||
AutoPtr<Where, Clear>(Where* v = NULL)
|
AutoPtr(Where* v = NULL)
|
||||||
: ptr(v)
|
: ptr(v)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
~AutoPtr()
|
~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;
|
ptr = v;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@ -157,14 +167,24 @@ public:
|
|||||||
{
|
{
|
||||||
if (v != ptr)
|
if (v != ptr)
|
||||||
{
|
{
|
||||||
Clear::clear(ptr);
|
Clear<Where>::clear(ptr);
|
||||||
ptr = v;
|
ptr = v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AutoPtr<Where, Clear>(AutoPtr<Where, Clear>&);
|
AutoPtr(AutoPtr&);
|
||||||
void operator=(AutoPtr<Where, Clear>&);
|
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
|
} //namespace Firebird
|
||||||
|
|
||||||
#endif // CLASSES_AUTO_PTR_H
|
#endif // CLASSES_AUTO_PTR_H
|
||||||
|
@ -93,7 +93,7 @@ namespace
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
#ifdef DEBUG_GDS_ALLOC
|
#ifdef DEBUG_GDS_ALLOC
|
||||||
Firebird::AutoPtr<FILE, Firebird::FileClose> file;
|
Firebird::AutoPtr<FILE> file;
|
||||||
|
|
||||||
{ // scope
|
{ // scope
|
||||||
Firebird::PathName name = "memdebug.log";
|
Firebird::PathName name = "memdebug.log";
|
||||||
@ -227,12 +227,37 @@ namespace Firebird
|
|||||||
{
|
{
|
||||||
MutexLockGuard guard(*StaticMutex::mutex, "InstanceControl::InstanceList::InstanceList");
|
MutexLockGuard guard(*StaticMutex::mutex, "InstanceControl::InstanceList::InstanceList");
|
||||||
next = instanceList;
|
next = instanceList;
|
||||||
|
prev = nullptr;
|
||||||
|
if (instanceList)
|
||||||
|
instanceList->prev = this;
|
||||||
instanceList = this;
|
instanceList = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
InstanceControl::InstanceList::~InstanceList()
|
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()
|
void InstanceControl::destructors()
|
||||||
@ -299,8 +324,13 @@ namespace Firebird
|
|||||||
}
|
}
|
||||||
} while (nextPriority != currentPriority);
|
} while (nextPriority != currentPriority);
|
||||||
|
|
||||||
delete instanceList;
|
|
||||||
instanceList = 0;
|
while (instanceList)
|
||||||
|
{
|
||||||
|
InstanceList* item = instanceList;
|
||||||
|
item->unlist();
|
||||||
|
delete item;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void InstanceControl::registerGdsCleanup(FPTR_VOID cleanup)
|
void InstanceControl::registerGdsCleanup(FPTR_VOID cleanup)
|
||||||
|
@ -71,10 +71,16 @@ public:
|
|||||||
virtual ~InstanceList();
|
virtual ~InstanceList();
|
||||||
static void destructors();
|
static void destructors();
|
||||||
|
|
||||||
|
// remove self from common list under StaticMutex protection
|
||||||
|
void remove();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
InstanceList* next;
|
|
||||||
DtorPriority priority;
|
|
||||||
virtual void dtor() = 0;
|
virtual void dtor() = 0;
|
||||||
|
void unlist();
|
||||||
|
|
||||||
|
InstanceList* next;
|
||||||
|
InstanceList* prev;
|
||||||
|
DtorPriority priority;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, InstanceControl::DtorPriority P = InstanceControl::PRIORITY_REGULAR>
|
template <typename T, InstanceControl::DtorPriority P = InstanceControl::PRIORITY_REGULAR>
|
||||||
@ -90,6 +96,11 @@ public:
|
|||||||
fb_assert(link);
|
fb_assert(link);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void remove()
|
||||||
|
{
|
||||||
|
InstanceList::remove();
|
||||||
|
}
|
||||||
|
|
||||||
void dtor()
|
void dtor()
|
||||||
{
|
{
|
||||||
fb_assert(link);
|
fb_assert(link);
|
||||||
|
@ -296,7 +296,7 @@ public:
|
|||||||
const bool at_begin = (m_begin == m_curr);
|
const bool at_begin = (m_begin == m_curr);
|
||||||
m_curr++;
|
m_curr++;
|
||||||
|
|
||||||
while (Marker::isMarked(m_curr) && m_curr < m_end)
|
while (m_curr < m_end && Marker::isMarked(m_curr))
|
||||||
m_curr++;
|
m_curr++;
|
||||||
|
|
||||||
if (m_curr == m_end)
|
if (m_curr == m_end)
|
||||||
|
@ -139,6 +139,10 @@
|
|||||||
#define FB_CPU CpuArm64
|
#define FB_CPU CpuArm64
|
||||||
#endif /* ARM64 */
|
#endif /* ARM64 */
|
||||||
|
|
||||||
|
#ifdef RISCV64
|
||||||
|
#define FB_CPU CpuRiscV64
|
||||||
|
#endif /* RISCV64 */
|
||||||
|
|
||||||
#ifdef sparc
|
#ifdef sparc
|
||||||
#define FB_CPU CpuUltraSparc
|
#define FB_CPU CpuUltraSparc
|
||||||
#define RISC_ALIGNMENT
|
#define RISC_ALIGNMENT
|
||||||
|
@ -203,6 +203,15 @@ const Config::ConfigEntry Config::entries[MAX_CONFIG_KEY] =
|
|||||||
{TYPE_INTEGER, "StatementTimeout", (ConfigValue) 0},
|
{TYPE_INTEGER, "StatementTimeout", (ConfigValue) 0},
|
||||||
{TYPE_INTEGER, "ConnectionIdleTimeout", (ConfigValue) 0},
|
{TYPE_INTEGER, "ConnectionIdleTimeout", (ConfigValue) 0},
|
||||||
{TYPE_INTEGER, "ClientBatchBuffer", (ConfigValue) (128 * 1024)},
|
{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, "ExtConnPoolSize", (ConfigValue) 0},
|
||||||
{TYPE_INTEGER, "ExtConnPoolLifeTime", (ConfigValue) 7200}
|
{TYPE_INTEGER, "ExtConnPoolLifeTime", (ConfigValue) 7200}
|
||||||
};
|
};
|
||||||
@ -841,6 +850,12 @@ unsigned int Config::getClientBatchBuffer() const
|
|||||||
return get<unsigned int>(KEY_CLIENT_BATCH_BUFFER);
|
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()
|
int Config::getExtConnPoolSize()
|
||||||
{
|
{
|
||||||
return getDefaultConfig()->get<int>(KEY_EXT_CONN_POOL_SIZE);
|
return getDefaultConfig()->get<int>(KEY_EXT_CONN_POOL_SIZE);
|
||||||
|
@ -146,6 +146,7 @@ public:
|
|||||||
KEY_STMT_TIMEOUT,
|
KEY_STMT_TIMEOUT,
|
||||||
KEY_CONN_IDLE_TIMEOUT,
|
KEY_CONN_IDLE_TIMEOUT,
|
||||||
KEY_CLIENT_BATCH_BUFFER,
|
KEY_CLIENT_BATCH_BUFFER,
|
||||||
|
KEY_OUTPUT_REDIRECTION_FILE,
|
||||||
KEY_EXT_CONN_POOL_SIZE,
|
KEY_EXT_CONN_POOL_SIZE,
|
||||||
KEY_EXT_CONN_POOL_LIFETIME,
|
KEY_EXT_CONN_POOL_LIFETIME,
|
||||||
MAX_CONFIG_KEY // keep it last
|
MAX_CONFIG_KEY // keep it last
|
||||||
@ -365,6 +366,8 @@ public:
|
|||||||
|
|
||||||
unsigned int getClientBatchBuffer() const;
|
unsigned int getClientBatchBuffer() const;
|
||||||
|
|
||||||
|
static const char* getOutputRedirectionFile();
|
||||||
|
|
||||||
static int getExtConnPoolSize();
|
static int getExtConnPoolSize();
|
||||||
|
|
||||||
static int getExtConnPoolLifeTime();
|
static int getExtConnPoolLifeTime();
|
||||||
|
@ -109,7 +109,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AutoPtr<FILE, FileClose> file;
|
AutoPtr<FILE> file;
|
||||||
Firebird::PathName fileName;
|
Firebird::PathName fileName;
|
||||||
unsigned int l;
|
unsigned int l;
|
||||||
};
|
};
|
||||||
|
@ -1466,6 +1466,8 @@ void dsc::getSqlInfo(SLONG* sqlLength, SLONG* sqlSubType, SLONG* sqlScale, SLONG
|
|||||||
case dtype_dec_fixed:
|
case dtype_dec_fixed:
|
||||||
*sqlType = SQL_DEC_FIXED;
|
*sqlType = SQL_DEC_FIXED;
|
||||||
*sqlScale = dsc_scale;
|
*sqlScale = dsc_scale;
|
||||||
|
if (dsc_sub_type)
|
||||||
|
*sqlSubType = dsc_sub_type;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -173,7 +173,7 @@ typedef struct dsc
|
|||||||
|
|
||||||
bool isDecOrInt() const
|
bool isDecOrInt() const
|
||||||
{
|
{
|
||||||
return isDecFloat() || isExact();
|
return isDecFloat() || isDecFixed() || isExact();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isApprox() const
|
bool isApprox() const
|
||||||
|
@ -2207,12 +2207,14 @@ SharedMemoryBase::SharedMemoryBase(const TEXT* filename, ULONG length, IpcObject
|
|||||||
|
|
||||||
if (file_handle == INVALID_HANDLE_VALUE)
|
if (file_handle == INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
if ((err == ERROR_SHARING_VIOLATION))
|
if ((err == ERROR_SHARING_VIOLATION) || (err == ERROR_ACCESS_DENIED))
|
||||||
{
|
{
|
||||||
if (!init_flag) {
|
if (!init_flag) {
|
||||||
CloseHandle(event_handle);
|
CloseHandle(event_handle);
|
||||||
}
|
}
|
||||||
goto retry;
|
|
||||||
|
if (retry_count < 200) // 2 sec
|
||||||
|
goto retry;
|
||||||
}
|
}
|
||||||
|
|
||||||
CloseHandle(event_handle);
|
CloseHandle(event_handle);
|
||||||
|
@ -101,7 +101,7 @@ public:
|
|||||||
"msvcr110.dll",
|
"msvcr110.dll",
|
||||||
#elif _MSC_VER == 1800
|
#elif _MSC_VER == 1800
|
||||||
"msvcr120.dll",
|
"msvcr120.dll",
|
||||||
#elif _MSC_VER >= 1900 && _MSC_VER <= 1912
|
#elif _MSC_VER >= 1900 && _MSC_VER < 1920
|
||||||
"vcruntime140.dll",
|
"vcruntime140.dll",
|
||||||
#else
|
#else
|
||||||
#error Specify CRT DLL name here !
|
#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>
|
# include <unicode/utf_old.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// The next major ICU version after 4.8 is 49.
|
|
||||||
#define ICU_NEW_VERSION_MEANING 49
|
|
||||||
|
|
||||||
|
|
||||||
using namespace Firebird;
|
using namespace Firebird;
|
||||||
|
|
||||||
@ -121,7 +118,7 @@ public:
|
|||||||
|
|
||||||
namespace Jrd {
|
namespace Jrd {
|
||||||
|
|
||||||
static void formatFilename(PathName& filename, const char* templateName,
|
static ModuleLoader::Module* formatAndLoad(const char* templateName,
|
||||||
int majorVersion, int minorVersion);
|
int majorVersion, int minorVersion);
|
||||||
|
|
||||||
|
|
||||||
@ -229,10 +226,7 @@ private:
|
|||||||
ImplementConversionICU(int aMajorVersion, int aMinorVersion)
|
ImplementConversionICU(int aMajorVersion, int aMinorVersion)
|
||||||
: BaseICU(aMajorVersion, aMinorVersion)
|
: BaseICU(aMajorVersion, aMinorVersion)
|
||||||
{
|
{
|
||||||
PathName filename;
|
module = formatAndLoad(ucTemplate, aMajorVersion, aMinorVersion);
|
||||||
formatFilename(filename, ucTemplate, aMajorVersion, aMinorVersion);
|
|
||||||
|
|
||||||
module = ModuleLoader::fixAndLoadModule(filename);
|
|
||||||
if (!module)
|
if (!module)
|
||||||
return;
|
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 GlobalPtr<UnicodeUtil::ICUModules> icuModules;
|
||||||
|
|
||||||
|
|
||||||
static void formatFilename(PathName& filename, const char* templateName,
|
static ModuleLoader::Module* formatAndLoad(const char* templateName,
|
||||||
int majorVersion, int minorVersion)
|
int majorVersion, int minorVersion)
|
||||||
{
|
{
|
||||||
string s;
|
// ICU has several schemas for placing version into file name
|
||||||
if (majorVersion >= ICU_NEW_VERSION_MEANING)
|
const char* patterns[] =
|
||||||
s.printf("%d", majorVersion);
|
{
|
||||||
else
|
"%d", "%d_%d", "%d%d", NULL
|
||||||
s.printf("%d%d", majorVersion, minorVersion);
|
};
|
||||||
|
|
||||||
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;
|
continue;
|
||||||
|
|
||||||
string configVersion;
|
string configVersion;
|
||||||
|
configVersion.printf("%d.%d", majorVersion, minorVersion);
|
||||||
if (majorVersion >= ICU_NEW_VERSION_MEANING)
|
if (version != configVersion)
|
||||||
{
|
{
|
||||||
minorVersion = 0;
|
minorVersion = 0;
|
||||||
configVersion.printf("%d", majorVersion);
|
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");
|
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))
|
if (icuModules->modules.get(version, icu))
|
||||||
return icu;
|
return icu;
|
||||||
|
|
||||||
PathName filename;
|
|
||||||
formatFilename(filename, ucTemplate, majorVersion, minorVersion);
|
|
||||||
|
|
||||||
icu = FB_NEW_POOL(*getDefaultMemoryPool()) ICU(majorVersion, minorVersion);
|
icu = FB_NEW_POOL(*getDefaultMemoryPool()) ICU(majorVersion, minorVersion);
|
||||||
|
|
||||||
icu->ucModule = ModuleLoader::fixAndLoadModule(filename);
|
icu->ucModule = formatAndLoad(ucTemplate, majorVersion, minorVersion);
|
||||||
|
|
||||||
if (!icu->ucModule)
|
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;
|
delete icu;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
formatFilename(filename, inTemplate, majorVersion, minorVersion);
|
icu->inModule = formatAndLoad(inTemplate, majorVersion, minorVersion);
|
||||||
|
|
||||||
icu->inModule = ModuleLoader::fixAndLoadModule(filename);
|
|
||||||
|
|
||||||
if (!icu->inModule)
|
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;
|
delete icu;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1137,26 +1132,25 @@ UnicodeUtil::ConversionICU& UnicodeUtil::getConversionICU()
|
|||||||
LocalStatus ls;
|
LocalStatus ls;
|
||||||
CheckStatusWrapper lastError(&ls);
|
CheckStatusWrapper lastError(&ls);
|
||||||
string version;
|
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
|
for (int minor = 20; minor--; ) // from 19 down to 0
|
||||||
{
|
{
|
||||||
if ((*major == favMaj) && (minor == favMin))
|
if ((major == favMaj) && (minor == favMin))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if ((convIcu = ImplementConversionICU::create(*major, minor)))
|
if ((convIcu = ImplementConversionICU::create(major, minor)))
|
||||||
return *convIcu;
|
return *convIcu;
|
||||||
}
|
}
|
||||||
catch (const Exception& ex)
|
catch (const Exception& ex)
|
||||||
{
|
{
|
||||||
ex.stuffException(&lastError);
|
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;
|
string rc;
|
||||||
UnicodeUtil::ConversionICU& icu(UnicodeUtil::getConversionICU());
|
UnicodeUtil::ConversionICU& icu(UnicodeUtil::getConversionICU());
|
||||||
|
|
||||||
if (icu.vMajor >= ICU_NEW_VERSION_MEANING)
|
if (icu.vMajor >= 10 && icu.vMinor == 0)
|
||||||
rc.printf("%d", icu.vMajor);
|
rc.printf("%d", icu.vMajor);
|
||||||
else
|
else
|
||||||
rc.printf("%d.%d", icu.vMajor, icu.vMinor);
|
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,
|
static int getGrantorOption(thread_db* tdbb, jrd_tra* transaction, const MetaName& grantor,
|
||||||
int grantorType, const MetaName& roleName);
|
int grantorType, const MetaName& roleName);
|
||||||
static MetaName getIndexRelationName(thread_db* tdbb, jrd_tra* transaction,
|
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 const char* getRelationScopeName(const rel_t type);
|
||||||
static void makeRelationScopeName(string& to, const MetaName& name, 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);
|
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.
|
// Get relation name of an index.
|
||||||
static MetaName getIndexRelationName(thread_db* tdbb, jrd_tra* transaction,
|
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);
|
AutoCacheRequest request(tdbb, drq_l_index_relname, DYN_REQUESTS);
|
||||||
|
|
||||||
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE transaction)
|
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE transaction)
|
||||||
IDX IN RDB$INDICES
|
IDX IN RDB$INDICES
|
||||||
WITH IDX.RDB$INDEX_NAME EQ indexName.c_str()
|
WITH IDX.RDB$INDEX_NAME EQ indexName.c_str()
|
||||||
{
|
{
|
||||||
|
systemIndex = IDX.RDB$SYSTEM_FLAG == 1;
|
||||||
return IDX.RDB$RELATION_NAME;
|
return IDX.RDB$RELATION_NAME;
|
||||||
}
|
}
|
||||||
END_FOR
|
END_FOR
|
||||||
@ -849,6 +852,12 @@ static void updateRdbFields(const TypeClause* type,
|
|||||||
fieldSubTypeNull = FALSE;
|
fieldSubTypeNull = FALSE;
|
||||||
fieldSubType = type->subType;
|
fieldSubType = type->subType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (DTYPE_IS_DECFLOAT(type->dtype))
|
||||||
|
{
|
||||||
|
fieldPrecisionNull = FALSE;
|
||||||
|
fieldPrecision = type->precision;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type->dtype == dtype_varying)
|
if (type->dtype == dtype_varying)
|
||||||
@ -1361,9 +1370,10 @@ bool CommentOnNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case obj_index:
|
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());
|
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;
|
break;
|
||||||
|
|
||||||
case obj_sql_role:
|
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.NULL = FALSE;
|
||||||
FUN.RDB$DETERMINISTIC_FLAG = deterministic ? TRUE : FALSE;
|
FUN.RDB$DETERMINISTIC_FLAG = deterministic ? TRUE : FALSE;
|
||||||
|
FUN.RDB$RETURN_ARGUMENT = 0;
|
||||||
|
|
||||||
if (ssDefiner.specified)
|
if (ssDefiner.specified)
|
||||||
{
|
{
|
||||||
@ -3566,6 +3577,26 @@ DdlNode* CreateAlterTriggerNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
|
|||||||
|
|
||||||
bool CreateAlterTriggerNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
|
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())
|
if (relationName.hasData())
|
||||||
{
|
{
|
||||||
dsc dscName;
|
dsc dscName;
|
||||||
@ -3590,26 +3621,6 @@ void CreateAlterTriggerNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlS
|
|||||||
// run all statements under savepoint control
|
// run all statements under savepoint control
|
||||||
AutoSavePoint savePoint(tdbb, transaction);
|
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);
|
compile(tdbb, dsqlScratch);
|
||||||
|
|
||||||
blrData = dsqlScratch->getBlrData();
|
blrData = dsqlScratch->getBlrData();
|
||||||
@ -9674,7 +9685,7 @@ bool CreateIndexNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
|
|||||||
dsc dscName;
|
dsc dscName;
|
||||||
const MetaName &relationName = relation->dsqlName;
|
const MetaName &relationName = relation->dsqlName;
|
||||||
dscName.makeText(relationName.length(), CS_METADATA, (UCHAR*) relationName.c_str());
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -9742,12 +9753,13 @@ string AlterIndexNode::internalPrint(NodePrinter& printer) const
|
|||||||
|
|
||||||
bool AlterIndexNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
|
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;
|
dsc dscName;
|
||||||
dscName.makeText(relationName.length(), CS_METADATA, (UCHAR*) relationName.c_str());
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -9804,7 +9816,8 @@ string SetStatisticsNode::internalPrint(NodePrinter& printer) const
|
|||||||
|
|
||||||
bool SetStatisticsNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
|
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;
|
dsc dscName;
|
||||||
dscName.makeText(relationName.length(), CS_METADATA, (UCHAR*) relationName.c_str());
|
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)
|
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;
|
dsc dscName;
|
||||||
dscName.makeText(relationName.length(), CS_METADATA, (UCHAR*) relationName.c_str());
|
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;
|
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"));
|
ERRD_post(Arg::Gds(isc_dsql_cant_grant_option) << Arg::Str("system privileges"));
|
||||||
break;
|
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:
|
default:
|
||||||
break;
|
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);
|
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();
|
(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);
|
MetaName grantorRevoker(grantor ? *grantor : currentUser);
|
||||||
|
|
||||||
if (!isGrant && !privs) // REVOKE ALL ON ALL
|
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$USER_TYPE = userType AND
|
||||||
PRIV.RDB$GRANTOR NOT MISSING
|
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)
|
grantorRevoker == PRIV.RDB$GRANTOR)
|
||||||
{
|
{
|
||||||
ERASE PRIV;
|
ERASE PRIV;
|
||||||
@ -11446,6 +11470,8 @@ void GrantRevokeNode::grantRevoke(thread_db* tdbb, jrd_tra* transaction, const G
|
|||||||
for (const char* pr = privileges; *pr; ++pr)
|
for (const char* pr = privileges; *pr; ++pr)
|
||||||
{
|
{
|
||||||
bool duplicate = false;
|
bool duplicate = false;
|
||||||
|
MetaName newField = field;
|
||||||
|
int newOptions = options;
|
||||||
priv[0] = *pr;
|
priv[0] = *pr;
|
||||||
|
|
||||||
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE transaction)
|
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$FIELD_NAME EQUIV NULLIF(field.c_str(), '') OR
|
||||||
(PRIV.RDB$OBJECT_TYPE EQ obj_sql_role))
|
(PRIV.RDB$OBJECT_TYPE EQ obj_sql_role))
|
||||||
{
|
{
|
||||||
if (PRIV.RDB$GRANT_OPTION.NULL ||
|
// It means we have such privilege without grant option but
|
||||||
PRIV.RDB$GRANT_OPTION ||
|
// user grants it with grant option. We should re-grant existing privilege.
|
||||||
PRIV.RDB$GRANT_OPTION == options)
|
const bool addGrantOption = (!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
|
|
||||||
|
|
||||||
if (duplicate && objType == obj_sql_role && field == "D" &&
|
// It means we have such granted role but without DEFAULT but user grants with DEFAULT.
|
||||||
PRIV.RDB$FIELD_NAME.NULL)
|
// We should re-grant it.
|
||||||
{
|
const bool addDefaultRole = (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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
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)
|
if (!duplicate)
|
||||||
ERASE PRIV;
|
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
|
// As long as only locksmith can use GRANTED BY, no need specially checking
|
||||||
// for privileges of current user. AP-2008
|
// for privileges of current user. AP-2008
|
||||||
|
|
||||||
if (objType == 0)
|
switch (objType)
|
||||||
{
|
{
|
||||||
// Relation or view because we cannot distinguish at this point.
|
case obj_relation:
|
||||||
checkGrantorCanGrant(tdbb, transaction,
|
{
|
||||||
tdbb->getAttachment()->att_user->getUserName().c_str(), priv, objName,
|
// Relation or view because we cannot distinguish at this point.
|
||||||
field, true);
|
checkGrantorCanGrantRelation(tdbb, transaction, currentUser.c_str(), priv, objName,
|
||||||
}
|
field, true);
|
||||||
else if (objType >= obj_database)
|
break;
|
||||||
{
|
}
|
||||||
checkGrantorCanGrantDdl(tdbb, transaction,
|
|
||||||
tdbb->getAttachment()->att_user->getUserName().c_str(), priv, objName);
|
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,
|
storePrivilege(tdbb, transaction, objName, user, newField, pr, userType, objType,
|
||||||
options, grantorRevoker);
|
newOptions, grantorRevoker);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // REVOKE
|
else // REVOKE
|
||||||
{
|
{
|
||||||
const bool revokeRoleDefault = (objType == obj_sql_role) && field.hasData();
|
const bool revokeDefaultRole = (objType == obj_sql_role) && field.hasData();
|
||||||
MetaName curField;
|
const bool revokeGrantOption = options;
|
||||||
int curOptions = 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)
|
for (const char* pr = privileges; (priv[0] = *pr); ++pr)
|
||||||
{
|
{
|
||||||
bool grantErased = false;
|
bool grantErased = false;
|
||||||
bool badGrantor = false;
|
bool badGrantor = false;
|
||||||
|
|
||||||
if (field.hasData() && objType != obj_sql_role)
|
if (withField) // (2)
|
||||||
{
|
{
|
||||||
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE transaction)
|
FOR(REQUEST_HANDLE request TRANSACTION_HANDLE transaction)
|
||||||
PRIV IN RDB$USER_PRIVILEGES
|
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)
|
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;
|
ERASE PRIV;
|
||||||
grantErased = true;
|
grantErased = true;
|
||||||
|
|
||||||
|
if (revokeDefaultRole || revokeGrantOption)
|
||||||
|
{
|
||||||
|
storePrivilege(tdbb, transaction, objName, user, newField, pr, userType, objType,
|
||||||
|
newOptions, grantorRevoker);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
badGrantor = true;
|
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
|
((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
|
(currentUser != user) && // And current user does not revoke his own grant
|
||||||
((isItSqlRole(tdbb, transaction, objName, owner) && // Pick up role owner name
|
((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
|
(owner == currentUser))) || // Current user is role owner
|
||||||
(getGrantorOption(tdbb, transaction, currentUser, obj_user, objName) == 2)))) // or has ADMIN option
|
(getGrantorOption(tdbb, transaction, currentUser, obj_user, objName) == 2)))) // or has ADMIN option
|
||||||
{
|
{
|
||||||
curOptions = PRIV.RDB$GRANT_OPTION;
|
MetaName newField = NULL;
|
||||||
curField = PRIV.RDB$FIELD_NAME;
|
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;
|
ERASE PRIV;
|
||||||
grantErased = true;
|
grantErased = true;
|
||||||
|
|
||||||
|
if (revokeDefaultRole || revokeGrantOption)
|
||||||
|
{
|
||||||
|
storePrivilege(tdbb, transaction, objName, user, newField, pr, userType, objType,
|
||||||
|
newOptions, grantorRevoker);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
badGrantor = true;
|
badGrantor = true;
|
||||||
@ -11603,25 +11669,7 @@ void GrantRevokeNode::grantRevoke(thread_db* tdbb, jrd_tra* transaction, const G
|
|||||||
END_FOR
|
END_FOR
|
||||||
}
|
}
|
||||||
|
|
||||||
if (grantErased)
|
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 (badGrantor)
|
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.
|
// 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 char* grantor, const char* privilege, const MetaName& relationName,
|
||||||
const MetaName& fieldName, bool topLevel)
|
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)
|
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);
|
G_VIEW.RDB$RELATION_NAME, G_FLD.RDB$BASE_FIELD, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
checkGrantorCanGrant(tdbb, transaction, grantor, privilege,
|
checkGrantorCanGrantRelation(tdbb, transaction, grantor, privilege,
|
||||||
G_VIEW.RDB$RELATION_NAME, G_FLD.RDB$BASE_FIELD, false);
|
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,
|
void GrantRevokeNode::checkGrantorCanGrantDdl(thread_db* tdbb, jrd_tra* transaction,
|
||||||
const MetaName& grantor, const char* privilege, const MetaName& objName)
|
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;
|
return;
|
||||||
|
|
||||||
AutoCacheRequest request(tdbb, drq_l_grant_option, DYN_REQUESTS);
|
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)
|
FOR (REQUEST_HANDLE request TRANSACTION_HANDLE transaction)
|
||||||
PRV IN RDB$USER_PRIVILEGES
|
PRV IN RDB$USER_PRIVILEGES
|
||||||
WITH PRV.RDB$USER = UPPERCASE(grantor.c_str()) AND
|
WITH ((PRV.RDB$USER = UPPERCASE(grantor.c_str()) AND
|
||||||
PRV.RDB$USER_TYPE = obj_user AND
|
PRV.RDB$USER_TYPE = obj_user) OR (PRV.RDB$USER_TYPE = obj_sql_role)) AND
|
||||||
PRV.RDB$RELATION_NAME EQ objName.c_str() AND
|
PRV.RDB$RELATION_NAME EQ objName.c_str() AND
|
||||||
PRV.RDB$OBJECT_TYPE >= obj_database AND
|
PRV.RDB$OBJECT_TYPE >= obj_database AND
|
||||||
PRV.RDB$PRIVILEGE EQ privilege
|
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
|
END_FOR
|
||||||
|
|
||||||
if (!grantable)
|
if (!grantable)
|
||||||
{
|
{
|
||||||
// no .. privilege with grant option on DDL ..
|
// no @1 privilege with grant option on DDL @2
|
||||||
status_exception::raise(Arg::PrivateDyn(174) << privilege << objName.c_str());
|
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,
|
void GrantRevokeNode::storePrivilege(thread_db* tdbb, jrd_tra* transaction, const MetaName& object,
|
||||||
const MetaName& user, const MetaName& field, const TEXT* privilege, SSHORT userType,
|
const MetaName& user, const MetaName& field, const TEXT* privilege, SSHORT userType,
|
||||||
SSHORT objType, int option, const MetaName& grantor)
|
SSHORT objType, int option, const MetaName& grantor)
|
||||||
@ -12065,7 +12154,7 @@ void AlterDatabaseNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratc
|
|||||||
{
|
{
|
||||||
checkClauses(tdbb);
|
checkClauses(tdbb);
|
||||||
|
|
||||||
// Take a LCK_alter_database lock to prevent altering of the database from
|
// Take a LCK_alter_database lock to prevent altering of the database from
|
||||||
// parallel transactions
|
// parallel transactions
|
||||||
|
|
||||||
if (!transaction->tra_alter_db_lock)
|
if (!transaction->tra_alter_db_lock)
|
||||||
|
@ -2269,13 +2269,15 @@ private:
|
|||||||
void modifyPrivileges(thread_db* tdbb, jrd_tra* transaction, SSHORT option, const GranteeClause* user);
|
void modifyPrivileges(thread_db* tdbb, jrd_tra* transaction, SSHORT option, const GranteeClause* user);
|
||||||
void grantRevoke(thread_db* tdbb, jrd_tra* transaction, const GranteeClause* object,
|
void grantRevoke(thread_db* tdbb, jrd_tra* transaction, const GranteeClause* object,
|
||||||
const GranteeClause* userNod, const char* privs, Firebird::MetaName field, int options);
|
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 char* privilege, const Firebird::MetaName& relationName,
|
||||||
const Firebird::MetaName& fieldName, bool topLevel);
|
const Firebird::MetaName& fieldName, bool topLevel);
|
||||||
static void checkGrantorCanGrantRole(thread_db* tdbb, jrd_tra* transaction,
|
static void checkGrantorCanGrantRole(thread_db* tdbb, jrd_tra* transaction,
|
||||||
const Firebird::MetaName& grantor, const Firebird::MetaName& roleName);
|
const Firebird::MetaName& grantor, const Firebird::MetaName& roleName);
|
||||||
static void checkGrantorCanGrantDdl(thread_db* tdbb, jrd_tra* transaction,
|
static void checkGrantorCanGrantDdl(thread_db* tdbb, jrd_tra* transaction,
|
||||||
const Firebird::MetaName& grantor, const char* privilege, const Firebird::MetaName& objName);
|
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,
|
static void storePrivilege(thread_db* tdbb, jrd_tra* transaction,
|
||||||
const Firebird::MetaName& object, const Firebird::MetaName& user,
|
const Firebird::MetaName& object, const Firebird::MetaName& user,
|
||||||
const Firebird::MetaName& field, const TEXT* privilege, SSHORT userType,
|
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);
|
m_alignment = m_meta->getAlignment(&st);
|
||||||
check(&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())
|
for (pb.rewind(); !pb.isEof(); pb.moveNext())
|
||||||
{
|
{
|
||||||
UCHAR t = pb.getClumpTag();
|
UCHAR t = pb.getClumpTag();
|
||||||
@ -146,7 +140,6 @@ DsqlBatch::DsqlBatch(dsql_req* req, const dsql_msg* /*message*/, IMessageMetadat
|
|||||||
switch (t)
|
switch (t)
|
||||||
{
|
{
|
||||||
case SQL_BLOB:
|
case SQL_BLOB:
|
||||||
case SQL_ARRAY:
|
|
||||||
{
|
{
|
||||||
BlobMeta bm;
|
BlobMeta bm;
|
||||||
bm.offset = m_meta->getOffset(&st, i);
|
bm.offset = m_meta->getOffset(&st, i);
|
||||||
@ -160,9 +153,9 @@ DsqlBatch::DsqlBatch(dsql_req* req, const dsql_msg* /*message*/, IMessageMetadat
|
|||||||
}
|
}
|
||||||
|
|
||||||
// allocate data buffers
|
// allocate data buffers
|
||||||
m_messages.setBuf(m_bufferSize);
|
m_messages.setBuf(m_bufferSize, MAX(m_alignedMessage * 2, RAM_BATCH));
|
||||||
if (m_blobMeta.hasData())
|
if (m_blobMeta.hasData())
|
||||||
m_blobs.setBuf(m_bufferSize);
|
m_blobs.setBuf(m_bufferSize, RAM_BATCH);
|
||||||
|
|
||||||
// assign initial default BPB
|
// assign initial default BPB
|
||||||
setDefBpb(FB_NELEM(initBlobParameters), initBlobParameters);
|
setDefBpb(FB_NELEM(initBlobParameters), initBlobParameters);
|
||||||
@ -270,6 +263,7 @@ void DsqlBatch::add(thread_db* tdbb, ULONG count, const void* inBuffer)
|
|||||||
return;
|
return;
|
||||||
m_messages.align(m_alignment);
|
m_messages.align(m_alignment);
|
||||||
m_messages.put(inBuffer, (count - 1) * m_alignedMessage + m_messageSize);
|
m_messages.put(inBuffer, (count - 1) * m_alignedMessage + m_messageSize);
|
||||||
|
DEB_BATCH(fprintf(stderr, "Put to batch %d messages\n", count));
|
||||||
}
|
}
|
||||||
|
|
||||||
void DsqlBatch::blobCheckMeta()
|
void DsqlBatch::blobCheckMeta()
|
||||||
@ -419,6 +413,7 @@ void DsqlBatch::addBlobStream(thread_db* tdbb, unsigned length, const void* inBu
|
|||||||
m_lastBlob = MAX_ULONG;
|
m_lastBlob = MAX_ULONG;
|
||||||
|
|
||||||
// store stream for further processing
|
// store stream for further processing
|
||||||
|
DEB_BATCH(fprintf(stderr, "Store stream %d\n", length));
|
||||||
fb_assert(m_blobs.getSize() % BLOB_STREAM_ALIGN == 0);
|
fb_assert(m_blobs.getSize() % BLOB_STREAM_ALIGN == 0);
|
||||||
m_blobs.put(inBuffer, length);
|
m_blobs.put(inBuffer, length);
|
||||||
}
|
}
|
||||||
@ -539,13 +534,13 @@ private:
|
|||||||
|
|
||||||
// parse blob header
|
// parse blob header
|
||||||
fb_assert(intptr_t(flow.data) % BLOB_STREAM_ALIGN == 0);
|
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* blobSize = reinterpret_cast<ULONG*>(flow.data + sizeof(ISC_QUAD));
|
||||||
ULONG* bpbSize = reinterpret_cast<ULONG*>(flow.data + sizeof(ISC_QUAD) + sizeof(ULONG));
|
ULONG* bpbSize = reinterpret_cast<ULONG*>(flow.data + sizeof(ISC_QUAD) + sizeof(ULONG));
|
||||||
flow.newHdr(*blobSize);
|
flow.newHdr(*blobSize);
|
||||||
ULONG currentBpbSize = *bpbSize;
|
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
|
// Sanity check
|
||||||
if (*bpbSize)
|
if (*bpbSize)
|
||||||
@ -591,7 +586,9 @@ private:
|
|||||||
bid engineBlobId;
|
bid engineBlobId;
|
||||||
blob = blb::create2(tdbb, transaction, &engineBlobId, bpb->getCount(),
|
blob = blb::create2(tdbb, transaction, &engineBlobId, bpb->getCount(),
|
||||||
bpb->begin(), true);
|
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);
|
fb_assert(req);
|
||||||
|
|
||||||
// prepare completion interface
|
// prepare completion interface
|
||||||
AutoPtr<BatchCompletionState, SimpleDispose<BatchCompletionState> > completionState
|
AutoPtr<BatchCompletionState, SimpleDispose> completionState
|
||||||
(FB_NEW BatchCompletionState(m_flags & (1 << IBatch::TAG_RECORD_COUNTS), m_detailed));
|
(FB_NEW BatchCompletionState(m_flags & (1 << IBatch::TAG_RECORD_COUNTS), m_detailed));
|
||||||
AutoSetRestore<bool> batchFlag(&req->req_batch, true);
|
AutoSetRestore<bool> batchFlag(&req->req_batch, true);
|
||||||
const dsql_msg* message = m_request->getStatement()->getSendMsg();
|
const dsql_msg* message = m_request->getStatement()->getSendMsg();
|
||||||
@ -702,6 +699,9 @@ private:
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
ISC_QUAD* id = reinterpret_cast<ISC_QUAD*>(&data[m_blobMeta[i].offset]);
|
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;
|
ISC_QUAD newId;
|
||||||
if (!m_blobMap.get(*id, newId))
|
if (!m_blobMap.get(*id, newId))
|
||||||
{
|
{
|
||||||
@ -719,9 +719,9 @@ private:
|
|||||||
remains -= m_messageSize;
|
remains -= m_messageSize;
|
||||||
|
|
||||||
UCHAR* msgBuffer = m_request->req_msg_buffers[message->msg_buffer_number];
|
UCHAR* msgBuffer = m_request->req_msg_buffers[message->msg_buffer_number];
|
||||||
DEB_BATCH(fprintf(stderr, "\n\n+++ Send\n\n"));
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
// runsend data to request and collect stats
|
||||||
ULONG before = req->req_records_inserted + req->req_records_updated +
|
ULONG before = req->req_records_inserted + req->req_records_updated +
|
||||||
req->req_records_deleted;
|
req->req_records_deleted;
|
||||||
EXE_send(tdbb, req, message->msg_number, message->msg_length, msgBuffer);
|
EXE_send(tdbb, req, message->msg_number, message->msg_length, msgBuffer);
|
||||||
@ -753,6 +753,15 @@ private:
|
|||||||
m_messages.remained(remains, alignedData - data);
|
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
|
// reset to initial state
|
||||||
cancel(tdbb);
|
cancel(tdbb);
|
||||||
|
|
||||||
@ -762,14 +771,11 @@ private:
|
|||||||
void DsqlBatch::cancel(thread_db* tdbb)
|
void DsqlBatch::cancel(thread_db* tdbb)
|
||||||
{
|
{
|
||||||
m_messages.clear();
|
m_messages.clear();
|
||||||
if (m_blobMeta.hasData())
|
m_blobs.clear();
|
||||||
{
|
m_setBlobSize = false;
|
||||||
m_blobs.clear();
|
m_lastBlob = MAX_ULONG;
|
||||||
m_setBlobSize = false;
|
memset(&m_genId, 0, sizeof(m_genId));
|
||||||
m_lastBlob = MAX_ULONG;
|
m_blobMap.clear();
|
||||||
memset(&m_genId, 0, sizeof(m_genId));
|
|
||||||
m_blobMap.clear();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DsqlBatch::genBlobId(ISC_QUAD* blobId)
|
void DsqlBatch::genBlobId(ISC_QUAD* blobId)
|
||||||
@ -779,13 +785,13 @@ void DsqlBatch::genBlobId(ISC_QUAD* blobId)
|
|||||||
memcpy(blobId, &m_genId, sizeof(m_genId));
|
memcpy(blobId, &m_genId, sizeof(m_genId));
|
||||||
}
|
}
|
||||||
|
|
||||||
void DsqlBatch::DataCache::setBuf(ULONG size)
|
void DsqlBatch::DataCache::setBuf(ULONG size, ULONG cacheCapacity)
|
||||||
{
|
{
|
||||||
m_limit = size;
|
m_limit = size;
|
||||||
|
|
||||||
// create ram cache
|
fb_assert(m_cacheCapacity == 0);
|
||||||
fb_assert(!m_cache);
|
fb_assert(cacheCapacity >= RAM_BATCH);
|
||||||
m_cache = FB_NEW_POOL(getPool()) Cache;
|
m_cacheCapacity = cacheCapacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DsqlBatch::DataCache::put3(const void* data, ULONG dataSize, ULONG offset)
|
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)
|
if (offset >= m_used)
|
||||||
{
|
{
|
||||||
// data in cache
|
// data in cache
|
||||||
UCHAR* to = m_cache->begin();
|
UCHAR* to = m_cache.begin();
|
||||||
to += (offset - m_used);
|
to += (offset - m_used);
|
||||||
fb_assert(to < m_cache->end());
|
fb_assert(to < m_cache.end());
|
||||||
memcpy(to, data, dataSize);
|
memcpy(to, data, dataSize);
|
||||||
}
|
}
|
||||||
else
|
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)
|
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) <<
|
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-104) <<
|
||||||
Arg::Gds(isc_batch_too_big));
|
Arg::Gds(isc_batch_too_big));
|
||||||
@ -823,17 +829,17 @@ void DsqlBatch::DataCache::put(const void* d, ULONG dataSize)
|
|||||||
const ULONG K = 4;
|
const ULONG K = 4;
|
||||||
|
|
||||||
// ensure ram cache presence
|
// ensure ram cache presence
|
||||||
fb_assert(m_cache);
|
fb_assert(m_cacheCapacity);
|
||||||
|
|
||||||
// swap to secondary cache if needed
|
// 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
|
// store data in the end of ram cache if needed
|
||||||
// avoid copy in case of huge buffer passed
|
// avoid copy in case of huge buffer passed
|
||||||
ULONG delta = m_cache->getCapacity() - m_cache->getCount();
|
ULONG delta = m_cacheCapacity - m_cache.getCount();
|
||||||
if (dataSize - delta < m_cache->getCapacity() / K)
|
if (dataSize - delta < m_cacheCapacity / K)
|
||||||
{
|
{
|
||||||
m_cache->append(data, delta);
|
m_cache.append(data, delta);
|
||||||
data += delta;
|
data += delta;
|
||||||
dataSize -= delta;
|
dataSize -= delta;
|
||||||
}
|
}
|
||||||
@ -842,13 +848,13 @@ void DsqlBatch::DataCache::put(const void* d, ULONG dataSize)
|
|||||||
if (!m_space)
|
if (!m_space)
|
||||||
m_space = FB_NEW_POOL(getPool()) TempSpace(getPool(), TEMP_NAME);
|
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());
|
const FB_UINT64 writtenBytes = m_space->write(m_used, m_cache.begin(), m_cache.getCount());
|
||||||
fb_assert(writtenBytes == m_cache->getCount());
|
fb_assert(writtenBytes == m_cache.getCount());
|
||||||
m_used += m_cache->getCount();
|
m_used += m_cache.getCount();
|
||||||
m_cache->clear();
|
m_cache.clear();
|
||||||
|
|
||||||
// in a case of huge buffer write directly to tempspace
|
// 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);
|
const FB_UINT64 writtenBytes = m_space->write(m_used, data, dataSize);
|
||||||
fb_assert(writtenBytes == 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)
|
void DsqlBatch::DataCache::align(ULONG alignment)
|
||||||
@ -873,16 +879,14 @@ void DsqlBatch::DataCache::align(ULONG alignment)
|
|||||||
|
|
||||||
void DsqlBatch::DataCache::done()
|
void DsqlBatch::DataCache::done()
|
||||||
{
|
{
|
||||||
fb_assert(m_cache);
|
if (m_cache.getCount() && m_used)
|
||||||
|
|
||||||
if (m_cache->getCount() && m_used)
|
|
||||||
{
|
{
|
||||||
fb_assert(m_space);
|
fb_assert(m_space);
|
||||||
|
|
||||||
const FB_UINT64 writtenBytes = m_space->write(m_used, m_cache->begin(), m_cache->getCount());
|
const FB_UINT64 writtenBytes = m_space->write(m_used, m_cache.begin(), m_cache.getCount());
|
||||||
fb_assert(writtenBytes == m_cache->getCount());
|
fb_assert(writtenBytes == m_cache.getCount());
|
||||||
m_used += m_cache->getCount();
|
m_used += m_cache.getCount();
|
||||||
m_cache->clear();
|
m_cache.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -891,26 +895,26 @@ ULONG DsqlBatch::DataCache::get(UCHAR** buffer)
|
|||||||
if (m_used > m_got)
|
if (m_used > m_got)
|
||||||
{
|
{
|
||||||
// get data from tempspace
|
// get data from tempspace
|
||||||
ULONG dlen = m_cache->getCount();
|
ULONG dlen = m_cache.getCount();
|
||||||
ULONG delta = m_cache->getCapacity() - dlen;
|
ULONG delta = m_cacheCapacity - dlen;
|
||||||
if (delta > m_used - m_got)
|
if (delta > m_used - m_got)
|
||||||
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;
|
buf += dlen;
|
||||||
const FB_UINT64 readBytes = m_space->read(m_got, buf, delta);
|
const FB_UINT64 readBytes = m_space->read(m_got, buf, delta);
|
||||||
fb_assert(readBytes == delta);
|
fb_assert(readBytes == delta);
|
||||||
m_got += delta;
|
m_got += delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_cache->getCount())
|
if (m_cache.getCount())
|
||||||
{
|
{
|
||||||
if (m_shift)
|
if (m_shift)
|
||||||
m_cache->removeCount(0, m_shift);
|
m_cache.removeCount(0, m_shift);
|
||||||
|
|
||||||
// return buffer full of data
|
// return buffer full of data
|
||||||
*buffer = m_cache->begin();
|
*buffer = m_cache.begin();
|
||||||
fb_assert(intptr_t(*buffer) % FB_ALIGNMENT == 0);
|
fb_assert(intptr_t(*buffer) % FB_ALIGNMENT == 0);
|
||||||
return m_cache->getCount();
|
return m_cache.getCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
// no more data
|
// no more data
|
||||||
@ -926,9 +930,9 @@ ULONG DsqlBatch::DataCache::reget(ULONG remains, UCHAR** buffer, ULONG alignment
|
|||||||
a = alignment - a;
|
a = alignment - a;
|
||||||
remains += 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);
|
ULONG size = get(buffer);
|
||||||
size -= a;
|
size -= a;
|
||||||
*buffer += a;
|
*buffer += a;
|
||||||
@ -949,25 +953,25 @@ void DsqlBatch::DataCache::remained(ULONG size, ULONG alignment)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!size)
|
if (!size)
|
||||||
m_cache->clear();
|
m_cache.clear();
|
||||||
else
|
else
|
||||||
m_cache->removeCount(0, m_cache->getCount() - size);
|
m_cache.removeCount(0, m_cache.getCount() - size);
|
||||||
|
|
||||||
m_shift = alignment;
|
m_shift = alignment;
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG DsqlBatch::DataCache::getSize() const
|
ULONG DsqlBatch::DataCache::getSize() const
|
||||||
{
|
{
|
||||||
if(!m_cache)
|
if (!m_cacheCapacity)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fb_assert((MAX_ULONG - 1) - m_used > m_cache->getCount());
|
fb_assert((MAX_ULONG - 1) - m_used > m_cache.getCount());
|
||||||
return m_used + m_cache->getCount();
|
return m_used + m_cache.getCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DsqlBatch::DataCache::clear()
|
void DsqlBatch::DataCache::clear()
|
||||||
{
|
{
|
||||||
m_cache->clear();
|
m_cache.clear();
|
||||||
if (m_space && m_used)
|
if (m_space && m_used)
|
||||||
m_space->releaseSpace(0, m_used);
|
m_space->releaseSpace(0, m_used);
|
||||||
m_used = m_got = m_shift = 0;
|
m_used = m_got = m_shift = 0;
|
||||||
|
@ -107,11 +107,11 @@ private:
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DataCache(MemoryPool& p)
|
DataCache(MemoryPool& p)
|
||||||
: PermanentStorage(p),
|
: PermanentStorage(p), m_cache(getPool()),
|
||||||
m_used(0), m_got(0), m_limit(0), m_shift(0)
|
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 put(const void* data, ULONG dataSize);
|
||||||
void put3(const void* data, ULONG dataSize, ULONG offset);
|
void put3(const void* data, ULONG dataSize, ULONG offset);
|
||||||
@ -124,10 +124,10 @@ private:
|
|||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef Firebird::Vector<UCHAR, DsqlBatch::RAM_BATCH, SINT64> Cache;
|
typedef Firebird::Array<UCHAR> Cache;
|
||||||
Firebird::AutoPtr<Cache> m_cache;
|
Cache m_cache;
|
||||||
Firebird::AutoPtr<TempSpace> m_space;
|
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
|
struct BlobMeta
|
||||||
|
@ -1397,18 +1397,6 @@ void ArithmeticNode::getDescDialect1(thread_db* /*tdbb*/, dsc* desc, dsc& desc1,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case blr_divide:
|
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
|
// for compatibility with older versions of the product, we accept
|
||||||
// text types for division in blr_version4 (dialect <= 1) only
|
// text types for division in blr_version4 (dialect <= 1) only
|
||||||
if (!(DTYPE_IS_NUMERIC(desc1.dsc_dtype) || DTYPE_IS_TEXT(desc1.dsc_dtype)))
|
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);
|
fb_assert(otherNode);
|
||||||
thread_db* tdbb = JRD_get_thread_data();
|
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)
|
ValueExprNode* LiteralNode::pass2(thread_db* tdbb, CompilerScratch* csb)
|
||||||
|
@ -329,17 +329,12 @@ bool Parser::yylexSkipSpaces()
|
|||||||
if (lex.ptr >= lex.end)
|
if (lex.ptr >= lex.end)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
c = *lex.ptr++;
|
if (yylexSkipEol())
|
||||||
|
continue;
|
||||||
|
|
||||||
// Process comments
|
// Process comments
|
||||||
|
|
||||||
if (c == '\n')
|
c = *lex.ptr++;
|
||||||
{
|
|
||||||
lex.lines++;
|
|
||||||
lex.line_start = lex.ptr;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c == '-' && lex.ptr < lex.end && *lex.ptr == '-')
|
if (c == '-' && lex.ptr < lex.end && *lex.ptr == '-')
|
||||||
{
|
{
|
||||||
// single-line
|
// single-line
|
||||||
@ -347,12 +342,9 @@ bool Parser::yylexSkipSpaces()
|
|||||||
lex.ptr++;
|
lex.ptr++;
|
||||||
while (lex.ptr < lex.end)
|
while (lex.ptr < lex.end)
|
||||||
{
|
{
|
||||||
if ((c = *lex.ptr++) == '\n')
|
if (yylexSkipEol())
|
||||||
{
|
|
||||||
lex.lines++;
|
|
||||||
lex.line_start = lex.ptr; // + 1; // CVC: +1 left out.
|
|
||||||
break;
|
break;
|
||||||
}
|
lex.ptr++;
|
||||||
}
|
}
|
||||||
if (lex.ptr >= lex.end)
|
if (lex.ptr >= lex.end)
|
||||||
return false;
|
return false;
|
||||||
@ -367,17 +359,14 @@ bool Parser::yylexSkipSpaces()
|
|||||||
lex.ptr++;
|
lex.ptr++;
|
||||||
while (lex.ptr < lex.end)
|
while (lex.ptr < lex.end)
|
||||||
{
|
{
|
||||||
|
if (yylexSkipEol())
|
||||||
|
continue;
|
||||||
|
|
||||||
if ((c = *lex.ptr++) == '*')
|
if ((c = *lex.ptr++) == '*')
|
||||||
{
|
{
|
||||||
if (*lex.ptr == '/')
|
if (*lex.ptr == '/')
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (c == '\n')
|
|
||||||
{
|
|
||||||
lex.lines++;
|
|
||||||
lex.line_start = lex.ptr; // + 1; // CVC: +1 left out.
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (lex.ptr >= lex.end)
|
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()
|
int Parser::yylexAux()
|
||||||
{
|
{
|
||||||
thread_db* tdbb = JRD_get_thread_data();
|
thread_db* tdbb = JRD_get_thread_data();
|
||||||
|
@ -241,6 +241,7 @@ private:
|
|||||||
|
|
||||||
int yylex();
|
int yylex();
|
||||||
bool yylexSkipSpaces();
|
bool yylexSkipSpaces();
|
||||||
|
bool yylexSkipEol(); // returns true if EOL is detected and skipped
|
||||||
int yylexAux();
|
int yylexAux();
|
||||||
|
|
||||||
void yyerror(const TEXT* error_string);
|
void yyerror(const TEXT* error_string);
|
||||||
@ -271,7 +272,7 @@ private:
|
|||||||
clause = value;
|
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)
|
void setClause(Firebird::AutoPtr<T, Delete>& clause, const char* duplicateMsg, T* value)
|
||||||
{
|
{
|
||||||
checkDuplicateClause(clause, duplicateMsg);
|
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);
|
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);
|
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->cursorNumber = csb->csb_blr_reader.getWord();
|
||||||
node->rse = PAR_rse(tdbb, csb);
|
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.
|
// 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.
|
// 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)
|
for (StreamList::const_iterator i = cursorStreams.begin(); i != cursorStreams.end(); ++i)
|
||||||
{
|
{
|
||||||
csb->csb_rpt[*i].csb_cursor_number = cursorNumber;
|
csb->csb_rpt[*i].csb_cursor_number = cursorNumber;
|
||||||
csb->csb_rpt[*i].activate();
|
csb->csb_rpt[*i].activate();
|
||||||
|
if (dsqlCursorType == CUR_TYPE_EXPLICIT)
|
||||||
|
csb->csb_rpt[*i].csb_flags |= csb_unstable;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
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
|
void SetRoleNode::execute(thread_db* tdbb, dsql_req* request) const
|
||||||
{
|
{
|
||||||
SET_TDBB(tdbb);
|
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
|
class SetRoleNode : public SessionManagementNode
|
||||||
{
|
{
|
||||||
public:
|
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;
|
desc.dsc_address = dsql_msg_buf + (IPTR) desc.dsc_address;
|
||||||
|
|
||||||
if (notNull)
|
if (notNull)
|
||||||
MOVD_move(tdbb, &parDesc, &desc);
|
MOVD_move(tdbb, &parDesc, &desc, toExternal);
|
||||||
else
|
else
|
||||||
memset(desc.dsc_address, 0, desc.dsc_length);
|
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.
|
// Safe cast because desc is used as source only.
|
||||||
desc.dsc_address = const_cast<UCHAR*>(in_dsql_msg_buf) + (IPTR) desc.dsc_address;
|
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
|
else
|
||||||
memset(parDesc.dsc_address, 0, parDesc.dsc_length);
|
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;
|
dsc desc = parameter->par_desc;
|
||||||
desc.dsc_address = msgBuffer + (IPTR) desc.dsc_address;
|
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;
|
dsql_par* null_ind = parameter->par_null;
|
||||||
if (null_ind != 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;
|
dsc desc = parameter->par_desc;
|
||||||
desc.dsc_address = msgBuffer + (IPTR) desc.dsc_address;
|
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;
|
dsql_par* null_ind = parameter->par_null;
|
||||||
if (null_ind != NULL)
|
if (null_ind != NULL)
|
||||||
|
@ -33,11 +33,11 @@ using namespace Firebird;
|
|||||||
|
|
||||||
|
|
||||||
// Move (and possible convert) something to something else.
|
// 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
|
try
|
||||||
{
|
{
|
||||||
MOV_move(tdbb, from, to);
|
MOV_move_ext(tdbb, from, to, toExternal);
|
||||||
}
|
}
|
||||||
catch (const status_exception& ex)
|
catch (const status_exception& ex)
|
||||||
{
|
{
|
||||||
|
@ -24,6 +24,6 @@
|
|||||||
#ifndef DSQL_MOVD_PROTO_H
|
#ifndef DSQL_MOVD_PROTO_H
|
||||||
#define 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
|
#endif // DSQL_MOVD_PROTO_H
|
||||||
|
@ -618,6 +618,7 @@ using namespace Firebird;
|
|||||||
%token <metaNamePtr> RDB_ERROR
|
%token <metaNamePtr> RDB_ERROR
|
||||||
%token <metaNamePtr> RDB_ROLE_IN_USE
|
%token <metaNamePtr> RDB_ROLE_IN_USE
|
||||||
%token <metaNamePtr> RDB_SYSTEM_PRIVILEGE
|
%token <metaNamePtr> RDB_SYSTEM_PRIVILEGE
|
||||||
|
%token <metaNamePtr> RESET
|
||||||
%token <metaNamePtr> SECURITY
|
%token <metaNamePtr> SECURITY
|
||||||
%token <metaNamePtr> SESSION
|
%token <metaNamePtr> SESSION
|
||||||
%token <metaNamePtr> SQL
|
%token <metaNamePtr> SQL
|
||||||
@ -784,6 +785,7 @@ using namespace Firebird;
|
|||||||
Jrd::SetRoundNode* setRoundNode;
|
Jrd::SetRoundNode* setRoundNode;
|
||||||
Jrd::SetTrapsNode* setTrapsNode;
|
Jrd::SetTrapsNode* setTrapsNode;
|
||||||
Jrd::SetBindNode* setBindNode;
|
Jrd::SetBindNode* setBindNode;
|
||||||
|
Jrd::SessionResetNode* sessionResetNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
%include types.y
|
%include types.y
|
||||||
@ -846,6 +848,7 @@ mng_statement
|
|||||||
| set_bind { $$ = $1; }
|
| set_bind { $$ = $1; }
|
||||||
| session_statement { $$ = $1; }
|
| session_statement { $$ = $1; }
|
||||||
| set_role { $$ = $1; }
|
| set_role { $$ = $1; }
|
||||||
|
| session_reset { $$ = $1; }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
@ -4166,7 +4169,8 @@ keyword_or_column
|
|||||||
| UPDATING
|
| UPDATING
|
||||||
| VAR_SAMP
|
| VAR_SAMP
|
||||||
| VAR_POP
|
| VAR_POP
|
||||||
| UNBOUNDED // added in FB 4.0
|
| DECFLOAT // added in FB 4.0
|
||||||
|
| UNBOUNDED
|
||||||
| WINDOW
|
| WINDOW
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -4830,15 +4834,17 @@ varbinary_character_keyword
|
|||||||
|
|
||||||
%type <legacyField> decfloat_type
|
%type <legacyField> decfloat_type
|
||||||
decfloat_type
|
decfloat_type
|
||||||
: DECFLOAT '(' signed_long_integer ')'
|
: DECFLOAT precision_opt_nz
|
||||||
{
|
{
|
||||||
if ($3 != 16 && $3 != 34)
|
SLONG precision = $2;
|
||||||
yyabandon(YYPOSNARG(3), -842, isc_decprecision_err); // DecFloat precision must be 16 or 34.
|
|
||||||
|
if (precision != 0 && precision != 16 && precision != 34)
|
||||||
|
yyabandon(YYPOSNARG(2), -842, isc_decprecision_err); // DecFloat precision must be 16 or 34.
|
||||||
|
|
||||||
$$ = newNode<dsql_fld>();
|
$$ = newNode<dsql_fld>();
|
||||||
$$->precision = $3;
|
$$->precision = precision == 0 ? 34 : (USHORT) precision;
|
||||||
$$->dtype = $3 == 16 ? dtype_dec64 : dtype_dec128;
|
$$->dtype = precision == 16 ? dtype_dec64 : dtype_dec128;
|
||||||
$$->length = $3 == 16 ? sizeof(Decimal64) : sizeof(Decimal128);
|
$$->length = precision == 16 ? sizeof(Decimal64) : sizeof(Decimal128);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -5040,6 +5046,12 @@ precision_opt
|
|||||||
| '(' nonneg_short_integer ')' { $$ = $2; }
|
| '(' 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
|
// transaction statements
|
||||||
|
|
||||||
@ -5130,6 +5142,12 @@ set_transaction
|
|||||||
{ $$ = $3; }
|
{ $$ = $3; }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
%type <sessionResetNode> session_reset
|
||||||
|
session_reset
|
||||||
|
: ALTER SESSION RESET
|
||||||
|
{ $$ = newNode<SessionResetNode>(); }
|
||||||
|
;
|
||||||
|
|
||||||
%type <setRoleNode> set_role
|
%type <setRoleNode> set_role
|
||||||
set_role
|
set_role
|
||||||
: SET ROLE valid_symbol_name
|
: SET ROLE valid_symbol_name
|
||||||
@ -8513,7 +8531,6 @@ non_reserved_word
|
|||||||
| BIND // added in FB 4.0
|
| BIND // added in FB 4.0
|
||||||
| COMPARE_DECFLOAT
|
| COMPARE_DECFLOAT
|
||||||
| CUME_DIST
|
| CUME_DIST
|
||||||
| DECFLOAT
|
|
||||||
| DEFINER
|
| DEFINER
|
||||||
| EXCLUDE
|
| EXCLUDE
|
||||||
| FIRST_DAY
|
| FIRST_DAY
|
||||||
@ -8532,6 +8549,7 @@ non_reserved_word
|
|||||||
| PRIVILEGE
|
| PRIVILEGE
|
||||||
| QUANTIZE
|
| QUANTIZE
|
||||||
| RANGE
|
| RANGE
|
||||||
|
| RESET
|
||||||
| SECURITY
|
| SECURITY
|
||||||
| SESSION
|
| SESSION
|
||||||
| SQL
|
| SQL
|
||||||
|
@ -1075,10 +1075,9 @@ static void gen_blob_open( const act* action, USHORT column)
|
|||||||
endp(column);
|
endp(column);
|
||||||
if (gpreGlob.sw_auto)
|
if (gpreGlob.sw_auto)
|
||||||
column -= INDENT;
|
column -= INDENT;
|
||||||
set_sqlcode(action, column);
|
|
||||||
if (action->act_type == ACT_blob_create)
|
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);
|
align(column + INDENT);
|
||||||
fprintf(gpreGlob.out_file, "%s = %s;", reference->ref_value, s);
|
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;
|
db = ready->rdy_database;
|
||||||
printa(column, "%s->detach(%s);",
|
printa(column, "%s->detach(%s);",
|
||||||
db->dbb_name->sym_string, status_vector(action));
|
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
|
// 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, "if (%s)", db->dbb_name->sym_string);
|
||||||
printa(column + INDENT, "%s->detach(%s);",
|
printa(column + INDENT, "%s->detach(%s);",
|
||||||
db->dbb_name->sym_string, status_vector(action));
|
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");
|
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) ?
|
(action->act_type == ACT_commit) ?
|
||||||
"commit" : (action->act_type == ACT_rollback) ? "rollback" : "prepare",
|
"commit" : (action->act_type == ACT_rollback) ? "rollback" : "prepare",
|
||||||
status_vector(action));
|
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_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_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 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_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_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 */
|
#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_length 7
|
||||||
#define isc_spb_bkp_skip_data 8
|
#define isc_spb_bkp_skip_data 8
|
||||||
#define isc_spb_bkp_stat 15
|
#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_checksums 0x01
|
||||||
#define isc_spb_bkp_ignore_limbo 0x02
|
#define isc_spb_bkp_ignore_limbo 0x02
|
||||||
#define isc_spb_bkp_metadata_only 0x04
|
#define isc_spb_bkp_metadata_only 0x04
|
||||||
@ -402,6 +405,7 @@
|
|||||||
#define isc_spb_bkp_convert 0x40
|
#define isc_spb_bkp_convert 0x40
|
||||||
#define isc_spb_bkp_expand 0x80
|
#define isc_spb_bkp_expand 0x80
|
||||||
#define isc_spb_bkp_no_triggers 0x8000
|
#define isc_spb_bkp_no_triggers 0x8000
|
||||||
|
#define isc_spb_bkp_zip 0x010000
|
||||||
|
|
||||||
/********************************************
|
/********************************************
|
||||||
* Parameters for isc_action_svc_properties *
|
* Parameters for isc_action_svc_properties *
|
||||||
@ -505,6 +509,9 @@
|
|||||||
#define isc_spb_res_access_mode 12
|
#define isc_spb_res_access_mode 12
|
||||||
#define isc_spb_res_fix_fss_data 13
|
#define isc_spb_res_fix_fss_data 13
|
||||||
#define isc_spb_res_fix_fss_metadata 14
|
#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_stat isc_spb_bkp_stat
|
||||||
#define isc_spb_res_metadata_only isc_spb_bkp_metadata_only
|
#define isc_spb_res_metadata_only isc_spb_bkp_metadata_only
|
||||||
#define isc_spb_res_deactivate_idx 0x0100
|
#define isc_spb_res_deactivate_idx 0x0100
|
||||||
|
@ -206,6 +206,9 @@
|
|||||||
/* Define to 1 if you have the `gmtime_r' function. */
|
/* Define to 1 if you have the `gmtime_r' function. */
|
||||||
#define HAVE_GMTIME_R 1
|
#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 to 1 if you have the <grp.h> header file. */
|
||||||
#define HAVE_GRP_H 1
|
#define HAVE_GRP_H 1
|
||||||
|
|
||||||
|
@ -212,6 +212,9 @@
|
|||||||
/* Define to 1 if you have the `gmtime_r' function. */
|
/* Define to 1 if you have the `gmtime_r' function. */
|
||||||
#define HAVE_GMTIME_R 1
|
#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 to 1 if you have the <grp.h> header file. */
|
||||||
#define HAVE_GRP_H 1
|
#define HAVE_GRP_H 1
|
||||||
|
|
||||||
|
@ -206,6 +206,9 @@
|
|||||||
/* Define to 1 if you have the `gmtime_r' function. */
|
/* Define to 1 if you have the `gmtime_r' function. */
|
||||||
#define HAVE_GMTIME_R 1
|
#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 to 1 if you have the <grp.h> header file. */
|
||||||
#define HAVE_GRP_H 1
|
#define HAVE_GRP_H 1
|
||||||
|
|
||||||
|
@ -206,6 +206,9 @@
|
|||||||
/* Define to 1 if you have the `gmtime_r' function. */
|
/* Define to 1 if you have the `gmtime_r' function. */
|
||||||
#define HAVE_GMTIME_R 1
|
#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 to 1 if you have the <grp.h> header file. */
|
||||||
#define HAVE_GRP_H 1
|
#define HAVE_GRP_H 1
|
||||||
|
|
||||||
|
@ -125,6 +125,7 @@ typedef void (*ErrorFunction) (const Firebird::Arg::StatusVector& v);
|
|||||||
typedef void (*FPTR_ERROR) (ISC_STATUS, ...);
|
typedef void (*FPTR_ERROR) (ISC_STATUS, ...);
|
||||||
|
|
||||||
typedef ULONG RCRD_OFFSET;
|
typedef ULONG RCRD_OFFSET;
|
||||||
|
typedef ULONG RCRD_LENGTH;
|
||||||
typedef USHORT FLD_LENGTH;
|
typedef USHORT FLD_LENGTH;
|
||||||
/* CVC: internal usage. I suspect the only reason to return int is that
|
/* 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,
|
vmslock.cpp:LOCK_convert() calls VMS' sys$enq that may require this signature,
|
||||||
|
@ -31,7 +31,6 @@ typedef ISC_QUAD;
|
|||||||
typedef ISC_TIME;
|
typedef ISC_TIME;
|
||||||
typedef FB_DEC16;
|
typedef FB_DEC16;
|
||||||
typedef FB_DEC34;
|
typedef FB_DEC34;
|
||||||
typedef FB_DEC_FIXED;
|
|
||||||
|
|
||||||
// Versioned interface - base for all FB interfaces
|
// Versioned interface - base for all FB interfaces
|
||||||
interface Versioned
|
interface Versioned
|
||||||
@ -214,6 +213,10 @@ interface PluginFactory : Versioned
|
|||||||
interface PluginModule : Versioned
|
interface PluginModule : Versioned
|
||||||
{
|
{
|
||||||
void doClean();
|
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
|
// Interface to deal with plugins here and there, returned by master interface
|
||||||
@ -514,15 +517,15 @@ interface Pipe : ReferenceCounted
|
|||||||
interface Request : ReferenceCounted
|
interface Request : ReferenceCounted
|
||||||
{
|
{
|
||||||
void receive(Status status, int level, uint msgType,
|
void receive(Status status, int level, uint msgType,
|
||||||
uint length, uchar* message);
|
uint length, void* message);
|
||||||
void send(Status status, int level, uint msgType,
|
void send(Status status, int level, uint msgType,
|
||||||
uint length, const uchar* message);
|
uint length, const void* message);
|
||||||
void getInfo(Status status, int level,
|
void getInfo(Status status, int level,
|
||||||
uint itemsLength, const uchar* items,
|
uint itemsLength, const uchar* items,
|
||||||
uint bufferLength, uchar* buffer);
|
uint bufferLength, uchar* buffer);
|
||||||
void start(Status status, Transaction tra, int level);
|
void start(Status status, Transaction tra, int level);
|
||||||
void startAndSend(Status status, Transaction tra, int level, uint msgType,
|
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 unwind(Status status, int level);
|
||||||
void free(Status status);
|
void free(Status status);
|
||||||
}
|
}
|
||||||
@ -599,6 +602,7 @@ version: // 3.0 => 4.0
|
|||||||
// Batch API
|
// Batch API
|
||||||
Batch createBatch(Status status, Transaction transaction, uint stmtLength, const string sqlStmt,
|
Batch createBatch(Status status, Transaction transaction, uint stmtLength, const string sqlStmt,
|
||||||
uint dialect, MessageMetadata inMetadata, uint parLength, const uchar* par);
|
uint dialect, MessageMetadata inMetadata, uint parLength, const uchar* par);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Pipe createPipe(Status status, uint stmtLength, const string sqlStmt, uint dialect,
|
Pipe createPipe(Status status, uint stmtLength, const string sqlStmt, uint dialect,
|
||||||
Transaction transaction, MessageMetadata inMetadata, void* inBuffer,
|
Transaction transaction, MessageMetadata inMetadata, void* inBuffer,
|
||||||
@ -1061,7 +1065,6 @@ version: // 3.0 => 4.0
|
|||||||
EventBlock createEventBlock(Status status, const string* events);
|
EventBlock createEventBlock(Status status, const string* events);
|
||||||
DecFloat16 getDecFloat16(Status status);
|
DecFloat16 getDecFloat16(Status status);
|
||||||
DecFloat34 getDecFloat34(Status status);
|
DecFloat34 getDecFloat34(Status status);
|
||||||
DecFixed getDecFixed(Status status);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface OffsetsCallback : Versioned
|
interface OffsetsCallback : Versioned
|
||||||
@ -1467,13 +1470,3 @@ interface DecFloat34 : Versioned
|
|||||||
void fromBcd(int sign, const uchar* bcd, int exp, FB_DEC34* to);
|
void fromBcd(int sign, const uchar* bcd, int exp, FB_DEC34* to);
|
||||||
void fromString(Status status, const string from, 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 IUdrPlugin;
|
||||||
class IDecFloat16;
|
class IDecFloat16;
|
||||||
class IDecFloat34;
|
class IDecFloat34;
|
||||||
class IDecFixed;
|
|
||||||
|
|
||||||
// Interfaces declarations
|
// Interfaces declarations
|
||||||
|
|
||||||
@ -737,6 +736,7 @@ namespace Firebird
|
|||||||
struct VTable : public IVersioned::VTable
|
struct VTable : public IVersioned::VTable
|
||||||
{
|
{
|
||||||
void (CLOOP_CARG *doClean)(IPluginModule* self) throw();
|
void (CLOOP_CARG *doClean)(IPluginModule* self) throw();
|
||||||
|
void (CLOOP_CARG *threadDetach)(IPluginModule* self) throw();
|
||||||
};
|
};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -750,12 +750,21 @@ namespace Firebird
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static const unsigned VERSION = 2;
|
static const unsigned VERSION = 3;
|
||||||
|
|
||||||
void doClean()
|
void doClean()
|
||||||
{
|
{
|
||||||
static_cast<VTable*>(this->cloopVTable)->doClean(this);
|
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
|
class IPluginManager : public IVersioned
|
||||||
@ -1931,11 +1940,11 @@ namespace Firebird
|
|||||||
public:
|
public:
|
||||||
struct VTable : public IReferenceCounted::VTable
|
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 *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 unsigned char* 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 *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 *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 *unwind)(IRequest* self, IStatus* status, int level) throw();
|
||||||
void (CLOOP_CARG *free)(IRequest* self, IStatus* status) throw();
|
void (CLOOP_CARG *free)(IRequest* self, IStatus* status) throw();
|
||||||
};
|
};
|
||||||
@ -1953,14 +1962,14 @@ namespace Firebird
|
|||||||
public:
|
public:
|
||||||
static const unsigned VERSION = 3;
|
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);
|
StatusType::clearException(status);
|
||||||
static_cast<VTable*>(this->cloopVTable)->receive(this, status, level, msgType, length, message);
|
static_cast<VTable*>(this->cloopVTable)->receive(this, status, level, msgType, length, message);
|
||||||
StatusType::checkException(status);
|
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);
|
StatusType::clearException(status);
|
||||||
static_cast<VTable*>(this->cloopVTable)->send(this, status, level, msgType, length, message);
|
static_cast<VTable*>(this->cloopVTable)->send(this, status, level, msgType, length, message);
|
||||||
@ -1981,7 +1990,7 @@ namespace Firebird
|
|||||||
StatusType::checkException(status);
|
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);
|
StatusType::clearException(status);
|
||||||
static_cast<VTable*>(this->cloopVTable)->startAndSend(this, status, tra, level, msgType, length, message);
|
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();
|
IEventBlock* (CLOOP_CARG *createEventBlock)(IUtil* self, IStatus* status, const char** events) throw();
|
||||||
IDecFloat16* (CLOOP_CARG *getDecFloat16)(IUtil* self, IStatus* status) throw();
|
IDecFloat16* (CLOOP_CARG *getDecFloat16)(IUtil* self, IStatus* status) throw();
|
||||||
IDecFloat34* (CLOOP_CARG *getDecFloat34)(IUtil* self, IStatus* status) throw();
|
IDecFloat34* (CLOOP_CARG *getDecFloat34)(IUtil* self, IStatus* status) throw();
|
||||||
IDecFixed* (CLOOP_CARG *getDecFixed)(IUtil* self, IStatus* status) throw();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -4081,20 +4089,6 @@ namespace Firebird
|
|||||||
StatusType::checkException(status);
|
StatusType::checkException(status);
|
||||||
return ret;
|
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
|
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
|
// Interfaces implementations
|
||||||
|
|
||||||
template <typename Name, typename StatusType, typename Base>
|
template <typename Name, typename StatusType, typename Base>
|
||||||
@ -7072,6 +7014,7 @@ namespace Firebird
|
|||||||
{
|
{
|
||||||
this->version = Base::VERSION;
|
this->version = Base::VERSION;
|
||||||
this->doClean = &Name::cloopdoCleanDispatcher;
|
this->doClean = &Name::cloopdoCleanDispatcher;
|
||||||
|
this->threadDetach = &Name::cloopthreadDetachDispatcher;
|
||||||
}
|
}
|
||||||
} vTable;
|
} vTable;
|
||||||
|
|
||||||
@ -7089,6 +7032,18 @@ namespace Firebird
|
|||||||
StatusType::catchException(0);
|
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> > >
|
template <typename Name, typename StatusType, typename Base = IVersionedImpl<Name, StatusType, Inherit<IPluginModule> > >
|
||||||
@ -7105,6 +7060,7 @@ namespace Firebird
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void doClean() = 0;
|
virtual void doClean() = 0;
|
||||||
|
virtual void threadDetach() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Name, typename StatusType, typename Base>
|
template <typename Name, typename StatusType, typename Base>
|
||||||
@ -9401,7 +9357,7 @@ namespace Firebird
|
|||||||
this->cloopVTable = &vTable;
|
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);
|
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);
|
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);
|
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 receive(StatusType* status, int level, unsigned msgType, unsigned length, void* message) = 0;
|
||||||
virtual void send(StatusType* status, int level, unsigned msgType, unsigned length, const unsigned char* 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 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 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 unwind(StatusType* status, int level) = 0;
|
||||||
virtual void free(StatusType* status) = 0;
|
virtual void free(StatusType* status) = 0;
|
||||||
};
|
};
|
||||||
@ -13809,7 +13765,6 @@ namespace Firebird
|
|||||||
this->createEventBlock = &Name::cloopcreateEventBlockDispatcher;
|
this->createEventBlock = &Name::cloopcreateEventBlockDispatcher;
|
||||||
this->getDecFloat16 = &Name::cloopgetDecFloat16Dispatcher;
|
this->getDecFloat16 = &Name::cloopgetDecFloat16Dispatcher;
|
||||||
this->getDecFloat34 = &Name::cloopgetDecFloat34Dispatcher;
|
this->getDecFloat34 = &Name::cloopgetDecFloat34Dispatcher;
|
||||||
this->getDecFixed = &Name::cloopgetDecFixedDispatcher;
|
|
||||||
}
|
}
|
||||||
} vTable;
|
} vTable;
|
||||||
|
|
||||||
@ -14037,21 +13992,6 @@ namespace Firebird
|
|||||||
return static_cast<IDecFloat34*>(0);
|
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> > >
|
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 IEventBlock* createEventBlock(StatusType* status, const char** events) = 0;
|
||||||
virtual IDecFloat16* getDecFloat16(StatusType* status) = 0;
|
virtual IDecFloat16* getDecFloat16(StatusType* status) = 0;
|
||||||
virtual IDecFloat34* getDecFloat34(StatusType* status) = 0;
|
virtual IDecFloat34* getDecFloat34(StatusType* status) = 0;
|
||||||
virtual IDecFixed* getDecFixed(StatusType* status) = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Name, typename StatusType, typename Base>
|
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 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;
|
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->setType(status, index, SQL_DEC34); \
|
||||||
builder->setLength(status, index, sizeof(FB_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 \
|
#define FB__META_FB_BLOB \
|
||||||
builder->setType(status, index, SQL_BLOB); \
|
builder->setType(status, index, SQL_BLOB); \
|
||||||
builder->setLength(status, index, sizeof(ISC_QUAD));
|
builder->setLength(status, index, sizeof(ISC_QUAD));
|
||||||
@ -200,7 +195,6 @@
|
|||||||
#define FB__TYPE_FB_DOUBLE double
|
#define FB__TYPE_FB_DOUBLE double
|
||||||
#define FB__TYPE_FB_DECFLOAT16 FB_DEC16
|
#define FB__TYPE_FB_DECFLOAT16 FB_DEC16
|
||||||
#define FB__TYPE_FB_DECFLOAT34 FB_DEC34
|
#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_BLOB ISC_QUAD
|
||||||
#define FB__TYPE_FB_BOOLEAN ISC_UCHAR
|
#define FB__TYPE_FB_BOOLEAN ISC_UCHAR
|
||||||
#define FB__TYPE_FB_DATE ::Firebird::FbDate
|
#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