Package tblfmt writes result sets as text tables. A result set is the rows
and columns that a database query returns. tblfmt reads a result set one row
at a time, so it does not keep the whole result in memory. It writes tables
like this one:
author_id | name | z
-----------+-----------------------+---
14 | a b c d |
15 | aoeu +|
| test +|
| |
16 | foo\bbar |
17 | a b \r +|
| a |
18 | 袈 袈 袈 |
19 | 袈 袈 袈+| a+
| |
(6 rows)
tblfmt also has encoders for JSON, CSV, HTML, AsciiDoc, unaligned text and
the other formats that usql supports.
Install tblfmt with the Go tool:
$ go get -u github.com/xo/tblfmttblfmt is for usql and for the database/sql types of Go. It
accepts any type that has this interface:
// ResultSet is the shared interface for a result set.
type ResultSet interface {
Next() bool
Scan(...interface{}) error
Columns() ([]string, error)
Close() error
Err() error
NextResultSet() bool
}This program uses tblfmt:
// _example/example.go
package main
import (
"log"
"os"
_ "github.com/lib/pq"
"github.com/xo/dburl"
"github.com/xo/tblfmt"
)
func main() {
db, err := dburl.Open("postgres://booktest:booktest@localhost")
if err != nil {
log.Fatal(err)
}
defer db.Close()
res, err := db.Query("select * from authors")
if err != nil {
log.Fatal(err)
}
defer res.Close()
enc, err := tblfmt.NewTableEncoder(
res,
// force minimum column widths
tblfmt.WithWidths(20, 20),
)
if err = enc.EncodeAll(os.Stdout); err != nil {
log.Fatal(err)
}
}The program writes output like this:
╔══════════════════════╦═══════════════════════════╦═══╗
║ author_id ║ name ║ z ║
╠══════════════════════╬═══════════════════════════╬═══╣
║ 14 ║ a b c d ║ ║
║ 15 ║ aoeu ↵║ ║
║ ║ test ↵║ ║
║ ║ ║ ║
║ 2 ║ 袈 袈 袈 ║ ║
╚══════════════════════╩═══════════════════════════╩═══╝
(3 rows)
The Go Reference has the full API.
tblfmt writes the same output as psql. The differences below are
deliberate. If you find a different difference, report it as a bug.
tblfmt pads the last column of a table that has a border, so that every
line of the table has the same width. psql pads the header, but it does not
pad the data rows. As a result, the right edge of a psql table is not
straight.
For select 42 as n, 'a'::text as t union all select 7, 'bb';, with trailing
spaces written as · and the width of each line at the right:
psql 18.6 tblfmt
n | t · 9 n | t · 9
----+---- 9 ----+---- 9
42 | a 7 42 | a · 9
7 | bb 8 7 | bb · 9
tblfmt does not follow psql here, for these reasons:
- A table that has lines of different widths is difficult to select in a
terminal, to compare with
diff, and to lay out in a program that measures the block. - The uneven edge gives no information.
psqlpads its own header, so the data rows do not agree with it.
See D28 in docs/PLAN.md. For a left aligned last column, the code does not match this section yet. See open question 1 there.
| Document | What it holds |
|---|---|
| CONTRIBUTING.md | What a change must do, and the commands to run before a pull request |
| docs/PLAN.md | Each decision that shapes tblfmt, and the reason for it |
| docs/BACKLOG.md | Known faults and work that is not done |
| AGENTS.md | The rules for a coding agent. CLAUDE.md imports it |
Run the tests with go test:
$ go test -v