Added flag has_primary_key_set to Model

Now we know whether the primary key is defined or not
and we do not allow to make update/remove if the key is not defined.

And when doing insert/update we can put NULL if child models don't have
the primary key set (fields with has_foreign_key set to true).

Now in after_select() we should also set has_primary_key_set flag
or just call get_last_sequence_for_primary_key instead of get_last_sequence.

fixed: added prefix +00 when serializing PT::Date to PostgreSQL (time zone)
(for a column with a time zone there was a wrong value saved)
This commit is contained in:
2021-03-09 18:10:34 +01:00
parent ff551a64b8
commit 133a45c84b
18 changed files with 474 additions and 110 deletions

View File

@@ -7,13 +7,13 @@ GLOBAL_WORKING_DIR := $(shell pwd)/../..
endif
CXX = g++7
CXX = g++10
#CXX = clang++
# -fsanitize=address
# -Wl,-rpath=/usr/local/lib/gcc5 or just compile with -static-libstdc++
CXXFLAGS = -Wl,-rpath=/usr/local/lib/gcc7 -Wfatal-errors -fPIC -Wall -pedantic -O0 -g3 -gdwarf-2 -pthread -std=c++17 -I/usr/local/include -I$(GLOBAL_WORKING_DIR)/pikotools -I$(GLOBAL_WORKING_DIR)/morm/src
CXXFLAGS = -Wl,-rpath=/usr/local/lib/gcc10 -Wfatal-errors -fPIC -Wall -pedantic -O0 -g3 -gdwarf-2 -pthread -std=c++20 -I/usr/local/include -I$(GLOBAL_WORKING_DIR)/pikotools -I$(GLOBAL_WORKING_DIR)/morm/src
LDFLAGS = -L/usr/local/lib

View File

@@ -20,4 +20,4 @@ main.o: ../../morm/src/cursor.h ../../morm/src/jsonexpression.h
main.o: ../../morm/src/postgresqlexpression.h ../../morm/src/jsonconnector.h
main.o: ../../morm/src/postgresqlconnector.h
main.o: ../../morm/src/postgresqlqueryresult.h person.h language.h
main.o: attachment.h type.h
main.o: attachment.h type.h attachment2.h

View File

@@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2019, Tomasz Sowa
* Copyright (c) 2019-2021, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -38,7 +38,7 @@
#include <string>
#include "morm.h"
#include "type.h"
#include "language.h"
namespace morm
@@ -54,7 +54,7 @@ CREATE TABLE public.attachment (
content text,
some_flags bool,
created_date timestamp with time zone,
bigint language_id,
language_id bigint,
primary key(id)
);
@@ -82,7 +82,6 @@ public:
field(L"name", name);
field(L"content", content);
field(L"attachment_id", L"types", types);
//field(L"types", types);
field(L"some_flags", some_flags);
field(L"created_date", created_date);
field(L"language_id", L"language", language);
@@ -94,9 +93,18 @@ public:
stream << "public.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);
}

120
samples/attachment2.h Normal file
View File

@@ -0,0 +1,120 @@
/*
* 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, false, false, true);
field(L"person_id", person_id);
field(L"name", name);
field(L"content", content);
field(L"attachment_id", L"types", types);
field(L"some_flags", some_flags);
field(L"created_date", created_date);
field(L"language_id", L"language", language);
}
void table_name(PT::TextStream & stream)
{
// schema.table_name or just table_name
stream << "public.attachment2";
}
void after_select()
{
if( has_primary_key_set )
{
morm::Finder<Type> finder(model_connector);
types = finder.select().where().eq(L"attachment_id", id).get_vector();
}
}
void after_insert()
{
get_last_sequence_for_primary_key(L"public.attachment2_id_seq", id);
}
};
}
}
#endif

View File

@@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2019, Tomasz Sowa
* Copyright (c) 2019-2021, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -86,7 +86,7 @@ public:
void after_insert()
{
get_last_sequence(L"public.language_id_seq", id);
get_last_sequence_for_primary_key(L"public.language_id_seq", id);
}

View File

@@ -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,29 +65,31 @@ 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"language_id", L"language", language);
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", L"attachment2", attachment2, true, true, false);
//field(L"id", id, f::no_insertable | f::no_updatable | f::primary_key);
//field(L"person_id", attachment, f::insertable | f::updatable | f::foreign_key);
//field(L"person_id", attachment, f::insertable, f::updatable, f::foreign_key);
}
@@ -99,13 +102,19 @@ public:
void after_select()
{
morm::Finder<Attachment> finder(model_connector);
attachments = finder.select().where().eq(L"person_id", id).get_list();
if( has_primary_key_set )
{
morm::Finder<Attachment> finder(model_connector);
attachments = finder.select().where().eq(L"person_id", id).get_list();
morm::Finder<Attachment2> finder2(model_connector);
attachment2 = finder2.select().where().eq(L"person_id", id).get();
}
}
void after_insert()
{
get_last_sequence(L"public.person_id_seq", id);
get_last_sequence_for_primary_key(L"public.person_id_seq", id);
}

View File

@@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2019, Tomasz Sowa
* Copyright (c) 2019-2021, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -51,23 +51,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"cosik wstawiony dynamicznie";
//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", 191).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 +93,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 +125,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 +134,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 +209,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);

View File

@@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2019, Tomasz Sowa
* Copyright (c) 2019-2021, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -79,7 +79,7 @@ public:
void after_insert()
{
get_last_sequence(L"public.types_id_seq", id);
get_last_sequence_for_primary_key(L"public.types_id_seq", id);
}