# cozo
![Cozo License](https://img.shields.io/github/license/niamtokik/cozo)
![Cozo Top Language](https://img.shields.io/github/languages/top/niamtokik/cozo)
![Cozo Workflow Status (main branch)](https://img.shields.io/github/actions/workflow/status/niamtokik/cozo/test.yaml?branch=main)
![Cozo Last Commit](https://img.shields.io/github/last-commit/niamtokik/cozo)
![Cozo Code Size (bytes)](https://img.shields.io/github/languages/code-size/niamtokik/cozo)
![Cozo Repository File Count](https://img.shields.io/github/directory-file-count/niamtokik/cozo)
![Cozo Repository Size](https://img.shields.io/github/repo-size/niamtokik/cozo)
This is an Erlang NIF wrapper for [CozoDB](https://www.cozodb.org), a FOSS embeddable, transactional, relational-graph-vector database, with time travelling capability, perfect as the long-term memory for LLMs and AI.
## Support
- [x] `cozo_open_db` with `cozo:open/0` and `cozo:open/2`.
- [x] `cozo_close_db` with `cozo:close/1`
- [x] `cozo_run_query` with `cozo:run/2`, `cozo:run/3` and `cozo:run/4`
- [x] `cozo_import_relations` with `cozo:import_relations/2`
- [x] `cozo_export_relations` with `cozo:export_relations/2`
- [x] `cozo_backup` with `cozo:backup/2`
- [x] `cozo_restore` with `cozo:restore/2`
- [x] `cozo_import_from_backup` with `cozo:import_backup/2`
## Todo
- [ ] Create test suite for `cozo` module
- [x] test `cozo:open` function
- [x] test `cozo:close` function
- [x] test `cozo:run` function
- [ ] test `cozo:import_relations` function
- [ ] test `cozo:export_relation` function
- [ ] test `cozo:backup` function
- [ ] test `cozo:restore` function
- [ ] test `cozo:import_backup` function
- [x] Create `cozo_db` module to deal with strong isolation
- [x] Create test suite for `cozo_nif` module
- [x] Specify interfaces
- [ ] Add property based testing support
- [x] Add Dialyzer support
- [ ] Create more usage example
- [ ] Create distributed example
- [ ] Check if `cozo_nif.c` is safe
## Build
This project is using `Makefile` to extend the capability of
rebar3. everything can be easily done with it.
```sh
make all
# or
make deps compile
```
## Test
A full test suite is present in `test/cozo_SUITE.erl` file, using the
cozodb tutorial present in the official documentation as template.
```sh
make test
```
## Documentation
Generate the project documentation.
```sh
make doc
```
Open the documentation.
```sh
open doc/index.html
```
## Usage
Open a shell with `make`
```sh
make shell
```
If you want to create a totally isolated database in its own process,
you can use `cozo_db` module.
```erlang
% open a new database in memory
{ok, Pid} = cozo_db:start([]).
% run a query
{ok,#{ <<"headers">> => [<<"_0">>,<<"_1">>,<<"_2">>],
<<"next">> => null,
<<"ok">> => true,
<<"rows">> => [[1,2,3]],
<<"took">> => 0.001401927
}
} = cozo_db:run(Pid, "?[] <- [[1, 2, 3]]").
% close the database
ok = cozo_db:stop(Pid).
```
If you want to create more than one process and you don't care about
isolation, you can use `cozo` module.
```erlang
% open a new database in memory
{ok, {0, _}} = cozo:open().
% run a query
{ok,#{ <<"headers">> => [<<"_0">>,<<"_1">>,<<"_2">>],
<<"next">> => null,
<<"ok">> => true,
<<"rows">> => [[1,2,3]],
<<"took">> => 0.001401927
}
} = cozo:run(Db, "?[] <- [[1, 2, 3]]").
% close the database
ok = cozo:close(Db).
```
If you want an access to a low level interface, you can also use
`cozo_nif` module.
## Examples
Some examples are present in `examples` directory like a cozo over
tcp, you can use with telnet or netcat.
```erlang
c("examples/cozo_tcp.erl").
{ok, Pid} = cozo_tcp:start().
```
```shell
nc localhost 6543
# ?[] <- [[1,2,3]]
```
## References
- [Official CozoDB Website](https://www.cozodb.org/)
- [Official CozoDB Documentation](https://docs.cozodb.org/en/latest/)
- [Official CozoDB Repository](https://github.com/cozodb/cozo)
- [Erlang NIF](https://www.erlang.org/doc/tutorial/nif.html)