Skip to content
GitLab
Explore
Projects
Groups
Snippets
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Azat Alimov
POD
Commits
306e8d3d
Unverified
Commit
306e8d3d
authored
4 years ago
by
Vasili Novikov
Browse files
Options
Download
Email Patches
Plain Diff
Implement insert_tree API
parent
081cb87f
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
docs/HTTP_API.md
+45
-2
docs/HTTP_API.md
src/api_model.rs
+16
-0
src/api_model.rs
src/internal_api.rs
+20
-7
src/internal_api.rs
src/warp_api.rs
+15
-2
src/warp_api.rs
src/warp_endpoints.rs
+10
-0
src/warp_endpoints.rs
with
106 additions
and
11 deletions
+106
-11
docs/HTTP_API.md
+
45
-
2
View file @
306e8d3d
...
...
@@ -196,6 +196,47 @@ Mark an item as deleted:
*
Update
`dateModified`
(server's time is taken)
### POST /v2/$owner_key/insert_tree
```
json5
{
"databaseKey": "2DD29CA851E7B56E4697B0E1F08507293D761A05CE4D1B628663F411A8086D99",
"payload": { /* item definition (see below) */ }
}
```
Insert a tree with edges (of arbitrary depth) in one batch.
Each item should either be an object with only
`uid`
and
`_edges`
fields:
```
json5
{
"uid": 123456789 /* uid of the item to create edge with */,
"_edges": [ /* see below edges definition*/ ]
}
```
Or the full item to be created, in which case
`uid`
is optional,
but all standard mandatory item fields need to be present:
```
json5
{
"_type": "SomeItemType",
"_edges": [ /* see below edges definition*/ ],
/* other item properties here */
}
```
Each edge in the array above is required to have the following form:
```
json5
{
"_type": "SomeEdgeType",
"_target": { /* item of identical structure to the above */ }
/* optional edge properties here */
}
```
As always, inserting edges will result in updating timestamps for
`_source`
items
(even if they are referenced by
`uid`
only).
The method will return the
`uid`
of the created root item, e.g.
`123456789`
.
### POST /v2/$owner_key/search_by_fields/
```
json
{
...
...
@@ -204,8 +245,10 @@ Mark an item as deleted:
}
```
Search items by their fields.
Field
`_dateServerModifiedAfter`
is not treated in the standard way, and instead, it filters
items by their
`_dateServerModified`
field using the
`>`
operator.
Ephemeral underscore field
`_dateServerModifiedAfter`
, if specified,
is treated specially. It will filter out those items that have
`_dateServerModified`
higher (
`>`
) than the specified value.
The endpoint will return an array of all items with exactly the same properties.
...
...
This diff is collapsed.
Click to expand it.
src/api_model.rs
+
16
-
0
View file @
306e8d3d
...
...
@@ -49,6 +49,22 @@ pub struct BulkAction {
pub
delete_edges
:
Vec
<
DeleteEdge
>
,
}
#[derive(Serialize,
Deserialize,
Debug)]
pub
struct
InsertTreeItem
{
#[serde(default)]
pub
_edges
:
Vec
<
InsertTreeEdge
>
,
#[serde(flatten)]
pub
fields
:
HashMap
<
String
,
Value
>
,
}
#[derive(Serialize,
Deserialize,
Debug)]
pub
struct
InsertTreeEdge
{
pub
_type
:
String
,
pub
_target
:
InsertTreeItem
,
#[serde(flatten)]
pub
fields
:
HashMap
<
String
,
Value
>
,
}
#[derive(Serialize,
Deserialize,
Debug)]
#[serde(rename_all
=
"camelCase"
)]
pub
struct
SearchByFields
{
...
...
This diff is collapsed.
Click to expand it.
src/internal_api.rs
+
20
-
7
View file @
306e8d3d
use
crate
::
api_model
::
BulkAction
;
use
crate
::
api_model
::
CreateItem
;
use
crate
::
api_model
::
DeleteEdge
;
use
crate
::
api_model
::
InsertTreeItem
;
use
crate
::
api_model
::
SearchByFields
;
use
crate
::
error
::
Error
;
use
crate
::
error
::
Result
;
...
...
@@ -250,12 +250,25 @@ pub fn bulk_action_tx(tx: &Transaction, bulk_action: BulkAction) -> Result<()> {
Ok
(())
}
pub
fn
create_item
(
conn
:
&
mut
Connection
,
create_action
:
CreateItem
)
->
Result
<
i64
>
{
debug!
(
"Creating item {:?}"
,
create_action
);
let
tx
=
conn
.transaction
()
?
;
let
result
=
create_item_tx
(
&
tx
,
create_action
.fields
)
?
;
tx
.commit
()
?
;
Ok
(
result
)
pub
fn
insert_tree
(
tx
:
&
Transaction
,
item
:
InsertTreeItem
)
->
Result
<
i64
>
{
let
source_uid
:
i64
=
if
item
.fields
.len
()
>
1
{
create_item_tx
(
tx
,
item
.fields
)
?
}
else
if
let
Some
(
uid
)
=
item
.fields
.get
(
"uid"
)
.map
(|
v
|
v
.as_i64
())
.flatten
()
{
if
!
item
._edges
.is_empty
()
{
update_item_tx
(
tx
,
uid
,
HashMap
::
new
())
?
;
}
uid
}
else
{
return
Err
(
Error
{
code
:
StatusCode
::
BAD_REQUEST
,
msg
:
format!
(
"Cannot create item: {:?}"
,
item
),
});
};
for
edge
in
item
._edges
{
let
target_item
=
insert_tree
(
tx
,
edge
._target
)
?
;
create_edge
(
tx
,
&
edge
._type
,
source_uid
,
target_item
,
edge
.fields
)
?
;
}
Ok
(
source_uid
)
}
pub
fn
search_by_fields
(
tx
:
&
Transaction
,
query
:
SearchByFields
)
->
Result
<
Vec
<
Value
>>
{
...
...
This diff is collapsed.
Click to expand it.
src/warp_api.rs
+
15
-
2
View file @
306e8d3d
use
crate
::
api_model
::
BulkAction
;
use
crate
::
api_model
::
CreateItem
;
use
crate
::
api_model
::
GetFile
;
use
crate
::
api_model
::
InsertTreeItem
;
use
crate
::
api_model
::
PayloadWrapper
;
use
crate
::
api_model
::
RunDownloader
;
use
crate
::
api_model
::
RunImporter
;
...
...
@@ -126,7 +127,18 @@ pub async fn run_server(cli_options: &CLIOptions) {
});
let
init_db
=
initialized_databases_arc
.clone
();
let
search
=
items_api
let
insert_tree
=
items_api
.and
(
warp
::
path!
(
String
/
"insert_tree"
))
.and
(
warp
::
path
::
end
())
.and
(
warp
::
body
::
json
())
.map
(
move
|
owner
:
String
,
body
:
PayloadWrapper
<
InsertTreeItem
>
|
{
let
result
=
warp_endpoints
::
insert_tree
(
owner
,
init_db
.deref
(),
body
);
let
result
=
result
.map
(|
result
|
warp
::
reply
::
json
(
&
result
));
respond_with_result
(
result
)
});
let
init_db
=
initialized_databases_arc
.clone
();
let
search_by_fields
=
items_api
.and
(
warp
::
path!
(
String
/
"search_by_fields"
))
.and
(
warp
::
path
::
end
())
.and
(
warp
::
body
::
json
())
...
...
@@ -250,7 +262,8 @@ pub async fn run_server(cli_options: &CLIOptions) {
.or
(
bulk_action
.with
(
&
headers
))
.or
(
update_item
.with
(
&
headers
))
.or
(
delete_item
.with
(
&
headers
))
.or
(
search
.with
(
&
headers
))
.or
(
insert_tree
.with
(
&
headers
))
.or
(
search_by_fields
.with
(
&
headers
))
.or
(
get_items_with_edges
.with
(
&
headers
))
.or
(
run_downloader
.with
(
&
headers
))
.or
(
run_importer
.with
(
&
headers
))
...
...
This diff is collapsed.
Click to expand it.
src/warp_endpoints.rs
+
10
-
0
View file @
306e8d3d
use
crate
::
api_model
::
BulkAction
;
use
crate
::
api_model
::
CreateItem
;
use
crate
::
api_model
::
GetFile
;
use
crate
::
api_model
::
InsertTreeItem
;
use
crate
::
api_model
::
PayloadWrapper
;
use
crate
::
api_model
::
RunDownloader
;
use
crate
::
api_model
::
RunImporter
;
...
...
@@ -94,6 +95,15 @@ pub fn delete_item(
})
}
pub
fn
insert_tree
(
owner
:
String
,
init_db
:
&
RwLock
<
HashSet
<
String
>>
,
body
:
PayloadWrapper
<
InsertTreeItem
>
,
)
->
Result
<
i64
>
{
let
mut
conn
:
Connection
=
check_owner_and_initialize_db
(
&
owner
,
&
init_db
,
&
body
.database_key
)
?
;
in_transaction
(
&
mut
conn
,
|
tx
|
internal_api
::
insert_tree
(
&
tx
,
body
.payload
))
}
pub
fn
search_by_fields
(
owner
:
String
,
init_db
:
&
RwLock
<
HashSet
<
String
>>
,
...
...
This diff is collapsed.
Click to expand it.
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment
Menu
Explore
Projects
Groups
Snippets