Pas un fork — du SQL ordinaire pour le PostgreSQL que vous avez déjà

La forme de Keal sur PostgreSQL.

Un schéma et ses requêtes dans un même fichier, dans la syntaxe de Keal, vérifiés l'un contre l'autre : une colonne que le schéma n'a pas, ou un null là où il l'interdit, est une erreur de compilation. La sortie est du SQL qu'un PostgreSQL non modifié exécute.

blog.kealsql▸ sql
table User {
    id:      Id
    name:    Slug
    unique email: String
    bio:     String?
}

table Post {
    id:       Id
    cascade author: RefId<User>
    editor:   RefId<User>?
    title:    String
    status:   Status
    created:  Timestamp

    // A method on the row, for the programs that read it.
    func headline(): String { "${this.title} [${this.status}]" }
}

func byAuthor(name: String): List<(Int, String)> {
    from(Post as p)
        .where(p.author.name == name)
        .where(status == Published)
        .orderBy(created.desc)
        .select(p.id, p.title)
}

func editorOf(post: Int): String? {
    from(Post).where(id == post).select(editor?.name).first()
}
-- func editorOf(post: Int): String?
PREPARE editor_of(integer) AS
SELECT editor.name
FROM post
LEFT JOIN "user" AS editor ON post.editor = editor.id
WHERE post.id = $1
LIMIT 1;

La null-safety contre le schéma

String est NOT NULL, String? est nullable, et ?. à travers une référence est un LEFT JOIN. Le type du résultat dit quelle jointure a eu lieu.

La logique ternaire, rendue visible

Bool3 n'apparaît que si un opérande est nullable. Le compilateur dit où un == peut valoir unknown — et === traite null comme une valeur.

Des migrations par diff

Le fichier est le schéma. --migrate lit le catalogue et imprime ce qui amène la base au fichier ; les étapes destructives sont retenues jusqu'à ce que vous le disiez.

Du Keal dans le serveur

Les corps de stored func et de trigger sont du Keal, compilé via C en fonctions LANGUAGE C — les plus rapides que PostgreSQL connaisse — qui appellent les requêtes du fichier, typées.

Les mêmes requêtes depuis un programme

Un programme Keal importe le .kealsql lui-même et obtient une méthode typée par requête sur une connexion libpq. L'application n'écrit jamais de SQL, et une colonne renommée l'empêche de compiler.

Un fichier, trois endroits où l'exécuter.

Le SQL compilé se charge dans psql comme instructions préparées. Le client en fait des méthodes dans un programme Keal. Et une fonction stockée les appelle depuis l'intérieur du serveur, via SPI, avec les mêmes types aux trois endroits.

psqlun programme Kealdans PostgreSQL

Un transpileur, délibérément.

La performance d'une requête est une propriété du SQL émis et du planificateur de PostgreSQL, pas du front-end. Le SQL est construit à la compilation, donc chaque requête est une instruction préparée constante — exactement ce qu'une main soigneuse écrirait — et tout l'écosystème, de pg_dump à l'hébergement managé, continue de marcher.

En route en une minute.

shell
git clone https://github.com/geneacta/kealsql
cd kealsql
keal fetch
tests/run.sh
keal src/main.keal blog.kealsql > blog.sql
createdb blog
psql -d blog -f blog.sql

Puis le guide : créer une base, l'utiliser, la faire évoluer →