aboutsummaryrefslogtreecommitdiffstats
path: root/docs/karuta-integration.org
diff options
context:
space:
mode:
authorMarcos Magueta <maguetamarcos@gmail.com>2026-03-06 21:45:03 -0300
committerMarcos Magueta <maguetamarcos@gmail.com>2026-03-06 21:45:03 -0300
commitfcd8571577f2b98ffc8fa2b95781ed16982804a9 (patch)
tree0d80b3cc6ed0b136ade5f69bdf50895e354d29aa /docs/karuta-integration.org
parentb2b1d9a3a8cbf2f5d0089e29931cacf36297065a (diff)
downloadSakura-fcd8571577f2b98ffc8fa2b95781ed16982804a9.tar.gz
Sakura-fcd8571577f2b98ffc8fa2b95781ed16982804a9.zip
wip: docs update
Diffstat (limited to '')
-rw-r--r--docs/karuta-integration.org130
1 files changed, 130 insertions, 0 deletions
diff --git a/docs/karuta-integration.org b/docs/karuta-integration.org
new file mode 100644
index 0000000..a144a25
--- /dev/null
+++ b/docs/karuta-integration.org
@@ -0,0 +1,130 @@
+* About Karuta
+
+Just like PostgreSQL and MySQL have SQL, Sakura has Karuta, a prolog-like language targetting the BEAM. [[karuta][https://github.com/dont-rely-on-nulls/karuta]] is the programming language that presents the different sublanguages to manage an RDBMS.
+
+We believe that what E. F. Codd envisioned was a stack of sublanguages that are embedded in a more powerful language, that expand it's abstraction scope as you move up the stack, trying to provide guarantees at each level. A data retrieval language should halt and has no business into being Turing Complete, but a predicate procedure language might. In light of this, Sakura is supposed to provide a common DSL that can differentiate between such sublanguages and execute things accordingly.
+
+The approach is that everything is a relation itself. So a constraint for instance is expressed as a relation less_than over NxN instead of simply being an operator '<'.
+
+* Sublanguages
+Here's an overview of the sublanguages and how they are manifested in Karuta:
+
+** DRL (Data Retrieval Language)
+
+- Pure querying, total/terminating subset;
+- No user recursion with no self references.
+
+** DCL (Data Constraint Language)
+
+- Integrity rules (key, FK-like, checks, assertions, aggregates-for-integrity).
+- Semantically predicates, but with enforcement timing (on write/commit), not free query operators.
+
+** DML (Data Manipulation Language)
+
+- Insert/update/delete;
+- Delta semantics, can trigger constraint evaluation.
+
+** DDL (Data Definition Language)
+
+- Define relations/views (ephemeral relations)/indexes/types/modules/predicate signatures and capabilities.
+
+** TCL (Transaction/Control Language)
+
+- Begin/commit/rollback, isolation/consistency controls, maybe savepoints.
+
+** PPL (Procedural Predicate Language)
+
+- Stored procedures/functions, recursion allowed, orchestration logic.
+- Can call DRL/DML/DCL-aware operations, but not all PPL predicates are DRL-safe.
+
+** ACL (Authorization/Policy Language) (optional early, important later)
+
+- Who can query/mutate/define; row/predicate-level access policies.
+
+* Prototype
+
+#+begin_src prolog
+ % DDL
+ :- schema[users] {
+ :- signature[people-sig] {
+ person[_, _].
+ another-person[string, natural].
+ valid_age[natural].
+ a-procedure[int, int].
+ a-view[_, _, _].
+ }.
+ :- module[people, people-sig] {
+ % This is using the arity directly, because the types are being specified in the signature.
+ % These Sakura-provided type extensions after '::' are the what informs Sakura through metadata on connection which type of Karuta predicate this is used as in Karuta.
+ another-person/2 :: sakura:persisted
+ another-person[Name, FavoriteNumber].
+
+ person[string, natural] :: sakura:persisted
+ person[Name, Age] :- valid_age[Age].
+
+ % DCL
+ another-constraint[list[person], string, natural] :: sakura:constraint
+ another-constraint[[], _, _].
+ another-constraint[[person[Name, Age]|Rest], Whatever1, Whatever2] :-
+ (eq[Name, Whatever1] ; !eq[Name, Whatever1], !eq[Age, Whatever2]),
+ another-constraint[Rest, Whatever1, Whatever2].
+
+ % DCL
+ my-predicate[int, string, nat] :: sakura:constraint
+ my-predicate[Arg1, Arg2, Arg3] :-
+ another-module:my-predicate[Arg1, Arg2, Arg3],
+ on[insert, update],
+ timing[immediate].
+
+ % DCL
+ valid_age/1 :: sakura:constraint
+ valid_age[Age] with [karuta, sakura] :-
+ nat[Age],
+ greater_or_equal[Age, 0],
+ % DRL
+ aggregate[person, 2, Tuples],
+ another-constraint[Tuples, "lemos", 26],
+ on[insert, update],
+ timing[immediate],
+ target[age].
+
+ % PPL
+ a-procedure/2 :: sakura:stored
+ a-procedure[Arg1, Arg2] :-
+ eq[Arg1, Arg2].
+
+ % DDL
+ a-view[string, natural, natural] :: sakura:ephemeral
+ a-view[Name, Age, FavoriteNumber] :-
+ person[Name, Age],
+ another-person[Name, FavoriteNumber].
+ }.
+ }.
+
+ my-predicate[users:people:person, string, nat] :: signature
+ my-predicate[Arg1, Arg2, Arg3] :-
+ another-module:my-predicate[Arg1, Arg2, Arg3].
+
+ main[Arg1, Arg2] :-
+ karuta:plus[Arg1, Arg2, Out],
+ karuta:aggregate[numbers:inc, 2, Tuples],
+
+ % Project directive should give us these configurations
+ project:sakura[Secret, Port, Host],
+ project:sakura:config[Users1, Commit],
+
+ sakura:connect[Secret, Port, Host, Connection],
+ sakura:database[Connection, Users1, Commit, DB1Handle],
+
+ % TCL
+ sakura:transaction[TXContext, DB1Handle],
+
+ % DML
+ sakura:insert[users:people:person["Toad", 18], TXContext],
+ (sakura:error?[TXContext, Reason], sakura:rollback[TXContext], print["We rolled back: ~s!", Reason]) ;
+ (sakura:new[TXContext, [name], Difference1],
+ sakura:commit[TXContext, DB2Handle],
+ sakura:delta[DB1Handle, DB2Handle, Difference2],
+ % DRL
+ @relation1[Arg2, Out]).
+#+end_src \ No newline at end of file