diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 259c4bc..c19dbd0 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -46,4 +46,4 @@ jobs: pip install mdformat-gfm - name: Markdown Style Check run: | - mdformat --number --wrap 80 --check README.md ARCHITECTURE.md + mdformat --number --wrap 100 --check README.md ARCHITECTURE.md diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index efde547..a43b3ec 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -5,13 +5,12 @@ The plugin is created from 2 parts: - Go backend that interacts with databases, - Lua frontend which wraps the backend with neat nvim integration. -These two parts should have clearly defined borders and not "leak" -responsibilities. +These two parts should have clearly defined borders and not "leak" responsibilities. ## Lua Architecture -The following diagram shows a high level overview of lua packages. Note that a -lot of connections are removed for diagram clarity. +The following diagram shows a high level overview of lua packages. Note that a lot of connections +are removed for diagram clarity. ``` ui @@ -41,24 +40,20 @@ lot of connections are removed for diagram clarity. Description: -- The "dbee" package consists of 2 major functional packages, ui and handler - (core). +- The "dbee" package consists of 2 major functional packages, ui and handler (core). - - `handler` or core package is a wrapper around the go backend handler. The - only extra thing lua handler does on top is information about sources. + - `handler` or core package is a wrapper around the go backend handler. The only extra thing lua + handler does on top is information about sources. - `ui` package consists of the following packages: - - `Drawer` represents the tree view. It uses the handler and editor to - provide the view of connections and notes. - - `Editor` represents the notepad view. It manages notes per namespace - (namespace is an arbitrary name - Drawer uses it to have connection-local - notes). + - `Drawer` represents the tree view. It uses the handler and editor to provide the view of + connections and notes. + - `Editor` represents the notepad view. It manages notes per namespace (namespace is an + arbitrary name - Drawer uses it to have connection-local notes). - `Result` represents the results view. - - `Call Log` represents the history of calls vie view and supports managing - past calls. + - `Call Log` represents the history of calls vie view and supports managing past calls. -- `install` package is independent of the other packages and is used for - installation of the compiled go binary using the manifest generated by the CI - pipeline. +- `install` package is independent of the other packages and is used for installation of the + compiled go binary using the manifest generated by the CI pipeline. - `sources` package holds an implementation of some of the most common sources. @@ -66,46 +61,41 @@ Description: ## Go Architecture -As We said, the Go backend is accessed exclusively through `handler` in lua. The -way the communication workd both ways is that lua can call the handler method -directly and go triggers events that lua then listens to. +As We said, the Go backend is accessed exclusively through `handler` in lua. The way the +communication workd both ways is that lua can call the handler method directly and go triggers +events that lua then listens to. -An example of this event based message passing is executing a query on -connection: +An example of this event based message passing is executing a query on connection: - lua registers an event listener to display results. - lua calls go execute method, which returns call details immediately. - lua then waits for call to yield some results, to display them. -One way of looking at the handler package in go is that it's just an -implementation specific use case of the `core` go package. +One way of looking at the handler package in go is that it's just an implementation specific use +case of the `core` go package. ### Core package -Here is the [godoc](https://pkg.go.dev/github.com/kndndrj/nvim-dbee/dbee/core) -of the core package. +Here is the [godoc](https://pkg.go.dev/github.com/kndndrj/nvim-dbee/dbee/core) of the core package. -Main construct is a `Connection`. It takes the parameters to connect to the -database and an adapter for the database. Adapter is a provider for specific -databases, which can return a database driver and returns common database -queries (helpers). +Main construct is a `Connection`. It takes the parameters to connect to the database and an adapter +for the database. Adapter is a provider for specific databases, which can return a database driver +and returns common database queries (helpers). -Then the connection can execute queries using a driver. This procudes a `Call`. -A call represents a single call to the database and holds it's state. +Then the connection can execute queries using a driver. This procudes a `Call`. A call represents a +single call to the database and holds it's state. -Database call returns a result, which transforms the iterator returned from -driver to different formats using a formatter. +Database call returns a result, which transforms the iterator returned from driver to different +formats using a formatter. #### Adapters package -One of the subpackages of core package is `adapters`. It contains implemetations -of multiple database drivers and adapters. One special thing it does is that it -has it's own method to create a connection. This is done so that individual -adapters can register themselves on startup in their init functions (so that we -can exclude some adapters on certain architectures/os-es). +One of the subpackages of core package is `adapters`. It contains implemetations of multiple +database drivers and adapters. One special thing it does is that it has it's own method to create a +connection. This is done so that individual adapters can register themselves on startup in their +init functions (so that we can exclude some adapters on certain architectures/os-es). #### Builders package -Another subpackage of `core`, which holds convenience functions for creating -some of the most used constructs. An example are multiple implementations of the -`ResultStream` interface. +Another subpackage of `core`, which holds convenience functions for creating some of the most used +constructs. An example are multiple implementations of the `ResultStream` interface. diff --git a/README.md b/README.md index 2fad49f..57c23f5 100644 --- a/README.md +++ b/README.md @@ -85,23 +85,21 @@ Click to expand -This project aims to be as cross-platform as possible, but there are some -limitations (for example some of the go dependencies only work on certain -platforms). To address this issue, the client implementations are detached from -the main logic and they register themselves to dbee backend on plugin start. -This allows the use of build constraints, which we use to exclued certain client +This project aims to be as cross-platform as possible, but there are some limitations (for example +some of the go dependencies only work on certain platforms). To address this issue, the client +implementations are detached from the main logic and they register themselves to dbee backend on +plugin start. This allows the use of build constraints, which we use to exclued certain client implementations on certain platforms. -The CI pipeline tries building the binary for GOARCH/GOOS combinations specified -in [targets.json](ci/targets.json) - if the builds succeed, they are stored in a -[remote bucket](https://github.com/kndndrj/nvim-dbee-bucket) on a separate -branch per run. Additionally, the -[install manifest](lua/dbee/install/__manifest.lua) gets created. +The CI pipeline tries building the binary for GOARCH/GOOS combinations specified in +[targets.json](ci/targets.json) - if the builds succeed, they are stored in a +[remote bucket](https://github.com/kndndrj/nvim-dbee-bucket) on a separate branch per run. +Additionally, the [install manifest](lua/dbee/install/__manifest.lua) gets created. To increase cgo cross-platform support, the pipeline uses zig as a C compiler. -To check if your platform is currently supported, check out the mentioned -manifest and the targets file. +To check if your platform is currently supported, check out the mentioned manifest and the targets +file. @@ -116,9 +114,9 @@ manifest and the targets file. Click to expand -The installation examples include the `build`/`run` functions, which get -triggered once the plugin updates. This should be sufficient for the majority of -users. If that doesn't include you, then you have a few options: +The installation examples include the `build`/`run` functions, which get triggered once the plugin +updates. This should be sufficient for the majority of users. If that doesn't include you, then you +have a few options: - just install with the `"go"` option (this performs `go build` under the hood): ```lua @@ -126,8 +124,7 @@ users. If that doesn't include you, then you have a few options: ``` - Download an already compiled binary from one of urls in the [install manifest](lua/dbee/install/__manifest.lua) -- `go install` (the install location will vary depending on your local go - configuration): +- `go install` (the install location will vary depending on your local go configuration): ```sh go install github.com/kndndrj/nvim-dbee/dbee@ ``` @@ -193,14 +190,12 @@ Here are a few steps to quickly get started: - call the `setup()` function in your `init.lua` -- Specify connections using one or more sources (reffer to - [this section](#specifying-connections)). +- Specify connections using one or more sources (reffer to [this section](#specifying-connections)). - When you restart the editor, call `lua require("dbee").open()` to open the UI. -- Navigate to the drawer (tree) and use the following key-bindings to perform - different actions depending on the context (the mappings can all be changed in - the config): +- Navigate to the drawer (tree) and use the following key-bindings to perform different actions + depending on the context (the mappings can all be changed in the config): - All nodes: @@ -210,49 +205,44 @@ Here are a few steps to quickly get started: - Connections: - Press `cw` to edit the connection - - Press `dd` to delete it (if source supports saving, it's also removed from - there - see more below.) - - Press `` to perform an action - view history or look at helper - queries. Pressing `` directly on the connection node will set it as - the active one + - Press `dd` to delete it (if source supports saving, it's also removed from there - see more + below.) + - Press `` to perform an action - view history or look at helper queries. Pressing `` + directly on the connection node will set it as the active one - Scratchpads: - Press `` on the `new` node to create a new scratchpad. - - When you try to save it to disk (`:w`), the path is automatically filled - for you. You can change the name to anything you want, if you save it to - the suggested directory, it will load the next time you open DBee. + - When you try to save it to disk (`:w`), the path is automatically filled for you. You can + change the name to anything you want, if you save it to the suggested directory, it will load + the next time you open DBee. - Press `cw` to rename the scratchpad. - Press `dd` to delete it (also from disk). - - Pressing `` on an existing scratchpad in the drawer will open it in - the editor pane. + - Pressing `` on an existing scratchpad in the drawer will open it in the editor pane. - Help: - Just view the key bindings. -- Once you selected the connection and created a scratchpad, you can navigate to - the editor pane (top-right by default) and start writing queries. In editor - pane, you can use the following actions: +- Once you selected the connection and created a scratchpad, you can navigate to the editor pane + (top-right by default) and start writing queries. In editor pane, you can use the following + actions: - - Highlight some text in visual mode and press `BB` - this will run the - selected query on the active connection. - - If you press `BB` in normal mode, you run the whole scratchpad on the active - connection. + - Highlight some text in visual mode and press `BB` - this will run the selected query on the + active connection. + - If you press `BB` in normal mode, you run the whole scratchpad on the active connection. -- If the request was successful, the results should appear in the "result" - buffer (bottom right by default). If the total number of results was lower - than the `page_size` parameter in config (100 by default), all results should - already be present. If there are more than `page_size` results, you can "page" - through them using one of the following: - -| Navigation using lua script
(even if your cursor is outside the result buffer) | Description | Default key mapping
(cursor should be inside result buffer) | -|---|:---:|:---:| -| `require("dbee").api.ui.result_page_next()` | Go to next page | L | -| `require("dbee").api.ui.result_page_prev()` | Go to the previous page | H | -| `require("dbee").api.ui.result_page_last()` | Go to the last page | E | -| `require("dbee").api.ui.result_page_first()` | Go to the first page | F | +- If the request was successful, the results should appear in the "result" buffer (bottom right by + default). If the total number of results was lower than the `page_size` parameter in config (100 + by default), all results should already be present. If there are more than `page_size` results, + you can "page" through them using one of the following: +| Navigation using lua script
(even if your cursor is outside the result buffer) | Description | Default key mapping
(cursor should be inside result buffer) | +| ------------------------------------------------------------------------------------ | :---------------------: | :---------------------------------------------------------------: | +| `require("dbee").api.ui.result_page_next()` | Go to next page | L | +| `require("dbee").api.ui.result_page_prev()` | Go to the previous page | H | +| `require("dbee").api.ui.result_page_last()` | Go to the last page | E | +| `require("dbee").api.ui.result_page_first()` | Go to the first page | F | - Once in the "result" buffer, you can yank the results with the following keys: @@ -261,9 +251,8 @@ Here are a few steps to quickly get started: - `yaJ` to yank all rows as json - `yaC` to yank all rows as CSV -- The current result (of the active connection) can also be saved to a file, - yank-register or buffer using `require("dbee").store()` lua function or - `:Dbee store` Ex command. Here are some examples: +- The current result (of the active connection) can also be saved to a file, yank-register or buffer + using `require("dbee").store()` lua function or `:Dbee store` Ex command. Here are some examples: ```lua -- All rows as CSV to current buffer: @@ -284,8 +273,8 @@ Here are a few steps to quickly get started: ### Specifying Connections -Connection represents an instance of the database client (i.e. one database). -This is how it looks like: +Connection represents an instance of the database client (i.e. one database). This is how it looks +like: ```lua { @@ -296,8 +285,8 @@ This is how it looks like: } ``` -The connections are loaded to dbee using so-called "sources". They can be added -to dbee using the `setup()` function: +The connections are loaded to dbee using so-called "sources". They can be added to dbee using the +`setup()` function: ```lua require("dbee").setup { @@ -321,8 +310,8 @@ The above sources are just built-ins. Here is a short description of them: - `MemorySource` just loads the connections you give it as an argument. -- `EnvSource` loads connection from an environment variable Just export the - variable you gave to the loader and you are good to go: +- `EnvSource` loads connection from an environment variable Just export the variable you gave to the + loader and you are good to go: ```sh export DBEE_CONNECTIONS='[ @@ -334,42 +323,37 @@ The above sources are just built-ins. Here is a short description of them: ]' ``` -- `FileSource` loads connections from a given json file. It also supports - editing and adding connections interactively +- `FileSource` loads connections from a given json file. It also supports editing and adding + connections interactively -If the source supports saving and editing you can add connections manually using -the "add" item in the drawer. Fill in the values and write the buffer (`:w`) to -save the connection. By default, this will save the connection to the global -connections file and will persist over restarts (because default `FileSource` -supports saving) +If the source supports saving and editing you can add connections manually using the "add" item in +the drawer. Fill in the values and write the buffer (`:w`) to save the connection. By default, this +will save the connection to the global connections file and will persist over restarts (because +default `FileSource` supports saving) -Another option is to use "edit" item in the tree and just edit the source -manually. +Another option is to use "edit" item in the tree and just edit the source manually. -If you aren't satisfied with the default capabilities, you can implement your -own source. You just need to fill the `Source` interface and pass it to config -at setup (`:h dbee.sources`). +If you aren't satisfied with the default capabilities, you can implement your own source. You just +need to fill the `Source` interface and pass it to config at setup (`:h dbee.sources`). #### Secrets -If you don't want to have secrets laying around your disk in plain text, you can -use the special placeholders in connection strings (this works using any method -for specifying connections). +If you don't want to have secrets laying around your disk in plain text, you can use the special +placeholders in connection strings (this works using any method for specifying connections). -Each connection parameter is passed through go templating engine, which has two -available functions: +Each connection parameter is passed through go templating engine, which has two available functions: - `env` for retrieving environment variables and - `exec` for evaluating shell commands. -The template syntax for functions is the following: `{{ "" }}`. If -you are dealing with json, you need to escape double quotes, so it's sometimes -better to use backticks instead (`` {{ `` }} ``). +The template syntax for functions is the following: `{{ "" }}`. If you are dealing +with json, you need to escape double quotes, so it's sometimes better to use backticks instead +(`` {{ `` }} ``). Example: -Using the `DBEE_CONNECTIONS` environment variable for specifying connections and -exporting secrets to environment: +Using the `DBEE_CONNECTIONS` environment variable for specifying connections and exporting secrets +to environment: ```sh # Define connections @@ -387,8 +371,7 @@ export SECRET_DB_USER="secretuser" export SECRET_DB_PASS="secretpass" ``` -If you start neovim in the same shell, this will evaluate to the following -connection: +If you start neovim in the same shell, this will evaluate to the following connection: ```lua { { @@ -414,18 +397,15 @@ require("dbee").api.ui.some_func() ## Projector Integration -DBee is compatible with my other plugin -[nvim-projector](https://github.com/kndndrj/nvim-projector), a -code-runner/project-configurator. +DBee is compatible with my other plugin [nvim-projector](https://github.com/kndndrj/nvim-projector), +a code-runner/project-configurator. -To use dbee with it, use -[this extension](https://github.com/kndndrj/projector-dbee). +To use dbee with it, use [this extension](https://github.com/kndndrj/projector-dbee). ## Development -Reffer to [ARCHITECTURE.md](ARCHITECTURE.md) for a brief overview of the -architecture. +Reffer to [ARCHITECTURE.md](ARCHITECTURE.md) for a brief overview of the architecture. diff --git a/lua/dbee/api/ui.lua b/lua/dbee/api/ui.lua index 440fcc3..3099a36 100644 --- a/lua/dbee/api/ui.lua +++ b/lua/dbee/api/ui.lua @@ -202,12 +202,12 @@ end --- Go to last page in results UI and display it. function ui.result_page_last() - entry.get_ui().result:page_last() + state.result():page_last() end --- Go to first page in results UI and display it. function ui.result_page_first() - entry.get_ui().result:page_first() + state.result():page_first() end --- Open the result UI.