EdgeDB Go Driver
Package edgedb is the official Go EdgeDB driver. https://www.edgedb.com
Typical usage looks like this:
package mainimport ("context""log""github.com/edgedb/edgedb-go")func main() {ctx := context.Background()client, err := edgedb.CreateClient(ctx, edgedb.Options{})if err != nil {log.Fatal(err)}defer client.Close()var (age int64 = 21users []struct {ID edgedb.UUID `edgedb:"id"`Name string `edgedb:"name"`})query := "SELECT User{name} FILTER .age = <int64>$0"err = client.Query(ctx, query, &users, age)...}
You can also connect to a database using a DSN:
url := "edgedb://edgedb@localhost/edgedb"client, err := edgedb.CreateClientDSN(ctx, url, opts)
Or you can use Option fields.
opts := edgedb.Options{Database: "edgedb",User: "edgedb",Concurrency: 4,}client, err := edgedb.CreateClient(ctx, opts)
# Errors
edgedb never returns underlying errors directly. If you are checking for things like context expiration use errors.Is() or errors.As().
err := client.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 := client.Query(...)var edbErr edgedb.Errorif 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 []anytypearray<anytype> []anytypetuple structnamed tuple structObject structbool bool, edgedb.OptionalBoolbytes []byte, edgedb.OptionalBytesstr string, edgedb.OptionalStranyenum string, edgedb.OptionalStrdatetime time.Time, edgedb.OptionalDateTimecal::local_datetime edgedb.LocalDateTime,edgedb.OptionalLocalDateTimecal::local_date edgedb.LocalDate, edgedb.OptionalLocalDatecal::local_time edgedb.LocalTime, edgedb.OptionalLocalTimeduration time.Duration, edgedb.OptionalDurationcal::relative_duraation edgedb.RelativeDuration,edgedb.OptionalRelativeDurationfloat32 float32, edgedb.OptionalFloat32float64 float64, edgedb.OptionalFloat64int16 int16, edgedb.OptionalFloat16int32 int32, edgedb.OptionalInt16int64 int64, edgedb.OptionalInt64uuid edgedb.UUID, edgedb.OptionalUUIDjson []byte, edgedb.OptionalBytesbigint *big.Int, edgedb.OptionalBigIntdecimal user defined (see Custom Marshalers)
Shape fields that are not required must use optional types for receiving query results. The edgedb.Optional struct can be embedded to make structs optional.
type User Struct {edgedb.OptionalEmail string `edgedb:"email"`}var result Usererr := client.QuerySingle(ctx, `SELECT User { email } LIMIT 0`, $result)fmt.Println(result.Missing())// Output: trueerr := client.QuerySingle(ctx, `SELECT User { email } LIMIT 1`, $result)fmt.Println(result.Missing())// Output: false
# Custom Marshalers
Interfaces for user defined marshaler/unmarshalers are documented in the internal/marshal package.
Usage Example
package edgedb_testimport ("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 Example() {opts := edgedb.Options{Concurrency: 4}ctx := context.Background()db, err := edgedb.CreateClientDSN(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.QuerySingle(ctx, `INSERT User {name := <str>$0,dob := <datetime>$1}`, &inserted, "Bob", time.Date(1984, 3, 1, 0, 0, 0, 0, time.UTC))if err != nil {log.Fatal(err)}// Select users.var users []Userargs := 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)}