mirror of
https://github.com/ent/ent.git
synced 2026-05-24 09:31:56 +03:00
examples/fs: document example and add readme
This commit is contained in:
committed by
Ariel Mashraki
parent
34578936dd
commit
6262a1cadc
44
examples/fs/README.md
Normal file
44
examples/fs/README.md
Normal file
@@ -0,0 +1,44 @@
|
||||
# Recursive Traversal Using [CTE](https://en.wikipedia.org/wiki/Hierarchical_and_recursive_queries_in_SQL#Common_table_expression)
|
||||
|
||||
In this example, we create a file system with a tree structure, and want to query all "undeleted" files.
|
||||
A file is considered as "deleted", if it's marked as "deleted" (a bool field), or any of its parents is
|
||||
marked as "deleted".
|
||||
|
||||
Given the following tree structure:
|
||||
|
||||
```console
|
||||
a/
|
||||
├─ b/
|
||||
│ ├─ ba
|
||||
│ ├─ bb
|
||||
│ └─ bc (deleted)
|
||||
├─ c/ (deleted)
|
||||
│ ├─ ca
|
||||
│ └─ cb
|
||||
└─ d (deleted)
|
||||
```
|
||||
|
||||
Query "undeleted" files should return the following structure:
|
||||
|
||||
```console
|
||||
a/
|
||||
└─ b/
|
||||
├─ ba
|
||||
└─ bb
|
||||
```
|
||||
|
||||
As you can see, in order to check if "cb" (or "ca") is "deleted", we need to "look behind" recursively
|
||||
until we find a "deleted" parent, or reach the root ("a").
|
||||
|
||||
|
||||
### Generate Assets
|
||||
|
||||
```console
|
||||
go generate ./...
|
||||
```
|
||||
|
||||
### Run Example
|
||||
|
||||
```console
|
||||
go test
|
||||
```
|
||||
@@ -28,7 +28,7 @@ func Example_RecursiveTraversal() {
|
||||
log.Fatalf("failed creating schema resources: %v", err)
|
||||
}
|
||||
|
||||
// Add multiple files in the following ree structure:
|
||||
// Add multiple files in the following tree structure:
|
||||
//
|
||||
// a/
|
||||
// ├─ b/
|
||||
@@ -62,6 +62,8 @@ func Example_RecursiveTraversal() {
|
||||
t1, t2 := sql.Table(file.Table), sql.Table(file.Table)
|
||||
with := sql.WithRecursive("undeleted", file.FieldID, file.FieldParentID)
|
||||
with.As(
|
||||
// The initial `SELECT` statement executed once at the start,
|
||||
// and produces the initial row or rows for the recursion.
|
||||
sql.Select(t1.Columns(file.FieldID, file.FieldParentID)...).
|
||||
From(t1).
|
||||
Where(
|
||||
@@ -70,7 +72,10 @@ func Example_RecursiveTraversal() {
|
||||
sql.EQ(t1.C(file.FieldDeleted), false),
|
||||
),
|
||||
).
|
||||
// Merge the `SELECT` statement above with the following:
|
||||
UnionAll(
|
||||
// A `SELECT` statement that produces additional rows and recurses by referring
|
||||
// to the CTE name (e.g. "undeleted"), and ends when there are no more new rows.
|
||||
sql.Select(t2.Columns(file.FieldID, file.FieldParentID)...).
|
||||
From(t2).
|
||||
Join(with).
|
||||
@@ -80,6 +85,7 @@ func Example_RecursiveTraversal() {
|
||||
),
|
||||
),
|
||||
)
|
||||
// Join the root `SELECT` query with the CTE result (`WITH` clause).
|
||||
s.Prefix(with).Join(with).On(s.C(file.FieldID), with.C(file.FieldID))
|
||||
}).
|
||||
Select(file.FieldName).
|
||||
|
||||
Reference in New Issue
Block a user