Git Product home page Git Product logo

nvim-dbee's Introduction

Linting Status Docgen Status Backend Frontend

Neovim DBee

Database Client for NeoVim!

Execute Your Favourite Queries From the Comfort of Your Editor!

Backend in Go!

Frontend in Lua!

Get Results FAST With Under-the-hood Iterator!

Integrates with nvim-projector!

Bees Love It!

Alpha Software - Expect Breaking Changes!

Screenshot

Installation

  • packer.nvim:

    use {
      "kndndrj/nvim-dbee",
      requires = {
        "MunifTanjim/nui.nvim",
      },
      run = function()
        -- Install tries to automatically detect the install method.
        -- if it fails, try calling it with one of these parameters:
        --    "curl", "wget", "bitsadmin", "go"
        require("dbee").install()
      end,
      config = function()
        require("dbee").setup(--[[optional config]])
      end
    }
  • lazy.nvim:

    {
      "kndndrj/nvim-dbee",
      dependencies = {
        "MunifTanjim/nui.nvim",
      },
      build = function()
        -- Install tries to automatically detect the install method.
        -- if it fails, try calling it with one of these parameters:
        --    "curl", "wget", "bitsadmin", "go"
        require("dbee").install()
      end,
      config = function()
        require("dbee").setup(--[[optional config]])
      end,
    },

Platform Support

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 implementations on certain platforms.

The CI pipeline tries building the binary for GOARCH/GOOS combinations specified in targets.json - if the builds succeed, they are stored in a remote bucket on a separate branch per run. Additionally, the install manifest 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.

Manual Binary Installation

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:

  • just install with the "go" option (this performs go install under the hood):
    require("dbee").install("go")
  • Download an already compiled binary from one of urls in the install manifest
  • go install (the install location will vary depending on your local go configuration):
    go install github.com/kndndrj/nvim-dbee/dbee@<version>
  • Clone and build
    # Clone the repository and cd into the "go subfolder"
    git clone <this_repo>
    cd <this_repo>/dbee
    # Build the binary (optional output path)
    go build [-o ~/.local/share/nvim/dbee/bin/dbee]

Configuration

You can pass an optional table parameter to setup() function.

Here are the defaults:

config.lua

Usage

Call the setup() function with an optional config parameter. If you are not using your plugin manager to lazy load for you, make sure to specify { lazy = true } in the config.

Brief reference (click to expand):
-- Open/close the UI.
require("dbee").open()
require("dbee").close()
-- Next/previou page of the results (there are the same mappings that work just inside the results buffer
-- available in config).
require("dbee").next()
require("dbee").prev()
-- Run a query on the active connection directly.
require("dbee").execute(query)
-- Save the current result to file (format is either "csv" or "json" for now).
require("dbee").save(format, file)

Getting Started

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).

  • 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):

    • All nodes:

      • Press o to toggle the tree node.
      • Press r to manually refresh the tree.
    • 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 <CR> to perform an action - view history or look at helper queries. Pressing <CR> directly on the connection node will set it as the active one
    • Scratchpads:

      • Press <CR> 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.
      • Press cw to rename the scratchpad.
      • Press dd to delete it (also from disk).
      • Pressing <CR> 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:

    • 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 one 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" thrugh them using one of the following:

    • Using require("dbee").next() and require("dbee").prev() from anywhere (even if your cursor is outside the result buffer).
    • Using L for next and H for previous page if the cursor is located inside the results buffer.
  • The current result (of the active connection) can also be saved to a file using require("dbee").save() command. Use:

    • require("dbee").save("csv", "/path/to/file.csv") for csv and
    • require("dbee").save("json", "/path/to/file.json") for json.
  • Once you are done or you want to go back to where you were, you can call require("dbee").close().

Specifying Connections

Connection represents an instance of the database client (i.e. one database). This is how it looks like:

{
  id = "optional_identifier" -- only mandatory if you edit a file by hand. IT'S YOUR JOB TO KEEP THESE UNIQUE!
  name = "My Database",
  type = "sqlite", -- type of database driver
  url = "~/path/to/mydb.db",
}

The connections are loaded to dbee using so-called "sources". They can be added to dbee using the setup() function:

  require("dbee").setup {
    sources = {
      require("dbee.sources").MemorySource:new({
        {
          name = "...",
          type = "...",
          url = "...",
        },
        -- ...
      }),
      require("dbee.sources").EnvSource:new("DBEE_CONNECTIONS"),
      require("dbee.sources").FileSource:new(vim.fn.stdpath("cache") .. "/dbee/persistence.json"),
    },
    -- ...
  },
  -- ... the rest of your config
  }

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:

      export DBEE_CONNECTIONS='[
          {
              "name": "DB from env",
              "url": "mysql://...",
              "type": "mysql"
          }
      ]'
  • 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)

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 following interface and pass it to config at setup.

---@class Source
---@field name fun(self: Source):string function to return the name of the source
---@field load fun(self: Source):connection_details[] function to load connections from external source
---@field save? fun(self: Source, conns: connection_details[], action: "add"|"delete") function to save connections to external source (optional)
---@field file? fun(self: Source):string function which returns a source file to edit (optional)

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).

NOTE: Currently only envirnoment variables are supported

Example:

Using the DBEE_CONNECTIONS environment variable for specifying connections and exporting secrets to environment:

# Define connections
export DBEE_CONNECTIONS='[
    {
        "name": "{{ env.SECRET_DB_NAME }}",
        "url": "postgres://{{ env.SECRET_DB_USER }}:{{ env.SECRET_DB_PASS }}@localhost:5432/{{ env.SECRET_DB_NAME }}?sslmode=disable",
        "type": "postgres"
    }
]'

# Export secrets
export SECRET_DB_NAME="secretdb"
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:

{ {
  name = "secretdb",
  url = "postgres://secretuser:secretpass@localhost:5432/secretdb?sslmode=disable",
  type = "postgres",
} }

Projector Integration

DBee is compatible with my other plugin nvim-projector, a code-runner/project-configurator.

To use dbee with it, simply use "dbee" as one of it's outputs.

Development

Reffer to ARCHITECTURE.md for a brief overview of the architecture.

nvim-dbee's People

Contributors

33kk avatar actions-user avatar dabbertorres avatar kndndrj avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.