New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
PostgreSQL driver, tests against DB backends, and general drivers cleanup #2723
PostgreSQL driver, tests against DB backends, and general drivers cleanup #2723
Conversation
Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
Most of the logic is now in PL/pgSQL. This completely avoids the use of Python f-strings to format identifiers into queries. Although an SQL-injection attack would have been impossible anyway (only the owner would have ever had the ability to do that), using PostgreSQL's format() is more reliable for unusual identifiers. Performance-wise, I'm not sure whether this is an improvement, but I highly doubt that it's worse. Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
# Conflicts: # Pipfile # Pipfile.lock # redbot/__main__.py # redbot/core/config.py # redbot/core/core_commands.py # redbot/core/drivers/json.py # redbot/core/json_io.py # redbot/setup.py # setup.cfg
Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
…-DiscordBot into V3/postgres_driver
Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
Signed-off-by: Toby Harradine <tobyharradine@gmail.com> # Conflicts: # redbot/core/config.py # redbot/core/drivers/red_base.py
Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
This is not at all a full review, but unless we intend on intentionally allowing users to use the drivers directly, in line with our updated version guarantees, the drivers should be private by convention.
@mikeshardmind The next PR for Config I do will be reorganising config into a package with the drivers as a private subpackage. I think that should be sufficient |
Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
Appears to work as intended, I still have a few more things to look at before I'm confident enough for a
Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
After the stuff which was brought up in discord was handled (ident based auth support, not requiring being a pg superuser) This is now ready for use.
Yay! The PostgreSQL driver is here. This comes with quite a few changes to the driver system, the data backup/migration/deletion system, and tests. The reason I made so many changes is because I wanted to harmonise backend-agnostic operations rather than add more driver-specific code where it didn't need to be. There are also just a few general cleanups in here too for the other drivers. This includes breaking changes for any dev using the drivers directly, but I think devs who are doing so should expect such breaking changes to occur (it's not exactly an interface we encourage devs to use).
The PostgreSQL driver
"cog_name.cog_identifier"
.red_cogs
table in thered_config
schema, to track which schemas actually contain red data, and to assist with migrations.redbot/core/driver/postgres/ddl.sql
contains all of the actual logic behind the driver, mostly in PL/pgSQL. At least we're diversifying our code baseinc()
andtoggle()
methods in anticipation for #2635.Changes to drivers more generally
red_
prefix. Also, driver classes are now available as attributes to theredbot.core.drivers
package, and extra requirements (motor, asyncpg) are imported conditionally.redbot.core.drivers
package:get_driver()
now takes the cog name, identifier, driver-specific kwargs (if needed) and an optionalstorage_type
kwarg. Ifstorage_type
is omitted, the function will default todata_manager.storage_type()
.get_driver_class()
, which simply takes an optionalstorage_type
and returns the class for the driver.BaseDriver.get_config_details()
is now an abstract staticmethod. With the Mongo driver, for some reason it was a module-level function, and was being called in a non-abstract and non-agnostic way.BaseDriver.initialize(**storage_details)
andBaseDriver.teardown()
are two new abstract coroutine classmethods to initialise and teardown the driver (db connections, DDL etc). For the JSON driver, these do nothing.BaseDriver.initialize()
will raise a new exception,redbot.core.errors.MissingExtraRequirements
, when the required extra has not been installed for that driver.data_path_override
kwarg to create standard drivers for a settings file in a core/cog data path. The kwarg is still available, however (for unit tests).IdentifierData.custom_group_data
is no longer a dict, has been renamed toIdentifierData.primary_key_len
and will always be an int (it was actually unclear what it was meant to be beforehand). This simplifies quite a bit of code where the primary key length is needed. Also,ConfigCategory.get_pkey_info()
is a new classmethod for the enum which returns a(primary_key_len, is_custom)
tuple based on the passed category and custom group data dict.BaseDriver.delete_all_data()
is a new coroutine method for deleting all data from the given backend. There is a generic implementation of this in the base driver, but the Mongo and Postgres drivers have overridden methods with extra options (e.g. allowing the data to be deleted by simply dropping the entire database). This replaces the logic which was previously inredbot.setup.remove_instance()
BaseDriver.aiter_cogs()
is an abstract asynchonous iterator which yields (cog_name, cog_id) tuples which refer to cogs which have data stored on that driver's backend. This is useful for migrations, as discussed below.BaseDriver.migrate_to()
is a new coroutine method which is a driver-agnostic (non-abstract) way of migrating data from one backend to another. It makes use of the newBaseDriver.aiter_cogs()
method and existingBaseDriver.(import|export)_data()
methods. Further discussed below.Changes to migrations and backups
redbot.setup
, except for that regarding MongoV1, has been removed.redbot.core.config.migrate()
is a new coroutine function for migrating from one driver to another. It usesBaseDriver.migrate_to()
under the hood, but abstracts away the retrieval of custom group data. It is used to migrate data to the JSON driver prior to a backup.[p]backup
command no longer contains driver-specific codeBaseDriver
ABC.Unit tests
-e
option or theTOXENV
env var. Options for the driver backend can be modified through environment variables (see tox.ini). Travis now has two extra jobs for these extra tox recipes.tests/conftest.py
has been added back in because pytest-asyncio is doing weird shit with theevent_loop
fixture (see pytest-dev/pytest-asyncio#75). It also contains the important new (autouse) fixture for setting up and tearing down the drivers. Now this may cause issues with 3rd party cog test suites which are making use of our fixtures, but I doubt it.That's it. I'm sorry it's such a massive PR. But all of these changes ultimately made it much easier to write and verify the new driver.