Scribble - A tiny Golang JSON database

Scribble GoDoc Go Report Card

A tiny JSON database in Golang

Installation

Install using go get github.com/sdomino/scribble.

Usage

// a new scribble driver, providing the directory where it will be writing to,
// and a qualified logger if desired
db, err := scribble.New(dir, nil)
if err != nil {
  fmt.Println("Error", err)
}

// Write a fish to the database
fish := Fish{}
if err := db.Write("fish", "onefish", fish); err != nil {
  fmt.Println("Error", err)
}

// Read a fish from the database (passing fish by reference)
onefish := Fish{}
if err := db.Read("fish", "onefish", &onefish); err != nil {
  fmt.Println("Error", err)
}

// Read all fish from the database, unmarshaling the response.
records, err := db.ReadAll("fish")
if err != nil {
  fmt.Println("Error", err)
}

fishies := []Fish{}
for _, f := range records {
  fishFound := Fish{}
  if err := json.Unmarshal([]byte(f), &fishFound); err != nil {
    fmt.Println("Error", err)
  }
  fishies = append(fishies, fishFound)
}

// Delete a fish from the database
if err := db.Delete("fish", "onefish"); err != nil {
  fmt.Println("Error", err)
}

// Delete all fish from the database
if err := db.Delete("fish", ""); err != nil {
  fmt.Println("Error", err)
}

Documentation

  • Complete documentation is available on godoc.
  • Coverage Report is available on gocover

Todo/Doing

  • Support for windows
  • Better support for concurrency
  • Better support for sub collections
  • More methods to allow different types of reads/writes
  • More tests (you can never have enough!)
Owner
Steve Domino
Husband, father, and tech enthusiast who is passionate about finding, using, and creating awesome stuff.
Steve Domino
Comments
  • Add options for New

    Add options for New

    Experimental feature for add Options to the New method. As example, i added ExistDir option, which is related with https://github.com/nanopack/yoke/issues/10 . If ExistDir is true, it not creates new dir, before starting.

  • not found 404 and missing open

    not found 404 and missing open

    The following is not found: godoc.org / github.com/nanobox-io/golang-hatchet from:

    For an example of a qualified logger see here.

    Using a nil Logger results in lumber for a console log, ok, for playing around.

    Also, there isn't an Open for an existing database, so something like this would be nice:

    // Open an existing scribble database at the desired directory location, and
    // return a *Driver to then use for interacting with the database
    func Open(dir string, logger Logger) (driver *Driver, err error) {
        dir = filepath.Clean(dir)
    
        // ensure the database location does exist
        if _, err := os.Stat(dir); err != nil {
            fmt.Printf("Database, '%s' does not exist.\n", dir)
            os.Exit(1)
        }
    
        if logger == nil {
            logger = lumber.NewConsoleLogger(lumber.INFO)
        }
    
        driver = &Driver{
            dir:     dir,
            mutexes: make(map[string]sync.Mutex),
            log:     logger,
        }
    
        logger.Info("Opening scribble database at '%v'...\n", dir)
    
        return driver, nil
    }
    

    ... or perhaps that isn't a valid use case (well, it is for me). Thanks for scribble.

  • List ID of records from a collection

    List ID of records from a collection

    usage eg.:

    func userGetList() []*userS {
        usersIDs, err := db.List("user")
        if err != nil {
            panic(err)
        }
    
        users := make([]*userS, len(usersIDs))
        for i, userID := range usersIDs {
            if err := db.Read("user", userID, &users[i]); err != nil {
                panic(err)
            }
        }
    }
    
  • Support for glide ?

    Support for glide ?

    I tried to add scribble to my code using

    glide get github.com/nanobox-io/golang-scribble
    

    I am prompted for my GitHub username and password but I get the after providing which I get the following error

    [WARN]	Unable to checkout github.com/nanobox-io/golang-scribbl
    [ERROR]	Update failed for github.com/nanobox-io/golang-scribbl: Unable to get repository
    [ERROR]	Failed to checkout packages: Unable to get repository
    

    Can we have this package available through glide as well?

  • Allow reading of empty collection

    Allow reading of empty collection

    Hi, I changed the code to simply return an empty array if the folder for the collections doesn't already exists. Otherwise we would have to check in the code each time if it exists, which I find counterintuitiv and also not perfect for performance. Otherwise I would like to add a methode to create the collections add the beginning.

  • README examples don't compile

    README examples don't compile

    The examples show how to read everything from a database:

    // Read all fish from the database, unmarshaling the response.
    records, err := db.ReadAll("fish")
    if err != nil {
      fmt.Println("Error", err)
    }
    
    fish := []Fish{}
    if err := json.Unmarshal([]byte(records), &fish); err != nil {
      fmt.Println("Error", err)
    }
    

    However, db.ReadAll returns a []string, which cannot be cast to []byte in the call to json.Unmarshal.

  • Fix mutex being copied & wrong mutex key

    Fix mutex being copied & wrong mutex key

    The get getOrCreateMutex function copies mutexes which the golang docs specifically tell us not to do: https://golang.org/pkg/sync/#Mutex Changed the mutex map to pointers to avoid this happening.

    Also, the delete function was creating a mutex for the resource, not the collection.

  • Fix/cleanup

    Fix/cleanup

    just general clean up of a few things that will eventually cause issues.

    • files are now written to a temporary location first. This fixes a situation where a file is truncated, and the scribble process exists before completing the write. DATALOSS
    • mutex locks are now unlocked in defer statements, this fixes situations where a lock is held and the not unlocked because errors cause the function to return early.
  • Add newline to json and fix dereferencing error in read()

    Add newline to json and fix dereferencing error in read()

    This PR fixes issues #26 and #28.

    It's super small, adding a newline with a one line change to fix #26.

    In another it changes a function call to no longer "reference" a variable that is already a pointer. This fixes #28.

  • scribble.read() hides json.InvalidUnmarshalError

    scribble.read() hides json.InvalidUnmarshalError

    Passing a receiving variable by value to scribble.Read() results in a silent failure to populate it. The underlying json.Unmarshall() handles correctly returns an error, but it does not propagate.

    I believe this happens because scribble.read() "references" (puts ampersand in front of) the v variable). This means that json.Unmarshall() gets the pointer it expects and populates it, but in reality, it is a pointer to a local copy of v inside scribble.read().

    I believe the fix is to remove the ampersand from the last line of scribble.read(). There is no need to include it, because the value must already be a pointer, and it should be passed as is to json.Unmarshall().

    Basically, change:

    func read(record string, v interface{}) error {
    
    	b, err := ioutil.ReadFile(record + ".json")
    	if err != nil {
    		return err
    	}
    
    	// unmarshal data
    	return json.Unmarshal(b, &v)
    }
    

    to

    func read(record string, v interface{}) error {
    
    	b, err := ioutil.ReadFile(record + ".json")
    	if err != nil {
    		return err
    	}
    
    	// unmarshal data
    	return json.Unmarshal(b, v)
    }
    

    After applying this fix locally, all my unit tests of scribble still pass, but passing a v variable by value results in an error as expected and desired.

  • Newline at end of file no longer working (regression)

    Newline at end of file no longer working (regression)

    I noticed that the change to add a newline to the end of json files, that got committed in 40263ff was reverted again without any comment in 4116320 (the otherwise very nice pull request #21).

    Given that there was no note regarding that, I'm thinking that it was an inadvertent regression. I really like having the newline.

    Looks like a very simple fix, just to add that code back at the end of write() prior to writing the marshaled data to temp file.

    	// marshal the pointer to a non-struct and indent with tab
    	b, err := json.MarshalIndent(v, "", "\t")
    	if err != nil {
    		return err
    	}
    
    	// add newline to the end
    	b = append(b, byte('\n'))
    
    	// write marshaled data to the temp file
    	if err := ioutil.WriteFile(tmpPath, b, 0644); err != nil {
    		return err
    
    
  • scribble.Driver.Delete should return os.ErrNotExist

    scribble.Driver.Delete should return os.ErrNotExist

    scribble.Driver.Delete returns an opaque error type for non-existent keys which makes it hard for the clients to distinguish between different kind of errors. This behavior is also inconsistent with the scribble.Driver.Read API.

  • Add context for TODO

    Add context for TODO "Better support for concurrency"

    Please add some context around the TODO item "Better support for concurrency." What exactly are the current weaknesses when it comes to concurrency?

☄ The golang convenient converter supports Database to Struct, SQL to Struct, and JSON to Struct.
☄ The golang convenient converter supports Database to Struct, SQL to Struct, and JSON to Struct.

Gormat - Cross platform gopher tool The golang convenient converter supports Database to Struct, SQL to Struct, and JSON to Struct. 中文说明 Features Data

Dec 20, 2022
Owl is a db manager platform,committed to standardizing the data, index in the database and operations to the database, to avoid risks and failures.

Owl is a db manager platform,committed to standardizing the data, index in the database and operations to the database, to avoid risks and failures. capabilities which owl provides include Process approval、sql Audit、sql execute and execute as crontab、data backup and recover .

Nov 9, 2022
This is a simple graph database in SQLite, inspired by "SQLite as a document database".

About This is a simple graph database in SQLite, inspired by "SQLite as a document database". Structure The schema consists of just two structures: No

Jan 3, 2023
Hard Disk Database based on a former database

Hard Disk Database based on a former database

Nov 1, 2021
Beerus-DB: a database operation framework, currently only supports Mysql, Use [go-sql-driver/mysql] to do database connection and basic operations

Beerus-DB · Beerus-DB is a database operation framework, currently only supports Mysql, Use [go-sql-driver/mysql] to do database connection and basic

Oct 29, 2022
Membin is an in-memory database that can be stored on disk. Data model smiliar to key-value but values store as JSON byte array.

Membin Docs | Contributing | License What is Membin? The Membin database system is in-memory database smiliar to key-value databases, target to effici

Jun 3, 2021
A tiny date object in Go. Tinydate uses only 4 bytes of memory

go-tinydate A tiny date object in Go. Tinydate uses 4 bytes of memory vs the 24 bytes of a standard time.Time{} A tinydate only has day precision. It

Mar 17, 2022
Golang in-memory database built on immutable radix trees

go-memdb Provides the memdb package that implements a simple in-memory database built on immutable radix trees. The database provides Atomicity, Consi

Jan 7, 2023
pure golang key database support key have value. 非常高效实用的键值数据库。
pure golang key database support key have value.  非常高效实用的键值数据库。

orderfile32 pure golang key database support key have value The orderfile32 is standard alone fast key value database. It have two version. one is thi

Apr 30, 2022
A simple memory database. It's nothing but a homework to learn primary datastruct of golang.

A simple memory database. It's nothing but a homework to learn primary datastruct of golang.

Nov 8, 2021
Rk-db - Enterprise level database bootstrapper with YAML based on rk-entry in Golang

rk-db Enterprise level database bootstrapper with YAML in golang. This belongs to rk-boot family. We suggest use this lib from rk-boot. Database Statu

Nov 16, 2022
This is a simple Golang application that executes SQL commands to clean up a mirror node's database.

This is a simple Golang application that executes SQL commands to clean up a mirror node's database.

Jan 24, 2022
A lightweight document-oriented NoSQL database written in pure Golang.
A lightweight document-oriented NoSQL database written in pure Golang.

Lightweight document-oriented NoSQL Database ???? English | ???? 简体中文 | ???? Spanish CloverDB is a lightweight NoSQL database designed for being simpl

Jan 1, 2023
An embedded key/value database for Go.

bbolt bbolt is a fork of Ben Johnson's Bolt key/value store. The purpose of this fork is to provide the Go community with an active maintenance and de

Jan 1, 2023
BuntDB is an embeddable, in-memory key/value database for Go with custom indexing and geospatial support
BuntDB is an embeddable, in-memory key/value database for Go with custom indexing and geospatial support

BuntDB is a low-level, in-memory, key/value store in pure Go. It persists to disk, is ACID compliant, and uses locking for multiple readers and a sing

Dec 30, 2022
CockroachDB - the open source, cloud-native distributed SQL database.
CockroachDB - the open source, cloud-native distributed SQL database.

CockroachDB is a cloud-native SQL database for building global, scalable cloud services that survive disasters. What is CockroachDB? Docs Quickstart C

Jan 2, 2023
ACID key-value database.

Coffer Simply ACID* key-value database. At the medium or even low latency it tries to provide greater throughput without losing the ACID properties of

Dec 7, 2022
A decentralized, trusted, high performance, SQL database with blockchain features
A decentralized, trusted, high performance, SQL database with blockchain features

中文简介 CovenantSQL(CQL) is a Byzantine Fault Tolerant relational database built on SQLite: ServerLess: Free, High Availabile, Auto Sync Database Service

Jan 3, 2023
Native GraphQL Database with graph backend
Native GraphQL Database with graph backend

The Only Native GraphQL Database With A Graph Backend. Dgraph is a horizontally scalable and distributed GraphQL database with a graph backend. It pro

Jan 4, 2023