summaryrefslogtreecommitdiff
path: root/includes/database.inc
diff options
context:
space:
mode:
Diffstat (limited to 'includes/database.inc')
-rw-r--r--includes/database.inc72
1 files changed, 51 insertions, 21 deletions
diff --git a/includes/database.inc b/includes/database.inc
index 5315e66ec..d43fd5ff2 100644
--- a/includes/database.inc
+++ b/includes/database.inc
@@ -131,32 +131,64 @@ function db_set_active($name = 'default') {
}
/**
+ * Helper function for db_query().
+ */
+function _db_query_callback($match, $init = FALSE) {
+ static $args = NULL;
+ if ($init) {
+ $args = $match;
+ return;
+ }
+
+ switch ($match[1]) {
+ case '%d': // We must use type casting to int to convert false/null/(true?)
+ return (int) array_shift($args); // We don't need db_escape_string as numbers are db-safe
+ case '%s':
+ return db_escape_string(array_shift($args));
+ case '%%':
+ return '%';
+ case '%f':
+ return (float) array_shift($args);
+ case '%b': // binary data
+ return db_encode_blob(array_shift($args));
+ }
+}
+
+define('DB_QUERY_REGEXP', '/(%d|%s|%%|%f|%b)/');
+
+/**
* Runs a basic query in the active database.
*
- * User-supplied arguments to the query should be passed in as separate parameters
- * so that they can be properly escaped to avoid SQL injection attacks.
+ * User-supplied arguments to the query should be passed in as separate
+ * parameters so that they can be properly escaped to avoid SQL injection
+ * attacks.
*
* @param $query
* A string containing an SQL query.
* @param ...
- * A variable number of arguments which are substituted into the query using
- * printf() syntax. Instead of a variable number of query arguments, you may
- * also pass a single array containing the query arguments.
+ * A variable number of arguments which are substituted into the query
+ * using printf() syntax. Instead of a variable number of query arguments,
+ * you may also pass a single array containing the query arguments.
+
+ * Valid %-modifiers are: %s, %d, %f, %b (binary data, do not enclose
+ * in '') and %%.
+ *
+ * NOTE: using this syntax will cast NULL and FALSE values to decimal 0,
+ * and TRUE values to decimal 1.
+ *
* @return
- * A database query result resource, or FALSE if the query was not executed
- * correctly.
+ * A database query result resource, or FALSE if the query was not
+ * executed correctly.
*/
function db_query($query) {
$args = func_get_args();
+ array_shift($args);
$query = db_prefix_tables($query);
- if (count($args) > 1) {
- if (is_array($args[1])) {
- $args = array_merge(array($query), $args[1]);
- }
- $args = array_map('db_escape_string', $args);
- $args[0] = $query;
- $query = call_user_func_array('sprintf', $args);
+ if (isset($args[0]) and is_array($args[0])) { // 'All arguments in one array' syntax
+ $args = $args[0];
}
+ _db_query_callback($args, TRUE);
+ $query = preg_replace_callback(DB_QUERY_REGEXP, '_db_query_callback', $query);
return _db_query($query);
}
@@ -167,15 +199,13 @@ function db_query($query) {
*/
function db_queryd($query) {
$args = func_get_args();
+ array_shift($args);
$query = db_prefix_tables($query);
- if (count($args) > 1) {
- if (is_array($args[1])) {
- $args = array_merge(array($query), $args[1]);
- }
- $args = array_map('db_escape_string', $args);
- $args[0] = $query;
- $query = call_user_func_array('sprintf', $args);
+ if (isset($args[0]) and is_array($args[0])) { // 'All arguments in one array' syntax
+ $args = $args[0];
}
+ _db_query_callback($args, TRUE);
+ $query = preg_replace_callback(DB_QUERY_REGEXP, '_db_query_callback', $query);
return _db_query($query, 1);
}