Skip to content

Commit 912654b

Browse files
committed
Refactor notes selection to use selector struct
Replaces the legacy select_notes function with a new version that takes a selector struct, simplifying and clarifying the API for selecting notes. Updates all usages throughout the codebase, including tests, to use the new selector-based approach. Removes the bible_selector field from the selector struct and adjusts logic to handle Bible filtering via the bibles vector. Cleans up related comments and improves code readability. #1046
1 parent 26d11e4 commit 912654b

File tree

9 files changed

+538
-432
lines changed

9 files changed

+538
-432
lines changed

changes/change.cpp

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -122,19 +122,23 @@ std::string changes_change (Webserver_Request& webserver_request)
122122

123123

124124
// Get notes for the passage.
125-
std::vector<int> notes = database_notes.select_notes (bibles, // Bibles.
126-
passage.m_book, passage.m_chapter, filter::strings::convert_to_int (passage.m_verse),
127-
0, // Passage selector.
128-
0, // Edit selector.
129-
0, // Non-edit selector.
130-
{}, // Status selectors.
131-
"", // Bible selector.
132-
"", // Assignment selector.
133-
0, // Subscription selector.
134-
-1, // Severity selector.
135-
0, // Text selector.
136-
"", // Search text.
137-
-1); // Limit.
125+
Database_Notes::selector selector {
126+
.bibles = bibles,
127+
.book = passage.m_book, \
128+
.chapter = passage.m_chapter,
129+
.verse = filter::strings::convert_to_int (passage.m_verse),
130+
.passage_selector = 0,
131+
.edit_selector = 0,
132+
.non_edit_selector = 0,
133+
.status_selectors = {},
134+
.assignment_selector = "",
135+
.subscription_selector = 0,
136+
.severity_selector = -1,
137+
.text_selector = 0,
138+
.search_text = "",
139+
.limit = -1
140+
};
141+
std::vector<int> notes = database_notes.select_notes(selector);
138142

139143
// Remove the ones marked for deletion.
140144
{
@@ -144,7 +148,7 @@ std::string changes_change (Webserver_Request& webserver_request)
144148
notes2.push_back (note);
145149
}
146150
}
147-
notes = notes2;
151+
notes = std::move(notes2);
148152
}
149153

150154
// Sort them, most recent notes first.
@@ -154,7 +158,7 @@ std::string changes_change (Webserver_Request& webserver_request)
154158
timestamps.push_back (timestap);
155159
}
156160
filter::strings::quick_sort (timestamps, notes, 0, static_cast <unsigned int> (notes.size ()));
157-
reverse (notes.begin(), notes.end());
161+
std::reverse (notes.begin(), notes.end());
158162

159163

160164
// Whether there"s a live notes editor available.

database/notes.cpp

Lines changed: 8 additions & 197 deletions
Original file line numberDiff line numberDiff line change
@@ -596,190 +596,7 @@ int Database_Notes::store_new_note (const std::string& bible, int book, int chap
596596
}
597597

598598

599-
// Returns an array of note identifiers selected.
600-
std::vector <int> Database_Notes::select_notes (std::vector <std::string> bibles, int book, int chapter, int verse, int passage_selector, int edit_selector, int non_edit_selector, const std::vector<std::string>& status_selectors, std::string bible_selector, std::string assignment_selector, bool subscription_selector, int severity_selector, int text_selector, const std::string& search_text, int limit)// Todo phase out.
601-
{
602-
const std::string& username = m_webserver_request.session_logic ()->get_username ();
603-
std::vector <int> identifiers;
604-
// SQL SELECT statement.
605-
std::string query = notes_select_identifier ();
606-
// SQL optional fulltext search statement sorted on relevance.
607-
if (text_selector == 1) {
608-
query.append (notes_optional_fulltext_search_relevance_statement (search_text));
609-
}
610-
// SQL FROM ... WHERE statement.
611-
query.append (notes_from_where_statement ());
612-
// Consider passage selector.
613-
std::string passage;
614-
switch (passage_selector) {
615-
case 0:
616-
// Select notes that refer to the current verse.
617-
// It means that the book, the chapter, and the verse, should match.
618-
passage = encode_passage (book, chapter, verse);
619-
query.append (" AND passage LIKE '%" + passage + "%' ");
620-
break;
621-
case 1:
622-
// Select notes that refer to the current chapter.
623-
// It means that the book and the chapter should match.
624-
passage = encode_passage (book, chapter, -1);
625-
query.append (" AND passage LIKE '%" + passage + "%' ");
626-
break;
627-
case 2:
628-
// Select notes that refer to the current book.
629-
// It means that the book should match.
630-
passage = encode_passage (book, -1, -1);
631-
query.append (" AND passage LIKE '%" + passage + "%' ");
632-
break;
633-
case 3:
634-
// Select notes that refer to any passage: No constraint to apply here.
635-
break;
636-
default: break;
637-
}
638-
// Consider edit selector.
639-
int time { 0 };
640-
switch (edit_selector) {
641-
case 0:
642-
// Select notes that have been edited at any time. Apply no constraint.
643-
time = 0;
644-
break;
645-
case 1:
646-
// Select notes that have been edited during the last 30 days.
647-
time = filter::date::seconds_since_epoch () - 30 * 24 * 3600;
648-
break;
649-
case 2:
650-
// Select notes that have been edited during the last 7 days.
651-
time = filter::date::seconds_since_epoch () - 7 * 24 * 3600;
652-
break;
653-
case 3:
654-
// Select notes that have been edited since yesterday.
655-
time = filter::date::seconds_since_epoch () - 1 * 24 * 3600 - filter::date::numerical_hour (filter::date::seconds_since_epoch ()) * 3600;
656-
break;
657-
case 4:
658-
// Select notes that have been edited today.
659-
time = filter::date::seconds_since_epoch () - filter::date::numerical_hour (filter::date::seconds_since_epoch ()) * 3600;
660-
break;
661-
default: break;
662-
}
663-
if (time != 0) {
664-
query.append (" AND modified >= ");
665-
query.append (std::to_string (time));
666-
query.append (" ");
667-
}
668-
// Consider non-edit selector.
669-
int nonedit { 0 };
670-
switch (non_edit_selector) {
671-
case 0:
672-
// Select notes that have not been edited at any time. Apply no constraint.
673-
nonedit = 0;
674-
break;
675-
case 1:
676-
// Select notes that have not been edited for a day.
677-
nonedit = filter::date::seconds_since_epoch () - 1 * 24 * 3600;
678-
break;
679-
case 2:
680-
// Select notes that have not been edited for two days.
681-
nonedit = filter::date::seconds_since_epoch () - 2 * 24 * 3600;
682-
break;
683-
case 3:
684-
// Select notes that have not been edited for a week.
685-
nonedit = filter::date::seconds_since_epoch () - 7 * 24 * 3600;
686-
break;
687-
case 4:
688-
// Select notes that have not been edited for a month.
689-
nonedit = filter::date::seconds_since_epoch () - 30 * 24 * 3600;
690-
break;
691-
case 5:
692-
// Select notes that have not been edited for a year.
693-
nonedit = filter::date::seconds_since_epoch () - 365 * 24 * 3600;
694-
break;
695-
default: break;
696-
}
697-
if (nonedit != 0) {
698-
query.append (" AND modified <= ");
699-
query.append (std::to_string (nonedit));
700-
query.append (" ");
701-
}
702-
// Consider the status selectors.
703-
if (!status_selectors.empty()) {
704-
query.append (" AND (status = '' ");
705-
for (const auto& status : status_selectors) {
706-
query.append (" OR status = '");
707-
query.append (status);
708-
query.append ("' ");
709-
}
710-
query.append (" ) ");
711-
}
712-
713-
// Consider two different Bible constraints:
714-
// 1. The vector of bibles: "bibles".
715-
// This contains all the Bibles a user has access to, so only notes that refer to any Bible in this lot are going to be selected.
716-
// 2. The string "bible_selector".
717-
// If this is left empty, then it selects notes that refer to Bibles in the vector above.
718-
// If this contains a Bible, then it selects notes that refer to this Bible.
719-
// In addition to the above two selectors, it always selects note that refer to any Bible.
720-
if (!bible_selector.empty()) {
721-
bibles.clear ();
722-
bibles.push_back (bible_selector);
723-
}
724-
if (!bibles.empty ()) {
725-
query.append (" AND (bible = '' ");
726-
for (auto bible : bibles) {
727-
bible = database::sqlite::no_sql_injection (bible);
728-
query.append (" OR bible = '");
729-
query.append (bible);
730-
query.append ("' ");
731-
}
732-
query.append (" ) ");
733-
}
734-
// Consider note assignment constraints.
735-
if (assignment_selector != "") {
736-
assignment_selector = database::sqlite::no_sql_injection (assignment_selector);
737-
query.append (" AND assigned LIKE '% ");
738-
query.append (assignment_selector);
739-
query.append (" %' ");
740-
}
741-
// Consider note subscription constraints.
742-
if (subscription_selector) {
743-
query.append (" AND subscriptions LIKE '% ");
744-
query.append (username);
745-
query.append (" %' ");
746-
}
747-
// Consider the note severity.
748-
if (severity_selector != -1) {
749-
query.append (" AND severity = ");
750-
query.append (std::to_string (severity_selector));
751-
query.append (" ");
752-
}
753-
// Consider text contained in notes.
754-
if (text_selector == 1) {
755-
query.append (notes_optional_fulltext_search_statement (search_text));
756-
}
757-
if (text_selector == 1) {
758-
// If searching in fulltext mode, notes get ordered on relevance of search hits.
759-
query.append (notes_order_by_relevance_statement ());
760-
} else {
761-
// Notes get ordered by the passage they refer to. It is a rough method and better ordering is needed.
762-
query.append (" ORDER BY ABS (passage) ");
763-
}
764-
// Limit the selection if a limit is given.
765-
if (limit >= 0) {
766-
query.append (" LIMIT ");
767-
query.append (std::to_string (limit));
768-
query.append (", 50 ");
769-
}
770-
query.append (";");
771-
772-
SqliteDatabase sql (database_notes);
773-
sql.set_sql (query);
774-
const std::vector <std::string> result = sql.query () ["identifier"];
775-
for (const auto& id : result) {
776-
identifiers.push_back (filter::strings::convert_to_int (id));
777-
}
778-
return identifiers;
779-
}
780-
781-
782-
std::vector <int> Database_Notes::select_notes (const selector& selector)
599+
std::vector<int> Database_Notes::select_notes(const selector& selector)
783600
{
784601
const std::string& username = m_webserver_request.session_logic ()->get_username ();
785602
std::vector <int> identifiers;
@@ -892,21 +709,15 @@ std::vector <int> Database_Notes::select_notes (const selector& selector)
892709
query.append (" ) ");
893710
}
894711

895-
// Consider two different Bible constraints:
712+
// Consider the Bible constraints:
896713
// 1. The vector of bibles: "bibles".
897-
// This contains all the Bibles a user has access to, so only notes that refer to any Bible in this lot are going to be selected.
898-
// 2. The string "bible_selector".
899-
// If this is left empty, then it selects notes that refer to Bibles in the vector above.
900-
// If this contains a Bible, then it selects notes that refer to this Bible.
901-
// In addition to the above two selectors, it always selects note that refer to any Bible.
902-
std::vector<std::string> bibles {selector.bibles};
903-
if (!selector.bible_selector.empty()) {
904-
bibles.clear ();
905-
bibles.push_back (selector.bible_selector);
906-
}
907-
if (!bibles.empty ()) {
714+
// This contains all the Bibles a user has access to,
715+
// so only notes that refer to any Bible in this lot are going to be selected.
716+
// Or it contains the Bible to be searched for notes.
717+
// In addition to the above s electors, it always selects notes that refer to any Bible.
718+
if (!selector.bibles.empty ()) {
908719
query.append (" AND (bible = '' ");
909-
for (auto bible : bibles) {
720+
for (auto bible : selector.bibles) {
910721
bible = database::sqlite::no_sql_injection (bible);
911722
query.append (" OR bible = '");
912723
query.append (bible);

database/notes.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,9 @@ class Database_Notes
7171

7272
public:
7373
struct selector {
74-
// Contaiiner of Bible names the user has read access to.
74+
// Container of Bible names that is going to be searched.
75+
// Can contains all Bibles the user has read access to.
76+
// Or can contain one Bible to be searched.
7577
std::vector<std::string> bibles{};
7678
// Four related selectors that can limit the selection.
7779
int book{};
@@ -81,10 +83,8 @@ class Database_Notes
8183
// Optionally constrains selection based on modification time.
8284
int edit_selector{}; // Todo default and enum?
8385
int non_edit_selector{}; // Todo default and enum?
84-
// Optionally constrains selection based on note status.
86+
// Optionally constrains selection based on list of note statuses.
8587
std::vector<std::string> status_selectors; // Todo enums?
86-
// Optionally constrains the selection, based on the note's Bible.
87-
std::string bible_selector{};
8888
// Optionally constrains the selection based on a note being assigned to somebody.
8989
std::string assignment_selector{};
9090
// Optionally limits the selection based on a note's subscription.
@@ -98,7 +98,6 @@ class Database_Notes
9898
// If >= 0, it indicates the starting limit for the selection.
9999
int limit{0};
100100
};
101-
std::vector <int> select_notes (std::vector <std::string> bibles, int book, int chapter, int verse, int passage_selector, int edit_selector, int non_edit_selector, const std::vector<std::string>& status_selectors, std::string bible_selector, std::string assignment_selector, bool subscription_selector, int severity_selector, int text_selector, const std::string& search_text, int limit);
102101
std::vector<int> select_notes (const selector& selector);
103102
private:
104103
std::string notes_select_identifier ();

notes/bulk.cpp

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -69,15 +69,15 @@ std::string notes_bulk (Webserver_Request& webserver_request)
6969
std::string success, error;
7070

7171

72-
std::vector <std::string> bibles = access_bible::bibles (webserver_request);
72+
std::vector <std::string> bibles = {webserver_request.database_config_user()->get_consultation_notes_bible_selector()};
73+
if (bibles.empty()) bibles = access_bible::bibles (webserver_request);
7374
int book = Ipc_Focus::getBook (webserver_request);
7475
int chapter = Ipc_Focus::getChapter (webserver_request);
7576
int verse = Ipc_Focus::getVerse (webserver_request);
7677
int passage_selector = webserver_request.database_config_user()->get_consultation_notes_passage_selector();
7778
int edit_selector = webserver_request.database_config_user()->get_consultation_notes_edit_selector();
7879
int non_edit_selector = webserver_request.database_config_user()->get_consultation_notes_non_edit_selector();
7980
const std::vector<std::string> status_selectors = webserver_request.database_config_user()->get_consultation_notes_status_selectors();
80-
std::string bible_selector = webserver_request.database_config_user()->get_consultation_notes_bible_selector();
8181
std::string assignment_selector = webserver_request.database_config_user()->get_consultation_notes_assignment_selector();
8282
bool subscription_selector = webserver_request.database_config_user()->get_consultation_notes_subscription_selector();
8383
int severity_selector = webserver_request.database_config_user()->get_consultation_notes_severity_selector();
@@ -111,21 +111,23 @@ std::string notes_bulk (Webserver_Request& webserver_request)
111111
// This is done to remember them as long as this page is active.
112112
// Thus erroneous bulk operations on notes can be rectified somewhat easier.
113113
if (!subscribe && !unsubscribe && !assign && !unassign && !status && !severity && !bible && !erase) {
114-
std::vector <int> identifiers = database_notes.select_notes (bibles,
115-
book,
116-
chapter,
117-
verse,
118-
passage_selector,
119-
edit_selector,
120-
non_edit_selector,
121-
status_selectors,
122-
bible_selector,
123-
assignment_selector,
124-
subscription_selector,
125-
severity_selector,
126-
text_selector,
127-
search_text,
128-
-1);
114+
Database_Notes::selector selector {
115+
.bibles = bibles,
116+
.book = book,
117+
.chapter = chapter,
118+
.verse = verse,
119+
.passage_selector = passage_selector,
120+
.edit_selector = edit_selector,
121+
.non_edit_selector = non_edit_selector,
122+
.status_selectors = status_selectors,
123+
.assignment_selector = assignment_selector,
124+
.subscription_selector = subscription_selector,
125+
.severity_selector = severity_selector,
126+
.text_selector = text_selector,
127+
.search_text = search_text,
128+
.limit = -1
129+
};
130+
std::vector <int> identifiers = database_notes.select_notes (selector);
129131
std::vector <std::string> sids;
130132
for (auto id : identifiers) sids.push_back (std::to_string (id));
131133
database::temporal::set_value (userid, "identifiers", filter::strings::implode (sids, " "));

0 commit comments

Comments
 (0)