Value types and helpers
Dart types for Postgres values that have no built-in Dart equivalent, plus two
small helpers. All are exported from package:gisila_orm/gisila.dart.
import 'package:gisila_orm/gisila.dart';
final v = Vector([0.1, 0.2, 0.3]);final p = Point(52.52, 13.40);Vector
Section titled “Vector”class Vector { Vector(List<double> values); factory Vector.fromList(List<num> values); factory Vector.zeros(int dimensions); factory Vector.parse(String text);}An immutable list of doubles matching pgvector’s vector(n). The field type of
type: vector columns, and the argument to the
vector operators.
When to use: storing embeddings and querying them by similarity. Requires the pgvector extension on the server.
| Member | Type | Description |
|---|---|---|
Vector(values) |
constructor | Copies values into an unmodifiable list. |
Vector.fromList(values) |
factory | Accepts any numbers (for example decoded JSON). |
Vector.zeros(n) |
factory | n zeros. Throws ArgumentError for negative n. |
Vector.parse(text) |
factory | Parses [0.1,0.2], tolerating whitespace, surrounding single quotes and a trailing ::vector. Throws FormatException otherwise. |
values |
List<double> |
The components (unmodifiable). |
dimensions |
int |
Length. |
toSqlLiteral() |
String |
[v1,v2,...], the form bound as a parameter. |
l2Norm |
double |
Euclidean length. |
normalized |
Vector |
Unit-length copy; a zero vector is returned unchanged. |
dot(other) |
double |
Dot product. Throws ArgumentError when dimensions differ. |
cosineSimilarityTo(other) |
double |
Similarity in [-1, 1]; 0 if either is zero. pgvector’s <=> returns distance, 1 - similarity. |
== and hashCode compare component-wise. When bound, a Vector is sent as
text with a ::vector cast.
await documents().insert({'title': 'Intro', 'embedding': Vector.fromList(embeddingFromApi)}).run(ctx);
final hits = await documents() .orderBy(DocumentTable.embedding.cosineDistance(queryVector)) .limit(5) .all(ctx);VectorDistance
Section titled “VectorDistance”enum VectorDistance { l2, cosine, innerProduct }| Value | op |
opclass |
alias (schema YAML) |
|---|---|---|---|
l2 |
<-> |
vector_l2_ops |
l2 |
cosine |
<=> |
vector_cosine_ops |
cosine |
innerProduct |
<#> |
vector_ip_ops |
ip |
VectorDistance.fromAlias(String) accepts the alias or the enum name
(case-insensitive) and returns null for anything else.
VectorIndexMethod
Section titled “VectorIndexMethod”enum VectorIndexMethod { hnsw, ivfflat }Index method for vector indexes. fromAlias(String) parses the name or returns
null. HNSW is the schema default; it needs no training data and is usually
the better choice. IVFFlat builds faster but should be created after the table
has data.
Geometric types
Section titled “Geometric types”Dart values for Postgres’s built-in geometric types. Each has const
constructors, value equality, toSqlLiteral() (also used by toString())
and a static fromString that throws FormatException on bad input.
| Class | Constructor | Postgres | Text form |
|---|---|---|---|
Point |
const Point(double x, double y) |
point |
(x,y) |
Box |
const Box(Point corner1, Point corner2) |
box |
((x1,y1),(x2,y2)) |
Circle |
const Circle(Point center, double radius) |
circle |
<(x,y),r> |
Lseg |
const Lseg(Point start, Point end) |
lseg |
[(x1,y1),(x2,y2)] |
When to use: simple planar geometry stored in core Postgres. There are no
geometric operators in the query builder beyond equality and null checks; use
RawSql for <@, <-> and friends. For
geographic data, PostGIS is a better fit (not supported by the schema).
When bound, each is sent as its text form with a matching cast ($1::point).
await places().insert({'name': 'Office', 'location': const Point(52.52, 13.40)}).run(ctx);
final near = await places() .where(RawSql<bool>('"places"."location" <-> \$1::point < 0.5', ['(52.5,13.4)'])) .all(ctx);encodeJsonColumn
Section titled “encodeJsonColumn”String? encodeJsonColumn(Object? value)jsonEncodes a value for a json column, passing null through.
When to use: when you write a JSON column through an insert or update map.
The driver can bind a Dart Map as JSON on its own, but a list would be turned
into a Postgres array literal and a string or boolean wouldn’t be parsed as
JSON. Generated toRow() already uses it.
await users().where(UserTable.id.eq(id)).update({ 'preferences': encodeJsonColumn({'theme': 'dark', 'langs': ['en', 'de']}),}).run(ctx);SafeString
Section titled “SafeString”extension SafeString on String { String get safeTk; // "identifier" String get safe; // 'literal'}| Getter | Result | Description |
|---|---|---|
safeTk |
"foo" |
Quotes an identifier, doubling inner ". Returns an already well-formed quoted identifier unchanged. |
safe |
'foo' |
Quotes a string literal, doubling inner '. Returns an already well-formed literal unchanged. |
When to use: safeTk when you build SQL that needs a table or column name
known only at runtime (for example a sort column picked from an allow-list).
For values, use bound parameters rather than safe.
const sortable = {'title', 'published_at'};final col = sortable.contains(requested) ? requested : 'published_at';final rows = await db.execute('SELECT * FROM "posts" ORDER BY ${col.safeTk} DESC LIMIT 20');See also: Schema YAML format, Expressions and operators.