On Fri, Jun 12, 2009 at 10:02 AM, Leons
Petrazickis<[email protected]> 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<[email protected]> 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*.

_______________________________________________
Wikitech-l mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/wikitech-l

Reply via email to