Notable changes:
* In SqlBagOStuff::getConnectionFromServerInfo, only two loggers were
injected. The rest implicitly got a NullLogger due to being absent.
These are now effectively unsilenced.
* Database::__construct() required almost all parameters, even the
loggers. I've wanted to move some of DatabaseFactory into the ctor
here for a while. In order to make this change not a breaking
change, the new 'logger' parameter is optional with NullLogger as
default. This allowed some of the test cases, which were simply
passing NullLogger, to be fixed by passing nothing instead of
passing the new option name.
The Database class is behind a dozen layers of indirection for
real use, so this will still be injected just fine (DBF, LB, LBF,
MWLBF, etc.).
* In LegacyLogger, the handling for $wgDBerrorLog was previously
limited to DBConnection and DBQuery. This now includes errors
from other (generally, newer) parts of Rdbms as well, which were
previously missing.
This only affects sites (typically CI and dev setup) where
$wgDBerrorLog is used, as opposed to the more common
$wgDebugLogGroups by-channel configuration.
* TransactionProfiler gets its logger injected in a rather odd way,
via entrypoints (MediaWiki.php, ApiMain.php, and MaintenanceRunner)
as opposed to service wiring. This is kept as-is for now.
* In LBFactoryTest, in particular testInvalidSelectDBIndependent2,
there are cases that intentionally produce failures of which
the result is then observed. In CI we assert that dberror.log is
empty so instead of adding the missing logger fields to that
LBFactory instance, the only one set (replLogger) is removed.
The alternative is to set 'logger' now, which would naturally
cause CI failures due to unexpected entries coming through to
non-mocked error log.
Bug: T320873
Change-Id: I7ca996618e41b93f488cb5c4de82000bb36e0dd3
Allow automatic retry if the first query fails due to the
connection having already been lost. Hide packet warnings
in doMultiStatementQuery(), which can occur due to dropped
connections.
Make queryMulti() actually mark the transaction or session
as corrupt when needed,
Improve executeQuery() handling of empty $sqls arrays.
Pass the full SQL statement array to beginIfImplied().
Add re-connection tests for queryMulti().
Related documentation changes:
* Clarify affectedRows()/insertId() documentation.
* Update queryMulti() documentation to mention exceptions.
* Add comments about avoiding direct BEGIN/COMMIT/ROLLBACK.
These should be avoided in queryMulti() as well.
Bug: T322689
Change-Id: I51d213acccfacc48674dbcf08c177cd9872c6e15
The RDBMs classes treat table names as application-supplied rather
than user-supplied, since it does not make sense for the user to be
able to blindly pick the schema (likely causing query errors). Table
names are generally non-problematic [a-zA-Z0-9_]+ strings. However,
they still should be escaped as identifiers, since they might have
problematic characters. Fix the SQLite backend to apply escaping
here, similar to MySQL and Postgres.
Fix incorrect use of tableName() in DatabaseSqlite::fieldInfo().
It should work the same as in tableExists().
Bug: T72510
Change-Id: I3713f81e6e1eca84cc51c12c9307d4c5dc737043
PHPUnit 3.7.0 was the first version to support @requires extension. At
the time checkPHPExtension() was added in a7901801b4, MediaWiki
still supported PHPUnit 3.6.7.
MediaWiki now requires intl and xml, so I removed checks for those
extensions rather than converting them to annotations.
checkPHPExtension() is removed without deprecation; it does not appear
to have ever been used (and is not likely to be used) in MW extensions.
This is explicitly permitted under the stable interface policy. Even if
it were not, only tests are affected, and they are supposed to fail
anyway if hard deprecated code is used.
Change-Id: I45f9b4c0e120683103cead916f4d4ef58bd11530
Per official policy, updates from versions older than two TLS releases
are not supported.
Finding the implicit marker is a bit tricky. The user might try to
upgrade from a really old version that doesn't have tag_summary table
and mistakenly think it's new and allow upgrade. So turning the check
logic into a boolean AND where it must be new enough to have
change_tag_def table AND new enough not to have tag_summary table.
Change-Id: I5ff9630a6539a587a47930847e108ac53757106f
This method is unused and the naming is not very clear in terms of what
it returns (server name vs config map). Removing it reduces externally
exposed complexity.
Optimize DBConnRef::getServerName() when the server index is known.
Use this to eliminate the "topologicalMaster" parameter from Database.
Rename internal fields and paramters in Database to use "primary"
instead of "master", for consistency.
Add some additional clarifying comments.
Bug: T299691
Change-Id: I98515fa02a58a4c72a06f1ff283b249b1617c886
Now that we moved considerable chunk of DatabaseSqlite to
SqlitePlatform, it's easier to mock and test without actually needing a
live db connection.
This allows moving a lot of tests from integration to unit tests making
them much faster.
Change-Id: I8ce7c470abed5144ba456a000c733e5d739c5c4e
It seems that on php 8.1, the data fetching from sqlite will
fetch integers for integer fields instead of strings. Cast
everything to strings so the test works on both php 8.1 and 7.x.
Bug: T313663
Change-Id: I0a2c2ab95b84565186ac7417f6cfdef2215f6bf1
Add Database::queryMulti(), which will execute an array of
queries as a batch with minimal roundtrips.
SQLite fallbacks to looping through each statement and
invoking doQuery().
Add QueryStatus class to reduce complexity in Database.
Rewrite doQuery() as doSingleStatementQuery().
Change-Id: I3d51083e36ab06fcc1d94558e51b38e106f71bb9
As required by the Iterator interface. In PHP 8.1 we can suppress the
warning with #[\ReturnTypeWillChange], but it's wrong and should change
anyway.
Depends-On: I576109808755b054e7876556f244ee8eafd12f9d
Change-Id: Ibaa7b4c81d8f114783db45c9100200ba14547c8f
Rename canRecoverFromDisconnect() in order to better describe
its function. Make it use the transaction ID and query walltime
as arguments and return an ERR_* class constant instead of a bool.
Avoid retries of slow queries that yield lost connection errors.
Track session state errors caused by the loss of named locks or
temp tables (e.g. during connection loss). Such errors will prevent
further queries except for rollback() and flushSession(), which must
be issued to resolve the error.
Add flushPrimarySessions() methods to LBFactory/LoadBalancer
and use it in places where session state loss is meant to be
safely aknowledged.
Change-Id: I60532f86e629c83b357d4832d1963eca17752944
This reverts commit eed58f2f61.
Reason for revert: Blocking the train, going to revert the whole chain
Change-Id: I64f9e5a9dde106671783f958a686ca697182077b
Use the LoadBalancer id in flushPrimarySessions(), not the LBFactory one,
and use assertOwnership() to check $owner, similar to other methods.
In DatabaseMysqlBase::doFlushSession(), change RELEASE_ALL_LOCKS() query
to use RELEASE_LOCK(), since only newer MariaDB versions (>=10.5.2) support
it. No errors were thrown in the method since they are suppressed, but the
syntax error would cause the transaction to be placed in an error state.
Add assertion to testTransactionCallbackChains() that would otherwise fail.
Randomize lock names in lock() tests to avoid contention.
Bug: T292239
Bug: T303887
Follow-Up: ee3c65d541
Follow-Up: 4cac31de4e
Change-Id: I414d737028338cfd5369eee24576df4aa26a2f6f
The policy allows this and since 1.39 is going to be the next LTS
release, I think it is fine to do this now.
Change-Id: If426e0ee349252ccc0ba9c4222c7d6865ab57fa2
The testUpgrades() method is slow and is easier to
parallelize via paratest if it lies in a separate class/file
Also make the test use a data provider
Bug: T50217
Change-Id: I5c8df6ae0ff34941f4cf7275680b309e79565925
Rename canRecoverFromDisconnect() in order to better describe
its function. Make it use the transaction ID and query walltime
as arguments and return an ERR_* class constant instead of a bool.
Avoid retries of slow queries that yield lost connection errors.
Add methods and class constants to track session state errors
caused by the loss of named locks or temp tables. Such errors can
be resolved by a "session flush" method.
Make assertQueryIsCurrentlyAllowed() better distinguish ROLLBACK
queries from ROLLBACK TO SAVEPOINT queries. For some scenarios,
only full tranasction ROLLBACK queries should be allowed.
Add flushSession() method to Database and flushPrimarySessions()
methods to LBFactory/LoadBalancer.
Also:
* Rename wasKnownStatementRollbackError() and make it take the
error number as an argument, similar to wasConnectionError().
Add mysql error codes for query timeouts since they only cause
statement rollbacks.
* Rename wasConnectionError() and mark it as protected. This is an
internal method with no outside callers.
* Rename wasQueryTimeout(), remove some HHVM-specific code, and
simplify the arguments.
* Make executeQuery() use a for loop for the query retry logic
to reduce code duplication.
* Move the error state setting logic in executeQueryAttempt() up
in order to reduce code duplication.
* Move the beginIfImplied() call in executeQueryAttempt() up to the
retry loop in executeQuery(). This narrows the executeQueryAttempt()
concerns to sending a single query and updating tracking fields.
* Make closeConnection() and doHandleSessionLossPreconnect() in
DatabaseSqlite more consistent with the base class by releasing named locks.
* Mark trxStatus() as @internal.
Bug: T281451
Bug: T293859
Change-Id: I200f90e413b8a725828745f81925b54985c72180
This is not testing anything since tables.sql was emptied
in I9f33132
It's probably also no longer necessary, since the schema
is now generated by Doctrine per platform, but I am not sure
about that, so I am just fixing the test and simplifying it.
Change-Id: Icb4d04e6057958771eb00a31b967a42cc948d6a1
Since the branch cut has happened, we can bump and get rid of legacy
cruft. According to the policy we can go up to 1.31 but let's keep it
that way to avoid major distruptions.
Change-Id: I9d697445a3bb5047726c8b2a7f808edb8403cdda
Make getServer() always return a string, as documented, even with new
Database::NEW_UNCONNECTED handles that have yet to call open(). If the
'host' parameter to __construct() is ''/null, getServer() now returns
'localhost' instead of null. This avoids problems like fatal errors in
calls to TransactionProfiler::recordConnection().
Use Database constants for "connectionParams" field keys for better
static analysis.
Also:
* Add Database::getServerName() method that returns "readable" server
names in the style of LoadBalancer::getServerName(). Note that the
"hostName" field is already passed in from LoadBalancer.
* Migrate most getServer() callers to getServerName() for easier
debugging and more readable logging.
* Also, normalize Database/LoadBalancer SPI logging context to use
"db_server" and reduce logging code duplication in LoadBalancer.
Bug: T277056
Change-Id: I00ed4049ebb45edab1ea07561c47e226a423ea3b
Ended up using
grep -Prl '\->setMethods\(' . | xargs sed -r -i 's/setMethods\(/onlyMethods\(/g'
special-casing setMethods( null ) -> onlyMethods( [] )
and then manual fix of failing test (from PS2 onwards).
Bug: T278010
Change-Id: I012dca7ae774bb430c1c44d50991ba0b633353f1
We don't support upgrading from below 1.31 officially and from below 1.27, the
upgrade system doesn't work at all.
The files are copied from the release branches.
Bug: T259771
Change-Id: Ib5251f7ae38148e00ac2dccb7bde76529c9d5076
Most of these are found by the not yet released I10559d8.
I remove the type MockObject in some cases when the calling
code really does not need to know if he get's a mock or the
real thing. However, I do this only in places that are very
closely related to the fixes.
Change-Id: I26a4c3c5a8ae141bf56161b52b54bce7e68f2e30
* parent::setUp() should be first, and ::tearDown()
should be last
* Move tests that directly extend PHPUnit\Framework\TestCase
to /unit
Change-Id: I1172855c58f4f52a8f624e6d596ec43beb8c93ff
These four test cases have been broken for months:
- testInsertIgnoreOld
- testInsertIgnoreNew
- testInsertSelectIgnoreOld
- testInsertSelectIgnoreNew
Disabling now to unblock T246358.
Bug: T246358
Bug: T259084
Change-Id: Idd1e920de8759d8795788572139c8528af05bd2c
The name change happened some time ago, and I think its
about time to start using the name name!
(Done with a find and replace)
My personal motivation for doing this is that I have started
trying out vscode as an IDE for mediawiki development, and
right now it doesn't appear to handle php aliases very well
or at all.
Change-Id: I412235d91ae26e4c1c6a62e0dbb7e7cf3c5ed4a6
Done with `composer fix` and suppressing the rest (i.e. sniffs for
global variables, which for core should be suppressed anyway).
Additionally, add `-p` to `phpcbf`, as otherwise it just seems stuck.
Change-Id: Ide8d6cdd083655891b6d654e78440fbda81ab2bc
Currently, when trying to automatically generate the schema, it
majestically explodes because "NULL" is not equal to "null".
Change-Id: I0facf313525eee1af31fdb307368ecf3bdda895b
These were left out by mistake (made easier by a bug where some phpunit
tests never run). Fixing the test bug is blocked on fixing the SQLite
schema so that DatabaseSqliteTest.php passes when it actually runs.
Bug: T246077
Change-Id: I75d7a7fb56a07c2984e987b6136e1fd00615c421
Add several new internal methods to help with wrangling
the various formats that rows, conditions, options, and
unique key lists can come in. Remove now unused method
isMultiRowArray().
Add various sanity checks and logging for parameters to
upsert(), replace(), insert(), and insertSelect().
Move DatabasePostgresTest to the integration/ directory.
Change-Id: If5988a6f0816e8da2cbf2fd612e1a3e3a2e9c52f