Skip to content

Commit 5139218

Browse files
authored
Merge pull request #62 from axiomhq/tabular-support
move axiom-rs to use tabular results for queries
2 parents c36032b + 821e2a2 commit 5139218

File tree

10 files changed

+499
-436
lines changed

10 files changed

+499
-436
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ futures-util = "0.3"
4747
httpmock = "0.7"
4848
structopt = "0.3"
4949
tracing-subscriber = { version = "0.3", features = ["ansi", "env-filter"] }
50+
cli-table = "0.4.9"
5051

5152
[features]
5253
default = ["tokio", "default-tls"]

examples/cli.rs

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use axiom_rs::{
22
datasets::{ContentEncoding, ContentType},
33
Client,
44
};
5-
use std::time::Duration;
5+
use cli_table::{Cell as _, Style as _, Table as _};
66
use structopt::StructOpt;
77
use tokio::io::{stdin, AsyncReadExt};
88

@@ -37,13 +37,6 @@ enum Datasets {
3737
},
3838
/// Delete a dataset
3939
Delete { name: String },
40-
/// Trim a dataset
41-
Trim {
42-
name: String,
43-
44-
#[structopt(long)]
45-
seconds: u64,
46-
},
4740
/// Ingest into a dataset from stdin.
4841
Ingest {
4942
name: String,
@@ -73,19 +66,11 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
7366
println!("{:?}", dataset);
7467
}),
7568
Datasets::Get { name } => println!("{:?}", client.datasets().get(&name).await?),
76-
// Datasets::Info { name } => println!("{:?}", client.datasets().info(&name).await?),
7769
Datasets::Update { name, description } => {
7870
let dataset = client.datasets().update(&name, description).await?;
7971
println!("{:?}", dataset);
8072
}
8173
Datasets::Delete { name } => client.datasets().delete(&name).await?,
82-
Datasets::Trim { name, seconds } => println!(
83-
"{:?}",
84-
client
85-
.datasets()
86-
.trim(&name, Duration::from_secs(seconds))
87-
.await?
88-
),
8974
Datasets::Ingest {
9075
name,
9176
content_type,
@@ -99,8 +84,34 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
9984
println!("{:?}", ingest_status);
10085
}
10186
Datasets::Query { apl } => {
102-
let result = client.query(apl, None).await?;
103-
println!("{:?}", result);
87+
let result = client.query(&apl, None).await?;
88+
for table in result.tables {
89+
println!("{}:", table.name());
90+
91+
let rows_iter = table.iter();
92+
let mut rows = Vec::with_capacity(rows_iter.size_hint().0);
93+
for row in rows_iter {
94+
let field_iter = row.iter();
95+
let mut row_vec = Vec::with_capacity(field_iter.size_hint().0);
96+
for field in field_iter {
97+
row_vec.push(field.map_or_else(
98+
|| "-".to_string(),
99+
|v| serde_json::to_string(v).unwrap(),
100+
));
101+
}
102+
rows.push(row_vec);
103+
}
104+
105+
let mut fields = Vec::with_capacity(table.fields().len());
106+
for field in table.fields() {
107+
fields.push(field.name().to_string().cell().bold(true));
108+
}
109+
110+
let t = rows.table().title(fields).bold(true);
111+
112+
let table_display = t.display().unwrap();
113+
println!("{}", table_display);
114+
}
104115
}
105116
},
106117
Opt::Users(users) => match users {

src/client.rs

Lines changed: 7 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ use tracing::instrument;
1818
use crate::{
1919
annotations,
2020
datasets::{
21-
self, ContentEncoding, ContentType, IngestStatus, LegacyQuery, LegacyQueryOptions,
22-
LegacyQueryResult, Query, QueryOptions, QueryParams, QueryResult,
21+
self, ContentEncoding, ContentType, IngestStatus, Query, QueryOptions, QueryParams,
22+
QueryResult,
2323
},
2424
error::{Error, Result},
2525
http::{self, HeaderMap},
@@ -107,37 +107,14 @@ impl Client {
107107
/// Executes the given query specified using the Axiom Processing Language (APL).
108108
/// To learn more about APL, see the APL documentation at https://www.axiom.co/docs/apl/introduction.
109109
#[instrument(skip(self, opts))]
110-
pub async fn query<S, O>(&self, apl: S, opts: O) -> Result<QueryResult>
110+
pub async fn query<S, O>(&self, apl: &S, opts: O) -> Result<QueryResult>
111111
where
112-
S: Into<String> + FmtDebug,
112+
S: ToString + FmtDebug + ?Sized,
113113
O: Into<Option<QueryOptions>>,
114114
{
115-
let (req, query_params) = match opts.into() {
116-
Some(opts) => {
117-
let req = Query {
118-
apl: apl.into(),
119-
start_time: opts.start_time,
120-
end_time: opts.end_time,
121-
cursor: opts.cursor,
122-
include_cursor: opts.include_cursor,
123-
};
124-
125-
let query_params = QueryParams {
126-
no_cache: opts.no_cache,
127-
save: opts.save,
128-
format: opts.format,
129-
};
130-
131-
(req, query_params)
132-
}
133-
None => (
134-
Query {
135-
apl: apl.into(),
136-
..Default::default()
137-
},
138-
QueryParams::default(),
139-
),
140-
};
115+
let opts: QueryOptions = opts.into().unwrap_or_default();
116+
let query_params = QueryParams::from(&opts);
117+
let req = Query::new(apl, opts);
141118

142119
let query_params = serde_qs::to_string(&query_params)?;
143120
let path = format!("/v1/datasets/_apl?{query_params}");
@@ -157,44 +134,6 @@ impl Client {
157134
Ok(result)
158135
}
159136

160-
/// Execute the given query on the dataset identified by its id.
161-
#[instrument(skip(self, opts))]
162-
#[deprecated(
163-
since = "0.6.0",
164-
note = "The legacy query will be removed in future versions, use `apl_query` instead"
165-
)]
166-
pub async fn query_legacy<N, O>(
167-
&self,
168-
dataset_name: N,
169-
query: LegacyQuery,
170-
opts: O,
171-
) -> Result<LegacyQueryResult>
172-
where
173-
N: Into<String> + FmtDebug,
174-
O: Into<Option<LegacyQueryOptions>>,
175-
{
176-
let path = format!(
177-
"/v1/datasets/{}/query?{}",
178-
dataset_name.into(),
179-
&opts
180-
.into()
181-
.map_or_else(|| Ok(String::new()), |opts| { serde_qs::to_string(&opts) })?
182-
);
183-
let res = self.http_client.post(path, &query).await?;
184-
185-
let saved_query_id = res
186-
.headers()
187-
.get("X-Axiom-History-Query-Id")
188-
.map(|s| s.to_str())
189-
.transpose()
190-
.map_err(|_e| Error::InvalidQueryId)?
191-
.map(std::string::ToString::to_string);
192-
let mut result = res.json::<LegacyQueryResult>().await?;
193-
result.saved_query_id = saved_query_id;
194-
195-
Ok(result)
196-
}
197-
198137
/// Ingest events into the dataset identified by its id.
199138
/// Restrictions for field names (JSON object keys) can be reviewed here:
200139
/// <https://www.axiom.co/docs/usage/field-restrictions>.

src/datasets/client.rs

Lines changed: 2 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
11
#[allow(deprecated)]
22
use crate::{
3-
datasets::model::{
4-
Dataset, DatasetCreateRequest, DatasetUpdateRequest, Info, TrimRequest, TrimResult,
5-
},
3+
datasets::model::{Dataset, DatasetCreateRequest, DatasetUpdateRequest, Info},
64
error::{Error, Result},
75
http,
86
};
97
use std::{
10-
convert::{TryFrom, TryInto},
11-
fmt::Debug as FmtDebug,
12-
result::Result as StdResult,
8+
convert::TryFrom, fmt::Debug as FmtDebug, result::Result as StdResult,
139
time::Duration as StdDuration,
1410
};
1511
use tracing::instrument;
@@ -93,27 +89,6 @@ impl<'client> Client<'client> {
9389
self.http_client.get("/v1/datasets").await?.json().await
9490
}
9591

96-
/// Trim the dataset identified by its id to a given length.
97-
/// The max duration given will mark the oldest timestamp an event can have.
98-
/// Older ones will be deleted from the dataset.
99-
/// The duration can either be a [`std::time::Duration`] or a
100-
/// [`chrono::Duration`].
101-
#[instrument(skip(self))]
102-
#[allow(deprecated)]
103-
pub async fn trim<N, D>(&self, dataset_name: N, duration: D) -> Result<TrimResult>
104-
where
105-
N: Into<String> + FmtDebug,
106-
D: TryInto<Duration, Error = Error> + FmtDebug,
107-
{
108-
let duration = duration.try_into()?;
109-
let req = TrimRequest::new(duration.into());
110-
self.http_client
111-
.post(format!("/v1/datasets/{}/trim", dataset_name.into()), &req)
112-
.await?
113-
.json()
114-
.await
115-
}
116-
11792
/// Update a dataset.
11893
#[instrument(skip(self))]
11994
pub async fn update<N, D>(&self, dataset_name: N, new_description: D) -> Result<Dataset>

0 commit comments

Comments
 (0)