Compare commits

..

11 Commits

61 changed files with 1394 additions and 5905 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++
endif
ifndef CXXFLAGS
CXXFLAGS = -Wall -pedantic -O2 -std=c++20 -I../src -I../../pikotools/src -I/usr/local/include
endif
ifndef LDFLAGS
LDFLAGS = -L/usr/local/lib
ifndef GLOBAL_WORKING_DIR
GLOBAL_WORKING_DIR := $(shell pwd)/../..
endif
name = mormsample
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
all: $(name)
export CXX
export CXXFLAGS
export LDFLAGS
export GLOBAL_WORKING_DIR
$(name): morm pikotools $(objfiles)
$(CXX) -o $(name) $(CXXFLAGS) $(LDFLAGS) $(objfiles) ../src/morm.a ../../pikotools/src/pikotools.a $(LDFLAGS) -lpq -lpthread
current_path := $(shell pwd)
global_relative_working_dir := $(shell relative_path $(current_path) $(GLOBAL_WORKING_DIR))
morm: FORCE
@cd ../src ; $(MAKE) -e
# IMPROVE ME
# add dependency to pikotools
all: morm $(name)
pikotools: FORCE
@cd ../../pikotools/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
.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,30 +1,17 @@
# DO NOT DELETE
./main.o: ../../pikotools/src/mainoptions/mainoptionsparser.h
./main.o: ../../pikotools/src/space/space.h
./main.o: ../../pikotools/src/textstream/types.h
./main.o: ../../pikotools/src/convert/inttostr.h
./main.o: ../../pikotools/src/utf8/utf8.h
./main.o: ../../pikotools/src/textstream/stream.h
./main.o: ../../pikotools/src/utf8/utf8_templates.h
./main.o: ../../pikotools/src/utf8/utf8_private.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 ../src/modelconnector.h
./main.o: ../src/clearer.h ../src/ft.h ../src/dbconnector.h
./main.o: ../../pikotools/src/log/log.h ../../pikotools/src/log/filelog.h
./main.o: ../src/queryresult.h ../src/flatconnector.h ../src/export.h
./main.o: ../src/dbexpression.h ../src/baseexpression.h ../src/modelenv.h
./main.o: ../src/modeldata.h ../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 ../../pikotools/src/convert/text.h
./main.o: ../src/flatexpression.h ../src/finder.h ../src/cursor.h
./main.o: ../src/jsonexpression.h ../src/postgresqlexpression.h
./main.o: ../src/xmlexpression.h ../src/jsonconnector.h
./main.o: ../src/postgresqlconnector.h ../src/postgresqlqueryresult.h
./main.o: ../src/xmlconnector.h ../src/transaction.h person.h language.h
./main.o: attachment.h type.h 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,380 +1,54 @@
# DO NOT DELETE
./baseexpression.o: baseexpression.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/textstream/types.h
./baseexpression.o: ../../pikotools/src/convert/inttostr.h
./baseexpression.o: ../../pikotools/src/utf8/utf8.h
./baseexpression.o: ../../pikotools/src/textstream/stream.h
./baseexpression.o: ../../pikotools/src/utf8/utf8_templates.h
./baseexpression.o: ../../pikotools/src/utf8/utf8_private.h
./baseexpression.o: ../../pikotools/src/date/date.h
./baseexpression.o: ../../pikotools/src/membuffer/membuffer.h
./baseexpression.o: ../../pikotools/src/textstream/types.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/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: export.h ../../pikotools/src/convert/text.h model.h
./baseexpression.o: modelconnector.h clearer.h dbconnector.h flatconnector.h
./baseexpression.o: 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/textstream/types.h
./clearer.o: ../../pikotools/src/utf8/utf8.h
./clearer.o: ../../pikotools/src/textstream/stream.h
./clearer.o: ../../pikotools/src/utf8/utf8_templates.h
./clearer.o: ../../pikotools/src/utf8/utf8_private.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 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
./clearer.o: ../../pikotools/src/convert/text.h flatexpression.h
./dbconnector.o: ../../pikotools/src/space/spaceparser.h
./dbconnector.o: ../../pikotools/src/space/space.h
./dbconnector.o: ../../pikotools/src/textstream/types.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/utf8/utf8_templates.h
./dbconnector.o: ../../pikotools/src/utf8/utf8_private.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.h
./dbconnector.o: ../../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 export.h
./dbconnector.o: ../../pikotools/src/convert/text.h model.h modelconnector.h
./dbconnector.o: clearer.h flatconnector.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/textstream.h
./dbexpression.o: ../../pikotools/src/textstream/stream.h
./dbexpression.o: ../../pikotools/src/space/space.h
./dbexpression.o: ../../pikotools/src/textstream/types.h
./dbexpression.o: ../../pikotools/src/convert/inttostr.h
./dbexpression.o: ../../pikotools/src/utf8/utf8.h
./dbexpression.o: ../../pikotools/src/textstream/stream.h
./dbexpression.o: ../../pikotools/src/utf8/utf8_templates.h
./dbexpression.o: ../../pikotools/src/utf8/utf8_private.h
./dbexpression.o: ../../pikotools/src/date/date.h
./dbexpression.o: ../../pikotools/src/membuffer/membuffer.h
./dbexpression.o: ../../pikotools/src/textstream/types.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/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: export.h ../../pikotools/src/convert/text.h model.h
./dbexpression.o: modelconnector.h clearer.h dbconnector.h flatconnector.h
./dbexpression.o: flatexpression.h
./flatconnector.o: flatconnector.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/textstream/types.h
./flatconnector.o: ../../pikotools/src/convert/inttostr.h
./flatconnector.o: ../../pikotools/src/utf8/utf8.h
./flatconnector.o: ../../pikotools/src/textstream/stream.h
./flatconnector.o: ../../pikotools/src/utf8/utf8_templates.h
./flatconnector.o: ../../pikotools/src/utf8/utf8_private.h
./flatconnector.o: ../../pikotools/src/date/date.h
./flatconnector.o: ../../pikotools/src/membuffer/membuffer.h
./flatconnector.o: ../../pikotools/src/textstream/types.h export.h
./flatconnector.o: flatexpression.h baseexpression.h morm_types.h modelenv.h
./flatconnector.o: modeldata.h cursorhelper.h queryresult.h
./flatconnector.o: ../../pikotools/src/log/log.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: ../../pikotools/src/convert/text.h model.h
./flatconnector.o: modelconnector.h clearer.h dbconnector.h dbexpression.h
./flatexpression.o: flatexpression.h baseexpression.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/textstream/types.h
./flatexpression.o: ../../pikotools/src/convert/inttostr.h
./flatexpression.o: ../../pikotools/src/utf8/utf8.h
./flatexpression.o: ../../pikotools/src/textstream/stream.h
./flatexpression.o: ../../pikotools/src/utf8/utf8_templates.h
./flatexpression.o: ../../pikotools/src/utf8/utf8_private.h
./flatexpression.o: ../../pikotools/src/date/date.h
./flatexpression.o: ../../pikotools/src/membuffer/membuffer.h
./flatexpression.o: ../../pikotools/src/textstream/types.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/log/filelog.h finderhelper.h
./flatexpression.o: fieldvaluehelper.h wrapper.h spacewrapper.h
./flatexpression.o: baseobjectwrapper.h modelcontainerwrapper.h select.h ft.h
./flatexpression.o: export.h ../../pikotools/src/convert/text.h
./jsonconnector.o: jsonconnector.h flatconnector.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/textstream/types.h
./jsonconnector.o: ../../pikotools/src/convert/inttostr.h
./jsonconnector.o: ../../pikotools/src/utf8/utf8.h
./jsonconnector.o: ../../pikotools/src/textstream/stream.h
./jsonconnector.o: ../../pikotools/src/utf8/utf8_templates.h
./jsonconnector.o: ../../pikotools/src/utf8/utf8_private.h
./jsonconnector.o: ../../pikotools/src/date/date.h
./jsonconnector.o: ../../pikotools/src/membuffer/membuffer.h
./jsonconnector.o: ../../pikotools/src/textstream/types.h export.h
./jsonconnector.o: jsonexpression.h flatexpression.h baseexpression.h
./jsonconnector.o: morm_types.h modelenv.h modeldata.h cursorhelper.h
./jsonconnector.o: queryresult.h ../../pikotools/src/log/log.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
./jsonconnector.o: ../../pikotools/src/convert/text.h
./jsonexpression.o: jsonexpression.h flatexpression.h baseexpression.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/textstream/types.h
./jsonexpression.o: ../../pikotools/src/convert/inttostr.h
./jsonexpression.o: ../../pikotools/src/utf8/utf8.h
./jsonexpression.o: ../../pikotools/src/textstream/stream.h
./jsonexpression.o: ../../pikotools/src/utf8/utf8_templates.h
./jsonexpression.o: ../../pikotools/src/utf8/utf8_private.h
./jsonexpression.o: ../../pikotools/src/date/date.h
./jsonexpression.o: ../../pikotools/src/membuffer/membuffer.h
./jsonexpression.o: ../../pikotools/src/textstream/types.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/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: export.h ../../pikotools/src/convert/text.h
./jsonexpression.o: ../../pikotools/src/convert/misc.h
./jsonexpression.o: ../../pikotools/src/convert/text.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/textstream/types.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/utf8/utf8_templates.h
./model.o: ../../pikotools/src/utf8/utf8_private.h
./model.o: ../../pikotools/src/date/date.h
./model.o: ../../pikotools/src/membuffer/membuffer.h
./model.o: ../../pikotools/src/textstream/types.h modelconnector.h clearer.h
./model.o: 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
./model.o: ../../pikotools/src/convert/text.h flatexpression.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/textstream/types.h
./modelconnector.o: ../../pikotools/src/utf8/utf8.h
./modelconnector.o: ../../pikotools/src/textstream/stream.h
./modelconnector.o: ../../pikotools/src/utf8/utf8_templates.h
./modelconnector.o: ../../pikotools/src/utf8/utf8_private.h ft.h
./modelconnector.o: dbconnector.h ../../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/log/log.h
./modelconnector.o: ../../pikotools/src/log/filelog.h queryresult.h
./modelconnector.o: flatconnector.h export.h
./postgresqlconnector.o: postgresqlconnector.h dbconnector.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/textstream/types.h
./postgresqlconnector.o: ../../pikotools/src/convert/inttostr.h
./postgresqlconnector.o: ../../pikotools/src/utf8/utf8.h
./postgresqlconnector.o: ../../pikotools/src/textstream/stream.h
./postgresqlconnector.o: ../../pikotools/src/utf8/utf8_templates.h
./postgresqlconnector.o: ../../pikotools/src/utf8/utf8_private.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/log/log.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
./postgresqlconnector.o: export.h ../../pikotools/src/convert/text.h
./postgresqlconnector.o: ../../pikotools/src/convert/strtoint.h
./postgresqlconnector.o: ../../pikotools/src/convert/text.h
./postgresqlconnector.o: ../../pikotools/src/convert/misc.h
./postgresqlexpression.o: postgresqlexpression.h dbexpression.h
./postgresqlexpression.o: baseexpression.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/textstream/types.h
./postgresqlexpression.o: ../../pikotools/src/convert/inttostr.h
./postgresqlexpression.o: ../../pikotools/src/utf8/utf8.h
./postgresqlexpression.o: ../../pikotools/src/textstream/stream.h
./postgresqlexpression.o: ../../pikotools/src/utf8/utf8_templates.h
./postgresqlexpression.o: ../../pikotools/src/utf8/utf8_private.h
./postgresqlexpression.o: ../../pikotools/src/date/date.h
./postgresqlexpression.o: ../../pikotools/src/membuffer/membuffer.h
./postgresqlexpression.o: ../../pikotools/src/textstream/types.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/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 export.h
./postgresqlexpression.o: ../../pikotools/src/convert/text.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/textstream/types.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/utf8/utf8_templates.h
./postgresqlqueryresult.o: ../../pikotools/src/utf8/utf8_private.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/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/textstream/types.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/utf8/utf8_templates.h
./queryresult.o: ../../pikotools/src/utf8/utf8_private.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/log/filelog.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/textstream/types.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/utf8/utf8_templates.h
./transaction.o: ../../pikotools/src/utf8/utf8_private.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/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/textstream.h
./xmlconnector.o: ../../pikotools/src/textstream/stream.h
./xmlconnector.o: ../../pikotools/src/space/space.h
./xmlconnector.o: ../../pikotools/src/textstream/types.h
./xmlconnector.o: ../../pikotools/src/convert/inttostr.h
./xmlconnector.o: ../../pikotools/src/utf8/utf8.h
./xmlconnector.o: ../../pikotools/src/textstream/stream.h
./xmlconnector.o: ../../pikotools/src/utf8/utf8_templates.h
./xmlconnector.o: ../../pikotools/src/utf8/utf8_private.h
./xmlconnector.o: ../../pikotools/src/date/date.h
./xmlconnector.o: ../../pikotools/src/membuffer/membuffer.h
./xmlconnector.o: ../../pikotools/src/textstream/types.h export.h
./xmlconnector.o: xmlexpression.h flatexpression.h baseexpression.h
./xmlconnector.o: morm_types.h modelenv.h modeldata.h cursorhelper.h
./xmlconnector.o: queryresult.h ../../pikotools/src/log/log.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
./xmlconnector.o: ../../pikotools/src/convert/text.h
./xmlexpression.o: xmlexpression.h flatexpression.h baseexpression.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/textstream/types.h
./xmlexpression.o: ../../pikotools/src/convert/inttostr.h
./xmlexpression.o: ../../pikotools/src/utf8/utf8.h
./xmlexpression.o: ../../pikotools/src/textstream/stream.h
./xmlexpression.o: ../../pikotools/src/utf8/utf8_templates.h
./xmlexpression.o: ../../pikotools/src/utf8/utf8_private.h
./xmlexpression.o: ../../pikotools/src/date/date.h
./xmlexpression.o: ../../pikotools/src/membuffer/membuffer.h
./xmlexpression.o: ../../pikotools/src/textstream/types.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/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: export.h ../../pikotools/src/convert/text.h
./xmlexpression.o: ../../pikotools/src/convert/misc.h
./xmlexpression.o: ../../pikotools/src/convert/text.h
./csvexpression.o: csvexpression.h flatexpression.h baseexpression.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/textstream/types.h
./csvexpression.o: ../../pikotools/src/convert/inttostr.h
./csvexpression.o: ../../pikotools/src/utf8/utf8.h
./csvexpression.o: ../../pikotools/src/textstream/stream.h
./csvexpression.o: ../../pikotools/src/utf8/utf8_templates.h
./csvexpression.o: ../../pikotools/src/utf8/utf8_private.h
./csvexpression.o: ../../pikotools/src/date/date.h
./csvexpression.o: ../../pikotools/src/membuffer/membuffer.h
./csvexpression.o: ../../pikotools/src/textstream/types.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/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: export.h ../../pikotools/src/convert/text.h
./csvexpression.o: ../../pikotools/src/convert/misc.h
./csvexpression.o: ../../pikotools/src/convert/text.h
./csvconnector.o: csvconnector.h flatconnector.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/textstream/types.h
./csvconnector.o: ../../pikotools/src/convert/inttostr.h
./csvconnector.o: ../../pikotools/src/utf8/utf8.h
./csvconnector.o: ../../pikotools/src/textstream/stream.h
./csvconnector.o: ../../pikotools/src/utf8/utf8_templates.h
./csvconnector.o: ../../pikotools/src/utf8/utf8_private.h
./csvconnector.o: ../../pikotools/src/date/date.h
./csvconnector.o: ../../pikotools/src/membuffer/membuffer.h
./csvconnector.o: ../../pikotools/src/textstream/types.h export.h
./csvconnector.o: csvexpression.h flatexpression.h baseexpression.h
./csvconnector.o: morm_types.h modelenv.h modeldata.h cursorhelper.h
./csvconnector.o: queryresult.h ../../pikotools/src/log/log.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
./csvconnector.o: ../../pikotools/src/convert/text.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

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
@ -44,14 +44,9 @@ namespace morm
BaseExpression::BaseExpression()
{
/*
* may it would be better for the ModelConnector/JSONConnector/PostgreSQLConnector to provide one scratch buffer?
*/
scratch_buffer = &scratch_buffer_local;
clear();
}
BaseExpression::~BaseExpression()
{
}
@ -62,7 +57,6 @@ void BaseExpression::clear()
out_stream = nullptr;
is_first_field = false;
work_mode = 0;
output_type = 0;
use_prefix = false;
}
@ -79,18 +73,6 @@ int BaseExpression::get_work_mode()
}
void BaseExpression::set_output_type(int output_type)
{
this->output_type = output_type;
}
int BaseExpression::get_output_type()
{
return output_type;
}
pt::TextStream * BaseExpression::get_text_stream()
{
@ -126,36 +108,21 @@ bool BaseExpression::get_allow_to_use_prefix()
void BaseExpression::generate_from_model(pt::TextStream & stream, Model & model)
{
FT field_type = FT::default_type;
generate_from_model(stream, model, field_type);
}
void BaseExpression::generate_from_model(pt::TextStream & stream, Model & model, const FT & field_type)
{
this->out_stream = &stream;
generate_from_model(model, field_type);
generate_from_model(model);
this->out_stream = nullptr;
}
void BaseExpression::generate_from_model(Model & model, const FT & field_type)
void BaseExpression::generate_from_model(Model & model)
{
if( out_stream )
{
if( should_field_model_be_generated_as_null(model.get_has_primary_key_set(), field_type) )
{
put_null_value();
}
else
{
before_generate_from_model();
dump_additional_info(model);
model.fields();
add_additional_columns(model);
after_generate_from_model();
}
before_generate_from_model();
dump_additional_info(model);
model.fields();
after_generate_from_model();
}
}
@ -170,11 +137,6 @@ void BaseExpression::dump_additional_info(Model & model)
}
void BaseExpression::add_additional_columns(Model & model)
{
}
void BaseExpression::before_generate_from_model()
{
is_first_field = true;
@ -192,24 +154,6 @@ bool BaseExpression::can_field_be_generated(const FT &)
}
bool BaseExpression::can_field_model_be_generated(bool has_model_primary_key, const FT & field_type)
{
return true;
}
bool BaseExpression::can_field_list_be_generated(const FT &)
{
return true;
}
bool BaseExpression::should_field_model_be_generated_as_null(bool has_model_primary_key, const FT & field_type)
{
return false;
}
void BaseExpression::field_before()
{
if( !is_first_field )
@ -256,27 +200,12 @@ void BaseExpression::put_field_name(const wchar_t * field_name, const FT & field
else
{
before_field_name();
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 */
esc(field_name, *out_stream);
after_field_name();
}
}
void BaseExpression::put_field_closing_name(const wchar_t * field_name, const FT & field_type, ModelEnv * model_env)
{
put_field_name(field_name, field_type, model_env);
}
void BaseExpression::put_value_list_opening_index(size_t index, const FT & field_type)
{
}
void BaseExpression::put_value_list_closing_index(size_t index, const FT & field_type)
{
}
void BaseExpression::save_foreign_key(const wchar_t * field_name, const FT & field_type, ModelEnv * model_env)
{
@ -307,10 +236,6 @@ void BaseExpression::table_field_separator()
}
void BaseExpression::alias_names_separator()
{
}
void BaseExpression::before_schema_name()
{
@ -342,105 +267,95 @@ void BaseExpression::after_field_name()
}
void BaseExpression::before_alias_name()
void BaseExpression::before_field_value(const std::wstring &, const FT & field_type)
{
before_field_value_string(field_type);
}
void BaseExpression::after_alias_name()
void BaseExpression::before_field_value(const std::string &, const FT & field_type)
{
before_field_value_string(field_type);
}
void BaseExpression::before_field_value(const std::wstring &, const FT & field_type, ModelEnv * model_env)
void BaseExpression::after_field_value(const std::wstring &, const FT & field_type)
{
before_field_value_string(field_type, model_env);
after_field_value_string(field_type);
}
void BaseExpression::before_field_value(const std::string &, const FT & field_type, ModelEnv * model_env)
void BaseExpression::after_field_value(const std::string &, const FT & field_type)
{
before_field_value_string(field_type, model_env);
after_field_value_string(field_type);
}
void BaseExpression::after_field_value(const std::wstring &, const FT & field_type, ModelEnv * model_env)
void BaseExpression::before_field_value(const wchar_t *, const FT & field_type)
{
after_field_value_string(field_type, model_env);
before_field_value_string(field_type);
}
void BaseExpression::after_field_value(const std::string &, const FT & field_type, ModelEnv * model_env)
void BaseExpression::after_field_value(const wchar_t *, const FT & field_type)
{
after_field_value_string(field_type, model_env);
after_field_value_string(field_type);
}
void BaseExpression::before_field_value(const wchar_t *, const FT & field_type, ModelEnv * model_env)
void BaseExpression::before_field_value(const char *, const FT & field_type)
{
before_field_value_string(field_type, model_env);
before_field_value_string(field_type);
}
void BaseExpression::after_field_value(const wchar_t *, const FT & field_type, ModelEnv * model_env)
void BaseExpression::after_field_value(const char *, const FT & field_type)
{
after_field_value_string(field_type, model_env);
after_field_value_string(field_type);
}
void BaseExpression::before_field_value(const char *, const FT & field_type, ModelEnv * model_env)
void BaseExpression::before_field_value(wchar_t, const FT & field_type)
{
before_field_value_string(field_type, model_env);
before_field_value_string(field_type);
}
void BaseExpression::after_field_value(const char *, const FT & field_type, ModelEnv * model_env)
void BaseExpression::after_field_value(wchar_t, const FT & field_type)
{
after_field_value_string(field_type, model_env);
after_field_value_string(field_type);
}
void BaseExpression::before_field_value(wchar_t, const FT & field_type, ModelEnv * model_env)
void BaseExpression::before_field_value(char, const FT & field_type)
{
before_field_value_string(field_type, model_env);
before_field_value_string(field_type);
}
void BaseExpression::after_field_value(wchar_t, const FT & field_type, ModelEnv * model_env)
void BaseExpression::after_field_value(char, const FT & field_type)
{
after_field_value_string(field_type, model_env);
after_field_value_string(field_type);
}
void BaseExpression::before_field_value(char, const FT & field_type, ModelEnv * model_env)
void BaseExpression::before_field_value(const pt::Date &, const FT & field_type)
{
before_field_value_string(field_type, model_env);
before_field_value_string(field_type);
}
void BaseExpression::after_field_value(char, const FT & field_type, ModelEnv * model_env)
void BaseExpression::after_field_value(const pt::Date &, const FT & field_type)
{
after_field_value_string(field_type, model_env);
after_field_value_string(field_type);
}
void BaseExpression::before_field_value(const pt::Date &, const FT & field_type, ModelEnv * model_env)
void BaseExpression::before_field_value(const pt::Space &, const FT & field_type)
{
before_field_value_string(field_type, model_env);
before_field_value_string(field_type);
}
void BaseExpression::after_field_value(const pt::Date &, const FT & field_type, ModelEnv * model_env)
void BaseExpression::after_field_value(const pt::Space &, const FT & field_type)
{
after_field_value_string(field_type, model_env);
}
void BaseExpression::before_field_value(const pt::Space &, const FT & field_type, ModelEnv * model_env)
{
before_field_value_string(field_type, model_env);
}
void BaseExpression::after_field_value(const pt::Space &, const FT & field_type, ModelEnv * model_env)
{
after_field_value_string(field_type, model_env);
after_field_value_string(field_type);
}
@ -466,41 +381,9 @@ void BaseExpression::char_to_hex(char c, pt::TextStream & stream)
}
void BaseExpression::char_to_hex(wchar_t c, pt::TextStream & stream)
{
unsigned int z = static_cast<unsigned int>(c);
char_to_hex((char)(unsigned char)(z >> 24), stream);
char_to_hex((char)(unsigned char)(z >> 16), stream);
char_to_hex((char)(unsigned char)(z >> 8), stream);
char_to_hex((char)(unsigned char)(z), stream);
}
/*
* return true if the val character was escaped and put (or ignored) to the stream
*
*/
bool BaseExpression::esc_char(char val, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
{
return esc_char((wchar_t)(unsigned char)val, stream, field_type, model_env);
}
/*
* return true if the val character was escaped and put (or ignored) to the stream
*
* in most caces you have to provide your own esc_char(wchar_t val, pt::TextStream & stream) method
*
*/
bool BaseExpression::esc_char(wchar_t val, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
{
return false;
}
void BaseExpression::esc(char val, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
void BaseExpression::esc(char val, pt::TextStream & stream, const FT & field_type)
{
if( field_type.is_binary() || field_type.is_hexadecimal() )
{
@ -508,99 +391,96 @@ void BaseExpression::esc(char val, pt::TextStream & stream, const FT & field_typ
}
else
{
if( !esc_char(val, stream, field_type, model_env) )
{
stream << val;
}
stream << val;
}
}
void BaseExpression::esc(unsigned char val, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
void BaseExpression::esc(unsigned char val, pt::TextStream & stream, const FT & field_type)
{
esc(static_cast<char>(val), stream, field_type, model_env);
esc(static_cast<char>(val), stream, field_type);
}
void BaseExpression::esc(wchar_t val, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
void BaseExpression::esc(wchar_t val, pt::TextStream & stream, const FT & field_type)
{
if( field_type.is_binary() || field_type.is_hexadecimal() )
if( field_type.use_utf8() )
{
char_to_hex(val, stream);
char utf8_buf[10];
// FIXME surrogate pairs are not used
size_t utf8_len = pt::int_to_utf8((int)val, utf8_buf, sizeof(utf8_buf));
for(size_t a = 0 ; a < utf8_len ; ++a)
{
esc(utf8_buf[a], stream, field_type);
}
}
else
{
if( field_type.use_utf8() )
{
if( !esc_char(val, stream, field_type, model_env) )
{
stream << val;
}
}
else
{
char val_char = (char)(unsigned char)val;
esc(static_cast<char>(val), stream, field_type);
}
}
if( !esc_char(val_char, stream, field_type, model_env) )
void BaseExpression::esc(const wchar_t * val, bool has_known_length, size_t len, pt::TextStream & stream, const FT & field_type)
{
if( field_type.use_utf8() )
{
char utf8_buf[10];
for(size_t i = 0 ; has_known_length ? (i < len) : val[i] != 0 ; ++i)
{
// FIXME surrogate pairs are not used
size_t utf8_len = pt::int_to_utf8((int)val[i], utf8_buf, sizeof(utf8_buf));
for(size_t a = 0 ; a < utf8_len ; ++a)
{
stream << val_char;
esc(utf8_buf[a], stream, field_type);
}
}
}
}
void BaseExpression::esc(const wchar_t * val, bool has_known_length, size_t len, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
{
if( field_type.is_numeric() )
{
esc_numeric_string(val, has_known_length, len, stream, field_type, model_env);
}
else
{
esc_normal_string(val, has_known_length, len, stream, field_type, model_env);
for(size_t i = 0 ; has_known_length ? (i < len) : val[i] != 0 ; ++i)
{
esc(static_cast<char>(val[i]), stream, field_type);
}
}
}
void BaseExpression::esc(const char * val, bool has_known_length, size_t len, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
void BaseExpression::esc(const std::wstring & val, pt::TextStream & stream, const FT & field_type)
{
if( field_type.is_numeric() )
esc(val.c_str(), true, val.size(), stream, field_type);
}
void BaseExpression::esc(const wchar_t * val, pt::TextStream & stream, const FT & field_type)
{
esc(val, false, 0, stream, field_type);
}
void BaseExpression::esc(const std::string & val, pt::TextStream & stream, const FT & field_type)
{
for(size_t i = 0 ; i < val.size() ; ++i)
{
esc_numeric_string(val, has_known_length, len, stream, field_type, model_env);
esc(val[i], stream, field_type);
}
else
}
void BaseExpression::esc(const char * val, pt::TextStream & stream, const FT & field_type)
{
for(size_t i = 0 ; val[i] != 0 ; ++i)
{
esc_normal_string(val, has_known_length, len, stream, field_type, model_env);
esc(val[i], stream, field_type);
}
}
void BaseExpression::esc(const std::wstring & val, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
{
esc(val.c_str(), true, val.size(), stream, field_type, model_env);
}
void BaseExpression::esc(const wchar_t * val, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
{
esc(val, false, 0, stream, field_type, model_env);
}
void BaseExpression::esc(const std::string & val, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
{
esc(val.c_str(), true, val.size(), stream, field_type, model_env);
}
void BaseExpression::esc(const char * val, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
{
esc(val, false, 0, stream, field_type, model_env);
}
void BaseExpression::esc(bool val, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
void BaseExpression::esc(bool val, pt::TextStream & stream, const FT & field_type)
{
if( val )
stream << "true";
@ -609,120 +489,101 @@ void BaseExpression::esc(bool val, pt::TextStream & stream, const FT & field_typ
}
void BaseExpression::esc(short val, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
void BaseExpression::esc(short val, pt::TextStream & stream, const FT & field_type)
{
stream << val;
}
void BaseExpression::esc(unsigned short val, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
void BaseExpression::esc(unsigned short val, pt::TextStream & stream, const FT & field_type)
{
stream << val;
}
void BaseExpression::esc(int val, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
void BaseExpression::esc(int val, pt::TextStream & stream, const FT & field_type)
{
stream << val;
}
void BaseExpression::esc(unsigned int val, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
void BaseExpression::esc(unsigned int val, pt::TextStream & stream, const FT & field_type)
{
stream << val;
}
void BaseExpression::esc(long val, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
void BaseExpression::esc(long val, pt::TextStream & stream, const FT & field_type)
{
stream << val;
}
void BaseExpression::esc(unsigned long val, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
void BaseExpression::esc(unsigned long val, pt::TextStream & stream, const FT & field_type)
{
stream << val;
}
void BaseExpression::esc(long long val, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
void BaseExpression::esc(long long val, pt::TextStream & stream, const FT & field_type)
{
stream << val;
}
void BaseExpression::esc(unsigned long long val, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
void BaseExpression::esc(unsigned long long val, pt::TextStream & stream, const FT & field_type)
{
stream << val;
}
void BaseExpression::esc(float val, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
void BaseExpression::esc(float val, pt::TextStream & stream, const FT & field_type)
{
stream << val;
}
void BaseExpression::esc(double val, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
void BaseExpression::esc(double val, pt::TextStream & stream, const FT & field_type)
{
stream << val;
}
void BaseExpression::esc(long double val, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
void BaseExpression::esc(long double val, pt::TextStream & stream, const FT & field_type)
{
stream << val;
}
void BaseExpression::esc(const pt::Date & date, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
void BaseExpression::esc(const pt::Date & date, pt::TextStream & stream, const FT & field_type)
{
if( field_type.is_date_only() )
{
date.SerializeYearMonthDay(stream, false);
}
else
if( field_type.is_time_only() )
{
date.SerializeHourMinSec(stream);
}
else
{
if( field_type.is_no_time_zone() )
{
date.Serialize(stream);
}
else
{
date.SerializeISO(stream);
}
}
stream << date;
}
void BaseExpression::esc(const pt::TextStream & val, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
void BaseExpression::esc(const pt::TextStream & val, pt::TextStream & stream, const FT & field_type)
{
pt::TextStream::const_iterator i = val.begin();
for(; i != val.end() ; ++i)
{
esc(*i, stream, field_type, model_env);
esc(*i, stream, field_type);
}
}
void BaseExpression::esc(const pt::WTextStream & val, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
void BaseExpression::esc(const pt::WTextStream & val, pt::TextStream & stream, const FT & field_type)
{
pt::WTextStream::const_iterator i = val.begin();
for(; i != val.end() ; ++i)
{
esc(*i, stream, field_type, model_env);
esc(*i, stream, field_type);
}
}
void BaseExpression::esc(const pt::Space & space, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
void BaseExpression::esc(const pt::Space & space, pt::TextStream & stream, const FT & field_type)
{
pt::WTextStream tmp_stream;
bool pretty_print = field_type.is_pretty_print();
@ -732,7 +593,7 @@ void BaseExpression::esc(const pt::Space & space, pt::TextStream & stream, const
else
space.serialize_to_json_stream(tmp_stream, pretty_print);
esc(tmp_stream, stream, field_type, model_env);
esc(tmp_stream, stream, field_type);
}
@ -845,11 +706,11 @@ void BaseExpression::esc(const pt::Space & space, pt::TextStream & stream, const
//}
void BaseExpression::before_field_value_string(const FT & field_type, ModelEnv * model_env)
void BaseExpression::before_field_value_string(const FT & field_type)
{
}
void BaseExpression::after_field_value_string(const FT & field_type, ModelEnv * model_env)
void BaseExpression::after_field_value_string(const FT & field_type)
{
}
@ -1002,7 +863,6 @@ void BaseExpression::put_table_and_field(const wchar_t * table_name, const wchar
}
}
void BaseExpression::put_table_and_field(const pt::WTextStream & table_name, const wchar_t * field_name, const FT & field_type)
{
if( out_stream )
@ -1014,79 +874,6 @@ void BaseExpression::put_table_and_field(const pt::WTextStream & table_name, con
}
void BaseExpression::put_alias(const pt::WTextStream & alias_name, int index)
{
if( out_stream )
{
before_alias_name();
esc(alias_name, *out_stream);
if( index > 1 )
{
(*out_stream) << index;
}
after_alias_name();
}
}
void BaseExpression::put_alias(const pt::WTextStream & alias_name_prefix, int index, const wchar_t * alias_name_postfix)
{
if( out_stream )
{
before_alias_name();
esc(alias_name_prefix, *out_stream);
if( index > 1 )
{
(*out_stream) << index;
}
alias_names_separator();
esc(alias_name_postfix, *out_stream);
after_alias_name();
}
}
void BaseExpression::put_string(const char * str, const FT & field_type, bool add_quotes, ModelEnv * model_env)
{
put_string_generic(str, field_type, add_quotes, model_env);
}
void BaseExpression::put_string(const wchar_t * str, const FT & field_type, bool add_quotes, ModelEnv * model_env)
{
put_string_generic(str, field_type, add_quotes, model_env);
}
void BaseExpression::put_string(const std::string & str, const FT & field_type, bool add_quotes, ModelEnv * model_env)
{
put_string_generic(str, field_type, add_quotes, model_env);
}
void BaseExpression::put_string(const std::wstring & str, const FT & field_type, bool add_quotes, ModelEnv * model_env)
{
put_string_generic(str, field_type, add_quotes, model_env);
}
void BaseExpression::put_stream(const pt::TextStream & str, const FT & field_type, bool add_quotes, ModelEnv * model_env)
{
put_string_generic(str, field_type, add_quotes, model_env);
}
void BaseExpression::put_stream(const pt::WTextStream & str, const FT & field_type, bool add_quotes, ModelEnv * model_env)
{
put_string_generic(str, field_type, add_quotes, model_env);
}
void BaseExpression::schema_table_to_stream(pt::TextStream & stream, const wchar_t * schema_name, const wchar_t * table_name)
{
@ -1168,73 +955,6 @@ void BaseExpression::table_and_field_to_stream(pt::TextStream & stream, const pt
}
void BaseExpression::alias_to_stream(pt::TextStream & stream, const pt::WTextStream & alias_name, int index)
{
this->out_stream = &stream;
put_alias(alias_name, index);
this->out_stream = nullptr;
}
void BaseExpression::alias_to_stream(pt::TextStream & stream, const pt::WTextStream & alias_name_prefix, int index, const wchar_t * alias_name_postfix)
{
this->out_stream = &stream;
put_alias(alias_name_prefix, index, alias_name_postfix);
this->out_stream = nullptr;
}
void BaseExpression::string_to_stream(pt::TextStream & stream, const char * str, const FT & field_type, bool add_quotes, ModelEnv * model_env)
{
this->out_stream = &stream;
put_string(str, field_type, add_quotes, model_env);
this->out_stream = nullptr;
}
void BaseExpression::string_to_stream(pt::TextStream & stream, const wchar_t * str, const FT & field_type, bool add_quotes, ModelEnv * model_env)
{
this->out_stream = &stream;
put_string(str, field_type, add_quotes, model_env);
this->out_stream = nullptr;
}
void BaseExpression::string_to_stream(pt::TextStream & stream, const std::string & str, const FT & field_type, bool add_quotes, ModelEnv * model_env)
{
this->out_stream = &stream;
put_string(str, field_type, add_quotes, model_env);
this->out_stream = nullptr;
}
void BaseExpression::string_to_stream(pt::TextStream & stream, const std::wstring & str, const FT & field_type, bool add_quotes, ModelEnv * model_env)
{
this->out_stream = &stream;
put_string(str, field_type, add_quotes, model_env);
this->out_stream = nullptr;
}
void BaseExpression::stream_to_stream(pt::TextStream & stream_out, const pt::TextStream & stream_in, const FT & field_type, bool add_quotes, ModelEnv * model_env)
{
this->out_stream = &stream_out;
put_stream(stream_in, field_type, add_quotes, model_env);
this->out_stream = nullptr;
}
void BaseExpression::stream_to_stream(pt::TextStream & stream_out, const pt::WTextStream & stream_in, const FT & field_type, bool add_quotes, ModelEnv * model_env)
{
this->out_stream = &stream_out;
put_stream(stream_in, field_type, add_quotes, model_env);
this->out_stream = nullptr;
}
bool BaseExpression::is_empty_field(const wchar_t * value)
{

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,22 +32,20 @@
*
*/
#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/textstream.h"
#include "date/date.h"
#include "morm_types.h"
#include "modelenv.h"
#include "ft.h"
#include "export.h"
#include "convert/text.h"
#ifdef MORM_HAS_EZC_LIBRARY
#include "funinfo.h"
#include "env.h"
#endif
@ -64,22 +62,15 @@ 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::TextStream * get_text_stream();
virtual void set_text_stream(pt::TextStream * out_stream);
virtual void clear();
virtual void generate_from_model(pt::TextStream & stream, Model & model);
virtual void generate_from_model(pt::TextStream & stream, Model & model, const FT & field_type);
virtual pt::TextStream * get_current_stream();
@ -126,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);
}
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);
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
{
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();
@ -139,6 +141,30 @@ public:
}
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);
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)
{
@ -164,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();
@ -175,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();
@ -190,38 +213,31 @@ 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);
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::TextStream & stream, const wchar_t * field_name, const FieldValue & field_value, const FT & field_type, ModelEnv * model_env)
{
@ -231,15 +247,6 @@ public:
}
template<typename FieldValue>
void value_to_stream(pt::TextStream & 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);
@ -250,15 +257,6 @@ 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::TextStream & str, const FT & field_type, bool add_quotes = false, ModelEnv * model_env = nullptr);
virtual void put_stream(const pt::WTextStream & 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);
@ -270,153 +268,86 @@ public:
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);
virtual void alias_to_stream(pt::TextStream & stream, const pt::WTextStream & alias_name, int index);
virtual void alias_to_stream(pt::TextStream & stream, const pt::WTextStream & alias_name_prefix, int index, const wchar_t * alias_name_postfix);
virtual void string_to_stream(pt::TextStream & stream, const char * str, const FT & field_type, bool add_quotes = false, ModelEnv * model_env = nullptr);
virtual void string_to_stream(pt::TextStream & stream, const wchar_t * str, const FT & field_type, bool add_quotes = false, ModelEnv * model_env = nullptr);
virtual void string_to_stream(pt::TextStream & stream, const std::string & str, const FT & field_type, bool add_quotes = false, ModelEnv * model_env = nullptr);
virtual void string_to_stream(pt::TextStream & stream, const std::wstring & str, const FT & field_type, bool add_quotes = false, ModelEnv * model_env = nullptr);
virtual void stream_to_stream(pt::TextStream & stream_out, const pt::TextStream & stream_in, const FT & field_type, bool add_quotes = false, ModelEnv * model_env = nullptr);
virtual void stream_to_stream(pt::TextStream & stream_out, const pt::WTextStream & stream_in, const FT & field_type, bool add_quotes = false, ModelEnv * model_env = 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::TextStream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
virtual bool esc_char(wchar_t val, pt::TextStream & 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::TextStream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
virtual void esc(unsigned char val, pt::TextStream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
virtual void esc(wchar_t val, pt::TextStream & 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::TextStream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
virtual void esc(const wchar_t * val, pt::TextStream & stream, const FT & field_type = FT::default_type, 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::TextStream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
virtual void esc(const char * val, pt::TextStream & stream, const FT & field_type = FT::default_type, 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::TextStream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
virtual void esc(short val, pt::TextStream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
virtual void esc(unsigned short val, pt::TextStream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
virtual void esc(int val, pt::TextStream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
virtual void esc(unsigned int val, pt::TextStream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
virtual void esc(long val, pt::TextStream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
virtual void esc(unsigned long val, pt::TextStream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
virtual void esc(long long val, pt::TextStream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
virtual void esc(unsigned long long val, pt::TextStream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
virtual void esc(float val, pt::TextStream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
virtual void esc(double val, pt::TextStream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
virtual void esc(long double val, pt::TextStream & stream, const FT & field_type = FT::default_type, 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::TextStream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
virtual void esc(const pt::TextStream & val,pt::TextStream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
virtual void esc(const pt::WTextStream & val,pt::TextStream & stream, const FT & field_type = FT::default_type, ModelEnv * model_env = nullptr);
virtual void esc(const pt::Space & space, pt::TextStream & stream, const FT & field_type = FT::default_type, 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);
protected:
int work_mode; /* what to do: generating fields list, values list or fields-values list */
int output_type;
bool is_first_field;
pt::TextStream * 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);
}
}
@ -453,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( !is_first )
{
if( index > 0 )
{
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;
field_value_list_separator();
}
put_field_value_list_model(child_model_item, model_connector, model_env);
is_first = false;
}
after_field_value_list();
@ -505,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( !is_first )
{
if( index > 0 )
{
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;
field_value_list_separator();
}
put_field_value_list_model(*child_model_item, model_connector, model_env);
is_first = false;
}
after_field_value_list();
@ -543,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();
@ -600,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;
}
@ -612,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();
@ -623,40 +540,38 @@ 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 &, const FT & field_type, ModelEnv * model_env)
void before_field_value(const FieldValue &, const FT & field_type)
{
}
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)
{
}
@ -708,180 +623,15 @@ protected:
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::TextStream & stream);
void char_to_hex(wchar_t c, pt::TextStream & stream);
void esc(const wchar_t * val, bool has_known_length, size_t len, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env);
void esc(const char * val, bool has_known_length, size_t len, pt::TextStream & 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::TextStream & 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::TextStream & 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();
}
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();
}
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, 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::TextStream & 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, 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::TextStream & stream, Model & model, Export exp);
protected:
void allocate_default_expression();
};
}
#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, 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(wchar_t val, pt::TextStream & 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, 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 &);
void field_before();
void after_generate_from_model();
void before_field_name();
void after_field_name();
void before_field_value_string(const FT & field_type, ModelEnv * model_env);
void after_field_value_string(const FT & field_type, ModelEnv * model_env);
using BaseExpression::esc;
bool esc_char(wchar_t val, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env);
};
}
#endif

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_cursor
#define headerfile_morm_src_cursor
#ifndef headerfile_morm_cursor
#define headerfile_morm_cursor
#include "queryresult.h"
#include "modelconnector.h"
@ -63,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 )
{
@ -109,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;
}
@ -135,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;
}
@ -153,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;
@ -175,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;
}
@ -184,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;
@ -215,37 +177,34 @@ public:
if( db_connector )
{
ModelEnv model_env_local;
result.model_env = &model_env_local;
result.model_env->cursor_helper = &cursor_helper;
result.model_env->finder_helper = &finder_helper;
result.model_env->model = &result;
try
{
ModelEnv model_env_local;
result.model_env = &model_env_local;
result.model_env->model = &result;
result.model_env->model_data = model_data;
finder_helper.clear(); // at the moment used only for calculating table prefixes (indices)
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() )
{
@ -314,7 +273,6 @@ public:
return get_list_generic(result, clear_list);
}
virtual std::vector<ModelClass> get_vector()
{
std::vector<ModelClass> result;
@ -324,142 +282,6 @@ public:
}
virtual size_t get_rows_counter()
{
return rows_counter;
}
virtual void set_cursor_name(pt::TextStream & cursor_name)
{
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:
@ -470,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::TextStream & cursor_name, pt::TextStream & out_stream);
typedef void (DbExpression::*prepare_fetch_long_count_method_type)(const pt::TextStream & cursor_name, long count, pt::TextStream & out_stream);
typedef void (DbExpression::*prepare_fetch_size_count_method_type)(const pt::TextStream & cursor_name, size_t count, pt::TextStream & 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>
@ -580,7 +312,7 @@ protected:
if( db_connector )
{
res = last_query_status;
res = select_status;
try
{
@ -627,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();
@ -669,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-2023, 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();
@ -144,11 +150,6 @@ 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::TextStream & stream, QueryResult & query_result)
@ -171,221 +172,6 @@ bool DbConnector::query_remove(const pt::TextStream & stream, QueryResult & quer
return query(stream, query_result);
}
bool DbConnector::query_declare_cursor(const pt::TextStream & 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()
@ -419,7 +205,7 @@ void DbConnector::generate_insert_query(pt::TextStream & 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::TextStream & 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 << ")";
@ -444,15 +230,15 @@ void DbConnector::generate_update_query(pt::TextStream & 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);
@ -469,17 +255,16 @@ void DbConnector::generate_remove_query(pt::TextStream & 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::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, wchar_t & c)
{
unsigned int res = 0;
unescape_hex_char(str, sizeof(wchar_t) * 2, res);
c = (wchar_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, wchar_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,53 +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() )
{
unescape_bin_char(value_str, field_value);
if( c <= 127 )
{
field_value = static_cast<char>(c);
}
else
{
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 = *value_str;
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)
{
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
{
@ -709,7 +556,7 @@ void DbConnector::get_value(const char * value_str, wchar_t & field_value, const
}
else
{
field_value = 0xFFFD; // U+FFFD "replacement character";
// report an error?
}
}
else
@ -721,18 +568,48 @@ void DbConnector::get_value(const char * value_str, wchar_t & field_value, const
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;
}
@ -745,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
@ -784,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);
}
@ -861,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);
}
@ -921,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-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_dbconnector
#define headerfile_morm_src_dbconnector
#ifndef headerfile_morm_dbconnector
#define headerfile_morm_dbconnector
#include "textstream/textstream.h"
#include "log/log.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);
@ -86,76 +85,32 @@ 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::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 bool query_declare_cursor(const pt::TextStream & stream, QueryResult & query_result);
/*
* create a new transaction
* first transaction has index equal to one
*/
virtual bool begin();
/*
* create a new transaction if there is no a transaction started yet
*/
virtual bool begin_if_needed();
/*
* rollback or commit the last transaction
*/
virtual bool rollback();
virtual bool commit();
/*
* rollback or commit all transactions from the last one to the index
* (first transaction has index one, there is no a transaction with index zero)
*
*/
virtual bool rollback(size_t index);
virtual bool commit(size_t index);
/*
* return current transaction index (within a group)
* first transaction has index equal to one
* returns zero if there are no any transactions
*/
virtual size_t get_transaction_index();
/*
* return current transaction group index
* a group index is incremented when you commit or rollback a transaction
* (if you are closing a nested transaction then the group index is not incremented)
*
*/
virtual size_t get_transaction_group();
virtual void get_value(const char * value_str, char & field_value, const FT & field_type = FT::default_type);
virtual void get_value(const char * value_str, unsigned char & field_value, const FT & field_type = FT::default_type);
virtual void get_value(const char * value_str, unsigned char & field_value, const FT & field_type = FT::default_type);
virtual void get_value(const char * value_str, wchar_t & field_value, const FT & field_type = FT::default_type);
virtual void get_value(const char * value_str, std::wstring & field_value, const FT & field_type = FT::default_type);
virtual void get_value(const char * value_str, std::string & field_value, const FT & field_type = FT::default_type);
virtual void get_value(const char * value_str, std::string_view & field_value, const FT & field_type = FT::default_type);
virtual void get_value(const char * value_str, bool & field_value, const FT & field_type = FT::default_type);
virtual void get_value(const char * value_str, short & field_value, const FT & field_type = FT::default_type);
virtual void get_value(const char * value_str, short & field_value, const FT & field_type = FT::default_type);
virtual void get_value(const char * value_str, unsigned short & field_value, const FT & field_type = FT::default_type);
virtual void get_value(const char * value_str, int & field_value, const FT & field_type = FT::default_type);
virtual void get_value(const char * value_str, unsigned int & field_value, const FT & field_type = FT::default_type);
virtual void get_value(const char * value_str, long & field_value, const FT & field_type = FT::default_type);
virtual void get_value(const char * value_str, unsigned long & field_value, const FT & field_type = FT::default_type);
virtual void get_value(const char * value_str, long long & field_value, const FT & field_type = FT::default_type);
virtual void get_value(const char * value_str, unsigned long & field_value, const FT & field_type = FT::default_type);
virtual void get_value(const char * value_str, long long & field_value, const FT & field_type = FT::default_type);
virtual void get_value(const char * value_str, unsigned long long & field_value, const FT & field_type = FT::default_type);
virtual void get_value(const char * value_str, float & field_value, const FT & field_type = FT::default_type);
virtual void get_value(const char * value_str, float & field_value, const FT & field_type = FT::default_type);
virtual void get_value(const char * value_str, double & field_value, const FT & field_type = FT::default_type);
virtual void get_value(const char * value_str, long double & field_value, const FT & field_type = FT::default_type);
virtual void get_value(const char * value_str, pt::Date & field_value, const FT & field_type = FT::default_type);
virtual void get_value(const char * value_str, pt::Space & field_value, const FT & field_type = FT::default_type);
virtual void get_value(const char * value_str, pt::Space & field_value, const FT & field_type = FT::default_type);
// add get_value for pt::TextStream and pt::WTextStream
@ -186,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;
@ -196,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, wchar_t & c);
virtual void unescape_bin_char(const char * str, char & c);
virtual void unescape_bin_char(const char * str, wchar_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-2023, 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) << "'";
}
@ -332,134 +293,11 @@ DbExpression & DbExpression::group_end(pt::TextStream & stream)
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::TextStream & 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::TextStream & cursor_name, bool scroll_cursor, pt::TextStream & 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::TextStream & cursor_name, pt::TextStream & out_stream)
{
out_stream << "FETCH NEXT FROM " << cursor_name;
}
void DbExpression::prepare_fetch_prior_query(const pt::TextStream & cursor_name, pt::TextStream & out_stream)
{
out_stream << "FETCH PRIOR FROM " << cursor_name;
}
void DbExpression::prepare_fetch_first_query(const pt::TextStream & cursor_name, pt::TextStream & out_stream)
{
out_stream << "FETCH FIRST FROM " << cursor_name;
}
void DbExpression::prepare_fetch_last_query(const pt::TextStream & cursor_name, pt::TextStream & out_stream)
{
out_stream << "FETCH LAST FROM " << cursor_name;
}
void DbExpression::prepare_fetch_absotule_query(const pt::TextStream & cursor_name, long position, pt::TextStream & out_stream)
{
out_stream << "FETCH ABSOLUTE " << position << " FROM " << cursor_name;
}
void DbExpression::prepare_fetch_relative_query(const pt::TextStream & cursor_name, long position, pt::TextStream & out_stream)
{
out_stream << "FETCH RELATIVE " << position << " FROM " << cursor_name;
}
void DbExpression::prepare_fetch_forward_count_query(const pt::TextStream & cursor_name, size_t len, pt::TextStream & out_stream)
{
out_stream << "FETCH FORWARD " << len << " FROM " << cursor_name;
}
void DbExpression::prepare_fetch_backward_count_query(const pt::TextStream & cursor_name, size_t len, pt::TextStream & out_stream)
{
out_stream << "FETCH BACKWARD " << len << " FROM " << cursor_name;
}
void DbExpression::prepare_fetch_all_query(const pt::TextStream & cursor_name, pt::TextStream & out_stream)
{
out_stream << "FETCH ALL FROM " << cursor_name;
}
}

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_dbexpression
#define headerfile_morm_src_dbexpression
#ifndef headerfile_morm_dbexpression
#define headerfile_morm_dbexpression
#include <vector>
#include "baseexpression.h"
@ -50,8 +50,9 @@ 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();
@ -59,9 +60,6 @@ public:
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::TextStream & stream, size_t page_number, size_t page_size);
template<typename FieldValue>
@ -70,29 +68,17 @@ 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::TextStream & str);
virtual void prepare_declare_cursor_query(const pt::TextStream & cursor_name, bool scroll_cursor, pt::TextStream & out_stream);
virtual void prepare_fetch_next_query(const pt::TextStream & cursor_name, pt::TextStream & out_stream);
virtual void prepare_fetch_prior_query(const pt::TextStream & cursor_name, pt::TextStream & out_stream);
virtual void prepare_fetch_first_query(const pt::TextStream & cursor_name, pt::TextStream & out_stream);
virtual void prepare_fetch_last_query(const pt::TextStream & cursor_name, pt::TextStream & out_stream);
virtual void prepare_fetch_absotule_query(const pt::TextStream & cursor_name, long position, pt::TextStream & out_stream);
virtual void prepare_fetch_relative_query(const pt::TextStream & cursor_name, long position, pt::TextStream & out_stream);
virtual void prepare_fetch_forward_count_query(const pt::TextStream & cursor_name, size_t len, pt::TextStream & out_stream);
virtual void prepare_fetch_backward_count_query(const pt::TextStream & cursor_name, size_t len, pt::TextStream & out_stream);
virtual void prepare_fetch_all_query(const pt::TextStream & cursor_name, pt::TextStream & out_stream);
protected:
int output_type;
std::vector<int> conjunctions;
bool can_field_be_generated(const FT & field_type);
@ -101,7 +87,6 @@ protected:
void schema_table_separator();
void table_field_separator();
void alias_names_separator();
void before_schema_name();
void after_schema_name();
@ -112,15 +97,12 @@ protected:
void before_field_name();
void after_field_name();
void before_alias_name();
void after_alias_name();
void add_additional_columns(Model & model);
private:
void before_field_value_string(const FT & field_type, ModelEnv * model_env);
void after_field_value_string(const FT & field_type, ModelEnv * model_env);
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-2023, 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::TextStream & 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::TextStream & stream, Model & model, Export exp)
}
void FlatConnector::deallocate_expression()
{
if( expression_allocated )

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,11 +32,10 @@
*
*/
#ifndef headerfile_morm_src_flatconnector
#define headerfile_morm_src_flatconnector
#ifndef headerfile_morm_flatconnector
#define headerfile_morm_flatconnector
#include "textstream/textstream.h"
#include "export.h"
namespace morm
@ -52,7 +51,7 @@ public:
FlatConnector();
virtual ~FlatConnector();
virtual void to_text(pt::TextStream & 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-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_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);
bool can_field_model_be_generated(bool has_model_primary_key, const FT & field_type);
};

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

@ -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"

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
@ -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,28 +117,50 @@ void JSONExpression::after_field_value_list()
}
bool JSONExpression::esc_char(wchar_t val, pt::TextStream & 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::TextStream & 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::WTextStream 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
space.serialize_to_json_stream(stream, pretty_print);
if( (unsigned char)val < 32 )
{
char buf[10];
size_t len;
pt::Toa((unsigned char)val, buf, sizeof(buf)/sizeof(char), 16, &len);
stream << "\\u";
if( len < 4 )
{
for(size_t i=0 ; i < (4-len) ; ++i)
{
stream << '0';
}
}
stream << buf;
}
else
{
switch( val )
{
case 0: stream << '\\'; stream << '0'; break; // may to skip this character is better?
case '\r': stream << '\\'; stream << 'r'; break;
case '\n': stream << '\\'; stream << 'n'; break;
case '\t': stream << '\\'; stream << 't'; break;
case 0x08: stream << '\\'; stream << 'b'; break;
case 0x0c: stream << '\\'; stream << 'f'; break;
case '\\': stream << '\\'; stream << '\\'; break;
case '"': stream << '\\'; stream << '\"'; break;
default:
stream << val;
}
}
}
}
}

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,8 +32,8 @@
*
*/
#ifndef headerfile_morm_src_jsonexpression
#define headerfile_morm_src_jsonexpression
#ifndef headerfile_morm_jsonexpression
#define headerfile_morm_jsonexpression
#include "flatexpression.h"
@ -62,17 +62,17 @@ protected:
void before_field_value_list();
void after_field_value_list();
bool esc_char(wchar_t val, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env);
void esc(const pt::Space & space, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env);
// 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);
void after_field_value_string(const FT & field_type, ModelEnv * model_env);
void before_field_value(const pt::Space &, const FT & field_type, ModelEnv * model_env);
void after_field_value(const pt::Space &, const FT & field_type, ModelEnv * model_env);
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-2023, Tomasz Sowa
* Copyright (c) 2018-2021, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -74,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;
}
@ -281,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)
{
@ -347,9 +308,10 @@ bool Model::get_raw_value(const wchar_t * db_field_name, const wchar_t * flat_fi
void Model::to_text(pt::TextStream & 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();
}
@ -358,7 +320,7 @@ void Model::to_text(pt::TextStream & 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;
@ -371,7 +333,7 @@ void Model::to_text(pt::TextStream & 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(...)
{
@ -385,32 +347,6 @@ void Model::to_text(pt::TextStream & stream, ModelData * model_data, Export exp)
}
void Model::to_text(pt::TextStream & stream, ModelData & model_data, Export exp)
{
to_text(stream, &model_data, exp);
}
void Model::to_text(pt::TextStream & stream, Export exp)
{
to_text(stream, nullptr, exp);
}
void Model::to_text(pt::TextStream & 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::TextStream & stream, ModelData & model_data, bool clear_stream, bool dump_mode)
{
to_text(stream, &model_data, clear_stream, dump_mode);
@ -424,7 +360,6 @@ void Model::to_text(pt::TextStream & stream, bool clear_stream, bool dump_mode)
void Model::to_text(std::string & str, ModelData * model_data, bool clear_string, bool dump_mode)
{
if( model_connector )
@ -520,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(...)
{
@ -533,27 +469,30 @@ 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?
// 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 )
@ -561,9 +500,9 @@ void Model::insert_tree(bool insert_whole_tree)
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
@ -586,22 +525,16 @@ 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;
}
@ -649,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(...)
{
@ -662,28 +596,30 @@ 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();
@ -695,29 +631,23 @@ void Model::update_tree(bool update_whole_tree)
{
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;
}
@ -765,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(...)
{
@ -778,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?
// 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;
@ -825,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;
}
@ -864,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(...)
{
@ -877,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;
@ -897,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 )
{
ModelEnv * old_model_env = model_env; // remove, insert or update will set model_env to nullptr
case DO_DELETE_ON_SAVE:
result = remove_tree(false);
break;
switch( save_mode )
{
case DO_DELETE_ON_SAVE:
remove_tree(false);
break;
case DO_INSERT_ON_SAVE:
result = insert_tree(false);
break;
case DO_INSERT_ON_SAVE:
insert_tree(false);
break;
case DO_UPDATE_ON_SAVE:
result = update_tree(false);
break;
case DO_UPDATE_ON_SAVE:
update_tree(false);
break;
case DO_NOTHING_ON_SAVE:
break;
}
model_env = old_model_env;
case DO_NOTHING_ON_SAVE:
result = true;
break;
}
if( model_env->status && save_whole_tree )
model_env = old_model_env;
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;
@ -932,6 +859,8 @@ void Model::save_tree(bool save_whole_tree)
model_env->model_work_submode = MORM_MODEL_WORK_SUBMODE_SAVE;
fields();
}
return result;
}
@ -961,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 )
@ -978,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()
{
@ -1190,24 +1084,16 @@ 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();
}
pt::Log * log = model_connector->get_logger();
return nullptr;
}
void Model::put_to_log(const wchar_t * str)
{
pt::Log * log = get_logger();
if( log )
{
(*log) << str << pt::Log::logend;
if( log )
{
(*log) << str << pt::Log::logend;
}
}
}
@ -1261,7 +1147,7 @@ void Model::field_model_left_join(const wchar_t * db_field_name, Model & field_m
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);
@ -1474,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);
@ -1548,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();
}
@ -1561,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);
}
}
@ -1646,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 )
@ -1658,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;
// model_env->was_field_found = true;
// model_env->model = &field_model;
}
}
if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_PROPAGATE_SAVE_STATUS )
{
field_model.set_save_mode2(save_mode, true);
}
field_model.model_env = nullptr;
if( !model_env_local.status )
model_env->status = false;
}
}
@ -1988,7 +1869,7 @@ void Model::field_member(
}
/*
bool Model::convert_to_bool(char v)
{
return v != 0;
@ -2109,7 +1990,7 @@ bool Model::convert_to_bool(const pt::Space & space)
{
return false;
}
*/

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_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();
@ -177,13 +165,9 @@ public:
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::TextStream & stream, ModelData * model_data, Export exp = Export::default_type);
virtual void to_text(pt::TextStream & stream, ModelData & model_data, Export exp = Export::default_type);
virtual void to_text(pt::TextStream & stream, Export exp = Export::default_type);
virtual void to_text(pt::TextStream & stream, ModelData * model_data, bool clear_stream, bool dump_mode);
virtual void to_text(pt::TextStream & stream, ModelData & model_data, bool clear_stream, bool dump_mode);
virtual void to_text(pt::TextStream & 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);
@ -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,14 +358,12 @@ 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);
@ -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,33 +1027,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)();
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_connector && model_env && model_env->model )
{
if( field_type.is_primary_key() )
{
pt::Log * plog = model_connector->get_logger();
if( plog )
{
(*plog) << pt::Log::log1 << "Morm:: an ezc method cannot be used as a primary key" << pt::Log::logend;
}
}
if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_GET_MODEL_WRAPPER )
{
if( (is_empty_field(model_env->db_field_name) || is_the_same_field(db_field_name, model_env->db_field_name)) &&
(is_empty_field(model_env->flat_field_name) || is_the_same_field(flat_field_name, model_env->flat_field_name)) )
{
(model_env->model->*method)(model_env->wrapper);
if( model_env->ezc_var_space_local )
{
model_env->ezc_var_space_local->set(res);
}
}
}
}
@ -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);
@ -1152,24 +1146,18 @@ 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);
model_env_local.model = &child_model;
ModelEnv model_env_local;
model_env_local.copy_global_objects(*model_env);
model_env_local.model = &child_model;
child_model.model_env = &model_env_local;
child_model.model_env->has_primary_key_set = child_model.has_primary_key_set;
child_model.set_connector(model_connector);
child_model.table();
child_model.model_env = &model_env_local;
child_model.model_env->has_primary_key_set = child_model.has_primary_key_set;
child_model.set_connector(model_connector);
child_model.table();
field_model_iterate_through_childs(child_model, field_type);
field_model_iterate_through_childs(child_model, field_type);
if( !model_env_local.status )
model_env->status = false;
child_model.model_env = nullptr;
}
child_model.model_env = nullptr;
}
@ -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,35 +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::TextStream & val);
virtual bool convert_to_bool(const pt::WTextStream & 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

@ -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"

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-2022, Tomasz Sowa
* Copyright (c) 2019-2021, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -32,20 +32,18 @@
*
*/
#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 "funinfo.h"
#include "env.h"
#endif
@ -97,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();
@ -149,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
@ -208,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
}
@ -238,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-2023, Tomasz Sowa
* Copyright (c) 2018-2021, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -97,15 +97,13 @@ 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();
psql_result->psql_result = PQexec(pg_conn, query_str);
if( PQstatus(pg_conn) != CONNECTION_OK )
{
assert_connection();
psql_result->psql_result = PQexec(pg_conn, query_str);
}
}
if( psql_result->psql_result )
@ -117,15 +115,19 @@ bool PostgreSQLConnector::do_query(const char * query_str, PostgreSQLQueryResult
if( !psql_result->psql_result || psql_result->psql_status == PGRES_FATAL_ERROR )
{
const char * err_msg = PQerrorMessage(pg_conn);
if( err_msg )
{
pt::utf8_to_wide(err_msg, psql_result->error_msg);
}
if( log )
{
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);
}
(*log) << pt::Log::log1 << "Morm: " << err_msg << pt::Log::logend;
}
}
else
@ -170,7 +172,7 @@ const char * PostgreSQLConnector::query_last_sequence(const wchar_t * sequence_t
if( log )
{
(*log) << pt::Log::log1 << "Morm: expected only one row in sequence result, has: " << psql_result.result_rows
<< pt::Log::logend;
<< pt::Log::logend;
}
}
}
@ -178,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;
}
}
}
@ -207,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;
}
@ -222,29 +219,48 @@ 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;
}
@ -272,11 +288,16 @@ bool PostgreSQLConnector::query_remove(const pt::TextStream & stream, QueryResul
return query_remove(query_str.c_str(), query_result);
}
bool PostgreSQLConnector::query_declare_cursor(const pt::TextStream & stream, QueryResult & query_result)
{
stream.to_str(query_str);
return query_declare_cursor(query_str.c_str(), query_result);
}
@ -370,48 +391,15 @@ bool PostgreSQLConnector::query_declare_cursor(const pt::TextStream & stream, Qu
//}
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::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;
}
void PostgreSQLConnector::overwrite(pt::TextStream & stream)
{
pt::TextStream::iterator i = stream.begin();
@ -439,44 +427,15 @@ void PostgreSQLConnector::connect()
if( db_expression )
{
stream.clear();
stream << "dbname='";
db_expression->esc(db_database, stream);
if( !db_conn_string.empty() )
{
stream << db_conn_string;
}
else
{
stream << "dbname='";
db_expression->esc(db_database, stream);
stream << "' user='";
db_expression->esc(db_user, stream);
stream << "' user='";
db_expression->esc(db_user, stream);
stream << "' password='";
db_expression->esc(db_pass, stream);
stream << "'";
if( !db_host.empty() )
{
stream << " host='";
db_expression->esc(db_host, stream);
stream << "'";
}
if( !db_hostaddr.empty() )
{
stream << " hostaddr='";
db_expression->esc(db_hostaddr, stream);
stream << "'";
}
if( !db_port.empty() )
{
stream << " port='";
db_expression->esc(db_port, stream);
stream << "'";
}
}
stream << "' password='";
db_expression->esc(db_pass, stream);
stream << "'";
std::string str;
stream.to_str(str);
@ -492,17 +451,6 @@ void PostgreSQLConnector::connect()
//
//
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()
{
if( pg_conn && log )
@ -513,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 )
@ -532,41 +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);
}
if( !attempts_exceeded )
{
sleep(attempt_delay);
}
sleep(5);
}
}
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;
@ -638,28 +559,17 @@ 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);
}
}
void PostgreSQLConnector::unescape_bin_char(const char * str, wchar_t & field_value)
{
if( str[0]!='\\' || str[1]!='x' )
{
log_unsupported_bin_format();
}
else
{
DbConnector::unescape_bin_char(str + 2, field_value);
return unescape_hex_char(str + 2, field_value, field_type);
}
}
@ -673,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' )
{
@ -686,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-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_postgresqlconnector
#define headerfile_morm_src_postgresqlconnector
#ifndef headerfile_morm_postgresqlconnector
#define headerfile_morm_postgresqlconnector
#include <libpq-fe.h>
#include <string>
@ -63,65 +63,22 @@ public:
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_declare_cursor(const char * query_str, QueryResult & query_result);
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);
bool query_declare_cursor(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,22 +88,11 @@ 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();
virtual void overwrite(pt::TextStream & stream);
virtual const char * query_last_sequence(const wchar_t * sequence_table_name);
@ -154,12 +100,9 @@ protected:
void log_unsupported_bin_format();
void unescape_bin_char(const char * str, char & field_value);
void unescape_bin_char(const char * str, wchar_t & field_value);
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);
void unescape_bin_string(const char * str, std::wstring & out, const FT & field_type);
};

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
@ -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(wchar_t val, pt::TextStream & 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;
}
else
if( val == '_' )
{
stream << "\\\\_"; // gives: "\\_"
return true;
}
else
if( val == '\\' )
{
stream << "\\\\\\\\"; // gives: "\\\\"
return true;
}
}
if( val == '\\' )
{
stream << "\\\\";
return true;
char_to_hex(val, stream);
}
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;
switch( val )
{
case '\\': stream << "\\\\"; break;
case '\'': stream << "\\\'"; break; // don't use "''" because we use the method for PQconnectdb too
default:
if( val != 0 )
{
stream << val;
}
}
}
}
return false;
void PostgreSQLExpression::esc(const pt::Date & date, pt::TextStream & stream, const FT & field_type)
{
stream << date << "+00";
}
DbExpression & PostgreSQLExpression::page(pt::TextStream & stream, size_t page_number, size_t page_size)
{
stream << " OFFSET " << (page_number*page_size) << " LIMIT " << page_size << " ";
stream << " offset " << page_number << " limit " << page_size << " ";
return *this;
}

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,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,6 +45,9 @@ class PostgreSQLExpression : public DbExpression
{
public:
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);
@ -55,10 +58,9 @@ protected:
private:
void before_field_value_string(const FT & field_type, ModelEnv * model_env);
void after_field_value_string(const FT & field_type, ModelEnv * model_env);
void before_field_value_string(const FT & field_type);
void after_field_value_string(const FT & field_type);
bool esc_char(wchar_t val, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env);
};

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-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.
*
*/
#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::TextStream & 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::TextStream & stream)
{
if( put_doctype )
{
stream << L"<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
}
}
void XMLConnector::put_opening_root_element(pt::TextStream & stream)
{
if( put_root_element )
{
stream << L"<";
put_root_element_name(stream);
stream << L">";
}
}
void XMLConnector::put_closing_root_element(pt::TextStream & stream)
{
if( put_root_element )
{
stream << L"</";
put_root_element_name(stream);
stream << L">";
}
}
void XMLConnector::put_root_element_name(pt::TextStream & 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-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_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::TextStream & stream, Model & model, Export exp);
protected:
bool put_doctype;
bool put_root_element;
std::wstring root_element_name;
void allocate_default_expression();
virtual void put_doctype_definition(pt::TextStream & stream);
virtual void put_opening_root_element(pt::TextStream & stream);
virtual void put_closing_root_element(pt::TextStream & stream);
virtual void put_root_element_name(pt::TextStream & stream);
};
}
#endif

View File

@ -1,143 +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.
*
*/
#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(wchar_t val, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env)
{
return pt::try_esc_to_xml(val, stream);
}
void XMLExpression::esc(const pt::Space & space, pt::TextStream & 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-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_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);
void before_field_name();
void after_field_name();
void put_name_value_separator();
using BaseExpression::esc;
bool esc_char(wchar_t val, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env);
void esc(const pt::Space & space, pt::TextStream & stream, const FT & field_type, ModelEnv * model_env);
private:
void before_field_value(const pt::Space &, const FT & field_type, ModelEnv * model_env);
void after_field_value(const pt::Space &, const FT & field_type, ModelEnv * model_env);
void put_value_list_opening_index(size_t index, const FT & field_type);
void put_value_list_closing_index(size_t index, const FT & field_type);
void field_value_list_separator();
};
}
#endif