Compare commits
59 Commits
Author | SHA1 | Date |
---|---|---|
Tomasz Sowa | e46c090b41 | |
Tomasz Sowa | cd067ae5c3 | |
Tomasz Sowa | 90b4d9af0b | |
Tomasz Sowa | 6fb7e29867 | |
Tomasz Sowa | 9a3f6a6e36 | |
Tomasz Sowa | e026af9994 | |
Tomasz Sowa | 92d9d2c01b | |
Tomasz Sowa | 8200092524 | |
Tomasz Sowa | 21f12a8a98 | |
Tomasz Sowa | 6619f3ecb5 | |
Tomasz Sowa | e7c62e35dc | |
Tomasz Sowa | 25a91168ac | |
Tomasz Sowa | 86177889af | |
Tomasz Sowa | d61fc31b5c | |
Tomasz Sowa | c56bae57ca | |
Tomasz Sowa | 1821c562f7 | |
Tomasz Sowa | dee48ea2b5 | |
Tomasz Sowa | cf377204a9 | |
Tomasz Sowa | 0fbd988eda | |
Tomasz Sowa | d1c86c84cf | |
Tomasz Sowa | 794051fa15 | |
Tomasz Sowa | a3c337355d | |
Tomasz Sowa | a4a1acebeb | |
Tomasz Sowa | dfc631dd06 | |
Tomasz Sowa | 2ac8769d3a | |
Tomasz Sowa | 7f4deaf847 | |
Tomasz Sowa | 0ce05850b3 | |
Tomasz Sowa | 38e790c2ac | |
Tomasz Sowa | bc92654be9 | |
Tomasz Sowa | c54a5bed05 | |
Tomasz Sowa | 8373f9e9d8 | |
Tomasz Sowa | 43dfbd5d5a | |
Tomasz Sowa | 4e8f3af8fc | |
Tomasz Sowa | 128f43482a | |
Tomasz Sowa | 3ddeb78c97 | |
Tomasz Sowa | ea6f9fd13e | |
Tomasz Sowa | 1ad3d89d52 | |
Tomasz Sowa | 576d537177 | |
Tomasz Sowa | c89d4f76bc | |
Tomasz Sowa | fc50c8ca5e | |
Tomasz Sowa | 1ace47266d | |
Tomasz Sowa | 21117e24c0 | |
Tomasz Sowa | dd04ee84b7 | |
Tomasz Sowa | 1d4de8abe2 | |
Tomasz Sowa | 907f10671d | |
Tomasz Sowa | c5cf4a2672 | |
Tomasz Sowa | b32917afe7 | |
Tomasz Sowa | 0ce7578de3 | |
Tomasz Sowa | 12232bf722 | |
Tomasz Sowa | 1ad4cb4fbd | |
Tomasz Sowa | 56cbebad4f | |
Tomasz Sowa | 3bde64e033 | |
Tomasz Sowa | df44296c04 | |
Tomasz Sowa | 469294502e | |
Tomasz Sowa | d384929e75 | |
Tomasz Sowa | ac77abb8fd | |
Tomasz Sowa | 0bdabfc7b4 | |
Tomasz Sowa | 48d515ea64 | |
Tomasz Sowa | c25a5d2215 |
|
@ -6,3 +6,12 @@
|
||||||
log.txt
|
log.txt
|
||||||
samples/log.txt
|
samples/log.txt
|
||||||
samples/mormsample
|
samples/mormsample
|
||||||
|
.clangd
|
||||||
|
.qtc_clangd/
|
||||||
|
morm.cflags
|
||||||
|
morm.config
|
||||||
|
morm.creator
|
||||||
|
morm.creator.user
|
||||||
|
morm.cxxflags
|
||||||
|
morm.files
|
||||||
|
morm.includes
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
Copyright (c) 2018-2022, Tomasz Sowa
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE.
|
|
@ -0,0 +1,42 @@
|
||||||
|
|
||||||
|
|
||||||
|
export CXX
|
||||||
|
export CXXFLAGS
|
||||||
|
export AR
|
||||||
|
|
||||||
|
|
||||||
|
all: src
|
||||||
|
|
||||||
|
|
||||||
|
src: FORCE
|
||||||
|
$(MAKE) -C src
|
||||||
|
|
||||||
|
|
||||||
|
samples: FORCE
|
||||||
|
$(MAKE) -C src
|
||||||
|
$(MAKE) -C samples
|
||||||
|
|
||||||
|
|
||||||
|
samples-gcc11: FORCE
|
||||||
|
env CXX=g++11 CXXFLAGS="-Wl,-rpath=/usr/local/lib/gcc11/ -Wall -pedantic -O0 -g -std=c++20 -fmax-errors=1 -I../src -I../../pikotools/src -I/usr/local/include" $(MAKE) -C src
|
||||||
|
env CXX=g++11 CXXFLAGS="-Wl,-rpath=/usr/local/lib/gcc11/ -Wall -pedantic -O0 -g -std=c++20 -fmax-errors=1 -I../src -I../../pikotools/src -I/usr/local/include" $(MAKE) -C samples
|
||||||
|
|
||||||
|
|
||||||
|
clean: FORCE
|
||||||
|
$(MAKE) -C src clean
|
||||||
|
$(MAKE) -C samples clean
|
||||||
|
|
||||||
|
|
||||||
|
cleanall: clean
|
||||||
|
$(MAKE) -C ../pikotools clean
|
||||||
|
|
||||||
|
|
||||||
|
depend: FORCE
|
||||||
|
$(MAKE) -C src depend
|
||||||
|
$(MAKE) -C samples depend
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
FORCE:
|
||||||
|
|
|
@ -1,68 +1,57 @@
|
||||||
include Makefile.o.dep
|
sourcefiles:=$(shell find . -name "*.cpp")
|
||||||
|
objfiles:=$(patsubst %.cpp,%.o,$(sourcefiles))
|
||||||
|
|
||||||
name=mormsample
|
|
||||||
|
|
||||||
ifndef GLOBAL_WORKING_DIR
|
|
||||||
GLOBAL_WORKING_DIR := $(shell pwd)/../..
|
ifndef CXX
|
||||||
|
CXX = g++
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifndef CXXFLAGS
|
||||||
|
CXXFLAGS = -Wall -pedantic -O2 -std=c++20 -I../src -I../../pikotools/src -I/usr/local/include
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifndef LDFLAGS
|
||||||
|
LDFLAGS = -L/usr/local/lib
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
CXX = g++10
|
name = mormsample
|
||||||
#CXX = clang++
|
|
||||||
|
|
||||||
# -fsanitize=address
|
|
||||||
# -Wl,-rpath=/usr/local/lib/gcc5 or just compile with -static-libstdc++
|
|
||||||
|
|
||||||
CXXFLAGS = -Wl,-rpath=/usr/local/lib/gcc10 -Wfatal-errors -fPIC -Wall -pedantic -O0 -g3 -pthread -std=c++20 -I/usr/local/include -I$(GLOBAL_WORKING_DIR)/pikotools/src -I$(GLOBAL_WORKING_DIR)/morm/src
|
|
||||||
LDFLAGS = -L/usr/local/lib
|
|
||||||
|
|
||||||
|
|
||||||
export CXX
|
all: $(name)
|
||||||
export CXXFLAGS
|
|
||||||
export LDFLAGS
|
|
||||||
export GLOBAL_WORKING_DIR
|
|
||||||
|
|
||||||
|
|
||||||
current_path := $(shell pwd)
|
$(name): morm pikotools $(objfiles)
|
||||||
global_relative_working_dir := $(shell relative_path $(current_path) $(GLOBAL_WORKING_DIR))
|
$(CXX) -o $(name) $(CXXFLAGS) $(LDFLAGS) $(objfiles) ../src/morm.a ../../pikotools/src/pikotools.a $(LDFLAGS) -lpq -lpthread
|
||||||
|
|
||||||
|
|
||||||
# IMPROVE ME
|
|
||||||
# add dependency to pikotools
|
morm: FORCE
|
||||||
all: morm $(name)
|
@cd ../src ; $(MAKE) -e
|
||||||
|
|
||||||
|
|
||||||
$(name): morm pikotools $(o)
|
pikotools: FORCE
|
||||||
$(CXX) -o $(name) $(CXXFLAGS) $(LDFLAGS) $(o) $(GLOBAL_WORKING_DIR)/morm/src/morm.a $(GLOBAL_WORKING_DIR)/pikotools/src/pikotools.a $(LDFLAGS) -lpq -lpthread
|
@cd ../../pikotools/src ; $(MAKE) -e
|
||||||
|
|
||||||
|
|
||||||
.PHONY: morm
|
|
||||||
|
|
||||||
|
|
||||||
morm:
|
|
||||||
@cd $(GLOBAL_WORKING_DIR)/morm/src ; $(MAKE) -e
|
|
||||||
|
|
||||||
|
|
||||||
pikotools:
|
|
||||||
@cd $(GLOBAL_WORKING_DIR)/pikotools/src ; $(MAKE) -e
|
|
||||||
|
|
||||||
|
|
||||||
%.o: %.cpp
|
%.o: %.cpp
|
||||||
$(CXX) -c $(CXXFLAGS) $<
|
$(CXX) -c $(CXXFLAGS) -o $@ $<
|
||||||
|
|
||||||
|
|
||||||
depend:
|
|
||||||
makedepend -Y. -I$(global_relative_working_dir)/pikotools/src -I$(global_relative_working_dir)/morm/src -f- *.cpp > Makefile.dep
|
|
||||||
echo -n "o = " > Makefile.o.dep
|
|
||||||
ls -1 *.cpp | xargs -I foo echo -n foo " " | sed -E "s/([^\.]*)\.cpp[ ]/\1\.o/g" >> Makefile.o.dep
|
|
||||||
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
@cd $(GLOBAL_WORKING_DIR)/morm/src ; $(MAKE) -e clean
|
rm -f $(objfiles)
|
||||||
rm -f *.o
|
|
||||||
rm -f $(name)
|
rm -f $(name)
|
||||||
|
|
||||||
|
|
||||||
|
depend:
|
||||||
|
makedepend -Y. -I../src -I../../pikotools/src -f- $(sourcefiles) > Makefile.dep
|
||||||
|
|
||||||
|
|
||||||
include Makefile.dep
|
FORCE:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-include Makefile.dep
|
||||||
|
|
||||||
|
|
|
@ -1,17 +1,29 @@
|
||||||
# DO NOT DELETE
|
# DO NOT DELETE
|
||||||
|
|
||||||
main.o: sample01.h basesample.h ../../morm/src/morm.h
|
./main.o: ../../pikotools/src/mainoptions/mainoptionsparser.h
|
||||||
main.o: ../../morm/src/morm_types.h ../../morm/src/model.h
|
./main.o: ../../pikotools/src/space/space.h
|
||||||
main.o: ../../morm/src/modelconnector.h ../../morm/src/clearer.h
|
./main.o: ../../pikotools/src/convert/inttostr.h
|
||||||
main.o: ../../morm/src/dbconnector.h ../../morm/src/queryresult.h
|
./main.o: ../../pikotools/src/utf8/utf8.h
|
||||||
main.o: ../../morm/src/ft.h ../../morm/src/flatconnector.h
|
./main.o: ../../pikotools/src/textstream/stream.h sample01.h basesample.h
|
||||||
main.o: ../../morm/src/dbexpression.h ../../morm/src/baseexpression.h
|
./main.o: ../src/morm.h ../src/version.h ../src/morm_types.h ../src/model.h
|
||||||
main.o: ../../morm/src/modelenv.h ../../morm/src/modeldata.h
|
./main.o: ../../pikotools/src/textstream/textstream.h
|
||||||
main.o: ../../morm/src/cursorhelper.h ../../morm/src/finderhelper.h
|
./main.o: ../../pikotools/src/textstream/stream.h
|
||||||
main.o: ../../morm/src/fieldvaluehelper.h ../../morm/src/flatexpression.h
|
./main.o: ../../pikotools/src/date/date.h
|
||||||
main.o: ../../morm/src/modelwrapper.h ../../morm/src/finder.h
|
./main.o: ../../pikotools/src/membuffer/membuffer.h
|
||||||
main.o: ../../morm/src/cursor.h ../../morm/src/jsonexpression.h
|
./main.o: ../../pikotools/src/textstream/types.h
|
||||||
main.o: ../../morm/src/postgresqlexpression.h ../../morm/src/jsonconnector.h
|
./main.o: ../../pikotools/src/textstream/stream_private.h
|
||||||
main.o: ../../morm/src/postgresqlconnector.h
|
./main.o: ../src/modelconnector.h ../src/clearer.h ../src/ft.h
|
||||||
main.o: ../../morm/src/postgresqlqueryresult.h person.h language.h
|
./main.o: ../src/dbconnector.h ../../pikotools/src/log/log.h
|
||||||
main.o: attachment.h type.h attachment2.h
|
./main.o: ../../pikotools/src/log/filelog.h ../src/queryresult.h
|
||||||
|
./main.o: ../src/flatconnector.h ../src/export.h ../src/dbexpression.h
|
||||||
|
./main.o: ../src/baseexpression.h ../src/modelenv.h ../src/modeldata.h
|
||||||
|
./main.o: ../src/cursorhelper.h ../src/finderhelper.h
|
||||||
|
./main.o: ../src/fieldvaluehelper.h ../src/wrapper.h ../src/spacewrapper.h
|
||||||
|
./main.o: ../src/baseobjectwrapper.h ../src/modelcontainerwrapper.h
|
||||||
|
./main.o: ../src/select.h ../src/flatexpression.h ../src/finder.h
|
||||||
|
./main.o: ../src/cursor.h ../src/jsonexpression.h
|
||||||
|
./main.o: ../src/postgresqlexpression.h ../src/xmlexpression.h
|
||||||
|
./main.o: ../src/jsonconnector.h ../src/postgresqlconnector.h
|
||||||
|
./main.o: ../src/postgresqlqueryresult.h ../src/xmlconnector.h
|
||||||
|
./main.o: ../src/transaction.h person.h language.h attachment.h type.h
|
||||||
|
./main.o: attachment2.h
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
o = main.o
|
|
43
src/Makefile
43
src/Makefile
|
@ -1,36 +1,45 @@
|
||||||
include Makefile.o.dep
|
sourcefiles:=$(shell find . -name "*.cpp")
|
||||||
|
objfiles:=$(patsubst %.cpp,%.o,$(sourcefiles))
|
||||||
|
|
||||||
libname=morm.a
|
|
||||||
|
|
||||||
ifndef GLOBAL_WORKING_DIR
|
|
||||||
GLOBAL_WORKING_DIR := $(shell pwd)/../..
|
ifndef CXX
|
||||||
|
CXX = g++
|
||||||
endif
|
endif
|
||||||
|
|
||||||
current_path := $(shell pwd)
|
ifndef CXXFLAGS
|
||||||
global_relative_working_dir := $(shell relative_path $(current_path) $(GLOBAL_WORKING_DIR))
|
CXXFLAGS = -Wall -pedantic -O2 -std=c++20 -I../../pikotools/src -I/usr/local/include
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifndef AR
|
||||||
|
AR = ar
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
libname = morm.a
|
||||||
|
|
||||||
|
|
||||||
all: $(libname)
|
all: $(libname)
|
||||||
|
|
||||||
$(libname): $(o)
|
|
||||||
$(AR) rcs $(libname) $(o)
|
|
||||||
|
|
||||||
|
$(libname): $(objfiles)
|
||||||
|
$(AR) rcs $(libname) $(objfiles)
|
||||||
|
|
||||||
|
|
||||||
%.o: %.cpp
|
%.o: %.cpp
|
||||||
$(CXX) -c $(CXXFLAGS) -I$(GLOBAL_WORKING_DIR)/pikotools $<
|
$(CXX) -c $(CXXFLAGS) -o $@ $<
|
||||||
|
|
||||||
|
|
||||||
depend:
|
|
||||||
makedepend -Y. -I$(global_relative_working_dir)/pikotools -f- *.cpp > Makefile.dep
|
|
||||||
echo -n "o = " > Makefile.o.dep
|
|
||||||
ls -1 *.cpp | xargs -I foo echo -n foo " " | sed -E "s/([^\.]*)\.cpp[ ]/\1\.o/g" >> Makefile.o.dep
|
|
||||||
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *.o
|
rm -f $(objfiles)
|
||||||
rm -f $(libname)
|
rm -f $(libname)
|
||||||
|
|
||||||
|
|
||||||
include Makefile.dep
|
depend:
|
||||||
|
makedepend -Y. -I../../pikotools/src -f- $(sourcefiles) > Makefile.dep
|
||||||
|
|
||||||
|
|
||||||
|
-include Makefile.dep
|
||||||
|
|
||||||
|
|
371
src/Makefile.dep
371
src/Makefile.dep
|
@ -1,54 +1,321 @@
|
||||||
# DO NOT DELETE
|
# DO NOT DELETE
|
||||||
|
|
||||||
baseexpression.o: baseexpression.h morm_types.h modelenv.h modeldata.h
|
./baseexpression.o: baseexpression.h ../../pikotools/src/textstream/stream.h
|
||||||
baseexpression.o: cursorhelper.h queryresult.h finderhelper.h
|
./baseexpression.o: ../../pikotools/src/date/date.h
|
||||||
baseexpression.o: fieldvaluehelper.h ft.h model.h modelconnector.h clearer.h
|
./baseexpression.o: ../../pikotools/src/convert/inttostr.h morm_types.h
|
||||||
baseexpression.o: dbconnector.h flatconnector.h dbexpression.h
|
./baseexpression.o: modelenv.h modeldata.h cursorhelper.h queryresult.h
|
||||||
baseexpression.o: flatexpression.h modelcontainerwrapper.h
|
./baseexpression.o: ../../pikotools/src/log/log.h
|
||||||
baseexpression.o: baseobjectwrapper.h spacewrapper.h
|
./baseexpression.o: ../../pikotools/src/textstream/textstream.h
|
||||||
clearer.o: clearer.h model.h modelconnector.h dbconnector.h queryresult.h
|
./baseexpression.o: ../../pikotools/src/textstream/stream.h
|
||||||
clearer.o: ft.h flatconnector.h dbexpression.h baseexpression.h morm_types.h
|
./baseexpression.o: ../../pikotools/src/space/space.h
|
||||||
clearer.o: modelenv.h modeldata.h cursorhelper.h finderhelper.h
|
./baseexpression.o: ../../pikotools/src/utf8/utf8.h
|
||||||
clearer.o: fieldvaluehelper.h flatexpression.h modelcontainerwrapper.h
|
./baseexpression.o: ../../pikotools/src/membuffer/membuffer.h
|
||||||
clearer.o: baseobjectwrapper.h spacewrapper.h
|
./baseexpression.o: ../../pikotools/src/textstream/types.h
|
||||||
dbconnector.o: dbconnector.h queryresult.h ft.h dbexpression.h
|
./baseexpression.o: ../../pikotools/src/textstream/stream_private.h
|
||||||
dbconnector.o: baseexpression.h morm_types.h modelenv.h modeldata.h
|
./baseexpression.o: ../../pikotools/src/log/filelog.h finderhelper.h
|
||||||
dbconnector.o: cursorhelper.h finderhelper.h fieldvaluehelper.h model.h
|
./baseexpression.o: fieldvaluehelper.h wrapper.h spacewrapper.h
|
||||||
dbconnector.o: modelconnector.h clearer.h flatconnector.h flatexpression.h
|
./baseexpression.o: baseobjectwrapper.h modelcontainerwrapper.h select.h ft.h
|
||||||
dbconnector.o: modelcontainerwrapper.h baseobjectwrapper.h spacewrapper.h
|
./baseexpression.o: model.h modelconnector.h clearer.h dbconnector.h
|
||||||
dbexpression.o: dbexpression.h baseexpression.h morm_types.h modelenv.h
|
./baseexpression.o: flatconnector.h export.h dbexpression.h flatexpression.h
|
||||||
dbexpression.o: modeldata.h cursorhelper.h queryresult.h finderhelper.h
|
./clearer.o: clearer.h ../../pikotools/src/date/date.h
|
||||||
dbexpression.o: fieldvaluehelper.h ft.h
|
./clearer.o: ../../pikotools/src/convert/inttostr.h
|
||||||
flatconnector.o: flatconnector.h flatexpression.h baseexpression.h
|
./clearer.o: ../../pikotools/src/space/space.h
|
||||||
flatconnector.o: morm_types.h modelenv.h modeldata.h cursorhelper.h
|
./clearer.o: ../../pikotools/src/utf8/utf8.h
|
||||||
flatconnector.o: queryresult.h finderhelper.h fieldvaluehelper.h ft.h model.h
|
./clearer.o: ../../pikotools/src/textstream/stream.h ft.h model.h
|
||||||
flatconnector.o: modelconnector.h clearer.h dbconnector.h dbexpression.h
|
./clearer.o: ../../pikotools/src/textstream/textstream.h
|
||||||
flatconnector.o: modelcontainerwrapper.h baseobjectwrapper.h spacewrapper.h
|
./clearer.o: ../../pikotools/src/textstream/stream.h
|
||||||
flatexpression.o: flatexpression.h baseexpression.h morm_types.h modelenv.h
|
./clearer.o: ../../pikotools/src/membuffer/membuffer.h
|
||||||
flatexpression.o: modeldata.h cursorhelper.h queryresult.h finderhelper.h
|
./clearer.o: ../../pikotools/src/textstream/types.h
|
||||||
flatexpression.o: fieldvaluehelper.h ft.h
|
./clearer.o: ../../pikotools/src/textstream/stream_private.h modelconnector.h
|
||||||
jsonconnector.o: jsonconnector.h flatconnector.h jsonexpression.h
|
./clearer.o: dbconnector.h ../../pikotools/src/log/log.h
|
||||||
jsonconnector.o: flatexpression.h baseexpression.h morm_types.h modelenv.h
|
./clearer.o: ../../pikotools/src/log/filelog.h queryresult.h flatconnector.h
|
||||||
jsonconnector.o: modeldata.h cursorhelper.h queryresult.h finderhelper.h
|
./clearer.o: export.h dbexpression.h baseexpression.h morm_types.h modelenv.h
|
||||||
jsonconnector.o: fieldvaluehelper.h ft.h
|
./clearer.o: modeldata.h cursorhelper.h finderhelper.h fieldvaluehelper.h
|
||||||
jsonexpression.o: jsonexpression.h flatexpression.h baseexpression.h
|
./clearer.o: wrapper.h spacewrapper.h baseobjectwrapper.h
|
||||||
jsonexpression.o: morm_types.h modelenv.h modeldata.h cursorhelper.h
|
./clearer.o: modelcontainerwrapper.h select.h flatexpression.h
|
||||||
jsonexpression.o: queryresult.h finderhelper.h fieldvaluehelper.h ft.h
|
./dbconnector.o: ../../pikotools/src/space/spaceparser.h
|
||||||
model.o: model.h modelconnector.h clearer.h dbconnector.h queryresult.h ft.h
|
./dbconnector.o: ../../pikotools/src/space/space.h
|
||||||
model.o: flatconnector.h dbexpression.h baseexpression.h morm_types.h
|
./dbconnector.o: ../../pikotools/src/convert/inttostr.h
|
||||||
model.o: modelenv.h modeldata.h cursorhelper.h finderhelper.h
|
./dbconnector.o: ../../pikotools/src/utf8/utf8.h
|
||||||
model.o: fieldvaluehelper.h flatexpression.h modelcontainerwrapper.h
|
./dbconnector.o: ../../pikotools/src/textstream/stream.h
|
||||||
model.o: baseobjectwrapper.h spacewrapper.h
|
./dbconnector.o: ../../pikotools/src/convert/baseparser.h
|
||||||
modelconnector.o: modelconnector.h clearer.h dbconnector.h queryresult.h ft.h
|
./dbconnector.o: ../../pikotools/src/textstream/textstream.h
|
||||||
modelconnector.o: flatconnector.h
|
./dbconnector.o: ../../pikotools/src/textstream/stream.h
|
||||||
postgresqlconnector.o: postgresqlconnector.h dbconnector.h queryresult.h ft.h
|
./dbconnector.o: ../../pikotools/src/space/space.h
|
||||||
postgresqlconnector.o: postgresqlqueryresult.h postgresqlexpression.h
|
./dbconnector.o: ../../pikotools/src/date/date.h
|
||||||
postgresqlconnector.o: dbexpression.h baseexpression.h morm_types.h
|
./dbconnector.o: ../../pikotools/src/membuffer/membuffer.h
|
||||||
postgresqlconnector.o: modelenv.h modeldata.h cursorhelper.h finderhelper.h
|
./dbconnector.o: ../../pikotools/src/textstream/types.h
|
||||||
postgresqlconnector.o: fieldvaluehelper.h
|
./dbconnector.o: ../../pikotools/src/textstream/stream_private.h
|
||||||
postgresqlexpression.o: postgresqlexpression.h dbexpression.h
|
./dbconnector.o: dbconnector.h ../../pikotools/src/log/log.h
|
||||||
postgresqlexpression.o: baseexpression.h morm_types.h modelenv.h modeldata.h
|
./dbconnector.o: ../../pikotools/src/log/filelog.h queryresult.h ft.h
|
||||||
postgresqlexpression.o: cursorhelper.h queryresult.h finderhelper.h
|
./dbconnector.o: dbexpression.h baseexpression.h morm_types.h modelenv.h
|
||||||
postgresqlexpression.o: fieldvaluehelper.h ft.h
|
./dbconnector.o: modeldata.h cursorhelper.h finderhelper.h fieldvaluehelper.h
|
||||||
postgresqlqueryresult.o: postgresqlqueryresult.h queryresult.h
|
./dbconnector.o: wrapper.h spacewrapper.h baseobjectwrapper.h
|
||||||
queryresult.o: queryresult.h
|
./dbconnector.o: modelcontainerwrapper.h select.h model.h modelconnector.h
|
||||||
|
./dbconnector.o: clearer.h flatconnector.h export.h flatexpression.h
|
||||||
|
./dbconnector.o: ../../pikotools/src/convert/convert.h
|
||||||
|
./dbconnector.o: ../../pikotools/src/convert/inttostr.h
|
||||||
|
./dbconnector.o: ../../pikotools/src/convert/patternreplacer.h
|
||||||
|
./dbconnector.o: ../../pikotools/src/convert/strtoint.h
|
||||||
|
./dbconnector.o: ../../pikotools/src/convert/text.h
|
||||||
|
./dbconnector.o: ../../pikotools/src/convert/misc.h
|
||||||
|
./dbconnector.o: ../../pikotools/src/convert/double.h
|
||||||
|
./dbexpression.o: dbexpression.h baseexpression.h
|
||||||
|
./dbexpression.o: ../../pikotools/src/textstream/stream.h
|
||||||
|
./dbexpression.o: ../../pikotools/src/date/date.h
|
||||||
|
./dbexpression.o: ../../pikotools/src/convert/inttostr.h morm_types.h
|
||||||
|
./dbexpression.o: modelenv.h modeldata.h cursorhelper.h queryresult.h
|
||||||
|
./dbexpression.o: ../../pikotools/src/log/log.h
|
||||||
|
./dbexpression.o: ../../pikotools/src/textstream/textstream.h
|
||||||
|
./dbexpression.o: ../../pikotools/src/textstream/stream.h
|
||||||
|
./dbexpression.o: ../../pikotools/src/space/space.h
|
||||||
|
./dbexpression.o: ../../pikotools/src/utf8/utf8.h
|
||||||
|
./dbexpression.o: ../../pikotools/src/membuffer/membuffer.h
|
||||||
|
./dbexpression.o: ../../pikotools/src/textstream/types.h
|
||||||
|
./dbexpression.o: ../../pikotools/src/textstream/stream_private.h
|
||||||
|
./dbexpression.o: ../../pikotools/src/log/filelog.h finderhelper.h
|
||||||
|
./dbexpression.o: fieldvaluehelper.h wrapper.h spacewrapper.h
|
||||||
|
./dbexpression.o: baseobjectwrapper.h modelcontainerwrapper.h select.h ft.h
|
||||||
|
./dbexpression.o: model.h modelconnector.h clearer.h dbconnector.h
|
||||||
|
./dbexpression.o: flatconnector.h export.h flatexpression.h
|
||||||
|
./flatconnector.o: flatconnector.h ../../pikotools/src/textstream/stream.h
|
||||||
|
./flatconnector.o: export.h flatexpression.h baseexpression.h
|
||||||
|
./flatconnector.o: ../../pikotools/src/date/date.h
|
||||||
|
./flatconnector.o: ../../pikotools/src/convert/inttostr.h morm_types.h
|
||||||
|
./flatconnector.o: modelenv.h modeldata.h cursorhelper.h queryresult.h
|
||||||
|
./flatconnector.o: ../../pikotools/src/log/log.h
|
||||||
|
./flatconnector.o: ../../pikotools/src/textstream/textstream.h
|
||||||
|
./flatconnector.o: ../../pikotools/src/textstream/stream.h
|
||||||
|
./flatconnector.o: ../../pikotools/src/space/space.h
|
||||||
|
./flatconnector.o: ../../pikotools/src/utf8/utf8.h
|
||||||
|
./flatconnector.o: ../../pikotools/src/membuffer/membuffer.h
|
||||||
|
./flatconnector.o: ../../pikotools/src/textstream/types.h
|
||||||
|
./flatconnector.o: ../../pikotools/src/textstream/stream_private.h
|
||||||
|
./flatconnector.o: ../../pikotools/src/log/filelog.h finderhelper.h
|
||||||
|
./flatconnector.o: fieldvaluehelper.h wrapper.h spacewrapper.h
|
||||||
|
./flatconnector.o: baseobjectwrapper.h modelcontainerwrapper.h select.h ft.h
|
||||||
|
./flatconnector.o: model.h modelconnector.h clearer.h dbconnector.h
|
||||||
|
./flatconnector.o: dbexpression.h
|
||||||
|
./flatexpression.o: flatexpression.h baseexpression.h
|
||||||
|
./flatexpression.o: ../../pikotools/src/textstream/stream.h
|
||||||
|
./flatexpression.o: ../../pikotools/src/date/date.h
|
||||||
|
./flatexpression.o: ../../pikotools/src/convert/inttostr.h morm_types.h
|
||||||
|
./flatexpression.o: modelenv.h modeldata.h cursorhelper.h queryresult.h
|
||||||
|
./flatexpression.o: ../../pikotools/src/log/log.h
|
||||||
|
./flatexpression.o: ../../pikotools/src/textstream/textstream.h
|
||||||
|
./flatexpression.o: ../../pikotools/src/textstream/stream.h
|
||||||
|
./flatexpression.o: ../../pikotools/src/space/space.h
|
||||||
|
./flatexpression.o: ../../pikotools/src/utf8/utf8.h
|
||||||
|
./flatexpression.o: ../../pikotools/src/membuffer/membuffer.h
|
||||||
|
./flatexpression.o: ../../pikotools/src/textstream/types.h
|
||||||
|
./flatexpression.o: ../../pikotools/src/textstream/stream_private.h
|
||||||
|
./flatexpression.o: ../../pikotools/src/log/filelog.h finderhelper.h
|
||||||
|
./flatexpression.o: fieldvaluehelper.h wrapper.h spacewrapper.h
|
||||||
|
./flatexpression.o: baseobjectwrapper.h modelcontainerwrapper.h select.h ft.h
|
||||||
|
./jsonconnector.o: jsonconnector.h flatconnector.h
|
||||||
|
./jsonconnector.o: ../../pikotools/src/textstream/stream.h export.h
|
||||||
|
./jsonconnector.o: jsonexpression.h flatexpression.h baseexpression.h
|
||||||
|
./jsonconnector.o: ../../pikotools/src/date/date.h
|
||||||
|
./jsonconnector.o: ../../pikotools/src/convert/inttostr.h morm_types.h
|
||||||
|
./jsonconnector.o: modelenv.h modeldata.h cursorhelper.h queryresult.h
|
||||||
|
./jsonconnector.o: ../../pikotools/src/log/log.h
|
||||||
|
./jsonconnector.o: ../../pikotools/src/textstream/textstream.h
|
||||||
|
./jsonconnector.o: ../../pikotools/src/textstream/stream.h
|
||||||
|
./jsonconnector.o: ../../pikotools/src/space/space.h
|
||||||
|
./jsonconnector.o: ../../pikotools/src/utf8/utf8.h
|
||||||
|
./jsonconnector.o: ../../pikotools/src/membuffer/membuffer.h
|
||||||
|
./jsonconnector.o: ../../pikotools/src/textstream/types.h
|
||||||
|
./jsonconnector.o: ../../pikotools/src/textstream/stream_private.h
|
||||||
|
./jsonconnector.o: ../../pikotools/src/log/filelog.h finderhelper.h
|
||||||
|
./jsonconnector.o: fieldvaluehelper.h wrapper.h spacewrapper.h
|
||||||
|
./jsonconnector.o: baseobjectwrapper.h modelcontainerwrapper.h select.h ft.h
|
||||||
|
./jsonexpression.o: jsonexpression.h flatexpression.h baseexpression.h
|
||||||
|
./jsonexpression.o: ../../pikotools/src/textstream/stream.h
|
||||||
|
./jsonexpression.o: ../../pikotools/src/date/date.h
|
||||||
|
./jsonexpression.o: ../../pikotools/src/convert/inttostr.h morm_types.h
|
||||||
|
./jsonexpression.o: modelenv.h modeldata.h cursorhelper.h queryresult.h
|
||||||
|
./jsonexpression.o: ../../pikotools/src/log/log.h
|
||||||
|
./jsonexpression.o: ../../pikotools/src/textstream/textstream.h
|
||||||
|
./jsonexpression.o: ../../pikotools/src/textstream/stream.h
|
||||||
|
./jsonexpression.o: ../../pikotools/src/space/space.h
|
||||||
|
./jsonexpression.o: ../../pikotools/src/utf8/utf8.h
|
||||||
|
./jsonexpression.o: ../../pikotools/src/membuffer/membuffer.h
|
||||||
|
./jsonexpression.o: ../../pikotools/src/textstream/types.h
|
||||||
|
./jsonexpression.o: ../../pikotools/src/textstream/stream_private.h
|
||||||
|
./jsonexpression.o: ../../pikotools/src/log/filelog.h finderhelper.h
|
||||||
|
./jsonexpression.o: fieldvaluehelper.h wrapper.h spacewrapper.h
|
||||||
|
./jsonexpression.o: baseobjectwrapper.h modelcontainerwrapper.h select.h ft.h
|
||||||
|
./jsonexpression.o: ../../pikotools/src/convert/misc.h
|
||||||
|
./model.o: model.h ../../pikotools/src/textstream/textstream.h
|
||||||
|
./model.o: ../../pikotools/src/textstream/stream.h
|
||||||
|
./model.o: ../../pikotools/src/space/space.h
|
||||||
|
./model.o: ../../pikotools/src/convert/inttostr.h
|
||||||
|
./model.o: ../../pikotools/src/utf8/utf8.h
|
||||||
|
./model.o: ../../pikotools/src/textstream/stream.h
|
||||||
|
./model.o: ../../pikotools/src/date/date.h
|
||||||
|
./model.o: ../../pikotools/src/membuffer/membuffer.h
|
||||||
|
./model.o: ../../pikotools/src/textstream/types.h
|
||||||
|
./model.o: ../../pikotools/src/textstream/stream_private.h modelconnector.h
|
||||||
|
./model.o: clearer.h ft.h dbconnector.h ../../pikotools/src/log/log.h
|
||||||
|
./model.o: ../../pikotools/src/log/filelog.h queryresult.h flatconnector.h
|
||||||
|
./model.o: export.h dbexpression.h baseexpression.h morm_types.h modelenv.h
|
||||||
|
./model.o: modeldata.h cursorhelper.h finderhelper.h fieldvaluehelper.h
|
||||||
|
./model.o: wrapper.h spacewrapper.h baseobjectwrapper.h
|
||||||
|
./model.o: modelcontainerwrapper.h select.h flatexpression.h
|
||||||
|
./model.o: ../../pikotools/src/convert/text.h
|
||||||
|
./modelconnector.o: modelconnector.h clearer.h
|
||||||
|
./modelconnector.o: ../../pikotools/src/date/date.h
|
||||||
|
./modelconnector.o: ../../pikotools/src/convert/inttostr.h
|
||||||
|
./modelconnector.o: ../../pikotools/src/space/space.h
|
||||||
|
./modelconnector.o: ../../pikotools/src/utf8/utf8.h
|
||||||
|
./modelconnector.o: ../../pikotools/src/textstream/stream.h ft.h
|
||||||
|
./modelconnector.o: dbconnector.h ../../pikotools/src/log/log.h
|
||||||
|
./modelconnector.o: ../../pikotools/src/textstream/textstream.h
|
||||||
|
./modelconnector.o: ../../pikotools/src/textstream/stream.h
|
||||||
|
./modelconnector.o: ../../pikotools/src/membuffer/membuffer.h
|
||||||
|
./modelconnector.o: ../../pikotools/src/textstream/types.h
|
||||||
|
./modelconnector.o: ../../pikotools/src/textstream/stream_private.h
|
||||||
|
./modelconnector.o: ../../pikotools/src/log/filelog.h queryresult.h
|
||||||
|
./modelconnector.o: flatconnector.h export.h
|
||||||
|
./postgresqlexpression.o: postgresqlexpression.h dbexpression.h
|
||||||
|
./postgresqlexpression.o: baseexpression.h
|
||||||
|
./postgresqlexpression.o: ../../pikotools/src/textstream/stream.h
|
||||||
|
./postgresqlexpression.o: ../../pikotools/src/date/date.h
|
||||||
|
./postgresqlexpression.o: ../../pikotools/src/convert/inttostr.h morm_types.h
|
||||||
|
./postgresqlexpression.o: modelenv.h modeldata.h cursorhelper.h queryresult.h
|
||||||
|
./postgresqlexpression.o: ../../pikotools/src/log/log.h
|
||||||
|
./postgresqlexpression.o: ../../pikotools/src/textstream/textstream.h
|
||||||
|
./postgresqlexpression.o: ../../pikotools/src/textstream/stream.h
|
||||||
|
./postgresqlexpression.o: ../../pikotools/src/space/space.h
|
||||||
|
./postgresqlexpression.o: ../../pikotools/src/utf8/utf8.h
|
||||||
|
./postgresqlexpression.o: ../../pikotools/src/membuffer/membuffer.h
|
||||||
|
./postgresqlexpression.o: ../../pikotools/src/textstream/types.h
|
||||||
|
./postgresqlexpression.o: ../../pikotools/src/textstream/stream_private.h
|
||||||
|
./postgresqlexpression.o: ../../pikotools/src/log/filelog.h finderhelper.h
|
||||||
|
./postgresqlexpression.o: fieldvaluehelper.h wrapper.h spacewrapper.h
|
||||||
|
./postgresqlexpression.o: baseobjectwrapper.h modelcontainerwrapper.h
|
||||||
|
./postgresqlexpression.o: select.h ft.h
|
||||||
|
./postgresqlqueryresult.o: postgresqlqueryresult.h queryresult.h
|
||||||
|
./postgresqlqueryresult.o: ../../pikotools/src/log/log.h
|
||||||
|
./postgresqlqueryresult.o: ../../pikotools/src/textstream/textstream.h
|
||||||
|
./postgresqlqueryresult.o: ../../pikotools/src/textstream/stream.h
|
||||||
|
./postgresqlqueryresult.o: ../../pikotools/src/space/space.h
|
||||||
|
./postgresqlqueryresult.o: ../../pikotools/src/convert/inttostr.h
|
||||||
|
./postgresqlqueryresult.o: ../../pikotools/src/utf8/utf8.h
|
||||||
|
./postgresqlqueryresult.o: ../../pikotools/src/textstream/stream.h
|
||||||
|
./postgresqlqueryresult.o: ../../pikotools/src/date/date.h
|
||||||
|
./postgresqlqueryresult.o: ../../pikotools/src/membuffer/membuffer.h
|
||||||
|
./postgresqlqueryresult.o: ../../pikotools/src/textstream/types.h
|
||||||
|
./postgresqlqueryresult.o: ../../pikotools/src/textstream/stream_private.h
|
||||||
|
./postgresqlqueryresult.o: ../../pikotools/src/log/filelog.h
|
||||||
|
./queryresult.o: queryresult.h ../../pikotools/src/log/log.h
|
||||||
|
./queryresult.o: ../../pikotools/src/textstream/textstream.h
|
||||||
|
./queryresult.o: ../../pikotools/src/textstream/stream.h
|
||||||
|
./queryresult.o: ../../pikotools/src/space/space.h
|
||||||
|
./queryresult.o: ../../pikotools/src/convert/inttostr.h
|
||||||
|
./queryresult.o: ../../pikotools/src/utf8/utf8.h
|
||||||
|
./queryresult.o: ../../pikotools/src/textstream/stream.h
|
||||||
|
./queryresult.o: ../../pikotools/src/date/date.h
|
||||||
|
./queryresult.o: ../../pikotools/src/membuffer/membuffer.h
|
||||||
|
./queryresult.o: ../../pikotools/src/textstream/types.h
|
||||||
|
./queryresult.o: ../../pikotools/src/textstream/stream_private.h
|
||||||
|
./queryresult.o: ../../pikotools/src/log/filelog.h
|
||||||
|
./csvexpression.o: csvexpression.h flatexpression.h baseexpression.h
|
||||||
|
./csvexpression.o: ../../pikotools/src/textstream/stream.h
|
||||||
|
./csvexpression.o: ../../pikotools/src/date/date.h
|
||||||
|
./csvexpression.o: ../../pikotools/src/convert/inttostr.h morm_types.h
|
||||||
|
./csvexpression.o: modelenv.h modeldata.h cursorhelper.h queryresult.h
|
||||||
|
./csvexpression.o: ../../pikotools/src/log/log.h
|
||||||
|
./csvexpression.o: ../../pikotools/src/textstream/textstream.h
|
||||||
|
./csvexpression.o: ../../pikotools/src/textstream/stream.h
|
||||||
|
./csvexpression.o: ../../pikotools/src/space/space.h
|
||||||
|
./csvexpression.o: ../../pikotools/src/utf8/utf8.h
|
||||||
|
./csvexpression.o: ../../pikotools/src/membuffer/membuffer.h
|
||||||
|
./csvexpression.o: ../../pikotools/src/textstream/types.h
|
||||||
|
./csvexpression.o: ../../pikotools/src/textstream/stream_private.h
|
||||||
|
./csvexpression.o: ../../pikotools/src/log/filelog.h finderhelper.h
|
||||||
|
./csvexpression.o: fieldvaluehelper.h wrapper.h spacewrapper.h
|
||||||
|
./csvexpression.o: baseobjectwrapper.h modelcontainerwrapper.h select.h ft.h
|
||||||
|
./csvexpression.o: ../../pikotools/src/convert/misc.h
|
||||||
|
./xmlexpression.o: xmlexpression.h flatexpression.h baseexpression.h
|
||||||
|
./xmlexpression.o: ../../pikotools/src/textstream/stream.h
|
||||||
|
./xmlexpression.o: ../../pikotools/src/date/date.h
|
||||||
|
./xmlexpression.o: ../../pikotools/src/convert/inttostr.h morm_types.h
|
||||||
|
./xmlexpression.o: modelenv.h modeldata.h cursorhelper.h queryresult.h
|
||||||
|
./xmlexpression.o: ../../pikotools/src/log/log.h
|
||||||
|
./xmlexpression.o: ../../pikotools/src/textstream/textstream.h
|
||||||
|
./xmlexpression.o: ../../pikotools/src/textstream/stream.h
|
||||||
|
./xmlexpression.o: ../../pikotools/src/space/space.h
|
||||||
|
./xmlexpression.o: ../../pikotools/src/utf8/utf8.h
|
||||||
|
./xmlexpression.o: ../../pikotools/src/membuffer/membuffer.h
|
||||||
|
./xmlexpression.o: ../../pikotools/src/textstream/types.h
|
||||||
|
./xmlexpression.o: ../../pikotools/src/textstream/stream_private.h
|
||||||
|
./xmlexpression.o: ../../pikotools/src/log/filelog.h finderhelper.h
|
||||||
|
./xmlexpression.o: fieldvaluehelper.h wrapper.h spacewrapper.h
|
||||||
|
./xmlexpression.o: baseobjectwrapper.h modelcontainerwrapper.h select.h ft.h
|
||||||
|
./xmlexpression.o: ../../pikotools/src/convert/misc.h
|
||||||
|
./postgresqlconnector.o: postgresqlconnector.h dbconnector.h
|
||||||
|
./postgresqlconnector.o: ../../pikotools/src/textstream/stream.h
|
||||||
|
./postgresqlconnector.o: ../../pikotools/src/log/log.h
|
||||||
|
./postgresqlconnector.o: ../../pikotools/src/textstream/textstream.h
|
||||||
|
./postgresqlconnector.o: ../../pikotools/src/textstream/stream.h
|
||||||
|
./postgresqlconnector.o: ../../pikotools/src/space/space.h
|
||||||
|
./postgresqlconnector.o: ../../pikotools/src/convert/inttostr.h
|
||||||
|
./postgresqlconnector.o: ../../pikotools/src/utf8/utf8.h
|
||||||
|
./postgresqlconnector.o: ../../pikotools/src/date/date.h
|
||||||
|
./postgresqlconnector.o: ../../pikotools/src/membuffer/membuffer.h
|
||||||
|
./postgresqlconnector.o: ../../pikotools/src/textstream/types.h
|
||||||
|
./postgresqlconnector.o: ../../pikotools/src/textstream/stream_private.h
|
||||||
|
./postgresqlconnector.o: ../../pikotools/src/log/filelog.h queryresult.h ft.h
|
||||||
|
./postgresqlconnector.o: postgresqlqueryresult.h postgresqlexpression.h
|
||||||
|
./postgresqlconnector.o: dbexpression.h baseexpression.h morm_types.h
|
||||||
|
./postgresqlconnector.o: modelenv.h modeldata.h cursorhelper.h finderhelper.h
|
||||||
|
./postgresqlconnector.o: fieldvaluehelper.h wrapper.h spacewrapper.h
|
||||||
|
./postgresqlconnector.o: baseobjectwrapper.h modelcontainerwrapper.h select.h
|
||||||
|
./transaction.o: transaction.h ../../pikotools/src/log/log.h
|
||||||
|
./transaction.o: ../../pikotools/src/textstream/textstream.h
|
||||||
|
./transaction.o: ../../pikotools/src/textstream/stream.h
|
||||||
|
./transaction.o: ../../pikotools/src/space/space.h
|
||||||
|
./transaction.o: ../../pikotools/src/convert/inttostr.h
|
||||||
|
./transaction.o: ../../pikotools/src/utf8/utf8.h
|
||||||
|
./transaction.o: ../../pikotools/src/textstream/stream.h
|
||||||
|
./transaction.o: ../../pikotools/src/date/date.h
|
||||||
|
./transaction.o: ../../pikotools/src/membuffer/membuffer.h
|
||||||
|
./transaction.o: ../../pikotools/src/textstream/types.h
|
||||||
|
./transaction.o: ../../pikotools/src/textstream/stream_private.h
|
||||||
|
./transaction.o: ../../pikotools/src/log/filelog.h modelconnector.h clearer.h
|
||||||
|
./transaction.o: ft.h dbconnector.h queryresult.h flatconnector.h export.h
|
||||||
|
./xmlconnector.o: xmlconnector.h flatconnector.h
|
||||||
|
./xmlconnector.o: ../../pikotools/src/textstream/stream.h export.h
|
||||||
|
./xmlconnector.o: xmlexpression.h flatexpression.h baseexpression.h
|
||||||
|
./xmlconnector.o: ../../pikotools/src/date/date.h
|
||||||
|
./xmlconnector.o: ../../pikotools/src/convert/inttostr.h morm_types.h
|
||||||
|
./xmlconnector.o: modelenv.h modeldata.h cursorhelper.h queryresult.h
|
||||||
|
./xmlconnector.o: ../../pikotools/src/log/log.h
|
||||||
|
./xmlconnector.o: ../../pikotools/src/textstream/textstream.h
|
||||||
|
./xmlconnector.o: ../../pikotools/src/textstream/stream.h
|
||||||
|
./xmlconnector.o: ../../pikotools/src/space/space.h
|
||||||
|
./xmlconnector.o: ../../pikotools/src/utf8/utf8.h
|
||||||
|
./xmlconnector.o: ../../pikotools/src/membuffer/membuffer.h
|
||||||
|
./xmlconnector.o: ../../pikotools/src/textstream/types.h
|
||||||
|
./xmlconnector.o: ../../pikotools/src/textstream/stream_private.h
|
||||||
|
./xmlconnector.o: ../../pikotools/src/log/filelog.h finderhelper.h
|
||||||
|
./xmlconnector.o: fieldvaluehelper.h wrapper.h spacewrapper.h
|
||||||
|
./xmlconnector.o: baseobjectwrapper.h modelcontainerwrapper.h select.h ft.h
|
||||||
|
./csvconnector.o: csvconnector.h flatconnector.h
|
||||||
|
./csvconnector.o: ../../pikotools/src/textstream/stream.h export.h
|
||||||
|
./csvconnector.o: csvexpression.h flatexpression.h baseexpression.h
|
||||||
|
./csvconnector.o: ../../pikotools/src/date/date.h
|
||||||
|
./csvconnector.o: ../../pikotools/src/convert/inttostr.h morm_types.h
|
||||||
|
./csvconnector.o: modelenv.h modeldata.h cursorhelper.h queryresult.h
|
||||||
|
./csvconnector.o: ../../pikotools/src/log/log.h
|
||||||
|
./csvconnector.o: ../../pikotools/src/textstream/textstream.h
|
||||||
|
./csvconnector.o: ../../pikotools/src/textstream/stream.h
|
||||||
|
./csvconnector.o: ../../pikotools/src/space/space.h
|
||||||
|
./csvconnector.o: ../../pikotools/src/utf8/utf8.h
|
||||||
|
./csvconnector.o: ../../pikotools/src/membuffer/membuffer.h
|
||||||
|
./csvconnector.o: ../../pikotools/src/textstream/types.h
|
||||||
|
./csvconnector.o: ../../pikotools/src/textstream/stream_private.h
|
||||||
|
./csvconnector.o: ../../pikotools/src/log/filelog.h finderhelper.h
|
||||||
|
./csvconnector.o: fieldvaluehelper.h wrapper.h spacewrapper.h
|
||||||
|
./csvconnector.o: baseobjectwrapper.h modelcontainerwrapper.h select.h ft.h
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
o = baseexpression.o clearer.o dbconnector.o dbexpression.o flatconnector.o flatexpression.o jsonconnector.o jsonexpression.o model.o modelconnector.o postgresqlconnector.o postgresqlexpression.o postgresqlqueryresult.o queryresult.o
|
|
File diff suppressed because it is too large
Load Diff
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018-2021, Tomasz Sowa
|
* Copyright (c) 2018-2024, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -32,21 +32,17 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef headerfile_morm_baseexpression
|
#ifndef headerfile_morm_src_baseexpression
|
||||||
#define headerfile_morm_baseexpression
|
#define headerfile_morm_src_baseexpression
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include "textstream/textstream.h"
|
#include <type_traits>
|
||||||
|
#include "textstream/stream.h"
|
||||||
#include "date/date.h"
|
#include "date/date.h"
|
||||||
#include "morm_types.h"
|
#include "morm_types.h"
|
||||||
#include "modelenv.h"
|
#include "modelenv.h"
|
||||||
#include "ft.h"
|
#include "ft.h"
|
||||||
#include "convert/text.h"
|
|
||||||
|
|
||||||
#ifdef MORM_HAS_EZC_LIBRARY
|
|
||||||
#include "env.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
namespace morm
|
namespace morm
|
||||||
|
@ -62,17 +58,22 @@ public:
|
||||||
BaseExpression();
|
BaseExpression();
|
||||||
virtual ~BaseExpression();
|
virtual ~BaseExpression();
|
||||||
|
|
||||||
|
BaseExpression(const BaseExpression &) = delete;
|
||||||
|
BaseExpression(BaseExpression &&) = delete;
|
||||||
|
|
||||||
virtual void set_work_mode(int work_mode);
|
virtual void set_work_mode(int work_mode);
|
||||||
virtual int get_work_mode();
|
virtual int get_work_mode();
|
||||||
|
|
||||||
virtual pt::TextStream * get_text_stream();
|
virtual void set_output_type(int output_type);
|
||||||
virtual void set_text_stream(pt::TextStream * out_stream);
|
virtual int get_output_type();
|
||||||
|
|
||||||
|
virtual pt::Stream * get_text_stream();
|
||||||
|
virtual void set_text_stream(pt::Stream * out_stream);
|
||||||
|
|
||||||
virtual void clear();
|
virtual void clear();
|
||||||
|
|
||||||
virtual void generate_from_model(pt::TextStream & stream, Model & model);
|
virtual void generate_from_model(pt::Stream & stream, Model & model);
|
||||||
|
virtual void generate_from_model(pt::Stream & stream, Model & model, const FT & field_type);
|
||||||
virtual pt::TextStream * get_current_stream();
|
|
||||||
|
|
||||||
// rename me
|
// rename me
|
||||||
virtual void allow_to_use_prefix(bool use_prefix);
|
virtual void allow_to_use_prefix(bool use_prefix);
|
||||||
|
@ -117,23 +118,12 @@ public:
|
||||||
else
|
else
|
||||||
if( work_mode == MORM_WORK_MODE_MODEL_FIELDS_VALUES )
|
if( work_mode == MORM_WORK_MODE_MODEL_FIELDS_VALUES )
|
||||||
{
|
{
|
||||||
if( model_env && model_env->set_field_name_helper )
|
put_field_name_and_value(field_name, field_value, getter_method, field_type, model_env);
|
||||||
{
|
}
|
||||||
if( (size_t)model_env->field_index < model_env->set_field_name_helper->size() )
|
else
|
||||||
{
|
if( work_mode == MORM_WORK_MODE_MODEL_FIELDS_VALUES_FIELDS )
|
||||||
put_field_name_and_table_if_needed((*model_env->set_field_name_helper)[model_env->field_index], field_type, model_env);
|
{
|
||||||
put_name_value_separator();
|
put_field_name_and_value_and_closing_name(field_name, field_value, getter_method, field_type, model_env);
|
||||||
put_field_value_or_null(field_value, getter_method, field_type, model_env);
|
|
||||||
}
|
|
||||||
|
|
||||||
model_env->field_index += 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
put_field_name_and_table_if_needed(field_name, field_type, model_env);
|
|
||||||
put_name_value_separator();
|
|
||||||
put_field_value_or_null(field_value, getter_method, field_type, model_env);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
field_after();
|
field_after();
|
||||||
|
@ -142,45 +132,21 @@ public:
|
||||||
|
|
||||||
|
|
||||||
template<typename FieldValue>
|
template<typename FieldValue>
|
||||||
void put_field_value_or_null(const FieldValue & field_value, void (Model::*getter_method)(pt::Stream &), const FT & field_type, ModelEnv * model_env)
|
void field_in(pt::Stream & stream, const wchar_t * field_name, const std::set<FieldValue> & container, ModelEnv * model_env)
|
||||||
{
|
|
||||||
if( getter_method )
|
|
||||||
{
|
|
||||||
put_field_value(getter_method, field_type, model_env);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if( field_type.is_primary_key() )
|
|
||||||
{
|
|
||||||
if( model_env && model_env->has_primary_key_set )
|
|
||||||
put_field_value(field_value, field_type);
|
|
||||||
else
|
|
||||||
put_null_value();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
put_field_value(field_value, field_type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<typename FieldValue>
|
|
||||||
void field_in(pt::TextStream & stream, const wchar_t * field_name, const std::set<FieldValue> & container, ModelEnv * model_env)
|
|
||||||
{
|
{
|
||||||
field_in_generic<FieldValue, std::set<FieldValue>>(stream, field_name, container, model_env);
|
field_in_generic<FieldValue, std::set<FieldValue>>(stream, field_name, container, model_env);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename FieldValue>
|
template<typename FieldValue>
|
||||||
void field_in(pt::TextStream & stream, const wchar_t * field_name, const std::list<FieldValue> & container, ModelEnv * model_env)
|
void field_in(pt::Stream & stream, const wchar_t * field_name, const std::list<FieldValue> & container, ModelEnv * model_env)
|
||||||
{
|
{
|
||||||
field_in_generic<FieldValue, std::list<FieldValue>>(stream, field_name, container, model_env);
|
field_in_generic<FieldValue, std::list<FieldValue>>(stream, field_name, container, model_env);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename FieldValue>
|
template<typename FieldValue>
|
||||||
void field_in(pt::TextStream & stream, const wchar_t * field_name, const std::vector<FieldValue> & container, ModelEnv * model_env)
|
void field_in(pt::Stream & stream, const wchar_t * field_name, const std::vector<FieldValue> & container, ModelEnv * model_env)
|
||||||
{
|
{
|
||||||
field_in_generic<FieldValue, std::vector<FieldValue>>(stream, field_name, container, model_env);
|
field_in_generic<FieldValue, std::vector<FieldValue>>(stream, field_name, container, model_env);
|
||||||
}
|
}
|
||||||
|
@ -190,7 +156,7 @@ public:
|
||||||
void field_list(const wchar_t * field_name, ModelContainer & field_value, ModelContainerType * model_container_type,
|
void field_list(const wchar_t * field_name, ModelContainer & field_value, ModelContainerType * model_container_type,
|
||||||
const FT & field_type, ModelConnector * model_connector, ModelEnv * model_env, IsContainerByValueRenameMe * foo)
|
const FT & field_type, ModelConnector * model_connector, ModelEnv * model_env, IsContainerByValueRenameMe * foo)
|
||||||
{
|
{
|
||||||
if( out_stream && can_field_be_generated(field_type) )
|
if( out_stream && can_field_be_generated(field_type) && can_field_list_be_generated(field_type) )
|
||||||
{
|
{
|
||||||
field_before();
|
field_before();
|
||||||
|
|
||||||
|
@ -201,9 +167,12 @@ public:
|
||||||
// else
|
// else
|
||||||
if( work_mode == MORM_WORK_MODE_MODEL_FIELDS_VALUES )
|
if( work_mode == MORM_WORK_MODE_MODEL_FIELDS_VALUES )
|
||||||
{
|
{
|
||||||
put_field_name_and_table_if_needed(field_name, field_type, model_env);
|
put_field_name_and_value_list(field_name, field_value, model_container_type, field_type, model_connector, model_env, foo);
|
||||||
put_name_value_separator();
|
}
|
||||||
put_field_value_list(field_value, model_container_type, model_connector, model_env, foo);
|
else
|
||||||
|
if( work_mode == MORM_WORK_MODE_MODEL_FIELDS_VALUES_FIELDS )
|
||||||
|
{
|
||||||
|
put_field_name_and_value_list_and_closing_name(field_name, field_value, model_container_type, field_type, model_connector, model_env, foo);
|
||||||
}
|
}
|
||||||
|
|
||||||
field_after();
|
field_after();
|
||||||
|
@ -213,33 +182,40 @@ public:
|
||||||
template<typename ModelClass>
|
template<typename ModelClass>
|
||||||
void field_model(const wchar_t * field_name, ModelClass & field_model, const FT & field_type, ModelEnv * model_env)
|
void field_model(const wchar_t * field_name, ModelClass & field_model, const FT & field_type, ModelEnv * model_env)
|
||||||
{
|
{
|
||||||
if( out_stream && can_field_be_generated(field_type) )
|
if( out_stream && can_field_be_generated(field_type) && can_field_model_be_generated(field_model.get_has_primary_key_set(), field_type) )
|
||||||
{
|
{
|
||||||
field_before();
|
field_before();
|
||||||
|
|
||||||
if( work_mode == MORM_WORK_MODE_MODEL_FIELDS )
|
if( work_mode == MORM_WORK_MODE_MODEL_FIELDS )
|
||||||
{
|
{
|
||||||
put_field_name_and_table_if_needed(field_name, field_type, model_env);
|
if( output_type == MORM_OUTPUT_TYPE_FIELDS_RECURSIVE )
|
||||||
|
generate_from_model(field_model, field_type);
|
||||||
|
else
|
||||||
|
put_field_name_and_table_if_needed(field_name, field_type, model_env);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if( work_mode == MORM_WORK_MODE_MODEL_VALUES )
|
if( work_mode == MORM_WORK_MODE_MODEL_VALUES )
|
||||||
{
|
{
|
||||||
generate_from_model(field_model); // is it ok as a value?
|
generate_from_model(field_model, field_type);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if( work_mode == MORM_WORK_MODE_MODEL_FIELDS_VALUES )
|
if( work_mode == MORM_WORK_MODE_MODEL_FIELDS_VALUES )
|
||||||
{
|
{
|
||||||
put_field_name_and_table_if_needed(field_name, field_type, model_env);
|
put_field_name_and_value_model(field_name, field_model, field_type, model_env);
|
||||||
put_name_value_separator();
|
}
|
||||||
generate_from_model(field_model);
|
else
|
||||||
|
if( work_mode == MORM_WORK_MODE_MODEL_FIELDS_VALUES_FIELDS )
|
||||||
|
{
|
||||||
|
put_field_name_and_value_model_and_closing_name(field_name, field_model, field_type, model_env);
|
||||||
}
|
}
|
||||||
|
|
||||||
field_after();
|
field_after();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename FieldValue>
|
template<typename FieldValue>
|
||||||
void field_to_stream(pt::TextStream & stream, const wchar_t * field_name, const FieldValue & field_value, const FT & field_type, ModelEnv * model_env)
|
void field_to_stream(pt::Stream & stream, const wchar_t * field_name, const FieldValue & field_value, const FT & field_type, ModelEnv * model_env)
|
||||||
{
|
{
|
||||||
this->out_stream = &stream;
|
this->out_stream = &stream;
|
||||||
field(field_name, field_value, field_type, model_env);
|
field(field_name, field_value, field_type, model_env);
|
||||||
|
@ -247,6 +223,15 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename FieldValue>
|
||||||
|
void value_to_stream(pt::Stream & stream, const FieldValue & field_value, const FT & field_type, ModelEnv * model_env = nullptr)
|
||||||
|
{
|
||||||
|
this->out_stream = &stream;
|
||||||
|
put_field_value(field_value, field_type, model_env);
|
||||||
|
this->out_stream = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
virtual void put_schema_table(const wchar_t * schema_name, const wchar_t * table_name);
|
virtual void put_schema_table(const wchar_t * schema_name, const wchar_t * table_name);
|
||||||
virtual void put_schema_table(const pt::WTextStream & schema_name, const pt::WTextStream & table_name);
|
virtual void put_schema_table(const pt::WTextStream & schema_name, const pt::WTextStream & table_name);
|
||||||
virtual void put_table(const wchar_t * table_name);
|
virtual void put_table(const wchar_t * table_name);
|
||||||
|
@ -257,97 +242,219 @@ public:
|
||||||
virtual void put_table_with_index_and_field(const pt::WTextStream & table_name, int index, const wchar_t * field_name, const FT & field_type);
|
virtual void put_table_with_index_and_field(const pt::WTextStream & table_name, int index, const wchar_t * field_name, const FT & field_type);
|
||||||
virtual void put_table_and_field(const wchar_t * table_name, const wchar_t * field_name, const FT & field_type);
|
virtual void put_table_and_field(const wchar_t * table_name, const wchar_t * field_name, const FT & field_type);
|
||||||
virtual void put_table_and_field(const pt::WTextStream & table_name, const wchar_t * field_name, const FT & field_type);
|
virtual void put_table_and_field(const pt::WTextStream & table_name, const wchar_t * field_name, const FT & field_type);
|
||||||
|
virtual void put_alias(const pt::WTextStream & alias_name, int index);
|
||||||
|
virtual void put_alias(const pt::WTextStream & alias_name_prefix, int index, const wchar_t * alias_name_postfix);
|
||||||
|
|
||||||
virtual void schema_table_to_stream(pt::TextStream & stream, const wchar_t * schema_name, const wchar_t * table_name);
|
virtual void put_string(const char * str, const FT & field_type, bool add_quotes = false, ModelEnv * model_env = nullptr);
|
||||||
virtual void schema_table_to_stream(pt::TextStream & stream, const pt::WTextStream & schema_name, const pt::WTextStream & table_name);
|
virtual void put_string(const wchar_t * str, const FT & field_type, bool add_quotes = false, ModelEnv * model_env = nullptr);
|
||||||
virtual void table_to_stream(pt::TextStream & stream, const wchar_t * table_name);
|
virtual void put_string(const std::string & str, const FT & field_type, bool add_quotes = false, ModelEnv * model_env = nullptr);
|
||||||
virtual void table_to_stream(pt::TextStream & stream, const pt::WTextStream & table_name);
|
virtual void put_string(const std::wstring & str, const FT & field_type, bool add_quotes = false, ModelEnv * model_env = nullptr);
|
||||||
virtual void table_with_index_to_stream(pt::TextStream & stream, const wchar_t * table_name, int index);
|
virtual void put_stream(const pt::Stream & str, const FT & field_type, bool add_quotes = false, ModelEnv * model_env = nullptr);
|
||||||
virtual void table_with_index_to_stream(pt::TextStream & stream, const pt::WTextStream & table_name, int index);
|
|
||||||
virtual void table_with_index_and_field_to_stream(pt::TextStream & stream, const wchar_t * table_name, int index, const wchar_t * field_name, const FT & field_type);
|
|
||||||
virtual void table_with_index_and_field_to_stream(pt::TextStream & stream, const pt::WTextStream & table_name, int index, const wchar_t * field_name, const FT & field_type);
|
|
||||||
virtual void table_and_field_to_stream(pt::TextStream & stream, const wchar_t * table_name, const wchar_t * field_name, const FT & field_type);
|
|
||||||
virtual void table_and_field_to_stream(pt::TextStream & stream, const pt::WTextStream & table_name, const wchar_t * field_name, const FT & field_type);
|
|
||||||
|
|
||||||
|
template<typename char_type, size_t stack_size, size_t heap_block_size>
|
||||||
|
void put_stream(const pt::TextStreamBase<char_type, stack_size, heap_block_size> & str, const FT & field_type, bool add_quotes = false, ModelEnv * model_env = nullptr)
|
||||||
|
{
|
||||||
|
put_string_generic(str, field_type, add_quotes, model_env);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void schema_table_to_stream(pt::Stream & stream, const wchar_t * schema_name, const wchar_t * table_name);
|
||||||
|
virtual void schema_table_to_stream(pt::Stream & stream, const pt::WTextStream & schema_name, const pt::WTextStream & table_name);
|
||||||
|
virtual void table_to_stream(pt::Stream & stream, const wchar_t * table_name);
|
||||||
|
virtual void table_to_stream(pt::Stream & stream, const pt::WTextStream & table_name);
|
||||||
|
virtual void table_with_index_to_stream(pt::Stream & stream, const wchar_t * table_name, int index);
|
||||||
|
virtual void table_with_index_to_stream(pt::Stream & stream, const pt::WTextStream & table_name, int index);
|
||||||
|
virtual void table_with_index_and_field_to_stream(pt::Stream & stream, const wchar_t * table_name, int index, const wchar_t * field_name, const FT & field_type);
|
||||||
|
virtual void table_with_index_and_field_to_stream(pt::Stream & stream, const pt::WTextStream & table_name, int index, const wchar_t * field_name, const FT & field_type);
|
||||||
|
virtual void table_and_field_to_stream(pt::Stream & stream, const wchar_t * table_name, const wchar_t * field_name, const FT & field_type);
|
||||||
|
virtual void table_and_field_to_stream(pt::Stream & stream, const pt::WTextStream & table_name, const wchar_t * field_name, const FT & field_type);
|
||||||
|
virtual void alias_to_stream(pt::Stream & stream, const pt::WTextStream & alias_name, int index);
|
||||||
|
virtual void alias_to_stream(pt::Stream & stream, const pt::WTextStream & alias_name_prefix, int index, const wchar_t * alias_name_postfix);
|
||||||
|
|
||||||
|
virtual void string_to_stream(pt::Stream & stream, const char * str, const FT & field_type, bool add_quotes = false, ModelEnv * model_env = nullptr);
|
||||||
|
virtual void string_to_stream(pt::Stream & stream, const wchar_t * str, const FT & field_type, bool add_quotes = false, ModelEnv * model_env = nullptr);
|
||||||
|
virtual void string_to_stream(pt::Stream & stream, const std::string & str, const FT & field_type, bool add_quotes = false, ModelEnv * model_env = nullptr);
|
||||||
|
virtual void string_to_stream(pt::Stream & stream, const std::wstring & str, const FT & field_type, bool add_quotes = false, ModelEnv * model_env = nullptr);
|
||||||
|
|
||||||
|
virtual void stream_to_stream(pt::Stream & stream_out, const pt::Stream & stream_in, const FT & field_type, bool add_quotes = false, ModelEnv * model_env = nullptr);
|
||||||
|
|
||||||
|
template<typename char_type, size_t stack_size, size_t heap_block_size>
|
||||||
|
void stream_to_stream(pt::Stream & stream_out, const pt::TextStreamBase<char_type, stack_size, heap_block_size> & stream_in, const FT & field_type, bool add_quotes = false, ModelEnv * model_env = nullptr)
|
||||||
|
{
|
||||||
|
this->out_stream = &stream_out;
|
||||||
|
put_stream(stream_in, field_type, add_quotes, model_env);
|
||||||
|
this->out_stream = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<typename StringType>
|
||||||
|
void put_string_generic(const StringType * str, const FT & field_type, bool add_quotes, ModelEnv * model_env = nullptr)
|
||||||
|
{
|
||||||
|
if( out_stream )
|
||||||
|
{
|
||||||
|
if( add_quotes )
|
||||||
|
{
|
||||||
|
before_field_value_string(field_type, model_env);
|
||||||
|
}
|
||||||
|
|
||||||
|
esc(str, *out_stream, field_type, model_env);
|
||||||
|
|
||||||
|
if( add_quotes )
|
||||||
|
{
|
||||||
|
after_field_value_string(field_type, model_env);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename StringOrStreamType>
|
||||||
|
void put_string_generic(const StringOrStreamType & str, const FT & field_type, bool add_quotes, ModelEnv * model_env = nullptr)
|
||||||
|
{
|
||||||
|
if( out_stream )
|
||||||
|
{
|
||||||
|
if( add_quotes )
|
||||||
|
{
|
||||||
|
before_field_value_string(field_type, model_env);
|
||||||
|
}
|
||||||
|
|
||||||
|
esc(str, *out_stream, field_type, model_env);
|
||||||
|
|
||||||
|
if( add_quotes )
|
||||||
|
{
|
||||||
|
after_field_value_string(field_type, model_env);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* IMPLEMENT ME
|
* IMPLEMENT ME
|
||||||
* esc for: signed char, wchar_t, char16_t, char32_t
|
* esc for: signed char, wchar_t, char16_t, char32_t
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
virtual void esc(char val, pt::TextStream & stream, const FT & field_type = FT::default_type);
|
virtual bool esc_char(char val, pt::Stream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
|
||||||
virtual void esc(unsigned char val, pt::TextStream & stream, const FT & field_type = FT::default_type);
|
virtual bool esc_char(wchar_t val, pt::Stream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
|
||||||
|
virtual bool esc_char(char32_t val, pt::Stream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
|
||||||
|
|
||||||
virtual void esc(wchar_t val, pt::TextStream & stream, const FT & field_type = FT::default_type);
|
virtual void esc(char val, pt::Stream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
|
||||||
|
virtual void esc(unsigned char val, pt::Stream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
|
||||||
|
virtual void esc(wchar_t val, pt::Stream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
|
||||||
|
virtual void esc(char32_t val, pt::Stream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
|
||||||
|
|
||||||
virtual void esc(const std::wstring & val, pt::TextStream & stream, const FT & field_type = FT::default_type);
|
virtual void esc(const std::wstring & val, pt::Stream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
|
||||||
virtual void esc(const wchar_t * val, pt::TextStream & stream, const FT & field_type = FT::default_type);
|
virtual void esc(const wchar_t * val, pt::Stream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
|
||||||
|
|
||||||
virtual void esc(const std::string & val, pt::TextStream & stream, const FT & field_type = FT::default_type);
|
virtual void esc(const std::string & val, pt::Stream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
|
||||||
virtual void esc(const char * val, pt::TextStream & stream, const FT & field_type = FT::default_type);
|
virtual void esc(const char * val, pt::Stream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
|
||||||
|
|
||||||
virtual void esc(bool val, pt::TextStream & stream, const FT & field_type = FT::default_type);
|
virtual void esc(bool val, pt::Stream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
|
||||||
virtual void esc(short val, pt::TextStream & stream, const FT & field_type = FT::default_type);
|
virtual void esc(short val, pt::Stream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
|
||||||
virtual void esc(unsigned short val, pt::TextStream & stream, const FT & field_type = FT::default_type);
|
virtual void esc(unsigned short val, pt::Stream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
|
||||||
virtual void esc(int val, pt::TextStream & stream, const FT & field_type = FT::default_type);
|
virtual void esc(int val, pt::Stream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
|
||||||
virtual void esc(unsigned int val, pt::TextStream & stream, const FT & field_type = FT::default_type);
|
virtual void esc(unsigned int val, pt::Stream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
|
||||||
virtual void esc(long val, pt::TextStream & stream, const FT & field_type = FT::default_type);
|
virtual void esc(long val, pt::Stream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
|
||||||
virtual void esc(unsigned long val, pt::TextStream & stream, const FT & field_type = FT::default_type);
|
virtual void esc(unsigned long val, pt::Stream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
|
||||||
virtual void esc(long long val, pt::TextStream & stream, const FT & field_type = FT::default_type);
|
virtual void esc(long long val, pt::Stream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
|
||||||
virtual void esc(unsigned long long val, pt::TextStream & stream, const FT & field_type = FT::default_type);
|
virtual void esc(unsigned long long val, pt::Stream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
|
||||||
virtual void esc(float val, pt::TextStream & stream, const FT & field_type = FT::default_type);
|
virtual void esc(float val, pt::Stream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
|
||||||
virtual void esc(double val, pt::TextStream & stream, const FT & field_type = FT::default_type);
|
virtual void esc(double val, pt::Stream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
|
||||||
virtual void esc(long double val, pt::TextStream & stream, const FT & field_type = FT::default_type);
|
virtual void esc(long double val, pt::Stream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
|
||||||
//virtual void esc(void* val, pt::TextStream & stream);
|
|
||||||
|
|
||||||
virtual void esc(const pt::Date & date, pt::TextStream & stream, const FT & field_type = FT::default_type);
|
virtual void esc(const pt::Date & date, pt::Stream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
|
||||||
virtual void esc(const pt::TextStream & val,pt::TextStream & stream, const FT & field_type = FT::default_type);
|
virtual void esc(const pt::Space & space, pt::Stream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
|
||||||
virtual void esc(const pt::WTextStream & val,pt::TextStream & stream, const FT & field_type = FT::default_type);
|
virtual void esc(const pt::Stream & val, pt::Stream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
|
||||||
virtual void esc(const pt::Space & space, pt::TextStream & stream, const FT & field_type = FT::default_type);
|
|
||||||
|
|
||||||
|
template<typename char_type, size_t stack_size, size_t heap_block_size>
|
||||||
|
void esc(const pt::TextStreamBase<char_type, stack_size, heap_block_size> & val, pt::Stream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr)
|
||||||
|
{
|
||||||
|
if( val.is_char_stream() )
|
||||||
|
{
|
||||||
|
if( field_type.is_hexadecimal() || field_type.is_binary() )
|
||||||
|
{
|
||||||
|
typename pt::TextStreamBase<char_type, stack_size, heap_block_size>::const_iterator start = val.begin();
|
||||||
|
typename pt::TextStreamBase<char_type, stack_size, heap_block_size>::const_iterator end = val.end();
|
||||||
|
|
||||||
|
for( ; start != end ; ++start )
|
||||||
|
{
|
||||||
|
esc(static_cast<char>(*start), stream, field_type, model_env);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// from utf8 to utf8 or from utf8 to wide
|
||||||
|
pt::utf8_to_output_function(val, [&](int z) {
|
||||||
|
esc(static_cast<char32_t>(z), stream, field_type, model_env);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if( val.is_wchar_stream() )
|
||||||
|
{
|
||||||
|
// from wide to wide or from wide to utf8
|
||||||
|
pt::wide_to_output_function(val, [&](int z) {
|
||||||
|
esc(static_cast<char32_t>(z), stream, field_type, model_env);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
int work_mode; /* what to do: generating fields list, values list or fields-values list */
|
int work_mode; /* what to do: generating fields list, values list or fields-values list */
|
||||||
|
int output_type;
|
||||||
bool is_first_field;
|
bool is_first_field;
|
||||||
|
pt::Stream * out_stream;
|
||||||
pt::TextStream * out_stream;
|
|
||||||
|
|
||||||
bool use_prefix;
|
bool use_prefix;
|
||||||
|
pt::TextStream scratch_buffer_local;
|
||||||
|
pt::TextStream * scratch_buffer;
|
||||||
|
|
||||||
virtual void generate_from_model(Model & model);
|
virtual void generate_from_model(Model & model, const FT & field_type);
|
||||||
|
|
||||||
virtual void before_generate_from_model();
|
virtual void before_generate_from_model();
|
||||||
virtual void after_generate_from_model();
|
virtual void after_generate_from_model();
|
||||||
|
|
||||||
virtual bool can_field_be_generated(const FT &);
|
virtual bool can_field_be_generated(const FT &);
|
||||||
|
virtual bool can_field_model_be_generated(bool has_model_primary_key, const FT & field_type);
|
||||||
|
virtual bool can_field_list_be_generated(const FT &);
|
||||||
|
virtual bool should_field_model_be_generated_as_null(bool has_model_primary_key, const FT & field_type);
|
||||||
|
|
||||||
virtual void field_before();
|
virtual void field_before();
|
||||||
virtual void field_after();
|
virtual void field_after();
|
||||||
|
|
||||||
virtual void put_field_name_and_table_if_needed(const wchar_t * field_name, const FT & field_type, ModelEnv * model_env);
|
virtual void put_field_name_and_table_if_needed(const wchar_t * field_name, const FT & field_type, ModelEnv * model_env);
|
||||||
virtual void put_field_name(const wchar_t * field_name, const FT & field_type, ModelEnv * model_env);
|
virtual void put_field_name(const wchar_t * field_name, const FT & field_type, ModelEnv * model_env);
|
||||||
|
virtual void put_field_closing_name(const wchar_t * field_name, const FT & field_type, ModelEnv * model_env);
|
||||||
|
virtual void put_value_list_opening_index(size_t index, const FT & field_type);
|
||||||
|
virtual void put_value_list_closing_index(size_t index, const FT & field_type);
|
||||||
|
|
||||||
virtual void save_foreign_key(const wchar_t * field_name, const FT & field_type, ModelEnv * model_env);
|
virtual void save_foreign_key(const wchar_t * field_name, const FT & field_type, ModelEnv * model_env);
|
||||||
virtual void dump_additional_info(Model & model);
|
virtual void dump_additional_info(Model & model);
|
||||||
|
virtual void add_additional_columns(Model & model);
|
||||||
|
|
||||||
template<typename FieldValue>
|
template<typename FieldValue>
|
||||||
void put_field_value(const FieldValue & field_value, const FT & field_type)
|
void put_field_value(const FieldValue & field_value, const FT & field_type, ModelEnv * model_env = nullptr)
|
||||||
{
|
{
|
||||||
if( out_stream )
|
if( out_stream )
|
||||||
{
|
{
|
||||||
before_field_value(field_value, field_type);
|
before_field_value(field_value, field_type, model_env);
|
||||||
esc(field_value, *out_stream, field_type);
|
esc(field_value, *out_stream, field_type, model_env);
|
||||||
after_field_value(field_value, field_type);
|
after_field_value(field_value, field_type, model_env);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void put_field_value(void (Model::*getter_method)(pt::Stream &), const FT & field_type, ModelEnv * model_env)
|
void put_field_value(void (Model::*getter_method)(pt::Stream &), const FT & field_type, ModelEnv * model_env = nullptr)
|
||||||
{
|
{
|
||||||
if( out_stream && model_env && model_env->model && getter_method )
|
if( out_stream && model_env && model_env->model && getter_method )
|
||||||
{
|
{
|
||||||
before_field_value_string(field_type);
|
before_field_value_string(field_type, model_env);
|
||||||
(model_env->model->*getter_method)(*out_stream);
|
|
||||||
after_field_value_string(field_type);
|
if( scratch_buffer )
|
||||||
|
{
|
||||||
|
scratch_buffer->clear();
|
||||||
|
(model_env->model->*getter_method)(*scratch_buffer);
|
||||||
|
esc(*scratch_buffer, *out_stream, field_type, model_env);
|
||||||
|
scratch_buffer->clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
after_field_value_string(field_type, model_env);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -384,45 +491,50 @@ protected:
|
||||||
|
|
||||||
|
|
||||||
template<typename ModelContainer, typename ModelContainerType, typename IsContainerByValueRenameMe>
|
template<typename ModelContainer, typename ModelContainerType, typename IsContainerByValueRenameMe>
|
||||||
void put_field_value_list(ModelContainer & field_value, ModelContainerType * model_container_type, ModelConnector * model_connector,
|
void put_field_value_list(ModelContainer & field_value, ModelContainerType * model_container_type, const FT & field_type,
|
||||||
ModelEnv * model_env, IsContainerByValueRenameMe * foo)
|
ModelConnector * model_connector, ModelEnv * model_env, IsContainerByValueRenameMe * foo)
|
||||||
{
|
{
|
||||||
if constexpr (std::is_base_of<Model, ModelContainerType>())
|
if constexpr (std::is_base_of<Model, ModelContainerType>())
|
||||||
{
|
{
|
||||||
if constexpr (std::is_base_of<Model, IsContainerByValueRenameMe>())
|
if constexpr (std::is_base_of<Model, IsContainerByValueRenameMe>())
|
||||||
{
|
{
|
||||||
put_field_value_list_model_by_value(field_value, model_container_type, model_connector, model_env);
|
put_field_value_list_model_by_value(field_value, model_container_type, field_type, model_connector, model_env);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
put_field_value_list_model_by_pointer(field_value, model_container_type, model_connector, model_env);
|
put_field_value_list_model_by_pointer(field_value, model_container_type, field_type, model_connector, model_env);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
put_field_value_list_non_model(field_value, model_connector);
|
put_field_value_list_non_model(field_value, model_connector, field_type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename ModelContainer, typename ModelContainerType>
|
template<typename ModelContainer, typename ModelContainerType>
|
||||||
void put_field_value_list_model_by_value(ModelContainer & field_value, ModelContainerType * model_container_type, ModelConnector * model_connector,
|
void put_field_value_list_model_by_value(ModelContainer & field_value, ModelContainerType * model_container_type, const FT & field_type,
|
||||||
ModelEnv * model_env)
|
ModelConnector * model_connector, ModelEnv * model_env)
|
||||||
{
|
{
|
||||||
if( model_connector && model_env && out_stream )
|
if( model_connector && model_env && out_stream )
|
||||||
{
|
{
|
||||||
bool is_first = true;
|
|
||||||
before_field_value_list();
|
before_field_value_list();
|
||||||
|
size_t index = 0;
|
||||||
|
|
||||||
for(auto & child_model_item : field_value)
|
for(auto & child_model_item : field_value)
|
||||||
{
|
{
|
||||||
if( !is_first )
|
if( can_field_model_be_generated(child_model_item.get_has_primary_key_set(), field_type) )
|
||||||
{
|
{
|
||||||
field_value_list_separator();
|
if( index > 0 )
|
||||||
}
|
{
|
||||||
|
field_value_list_separator();
|
||||||
|
}
|
||||||
|
|
||||||
put_field_value_list_model(child_model_item, model_connector, model_env);
|
put_value_list_opening_index(index, field_type);
|
||||||
is_first = false;
|
put_field_value_list_model(child_model_item, model_connector, model_env);
|
||||||
|
put_value_list_closing_index(index, field_type);
|
||||||
|
index += 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
after_field_value_list();
|
after_field_value_list();
|
||||||
|
@ -431,23 +543,28 @@ protected:
|
||||||
|
|
||||||
|
|
||||||
template<typename ModelContainer, typename ModelContainerType>
|
template<typename ModelContainer, typename ModelContainerType>
|
||||||
void put_field_value_list_model_by_pointer(ModelContainer & field_value, ModelContainerType * model_container_type, ModelConnector * model_connector,
|
void put_field_value_list_model_by_pointer(ModelContainer & field_value, ModelContainerType * model_container_type, const FT & field_type,
|
||||||
ModelEnv * model_env)
|
ModelConnector * model_connector, ModelEnv * model_env)
|
||||||
{
|
{
|
||||||
if( model_connector && model_env && out_stream )
|
if( model_connector && model_env && out_stream )
|
||||||
{
|
{
|
||||||
bool is_first = true;
|
|
||||||
before_field_value_list();
|
before_field_value_list();
|
||||||
|
size_t index = 0;
|
||||||
|
|
||||||
for(auto * child_model_item : field_value)
|
for(auto * child_model_item : field_value)
|
||||||
{
|
{
|
||||||
if( !is_first )
|
if( can_field_model_be_generated(child_model_item->get_has_primary_key_set(), field_type) )
|
||||||
{
|
{
|
||||||
field_value_list_separator();
|
if( index > 0 )
|
||||||
}
|
{
|
||||||
|
field_value_list_separator();
|
||||||
|
}
|
||||||
|
|
||||||
put_field_value_list_model(*child_model_item, model_connector, model_env);
|
put_value_list_opening_index(index, field_type);
|
||||||
is_first = false;
|
put_field_value_list_model(*child_model_item, model_connector, model_env);
|
||||||
|
put_value_list_closing_index(index, field_type);
|
||||||
|
index += 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
after_field_value_list();
|
after_field_value_list();
|
||||||
|
@ -464,29 +581,32 @@ protected:
|
||||||
child_model.model_env->model = &child_model;
|
child_model.model_env->model = &child_model;
|
||||||
child_model.set_connector(model_connector);
|
child_model.set_connector(model_connector);
|
||||||
|
|
||||||
generate_from_model(child_model);
|
FT field_type = FT::default_type;
|
||||||
|
generate_from_model(child_model, field_type);
|
||||||
|
|
||||||
child_model.model_env = nullptr;
|
child_model.model_env = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename ModelContainer>
|
template<typename ModelContainer>
|
||||||
void put_field_value_list_non_model(ModelContainer & field_value, ModelConnector * model_connector)
|
void put_field_value_list_non_model(ModelContainer & field_value, ModelConnector * model_connector, const FT & field_type)
|
||||||
{
|
{
|
||||||
if( model_connector && out_stream )
|
if( model_connector && out_stream )
|
||||||
{
|
{
|
||||||
bool is_first = true;
|
|
||||||
before_field_value_list();
|
before_field_value_list();
|
||||||
|
size_t index = 0;
|
||||||
|
|
||||||
for(const auto & m : field_value)
|
for(const auto & m : field_value)
|
||||||
{
|
{
|
||||||
if( !is_first )
|
if( index > 0 )
|
||||||
{
|
{
|
||||||
field_value_list_separator();
|
field_value_list_separator();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
put_value_list_opening_index(index, field_type);
|
||||||
put_field_value(m, FT::default_type);
|
put_field_value(m, FT::default_type);
|
||||||
is_first = false;
|
put_value_list_closing_index(index, field_type);
|
||||||
|
index += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
after_field_value_list();
|
after_field_value_list();
|
||||||
|
@ -497,7 +617,7 @@ protected:
|
||||||
|
|
||||||
// used in 'in()' statements, may should be renamed?
|
// used in 'in()' statements, may should be renamed?
|
||||||
template<typename FieldValue, typename Container>
|
template<typename FieldValue, typename Container>
|
||||||
void field_in_generic(pt::TextStream & stream, const wchar_t * field_name, const Container & container, ModelEnv * model_env)
|
void field_in_generic(pt::Stream & stream, const wchar_t * field_name, const Container & container, ModelEnv * model_env)
|
||||||
{
|
{
|
||||||
// IMPROVE ME
|
// IMPROVE ME
|
||||||
// what about if container is empty?
|
// what about if container is empty?
|
||||||
|
@ -518,7 +638,7 @@ protected:
|
||||||
field_value_list_separator();
|
field_value_list_separator();
|
||||||
}
|
}
|
||||||
|
|
||||||
put_field_value(v, FT::default_type);
|
put_field_value(v, FT::default_type, model_env);
|
||||||
is_first = false;
|
is_first = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -530,6 +650,7 @@ protected:
|
||||||
|
|
||||||
virtual void schema_table_separator();
|
virtual void schema_table_separator();
|
||||||
virtual void table_field_separator();
|
virtual void table_field_separator();
|
||||||
|
virtual void alias_names_separator();
|
||||||
|
|
||||||
virtual void before_schema_name();
|
virtual void before_schema_name();
|
||||||
virtual void after_schema_name();
|
virtual void after_schema_name();
|
||||||
|
@ -540,41 +661,62 @@ protected:
|
||||||
virtual void before_field_name();
|
virtual void before_field_name();
|
||||||
virtual void after_field_name();
|
virtual void after_field_name();
|
||||||
|
|
||||||
|
virtual void before_alias_name();
|
||||||
|
virtual void after_alias_name();
|
||||||
|
|
||||||
virtual void before_field_value(const std::wstring &, const FT & field_type);
|
virtual void before_field_value(const std::wstring &, const FT & field_type, ModelEnv * model_env);
|
||||||
virtual void after_field_value(const std::wstring &, const FT & field_type);
|
virtual void after_field_value(const std::wstring &, const FT & field_type, ModelEnv * model_env);
|
||||||
|
|
||||||
virtual void before_field_value(const std::string &, const FT & field_type);
|
virtual void before_field_value(const std::string &, const FT & field_type, ModelEnv * model_env);
|
||||||
virtual void after_field_value(const std::string &, const FT & field_type);
|
virtual void after_field_value(const std::string &, const FT & field_type, ModelEnv * model_env);
|
||||||
|
|
||||||
virtual void before_field_value(const wchar_t *, const FT & field_type);
|
virtual void before_field_value(const wchar_t *, const FT & field_type, ModelEnv * model_env);
|
||||||
virtual void after_field_value(const wchar_t *, const FT & field_type);
|
virtual void after_field_value(const wchar_t *, const FT & field_type, ModelEnv * model_env);
|
||||||
|
|
||||||
virtual void before_field_value(const char *, const FT & field_type);
|
virtual void before_field_value(const char *, const FT & field_type, ModelEnv * model_env);
|
||||||
virtual void after_field_value(const char *, const FT & field_type);
|
virtual void after_field_value(const char *, const FT & field_type, ModelEnv * model_env);
|
||||||
|
|
||||||
virtual void before_field_value(wchar_t, const FT & field_type);
|
virtual void before_field_value(wchar_t, const FT & field_type, ModelEnv * model_env);
|
||||||
virtual void after_field_value(wchar_t, const FT & field_type);
|
virtual void after_field_value(wchar_t, const FT & field_type, ModelEnv * model_env);
|
||||||
|
|
||||||
virtual void before_field_value(char, const FT & field_type);
|
virtual void before_field_value(char, const FT & field_type, ModelEnv * model_env);
|
||||||
virtual void after_field_value(char, const FT & field_type);
|
virtual void after_field_value(char, const FT & field_type, ModelEnv * model_env);
|
||||||
|
|
||||||
virtual void before_field_value(const pt::Date &, const FT & field_type);
|
virtual void before_field_value(const pt::Date &, const FT & field_type, ModelEnv * model_env);
|
||||||
virtual void after_field_value(const pt::Date &, const FT & field_type);
|
virtual void after_field_value(const pt::Date &, const FT & field_type, ModelEnv * model_env);
|
||||||
|
|
||||||
virtual void before_field_value(const pt::Space &, const FT & field_type);
|
virtual void before_field_value(const pt::Space &, const FT & field_type, ModelEnv * model_env);
|
||||||
virtual void after_field_value(const pt::Space &, const FT & field_type);
|
virtual void after_field_value(const pt::Space &, const FT & field_type, ModelEnv * model_env);
|
||||||
|
|
||||||
template<typename FieldValue>
|
template<typename FieldValue>
|
||||||
void before_field_value(const FieldValue &, const FT & field_type)
|
void before_field_value(const FieldValue & field_value, const FT & field_type, ModelEnv * model_env)
|
||||||
{
|
{
|
||||||
|
if constexpr ( std::is_base_of<pt::Stream, FieldValue>() )
|
||||||
|
{
|
||||||
|
before_field_value_string(field_type, model_env);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
before_field_value_generic();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename FieldValue>
|
template<typename FieldValue>
|
||||||
void after_field_value(const FieldValue &, const FT & field_type)
|
void after_field_value(const FieldValue &, const FT & field_type, ModelEnv * model_env)
|
||||||
{
|
{
|
||||||
|
if constexpr ( std::is_base_of<pt::Stream, FieldValue>() )
|
||||||
|
{
|
||||||
|
after_field_value_string(field_type, model_env);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
after_field_value_generic();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void before_field_value_generic();
|
||||||
|
virtual void after_field_value_generic();
|
||||||
|
|
||||||
virtual void put_name_value_separator();
|
virtual void put_name_value_separator();
|
||||||
|
|
||||||
|
|
||||||
|
@ -583,55 +725,220 @@ protected:
|
||||||
* put_type for: signed char, wchar_t, char16_t, char32_t
|
* put_type for: signed char, wchar_t, char16_t, char32_t
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
// virtual void put_type(char val, pt::TextStream & stream);
|
// virtual void put_type(char val, pt::Stream & stream);
|
||||||
// virtual void put_type(unsigned char val, pt::TextStream & stream);
|
// virtual void put_type(unsigned char val, pt::Stream & stream);
|
||||||
//
|
//
|
||||||
// virtual void put_type(const std::wstring & val, pt::TextStream & stream);
|
// virtual void put_type(const std::wstring & val, pt::Stream & stream);
|
||||||
// virtual void put_type(const wchar_t * val, pt::TextStream & stream);
|
// virtual void put_type(const wchar_t * val, pt::Stream & stream);
|
||||||
//
|
//
|
||||||
// virtual void put_type(const std::string & val, pt::TextStream & stream);
|
// virtual void put_type(const std::string & val, pt::Stream & stream);
|
||||||
// virtual void put_type(const char * val, pt::TextStream & stream);
|
// virtual void put_type(const char * val, pt::Stream & stream);
|
||||||
//
|
//
|
||||||
// virtual void put_type(bool val, pt::TextStream & stream);
|
// virtual void put_type(bool val, pt::Stream & stream);
|
||||||
// virtual void put_type(short val, pt::TextStream & stream);
|
// virtual void put_type(short val, pt::Stream & stream);
|
||||||
// virtual void put_type(unsigned short val, pt::TextStream & stream);
|
// virtual void put_type(unsigned short val, pt::Stream & stream);
|
||||||
// virtual void put_type(int val, pt::TextStream & stream);
|
// virtual void put_type(int val, pt::Stream & stream);
|
||||||
// virtual void put_type(unsigned int val, pt::TextStream & stream);
|
// virtual void put_type(unsigned int val, pt::Stream & stream);
|
||||||
// virtual void put_type(long val, pt::TextStream & stream);
|
// virtual void put_type(long val, pt::Stream & stream);
|
||||||
// virtual void put_type(unsigned long val, pt::TextStream & stream);
|
// virtual void put_type(unsigned long val, pt::Stream & stream);
|
||||||
// virtual void put_type(long long val, pt::TextStream & stream);
|
// virtual void put_type(long long val, pt::Stream & stream);
|
||||||
// virtual void put_type(unsigned long long val, pt::TextStream & stream);
|
// virtual void put_type(unsigned long long val, pt::Stream & stream);
|
||||||
// virtual void put_type(float val, pt::TextStream & stream);
|
// virtual void put_type(float val, pt::Stream & stream);
|
||||||
// virtual void put_type(double val, pt::TextStream & stream);
|
// virtual void put_type(double val, pt::Stream & stream);
|
||||||
// virtual void put_type(long double val, pt::TextStream & stream);
|
// virtual void put_type(long double val, pt::Stream & stream);
|
||||||
//virtual void put_type(void* val, pt::TextStream & stream);
|
//virtual void put_type(void* val, pt::Stream & stream);
|
||||||
|
|
||||||
// virtual void put_type(const pt::Date & date, pt::TextStream & stream);
|
// virtual void put_type(const pt::Date & date, pt::Stream & stream);
|
||||||
// virtual void put_type(const Model & model, pt::TextStream & stream);
|
// virtual void put_type(const Model & model, pt::Stream & stream);
|
||||||
//
|
//
|
||||||
// template<typename ListType>
|
// template<typename ListType>
|
||||||
// void put_type(const std::list<ListType> & model, pt::TextStream & stream)
|
// void put_type(const std::list<ListType> & model, pt::Stream & stream)
|
||||||
// {
|
// {
|
||||||
// stream << "table"; // may just use std::list?
|
// stream << "table"; // may just use std::list?
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// template<typename ListType>
|
// template<typename ListType>
|
||||||
// void put_type(const std::vector<ListType> & model, pt::TextStream & stream)
|
// void put_type(const std::vector<ListType> & model, pt::Stream & stream)
|
||||||
// {
|
// {
|
||||||
// stream << "table"; // may just just std::vector?
|
// stream << "table"; // may just just std::vector?
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
virtual void before_field_value_string(const FT & field_type);
|
virtual void before_field_value_string(const FT & field_type, ModelEnv * model_env);
|
||||||
virtual void after_field_value_string(const FT & field_type);
|
virtual void after_field_value_string(const FT & field_type, ModelEnv * model_env);
|
||||||
|
|
||||||
char char_to_hex_part(char c);
|
char char_to_hex_part(char c);
|
||||||
void char_to_hex(char c, pt::TextStream & stream);
|
void char_to_hex(char c, pt::Stream & stream);
|
||||||
|
void char_to_hex(char32_t c, pt::Stream & stream);
|
||||||
|
|
||||||
void esc(const wchar_t * val, bool has_known_length, size_t len, pt::TextStream & stream, const FT & field_type = FT::default_type);
|
void esc(const wchar_t * val, bool has_known_length, size_t len, pt::Stream & stream, const FT & field_type, ModelEnv * model_env);
|
||||||
|
void esc(const char * val, bool has_known_length, size_t len, pt::Stream & stream, const FT & field_type, ModelEnv * model_env);
|
||||||
|
|
||||||
bool is_empty_field(const wchar_t * value);
|
bool is_empty_field(const wchar_t * value);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<typename CharType>
|
||||||
|
void esc_normal_string(CharType * val, bool has_known_length, size_t len, pt::Stream & stream, const FT & field_type, ModelEnv * model_env)
|
||||||
|
{
|
||||||
|
for(size_t i = 0 ; has_known_length ? (i < len) : val[i] != 0 ; ++i)
|
||||||
|
{
|
||||||
|
esc(val[i], stream, field_type, model_env);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename CharType>
|
||||||
|
void esc_numeric_string(CharType * val, bool has_known_length, size_t len, pt::Stream & stream, const FT & field_type, ModelEnv * model_env)
|
||||||
|
{
|
||||||
|
bool was_comma = false;
|
||||||
|
bool was_something_printed = false;
|
||||||
|
bool was_digit_printed = false;
|
||||||
|
|
||||||
|
for(size_t i = 0 ; has_known_length ? (i < len) : val[i] != 0 ; ++i)
|
||||||
|
{
|
||||||
|
typename std::remove_const<CharType>::type c = val[i];
|
||||||
|
|
||||||
|
if( c == ',' )
|
||||||
|
c = '.';
|
||||||
|
|
||||||
|
if( (c=='.' && !was_comma) || (c>='0' && c<='9') || (c=='-' && !was_something_printed) )
|
||||||
|
{
|
||||||
|
if( c=='.' )
|
||||||
|
{
|
||||||
|
if( !was_digit_printed )
|
||||||
|
{
|
||||||
|
esc(static_cast<CharType>('0'), stream, field_type, model_env);
|
||||||
|
was_digit_printed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
was_comma = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
esc(c, stream, field_type, model_env);
|
||||||
|
was_something_printed = true;
|
||||||
|
|
||||||
|
if( c>='0' && c<='9' )
|
||||||
|
{
|
||||||
|
was_digit_printed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !was_digit_printed )
|
||||||
|
{
|
||||||
|
esc(static_cast<CharType>('0'), stream, field_type, model_env);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename FieldValue>
|
||||||
|
void put_field_value_or_null(const FieldValue & field_value, void (Model::*getter_method)(pt::Stream &), const FT & field_type, ModelEnv * model_env)
|
||||||
|
{
|
||||||
|
if( getter_method )
|
||||||
|
{
|
||||||
|
put_field_value(getter_method, field_type, model_env);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( field_type.is_primary_key() )
|
||||||
|
{
|
||||||
|
if( model_env && model_env->has_primary_key_set )
|
||||||
|
put_field_value(field_value, field_type, model_env);
|
||||||
|
else
|
||||||
|
put_null_value();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
put_field_value(field_value, field_type, model_env);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename FieldValue>
|
||||||
|
void put_field_name_and_value(const wchar_t * field_name, const FieldValue & field_value, void (Model::*getter_method)(pt::Stream &), const FT & field_type, ModelEnv * model_env)
|
||||||
|
{
|
||||||
|
bool allow_to_put_value = (get_output_type() != MORM_OUTPUT_TYPE_WHERE_IS_NULL && get_output_type() != MORM_OUTPUT_TYPE_WHERE_IS_NOT_NULL);
|
||||||
|
|
||||||
|
if( model_env && model_env->set_field_name_helper )
|
||||||
|
{
|
||||||
|
if( (size_t)model_env->field_index < model_env->set_field_name_helper->size() )
|
||||||
|
{
|
||||||
|
put_field_name_and_table_if_needed((*model_env->set_field_name_helper)[model_env->field_index], field_type, model_env);
|
||||||
|
put_name_value_separator();
|
||||||
|
|
||||||
|
if( allow_to_put_value )
|
||||||
|
put_field_value_or_null(field_value, getter_method, field_type, model_env);
|
||||||
|
}
|
||||||
|
|
||||||
|
model_env->field_index += 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
put_field_name_and_table_if_needed(field_name, field_type, model_env);
|
||||||
|
put_name_value_separator();
|
||||||
|
|
||||||
|
if( allow_to_put_value )
|
||||||
|
put_field_value_or_null(field_value, getter_method, field_type, model_env);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename ModelContainer, typename ModelContainerType, typename IsContainerByValueRenameMe>
|
||||||
|
void put_field_name_and_value_list(const wchar_t * field_name, ModelContainer & field_value, ModelContainerType * model_container_type,
|
||||||
|
const FT & field_type, ModelConnector * model_connector, ModelEnv * model_env, IsContainerByValueRenameMe * foo)
|
||||||
|
{
|
||||||
|
put_field_name_and_table_if_needed(field_name, field_type, model_env);
|
||||||
|
put_name_value_separator();
|
||||||
|
put_field_value_list(field_value, model_container_type, field_type, model_connector, model_env, foo);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename ModelClass>
|
||||||
|
void put_field_name_and_value_model(const wchar_t * field_name, ModelClass & field_model, const FT & field_type, ModelEnv * model_env)
|
||||||
|
{
|
||||||
|
put_field_name_and_table_if_needed(field_name, field_type, model_env);
|
||||||
|
put_name_value_separator();
|
||||||
|
generate_from_model(field_model, field_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename FieldValue>
|
||||||
|
void put_field_name_and_value_and_closing_name(const wchar_t * field_name, const FieldValue & field_value, void (Model::*getter_method)(pt::Stream &), const FT & field_type, ModelEnv * model_env)
|
||||||
|
{
|
||||||
|
put_field_name_and_table_if_needed(field_name, field_type, model_env);
|
||||||
|
put_name_value_separator();
|
||||||
|
put_field_value_or_null(field_value, getter_method, field_type, model_env);
|
||||||
|
put_name_value_separator();
|
||||||
|
put_field_closing_name(field_name, field_type, model_env);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename ModelContainer, typename ModelContainerType, typename IsContainerByValueRenameMe>
|
||||||
|
void put_field_name_and_value_list_and_closing_name(const wchar_t * field_name, ModelContainer & field_value, ModelContainerType * model_container_type,
|
||||||
|
const FT & field_type, ModelConnector * model_connector, ModelEnv * model_env, IsContainerByValueRenameMe * foo)
|
||||||
|
{
|
||||||
|
put_field_name_and_table_if_needed(field_name, field_type, model_env);
|
||||||
|
put_name_value_separator();
|
||||||
|
put_field_value_list(field_value, model_container_type, field_type, model_connector, model_env, foo);
|
||||||
|
put_name_value_separator();
|
||||||
|
put_field_closing_name(field_name, field_type, model_env);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename ModelClass>
|
||||||
|
void put_field_name_and_value_model_and_closing_name(const wchar_t * field_name, ModelClass & field_model, const FT & field_type, ModelEnv * model_env)
|
||||||
|
{
|
||||||
|
put_field_name_and_table_if_needed(field_name, field_type, model_env);
|
||||||
|
put_name_value_separator();
|
||||||
|
generate_from_model(field_model, field_type);
|
||||||
|
put_name_value_separator();
|
||||||
|
put_field_closing_name(field_name, field_type, model_env);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,8 +32,8 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef headerfile_morm_baseobjectwrapper
|
#ifndef headerfile_morm_src_baseobjectwrapper
|
||||||
#define headerfile_morm_baseobjectwrapper
|
#define headerfile_morm_src_baseobjectwrapper
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018-2021, Tomasz Sowa
|
* Copyright (c) 2018-2024, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -50,105 +50,124 @@ Clearer::~Clearer()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Clearer::clear_value(char & field_value)
|
void Clearer::clear_value(char & field_value, const FT & field_type)
|
||||||
{
|
{
|
||||||
field_value = 0;
|
field_value = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Clearer::clear_value(unsigned char & field_value)
|
void Clearer::clear_value(unsigned char & field_value, const FT & field_type)
|
||||||
{
|
{
|
||||||
field_value = 0;
|
field_value = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Clearer::clear_value(wchar_t & field_value)
|
void Clearer::clear_value(wchar_t & field_value, const FT & field_type)
|
||||||
{
|
{
|
||||||
field_value = 0;
|
field_value = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Clearer::clear_value(std::wstring & field_value)
|
void Clearer::clear_value(std::wstring & field_value, const FT & field_type)
|
||||||
{
|
{
|
||||||
field_value.clear();
|
if( field_type.is_numeric() )
|
||||||
|
{
|
||||||
|
field_value = L"0";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
field_value.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Clearer::clear_value(std::string & field_value)
|
void Clearer::clear_value(std::string & field_value, const FT & field_type)
|
||||||
{
|
{
|
||||||
field_value.clear();
|
if( field_type.is_numeric() )
|
||||||
|
{
|
||||||
|
field_value = "0";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
field_value.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Clearer::clear_value(bool & field_value)
|
void Clearer::clear_value(bool & field_value, const FT & field_type)
|
||||||
{
|
{
|
||||||
field_value = false;
|
field_value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Clearer::clear_value(short & field_value)
|
void Clearer::clear_value(short & field_value, const FT & field_type)
|
||||||
{
|
{
|
||||||
field_value = 0;
|
field_value = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Clearer::clear_value(unsigned short & field_value)
|
void Clearer::clear_value(unsigned short & field_value, const FT & field_type)
|
||||||
{
|
{
|
||||||
field_value = 0;
|
field_value = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Clearer::clear_value(int & field_value)
|
void Clearer::clear_value(int & field_value, const FT & field_type)
|
||||||
{
|
{
|
||||||
field_value = 0;
|
field_value = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Clearer::clear_value(unsigned int & field_value)
|
void Clearer::clear_value(unsigned int & field_value, const FT & field_type)
|
||||||
{
|
{
|
||||||
field_value = 0;
|
field_value = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Clearer::clear_value(long & field_value)
|
void Clearer::clear_value(long & field_value, const FT & field_type)
|
||||||
{
|
{
|
||||||
field_value = 0;
|
field_value = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Clearer::clear_value(unsigned long & field_value)
|
void Clearer::clear_value(unsigned long & field_value, const FT & field_type)
|
||||||
{
|
{
|
||||||
field_value = 0;
|
field_value = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Clearer::clear_value(long long & field_value)
|
void Clearer::clear_value(long long & field_value, const FT & field_type)
|
||||||
{
|
{
|
||||||
field_value = 0;
|
field_value = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Clearer::clear_value(unsigned long long & field_value)
|
void Clearer::clear_value(unsigned long long & field_value, const FT & field_type)
|
||||||
{
|
{
|
||||||
field_value = 0;
|
field_value = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Clearer::clear_value(float & field_value)
|
void Clearer::clear_value(float & field_value, const FT & field_type)
|
||||||
{
|
{
|
||||||
field_value = 0.0f;
|
field_value = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Clearer::clear_value(double & field_value)
|
void Clearer::clear_value(double & field_value, const FT & field_type)
|
||||||
{
|
{
|
||||||
field_value = 0.0;
|
field_value = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Clearer::clear_value(long double & field_value)
|
void Clearer::clear_value(long double & field_value, const FT & field_type)
|
||||||
{
|
{
|
||||||
field_value = 0.0;
|
field_value = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Clearer::clear_value(pt::Date & field_value)
|
void Clearer::clear_value(pt::Date & field_value, const FT & field_type)
|
||||||
{
|
{
|
||||||
field_value.Clear();
|
field_value.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Clearer::clear_value(pt::Space & field_value)
|
void Clearer::clear_value(pt::Space & field_value, const FT & field_type)
|
||||||
{
|
{
|
||||||
field_value.clear();
|
field_value.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Clearer::clear_model(Model & field_value)
|
void Clearer::clear_value(pt::Stream & field_value, const FT & field_type)
|
||||||
|
{
|
||||||
|
field_value.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Clearer::clear_model(Model & field_value, const FT & field_type)
|
||||||
{
|
{
|
||||||
field_value.clear();
|
field_value.clear();
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018-2021, Tomasz Sowa
|
* Copyright (c) 2018-2024, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -32,12 +32,13 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef headerfile_morm_clearer
|
#ifndef headerfile_morm_src_clearer
|
||||||
#define headerfile_morm_clearer
|
#define headerfile_morm_src_clearer
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "date/date.h"
|
#include "date/date.h"
|
||||||
#include "space/space.h"
|
#include "space/space.h"
|
||||||
|
#include "ft.h"
|
||||||
|
|
||||||
|
|
||||||
namespace morm
|
namespace morm
|
||||||
|
@ -52,30 +53,31 @@ public:
|
||||||
Clearer();
|
Clearer();
|
||||||
virtual ~Clearer();
|
virtual ~Clearer();
|
||||||
|
|
||||||
virtual void clear_value(char & field_value);
|
virtual void clear_value(char & field_value, const FT & field_type);
|
||||||
virtual void clear_value(unsigned char & field_value);
|
virtual void clear_value(unsigned char & field_value, const FT & field_type);
|
||||||
virtual void clear_value(wchar_t & field_value);
|
virtual void clear_value(wchar_t & field_value, const FT & field_type);
|
||||||
virtual void clear_value(std::wstring & field_value);
|
virtual void clear_value(std::wstring & field_value, const FT & field_type);
|
||||||
virtual void clear_value(std::string & field_value);
|
virtual void clear_value(std::string & field_value, const FT & field_type);
|
||||||
virtual void clear_value(bool & field_value);
|
virtual void clear_value(bool & field_value, const FT & field_type);
|
||||||
virtual void clear_value(short & field_value);
|
virtual void clear_value(short & field_value, const FT & field_type);
|
||||||
virtual void clear_value(unsigned short & field_value);
|
virtual void clear_value(unsigned short & field_value, const FT & field_type);
|
||||||
virtual void clear_value(int & field_value);
|
virtual void clear_value(int & field_value, const FT & field_type);
|
||||||
virtual void clear_value(unsigned int & field_value);
|
virtual void clear_value(unsigned int & field_value, const FT & field_type);
|
||||||
virtual void clear_value(long & field_value);
|
virtual void clear_value(long & field_value, const FT & field_type);
|
||||||
virtual void clear_value(unsigned long & field_value);
|
virtual void clear_value(unsigned long & field_value, const FT & field_type);
|
||||||
virtual void clear_value(long long & field_value);
|
virtual void clear_value(long long & field_value, const FT & field_type);
|
||||||
virtual void clear_value(unsigned long long & field_value);
|
virtual void clear_value(unsigned long long & field_value, const FT & field_type);
|
||||||
virtual void clear_value(float & field_value);
|
virtual void clear_value(float & field_value, const FT & field_type);
|
||||||
virtual void clear_value(double & field_value);
|
virtual void clear_value(double & field_value, const FT & field_type);
|
||||||
virtual void clear_value(long double & field_value);
|
virtual void clear_value(long double & field_value, const FT & field_type);
|
||||||
virtual void clear_value(pt::Date & field_value);
|
virtual void clear_value(pt::Date & field_value, const FT & field_type);
|
||||||
virtual void clear_value(pt::Space & field_value);
|
virtual void clear_value(pt::Space & field_value, const FT & field_type);
|
||||||
|
virtual void clear_value(pt::Stream & field_value, const FT & field_type);
|
||||||
|
|
||||||
virtual void clear_model(Model & field_value);
|
virtual void clear_model(Model & field_value, const FT & field_type);
|
||||||
|
|
||||||
template<typename ModelContainer, typename ModelContainerType, typename IsContainerByValueRenameMe>
|
template<typename ModelContainer, typename ModelContainerType, typename IsContainerByValueRenameMe>
|
||||||
void clear_container(ModelContainer & container, ModelContainerType * model_container_type, IsContainerByValueRenameMe * foo)
|
void clear_container(ModelContainer & container, ModelContainerType * model_container_type, IsContainerByValueRenameMe * foo, const FT & field_type)
|
||||||
{
|
{
|
||||||
if constexpr (std::is_base_of<Model, ModelContainerType>())
|
if constexpr (std::is_base_of<Model, ModelContainerType>())
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
/*
|
||||||
|
* This file is a part of morm
|
||||||
|
* and is distributed under the 2-Clause BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023-2024, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "csvconnector.h"
|
||||||
|
#include "csvexpression.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace morm
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
CSVConnector::CSVConnector()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CSVConnector::allocate_default_expression()
|
||||||
|
{
|
||||||
|
deallocate_expression();
|
||||||
|
flat_expression = new CSVExpression();
|
||||||
|
expression_allocated = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CSVConnector::to_text(pt::Stream & stream, Model & model, Export exp)
|
||||||
|
{
|
||||||
|
allocate_default_expression_if_needed();
|
||||||
|
|
||||||
|
if( flat_expression )
|
||||||
|
{
|
||||||
|
flat_expression->clear();
|
||||||
|
|
||||||
|
if( exp.is_export_headers() )
|
||||||
|
{
|
||||||
|
flat_expression->set_work_mode(MORM_WORK_MODE_MODEL_FIELDS);
|
||||||
|
flat_expression->set_output_type(MORM_OUTPUT_TYPE_FIELDS_RECURSIVE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
flat_expression->set_work_mode(MORM_WORK_MODE_MODEL_VALUES);
|
||||||
|
}
|
||||||
|
|
||||||
|
flat_expression->allow_to_use_prefix(false);
|
||||||
|
flat_expression->generate_from_model(stream, model);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
/*
|
||||||
|
* This file is a part of morm
|
||||||
|
* and is distributed under the 2-Clause BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023-2024, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef headerfile_morm_src_csvconnector
|
||||||
|
#define headerfile_morm_src_csvconnector
|
||||||
|
|
||||||
|
#include "flatconnector.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace morm
|
||||||
|
{
|
||||||
|
|
||||||
|
class CSVConnector : public FlatConnector
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
CSVConnector();
|
||||||
|
|
||||||
|
|
||||||
|
void to_text(pt::Stream & stream, Model & model, Export exp) override;
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
void allocate_default_expression() override;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,97 @@
|
||||||
|
/*
|
||||||
|
* This file is a part of morm
|
||||||
|
* and is distributed under the 2-Clause BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023-2024, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "csvexpression.h"
|
||||||
|
#include "morm_types.h"
|
||||||
|
#include "convert/misc.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace morm
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
bool CSVExpression::can_field_list_be_generated(const FT &)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CSVExpression::field_before()
|
||||||
|
{
|
||||||
|
BaseExpression::field_before();
|
||||||
|
|
||||||
|
if( !is_first_field )
|
||||||
|
{
|
||||||
|
(*out_stream) << ",";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CSVExpression::after_generate_from_model()
|
||||||
|
{
|
||||||
|
(*out_stream) << ",";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CSVExpression::before_field_name()
|
||||||
|
{
|
||||||
|
(*out_stream) << '"';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CSVExpression::after_field_name()
|
||||||
|
{
|
||||||
|
(*out_stream) << '"';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CSVExpression::before_field_value_string(const FT & field_type, ModelEnv * model_env)
|
||||||
|
{
|
||||||
|
(*out_stream) << '"';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CSVExpression::after_field_value_string(const FT & field_type, ModelEnv * model_env)
|
||||||
|
{
|
||||||
|
(*out_stream) << '"';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool CSVExpression::esc_char(char32_t val, pt::Stream & stream, const FT & field_type, ModelEnv * model_env)
|
||||||
|
{
|
||||||
|
return pt::try_esc_to_csv(val, stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
/*
|
||||||
|
* This file is a part of morm
|
||||||
|
* and is distributed under the 2-Clause BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023-2024, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef headerfile_morm_src_csvexpression
|
||||||
|
#define headerfile_morm_src_csvexpression
|
||||||
|
|
||||||
|
#include "flatexpression.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace morm
|
||||||
|
{
|
||||||
|
|
||||||
|
class CSVExpression : public FlatExpression
|
||||||
|
{
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
bool can_field_list_be_generated(const FT &) override;
|
||||||
|
void field_before() override;
|
||||||
|
void after_generate_from_model() override;
|
||||||
|
|
||||||
|
void before_field_name() override;
|
||||||
|
void after_field_name() override;
|
||||||
|
|
||||||
|
void before_field_value_string(const FT & field_type, ModelEnv * model_env) override;
|
||||||
|
void after_field_value_string(const FT & field_type, ModelEnv * model_env) override;
|
||||||
|
|
||||||
|
using BaseExpression::esc;
|
||||||
|
bool esc_char(char32_t val, pt::Stream & stream, const FT & field_type, ModelEnv * model_env) override;
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
353
src/cursor.h
353
src/cursor.h
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018-2021, Tomasz Sowa
|
* Copyright (c) 2018-2024, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -32,11 +32,15 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef headerfile_morm_cursor
|
#ifndef headerfile_morm_src_cursor
|
||||||
#define headerfile_morm_cursor
|
#define headerfile_morm_src_cursor
|
||||||
|
|
||||||
#include "queryresult.h"
|
#include "queryresult.h"
|
||||||
#include "modelconnector.h"
|
#include "modelconnector.h"
|
||||||
|
#include "modeldata.h"
|
||||||
|
#include "select.h"
|
||||||
|
#include "modelenv.h"
|
||||||
|
#include "dbexpression.h"
|
||||||
|
|
||||||
|
|
||||||
namespace morm
|
namespace morm
|
||||||
|
@ -63,7 +67,11 @@ public:
|
||||||
has_autogenerated_select = c.has_autogenerated_select;
|
has_autogenerated_select = c.has_autogenerated_select;
|
||||||
use_table_prefix_for_fetching = c.use_table_prefix_for_fetching;
|
use_table_prefix_for_fetching = c.use_table_prefix_for_fetching;
|
||||||
query_result = c.query_result;
|
query_result = c.query_result;
|
||||||
select_status = c.select_status;
|
last_query_status = c.last_query_status;
|
||||||
|
select_flags = c.select_flags;
|
||||||
|
rows_counter = c.rows_counter;
|
||||||
|
cursor_name = c.cursor_name;
|
||||||
|
scroll_cursor = c.scroll_cursor;
|
||||||
|
|
||||||
if( query_result )
|
if( query_result )
|
||||||
{
|
{
|
||||||
|
@ -105,7 +113,11 @@ public:
|
||||||
cursor_helper.clear();
|
cursor_helper.clear();
|
||||||
finder_helper.clear();
|
finder_helper.clear();
|
||||||
query_result = nullptr;
|
query_result = nullptr;
|
||||||
select_status = false;
|
last_query_status = false;
|
||||||
|
select_flags = Select::default_type;
|
||||||
|
rows_counter = 0;
|
||||||
|
cursor_name.clear();
|
||||||
|
scroll_cursor = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -127,9 +139,9 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
virtual void set_select_status(bool select_status)
|
virtual void set_last_query_status(bool status)
|
||||||
{
|
{
|
||||||
this->select_status = select_status;
|
this->last_query_status = status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -145,6 +157,18 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virtual void set_select_flags(const Select & select_flags)
|
||||||
|
{
|
||||||
|
this->select_flags = select_flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virtual void set_rows_counter_column_name(const std::wstring & column_name)
|
||||||
|
{
|
||||||
|
this->rows_counter_column_name = column_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
virtual QueryResult * get_query_result()
|
virtual QueryResult * get_query_result()
|
||||||
{
|
{
|
||||||
return query_result;
|
return query_result;
|
||||||
|
@ -155,7 +179,7 @@ public:
|
||||||
{
|
{
|
||||||
bool has = false;
|
bool has = false;
|
||||||
|
|
||||||
if( model_connector && query_result && query_result->has_db_result() && select_status )
|
if( model_connector && query_result && query_result->has_db_result() && last_query_status )
|
||||||
{
|
{
|
||||||
has = query_result->cur_row < query_result->result_rows;
|
has = query_result->cur_row < query_result->result_rows;
|
||||||
}
|
}
|
||||||
|
@ -164,6 +188,24 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virtual void prepare_model_env_for_new_object(ModelEnv & model_env)
|
||||||
|
{
|
||||||
|
model_env.cursor_helper = &cursor_helper;
|
||||||
|
model_env.finder_helper = &finder_helper;
|
||||||
|
model_env.select_flags = select_flags;
|
||||||
|
model_env.rows_counter = 0;
|
||||||
|
model_env.model_data = model_data;
|
||||||
|
|
||||||
|
if( model_env.select_flags.is_with_rows_counter() )
|
||||||
|
{
|
||||||
|
if( cursor_helper.current_row == 0 )
|
||||||
|
{
|
||||||
|
model_env.rows_counter_column_name = rows_counter_column_name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
virtual bool get(ModelClass & result)
|
virtual bool get(ModelClass & result)
|
||||||
{
|
{
|
||||||
bool res = false;
|
bool res = false;
|
||||||
|
@ -177,34 +219,37 @@ public:
|
||||||
|
|
||||||
if( db_connector )
|
if( db_connector )
|
||||||
{
|
{
|
||||||
ModelEnv model_env_local;
|
|
||||||
result.model_env = &model_env_local;
|
|
||||||
result.model_env->cursor_helper = &cursor_helper;
|
|
||||||
result.model_env->finder_helper = &finder_helper;
|
|
||||||
result.model_env->model = &result;
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
ModelEnv model_env_local;
|
||||||
|
result.model_env = &model_env_local;
|
||||||
|
result.model_env->model = &result;
|
||||||
|
result.model_env->model_data = model_data;
|
||||||
|
|
||||||
finder_helper.clear(); // at the moment used only for calculating table prefixes (indices)
|
finder_helper.clear(); // at the moment used only for calculating table prefixes (indices)
|
||||||
cursor_helper.clear();
|
cursor_helper.clear();
|
||||||
cursor_helper.query_result = query_result;
|
cursor_helper.query_result = query_result;
|
||||||
cursor_helper.has_autogenerated_select = has_autogenerated_select;
|
cursor_helper.has_autogenerated_select = has_autogenerated_select;
|
||||||
cursor_helper.use_table_prefix_for_fetching_values = use_table_prefix_for_fetching;
|
cursor_helper.use_table_prefix_for_fetching_values = use_table_prefix_for_fetching;
|
||||||
result.model_env->model_data = model_data;
|
cursor_helper.current_row = 0;
|
||||||
|
|
||||||
|
prepare_model_env_for_new_object(model_env_local);
|
||||||
|
|
||||||
if( !cursor_helper.has_autogenerated_select && cursor_helper.use_table_prefix_for_fetching_values )
|
if( !cursor_helper.has_autogenerated_select && cursor_helper.use_table_prefix_for_fetching_values )
|
||||||
{
|
{
|
||||||
|
result.table();
|
||||||
result.model_env->add_table_name_to_finder_helper();
|
result.model_env->add_table_name_to_finder_helper();
|
||||||
}
|
}
|
||||||
|
|
||||||
result.before_select();
|
result.before_select();
|
||||||
res = select_status;
|
res = last_query_status;
|
||||||
|
|
||||||
if( res )
|
if( res )
|
||||||
{
|
{
|
||||||
if( query_result->cur_row < query_result->result_rows )
|
if( query_result->cur_row < query_result->result_rows )
|
||||||
{
|
{
|
||||||
result.map_values_from_query();
|
result.map_values_from_query();
|
||||||
|
rows_counter = model_env_local.rows_counter;
|
||||||
|
|
||||||
if( result.found() )
|
if( result.found() )
|
||||||
{
|
{
|
||||||
|
@ -273,6 +318,7 @@ public:
|
||||||
return get_list_generic(result, clear_list);
|
return get_list_generic(result, clear_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
virtual std::vector<ModelClass> get_vector()
|
virtual std::vector<ModelClass> get_vector()
|
||||||
{
|
{
|
||||||
std::vector<ModelClass> result;
|
std::vector<ModelClass> result;
|
||||||
|
@ -282,6 +328,143 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virtual size_t get_rows_counter()
|
||||||
|
{
|
||||||
|
return rows_counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virtual void set_cursor_name(pt::Stream & cursor_name)
|
||||||
|
{
|
||||||
|
this->cursor_name.clear();
|
||||||
|
this->cursor_name << cursor_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virtual void set_scroll_cursor(bool scroll_cursor)
|
||||||
|
{
|
||||||
|
this->scroll_cursor = scroll_cursor;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virtual Cursor & fetch(const char * fetch_str)
|
||||||
|
{
|
||||||
|
last_query_status = false;
|
||||||
|
rows_counter = 0;
|
||||||
|
|
||||||
|
if( query_result )
|
||||||
|
{
|
||||||
|
query_result->clear();
|
||||||
|
|
||||||
|
if( model_connector )
|
||||||
|
{
|
||||||
|
DbConnector * db_connector = model_connector->get_db_connector();
|
||||||
|
|
||||||
|
if( db_connector )
|
||||||
|
{
|
||||||
|
bool status = db_connector->query_select(fetch_str, *query_result);
|
||||||
|
last_query_status = status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virtual Cursor & fetch(pt::TextStream & str)
|
||||||
|
{
|
||||||
|
if( str.size() < 256 )
|
||||||
|
{
|
||||||
|
char str_buf[256];
|
||||||
|
|
||||||
|
if( str.to_str(str_buf, sizeof(str_buf) / sizeof(char)) )
|
||||||
|
{
|
||||||
|
fetch(str_buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
put_cursor_fetch_query_too_long();
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virtual Cursor & fetch(pt::WTextStream & str)
|
||||||
|
{
|
||||||
|
if( str.size() < 256 )
|
||||||
|
{
|
||||||
|
char str_buf[256];
|
||||||
|
|
||||||
|
if( str.to_str(str_buf, sizeof(str_buf) / sizeof(char)) )
|
||||||
|
{
|
||||||
|
fetch(str_buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
put_cursor_fetch_query_too_long();
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virtual Cursor & fetch_next()
|
||||||
|
{
|
||||||
|
return fetch(&DbExpression::prepare_fetch_next_query);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virtual Cursor & fetch_prior()
|
||||||
|
{
|
||||||
|
return fetch(&DbExpression::prepare_fetch_prior_query);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virtual Cursor & fetch_first()
|
||||||
|
{
|
||||||
|
return fetch(&DbExpression::prepare_fetch_first_query);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virtual Cursor & fetch_last()
|
||||||
|
{
|
||||||
|
return fetch(&DbExpression::prepare_fetch_last_query);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virtual Cursor & fetch_absolute(long position)
|
||||||
|
{
|
||||||
|
return fetch(&DbExpression::prepare_fetch_absotule_query, position);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virtual Cursor & fetch_relative(long position)
|
||||||
|
{
|
||||||
|
return fetch(&DbExpression::prepare_fetch_relative_query, position);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virtual Cursor & fetch_forward_count(size_t len)
|
||||||
|
{
|
||||||
|
return fetch(&DbExpression::prepare_fetch_forward_count_query, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virtual Cursor & fetch_backward_count(size_t len)
|
||||||
|
{
|
||||||
|
return fetch(&DbExpression::prepare_fetch_backward_count_query, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virtual Cursor & fetch_all()
|
||||||
|
{
|
||||||
|
return fetch(&DbExpression::prepare_fetch_all_query);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
@ -292,8 +475,98 @@ protected:
|
||||||
CursorHelper cursor_helper;
|
CursorHelper cursor_helper;
|
||||||
FinderHelper finder_helper; // may CursorHelper and FinderHelper should be one class?
|
FinderHelper finder_helper; // may CursorHelper and FinderHelper should be one class?
|
||||||
QueryResult * query_result;
|
QueryResult * query_result;
|
||||||
bool select_status;
|
bool last_query_status;
|
||||||
|
Select select_flags;
|
||||||
|
size_t rows_counter;
|
||||||
|
std::wstring rows_counter_column_name;
|
||||||
|
pt::TextStream cursor_name;
|
||||||
|
bool scroll_cursor;
|
||||||
|
|
||||||
|
typedef void (DbExpression::*prepare_fetch_method_type)(const pt::Stream & cursor_name, pt::Stream & out_stream);
|
||||||
|
typedef void (DbExpression::*prepare_fetch_long_count_method_type)(const pt::Stream & cursor_name, long count, pt::Stream & out_stream);
|
||||||
|
typedef void (DbExpression::*prepare_fetch_size_count_method_type)(const pt::Stream & cursor_name, size_t count, pt::Stream & out_stream);
|
||||||
|
|
||||||
|
|
||||||
|
DbExpression * get_db_expression()
|
||||||
|
{
|
||||||
|
if( model_connector )
|
||||||
|
{
|
||||||
|
DbConnector * db_connector = model_connector->get_db_connector();
|
||||||
|
|
||||||
|
if( db_connector )
|
||||||
|
{
|
||||||
|
return db_connector->get_expression();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virtual Cursor & fetch(prepare_fetch_method_type prepare_fetch_method)
|
||||||
|
{
|
||||||
|
if( !cursor_name.empty() )
|
||||||
|
{
|
||||||
|
DbExpression * db_expression = get_db_expression();
|
||||||
|
|
||||||
|
if( db_expression )
|
||||||
|
{
|
||||||
|
pt::TextStream str;
|
||||||
|
(db_expression->*prepare_fetch_method)(cursor_name, str);
|
||||||
|
fetch(str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
put_cursor_not_declared_log();
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virtual Cursor & fetch(prepare_fetch_long_count_method_type prepare_fetch_method, long count)
|
||||||
|
{
|
||||||
|
if( !cursor_name.empty() )
|
||||||
|
{
|
||||||
|
DbExpression * db_expression = get_db_expression();
|
||||||
|
|
||||||
|
if( db_expression )
|
||||||
|
{
|
||||||
|
pt::TextStream str;
|
||||||
|
(db_expression->*prepare_fetch_method)(cursor_name, count, str);
|
||||||
|
fetch(str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
put_cursor_not_declared_log();
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virtual Cursor & fetch(prepare_fetch_size_count_method_type prepare_fetch_method, size_t count)
|
||||||
|
{
|
||||||
|
if( !cursor_name.empty() )
|
||||||
|
{
|
||||||
|
DbExpression * db_expression = get_db_expression();
|
||||||
|
|
||||||
|
if( db_expression )
|
||||||
|
{
|
||||||
|
pt::TextStream str;
|
||||||
|
(db_expression->*prepare_fetch_method)(cursor_name, count, str);
|
||||||
|
fetch(str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
put_cursor_not_declared_log();
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename ContainerType>
|
template<typename ContainerType>
|
||||||
|
@ -312,7 +585,7 @@ protected:
|
||||||
|
|
||||||
if( db_connector )
|
if( db_connector )
|
||||||
{
|
{
|
||||||
res = select_status;
|
res = last_query_status;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -359,24 +632,30 @@ protected:
|
||||||
cursor_helper.query_result = query_result;
|
cursor_helper.query_result = query_result;
|
||||||
cursor_helper.has_autogenerated_select = has_autogenerated_select;
|
cursor_helper.has_autogenerated_select = has_autogenerated_select;
|
||||||
cursor_helper.use_table_prefix_for_fetching_values = use_table_prefix_for_fetching;
|
cursor_helper.use_table_prefix_for_fetching_values = use_table_prefix_for_fetching;
|
||||||
|
cursor_helper.current_row = query_result->cur_row;
|
||||||
|
|
||||||
added_model.set_connector(model_connector);
|
added_model.set_connector(model_connector);
|
||||||
added_model.clear();
|
added_model.clear();
|
||||||
|
|
||||||
|
prepare_model_env_for_new_object(model_env_local);
|
||||||
added_model.model_env = &model_env_local;
|
added_model.model_env = &model_env_local;
|
||||||
added_model.model_env->cursor_helper = &cursor_helper;
|
|
||||||
added_model.model_env->finder_helper = &finder_helper;
|
|
||||||
added_model.model_env->model_data = model_data;
|
|
||||||
added_model.model_env->model = &added_model;
|
added_model.model_env->model = &added_model;
|
||||||
|
added_model.model_env->model_data = model_data;
|
||||||
|
|
||||||
if( !cursor_helper.has_autogenerated_select && cursor_helper.use_table_prefix_for_fetching_values )
|
if( !cursor_helper.has_autogenerated_select && cursor_helper.use_table_prefix_for_fetching_values )
|
||||||
{
|
{
|
||||||
|
added_model.table();
|
||||||
added_model.model_env->add_table_name_to_finder_helper();
|
added_model.model_env->add_table_name_to_finder_helper();
|
||||||
}
|
}
|
||||||
|
|
||||||
added_model.before_select();
|
added_model.before_select();
|
||||||
added_model.map_values_from_query();
|
added_model.map_values_from_query();
|
||||||
|
|
||||||
|
if( model_env_local.select_flags.is_with_rows_counter() && query_result->cur_row == 0 )
|
||||||
|
{
|
||||||
|
rows_counter = model_env_local.rows_counter;
|
||||||
|
}
|
||||||
|
|
||||||
if( added_model.found() )
|
if( added_model.found() )
|
||||||
{
|
{
|
||||||
added_model.after_select();
|
added_model.after_select();
|
||||||
|
@ -395,6 +674,38 @@ protected:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pt::Log * get_logger()
|
||||||
|
{
|
||||||
|
if( model_connector )
|
||||||
|
{
|
||||||
|
return model_connector->get_logger();
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void put_log(pt::Log::Manipulators level, const char * msg)
|
||||||
|
{
|
||||||
|
pt::Log * plog = get_logger();
|
||||||
|
|
||||||
|
if( plog )
|
||||||
|
{
|
||||||
|
(*plog) << level << msg << pt::Log::logend;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void put_cursor_fetch_query_too_long()
|
||||||
|
{
|
||||||
|
put_log(pt::Log::log2, "Morm: error: a fetch query should be less than 256 characters long");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void put_cursor_not_declared_log()
|
||||||
|
{
|
||||||
|
put_log(pt::Log::log2, "Morm: you cannot use fetch* methods, a cursor has not been declared, use Finder::declare_cursor(...) to declare a cursor");
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -32,8 +32,8 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef headerfile_morm_cursorhelper
|
#ifndef headerfile_morm_src_cursorhelper
|
||||||
#define headerfile_morm_cursorhelper
|
#define headerfile_morm_src_cursorhelper
|
||||||
|
|
||||||
#include "queryresult.h"
|
#include "queryresult.h"
|
||||||
|
|
||||||
|
@ -48,6 +48,7 @@ public:
|
||||||
bool has_autogenerated_select;
|
bool has_autogenerated_select;
|
||||||
QueryResult * query_result;
|
QueryResult * query_result;
|
||||||
int current_column;
|
int current_column;
|
||||||
|
size_t current_row;
|
||||||
|
|
||||||
// used if has_autogenerated_select is equal false
|
// used if has_autogenerated_select is equal false
|
||||||
// if use_table_prefix_for_fetching_values is true we find a column in such a form: table.column_name instead of just column_name
|
// if use_table_prefix_for_fetching_values is true we find a column in such a form: table.column_name instead of just column_name
|
||||||
|
@ -71,6 +72,7 @@ public:
|
||||||
has_autogenerated_select = false;
|
has_autogenerated_select = false;
|
||||||
query_result = nullptr;
|
query_result = nullptr;
|
||||||
current_column = 0;
|
current_column = 0;
|
||||||
|
current_row = 0;
|
||||||
use_table_prefix_for_fetching_values = false;
|
use_table_prefix_for_fetching_values = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018-2021, Tomasz Sowa
|
* Copyright (c) 2018-2024, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -51,16 +51,10 @@ DbConnector::DbConnector()
|
||||||
expression_allocated = false;
|
expression_allocated = false;
|
||||||
log = nullptr;
|
log = nullptr;
|
||||||
log_queries = false;
|
log_queries = false;
|
||||||
|
transaction_index = 0;
|
||||||
|
transaction_group = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DbConnector::DbConnector(const DbConnector &)
|
|
||||||
{
|
|
||||||
db_expression = nullptr;
|
|
||||||
expression_allocated = false;
|
|
||||||
log = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
DbConnector::~DbConnector()
|
DbConnector::~DbConnector()
|
||||||
{
|
{
|
||||||
deallocate_expression();
|
deallocate_expression();
|
||||||
|
@ -85,7 +79,7 @@ void DbConnector::set_log_queries(bool log_queries)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool DbConnector::query(const pt::TextStream & stream)
|
bool DbConnector::query(const pt::Stream & stream)
|
||||||
{
|
{
|
||||||
std::unique_ptr<QueryResult> query_result_ptr(create_query_result());
|
std::unique_ptr<QueryResult> query_result_ptr(create_query_result());
|
||||||
return query(stream, *query_result_ptr);
|
return query(stream, *query_result_ptr);
|
||||||
|
@ -107,7 +101,7 @@ bool DbConnector::query(const char * query_str)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool DbConnector::query(const pt::TextStream & stream, QueryResult & query_result)
|
bool DbConnector::query(const pt::Stream & stream, QueryResult & query_result)
|
||||||
{
|
{
|
||||||
std::string query_str;
|
std::string query_str;
|
||||||
stream.to_str(query_str);
|
stream.to_str(query_str);
|
||||||
|
@ -124,7 +118,7 @@ bool DbConnector::query(const std::string & query_str, QueryResult & query_resul
|
||||||
|
|
||||||
bool DbConnector::query(const char * query_str, QueryResult & query_result)
|
bool DbConnector::query(const char * query_str, QueryResult & query_result)
|
||||||
{
|
{
|
||||||
// do query
|
// do the query
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,28 +144,248 @@ bool DbConnector::query_remove(const char * query_str, QueryResult & query_resul
|
||||||
return query(query_str, query_result);
|
return query(query_str, query_result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DbConnector::query_declare_cursor(const char * query_str, QueryResult & query_result)
|
||||||
|
{
|
||||||
|
return query(query_str, query_result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool DbConnector::query_select(const pt::TextStream & stream, QueryResult & query_result)
|
|
||||||
|
bool DbConnector::query_select(const pt::Stream & stream, QueryResult & query_result)
|
||||||
{
|
{
|
||||||
return query(stream, query_result);
|
return query(stream, query_result);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DbConnector::query_update(const pt::TextStream & stream, QueryResult & query_result)
|
bool DbConnector::query_update(const pt::Stream & stream, QueryResult & query_result)
|
||||||
{
|
{
|
||||||
return query(stream, query_result);
|
return query(stream, query_result);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DbConnector::query_insert(const pt::TextStream & stream, QueryResult & query_result)
|
bool DbConnector::query_insert(const pt::Stream & stream, QueryResult & query_result)
|
||||||
{
|
{
|
||||||
return query(stream, query_result);
|
return query(stream, query_result);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DbConnector::query_remove(const pt::TextStream & stream, QueryResult & query_result)
|
bool DbConnector::query_remove(const pt::Stream & stream, QueryResult & query_result)
|
||||||
{
|
{
|
||||||
return query(stream, query_result);
|
return query(stream, query_result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DbConnector::query_declare_cursor(const pt::Stream & stream, QueryResult & query_result)
|
||||||
|
{
|
||||||
|
return query(stream, query_result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool DbConnector::begin()
|
||||||
|
{
|
||||||
|
bool status = false;
|
||||||
|
|
||||||
|
if( transaction_index > 0 )
|
||||||
|
{
|
||||||
|
pt::TextStream str;
|
||||||
|
str << "SAVEPOINT savepoint_" << transaction_index;
|
||||||
|
status = DbConnector::query(str);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
status = DbConnector::query("BEGIN");
|
||||||
|
}
|
||||||
|
|
||||||
|
if( status )
|
||||||
|
{
|
||||||
|
transaction_index += 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( log )
|
||||||
|
{
|
||||||
|
(*log) << pt::Log::log1 << "Morm: I cannot start a transaction" << pt::Log::logend;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool DbConnector::begin_if_needed()
|
||||||
|
{
|
||||||
|
bool status = true;
|
||||||
|
|
||||||
|
if( transaction_index == 0 )
|
||||||
|
{
|
||||||
|
status = begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool DbConnector::rollback()
|
||||||
|
{
|
||||||
|
return rollback(transaction_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool DbConnector::commit()
|
||||||
|
{
|
||||||
|
return commit(transaction_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool DbConnector::rollback_one_transaction(size_t index)
|
||||||
|
{
|
||||||
|
bool status = false;
|
||||||
|
|
||||||
|
if( index > 1 )
|
||||||
|
{
|
||||||
|
pt::TextStream str;
|
||||||
|
str << "ROLLBACK TO SAVEPOINT savepoint_" << (index - 1);
|
||||||
|
status = DbConnector::query(str);
|
||||||
|
transaction_index = index - 1; // decrement it even if rollback failed
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if( index == 1 )
|
||||||
|
{
|
||||||
|
status = DbConnector::query("ROLLBACK");
|
||||||
|
transaction_index = 0;
|
||||||
|
transaction_group += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool DbConnector::rollback(size_t index)
|
||||||
|
{
|
||||||
|
bool status = false;
|
||||||
|
|
||||||
|
if( index == 0 )
|
||||||
|
{
|
||||||
|
if( log )
|
||||||
|
{
|
||||||
|
(*log) << pt::Log::log1 << "Morm: there is no a transaction with zero index - skipping rollback";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if( index > transaction_index )
|
||||||
|
{
|
||||||
|
if( log )
|
||||||
|
{
|
||||||
|
(*log) << pt::Log::log1 << "Morm: transaction";
|
||||||
|
|
||||||
|
if( index > 1 )
|
||||||
|
(*log) << " for savepoint_" << (index-1);
|
||||||
|
|
||||||
|
(*log) << " does not exist - skipping rollback" << pt::Log::logend;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
status = true;
|
||||||
|
|
||||||
|
for(size_t i = transaction_index ; i >= index ; --i)
|
||||||
|
{
|
||||||
|
if( !rollback_one_transaction(i) )
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* return false if at least one rollback failed
|
||||||
|
*/
|
||||||
|
status = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool DbConnector::commit_one_transaction(size_t index)
|
||||||
|
{
|
||||||
|
bool status = false;
|
||||||
|
|
||||||
|
if( index > 1 )
|
||||||
|
{
|
||||||
|
pt::TextStream str;
|
||||||
|
str << "RELEASE SAVEPOINT savepoint_" << (index - 1);
|
||||||
|
status = DbConnector::query(str);
|
||||||
|
transaction_index = index - 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if( index == 1 )
|
||||||
|
{
|
||||||
|
status = DbConnector::query("COMMIT");
|
||||||
|
transaction_index = 0;
|
||||||
|
transaction_group += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool DbConnector::commit(size_t index)
|
||||||
|
{
|
||||||
|
bool status = false;
|
||||||
|
|
||||||
|
if( index == 0 )
|
||||||
|
{
|
||||||
|
if( log )
|
||||||
|
{
|
||||||
|
(*log) << pt::Log::log1 << "Morm: there is no a transaction with zero index - skipping commit";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if( index > transaction_index )
|
||||||
|
{
|
||||||
|
if( log )
|
||||||
|
{
|
||||||
|
(*log) << pt::Log::log1 << "Morm: transaction";
|
||||||
|
|
||||||
|
if( index > 1 )
|
||||||
|
(*log) << " for savepoint_" << (index-1);
|
||||||
|
|
||||||
|
(*log) << " does not exist - skipping commit" << pt::Log::logend;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
status = true;
|
||||||
|
|
||||||
|
for(size_t i = transaction_index ; i >= index ; --i)
|
||||||
|
{
|
||||||
|
if( !commit_one_transaction(i) )
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* return false if at least one commit failed
|
||||||
|
*/
|
||||||
|
status = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
size_t DbConnector::get_transaction_index()
|
||||||
|
{
|
||||||
|
return transaction_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t DbConnector::get_transaction_group()
|
||||||
|
{
|
||||||
|
return transaction_group;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
DbExpression * DbConnector::get_expression()
|
DbExpression * DbConnector::get_expression()
|
||||||
|
@ -181,7 +395,7 @@ DbExpression * DbConnector::get_expression()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DbConnector::generate_select_columns(pt::TextStream & stream, Model & model)
|
void DbConnector::generate_select_columns(pt::Stream & stream, Model & model)
|
||||||
{
|
{
|
||||||
allocate_default_expression_if_needed();
|
allocate_default_expression_if_needed();
|
||||||
|
|
||||||
|
@ -196,7 +410,7 @@ void DbConnector::generate_select_columns(pt::TextStream & stream, Model & model
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DbConnector::generate_insert_query(pt::TextStream & stream, Model & model)
|
void DbConnector::generate_insert_query(pt::Stream & stream, Model & model)
|
||||||
{
|
{
|
||||||
allocate_default_expression_if_needed();
|
allocate_default_expression_if_needed();
|
||||||
|
|
||||||
|
@ -205,7 +419,7 @@ void DbConnector::generate_insert_query(pt::TextStream & stream, Model & model)
|
||||||
db_expression->clear();
|
db_expression->clear();
|
||||||
db_expression->allow_to_use_prefix(false);
|
db_expression->allow_to_use_prefix(false);
|
||||||
|
|
||||||
stream << "insert into ";
|
stream << "INSERT INTO ";
|
||||||
db_expression->schema_table_to_stream(stream, model.model_env->schema_name, model.model_env->table_name);
|
db_expression->schema_table_to_stream(stream, model.model_env->schema_name, model.model_env->table_name);
|
||||||
|
|
||||||
stream << " (";
|
stream << " (";
|
||||||
|
@ -213,7 +427,7 @@ void DbConnector::generate_insert_query(pt::TextStream & stream, Model & model)
|
||||||
db_expression->set_output_type(MORM_OUTPUT_TYPE_DB_INSERT);
|
db_expression->set_output_type(MORM_OUTPUT_TYPE_DB_INSERT);
|
||||||
db_expression->generate_from_model(stream, model);
|
db_expression->generate_from_model(stream, model);
|
||||||
|
|
||||||
stream << ") values (";
|
stream << ") VALUES (";
|
||||||
db_expression->set_work_mode(MORM_WORK_MODE_MODEL_VALUES);
|
db_expression->set_work_mode(MORM_WORK_MODE_MODEL_VALUES);
|
||||||
db_expression->generate_from_model(stream, model);
|
db_expression->generate_from_model(stream, model);
|
||||||
stream << ")";
|
stream << ")";
|
||||||
|
@ -221,7 +435,7 @@ void DbConnector::generate_insert_query(pt::TextStream & stream, Model & model)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DbConnector::generate_update_query(pt::TextStream & stream, Model & model)
|
void DbConnector::generate_update_query(pt::Stream & stream, Model & model)
|
||||||
{
|
{
|
||||||
allocate_default_expression_if_needed();
|
allocate_default_expression_if_needed();
|
||||||
|
|
||||||
|
@ -230,15 +444,15 @@ void DbConnector::generate_update_query(pt::TextStream & stream, Model & model)
|
||||||
db_expression->clear();
|
db_expression->clear();
|
||||||
db_expression->allow_to_use_prefix(false);
|
db_expression->allow_to_use_prefix(false);
|
||||||
|
|
||||||
stream << "update ";
|
stream << "UPDATE ";
|
||||||
db_expression->schema_table_to_stream(stream, model.model_env->schema_name, model.model_env->table_name);
|
db_expression->schema_table_to_stream(stream, model.model_env->schema_name, model.model_env->table_name);
|
||||||
|
|
||||||
stream << " set ";
|
stream << " SET ";
|
||||||
db_expression->set_work_mode(MORM_WORK_MODE_MODEL_FIELDS_VALUES);
|
db_expression->set_work_mode(MORM_WORK_MODE_MODEL_FIELDS_VALUES);
|
||||||
db_expression->set_output_type(MORM_OUTPUT_TYPE_DB_UPDATE);
|
db_expression->set_output_type(MORM_OUTPUT_TYPE_DB_UPDATE);
|
||||||
db_expression->generate_from_model(stream, model);
|
db_expression->generate_from_model(stream, model);
|
||||||
|
|
||||||
stream << " where ";
|
stream << " WHERE ";
|
||||||
db_expression->set_work_mode(MORM_WORK_MODE_MODEL_FIELDS_VALUES);
|
db_expression->set_work_mode(MORM_WORK_MODE_MODEL_FIELDS_VALUES);
|
||||||
db_expression->set_output_type(MORM_OUTPUT_TYPE_DB_PRIMARY_KEY);
|
db_expression->set_output_type(MORM_OUTPUT_TYPE_DB_PRIMARY_KEY);
|
||||||
db_expression->generate_from_model(stream, model);
|
db_expression->generate_from_model(stream, model);
|
||||||
|
@ -246,7 +460,7 @@ void DbConnector::generate_update_query(pt::TextStream & stream, Model & model)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DbConnector::generate_remove_query(pt::TextStream & stream, Model & model)
|
void DbConnector::generate_remove_query(pt::Stream & stream, Model & model)
|
||||||
{
|
{
|
||||||
allocate_default_expression_if_needed();
|
allocate_default_expression_if_needed();
|
||||||
|
|
||||||
|
@ -255,17 +469,18 @@ void DbConnector::generate_remove_query(pt::TextStream & stream, Model & model)
|
||||||
db_expression->clear();
|
db_expression->clear();
|
||||||
db_expression->allow_to_use_prefix(false);
|
db_expression->allow_to_use_prefix(false);
|
||||||
|
|
||||||
stream << "delete from ";
|
stream << "DELETE FROM ";
|
||||||
db_expression->schema_table_to_stream(stream, model.model_env->schema_name, model.model_env->table_name);
|
db_expression->schema_table_to_stream(stream, model.model_env->schema_name, model.model_env->table_name);
|
||||||
|
|
||||||
stream << " where ";
|
stream << " WHERE ";
|
||||||
db_expression->set_work_mode(MORM_WORK_MODE_MODEL_FIELDS_VALUES);
|
db_expression->set_work_mode(MORM_WORK_MODE_MODEL_FIELDS_VALUES);
|
||||||
db_expression->set_output_type(MORM_OUTPUT_TYPE_DB_PRIMARY_KEY);
|
db_expression->set_output_type(MORM_OUTPUT_TYPE_DB_PRIMARY_KEY);
|
||||||
db_expression->generate_from_model(stream, model);
|
db_expression->generate_from_model(stream, model);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DbConnector::insert(pt::TextStream & stream, Model & model)
|
|
||||||
|
bool DbConnector::insert(pt::Stream & stream, Model & model)
|
||||||
{
|
{
|
||||||
std::unique_ptr<QueryResult> query_result_ptr(create_query_result());
|
std::unique_ptr<QueryResult> query_result_ptr(create_query_result());
|
||||||
|
|
||||||
|
@ -274,7 +489,7 @@ bool DbConnector::insert(pt::TextStream & stream, Model & model)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool DbConnector::update(pt::TextStream & stream, Model & model)
|
bool DbConnector::update(pt::Stream & stream, Model & model)
|
||||||
{
|
{
|
||||||
std::unique_ptr<QueryResult> query_result_ptr(create_query_result());
|
std::unique_ptr<QueryResult> query_result_ptr(create_query_result());
|
||||||
|
|
||||||
|
@ -283,7 +498,7 @@ bool DbConnector::update(pt::TextStream & stream, Model & model)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool DbConnector::remove(pt::TextStream & stream, Model & model)
|
bool DbConnector::remove(pt::Stream & stream, Model & model)
|
||||||
{
|
{
|
||||||
std::unique_ptr<QueryResult> query_result_ptr(create_query_result());
|
std::unique_ptr<QueryResult> query_result_ptr(create_query_result());
|
||||||
|
|
||||||
|
@ -313,7 +528,7 @@ void DbConnector::allocate_default_expression_if_needed()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
char DbConnector::unescape_hex_char_part(char hex)
|
unsigned int DbConnector::unescape_hex_char_part(char hex)
|
||||||
{
|
{
|
||||||
if( hex>='0' && hex<='9' )
|
if( hex>='0' && hex<='9' )
|
||||||
{
|
{
|
||||||
|
@ -348,42 +563,110 @@ char DbConnector::unescape_hex_char_part(char hex)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
char DbConnector::unescape_hex_char(char char1, char char2)
|
|
||||||
{
|
|
||||||
int c1 = unescape_hex_char_part(char1);
|
|
||||||
int c2 = unescape_hex_char_part(char2);
|
|
||||||
|
|
||||||
return static_cast<char>(((c1 << 4) | c2));
|
const char * DbConnector::unescape_hex_char(const char * str, size_t len, unsigned int & res)
|
||||||
|
{
|
||||||
|
unsigned int c;
|
||||||
|
res = 0;
|
||||||
|
bool was_log_printed = false;
|
||||||
|
|
||||||
|
for(size_t i = 0 ; i < len ; ++i)
|
||||||
|
{
|
||||||
|
if( *str != 0 )
|
||||||
|
{
|
||||||
|
c = unescape_hex_char_part(*str);
|
||||||
|
str += 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
c = 0;
|
||||||
|
|
||||||
|
if( log && !was_log_printed )
|
||||||
|
{
|
||||||
|
(*log) << pt::Log::log2 << "Morm: the hex string ended unexpectedly, filling the part of the the last character with zeroes"
|
||||||
|
<< pt::Log::logend;
|
||||||
|
was_log_printed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
res = (res << 4) | c;
|
||||||
|
}
|
||||||
|
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DbConnector::unescape_hex_char(const char * str, char & c)
|
||||||
|
{
|
||||||
|
unsigned int res = 0;
|
||||||
|
unescape_hex_char(str, sizeof(char) * 2, res);
|
||||||
|
c = (char)res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DbConnector::unescape_hex_char(const char * str, char32_t & c)
|
||||||
|
{
|
||||||
|
unsigned int res = 0;
|
||||||
|
unescape_hex_char(str, sizeof(wchar_t) * 2, res);
|
||||||
|
c = (char32_t)res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DbConnector::unescape_bin_char(const char * str, char & c)
|
||||||
|
{
|
||||||
|
unescape_hex_char(str, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DbConnector::unescape_bin_char(const char * str, char32_t & c)
|
||||||
|
{
|
||||||
|
unescape_hex_char(str, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DbConnector::unescape_hex_string(const char * str, std::string & out)
|
void DbConnector::unescape_hex_string(const char * str, std::string & out)
|
||||||
{
|
{
|
||||||
for(size_t i=0 ; str[i] != 0 ; i+=2 )
|
unsigned int c = 0;
|
||||||
|
|
||||||
|
while( *str != 0 )
|
||||||
{
|
{
|
||||||
out += unescape_hex_char(str[i], str[i+1]);
|
str = unescape_hex_char(str, sizeof(char) * 2, c);
|
||||||
|
out += (char)c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DbConnector::unescape_hex_string(const char * str, std::wstring & out, const FT & field_type)
|
void DbConnector::unescape_hex_string(const char * str, std::wstring & out)
|
||||||
{
|
{
|
||||||
if( field_type.use_utf8() )
|
unsigned int c = 0;
|
||||||
{
|
|
||||||
size_t len;
|
|
||||||
wchar_t c;
|
|
||||||
|
|
||||||
while( *str != 0 && (len = unescape_hex_char(str, c, field_type)) > 0 )
|
while( *str != 0 )
|
||||||
|
{
|
||||||
|
str = unescape_hex_char(str, sizeof(wchar_t) * 2, c);
|
||||||
|
out += (wchar_t)c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DbConnector::unescape_hex_string(const char * str, pt::Stream & out)
|
||||||
|
{
|
||||||
|
unsigned int c = 0;
|
||||||
|
|
||||||
|
if( out.is_char_stream() )
|
||||||
|
{
|
||||||
|
while( *str != 0 )
|
||||||
{
|
{
|
||||||
out += c;
|
str = unescape_hex_char(str, sizeof(char) * 2, c);
|
||||||
str += len;
|
out << (char)c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
if( out.is_wchar_stream() )
|
||||||
{
|
{
|
||||||
for(size_t i=0 ; str[i] != 0 ; i+=2 )
|
while( *str != 0 )
|
||||||
{
|
{
|
||||||
out += static_cast<wchar_t>(static_cast<unsigned char>(unescape_hex_char(str[i], str[i+1])));
|
str = unescape_hex_char(str, sizeof(wchar_t) * 2, c);
|
||||||
|
out << (wchar_t)c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -395,151 +678,65 @@ void DbConnector::unescape_bin_string(const char * str, std::string & out)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DbConnector::unescape_bin_string(const char * str, std::wstring & out, const FT & field_type)
|
void DbConnector::unescape_bin_string(const char * str, std::wstring & out)
|
||||||
{
|
{
|
||||||
unescape_hex_string(str, out, field_type);
|
unescape_hex_string(str, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// returns how many characters have been provided to utf8_str buffer
|
void DbConnector::unescape_bin_string(const char * str, pt::Stream & out)
|
||||||
// min size of utf8_str should be 5 bytes (max 4 bytes for utf8 sequence + terminating null)
|
|
||||||
size_t DbConnector::unescape_hex_char(const char * value_str, char * utf8_str, size_t utf8_str_max_len)
|
|
||||||
{
|
{
|
||||||
size_t value_str_index = 0;
|
unescape_hex_string(str, out);
|
||||||
size_t utf8_str_index = 0;
|
|
||||||
|
|
||||||
utf8_str[0] = 0;
|
|
||||||
|
|
||||||
while( utf8_str_index + 1 < utf8_str_max_len )
|
|
||||||
{
|
|
||||||
if( value_str[value_str_index] != 0 && value_str[value_str_index+1] != 0 )
|
|
||||||
{
|
|
||||||
utf8_str[utf8_str_index] = unescape_hex_char(value_str[value_str_index], value_str[value_str_index+1]);
|
|
||||||
utf8_str[utf8_str_index+1] = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
value_str_index += 2;
|
|
||||||
utf8_str_index += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return utf8_str_index;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// CHECKME need to be tested
|
|
||||||
// returns how many characters were used from value_str
|
|
||||||
size_t DbConnector::unescape_hex_char(const char * value_str, wchar_t & field_value, const FT & field_type)
|
|
||||||
{
|
|
||||||
size_t len = 0;
|
|
||||||
|
|
||||||
if( field_type.use_utf8() )
|
|
||||||
{
|
|
||||||
char utf8_str[4 + 1]; // max utf8 sequence length + terminating zero
|
|
||||||
size_t utf8_str_len = unescape_hex_char(value_str, utf8_str, sizeof(utf8_str) / sizeof(char));
|
|
||||||
|
|
||||||
int value_int;
|
|
||||||
bool is_correct;
|
|
||||||
len = pt::utf8_to_int(utf8_str, utf8_str_len, value_int, is_correct);
|
|
||||||
len = len * 2;
|
|
||||||
|
|
||||||
if( is_correct )
|
|
||||||
{
|
|
||||||
field_value = static_cast<wchar_t>(value_int);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if( log )
|
|
||||||
{
|
|
||||||
(*log) << pt::Log::log2 << "Morm: incorrect utf-8 sequence (ignoring)" << pt::Log::logend;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if( value_str[0] != 0 && value_str[1] != 0 )
|
|
||||||
{
|
|
||||||
field_value = static_cast<wchar_t>(static_cast<unsigned char>(unescape_hex_char(value_str[0], value_str[1])));
|
|
||||||
len = 2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if( log )
|
|
||||||
{
|
|
||||||
(*log) << pt::Log::log2 << "Morm: unexpected end of string (ignoring)" << pt::Log::logend;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
size_t DbConnector::unescape_bin_char(const char * value_str, wchar_t & field_value, const FT & field_type)
|
|
||||||
{
|
|
||||||
return unescape_hex_char(value_str, field_value, field_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// CHECKME need to be tested
|
|
||||||
void DbConnector::get_value(const char * value_str, char & field_value, const FT & field_type)
|
void DbConnector::get_value(const char * value_str, char & field_value, const FT & field_type)
|
||||||
{
|
{
|
||||||
wchar_t c;
|
if( field_type.is_hexadecimal() )
|
||||||
|
|
||||||
field_value = 0;
|
|
||||||
get_value(value_str, c, field_type);
|
|
||||||
|
|
||||||
if( field_type.use_utf8() )
|
|
||||||
{
|
{
|
||||||
if( c <= 127 )
|
unescape_hex_char(value_str, field_value);
|
||||||
{
|
}
|
||||||
field_value = static_cast<char>(c);
|
else
|
||||||
}
|
if( field_type.is_binary() )
|
||||||
else
|
{
|
||||||
{
|
unescape_bin_char(value_str, field_value);
|
||||||
if( log )
|
|
||||||
{
|
|
||||||
(*log) << pt::Log::log2 << "Morm: a character greater than 127 cannot be stored in char type, code point: "
|
|
||||||
<< (int)c << " '" << c << "'" << pt::Log::logend;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
field_value = static_cast<char>(c);
|
field_value = *value_str;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// CHECKME need to be tested
|
|
||||||
void DbConnector::get_value(const char * value_str, unsigned char & field_value, const FT & field_type)
|
void DbConnector::get_value(const char * value_str, unsigned char & field_value, const FT & field_type)
|
||||||
{
|
{
|
||||||
char tmp_char;
|
char tmp_char;
|
||||||
get_value(value_str, tmp_char, field_type);
|
get_value(value_str, tmp_char, field_type);
|
||||||
|
|
||||||
field_value = static_cast<unsigned char>(tmp_char);
|
field_value = static_cast<unsigned char>(tmp_char);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// CHECKME need to be tested
|
|
||||||
void DbConnector::get_value(const char * value_str, wchar_t & field_value, const FT & field_type)
|
void DbConnector::get_value(const char * value_str, wchar_t & field_value, const FT & field_type)
|
||||||
|
{
|
||||||
|
char32_t tmp;
|
||||||
|
get_value(value_str, tmp, field_type);
|
||||||
|
field_value = static_cast<wchar_t>(tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DbConnector::get_value(const char * value_str, char32_t & field_value, const FT & field_type)
|
||||||
{
|
{
|
||||||
field_value = 0;
|
field_value = 0;
|
||||||
|
|
||||||
if( field_type.is_binary() )
|
|
||||||
{
|
|
||||||
unescape_bin_char(value_str, field_value, field_type);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if( field_type.is_hexadecimal() )
|
if( field_type.is_hexadecimal() )
|
||||||
{
|
{
|
||||||
unescape_hex_char(value_str, field_value, field_type);
|
unescape_hex_char(value_str, field_value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if( field_type.is_binary() )
|
||||||
|
{
|
||||||
|
unescape_bin_char(value_str, field_value);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -552,64 +749,33 @@ void DbConnector::get_value(const char * value_str, wchar_t & field_value, const
|
||||||
|
|
||||||
if( is_correct )
|
if( is_correct )
|
||||||
{
|
{
|
||||||
field_value = static_cast<wchar_t>(value_int);
|
field_value = static_cast<char32_t>(value_int);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// report an error?
|
field_value = 0xFFFD; // U+FFFD "replacement character";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
field_value = static_cast<wchar_t>((unsigned char)*value_str);
|
field_value = static_cast<char32_t>((unsigned char)*value_str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// CHECKME need to be tested
|
|
||||||
void DbConnector::get_value(const char * value_str, std::wstring & field_value, const FT & field_type)
|
|
||||||
{
|
|
||||||
if( field_type.is_binary() )
|
|
||||||
{
|
|
||||||
unescape_bin_string(value_str, field_value, field_type);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if( field_type.is_hexadecimal() )
|
|
||||||
{
|
|
||||||
unescape_hex_string(value_str, field_value, field_type);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if( field_type.use_utf8() )
|
|
||||||
{
|
|
||||||
pt::utf8_to_wide(value_str, field_value);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for(size_t i=0 ; value_str[i] != 0 ; ++i)
|
|
||||||
{
|
|
||||||
field_value += static_cast<wchar_t>(value_str[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// CHECKME need to be tested
|
|
||||||
void DbConnector::get_value(const char * value_str, std::string & field_value, const FT & field_type)
|
void DbConnector::get_value(const char * value_str, std::string & field_value, const FT & field_type)
|
||||||
{
|
{
|
||||||
if( field_type.is_binary() )
|
|
||||||
{
|
|
||||||
unescape_bin_string(value_str, field_value);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if( field_type.is_hexadecimal() )
|
if( field_type.is_hexadecimal() )
|
||||||
{
|
{
|
||||||
unescape_hex_string(value_str, field_value);
|
unescape_hex_string(value_str, field_value);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
if( field_type.is_binary() )
|
||||||
|
{
|
||||||
|
unescape_bin_string(value_str, field_value);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
field_value = value_str;
|
field_value = value_str;
|
||||||
}
|
}
|
||||||
|
@ -622,6 +788,34 @@ void DbConnector::get_value(const char * value_str, std::string_view & field_val
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DbConnector::get_value(const char * value_str, std::wstring & field_value, const FT & field_type)
|
||||||
|
{
|
||||||
|
if( field_type.is_hexadecimal() )
|
||||||
|
{
|
||||||
|
unescape_hex_string(value_str, field_value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if( field_type.is_binary() )
|
||||||
|
{
|
||||||
|
unescape_bin_string(value_str, field_value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( field_type.use_utf8() )
|
||||||
|
{
|
||||||
|
pt::utf8_to_wide(value_str, field_value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(size_t i=0 ; value_str[i] != 0 ; ++i)
|
||||||
|
{
|
||||||
|
field_value += static_cast<wchar_t>((unsigned char)value_str[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void DbConnector::get_value(const char * value_str, bool & field_value, const FT & field_type)
|
void DbConnector::get_value(const char * value_str, bool & field_value, const FT & field_type)
|
||||||
{
|
{
|
||||||
// IMPROVE ME
|
// IMPROVE ME
|
||||||
|
@ -633,56 +827,56 @@ void DbConnector::get_value(const char * value_str, bool & field_value, const FT
|
||||||
void DbConnector::get_value(const char * value_str, short & field_value, const FT & field_type)
|
void DbConnector::get_value(const char * value_str, short & field_value, const FT & field_type)
|
||||||
{
|
{
|
||||||
// IMPROVE ME give some overflow checking
|
// IMPROVE ME give some overflow checking
|
||||||
field_value = (short)pt::Toi(value_str, 10);
|
field_value = (short)pt::to_i(value_str, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DbConnector::get_value(const char * value_str, unsigned short & field_value, const FT & field_type)
|
void DbConnector::get_value(const char * value_str, unsigned short & field_value, const FT & field_type)
|
||||||
{
|
{
|
||||||
// IMPROVE ME give some overflow checking
|
// IMPROVE ME give some overflow checking
|
||||||
field_value = (unsigned short)pt::Toui(value_str, 10);
|
field_value = (unsigned short)pt::to_ui(value_str, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DbConnector::get_value(const char * value_str, int & field_value, const FT & field_type)
|
void DbConnector::get_value(const char * value_str, int & field_value, const FT & field_type)
|
||||||
{
|
{
|
||||||
// IMPROVE ME give some overflow checking
|
// IMPROVE ME give some overflow checking
|
||||||
field_value = pt::Toi(value_str, 10);
|
field_value = pt::to_i(value_str, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DbConnector::get_value(const char * value_str, unsigned int & field_value, const FT & field_type)
|
void DbConnector::get_value(const char * value_str, unsigned int & field_value, const FT & field_type)
|
||||||
{
|
{
|
||||||
// IMPROVE ME give some overflow checking
|
// IMPROVE ME give some overflow checking
|
||||||
field_value = pt::Toui(value_str, 10);
|
field_value = pt::to_ui(value_str, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DbConnector::get_value(const char * value_str, long & field_value, const FT & field_type)
|
void DbConnector::get_value(const char * value_str, long & field_value, const FT & field_type)
|
||||||
{
|
{
|
||||||
// IMPROVE ME give some overflow checking
|
// IMPROVE ME give some overflow checking
|
||||||
field_value = pt::Tol(value_str, 10);
|
field_value = pt::to_l(value_str, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DbConnector::get_value(const char * value_str, unsigned long & field_value, const FT & field_type)
|
void DbConnector::get_value(const char * value_str, unsigned long & field_value, const FT & field_type)
|
||||||
{
|
{
|
||||||
// IMPROVE ME give some overflow checking
|
// IMPROVE ME give some overflow checking
|
||||||
field_value = pt::Toul(value_str, 10);
|
field_value = pt::to_ul(value_str, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DbConnector::get_value(const char * value_str, long long & field_value, const FT & field_type)
|
void DbConnector::get_value(const char * value_str, long long & field_value, const FT & field_type)
|
||||||
{
|
{
|
||||||
// IMPROVE ME give some overflow checking
|
// IMPROVE ME give some overflow checking
|
||||||
field_value = pt::Toll(value_str, 10);
|
field_value = pt::to_ll(value_str, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DbConnector::get_value(const char * value_str, unsigned long long & field_value, const FT & field_type)
|
void DbConnector::get_value(const char * value_str, unsigned long long & field_value, const FT & field_type)
|
||||||
{
|
{
|
||||||
// IMPROVE ME give some overflow checking
|
// IMPROVE ME give some overflow checking
|
||||||
field_value = pt::Toull(value_str, 10);
|
field_value = pt::to_ull(value_str, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -710,7 +904,20 @@ void DbConnector::get_value(const char * value_str, long double & field_value, c
|
||||||
void DbConnector::get_value(const char * value_str, pt::Date & field_value, const FT & field_type)
|
void DbConnector::get_value(const char * value_str, pt::Date & field_value, const FT & field_type)
|
||||||
{
|
{
|
||||||
// IMPROVE ME give some log if parsing failed
|
// IMPROVE ME give some log if parsing failed
|
||||||
field_value.Parse(value_str);
|
|
||||||
|
if( field_type.is_date_only() )
|
||||||
|
{
|
||||||
|
field_value.ParseYearMonthDay(value_str);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if( field_type.is_time_only() )
|
||||||
|
{
|
||||||
|
field_value.ParseHourMinSec(value_str);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
field_value.Parse(value_str, !field_type.is_no_time_zone());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -752,9 +959,39 @@ void DbConnector::get_value(const char * value_str, pt::Space & field_value, con
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DbConnector::get_value(const char * value_str, pt::Stream & field_value, const FT & field_type)
|
||||||
|
{
|
||||||
|
if( field_type.is_hexadecimal() )
|
||||||
|
{
|
||||||
|
unescape_hex_string(value_str, field_value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if( field_type.is_binary() )
|
||||||
|
{
|
||||||
|
unescape_bin_string(value_str, field_value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( field_type.use_utf8() )
|
||||||
|
{
|
||||||
|
pt::utf8_to_wide(value_str, field_value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(size_t i=0 ; value_str[i] != 0 ; ++i)
|
||||||
|
{
|
||||||
|
field_value << static_cast<wchar_t>((unsigned char)value_str[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const char * DbConnector::query_last_sequence(const wchar_t * sequence_table_name)
|
const char * DbConnector::query_last_sequence(const wchar_t * sequence_table_name)
|
||||||
{
|
{
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018-2021, Tomasz Sowa
|
* Copyright (c) 2018-2024, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -32,10 +32,10 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef headerfile_morm_dbconnector
|
#ifndef headerfile_morm_src_dbconnector
|
||||||
#define headerfile_morm_dbconnector
|
#define headerfile_morm_src_dbconnector
|
||||||
|
|
||||||
#include "textstream/textstream.h"
|
#include "textstream/stream.h"
|
||||||
#include "log/log.h"
|
#include "log/log.h"
|
||||||
#include "queryresult.h"
|
#include "queryresult.h"
|
||||||
#include "ft.h"
|
#include "ft.h"
|
||||||
|
@ -52,7 +52,8 @@ class DbConnector
|
||||||
public:
|
public:
|
||||||
|
|
||||||
DbConnector();
|
DbConnector();
|
||||||
DbConnector(const DbConnector &);
|
DbConnector(const DbConnector &) = delete;
|
||||||
|
DbConnector(DbConnector &&) = delete;
|
||||||
virtual ~DbConnector();
|
virtual ~DbConnector();
|
||||||
|
|
||||||
virtual void set_logger(pt::Log * log);
|
virtual void set_logger(pt::Log * log);
|
||||||
|
@ -62,22 +63,22 @@ public:
|
||||||
|
|
||||||
DbExpression * get_expression();
|
DbExpression * get_expression();
|
||||||
|
|
||||||
virtual void generate_select_columns(pt::TextStream & stream, Model & model);
|
virtual void generate_select_columns(pt::Stream & stream, Model & model);
|
||||||
virtual void generate_insert_query(pt::TextStream & stream, Model & model);
|
virtual void generate_insert_query(pt::Stream & stream, Model & model);
|
||||||
virtual void generate_update_query(pt::TextStream & stream, Model & model);
|
virtual void generate_update_query(pt::Stream & stream, Model & model);
|
||||||
virtual void generate_remove_query(pt::TextStream & stream, Model & model);
|
virtual void generate_remove_query(pt::Stream & stream, Model & model);
|
||||||
|
|
||||||
virtual bool insert(pt::TextStream & stream, Model & model);
|
virtual bool insert(pt::Stream & stream, Model & model);
|
||||||
virtual bool update(pt::TextStream & stream, Model & model);
|
virtual bool update(pt::Stream & stream, Model & model);
|
||||||
virtual bool remove(pt::TextStream & stream, Model & model);
|
virtual bool remove(pt::Stream & stream, Model & model);
|
||||||
|
|
||||||
virtual bool query(const pt::TextStream & stream);
|
virtual bool query(const pt::Stream & stream);
|
||||||
virtual bool query(const std::string & query_str);
|
virtual bool query(const std::string & query_str);
|
||||||
virtual bool query(const char * query_str);
|
virtual bool query(const char * query_str);
|
||||||
|
|
||||||
virtual QueryResult * create_query_result() = 0;
|
virtual QueryResult * create_query_result() = 0;
|
||||||
|
|
||||||
virtual bool query(const pt::TextStream & stream, QueryResult & query_result);
|
virtual bool query(const pt::Stream & stream, QueryResult & query_result);
|
||||||
virtual bool query(const std::string & query_str, QueryResult & query_result);
|
virtual bool query(const std::string & query_str, QueryResult & query_result);
|
||||||
virtual bool query(const char * query_str, QueryResult & query_result);
|
virtual bool query(const char * query_str, QueryResult & query_result);
|
||||||
|
|
||||||
|
@ -85,34 +86,80 @@ public:
|
||||||
virtual bool query_update(const char * query_str, QueryResult & query_result);
|
virtual bool query_update(const char * query_str, QueryResult & query_result);
|
||||||
virtual bool query_insert(const char * query_str, QueryResult & query_result);
|
virtual bool query_insert(const char * query_str, QueryResult & query_result);
|
||||||
virtual bool query_remove(const char * query_str, QueryResult & query_result);
|
virtual bool query_remove(const char * query_str, QueryResult & query_result);
|
||||||
|
virtual bool query_declare_cursor(const char * query_str, QueryResult & query_result);
|
||||||
|
|
||||||
virtual bool query_select(const pt::TextStream & stream, QueryResult & query_result);
|
virtual bool query_select(const pt::Stream & stream, QueryResult & query_result);
|
||||||
virtual bool query_update(const pt::TextStream & stream, QueryResult & query_result);
|
virtual bool query_update(const pt::Stream & stream, QueryResult & query_result);
|
||||||
virtual bool query_insert(const pt::TextStream & stream, QueryResult & query_result);
|
virtual bool query_insert(const pt::Stream & stream, QueryResult & query_result);
|
||||||
virtual bool query_remove(const pt::TextStream & stream, QueryResult & query_result);
|
virtual bool query_remove(const pt::Stream & stream, QueryResult & query_result);
|
||||||
|
virtual bool query_declare_cursor(const pt::Stream & stream, QueryResult & query_result);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* create a new transaction
|
||||||
|
* first transaction has index equal to one
|
||||||
|
*/
|
||||||
|
virtual bool begin();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* create a new transaction if there is no a transaction started yet
|
||||||
|
*/
|
||||||
|
virtual bool begin_if_needed();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rollback or commit the last transaction
|
||||||
|
*/
|
||||||
|
virtual bool rollback();
|
||||||
|
virtual bool commit();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rollback or commit all transactions from the last one to the index
|
||||||
|
* (first transaction has index one, there is no a transaction with index zero)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
virtual bool rollback(size_t index);
|
||||||
|
virtual bool commit(size_t index);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* return current transaction index (within a group)
|
||||||
|
* first transaction has index equal to one
|
||||||
|
* returns zero if there are no any transactions
|
||||||
|
*/
|
||||||
|
virtual size_t get_transaction_index();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* return current transaction group index
|
||||||
|
* a group index is incremented when you commit or rollback a transaction
|
||||||
|
* (if you are closing a nested transaction then the group index is not incremented)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
virtual size_t get_transaction_group();
|
||||||
|
|
||||||
|
|
||||||
|
virtual void get_value(const char * value_str, char & field_value, const FT & field_type = FT::default_type);
|
||||||
|
virtual void get_value(const char * value_str, unsigned char & field_value, const FT & field_type = FT::default_type);
|
||||||
|
virtual void get_value(const char * value_str, wchar_t & field_value, const FT & field_type = FT::default_type);
|
||||||
|
virtual void get_value(const char * value_str, char32_t & field_value, const FT & field_type = FT::default_type);
|
||||||
|
virtual void get_value(const char * value_str, std::wstring & field_value, const FT & field_type = FT::default_type);
|
||||||
|
virtual void get_value(const char * value_str, std::string & field_value, const FT & field_type = FT::default_type);
|
||||||
|
virtual void get_value(const char * value_str, std::string_view & field_value, const FT & field_type = FT::default_type);
|
||||||
|
virtual void get_value(const char * value_str, bool & field_value, const FT & field_type = FT::default_type);
|
||||||
|
virtual void get_value(const char * value_str, short & field_value, const FT & field_type = FT::default_type);
|
||||||
|
virtual void get_value(const char * value_str, unsigned short & field_value, const FT & field_type = FT::default_type);
|
||||||
|
virtual void get_value(const char * value_str, int & field_value, const FT & field_type = FT::default_type);
|
||||||
|
virtual void get_value(const char * value_str, unsigned int & field_value, const FT & field_type = FT::default_type);
|
||||||
|
virtual void get_value(const char * value_str, long & field_value, const FT & field_type = FT::default_type);
|
||||||
|
virtual void get_value(const char * value_str, unsigned long & field_value, const FT & field_type = FT::default_type);
|
||||||
|
virtual void get_value(const char * value_str, long long & field_value, const FT & field_type = FT::default_type);
|
||||||
|
virtual void get_value(const char * value_str, unsigned long long & field_value, const FT & field_type = FT::default_type);
|
||||||
|
virtual void get_value(const char * value_str, float & field_value, const FT & field_type = FT::default_type);
|
||||||
|
virtual void get_value(const char * value_str, double & field_value, const FT & field_type = FT::default_type);
|
||||||
|
virtual void get_value(const char * value_str, long double & field_value, const FT & field_type = FT::default_type);
|
||||||
|
virtual void get_value(const char * value_str, pt::Date & field_value, const FT & field_type = FT::default_type);
|
||||||
|
virtual void get_value(const char * value_str, pt::Space & field_value, const FT & field_type = FT::default_type);
|
||||||
|
virtual void get_value(const char * value_str, pt::Stream & field_value, const FT & field_type = FT::default_type);
|
||||||
|
|
||||||
virtual void get_value(const char * value_str, char & field_value, const FT & field_type = FT::default_type);
|
|
||||||
virtual void get_value(const char * value_str, unsigned char & field_value, const FT & field_type = FT::default_type);
|
|
||||||
virtual void get_value(const char * value_str, wchar_t & field_value, const FT & field_type = FT::default_type);
|
|
||||||
virtual void get_value(const char * value_str, std::wstring & field_value, const FT & field_type = FT::default_type);
|
|
||||||
virtual void get_value(const char * value_str, std::string & field_value, const FT & field_type = FT::default_type);
|
|
||||||
virtual void get_value(const char * value_str, std::string_view & field_value, const FT & field_type = FT::default_type);
|
|
||||||
virtual void get_value(const char * value_str, bool & field_value, const FT & field_type = FT::default_type);
|
|
||||||
virtual void get_value(const char * value_str, short & field_value, const FT & field_type = FT::default_type);
|
|
||||||
virtual void get_value(const char * value_str, unsigned short & field_value, const FT & field_type = FT::default_type);
|
|
||||||
virtual void get_value(const char * value_str, int & field_value, const FT & field_type = FT::default_type);
|
|
||||||
virtual void get_value(const char * value_str, unsigned int & field_value, const FT & field_type = FT::default_type);
|
|
||||||
virtual void get_value(const char * value_str, long & field_value, const FT & field_type = FT::default_type);
|
|
||||||
virtual void get_value(const char * value_str, unsigned long & field_value, const FT & field_type = FT::default_type);
|
|
||||||
virtual void get_value(const char * value_str, long long & field_value, const FT & field_type = FT::default_type);
|
|
||||||
virtual void get_value(const char * value_str, unsigned long long & field_value, const FT & field_type = FT::default_type);
|
|
||||||
virtual void get_value(const char * value_str, float & field_value, const FT & field_type = FT::default_type);
|
|
||||||
virtual void get_value(const char * value_str, double & field_value, const FT & field_type = FT::default_type);
|
|
||||||
virtual void get_value(const char * value_str, long double & field_value, const FT & field_type = FT::default_type);
|
|
||||||
virtual void get_value(const char * value_str, pt::Date & field_value, const FT & field_type = FT::default_type);
|
|
||||||
virtual void get_value(const char * value_str, pt::Space & field_value, const FT & field_type = FT::default_type);
|
|
||||||
|
|
||||||
// add get_value for pt::TextStream and pt::WTextStream
|
|
||||||
|
|
||||||
template<typename FieldValue>
|
template<typename FieldValue>
|
||||||
bool get_last_sequence(const wchar_t * sequence_table_name, FieldValue & field_value)
|
bool get_last_sequence(const wchar_t * sequence_table_name, FieldValue & field_value)
|
||||||
|
@ -141,6 +188,8 @@ protected:
|
||||||
bool expression_allocated;
|
bool expression_allocated;
|
||||||
pt::Log * log;
|
pt::Log * log;
|
||||||
bool log_queries;
|
bool log_queries;
|
||||||
|
size_t transaction_index;
|
||||||
|
size_t transaction_group;
|
||||||
|
|
||||||
|
|
||||||
virtual void allocate_default_expression() = 0;
|
virtual void allocate_default_expression() = 0;
|
||||||
|
@ -149,22 +198,27 @@ protected:
|
||||||
|
|
||||||
virtual const char * query_last_sequence(const wchar_t * sequence_table_name);
|
virtual const char * query_last_sequence(const wchar_t * sequence_table_name);
|
||||||
|
|
||||||
|
virtual void unescape_hex_char(const char * str, char & c);
|
||||||
|
virtual void unescape_hex_char(const char * str, char32_t & c);
|
||||||
|
|
||||||
|
virtual void unescape_bin_char(const char * str, char & c);
|
||||||
|
virtual void unescape_bin_char(const char * str, char32_t & c);
|
||||||
|
|
||||||
virtual void unescape_hex_string(const char * str, std::string & out);
|
virtual void unescape_hex_string(const char * str, std::string & out);
|
||||||
virtual void unescape_hex_string(const char * str, std::wstring & out, const FT & field_type);
|
virtual void unescape_hex_string(const char * str, std::wstring & out);
|
||||||
|
virtual void unescape_hex_string(const char * str, pt::Stream & out);
|
||||||
|
|
||||||
virtual void unescape_bin_string(const char * str, std::string & out);
|
virtual void unescape_bin_string(const char * str, std::string & out);
|
||||||
virtual void unescape_bin_string(const char * str, std::wstring & out, const FT & field_type);
|
virtual void unescape_bin_string(const char * str, std::wstring & out);
|
||||||
|
virtual void unescape_bin_string(const char * str, pt::Stream & out);
|
||||||
|
|
||||||
virtual size_t unescape_hex_char(const char * value_str, char * utf8_str, size_t utf8_str_max_len);
|
virtual bool rollback_one_transaction(size_t index);
|
||||||
virtual size_t unescape_hex_char(const char * value_str, wchar_t & field_value, const FT & field_type);
|
virtual bool commit_one_transaction(size_t index);
|
||||||
virtual size_t unescape_bin_char(const char * value_str, wchar_t & field_value, const FT & field_type);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
char unescape_hex_char_part(char hex);
|
unsigned int unescape_hex_char_part(char hex);
|
||||||
char unescape_hex_char(char char1, char char2);
|
const char * unescape_hex_char(const char * str, size_t len, unsigned int & res);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018-2021, Tomasz Sowa
|
* Copyright (c) 2018-2024, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -33,6 +33,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "dbexpression.h"
|
#include "dbexpression.h"
|
||||||
|
#include "model.h"
|
||||||
|
|
||||||
|
|
||||||
namespace morm
|
namespace morm
|
||||||
|
@ -41,7 +42,6 @@ namespace morm
|
||||||
|
|
||||||
DbExpression::DbExpression()
|
DbExpression::DbExpression()
|
||||||
{
|
{
|
||||||
output_type = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -50,18 +50,6 @@ DbExpression::~DbExpression()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DbExpression::set_output_type(int output_type)
|
|
||||||
{
|
|
||||||
this->output_type = output_type;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int DbExpression::get_output_type()
|
|
||||||
{
|
|
||||||
return output_type;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool DbExpression::can_field_be_generated(const FT & field_type)
|
bool DbExpression::can_field_be_generated(const FT & field_type)
|
||||||
{
|
{
|
||||||
if( output_type == MORM_OUTPUT_TYPE_DB_INSERT )
|
if( output_type == MORM_OUTPUT_TYPE_DB_INSERT )
|
||||||
|
@ -76,7 +64,8 @@ bool DbExpression::can_field_be_generated(const FT & field_type)
|
||||||
else
|
else
|
||||||
if( output_type == MORM_OUTPUT_TYPE_DB_PRIMARY_KEY ||
|
if( output_type == MORM_OUTPUT_TYPE_DB_PRIMARY_KEY ||
|
||||||
output_type == MORM_OUTPUT_TYPE_JOIN_TABLES ||
|
output_type == MORM_OUTPUT_TYPE_JOIN_TABLES ||
|
||||||
output_type == MORM_OUTPUT_TYPE_DB_INSERT_PRIMARY_KEY )
|
output_type == MORM_OUTPUT_TYPE_DB_INSERT_PRIMARY_KEY ||
|
||||||
|
output_type == MORM_OUTPUT_TYPE_DB_UPDATE_PRIMARY_KEY )
|
||||||
{
|
{
|
||||||
return field_type.is_primary_key();
|
return field_type.is_primary_key();
|
||||||
}
|
}
|
||||||
|
@ -106,7 +95,8 @@ void DbExpression::field_before()
|
||||||
(*out_stream) << " AND ";
|
(*out_stream) << " AND ";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if( output_type == MORM_OUTPUT_TYPE_DB_INSERT_PRIMARY_KEY )
|
if( output_type == MORM_OUTPUT_TYPE_DB_INSERT_PRIMARY_KEY ||
|
||||||
|
output_type == MORM_OUTPUT_TYPE_DB_UPDATE_PRIMARY_KEY )
|
||||||
{
|
{
|
||||||
(*out_stream) << ", ";
|
(*out_stream) << ", ";
|
||||||
}
|
}
|
||||||
|
@ -117,7 +107,11 @@ void DbExpression::field_before()
|
||||||
output_type == MORM_OUTPUT_TYPE_WHERE_LE ||
|
output_type == MORM_OUTPUT_TYPE_WHERE_LE ||
|
||||||
output_type == MORM_OUTPUT_TYPE_WHERE_LT ||
|
output_type == MORM_OUTPUT_TYPE_WHERE_LT ||
|
||||||
output_type == MORM_OUTPUT_TYPE_WHERE_NOT_EQ ||
|
output_type == MORM_OUTPUT_TYPE_WHERE_NOT_EQ ||
|
||||||
output_type == MORM_OUTPUT_TYPE_WHERE_IN )
|
output_type == MORM_OUTPUT_TYPE_WHERE_IN ||
|
||||||
|
output_type == MORM_OUTPUT_TYPE_WHERE_LIKE ||
|
||||||
|
output_type == MORM_OUTPUT_TYPE_WHERE_ILIKE ||
|
||||||
|
output_type == MORM_OUTPUT_TYPE_WHERE_IS_NULL ||
|
||||||
|
output_type == MORM_OUTPUT_TYPE_WHERE_IS_NOT_NULL )
|
||||||
{
|
{
|
||||||
int conjunction = MORM_CONJUNCTION_AND;
|
int conjunction = MORM_CONJUNCTION_AND;
|
||||||
|
|
||||||
|
@ -177,7 +171,27 @@ void DbExpression::put_name_value_separator()
|
||||||
else
|
else
|
||||||
if( output_type == MORM_OUTPUT_TYPE_WHERE_IN )
|
if( output_type == MORM_OUTPUT_TYPE_WHERE_IN )
|
||||||
{
|
{
|
||||||
(*out_stream) << " in ";
|
(*out_stream) << " IN ";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if( output_type == MORM_OUTPUT_TYPE_WHERE_LIKE )
|
||||||
|
{
|
||||||
|
(*out_stream) << " LIKE ";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if( output_type == MORM_OUTPUT_TYPE_WHERE_ILIKE )
|
||||||
|
{
|
||||||
|
(*out_stream) << " ILIKE ";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if( output_type == MORM_OUTPUT_TYPE_WHERE_IS_NULL )
|
||||||
|
{
|
||||||
|
(*out_stream) << " IS NULL ";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if( output_type == MORM_OUTPUT_TYPE_WHERE_IS_NOT_NULL )
|
||||||
|
{
|
||||||
|
(*out_stream) << " IS NOT NULL ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,6 +208,12 @@ void DbExpression::table_field_separator()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DbExpression::alias_names_separator()
|
||||||
|
{
|
||||||
|
(*out_stream) << '.';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void DbExpression::before_schema_name()
|
void DbExpression::before_schema_name()
|
||||||
{
|
{
|
||||||
(*out_stream) << '"';
|
(*out_stream) << '"';
|
||||||
|
@ -230,15 +250,34 @@ void DbExpression::after_field_name()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DbExpression::before_alias_name()
|
||||||
void DbExpression::before_field_value_string(const FT & field_type)
|
|
||||||
{
|
{
|
||||||
(*out_stream) << "'";
|
(*out_stream) << '"';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DbExpression::after_field_value_string(const FT & field_type)
|
void DbExpression::after_alias_name()
|
||||||
{
|
{
|
||||||
|
(*out_stream) << '"';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void DbExpression::before_field_value_string(const FT & field_type, ModelEnv * model_env)
|
||||||
|
{
|
||||||
|
(*out_stream) << "'";
|
||||||
|
|
||||||
|
if( model_env && model_env->use_escaping_for_like && model_env->add_prefix_percent )
|
||||||
|
(*out_stream) << '%';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DbExpression::after_field_value_string(const FT & field_type, ModelEnv * model_env)
|
||||||
|
{
|
||||||
|
if( model_env && model_env->use_escaping_for_like && model_env->add_postfix_percent )
|
||||||
|
(*out_stream) << '%';
|
||||||
|
|
||||||
(*out_stream) << "'";
|
(*out_stream) << "'";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,7 +290,7 @@ void DbExpression::prepare_to_where_clause()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DbExpression & DbExpression::group_or(pt::TextStream & stream)
|
DbExpression & DbExpression::group_or(pt::Stream & stream)
|
||||||
{
|
{
|
||||||
out_stream = &stream;
|
out_stream = &stream;
|
||||||
field_before();
|
field_before();
|
||||||
|
@ -263,7 +302,7 @@ DbExpression & DbExpression::group_or(pt::TextStream & stream)
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
DbExpression & DbExpression::group_and(pt::TextStream & stream)
|
DbExpression & DbExpression::group_and(pt::Stream & stream)
|
||||||
{
|
{
|
||||||
out_stream = &stream;
|
out_stream = &stream;
|
||||||
field_before();
|
field_before();
|
||||||
|
@ -275,7 +314,7 @@ DbExpression & DbExpression::group_and(pt::TextStream & stream)
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
DbExpression & DbExpression::group_end(pt::TextStream & stream)
|
DbExpression & DbExpression::group_end(pt::Stream & stream)
|
||||||
{
|
{
|
||||||
out_stream = &stream;
|
out_stream = &stream;
|
||||||
|
|
||||||
|
@ -291,13 +330,136 @@ DbExpression & DbExpression::group_end(pt::TextStream & stream)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DbExpression & DbExpression::page(pt::TextStream & stream, size_t page_number, size_t page_size)
|
DbExpression & DbExpression::page(pt::Stream & stream, size_t page_number, size_t page_size)
|
||||||
{
|
{
|
||||||
stream << " limit " << page_number << "," << page_size << " ";
|
stream << " LIMIT " << (page_number*page_size) << "," << page_size << " ";
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DbExpression::generate_rows_counter_column_name(ModelEnv & model_env, pt::Stream & str)
|
||||||
|
{
|
||||||
|
str << model_env.table_name;
|
||||||
|
|
||||||
|
if( model_env.table_index > 1 )
|
||||||
|
{
|
||||||
|
str << model_env.table_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
str << DbExpression::COLUMN_ROWS_COUNTER_POSTFIX;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DbExpression::add_additional_columns(Model & model)
|
||||||
|
{
|
||||||
|
if( model.model_env )
|
||||||
|
{
|
||||||
|
if( model.model_env->select_flags.is_with_rows_counter() )
|
||||||
|
{
|
||||||
|
add_rows_counter_column(model);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DbExpression::add_rows_counter_column(Model & model)
|
||||||
|
{
|
||||||
|
if( out_stream && model.model_env )
|
||||||
|
{
|
||||||
|
field_before();
|
||||||
|
(*out_stream) << "COUNT(*) OVER() AS ";
|
||||||
|
before_field_name();
|
||||||
|
|
||||||
|
if( model.model_env->rows_counter_column_name.empty() )
|
||||||
|
{
|
||||||
|
pt::TextStream str;
|
||||||
|
generate_rows_counter_column_name(*model.model_env, str);
|
||||||
|
esc(str, *out_stream);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* for autogenerated selects we don't have to copy the rows_counter_column_name
|
||||||
|
* because a field() method will use an index instead of this name
|
||||||
|
*/
|
||||||
|
if( !model.model_env->has_autogenerated_select )
|
||||||
|
{
|
||||||
|
str.to_str(model.model_env->rows_counter_column_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
esc(model.model_env->rows_counter_column_name, *out_stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
after_field_name();
|
||||||
|
field_after();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void DbExpression::prepare_declare_cursor_query(const pt::Stream & cursor_name, bool scroll_cursor, pt::Stream & out_stream)
|
||||||
|
{
|
||||||
|
out_stream << "DECLARE " << cursor_name;
|
||||||
|
|
||||||
|
if( scroll_cursor )
|
||||||
|
out_stream << " SCROLL";
|
||||||
|
|
||||||
|
out_stream << " CURSOR FOR ";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DbExpression::prepare_fetch_next_query(const pt::Stream & cursor_name, pt::Stream & out_stream)
|
||||||
|
{
|
||||||
|
out_stream << "FETCH NEXT FROM " << cursor_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DbExpression::prepare_fetch_prior_query(const pt::Stream & cursor_name, pt::Stream & out_stream)
|
||||||
|
{
|
||||||
|
out_stream << "FETCH PRIOR FROM " << cursor_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DbExpression::prepare_fetch_first_query(const pt::Stream & cursor_name, pt::Stream & out_stream)
|
||||||
|
{
|
||||||
|
out_stream << "FETCH FIRST FROM " << cursor_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DbExpression::prepare_fetch_last_query(const pt::Stream & cursor_name, pt::Stream & out_stream)
|
||||||
|
{
|
||||||
|
out_stream << "FETCH LAST FROM " << cursor_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DbExpression::prepare_fetch_absotule_query(const pt::Stream & cursor_name, long position, pt::Stream & out_stream)
|
||||||
|
{
|
||||||
|
out_stream << "FETCH ABSOLUTE " << position << " FROM " << cursor_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DbExpression::prepare_fetch_relative_query(const pt::Stream & cursor_name, long position, pt::Stream & out_stream)
|
||||||
|
{
|
||||||
|
out_stream << "FETCH RELATIVE " << position << " FROM " << cursor_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DbExpression::prepare_fetch_forward_count_query(const pt::Stream & cursor_name, size_t len, pt::Stream & out_stream)
|
||||||
|
{
|
||||||
|
out_stream << "FETCH FORWARD " << len << " FROM " << cursor_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DbExpression::prepare_fetch_backward_count_query(const pt::Stream & cursor_name, size_t len, pt::Stream & out_stream)
|
||||||
|
{
|
||||||
|
out_stream << "FETCH BACKWARD " << len << " FROM " << cursor_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DbExpression::prepare_fetch_all_query(const pt::Stream & cursor_name, pt::Stream & out_stream)
|
||||||
|
{
|
||||||
|
out_stream << "FETCH ALL FROM " << cursor_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018-2021, Tomasz Sowa
|
* Copyright (c) 2018-2024, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -32,8 +32,8 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef headerfile_morm_dbexpression
|
#ifndef headerfile_morm_src_dbexpression
|
||||||
#define headerfile_morm_dbexpression
|
#define headerfile_morm_src_dbexpression
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "baseexpression.h"
|
#include "baseexpression.h"
|
||||||
|
@ -50,17 +50,19 @@ public:
|
||||||
DbExpression();
|
DbExpression();
|
||||||
virtual ~DbExpression();
|
virtual ~DbExpression();
|
||||||
|
|
||||||
virtual void set_output_type(int output_type);
|
|
||||||
virtual int get_output_type();
|
|
||||||
|
|
||||||
|
constexpr static const char * COLUMN_ROWS_COUNTER_POSTFIX = "_autoadded_rows_counter";
|
||||||
|
|
||||||
virtual void prepare_to_where_clause();
|
virtual void prepare_to_where_clause();
|
||||||
|
|
||||||
virtual DbExpression & group_or(pt::TextStream & stream);
|
virtual DbExpression & group_or(pt::Stream & stream);
|
||||||
virtual DbExpression & group_and(pt::TextStream & stream);
|
virtual DbExpression & group_and(pt::Stream & stream);
|
||||||
virtual DbExpression & group_end(pt::TextStream & stream);
|
virtual DbExpression & group_end(pt::Stream & stream);
|
||||||
|
|
||||||
virtual DbExpression & page(pt::TextStream & stream, size_t page_number, size_t page_size);
|
/*
|
||||||
|
* page_number starts from zero (it's a number of a page, not an offset)
|
||||||
|
*/
|
||||||
|
virtual DbExpression & page(pt::Stream & stream, size_t page_number, size_t page_size);
|
||||||
|
|
||||||
template<typename FieldValue>
|
template<typename FieldValue>
|
||||||
void add_field_for_select(const wchar_t * new_column_expression, const wchar_t * new_column_name, FieldValue & field_value, const FT & field_type, ModelEnv * model_env)
|
void add_field_for_select(const wchar_t * new_column_expression, const wchar_t * new_column_name, FieldValue & field_value, const FT & field_type, ModelEnv * model_env)
|
||||||
|
@ -68,41 +70,57 @@ public:
|
||||||
std::wstring column_expression; // field() methods can be called recursively, so don't make it as class object
|
std::wstring column_expression; // field() methods can be called recursively, so don't make it as class object
|
||||||
|
|
||||||
column_expression = new_column_expression;
|
column_expression = new_column_expression;
|
||||||
column_expression += L" as ";
|
column_expression += L" AS ";
|
||||||
column_expression += new_column_name;
|
column_expression += new_column_name;
|
||||||
|
|
||||||
field(column_expression.c_str(), field_value, field_type, model_env);
|
field(column_expression.c_str(), field_value, field_type, model_env);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void generate_rows_counter_column_name(ModelEnv & model_env, pt::Stream & str);
|
||||||
|
|
||||||
|
virtual void prepare_declare_cursor_query(const pt::Stream & cursor_name, bool scroll_cursor, pt::Stream & out_stream);
|
||||||
|
virtual void prepare_fetch_next_query(const pt::Stream & cursor_name, pt::Stream & out_stream);
|
||||||
|
virtual void prepare_fetch_prior_query(const pt::Stream & cursor_name, pt::Stream & out_stream);
|
||||||
|
virtual void prepare_fetch_first_query(const pt::Stream & cursor_name, pt::Stream & out_stream);
|
||||||
|
virtual void prepare_fetch_last_query(const pt::Stream & cursor_name, pt::Stream & out_stream);
|
||||||
|
virtual void prepare_fetch_absotule_query(const pt::Stream & cursor_name, long position, pt::Stream & out_stream);
|
||||||
|
virtual void prepare_fetch_relative_query(const pt::Stream & cursor_name, long position, pt::Stream & out_stream);
|
||||||
|
virtual void prepare_fetch_forward_count_query(const pt::Stream & cursor_name, size_t len, pt::Stream & out_stream);
|
||||||
|
virtual void prepare_fetch_backward_count_query(const pt::Stream & cursor_name, size_t len, pt::Stream & out_stream);
|
||||||
|
virtual void prepare_fetch_all_query(const pt::Stream & cursor_name, pt::Stream & out_stream);
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
int output_type;
|
|
||||||
std::vector<int> conjunctions;
|
std::vector<int> conjunctions;
|
||||||
|
|
||||||
bool can_field_be_generated(const FT & field_type);
|
bool can_field_be_generated(const FT & field_type) override;
|
||||||
void field_before();
|
void field_before() override;
|
||||||
void put_name_value_separator();
|
void put_name_value_separator() override;
|
||||||
|
|
||||||
void schema_table_separator();
|
void schema_table_separator() override;
|
||||||
void table_field_separator();
|
void table_field_separator() override;
|
||||||
|
void alias_names_separator() override;
|
||||||
|
|
||||||
void before_schema_name();
|
void before_schema_name() override;
|
||||||
void after_schema_name();
|
void after_schema_name() override;
|
||||||
|
|
||||||
void before_table_name();
|
void before_table_name() override;
|
||||||
void after_table_name();
|
void after_table_name() override;
|
||||||
|
|
||||||
void before_field_name();
|
void before_field_name() override;
|
||||||
void after_field_name();
|
void after_field_name() override;
|
||||||
|
|
||||||
|
void before_alias_name() override;
|
||||||
|
void after_alias_name() override;
|
||||||
|
|
||||||
private:
|
void add_additional_columns(Model & model) override;
|
||||||
|
|
||||||
void before_field_value_string(const FT & field_type);
|
void before_field_value_string(const FT & field_type, ModelEnv * model_env) override;
|
||||||
void after_field_value_string(const FT & field_type);
|
void after_field_value_string(const FT & field_type, ModelEnv * model_env) override;
|
||||||
|
|
||||||
|
virtual void add_rows_counter_column(Model & model);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,128 @@
|
||||||
|
/*
|
||||||
|
* This file is a part of morm
|
||||||
|
* and is distributed under the 2-Clause BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWAExportType, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef headerfile_morm_src_export
|
||||||
|
#define headerfile_morm_src_export
|
||||||
|
|
||||||
|
namespace morm
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* field types
|
||||||
|
*/
|
||||||
|
class Export
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
enum ExportType
|
||||||
|
{
|
||||||
|
default_type = 0,
|
||||||
|
no_clear_stream = 1,
|
||||||
|
dump_mode = 2,
|
||||||
|
export_headers = 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* type can be a superposition from ExportType values
|
||||||
|
*/
|
||||||
|
int type;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Export()
|
||||||
|
{
|
||||||
|
type = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Export(const Export & field_type)
|
||||||
|
{
|
||||||
|
type = field_type.type;
|
||||||
|
}
|
||||||
|
|
||||||
|
Export(ExportType type)
|
||||||
|
{
|
||||||
|
this->type = static_cast<int>(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
Export(int type)
|
||||||
|
{
|
||||||
|
this->type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
Export & operator=(const Export & field_type)
|
||||||
|
{
|
||||||
|
type = field_type.type;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Export & operator=(ExportType type)
|
||||||
|
{
|
||||||
|
this->type = static_cast<int>(type);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Export & operator=(int type)
|
||||||
|
{
|
||||||
|
this->type = type;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_flag_set(int flag_mask) const
|
||||||
|
{
|
||||||
|
return (type & flag_mask) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_no_clear_stream() const
|
||||||
|
{
|
||||||
|
return is_flag_set(no_clear_stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_dump_mode() const
|
||||||
|
{
|
||||||
|
return is_flag_set(dump_mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_export_headers() const
|
||||||
|
{
|
||||||
|
return is_flag_set(export_headers);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -32,8 +32,8 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef headerfile_morm_fieldvaluehelper
|
#ifndef headerfile_morm_src_fieldvaluehelper
|
||||||
#define headerfile_morm_fieldvaluehelper
|
#define headerfile_morm_src_fieldvaluehelper
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <typeinfo>
|
#include <typeinfo>
|
||||||
|
|
1257
src/finder.h
1257
src/finder.h
File diff suppressed because it is too large
Load Diff
|
@ -32,8 +32,8 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef headerfile_morm_finderhelper
|
#ifndef headerfile_morm_src_finderhelper
|
||||||
#define headerfile_morm_finderhelper
|
#define headerfile_morm_src_finderhelper
|
||||||
|
|
||||||
#include "queryresult.h"
|
#include "queryresult.h"
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018-2021, Tomasz Sowa
|
* Copyright (c) 2018-2024, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -67,8 +67,7 @@ FlatExpression * FlatConnector::get_expression()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FlatConnector::to_text(pt::Stream & stream, Model & model, Export exp)
|
||||||
void FlatConnector::to_text(pt::TextStream & stream, Model & model)
|
|
||||||
{
|
{
|
||||||
allocate_default_expression_if_needed();
|
allocate_default_expression_if_needed();
|
||||||
|
|
||||||
|
@ -82,8 +81,6 @@ void FlatConnector::to_text(pt::TextStream & stream, Model & model)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void FlatConnector::deallocate_expression()
|
void FlatConnector::deallocate_expression()
|
||||||
{
|
{
|
||||||
if( expression_allocated )
|
if( expression_allocated )
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018-2021, Tomasz Sowa
|
* Copyright (c) 2018-2024, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -32,10 +32,11 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef headerfile_morm_flatconnector
|
#ifndef headerfile_morm_src_flatconnector
|
||||||
#define headerfile_morm_flatconnector
|
#define headerfile_morm_src_flatconnector
|
||||||
|
|
||||||
#include "textstream/textstream.h"
|
#include "textstream/stream.h"
|
||||||
|
#include "export.h"
|
||||||
|
|
||||||
|
|
||||||
namespace morm
|
namespace morm
|
||||||
|
@ -51,7 +52,7 @@ public:
|
||||||
FlatConnector();
|
FlatConnector();
|
||||||
virtual ~FlatConnector();
|
virtual ~FlatConnector();
|
||||||
|
|
||||||
virtual void to_text(pt::TextStream & stream, Model & model);
|
virtual void to_text(pt::Stream & stream, Model & model, Export exp);
|
||||||
virtual void set_expression(FlatExpression & expression);
|
virtual void set_expression(FlatExpression & expression);
|
||||||
virtual FlatExpression * get_expression();
|
virtual FlatExpression * get_expression();
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018-2021, Tomasz Sowa
|
* Copyright (c) 2018-2023, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -39,9 +39,27 @@
|
||||||
namespace morm
|
namespace morm
|
||||||
{
|
{
|
||||||
|
|
||||||
void FlatExpression::esc(const pt::Date & date, pt::TextStream & stream, const FT & field_type)
|
|
||||||
|
FlatExpression::FlatExpression()
|
||||||
{
|
{
|
||||||
date.SerializeISO(stream);
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FlatExpression::~FlatExpression()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool FlatExpression::should_field_model_be_generated_as_null(bool has_model_primary_key, const FT & field_type)
|
||||||
|
{
|
||||||
|
return !has_model_primary_key && field_type.is_serialize_to_null_if_null();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool FlatExpression::can_field_model_be_generated(bool has_model_primary_key, const FT & field_type)
|
||||||
|
{
|
||||||
|
return has_model_primary_key || !field_type.is_do_not_serialize_if_null();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018-2021, Tomasz Sowa
|
* Copyright (c) 2018-2024, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -32,8 +32,8 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef headerfile_morm_flatexpression
|
#ifndef headerfile_morm_src_flatexpression
|
||||||
#define headerfile_morm_flatexpression
|
#define headerfile_morm_src_flatexpression
|
||||||
|
|
||||||
#include "baseexpression.h"
|
#include "baseexpression.h"
|
||||||
|
|
||||||
|
@ -45,9 +45,15 @@ class FlatExpression : public BaseExpression
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void esc(const pt::Date & date, pt::TextStream & stream, const FT & field_type);
|
FlatExpression();
|
||||||
|
virtual ~FlatExpression();
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
bool should_field_model_be_generated_as_null(bool has_model_primary_key, const FT & field_type) override;
|
||||||
|
bool can_field_model_be_generated(bool has_model_primary_key, const FT & field_type) override;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
63
src/ft.h
63
src/ft.h
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2021, Tomasz Sowa
|
* Copyright (c) 2021-2023, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -32,8 +32,8 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef headerfile_morm_ft
|
#ifndef headerfile_morm_src_ft
|
||||||
#define headerfile_morm_ft
|
#define headerfile_morm_src_ft
|
||||||
|
|
||||||
namespace morm
|
namespace morm
|
||||||
{
|
{
|
||||||
|
@ -58,12 +58,25 @@ public:
|
||||||
no_fetchable = 32, /* not supported yet */
|
no_fetchable = 32, /* not supported yet */
|
||||||
no_removable = 64,
|
no_removable = 64,
|
||||||
raw_field_name = 128,
|
raw_field_name = 128,
|
||||||
dont_use_utf8 = 256,
|
dont_use_utf8 = 256, /* used only with wchar_t and std::wstring, ignored if a binary or a hexadecimal flags are used */
|
||||||
hexadecimal = 512,
|
hexadecimal = 512,
|
||||||
binary = 1024,
|
binary = 1024,
|
||||||
json = 2048,
|
json = 2048,
|
||||||
space = 4096,
|
space = 4096,
|
||||||
pretty_print = 8192,
|
pretty_print = 8192,
|
||||||
|
numeric = 16384,
|
||||||
|
date_only = 32768, /* use only year, month and day from pt::Date, no_time_zone flag is not used here */
|
||||||
|
time_only = 65536, /* use only hour, min, sec from pt::Date, no_time_zone flag is not used here */
|
||||||
|
no_time_zone = 131072, /* no time zone, used only with pt::Date */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* if this flag is set and a model does not have a primary key set
|
||||||
|
* then we print only 'null'
|
||||||
|
* (this is used only with flat strings)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
serialize_to_null_if_null = 262144,
|
||||||
|
do_not_serialize_if_null = 524288, /* null objects are completely skipped when serializing to a flat string (test only for Model objects, not lists/vectors with childs models */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -99,6 +112,18 @@ public:
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FT & operator=(FieldType type)
|
||||||
|
{
|
||||||
|
this->type = static_cast<int>(type);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
FT & operator=(int type)
|
||||||
|
{
|
||||||
|
this->type = type;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
bool is_flag_set(int flag_mask) const
|
bool is_flag_set(int flag_mask) const
|
||||||
{
|
{
|
||||||
return (type & flag_mask) != 0;
|
return (type & flag_mask) != 0;
|
||||||
|
@ -176,6 +201,36 @@ public:
|
||||||
return is_flag_set(pretty_print);
|
return is_flag_set(pretty_print);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_numeric() const
|
||||||
|
{
|
||||||
|
return is_flag_set(numeric);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_date_only() const
|
||||||
|
{
|
||||||
|
return is_flag_set(date_only);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_time_only() const
|
||||||
|
{
|
||||||
|
return is_flag_set(time_only);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_no_time_zone() const
|
||||||
|
{
|
||||||
|
return is_flag_set(no_time_zone);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_serialize_to_null_if_null() const
|
||||||
|
{
|
||||||
|
return is_flag_set(serialize_to_null_if_null);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_do_not_serialize_if_null() const
|
||||||
|
{
|
||||||
|
return is_flag_set(do_not_serialize_if_null);
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018, Tomasz Sowa
|
* Copyright (c) 2018-2024, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -32,8 +32,8 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef headerfile_morm_jsonconnector
|
#ifndef headerfile_morm_src_jsonconnector
|
||||||
#define headerfile_morm_jsonconnector
|
#define headerfile_morm_src_jsonconnector
|
||||||
|
|
||||||
#include "flatconnector.h"
|
#include "flatconnector.h"
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ public:
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
|
||||||
void allocate_default_expression();
|
void allocate_default_expression() override;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018-2021, Tomasz Sowa
|
* Copyright (c) 2018-2024, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -34,7 +34,7 @@
|
||||||
|
|
||||||
#include "jsonexpression.h"
|
#include "jsonexpression.h"
|
||||||
#include "morm_types.h"
|
#include "morm_types.h"
|
||||||
|
#include "convert/misc.h"
|
||||||
|
|
||||||
|
|
||||||
namespace morm
|
namespace morm
|
||||||
|
@ -88,17 +88,35 @@ void JSONExpression::after_field_name()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void JSONExpression::before_field_value_string(const FT & field_type)
|
void JSONExpression::before_field_value_string(const FT & field_type, ModelEnv * model_env)
|
||||||
{
|
{
|
||||||
(*out_stream) << "\"";
|
(*out_stream) << "\"";
|
||||||
}
|
}
|
||||||
|
|
||||||
void JSONExpression::after_field_value_string(const FT & field_type)
|
void JSONExpression::after_field_value_string(const FT & field_type, ModelEnv * model_env)
|
||||||
{
|
{
|
||||||
(*out_stream) << "\"";
|
(*out_stream) << "\"";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void JSONExpression::before_field_value(const pt::Space &, const FT & field_type, ModelEnv * model_env)
|
||||||
|
{
|
||||||
|
if( field_type.is_space() )
|
||||||
|
{
|
||||||
|
before_field_value_string(field_type, model_env);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void JSONExpression::after_field_value(const pt::Space &, const FT & field_type, ModelEnv * model_env)
|
||||||
|
{
|
||||||
|
if( field_type.is_space() )
|
||||||
|
{
|
||||||
|
after_field_value_string(field_type, model_env);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void JSONExpression::put_name_value_separator()
|
void JSONExpression::put_name_value_separator()
|
||||||
{
|
{
|
||||||
(*out_stream) << ':';
|
(*out_stream) << ':';
|
||||||
|
@ -117,50 +135,30 @@ void JSONExpression::after_field_value_list()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void JSONExpression::esc(char val, pt::TextStream & stream, const FT & field_type)
|
bool JSONExpression::esc_char(char32_t val, pt::Stream & stream, const FT & field_type, ModelEnv * model_env)
|
||||||
{
|
{
|
||||||
if( field_type.is_hexadecimal() || field_type.is_binary() )
|
return pt::try_esc_to_json(val, stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void JSONExpression::esc(const pt::Space & space, pt::Stream & stream, const FT & field_type, ModelEnv * model_env)
|
||||||
|
{
|
||||||
|
bool pretty_print = field_type.is_pretty_print();
|
||||||
|
|
||||||
|
if( field_type.is_space() )
|
||||||
{
|
{
|
||||||
char_to_hex(val, stream);
|
pt::TextStream tmp_stream;
|
||||||
|
space.serialize_to_space_stream(tmp_stream, pretty_print);
|
||||||
|
BaseExpression::esc(tmp_stream, stream, field_type, model_env);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if( (unsigned char)val < 32 )
|
// when serializing as json put it directly without escaping
|
||||||
{
|
pt::TextStream tmp_stream;
|
||||||
char buf[10];
|
space.serialize_to_json_stream(tmp_stream, pretty_print);
|
||||||
size_t len;
|
stream << tmp_stream;
|
||||||
pt::Toa((unsigned char)val, buf, sizeof(buf)/sizeof(char), 16, &len);
|
|
||||||
|
|
||||||
stream << "\\u";
|
|
||||||
|
|
||||||
if( len < 4 )
|
|
||||||
{
|
|
||||||
for(size_t i=0 ; i < (4-len) ; ++i)
|
|
||||||
{
|
|
||||||
stream << '0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
stream << buf;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch( val )
|
|
||||||
{
|
|
||||||
case 0: stream << '\\'; stream << '0'; break; // may to skip this character is better?
|
|
||||||
case '\r': stream << '\\'; stream << 'r'; break;
|
|
||||||
case '\n': stream << '\\'; stream << 'n'; break;
|
|
||||||
case '\t': stream << '\\'; stream << 't'; break;
|
|
||||||
case 0x08: stream << '\\'; stream << 'b'; break;
|
|
||||||
case 0x0c: stream << '\\'; stream << 'f'; break;
|
|
||||||
case '\\': stream << '\\'; stream << '\\'; break;
|
|
||||||
case '"': stream << '\\'; stream << '\"'; break;
|
|
||||||
default:
|
|
||||||
stream << val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018-2021, Tomasz Sowa
|
* Copyright (c) 2018-2024, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -32,8 +32,8 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef headerfile_morm_jsonexpression
|
#ifndef headerfile_morm_src_jsonexpression
|
||||||
#define headerfile_morm_jsonexpression
|
#define headerfile_morm_src_jsonexpression
|
||||||
|
|
||||||
#include "flatexpression.h"
|
#include "flatexpression.h"
|
||||||
|
|
||||||
|
@ -47,32 +47,32 @@ class JSONExpression : public FlatExpression
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
void before_generate_from_model();
|
void before_generate_from_model() override;
|
||||||
void after_generate_from_model();
|
void after_generate_from_model() override;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void field_before();
|
void field_before() override;
|
||||||
|
|
||||||
void before_field_name();
|
void before_field_name() override;
|
||||||
void after_field_name();
|
void after_field_name() override;
|
||||||
|
|
||||||
void put_name_value_separator();
|
void put_name_value_separator() override;
|
||||||
|
|
||||||
void before_field_value_list();
|
void before_field_value_list() override;
|
||||||
void after_field_value_list();
|
void after_field_value_list() override;
|
||||||
|
|
||||||
// using FlatExpression::esc to suppress clang warning:
|
bool esc_char(char32_t val, pt::Stream & stream, const FT & field_type, ModelEnv * model_env) override;
|
||||||
// 'morm::JSONExpression::esc' hides overloaded virtual function [-Woverloaded-virtual]
|
void esc(const pt::Space & space, pt::Stream & stream, const FT & field_type, ModelEnv * model_env) override;
|
||||||
using FlatExpression::esc;
|
|
||||||
|
|
||||||
void esc(char val, pt::TextStream & stream, const FT & field_type);
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void before_field_value_string(const FT & field_type);
|
void before_field_value_string(const FT & field_type, ModelEnv * model_env) override;
|
||||||
void after_field_value_string(const FT & field_type);
|
void after_field_value_string(const FT & field_type, ModelEnv * model_env) override;
|
||||||
|
void before_field_value(const pt::Space &, const FT & field_type, ModelEnv * model_env) override;
|
||||||
|
void after_field_value(const pt::Space &, const FT & field_type, ModelEnv * model_env) override;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
368
src/model.cpp
368
src/model.cpp
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018-2021, Tomasz Sowa
|
* Copyright (c) 2018-2024, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -33,6 +33,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "model.h"
|
#include "model.h"
|
||||||
|
#include "convert/text.h"
|
||||||
#include "utf8/utf8.h"
|
#include "utf8/utf8.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -74,13 +75,28 @@ Model::SaveMode Model::get_save_mode()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Model::set_save_mode2(SaveMode save_mode, bool update_whole_tree)
|
||||||
|
{
|
||||||
|
this->save_mode = save_mode;
|
||||||
|
|
||||||
|
if( update_whole_tree )
|
||||||
|
{
|
||||||
|
ModelEnv model_env_local;
|
||||||
|
model_env = &model_env_local;
|
||||||
|
model_env->model_work_mode = MORM_MODEL_WORK_MODE_PROPAGATE_SAVE_STATUS;
|
||||||
|
fields();
|
||||||
|
model_env = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Model::set_has_primary_key_set(bool has_primary_key)
|
void Model::set_has_primary_key_set(bool has_primary_key)
|
||||||
{
|
{
|
||||||
this->has_primary_key_set = has_primary_key;
|
this->has_primary_key_set = has_primary_key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Model::get_has_primary_key_set()
|
bool Model::get_has_primary_key_set() const
|
||||||
{
|
{
|
||||||
return this->has_primary_key_set;
|
return this->has_primary_key_set;
|
||||||
}
|
}
|
||||||
|
@ -178,7 +194,7 @@ bool Model::found()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Model::get_table_name(pt::WTextStream & stream, bool with_schema_name, ModelData * model_data, bool clear_stream)
|
void Model::get_table_name(pt::Stream & stream, bool with_schema_name, ModelData * model_data, bool clear_stream)
|
||||||
{
|
{
|
||||||
if( clear_stream )
|
if( clear_stream )
|
||||||
{
|
{
|
||||||
|
@ -266,6 +282,30 @@ Model * Model::get_model(const wchar_t * db_field_name, const wchar_t * flat_fie
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Wrapper Model::get_wrapper(const wchar_t * db_field_name, const wchar_t * flat_field_name)
|
||||||
|
{
|
||||||
|
ModelEnv model_env_local;
|
||||||
|
model_env = &model_env_local;
|
||||||
|
model_env->model_work_mode = MORM_MODEL_WORK_MODE_GET_MODEL_WRAPPER;
|
||||||
|
model_env->db_field_name = db_field_name;
|
||||||
|
model_env->flat_field_name = flat_field_name;
|
||||||
|
model_env->model = this;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
fields();
|
||||||
|
}
|
||||||
|
catch(...)
|
||||||
|
{
|
||||||
|
model_env = nullptr;
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
model_env = nullptr;
|
||||||
|
return model_env_local.wrapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool Model::get_raw_value(const wchar_t * db_field_name, const wchar_t * flat_field_name, pt::Stream & stream, bool clear_stream)
|
bool Model::get_raw_value(const wchar_t * db_field_name, const wchar_t * flat_field_name, pt::Stream & stream, bool clear_stream)
|
||||||
{
|
{
|
||||||
|
@ -308,10 +348,9 @@ bool Model::get_raw_value(const wchar_t * db_field_name, const wchar_t * flat_fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void Model::to_text(pt::Stream & stream, ModelData * model_data, Export exp)
|
||||||
void Model::to_text(pt::TextStream & stream, ModelData * model_data, bool clear_stream, bool dump_mode)
|
|
||||||
{
|
{
|
||||||
if( clear_stream )
|
if( !exp.is_no_clear_stream() )
|
||||||
{
|
{
|
||||||
stream.clear();
|
stream.clear();
|
||||||
}
|
}
|
||||||
|
@ -320,7 +359,7 @@ void Model::to_text(pt::TextStream & stream, ModelData * model_data, bool clear_
|
||||||
model_env = &model_env_local;
|
model_env = &model_env_local;
|
||||||
model_env->has_primary_key_set = has_primary_key_set;
|
model_env->has_primary_key_set = has_primary_key_set;
|
||||||
model_env->model_work_mode = MORM_MODEL_WORK_MODE_GENERATING_FLAT_STRING;
|
model_env->model_work_mode = MORM_MODEL_WORK_MODE_GENERATING_FLAT_STRING;
|
||||||
model_env->dump_mode = dump_mode;
|
model_env->dump_mode = exp.is_dump_mode();
|
||||||
model_env->model_data = model_data;
|
model_env->model_data = model_data;
|
||||||
model_env->model = this;
|
model_env->model = this;
|
||||||
|
|
||||||
|
@ -333,7 +372,7 @@ void Model::to_text(pt::TextStream & stream, ModelData * model_data, bool clear_
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// table(); at the moment flat strings (json/space) do not need a table name
|
// table(); at the moment flat strings (json/space) do not need a table name
|
||||||
flat_connector->to_text(stream, *this);
|
flat_connector->to_text(stream, *this, exp);
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
|
@ -347,25 +386,52 @@ void Model::to_text(pt::TextStream & stream, ModelData * model_data, bool clear_
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Model::to_text(pt::TextStream & stream, ModelData & model_data, bool clear_stream, bool dump_mode)
|
void Model::to_text(pt::Stream & stream, ModelData & model_data, Export exp)
|
||||||
|
{
|
||||||
|
to_text(stream, &model_data, exp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Model::to_text(pt::Stream & stream, Export exp)
|
||||||
|
{
|
||||||
|
to_text(stream, nullptr, exp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Model::to_text(pt::Stream & stream, ModelData * model_data, bool clear_stream, bool dump_mode)
|
||||||
|
{
|
||||||
|
Export exp = Export::default_type;
|
||||||
|
|
||||||
|
if( !clear_stream )
|
||||||
|
exp = exp.type | Export::no_clear_stream;
|
||||||
|
|
||||||
|
if( dump_mode )
|
||||||
|
exp = exp.type | Export::dump_mode;
|
||||||
|
|
||||||
|
to_text(stream, model_data, exp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Model::to_text(pt::Stream & stream, ModelData & model_data, bool clear_stream, bool dump_mode)
|
||||||
{
|
{
|
||||||
to_text(stream, &model_data, clear_stream, dump_mode);
|
to_text(stream, &model_data, clear_stream, dump_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Model::to_text(pt::TextStream & stream, bool clear_stream, bool dump_mode)
|
void Model::to_text(pt::Stream & stream, bool clear_stream, bool dump_mode)
|
||||||
{
|
{
|
||||||
to_text(stream, nullptr, clear_stream, dump_mode);
|
to_text(stream, nullptr, clear_stream, dump_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Model::to_text(std::string & str, ModelData * model_data, bool clear_string, bool dump_mode)
|
void Model::to_text(std::string & str, ModelData * model_data, bool clear_string, bool dump_mode)
|
||||||
{
|
{
|
||||||
if( model_connector )
|
if( model_connector )
|
||||||
{
|
{
|
||||||
// CHECK ME what if the stream is being used by something other?
|
// CHECK ME what if the stream is being used by someone else?
|
||||||
pt::TextStream * out_stream = model_connector->get_stream();
|
pt::Stream * out_stream = model_connector->get_stream();
|
||||||
|
|
||||||
if( out_stream )
|
if( out_stream )
|
||||||
{
|
{
|
||||||
|
@ -405,7 +471,7 @@ std::string Model::to_string()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Model::generate_insert_query(pt::TextStream & stream, ModelData * model_data)
|
void Model::generate_insert_query(pt::Stream & stream, ModelData * model_data)
|
||||||
{
|
{
|
||||||
ModelEnv model_env_local;
|
ModelEnv model_env_local;
|
||||||
model_env = &model_env_local;
|
model_env = &model_env_local;
|
||||||
|
@ -455,12 +521,11 @@ bool Model::insert(ModelData * model_data, bool insert_whole_tree)
|
||||||
model_env = &model_env_local;
|
model_env = &model_env_local;
|
||||||
model_env->model_data = model_data;
|
model_env->model_data = model_data;
|
||||||
model_env->model = this;
|
model_env->model = this;
|
||||||
bool status = false;
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
table();
|
table();
|
||||||
status = insert_tree(insert_whole_tree);
|
insert_tree(insert_whole_tree);
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
|
@ -469,40 +534,37 @@ bool Model::insert(ModelData * model_data, bool insert_whole_tree)
|
||||||
}
|
}
|
||||||
|
|
||||||
model_env = nullptr;
|
model_env = nullptr;
|
||||||
return status;
|
return model_env_local.status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// has ModelEnv set
|
void Model::insert_tree(bool insert_whole_tree)
|
||||||
// FIX ME we need to propagage the status from the whole tree, if there is an error somewhere then we should return error from the parent
|
|
||||||
bool Model::insert_tree(bool insert_whole_tree)
|
|
||||||
{
|
{
|
||||||
bool result = false;
|
|
||||||
model_env->has_primary_key_set = has_primary_key_set;
|
model_env->has_primary_key_set = has_primary_key_set;
|
||||||
|
|
||||||
if( insert_whole_tree )
|
if( model_env->status && insert_whole_tree )
|
||||||
{
|
{
|
||||||
model_env->model_work_mode = MORM_MODEL_WORK_MODE_ITERATE_THROUGH_CHILDS_WITH_FOREIGN_KEY;
|
model_env->model_work_mode = MORM_MODEL_WORK_MODE_ITERATE_THROUGH_CHILDS_WITH_FOREIGN_KEY;
|
||||||
model_env->model_work_submode = MORM_MODEL_WORK_SUBMODE_INSERT;
|
model_env->model_work_submode = MORM_MODEL_WORK_SUBMODE_INSERT;
|
||||||
fields();
|
fields();
|
||||||
}
|
}
|
||||||
|
|
||||||
if( model_connector )
|
if( model_env->status && model_connector )
|
||||||
{
|
{
|
||||||
model_env->model_work_mode = MORM_MODEL_WORK_MODE_GENERATING_DB_SQL;
|
model_env->model_work_mode = MORM_MODEL_WORK_MODE_GENERATING_DB_SQL;
|
||||||
DbConnector * db_connector = model_connector->get_db_connector();
|
DbConnector * db_connector = model_connector->get_db_connector();
|
||||||
|
|
||||||
// CHECK ME what if the stream is being used by something other?
|
// CHECK ME what if the stream is being used by someone else?
|
||||||
pt::TextStream * out_stream = model_connector->get_stream();
|
pt::Stream * out_stream = model_connector->get_stream();
|
||||||
|
|
||||||
if( db_connector && out_stream )
|
if( db_connector && out_stream )
|
||||||
{
|
{
|
||||||
|
|
||||||
before_insert();
|
before_insert();
|
||||||
out_stream->clear();
|
out_stream->clear();
|
||||||
result = db_connector->insert(*out_stream, *this);
|
model_env->status = db_connector->insert(*out_stream, *this);
|
||||||
|
|
||||||
if( result )
|
if( model_env->status )
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* after_insert() should read the new primary key and set has_primary_key_set flag if the key was read correctly
|
* after_insert() should read the new primary key and set has_primary_key_set flag if the key was read correctly
|
||||||
|
@ -525,21 +587,27 @@ bool Model::insert_tree(bool insert_whole_tree)
|
||||||
after_insert_failure();
|
after_insert_failure();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
model_env->status = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
model_env->status = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( insert_whole_tree )
|
if( model_env->status && insert_whole_tree )
|
||||||
{
|
{
|
||||||
model_env->model_work_mode = MORM_MODEL_WORK_MODE_ITERATE_THROUGH_CHILDS_WITHOUT_FOREIGN_KEY;
|
model_env->model_work_mode = MORM_MODEL_WORK_MODE_ITERATE_THROUGH_CHILDS_WITHOUT_FOREIGN_KEY;
|
||||||
model_env->model_work_submode = MORM_MODEL_WORK_SUBMODE_INSERT;
|
model_env->model_work_submode = MORM_MODEL_WORK_SUBMODE_INSERT;
|
||||||
fields();
|
fields();
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Model::generate_update_query(pt::TextStream & stream, ModelData * model_data)
|
void Model::generate_update_query(pt::Stream & stream, ModelData * model_data)
|
||||||
{
|
{
|
||||||
ModelEnv model_env_local;
|
ModelEnv model_env_local;
|
||||||
model_env = &model_env_local;
|
model_env = &model_env_local;
|
||||||
|
@ -582,12 +650,11 @@ bool Model::update(ModelData * model_data, bool update_whole_tree)
|
||||||
model_env = &model_env_local;
|
model_env = &model_env_local;
|
||||||
model_env->model_data = model_data;
|
model_env->model_data = model_data;
|
||||||
model_env->model = this;
|
model_env->model = this;
|
||||||
bool status = false;
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
table();
|
table();
|
||||||
status = update_tree(update_whole_tree);
|
update_tree(update_whole_tree);
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
|
@ -596,62 +663,66 @@ bool Model::update(ModelData * model_data, bool update_whole_tree)
|
||||||
}
|
}
|
||||||
|
|
||||||
model_env = nullptr;
|
model_env = nullptr;
|
||||||
return status;
|
return model_env_local.status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// FIX ME we need to propagage the status from the whole tree, if there is an error somewhere then we should return error from the parent
|
void Model::update_tree(bool update_whole_tree)
|
||||||
bool Model::update_tree(bool update_whole_tree)
|
|
||||||
{
|
{
|
||||||
bool result = false;
|
|
||||||
model_env->has_primary_key_set = has_primary_key_set;
|
model_env->has_primary_key_set = has_primary_key_set;
|
||||||
|
|
||||||
if( !has_primary_key_set )
|
if( !has_primary_key_set )
|
||||||
{
|
{
|
||||||
put_to_log(L"Morm: call update but model doesn't have a primary key set");
|
put_to_log(L"Morm: call update but model doesn't have a primary key set");
|
||||||
return result;
|
model_env->status = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( update_whole_tree )
|
if( model_env->status && update_whole_tree )
|
||||||
{
|
{
|
||||||
model_env->model_work_mode = MORM_MODEL_WORK_MODE_ITERATE_THROUGH_CHILDS_WITH_FOREIGN_KEY;
|
model_env->model_work_mode = MORM_MODEL_WORK_MODE_ITERATE_THROUGH_CHILDS_WITH_FOREIGN_KEY;
|
||||||
model_env->model_work_submode = MORM_MODEL_WORK_SUBMODE_UPDATE;
|
model_env->model_work_submode = MORM_MODEL_WORK_SUBMODE_UPDATE;
|
||||||
fields();
|
fields();
|
||||||
}
|
}
|
||||||
|
|
||||||
if( model_connector )
|
if( model_env->status && model_connector )
|
||||||
{
|
{
|
||||||
model_env->model_work_mode = MORM_MODEL_WORK_MODE_GENERATING_DB_SQL;
|
model_env->model_work_mode = MORM_MODEL_WORK_MODE_GENERATING_DB_SQL;
|
||||||
DbConnector * db_connector = model_connector->get_db_connector();
|
DbConnector * db_connector = model_connector->get_db_connector();
|
||||||
|
|
||||||
// CHECK ME what if the stream is being used by something other?
|
// CHECK ME what if the stream is being used by something other?
|
||||||
pt::TextStream * out_stream = model_connector->get_stream();
|
pt::Stream * out_stream = model_connector->get_stream();
|
||||||
|
|
||||||
if( db_connector && out_stream )
|
if( db_connector && out_stream )
|
||||||
{
|
{
|
||||||
before_update();
|
before_update();
|
||||||
out_stream->clear();
|
out_stream->clear();
|
||||||
result = db_connector->update(*out_stream, *this);
|
model_env->status = db_connector->update(*out_stream, *this);
|
||||||
|
|
||||||
if( result )
|
if( model_env->status )
|
||||||
after_update();
|
after_update();
|
||||||
else
|
else
|
||||||
after_update_failure();
|
after_update_failure();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
model_env->status = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
model_env->status = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( update_whole_tree )
|
if( model_env->status && update_whole_tree )
|
||||||
{
|
{
|
||||||
model_env->model_work_mode = MORM_MODEL_WORK_MODE_ITERATE_THROUGH_CHILDS_WITHOUT_FOREIGN_KEY;
|
model_env->model_work_mode = MORM_MODEL_WORK_MODE_ITERATE_THROUGH_CHILDS_WITHOUT_FOREIGN_KEY;
|
||||||
model_env->model_work_submode = MORM_MODEL_WORK_SUBMODE_UPDATE;
|
model_env->model_work_submode = MORM_MODEL_WORK_SUBMODE_UPDATE;
|
||||||
fields();
|
fields();
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Model::generate_remove_query(pt::TextStream & stream, ModelData * model_data)
|
void Model::generate_remove_query(pt::Stream & stream, ModelData * model_data)
|
||||||
{
|
{
|
||||||
ModelEnv model_env_local;
|
ModelEnv model_env_local;
|
||||||
model_env = &model_env_local;
|
model_env = &model_env_local;
|
||||||
|
@ -695,12 +766,11 @@ bool Model::remove(ModelData * model_data, bool remove_whole_tree)
|
||||||
model_env = &model_env_local;
|
model_env = &model_env_local;
|
||||||
model_env->model_data = model_data;
|
model_env->model_data = model_data;
|
||||||
model_env->model = this;
|
model_env->model = this;
|
||||||
bool status = false;
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
table();
|
table();
|
||||||
status = remove_tree(remove_whole_tree);
|
remove_tree(remove_whole_tree);
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
|
@ -709,44 +779,42 @@ bool Model::remove(ModelData * model_data, bool remove_whole_tree)
|
||||||
}
|
}
|
||||||
|
|
||||||
model_env = nullptr;
|
model_env = nullptr;
|
||||||
return status;
|
return model_env_local.status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// FIX ME we need to propagage the status from the whole tree, if there is an error somewhere then we should return error from the parent
|
void Model::remove_tree(bool remove_whole_tree)
|
||||||
bool Model::remove_tree(bool remove_whole_tree)
|
|
||||||
{
|
{
|
||||||
bool result = false;
|
|
||||||
model_env->has_primary_key_set = has_primary_key_set;
|
model_env->has_primary_key_set = has_primary_key_set;
|
||||||
|
|
||||||
if( !has_primary_key_set )
|
if( !has_primary_key_set )
|
||||||
{
|
{
|
||||||
put_to_log(L"Morm: call remove but model doesn't have a primary key set");
|
put_to_log(L"Morm: call remove but model doesn't have a primary key set");
|
||||||
return result;
|
model_env->status = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( remove_whole_tree )
|
if( model_env->status && remove_whole_tree )
|
||||||
{
|
{
|
||||||
model_env->model_work_mode = MORM_MODEL_WORK_MODE_ITERATE_THROUGH_CHILDS_WITHOUT_FOREIGN_KEY;
|
model_env->model_work_mode = MORM_MODEL_WORK_MODE_ITERATE_THROUGH_CHILDS_WITHOUT_FOREIGN_KEY;
|
||||||
model_env->model_work_submode = MORM_MODEL_WORK_SUBMODE_REMOVE;
|
model_env->model_work_submode = MORM_MODEL_WORK_SUBMODE_REMOVE;
|
||||||
fields();
|
fields();
|
||||||
}
|
}
|
||||||
|
|
||||||
if( model_connector )
|
if( model_env->status && model_connector )
|
||||||
{
|
{
|
||||||
model_env->model_work_mode = MORM_MODEL_WORK_MODE_GENERATING_DB_SQL;
|
model_env->model_work_mode = MORM_MODEL_WORK_MODE_GENERATING_DB_SQL;
|
||||||
DbConnector * db_connector = model_connector->get_db_connector();
|
DbConnector * db_connector = model_connector->get_db_connector();
|
||||||
|
|
||||||
// CHECK ME what if the stream is being used by something other?
|
// CHECK ME what if the stream is being used by someone else?
|
||||||
pt::TextStream * out_stream = model_connector->get_stream();
|
pt::Stream * out_stream = model_connector->get_stream();
|
||||||
|
|
||||||
if( db_connector && out_stream )
|
if( db_connector && out_stream )
|
||||||
{
|
{
|
||||||
before_remove();
|
before_remove();
|
||||||
out_stream->clear();
|
out_stream->clear();
|
||||||
result = db_connector->remove(*out_stream, *this);
|
model_env->status = db_connector->remove(*out_stream, *this);
|
||||||
|
|
||||||
if( result )
|
if( model_env->status )
|
||||||
{
|
{
|
||||||
save_mode = DO_NOTHING_ON_SAVE;
|
save_mode = DO_NOTHING_ON_SAVE;
|
||||||
has_primary_key_set = false;
|
has_primary_key_set = false;
|
||||||
|
@ -758,16 +826,22 @@ bool Model::remove_tree(bool remove_whole_tree)
|
||||||
after_remove_failure();
|
after_remove_failure();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
model_env->status = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
model_env->status = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( remove_whole_tree )
|
if( model_env->status && remove_whole_tree )
|
||||||
{
|
{
|
||||||
model_env->model_work_mode = MORM_MODEL_WORK_MODE_ITERATE_THROUGH_CHILDS_WITH_FOREIGN_KEY;
|
model_env->model_work_mode = MORM_MODEL_WORK_MODE_ITERATE_THROUGH_CHILDS_WITH_FOREIGN_KEY;
|
||||||
model_env->model_work_submode = MORM_MODEL_WORK_SUBMODE_REMOVE;
|
model_env->model_work_submode = MORM_MODEL_WORK_SUBMODE_REMOVE;
|
||||||
fields();
|
fields();
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -791,12 +865,11 @@ bool Model::save(ModelData * model_data, bool save_whole_tree)
|
||||||
model_env = &model_env_local;
|
model_env = &model_env_local;
|
||||||
model_env->model_data = model_data;
|
model_env->model_data = model_data;
|
||||||
model_env->model = this;
|
model_env->model = this;
|
||||||
bool status = false;
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
table();
|
table();
|
||||||
status = save_tree(save_whole_tree);
|
save_tree(save_whole_tree);
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
|
@ -805,17 +878,16 @@ bool Model::save(ModelData * model_data, bool save_whole_tree)
|
||||||
}
|
}
|
||||||
|
|
||||||
model_env = nullptr;
|
model_env = nullptr;
|
||||||
return status;
|
return model_env_local.status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// FIX ME we need to propagage the status from the whole tree, if there is an error somewhere then we should return error from the parent
|
void Model::save_tree(bool save_whole_tree)
|
||||||
bool Model::save_tree(bool save_whole_tree)
|
|
||||||
{
|
{
|
||||||
bool result = false;
|
|
||||||
model_env->has_primary_key_set = has_primary_key_set;
|
model_env->has_primary_key_set = has_primary_key_set;
|
||||||
|
SaveMode origin_save_mode = save_mode;
|
||||||
|
|
||||||
if( save_whole_tree )
|
if( model_env->status && save_whole_tree )
|
||||||
{
|
{
|
||||||
if( save_mode == DO_DELETE_ON_SAVE )
|
if( save_mode == DO_DELETE_ON_SAVE )
|
||||||
model_env->model_work_mode = MORM_MODEL_WORK_MODE_ITERATE_THROUGH_CHILDS_WITHOUT_FOREIGN_KEY;
|
model_env->model_work_mode = MORM_MODEL_WORK_MODE_ITERATE_THROUGH_CHILDS_WITHOUT_FOREIGN_KEY;
|
||||||
|
@ -826,32 +898,34 @@ bool Model::save_tree(bool save_whole_tree)
|
||||||
fields();
|
fields();
|
||||||
}
|
}
|
||||||
|
|
||||||
ModelEnv * old_model_env = model_env; // remove, insert or update will set model_env to nullptr
|
if( model_env->status )
|
||||||
|
|
||||||
switch( save_mode )
|
|
||||||
{
|
{
|
||||||
case DO_DELETE_ON_SAVE:
|
ModelEnv * old_model_env = model_env; // remove, insert or update will set model_env to nullptr
|
||||||
result = remove_tree(false);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DO_INSERT_ON_SAVE:
|
switch( save_mode )
|
||||||
result = insert_tree(false);
|
{
|
||||||
break;
|
case DO_DELETE_ON_SAVE:
|
||||||
|
remove_tree(false);
|
||||||
|
break;
|
||||||
|
|
||||||
case DO_UPDATE_ON_SAVE:
|
case DO_INSERT_ON_SAVE:
|
||||||
result = update_tree(false);
|
insert_tree(false);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DO_NOTHING_ON_SAVE:
|
case DO_UPDATE_ON_SAVE:
|
||||||
result = true;
|
update_tree(false);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case DO_NOTHING_ON_SAVE:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
model_env = old_model_env;
|
||||||
}
|
}
|
||||||
|
|
||||||
model_env = old_model_env;
|
if( model_env->status && save_whole_tree )
|
||||||
|
|
||||||
if( save_whole_tree )
|
|
||||||
{
|
{
|
||||||
if( save_mode == DO_DELETE_ON_SAVE )
|
if( origin_save_mode == DO_DELETE_ON_SAVE )
|
||||||
model_env->model_work_mode = MORM_MODEL_WORK_MODE_ITERATE_THROUGH_CHILDS_WITH_FOREIGN_KEY;
|
model_env->model_work_mode = MORM_MODEL_WORK_MODE_ITERATE_THROUGH_CHILDS_WITH_FOREIGN_KEY;
|
||||||
else
|
else
|
||||||
model_env->model_work_mode = MORM_MODEL_WORK_MODE_ITERATE_THROUGH_CHILDS_WITHOUT_FOREIGN_KEY;
|
model_env->model_work_mode = MORM_MODEL_WORK_MODE_ITERATE_THROUGH_CHILDS_WITHOUT_FOREIGN_KEY;
|
||||||
|
@ -859,12 +933,10 @@ bool Model::save_tree(bool save_whole_tree)
|
||||||
model_env->model_work_submode = MORM_MODEL_WORK_SUBMODE_SAVE;
|
model_env->model_work_submode = MORM_MODEL_WORK_SUBMODE_SAVE;
|
||||||
fields();
|
fields();
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Model::generate_select_columns(pt::TextStream & stream)
|
void Model::generate_select_columns(pt::Stream & stream)
|
||||||
{
|
{
|
||||||
if( model_connector && model_env )
|
if( model_connector && model_env )
|
||||||
{
|
{
|
||||||
|
@ -890,6 +962,7 @@ void Model::map_values_from_query()
|
||||||
model_env->was_primary_key_read = false; // whether or not there was at least one column with primary_key flag
|
model_env->was_primary_key_read = false; // whether or not there was at least one column with primary_key flag
|
||||||
model_env->has_primary_key_set = true; // whether all primary_columns were different than null
|
model_env->has_primary_key_set = true; // whether all primary_columns were different than null
|
||||||
fields();
|
fields();
|
||||||
|
map_additional_columns_from_query();
|
||||||
model_env->model_work_mode = MORM_MODEL_WORK_MODE_NONE;
|
model_env->model_work_mode = MORM_MODEL_WORK_MODE_NONE;
|
||||||
|
|
||||||
if( model_env->was_primary_key_read && model_env->has_primary_key_set )
|
if( model_env->was_primary_key_read && model_env->has_primary_key_set )
|
||||||
|
@ -906,6 +979,40 @@ void Model::map_values_from_query()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Model::map_additional_columns_from_query()
|
||||||
|
{
|
||||||
|
if( model_env )
|
||||||
|
{
|
||||||
|
if( model_env->select_flags.is_with_rows_counter() )
|
||||||
|
{
|
||||||
|
map_rows_counter_from_query();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Model::map_rows_counter_from_query()
|
||||||
|
{
|
||||||
|
if( model_env && model_env->cursor_helper )
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* take the value only from the first row, the value should be the same on every row
|
||||||
|
*/
|
||||||
|
if( model_env->cursor_helper->current_row == 0 )
|
||||||
|
{
|
||||||
|
field(model_env->rows_counter_column_name.c_str(), L"", model_env->rows_counter);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( model_env->cursor_helper && model_env->cursor_helper->has_autogenerated_select )
|
||||||
|
{
|
||||||
|
model_env->cursor_helper->current_column += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Model::clear()
|
void Model::clear()
|
||||||
{
|
{
|
||||||
|
@ -1084,16 +1191,24 @@ void Model::log_table_name_with_field(const wchar_t * db_field_name, bool put_sc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Model::put_to_log(const wchar_t * str)
|
pt::Log * Model::get_logger()
|
||||||
{
|
{
|
||||||
if( model_connector )
|
if( model_connector )
|
||||||
{
|
{
|
||||||
pt::Log * log = model_connector->get_logger();
|
return model_connector->get_logger();
|
||||||
|
}
|
||||||
|
|
||||||
if( log )
|
return nullptr;
|
||||||
{
|
}
|
||||||
(*log) << str << pt::Log::logend;
|
|
||||||
}
|
|
||||||
|
void Model::put_to_log(const wchar_t * str)
|
||||||
|
{
|
||||||
|
pt::Log * log = get_logger();
|
||||||
|
|
||||||
|
if( log )
|
||||||
|
{
|
||||||
|
(*log) << str << pt::Log::logend;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1140,14 +1255,14 @@ void Model::field_model_left_join(const wchar_t * db_field_name, Model & field_m
|
||||||
|
|
||||||
join_tables_str << "LEFT JOIN ";
|
join_tables_str << "LEFT JOIN ";
|
||||||
|
|
||||||
pt::TextStream * db_expression_stream = db_expression->get_text_stream();
|
pt::Stream * db_expression_stream = db_expression->get_text_stream();
|
||||||
int expr_work_mode = db_expression->get_work_mode();
|
int expr_work_mode = db_expression->get_work_mode();
|
||||||
int expr_output_type = db_expression->get_output_type();
|
int expr_output_type = db_expression->get_output_type();
|
||||||
bool expr_allow_prefix = db_expression->get_allow_to_use_prefix();
|
bool expr_allow_prefix = db_expression->get_allow_to_use_prefix();
|
||||||
|
|
||||||
db_expression->schema_table_to_stream(join_tables_str, field_model.model_env->schema_name, field_model.model_env->table_name);
|
db_expression->schema_table_to_stream(join_tables_str, field_model.model_env->schema_name, field_model.model_env->table_name);
|
||||||
join_tables_str << " AS ";
|
join_tables_str << " AS ";
|
||||||
db_expression->table_with_index_to_stream(join_tables_str, field_model.model_env->table_name, field_model.model_env->table_index);
|
db_expression->alias_to_stream(join_tables_str, field_model.model_env->table_name, field_model.model_env->table_index);
|
||||||
|
|
||||||
db_expression->set_work_mode(MORM_WORK_MODE_MODEL_SAVE_FIELDS);
|
db_expression->set_work_mode(MORM_WORK_MODE_MODEL_SAVE_FIELDS);
|
||||||
db_expression->set_output_type(MORM_OUTPUT_TYPE_JOIN_TABLES);
|
db_expression->set_output_type(MORM_OUTPUT_TYPE_JOIN_TABLES);
|
||||||
|
@ -1360,7 +1475,7 @@ void Model::field_model_generate_flat_string(const wchar_t * flat_field_name, Mo
|
||||||
|
|
||||||
if( flat_expression )
|
if( flat_expression )
|
||||||
{
|
{
|
||||||
if( model_env->dump_mode || field_model.save_mode == DO_INSERT_ON_SAVE || field_model.save_mode == DO_UPDATE_ON_SAVE )
|
if( model_env->dump_mode || field_model.save_mode != DO_DELETE_ON_SAVE )
|
||||||
{
|
{
|
||||||
field_model.model_env->model_work_mode = MORM_MODEL_WORK_MODE_GENERATING_FLAT_STRING;
|
field_model.model_env->model_work_mode = MORM_MODEL_WORK_MODE_GENERATING_FLAT_STRING;
|
||||||
flat_expression->field_model(flat_field_name, field_model, field_type, model_env);
|
flat_expression->field_model(flat_field_name, field_model, field_type, model_env);
|
||||||
|
@ -1434,7 +1549,9 @@ void Model::field_model_generate_db_sql(const wchar_t * db_field_name, Model & f
|
||||||
if( db_expression->get_output_type() != MORM_OUTPUT_TYPE_JOIN_TABLES &&
|
if( db_expression->get_output_type() != MORM_OUTPUT_TYPE_JOIN_TABLES &&
|
||||||
db_expression->get_output_type() != MORM_OUTPUT_TYPE_DB_PRIMARY_KEY &&
|
db_expression->get_output_type() != MORM_OUTPUT_TYPE_DB_PRIMARY_KEY &&
|
||||||
db_expression->get_output_type() != MORM_OUTPUT_TYPE_DB_INSERT &&
|
db_expression->get_output_type() != MORM_OUTPUT_TYPE_DB_INSERT &&
|
||||||
db_expression->get_output_type() != MORM_OUTPUT_TYPE_DB_UPDATE )
|
db_expression->get_output_type() != MORM_OUTPUT_TYPE_DB_UPDATE &&
|
||||||
|
db_expression->get_output_type() != MORM_OUTPUT_TYPE_DB_INSERT_PRIMARY_KEY &&
|
||||||
|
db_expression->get_output_type() != MORM_OUTPUT_TYPE_DB_UPDATE_PRIMARY_KEY )
|
||||||
{
|
{
|
||||||
field_model.fields();
|
field_model.fields();
|
||||||
}
|
}
|
||||||
|
@ -1445,13 +1562,13 @@ void Model::field_model_generate_db_sql(const wchar_t * db_field_name, Model & f
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Model::field_model_clear_values(Model & field_model)
|
void Model::field_model_clear_values(Model & field_model, const FT & field_type)
|
||||||
{
|
{
|
||||||
Clearer * clearer = model_connector->get_clearer();
|
Clearer * clearer = model_connector->get_clearer();
|
||||||
|
|
||||||
if( clearer )
|
if( clearer )
|
||||||
{
|
{
|
||||||
clearer->clear_model(field_model);
|
clearer->clear_model(field_model, field_type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1530,7 +1647,7 @@ void Model::field_model(const wchar_t * db_field_name, const wchar_t * flat_fiel
|
||||||
|
|
||||||
if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_CLEARING_VALUE )
|
if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_CLEARING_VALUE )
|
||||||
{
|
{
|
||||||
field_model_clear_values(field_model);
|
field_model_clear_values(field_model, field_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_GET_FIELD_MODEL )
|
if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_GET_FIELD_MODEL )
|
||||||
|
@ -1542,22 +1659,25 @@ void Model::field_model(const wchar_t * db_field_name, const wchar_t * flat_fiel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_PUT_FIELD_RAW_VALUE_TO_STREAM )
|
if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_GET_MODEL_WRAPPER )
|
||||||
{
|
{
|
||||||
if( (is_empty_field(model_env->db_field_name) || is_the_same_field(db_field_name, model_env->db_field_name)) &&
|
if( (is_empty_field(model_env->db_field_name) || is_the_same_field(db_field_name, model_env->db_field_name)) &&
|
||||||
(is_empty_field(model_env->flat_field_name) || is_the_same_field(flat_field_name, model_env->flat_field_name)) &&
|
(is_empty_field(model_env->flat_field_name) || is_the_same_field(flat_field_name, model_env->flat_field_name)) &&
|
||||||
!model_env->model )
|
!model_env->wrapper.model )
|
||||||
{
|
{
|
||||||
// FIX ME
|
model_env->wrapper.model = &field_model;
|
||||||
//model_env->wrapper.model = &field_model;
|
|
||||||
|
|
||||||
|
|
||||||
// model_env->was_field_found = true;
|
|
||||||
// model_env->model = &field_model;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_PROPAGATE_SAVE_STATUS )
|
||||||
|
{
|
||||||
|
field_model.set_save_mode2(save_mode, true);
|
||||||
|
}
|
||||||
|
|
||||||
field_model.model_env = nullptr;
|
field_model.model_env = nullptr;
|
||||||
|
|
||||||
|
if( !model_env_local.status )
|
||||||
|
model_env->status = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1637,7 +1757,7 @@ bool Model::db_query(const std::string & raw_sql)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Model::db_query(const pt::TextStream & raw_sql)
|
bool Model::db_query(const pt::Stream & raw_sql)
|
||||||
{
|
{
|
||||||
bool status = false;
|
bool status = false;
|
||||||
|
|
||||||
|
@ -1869,7 +1989,7 @@ void Model::field_member(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
bool Model::convert_to_bool(char v)
|
bool Model::convert_to_bool(char v)
|
||||||
{
|
{
|
||||||
return v != 0;
|
return v != 0;
|
||||||
|
@ -1957,40 +2077,36 @@ bool Model::convert_to_bool(unsigned long long v)
|
||||||
|
|
||||||
bool Model::convert_to_bool(float v)
|
bool Model::convert_to_bool(float v)
|
||||||
{
|
{
|
||||||
return v != 0;
|
return v != 0.0F;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Model::convert_to_bool(double v)
|
bool Model::convert_to_bool(double v)
|
||||||
{
|
{
|
||||||
return v != 0;
|
return v != 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Model::convert_to_bool(long double v)
|
bool Model::convert_to_bool(long double v)
|
||||||
{
|
{
|
||||||
return v != 0;
|
return v != 0.0L;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Model::convert_to_bool(const pt::Date & date)
|
bool Model::convert_to_bool(const pt::Date & date)
|
||||||
{
|
{
|
||||||
|
// may return true if the date is not the Unix epoch?
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Model::convert_to_bool(const pt::TextStream & val)
|
bool Model::convert_to_bool(const pt::Stream & val)
|
||||||
{
|
{
|
||||||
return false;
|
return !val.empty();
|
||||||
}
|
|
||||||
|
|
||||||
bool Model::convert_to_bool(const pt::WTextStream & val)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Model::convert_to_bool(const pt::Space & space)
|
bool Model::convert_to_bool(const pt::Space & space)
|
||||||
{
|
{
|
||||||
return false;
|
return space.to_bool();
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
379
src/model.h
379
src/model.h
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018-2021, Tomasz Sowa
|
* Copyright (c) 2018-2024, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -32,8 +32,8 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef headerfile_morm_model
|
#ifndef headerfile_morm_src_model
|
||||||
#define headerfile_morm_model
|
#define headerfile_morm_src_model
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
@ -48,11 +48,10 @@
|
||||||
#include "flatexpression.h"
|
#include "flatexpression.h"
|
||||||
#include "modelenv.h"
|
#include "modelenv.h"
|
||||||
#include "ft.h"
|
#include "ft.h"
|
||||||
#include "modelcontainerwrapper.h"
|
#include "wrapper.h"
|
||||||
#include "spacewrapper.h"
|
|
||||||
|
|
||||||
#ifdef MORM_HAS_EZC_LIBRARY
|
#ifdef MORM_HAS_EZC_LIBRARY
|
||||||
#include "env.h"
|
#include "funinfo.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -83,14 +82,14 @@
|
||||||
#ifdef MORM_HAS_EZC_LIBRARY
|
#ifdef MORM_HAS_EZC_LIBRARY
|
||||||
#define MORM_MODEL_MEMBER_FIELD_EZC(ClassName) \
|
#define MORM_MODEL_MEMBER_FIELD_EZC(ClassName) \
|
||||||
template<typename FunInfoStreamType> \
|
template<typename FunInfoStreamType> \
|
||||||
void field(const wchar_t * field_name, void (ClassName::*method)(Ezc::Env<FunInfoStreamType> &), const morm::FT & field_type = morm::FT::default_type) \
|
void field(const wchar_t * field_name, void (ClassName::*method)(Ezc::FunInfo<FunInfoStreamType> &), const morm::FT & field_type = morm::FT::default_type) \
|
||||||
{ \
|
{ \
|
||||||
field(field_name, field_name, method, field_type); \
|
field(field_name, field_name, method, field_type); \
|
||||||
} \
|
} \
|
||||||
template<typename FunInfoStreamType> \
|
template<typename FunInfoStreamType> \
|
||||||
void field(const wchar_t * db_field_name, const wchar_t * flat_field_name, void (ClassName::*method)(Ezc::Env<FunInfoStreamType> &), const morm::FT & field_type = morm::FT::default_type) \
|
void field(const wchar_t * db_field_name, const wchar_t * flat_field_name, void (ClassName::*method)(Ezc::FunInfo<FunInfoStreamType> &), const morm::FT & field_type = morm::FT::default_type) \
|
||||||
{ \
|
{ \
|
||||||
typedef void (Model::*ModelMember)(Ezc::Env<FunInfoStreamType> &); \
|
typedef void (Model::*ModelMember)(Ezc::FunInfo<FunInfoStreamType> &); \
|
||||||
ModelMember model_member = static_cast<ModelMember>(method); \
|
ModelMember model_member = static_cast<ModelMember>(method); \
|
||||||
field_member_ezc(db_field_name, flat_field_name, model_member, field_type); \
|
field_member_ezc(db_field_name, flat_field_name, model_member, field_type); \
|
||||||
} \
|
} \
|
||||||
|
@ -113,6 +112,16 @@
|
||||||
typedef bool (Model::*ModelMember)() const; \
|
typedef bool (Model::*ModelMember)() const; \
|
||||||
ModelMember model_member = static_cast<ModelMember>(method); \
|
ModelMember model_member = static_cast<ModelMember>(method); \
|
||||||
field_member_ezc(db_field_name, flat_field_name, model_member, field_type); \
|
field_member_ezc(db_field_name, flat_field_name, model_member, field_type); \
|
||||||
|
} \
|
||||||
|
void field(const wchar_t * field_name, void (ClassName::*method)(morm::Wrapper &), const morm::FT & field_type = morm::FT::default_type) \
|
||||||
|
{ \
|
||||||
|
field(field_name, field_name, method, field_type); \
|
||||||
|
} \
|
||||||
|
void field(const wchar_t * db_field_name, const wchar_t * flat_field_name, void (ClassName::*method)(morm::Wrapper &), const morm::FT & field_type = morm::FT::default_type) \
|
||||||
|
{ \
|
||||||
|
typedef void (Model::*ModelMember)(morm::Wrapper &); \
|
||||||
|
ModelMember model_member = static_cast<ModelMember>(method); \
|
||||||
|
field_member_ezc(db_field_name, flat_field_name, model_member, field_type); \
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -144,8 +153,11 @@ public:
|
||||||
virtual void set_save_mode(SaveMode save_mode);
|
virtual void set_save_mode(SaveMode save_mode);
|
||||||
virtual SaveMode get_save_mode();
|
virtual SaveMode get_save_mode();
|
||||||
|
|
||||||
|
// set_save_mode() will be changed to set_save_mode2() in the future
|
||||||
|
virtual void set_save_mode2(SaveMode save_mode, bool update_whole_tree = true);
|
||||||
|
|
||||||
virtual void set_has_primary_key_set(bool has_primary_key);
|
virtual void set_has_primary_key_set(bool has_primary_key);
|
||||||
virtual bool get_has_primary_key_set();
|
virtual bool get_has_primary_key_set() const;
|
||||||
|
|
||||||
virtual void mark_to_delete();
|
virtual void mark_to_delete();
|
||||||
virtual void mark_to_remove();
|
virtual void mark_to_remove();
|
||||||
|
@ -161,13 +173,17 @@ public:
|
||||||
void set_connector(ModelConnector * connector);
|
void set_connector(ModelConnector * connector);
|
||||||
ModelConnector * get_connector();
|
ModelConnector * get_connector();
|
||||||
|
|
||||||
virtual void get_table_name(pt::WTextStream & stream, bool with_schema_name = true, ModelData * model_data = nullptr, bool clear_stream = true);
|
virtual void get_table_name(pt::Stream & stream, bool with_schema_name = true, ModelData * model_data = nullptr, bool clear_stream = true);
|
||||||
virtual void get_table_name(std::wstring & str, bool with_schema_name = true, ModelData * model_data = nullptr, bool clear_string = true);
|
virtual void get_table_name(std::wstring & str, bool with_schema_name = true, ModelData * model_data = nullptr, bool clear_string = true);
|
||||||
virtual void get_table_name(std::string & str, bool with_schema_name = true, ModelData * model_data = nullptr, bool clear_string = true);
|
virtual void get_table_name(std::string & str, bool with_schema_name = true, ModelData * model_data = nullptr, bool clear_string = true);
|
||||||
|
|
||||||
virtual void to_text(pt::TextStream & stream, ModelData * model_data, bool clear_stream = true, bool dump_mode = false);
|
virtual void to_text(pt::Stream & stream, ModelData * model_data, Export exp = Export::default_type);
|
||||||
virtual void to_text(pt::TextStream & stream, ModelData & model_data, bool clear_stream = true, bool dump_mode = false);
|
virtual void to_text(pt::Stream & stream, ModelData & model_data, Export exp = Export::default_type);
|
||||||
virtual void to_text(pt::TextStream & stream, bool clear_stream = true, bool dump_mode = false);
|
virtual void to_text(pt::Stream & stream, Export exp = Export::default_type);
|
||||||
|
|
||||||
|
virtual void to_text(pt::Stream & stream, ModelData * model_data, bool clear_stream, bool dump_mode);
|
||||||
|
virtual void to_text(pt::Stream & stream, ModelData & model_data, bool clear_stream, bool dump_mode);
|
||||||
|
virtual void to_text(pt::Stream & stream, bool clear_stream, bool dump_mode);
|
||||||
|
|
||||||
virtual void to_text(std::string & str, ModelData * model_data, bool clear_string = true, bool dump_mode = false);
|
virtual void to_text(std::string & str, ModelData * model_data, bool clear_string = true, bool dump_mode = false);
|
||||||
virtual void to_text(std::string & str, ModelData & model_data, bool clear_string = true, bool dump_mode = false);
|
virtual void to_text(std::string & str, ModelData & model_data, bool clear_string = true, bool dump_mode = false);
|
||||||
|
@ -176,17 +192,17 @@ public:
|
||||||
virtual std::string to_text();
|
virtual std::string to_text();
|
||||||
virtual std::string to_string();
|
virtual std::string to_string();
|
||||||
|
|
||||||
virtual void generate_insert_query(pt::TextStream & stream, ModelData * model_data = nullptr);
|
virtual void generate_insert_query(pt::Stream & stream, ModelData * model_data = nullptr);
|
||||||
virtual bool insert(ModelData * model_data, bool insert_whole_tree = true);
|
virtual bool insert(ModelData * model_data, bool insert_whole_tree = true);
|
||||||
virtual bool insert(ModelData & model_data, bool insert_whole_tree = true);
|
virtual bool insert(ModelData & model_data, bool insert_whole_tree = true);
|
||||||
virtual bool insert(bool insert_whole_tree = true);
|
virtual bool insert(bool insert_whole_tree = true);
|
||||||
|
|
||||||
virtual void generate_update_query(pt::TextStream & stream, ModelData * model_data = nullptr);
|
virtual void generate_update_query(pt::Stream & stream, ModelData * model_data = nullptr);
|
||||||
virtual bool update(ModelData * model_data, bool update_whole_tree = true);
|
virtual bool update(ModelData * model_data, bool update_whole_tree = true);
|
||||||
virtual bool update(ModelData & model_data, bool update_whole_tree = true);
|
virtual bool update(ModelData & model_data, bool update_whole_tree = true);
|
||||||
virtual bool update(bool update_whole_tree = true);
|
virtual bool update(bool update_whole_tree = true);
|
||||||
|
|
||||||
virtual void generate_remove_query(pt::TextStream & stream, ModelData * model_data = nullptr);
|
virtual void generate_remove_query(pt::Stream & stream, ModelData * model_data = nullptr);
|
||||||
virtual bool remove(ModelData * model_data, bool remove_whole_tree = true);
|
virtual bool remove(ModelData * model_data, bool remove_whole_tree = true);
|
||||||
virtual bool remove(ModelData & model_data, bool remove_whole_tree = true);
|
virtual bool remove(ModelData & model_data, bool remove_whole_tree = true);
|
||||||
virtual bool remove(bool remove_whole_tree = true);
|
virtual bool remove(bool remove_whole_tree = true);
|
||||||
|
@ -196,7 +212,7 @@ public:
|
||||||
virtual bool save(bool save_whole_tree = true);
|
virtual bool save(bool save_whole_tree = true);
|
||||||
|
|
||||||
|
|
||||||
virtual void generate_select_columns(pt::TextStream & stream);
|
virtual void generate_select_columns(pt::Stream & stream);
|
||||||
|
|
||||||
// set object to default values
|
// set object to default values
|
||||||
virtual void clear();
|
virtual void clear();
|
||||||
|
@ -244,6 +260,7 @@ public:
|
||||||
|
|
||||||
|
|
||||||
Model * get_model(const wchar_t * db_field_name, const wchar_t * flat_field_name);
|
Model * get_model(const wchar_t * db_field_name, const wchar_t * flat_field_name);
|
||||||
|
Wrapper get_wrapper(const wchar_t * db_field_name, const wchar_t * flat_field_name);
|
||||||
|
|
||||||
bool get_raw_value(const wchar_t * db_field_name, const wchar_t * flat_field_name, pt::Stream & stream, bool clear_stream = true);
|
bool get_raw_value(const wchar_t * db_field_name, const wchar_t * flat_field_name, pt::Stream & stream, bool clear_stream = true);
|
||||||
bool get_raw_value(const wchar_t * db_field_name, const wchar_t * flat_field_name, ModelData * model_data, pt::Stream & stream, bool clear_stream = true);
|
bool get_raw_value(const wchar_t * db_field_name, const wchar_t * flat_field_name, ModelData * model_data, pt::Stream & stream, bool clear_stream = true);
|
||||||
|
@ -253,8 +270,13 @@ public:
|
||||||
#ifdef MORM_HAS_EZC_LIBRARY
|
#ifdef MORM_HAS_EZC_LIBRARY
|
||||||
template<typename FunInfoStreamType>
|
template<typename FunInfoStreamType>
|
||||||
bool get_raw_value(const wchar_t * db_field_name, const wchar_t * flat_field_name, ModelData * model_data,
|
bool get_raw_value(const wchar_t * db_field_name, const wchar_t * flat_field_name, ModelData * model_data,
|
||||||
Ezc::Env<FunInfoStreamType> & env)
|
Ezc::FunInfo<FunInfoStreamType> & fun_info, pt::Stream & stream, bool clear_stream = true)
|
||||||
{
|
{
|
||||||
|
if( clear_stream )
|
||||||
|
{
|
||||||
|
stream.clear();
|
||||||
|
}
|
||||||
|
|
||||||
ModelEnv model_env_local;
|
ModelEnv model_env_local;
|
||||||
model_env = &model_env_local;
|
model_env = &model_env_local;
|
||||||
|
|
||||||
|
@ -263,15 +285,15 @@ public:
|
||||||
model_env->db_field_name = db_field_name;
|
model_env->db_field_name = db_field_name;
|
||||||
model_env->flat_field_name = flat_field_name;
|
model_env->flat_field_name = flat_field_name;
|
||||||
model_env->model_data = model_data;
|
model_env->model_data = model_data;
|
||||||
model_env->ezc_fun_info = &env;
|
model_env->stream = &stream;
|
||||||
model_env->ezc_fun_info_typeinfo = &typeid(env);
|
model_env->ezc_fun_info = &fun_info;
|
||||||
model_env->ezc_var_space_local = &env.res.space_local;
|
model_env->ezc_fun_info_typeinfo = &typeid(fun_info);
|
||||||
model_env->model = this;
|
model_env->model = this;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
fields();
|
fields();
|
||||||
//fun_info.res = model_env->ezc_fun_result;
|
fun_info.res = model_env->ezc_fun_result;
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
|
@ -279,38 +301,6 @@ public:
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( model_env->model_container_wrapper )
|
|
||||||
{
|
|
||||||
env.res.type = Ezc::Var<FunInfoStreamType>::Type::TYPE_MODEL_CONTAINER_WRAPPER;
|
|
||||||
env.res.model_container_wrapper = model_env->model_container_wrapper;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( model_env->space_wrapper )
|
|
||||||
{
|
|
||||||
env.res.type = Ezc::Var<FunInfoStreamType>::Type::TYPE_SPACE_WRAPPER;
|
|
||||||
env.res.space_wrapper = model_env->space_wrapper;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( model_env->ezc_var_space_local && model_env->ezc_var_space_local->type != pt::Space::Type::type_null )
|
|
||||||
{
|
|
||||||
env.res.type = Ezc::Var<FunInfoStreamType>::Type::TYPE_SPACE_LOCAL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if( model_env->ezc_var_date )
|
|
||||||
{
|
|
||||||
env.res.type = Ezc::Var<FunInfoStreamType>::Type::TYPE_DATE;
|
|
||||||
env.res.date = model_env->ezc_var_date;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// else
|
|
||||||
// if( model_env->model )
|
|
||||||
// {
|
|
||||||
// env.res.type = Ezc::Var<FunInfoStreamType>::Type::TYPE_MODEL;
|
|
||||||
// env.res.model = model_env->model;
|
|
||||||
// }
|
|
||||||
|
|
||||||
model_env = nullptr;
|
model_env = nullptr;
|
||||||
return model_env_local.was_field_found;
|
return model_env_local.was_field_found;
|
||||||
}
|
}
|
||||||
|
@ -358,16 +348,18 @@ protected:
|
||||||
|
|
||||||
virtual ModelData * get_model_data();
|
virtual ModelData * get_model_data();
|
||||||
|
|
||||||
virtual bool insert_tree(bool insert_whole_tree);
|
virtual void insert_tree(bool insert_whole_tree);
|
||||||
virtual bool update_tree(bool update_whole_tree);
|
virtual void update_tree(bool update_whole_tree);
|
||||||
virtual bool remove_tree(bool remove_whole_tree);
|
virtual void remove_tree(bool remove_whole_tree);
|
||||||
virtual bool save_tree(bool save_whole_tree);
|
virtual void save_tree(bool save_whole_tree);
|
||||||
|
|
||||||
virtual void map_values_from_query();
|
virtual void map_values_from_query();
|
||||||
|
virtual void map_additional_columns_from_query();
|
||||||
|
virtual void map_rows_counter_from_query();
|
||||||
|
|
||||||
virtual bool db_query(const char * raw_sql);
|
virtual bool db_query(const char * raw_sql);
|
||||||
virtual bool db_query(const std::string & raw_sql);
|
virtual bool db_query(const std::string & raw_sql);
|
||||||
virtual bool db_query(const pt::TextStream & raw_sql);
|
virtual bool db_query(const pt::Stream & raw_sql);
|
||||||
virtual bool db_query(const char ** raw_sql, size_t len);
|
virtual bool db_query(const char ** raw_sql, size_t len);
|
||||||
|
|
||||||
|
|
||||||
|
@ -483,6 +475,17 @@ protected:
|
||||||
field_model(field_name, field_name, field_value, field_type);
|
field_model(field_name, field_name, field_value, field_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void field(const wchar_t * field_name, pt::Stream & field_value, const FT & field_type = FT::default_type)
|
||||||
|
{
|
||||||
|
field_generic(field_name, field_name, field_value, field_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename char_type, size_t stack_size, size_t heap_block_size>
|
||||||
|
void field(const wchar_t * field_name, pt::TextStreamBase<char_type, stack_size, heap_block_size> & field_value, const FT & field_type = FT::default_type)
|
||||||
|
{
|
||||||
|
field_generic(field_name, field_name, field_value, field_type);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename ContainerItemType>
|
template<typename ContainerItemType>
|
||||||
void field(const wchar_t * field_name, std::list<ContainerItemType> & field_value, const FT & field_type = FT::default_type)
|
void field(const wchar_t * field_name, std::list<ContainerItemType> & field_value, const FT & field_type = FT::default_type)
|
||||||
{
|
{
|
||||||
|
@ -613,6 +616,17 @@ protected:
|
||||||
field_model(db_field_name, flat_field_name, field_value, field_type);
|
field_model(db_field_name, flat_field_name, field_value, field_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void field(const wchar_t * db_field_name, const wchar_t * flat_field_name, pt::Stream & field_value, const FT & field_type = FT::default_type)
|
||||||
|
{
|
||||||
|
field_generic(db_field_name, flat_field_name, field_value, field_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename char_type, size_t stack_size, size_t heap_block_size>
|
||||||
|
void field(const wchar_t * db_field_name, const wchar_t * flat_field_name, pt::TextStreamBase<char_type, stack_size, heap_block_size> & field_value, const FT & field_type = FT::default_type)
|
||||||
|
{
|
||||||
|
field_generic(db_field_name, flat_field_name, field_value, field_type);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename ContainerItemType>
|
template<typename ContainerItemType>
|
||||||
void field(const wchar_t * db_field_name, const wchar_t * flat_field_name, std::list<ContainerItemType> & field_value, const FT & field_type = FT::default_type)
|
void field(const wchar_t * db_field_name, const wchar_t * flat_field_name, std::list<ContainerItemType> & field_value, const FT & field_type = FT::default_type)
|
||||||
{
|
{
|
||||||
|
@ -768,7 +782,7 @@ protected:
|
||||||
|
|
||||||
if( clearer )
|
if( clearer )
|
||||||
{
|
{
|
||||||
clearer->clear_value(field_value);
|
clearer->clear_value(field_value, field_type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -781,10 +795,14 @@ protected:
|
||||||
{
|
{
|
||||||
model_env->was_field_found = true;
|
model_env->was_field_found = true;
|
||||||
|
|
||||||
if( model_env->ezc_var_space_local )
|
if( model_env->stream )
|
||||||
{
|
{
|
||||||
model_env->ezc_var_space_local->set(field_value);
|
(*model_env->stream) << field_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MORM_HAS_EZC_LIBRARY
|
||||||
|
model_env->ezc_fun_result = convert_to_bool(field_value);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -841,18 +859,13 @@ protected:
|
||||||
{
|
{
|
||||||
if( model_connector && model_env )
|
if( model_connector && model_env )
|
||||||
{
|
{
|
||||||
if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_PUT_FIELD_RAW_VALUE_TO_STREAM )
|
if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_GET_MODEL_WRAPPER )
|
||||||
{
|
{
|
||||||
if( (is_empty_field(model_env->db_field_name) || is_the_same_field(db_field_name, model_env->db_field_name)) &&
|
if( (is_empty_field(model_env->db_field_name) || is_the_same_field(db_field_name, model_env->db_field_name)) &&
|
||||||
(is_empty_field(model_env->flat_field_name) || is_the_same_field(flat_field_name, model_env->flat_field_name)) )
|
(is_empty_field(model_env->flat_field_name) || is_the_same_field(flat_field_name, model_env->flat_field_name)) &&
|
||||||
|
!model_env->wrapper.date )
|
||||||
{
|
{
|
||||||
model_env->was_field_found = true;
|
model_env->wrapper.date = &field_value;
|
||||||
|
|
||||||
// !! CHECKME is correct here? should be !model_env->ezc_var_date used?
|
|
||||||
if( model_env->ezc_var_date )
|
|
||||||
{
|
|
||||||
model_env->ezc_var_date = &field_value;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -867,14 +880,13 @@ protected:
|
||||||
{
|
{
|
||||||
if( model_connector && model_env )
|
if( model_connector && model_env )
|
||||||
{
|
{
|
||||||
if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_PUT_FIELD_RAW_VALUE_TO_STREAM )
|
if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_GET_MODEL_WRAPPER )
|
||||||
{
|
{
|
||||||
if( (is_empty_field(model_env->db_field_name) || is_the_same_field(db_field_name, model_env->db_field_name)) &&
|
if( (is_empty_field(model_env->db_field_name) || is_the_same_field(db_field_name, model_env->db_field_name)) &&
|
||||||
(is_empty_field(model_env->flat_field_name) || is_the_same_field(flat_field_name, model_env->flat_field_name)) &&
|
(is_empty_field(model_env->flat_field_name) || is_the_same_field(flat_field_name, model_env->flat_field_name)) &&
|
||||||
!model_env->space_wrapper )
|
!model_env->wrapper.space_wrapper )
|
||||||
{
|
{
|
||||||
model_env->was_field_found = true;
|
model_env->wrapper.space_wrapper = new SpaceWrapper(&field_value);
|
||||||
model_env->space_wrapper = new SpaceWrapper(&field_value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -885,6 +897,7 @@ protected:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void field_member_set_field_value(
|
void field_member_set_field_value(
|
||||||
const wchar_t * db_field_name,
|
const wchar_t * db_field_name,
|
||||||
const wchar_t * flat_field_name,
|
const wchar_t * flat_field_name,
|
||||||
|
@ -926,7 +939,7 @@ protected:
|
||||||
|
|
||||||
#ifdef MORM_HAS_EZC_LIBRARY
|
#ifdef MORM_HAS_EZC_LIBRARY
|
||||||
template<typename FunInfoStreamType>
|
template<typename FunInfoStreamType>
|
||||||
void field_member_ezc(const wchar_t * db_field_name, const wchar_t * flat_field_name, void (Model::*method)(Ezc::Env<FunInfoStreamType> &), const FT & field_type)
|
void field_member_ezc(const wchar_t * db_field_name, const wchar_t * flat_field_name, void (Model::*method)(Ezc::FunInfo<FunInfoStreamType> &), const FT & field_type)
|
||||||
{
|
{
|
||||||
if( model_connector && model_env && model_env->ezc_fun_info && model_env->ezc_fun_info_typeinfo && model_env->model )
|
if( model_connector && model_env && model_env->ezc_fun_info && model_env->ezc_fun_info_typeinfo && model_env->model )
|
||||||
{
|
{
|
||||||
|
@ -949,18 +962,18 @@ protected:
|
||||||
|
|
||||||
|
|
||||||
template<typename FunInfoStreamType>
|
template<typename FunInfoStreamType>
|
||||||
void field_member_ezc_put_field_value_to_stream(const wchar_t * db_field_name, const wchar_t * flat_field_name,
|
void field_member_ezc_put_field_value_to_stream(const wchar_t * db_field_name, const wchar_t * flat_field_name, void (Model::*method)(Ezc::FunInfo<FunInfoStreamType> &), const FT & field_type)
|
||||||
void (Model::*method)(Ezc::Env<FunInfoStreamType> &), const FT & field_type)
|
|
||||||
{
|
{
|
||||||
if( (is_empty_field(model_env->db_field_name) || is_the_same_field(db_field_name, model_env->db_field_name)) &&
|
if( (is_empty_field(model_env->db_field_name) || is_the_same_field(db_field_name, model_env->db_field_name)) &&
|
||||||
(is_empty_field(model_env->flat_field_name) || is_the_same_field(flat_field_name, model_env->flat_field_name)) )
|
(is_empty_field(model_env->flat_field_name) || is_the_same_field(flat_field_name, model_env->flat_field_name)) )
|
||||||
{
|
{
|
||||||
model_env->was_field_found = true;
|
model_env->was_field_found = true;
|
||||||
|
|
||||||
if( typeid(Ezc::Env<FunInfoStreamType>) == *model_env->ezc_fun_info_typeinfo )
|
if( typeid(Ezc::FunInfo<FunInfoStreamType>) == *model_env->ezc_fun_info_typeinfo )
|
||||||
{
|
{
|
||||||
Ezc::Env<FunInfoStreamType> * ezc_fun_info = reinterpret_cast<Ezc::Env<FunInfoStreamType>*>(model_env->ezc_fun_info);
|
Ezc::FunInfo<FunInfoStreamType> * ezc_fun_info = reinterpret_cast<Ezc::FunInfo<FunInfoStreamType>*>(model_env->ezc_fun_info);
|
||||||
(model_env->model->*method)(*ezc_fun_info);
|
(model_env->model->*method)(*ezc_fun_info);
|
||||||
|
model_env->ezc_fun_result = ezc_fun_info->res; // ezc_fun_info->res is overwritten in get_raw_value() after fields() method call so we have to remember it in model_env
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -995,12 +1008,7 @@ protected:
|
||||||
(is_empty_field(model_env->flat_field_name) || is_the_same_field(flat_field_name, model_env->flat_field_name)) )
|
(is_empty_field(model_env->flat_field_name) || is_the_same_field(flat_field_name, model_env->flat_field_name)) )
|
||||||
{
|
{
|
||||||
model_env->was_field_found = true;
|
model_env->was_field_found = true;
|
||||||
bool res = (model_env->model->*method)();
|
model_env->ezc_fun_result = (model_env->model->*method)();
|
||||||
|
|
||||||
if( model_env->ezc_var_space_local )
|
|
||||||
{
|
|
||||||
model_env->ezc_var_space_local->set(res);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1027,12 +1035,33 @@ protected:
|
||||||
(is_empty_field(model_env->flat_field_name) || is_the_same_field(flat_field_name, model_env->flat_field_name)) )
|
(is_empty_field(model_env->flat_field_name) || is_the_same_field(flat_field_name, model_env->flat_field_name)) )
|
||||||
{
|
{
|
||||||
model_env->was_field_found = true;
|
model_env->was_field_found = true;
|
||||||
bool res = (model_env->model->*method)();
|
model_env->ezc_fun_result = (model_env->model->*method)();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if( model_env->ezc_var_space_local )
|
|
||||||
{
|
void field_member_ezc(const wchar_t * db_field_name, const wchar_t * flat_field_name, void (Model::*method)(Wrapper & wrapper), const FT & field_type)
|
||||||
model_env->ezc_var_space_local->set(res);
|
{
|
||||||
}
|
if( model_connector && model_env && model_env->model )
|
||||||
|
{
|
||||||
|
if( field_type.is_primary_key() )
|
||||||
|
{
|
||||||
|
pt::Log * plog = model_connector->get_logger();
|
||||||
|
|
||||||
|
if( plog )
|
||||||
|
{
|
||||||
|
(*plog) << pt::Log::log1 << "Morm:: an ezc method cannot be used as a primary key" << pt::Log::logend;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_GET_MODEL_WRAPPER )
|
||||||
|
{
|
||||||
|
if( (is_empty_field(model_env->db_field_name) || is_the_same_field(db_field_name, model_env->db_field_name)) &&
|
||||||
|
(is_empty_field(model_env->flat_field_name) || is_the_same_field(flat_field_name, model_env->flat_field_name)) )
|
||||||
|
{
|
||||||
|
(model_env->model->*method)(model_env->wrapper);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1050,7 +1079,7 @@ protected:
|
||||||
void field_model_iterate_through_childs(Model & field_model, const FT & field_type);
|
void field_model_iterate_through_childs(Model & field_model, const FT & field_type);
|
||||||
void field_model_generate_flat_string(const wchar_t * flat_field_name, Model & field_model, const FT & field_type);
|
void field_model_generate_flat_string(const wchar_t * flat_field_name, Model & field_model, const FT & field_type);
|
||||||
void field_model_generate_db_sql(const wchar_t * db_field_name, Model & field_model, const FT & field_type);
|
void field_model_generate_db_sql(const wchar_t * db_field_name, Model & field_model, const FT & field_type);
|
||||||
void field_model_clear_values(Model & field_model);
|
void field_model_clear_values(Model & field_model, const FT & field_type);
|
||||||
void field_model_read_values_from_queryresult(const wchar_t * db_field_name, Model & field_model, const FT & field_type);
|
void field_model_read_values_from_queryresult(const wchar_t * db_field_name, Model & field_model, const FT & field_type);
|
||||||
void field_model(const wchar_t * db_field_name, const wchar_t * flat_field_name, Model & field_model, const FT & field_type);
|
void field_model(const wchar_t * db_field_name, const wchar_t * flat_field_name, Model & field_model, const FT & field_type);
|
||||||
void field_model(const wchar_t * db_field_name, const wchar_t * flat_field_name, Model * field_model, const FT & field_type);
|
void field_model(const wchar_t * db_field_name, const wchar_t * flat_field_name, Model * field_model, const FT & field_type);
|
||||||
|
@ -1146,18 +1175,24 @@ protected:
|
||||||
template<typename ModelContainerType>
|
template<typename ModelContainerType>
|
||||||
void field_list_iterate_through_childs(ModelContainerType & child_model, const FT & field_type)
|
void field_list_iterate_through_childs(ModelContainerType & child_model, const FT & field_type)
|
||||||
{
|
{
|
||||||
ModelEnv model_env_local;
|
if( model_env->status )
|
||||||
model_env_local.copy_global_objects(*model_env);
|
{
|
||||||
model_env_local.model = &child_model;
|
ModelEnv model_env_local;
|
||||||
|
model_env_local.copy_global_objects(*model_env);
|
||||||
|
model_env_local.model = &child_model;
|
||||||
|
|
||||||
child_model.model_env = &model_env_local;
|
child_model.model_env = &model_env_local;
|
||||||
child_model.model_env->has_primary_key_set = child_model.has_primary_key_set;
|
child_model.model_env->has_primary_key_set = child_model.has_primary_key_set;
|
||||||
child_model.set_connector(model_connector);
|
child_model.set_connector(model_connector);
|
||||||
child_model.table();
|
child_model.table();
|
||||||
|
|
||||||
field_model_iterate_through_childs(child_model, field_type);
|
field_model_iterate_through_childs(child_model, field_type);
|
||||||
|
|
||||||
child_model.model_env = nullptr;
|
if( !model_env_local.status )
|
||||||
|
model_env->status = false;
|
||||||
|
|
||||||
|
child_model.model_env = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1180,13 +1215,52 @@ protected:
|
||||||
|
|
||||||
|
|
||||||
template<typename ModelContainer, typename ModelContainerType, typename IsContainerByValueRenameMe>
|
template<typename ModelContainer, typename ModelContainerType, typename IsContainerByValueRenameMe>
|
||||||
void field_list_clearing_values(ModelContainer & field_container, ModelContainerType * model_container_type, IsContainerByValueRenameMe * foo)
|
void field_list_clearing_values(ModelContainer & field_container, ModelContainerType * model_container_type, IsContainerByValueRenameMe * foo, const FT & field_type)
|
||||||
{
|
{
|
||||||
Clearer * clearer = model_connector->get_clearer();
|
Clearer * clearer = model_connector->get_clearer();
|
||||||
|
|
||||||
if( clearer )
|
if( clearer )
|
||||||
{
|
{
|
||||||
clearer->clear_container(field_container, model_container_type, foo);
|
clearer->clear_container(field_container, model_container_type, foo, field_type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename ModelContainer, typename ModelContainerType, typename IsContainerByValueRenameMe>
|
||||||
|
void field_list_propagate_save_status(ModelContainer & field_container, ModelContainerType * model_container_type, IsContainerByValueRenameMe * foo)
|
||||||
|
{
|
||||||
|
if constexpr (std::is_base_of<Model, ModelContainerType>())
|
||||||
|
{
|
||||||
|
if constexpr (std::is_base_of<Model, IsContainerByValueRenameMe>())
|
||||||
|
{
|
||||||
|
field_list_propagate_save_status_in_container_by_value(field_container, model_container_type);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
field_list_propagate_save_status_in_container_by_pointer(field_container, model_container_type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename ModelContainer, typename ModelContainerType>
|
||||||
|
void field_list_propagate_save_status_in_container_by_value(ModelContainer & field_container, ModelContainerType * model_container_type)
|
||||||
|
{
|
||||||
|
for(ModelContainerType & item : field_container)
|
||||||
|
{
|
||||||
|
item.set_connector(model_connector);
|
||||||
|
item.set_save_mode2(save_mode, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename ModelContainer, typename ModelContainerType>
|
||||||
|
void field_list_propagate_save_status_in_container_by_pointer(ModelContainer & field_container, ModelContainerType * model_container_type)
|
||||||
|
{
|
||||||
|
for(ModelContainerType * item : field_container)
|
||||||
|
{
|
||||||
|
item->set_connector(model_connector);
|
||||||
|
item->set_save_mode2(save_mode, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1196,16 +1270,15 @@ protected:
|
||||||
{
|
{
|
||||||
ContainerItemType * item_type_null_pointer = nullptr;
|
ContainerItemType * item_type_null_pointer = nullptr;
|
||||||
|
|
||||||
if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_PUT_FIELD_RAW_VALUE_TO_STREAM )
|
if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_GET_MODEL_WRAPPER )
|
||||||
{
|
{
|
||||||
if constexpr (std::is_base_of<Model, ContainerItemType>())
|
if constexpr (std::is_base_of<Model, ContainerItemType>())
|
||||||
{
|
{
|
||||||
if( (is_empty_field(model_env->db_field_name) || is_the_same_field(db_field_name, model_env->db_field_name)) &&
|
if( (is_empty_field(model_env->db_field_name) || is_the_same_field(db_field_name, model_env->db_field_name)) &&
|
||||||
(is_empty_field(model_env->flat_field_name) || is_the_same_field(flat_field_name, model_env->flat_field_name)) &&
|
(is_empty_field(model_env->flat_field_name) || is_the_same_field(flat_field_name, model_env->flat_field_name)) &&
|
||||||
!model_env->model_container_wrapper )
|
!model_env->wrapper.model_container_wrapper )
|
||||||
{
|
{
|
||||||
model_env->was_field_found = true;
|
model_env->wrapper.model_container_wrapper = new ModelWrapperVector(&field_value);
|
||||||
model_env->model_container_wrapper = new ModelWrapperVector(&field_value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1222,16 +1295,15 @@ protected:
|
||||||
{
|
{
|
||||||
ContainerItemType * item_type_null_pointer = nullptr;
|
ContainerItemType * item_type_null_pointer = nullptr;
|
||||||
|
|
||||||
if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_PUT_FIELD_RAW_VALUE_TO_STREAM )
|
if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_GET_MODEL_WRAPPER )
|
||||||
{
|
{
|
||||||
if constexpr (std::is_base_of<Model, ContainerItemType>())
|
if constexpr (std::is_base_of<Model, ContainerItemType>())
|
||||||
{
|
{
|
||||||
if( (is_empty_field(model_env->db_field_name) || is_the_same_field(db_field_name, model_env->db_field_name)) &&
|
if( (is_empty_field(model_env->db_field_name) || is_the_same_field(db_field_name, model_env->db_field_name)) &&
|
||||||
(is_empty_field(model_env->flat_field_name) || is_the_same_field(flat_field_name, model_env->flat_field_name)) &&
|
(is_empty_field(model_env->flat_field_name) || is_the_same_field(flat_field_name, model_env->flat_field_name)) &&
|
||||||
!model_env->model_container_wrapper )
|
!model_env->wrapper.model_container_wrapper )
|
||||||
{
|
{
|
||||||
model_env->was_field_found = true;
|
model_env->wrapper.model_container_wrapper = new ModelWrapperList(&field_value);
|
||||||
model_env->model_container_wrapper = new ModelWrapperList(&field_value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1248,16 +1320,15 @@ protected:
|
||||||
{
|
{
|
||||||
ContainerItemType * item_type_null_pointer = nullptr;
|
ContainerItemType * item_type_null_pointer = nullptr;
|
||||||
|
|
||||||
if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_PUT_FIELD_RAW_VALUE_TO_STREAM )
|
if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_GET_MODEL_WRAPPER )
|
||||||
{
|
{
|
||||||
if constexpr (std::is_base_of<Model, ContainerItemType>())
|
if constexpr (std::is_base_of<Model, ContainerItemType>())
|
||||||
{
|
{
|
||||||
if( (is_empty_field(model_env->db_field_name) || is_the_same_field(db_field_name, model_env->db_field_name)) &&
|
if( (is_empty_field(model_env->db_field_name) || is_the_same_field(db_field_name, model_env->db_field_name)) &&
|
||||||
(is_empty_field(model_env->flat_field_name) || is_the_same_field(flat_field_name, model_env->flat_field_name)) &&
|
(is_empty_field(model_env->flat_field_name) || is_the_same_field(flat_field_name, model_env->flat_field_name)) &&
|
||||||
!model_env->model_container_wrapper )
|
!model_env->wrapper.model_container_wrapper )
|
||||||
{
|
{
|
||||||
model_env->was_field_found = true;
|
model_env->wrapper.model_container_wrapper = new ModelWrapperVectorPointer(&field_value);
|
||||||
model_env->model_container_wrapper = new ModelWrapperVectorPointer(&field_value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1274,16 +1345,15 @@ protected:
|
||||||
{
|
{
|
||||||
ContainerItemType * item_type_null_pointer = nullptr;
|
ContainerItemType * item_type_null_pointer = nullptr;
|
||||||
|
|
||||||
if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_PUT_FIELD_RAW_VALUE_TO_STREAM )
|
if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_GET_MODEL_WRAPPER )
|
||||||
{
|
{
|
||||||
if constexpr (std::is_base_of<Model, ContainerItemType>())
|
if constexpr (std::is_base_of<Model, ContainerItemType>())
|
||||||
{
|
{
|
||||||
if( (is_empty_field(model_env->db_field_name) || is_the_same_field(db_field_name, model_env->db_field_name)) &&
|
if( (is_empty_field(model_env->db_field_name) || is_the_same_field(db_field_name, model_env->db_field_name)) &&
|
||||||
(is_empty_field(model_env->flat_field_name) || is_the_same_field(flat_field_name, model_env->flat_field_name)) &&
|
(is_empty_field(model_env->flat_field_name) || is_the_same_field(flat_field_name, model_env->flat_field_name)) &&
|
||||||
!model_env->model_container_wrapper )
|
!model_env->wrapper.model_container_wrapper )
|
||||||
{
|
{
|
||||||
model_env->was_field_found = true;
|
model_env->wrapper.model_container_wrapper = new ModelWrapperListPointer(&field_value);
|
||||||
model_env->model_container_wrapper = new ModelWrapperListPointer(&field_value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1377,7 +1447,12 @@ protected:
|
||||||
|
|
||||||
if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_CLEARING_VALUE )
|
if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_CLEARING_VALUE )
|
||||||
{
|
{
|
||||||
field_list_clearing_values(field_container, model_container_type, foo);
|
field_list_clearing_values(field_container, model_container_type, foo, field_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_PROPAGATE_SAVE_STATUS )
|
||||||
|
{
|
||||||
|
field_list_propagate_save_status(field_container, model_container_type, foo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1425,13 +1500,18 @@ protected:
|
||||||
|
|
||||||
if( db_expression )
|
if( db_expression )
|
||||||
{
|
{
|
||||||
std::wstring table_field_name;
|
|
||||||
pt::TextStream table_field_name_str;
|
pt::TextStream table_field_name_str;
|
||||||
|
db_expression->alias_to_stream(table_field_name_str, model_env->table_name, model_env->table_index, field_name);
|
||||||
|
|
||||||
// CHECK ME not tested yet after changing to db_expression->table_with_index_and_field_to_stream()
|
if( table_field_name_str.size() < 256 )
|
||||||
db_expression->table_with_index_and_field_to_stream(table_field_name_str, model_env->table_name, model_env->table_index, field_name, field_type);
|
{
|
||||||
table_field_name_str.to_str(table_field_name);
|
wchar_t alias_name[256];
|
||||||
column_index = model_env->cursor_helper->query_result->get_column_index(table_field_name.c_str());
|
|
||||||
|
if( table_field_name_str.to_str(alias_name, sizeof(alias_name) / sizeof(wchar_t)) )
|
||||||
|
{
|
||||||
|
column_index = model_env->cursor_helper->query_result->get_column_index(alias_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1541,6 +1621,7 @@ protected:
|
||||||
virtual bool is_empty_field(const wchar_t * value);
|
virtual bool is_empty_field(const wchar_t * value);
|
||||||
virtual bool is_the_same_field(const wchar_t * field1, const wchar_t * field2);
|
virtual bool is_the_same_field(const wchar_t * field1, const wchar_t * field2);
|
||||||
|
|
||||||
|
virtual pt::Log * get_logger();
|
||||||
virtual void put_to_log(const wchar_t * str);
|
virtual void put_to_log(const wchar_t * str);
|
||||||
virtual void put_fields_to_log(pt::Log & log, const wchar_t * db_field_name, const wchar_t * flat_field_name);
|
virtual void put_fields_to_log(pt::Log & log, const wchar_t * db_field_name, const wchar_t * flat_field_name);
|
||||||
|
|
||||||
|
@ -1568,34 +1649,34 @@ protected:
|
||||||
}
|
}
|
||||||
|
|
||||||
// those methods are used when converting fields to bool for Ezc library
|
// those methods are used when converting fields to bool for Ezc library
|
||||||
// virtual bool convert_to_bool(char v);
|
virtual bool convert_to_bool(char v);
|
||||||
// virtual bool convert_to_bool(unsigned char v);
|
virtual bool convert_to_bool(unsigned char v);
|
||||||
// virtual bool convert_to_bool(wchar_t v);
|
virtual bool convert_to_bool(wchar_t v);
|
||||||
// virtual bool convert_to_bool(const std::wstring & str);
|
virtual bool convert_to_bool(const std::wstring & str);
|
||||||
// virtual bool convert_to_bool(const wchar_t * str);
|
virtual bool convert_to_bool(const wchar_t * str);
|
||||||
// virtual bool convert_to_bool(const std::string & str);
|
virtual bool convert_to_bool(const std::string & str);
|
||||||
// virtual bool convert_to_bool(const char * str);
|
virtual bool convert_to_bool(const char * str);
|
||||||
// virtual bool convert_to_bool(bool v);
|
virtual bool convert_to_bool(bool v);
|
||||||
// virtual bool convert_to_bool(short v);
|
virtual bool convert_to_bool(short v);
|
||||||
// virtual bool convert_to_bool(unsigned short v);
|
virtual bool convert_to_bool(unsigned short v);
|
||||||
// virtual bool convert_to_bool(int v);
|
virtual bool convert_to_bool(int v);
|
||||||
// virtual bool convert_to_bool(unsigned int v);
|
virtual bool convert_to_bool(unsigned int v);
|
||||||
// virtual bool convert_to_bool(long v);
|
virtual bool convert_to_bool(long v);
|
||||||
// virtual bool convert_to_bool(unsigned long v);
|
virtual bool convert_to_bool(unsigned long v);
|
||||||
// virtual bool convert_to_bool(long long v);
|
virtual bool convert_to_bool(long long v);
|
||||||
// virtual bool convert_to_bool(unsigned long long v);
|
virtual bool convert_to_bool(unsigned long long v);
|
||||||
// virtual bool convert_to_bool(float v);
|
virtual bool convert_to_bool(float v);
|
||||||
// virtual bool convert_to_bool(double v);
|
virtual bool convert_to_bool(double v);
|
||||||
// virtual bool convert_to_bool(long double v);
|
virtual bool convert_to_bool(long double v);
|
||||||
// virtual bool convert_to_bool(const pt::Date & date);
|
virtual bool convert_to_bool(const pt::Date & date);
|
||||||
// virtual bool convert_to_bool(const pt::TextStream & val);
|
virtual bool convert_to_bool(const pt::Stream & val);
|
||||||
// virtual bool convert_to_bool(const pt::WTextStream & val);
|
virtual bool convert_to_bool(const pt::Space & space);
|
||||||
// virtual bool convert_to_bool(const pt::Space & space);
|
|
||||||
|
|
||||||
|
|
||||||
template<typename ModelClass> friend class Finder;
|
template<typename ModelClass> friend class Finder;
|
||||||
template<typename ModelClass> friend class Cursor;
|
template<typename ModelClass> friend class Cursor;
|
||||||
friend class BaseExpression;
|
friend class BaseExpression;
|
||||||
|
friend class DbExpression;
|
||||||
friend class DbConnector;
|
friend class DbConnector;
|
||||||
friend class FlatConnector;
|
friend class FlatConnector;
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018-2019, Tomasz Sowa
|
* Copyright (c) 2018-2024, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -133,14 +133,14 @@ void ModelConnector::allocate_default_clearer_if_needed()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ModelConnector::set_stream(pt::TextStream & stream)
|
void ModelConnector::set_stream(pt::Stream & stream)
|
||||||
{
|
{
|
||||||
deallocate_stream();
|
deallocate_stream();
|
||||||
this->out_stream = &stream;
|
this->out_stream = &stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pt::TextStream * ModelConnector::get_stream()
|
pt::Stream * ModelConnector::get_stream()
|
||||||
{
|
{
|
||||||
allocate_default_stream_if_needed();
|
allocate_default_stream_if_needed();
|
||||||
return out_stream;
|
return out_stream;
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018-2019, Tomasz Sowa
|
* Copyright (c) 2018-2024, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -32,8 +32,8 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef headerfile_morm_modelconnector
|
#ifndef headerfile_morm_src_modelconnector
|
||||||
#define headerfile_morm_modelconnector
|
#define headerfile_morm_src_modelconnector
|
||||||
|
|
||||||
#include "clearer.h"
|
#include "clearer.h"
|
||||||
#include "dbconnector.h"
|
#include "dbconnector.h"
|
||||||
|
@ -64,8 +64,8 @@ public:
|
||||||
|
|
||||||
virtual pt::Log * get_logger();
|
virtual pt::Log * get_logger();
|
||||||
|
|
||||||
virtual void set_stream(pt::TextStream & stream);
|
virtual void set_stream(pt::Stream & stream);
|
||||||
virtual pt::TextStream * get_stream();
|
virtual pt::Stream * get_stream();
|
||||||
|
|
||||||
virtual void set_flat_connector(FlatConnector & flat_connector);
|
virtual void set_flat_connector(FlatConnector & flat_connector);
|
||||||
virtual FlatConnector * get_flat_connector();
|
virtual FlatConnector * get_flat_connector();
|
||||||
|
@ -85,7 +85,7 @@ protected:
|
||||||
FlatConnector * flat_connector;
|
FlatConnector * flat_connector;
|
||||||
DbConnector * db_connector;
|
DbConnector * db_connector;
|
||||||
|
|
||||||
pt::TextStream * out_stream; // IMPROVE ME give here an interface to the base stream (implement him)
|
pt::Stream * out_stream;
|
||||||
bool out_stream_allocated;
|
bool out_stream_allocated;
|
||||||
|
|
||||||
Clearer * clearer;
|
Clearer * clearer;
|
||||||
|
|
|
@ -32,8 +32,8 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef headerfile_morm_modelcontainerwrapper
|
#ifndef headerfile_morm_src_modelcontainerwrapper
|
||||||
#define headerfile_morm_modelcontainerwrapper
|
#define headerfile_morm_src_modelcontainerwrapper
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
@ -55,16 +55,11 @@ public:
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool is_container_empty() const
|
virtual bool is_container_empty()
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual size_t size() const
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void increment_iterator()
|
virtual void increment_iterator()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -74,6 +69,9 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void set_iterator_at_first_model()
|
||||||
|
{
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -89,16 +87,11 @@ public:
|
||||||
iterator = container->end();
|
iterator = container->end();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_container_empty() const
|
bool is_container_empty()
|
||||||
{
|
{
|
||||||
return container->empty();
|
return container->empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t size() const
|
|
||||||
{
|
|
||||||
return container->size();
|
|
||||||
}
|
|
||||||
|
|
||||||
void increment_iterator()
|
void increment_iterator()
|
||||||
{
|
{
|
||||||
if( iterator == container->end() )
|
if( iterator == container->end() )
|
||||||
|
@ -116,6 +109,10 @@ public:
|
||||||
return iterator != container->end();
|
return iterator != container->end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_iterator_at_first_model()
|
||||||
|
{
|
||||||
|
iterator = container->begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -32,8 +32,8 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef headerfile_morm_modeldata
|
#ifndef headerfile_morm_src_modeldata
|
||||||
#define headerfile_morm_modeldata
|
#define headerfile_morm_src_modeldata
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019-2021, Tomasz Sowa
|
* Copyright (c) 2019-2024, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -32,20 +32,18 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef headerfile_morm_modelenv
|
#ifndef headerfile_morm_src_modelenv
|
||||||
#define headerfile_morm_modelenv
|
#define headerfile_morm_src_modelenv
|
||||||
|
|
||||||
#include "modeldata.h"
|
#include "modeldata.h"
|
||||||
#include "cursorhelper.h"
|
#include "cursorhelper.h"
|
||||||
#include "finderhelper.h"
|
#include "finderhelper.h"
|
||||||
#include "fieldvaluehelper.h"
|
#include "fieldvaluehelper.h"
|
||||||
#include "morm_types.h"
|
#include "morm_types.h"
|
||||||
|
#include "wrapper.h"
|
||||||
|
#include "select.h"
|
||||||
|
|
||||||
|
|
||||||
#ifdef MORM_HAS_EZC_LIBRARY
|
|
||||||
#include "env.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
namespace morm
|
namespace morm
|
||||||
{
|
{
|
||||||
|
@ -95,19 +93,26 @@ public:
|
||||||
Model * child_model;
|
Model * child_model;
|
||||||
pt::Stream * stream;
|
pt::Stream * stream;
|
||||||
bool was_field_found; // used only in MORM_MODEL_WORK_MODE_PUT_FIELD_RAW_VALUE_TO_STREAM
|
bool was_field_found; // used only in MORM_MODEL_WORK_MODE_PUT_FIELD_RAW_VALUE_TO_STREAM
|
||||||
|
Wrapper wrapper;
|
||||||
|
|
||||||
|
|
||||||
#ifdef MORM_HAS_EZC_LIBRARY
|
#ifdef MORM_HAS_EZC_LIBRARY
|
||||||
void * ezc_fun_info;
|
void * ezc_fun_info;
|
||||||
|
bool ezc_fun_result;
|
||||||
const std::type_info * ezc_fun_info_typeinfo;
|
const std::type_info * ezc_fun_info_typeinfo;
|
||||||
pt::Space * ezc_var_space_local;
|
|
||||||
pt::Date * ezc_var_date;
|
|
||||||
|
|
||||||
ModelContainerWrapper * model_container_wrapper;
|
|
||||||
SpaceWrapper * space_wrapper;
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
bool status;
|
||||||
|
bool has_autogenerated_select;
|
||||||
|
Select select_flags;
|
||||||
|
size_t rows_counter;
|
||||||
|
std::wstring rows_counter_column_name;
|
||||||
|
bool use_escaping_for_like; // escaping % and _ characters for LIKE or ILIKE statements
|
||||||
|
bool add_prefix_percent; // add a percent sign before a string value (used mainly in LIKE or ILIKE)
|
||||||
|
bool add_postfix_percent; // add a percent sign after a string value (used mainly in LIKE or ILIKE)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ModelEnv()
|
ModelEnv()
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
|
@ -140,14 +145,20 @@ public:
|
||||||
child_model = e.child_model;
|
child_model = e.child_model;
|
||||||
stream = e.stream;
|
stream = e.stream;
|
||||||
was_field_found = e.was_field_found;
|
was_field_found = e.was_field_found;
|
||||||
|
wrapper = e.wrapper;
|
||||||
|
status = e.status;
|
||||||
|
has_autogenerated_select = e.has_autogenerated_select;
|
||||||
|
select_flags = e.select_flags;
|
||||||
|
rows_counter = e.rows_counter;
|
||||||
|
rows_counter_column_name = e.rows_counter_column_name;
|
||||||
|
use_escaping_for_like = e.use_escaping_for_like;
|
||||||
|
add_prefix_percent = e.add_prefix_percent;
|
||||||
|
add_postfix_percent = e.add_postfix_percent;
|
||||||
|
|
||||||
#ifdef MORM_HAS_EZC_LIBRARY
|
#ifdef MORM_HAS_EZC_LIBRARY
|
||||||
ezc_fun_info = e.ezc_fun_info;
|
ezc_fun_info = e.ezc_fun_info;
|
||||||
|
ezc_fun_result = e.ezc_fun_result;
|
||||||
ezc_fun_info_typeinfo = e.ezc_fun_info_typeinfo;
|
ezc_fun_info_typeinfo = e.ezc_fun_info_typeinfo;
|
||||||
ezc_var_space_local = e.ezc_var_space_local;
|
|
||||||
ezc_var_date = e.ezc_var_date;
|
|
||||||
model_container_wrapper = e.model_container_wrapper;
|
|
||||||
space_wrapper = e.space_wrapper;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// schema_name and table_name don't have to be copied
|
// schema_name and table_name don't have to be copied
|
||||||
|
@ -193,14 +204,20 @@ public:
|
||||||
child_model = nullptr;
|
child_model = nullptr;
|
||||||
stream = nullptr;
|
stream = nullptr;
|
||||||
was_field_found = false;
|
was_field_found = false;
|
||||||
|
wrapper.clear();
|
||||||
|
status = true;
|
||||||
|
has_autogenerated_select = false;
|
||||||
|
select_flags = Select::default_type;
|
||||||
|
rows_counter = 0;
|
||||||
|
rows_counter_column_name.clear();
|
||||||
|
use_escaping_for_like = false;
|
||||||
|
add_prefix_percent = false;
|
||||||
|
add_postfix_percent = false;
|
||||||
|
|
||||||
#ifdef MORM_HAS_EZC_LIBRARY
|
#ifdef MORM_HAS_EZC_LIBRARY
|
||||||
ezc_fun_info = nullptr;
|
ezc_fun_info = nullptr;
|
||||||
|
ezc_fun_result = false;
|
||||||
ezc_fun_info_typeinfo = nullptr;
|
ezc_fun_info_typeinfo = nullptr;
|
||||||
ezc_var_space_local = nullptr;
|
|
||||||
ezc_var_date = nullptr;
|
|
||||||
model_container_wrapper = nullptr;
|
|
||||||
space_wrapper = nullptr;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,7 +234,6 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
11
src/morm.h
11
src/morm.h
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018-2019, Tomasz Sowa
|
* Copyright (c) 2018-2023, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -32,23 +32,28 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef headerfile_morm_morm
|
#ifndef headerfile_morm_src_morm
|
||||||
#define headerfile_morm_morm
|
#define headerfile_morm_src_morm
|
||||||
|
|
||||||
|
|
||||||
|
#include "version.h"
|
||||||
#include "morm_types.h"
|
#include "morm_types.h"
|
||||||
#include "model.h"
|
#include "model.h"
|
||||||
#include "finder.h"
|
#include "finder.h"
|
||||||
|
|
||||||
#include "jsonexpression.h"
|
#include "jsonexpression.h"
|
||||||
#include "postgresqlexpression.h"
|
#include "postgresqlexpression.h"
|
||||||
|
#include "xmlexpression.h"
|
||||||
|
|
||||||
#include "jsonconnector.h"
|
#include "jsonconnector.h"
|
||||||
#include "postgresqlconnector.h"
|
#include "postgresqlconnector.h"
|
||||||
|
#include "xmlconnector.h"
|
||||||
|
|
||||||
#include "modelconnector.h"
|
#include "modelconnector.h"
|
||||||
#include "clearer.h"
|
#include "clearer.h"
|
||||||
|
|
||||||
|
#include "transaction.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace morm
|
namespace morm
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018-2021, Tomasz Sowa
|
* Copyright (c) 2018-2023, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -32,8 +32,8 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef headerfile_morm_morm_types
|
#ifndef headerfile_morm_src_morm_types
|
||||||
#define headerfile_morm_morm_types
|
#define headerfile_morm_src_morm_types
|
||||||
|
|
||||||
#define MORM_MODEL_WORK_MODE_NONE 0
|
#define MORM_MODEL_WORK_MODE_NONE 0
|
||||||
#define MORM_MODEL_WORK_MODE_GENERATING_DB_SQL 1
|
#define MORM_MODEL_WORK_MODE_GENERATING_DB_SQL 1
|
||||||
|
@ -46,8 +46,9 @@
|
||||||
#define MORM_MODEL_WORK_MODE_ITERATE_PRIMARY_KEY_VALUES 8
|
#define MORM_MODEL_WORK_MODE_ITERATE_PRIMARY_KEY_VALUES 8
|
||||||
#define MORM_MODEL_WORK_MODE_SET_FIELD_VALUE 9
|
#define MORM_MODEL_WORK_MODE_SET_FIELD_VALUE 9
|
||||||
#define MORM_MODEL_WORK_MODE_GET_FIELD_MODEL 10
|
#define MORM_MODEL_WORK_MODE_GET_FIELD_MODEL 10
|
||||||
#define MORM_MODEL_WORK_MODE_PUT_FIELD_RAW_VALUE_TO_STREAM 11
|
#define MORM_MODEL_WORK_MODE_GET_MODEL_WRAPPER 11
|
||||||
|
#define MORM_MODEL_WORK_MODE_PUT_FIELD_RAW_VALUE_TO_STREAM 12
|
||||||
|
#define MORM_MODEL_WORK_MODE_PROPAGATE_SAVE_STATUS 13
|
||||||
|
|
||||||
|
|
||||||
// submodes used in some cases
|
// submodes used in some cases
|
||||||
|
@ -63,7 +64,8 @@
|
||||||
#define MORM_WORK_MODE_MODEL_FIELDS 1
|
#define MORM_WORK_MODE_MODEL_FIELDS 1
|
||||||
#define MORM_WORK_MODE_MODEL_VALUES 2
|
#define MORM_WORK_MODE_MODEL_VALUES 2
|
||||||
#define MORM_WORK_MODE_MODEL_FIELDS_VALUES 3
|
#define MORM_WORK_MODE_MODEL_FIELDS_VALUES 3
|
||||||
#define MORM_WORK_MODE_MODEL_SAVE_FIELDS 4
|
#define MORM_WORK_MODE_MODEL_FIELDS_VALUES_FIELDS 4
|
||||||
|
#define MORM_WORK_MODE_MODEL_SAVE_FIELDS 5
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -75,10 +77,12 @@
|
||||||
#define MORM_OUTPUT_TYPE_DB_UPDATE 3
|
#define MORM_OUTPUT_TYPE_DB_UPDATE 3
|
||||||
|
|
||||||
// change to something like MORM_OUTPUT_TYPE_DB_WHERE_PRIMARY_KEY
|
// change to something like MORM_OUTPUT_TYPE_DB_WHERE_PRIMARY_KEY
|
||||||
|
|
||||||
|
// put a primary key
|
||||||
#define MORM_OUTPUT_TYPE_DB_PRIMARY_KEY 4
|
#define MORM_OUTPUT_TYPE_DB_PRIMARY_KEY 4
|
||||||
|
|
||||||
#define MORM_OUTPUT_TYPE_DB_INSERT_PRIMARY_KEY 5
|
#define MORM_OUTPUT_TYPE_DB_INSERT_PRIMARY_KEY 5
|
||||||
#define MORM_OUTPUT_TYPE_DB_UPDATE_PRIMARY_KEY 5
|
#define MORM_OUTPUT_TYPE_DB_UPDATE_PRIMARY_KEY 6
|
||||||
|
|
||||||
|
|
||||||
//#define MORM_OUTPUT_TYPE_WHERE_CUSTOM 7
|
//#define MORM_OUTPUT_TYPE_WHERE_CUSTOM 7
|
||||||
|
@ -95,7 +99,12 @@
|
||||||
#define MORM_OUTPUT_TYPE_WHERE_GE 24
|
#define MORM_OUTPUT_TYPE_WHERE_GE 24
|
||||||
#define MORM_OUTPUT_TYPE_WHERE_IN 25
|
#define MORM_OUTPUT_TYPE_WHERE_IN 25
|
||||||
#define MORM_OUTPUT_TYPE_WHERE_NOT_EQ 26
|
#define MORM_OUTPUT_TYPE_WHERE_NOT_EQ 26
|
||||||
|
#define MORM_OUTPUT_TYPE_WHERE_LIKE 27
|
||||||
|
#define MORM_OUTPUT_TYPE_WHERE_ILIKE 28
|
||||||
|
#define MORM_OUTPUT_TYPE_WHERE_IS_NULL 29
|
||||||
|
#define MORM_OUTPUT_TYPE_WHERE_IS_NOT_NULL 30
|
||||||
|
|
||||||
|
#define MORM_OUTPUT_TYPE_FIELDS_RECURSIVE 31
|
||||||
|
|
||||||
#define MORM_CONJUNCTION_AND 1
|
#define MORM_CONJUNCTION_AND 1
|
||||||
#define MORM_CONJUNCTION_OR 2
|
#define MORM_CONJUNCTION_OR 2
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018-2021, Tomasz Sowa
|
* Copyright (c) 2018-2024, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -34,16 +34,14 @@
|
||||||
|
|
||||||
// for sleep()
|
// for sleep()
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "postgresqlconnector.h"
|
#include "postgresqlconnector.h"
|
||||||
#include "utf8/utf8.h"
|
|
||||||
#include "postgresqlexpression.h"
|
#include "postgresqlexpression.h"
|
||||||
#include "convert/strtoint.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace morm
|
namespace morm
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
PostgreSQLConnector::PostgreSQLConnector()
|
PostgreSQLConnector::PostgreSQLConnector()
|
||||||
{
|
{
|
||||||
pg_conn = nullptr;
|
pg_conn = nullptr;
|
||||||
|
@ -66,7 +64,6 @@ void PostgreSQLConnector::close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void PostgreSQLConnector::allocate_default_expression()
|
void PostgreSQLConnector::allocate_default_expression()
|
||||||
{
|
{
|
||||||
deallocate_expression();
|
deallocate_expression();
|
||||||
|
@ -75,9 +72,6 @@ void PostgreSQLConnector::allocate_default_expression()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
QueryResult * PostgreSQLConnector::create_query_result()
|
QueryResult * PostgreSQLConnector::create_query_result()
|
||||||
{
|
{
|
||||||
return new PostgreSQLQueryResult();
|
return new PostgreSQLQueryResult();
|
||||||
|
@ -97,13 +91,15 @@ bool PostgreSQLConnector::do_query(const char * query_str, PostgreSQLQueryResult
|
||||||
|
|
||||||
psql_result->psql_result = PQexec(pg_conn, query_str);
|
psql_result->psql_result = PQexec(pg_conn, query_str);
|
||||||
|
|
||||||
if( !psql_result->psql_result )
|
/*
|
||||||
|
* in older versions of PostgreSQL when there was a connection issue then the psql_result pointer would be null
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
if( !psql_result->psql_result || PQstatus(pg_conn) != CONNECTION_OK )
|
||||||
{
|
{
|
||||||
if( PQstatus(pg_conn) != CONNECTION_OK )
|
psql_result->clear();
|
||||||
{
|
assert_connection_is_working();
|
||||||
assert_connection();
|
psql_result->psql_result = PQexec(pg_conn, query_str);
|
||||||
psql_result->psql_result = PQexec(pg_conn, query_str);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( psql_result->psql_result )
|
if( psql_result->psql_result )
|
||||||
|
@ -115,19 +111,15 @@ bool PostgreSQLConnector::do_query(const char * query_str, PostgreSQLQueryResult
|
||||||
|
|
||||||
if( !psql_result->psql_result || psql_result->psql_status == PGRES_FATAL_ERROR )
|
if( !psql_result->psql_result || psql_result->psql_status == PGRES_FATAL_ERROR )
|
||||||
{
|
{
|
||||||
const char * err_msg = PQerrorMessage(pg_conn);
|
|
||||||
|
|
||||||
if( err_msg )
|
|
||||||
{
|
|
||||||
pt::utf8_to_wide(err_msg, psql_result->error_msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
if( log )
|
if( log )
|
||||||
{
|
{
|
||||||
|
const char * err_msg = PQerrorMessage(pg_conn);
|
||||||
(*log) << pt::Log::log1 << "Morm: Problem with this query: \"" << query_str << '\"' << pt::Log::logend;
|
(*log) << pt::Log::log1 << "Morm: Problem with this query: \"" << query_str << '\"' << pt::Log::logend;
|
||||||
|
|
||||||
if( err_msg )
|
if( err_msg )
|
||||||
(*log) << pt::Log::log1 << "Morm: " << err_msg << pt::Log::logend;
|
{
|
||||||
|
log->put_multiline("Morm: ", err_msg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -172,7 +164,7 @@ const char * PostgreSQLConnector::query_last_sequence(const wchar_t * sequence_t
|
||||||
if( log )
|
if( log )
|
||||||
{
|
{
|
||||||
(*log) << pt::Log::log1 << "Morm: expected only one row in sequence result, has: " << psql_result.result_rows
|
(*log) << pt::Log::log1 << "Morm: expected only one row in sequence result, has: " << psql_result.result_rows
|
||||||
<< pt::Log::logend;
|
<< pt::Log::logend;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -180,8 +172,13 @@ const char * PostgreSQLConnector::query_last_sequence(const wchar_t * sequence_t
|
||||||
{
|
{
|
||||||
if( pg_conn && log )
|
if( pg_conn && log )
|
||||||
{
|
{
|
||||||
(*log) << pt::Log::log1 << "Morm: error (currval) for table: " << sequence_table_name << ", "
|
const char * err_msg = PQerrorMessage(pg_conn);
|
||||||
<< PQerrorMessage(pg_conn) << pt::Log::logend;
|
(*log) << pt::Log::log1 << "Morm: error (currval) for table: " << sequence_table_name << pt::Log::logend;
|
||||||
|
|
||||||
|
if( err_msg )
|
||||||
|
{
|
||||||
|
log->put_multiline("Morm: ", err_msg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -191,7 +188,7 @@ const char * PostgreSQLConnector::query_last_sequence(const wchar_t * sequence_t
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool PostgreSQLConnector::query(const pt::TextStream & stream, QueryResult & query_result)
|
bool PostgreSQLConnector::query(const pt::Stream & stream, QueryResult & query_result)
|
||||||
{
|
{
|
||||||
stream.to_str(query_str);
|
stream.to_str(query_str);
|
||||||
return query(query_str.c_str(), query_result);
|
return query(query_str.c_str(), query_result);
|
||||||
|
@ -204,14 +201,14 @@ bool PostgreSQLConnector::query(const std::string & query_str, QueryResult & que
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool PostgreSQLConnector::query_select(const char * query_str, QueryResult & query_result)
|
bool PostgreSQLConnector::query_command(const char * query_str, QueryResult & query_result, ExecStatusType expected_status)
|
||||||
{
|
{
|
||||||
PostgreSQLQueryResult * psql_result = dynamic_cast<PostgreSQLQueryResult*>(&query_result);
|
PostgreSQLQueryResult * psql_result = dynamic_cast<PostgreSQLQueryResult*>(&query_result);
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
if( psql_result )
|
if( psql_result )
|
||||||
{
|
{
|
||||||
result = (do_query(query_str, psql_result) && psql_result->psql_status == PGRES_TUPLES_OK);
|
result = (do_query(query_str, psql_result) && psql_result->psql_status == expected_status);
|
||||||
psql_result->status = result;
|
psql_result->status = result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,181 +216,97 @@ bool PostgreSQLConnector::query_select(const char * query_str, QueryResult & que
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PostgreSQLConnector::query_select(const char * query_str, QueryResult & query_result)
|
||||||
|
{
|
||||||
|
return query_command(query_str, query_result, PGRES_TUPLES_OK);
|
||||||
|
}
|
||||||
|
|
||||||
bool PostgreSQLConnector::query_update(const char * query_str, QueryResult & query_result)
|
bool PostgreSQLConnector::query_update(const char * query_str, QueryResult & query_result)
|
||||||
{
|
{
|
||||||
PostgreSQLQueryResult * psql_result = dynamic_cast<PostgreSQLQueryResult*>(&query_result);
|
return query_command(query_str, query_result, PGRES_COMMAND_OK);
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
if( psql_result )
|
|
||||||
{
|
|
||||||
result = (do_query(query_str, psql_result) && psql_result->psql_status == PGRES_COMMAND_OK);
|
|
||||||
psql_result->status = result;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool PostgreSQLConnector::query_insert(const char * query_str, QueryResult & query_result)
|
bool PostgreSQLConnector::query_insert(const char * query_str, QueryResult & query_result)
|
||||||
{
|
{
|
||||||
PostgreSQLQueryResult * psql_result = dynamic_cast<PostgreSQLQueryResult*>(&query_result);
|
return query_command(query_str, query_result, PGRES_COMMAND_OK);
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
if( psql_result )
|
|
||||||
{
|
|
||||||
result = (do_query(query_str, psql_result) && psql_result->psql_status == PGRES_COMMAND_OK);
|
|
||||||
psql_result->status = result;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool PostgreSQLConnector::query_remove(const char * query_str, QueryResult & query_result)
|
bool PostgreSQLConnector::query_remove(const char * query_str, QueryResult & query_result)
|
||||||
{
|
{
|
||||||
PostgreSQLQueryResult * psql_result = dynamic_cast<PostgreSQLQueryResult*>(&query_result);
|
return query_command(query_str, query_result, PGRES_COMMAND_OK);
|
||||||
bool result = false;
|
}
|
||||||
|
|
||||||
if( psql_result )
|
bool PostgreSQLConnector::query_declare_cursor(const char * query_str, QueryResult & query_result)
|
||||||
{
|
{
|
||||||
result = (do_query(query_str, psql_result) && psql_result->psql_status == PGRES_COMMAND_OK);
|
return query_command(query_str, query_result, PGRES_COMMAND_OK);
|
||||||
psql_result->status = result;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool PostgreSQLConnector::query_select(const pt::TextStream & stream, QueryResult & query_result)
|
bool PostgreSQLConnector::query_select(const pt::Stream & stream, QueryResult & query_result)
|
||||||
{
|
{
|
||||||
stream.to_str(query_str);
|
stream.to_str(query_str);
|
||||||
return query_select(query_str.c_str(), query_result);
|
return query_select(query_str.c_str(), query_result);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PostgreSQLConnector::query_update(const pt::TextStream & stream, QueryResult & query_result)
|
bool PostgreSQLConnector::query_update(const pt::Stream & stream, QueryResult & query_result)
|
||||||
{
|
{
|
||||||
stream.to_str(query_str);
|
stream.to_str(query_str);
|
||||||
return query_update(query_str.c_str(), query_result);
|
return query_update(query_str.c_str(), query_result);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PostgreSQLConnector::query_insert(const pt::TextStream & stream, QueryResult & query_result)
|
bool PostgreSQLConnector::query_insert(const pt::Stream & stream, QueryResult & query_result)
|
||||||
{
|
{
|
||||||
stream.to_str(query_str);
|
stream.to_str(query_str);
|
||||||
return query_insert(query_str.c_str(), query_result);
|
return query_insert(query_str.c_str(), query_result);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PostgreSQLConnector::query_remove(const pt::TextStream & stream, QueryResult & query_result)
|
bool PostgreSQLConnector::query_remove(const pt::Stream & stream, QueryResult & query_result)
|
||||||
{
|
{
|
||||||
stream.to_str(query_str);
|
stream.to_str(query_str);
|
||||||
return query_remove(query_str.c_str(), query_result);
|
return query_remove(query_str.c_str(), query_result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PostgreSQLConnector::query_declare_cursor(const pt::Stream & stream, QueryResult & query_result)
|
||||||
|
{
|
||||||
|
stream.to_str(query_str);
|
||||||
|
return query_declare_cursor(query_str.c_str(), query_result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PostgreSQLConnector::set_conn_param(const std::wstring & database_conn_string)
|
||||||
|
{
|
||||||
|
db_conn_string = database_conn_string;
|
||||||
|
db_hostaddr.clear();
|
||||||
|
db_port.clear();
|
||||||
|
db_database.clear();
|
||||||
|
db_user.clear();
|
||||||
|
db_pass.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PostgreSQLConnector::set_conn_param(const std::wstring & database_host,
|
||||||
|
const std::wstring & database_hostaddr,
|
||||||
|
const std::wstring & database_port,
|
||||||
|
const std::wstring & database_name,
|
||||||
|
const std::wstring & user,
|
||||||
|
const std::wstring & pass)
|
||||||
|
{
|
||||||
|
db_conn_string.clear();
|
||||||
|
db_host = database_host;
|
||||||
|
db_hostaddr = database_hostaddr;
|
||||||
|
db_port = database_port;
|
||||||
|
db_database = database_name;
|
||||||
|
db_user = user;
|
||||||
|
db_pass = pass;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//void PostgreSQLConnector::CreateIdList(const std::vector<long> & id_tab, std::wstring & list, bool add_parentheses)
|
|
||||||
//{
|
|
||||||
//wchar_t buffer[50];
|
|
||||||
//size_t buffer_len = sizeof(buffer) / sizeof(wchar_t);
|
|
||||||
//
|
|
||||||
// list.clear();
|
|
||||||
//
|
|
||||||
// if( add_parentheses )
|
|
||||||
// list += '(';
|
|
||||||
//
|
|
||||||
// for(size_t i=0 ; i<id_tab.size() ; ++i)
|
|
||||||
// {
|
|
||||||
// Toa((unsigned long)id_tab[i], buffer, buffer_len);
|
|
||||||
// list += buffer;
|
|
||||||
//
|
|
||||||
// if( i+1 < id_tab.size() )
|
|
||||||
// list += ',';
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if( add_parentheses )
|
|
||||||
// list += ')';
|
|
||||||
//}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//Error PostgreSQLConnector::BeginTrans()
|
|
||||||
//{
|
|
||||||
// return DoCommand("BEGIN;");
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//Error PostgreSQLConnector::RollbackTrans()
|
|
||||||
//{
|
|
||||||
// return DoCommand("ROLLBACK;");
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//Error PostgreSQLConnector::CommitTrans()
|
|
||||||
//{
|
|
||||||
// return DoCommand("COMMIT;");
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//bool PostgreSQLConnector::EndTrans(bool everything_ok)
|
|
||||||
//{
|
|
||||||
//bool result;
|
|
||||||
//
|
|
||||||
// if( everything_ok )
|
|
||||||
// {
|
|
||||||
// result = (CommitTrans() == WINIX_ERR_OK);
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// RollbackTrans();
|
|
||||||
// // we return the old err code
|
|
||||||
// result = false;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//return result;
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//Error PostgreSQLConnector::EndTrans(Error err)
|
|
||||||
//{
|
|
||||||
// if( err == WINIX_ERR_OK )
|
|
||||||
// {
|
|
||||||
// err = CommitTrans();
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// // we return the old err code
|
|
||||||
// RollbackTrans();
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//return err;
|
|
||||||
//}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void PostgreSQLConnector::set_conn_param(const std::wstring & database_name, const std::wstring & user, const std::wstring & pass)
|
void PostgreSQLConnector::set_conn_param(const std::wstring & database_name, const std::wstring & user, const std::wstring & pass)
|
||||||
{
|
{
|
||||||
|
db_conn_string.clear();
|
||||||
|
db_host.clear();
|
||||||
|
db_hostaddr.clear();
|
||||||
|
db_port.clear();
|
||||||
db_database = database_name;
|
db_database = database_name;
|
||||||
db_user = user;
|
db_user = user;
|
||||||
db_pass = pass;
|
db_pass = pass;
|
||||||
|
@ -413,6 +326,17 @@ void PostgreSQLConnector::overwrite(pt::TextStream & stream)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PostgreSQLConnector::overwrite(pt::WTextStream & stream)
|
||||||
|
{
|
||||||
|
pt::WTextStream::iterator i = stream.begin();
|
||||||
|
|
||||||
|
for( ; i != stream.end() ; ++i)
|
||||||
|
{
|
||||||
|
*i = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
stream.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void PostgreSQLConnector::connect()
|
void PostgreSQLConnector::connect()
|
||||||
|
@ -427,15 +351,44 @@ void PostgreSQLConnector::connect()
|
||||||
if( db_expression )
|
if( db_expression )
|
||||||
{
|
{
|
||||||
stream.clear();
|
stream.clear();
|
||||||
stream << "dbname='";
|
|
||||||
db_expression->esc(db_database, stream);
|
|
||||||
|
|
||||||
stream << "' user='";
|
if( !db_conn_string.empty() )
|
||||||
db_expression->esc(db_user, stream);
|
{
|
||||||
|
stream << db_conn_string;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
stream << "dbname='";
|
||||||
|
db_expression->esc(db_database, stream);
|
||||||
|
|
||||||
stream << "' password='";
|
stream << "' user='";
|
||||||
db_expression->esc(db_pass, stream);
|
db_expression->esc(db_user, stream);
|
||||||
stream << "'";
|
|
||||||
|
stream << "' password='";
|
||||||
|
db_expression->esc(db_pass, stream);
|
||||||
|
stream << "'";
|
||||||
|
|
||||||
|
if( !db_host.empty() )
|
||||||
|
{
|
||||||
|
stream << " host='";
|
||||||
|
db_expression->esc(db_host, stream);
|
||||||
|
stream << "'";
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !db_hostaddr.empty() )
|
||||||
|
{
|
||||||
|
stream << " hostaddr='";
|
||||||
|
db_expression->esc(db_hostaddr, stream);
|
||||||
|
stream << "'";
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !db_port.empty() )
|
||||||
|
{
|
||||||
|
stream << " port='";
|
||||||
|
db_expression->esc(db_port, stream);
|
||||||
|
stream << "'";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::string str;
|
std::string str;
|
||||||
stream.to_str(str);
|
stream.to_str(str);
|
||||||
|
@ -447,9 +400,17 @@ void PostgreSQLConnector::connect()
|
||||||
// use PQstatus(pg_conn) to check whether the connection works fine
|
// use PQstatus(pg_conn) to check whether the connection works fine
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
//
|
void PostgreSQLConnector::log_no_connection(size_t attempts)
|
||||||
//
|
{
|
||||||
|
if( log )
|
||||||
|
{
|
||||||
|
(*log) << pt::Log::log2 << "Morm: connection to the database cannot be established";
|
||||||
|
(*log) << pt::Log::log3 << ", (" << attempts << " attempt(s))" << pt::Log::logend;
|
||||||
|
(*log) << pt::Log::logsave;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void PostgreSQLConnector::log_connection_socket()
|
void PostgreSQLConnector::log_connection_socket()
|
||||||
{
|
{
|
||||||
|
@ -461,8 +422,18 @@ void PostgreSQLConnector::log_connection_socket()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PostgreSQLConnector::wait_for_connection()
|
|
||||||
|
bool PostgreSQLConnector::wait_for_connection(size_t attempts_max, size_t attempt_delay)
|
||||||
{
|
{
|
||||||
|
size_t attempts = 0;
|
||||||
|
bool attempts_exceeded = false;
|
||||||
|
|
||||||
|
if( attempt_delay == 0 )
|
||||||
|
attempt_delay = 1;
|
||||||
|
|
||||||
|
if( attempt_delay > 120 )
|
||||||
|
attempt_delay = 120;
|
||||||
|
|
||||||
if( !pg_conn || PQstatus(pg_conn) != CONNECTION_OK )
|
if( !pg_conn || PQstatus(pg_conn) != CONNECTION_OK )
|
||||||
{
|
{
|
||||||
if( log )
|
if( log )
|
||||||
|
@ -470,24 +441,39 @@ void PostgreSQLConnector::wait_for_connection()
|
||||||
(*log) << pt::Log::log3 << "Morm: waiting for the db to be ready...." << pt::Log::logend << pt::Log::logsave;
|
(*log) << pt::Log::log3 << "Morm: waiting for the db to be ready...." << pt::Log::logend << pt::Log::logsave;
|
||||||
}
|
}
|
||||||
|
|
||||||
while( !assert_connection(false) )
|
while( !attempts_exceeded && !assert_connection_is_working(false) )
|
||||||
{
|
{
|
||||||
sleep(5);
|
if( attempts_max != 0 )
|
||||||
}
|
{
|
||||||
|
attempts += 1;
|
||||||
|
attempts_exceeded = (attempts >= attempts_max);
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !attempts_exceeded )
|
||||||
|
{
|
||||||
|
sleep(attempt_delay);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( attempts_exceeded )
|
||||||
|
{
|
||||||
|
log_no_connection(attempts);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
log_connection_socket();
|
log_connection_socket();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return !attempts_exceeded;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// IMPROVE ME what about the exception now?
|
// IMPROVE ME what about the exception now?
|
||||||
bool PostgreSQLConnector::assert_connection(bool put_log)
|
bool PostgreSQLConnector::assert_connection_is_working(bool put_log)
|
||||||
{
|
{
|
||||||
bool was_connection = true;
|
bool was_connection = true;
|
||||||
|
|
||||||
|
|
||||||
if( !pg_conn )
|
if( !pg_conn )
|
||||||
{
|
{
|
||||||
was_connection = false;
|
was_connection = false;
|
||||||
|
@ -559,21 +545,31 @@ void PostgreSQLConnector::log_unsupported_bin_format()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PostgreSQLConnector::unescape_bin_char(const char * str, char & field_value)
|
||||||
size_t PostgreSQLConnector::unescape_bin_char(const char * str, wchar_t & field_value, const FT & field_type)
|
|
||||||
{
|
{
|
||||||
if( str[0]!='\\' || str[1]!='x' )
|
if( str[0]!='\\' || str[1]!='x' )
|
||||||
{
|
{
|
||||||
log_unsupported_bin_format();
|
log_unsupported_bin_format();
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return unescape_hex_char(str + 2, field_value, field_type);
|
DbConnector::unescape_bin_char(str + 2, field_value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PostgreSQLConnector::unescape_bin_char(const char * str, char32_t & field_value)
|
||||||
|
{
|
||||||
|
if( str[0]!='\\' || str[1]!='x' )
|
||||||
|
{
|
||||||
|
log_unsupported_bin_format();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DbConnector::unescape_bin_char(str + 2, field_value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void PostgreSQLConnector::unescape_bin_string(const char * str, std::string & out)
|
void PostgreSQLConnector::unescape_bin_string(const char * str, std::string & out)
|
||||||
{
|
{
|
||||||
|
@ -583,12 +579,12 @@ void PostgreSQLConnector::unescape_bin_string(const char * str, std::string & ou
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
unescape_hex_string(str + 2, out);
|
DbConnector::unescape_bin_string(str + 2, out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PostgreSQLConnector::unescape_bin_string(const char * str, std::wstring & out, const FT & field_type)
|
void PostgreSQLConnector::unescape_bin_string(const char * str, std::wstring & out)
|
||||||
{
|
{
|
||||||
if( str[0]!='\\' || str[1]!='x' )
|
if( str[0]!='\\' || str[1]!='x' )
|
||||||
{
|
{
|
||||||
|
@ -596,7 +592,20 @@ void PostgreSQLConnector::unescape_bin_string(const char * str, std::wstring & o
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
unescape_hex_string(str + 2, out, field_type);
|
DbConnector::unescape_bin_string(str + 2, out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PostgreSQLConnector::unescape_bin_string(const char * str, pt::Stream & out)
|
||||||
|
{
|
||||||
|
if( str[0]!='\\' || str[1]!='x' )
|
||||||
|
{
|
||||||
|
log_unsupported_bin_format();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DbConnector::unescape_bin_string(str + 2, out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018-2021, Tomasz Sowa
|
* Copyright (c) 2018-2024, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -32,8 +32,8 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef headerfile_morm_postgresqlconnector
|
#ifndef headerfile_morm_src_postgresqlconnector
|
||||||
#define headerfile_morm_postgresqlconnector
|
#define headerfile_morm_src_postgresqlconnector
|
||||||
|
|
||||||
#include <libpq-fe.h>
|
#include <libpq-fe.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -55,31 +55,74 @@ public:
|
||||||
virtual ~PostgreSQLConnector();
|
virtual ~PostgreSQLConnector();
|
||||||
|
|
||||||
|
|
||||||
bool query(const pt::TextStream & stream, QueryResult & query_result);
|
bool query(const pt::Stream & stream, QueryResult & query_result) override;
|
||||||
bool query(const char * query_str, QueryResult & query_result);
|
bool query(const char * query_str, QueryResult & query_result) override;
|
||||||
bool query(const std::string & query_str, QueryResult & query_result);
|
bool query(const std::string & query_str, QueryResult & query_result) override;
|
||||||
|
|
||||||
bool query_select(const char * query_str, QueryResult & query_result);
|
bool query_select(const char * query_str, QueryResult & query_result) override;
|
||||||
bool query_update(const char * query_str, QueryResult & query_result);
|
bool query_update(const char * query_str, QueryResult & query_result) override;
|
||||||
bool query_insert(const char * query_str, QueryResult & query_result);
|
bool query_insert(const char * query_str, QueryResult & query_result) override;
|
||||||
bool query_remove(const char * query_str, QueryResult & query_result);
|
bool query_remove(const char * query_str, QueryResult & query_result) override;
|
||||||
|
bool query_declare_cursor(const char * query_str, QueryResult & query_result) override;
|
||||||
|
|
||||||
bool query_select(const pt::TextStream & stream, QueryResult & query_result);
|
bool query_select(const pt::Stream & stream, QueryResult & query_result) override;
|
||||||
bool query_update(const pt::TextStream & stream, QueryResult & query_result);
|
bool query_update(const pt::Stream & stream, QueryResult & query_result) override;
|
||||||
bool query_insert(const pt::TextStream & stream, QueryResult & query_result);
|
bool query_insert(const pt::Stream & stream, QueryResult & query_result) override;
|
||||||
bool query_remove(const pt::TextStream & stream, QueryResult & query_result);
|
bool query_remove(const pt::Stream & stream, QueryResult & query_result) override;
|
||||||
|
bool query_declare_cursor(const pt::Stream & stream, QueryResult & query_result) override;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* https://www.postgresql.org/docs/14/libpq-connect.html#LIBPQ-CONNSTRING
|
||||||
|
*/
|
||||||
|
virtual void set_conn_param(const std::wstring & database_conn_string);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* database_host - name of host to connect to (can be empty)
|
||||||
|
* database_hostaddr - numeric IP address of host to connect to (can be empty)
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* meaning of this parameters is the same as described in
|
||||||
|
* https://www.postgresql.org/docs/14/libpq-connect.html#LIBPQ-CONNSTRING
|
||||||
|
*
|
||||||
|
* from above documentation:
|
||||||
|
* Using hostaddr allows the application to avoid a host name look-up, which might be important
|
||||||
|
* in applications with time constraints. However, a host name is required for GSSAPI or SSPI
|
||||||
|
* authentication methods, as well as for verify-full SSL certificate verification.
|
||||||
|
* The following rules are used:
|
||||||
|
*
|
||||||
|
* - If host is specified without hostaddr, a host name lookup occurs.
|
||||||
|
*
|
||||||
|
* - If hostaddr is specified without host, the value for hostaddr gives the server network address.
|
||||||
|
* The connection attempt will fail if the authentication method requires a host name.
|
||||||
|
*
|
||||||
|
* - If both host and hostaddr are specified, the value for hostaddr gives the server network address.
|
||||||
|
* The value for host is ignored unless the authentication method requires it, in which case it will
|
||||||
|
* be used as the host name.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
virtual void set_conn_param(const std::wstring & database_host, const std::wstring & database_hostaddr, const std::wstring & database_port,
|
||||||
|
const std::wstring & database, const std::wstring & user, const std::wstring & pass);
|
||||||
|
|
||||||
virtual void set_conn_param(const std::wstring & database, const std::wstring & user, const std::wstring & pass);
|
virtual void set_conn_param(const std::wstring & database, const std::wstring & user, const std::wstring & pass);
|
||||||
virtual void connect();
|
|
||||||
virtual void wait_for_connection();
|
|
||||||
virtual void close();
|
|
||||||
//virtual bool assert_connection(bool put_log = true, bool throw_if_no_connection = true);
|
|
||||||
virtual bool assert_connection(bool put_log = true);
|
|
||||||
virtual void set_db_parameters();
|
|
||||||
virtual void log_connection_socket();
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* waiting for a valid connection to the database
|
||||||
|
*
|
||||||
|
* attempts_max - how many connection attempts are allowed (0 - infinite)
|
||||||
|
* attempt_delay - delay between each attempt (in seconds)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
virtual bool wait_for_connection(size_t attempts_max = 0, size_t attempt_delay = 5);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* close the connection with the database if it was open
|
||||||
|
*/
|
||||||
|
virtual void close();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -88,21 +131,37 @@ protected:
|
||||||
pt::TextStream stream;
|
pt::TextStream stream;
|
||||||
std::string query_str;
|
std::string query_str;
|
||||||
|
|
||||||
|
std::wstring db_conn_string;
|
||||||
|
std::wstring db_host;
|
||||||
|
std::wstring db_hostaddr;
|
||||||
|
std::wstring db_port;
|
||||||
std::wstring db_database;
|
std::wstring db_database;
|
||||||
std::wstring db_user;
|
std::wstring db_user;
|
||||||
std::wstring db_pass;
|
std::wstring db_pass;
|
||||||
|
|
||||||
|
virtual void set_db_parameters();
|
||||||
|
virtual void log_no_connection(size_t attempts);
|
||||||
|
virtual void log_connection_socket();
|
||||||
|
virtual bool assert_connection_is_working(bool put_log = true);
|
||||||
|
virtual void connect();
|
||||||
|
|
||||||
virtual bool do_query(const char * query_str, PostgreSQLQueryResult * psql_result);
|
virtual bool do_query(const char * query_str, PostgreSQLQueryResult * psql_result);
|
||||||
virtual void allocate_default_expression();
|
virtual bool query_command(const char * query_str, QueryResult & query_result, ExecStatusType expected_status);
|
||||||
|
virtual void allocate_default_expression() override;
|
||||||
virtual void overwrite(pt::TextStream & stream);
|
virtual void overwrite(pt::TextStream & stream);
|
||||||
virtual const char * query_last_sequence(const wchar_t * sequence_table_name);
|
virtual void overwrite(pt::WTextStream & stream);
|
||||||
virtual QueryResult * create_query_result();
|
virtual const char * query_last_sequence(const wchar_t * sequence_table_name) override;
|
||||||
|
virtual QueryResult * create_query_result() override;
|
||||||
|
|
||||||
void log_unsupported_bin_format();
|
void log_unsupported_bin_format();
|
||||||
|
|
||||||
size_t unescape_bin_char(const char * str, wchar_t & field_value, const FT & field_type);
|
void unescape_bin_char(const char * str, char & field_value) override;
|
||||||
void unescape_bin_string(const char * str, std::string & out);
|
void unescape_bin_char(const char * str, char32_t & field_value) override;
|
||||||
void unescape_bin_string(const char * str, std::wstring & out, const FT & field_type);
|
|
||||||
|
void unescape_bin_string(const char * str, std::string & out) override;
|
||||||
|
void unescape_bin_string(const char * str, std::wstring & out) override;
|
||||||
|
void unescape_bin_string(const char * str, pt::Stream & out) override;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018-2021, Tomasz Sowa
|
* Copyright (c) 2018-2024, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -40,7 +40,7 @@ namespace morm
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void PostgreSQLExpression::before_field_value_string(const FT & field_type)
|
void PostgreSQLExpression::before_field_value_string(const FT & field_type, ModelEnv * model_env)
|
||||||
{
|
{
|
||||||
if( field_type.is_binary() )
|
if( field_type.is_binary() )
|
||||||
{
|
{
|
||||||
|
@ -52,49 +52,76 @@ void PostgreSQLExpression::before_field_value_string(const FT & field_type)
|
||||||
(*out_stream) << "'";
|
(*out_stream) << "'";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
if( field_type.is_numeric() )
|
||||||
|
{
|
||||||
|
(*out_stream) << "'";
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
(*out_stream) << "E'";
|
(*out_stream) << "E'";
|
||||||
|
|
||||||
|
if( model_env && model_env->add_prefix_percent )
|
||||||
|
(*out_stream) << '%';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PostgreSQLExpression::after_field_value_string(const FT & field_type)
|
void PostgreSQLExpression::after_field_value_string(const FT & field_type, ModelEnv * model_env)
|
||||||
{
|
{
|
||||||
|
if( model_env && model_env->add_postfix_percent )
|
||||||
|
(*out_stream) << '%';
|
||||||
|
|
||||||
(*out_stream) << "'";
|
(*out_stream) << "'";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PostgreSQLExpression::esc_char(char32_t val, pt::Stream & stream, const FT & field_type, ModelEnv * model_env)
|
||||||
void PostgreSQLExpression::esc(char val, pt::TextStream & stream, const FT & field_type)
|
|
||||||
{
|
{
|
||||||
if( field_type.is_hexadecimal() || field_type.is_binary() )
|
if( model_env && model_env->use_escaping_for_like )
|
||||||
{
|
{
|
||||||
char_to_hex(val, stream);
|
if( val == '%' )
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch( val )
|
|
||||||
{
|
{
|
||||||
case '\\': stream << "\\\\"; break;
|
stream << "\\\\%"; // gives: "\\%" (we are using a string form with E so we need to double backslashes here)
|
||||||
case '\'': stream << "\\\'"; break; // don't use "''" because we use the method for PQconnectdb too
|
return true;
|
||||||
default:
|
}
|
||||||
if( val != 0 )
|
else
|
||||||
{
|
if( val == '_' )
|
||||||
stream << val;
|
{
|
||||||
}
|
stream << "\\\\_"; // gives: "\\_"
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if( val == '\\' )
|
||||||
|
{
|
||||||
|
stream << "\\\\\\\\"; // gives: "\\\\"
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( val == '\\' )
|
||||||
|
{
|
||||||
|
stream << "\\\\";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if( val == '\'' )
|
||||||
|
{
|
||||||
|
stream << "\\\'"; // don't use "''" because we use the method for PQconnectdb too
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if( val == 0 )
|
||||||
|
{
|
||||||
|
// may put the replacement character to the stream?
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PostgreSQLExpression::esc(const pt::Date & date, pt::TextStream & stream, const FT & field_type)
|
DbExpression & PostgreSQLExpression::page(pt::Stream & stream, size_t page_number, size_t page_size)
|
||||||
{
|
{
|
||||||
stream << date << "+00";
|
stream << " OFFSET " << (page_number*page_size) << " LIMIT " << page_size << " ";
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
DbExpression & PostgreSQLExpression::page(pt::TextStream & stream, size_t page_number, size_t page_size)
|
|
||||||
{
|
|
||||||
stream << " offset " << page_number << " limit " << page_size << " ";
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018-2021, Tomasz Sowa
|
* Copyright (c) 2018-2024, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -32,8 +32,8 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef headerfile_morm_postgresqlexpression
|
#ifndef headerfile_morm_src_postgresqlexpression
|
||||||
#define headerfile_morm_postgresqlexpression
|
#define headerfile_morm_src_postgresqlexpression
|
||||||
|
|
||||||
#include "dbexpression.h"
|
#include "dbexpression.h"
|
||||||
|
|
||||||
|
@ -45,10 +45,7 @@ class PostgreSQLExpression : public DbExpression
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void esc(char val, pt::TextStream & stream, const FT & field_type);
|
DbExpression & page(pt::Stream & stream, size_t page_number, size_t page_size) override;
|
||||||
void esc(const pt::Date & date, pt::TextStream & stream, const FT & field_type);
|
|
||||||
|
|
||||||
DbExpression & page(pt::TextStream & stream, size_t page_number, size_t page_size);
|
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -58,9 +55,10 @@ protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void before_field_value_string(const FT & field_type);
|
void before_field_value_string(const FT & field_type, ModelEnv * model_env) override;
|
||||||
void after_field_value_string(const FT & field_type);
|
void after_field_value_string(const FT & field_type, ModelEnv * model_env) override;
|
||||||
|
|
||||||
|
bool esc_char(char32_t val, pt::Stream & stream, const FT & field_type, ModelEnv * model_env) override;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -32,8 +32,8 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef headerfile_morm_postgresqlqueryresult
|
#ifndef headerfile_morm_src_postgresqlqueryresult
|
||||||
#define headerfile_morm_postgresqlqueryresult
|
#define headerfile_morm_src_postgresqlqueryresult
|
||||||
|
|
||||||
#include "queryresult.h"
|
#include "queryresult.h"
|
||||||
#include <libpq-fe.h>
|
#include <libpq-fe.h>
|
||||||
|
|
|
@ -32,8 +32,8 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef headerfile_morm_queryresult
|
#ifndef headerfile_morm_src_queryresult
|
||||||
#define headerfile_morm_queryresult
|
#define headerfile_morm_src_queryresult
|
||||||
|
|
||||||
#include <log/log.h>
|
#include <log/log.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
|
@ -0,0 +1,130 @@
|
||||||
|
/*
|
||||||
|
* This file is a part of morm
|
||||||
|
* and is distributed under the 2-Clause BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022-2023, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef headerfile_morm_src_select
|
||||||
|
#define headerfile_morm_src_select
|
||||||
|
|
||||||
|
namespace morm
|
||||||
|
{
|
||||||
|
|
||||||
|
/*
|
||||||
|
* additional arguments for Finder::select method
|
||||||
|
*/
|
||||||
|
class Select
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
enum SelectType
|
||||||
|
{
|
||||||
|
default_type = 0,
|
||||||
|
no_auto_generated_columns = 1,
|
||||||
|
with_rows_counter = 2,
|
||||||
|
distinct = 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* type can be a superposition from SelectType values
|
||||||
|
*/
|
||||||
|
int type;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Select()
|
||||||
|
{
|
||||||
|
type = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Select(const Select & select_type)
|
||||||
|
{
|
||||||
|
this->type = select_type.type;
|
||||||
|
}
|
||||||
|
|
||||||
|
Select(SelectType select_type)
|
||||||
|
{
|
||||||
|
this->type = static_cast<int>(select_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
Select(int type)
|
||||||
|
{
|
||||||
|
this->type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
Select & operator=(const Select & select_type)
|
||||||
|
{
|
||||||
|
type = select_type.type;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Select & operator=(SelectType select_type)
|
||||||
|
{
|
||||||
|
this->type = static_cast<int>(select_type);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Select & operator=(int type)
|
||||||
|
{
|
||||||
|
this->type = type;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool is_flag_set(int flag_mask) const
|
||||||
|
{
|
||||||
|
return (type & flag_mask) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool is_with_rows_counter() const
|
||||||
|
{
|
||||||
|
return is_flag_set(with_rows_counter);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool is_no_auto_generated_columns() const
|
||||||
|
{
|
||||||
|
return is_flag_set(no_auto_generated_columns);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool is_distinct() const
|
||||||
|
{
|
||||||
|
return is_flag_set(distinct);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -32,8 +32,8 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef headerfile_morm_spacewrapper
|
#ifndef headerfile_morm_src_spacewrapper
|
||||||
#define headerfile_morm_spacewrapper
|
#define headerfile_morm_src_spacewrapper
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
@ -49,11 +49,6 @@ class SpaceWrapper : public BaseObjectWrapper
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
SpaceWrapper() = delete;
|
|
||||||
SpaceWrapper(const SpaceWrapper &) = delete;
|
|
||||||
SpaceWrapper & operator=(const SpaceWrapper &) = delete;
|
|
||||||
|
|
||||||
|
|
||||||
SpaceWrapper(pt::Space * space)
|
SpaceWrapper(pt::Space * space)
|
||||||
{
|
{
|
||||||
this->space = space;
|
this->space = space;
|
||||||
|
@ -104,7 +99,6 @@ public:
|
||||||
return std::numeric_limits<size_t>::max();
|
return std::numeric_limits<size_t>::max();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
const size_t SPACE_INDICES_TABLE_SIZE = 32;
|
const size_t SPACE_INDICES_TABLE_SIZE = 32;
|
||||||
|
|
|
@ -0,0 +1,285 @@
|
||||||
|
/*
|
||||||
|
* This file is a part of morm
|
||||||
|
* and is distributed under the 2-Clause BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "transaction.h"
|
||||||
|
#include "dbconnector.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace morm
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Transaction::Transaction(ModelConnector * model_connector, bool auto_begin_transaction)
|
||||||
|
{
|
||||||
|
this->model_connector = model_connector;
|
||||||
|
is_transaction_started = false;
|
||||||
|
is_transaction_successful = true;
|
||||||
|
transaction_index = 0;
|
||||||
|
transaction_group = 0;
|
||||||
|
|
||||||
|
if( auto_begin_transaction )
|
||||||
|
{
|
||||||
|
begin();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Transaction::Transaction(const Transaction &)
|
||||||
|
{
|
||||||
|
// at the moment do not allow to copy transactions (make me private)
|
||||||
|
}
|
||||||
|
|
||||||
|
Transaction::Transaction(Transaction &&)
|
||||||
|
{
|
||||||
|
// at the moment do not allow to move transactions (make me private)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Transaction::~Transaction()
|
||||||
|
{
|
||||||
|
if( is_current_group() && is_transaction_started )
|
||||||
|
{
|
||||||
|
rollback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool Transaction::is_started()
|
||||||
|
{
|
||||||
|
return is_current_group() && is_transaction_started;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Transaction::is_successful()
|
||||||
|
{
|
||||||
|
return is_transaction_successful;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Transaction::set_successful(bool is_successful)
|
||||||
|
{
|
||||||
|
is_transaction_successful = is_successful;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool Transaction::begin()
|
||||||
|
{
|
||||||
|
bool status = false;
|
||||||
|
pt::Log * log = get_logger();
|
||||||
|
|
||||||
|
if( is_current_group() && is_transaction_started )
|
||||||
|
{
|
||||||
|
if( log )
|
||||||
|
{
|
||||||
|
(*log) << pt::Log::log2 << "Morm: a transaction is already started - rollbacking existing transaction before creating a new one" << pt::Log::logend;
|
||||||
|
}
|
||||||
|
|
||||||
|
rollback(); // what if there is an error here? skip it at the moment
|
||||||
|
}
|
||||||
|
|
||||||
|
if( model_connector )
|
||||||
|
{
|
||||||
|
DbConnector * db_connector = model_connector->get_db_connector();
|
||||||
|
|
||||||
|
if( db_connector )
|
||||||
|
{
|
||||||
|
status = db_connector->begin();
|
||||||
|
transaction_index = db_connector->get_transaction_index();
|
||||||
|
transaction_group = db_connector->get_transaction_group();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( status )
|
||||||
|
{
|
||||||
|
is_transaction_started = true;
|
||||||
|
is_transaction_successful = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
is_transaction_started = false;
|
||||||
|
is_transaction_successful = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Transaction::begin_if_needed()
|
||||||
|
{
|
||||||
|
bool status = true;
|
||||||
|
|
||||||
|
if( !is_transaction_started )
|
||||||
|
{
|
||||||
|
status = begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Transaction::rollback()
|
||||||
|
{
|
||||||
|
bool status = false;
|
||||||
|
pt::Log * log = get_logger();
|
||||||
|
|
||||||
|
if( is_current_group() )
|
||||||
|
{
|
||||||
|
if( is_transaction_started )
|
||||||
|
{
|
||||||
|
if( model_connector )
|
||||||
|
{
|
||||||
|
DbConnector * db_connector = model_connector->get_db_connector();
|
||||||
|
|
||||||
|
if( db_connector )
|
||||||
|
{
|
||||||
|
status = db_connector->rollback(transaction_index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// set it to false even if rollback failed
|
||||||
|
is_transaction_started = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( log )
|
||||||
|
{
|
||||||
|
(*log) << pt::Log::log1 << "Morm: not doing rollback, a transaction was not started - skipping" << pt::Log::logend;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( log )
|
||||||
|
{
|
||||||
|
(*log) << pt::Log::log1 << "Morm: not doing rollback, this transaction has already been completed" << pt::Log::logend;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Transaction::commit()
|
||||||
|
{
|
||||||
|
bool status = false;
|
||||||
|
pt::Log * log = get_logger();
|
||||||
|
|
||||||
|
if( is_current_group() )
|
||||||
|
{
|
||||||
|
if( is_transaction_started )
|
||||||
|
{
|
||||||
|
if( model_connector )
|
||||||
|
{
|
||||||
|
DbConnector * db_connector = model_connector->get_db_connector();
|
||||||
|
|
||||||
|
if( db_connector )
|
||||||
|
{
|
||||||
|
status = db_connector->commit(transaction_index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// set it to false even if commit failed
|
||||||
|
is_transaction_started = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( log )
|
||||||
|
{
|
||||||
|
(*log) << pt::Log::log1 << "Morm: not doing commit, a transaction was not started - skipping" << pt::Log::logend;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( log )
|
||||||
|
{
|
||||||
|
(*log) << pt::Log::log1 << "Morm: not doing commit, this transaction has already been completed" << pt::Log::logend;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Transaction::finish()
|
||||||
|
{
|
||||||
|
bool status = false;
|
||||||
|
|
||||||
|
if( is_transaction_successful )
|
||||||
|
status = commit();
|
||||||
|
else
|
||||||
|
status = rollback();
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pt::Log * Transaction::get_logger()
|
||||||
|
{
|
||||||
|
pt::Log * logger = nullptr;
|
||||||
|
|
||||||
|
if( model_connector )
|
||||||
|
{
|
||||||
|
logger = model_connector->get_logger();
|
||||||
|
}
|
||||||
|
|
||||||
|
return logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Transaction::is_current_group()
|
||||||
|
{
|
||||||
|
if( model_connector )
|
||||||
|
{
|
||||||
|
DbConnector * db_connector = model_connector->get_db_connector();
|
||||||
|
|
||||||
|
if( db_connector )
|
||||||
|
{
|
||||||
|
return (db_connector->get_transaction_group() == transaction_group);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,89 @@
|
||||||
|
/*
|
||||||
|
* This file is a part of morm
|
||||||
|
* and is distributed under the 2-Clause BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef headerfile_morm_src_transaction
|
||||||
|
#define headerfile_morm_src_transaction
|
||||||
|
|
||||||
|
#include "log/log.h"
|
||||||
|
#include "modelconnector.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace morm
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
class Transaction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
Transaction(ModelConnector * model_connector, bool auto_begin_transaction = true);
|
||||||
|
virtual ~Transaction();
|
||||||
|
|
||||||
|
virtual bool is_started();
|
||||||
|
|
||||||
|
virtual bool is_successful();
|
||||||
|
virtual void set_successful(bool is_successful = true);
|
||||||
|
|
||||||
|
virtual bool begin();
|
||||||
|
virtual bool begin_if_needed();
|
||||||
|
virtual bool rollback();
|
||||||
|
virtual bool commit();
|
||||||
|
virtual bool finish();
|
||||||
|
|
||||||
|
virtual bool is_current_group();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
ModelConnector * model_connector;
|
||||||
|
bool is_transaction_started;
|
||||||
|
bool is_transaction_successful;
|
||||||
|
size_t transaction_index;
|
||||||
|
size_t transaction_group;
|
||||||
|
|
||||||
|
virtual pt::Log * get_logger();
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Transaction(const Transaction &);
|
||||||
|
Transaction(Transaction &&);
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
* This file is a part of morm
|
||||||
|
* and is distributed under the 2-Clause BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef headerfile_morm_src_version
|
||||||
|
#define headerfile_morm_src_version
|
||||||
|
|
||||||
|
|
||||||
|
#define MORM_VERSION_MAJOR 0
|
||||||
|
#define MORM_VERSION_MINOR 7
|
||||||
|
#define MORM_VERSION_PATCH 0
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,193 @@
|
||||||
|
/*
|
||||||
|
* This file is a part of morm
|
||||||
|
* and is distributed under the 2-Clause BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef headerfile_morm_src_wrapper
|
||||||
|
#define headerfile_morm_src_wrapper
|
||||||
|
|
||||||
|
#include "spacewrapper.h"
|
||||||
|
#include "date/date.h"
|
||||||
|
#include "modelcontainerwrapper.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace morm
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
class Wrapper
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
Model * model;
|
||||||
|
ModelContainerWrapper * model_container_wrapper;
|
||||||
|
pt::Date * date;
|
||||||
|
SpaceWrapper * space_wrapper;
|
||||||
|
|
||||||
|
|
||||||
|
Wrapper()
|
||||||
|
{
|
||||||
|
model = nullptr;
|
||||||
|
model_container_wrapper = nullptr;
|
||||||
|
date = nullptr;
|
||||||
|
space_wrapper = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Wrapper(const Wrapper & wrapper)
|
||||||
|
{
|
||||||
|
model = nullptr;
|
||||||
|
model_container_wrapper = nullptr;
|
||||||
|
date = nullptr;
|
||||||
|
space_wrapper = nullptr;
|
||||||
|
|
||||||
|
copy(wrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Wrapper & operator=(const Wrapper & wrapper)
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
copy(wrapper);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virtual ~Wrapper()
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virtual void clear()
|
||||||
|
{
|
||||||
|
if( model_container_wrapper )
|
||||||
|
{
|
||||||
|
model_container_wrapper->decrement_reference_counter();
|
||||||
|
|
||||||
|
if( model_container_wrapper->get_reference_counter() == 0 && model_container_wrapper->should_be_auto_removed() )
|
||||||
|
{
|
||||||
|
delete model_container_wrapper;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( space_wrapper )
|
||||||
|
{
|
||||||
|
space_wrapper->decrement_reference_counter();
|
||||||
|
|
||||||
|
if( space_wrapper->get_reference_counter() == 0 && space_wrapper->should_be_auto_removed() )
|
||||||
|
{
|
||||||
|
delete space_wrapper;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
model = nullptr;
|
||||||
|
model_container_wrapper = nullptr;
|
||||||
|
date = nullptr;
|
||||||
|
space_wrapper = nullptr;
|
||||||
|
|
||||||
|
clear_childs();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virtual void clear_childs()
|
||||||
|
{
|
||||||
|
childs_map.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virtual Wrapper * add_child(const std::wstring & child_name, Wrapper & wrapper)
|
||||||
|
{
|
||||||
|
Wrapper & w = childs_map[child_name];
|
||||||
|
w.clear();
|
||||||
|
w = wrapper;
|
||||||
|
return &w;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virtual Wrapper * find_child(const std::wstring & child_name)
|
||||||
|
{
|
||||||
|
auto i = childs_map.find(child_name);
|
||||||
|
|
||||||
|
if( i != childs_map.end() )
|
||||||
|
{
|
||||||
|
return &i->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool has_object()
|
||||||
|
{
|
||||||
|
return model || model_container_wrapper || date || space_wrapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool has_model_object()
|
||||||
|
{
|
||||||
|
return model || model_container_wrapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
std::map<std::wstring, Wrapper> childs_map;
|
||||||
|
|
||||||
|
|
||||||
|
void copy(const Wrapper & wrapper)
|
||||||
|
{
|
||||||
|
model = wrapper.model;
|
||||||
|
model_container_wrapper = wrapper.model_container_wrapper;
|
||||||
|
date = wrapper.date;
|
||||||
|
space_wrapper = wrapper.space_wrapper;
|
||||||
|
|
||||||
|
if( model_container_wrapper )
|
||||||
|
{
|
||||||
|
model_container_wrapper->increment_reference_counter();
|
||||||
|
}
|
||||||
|
|
||||||
|
if( space_wrapper )
|
||||||
|
{
|
||||||
|
space_wrapper->increment_reference_counter();
|
||||||
|
}
|
||||||
|
|
||||||
|
// childs_map don't need to be copied
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,168 @@
|
||||||
|
/*
|
||||||
|
* This file is a part of morm
|
||||||
|
* and is distributed under the 2-Clause BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022-2024, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "xmlconnector.h"
|
||||||
|
#include "xmlexpression.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace morm
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
XMLConnector::XMLConnector()
|
||||||
|
{
|
||||||
|
put_doctype = true;
|
||||||
|
put_root_element = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void XMLConnector::set_putting_doctype(bool put_doctype)
|
||||||
|
{
|
||||||
|
this->put_doctype = put_doctype;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void XMLConnector::set_putting_root_element(bool put_root_element)
|
||||||
|
{
|
||||||
|
this->put_root_element = put_root_element;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool XMLConnector::get_putting_doctype()
|
||||||
|
{
|
||||||
|
return put_doctype;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool XMLConnector::get_putting_root_element()
|
||||||
|
{
|
||||||
|
return put_root_element;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void XMLConnector::set_root_element(const wchar_t * root_name)
|
||||||
|
{
|
||||||
|
root_element_name = root_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void XMLConnector::set_root_element(const std::wstring & root_name)
|
||||||
|
{
|
||||||
|
root_element_name = root_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::wstring & XMLConnector::get_root_element()
|
||||||
|
{
|
||||||
|
return root_element_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void XMLConnector::allocate_default_expression()
|
||||||
|
{
|
||||||
|
deallocate_expression();
|
||||||
|
flat_expression = new XMLExpression();
|
||||||
|
expression_allocated = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void XMLConnector::to_text(pt::Stream & stream, Model & model, Export exp)
|
||||||
|
{
|
||||||
|
allocate_default_expression_if_needed();
|
||||||
|
|
||||||
|
if( flat_expression )
|
||||||
|
{
|
||||||
|
flat_expression->clear();
|
||||||
|
flat_expression->set_work_mode(MORM_WORK_MODE_MODEL_FIELDS_VALUES_FIELDS);
|
||||||
|
flat_expression->allow_to_use_prefix(false);
|
||||||
|
|
||||||
|
put_doctype_definition(stream);
|
||||||
|
put_opening_root_element(stream);
|
||||||
|
flat_expression->generate_from_model(stream, model);
|
||||||
|
put_closing_root_element(stream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void XMLConnector::put_doctype_definition(pt::Stream & stream)
|
||||||
|
{
|
||||||
|
if( put_doctype )
|
||||||
|
{
|
||||||
|
stream << L"<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void XMLConnector::put_opening_root_element(pt::Stream & stream)
|
||||||
|
{
|
||||||
|
if( put_root_element )
|
||||||
|
{
|
||||||
|
stream << L"<";
|
||||||
|
put_root_element_name(stream);
|
||||||
|
stream << L">";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void XMLConnector::put_closing_root_element(pt::Stream & stream)
|
||||||
|
{
|
||||||
|
if( put_root_element )
|
||||||
|
{
|
||||||
|
stream << L"</";
|
||||||
|
put_root_element_name(stream);
|
||||||
|
stream << L">";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void XMLConnector::put_root_element_name(pt::Stream & stream)
|
||||||
|
{
|
||||||
|
if( root_element_name.empty() )
|
||||||
|
{
|
||||||
|
stream << L"xml";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( flat_expression )
|
||||||
|
{
|
||||||
|
flat_expression->esc(root_element_name, stream, FT::default_type, nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
/*
|
||||||
|
* This file is a part of morm
|
||||||
|
* and is distributed under the 2-Clause BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022-2024, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef headerfile_morm_src_xmlconnector
|
||||||
|
#define headerfile_morm_src_xmlconnector
|
||||||
|
|
||||||
|
#include "flatconnector.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace morm
|
||||||
|
{
|
||||||
|
|
||||||
|
class XMLConnector : public FlatConnector
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
XMLConnector();
|
||||||
|
|
||||||
|
virtual void set_putting_doctype(bool put_doctype);
|
||||||
|
virtual void set_putting_root_element(bool put_root_element);
|
||||||
|
virtual bool get_putting_doctype();
|
||||||
|
virtual bool get_putting_root_element();
|
||||||
|
|
||||||
|
virtual void set_root_element(const wchar_t * root_name);
|
||||||
|
virtual void set_root_element(const std::wstring & root_name);
|
||||||
|
virtual std::wstring & get_root_element();
|
||||||
|
|
||||||
|
void to_text(pt::Stream & stream, Model & model, Export exp) override;
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
bool put_doctype;
|
||||||
|
bool put_root_element;
|
||||||
|
std::wstring root_element_name;
|
||||||
|
|
||||||
|
void allocate_default_expression() override;
|
||||||
|
|
||||||
|
virtual void put_doctype_definition(pt::Stream & stream);
|
||||||
|
virtual void put_opening_root_element(pt::Stream & stream);
|
||||||
|
virtual void put_closing_root_element(pt::Stream & stream);
|
||||||
|
virtual void put_root_element_name(pt::Stream & stream);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,142 @@
|
||||||
|
/*
|
||||||
|
* This file is a part of morm
|
||||||
|
* and is distributed under the 2-Clause BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022-2024, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "xmlexpression.h"
|
||||||
|
#include "morm_types.h"
|
||||||
|
#include "convert/misc.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace morm
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
void XMLExpression::before_field_name()
|
||||||
|
{
|
||||||
|
(*out_stream) << "<";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void XMLExpression::after_field_name()
|
||||||
|
{
|
||||||
|
(*out_stream) << ">";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void XMLExpression::before_field_value(const pt::Space &, const FT & field_type, ModelEnv * model_env)
|
||||||
|
{
|
||||||
|
if( field_type.is_space() )
|
||||||
|
{
|
||||||
|
//before_field_value_string(field_type, model_env);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void XMLExpression::after_field_value(const pt::Space &, const FT & field_type, ModelEnv * model_env)
|
||||||
|
{
|
||||||
|
if( field_type.is_space() )
|
||||||
|
{
|
||||||
|
//after_field_value_string(field_type, model_env);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void XMLExpression::put_field_closing_name(const wchar_t * field_name, const FT & field_type, ModelEnv * model_env)
|
||||||
|
{
|
||||||
|
if( field_type.is_raw_field_name() )
|
||||||
|
{
|
||||||
|
(*out_stream) << '/';
|
||||||
|
(*out_stream) << field_name;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
before_field_name();
|
||||||
|
(*out_stream) << '/';
|
||||||
|
esc(field_name, *out_stream, FT::default_type, nullptr); /* do not use provided field_type here - it would use e.g. binary mode if it was set, similar don't use model_env */
|
||||||
|
after_field_name();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void XMLExpression::put_name_value_separator()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool XMLExpression::esc_char(char32_t val, pt::Stream & stream, const FT & field_type, ModelEnv * model_env)
|
||||||
|
{
|
||||||
|
return pt::try_esc_to_xml(val, stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void XMLExpression::esc(const pt::Space & space, pt::Stream & stream, const FT & field_type, ModelEnv * model_env)
|
||||||
|
{
|
||||||
|
bool pretty_print = field_type.is_pretty_print();
|
||||||
|
|
||||||
|
if( field_type.is_space() )
|
||||||
|
{
|
||||||
|
pt::WTextStream tmp_stream;
|
||||||
|
space.serialize_to_space_stream(tmp_stream, pretty_print);
|
||||||
|
BaseExpression::esc(tmp_stream, stream, field_type, model_env);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* IMPROVEME it would be better to serialize to xml
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
pt::WTextStream tmp_stream;
|
||||||
|
space.serialize_to_json_stream(tmp_stream, pretty_print);
|
||||||
|
BaseExpression::esc(tmp_stream, stream, field_type, model_env);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void XMLExpression::put_value_list_opening_index(size_t index, const FT & field_type)
|
||||||
|
{
|
||||||
|
(*out_stream) << L"<item index=\"" << index << L"\">";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void XMLExpression::put_value_list_closing_index(size_t index, const FT & field_type)
|
||||||
|
{
|
||||||
|
(*out_stream) << L"</item>";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void XMLExpression::field_value_list_separator()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,76 @@
|
||||||
|
/*
|
||||||
|
* This file is a part of morm
|
||||||
|
* and is distributed under the 2-Clause BSD licence.
|
||||||
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022-2024, Tomasz Sowa
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef headerfile_morm_src_xmlexpression
|
||||||
|
#define headerfile_morm_src_xmlexpression
|
||||||
|
|
||||||
|
#include "flatexpression.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace morm
|
||||||
|
{
|
||||||
|
|
||||||
|
class XMLExpression : public FlatExpression
|
||||||
|
{
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
void put_field_closing_name(const wchar_t * field_name, const FT & field_type, ModelEnv * model_env) override;
|
||||||
|
|
||||||
|
void before_field_name() override;
|
||||||
|
void after_field_name() override;
|
||||||
|
|
||||||
|
void put_name_value_separator() override;
|
||||||
|
|
||||||
|
using BaseExpression::esc;
|
||||||
|
bool esc_char(char32_t val, pt::Stream & stream, const FT & field_type, ModelEnv * model_env) override;
|
||||||
|
void esc(const pt::Space & space, pt::Stream & stream, const FT & field_type, ModelEnv * model_env) override;
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void before_field_value(const pt::Space &, const FT & field_type, ModelEnv * model_env) override;
|
||||||
|
void after_field_value(const pt::Space &, const FT & field_type, ModelEnv * model_env) override;
|
||||||
|
|
||||||
|
void put_value_list_opening_index(size_t index, const FT & field_type) override;
|
||||||
|
void put_value_list_closing_index(size_t index, const FT & field_type) override;
|
||||||
|
|
||||||
|
void field_value_list_separator() override;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue