/** * Executes a SQL statement * * @param mixed $po_caller object representation of the calling class, usually Db() * @param DbStatement $opo_statement * @param string $ps_sql SQL statement * @param array $pa_values array of placeholder replacements */ public function execute($po_caller, $opo_statement, $ps_sql, $pa_values) { if (!$ps_sql) { $opo_statement->postError(240, _t("Query is empty"), "Db->mysql->execute()"); return false; } $vs_sql = $ps_sql; $va_placeholder_map = $opo_statement->getOption('placeholder_map'); $vn_needed_values = sizeof($va_placeholder_map); if ($vn_needed_values != sizeof($pa_values)) { $opo_statement->postError(285, _t("Number of values passed (%1) does not equal number of values required (%2)", sizeof($pa_values), $vn_needed_values), "Db->mysql->execute()"); return false; } for ($vn_i = sizeof($pa_values) - 1; $vn_i >= 0; $vn_i--) { if (is_array($pa_values[$vn_i])) { foreach ($pa_values[$vn_i] as $vn_x => $vs_vx) { $pa_values[$vn_i][$vn_x] = $this->autoQuote($vs_vx); } $vs_sql = substr_replace($vs_sql, join(',', $pa_values[$vn_i]), $va_placeholder_map[$vn_i], 1); } else { $vs_sql = substr_replace($vs_sql, $this->autoQuote($pa_values[$vn_i]), $va_placeholder_map[$vn_i], 1); } } $va_limit_info = $opo_statement->getLimit(); if ($va_limit_info["limit"] > 0 || $va_limit_info["offset"] > 0) { if (!preg_match("/LIMIT[ ]+[\\d]+[,]{0,1}[\\d]*\$/i", $vs_sql)) { // check for LIMIT clause is raw SQL $vn_limit = $va_limit_info["limit"]; if ($vn_limit == 0) { $vn_limit = 4000000000.0; } $vs_sql .= " LIMIT " . intval($va_limit_info["offset"]) . "," . intval($vn_limit); } } if (Db::$monitor) { $t = new Timer(); } if (!($r_res = mysql_query($vs_sql, $this->opr_db))) { $vn_mysql_err = (int) mysql_errno($this->opr_db); switch ($vn_mysql_err) { case 1205: // deadlock // deadlock case 1216: // deadlock $vn_tries = 0; // wait a bit and try the query again (up to 10 times) while ($vn_tries < 10) { usleep(500); if ($r_res = mysql_query($vs_sql, $this->opr_db)) { break; } $vn_tries++; } if (!$r_res) { $opo_statement->postError($this->nativeToDbError($vn_mysql_err), mysql_error($this->opr_db) . (__CA_ENABLE_DEBUG_OUTPUT__ ? "\n<pre>" . caPrintStacktrace() . "</pre>" : ""), "Db->mysql->execute()"); return false; } return new DbResult($this, $r_res); break; case 2006: // gone away // reconnect if ($this->connect()) { if ($r_res = mysql_query($vs_sql, $this->opr_db)) { return new DbResult($this, $r_res); } } $opo_statement->postError($this->nativeToDbError($vn_mysql_err), mysql_error($this->opr_db) . (__CA_ENABLE_DEBUG_OUTPUT__ ? "\n<pre>" . caPrintStacktrace() . "</pre>" : ""), "Db->mysql->execute()"); break; default: $opo_statement->postError($this->nativeToDbError($vn_mysql_err), mysql_error($this->opr_db) . (__CA_ENABLE_DEBUG_OUTPUT__ ? "\n<pre>" . caPrintStacktrace() . "</pre>" : ""), "Db->mysql->execute()"); break; } return false; } if (Db::$monitor) { Db::$monitor->logQuery($ps_sql, $pa_values, $t->getTime(4), is_bool($r_res) ? null : mysql_num_rows($r_res)); } return new DbResult($this, $r_res); }
/** * Executes a SQL statement * * @param mixed $po_caller object representation of the calling class, usually Db() * @param DbStatement $opo_statement * @param string $ps_sql SQL statement * @param array $pa_values array of placeholder replacements */ public function execute($po_caller, $opo_statement, $ps_sql, $pa_values) { if (!$ps_sql) { $opo_statement->postError(240, _t("Query is empty"), "Db->mysqli->execute()"); return false; } $vs_sql = $ps_sql; $va_placeholder_map = $opo_statement->getOption('placeholder_map'); $vn_needed_values = sizeof($va_placeholder_map); if ($vn_needed_values != sizeof($pa_values)) { $opo_statement->postError(285, _t("Number of values passed (%1) does not equal number of values required (%2)", sizeof($pa_values), $vn_needed_values), "Db->mysqli->execute()"); return false; } for ($vn_i = sizeof($pa_values) - 1; $vn_i >= 0; $vn_i--) { if (is_array($pa_values[$vn_i])) { foreach ($pa_values[$vn_i] as $vn_x => $vs_vx) { $pa_values[$vn_i][$vn_x] = $this->autoQuote($vs_vx); } $vs_sql = substr_replace($vs_sql, join(',', $pa_values[$vn_i]), $va_placeholder_map[$vn_i], 1); } else { $vs_sql = substr_replace($vs_sql, $this->autoQuote($pa_values[$vn_i]), $va_placeholder_map[$vn_i], 1); } } $va_limit_info = $opo_statement->getLimit(); if ($va_limit_info["limit"] > 0 || $va_limit_info["offset"] > 0) { if (!preg_match("/LIMIT[ ]+[\\d]+[,]{0,1}[\\d]*\$/i", $vs_sql)) { // check for LIMIT clause is raw SQL $vn_limit = $va_limit_info["limit"]; if ($vn_limit == 0) { $vn_limit = 4000000000; } $vs_sql .= " LIMIT " . intval($va_limit_info["offset"]) . "," . intval($vn_limit); } } if (Db::$monitor) { $t = new Timer(); } if (!($r_res = mysqli_query($this->opr_db, $vs_sql))) { //print "<pre>".caPrintStacktrace()."</pre>\n"; $opo_statement->postError($this->nativeToDbError(mysqli_errno($this->opr_db)), mysqli_error($this->opr_db), "Db->mysqli->execute()"); return false; } if (Db::$monitor) { Db::$monitor->logQuery($ps_sql, $pa_values, $t->getTime(4), is_bool($r_res) ? null : mysqli_num_rows($r_res)); } return new DbResult($this, $r_res); }