Exemple #1
0
func TestRecordsQueryTemplate(t *testing.T) {
	db := mem.NewDB()

	creds := make([]map[string]interface{}, 5)
	for i := 0; i < 5; i++ {
		_, c, err := user.Create(db, "username", "password")
		if err != nil {
			t.Fatal("user.Create error: %s", err)
		}

		m := make(map[string]interface{})
		transfer.TransferAttrs(c, &m)
		creds[i] = m
	}
	s := &records.QueryData{
		Model:   models.Metis[models.CredentialKind],
		Records: creds,
	}

	var b bytes.Buffer
	if err := records.QueryTemplate.Execute(&b, s); err != nil {
		t.Fatalf("template.Execute error: %s", err)
	}

	o := b.String()
	t.Logf("TemplateOutput:\n%s", o)

	if got, want := strings.Contains(o, "username"), true; got != want {
		t.Errorf("strings.Contains(\"username\"): got %t, want %t", got, want)
	}
	if got, want := strings.Contains(o, "password"), true; got != want {
		t.Errorf("strings.Contains(\"password\"): got %t, want %t", got, want)
	}
}
Exemple #2
0
// execute retrieves the records matching a *query, which the user can read, and marshals them to attr maps.
//
// Errors:
//		- db.Query error
//		- access.CanRead error
//		- iter.Close error
func execute(db data.DB, u *models.User, q *query) ([]map[string]interface{}, error) {
	rs := make([]map[string]interface{}, 0)

	iter, err := db.Query(q.Kind).Limit(q.Limit).Batch(q.Batch).Skip(q.Skip).Select(q.Select).Order(q.Order...).Execute()
	if err != nil {
		return nil, err
	}

	m := models.ModelFor(q.Kind)
	for iter.Next(m) {
		ok, err := access.CanRead(db, u, m)

		if err != nil {
			return nil, err
		}

		if !ok {
			continue
		}

		temp := make(map[string]interface{})
		transfer.TransferAttrs(m, &temp)
		rs = append(rs, temp)
		m = models.ModelFor(q.Kind)
	}

	if err := iter.Close(); err != nil {
		return nil, err
	}

	return rs, nil
}
Exemple #3
0
Fichier : db.go Projet : elos/gaia
func (db *DB) Changes() *chan *data.Change {
	ch := make(chan *data.Change)

	go func() {
		// setup Params
		wsURL := db.recordChangesURL(url.Values{
			"public":  []string{db.Username},
			"private": []string{db.Password},
		})

		ws, err := websocket.Dial(wsURL, "", db.URL)
		if err != nil {
			log.Print("FAILED TO CONNECT TO GAIA")
			close(ch)
			return
		}
		defer ws.Close()

		var change transfer.ChangeTransport
		for {
			if err := websocket.JSON.Receive(ws, &change); err != nil {
				if err == io.EOF {
					close(ch)
					return
				}
				close(ch)
				return
			}

			m := models.ModelFor(change.RecordKind)
			transfer.TransferAttrs(change.Record, m)

			ch <- data.NewChange(change.ChangeKind, m)
		}
	}()

	return &ch
}
Exemple #4
0
Fichier : db.go Projet : elos/gaia
func (db *DB) query(q *query) (data.Iterator, error) {
	url := db.recordQueryURL(url.Values{
		"kind":  []string{q.kind.String()},
		"skip":  []string{fmt.Sprintf("%d", q.skip)},
		"limit": []string{fmt.Sprintf("%d", q.limit)},
		"batch": []string{fmt.Sprintf("%d", q.batch)},
		"order": q.order,
	})

	resp, err := db.postJSON(url, q.attrs)
	if err != nil {
		return nil, err
	}

	switch resp.StatusCode {
	case http.StatusBadRequest:
		log.Print("gaia db bad request")
		fallthrough
	case http.StatusInternalServerError:
		return nil, data.ErrNoConnection
	case http.StatusUnauthorized:
		return nil, data.ErrAccessDenial
	case http.StatusOK:
		defer resp.Body.Close()
		body, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			return nil, err
		}

		var resultsUntyped []*data.AttrMap

		if err := json.Unmarshal(body, &resultsUntyped); err != nil {
			return nil, err
		}

		var results []data.Record

		for _, attrs := range resultsUntyped {
			r := models.ModelFor(q.kind)

			if err := transfer.TransferAttrs(attrs, r); err != nil {
				return nil, err
			}

			results = append(results, r)
		}

		out := make(chan data.Record)

		// cache results in another goroutine
		go func() {
			// read them off
			for _, r := range results {
				out <- r
			}
			close(out)
		}()

		return mem.Iter(out), nil
	default:
		log.Printf("Unexpected status code: %d", resp.StatusCode)
		return nil, data.ErrNoConnection
	}

	return nil, nil
}