Documentation
¶
Overview ¶
Package db provides the host-side database capability adapter for Vibescript. It exposes a thin Database interface plus the request structs that scripts can call via the db.* methods bound on a script invocation. The top-level vibes package wraps the capability behind a CapabilityAdapter implementation for installation on script calls.
Example ¶
Example shows how to wire a db.Capability into a script invocation via the vibes facade and observe the find dispatch.
package main
import (
"context"
"fmt"
"github.com/mgomes/vibescript/vibes"
"github.com/mgomes/vibescript/vibes/capability/db"
"github.com/mgomes/vibescript/vibes/value"
)
// stubDB returns canned responses for the godoc Examples. Real embedders
// would query an actual database, ORM, or external API.
type stubDB struct{}
func (stubDB) Find(_ context.Context, req db.DBFindRequest) (value.Value, error) {
return value.NewHash(map[string]value.Value{
"id": req.ID,
"name": value.NewString("Ada"),
}), nil
}
func (stubDB) Query(_ context.Context, _ db.DBQueryRequest) (value.Value, error) {
return value.NewArray(nil), nil
}
func (stubDB) Update(_ context.Context, _ db.DBUpdateRequest) (value.Value, error) {
return value.NewBool(true), nil
}
func (stubDB) Sum(_ context.Context, _ db.DBSumRequest) (value.Value, error) {
return value.NewInt(0), nil
}
func (stubDB) Each(_ context.Context, _ db.DBEachRequest) ([]value.Value, error) {
return nil, nil
}
func main() {
engine := vibes.MustNewEngine(vibes.Config{})
script, err := engine.Compile(`def run()
user = users.find("Player", "p-1")
user[:name]
end`)
if err != nil {
fmt.Println("compile:", err)
return
}
result, err := script.Call(context.Background(), "run", nil, vibes.CallOptions{
Capabilities: []vibes.CapabilityAdapter{
vibes.MustNewDBCapability("users", stubDB{}),
},
})
if err != nil {
fmt.Println("call:", err)
return
}
fmt.Println(result.String())
}
Output: Ada
Index ¶
- type Capability
- func (c *Capability) CallEach(exec ExecutionContext, args []value.Value, kwargs map[string]value.Value, ...) (value.Value, error)
- func (c *Capability) CallFind(exec ExecutionContext, args []value.Value, kwargs map[string]value.Value, ...) (value.Value, error)
- func (c *Capability) CallQuery(exec ExecutionContext, args []value.Value, kwargs map[string]value.Value, ...) (value.Value, error)
- func (c *Capability) CallSum(exec ExecutionContext, args []value.Value, kwargs map[string]value.Value, ...) (value.Value, error)
- func (c *Capability) CallUpdate(exec ExecutionContext, args []value.Value, kwargs map[string]value.Value, ...) (value.Value, error)
- func (c *Capability) Contracts() map[string]Contract
- func (c *Capability) Name() string
- type Contract
- type DBEachRequest
- type DBFindRequest
- type DBQueryRequest
- type DBSumRequest
- type DBUpdateRequest
- type Database
- type DatabaseReader
- type DatabaseWriter
- type ExecutionContext
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Capability ¶
type Capability struct {
// contains filtered or unexported fields
}
Capability is the concrete adapter returned by NewCapability. The per-method Call* functions accept an ExecutionContext so the package stays free of a vibes runtime dependency.
func MustNewCapability ¶
func MustNewCapability(name string, db Database) *Capability
MustNewCapability constructs a database capability adapter or panics when name is empty or db is a nil implementation.
Example ¶
package main
import (
"context"
"fmt"
"github.com/mgomes/vibescript/vibes/capability/db"
"github.com/mgomes/vibescript/vibes/value"
)
// stubDB returns canned responses for the godoc Examples. Real embedders
// would query an actual database, ORM, or external API.
type stubDB struct{}
func (stubDB) Find(_ context.Context, req db.DBFindRequest) (value.Value, error) {
return value.NewHash(map[string]value.Value{
"id": req.ID,
"name": value.NewString("Ada"),
}), nil
}
func (stubDB) Query(_ context.Context, _ db.DBQueryRequest) (value.Value, error) {
return value.NewArray(nil), nil
}
func (stubDB) Update(_ context.Context, _ db.DBUpdateRequest) (value.Value, error) {
return value.NewBool(true), nil
}
func (stubDB) Sum(_ context.Context, _ db.DBSumRequest) (value.Value, error) {
return value.NewInt(0), nil
}
func (stubDB) Each(_ context.Context, _ db.DBEachRequest) ([]value.Value, error) {
return nil, nil
}
func main() {
cap := db.MustNewCapability("users", stubDB{})
fmt.Println(cap.Name())
}
Output: users
func NewCapability ¶
func NewCapability(name string, db Database) (*Capability, error)
NewCapability constructs a database capability adapter bound to the provided script-facing name. The returned *Capability holds the per-call dispatchers; package vibes wraps it in a CapabilityAdapter for installation on a script invocation.
Example ¶
package main
import (
"context"
"fmt"
"github.com/mgomes/vibescript/vibes/capability/db"
"github.com/mgomes/vibescript/vibes/value"
)
// stubDB returns canned responses for the godoc Examples. Real embedders
// would query an actual database, ORM, or external API.
type stubDB struct{}
func (stubDB) Find(_ context.Context, req db.DBFindRequest) (value.Value, error) {
return value.NewHash(map[string]value.Value{
"id": req.ID,
"name": value.NewString("Ada"),
}), nil
}
func (stubDB) Query(_ context.Context, _ db.DBQueryRequest) (value.Value, error) {
return value.NewArray(nil), nil
}
func (stubDB) Update(_ context.Context, _ db.DBUpdateRequest) (value.Value, error) {
return value.NewBool(true), nil
}
func (stubDB) Sum(_ context.Context, _ db.DBSumRequest) (value.Value, error) {
return value.NewInt(0), nil
}
func (stubDB) Each(_ context.Context, _ db.DBEachRequest) ([]value.Value, error) {
return nil, nil
}
func main() {
cap, err := db.NewCapability("users", stubDB{})
if err != nil {
fmt.Println("error:", err)
return
}
fmt.Println(cap.Name())
}
Output: users
func (*Capability) CallEach ¶
func (c *Capability) CallEach(exec ExecutionContext, args []value.Value, kwargs map[string]value.Value, block value.Value) (value.Value, error)
CallEach implements the db.each boundary. The host returns the row set up front; the capability charges each row and its bounded data-only copy, then yields the independent snapshot to the script-supplied block.
func (*Capability) CallFind ¶
func (c *Capability) CallFind(exec ExecutionContext, args []value.Value, kwargs map[string]value.Value, block value.Value) (value.Value, error)
CallFind implements the db.find boundary: arg validation, host invocation, and cloning of the host-returned Value so script-side state cannot alias the host's data.
func (*Capability) CallQuery ¶
func (c *Capability) CallQuery(exec ExecutionContext, args []value.Value, kwargs map[string]value.Value, block value.Value) (value.Value, error)
CallQuery implements the db.query boundary.
func (*Capability) CallSum ¶
func (c *Capability) CallSum(exec ExecutionContext, args []value.Value, kwargs map[string]value.Value, block value.Value) (value.Value, error)
CallSum implements the db.sum boundary.
func (*Capability) CallUpdate ¶
func (c *Capability) CallUpdate(exec ExecutionContext, args []value.Value, kwargs map[string]value.Value, block value.Value) (value.Value, error)
CallUpdate implements the db.update boundary.
func (*Capability) Contracts ¶
func (c *Capability) Contracts() map[string]Contract
Contracts returns the boundary validators the runtime should enforce around each db.* builtin. The map keys must match the builtin names bound in the vibes-side adapter so the contract scanner can resolve them.
func (*Capability) Name ¶
func (c *Capability) Name() string
Name returns the script-facing name the capability was bound under.
type Contract ¶
type Contract struct {
ValidateArgs func(args []value.Value, kwargs map[string]value.Value, block value.Value) error
ValidateReturn func(result value.Value) error
// CallValidated runs the method after ValidateArgs has already succeeded.
CallValidated func(exec ExecutionContext, args []value.Value, kwargs map[string]value.Value, block value.Value) (value.Value, error)
}
Contract pairs the boundary validators registered for a single capability method. The runtime adapter converts this into vibes.CapabilityMethodContract when installing the capability.
type DBEachRequest ¶
DBEachRequest captures db.each calls.
type DBFindRequest ¶
DBFindRequest captures db.find calls.
type DBQueryRequest ¶
DBQueryRequest captures db.query calls.
type DBSumRequest ¶
DBSumRequest captures db.sum calls.
type DBUpdateRequest ¶
type DBUpdateRequest struct {
Collection string
ID value.Value
Attributes map[string]value.Value
Options map[string]value.Value
}
DBUpdateRequest captures db.update calls.
type Database ¶
type Database interface {
DatabaseReader
DatabaseWriter
}
Database is the full read/write surface scripts can call. It is satisfied by any type that implements both DatabaseReader and DatabaseWriter, so existing implementations keep compiling unchanged.
type DatabaseReader ¶
type DatabaseReader interface {
Find(ctx context.Context, req DBFindRequest) (value.Value, error)
Query(ctx context.Context, req DBQueryRequest) (value.Value, error)
Sum(ctx context.Context, req DBSumRequest) (value.Value, error)
Each(ctx context.Context, req DBEachRequest) ([]value.Value, error)
}
DatabaseReader exposes the read-only subset of the database capability. Host implementations that should not allow scripts to mutate data can satisfy only this interface and wrap with a writer that returns an error on Update calls.
type DatabaseWriter ¶
type DatabaseWriter interface {
Update(ctx context.Context, req DBUpdateRequest) (value.Value, error)
}
DatabaseWriter exposes the write subset of the database capability.
type ExecutionContext ¶
type ExecutionContext interface {
Context() context.Context
Step() error
CallBlock(block value.Value, args []value.Value) (value.Value, error)
}
ExecutionContext describes the slice of the vibes runtime the db capability calls into. *vibes.Execution satisfies it structurally. Defining the interface here keeps the db package free of an import of vibes and so prevents an import cycle.