Documentation
¶
Overview ¶
Package writer provides small streaming helpers for exporting Spanner rows using spanvalue formatters.
DelimitedWriter is the primary writer for CSV-style delimited text. NewCSVWriter is a thin helper for the common comma-delimited CSV case, while NewDelimitedWriter accepts an explicit delimiter for TSV and other delimited output. DelimitedWriter and JSONLWriter preserve explicit duplicate column names. Their UnnamedFieldNamer only fills empty column names, and generated names avoid collisions with existing names. DelimitedWriter buffers through encoding/csv, so callers must call Flush after the final write.
Writer streams *spanner.Row values; concrete writers also offer WriteValues, WriteGCVs, and WriteStructValues. FlushWriter adds Flush (required for buffered DelimitedWriter). Flush does not close the underlying io.Writer.
Constructors ¶
NewDelimitedWriter, NewCSVWriter, NewJSONLWriter, and NewSQLInsertWriter accept WithFormatter and schema options below. WithSQLInsertKind selects the INSERT prefix (see Spanner INSERT DML syntax). RowData, FormatDelimitedRow, and FormatJSONLRow format a single row without a writer.
Column names and field types ¶
Each write API either supplies schema on every call or expects it in the writer:
- WriteRow, WriteValues: column names and GCV types per call; no registration.
- WriteGCVs: register column names before the first row; types from each GCV.
- WriteStructValues: register column names and field types before the first row.
Pre-register at construction with With* or later with Prepare* on the concrete writer. Names only: WithColumnNames, PrepareColumnNames. Names and types: WithRowType, WithMetadata, PrepareRowType. WithMetadata uses metadata.GetRowType(); from a cloud.google.com/go/spanner.RowIterator, Metadata is set after the first Next. The first [WriteRow] or [WriteValues] call can also register column names from a row. DelimitedWriter.Prepare, JSONLWriter.Prepare, and SQLInsertWriter.Prepare are deprecated.
Registered schema vs missing schema ¶
Writers distinguish schema that was never registered from a registered schema with zero column names (len(names) == 0):
- Not registered: no Prepare*, With*, or row has supplied names yet. DelimitedWriter.WriteHeader, DelimitedWriter.Flush (with WithHeader(true)), and DelimitedWriter.WriteGCVs without prior registration return ErrMissingColumnNames.
- Registered empty: [PrepareRowType] or WithRowType with a nil row type or a row type whose fields slice is empty (for example DML without THEN RETURN: zero rows and zero columns). DelimitedWriter.Flush succeeds and writes no output; DelimitedWriter.WriteHeader is a no-op because there are no column names. A later [WriteRow] still initializes names from the row if one arrives.
- [PrepareColumnNames] with an empty name list returns ErrMissingColumnNames.
- WithColumnNames with an empty name list is ignored at construction (the writer stays unregistered); it does not return an error because options cannot report one. For a zero-column result set, use [PrepareRowType] or WithRowType instead (for example after iter.Metadata.GetRowType() on DML without THEN RETURN).
DelimitedWriter defaults to a CSV/TSV header once column names are known (WithHeader): before the first data row, or on DelimitedWriter.Flush when no data row was written (including zero-row SELECT when names were registered). WithHeader(false) omits the header. DelimitedWriter.WriteHeader forces the header earlier.
Delimited, JSONL, and SQL encodings differ after spanvalue formats each column.
Compatibility constructors ¶
NewDelimitedWriterWithOptions, NewJSONLWriterWithOptions, and NewSQLInsertWriterWithOptions forward to the primary constructors above.
Index ¶
- Constants
- Variables
- func FormatDelimitedRow(fc *spanvalue.FormatConfig, row *spanner.Row, delimiter rune) (string, error)
- func FormatDelimitedValues(fc *spanvalue.FormatConfig, columnNames []string, ...) (string, error)
- func FormatJSONLRow(fc *spanvalue.FormatConfig, row *spanner.Row, ...) (string, error)
- func FormatJSONLValues(fc *spanvalue.FormatConfig, columnNames []string, ...) (string, error)
- func RowData(row *spanner.Row) ([]string, []spanner.GenericColumnValue, error)
- type DelimitedOption
- type DelimitedWriter
- func (w *DelimitedWriter) Flush() error
- func (w *DelimitedWriter) Prepare(metadata *sppb.ResultSetMetadata) errordeprecated
- func (w *DelimitedWriter) PrepareColumnNames(names []string) error
- func (w *DelimitedWriter) PrepareRowType(rowType *sppb.StructType) error
- func (w *DelimitedWriter) WriteGCVs(values []spanner.GenericColumnValue) error
- func (w *DelimitedWriter) WriteHeader() error
- func (w *DelimitedWriter) WriteRow(row *spanner.Row) error
- func (w *DelimitedWriter) WriteStructValues(values []*structpb.Value) error
- func (w *DelimitedWriter) WriteValues(columnNames []string, values []spanner.GenericColumnValue) error
- type FlushWriter
- type Flusher
- type JSONLOption
- type JSONLWriter
- func (w *JSONLWriter) Flush() error
- func (w *JSONLWriter) Prepare(metadata *sppb.ResultSetMetadata) errordeprecated
- func (w *JSONLWriter) PrepareColumnNames(names []string) error
- func (w *JSONLWriter) PrepareRowType(rowType *sppb.StructType) error
- func (w *JSONLWriter) WriteGCVs(values []spanner.GenericColumnValue) error
- func (w *JSONLWriter) WriteRow(row *spanner.Row) error
- func (w *JSONLWriter) WriteStructValues(values []*structpb.Value) error
- func (w *JSONLWriter) WriteValues(columnNames []string, values []spanner.GenericColumnValue) error
- type NameOption
- type Option
- type SQLInsertKind
- type SQLInsertOption
- type SQLInsertWriter
- func (w *SQLInsertWriter) Flush() error
- func (w *SQLInsertWriter) Prepare(metadata *sppb.ResultSetMetadata) errordeprecated
- func (w *SQLInsertWriter) PrepareColumnNames(names []string) error
- func (w *SQLInsertWriter) PrepareRowType(rowType *sppb.StructType) error
- func (w *SQLInsertWriter) WriteGCVs(values []spanner.GenericColumnValue) error
- func (w *SQLInsertWriter) WriteRow(row *spanner.Row) error
- func (w *SQLInsertWriter) WriteStructValues(values []*structpb.Value) error
- func (w *SQLInsertWriter) WriteValues(columnNames []string, values []spanner.GenericColumnValue) error
- type Writer
Constants ¶
const ( // Comma is the standard CSV field delimiter. Pass Comma to // NewDelimitedWriter for CSV output. Comma rune = ',' )
Variables ¶
var ( // ErrEmptyTableName reports that SQLInsertWriter.Table is empty. ErrEmptyTableName = errors.New("empty table name") // ErrEmptyColumnName reports that a SQL writer received an empty column name. ErrEmptyColumnName = errors.New("empty column name") // ErrNilOutputWriter reports that a writer was constructed without an output. ErrNilOutputWriter = errors.New("nil output writer") // ErrNilRow reports that WriteRow was called with a nil row. ErrNilRow = spanvalue.ErrNilRow // ErrMissingColumnNames reports that an operation requires a registered column schema // when none was registered yet, or column names/types are insufficient for the write // (for example values without names). It is not returned for a registered zero-column // schema (see package doc "Registered schema vs missing schema"). [PrepareColumnNames] // with an empty name list returns this error; [WithColumnNames] with an empty list is // ignored (writer stays unregistered). Use [PrepareRowType] for zero-column result sets. ErrMissingColumnNames = errors.New("missing column names") // ErrColumnNamesMismatch reports that provided column names differ from initialized schema. ErrColumnNamesMismatch = errors.New("column names mismatch") // ErrHeaderAfterData reports that DelimitedWriter.WriteHeader was called after data rows were emitted. ErrHeaderAfterData = errors.New("header after data") // ErrInvalidDelimiter reports that DelimitedWriter received an invalid delimiter. ErrInvalidDelimiter = errors.New("invalid delimiter") // ErrMissingFieldTypes reports that WriteStructValues requires registered field types. ErrMissingFieldTypes = errors.New("missing field types schema") // ErrMismatchedStructValueCount reports that WriteStructValues value count does not match the schema. ErrMismatchedStructValueCount = errors.New("mismatched struct value count") )
Functions ¶
func FormatDelimitedRow ¶ added in v0.3.2
func FormatDelimitedRow(fc *spanvalue.FormatConfig, row *spanner.Row, delimiter rune) (string, error)
FormatDelimitedRow formats one row as a CSV-style delimited record without a trailing newline. Pass Comma for CSV output.
func FormatDelimitedValues ¶ added in v0.3.2
func FormatDelimitedValues(fc *spanvalue.FormatConfig, columnNames []string, values []spanner.GenericColumnValue, delimiter rune) (string, error)
FormatDelimitedValues formats one row represented as column names plus GCV values as a CSV-style delimited record without a trailing newline. Pass Comma for CSV output.
func FormatJSONLRow ¶ added in v0.3.2
func FormatJSONLRow(fc *spanvalue.FormatConfig, row *spanner.Row, namer spanvalue.UnnamedFieldNamer) (string, error)
FormatJSONLRow formats one row as a JSON object string without a trailing newline. Callers writing JSONL streams should add the newline at the stream boundary.
func FormatJSONLValues ¶ added in v0.3.2
func FormatJSONLValues(fc *spanvalue.FormatConfig, columnNames []string, values []spanner.GenericColumnValue, namer spanvalue.UnnamedFieldNamer) (string, error)
FormatJSONLValues formats one row represented as column names plus GCV values as a JSON object string without a trailing newline. Callers writing JSONL streams should add the newline at the stream boundary.
Types ¶
type DelimitedOption ¶ added in v0.3.2
type DelimitedOption interface {
// contains filtered or unexported methods
}
DelimitedOption configures a DelimitedWriter created by NewDelimitedWriter or NewCSVWriter.
func WithHeader ¶ added in v0.3.2
func WithHeader(header bool) DelimitedOption
WithHeader sets whether DelimitedWriter emits a CSV/TSV header (default true). The header is written before the first data row, or on DelimitedWriter.Flush if only names were registered. See DelimitedWriter.WriteHeader to emit it earlier.
type DelimitedWriter ¶ added in v0.3.2
type DelimitedWriter struct {
Formatter *spanvalue.FormatConfig
// Header enables a header line before the first data row when true (default).
// See [WithHeader].
Header bool
// Set before the first write. Once names have been resolved for the current
// schema, later changes do not retroactively rewrite cached header names.
UnnamedFieldNamer spanvalue.UnnamedFieldNamer
// contains filtered or unexported fields
}
DelimitedWriter writes rows as CSV-style delimited text. Call Flush after the final write. Header controls automatic header output; see WithHeader and DelimitedWriter.WriteHeader.
func NewCSVWriter ¶
func NewCSVWriter(out io.Writer, opts ...DelimitedOption) *DelimitedWriter
NewCSVWriter returns a comma-delimited CSV writer configured by options. It is a thin helper for NewDelimitedWriter(out, Comma, opts...).
func NewDelimitedWriter ¶ added in v0.3.1
func NewDelimitedWriter(out io.Writer, delimiter rune, options ...DelimitedOption) *DelimitedWriter
NewDelimitedWriter returns a CSV-style writer using delimiter as the field delimiter and configured by options. Pass Comma for CSV output or '\t' for TSV output. Delimiter must be non-zero and a valid encoding/csv delimiter.
func NewDelimitedWriterWithOptions
deprecated
added in
v0.3.2
func NewDelimitedWriterWithOptions(out io.Writer, delimiter rune, options ...DelimitedOption) *DelimitedWriter
NewDelimitedWriterWithOptions forwards to NewDelimitedWriter.
Deprecated: Use NewDelimitedWriter instead.
func (*DelimitedWriter) Flush ¶ added in v0.3.2
func (w *DelimitedWriter) Flush() error
Flush flushes buffered delimited data to the underlying writer. When DelimitedWriter.Header is true, a schema is registered, len(column names) > 0, and no header was written yet, Flush writes the header first (including zero-row SELECT exports). With a registered zero-column schema, Flush succeeds without writing. With no registered schema and DelimitedWriter.Header true, Flush returns ErrMissingColumnNames. Flush does not close the underlying writer.
func (*DelimitedWriter) Prepare
deprecated
added in
v0.3.2
func (w *DelimitedWriter) Prepare(metadata *sppb.ResultSetMetadata) error
Prepare initializes the delimited schema from result-set metadata before the first row is written.
Deprecated: Use DelimitedWriter.PrepareRowType or DelimitedWriter.PrepareColumnNames.
func (*DelimitedWriter) PrepareColumnNames ¶ added in v0.4.1
func (w *DelimitedWriter) PrepareColumnNames(names []string) error
PrepareColumnNames registers column names only; same as WithColumnNames for non-empty names. Unlike WithColumnNames, an empty names slice returns ErrMissingColumnNames; for zero-column result sets use DelimitedWriter.PrepareRowType instead.
func (*DelimitedWriter) PrepareRowType ¶ added in v0.4.1
func (w *DelimitedWriter) PrepareRowType(rowType *sppb.StructType) error
PrepareRowType registers column names and field types; same as WithRowType. Nil rowType and a row type with no fields both register an empty schema (see package doc).
func (*DelimitedWriter) WriteGCVs ¶ added in v0.3.2
func (w *DelimitedWriter) WriteGCVs(values []spanner.GenericColumnValue) error
WriteGCVs writes one row from GCVs; see package doc "Column names and field types".
func (*DelimitedWriter) WriteHeader ¶ added in v0.3.2
func (w *DelimitedWriter) WriteHeader() error
WriteHeader writes the CSV/TSV header once; a column schema must already be registered. With zero registered column names (empty row type), WriteHeader succeeds without writing. With no registered schema, it returns ErrMissingColumnNames. When DelimitedWriter.Header is true, DelimitedWriter.Flush also writes a pending header.
func (*DelimitedWriter) WriteRow ¶ added in v0.3.2
func (w *DelimitedWriter) WriteRow(row *spanner.Row) error
WriteRow writes one delimited row; see package doc "Column names and field types".
func (*DelimitedWriter) WriteStructValues ¶ added in v0.4.1
func (w *DelimitedWriter) WriteStructValues(values []*structpb.Value) error
WriteStructValues writes one row from []*structpb.Value; see package doc "Column names and field types".
func (*DelimitedWriter) WriteValues ¶ added in v0.3.2
func (w *DelimitedWriter) WriteValues(columnNames []string, values []spanner.GenericColumnValue) error
WriteValues writes one row from column names and GCVs.
type FlushWriter ¶ added in v0.3.2
FlushWriter streams Spanner rows and finalizes any buffered output.
type Flusher ¶ added in v0.3.1
type Flusher interface {
Flush() error
}
Flusher finalizes any buffered output. Flush does not close the underlying io.Writer. DelimitedWriter uses Flush to forward buffered CSV-style data; JSONLWriter and SQLInsertWriter implement it as a no-op so adapters can use one finalize path for all writer implementations.
type JSONLOption ¶ added in v0.3.2
type JSONLOption interface {
// contains filtered or unexported methods
}
JSONLOption configures a JSONLWriter created by NewJSONLWriter.
type JSONLWriter ¶
type JSONLWriter struct {
Formatter *spanvalue.FormatConfig
// Set before the first write. Once names have been resolved for the current
// schema, later changes do not retroactively rewrite cached object keys.
UnnamedFieldNamer spanvalue.UnnamedFieldNamer
// contains filtered or unexported fields
}
JSONLWriter writes one JSON object per line.
func NewJSONLWriter ¶
func NewJSONLWriter(out io.Writer, options ...JSONLOption) *JSONLWriter
NewJSONLWriter returns a JSONL writer configured by options.
func NewJSONLWriterWithOptions
deprecated
added in
v0.3.2
func NewJSONLWriterWithOptions(out io.Writer, options ...JSONLOption) *JSONLWriter
NewJSONLWriterWithOptions forwards to NewJSONLWriter.
Deprecated: Use NewJSONLWriter instead.
func (*JSONLWriter) Flush ¶ added in v0.3.1
func (w *JSONLWriter) Flush() error
Flush finalizes JSONL output. JSONLWriter is unbuffered, so this is a no-op.
func (*JSONLWriter) Prepare
deprecated
added in
v0.3.2
func (w *JSONLWriter) Prepare(metadata *sppb.ResultSetMetadata) error
Prepare initializes the JSONL schema from result-set metadata before the first row is written. If a schema is already initialized, Prepare verifies that the metadata column names match the existing schema.
Deprecated: Use JSONLWriter.PrepareRowType, JSONLWriter.PrepareColumnNames, WithRowType, WithColumnNames, or WithMetadata.
func (*JSONLWriter) PrepareColumnNames ¶ added in v0.4.1
func (w *JSONLWriter) PrepareColumnNames(names []string) error
PrepareColumnNames registers column names; see DelimitedWriter.PrepareColumnNames.
func (*JSONLWriter) PrepareRowType ¶ added in v0.4.1
func (w *JSONLWriter) PrepareRowType(rowType *sppb.StructType) error
PrepareRowType registers names and field types; see DelimitedWriter.PrepareRowType. Nil rowType registers an empty schema.
func (*JSONLWriter) WriteGCVs ¶
func (w *JSONLWriter) WriteGCVs(values []spanner.GenericColumnValue) error
WriteGCVs writes one row; see DelimitedWriter.WriteGCVs.
func (*JSONLWriter) WriteRow ¶
func (w *JSONLWriter) WriteRow(row *spanner.Row) error
WriteRow writes one JSONL row. Does not require With* or Prepare*; see DelimitedWriter.WriteRow.
func (*JSONLWriter) WriteStructValues ¶ added in v0.4.1
func (w *JSONLWriter) WriteStructValues(values []*structpb.Value) error
WriteStructValues writes one row; see DelimitedWriter.WriteStructValues.
func (*JSONLWriter) WriteValues ¶
func (w *JSONLWriter) WriteValues(columnNames []string, values []spanner.GenericColumnValue) error
WriteValues writes one row; see DelimitedWriter.WriteValues.
type NameOption ¶ added in v0.3.2
type NameOption interface {
DelimitedOption
JSONLOption
}
NameOption configures field-name handling for delimited and JSONL writers.
func WithUnnamedFieldNamer ¶ added in v0.3.2
func WithUnnamedFieldNamer(namer spanvalue.UnnamedFieldNamer) NameOption
WithUnnamedFieldNamer sets the unnamed-field naming policy for delimited and JSONL writers.
type Option ¶ added in v0.3.2
type Option interface {
DelimitedOption
JSONLOption
SQLInsertOption
}
Option configures any writer type created by a writer constructor.
func WithColumnNames ¶ added in v0.4.1
WithColumnNames registers column names only and clears any registered field types. An empty names slice is ignored (the writer stays unregistered); use WithRowType for a zero-column result set.
func WithFormatter ¶ added in v0.3.2
func WithFormatter(formatter *spanvalue.FormatConfig) Option
WithFormatter sets the FormatConfig used by a writer.
func WithMetadata ¶ added in v0.3.2
func WithMetadata(metadata *sppb.ResultSetMetadata) Option
WithMetadata registers names and types from metadata.GetRowType(); same as WithRowType. Other metadata fields are ignored.
func WithRowType ¶ added in v0.4.1
func WithRowType(rowType *sppb.StructType) Option
WithRowType registers column names and field types at construction. Nil rowType registers an empty schema (see package doc).
type SQLInsertKind ¶ added in v0.4.0
type SQLInsertKind int
SQLInsertKind selects the INSERT statement prefix written by SQLInsertWriter.
Variants follow Spanner GoogleSQL DML: INSERT OR IGNORE skips rows whose primary key already exists; INSERT OR UPDATE inserts or updates by primary key. They cannot be combined with ON CONFLICT in the same statement, and INSERT is not supported in Partitioned DML. See https://cloud.google.com/spanner/docs/reference/standard-sql/dml-syntax .
const ( // SQLInsert writes plain INSERT INTO statements. SQLInsert SQLInsertKind = iota // SQLInsertOrIgnore writes INSERT OR IGNORE INTO statements. SQLInsertOrIgnore // SQLInsertOrUpdate writes INSERT OR UPDATE INTO statements. SQLInsertOrUpdate )
func (SQLInsertKind) String ¶ added in v0.4.0
func (k SQLInsertKind) String() string
type SQLInsertOption ¶ added in v0.3.2
type SQLInsertOption interface {
// contains filtered or unexported methods
}
SQLInsertOption configures a SQLInsertWriter created by NewSQLInsertWriter.
func WithSQLInsertKind ¶ added in v0.4.0
func WithSQLInsertKind(kind SQLInsertKind) SQLInsertOption
WithSQLInsertKind sets the INSERT statement variant for a SQLInsertWriter.
type SQLInsertWriter ¶
type SQLInsertWriter struct {
Table string
Formatter *spanvalue.FormatConfig
// contains filtered or unexported fields
}
SQLInsertWriter writes rows as GoogleSQL INSERT statements.
func NewSQLInsertWriter ¶
func NewSQLInsertWriter(out io.Writer, table string, options ...SQLInsertOption) *SQLInsertWriter
NewSQLInsertWriter returns a SQL INSERT writer configured by options.
func NewSQLInsertWriterWithOptions
deprecated
added in
v0.3.2
func NewSQLInsertWriterWithOptions(out io.Writer, table string, options ...SQLInsertOption) *SQLInsertWriter
NewSQLInsertWriterWithOptions forwards to NewSQLInsertWriter.
Deprecated: Use NewSQLInsertWriter instead.
func (*SQLInsertWriter) Flush ¶ added in v0.3.1
func (w *SQLInsertWriter) Flush() error
Flush finalizes SQL INSERT output. SQLInsertWriter is unbuffered, so this is a no-op.
func (*SQLInsertWriter) Prepare
deprecated
added in
v0.3.2
func (w *SQLInsertWriter) Prepare(metadata *sppb.ResultSetMetadata) error
Prepare initializes the SQL INSERT schema from result-set metadata before the first row is written. If a schema is already initialized, Prepare verifies that the metadata column names match the existing schema.
Deprecated: Use SQLInsertWriter.PrepareRowType, SQLInsertWriter.PrepareColumnNames, WithRowType, WithColumnNames, or WithMetadata.
func (*SQLInsertWriter) PrepareColumnNames ¶ added in v0.4.1
func (w *SQLInsertWriter) PrepareColumnNames(names []string) error
PrepareColumnNames initializes the SQL INSERT schema from column names before the first row is written. See DelimitedWriter.PrepareColumnNames for empty-name behavior.
func (*SQLInsertWriter) PrepareRowType ¶ added in v0.4.1
func (w *SQLInsertWriter) PrepareRowType(rowType *sppb.StructType) error
PrepareRowType initializes the SQL INSERT schema from a row type before the first row is written. When the row type comes from a cloud.google.com/go/spanner.RowIterator, use iter.Metadata.GetRowType after the first Next. Nil rowType registers an empty schema; SQLInsertWriter.WriteGCVs still requires at least one column to emit SQL.
func (*SQLInsertWriter) WriteGCVs ¶
func (w *SQLInsertWriter) WriteGCVs(values []spanner.GenericColumnValue) error
func (*SQLInsertWriter) WriteStructValues ¶ added in v0.4.1
func (w *SQLInsertWriter) WriteStructValues(values []*structpb.Value) error
WriteStructValues writes one row from structpb values using the field-type schema registered by WithRowType, WithMetadata, or [PrepareRowType].
func (*SQLInsertWriter) WriteValues ¶
func (w *SQLInsertWriter) WriteValues(columnNames []string, values []spanner.GenericColumnValue) error
type Writer ¶
Writer writes Spanner rows to an output stream.
WriteRow supplies column names and values on each call; see package doc "Column names and field types". Writer intentionally models row streaming only. Some concrete writers also implement Flusher; callers that own the full write lifecycle must call Flush after the final row when it is available. Factories that may return a buffered writer should return a concrete type or FlushWriter, not Writer alone.