Compare commits

..

11 Commits

62 changed files with 1748 additions and 6263 deletions

9
.gitignore vendored
View File

@ -6,12 +6,3 @@
log.txt
samples/log.txt
samples/mormsample
.clangd
.qtc_clangd/
morm.cflags
morm.config
morm.creator
morm.creator.user
morm.cxxflags
morm.files
morm.includes

24
LICENSE
View File

@ -1,24 +0,0 @@
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.

View File

@ -1,42 +0,0 @@
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:

View File

@ -1,57 +1,68 @@
sourcefiles:=$(shell find . -name "*.cpp")
objfiles:=$(patsubst %.cpp,%.o,$(sourcefiles))
include Makefile.o.dep
name=mormsample
ifndef CXX
CXX = g++
ifndef GLOBAL_WORKING_DIR
GLOBAL_WORKING_DIR := $(shell pwd)/../..
endif
ifndef CXXFLAGS
CXXFLAGS = -Wall -pedantic -O2 -std=c++20 -I../src -I../../pikotools/src -I/usr/local/include
endif
ifndef LDFLAGS
CXX = g++10
#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
endif
name = mormsample
export CXX
export CXXFLAGS
export LDFLAGS
export GLOBAL_WORKING_DIR
all: $(name)
current_path := $(shell pwd)
global_relative_working_dir := $(shell relative_path $(current_path) $(GLOBAL_WORKING_DIR))
$(name): morm pikotools $(objfiles)
$(CXX) -o $(name) $(CXXFLAGS) $(LDFLAGS) $(objfiles) ../src/morm.a ../../pikotools/src/pikotools.a $(LDFLAGS) -lpq -lpthread
# IMPROVE ME
# add dependency to pikotools
all: morm $(name)
morm: FORCE
@cd ../src ; $(MAKE) -e
$(name): morm pikotools $(o)
$(CXX) -o $(name) $(CXXFLAGS) $(LDFLAGS) $(o) $(GLOBAL_WORKING_DIR)/morm/src/morm.a $(GLOBAL_WORKING_DIR)/pikotools/src/pikotools.a $(LDFLAGS) -lpq -lpthread
pikotools: FORCE
@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
$(CXX) -c $(CXXFLAGS) -o $@ $<
clean:
rm -f $(objfiles)
rm -f $(name)
$(CXX) -c $(CXXFLAGS) $<
depend:
makedepend -Y. -I../src -I../../pikotools/src -f- $(sourcefiles) > Makefile.dep
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
FORCE:
clean:
@cd $(GLOBAL_WORKING_DIR)/morm/src ; $(MAKE) -e clean
rm -f *.o
rm -f $(name)
-include Makefile.dep
include Makefile.dep

View File

@ -1,29 +1,17 @@
# DO NOT DELETE
./main.o: ../../pikotools/src/mainoptions/mainoptionsparser.h
./main.o: ../../pikotools/src/space/space.h
./main.o: ../../pikotools/src/convert/inttostr.h
./main.o: ../../pikotools/src/utf8/utf8.h
./main.o: ../../pikotools/src/textstream/stream.h sample01.h basesample.h
./main.o: ../src/morm.h ../src/version.h ../src/morm_types.h ../src/model.h
./main.o: ../../pikotools/src/textstream/textstream.h
./main.o: ../../pikotools/src/textstream/stream.h
./main.o: ../../pikotools/src/date/date.h
./main.o: ../../pikotools/src/membuffer/membuffer.h
./main.o: ../../pikotools/src/textstream/types.h
./main.o: ../../pikotools/src/textstream/stream_private.h
./main.o: ../src/modelconnector.h ../src/clearer.h ../src/ft.h
./main.o: ../src/dbconnector.h ../../pikotools/src/log/log.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
main.o: sample01.h basesample.h ../../morm/src/morm.h
main.o: ../../morm/src/morm_types.h ../../morm/src/model.h
main.o: ../../morm/src/modelconnector.h ../../morm/src/clearer.h
main.o: ../../morm/src/dbconnector.h ../../morm/src/queryresult.h
main.o: ../../morm/src/ft.h ../../morm/src/flatconnector.h
main.o: ../../morm/src/dbexpression.h ../../morm/src/baseexpression.h
main.o: ../../morm/src/modelenv.h ../../morm/src/modeldata.h
main.o: ../../morm/src/cursorhelper.h ../../morm/src/finderhelper.h
main.o: ../../morm/src/fieldvaluehelper.h ../../morm/src/flatexpression.h
main.o: ../../morm/src/modelwrapper.h ../../morm/src/finder.h
main.o: ../../morm/src/cursor.h ../../morm/src/jsonexpression.h
main.o: ../../morm/src/postgresqlexpression.h ../../morm/src/jsonconnector.h
main.o: ../../morm/src/postgresqlconnector.h
main.o: ../../morm/src/postgresqlqueryresult.h person.h language.h
main.o: attachment.h type.h attachment2.h

1
samples/Makefile.o.dep Normal file
View File

@ -0,0 +1 @@
o = main.o

View File

@ -1,45 +1,36 @@
sourcefiles:=$(shell find . -name "*.cpp")
objfiles:=$(patsubst %.cpp,%.o,$(sourcefiles))
include Makefile.o.dep
libname=morm.a
ifndef CXX
CXX = g++
ifndef GLOBAL_WORKING_DIR
GLOBAL_WORKING_DIR := $(shell pwd)/../..
endif
ifndef CXXFLAGS
CXXFLAGS = -Wall -pedantic -O2 -std=c++20 -I../../pikotools/src -I/usr/local/include
endif
current_path := $(shell pwd)
global_relative_working_dir := $(shell relative_path $(current_path) $(GLOBAL_WORKING_DIR))
ifndef AR
AR = ar
endif
libname = morm.a
all: $(libname)
$(libname): $(o)
$(AR) rcs $(libname) $(o)
$(libname): $(objfiles)
$(AR) rcs $(libname) $(objfiles)
%.o: %.cpp
$(CXX) -c $(CXXFLAGS) -o $@ $<
clean:
rm -f $(objfiles)
rm -f $(libname)
$(CXX) -c $(CXXFLAGS) -I$(GLOBAL_WORKING_DIR)/pikotools $<
depend:
makedepend -Y. -I../../pikotools/src -f- $(sourcefiles) > Makefile.dep
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
-include Makefile.dep
clean:
rm -f *.o
rm -f $(libname)
include Makefile.dep

View File

@ -1,321 +1,54 @@
# DO NOT DELETE
./baseexpression.o: baseexpression.h ../../pikotools/src/textstream/stream.h
./baseexpression.o: ../../pikotools/src/date/date.h
./baseexpression.o: ../../pikotools/src/convert/inttostr.h morm_types.h
./baseexpression.o: modelenv.h modeldata.h cursorhelper.h queryresult.h
./baseexpression.o: ../../pikotools/src/log/log.h
./baseexpression.o: ../../pikotools/src/textstream/textstream.h
./baseexpression.o: ../../pikotools/src/textstream/stream.h
./baseexpression.o: ../../pikotools/src/space/space.h
./baseexpression.o: ../../pikotools/src/utf8/utf8.h
./baseexpression.o: ../../pikotools/src/membuffer/membuffer.h
./baseexpression.o: ../../pikotools/src/textstream/types.h
./baseexpression.o: ../../pikotools/src/textstream/stream_private.h
./baseexpression.o: ../../pikotools/src/log/filelog.h finderhelper.h
./baseexpression.o: fieldvaluehelper.h wrapper.h spacewrapper.h
./baseexpression.o: baseobjectwrapper.h modelcontainerwrapper.h select.h ft.h
./baseexpression.o: model.h modelconnector.h clearer.h dbconnector.h
./baseexpression.o: flatconnector.h export.h dbexpression.h flatexpression.h
./clearer.o: clearer.h ../../pikotools/src/date/date.h
./clearer.o: ../../pikotools/src/convert/inttostr.h
./clearer.o: ../../pikotools/src/space/space.h
./clearer.o: ../../pikotools/src/utf8/utf8.h
./clearer.o: ../../pikotools/src/textstream/stream.h ft.h model.h
./clearer.o: ../../pikotools/src/textstream/textstream.h
./clearer.o: ../../pikotools/src/textstream/stream.h
./clearer.o: ../../pikotools/src/membuffer/membuffer.h
./clearer.o: ../../pikotools/src/textstream/types.h
./clearer.o: ../../pikotools/src/textstream/stream_private.h modelconnector.h
./clearer.o: dbconnector.h ../../pikotools/src/log/log.h
./clearer.o: ../../pikotools/src/log/filelog.h queryresult.h flatconnector.h
./clearer.o: export.h dbexpression.h baseexpression.h morm_types.h modelenv.h
./clearer.o: modeldata.h cursorhelper.h finderhelper.h fieldvaluehelper.h
./clearer.o: wrapper.h spacewrapper.h baseobjectwrapper.h
./clearer.o: modelcontainerwrapper.h select.h flatexpression.h
./dbconnector.o: ../../pikotools/src/space/spaceparser.h
./dbconnector.o: ../../pikotools/src/space/space.h
./dbconnector.o: ../../pikotools/src/convert/inttostr.h
./dbconnector.o: ../../pikotools/src/utf8/utf8.h
./dbconnector.o: ../../pikotools/src/textstream/stream.h
./dbconnector.o: ../../pikotools/src/convert/baseparser.h
./dbconnector.o: ../../pikotools/src/textstream/textstream.h
./dbconnector.o: ../../pikotools/src/textstream/stream.h
./dbconnector.o: ../../pikotools/src/space/space.h
./dbconnector.o: ../../pikotools/src/date/date.h
./dbconnector.o: ../../pikotools/src/membuffer/membuffer.h
./dbconnector.o: ../../pikotools/src/textstream/types.h
./dbconnector.o: ../../pikotools/src/textstream/stream_private.h
./dbconnector.o: dbconnector.h ../../pikotools/src/log/log.h
./dbconnector.o: ../../pikotools/src/log/filelog.h queryresult.h ft.h
./dbconnector.o: dbexpression.h baseexpression.h morm_types.h modelenv.h
./dbconnector.o: modeldata.h cursorhelper.h finderhelper.h fieldvaluehelper.h
./dbconnector.o: wrapper.h spacewrapper.h baseobjectwrapper.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
baseexpression.o: baseexpression.h morm_types.h modelenv.h modeldata.h
baseexpression.o: cursorhelper.h queryresult.h finderhelper.h
baseexpression.o: fieldvaluehelper.h ft.h model.h modelconnector.h clearer.h
baseexpression.o: dbconnector.h flatconnector.h dbexpression.h
baseexpression.o: flatexpression.h modelcontainerwrapper.h
baseexpression.o: baseobjectwrapper.h spacewrapper.h
clearer.o: clearer.h model.h modelconnector.h dbconnector.h queryresult.h
clearer.o: ft.h flatconnector.h dbexpression.h baseexpression.h morm_types.h
clearer.o: modelenv.h modeldata.h cursorhelper.h finderhelper.h
clearer.o: fieldvaluehelper.h flatexpression.h modelcontainerwrapper.h
clearer.o: baseobjectwrapper.h spacewrapper.h
dbconnector.o: dbconnector.h queryresult.h ft.h dbexpression.h
dbconnector.o: baseexpression.h morm_types.h modelenv.h modeldata.h
dbconnector.o: cursorhelper.h finderhelper.h fieldvaluehelper.h model.h
dbconnector.o: modelconnector.h clearer.h flatconnector.h flatexpression.h
dbconnector.o: modelcontainerwrapper.h baseobjectwrapper.h spacewrapper.h
dbexpression.o: dbexpression.h baseexpression.h morm_types.h modelenv.h
dbexpression.o: modeldata.h cursorhelper.h queryresult.h finderhelper.h
dbexpression.o: fieldvaluehelper.h ft.h
flatconnector.o: flatconnector.h flatexpression.h baseexpression.h
flatconnector.o: morm_types.h modelenv.h modeldata.h cursorhelper.h
flatconnector.o: queryresult.h finderhelper.h fieldvaluehelper.h ft.h model.h
flatconnector.o: modelconnector.h clearer.h dbconnector.h dbexpression.h
flatconnector.o: modelcontainerwrapper.h baseobjectwrapper.h spacewrapper.h
flatexpression.o: flatexpression.h baseexpression.h morm_types.h modelenv.h
flatexpression.o: modeldata.h cursorhelper.h queryresult.h finderhelper.h
flatexpression.o: fieldvaluehelper.h ft.h
jsonconnector.o: jsonconnector.h flatconnector.h jsonexpression.h
jsonconnector.o: flatexpression.h baseexpression.h morm_types.h modelenv.h
jsonconnector.o: modeldata.h cursorhelper.h queryresult.h finderhelper.h
jsonconnector.o: fieldvaluehelper.h ft.h
jsonexpression.o: jsonexpression.h flatexpression.h baseexpression.h
jsonexpression.o: morm_types.h modelenv.h modeldata.h cursorhelper.h
jsonexpression.o: queryresult.h finderhelper.h fieldvaluehelper.h ft.h
model.o: model.h modelconnector.h clearer.h dbconnector.h queryresult.h ft.h
model.o: flatconnector.h dbexpression.h baseexpression.h morm_types.h
model.o: modelenv.h modeldata.h cursorhelper.h finderhelper.h
model.o: fieldvaluehelper.h flatexpression.h modelcontainerwrapper.h
model.o: baseobjectwrapper.h spacewrapper.h
modelconnector.o: modelconnector.h clearer.h dbconnector.h queryresult.h ft.h
modelconnector.o: flatconnector.h
postgresqlconnector.o: postgresqlconnector.h dbconnector.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
postgresqlexpression.o: postgresqlexpression.h dbexpression.h
postgresqlexpression.o: baseexpression.h morm_types.h modelenv.h modeldata.h
postgresqlexpression.o: cursorhelper.h queryresult.h finderhelper.h
postgresqlexpression.o: fieldvaluehelper.h ft.h
postgresqlqueryresult.o: postgresqlqueryresult.h queryresult.h
queryresult.o: queryresult.h

1
src/Makefile.o.dep Normal file
View File

@ -0,0 +1 @@
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

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2018-2024, Tomasz Sowa
* Copyright (c) 2018-2021, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -32,17 +32,21 @@
*
*/
#ifndef headerfile_morm_src_baseexpression
#define headerfile_morm_src_baseexpression
#ifndef headerfile_morm_baseexpression
#define headerfile_morm_baseexpression
#include <list>
#include <set>
#include <type_traits>
#include "textstream/stream.h"
#include "textstream/textstream.h"
#include "date/date.h"
#include "morm_types.h"
#include "modelenv.h"
#include "ft.h"
#include "convert/text.h"
#ifdef MORM_HAS_EZC_LIBRARY
#include "env.h"
#endif
namespace morm
@ -58,22 +62,17 @@ public:
BaseExpression();
virtual ~BaseExpression();
BaseExpression(const BaseExpression &) = delete;
BaseExpression(BaseExpression &&) = delete;
virtual void set_work_mode(int work_mode);
virtual int get_work_mode();
virtual void set_output_type(int output_type);
virtual int get_output_type();
virtual pt::Stream * get_text_stream();
virtual void set_text_stream(pt::Stream * out_stream);
virtual pt::TextStream * get_text_stream();
virtual void set_text_stream(pt::TextStream * out_stream);
virtual void clear();
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 void generate_from_model(pt::TextStream & stream, Model & model);
virtual pt::TextStream * get_current_stream();
// rename me
virtual void allow_to_use_prefix(bool use_prefix);
@ -118,12 +117,23 @@ public:
else
if( work_mode == MORM_WORK_MODE_MODEL_FIELDS_VALUES )
{
put_field_name_and_value(field_name, field_value, getter_method, field_type, model_env);
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();
put_field_value_or_null(field_value, getter_method, field_type, model_env);
}
model_env->field_index += 1;
}
else
if( work_mode == MORM_WORK_MODE_MODEL_FIELDS_VALUES_FIELDS )
{
put_field_name_and_value_and_closing_name(field_name, field_value, getter_method, field_type, 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);
}
}
field_after();
@ -132,21 +142,45 @@ public:
template<typename FieldValue>
void field_in(pt::Stream & stream, const wchar_t * field_name, const std::set<FieldValue> & container, ModelEnv * model_env)
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);
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);
}
template<typename FieldValue>
void field_in(pt::Stream & stream, const wchar_t * field_name, const std::list<FieldValue> & container, ModelEnv * model_env)
void field_in(pt::TextStream & 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);
}
template<typename FieldValue>
void field_in(pt::Stream & stream, const wchar_t * field_name, const std::vector<FieldValue> & container, ModelEnv * model_env)
void field_in(pt::TextStream & 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);
}
@ -156,7 +190,7 @@ public:
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)
{
if( out_stream && can_field_be_generated(field_type) && can_field_list_be_generated(field_type) )
if( out_stream && can_field_be_generated(field_type) )
{
field_before();
@ -167,12 +201,9 @@ public:
// else
if( work_mode == MORM_WORK_MODE_MODEL_FIELDS_VALUES )
{
put_field_name_and_value_list(field_name, field_value, model_container_type, field_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);
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, model_connector, model_env, foo);
}
field_after();
@ -182,40 +213,33 @@ public:
template<typename ModelClass>
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) && can_field_model_be_generated(field_model.get_has_primary_key_set(), field_type) )
if( out_stream && can_field_be_generated(field_type) )
{
field_before();
if( work_mode == MORM_WORK_MODE_MODEL_FIELDS )
{
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
if( work_mode == MORM_WORK_MODE_MODEL_VALUES )
{
generate_from_model(field_model, field_type);
generate_from_model(field_model); // is it ok as a value?
}
else
if( work_mode == MORM_WORK_MODE_MODEL_FIELDS_VALUES )
{
put_field_name_and_value_model(field_name, field_model, field_type, model_env);
}
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);
put_field_name_and_table_if_needed(field_name, field_type, model_env);
put_name_value_separator();
generate_from_model(field_model);
}
field_after();
}
}
template<typename FieldValue>
void field_to_stream(pt::Stream & stream, const wchar_t * field_name, const FieldValue & field_value, const FT & field_type, ModelEnv * model_env)
void field_to_stream(pt::TextStream & stream, const wchar_t * field_name, const FieldValue & field_value, const FT & field_type, ModelEnv * model_env)
{
this->out_stream = &stream;
field(field_name, field_value, field_type, model_env);
@ -223,15 +247,6 @@ 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 pt::WTextStream & schema_name, const pt::WTextStream & table_name);
virtual void put_table(const wchar_t * table_name);
@ -242,206 +257,97 @@ 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_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_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 put_string(const char * str, const FT & field_type, bool add_quotes = false, ModelEnv * model_env = nullptr);
virtual void put_string(const wchar_t * str, const FT & field_type, bool add_quotes = false, ModelEnv * model_env = nullptr);
virtual void put_string(const std::string & str, const FT & field_type, bool add_quotes = false, ModelEnv * model_env = nullptr);
virtual void put_string(const std::wstring & str, const FT & field_type, bool add_quotes = false, ModelEnv * model_env = nullptr);
virtual void put_stream(const pt::Stream & str, const FT & field_type, bool add_quotes = false, ModelEnv * model_env = nullptr);
virtual void schema_table_to_stream(pt::TextStream & stream, const wchar_t * schema_name, const wchar_t * table_name);
virtual void schema_table_to_stream(pt::TextStream & stream, const pt::WTextStream & schema_name, const pt::WTextStream & table_name);
virtual void table_to_stream(pt::TextStream & stream, const wchar_t * table_name);
virtual void table_to_stream(pt::TextStream & stream, const pt::WTextStream & table_name);
virtual void table_with_index_to_stream(pt::TextStream & stream, const wchar_t * table_name, int index);
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
* esc for: signed char, wchar_t, char16_t, char32_t
*
*/
virtual bool esc_char(char val, pt::Stream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
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(char val, pt::TextStream & stream, const FT & field_type = FT::default_type);
virtual void esc(unsigned char 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(wchar_t 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::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 wchar_t * 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::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 char * 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::Stream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
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::Stream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
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::Stream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
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::Stream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
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::Stream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
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::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(short val, pt::TextStream & stream, const FT & field_type = FT::default_type);
virtual void esc(unsigned short val, pt::TextStream & stream, const FT & field_type = FT::default_type);
virtual void esc(int val, pt::TextStream & stream, const FT & field_type = FT::default_type);
virtual void esc(unsigned int val, pt::TextStream & stream, const FT & field_type = FT::default_type);
virtual void esc(long val, pt::TextStream & stream, const FT & field_type = FT::default_type);
virtual void esc(unsigned long val, pt::TextStream & stream, const FT & field_type = FT::default_type);
virtual void esc(long long val, pt::TextStream & stream, const FT & field_type = FT::default_type);
virtual void esc(unsigned long long val, pt::TextStream & stream, const FT & field_type = FT::default_type);
virtual void esc(float val, pt::TextStream & stream, const FT & field_type = FT::default_type);
virtual void esc(double val, pt::TextStream & stream, const FT & field_type = FT::default_type);
virtual void esc(long double val, pt::TextStream & stream, const FT & field_type = FT::default_type);
//virtual void esc(void* val, pt::TextStream & stream);
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::Space & space, pt::Stream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
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::Date & date, pt::TextStream & stream, const FT & field_type = FT::default_type);
virtual void esc(const pt::TextStream & val,pt::TextStream & stream, const FT & field_type = FT::default_type);
virtual void esc(const pt::WTextStream & val,pt::TextStream & stream, const FT & field_type = FT::default_type);
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() )
{
// 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:
int work_mode; /* what to do: generating fields list, values list or fields-values list */
int output_type;
bool is_first_field;
pt::Stream * out_stream;
bool use_prefix;
pt::TextStream scratch_buffer_local;
pt::TextStream * scratch_buffer;
virtual void generate_from_model(Model & model, const FT & field_type);
pt::TextStream * out_stream;
bool use_prefix;
virtual void generate_from_model(Model & model);
virtual void before_generate_from_model();
virtual void after_generate_from_model();
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_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(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 dump_additional_info(Model & model);
virtual void add_additional_columns(Model & model);
template<typename FieldValue>
void put_field_value(const FieldValue & field_value, const FT & field_type, ModelEnv * model_env = nullptr)
void put_field_value(const FieldValue & field_value, const FT & field_type)
{
if( out_stream )
{
before_field_value(field_value, field_type, model_env);
esc(field_value, *out_stream, field_type, model_env);
after_field_value(field_value, field_type, model_env);
before_field_value(field_value, field_type);
esc(field_value, *out_stream, field_type);
after_field_value(field_value, field_type);
}
}
void put_field_value(void (Model::*getter_method)(pt::Stream &), const FT & field_type, ModelEnv * model_env = nullptr)
void put_field_value(void (Model::*getter_method)(pt::Stream &), const FT & field_type, ModelEnv * model_env)
{
if( out_stream && model_env && model_env->model && getter_method )
{
before_field_value_string(field_type, model_env);
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);
before_field_value_string(field_type);
(model_env->model->*getter_method)(*out_stream);
after_field_value_string(field_type);
}
}
@ -478,50 +384,45 @@ protected:
template<typename ModelContainer, typename ModelContainerType, typename IsContainerByValueRenameMe>
void put_field_value_list(ModelContainer & field_value, ModelContainerType * model_container_type, const FT & field_type,
ModelConnector * model_connector, ModelEnv * model_env, IsContainerByValueRenameMe * foo)
void put_field_value_list(ModelContainer & field_value, ModelContainerType * model_container_type, ModelConnector * model_connector,
ModelEnv * model_env, IsContainerByValueRenameMe * foo)
{
if constexpr (std::is_base_of<Model, ModelContainerType>())
{
if constexpr (std::is_base_of<Model, IsContainerByValueRenameMe>())
{
put_field_value_list_model_by_value(field_value, model_container_type, field_type, model_connector, model_env);
put_field_value_list_model_by_value(field_value, model_container_type, model_connector, model_env);
}
else
{
put_field_value_list_model_by_pointer(field_value, model_container_type, field_type, model_connector, model_env);
put_field_value_list_model_by_pointer(field_value, model_container_type, model_connector, model_env);
}
}
else
{
put_field_value_list_non_model(field_value, model_connector, field_type);
put_field_value_list_non_model(field_value, model_connector);
}
}
template<typename ModelContainer, typename ModelContainerType>
void put_field_value_list_model_by_value(ModelContainer & field_value, ModelContainerType * model_container_type, const FT & field_type,
ModelConnector * model_connector, ModelEnv * model_env)
void put_field_value_list_model_by_value(ModelContainer & field_value, ModelContainerType * model_container_type, ModelConnector * model_connector,
ModelEnv * model_env)
{
if( model_connector && model_env && out_stream )
{
bool is_first = true;
before_field_value_list();
size_t index = 0;
for(auto & child_model_item : field_value)
{
if( can_field_model_be_generated(child_model_item.get_has_primary_key_set(), field_type) )
{
if( index > 0 )
if( !is_first )
{
field_value_list_separator();
}
put_value_list_opening_index(index, field_type);
put_field_value_list_model(child_model_item, model_connector, model_env);
put_value_list_closing_index(index, field_type);
index += 1;
}
is_first = false;
}
after_field_value_list();
@ -530,28 +431,23 @@ protected:
template<typename ModelContainer, typename ModelContainerType>
void put_field_value_list_model_by_pointer(ModelContainer & field_value, ModelContainerType * model_container_type, const FT & field_type,
ModelConnector * model_connector, ModelEnv * model_env)
void put_field_value_list_model_by_pointer(ModelContainer & field_value, ModelContainerType * model_container_type, ModelConnector * model_connector,
ModelEnv * model_env)
{
if( model_connector && model_env && out_stream )
{
bool is_first = true;
before_field_value_list();
size_t index = 0;
for(auto * child_model_item : field_value)
{
if( can_field_model_be_generated(child_model_item->get_has_primary_key_set(), field_type) )
{
if( index > 0 )
if( !is_first )
{
field_value_list_separator();
}
put_value_list_opening_index(index, field_type);
put_field_value_list_model(*child_model_item, model_connector, model_env);
put_value_list_closing_index(index, field_type);
index += 1;
}
is_first = false;
}
after_field_value_list();
@ -568,32 +464,29 @@ protected:
child_model.model_env->model = &child_model;
child_model.set_connector(model_connector);
FT field_type = FT::default_type;
generate_from_model(child_model, field_type);
generate_from_model(child_model);
child_model.model_env = nullptr;
}
template<typename ModelContainer>
void put_field_value_list_non_model(ModelContainer & field_value, ModelConnector * model_connector, const FT & field_type)
void put_field_value_list_non_model(ModelContainer & field_value, ModelConnector * model_connector)
{
if( model_connector && out_stream )
{
bool is_first = true;
before_field_value_list();
size_t index = 0;
for(const auto & m : field_value)
{
if( index > 0 )
if( !is_first )
{
field_value_list_separator();
}
put_value_list_opening_index(index, field_type);
put_field_value(m, FT::default_type);
put_value_list_closing_index(index, field_type);
index += 1;
is_first = false;
}
after_field_value_list();
@ -604,7 +497,7 @@ protected:
// used in 'in()' statements, may should be renamed?
template<typename FieldValue, typename Container>
void field_in_generic(pt::Stream & stream, const wchar_t * field_name, const Container & container, ModelEnv * model_env)
void field_in_generic(pt::TextStream & stream, const wchar_t * field_name, const Container & container, ModelEnv * model_env)
{
// IMPROVE ME
// what about if container is empty?
@ -625,7 +518,7 @@ protected:
field_value_list_separator();
}
put_field_value(v, FT::default_type, model_env);
put_field_value(v, FT::default_type);
is_first = false;
}
@ -637,7 +530,6 @@ protected:
virtual void schema_table_separator();
virtual void table_field_separator();
virtual void alias_names_separator();
virtual void before_schema_name();
virtual void after_schema_name();
@ -648,61 +540,40 @@ protected:
virtual void before_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, ModelEnv * model_env);
virtual void after_field_value(const std::wstring &, const FT & field_type, ModelEnv * model_env);
virtual void before_field_value(const std::wstring &, const FT & field_type);
virtual void after_field_value(const std::wstring &, 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, ModelEnv * model_env);
virtual void before_field_value(const std::string &, const FT & field_type);
virtual void after_field_value(const std::string &, 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, ModelEnv * model_env);
virtual void before_field_value(const wchar_t *, const FT & field_type);
virtual void after_field_value(const wchar_t *, 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, ModelEnv * model_env);
virtual void before_field_value(const char *, const FT & field_type);
virtual void after_field_value(const char *, 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, ModelEnv * model_env);
virtual void before_field_value(wchar_t, const FT & field_type);
virtual void after_field_value(wchar_t, 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, ModelEnv * model_env);
virtual void before_field_value(char, const FT & field_type);
virtual void after_field_value(char, 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, ModelEnv * model_env);
virtual void before_field_value(const pt::Date &, const FT & field_type);
virtual void after_field_value(const pt::Date &, 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, ModelEnv * model_env);
virtual void before_field_value(const pt::Space &, const FT & field_type);
virtual void after_field_value(const pt::Space &, const FT & field_type);
template<typename FieldValue>
void before_field_value(const FieldValue & field_value, const FT & field_type, ModelEnv * model_env)
void before_field_value(const FieldValue &, const FT & field_type)
{
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>
void after_field_value(const FieldValue &, const FT & field_type, ModelEnv * model_env)
void after_field_value(const FieldValue &, const FT & field_type)
{
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();
@ -712,220 +583,55 @@ protected:
* put_type for: signed char, wchar_t, char16_t, char32_t
*
*/
// virtual void put_type(char val, pt::Stream & stream);
// virtual void put_type(unsigned char val, pt::Stream & stream);
// virtual void put_type(char val, pt::TextStream & stream);
// virtual void put_type(unsigned char val, pt::TextStream & stream);
//
// virtual void put_type(const std::wstring & val, pt::Stream & stream);
// virtual void put_type(const wchar_t * val, pt::Stream & stream);
// virtual void put_type(const std::wstring & val, pt::TextStream & stream);
// virtual void put_type(const wchar_t * val, pt::TextStream & stream);
//
// virtual void put_type(const std::string & val, pt::Stream & stream);
// virtual void put_type(const char * val, pt::Stream & stream);
// virtual void put_type(const std::string & val, pt::TextStream & stream);
// virtual void put_type(const char * val, pt::TextStream & stream);
//
// virtual void put_type(bool val, pt::Stream & stream);
// virtual void put_type(short val, pt::Stream & stream);
// virtual void put_type(unsigned short val, pt::Stream & stream);
// virtual void put_type(int val, pt::Stream & stream);
// virtual void put_type(unsigned int val, pt::Stream & stream);
// virtual void put_type(long val, pt::Stream & stream);
// virtual void put_type(unsigned long val, pt::Stream & stream);
// virtual void put_type(long long val, pt::Stream & stream);
// virtual void put_type(unsigned long long val, pt::Stream & stream);
// virtual void put_type(float val, pt::Stream & stream);
// virtual void put_type(double val, pt::Stream & stream);
// virtual void put_type(long double val, pt::Stream & stream);
//virtual void put_type(void* val, pt::Stream & stream);
// virtual void put_type(bool val, pt::TextStream & stream);
// virtual void put_type(short val, pt::TextStream & stream);
// virtual void put_type(unsigned short val, pt::TextStream & stream);
// virtual void put_type(int val, pt::TextStream & stream);
// virtual void put_type(unsigned int val, pt::TextStream & stream);
// virtual void put_type(long val, pt::TextStream & stream);
// virtual void put_type(unsigned long val, pt::TextStream & stream);
// virtual void put_type(long long val, pt::TextStream & stream);
// virtual void put_type(unsigned long long val, pt::TextStream & stream);
// virtual void put_type(float val, pt::TextStream & stream);
// virtual void put_type(double val, pt::TextStream & stream);
// virtual void put_type(long double val, pt::TextStream & stream);
//virtual void put_type(void* val, pt::TextStream & stream);
// virtual void put_type(const pt::Date & date, pt::Stream & stream);
// virtual void put_type(const Model & model, pt::Stream & stream);
// virtual void put_type(const pt::Date & date, pt::TextStream & stream);
// virtual void put_type(const Model & model, pt::TextStream & stream);
//
// template<typename ListType>
// void put_type(const std::list<ListType> & model, pt::Stream & stream)
// void put_type(const std::list<ListType> & model, pt::TextStream & stream)
// {
// stream << "table"; // may just use std::list?
// }
//
// template<typename ListType>
// void put_type(const std::vector<ListType> & model, pt::Stream & stream)
// void put_type(const std::vector<ListType> & model, pt::TextStream & stream)
// {
// stream << "table"; // may just just std::vector?
// }
virtual void before_field_value_string(const FT & field_type, ModelEnv * model_env);
virtual void after_field_value_string(const FT & field_type, ModelEnv * model_env);
virtual void before_field_value_string(const FT & field_type);
virtual void after_field_value_string(const FT & field_type);
char char_to_hex_part(char c);
void char_to_hex(char c, pt::Stream & stream);
void char_to_hex(char32_t c, pt::Stream & stream);
void char_to_hex(char c, pt::TextStream & stream);
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);
void esc(const wchar_t * val, bool has_known_length, size_t len, pt::TextStream & stream, const FT & field_type = FT::default_type);
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);
}
};
}

View File

@ -32,8 +32,8 @@
*
*/
#ifndef headerfile_morm_src_baseobjectwrapper
#define headerfile_morm_src_baseobjectwrapper
#ifndef headerfile_morm_baseobjectwrapper
#define headerfile_morm_baseobjectwrapper

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2018-2022, Tomasz Sowa
* Copyright (c) 2018-2021, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -50,119 +50,105 @@ Clearer::~Clearer()
}
void Clearer::clear_value(char & field_value, const FT & field_type)
void Clearer::clear_value(char & field_value)
{
field_value = 0;
}
void Clearer::clear_value(unsigned char & field_value, const FT & field_type)
void Clearer::clear_value(unsigned char & field_value)
{
field_value = 0;
}
void Clearer::clear_value(wchar_t & field_value, const FT & field_type)
void Clearer::clear_value(wchar_t & field_value)
{
field_value = 0;
}
void Clearer::clear_value(std::wstring & field_value, const FT & field_type)
void Clearer::clear_value(std::wstring & field_value)
{
if( field_type.is_numeric() )
{
field_value = L"0";
}
else
{
field_value.clear();
}
}
void Clearer::clear_value(std::string & field_value, const FT & field_type)
void Clearer::clear_value(std::string & field_value)
{
if( field_type.is_numeric() )
{
field_value = "0";
}
else
{
field_value.clear();
}
}
void Clearer::clear_value(bool & field_value, const FT & field_type)
void Clearer::clear_value(bool & field_value)
{
field_value = false;
}
void Clearer::clear_value(short & field_value, const FT & field_type)
void Clearer::clear_value(short & field_value)
{
field_value = 0;
}
void Clearer::clear_value(unsigned short & field_value, const FT & field_type)
void Clearer::clear_value(unsigned short & field_value)
{
field_value = 0;
}
void Clearer::clear_value(int & field_value, const FT & field_type)
void Clearer::clear_value(int & field_value)
{
field_value = 0;
}
void Clearer::clear_value(unsigned int & field_value, const FT & field_type)
void Clearer::clear_value(unsigned int & field_value)
{
field_value = 0;
}
void Clearer::clear_value(long & field_value, const FT & field_type)
void Clearer::clear_value(long & field_value)
{
field_value = 0;
}
void Clearer::clear_value(unsigned long & field_value, const FT & field_type)
void Clearer::clear_value(unsigned long & field_value)
{
field_value = 0;
}
void Clearer::clear_value(long long & field_value, const FT & field_type)
void Clearer::clear_value(long long & field_value)
{
field_value = 0;
}
void Clearer::clear_value(unsigned long long & field_value, const FT & field_type)
void Clearer::clear_value(unsigned long long & field_value)
{
field_value = 0;
}
void Clearer::clear_value(float & field_value, const FT & field_type)
void Clearer::clear_value(float & field_value)
{
field_value = 0.0f;
}
void Clearer::clear_value(double & field_value, const FT & field_type)
void Clearer::clear_value(double & field_value)
{
field_value = 0.0;
}
void Clearer::clear_value(long double & field_value, const FT & field_type)
void Clearer::clear_value(long double & field_value)
{
field_value = 0.0;
}
void Clearer::clear_value(pt::Date & field_value, const FT & field_type)
void Clearer::clear_value(pt::Date & field_value)
{
field_value.Clear();
}
void Clearer::clear_value(pt::Space & field_value, const FT & field_type)
void Clearer::clear_value(pt::Space & field_value)
{
field_value.clear();
}
void Clearer::clear_model(Model & field_value, const FT & field_type)
void Clearer::clear_model(Model & field_value)
{
field_value.clear();
}

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2018-2022, Tomasz Sowa
* Copyright (c) 2018-2021, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -32,13 +32,12 @@
*
*/
#ifndef headerfile_morm_src_clearer
#define headerfile_morm_src_clearer
#ifndef headerfile_morm_clearer
#define headerfile_morm_clearer
#include <string>
#include "date/date.h"
#include "space/space.h"
#include "ft.h"
namespace morm
@ -53,30 +52,30 @@ public:
Clearer();
virtual ~Clearer();
virtual void clear_value(char & field_value, const FT & field_type);
virtual void clear_value(unsigned char & field_value, const FT & field_type);
virtual void clear_value(wchar_t & field_value, const FT & field_type);
virtual void clear_value(std::wstring & field_value, const FT & field_type);
virtual void clear_value(std::string & field_value, const FT & field_type);
virtual void clear_value(bool & field_value, const FT & field_type);
virtual void clear_value(short & field_value, const FT & field_type);
virtual void clear_value(unsigned short & field_value, const FT & field_type);
virtual void clear_value(int & field_value, const FT & field_type);
virtual void clear_value(unsigned int & field_value, const FT & field_type);
virtual void clear_value(long & field_value, const FT & field_type);
virtual void clear_value(unsigned long & field_value, const FT & field_type);
virtual void clear_value(long long & field_value, const FT & field_type);
virtual void clear_value(unsigned long long & field_value, const FT & field_type);
virtual void clear_value(float & field_value, const FT & field_type);
virtual void clear_value(double & field_value, const FT & field_type);
virtual void clear_value(long double & field_value, const FT & field_type);
virtual void clear_value(pt::Date & field_value, const FT & field_type);
virtual void clear_value(pt::Space & field_value, const FT & field_type);
virtual void clear_value(char & field_value);
virtual void clear_value(unsigned char & field_value);
virtual void clear_value(wchar_t & field_value);
virtual void clear_value(std::wstring & field_value);
virtual void clear_value(std::string & field_value);
virtual void clear_value(bool & field_value);
virtual void clear_value(short & field_value);
virtual void clear_value(unsigned short & field_value);
virtual void clear_value(int & field_value);
virtual void clear_value(unsigned int & field_value);
virtual void clear_value(long & field_value);
virtual void clear_value(unsigned long & field_value);
virtual void clear_value(long long & field_value);
virtual void clear_value(unsigned long long & field_value);
virtual void clear_value(float & field_value);
virtual void clear_value(double & field_value);
virtual void clear_value(long double & field_value);
virtual void clear_value(pt::Date & field_value);
virtual void clear_value(pt::Space & field_value);
virtual void clear_model(Model & field_value, const FT & field_type);
virtual void clear_model(Model & field_value);
template<typename ModelContainer, typename ModelContainerType, typename IsContainerByValueRenameMe>
void clear_container(ModelContainer & container, ModelContainerType * model_container_type, IsContainerByValueRenameMe * foo, const FT & field_type)
void clear_container(ModelContainer & container, ModelContainerType * model_container_type, IsContainerByValueRenameMe * foo)
{
if constexpr (std::is_base_of<Model, ModelContainerType>())
{

View File

@ -1,81 +0,0 @@
/*
* 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);
}
}
}

View File

@ -1,63 +0,0 @@
/*
* 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

View File

@ -1,97 +0,0 @@
/*
* 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);
}
}

View File

@ -1,68 +0,0 @@
/*
* 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

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2018-2024, Tomasz Sowa
* Copyright (c) 2018-2021, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -32,15 +32,11 @@
*
*/
#ifndef headerfile_morm_src_cursor
#define headerfile_morm_src_cursor
#ifndef headerfile_morm_cursor
#define headerfile_morm_cursor
#include "queryresult.h"
#include "modelconnector.h"
#include "modeldata.h"
#include "select.h"
#include "modelenv.h"
#include "dbexpression.h"
namespace morm
@ -67,11 +63,7 @@ public:
has_autogenerated_select = c.has_autogenerated_select;
use_table_prefix_for_fetching = c.use_table_prefix_for_fetching;
query_result = c.query_result;
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;
select_status = c.select_status;
if( query_result )
{
@ -113,11 +105,7 @@ public:
cursor_helper.clear();
finder_helper.clear();
query_result = nullptr;
last_query_status = false;
select_flags = Select::default_type;
rows_counter = 0;
cursor_name.clear();
scroll_cursor = false;
select_status = false;
}
@ -139,9 +127,9 @@ public:
}
virtual void set_last_query_status(bool status)
virtual void set_select_status(bool select_status)
{
this->last_query_status = status;
this->select_status = select_status;
}
@ -157,18 +145,6 @@ 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()
{
return query_result;
@ -179,7 +155,7 @@ public:
{
bool has = false;
if( model_connector && query_result && query_result->has_db_result() && last_query_status )
if( model_connector && query_result && query_result->has_db_result() && select_status )
{
has = query_result->cur_row < query_result->result_rows;
}
@ -188,24 +164,6 @@ 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)
{
bool res = false;
@ -218,38 +176,35 @@ public:
DbConnector * db_connector = model_connector->get_db_connector();
if( db_connector )
{
try
{
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;
result.model_env->model_data = model_data;
try
{
finder_helper.clear(); // at the moment used only for calculating table prefixes (indices)
cursor_helper.clear();
cursor_helper.query_result = query_result;
cursor_helper.has_autogenerated_select = has_autogenerated_select;
cursor_helper.use_table_prefix_for_fetching_values = use_table_prefix_for_fetching;
cursor_helper.current_row = 0;
prepare_model_env_for_new_object(model_env_local);
result.model_env->model_data = model_data;
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.before_select();
res = last_query_status;
res = select_status;
if( res )
{
if( query_result->cur_row < query_result->result_rows )
{
result.map_values_from_query();
rows_counter = model_env_local.rows_counter;
if( result.found() )
{
@ -318,7 +273,6 @@ public:
return get_list_generic(result, clear_list);
}
virtual std::vector<ModelClass> get_vector()
{
std::vector<ModelClass> result;
@ -328,143 +282,6 @@ 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:
@ -475,98 +292,8 @@ protected:
CursorHelper cursor_helper;
FinderHelper finder_helper; // may CursorHelper and FinderHelper should be one class?
QueryResult * query_result;
bool last_query_status;
Select select_flags;
size_t rows_counter;
std::wstring rows_counter_column_name;
pt::TextStream cursor_name;
bool scroll_cursor;
bool select_status;
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>
@ -585,7 +312,7 @@ protected:
if( db_connector )
{
res = last_query_status;
res = select_status;
try
{
@ -632,30 +359,24 @@ protected:
cursor_helper.query_result = query_result;
cursor_helper.has_autogenerated_select = has_autogenerated_select;
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.clear();
prepare_model_env_for_new_object(model_env_local);
added_model.model_env = &model_env_local;
added_model.model_env->model = &added_model;
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;
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.before_select();
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() )
{
added_model.after_select();
@ -674,38 +395,6 @@ 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");
}
};

View File

@ -32,8 +32,8 @@
*
*/
#ifndef headerfile_morm_src_cursorhelper
#define headerfile_morm_src_cursorhelper
#ifndef headerfile_morm_cursorhelper
#define headerfile_morm_cursorhelper
#include "queryresult.h"
@ -48,7 +48,6 @@ public:
bool has_autogenerated_select;
QueryResult * query_result;
int current_column;
size_t current_row;
// 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
@ -72,7 +71,6 @@ public:
has_autogenerated_select = false;
query_result = nullptr;
current_column = 0;
current_row = 0;
use_table_prefix_for_fetching_values = false;
}

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2018-2024, Tomasz Sowa
* Copyright (c) 2018-2021, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -51,10 +51,16 @@ DbConnector::DbConnector()
expression_allocated = false;
log = nullptr;
log_queries = false;
transaction_index = 0;
transaction_group = 0;
}
DbConnector::DbConnector(const DbConnector &)
{
db_expression = nullptr;
expression_allocated = false;
log = nullptr;
}
DbConnector::~DbConnector()
{
deallocate_expression();
@ -79,7 +85,7 @@ void DbConnector::set_log_queries(bool log_queries)
}
bool DbConnector::query(const pt::Stream & stream)
bool DbConnector::query(const pt::TextStream & stream)
{
std::unique_ptr<QueryResult> query_result_ptr(create_query_result());
return query(stream, *query_result_ptr);
@ -101,7 +107,7 @@ bool DbConnector::query(const char * query_str)
bool DbConnector::query(const pt::Stream & stream, QueryResult & query_result)
bool DbConnector::query(const pt::TextStream & stream, QueryResult & query_result)
{
std::string query_str;
stream.to_str(query_str);
@ -118,7 +124,7 @@ bool DbConnector::query(const std::string & query_str, QueryResult & query_resul
bool DbConnector::query(const char * query_str, QueryResult & query_result)
{
// do the query
// do query
return false;
}
@ -144,248 +150,28 @@ bool DbConnector::query_remove(const char * query_str, QueryResult & query_resul
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::Stream & stream, QueryResult & query_result)
bool DbConnector::query_select(const pt::TextStream & stream, QueryResult & query_result)
{
return query(stream, query_result);
}
bool DbConnector::query_update(const pt::Stream & stream, QueryResult & query_result)
bool DbConnector::query_update(const pt::TextStream & stream, QueryResult & query_result)
{
return query(stream, query_result);
}
bool DbConnector::query_insert(const pt::Stream & stream, QueryResult & query_result)
bool DbConnector::query_insert(const pt::TextStream & stream, QueryResult & query_result)
{
return query(stream, query_result);
}
bool DbConnector::query_remove(const pt::Stream & stream, QueryResult & query_result)
bool DbConnector::query_remove(const pt::TextStream & stream, QueryResult & 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()
@ -395,7 +181,7 @@ DbExpression * DbConnector::get_expression()
}
void DbConnector::generate_select_columns(pt::Stream & stream, Model & model)
void DbConnector::generate_select_columns(pt::TextStream & stream, Model & model)
{
allocate_default_expression_if_needed();
@ -410,7 +196,7 @@ void DbConnector::generate_select_columns(pt::Stream & stream, Model & model)
}
void DbConnector::generate_insert_query(pt::Stream & stream, Model & model)
void DbConnector::generate_insert_query(pt::TextStream & stream, Model & model)
{
allocate_default_expression_if_needed();
@ -419,7 +205,7 @@ void DbConnector::generate_insert_query(pt::Stream & stream, Model & model)
db_expression->clear();
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);
stream << " (";
@ -427,7 +213,7 @@ void DbConnector::generate_insert_query(pt::Stream & stream, Model & model)
db_expression->set_output_type(MORM_OUTPUT_TYPE_DB_INSERT);
db_expression->generate_from_model(stream, model);
stream << ") VALUES (";
stream << ") values (";
db_expression->set_work_mode(MORM_WORK_MODE_MODEL_VALUES);
db_expression->generate_from_model(stream, model);
stream << ")";
@ -435,7 +221,7 @@ void DbConnector::generate_insert_query(pt::Stream & stream, Model & model)
}
void DbConnector::generate_update_query(pt::Stream & stream, Model & model)
void DbConnector::generate_update_query(pt::TextStream & stream, Model & model)
{
allocate_default_expression_if_needed();
@ -444,15 +230,15 @@ void DbConnector::generate_update_query(pt::Stream & stream, Model & model)
db_expression->clear();
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);
stream << " SET ";
stream << " set ";
db_expression->set_work_mode(MORM_WORK_MODE_MODEL_FIELDS_VALUES);
db_expression->set_output_type(MORM_OUTPUT_TYPE_DB_UPDATE);
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_output_type(MORM_OUTPUT_TYPE_DB_PRIMARY_KEY);
db_expression->generate_from_model(stream, model);
@ -460,7 +246,7 @@ void DbConnector::generate_update_query(pt::Stream & stream, Model & model)
}
void DbConnector::generate_remove_query(pt::Stream & stream, Model & model)
void DbConnector::generate_remove_query(pt::TextStream & stream, Model & model)
{
allocate_default_expression_if_needed();
@ -469,18 +255,17 @@ void DbConnector::generate_remove_query(pt::Stream & stream, Model & model)
db_expression->clear();
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);
stream << " WHERE ";
stream << " where ";
db_expression->set_work_mode(MORM_WORK_MODE_MODEL_FIELDS_VALUES);
db_expression->set_output_type(MORM_OUTPUT_TYPE_DB_PRIMARY_KEY);
db_expression->generate_from_model(stream, model);
}
}
bool DbConnector::insert(pt::Stream & stream, Model & model)
bool DbConnector::insert(pt::TextStream & stream, Model & model)
{
std::unique_ptr<QueryResult> query_result_ptr(create_query_result());
@ -489,7 +274,7 @@ bool DbConnector::insert(pt::Stream & stream, Model & model)
}
bool DbConnector::update(pt::Stream & stream, Model & model)
bool DbConnector::update(pt::TextStream & stream, Model & model)
{
std::unique_ptr<QueryResult> query_result_ptr(create_query_result());
@ -498,7 +283,7 @@ bool DbConnector::update(pt::Stream & stream, Model & model)
}
bool DbConnector::remove(pt::Stream & stream, Model & model)
bool DbConnector::remove(pt::TextStream & stream, Model & model)
{
std::unique_ptr<QueryResult> query_result_ptr(create_query_result());
@ -528,7 +313,7 @@ void DbConnector::allocate_default_expression_if_needed()
}
unsigned int DbConnector::unescape_hex_char_part(char hex)
char DbConnector::unescape_hex_char_part(char hex)
{
if( hex>='0' && hex<='9' )
{
@ -563,79 +348,43 @@ unsigned int DbConnector::unescape_hex_char_part(char hex)
}
const char * DbConnector::unescape_hex_char(const char * str, size_t len, unsigned int & res)
char DbConnector::unescape_hex_char(char char1, char char2)
{
unsigned int c;
res = 0;
int c1 = unescape_hex_char_part(char1);
int c2 = unescape_hex_char_part(char2);
for(size_t i = 0 ; i < len ; ++i)
{
if( *str != 0 )
{
c = unescape_hex_char_part(*str);
str += 1;
}
else
{
c = 0;
}
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);
return static_cast<char>(((c1 << 4) | c2));
}
void DbConnector::unescape_hex_string(const char * str, std::string & out)
{
unsigned int c = 0;
while( *str != 0 )
for(size_t i=0 ; str[i] != 0 ; i+=2 )
{
str = unescape_hex_char(str, sizeof(char) * 2, c);
out += (char)c;
out += unescape_hex_char(str[i], str[i+1]);
}
}
void DbConnector::unescape_hex_string(const char * str, std::wstring & out)
void DbConnector::unescape_hex_string(const char * str, std::wstring & out, const FT & field_type)
{
unsigned int c = 0;
while( *str != 0 )
if( field_type.use_utf8() )
{
str = unescape_hex_char(str, sizeof(wchar_t) * 2, c);
out += (wchar_t)c;
size_t len;
wchar_t c;
while( *str != 0 && (len = unescape_hex_char(str, c, field_type)) > 0 )
{
out += c;
str += len;
}
}
else
{
for(size_t i=0 ; str[i] != 0 ; i+=2 )
{
out += static_cast<wchar_t>(static_cast<unsigned char>(unescape_hex_char(str[i], str[i+1])));
}
}
}
@ -646,60 +395,151 @@ void DbConnector::unescape_bin_string(const char * str, std::string & out)
}
void DbConnector::unescape_bin_string(const char * str, std::wstring & out)
void DbConnector::unescape_bin_string(const char * str, std::wstring & out, const FT & field_type)
{
unescape_hex_string(str, out);
unescape_hex_string(str, out, field_type);
}
// returns how many characters have been provided to utf8_str buffer
// 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;
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)
{
if( field_type.is_hexadecimal() )
wchar_t c;
field_value = 0;
get_value(value_str, c, field_type);
if( field_type.use_utf8() )
{
unescape_hex_char(value_str, field_value);
}
else
if( field_type.is_binary() )
if( c <= 127 )
{
unescape_bin_char(value_str, field_value);
field_value = static_cast<char>(c);
}
else
{
field_value = *value_str;
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
{
field_value = static_cast<char>(c);
}
}
// CHECKME need to be tested
void DbConnector::get_value(const char * value_str, unsigned char & field_value, const FT & field_type)
{
char tmp_char;
get_value(value_str, tmp_char, field_type);
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)
{
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;
if( field_type.is_hexadecimal() )
{
unescape_hex_char(value_str, field_value);
}
else
if( field_type.is_binary() )
{
unescape_bin_char(value_str, field_value);
unescape_bin_char(value_str, field_value, field_type);
}
else
if( field_type.is_hexadecimal() )
{
unescape_hex_char(value_str, field_value, field_type);
}
else
{
@ -712,33 +552,64 @@ void DbConnector::get_value(const char * value_str, char32_t & field_value, cons
if( is_correct )
{
field_value = static_cast<char32_t>(value_int);
field_value = static_cast<wchar_t>(value_int);
}
else
{
field_value = 0xFFFD; // U+FFFD "replacement character";
// report an error?
}
}
else
{
field_value = static_cast<char32_t>((unsigned char)*value_str);
field_value = static_cast<wchar_t>((unsigned char)*value_str);
}
}
}
void DbConnector::get_value(const char * value_str, std::string & field_value, const FT & field_type)
// 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_hexadecimal() )
if( field_type.is_binary() )
{
unescape_hex_string(value_str, field_value);
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)
{
if( field_type.is_binary() )
{
unescape_bin_string(value_str, field_value);
}
else
if( field_type.is_hexadecimal() )
{
unescape_hex_string(value_str, field_value);
}
else
{
field_value = value_str;
}
@ -751,34 +622,6 @@ 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)
{
// IMPROVE ME
@ -790,56 +633,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)
{
// IMPROVE ME give some overflow checking
field_value = (short)pt::to_i(value_str, 10);
field_value = (short)pt::Toi(value_str, 10);
}
void DbConnector::get_value(const char * value_str, unsigned short & field_value, const FT & field_type)
{
// IMPROVE ME give some overflow checking
field_value = (unsigned short)pt::to_ui(value_str, 10);
field_value = (unsigned short)pt::Toui(value_str, 10);
}
void DbConnector::get_value(const char * value_str, int & field_value, const FT & field_type)
{
// IMPROVE ME give some overflow checking
field_value = pt::to_i(value_str, 10);
field_value = pt::Toi(value_str, 10);
}
void DbConnector::get_value(const char * value_str, unsigned int & field_value, const FT & field_type)
{
// IMPROVE ME give some overflow checking
field_value = pt::to_ui(value_str, 10);
field_value = pt::Toui(value_str, 10);
}
void DbConnector::get_value(const char * value_str, long & field_value, const FT & field_type)
{
// IMPROVE ME give some overflow checking
field_value = pt::to_l(value_str, 10);
field_value = pt::Tol(value_str, 10);
}
void DbConnector::get_value(const char * value_str, unsigned long & field_value, const FT & field_type)
{
// IMPROVE ME give some overflow checking
field_value = pt::to_ul(value_str, 10);
field_value = pt::Toul(value_str, 10);
}
void DbConnector::get_value(const char * value_str, long long & field_value, const FT & field_type)
{
// IMPROVE ME give some overflow checking
field_value = pt::to_ll(value_str, 10);
field_value = pt::Toll(value_str, 10);
}
void DbConnector::get_value(const char * value_str, unsigned long long & field_value, const FT & field_type)
{
// IMPROVE ME give some overflow checking
field_value = pt::to_ull(value_str, 10);
field_value = pt::Toull(value_str, 10);
}
@ -867,20 +710,7 @@ 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)
{
// IMPROVE ME give some log if parsing failed
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());
}
field_value.Parse(value_str);
}
@ -927,6 +757,4 @@ const char * DbConnector::query_last_sequence(const wchar_t * sequence_table_nam
return nullptr;
}
}

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2018-2024, Tomasz Sowa
* Copyright (c) 2018-2021, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -32,10 +32,10 @@
*
*/
#ifndef headerfile_morm_src_dbconnector
#define headerfile_morm_src_dbconnector
#ifndef headerfile_morm_dbconnector
#define headerfile_morm_dbconnector
#include "textstream/stream.h"
#include "textstream/textstream.h"
#include "log/log.h"
#include "queryresult.h"
#include "ft.h"
@ -52,8 +52,7 @@ class DbConnector
public:
DbConnector();
DbConnector(const DbConnector &) = delete;
DbConnector(DbConnector &&) = delete;
DbConnector(const DbConnector &);
virtual ~DbConnector();
virtual void set_logger(pt::Log * log);
@ -63,22 +62,22 @@ public:
DbExpression * get_expression();
virtual void generate_select_columns(pt::Stream & stream, Model & model);
virtual void generate_insert_query(pt::Stream & stream, Model & model);
virtual void generate_update_query(pt::Stream & stream, Model & model);
virtual void generate_remove_query(pt::Stream & stream, Model & model);
virtual void generate_select_columns(pt::TextStream & stream, Model & model);
virtual void generate_insert_query(pt::TextStream & stream, Model & model);
virtual void generate_update_query(pt::TextStream & stream, Model & model);
virtual void generate_remove_query(pt::TextStream & stream, Model & model);
virtual bool insert(pt::Stream & stream, Model & model);
virtual bool update(pt::Stream & stream, Model & model);
virtual bool remove(pt::Stream & stream, Model & model);
virtual bool insert(pt::TextStream & stream, Model & model);
virtual bool update(pt::TextStream & stream, Model & model);
virtual bool remove(pt::TextStream & stream, Model & model);
virtual bool query(const pt::Stream & stream);
virtual bool query(const pt::TextStream & stream);
virtual bool query(const std::string & query_str);
virtual bool query(const char * query_str);
virtual QueryResult * create_query_result() = 0;
virtual bool query(const pt::Stream & stream, QueryResult & query_result);
virtual bool query(const pt::TextStream & stream, QueryResult & query_result);
virtual bool query(const std::string & query_str, QueryResult & query_result);
virtual bool query(const char * query_str, QueryResult & query_result);
@ -86,60 +85,15 @@ public:
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_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::Stream & stream, QueryResult & query_result);
virtual bool query_update(const pt::Stream & stream, QueryResult & query_result);
virtual bool query_insert(const pt::Stream & 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 bool query_select(const pt::TextStream & stream, QueryResult & query_result);
virtual bool query_update(const pt::TextStream & stream, QueryResult & query_result);
virtual bool query_insert(const pt::TextStream & stream, QueryResult & query_result);
virtual bool query_remove(const pt::TextStream & stream, QueryResult & query_result);
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);
@ -187,8 +141,6 @@ protected:
bool expression_allocated;
pt::Log * log;
bool log_queries;
size_t transaction_index;
size_t transaction_group;
virtual void allocate_default_expression() = 0;
@ -197,25 +149,22 @@ protected:
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::wstring & out);
virtual void unescape_hex_string(const char * str, std::wstring & out, const FT & field_type);
virtual void unescape_bin_string(const char * str, std::string & out);
virtual void unescape_bin_string(const char * str, std::wstring & out);
virtual void unescape_bin_string(const char * str, std::wstring & out, const FT & field_type);
virtual bool rollback_one_transaction(size_t index);
virtual bool commit_one_transaction(size_t index);
virtual size_t unescape_hex_char(const char * value_str, char * utf8_str, size_t utf8_str_max_len);
virtual size_t unescape_hex_char(const char * value_str, wchar_t & field_value, const FT & field_type);
virtual size_t unescape_bin_char(const char * value_str, wchar_t & field_value, const FT & field_type);
private:
unsigned int unescape_hex_char_part(char hex);
const char * unescape_hex_char(const char * str, size_t len, unsigned int & res);
char unescape_hex_char_part(char hex);
char unescape_hex_char(char char1, char char2);

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2018-2024, Tomasz Sowa
* Copyright (c) 2018-2021, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -33,7 +33,6 @@
*/
#include "dbexpression.h"
#include "model.h"
namespace morm
@ -42,6 +41,7 @@ namespace morm
DbExpression::DbExpression()
{
output_type = 0;
}
@ -50,6 +50,18 @@ 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)
{
if( output_type == MORM_OUTPUT_TYPE_DB_INSERT )
@ -64,8 +76,7 @@ bool DbExpression::can_field_be_generated(const FT & field_type)
else
if( output_type == MORM_OUTPUT_TYPE_DB_PRIMARY_KEY ||
output_type == MORM_OUTPUT_TYPE_JOIN_TABLES ||
output_type == MORM_OUTPUT_TYPE_DB_INSERT_PRIMARY_KEY ||
output_type == MORM_OUTPUT_TYPE_DB_UPDATE_PRIMARY_KEY )
output_type == MORM_OUTPUT_TYPE_DB_INSERT_PRIMARY_KEY )
{
return field_type.is_primary_key();
}
@ -95,8 +106,7 @@ void DbExpression::field_before()
(*out_stream) << " AND ";
}
else
if( output_type == MORM_OUTPUT_TYPE_DB_INSERT_PRIMARY_KEY ||
output_type == MORM_OUTPUT_TYPE_DB_UPDATE_PRIMARY_KEY )
if( output_type == MORM_OUTPUT_TYPE_DB_INSERT_PRIMARY_KEY )
{
(*out_stream) << ", ";
}
@ -107,11 +117,7 @@ void DbExpression::field_before()
output_type == MORM_OUTPUT_TYPE_WHERE_LE ||
output_type == MORM_OUTPUT_TYPE_WHERE_LT ||
output_type == MORM_OUTPUT_TYPE_WHERE_NOT_EQ ||
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 )
output_type == MORM_OUTPUT_TYPE_WHERE_IN )
{
int conjunction = MORM_CONJUNCTION_AND;
@ -171,27 +177,7 @@ void DbExpression::put_name_value_separator()
else
if( output_type == MORM_OUTPUT_TYPE_WHERE_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 ";
(*out_stream) << " in ";
}
}
@ -208,12 +194,6 @@ void DbExpression::table_field_separator()
}
void DbExpression::alias_names_separator()
{
(*out_stream) << '.';
}
void DbExpression::before_schema_name()
{
(*out_stream) << '"';
@ -250,34 +230,15 @@ void DbExpression::after_field_name()
}
void DbExpression::before_alias_name()
{
(*out_stream) << '"';
}
void DbExpression::after_alias_name()
{
(*out_stream) << '"';
}
void DbExpression::before_field_value_string(const FT & field_type, ModelEnv * model_env)
void DbExpression::before_field_value_string(const FT & field_type)
{
(*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)
void DbExpression::after_field_value_string(const FT & field_type)
{
if( model_env && model_env->use_escaping_for_like && model_env->add_postfix_percent )
(*out_stream) << '%';
(*out_stream) << "'";
}
@ -290,7 +251,7 @@ void DbExpression::prepare_to_where_clause()
}
DbExpression & DbExpression::group_or(pt::Stream & stream)
DbExpression & DbExpression::group_or(pt::TextStream & stream)
{
out_stream = &stream;
field_before();
@ -302,7 +263,7 @@ DbExpression & DbExpression::group_or(pt::Stream & stream)
return *this;
}
DbExpression & DbExpression::group_and(pt::Stream & stream)
DbExpression & DbExpression::group_and(pt::TextStream & stream)
{
out_stream = &stream;
field_before();
@ -314,7 +275,7 @@ DbExpression & DbExpression::group_and(pt::Stream & stream)
return *this;
}
DbExpression & DbExpression::group_end(pt::Stream & stream)
DbExpression & DbExpression::group_end(pt::TextStream & stream)
{
out_stream = &stream;
@ -330,136 +291,13 @@ DbExpression & DbExpression::group_end(pt::Stream & stream)
}
DbExpression & DbExpression::page(pt::Stream & stream, size_t page_number, size_t page_size)
DbExpression & DbExpression::page(pt::TextStream & stream, size_t page_number, size_t page_size)
{
stream << " LIMIT " << (page_number*page_size) << "," << page_size << " ";
stream << " limit " << page_number << "," << page_size << " ";
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;
}
}

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2018-2024, Tomasz Sowa
* Copyright (c) 2018-2021, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -32,8 +32,8 @@
*
*/
#ifndef headerfile_morm_src_dbexpression
#define headerfile_morm_src_dbexpression
#ifndef headerfile_morm_dbexpression
#define headerfile_morm_dbexpression
#include <vector>
#include "baseexpression.h"
@ -50,19 +50,17 @@ public:
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 DbExpression & group_or(pt::Stream & stream);
virtual DbExpression & group_and(pt::Stream & stream);
virtual DbExpression & group_end(pt::Stream & stream);
virtual DbExpression & group_or(pt::TextStream & stream);
virtual DbExpression & group_and(pt::TextStream & stream);
virtual DbExpression & group_end(pt::TextStream & stream);
/*
* 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);
virtual DbExpression & page(pt::TextStream & stream, size_t page_number, size_t page_size);
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)
@ -70,57 +68,41 @@ public:
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 += L" AS ";
column_expression += L" as ";
column_expression += new_column_name;
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:
int output_type;
std::vector<int> conjunctions;
bool can_field_be_generated(const FT & field_type) override;
void field_before() override;
void put_name_value_separator() override;
bool can_field_be_generated(const FT & field_type);
void field_before();
void put_name_value_separator();
void schema_table_separator() override;
void table_field_separator() override;
void alias_names_separator() override;
void schema_table_separator();
void table_field_separator();
void before_schema_name() override;
void after_schema_name() override;
void before_schema_name();
void after_schema_name();
void before_table_name() override;
void after_table_name() override;
void before_table_name();
void after_table_name();
void before_field_name() override;
void after_field_name() override;
void before_field_name();
void after_field_name();
void before_alias_name() override;
void after_alias_name() override;
void add_additional_columns(Model & model) override;
private:
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;
void before_field_value_string(const FT & field_type);
void after_field_value_string(const FT & field_type);
virtual void add_rows_counter_column(Model & model);
};

View File

@ -1,128 +0,0 @@
/*
* 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

View File

@ -32,8 +32,8 @@
*
*/
#ifndef headerfile_morm_src_fieldvaluehelper
#define headerfile_morm_src_fieldvaluehelper
#ifndef headerfile_morm_fieldvaluehelper
#define headerfile_morm_fieldvaluehelper
#include <vector>
#include <typeinfo>

File diff suppressed because it is too large Load Diff

View File

@ -32,8 +32,8 @@
*
*/
#ifndef headerfile_morm_src_finderhelper
#define headerfile_morm_src_finderhelper
#ifndef headerfile_morm_finderhelper
#define headerfile_morm_finderhelper
#include "queryresult.h"

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2018-2024, Tomasz Sowa
* Copyright (c) 2018-2021, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -67,7 +67,8 @@ 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();
@ -81,6 +82,8 @@ void FlatConnector::to_text(pt::Stream & stream, Model & model, Export exp)
}
void FlatConnector::deallocate_expression()
{
if( expression_allocated )

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2018-2024, Tomasz Sowa
* Copyright (c) 2018-2021, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -32,11 +32,10 @@
*
*/
#ifndef headerfile_morm_src_flatconnector
#define headerfile_morm_src_flatconnector
#ifndef headerfile_morm_flatconnector
#define headerfile_morm_flatconnector
#include "textstream/stream.h"
#include "export.h"
#include "textstream/textstream.h"
namespace morm
@ -52,7 +51,7 @@ public:
FlatConnector();
virtual ~FlatConnector();
virtual void to_text(pt::Stream & stream, Model & model, Export exp);
virtual void to_text(pt::TextStream & stream, Model & model);
virtual void set_expression(FlatExpression & expression);
virtual FlatExpression * get_expression();

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2018-2023, Tomasz Sowa
* Copyright (c) 2018-2021, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -39,27 +39,9 @@
namespace morm
{
FlatExpression::FlatExpression()
void FlatExpression::esc(const pt::Date & date, pt::TextStream & stream, const FT & field_type)
{
}
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();
date.SerializeISO(stream);
}

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2018-2024, Tomasz Sowa
* Copyright (c) 2018-2021, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -32,8 +32,8 @@
*
*/
#ifndef headerfile_morm_src_flatexpression
#define headerfile_morm_src_flatexpression
#ifndef headerfile_morm_flatexpression
#define headerfile_morm_flatexpression
#include "baseexpression.h"
@ -45,15 +45,9 @@ class FlatExpression : public BaseExpression
{
public:
FlatExpression();
virtual ~FlatExpression();
void esc(const pt::Date & date, pt::TextStream & stream, const FT & field_type);
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;
};

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2021-2023, Tomasz Sowa
* Copyright (c) 2021, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -32,8 +32,8 @@
*
*/
#ifndef headerfile_morm_src_ft
#define headerfile_morm_src_ft
#ifndef headerfile_morm_ft
#define headerfile_morm_ft
namespace morm
{
@ -58,25 +58,12 @@ public:
no_fetchable = 32, /* not supported yet */
no_removable = 64,
raw_field_name = 128,
dont_use_utf8 = 256, /* used only with wchar_t and std::wstring, ignored if a binary or a hexadecimal flags are used */
dont_use_utf8 = 256,
hexadecimal = 512,
binary = 1024,
json = 2048,
space = 4096,
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 */
};
/*
@ -112,18 +99,6 @@ public:
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
{
return (type & flag_mask) != 0;
@ -201,36 +176,6 @@ public:
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);
}
};
}

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2018-2024, Tomasz Sowa
* Copyright (c) 2018, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -32,8 +32,8 @@
*
*/
#ifndef headerfile_morm_src_jsonconnector
#define headerfile_morm_src_jsonconnector
#ifndef headerfile_morm_jsonconnector
#define headerfile_morm_jsonconnector
#include "flatconnector.h"
@ -51,7 +51,7 @@ public:
protected:
void allocate_default_expression() override;
void allocate_default_expression();
};

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2018-2024, Tomasz Sowa
* Copyright (c) 2018-2021, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -34,7 +34,7 @@
#include "jsonexpression.h"
#include "morm_types.h"
#include "convert/misc.h"
namespace morm
@ -88,35 +88,17 @@ void JSONExpression::after_field_name()
void JSONExpression::before_field_value_string(const FT & field_type, ModelEnv * model_env)
void JSONExpression::before_field_value_string(const FT & field_type)
{
(*out_stream) << "\"";
}
void JSONExpression::after_field_value_string(const FT & field_type, ModelEnv * model_env)
void JSONExpression::after_field_value_string(const FT & field_type)
{
(*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()
{
(*out_stream) << ':';
@ -135,31 +117,50 @@ void JSONExpression::after_field_value_list()
}
bool JSONExpression::esc_char(char32_t val, pt::Stream & stream, const FT & field_type, ModelEnv * model_env)
void JSONExpression::esc(char val, pt::TextStream & stream, const FT & field_type)
{
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() )
if( field_type.is_hexadecimal() || field_type.is_binary() )
{
pt::TextStream tmp_stream;
space.serialize_to_space_stream(tmp_stream, pretty_print);
BaseExpression::esc(tmp_stream, stream, field_type, model_env);
char_to_hex(val, stream);
}
else
{
// when serializing as json put it directly without escaping
if( (unsigned char)val < 32 )
{
char buf[10];
size_t len;
pt::Toa((unsigned char)val, buf, sizeof(buf)/sizeof(char), 16, &len);
pt::TextStream tmp_stream;
space.serialize_to_json_stream(tmp_stream, pretty_print);
BaseExpression::esc(tmp_stream, stream, field_type, model_env);
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;
}
}
}
}
}

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2018-2024, Tomasz Sowa
* Copyright (c) 2018-2021, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -32,8 +32,8 @@
*
*/
#ifndef headerfile_morm_src_jsonexpression
#define headerfile_morm_src_jsonexpression
#ifndef headerfile_morm_jsonexpression
#define headerfile_morm_jsonexpression
#include "flatexpression.h"
@ -47,32 +47,32 @@ class JSONExpression : public FlatExpression
protected:
void before_generate_from_model() override;
void after_generate_from_model() override;
void before_generate_from_model();
void after_generate_from_model();
void field_before() override;
void field_before();
void before_field_name() override;
void after_field_name() override;
void before_field_name();
void after_field_name();
void put_name_value_separator() override;
void put_name_value_separator();
void before_field_value_list() override;
void after_field_value_list() override;
void before_field_value_list();
void after_field_value_list();
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;
// using FlatExpression::esc to suppress clang warning:
// 'morm::JSONExpression::esc' hides overloaded virtual function [-Woverloaded-virtual]
using FlatExpression::esc;
void esc(char val, pt::TextStream & stream, const FT & field_type);
private:
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;
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 before_field_value_string(const FT & field_type);
void after_field_value_string(const FT & field_type);
};

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2018-2024, Tomasz Sowa
* Copyright (c) 2018-2021, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -33,7 +33,6 @@
*/
#include "model.h"
#include "convert/text.h"
#include "utf8/utf8.h"
@ -75,28 +74,13 @@ 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)
{
this->has_primary_key_set = has_primary_key;
}
bool Model::get_has_primary_key_set() const
bool Model::get_has_primary_key_set()
{
return this->has_primary_key_set;
}
@ -194,7 +178,7 @@ bool Model::found()
}
void Model::get_table_name(pt::Stream & stream, bool with_schema_name, ModelData * model_data, bool clear_stream)
void Model::get_table_name(pt::WTextStream & stream, bool with_schema_name, ModelData * model_data, bool clear_stream)
{
if( clear_stream )
{
@ -282,30 +266,6 @@ 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)
{
@ -348,9 +308,10 @@ 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( !exp.is_no_clear_stream() )
if( clear_stream )
{
stream.clear();
}
@ -359,7 +320,7 @@ void Model::to_text(pt::Stream & stream, ModelData * model_data, Export exp)
model_env = &model_env_local;
model_env->has_primary_key_set = has_primary_key_set;
model_env->model_work_mode = MORM_MODEL_WORK_MODE_GENERATING_FLAT_STRING;
model_env->dump_mode = exp.is_dump_mode();
model_env->dump_mode = dump_mode;
model_env->model_data = model_data;
model_env->model = this;
@ -372,7 +333,7 @@ void Model::to_text(pt::Stream & stream, ModelData * model_data, Export exp)
try
{
// table(); at the moment flat strings (json/space) do not need a table name
flat_connector->to_text(stream, *this, exp);
flat_connector->to_text(stream, *this);
}
catch(...)
{
@ -386,52 +347,25 @@ void Model::to_text(pt::Stream & stream, ModelData * model_data, Export exp)
}
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)
void Model::to_text(pt::TextStream & stream, ModelData & model_data, bool clear_stream, bool dump_mode)
{
to_text(stream, &model_data, clear_stream, dump_mode);
}
void Model::to_text(pt::Stream & stream, bool clear_stream, bool dump_mode)
void Model::to_text(pt::TextStream & stream, bool clear_stream, bool 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)
{
if( model_connector )
{
// CHECK ME what if the stream is being used by someone else?
pt::Stream * out_stream = model_connector->get_stream();
// CHECK ME what if the stream is being used by something other?
pt::TextStream * out_stream = model_connector->get_stream();
if( out_stream )
{
@ -471,7 +405,7 @@ std::string Model::to_string()
void Model::generate_insert_query(pt::Stream & stream, ModelData * model_data)
void Model::generate_insert_query(pt::TextStream & stream, ModelData * model_data)
{
ModelEnv model_env_local;
model_env = &model_env_local;
@ -521,11 +455,12 @@ bool Model::insert(ModelData * model_data, bool insert_whole_tree)
model_env = &model_env_local;
model_env->model_data = model_data;
model_env->model = this;
bool status = false;
try
{
table();
insert_tree(insert_whole_tree);
status = insert_tree(insert_whole_tree);
}
catch(...)
{
@ -534,37 +469,40 @@ bool Model::insert(ModelData * model_data, bool insert_whole_tree)
}
model_env = nullptr;
return model_env_local.status;
return status;
}
void Model::insert_tree(bool insert_whole_tree)
// has ModelEnv set
// 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;
if( model_env->status && insert_whole_tree )
if( insert_whole_tree )
{
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;
fields();
}
if( model_env->status && model_connector )
if( model_connector )
{
model_env->model_work_mode = MORM_MODEL_WORK_MODE_GENERATING_DB_SQL;
DbConnector * db_connector = model_connector->get_db_connector();
// CHECK ME what if the stream is being used by someone else?
pt::Stream * out_stream = model_connector->get_stream();
// CHECK ME what if the stream is being used by something other?
pt::TextStream * out_stream = model_connector->get_stream();
if( db_connector && out_stream )
{
before_insert();
out_stream->clear();
model_env->status = db_connector->insert(*out_stream, *this);
result = db_connector->insert(*out_stream, *this);
if( model_env->status )
if( result )
{
/*
* after_insert() should read the new primary key and set has_primary_key_set flag if the key was read correctly
@ -587,27 +525,21 @@ void Model::insert_tree(bool insert_whole_tree)
after_insert_failure();
}
}
else
{
model_env->status = false;
}
}
else
{
model_env->status = false;
}
if( model_env->status && insert_whole_tree )
if( insert_whole_tree )
{
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;
fields();
}
return result;
}
void Model::generate_update_query(pt::Stream & stream, ModelData * model_data)
void Model::generate_update_query(pt::TextStream & stream, ModelData * model_data)
{
ModelEnv model_env_local;
model_env = &model_env_local;
@ -650,11 +582,12 @@ bool Model::update(ModelData * model_data, bool update_whole_tree)
model_env = &model_env_local;
model_env->model_data = model_data;
model_env->model = this;
bool status = false;
try
{
table();
update_tree(update_whole_tree);
status = update_tree(update_whole_tree);
}
catch(...)
{
@ -663,66 +596,62 @@ bool Model::update(ModelData * model_data, bool update_whole_tree)
}
model_env = nullptr;
return model_env_local.status;
return status;
}
void Model::update_tree(bool update_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::update_tree(bool update_whole_tree)
{
bool result = false;
model_env->has_primary_key_set = 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");
model_env->status = false;
return result;
}
if( model_env->status && update_whole_tree )
if( update_whole_tree )
{
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;
fields();
}
if( model_env->status && model_connector )
if( model_connector )
{
model_env->model_work_mode = MORM_MODEL_WORK_MODE_GENERATING_DB_SQL;
DbConnector * db_connector = model_connector->get_db_connector();
// CHECK ME what if the stream is being used by something other?
pt::Stream * out_stream = model_connector->get_stream();
pt::TextStream * out_stream = model_connector->get_stream();
if( db_connector && out_stream )
{
before_update();
out_stream->clear();
model_env->status = db_connector->update(*out_stream, *this);
result = db_connector->update(*out_stream, *this);
if( model_env->status )
if( result )
after_update();
else
after_update_failure();
}
else
{
model_env->status = false;
}
}
else
{
model_env->status = false;
}
if( model_env->status && update_whole_tree )
if( update_whole_tree )
{
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;
fields();
}
return result;
}
void Model::generate_remove_query(pt::Stream & stream, ModelData * model_data)
void Model::generate_remove_query(pt::TextStream & stream, ModelData * model_data)
{
ModelEnv model_env_local;
model_env = &model_env_local;
@ -766,11 +695,12 @@ bool Model::remove(ModelData * model_data, bool remove_whole_tree)
model_env = &model_env_local;
model_env->model_data = model_data;
model_env->model = this;
bool status = false;
try
{
table();
remove_tree(remove_whole_tree);
status = remove_tree(remove_whole_tree);
}
catch(...)
{
@ -779,42 +709,44 @@ bool Model::remove(ModelData * model_data, bool remove_whole_tree)
}
model_env = nullptr;
return model_env_local.status;
return status;
}
void Model::remove_tree(bool remove_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::remove_tree(bool remove_whole_tree)
{
bool result = false;
model_env->has_primary_key_set = 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");
model_env->status = false;
return result;
}
if( model_env->status && remove_whole_tree )
if( remove_whole_tree )
{
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;
fields();
}
if( model_env->status && model_connector )
if( model_connector )
{
model_env->model_work_mode = MORM_MODEL_WORK_MODE_GENERATING_DB_SQL;
DbConnector * db_connector = model_connector->get_db_connector();
// CHECK ME what if the stream is being used by someone else?
pt::Stream * out_stream = model_connector->get_stream();
// CHECK ME what if the stream is being used by something other?
pt::TextStream * out_stream = model_connector->get_stream();
if( db_connector && out_stream )
{
before_remove();
out_stream->clear();
model_env->status = db_connector->remove(*out_stream, *this);
result = db_connector->remove(*out_stream, *this);
if( model_env->status )
if( result )
{
save_mode = DO_NOTHING_ON_SAVE;
has_primary_key_set = false;
@ -826,22 +758,16 @@ void Model::remove_tree(bool remove_whole_tree)
after_remove_failure();
}
}
else
{
model_env->status = false;
}
}
else
{
model_env->status = false;
}
if( model_env->status && remove_whole_tree )
if( remove_whole_tree )
{
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;
fields();
}
return result;
}
@ -865,11 +791,12 @@ bool Model::save(ModelData * model_data, bool save_whole_tree)
model_env = &model_env_local;
model_env->model_data = model_data;
model_env->model = this;
bool status = false;
try
{
table();
save_tree(save_whole_tree);
status = save_tree(save_whole_tree);
}
catch(...)
{
@ -878,16 +805,17 @@ bool Model::save(ModelData * model_data, bool save_whole_tree)
}
model_env = nullptr;
return model_env_local.status;
return status;
}
void Model::save_tree(bool save_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::save_tree(bool save_whole_tree)
{
bool result = false;
model_env->has_primary_key_set = has_primary_key_set;
SaveMode origin_save_mode = save_mode;
if( model_env->status && save_whole_tree )
if( save_whole_tree )
{
if( save_mode == DO_DELETE_ON_SAVE )
model_env->model_work_mode = MORM_MODEL_WORK_MODE_ITERATE_THROUGH_CHILDS_WITHOUT_FOREIGN_KEY;
@ -898,34 +826,32 @@ void Model::save_tree(bool save_whole_tree)
fields();
}
if( model_env->status )
{
ModelEnv * old_model_env = model_env; // remove, insert or update will set model_env to nullptr
switch( save_mode )
{
case DO_DELETE_ON_SAVE:
remove_tree(false);
result = remove_tree(false);
break;
case DO_INSERT_ON_SAVE:
insert_tree(false);
result = insert_tree(false);
break;
case DO_UPDATE_ON_SAVE:
update_tree(false);
result = update_tree(false);
break;
case DO_NOTHING_ON_SAVE:
result = true;
break;
}
model_env = old_model_env;
}
if( model_env->status && save_whole_tree )
if( save_whole_tree )
{
if( origin_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_WITH_FOREIGN_KEY;
else
model_env->model_work_mode = MORM_MODEL_WORK_MODE_ITERATE_THROUGH_CHILDS_WITHOUT_FOREIGN_KEY;
@ -933,10 +859,12 @@ void Model::save_tree(bool save_whole_tree)
model_env->model_work_submode = MORM_MODEL_WORK_SUBMODE_SAVE;
fields();
}
return result;
}
void Model::generate_select_columns(pt::Stream & stream)
void Model::generate_select_columns(pt::TextStream & stream)
{
if( model_connector && model_env )
{
@ -962,7 +890,6 @@ 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->has_primary_key_set = true; // whether all primary_columns were different than null
fields();
map_additional_columns_from_query();
model_env->model_work_mode = MORM_MODEL_WORK_MODE_NONE;
if( model_env->was_primary_key_read && model_env->has_primary_key_set )
@ -979,40 +906,6 @@ 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()
{
@ -1191,25 +1084,17 @@ void Model::log_table_name_with_field(const wchar_t * db_field_name, bool put_sc
}
pt::Log * Model::get_logger()
void Model::put_to_log(const wchar_t * str)
{
if( model_connector )
{
return model_connector->get_logger();
}
return nullptr;
}
void Model::put_to_log(const wchar_t * str)
{
pt::Log * log = get_logger();
pt::Log * log = model_connector->get_logger();
if( log )
{
(*log) << str << pt::Log::logend;
}
}
}
@ -1255,14 +1140,14 @@ void Model::field_model_left_join(const wchar_t * db_field_name, Model & field_m
join_tables_str << "LEFT JOIN ";
pt::Stream * db_expression_stream = db_expression->get_text_stream();
pt::TextStream * db_expression_stream = db_expression->get_text_stream();
int expr_work_mode = db_expression->get_work_mode();
int expr_output_type = db_expression->get_output_type();
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);
join_tables_str << " AS ";
db_expression->alias_to_stream(join_tables_str, field_model.model_env->table_name, field_model.model_env->table_index);
db_expression->table_with_index_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_output_type(MORM_OUTPUT_TYPE_JOIN_TABLES);
@ -1475,7 +1360,7 @@ void Model::field_model_generate_flat_string(const wchar_t * flat_field_name, Mo
if( flat_expression )
{
if( model_env->dump_mode || field_model.save_mode != DO_DELETE_ON_SAVE )
if( model_env->dump_mode || field_model.save_mode == DO_INSERT_ON_SAVE || field_model.save_mode == DO_UPDATE_ON_SAVE )
{
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);
@ -1549,9 +1434,7 @@ 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 &&
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_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 )
db_expression->get_output_type() != MORM_OUTPUT_TYPE_DB_UPDATE )
{
field_model.fields();
}
@ -1562,13 +1445,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, const FT & field_type)
void Model::field_model_clear_values(Model & field_model)
{
Clearer * clearer = model_connector->get_clearer();
if( clearer )
{
clearer->clear_model(field_model, field_type);
clearer->clear_model(field_model);
}
}
@ -1647,7 +1530,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 )
{
field_model_clear_values(field_model, field_type);
field_model_clear_values(field_model);
}
if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_GET_FIELD_MODEL )
@ -1659,25 +1542,22 @@ 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_GET_MODEL_WRAPPER )
if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_PUT_FIELD_RAW_VALUE_TO_STREAM )
{
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->wrapper.model )
!model_env->model )
{
model_env->wrapper.model = &field_model;
}
}
// FIX ME
//model_env->wrapper.model = &field_model;
if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_PROPAGATE_SAVE_STATUS )
{
field_model.set_save_mode2(save_mode, true);
// model_env->was_field_found = true;
// model_env->model = &field_model;
}
}
field_model.model_env = nullptr;
if( !model_env_local.status )
model_env->status = false;
}
}
@ -1757,7 +1637,7 @@ bool Model::db_query(const std::string & raw_sql)
}
bool Model::db_query(const pt::Stream & raw_sql)
bool Model::db_query(const pt::TextStream & raw_sql)
{
bool status = false;
@ -1989,7 +1869,7 @@ void Model::field_member(
}
/*
bool Model::convert_to_bool(char v)
{
return v != 0;
@ -2077,36 +1957,40 @@ bool Model::convert_to_bool(unsigned long long v)
bool Model::convert_to_bool(float v)
{
return v != 0.0F;
return v != 0;
}
bool Model::convert_to_bool(double v)
{
return v != 0.0;
return v != 0;
}
bool Model::convert_to_bool(long double v)
{
return v != 0.0L;
return v != 0;
}
bool Model::convert_to_bool(const pt::Date & date)
{
// may return true if the date is not the Unix epoch?
return false;
}
bool Model::convert_to_bool(const pt::Stream & val)
bool Model::convert_to_bool(const pt::TextStream & val)
{
return !val.empty();
return false;
}
bool Model::convert_to_bool(const pt::WTextStream & val)
{
return false;
}
bool Model::convert_to_bool(const pt::Space & space)
{
return space.to_bool();
return false;
}
*/

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2018-2024, Tomasz Sowa
* Copyright (c) 2018-2021, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -32,8 +32,8 @@
*
*/
#ifndef headerfile_morm_src_model
#define headerfile_morm_src_model
#ifndef headerfile_morm_model
#define headerfile_morm_model
#include <string>
#include <list>
@ -48,10 +48,11 @@
#include "flatexpression.h"
#include "modelenv.h"
#include "ft.h"
#include "wrapper.h"
#include "modelcontainerwrapper.h"
#include "spacewrapper.h"
#ifdef MORM_HAS_EZC_LIBRARY
#include "funinfo.h"
#include "env.h"
#endif
@ -82,14 +83,14 @@
#ifdef MORM_HAS_EZC_LIBRARY
#define MORM_MODEL_MEMBER_FIELD_EZC(ClassName) \
template<typename FunInfoStreamType> \
void field(const wchar_t * field_name, void (ClassName::*method)(Ezc::FunInfo<FunInfoStreamType> &), const morm::FT & field_type = morm::FT::default_type) \
void field(const wchar_t * field_name, void (ClassName::*method)(Ezc::Env<FunInfoStreamType> &), const morm::FT & field_type = morm::FT::default_type) \
{ \
field(field_name, field_name, method, field_type); \
} \
template<typename FunInfoStreamType> \
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) \
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) \
{ \
typedef void (Model::*ModelMember)(Ezc::FunInfo<FunInfoStreamType> &); \
typedef void (Model::*ModelMember)(Ezc::Env<FunInfoStreamType> &); \
ModelMember model_member = static_cast<ModelMember>(method); \
field_member_ezc(db_field_name, flat_field_name, model_member, field_type); \
} \
@ -112,16 +113,6 @@
typedef bool (Model::*ModelMember)() const; \
ModelMember model_member = static_cast<ModelMember>(method); \
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
@ -153,11 +144,8 @@ public:
virtual void set_save_mode(SaveMode 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 bool get_has_primary_key_set() const;
virtual bool get_has_primary_key_set();
virtual void mark_to_delete();
virtual void mark_to_remove();
@ -173,17 +161,13 @@ public:
void set_connector(ModelConnector * connector);
ModelConnector * get_connector();
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(pt::WTextStream & 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::string & str, bool with_schema_name = true, ModelData * model_data = nullptr, bool clear_string = true);
virtual void to_text(pt::Stream & stream, ModelData * model_data, Export exp = Export::default_type);
virtual void to_text(pt::Stream & stream, ModelData & model_data, Export exp = Export::default_type);
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(pt::TextStream & stream, ModelData * model_data, bool clear_stream = true, bool dump_mode = false);
virtual void to_text(pt::TextStream & stream, ModelData & model_data, bool clear_stream = true, bool dump_mode = false);
virtual void to_text(pt::TextStream & stream, bool clear_stream = 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);
@ -192,17 +176,17 @@ public:
virtual std::string to_text();
virtual std::string to_string();
virtual void generate_insert_query(pt::Stream & stream, ModelData * model_data = nullptr);
virtual void generate_insert_query(pt::TextStream & 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(bool insert_whole_tree = true);
virtual void generate_update_query(pt::Stream & stream, ModelData * model_data = nullptr);
virtual void generate_update_query(pt::TextStream & 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(bool update_whole_tree = true);
virtual void generate_remove_query(pt::Stream & stream, ModelData * model_data = nullptr);
virtual void generate_remove_query(pt::TextStream & 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(bool remove_whole_tree = true);
@ -212,7 +196,7 @@ public:
virtual bool save(bool save_whole_tree = true);
virtual void generate_select_columns(pt::Stream & stream);
virtual void generate_select_columns(pt::TextStream & stream);
// set object to default values
virtual void clear();
@ -260,7 +244,6 @@ public:
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, ModelData * model_data, pt::Stream & stream, bool clear_stream = true);
@ -270,13 +253,8 @@ public:
#ifdef MORM_HAS_EZC_LIBRARY
template<typename FunInfoStreamType>
bool get_raw_value(const wchar_t * db_field_name, const wchar_t * flat_field_name, ModelData * model_data,
Ezc::FunInfo<FunInfoStreamType> & fun_info, pt::Stream & stream, bool clear_stream = true)
Ezc::Env<FunInfoStreamType> & env)
{
if( clear_stream )
{
stream.clear();
}
ModelEnv model_env_local;
model_env = &model_env_local;
@ -285,15 +263,15 @@ public:
model_env->db_field_name = db_field_name;
model_env->flat_field_name = flat_field_name;
model_env->model_data = model_data;
model_env->stream = &stream;
model_env->ezc_fun_info = &fun_info;
model_env->ezc_fun_info_typeinfo = &typeid(fun_info);
model_env->ezc_fun_info = &env;
model_env->ezc_fun_info_typeinfo = &typeid(env);
model_env->ezc_var_space_local = &env.res.space_local;
model_env->model = this;
try
{
fields();
fun_info.res = model_env->ezc_fun_result;
//fun_info.res = model_env->ezc_fun_result;
}
catch(...)
{
@ -301,6 +279,38 @@ public:
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;
return model_env_local.was_field_found;
}
@ -348,18 +358,16 @@ protected:
virtual ModelData * get_model_data();
virtual void insert_tree(bool insert_whole_tree);
virtual void update_tree(bool update_whole_tree);
virtual void remove_tree(bool remove_whole_tree);
virtual void save_tree(bool save_whole_tree);
virtual bool insert_tree(bool insert_whole_tree);
virtual bool update_tree(bool update_whole_tree);
virtual bool remove_tree(bool remove_whole_tree);
virtual bool save_tree(bool save_whole_tree);
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 std::string & raw_sql);
virtual bool db_query(const pt::Stream & raw_sql);
virtual bool db_query(const pt::TextStream & raw_sql);
virtual bool db_query(const char ** raw_sql, size_t len);
@ -760,7 +768,7 @@ protected:
if( clearer )
{
clearer->clear_value(field_value, field_type);
clearer->clear_value(field_value);
}
}
@ -773,14 +781,10 @@ protected:
{
model_env->was_field_found = true;
if( model_env->stream )
if( model_env->ezc_var_space_local )
{
(*model_env->stream) << field_value;
model_env->ezc_var_space_local->set(field_value);
}
#ifdef MORM_HAS_EZC_LIBRARY
model_env->ezc_fun_result = convert_to_bool(field_value);
#endif
}
}
@ -837,13 +841,18 @@ protected:
{
if( model_connector && model_env )
{
if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_GET_MODEL_WRAPPER )
if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_PUT_FIELD_RAW_VALUE_TO_STREAM )
{
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->wrapper.date )
(is_empty_field(model_env->flat_field_name) || is_the_same_field(flat_field_name, model_env->flat_field_name)) )
{
model_env->wrapper.date = &field_value;
model_env->was_field_found = true;
// !! 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
@ -858,13 +867,14 @@ protected:
{
if( model_connector && model_env )
{
if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_GET_MODEL_WRAPPER )
if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_PUT_FIELD_RAW_VALUE_TO_STREAM )
{
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->wrapper.space_wrapper )
!model_env->space_wrapper )
{
model_env->wrapper.space_wrapper = new SpaceWrapper(&field_value);
model_env->was_field_found = true;
model_env->space_wrapper = new SpaceWrapper(&field_value);
}
}
else
@ -916,7 +926,7 @@ protected:
#ifdef MORM_HAS_EZC_LIBRARY
template<typename FunInfoStreamType>
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)
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)
{
if( model_connector && model_env && model_env->ezc_fun_info && model_env->ezc_fun_info_typeinfo && model_env->model )
{
@ -939,18 +949,18 @@ protected:
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 (Model::*method)(Ezc::FunInfo<FunInfoStreamType> &), const FT & field_type)
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::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)) &&
(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;
if( typeid(Ezc::FunInfo<FunInfoStreamType>) == *model_env->ezc_fun_info_typeinfo )
if( typeid(Ezc::Env<FunInfoStreamType>) == *model_env->ezc_fun_info_typeinfo )
{
Ezc::FunInfo<FunInfoStreamType> * ezc_fun_info = reinterpret_cast<Ezc::FunInfo<FunInfoStreamType>*>(model_env->ezc_fun_info);
Ezc::Env<FunInfoStreamType> * ezc_fun_info = reinterpret_cast<Ezc::Env<FunInfoStreamType>*>(model_env->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
{
@ -985,7 +995,12 @@ protected:
(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->ezc_fun_result = (model_env->model->*method)();
bool res = (model_env->model->*method)();
if( model_env->ezc_var_space_local )
{
model_env->ezc_var_space_local->set(res);
}
}
}
}
@ -1012,34 +1027,13 @@ protected:
(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->ezc_fun_result = (model_env->model->*method)();
}
}
}
}
bool res = (model_env->model->*method)();
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)
if( model_env->ezc_var_space_local )
{
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;
model_env->ezc_var_space_local->set(res);
}
}
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);
}
}
}
}
@ -1056,7 +1050,7 @@ protected:
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_db_sql(const wchar_t * db_field_name, Model & field_model, const FT & field_type);
void field_model_clear_values(Model & field_model, const FT & field_type);
void field_model_clear_values(Model & field_model);
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);
@ -1151,8 +1145,6 @@ protected:
template<typename ModelContainerType>
void field_list_iterate_through_childs(ModelContainerType & child_model, const FT & field_type)
{
if( model_env->status )
{
ModelEnv model_env_local;
model_env_local.copy_global_objects(*model_env);
@ -1165,12 +1157,8 @@ protected:
field_model_iterate_through_childs(child_model, field_type);
if( !model_env_local.status )
model_env->status = false;
child_model.model_env = nullptr;
}
}
template<typename ModelContainer, typename ModelContainerType, typename IsContainerByValueRenameMe>
@ -1192,52 +1180,13 @@ protected:
template<typename ModelContainer, typename ModelContainerType, typename IsContainerByValueRenameMe>
void field_list_clearing_values(ModelContainer & field_container, ModelContainerType * model_container_type, IsContainerByValueRenameMe * foo, const FT & field_type)
void field_list_clearing_values(ModelContainer & field_container, ModelContainerType * model_container_type, IsContainerByValueRenameMe * foo)
{
Clearer * clearer = model_connector->get_clearer();
if( clearer )
{
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);
clearer->clear_container(field_container, model_container_type, foo);
}
}
@ -1247,15 +1196,16 @@ protected:
{
ContainerItemType * item_type_null_pointer = nullptr;
if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_GET_MODEL_WRAPPER )
if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_PUT_FIELD_RAW_VALUE_TO_STREAM )
{
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)) &&
(is_empty_field(model_env->flat_field_name) || is_the_same_field(flat_field_name, model_env->flat_field_name)) &&
!model_env->wrapper.model_container_wrapper )
!model_env->model_container_wrapper )
{
model_env->wrapper.model_container_wrapper = new ModelWrapperVector(&field_value);
model_env->was_field_found = true;
model_env->model_container_wrapper = new ModelWrapperVector(&field_value);
}
}
}
@ -1272,15 +1222,16 @@ protected:
{
ContainerItemType * item_type_null_pointer = nullptr;
if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_GET_MODEL_WRAPPER )
if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_PUT_FIELD_RAW_VALUE_TO_STREAM )
{
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)) &&
(is_empty_field(model_env->flat_field_name) || is_the_same_field(flat_field_name, model_env->flat_field_name)) &&
!model_env->wrapper.model_container_wrapper )
!model_env->model_container_wrapper )
{
model_env->wrapper.model_container_wrapper = new ModelWrapperList(&field_value);
model_env->was_field_found = true;
model_env->model_container_wrapper = new ModelWrapperList(&field_value);
}
}
}
@ -1297,15 +1248,16 @@ protected:
{
ContainerItemType * item_type_null_pointer = nullptr;
if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_GET_MODEL_WRAPPER )
if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_PUT_FIELD_RAW_VALUE_TO_STREAM )
{
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)) &&
(is_empty_field(model_env->flat_field_name) || is_the_same_field(flat_field_name, model_env->flat_field_name)) &&
!model_env->wrapper.model_container_wrapper )
!model_env->model_container_wrapper )
{
model_env->wrapper.model_container_wrapper = new ModelWrapperVectorPointer(&field_value);
model_env->was_field_found = true;
model_env->model_container_wrapper = new ModelWrapperVectorPointer(&field_value);
}
}
}
@ -1322,15 +1274,16 @@ protected:
{
ContainerItemType * item_type_null_pointer = nullptr;
if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_GET_MODEL_WRAPPER )
if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_PUT_FIELD_RAW_VALUE_TO_STREAM )
{
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)) &&
(is_empty_field(model_env->flat_field_name) || is_the_same_field(flat_field_name, model_env->flat_field_name)) &&
!model_env->wrapper.model_container_wrapper )
!model_env->model_container_wrapper )
{
model_env->wrapper.model_container_wrapper = new ModelWrapperListPointer(&field_value);
model_env->was_field_found = true;
model_env->model_container_wrapper = new ModelWrapperListPointer(&field_value);
}
}
}
@ -1424,12 +1377,7 @@ protected:
if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_CLEARING_VALUE )
{
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);
field_list_clearing_values(field_container, model_container_type, foo);
}
}
}
@ -1477,18 +1425,13 @@ protected:
if( db_expression )
{
std::wstring table_field_name;
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);
if( table_field_name_str.size() < 256 )
{
wchar_t alias_name[256];
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);
}
}
// CHECK ME not tested yet after changing to db_expression->table_with_index_and_field_to_stream()
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);
column_index = model_env->cursor_helper->query_result->get_column_index(table_field_name.c_str());
}
}
else
@ -1598,7 +1541,6 @@ protected:
virtual bool is_empty_field(const wchar_t * value);
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_fields_to_log(pt::Log & log, const wchar_t * db_field_name, const wchar_t * flat_field_name);
@ -1626,34 +1568,34 @@ protected:
}
// those methods are used when converting fields to bool for Ezc library
virtual bool convert_to_bool(char v);
virtual bool convert_to_bool(unsigned char v);
virtual bool convert_to_bool(wchar_t v);
virtual bool convert_to_bool(const std::wstring & 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 char * str);
virtual bool convert_to_bool(bool v);
virtual bool convert_to_bool(short v);
virtual bool convert_to_bool(unsigned short v);
virtual bool convert_to_bool(int v);
virtual bool convert_to_bool(unsigned int v);
virtual bool convert_to_bool(long v);
virtual bool convert_to_bool(unsigned long v);
virtual bool convert_to_bool(long long v);
virtual bool convert_to_bool(unsigned long long v);
virtual bool convert_to_bool(float v);
virtual bool convert_to_bool(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::Stream & val);
virtual bool convert_to_bool(const pt::Space & space);
// virtual bool convert_to_bool(char v);
// virtual bool convert_to_bool(unsigned char v);
// virtual bool convert_to_bool(wchar_t v);
// virtual bool convert_to_bool(const std::wstring & 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 char * str);
// virtual bool convert_to_bool(bool v);
// virtual bool convert_to_bool(short v);
// virtual bool convert_to_bool(unsigned short v);
// virtual bool convert_to_bool(int v);
// virtual bool convert_to_bool(unsigned int v);
// virtual bool convert_to_bool(long v);
// virtual bool convert_to_bool(unsigned long v);
// virtual bool convert_to_bool(long long v);
// virtual bool convert_to_bool(unsigned long long v);
// virtual bool convert_to_bool(float v);
// virtual bool convert_to_bool(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::TextStream & val);
// virtual bool convert_to_bool(const pt::WTextStream & val);
// virtual bool convert_to_bool(const pt::Space & space);
template<typename ModelClass> friend class Finder;
template<typename ModelClass> friend class Cursor;
friend class BaseExpression;
friend class DbExpression;
friend class DbConnector;
friend class FlatConnector;

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2018-2024, Tomasz Sowa
* Copyright (c) 2018-2019, Tomasz Sowa
* All rights reserved.
*
* 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::Stream & stream)
void ModelConnector::set_stream(pt::TextStream & stream)
{
deallocate_stream();
this->out_stream = &stream;
}
pt::Stream * ModelConnector::get_stream()
pt::TextStream * ModelConnector::get_stream()
{
allocate_default_stream_if_needed();
return out_stream;

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2018-2024, Tomasz Sowa
* Copyright (c) 2018-2019, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -32,8 +32,8 @@
*
*/
#ifndef headerfile_morm_src_modelconnector
#define headerfile_morm_src_modelconnector
#ifndef headerfile_morm_modelconnector
#define headerfile_morm_modelconnector
#include "clearer.h"
#include "dbconnector.h"
@ -64,8 +64,8 @@ public:
virtual pt::Log * get_logger();
virtual void set_stream(pt::Stream & stream);
virtual pt::Stream * get_stream();
virtual void set_stream(pt::TextStream & stream);
virtual pt::TextStream * get_stream();
virtual void set_flat_connector(FlatConnector & flat_connector);
virtual FlatConnector * get_flat_connector();
@ -85,7 +85,7 @@ protected:
FlatConnector * flat_connector;
DbConnector * db_connector;
pt::Stream * out_stream;
pt::TextStream * out_stream; // IMPROVE ME give here an interface to the base stream (implement him)
bool out_stream_allocated;
Clearer * clearer;

View File

@ -32,8 +32,8 @@
*
*/
#ifndef headerfile_morm_src_modelcontainerwrapper
#define headerfile_morm_src_modelcontainerwrapper
#ifndef headerfile_morm_modelcontainerwrapper
#define headerfile_morm_modelcontainerwrapper
#include <vector>
#include <list>
@ -55,11 +55,16 @@ public:
return nullptr;
}
virtual bool is_container_empty()
virtual bool is_container_empty() const
{
return true;
}
virtual size_t size() const
{
return 0;
}
virtual void increment_iterator()
{
}
@ -69,9 +74,6 @@ public:
return false;
}
virtual void set_iterator_at_first_model()
{
}
};
@ -87,11 +89,16 @@ public:
iterator = container->end();
}
bool is_container_empty()
bool is_container_empty() const
{
return container->empty();
}
size_t size() const
{
return container->size();
}
void increment_iterator()
{
if( iterator == container->end() )
@ -109,10 +116,6 @@ public:
return iterator != container->end();
}
void set_iterator_at_first_model()
{
iterator = container->begin();
}
protected:

View File

@ -32,8 +32,8 @@
*
*/
#ifndef headerfile_morm_src_modeldata
#define headerfile_morm_src_modeldata
#ifndef headerfile_morm_modeldata
#define headerfile_morm_modeldata

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2019-2024, Tomasz Sowa
* Copyright (c) 2019-2021, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -32,18 +32,20 @@
*
*/
#ifndef headerfile_morm_src_modelenv
#define headerfile_morm_src_modelenv
#ifndef headerfile_morm_modelenv
#define headerfile_morm_modelenv
#include "modeldata.h"
#include "cursorhelper.h"
#include "finderhelper.h"
#include "fieldvaluehelper.h"
#include "morm_types.h"
#include "wrapper.h"
#include "select.h"
#ifdef MORM_HAS_EZC_LIBRARY
#include "env.h"
#endif
namespace morm
{
@ -93,26 +95,19 @@ public:
Model * child_model;
pt::Stream * 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
void * ezc_fun_info;
bool ezc_fun_result;
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
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()
{
clear();
@ -145,20 +140,14 @@ public:
child_model = e.child_model;
stream = e.stream;
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
ezc_fun_info = e.ezc_fun_info;
ezc_fun_result = e.ezc_fun_result;
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
// schema_name and table_name don't have to be copied
@ -204,20 +193,14 @@ public:
child_model = nullptr;
stream = nullptr;
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
ezc_fun_info = nullptr;
ezc_fun_result = false;
ezc_fun_info_typeinfo = nullptr;
ezc_var_space_local = nullptr;
ezc_var_date = nullptr;
model_container_wrapper = nullptr;
space_wrapper = nullptr;
#endif
}
@ -234,6 +217,7 @@ public:
}
}
};
}

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2018-2023, Tomasz Sowa
* Copyright (c) 2018-2019, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -32,28 +32,23 @@
*
*/
#ifndef headerfile_morm_src_morm
#define headerfile_morm_src_morm
#ifndef headerfile_morm_morm
#define headerfile_morm_morm
#include "version.h"
#include "morm_types.h"
#include "model.h"
#include "finder.h"
#include "jsonexpression.h"
#include "postgresqlexpression.h"
#include "xmlexpression.h"
#include "jsonconnector.h"
#include "postgresqlconnector.h"
#include "xmlconnector.h"
#include "modelconnector.h"
#include "clearer.h"
#include "transaction.h"
namespace morm

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2018-2023, Tomasz Sowa
* Copyright (c) 2018-2021, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -32,8 +32,8 @@
*
*/
#ifndef headerfile_morm_src_morm_types
#define headerfile_morm_src_morm_types
#ifndef headerfile_morm_morm_types
#define headerfile_morm_morm_types
#define MORM_MODEL_WORK_MODE_NONE 0
#define MORM_MODEL_WORK_MODE_GENERATING_DB_SQL 1
@ -46,9 +46,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_GET_FIELD_MODEL 10
#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
#define MORM_MODEL_WORK_MODE_PUT_FIELD_RAW_VALUE_TO_STREAM 11
// submodes used in some cases
@ -64,8 +63,7 @@
#define MORM_WORK_MODE_MODEL_FIELDS 1
#define MORM_WORK_MODE_MODEL_VALUES 2
#define MORM_WORK_MODE_MODEL_FIELDS_VALUES 3
#define MORM_WORK_MODE_MODEL_FIELDS_VALUES_FIELDS 4
#define MORM_WORK_MODE_MODEL_SAVE_FIELDS 5
#define MORM_WORK_MODE_MODEL_SAVE_FIELDS 4
@ -77,12 +75,10 @@
#define MORM_OUTPUT_TYPE_DB_UPDATE 3
// 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_INSERT_PRIMARY_KEY 5
#define MORM_OUTPUT_TYPE_DB_UPDATE_PRIMARY_KEY 6
#define MORM_OUTPUT_TYPE_DB_UPDATE_PRIMARY_KEY 5
//#define MORM_OUTPUT_TYPE_WHERE_CUSTOM 7
@ -99,12 +95,7 @@
#define MORM_OUTPUT_TYPE_WHERE_GE 24
#define MORM_OUTPUT_TYPE_WHERE_IN 25
#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_OR 2

0
src/outstream.h Normal file
View File

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2018-2024, Tomasz Sowa
* Copyright (c) 2018-2021, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -34,14 +34,16 @@
// for sleep()
#include <unistd.h>
#include "postgresqlconnector.h"
#include "utf8/utf8.h"
#include "postgresqlexpression.h"
#include "convert/strtoint.h"
namespace morm
{
PostgreSQLConnector::PostgreSQLConnector()
{
pg_conn = nullptr;
@ -64,6 +66,7 @@ void PostgreSQLConnector::close()
}
void PostgreSQLConnector::allocate_default_expression()
{
deallocate_expression();
@ -72,6 +75,9 @@ void PostgreSQLConnector::allocate_default_expression()
}
QueryResult * PostgreSQLConnector::create_query_result()
{
return new PostgreSQLQueryResult();
@ -91,16 +97,14 @@ bool PostgreSQLConnector::do_query(const char * query_str, PostgreSQLQueryResult
psql_result->psql_result = PQexec(pg_conn, query_str);
/*
* 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( !psql_result->psql_result )
{
psql_result->clear();
assert_connection_is_working();
if( PQstatus(pg_conn) != CONNECTION_OK )
{
assert_connection();
psql_result->psql_result = PQexec(pg_conn, query_str);
}
}
if( psql_result->psql_result )
{
@ -110,16 +114,20 @@ bool PostgreSQLConnector::do_query(const char * query_str, PostgreSQLQueryResult
}
if( !psql_result->psql_result || psql_result->psql_status == PGRES_FATAL_ERROR )
{
if( log )
{
const char * err_msg = PQerrorMessage(pg_conn);
(*log) << pt::Log::log1 << "Morm: Problem with this query: \"" << query_str << '\"' << pt::Log::logend;
if( err_msg )
{
log->put_multiline("Morm: ", err_msg);
pt::utf8_to_wide(err_msg, psql_result->error_msg);
}
if( log )
{
(*log) << pt::Log::log1 << "Morm: Problem with this query: \"" << query_str << '\"' << pt::Log::logend;
if( err_msg )
(*log) << pt::Log::log1 << "Morm: " << err_msg << pt::Log::logend;
}
}
else
@ -172,13 +180,8 @@ const char * PostgreSQLConnector::query_last_sequence(const wchar_t * sequence_t
{
if( pg_conn && log )
{
const char * err_msg = PQerrorMessage(pg_conn);
(*log) << pt::Log::log1 << "Morm: error (currval) for table: " << sequence_table_name << pt::Log::logend;
if( err_msg )
{
log->put_multiline("Morm: ", err_msg);
}
(*log) << pt::Log::log1 << "Morm: error (currval) for table: " << sequence_table_name << ", "
<< PQerrorMessage(pg_conn) << pt::Log::logend;
}
}
}
@ -188,7 +191,7 @@ const char * PostgreSQLConnector::query_last_sequence(const wchar_t * sequence_t
bool PostgreSQLConnector::query(const pt::Stream & stream, QueryResult & query_result)
bool PostgreSQLConnector::query(const pt::TextStream & stream, QueryResult & query_result)
{
stream.to_str(query_str);
return query(query_str.c_str(), query_result);
@ -201,14 +204,14 @@ bool PostgreSQLConnector::query(const std::string & query_str, QueryResult & que
}
bool PostgreSQLConnector::query_command(const char * query_str, QueryResult & query_result, ExecStatusType expected_status)
bool PostgreSQLConnector::query_select(const char * query_str, QueryResult & query_result)
{
PostgreSQLQueryResult * psql_result = dynamic_cast<PostgreSQLQueryResult*>(&query_result);
bool result = false;
if( psql_result )
{
result = (do_query(query_str, psql_result) && psql_result->psql_status == expected_status);
result = (do_query(query_str, psql_result) && psql_result->psql_status == PGRES_TUPLES_OK);
psql_result->status = result;
}
@ -216,97 +219,181 @@ bool PostgreSQLConnector::query_command(const char * query_str, QueryResult & qu
}
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)
{
return query_command(query_str, query_result, PGRES_COMMAND_OK);
PostgreSQLQueryResult * psql_result = dynamic_cast<PostgreSQLQueryResult*>(&query_result);
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)
{
return query_command(query_str, query_result, PGRES_COMMAND_OK);
PostgreSQLQueryResult * psql_result = dynamic_cast<PostgreSQLQueryResult*>(&query_result);
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)
{
return query_command(query_str, query_result, PGRES_COMMAND_OK);
}
PostgreSQLQueryResult * psql_result = dynamic_cast<PostgreSQLQueryResult*>(&query_result);
bool result = false;
bool PostgreSQLConnector::query_declare_cursor(const char * query_str, QueryResult & query_result)
{
return query_command(query_str, query_result, PGRES_COMMAND_OK);
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_select(const pt::Stream & stream, QueryResult & query_result)
bool PostgreSQLConnector::query_select(const pt::TextStream & stream, QueryResult & query_result)
{
stream.to_str(query_str);
return query_select(query_str.c_str(), query_result);
}
bool PostgreSQLConnector::query_update(const pt::Stream & stream, QueryResult & query_result)
bool PostgreSQLConnector::query_update(const pt::TextStream & stream, QueryResult & query_result)
{
stream.to_str(query_str);
return query_update(query_str.c_str(), query_result);
}
bool PostgreSQLConnector::query_insert(const pt::Stream & stream, QueryResult & query_result)
bool PostgreSQLConnector::query_insert(const pt::TextStream & stream, QueryResult & query_result)
{
stream.to_str(query_str);
return query_insert(query_str.c_str(), query_result);
}
bool PostgreSQLConnector::query_remove(const pt::Stream & stream, QueryResult & query_result)
bool PostgreSQLConnector::query_remove(const pt::TextStream & stream, QueryResult & query_result)
{
stream.to_str(query_str);
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)
{
db_conn_string.clear();
db_host.clear();
db_hostaddr.clear();
db_port.clear();
db_database = database_name;
db_user = user;
db_pass = pass;
@ -326,17 +413,6 @@ 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()
@ -351,13 +427,6 @@ void PostgreSQLConnector::connect()
if( db_expression )
{
stream.clear();
if( !db_conn_string.empty() )
{
stream << db_conn_string;
}
else
{
stream << "dbname='";
db_expression->esc(db_database, stream);
@ -368,28 +437,6 @@ void PostgreSQLConnector::connect()
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;
stream.to_str(str);
pg_conn = PQconnectdb(str.c_str());
@ -400,17 +447,9 @@ void PostgreSQLConnector::connect()
// 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()
{
@ -422,18 +461,8 @@ void PostgreSQLConnector::log_connection_socket()
}
}
bool PostgreSQLConnector::wait_for_connection(size_t attempts_max, size_t attempt_delay)
void PostgreSQLConnector::wait_for_connection()
{
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( log )
@ -441,39 +470,24 @@ bool PostgreSQLConnector::wait_for_connection(size_t attempts_max, size_t attemp
(*log) << pt::Log::log3 << "Morm: waiting for the db to be ready...." << pt::Log::logend << pt::Log::logsave;
}
while( !attempts_exceeded && !assert_connection_is_working(false) )
while( !assert_connection(false) )
{
if( attempts_max != 0 )
{
attempts += 1;
attempts_exceeded = (attempts >= attempts_max);
sleep(5);
}
if( !attempts_exceeded )
{
sleep(attempt_delay);
}
}
}
if( attempts_exceeded )
{
log_no_connection(attempts);
}
else
{
log_connection_socket();
}
return !attempts_exceeded;
}
// IMPROVE ME what about the exception now?
bool PostgreSQLConnector::assert_connection_is_working(bool put_log)
bool PostgreSQLConnector::assert_connection(bool put_log)
{
bool was_connection = true;
if( !pg_conn )
{
was_connection = false;
@ -545,31 +559,21 @@ 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' )
{
log_unsupported_bin_format();
return 0;
}
else
{
DbConnector::unescape_bin_char(str + 2, field_value);
return unescape_hex_char(str + 2, field_value, field_type);
}
}
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)
{
@ -579,12 +583,12 @@ void PostgreSQLConnector::unescape_bin_string(const char * str, std::string & ou
}
else
{
DbConnector::unescape_bin_string(str + 2, out);
unescape_hex_string(str + 2, out);
}
}
void PostgreSQLConnector::unescape_bin_string(const char * str, std::wstring & out)
void PostgreSQLConnector::unescape_bin_string(const char * str, std::wstring & out, const FT & field_type)
{
if( str[0]!='\\' || str[1]!='x' )
{
@ -592,7 +596,7 @@ void PostgreSQLConnector::unescape_bin_string(const char * str, std::wstring & o
}
else
{
DbConnector::unescape_bin_string(str + 2, out);
unescape_hex_string(str + 2, out, field_type);
}
}

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2018-2024, Tomasz Sowa
* Copyright (c) 2018-2021, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -32,8 +32,8 @@
*
*/
#ifndef headerfile_morm_src_postgresqlconnector
#define headerfile_morm_src_postgresqlconnector
#ifndef headerfile_morm_postgresqlconnector
#define headerfile_morm_postgresqlconnector
#include <libpq-fe.h>
#include <string>
@ -55,73 +55,30 @@ public:
virtual ~PostgreSQLConnector();
bool query(const pt::Stream & stream, QueryResult & query_result) override;
bool query(const char * query_str, QueryResult & query_result) override;
bool query(const std::string & query_str, QueryResult & query_result) override;
bool query(const pt::TextStream & stream, QueryResult & query_result);
bool query(const char * query_str, QueryResult & query_result);
bool query(const std::string & 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) override;
bool query_insert(const char * query_str, QueryResult & query_result) override;
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 char * query_str, QueryResult & query_result);
bool query_update(const char * query_str, QueryResult & query_result);
bool query_insert(const char * query_str, QueryResult & query_result);
bool query_remove(const char * query_str, QueryResult & query_result);
bool query_select(const pt::Stream & stream, QueryResult & query_result) override;
bool query_update(const pt::Stream & stream, QueryResult & query_result) override;
bool query_insert(const pt::Stream & stream, QueryResult & query_result) override;
bool query_remove(const pt::Stream & stream, QueryResult & query_result) override;
bool query_declare_cursor(const pt::Stream & stream, QueryResult & query_result) override;
bool query_select(const pt::TextStream & stream, QueryResult & query_result);
bool query_update(const pt::TextStream & stream, QueryResult & query_result);
bool query_insert(const pt::TextStream & stream, QueryResult & query_result);
bool query_remove(const pt::TextStream & stream, QueryResult & query_result);
/*
* 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);
/*
* 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 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();
@ -131,36 +88,21 @@ protected:
pt::TextStream stream;
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_user;
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 query_command(const char * query_str, QueryResult & query_result, ExecStatusType expected_status);
virtual void allocate_default_expression() override;
virtual void allocate_default_expression();
virtual void overwrite(pt::TextStream & stream);
virtual void overwrite(pt::WTextStream & stream);
virtual const char * query_last_sequence(const wchar_t * sequence_table_name) override;
virtual QueryResult * create_query_result() override;
virtual const char * query_last_sequence(const wchar_t * sequence_table_name);
virtual QueryResult * create_query_result();
void log_unsupported_bin_format();
void unescape_bin_char(const char * str, char & field_value) override;
void unescape_bin_char(const char * str, char32_t & field_value) override;
void unescape_bin_string(const char * str, std::string & out) override;
void unescape_bin_string(const char * str, std::wstring & out) override;
size_t unescape_bin_char(const char * str, wchar_t & field_value, const FT & field_type);
void unescape_bin_string(const char * str, std::string & out);
void unescape_bin_string(const char * str, std::wstring & out, const FT & field_type);
};

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2018-2024, Tomasz Sowa
* Copyright (c) 2018-2021, Tomasz Sowa
* All rights reserved.
*
* 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, ModelEnv * model_env)
void PostgreSQLExpression::before_field_value_string(const FT & field_type)
{
if( field_type.is_binary() )
{
@ -52,76 +52,49 @@ void PostgreSQLExpression::before_field_value_string(const FT & field_type, Mode
(*out_stream) << "'";
}
else
if( field_type.is_numeric() )
{
(*out_stream) << "'";
}
else
{
(*out_stream) << "E'";
if( model_env && model_env->add_prefix_percent )
(*out_stream) << '%';
}
}
void PostgreSQLExpression::after_field_value_string(const FT & field_type, ModelEnv * model_env)
void PostgreSQLExpression::after_field_value_string(const FT & field_type)
{
if( model_env && model_env->add_postfix_percent )
(*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( model_env && model_env->use_escaping_for_like )
if( field_type.is_hexadecimal() || field_type.is_binary() )
{
if( val == '%' )
{
stream << "\\\\%"; // gives: "\\%" (we are using a string form with E so we need to double backslashes here)
return true;
char_to_hex(val, stream);
}
else
if( val == '_' )
{
stream << "\\\\_"; // gives: "\\_"
return true;
}
else
if( val == '\\' )
switch( val )
{
stream << "\\\\\\\\"; // gives: "\\\\"
return true;
}
}
if( val == '\\' )
case '\\': stream << "\\\\"; break;
case '\'': stream << "\\\'"; break; // don't use "''" because we use the method for PQconnectdb too
default:
if( val != 0 )
{
stream << "\\\\";
return true;
stream << val;
}
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;
}
DbExpression & PostgreSQLExpression::page(pt::Stream & stream, size_t page_number, size_t page_size)
void PostgreSQLExpression::esc(const pt::Date & date, pt::TextStream & stream, const FT & field_type)
{
stream << " OFFSET " << (page_number*page_size) << " LIMIT " << page_size << " ";
stream << date << "+00";
}
DbExpression & PostgreSQLExpression::page(pt::TextStream & stream, size_t page_number, size_t page_size)
{
stream << " offset " << page_number << " limit " << page_size << " ";
return *this;
}

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2018-2024, Tomasz Sowa
* Copyright (c) 2018-2021, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -32,8 +32,8 @@
*
*/
#ifndef headerfile_morm_src_postgresqlexpression
#define headerfile_morm_src_postgresqlexpression
#ifndef headerfile_morm_postgresqlexpression
#define headerfile_morm_postgresqlexpression
#include "dbexpression.h"
@ -45,7 +45,10 @@ class PostgreSQLExpression : public DbExpression
{
public:
DbExpression & page(pt::Stream & stream, size_t page_number, size_t page_size) override;
void esc(char val, pt::TextStream & stream, const FT & field_type);
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:
@ -55,10 +58,9 @@ protected:
private:
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;
void before_field_value_string(const FT & field_type);
void after_field_value_string(const FT & field_type);
bool esc_char(char32_t val, pt::Stream & stream, const FT & field_type, ModelEnv * model_env) override;
};

View File

@ -32,8 +32,8 @@
*
*/
#ifndef headerfile_morm_src_postgresqlqueryresult
#define headerfile_morm_src_postgresqlqueryresult
#ifndef headerfile_morm_postgresqlqueryresult
#define headerfile_morm_postgresqlqueryresult
#include "queryresult.h"
#include <libpq-fe.h>

View File

@ -32,8 +32,8 @@
*
*/
#ifndef headerfile_morm_src_queryresult
#define headerfile_morm_src_queryresult
#ifndef headerfile_morm_queryresult
#define headerfile_morm_queryresult
#include <log/log.h>
#include <string>

View File

@ -1,130 +0,0 @@
/*
* 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

View File

@ -32,8 +32,8 @@
*
*/
#ifndef headerfile_morm_src_spacewrapper
#define headerfile_morm_src_spacewrapper
#ifndef headerfile_morm_spacewrapper
#define headerfile_morm_spacewrapper
#include <vector>
#include <limits>
@ -49,6 +49,11 @@ class SpaceWrapper : public BaseObjectWrapper
{
public:
SpaceWrapper() = delete;
SpaceWrapper(const SpaceWrapper &) = delete;
SpaceWrapper & operator=(const SpaceWrapper &) = delete;
SpaceWrapper(pt::Space * space)
{
this->space = space;
@ -99,6 +104,7 @@ public:
return std::numeric_limits<size_t>::max();
}
protected:
const size_t SPACE_INDICES_TABLE_SIZE = 32;

View File

@ -1,285 +0,0 @@
/*
* 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

View File

@ -1,89 +0,0 @@
/*
* 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

View File

@ -1,44 +0,0 @@
/*
* 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

View File

@ -1,193 +0,0 @@
/*
* 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

View File

@ -1,168 +0,0 @@
/*
* 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);
}
}
}
}

View File

@ -1,80 +0,0 @@
/*
* 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

View File

@ -1,142 +0,0 @@
/*
* 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()
{
}
}

View File

@ -1,76 +0,0 @@
/*
* 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