An open API service indexing awesome lists of open source software.

https://github.com/haxetink/tink_sql

SQL embedded into Haxe
https://github.com/haxetink/tink_sql

database haxe sql tink

Last synced: 2 months ago
JSON representation

SQL embedded into Haxe

Awesome Lists containing this project

README

          

[![CI](https://github.com/haxetink/tink_sql/workflows/CI/badge.svg)](https://github.com/haxetink/tink_sql/actions)
[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/haxetink/public)

# Tinkerbell SQL

This library embeds SQL right into the Haxe language. Think LINQ (not the syntax sugar, but the framework).

**Breaking Change (2021-09-16)**

[Transaction](#transactions) is now supported with a minor breaking change.
Migration guide: https://github.com/haxetink/tink_sql/pull/130#issuecomment-822971910

## Motivation

Most developers tend to dislike SQL, at least for a significant part of their career. A symptom of that are ever-repeating attempts to hide the database layer behind ORMs, with very limited success.

Relational databases are however a very powerful concept, that was pioneered over 40 years ago.

Tink SQL has been built to embrace using SQL for your database interactions, but in a type safe way that fits with the Haxe ecosystem.

## Defining your schema

Define a database like so:

```haxe
import tink.sql.Types;

typedef User = {
var id:Id;
var name:VarChar<255>;
@:unique var email:VarChar<255>;
var password:VarChar<255>;
}

typedef Post = {
var id:Id;
var author:Id;
var title:LongText;
var url:VarChar<255>;
}

typedef Tag = {
var id:Id;
var name:VarChar<20>;
var desc:Null;
}

typedef PostTags = {
var post:Id;
var tag:Id;
}

@:tables(User, Post, Tag, PostTags)
class Db extends tink.sql.Database {}
```

## Redefining table names

```haxe
class Db extends tink.sql.Database {
@:table("blog_users") var user:User;
@:table("blog_posts") var post:Post;
@:table("news_tags") var tag:Tag;
@:table("post_tags") var postTags:PostTags;
}
```

## Connecting to the database

```haxe
import tink.sql.drivers.MySql;

var driver = new tink.sql.drivers.MySql({
user: 'user',
password: 'pass'
});
var db = new Db('db_name', driver);
```

## Tables API

- Table setup
- `db.User.create(): Promise;`
- `db.User.drop(): Promise;`
- `db.User.truncate(): Promise;`
- Selecting
- `db.User.count(): Promise;`
- `db.User.all(limit, orderBy): Promise>;`
- `db.User.first(orderBy): Promise;`
- `db.User.where(filter)`
- `db.User.select(f:Fields->Selection)`
- Example, select name of user: `db.User.select({name: User.name}).where(User.id == 1).first()`
- Writing
- `db.User.insertOne(row: User): Promise>;`
- `db.User.insertMany(rows: Array): Promise>;`
- `db.User.update(f:Fields->Update, options:{ where: Filter, ?max:Int }): Promise<{rowsAffected: Int}>;`
- Example, rename all users called 'Dave' to 'Donald': `db.User.update(function (u) return [u.name.set('Donald')], { where: function (u) return u.name == 'Dave' } );`
- `db.User.delete(options:{ where: Filter, ?max:Int }): Promise<{rowsAffected: Int}>;`
- Advanced Selecting
- `db.User.as(alias);`
- `db.User.join(db.User).on(id == copiedFrom).all();`
- `db.User.leftJoin(db.User);`
- `db.User.rightJoin(db.User);`
- `db.User.stream(limit, orderBy): tink.streams.RealStream;`

... to be continued ...

## Transactions

```haxe
// transaction with a commit
db.transaction(trx -> {
trx.User.insertOne(...).next(id -> Commit(id)); // user is inserted
});

// transaction with explicit rollback
db.transaction(trx -> {
trx.User.insertOne(...).next(_ -> Rollback); // user insert is rolled back
});

// transaction with implicit rollback upon error
db.transaction(trx -> {
trx.User.insertOne(...).next(_ -> new Error('Aborted')); // user insert is rolled back
});
```