What part of it isn't expressive enough? Can't one do array( "any sql here" )?
No. That's not free sql, but a field value. So using $db->makeList(array("foo is not in ( 'a', 'b') ")); you get
$db->makeList(array("foo is not in ( 'a', 'b') "));
'foo is not in ( \'a\', \'b\') '
not the expected SQL.
Abstraction for NOT IN was added in r87992, but removed in r96930.
So instead of array("oi_sha1!" => $badKeys) I have to use this ugly code
array("oi_sha1!" => $badKeys)
count ( $badKeys ) ? "oi_sha1 NOT IN (" . $db->makeList( $badKeys ) . ")" : "*"
plus this change to allow free SQL text. :(