Merge pull request 'winix_fullmorm' (#4) from winix_fullmorm into master
Reviewed-on: #4
This commit is contained in:
commit
284cbc5c66
|
@ -3,3 +3,6 @@
|
|||
.settings/
|
||||
*.o
|
||||
*.a
|
||||
log.txt
|
||||
samples/log.txt
|
||||
samples/mormsample
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
191
src/Makefile.dep
191
src/Makefile.dep
|
@ -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
|
@ -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);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
||||
};
|
||||
|
|
346
src/finder.h
346
src/finder.h
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
};
|
||||
|
||||
|
|
890
src/model.cpp
890
src/model.cpp
File diff suppressed because it is too large
Load Diff
1071
src/model.h
1071
src/model.h
File diff suppressed because it is too large
Load Diff
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue