clean up query parsing code -- will be necessary for transition to prepared statement approach
This commit is contained in:
96
db.class.php
96
db.class.php
@@ -439,14 +439,13 @@ class MeekroDB {
|
|||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function parseQueryParams() {
|
public function preparseQueryParams() {
|
||||||
$args = func_get_args();
|
$args = func_get_args();
|
||||||
if (count($args) < 2) return $args[0];
|
$sql = trim(strval(array_shift($args)));
|
||||||
|
|
||||||
$sql = array_shift($args);
|
|
||||||
$args_all = $args;
|
$args_all = $args;
|
||||||
$posList = array();
|
|
||||||
$pos_adj = 0;
|
if (count($args_all) == 0) return array($sql);
|
||||||
|
|
||||||
$param_char_length = strlen($this->param_char);
|
$param_char_length = strlen($this->param_char);
|
||||||
$named_seperator_length = strlen($this->named_param_seperator);
|
$named_seperator_length = strlen($this->named_param_seperator);
|
||||||
|
|
||||||
@@ -464,6 +463,9 @@ class MeekroDB {
|
|||||||
$this->param_char . 'ss' // search string (like string, surrounded with %'s)
|
$this->param_char . 'ss' // search string (like string, surrounded with %'s)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// generate list of all MeekroDB variables in our query, and their position
|
||||||
|
// in the form "offset => variable", sorted by offsets
|
||||||
|
$posList = array();
|
||||||
foreach ($types as $type) {
|
foreach ($types as $type) {
|
||||||
$lastPos = 0;
|
$lastPos = 0;
|
||||||
while (($pos = strpos($sql, $type, $lastPos)) !== false) {
|
while (($pos = strpos($sql, $type, $lastPos)) !== false) {
|
||||||
@@ -475,19 +477,25 @@ class MeekroDB {
|
|||||||
|
|
||||||
ksort($posList);
|
ksort($posList);
|
||||||
|
|
||||||
|
// for each MeekroDB variable, substitute it with array(type: i, value: 53) or whatever
|
||||||
|
$chunkyQuery = array(); // preparsed query
|
||||||
|
$pos_adj = 0; // how much we've added or removed from the original sql string
|
||||||
foreach ($posList as $pos => $type) {
|
foreach ($posList as $pos => $type) {
|
||||||
$type = substr($type, $param_char_length);
|
$type = substr($type, $param_char_length); // variable, without % in front of it
|
||||||
$length_type = strlen($type) + $param_char_length;
|
$length_type = strlen($type) + $param_char_length; // length of variable w/o %
|
||||||
|
|
||||||
$new_pos = $pos + $pos_adj;
|
$new_pos = $pos + $pos_adj; // position of start of variable
|
||||||
$new_pos_back = $new_pos + $length_type;
|
$new_pos_back = $new_pos + $length_type; // position of end of variable
|
||||||
|
$arg_number_length = 0; // length of any named or numbered parameter addition
|
||||||
|
|
||||||
|
// handle numbered parameters
|
||||||
if ($arg_number_length = strspn($sql, '0123456789', $new_pos_back)) {
|
if ($arg_number_length = strspn($sql, '0123456789', $new_pos_back)) {
|
||||||
$arg_number = substr($sql, $new_pos_back, $arg_number_length);
|
$arg_number = substr($sql, $new_pos_back, $arg_number_length);
|
||||||
if (! array_key_exists($arg_number, $args_all)) $this->nonSQLError("Non existent argument reference (arg $arg_number): $sql");
|
if (! array_key_exists($arg_number, $args_all)) $this->nonSQLError("Non existent argument reference (arg $arg_number): $sql");
|
||||||
|
|
||||||
$arg = $args_all[$arg_number];
|
$arg = $args_all[$arg_number];
|
||||||
|
|
||||||
|
// handle named parameters
|
||||||
} else if (substr($sql, $new_pos_back, $named_seperator_length) == $this->named_param_seperator) {
|
} else if (substr($sql, $new_pos_back, $named_seperator_length) == $this->named_param_seperator) {
|
||||||
$arg_number_length = strspn($sql, 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_',
|
$arg_number_length = strspn($sql, 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_',
|
||||||
$new_pos_back + $named_seperator_length) + $named_seperator_length;
|
$new_pos_back + $named_seperator_length) + $named_seperator_length;
|
||||||
@@ -503,35 +511,59 @@ class MeekroDB {
|
|||||||
$arg = array_shift($args);
|
$arg = array_shift($args);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (in_array($type, array('s', 'i', 'd', 'b', 'l'))) {
|
if ($new_pos > 0) $chunkyQuery[] = substr($sql, 0, $new_pos);
|
||||||
$array_type = false;
|
$chunkyQuery[] = array('type' => $type, 'value' => $arg);
|
||||||
$arg = array($arg);
|
$sql = substr($sql, $new_pos_back + $arg_number_length);
|
||||||
$type = 'l' . $type;
|
$pos_adj -= $new_pos_back + $arg_number_length;
|
||||||
} else if ($type == 'ss') {
|
}
|
||||||
$result = "'%" . $this->escape(str_replace(array('%', '_'), array('\%', '\_'), $arg)) . "%'";
|
|
||||||
} else {
|
if (strlen($sql) > 0) $chunkyQuery[] = $sql;
|
||||||
$array_type = true;
|
|
||||||
if (! is_array($arg)) $this->nonSQLError("Badly formatted SQL query: $sql -- expecting array, but didn't get one!");
|
return $chunkyQuery;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function parseQueryParams() {
|
||||||
|
$args = func_get_args();
|
||||||
|
$chunkyQuery = call_user_func_array(array($this, 'preparseQueryParams'), $args);
|
||||||
|
|
||||||
|
$query = '';
|
||||||
|
$array_types = array('ls', 'li', 'ld', 'lb', 'll');
|
||||||
|
|
||||||
|
foreach ($chunkyQuery as $chunk) {
|
||||||
|
if (is_string($chunk)) {
|
||||||
|
$query .= $chunk;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($type == 'ls') $result = $this->wrapStr($arg, "'", true);
|
$type = $chunk['type'];
|
||||||
|
$arg = $chunk['value'];
|
||||||
|
$result = '';
|
||||||
|
$is_array_type = in_array($type, $array_types, true);
|
||||||
|
|
||||||
|
if ($is_array_type && !is_array($arg)) $this->nonSQLError("Badly formatted SQL query: Expected array, got scalar instead!");
|
||||||
|
else if (!$is_array_type && is_array($arg)) $this->nonSQLError("Badly formatted SQL query: Expected scalar, got array instead!");
|
||||||
|
|
||||||
|
if ($type == 's') $result = $this->wrapStr($arg, "'", true);
|
||||||
|
else if ($type == 'i') $result = intval($arg);
|
||||||
|
else if ($type == 'd') $result = doubleval($arg);
|
||||||
|
else if ($type == 'b') $result = $this->formatTableName($arg);
|
||||||
|
else if ($type == 'l') $result = $arg;
|
||||||
|
else if ($type == 'ss') $result = "'%" . $this->escape(str_replace(array('%', '_'), array('\%', '\_'), $arg)) . "%'";
|
||||||
|
|
||||||
|
else if ($type == 'ls') $result = $this->wrapStr($arg, "'", true);
|
||||||
else if ($type == 'li') $result = array_map('intval', $arg);
|
else if ($type == 'li') $result = array_map('intval', $arg);
|
||||||
else if ($type == 'ld') $result = array_map('floatval', $arg);
|
else if ($type == 'ld') $result = array_map('doubleval', $arg);
|
||||||
else if ($type == 'lb') $result = array_map(array($this, 'formatTableName'), $arg);
|
else if ($type == 'lb') $result = array_map(array($this, 'formatTableName'), $arg);
|
||||||
else if ($type == 'll') $result = $arg;
|
else if ($type == 'll') $result = $arg;
|
||||||
else if (! $result) $this->nonSQLError("Badly formatted SQL query: $sql");
|
|
||||||
|
|
||||||
if (is_array($result)) {
|
else $this->nonSQLError("Badly formatted SQL query: Invalid MeekroDB param $type");
|
||||||
if (! $array_type) $result = $result[0];
|
|
||||||
else $result = '(' . implode(',', $result) . ')';
|
if (is_array($result)) $result = '(' . implode(',', $result) . ')';
|
||||||
|
|
||||||
if (is_array($result)) $this->nonSQLError("Badly formatted SQL query: $sql -- you passed an array but I didn't expect one!");
|
$query .= $result;
|
||||||
}
|
|
||||||
|
|
||||||
$sql = substr_replace($sql, $result, $new_pos, $length_type + $arg_number_length);
|
|
||||||
$pos_adj += strlen($result) - ($length_type + $arg_number_length);
|
|
||||||
}
|
}
|
||||||
return $sql;
|
|
||||||
|
return $query;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user