Skip to content
Extraits de code Groupes Projets
Vérifiée Valider 2cbbf827 rédigé par Kubat's avatar Kubat
Parcourir les fichiers

[WIP] RUST-DB: Try to experiment by first making simple requests and building things around

parent 96a03996
Aucune branche associée trouvée
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
Pipeline #3303 en échec
......@@ -10,4 +10,5 @@ crate-type = [ "staticlib" ]
log = "0.4"
libc = "0.2.0"
diesel_migrations = "2"
diesel = { version = "2", default-features = false, features = [ "sqlite" ] }
diesel = { version = "2", default-features = false, features = [ "sqlite" ] }
serde = { version = "^1", default-features = false, features = [ "std", "derive" ] }
......@@ -24,7 +24,7 @@ CREATE TABLE kara
, song_origin TEXT NOT NULL
, source_name TEXT NOT NULL
, language TEXT NOT NULL REFERENCES iso_639_1(code)
, kara_hash TEXT NOT NULL -- TEXT ABOVE + HASH OF FILE IN FS
, file_hash TEXT NOT NULL
);
-- We can have multiple kara makers for one kara.
......
......@@ -8,6 +8,10 @@ pub mod models;
pub mod schema;
pub mod unsafe_interface;
use self::models::*;
use crate::{database::schema::kara_tags, kurisu_api::v1 as api_v1};
/// The migrations!
const MIGRATIONS: EmbeddedMigrations = embed_migrations!();
......@@ -25,3 +29,68 @@ pub fn establish_connection(path: impl AsRef<str>) -> Result<SqliteConnection, S
self::run_migration(&mut conn)?;
Ok(conn)
}
/// All the information needed to add a kara recieved from a repo!
pub type NewKaraRequest<'a> = (
models::NewKaraId,
models::NewKara<'a>,
models::NewLanguage<'a>,
Vec<models::AddKaraMaker<'a>>,
Vec<models::AddKaraTag>,
);
pub struct LktDatabaseConnection {
sqlite: SqliteConnection,
}
impl LktDatabaseConnection {
/// Get a tag id by its name.
pub fn get_tag_id_by_name(&mut self, tag_name: impl AsRef<str>) -> i32 {
use self::schema::tag::dsl::*;
tag.filter(name.is(tag_name.as_ref()))
.first::<Tag>(&mut self.sqlite)
.unwrap()
.id
}
/// Get a free local id for all karas.
pub fn get_kara_new_local_id(&mut self) -> i32 {
use self::schema::kara::dsl::*;
use diesel::dsl::*;
kara.select(max(id))
.first::<Option<i32>>(&mut self.sqlite)
.unwrap()
.unwrap_or(0)
}
/// Create a series of models from a kara signature from Kurisu's V1 API.
pub fn new_kara<'a>(&mut self, repo_id: u64, kara: api_v1::Kara<'a>) -> NewKaraRequest<'a> {
error!("todo: query the database for a new local id");
let local_id = self.get_kara_new_local_id();
let id = NewKaraId {
repo_id: repo_id as i32,
local_kara_id: local_id as i32,
repo_kara_id: kara.id as i32,
};
let lang = NewLanguage::from(kara.get_language());
let kara_makers = vec![AddKaraMaker {
id: local_id as i32,
name: kara.author_name,
}];
let tags = vec![AddKaraTag {
kara_id: local_id as i32,
tag_id: self.get_tag_id_by_name("number"),
value: Some(format!("{}", kara.song_number)),
}];
let kara = NewKara {
id: local_id as i32,
song_title: kara.song_name,
song_type: kara.song_type,
song_origin: kara.category,
source_name: kara.source_name,
language: lang.code,
file_hash: format!("{}", kara.unix_timestamp),
};
(id, kara, lang, kara_makers, tags)
}
}
//! Models used for querying, inserting or updating the database.
use crate::database::{schema::*, *};
use crate::{
database::{schema::*, *},
kurisu_api::v1 as api_v1,
};
// First the insertable things
#[derive(Insertable)]
#[diesel(table_name = repo)]
pub struct NewRepo<'a> {
pub id: i32,
pub name: &'a str,
}
#[derive(Insertable)]
#[diesel(table_name = repo_kara)]
pub struct NewKaraId {
pub repo_id: i32,
pub repo_kara_id: i32,
pub local_kara_id: i32,
}
#[derive(Insertable)]
#[diesel(table_name = kara)]
pub struct NewKara<'a> {
pub id: i32,
pub song_title: &'a str,
pub song_type: &'a str,
pub song_origin: &'a str,
pub source_name: &'a str,
pub language: &'a str,
pub file_hash: String,
}
#[derive(Insertable)]
#[diesel(table_name = kara_makers)]
pub struct AddKaraMaker<'a> {
pub id: i32,
pub name: &'a str,
}
#[derive(Insertable)]
#[diesel(table_name = iso_639_1)]
pub struct NewLanguage<'a> {
pub code: &'a str,
pub name_en: &'a str,
pub is_iso: bool,
pub is_macro: bool,
}
#[derive(Insertable)]
#[diesel(table_name = kara_tags)]
pub struct AddKaraTag {
pub kara_id: i32,
pub tag_id: i32,
pub value: Option<String>,
}
impl<'a> From<api_v1::Language<'a>> for NewLanguage<'a> {
fn from(lang: api_v1::Language<'a>) -> Self {
Self {
code: lang.code,
name_en: lang.code,
is_iso: false,
is_macro: false,
}
}
}
// Then the queriable things
#[derive(Queryable)]
#[diesel(table_name = tag)]
pub struct Tag {
pub id: i32,
pub name: String,
}
......@@ -25,7 +25,7 @@ diesel::table! {
song_origin -> Text,
source_name -> Text,
language -> Text,
kara_hash -> Text,
file_hash -> Text,
}
}
......
......@@ -12,7 +12,7 @@ use std::mem::ManuallyDrop;
#[no_mangle]
pub unsafe extern "C" fn lkt_database_establish_connection(
path: *const u8,
) -> *mut SqliteConnection {
) -> *mut LktDatabaseConnection {
let mut path_len = 0;
while *path.offset(path_len) != 0 {
path_len += 1
......@@ -20,7 +20,7 @@ pub unsafe extern "C" fn lkt_database_establish_connection(
let len = path_len as usize;
let path = ManuallyDrop::new(String::from_raw_parts(path as *mut _, len, len));
match establish_connection(&path[..]) {
Ok(conn) => Box::leak(Box::new(conn)) as *mut _,
Ok(conn) => Box::leak(Box::new(LktDatabaseConnection { sqlite: conn })) as *mut _,
Err(err) => {
error!("failed to establish connexion to {}: {err}", &path[..]);
std::ptr::null_mut()
......@@ -33,7 +33,7 @@ pub unsafe extern "C" fn lkt_database_establish_connection(
/// passed pointer was not obtained by the correct function the behaviour is
/// undefined.
#[no_mangle]
pub unsafe extern "C" fn lkt_database_close_connection(db: *mut SqliteConnection) {
pub unsafe extern "C" fn lkt_database_close_connection(db: *mut LktDatabaseConnection) {
if db == std::ptr::null_mut() {
error!("can't clost a connexion to a null database!")
} else {
......
pub mod v1;
use serde::Deserialize;
#[derive(Debug, Deserialize)]
pub struct Kara<'a> {
pub id: u64,
pub source_name: &'a str,
pub song_name: &'a str,
pub song_type: &'a str,
pub song_number: u64,
pub category: &'a str,
pub language: &'a str,
pub author_name: &'a str,
pub author_year: &'a str,
pub is_new: u64,
pub upload_comment: &'a str,
pub popularity: u64,
pub unix_timestamp: u64,
pub size: u64,
}
#[derive(Debug, Deserialize)]
pub struct Language<'a> {
pub code: &'a str,
}
impl<'a> Kara<'a> {
/// Get the language out of a kara
pub fn get_language(&self) -> Language<'a> {
Language {
code: self.language,
}
}
}
......@@ -2,6 +2,7 @@
mod compat;
mod database;
pub mod kurisu_api;
mod module;
pub(crate) use compat::*;
......
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Terminez d'abord l'édition de ce message.
Veuillez vous inscrire ou vous pour commenter