adding migration command

This commit is contained in:
Namekuji 2023-08-16 22:05:47 -04:00
parent d8154dc591
commit ef0d842298
No known key found for this signature in database
GPG key ID: 1D62332C07FBA532
8 changed files with 110 additions and 5 deletions

View file

@ -577,6 +577,21 @@ dependencies = [
"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]]
name = "crossbeam-queue"
version = "0.3.8"
@ -2447,8 +2462,10 @@ dependencies = [
"scylla",
"serde",
"serde_yaml",
"sqlx",
"thiserror",
"tokio",
"urlencoding",
]
[[package]]
@ -2869,6 +2886,7 @@ dependencies = [
"byteorder",
"bytes",
"chrono",
"crc",
"crossbeam-queue",
"dirs",
"dotenvy",
@ -2929,6 +2947,7 @@ dependencies = [
"proc-macro2",
"quote",
"serde_json",
"sha2",
"sqlx-core",
"sqlx-rt",
"syn 1.0.109",
@ -3396,9 +3415,9 @@ dependencies = [
[[package]]
name = "urlencoding"
version = "2.1.2"
version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8db7427f936968176eaa7cdf81b7f98b980b18495ec28f1b5791ac3bfe3eea9"
checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da"
[[package]]
name = "utf8parse"

View file

@ -11,5 +11,7 @@ clap = { version = "4.3.11", features = ["derive"] }
scylla = "0.8.2"
serde = { version = "1.0.171", features = ["derive"] }
serde_yaml = "0.9.22"
sqlx = { version = "0.6.0", features = ["runtime-tokio-rustls", "postgres"] }
thiserror = "1.0.43"
tokio = { version = "1.29.1", features = ["full"] }
urlencoding = "2.1.3"

View file

@ -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"))
.expect("Failed to open 'default.yml'");
let config: Config = serde_yaml::from_reader(yml).expect("Failed to parse yaml");
let config = config
let scylla_conf = config
.scylla
.expect("ScyllaDB config not found in 'default.yml'");
match cli.subcommand {
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 } => {
Migrator::new(migration_dir, &config)
Migrator::new(migration_dir, &scylla_conf)
.await?
.down(num)
.await?
@ -106,4 +106,6 @@ pub(crate) enum MigrationCommand {
)]
num: u32,
},
#[clap(about = "Set up PostgreSQL and ScyllaDB", display_order = 40)]
Setup,
}

View file

@ -4,6 +4,7 @@ use serde::Deserialize;
#[serde(rename_all = "camelCase")]
pub struct Config {
pub scylla: Option<ScyllaConfig>,
pub db: DbConfig,
}
#[derive(Debug, PartialEq, Deserialize)]
@ -13,3 +14,12 @@ pub struct ScyllaConfig {
pub keyspace: String,
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,
}

View file

@ -20,4 +20,6 @@ pub enum Error {
Row(#[from] SingleRowTypedError),
#[error("File error: {0}")]
File(#[from] io::Error),
#[error("PostgreSQL error: {0}")]
Postgres(#[from] sqlx::Error),
}

View file

@ -5,3 +5,4 @@ pub mod config;
pub mod error;
pub(crate) mod migrator;
pub(crate) mod setup;

View 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(())
}
}

View file

@ -1,3 +1,4 @@
import { scyllaClient } from "@/db/scylla.js";
import define from "../../define.js";
import { MutedNotes } from "@/models/index.js";
@ -29,6 +30,10 @@ export const paramDef = {
} as const;
export default define(meta, paramDef, async (ps, user) => {
if (scyllaClient) {
return { count: -1 };
}
return {
count: await MutedNotes.countBy({
userId: user.id,