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 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
The decision to treat COMMIT/BEGIN as a "read" in isWriteQuery()
for the benefit of ChronologyProtector was first introduced
in r47360 (8653947b, 2009).
* Re-order strings in isTransactableQuery() to match the regular
expression in isWriteQuery() for quicker mental comparison
* Add missing visibility to DatabaseSqlite->isWriteQuery, matching
the parent class implementation.
Bug: T201900
Change-Id: Ic90f6455a2e696ba9428ad5835d0f4be6a0d9a5c
This ensure that the regex is escaped correctly,
even when the quoted value never contains the delimiter
Change-Id: I2dc93fa0154d4506c276a30cab008bc2ac5e0687
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
Partial revert of 8d61cf2793, since LBFactoryTest.php passes without
overriding selectDB() in the current master. It's unclear why it was necessary.
Bug: T200861
Change-Id: I7c0560d7890616899297f81a227db98996d5cb7f
Sqlite used the base implementation of trying a SELECT 1 query and
seeing if it failed. Instead, make it use the sqlite_master table.
Also remove the base version of that method since it would always
cause this problem and all subclasses have proper implementations.
Make LoadBalancerTest::assertWriteAllowed() more explicit and add
more assertions there.
Change-Id: I6c7b0bea8894c45dfe8931748d6687f0e5d1e101
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
Various revision storage tests assume the sequences are reset
and fail otherwise.
Also disable some failing tests that are not applicable to sqlite
as well as postgres.
Change-Id: Ibdb034121a44e16bb35059a92baafb1867951ea8
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
This takes the logic from wasErrorReissuable(), but puts it under
better name. The way that method was used, as well its comments,
were only about connection loss.
Make wasErrorReissuable() check if there was any error that
does not preclude the ability to retry. This matches the actual
name of the method.
Also improve some other related comments.
Change-Id: I68455d803afb2370897fecab0e79aadbb5d1a740
* Database::factory() supports a $connect parameter, that defaults
to NEW_CONNECTED (current behavior) but can also be NEW_UNCONNECTED.
* Add tests asserting the type of various instances returned from
Database::factory().
* Clean up sqlite "conn" field handling to handle cases of it
not being set, just as other classes do.
* Add some comments about the return type of doQuery().
Change-Id: Ic0837cfdb35326c2045133d664abd29043d48c03
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
At the time of the constructor, tableAliases will always be an empty
array. As such, the ATTACH command is never run for shared dbs, and we
get query errors when later trying to reference them. This changes it so
that the shared db is attached whenever the table aliases are finally
set.
Since table aliases may be set multiple times, the list of already
attached dbs was moved into class scope so that subsequent calls to set
the aliases do not result in query errors.
Bug: T181962
Change-Id: Ia654e996f54077bc3749b884a528e121ab25a2d2
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
The used phpcs has a bug, so the version 0.9.0 could not be enforced at the moment.
Will be fixed in next version, see T167168
Changed:
- Remove duplicate newline at end of file
- Add space between function and ( for closures
- and -> &&, or -> ||
Change-Id: I4172fb08861729bccd55aecbd07e029e2638d311
Move Sqlites's indexName to Database to have no remapping by default.
This is because MSSQL and Postgresql both don't need remapping, it's
just MySQL that's the problem.
So move the one from Database into MysqlBase to only do the remappings
there.
Also fix up the comments to make them less vague, not mentioning tables
when the function has no table parameter passed, so hence, no context
as to which table said index is wanted to be used
Bug: T154872
Change-Id: I46c575771e6cb36176bcf6cd1a865b703db0275d
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
The annotation was claiming string, but it's very obvious from
the usage the it should be string[].
Change-Id: I99849a338971590ca68dfb175b2458ad5ebc0df2
While prepping the code base for using etsy/phan i found a few problems.
A couple are real problems, while others are just places etsy couldn't
figure out the types.
* AuthPlugin referenced UserLoginTemplate which doesn't exist. Tracing
back usages this accepts classes that extend from BaseTemplate.
* DatabaseSqlite had an invalid @var annotation.
* LoadBalancer had some missing or under-defined annotations. Make them
more specific where possible.
* SqlBagOStuff didn't have the appropriate use statement for
WaitConditionLoop and probably doesn't work. Also updated annotations
that point to non-existent DatabaseBase to use IDatabase.
Change-Id: Iff2270b418ad2f8f97cfdb6df646c435d3283536
Use HTTPS instead of HTTP where the HTTP link is a redirect to the HTTPS link.
Also update some defect links.
Change-Id: Ic3a5eac910d098ed5c2a21e9f47c9b6ee06b2643
* Make isTransactableQuery() exclude CREATE/ALTER.
Starting transactions for schema changes like this can cause
errors as it is not supported for MySQL and some Postgres
operations. Note that temporary tables are session-level,
so they are not effected by this change.
* Clean up the transaction logic in determineCoreSchema()
so a transaction is not left dangling.
* Fix broken getSchemaPath() call in PostgresInstaller.
* Avoid warnings in DatabasePostgres::closeConnection() if
mConn is already unset.
* Commit master changes in doMaintenance.php before running
deferred updates, just as MediaWiki.php does.
* Change E_WARNING to E_USER_WARNING to avoid notices in the
default /rdbms error handlers.
* Also avoid trying to rollback in MWExceptionHandler if the
LBFactory service is disabled, which just results in an error.
Bug: T147599
Change-Id: I64ccab7f9b74f60309ba0c9a8ce68337c42ffb0f