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

query method for store API #311

Merged
merged 108 commits into from
Apr 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
108 commits
Select commit Hold shift + click to select a range
8c11ee0
Introduce query store again
adzialocha Mar 23, 2023
4f4e4e9
Introduce list_index to operation field model
adzialocha Mar 23, 2023
a4b015f
Use INT type instead of NUMERIC as the latter is a decimal in PostgreSQL
adzialocha Mar 23, 2023
9d7c783
Remove find method and rename findMany to query
adzialocha Mar 23, 2023
2343d48
Change list_index to Option for DELETE operations
adzialocha Mar 23, 2023
43dca55
Update tests
adzialocha Mar 23, 2023
c3a3a01
Use storage provider error type
adzialocha Mar 23, 2023
7752e48
Run cargo fmt
adzialocha Mar 28, 2023
2c6a680
WIP: Sea gull query
adzialocha Mar 29, 2023
3a5502c
Minor clean ups, fix negated version of contains
adzialocha Mar 29, 2023
1f1aee8
Build this whole query
adzialocha Mar 29, 2023
7eaf540
Move code into separate methods
adzialocha Mar 29, 2023
9c53e22
Retrieve and parse the data into document view field rows
adzialocha Mar 29, 2023
7dccdf2
Run cargo fmt
adzialocha Mar 29, 2023
1564a19
WIP: Glue backend together with frontend
adzialocha Mar 29, 2023
cf5923d
Upsi
adzialocha Mar 29, 2023
4178008
Select all for now
adzialocha Mar 29, 2023
ac04db0
Escape string correctly
adzialocha Mar 29, 2023
f739ff4
Get owner, edited and deleted state as well
adzialocha Mar 30, 2023
2e337a8
Add TODO markers
adzialocha Mar 30, 2023
da91535
Get has_next_page flag
adzialocha Mar 30, 2023
d0c5b11
Correct way of merging rows into documents
adzialocha Mar 30, 2023
c493440
WIP: Handle pagination cursor
adzialocha Apr 7, 2023
7ba6709
Fix some SQL bugs
adzialocha Apr 8, 2023
55f0a27
Start adding more fields to PageInfo
adzialocha Apr 8, 2023
667e0d7
Pinned relation list should query document views
adzialocha Apr 8, 2023
e9a8c3d
Handle relations
adzialocha Apr 9, 2023
6d13372
Fix wrongly queried document view if it is not the last one
adzialocha Apr 9, 2023
4aa87fa
Minor formatting
adzialocha Apr 9, 2023
618676f
Fix handling empty responses, correctly order
adzialocha Apr 9, 2023
e07c678
Find out what got selected and accordingly adjust sql query
adzialocha Apr 10, 2023
4393ace
Correct doc strings
adzialocha Apr 10, 2023
eb06cc5
Make clippy happy
adzialocha Apr 10, 2023
eaefe3b
Even better
adzialocha Apr 10, 2023
08e9f5f
Group documents based on fields, not on id
adzialocha Apr 10, 2023
60e7ffe
Ensure only one row per operation field
adzialocha Apr 10, 2023
38a4e24
Introduce SelectList to query nested relation lists
adzialocha Apr 10, 2023
afed2f2
Make sure that list index is sorted
adzialocha Apr 10, 2023
55b5be5
Rename pagination GraphQL types
sandreae Apr 11, 2023
090b689
INNER JOIN is always implicit
adzialocha Apr 11, 2023
9064541
Make querying relation lists actually work
adzialocha Apr 11, 2023
d1f24ab
Improve comments
adzialocha Apr 11, 2023
a52aac7
Use base58 encoding for cursors
adzialocha Apr 11, 2023
225bdbf
Update and add some more doc strings
adzialocha Apr 12, 2023
115fc95
Correct structure for paginated collection object
sandreae Apr 14, 2023
a4273b1
fmt
sandreae Apr 14, 2023
fd4a0b3
Clippy
sandreae Apr 14, 2023
546d107
Use document view id for pagination, set it to root when in relation …
adzialocha Apr 14, 2023
f768eb0
Update test
sandreae Apr 14, 2023
69e642a
Reuse selected value in pagination
adzialocha Apr 14, 2023
de6b629
Introduce root in document cursor next to list index and view id
adzialocha Apr 14, 2023
dfffe4c
Allow pagination over nested relation lists
adzialocha Apr 14, 2023
e49539e
Ignore cursor if root view id does not match
adzialocha Apr 14, 2023
825ec92
Merge remote-tracking branch 'origin/fix-paginated-collection-type' i…
adzialocha Apr 14, 2023
7b45182
Fix filter and zero-result query for total count
adzialocha Apr 14, 2023
9d40904
Add endCursor to GraphQL API
adzialocha Apr 14, 2023
744dd6e
Add to CHANGELOG.md
adzialocha Apr 14, 2023
10322b6
Turn off some ordering fields for now
adzialocha Apr 14, 2023
a3f70a7
Add first test
adzialocha Apr 14, 2023
876164e
Comment all tests related to GraphQL API frontend
adzialocha Apr 14, 2023
2f0dc84
Formatting
adzialocha Apr 14, 2023
ec2f410
Fix clippy warnings
adzialocha Apr 14, 2023
b7df96f
Merge branch 'main' into query-sql
adzialocha Apr 14, 2023
c2d718d
Clippy happy
adzialocha Apr 14, 2023
4140fbb
Add operation_id to GROUP BY for postgres
adzialocha Apr 14, 2023
6d73bf6
Update GraphQL Cursor scalar
sandreae Apr 15, 2023
fa19cd5
Update GraphQL query tests
sandreae Apr 15, 2023
43b45a2
fmt
sandreae Apr 15, 2023
35802f2
Simplify complex test query
sandreae Apr 15, 2023
16447a4
Use CursorScalar in GraphQL argument parsing
sandreae Apr 15, 2023
9f7f750
fmt
sandreae Apr 15, 2023
4df476f
Do not use GROUP BY and filter by list_index instead to get one row p…
adzialocha Apr 17, 2023
8e7b15d
Derive Eq and PartialEq for DocumentCursor, fix totalCount query
adzialocha Apr 17, 2023
6fde7bf
Postgres does not allow aliases like that
adzialocha Apr 17, 2023
f1b62c2
Correct boolean values for postgres
adzialocha Apr 17, 2023
257a4f9
Boolean value is a string in database
adzialocha Apr 17, 2023
e36e706
Fix expected result in test
adzialocha Apr 17, 2023
b2bdcd4
Set deleted filter to true by default
adzialocha Apr 18, 2023
0344900
Link TODOs to issues
adzialocha Apr 18, 2023
1f4e2a8
Overwrite boolean filters if one was set for the same field
adzialocha Apr 18, 2023
909e564
Have a nice test method which derives the schema from given documents…
adzialocha Apr 18, 2023
6aa2d4e
Add more tests, fix a bug where filtering floats did not work due to …
adzialocha Apr 18, 2023
b0a27d4
Add test to filter by search string
adzialocha Apr 18, 2023
a372361
Correct filter default to only show non-deleted documents
adzialocha Apr 18, 2023
20288ae
Add a pagination test
adzialocha Apr 18, 2023
6246688
Fix tests after changing default value of deleted filter
adzialocha Apr 18, 2023
ec24f5c
Add a relation list test, fix ordering of relation lists
adzialocha Apr 18, 2023
640858e
Add pagination test over lists, fix group by for queries without sele…
adzialocha Apr 19, 2023
25f37e3
Only query fields when any have been selected
adzialocha Apr 19, 2023
d558645
Prepare pagination test to handle different cases
adzialocha Apr 19, 2023
136ce9c
Move counting documents into own method
adzialocha Apr 19, 2023
84aba7b
Clippy happy, developer happy
adzialocha Apr 19, 2023
504df42
Better comments and method names
adzialocha Apr 20, 2023
aa58df5
Refactor pagination, introduce unique cursor in table
adzialocha Apr 20, 2023
d3dcb49
Clarify comment
adzialocha Apr 20, 2023
85faa86
Limit sub-query to only one result
adzialocha Apr 20, 2023
3c8e3df
WIP: Troubleshooting, add some more TODOs
adzialocha Apr 24, 2023
dfd0278
Revert change when paginating over ordered meta data, simplify list i…
adzialocha Apr 24, 2023
34f129c
Add test with pagination over ordered view ids, fix pagination for ro…
adzialocha Apr 24, 2023
a2b5a1f
Always select at least one field
adzialocha Apr 24, 2023
cea82ae
Remove printing query
adzialocha Apr 24, 2023
d3191e1
Bring back commented test
adzialocha Apr 24, 2023
a0a7572
Add total_count test
sandreae Apr 24, 2023
506d366
Update default order test
sandreae Apr 24, 2023
654e10c
Update GraphQL collection query tests
sandreae Apr 24, 2023
2654155
Bring back select_cursor_during_conversion test
sandreae Apr 24, 2023
023a81c
fmt
sandreae Apr 24, 2023
f871761
Merge branch 'query-sql' of github.com:p2panda/aquadoggo into query-sql
sandreae Apr 24, 2023
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Introduce libp2p networking service and configuration [#282](https://github.com/p2panda/aquadoggo/pull/282)
- Create and validate abstract queries [#302](https://github.com/p2panda/aquadoggo/pull/302)
- Support paginated, ordered and filtered collection queries [#308](https://github.com/p2panda/aquadoggo/pull/308)
- SQL query for collections [#311](https://github.com/p2panda/aquadoggo/pull/311)
- Add custom validation to GraphQL scalar types [#318](https://github.com/p2panda/aquadoggo/pull/318)

### Changed
Expand Down
1 change: 1 addition & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions aquadoggo/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ async-graphql-axum = "^5.0.6"
async-trait = "^0.1.64"
axum = "^0.6.10"
bamboo-rs-core-ed25519-yasmf = "^0.1.1"
bs58 = "^0.4.0"
deadqueue = { version = "^0.2.3", default-features = false, features = [
"unlimited",
] }
Expand Down
2 changes: 1 addition & 1 deletion aquadoggo/migrations/20220509090252_create-operations.sql
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ CREATE TABLE IF NOT EXISTS operation_fields_v1 (
name TEXT NOT NULL,
field_type TEXT NOT NULL,
value TEXT NULL,
list_index NUMERIC NOT NULL,
list_index INT NOT NULL,
FOREIGN KEY(operation_id) REFERENCES operations_v1(operation_id)
);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-- SPDX-License-Identifier: AGPL-3.0-or-later

ALTER TABLE operation_fields_v1 ADD COLUMN cursor TEXT NOT NULL;

CREATE UNIQUE INDEX ux_operation_fields_v1 ON operation_fields_v1 (cursor);
28 changes: 17 additions & 11 deletions aquadoggo/src/db/models/document.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,43 @@ use sqlx::FromRow;
/// A struct representing a single row with joins from the document_view_fields table.
#[derive(FromRow, Debug, Clone)]
pub struct DocumentViewFieldRow {
/// The id of this operation.
/// Id of the document.
pub document_id: String,

/// Id of the view id representing the document version with this field value.
pub document_view_id: String,

/// The id of this operation.
/// Id of operation which set that field value.
pub operation_id: String,

/// The name of this field.
/// Name of field.
pub name: String,

/// The type of this field.
/// Position index of value when it is in a relation list.
pub list_index: i32,

/// Type of field.
pub field_type: String,

/// The actual value contained in this field.
/// Actual value contained in field.
pub value: String,
}

/// A struct representing a single row of a document table.
#[derive(FromRow, Debug, Clone)]
pub struct DocumentRow {
/// The id of this document
/// Id of this document
pub document_id: String,

/// The id of this documents most recent view.
/// Id of this documents most recent view.
pub document_view_id: String,

/// The id of the author of this document.
pub public_key: String,

/// The id of this documents schema.
/// Id of this documents schema.
pub schema_id: String,

/// Author of this document.
pub public_key: String,

/// Flag for if this document is deleted.
pub is_deleted: bool,
}
2 changes: 2 additions & 0 deletions aquadoggo/src/db/models/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ mod document;
mod entry;
mod log;
mod operation;
mod query;
mod task;
pub mod utils;

pub use self::log::LogRow;
pub use document::{DocumentRow, DocumentViewFieldRow};
pub use entry::EntryRow;
pub use operation::{OperationFieldsJoinedRow, OperationRow};
pub use query::{OptionalOwner, QueryRow};
pub use task::TaskRow;
14 changes: 14 additions & 0 deletions aquadoggo/src/db/models/operation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,14 @@ pub struct OperationFieldRow {
///
/// This is an Option as a DELETE operation contains no fields.
pub value: Option<String>,

/// Index of document id or view id in (pinned) relation lists.
///
/// This numeric value is a simple list index to represent multiple values within one operation
/// field.
///
/// This is an Option as a DELETE operation contains no fields.
pub list_index: Option<i32>,
}

/// A struct representing a joined OperationRow and OperationFieldRow.
Expand Down Expand Up @@ -85,4 +93,10 @@ pub struct OperationFieldsJoinedRow {
///
/// This is an Option as a DELETE operation contains no fields.
pub value: Option<String>,

/// Index of document id or view id in (pinned) relation lists.
///
/// This numeric value is a simple list index to represent multiple values within one operation
/// field.
pub list_index: Option<i32>,
}
79 changes: 79 additions & 0 deletions aquadoggo/src/db/models/query.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// SPDX-License-Identifier: AGPL-3.0-or-later

use p2panda_rs::identity::PublicKey;
use sqlx::{FromRow, Type};

/// Resulting row of a custom SQL query for filtered, ordered and paginated collection requests
/// against the database.
///
/// Some fields will be set to default values when they have not been included in the SQL query.
#[derive(FromRow, Debug, Clone)]
pub struct QueryRow {
/// Id of the document the operation is part of.
pub document_id: String,

/// Latest view id of the document.
pub document_view_id: String,

/// Id of the operation which contains that field value.
pub operation_id: String,

/// Flag if document is deleted.
pub is_deleted: bool,

/// Unique identifier aiding cursor-based pagination.
///
/// This value gets especially useful if we need to paginate over duplicate documents.
pub cmp_value_cursor: String,

#[sqlx(default)]
pub root_cursor: String,

/// Flag if document was at least changed once (more than one operation).
#[sqlx(default)]
pub is_edited: bool,

/// Public key of original author of document / CREATE operation.
#[sqlx(default)]
pub owner: OptionalOwner,

/// Name of the application field value we're interested in.
#[sqlx(default)]
pub name: String,

/// Application field value.
#[sqlx(default)]
pub value: String,

/// Type of the application field (string, boolean, float, int, relation etc.).
#[sqlx(default)]
pub field_type: String,

/// Special index value for (pinned) relation list fields which can contain multiple values.
/// The order of these values is crucial and needs to be preserved by keeping the index around.
#[sqlx(default)]
pub list_index: i32,
}

/// Wrapper around a public key, represented as a string in the database.
///
/// Since other structs assume that there is always a public key set, we have this wrapper type to
/// give a default "fake" public key, even when it was not returned by the SQL query.
#[derive(Type, Debug, Clone)]
#[sqlx(transparent)]
pub struct OptionalOwner(String);
adzialocha marked this conversation as resolved.
Show resolved Hide resolved

impl From<&OptionalOwner> for PublicKey {
fn from(value: &OptionalOwner) -> Self {
// Unwrap here since we assume that public key was already validated before it was stored
// in database
value.0.parse().unwrap()
}
}

impl Default for OptionalOwner {
fn default() -> Self {
// "Fake" ed25519 public key serving as a placeholder when it was not requested in query
Self("0000000000000000000000000000000000000000000000000000000000000000".to_string())
}
}
Loading