Merge pull request 'winix_fullmorm' (#4) from winix_fullmorm into master

Reviewed-on: #4
This commit is contained in:
Tomasz Sowa 2021-05-27 10:49:46 +02:00
commit 284cbc5c66
42 changed files with 3466 additions and 2047 deletions

3
.gitignore vendored
View File

@ -3,3 +3,6 @@
.settings/
*.o
*.a
log.txt
samples/log.txt
samples/mormsample

View File

@ -7,13 +7,13 @@ GLOBAL_WORKING_DIR := $(shell pwd)/../..
endif
CXX = g++7
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/gcc7 -Wfatal-errors -fPIC -Wall -pedantic -O0 -g3 -gdwarf-2 -pthread -std=c++17 -I/usr/local/include -I$(GLOBAL_WORKING_DIR)/pikotools -I$(GLOBAL_WORKING_DIR)/morm/src
CXXFLAGS = -Wl,-rpath=/usr/local/lib/gcc10 -Wfatal-errors -fPIC -Wall -pedantic -O0 -g3 -gdwarf-2 -pthread -std=c++20 -I/usr/local/include -I$(GLOBAL_WORKING_DIR)/pikotools -I$(GLOBAL_WORKING_DIR)/morm/src
LDFLAGS = -L/usr/local/lib
@ -27,11 +27,12 @@ current_path := $(shell pwd)
global_relative_working_dir := $(shell relative_path $(current_path) $(GLOBAL_WORKING_DIR))
# IMPROVE ME
# add dependency to pikotools
all: morm $(name)
$(name): $(o)
$(name): morm $(o)
$(CXX) -o $(name) $(CXXFLAGS) $(LDFLAGS) $(o) $(GLOBAL_WORKING_DIR)/morm/src/morm.a $(GLOBAL_WORKING_DIR)/pikotools/log/log.a $(GLOBAL_WORKING_DIR)/pikotools/space/space.a $(GLOBAL_WORKING_DIR)/pikotools/mainspaceparser/mainspaceparser.a $(GLOBAL_WORKING_DIR)/pikotools/date/date.a $(GLOBAL_WORKING_DIR)/pikotools/convert/convert.a $(GLOBAL_WORKING_DIR)/pikotools/utf8/utf8.a $(LDFLAGS) -lpq -lpthread

View File

@ -2,11 +2,10 @@
main.o: ../../pikotools/mainspaceparser/mainspaceparser.h
main.o: ../../pikotools/space/space.h ../../pikotools/textstream/types.h
main.o: sample01.h basesample.h ../../morm/src/morm.h
main.o: ../../morm/src/morm_types.h ../../morm/src/model.h
main.o: ../../pikotools/textstream/textstream.h ../../pikotools/date/date.h
main.o: ../../pikotools/convert/inttostr.h
main.o: ../../pikotools/membuffer/membuffer.h
main.o: ../../pikotools/convert/inttostr.h sample01.h basesample.h
main.o: ../../morm/src/morm.h ../../morm/src/morm_types.h
main.o: ../../morm/src/model.h ../../pikotools/textstream/textstream.h
main.o: ../../pikotools/date/date.h ../../pikotools/membuffer/membuffer.h
main.o: ../../pikotools/textstream/types.h ../../morm/src/modelconnector.h
main.o: ../../morm/src/clearer.h ../../morm/src/dbconnector.h
main.o: ../../pikotools/log/log.h ../../pikotools/log/filelog.h
@ -14,10 +13,11 @@ main.o: ../../morm/src/queryresult.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/finder.h ../../pikotools/utf8/utf8.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/fieldvaluehelper.h ../../morm/src/ft.h
main.o: ../../morm/src/flatexpression.h ../../morm/src/finder.h
main.o: ../../pikotools/utf8/utf8.h ../../pikotools/utf8/utf8_templates.h
main.o: ../../pikotools/utf8/utf8_private.h ../../morm/src/cursor.h
main.o: ../../morm/src/jsonexpression.h ../../morm/src/postgresqlexpression.h
main.o: ../../morm/src/jsonconnector.h ../../morm/src/postgresqlconnector.h
main.o: ../../morm/src/postgresqlqueryresult.h person.h language.h
main.o: attachment.h type.h
main.o: attachment.h type.h attachment2.h

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2019, Tomasz Sowa
* Copyright (c) 2019-2021, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -38,7 +38,7 @@
#include <string>
#include "morm.h"
#include "type.h"
#include "language.h"
namespace morm
@ -54,7 +54,7 @@ CREATE TABLE public.attachment (
content text,
some_flags bool,
created_date timestamp with time zone,
bigint language_id,
language_id bigint,
primary key(id)
);
@ -71,32 +71,39 @@ public:
std::string content;
std::vector<Type> types;
bool some_flags;
PT::Date created_date;
pt::Date created_date;
Language language;
void map_fields()
{
field(L"id", id, false, false, true);
field(L"id", id, FT::no_insertable | FT::no_updatable | FT::primary_key);
field(L"person_id", person_id);
field(L"name", name);
field(L"content", content);
field(L"attachment_id", L"types", types);
//field(L"types", types);
field(L"attachment_id", L"types", types, FT::foreign_key_in_child);
field(L"some_flags", some_flags);
field(L"created_date", created_date);
field(L"language_id", L"language", language);
field(L"language_id", L"language", language, FT::foreign_key);
}
void table_name(PT::TextStream & stream)
void prepare_table()
{
// schema.table_name or just table_name
stream << "public.attachment";
table(L"public", L"attachment");
}
void after_select()
{
if( has_primary_key_set )
{
morm::Finder<Type> finder(model_connector);
types = finder.select().where().eq(L"attachment_id", id).get_vector();
}
}
void after_insert()
{
get_last_sequence(L"public.attachment_id_seq", id);
get_last_sequence_for_primary_key(L"public.attachment_id_seq", id);
}

119
samples/attachment2.h Normal file
View File

@ -0,0 +1,119 @@
/*
* 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_samples_attachment2
#define headerfile_morm_samples_attachment2
#include <string>
#include "morm.h"
#include "type.h"
#include "language.h"
namespace morm
{
namespace samples
{
/*
CREATE TABLE public.attachment2 (
id bigserial,
person_id bigint,
name varchar(64),
content text,
some_flags bool,
created_date timestamp with time zone,
language_id bigint,
primary key(id)
);
*/
// copied from Attachment and changed the table name
class Attachment2 : public morm::Model
{
public:
long id;
long person_id;
std::wstring name;
std::string content;
std::vector<Type> types;
bool some_flags;
pt::Date created_date;
Language language;
void map_fields()
{
field(L"id", id, FT::no_insertable | FT::no_updatable | FT::primary_key);
field(L"person_id", person_id);
field(L"name", name);
field(L"content", content);
field(L"attachment_id", L"types", types, FT::foreign_key_in_child);
field(L"some_flags", some_flags);
field(L"created_date", created_date);
field(L"language_id", L"language", language, FT::foreign_key);
}
void prepare_table()
{
table(L"public", L"attachment2");
}
void after_select()
{
if( has_primary_key_set )
{
morm::Finder<Type> finder(model_connector);
types = finder.select().where().eq(L"attachment_id", id).get_vector();
}
}
void after_insert()
{
get_last_sequence_for_primary_key(L"public.attachment2_id_seq", id);
}
};
}
}
#endif

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2019, Tomasz Sowa
* Copyright (c) 2019-2021, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -70,23 +70,21 @@ public:
void map_fields()
{
field(L"id", id, false, false, true);
field(L"id", id, FT::no_insertable | FT::no_updatable | FT::primary_key);
field(L"english_name", english_name);
field(L"local_name", local_name);
field(L"code_str", code_str);
field(L"code_int", code_int);
}
void table_name(PT::TextStream & stream)
void prepare_table()
{
// schema.table_name or just table_name
stream << "public.language";
table(L"public", L"language");
}
void after_insert()
{
get_last_sequence(L"public.language_id_seq", id);
get_last_sequence_for_primary_key(L"public.language_id_seq", id);
}

View File

@ -61,17 +61,17 @@ void print_syntax()
int main(int argc, const char ** argv)
{
PT::Space args;
PT::Space & args_options = args.FindAddSpace(L"options");
pt::Space args;
pt::Space & args_options = args.FindAddSpace(L"options");
args_options.Add(L"c", 1); // one argument - config file
args_options.Add(L"config", 1);
PT::MainSpaceParser main_parser;
pt::MainSpaceParser main_parser;
main_parser.UTF8(true);
main_parser.SetSpace(args);
PT::MainSpaceParser::Status args_status = main_parser.Parse(argc, argv);
pt::MainSpaceParser::Status args_status = main_parser.Parse(argc, argv);
if( args_status != PT::MainSpaceParser::status_ok )
if( args_status != pt::MainSpaceParser::status_ok )
{
std::cout << "Syntax error in arguments" << std::endl;
return 1;
@ -101,9 +101,9 @@ args_options.Add(L"config", 1);
* create database morm_test owner morm_test;
*
*/
PT::Log log;
PT::FileLog file_log;
PT::WTextStream log_buffer;
pt::Log log;
pt::FileLog file_log;
pt::WTextStream log_buffer;
file_log.init(L"log.txt", true, 4, true);
log.SetLogBuffer(&log_buffer);

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2019, Tomasz Sowa
* Copyright (c) 2019-2021, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -39,6 +39,7 @@
#include "morm.h"
#include "language.h"
#include "attachment.h"
#include "attachment2.h"
@ -64,48 +65,49 @@ class Person : public morm::Model
public:
long id;
std::wstring first_name;
std::wstring last_name;
std::wstring email;
Language language;
std::list<Attachment> attachments;
Attachment attachment;
Attachment2 attachment2;
void map_fields()
{
field(L"id", id, false, false, true);
//field(L"id", id, f::no_insertable | f::no_updatable | f::primary_key);
field(L"id", id, FT::no_insertable | FT::no_updatable | FT::primary_key);
field(L"language_id", L"language", language, FT::foreign_key);
field(L"first_name", first_name);
field(L"last_name", last_name);
field(L"email", email);
field(L"language_id", L"language", language);
field(L"person_id", L"attachments", attachments);
field(L"person_id", L"attachment", attachment, true, true, false);
//field(L"person_id", attachment, f::insertable | f::updatable | f::foreign_key);
//field(L"person_id", attachment, f::insertable, f::updatable, f::foreign_key);
field(L"person_id", L"attachments", attachments, FT::foreign_key_in_child);
field(L"person_id", L"attachment2", attachment2, FT::foreign_key_in_child | FT::no_insertable | FT::no_updatable);
}
void table_name(PT::TextStream & stream)
void prepare_table()
{
// schema.table_name or just table_name
stream << "public.person";
table(L"public", L"person");
}
void after_select()
{
morm::Finder<Attachment> finder(model_connector);
attachments = finder.select().where().eq(L"person_id", id).get_list();
if( has_primary_key_set )
{
morm::Finder<Attachment> finder(model_connector);
attachments = finder.select().where().eq(L"person_id", id).get_list();
morm::Finder<Attachment2> finder2(model_connector);
attachment2 = finder2.select().where().eq(L"person_id", id).get();
}
}
void after_insert()
{
get_last_sequence(L"public.person_id_seq", id);
get_last_sequence_for_primary_key(L"public.person_id_seq", id);
}

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2019, Tomasz Sowa
* Copyright (c) 2019-2021, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -32,6 +32,9 @@
*
*/
#ifndef headerfile_morm_samples_sample01
#define headerfile_morm_samples_sample01
#include <ctime>
#include "basesample.h"
#include "person.h"
@ -51,23 +54,37 @@ public:
void make()
{
// delete all datas
// delete from attachment; delete from attachment2; delete from language; delete from person; delete from types;
// select * from person; select * from attachment; select * from attachment2 ; select * from types; select * from language;
std::string str;
person.set_connector(model_connector);
load_defaults(person);
std::wstring sss = L"cosik wstawiony dynamicznie";
person.set_field_value_generic(L"email", L"email", sss);
//std::wstring sss = L"some text put dynamically";
//person.set_field_value_generic(L"email", L"email", sss);
//person.insert();
//person.update();
person.save();
//person.save();
//person.remove();
//person.to_text(str, true, true);
morm::Finder<Person> finder(model_connector);
Person p = finder.select().where().eq(L"id", 210).get();
p.to_text(str, true, true);
//std::list<Person> plist = finder.use_table_prefix(false).select().where().eq(L"id", 120).get_list();
//Person p = finder.use_table_prefix(false).select().where().eq(L"id", 120).get();
// Person p = finder.prepare_to_select().use_table_prefix(true).raw("select person.id as \"person.id\", person.first_name as \"person.first_name\", person.last_name as \"person.last_name\", person.email as \"person.email\", "
// "language.id as \"language.id\", language.english_name as \"language.english_name\", language.local_name as \"language.local_name\", language.code_str as \"language.code_str\", language.code_int as \"language.code_int\", "
@ -79,14 +96,13 @@ void make()
// "LEFT JOIN public.language AS language2 ON attachment.language_id = language2.id "
// "where person.id=120").get();
std::cout << "--------------------------------" << std::endl;
//std::cout << "--------------------------------" << std::endl;
//p.remove();
//std::cout << "--------------------------------" << std::endl;
std::string str;
//str += "--------\n";
person.to_text(str, true, true);
// for(Person & person : plist)
// {
@ -112,6 +128,7 @@ private:
person.first_name = L"MyFirstName";
person.last_name = L"MyLastName";
person.email = L"myemail@mydomain.ltd";
//person.set_save_mode(Model::DO_NOTHING_ON_SAVE);
person.set_save_mode(Model::DO_INSERT_ON_SAVE);
//person.set_save_mode(Model::DO_UPDATE_ON_SAVE);
@ -120,29 +137,38 @@ private:
person.language.local_name = L"polish";
person.language.code_str = L"en";
person.language.code_int = 200;
//person.language.set_save_mode(Model::DO_NOTHING_ON_SAVE);
person.language.set_save_mode(Model::DO_INSERT_ON_SAVE);
//person.language.set_save_mode(Model::DO_UPDATE_ON_SAVE);
std::time_t t = std::time(0);
// person.attachment.id = 40;
person.attachment.person_id = person.id;
person.attachment.created_date.FromTime(t);
person.attachment.name = L"attachment name";
person.attachment.content = "long binary content";
person.attachment.some_flags = true;
person.attachment.set_save_mode(Model::DO_INSERT_ON_SAVE);
// //person.attachment.set_save_mode(Model::DO_UPDATE_ON_SAVE);
//
person.attachment.language.id = 86;
person.attachment.language.english_name = L"attachment language";
person.attachment.language.local_name = L"attachment local name";
person.attachment.language.code_str = L"loen";
person.attachment.language.code_int = 300;
// person.attachment.language.set_save_mode(Model::DO_UPDATE_ON_SAVE);
Type type;
type.id = 0;
type.set_save_mode(Model::DO_INSERT_ON_SAVE);
person.attachment2.id = 40;
person.attachment2.person_id = person.id;
person.attachment2.created_date.FromTime(t);
person.attachment2.name = L"attachment name";
person.attachment2.content = "long binary content";
person.attachment2.some_flags = true;
person.attachment2.set_save_mode(Model::DO_INSERT_ON_SAVE);
// //person.attachment.set_save_mode(Model::DO_UPDATE_ON_SAVE);
person.attachment2.language.id = 86;
person.attachment2.language.english_name = L"attachment language";
person.attachment2.language.local_name = L"attachment local name";
person.attachment2.language.code_str = L"loen";
person.attachment2.language.code_int = 300;
person.attachment2.language.set_save_mode(Model::DO_INSERT_ON_SAVE);
person.attachment2.language.set_has_primary_key_set(true);
type.name = L"abcde - fghi";
person.attachment2.types.push_back(type);
type.name = L"second type";
person.attachment2.types.push_back(type);
Attachment attachment;
attachment.id = 0;
@ -186,7 +212,6 @@ private:
type.name = L"Typ dla attachment 3 - 3";
person.attachments.back().types.push_back(type);
//type.name = L"Typik";
//person.attachment.types.push_back(type);
@ -201,3 +226,5 @@ private:
}
}
#endif

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2019, Tomasz Sowa
* Copyright (c) 2019-2021, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -65,21 +65,19 @@ public:
void map_fields()
{
field(L"id", id, false, false, true);
field(L"id", id, FT::no_insertable | FT::no_updatable | FT::primary_key);
field(L"attachment_id", attachment_id);
field(L"name", name);
}
void table_name(PT::TextStream & stream)
void prepare_table()
{
// schema.table_name or just table_name
stream << "public.types";
table(L"public", L"types");
}
void after_insert()
{
get_last_sequence(L"public.types_id_seq", id);
get_last_sequence_for_primary_key(L"public.types_id_seq", id);
}

View File

@ -1,162 +1,49 @@
# DO NOT DELETE
baseexpression.o: baseexpression.h ../../pikotools/textstream/textstream.h
baseexpression.o: ../../pikotools/space/space.h
baseexpression.o: ../../pikotools/textstream/types.h
baseexpression.o: ../../pikotools/date/date.h
baseexpression.o: ../../pikotools/convert/inttostr.h
baseexpression.o: ../../pikotools/membuffer/membuffer.h
baseexpression.o: ../../pikotools/textstream/types.h morm_types.h modelenv.h
baseexpression.o: modeldata.h cursorhelper.h queryresult.h
baseexpression.o: ../../pikotools/log/log.h ../../pikotools/log/filelog.h
baseexpression.o: finderhelper.h fieldvaluehelper.h model.h modelconnector.h
baseexpression.o: clearer.h dbconnector.h flatconnector.h dbexpression.h
baseexpression.o: flatexpression.h ../../pikotools/utf8/utf8.h
clearer.o: clearer.h ../../pikotools/date/date.h
clearer.o: ../../pikotools/convert/inttostr.h model.h
clearer.o: ../../pikotools/textstream/textstream.h
clearer.o: ../../pikotools/space/space.h ../../pikotools/textstream/types.h
clearer.o: ../../pikotools/membuffer/membuffer.h
clearer.o: ../../pikotools/textstream/types.h modelconnector.h dbconnector.h
clearer.o: ../../pikotools/log/log.h ../../pikotools/log/filelog.h
clearer.o: queryresult.h flatconnector.h dbexpression.h baseexpression.h
clearer.o: morm_types.h modelenv.h modeldata.h cursorhelper.h finderhelper.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
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
dbconnector.o: dbconnector.h ../../pikotools/textstream/textstream.h
dbconnector.o: ../../pikotools/space/space.h
dbconnector.o: ../../pikotools/textstream/types.h ../../pikotools/date/date.h
dbconnector.o: ../../pikotools/convert/inttostr.h
dbconnector.o: ../../pikotools/membuffer/membuffer.h
dbconnector.o: ../../pikotools/textstream/types.h ../../pikotools/log/log.h
dbconnector.o: ../../pikotools/log/filelog.h queryresult.h dbexpression.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: ../../pikotools/utf8/utf8.h ../../pikotools/convert/convert.h
dbconnector.o: ../../pikotools/convert/inttostr.h
dbconnector.o: ../../pikotools/convert/patternreplacer.h
dbconnector.o: ../../pikotools/convert/strtoint.h
dbconnector.o: ../../pikotools/convert/text.h ../../pikotools/convert/misc.h
dbexpression.o: dbexpression.h baseexpression.h
dbexpression.o: ../../pikotools/textstream/textstream.h
dbexpression.o: ../../pikotools/space/space.h
dbexpression.o: ../../pikotools/textstream/types.h
dbexpression.o: ../../pikotools/date/date.h
dbexpression.o: ../../pikotools/convert/inttostr.h
dbexpression.o: ../../pikotools/membuffer/membuffer.h
dbexpression.o: ../../pikotools/textstream/types.h morm_types.h modelenv.h
dbexpression.o: modeldata.h cursorhelper.h queryresult.h
dbexpression.o: ../../pikotools/log/log.h ../../pikotools/log/filelog.h
dbexpression.o: finderhelper.h fieldvaluehelper.h
flatconnector.o: flatconnector.h ../../pikotools/textstream/textstream.h
flatconnector.o: ../../pikotools/space/space.h
flatconnector.o: ../../pikotools/textstream/types.h
flatconnector.o: ../../pikotools/date/date.h
flatconnector.o: ../../pikotools/convert/inttostr.h
flatconnector.o: ../../pikotools/membuffer/membuffer.h
flatconnector.o: ../../pikotools/textstream/types.h flatexpression.h
flatconnector.o: baseexpression.h morm_types.h modelenv.h modeldata.h
flatconnector.o: cursorhelper.h queryresult.h ../../pikotools/log/log.h
flatconnector.o: ../../pikotools/log/filelog.h finderhelper.h
flatconnector.o: fieldvaluehelper.h model.h modelconnector.h clearer.h
flatconnector.o: dbconnector.h dbexpression.h
flatexpression.o: flatexpression.h baseexpression.h
flatexpression.o: ../../pikotools/textstream/textstream.h
flatexpression.o: ../../pikotools/space/space.h
flatexpression.o: ../../pikotools/textstream/types.h
flatexpression.o: ../../pikotools/date/date.h
flatexpression.o: ../../pikotools/convert/inttostr.h
flatexpression.o: ../../pikotools/membuffer/membuffer.h
flatexpression.o: ../../pikotools/textstream/types.h morm_types.h modelenv.h
flatexpression.o: modeldata.h cursorhelper.h queryresult.h
flatexpression.o: ../../pikotools/log/log.h ../../pikotools/log/filelog.h
flatexpression.o: finderhelper.h fieldvaluehelper.h
jsonconnector.o: jsonconnector.h flatconnector.h
jsonconnector.o: ../../pikotools/textstream/textstream.h
jsonconnector.o: ../../pikotools/space/space.h
jsonconnector.o: ../../pikotools/textstream/types.h
jsonconnector.o: ../../pikotools/date/date.h
jsonconnector.o: ../../pikotools/convert/inttostr.h
jsonconnector.o: ../../pikotools/membuffer/membuffer.h
jsonconnector.o: ../../pikotools/textstream/types.h jsonexpression.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
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
jsonconnector.o: ../../pikotools/log/log.h ../../pikotools/log/filelog.h
jsonconnector.o: finderhelper.h fieldvaluehelper.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: ../../pikotools/textstream/textstream.h
jsonexpression.o: ../../pikotools/space/space.h
jsonexpression.o: ../../pikotools/textstream/types.h
jsonexpression.o: ../../pikotools/date/date.h
jsonexpression.o: ../../pikotools/convert/inttostr.h
jsonexpression.o: ../../pikotools/membuffer/membuffer.h
jsonexpression.o: ../../pikotools/textstream/types.h morm_types.h modelenv.h
jsonexpression.o: modeldata.h cursorhelper.h queryresult.h
jsonexpression.o: ../../pikotools/log/log.h ../../pikotools/log/filelog.h
jsonexpression.o: finderhelper.h fieldvaluehelper.h
model.o: model.h ../../pikotools/textstream/textstream.h
model.o: ../../pikotools/space/space.h ../../pikotools/textstream/types.h
model.o: ../../pikotools/date/date.h ../../pikotools/convert/inttostr.h
model.o: ../../pikotools/membuffer/membuffer.h
model.o: ../../pikotools/textstream/types.h modelconnector.h clearer.h
model.o: dbconnector.h ../../pikotools/log/log.h
model.o: ../../pikotools/log/filelog.h queryresult.h flatconnector.h
model.o: dbexpression.h baseexpression.h morm_types.h modelenv.h modeldata.h
model.o: cursorhelper.h finderhelper.h fieldvaluehelper.h flatexpression.h
modelconnector.o: modelconnector.h clearer.h ../../pikotools/date/date.h
modelconnector.o: ../../pikotools/convert/inttostr.h dbconnector.h
modelconnector.o: ../../pikotools/textstream/textstream.h
modelconnector.o: ../../pikotools/space/space.h
modelconnector.o: ../../pikotools/textstream/types.h
modelconnector.o: ../../pikotools/membuffer/membuffer.h
modelconnector.o: ../../pikotools/textstream/types.h
modelconnector.o: ../../pikotools/log/log.h ../../pikotools/log/filelog.h
modelconnector.o: queryresult.h flatconnector.h
postgresqlconnector.o: postgresqlconnector.h dbconnector.h
postgresqlconnector.o: ../../pikotools/textstream/textstream.h
postgresqlconnector.o: ../../pikotools/space/space.h
postgresqlconnector.o: ../../pikotools/textstream/types.h
postgresqlconnector.o: ../../pikotools/date/date.h
postgresqlconnector.o: ../../pikotools/convert/inttostr.h
postgresqlconnector.o: ../../pikotools/membuffer/membuffer.h
postgresqlconnector.o: ../../pikotools/textstream/types.h
postgresqlconnector.o: ../../pikotools/log/log.h
postgresqlconnector.o: ../../pikotools/log/filelog.h queryresult.h
postgresqlconnector.o: postgresqlqueryresult.h ../../pikotools/utf8/utf8.h
postgresqlconnector.o: postgresqlexpression.h dbexpression.h baseexpression.h
postgresqlconnector.o: morm_types.h modelenv.h modeldata.h cursorhelper.h
postgresqlconnector.o: finderhelper.h fieldvaluehelper.h
postgresqlconnector.o: ../../pikotools/convert/strtoint.h
postgresqlconnector.o: ../../pikotools/convert/text.h
postgresqlconnector.o: ../../pikotools/convert/misc.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
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
postgresqlexpression.o: ../../pikotools/textstream/textstream.h
postgresqlexpression.o: ../../pikotools/space/space.h
postgresqlexpression.o: ../../pikotools/textstream/types.h
postgresqlexpression.o: ../../pikotools/date/date.h
postgresqlexpression.o: ../../pikotools/convert/inttostr.h
postgresqlexpression.o: ../../pikotools/membuffer/membuffer.h
postgresqlexpression.o: ../../pikotools/textstream/types.h morm_types.h
postgresqlexpression.o: modelenv.h modeldata.h cursorhelper.h queryresult.h
postgresqlexpression.o: ../../pikotools/log/log.h
postgresqlexpression.o: ../../pikotools/log/filelog.h finderhelper.h
postgresqlexpression.o: fieldvaluehelper.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
postgresqlqueryresult.o: ../../pikotools/log/log.h
postgresqlqueryresult.o: ../../pikotools/textstream/textstream.h
postgresqlqueryresult.o: ../../pikotools/space/space.h
postgresqlqueryresult.o: ../../pikotools/textstream/types.h
postgresqlqueryresult.o: ../../pikotools/date/date.h
postgresqlqueryresult.o: ../../pikotools/convert/inttostr.h
postgresqlqueryresult.o: ../../pikotools/membuffer/membuffer.h
postgresqlqueryresult.o: ../../pikotools/textstream/types.h
postgresqlqueryresult.o: ../../pikotools/log/filelog.h
queryresult.o: queryresult.h ../../pikotools/log/log.h
queryresult.o: ../../pikotools/textstream/textstream.h
queryresult.o: ../../pikotools/space/space.h
queryresult.o: ../../pikotools/textstream/types.h ../../pikotools/date/date.h
queryresult.o: ../../pikotools/convert/inttostr.h
queryresult.o: ../../pikotools/membuffer/membuffer.h
queryresult.o: ../../pikotools/textstream/types.h
queryresult.o: ../../pikotools/log/filelog.h ../../pikotools/utf8/utf8.h
queryresult.o: queryresult.h

File diff suppressed because it is too large Load Diff

View File

@ -41,7 +41,7 @@
#include "date/date.h"
#include "morm_types.h"
#include "modelenv.h"
#include "ft.h"
namespace morm
@ -60,11 +60,14 @@ public:
virtual void set_work_mode(int work_mode);
virtual int get_work_mode();
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);
virtual PT::TextStream * get_current_stream();
virtual pt::TextStream * get_current_stream();
// rename me
virtual void allow_to_use_prefix(bool use_prefix);
@ -73,25 +76,25 @@ public:
template<typename FieldValue>
void field(const wchar_t * field_name, const FieldValue & field_value, bool insertable, bool updatable, bool is_primary_key, ModelEnv * model_env)
void field(const wchar_t * field_name, const FieldValue & field_value, const FT & field_type, ModelEnv * model_env)
{
if( out_stream && can_field_be_generated(insertable, updatable, is_primary_key) )
if( out_stream && can_field_be_generated(field_type) )
{
field_before();
if( work_mode == MORM_WORK_MODE_MODEL_FIELDS )
{
put_field_name(field_name, model_env);
put_field_name_and_table_if_needed(field_name, field_type, model_env);
}
else
if( work_mode == MORM_WORK_MODE_MODEL_SAVE_FIELDS )
{
save_foreign_key(field_name, model_env);
save_foreign_key(field_name, field_type, model_env);
}
else
if( work_mode == MORM_WORK_MODE_MODEL_VALUES )
{
put_field_value(field_value);
put_field_value_or_null(field_value, field_type, model_env);
}
else
if( work_mode == MORM_WORK_MODE_MODEL_FIELDS_VALUES )
@ -100,18 +103,18 @@ public:
{
if( (size_t)model_env->field_index < model_env->set_field_name_helper->size() )
{
put_field_name((*model_env->set_field_name_helper)[model_env->field_index], model_env);
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(field_value);
put_field_value_or_null(field_value, field_type, model_env);
}
model_env->field_index += 1;
}
else
{
put_field_name(field_name, model_env);
put_field_name_and_table_if_needed(field_name, field_type, model_env);
put_name_value_separator();
put_field_value(field_value);
put_field_value_or_null(field_value, field_type, model_env);
}
}
@ -121,43 +124,60 @@ public:
}
template<typename FieldValue>
void field_in(PT::TextStream & stream, const wchar_t * field_name, const std::set<FieldValue> & container, ModelEnv * model_env)
void put_field_value_or_null(const FieldValue & field_value, const FT & field_type, ModelEnv * model_env)
{
if( field_type.is_primary_key() )
{
if( model_env && model_env->has_primary_key_set )
put_field_value(field_value, field_type);
else
put_null_value();
}
else
{
put_field_value(field_value, field_type);
}
}
template<typename FieldValue>
void field_in(pt::TextStream & stream, const wchar_t * field_name, const std::set<FieldValue> & container, ModelEnv * model_env)
{
field_in_generic<FieldValue, std::set<FieldValue>>(stream, field_name, container, model_env);
}
template<typename FieldValue>
void field_in(PT::TextStream & stream, const wchar_t * field_name, const std::list<FieldValue> & container, ModelEnv * model_env)
void field_in(pt::TextStream & stream, const wchar_t * field_name, const std::list<FieldValue> & container, ModelEnv * model_env)
{
field_in_generic<FieldValue, std::list<FieldValue>>(stream, field_name, container, model_env);
}
template<typename FieldValue>
void field_in(PT::TextStream & stream, const wchar_t * field_name, const std::vector<FieldValue> & container, ModelEnv * model_env)
void field_in(pt::TextStream & stream, const wchar_t * field_name, const std::vector<FieldValue> & container, ModelEnv * model_env)
{
field_in_generic<FieldValue, std::vector<FieldValue>>(stream, field_name, container, model_env);
}
template<typename ModelContainer>
void field_list(const wchar_t * field_name, ModelContainer & field_value, bool insertable, bool updatable, bool is_primary_key,
ModelConnector * model_connector, ModelEnv * model_env)
void field_list(const wchar_t * field_name, ModelContainer & field_value, const FT & field_type, ModelConnector * model_connector, ModelEnv * model_env)
{
if( out_stream && can_field_be_generated(insertable, updatable, is_primary_key) )
if( out_stream && can_field_be_generated(field_type) )
{
field_before();
// if( work_mode == MORM_WORK_MODE_MODEL_FIELDS )
// {
// put_field_name(field_name);
// put_field_name_and_table_if_needed(field_name);
// }
// else
if( work_mode == MORM_WORK_MODE_MODEL_FIELDS_VALUES )
{
put_field_name(field_name, model_env);
put_field_name_and_table_if_needed(field_name, field_type, model_env);
put_name_value_separator();
put_field_value_list(field_value, model_connector, model_env);
}
@ -167,15 +187,15 @@ public:
}
template<typename ModelClass>
void field_model(const wchar_t * field_name, ModelClass & field_model, bool insertable, bool updatable, bool is_primary_key, ModelEnv * model_env)
void field_model(const wchar_t * field_name, ModelClass & field_model, const FT & field_type, ModelEnv * model_env)
{
if( out_stream && can_field_be_generated(insertable, updatable, is_primary_key) )
if( out_stream && can_field_be_generated(field_type) )
{
field_before();
if( work_mode == MORM_WORK_MODE_MODEL_FIELDS )
{
put_field_name(field_name, model_env);
put_field_name_and_table_if_needed(field_name, field_type, model_env);
}
else
if( work_mode == MORM_WORK_MODE_MODEL_VALUES )
@ -185,7 +205,7 @@ public:
else
if( work_mode == MORM_WORK_MODE_MODEL_FIELDS_VALUES )
{
put_field_name(field_name, model_env);
put_field_name_and_table_if_needed(field_name, field_type, model_env);
put_name_value_separator();
generate_from_model(field_model);
}
@ -195,53 +215,71 @@ public:
}
template<typename FieldValue>
void field_to_stream(PT::TextStream & stream, const wchar_t * field_name, const FieldValue & field_value, bool insertable, bool updatable, bool is_primary_key,
ModelEnv * model_env)
void field_to_stream(pt::TextStream & stream, const wchar_t * field_name, const FieldValue & field_value, const FT & field_type, ModelEnv * model_env)
{
this->out_stream = &stream;
field(field_name, field_value, insertable, updatable, is_primary_key, model_env);
field(field_name, 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);
virtual void put_table(const pt::WTextStream & table_name);
virtual void put_table_with_index(const wchar_t * table_name, int index);
virtual void put_table_with_index(const pt::WTextStream & table_name, int index);
virtual void put_table_with_index_and_field(const wchar_t * table_name, int index, const wchar_t * field_name, const FT & field_type);
virtual void put_table_with_index_and_field(const pt::WTextStream & table_name, int index, const wchar_t * field_name, const FT & field_type);
virtual void put_table_and_field(const wchar_t * table_name, const wchar_t * field_name, const FT & field_type);
virtual void put_table_and_field(const pt::WTextStream & table_name, const wchar_t * field_name, const FT & field_type);
virtual void schema_table_to_stream(pt::TextStream & stream, const wchar_t * schema_name, const wchar_t * table_name);
virtual void schema_table_to_stream(pt::TextStream & stream, const pt::WTextStream & schema_name, const pt::WTextStream & table_name);
virtual void table_to_stream(pt::TextStream & stream, const wchar_t * table_name);
virtual void table_to_stream(pt::TextStream & stream, const pt::WTextStream & table_name);
virtual void table_with_index_to_stream(pt::TextStream & stream, const wchar_t * table_name, int index);
virtual void table_with_index_to_stream(pt::TextStream & stream, const pt::WTextStream & table_name, int index);
virtual void table_with_index_and_field_to_stream(pt::TextStream & stream, const wchar_t * table_name, int index, const wchar_t * field_name, const FT & field_type);
virtual void table_with_index_and_field_to_stream(pt::TextStream & stream, const pt::WTextStream & table_name, int index, const wchar_t * field_name, const FT & field_type);
virtual void table_and_field_to_stream(pt::TextStream & stream, const wchar_t * table_name, const wchar_t * field_name, const FT & field_type);
virtual void table_and_field_to_stream(pt::TextStream & stream, const pt::WTextStream & table_name, const wchar_t * field_name, const FT & field_type);
/*
* IMPLEMENT ME
* esc for: signed char, wchar_t, char16_t, char32_t
*
*/
virtual void esc(char val, PT::TextStream & stream);
virtual void esc(unsigned char val, PT::TextStream & stream);
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(wchar_t val, PT::TextStream & stream);
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);
virtual void esc(const wchar_t * val, PT::TextStream & stream);
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);
virtual void esc(const char * val, PT::TextStream & stream);
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);
virtual void esc(short val, PT::TextStream & stream);
virtual void esc(unsigned short val, PT::TextStream & stream);
virtual void esc(int val, PT::TextStream & stream);
virtual void esc(unsigned int val, PT::TextStream & stream);
virtual void esc(long val, PT::TextStream & stream);
virtual void esc(unsigned long val, PT::TextStream & stream);
virtual void esc(long long val, PT::TextStream & stream);
virtual void esc(unsigned long long val, PT::TextStream & stream);
virtual void esc(float val, PT::TextStream & stream);
virtual void esc(double val, PT::TextStream & stream);
virtual void esc(long double val, PT::TextStream & stream);
//virtual void esc(void* val, PT::TextStream & stream);
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);
virtual void esc(const PT::TextStream & val,PT::TextStream & stream);
virtual bool is_long_field_name(const wchar_t * field_name);
virtual bool is_long_field_name(const PT::TextStream & table_name);
virtual bool is_long_table_name(const wchar_t * field_name);
virtual bool is_long_table_name(const PT::TextStream & table_name);
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);
@ -250,7 +288,7 @@ protected:
int work_mode; /* what to do: generating fields list, values list or fields-values list */
bool is_first_field;
PT::TextStream * out_stream;
pt::TextStream * out_stream;
bool use_prefix;
@ -258,30 +296,34 @@ protected:
virtual void before_generate_from_model();
virtual void after_generate_from_model();
virtual bool can_field_be_generated(bool insertable, bool updatable, bool is_primary_key);
virtual bool can_field_be_generated(const FT &);
virtual void field_before();
virtual void field_after();
//void field(const wchar_t * field_name, Model & field, bool insertable = true, bool updatable = true);
virtual void put_field_name(const wchar_t * field_name, ModelEnv * model_env);
virtual void save_foreign_key(const wchar_t * field_name, ModelEnv * model_env);
virtual void put_field_name_and_table_if_needed(const wchar_t * field_name, const FT & field_type, ModelEnv * model_env);
virtual void put_field_name(const wchar_t * field_name, const FT & field_type, ModelEnv * model_env);
virtual void save_foreign_key(const wchar_t * field_name, const FT & field_type, ModelEnv * model_env);
virtual void dump_additional_info(Model & model);
template<typename FieldValue>
void put_field_value(const FieldValue & field_value)
void put_field_value(const FieldValue & field_value, const FT & field_type)
{
if( out_stream )
{
before_field_value(field_value);
esc(field_value, *out_stream);
after_field_value(field_value);
before_field_value(field_value, field_type);
esc(field_value, *out_stream, field_type);
after_field_value(field_value, field_type);
}
}
virtual void put_null_value()
{
(*out_stream) << "null";
}
virtual void before_field_value_list()
{
}
@ -323,16 +365,7 @@ protected:
field_value_list_separator();
}
//ModelEnv model_env_local(*model_env);
//m.model_env = &model_env_local;
//before_field_value(field_value);
//m.set_connector(model_connector);
put_field_value(m);
//generate_from_model(m);
//m.model_env = nullptr;
//after_field_value(field_value);
put_field_value(m, FT::default_type);
is_first = false;
}
@ -358,11 +391,12 @@ protected:
ModelEnv model_env_local(*model_env);
m.model_env = &model_env_local;
//before_field_value(field_value);
m.model_env->has_primary_key_set = m.get_has_primary_key_set();
m.set_connector(model_connector);
generate_from_model(m);
m.model_env = nullptr;
//after_field_value(field_value);
is_first = false;
}
@ -451,7 +485,7 @@ protected:
put_field_value_list_non_model(field_value, model_connector);
}
void put_field_value_list(std::vector<PT::Date> & field_value, ModelConnector * model_connector, ModelEnv *)
void put_field_value_list(std::vector<pt::Date> & field_value, ModelConnector * model_connector, ModelEnv *)
{
put_field_value_list_non_model(field_value, model_connector);
}
@ -540,7 +574,7 @@ protected:
put_field_value_list_non_model(field_value, model_connector);
}
void put_field_value_list(std::list<PT::Date> & field_value, ModelConnector * model_connector, ModelEnv *)
void put_field_value_list(std::list<pt::Date> & field_value, ModelConnector * model_connector, ModelEnv *)
{
put_field_value_list_non_model(field_value, model_connector);
}
@ -549,7 +583,7 @@ protected:
// used in 'in()' statements, may should be renamed?
template<typename FieldValue, typename Container>
void field_in_generic(PT::TextStream & stream, const wchar_t * field_name, const Container & container, ModelEnv * model_env)
void field_in_generic(pt::TextStream & stream, const wchar_t * field_name, const Container & container, ModelEnv * model_env)
{
// IMPROVE ME
// what about if container is empty?
@ -557,7 +591,7 @@ protected:
this->out_stream = &stream;
field_before();
put_field_name(field_name, model_env);
put_field_name_and_table_if_needed(field_name, FT::default_type, model_env);
put_name_value_separator();
bool is_first = true;
@ -570,7 +604,7 @@ protected:
field_value_list_separator();
}
put_field_value(v);
put_field_value(v, FT::default_type);
is_first = false;
}
@ -580,50 +614,50 @@ protected:
}
/*
* escaping column names in a case when using short form - just only column_name
* [before_short_field_name]column_name[after_short_field_name]
*/
virtual void before_short_field_name();
virtual void after_short_field_name();
virtual void schema_table_separator();
virtual void table_field_separator();
/*
* escaping column names in a case when using long form: table_name.column_name
* [before_first_part_long_field_name]table_name[after_first_part_long_field_name].[before_second_part_long_field_name]column_name[after_second_part_long_field_name]
*
*/
virtual void before_first_part_long_field_name();
virtual void after_first_part_long_field_name();
virtual void before_second_part_long_field_name();
virtual void after_second_part_long_field_name();
virtual void before_schema_name();
virtual void after_schema_name();
virtual const wchar_t * put_long_part_field_name(const wchar_t * field_name);
virtual void put_long_field_name(const wchar_t * field_name);
virtual void put_short_field_name(const wchar_t * field_name, ModelEnv * model_env);
virtual void before_table_name();
virtual void after_table_name();
virtual void before_field_value(const std::wstring &);
virtual void after_field_value(const std::wstring &);
virtual void before_field_name();
virtual void after_field_name();
virtual void before_field_value(const std::string &);
virtual void after_field_value(const std::string &);
virtual void before_field_value(const wchar_t *);
virtual void after_field_value(const wchar_t *);
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 char *);
virtual void after_field_value(const char *);
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 PT::Date &);
virtual void after_field_value(const PT::Date &);
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);
virtual void after_field_value(const char *, const FT & field_type);
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);
virtual void after_field_value(char, const FT & field_type);
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);
virtual void after_field_value(const pt::Space &, const FT & field_type);
template<typename FieldValue>
void before_field_value(const FieldValue &)
void before_field_value(const FieldValue &, const FT & field_type)
{
}
template<typename FieldValue>
void after_field_value(const FieldValue &)
void after_field_value(const FieldValue &, const FT & field_type)
{
}
@ -635,44 +669,55 @@ protected:
* put_type for: signed char, wchar_t, char16_t, char32_t
*
*/
virtual void put_type(char val, PT::TextStream & stream);
virtual void put_type(unsigned char val, PT::TextStream & stream);
// virtual void put_type(char val, pt::TextStream & stream);
// virtual void put_type(unsigned char val, pt::TextStream & stream);
//
// virtual void put_type(const std::wstring & val, pt::TextStream & stream);
// virtual void put_type(const wchar_t * val, pt::TextStream & stream);
//
// virtual void put_type(const std::string & val, pt::TextStream & stream);
// virtual void put_type(const char * val, pt::TextStream & stream);
//
// virtual void put_type(bool val, pt::TextStream & stream);
// virtual void put_type(short val, pt::TextStream & stream);
// virtual void put_type(unsigned short val, pt::TextStream & stream);
// virtual void put_type(int val, pt::TextStream & stream);
// virtual void put_type(unsigned int val, pt::TextStream & stream);
// virtual void put_type(long val, pt::TextStream & stream);
// virtual void put_type(unsigned long val, pt::TextStream & stream);
// virtual void put_type(long long val, pt::TextStream & stream);
// virtual void put_type(unsigned long long val, pt::TextStream & stream);
// virtual void put_type(float val, pt::TextStream & stream);
// virtual void put_type(double val, pt::TextStream & stream);
// virtual void put_type(long double val, pt::TextStream & stream);
//virtual void put_type(void* val, pt::TextStream & stream);
virtual void put_type(const std::wstring & val, PT::TextStream & stream);
virtual void put_type(const wchar_t * val, PT::TextStream & stream);
// virtual void put_type(const pt::Date & date, pt::TextStream & stream);
// virtual void put_type(const Model & model, pt::TextStream & stream);
//
// template<typename ListType>
// void put_type(const std::list<ListType> & model, pt::TextStream & stream)
// {
// stream << "table"; // may just use std::list?
// }
//
// template<typename ListType>
// void put_type(const std::vector<ListType> & model, pt::TextStream & stream)
// {
// stream << "table"; // may just just std::vector?
// }
virtual void put_type(const std::string & val, PT::TextStream & stream);
virtual void put_type(const char * val, PT::TextStream & stream);
virtual void put_type(bool val, PT::TextStream & stream);
virtual void put_type(short val, PT::TextStream & stream);
virtual void put_type(unsigned short val, PT::TextStream & stream);
virtual void put_type(int val, PT::TextStream & stream);
virtual void put_type(unsigned int val, PT::TextStream & stream);
virtual void put_type(long val, PT::TextStream & stream);
virtual void put_type(unsigned long val, PT::TextStream & stream);
virtual void put_type(long long val, PT::TextStream & stream);
virtual void put_type(unsigned long long val, PT::TextStream & stream);
virtual void put_type(float val, PT::TextStream & stream);
virtual void put_type(double val, PT::TextStream & stream);
virtual void put_type(long double val, PT::TextStream & stream);
//virtual void put_type(void* val, PT::TextStream & stream);
virtual void put_type(const PT::Date & date, PT::TextStream & stream);
virtual void put_type(const Model & model, PT::TextStream & stream);
virtual void before_field_value_string(const FT & field_type);
virtual void after_field_value_string(const FT & field_type);
template<typename ListType>
void put_type(const std::list<ListType> & model, PT::TextStream & stream)
{
stream << "table"; // may just use std::list?
}
char char_to_hex_part(char c);
void char_to_hex(char c, pt::TextStream & stream);
template<typename ListType>
void put_type(const std::vector<ListType> & model, PT::TextStream & stream)
{
stream << "table"; // may just just std::vector?
}
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);
};
}

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2018, Tomasz Sowa
* Copyright (c) 2018-2021, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -61,6 +61,10 @@ void Clearer::clear_value(unsigned char & field_value)
field_value = 0;
}
void Clearer::clear_value(wchar_t & field_value)
{
field_value = 0;
}
void Clearer::clear_value(std::wstring & field_value)
{
@ -134,11 +138,16 @@ void Clearer::clear_value(long double & field_value)
field_value = 0.0;
}
void Clearer::clear_value(PT::Date & field_value)
void Clearer::clear_value(pt::Date & field_value)
{
field_value.Clear();
}
void Clearer::clear_value(pt::Space & field_value)
{
field_value.clear();
}
void Clearer::clear_model(Model & field_value)
{
field_value.clear();

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2018, Tomasz Sowa
* Copyright (c) 2018-2021, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -37,6 +37,7 @@
#include <string>
#include "date/date.h"
#include "space/space.h"
namespace morm
@ -53,6 +54,7 @@ public:
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);
@ -67,7 +69,8 @@ public:
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::Date & field_value);
virtual void clear_value(pt::Space & field_value);
virtual void clear_model(Model & field_value);

View File

@ -193,7 +193,7 @@ public:
if( !cursor_helper.has_autogenerated_select && cursor_helper.use_table_prefix_for_fetching_values )
{
result.prepare_table_names();
result.model_env->add_table_name_to_finder_helper();
}
result.before_select();
@ -369,7 +369,7 @@ protected:
if( !cursor_helper.has_autogenerated_select && cursor_helper.use_table_prefix_for_fetching_values )
{
added_model.prepare_table_names();
added_model.model_env->add_table_name_to_finder_helper();
}
added_model.before_select();

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2018-2019, Tomasz Sowa
* Copyright (c) 2018-2021, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -34,6 +34,7 @@
#include <cstdlib>
#include <memory>
#include "space/spaceparser.h"
#include "dbconnector.h"
#include "dbexpression.h"
#include "model.h"
@ -66,13 +67,13 @@ DbConnector::~DbConnector()
}
void DbConnector::set_logger(PT::Log * log)
void DbConnector::set_logger(pt::Log * log)
{
this->log = log;
}
void DbConnector::set_logger(PT::Log & log)
void DbConnector::set_logger(pt::Log & log)
{
this->log = &log;
}
@ -84,7 +85,29 @@ void DbConnector::set_log_queries(bool log_queries)
}
bool DbConnector::query(const PT::TextStream & stream, QueryResult & query_result)
bool DbConnector::query(const pt::TextStream & stream)
{
std::unique_ptr<QueryResult> query_result_ptr(create_query_result());
return query(stream, *query_result_ptr);
}
bool DbConnector::query(const std::string & query_str)
{
std::unique_ptr<QueryResult> query_result_ptr(create_query_result());
return query(query_str, *query_result_ptr);
}
bool DbConnector::query(const char * query_str)
{
std::unique_ptr<QueryResult> query_result_ptr(create_query_result());
return query(query_str, *query_result_ptr);
}
bool DbConnector::query(const pt::TextStream & stream, QueryResult & query_result)
{
std::string query_str;
stream.to_string(query_str);
@ -129,22 +152,22 @@ bool DbConnector::query_remove(const char * query_str, QueryResult & query_resul
bool DbConnector::query_select(const PT::TextStream & stream, QueryResult & query_result)
bool DbConnector::query_select(const pt::TextStream & stream, QueryResult & query_result)
{
return query(stream, query_result);
}
bool DbConnector::query_update(const PT::TextStream & stream, QueryResult & query_result)
bool DbConnector::query_update(const pt::TextStream & stream, QueryResult & query_result)
{
return query(stream, query_result);
}
bool DbConnector::query_insert(const PT::TextStream & stream, QueryResult & query_result)
bool DbConnector::query_insert(const pt::TextStream & stream, QueryResult & query_result)
{
return query(stream, query_result);
}
bool DbConnector::query_remove(const PT::TextStream & stream, QueryResult & query_result)
bool DbConnector::query_remove(const pt::TextStream & stream, QueryResult & query_result)
{
return query(stream, query_result);
}
@ -158,7 +181,7 @@ DbExpression * DbConnector::get_expression()
}
void DbConnector::generate_select_columns(PT::TextStream & stream, Model & model)
void DbConnector::generate_select_columns(pt::TextStream & stream, Model & model)
{
allocate_default_expression_if_needed();
@ -173,7 +196,7 @@ void DbConnector::generate_select_columns(PT::TextStream & stream, Model & model
}
void DbConnector::generate_insert_query(PT::TextStream & stream, Model & model)
void DbConnector::generate_insert_query(pt::TextStream & stream, Model & model)
{
allocate_default_expression_if_needed();
@ -183,7 +206,7 @@ void DbConnector::generate_insert_query(PT::TextStream & stream, Model & model)
db_expression->allow_to_use_prefix(false);
stream << "insert into ";
model.table_name(stream);
db_expression->schema_table_to_stream(stream, model.model_env->schema_name, model.model_env->table_name);
stream << " (";
db_expression->set_work_mode(MORM_WORK_MODE_MODEL_FIELDS);
@ -198,7 +221,7 @@ void DbConnector::generate_insert_query(PT::TextStream & stream, Model & model)
}
void DbConnector::generate_update_query(PT::TextStream & stream, Model & model)
void DbConnector::generate_update_query(pt::TextStream & stream, Model & model)
{
allocate_default_expression_if_needed();
@ -208,7 +231,7 @@ void DbConnector::generate_update_query(PT::TextStream & stream, Model & model)
db_expression->allow_to_use_prefix(false);
stream << "update ";
model.table_name(stream);
db_expression->schema_table_to_stream(stream, model.model_env->schema_name, model.model_env->table_name);
stream << " set ";
db_expression->set_work_mode(MORM_WORK_MODE_MODEL_FIELDS_VALUES);
@ -223,7 +246,7 @@ void DbConnector::generate_update_query(PT::TextStream & stream, Model & model)
}
void DbConnector::generate_remove_query(PT::TextStream & stream, Model & model)
void DbConnector::generate_remove_query(pt::TextStream & stream, Model & model)
{
allocate_default_expression_if_needed();
@ -233,7 +256,8 @@ void DbConnector::generate_remove_query(PT::TextStream & stream, Model & model)
db_expression->allow_to_use_prefix(false);
stream << "delete from ";
model.table_name(stream);
db_expression->schema_table_to_stream(stream, model.model_env->schema_name, model.model_env->table_name);
stream << " where ";
db_expression->set_work_mode(MORM_WORK_MODE_MODEL_FIELDS_VALUES);
db_expression->set_output_type(MORM_OUTPUT_TYPE_DB_PRIMARY_KEY);
@ -241,7 +265,7 @@ void DbConnector::generate_remove_query(PT::TextStream & stream, Model & model)
}
}
bool DbConnector::insert(PT::TextStream & stream, Model & model)
bool DbConnector::insert(pt::TextStream & stream, Model & model)
{
std::unique_ptr<QueryResult> query_result_ptr(create_query_result());
@ -250,7 +274,7 @@ bool DbConnector::insert(PT::TextStream & stream, Model & model)
}
bool DbConnector::update(PT::TextStream & stream, Model & model)
bool DbConnector::update(pt::TextStream & stream, Model & model)
{
std::unique_ptr<QueryResult> query_result_ptr(create_query_result());
@ -259,7 +283,7 @@ bool DbConnector::update(PT::TextStream & stream, Model & model)
}
bool DbConnector::remove(PT::TextStream & stream, Model & model)
bool DbConnector::remove(pt::TextStream & stream, Model & model)
{
std::unique_ptr<QueryResult> query_result_ptr(create_query_result());
@ -289,52 +313,310 @@ void DbConnector::allocate_default_expression_if_needed()
}
void DbConnector::get_value(const char * value_str, char & field_value)
char DbConnector::unescape_hex_char_part(char hex)
{
field_value = *value_str;
value_str += 1;
if( *value_str != 0 )
if( hex>='0' && hex<='9' )
{
// value has more than one charater, put some error?
return hex - '0';
}
else
if( hex>='a' && hex<='f' )
{
return hex - 'a' + 10;
}
else
if( hex>='A' && hex<='F' )
{
return hex - 'A' + 10;
}
else
{
if( log )
{
(*log) << pt::Log::log2 << "Morm: incorrect character when reading a hex string, char code: " << (int)(unsigned char)hex;
if( hex >= 32 )
{
(*log) << " '" << hex << "'";
}
(*log) << pt::Log::logend;
}
}
return 0;
}
char DbConnector::unescape_hex_char(char char1, char char2)
{
int c1 = unescape_hex_char_part(char1);
int c2 = unescape_hex_char_part(char2);
return static_cast<char>(((c1 << 4) | c2));
}
void DbConnector::unescape_hex_string(const char * str, std::string & out)
{
for(size_t i=0 ; str[i] != 0 ; i+=2 )
{
out += unescape_hex_char(str[i], str[i+1]);
}
}
void DbConnector::unescape_hex_string(const char * str, std::wstring & out, const FT & field_type)
{
if( field_type.use_utf8() )
{
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])));
}
}
}
void DbConnector::unescape_bin_string(const char * str, std::string & out)
{
unescape_hex_string(str, out);
}
void DbConnector::unescape_bin_string(const char * str, std::wstring & out, const FT & field_type)
{
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)
{
wchar_t c;
field_value = 0;
get_value(value_str, c, field_type);
if( field_type.use_utf8() )
{
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 = static_cast<char>(c);
}
}
void DbConnector::get_value(const char * value_str, unsigned char & field_value)
// CHECKME need to be tested
void DbConnector::get_value(const char * value_str, unsigned char & field_value, const FT & field_type)
{
field_value = *(const unsigned char*)value_str;
value_str += 1;
char tmp_char;
get_value(value_str, tmp_char, field_type);
if( *value_str != 0 )
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_binary() )
{
// value has more than one charater, put some error?
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
{
if( field_type.use_utf8() )
{
int value_int;
bool is_correct;
pt::utf8_to_int(value_str, value_int, is_correct);
if( is_correct )
{
field_value = static_cast<wchar_t>(value_int);
}
else
{
// report an error?
}
}
else
{
field_value = static_cast<wchar_t>((unsigned char)*value_str);
}
}
}
void DbConnector::get_value(const char * value_str, std::wstring & field_value)
// CHECKME need to be tested
void DbConnector::get_value(const char * value_str, std::wstring & field_value, const FT & field_type)
{
// CHECKME
// what about \0 in val_str?
// it is escaped somehow?
PT::UTF8ToWide(value_str, field_value);
if( field_type.is_binary() )
{
unescape_bin_string(value_str, field_value, field_type);
}
else
if( field_type.is_hexadecimal() )
{
unescape_hex_string(value_str, field_value, field_type);
}
else
{
if( field_type.use_utf8() )
{
pt::utf8_to_wide(value_str, field_value);
}
else
{
for(size_t i=0 ; value_str[i] != 0 ; ++i)
{
field_value += static_cast<wchar_t>(value_str[i]);
}
}
}
}
void DbConnector::get_value(const char * value_str, std::string & field_value)
// CHECKME need to be tested
void DbConnector::get_value(const char * value_str, std::string & field_value, const FT & field_type)
{
field_value = value_str;
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;
}
}
void DbConnector::get_value(const char * value_str, bool & field_value)
void DbConnector::get_value(const char * value_str, bool & field_value, const FT & field_type)
{
// IMPROVE ME
// this 't' is locale dependent
@ -342,90 +624,112 @@ void DbConnector::get_value(const char * value_str, bool & field_value)
}
void DbConnector::get_value(const char * value_str, short & field_value)
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::Toi(value_str, 10);
field_value = (short)pt::Toi(value_str, 10);
}
void DbConnector::get_value(const char * value_str, unsigned short & field_value)
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::Toui(value_str, 10);
field_value = (unsigned short)pt::Toui(value_str, 10);
}
void DbConnector::get_value(const char * value_str, int & field_value)
void DbConnector::get_value(const char * value_str, int & field_value, const FT & field_type)
{
// IMPROVE ME give some overflow checking
field_value = PT::Toi(value_str, 10);
field_value = pt::Toi(value_str, 10);
}
void DbConnector::get_value(const char * value_str, unsigned int & field_value)
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::Toui(value_str, 10);
field_value = pt::Toui(value_str, 10);
}
void DbConnector::get_value(const char * value_str, long & field_value)
void DbConnector::get_value(const char * value_str, long & field_value, const FT & field_type)
{
// IMPROVE ME give some overflow checking
field_value = PT::Tol(value_str, 10);
field_value = pt::Tol(value_str, 10);
}
void DbConnector::get_value(const char * value_str, unsigned long & field_value)
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::Toul(value_str, 10);
field_value = pt::Toul(value_str, 10);
}
void DbConnector::get_value(const char * value_str, long long & field_value)
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::Toll(value_str, 10);
field_value = pt::Toll(value_str, 10);
}
void DbConnector::get_value(const char * value_str, unsigned long long & field_value)
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::Toull(value_str, 10);
field_value = pt::Toull(value_str, 10);
}
void DbConnector::get_value(const char * value_str, float & field_value)
void DbConnector::get_value(const char * value_str, float & field_value, const FT & field_type)
{
// IMPROVE ME give some overflow checking
field_value = strtof(value_str, 0);
}
void DbConnector::get_value(const char * value_str, double & field_value)
void DbConnector::get_value(const char * value_str, double & field_value, const FT & field_type)
{
// IMPROVE ME give some overflow checking
field_value = strtod(value_str, 0);
}
void DbConnector::get_value(const char * value_str, long double & field_value)
void DbConnector::get_value(const char * value_str, long double & field_value, const FT & field_type)
{
// IMPROVE ME give some overflow checking
field_value = strtold(value_str, 0);
}
void DbConnector::get_value(const char * value_str, PT::Date & field_value)
void DbConnector::get_value(const char * value_str, pt::Date & field_value, const FT & field_type)
{
// IMPROVE ME give some log if parsing failed
field_value.Parse(value_str);
}
void DbConnector::get_value(const char * value_str, pt::Space & field_value, const FT & field_type)
{
field_value.clear();
if( *value_str != '\0' )
{
pt::SpaceParser space_parser;
if( space_parser.parse_space(value_str, field_value) != pt::SpaceParser::ok )
{
field_value.clear();
if( log )
{
(*log) << pt::Log::log2 << "Morm: I cannot correctly parse the Space struct from the datebase"
<< ", the raw string is: " << value_str << pt::Log::logend;
}
}
}
}
const char * DbConnector::query_last_sequence(const wchar_t * sequence_table_name)
{
return nullptr;

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2018-2019, Tomasz Sowa
* Copyright (c) 2018-2021, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -38,6 +38,7 @@
#include "textstream/textstream.h"
#include "log/log.h"
#include "queryresult.h"
#include "ft.h"
namespace morm
@ -54,29 +55,29 @@ public:
DbConnector(const DbConnector &);
virtual ~DbConnector();
virtual void set_logger(PT::Log * log);
virtual void set_logger(PT::Log & log);
virtual void set_logger(pt::Log * log);
virtual void set_logger(pt::Log & log);
virtual void set_log_queries(bool log_queries);
DbExpression * get_expression();
//virtual void clear_last_query_result();
virtual void generate_select_columns(pt::TextStream & stream, Model & model);
virtual void generate_insert_query(pt::TextStream & stream, Model & model);
virtual void generate_update_query(pt::TextStream & stream, Model & model);
virtual void generate_remove_query(pt::TextStream & stream, Model & model);
virtual void generate_select_columns(PT::TextStream & stream, Model & model);
virtual void generate_insert_query(PT::TextStream & stream, Model & model);
virtual void generate_update_query(PT::TextStream & stream, Model & model);
virtual void generate_remove_query(PT::TextStream & stream, Model & model);
virtual bool insert(pt::TextStream & stream, Model & model);
virtual bool update(pt::TextStream & stream, Model & model);
virtual bool remove(pt::TextStream & stream, Model & model);
virtual bool insert(PT::TextStream & stream, Model & model);
virtual bool update(PT::TextStream & stream, Model & model);
virtual bool remove(PT::TextStream & stream, Model & model);
//void ModelConnector::get_values_from_db(Model & model)
virtual bool query(const pt::TextStream & stream);
virtual bool query(const std::string & query_str);
virtual bool query(const char * query_str);
virtual QueryResult * create_query_result() = 0;
virtual bool query(const PT::TextStream & stream, QueryResult & query_result);
virtual bool query(const pt::TextStream & stream, QueryResult & query_result);
virtual bool query(const std::string & query_str, QueryResult & query_result);
virtual bool query(const char * query_str, QueryResult & query_result);
@ -85,32 +86,35 @@ public:
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_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_select(const pt::TextStream & stream, QueryResult & query_result);
virtual bool query_update(const pt::TextStream & stream, QueryResult & query_result);
virtual bool query_insert(const pt::TextStream & stream, QueryResult & query_result);
virtual bool query_remove(const pt::TextStream & stream, QueryResult & query_result);
virtual void get_value(const char * value_str, char & field_value);
virtual void get_value(const char * value_str, unsigned char & field_value);
virtual void get_value(const char * value_str, std::wstring & field_value);
virtual void get_value(const char * value_str, std::string & field_value);
virtual void get_value(const char * value_str, bool & field_value);
virtual void get_value(const char * value_str, short & field_value);
virtual void get_value(const char * value_str, unsigned short & field_value);
virtual void get_value(const char * value_str, int & field_value);
virtual void get_value(const char * value_str, unsigned int & field_value);
virtual void get_value(const char * value_str, long & field_value);
virtual void get_value(const char * value_str, unsigned long & field_value);
virtual void get_value(const char * value_str, long long & field_value);
virtual void get_value(const char * value_str, unsigned long long & field_value);
virtual void get_value(const char * value_str, float & field_value);
virtual void get_value(const char * value_str, double & field_value);
virtual void get_value(const char * value_str, long double & field_value);
virtual void get_value(const char * value_str, PT::Date & field_value);
virtual void get_value(const char * value_str, char & field_value, const FT & field_type = FT::default_type);
virtual void get_value(const char * value_str, unsigned char & field_value, const FT & field_type = FT::default_type);
virtual void get_value(const char * value_str, wchar_t & field_value, const FT & field_type = FT::default_type);
virtual void get_value(const char * value_str, std::wstring & field_value, const FT & field_type = FT::default_type);
virtual void get_value(const char * value_str, std::string & field_value, const FT & field_type = FT::default_type);
virtual void get_value(const char * value_str, bool & field_value, const FT & field_type = FT::default_type);
virtual void get_value(const char * value_str, short & field_value, const FT & field_type = FT::default_type);
virtual void get_value(const char * value_str, unsigned short & field_value, const FT & field_type = FT::default_type);
virtual void get_value(const char * value_str, int & field_value, const FT & field_type = FT::default_type);
virtual void get_value(const char * value_str, unsigned int & field_value, const FT & field_type = FT::default_type);
virtual void get_value(const char * value_str, long & field_value, const FT & field_type = FT::default_type);
virtual void get_value(const char * value_str, unsigned long & field_value, const FT & field_type = FT::default_type);
virtual void get_value(const char * value_str, long long & field_value, const FT & field_type = FT::default_type);
virtual void get_value(const char * value_str, unsigned long long & field_value, const FT & field_type = FT::default_type);
virtual void get_value(const char * value_str, float & field_value, const FT & field_type = FT::default_type);
virtual void get_value(const char * value_str, double & field_value, const FT & field_type = FT::default_type);
virtual void get_value(const char * value_str, long double & field_value, const FT & field_type = FT::default_type);
virtual void get_value(const char * value_str, pt::Date & field_value, const FT & field_type = FT::default_type);
virtual void get_value(const char * value_str, pt::Space & field_value, const FT & field_type = FT::default_type);
// add get_value for pt::TextStream and pt::WTextStream
template<typename FieldValue>
void get_last_sequence(const wchar_t * sequence_table_name, FieldValue & field_value)
bool get_last_sequence(const wchar_t * sequence_table_name, FieldValue & field_value)
{
const char * val_str = query_last_sequence(sequence_table_name);
@ -120,9 +124,13 @@ public:
if( log && log_queries )
{
(*log) << PT::Log::log3 << "Morm: sequence value: " << field_value << PT::Log::logend;
(*log) << pt::Log::log3 << "Morm: sequence value: " << field_value << pt::Log::logend;
}
return true;
}
return false;
}
@ -130,7 +138,7 @@ protected:
DbExpression * db_expression;
bool expression_allocated;
PT::Log * log;
pt::Log * log;
bool log_queries;
@ -140,6 +148,23 @@ protected:
virtual const char * query_last_sequence(const wchar_t * sequence_table_name);
virtual void unescape_hex_string(const char * str, std::string & out);
virtual void unescape_hex_string(const char * str, std::wstring & out, const FT & field_type);
virtual void unescape_bin_string(const char * str, std::string & out);
virtual void unescape_bin_string(const char * str, std::wstring & out, const FT & field_type);
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:
char unescape_hex_char_part(char hex);
char unescape_hex_char(char char1, char char2);
};

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2018-2019, Tomasz Sowa
* Copyright (c) 2018-2021, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -62,23 +62,23 @@ int DbExpression::get_output_type()
}
bool DbExpression::can_field_be_generated(bool insertable, bool updatable, bool is_primary_key)
bool DbExpression::can_field_be_generated(const FT & field_type)
{
if( output_type == MORM_OUTPUT_TYPE_DB_INSERT )
{
return insertable;
return field_type.is_insertable();
}
else
if( output_type == MORM_OUTPUT_TYPE_DB_UPDATE )
{
return updatable;
return field_type.is_updatable();
}
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 )
{
return is_primary_key;
return field_type.is_primary_key();
}
else
{
@ -182,78 +182,64 @@ void DbExpression::put_name_value_separator()
}
void DbExpression::before_field_value_string()
void DbExpression::schema_table_separator()
{
// if( output_type == MORM_OUTPUT_TYPE_SELECT_COLUMNS ||
// output_type == MORM_OUTPUT_TYPE_DB_INSERT ||
// output_type == MORM_OUTPUT_TYPE_DB_UPDATE ||
// output_type == MORM_OUTPUT_TYPE_DB_PRIMARY_KEY )
{
(*out_stream) << "'";
}
}
void DbExpression::after_field_value_string()
{
// if( output_type == MORM_OUTPUT_TYPE_SELECT_COLUMNS ||
// output_type == MORM_OUTPUT_TYPE_DB_INSERT ||
// output_type == MORM_OUTPUT_TYPE_DB_UPDATE ||
// output_type == MORM_OUTPUT_TYPE_DB_PRIMARY_KEY )
{
(*out_stream) << "'";
}
(*out_stream) << '.';
}
void DbExpression::before_field_value(const std::wstring &)
void DbExpression::table_field_separator()
{
before_field_value_string();
(*out_stream) << '.';
}
void DbExpression::after_field_value(const std::wstring &)
void DbExpression::before_schema_name()
{
after_field_value_string();
(*out_stream) << '"';
}
void DbExpression::before_field_value(const std::string &)
void DbExpression::after_schema_name()
{
before_field_value_string();
(*out_stream) << '"';
}
void DbExpression::after_field_value(const std::string &)
void DbExpression::before_table_name()
{
after_field_value_string();
(*out_stream) << '"';
}
void DbExpression::before_field_value(const wchar_t *)
void DbExpression::after_table_name()
{
before_field_value_string();
(*out_stream) << '"';
}
void DbExpression::after_field_value(const wchar_t *)
void DbExpression::before_field_name()
{
after_field_value_string();
(*out_stream) << '"';
}
void DbExpression::before_field_value(const char *)
void DbExpression::after_field_name()
{
before_field_value_string();
(*out_stream) << '"';
}
void DbExpression::after_field_value(const char *)
void DbExpression::before_field_value_string(const FT & field_type)
{
after_field_value_string();
(*out_stream) << "'";
}
void DbExpression::before_field_value(const PT::Date &)
{
before_field_value_string();
}
void DbExpression::after_field_value(const PT::Date &)
void DbExpression::after_field_value_string(const FT & field_type)
{
after_field_value_string();
(*out_stream) << "'";
}
@ -265,7 +251,7 @@ void DbExpression::prepare_to_where_clause()
}
DbExpression & DbExpression::group_or(PT::TextStream & stream)
DbExpression & DbExpression::group_or(pt::TextStream & stream)
{
out_stream = &stream;
field_before();
@ -277,7 +263,7 @@ DbExpression & DbExpression::group_or(PT::TextStream & stream)
return *this;
}
DbExpression & DbExpression::group_and(PT::TextStream & stream)
DbExpression & DbExpression::group_and(pt::TextStream & stream)
{
out_stream = &stream;
field_before();
@ -289,7 +275,7 @@ DbExpression & DbExpression::group_and(PT::TextStream & stream)
return *this;
}
DbExpression & DbExpression::group_end(PT::TextStream & stream)
DbExpression & DbExpression::group_end(pt::TextStream & stream)
{
out_stream = &stream;
@ -305,7 +291,7 @@ DbExpression & DbExpression::group_end(PT::TextStream & stream)
}
DbExpression & DbExpression::page(PT::TextStream & stream, size_t page_number, size_t page_size)
DbExpression & DbExpression::page(pt::TextStream & stream, size_t page_number, size_t page_size)
{
stream << " limit " << page_number << "," << page_size << " ";
return *this;
@ -314,37 +300,4 @@ DbExpression & DbExpression::page(PT::TextStream & stream, size_t page_number, s
void DbExpression::prepare_short_table_name(const PT::TextStream & table_name, PT::TextStream & short_table_name)
{
short_table_name.clear();
if( is_long_table_name(table_name) )
{
PT::TextStream::const_iterator i = table_name.begin();
bool was_dot = false;
while( i != table_name.end() )
{
if( was_dot )
{
short_table_name << *i;
}
else
if( *i == '.' )
{
was_dot = true;
}
++i;
}
}
if( short_table_name.empty() )
{
short_table_name = table_name;
}
}
}

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2018, Tomasz Sowa
* Copyright (c) 2018-2021, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -56,14 +56,14 @@ public:
virtual void prepare_to_where_clause();
virtual DbExpression & group_or(PT::TextStream & stream);
virtual DbExpression & group_and(PT::TextStream & stream);
virtual DbExpression & group_end(PT::TextStream & stream);
virtual DbExpression & group_or(pt::TextStream & stream);
virtual DbExpression & group_and(pt::TextStream & stream);
virtual DbExpression & group_end(pt::TextStream & stream);
virtual DbExpression & page(PT::TextStream & stream, size_t page_number, size_t page_size);
virtual DbExpression & page(pt::TextStream & stream, size_t page_number, size_t page_size);
template<typename FieldValue>
void add_field_for_select(const wchar_t * new_column_expression, const wchar_t * new_column_name, FieldValue & field_value)
void add_field_for_select(const wchar_t * new_column_expression, const wchar_t * new_column_name, FieldValue & field_value, const FT & field_type, ModelEnv * model_env)
{
std::wstring column_expression; // field() methods can be called recursively, so don't make it as class object
@ -71,47 +71,37 @@ public:
column_expression += L" as ";
column_expression += new_column_name;
// put nullptr to ModelEnv* to not allow to use prefix
// or may better remember current value of use_prefix and set it to false for a while?
field(column_expression.c_str(), field_value, false, false, false, nullptr);
field(column_expression.c_str(), field_value, field_type, model_env);
}
virtual void prepare_short_table_name(const PT::TextStream & table_name, PT::TextStream & short_table_name);
protected:
int output_type;
std::vector<int> conjunctions;
bool can_field_be_generated(bool insertable, bool updatable, bool is_primary_key);
bool can_field_be_generated(const FT & field_type);
void field_before();
void before_field_value(const std::wstring &);
void after_field_value(const std::wstring &);
void before_field_value(const std::string &);
void after_field_value(const std::string &);
void before_field_value(const wchar_t *);
void after_field_value(const wchar_t *);
void before_field_value(const char *);
void after_field_value(const char *);
void before_field_value(const PT::Date &);
void after_field_value(const PT::Date &);
void put_name_value_separator();
void schema_table_separator();
void table_field_separator();
void before_schema_name();
void after_schema_name();
void before_table_name();
void after_table_name();
void before_field_name();
void after_field_name();
private:
void before_field_value_string();
void after_field_value_string();
void before_field_value_string(const FT & field_type);
void after_field_value_string(const FT & field_type);
};

View File

@ -66,7 +66,7 @@ public:
}
Finder(PT::TextStream & out_stream)
Finder(pt::TextStream & out_stream)
{
this->out_stream = &out_stream;
this->model_connector = nullptr;
@ -95,7 +95,7 @@ public:
set_out_stream();
}
Finder(PT::TextStream & out_stream, ModelConnector & model_connector)
Finder(pt::TextStream & out_stream, ModelConnector & model_connector)
{
this->out_stream = &out_stream;
this->model_connector = &model_connector;
@ -104,7 +104,7 @@ public:
model_data = nullptr;
}
Finder(PT::TextStream & out_stream, ModelConnector * model_connector)
Finder(pt::TextStream & out_stream, ModelConnector * model_connector)
{
this->out_stream = &out_stream;
this->model_connector = model_connector;
@ -116,7 +116,7 @@ public:
Finder<ModelClass> & set_out_stream(PT::TextStream * out_stream)
Finder<ModelClass> & set_out_stream(pt::TextStream * out_stream)
{
this->out_stream = out_stream;
return *this;
@ -173,6 +173,17 @@ public:
last_query_error = L"model connector object is required";
}
model.set_connector(model_connector);
finder_helper.clear();
model_env.clear();
model.model_env = &model_env;
model.model_env->model_data = model_data;
model.model_env->finder_helper = &finder_helper;
model.table();
model.model_env->add_table_name_to_finder_helper();
return *this;
}
@ -193,7 +204,7 @@ public:
return select();
}
Finder<ModelClass> & select(PT::TextStream & out_stream, ModelConnector & model_connector)
Finder<ModelClass> & select(pt::TextStream & out_stream, ModelConnector & model_connector)
{
this->out_stream = &out_stream;
this->model_connector = &model_connector;
@ -202,7 +213,7 @@ public:
return select();
}
Finder<ModelClass> & select(PT::TextStream & out_stream, ModelConnector * model_connector)
Finder<ModelClass> & select(pt::TextStream & out_stream, ModelConnector * model_connector)
{
this->out_stream = &out_stream;
this->model_connector = model_connector;
@ -219,27 +230,31 @@ public:
prepare_to_select();
}
model.set_connector(model_connector);
finder_helper.clear();
model_env.clear();
model.model_env = &model_env;
model.model_env->model_data = model_data;
model.model_env->finder_helper = &finder_helper;
has_autogenerated_select = true;
if( model_connector && out_stream && db_expression )
{
model.prepare_table_names();
(*out_stream) << "SELECT ";
model.generate_select_columns(*out_stream);
(*out_stream) << " FROM " << model.model_env->table_name << " AS ";
(*out_stream) << model.model_env->table_name_short;
(*out_stream) << " ";
(*out_stream) << finder_helper.join_tables_str;
(*out_stream) << " FROM ";
if( !model.model_env->schema_name.empty() )
{
db_expression->schema_table_to_stream(*out_stream, model.model_env->schema_name, model.model_env->table_name);
}
else
{
db_expression->table_to_stream(*out_stream, model.model_env->table_name);
}
(*out_stream) << " AS ";
db_expression->table_to_stream(*out_stream, model.model_env->table_name);
if( !finder_helper.join_tables_str.empty() )
{
(*out_stream) << " ";
(*out_stream) << finder_helper.join_tables_str;
}
}
return *this;
@ -326,14 +341,39 @@ public:
template<typename FieldValue>
Finder<ModelClass> & eq(const wchar_t * field_name, const FieldValue & field_value)
{
if( db_expression )
{
db_expression->set_output_type(MORM_OUTPUT_TYPE_WHERE_EQ);
db_expression->field_to_stream(*out_stream, field_name, field_value, false, false, false, &model_env);
db_expression->field_to_stream(*out_stream, field_name, field_value, FT::default_type, &model_env);
}
return *this;
}
template<typename FieldValue>
Finder<ModelClass> & eq(const wchar_t * table_name, const wchar_t * field_name, const FieldValue & field_value)
{
if( db_expression )
{
db_expression->set_output_type(MORM_OUTPUT_TYPE_WHERE_EQ);
field_to_stream(table_name, 1, field_name, field_value);
}
return *this;
}
template<typename FieldValue>
Finder<ModelClass> & eq(const wchar_t * table_name, int table_index, const wchar_t * field_name, const FieldValue & field_value)
{
if( db_expression )
{
db_expression->set_output_type(MORM_OUTPUT_TYPE_WHERE_EQ);
field_to_stream(table_name, table_index, field_name, field_value);
}
return *this;
@ -346,19 +386,72 @@ public:
if( db_expression )
{
db_expression->set_output_type(MORM_OUTPUT_TYPE_WHERE_NOT_EQ);
db_expression->field_to_stream(*out_stream, field_name, field_value, false, false, false, &model_env);
db_expression->field_to_stream(*out_stream, field_name, field_value, FT::default_type, &model_env);
}
return *this;
}
template<typename FieldValue>
Finder<ModelClass> & neq(const wchar_t * table_name, const wchar_t * field_name, const FieldValue & field_value)
{
if( db_expression )
{
db_expression->set_output_type(MORM_OUTPUT_TYPE_WHERE_NOT_EQ);
field_to_stream(table_name, 1, field_name, field_value);
}
return *this;
}
template<typename FieldValue>
Finder<ModelClass> & neq(const wchar_t * table_name, int table_index, const wchar_t * field_name, const FieldValue & field_value)
{
if( db_expression )
{
db_expression->set_output_type(MORM_OUTPUT_TYPE_WHERE_NOT_EQ);
field_to_stream(table_name, table_index, field_name, field_value);
}
return *this;
}
template<typename FieldValue>
Finder<ModelClass> & lt(const wchar_t * field_name, const FieldValue & field_value)
{
if( db_expression )
{
db_expression->set_output_type(MORM_OUTPUT_TYPE_WHERE_LT);
db_expression->field_to_stream(*out_stream, field_name, field_value, false, false, false, &model_env);
db_expression->field_to_stream(*out_stream, field_name, field_value, FT::default_type, &model_env);
}
return *this;
}
template<typename FieldValue>
Finder<ModelClass> & lt(const wchar_t * table_name, const wchar_t * field_name, const FieldValue & field_value)
{
if( db_expression )
{
db_expression->set_output_type(MORM_OUTPUT_TYPE_WHERE_LT);
field_to_stream(table_name, 1, field_name, field_value);
}
return *this;
}
template<typename FieldValue>
Finder<ModelClass> & lt(const wchar_t * table_name, int table_index, const wchar_t * field_name, const FieldValue & field_value)
{
if( db_expression )
{
db_expression->set_output_type(MORM_OUTPUT_TYPE_WHERE_LT);
field_to_stream(table_name, table_index, field_name, field_value);
}
return *this;
@ -371,7 +464,33 @@ public:
if( db_expression )
{
db_expression->set_output_type(MORM_OUTPUT_TYPE_WHERE_GT);
db_expression->field_to_stream(*out_stream, field_name, field_value, false, false, false, &model_env);
db_expression->field_to_stream(*out_stream, field_name, field_value, FT::default_type, &model_env);
}
return *this;
}
template<typename FieldValue>
Finder<ModelClass> & gt(const wchar_t * table_name, const wchar_t * field_name, const FieldValue & field_value)
{
if( db_expression )
{
db_expression->set_output_type(MORM_OUTPUT_TYPE_WHERE_GT);
field_to_stream(table_name, 1, field_name, field_value);
}
return *this;
}
template<typename FieldValue>
Finder<ModelClass> & gt(const wchar_t * table_name, int table_index, const wchar_t * field_name, const FieldValue & field_value)
{
if( db_expression )
{
db_expression->set_output_type(MORM_OUTPUT_TYPE_WHERE_GT);
field_to_stream(table_name, table_index, field_name, field_value);
}
return *this;
@ -384,20 +503,75 @@ public:
if( db_expression )
{
db_expression->set_output_type(MORM_OUTPUT_TYPE_WHERE_LE);
db_expression->field_to_stream(*out_stream, field_name, field_value, false, false, false, &model_env);
db_expression->field_to_stream(*out_stream, field_name, field_value, FT::default_type, &model_env);
}
return *this;
}
template<typename FieldValue>
Finder<ModelClass> & le(const wchar_t * table_name, const wchar_t * field_name, const FieldValue & field_value)
{
if( db_expression )
{
db_expression->set_output_type(MORM_OUTPUT_TYPE_WHERE_LE);
field_to_stream(table_name, 1, field_name, field_value);
}
return *this;
}
template<typename FieldValue>
Finder<ModelClass> & le(const wchar_t * table_name, int table_index, const wchar_t * field_name, const FieldValue & field_value)
{
if( db_expression )
{
db_expression->set_output_type(MORM_OUTPUT_TYPE_WHERE_LE);
field_to_stream(table_name, table_index, field_name, field_value);
}
return *this;
}
template<typename FieldValue>
Finder<ModelClass> & ge(const wchar_t * field_name, const FieldValue & field_value)
{
if( db_expression )
{
db_expression->set_output_type(MORM_OUTPUT_TYPE_WHERE_GE);
db_expression->field_to_stream(*out_stream, field_name, field_value, false, false, false, &model_env);
db_expression->field_to_stream(*out_stream, field_name, field_value, FT::default_type, &model_env);
}
return *this;
}
template<typename FieldValue>
Finder<ModelClass> & ge(const wchar_t * table_name, const wchar_t * field_name, const FieldValue & field_value)
{
if( db_expression )
{
db_expression->set_output_type(MORM_OUTPUT_TYPE_WHERE_GE);
field_to_stream(table_name, 1, field_name, field_value);
}
return *this;
}
template<typename FieldValue>
Finder<ModelClass> & ge(const wchar_t * table_name, int table_index, const wchar_t * field_name, const FieldValue & field_value)
{
if( db_expression )
{
db_expression->set_output_type(MORM_OUTPUT_TYPE_WHERE_GE);
field_to_stream(table_name, table_index, field_name, field_value);
}
return *this;
@ -417,6 +591,33 @@ public:
return *this;
}
template<typename FieldValue>
Finder<ModelClass> & in(const wchar_t * table_name, const wchar_t * field_name, const std::set<FieldValue> & container)
{
if( db_expression )
{
db_expression->set_output_type(MORM_OUTPUT_TYPE_WHERE_IN);
field_in(table_name, 1, field_name, container);
}
return *this;
}
template<typename FieldValue>
Finder<ModelClass> & in(const wchar_t * table_name, int table_index, const wchar_t * field_name, const std::set<FieldValue> & container)
{
if( db_expression )
{
db_expression->set_output_type(MORM_OUTPUT_TYPE_WHERE_IN);
field_in(table_name, table_index, field_name, container);
}
return *this;
}
template<typename FieldValue>
Finder<ModelClass> & in(const wchar_t * field_name, const std::list<FieldValue> & container)
{
@ -429,6 +630,33 @@ public:
return *this;
}
template<typename FieldValue>
Finder<ModelClass> & in(const wchar_t * table_name, const wchar_t * field_name, const std::list<FieldValue> & container)
{
if( db_expression )
{
db_expression->set_output_type(MORM_OUTPUT_TYPE_WHERE_IN);
field_in(table_name, 1, field_name, container);
}
return *this;
}
template<typename FieldValue>
Finder<ModelClass> & in(const wchar_t * table_name, int table_index, const wchar_t * field_name, const std::list<FieldValue> & container)
{
if( db_expression )
{
db_expression->set_output_type(MORM_OUTPUT_TYPE_WHERE_IN);
field_in(table_name, table_index, field_name, container);
}
return *this;
}
template<typename FieldValue>
Finder<ModelClass> & in(const wchar_t * field_name, const std::vector<FieldValue> & container)
{
@ -441,6 +669,35 @@ public:
return *this;
}
template<typename FieldValue>
Finder<ModelClass> & in(const wchar_t * table_name, const wchar_t * field_name, const std::vector<FieldValue> & container)
{
if( db_expression )
{
db_expression->set_output_type(MORM_OUTPUT_TYPE_WHERE_IN);
field_in(table_name, 1, field_name, container);
}
return *this;
}
template<typename FieldValue>
Finder<ModelClass> & in(const wchar_t * table_name, int table_index, const wchar_t * field_name, const std::vector<FieldValue> & container)
{
if( db_expression )
{
db_expression->set_output_type(MORM_OUTPUT_TYPE_WHERE_IN);
field_in(table_name, table_index, field_name, container);
}
return *this;
}
Finder<ModelClass> & page(size_t page_number, size_t page_size)
{
if( out_stream && db_expression )
@ -469,7 +726,7 @@ public:
}
Finder<ModelClass> & raw(PT::TextStream & sql, bool add_spaces = true)
Finder<ModelClass> & raw(pt::TextStream & sql, bool add_spaces = true)
{
if( out_stream )
{
@ -598,7 +855,7 @@ protected:
private:
PT::TextStream * out_stream;
pt::TextStream * out_stream;
ModelConnector * model_connector;
DbExpression * db_expression;
ModelClass model;
@ -625,6 +882,35 @@ private:
}
template<typename FieldValue>
void field_to_stream(const wchar_t * table_name, int table_index, const wchar_t * field_name, const FieldValue & field_value)
{
if( db_expression )
{
model_env.table2_name = table_name;
model_env.table2_index = table_index;
db_expression->field_to_stream(*out_stream, field_name, field_value, FT::default_type, &model_env);
model_env.table2_name = nullptr;
model_env.table2_index = 0;
}
}
template<typename Container>
void field_in(const wchar_t * table_name, int table_index, const wchar_t * field_name, const Container & container)
{
if( db_expression )
{
model_env.table2_name = table_name;
model_env.table2_index = table_index;
db_expression->field_in(*out_stream, field_name, container, &model_env);
model_env.table2_name = nullptr;
model_env.table2_index = 0;
}
}
};

View File

@ -46,9 +46,9 @@ class FinderHelper
{
public:
PT::TextStream join_tables_str;
pt::TextStream join_tables_str;
std::map<std::string, int> join_tables_map;
std::map<std::wstring, int> join_tables_map;
std::list<std::string> foreign_keys;
@ -72,16 +72,16 @@ public:
}
virtual int add_join_table(const PT::TextStream & table_name)
virtual int add_join_table(const pt::WTextStream & table_name)
{
std::string table_name_str;
std::wstring table_name_str;
table_name.to_string(table_name_str);
return add_join_table(table_name_str);
}
virtual int add_join_table(const std::string & table_name)
virtual int add_join_table(const std::wstring & table_name)
{
auto res = join_tables_map.insert(std::make_pair(table_name, 1));

View File

@ -68,7 +68,7 @@ FlatExpression * FlatConnector::get_expression()
void FlatConnector::to_text(PT::TextStream & stream, Model & model)
void FlatConnector::to_text(pt::TextStream & stream, Model & model)
{
allocate_default_expression_if_needed();

View File

@ -51,7 +51,7 @@ public:
FlatConnector();
virtual ~FlatConnector();
virtual void to_text(PT::TextStream & stream, Model & model);
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, Tomasz Sowa
* Copyright (c) 2018-2021, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -39,7 +39,7 @@
namespace morm
{
void FlatExpression::esc(const PT::Date & date, PT::TextStream & stream)
void FlatExpression::esc(const pt::Date & date, pt::TextStream & stream, const FT & field_type)
{
date.SerializeISO(stream);
}

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2018, Tomasz Sowa
* Copyright (c) 2018-2021, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -45,7 +45,7 @@ class FlatExpression : public BaseExpression
{
public:
void esc(const PT::Date & date, PT::TextStream & stream);
void esc(const pt::Date & date, pt::TextStream & stream, const FT & field_type);

167
src/ft.h Normal file
View File

@ -0,0 +1,167 @@
/*
* 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_ft
#define headerfile_morm_ft
namespace morm
{
/*
* field types
*/
class FT
{
public:
enum FieldType
{
default_type = 0,
primary_key = 1,
foreign_key = 2,
foreign_key_in_child = 4,
no_insertable = 8,
no_updatable = 16,
no_fetchable = 32, /* not supported yet */
no_removable = 64,
raw_field_name = 128,
dont_use_utf8 = 256,
hexadecimal = 512,
binary = 1024,
};
/*
* type can be a superposition from FieldType values
*/
int type;
FT()
{
type = 0;
}
FT(const FT & field_type)
{
type = field_type.type;
}
FT(FieldType type)
{
this->type = static_cast<int>(type);
}
FT(int type)
{
this->type = type;
}
FT & operator=(const FT & field_type)
{
type = field_type.type;
return *this;
}
bool is_flag_set(int flag_mask) const
{
return (type & flag_mask) != 0;
}
bool is_primary_key() const
{
return is_flag_set(primary_key);
}
bool is_foreign_key() const
{
return is_flag_set(foreign_key);
}
bool is_foreign_key_in_child() const
{
return is_flag_set(foreign_key_in_child);
}
bool is_insertable() const
{
return !is_flag_set(no_insertable);
}
bool is_updatable() const
{
return !is_flag_set(no_updatable);
}
bool is_fetchable() const
{
return !is_flag_set(no_fetchable);
}
bool is_removable() const
{
return !is_flag_set(no_removable);
}
bool is_raw_field_name() const
{
return is_flag_set(raw_field_name);
}
bool use_utf8() const
{
return !is_flag_set(dont_use_utf8);
}
bool is_hexadecimal() const
{
return is_flag_set(hexadecimal);
}
bool is_binary() const
{
return is_flag_set(binary);
}
};
}
#endif

View File

@ -76,80 +76,29 @@ void JSONExpression::field_before()
void JSONExpression::before_short_field_name()
void JSONExpression::before_field_name()
{
(*out_stream) << "\"";
}
void JSONExpression::after_short_field_name()
{
(*out_stream) << "\"";
}
void JSONExpression::before_first_part_long_field_name()
{
(*out_stream) << "\"";
}
void JSONExpression::after_first_part_long_field_name()
{
}
void JSONExpression::before_second_part_long_field_name()
{
}
void JSONExpression::after_second_part_long_field_name()
void JSONExpression::after_field_name()
{
(*out_stream) << "\"";
}
void JSONExpression::before_field_value_string()
void JSONExpression::before_field_value_string(const FT & field_type)
{
(*out_stream) << "\"";
}
void JSONExpression::after_field_value_string()
void JSONExpression::after_field_value_string(const FT & field_type)
{
(*out_stream) << "\"";
}
void JSONExpression::before_field_value(const std::wstring &)
{
before_field_value_string();
}
void JSONExpression::before_field_value(const std::string &)
{
before_field_value_string();
}
void JSONExpression::after_field_value(const std::wstring &)
{
after_field_value_string();
}
void JSONExpression::after_field_value(const std::string &)
{
after_field_value_string();
}
void JSONExpression::before_field_value(const PT::Date &)
{
before_field_value_string();
}
void JSONExpression::after_field_value(const PT::Date &)
{
after_field_value_string();
}
void JSONExpression::put_name_value_separator()
{
(*out_stream) << ':';
@ -168,20 +117,48 @@ void JSONExpression::after_field_value_list()
}
void JSONExpression::esc(char val, PT::TextStream & stream)
void JSONExpression::esc(char val, pt::TextStream & stream, const FT & field_type)
{
switch( val )
if( field_type.is_hexadecimal() || field_type.is_binary() )
{
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;
char_to_hex(val, stream);
}
else
{
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

@ -54,22 +54,11 @@ protected:
void field_before();
void before_short_field_name();
void after_short_field_name();
void before_first_part_long_field_name();
void after_first_part_long_field_name();
void before_second_part_long_field_name();
void after_second_part_long_field_name();
void before_field_name();
void after_field_name();
void before_field_value(const std::wstring &);
void before_field_value(const std::string &);
void after_field_value(const std::wstring &);
void after_field_value(const std::string &);
void put_name_value_separator();
void before_field_value(const PT::Date &);
void after_field_value(const PT::Date &);
void before_field_value_list();
void after_field_value_list();
@ -77,13 +66,13 @@ protected:
// 'morm::JSONExpression::esc' hides overloaded virtual function [-Woverloaded-virtual]
using FlatExpression::esc;
void esc(char val, PT::TextStream & stream);
void esc(char val, pt::TextStream & stream, const FT & field_type);
private:
void before_field_value_string();
void after_field_value_string();
void before_field_value_string(const FT & field_type);
void after_field_value_string(const FT & field_type);
};

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -60,17 +60,17 @@ ModelConnector::~ModelConnector()
}
void ModelConnector::set_logger(PT::Log * log)
void ModelConnector::set_logger(pt::Log * log)
{
this->log = log;
}
void ModelConnector::set_logger(PT::Log & log)
void ModelConnector::set_logger(pt::Log & log)
{
this->log = &log;
}
PT::Log * ModelConnector::get_logger()
pt::Log * ModelConnector::get_logger()
{
return log;
}
@ -91,7 +91,7 @@ void ModelConnector::deallocate_stream()
void ModelConnector::allocate_default_stream()
{
deallocate_stream();
out_stream = new PT::TextStream();
out_stream = new pt::TextStream();
out_stream_allocated = true;
}
@ -133,14 +133,14 @@ void ModelConnector::allocate_default_clearer_if_needed()
}
void ModelConnector::set_stream(PT::TextStream & stream)
void ModelConnector::set_stream(pt::TextStream & stream)
{
deallocate_stream();
this->out_stream = &stream;
}
PT::TextStream * ModelConnector::get_stream()
pt::TextStream * ModelConnector::get_stream()
{
allocate_default_stream_if_needed();
return out_stream;

View File

@ -59,13 +59,13 @@ public:
ModelConnector(const ModelConnector &) = delete;
virtual ~ModelConnector();
virtual void set_logger(PT::Log * log);
virtual void set_logger(PT::Log & log);
virtual void set_logger(pt::Log * log);
virtual void set_logger(pt::Log & log);
virtual PT::Log * get_logger();
virtual pt::Log * get_logger();
virtual void set_stream(PT::TextStream & stream);
virtual PT::TextStream * get_stream();
virtual void set_stream(pt::TextStream & stream);
virtual pt::TextStream * get_stream();
virtual void set_flat_connector(FlatConnector & flat_connector);
virtual FlatConnector * get_flat_connector();
@ -80,12 +80,12 @@ public:
protected:
PT::Log * log;
pt::Log * log;
FlatConnector * flat_connector;
DbConnector * db_connector;
PT::TextStream * out_stream; // IMPROVE ME give here an interface to the base stream (implement him)
pt::TextStream * out_stream; // IMPROVE ME give here an interface to the base stream (implement him)
bool out_stream_allocated;
Clearer * clearer;

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2019, Tomasz Sowa
* Copyright (c) 2019-2021, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -46,6 +46,8 @@ namespace morm
{
class ModelEnv
{
public:
@ -59,11 +61,22 @@ public:
int model_work_submode;
bool dump_mode;
PT::TextStream table_name; // CHECK ME may it should be PT::WTextStream?
PT::TextStream table_name_short;
pt::WTextStream schema_name;
pt::WTextStream table_name;
int table_index;
/*
* optional additional table name
* used in eq(), neq(), ... methods in Finder
*/
const wchar_t * table2_name;
int table2_index;
int field_index;
bool all_fields_are_null;
bool was_primary_key_read;
bool has_primary_key_set;
std::vector<const wchar_t *> * set_field_name_helper;
std::vector<FieldValueHelper> * field_value_helper_tab;
@ -74,7 +87,6 @@ public:
clear();
}
~ModelEnv()
{
}
@ -82,19 +94,18 @@ public:
ModelEnv(const ModelEnv & e)
{
model_data = e.model_data;
finder_helper = e.finder_helper;
cursor_helper = e.cursor_helper;
model_work_mode = e.model_work_mode;
model_work_submode = e.model_work_submode;
dump_mode = e.dump_mode;
copy_global_objects(e);
table_index = e.table_index;
table2_index = e.table2_index;
set_field_name_helper = e.set_field_name_helper;
field_value_helper_tab = e.field_value_helper_tab;
field_index = e.field_index;
all_fields_are_null = e.all_fields_are_null;
was_primary_key_read = e.was_primary_key_read;
has_primary_key_set = e.has_primary_key_set;
// table_name and table_name_short don't have to bo copied
// schema_name and table_name don't have to be copied
table2_name = nullptr;
}
@ -118,16 +129,31 @@ public:
model_work_mode = MORM_MODEL_WORK_MODE_NONE;
model_work_submode = MORM_MODEL_WORK_SUBMODE_NONE;
dump_mode = false;
schema_name.clear();
table_name.clear();
table_name_short.clear();
table2_name = nullptr;
table_index = 0;
table2_index = 0;
set_field_name_helper = nullptr;
field_value_helper_tab = nullptr;
field_index = 0;
all_fields_are_null = false;
was_primary_key_read = false;
has_primary_key_set = false;
}
void add_table_name_to_finder_helper()
{
if( finder_helper )
{
table_index = finder_helper->add_join_table(table_name);
}
else
{
table_index = 0;
}
}
};
}

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2018-2019, Tomasz Sowa
* Copyright (c) 2018-2021, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -92,7 +92,7 @@ bool PostgreSQLConnector::do_query(const char * query_str, PostgreSQLQueryResult
if( log_queries && log )
{
(*log) << PT::Log::log3 << "Morm: query: " << query_str << PT::Log::logend;
(*log) << pt::Log::log3 << "Morm: query: " << query_str << pt::Log::logend;
}
psql_result->psql_result = PQexec(pg_conn, query_str);
@ -119,15 +119,15 @@ bool PostgreSQLConnector::do_query(const char * query_str, PostgreSQLQueryResult
if( err_msg )
{
PT::UTF8ToWide(err_msg, psql_result->error_msg);
pt::utf8_to_wide(err_msg, psql_result->error_msg);
}
if( log )
{
(*log) << PT::Log::log1 << "Morm: Problem with this query: \"" << query_str << '\"' << PT::Log::logend;
(*log) << pt::Log::log1 << "Morm: Problem with this query: \"" << query_str << '\"' << pt::Log::logend;
if( err_msg )
(*log) << PT::Log::log1 << "Morm: " << err_msg << PT::Log::logend;
(*log) << pt::Log::log1 << "Morm: " << err_msg << pt::Log::logend;
}
}
else
@ -171,8 +171,8 @@ 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;
(*log) << pt::Log::log1 << "Morm: expected only one row in sequence result, has: " << psql_result.result_rows
<< pt::Log::logend;
}
}
}
@ -180,8 +180,8 @@ const char * PostgreSQLConnector::query_last_sequence(const wchar_t * sequence_t
{
if( pg_conn && log )
{
(*log) << PT::Log::log1 << "Morm: error (currval) for table: " << sequence_table_name << ", "
<< PQerrorMessage(pg_conn) << PT::Log::logend;
(*log) << pt::Log::log1 << "Morm: error (currval) for table: " << sequence_table_name << ", "
<< PQerrorMessage(pg_conn) << pt::Log::logend;
}
}
}
@ -191,7 +191,7 @@ const char * PostgreSQLConnector::query_last_sequence(const wchar_t * sequence_t
bool PostgreSQLConnector::query(const PT::TextStream & stream, QueryResult & query_result)
bool PostgreSQLConnector::query(const pt::TextStream & stream, QueryResult & query_result)
{
stream.to_string(query_str);
return query(query_str.c_str(), query_result);
@ -264,25 +264,25 @@ bool PostgreSQLConnector::query_remove(const char * query_str, QueryResult & que
}
bool PostgreSQLConnector::query_select(const PT::TextStream & stream, QueryResult & query_result)
bool PostgreSQLConnector::query_select(const pt::TextStream & stream, QueryResult & query_result)
{
stream.to_string(query_str);
return query_select(query_str.c_str(), query_result);
}
bool PostgreSQLConnector::query_update(const PT::TextStream & stream, QueryResult & query_result)
bool PostgreSQLConnector::query_update(const pt::TextStream & stream, QueryResult & query_result)
{
stream.to_string(query_str);
return query_update(query_str.c_str(), query_result);
}
bool PostgreSQLConnector::query_insert(const PT::TextStream & stream, QueryResult & query_result)
bool PostgreSQLConnector::query_insert(const pt::TextStream & stream, QueryResult & query_result)
{
stream.to_string(query_str);
return query_insert(query_str.c_str(), query_result);
}
bool PostgreSQLConnector::query_remove(const PT::TextStream & stream, QueryResult & query_result)
bool PostgreSQLConnector::query_remove(const pt::TextStream & stream, QueryResult & query_result)
{
stream.to_string(query_str);
return query_remove(query_str.c_str(), query_result);
@ -392,128 +392,6 @@ bool PostgreSQLConnector::query_remove(const PT::TextStream & stream, QueryResul
/*
converting from a bytea
the old way (escape format)
*/
/*
int PostgreSQLConnector::CharToInt(char c)
{
return (int)(unsigned char)(c-'0');
}
bool PostgreSQLConnector::IsCorrectOctalDigit(char c)
{
return c>='0' && c<='7';
}
// moves 'i' at least once
// return -1 if there is en error
int PostgreSQLConnector::UnescapeBin(const char * str, size_t & i, size_t len)
{
if( str[i] != '\\' )
return str[i++];
i += 1;
if( i >= len )
return -1;
if( str[i] == '\\' )
return str[i++];
if( i+2 >= len )
{
i = len;
return -1;
}
if( !IsCorrectOctalDigit(str[i]) ||
!IsCorrectOctalDigit(str[i+1]) ||
!IsCorrectOctalDigit(str[i+2]) )
{
i += 3;
return -1;
}
int c = 8*8*CharToInt(str[i]) + 8*CharToInt(str[i+1]) + CharToInt(str[i+2]);
i += 3;
if( c<0 || c>255 )
return -1;
return c;
}
void PostgreSQLConnector::UnescapeBin(const char * str, size_t len, std::string & out, bool clear_out)
{
int c;
size_t i = 0;
if( clear_out )
out.clear();
while( i < len )
{
c = UnescapeBin(str, i, len);
if( c != -1 )
out += c;
}
}
*/
/*
converting from a bytea
the new way (hex format)
*/
//char PostgreSQLConnector::UnescapeBinHexToDigit(char hex)
//{
// if( hex>='0' && hex<='9' )
// return hex - '0';
//
// if( hex>='a' && hex<='z' )
// return hex - 'a' + 10;
//
// if( hex>='A' && hex<='Z' )
// return hex - 'A' + 10;
//
//return 0;
//}
//
//
//void PostgreSQLConnector::UnescapeBin(const char * str, size_t len, std::string & out, bool clear_out)
//{
// if( clear_out )
// out.clear();
//
// if( len < 2 || str[0]!='\\' || str[1]!='x' )
// {
// log << log1 << "Morm: unsupported binary format (skipping)" << logend;
// return;
// }
//
// for(size_t i=2 ; i + 1 < len ; i+=2 )
// {
// int c1 = UnescapeBinHexToDigit(str[i]);
// int c2 = UnescapeBinHexToDigit(str[i+1]);
//
// out += ((c1 << 4) | c2);
// }
//}
void PostgreSQLConnector::set_conn_param(const std::wstring & database_name, const std::wstring & user, const std::wstring & pass)
{
db_database = database_name;
@ -522,9 +400,9 @@ void PostgreSQLConnector::set_conn_param(const std::wstring & database_name, con
}
void PostgreSQLConnector::overwrite(PT::TextStream & stream)
void PostgreSQLConnector::overwrite(pt::TextStream & stream)
{
PT::TextStream::iterator i = stream.begin();
pt::TextStream::iterator i = stream.begin();
for( ; i != stream.end() ; ++i)
{
@ -577,9 +455,9 @@ void PostgreSQLConnector::log_connection_socket()
{
if( pg_conn && log )
{
(*log) << PT::Log::log2 << "Morm: connection to the database works fine" << PT::Log::logend;
(*log) << PT::Log::log3 << "Morm: connection socket: " << PQsocket(pg_conn) << PT::Log::logend;
(*log) << PT::Log::logsave;
(*log) << pt::Log::log2 << "Morm: connection to the database works fine" << pt::Log::logend;
(*log) << pt::Log::log3 << "Morm: connection socket: " << PQsocket(pg_conn) << pt::Log::logend;
(*log) << pt::Log::logsave;
}
}
@ -589,7 +467,7 @@ void PostgreSQLConnector::wait_for_connection()
{
if( log )
{
(*log) << PT::Log::log3 << "Morm: waiting for the db to be ready...." << PT::Log::logend << PT::Log::logsave;
(*log) << pt::Log::log3 << "Morm: waiting for the db to be ready...." << pt::Log::logend << pt::Log::logsave;
}
while( !assert_connection(false) )
@ -620,7 +498,7 @@ bool was_connection = true;
{
if( put_log && log )
{
(*log) << PT::Log::log2 << "Morm: connection to the database is lost, trying to recover" << PT::Log::logend << PT::Log::logsave;
(*log) << pt::Log::log2 << "Morm: connection to the database is lost, trying to recover" << pt::Log::logend << pt::Log::logsave;
}
was_connection = false;
@ -644,7 +522,7 @@ bool was_connection = true;
{
if( put_log && log )
{
(*log) << PT::Log::log1 << "Morm: connection to db server cannot be established" << PT::Log::logend << PT::Log::logsave;
(*log) << pt::Log::log1 << "Morm: connection to db server cannot be established" << pt::Log::logend << pt::Log::logsave;
}
// if( throw_if_no_connection )
@ -665,15 +543,62 @@ void PostgreSQLConnector::set_db_parameters()
{
if( log )
{
(*log) << PT::Log::log1 << "Morm: Can't set the proper client encoding" << PT::Log::logend << PT::Log::logsave;
(*log) << pt::Log::log1 << "Morm: Can't set the proper client encoding" << pt::Log::logend << pt::Log::logsave;
}
}
}
}
void PostgreSQLConnector::log_unsupported_bin_format()
{
if( log )
{
(*log) << pt::Log::log1 << "Morm: unsupported binary format (skipping)" << pt::Log::logend;
}
}
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
{
return unescape_hex_char(str + 2, field_value, field_type);
}
}
void PostgreSQLConnector::unescape_bin_string(const char * str, std::string & out)
{
if( str[0]!='\\' || str[1]!='x' )
{
log_unsupported_bin_format();
}
else
{
unescape_hex_string(str + 2, out);
}
}
void PostgreSQLConnector::unescape_bin_string(const char * str, std::wstring & out, const FT & field_type)
{
if( str[0]!='\\' || str[1]!='x' )
{
log_unsupported_bin_format();
}
else
{
unescape_hex_string(str + 2, out, field_type);
}
}
}

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2018-2019, Tomasz Sowa
* Copyright (c) 2018-2021, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -55,7 +55,7 @@ public:
virtual ~PostgreSQLConnector();
bool query(const PT::TextStream & stream, QueryResult & query_result);
bool query(const pt::TextStream & stream, QueryResult & query_result);
bool query(const char * query_str, QueryResult & query_result);
bool query(const std::string & query_str, QueryResult & query_result);
@ -64,10 +64,10 @@ public:
bool query_insert(const char * query_str, QueryResult & query_result);
bool query_remove(const char * query_str, QueryResult & query_result);
bool query_select(const PT::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_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);
virtual void set_conn_param(const std::wstring & database, const std::wstring & user, const std::wstring & pass);
@ -85,7 +85,7 @@ public:
protected:
PGconn * pg_conn;
PT::TextStream stream;
pt::TextStream stream;
std::string query_str;
std::wstring db_database;
@ -94,10 +94,15 @@ protected:
virtual bool do_query(const char * query_str, PostgreSQLQueryResult * psql_result);
virtual void allocate_default_expression();
virtual void overwrite(PT::TextStream & stream);
virtual void overwrite(pt::TextStream & stream);
virtual const char * query_last_sequence(const wchar_t * sequence_table_name);
virtual QueryResult * create_query_result();
void log_unsupported_bin_format();
size_t unescape_bin_char(const char * str, wchar_t & field_value, const FT & field_type);
void unescape_bin_string(const char * str, std::string & out);
void unescape_bin_string(const char * str, std::wstring & out, const FT & field_type);
};

View File

@ -39,120 +39,60 @@ namespace morm
{
void PostgreSQLExpression::before_short_field_name()
void PostgreSQLExpression::before_field_value_string(const FT & field_type)
{
(*out_stream) << '"';
}
void PostgreSQLExpression::after_short_field_name()
{
(*out_stream) << '"';
}
void PostgreSQLExpression::before_first_part_long_field_name()
{
}
void PostgreSQLExpression::after_first_part_long_field_name()
{
}
void PostgreSQLExpression::before_second_part_long_field_name()
{
before_short_field_name();
}
void PostgreSQLExpression::after_second_part_long_field_name()
{
after_short_field_name();
}
void PostgreSQLExpression::before_field_value_string()
{
// if( output_type == MORM_OUTPUT_TYPE_DB_INSERT ||
// output_type == MORM_OUTPUT_TYPE_DB_UPDATE ||
// output_type == MORM_OUTPUT_TYPE_DB_PRIMARY_KEY )
if( field_type.is_binary() )
{
(*out_stream) << "'\\x";
}
else
if( field_type.is_hexadecimal() )
{
(*out_stream) << "'";
}
else
{
(*out_stream) << "E'";
}
}
void PostgreSQLExpression::after_field_value_string()
void PostgreSQLExpression::after_field_value_string(const FT & field_type)
{
// if( output_type == MORM_OUTPUT_TYPE_DB_INSERT ||
// output_type == MORM_OUTPUT_TYPE_DB_UPDATE ||
// output_type == MORM_OUTPUT_TYPE_DB_PRIMARY_KEY )
(*out_stream) << "'";
}
void PostgreSQLExpression::esc(char val, pt::TextStream & stream, const FT & field_type)
{
if( field_type.is_hexadecimal() || field_type.is_binary() )
{
(*out_stream) << "'";
char_to_hex(val, stream);
}
}
void PostgreSQLExpression::before_field_value(const std::wstring &)
{
before_field_value_string();
}
void PostgreSQLExpression::after_field_value(const std::wstring &)
{
after_field_value_string();
}
void PostgreSQLExpression::before_field_value(const std::string &)
{
before_field_value_string();
}
void PostgreSQLExpression::after_field_value(const std::string &)
{
after_field_value_string();
}
void PostgreSQLExpression::before_field_value(const wchar_t *)
{
before_field_value_string();
}
void PostgreSQLExpression::after_field_value(const wchar_t *)
{
after_field_value_string();
}
void PostgreSQLExpression::before_field_value(const char *)
{
before_field_value_string();
}
void PostgreSQLExpression::after_field_value(const char *)
{
after_field_value_string();
}
void PostgreSQLExpression::esc(char val, PT::TextStream & stream)
{
switch( val )
else
{
case '\\': stream << "\\\\"; break;
case '\'': stream << "\\\'"; break; // don't use "''" because we use the method for PQconnectdb too
default:
if( val != 0 )
switch( val )
{
stream << val;
case '\\': stream << "\\\\"; break;
case '\'': stream << "\\\'"; break; // don't use "''" because we use the method for PQconnectdb too
default:
if( val != 0 )
{
stream << val;
}
}
}
}
DbExpression & PostgreSQLExpression::page(PT::TextStream & stream, size_t page_number, size_t page_size)
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 << " limit " << page_size << " ";
return *this;

View File

@ -45,38 +45,21 @@ class PostgreSQLExpression : public DbExpression
{
public:
void esc(char val, PT::TextStream & stream);
DbExpression & page(PT::TextStream & stream, size_t page_number, size_t page_size);
void esc(char val, pt::TextStream & stream, const FT & field_type);
void esc(const pt::Date & date, pt::TextStream & stream, const FT & field_type);
DbExpression & page(pt::TextStream & stream, size_t page_number, size_t page_size);
protected:
virtual void before_short_field_name();
virtual void after_short_field_name();
virtual void before_first_part_long_field_name();
virtual void after_first_part_long_field_name();
virtual void before_second_part_long_field_name();
virtual void after_second_part_long_field_name();
void before_field_value(const std::wstring &);
void after_field_value(const std::wstring &);
void before_field_value(const std::string &);
void after_field_value(const std::string &);
void before_field_value(const wchar_t *);
void after_field_value(const wchar_t *);
void before_field_value(const char *);
void after_field_value(const char *);
private:
void before_field_value_string();
void after_field_value_string();
void before_field_value_string(const FT & field_type);
void after_field_value_string(const FT & field_type);
};

View File

@ -184,7 +184,7 @@ bool PostgreSQLQueryResult::is_null(int row, int col)
}
void PostgreSQLQueryResult::dump_column_names(PT::Log & log)
void PostgreSQLQueryResult::dump_column_names(pt::Log & log)
{
if( psql_result )
{
@ -192,7 +192,7 @@ void PostgreSQLQueryResult::dump_column_names(PT::Log & log)
for(int i = 0 ; i < cols ; ++i)
{
log << i << ' ' << PQfname(psql_result, i) << PT::Log::logend;
log << i << ' ' << PQfname(psql_result, i) << pt::Log::logend;
}
}
}
@ -255,20 +255,20 @@ void PostgreSQLQueryResult::dump_column_names(PT::Log & log)
//}
//bool PostgreSQLConnector::AssertValueSpace(PGresult * r, int row, int col, PT::Space & space)
//bool PostgreSQLConnector::AssertValueSpace(PGresult * r, int row, int col, pt::Space & space)
//{
// const char * res = AssertValue(r, row, col);
//
// conf_parser.SetSpace(space);
// space.Clear();
//
// PT::SpaceParser::Status status = conf_parser.ParseString(res);
// pt::SpaceParser::Status status = conf_parser.ParseString(res);
//
// if( status != PT::SpaceParser::ok )
// if( status != pt::SpaceParser::ok )
// {
// log << log1 << "Morm: a problem with parsing a PT::Space";
// log << log1 << "Morm: a problem with parsing a pt::Space";
//
// if( status == PT::SpaceParser::syntax_error )
// if( status == pt::SpaceParser::syntax_error )
// log << ", syntax error at line: " << conf_parser.line;
//
// log << logend;

View File

@ -68,7 +68,7 @@ struct PostgreSQLQueryResult : public QueryResult
bool is_null(int row, int col);
void dump_column_names(PT::Log & log);
void dump_column_names(pt::Log & log);
};

View File

@ -85,7 +85,7 @@ const char * QueryResult::get_field_string_value(const char * column_name)
const char * QueryResult::get_field_string_value(const wchar_t * column_name)
{
PT::WideToUTF8(column_name, temp_column_name);
pt::wide_to_utf8(column_name, temp_column_name);
return get_field_string_value(temp_column_name.c_str());
}
@ -98,7 +98,7 @@ int QueryResult::get_column_index(const char * column_name)
int QueryResult::get_column_index(const wchar_t * column_name)
{
PT::WideToUTF8(column_name, temp_column_name);
pt::wide_to_utf8(column_name, temp_column_name);
return get_column_index(temp_column_name.c_str());
}
@ -125,7 +125,7 @@ bool QueryResult::is_null(int row, int col)
}
void QueryResult::dump_column_names(PT::Log & log)
void QueryResult::dump_column_names(pt::Log & log)
{
}

View File

@ -76,7 +76,7 @@ struct QueryResult
virtual int get_value_length(int row, int col);
virtual bool is_null(int row, int col);
virtual void dump_column_names(PT::Log & log);
virtual void dump_column_names(pt::Log & log);
};