July 15, 2021·4 min read·engineeringsqlitedatasettesearchdeployment

Datasette 0.58 adds local sockets and explicit search syntax

Unix-domain-socket serving changes the proxy connection, while raw full-text search gives a table an advanced query default. Both options make deployment policy more explicit.

A SQLite publishing tool has two distinct interfaces to configure. One is the connection through which a web proxy reaches the application. Another is the language a reader can enter into its search box. The Datasette 0.58 release adds Unix-domain-socket serving and a table metadata option for raw full-text search. Both additions let an operator choose behavior that previously required a different arrangement or a per-request option.

These are Datasette changes, not additions to SQLite's SQL grammar. Datasette exposes SQLite data through a web application and uses SQLite's full-text search machinery underneath its search interface. Keeping those responsibilities separate helps explain what the release actually changes. The database remains responsible for matching indexed content, while Datasette decides how to interpret a submitted search and where to accept proxied HTTP traffic.

I like tools that make a SQLite database useful without requiring a larger database service. Datasette's choices here fit that preference. They make specific deployment and query behaviors configurable without turning either choice into a requirement for every installation.

Bind the application to a local socket

The deployment documentation in the 0.58 tag gives the new --uds option. Datasette can listen on a Unix domain socket instead of a TCP port. Its example places a proxy in front of that socket and continues to expose ordinary HTTP URLs to readers.

datasette --uds /tmp/datasette.sock data.db \
  --setting base_url /data/

The database filename and URL prefix above are illustrative. The command follows the tagged documentation's combination of a socket path, database path, and base_url setting. A socket changes the local connection between processes. The URL prefix remains a separate application setting that must agree with the proxy's public route.

For nginx, the documented arrangement defines an upstream server with unix:/tmp/datasette.sock and sends requests to that upstream. Apache receives a corresponding Unix-socket form of ProxyPass. These examples establish support for both proxy configurations. They do not make a socket path a browser-facing URL.

The same documentation explains why preserving the incoming host matters. Datasette uses it when assembling absolute links to other pages. A correct proxy connection therefore includes application-level request information as well as a working transport. Choosing a Unix socket does not eliminate the host-header or path-prefix configuration.

This option is useful when the proxy and Datasette run on the same host and the deployment already has a reason to connect them locally. A remote proxy cannot simply use that filesystem socket path. The release adds another local serving arrangement without changing the external interface that readers use.

Choose whether the search box accepts operators

Datasette's tagged full-text search documentation describes the existing default. It escapes advanced search syntax to avoid errors and confusion for people who do not know the operators. A request can opt into SQLite's advanced full-text query syntax with _searchmode=raw.

Version 0.58 adds a persistent table metadata choice, "searchmode": "raw". A table can now accept the advanced syntax by default. The setting belongs to the table's metadata, so it expresses a decision about the audience of that table's search interface.

{
  "databases": {
    "catalog": {
      "tables": {
        "documents": {
          "searchmode": "raw"
        }
      }
    }
  }
}

This example sets the mode for an already searchable table. It does not create or populate a full-text index. The documentation treats index setup separately and explains that a corresponding external-content FTS table can be detected automatically. A metadata default changes interpretation of search input, not which data has been indexed.

The raw mode exposes operators such as AND, OR, NOT, and NEAR where supported by the underlying FTS query syntax. That gives an informed reader more control over the query. It also means that punctuation and operator words can carry search-language meaning. The escaped default exists to avoid requiring that knowledge from every reader.

An individual request can override the new default with _searchmode=escaped. This is useful because choosing a table default does not mean every caller has the same intent. A program submitting ordinary text can retain escaped behavior while an advanced interface exposes operator syntax.

The query remains inspectable

The full-text documentation shows a search as an outer query filtered by row identifiers from a matching FTS subquery. It also describes the table page's option to view and edit the SQL behind a search. That connection between the interface and the underlying query helps distinguish search-language behavior from a failure to index the expected content.

I regard the reversible search default as the more consequential user-interface choice in this release. It lets the publisher decide whether the audience expects literal input or a query language, while leaving the alternate behavior available per request. Combined with socket serving, it gives deployments two concrete controls, how the proxy connects locally and how a searchable table interprets its readers' input.