|
1 | | -"""Implement the database managed with pony.""" |
| 1 | +"""Contains hooks related to the database.""" |
2 | 2 | from __future__ import annotations |
3 | 3 |
|
4 | | -import enum |
5 | 4 | from pathlib import Path |
6 | 5 | from typing import Any |
7 | 6 |
|
8 | | -import click |
9 | | -from _pytask.click import EnumChoice |
10 | 7 | from _pytask.config import hookimpl |
11 | 8 | from _pytask.database_utils import create_database |
12 | | -from click import Context |
13 | | - |
14 | | - |
15 | | -class _DatabaseProviders(enum.Enum): |
16 | | - SQLITE = "sqlite" |
17 | | - POSTGRES = "postgres" |
18 | | - MYSQL = "mysql" |
19 | | - ORACLE = "oracle" |
20 | | - COCKROACH = "cockroach" |
21 | | - |
22 | | - |
23 | | -def _database_filename_callback( |
24 | | - ctx: Context, name: str, value: str | None # noqa: ARG001 |
25 | | -) -> str | None: |
26 | | - if value is None: |
27 | | - return ctx.params["root"].joinpath(".pytask.sqlite3") |
28 | | - return value |
29 | | - |
30 | | - |
31 | | -@hookimpl |
32 | | -def pytask_extend_command_line_interface(cli: click.Group) -> None: |
33 | | - """Extend command line interface.""" |
34 | | - additional_parameters = [ |
35 | | - click.Option( |
36 | | - ["--database-provider"], |
37 | | - type=EnumChoice(_DatabaseProviders), |
38 | | - help=( |
39 | | - "Database provider. All providers except sqlite are considered " |
40 | | - "experimental." |
41 | | - ), |
42 | | - default=_DatabaseProviders.SQLITE, |
43 | | - ), |
44 | | - click.Option( |
45 | | - ["--database-filename"], |
46 | | - type=click.Path(file_okay=True, dir_okay=False, path_type=Path), |
47 | | - help=("Path to database relative to root."), |
48 | | - default=Path(".pytask.sqlite3"), |
49 | | - callback=_database_filename_callback, |
50 | | - ), |
51 | | - click.Option( |
52 | | - ["--database-create-db"], |
53 | | - type=bool, |
54 | | - help="Create database if it does not exist.", |
55 | | - default=True, |
56 | | - ), |
57 | | - click.Option( |
58 | | - ["--database-create-tables"], |
59 | | - type=bool, |
60 | | - help="Create tables if they do not exist.", |
61 | | - default=True, |
62 | | - ), |
63 | | - ] |
64 | | - cli.commands["build"].params.extend(additional_parameters) |
| 9 | +from sqlalchemy.engine import make_url |
65 | 10 |
|
66 | 11 |
|
67 | 12 | @hookimpl |
68 | 13 | def pytask_parse_config(config: dict[str, Any]) -> None: |
69 | 14 | """Parse the configuration.""" |
70 | | - if not config["database_filename"].is_absolute(): |
71 | | - config["database_filename"] = config["root"].joinpath( |
72 | | - config["database_filename"] |
| 15 | + # Set default. |
| 16 | + if not config["database_url"]: |
| 17 | + config["database_url"] = make_url( |
| 18 | + f"sqlite:///{config['root'].as_posix()}/.pytask.sqlite3" |
73 | 19 | ) |
74 | 20 |
|
75 | | - config["database"] = { |
76 | | - "provider": config["database_provider"].value, |
77 | | - "filename": config["database_filename"].as_posix(), |
78 | | - "create_db": config["database_create_db"], |
79 | | - "create_tables": config["database_create_tables"], |
80 | | - } |
| 21 | + if ( |
| 22 | + config["database_url"].drivername == "sqlite" |
| 23 | + and config["database_url"].database |
| 24 | + ) and not Path(config["database_url"].database).is_absolute(): |
| 25 | + if config["config"]: |
| 26 | + full_path = ( |
| 27 | + config["config"] |
| 28 | + .parent.joinpath(config["database_url"].database) |
| 29 | + .resolve() |
| 30 | + ) |
| 31 | + else: |
| 32 | + full_path = ( |
| 33 | + config["root"].joinpath(config["database_url"].database).resolve() |
| 34 | + ) |
| 35 | + config["database_url"] = config["database_url"]._replace( |
| 36 | + database=full_path.as_posix() |
| 37 | + ) |
81 | 38 |
|
82 | 39 |
|
83 | 40 | @hookimpl |
84 | 41 | def pytask_post_parse(config: dict[str, Any]) -> None: |
85 | 42 | """Post-parse the configuration.""" |
86 | | - create_database(**config["database"]) |
| 43 | + create_database(config["database_url"]) |
0 commit comments