Skip to content

Commit

Permalink
Add Dbl syntax for values() generalization.
Browse files Browse the repository at this point in the history
  • Loading branch information
kohler committed Dec 10, 2021
1 parent 01a100b commit 418ace0
Show file tree
Hide file tree
Showing 9 changed files with 69 additions and 19 deletions.
4 changes: 2 additions & 2 deletions batch/updatecontactdb.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@

// perform role updates
if (!empty($qv)) {
Dbl::ql($cdb, "insert into Roles (contactDbId,confid,roles,activity_at) values ?v on duplicate key update roles=values(roles), activity_at=values(activity_at)", $qv);
Dbl::ql($cdb, "insert into Roles (contactDbId,confid,roles,activity_at) values ?v ?U on duplicate key update roles=?U(roles), activity_at=?U(activity_at)", $qv);
}

// remove old roles
Expand All @@ -105,7 +105,7 @@
Dbl::free($result);

if (!empty($qv)) {
Dbl::ql($cdb, "insert into ConferencePapers (confid,paperId,title) values ?v on duplicate key update title=values(title)", $qv);
Dbl::ql($cdb, "insert into ConferencePapers (confid,paperId,title) values ?v ?U on duplicate key update title=?U(title)", $qv);
}
Dbl::ql($cdb, "delete from ConferencePapers where confid=? and paperId?A", $confid, $pids);
if ($confrow->last_submission_at != $max_submitted) {
Expand Down
42 changes: 36 additions & 6 deletions lib/dbl.php
Original file line number Diff line number Diff line change
Expand Up @@ -268,16 +268,45 @@ static private function format_query_args($dblink, $qstr, $argv) {
$strpos = $argpos = 0;
$usedargs = [];
$simpleargs = true;
$U_mysql8 = null;
while (($strpos = strpos($qstr, "?", $strpos)) !== false) {
// argument name
$prefix = substr($qstr, 0, $strpos);
$nextpos = $strpos + 1;
$nextch = substr($qstr, $nextpos, 1);

// non-argument expansions
if ($nextch === "?") {
$qstr = substr($qstr, 0, $strpos + 1) . substr($qstr, $strpos + 2);
$strpos = $strpos + 1;
$qstr = $prefix . substr($qstr, $nextpos);
$strpos = $nextpos;
continue;
} else if ($nextch === "{"
&& ($rbracepos = strpos($qstr, "}", $nextpos + 1)) !== false) {
} else if ($nextch === "U") {
$U_mysql8 = $U_mysql8 ?? (strpos($dblink->server_info, "Maria") === false
&& $dblink->server_version >= 80020);
$ql = substr($qstr, 0, $strpos);
if (substr($qstr, $nextpos + 1, 1) === "(") {
$rparen = strpos($qstr, ")", $nextpos + 2);
$name = substr($qstr, $nextpos + 2, $rparen - $nextpos - 2);
$suffix = substr($qstr, $rparen + 1);
if ($U_mysql8) {
$qstr = "{$prefix}__values.{$name}{$suffix}";
} else {
$qstr = "{$prefix}values({$name}){$suffix}";
}
} else {
$suffix = substr($qstr, $nextpos + 1);
if ($U_mysql8) {
$qstr = "{$prefix} as __values {$suffix}";
} else {
$qstr = "{$prefix}{$suffix}";
}
}
$nextpos = strlen($qstr) - strlen($suffix);
continue;
}

// find argument
if ($nextch === "{"
&& ($rbracepos = strpos($qstr, "}", $nextpos + 1)) !== false) {
$thisarg = substr($qstr, $nextpos + 1, $rbracepos - $nextpos - 1);
if ($thisarg === (string) (int) $thisarg)
--$thisarg;
Expand All @@ -294,6 +323,7 @@ static private function format_query_args($dblink, $qstr, $argv) {
trigger_error(self::landmark() . ": query '$original_qstr' argument " . (is_int($thisarg) ? $thisarg + 1 : $thisarg) . " not set");
}
$usedargs[$thisarg] = true;

// argument format
$arg = $argv[$thisarg] ?? null;
if ($nextch === "e" || $nextch === "E") {
Expand Down Expand Up @@ -387,7 +417,7 @@ static private function format_query_args($dblink, $qstr, $argv) {
}
// combine
$suffix = substr($qstr, $nextpos);
$qstr = substr($qstr, 0, $strpos) . $arg . $suffix;
$qstr = "$prefix$arg$suffix";
$strpos = strlen($qstr) - strlen($suffix);
}
if ($simpleargs && $argpos !== count($argv)) {
Expand Down
2 changes: 1 addition & 1 deletion src/api/api_searchconfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ static function save_namedsearch(Contact $user, Qrequest $qreq) {
$qv[] = ["ss:" . $search_names[$lname], Conf::$now, json_encode_db($q)];
}
if (!empty($qv)) {
$user->conf->qe("insert into Settings (name, value, data) values ?v on duplicate key update value=values(value), data=values(data)", $qv);
$user->conf->qe("insert into Settings (name, value, data) values ?v ?U on duplicate key update value=?U(value), data=?U(data)", $qv);
}
$user->conf->replace_named_searches();
return self::namedsearch($user, $qreq);
Expand Down
2 changes: 1 addition & 1 deletion src/conference.php
Original file line number Diff line number Diff line change
Expand Up @@ -804,7 +804,7 @@ function save_setting($name, $value, $data = null) {
if (is_array($dval) || is_object($dval)) {
$dval = json_encode_db($dval);
}
$result = $this->qe("insert into Settings (name, value, data) values (?, ?, ?) on duplicate key update value=values(value), data=values(data)", $name, $value, $dval);
$result = $this->qe("insert into Settings (name, value, data) values (?, ?, ?) ?U on duplicate key update value=?U(value), data=?U(data)", $name, $value, $dval);
if (!Dbl::is_error($result)) {
$this->settings[$name] = $value;
$this->settingTexts[$name] = $dval;
Expand Down
2 changes: 1 addition & 1 deletion src/mergecontacts.php
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ private function merge() {
}
}
if (!empty($qv)) {
$this->q("insert into PaperConflict (paperId,contactId,conflictType) values ?v on duplicate key update conflictType=values(conflictType)", $qv);
$this->q("insert into PaperConflict (paperId,contactId,conflictType) values ?v ?U on duplicate key update conflictType=?U(conflictType)", $qv);
}
$this->q("delete from PaperConflict where contactId=?", $this->oldu->contactId);
$this->conf->q_raw("unlock tables");
Expand Down
4 changes: 2 additions & 2 deletions src/settingvalues.php
Original file line number Diff line number Diff line change
Expand Up @@ -1749,8 +1749,8 @@ function execute() {
//Conf::msg_info(Ht::pre_text_wrap(Dbl::format_query("delete from Settings where name?a", $dv)));
}
if (!empty($av)) {
$this->conf->qe("insert into Settings (name, value, data) values ?v on duplicate key update value=values(value), data=values(data)", $av);
//Conf::msg_info(Ht::pre_text_wrap(Dbl::format_query("insert into Settings (name, value, data) values ?v on duplicate key update value=values(value), data=values(data)", $av)));
$this->conf->qe("insert into Settings (name, value, data) values ?v ?U on duplicate key update value=?U(value), data=?U(data)", $av);
//Conf::msg_info(Ht::pre_text_wrap(Dbl::format_query("insert into Settings (name, value, data) values ?v ?U on duplicate key update value=?U(value), data=?U(data)", $av)));
}

$this->conf->qe_raw("unlock tables");
Expand Down
13 changes: 7 additions & 6 deletions src/updateschema.php
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ private function v154_mimetype_extensions() {
$qv[] = [$row->mimetypeid, $row->mimetype, $extension];
}
Dbl::free($result);
return empty($qv) || $this->conf->ql_ok("insert into Mimetype (mimetypeid, mimetype, extension) values ?v on duplicate key update extension=values(extension)", $qv);
return empty($qv) || $this->conf->ql_ok("insert into Mimetype (mimetypeid, mimetype, extension) values ?v ?U on duplicate key update extension=?U(extension)", $qv);
}

private function v174_paper_review_tfields() {
Expand Down Expand Up @@ -630,8 +630,8 @@ function run() {
&& $conf->ql_ok("alter table OptionType add `optionValues` text NOT NULL default ''")) {
$conf->update_schema_version(14);
}
if ($conf->sversion === 14
&& $conf->ql_ok("insert into Settings (name, value) select 'rev_tokens', count(reviewId) from PaperReview where reviewToken!=0 on duplicate key update value=values(value)")) {
if ($conf->sversion === 14) {
$conf->update_rev_tokens_setting(0);
$conf->update_schema_version(15);
}
if ($conf->sversion === 15) {
Expand Down Expand Up @@ -688,10 +688,11 @@ function run() {
$conf->update_schema_version(25);
}
if ($conf->sversion === 25) {
if ($conf->settings["final_done"] > 0
if (($fd = $conf->settings["final_done"]) > 0
&& !isset($conf->settings["final_soft"])
&& $conf->ql_ok("insert into Settings (name, value) values ('final_soft', " . $conf->settings["final_done"] . ") on duplicate key update value=values(value)"))
$conf->settings["final_soft"] = $conf->settings["final_done"];
&& $conf->ql_ok("insert into Settings (name, value) values ('final_soft', ?) on duplicate key update value=?", $fd, $fd)) {
$conf->settings["final_soft"] = $fd;
}
$conf->update_schema_version(26);
}
if ($conf->sversion === 26
Expand Down
17 changes: 17 additions & 0 deletions test/setup.php
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,23 @@ function xassert_neqq($a, $b) {
return $ok;
}

/** @param list $b
* @return bool */
function xassert_in_eqq($a, $b) {
++Xassert::$n;
$ok = false;
foreach ($b as $bx) {
$ok = $ok || $a === $bx;
}
if ($ok) {
++Xassert::$nsuccess;
} else {
trigger_error("Assertion " . var_export($a, true) . " \in " . var_export($b, true)
. " failed at " . assert_location() . "\n", E_USER_WARNING);
}
return $ok;
}

/** @return bool */
function xassert_eq($a, $b) {
++Xassert::$n;
Expand Down
2 changes: 2 additions & 0 deletions test/test02.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
xassert_eqq(Dbl::format_query("Hello"), "Hello");
xassert_eqq(Dbl::format_query("Hello??"), "Hello?");
xassert_eqq(Dbl::format_query("Hello????"), "Hello??");
xassert_eqq(Dbl::format_query("Hello????? What the heck", 1), "Hello??1 What the heck");
xassert_in_eqq(Dbl::format_query("Hello ?U? ?U(a)?", 1, 2), ["Hello 1 values(a)2", "Hello as __values 1 __values.a2"]);
xassert_eqq(Dbl::format_query("select ?, ?, ?, ?s, ?s, ?s, ?",
1, "a", null, 2, "b", null, 3),
"select 1, 'a', NULL, 2, b, , 3");
Expand Down

0 comments on commit 418ace0

Please sign in to comment.