Also improved the atomicity and affected row count logic for
insert/replace with sqlite.
Also remove unused "fileHandle" code from insert().
Change-Id: If7b9148fd44f3a958899885753c7c86ba66bf193
LoadBalancer uses Database::getDomainId() for deciding which keys to use
in the foreign connection handle arrays. This method should reflect any
changes made to the DB selection.
If the query fails, then do not change domain field. This is the sort of
approach that LoadBalancer is expects in openForeignConnection(). Also,
throw an exception when selectDB() fails.
The db/schema/prefix fields of Database no longer exist in favor of just
using the newer currentDomain field.
Also:
* Add IDatabase::selectDomain() method and made selectDB() wrap it.
* Extract the DB name from sqlite files if not explicitly provided.
* Fix inconsistent open() return values from Database subclasses.
* Make a relationSchemaQualifier() method to handle the concern of
omitting schema names in queries. The means that getDomainId() can
still return the right value, rather than confusingly omitt the schema.
* Make RevisionStore::checkDatabaseWikiId() account for the domain schema.
Unlike d2a4d614fc, this does not incorrectly assume the storage is
always for the current wiki domain. Also, LBFactorySingle sets the local
domain so it is defined even in install.php.
* Make RevisionStoreDbTestBase actually set the LoadBalancer local domain.
* Make RevisionTest::testLoadFromTitle() account for the domain schema.
Bug: T193565
Change-Id: I6e51cd54c6da78830b38906b8c46789c79498ab5
This is not called externally and there is little reason for that to
change. The current caller pattern is to use factory(), possibly with
initConnection() afterwards, or to use a LoadBalancer to begin with.
Change-Id: Ib1fdd5c960f1ed877fcd17bcb99b999d5d894716
Find: /isset\(\s*([^()]+?)\s*\)\s*\?\s*\1\s*:\s*/
Replace with: '\1 ?? '
(Everywhere except includes/PHPVersionCheck.php)
(Then, manually fix some line length and indentation issues)
Then manually reviewed the replacements for cases where confusing
operator precedence would result in incorrect results
(fixing those in I478db046a1cc162c6767003ce45c9b56270f3372).
Change-Id: I33b421c8cb11cdd4ce896488c9ff5313f03a38cf
Handle all errors in query() that might have caused rollback by
putting the Database handle into an error state that can only be
resolved by cancelAtomic() or rollback(). Other queries will be
rejected until then.
This results in more immediate exceptions in some cases where
atomic section mismatch errors would have been thrown, such as a
an error bubbling up from a child atomic section. Most cases were
a try/catch block assumes that only the statement was rolled back
now result in an error and rollback.
Callers using try/catch to handle key conflicts should instead use
SELECT FOR UPDATE to find conflicts beforehand, or use IGNORE, or
the upsert()/replace() methods. The try/catch pattern is unsafe and
no longer allowed, except for some common errors known to just
rollback the statement. Even then, such statements can come from
child atomic sections, so committing would be unsafe. Luckily, in
such cases, there will be a mismatch detected on endAtomic() or a
dangling section detected in close(), resulting in rollback.
Remove caching from DatabaseMyslBase::getServerVariableSettings
in case some SET query changes the values.
Bug: T189999
Change-Id: I532bc5201681a915d0c8aa7a3b1c143b040b142e
Atomic sections are currently useful if you want to wrap some SQL
statements in a transaction when you might be called from inside someone
else's transaction, and you expect the caller to roll back everything if
you fail.
But there are some cases where you want to allow the caller to recover
from errors, in which case you need to roll back just the atomic
section. Savepoints are supported by all our databases and can be used
for this purpose, so let's do so.
Bug: T188660
Change-Id: Iee548619df89fd7fbd581b01106b8b41d3df71cc
If the $var argument is provided, then it will make the resulting
count exclude rows where the value for that column is NULL.
Also add buildSelectSubquery() method and Subquery
wrapper class for use with select() for calculated tables.
Change-Id: I549d629af99afdf370602de095f7fba6d1546c37
Done using the PhpStorm refactor->rename tool.
Also move "defaultBigSelects" declaration to DatabaseMysqlBase
as no other classes uses that.
Change-Id: I424a2d9815de3a5d4cca2522f3db23a5efe6b592
* Update replace()/upsert() to combine the affected row
count for the non-native case
* Also make replace() atomic in the non-native case,
similar to how upsert() already works
Change-Id: I6c9bcba54eca6bcf4a93a9b230aaedf7f36aa877
SQL supports parentheses for grouping in the FROM clause.[1] This is
useful when you want to left-join against a join of other tables.
For example, say you have tables 'a', 'b', and 'c'. You want all rows
from 'a', along with rows from 'b' + 'c' only where both of those
exist.
SELECT * FROM a LEFT JOIN b ON (a_b = b_id) JOIN c ON (b_c = c_id)
doesn't work, it'll only give you the rows where 'c' exists.
SELECT * FROM a LEFT JOIN b ON (a_b = b_id) LEFT JOIN c ON (b_c = c_id)
doesn't work either, it'll give you rows from 'b' without a
corresponding row in 'c'. What you need to do is
SELECT * FROM a LEFT JOIN (b JOIN c ON (b_c = c_id)) ON (a_b = b_id)
This patch implements this by extending the syntax for the $table
parameter to IDatabase::select(). When passing an array of tables, if a
value in the array is itself an array that is interpreted as a request
for a parenthesized join. To produce the example above, you'd do
something like
$db->select(
[ 'a', 'nest' => [ 'b', 'c' ] ],
'*',
[],
__METHOD__,
[],
[
'c' => [ 'JOIN', 'b_c = c_id ],
'nest' => [ 'LEFT JOIN', 'a_b = b_id' ],
]
);
[1]: In standards as far back as SQL-1992 (I couldn't find an earlier
version), and it seems to be supported by at least MySQL 5.6, MariaDB
10.1.28, PostgreSQL 9.3, PostgreSQL 10.0, Oracle 11g R2, SQLite 3.20.1,
and MSSQL 2014 (from local testing and sqlfiddle.com).
Change-Id: I1e0a77381e06d885650a94f53847fb82f01c2694
Under some conditions (Semantic MediaWiki, Gadgets), an integer is
passed to DatabaseMysqli::mysqlRealEscapeString (). This integer is, in
turn, passed to mysqli::real_escape_string (), which needs a string.
Under HHVM 3.19.1 (at least) this type mismatch causes an exception.
A typecast should prevent it.
I repeated the patch in other DB drivers where I could find a function
that escaped strings for SQL.
Bug: T163646
Change-Id: I1b7820bc064dc79498cf9f17747f745990c526b7
selectField() and selectFieldValues() are trivial, they just need to
pass it through to select(). In fact, selectFieldValues() was already
doing it, just no one ever updated IDatabase.
insertSelect() is a little more work. nativeInsertSelect() was
originally written as largely a copy-paste of select() and has since
gotten well out of sync. Now that we have selectSQLText(), we should be
able to just use that. DatabasePostgres's implementation can wrap the
parent implementation instead of being another copy-paste, but
DatabaseOracle seems to still need to be special.
Change-Id: I0e6a9e6daa510639d3212641606047a5db96c500
The TitleValue constructor, used by the link cache among other things,
throws an exception for DB keys which do not satisfy a simple sanity test
(starting or ending with _, or containing a space, tab, CR or LF
character). This has broken certain special pages on a number of WMF sites;
see T99736, T146778 and T155091.
The new cleanupInvalidDbKeys.php script allows these bogus entries to be
removed from the DB, making sure these exceptions won't be thrown in the
future. It cleans the title columns of the page, archive, redirect,
logging, category, protected_titles, recentchanges, watchlist, pagelinks,
templatelinks, and categorylinks tables.
The script doesn't support batching; most wikis should have fewer than 500
broken entries in each table. If need be, the script can be run several
times.
To make the LIKE queries work properly I had to fix the broken escaping
behaviour of Database::buildLike() -- previously it had a habit of double-
escaping things. Now an ESCAPE clause is added to change the escape
character from the problematic default backslash, and tests are added to
cover the changes.
Bug: T155091
Change-Id: I908e795e884e35be91852c0eaf056d6acfda31d8
Leave \Blob as an alias. Callers can now use the Rdbms\Blob class
for "extends"/"new" and the Rdbms\IBlob interface for type hints.
Change-Id: I983b76f181ac60c1eb92c350cd27ad77ec90a192
* Inject global variables in MWLBFactory.php
* Remove incompatible ignoreErrors() override which is only called
from the base classes.
* Remove use of wf* methods.
Change-Id: Idf8202474182cc82fb6ef453e2722e7af17e32aa
2017-02-10 10:31:52 -08:00
Renamed from includes/db/DatabaseMssql.php (Browse further)