added:
removing objects saving objects (either insert or update or remove) git-svn-id: svn://ttmath.org/publicrep/morm/trunk@1091 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
parent
925017300b
commit
4c0d203fc8
|
@ -36,16 +36,6 @@ dbexpression.o: ../../pikotools/convert/strtoint.h
|
|||
dbexpression.o: ../../pikotools/convert/text.h ../../pikotools/convert/misc.h
|
||||
dbexpression.o: ../../pikotools/membuffer/membuffer.h
|
||||
dbexpression.o: ../../pikotools/textstream/types.h morm_types.h
|
||||
finder.o: finder.h model.h ../../pikotools/textstream/textstream.h
|
||||
finder.o: ../../pikotools/space/space.h ../../pikotools/textstream/types.h
|
||||
finder.o: ../../pikotools/date/date.h ../../pikotools/convert/convert.h
|
||||
finder.o: ../../pikotools/convert/inttostr.h
|
||||
finder.o: ../../pikotools/convert/strtoint.h ../../pikotools/convert/text.h
|
||||
finder.o: ../../pikotools/convert/misc.h
|
||||
finder.o: ../../pikotools/membuffer/membuffer.h
|
||||
finder.o: ../../pikotools/textstream/types.h modelconnector.h
|
||||
finder.o: baseexpression.h morm_types.h dbconnector.h dbexpression.h
|
||||
finder.o: flatexpression.h flatconnector.h
|
||||
flatconnector.o: flatconnector.h flatexpression.h baseexpression.h
|
||||
flatconnector.o: ../../pikotools/textstream/textstream.h
|
||||
flatconnector.o: ../../pikotools/space/space.h
|
||||
|
|
|
@ -1 +1 @@
|
|||
o = baseexpression.o dbconnector.o dbexpression.o finder.o flatconnector.o flatexpression.o jsonconnector.o jsonexpression.o model.o modelconnector.o postgresqlconnector.o postgresqlexpression.o
|
||||
o = baseexpression.o dbconnector.o dbexpression.o flatconnector.o flatexpression.o jsonconnector.o jsonexpression.o model.o modelconnector.o postgresqlconnector.o postgresqlexpression.o
|
|
@ -112,11 +112,26 @@ bool DbConnector::query_insert(const PT::TextStream & stream)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool DbConnector::query_remove(const PT::TextStream & stream)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t DbConnector::last_select_size()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::wstring DbConnector::get_last_query_error_msg()
|
||||
{
|
||||
return std::wstring();
|
||||
}
|
||||
|
||||
bool DbConnector::was_error_in_last_query()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void DbConnector::set_current_row_at_beginning()
|
||||
{
|
||||
|
@ -159,12 +174,12 @@ void DbConnector::generate_insert_query(PT::TextStream & stream, Model & model)
|
|||
|
||||
if( db_expression )
|
||||
{
|
||||
db_expression->set_output_type(MORM_OUTPUT_TYPE_DB_UPDATE);
|
||||
|
||||
stream << "insert into ";
|
||||
model.table_name(stream);
|
||||
|
||||
stream << " (";
|
||||
db_expression->set_work_mode(MORM_WORK_MODE_MODEL_FIELDS);
|
||||
db_expression->set_output_type(MORM_OUTPUT_TYPE_DB_UPDATE);
|
||||
db_expression->generate_from_model(stream, model);
|
||||
|
||||
stream << ") values (";
|
||||
|
@ -181,13 +196,12 @@ void DbConnector::generate_update_query(PT::TextStream & stream, Model & model)
|
|||
|
||||
if( db_expression )
|
||||
{
|
||||
db_expression->set_output_type(MORM_OUTPUT_TYPE_DB_UPDATE);
|
||||
|
||||
stream << "update ";
|
||||
model.table_name(stream);
|
||||
stream << " set ";
|
||||
|
||||
stream << " set ";
|
||||
db_expression->set_work_mode(MORM_WORK_MODE_MODEL_FIELDS_VALUES);
|
||||
db_expression->set_output_type(MORM_OUTPUT_TYPE_DB_UPDATE);
|
||||
db_expression->generate_from_model(stream, model);
|
||||
|
||||
stream << " where ";
|
||||
|
@ -198,6 +212,20 @@ void DbConnector::generate_update_query(PT::TextStream & stream, Model & model)
|
|||
}
|
||||
|
||||
|
||||
void DbConnector::generate_remove_query(PT::TextStream & stream, Model & model)
|
||||
{
|
||||
allocate_default_expression_if_needed();
|
||||
|
||||
if( db_expression )
|
||||
{
|
||||
stream << "delete from ";
|
||||
model.table_name(stream);
|
||||
stream << " where ";
|
||||
db_expression->set_work_mode(MORM_WORK_MODE_MODEL_FIELDS_VALUES);
|
||||
db_expression->set_output_type(MORM_OUTPUT_TYPE_DB_PRIMARY_KEY);
|
||||
db_expression->generate_from_model(stream, model);
|
||||
}
|
||||
}
|
||||
|
||||
bool DbConnector::insert(PT::TextStream & stream, Model & model)
|
||||
{
|
||||
|
@ -213,6 +241,13 @@ bool DbConnector::update(PT::TextStream & stream, Model & model)
|
|||
}
|
||||
|
||||
|
||||
bool DbConnector::remove(PT::TextStream & stream, Model & model)
|
||||
{
|
||||
generate_remove_query(stream, model);
|
||||
return query_remove(stream);
|
||||
}
|
||||
|
||||
|
||||
void DbConnector::deallocate_expression()
|
||||
{
|
||||
if( expression_allocated )
|
||||
|
|
|
@ -60,9 +60,11 @@ public:
|
|||
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);
|
||||
|
||||
//void ModelConnector::get_values_from_db(Model & model)
|
||||
|
||||
|
@ -76,8 +78,11 @@ public:
|
|||
virtual bool query_select(const PT::TextStream & stream);
|
||||
virtual bool query_update(const PT::TextStream & stream);
|
||||
virtual bool query_insert(const PT::TextStream & stream);
|
||||
virtual bool query_remove(const PT::TextStream & stream);
|
||||
|
||||
virtual size_t last_select_size();
|
||||
virtual std::wstring get_last_query_error_msg();
|
||||
virtual bool was_error_in_last_query();
|
||||
|
||||
// give me a better name
|
||||
virtual void set_current_row_at_beginning();
|
||||
|
@ -153,6 +158,7 @@ protected:
|
|||
|
||||
DbExpression * db_expression;
|
||||
bool expression_allocated;
|
||||
std::wstring last_query_error_msg;
|
||||
|
||||
virtual void allocate_default_expression() = 0;
|
||||
virtual void allocate_default_expression_if_needed();
|
||||
|
|
|
@ -1,54 +0,0 @@
|
|||
/*
|
||||
* This file is a part of morm
|
||||
* and is distributed under the 2-Clause BSD licence.
|
||||
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2018, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "finder.h"
|
||||
|
||||
|
||||
namespace morm
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace
|
||||
|
166
src/finder.h
166
src/finder.h
|
@ -59,48 +59,94 @@ public:
|
|||
model_connector = nullptr;
|
||||
out_stream = nullptr;
|
||||
db_expression = nullptr;
|
||||
was_query_error = false;
|
||||
}
|
||||
|
||||
|
||||
Finder(PT::TextStream & out_stream)
|
||||
{
|
||||
this->out_stream = &out_stream;
|
||||
this->model_connector = nullptr;
|
||||
db_expression = nullptr;
|
||||
was_query_error = false;
|
||||
}
|
||||
|
||||
Finder(ModelConnector & model_connector)
|
||||
{
|
||||
this->model_connector = &model_connector;
|
||||
out_stream = nullptr;
|
||||
db_expression = nullptr;
|
||||
was_query_error = false;
|
||||
}
|
||||
|
||||
Finder(ModelConnector * model_connector)
|
||||
{
|
||||
this->model_connector = model_connector;
|
||||
out_stream = nullptr;
|
||||
db_expression = nullptr;
|
||||
was_query_error = false;
|
||||
}
|
||||
|
||||
Finder(PT::TextStream & out_stream, ModelConnector & model_connector)
|
||||
{
|
||||
this->out_stream = &out_stream;
|
||||
this->model_connector = &model_connector;
|
||||
db_expression = nullptr;
|
||||
was_query_error = false;
|
||||
}
|
||||
|
||||
Finder(PT::TextStream & out_stream, ModelConnector * model_connector)
|
||||
{
|
||||
this->out_stream = &out_stream;
|
||||
this->model_connector = model_connector;
|
||||
db_expression = nullptr;
|
||||
was_query_error = false;
|
||||
}
|
||||
|
||||
|
||||
Finder<ModelClass> & find(ModelConnector & model_connector)
|
||||
bool was_error()
|
||||
{
|
||||
return was_query_error;
|
||||
}
|
||||
|
||||
std::wstring get_error_msg()
|
||||
{
|
||||
return last_query_error;
|
||||
}
|
||||
|
||||
|
||||
Finder<ModelClass> & select(ModelConnector & model_connector)
|
||||
{
|
||||
this->model_connector = &model_connector;
|
||||
return find();
|
||||
return select();
|
||||
}
|
||||
|
||||
Finder<ModelClass> & select(ModelConnector * model_connector)
|
||||
{
|
||||
this->model_connector = model_connector;
|
||||
return select();
|
||||
}
|
||||
|
||||
Finder<ModelClass> & find(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;
|
||||
return find();
|
||||
return select();
|
||||
}
|
||||
|
||||
Finder<ModelClass> & select(PT::TextStream & out_stream, ModelConnector * model_connector)
|
||||
{
|
||||
this->out_stream = &out_stream;
|
||||
this->model_connector = model_connector;
|
||||
return select();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Finder<ModelClass> & find()
|
||||
Finder<ModelClass> & prepare_to_select()
|
||||
{
|
||||
was_query_error = false;
|
||||
last_query_error.clear();
|
||||
|
||||
if( model_connector )
|
||||
{
|
||||
if( !out_stream )
|
||||
|
@ -113,14 +159,18 @@ public:
|
|||
set_db_expression();
|
||||
|
||||
out_stream->clear();
|
||||
model.set_connector(*model_connector);
|
||||
model.clear();
|
||||
|
||||
(*out_stream) << "SELECT ";
|
||||
model_connector->generate_select_columns(*out_stream, model);
|
||||
(*out_stream) << " FROM ";
|
||||
model.table_name(*out_stream);
|
||||
model.set_connector(model_connector);
|
||||
}
|
||||
else
|
||||
{
|
||||
was_query_error = true;
|
||||
last_query_error = L"out stream object is required";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
was_query_error = true;
|
||||
last_query_error = L"model connector object is required";
|
||||
}
|
||||
|
||||
return *this;
|
||||
|
@ -128,27 +178,23 @@ public:
|
|||
|
||||
|
||||
|
||||
ModelClass find_one()
|
||||
Finder<ModelClass> & select()
|
||||
{
|
||||
//model.set_object_exists(true);
|
||||
prepare_to_select();
|
||||
|
||||
// at the end
|
||||
db_expression = nullptr;
|
||||
return model;
|
||||
if( model_connector && out_stream )
|
||||
{
|
||||
(*out_stream) << "SELECT ";
|
||||
model_connector->generate_select_columns(*out_stream, model);
|
||||
(*out_stream) << " FROM ";
|
||||
model.table_name(*out_stream);
|
||||
(*out_stream) << " ";
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
std::vector<ModelClass> find_many()
|
||||
{
|
||||
std::vector<ModelClass> res;
|
||||
|
||||
|
||||
// at the end
|
||||
db_expression = nullptr;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
Finder<ModelClass> & where()
|
||||
{
|
||||
|
@ -162,8 +208,6 @@ public:
|
|||
}
|
||||
|
||||
|
||||
|
||||
// may better names?
|
||||
Finder<ModelClass> & group_or()
|
||||
{
|
||||
if( db_expression && out_stream )
|
||||
|
@ -315,8 +359,10 @@ public:
|
|||
bool get(ModelClass & result)
|
||||
{
|
||||
bool res = false;
|
||||
result.clear();
|
||||
result.set_object_exists(false);
|
||||
result.clear(); // here has to be a model connector (it clears all fields)
|
||||
|
||||
// what about setting a model connector for the result?
|
||||
// it can be a different object
|
||||
|
||||
if( model_connector && out_stream )
|
||||
{
|
||||
|
@ -324,22 +370,20 @@ public:
|
|||
|
||||
if( db_connector )
|
||||
{
|
||||
res = db_connector->query_select(*out_stream);
|
||||
|
||||
try
|
||||
{
|
||||
result.before_select();
|
||||
res = db_connector->query_select(*out_stream);
|
||||
|
||||
if( res )
|
||||
{
|
||||
result.set_object_exists(true);
|
||||
result.set_connector(*model_connector);
|
||||
result.before_select();
|
||||
result.set_save_mode(Model::DO_UPDATE_ON_SAVE);
|
||||
model_connector->map_values_from_query(result);
|
||||
result.after_select();
|
||||
}
|
||||
|
||||
if( !res )
|
||||
else
|
||||
{
|
||||
// put some log here?
|
||||
result.after_select_failure();
|
||||
}
|
||||
}
|
||||
catch(...)
|
||||
|
@ -389,20 +433,25 @@ public:
|
|||
|
||||
for(size_t i = 0 ; i < len ; ++i)
|
||||
{
|
||||
model.clear();
|
||||
model.set_object_exists(true);
|
||||
model.set_connector(*model_connector);
|
||||
model.before_select();
|
||||
model_connector->map_values_from_query(model);
|
||||
model.after_select();
|
||||
result.push_back(model);
|
||||
result.emplace_back(); // it returns a reference from c++17
|
||||
ModelClass & added_model = result.back();
|
||||
|
||||
added_model.set_connector(model_connector);
|
||||
added_model.clear();
|
||||
added_model.set_save_mode(Model::DO_UPDATE_ON_SAVE);
|
||||
added_model.before_select();
|
||||
model_connector->map_values_from_query(added_model);
|
||||
added_model.after_select();
|
||||
|
||||
db_connector->advance_current_row();
|
||||
}
|
||||
}
|
||||
|
||||
if( !res )
|
||||
// if there was a failure we do not call after_select_failure()
|
||||
// because there are no any objects in the list
|
||||
}
|
||||
else
|
||||
{
|
||||
// put some log here?
|
||||
// log
|
||||
}
|
||||
}
|
||||
catch(...)
|
||||
|
@ -422,7 +471,7 @@ public:
|
|||
{
|
||||
std::list<ModelClass> result;
|
||||
get_list(result, false);
|
||||
return result;
|
||||
return std::move(result);
|
||||
}
|
||||
|
||||
|
||||
|
@ -433,7 +482,8 @@ private:
|
|||
ModelConnector * model_connector;
|
||||
DbExpression * db_expression;
|
||||
ModelClass model;
|
||||
|
||||
bool was_query_error;
|
||||
std::wstring last_query_error;
|
||||
|
||||
void set_db_expression()
|
||||
{
|
||||
|
|
143
src/model.cpp
143
src/model.cpp
|
@ -41,13 +41,70 @@ namespace morm
|
|||
Model::Model()
|
||||
{
|
||||
model_connector = nullptr;
|
||||
morm_object_exists = false;
|
||||
save_mode = DO_INSERT_ON_SAVE;
|
||||
}
|
||||
|
||||
Model::~Model()
|
||||
{
|
||||
}
|
||||
|
||||
void Model::set_save_mode(SaveMode save_mode)
|
||||
{
|
||||
this->save_mode = save_mode;
|
||||
}
|
||||
|
||||
|
||||
Model::SaveMode Model::get_save_mode()
|
||||
{
|
||||
return save_mode;
|
||||
}
|
||||
|
||||
|
||||
void Model::mark_to_delete()
|
||||
{
|
||||
save_mode = DO_DELETE_ON_SAVE;
|
||||
}
|
||||
|
||||
void Model::mark_to_remove()
|
||||
{
|
||||
save_mode = DO_DELETE_ON_SAVE;
|
||||
}
|
||||
|
||||
void Model::mark_to_insert()
|
||||
{
|
||||
save_mode = DO_INSERT_ON_SAVE;
|
||||
}
|
||||
|
||||
|
||||
void Model::mark_to_update()
|
||||
{
|
||||
save_mode = DO_UPDATE_ON_SAVE;
|
||||
}
|
||||
|
||||
|
||||
bool Model::was_db_error()
|
||||
{
|
||||
if( model_connector )
|
||||
{
|
||||
return model_connector->was_db_error();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
std::wstring Model::get_db_error()
|
||||
{
|
||||
if( model_connector )
|
||||
{
|
||||
return model_connector->get_db_error();
|
||||
}
|
||||
|
||||
return std::wstring();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Model::table_name(PT::TextStream & stream)
|
||||
{
|
||||
}
|
||||
|
@ -58,20 +115,21 @@ void Model::set_connector(ModelConnector & connector)
|
|||
model_connector = &connector;
|
||||
}
|
||||
|
||||
void Model::set_object_exists(bool object_exists)
|
||||
void Model::set_connector(ModelConnector * connector)
|
||||
{
|
||||
this->morm_object_exists = object_exists;
|
||||
model_connector = connector;
|
||||
}
|
||||
|
||||
|
||||
bool Model::object_exists()
|
||||
{
|
||||
return morm_object_exists;
|
||||
return save_mode == DO_UPDATE_ON_SAVE;
|
||||
}
|
||||
|
||||
|
||||
bool Model::found()
|
||||
{
|
||||
return morm_object_exists;
|
||||
return save_mode == DO_UPDATE_ON_SAVE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -107,6 +165,7 @@ std::string Model::to_text()
|
|||
return str;
|
||||
}
|
||||
|
||||
|
||||
std::string Model::to_string()
|
||||
{
|
||||
return to_text();
|
||||
|
@ -126,7 +185,10 @@ void Model::insert()
|
|||
{
|
||||
if( model_connector )
|
||||
{
|
||||
model_connector->insert(*this);
|
||||
if( model_connector->insert(*this) )
|
||||
{
|
||||
save_mode = DO_UPDATE_ON_SAVE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -149,6 +211,49 @@ void Model::update()
|
|||
}
|
||||
|
||||
|
||||
void Model::generate_remove_query(PT::TextStream & stream)
|
||||
{
|
||||
if( model_connector )
|
||||
{
|
||||
model_connector->generate_remove_query(stream, *this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Model::remove()
|
||||
{
|
||||
if( model_connector )
|
||||
{
|
||||
if( model_connector->remove(*this) )
|
||||
{
|
||||
save_mode = DO_INSERT_ON_SAVE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Model::save()
|
||||
{
|
||||
switch( save_mode )
|
||||
{
|
||||
case DO_DELETE_ON_SAVE:
|
||||
remove();
|
||||
break;
|
||||
|
||||
case DO_INSERT_ON_SAVE:
|
||||
insert();
|
||||
break;
|
||||
|
||||
case DO_UPDATE_ON_SAVE:
|
||||
update();
|
||||
break;
|
||||
|
||||
case DO_NOTHING_ON_SAVE:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Model::clear()
|
||||
{
|
||||
if( model_connector )
|
||||
|
@ -156,7 +261,7 @@ void Model::clear()
|
|||
model_connector->clear_values(*this);
|
||||
}
|
||||
|
||||
morm_object_exists = false;
|
||||
save_mode = DO_INSERT_ON_SAVE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -172,6 +277,10 @@ void Model::before_update()
|
|||
{
|
||||
}
|
||||
|
||||
void Model::before_remove()
|
||||
{
|
||||
}
|
||||
|
||||
void Model::after_select()
|
||||
{
|
||||
}
|
||||
|
@ -184,6 +293,26 @@ void Model::after_update()
|
|||
{
|
||||
}
|
||||
|
||||
void Model::after_remove()
|
||||
{
|
||||
}
|
||||
|
||||
void Model::after_select_failure()
|
||||
{
|
||||
}
|
||||
|
||||
void Model::after_insert_failure()
|
||||
{
|
||||
}
|
||||
|
||||
void Model::after_update_failure()
|
||||
{
|
||||
}
|
||||
|
||||
void Model::after_remove_failure()
|
||||
{
|
||||
}
|
||||
|
||||
int Model::get_connector_mode()
|
||||
{
|
||||
if( model_connector )
|
||||
|
|
43
src/model.h
43
src/model.h
|
@ -51,7 +51,34 @@ class Model
|
|||
{
|
||||
public:
|
||||
|
||||
enum SaveMode
|
||||
{
|
||||
DO_INSERT_ON_SAVE,
|
||||
DO_UPDATE_ON_SAVE,
|
||||
DO_DELETE_ON_SAVE,
|
||||
DO_NOTHING_ON_SAVE,
|
||||
};
|
||||
|
||||
virtual void set_save_mode(SaveMode save_mode);
|
||||
virtual SaveMode get_save_mode();
|
||||
|
||||
virtual void mark_to_delete();
|
||||
virtual void mark_to_remove();
|
||||
|
||||
virtual void mark_to_insert();
|
||||
virtual void mark_to_update();
|
||||
|
||||
virtual bool object_exists();
|
||||
virtual bool found();
|
||||
|
||||
|
||||
virtual bool was_db_error();
|
||||
virtual std::wstring get_db_error();
|
||||
|
||||
|
||||
void set_connector(ModelConnector & connector);
|
||||
void set_connector(ModelConnector * connector);
|
||||
|
||||
|
||||
/*
|
||||
* map fields to names
|
||||
|
@ -81,10 +108,11 @@ public:
|
|||
virtual void generate_update_query(PT::TextStream & stream);
|
||||
virtual void update();
|
||||
|
||||
virtual void set_object_exists(bool object_exists);
|
||||
virtual void generate_remove_query(PT::TextStream & stream);
|
||||
virtual void remove();
|
||||
|
||||
virtual void save();
|
||||
|
||||
virtual bool object_exists();
|
||||
virtual bool found();
|
||||
|
||||
// set object to default values
|
||||
virtual void clear();
|
||||
|
@ -93,7 +121,7 @@ public:
|
|||
protected:
|
||||
|
||||
ModelConnector * model_connector;
|
||||
bool morm_object_exists;
|
||||
SaveMode save_mode;
|
||||
|
||||
Model();
|
||||
virtual ~Model();
|
||||
|
@ -101,10 +129,17 @@ protected:
|
|||
virtual void before_select();
|
||||
virtual void before_insert();
|
||||
virtual void before_update();
|
||||
virtual void before_remove();
|
||||
|
||||
virtual void after_select();
|
||||
virtual void after_insert();
|
||||
virtual void after_update();
|
||||
virtual void after_remove();
|
||||
|
||||
virtual void after_select_failure();
|
||||
virtual void after_insert_failure();
|
||||
virtual void after_update_failure();
|
||||
virtual void after_remove_failure();
|
||||
|
||||
virtual int get_connector_mode();
|
||||
|
||||
|
|
|
@ -146,6 +146,30 @@ DbConnector * ModelConnector::get_db_connector()
|
|||
}
|
||||
|
||||
|
||||
bool ModelConnector::was_db_error()
|
||||
{
|
||||
if( db_connector )
|
||||
{
|
||||
return db_connector->was_error_in_last_query();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
std::wstring ModelConnector::get_db_error()
|
||||
{
|
||||
if( db_connector )
|
||||
{
|
||||
return db_connector->get_last_query_error_msg();
|
||||
}
|
||||
|
||||
return std::wstring();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void ModelConnector::to_text(PT::TextStream & stream, Model & model)
|
||||
{
|
||||
if( flat_connector )
|
||||
|
@ -219,8 +243,23 @@ void ModelConnector::generate_update_query(PT::TextStream & stream, Model & mode
|
|||
}
|
||||
|
||||
|
||||
void ModelConnector::insert(Model & model)
|
||||
void ModelConnector::generate_remove_query(PT::TextStream & stream, Model & model)
|
||||
{
|
||||
if( db_connector )
|
||||
{
|
||||
model_connector_mode = MORM_MODEL_CONNECTOR_MODE_GENERATING_DB_EXPRESSION;
|
||||
db_connector->generate_remove_query(stream, model);
|
||||
model_connector_mode = MORM_MODEL_CONNECTOR_MODE_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool ModelConnector::insert(Model & model)
|
||||
{
|
||||
bool result = false;
|
||||
allocate_default_stream_if_needed();
|
||||
|
||||
if( db_connector && out_stream )
|
||||
|
@ -230,17 +269,24 @@ void ModelConnector::insert(Model & model)
|
|||
|
||||
model.before_insert();
|
||||
out_stream->clear();
|
||||
db_connector->insert(*out_stream, model);
|
||||
model.after_insert();
|
||||
result = db_connector->insert(*out_stream, model);
|
||||
|
||||
if( result )
|
||||
model.after_insert();
|
||||
else
|
||||
model.after_insert_failure();
|
||||
|
||||
//db_connector_callback = nullptr;
|
||||
model_connector_mode = MORM_MODEL_CONNECTOR_MODE_NONE;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void ModelConnector::update(Model & model)
|
||||
bool ModelConnector::update(Model & model)
|
||||
{
|
||||
bool result = false;
|
||||
allocate_default_stream_if_needed();
|
||||
|
||||
if( db_connector && out_stream )
|
||||
|
@ -250,17 +296,56 @@ void ModelConnector::update(Model & model)
|
|||
|
||||
model.before_update();
|
||||
out_stream->clear();
|
||||
db_connector->update(*out_stream, model);
|
||||
model.after_update();
|
||||
result = db_connector->update(*out_stream, model);
|
||||
|
||||
if( result )
|
||||
model.after_update();
|
||||
else
|
||||
model.after_update_failure();
|
||||
|
||||
//db_connector_callback = nullptr;
|
||||
model_connector_mode = MORM_MODEL_CONNECTOR_MODE_NONE;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool ModelConnector::remove(Model & model)
|
||||
{
|
||||
bool result = false;
|
||||
allocate_default_stream_if_needed();
|
||||
|
||||
if( db_connector && out_stream )
|
||||
{
|
||||
model_connector_mode = MORM_MODEL_CONNECTOR_MODE_GENERATING_DB_EXPRESSION;
|
||||
//db_connector_callback = db_connector;
|
||||
|
||||
model.before_remove();
|
||||
out_stream->clear();
|
||||
result = db_connector->remove(*out_stream, model);
|
||||
|
||||
if( result )
|
||||
model.after_remove();
|
||||
else
|
||||
model.after_remove_failure();
|
||||
|
||||
//db_connector_callback = nullptr;
|
||||
model_connector_mode = MORM_MODEL_CONNECTOR_MODE_NONE;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void ModelConnector::map_values_from_query(Model & model)
|
||||
{
|
||||
// CHECK ME
|
||||
// may we should set model.model_connector() to this?
|
||||
// the same in other methods which get a model parameter
|
||||
|
||||
if( db_connector )
|
||||
{
|
||||
model_connector_mode = MORM_MODEL_CONNECTOR_MODE_READING_VALUE_FROM_DB;
|
||||
|
|
|
@ -63,6 +63,10 @@ public:
|
|||
// FIX ME
|
||||
// add c-copy ctr (allocate a new stream and expression)
|
||||
|
||||
virtual bool was_db_error();
|
||||
virtual std::wstring get_db_error();
|
||||
|
||||
|
||||
virtual void set_stream(PT::TextStream & stream);
|
||||
virtual PT::TextStream * get_stream();
|
||||
|
||||
|
@ -80,9 +84,11 @@ public:
|
|||
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 insert(Model & model);
|
||||
virtual void update(Model & model);
|
||||
virtual bool insert(Model & model);
|
||||
virtual bool update(Model & model);
|
||||
virtual bool remove(Model & model);
|
||||
|
||||
virtual void map_values_from_query(Model & model);
|
||||
|
||||
|
|
|
@ -91,6 +91,8 @@ void PostgreSQLConnector::clear_last_query_result()
|
|||
res.result_rows = 0;
|
||||
res.status = PGRES_EMPTY_QUERY;
|
||||
res.cur_row = 0;
|
||||
res.error_msg.clear(); // may overwrite it first?
|
||||
res.was_error = false;
|
||||
|
||||
query_results.pop_back();
|
||||
}
|
||||
|
@ -132,6 +134,59 @@ bool PostgreSQLConnector::is_last_result(ExecStatusType t)
|
|||
}
|
||||
|
||||
|
||||
std::wstring PostgreSQLConnector::get_last_query_error_msg()
|
||||
{
|
||||
if( !query_results.empty() )
|
||||
{
|
||||
return query_results.back().error_msg;
|
||||
}
|
||||
|
||||
return std::wstring();
|
||||
}
|
||||
|
||||
|
||||
void PostgreSQLConnector::set_last_query_error_msg(const char * error_msg)
|
||||
{
|
||||
if( !query_results.empty() )
|
||||
{
|
||||
if( error_msg )
|
||||
{
|
||||
PT::UTF8ToWide(error_msg, query_results.back().error_msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PostgreSQLConnector::set_last_query_error_msg(const wchar_t * error_msg)
|
||||
{
|
||||
if( !query_results.empty() )
|
||||
{
|
||||
if( error_msg )
|
||||
{
|
||||
query_results.back().error_msg = error_msg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool PostgreSQLConnector::was_error_in_last_query()
|
||||
{
|
||||
if( !query_results.empty() )
|
||||
{
|
||||
return query_results.back().was_error;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void PostgreSQLConnector::set_was_error_in_last_query(bool was_error)
|
||||
{
|
||||
if( !query_results.empty() )
|
||||
{
|
||||
query_results.back().was_error = was_error;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PostgreSQLConnector::allocate_default_expression()
|
||||
|
@ -233,19 +288,55 @@ bool PostgreSQLConnector::query(const std::string & query_str)
|
|||
|
||||
bool PostgreSQLConnector::query_select(const char * query_str)
|
||||
{
|
||||
return (query(query_str) && last_query_status() == PGRES_TUPLES_OK);
|
||||
bool result = (query(query_str) && last_query_status() == PGRES_TUPLES_OK);
|
||||
|
||||
if( !result )
|
||||
{
|
||||
set_was_error_in_last_query(true);
|
||||
set_last_query_error_msg(PQerrorMessage(pg_conn));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool PostgreSQLConnector::query_update(const char * query_str)
|
||||
{
|
||||
return (query(query_str) && last_query_status() == PGRES_COMMAND_OK);
|
||||
bool result = (query(query_str) && last_query_status() == PGRES_COMMAND_OK);
|
||||
|
||||
if( !result )
|
||||
{
|
||||
set_was_error_in_last_query(true);
|
||||
set_last_query_error_msg(PQerrorMessage(pg_conn));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool PostgreSQLConnector::query_insert(const char * query_str)
|
||||
{
|
||||
return (query(query_str) && last_query_status() == PGRES_COMMAND_OK);
|
||||
bool result = (query(query_str) && last_query_status() == PGRES_COMMAND_OK);
|
||||
|
||||
if( !result )
|
||||
{
|
||||
set_was_error_in_last_query(true);
|
||||
set_last_query_error_msg(PQerrorMessage(pg_conn));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool PostgreSQLConnector::query_remove(const char * query_str)
|
||||
{
|
||||
bool result = (query(query_str) && last_query_status() == PGRES_COMMAND_OK);
|
||||
|
||||
if( !result )
|
||||
{
|
||||
set_was_error_in_last_query(true);
|
||||
set_last_query_error_msg(PQerrorMessage(pg_conn));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
bool PostgreSQLConnector::query_select(const PT::TextStream & stream)
|
||||
|
@ -266,6 +357,11 @@ bool PostgreSQLConnector::query_insert(const PT::TextStream & stream)
|
|||
return query_insert(query_str.c_str());
|
||||
}
|
||||
|
||||
bool PostgreSQLConnector::query_remove(const PT::TextStream & stream)
|
||||
{
|
||||
stream.to_string(query_str);
|
||||
return query_remove(query_str.c_str());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@ namespace morm
|
|||
class PostgreSQLConnector : public DbConnector
|
||||
{
|
||||
public:
|
||||
|
||||
PostgreSQLConnector();
|
||||
virtual ~PostgreSQLConnector();
|
||||
|
||||
|
@ -54,10 +55,16 @@ public:
|
|||
void clear_last_query_result();
|
||||
|
||||
// give me a better names
|
||||
virtual size_t last_select_size(); // was: last_select_size
|
||||
virtual size_t last_select_size();
|
||||
virtual ExecStatusType last_query_status();
|
||||
virtual bool is_last_result(ExecStatusType t); // was: is_last_result
|
||||
|
||||
virtual std::wstring get_last_query_error_msg();
|
||||
virtual void set_last_query_error_msg(const char * error_msg);
|
||||
virtual void set_last_query_error_msg(const wchar_t * error_msg);
|
||||
|
||||
virtual bool was_error_in_last_query();
|
||||
virtual void set_was_error_in_last_query(bool was_error);
|
||||
|
||||
void set_log_queries(bool log_queries);
|
||||
|
||||
|
@ -68,10 +75,12 @@ public:
|
|||
bool query_select(const char * query_str);
|
||||
bool query_update(const char * query_str);
|
||||
bool query_insert(const char * query_str);
|
||||
bool query_remove(const char * query_str);
|
||||
|
||||
bool query_select(const PT::TextStream & stream);
|
||||
bool query_update(const PT::TextStream & stream);
|
||||
bool query_insert(const PT::TextStream & stream);
|
||||
bool query_remove(const PT::TextStream & stream);
|
||||
|
||||
|
||||
// give me a better name
|
||||
|
@ -134,6 +143,8 @@ protected:
|
|||
size_t result_rows; // how many rows in the result query
|
||||
ExecStatusType status;
|
||||
size_t cur_row; // used for reading
|
||||
bool was_error;
|
||||
std::wstring error_msg;
|
||||
|
||||
QueryResult()
|
||||
{
|
||||
|
@ -141,6 +152,7 @@ protected:
|
|||
result_rows = 0;
|
||||
status = PGRES_EMPTY_QUERY;
|
||||
cur_row = 0;
|
||||
was_error = false;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -154,6 +166,7 @@ protected:
|
|||
virtual const char * get_field_string_value(const wchar_t * field_name);
|
||||
|
||||
|
||||
|
||||
const char * query_last_sequence(const wchar_t * sequence_table_name);
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue