All Projects → ulfox → dby

ulfox / dby

Licence: MIT license
Simple Yaml DB

Programming Languages

go
31211 projects - #10 most used programming language
Makefile
30231 projects

Projects that are alternatives of or similar to dby

read-yaml
Very thin wrapper around js-yaml for directly reading in YAML files.
Stars: ✭ 25 (-46.81%)
Mutual labels:  yaml
django-undeletable
undeletable Django models
Stars: ✭ 13 (-72.34%)
Mutual labels:  db
iiitdmj-gpa
GPA Calculator + Quiz Bot for IIITDM Jabalpur
Stars: ✭ 16 (-65.96%)
Mutual labels:  db
multilanguages
AKSoftware.Localization.MultiLanguages is a package for .NET developers allows them to easily build apps target multiple languages with just few lines of code
Stars: ✭ 54 (+14.89%)
Mutual labels:  yaml
ccxx
This is a cross-platform library software library about c, c ++, unix4, posix. Include gtest, benchmark, cmake, process lock, daemon, libuv, lua, cpython, re2, json, yaml, mysql, redis, opencv, qt, lz4, oci ... https://hub.docker.com/u/oudream
Stars: ✭ 31 (-34.04%)
Mutual labels:  yaml
tr4n5l4te
Use Google Translate without an API key.
Stars: ✭ 32 (-31.91%)
Mutual labels:  yaml
csvy
Import and Export CSV Data With a YAML Metadata Header
Stars: ✭ 52 (+10.64%)
Mutual labels:  yaml
yaask
Make your yaml configurable with interactive configurations!
Stars: ✭ 15 (-68.09%)
Mutual labels:  yaml
coAST
Universal and language-independent abstract syntax tree
Stars: ✭ 30 (-36.17%)
Mutual labels:  yaml
ocp-flyway-db-migration
Database Migration Sample with Flyway, Docker and Kubernetes in Openshift Container Platform
Stars: ✭ 17 (-63.83%)
Mutual labels:  db
EnvCLI
Don't install Node, Go, ... locally - use containers you define within your project. If you have a new machine / other contributors you just have to install docker and envcli to get started.
Stars: ✭ 93 (+97.87%)
Mutual labels:  yaml
hammerkit
build tool with support for containerization, build caching for local development and ci
Stars: ✭ 50 (+6.38%)
Mutual labels:  yaml
php-helpers
A Collection of useful php helper functions.
Stars: ✭ 26 (-44.68%)
Mutual labels:  yaml
db-rest
A clean REST API wrapping around the Deutsche Bahn API.
Stars: ✭ 40 (-14.89%)
Mutual labels:  db
goodconf
Transparently load variables from environment or JSON/YAML file.
Stars: ✭ 80 (+70.21%)
Mutual labels:  yaml
crimson
Bioinformatics tool outputs converter to JSON or YAML
Stars: ✭ 30 (-36.17%)
Mutual labels:  yaml
pystest
WEB UI自动化测试框架,selenium结合python,测试人员不需要会代码,只需要写配置即可实现,并且方便懂代码的测试人员扩展
Stars: ✭ 24 (-48.94%)
Mutual labels:  yaml
Config
PHP library for simple configuration management
Stars: ✭ 39 (-17.02%)
Mutual labels:  yaml
odbc-rs
Rust ODBC FFI binding
Stars: ✭ 90 (+91.49%)
Mutual labels:  db
odin
Data-structure definition/validation/traversal, mapping and serialisation toolkit for Python
Stars: ✭ 24 (-48.94%)
Mutual labels:  yaml

DB Yaml

Simple DB using yaml. A project for managing the content of yaml files.

Table of Contents

Features

The module can do

  • Create/Load yaml files
  • Update content
  • Get values from keys
  • Query for keys
  • Delete keys
  • Merge content

Usage

Simple examples for working with yaml files as db

Initiate a new stateful DB

Create a new local DB

package main

import (
	"github.com/sirupsen/logrus"
	"github.com/ulfox/dby/db"
)

func main() {
	logger := logrus.New()

	state, err := db.NewStorageFactory("local/db.yaml")
	if err != nil {
		logger.Fatalf(err.Error())
	}
}

The code above will create a new yaml file under local directory.

Initiate a new stateless DB

package main

import (
	"github.com/sirupsen/logrus"
	"github.com/ulfox/dby/db"
)

func main() {
	logger := logrus.New()

	state, err := db.NewStorageFactory()
	if err != nil {
		logger.Fatalf(err.Error())
	}
}

Initiating a db without arguments will not create/write/read from a file. All operations will be done in memory and unless the caller saves the data externally, all data will be lose on termination

Write to DB

Insert a map to the local yaml file.

err = state.Upsert(
	"some.path",
	map[string]string{
		"key-1": "value-1",
		"key-2": "value-2",
	},
)

if err != nil {
	logger.Fatalf(err.Error())
}

Query DB

Get First Key

Get the value of the first key in the hierarchy (if any)

val, err := state.GetFirst("key-1")
if err != nil {
	logger.Fatalf(err.Error())
}
logger.Info(val)

For example if we have the following structure

key-1:
    key-2:
        key-3: "1"
    key-3: "2"

And we query for key-3, then we will get back "2" and not "1" since key-3 appears first on a higher layer with a value of 2

Search for keys

Get all they keys (if any). This returns the full path for the key, not the key values. To get the values check the next section GetPath

keys, err := state.FindKeys("key-1")
if err != nil {
	logger.Fatalf(err.Error())
}
logger.Info(keys)

From the previous example, this query would have returned

["key-1.key-2.key-3", "key-1.key-3"]

Query Path

Get the value from a given path (if any)

For example if we have in yaml file the following key-path

key-1:
    key-2:
        key-3: someValue

Then to get someValue, issue

keyPath, err := state.GetPath("key-1.key-2.key-3")
if err != nil {
	logger.Fatalf(err.Error())
}
logger.Info(keyPath)

Query Path with Arrays

We can also query paths that have arrays.

Without trailing array
key-1:
    key-2:
        - key-3: 
            key-4: value-1

To get the value of key-4, issue

keyPath, err := state.GetPath("key-1.key-2.[0].key-3.key-4")
if err != nil {
	logger.Fatalf(err.Error())
}
logger.Info(keyPath)
With trailing array
key-1:
    key-2:
        - value-1
        - value-2
        - value-3

To get the first index of key-2, issue

keyPath, err := state.GetPath("key-1.key-2.[0]")
if err != nil {
	logger.Fatalf(err.Error())
}
logger.Info(keyPath)

Delete Key By Path

To delete a single key for a given path, e.g. key-2 from the example above, issue

err = state.Delete("key-1.key-2")
if err != nil {
	logger.Fatalf(err.Error())
}

Document Management

DBy creates by default an array of documents called library. That is in fact an array of interfaces

When initiating DBy, document 0 (index 0) is creatd by default and any action is done to that document, unless we switch to a new one

Add a new doc

To add a new doc, issue

err = state.AddDoc()
if err != nil {
  logger.Fatal(err)
}

Note: Adding a new doc also switches the pointer to that doc. Any action will write/read from the new doc by default

Switch Doc

To switch a different document, we can use Switch method that takes as an argument an index

For example to switch to doc 1 (second doc), issue

err = state.Switch(1)
if err != nil {
  logger.Fatal(err)
}

Document names

When we work with more than 1 document, we may want to set names in order to easily switch between docs

We have 2 ways to name our documents

  • Add a name to each document manually
  • Add a name providing a path that exists in all documents
Name documents manually

To name a document manually, we can use the SetName method which takes 2 arguments

  • name
  • doc index

For example to name document with index 0, as myDoc

err := state.SetName("myDoc", 0)
if err != nil {
  logger.Fatal(err)
}
Name all documents automatically

To name all documents automatically we need to ensure that the same path exists in all documents.

The method for updating all documents is called SetNames and takes 2 arguments

  • Prefix: A path in the documents that will be used for the first name
  • Suffix: A path in the documents that will be used for the last name

Note: Docs that do not have the paths that are queried will not get a name

This method best works with Kubernetes manifests, where all docs have a common set of fields.

For example

apiVersion: someApi-0
kind: someKind-0
metadata:
...
  name: someName-0
...
---
apiVersion: someApi-1
kind: someKind-1
metadata:
...
  name: someName-1
...
---

From above we could give a name for all our documents if we use kind + metadata.name for the name.

err := state.SetNames("kind", "metadata.name")
if err != nil {
  logger.Fatal(err)
}
List all doc names

To get the name of all named docs, issue

for i, j := range state.ListDocs() {
  fmt.Println(i, j)
}

Example output based on the previous SetNames example

0 service/listener-svc
1 poddisruptionbudget/listener-svc
2 horizontalpodautoscaler/caller-svc
3 deployment/caller-svc
4 service/caller-svc
5 poddisruptionbudget/caller-svc
6 horizontalpodautoscaler/listener-svc
7 deployment/listener-svc
Switch between docs by name

To switch to a doc by using the doc's name, issue

err = state.SwitchDoc("PodDisruptionBudget/caller-svc")
if err != nil {
  logger.Fatal(err)
}

Import Docs

We can import a set of docs with ImportDocs method. For example if we have the following yaml

apiVersion: someApi-0
kind: someKind-0
metadata:
...
  name: someName-0
...
---
apiVersion: someApi-1
kind: someKind-1
metadata:
...
  name: someName-1
...
---

We can import it by giving the path of the file

err = state.ImportDocs("file-name.yaml")
if err != nil {
  logger.Fatal(err)
}

Global Commands

Wrappers for working with all documents

Global Upsert

We can use upsert to update or create keys on all documents

err = state.UpsertGlobal(
  "some.path",
  "v0.3.0",
)
if err != nil {
  logger.Fatal(err)
}
Global Update

Global update works as GlobalUpsert but it skips documents that miss a path rather than creating the path on those docs.

Global GetFirst

To get the value of the first key in the hierarchy for each document, issue

valueOfDocs, err := state.GetFirstGlobal("keyName")
if err != nil {
	logger.Fatalf(err.Error())
}
logger.Info(valueOfDocs)

This returns a map[int]interface{} object. The key is the index of each document and it's value is the value of the first key in the hierarchy in that document

Global FindKeys

To get all the paths for a given from all documents, issue

mapOfPaths, err := state.FindKeysGlobal("keyName")
if err != nil {
	logger.Fatalf(err.Error())
}
logger.Info(mapOfPaths)

This returns a map[int][]string object. The key is the index of each document and it's value is a list of paths that have the queried key

Global GetPath

To get a path that exists in all documents, issue

valueOfDocs, err := state.GetPathGlobal("key-1.key-2.key-3")
if err != nil {
	logger.Fatalf(err.Error())
}
logger.Info(valueOfDocs)

This returns a map[int]interface{} object. The key is the index of each document and it's value is the value of the specific key in that document

Global Delete

To delete a path from all documents, issue

err := state.DeleteGlobal("key-1.key-2.key-3")
if err != nil {
	logger.Fatalf(err.Error())
}

The above will delete all the paths that match the queried path from each doc

Convert Utils

Convert simply automate the need to explicitly do assertion each time we need to access an interface object.

Let us assume we have the following YAML structure

to:
  array-1:
    key-1:
    - key-2: 2
    - key-3: 3
    - key-4: 4
  array-2:
  - 1
  - 2
  - 3
  - 4
  - 5
  array-3:
  - key-1: 1
  - key-2: 2

Get map of strings from interface

We can do this in two ways, get object by giving a path and assert the interface to map[string]string, or work manually our way to the object

Get map directly from a GetPath object

To get map key-2: 2, first get object via GetPath

obj, err := state.GetPath("to.array-1.key-1.[0]")
if err != nil {
	logger.Fatalf(err.Error())
}
logger.Info(val)

Next, assert obj as map[string]string

assertData := db.NewConvertFactory()

assertData.Input(val)
if assertData.GetError() != nil {
	logger.Fatal(assertData.GetError())
}
vMap, err := assertData.GetMap()
if err != nil {
	logger.Fatal(err)
}
logger.Info(vMap["key-2"])
Get map manually

We can get the map manually by using only Convert operations

assertData := db.NewConvertFactory()

assertData.Input(state.Data).
	Key("to").
	Key("array-1").
	Key("key-1").Index(0)
if assertData.GetError() != nil {
	logger.Fatal(assertData.GetError())
}
vMap, err := assertData.GetMap()
if err != nil {
	logger.Fatal(err)
}
logger.Info(vMap["key-2"])

Get array of string from interface

Again here we can do it two ways as with the map example

Get array directly from a GetPath object

To get array-2 as []string, first get object via GetPath

obj, err = state.GetPath("to.array-2")
if err != nil {
	logger.Fatalf(err.Error())
}
logger.Info(obj)

Next, assert obj as []string

assertData := db.NewConvertFactory()

assertData.Input(obj)
if assertData.GetError() != nil {
	logger.Fatal(assertData.GetError())
}
vArray, err := assertData.GetArray()
if err != nil {
	logger.Fatal(err)
}
logger.Info(vArray)
Get array manually

We can get the array manually by using only Convert operations

assertData.Input(state.Data).
	Key("to").
	Key("array-2")
if assertData.GetError() != nil {
	logger.Fatal(assertData.GetError())
}
vArray, err := assertData.GetArray()
if err != nil {
	logger.Fatal(err)
}
logger.Info(vArray)
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].