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)))) }
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))) } }
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")) } }
// 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() }
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() }
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() }