[0-9]+)`, "m");
}
auto rgx = Rgx();
string _previous_next = "";
int _current_offset_value = 0;
string _set_offset_next = "";
string _set_offset_previous = "";
string _url = "";
string _url_previous = "";
string _url_next = "";
string arrow_previous = "";
string arrow_next = "";
if (environment.get("REQUEST_METHOD", "POST") == "POST") {
_url = conf.http_request_type ~ "://" ~ conf.http_host ~ conf.cgi_script ~ "?" ~ tf.canned_query;
} else if (environment.get("REQUEST_METHOD", "POST") == "GET") {
_url = conf.http_request_type ~ "://" ~ conf.http_host ~ conf.cgi_script ~ "?" ~ environment.get("QUERY_STRING", "");
}
if (auto m = _url.matchFirst(rgx.track_offset)) {
_current_offset_value = m.captures["offset_val"].to!int;
_set_offset_next = m.captures["offset_key"] ~ ((m.captures["offset_val"]).to!int + cv.sql_match_limit.to!int).to!string;
_url_next = _url.replace(rgx.track_offset, _set_offset_next);
if (_current_offset_value < cv.sql_match_limit.to!int) {
_url_previous = "";
} else {
_url_previous = "";
_set_offset_previous = m.captures["offset_key"] ~ ((m.captures["offset_val"]).to!int - cv.sql_match_limit.to!int).to!string;
_url_previous = _url.replace(rgx.track_offset, _set_offset_previous);
}
} else {// _current_offset_value = 0;
_url_next = _url ~= "&smo=" ~ cv.sql_match_limit.to!string;
}
if (_url_previous.empty) {
arrow_previous = "";
} else {
arrow_previous =
""
~ ""
~ "<< prev"
~ " || ";
}
arrow_next =
""
~ ""
~ "next >>"
~ "";
_previous_next = "
" ~ arrow_previous ~ arrow_next;
return _previous_next;
}
{
header = format(q"┃
≅ SiSU spine search form
┃",
conf.http_host,
);
}
{
table = format(q"┃
|
|
┃");
}
{
string post_value(string field_name, string type="box", string set="on") {
string val = "";
switch (type) {
case "field":
val = ((field_name in cgi.post && !(cgi.post[field_name]).empty)
? cgi.post[field_name]
: (field_name in cgi.get)
? cgi.get[field_name]
: "");
val = tf.search_text_area;
break;
case "box": // generic for checkbox or radio; checkbox set == "on" radio set == "name set"
val = ((field_name in cgi.post && !(cgi.post[field_name]).empty)
? (cgi.post[field_name] == set ? "checked" : "off")
: (field_name in cgi.get)
? (cgi.get[field_name] == set ? "checked" : "off")
: "off");
break;
case "radio": // used generic bo
val = ((field_name in cgi.post && !(cgi.post[field_name]).empty)
? (cgi.post[field_name] == set ? "checked" : "off")
: (field_name in cgi.get)
? (cgi.get[field_name] == set ? "checked" : "off")
: "checked");
break;
case "checkbox": // used generic bo
val = ((field_name in cgi.post && !(cgi.post[field_name]).empty)
? (cgi.post[field_name] == set ? "checked" : "off")
: (field_name in cgi.get)
? (cgi.get[field_name] == set ? "checked" : "off")
: "checked");
break;
default:
}
return val;
}
string the_can(string fv) {
string show_the_can = post_value("url");
string _the_can = "";
if (show_the_can == "checked") {
tf = text_fields;
string method_get_url = conf.http_request_type ~ "://" ~ conf.http_host ~ conf.cgi_script ~ "?" ~ environment.get("QUERY_STRING", "");
string method_post_url_construct = conf.http_request_type ~ "://" ~ conf.http_host ~ conf.cgi_script ~ "?" ~ tf.canned_query;
// assert(method_get_url == environment.get("HTTP_REFERER", conf.http_request_type ~ "://" ~ conf.http_host ~ conf.cgi_script ~ "?" ~ conf.query_string));
if (conf.request_method == "POST") {
_the_can =
""
~ "POST: "
~ ""
~ method_post_url_construct
~ ""
~ "
";
} else if (conf.request_method == "GET") {
_the_can =
""
~ "GET: "
~ ""
~ method_get_url
~ "";
}
conf.http_url = conf.http_request_type ~ "://" ~ conf.http_host ~ conf.cgi_script ~ tf.canned_query;
}
return _the_can;
}
string provide_tip() {
string searched_tip = post_value("se");
string tip = "";
if (searched_tip == "checked") {
string search_field = post_value("sf", "field");
tf = text_fields;
tip = format(q"┃
database: %%s; selected view: index
search string: %%s %%s %%s %%s %%s %%s
%%s %%s %%s %%s %%s %%s
┃",
cv.db_selected,
(tf.text.empty ? "" : "\"text: " ~ tf.text ~ "; "),
(tf.title.empty ? "" : "\"title: " ~ tf.title ~ "; "),
(tf.author.empty ? "" : "\"author: " ~ tf.author ~ "; "),
(tf.date.empty ? "" : "\"date " ~ tf.date ~ "; "),
(tf.uid.empty ? "" : "\"uid: " ~ tf.uid ~ "; "),
(tf.fn.empty ? "" : "\"fn: " ~ tf.fn ~ "; "),
(tf.text.empty ? "" : "text: " ~ tf.text ~ "
"),
(tf.title.empty ? "" : "title: " ~ tf.title ~ "
"),
(tf.author.empty ? "" : "author: " ~ tf.author ~ "
"),
(tf.date.empty ? "" : "date: " ~ tf.date ~ "
"),
(tf.uid.empty ? "" : "\"uid: " ~ tf.uid ~ "; "),
(tf.fn.empty ? "" : "\"fn: " ~ tf.fn ~ "; "),
);
}
return tip;
}
form = format(q"┃
┃",
"%s",
(post_value("ec") == "checked") ? post_value("sf", "field") : "",
provide_tip,
search_note,
the_can(post_value("sf", "field")),
cv.db_selected,
cv.db_selected,
post_value("rt", "box", "idx"),
post_value("rt", "box", "txt"),
post_value("sml", "box", "1000"),
post_value("sml", "box", "2500"),
post_value("ec"),
post_value("sts"),
post_value("url"),
post_value("se"),
post_value("tip"),
post_value("sql"),
);
{
string set_value(string field_name, string default_val) {
string val;
if (field_name in cgi.post) {
val = cgi.post[field_name];
} else if (field_name in cgi.get) {
val = cgi.get[field_name];
} else { val = default_val; }
return val;
}
bool set_bool(string field_name) {
bool val;
if (field_name in cgi.post
&& cgi.post[field_name] == "on") {
val = true;
} else if (field_name in cgi.get
&& cgi.get[field_name] == "on") {
val = true;
} else { val = false; }
return val;
}
cv.db_selected = set_value("selected_db", "spine.search.db"); // selected_db == db
cv.sql_match_limit = set_value("sml", "1000");
cv.sql_match_offset = set_value("smo", "0");
cv.search_text = set_value("sf", "");
cv.results_type = set_value("rt", "idx");
cv.checked_echo = set_bool("ec");
cv.checked_stats = set_bool("sts");
cv.checked_url = set_bool("url");
cv.checked_searched = set_bool("se");
cv.checked_tip = set_bool("tip");
cv.checked_sql = set_bool("sql");
tf = text_fields;
}
}
{
cgi.write(header);
cgi.write(table);
cgi.write(form);
// cgi.write(previous_next);
{ // debug environment
// foreach (k, d; environment.toAA) {
// cgi.write(k ~ ": " ~ d ~ "
");
// }
}
{ // debug cgi info
// cgi.write("db_selected: " ~ cv.db_selected ~ "
\n");
// cgi.write("search_text: " ~ cv.search_text ~ "
\n");
// cgi.write("sql_match_limit: " ~ cv.sql_match_limit ~ ";\n");
// cgi.write("sql_match_offset: " ~ cv.sql_match_offset ~ ";\n");
// cgi.write("results_type: " ~ cv.results_type ~ "
\n");
// cgi.write("cv.checked_echo: " ~ (cv.checked_echo ? "checked" : "off") ~ "; \n");
// cgi.write("cv.checked_stats: " ~ (cv.checked_stats ? "checked" : "off") ~ "; \n");
// cgi.write("cv.checked_url: " ~ (cv.checked_url ? "checked" : "off") ~ "; \n");
// cgi.write("cv.checked_searched: " ~ (cv.checked_searched ? "checked" : "off") ~ ";
\n");
// cgi.write("cv.checked_tip: " ~ (cv.checked_tip ? "checked" : "off") ~ "; \n");
// cgi.write("cv.checked_sql: " ~ (cv.checked_sql ? "checked" : "off") ~ "
\n");
}
}
auto db = Database(conf.db_path ~ cv.db_selected);
{
uint sql_match_offset_counter(T)(T cv) {
sql_match_offset_count += cv.sql_match_limit.to!uint;
return sql_match_offset_count;
}
void sql_search_query() {
string select_field_like(string db_field, string search_field) {
string where_ = "";
if (!(search_field.empty)) {
string _sf = search_field.strip.split("%%20").join(" ");
if (_sf.match(r" OR ")) {
_sf = _sf.split(" OR ").join("%%' OR " ~ db_field ~ " LIKE '%%");
}
if (_sf.match(r" AND ")) {
_sf = _sf.split(" AND ").join("%%' AND " ~ db_field ~ " LIKE '%%");
}
_sf = "( " ~ db_field ~ " LIKE\n '%%" ~ _sf ~ "%%' )";
where_ ~= format(q"┃
%%s
┃",
_sf
);
}
return where_;
}
string[] _fields;
_fields ~= select_field_like("doc_objects.clean", tf.text);
_fields ~= select_field_like("metadata_and_text.title", tf.title);
_fields ~= select_field_like("metadata_and_text.creator_author", tf.author);
_fields ~= select_field_like("metadata_and_text.uid", tf.uid);
_fields ~= select_field_like("metadata_and_text.src_filename_base", tf.fn);
_fields ~= select_field_like("metadata_and_text.src_filename_base", tf.src_filename_base);
_fields ~= select_field_like("metadata_and_text.language_document_char", tf.language);
_fields ~= select_field_like("metadata_and_text.date_published", tf.date);
_fields ~= select_field_like("metadata_and_text.classify_keywords", tf.keywords);
_fields ~= select_field_like("metadata_and_text.classify_topic_register", tf.topic_register);
string[] fields;
foreach (f; _fields) {
if (!(f.empty)) { fields ~= f; }
}
string fields_str = "";
fields_str ~= fields.join(" AND ");
sql_select.the_body ~= format(q"┃
SELECT
metadata_and_text.uid,
metadata_and_text.title,
metadata_and_text.creator_author_last_first,
metadata_and_text.creator_author,
metadata_and_text.src_filename_base,
metadata_and_text.language_document_char,
metadata_and_text.date_published,
metadata_and_text.classify_keywords,
metadata_and_text.classify_topic_register,
doc_objects.body,
doc_objects.seg_name,
doc_objects.ocn,
metadata_and_text.uid
FROM
doc_objects,
metadata_and_text
WHERE (
%%s
)
AND
doc_objects.uid_metadata_and_text = metadata_and_text.uid
ORDER BY
metadata_and_text.creator_author_last_first,
metadata_and_text.date_published DESC,
metadata_and_text.title,
metadata_and_text.language_document_char,
metadata_and_text.src_filename_base,
doc_objects.ocn
LIMIT %%s OFFSET %%s
;┃",
fields_str,
cv.sql_match_limit,
cv.sql_match_offset,
);
(cv.checked_sql)
? cgi.write(previous_next ~ "
" ~ sql_select.the_body.split("\n ").join(" ").split("\n").join("
") ~ "\n")
: "";
cgi.write(previous_next);
auto select_query_results = db.execute(sql_select.the_body).cached;
string _old_uid = "";
if (!select_query_results.empty) {
foreach (row; select_query_results) {
if (row["uid"].as!string != _old_uid) {
_old_uid = row["uid"].as!string;
auto m = (row["date_published"].as!string).match(regex(r"^([0-9]{4})")); // breaks if row missing or no match?
cgi.write(
"
\""
~ row["title"].as!string ~ "\""
~ " ("
~ m.hit
~ ") "
~ "["
~ row["language_document_char"].as!string
~ "] "
~ row["creator_author_last_first"].as!string
~ ":
\n"
);
}
if (cv.results_type == "txt") {
cgi.write(
"
"
~ row["ocn"].as!string
~ ""
~ "
"
~ row["body"].as!string
);
} else {
cgi.write(
""
~ row["ocn"].as!string
~ ", "
);
}
}
cgi.write( previous_next);
} else { // offset_not_beyond_limit = false;
cgi.write("select_query_results empty\n");
}
}
sql_search_query;
}
{
db.close;
}
{
string tail = format(q"┃
┃");
cgi.write(tail);
}
}
mixin GenericMain!cgi_function_intro;
≓",
_sqlite_db_fn,
_cgi_search_script,
).strip;
auto pth_sqlite_cgi = spinePathsSQLiteCGI!()(_cgi_search_script_raw_fn_d, _cgi_search_script, opt_action.output_dir_set); // TODO
{ // cgi-bin search form src d
try {
if (!exists(pth_sqlite_cgi.src)) {
pth_sqlite_cgi.src.mkdirRecurse;
}
if (!exists(pth_sqlite_cgi.cgi_bin)) {
pth_sqlite_cgi.cgi_bin.mkdirRecurse;
}
auto f = File(pth_sqlite_cgi.search_form_path_out, "w");
f.write(the_cgi_search_form);
// foreach (o; metadata_) {
// f.writeln(o);
// }
} catch (ErrnoException ex) {
// Handle error
}
// if (!(opt_action.quiet)) {
// writeln(" ", pth_sqlite_cgi.search_form);
// }
}
string the_dub_sdl = format(q"≓
name "spine_cgi_sqlite_search"
description "spine cgi sqlite search"
authors "Ralph Amissah"
copyright "Copyright © 2020, Ralph Amissah"
license "GPL-3.0+"
dependency "d2sqlite3" version="%s"
targetType "executable"
targetPath "./cgi-bin"
mainSourceFile "%s"
configuration "default" {
targetType "executable"
targetName "%s"
postGenerateCommands "/usr/bin/notify-send -t 0 'D executable ready' 'spine cgi sqlite search d'"
}
≓",
"~>0.18.3", // d2sqlite3 dependency version
"src/" ~ _cgi_search_script_raw_fn_d,
_cgi_search_script
).strip;
{ // dub.sdl
try {
auto f = File(pth_sqlite_cgi.dub_sdl_path_out, "w");
f.write(the_dub_sdl);
// foreach (o; metadata_) {
// f.writeln(o);
// }
} catch (ErrnoException ex) {
// Handle error
}
}
{ // cgi.d
import std.net.curl, std.stdio;
try {
auto cgi_d = get("https://raw.githubusercontent.com/adamdruppe/arsd/master/cgi.d");
try {
auto f = File(pth_sqlite_cgi.cgi_d_path_out, "w");
f.write(cgi_d);
} catch (ErrnoException ex) {
// Handle error
}
} catch (ErrnoException ex) {
// Handle error
}
}
}
}