Skip to content

Commit

Permalink
Propose api
Browse files Browse the repository at this point in the history
  • Loading branch information
tarrencev committed Sep 28, 2023
1 parent 57f1e6b commit 45a8e1e
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 52 deletions.
54 changes: 22 additions & 32 deletions crates/dojo-core/src/database.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -37,29 +37,33 @@ fn set(

fn del(class_hash: starknet::ClassHash, table: felt252, key: felt252, keys_layout: Span<u8>) {
// index::delete(0, table, key, keys_layout);
}
}

// returns a tuple of spans, first contains the entity IDs,
// second the deserialized entities themselves
fn all(
class_hash: starknet::ClassHash, model: felt252, index: felt252, length: usize, layout: Span<u8>
// Query all entities that meet a criteria. If no index is defined,
// Returns a tuple of spans, first contains the entity IDs,
// second the deserialized entities themselves.
fn scan(
class_hash: starknet::ClassHash, model: felt252, where: Option<WhereCondition>, values_length: usize, values_layout: Span<u8>
) -> (Span<felt252>, Span<Span<felt252>>) {
let table = {
if index == 0.into() {
model
} else {
match where {
//
Option::Some(clause) => {
let mut serialized = ArrayTrait::new();
model.serialize(ref serialized);
index.serialize(ref serialized);
let hash = poseidon_hash_span(serialized.span());
hash.into()
}
};
clause.key.serialize(ref serialized);
let index = poseidon_hash_span(serialized.span());

let all_ids = index::get_by_key(0, index, clause.value);
(all_ids.span(), get_by_ids(class_hash, index, all_ids.span(), length, layout))
},

let all_ids = index::get(0, table);
let mut ids = all_ids.span();

(all_ids.span(), get_by_ids(class_hash, table, all_ids.span(), length, layout))
// If no `where` clause is defined, we return all values.
Option::None(_) => {
let all_ids = index::get(0, table);
let mut ids = all_ids.span();
(all_ids.span(), get_by_ids(class_hash, table, all_ids.span(), values_size, values_layout))
}
}
}

/// Returns entries on the given ids.
Expand Down Expand Up @@ -88,20 +92,6 @@ fn get_by_ids(class_hash: starknet::ClassHash, table: felt252, all_ids: Span<fel
}
}

/// Returns entries on the given keys.
/// # Arguments
/// * `class_hash` - The class hash of the contract.
/// * `model` - The model to get the entries from.
/// * `index` - The index of the model to get the entries from.
/// * `key` - The key of the entries to get.
/// * `length` - The length of the entries.
fn get_by_key(
class_hash: starknet::ClassHash, model: felt252, index: felt252, key: felt252, length: usize, layout: Span<u8>
) -> (Span<felt252>, Span<Span<felt252>>) {
let all_ids = index::get_by_key(0, index, key);
(all_ids.span(), get_by_ids(class_hash, index, all_ids.span(), length, layout))
}

/// Set, but with writing keys to the appropriate indexes
/// # Arguments
/// * `class_hash` - The class hash of the contract.
Expand Down
51 changes: 40 additions & 11 deletions crates/dojo-core/src/database/index.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ use serde::Serde;

use dojo::database::storage;

#[derive(Copy, Drop)]
struct WhereCondition {
key: felt252,
value: felt252,
}

fn create(address_domain: u32, index: felt252, id: felt252) {
if exists(address_domain, index, id) {
return ();
Expand Down Expand Up @@ -145,21 +151,44 @@ fn exists(address_domain: u32, index: felt252, id: felt252) -> bool {
storage::get(address_domain, build_index_item_key(index, id)) != 0
}

fn get(address_domain: u32, index: felt252) -> Array<felt252> {
fn query(address_domain: u32, table: felt252, where: Option<WhereCondition>) -> Array<felt252> {
let mut res = ArrayTrait::new();

let index_len_key = build_index_len_key(index);
let index_len = storage::get(address_domain, index_len_key);
let mut idx = 0;
match where {
//
Option::Some(clause) => {
let mut serialized = ArrayTrait::new();
model.serialize(ref serialized);
clause.key.serialize(ref serialized);
let index = poseidon_hash_span(serialized.span());

loop {
if idx == index_len {
break ();
}
let index_len_key = build_index_len_key(index);
let index_len = storage::get(address_domain, index_len_key);
let mut idx = 0;

res.append(storage::get(address_domain, build_index_key(index, idx)));
idx += 1;
};
// TODO: Query on key value.

(all_ids.span(), get_by_ids(class_hash, index, all_ids.span(), length, layout))
},

// If no `where` clause is defined, we return all values.
Option::None(_) => {


let index_len_key = build_index_len_key(index);
let index_len = storage::get(address_domain, index_len_key);
let mut idx = 0;

loop {
if idx == index_len {
break ();
}

res.append(storage::get(address_domain, build_index_key(index, idx)));
idx += 1;
};
}
}

res
}
Expand Down
12 changes: 3 additions & 9 deletions crates/dojo-core/src/world.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -371,23 +371,17 @@ mod world {
///
/// * `model` - The name of the model to be retrieved.
/// * `index` - The index to be retrieved.
/// * `keys` - The query to be used to find the entity.
/// * `values` - The query to be used to find the entity.
/// * `length` - The length of the model values.
///
/// # Returns
///
/// * `Span<felt252>` - The entity IDs.
/// * `Span<Span<felt252>>` - The entities.
fn entities(
self: @ContractState, model: felt252, index: felt252, keys: Span<felt252>, length: usize, keys_layout: Span<u8>
self: @ContractState, model: felt252, index: Option<felt252>, values: Span<felt252>, values_length: usize, values_layout: Span<u8>
) -> (Span<felt252>, Span<Span<felt252>>) {
let class_hash = self.models.read(model);
assert(keys.len() <= 1, 'Multiple keys not implemented');
if (keys.len() == 0) {
database::all(class_hash, model, index, length, keys_layout)
} else {
database::get_by_key(class_hash, model.into(), index, *keys.at(0), length, keys_layout)
}
database::all(class_hash, model, index, values, values_length, values_layout)
}

/// Sets the executor contract address.
Expand Down

0 comments on commit 45a8e1e

Please sign in to comment.