good morning!!!!

Skip to content
Snippets Groups Projects
Commit b51c740a authored by José Carlos Nieto's avatar José Carlos Nieto
Browse files

Adding Relate and RelateAll plus more examples, still lacks documentation.

parent f25a32f3
Branches
Tags
No related merge requests found
......@@ -29,9 +29,11 @@ type Or []interface{}
type Sort map[string] interface{}
type Modify map[string] interface{}
type Relate map[string] interface{}
type On []interface{}
type Relate map[string] On
type RelateAll map[string] On
type Multi bool
type CountFlag bool
......
......@@ -28,8 +28,10 @@ import (
"reflect"
"time"
"net/url"
"regexp"
"launchpad.net/mgo"
"launchpad.net/mgo/bson"
. "github.com/xiam/gosexy"
)
type MongoDB struct {
......@@ -376,6 +378,27 @@ func (c *MongoDBCollection) FindAll(terms ...interface{}) []Item {
var items []Item
var result []interface {}
var relate interface {}
var relateAll interface {}
var itop int
// Analyzing
itop = len(terms)
for i := 0; i < itop; i++ {
term := terms[i]
switch term.(type) {
case Relate: {
relate = term.(Relate)
}
case RelateAll: {
relateAll = term.(RelateAll)
}
}
}
// Retrieving data
q := c.Invoke("BuildQuery", terms)
......@@ -383,14 +406,107 @@ func (c *MongoDBCollection) FindAll(terms ...interface{}) []Item {
p.All(&result)
itop := len(result)
var relations []Tuple
// This query is related to other collections.
if relate != nil {
for rname, rterms := range relate.(Relate) {
rcollection := c.parent.Collection(rname)
ttop := len(rterms)
for t := ttop - 1; t >= 0; t-- {
rterm := rterms[t]
switch rterm.(type) {
case Collection: {
rcollection = rterm.(Collection)
}
}
}
relations = append(relations, Tuple { "all": false, "name": rname, "collection": rcollection, "terms": rterms, })
}
}
if relateAll != nil {
for rname, rterms := range relateAll.(RelateAll) {
rcollection := c.parent.Collection(rname)
ttop := len(rterms)
for t := ttop - 1; t >= 0; t-- {
rterm := rterms[t]
switch rterm.(type) {
case Collection: {
rcollection = rterm.(Collection)
}
}
}
relations = append(relations, Tuple { "all": true, "name": rname, "collection": rcollection, "terms": rterms, })
}
}
var term interface{}
jtop := len(relations)
itop = len(result)
items = make([]Item, itop)
for i := 0; i < itop; i++ {
item := Item{}
// Default values.
for key, val := range result[i].(bson.M) {
item[key] = val
}
// Querying relations
for j := 0; j < jtop; j++ {
relation := relations[j]
terms := []interface{}{}
ktop := len(relation["terms"].(On))
for k := 0; k < ktop; k++ {
//term = tcopy[k]
term = relation["terms"].(On)[k]
switch term.(type) {
// Just waiting for Where statements.
case Where: {
for wkey, wval := range term.(Where) {
//if reflect.TypeOf(wval).Kind() == reflect.String { // does not always work.
if reflect.TypeOf(wval).Name() == "string" {
// Matching dynamic values.
matched, _ := regexp.MatchString("\\{.+\\}", wval.(string))
if matched {
// Replacing dynamic values.
kname := strings.Trim(wval.(string), "{}")
term = Where { wkey : item[kname] }
}
}
}
}
}
terms = append(terms, term)
}
// Executing external query.
if relation["all"] == true {
value := relation["collection"].(*MongoDBCollection).Invoke("FindAll", terms)
item[relation["name"].(string)] = value[0].Interface().([]Item)
} else {
value := relation["collection"].(*MongoDBCollection).Invoke("Find", terms)
item[relation["name"].(string)] = value[0].Interface().(Item)
}
}
// Appending to results.
items[i] = item
}
......
package db
import (
//. "github.com/xiam/gosexy"
"fmt"
"math/rand"
"github.com/kr/pretty"
"testing"
)
......@@ -158,12 +158,12 @@ func TestPopulate(t *testing.T) {
db.Use("test")
states := []string { "Alaska", "Alabama", "Cancún" }
places := []string { "Alaska", "Nebraska", "Alaska", "Acapulco", "Rome", "Singapore", "Alabama", "Cancún" }
for i = 0; i < len(states); i++ {
db.Collection("states").Append(Item {
for i = 0; i < len(places); i++ {
db.Collection("places").Append(Item {
"code_id": i,
"name": states[i],
"name": places[i],
})
}
......@@ -180,11 +180,22 @@ func TestPopulate(t *testing.T) {
})
}
// Belongs to one State.
// Lives in
db.Collection("people").Update(
Where { "_id": person["_id"] },
Set { "state_code_id": int( rand.Float32() * float32(len(states)) ) },
Set { "place_code_id": int( rand.Float32() * float32(len(places)) ) },
)
// Has visited
for k := 0; k < 3; k++ {
place := db.Collection("places").Find(Where {
"code_id": int( rand.Float32() * float32(len(places)) ),
})
db.Collection("visits").Append(Item {
"place_id": place["_id"],
"person_id": person["_id"],
})
}
}
}
......@@ -202,17 +213,31 @@ func TestRelation(t *testing.T) {
col := db.Collection("people")
col.FindAll(
result := col.FindAll(
Relate {
"lives_in": On {
db.Collection("places"),
Where { "code_id": "{place_code_id}" },
},
},
RelateAll {
"has_children": On {
db.Collection("children"),
Where { "parent_id": "{_id}" },
},
"has_visited": On {
db.Collection("visits"),
Where { "person_id": "{_id}" },
Relate {
"state": On {
db.Collection("states"),
Where { "{this}.code_id": "{that}.state_code_id" },
"place": On {
db.Collection("places"),
Where { "_id": "{place_id}" },
},
},
"children": On {
Where { "{this}.parent_id": "{that}._id" },
Limit(4),
},
},
)
fmt.Printf("%# v\n", pretty.Formatter(result))
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment