Search Apps Documentation Source Content File Folder Download Copy Actions Download State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

/p/g17khqpukees4237dtn3astzapmp462vjhsz6st4/datastore

Directory · 11 Files
README.md Open

Datastore Package

Package provides support to store multiple collections of records.

It supports the definition of multiple storages, where each one is a collection of records. Records can have any number of user defined fields which are added dynamically when values are set on a record. These fields can also be renamed or removed.

Storages have support for simple schemas that allow users to pre-define fields which can optionally have a default value also defined. Default values are assigned to new records on creation.

User defined schemas can optionally be strict, which means that records from a storage using the schema can only assign values to the pre-defined set of fields. In which case, assigning a value to an unknown field results in an error.

Package also supports the definition of custom record indexes. Indexes are used by storages to search and iterate records. The default index is the ID index but custom single and multi value indexes can be defined.

Warning

Using this package to store your realm data must be carefully considered. The fact that record fields are not strictly typed and can be renamed or removed could lead to issues if not careful when coding your realm(s). So it's recommended that you consider other alternatives first, like alternative patterns or solutions provided by the blockchain to deal with data, types and data migration for example.

Repository can be found at jeronimoalbi/gnome, as part of jeronimoalbi's Gno smart contracts monorepo.

Usage

 1package main
 2
 3import "gno.land/p/g17khqpukees4237dtn3astzapmp462vjhsz6st4/datastore"
 4
 5func main() {
 6	db := datastore.NewDatastore()
 7
 8	// Define a unique case insensitive index for user emails
 9	emailIdx := datastore.NewIndex("email", func(r datastore.Record) string {
10		return r.MustGet("email").(string)
11	}).Unique().CaseInsensitive()
12
13	// Create a new storage for user records
14	users := db.CreateStorage("users", datastore.WithIndex(emailIdx))
15
16	// Add a user with a single "email" field
17	user := users.NewRecord()
18	user.Set("email", "[email protected]")
19
20	// Save to assign the user ID and update indexes
21	user.Save()
22
23	// Find user by email using the custom index
24	user, _ = users.Get(emailIdx.Name(), "[email protected]")
25	println("Found by email:", user.MustGet("email"))
26
27	// Find user by ID
28	user, _ = users.GetByID(user.ID())
29	println("Found by ID:", user.ID())
30
31	// Delete the user from the storage and update indexes
32	users.Delete(user.ID())
33	println("Users:", users.Size())
34}
35
36// Output:
37// Found by email: [email protected]
38// Found by ID: 1
39// Users: 0

Querying

 1package main
 2
 3import "gno.land/p/g17khqpukees4237dtn3astzapmp462vjhsz6st4/datastore"
 4
 5func main() {
 6	db := datastore.NewDatastore()
 7
 8	// Define a multi value index to search posts by tag
 9	tagsIdx := datastore.NewMultiValueIndex("tags", func(r datastore.Record) []string {
10		return r.MustGet("tags").([]string)
11	})
12
13	posts := db.CreateStorage("posts", datastore.WithIndex(tagsIdx))
14	for _, title := range []string{"Post 1", "Post 2", "Post 3"} {
15		post := posts.NewRecord()
16		post.Set("title", title)
17		post.Set("tags", []string{"gno", title})
18		post.Save()
19	}
20
21	// Get two records starting from the second one
22	recordset, err := posts.Query(datastore.WithOffset(1), datastore.WithSize(2))
23	if err != nil {
24		panic(err)
25	}
26
27	recordset.Iterate(func(r datastore.Record) bool {
28		println("Post:", r.MustGet("title"))
29		return false // Continue iterating
30	})
31
32	// Get all the records that have the "gno" tag using the custom index
33	recordset = posts.MustQuery(datastore.UseIndex("tags", "gno"))
34	println("Tagged posts:", recordset.Size())
35}
36
37// Output:
38// Post: Post 2
39// Post: Post 3
40// Tagged posts: 3