Aside from having no callers, it is not part of the documented interface
of IDatabase, or even Database.
Change-Id: I85e64fbb6527ab26494d9a5e5cec4bb518878b99
Cleanup after the switch of Database::query() to return ResultWrapper
instead of resource.
* Soft-deprecate the IResultWrapper accessors in IDatabase.
* Move relevant DBMS-specific functionality to ResultWrapper subclasses.
The deprecated methods in IResultWrapper become short and simple.
ResultWrapper is now abstract (b/c break).
* Move the implementation of fieldName(), numFields() and one of the
fieldInfo() implementations to the ResultWrapper subclass in order to
avoid ResultWrapper::unwrap() calls.
* Make Database::doQuery() return a ResultWrapper subclass instead of
underlying result data, so that the Database parent class does not
need to be aware of wrapper construction.
* Hard-deprecate ResultWrapper::unwrap(),
DatabaseMysqlBase::fieldType(), DatabasePostgres::fieldType().
* Fix the inefficient seeking method in SQLite.
* Make FakeResultWrapper extend ResultWrapper with an implementation
similar to the SQLite one. This is possible because ResultWrapper does
not depend on IDatabase anymore.
* Resolve fixme in DatabasePostgres: from studying the source,
neither pg_fetch_object() nor pg_num_rows() can set an error
retrievable with pg_last_error(). Removed unnecessary warning
suppression.
* ResultWrapperTest didn't make sense as a unit test anymore, so I
adapted it as an integration test against the current DBMS.
This change also means that ResultWrapper::key() always gives the
correct offset, even if Iterator methods are not being used.
Bug: T286694
Change-Id: I935835316c0bd7d3d061bd8fde9c9ce99ce756ec
This is useful assigning timestamps to critical section operations
without the risk of second-level clock drift from application servers
Bug: T274174
Change-Id: I2fa8af3632f5edb608113b401c6089d8476b06dd
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
These are no longer necessary, with abstract schema, the table
names should now be in sync with the names used in MySQL/SQlite.
Postgres-reserved identifiers need to be quoted where necessary.
Bug: T164898
Change-Id: I3bb11a021062d062ca645291c3c82cc318886bd9
On Postgres < 9.4, the query will be sent serially for each row
and so the values (for a row) cannot be enclosed in extra parentheses.
For batched query, it's possible even though not required there too.
Bug: T269964
Change-Id: Id3c0307d8999577529715017bba7ed43811f7fe3
A terminating line break has not been required in wfDebug() since 2014,
however no migration was done. Some of these line breaks found their way
into LoggerInterface::debug() calls, where they mess up the formatting
of the debug log.
So, remove terminating line breaks from wfDebug() and
LoggerInterface::debug() calls.
Also:
* Fix the stripping of leading line breaks from the log header emitted
by Setup.php. This feature, accidentally broken in 2014, allows
requests to be distinguished in the log file.
* Avoid using the global variable $self.
* Move the logging of the client IP back to Setup.php. It was moved to
WebRequest in the hopes that it would not always be needed, however
$wgRequest->getIP() is now called unconditionally a few lines up in
Setup.php. This means that it is put in its proper place after the
"start request" message.
* Wrap the log header code in a closure so that variables like $name do
not leak into global scope.
* In Linker.php, remove a few instances of an unnecessary second
parameter to wfDebug().
Change-Id: I96651d3044a95b9d210b51cb8368edc76bebbb9e
This reduces regex overhead and reliance on brittle assumptions.
This will also be useful for complex write queries involving WITH.
Some RDBMS types allow writes with in the WITH aliases themselves,
in addition to the main query itself. Checking raw SQL strings for
such things would get fairly complex.
Change-Id: I8ac4bc4d671abf02f97e82c5daf7b21271b85e5e
Allow truncation of multiple tables. This also provides for
a way to avoid risky keywords like CASCADE for Postgres.
For Postgres, use RESTART IDENTITY, which has been supported
since Postgres 8.4.
Avoid TRUNCATE/DELETE queries for empty temp tables, which is
useful for integrations tests that frequently call this method.
Reorganize and tweak the regexes in Database::getTempWrites().
It now recognizes multi-table DROP/TRUNCATE (Postgres-style).
Change-Id: Idd49f118b20ea5a0f7a3e8c00369aabcd45dd44e
Make related DatabaseSqlite::listTables() method directly use query()
rather than high-level wrapper.
Change-Id: I253f83091fb62fd0a449ac78d8846fb69bb808f6
Use it in MediaWikiIntegrationTestCase for resetting tables.
Also create Database::resetSequencesForTable() helper method from
the resetSequenceForTable() methods in the SQLite/Postgres classes.
Change-Id: I20945e20590e69340b1ce75f6bb2f6972375b00c
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
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
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
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
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
This avoids having two similar fields that have to stay
in sync. Clean up the related error handling for connections.
If a connection handle is unusable, like when essential SET
queries fail, then destroy it.
Also:
* Avoid use of transactions in DatabasePostgres::determineCoreSchema.
* Make sure all subclasses log on connection failure.
* Add schema sanity checks to mysql/sqlite classes.
* Add IDatabase::QUERY_NO_RETRY flag to simplify reasoning about
queries that already run on open() to begin with.
* Remove unused return value of Database::open.
* Remove deprecated Database::reportConnectionError method.
Change-Id: I97beba7ead1523085bda8784234d00c69ef1accc
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
Also:
* Fixed LoadBalancer::getAnyOpenConnection for both
DB_MASTER and DB_REPLICA, which are not real indexes.
* Lock down DBConnRef::close since it can only cause trouble.
* Relax DBConnRef restrictions on tablePrefix()/dbSchema()
for the harmless "getter" mode case.
* Remove redundant DatabasePostgres::getServer definition.
Change-Id: Ia855d901cc3c28147e52284fdabb1645805d4466
PostgreSQL doesn't support anything like this. For now, avoid generating
invalid SQL by just ignoring the option. If we come up with a use case
someday, that can guide implementation of a workalike.
Also, remove a pointless "IGNORE" from populateExternallinksIndex60.php.
el_index_60 isn't uniquely indexed, so it has no effect anyway.
Bug: T215169
Change-Id: I1409c80b39834d1977c82c489226255a8cc93fd0
PostgreSQL v12 will remove the long-deprecated column
pg_attrdef.adsrc. The supported way to introspect into column
default values is pg_get_expr(adbin, adrelid), which works
back through all versions of PostgreSQL supported by wikimedia.
Changing to the supported method will allow the upcoming v12 of the
database to be used while maintaining compatibility with older
versions, without needing to write version-specific code.
This patch has been tested with maintenance/update.php and
with phpunit in PostgreSQL versions 9.2, 11, and 12dev. It does
not harm the first two, and fixes errors that would otherwise
arise in the dev version. All unit tests which pass under version
11 now pass under 12dev as well.
Change-Id: I874d347fd286b26773113d4f0c6c30d9a4055ad3