Skip to content
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

Support history_file configuration per dsn, and --history option. #1216

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 17 additions & 5 deletions pgcli/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,8 @@ def __init__(
prompt_dsn=None,
auto_vertical_output=False,
warn=None,
histfile=None,
alias_dsn=None,
):

self.force_passwd_prompt = force_passwd_prompt
Expand Down Expand Up @@ -227,6 +229,16 @@ def __init__(

self.completion_refresher = CompletionRefresher()

# history file location: --hisfile > pgclirc:history
if histfile:
self.history_file = histfile
else:
self.history_file = self.config["main"]["history_file"]
if self.history_file == "default":
self.history_file = config_location() + "history"

if alias_dsn:
self.dsn_alias = alias_dsn
self.query_history = []

# Initialize completer
Expand Down Expand Up @@ -718,10 +730,7 @@ def execute_command(self, text):
def run_cli(self):
logger = self.logger

history_file = self.config["main"]["history_file"]
if history_file == "default":
history_file = config_location() + "history"
history = FileHistory(os.path.expanduser(history_file))
history = FileHistory(os.path.expanduser(self.history_file))
self.refresh_completions(history=history, persist_priorities="none")

self.prompt_app = self._build_cli(history)
Expand Down Expand Up @@ -1194,6 +1203,7 @@ def echo_via_pager(self, text, color=None):
@click.option(
"--warn/--no-warn", default=None, help="Warn before running a destructive query."
)
@click.option("--histfile", default=None, help="Specify history file location.")
@click.argument("dbname", default=lambda: None, envvar="PGDATABASE", nargs=1)
@click.argument("username", default=lambda: None, envvar="PGUSER", nargs=1)
def cli(
Expand All @@ -1217,6 +1227,7 @@ def cli(
auto_vertical_output,
list_dsn,
warn,
histfile,
):
if version:
print("Version:", __version__)
Expand Down Expand Up @@ -1264,6 +1275,8 @@ def cli(
prompt_dsn=prompt_dsn,
auto_vertical_output=auto_vertical_output,
warn=warn,
histfile=histfile,
alias_dsn=dsn,
)

# Choose which ever one has a valid value.
Expand Down Expand Up @@ -1302,7 +1315,6 @@ def cli(
)
exit(1)
pgcli.connect_uri(dsn_config)
pgcli.dsn_alias = dsn
elif "://" in database:
pgcli.connect_uri(database)
elif "=" in database and service is None:
Expand Down
8 changes: 7 additions & 1 deletion pgcli/pgclirc
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ generate_casing_file = False
# Casing of column headers based on the casing_file described above
case_column_headers = True

# history_file location.
# default history_file location. You can also set history file location for
# specific database. see [dsn_history_file] section.
# In Unix/Linux: ~/.config/pgcli/history
# In Windows: %USERPROFILE%\AppData\Local\dbcli\pgcli\history
# %USERPROFILE% is typically C:\Users\{username}
Expand Down Expand Up @@ -187,6 +188,11 @@ output.null = "#808080"
[alias_dsn]
# example_dsn = postgresql://[user[:password]@][netloc][:port][/dbname]

# Specify sperate history file for alias_dsn.
# If not set, will use history_file settings.
[dsn_history_file]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can support mapping of history file to not only DSN aliases, but database names as well. That way, if you have mydb1 hosted on different servers, you could just configure:

[db_history_file]
mydb1 = ~/config/pgcli/history_mydb1

this could be useful to users that do not use DSN aliases.

There will be ambiguity if we do that: we'd have to figure out if mydb1 is a DSN alias or a database name. We can look for matching DSN alias first, if user provided --dsn when running the cli, and if there's no alias found, assume this is database name.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I like the idea that mapping of the history file for the database. I think it covers most of the use cases. Maybe consider alias_dsn is kind of overthinking and over-designed, I think we add too mush to configuration, and cloud leads to misunderstanding. I don't think users want to share history between databases. Even if they want to do that, they can use --histfile option.

Let's see, we only add a flag sperate_history_on_database_name = False, and add --histfile option. (Also, if user use \c[onnect] database_name, we should switch history file as well.

If the user does want to share history between database, they can:

  1. Use --histfile, maybe use shell's alias together.
  2. Save the most used query to named query.

What do you think?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that:

  • separating history per database does not need a config flag. Once that feature is in, we should do it by default. When you're connected to a specific database, queries from other databases are not very useful / relevant, and would only clutter history.
  • user can use --histfile to override the default history-file-per-database.
  • mapping to DSN vs database name can be useful. I had a use case with prod and beta database tables named table1_prod, table2_prod etc. Table structure was the same, but table names were different, so you could not use exactly the same query on those databases. This may be an edge case.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am convinced, I will only add a section named dsn_history_file section(maybe we cloud come up with a better name), and left other configs untouched.

So the process of choosing a history file will look like this:

image

Do I understand it correctly?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this looks exactly right.

# example_dsn = ~/.config/pgcli/example_dsn.history

# Format for number representation
# for decimal "d" - 12345678, ",d" - 12,345,678
# for float "g" - 123456.78, ",g" - 123,456.78
Expand Down