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 unrar::Archive;
|
||||||
use zip::write::{FileOptions, ZipWriter};
|
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 USER_AGENT: &str = "mod-mapper/0.1";
|
||||||
static GAME_NAME: &str = "skyrimspecialedition";
|
static GAME_NAME: &str = "skyrimspecialedition";
|
||||||
const GAME_ID: u32 = 1704;
|
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>> {
|
fn rate_limit_wait_duration(res: &Response) -> Result<Option<std::time::Duration>> {
|
||||||
let daily_remaining = res
|
let daily_remaining = res
|
||||||
.headers()
|
.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