Skip to content

Commit

Permalink
wip, wrong direction but useful
Browse files Browse the repository at this point in the history
  • Loading branch information
bnaecker committed Jun 28, 2024
1 parent 7c19eb2 commit e59df96
Show file tree
Hide file tree
Showing 4 changed files with 433 additions and 138 deletions.
10 changes: 6 additions & 4 deletions nexus/db-model/src/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1762,16 +1762,16 @@ table! {
}

table! {
timeseries_schema (timeseries_name, version) {
timeseries_schema (timeseries_name) {
timeseries_name -> Text,
version -> Int2,
authz_scope -> crate::TimeseriesAuthzScopeEnum,
target_description -> Text,
metric_description -> Text,
datum_type -> crate::TimeseriesDatumTypeEnum,
units -> crate::TimeseriesUnitsEnum,
time_created -> Timestamptz,
time_modified -> Timestamptz,
generation -> Int8,
}
}

Expand All @@ -1784,14 +1784,16 @@ table! {
description -> Text,
time_created -> Timestamptz,
time_modified -> Timestamptz,
generation -> Int8,
}
}

table! {
timeseries_version_field (timeseries_name, version, field_name) {
timeseries_field_by_version (timeseries_name, version, field_name) {
timeseries_name -> Text,
version -> Int2,
field_name -> Text,
generation -> Int8,
}
}

Expand Down Expand Up @@ -1900,5 +1902,5 @@ joinable!(network_interface -> probe (parent_id));
allow_tables_to_appear_in_same_query!(
timeseries_field,
timeseries_schema,
timeseries_version_field
timeseries_field_by_version
);
71 changes: 36 additions & 35 deletions nexus/db-model/src/timeseries_schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,18 @@

//! Types modeling the timeseries schema tables.
use std::collections::BTreeSet;
use std::num::NonZeroU8;

use crate::impl_enum_type;
use crate::schema::timeseries_field;
use crate::schema::timeseries_schema;
use crate::schema::timeseries_version_field;
use crate::schema::timeseries_field_by_version;
use crate::Generation;
use crate::SqlU8;
use chrono::DateTime;
use chrono::Utc;
use omicron_common::api::external::Error;
use std::collections::BTreeSet;
use std::num::NonZeroU8;

impl_enum_type! {
#[derive(SqlType, QueryId, Debug, Clone, Copy)]
Expand Down Expand Up @@ -287,8 +289,6 @@ impl From<TimeseriesUnits> for oximeter::schema::Units {
pub struct TimeseriesSchema {
/// The name of the timeseries.
pub timeseries_name: String,
/// The version of the timeseries.
pub version: SqlU8,
/// The authorization scope of the timeseries.
pub authz_scope: TimeseriesAuthzScope,
/// The description of the timeseries's target.
Expand All @@ -301,40 +301,32 @@ pub struct TimeseriesSchema {
pub units: TimeseriesUnits,
pub time_created: DateTime<Utc>,
pub time_modified: DateTime<Utc>,
/// Generation number of the timeseries schema, shared by all records for a
/// single schema. Used for OCC.
pub generation: Generation,
}

impl TryFrom<TimeseriesSchema> for oximeter::TimeseriesSchema {
type Error = Error;

// NOTE: This converts _only_ the parts in the actual `timeseries_schema`
// table, which omits the field schema. those must be added later.
fn try_from(value: TimeseriesSchema) -> Result<Self, Self::Error> {
let Ok(timeseries_name) = value.timeseries_name.as_str().try_into()
impl TimeseriesSchema {
pub fn into_bare_schema(self, version: NonZeroU8) -> Result<oximeter::TimeseriesSchema, Error> {
let Ok(timeseries_name) = self.timeseries_name.as_str().try_into()
else {
return Err(Error::internal_error(&format!(
"Invalid timeseries name in database: '{}'",
value.timeseries_name
)));
};
let Some(version) = NonZeroU8::new(*value.version) else {
return Err(Error::internal_error(&format!(
"Found zero version number for \
timeseries '{}' in database",
*value.version,
self.timeseries_name
)));
};
Ok(Self {
Ok(oximeter::TimeseriesSchema {
timeseries_name,
description: oximeter::schema::TimeseriesDescription {
target: value.target_description,
metric: value.metric_description,
target: self.target_description,
metric: self.metric_description,
},
field_schema: BTreeSet::new(),
datum_type: value.datum_type.into(),
datum_type: self.datum_type.into(),
version,
authz_scope: value.authz_scope.into(),
units: value.units.into(),
created: value.time_created,
authz_scope: self.authz_scope.into(),
units: self.units.into(),
created: self.time_created,
})
}
}
Expand All @@ -357,18 +349,19 @@ impl TimeseriesSchemaUpdate {
}
}

impl From<&oximeter::TimeseriesSchema> for TimeseriesSchema {
fn from(schema: &oximeter::TimeseriesSchema) -> Self {
impl TimeseriesSchema {
/// Create a schema row with the provided generation.
pub fn new(schema: &oximeter::TimeseriesSchema, generation: Generation) -> Self {
Self {
timeseries_name: schema.timeseries_name.to_string(),
version: schema.version.get().into(),
authz_scope: schema.authz_scope.into(),
target_description: schema.description.target.clone(),
metric_description: schema.description.metric.clone(),
datum_type: schema.datum_type.into(),
units: schema.units.into(),
time_created: schema.created,
time_modified: schema.created,
generation,
}
}
}
Expand All @@ -388,6 +381,9 @@ pub struct TimeseriesField {
pub description: String,
pub time_created: DateTime<Utc>,
pub time_modified: DateTime<Utc>,
/// Generation number of the timeseries schema, shared by all records for a
/// single schema. Used for OCC.
pub generation: Generation,
}

impl From<TimeseriesField> for oximeter::FieldSchema {
Expand All @@ -402,7 +398,7 @@ impl From<TimeseriesField> for oximeter::FieldSchema {
}

impl TimeseriesField {
pub fn for_schema(schema: &oximeter::TimeseriesSchema) -> Vec<Self> {
pub fn for_schema(schema: &oximeter::TimeseriesSchema, generation: Generation) -> Vec<Self> {
schema
.field_schema
.iter()
Expand All @@ -414,6 +410,7 @@ impl TimeseriesField {
description: field.description.clone(),
time_created: schema.created,
time_modified: schema.created,
generation,
})
.collect()
}
Expand All @@ -422,25 +419,29 @@ impl TimeseriesField {
/// This type models the mapping from each version of a timeseries schema to a
/// row it contains.
#[derive(Insertable, Selectable, Queryable, Clone, Debug)]
#[diesel(table_name = timeseries_version_field)]
pub struct TimeseriesVersionField {
#[diesel(table_name = timeseries_field_by_version)]
pub struct TimeseriesFieldByVersion {
/// The name of the timeseries this field belongs to.
pub timeseries_name: String,
/// The version of the timeseries this field belongs to.
pub version: SqlU8,
/// The name of the field.
pub field_name: String,
/// Generation number of the timeseries schema, shared by all records for a
/// single schema. Used for OCC.
pub generation: Generation,
}

impl TimeseriesVersionField {
pub fn for_schema(schema: &oximeter::TimeseriesSchema) -> Vec<Self> {
impl TimeseriesFieldByVersion {
pub fn for_schema(schema: &oximeter::TimeseriesSchema, generation: Generation) -> Vec<Self> {
schema
.field_schema
.iter()
.map(|field| Self {
timeseries_name: schema.timeseries_name.to_string(),
version: schema.version.get().into(),
field_name: field.name.clone(),
generation,
})
.collect()
}
Expand Down
Loading

0 comments on commit e59df96

Please sign in to comment.