format

package
v0.27.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 1, 2026 License: Apache-2.0 Imports: 25 Imported by: 0

Documentation

Overview

Package format implements SQL export formatting for query results. It generates INSERT, INSERT OR IGNORE, and INSERT OR UPDATE statements that can be used for database migration, backup/restore, and test data generation.

Current Design Constraints: - Values are expected to be pre-formatted as SQL literals using spanvalue.LiteralFormatConfig - The formatter receives []string (Row) rather than raw *spanner.Row data - Format decision is made early in execute_sql.go, not at formatting time

Future Improvements: - Consider passing raw *spanner.Row to formatters for late-binding format decisions - This would allow formatters to choose appropriate FormatConfig based on their needs - Would enable format-specific optimizations and better separation of concerns

The implementation uses memefish's ast.Path for correct identifier handling.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CalculateWidth

func CalculateWidth(columnNames []string, verboseHeaders []string, wc *widthCalculator, screenWidth int, rows []Row) []int

CalculateWidth calculates optimal column widths for table rendering. columnNames are the plain column names, verboseHeaders are optionally the verbose header strings (with type info, may contain newlines). Both are used for width calculation.

func ExecuteWithFormatter

func ExecuteWithFormatter(formatter StreamingFormatter, rows []Row, columnNames []string, config FormatConfig) error

ExecuteWithFormatter executes buffered formatting using a streaming formatter. This reduces duplication in formatCSV, formatTab, formatVertical, etc.

func ExtractTableNameFromQuery

func ExtractTableNameFromQuery(sql string) (string, error)

ExtractTableNameFromQuery attempts to extract a table name from a simple SELECT query. It supports simple SELECT patterns including:

  • SELECT * FROM table_name
  • SELECT columns FROM table_name
  • SELECT * FROM table_name WHERE ...
  • SELECT * FROM table_name ORDER BY ...
  • SELECT * FROM table_name LIMIT ...
  • SELECT DISTINCT columns FROM table_name (DISTINCT is allowed since Spanner tables always have PKs)
  • Combinations of the above

NOT supported:

  • GROUP BY / HAVING (aggregations change the result set structure)
  • JOINs (combine multiple tables)
  • Subqueries, CTEs, UNIONs (complex structures)

Note: DISTINCT is allowed because Spanner tables always have primary keys, making SELECT * results inherently unique. DISTINCT on unique results is a no-op.

Returns:

  • (tableName, nil) when extraction succeeds
  • ("", error) when extraction fails with a reason

The error messages are intended for debug logging to help understand why auto-detection failed, allowing users to adjust their queries or use explicit CLI_SQL_TABLE_NAME setting.

func MaxByWithIdx

func MaxByWithIdx[O cmp.Ordered, E any](fallback E, f func(E) O, seq iter.Seq[E]) (int, E)

MaxByWithIdx returns the index and value of the element with the maximum key.

func MaxWithIdx

func MaxWithIdx[E cmp.Ordered](fallback E, seq iter.Seq[E]) (int, E)

MaxWithIdx returns the index and value of the maximum element in seq.

func ParseSimpleTablePath

func ParseSimpleTablePath(input string) (*ast.Path, error)

ParseSimpleTablePath converts a simple table path string from CLI input to an ast.Path. This function handles user-friendly input where reserved words don't need quoting. Examples: "Users", "Order" (reserved word OK), "myschema.Users" The function does NOT parse SQL expressions - it simply splits on dots. Quoting for reserved words is handled automatically by ast.Ident.SQL() during output.

func WriteTable

func WriteTable(w io.Writer, rows []Row, columnNames []string, config FormatConfig, screenWidth int, mode enums.DisplayMode) error

WriteTable writes the table to the provided writer. verboseNames and columnAlign are passed separately because they are specific to table formatting and not available in the generic FormatConfig.

func WriteTableWithParams

func WriteTableWithParams(w io.Writer, rows []Row, columnNames []string, config FormatConfig, screenWidth int, mode enums.DisplayMode, params TableParams) error

WriteTableWithParams writes the table with additional table-specific parameters.

Types

type CSVFormatter

type CSVFormatter struct {
	// contains filtered or unexported fields
}

CSVFormatter provides shared CSV formatting logic for both buffered and streaming modes.

func NewCSVFormatter

func NewCSVFormatter(out io.Writer, skipHeaders bool) *CSVFormatter

NewCSVFormatter creates a new CSV formatter.

func (*CSVFormatter) FinishFormat

func (f *CSVFormatter) FinishFormat() error

FinishFormat completes CSV output.

func (*CSVFormatter) InitFormat

func (f *CSVFormatter) InitFormat(columnNames []string, config FormatConfig, previewRows []Row) error

InitFormat writes CSV headers if needed.

func (*CSVFormatter) WriteRow

func (f *CSVFormatter) WriteRow(row Row) error

WriteRow writes a single CSV row.

type FormatConfig

type FormatConfig struct {
	TabWidth        int
	Verbose         bool
	SkipColumnNames bool
	SQLTableName    string
	SQLBatchSize    int64
	PreviewRows     int64
}

FormatConfig holds configuration values needed by formatters. This replaces the dependency on *systemVariables, exposing only the fields that formatters actually use.

type FormatFunc

type FormatFunc func(out io.Writer, rows []Row, columnNames []string, config FormatConfig, screenWidth int) error

FormatFunc is a function type that formats and writes result data. It takes an output writer, rows, column names, config, and screen width.

func FormatSQL

func FormatSQL(mode enums.DisplayMode) FormatFunc

FormatSQL is the non-streaming formatter for SQL export.

func NewFormatter

func NewFormatter(mode enums.DisplayMode) (FormatFunc, error)

NewFormatter creates a new formatter function based on the display mode.

type HTMLFormatter

type HTMLFormatter struct {
	// contains filtered or unexported fields
}

HTMLFormatter provides streaming HTML table output.

func NewHTMLFormatter

func NewHTMLFormatter(out io.Writer, skipHeaders bool) *HTMLFormatter

NewHTMLFormatter creates a new HTML streaming formatter.

func (*HTMLFormatter) FinishFormat

func (f *HTMLFormatter) FinishFormat() error

FinishFormat completes the HTML table.

func (*HTMLFormatter) InitFormat

func (f *HTMLFormatter) InitFormat(columnNames []string, config FormatConfig, previewRows []Row) error

InitFormat writes the HTML table opening and headers.

func (*HTMLFormatter) WriteRow

func (f *HTMLFormatter) WriteRow(row Row) error

WriteRow writes a single HTML table row.

type Row

type Row = []string

Row is a type alias for a row of string values. Using a type alias (not a new type) ensures zero breaking change at call sites.

type SQLFormatter

type SQLFormatter struct {
	// contains filtered or unexported fields
}

SQLFormatter handles SQL export formatting for different INSERT variants. It supports both single-row and multi-row INSERT statements based on batchSize. The formatter buffers rows when batchSize > 1 to generate multi-row INSERTs.

func NewSQLFormatter

func NewSQLFormatter(out io.Writer, mode enums.DisplayMode, tableName string, batchSize int64) (*SQLFormatter, error)

NewSQLFormatter creates a new SQL formatter for streaming output.

func (*SQLFormatter) Finish

func (f *SQLFormatter) Finish() error

Finish flushes any remaining rows.

func (*SQLFormatter) WriteHeader

func (f *SQLFormatter) WriteHeader(columnNames []string) error

WriteHeader sets up column names for the formatter.

func (*SQLFormatter) WriteRow

func (f *SQLFormatter) WriteRow(values []string) error

WriteRow processes a single row and outputs SQL when batch is full.

type SQLStreamingFormatter

type SQLStreamingFormatter struct {
	// contains filtered or unexported fields
}

SQLStreamingFormatter implements StreamingFormatter for SQL export.

func NewSQLStreamingFormatter

func NewSQLStreamingFormatter(out io.Writer, config FormatConfig, mode enums.DisplayMode) (*SQLStreamingFormatter, error)

NewSQLStreamingFormatter creates a new streaming SQL formatter.

func (*SQLStreamingFormatter) FinishFormat

func (s *SQLStreamingFormatter) FinishFormat() error

FinishFormat completes the SQL export.

func (*SQLStreamingFormatter) InitFormat

func (s *SQLStreamingFormatter) InitFormat(columnNames []string, config FormatConfig, previewRows []Row) error

InitFormat initializes the formatter with column information.

func (*SQLStreamingFormatter) WriteRow

func (s *SQLStreamingFormatter) WriteRow(row Row) error

WriteRow outputs a single row.

type StreamingFormatter

type StreamingFormatter interface {
	// InitFormat is called once with column names and configuration.
	// For table formats, previewRows contains the first N rows for width calculation.
	// For other formats, previewRows may be empty as they don't need preview.
	InitFormat(columnNames []string, config FormatConfig, previewRows []Row) error

	// WriteRow outputs a single row.
	WriteRow(row Row) error

	// FinishFormat completes the output (e.g., closing tags, final flush).
	FinishFormat() error
}

StreamingFormatter defines the interface for format-specific streaming output. Each format (CSV, TAB, etc.) implements this interface to handle streaming output.

func NewStreamingFormatter

func NewStreamingFormatter(mode enums.DisplayMode, out io.Writer, config FormatConfig) (StreamingFormatter, error)

NewStreamingFormatter creates a streaming formatter for the given display mode. Note: Table formats (Table, TableComment, TableDetailComment) require screenWidth and should be created with NewTableStreamingFormatter directly by the caller.

type TabFormatter

type TabFormatter struct {
	// contains filtered or unexported fields
}

TabFormatter provides shared tab-separated formatting logic.

func NewTabFormatter

func NewTabFormatter(out io.Writer, skipHeaders bool) *TabFormatter

NewTabFormatter creates a new tab-separated formatter.

func (*TabFormatter) FinishFormat

func (f *TabFormatter) FinishFormat() error

FinishFormat completes tab-separated output.

func (*TabFormatter) InitFormat

func (f *TabFormatter) InitFormat(columnNames []string, config FormatConfig, previewRows []Row) error

InitFormat writes tab-separated headers if needed.

func (*TabFormatter) WriteRow

func (f *TabFormatter) WriteRow(row Row) error

WriteRow writes a single tab-separated row.

type TableParams

type TableParams struct {
	// VerboseHeaders contains header strings rendered with type information.
	// These may include newlines (e.g., "Name\nSTRING") and are used for display
	// when Verbose mode is enabled.
	VerboseHeaders []string
	ColumnAlign    []tw.Align
}

TableParams holds additional parameters for table formatting that are not part of the standard FormatConfig (used only by table format).

type TableStreamingFormatter

type TableStreamingFormatter struct {
	// contains filtered or unexported fields
}

TableStreamingFormatter provides streaming table output using tablewriter v1.0.9. It uses a configurable number of preview rows to calculate optimal column widths.

func NewTableStreamingFormatter

func NewTableStreamingFormatter(out io.Writer, config FormatConfig, screenWidth int, previewSize int) *TableStreamingFormatter

NewTableStreamingFormatter creates a new table streaming formatter. previewSize determines how many rows to use for width calculation (0 = all rows).

func (*TableStreamingFormatter) FinishFormat

func (f *TableStreamingFormatter) FinishFormat() error

FinishFormat completes the table output.

func (*TableStreamingFormatter) InitFormat

func (f *TableStreamingFormatter) InitFormat(columnNames []string, config FormatConfig, previewRows []Row) error

InitFormat initializes the table with preview rows for width calculation.

func (*TableStreamingFormatter) WriteRow

func (f *TableStreamingFormatter) WriteRow(row Row) error

WriteRow writes a single table row.

type VerticalFormatter

type VerticalFormatter struct {
	// contains filtered or unexported fields
}

VerticalFormatter provides shared vertical formatting logic.

func NewVerticalFormatter

func NewVerticalFormatter(out io.Writer) *VerticalFormatter

NewVerticalFormatter creates a new vertical formatter.

func (*VerticalFormatter) FinishFormat

func (f *VerticalFormatter) FinishFormat() error

FinishFormat completes vertical format output.

func (*VerticalFormatter) InitFormat

func (f *VerticalFormatter) InitFormat(columnNames []string, config FormatConfig, previewRows []Row) error

InitFormat prepares vertical format output.

func (*VerticalFormatter) WriteRow

func (f *VerticalFormatter) WriteRow(row Row) error

WriteRow writes a single row in vertical format.

type WidthCount

type WidthCount struct {
	// contains filtered or unexported fields
}

WidthCount tracks the width and frequency of column values.

func (WidthCount) Count

func (wc WidthCount) Count() int

Count returns the frequency count.

func (WidthCount) Length

func (wc WidthCount) Length() int

Length returns the width value.

type XMLFormatter

type XMLFormatter struct {
	// contains filtered or unexported fields
}

XMLFormatter provides streaming XML output.

func NewXMLFormatter

func NewXMLFormatter(out io.Writer, skipHeaders bool) *XMLFormatter

NewXMLFormatter creates a new XML streaming formatter.

func (*XMLFormatter) FinishFormat

func (f *XMLFormatter) FinishFormat() error

FinishFormat completes the XML output.

func (*XMLFormatter) InitFormat

func (f *XMLFormatter) InitFormat(columnNames []string, config FormatConfig, previewRows []Row) error

InitFormat writes the XML declaration and starts the result set.

func (*XMLFormatter) WriteRow

func (f *XMLFormatter) WriteRow(row Row) error

WriteRow writes a single XML row.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL