summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Almdal <tnalmdal@shaw.ca>2009-03-12 03:20:13 +0000
committerTim Almdal <tnalmdal@shaw.ca>2009-03-12 03:20:13 +0000
commitd1f181da08cbb747a7353bf84fbaa5d1ab82bd02 (patch)
tree5b2f3c3e6675c59db77af4699b5e4585d071af02
parente58b955d4acc44bc2b49fffbffda42ad8b66069d (diff)
Attempt to reduce the chance of replacing text in sql statements that
is not a table name (but contained in braces) with the database prefix by building and maintaining a cache of database tables and prefixes.
-rw-r--r--core/libraries/MY_Database.php28
-rw-r--r--core/tests/Database_Test.php19
2 files changed, 44 insertions, 3 deletions
diff --git a/core/libraries/MY_Database.php b/core/libraries/MY_Database.php
index be0c2ec3..d54ac82b 100644
--- a/core/libraries/MY_Database.php
+++ b/core/libraries/MY_Database.php
@@ -18,6 +18,8 @@
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
class Database extends Database_Core {
+ protected $_table_names;
+
public function open_paren() {
$this->where[] = "(";
return $this;
@@ -56,6 +58,30 @@ class Database extends Database_Core {
public function add_table_prefixes($sql) {
$prefix = $this->config["table_prefix"];
- return preg_replace("#{([a-zA-Z0-9_]+)}#", "{$prefix}$1", $sql);
+ if (strpos($sql, "SHOW TABLES") === 0) {
+ /*
+ * Don't ignore "show tables", otherwise we could have a infinite
+ * @todo this may have to be changed if we support more than mysql
+ */
+ return $sql;
+ } else if (strpos($sql, "CREATE TABLE") === 0) {
+ // Creating a new table add it to the table cache.
+ $open_brace = strpos($sql, "{") + 1;
+ $close_brace = strpos($sql, "}", $open_brace);
+ $name = substr($sql, $open_brace, $close_brace - $open_brace);
+ $this->_table_names["{{$name}}"] = "{$prefix}$name";
+ }
+
+ if (!isset($this->_table_names)) {
+ // This should only run once on the first query
+ $this->_table_names =array();
+ $len = strlen($prefix);
+ foreach($this->list_tables() as $table_name) {
+ $naked_name = strpos($table_name, $prefix) !== 0 ? $table_name : substr($table_name, $len);
+ $this->_table_names["{{$naked_name}}"] = $table_name;
+ }
+ }
+
+ return empty($this->_table_names) ? $sql : strtr($sql, $this->_table_names);
}
} \ No newline at end of file
diff --git a/core/tests/Database_Test.php b/core/tests/Database_Test.php
index 1e0764cc..3d3c965b 100644
--- a/core/tests/Database_Test.php
+++ b/core/tests/Database_Test.php
@@ -86,14 +86,28 @@ class Database_Test extends Unit_Test_Case {
function prefix_replacement_test() {
$db = Database_For_Test::instance();
- $sql = "UPDATE {access_caches} SET `edit_1` = 1 " .
+ $converted = $db->add_table_prefixes("CREATE TABLE IF NOT EXISTS {test_tables} (
+ `id` int(9) NOT NULL auto_increment,
+ `name` varchar(32) NOT NULL,
+ PRIMARY KEY (`id`),
+ UNIQUE KEY(`name`))
+ ENGINE=InnoDB DEFAULT CHARSET=utf8");
+ $expected = "CREATE TABLE IF NOT EXISTS g3test_test_tables (
+ `id` int(9) NOT NULL auto_increment,
+ `name` varchar(32) NOT NULL,
+ PRIMARY KEY (`id`),
+ UNIQUE KEY(`name`))
+ ENGINE=InnoDB DEFAULT CHARSET=utf8";
+ $this->assert_same($expected, $converted);
+
+ $sql = "UPDATE {test_tables} SET `name` = '{test string}' " .
"WHERE `item_id` IN " .
" (SELECT `id` FROM {items} " .
" WHERE `left` >= 1 " .
" AND `right` <= 6)";
$sql = $db->add_table_prefixes($sql);
- $expected = "UPDATE g3test_access_caches SET `edit_1` = 1 " .
+ $expected = "UPDATE g3test_test_tables SET `name` = '{test string}' " .
"WHERE `item_id` IN " .
" (SELECT `id` FROM g3test_items " .
" WHERE `left` >= 1 " .
@@ -113,6 +127,7 @@ class Database_Test extends Unit_Test_Case {
class Database_For_Test extends Database {
static function instance() {
$db = new Database_For_Test();
+ $db->_table_names["{items}"] = "g3test_items";
$db->config["table_prefix"] = "g3test_";
return $db;
}