sp

package
v1.12.0 Latest Latest
Warning

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

Go to latest
Published: Sep 3, 2026 License: MIT Imports: 15 Imported by: 0

Documentation

Overview

Package sp is the SharePoint backend for xql: list binding (site + list resolution + column schema), OData translation, and the read/write executor. Sign-in and the Graph HTTP client come from github.com/excelano/spauth, the layer this backend shares with the xfiles tools.

Index

Constants

View Source
const ODataFieldPrefix = "fields/"

ODataFieldPrefix is prepended to every column reference in generated $filter expressions. SharePoint list-item filtering requires the "fields/" prefix because user columns live under the fields subobject on item resources.

Variables

This section is empty.

Functions

func BuildCellSchema

func BuildCellSchema(bound *BoundList) ([]string, map[string]cell.ColumnInfo)

BuildCellSchema converts a bound list's SharePoint schema into the cell- based schema the shared evaluator expects. Column order matches Bound.Columns so row position is stable across calls.

func BuildCellTable

func BuildCellTable(bound *BoundList, items []listItem) (*cell.Table, error)

BuildCellTable assembles a cell.Table from a bound list and a fetched item set. Row indices align with the items slice: rows[i] corresponds to items[i].ID, so callers that need to PATCH or DELETE the underlying Graph item can index back without a separate lookup.

Path carries the bound list's display name as a label for table-rendering callers; SharePoint lists have no filesystem path.

func FieldTypeToCellType

func FieldTypeToCellType(t FieldType) cell.ColumnType

FieldTypeToCellType maps a SharePoint FieldType to the cell.ColumnType used by the shared evaluator. Number is mapped to TypeFloat (not TypeInt) because Graph returns JSON numbers and json.Unmarshal into any always produces float64; even integer-valued list-item numbers arrive as floats. Object-shaped types (person, lookup, hyperlink) and the read-only calculated/unknown types fall back to TypeString — they round-trip as rendered text for read paths but cannot be written.

func FieldsToRow

func FieldsToRow(fields map[string]any, cols []string, info map[string]cell.ColumnInfo) (cell.Row, error)

FieldsToRow converts one Graph row (the unmarshaled "fields" subobject) into a typed cell.Row in the column order returned by BuildCellSchema. Missing keys, explicit nulls, and empty strings on non-string columns all produce Null cells; the evaluator treats those as NULL under SQL three-valued logic. Per-column conversion errors are surfaced rather than silently dropped so a malformed list row isn't mistaken for a NULL one.

func ToOData

func ToOData(node parse.Predicate, schema map[string]FieldInfo) (string, error)

ToOData converts a parsed Predicate to a Microsoft Graph $filter expression. Column references are verified against schema (keyed by internal name) and formatted with the fields/ prefix. Values are emitted in OData v4 form: single-quoted strings (with ” escape), bare numbers, lowercase booleans, and bare ISO 8601 datetimes. Date-only strings on DateTime columns are normalized to full RFC3339 in UTC.

A nil predicate returns the empty string. The result is not URL-encoded; pass it through url.Values when building the request.

Types

type BoundList

type BoundList struct {
	SiteID      string
	ListID      string
	Name        string
	DisplayName string
	SourceURL   string
	Columns     []string
	Schema      map[string]FieldInfo
}

BoundList is the resolved single list this REPL session operates on. Columns preserves Graph's response order (creation order in SharePoint) so SELECT * renders columns predictably; Schema is the lookup map keyed by internal name. SourceURL is the original URL passed to ResolveListBinding, kept so the REPL's refresh command can re-bind without re-asking the user.

func ResolveListBinding

func ResolveListBinding(ctx context.Context, graph *spauth.GraphClient, listURL string) (*BoundList, error)

ResolveListBinding resolves a SharePoint list URL to its Graph IDs and column schema in three calls: site, list, columns.

type Executor

type Executor struct {
	Graph              *spauth.GraphClient
	Bound              *BoundList
	Mode               string
	Headers            bool
	AllFields          bool
	ConfirmDestructive bool
	Confirm            func() bool
	OutputPath         string
	Out                io.Writer
}

Executor binds a parsed statement to the live SharePoint list and runs it. One Executor per session; the bound list and graph client are immutable for the session.

Confirm is the interactive "Apply? y/N" callback used by the REPL (lands in slice 4). When non-nil, write executors will call it after the dry-run preview to decide whether to commit (unless commit is already true via the trailing '!'). --exec mode leaves Confirm nil so writes either dry-run or commit explicitly based on --commit.

func (*Executor) Describe

func (e *Executor) Describe(w io.Writer, arg string) error

Describe renders the bound list's columns and Graph-side types to w using the executor's current format. The primary "name" column shows the user- facing display name (what the SharePoint UI labels the column); a second "internal" column shows the Graph internal name when it differs, since that name is what Graph $filter expressions and PATCH bodies actually use. Hidden and read-only flags shape SELECT * (hidden) and INSERT/UPDATE (read-only); users hitting "why won't this column write?" find the answer here.

arg is the REPL meta-command argument: "" omits hidden columns (matching the SELECT * default), "all" shows every column including SharePoint's system fields (LinkTitle, _ColorTag, ContentType, ...). Anything else is a usage error.

func (*Executor) Execute

func (e *Executor) Execute(ctx context.Context, stmt parse.Stmt, commit bool) error

Execute dispatches to the per-statement handler. The commit flag distinguishes dry-run (commit=false: preview only) from a real write (commit=true: preview + apply). It is ignored for SELECT.

func (*Executor) Refresh

func (e *Executor) Refresh() error

Refresh re-resolves the bound list from its source URL, picking up any column schema changes made in SharePoint mid-session. The graph client and its cached token are reused. Uses context.Background() because this is a user-initiated REPL command with no outer deadline to honor.

func (*Executor) SetConfirm

func (e *Executor) SetConfirm(fn func() bool)

SetConfirm wires the REPL's y/N callback into the executor's destructive- write confirmation hook. Called once by repl.Run via Session.SetConfirm.

type FieldInfo

type FieldInfo struct {
	Name        string
	DisplayName string
	Type        FieldType
	Hidden      bool
	ReadOnly    bool
	Required    bool
}

FieldInfo describes one column. Name is the internal name used in Graph $filter expressions and PATCH bodies; DisplayName is what the SharePoint UI shows.

type FieldType

type FieldType string

FieldType is a coarse classification of a SharePoint column, derived from Graph's per-type discriminator subobjects on the column resource (text, number, dateTime, ...). Used by the OData translator to format comparisons correctly and by the write path to reject writes to unsupported types.

const (
	FieldText       FieldType = "text"
	FieldNote       FieldType = "note"
	FieldNumber     FieldType = "number"
	FieldBoolean    FieldType = "boolean"
	FieldDateTime   FieldType = "dateTime"
	FieldChoice     FieldType = "choice"
	FieldPerson     FieldType = "person"
	FieldLookup     FieldType = "lookup"
	FieldHyperlink  FieldType = "hyperlink"
	FieldCalculated FieldType = "calculated"
	FieldUnknown    FieldType = "unknown"
)

Jump to

Keyboard shortcuts

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