Document-oriented, embedded SQL database

Overview

Genji

Genji

Document-oriented, embedded, SQL database

Table of contents

Introduction

Build Status go.dev reference Slack channel Fuzz

Genji is a schemaless database that allows running SQL queries on documents.

Checkout the SQL documentation, the Go doc and the usage example in the README to get started quickly.

⚠️ Genji's API is still unstable: Database compatibility is not guaranteed before reaching v1.0.0

Features

  • Optional schemas: Genji tables are schemaless, but it is possible to add constraints on any field to ensure the coherence of data within a table.
  • Multiple Storage Engines: It is possible to store data on disk or in ram, but also to choose between B-Trees and LSM trees. Genji relies on BoltDB and Badger to manage data.
  • Transaction support: Read-only and read/write transactions are supported by default.
  • SQL and Documents: Genji mixes the best of both worlds by combining powerful SQL commands with JSON.
  • Easy to use, easy to learn: Genji was designed for simplicity in mind. It is really easy to insert and read documents of any shape.
  • Compatible with the database/sql package

Installation

Install the Genji database

go get github.com/genjidb/genji

Usage

There are two ways of using Genji, either by using Genji's API or by using the database/sql package.

Using Genji's API

package main

import (
    "context"
    "fmt"
    "log"

    "github.com/genjidb/genji"
    "github.com/genjidb/genji/document"
)

func main() {
    // Create a database instance, here we'll store everything on-disk using the BoltDB engine
    db, err := genji.Open("my.db")
    if err != nil {
        log.Fatal(err)
    }
    // Don't forget to close the database when you're done
    defer db.Close()

    // Attach context, e.g. (*http.Request).Context().
    db = db.WithContext(context.Background())

    // Create a table. Schemas are optional, you don't need to specify one if not needed
    err = db.Exec("CREATE TABLE user")

    // Create an index
    err = db.Exec("CREATE INDEX idx_user_name ON test (name)")

    // Insert some data
    err = db.Exec("INSERT INTO user (id, name, age) VALUES (?, ?, ?)", 10, "Foo1", 15)

    // Supported values can go from simple integers to richer data types like lists or documents
    err = db.Exec(`
    INSERT INTO user (id, name, age, address, friends)
    VALUES (
        11,
        'Foo2',
        20,
        {"city": "Lyon", "zipcode": "69001"},
        ["foo", "bar", "baz"]
    )`)

    // Go structures can be passed directly
    type User struct {
        ID              uint
        Name            string
        TheAgeOfTheUser float64 `genji:"age"`
        Address         struct {
            City    string
            ZipCode string
        }
    }

    // Let's create a user
    u := User{
        ID:              20,
        Name:            "foo",
        TheAgeOfTheUser: 40,
    }
    u.Address.City = "Lyon"
    u.Address.ZipCode = "69001"

    err = db.Exec(`INSERT INTO user VALUES ?`, &u)

    // Query some documents
    res, err := db.Query("SELECT id, name, age, address FROM user WHERE age >= ?", 18)
    // always close the result when you're done with it
    defer res.Close()

    // Iterate over the results
    err = res.Iterate(func(d document.Document) error {
        // When querying an explicit list of fields, you can use the Scan function to scan them
        // in order. Note that the types don't have to match exactly the types stored in the table
        // as long as they are compatible.
        var id int
        var name string
        var age int32
        var address struct {
            City    string
            ZipCode string
        }

        err = document.Scan(d, &id, &name, &age, &address)
        if err != nil {
            return err
        }

        fmt.Println(id, name, age, address)

        // It is also possible to scan the results into a structure
        var u User
        err = document.StructScan(d, &u)
        if err != nil {
            return err
        }

        fmt.Println(u)

        // Or scan into a map
        var m map[string]interface{}
        err = document.MapScan(d, &m)
        if err != nil {
            return err
        }

        fmt.Println(m)
        return nil
    })
}

Using database/sql

// import Genji as a blank import
import _ "github.com/genjidb/genji/sql/driver"

// Create a sql/database DB instance
db, err := sql.Open("genji", "my.db")
if err != nil {
    log.Fatal(err)
}
defer db.Close()

// Then use db as usual
res, err := db.ExecContext(...)
res, err := db.Query(...)
res, err := db.QueryRow(...)

Engines

Genji currently supports storing data in BoltDB, Badger and in-memory.

Using the BoltDB engine

import (
    "log"

    "github.com/genjidb/genji"
)

func main() {
    db, err := genji.Open("my.db")
    defer db.Close()
}

Using the memory engine

import (
    "log"

    "github.com/genjidb/genji"
)

func main() {
    db, err := genji.Open(":memory:")
    if err != nil {
        log.Fatal(err)
    }
    defer db.Close()
}

Using the Badger engine

First install the module

go get github.com/genjidb/genji/engine/badgerengine
import (
    "context"
    "log"

    "github.com/genjidb/genji"
    "github.com/genjidb/genji/engine/badgerengine"
    "github.com/dgraph-io/badger/v2"
)

func main() {
    // Create a badger engine
    ng, err := badgerengine.NewEngine(badger.DefaultOptions("mydb"))
    if err != nil {
        log.Fatal(err)
    }

    // Pass it to genji
    db, err := genji.New(context.Background(), ng)
    if err != nil {
        log.Fatal(err)
    }
    defer db.Close()
}

Genji shell

The genji command line provides an SQL shell that can be used to create, modify and consult Genji databases.

Make sure the Genji command line is installed:

go get github.com/genjidb/genji/cmd/genji

Example:

# Opening an in-memory database:
genji

# Opening a BoltDB database:
genji my.db

# Opening a Badger database:
genji --badger pathToData

Contributing

Contributions are welcome!

See ARCHITECTURE.md and CONTRIBUTING.md.

Thank you, contributors!

If you have any doubt, join the Gophers Slack channel or open an issue.

Comments
  • Database is deadlocking

    Database is deadlocking

    Hi, I've been experimenting with Genji v0.8.0 in one of my apps:

    https://github.com/simpleiot/simpleiot/blob/feature-genji2/db/genji/genji.go

    After I click around in the frontend a bit, API calls start timing out.

    I instrumented the db calls, and learned that if one of the calls starts before the previous one finishes, the API calls start timing out soon after that.

    Am I doing anything obviously wrong? I'm using boltdb backend and thought boltdb was thread safe. Do I need to wrap all db operations in transactions?

    bug 
    opened by cbrake 13
  • TIKV as the distributed storage engine

    TIKV as the distributed storage engine

    opened by rock59 11
  • Automate releases

    Automate releases

    This PR automates publishing new releases.

    To publish a new release, just git push release. The new version is automatically inferred based on API changes. Alternatively, it’s possible to override this behavior (e.g. if we have breaking changes in cmd/genji but not in Go API) by pushing to release-v0.13.0 branch, or manually dispatching a workflow with version inputs.

    The workflow then creates version bump commits for Genji’s submodules and tags them. In the end it creates a draft release with changelog (additionally using CHANGELOG.md if it exists). When GitHub release is published, another CI workflow kicks in that builds and uploads binaries as release assets.

    Additionally, version bump commits are only reachable from tags so it should be safe to dispatch the workflow on main branch.

    That said, this should also eliminate the need to manually manage unreleased versions in go.mod.

    workflow

    Build matrix
    Build matrix

    Closes #269

    opened by tie 9
  • Support AUTO_INCREMENT.

    Support AUTO_INCREMENT.

    This a proposal draft for #43.

    SQL Server seems good because it proposes a customizable AUTO_INCREMENT with a "natural language".

    ### Default value
    CREATE TABLE foo (id INTEGER AUTO_INCREMENT);
    INSERT INTO foo VALUES {"a": "foo"};
    SELECT * FROM foo;
    { "a": "foo", "id": 1}
    
    ### Set a start index and an increment value;
    ###`AUTO_INCREMENT(startIndex, incBy)`
    ###The first value of the sequence start at 10 and the next is incremented by 5
    CREATE TABLE bar (id INTEGER AUTO_INCREMENT(10, 5));
    INSERT INTO bar VALUES {"a": "bar"};
    INSERT INTO bar VALUES {"a": "baz"};
    SELECT * FROM bar;
    { "a": "bar", "id": 10 }
    {  "a": "baz", "id": 15 }
    

    AUTO_INCREMENT have to be applied only on number value type. INTEGER and DOUBLE

    genji> CREATE TABLE foo(bar TEXT AUTO_INCREMENT);
    genji> found text, expected integer, double at line 1, char 27
    

    About ALTER TABLE table_name AUTO_INCREMENT=100, If we keep it like that, we should be able to write the both following syntaxes:

    ###For default value
    ALTER TABLE foo AUTO_INCREMENT=100;
    
    ### And this even if the creation was with default value
    ALTER TABLE foo AUTO_INCREMENT(100, 10);
    

    Thank you for your feedbacks.

    opened by tzzed 9
  • tableInfoStore should be scoped to transaction

    tableInfoStore should be scoped to transaction

    Currently database.Database holds a reference to tableInfoStore that is shared between all transactions which, among other things, may create/rename/alter/drop tables. This violates the transaction isolation.

    Make sure INSERT is indeed isolated.
    package main
    
    import (
    	"github.com/dgraph-io/badger/v2"
    	"github.com/genjidb/genji"
    	"github.com/genjidb/genji/engine/badgerengine"
    )
    
    func main() {
    	ng, err := badgerengine.NewEngine(badger.DefaultOptions("").WithInMemory(true))
    	if err != nil { panic(err) }
    	db, err := genji.New(ng)
    	if err != nil { panic(err) }
    
    	err = db.Exec("CREATE TABLE tb (id INTEGER PRIMARY KEY)")
    	if err != nil { panic(err) }
    
    	// Does panic with "duplicate document" error unless committed.
    	for i := 0; i < 2; i++ {
    		tx, err := db.Begin(true)
    		if err != nil { panic(err) }
    		defer tx.Rollback()
    		err = tx.Exec("INSERT INTO tb (id) VALUES (?)", 42)
    		if err != nil { panic(err) }
    	}
    }
    
    Make sure that CREATE INDEX is indeed isolated.
    package main
    
    import (
    	"github.com/dgraph-io/badger/v2"
    	"github.com/genjidb/genji"
    	"github.com/genjidb/genji/engine/badgerengine"
    )
    
    func main() {
    	ng, err := badgerengine.NewEngine(badger.DefaultOptions("").WithInMemory(true))
    	if err != nil { panic(err) }
    	db, err := genji.New(ng)
    	if err != nil { panic(err) }
    
    	err = db.Exec("CREATE TABLE tb")
    	if err != nil { panic(err) }
    
    	// Does panic with "index already exists" error unless committed.
    	for i := 0; i < 2; i++ {
    		tx, err := db.Begin(true)
    		if err != nil { panic(err) }
    		err = tx.Exec("CREATE UNIQUE INDEX idx ON tb(id)")
    		if err != nil { panic(err) }
    	}
    }
    
    Reproduce the bug. Panics with "table already exists" error.
    package main
    
    import (
    	"github.com/dgraph-io/badger/v2"
    	"github.com/genjidb/genji"
    	"github.com/genjidb/genji/engine/badgerengine"
    )
    
    func main() {
    	ng, err := badgerengine.NewEngine(badger.DefaultOptions("").WithInMemory(true))
    	if err != nil { panic(err) }
    	db, err := genji.New(ng)
    	if err != nil { panic(err) }
    
    	// We never commit the transaction, so these changes should be isolated
    	// from other concurrent (but not necessarily parallel) transactions.
    	for i := 0; i < 2; i++ {
    		tx, err := db.Begin(true)
    		if err != nil { panic(err) }
    		err = tx.Exec("CREATE TABLE tb")
    		if err != nil { panic(err) }
    	}
    }
    

    Tangentially related to #210 since it needs concurrent transactions.

    opened by tie 9
  • SQL driver doesn't support timestamp (time.Time)

    SQL driver doesn't support timestamp (time.Time)

    I have seen an issue about supporting time.Time in sql driver: https://github.com/genjidb/genji/issues/154.

    But it seems that time.Time still doesn't work. Parser doesn't recognize keyword TIMESTAMP (not surprisingly, no changes was made in driver in corresponding MR for that issue).

    package main
    
    import (
    	"database/sql"
    	"fmt"
    	"time"
    
    	_ "github.com/genjidb/genji/sql/driver"
    )
    
    func main() {
    	db, err := sql.Open("genji", ":memory:")
    	if err != nil {
    		panic(err)
    	}
    	defer db.Close()
    
    	_, err = db.Exec(`CREATE TABLE foo (created_at TIMESTAMP NOT NULL)`)
    	if err != nil {
    		panic(err)
    	}
           //...
    

    Prints:

    panic: found TIMESTAMP, expected ) at line 1, char 30
    

    Scanning time.Time stored as TEXT doesn't work either:

    package main
    
    import (
    	"database/sql"
    	"fmt"
    	"time"
    
    	_ "github.com/genjidb/genji/sql/driver"
    )
    
    func main() {
    	db, err := sql.Open("genji", ":memory:")
    	if err != nil {
    		panic(err)
    	}
    	defer db.Close()
    
    	_, err = db.Exec(`CREATE TABLE foo (created_at TEXT NOT NULL)`)
    	if err != nil {
    		panic(err)
    	}
    
    	_, err = db.Exec(`INSERT INTO foo (created_at) VALUES (?)`, time.Now().UTC())
    	if err != nil {
    		panic(err)
    	}
    
    	rows, err := db.Query(`SELECT created_at FROM foo`)
    	if err != nil {
    		panic(err)
    	}
    	defer rows.Close()
    	for rows.Next() {
    		var createdAt time.Time
    		if err := rows.Scan(&createdAt); err != nil {
    			panic(err)
    		}
    		fmt.Printf("foo found: (%v)", createdAt)
    	}
    	if err := rows.Err(); err != nil {
    		panic(err)
    	}
    }
    

    Prints:

    panic: sql: Scan error on column index 0, name "created_at": unsupported Scan, storing driver.Value type string into type *time.Time
    

    Is this a bug or I misusing sql driver?

    bug 
    opened by Darkclainer 8
  • Add support for context.Context

    Add support for context.Context

    This PR adds context.Context support in Genji, starting with the engine package and then fixing compile errors everywhere. It doesn’t introduce any cancellation behavior though—that should be a separate, smaller, PR.

    • engine.Iterator usage now requires a it.Err() check after the loop.

      it := st.Iterator(engine.IteratorOptions{})
      defer it.Close()
      
      for it.Seek(ctx, nil); it.Valid(); it.Next(ctx) {
      	…
      }
      if err := it.Err(); err != nil {
      	…
      }
      

      Notice that Seek and Next now accept a context.Context parameter. If an error occurs, Valid returns false.

    • database.Table no longer directly implements document.Iterator since iteration may be I/O bound.

      // Before
      func (*Table) Iterate(func(d document.Document) error) error
      // After
      func (*Table) Iterator(context.Context) document.IteratorFunc
      func (*Table) Iterate(context.Context, func(d document.Document) error) error
      

    Closes #224 and #206

    opened by tie 8
  • Merge key and document packages

    Merge key and document packages

    This PR removes the key package and moves its content to 3 different locations:

    • Add MarshalBinary, UnmarshalBinary and Append to Value type. These methods encode values without type information.
    • Add ValueEncoder type which can different types in the same namespace while keeping ordering between types. It is the type used for untyped indexes.
    • Add a pkg/nsb package for naturally sorted binary representation of supported variables.

    This was done because we are going to need the ValueEncoder from within the document package, which currently provokes a cyclic dependency with the key package.

    opened by asdine 7
  • Add Bitcask backend

    Add Bitcask backend

    KV Store: https://github.com/prologic/bitcask

    Currently the master branch is (really) unstable as I'm basically breaking everything with a sledgehammer. The engine package though (the one that contains interfaces that need to be implemented) wasn't touch in the master branch so it should be good.

    Also, I'd really like to avoid having too many dependencies with Genji (especially because of the store implementations) so I think it should be better if the Bitcask package had its own go.mod. In next release, every backends will have their own go.mod so users will be able to choose explicitly the store they want to use. This also means that you'll have to base your work on the v0.1.0 tag, which is fine I suppose, as I said there aren't that many changes in the engine on the master branch.

    Regarding tests, there is a engine/enginetest package that contains importable tests that make sure your backend is compatible, you can take a look at the other backends if you need examples.

    engine 
    opened by asdine 7
  • msgpack codec encodes all integers type into int64 rather than picking the right type

    msgpack codec encodes all integers type into int64 rather than picking the right type

    What version of Genji are you using?

    The main branch.

    $ genji version
    Genji v0.11.0
    Genji CLI (devel)
    

    Does this issue reproduce with the latest release?

    Yes

    What did you do?

    (Preamble, I know that all sql INT* types are just document.IntegerValue under the hood, I'm talking at codec level here).

    While reading the msgpack codec, my eye was caught by https://github.com/genjidb/genji/blob/8e580748aedb60ec007df65013936287ec5dcc21/document/encoding/msgpack/codec.go#L100-L111 which says that the int types will be encoded using they msg pack counterpart, ie int8 -> int8, but the code didn't look like it handles those case.

    While digging, I found out that:

    • all integers end up as int64 anyway when reaching the codec
    • even if fed an int8, EncodeValue will end up using an int64 in msgpack because it uses case document.IntegerValue: return e.enc.EncodeInt64(v.V.(int64)) under the hood.

    ➡️ It looks to me that the comment is wrong and that the int64 encoding for all ints is actually on purpose as per what the decoder does here: https://github.com/genjidb/genji/blob/main/document/encoding/msgpack/codec.go#L221

    ❓ @asdine Is that a deliberate choice here? Is it related to how msgpack work somehow? Otherwise it looks like it's a rather low hanging fruit to have more compact integer storage.


    package main
    
    import (
    	"bytes"
    	"context"
    	"fmt"
    	"os"
    
    	"github.com/genjidb/genji"
    	"github.com/genjidb/genji/engine"
    	"github.com/genjidb/genji/engine/boltengine"
    	mp "github.com/vmihailenco/msgpack/v5"
    )
    
    func main() {
    	// so we always get the same store id every run, see line 52
    	_ = os.Remove("test.db")
    
    	db, err := genji.Open("test.db")
    	if err != nil {
    		panic(err)
    	}
    
    	err = db.Exec("CREATE TABLE foo ( a INTEGER )")
    	if err != nil {
    		panic(err)
    	}
    
    	err = db.Exec("INSERT INTO foo (a) VALUES (?)", 2)
    	if err != nil {
    		panic(err)
    	}
    
    	err = db.Close()
    	if err != nil {
    		panic(err)
    	}
    
    	ng1, err := boltengine.NewEngine("test.db", 0o600, nil)
    	if err != nil {
    		panic(err)
    	}
    
    	etx, err := ng1.Begin(context.Background(), engine.TxOptions{})
    	if err != nil {
    		panic(err)
    	}
    
    	//  func (t *tableInfoStore) Insert(tx *Transaction, tableName string, info *TableInfo) error {
    	//		(...)
    	//      fmt.Println(info.storeName)
    	store, err := etx.GetStore([]byte{116, 1})
    	if err != nil {
    		panic(err)
    	}
    
    	it := store.Iterator(engine.IteratorOptions{})
    	it.Seek(nil)
    
    	item := it.Item()
    
    	k := item.Key()
    
    	b, err := store.Get(k)
    	if err != nil {
    		panic(err)
    	}
    
    	fmt.Println(b)
    
    	dec := mp.NewDecoder(bytes.NewReader(b))
    
    	ii, err := dec.DecodeInterface()
    	if err != nil {
    		panic(err)
    	}
    
            // ➡️ ### What did you expect to see? ⬅️
    	fmt.Printf("%$v\n", ii)
    }
    
    

    What did you expect to see?

    [129 161 97 2]
    map[%!$(string=a):%!$(int8=2)]v
    

    What did you see instead?

    [129 161 97 211 0 0 0 0 0 0 0 2]
    map[%!$(string=a):%!$(int64=2)]v
    

    What Go version and environment are you using?

    $ go version
    go version go1.15.8 darwin/amd64
    
    go env Output
    $ go env
    GO111MODULE="on"
    GOARCH="amd64"
    GOBIN="/Users/tech/code/bin"
    GOCACHE="/Users/tech/Library/Caches/go-build"
    GOENV="/Users/tech/Library/Application Support/go/env"
    GOEXE=""
    GOFLAGS=""
    GOHOSTARCH="amd64"
    GOHOSTOS="darwin"
    GOINSECURE=""
    GOMODCACHE="/Users/tech/code/pkg/mod"
    GONOPROXY=""
    GONOSUMDB=""
    GOOS="darwin"
    GOPATH="/Users/tech/code"
    GOPRIVATE=""
    GOPROXY="https://proxy.golang.org,direct"
    GOROOT="/Users/tech/.asdf/installs/golang/1.15.8/go"
    GOSUMDB="sum.golang.org"
    GOTMPDIR=""
    GOTOOLDIR="/Users/tech/.asdf/installs/golang/1.15.8/go/pkg/tool/darwin_amd64"
    GCCGO="gccgo"
    AR="ar"
    CC="clang"
    CXX="clang++"
    CGO_ENABLED="1"
    GOMOD="/Users/tech/code/src/github.com/genjidb/play/go.mod"
    CGO_CFLAGS="-g -O2"
    CGO_CPPFLAGS=""
    CGO_CXXFLAGS="-g -O2"
    CGO_FFLAGS="-g -O2"
    CGO_LDFLAGS="-g -O2"
    PKG_CONFIG="pkg-config"
    GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/xl/dfsx6nzs4cb2y40m555mlfjh0000gn/T/go-build230471881=/tmp/go-build -gno-record-gcc-switches -fno-common"
    

    bug 
    opened by jhchabran 6
  • Add dump command

    Add dump command

    $ genji dump -h
    NAME:
       genji dump - Dump a database or a table as a text file.
    
    USAGE:
       genji dump [options] dbpath
    
    DESCRIPTION:
      The dump command can dump a database as a text file.
    
      By default, the content of the database is sent to the standard output:
    
      $ genji dump my.db
      CREATE TABLE foo;
      ...
    
      It is possible to specify a list of tables to output:
    
      $ genji dump -t foo -f bar my.db
    
      The dump command can also write directly into a file:
    
      $ genji dump -f dump.sql my.db
    
    OPTIONS:
       --table value, -t value   name of the table to dump, it must already exist. Defaults to all tables.
       --file value, -f value       name of the file to output to. Defaults to STDOUT
       --help, -h                show help (default: false)
    
    cli 
    opened by asdine 6
  • Why return a error sometimes when insert or update a record?

    Why return a error sometimes when insert or update a record?

    What version of Genji are you using?

    v0.15.1

    What did you do?

    data := UserLog{
       ...
    }
    func InsertData(db *genji.DB, sql string, data ...interface{}) error {
    	err := db.Exec(sql, data...)
    	return err
    }
    err := InsertData(db, "INSERT INTO USERLOG VALUES ?", &data)
    

    What did you expect to see?

    error is nil. It is not returned error all the time but sometimes. The error is not always the same, it seems like random string,

    Wraps: (2) "ER\xda\x05tableO\xda" not found
    Wraps: (2) "SER\x05\x02\x15J\fTER" not found
    

    Usually error will disappear if I restart program. I don't know why, I just insert a record use struct.

    What did you see instead?

    (1) attached stack trace
      -- stack trace:
      | github.com/genjidb/genji/internal/database.(*catalogCache).Get
      |     github.com/genjidb/[email protected]/internal/database/catalog.go:792
      | github.com/genjidb/genji/internal/database.(*Catalog).GetSequence
      |     github.com/genjidb/[email protected]/internal/database/catalog.go:509
      | github.com/genjidb/genji/internal/database.(*Table).generateKey
      |     github.com/genjidb/[email protected]/internal/database/table.go:186
      | github.com/genjidb/genji/internal/database.(*Table).Insert
      |     github.com/genjidb/[email protected]/internal/database/table.go:41
      | github.com/genjidb/genji/internal/stream/table.(*InsertOperator).Iterate.func1
      |     github.com/genjidb/[email protected]/internal/stream/table/insert.go:46
      | github.com/genjidb/genji/internal/stream/table.(*ValidateOperator).Iterate.func1
      |     github.com/genjidb/[email protected]/internal/stream/table/validate.go:67
      | github.com/genjidb/genji/internal/stream/docs.(*EmitOperator).Iterate
      |     github.com/genjidb/[email protected]/internal/stream/docs/emit.go:39
      | github.com/genjidb/genji/internal/stream/table.(*ValidateOperator).Iterate
      |     github.com/genjidb/[email protected]/internal/stream/table/validate.go:41
      | github.com/genjidb/genji/internal/stream/table.(*InsertOperator).Iterate
      |     github.com/genjidb/[email protected]/internal/stream/table/insert.go:30
      | github.com/genjidb/genji/internal/stream.(*DiscardOperator).Iterate
      |     github.com/genjidb/[email protected]/internal/stream/stream.go:129
      | github.com/genjidb/genji/internal/stream.(*Stream).Iterate
      |     github.com/genjidb/[email protected]/internal/stream/stream.go:34
      | github.com/genjidb/genji/internal/query/statement.(*StreamStmtIterator).Iterate
      |     github.com/genjidb/[email protected]/internal/query/statement/stream.go:70
      | github.com/genjidb/genji/internal/query/statement.(*Result).Iterate
      |     github.com/genjidb/[email protected]/internal/query/statement/statement.go:59
      | github.com/genjidb/genji.(*Result).Iterate
      |     github.com/genjidb/[email protected]/db.go:366
      | github.com/genjidb/genji.(*Statement).Exec
      |     github.com/genjidb/[email protected]/db.go:353
      | github.com/genjidb/genji.(*DB).Exec
      |     github.com/genjidb/[email protected]/db.go:160
      | runtime.goexit
      |     runtime/asm_amd64.s:1594
    Wraps: (2) "64\x05\xe6\x02\xda\x04NODE" not found
    Error types: (1) *withstack.withStack (2) *errors.NotFoundError
    
    bug 
    opened by handewo 3
  • Import json file

    Import json file

    • Added support to import json files
    • Separated csv insert logic into InsertCSV function and moved it to "cmd/genji/dbutil/insert.go"

    Refers #444

    opened by abramlab 0
  • Consider switching to a different K/V store

    Consider switching to a different K/V store

    Proposal

    Currently, Genji uses Pebble as its K/V store. Pebble is maintained by CockroachDB, and they have said many times that it is meant to match the roadmap of CockroachDB itself, and that features outside of that are a low priority. As I mentioned in #485, Pebble prevents Genji from compiling on 32-bit platforms such as GOARCH=386 and GOARCH=arm. It also fails to compile on riscv64. This is because Pebble uses build tags to detect 64-bit architectures, and every architecture has to be added explicitly to each file that uses them. The developers of Pebble have stated that this is not a priority for them.

    I propose a switch to a different K/V store that compiles on more platforms, such as https://github.com/etcd-io/bbolt, or the addition of an interface to allow users to choose whichever implementation they want.

    Motivation

    Nearly all other databases compile and run on 32-bit platforms. This change would alleviate all platform restrictions imposed by Pebble. There are many 32-bit machines and even some 64-bit machines that weren't able to use Genji before but will be able to if this is implemented.

    enhancement 
    opened by Arsen6331 0
  • Genji does not compile for 32-bit platforms

    Genji does not compile for 32-bit platforms

    What version of Genji are you using?

    $ genji version
    Genji v0.15.1
    Genji CLI v0.15.1
    

    What did you do?

    Attempted to compile a program importing GenjiDB with GOARCH=386

    What did you expect to see?

    Successful compilation

    What did you see instead?

    # github.com/cockroachdb/pebble/internal/batchskl
    ../../.go/pkg/mod/github.com/cockroachdb/[email protected]/internal/batchskl/skl.go:310:18: maxNodesSize (untyped int constant 4294967295) overflows int
    ../../.go/pkg/mod/github.com/cockroachdb/[email protected]/internal/batchskl/skl.go:320:16: cannot use maxNodesSize (untyped int constant 4294967295) as int value in assignment (overflows)
    

    This appears to be an issue with Pebble (cockroachdb/pebble#2120)

    bug 
    opened by Arsen6331 0
  • Column name

    Column name "value" causes syntax error

    What version of Genji are you using?

    0.15.1
    

    What did you do?

    First, I created a table with no schema:

    CREATE TABLE IF NOT EXISTS settings
    

    Then I tried to query the table:

    res, err := db.Query(`SELECT name, value FROM settings`)
    

    What did you expect to see?

    Given I had not populated any rows, an empty result set.

    What did you see instead?

    parsing error:

    found VALUE, expected  at line 1, char 14
    

    Given I change the column name in the select to val it works. This is what makes me think it's an issue with the parser. I believe the error returned could be improved as well. It looks like the expected value passed to the message cannot render as string.

    bug 
    opened by aarongodin 0
Releases(v0.15.1)
  • v0.15.1(Jul 14, 2022)

    This release contains a few bug fixes:

    • orderby: fix evaluation of ORDER BY expr when used with projection #471
    • errors: publish error functions to easily determine if an error is a NotFoundError or an AlreadyExists error. 492cdbe26b2f2f415a37912f291e552af7484eaa
    • pebble: use custom Separator function. Without this, Pebble would sometimes generate an incompatible key that would cause a panic a35719a72759576a2527bfda0007f7c157354bb8
    Source code(tar.gz)
    Source code(zip)
  • v0.15.0(Jun 29, 2022)

    Genji v0.15.0 is out and comes a few big architectural changes 🚀

    Goodbye Bolt and Badger, hello Pebble

    Historically, Genji started as a layer on top of the amazing Bolt and Badger. As features were being added, Genji is pretending to become more and more like a full featured SQL database, and thus needed more flexibility than what Bolt and Badger could offer.

    Things like custom key comparators (to control how keys are organized in the tree), snapshots, concurrent read/writes (in Bolt only), were missing greatly. Both came with their own transaction mechanism which were a bit limiting for Genji (limited number of writes per transaction, no support for transaction promotion, etc.). Also, having to maintain both data layers came with lots of challenges that we believe wasn't worth it.

    That's why we decided to use a single backend: Pebble.

    Pebble comes with lots of nice features, here are the ones we consider particularly interesting for Genji:

    • No transactions (this is a good thing, we have our own now!)
    • Batches
    • Snapshots
    • Can also be used in-memory only
    • Full control on how the tree is organized

    New transaction mechanism

    Pebble doesn't come with its own transactions mechanism, so we had to implement our own, which comes will lots of advantages:

    • Reads don't block writes, writes don't block reads: Read transactions always operate on the latest snapshot and don't require any locking. Write transactions use small in-memory batches which are atomically persisted alongside a rollback segment. The rollback segment contains undo changes to apply if the transaction is rolled back or if the database crashes.
    • Fully serializable transactions: Genji supports multiple readers at a time and a single writer. This doesn't change from the previous releases, however we believe having a single writer should be more than enough in a embedded setting.
    • Arbitrarily large transactions: Write transactions can contain a virtually unlimited number of changes while guaranteeing they won't be taking more than 10MB of ram (hardcoded value for this release). This allows to run Genji on small devices without worrying about the ram usage.
    • Super fast writes: This release doesn't come with any official benchmark but our own biased ones showed that when inserting large documents, writes are twice as fast as the amazing SQLite (with WAL mode). Again, this is on a very specific benchmark, on a very specific device. But it is promising.

    New CREATE TABLE API

    The CREATE TABLE statement introduces new rules for table creation that gives much more control.

    By default, a table now only inserts fields that have been declared. Any other field will be ignored and not inserted.

    CREATE TABLE foo (a INTEGER, b TEXT);
    INSERT INTO foo (a, b, c) VALUES (1, 'hello', 'not inserted');
    INSERT INTO foo VALUES {a: 2, b: 'bye', c: 'not inserted'};
    SELECT * FROM foo;
    
    {
      "a": 1,
      "b": "hello"
    }
    {
      "a": 2,
      "b": "bye"
    }
    

    If you want to insert any field, and only care about declaring a few ones, you can use the ... notation.

    CREATE TABLE foo (a INTEGER, b TEXT, ...);
    INSERT INTO foo (a, b, c) VALUES (1, 'hello', 'inserted');
    SELECT * FROM foo;
    
    {
      "a": 1,
      "b": "hello"
      "c": "inserted"
    }
    
    

    Nested fields are now declared like this:

    CREATE TABLE user (
        name TEXT,
        address (
            number INTEGER,
            street TEXT,
            zipcode TEXT NOT NULL
        )
    );
    INSERT INTO user (name, address) VALUES (
        "Ilias",
        {
            number: 10,
            street: "rue de la paix",
            zipcode: "12345"
        }
    );
    

    Drop support for WASM and TinyGo

    Historically, Genji has invested a lot of efforts in supporting TinyGo in the hopes of being compiled in WASM and being used in the browser. However, because of the lack of support for certain packages of the standard library (like reflect, fmt, encoding/jsom, etc.), it was very difficult for us to keep maintaining compatibility across different releases. Even when we managed to compile, TinyGo would produce very large files (> 3MB), which defeats the purpose of using it. We may reconsider this in the future as the support for Wasm in TinyGo becomes more mature.

    Breaking changes and data format stability

    ⚠️ This release introduces a big refactoring and thus is not compatible with previous versions. ⚠️ It also only support Go 1.18+ as it relies on the new generics feature introduced in Go 1.18.

    However, the database format is almost stable and future releases should not introduce any breaking changes. If that happens, we will over communicate and provide ways to make it transparent as much as possible.

    Our goal is to reach v1 very soon 🚀

    Other notable changes

    • index: treat all NULL values differently in UNIQUE indexes by @asdine in https://github.com/genjidb/genji/commit/2d4df658e47e276364be3d33c42ebc6856e86f70
    • index: use index with BETWEEN operator by @asdine in https://github.com/genjidb/genji/commit/a304e806ff2f0934b8fcd75762d6bd65aadc32ff
    • index: prevent index creation on undeclared paths by @asdine in https://github.com/genjidb/genji/commit/3f32bcbf19161b856c7dcbb47dcc0657790ad2e4
    • cli: fix genji restore command with certains whitespace characters by @tzzed in https://github.com/genjidb/genji/pull/439
    • cli: add .timer shell command by @tzzed in https://github.com/genjidb/genji/pull/445
    • cli: ensure the inserts are run in the same transaction in genji insert by @tzzed in https://github.com/genjidb/genji/commit/b4606f7cdfd9c025b83b85e1c3c28f05b277a56a
    • sql: fix UPDATE behavior with primary keys by @asdine in https://github.com/genjidb/genji/commit/f81f3f18f04df59fd6fa0c13b8c97e38bb3a1228
    • sql: support params in LIMIT and OFFSET by @asdine in https://github.com/genjidb/genji/commit/6178d1acfb341950f83631a48132fde3b78382bf

    Full Changelog: https://github.com/genjidb/genji/compare/v0.14.0...v0.15.0

    Source code(tar.gz)
    Source code(zip)
  • v0.14.1(Dec 22, 2021)

  • v0.14.0(Dec 9, 2021)

    SQL

    • Add more math functions by @jhchabran in https://github.com/genjidb/genji/pull/421
    • Parse blob literal by @asdine in https://github.com/genjidb/genji/pull/423
    • Add typeof function by @asdine in bba4c0a63006e936644301483d6f7a0d29283f37
    • Handle integer conversion errors by @jhchabran in https://github.com/genjidb/genji/pull/425
    • Add support for scientific notation for doubles by @asdine in d3b81ad6f1a3c58b471123dc38ada766fc215f14
    • Parse optional parentheses on DEFAULT clause by @asdine in 1654f358d40b2d611afdffb48d95045fc0bc6461
    • Add support for UNION by @asdine in 412d30030d97c9d6414a91e08ad0f114a75c6f4b
    • Add support for CHECK by @asdine in https://github.com/genjidb/genji/pull/436
    • Add support for composite primary keys by @asdine in 8983d68daf1d030e5a2282ac39cdf76d637bdac8

    CLI

    • Add bench command by @asdine in 74603aa55e815bc97dd5d5aca5a9fea9fc8f78ed
    • Fix .indexes command when transaction is active by @asdine in d5fd8796d760e12bb5adcf23fdf3fdc956a57f2f

    Other

    • Improve failures readability when testing exprs by @jhchabran in https://github.com/genjidb/genji/pull/426
    • Add support for transient databases by @asdine in a45d2c1ae57cd6605a630888b55813a65e2b4d7a
    • Improved planner logic by @asdine in https://github.com/genjidb/genji/pull/428
    • Add errors package with optional stacktrace capturing by @jhchabran in https://github.com/genjidb/genji/pull/431
    • Refactor to handle errors with internal/errors by @jhchabran in https://github.com/genjidb/genji/pull/432
    • Parse path fields with brackets by @asdine in cfdb78487fe124ed804c9627168ed22d26888a92
    • Fixed filling index types when loading indices from existing db by @KudinovKV in https://github.com/genjidb/genji/pull/434
    • Use same tree structure for both tables and indexes by @asdine (⚠️ Breaking change) in a7309a70c50167679b4ec1152a36ab559de8d8ab
    • Fix goacc and CI by @asdine in https://github.com/genjidb/genji/pull/435

    New Contributors

    • @KudinovKV made their first contribution in https://github.com/genjidb/genji/pull/434

    Full Changelog: https://github.com/genjidb/genji/compare/v0.13.0...v0.14.0

    Source code(tar.gz)
    Source code(zip)
  • v0.13.0(Jul 21, 2021)

    SQL

    • Add concat operator
    • Add NOT operator
    • Add BETWEEN operator
    • Add INSERT ... RETURNING
    • Add ON CONFLICT
    • Add UNION ALL #408 (@jhchabran)
    • Add CREATE SEQUENCE
    • Add DROP SEQUENCE
    • Add NEXT VALUE FOR

    Core

    • Add document.NewFromCSV
    • Add prepared statements
    • Add new __genji_catalog table and drop __genji_table and __genji_indexes
    • Remove engine.NextSequence

    CLI

    • Add .import command

    This release also contains various bug fixes.

    Source code(tar.gz)
    Source code(zip)
  • v0.12.0(May 1, 2021)

    SQL

    • Added support for composite indexes #376 (⚠️Breaking change) @jhchabran
    • Added support for UNIQUE table constraint #387
    • Added support for PRIMARY KEY table constraint #333
    • Added support for INSERT ... SELECT #385
    • Indexes can be created with a generated name now #386

    Core

    • Fix indexed array comparisons with numbers #378
    • Fix a bug preventing the use of time.Time with driver.Scanner #258

    CLI

    • Added a new way of writing integration tests: Examplar #380 @jhchabran
    • Added .schema command #339 @tzzed
    Source code(tar.gz)
    Source code(zip)
  • v0.11.0(Mar 24, 2021)

    SQL

    • Add OFFSET, LIMIT and ORDER BY to DELETE statement #318 #319 #320 @jhchabran
    • fix: query returning no result when using ORDER BY with sql/driver implementation #352 @tzzed

    Core

    • New Stream API #343
    • Update Badger to v3 #350
    • Integers are now compacted when encoded #351 (⚠️Breaking change) @jhchabran
    • Infer constraints based on user-defined ones #358
    • Queries using primary keys are much faster #310
    • fix: Encoding of consecutive integers in arrays #362 @jhchabran
    • fix: Incorrect index state with UPDATE queries on indexed fields #355 #368
    • fix: Build index upon creation #371
    • fix: BLOB to byte array decoding #305

    CLI

    • New genji dump command #315 @tzzed
    • New genji restore command #321 @tzzed
    • fix: .dump not outputting DEFAULT clause #329 @jhchabran
    • fix: Deadlock when trying to open a locked database #365
    • fix: Panic on genji insert when specified engine doesn't exist #331
    Source code(tar.gz)
    Source code(zip)
  • v0.10.0(Jan 26, 2021)

    SQL

    • fix: COUNT(*) with empty set #284
    • fix: Selection of field in GROUP BY expression #317
    • fix: Index selection of IN operator #281

    Core

    • Update msgpack #340 @kenshaw
    • fix: Panic when optimizer returns empty tree #283 @goku321

    CLI

    • Add .save command #311 @jhchabran
    Source code(tar.gz)
    Source code(zip)
  • v0.9.0(Nov 12, 2020)

    SQL

    • Drop Duration type #212 @asdine
    • Expose the __genji_indexes table #214 @tzzed
    • Add ALTER TABLE ... ADD FIELD ... #96 @tdakkota
    • Prevent creating a table if constraints are incoherent #222 @tdakkota
    • Add LIKE operator #241 @tdakkota
    • Add SELECT DISTINCT #264 @tdakkota
    • fix: IN operator behavior with parentheses #207 @tdakkota
    • fix: Panic when parsing large integers #256 @goku321
    • fix: Ignore currently unsupported regex operators #252 @tie
    • fix: Panic on SELECT with LIMIT min(0)/max(0) #257 @goku321
    • fix: Panic when running GROUP BY on array values #208 @asdine

    Core

    • Implement driver.DriverContext and driver.Connector interfaces in sql/driver #213 @tie
    • Add support for context.Context #206 #224 @tie @asdine
    • Slightly more efficient conversion from JSON to document #270 @asdine
    • Add support for embedded structs to document.NewFromStruct #225 @tzzed
    • Numbers are stored as double by default, unless a field constraint is specified during table creation #312 @asdine (:warning: Breaking change)
    • fix: CI tests with nested modules #232 @tie
    • fix: badgerengine benchmarks #209 @tie
    • fix: Be more forgiving when scanning null values in StructScan #211 @tie
    • fix: Badger tests on Windows #288 @tie
    • ci: Add support for fuzzing #253 @tie

    CLI

    • Respect NO_COLOR and NO_HISTORY environment variables #215 @tie
    • Add .dump command #181 @tzzed
    • Add version command #184 @cvhariharan
    • Add support for exit and help commands without leading dot #180 @Amirhossein2000
    • fix: Autocompletion panic when there is no suggestion #178 @tdakkota
    • fix: Panic on genji version when compiled in GOPATH mode #261 @tdemin
    Source code(tar.gz)
    Source code(zip)
  • v0.8.1(Oct 30, 2020)

  • v0.8.0(Sep 26, 2020)

    SQL

    • Add BEGIN, ROLLBACK, and COMMIT statements #78
    • Add support for paths in UPDATE statement #84
    • Add GROUP BY clause #6
    • Add COUNT aggregator #5
    • Add MIN aggregator #165
    • Add MAX aggregator #166
    • Add SUM aggregator #4

    Core

    • Add codec system #177
    • Remove introduction text when reading from STDIN #179
    • Improved how values are indexed #194
    • Indexes created on field who has a typed constraint are now typed #195
    • Add support for array and document indexes #199
    • Removed encoding/json dependency and use jsonparser instead #203

    CLI

    • Add table autocompletion #143
    • Add index autocompletion #157
    • Add command suggestions #163

    Bug fixes

    • Fix order of SELECT ast nodes #188
    • MapScan now decodes nested documents #191
    • Fix saving of history when .exit was called #196
    Source code(tar.gz)
    Source code(zip)
  • v0.7.1(Sep 1, 2020)

  • v0.7.0(Aug 25, 2020)

    SQL

    • Add REINDEX statement #72
    • Add ALTER TABLE ... RENAME TO ... statement #95
    • Add new __genji_tables table #152
    • Allow referencing current document in expression #147

    Core

    • Removed fixed size integers #130
    • Renamed float64 type to double #130
    • Integers are now converted to double prior to comparison and indexing #146
    • Encode documents using MessagePack #117
    • Move badgerengine into its own module #140
    • Replaced memoryengine with custom implementation #139
    • Store table information in memory #142
    • Add support for time.Time in document.StructScan

    CLI

    • Add .help command #160
    • Add .indexes command #100
    • Add table suggestions after FROM keyword #159
    • Ignore input with whitespace only #106

    Bug fixes

    • Prevent primary key overlap with concurrent inserts #74
    • Fix behavior of ValueBuffer#Copy #111
    • Fix UPDATE ... SET clause setting the wrong array indexes #91
    • Fix display of field names with backquotes #64
    • Arithmetic operators return null for incompatible types #105
    • Fix parentheses behavior #131
    • Fix CAST behavior #138
    • Remove transaction promotion #150
    Source code(tar.gz)
    Source code(zip)
  • v0.6.0(Jun 28, 2020)

    SQL

    • Added support for IS and IS NOT #75
    • Added support for IN and NOT IN #76 #81
    • Added support for UPDATE ... UNSET #68
    • Added support for field constraints for missing types #85
    • Added support for EXPLAIN #102

    Core

    • Added support for Cursors to Engines #40
    • Added query planner #88

    Bug fixes

    • Fix null to text conversion #66
    • Make UPDATE ... SET set a field to every matching document #82
    • Fix panic when ORDER BY is used with an indexed field #71
    • Fix DROP TABLE behavior that used to remove all database indexes #99
    • Normalize behavior of boolean field constraint with incompatible types #89
    Source code(tar.gz)
    Source code(zip)
  • v0.5.0(Mar 5, 2020)

    • Support NOT NULL field constraints
    • Support Bitwise operators
    • Support Duration values
    • Support SELECT without table reference
    • Support arithmetic operators
    • Support AS
    • Support CAST
    • Use Badger as main in memory engine
    Source code(tar.gz)
    Source code(zip)
  • v0.4.0(Jan 5, 2020)

    Core

    • Support for Documents
    • Functions for translating structs and maps into documents
    • Renamed references to Record to Document
    • Moved database logic to database package

    SQL

    • Insert documents using document notation
    • Select sub fields
    • Support for ORDER BY
    • Support for field constraints

    Misc

    • Removed code generation temporarily
    • Improved shell auto completion
    Source code(tar.gz)
    Source code(zip)
  • v0.3.0(Nov 23, 2019)

    Changelog

    Core

    • New (db/tx).QueryRecord method to query a single record
    • New db.SQLDB method that wraps the db into a database/sql db
    • New tx.ListTables method
    • New tx.ReIndex method
    • New tx.ReIndexAll method
    • New index implementation
    • Moved package recordutil to record
    • New record.Scan method

    SQL

    • Support key() function to return the primary key
    • Support specifying primary key of any type during a CREATE TABLE statement
    • Generate autoincrementing default key instead of uuid
    • Support multiple wildcards, fields and functions in SELECT statement
    • Support != operator
    • Support == operator as an alias for =
    • Better support for NULL
    • Parsed integers are converted to the smallest int size that fits
    • Double quoted strings are now treated exclusively as identifiers
    • Where expression containing only the primary key will benefit from a primary key optimization
    • Float32 numbers no longer supported

    Engines

    • Open a BoltDB database without referencing the engine
    • Badger now has its own module
    • Upgrade Badger to v2
    • Renamed engine/memory to engine/memoryengine
    • Renamed engine/bolt to engine/boltengine
    • Renamed engine/badger to engine/badgerengine

    Command-line tool

    • Code generation moved under genji generate command
    • Struct fields are lowercased by default
    • Support for struct tag genji:"pk" removed
    • Struct tags are now used to rename a field
    • New SQL shell
    • Store history under $HOME/.genji_history

    database/sql

    • Registers as a driver at startup
    • Support record.Scanner as a scan target
    Source code(tar.gz)
    Source code(zip)
  • v0.2.2(Oct 31, 2019)

    • Fix index not found error
    • Fix support for double quoted strings
    • Fix comparison of floats
    • Fix support for sql.NamedArg
    • Skip nil values during encoding of maps
    • Fix Update behaviour
    Source code(tar.gz)
    Source code(zip)
  • v0.2.1(Oct 21, 2019)

    • BoltDB engine: Fix sparse DELETE by batching the deletion of records
    • Badger engine: Fix panic when using multiple iterators during UPDATE statement
    • DB.Query / DB.Exec: Run each statement in its own transaction
    • Prefetch indexes when getting the table
    • Expect iterator instead of stream in recordutil helpers
    • Fix comparison between list with one element and single value
    Source code(tar.gz)
    Source code(zip)
  • v0.2.0(Oct 19, 2019)

  • v0.1.1(Sep 20, 2019)

  • v0.1.0(Aug 16, 2019)

Owner
Genji
Document-oriented, embedded, SQL database
Genji
Go fearless SQL. Sqlvet performs static analysis on raw SQL queries in your Go code base.

Sqlvet Sqlvet performs static analysis on raw SQL queries in your Go code base to surface potential runtime errors at build time. Feature highlights:

QP Hou 460 Dec 19, 2022
Database Abstraction Layer (dbal) for Go. Support SQL builder and get result easily (now only support mysql)

godbal Database Abstraction Layer (dbal) for go (now only support mysql) Motivation I wanted a DBAL that No ORM、No Reflect、Concurrency Save, support S

徐佳军 56 Nov 17, 2022
A Go (golang) package that enhances the standard database/sql package by providing powerful data retrieval methods as well as DB-agnostic query building capabilities.

ozzo-dbx Summary Description Requirements Installation Supported Databases Getting Started Connecting to Database Executing Queries Binding Parameters

Ozzo Framework 589 Dec 31, 2022
LBADD: An experimental, distributed SQL database

LBADD Let's build a distributed database. LBADD is an experimental distributed SQL database, written in Go. The goal of this project is to build a dat

Tom Arrell 379 Nov 29, 2022
Mocking your SQL database in Go tests has never been easier.

copyist Mocking your SQL database in Go tests has never been easier. The copyist library automatically records low-level SQL calls made during your te

CockroachDB 824 Dec 19, 2022
Additions to Go's database/sql for super fast performance and convenience. (fork of gocraft/dbr)

dbr (fork of gocraft/dbr) provides additions to Go's database/sql for super fast performance and convenience. Getting Started // create a connection (

Free and open source software developed at Mail.Ru 162 Dec 31, 2022
Go library for accessing multi-host SQL database installations

hasql hasql provides simple and reliable way to access high-availability database setups with multiple hosts. Status hasql is production-ready and is

Yandex 106 Dec 28, 2022
Bluge, will this document match this query?

sour Will this bluge.Document match this bluge.Query? This library allows you to efficiently answer this question. s := sour.New(bluge.InMemoryOnlyCo

Bluge Labs 6 Dec 16, 2022
A Golang library for using SQL.

dotsql A Golang library for using SQL. It is not an ORM, it is not a query builder. Dotsql is a library that helps you keep sql files in one place and

Gustavo Chaín 653 Dec 27, 2022
a golang library for sql builder

Gendry gendry is a Go library that helps you operate database. Based on go-sql-driver/mysql, it provides a series of simple but useful tools to prepar

DiDi 1.4k Dec 26, 2022
SQL builder and query library for golang

__ _ ___ __ _ _ _ / _` |/ _ \ / _` | | | | | (_| | (_) | (_| | |_| | \__, |\___/ \__, |\__,_| |___/ |_| goqu is an expressive SQL bu

Doug Martin 1.8k Dec 30, 2022
SQL query builder for Go

GoSQL Query builder with some handy utility functions. Documentation For full documentation see the pkg.go.dev or GitBook. Examples // Open database a

Travis Harmon 27 Dec 12, 2022
Type safe SQL builder with code generation and automatic query result data mapping

Jet Jet is a complete solution for efficient and high performance database access, consisting of type-safe SQL builder with code generation and automa

null 940 Jan 6, 2023
Write your SQL queries in raw files with all benefits of modern IDEs, use them in an easy way inside your application with all the profit of compile time constants

About qry is a general purpose library for storing your raw database queries in .sql files with all benefits of modern IDEs, instead of strings and co

Sergey Treinis 26 Dec 25, 2022
Type safe SQL query builder and struct mapper for Go

sq (Structured Query) ?? ?? sq is a code-generated, type safe query builder and struct mapper for Go. ?? ?? Documentation • Reference • Examples This

null 185 Dec 19, 2022
Fast SQL query builder for Go

sqlf A fast SQL query builder for Go. sqlf statement builder provides a way to: Combine SQL statements from fragments of raw SQL and arguments that ma

Vlad Glushchuk 92 Dec 23, 2022
💥 A lightweight DSL & ORM which helps you to write SQL in Go.

sqlingo is a SQL DSL (a.k.a. SQL Builder or ORM) library in Go. It generates code from the database and lets you write SQL queries in an elegant way.

Qishuai Liu 274 Jan 2, 2023
Fluent SQL generation for golang

sqrl - fat-free version of squirrel - fluent SQL generator for Go Non thread safe fork of squirrel. The same handy fluffy helper, but with extra lette

Ivan Kirichenko 245 Dec 16, 2022
Fluent SQL generation for golang

Squirrel is "complete". Bug fixes will still be merged (slowly). Bug reports are welcome, but I will not necessarily respond to them. If another fork

null 5.4k Jan 6, 2023