Merge pull request 'database-setup' (#3) from database-setup into master
Reviewed-on: finwise/finewise#3
This commit was merged in pull request #3.
This commit is contained in:
6901
Cargo.lock
generated
Normal file
6901
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
15
Cargo.toml
Normal file
15
Cargo.toml
Normal file
@@ -0,0 +1,15 @@
|
||||
[workspace]
|
||||
members = ["crates/*", "src-tauri"]
|
||||
resolver = "2"
|
||||
|
||||
[workspace.package]
|
||||
edition = "2021"
|
||||
rust-version = "1.85.0"
|
||||
|
||||
[workspace.dependencies]
|
||||
sea-orm = { version = "^2.0.0-rc", features = ["sqlx-sqlite", "runtime-tokio-native-tls"] }
|
||||
sea-orm-migration = { version = "^2.0.0-rc", features = ["runtime-tokio-native-tls", "sqlx-sqlite"] }
|
||||
tokio = { version = "1", features = ["macros", "rt", "rt-multi-thread"] }
|
||||
chrono = { version = "0.4.43", features = ["serde"] }
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
18
crates/migration/Cargo.toml
Normal file
18
crates/migration/Cargo.toml
Normal file
@@ -0,0 +1,18 @@
|
||||
[package]
|
||||
name = "migration"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
rust-version = "1.85.0"
|
||||
publish = false
|
||||
|
||||
[lib]
|
||||
name = "migration"
|
||||
path = "src/lib.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "migration-cli"
|
||||
path = "src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
tokio = { workspace = true }
|
||||
sea-orm-migration = { workspace = true }
|
||||
41
crates/migration/README.md
Normal file
41
crates/migration/README.md
Normal file
@@ -0,0 +1,41 @@
|
||||
# Running Migrator CLI
|
||||
|
||||
- Generate a new migration file
|
||||
```sh
|
||||
cargo run -- generate MIGRATION_NAME
|
||||
```
|
||||
- Apply all pending migrations
|
||||
```sh
|
||||
cargo run
|
||||
```
|
||||
```sh
|
||||
cargo run -- up
|
||||
```
|
||||
- Apply first 10 pending migrations
|
||||
```sh
|
||||
cargo run -- up -n 10
|
||||
```
|
||||
- Rollback last applied migrations
|
||||
```sh
|
||||
cargo run -- down
|
||||
```
|
||||
- Rollback last 10 applied migrations
|
||||
```sh
|
||||
cargo run -- down -n 10
|
||||
```
|
||||
- Drop all tables from the database, then reapply all migrations
|
||||
```sh
|
||||
cargo run -- fresh
|
||||
```
|
||||
- Rollback all applied migrations, then reapply all migrations
|
||||
```sh
|
||||
cargo run -- refresh
|
||||
```
|
||||
- Rollback all applied migrations
|
||||
```sh
|
||||
cargo run -- reset
|
||||
```
|
||||
- Check the status of all migrations
|
||||
```sh
|
||||
cargo run -- status
|
||||
```
|
||||
30
crates/migration/src/lib.rs
Normal file
30
crates/migration/src/lib.rs
Normal file
@@ -0,0 +1,30 @@
|
||||
pub use sea_orm_migration::prelude::*;
|
||||
|
||||
mod m20250214_000001_create_accounts;
|
||||
mod m20250214_000002_create_settings_and_exchange_rates;
|
||||
mod m20250214_000003_create_goals_and_tags;
|
||||
mod m20250214_000004_create_scheduled_transactions;
|
||||
mod m20250214_000005_create_transactions;
|
||||
mod m20250214_000006_create_reconciliations_and_transfers;
|
||||
mod m20250214_000007_create_transaction_tags;
|
||||
mod m20250214_000008_create_goal_rules_and_progress;
|
||||
mod m20250214_000009_create_scheduled_instances;
|
||||
|
||||
pub struct Migrator;
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigratorTrait for Migrator {
|
||||
fn migrations() -> Vec<Box<dyn MigrationTrait>> {
|
||||
vec![
|
||||
Box::new(m20250214_000001_create_accounts::Migration),
|
||||
Box::new(m20250214_000002_create_settings_and_exchange_rates::Migration),
|
||||
Box::new(m20250214_000003_create_goals_and_tags::Migration),
|
||||
Box::new(m20250214_000004_create_scheduled_transactions::Migration),
|
||||
Box::new(m20250214_000005_create_transactions::Migration),
|
||||
Box::new(m20250214_000006_create_reconciliations_and_transfers::Migration),
|
||||
Box::new(m20250214_000007_create_transaction_tags::Migration),
|
||||
Box::new(m20250214_000008_create_goal_rules_and_progress::Migration),
|
||||
Box::new(m20250214_000009_create_scheduled_instances::Migration),
|
||||
]
|
||||
}
|
||||
}
|
||||
65
crates/migration/src/m20250214_000001_create_accounts.rs
Normal file
65
crates/migration/src/m20250214_000001_create_accounts.rs
Normal file
@@ -0,0 +1,65 @@
|
||||
use sea_orm_migration::{prelude::*, schema::*};
|
||||
|
||||
#[derive(DeriveMigrationName)]
|
||||
pub struct Migration;
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigrationTrait for Migration {
|
||||
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.create_table(
|
||||
Table::create()
|
||||
.table(Accounts::Table)
|
||||
.if_not_exists()
|
||||
.col(string(Accounts::Id).primary_key())
|
||||
.col(string(Accounts::Name))
|
||||
.col(string(Accounts::AccountType))
|
||||
.col(string(Accounts::Currency))
|
||||
.col(string(Accounts::InitialBalance))
|
||||
.col(string(Accounts::CurrentBalance))
|
||||
.col(string_null(Accounts::Color))
|
||||
.col(string_null(Accounts::Icon))
|
||||
.col(integer(Accounts::SortOrder))
|
||||
.col(boolean(Accounts::IsActive))
|
||||
.col(boolean(Accounts::IsArchived))
|
||||
.col(boolean(Accounts::IncludeInNetWorth))
|
||||
.col(boolean(Accounts::ShowInCombinedView))
|
||||
.col(date_time(Accounts::CreatedAt))
|
||||
.col(date_time(Accounts::UpdatedAt))
|
||||
.col(integer(Accounts::Version))
|
||||
.col(string_null(Accounts::DeviceId))
|
||||
.col(boolean(Accounts::IsDeleted))
|
||||
.to_owned(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.drop_table(Table::drop().table(Accounts::Table).to_owned())
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(DeriveIden)]
|
||||
enum Accounts {
|
||||
Table,
|
||||
Id,
|
||||
Name,
|
||||
AccountType,
|
||||
Currency,
|
||||
InitialBalance,
|
||||
CurrentBalance,
|
||||
Color,
|
||||
Icon,
|
||||
SortOrder,
|
||||
IsActive,
|
||||
IsArchived,
|
||||
IncludeInNetWorth,
|
||||
ShowInCombinedView,
|
||||
CreatedAt,
|
||||
UpdatedAt,
|
||||
Version,
|
||||
DeviceId,
|
||||
IsDeleted,
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
use sea_orm_migration::{prelude::*, schema::*};
|
||||
|
||||
#[derive(DeriveMigrationName)]
|
||||
pub struct Migration;
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigrationTrait for Migration {
|
||||
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
// Create settings table
|
||||
manager
|
||||
.create_table(
|
||||
Table::create()
|
||||
.table(Settings::Table)
|
||||
.if_not_exists()
|
||||
.col(string(Settings::Key).primary_key())
|
||||
.col(string_null(Settings::Value))
|
||||
.col(date_time(Settings::UpdatedAt))
|
||||
.to_owned(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
// Create exchange_rates table
|
||||
manager
|
||||
.create_table(
|
||||
Table::create()
|
||||
.table(ExchangeRates::Table)
|
||||
.if_not_exists()
|
||||
.col(string(ExchangeRates::FromCurrency))
|
||||
.col(string(ExchangeRates::ToCurrency))
|
||||
.col(string(ExchangeRates::Date))
|
||||
.col(string(ExchangeRates::Rate))
|
||||
.col(string_null(ExchangeRates::Source))
|
||||
.col(date_time_null(ExchangeRates::FetchedAt))
|
||||
.primary_key(
|
||||
Index::create()
|
||||
.col(ExchangeRates::FromCurrency)
|
||||
.col(ExchangeRates::ToCurrency)
|
||||
.col(ExchangeRates::Date),
|
||||
)
|
||||
.to_owned(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.drop_table(Table::drop().table(ExchangeRates::Table).to_owned())
|
||||
.await?;
|
||||
manager
|
||||
.drop_table(Table::drop().table(Settings::Table).to_owned())
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(DeriveIden)]
|
||||
enum Settings {
|
||||
Table,
|
||||
Key,
|
||||
Value,
|
||||
UpdatedAt,
|
||||
}
|
||||
|
||||
#[derive(DeriveIden)]
|
||||
enum ExchangeRates {
|
||||
Table,
|
||||
FromCurrency,
|
||||
ToCurrency,
|
||||
Date,
|
||||
Rate,
|
||||
Source,
|
||||
FetchedAt,
|
||||
}
|
||||
132
crates/migration/src/m20250214_000003_create_goals_and_tags.rs
Normal file
132
crates/migration/src/m20250214_000003_create_goals_and_tags.rs
Normal file
@@ -0,0 +1,132 @@
|
||||
use sea_orm_migration::{prelude::*, schema::*};
|
||||
|
||||
#[derive(DeriveMigrationName)]
|
||||
pub struct Migration;
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigrationTrait for Migration {
|
||||
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
// Create goals table
|
||||
manager
|
||||
.create_table(
|
||||
Table::create()
|
||||
.table(Goals::Table)
|
||||
.if_not_exists()
|
||||
.col(string(Goals::Id).primary_key())
|
||||
.col(string(Goals::Name))
|
||||
.col(string_null(Goals::Description))
|
||||
.col(string(Goals::TargetAmount))
|
||||
.col(string(Goals::CurrentAmount))
|
||||
.col(string(Goals::Currency))
|
||||
.col(string(Goals::GoalType))
|
||||
.col(string_null(Goals::TargetDate))
|
||||
.col(boolean(Goals::IsRecurring))
|
||||
.col(string_null(Goals::RecurrencePeriod))
|
||||
.col(string_null(Goals::LinkedAccountId))
|
||||
.col(string_null(Goals::Color))
|
||||
.col(string_null(Goals::Icon))
|
||||
.col(boolean(Goals::IsActive))
|
||||
.col(boolean(Goals::IsAchieved))
|
||||
.col(date_time_null(Goals::AchievedAt))
|
||||
.col(string_null(Goals::LastResetDate))
|
||||
.col(date_time(Goals::CreatedAt))
|
||||
.col(date_time(Goals::UpdatedAt))
|
||||
.col(integer(Goals::Version))
|
||||
.col(string_null(Goals::DeviceId))
|
||||
.col(boolean(Goals::IsDeleted))
|
||||
.foreign_key(
|
||||
ForeignKey::create()
|
||||
.name("fk_goals_account")
|
||||
.from(Goals::Table, Goals::LinkedAccountId)
|
||||
.to(Accounts::Table, Accounts::Id)
|
||||
.on_delete(ForeignKeyAction::SetNull)
|
||||
.on_update(ForeignKeyAction::Cascade),
|
||||
)
|
||||
.to_owned(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
// Create tags table
|
||||
manager
|
||||
.create_table(
|
||||
Table::create()
|
||||
.table(Tags::Table)
|
||||
.if_not_exists()
|
||||
.col(string(Tags::Id).primary_key())
|
||||
.col(string(Tags::Name))
|
||||
.col(string(Tags::Color))
|
||||
.col(string_null(Tags::Icon))
|
||||
.col(string_null(Tags::BudgetAmount))
|
||||
.col(string_null(Tags::BudgetPeriod))
|
||||
.col(boolean(Tags::IsSystem))
|
||||
.col(integer(Tags::SortOrder))
|
||||
.col(date_time(Tags::CreatedAt))
|
||||
.col(date_time(Tags::UpdatedAt))
|
||||
.col(integer(Tags::Version))
|
||||
.col(string_null(Tags::DeviceId))
|
||||
.col(boolean(Tags::IsDeleted))
|
||||
.to_owned(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.drop_table(Table::drop().table(Tags::Table).to_owned())
|
||||
.await?;
|
||||
manager
|
||||
.drop_table(Table::drop().table(Goals::Table).to_owned())
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(DeriveIden)]
|
||||
enum Goals {
|
||||
Table,
|
||||
Id,
|
||||
Name,
|
||||
Description,
|
||||
TargetAmount,
|
||||
CurrentAmount,
|
||||
Currency,
|
||||
GoalType,
|
||||
TargetDate,
|
||||
IsRecurring,
|
||||
RecurrencePeriod,
|
||||
LinkedAccountId,
|
||||
Color,
|
||||
Icon,
|
||||
IsActive,
|
||||
IsAchieved,
|
||||
AchievedAt,
|
||||
LastResetDate,
|
||||
CreatedAt,
|
||||
UpdatedAt,
|
||||
Version,
|
||||
DeviceId,
|
||||
IsDeleted,
|
||||
}
|
||||
|
||||
#[derive(DeriveIden)]
|
||||
enum Accounts {
|
||||
Table,
|
||||
Id,
|
||||
}
|
||||
|
||||
#[derive(DeriveIden)]
|
||||
enum Tags {
|
||||
Table,
|
||||
Id,
|
||||
Name,
|
||||
Color,
|
||||
Icon,
|
||||
BudgetAmount,
|
||||
BudgetPeriod,
|
||||
IsSystem,
|
||||
SortOrder,
|
||||
CreatedAt,
|
||||
UpdatedAt,
|
||||
Version,
|
||||
DeviceId,
|
||||
IsDeleted,
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
use sea_orm_migration::{prelude::*, schema::*};
|
||||
|
||||
#[derive(DeriveMigrationName)]
|
||||
pub struct Migration;
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigrationTrait for Migration {
|
||||
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.create_table(
|
||||
Table::create()
|
||||
.table(ScheduledTransactions::Table)
|
||||
.if_not_exists()
|
||||
.col(string(ScheduledTransactions::Id).primary_key())
|
||||
.col(string(ScheduledTransactions::AccountId))
|
||||
.col(string(ScheduledTransactions::ScheduleType))
|
||||
.col(integer(ScheduledTransactions::Frequency))
|
||||
.col(string_null(ScheduledTransactions::DaysOfWeek))
|
||||
.col(integer_null(ScheduledTransactions::DayOfMonth))
|
||||
.col(integer_null(ScheduledTransactions::MonthOfYear))
|
||||
.col(string(ScheduledTransactions::ExecutionTime))
|
||||
.col(string_null(ScheduledTransactions::Timezone))
|
||||
.col(string(ScheduledTransactions::StartDate))
|
||||
.col(string_null(ScheduledTransactions::EndDate))
|
||||
.col(integer_null(ScheduledTransactions::OccurrenceCount))
|
||||
.col(integer(ScheduledTransactions::CurrentOccurrence))
|
||||
.col(string(ScheduledTransactions::TransactionType))
|
||||
.col(string(ScheduledTransactions::GrossAmount))
|
||||
.col(string(ScheduledTransactions::TaxAmount))
|
||||
.col(string(ScheduledTransactions::NetAmount))
|
||||
.col(string(ScheduledTransactions::Currency))
|
||||
.col(string_null(ScheduledTransactions::Description))
|
||||
.col(string_null(ScheduledTransactions::Merchant))
|
||||
.col(string_null(ScheduledTransactions::Notes))
|
||||
.col(string_null(ScheduledTransactions::TagIds))
|
||||
.col(boolean(ScheduledTransactions::IsActive))
|
||||
.col(string_null(ScheduledTransactions::LastGeneratedDate))
|
||||
.col(date_time_null(ScheduledTransactions::NextExecutionDatetime))
|
||||
.col(date_time(ScheduledTransactions::CreatedAt))
|
||||
.col(date_time(ScheduledTransactions::UpdatedAt))
|
||||
.col(integer(ScheduledTransactions::Version))
|
||||
.col(string_null(ScheduledTransactions::DeviceId))
|
||||
.col(boolean(ScheduledTransactions::IsDeleted))
|
||||
.foreign_key(
|
||||
ForeignKey::create()
|
||||
.name("fk_scheduled_transactions_account")
|
||||
.from(ScheduledTransactions::Table, ScheduledTransactions::AccountId)
|
||||
.to(Accounts::Table, Accounts::Id)
|
||||
.on_delete(ForeignKeyAction::Cascade)
|
||||
.on_update(ForeignKeyAction::Cascade),
|
||||
)
|
||||
.to_owned(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.drop_table(Table::drop().table(ScheduledTransactions::Table).to_owned())
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(DeriveIden)]
|
||||
enum ScheduledTransactions {
|
||||
Table,
|
||||
Id,
|
||||
AccountId,
|
||||
ScheduleType,
|
||||
Frequency,
|
||||
DaysOfWeek,
|
||||
DayOfMonth,
|
||||
MonthOfYear,
|
||||
ExecutionTime,
|
||||
Timezone,
|
||||
StartDate,
|
||||
EndDate,
|
||||
OccurrenceCount,
|
||||
CurrentOccurrence,
|
||||
TransactionType,
|
||||
GrossAmount,
|
||||
TaxAmount,
|
||||
NetAmount,
|
||||
Currency,
|
||||
Description,
|
||||
Merchant,
|
||||
Notes,
|
||||
TagIds,
|
||||
IsActive,
|
||||
LastGeneratedDate,
|
||||
NextExecutionDatetime,
|
||||
CreatedAt,
|
||||
UpdatedAt,
|
||||
Version,
|
||||
DeviceId,
|
||||
IsDeleted,
|
||||
}
|
||||
|
||||
#[derive(DeriveIden)]
|
||||
enum Accounts {
|
||||
Table,
|
||||
Id,
|
||||
}
|
||||
109
crates/migration/src/m20250214_000005_create_transactions.rs
Normal file
109
crates/migration/src/m20250214_000005_create_transactions.rs
Normal file
@@ -0,0 +1,109 @@
|
||||
use sea_orm_migration::{prelude::*, schema::*};
|
||||
|
||||
#[derive(DeriveMigrationName)]
|
||||
pub struct Migration;
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigrationTrait for Migration {
|
||||
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.create_table(
|
||||
Table::create()
|
||||
.table(Transactions::Table)
|
||||
.if_not_exists()
|
||||
.col(string(Transactions::Id).primary_key())
|
||||
.col(string(Transactions::AccountId))
|
||||
.col(string(Transactions::TransactionType))
|
||||
.col(string(Transactions::GrossAmount))
|
||||
.col(string(Transactions::TaxAmount))
|
||||
.col(string(Transactions::NetAmount))
|
||||
.col(string_null(Transactions::TaxRate))
|
||||
.col(string(Transactions::Currency))
|
||||
.col(string(Transactions::Description))
|
||||
.col(string_null(Transactions::Merchant))
|
||||
.col(string_null(Transactions::Notes))
|
||||
.col(string_null(Transactions::ReceiptPaths))
|
||||
.col(string_null(Transactions::ReceiptOcrData))
|
||||
.col(string_null(Transactions::TransferId))
|
||||
.col(string_null(Transactions::RelatedTransactionId))
|
||||
.col(string_null(Transactions::ScheduleId))
|
||||
.col(boolean(Transactions::IsScheduledInstance))
|
||||
.col(boolean(Transactions::IsAutoInserted))
|
||||
.col(boolean(Transactions::NeedsReview))
|
||||
.col(string(Transactions::TransactionDate))
|
||||
.col(date_time(Transactions::CreatedAt))
|
||||
.col(date_time(Transactions::UpdatedAt))
|
||||
.col(integer(Transactions::Version))
|
||||
.col(string_null(Transactions::DeviceId))
|
||||
.col(boolean(Transactions::IsDeleted))
|
||||
.col(string(Transactions::SyncStatus))
|
||||
.foreign_key(
|
||||
ForeignKey::create()
|
||||
.name("fk_transactions_account")
|
||||
.from(Transactions::Table, Transactions::AccountId)
|
||||
.to(Accounts::Table, Accounts::Id)
|
||||
.on_delete(ForeignKeyAction::Cascade)
|
||||
.on_update(ForeignKeyAction::Cascade),
|
||||
)
|
||||
.foreign_key(
|
||||
ForeignKey::create()
|
||||
.name("fk_transactions_schedule")
|
||||
.from(Transactions::Table, Transactions::ScheduleId)
|
||||
.to(ScheduledTransactions::Table, ScheduledTransactions::Id)
|
||||
.on_delete(ForeignKeyAction::SetNull)
|
||||
.on_update(ForeignKeyAction::Cascade),
|
||||
)
|
||||
.to_owned(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.drop_table(Table::drop().table(Transactions::Table).to_owned())
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(DeriveIden)]
|
||||
enum Transactions {
|
||||
Table,
|
||||
Id,
|
||||
AccountId,
|
||||
TransactionType,
|
||||
GrossAmount,
|
||||
TaxAmount,
|
||||
NetAmount,
|
||||
TaxRate,
|
||||
Currency,
|
||||
Description,
|
||||
Merchant,
|
||||
Notes,
|
||||
ReceiptPaths,
|
||||
ReceiptOcrData,
|
||||
TransferId,
|
||||
RelatedTransactionId,
|
||||
ScheduleId,
|
||||
IsScheduledInstance,
|
||||
IsAutoInserted,
|
||||
NeedsReview,
|
||||
TransactionDate,
|
||||
CreatedAt,
|
||||
UpdatedAt,
|
||||
Version,
|
||||
DeviceId,
|
||||
IsDeleted,
|
||||
SyncStatus,
|
||||
}
|
||||
|
||||
#[derive(DeriveIden)]
|
||||
enum Accounts {
|
||||
Table,
|
||||
Id,
|
||||
}
|
||||
|
||||
#[derive(DeriveIden)]
|
||||
enum ScheduledTransactions {
|
||||
Table,
|
||||
Id,
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
use sea_orm_migration::{prelude::*, schema::*};
|
||||
|
||||
#[derive(DeriveMigrationName)]
|
||||
pub struct Migration;
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigrationTrait for Migration {
|
||||
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
// Create reconciliations table
|
||||
manager
|
||||
.create_table(
|
||||
Table::create()
|
||||
.table(Reconciliations::Table)
|
||||
.if_not_exists()
|
||||
.col(string(Reconciliations::Id).primary_key())
|
||||
.col(string(Reconciliations::AccountId))
|
||||
.col(string(Reconciliations::StatementDate))
|
||||
.col(string(Reconciliations::StatementBalance))
|
||||
.col(string(Reconciliations::AppBalance))
|
||||
.col(string(Reconciliations::Difference))
|
||||
.col(string(Reconciliations::Status))
|
||||
.col(string_null(Reconciliations::Notes))
|
||||
.col(date_time(Reconciliations::CreatedAt))
|
||||
.col(date_time_null(Reconciliations::ResolvedAt))
|
||||
.col(integer(Reconciliations::Version))
|
||||
.col(string_null(Reconciliations::DeviceId))
|
||||
.foreign_key(
|
||||
ForeignKey::create()
|
||||
.name("fk_reconciliations_account")
|
||||
.from(Reconciliations::Table, Reconciliations::AccountId)
|
||||
.to(Accounts::Table, Accounts::Id)
|
||||
.on_delete(ForeignKeyAction::Cascade)
|
||||
.on_update(ForeignKeyAction::Cascade),
|
||||
)
|
||||
.to_owned(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
// Create transfers table
|
||||
manager
|
||||
.create_table(
|
||||
Table::create()
|
||||
.table(Transfers::Table)
|
||||
.if_not_exists()
|
||||
.col(string(Transfers::Id).primary_key())
|
||||
.col(string(Transfers::FromAccountId))
|
||||
.col(string(Transfers::ToAccountId))
|
||||
.col(string_null(Transfers::FromTransactionId))
|
||||
.col(string_null(Transfers::ToTransactionId))
|
||||
.col(string(Transfers::FromAmount))
|
||||
.col(string(Transfers::ToAmount))
|
||||
.col(string_null(Transfers::ExchangeRate))
|
||||
.col(string_null(Transfers::ExchangeRateSource))
|
||||
.col(string(Transfers::Fees))
|
||||
.col(string_null(Transfers::Description))
|
||||
.col(string(Transfers::TransferDate))
|
||||
.col(date_time(Transfers::CreatedAt))
|
||||
.col(integer(Transfers::Version))
|
||||
.col(string_null(Transfers::DeviceId))
|
||||
.col(boolean(Transfers::IsDeleted))
|
||||
.to_owned(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.drop_table(Table::drop().table(Transfers::Table).to_owned())
|
||||
.await?;
|
||||
manager
|
||||
.drop_table(Table::drop().table(Reconciliations::Table).to_owned())
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(DeriveIden)]
|
||||
enum Reconciliations {
|
||||
Table,
|
||||
Id,
|
||||
AccountId,
|
||||
StatementDate,
|
||||
StatementBalance,
|
||||
AppBalance,
|
||||
Difference,
|
||||
Status,
|
||||
Notes,
|
||||
CreatedAt,
|
||||
ResolvedAt,
|
||||
Version,
|
||||
DeviceId,
|
||||
}
|
||||
|
||||
#[derive(DeriveIden)]
|
||||
enum Transfers {
|
||||
Table,
|
||||
Id,
|
||||
FromAccountId,
|
||||
ToAccountId,
|
||||
FromTransactionId,
|
||||
ToTransactionId,
|
||||
FromAmount,
|
||||
ToAmount,
|
||||
ExchangeRate,
|
||||
ExchangeRateSource,
|
||||
Fees,
|
||||
Description,
|
||||
TransferDate,
|
||||
CreatedAt,
|
||||
Version,
|
||||
DeviceId,
|
||||
IsDeleted,
|
||||
}
|
||||
|
||||
#[derive(DeriveIden)]
|
||||
enum Accounts {
|
||||
Table,
|
||||
Id,
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
use sea_orm_migration::{prelude::*, schema::*};
|
||||
|
||||
#[derive(DeriveMigrationName)]
|
||||
pub struct Migration;
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigrationTrait for Migration {
|
||||
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.create_table(
|
||||
Table::create()
|
||||
.table(TransactionTags::Table)
|
||||
.if_not_exists()
|
||||
.col(string(TransactionTags::TransactionId))
|
||||
.col(string(TransactionTags::TagId))
|
||||
.primary_key(
|
||||
Index::create()
|
||||
.col(TransactionTags::TransactionId)
|
||||
.col(TransactionTags::TagId),
|
||||
)
|
||||
.foreign_key(
|
||||
ForeignKey::create()
|
||||
.name("fk_transaction_tags_transaction")
|
||||
.from(TransactionTags::Table, TransactionTags::TransactionId)
|
||||
.to(Transactions::Table, Transactions::Id)
|
||||
.on_delete(ForeignKeyAction::Cascade)
|
||||
.on_update(ForeignKeyAction::Cascade),
|
||||
)
|
||||
.foreign_key(
|
||||
ForeignKey::create()
|
||||
.name("fk_transaction_tags_tag")
|
||||
.from(TransactionTags::Table, TransactionTags::TagId)
|
||||
.to(Tags::Table, Tags::Id)
|
||||
.on_delete(ForeignKeyAction::Cascade)
|
||||
.on_update(ForeignKeyAction::Cascade),
|
||||
)
|
||||
.to_owned(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.drop_table(Table::drop().table(TransactionTags::Table).to_owned())
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(DeriveIden)]
|
||||
enum TransactionTags {
|
||||
Table,
|
||||
TransactionId,
|
||||
TagId,
|
||||
}
|
||||
|
||||
#[derive(DeriveIden)]
|
||||
enum Transactions {
|
||||
Table,
|
||||
Id,
|
||||
}
|
||||
|
||||
#[derive(DeriveIden)]
|
||||
enum Tags {
|
||||
Table,
|
||||
Id,
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
use sea_orm_migration::{prelude::*, schema::*};
|
||||
|
||||
#[derive(DeriveMigrationName)]
|
||||
pub struct Migration;
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigrationTrait for Migration {
|
||||
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
// Create goal_rules table
|
||||
manager
|
||||
.create_table(
|
||||
Table::create()
|
||||
.table(GoalRules::Table)
|
||||
.if_not_exists()
|
||||
.col(string(GoalRules::Id).primary_key())
|
||||
.col(string(GoalRules::GoalId))
|
||||
.col(string(GoalRules::TagIds))
|
||||
.col(string(GoalRules::ContributionType))
|
||||
.col(string_null(GoalRules::Percentage))
|
||||
.col(string_null(GoalRules::FixedAmount))
|
||||
.col(string_null(GoalRules::MaxContributionPerTransaction))
|
||||
.col(string_null(GoalRules::MonthlyCap))
|
||||
.col(boolean(GoalRules::IsActive))
|
||||
.col(date_time(GoalRules::CreatedAt))
|
||||
.col(date_time(GoalRules::UpdatedAt))
|
||||
.col(integer(GoalRules::Version))
|
||||
.col(string_null(GoalRules::DeviceId))
|
||||
.col(boolean(GoalRules::IsDeleted))
|
||||
.foreign_key(
|
||||
ForeignKey::create()
|
||||
.name("fk_goal_rules_goal")
|
||||
.from(GoalRules::Table, GoalRules::GoalId)
|
||||
.to(Goals::Table, Goals::Id)
|
||||
.on_delete(ForeignKeyAction::Cascade)
|
||||
.on_update(ForeignKeyAction::Cascade),
|
||||
)
|
||||
.to_owned(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
// Create goal_progress table
|
||||
manager
|
||||
.create_table(
|
||||
Table::create()
|
||||
.table(GoalProgress::Table)
|
||||
.if_not_exists()
|
||||
.col(string(GoalProgress::Id).primary_key())
|
||||
.col(string(GoalProgress::GoalId))
|
||||
.col(string(GoalProgress::Amount))
|
||||
.col(string_null(GoalProgress::TransactionId))
|
||||
.col(string_null(GoalProgress::Notes))
|
||||
.col(date_time(GoalProgress::RecordedAt))
|
||||
.foreign_key(
|
||||
ForeignKey::create()
|
||||
.name("fk_goal_progress_goal")
|
||||
.from(GoalProgress::Table, GoalProgress::GoalId)
|
||||
.to(Goals::Table, Goals::Id)
|
||||
.on_delete(ForeignKeyAction::Cascade)
|
||||
.on_update(ForeignKeyAction::Cascade),
|
||||
)
|
||||
.foreign_key(
|
||||
ForeignKey::create()
|
||||
.name("fk_goal_progress_transaction")
|
||||
.from(GoalProgress::Table, GoalProgress::TransactionId)
|
||||
.to(Transactions::Table, Transactions::Id)
|
||||
.on_delete(ForeignKeyAction::SetNull)
|
||||
.on_update(ForeignKeyAction::Cascade),
|
||||
)
|
||||
.to_owned(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.drop_table(Table::drop().table(GoalProgress::Table).to_owned())
|
||||
.await?;
|
||||
manager
|
||||
.drop_table(Table::drop().table(GoalRules::Table).to_owned())
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(DeriveIden)]
|
||||
enum GoalRules {
|
||||
Table,
|
||||
Id,
|
||||
GoalId,
|
||||
TagIds,
|
||||
ContributionType,
|
||||
Percentage,
|
||||
FixedAmount,
|
||||
MaxContributionPerTransaction,
|
||||
MonthlyCap,
|
||||
IsActive,
|
||||
CreatedAt,
|
||||
UpdatedAt,
|
||||
Version,
|
||||
DeviceId,
|
||||
IsDeleted,
|
||||
}
|
||||
|
||||
#[derive(DeriveIden)]
|
||||
enum GoalProgress {
|
||||
Table,
|
||||
Id,
|
||||
GoalId,
|
||||
Amount,
|
||||
TransactionId,
|
||||
Notes,
|
||||
RecordedAt,
|
||||
}
|
||||
|
||||
#[derive(DeriveIden)]
|
||||
enum Goals {
|
||||
Table,
|
||||
Id,
|
||||
}
|
||||
|
||||
#[derive(DeriveIden)]
|
||||
enum Transactions {
|
||||
Table,
|
||||
Id,
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
use sea_orm_migration::{prelude::*, schema::*};
|
||||
|
||||
#[derive(DeriveMigrationName)]
|
||||
pub struct Migration;
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigrationTrait for Migration {
|
||||
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.create_table(
|
||||
Table::create()
|
||||
.table(ScheduledInstances::Table)
|
||||
.if_not_exists()
|
||||
.col(string(ScheduledInstances::Id).primary_key())
|
||||
.col(string(ScheduledInstances::ScheduleId))
|
||||
.col(string_null(ScheduledInstances::TransactionId))
|
||||
.col(string(ScheduledInstances::DueDate))
|
||||
.col(boolean(ScheduledInstances::IsGenerated))
|
||||
.col(boolean(ScheduledInstances::IsSkipped))
|
||||
.col(date_time_null(ScheduledInstances::GeneratedAt))
|
||||
.col(boolean(ScheduledInstances::Notified))
|
||||
.col(date_time(ScheduledInstances::CreatedAt))
|
||||
.foreign_key(
|
||||
ForeignKey::create()
|
||||
.name("fk_scheduled_instances_schedule")
|
||||
.from(ScheduledInstances::Table, ScheduledInstances::ScheduleId)
|
||||
.to(ScheduledTransactions::Table, ScheduledTransactions::Id)
|
||||
.on_delete(ForeignKeyAction::Cascade)
|
||||
.on_update(ForeignKeyAction::Cascade),
|
||||
)
|
||||
.foreign_key(
|
||||
ForeignKey::create()
|
||||
.name("fk_scheduled_instances_transaction")
|
||||
.from(ScheduledInstances::Table, ScheduledInstances::TransactionId)
|
||||
.to(Transactions::Table, Transactions::Id)
|
||||
.on_delete(ForeignKeyAction::SetNull)
|
||||
.on_update(ForeignKeyAction::Cascade),
|
||||
)
|
||||
.to_owned(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.drop_table(Table::drop().table(ScheduledInstances::Table).to_owned())
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(DeriveIden)]
|
||||
enum ScheduledInstances {
|
||||
Table,
|
||||
Id,
|
||||
ScheduleId,
|
||||
TransactionId,
|
||||
DueDate,
|
||||
IsGenerated,
|
||||
IsSkipped,
|
||||
GeneratedAt,
|
||||
Notified,
|
||||
CreatedAt,
|
||||
}
|
||||
|
||||
#[derive(DeriveIden)]
|
||||
enum ScheduledTransactions {
|
||||
Table,
|
||||
Id,
|
||||
}
|
||||
|
||||
#[derive(DeriveIden)]
|
||||
enum Transactions {
|
||||
Table,
|
||||
Id,
|
||||
}
|
||||
6
crates/migration/src/main.rs
Normal file
6
crates/migration/src/main.rs
Normal file
@@ -0,0 +1,6 @@
|
||||
use sea_orm_migration::prelude::*;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
cli::run_cli(migration::Migrator).await;
|
||||
}
|
||||
5
justfile
5
justfile
@@ -13,7 +13,10 @@ db-migrate:
|
||||
-u sqlite://temp.db \
|
||||
-o ../src-tauri/src/db/entities \
|
||||
--with-serde both \
|
||||
--date-time-crate chrono
|
||||
--date-time-crate chrono \
|
||||
--with-prelude all-allow-unused-imports \
|
||||
--model-extra-attributes 'allow(dead_code)' \
|
||||
--enum-extra-attributes 'allow(dead_code)'
|
||||
|
||||
rm crates/temp.db
|
||||
|
||||
|
||||
1387
src-tauri/Cargo.lock
generated
1387
src-tauri/Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -4,25 +4,30 @@ version = "0.1.0"
|
||||
description = "A Tauri App"
|
||||
authors = ["you"]
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
rust-version = "1.85.0"
|
||||
|
||||
[lib]
|
||||
# The `_lib` suffix may seem redundant but it is necessary
|
||||
# to make the lib name unique and wouldn't conflict with the bin name.
|
||||
# This seems to be only an issue on Windows, see https://github.com/rust-lang/cargo/issues/8519
|
||||
name = "finwise_lib"
|
||||
crate-type = ["staticlib", "cdylib", "rlib"]
|
||||
|
||||
[[bin]]
|
||||
name = "finwise"
|
||||
path = "src/main.rs"
|
||||
|
||||
[build-dependencies]
|
||||
tauri-build = { version = "2", features = [] }
|
||||
|
||||
[dependencies]
|
||||
tauri = { version = "2", features = [] }
|
||||
tauri-plugin-opener = "2"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
|
||||
serde = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
sea-orm = { workspace = true }
|
||||
chrono = { workspace = true }
|
||||
migration = { path = "../crates/migration" }
|
||||
thiserror = "1"
|
||||
rust_decimal = "1"
|
||||
uuid = { version = "1", features = ["v4"] }
|
||||
|
||||
[profile.dev]
|
||||
incremental = true
|
||||
|
||||
47
src-tauri/src/db/connection.rs
Normal file
47
src-tauri/src/db/connection.rs
Normal file
@@ -0,0 +1,47 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use sea_orm::{Database, DatabaseConnection, DbErr};
|
||||
use tauri::{AppHandle, Manager};
|
||||
|
||||
use super::migrations;
|
||||
|
||||
const DATABASE_PATH: &str = "finance.db";
|
||||
|
||||
pub(super) async fn establish_connection(
|
||||
app_handle: &AppHandle,
|
||||
) -> Result<DatabaseConnection, DbErr> {
|
||||
let app_dir = app_handle
|
||||
.path()
|
||||
.app_data_dir()
|
||||
.expect("Failed to get app data directory");
|
||||
|
||||
// Create directory if it doesn't exist
|
||||
std::fs::create_dir_all(&app_dir).expect("Failed to create app data directory");
|
||||
|
||||
let db_path = app_dir.join(DATABASE_PATH);
|
||||
let url = format!("sqlite://{}?mode=rwc", db_path.display());
|
||||
|
||||
println!("Connecting to database at: {}", db_path.display());
|
||||
|
||||
let db = Database::connect(&url).await?;
|
||||
|
||||
// Enable foreign keys and set pragmas
|
||||
sea_orm::ConnectionTrait::execute_unprepared(
|
||||
&db,
|
||||
"PRAGMA foreign_keys = ON; PRAGMA journal_mode = WAL; PRAGMA synchronous = NORMAL;",
|
||||
)
|
||||
.await?;
|
||||
|
||||
// Run migrations
|
||||
migrations::run_migrations(&db).await?;
|
||||
|
||||
Ok(db)
|
||||
}
|
||||
|
||||
pub(super) fn get_database_path(app_handle: &AppHandle) -> PathBuf {
|
||||
app_handle
|
||||
.path()
|
||||
.app_data_dir()
|
||||
.expect("Failed to get app data directory")
|
||||
.join(DATABASE_PATH)
|
||||
}
|
||||
67
src-tauri/src/db/entities/accounts.rs
Normal file
67
src-tauri/src/db/entities/accounts.rs
Normal file
@@ -0,0 +1,67 @@
|
||||
//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0
|
||||
|
||||
use sea_orm::entity::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Serialize, Deserialize)]
|
||||
#[sea_orm(table_name = "accounts")]
|
||||
#[allow(dead_code)]
|
||||
pub struct Model {
|
||||
#[sea_orm(primary_key, auto_increment = false)]
|
||||
pub id: String,
|
||||
pub name: String,
|
||||
pub account_type: String,
|
||||
pub currency: String,
|
||||
pub initial_balance: String,
|
||||
pub current_balance: String,
|
||||
pub color: Option<String>,
|
||||
pub icon: Option<String>,
|
||||
pub sort_order: i64,
|
||||
pub is_active: bool,
|
||||
pub is_archived: bool,
|
||||
pub include_in_net_worth: bool,
|
||||
pub show_in_combined_view: bool,
|
||||
pub created_at: DateTime,
|
||||
pub updated_at: DateTime,
|
||||
pub version: i64,
|
||||
pub device_id: Option<String>,
|
||||
pub is_deleted: bool,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||
pub enum Relation {
|
||||
#[sea_orm(has_many = "super::goals::Entity")]
|
||||
Goals,
|
||||
#[sea_orm(has_many = "super::reconciliations::Entity")]
|
||||
Reconciliations,
|
||||
#[sea_orm(has_many = "super::scheduled_transactions::Entity")]
|
||||
ScheduledTransactions,
|
||||
#[sea_orm(has_many = "super::transactions::Entity")]
|
||||
Transactions,
|
||||
}
|
||||
|
||||
impl Related<super::goals::Entity> for Entity {
|
||||
fn to() -> RelationDef {
|
||||
Relation::Goals.def()
|
||||
}
|
||||
}
|
||||
|
||||
impl Related<super::reconciliations::Entity> for Entity {
|
||||
fn to() -> RelationDef {
|
||||
Relation::Reconciliations.def()
|
||||
}
|
||||
}
|
||||
|
||||
impl Related<super::scheduled_transactions::Entity> for Entity {
|
||||
fn to() -> RelationDef {
|
||||
Relation::ScheduledTransactions.def()
|
||||
}
|
||||
}
|
||||
|
||||
impl Related<super::transactions::Entity> for Entity {
|
||||
fn to() -> RelationDef {
|
||||
Relation::Transactions.def()
|
||||
}
|
||||
}
|
||||
|
||||
impl ActiveModelBehavior for ActiveModel {}
|
||||
24
src-tauri/src/db/entities/exchange_rates.rs
Normal file
24
src-tauri/src/db/entities/exchange_rates.rs
Normal file
@@ -0,0 +1,24 @@
|
||||
//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0
|
||||
|
||||
use sea_orm::entity::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Serialize, Deserialize)]
|
||||
#[sea_orm(table_name = "exchange_rates")]
|
||||
#[allow(dead_code)]
|
||||
pub struct Model {
|
||||
#[sea_orm(primary_key, auto_increment = false)]
|
||||
pub from_currency: String,
|
||||
#[sea_orm(primary_key, auto_increment = false)]
|
||||
pub to_currency: String,
|
||||
#[sea_orm(primary_key, auto_increment = false)]
|
||||
pub date: String,
|
||||
pub rate: String,
|
||||
pub source: Option<String>,
|
||||
pub fetched_at: Option<DateTime>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||
pub enum Relation {}
|
||||
|
||||
impl ActiveModelBehavior for ActiveModel {}
|
||||
51
src-tauri/src/db/entities/goal_progress.rs
Normal file
51
src-tauri/src/db/entities/goal_progress.rs
Normal file
@@ -0,0 +1,51 @@
|
||||
//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0
|
||||
|
||||
use sea_orm::entity::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Serialize, Deserialize)]
|
||||
#[sea_orm(table_name = "goal_progress")]
|
||||
#[allow(dead_code)]
|
||||
pub struct Model {
|
||||
#[sea_orm(primary_key, auto_increment = false)]
|
||||
pub id: String,
|
||||
pub goal_id: String,
|
||||
pub amount: String,
|
||||
pub transaction_id: Option<String>,
|
||||
pub notes: Option<String>,
|
||||
pub recorded_at: DateTime,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||
pub enum Relation {
|
||||
#[sea_orm(
|
||||
belongs_to = "super::goals::Entity",
|
||||
from = "Column::GoalId",
|
||||
to = "super::goals::Column::Id",
|
||||
on_update = "Cascade",
|
||||
on_delete = "Cascade"
|
||||
)]
|
||||
Goals,
|
||||
#[sea_orm(
|
||||
belongs_to = "super::transactions::Entity",
|
||||
from = "Column::TransactionId",
|
||||
to = "super::transactions::Column::Id",
|
||||
on_update = "Cascade",
|
||||
on_delete = "SetNull"
|
||||
)]
|
||||
Transactions,
|
||||
}
|
||||
|
||||
impl Related<super::goals::Entity> for Entity {
|
||||
fn to() -> RelationDef {
|
||||
Relation::Goals.def()
|
||||
}
|
||||
}
|
||||
|
||||
impl Related<super::transactions::Entity> for Entity {
|
||||
fn to() -> RelationDef {
|
||||
Relation::Transactions.def()
|
||||
}
|
||||
}
|
||||
|
||||
impl ActiveModelBehavior for ActiveModel {}
|
||||
45
src-tauri/src/db/entities/goal_rules.rs
Normal file
45
src-tauri/src/db/entities/goal_rules.rs
Normal file
@@ -0,0 +1,45 @@
|
||||
//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0
|
||||
|
||||
use sea_orm::entity::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Serialize, Deserialize)]
|
||||
#[sea_orm(table_name = "goal_rules")]
|
||||
#[allow(dead_code)]
|
||||
pub struct Model {
|
||||
#[sea_orm(primary_key, auto_increment = false)]
|
||||
pub id: String,
|
||||
pub goal_id: String,
|
||||
pub tag_ids: String,
|
||||
pub contribution_type: String,
|
||||
pub percentage: Option<String>,
|
||||
pub fixed_amount: Option<String>,
|
||||
pub max_contribution_per_transaction: Option<String>,
|
||||
pub monthly_cap: Option<String>,
|
||||
pub is_active: bool,
|
||||
pub created_at: DateTime,
|
||||
pub updated_at: DateTime,
|
||||
pub version: i64,
|
||||
pub device_id: Option<String>,
|
||||
pub is_deleted: bool,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||
pub enum Relation {
|
||||
#[sea_orm(
|
||||
belongs_to = "super::goals::Entity",
|
||||
from = "Column::GoalId",
|
||||
to = "super::goals::Column::Id",
|
||||
on_update = "Cascade",
|
||||
on_delete = "Cascade"
|
||||
)]
|
||||
Goals,
|
||||
}
|
||||
|
||||
impl Related<super::goals::Entity> for Entity {
|
||||
fn to() -> RelationDef {
|
||||
Relation::Goals.def()
|
||||
}
|
||||
}
|
||||
|
||||
impl ActiveModelBehavior for ActiveModel {}
|
||||
69
src-tauri/src/db/entities/goals.rs
Normal file
69
src-tauri/src/db/entities/goals.rs
Normal file
@@ -0,0 +1,69 @@
|
||||
//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0
|
||||
|
||||
use sea_orm::entity::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Serialize, Deserialize)]
|
||||
#[sea_orm(table_name = "goals")]
|
||||
#[allow(dead_code)]
|
||||
pub struct Model {
|
||||
#[sea_orm(primary_key, auto_increment = false)]
|
||||
pub id: String,
|
||||
pub name: String,
|
||||
pub description: Option<String>,
|
||||
pub target_amount: String,
|
||||
pub current_amount: String,
|
||||
pub currency: String,
|
||||
pub goal_type: String,
|
||||
pub target_date: Option<String>,
|
||||
pub is_recurring: bool,
|
||||
pub recurrence_period: Option<String>,
|
||||
pub linked_account_id: Option<String>,
|
||||
pub color: Option<String>,
|
||||
pub icon: Option<String>,
|
||||
pub is_active: bool,
|
||||
pub is_achieved: bool,
|
||||
pub achieved_at: Option<DateTime>,
|
||||
pub last_reset_date: Option<String>,
|
||||
pub created_at: DateTime,
|
||||
pub updated_at: DateTime,
|
||||
pub version: i64,
|
||||
pub device_id: Option<String>,
|
||||
pub is_deleted: bool,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||
pub enum Relation {
|
||||
#[sea_orm(
|
||||
belongs_to = "super::accounts::Entity",
|
||||
from = "Column::LinkedAccountId",
|
||||
to = "super::accounts::Column::Id",
|
||||
on_update = "Cascade",
|
||||
on_delete = "SetNull"
|
||||
)]
|
||||
Accounts,
|
||||
#[sea_orm(has_many = "super::goal_progress::Entity")]
|
||||
GoalProgress,
|
||||
#[sea_orm(has_many = "super::goal_rules::Entity")]
|
||||
GoalRules,
|
||||
}
|
||||
|
||||
impl Related<super::accounts::Entity> for Entity {
|
||||
fn to() -> RelationDef {
|
||||
Relation::Accounts.def()
|
||||
}
|
||||
}
|
||||
|
||||
impl Related<super::goal_progress::Entity> for Entity {
|
||||
fn to() -> RelationDef {
|
||||
Relation::GoalProgress.def()
|
||||
}
|
||||
}
|
||||
|
||||
impl Related<super::goal_rules::Entity> for Entity {
|
||||
fn to() -> RelationDef {
|
||||
Relation::GoalRules.def()
|
||||
}
|
||||
}
|
||||
|
||||
impl ActiveModelBehavior for ActiveModel {}
|
||||
17
src-tauri/src/db/entities/mod.rs
Normal file
17
src-tauri/src/db/entities/mod.rs
Normal file
@@ -0,0 +1,17 @@
|
||||
//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0
|
||||
|
||||
pub mod prelude;
|
||||
|
||||
pub mod accounts;
|
||||
pub mod exchange_rates;
|
||||
pub mod goal_progress;
|
||||
pub mod goal_rules;
|
||||
pub mod goals;
|
||||
pub mod reconciliations;
|
||||
pub mod scheduled_instances;
|
||||
pub mod scheduled_transactions;
|
||||
pub mod settings;
|
||||
pub mod tags;
|
||||
pub mod transaction_tags;
|
||||
pub mod transactions;
|
||||
pub mod transfers;
|
||||
17
src-tauri/src/db/entities/prelude.rs
Normal file
17
src-tauri/src/db/entities/prelude.rs
Normal file
@@ -0,0 +1,17 @@
|
||||
//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0
|
||||
|
||||
#![allow(unused_imports)]
|
||||
|
||||
pub use super::accounts::Entity as Accounts;
|
||||
pub use super::exchange_rates::Entity as ExchangeRates;
|
||||
pub use super::goal_progress::Entity as GoalProgress;
|
||||
pub use super::goal_rules::Entity as GoalRules;
|
||||
pub use super::goals::Entity as Goals;
|
||||
pub use super::reconciliations::Entity as Reconciliations;
|
||||
pub use super::scheduled_instances::Entity as ScheduledInstances;
|
||||
pub use super::scheduled_transactions::Entity as ScheduledTransactions;
|
||||
pub use super::settings::Entity as Settings;
|
||||
pub use super::tags::Entity as Tags;
|
||||
pub use super::transaction_tags::Entity as TransactionTags;
|
||||
pub use super::transactions::Entity as Transactions;
|
||||
pub use super::transfers::Entity as Transfers;
|
||||
43
src-tauri/src/db/entities/reconciliations.rs
Normal file
43
src-tauri/src/db/entities/reconciliations.rs
Normal file
@@ -0,0 +1,43 @@
|
||||
//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0
|
||||
|
||||
use sea_orm::entity::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Serialize, Deserialize)]
|
||||
#[sea_orm(table_name = "reconciliations")]
|
||||
#[allow(dead_code)]
|
||||
pub struct Model {
|
||||
#[sea_orm(primary_key, auto_increment = false)]
|
||||
pub id: String,
|
||||
pub account_id: String,
|
||||
pub statement_date: String,
|
||||
pub statement_balance: String,
|
||||
pub app_balance: String,
|
||||
pub difference: String,
|
||||
pub status: String,
|
||||
pub notes: Option<String>,
|
||||
pub created_at: DateTime,
|
||||
pub resolved_at: Option<DateTime>,
|
||||
pub version: i64,
|
||||
pub device_id: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||
pub enum Relation {
|
||||
#[sea_orm(
|
||||
belongs_to = "super::accounts::Entity",
|
||||
from = "Column::AccountId",
|
||||
to = "super::accounts::Column::Id",
|
||||
on_update = "Cascade",
|
||||
on_delete = "Cascade"
|
||||
)]
|
||||
Accounts,
|
||||
}
|
||||
|
||||
impl Related<super::accounts::Entity> for Entity {
|
||||
fn to() -> RelationDef {
|
||||
Relation::Accounts.def()
|
||||
}
|
||||
}
|
||||
|
||||
impl ActiveModelBehavior for ActiveModel {}
|
||||
54
src-tauri/src/db/entities/scheduled_instances.rs
Normal file
54
src-tauri/src/db/entities/scheduled_instances.rs
Normal file
@@ -0,0 +1,54 @@
|
||||
//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0
|
||||
|
||||
use sea_orm::entity::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Serialize, Deserialize)]
|
||||
#[sea_orm(table_name = "scheduled_instances")]
|
||||
#[allow(dead_code)]
|
||||
pub struct Model {
|
||||
#[sea_orm(primary_key, auto_increment = false)]
|
||||
pub id: String,
|
||||
pub schedule_id: String,
|
||||
pub transaction_id: Option<String>,
|
||||
pub due_date: String,
|
||||
pub is_generated: bool,
|
||||
pub is_skipped: bool,
|
||||
pub generated_at: Option<DateTime>,
|
||||
pub notified: bool,
|
||||
pub created_at: DateTime,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||
pub enum Relation {
|
||||
#[sea_orm(
|
||||
belongs_to = "super::scheduled_transactions::Entity",
|
||||
from = "Column::ScheduleId",
|
||||
to = "super::scheduled_transactions::Column::Id",
|
||||
on_update = "Cascade",
|
||||
on_delete = "Cascade"
|
||||
)]
|
||||
ScheduledTransactions,
|
||||
#[sea_orm(
|
||||
belongs_to = "super::transactions::Entity",
|
||||
from = "Column::TransactionId",
|
||||
to = "super::transactions::Column::Id",
|
||||
on_update = "Cascade",
|
||||
on_delete = "SetNull"
|
||||
)]
|
||||
Transactions,
|
||||
}
|
||||
|
||||
impl Related<super::scheduled_transactions::Entity> for Entity {
|
||||
fn to() -> RelationDef {
|
||||
Relation::ScheduledTransactions.def()
|
||||
}
|
||||
}
|
||||
|
||||
impl Related<super::transactions::Entity> for Entity {
|
||||
fn to() -> RelationDef {
|
||||
Relation::Transactions.def()
|
||||
}
|
||||
}
|
||||
|
||||
impl ActiveModelBehavior for ActiveModel {}
|
||||
77
src-tauri/src/db/entities/scheduled_transactions.rs
Normal file
77
src-tauri/src/db/entities/scheduled_transactions.rs
Normal file
@@ -0,0 +1,77 @@
|
||||
//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0
|
||||
|
||||
use sea_orm::entity::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Serialize, Deserialize)]
|
||||
#[sea_orm(table_name = "scheduled_transactions")]
|
||||
#[allow(dead_code)]
|
||||
pub struct Model {
|
||||
#[sea_orm(primary_key, auto_increment = false)]
|
||||
pub id: String,
|
||||
pub account_id: String,
|
||||
pub schedule_type: String,
|
||||
pub frequency: i64,
|
||||
pub days_of_week: Option<String>,
|
||||
pub day_of_month: Option<i64>,
|
||||
pub month_of_year: Option<i64>,
|
||||
pub execution_time: String,
|
||||
pub timezone: Option<String>,
|
||||
pub start_date: String,
|
||||
pub end_date: Option<String>,
|
||||
pub occurrence_count: Option<i64>,
|
||||
pub current_occurrence: i64,
|
||||
pub transaction_type: String,
|
||||
pub gross_amount: String,
|
||||
pub tax_amount: String,
|
||||
pub net_amount: String,
|
||||
pub currency: String,
|
||||
pub description: Option<String>,
|
||||
pub merchant: Option<String>,
|
||||
pub notes: Option<String>,
|
||||
pub tag_ids: Option<String>,
|
||||
pub is_active: bool,
|
||||
pub last_generated_date: Option<String>,
|
||||
pub next_execution_datetime: Option<DateTime>,
|
||||
pub created_at: DateTime,
|
||||
pub updated_at: DateTime,
|
||||
pub version: i64,
|
||||
pub device_id: Option<String>,
|
||||
pub is_deleted: bool,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||
pub enum Relation {
|
||||
#[sea_orm(
|
||||
belongs_to = "super::accounts::Entity",
|
||||
from = "Column::AccountId",
|
||||
to = "super::accounts::Column::Id",
|
||||
on_update = "Cascade",
|
||||
on_delete = "Cascade"
|
||||
)]
|
||||
Accounts,
|
||||
#[sea_orm(has_many = "super::scheduled_instances::Entity")]
|
||||
ScheduledInstances,
|
||||
#[sea_orm(has_many = "super::transactions::Entity")]
|
||||
Transactions,
|
||||
}
|
||||
|
||||
impl Related<super::accounts::Entity> for Entity {
|
||||
fn to() -> RelationDef {
|
||||
Relation::Accounts.def()
|
||||
}
|
||||
}
|
||||
|
||||
impl Related<super::scheduled_instances::Entity> for Entity {
|
||||
fn to() -> RelationDef {
|
||||
Relation::ScheduledInstances.def()
|
||||
}
|
||||
}
|
||||
|
||||
impl Related<super::transactions::Entity> for Entity {
|
||||
fn to() -> RelationDef {
|
||||
Relation::Transactions.def()
|
||||
}
|
||||
}
|
||||
|
||||
impl ActiveModelBehavior for ActiveModel {}
|
||||
19
src-tauri/src/db/entities/settings.rs
Normal file
19
src-tauri/src/db/entities/settings.rs
Normal file
@@ -0,0 +1,19 @@
|
||||
//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0
|
||||
|
||||
use sea_orm::entity::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Serialize, Deserialize)]
|
||||
#[sea_orm(table_name = "settings")]
|
||||
#[allow(dead_code)]
|
||||
pub struct Model {
|
||||
#[sea_orm(primary_key, auto_increment = false)]
|
||||
pub key: String,
|
||||
pub value: Option<String>,
|
||||
pub updated_at: DateTime,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||
pub enum Relation {}
|
||||
|
||||
impl ActiveModelBehavior for ActiveModel {}
|
||||
47
src-tauri/src/db/entities/tags.rs
Normal file
47
src-tauri/src/db/entities/tags.rs
Normal file
@@ -0,0 +1,47 @@
|
||||
//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0
|
||||
|
||||
use sea_orm::entity::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Serialize, Deserialize)]
|
||||
#[sea_orm(table_name = "tags")]
|
||||
#[allow(dead_code)]
|
||||
pub struct Model {
|
||||
#[sea_orm(primary_key, auto_increment = false)]
|
||||
pub id: String,
|
||||
pub name: String,
|
||||
pub color: String,
|
||||
pub icon: Option<String>,
|
||||
pub budget_amount: Option<String>,
|
||||
pub budget_period: Option<String>,
|
||||
pub is_system: bool,
|
||||
pub sort_order: i64,
|
||||
pub created_at: DateTime,
|
||||
pub updated_at: DateTime,
|
||||
pub version: i64,
|
||||
pub device_id: Option<String>,
|
||||
pub is_deleted: bool,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||
pub enum Relation {
|
||||
#[sea_orm(has_many = "super::transaction_tags::Entity")]
|
||||
TransactionTags,
|
||||
}
|
||||
|
||||
impl Related<super::transaction_tags::Entity> for Entity {
|
||||
fn to() -> RelationDef {
|
||||
Relation::TransactionTags.def()
|
||||
}
|
||||
}
|
||||
|
||||
impl Related<super::transactions::Entity> for Entity {
|
||||
fn to() -> RelationDef {
|
||||
super::transaction_tags::Relation::Transactions.def()
|
||||
}
|
||||
fn via() -> Option<RelationDef> {
|
||||
Some(super::transaction_tags::Relation::Tags.def().rev())
|
||||
}
|
||||
}
|
||||
|
||||
impl ActiveModelBehavior for ActiveModel {}
|
||||
48
src-tauri/src/db/entities/transaction_tags.rs
Normal file
48
src-tauri/src/db/entities/transaction_tags.rs
Normal file
@@ -0,0 +1,48 @@
|
||||
//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0
|
||||
|
||||
use sea_orm::entity::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Serialize, Deserialize)]
|
||||
#[sea_orm(table_name = "transaction_tags")]
|
||||
#[allow(dead_code)]
|
||||
pub struct Model {
|
||||
#[sea_orm(primary_key, auto_increment = false)]
|
||||
pub transaction_id: String,
|
||||
#[sea_orm(primary_key, auto_increment = false)]
|
||||
pub tag_id: String,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||
pub enum Relation {
|
||||
#[sea_orm(
|
||||
belongs_to = "super::tags::Entity",
|
||||
from = "Column::TagId",
|
||||
to = "super::tags::Column::Id",
|
||||
on_update = "Cascade",
|
||||
on_delete = "Cascade"
|
||||
)]
|
||||
Tags,
|
||||
#[sea_orm(
|
||||
belongs_to = "super::transactions::Entity",
|
||||
from = "Column::TransactionId",
|
||||
to = "super::transactions::Column::Id",
|
||||
on_update = "Cascade",
|
||||
on_delete = "Cascade"
|
||||
)]
|
||||
Transactions,
|
||||
}
|
||||
|
||||
impl Related<super::tags::Entity> for Entity {
|
||||
fn to() -> RelationDef {
|
||||
Relation::Tags.def()
|
||||
}
|
||||
}
|
||||
|
||||
impl Related<super::transactions::Entity> for Entity {
|
||||
fn to() -> RelationDef {
|
||||
Relation::Transactions.def()
|
||||
}
|
||||
}
|
||||
|
||||
impl ActiveModelBehavior for ActiveModel {}
|
||||
104
src-tauri/src/db/entities/transactions.rs
Normal file
104
src-tauri/src/db/entities/transactions.rs
Normal file
@@ -0,0 +1,104 @@
|
||||
//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0
|
||||
|
||||
use sea_orm::entity::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Serialize, Deserialize)]
|
||||
#[sea_orm(table_name = "transactions")]
|
||||
#[allow(dead_code)]
|
||||
pub struct Model {
|
||||
#[sea_orm(primary_key, auto_increment = false)]
|
||||
pub id: String,
|
||||
pub account_id: String,
|
||||
pub transaction_type: String,
|
||||
pub gross_amount: String,
|
||||
pub tax_amount: String,
|
||||
pub net_amount: String,
|
||||
pub tax_rate: Option<String>,
|
||||
pub currency: String,
|
||||
pub description: String,
|
||||
pub merchant: Option<String>,
|
||||
pub notes: Option<String>,
|
||||
pub receipt_paths: Option<String>,
|
||||
pub receipt_ocr_data: Option<String>,
|
||||
pub transfer_id: Option<String>,
|
||||
pub related_transaction_id: Option<String>,
|
||||
pub schedule_id: Option<String>,
|
||||
pub is_scheduled_instance: bool,
|
||||
pub is_auto_inserted: bool,
|
||||
pub needs_review: bool,
|
||||
pub transaction_date: String,
|
||||
pub created_at: DateTime,
|
||||
pub updated_at: DateTime,
|
||||
pub version: i64,
|
||||
pub device_id: Option<String>,
|
||||
pub is_deleted: bool,
|
||||
pub sync_status: String,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||
pub enum Relation {
|
||||
#[sea_orm(
|
||||
belongs_to = "super::accounts::Entity",
|
||||
from = "Column::AccountId",
|
||||
to = "super::accounts::Column::Id",
|
||||
on_update = "Cascade",
|
||||
on_delete = "Cascade"
|
||||
)]
|
||||
Accounts,
|
||||
#[sea_orm(has_many = "super::goal_progress::Entity")]
|
||||
GoalProgress,
|
||||
#[sea_orm(has_many = "super::scheduled_instances::Entity")]
|
||||
ScheduledInstances,
|
||||
#[sea_orm(
|
||||
belongs_to = "super::scheduled_transactions::Entity",
|
||||
from = "Column::ScheduleId",
|
||||
to = "super::scheduled_transactions::Column::Id",
|
||||
on_update = "Cascade",
|
||||
on_delete = "SetNull"
|
||||
)]
|
||||
ScheduledTransactions,
|
||||
#[sea_orm(has_many = "super::transaction_tags::Entity")]
|
||||
TransactionTags,
|
||||
}
|
||||
|
||||
impl Related<super::accounts::Entity> for Entity {
|
||||
fn to() -> RelationDef {
|
||||
Relation::Accounts.def()
|
||||
}
|
||||
}
|
||||
|
||||
impl Related<super::goal_progress::Entity> for Entity {
|
||||
fn to() -> RelationDef {
|
||||
Relation::GoalProgress.def()
|
||||
}
|
||||
}
|
||||
|
||||
impl Related<super::scheduled_instances::Entity> for Entity {
|
||||
fn to() -> RelationDef {
|
||||
Relation::ScheduledInstances.def()
|
||||
}
|
||||
}
|
||||
|
||||
impl Related<super::scheduled_transactions::Entity> for Entity {
|
||||
fn to() -> RelationDef {
|
||||
Relation::ScheduledTransactions.def()
|
||||
}
|
||||
}
|
||||
|
||||
impl Related<super::transaction_tags::Entity> for Entity {
|
||||
fn to() -> RelationDef {
|
||||
Relation::TransactionTags.def()
|
||||
}
|
||||
}
|
||||
|
||||
impl Related<super::tags::Entity> for Entity {
|
||||
fn to() -> RelationDef {
|
||||
super::transaction_tags::Relation::Tags.def()
|
||||
}
|
||||
fn via() -> Option<RelationDef> {
|
||||
Some(super::transaction_tags::Relation::Transactions.def().rev())
|
||||
}
|
||||
}
|
||||
|
||||
impl ActiveModelBehavior for ActiveModel {}
|
||||
32
src-tauri/src/db/entities/transfers.rs
Normal file
32
src-tauri/src/db/entities/transfers.rs
Normal file
@@ -0,0 +1,32 @@
|
||||
//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0
|
||||
|
||||
use sea_orm::entity::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Serialize, Deserialize)]
|
||||
#[sea_orm(table_name = "transfers")]
|
||||
#[allow(dead_code)]
|
||||
pub struct Model {
|
||||
#[sea_orm(primary_key, auto_increment = false)]
|
||||
pub id: String,
|
||||
pub from_account_id: String,
|
||||
pub to_account_id: String,
|
||||
pub from_transaction_id: Option<String>,
|
||||
pub to_transaction_id: Option<String>,
|
||||
pub from_amount: String,
|
||||
pub to_amount: String,
|
||||
pub exchange_rate: Option<String>,
|
||||
pub exchange_rate_source: Option<String>,
|
||||
pub fees: String,
|
||||
pub description: Option<String>,
|
||||
pub transfer_date: String,
|
||||
pub created_at: DateTime,
|
||||
pub version: i64,
|
||||
pub device_id: Option<String>,
|
||||
pub is_deleted: bool,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||
pub enum Relation {}
|
||||
|
||||
impl ActiveModelBehavior for ActiveModel {}
|
||||
7
src-tauri/src/db/migrations.rs
Normal file
7
src-tauri/src/db/migrations.rs
Normal file
@@ -0,0 +1,7 @@
|
||||
use migration::{Migrator, MigratorTrait};
|
||||
use sea_orm::DatabaseConnection;
|
||||
|
||||
pub(super) async fn run_migrations(conn: &DatabaseConnection) -> Result<(), sea_orm::DbErr> {
|
||||
Migrator::up(conn, None).await?;
|
||||
Ok(())
|
||||
}
|
||||
5
src-tauri/src/db/mod.rs
Normal file
5
src-tauri/src/db/mod.rs
Normal file
@@ -0,0 +1,5 @@
|
||||
pub mod entities;
|
||||
pub mod service;
|
||||
|
||||
mod connection;
|
||||
mod migrations;
|
||||
26
src-tauri/src/db/service.rs
Normal file
26
src-tauri/src/db/service.rs
Normal file
@@ -0,0 +1,26 @@
|
||||
use sea_orm::{DatabaseConnection, DbErr};
|
||||
|
||||
use super::connection;
|
||||
|
||||
pub struct DbService {
|
||||
connection: DatabaseConnection,
|
||||
}
|
||||
|
||||
impl DbService {
|
||||
pub async fn new(app_handle: &tauri::AppHandle) -> Result<Self, DbErr> {
|
||||
let connection = connection::establish_connection(app_handle).await?;
|
||||
Ok(Self { connection })
|
||||
}
|
||||
|
||||
pub fn get_connection(&self) -> &DatabaseConnection {
|
||||
&self.connection
|
||||
}
|
||||
|
||||
pub fn get_connection_mut(&mut self) -> &mut DatabaseConnection {
|
||||
&mut self.connection
|
||||
}
|
||||
|
||||
pub async fn run_migrations(&self) -> Result<(), DbErr> {
|
||||
crate::db::migrations::run_migrations(&self.connection).await
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
mod db;
|
||||
|
||||
// Learn more about Tauri commands at https://tauri.app/develop/calling-rust/
|
||||
#[tauri::command]
|
||||
fn greet(name: &str) -> String {
|
||||
|
||||
Reference in New Issue
Block a user