Skip to content

Commit

Permalink
[query] Add conversion from SearchQuery to QueryIds #629 (#630)
Browse files Browse the repository at this point in the history
simplify sub-search queries
  • Loading branch information
michaelvlach authored Jul 8, 2023
1 parent b006a04 commit f9f9c32
Show file tree
Hide file tree
Showing 25 changed files with 45 additions and 123 deletions.
6 changes: 3 additions & 3 deletions docs/guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ Selecting all posts is a fairly straightforward query but we would rarely need a
```Rust
let posts = db.read()?.exec(
&QueryBuilder::select()
.search(
.ids(
QueryBuilder::search()
.from("posts")
.offset(0)
Expand All @@ -261,7 +261,7 @@ Now that we have the posts we will want to fetch the comments. Our graph schema
```Rust
let comments = db.read()?.exec(
&QueryBuilder::select()
.search(
.ids(
QueryBuilder::search()
.depth_first()
.from(posts.elements[0].id)
Expand Down Expand Up @@ -321,7 +321,7 @@ use agdb::DbKeyOrder;

let posts = db.read()?.exec(
&QueryBuilder::select()
.search(
.ids(
QueryBuilder::search()
.from("posts")
.order_by(vec![DbKeyOrder::Desc("likes".into())])
Expand Down
24 changes: 12 additions & 12 deletions docs/queries.md
Original file line number Diff line number Diff line change
Expand Up @@ -230,9 +230,9 @@ QueryBuilder::insert().edges().from(vec![1, 2]).to(vec![2, 3]).query();
QueryBuilder::insert().edges().from(vec![1, 2]).to(vec![2, 3]).each().query();
QueryBuilder::insert().edges().from("a").to(vec![1, 2]).values(vec![vec![("k", 1).into()], vec![("k", 2).into()]]).query();
QueryBuilder::insert().edges().from("a").to(vec![1, 2]).values_uniform(vec![("k", "v").into(), (1, 10).into()]).query();
QueryBuilder::insert().edges().from_search(QueryBuilder::search().from("a").where_().node().query()).to_search(QueryBuilder::search().from("b").where_().node().query()).query();
QueryBuilder::insert().edges().from_search(QueryBuilder::search().from("a").where_().node().query()).to_search(QueryBuilder::search().from("b").where_().node().query()).values(vec![vec![("k", 1).into()], vec![("k", 2).into()]]).query();
QueryBuilder::insert().edges().from_search(QueryBuilder::search().from("a").where_().node().query()).to_search(QueryBuilder::search().from("b").where_().node().query()).values_uniform(vec![("k", "v").into(), (1, 10).into()]).query();
QueryBuilder::insert().edges().from(QueryBuilder::search().from("a").where_().node().query()).to(QueryBuilder::search().from("b").where_().node().query()).query();
QueryBuilder::insert().edges().from(QueryBuilder::search().from("a").where_().node().query()).to(QueryBuilder::search().from("b").where_().node().query()).values(vec![vec![("k", 1).into()], vec![("k", 2).into()]]).query();
QueryBuilder::insert().edges().from(QueryBuilder::search().from("a").where_().node().query()).to(QueryBuilder::search().from("b").where_().node().query()).values_uniform(vec![("k", "v").into(), (1, 10).into()]).query();
```

The `from` and `to` represents list of origins and destinations of the edges to be inserted. As per [`QueryIds`](#queryids--queryid) it can be a list, single value, search query or even a result of another query (e.g. [insert nodes](#insert-nodes)) through the call of convenient `QueryResult::ids()` method. All ids must be `node`s and all must exist in the database otherwise data error will occur. If the `values` is [`QueryValues::Single`](#queryvalues) all edges will be associated with the copy of the same properties. If `values` is [`QueryValues::Multi`](#queryvalues) then the number of edges being inserted must match the provided values otherwise a logic error will occur. By default the `from` and `to` are expected to be of equal length specifying at each index the pair of nodes to connect with an edge. If all-to-all is desired set the `each` flag to `true`. The rule about the `values` [`QueryValues::Multi`](#queryvalues) still applies though so there must be enough values for all nodes resulting from the combination.
Expand Down Expand Up @@ -281,9 +281,9 @@ Builder pattern:

```Rust
QueryBuilder::insert().values(vec![vec![("k", "v").into(), (1, 10).into()], vec![("k", 2).into()]]).ids(vec![1, 2]).query();
QueryBuilder::insert().values(vec![vec![("k", "v").into(), (1, 10).into()], vec![("k", 2).into()]]).search(QueryBuilder::search().from("a").query()).query();
QueryBuilder::insert().values(vec![vec![("k", "v").into(), (1, 10).into()], vec![("k", 2).into()]]).ids(QueryBuilder::search().from("a").query()).query();
QueryBuilder::insert().values_uniform(vec![("k", "v").into(), (1, 10).into()]).ids(vec![1, 2]).query();
QueryBuilder::insert().values_uniform(vec![("k", "v").into(), (1, 10).into()]).search(QueryBuilder::search().from("a").query()).query();
QueryBuilder::insert().values_uniform(vec![("k", "v").into(), (1, 10).into()]).ids(QueryBuilder::search().from("a").query()).query();
```

Inserts or updates key-value pairs (properties) of existing elements. You need to specify the `ids` [`QueryIds`](#queryids--queryid) and the list of `values`. The `values` can be either [`QueryValues::Single`](#queryvalues) that will insert the single set of properties to all elements identified by `ids` or [`QueryValues::Multi`](#queryvalues) that will insert to each `id` its own set of properties but their number must match the number of `ids`.
Expand Down Expand Up @@ -316,7 +316,7 @@ QueryBuilder::remove().ids(1).query();
QueryBuilder::remove().ids("a").query();
QueryBuilder::remove().ids(vec![1, 2]).query();
QueryBuilder::remove().ids(vec!["a", "b"]).query();
QueryBuilder::remove().search(QueryBuilder::search().from("a").query()).query();
QueryBuilder::remove().ids(QueryBuilder::search().from("a").query()).query();
```

The elements identified by [`QueryIds`](#queryids--queryid) will be removed from the database if they exist. It is NOT an error if the elements to be removed do not exist in the database. All associated properties (key-value pairs) are also removed from all elements. Removing nodes will also remove all their edges (incoming and outgoing) and their properties.
Expand Down Expand Up @@ -358,7 +358,7 @@ Builder pattern:

```Rust
QueryBuilder::remove().values(vec!["k1".into(), "k2".into()]).ids(vec![1, 2]).query();
QueryBuilder::remove().values(vec!["k1".into(), "k2".into()]).search(QueryBuilder::search().from("a").query()).query();
QueryBuilder::remove().values(vec!["k1".into(), "k2".into()]).ids(QueryBuilder::search().from("a").query()).query();
```

The properties (key-value pairs) identified by `keys` and associated with `ids` [`QueryIds`](#queryids--queryid) will be removed from the database if they exist. It is a data error if any of the `ids` do not exist in the database but it is NOT an error if any of the keys does not exist or is not associated as property to any of the `ids`.
Expand Down Expand Up @@ -399,7 +399,7 @@ Builder pattern:
```Rust
QueryBuilder::select().ids("a").query();
QueryBuilder::select().ids(vec![1, 2]).query();
QueryBuilder::select().search(QueryBuilder::search().from(1).query()).query();
QueryBuilder::select().ids(QueryBuilder::search().from(1).query()).query();
```

Selects elements identified by `ids` [`QueryIds`](#queryids--queryid) or search query with all their properties. If any of the ids does not exist in the database running the query will return an error. The search query is most commonly used to find, filter or otherwise limit what elements to select.
Expand All @@ -423,7 +423,7 @@ Builder pattern:
```Rust
QueryBuilder::select().values(vec!["k".into(), "k2".into()]).ids("a").query();
QueryBuilder::select().values(vec!["k".into(), "k2".into()]).ids(vec![1, 2]).query();
QueryBuilder::select().values(vec!["k".into(), "k2".into()]).search(QueryBuilder::search().from(1).query()).query();
QueryBuilder::select().values(vec!["k".into(), "k2".into()]).ids(QueryBuilder::search().from(1).query()).query();
```

Selects elements identified by `ids` [`QueryIds`](#queryids--queryid) or search query with only selected properties (identified by the list of keys). If any of the ids does not exist in the database or does not have all the keys associated with it then running the query will return an error. While the search query is most commonly used to find, filter or otherwise limit what elements to select, using this particular query can limit what properties will be returned.
Expand All @@ -444,7 +444,7 @@ Builder pattern:
```Rust
QueryBuilder::select().keys().ids("a").query();
QueryBuilder::select().keys().ids(vec![1, 2]).query();
QueryBuilder::select().keys().search(QueryBuilder::search().from(1).query()).query();
QueryBuilder::select().keys().ids(QueryBuilder::search().from(1).query()).query();
```

Selects elements identified by `ids` [`QueryIds`](#queryids--queryid) or search query with only keys returned. If any of the ids does not exist in the database running the query will return an error. This query is most commonly used for establishing what data is available in on the graph elements (e.g. when transforming the data into a table this query could be used to populate the column names).
Expand All @@ -465,7 +465,7 @@ Builder pattern:
```Rust
QueryBuilder::select().key_count().ids("a").query();
QueryBuilder::select().key_count().ids(vec![1, 2]).query();
QueryBuilder::select().key_count().search(QueryBuilder::search().from(1).query()).query();
QueryBuilder::select().key_count().ids(QueryBuilder::search().from(1).query()).query();
```

Selects elements identified by `ids` [`QueryIds`](#queryids--queryid) or search query with only key count returned. If any of the ids does not exist in the database running the query will return an error. This query is most commonly used for establishing how many properties there are associated with the graph elements.
Expand All @@ -485,7 +485,7 @@ Builder pattern:

```Rust
QueryBuilder::select().aliases().ids(vec![1, 2]).query();
QueryBuilder::select().aliases().search(QueryBuilder::search().from(1).query()).query();
QueryBuilder::select().aliases().ids(QueryBuilder::search().from(1).query()).query();
```

Selects aliases of the `ids` [`QueryIds`](#queryids--queryid) or a search. If any of the ids does not have an alias running the query will return an error.
Expand Down
6 changes: 6 additions & 0 deletions src/agdb/query/query_ids.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,12 @@ impl From<&QueryResult> for QueryIds {
}
}

impl From<SearchQuery> for QueryIds {
fn from(query: SearchQuery) -> Self {
QueryIds::Search(query)
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
5 changes: 2 additions & 3 deletions src/agdb/query_builder/insert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ use super::insert_aliases::InsertAliases;
use super::insert_edge::InsertEdges;
use super::insert_nodes::InsertNodes;
use super::insert_values::InsertValues;
use super::insert_values::InsertValuesUniform;
use crate::query::insert_aliases_query::InsertAliasesQuery;
use crate::query::insert_edges_query::InsertEdgesQuery;
use crate::query::insert_nodes_query::InsertNodesQuery;
Expand Down Expand Up @@ -47,8 +46,8 @@ impl Insert {
})
}

pub fn values_uniform<T: Into<SingleValues>>(self, key_values: T) -> InsertValuesUniform {
InsertValuesUniform(InsertValuesQuery {
pub fn values_uniform<T: Into<SingleValues>>(self, key_values: T) -> InsertValues {
InsertValues(InsertValuesQuery {
ids: QueryIds::Ids(vec![0.into()]),
values: QueryValues::Single(Into::<SingleValues>::into(key_values).0),
})
Expand Down
15 changes: 0 additions & 15 deletions src/agdb/query_builder/insert_edge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ use crate::query::query_ids::QueryIds;
use crate::query::query_values::MultiValues;
use crate::query::query_values::QueryValues;
use crate::query::query_values::SingleValues;
use crate::query::search_query::SearchQuery;

pub struct InsertEdgesEach(pub InsertEdgesQuery);

Expand Down Expand Up @@ -39,13 +38,6 @@ impl InsertEdges {

InsertEdgesFrom(self.0)
}

#[allow(clippy::wrong_self_convention)]
pub fn from_search(mut self, query: SearchQuery) -> InsertEdgesFrom {
self.0.from = QueryIds::Search(query);

InsertEdgesFrom(self.0)
}
}

impl InsertEdgesFrom {
Expand All @@ -54,13 +46,6 @@ impl InsertEdgesFrom {

InsertEdgesFromTo(self.0)
}

#[allow(clippy::wrong_self_convention)]
pub fn to_search(mut self, query: SearchQuery) -> InsertEdgesFromTo {
self.0.to = QueryIds::Search(query);

InsertEdgesFromTo(self.0)
}
}

impl InsertEdgesFromTo {
Expand Down
25 changes: 1 addition & 24 deletions src/agdb/query_builder/insert_values.rs
Original file line number Diff line number Diff line change
@@ -1,39 +1,16 @@
use crate::query::insert_values_query::InsertValuesQuery;
use crate::query::query_ids::QueryIds;
use crate::query::search_query::SearchQuery;

pub struct InsertValuesUniform(pub InsertValuesQuery);
pub struct InsertValues(pub InsertValuesQuery);

pub struct InsertValuesIds(pub InsertValuesQuery);

pub struct InsertValues(pub InsertValuesQuery);

impl InsertValues {
pub fn ids<T: Into<QueryIds>>(mut self, ids: T) -> InsertValuesIds {
self.0.ids = ids.into();

InsertValuesIds(self.0)
}

pub fn search(mut self, query: SearchQuery) -> InsertValuesIds {
self.0.ids = QueryIds::Search(query);

InsertValuesIds(self.0)
}
}

impl InsertValuesUniform {
pub fn ids<T: Into<QueryIds>>(mut self, ids: T) -> InsertValuesIds {
self.0.ids = ids.into();

InsertValuesIds(self.0)
}

pub fn search(mut self, query: SearchQuery) -> InsertValuesIds {
self.0.ids = QueryIds::Search(query);

InsertValuesIds(self.0)
}
}

impl InsertValuesIds {
Expand Down
5 changes: 0 additions & 5 deletions src/agdb/query_builder/remove.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ use crate::query::query_values::QueryKeys;
use crate::query::remove_aliases_query::RemoveAliasesQuery;
use crate::query::remove_query::RemoveQuery;
use crate::query::remove_values_query::RemoveValuesQuery;
use crate::query::search_query::SearchQuery;
use crate::query::select_values_query::SelectValuesQuery;

pub struct Remove {}
Expand All @@ -21,10 +20,6 @@ impl Remove {
RemoveIds(RemoveQuery(ids.into()))
}

pub fn search(self, query: SearchQuery) -> RemoveIds {
RemoveIds(RemoveQuery(QueryIds::Search(query)))
}

pub fn values<T: Into<QueryKeys>>(self, keys: T) -> RemoveValues {
RemoveValues(RemoveValuesQuery(SelectValuesQuery {
keys: Into::<QueryKeys>::into(keys).0,
Expand Down
7 changes: 0 additions & 7 deletions src/agdb/query_builder/remove_values.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use crate::query::query_ids::QueryIds;
use crate::query::remove_values_query::RemoveValuesQuery;
use crate::query::search_query::SearchQuery;

pub struct RemoveValues(pub RemoveValuesQuery);

Expand All @@ -12,12 +11,6 @@ impl RemoveValues {

RemoveValuesIds(self.0)
}

pub fn search(mut self, query: SearchQuery) -> RemoveValuesIds {
self.0 .0.ids = QueryIds::Search(query);

RemoveValuesIds(self.0)
}
}

impl RemoveValuesIds {
Expand Down
5 changes: 0 additions & 5 deletions src/agdb/query_builder/select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ use super::select_keys::SelectKeys;
use super::select_values::SelectValues;
use crate::query::query_ids::QueryIds;
use crate::query::query_values::QueryKeys;
use crate::query::search_query::SearchQuery;
use crate::query::select_aliases_query::SelectAliasesQuery;
use crate::query::select_key_count_query::SelectKeyCountQuery;
use crate::query::select_keys_query::SelectKeysQuery;
Expand All @@ -23,10 +22,6 @@ impl Select {
SelectIds(SelectQuery(ids.into()))
}

pub fn search(self, search: SearchQuery) -> SelectIds {
SelectIds(SelectQuery(QueryIds::Search(search)))
}

pub fn keys(self) -> SelectKeys {
SelectKeys(SelectKeysQuery(QueryIds::Ids(vec![0.into()])))
}
Expand Down
7 changes: 0 additions & 7 deletions src/agdb/query_builder/select_aliases.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use crate::query::query_ids::QueryIds;
use crate::query::search_query::SearchQuery;
use crate::query::select_aliases_query::SelectAliasesQuery;
use crate::query::select_all_aliases_query::SelectAllAliases;

Expand All @@ -14,12 +13,6 @@ impl SelectAliases {
SelectAliasesIds(self.0)
}

pub fn search(mut self, query: SearchQuery) -> SelectAliasesIds {
self.0 .0 = QueryIds::Search(query);

SelectAliasesIds(self.0)
}

pub fn query(self) -> SelectAllAliases {
SelectAllAliases {}
}
Expand Down
7 changes: 0 additions & 7 deletions src/agdb/query_builder/select_key_count.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use crate::query::query_ids::QueryIds;
use crate::query::search_query::SearchQuery;
use crate::query::select_key_count_query::SelectKeyCountQuery;

pub struct SelectKeyCount(pub SelectKeyCountQuery);
Expand All @@ -12,12 +11,6 @@ impl SelectKeyCount {

SelectKeyCountIds(self.0)
}

pub fn search(mut self, query: SearchQuery) -> SelectKeyCountIds {
self.0 .0 = QueryIds::Search(query);

SelectKeyCountIds(self.0)
}
}

impl SelectKeyCountIds {
Expand Down
7 changes: 0 additions & 7 deletions src/agdb/query_builder/select_keys.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use crate::query::query_ids::QueryIds;
use crate::query::search_query::SearchQuery;
use crate::query::select_keys_query::SelectKeysQuery;

pub struct SelectKeys(pub SelectKeysQuery);
Expand All @@ -12,12 +11,6 @@ impl SelectKeys {

SelectKeysIds(self.0)
}

pub fn search(mut self, query: SearchQuery) -> SelectKeysIds {
self.0 .0 = QueryIds::Search(query);

SelectKeysIds(self.0)
}
}

impl SelectKeysIds {
Expand Down
7 changes: 0 additions & 7 deletions src/agdb/query_builder/select_values.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use crate::query::query_ids::QueryIds;
use crate::query::search_query::SearchQuery;
use crate::query::select_values_query::SelectValuesQuery;

pub struct SelectValues(pub SelectValuesQuery);
Expand All @@ -12,12 +11,6 @@ impl SelectValues {

SelectValuesIds(self.0)
}

pub fn search(mut self, query: SearchQuery) -> SelectValuesIds {
self.0.ids = QueryIds::Search(query);

SelectValuesIds(self.0)
}
}

impl SelectValuesIds {
Expand Down
8 changes: 4 additions & 4 deletions tests/examples.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ fn quickstart() -> Result<(), QueryError> {

let user_id = db.exec(
&QueryBuilder::select()
.search(
.ids(
QueryBuilder::search()
.from("users")
.where_()
Expand Down Expand Up @@ -250,7 +250,7 @@ fn guide() -> Result<(), QueryError> {

let posts = db.read()?.exec(
&QueryBuilder::select()
.search(
.ids(
QueryBuilder::search()
.from("posts")
.order_by(vec![DbKeyOrder::Desc("likes".into())])
Expand All @@ -265,7 +265,7 @@ fn guide() -> Result<(), QueryError> {

let _comments = db.read()?.exec(
&QueryBuilder::select()
.search(
.ids(
QueryBuilder::search()
.depth_first()
.from(posts.elements[0].id)
Expand Down Expand Up @@ -306,7 +306,7 @@ fn guide() -> Result<(), QueryError> {
db.write()?.exec_mut(
&QueryBuilder::insert()
.values_uniform(vec![("level", 1).into()])
.search(
.ids(
QueryBuilder::search()
.from("posts")
.where_()
Expand Down
Loading

0 comments on commit f9f9c32

Please sign in to comment.