Skip to content

Commit b0cef62

Browse files
committed
Document search rpc
1 parent 0768846 commit b0cef62

6 files changed

Lines changed: 145 additions & 61 deletions

File tree

docs/rpc/analytics/search.md

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# search
2+
3+
## Description
4+
5+
Performs a case-insensitive substring search across areas, places and events, returning matching records sorted by source (areas first, then places, then events). When the optional `type` filter is provided, only records of that source are returned.
6+
7+
## Params
8+
9+
```json
10+
{
11+
"query": "berlin",
12+
"type": "place"
13+
}
14+
```
15+
16+
| Field | Type | Required | Description |
17+
| ------ | ------ | -------- | ------------------------------------------------------------------------------------------------- |
18+
| query | string | yes | The search string matched against area names, place names and event names (case-insensitive). |
19+
| type | string | no | Restricts the result set to a single source. Accepts `area`, `place` or `event`. Defaults to all. |
20+
21+
## Result Format
22+
23+
```json
24+
[
25+
{
26+
"name": "Berlin",
27+
"type": "area",
28+
"id": 42
29+
},
30+
{
31+
"name": "Berlin Bitcoin Meetup",
32+
"type": "place",
33+
"id": 1337
34+
},
35+
{
36+
"name": "Bitcoin Berlin Conference",
37+
"type": "event",
38+
"id": 9
39+
}
40+
]
41+
```
42+
43+
| Field | Type | Description |
44+
| ----- | ------- | ------------------------------------------------------------------------ |
45+
| name | string | Display name of the matched record. |
46+
| type | string | Source of the record: `area`, `place` or `event`. |
47+
| id | integer | Database id of the matched area, place or event. |
48+
49+
## Allowed Roles
50+
51+
- Root
52+
- Admin
53+
- Event Manager
54+
55+
## Examples
56+
57+
### curl
58+
59+
```bash
60+
curl --header 'Content-Type: application/json' \
61+
--header "Authorization: Bearer $ACCESS_TOKEN" \
62+
--request POST \
63+
--data '{"jsonrpc":"2.0","method":"search","params":{"query":"berlin"},"id":1}' \
64+
https://api.btcmap.org/rpc
65+
```
66+
67+
Search only places:
68+
69+
```bash
70+
curl --header 'Content-Type: application/json' \
71+
--header "Authorization: Bearer $ACCESS_TOKEN" \
72+
--request POST \
73+
--data '{"jsonrpc":"2.0","method":"search","params":{"query":"berlin","type":"place"},"id":1}' \
74+
https://api.btcmap.org/rpc
75+
```

src/rpc/analytics/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ pub mod get_daily_infra_report;
33
pub mod get_report;
44
pub mod get_request_log;
55
pub mod get_top_clients;
6+
pub mod search;

src/rpc/analytics/search.rs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
use crate::{db, Result};
2+
use deadpool_sqlite::Pool;
3+
use serde::{Deserialize, Serialize};
4+
5+
#[derive(Deserialize)]
6+
pub struct Params {
7+
pub query: String,
8+
pub r#type: Option<String>,
9+
}
10+
11+
#[derive(Serialize)]
12+
pub struct Res {
13+
pub name: String,
14+
pub r#type: String,
15+
pub id: i64,
16+
}
17+
18+
pub async fn run(params: Params, pool: &Pool) -> Result<Vec<Res>> {
19+
let mut res = vec![];
20+
let filter = params.r#type.as_deref();
21+
if filter.is_none() || filter == Some("area") {
22+
let areas = db::main::area::queries::select_by_search_query(&params.query, pool).await?;
23+
let mut res_areas: Vec<Res> = areas
24+
.into_iter()
25+
.map(|it| Res {
26+
name: it.name(),
27+
r#type: "area".into(),
28+
id: it.id,
29+
})
30+
.collect();
31+
res.append(&mut res_areas);
32+
}
33+
if filter.is_none() || filter == Some("place") {
34+
let elements =
35+
db::main::element::queries::select_by_search_query(&params.query, true, pool).await?;
36+
let mut res_elements: Vec<Res> = elements
37+
.into_iter()
38+
.map(|it| Res {
39+
name: it.name(None),
40+
r#type: "place".into(),
41+
id: it.id,
42+
})
43+
.collect();
44+
res.append(&mut res_elements);
45+
}
46+
if filter.is_none() || filter == Some("event") {
47+
let events = db::main::event::queries::select_all(pool).await?;
48+
let events: Vec<_> = events
49+
.into_iter()
50+
.filter(|it| {
51+
it.name
52+
.to_uppercase()
53+
.contains(&params.query.to_uppercase())
54+
})
55+
.collect();
56+
let mut res_events: Vec<Res> = events
57+
.into_iter()
58+
.map(|it| Res {
59+
name: it.name,
60+
r#type: "event".into(),
61+
id: it.id,
62+
})
63+
.collect();
64+
res.append(&mut res_events);
65+
}
66+
Ok(res)
67+
}

src/rpc/handler.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -572,7 +572,7 @@ pub async fn handle(
572572
),
573573
RpcMethod::Search => RpcResponse::from(
574574
req.id.clone(),
575-
super::search::run(params(req.params)?, &main_pool).await?,
575+
super::analytics::search::run(params(req.params)?, &main_pool).await?,
576576
),
577577
RpcMethod::GetReport => RpcResponse::from(
578578
req.id.clone(),

src/rpc/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ pub mod remove_area;
2929
pub mod remove_area_tag;
3030
pub mod remove_element_tag;
3131
pub mod remove_user_tag;
32-
pub mod search;
32+
3333
pub mod set_area_image;
3434
pub mod set_area_tag;
3535
pub mod set_element_tag;

src/rpc/search.rs

Lines changed: 0 additions & 59 deletions
This file was deleted.

0 commit comments

Comments
 (0)