Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

https://github.com/diegogub/aranGO

Golang driver for ArangoDB
https://github.com/diegogub/aranGO

aql arango arangodb driver transactions

Last synced: 5 days ago
JSON representation

Golang driver for ArangoDB

Lists

README

        

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
-------------------
* Minimal Models with hooks
* AqlBuilder ( https://gowalker.org/github.com/diegogub/aranGO#AqlStruct , check Filter, it has some nice JSON2AQL filter feature. If you have any suggestion about JSON format and new ideas to improve it feel free to write me or pull-request :P )

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
-----------
~~~~go
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
-----------------------------------
~~~go
//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
---------------------------
~~~go
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
---

~~~go
// 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
------------

~~~go
// 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.

~~~go
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..
~~~go

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..
~~~go
// 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
}
~~~