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
This makes it possible to use with counter UPDATE queries.
Also add some extra sanity checks for input types.
Change-Id: Ibc2b7173e28022b5ba7bb04d11c594313a47a101
Add a query builder class which encapsulates the parameters to
IDatabase::select() and related functions.
Override useIndexClause() and ignoreIndexClause() in DatabaseTestHelper
so that index hints can be tested.
Bug: T243051
Change-Id: I58eec4eeb23bd7fb05b8b77d0a748f1026afee52
Previously it would give FROM followed by nothing which is always a
syntax error. Easier to fix it here than to convert empty arrays to
empty strings in SelectQueryBuilder.
Bug: T243051
Change-Id: I95a9b6a34cfb5c1ca4cf243c4226b5ed4f968035
testIsWriteQuery() never worked. It was using a non-existing provider,
which caused the test to be skipped with a warning. Access to the
protected method under test also needed fixing.
Change-Id: If35789027f2d6c44a7079e68a1c07c86be72d42b
Also changing its structure to be more readable and more like
https://w.wiki/CXo
My plan is to add more tables to this test.
Bug: T230428
Change-Id: Ia19d5c875cc95238f7fd7cd9adbed1ddb92af078
Quotes started being added to integers in r4984 (August 2004). Before
that, is_numeric() was used to determine whether to add quotes, so
quotes were omitted from numeric strings, which is obviously wrong.
The idea here is to use the type of the variable to hint to the database
as to whether quotes are needed. The results are somewhat inconsistent,
since some callers do not convert numeric strings obtained from user
input to integers. That makes it a more conservative change. Callers can
opt out of unquoted integers by casting them to string.
The reason for doing this is that quoting integers turns out to be not
as harmless as originally assumed. We found a case of it confusing the
MariaDB query planner, causing inappropriate indexes to be used.
I also made addQuotes() consistently return a string, instead of
returning an integer for boolean values. This was already the case for
MySQL, but it seems like a good idea everywhere.
Bug: T238378
Change-Id: I70473280f542ee5ecd79e187f580807410fbd548
If a string starts with "DELIMITER" but the word is *not* followed by
a space, the code will set $this->delimiter to null, possibly resulting
in all kinds of hard to track errors.
Even more problematic: the preg_match was *not* case-insensitive, but the
condition was. Which means that all non-uppercase "delimiter …" would
result in the same error.
I'm not sure if it's worth keeping the additional string comparison for
performance reasons. Probably not. That comparison is slow as well, and
preg_match is surprisingly fast (when the pattern is properly written,
which it is).
Change-Id: I33944b7a2410f77e67ce7450af0359a88d39f1aa
Move the DBO_TRX init logic out of Database::__construct() and into
LoadBalancer since the later already handles setting and clearing this
flag based on transaction rounds starting and ending.
Add 'lazyMasterHandle', 'topologyRole', and 'topologicalMaster' parameters
to Database::factory() and inject them via LoadBalancer all at once in order
to avoid worrying about call order. Move some type casting code to
Database::__construct().
Add IDatabase::getTopologyRole()/getTopologicalMaster().
Use constants for getLBInfo()/setLBInfo() for better usage tracking and
typo resistance.
Change-Id: I437ce434326601e6ba36d9aedc55db396dfe4452
Add public, protected or private to function missing a visibility
Enable the tests folder for the phpcs sniff
Change-Id: Ibefce76ea9984c47e08c94889ea2eafca7565e2c
assertEquals( false, … ) still succeeds when the actual value is 0, null,
an empty string, even an empty array. All these should be reported as a
failure, I would argue.
Note this patch previously also touched assertSame( false ). I reverted
these. The only benefit would have been consistency within this codebase,
but there is no strict reason to prefer one over the other. assertFalse()
and assertSame( false ) are functionally identical.
Change-Id: Ic5f1c7d504e7249002d3184520012e03313137b4
In masterPosWait(), only $pos will have the known active domain/server set
since it usually comes from getMasterPos(). However, the reference position,
from getReplicaDB(), does not have the active domains set since querying
gtid_domain_id on the replica would be incorrect and getting a connection
to the master could be expensive.
Remove obsolete hacks for jobs that used to store master positions.
Also, use the regular Database::query() method for stylistic consistency.
Bug: T224422
Change-Id: I41bbb9f337e46451aa17788dbd446db4a213a5a7
These type hints make it easier to follow the code paths and understand
what code is actually under test here. A few of these tests appear to
be misplaced, as they don't cover any code in the DatabaseMysqlBase
class.
This also makes all @covers tags absolute so more tools can understand
them (e.g. PHPStorm doesn't).
Change-Id: I43c69be994d6094239954ea662801c1e7e8e2e41
assertSame() is guaranteed to not do any type conversion. This can be
critical when acciden tially comparing, for example, 0 to 0.0.
Change-Id: Iffcc9bda69573623ba14af655dcd697d0fcce525
Enforce this pattern for the remaining LoadBalancer methods.
Carry this over into Database::close() to decide how loud the
error handling should be.
In LBFactory, clean up ownership of newMainLB()/newExternalLB().
The should have a null owner if called from outside the class
since the LBFactory does not track nor care about them anymore
in that case. Disable newMainLB() for LBFactorySingle as it
makes no sense and was broken.
Also remove some redundant abstract LBFactory methods that
just duplciate ILBFactory.
Bug: T231443
Bug: T217819
Depends-On: I7ed5c799320430c196a9a8e81af901999e2de7d0
Change-Id: I90b30a79754cfcc290277d302052e60df4fbc649
Make LoadBalancer::reallyOpenConnection() handle initializing DBO_TRX
instead of Database::__construct().
Also:
* Avoid having the "catch" block appear like it returns a
half-constructed Database.
* Use the variable name $conn instead of $db to be consistent
throughout the class. Only send Database::__construct() parameters
that it recognizes instead of mixing in setLBInfo() data.
Change-Id: Iffc3d1d0713051a164adb51a4c4ee12e4ac887c3
After approval of RFC T191231, we are going to drop oracle and mssql
and it will be possible to bring back the support using the abstract schema
Adding to release notes will be done in a follow-up
Bug: T230418
Change-Id: I90bd5cfcc3e18011b193c965fdb1fa54675040b5
Mainly:
* Use oci_new_connect() for Oracle to avoid broken connection reuse
similar to the PGSQL_CONNECT_FORCE_NEW flag in DatabasePostgres
* Set 'client_min_messages' unconditionally for PostgreSQL
* Factor out Database::getConnectExceptionAndLog() helper method
* Use the same style of query() calls in DatabaseOracle::open() as
the other subclasses
* Make sure the Database driver handle field is null on failure
instead of false for sanity
Also:
* Disallow changing of Database handle DBO_* flags after construction
where it does not make sense to change them
* Do not mention DBO_* flags meant for non-config use in $wgDBservers
* Ignore DBO_PERSISTENT for SQLite if DBO_TRX is also set for sanity
* Remove $wgDBOracleDRCP variable to discourage careless automatic
setting of DBO_PERSISTENT that breaks LoadBalancer assumptions
Change-Id: Iea948f7f872294ea8fc5d897fc10c9d29b7141d5
Make flushSnapshot() logging more detailed and check for explicit transaction
rounds. Also removing periods and trailing newlines from log/exception messages.
Change-Id: I0f6520f563680ab3a65b6338ced59ba25a2ec7b5
The callback will be called immediately when the section is cancelled,
whether that occurs directly, or via cancelling of an outer section, or
via rollback of the entire transaction.
Change-Id: Id05296948b52b95544547bd38c4387496b6c83b9
This is needed in order for Phan not to consider calls to
IDatabase::buildLike as invalid. Interestingly, it does not
consider calls to Database::buildLike invalid.
Bug: T191668
Change-Id: I0e027f5ec66d20b1d11e3441086001f6a751e1f5
This changeset implements T89432 and related tickets and is based on exploration
done at the Prague Hackathon. The goal is to identify tests in MediaWiki core
that can be run without having to install & configure MediaWiki and its dependencies,
and provide a way to execute these tests via the standard phpunit entry point,
allowing for faster development and integration with existing tooling like IDEs.
The initial set of tests that met these criteria were identified using the work Amir did in
I88822667693d9e00ac3d4639c87bc24e5083e5e8. These tests were then moved into a new subdirectory
under phpunit/ and organized into a separate test suite. The environment for this suite
is set up via a PHPUnit bootstrap file without a custom entry point.
You can execute these tests by running:
$ vendor/bin/phpunit -d memory_limit=512M -c tests/phpunit/unit-tests.xml
Bug: T89432
Bug: T87781
Bug: T84948
Change-Id: Iad01033a0548afd4d2a6f2c1ef6fcc9debf72c0d
This shares reconnection and retry logic but lacks some of the
restrictions applied to queries that go through the public query()
interface.
Use this in a few places such as doSelectDomain() for mysql/mssql.
Bug: T212284
Change-Id: Ie7341a0e6c4149fc375cc357877486efe9e56eb9
Even if there is only one database, if a DB_REPLICA connection
reference is obtained and an attempt is made to write it then
it will still fail. This can make it easier to spot incorrect
database usage even in a simple vanilla developer environment.
Note that methods like ILoadBalancer::getConnectionRef() can
be used for local connections as well as foreign ones.
Change-Id: I5523daad1bdd64624d3e0dd41bfd8d078b1078b0
Make IDatabase::lastDoneWrites() reflect creation and changes to
the cloned temporary unit test tables but not other temporary tables.
This effects the LB method hasOrMadeRecentMasterChanges(). Other tables
are assumpted to really just be there for temporary calculations rather
acting as test-only ephemeral versions of permanent tables. Treating
writes to the "fake permanent" temp tables more like real permanent
tables means that the tests better align with production.
At the moment, temporary tables still have to use DB_MASTER, given
the assertIsWritableMaster() check in query(). This restriction
can be lifted at some point, when RDBMs compatibility is robust.
Bug: T218388
Change-Id: I4c0d629da254ac2aaf31aae35bd2efc7bc064ac6