Make some db tests pass against the new sea-orm implementation
This commit is contained in:
parent
b7294887c7
commit
d9a892a423
9 changed files with 849 additions and 711 deletions
|
@ -8,7 +8,7 @@ CREATE TABLE "users" (
|
||||||
"inviter_id" INTEGER REFERENCES users (id),
|
"inviter_id" INTEGER REFERENCES users (id),
|
||||||
"connected_once" BOOLEAN NOT NULL DEFAULT false,
|
"connected_once" BOOLEAN NOT NULL DEFAULT false,
|
||||||
"created_at" TIMESTAMP NOT NULL DEFAULT now,
|
"created_at" TIMESTAMP NOT NULL DEFAULT now,
|
||||||
"metrics_id" VARCHAR(255),
|
"metrics_id" TEXT,
|
||||||
"github_user_id" INTEGER
|
"github_user_id" INTEGER
|
||||||
);
|
);
|
||||||
CREATE UNIQUE INDEX "index_users_github_login" ON "users" ("github_login");
|
CREATE UNIQUE INDEX "index_users_github_login" ON "users" ("github_login");
|
||||||
|
|
|
@ -18,6 +18,7 @@ use sea_orm::{
|
||||||
entity::prelude::*, ConnectOptions, DatabaseConnection, DatabaseTransaction, DbErr,
|
entity::prelude::*, ConnectOptions, DatabaseConnection, DatabaseTransaction, DbErr,
|
||||||
TransactionTrait,
|
TransactionTrait,
|
||||||
};
|
};
|
||||||
|
use sea_query::OnConflict;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use sqlx::migrate::{Migrate, Migration, MigrationSource};
|
use sqlx::migrate::{Migrate, Migration, MigrationSource};
|
||||||
use sqlx::Connection;
|
use sqlx::Connection;
|
||||||
|
@ -42,7 +43,7 @@ pub struct Database {
|
||||||
impl Database {
|
impl Database {
|
||||||
pub async fn new(url: &str, max_connections: u32) -> Result<Self> {
|
pub async fn new(url: &str, max_connections: u32) -> Result<Self> {
|
||||||
let mut options = ConnectOptions::new(url.into());
|
let mut options = ConnectOptions::new(url.into());
|
||||||
options.min_connections(1).max_connections(max_connections);
|
options.max_connections(max_connections);
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
url: url.into(),
|
url: url.into(),
|
||||||
pool: sea_orm::Database::connect(options).await?,
|
pool: sea_orm::Database::connect(options).await?,
|
||||||
|
@ -58,7 +59,7 @@ impl Database {
|
||||||
&self,
|
&self,
|
||||||
migrations_path: &Path,
|
migrations_path: &Path,
|
||||||
ignore_checksum_mismatch: bool,
|
ignore_checksum_mismatch: bool,
|
||||||
) -> anyhow::Result<Vec<(Migration, Duration)>> {
|
) -> anyhow::Result<(sqlx::AnyConnection, Vec<(Migration, Duration)>)> {
|
||||||
let migrations = MigrationSource::resolve(migrations_path)
|
let migrations = MigrationSource::resolve(migrations_path)
|
||||||
.await
|
.await
|
||||||
.map_err(|err| anyhow!("failed to load migrations: {err:?}"))?;
|
.map_err(|err| anyhow!("failed to load migrations: {err:?}"))?;
|
||||||
|
@ -92,11 +93,45 @@ impl Database {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(new_migrations)
|
Ok((connection, new_migrations))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn create_user(
|
||||||
|
&self,
|
||||||
|
email_address: &str,
|
||||||
|
admin: bool,
|
||||||
|
params: NewUserParams,
|
||||||
|
) -> Result<NewUserResult> {
|
||||||
|
self.transact(|tx| async {
|
||||||
|
let user = user::Entity::insert(user::ActiveModel {
|
||||||
|
email_address: ActiveValue::set(Some(email_address.into())),
|
||||||
|
github_login: ActiveValue::set(params.github_login.clone()),
|
||||||
|
github_user_id: ActiveValue::set(Some(params.github_user_id)),
|
||||||
|
admin: ActiveValue::set(admin),
|
||||||
|
metrics_id: ActiveValue::set(Uuid::new_v4()),
|
||||||
|
..Default::default()
|
||||||
|
})
|
||||||
|
.on_conflict(
|
||||||
|
OnConflict::column(user::Column::GithubLogin)
|
||||||
|
.update_column(user::Column::GithubLogin)
|
||||||
|
.to_owned(),
|
||||||
|
)
|
||||||
|
.exec_with_returning(&tx)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
tx.commit().await?;
|
||||||
|
|
||||||
|
Ok(NewUserResult {
|
||||||
|
user_id: user.id,
|
||||||
|
metrics_id: user.metrics_id.to_string(),
|
||||||
|
signup_device_id: None,
|
||||||
|
inviting_user_id: None,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_users_by_ids(&self, ids: Vec<UserId>) -> Result<Vec<user::Model>> {
|
pub async fn get_users_by_ids(&self, ids: Vec<UserId>) -> Result<Vec<user::Model>> {
|
||||||
let ids = ids.iter().map(|id| id.0).collect::<Vec<_>>();
|
|
||||||
self.transact(|tx| async {
|
self.transact(|tx| async {
|
||||||
let tx = tx;
|
let tx = tx;
|
||||||
Ok(user::Entity::find()
|
Ok(user::Entity::find()
|
||||||
|
@ -119,7 +154,7 @@ impl Database {
|
||||||
.one(&tx)
|
.one(&tx)
|
||||||
.await?
|
.await?
|
||||||
.ok_or_else(|| anyhow!("could not find participant"))?;
|
.ok_or_else(|| anyhow!("could not find participant"))?;
|
||||||
if participant.room_id != room_id.0 {
|
if participant.room_id != room_id {
|
||||||
return Err(anyhow!("shared project on unexpected room"))?;
|
return Err(anyhow!("shared project on unexpected room"))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,14 +191,14 @@ impl Database {
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let room = self.get_room(room_id, &tx).await?;
|
let room = self.get_room(room_id, &tx).await?;
|
||||||
self.commit_room_transaction(room_id, tx, (ProjectId(project.id), room))
|
self.commit_room_transaction(room_id, tx, (project.id, room))
|
||||||
.await
|
.await
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_room(&self, room_id: RoomId, tx: &DatabaseTransaction) -> Result<proto::Room> {
|
async fn get_room(&self, room_id: RoomId, tx: &DatabaseTransaction) -> Result<proto::Room> {
|
||||||
let db_room = room::Entity::find_by_id(room_id.0)
|
let db_room = room::Entity::find_by_id(room_id)
|
||||||
.one(tx)
|
.one(tx)
|
||||||
.await?
|
.await?
|
||||||
.ok_or_else(|| anyhow!("could not find room"))?;
|
.ok_or_else(|| anyhow!("could not find room"))?;
|
||||||
|
@ -184,7 +219,7 @@ impl Database {
|
||||||
(Some(0), Some(project_id)) => {
|
(Some(0), Some(project_id)) => {
|
||||||
Some(proto::participant_location::Variant::SharedProject(
|
Some(proto::participant_location::Variant::SharedProject(
|
||||||
proto::participant_location::SharedProject {
|
proto::participant_location::SharedProject {
|
||||||
id: project_id as u64,
|
id: project_id.to_proto(),
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
@ -198,7 +233,7 @@ impl Database {
|
||||||
participants.insert(
|
participants.insert(
|
||||||
answering_connection_id,
|
answering_connection_id,
|
||||||
proto::Participant {
|
proto::Participant {
|
||||||
user_id: db_participant.user_id as u64,
|
user_id: db_participant.user_id.to_proto(),
|
||||||
peer_id: answering_connection_id as u32,
|
peer_id: answering_connection_id as u32,
|
||||||
projects: Default::default(),
|
projects: Default::default(),
|
||||||
location: Some(proto::ParticipantLocation { variant: location }),
|
location: Some(proto::ParticipantLocation { variant: location }),
|
||||||
|
@ -206,9 +241,9 @@ impl Database {
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
pending_participants.push(proto::PendingParticipant {
|
pending_participants.push(proto::PendingParticipant {
|
||||||
user_id: db_participant.user_id as u64,
|
user_id: db_participant.user_id.to_proto(),
|
||||||
calling_user_id: db_participant.calling_user_id as u64,
|
calling_user_id: db_participant.calling_user_id.to_proto(),
|
||||||
initial_project_id: db_participant.initial_project_id.map(|id| id as u64),
|
initial_project_id: db_participant.initial_project_id.map(|id| id.to_proto()),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -225,12 +260,12 @@ impl Database {
|
||||||
let project = if let Some(project) = participant
|
let project = if let Some(project) = participant
|
||||||
.projects
|
.projects
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.find(|project| project.id as i32 == db_project.id)
|
.find(|project| project.id == db_project.id.to_proto())
|
||||||
{
|
{
|
||||||
project
|
project
|
||||||
} else {
|
} else {
|
||||||
participant.projects.push(proto::ParticipantProject {
|
participant.projects.push(proto::ParticipantProject {
|
||||||
id: db_project.id as u64,
|
id: db_project.id.to_proto(),
|
||||||
worktree_root_names: Default::default(),
|
worktree_root_names: Default::default(),
|
||||||
});
|
});
|
||||||
participant.projects.last_mut().unwrap()
|
participant.projects.last_mut().unwrap()
|
||||||
|
@ -243,7 +278,7 @@ impl Database {
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(proto::Room {
|
Ok(proto::Room {
|
||||||
id: db_room.id as u64,
|
id: db_room.id.to_proto(),
|
||||||
live_kit_room: db_room.live_kit_room,
|
live_kit_room: db_room.live_kit_room,
|
||||||
participants: participants.into_values().collect(),
|
participants: participants.into_values().collect(),
|
||||||
pending_participants,
|
pending_participants,
|
||||||
|
@ -393,6 +428,84 @@ macro_rules! id_type {
|
||||||
self.0.fmt(f)
|
self.0.fmt(f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<$name> for sea_query::Value {
|
||||||
|
fn from(value: $name) -> Self {
|
||||||
|
sea_query::Value::Int(Some(value.0))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl sea_orm::TryGetable for $name {
|
||||||
|
fn try_get(
|
||||||
|
res: &sea_orm::QueryResult,
|
||||||
|
pre: &str,
|
||||||
|
col: &str,
|
||||||
|
) -> Result<Self, sea_orm::TryGetError> {
|
||||||
|
Ok(Self(i32::try_get(res, pre, col)?))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl sea_query::ValueType for $name {
|
||||||
|
fn try_from(v: Value) -> Result<Self, sea_query::ValueTypeErr> {
|
||||||
|
match v {
|
||||||
|
Value::TinyInt(Some(int)) => {
|
||||||
|
Ok(Self(int.try_into().map_err(|_| sea_query::ValueTypeErr)?))
|
||||||
|
}
|
||||||
|
Value::SmallInt(Some(int)) => {
|
||||||
|
Ok(Self(int.try_into().map_err(|_| sea_query::ValueTypeErr)?))
|
||||||
|
}
|
||||||
|
Value::Int(Some(int)) => {
|
||||||
|
Ok(Self(int.try_into().map_err(|_| sea_query::ValueTypeErr)?))
|
||||||
|
}
|
||||||
|
Value::BigInt(Some(int)) => {
|
||||||
|
Ok(Self(int.try_into().map_err(|_| sea_query::ValueTypeErr)?))
|
||||||
|
}
|
||||||
|
Value::TinyUnsigned(Some(int)) => {
|
||||||
|
Ok(Self(int.try_into().map_err(|_| sea_query::ValueTypeErr)?))
|
||||||
|
}
|
||||||
|
Value::SmallUnsigned(Some(int)) => {
|
||||||
|
Ok(Self(int.try_into().map_err(|_| sea_query::ValueTypeErr)?))
|
||||||
|
}
|
||||||
|
Value::Unsigned(Some(int)) => {
|
||||||
|
Ok(Self(int.try_into().map_err(|_| sea_query::ValueTypeErr)?))
|
||||||
|
}
|
||||||
|
Value::BigUnsigned(Some(int)) => {
|
||||||
|
Ok(Self(int.try_into().map_err(|_| sea_query::ValueTypeErr)?))
|
||||||
|
}
|
||||||
|
_ => Err(sea_query::ValueTypeErr),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn type_name() -> String {
|
||||||
|
stringify!($name).into()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn array_type() -> sea_query::ArrayType {
|
||||||
|
sea_query::ArrayType::Int
|
||||||
|
}
|
||||||
|
|
||||||
|
fn column_type() -> sea_query::ColumnType {
|
||||||
|
sea_query::ColumnType::Integer(None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl sea_orm::TryFromU64 for $name {
|
||||||
|
fn try_from_u64(n: u64) -> Result<Self, DbErr> {
|
||||||
|
Ok(Self(n.try_into().map_err(|_| {
|
||||||
|
DbErr::ConvertFromU64(concat!(
|
||||||
|
"error converting ",
|
||||||
|
stringify!($name),
|
||||||
|
" to u64"
|
||||||
|
))
|
||||||
|
})?))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl sea_query::Nullable for $name {
|
||||||
|
fn null() -> Value {
|
||||||
|
Value::Int(None)
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -400,6 +513,7 @@ id_type!(UserId);
|
||||||
id_type!(RoomId);
|
id_type!(RoomId);
|
||||||
id_type!(RoomParticipantId);
|
id_type!(RoomParticipantId);
|
||||||
id_type!(ProjectId);
|
id_type!(ProjectId);
|
||||||
|
id_type!(ProjectCollaboratorId);
|
||||||
id_type!(WorktreeId);
|
id_type!(WorktreeId);
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -412,17 +526,18 @@ mod test {
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use rand::prelude::*;
|
use rand::prelude::*;
|
||||||
|
use sea_orm::ConnectionTrait;
|
||||||
use sqlx::migrate::MigrateDatabase;
|
use sqlx::migrate::MigrateDatabase;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
pub struct TestDb {
|
pub struct TestDb {
|
||||||
pub db: Option<Arc<Database>>,
|
pub db: Option<Arc<Database>>,
|
||||||
|
pub connection: Option<sqlx::AnyConnection>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TestDb {
|
impl TestDb {
|
||||||
pub fn sqlite(background: Arc<Background>) -> Self {
|
pub fn sqlite(background: Arc<Background>) -> Self {
|
||||||
let mut rng = StdRng::from_entropy();
|
let url = format!("sqlite::memory:");
|
||||||
let url = format!("sqlite://file:zed-test-{}?mode=memory", rng.gen::<u128>());
|
|
||||||
let runtime = tokio::runtime::Builder::new_current_thread()
|
let runtime = tokio::runtime::Builder::new_current_thread()
|
||||||
.enable_io()
|
.enable_io()
|
||||||
.enable_time()
|
.enable_time()
|
||||||
|
@ -431,8 +546,17 @@ mod test {
|
||||||
|
|
||||||
let mut db = runtime.block_on(async {
|
let mut db = runtime.block_on(async {
|
||||||
let db = Database::new(&url, 5).await.unwrap();
|
let db = Database::new(&url, 5).await.unwrap();
|
||||||
let migrations_path = concat!(env!("CARGO_MANIFEST_DIR"), "/migrations.sqlite");
|
let sql = include_str!(concat!(
|
||||||
db.migrate(migrations_path.as_ref(), false).await.unwrap();
|
env!("CARGO_MANIFEST_DIR"),
|
||||||
|
"/migrations.sqlite/20221109000000_test_schema.sql"
|
||||||
|
));
|
||||||
|
db.pool
|
||||||
|
.execute(sea_orm::Statement::from_string(
|
||||||
|
db.pool.get_database_backend(),
|
||||||
|
sql.into(),
|
||||||
|
))
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
db
|
db
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -441,6 +565,7 @@ mod test {
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
db: Some(Arc::new(db)),
|
db: Some(Arc::new(db)),
|
||||||
|
connection: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -476,6 +601,7 @@ mod test {
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
db: Some(Arc::new(db)),
|
db: Some(Arc::new(db)),
|
||||||
|
connection: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
|
use super::{ProjectId, RoomId, UserId};
|
||||||
use sea_orm::entity::prelude::*;
|
use sea_orm::entity::prelude::*;
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]
|
#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]
|
||||||
#[sea_orm(table_name = "projects")]
|
#[sea_orm(table_name = "projects")]
|
||||||
pub struct Model {
|
pub struct Model {
|
||||||
#[sea_orm(primary_key)]
|
#[sea_orm(primary_key)]
|
||||||
pub id: i32,
|
pub id: ProjectId,
|
||||||
pub room_id: i32,
|
pub room_id: RoomId,
|
||||||
pub host_user_id: i32,
|
pub host_user_id: UserId,
|
||||||
pub host_connection_id: i32,
|
pub host_connection_id: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
|
use super::{ProjectCollaboratorId, ProjectId, UserId};
|
||||||
use sea_orm::entity::prelude::*;
|
use sea_orm::entity::prelude::*;
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]
|
#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]
|
||||||
#[sea_orm(table_name = "project_collaborators")]
|
#[sea_orm(table_name = "project_collaborators")]
|
||||||
pub struct Model {
|
pub struct Model {
|
||||||
#[sea_orm(primary_key)]
|
#[sea_orm(primary_key)]
|
||||||
pub id: i32,
|
pub id: ProjectCollaboratorId,
|
||||||
pub project_id: i32,
|
pub project_id: ProjectId,
|
||||||
pub connection_id: i32,
|
pub connection_id: i32,
|
||||||
pub user_id: i32,
|
pub user_id: UserId,
|
||||||
pub replica_id: i32,
|
pub replica_id: i32,
|
||||||
pub is_host: bool,
|
pub is_host: bool,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
|
use super::RoomId;
|
||||||
use sea_orm::entity::prelude::*;
|
use sea_orm::entity::prelude::*;
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]
|
#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]
|
||||||
#[sea_orm(table_name = "room_participants")]
|
#[sea_orm(table_name = "room_participants")]
|
||||||
pub struct Model {
|
pub struct Model {
|
||||||
#[sea_orm(primary_key)]
|
#[sea_orm(primary_key)]
|
||||||
pub id: i32,
|
pub id: RoomId,
|
||||||
pub live_kit_room: String,
|
pub live_kit_room: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,17 +1,18 @@
|
||||||
|
use super::{ProjectId, RoomId, RoomParticipantId, UserId};
|
||||||
use sea_orm::entity::prelude::*;
|
use sea_orm::entity::prelude::*;
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]
|
#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]
|
||||||
#[sea_orm(table_name = "room_participants")]
|
#[sea_orm(table_name = "room_participants")]
|
||||||
pub struct Model {
|
pub struct Model {
|
||||||
#[sea_orm(primary_key)]
|
#[sea_orm(primary_key)]
|
||||||
pub id: i32,
|
pub id: RoomParticipantId,
|
||||||
pub room_id: i32,
|
pub room_id: RoomId,
|
||||||
pub user_id: i32,
|
pub user_id: UserId,
|
||||||
pub answering_connection_id: Option<i32>,
|
pub answering_connection_id: Option<i32>,
|
||||||
pub location_kind: Option<i32>,
|
pub location_kind: Option<i32>,
|
||||||
pub location_project_id: Option<i32>,
|
pub location_project_id: Option<ProjectId>,
|
||||||
pub initial_project_id: Option<i32>,
|
pub initial_project_id: Option<ProjectId>,
|
||||||
pub calling_user_id: i32,
|
pub calling_user_id: UserId,
|
||||||
pub calling_connection_id: i32,
|
pub calling_connection_id: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,7 +1,7 @@
|
||||||
use super::UserId;
|
use super::UserId;
|
||||||
use sea_orm::entity::prelude::*;
|
use sea_orm::entity::prelude::*;
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]
|
#[derive(Clone, Debug, Default, PartialEq, Eq, DeriveEntityModel)]
|
||||||
#[sea_orm(table_name = "users")]
|
#[sea_orm(table_name = "users")]
|
||||||
pub struct Model {
|
pub struct Model {
|
||||||
#[sea_orm(primary_key)]
|
#[sea_orm(primary_key)]
|
||||||
|
@ -13,6 +13,7 @@ pub struct Model {
|
||||||
pub invite_code: Option<String>,
|
pub invite_code: Option<String>,
|
||||||
pub invite_count: i32,
|
pub invite_count: i32,
|
||||||
pub connected_once: bool,
|
pub connected_once: bool,
|
||||||
|
pub metrics_id: Uuid,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
use sea_orm::entity::prelude::*;
|
use sea_orm::entity::prelude::*;
|
||||||
|
|
||||||
|
use super::ProjectId;
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]
|
#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]
|
||||||
#[sea_orm(table_name = "worktrees")]
|
#[sea_orm(table_name = "worktrees")]
|
||||||
pub struct Model {
|
pub struct Model {
|
||||||
#[sea_orm(primary_key)]
|
#[sea_orm(primary_key)]
|
||||||
pub id: i32,
|
pub id: i32,
|
||||||
#[sea_orm(primary_key)]
|
#[sea_orm(primary_key)]
|
||||||
pub project_id: i32,
|
pub project_id: ProjectId,
|
||||||
pub abs_path: String,
|
pub abs_path: String,
|
||||||
pub root_name: String,
|
pub root_name: String,
|
||||||
pub visible: bool,
|
pub visible: bool,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue