On Fri, Jun 12, 2009 at 10:02 AM, Leons
Petrazickis<leons.petrazickis(a)gmail.com> wrote:
1. Refactor the database to not use an integer as a
bit field. Just
use four different boolean columns, which works well cross-database.
In MySQL, four different boolean columns means four times the storage,
as compared to one TINYINT used as a bitfield. So this isn't a good
solution.
2. Add a function to the Database API for each bit
operator.
$sql = $database->bitand('log_deleted', 1);
3. Add a function to the Database API to handle all the operators.
$sql = $database->op('&', 'log_deleted', 1);
or
$sql = $database->op(Database::BITAND, 'log_deleted', 1);
These would be the way to do it, I guess. We do something similar for
things like conditionals already. I think 2 is preferable to 3,
stylistically.
On Fri, Jun 12, 2009 at 11:06 AM, Freako F. Freakolowsky<freak(a)drajv.si> wrote:
Oracle abstraction solves this problem in makeList
function ... the only
weak point for this solution is if you write SQL statements manualy, if
you use Database class functions to create the actual SQL statement this
works and as i was told on #mediawiki manual sql creation should
gradually be rooted out.
This isn't a good solution:
foreach ($a as $key => $value) {
if (strpos($key, ' & ') !== FALSE)
$a2[preg_replace('/(.*)\s&\s(.*)/', 'BITAND($1, $2)',
$key)] = $value;
elseif (strpos($key, ' | ') !== FALSE)
$a2[preg_replace('/(.*)\s|\s(.*)/', 'BITOR($1, $2)',
$key)] = $value;
elseif (!is_array($value)) {
if (strpos($value, ' = ') !== FALSE) {
if (strpos($value, ' & ') !== FALSE)
$a2[$key] =
preg_replace('/(.*)\s&\s(.*?)\s=\s(.*)/', 'BITAND($1, $2) = $3',
$value);
elseif (strpos($value, ' | ') !== FALSE)
$a2[$key] =
preg_replace('/(.*)\s|\s(.*?)\s=\s(.*)/', 'BITOR($1, $2) = $3',
$value);
else $a2[$key] = $value;
}
elseif (strpos($value, ' & ') !== FALSE)
$a2[$key] = preg_replace('/(.*)\s&\s(.*)/',
'BITAND($1, $2)', $value);
elseif (strpos($value, ' | ') !== FALSE)
$a2[$key] = preg_replace('/(.*)\s|\s(.*)/',
'BITOR($1, $2)', $value);
else
$a2[$key] = $value;
}
It breaks on all sorts of possible input, like $dbr->select(
'revision', '*', 'rev_deleted&1' ) or $dbr->update(
'user', array(
'user_name' => 'Sam & Max'), $where ), or any number of other
things.
Not actually tested, but it definitely breaks *somewhere*.