Queries and mutations
The example stores the people in a database and queries their names. It collects query pages, updates Ada's age, and reads the changed age.
Example
The example compares these results:
- a committed mutation
- a repeated mutation
- a query that matches no entity
Give Ada her birthday and read her age
birthdayText holds this document:
query {find [?e]
where [[?e name Ada]]}
patch {?e {age 37}}
queryText holds this document:
find [?age]
where [[?e name Ada]
[?e age ?age]]
birthday, err := stardust.Parse(birthdayText, stardust.DUST)
if err != nil {
return err
}
defer birthday.Close()
mutation, err := db.Mutation(birthday)
if err != nil {
return err
}
defer mutation.Close()
if _, err := mutation.Run(nil, stardust.RunOptions{}, nil); err != nil {
return err
}
definition, err := stardust.Parse(queryText, stardust.DUST)
if err != nil {
return err
}
defer definition.Close()
query, err := db.Query(definition)
if err != nil {
return err
}
defer query.Close()
rows, err := query.Run(nil, stardust.RunOptions{}, nil)
if err != nil {
return err
}
defer rows.Close()
result, err := rows.AllPages()
if err != nil {
return err
}
defer result.Close()[{age 37}]Query pages
Each query page is an owned document.
- You can keep a page after you release the rows handle, query, or database that produced it.
- Release each page when you finish with its values. The document ownership rule applies.
Operations
| Operation | Returns | Summary |
|---|---|---|
| Database.Query | query | Open an owned query from a path or an inline definition. |
| Database.Mutation | mutation | Open an owned mutation from a path or an inline definition. |
| Query.Run | rows | Run the query and return an owned row cursor. |
| Query.Close | none | Release the query handle. |
| Rows.Next | document | Read the next page as an owned document. |
| Rows.Pages | pages | rows.pages() iterates the non-empty pages of the cursor. |
| Rows.AllPages | document | rows.all_pages() reads every remaining page into one owned array document. |
| Rows.Close | none | Release the rows handle. |
| Query.Subscribe | subscription | query.subscribe(parameters, options) opens an owned live subscription. |
| Subscription.Next | event | Wait for the next live event. |
| Subscription.All | events | subscription.events() delivers events in order until the subscription is cancelled, closes or fails. |
| Subscription.Cancel | none | subscription.cancel() ends the subscription. |
| Subscription.Close | none | Release the subscription handle. |
| Mutation.Run | commit | Run the mutation and return commit information. |
| Mutation.Close | none | Release the mutation handle. |
| Database.MergePatch | commit | database.merge_patch(patch) applies an entity-keyed patch document in one transaction and returns commit information. |
Database.Query
Open an owned query from a path or an inline definition.
Database.Query(definition) opens an owned query from an inline native definition document.
- The call copies the definition.
- Database.QueryPath(path) opens an owned query from a stored definition path.
- Each run selects the stored definition using its run options, including
as_ofwhen supplied.
func (d *Database) Query(definition *Document) (*Query, error)func (d *Database) QueryPath(path string) (*Query, error)- Concurrency: Other calls can overlap this call, except the release of a handle that this call uses.
- Ownership: The caller owns the returned handle and releases it.
Parameters
| Parameter | Type | Ownership | Default | Meaning |
|---|---|---|---|---|
definition | *Document | Borrowed for the call | Required | The inline native query definition copied into the query handle. |
path | string | Value | Required | The stored query definition path selected at run time. |
Errors
| Status | When |
|---|---|
StatusNotFound | no definition is stored at the path |
StatusInvalidDefinition | the definition is invalid |
StatusClosed | the database is closed |
StatusOutOfMemory | native memory is exhausted |
Examples
Open an inline query and read its first page
queryText holds this document:
find [?name]
where [[?e name ?name]]
orderBy [?name]
definition, err := stardust.Parse(queryText, stardust.DUST)
if err != nil {
return err
}
defer definition.Close()
query, err := db.Query(definition)
if err != nil {
return err
}
defer query.Close()
rows, err := query.Run(nil, stardust.RunOptions{}, nil)
if err != nil {
return err
}
defer rows.Close()
result, err := rows.Next()
if err != nil {
return err
}
defer result.Close()[{name Ada} {name Bob} {name Cy}]Refuse an invalid query definition
queryText holds this document:
find [?x]
definition, err := stardust.Parse(queryText, stardust.DUST)
if err != nil {
return err
}
defer definition.Close()
query, result := db.Query(definition)
if query != nil {
defer query.Close()
}{code unbound_variable
message Unbound_Variable
path null
field null
entity null
offset null
status invalid_definition}Report a missing stored query
query, result := db.QueryPath("people/missing")
if query != nil {
defer query.Close()
}{code not_found
message no definition at this path
path people/missing
field null
entity null
offset null
status not_found}C exports: stardust_db_query_open, stardust_db_query_error
Database.Mutation
Open an owned mutation from a path or an inline definition.
Database.Mutation(definition) opens an owned mutation from an inline native definition document.
- The call copies the definition.
- Database.MutationPath(path) opens an owned mutation from a stored definition path.
- Each run selects the stored definition using its run options, including
as_ofwhen supplied.
func (d *Database) Mutation(definition *Document) (*Mutation, error)func (d *Database) MutationPath(path string) (*Mutation, error)- Concurrency: Other calls can overlap this call, except the release of a handle that this call uses.
- Ownership: The caller owns the returned handle and releases it.
Parameters
| Parameter | Type | Ownership | Default | Meaning |
|---|---|---|---|---|
definition | *Document | Borrowed for the call | Required | The inline native mutation definition copied into the mutation handle. |
path | string | Value | Required | The stored mutation definition path selected at run time. |
Errors
| Status | When |
|---|---|
StatusNotFound | no definition is stored at the path |
StatusInvalidDefinition | the definition is invalid |
StatusClosed | the database is closed |
StatusOutOfMemory | native memory is exhausted |
Examples
database/mutation
birthdayText holds this document:
query {find [?e]
where [[?e name Ada]]}
patch {?e {age 37}}
source, err := stardust.Parse(birthdayText, stardust.DUST)
if err != nil {
return err
}
defer source.Close()
mutation, err := db.Mutation(source)
if err != nil {
return err
}
defer mutation.Close()
result, err := mutation.Run(nil, stardust.RunOptions{}, nil)
if err != nil {
return err
}{status committed
transaction 5
facts 1
committed_at 17915443414964059
ids {}}C exports: stardust_db_mutation_open, stardust_db_mutation_error
Query.Run
Run the query and return an owned row cursor.
handle.run(parameters, options) runs a query or mutation.
- Parameters apply a JSON merge patch (RFC 7396) to the declared defaults.
- Omitted parameters keep their defaults.
- Absent parameters have the same effect as an empty object.
- Objects merge recursively.
- Other values replace the defaults, including tagged values such as {#utc …}.
A name matches with or without its leading ?.
- A null parameter has no value, so the run fails with missing_parameter.
Query runs return owned rows.
- Mutation runs return commit information.
- Options include
as_of,max_costand querypage_size. - The
as_ofoption selects a historical stored definition.
func (q *Query) Run(parameters *Document, options RunOptions, explain *QueryExplain) (*Rows, error)- Concurrency: Other calls can overlap this call, except the release of a handle that this call uses.
- Ownership: The caller owns the returned handle and releases it.
Parameters
| Parameter | Type | Ownership | Default | Meaning |
|---|---|---|---|---|
parameters | *Document | Borrowed for the call | Absent means no supplied parameters | Named values bound for this execution. |
options | RunOptions | Value | Required options record. See field defaults | The operation's options record. See its field defaults. |
explain | *QueryExplain | Caller-owned output | Absent skips explain output | Optional explain output. This record contains explain output for query run. The compile, plan, execute, group and order fields divide the wall time of run into stages. |
Errors
| Status | When |
|---|---|
StatusNotFound | the stored query definition was deleted |
StatusInvalidDefinition | the loaded query definition is invalid |
StatusInvalidArgument | the parameters or run options are invalid |
StatusEvaluationFailed | the query fails or exceeds max_cost |
StatusClosed | the query is closed |
StatusOutOfMemory | native memory is exhausted |
Examples
Open an inline query and read its first page
queryText holds this document:
find [?name]
where [[?e name ?name]]
orderBy [?name]
definition, err := stardust.Parse(queryText, stardust.DUST)
if err != nil {
return err
}
defer definition.Close()
query, err := db.Query(definition)
if err != nil {
return err
}
defer query.Close()
rows, err := query.Run(nil, stardust.RunOptions{}, nil)
if err != nil {
return err
}
defer rows.Close()
result, err := rows.Next()
if err != nil {
return err
}
defer result.Close()[{name Ada} {name Bob} {name Cy}]Capture the host duration boundary
boundaryText holds this document:
9223372036854775807
queryText holds this document:
find [?name]
where [[?e name ?name]]
orderBy [?name]
definition, err := stardust.Parse(queryText, stardust.DUST)
if err != nil {
return err
}
defer definition.Close()
query, err := db.Query(definition)
if err != nil {
return err
}
defer query.Close()
boundary, err := stardust.Parse(boundaryText, stardust.DUST)
if err != nil {
return err
}
defer boundary.Close()
boundaryRoot, err := boundary.Root()
if err != nil {
return err
}
nanoseconds, err := boundary.I64(boundaryRoot)
if err != nil {
return err
}
result := stardust.RunOptions{PageSize: 2, MaxCost: time.Duration(nanoseconds)}
rows, err := query.Run(nil, result, nil)
if err != nil {
return err
}
defer rows.Close(){page_size 2
max_cost 92233720368547758
as_of 0}Truncate a positive sub-tick duration
boundaryText holds this document:
99
queryText holds this document:
find [?name]
where [[?e name ?name]]
orderBy [?name]
definition, err := stardust.Parse(queryText, stardust.DUST)
if err != nil {
return err
}
defer definition.Close()
query, err := db.Query(definition)
if err != nil {
return err
}
defer query.Close()
boundary, err := stardust.Parse(boundaryText, stardust.DUST)
if err != nil {
return err
}
defer boundary.Close()
boundaryRoot, err := boundary.Root()
if err != nil {
return err
}
nanoseconds, err := boundary.I64(boundaryRoot)
if err != nil {
return err
}
result := stardust.RunOptions{PageSize: 2, MaxCost: time.Duration(nanoseconds)}
rows, err := query.Run(nil, result, nil)
if err != nil {
return err
}
defer rows.Close(){page_size 2
max_cost 0
as_of 0}Explain query execution
queryText holds this document:
find [?name]
where [[?e name ?name]]
orderBy [?name]
definition, err := stardust.Parse(queryText, stardust.DUST)
if err != nil {
return err
}
defer definition.Close()
query, err := db.Query(definition)
if err != nil {
return err
}
defer query.Close()
var result stardust.QueryExplain
rows, err := query.Run(nil, stardust.RunOptions{}, &result)
if err != nil {
return err
}
defer rows.Close(){load_definition {cpu 361
wall 366
arena_bytes 1664}
parameters {cpu 3
wall 5
arena_bytes 0}
run {cpu 1988
wall 1987
arena_bytes 6408}
total {cpu 2368
wall 2374
arena_bytes 8072}
arena_capacity 4194304
work 308
rows 3
compile 37
plan 25
execute 224
group 0
order 14
stages_completed 3}A negative Go duration keeps its sign at the ABI boundary
result := stardust.RunOptions{MaxCost: -time.Nanosecond}{page_size 0
max_cost -1
as_of 0}Run with typed query options
queryText holds this document:
find [?name]
where [[?e name ?name]]
orderBy [?name]
definition, err := stardust.Parse(queryText, stardust.DUST)
if err != nil {
return err
}
defer definition.Close()
query, err := db.Query(definition)
if err != nil {
return err
}
defer query.Close()
result := stardust.RunOptions{PageSize: 2, MaxCost: time.Second}
rows, err := query.Run(nil, result, nil)
if err != nil {
return err
}
defer rows.Close(){page_size 2
max_cost 10000000
as_of 0}C exports: stardust_db_query_run, stardust_db_rows_error
Query.Close
Release the query handle.
close(handle) releases the handle.
- Do not use it after closure.
- Result documents remain usable after the handle that produces them closes.
func (q *Query) Close()- Concurrency: This call is the last use of the receiver and ends its ownership.
Examples
Open an inline query and read its first page
queryText holds this document:
find [?name]
where [[?e name ?name]]
orderBy [?name]
definition, err := stardust.Parse(queryText, stardust.DUST)
if err != nil {
return err
}
defer definition.Close()
query, err := db.Query(definition)
if err != nil {
return err
}
defer query.Close()
rows, err := query.Run(nil, stardust.RunOptions{}, nil)
if err != nil {
return err
}
defer rows.Close()
result, err := rows.Next()
if err != nil {
return err
}
defer result.Close()
query.Close()[{name Ada} {name Bob} {name Cy}]C exports: stardust_db_query_release
Rows.Next
Read the next page as an owned document.
rows.next() returns an owned array document with the next page.
- An empty array ends the cursor.
- A page outlives the rows, query and database.
subscription.next(max_wait) returns the next live event with sequence, superseded, transaction and an owned result document.
- Event 1 is the initial result.
- The superseded field counts intermediate computed results skipped since this subscription's previous event.
- Its first event always has 0.
- Each delivered result is a full replacement.
- Consumers replace their previous view with this result.
Identical subscriptions share computed results.
- If another consumer computes two newer results before this consumer calls next, this consumer receives the latest with superseded 1.
- One rerun can include several commits.
- Thus, superseded counts neither commits nor changed rows.
- The sequence field counts delivered events.
- It advances by one even when the subscription skips results.
The max_wait argument uses the host duration type.
- The binding gives it to one native call as 100-ns ticks.
- Zero polls.
- A positive wait returns when an event exists, or returns no event at the deadline.
- A representable negative wait reports
invalid_argument. - Bindings do not divide the wait into shorter waits.
Cancel, close and database close wake a blocked next immediately.
- The precision of a timed deadline depends on the platform.
- Windows rounds it to milliseconds.
After cancel or close, the subscription reports cancelled.
- After database close, it reports closed.
- A failed rerun is terminal.
- Every later call reports that failure.
func (r *Rows) Next() (*Document, error)- Concurrency: Other calls can overlap this call, except the release of a handle that this call uses.
- Ownership: The caller owns the returned handle and releases it.
Errors
| Status | When |
|---|---|
StatusEvaluationFailed | the page does not render |
StatusClosed | the rows is closed |
StatusOutOfMemory | native memory is exhausted |
Examples
Open an inline query and read its first page
queryText holds this document:
find [?name]
where [[?e name ?name]]
orderBy [?name]
definition, err := stardust.Parse(queryText, stardust.DUST)
if err != nil {
return err
}
defer definition.Close()
query, err := db.Query(definition)
if err != nil {
return err
}
defer query.Close()
rows, err := query.Run(nil, stardust.RunOptions{}, nil)
if err != nil {
return err
}
defer rows.Close()
result, err := rows.Next()
if err != nil {
return err
}
defer result.Close()[{name Ada} {name Bob} {name Cy}]C exports: stardust_db_rows_next, stardust_result_take_document, stardust_result_error, stardust_result_release
Rows.Pages
rows.pages() iterates the non-empty pages of the cursor.
rows.pages() lazily iterates the remaining non-empty pages in order.
- Advancing the iterator reads the next page.
- Each page is an array document; the iterator does not build a document containing the whole result.
- The empty page ends iteration and is not yielded.
- Rust pages belong to the caller.
- Go, Clojure, Python and Odin pages belong to the iteration and close when it advances; use next to keep an owned page.
- Close the iterator after an early exit where the language requires explicit cleanup.
- The cursor stays open until the caller closes it.
- A failure is reported once, and then iteration ends.
func (r *Rows) Pages() iter.Seq2[*Document, error]- Concurrency: Other calls can overlap this call, except the release of a handle that this call uses.
Errors
| Status | When |
|---|---|
StatusEvaluationFailed | a page does not render |
StatusClosed | the rows is closed |
StatusOutOfMemory | native memory is exhausted |
Examples
Iterate the pages of a query run
queryText holds this document:
find [?name]
where [[?e name ?name]]
orderBy [?name]
definition, err := stardust.Parse(queryText, stardust.DUST)
if err != nil {
return err
}
defer definition.Close()
query, err := db.Query(definition)
if err != nil {
return err
}
defer query.Close()
rows, err := query.Run(nil, stardust.RunOptions{PageSize: 1}, nil)
if err != nil {
return err
}
defer rows.Close()
result := 0
for page, err := range rows.Pages() {
if err != nil {
return err
}
if _, err := page.Count(); err != nil {
return err
}
result++
}3
C exports: stardust_db_rows_next, stardust_result_take_document, stardust_result_error, stardust_result_release, stardust_document_root, stardust_document_read_many, stardust_document_release
Rows.AllPages
rows.all_pages() reads every remaining page into one owned array document.
rows.all_pages() eagerly reads all remaining pages before returning one owned array document.
- The document contains every remaining row in order, not an array of page documents.
- Pages already read from the cursor are excluded.
- This operation is not lazy: memory grows with the full remaining result.
- Use pages to process one page at a time.
- It copies rows through a native builder, preserving typed numbers, member order and duplicate keys, and closes each intermediate page.
- The caller closes the returned document and the rows cursor.
- On failure, it releases the partial result and reports the error.
func (r *Rows) AllPages() (*Document, error)- Concurrency: Other calls can overlap this call, except the release of a handle that this call uses.
- Ownership: The caller owns the returned handle and releases it.
Errors
| Status | When |
|---|---|
StatusEvaluationFailed | a page does not render |
StatusClosed | the rows is closed |
StatusOutOfMemory | native memory is exhausted |
Examples
Read all remaining rows into one document
queryText holds this document:
find [?name]
where [[?e name ?name]]
orderBy [?name]
definition, err := stardust.Parse(queryText, stardust.DUST)
if err != nil {
return err
}
defer definition.Close()
query, err := db.Query(definition)
if err != nil {
return err
}
defer query.Close()
rows, err := query.Run(nil, stardust.RunOptions{PageSize: 1}, nil)
if err != nil {
return err
}
defer rows.Close()
result, err := rows.AllPages()
if err != nil {
return err
}
defer result.Close()[{name Ada} {name Bob} {name Cy}]C exports: stardust_db_rows_next, stardust_result_take_document, stardust_result_error, stardust_result_release, stardust_document_count, stardust_document_read_many, stardust_document_i64, stardust_document_f64, stardust_document_release, stardust_document_builder_create, stardust_document_builder_add_many, stardust_document_builder_seal, stardust_document_builder_release
Rows.Close
Release the rows handle.
close(handle) releases the handle.
- Do not use it after closure.
- Result documents remain usable after the handle that produces them closes.
func (r *Rows) Close()- Concurrency: This call is the last use of the receiver and ends its ownership.
Examples
Open an inline query and read its first page
queryText holds this document:
find [?name]
where [[?e name ?name]]
orderBy [?name]
definition, err := stardust.Parse(queryText, stardust.DUST)
if err != nil {
return err
}
defer definition.Close()
query, err := db.Query(definition)
if err != nil {
return err
}
defer query.Close()
rows, err := query.Run(nil, stardust.RunOptions{}, nil)
if err != nil {
return err
}
defer rows.Close()
result, err := rows.Next()
if err != nil {
return err
}
defer result.Close()
rows.Close()[{name Ada} {name Bob} {name Cy}]C exports: stardust_db_rows_release
Query.Subscribe
query.subscribe(parameters, options) opens an owned live subscription.
- Parameters apply a merge patch to the declared defaults as in run.
- The call copies the definition and parameters.
- For a stored path, a positive
options.as_ofselects the historical definition. - Later definition edits do not affect the subscription.
Options use as_of and max_cost.
- The call ignores
page_size.
func (q *Query) Subscribe(parameters *Document, options RunOptions) (*Subscription, error)- Concurrency: Other calls can overlap this call, except the release of a handle that this call uses.
- Ownership: The caller owns the returned handle and releases it.
Parameters
| Parameter | Type | Ownership | Default | Meaning |
|---|---|---|---|---|
parameters | *Document | Borrowed for the call | Absent means no supplied parameters | Named values bound for this execution. |
options | RunOptions | Value | Required options record. See field defaults | The operation's options record. See its field defaults. |
Errors
| Status | When |
|---|---|
StatusInvalidDefinition | the query or its callable definitions are invalid |
StatusInvalidArgument | the parameters or subscription options are invalid |
StatusClosed | the query is closed |
StatusOutOfMemory | native memory is exhausted |
Examples
query/subscribe
queryText holds this document:
find [?name]
where [[?e name ?name]]
orderBy [?name]
definition, err := stardust.Parse(queryText, stardust.DUST)
if err != nil {
return err
}
defer definition.Close()
query, err := db.Query(definition)
if err != nil {
return err
}
defer query.Close()
subscription, err := query.Subscribe(nil, stardust.RunOptions{})
if err != nil {
return err
}
defer subscription.Close()
event, err := subscription.Next(context.Background(), 0)
if err != nil {
return err
}
result := event.Result
defer result.Close()[{name Ada} {name Bob} {name Cy}]Read the complete initial subscription event
queryText holds this document:
find [?name]
where [[?e name ?name]]
orderBy [?name]
definition, err := stardust.Parse(queryText, stardust.DUST)
if err != nil {
return err
}
defer definition.Close()
query, err := db.Query(definition)
if err != nil {
return err
}
defer query.Close()
subscription, err := query.Subscribe(nil, stardust.RunOptions{})
if err != nil {
return err
}
defer subscription.Close()
result, err := subscription.Next(context.Background(), 0)
if err != nil {
return err
}
defer result.Result.Close(){sequence 1
superseded 0
transaction 4
result [{name Ada} {name Bob} {name Cy}]}C exports: stardust_db_query_subscribe, stardust_db_subscription_error
Subscription.Next
Wait for the next live event.
rows.next() returns an owned array document with the next page.
- An empty array ends the cursor.
- A page outlives the rows, query and database.
subscription.next(max_wait) returns the next live event with sequence, superseded, transaction and an owned result document.
- Event 1 is the initial result.
- The superseded field counts intermediate computed results skipped since this subscription's previous event.
- Its first event always has 0.
- Each delivered result is a full replacement.
- Consumers replace their previous view with this result.
Identical subscriptions share computed results.
- If another consumer computes two newer results before this consumer calls next, this consumer receives the latest with superseded 1.
- One rerun can include several commits.
- Thus, superseded counts neither commits nor changed rows.
- The sequence field counts delivered events.
- It advances by one even when the subscription skips results.
The max_wait argument uses the host duration type.
- The binding gives it to one native call as 100-ns ticks.
- Zero polls.
- A positive wait returns when an event exists, or returns no event at the deadline.
- A representable negative wait reports
invalid_argument. - Bindings do not divide the wait into shorter waits.
Cancel, close and database close wake a blocked next immediately.
- The precision of a timed deadline depends on the platform.
- Windows rounds it to milliseconds.
After cancel or close, the subscription reports cancelled.
- After database close, it reports closed.
- A failed rerun is terminal.
- Every later call reports that failure.
func (s *Subscription) Next(ctx context.Context, maxWait time.Duration) (*Event, error)- Concurrency: Other calls can overlap this call, except the release of a handle that this call uses.
Parameters
| Parameter | Type | Ownership | Default | Meaning |
|---|---|---|---|---|
ctx | context.Context | Value | Required | Context controlling cancellation of the call. |
maxWait | time.Duration | Value | Required | The maximum wait for the next event, as a native duration. |
Errors
| Status | When |
|---|---|
StatusInvalidArgument | max_wait is negative |
StatusCancelled | the subscription is cancelled or closed |
StatusEvaluationFailed | a rerun of the query failed. Every later call reports this failure |
StatusClosed | the subscription is closed |
StatusOutOfMemory | native memory is exhausted |
Examples
subscription/next
queryText holds this document:
find [?name]
where [[?e name ?name]]
orderBy [?name]
definition, err := stardust.Parse(queryText, stardust.DUST)
if err != nil {
return err
}
defer definition.Close()
query, err := db.Query(definition)
if err != nil {
return err
}
defer query.Close()
subscription, err := query.Subscribe(nil, stardust.RunOptions{})
if err != nil {
return err
}
defer subscription.Close()
event, err := subscription.Next(context.Background(), 0)
if err != nil {
return err
}
result := event.Result
defer result.Close()[{name Ada} {name Bob} {name Cy}]C exports: stardust_db_subscription_next, stardust_db_subscription_error, stardust_document_release
Subscription.All
subscription.events() delivers events in order until the subscription is cancelled, closes or fails.
- It waits with no deadline between events.
- The consumer owns and closes each result.
- Cancellation and closure end the iteration without an error.
- A failed rerun is reported once, and then the iteration ends.
- Leaving the iteration early cancels the subscription; the subscription still needs close.
func (s *Subscription) All(ctx context.Context) iter.Seq2[*Event, error]- Concurrency: Other calls can overlap this call, except the release of a handle that this call uses.
Parameters
| Parameter | Type | Ownership | Default | Meaning |
|---|---|---|---|---|
ctx | context.Context | Value | Required | Context controlling cancellation of the call. |
Errors
Cancellation and closure end iteration. The iteration reports other terminal failures.
| Status | When |
|---|---|
StatusEvaluationFailed | a rerun of the query failed |
StatusOutOfMemory | native memory is exhausted |
Examples
subscription/events
queryText holds this document:
find [?name]
where [[?e name ?name]]
orderBy [?name]
definition, err := stardust.Parse(queryText, stardust.DUST)
if err != nil {
return err
}
defer definition.Close()
query, err := db.Query(definition)
if err != nil {
return err
}
defer query.Close()
subscription, err := query.Subscribe(nil, stardust.RunOptions{})
if err != nil {
return err
}
defer subscription.Close()
var result *stardust.Document
for event, err := range subscription.All(context.Background()) {
if err != nil {
return err
}
result = event.Result
break
}
defer result.Close()[{name Ada} {name Bob} {name Cy}]C exports: stardust_db_subscription_next, stardust_db_subscription_error
Subscription.Cancel
subscription.cancel() ends the subscription.
- Any thread can call it.
- Each blocked next returns cancelled immediately, and later calls also report cancelled.
- A second cancel has no effect.
- The subscription still needs close, which cancels, waits for active calls and releases the handle.
func (s *Subscription) Cancel()- Concurrency: Other calls can overlap this call, except the release of a handle that this call uses.
Examples
subscription/cancel
queryText holds this document:
find [?name]
where [[?e name ?name]]
orderBy [?name]
definition, err := stardust.Parse(queryText, stardust.DUST)
if err != nil {
return err
}
defer definition.Close()
query, err := db.Query(definition)
if err != nil {
return err
}
defer query.Close()
subscription, err := query.Subscribe(nil, stardust.RunOptions{})
if err != nil {
return err
}
defer subscription.Close()
event, err := subscription.Next(context.Background(), 0)
if err != nil {
return err
}
subscription.Cancel()
result := event.Result
defer result.Close()[{name Ada} {name Bob} {name Cy}]C exports: stardust_db_subscription_cancel
Subscription.Close
Release the subscription handle.
close(handle) releases the handle.
- Do not use it after closure.
- Result documents remain usable after the handle that produces them closes.
func (s *Subscription) Close()- Concurrency: This call is the last use of the receiver and ends its ownership.
Examples
subscription/close
queryText holds this document:
find [?name]
where [[?e name ?name]]
orderBy [?name]
definition, err := stardust.Parse(queryText, stardust.DUST)
if err != nil {
return err
}
defer definition.Close()
query, err := db.Query(definition)
if err != nil {
return err
}
defer query.Close()
subscription, err := query.Subscribe(nil, stardust.RunOptions{})
if err != nil {
return err
}
defer subscription.Close()
event, err := subscription.Next(context.Background(), 0)
if err != nil {
return err
}
result := event.Result
defer result.Close()
subscription.Close()[{name Ada} {name Bob} {name Cy}]C exports: stardust_db_subscription_release
Mutation.Run
Run the mutation and return commit information.
handle.run(parameters, options) runs a query or mutation.
- Parameters apply a JSON merge patch (RFC 7396) to the declared defaults.
- Omitted parameters keep their defaults.
- Absent parameters have the same effect as an empty object.
- Objects merge recursively.
- Other values replace the defaults, including tagged values such as {#utc …}.
A name matches with or without its leading ?.
- A null parameter has no value, so the run fails with missing_parameter.
Query runs return owned rows.
- Mutation runs return commit information.
- Options include
as_of,max_costand querypage_size. - The
as_ofoption selects a historical stored definition.
func (m *Mutation) Run(parameters *Document, options RunOptions, explain *MutationExplain) (Commit, error)- Concurrency: Other calls can overlap this call, except the release of a handle that this call uses.
Parameters
| Parameter | Type | Ownership | Default | Meaning |
|---|---|---|---|---|
parameters | *Document | Borrowed for the call | Absent means no supplied parameters | Named values bound for this execution. |
options | RunOptions | Value | Required options record. See field defaults | The operation's options record. See its field defaults. |
explain | *MutationExplain | Caller-owned output | Absent skips explain output | Optional explain output. This record contains explain output for mutation run. |
Errors
| Status | When |
|---|---|
StatusInvalidDefinition | the mutation selection or definition is invalid |
StatusInvalidArgument | the parameters or run options are invalid |
StatusSchemaViolation | the write breaks a schema |
StatusConflict | concurrent writes prevent the commit |
StatusRejected | a mutation target or write guard refuses the write |
StatusEvaluationFailed | the mutation fails |
StatusClosed | the mutation is closed |
StatusOutOfMemory | native memory is exhausted |
Examples
mutation/run
birthdayText holds this document:
query {find [?e]
where [[?e name Ada]]}
patch {?e {age 37}}
source, err := stardust.Parse(birthdayText, stardust.DUST)
if err != nil {
return err
}
defer source.Close()
mutation, err := db.Mutation(source)
if err != nil {
return err
}
defer mutation.Close()
result, err := mutation.Run(nil, stardust.RunOptions{}, nil)
if err != nil {
return err
}{status committed
transaction 5
facts 1
committed_at 17915443416714906
ids {}}Explain mutation execution
birthdayText holds this document:
query {find [?e]
where [[?e name Ada]]}
patch {?e {age 37}}
source, err := stardust.Parse(birthdayText, stardust.DUST)
if err != nil {
return err
}
defer source.Close()
mutation, err := db.Mutation(source)
if err != nil {
return err
}
defer mutation.Close()
var result stardust.MutationExplain
if _, err := mutation.Run(nil, stardust.RunOptions{}, &result); err != nil {
return err
}{load_definition {cpu 343
wall 348
arena_bytes 2304}
parameters {cpu 4
wall 6
arena_bytes 0}
run {cpu 2019
wall 28517
arena_bytes 24640}
total {cpu 2395
wall 28900
arena_bytes 26944}
arena_capacity 4194304
stages_completed 3
attempts 1}C exports: stardust_db_mutation_run, stardust_db_result_commit_info, stardust_result_error, stardust_result_release
Mutation.Close
Release the mutation handle.
close(handle) releases the handle.
- Do not use it after closure.
- Result documents remain usable after the handle that produces them closes.
func (m *Mutation) Close()- Concurrency: This call is the last use of the receiver and ends its ownership.
Examples
mutation/close
birthdayText holds this document:
query {find [?e]
where [[?e name Ada]]}
patch {?e {age 37}}
source, err := stardust.Parse(birthdayText, stardust.DUST)
if err != nil {
return err
}
defer source.Close()
mutation, err := db.Mutation(source)
if err != nil {
return err
}
defer mutation.Close()
result, err := mutation.Run(nil, stardust.RunOptions{}, nil)
if err != nil {
return err
}
mutation.Close(){status committed
transaction 5
facts 1
committed_at 17915443416384677
ids {}}C exports: stardust_db_mutation_release
Database.MergePatch
database.merge_patch(patch) applies an entity-keyed patch document in one transaction and returns commit information. Temporary names use #_name and transaction metadata uses #_tx.
func (d *Database) MergePatch(patch *Document, explain *PatchExplain) (Commit, error)- Concurrency: Other calls can overlap this call, except the release of a handle that this call uses.
Parameters
| Parameter | Type | Ownership | Default | Meaning |
|---|---|---|---|---|
patch | *Document | Borrowed for the call | Required | An entity-keyed native patch document for one transaction. Temporary names use #_name. Transaction metadata uses #_tx. |
explain | *PatchExplain | Caller-owned output | Absent skips explain output | Optional explain output. This record contains explain output for merge_patch. |
Errors
| Status | When |
|---|---|
StatusInvalidCommitTime | the #_tx commit time is not later than the last commit |
StatusRejected | the database refuses the patch |
StatusInvalidArgument | the patch is not an entity-keyed object |
StatusClosed | the database is closed |
StatusOutOfMemory | native memory is exhausted |
Examples
database/merge_patch
patchText holds this document:
#_ada {name Ada
role engineer
age 36}
#_bob {name Bob
role engineer
age 41
mentor {#link #_ada}}
#_cy {name Cy
role designer
age 29}
#_tx {author smoke
reason seed}
patch, err := stardust.Parse(patchText, stardust.DUST)
if err != nil {
return err
}
defer patch.Close()
result, err := db.MergePatch(patch, nil)
if err != nil {
return err
}{status committed
transaction 4
facts 12
committed_at 17915443414178231
ids {#_ada 1
#_bob 2
#_cy 3}}Explain patch validation and commit
patchText holds this document:
#_ada {name Ada
role engineer
age 36}
#_bob {name Bob
role engineer
age 41
mentor {#link #_ada}}
#_cy {name Cy
role designer
age 29}
#_tx {author smoke
reason seed}
patch, err := stardust.Parse(patchText, stardust.DUST)
if err != nil {
return err
}
defer patch.Close()
var result stardust.PatchExplain
if _, err := db.MergePatch(patch, &result); err != nil {
return err
}{copy_patch {cpu 399
wall 434
arena_bytes 3080}
commit {cpu 248
wall 15494
arena_bytes 8200}
total {cpu 685
wall 15966
arena_bytes 11294}
arena_capacity 4194304
stages_completed 2}Refuse a metadata-only transaction
patchText holds this document:
#_tx {author x}
patch, err := stardust.Parse(patchText, stardust.DUST)
if err != nil {
return err
}
defer patch.Close()
_, result := db.MergePatch(patch, nil){code invalid
message the write is invalid: check entity ids, field names, values and #_tx (a patch of only #_tx is refused)
path null
field null
entity null
offset null
status rejected}Refuse a repeated commit time
futureText holds this document:
#_d {x 1}
#_tx {stardust/committedAt {#utc 2200-01-01T00:00:00Z}}
patchText holds this document:
#_e {x 2}
#_tx {stardust/committedAt {#utc 2200-01-01T00:00:00Z}}
future, err := stardust.Parse(futureText, stardust.DUST)
if err != nil {
return err
}
defer future.Close()
if _, err := db.MergePatch(future, nil); err != nil {
return err
}
patch, err := stardust.Parse(patchText, stardust.DUST)
if err != nil {
return err
}
defer patch.Close()
_, result := db.MergePatch(patch, nil){code invalid_commit_time
message stardust/committedAt must be strictly newer than the latest commit time
path null
field null
entity null
offset null
status invalid_commit_time}C exports: stardust_db_merge_patch, stardust_db_result_commit_info, stardust_result_error, stardust_result_release
run_options
This record supplies options for query and mutation run. Zero selects each default. Mutations use DB_Write_Options, whose fields are a subset.
| Field | Type | Unit | Range | Meaning |
|---|---|---|---|---|
page_size | uint32 | Count | Host type range | Rows per page. 0 selects the default page size. Queries only. |
max_cost | time.Duration | Host duration (100 ns ticks at the ABI) | Tick range | Thread CPU duration limit. 0 selects the engine’s dynamic budget. |
as_of | int64 | None | Host type range | A positive transaction runs a stored definition as of that transaction. |
commit
This record contains the result of mutation run, merge_patch and patch_definition.
| Field | Type | Unit | Range | Absent | Meaning |
|---|---|---|---|---|---|
status | CommitStatus | None | Host type range | — | — |
transaction | int64 | None | Host type range | — | Zero when nothing was written. |
facts | int64 | Count | Host type range | — | — |
committed_at | time.Time | UTC instant (100 ns ticks since the Unix epoch at the ABI) | Tick range | The zero time.Time | Recorded commit time as a UTC instant. The call measures this value. Independent calls can differ. |
ids | map[string]int64 | None | Host type range | — | Maps each #_name of a merge patch to its entity. |
event
This record contains the result of subscription next.
| Field | Type | Unit | Meaning |
|---|---|---|---|
sequence | int64 | Count | Event number. Event 1 is the initial result. |
superseded | int64 | Count | Intermediate computed results skipped by this subscription since its previous event. Zero for its first event. The delivered result replaces them in full. This value counts neither commits nor changed rows. |
transaction | int64 | None | Transaction the result was computed at. |
result | *Document | None | The full query result. The event owns it and the consumer closes it. |