🚀 Big News: Socket Acquires Coana to Bring Reachability Analysis to Every Appsec Team.Learn more
Socket
DemoInstallSign in
Socket

github.com/anyproto/any-store

Package Overview
Dependencies
Alerts
File Explorer
Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

github.com/anyproto/any-store

v0.1.13
Source
Go
Version published
Created
Source

Any Store

Any Store is a document-oriented database with a MongoDB-like query language. It is built on top of SQLite. The database supports transactions and indexes.

Warning: This library is not well tested and the API is still unstable. However, it is under active development.

Installation

To install Any Store, run:

go get github.com/anyproto/any-store

For the CLI interface, run:

go install github.com/anyproto/any-store/cmd/any-store-cli@latest

Usage Example

Here is an all-in-one example demonstrating various operations with Any Store:

package main

import (
	"context"
	"fmt"
	"log"

	anystore "github.com/anyproto/any-store"
	"github.com/anyproto/any-store/anyenc"
)

var ctx = context.Background()

func main() {
	// open database
	db, err := anystore.Open(ctx, "/tmp/file.db", nil)
	if err != nil {
		log.Fatalf("unable to open db: %v", err)
	}

	defer func() {
		if err = db.Close(); err != nil {
			log.Fatalf("close db eroor: %v", err)
		}
	}()

	coll, err := db.Collection(ctx, "users")
	if err != nil {
		log.Fatalf("unable to open collection: %v", err)
	}

	// insert document, convert from json
	doc := anyenc.MustParseJson(`{"id":1, "name": "John"}`)
	err = coll.Insert(ctx, doc)
	if err != nil {
		log.Fatalf("unable to insert document: %v", err)
	}

	// create document
	a := &anyenc.Arena{}
	doc = a.NewObject()
	doc.Set("id", a.NewNumberInt(2))
	doc.Set("name", a.NewString("Jane"))
	err = coll.Insert(ctx, doc)
	if err != nil {
		log.Fatalf("unable to insert document: %v", err)
	}

	// batch insert
	if err = coll.Insert(ctx,
		anyenc.MustParseJson(`{"id":3, "name": "Alex"}`),
		anyenc.MustParseJson(`{"id":4, "name": "rob"}`),
		anyenc.MustParseJson(`{"id":5, "name": "Paul"}`),
	); err != nil {
		log.Fatalf("unable to insert document: %v", err)
	}

	// upsert
	err = coll.UpsertOne(ctx, anyenc.MustParseJson(`{"id":6, "name": "Mike"}`))
	if err != nil {
		log.Fatalf("unable to insert document: %v", err)
	}

	// update one
	if err = coll.UpdateOne(ctx, anyenc.MustParseJson(`{"id":4, "name": "Rob"}`)); err != nil {
		log.Fatalf("unable to update document: %v", err)
	}

	// find by id
	res, err := coll.FindId(ctx, 2)
	if err != nil {
		log.Fatalf("unable to find document: %v", err)
	}
	fmt.Println("document found:", res.Value().String())

	// collection count
	count, err := coll.Count(ctx)
	if err != nil {
		log.Fatalf("unable to count documents: %v", err)
	}
	fmt.Println("document count:", count)

	// find many with condition
	iter, err := coll.Find(`{"id":{"$in":[1,2,3]}}`).Sort("-name").Limit(2).Offset(1).Iter(ctx)
	if err != nil {
		log.Fatalf("query failed: %v", err)
	}
	defer func() {
		if err = iter.Close(); err != nil {
			log.Fatalf("unable to close iterator: %v", err)
		}
	}()
	for iter.Next() {
		res, err = iter.Doc()
		if err != nil {
			log.Fatalf("load document error: %v", err)
		}
		fmt.Println("findMany:", res.Value().String())
	}

	// create index
	if err = coll.EnsureIndex(ctx, anystore.IndexInfo{Fields: []string{"name"}}); err != nil {
		fmt.Println("unable to ensure index:", err)
	}

	// update many
	result, err := coll.Find(`{"name": {"$in": ["Rob","Alex"]}}`).Update(ctx, `{"$inc":{"rating":0.1}}`)
	if err != nil {
		log.Fatalf("cannot update document: %v", err)
	}
	fmt.Printf("updated documents count: %d\n", result.Modified)

	// transaction
	tx, err := db.WriteTx(ctx)
	if err != nil {
		log.Fatalf("cannot create tx: %v", err)
	}

	// it's important to pass tx.Context() to any operations within transaction
	// because sqlite can handle only one transaction in time - passing ctx instead tx.Context() will cause possibly deadlock
	result, err = coll.Find(`{"name": "Mike"}`).Delete(tx.Context())
	if err != nil {
		log.Fatalf("cannot delete document: %v", err)
	}
	fmt.Println("deleted count:", result.Modified)

	// document is deleted inside transaction
	count, err = coll.Find(`{"name": "Mike"}`).Count(tx.Context())
	if err != nil {
		log.Fatalf("cannot count documents: %v", err)
	}
	fmt.Println("count within transaction:", count)

	// by passing other ctx we can find Mike in other transaction
	count, err = coll.Find(`{"name": "Mike"}`).Count(ctx)
	if err != nil {
		log.Fatalf("cannot count documents: %v", err)
	}
	fmt.Println("count outside transaction:", count)

	if err = tx.Commit(); err != nil {
		log.Fatalf("cannot commit transaction: %v", err)
	}

}

License

This project is licensed under the MIT License. See the LICENSE file for details.

FAQs

Package last updated on 02 Apr 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts