diff --git a/winixd/plugins/thread/createthread.cpp b/winixd/plugins/thread/createthread.cpp index 4516674..342295a 100644 --- a/winixd/plugins/thread/createthread.cpp +++ b/winixd/plugins/thread/createthread.cpp @@ -105,13 +105,19 @@ void CreateThread::MakePost() if( functions->CheckAbuse() ) return; + thread.set_connector(model_connector); + thread.clear(); + cur->request->status = system->AddFile(cur->request->item) ? WINIX_ERR_OK : WINIX_ERR_PERMISSION_DENIED; if( cur->request->status == WINIX_ERR_OK ) { - thread.Clear(); thread.file_id = cur->request->item.id; - cur->request->status = tdb->AddThread(thread); + thread.last_item.id = cur->request->item.id; + thread.set_has_primary_key_set(true); + + if( !thread.insert() ) + cur->request->status = WINIX_ERR_PERMISSION_DENIED; } if( cur->request->status == WINIX_ERR_OK ) diff --git a/winixd/plugins/thread/funthread.cpp b/winixd/plugins/thread/funthread.cpp index 04d19cf..0051cf3 100644 --- a/winixd/plugins/thread/funthread.cpp +++ b/winixd/plugins/thread/funthread.cpp @@ -79,19 +79,25 @@ return true; void FunThread::PrepareThread(long file_id) { thread_info->Clear(); - cur->request->status = tdb->GetAnswers(file_id, id_tab); + //cur->request->status = tdb->GetAnswers(file_id, id_tab); + + morm::Finder finder_answers(model_connector); + + std::vector answers = finder_answers. + select(). + where(). + eq(L"file_id", file_id). + get_vector(); + + id_tab.resize(answers.size()); + + for(size_t i = 0 ; i < answers.size() ; ++i) + { + id_tab[i] = answers[i].answer_id; + } if( !id_tab.empty() ) { -// DbItemQuery iq; -// -// if( system->mounts.pmount->IsArg(thread_info->mount_par_thread, L"sort_desc") ) -// iq.sort_date_asc = false; // sort_index_asc we are ignoring -// -// iq.WhereIdIn(id_tab); -// iq.WhereType(Item::file); -// iq.WhereFileType(WINIX_ITEM_FILETYPE_NONE); - morm::Finder finder(model_connector); thread_info->item_tab = finder. diff --git a/winixd/plugins/thread/funthread.h b/winixd/plugins/thread/funthread.h index e2850be..f634bed 100644 --- a/winixd/plugins/thread/funthread.h +++ b/winixd/plugins/thread/funthread.h @@ -38,6 +38,8 @@ #include "functions/functionbase.h" #include "tdb.h" #include "threadinfo.h" +#include "threadfiles.h" + namespace Winix { @@ -63,6 +65,7 @@ private: TDb * tdb; ThreadInfo * thread_info; + std::vector answers; std::vector id_tab; }; diff --git a/winixd/plugins/thread/reply.cpp b/winixd/plugins/thread/reply.cpp index f950573..04c0f80 100644 --- a/winixd/plugins/thread/reply.cpp +++ b/winixd/plugins/thread/reply.cpp @@ -112,11 +112,13 @@ void Reply::MakePost() // !! jak bedzie dostepne assert // ASSERT(files_dir) - if( tdb->GetThread(cur->request->item.id, thread) != WINIX_ERR_OK ) + thread = Thread::get_thread(model_connector, cur->request->item.id); + + if( !thread.found() ) { - thread.Clear(); + thread.clear(); thread.file_id = cur->request->item.id; - tdb->AddThread(thread); + thread.insert(); } answer.Clear(); diff --git a/winixd/plugins/thread/showthreads.cpp b/winixd/plugins/thread/showthreads.cpp index 6d066cb..f22a7f9 100644 --- a/winixd/plugins/thread/showthreads.cpp +++ b/winixd/plugins/thread/showthreads.cpp @@ -98,21 +98,6 @@ bool ShowThreads::Sort::operator()(const Item * item1, const Item * item2) void ShowThreads::ReadFiles() { - // reading files -// DbItemQuery iq; -// iq.SetAll(false, false); -// iq.sel_url = true; -// iq.sel_subject = true; -// iq.sel_date = true; -// iq.sel_user_id = true; -// iq.sel_group_id = true; -// iq.sel_guest_name = true; -// iq.sel_privileges = true; -// iq.sel_date = true; -// iq.WhereParentId(cur->request->dir_tab.back()->id); -// iq.WhereType(Item::file); -// iq.WhereFileType(WINIX_ITEM_FILETYPE_NONE); - morm::Finder finder(model_connector); thread_info->item_tab = finder. @@ -123,7 +108,6 @@ void ShowThreads::ReadFiles() eq(L"content", L"file_type", WINIX_ITEM_FILETYPE_NONE). get_vector(); - //db->GetItems(thread_info->item_tab, iq); system->CheckAccessToItems(thread_info->item_tab); } @@ -160,7 +144,7 @@ void ShowThreads::ReadThreads() for(size_t i=0 ; iitem_sort_tab.size() ; ++i) file_id_tab[i] = thread_info->item_sort_tab[i]->id; - tdb->GetThreads(file_id_tab, thread_info->thread_tab); + thread_info->thread_tab = Thread::get_threads(model_connector, file_id_tab); } diff --git a/winixd/plugins/thread/tdb.cpp b/winixd/plugins/thread/tdb.cpp index cc445c8..bbeac00 100644 --- a/winixd/plugins/thread/tdb.cpp +++ b/winixd/plugins/thread/tdb.cpp @@ -5,7 +5,7 @@ */ /* - * Copyright (c) 2010-2014, Tomasz Sowa + * Copyright (c) 2010-2021, Tomasz Sowa * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -45,18 +45,18 @@ namespace Thread -Error TDb::AddThread(const Thread & thread) -{ - query.Clear(); - query << R("insert into plugins.thread (file_id, replies, last_item, closed) values (") - << thread.file_id - << thread.replies - << thread.last_item_id - << (thread.closed ? 1 : 0 ) - << R(");"); - -return DoCommand(query); -} +//Error TDb::AddThread(const Thread & thread) +//{ +// query.Clear(); +// query << R("insert into plugins.thread (file_id, replies, last_item, closed) values (") +// << thread.file_id +// << thread.replies +// << thread.last_item_id +// << (thread.closed ? 1 : 0 ) +// << R(");"); +// +//return DoCommand(query); +//} @@ -65,10 +65,10 @@ void TDb::SetThreadColumns(PGresult * r) cfile_id = AssertColumn(r, "file_id"); creplies = AssertColumn(r, "replies"); cclosed = AssertColumn(r, "closed"); - clast_item = AssertColumn(r, "last_item"); - cdate_modification = AssertColumn(r, "date_modification"); - cuser_id = AssertColumn(r, "user_id"); - cguest = AssertColumn(r, "guest_name"); +// clast_item = AssertColumn(r, "last_item"); +// cdate_modification = AssertColumn(r, "date_modification"); +// cuser_id = AssertColumn(r, "user_id"); +// cguest = AssertColumn(r, "guest_name"); } @@ -77,95 +77,95 @@ void TDb::SetThread(PGresult * r, int col, Thread & thread) thread.file_id = AssertValueLong(r, col, cfile_id); thread.replies = AssertValueLong(r, col, creplies); thread.closed = AssertValueBool(r, col, cclosed); - thread.last_item_id = AssertValueLong(r, col, clast_item); - thread.last_item_date_modification = AssertValueDate(r, col, cdate_modification); - thread.last_item_user_id = AssertValueLong(r, col, cuser_id); - AssertValueWide(r, col, cguest, thread.last_item_guest_name); + //thread.last_item_id = AssertValueLong(r, col, clast_item); + //thread.last_item_date_modification = AssertValueDate(r, col, cdate_modification); + //thread.last_item_user_id = AssertValueLong(r, col, cuser_id); + //AssertValueWide(r, col, cguest, thread.last_item_guest_name); } -Error TDb::GetThread(long file_id, Thread & thread) -{ - PGresult * r = 0; - Error status = WINIX_ERR_OK; - - try - { - query.Clear(); - query << R("select thread.file_id, thread.replies, thread.closed, thread.last_item, " - "item.date_modification, item.user_id, item.guest_name " - "from plugins.thread left join core.item on thread.last_item = item.id " - "where thread.file_id = ") << file_id << R(";"); - - r = AssertQuery(query); - AssertResult(r, PGRES_TUPLES_OK); - - int rows = Rows(r); - - if( rows > 1 ) - log << log1 << "ThreadDb: there is more than one thread with file_id: " << file_id << logend; - else - if( rows == 0 ) - throw Error(WINIX_ERR_NO_THREAD); - - SetThreadColumns(r); - SetThread(r, 0, thread); - } - catch(const Error & e) - { - status = e; - } - - ClearResult(r); - -return status; -} +//Error TDb::GetThread(long file_id, Thread & thread) +//{ +// PGresult * r = 0; +// Error status = WINIX_ERR_OK; +// +// try +// { +// query.Clear(); +// query << R("select thread.file_id, thread.replies, thread.closed, thread.last_item, " +// "item.date_modification, item.user_id, item.guest_name " +// "from plugins.thread left join core.item on thread.last_item = item.id " +// "where thread.file_id = ") << file_id << R(";"); +// +// r = AssertQuery(query); +// AssertResult(r, PGRES_TUPLES_OK); +// +// int rows = Rows(r); +// +// if( rows > 1 ) +// log << log1 << "ThreadDb: there is more than one thread with file_id: " << file_id << logend; +// else +// if( rows == 0 ) +// throw Error(WINIX_ERR_NO_THREAD); +// +// SetThreadColumns(r); +// SetThread(r, 0, thread); +// } +// catch(const Error & e) +// { +// status = e; +// } +// +// ClearResult(r); +// +//return status; +//} -Error TDb::GetThreads(const std::vector & file_id_tab, std::vector & thread_tab) -{ - PGresult * r = 0; - Error status = WINIX_ERR_OK; - thread_tab.clear(); - - if( file_id_tab.empty() ) - return status; - - try - { - CreateIdList(file_id_tab, list_id); - - // they should be sorted by file_id (they are used in a binary search later) - query.Clear(); - query << R("select thread.file_id, thread.replies, thread.closed, thread.last_item, " - "item.date_modification, item.user_id, item.guest_name " - "from plugins.thread left join core.item on thread.last_item = item.id " - "where thread.file_id in ") << R(list_id) << R(" order by file_id asc;"); - - r = AssertQuery(query); - AssertResult(r, PGRES_TUPLES_OK); - - int rows = Rows(r); - SetThreadColumns(r); - - for(int i=0 ; i & file_id_tab, std::vector & thread_tab) +//{ +// PGresult * r = 0; +// Error status = WINIX_ERR_OK; +// thread_tab.clear(); +// +// if( file_id_tab.empty() ) +// return status; +// +// try +// { +// CreateIdList(file_id_tab, list_id); +// +// // they should be sorted by file_id (they are used in a binary search later) +// query.Clear(); +// query << R("select thread.file_id, thread.replies, thread.closed, thread.last_item, " +// "item.date_modification, item.user_id, item.guest_name " +// "from plugins.thread left join core.item on thread.last_item = item.id " +// "where thread.file_id in ") << R(list_id) << R(" order by file_id asc;"); +// +// r = AssertQuery(query); +// AssertResult(r, PGRES_TUPLES_OK); +// +// int rows = Rows(r); +// SetThreadColumns(r); +// +// for(int i=0 ; i & file_id_tab, std::vector & thread_tab); + //Error AddThread(const Thread & thread); + //Error GetThread(long file_id, Thread & thread); + //Error GetThreads(const std::vector & file_id_tab, std::vector & thread_tab); Error RemoveThread(long file_id); Error AddAnswer(long file_id, long answer_id); @@ -93,7 +93,8 @@ private: DbTextStream query; std::wstring list_id; - int cfile_id, creplies, cclosed, clast_item, cdate_modification, cuser_id, cguest; + int cfile_id, creplies, cclosed; + //int clast_item, cdate_modification, cuser_id, cguest; Thread thread_temp; std::vector file_id_tab; diff --git a/winixd/plugins/thread/templates.cpp b/winixd/plugins/thread/templates.cpp index 1fcba50..fa646f4 100644 --- a/winixd/plugins/thread/templates.cpp +++ b/winixd/plugins/thread/templates.cpp @@ -452,8 +452,8 @@ void thread_sort_tab_last_item_date_modification_nice(Info & i) { Thread & thread = thread_info.thread_tab[thread_index]; - if( thread.last_item_id != -1 ) - print_date_nice(i, thread.last_item_date_modification); + if( thread.last_item.id != -1 ) + print_date_nice(i, thread.last_item.item_content.date_modification); else print_date_nice(i, thread_info.item_sort_tab[item_sort_index]->item_content.date_modification); } @@ -469,10 +469,10 @@ void thread_sort_tab_last_item_user(Info & i) { Thread & thread = thread_info.thread_tab[thread_index]; - if( thread.last_item_id != -1 ) + if( thread.last_item.id != -1 ) { - User * puser = system->users.GetUser(thread.last_item_user_id); - print_user_name(i, puser, thread.last_item_guest_name); + User * puser = system->users.GetUser(thread.last_item.item_content.user_id); + print_user_name(i, puser, thread.last_item.item_content.guest_name); } else { diff --git a/winixd/plugins/thread/thread.cpp b/winixd/plugins/thread/thread.cpp new file mode 100644 index 0000000..0cf158d --- /dev/null +++ b/winixd/plugins/thread/thread.cpp @@ -0,0 +1,122 @@ +/* + * This file is a part of Winix + * and is distributed under the 2-Clause BSD licence. + * Author: Tomasz Sowa + */ + +/* + * 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. + * + */ + +#include "thread.h" +#include "finder.h" + + +namespace Winix +{ + +namespace Thread +{ + + +Thread Thread::get_thread(morm::ModelConnector * model_connector, long file_id) +{ + morm::Finder finder(model_connector); + + Thread thread = finder. + select(). + where(). + eq(L"file_id", file_id). + get(); + + return thread; +} + + +std::vector Thread::get_threads(morm::ModelConnector * model_connector, const std::vector & file_id_tab) +{ + morm::Finder finder(model_connector); + std::vector threads; + + if( !file_id_tab.empty() ) + { + threads = finder. + select(). + where(). + in(L"file_id", file_id_tab). + raw("order by file_id asc"). + get_vector(); + } + + return threads; +} + + + + +bool Thread::do_migration(int & current_table_version) +{ + bool ok = true; + + ok = ok && morm::Model::do_migration(current_table_version, 1, this, &Thread::do_migration_to_1); + + return ok; +} + + +bool Thread::do_migration_to_1() +{ + const char * str = R"sql( + CREATE TABLE plugins.thread ( + file_id bigint NOT NULL, + replies integer, + last_item bigint, + closed smallint + ); + )sql"; + + db_query(str); + return true; +} + + +//bool Thread::do_migration_to_2() +//{ +// const char * str = R"sql( +// +// )sql"; +// +// db_query(str); +// return true; +//} + + + +} // namespace + +} // namespace Winix + diff --git a/winixd/plugins/thread/thread.h b/winixd/plugins/thread/thread.h index 2cf4ab1..947d3a0 100644 --- a/winixd/plugins/thread/thread.h +++ b/winixd/plugins/thread/thread.h @@ -5,7 +5,7 @@ */ /* - * Copyright (c) 2009-2014, Tomasz Sowa + * Copyright (c) 2009-2021, Tomasz Sowa * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -37,47 +37,67 @@ #include #include +#include "model.h" #include "date/date.h" +#include "models/item.h" + namespace Winix { - namespace Thread { -class Thread +class Thread : public morm::Model { public: long file_id; long replies; - bool closed; - - // the last file in a thread - long last_item_id; - pt::Date last_item_date_modification; - long last_item_user_id; - std::wstring last_item_guest_name; + short int closed; + Winix::Item last_item; - void Clear() - { - file_id = -1; - closed = false; - replies = 0; - last_item_id = -1; - last_item_user_id = -1; - last_item_date_modification.Clear(); - last_item_guest_name.clear(); - } - Thread() { - Clear(); } + + + void fields() + { + field(L"file_id", file_id, morm::FT::primary_key); + field(L"replies", replies); + field(L"closed", closed); + field(L"last_item", last_item, morm::FT::no_insertable | morm::FT::no_updatable | morm::FT::no_removable | morm::FT::foreign_key); + } + + + void table() + { + table_name(L"plugins", L"thread"); + } + + + void after_insert() + { + } + + + bool do_migration(int & current_table_version); + + static Thread get_thread(morm::ModelConnector * model_connector, long file_id); + static std::vector get_threads(morm::ModelConnector * model_connector, const std::vector & file_id_tab); + + + +protected: + + bool do_migration_to_1(); + //bool do_migration_to_2(); + + }; diff --git a/winixd/plugins/thread/threadfiles.cpp b/winixd/plugins/thread/threadfiles.cpp new file mode 100644 index 0000000..38d4fc4 --- /dev/null +++ b/winixd/plugins/thread/threadfiles.cpp @@ -0,0 +1,75 @@ +/* + * This file is a part of Winix + * and is distributed under the 2-Clause BSD licence. + * Author: Tomasz Sowa + */ + +/* + * 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. + * + */ + +#include "threadfiles.h" + + +namespace Winix +{ + +namespace Thread +{ + + +bool ThreadFiles::do_migration(int & current_table_version) +{ + bool ok = true; + + ok = ok && morm::Model::do_migration(current_table_version, 1, this, &ThreadFiles::do_migration_to_1); + + return ok; +} + + +bool ThreadFiles::do_migration_to_1() +{ + const char * str = R"sql( + CREATE TABLE plugins.thread_files ( + file_id bigint, + answer_id bigint + ); + )sql"; + + db_query(str); + return true; +} + + + + +} // namespace + +} // namespace Winix + + diff --git a/winixd/plugins/thread/threadfiles.h b/winixd/plugins/thread/threadfiles.h new file mode 100644 index 0000000..2ac56f2 --- /dev/null +++ b/winixd/plugins/thread/threadfiles.h @@ -0,0 +1,97 @@ +/* + * This file is a part of Winix + * and is distributed under the 2-Clause BSD licence. + * Author: Tomasz Sowa + */ + +/* + * Copyright (c) 2008-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_winix_plugins_thread_threadfiles +#define headerfile_winix_plugins_thread_threadfiles + +#include +#include +#include "model.h" + + +namespace Winix +{ + +namespace Thread +{ + + + +class ThreadFiles : public morm::Model +{ +public: + + long file_id; + long answer_id; + + ThreadFiles() + { + } + + + void fields() + { + field(L"file_id", file_id); + field(L"answer_id", answer_id); + } + + void table() + { + table_name(L"plugins", L"thread_files"); + } + + void after_insert() + { + } + + + bool do_migration(int & current_table_version); + + +protected: + + bool do_migration_to_1(); + + +}; + + + +} // namespace + +} // namespace Winix + + + +#endif