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.
The following diagram shows a high level overview of lua packages. Note that a lot of connections are removed for diagram clarity.
ui
┌──────────┐
┌─────►│ Result ├──────┐
│ └──────────┘ │
│ │
│ ┌──────────┐ │
├─────►│ Editor ├──────┤ core
┌──────────┐ ┌──────────┐ │ └──────────┘ │ ┌──────────┐
│ API ├──►│ entry ├──┤ ├────►│ Handler ├───► Go
└──────────┘ └──────────┘ │ ┌──────────┐ │ └──────────┘
├─────►│ Drawer ├──────┤
│ └──────────┘ │
│ │
│ ┌──────────┐ │
└─────►│ Call Log ├──────┘
└──────────┘
┌──────────┐ ┌──────────┐
│ sources │ │ layouts │
└──────────┘ └──────────┘
┌──────────┐
│ install │
└──────────┘
Description:
-
The "dbee" package consists of 2 major functional packages, ui and handler (core).
handleror core package is a wrapper around the go backend handler. The only extra thing lua handler does on top is information about sources.uipackage consists of the following packages:Drawerrepresents the tree view. It uses the handler and editor to provide the view of connections and notes.Editorrepresents the notepad view. It manages notes per namespace (namespace is an arbitrary name - Drawer uses it to have connection-local notes).Resultrepresents the results view.Call Logrepresents the history of calls vie view and supports managing past calls.
-
installpackage is independent of the other packages and is used for installation of the compiled go binary using the manifest generated by the CI pipeline. -
sourcespackage holds an implementation of some of the most common sources. -
layoutspackage holds the implementation of the default window layout.
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:
- 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.
Here is the godoc 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).
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.
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).
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.