Repository: Cog-Creators/Red-DiscordBot

Issue:
Can't drop db with `redbot-setup delete`
# Other bugs

There are two problems here:
a) options 1 and 2 are doing the opposite of what they're supposed to (easy fix so I'm just including it in same issue):
```
Please choose from one of the following options:
 1. Drop the entire PostgreSQL database for this instance, or
 2. Delete all of Red's data within this database, without dropping the database itself.
```
b) There's a PostgresSyntaxError in drop database query (SQL function arguments can only be used as data values, not as identifiers):
```
Traceback (most recent call last):
  File "C:\Python38\lib\runpy.py", line 193, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "C:\Python38\lib\runpy.py", line 86, in _run_code
    exec(code, run_globals)
  File "C:\red\redbot\setup.py", line 700, in <module>
    run_cli()
  File "C:\red\redbot\setup.py", line 692, in run_cli
    cli()  # pylint: disable=no-value-for-parameter  # click
  File "C:\red\.venv\lib\site-packages\click\core.py", line 764, in __call__
    return self.main(*args, **kwargs)
  File "C:\red\.venv\lib\site-packages\click\core.py", line 717, in main
    rv = self.invoke(ctx)
  File "C:\red\.venv\lib\site-packages\click\core.py", line 1137, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "C:\red\.venv\lib\site-packages\click\core.py", line 956, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "C:\red\.venv\lib\site-packages\click\core.py", line 555, in invoke
    return callback(*args, **kwargs)
  File "C:\red\redbot\setup.py", line 632, in delete
    asyncio.run(
  File "C:\Python38\lib\asyncio\runners.py", line 43, in run
    return loop.run_until_complete(main)
  File "C:\Python38\lib\asyncio\base_events.py", line 612, in run_until_complete
    return future.result()
  File "C:\red\redbot\setup.py", line 267, in remove_instance
    await driver_cls.delete_all_data(interactive=interactive, drop_db=drop_db)
  File "C:\red\redbot\core\drivers\postgres\postgres.py", line 243, in delete_all_data
    await cls._pool.execute(f"DROP DATABASE $1", storage_details["database"])
  File "C:\red\.venv\lib\site-packages\asyncpg\pool.py", line 518, in execute
    return await con.execute(query, *args, timeout=timeout)
  File "C:\red\.venv\lib\site-packages\asyncpg\connection.py", line 274, in execute
    _, status, _ = await self._execute(query, args, 0, timeout, True)
  File "C:\red\.venv\lib\site-packages\asyncpg\connection.py", line 1402, in _execute
    result, _ = await self.__execute(
  File "C:\red\.venv\lib\site-packages\asyncpg\connection.py", line 1411, in __execute
    return await self._do_execute(query, executor, timeout)
  File "C:\red\.venv\lib\site-packages\asyncpg\connection.py", line 1423, in _do_execute
    stmt = await self._get_statement(query, None)
  File "C:\red\.venv\lib\site-packages\asyncpg\connection.py", line 328, in _get_statement
    statement = await self._protocol.prepare(stmt_name, query, timeout)
  File "asyncpg\protocol\protocol.pyx", line 163, in prepare
asyncpg.exceptions.PostgresSyntaxError: syntax error at or near "$1"
```


Discussion:
PostgreSQL needs to be connected to a database to drop another database (the database to drop can't have any active connections) and we can't know for sure what's the maintenance db for given PostgreSQL server. We can either remove option to drop whole database or try names that were most likely used for maintenance database (`postgres` or `template1`) and only clear schemas if we can't find the maintenance database.
I think just remove the option to drop the database - I put the option in there without reading the fine-print!



Resolving patch:
diff --git a/redbot/core/drivers/_mongo.py b/redbot/core/drivers/_mongo.py
--- a/redbot/core/drivers/_mongo.py
+++ b/redbot/core/drivers/_mongo.py
@@ -381,7 +381,7 @@ async def delete_all_data(
             while True:
                 resp = input("> ")
                 try:
-                    drop_db = bool(options.index(resp))
+                    drop_db = not bool(options.index(resp))
                 except ValueError:
                     print("Please type a number corresponding to one of the options.")
                 else:
diff --git a/redbot/core/drivers/postgres/postgres.py b/redbot/core/drivers/postgres/postgres.py
--- a/redbot/core/drivers/postgres/postgres.py
+++ b/redbot/core/drivers/postgres/postgres.py
@@ -204,46 +204,28 @@ async def aiter_cogs(cls) -> AsyncIterator[Tuple[str, str]]:
                 yield row["cog_name"], row["cog_id"]
 
     @classmethod
-    async def delete_all_data(
-        cls, *, interactive: bool = False, drop_db: Optional[bool] = None, **kwargs
-    ) -> None:
+    async def delete_all_data(cls, *, drop_db: Optional[bool] = None, **kwargs) -> None:
         """Delete all data being stored by this driver.
 
+        Schemas within the database which
+        store bot data will be dropped, as well as functions,
+        aggregates, event triggers, and meta-tables.
+
         Parameters
         ----------
-        interactive : bool
-            Set to ``True`` to allow the method to ask the user for
-            input from the console, regarding the other unset parameters
-            for this method.
         drop_db : Optional[bool]
-            Set to ``True`` to drop the entire database for the current
-            bot's instance. Otherwise, schemas within the database which
-            store bot data will be dropped, as well as functions,
-            aggregates, event triggers, and meta-tables.
+            If set to ``True``, function will print information
+            about not being able to drop the entire database.
 
         """
-        if interactive is True and drop_db is None:
+        if drop_db is True:
             print(
-                "Please choose from one of the following options:\n"
-                " 1. Drop the entire PostgreSQL database for this instance, or\n"
-                " 2. Delete all of Red's data within this database, without dropping the database "
-                "itself."
+                "Dropping the entire database is not possible in PostgreSQL driver."
+                " We will delete all of Red's data within this database,"
+                " without dropping the database itself."
             )
-            options = ("1", "2")
-            while True:
-                resp = input("> ")
-                try:
-                    drop_db = bool(options.index(resp))
-                except ValueError:
-                    print("Please type a number corresponding to one of the options.")
-                else:
-                    break
-        if drop_db is True:
-            storage_details = data_manager.storage_details()
-            await cls._pool.execute(f"DROP DATABASE $1", storage_details["database"])
-        else:
-            with DROP_DDL_SCRIPT_PATH.open() as fs:
-                await cls._pool.execute(fs.read())
+        with DROP_DDL_SCRIPT_PATH.open() as fs:
+            await cls._pool.execute(fs.read())
 
     @classmethod
     async def _execute(cls, query: str, *args, method: Optional[Callable] = None) -> Any:


Test patch: