edgedb

package module
v0.5.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 22, 2021 License: Apache-2.0 Imports: 33 Imported by: 0

README

The Go driver for EdgeDB

Build Status Join GitHub discussions

Installation

$ go get https://github.com/edgedb/edgedb-go

Basic Usage

Follow the EdgeDB tutorial to get EdgeDB installed and minimally configured.

package main

import (
	"context"
	"fmt"
	"log"

	"github.com/edgedb/edgedb-go"
)

func main() {
	opts := edgedb.Options{
		Database: "edgedb",
		User: "edgedb",
		MinConns: 1,
		MaxConns: 4,
	}

	ctx := context.Background()
	pool, err := edgedb.Connect(ctx, opts)
	if err != nil {
		log.Fatal(err)
	}
	defer pool.Close()

	var result string
	err = pool.QueryOne(ctx, "SELECT 'hello EdgeDB!'", &result)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(result)
}

Development

A local installation of EdgeDB is required to run tests. Download EdgeDB from here or build it manually.

To run the test suite run make test. To run lints make lint.

License

edgedb-go is developed and distributed under the Apache 2.0 license.

Documentation

Overview

Package edgedb is the official Go EdgeDB driver. https://edgedb.com

Typical usage looks like this:

import (
    "context"
    "log"

    "github.com/edgedb/edgedb-go"
)

opts := edgedb.Options{
    MinConns: 1,
    MaxConns: 4,
}

func main() {
    ctx := context.Background()
    pool, err := edgedb.ConnectDSN(ctx, "my_instance", opts)
    if err != nil {
        log.Fatal(err)
    }
    defer pool.Close()

    var (
        age int64 = 21
        users []struct{
            ID edgedb.UUID `edgedb:"id"`
            Name string    `edgedb:"name"`
        }
    )

    query := "SELECT User{name} WHERE .age = <int64>$0"
    err = pool.Query(ctx, query, &users, age)
    ...
}

You can also connect to a database using a DSN:

url := "edgedb://edgedb@localhost/edgedb"
pool, err := edgedb.ConnectDSN(ctx, url, opts)

Or you can use Option fields.

opts := edgedb.Options{
    Database: "edgedb",
    User:     "edgedb",
    MinConns: 1,
    MaxConns: 4,
}

pool, err := edgedb.Connect(ctx, opts)

Pooling

Most use cases will benefit from the concurrency safe pool implementation returned from Connect() and ConnectDSN(). Pool.Acquire(), ConnectOne() and ConnectOneDSN() will give you access to a single connection.

Errors

edgedb never returns underlying errors directly. If you are checking for things like context expiration use errors.Is() or errors.As().

err := pool.Query(...)
if errors.Is(err, context.Canceled) { ... }

Most errors returned by the edgedb package will satisfy the edgedb.Error interface which has methods for introspecting.

err := pool.Query(...)

var edbErr edgedb.Error
if errors.As(err, &edbErr) && edbErr.Category(edgedb.NoDataError){
    ...
}

Datatypes

The following list shows the marshal/unmarshal mapping between EdgeDB types and go types:

EdgeDB                Go
---------             ---------
Set                   []anytype
array<anytype>        []anytype
tuple                 []interface{}
named tuple           struct
Object                struct
bool                  bool
bytes                 []byte
str                   string
anyenum               string
datetime              time.Time
cal::local_datetime   edgedb.LocalDateTime
cal::local_date       edgedb.LocalDate
cal::local_time       edgedb.LocalTime
duration              time.Duration
float32               float32
float64               float64
int16                 int16
int32                 int32
int64                 int64
uuid                  edgedb.UUID
json                  []byte
bigint                *big.Int

// not yet implemented in this driver
decimal
Example
// This source file is part of the EdgeDB open source project.
//
// Copyright 2020-present EdgeDB Inc. and the EdgeDB authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"context"
	"fmt"
	"log"
	"time"

	"github.com/edgedb/edgedb-go"
)

type User struct {
	ID   edgedb.UUID `edgedb:"id"`
	Name string      `edgedb:"name"`
	DOB  time.Time   `edgedb:"dob"`
}

func main() {
	opts := edgedb.Options{
		MinConns: 1,
		MaxConns: 4,
	}

	ctx := context.Background()
	db, err := edgedb.ConnectDSN(ctx, "edgedb://edgedb@localhost/test", opts)
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()

	// create a user object type.
	err = db.Execute(ctx, `
		CREATE TYPE User {
			CREATE REQUIRED PROPERTY name -> str;
			CREATE PROPERTY dob -> datetime;
		}
	`)
	if err != nil {
		log.Fatal(err)
	}

	// Insert a new user.
	var inserted struct{ id edgedb.UUID }
	err = db.QueryOne(ctx, `
		INSERT User {
			name := <str>$1,
			dob := <datetime>$2
		}
	`, inserted, "Bob", time.Date(1984, 3, 1, 0, 0, 0, 0, time.UTC))
	if err != nil {
		log.Fatal(err)
	}

	// Select users.
	var users []User
	args := map[string]interface{}{"name": "Bob"}
	query := "SELECT User {name, dob} FILTER .name = <str>$name"
	err = db.Query(ctx, query, &users, args)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(users)
}

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	// NewLocalDateTime returns a new LocalDateTime
	NewLocalDateTime = edgedbtypes.NewLocalDateTime

	// NewLocalDate returns a new LocalDate
	NewLocalDate = edgedbtypes.NewLocalDate

	// NewLocalTime returns a new LocalTime
	NewLocalTime = edgedbtypes.NewLocalTime
)

Functions

This section is empty.

Types

type Action

type Action func(context.Context, Tx) error

Action is work to be done in a transaction.

type Conn

type Conn interface {
	Executor
	Trier

	// Close closes the connection.
	// Connections are not usable after they are closed.
	Close() error
}

Conn is a single connection to a server. Conn implementations are not safe for concurrent use. Pool should be preferred over Conn for most use cases.

func ConnectOne

func ConnectOne(ctx context.Context, opts Options) (Conn, error)

ConnectOne establishes a connection to an EdgeDB server.

func ConnectOneDSN

func ConnectOneDSN(
	ctx context.Context,
	dsn string,
	opts Options,
) (Conn, error)

ConnectOneDSN establishes a connection to an EdgeDB server.

dsn is either an instance name https://www.edgedb.com/docs/clients/00_python/instances/#edgedb-instances or it specifies a single string in the following format:

edgedb://user:password@host:port/database?option=value.

The following options are recognized: host, port, user, database, password.

type Duration

type Duration = edgedbtypes.Duration

Duration representing a span of time.

type Error

type Error interface {
	Error() string
	Unwrap() error

	// HasTag returns true if the error is marked with the supplied tag.
	HasTag(ErrorTag) bool

	// Category returns true if the error is in the provided category.
	Category(ErrorCategory) bool
}

Error is the error type returned from edgedb.

type ErrorCategory

type ErrorCategory string

ErrorCategory values represent EdgeDB's error types.

const (
	InternalServerError                    ErrorCategory = "errors::InternalServerError"
	UnsupportedFeatureError                ErrorCategory = "errors::UnsupportedFeatureError"
	ProtocolError                          ErrorCategory = "errors::ProtocolError"
	BinaryProtocolError                    ErrorCategory = "errors::BinaryProtocolError"
	UnsupportedProtocolVersionError        ErrorCategory = "errors::UnsupportedProtocolVersionError"
	TypeSpecNotFoundError                  ErrorCategory = "errors::TypeSpecNotFoundError"
	UnexpectedMessageError                 ErrorCategory = "errors::UnexpectedMessageError"
	InputDataError                         ErrorCategory = "errors::InputDataError"
	ResultCardinalityMismatchError         ErrorCategory = "errors::ResultCardinalityMismatchError"
	CapabilityError                        ErrorCategory = "errors::CapabilityError"
	UnsupportedCapabilityError             ErrorCategory = "errors::UnsupportedCapabilityError"
	DisabledCapabilityError                ErrorCategory = "errors::DisabledCapabilityError"
	QueryError                             ErrorCategory = "errors::QueryError"
	InvalidSyntaxError                     ErrorCategory = "errors::InvalidSyntaxError"
	EdgeQLSyntaxError                      ErrorCategory = "errors::EdgeQLSyntaxError"
	SchemaSyntaxError                      ErrorCategory = "errors::SchemaSyntaxError"
	GraphQLSyntaxError                     ErrorCategory = "errors::GraphQLSyntaxError"
	InvalidTypeError                       ErrorCategory = "errors::InvalidTypeError"
	InvalidTargetError                     ErrorCategory = "errors::InvalidTargetError"
	InvalidLinkTargetError                 ErrorCategory = "errors::InvalidLinkTargetError"
	InvalidPropertyTargetError             ErrorCategory = "errors::InvalidPropertyTargetError"
	InvalidReferenceError                  ErrorCategory = "errors::InvalidReferenceError"
	UnknownModuleError                     ErrorCategory = "errors::UnknownModuleError"
	UnknownLinkError                       ErrorCategory = "errors::UnknownLinkError"
	UnknownPropertyError                   ErrorCategory = "errors::UnknownPropertyError"
	UnknownUserError                       ErrorCategory = "errors::UnknownUserError"
	UnknownDatabaseError                   ErrorCategory = "errors::UnknownDatabaseError"
	UnknownParameterError                  ErrorCategory = "errors::UnknownParameterError"
	SchemaError                            ErrorCategory = "errors::SchemaError"
	SchemaDefinitionError                  ErrorCategory = "errors::SchemaDefinitionError"
	InvalidDefinitionError                 ErrorCategory = "errors::InvalidDefinitionError"
	InvalidModuleDefinitionError           ErrorCategory = "errors::InvalidModuleDefinitionError"
	InvalidLinkDefinitionError             ErrorCategory = "errors::InvalidLinkDefinitionError"
	InvalidPropertyDefinitionError         ErrorCategory = "errors::InvalidPropertyDefinitionError"
	InvalidUserDefinitionError             ErrorCategory = "errors::InvalidUserDefinitionError"
	InvalidDatabaseDefinitionError         ErrorCategory = "errors::InvalidDatabaseDefinitionError"
	InvalidOperatorDefinitionError         ErrorCategory = "errors::InvalidOperatorDefinitionError"
	InvalidAliasDefinitionError            ErrorCategory = "errors::InvalidAliasDefinitionError"
	InvalidFunctionDefinitionError         ErrorCategory = "errors::InvalidFunctionDefinitionError"
	InvalidConstraintDefinitionError       ErrorCategory = "errors::InvalidConstraintDefinitionError"
	InvalidCastDefinitionError             ErrorCategory = "errors::InvalidCastDefinitionError"
	DuplicateDefinitionError               ErrorCategory = "errors::DuplicateDefinitionError"
	DuplicateModuleDefinitionError         ErrorCategory = "errors::DuplicateModuleDefinitionError"
	DuplicateLinkDefinitionError           ErrorCategory = "errors::DuplicateLinkDefinitionError"
	DuplicatePropertyDefinitionError       ErrorCategory = "errors::DuplicatePropertyDefinitionError"
	DuplicateUserDefinitionError           ErrorCategory = "errors::DuplicateUserDefinitionError"
	DuplicateDatabaseDefinitionError       ErrorCategory = "errors::DuplicateDatabaseDefinitionError"
	DuplicateOperatorDefinitionError       ErrorCategory = "errors::DuplicateOperatorDefinitionError"
	DuplicateViewDefinitionError           ErrorCategory = "errors::DuplicateViewDefinitionError"
	DuplicateFunctionDefinitionError       ErrorCategory = "errors::DuplicateFunctionDefinitionError"
	DuplicateConstraintDefinitionError     ErrorCategory = "errors::DuplicateConstraintDefinitionError"
	DuplicateCastDefinitionError           ErrorCategory = "errors::DuplicateCastDefinitionError"
	QueryTimeoutError                      ErrorCategory = "errors::QueryTimeoutError"
	ExecutionError                         ErrorCategory = "errors::ExecutionError"
	InvalidValueError                      ErrorCategory = "errors::InvalidValueError"
	DivisionByZeroError                    ErrorCategory = "errors::DivisionByZeroError"
	NumericOutOfRangeError                 ErrorCategory = "errors::NumericOutOfRangeError"
	IntegrityError                         ErrorCategory = "errors::IntegrityError"
	ConstraintViolationError               ErrorCategory = "errors::ConstraintViolationError"
	CardinalityViolationError              ErrorCategory = "errors::CardinalityViolationError"
	MissingRequiredError                   ErrorCategory = "errors::MissingRequiredError"
	TransactionError                       ErrorCategory = "errors::TransactionError"
	TransactionSerializationError          ErrorCategory = "errors::TransactionSerializationError"
	TransactionDeadlockError               ErrorCategory = "errors::TransactionDeadlockError"
	ConfigurationError                     ErrorCategory = "errors::ConfigurationError"
	AccessError                            ErrorCategory = "errors::AccessError"
	AuthenticationError                    ErrorCategory = "errors::AuthenticationError"
	ClientError                            ErrorCategory = "errors::ClientError"
	ClientConnectionError                  ErrorCategory = "errors::ClientConnectionError"
	ClientConnectionFailedError            ErrorCategory = "errors::ClientConnectionFailedError"
	ClientConnectionFailedTemporarilyError ErrorCategory = "errors::ClientConnectionFailedTemporarilyError"
	ClientConnectionTimeoutError           ErrorCategory = "errors::ClientConnectionTimeoutError"
	ClientConnectionClosedError            ErrorCategory = "errors::ClientConnectionClosedError"
	InterfaceError                         ErrorCategory = "errors::InterfaceError"
	QueryArgumentError                     ErrorCategory = "errors::QueryArgumentError"
	MissingArgumentError                   ErrorCategory = "errors::MissingArgumentError"
	UnknownArgumentError                   ErrorCategory = "errors::UnknownArgumentError"
	InvalidArgumentError                   ErrorCategory = "errors::InvalidArgumentError"
	NoDataError                            ErrorCategory = "errors::NoDataError"
)

type ErrorTag

type ErrorTag string

ErrorTag is the argument type to Error.HasTag().

const (
	ShouldRetry     ErrorTag = "SHOULD_RETRY"
	ShouldReconnect ErrorTag = "SHOULD_RECONNECT"
)

type Executor

type Executor interface {
	// Execute an EdgeQL command (or commands).
	Execute(context.Context, string) error

	// Query runs a query and returns the results.
	Query(context.Context, string, interface{}, ...interface{}) error

	// QueryOne runs a singleton-returning query and returns its element.
	// If the query executes successfully but doesn't return a result
	// a NoDataError is returned.
	QueryOne(context.Context, string, interface{}, ...interface{}) error

	// QueryJSON runs a query and return the results as JSON.
	QueryJSON(context.Context, string, *[]byte, ...interface{}) error

	// QueryOneJSON runs a singleton-returning query.
	// If the query executes successfully but doesn't have a result
	// a NoDataError is returned.
	QueryOneJSON(context.Context, string, *[]byte, ...interface{}) error
}

Executor allows querying the database.

type LocalDate

type LocalDate = edgedbtypes.LocalDate

LocalDate is a date without a time zone.

type LocalDateTime

type LocalDateTime = edgedbtypes.LocalDateTime

LocalDateTime is a date and time without a time zone.

type LocalTime

type LocalTime = edgedbtypes.LocalTime

LocalTime is a time without a time zone.

type Options

type Options struct {
	// Hosts is a slice of database host addresses as one of the following
	//
	// - an IP address or domain name
	//
	// - an absolute path to the directory
	//   containing the database server Unix-domain socket
	//   (not supported on Windows)
	//
	// If the slice is empty, the following will be tried, in order:
	//
	// - host address(es) parsed from the dsn argument
	//
	// - the value of the EDGEDB_HOST environment variable
	//
	// - on Unix, common directories used for EdgeDB Unix-domain sockets:
	//   "/run/edgedb" and "/var/run/edgedb"
	//
	// - "localhost"
	Hosts []string

	// Ports is a slice of port numbers to connect to at the server host
	// (or Unix-domain socket file extension).
	//
	// Ports may either be:
	//
	// - the same length ans Hosts
	//
	// - a single port to be used all specified hosts
	//
	// - empty indicating the value parsed from the dsn argument
	//   should be used, or the value of the EDGEDB_PORT environment variable,
	//   or 5656 if neither is specified.
	Ports []int

	// User is the name of the database role used for authentication.
	// If not specified, the value parsed from the dsn argument is used,
	// or the value of the EDGEDB_USER environment variable,
	// or the operating system name of the user running the application.
	User string

	// Database is the name of the database to connect to.
	// If not specified, the value parsed from the dsn argument is used,
	// or the value of the EDGEDB_DATABASE environment variable,
	// or the operating system name of the user running the application.
	Database string

	// Password to be used for authentication,
	// if the server requires one. If not specified,
	// the value parsed from the dsn argument is used,
	// or the value of the EDGEDB_PASSWORD environment variable.
	// Note that the use of the environment variable is discouraged
	// as other users and applications may be able to read it
	// without needing specific privileges.
	Password string

	// ConnectTimeout is used when establishing connections in the background.
	ConnectTimeout time.Duration

	// WaitUntilAvailable determines how long to wait
	// to reestablish a connection.
	WaitUntilAvailable time.Duration

	// MinConns determines the minimum number of connections.
	// If MinConns is zero, 1 will be used.
	// Has no effect for single connections.
	MinConns uint

	// MaxConns determines the maximum number of connections.
	// If MaxConns is zero, max(4, runtime.NumCPU()) will be used.
	// Has no effect for single connections.
	MaxConns uint

	// ServerSettings is currently unused.
	ServerSettings map[string]string
}

Options for connecting to an EdgeDB server

type Pool

type Pool interface {
	Executor
	Trier

	// Acquire returns a connection from the pool
	// blocking until a connection is available.
	// Acquired connections must be released to the pool when no longer needed.
	Acquire(context.Context) (PoolConn, error)

	// Close closes all connections in the pool.
	// Calling close blocks until all acquired connections have been released,
	// and returns an error if called more than once.
	Close() error
}

Pool is a connection pool.

func Connect

func Connect(ctx context.Context, opts Options) (Pool, error)

Connect a pool of connections to a server.

func ConnectDSN

func ConnectDSN(ctx context.Context, dsn string, opts Options) (Pool, error)

ConnectDSN connects a pool to a server.

dsn is either an instance name https://www.edgedb.com/docs/clients/00_python/instances/#edgedb-instances or it specifies a single string in the following format:

edgedb://user:password@host:port/database?option=value.

The following options are recognized: host, port, user, database, password.

type PoolConn

type PoolConn interface {
	Executor
	Trier

	// Release the connection back to its pool.
	// Release returns an error if called more than once.
	// A PoolConn is not usable after Release has been called.
	Release() error
}

PoolConn is a pooled connection.

type Trier

type Trier interface {
	// RawTx runs an action in a transaction.
	// If the action returns an error the transaction is rolled back,
	// otherwise it is committed.
	RawTx(context.Context, Action) error

	// RetryingTx does the same as RawTx but retries failed actions
	// if they might succeed on a subsequent attempt.
	RetryingTx(context.Context, Action) error
}

Trier allows trying actions in a transaction.

type Tx

type Tx interface {
	Executor
}

Tx is a transaction.

type UUID

type UUID = edgedbtypes.UUID

UUID a universally unique identifier

Directories

Path Synopsis
edgedb module
internal
cmd/generr command
soc
Package soc has utilities for working with sockets.
Package soc has utilities for working with sockets.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL