Пример #1
0
func Count(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Cache-Control", "must-revalidate")
	w.Header().Set("Content-Type", "text/plain")
	var col, q string
	if !Require(w, r, "col", &col) {
		return
	}
	if !Require(w, r, "q", &q) {
		return
	}
	var qJson interface{}
	if err := json.Unmarshal([]byte(q), &qJson); err != nil {
		http.Error(w, fmt.Sprintf("'%v' is not valid JSON.", q), 400)
		return
	}
	V1Sync.RLock()
	defer V1Sync.RUnlock()
	dbcol := V1DB.Use(col)
	if dbcol == nil {
		http.Error(w, fmt.Sprintf("Collection '%s' does not exist.", col), 400)
		return
	}
	queryResult := make(map[uint64]struct{})
	if err := db.EvalQuery(qJson, dbcol, &queryResult); err != nil {
		http.Error(w, fmt.Sprint(err), 400)
		return
	}
	w.Write([]byte(strconv.Itoa(len(queryResult))))
}
Пример #2
0
func QueryID(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Cache-Control", "must-revalidate")
	var col, q string
	if !Require(w, r, "col", &col) {
		return
	}
	if !Require(w, r, "q", &q) {
		return
	}
	var qJson interface{}
	if err := json.Unmarshal([]byte(q), &qJson); err != nil {
		http.Error(w, fmt.Sprintf("'%v' is not valid JSON.", q), 400)
		return
	}
	V1Sync.RLock()
	defer V1Sync.RUnlock()
	dbcol := V1DB.Use(col)
	if dbcol == nil {
		http.Error(w, fmt.Sprintf("Collection '%s' does not exist.", col), 400)
		return
	}
	queryResult := make(map[uint64]bool)
	if err := db.EvalQuery(qJson, dbcol, &queryResult); err != nil {
		http.Error(w, fmt.Sprint(err), 400)
		return
	}
	for k := range queryResult {
		w.Write([]byte(fmt.Sprintf("%d\n", k)))
	}
}
Пример #3
0
func Query(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Cache-Control", "must-revalidate")
	w.Header().Set("Content-Type", "text/plain")
	var col, q string
	if !Require(w, r, "col", &col) {
		return
	}
	if !Require(w, r, "q", &q) {
		return
	}
	var qJson interface{}
	if err := json.Unmarshal([]byte(q), &qJson); err != nil {
		http.Error(w, fmt.Sprintf("'%v' is not valid JSON.", q), 400)
		return
	}
	V1Sync.RLock()
	defer V1Sync.RUnlock()
	dbcol := V1DB.Use(col)
	if dbcol == nil {
		http.Error(w, fmt.Sprintf("Collection '%s' does not exist.", col), 400)
		return
	}
	// evaluate the query
	queryResult := make(map[uint64]struct{})
	if err := db.EvalQuery(qJson, dbcol, &queryResult); err != nil {
		http.Error(w, fmt.Sprint(err), 400)
		return
	}
	// write each document on a new line
	for k := range queryResult {
		var doc interface{}
		dbcol.Read(k, &doc)
		if doc == nil {
			continue
		}
		resp, err := json.Marshal(doc)
		if err != nil {
			log.Printf("Query returned invalid JSON '%v'", doc)
			continue
		}
		w.Write([]byte(string(resp) + "\r\n"))
	}
}
Пример #4
0
// Benchmark durable operations.
func durableBenchmark() {
	// initialization
	rand.Seed(time.Now().UTC().UnixNano())
	// prepare benchmark data
	docs := [DURABLE_BENCH_SIZE]interface{}{}
	for i := range docs {
		if err := json.Unmarshal([]byte(
			`{"a": {"b": {"c": `+strconv.Itoa(rand.Intn(DURABLE_BENCH_SIZE))+`}},`+
				`"c": {"d": `+strconv.Itoa(rand.Intn(DURABLE_BENCH_SIZE))+`},`+
				`"more": "abcdefghijklmnopqrstuvwxyz"}`), &docs[i]); err != nil {
			panic("json error")
		}
	}
	// prepare collection
	tmp := "/tmp/tiedot_bench"
	os.RemoveAll(tmp)
	defer os.RemoveAll(tmp)
	col, err := db.OpenCol(tmp)
	if err != nil {
		panic(err)
	}
	col.Index([]string{"a", "b", "c"})
	col.Index([]string{"c", "d"})
	// start benchmarks
	average("insert", DURABLE_BENCH_SIZE, func() {}, func() {
		if _, err := col.DurableInsert(docs[rand.Intn(DURABLE_BENCH_SIZE)]); err != nil {
			panic("insert error")
		}
	})
	ids := make([]uint64, 0)
	average("read", DURABLE_BENCH_SIZE, func() {
		col.ForAll(func(id uint64, doc interface{}) bool {
			ids = append(ids, id)
			return true
		})
	}, func() {
		var doc interface{}
		err = col.Read(ids[uint64(rand.Intn(DURABLE_BENCH_SIZE))], &doc)
		if doc == nil {
			panic("read error")
		}
	})
	average("lookup", DURABLE_BENCH_SIZE, func() {}, func() {
		var query interface{}
		if err := json.Unmarshal([]byte(`["c", ["=", {"eq": `+strconv.Itoa(rand.Intn(DURABLE_BENCH_SIZE))+`, "in": ["a", "b", "c"], "limit": 1}],`+
			`["=", {"eq": `+strconv.Itoa(rand.Intn(DURABLE_BENCH_SIZE))+`, "in": ["c", "d"], "limit": 1}]]`), &query); err != nil {
			panic("json error")
		}
		result := make(map[uint64]struct{})
		if err := db.EvalQuery(query, col, &result); err != nil {
			panic("query error")
		}
	})
	average("update", DURABLE_BENCH_SIZE, func() {}, func() {
		if _, err := col.DurableUpdate(ids[rand.Intn(DURABLE_BENCH_SIZE)], docs[rand.Intn(DURABLE_BENCH_SIZE)]); err != nil {
			panic("update error")
		}
	})
	average("delete", DURABLE_BENCH_SIZE, func() {}, func() {
		if err := col.DurableDelete(ids[rand.Intn(DURABLE_BENCH_SIZE)]); err != nil {
			panic("delete error")
		}
	})
	col.Close()
}
Пример #5
0
func embeddedExample() {
	dir := "/tmp/MyDatabase"
	os.RemoveAll(dir)
	defer os.RemoveAll(dir)

	// Open database
	myDB, err := db.OpenDB(dir)
	if err != nil {
		panic(err)
	}

	// Create collection
	if err := myDB.Create("A"); err != nil {
		panic(err)
	}
	if err := myDB.Create("B"); err != nil {
		panic(err)
	}

	// Rename collection
	if err := myDB.Rename("B", "C"); err != nil {
		panic(err)
	}

	// Which collections do I have?
	for name := range myDB.StrCol {
		fmt.Printf("I have a collection called %s\n", name)
	}

	// Drop collection
	if err := myDB.Drop("C"); err != nil {
		panic(err)
	}

	// Start using collection
	A := myDB.Use("A")

	/*
		Insert document.

		You may insert/update any interface{} to collection, for example:
		var doc interface{}
		json.Unmarshal([]byte(`{"a": 1, "b": 2}`), &doc)
		A.Insert(doc)

		And here is an example using struct:
	*/

	type Document struct {
		Url, Owner string
	}

	docID, err := A.Insert(Document{"http://google.com", "Google Inc."})
	if err != nil {
		panic(err)
	}
	fmt.Printf("Inserted document at %d (document ID)\n", docID)

	// Update document (you can still use struct, but this example uses generic interface{})
	var doc interface{}
	json.Unmarshal([]byte(`{"Url": "http://www.google.com.au", "Owner": "Google Inc."}`), &doc)
	newID, err := A.Update(docID, doc) // newID may or may not be the same!
	if err != nil {
		panic(err)
	}
	fmt.Printf("Updated document %d to %v, new ID is %d\n", docID, doc, newID)

	// Read document
	var readback Document
	if err := A.Read(newID, &readback); err != nil {
		panic(err)
	}
	fmt.Printf("Read document ID %d: %v\n", newID, readback)

	// Delete document
	A.Delete(123) // passing invalid ID to it will not harm your data

	/*
	   Collection insert/update/delete have their dedicated "durable" calls:
	   - durableInsert
	   - durableUpdate
	  - durableDelete
	  Those operations ensure a disk flush after each call to guarantee data durability on disk.
	  However - those operations are 10000x more expensive than ordinary insert/update/delete!
	*/

	// Create index
	if err := A.Index([]string{"a", "b", "c"}); err != nil {
		panic(err)
	}

	// Which indexes do I have on collection A?
	for path := range A.StrHT {
		fmt.Printf("I have an index on path %s\n", path)
	}

	// Remove index
	if err := A.Unindex([]string{"a", "b", "c"}); err != nil {
		panic(err)
	}

	// Execute query
	result := make(map[uint64]struct{})
	var query interface{}
	json.Unmarshal([]byte(`["all"]`), &query)
	if err := db.EvalQuery(query, A, &result); err != nil {
		panic(err)
	}
	for id := range result {
		// query results are in map keys
		fmt.Printf("Query returned document ID %d\n", id)
	}

	// Gracefully close database
	myDB.Close()
}
Пример #6
0
func embeddedExample() {
	dir := "/tmp/MyDatabase"
	os.RemoveAll(dir)
	defer os.RemoveAll(dir)

	// Open database
	myDB, err := db.OpenDB(dir)
	if err != nil {
		panic(err)
	}

	// Create collection
	if err := myDB.Create("A"); err != nil {
		panic(err)
	}
	if err := myDB.Create("B"); err != nil {
		panic(err)
	}

	// Rename collection
	if err := myDB.Rename("B", "C"); err != nil {
		panic(err)
	}

	// Which collections do I have?
	for name := range myDB.StrCol {
		fmt.Printf("I have a collection called %s\n", name)
	}

	// Drop collection
	if err := myDB.Drop("C"); err != nil {
		panic(err)
	}

	// Start using collection
	A := myDB.Use("A")

	// Insert document
	var doc interface{}
	json.Unmarshal([]byte(`{"a": 1, "b": 2}`), &doc)
	docID, err := A.Insert(doc)
	if err != nil {
		panic(err)
	}
	fmt.Printf("Inserted document %v at %d (document ID)\n", doc, docID)

	// Update document
	json.Unmarshal([]byte(`{"a": 2, "b": 3}`), &doc)
	newID, err := A.Update(docID, doc) // newID may or may not be the same
	if err != nil {
		panic(err)
	}
	fmt.Printf("Updated document %d to %v, new ID is %d\n", docID, doc, newID)

	// Delete document
	A.Delete(123) // passing invalid ID to it will not harm your data

	// Create index
	if err := A.Index([]string{"a", "b", "c"}); err != nil {
		panic(err)
	}

	// Which indexes do I have on collection A?
	for path := range A.StrHT {
		fmt.Printf("I have an index on path %s\n", path)
	}

	// Remove index
	if err := A.Unindex([]string{"a", "b", "c"}); err != nil {
		panic(err)
	}

	// Execute query
	result := make(map[uint64]bool)
	var query interface{}
	json.Unmarshal([]byte(`["all"]`), &query)
	if err := db.EvalQuery(query, A, &result); err != nil {
		panic(err)
	}
	for id := range result {
		// query results are in map keys
		fmt.Printf("Query returned document ID %d\n", id)
	}

	// Gracefully close database
	myDB.Close()
}