blob: e43ab454e31238172055de5c9a3e15dc6932bcfd [file] [log] [blame]
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package nosql defines the wire API for the NoSQL part of Syncbase.
package nosql
import (
"v.io/v23/security/access"
"v.io/v23/services/permissions"
)
// Database represents a collection of Tables. Batches, queries, sync, watch,
// etc. all operate at the Database level.
// Database.Glob operates over Table names.
//
// TODO(sadovsky): Add Watch method.
type Database interface {
// Create creates this Database.
// If perms is nil, we inherit (copy) the App perms.
// Create requires the caller to have Write permission at the App.
Create(perms access.Permissions) error {access.Write}
// Delete deletes this Database.
Delete() error {access.Write}
// BeginBatch creates a new batch. It returns an App-relative name for a
// Database handle bound to this batch. If this Database is already bound to a
// batch, BeginBatch() will fail with ErrBoundToBatch.
//
// Concurrency semantics are documented in model.go.
BeginBatch(bo BatchOptions) (string | error) {access.Read}
// Commit persists the pending changes to the database.
// If this Database is not bound to a batch, Commit() will fail with
// ErrNotBoundToBatch.
Commit() error {access.Read}
// Abort notifies the server that any pending changes can be discarded.
// It is not strictly required, but it may allow the server to release locks
// or other resources sooner than if it was not called.
// If this Database is not bound to a batch, Abort() will fail with
// ErrNotBoundToBatch.
Abort() error {access.Read}
// SetPermissions and GetPermissions are included from the Object interface.
permissions.Object
}
// Table represents a collection of Rows.
// Table.Glob operates over the primary keys of Rows in the Table.
type Table interface {
// Create creates this Table.
// If perms is nil, we inherit (copy) the Database perms.
Create(perms access.Permissions) error {access.Write}
// Delete deletes this Table.
Delete() error {access.Write}
// DeleteRowRange deletes all rows in the given range. If the last row that is
// covered by a prefix from SetPermissions is deleted, that (prefix, perms)
// pair is removed. If end is "", all rows with keys >= start are included.
// TODO(sadovsky): Automatic GC interacts poorly with sync. Revisit this API.
DeleteRowRange(start, end string) error {access.Write}
// Scan returns all rows in the given range. The returned stream reads from a
// consistent snapshot taken at the time of the Scan RPC. If end is "", all
// rows with keys >= start are included.
Scan(start, end string) stream<_, KeyValue> error {access.Read}
// SetPermissions sets the permissions for all current and future rows with
// the given prefix. If the prefix overlaps with an existing prefix, the
// longest prefix that matches a row applies. For example:
// SetPermissions(ctx, Prefix("a/b"), perms1)
// SetPermissions(ctx, Prefix("a/b/c"), perms2)
// The permissions for row "a/b/1" are perms1, and the permissions for row
// "a/b/c/1" are perms2.
//
// SetPermissions will fail if called with a prefix that does not match any
// rows.
SetPermissions(prefix string, perms access.Permissions) error {access.Admin}
// GetPermissions returns an array of (prefix, perms) pairs. The array is
// sorted from longest prefix to shortest, so element zero is the one that
// applies to the row with the given key. The last element is always the
// prefix "" which represents the table's permissions -- the array will always
// have at least one element.
GetPermissions(key string) ([]PrefixPermissions | error) {access.Admin}
// DeletePermissions deletes the permissions for the specified prefix. Any
// rows covered by this prefix will use the next longest prefix's permissions
// (see the array returned by GetPermissions).
DeletePermissions(prefix string) error {access.Admin}
}
// Row represents a single row in a Table.
// All access checks are performed against the most specific matching prefix
// permissions in the Table.
// NOTE(sadovsky): Currently we send []byte values over the wire for Get, Put,
// and Scan. If there's a way to avoid encoding/decoding on the server side, we
// can use vdl.Value everywhere without sacrificing performance.
type Row interface {
// Get returns the value for this Row.
Get() ([]byte | error) {access.Read}
// Put writes the given value for this Row.
Put(value []byte) error {access.Write}
// Delete deletes this Row.
Delete() error {access.Write}
}
error (
BoundToBatch() {"en": "bound to batch"}
NotBoundToBatch() {"en": "not bound to batch"}
)