adding migration command
This commit is contained in:
parent
d8154dc591
commit
ef0d842298
8 changed files with 110 additions and 5 deletions
23
packages/backend/native-utils/Cargo.lock
generated
23
packages/backend/native-utils/Cargo.lock
generated
|
@ -577,6 +577,21 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crc"
|
||||||
|
version = "3.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe"
|
||||||
|
dependencies = [
|
||||||
|
"crc-catalog",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crc-catalog"
|
||||||
|
version = "2.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9cace84e55f07e7301bae1c519df89cdad8cc3cd868413d3fdbdeca9ff3db484"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-queue"
|
name = "crossbeam-queue"
|
||||||
version = "0.3.8"
|
version = "0.3.8"
|
||||||
|
@ -2447,8 +2462,10 @@ dependencies = [
|
||||||
"scylla",
|
"scylla",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_yaml",
|
"serde_yaml",
|
||||||
|
"sqlx",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"urlencoding",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2869,6 +2886,7 @@ dependencies = [
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"bytes",
|
"bytes",
|
||||||
"chrono",
|
"chrono",
|
||||||
|
"crc",
|
||||||
"crossbeam-queue",
|
"crossbeam-queue",
|
||||||
"dirs",
|
"dirs",
|
||||||
"dotenvy",
|
"dotenvy",
|
||||||
|
@ -2929,6 +2947,7 @@ dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
"sha2",
|
||||||
"sqlx-core",
|
"sqlx-core",
|
||||||
"sqlx-rt",
|
"sqlx-rt",
|
||||||
"syn 1.0.109",
|
"syn 1.0.109",
|
||||||
|
@ -3396,9 +3415,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "urlencoding"
|
name = "urlencoding"
|
||||||
version = "2.1.2"
|
version = "2.1.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e8db7427f936968176eaa7cdf81b7f98b980b18495ec28f1b5791ac3bfe3eea9"
|
checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "utf8parse"
|
name = "utf8parse"
|
||||||
|
|
|
@ -11,5 +11,7 @@ clap = { version = "4.3.11", features = ["derive"] }
|
||||||
scylla = "0.8.2"
|
scylla = "0.8.2"
|
||||||
serde = { version = "1.0.171", features = ["derive"] }
|
serde = { version = "1.0.171", features = ["derive"] }
|
||||||
serde_yaml = "0.9.22"
|
serde_yaml = "0.9.22"
|
||||||
|
sqlx = { version = "0.6.0", features = ["runtime-tokio-rustls", "postgres"] }
|
||||||
thiserror = "1.0.43"
|
thiserror = "1.0.43"
|
||||||
tokio = { version = "1.29.1", features = ["full"] }
|
tokio = { version = "1.29.1", features = ["full"] }
|
||||||
|
urlencoding = "2.1.3"
|
||||||
|
|
|
@ -23,16 +23,16 @@ pub async fn run_cli() -> Result<(), Error> {
|
||||||
let yml = fs::File::open(cli.config.expect("Path to 'default.yml' not specified"))
|
let yml = fs::File::open(cli.config.expect("Path to 'default.yml' not specified"))
|
||||||
.expect("Failed to open 'default.yml'");
|
.expect("Failed to open 'default.yml'");
|
||||||
let config: Config = serde_yaml::from_reader(yml).expect("Failed to parse yaml");
|
let config: Config = serde_yaml::from_reader(yml).expect("Failed to parse yaml");
|
||||||
let config = config
|
let scylla_conf = config
|
||||||
.scylla
|
.scylla
|
||||||
.expect("ScyllaDB config not found in 'default.yml'");
|
.expect("ScyllaDB config not found in 'default.yml'");
|
||||||
|
|
||||||
match cli.subcommand {
|
match cli.subcommand {
|
||||||
MigrationCommand::Up { num } => {
|
MigrationCommand::Up { num } => {
|
||||||
Migrator::new(migration_dir, &config).await?.up(num).await?
|
Migrator::new(migration_dir, &scylla_conf).await?.up(num).await?
|
||||||
}
|
}
|
||||||
MigrationCommand::Down { num } => {
|
MigrationCommand::Down { num } => {
|
||||||
Migrator::new(migration_dir, &config)
|
Migrator::new(migration_dir, &scylla_conf)
|
||||||
.await?
|
.await?
|
||||||
.down(num)
|
.down(num)
|
||||||
.await?
|
.await?
|
||||||
|
@ -106,4 +106,6 @@ pub(crate) enum MigrationCommand {
|
||||||
)]
|
)]
|
||||||
num: u32,
|
num: u32,
|
||||||
},
|
},
|
||||||
|
#[clap(about = "Set up PostgreSQL and ScyllaDB", display_order = 40)]
|
||||||
|
Setup,
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ use serde::Deserialize;
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
pub scylla: Option<ScyllaConfig>,
|
pub scylla: Option<ScyllaConfig>,
|
||||||
|
pub db: DbConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Deserialize)]
|
#[derive(Debug, PartialEq, Deserialize)]
|
||||||
|
@ -13,3 +14,12 @@ pub struct ScyllaConfig {
|
||||||
pub keyspace: String,
|
pub keyspace: String,
|
||||||
pub replication_factor: i32,
|
pub replication_factor: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Deserialize)]
|
||||||
|
pub struct DbConfig {
|
||||||
|
pub host: String,
|
||||||
|
pub port: u32,
|
||||||
|
pub db: String,
|
||||||
|
pub user: String,
|
||||||
|
pub pass: String,
|
||||||
|
}
|
||||||
|
|
|
@ -20,4 +20,6 @@ pub enum Error {
|
||||||
Row(#[from] SingleRowTypedError),
|
Row(#[from] SingleRowTypedError),
|
||||||
#[error("File error: {0}")]
|
#[error("File error: {0}")]
|
||||||
File(#[from] io::Error),
|
File(#[from] io::Error),
|
||||||
|
#[error("PostgreSQL error: {0}")]
|
||||||
|
Postgres(#[from] sqlx::Error),
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,3 +5,4 @@ pub mod config;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
|
|
||||||
pub(crate) mod migrator;
|
pub(crate) mod migrator;
|
||||||
|
pub(crate) mod setup;
|
||||||
|
|
64
packages/backend/native-utils/scylla-migration/src/setup.rs
Normal file
64
packages/backend/native-utils/scylla-migration/src/setup.rs
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
use scylla::{Session, SessionBuilder};
|
||||||
|
use sqlx::{Connection, PgConnection};
|
||||||
|
use urlencoding::encode;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
config::{DbConfig, ScyllaConfig},
|
||||||
|
error::Error,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub(crate) struct Initializer {
|
||||||
|
scylla: Session,
|
||||||
|
postgres_url: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Initializer {
|
||||||
|
pub(crate) async fn new(
|
||||||
|
scylla_conf: &ScyllaConfig,
|
||||||
|
postgres_conf: &DbConfig,
|
||||||
|
) -> Result<Self, Error> {
|
||||||
|
let session = SessionBuilder::new()
|
||||||
|
.known_nodes(&scylla_conf.nodes)
|
||||||
|
.build()
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
let conn_url = format!(
|
||||||
|
"postgres://{}:{}@{}:{}/{}",
|
||||||
|
postgres_conf.user,
|
||||||
|
encode(&postgres_conf.pass),
|
||||||
|
postgres_conf.host,
|
||||||
|
postgres_conf.port,
|
||||||
|
postgres_conf.db,
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
scylla: session,
|
||||||
|
postgres_url: conn_url,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) async fn setup(&self) -> Result<(), Error> {
|
||||||
|
const DROP_CONSTRAINT: &str = "ALTER TABLE ? DROP CONSTRAINT ?";
|
||||||
|
|
||||||
|
let pairs = vec![
|
||||||
|
("channel_note_pining", "FK_10b19ef67d297ea9de325cd4502"),
|
||||||
|
("clip_note", "FK_a012eaf5c87c65da1deb5fdbfa3"),
|
||||||
|
("muted_note", "FK_70ab9786313d78e4201d81cdb89"),
|
||||||
|
("note_edit", "FK_702ad5ae993a672e4fbffbcd38c"),
|
||||||
|
("note_favorite", "FK_0e00498f180193423c992bc4370"),
|
||||||
|
("note_unread", "FK_e637cba4dc4410218c4251260e4"),
|
||||||
|
("note_wathing", "FK_03e7028ab8388a3f5e3ce2a8619"),
|
||||||
|
("promo_note", "FK_e263909ca4fe5d57f8d4230dd5c"),
|
||||||
|
("promo_read", "FK_a46a1a603ecee695d7db26da5f4"),
|
||||||
|
("user_note_pining", "FK_68881008f7c3588ad7ecae471cf")
|
||||||
|
];
|
||||||
|
|
||||||
|
let mut conn = PgConnection::connect(&self.postgres_url).await?;
|
||||||
|
|
||||||
|
for (table, fk) in pairs {
|
||||||
|
sqlx::query(DROP_CONSTRAINT).bind(table).bind(fk).execute(&mut conn).await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { scyllaClient } from "@/db/scylla.js";
|
||||||
import define from "../../define.js";
|
import define from "../../define.js";
|
||||||
import { MutedNotes } from "@/models/index.js";
|
import { MutedNotes } from "@/models/index.js";
|
||||||
|
|
||||||
|
@ -29,6 +30,10 @@ export const paramDef = {
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export default define(meta, paramDef, async (ps, user) => {
|
export default define(meta, paramDef, async (ps, user) => {
|
||||||
|
if (scyllaClient) {
|
||||||
|
return { count: -1 };
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
count: await MutedNotes.countBy({
|
count: await MutedNotes.countBy({
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
|
|
Loading…
Reference in a new issue