ystore

package module
v0.3.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 11, 2020 License: BSD-3-Clause Imports: 12 Imported by: 0

README



ystore is a data management tool. It can be used as a generic key-value datastore, for flexible configuration storage or used as a way to import arbitrary data into your application from data files (e.g.: from a CMS or other system).

The goal of ystore's is to provide flexible access to your data.

Features

  • flexible key-value storage
  • load directly from JSON, TOML and YAML files
  • merge whole directories of files into single stores
  • simple nested key queries (e.g.: GetString("node.sub.key"))
  • match store keys using a pattern
  • Store splitting and merging
  • conversion from map values

Memory-based Stores

At it's core, ystore is a simple key-value store. You can easily create a simple Store like so:

store := NewStore()
store.Set("color", "red")
store.Set("length", 100)
fmt.Printf("The item is %s and the length is %d.\n", 
	store.GetString("color"), store.GetInt("length"))
// Output: The item is red and the length is 100.

You can also implement your store with default values using a the map initializer:

store := NewStoreFromMap(map[string]interface{}{
	"color" : green,
	"length" : 80,
})
fmt.Printf("The item is %s and the length is %d.\n", 
	store.GetString("color"), store.GetInt("length"))
// Output: The item is green and the length is 80.

File-based Stores

Let's assume we have a .toml file that looks like this:

[item]
name="First Item"
colors=["red", "green", "blue"]
numbers=[5, 2, 1, 6, 5]

We can load the file by creating a Store and then using the ReadFile function. Note: You will need to pass the absolute file path to ReadFile.

filename, fileErr := filepath.Abs("./config.toml")
if fileErr != nil {
	// handle the path error
	return
}
store := NewStore()
if readErr := store.ReadFile(filename); readErr != nil {
	// handle store load error
	return
}
name := store.GetString("item.name")
numbers := store.GetIntSlice("item.numbers")
fmt.Printf("The item name is '%s' and the numbers slice has %d element(s).\n", name, len(numbers))
// Output: The item name is 'First Item' and the numbers slice has 5 element(s).

FAQ

Can I use this as a database?

You could, but it may not be the best solution. Our goal is to provide a super flexible data management solution for a variety of application data and to not be a full scale database. A quick search on Google will find a variety of great solutions if you need to embed a database.

How is this different to Viper?

First up, Viper is fantastic and super useful. ystore isn't trying to compete with viper.

The overall intent of ystore is to offer a more generic data mechanism, to allow files/formats to be used interchangeably, and to make it simple to just parse a bunch of it at the same time. Viper is more suited for application configuration specific task. You can still use ystore for application configuration (it works great!) but you may end up needing to do a few additional tasks yourself.

Viper - Go configuration with fangs

License

ystore is released under a modified MIT license. See LICENSE for details.

Portions of the code are derived from other works. Please see NOTICE for details on usage and their associated licenses.

Documentation

Index

Examples

Constants

View Source
const DataKeySeparator = "."

DataKeySeparator is the separator that is used to split keys that are

Variables

This section is empty.

Functions

func BaseDir

func BaseDir(filename string) string

func MergeMaps

func MergeMaps(src, tgt map[string]interface{}, itgt map[interface{}]interface{})

MergeMaps merges two maps. The `itgt` parameter is for handling go-yaml's insistence on parsing nested structures as `map[interface{}]interface{}` instead of using a `string` as the key for nest structures beyond one level deep. Both map types are supported as there is a go-yaml fork that uses `map[string]interface{}` instead.

func SearchMap

func SearchMap(source map[string]interface{}, path []string) interface{}

SearchMap recursively searches for a value for path in source map. Returns nil if not found. Note: This assumes that the path entries and map keys are lower cased.

Types

type EachFunc

type EachFunc func(string, interface{})

type ProcessElementFunc

type ProcessElementFunc func(key string, val interface{}) interface{}

type Store

type Store struct {

	// PrefixDirectories adds a prefix to the data map for any directories that are
	// not the top-level directory. For example: given the file
	// <datadir>/categories/somecat.toml, the contents of the toml file will live in
	// the map under the prefix (key) "categories"
	PrefixDirectories bool

	// Exclude contains patterns that we should be excluding when walking the data
	// directory
	Exclude []string
	// contains filtered or unexported fields
}

Store is a giant data map that is constructed from one or more data files that are stored within a directory and series of sub-directories

Example
package main

import (
	"fmt"

	"github.com/theyakka/ystore"
)

func main() {
	store := ystore.NewStore()
	store.Set("color", "red")
	store.Set("length", 100)
	fmt.Printf("The item is %s and the length is %d.\n", store.GetString("color"), store.GetInt("length"))
}
Output:
The item is red and the length is 100.
Example (File)
package main

import (
	"fmt"
	"path/filepath"

	"github.com/theyakka/ystore"
)

func main() {
	filename, fileErr := filepath.Abs("./_testdata/first.toml")
	if fileErr != nil {
		// handle the path error
		return
	}
	store := ystore.NewStore()
	if readErr := store.ReadFile(filename); readErr != nil {
		// handle store load error
		return
	}
	name := store.GetString("firstdata.name")
	numbers := store.GetIntSlice("firstdata.numbers")
	fmt.Printf("The item name is '%s' and the numbers slice has %d element(s).\n", name, len(numbers))
}
Output:
The item name is 'First Item' and the numbers slice has 5 element(s).
Example (Map)
package main

import (
	"fmt"

	"github.com/theyakka/ystore"
)

func main() {
	store := ystore.NewStoreFromMap(map[string]interface{}{
		"color":  "green",
		"length": 80,
	})
	fmt.Printf("The item is %s and the length is %d.\n", store.GetString("color"), store.GetInt("length"))
}
Output:
The item is green and the length is 80.

func MergeStores

func MergeStores(stores ...*Store) *Store

func NewStore

func NewStore() *Store

func NewStoreFromMap

func NewStoreFromMap(data map[string]interface{}) *Store

func NewStoreFromMapWithSubs

func NewStoreFromMapWithSubs(data map[string]interface{}) *Store

func NewStoreWithData added in v0.3.0

func NewStoreWithData(data interface{}) *Store

func (*Store) AllValues

func (ds *Store) AllValues() map[string]interface{}

func (*Store) Each

func (ds *Store) Each(eachFunc EachFunc)

func (Store) Get

func (ds Store) Get(key string) interface{}

func (Store) GetBool

func (ds Store) GetBool(key string) bool

func (Store) GetBoolD

func (ds Store) GetBoolD(key string, defaultValue bool) bool

func (Store) GetD

func (ds Store) GetD(key string, defaultValue interface{}) interface{}

func (Store) GetFloat

func (ds Store) GetFloat(key string) float64

func (Store) GetFloatD

func (ds Store) GetFloatD(key string, defaultValue float64) float64

func (Store) GetInt

func (ds Store) GetInt(key string) int

func (Store) GetIntD

func (ds Store) GetIntD(key string, defaultValue int) int

func (Store) GetIntSlice

func (ds Store) GetIntSlice(key string) []int

func (Store) GetIntSliceD

func (ds Store) GetIntSliceD(key string, defaultValue []int) []int

func (Store) GetMap

func (ds Store) GetMap(key string) map[string]interface{}

func (Store) GetMapD

func (ds Store) GetMapD(key string, defaultValue map[string]interface{}) map[string]interface{}

func (Store) GetSlice

func (ds Store) GetSlice(key string) []interface{}

func (Store) GetSliceD

func (ds Store) GetSliceD(key string, defaultValue []interface{}) []interface{}

func (Store) GetStore

func (ds Store) GetStore(key string) *Store

func (Store) GetStoreD

func (ds Store) GetStoreD(key string, defaultValue *Store) *Store

func (Store) GetString

func (ds Store) GetString(key string) string

func (Store) GetStringD

func (ds Store) GetStringD(key string, defaultValue string) string

func (Store) GetStringSlice

func (ds Store) GetStringSlice(key string) []string

func (Store) GetStringSliceD

func (ds Store) GetStringSliceD(key string, defaultValue []string) []string

func (*Store) Len

func (ds *Store) Len() int

func (*Store) MergeWith added in v0.3.0

func (ds *Store) MergeWith(stores ...*Store) *Store

func (*Store) Process

func (ds *Store) Process(processor ProcessElementFunc) *Store

func (*Store) ReadDir

func (ds *Store) ReadDir(path string) error

ReadDir will parse all data files within the directory and all sub-directories

func (*Store) ReadFile

func (ds *Store) ReadFile(filePath string) error

func (*Store) ReadFiles

func (ds *Store) ReadFiles(filePaths ...string) error

func (*Store) Set

func (ds *Store) Set(key string, value interface{})

func (*Store) SetAsString added in v0.3.0

func (ds *Store) SetAsString(key string, value interface{})

func (*Store) StoreFromMap

func (ds *Store) StoreFromMap(key string) *Store

func (*Store) StoreFromMapOrEmpty

func (ds *Store) StoreFromMapOrEmpty(key string) *Store

func (*Store) StoreMatching

func (ds *Store) StoreMatching(pattern string) *Store

func (*Store) ToJSONString added in v0.2.0

func (ds *Store) ToJSONString() string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL