Move SQL stuff into separate models module
This commit is contained in:
parent
d8080091f2
commit
19350081c3
260
src/main.rs
260
src/main.rs
@ -24,261 +24,19 @@ use tokio_util::compat::FuturesAsyncReadCompatExt;
|
||||
use unrar::Archive;
|
||||
use zip::write::{FileOptions, ZipWriter};
|
||||
|
||||
mod models;
|
||||
|
||||
use models::cell::insert_cell;
|
||||
use models::file::{insert_file, File};
|
||||
use models::game::insert_game;
|
||||
use models::game_mod::{get_mod_by_nexus_mod_id, insert_mod, Mod};
|
||||
use models::plugin::insert_plugin;
|
||||
use models::plugin_cell::insert_plugin_cell;
|
||||
|
||||
static USER_AGENT: &str = "mod-mapper/0.1";
|
||||
static GAME_NAME: &str = "skyrimspecialedition";
|
||||
const GAME_ID: u32 = 1704;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct Game {
|
||||
id: i32,
|
||||
name: String,
|
||||
nexus_game_id: i32,
|
||||
updated_at: NaiveDateTime,
|
||||
created_at: NaiveDateTime,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct Mod {
|
||||
id: i32,
|
||||
name: String,
|
||||
nexus_mod_id: i32,
|
||||
author: String,
|
||||
category: String,
|
||||
description: Option<String>,
|
||||
game_id: i32,
|
||||
updated_at: NaiveDateTime,
|
||||
created_at: NaiveDateTime,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct File {
|
||||
id: i32,
|
||||
name: String,
|
||||
file_name: String,
|
||||
nexus_file_id: i32,
|
||||
mod_id: i32,
|
||||
category: Option<String>,
|
||||
version: Option<String>,
|
||||
mod_version: Option<String>,
|
||||
uploaded_at: NaiveDateTime,
|
||||
updated_at: NaiveDateTime,
|
||||
created_at: NaiveDateTime,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct Plugin {
|
||||
id: i32,
|
||||
name: String,
|
||||
hash: i64,
|
||||
file_id: i32,
|
||||
version: Option<f64>,
|
||||
author: Option<String>,
|
||||
description: Option<String>,
|
||||
masters: Option<Vec<String>>,
|
||||
updated_at: NaiveDateTime,
|
||||
created_at: NaiveDateTime,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct Cell {
|
||||
id: i32,
|
||||
form_id: i32,
|
||||
x: Option<i32>,
|
||||
y: Option<i32>,
|
||||
is_persistent: bool,
|
||||
updated_at: NaiveDateTime,
|
||||
created_at: NaiveDateTime,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct PluginCell {
|
||||
id: i32,
|
||||
plugin_id: i32,
|
||||
cell_id: i32,
|
||||
editor_id: Option<String>,
|
||||
updated_at: NaiveDateTime,
|
||||
created_at: NaiveDateTime,
|
||||
}
|
||||
|
||||
async fn insert_game(
|
||||
pool: &sqlx::Pool<sqlx::Postgres>,
|
||||
name: &str,
|
||||
nexus_game_id: i32,
|
||||
) -> Result<Game> {
|
||||
sqlx::query_as!(
|
||||
Game,
|
||||
"INSERT INTO games
|
||||
(name, nexus_game_id, created_at, updated_at)
|
||||
VALUES ($1, $2, now(), now())
|
||||
ON CONFLICT (nexus_game_id, name) DO UPDATE SET (name, updated_at) = (EXCLUDED.name, now())
|
||||
RETURNING *",
|
||||
name,
|
||||
nexus_game_id
|
||||
)
|
||||
.fetch_one(pool)
|
||||
.await
|
||||
.context("Failed to insert game")
|
||||
}
|
||||
|
||||
async fn get_mod_by_nexus_mod_id(
|
||||
pool: &sqlx::Pool<sqlx::Postgres>,
|
||||
nexus_mod_id: i32,
|
||||
) -> Result<Option<Mod>> {
|
||||
sqlx::query_as!(
|
||||
Mod,
|
||||
"SELECT * FROM mods WHERE nexus_mod_id = $1",
|
||||
nexus_mod_id,
|
||||
)
|
||||
.fetch_optional(pool)
|
||||
.await
|
||||
.context("Failed to get mod")
|
||||
}
|
||||
|
||||
async fn insert_mod(
|
||||
pool: &sqlx::Pool<sqlx::Postgres>,
|
||||
name: &str,
|
||||
nexus_mod_id: i32,
|
||||
author: &str,
|
||||
category: &str,
|
||||
description: Option<&str>,
|
||||
game_id: i32,
|
||||
) -> Result<Mod> {
|
||||
sqlx::query_as!(
|
||||
Mod,
|
||||
"INSERT INTO mods
|
||||
(name, nexus_mod_id, author, category, description, game_id, created_at, updated_at)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, now(), now())
|
||||
ON CONFLICT (game_id, nexus_mod_id) DO UPDATE
|
||||
SET (name, author, category, description, updated_at) =
|
||||
(EXCLUDED.name, EXCLUDED.author, EXCLUDED.category, EXCLUDED.description, now())
|
||||
RETURNING *",
|
||||
name,
|
||||
nexus_mod_id,
|
||||
author,
|
||||
category,
|
||||
description,
|
||||
game_id
|
||||
)
|
||||
.fetch_one(pool)
|
||||
.await
|
||||
.context("Failed to insert or update mod")
|
||||
}
|
||||
|
||||
async fn insert_file(
|
||||
pool: &sqlx::Pool<sqlx::Postgres>,
|
||||
name: &str,
|
||||
file_name: &str,
|
||||
nexus_file_id: i32,
|
||||
mod_id: i32,
|
||||
category: Option<&str>,
|
||||
version: Option<&str>,
|
||||
mod_version: Option<&str>,
|
||||
uploaded_at: NaiveDateTime,
|
||||
) -> Result<File> {
|
||||
sqlx::query_as!(
|
||||
File,
|
||||
"INSERT INTO files
|
||||
(name, file_name, nexus_file_id, mod_id, category, version, mod_version, uploaded_at, created_at, updated_at)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, now(), now())
|
||||
ON CONFLICT (mod_id, nexus_file_id) DO UPDATE
|
||||
SET (name, file_name, category, version, mod_version, uploaded_at, updated_at) =
|
||||
(EXCLUDED.name, EXCLUDED.file_name, EXCLUDED.category, EXCLUDED.version, EXCLUDED.mod_version, EXCLUDED.uploaded_at, now())
|
||||
RETURNING *",
|
||||
name,
|
||||
file_name,
|
||||
nexus_file_id,
|
||||
mod_id,
|
||||
category,
|
||||
version,
|
||||
mod_version,
|
||||
uploaded_at
|
||||
)
|
||||
.fetch_one(pool)
|
||||
.await
|
||||
.context("Failed to insert file")
|
||||
}
|
||||
|
||||
async fn insert_plugin(
|
||||
pool: &sqlx::Pool<sqlx::Postgres>,
|
||||
name: &str,
|
||||
hash: i64,
|
||||
file_id: i32,
|
||||
version: Option<f64>,
|
||||
author: Option<&str>,
|
||||
description: Option<&str>,
|
||||
masters: Option<&[String]>,
|
||||
) -> Result<Plugin> {
|
||||
sqlx::query_as!(
|
||||
Plugin,
|
||||
"INSERT INTO plugins
|
||||
(name, hash, file_id, version, author, description, masters, created_at, updated_at)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, now(), now())
|
||||
ON CONFLICT (file_id, name) DO UPDATE
|
||||
SET (hash, version, author, description, masters, updated_at) =
|
||||
(EXCLUDED.hash, EXCLUDED.version, EXCLUDED.author, EXCLUDED.description, EXCLUDED.masters, now())
|
||||
RETURNING *",
|
||||
name,
|
||||
hash,
|
||||
file_id,
|
||||
version,
|
||||
author,
|
||||
description,
|
||||
masters
|
||||
)
|
||||
.fetch_one(pool)
|
||||
.await
|
||||
.context("Failed to insert plugin")
|
||||
}
|
||||
|
||||
async fn insert_cell(
|
||||
pool: &sqlx::Pool<sqlx::Postgres>,
|
||||
form_id: i32,
|
||||
x: Option<i32>,
|
||||
y: Option<i32>,
|
||||
is_persistent: bool,
|
||||
) -> Result<Cell> {
|
||||
sqlx::query_as!(
|
||||
Cell,
|
||||
"INSERT INTO cells
|
||||
(form_id, x, y, is_persistent, created_at, updated_at)
|
||||
VALUES ($1, $2, $3, $4, now(), now())
|
||||
ON CONFLICT (form_id) DO UPDATE
|
||||
SET (x, y, is_persistent, updated_at) =
|
||||
(EXCLUDED.x, EXCLUDED.y, EXCLUDED.is_persistent, now())
|
||||
RETURNING *",
|
||||
form_id,
|
||||
x,
|
||||
y,
|
||||
is_persistent
|
||||
)
|
||||
.fetch_one(pool)
|
||||
.await
|
||||
.context("Failed to insert cell")
|
||||
}
|
||||
|
||||
async fn insert_plugin_cell(
|
||||
pool: &sqlx::Pool<sqlx::Postgres>,
|
||||
plugin_id: i32,
|
||||
cell_id: i32,
|
||||
editor_id: Option<String>,
|
||||
) -> Result<PluginCell> {
|
||||
sqlx::query_as!(
|
||||
PluginCell,
|
||||
"INSERT INTO plugin_cells
|
||||
(plugin_id, cell_id, editor_id, created_at, updated_at)
|
||||
VALUES ($1, $2, $3, now(), now())
|
||||
ON CONFLICT (plugin_id, cell_id) DO UPDATE
|
||||
SET (editor_id, updated_at) = (EXCLUDED.editor_id, now())
|
||||
RETURNING *",
|
||||
plugin_id,
|
||||
cell_id,
|
||||
editor_id,
|
||||
)
|
||||
.fetch_one(pool)
|
||||
.await
|
||||
.context("Failed to insert cell")
|
||||
}
|
||||
|
||||
fn rate_limit_wait_duration(res: &Response) -> Result<Option<std::time::Duration>> {
|
||||
let daily_remaining = res
|
||||
.headers()
|
||||
|
40
src/models/cell.rs
Normal file
40
src/models/cell.rs
Normal file
@ -0,0 +1,40 @@
|
||||
use anyhow::{Context, Result};
|
||||
use chrono::NaiveDateTime;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct Cell {
|
||||
pub id: i32,
|
||||
pub form_id: i32,
|
||||
pub x: Option<i32>,
|
||||
pub y: Option<i32>,
|
||||
pub is_persistent: bool,
|
||||
pub updated_at: NaiveDateTime,
|
||||
pub created_at: NaiveDateTime,
|
||||
}
|
||||
|
||||
pub async fn insert_cell(
|
||||
pool: &sqlx::Pool<sqlx::Postgres>,
|
||||
form_id: i32,
|
||||
x: Option<i32>,
|
||||
y: Option<i32>,
|
||||
is_persistent: bool,
|
||||
) -> Result<Cell> {
|
||||
sqlx::query_as!(
|
||||
Cell,
|
||||
"INSERT INTO cells
|
||||
(form_id, x, y, is_persistent, created_at, updated_at)
|
||||
VALUES ($1, $2, $3, $4, now(), now())
|
||||
ON CONFLICT (form_id) DO UPDATE
|
||||
SET (x, y, is_persistent, updated_at) =
|
||||
(EXCLUDED.x, EXCLUDED.y, EXCLUDED.is_persistent, now())
|
||||
RETURNING *",
|
||||
form_id,
|
||||
x,
|
||||
y,
|
||||
is_persistent
|
||||
)
|
||||
.fetch_one(pool)
|
||||
.await
|
||||
.context("Failed to insert cell")
|
||||
}
|
52
src/models/file.rs
Normal file
52
src/models/file.rs
Normal file
@ -0,0 +1,52 @@
|
||||
use anyhow::{Context, Result};
|
||||
use chrono::NaiveDateTime;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct File {
|
||||
pub id: i32,
|
||||
pub name: String,
|
||||
pub file_name: String,
|
||||
pub nexus_file_id: i32,
|
||||
pub mod_id: i32,
|
||||
pub category: Option<String>,
|
||||
pub version: Option<String>,
|
||||
pub mod_version: Option<String>,
|
||||
pub uploaded_at: NaiveDateTime,
|
||||
pub updated_at: NaiveDateTime,
|
||||
pub created_at: NaiveDateTime,
|
||||
}
|
||||
|
||||
pub async fn insert_file(
|
||||
pool: &sqlx::Pool<sqlx::Postgres>,
|
||||
name: &str,
|
||||
file_name: &str,
|
||||
nexus_file_id: i32,
|
||||
mod_id: i32,
|
||||
category: Option<&str>,
|
||||
version: Option<&str>,
|
||||
mod_version: Option<&str>,
|
||||
uploaded_at: NaiveDateTime,
|
||||
) -> Result<File> {
|
||||
sqlx::query_as!(
|
||||
File,
|
||||
"INSERT INTO files
|
||||
(name, file_name, nexus_file_id, mod_id, category, version, mod_version, uploaded_at, created_at, updated_at)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, now(), now())
|
||||
ON CONFLICT (mod_id, nexus_file_id) DO UPDATE
|
||||
SET (name, file_name, category, version, mod_version, uploaded_at, updated_at) =
|
||||
(EXCLUDED.name, EXCLUDED.file_name, EXCLUDED.category, EXCLUDED.version, EXCLUDED.mod_version, EXCLUDED.uploaded_at, now())
|
||||
RETURNING *",
|
||||
name,
|
||||
file_name,
|
||||
nexus_file_id,
|
||||
mod_id,
|
||||
category,
|
||||
version,
|
||||
mod_version,
|
||||
uploaded_at
|
||||
)
|
||||
.fetch_one(pool)
|
||||
.await
|
||||
.context("Failed to insert file")
|
||||
}
|
32
src/models/game.rs
Normal file
32
src/models/game.rs
Normal file
@ -0,0 +1,32 @@
|
||||
use anyhow::{Context, Result};
|
||||
use chrono::NaiveDateTime;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct Game {
|
||||
pub id: i32,
|
||||
pub name: String,
|
||||
pub nexus_game_id: i32,
|
||||
pub updated_at: NaiveDateTime,
|
||||
pub created_at: NaiveDateTime,
|
||||
}
|
||||
|
||||
pub async fn insert_game(
|
||||
pool: &sqlx::Pool<sqlx::Postgres>,
|
||||
name: &str,
|
||||
nexus_game_id: i32,
|
||||
) -> Result<Game> {
|
||||
sqlx::query_as!(
|
||||
Game,
|
||||
"INSERT INTO games
|
||||
(name, nexus_game_id, created_at, updated_at)
|
||||
VALUES ($1, $2, now(), now())
|
||||
ON CONFLICT (nexus_game_id, name) DO UPDATE SET (name, updated_at) = (EXCLUDED.name, now())
|
||||
RETURNING *",
|
||||
name,
|
||||
nexus_game_id
|
||||
)
|
||||
.fetch_one(pool)
|
||||
.await
|
||||
.context("Failed to insert game")
|
||||
}
|
60
src/models/game_mod.rs
Normal file
60
src/models/game_mod.rs
Normal file
@ -0,0 +1,60 @@
|
||||
use anyhow::{Context, Result};
|
||||
use chrono::NaiveDateTime;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct Mod {
|
||||
pub id: i32,
|
||||
pub name: String,
|
||||
pub nexus_mod_id: i32,
|
||||
pub author: String,
|
||||
pub category: String,
|
||||
pub description: Option<String>,
|
||||
pub game_id: i32,
|
||||
pub updated_at: NaiveDateTime,
|
||||
pub created_at: NaiveDateTime,
|
||||
}
|
||||
|
||||
pub async fn get_mod_by_nexus_mod_id(
|
||||
pool: &sqlx::Pool<sqlx::Postgres>,
|
||||
nexus_mod_id: i32,
|
||||
) -> Result<Option<Mod>> {
|
||||
sqlx::query_as!(
|
||||
Mod,
|
||||
"SELECT * FROM mods WHERE nexus_mod_id = $1",
|
||||
nexus_mod_id,
|
||||
)
|
||||
.fetch_optional(pool)
|
||||
.await
|
||||
.context("Failed to get mod")
|
||||
}
|
||||
|
||||
pub async fn insert_mod(
|
||||
pool: &sqlx::Pool<sqlx::Postgres>,
|
||||
name: &str,
|
||||
nexus_mod_id: i32,
|
||||
author: &str,
|
||||
category: &str,
|
||||
description: Option<&str>,
|
||||
game_id: i32,
|
||||
) -> Result<Mod> {
|
||||
sqlx::query_as!(
|
||||
Mod,
|
||||
"INSERT INTO mods
|
||||
(name, nexus_mod_id, author, category, description, game_id, created_at, updated_at)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, now(), now())
|
||||
ON CONFLICT (game_id, nexus_mod_id) DO UPDATE
|
||||
SET (name, author, category, description, updated_at) =
|
||||
(EXCLUDED.name, EXCLUDED.author, EXCLUDED.category, EXCLUDED.description, now())
|
||||
RETURNING *",
|
||||
name,
|
||||
nexus_mod_id,
|
||||
author,
|
||||
category,
|
||||
description,
|
||||
game_id
|
||||
)
|
||||
.fetch_one(pool)
|
||||
.await
|
||||
.context("Failed to insert or update mod")
|
||||
}
|
6
src/models/mod.rs
Normal file
6
src/models/mod.rs
Normal file
@ -0,0 +1,6 @@
|
||||
pub mod cell;
|
||||
pub mod file;
|
||||
pub mod game;
|
||||
pub mod game_mod;
|
||||
pub mod plugin;
|
||||
pub mod plugin_cell;
|
49
src/models/plugin.rs
Normal file
49
src/models/plugin.rs
Normal file
@ -0,0 +1,49 @@
|
||||
use anyhow::{Context, Result};
|
||||
use chrono::NaiveDateTime;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct Plugin {
|
||||
pub id: i32,
|
||||
pub name: String,
|
||||
pub hash: i64,
|
||||
pub file_id: i32,
|
||||
pub version: Option<f64>,
|
||||
pub author: Option<String>,
|
||||
pub description: Option<String>,
|
||||
pub masters: Option<Vec<String>>,
|
||||
pub updated_at: NaiveDateTime,
|
||||
pub created_at: NaiveDateTime,
|
||||
}
|
||||
|
||||
pub async fn insert_plugin(
|
||||
pool: &sqlx::Pool<sqlx::Postgres>,
|
||||
name: &str,
|
||||
hash: i64,
|
||||
file_id: i32,
|
||||
version: Option<f64>,
|
||||
author: Option<&str>,
|
||||
description: Option<&str>,
|
||||
masters: Option<&[String]>,
|
||||
) -> Result<Plugin> {
|
||||
sqlx::query_as!(
|
||||
Plugin,
|
||||
"INSERT INTO plugins
|
||||
(name, hash, file_id, version, author, description, masters, created_at, updated_at)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, now(), now())
|
||||
ON CONFLICT (file_id, name) DO UPDATE
|
||||
SET (hash, version, author, description, masters, updated_at) =
|
||||
(EXCLUDED.hash, EXCLUDED.version, EXCLUDED.author, EXCLUDED.description, EXCLUDED.masters, now())
|
||||
RETURNING *",
|
||||
name,
|
||||
hash,
|
||||
file_id,
|
||||
version,
|
||||
author,
|
||||
description,
|
||||
masters
|
||||
)
|
||||
.fetch_one(pool)
|
||||
.await
|
||||
.context("Failed to insert plugin")
|
||||
}
|
36
src/models/plugin_cell.rs
Normal file
36
src/models/plugin_cell.rs
Normal file
@ -0,0 +1,36 @@
|
||||
use anyhow::{Context, Result};
|
||||
use chrono::NaiveDateTime;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct PluginCell {
|
||||
pub id: i32,
|
||||
pub plugin_id: i32,
|
||||
pub cell_id: i32,
|
||||
pub editor_id: Option<String>,
|
||||
pub updated_at: NaiveDateTime,
|
||||
pub created_at: NaiveDateTime,
|
||||
}
|
||||
|
||||
pub async fn insert_plugin_cell(
|
||||
pool: &sqlx::Pool<sqlx::Postgres>,
|
||||
plugin_id: i32,
|
||||
cell_id: i32,
|
||||
editor_id: Option<String>,
|
||||
) -> Result<PluginCell> {
|
||||
sqlx::query_as!(
|
||||
PluginCell,
|
||||
"INSERT INTO plugin_cells
|
||||
(plugin_id, cell_id, editor_id, created_at, updated_at)
|
||||
VALUES ($1, $2, $3, now(), now())
|
||||
ON CONFLICT (plugin_id, cell_id) DO UPDATE
|
||||
SET (editor_id, updated_at) = (EXCLUDED.editor_id, now())
|
||||
RETURNING *",
|
||||
plugin_id,
|
||||
cell_id,
|
||||
editor_id,
|
||||
)
|
||||
.fetch_one(pool)
|
||||
.await
|
||||
.context("Failed to insert cell")
|
||||
}
|
Loading…
Reference in New Issue
Block a user