Commit graph

110 commits

Author SHA1 Message Date
Umherirrender
88fe512c22 Pass function name to database functions (rdbms/installer)
Change-Id: Ia37d37f2471960c1d9d04fd9bd86224058e88413
2020-06-07 21:06:47 +02:00
Tim Starling
47a1619027 Remove terminating line breaks from debug messages
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
2020-06-03 12:01:16 +10:00
Aaron Schulz
27cf5ace45 rdbms: add IDatabase::QUERY_* flags to obviate isWriteQuery()
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
2020-04-28 00:49:11 +00:00
Aaron Schulz
cbc700e186 rbms: optimize and rename truncateTable() to truncate()
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
2020-04-21 01:26:18 -07:00
Aaron Schulz
303ec64395 rdbms: convert "Exception" try/catch blocks to "Throwable" or "RuntimeException"
Change-Id: I95c204c5c436c3504dcab9e7fe2ae27936ffb590
2020-04-02 01:14:17 +00:00
jenkins-bot
20a0c8ab5a Merge "rdbms: add QUERY_IGNORE_DBO_TRX to duplicateTableStructure() queries" 2020-03-29 16:42:34 +00:00
Aaron Schulz
d42ad1e215 rdbms: add QUERY_IGNORE_DBO_TRX to duplicateTableStructure() queries
Make related DatabaseSqlite::listTables() method directly use query()
rather than high-level wrapper.

Change-Id: I253f83091fb62fd0a449ac78d8846fb69bb808f6
2020-03-27 01:40:24 +00:00
Aaron Schulz
e1a8c4e2a0 rdbms: add IMaintainableDatabase::truncateTable()
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
2020-03-25 01:36:06 +00:00
Aaron Schulz
13b11a946e rdbms: reduce duplication in Database via helper methods
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
2020-03-10 22:26:04 +00:00
Umherirrender
92a0db8165 Pass 1 always as string to IDatabase::select and friends
Column names or other sql fragments are strings, not integer

Change-Id: I7950b6e7ce4fa3b97c8b8ed55c8d7d0119eaac7e
2020-01-11 00:36:13 +00:00
James D. Forrester
0958a0bce4 Coding style: Auto-fix MediaWiki.Usage.IsNull.IsNull
Change-Id: I90cfe8366c0245c9c67e598d17800684897a4e27
2020-01-10 14:17:13 -08:00
James D. Forrester
4f2d1efdda Coding style: Auto-fix MediaWiki.Classes.UnsortedUseStatements.UnsortedUse
Change-Id: I94a0ae83c65e8ee419bbd1ae1e86ab21ed4d8210
2020-01-10 09:32:25 -08:00
Umherirrender
c7ad21c25f Improve param docs
Change-Id: I746a69f6ed01c3ff000da125457df62b02d13b34
2019-11-28 19:08:59 +01:00
Tim Starling
673d496f2d Have Database::addQuotes() pass through bare integers without quoting
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
2019-11-18 11:40:28 +11:00
Aaron Schulz
fb621c26a3 rdbms: various cleanups to LoadBalancer::reallyOpenConnection()
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
2019-10-11 11:35:02 -07:00
Aaron Schulz
2f8be5ca9d rdbms: cleanup visibility of Database::makeSelectOptions()
Change-Id: I2e18dd3d450ceec9895d3143074743bc206a943d
2019-09-03 20:27:27 -07:00
Urbanecm
6ded91313c Revert "rdbms: make LoadBalancer::reallyOpenConnection() handle setting DBO_TRX"
This reverts commit 45831e619c.

Reason for revert: Caused beta not work at all.

Bug: T231162
Change-Id: Icc5c1fa0dc01082a622641ad96c22c939cd56d48
2019-08-25 16:39:33 +00:00
Aaron Schulz
45831e619c rdbms: make LoadBalancer::reallyOpenConnection() handle setting DBO_TRX
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
2019-08-24 20:06:17 +00:00
jenkins-bot
436f8eb32f Merge "rdbms: remove various deprecated methods" 2019-07-26 15:16:38 +00:00
Aaron Schulz
4c7e4575f5 rdbms: remove various deprecated methods
Change-Id: I5ae923065a08078225b7df080cb92edca799ebaf
2019-07-26 15:56:02 +01:00
Aaron Schulz
023c73f612 rdbms: normalize Database open() code and error handling
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
2019-07-26 15:24:28 +01:00
jenkins-bot
3fda59f962 Merge "rdbms: fix some phpstorm warnings database classes" 2019-07-13 23:22:51 +00:00
Aaron Schulz
0848e9049c rdbms: fix some phpstorm warnings database classes
Change-Id: Ib3b8aaadda8101ed82158b1260f10f6d7be16783
2019-07-13 21:49:51 +00:00
Aaron Schulz
d322031d52 rdbms: switch to AtEast warning suppression in Database classes
Change-Id: Ia32f1ba048a540438f78b11a1e94f80acfc7bf50
2019-07-13 01:49:05 +00:00
Aaron Schulz
c351a9cab0 rdbms: cleanup some Database error message wording for consistency
Change-Id: I7b338e6e856c62ecaab2ef97f76431c2220b430d
2019-07-11 21:37:54 +00:00
Aaron Schulz
a830c14d0b rdbms: make implement IResultWrapper directly instead of via inheritence
Change-Id: If1b15c0c21d0ee336025fb99f47fc19ddf1d5435
2019-07-04 13:42:53 +00:00
Aaron Schulz
23ffabbf77 rdbms: combine trxLevel and trxShortId fields in Database
This avoids having to keep multiple fields in sync

Change-Id: If96267afe56a9b9cd660bab333e7667e4d8dc3d4
2019-06-28 14:40:27 -07:00
Aaron Schulz
7911da9c6f rdbms: remove $opened field from Database for simplicity
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
2019-06-27 18:29:12 +01:00
Fomafix
9cbb8f104d Use https://www.php.net/ instead of https://secure.php.net/
Change-Id: I0acca592c6909e91b28b904da49dcbd6a43cd2a5
2019-04-12 06:44:48 +02:00
jenkins-bot
970fbf54ab Merge "rdbms: add ATTR_SCHEMAS_AS_TABLE_GROUPS attribute" 2019-03-27 19:22:07 +00:00
jenkins-bot
1a62e51a00 Merge "rdbms: treat cloned temporary tables as "effective write" targets" 2019-03-26 22:02:10 +00:00
Aaron Schulz
314968036b rdbms: add ATTR_SCHEMAS_AS_TABLE_GROUPS attribute
Change-Id: Ia12a00c30039acd6c59726f35d03cc76aa957902
2019-03-26 14:37:27 -07:00
Aaron Schulz
108fd8b18c rdbms: treat cloned temporary tables as "effective write" targets
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
2019-03-26 14:24:42 -07:00
jenkins-bot
4905504fad Merge "rdbms: Use correct value for 'sslmode' in DatabasePostgres" 2019-03-26 18:51:26 +00:00
Mark A. Hershberger
2e5d114a99 rdbms: Use correct value for 'sslmode' in DatabasePostgres
Fix Postgres support by using ‘sslmode=require' instead of ‘sslmode=1'.

See https://www.postgresql.org/docs/current/static/libpq-ssl.html#LIBPQ-SSL-SSLMODE-STATEMENTS

Change-Id: I424b0e3e144bbe9f0a2bde9a3b4a674dde10c729
2019-03-26 18:22:07 +00:00
Aaron Schulz
4118762bbe rdbms: avoid connections on more lazy DBConnRef methods
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
2019-03-21 17:35:27 -07:00
Aaron Schulz
6ab386219e rdbms: document Database::doQuery() return value
Removed random @throws tag from a subclass while at it

Change-Id: I1cad1f66b62bb4a306feb5c773ed5556891f82a7
2019-03-01 02:23:27 +00:00
Brad Jorsch
814605a979 DatabasePostgres: Ignore "IGNORE" option to update()
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
2019-02-20 10:39:45 -05:00
Jeff Janes
27d342ef4b rdbms: Remove references to pg_attrdef.adsrc in Postgres code
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
2019-01-22 19:23:06 +00:00
Fomafix
3ee1560232 No yoda conditions
Replace
  if ( 42 === $foo )
by
  if ( $foo === 42 )

Change-Id: Ice320ef1ae64a59ed035c20134326b35d454f943
2018-11-21 17:54:39 +01:00
Aaron Schulz
633eb437a3 rdbms: clean up return values of IDatabase write methods
Also improved the atomicity and affected row count logic for
insert/replace with sqlite.

Also remove unused "fileHandle" code from insert().

Change-Id: If7b9148fd44f3a958899885753c7c86ba66bf193
2018-10-30 03:34:52 +00:00
Aaron Schulz
fe0af6cad5 rdbms: Database::selectDB() update the domain and handle failure better
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
2018-10-10 12:03:30 -07:00
Brian Wolff
528042054f Fix some phan-taint-check false positives
Change-Id: Ic5ccbb3f97722476bee7188b83b80cdc652d2a64
2018-09-21 17:27:44 -07:00
Aaron Schulz
41a37d14fa rdbms: make Database::open() protected
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
2018-08-21 18:34:51 -07:00
Fomafix
0a0d5cb7f7 Fix typos
Bug: T201491
Change-Id: I25a27d11faabe2f5fa02950c7a4fb58b13fb3662
2018-08-14 09:52:19 +00:00
Aaron Schulz
f3a197e49b rdbms: add "maxReadRows" limit to TransactionProfiler
Change-Id: I008fc1857c7aa43d93f43361803d5e52c4ddf089
2018-08-13 13:30:08 -07:00
Bartosz Dziewoński
485f66f174 Use PHP 7 '??' operator instead of '?:' with 'isset()' where convenient
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
2018-05-30 18:06:13 -07:00
Reedy
765370a6db Add @deprecated tags to various class_alias calls
Bug: T195576
Change-Id: I10cd8415891bfe4a278eee06c9cfe905b3e036dc
2018-05-29 13:10:20 -07:00
Brad Jorsch
6318430fc8 PostgreSQL: Set owners for sequences
PostgreSQL allows setting an "owner" column for a sequence, so if that
column is dropped then the sequence will be dropped too. We should
certainly take advantage of that when creating duplicate tables for unit
testing (particularly when $temporary is false), and we may as well do
it for our permanent tables too.

Change-Id: I4822ac33298e3f3ef59f4372a24aa0866a6e66ae
2018-04-09 12:05:29 -04:00
Brad Jorsch
501b1fb7df tests: Reset Postgres sequences when cloning and truncating
This improves the repeatability of the unit tests by making the ID
values generated depend less on what previous tests might have done.

It also prevents tests from using up sequence numbers for the live DB's
tables.

Change-Id: Iaa8ae1e5cef4b9099bd1b4b8fc806f5af372a7ff
2018-04-05 23:57:24 +00:00