All Projects → proullon → Ramsql

proullon / Ramsql

Licence: bsd-3-clause
In-memory SQL engine in Go sql/driver for testing purpose

Programming Languages

go
31211 projects - #10 most used programming language

Projects that are alternatives of or similar to Ramsql

Imdbpy
IMDbPY is a Python package useful to retrieve and manage the data of the IMDb movie database about movies, people, characters and companies
Stars: ✭ 792 (+81.24%)
Mutual labels:  sql, database, imdb
Pg timetable
pg_timetable: Advanced scheduling for PostgreSQL
Stars: ✭ 382 (-12.59%)
Mutual labels:  sql, database
Dbeaver
Free universal database tool and SQL client
Stars: ✭ 23,752 (+5335.24%)
Mutual labels:  sql, database
Tpt Oracle
Tanel Poder's Troubleshooting & Performance Tools for Oracle Databases
Stars: ✭ 429 (-1.83%)
Mutual labels:  sql, database
Hyrise
Hyrise is a research in-memory database.
Stars: ✭ 371 (-15.1%)
Mutual labels:  sql, database
Hive
Apache Hive
Stars: ✭ 4,031 (+822.43%)
Mutual labels:  sql, database
Ignite
Apache Ignite
Stars: ✭ 4,027 (+821.51%)
Mutual labels:  sql, database
Jupyterlab Sql
SQL GUI for JupyterLab
Stars: ✭ 336 (-23.11%)
Mutual labels:  sql, database
Sqlhooks
Attach hooks to any database/sql driver
Stars: ✭ 397 (-9.15%)
Mutual labels:  sql, database
Edge Sql
Cloudflare Workers providing a SQL API
Stars: ✭ 429 (-1.83%)
Mutual labels:  sql, database
Dotmim.sync
A brand new database synchronization framework, multi platform, multi databases, developed on top of .Net Standard 2.0. https://dotmimsync.readthedocs.io/
Stars: ✭ 406 (-7.09%)
Mutual labels:  sql, database
Dataset
Easy-to-use data handling for SQL data stores with support for implicit table creation, bulk loading, and transactions.
Stars: ✭ 4,110 (+840.5%)
Mutual labels:  sql, database
Lbadd
LBADD: An experimental, distributed SQL database
Stars: ✭ 362 (-17.16%)
Mutual labels:  sql, database
Jet
Type safe SQL builder with code generation and automatic query result data mapping
Stars: ✭ 373 (-14.65%)
Mutual labels:  sql, database
Go Sqlmock
Sql mock driver for golang to test database interactions
Stars: ✭ 4,003 (+816.02%)
Mutual labels:  sql, database
Grdb.swift
A toolkit for SQLite databases, with a focus on application development
Stars: ✭ 4,637 (+961.1%)
Mutual labels:  sql, database
Gnorm
A database-first code generator for any language
Stars: ✭ 415 (-5.03%)
Mutual labels:  sql, database
Freezer
A simple & fluent Android ORM, how can it be easier ? RxJava2 compatible
Stars: ✭ 326 (-25.4%)
Mutual labels:  sql, database
Datafuse
Datafuse is a free Cloud-Native Analytics DBMS(Inspired by ClickHouse) implemented in Rust
Stars: ✭ 327 (-25.17%)
Mutual labels:  sql, database
Franchise
🍟 a notebook sql client. what you get when have a lot of sequels.
Stars: ✭ 3,823 (+774.83%)
Mutual labels:  sql, database

RamSQL

Build Status

Disposable SQL engine

RamSQL has been written to be used in your project's test suite.

Unit testing in Go is simple, create a foo_test.go import testing and run go test ./.... But then there is SQL queries, constraints, CRUD...and suddenly you need a PostgresSQL, setup scripts and nothing is easy anymore.

The idea is to avoid setup, DBMS installation and credentials management as long as possible. A unique engine is tied to a single sql.DB with as much sql.Conn as needed providing a unique DataSourceName. Bottom line : One DataSourceName per test and you have full test isolation in no time.

Installation

  go get github.com/proullon/ramsql

Usage

Let's say you want to test the function LoadUserAddresses :

func LoadUserAddresses(db *sql.DB, userID int64) ([]string, error) {
	query := `SELECT address.street_number, address.street FROM address 
							JOIN user_addresses ON address.id=user_addresses.address_id 
							WHERE user_addresses.user_id = $1;`

	rows, err := db.Query(query, userID)
	if err != nil {
		return nil, err
	}

	var addresses []string
	for rows.Next() {
		var number int
		var street string
		if err := rows.Scan(&number, &street); err != nil {
			return nil, err
		}
		addresses = append(addresses, fmt.Sprintf("%d %s", number, street))
	}

	return addresses, nil
}

Use RamSQL to test it in a disposable isolated in-memory SQL engine :

package myproject 

import (
	"database/sql"
	"fmt"
	"testing"

	_ "github.com/proullon/ramsql/driver"
)


func TestLoadUserAddresses(t *testing.T) {
	batch := []string{
		`CREATE TABLE address (id BIGSERIAL PRIMARY KEY, street TEXT, street_number INT);`,
		`CREATE TABLE user_addresses (address_id INT, user_id INT);`,
		`INSERT INTO address (street, street_number) VALUES ('rue Victor Hugo', 32);`,
		`INSERT INTO address (street, street_number) VALUES ('boulevard de la République', 23);`,
		`INSERT INTO address (street, street_number) VALUES ('rue Charles Martel', 5);`,
		`INSERT INTO address (street, street_number) VALUES ('chemin du bout du monde ', 323);`,
		`INSERT INTO address (street, street_number) VALUES ('boulevard de la liberté', 2);`,
		`INSERT INTO address (street, street_number) VALUES ('avenue des champs', 12);`,
		`INSERT INTO user_addresses (address_id, user_id) VALUES (2, 1);`,
		`INSERT INTO user_addresses (address_id, user_id) VALUES (4, 1);`,
		`INSERT INTO user_addresses (address_id, user_id) VALUES (2, 2);`,
		`INSERT INTO user_addresses (address_id, user_id) VALUES (2, 3);`,
		`INSERT INTO user_addresses (address_id, user_id) VALUES (4, 4);`,
		`INSERT INTO user_addresses (address_id, user_id) VALUES (4, 5);`,
	}

	db, err := sql.Open("ramsql", "TestLoadUserAddresses")
	if err != nil {
		t.Fatalf("sql.Open : Error : %s\n", err)
	}
	defer db.Close()

	for _, b := range batch {
		_, err = db.Exec(b)
		if err != nil {
			t.Fatalf("sql.Exec: Error: %s\n", err)
		}
	}

	addresses, err := LoadUserAddresses(db, 1)
	if err != nil {
		t.Fatalf("Too bad! unexpected error: %s", err)
	}

	if len(addresses) != 2 {
		t.Fatalf("Expected 2 addresses, got %d", len(addresses))
	}

}

Done. No need for a running PostgreSQL or a setup. Your tests are isolated, and compliant with go tools.

RamSQL binary

Let's say you have a SQL describing your application structure:

CREATE TABLE IF NOT EXISTS address (id BIGSERIAL PRIMARY KEY, street TEXT, street_number INT);
CREATE TABLE IF NOT EXISTS user_addresses (address_id INT, user_id INT);

You may want to test its validity:

$ go install github.com/proullon/ramsql
$ ramsql < schema.sql
ramsql> Query OK. 1 rows affected
ramsql> Query OK. 1 rows affected
$ echo $?
0

Features

Unit testing

  • Full isolation between tests
  • No setup (either file or databases)
  • Good performance

SQL parsing

  • Databse schema validation
  • ALTER file validation

Stress testing

  • File system full error with configurable maximum database size
  • Random configurable slow queries
  • Random deconnection
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].