Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamic GraphQL document API #141

Merged
merged 205 commits into from
Aug 7, 2022
Merged
Show file tree
Hide file tree
Changes from 186 commits
Commits
Show all changes
205 commits
Select commit Hold shift + click to select a range
b77460f
Introduce client api with nextEntryArgs stub
cafca May 16, 2022
477aca4
Implement current nextEntryArgs RPC method using graphql
cafca May 16, 2022
4bd6a18
Fix basic graphql endpoint test
cafca May 16, 2022
9df6cd6
Add tests
cafca May 16, 2022
599d0ca
Update changelog
cafca May 16, 2022
9b91ef8
Handle errors
cafca May 16, 2022
591c6a0
Clean up
cafca May 16, 2022
d0fc7c7
Refactor for storage provider
cafca May 17, 2022
bdc9abe
Revert changelog style change
cafca May 17, 2022
7eced50
Move request/response structs to graphql client module
cafca May 17, 2022
58bcffb
Adapt EntryArgsResponse implementation to GraphQL
cafca May 17, 2022
f935853
Recover old file structure for now
cafca May 17, 2022
0a309a8
Merge branch 'development' into graphql-client-api
cafca May 17, 2022
a9ea7a1
Improve test
cafca May 18, 2022
89b3aeb
Switch back branch
cafca May 18, 2022
821596a
Clarify test scope
cafca May 18, 2022
2244352
Handle serialisation in EntryArgsResponse impl
cafca May 18, 2022
086c064
Implement deserialisation
cafca May 18, 2022
1008b80
Implement serialisation
cafca May 18, 2022
3fe7220
Rearrange file
cafca May 18, 2022
9bf459f
Implement publishEntry mutation
cafca May 18, 2022
0a65d04
Add test for error handling
cafca May 19, 2022
660207a
Update changelog
cafca May 19, 2022
a74ed52
Merge branch 'development' into graphql-publish-entry
cafca May 19, 2022
e4bb404
Remove merge error
cafca May 19, 2022
b5850a7
Fix changelog format
cafca May 19, 2022
4b5beca
Adopt async-graphql naming
cafca May 19, 2022
d2a6c67
Extend APi description
cafca May 19, 2022
3656efd
Remove renamed file
cafca May 20, 2022
44cef4f
Experimental non-dynamic implementation
cafca May 24, 2022
9dace1b
Insert p2panda schemas into graphql schema
cafca Jun 1, 2022
c836882
Restructure files
cafca Jun 3, 2022
c163247
Merge branch 'development' into graphql-document-query-experimental
cafca Jun 3, 2022
644b692
Load schemas from store
cafca Jun 14, 2022
c39e9f5
Revert changes to SchemaStore
cafca Jun 14, 2022
b583b06
Improve temp file helper to provide static ref
cafca Jun 14, 2022
6dbddf1
Add schema service
cafca Jun 16, 2022
ba1e1d7
Add schema task
cafca Jun 16, 2022
056e72f
Fix docstring
cafca Jun 16, 2022
669f512
Rename to SchemaProvider and add to node context
cafca Jun 16, 2022
19fdd77
Remove temp file helper from this branch
cafca Jun 16, 2022
024dc4d
Remove doctest that uses private items
cafca Jun 16, 2022
50b184d
Rewrite schema provider without storage provider
cafca Jun 16, 2022
a6b1ee2
Add comment
cafca Jun 16, 2022
d666cf0
Reset p2panda-rs dep
cafca Jun 16, 2022
3590bfd
Remove custom error type
cafca Jun 16, 2022
bcabdde
Allow dead code for now
cafca Jun 16, 2022
70171ef
Fix url
cafca Jun 16, 2022
f7305a8
Add test
cafca Jun 17, 2022
3b72d82
Remove unused import
cafca Jun 17, 2022
23ea3f1
Merge branch 'development' into graphql-document-query-experimental
adzialocha Jun 20, 2022
7969324
Minor formatting fix
adzialocha Jun 20, 2022
0d05cd5
Add default impl
cafca Jun 20, 2022
f2283e5
Introduce manager handling multiple schemas
adzialocha Jun 21, 2022
818ce62
Move creating the temp file to graphql manager
adzialocha Jun 21, 2022
5b78049
Fix calling the right build method, move it all to http service
adzialocha Jun 21, 2022
ffd76fc
Get path from same constant
adzialocha Jun 21, 2022
16000cf
Subscribe to schema changes and build a new GraphQL schema accordingly
adzialocha Jun 22, 2022
815bc51
Remove unused test
adzialocha Jun 22, 2022
216d869
Init env_logger when tests start
cafca Jun 22, 2022
c359404
Consistent naming and default use
cafca Jun 22, 2022
7fc19bc
Update p2panda-rs api
cafca Jun 22, 2022
1c18f20
Add task logging
cafca Jun 22, 2022
bea2ab1
Kick off schema task
cafca Jun 22, 2022
6d2de1e
Log all the things
cafca Jun 22, 2022
026464a
Don't rely on all schemas to be in the provider
cafca Jun 22, 2022
265ca63
Add tests
cafca Jun 22, 2022
dbdbc77
Remove unused import
cafca Jun 22, 2022
c2dab69
Remove unused imports
cafca Jun 22, 2022
d040497
Merge branch 'development' into schema-provider
cafca Jun 22, 2022
e7dab6a
Update api after merge
cafca Jun 22, 2022
adddb64
Consistent logging
cafca Jun 22, 2022
4d873b6
Update changelog
cafca Jun 22, 2022
de96ba3
Add test for new functionality in dependency task
cafca Jun 22, 2022
826d8e4
Merge branch 'schema-provider' into graphql-document-query-experimental
cafca Jun 22, 2022
b236896
Always remove tasks from the task store
cafca Jun 22, 2022
3dd82c7
Pin p2panda-rs because we don't have an OperationStore
cafca Jun 22, 2022
1259d70
Update for SchemaProvider
cafca Jun 22, 2022
558bf27
Fix duplicate schema provider instances
adzialocha Jun 23, 2022
f24d262
Use default application directory for temp file
cafca Jun 23, 2022
5d3a8a2
Merge branch 'graphql-document-query-experimental' of github.com:p2pa…
cafca Jun 23, 2022
ac36498
Panic when failing to build initial schema
cafca Jun 23, 2022
caa209c
Query prototype
cafca Jun 24, 2022
86b9031
Fix nextEntryArgs
cafca Jun 24, 2022
a71cf87
Simplify
cafca Jun 24, 2022
35d89fa
Make clippy happy
adzialocha Jun 25, 2022
62ea4ba
Merge branch 'main' into graphql-document-query-experimental
adzialocha Jun 27, 2022
85de0be
Fix API changes
adzialocha Jun 27, 2022
b6ec8d6
Merge branch 'main' into schema-provider
adzialocha Jun 27, 2022
7e2f198
Merge branch 'main' into graphql-document-query-experimental
adzialocha Jun 29, 2022
78a5c9b
Merge branch 'main' into schema-provider
adzialocha Jul 1, 2022
37b9a68
Move to unreleased section in CHANGELOG
adzialocha Jul 1, 2022
fe2a914
Minor clean ups
adzialocha Jul 1, 2022
3ecc52d
Merge branch 'schema-provider' into graphql-document-query-experimental
adzialocha Jul 1, 2022
3cf7954
Remove temp-file and store everything in static memory
adzialocha Jul 1, 2022
fa3f484
Give test more time
adzialocha Jul 1, 2022
72e8e03
Bring back receivers
adzialocha Jul 1, 2022
115bb7d
Bring back receiver to make cov tests work
adzialocha Jul 1, 2022
d825a60
Add a comment about memory leak and prepare struct to manage it
adzialocha Jul 1, 2022
dcb438e
Write a lot about this
adzialocha Jul 2, 2022
6529466
Add a warning in GraphQLSchemaManager
adzialocha Jul 2, 2022
56d93c9
Merge branch 'main' into schema-provider
adzialocha Jul 2, 2022
b6c2aaa
Move serde_json back to dev dependencies
adzialocha Jul 2, 2022
37a0346
Merge branch 'main' into schema-provider
adzialocha Jul 2, 2022
e5562be
Merge branch 'main' into graphql-document-query-experimental
adzialocha Jul 2, 2022
6693f1c
Remove unused apollo-parser
adzialocha Jul 2, 2022
b3f8798
Merge branch 'schema-provider' into graphql-document-query-experimental
adzialocha Jul 2, 2022
d39a003
Improve error logging in worker (#194)
adzialocha Jul 5, 2022
680bd03
Use Tokio Mutex
cafca Jul 13, 2022
a185462
Update docstrings
cafca Jul 13, 2022
2c4fced
Improve log readability
cafca Jul 13, 2022
c092363
Refactor schema task tests
sandreae Jul 14, 2022
699f408
Fix comments
sandreae Jul 14, 2022
e4cd7f5
Remove unused dependencies
sandreae Jul 14, 2022
885ba5f
Merge branch 'schema-provider' of github.com:p2panda/aquadoggo into s…
cafca Jul 14, 2022
905c30c
Handle document view being deleted while processing task
cafca Jul 14, 2022
92acffc
Less verbose logging from tasks
cafca Jul 14, 2022
1675f85
Formatting and docstrings
cafca Jul 14, 2022
e8c0b7a
Replace helper function with store call
cafca Jul 14, 2022
cd9bf4b
Rewrite test using test node
cafca Jul 14, 2022
e4cafa8
Improve test fidelity
cafca Jul 14, 2022
4bccc58
Rename module
cafca Jul 14, 2022
dfa83e6
Remove unused method
cafca Jul 14, 2022
cd2955d
Extend tests
cafca Jul 14, 2022
65c8f4e
Update docstring
cafca Jul 14, 2022
0880d07
Merge branch 'schema-provider' into graphql-document-query-experimental
cafca Jul 14, 2022
fb38c03
Rename module
cafca Jul 14, 2022
cf3e09a
Construct list of schema documents async
cafca Jul 14, 2022
b648637
Use async_graphql query context to access SchemaProvider
cafca Jul 14, 2022
2f5fbba
Add placeholder response when documents don't exist yet
cafca Jul 14, 2022
8610d74
Merge branch 'main' into graphql-document-query-experimental
cafca Jul 14, 2022
9c79da5
Update docstring
cafca Jul 14, 2022
2845c8e
Rename module
cafca Jul 14, 2022
cb889d8
Refactor output types with additional nesting
cafca Jul 14, 2022
f2cc681
Comment out test that keeps failing on my machine
cafca Jul 14, 2022
b11839f
Add root wrapper
cafca Jul 14, 2022
01596d4
Add meta field
cafca Jul 14, 2022
f077181
Remove redundant status
cafca Jul 14, 2022
077bad3
Add helpers for creating metafield and metaobject
cafca Jul 15, 2022
5920c4b
Restructure modules
cafca Jul 15, 2022
6ec0298
Add module docstring
cafca Jul 15, 2022
12ac941
Remove unused items
cafca Jul 15, 2022
962eb36
Sort items alphabetically
cafca Jul 15, 2022
995193a
Add DocumentSelector
cafca Jul 15, 2022
e0c6181
Add log line for successfull initial schema build
cafca Jul 15, 2022
a523c51
Remove document status for now
cafca Jul 15, 2022
9eba6ba
Add trait for dynamically generated types
cafca Jul 15, 2022
885240c
Experiment with using scalar types in dynamic api
cafca Jul 15, 2022
3000a78
Clean up module structure
cafca Jul 15, 2022
50a9f5e
Lot's of restructuring today
cafca Jul 15, 2022
447c3e4
Move metadata resolver next to type definition
cafca Jul 15, 2022
d4fe2ce
Update descriptions
cafca Jul 15, 2022
d5cd667
Extend docstrings
cafca Jul 15, 2022
cbef328
Add single query and parameters
cafca Jul 15, 2022
c2d80eb
Fix imports
cafca Jul 15, 2022
e5210cd
Follow clippy
cafca Jul 15, 2022
fde6d67
Validate that args match query schema
cafca Jul 16, 2022
80bc4e7
Improve argument handling
cafca Jul 16, 2022
d04d047
Define field names as constants
cafca Jul 17, 2022
73a7608
Some refactoring
cafca Jul 17, 2022
1899069
Fix typo
cafca Jul 17, 2022
a42fc1f
Merge branch 'graphql-document-query-experimental' of github.com:p2pa…
cafca Jul 17, 2022
90cb82f
Changes from review comments
cafca Jul 28, 2022
ea2962b
Mark unsafe fn
cafca Jul 28, 2022
ef28fba
Basic document test runner
cafca Jul 28, 2022
7f39860
Merge branch 'main' into graphql-document-query-experimental
cafca Jul 28, 2022
3e43be9
Expect log id 0
cafca Jul 28, 2022
8088de0
Merge branch 'graphql-tests' into graphql-document-query-experimental
cafca Jul 28, 2022
e2f5b72
Basic testing setup
cafca Jul 29, 2022
0d4a79f
Fix task input
cafca Jul 29, 2022
a4463d2
New test for relation fields
cafca Jul 29, 2022
438ee49
Add test for utility
cafca Jul 29, 2022
d1c0321
Add tests for output types
cafca Jul 30, 2022
1db2a8f
Docstring format
cafca Jul 30, 2022
4619584
Add test for gql schema manager.
cafca Jul 30, 2022
afa76fc
Fix display impl
cafca Jul 30, 2022
5a793c9
Extend simple query test for document id param
cafca Jul 30, 2022
0cfd69c
Clear import
cafca Jul 30, 2022
3dcb64f
Add dedicated tests for single and listing query variations
cafca Jul 30, 2022
3bd774a
Add tests for parameter handling
cafca Jul 30, 2022
de5310e
Remove clippy rule that CI doesn't know
cafca Jul 30, 2022
13c03a8
Cleanup
cafca Jul 31, 2022
4c6130f
Remove duplicate test
cafca Jul 31, 2022
ef4b85f
Cleanup
cafca Jul 31, 2022
d99bf69
Debug logging of available schemas
cafca Jul 31, 2022
6031d4d
Formatting
cafca Aug 1, 2022
95d86d6
Fix comma
cafca Aug 1, 2022
cda6e1e
Merge branch 'graphql-document-query-experimental' of github.com:p2pa…
cafca Aug 4, 2022
f00c09d
Replace quotation marks with explanation
cafca Aug 4, 2022
86d01e4
Remove `StaticLeak`
cafca Aug 4, 2022
337271d
Remove gql type name suffix
cafca Aug 4, 2022
a858d44
ScalarType impl for scalars (WIP)
cafca Aug 4, 2022
851dc1d
Safe ScalarType implementation of all scalar types
cafca Aug 4, 2022
8a3100e
Docstrings
cafca Aug 4, 2022
328a2d6
Don't answer queries for schemas that are not in the schema provider
cafca Aug 4, 2022
02966ee
Add more debug output
cafca Aug 4, 2022
980cd75
Reduce nesting
cafca Aug 4, 2022
07efded
Remove aliases
cafca Aug 4, 2022
34dfb51
Use only one thread for tarpaulin
cafca Aug 4, 2022
c27bb0d
Remove debug logging again
cafca Aug 4, 2022
45beba6
Merge branch 'main' into graphql-document-query-experimental
sandreae Aug 6, 2022
05c0ee0
Make it work after merge
sandreae Aug 7, 2022
96733d8
Increase safety around dynamic schemas
cafca Aug 7, 2022
873078b
listing -> collection
cafca Aug 7, 2022
cdb1977
Fix debug log using `Human`
cafca Aug 7, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions aquadoggo/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ edition = "2018"
anyhow = "^1.0.58"
async-graphql = "^3.0.38"
async-graphql-axum = "^3.0.38"
async-recursion = "^1.0.0"
async-trait = "^0.1.56"
axum = "^0.5.10"
bamboo-rs-core-ed25519-yasmf = "^0.1.1"
Expand All @@ -30,8 +31,9 @@ futures = "^0.3.21"
gql_client = "^1.0.6"
lipmaa-link = "^0.2.2"
log = "^0.4.17"
once_cell = "^1.12.0"
openssl-probe = "^0.1.5"
p2panda-rs = { git = "https://github.com/p2panda/p2panda", rev = "e06fd08c45253d60fcd42778f59e946a9ed73f71" }
p2panda-rs = { git = "https://github.com/p2panda/p2panda", rev = "c79622e7f8edc495d74a37825d5f72234a7b0c9e" }
serde = { version = "^1.0.137", features = ["derive"] }
sqlx = { version = "^0.6.0", features = [
"any",
Expand Down Expand Up @@ -61,7 +63,7 @@ hex = "0.4.3"
http = "^0.2.8"
hyper = "^0.14.19"
once_cell = "^1.12.0"
p2panda-rs = { git = "https://github.com/p2panda/p2panda", rev = "e06fd08c45253d60fcd42778f59e946a9ed73f71", features = [
p2panda-rs = { git = "https://github.com/p2panda/p2panda", rev = "c79622e7f8edc495d74a37825d5f72234a7b0c9e", features = [
"testing",
] }
rand = "^0.8.5"
Expand Down
2 changes: 1 addition & 1 deletion aquadoggo/src/db/models/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use sqlx::FromRow;
///
/// We store the u64 integer values of `log_id` and `seq_num` as strings since SQLite doesn't
/// support storing unsigned 64 bit integers.
#[derive(FromRow, Debug, Serialize, Clone, PartialEq)]
#[derive(FromRow, Debug, Serialize, Clone, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct EntryRow {
/// Public key of the author.
Expand Down
2 changes: 1 addition & 1 deletion aquadoggo/src/db/models/task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use sqlx::FromRow;
/// Representation of a row from the `tasks` table as stored in the database.
///
/// This table holds all "pending" tasks of the materialization service worker.
#[derive(FromRow, Debug, Serialize, Clone, PartialEq)]
#[derive(FromRow, Debug, Serialize, Clone, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct TaskRow {
/// Name of the task worker.
Expand Down
6 changes: 3 additions & 3 deletions aquadoggo/src/db/provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::db::request::{EntryArgsRequest, PublishEntryRequest};
use crate::db::stores::{StorageEntry, StorageLog};
use crate::db::Pool;
use crate::errors::StorageProviderResult;
use crate::graphql::client::NextEntryArguments;
use crate::graphql::client::NextEntryArgumentsType;

/// Sql based storage that implements `StorageProvider`.
#[derive(Clone, Debug)]
Expand All @@ -32,9 +32,9 @@ impl SqlStorage {
/// databases.
#[async_trait]
impl StorageProvider<StorageEntry, StorageLog, VerifiedOperation> for SqlStorage {
type EntryArgsResponse = NextEntryArguments;
type EntryArgsResponse = NextEntryArgumentsType;
type EntryArgsRequest = EntryArgsRequest;
type PublishEntryResponse = NextEntryArguments;
type PublishEntryResponse = NextEntryArgumentsType;
type PublishEntryRequest = PublishEntryRequest;

/// Returns the related document for any entry.
Expand Down
2 changes: 1 addition & 1 deletion aquadoggo/src/db/stores/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use crate::db::provider::SqlStorage;
///
/// This struct implements the `AsStorageEntry` trait which is required when constructing the
/// `EntryStore`.
#[derive(Debug, Clone, PartialEq)]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct StorageEntry {
entry_signed: EntrySigned,
operation_encoded: OperationEncoded,
Expand Down
2 changes: 2 additions & 0 deletions aquadoggo/src/db/stores/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ impl SchemaStore for SqlStorage {
/// Get all Schema which have been published to this node.
///
/// Returns an error if a fatal db error occured.
///
/// Silently ignores incomplete or broken schema definitions.
async fn get_all_schema(&self) -> Result<Vec<Schema>, SchemaStoreError> {
let schema_views: Vec<SchemaView> = self
.get_documents_by_schema(&SchemaId::new("schema_definition_v1")?)
Expand Down
136 changes: 125 additions & 11 deletions aquadoggo/src/db/stores/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,16 @@ use std::convert::TryFrom;
use std::sync::Arc;

use futures::Future;
use log::{debug, error, info};
use p2panda_rs::document::{DocumentBuilder, DocumentId, DocumentViewId};
use p2panda_rs::entry::{sign_and_encode, Entry, EntrySigned};
use p2panda_rs::hash::Hash;
use p2panda_rs::identity::{Author, KeyPair};
use p2panda_rs::operation::{
AsOperation, AsVerifiedOperation, Operation, OperationEncoded, OperationId, OperationValue,
PinnedRelation, PinnedRelationList, Relation, RelationList, VerifiedOperation,
AsOperation, AsVerifiedOperation, Operation, OperationEncoded, OperationFields, OperationId,
OperationValue, PinnedRelation, PinnedRelationList, Relation, RelationList, VerifiedOperation,
};
use p2panda_rs::schema::SchemaId;
use p2panda_rs::schema::{FieldType, Schema, SchemaId};
use p2panda_rs::storage_provider::traits::{OperationStore, StorageProvider};
use p2panda_rs::test_utils::constants::{PRIVATE_KEY, SCHEMA_ID};
use p2panda_rs::test_utils::fixtures::{operation, operation_fields};
Expand All @@ -22,12 +23,16 @@ use sqlx::Any;
use tokio::runtime::Builder;
use tokio::sync::Mutex;

use crate::context::Context;
use crate::db::provider::SqlStorage;
use crate::db::request::{EntryArgsRequest, PublishEntryRequest};
use crate::db::traits::DocumentStore;
use crate::db::{connection_pool, create_database, run_pending_migrations, Pool};
use crate::graphql::client::NextEntryArguments;
use crate::graphql::client::NextEntryArgumentsType;
use crate::materializer::tasks::{dependency_task, reduce_task, schema_task};
use crate::materializer::TaskInput;
use crate::test_helpers::TEST_CONFIG;
use crate::{Configuration, SchemaProvider};

/// The fields used as defaults in the tests.
pub fn doggo_test_fields() -> Vec<(&'static str, OperationValue)> {
Expand Down Expand Up @@ -264,8 +269,15 @@ impl TestDatabaseRunner {
runtime.block_on(async {
// Initialise test database
let pool = initialize_db().await;
let store = SqlStorage::new(pool);
let context = Context::new(
store.clone(),
Configuration::default(),
SchemaProvider::default(),
);
let mut db = TestDatabase {
store: SqlStorage::new(pool),
context,
store,
test_data: TestData::default(),
};

Expand All @@ -291,7 +303,7 @@ impl TestDatabaseRunner {

// Panic here when test failed. The test fails within its own async task and stays
// there, we need to propagate it further to inform the test runtime about the result
result.unwrap();
result.expect("The test failed");
});
}
}
Expand Down Expand Up @@ -380,10 +392,97 @@ pub fn test_db(
/// Container for `SqlStore` with access to the document ids and key_pairs used in the
/// pre-populated database for testing.
pub struct TestDatabase {
pub context: Context,
pub store: SqlStorage,
pub test_data: TestData,
}

impl TestDatabase {
/// Publish a document and materialise it in the store.
///
/// Also runs dependency task for document.
pub async fn add_document(
cafca marked this conversation as resolved.
Show resolved Hide resolved
&mut self,
schema_id: &SchemaId,
fields: OperationFields,
key_pair: &KeyPair,
) -> DocumentViewId {
info!("Creating document for {}", schema_id);

// Get requested schema from store.
let schema = self
.context
.schema_provider
.get(schema_id)
.await
.expect("Schema not found");

// Build, publish and reduce create operation for document.
let create_op = Operation::new_create(schema.id().to_owned(), fields).unwrap();
let (entry_signed, _) = send_to_store(&self.store, &create_op, None, key_pair).await;
let input = TaskInput::new(Some(DocumentId::from(entry_signed.hash())), None);
let dependency_tasks = reduce_task(self.context.clone(), input.clone())
.await
.unwrap();

// Run dependency tasks
if let Some(tasks) = dependency_tasks {
for task in tasks {
dependency_task(self.context.clone(), task.input().to_owned())
.await
.unwrap();
}
}
DocumentViewId::from(entry_signed.hash())
}

/// Publish a schema and materialise it in the store.
pub async fn add_schema(
&mut self,
name: &str,
fields: Vec<(&str, FieldType)>,
key_pair: &KeyPair,
) -> Schema {
info!("Creating schema {}", name);
let mut field_ids = Vec::new();

// Build and reduce schema field definitions
for field in fields {
let create_field_op = Schema::create_field(field.0, field.1.clone().into()).unwrap();
let (entry_signed, _) =
send_to_store(&self.store, &create_field_op, None, key_pair).await;

let input = TaskInput::new(Some(DocumentId::from(entry_signed.hash())), None);
reduce_task(self.context.clone(), input).await.unwrap();

info!("Added field '{}' ({})", field.0, field.1.serialise());
field_ids.push(DocumentViewId::from(entry_signed.hash()));
}

// Build and reduce schema definition
let create_schema_op =
Schema::create(name, "test schema description", field_ids.into()).unwrap();
let (entry_signed, _) = send_to_store(&self.store, &create_schema_op, None, key_pair).await;
let input = TaskInput::new(None, Some(DocumentViewId::from(entry_signed.hash())));
reduce_task(self.context.clone(), input.clone())
.await
.unwrap();

// Run schema task for this spec
schema_task(self.context.clone(), input).await.unwrap();

let view_id = DocumentViewId::from(entry_signed.hash());
let schema_id = SchemaId::Application(name.to_string(), view_id);

debug!("Done building {}", schema_id);
self.context
.schema_provider
.get(&schema_id)
.await
.expect("Failed adding schema to provider.")
}
}

/// Data collected when populating a `TestData` base in order to easily check values which
/// would be otherwise hard or impossible to get through the store methods.
#[derive(Default)]
Expand Down Expand Up @@ -453,7 +552,7 @@ pub async fn send_to_store(
operation: &Operation,
document_id: Option<&DocumentId>,
key_pair: &KeyPair,
) -> (EntrySigned, NextEntryArguments) {
) -> (EntrySigned, NextEntryArgumentsType) {
// Get an Author from the key_pair.
let author = Author::try_from(key_pair.public_key().to_owned()).unwrap();

Expand Down Expand Up @@ -497,10 +596,13 @@ pub async fn send_to_store(
// Also insert the operation into the store.
let verified_operation =
VerifiedOperation::new(&author, &entry_encoded.hash().into(), operation).unwrap();
store
match store
.insert_operation(&verified_operation, &document_id)
.await
.unwrap();
{
Ok(_) => {}
Err(err) => error!("Failed inserting operation: {}", err),
}

(entry_encoded, publish_entry_response)
}
Expand Down Expand Up @@ -559,10 +661,22 @@ impl TestDatabaseManager {
}

pub async fn create(&self, url: &str) -> TestDatabase {
// Initialise test database
let pool = initialize_db_with_url(url).await;

// Initialise test store using pool.
let store = SqlStorage::new(pool.clone());

// Initialise context for store.
let context = Context::new(
store.clone(),
Configuration::default(),
SchemaProvider::default(),
);

// Initialise finished test database.
let test_db = TestDatabase {
store: SqlStorage::new(pool.clone()),
context,
store,
test_data: TestData::default(),
};
self.pools.lock().await.push(pool);
Expand Down
2 changes: 1 addition & 1 deletion aquadoggo/src/db/traits/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@ pub trait SchemaStore {
/// Get all published Schema from storage.
///
/// Returns a vector of Schema, or an empty vector if none were found. Returns
/// an error when a fatal storage error occured or a schema could not be constructed.
/// an error when a fatal storage error occured or a schema could not be constructed.
async fn get_all_schema(&self) -> Result<Vec<Schema>, SchemaStoreError>;
}
21 changes: 21 additions & 0 deletions aquadoggo/src/errors.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,25 @@
// SPDX-License-Identifier: AGPL-3.0-or-later

use p2panda_rs::schema::{SchemaId, SchemaIdError};
use thiserror::Error;

/// A specialized result type for the storage provider.
pub type StorageProviderResult<T> = anyhow::Result<T, Box<dyn std::error::Error + Send + Sync>>;

/// Errors returned by schema service.
#[derive(Error, Debug)]
pub enum SchemaProviderError {
/// Schema service can only handle application schemas it has definitions for.
#[allow(dead_code)]
#[error("not a known application schema: {0}")]
UnknownApplicationSchema(SchemaId),

/// This operation has a requirement on the schema parameter.
#[allow(dead_code)]
#[error("invalid schema: {0}, {1}")]
InvalidSchema(SchemaId, String),

/// Schema service can only handle valid schema ids.
#[error(transparent)]
InvalidSchemaId(#[from] SchemaIdError),
}
Loading