README.md

# 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)