Golang driver for ArangoDB
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
.gitignore
LICENSE
README.md
aql2.go
arango.go
collection.go
config_test.go
cursor.go
database.go
document.go
edge.go
graph.go
misc.go
model.go go fmt Sep 22, 2014
replication.go
session.go
simple_test.go fix -- simple query, Any and Firt Sep 25, 2014
transaction.go

README.md

aranGO

go get github.com/diegogub/aranGO

Golang driver for ArangoDB.

Here are the things you can do until now:

  • Databases : create
  • Collections : drop, create, list, truncate
  • Documents : save, replace,patch, query (simple query,AQL,Transactions)
  • Edges : Relate documents, save, patch, replace
  • Execute transactions
  • Execute AQL
  • Replication config

Additional Features

Any ideas for the driver or bug fixes please feel free to create a issue or pull-request to dev :)

Documentation

https://gowalker.org/github.com/diegogub/aranGO

Basic Usage

import ara "github.com/diegogub/aranGO"

type DocTest struct {
  ara.Document // Must include arango Document in every struct you want to save id, key, rev after saving it
  Name     string
  Age      int
  Likes    []string
}

Connect and create collections

    //change false to true if you want to see every http request
    //Connect(host, user, password string, log bool) (*Session, error) {
    s,err := ara.Connect("http://localhost:8529","diego","test",false) 
    if err != nil{
        panic(err)
    }

    // CreateDB(name string,users []User) error
    s.CreateDB("test",nil)

    // create Collections test if exist
    if !s.DB("test").ColExist("docs1"){
        // CollectionOptions has much more options, here we just define name , sync
        docs1 := NewCollectionOptions("docs1",true)
        s.DB("test").CreateCollection(docs1)
    }

    if !s.DB("test").ColExist("docs2"){
        docs2 := NewCollectionOptions("docs2",true)
        s.DB("test").CreateCollection(docs2)
    }

    if !s.DB("test").ColExist("ed"){
        edges := NewCollectionOptions("ed",true)
        edges.IsEdge() // set to Edge
        s.DB("test").CreateCollection(edges)
    }

Create and Relate documents

  var d1,d2 DocTest
  d1.Name = "Diego"
  d1.Age = 22
  d1.Likes = []string { "arangodb", "golang", "linux" }
  
  d2.Name = "Facundo"
  d2.Age = 25
  d2.Likes = []string { "php", "linux", "python" }


  err =s.DB("test").Col("docs1").Save(&d1)
  err =s.DB("test").Col("docs1").Save(&d2)
  if err != nil {
    panic(err)
  }

  // could also check error in document
  /*
  if d1.Error {
    panic(d1.Message)
  }
  */

  // update document
  d1.Age = 23
  err =s.DB("test").Col("docs1").Replace(d1.Key,d1)
  if err != nil {
    panic(err)
  }
  
  // Relate documents
  s.DB("test").Col("ed").Relate(d1.Id,d2.Id,map[string]interface{}{ "is" : "friend" })

AQL

// query query 
  q := ara.NewQuery("FOR i in docs1 RETURN i")
  c ,err:=s.DB("test").Execute(q)
  if err != nil {
    panic(err)
  }
  var doc DocTest

  for c.FetchOne(&doc){
    log.Println(doc)
  }

Transactions

// saving document with transaction
func TranSave(db *ara.Database,doc interface{},col string,counter string) (*ara.Transaction,error){
  if  col == "" || counter == ""{
    return nil,errors.New("Collection or counter must not be nil")
  }

  write := []string { col }
  q := `function(params){
                var db = require('internal').db;
                try {
                  var c = db.`+col+`.document('c');
                }catch(error){
                  var tmp = db.`+col+`.save( { '_key' : 'c' , '`+counter+`' : 0 });
                }
                var c = db.`+col+`.document('c');
                var co = c.`+counter+` || 0;
                co = co + 1 ;
                // update counter
                db.`+col+`.update(c, { '`+counter+`' : co }) ;
                params.doc.s = -1 * co ;
                params.doc.created = new Date().toISOString();
                var res = db.`+col+`.save(params.doc) ;
                return res._key
        }
  `
  t := ara.NewTransaction(q,write,nil)
  t.Params = map[string]interface{}{ "doc" : doc }

  err := t.Execute(db)

  return t,err
}

Models

To be a model, any struct must implement Modeler Interface.

type Modeler interface {
    // Returns current model key
    GetKey() string
    // Returns collection where I should save the model
    GetCollection() string
    // Error
    GetError() (string, bool)
}

Implement Modeler and add tags to struct..

type DocTest struct {
  ara.Document // Must include arango Document in every struct you want to save id, key, rev after saving it
// required tag for strings.
  Name     string `required:"-"`
// unique tag validate within collection users, if username is unique
  Username string `unique:"users"`
// enum tag checks string value
  Type     string `enum:"A,M,S"`
// Next release I will be implementing some other tags to validate int
and arrays
  Age      int
  Likes    []string
}

func (d *DocTest) GetKey() string{
  return d.Key
}

func (d *DocTest) GetCollection() string {
  return "testcollection"
}

func (d *DocTest) GetError()(string,error){
    // default error bool and messages. Could be any kind of error
    return d.Message,d.Error
}

// pass ArangoDB database as context
ctx, err :=  NewContext(db)

// save model, returns map of errors or empty map
e := ctx.Save(d1)

// check errors, also Error is saved in Context struct
if len(e) > 1 {
  panic(e)
}

// get other document
d2.Key = "d2key"
ctx.Get(d2)
log.Println(d2)

We can implement hooks to execute when saving,updating or deleting model..

// execute before saving
func (d *DocTest) PreSave(c *ara.Context) {
   var e error
  // Any extra validation
  // ......
  // ......
  if e != nil {
    // errors should be set into context struct
    c.Err["presave"] = "failed to validate doctest"
  }

  return
}