Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2,866 changes: 0 additions & 2,866 deletions nexus/src/db/model.rs

This file was deleted.

52 changes: 52 additions & 0 deletions nexus/src/db/model/block_size.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

use super::impl_enum_type;
use crate::external_api::params;
use omicron_common::api::external;
use serde::{Deserialize, Serialize};
use std::io::Write;

impl_enum_type!(
#[derive(SqlType, Debug, QueryId)]
#[diesel(postgres_type(name = "block_size"))]
pub struct BlockSizeEnum;

#[derive(Copy, Clone, Debug, AsExpression, FromSqlRow, Serialize, Deserialize, PartialEq)]
#[diesel(sql_type = BlockSizeEnum)]
pub enum BlockSize;

// Enum values
Traditional => b"512"
Iso => b"2048"
AdvancedFormat => b"4096"
);

impl BlockSize {
pub fn to_bytes(&self) -> u32 {
match self {
BlockSize::Traditional => 512,
BlockSize::Iso => 2048,
BlockSize::AdvancedFormat => 4096,
}
}
}

impl Into<external::ByteCount> for BlockSize {
fn into(self) -> external::ByteCount {
external::ByteCount::from(self.to_bytes())
}
}

impl TryFrom<params::BlockSize> for BlockSize {
type Error = anyhow::Error;
fn try_from(block_size: params::BlockSize) -> Result<Self, Self::Error> {
match block_size.0 {
512 => Ok(BlockSize::Traditional),
2048 => Ok(BlockSize::Iso),
4096 => Ok(BlockSize::AdvancedFormat),
_ => anyhow::bail!("invalid block size {}", block_size.0),
}
}
}
65 changes: 65 additions & 0 deletions nexus/src/db/model/bytecount.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

use super::BlockSize;
use diesel::backend::{Backend, RawValue};
use diesel::deserialize::{self, FromSql};
use diesel::pg::Pg;
use diesel::serialize::{self, ToSql};
use diesel::sql_types;
use omicron_common::api::external;
use serde::{Deserialize, Serialize};
use std::convert::TryFrom;

#[derive(
Copy,
Clone,
Debug,
AsExpression,
FromSqlRow,
Serialize,
Deserialize,
PartialEq,
)]
#[diesel(sql_type = sql_types::BigInt)]
pub struct ByteCount(pub external::ByteCount);

NewtypeFrom! { () pub struct ByteCount(external::ByteCount); }
NewtypeDeref! { () pub struct ByteCount(external::ByteCount); }

impl ToSql<sql_types::BigInt, Pg> for ByteCount {
fn to_sql<'a>(
&'a self,
out: &mut serialize::Output<'a, '_, Pg>,
) -> serialize::Result {
<i64 as ToSql<sql_types::BigInt, Pg>>::to_sql(
&i64::from(self.0),
&mut out.reborrow(),
)
}
}

impl<DB> FromSql<sql_types::BigInt, DB> for ByteCount
where
DB: Backend,
i64: FromSql<sql_types::BigInt, DB>,
{
fn from_sql(bytes: RawValue<DB>) -> deserialize::Result<Self> {
external::ByteCount::try_from(i64::from_sql(bytes)?)
.map(ByteCount)
.map_err(|e| e.into())
}
}

impl From<ByteCount> for sled_agent_client::types::ByteCount {
fn from(b: ByteCount) -> Self {
Self(b.to_bytes())
}
}

impl From<BlockSize> for ByteCount {
fn from(bs: BlockSize) -> Self {
Self(bs.to_bytes().into())
}
}
29 changes: 29 additions & 0 deletions nexus/src/db/model/console_session.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

use crate::db::schema::console_session;
use chrono::{DateTime, Utc};
use uuid::Uuid;

// TODO: `struct SessionToken(String)` for session token

#[derive(Queryable, Insertable, Clone, Debug, Selectable)]
#[diesel(table_name = console_session)]
pub struct ConsoleSession {
pub token: String,
pub time_created: DateTime<Utc>,
pub time_last_used: DateTime<Utc>,
pub silo_user_id: Uuid,
}

impl ConsoleSession {
pub fn new(token: String, silo_user_id: Uuid) -> Self {
let now = Utc::now();
Self { token, silo_user_id, time_last_used: now, time_created: now }
}

pub fn id(&self) -> String {
self.token.clone()
}
}
84 changes: 84 additions & 0 deletions nexus/src/db/model/dataset.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

use super::{DatasetKind, Generation, Region};
use crate::db::collection_insert::DatastoreCollection;
use crate::db::schema::{dataset, region};
use chrono::{DateTime, Utc};
use db_macros::Asset;
use serde::{Deserialize, Serialize};
use std::net::SocketAddr;
use uuid::Uuid;

/// Database representation of a Dataset.
///
/// A dataset represents a portion of a Zpool, which is then made
/// available to a service on the Sled.
#[derive(
Queryable,
Insertable,
Debug,
Clone,
Selectable,
Asset,
Deserialize,
Serialize,
PartialEq,
)]
#[diesel(table_name = dataset)]
pub struct Dataset {
#[diesel(embed)]
identity: DatasetIdentity,
time_deleted: Option<DateTime<Utc>>,
rcgen: Generation,

pub pool_id: Uuid,

ip: ipnetwork::IpNetwork,
port: i32,

kind: DatasetKind,
pub size_used: Option<i64>,
}

impl Dataset {
pub fn new(
id: Uuid,
pool_id: Uuid,
addr: SocketAddr,
kind: DatasetKind,
) -> Self {
let size_used = match kind {
DatasetKind::Crucible => Some(0),
_ => None,
};
Self {
identity: DatasetIdentity::new(id),
time_deleted: None,
rcgen: Generation::new(),
pool_id,
ip: addr.ip().into(),
port: addr.port().into(),
kind,
size_used,
}
}

pub fn address(&self) -> SocketAddr {
// TODO: avoid this unwrap
self.address_with_port(u16::try_from(self.port).unwrap())
}

pub fn address_with_port(&self, port: u16) -> SocketAddr {
SocketAddr::new(self.ip.ip(), port)
}
}

// Datasets contain regions
impl DatastoreCollection<Region> for Dataset {
type CollectionId = Uuid;
type GenerationNumberColumn = dataset::dsl::rcgen;
type CollectionTimeDeletedColumn = dataset::dsl::time_deleted;
type CollectionIdColumn = region::dsl::dataset_id;
}
39 changes: 39 additions & 0 deletions nexus/src/db/model/dataset_kind.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

use super::impl_enum_type;
use crate::internal_api;
use serde::{Deserialize, Serialize};
use std::io::Write;

impl_enum_type!(
#[derive(SqlType, Debug, QueryId)]
#[diesel(postgres_type(name = "dataset_kind"))]
pub struct DatasetKindEnum;

#[derive(Clone, Debug, AsExpression, FromSqlRow, Serialize, Deserialize, PartialEq)]
#[diesel(sql_type = DatasetKindEnum)]
pub enum DatasetKind;

// Enum values
Crucible => b"crucible"
Cockroach => b"cockroach"
Clickhouse => b"clickhouse"
);

impl From<internal_api::params::DatasetKind> for DatasetKind {
fn from(k: internal_api::params::DatasetKind) -> Self {
match k {
internal_api::params::DatasetKind::Crucible => {
DatasetKind::Crucible
}
internal_api::params::DatasetKind::Cockroach => {
DatasetKind::Cockroach
}
internal_api::params::DatasetKind::Clickhouse => {
DatasetKind::Clickhouse
}
}
}
}
62 changes: 62 additions & 0 deletions nexus/src/db/model/digest.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

use diesel::backend::{Backend, RawValue};
use diesel::deserialize::{self, FromSql};
use diesel::pg::Pg;
use diesel::serialize::{self, ToSql};
use diesel::sql_types;
use omicron_common::api::external;
use parse_display::Display;
use ref_cast::RefCast;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};

/// Newtype wrapper around [external::Digest]
#[derive(
Clone,
Debug,
Display,
AsExpression,
FromSqlRow,
Eq,
PartialEq,
Ord,
PartialOrd,
RefCast,
JsonSchema,
Serialize,
Deserialize,
)]
#[diesel(sql_type = sql_types::Text)]
#[serde(transparent)]
#[repr(transparent)]
#[display("{0}")]
pub struct Digest(pub external::Digest);

NewtypeFrom! { () pub struct Digest(external::Digest); }
NewtypeDeref! { () pub struct Digest(external::Digest); }

impl ToSql<sql_types::Text, Pg> for Digest {
fn to_sql<'a>(
&'a self,
out: &mut serialize::Output<'a, '_, Pg>,
) -> serialize::Result {
<String as ToSql<sql_types::Text, Pg>>::to_sql(
&self.0.to_string(),
&mut out.reborrow(),
)
}
}

impl<DB> FromSql<sql_types::Text, DB> for Digest
where
DB: Backend,
String: FromSql<sql_types::Text, DB>,
{
fn from_sql(bytes: RawValue<DB>) -> deserialize::Result<Self> {
let digest: external::Digest = String::from_sql(bytes)?.parse()?;
Ok(Digest(digest))
}
}
Loading