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.
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;
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.
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.
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.
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.
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.
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.
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.
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 →