Documentation
¶
Overview ¶
Package sqlcomplete suggests what to type next in a SQL buffer: the columns, tables and join conditions the connection's schema holds, and the dialect's keywords, functions and types. Both UIs ask it — the TUI's editor popup and dbc web's Monaco suggest widget — so the rules for what is offered where exist once, in Go, rather than as a JavaScript copy that would drift from the terminal's.
How a request is answered ¶
buffer + caret ─► the statement under the caret (sqlsplit, the run's splitter)
│
├─► tokens (sqlsplit.Lex for strings/comments/quoted names)
│
├─► scope: FROM/JOIN/UPDATE/INTO refs and their aliases,
│ CTEs with the columns their SELECT lists name
│
└─► context: what the token before the caret asks for
│
┌──────────┬────────┴──────┬────────────┬──────────┐
start tables expression qualified clause …
(SELECT…) (FROM ▮) (WHERE ▮, =▮) (o.▮) (FROM t ▮)
│
candidates ─► filtered by the typed prefix ─► ranked ─► capped
Lexical, not a parse ¶
Like the splitter and the highlighter this is a scanner with a few rules, not a SQL grammar. It knows which keyword precedes the caret and which tables the statement names; it does not know that a subquery's columns are out of scope outside it. Every table the statement names is therefore in scope everywhere in it. Offering a column one subquery too early costs a line in a list; a grammar for four dialects would cost far more and still fail on the half-typed statement a completion request always sees.
Offsets ¶
Every offset in and out is a byte offset into the buffer. dbc web converts to and from the UTF-16 units the browser counts (web/api.go byteOffset), the TUI from its rune positions.
Index ¶
Constants ¶
const MaxItems = 400
MaxItems caps a result. A catalog of thousands of columns answered in full would be a long list nobody scrolls and a large response per keystroke; the first few hundred, best first, are the useful ones, and Incomplete tells the client to ask again as the prefix narrows it.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Item ¶
type Item struct {
Label string `json:"label"` // what the list shows
Kind Kind `json:"kind"` // see Kind
Detail string `json:"detail,omitempty"` // one line beside the label: a type, a signature
Doc string `json:"doc,omitempty"` // longer text: a table's DDL, a function's description
Insert string `json:"insert"` // what replaces [From, To) when picked
// Filter is the text the typed prefix is matched against when it is
// not the label — a column offered qualified ("o.id") still matches
// "id". Empty means the label.
Filter string `json:"filter,omitempty"`
// Cursor is where the caret lands inside Insert after the pick, as a
// byte offset into Insert; -1 means after it. A function lands
// between its parentheses.
Cursor int `json:"cursor"`
Sort string `json:"sort"` // ascending sort key; the order Items is already in
}
Item is one suggestion.
type Kind ¶
type Kind string
Kind classifies a suggestion, for its icon and its place in the order.
const ( KindColumn Kind = "column" KindTable Kind = "table" KindView Kind = "view" KindSchema Kind = "schema" KindAlias Kind = "alias" // a table reference's alias, or a CTE KindJoin Kind = "join" // a whole join clause or ON condition from a foreign key KindKeyword Kind = "keyword" KindFunction Kind = "function" KindType Kind = "type" )
type Request ¶
type Request struct {
// Schema is the connection's tables, columns and keys (the ERD's
// reading of the catalog); nil offers only the dialect's vocabulary.
Schema *erd.Schema
// Driver is the connection's driver as configured (postgres, pg,
// mysql, sqlite, bytdb …), for the dialect's vocabulary and quoting.
Driver string
// Focus is the schema the user is browsing (the sidebar's), whose
// tables are ranked first; "" when there is none.
Focus string
// SearchPath is the schemas a bare table name resolves through, in
// order (Postgres's current_schemas); nil means the dialect's default
// (public on Postgres and bytdb). A table in one of them is inserted
// bare unless a schema earlier on the path has a table of that name.
SearchPath []string
// Buffer is the whole editor text and Caret a byte offset into it.
Buffer string
Caret int
}
Request is one completion request.
type Result ¶
type Result struct {
From, To int // the byte range a picked item replaces: the word being typed
Prefix string // buffer[From:To], what was matched against
Items []Item
// Incomplete reports that Items was cut at MaxItems: a longer prefix
// may surface items not listed now, so a client should ask again as
// the prefix grows rather than filter this list itself.
Incomplete bool
}
Result is the answer to a request.