An untested attempt to port Oxigraph to the Internet Computer, in order to host an RDF database fully on-chain.
The repository is a fork of oxigraph and has been adapted to be compiled to wasm32-unknown-unknown
Rust target.
For usage reference, see Oxigraph's docs at https://docs.rs/oxigraph.
For this porting, relevant features from Oxigraph are:
- The database written as a Rust library. Its source code is in the
lib
directory. - it implements the following specifications:
- SPARQL 1.1 Query, SPARQL 1.1 Update, and SPARQL 1.1 Federated Query.
- Turtle, TriG, N-Triples, N-Quads, and RDF XML RDF serialization formats for both data ingestion and retrieval using the Rio library.
- SPARQL Query Results XML Format, SPARQL 1.1 Query Results JSON Format and SPARQL 1.1 Query Results CSV and TSV Formats.
The main problems for Oxigraph to run on the Internet Computer were the Date::now() function from js_sys crate and the random number generator from rand crate.
Using time from ic-cdk api, this function has been substituted with:
pub fn now() -> f64 {
(ic_cdk::api::time() / 1_000_000) as f64
}
To register the Random Number Generator you have two options:
-
(default) register a custom getrandom implementation by yourself and pass a
&RefCell<StdRng>
to theinit()
function, which saves it to the local state. Example:use ic_cdk_macros::{init, post_upgrade}; use ic_oxigraph; thread_local! { // Feed the RNG with a seed of 32 bytes and pass this reference to the library. /* flexible */ static RNG_REF_CELL: RefCell<StdRng> = RefCell::new(SeedableRng::from_seed([0_u8; 32])); } #[init] fn init() { RNG_REF_CELL.with(ic_oxigraph::init); // other init code } #[post_upgrade] fn post_upgrade() { RNG_REF_CELL.with(ic_oxigraph::init); // other post_upgrade code like loading the stable memory into the state }
See lib.rs for an example of how to register a custom getrandom implementation. See also Demergent Labs' cdk_framework source code, from which this code has been taken.
-
enable the
internal-rng
feature, which takes care of calling the management canister to get a random seed and register a custom getrandom. Example:use ic_cdk_macros::{init, post_upgrade}; use ic_oxigraph; #[init] fn init() { ic_oxigraph::init(); // other init code } #[post_upgrade] fn post_upgrade() { ic_oxigraph::init(); // other post_upgrade code like loading the stable memory into the state }
In both cases, the
init()
function must be called in theinit
andpost_upgrade
functions of the canister that imports this library.
If you're using rust-analyzer in VSCode, edit this setting to target wasm32-unknown-unknown
and have the correct autocompletion:
{
"rust-analyzer.cargo.target": "wasm32-unknown-unknown"
}
As suggested in this comment, this repository should have a script that automatically removes all the unnecessary code from original Oxigraph's repository, so that updates can be easily merged.
See Oxigraph's GitHub discussions or the Oxigraph's Gitter chat to ask questions or talk about Oxigraph. If you want to report bugs, use Oxigraph's Bug reports.
This project is licensed under MIT license (LICENSE or http://opensource.org/licenses/MIT).
This is an untested implementation that needs a lot of help from the community! Feel free to open PRs :).