sphericle / TheClicksyncChallengeList

now open source!
MIT License
1 stars 1 forks source link

add ability to remove / hide levels #6

Closed sphericle closed 2 months ago

sphericle commented 2 months ago

this issue should have been closed and opened like 6 different times, i keep finding leads that eventually turn into nothing or the most impossible task ever. but i think i finally figured out what i need to do!

the demon table in the database has a few constraints, meaning a demon has to exist for other things to exist, being the demon's creators and records. the records should be self explanatory, there's already a working function in the code that deletes a record. here is the plan for the creators:

the creators table has two columns: player and demon. think of this table has a "link" between a player and a demon, which denotes a creator. so we need to delete each row with a "demon" value that matches the id of the demon which we want to delete. remember that demons can have more than one creator, so we must delete ALL creator links that match the ID of the demon.

records are self explanatory, just copy paste the code that deletes records and modify it so that it can delete each record linked to the demon we're trying to delete, and we're golden.

we need to remember that these processes need to be asynchronous, so that we don't try to delete the demon before the records are finished being deleted, for example.

pray 🙏

sphericle commented 2 months ago

wrote the code to have the server delete the demon from the database, we need to now get the api to send that request to the server. prolly just copy the code for the record lol. oh and also make sure this all actually works and doesn't have a bunch of errors! :D

sphericle commented 2 months ago

i think the move is to work from the ground up, from here to adding the "delete" button

sphericle commented 2 months ago

pointercrate-demonlist/src/demon/delete.rs

use crate::{
    demon::MinimalDemon,
    error::Result,
};
use log::info;
use sqlx::PgConnection;

impl MinimalDemon {
    /// Must be run within a transaction!
    pub async fn delete_demon(self, connection: &mut PgConnection) -> Result<()> {
        info!("Deleting demon {}", self);

        MinimalDemon::delete_by_id(self.id, &mut *connection).await?;

        Ok(())
    }

    pub async fn delete_by_id(demon_id: i32, connection: &mut PgConnection) -> Result<()> {

        sqlx::query!("DELETE FROM demons WHERE id = $1", demon_id)
            .execute(connection)
            .await?;

        Ok(())
    }
}
sphericle commented 2 months ago

api endpoint should also work

#[rocket::delete("/<demon_id>")]
pub async fn delete_demon_data(demon_id: i32, mut auth: TokenAuth) -> Result<Status> {
    auth.require_permission(LIST_MODERATOR)?;

    let demon = MinimalDemon::by_id(demon_id, &mut auth.connection).await?;

    MinimalDemon::by_id(demon.id, &mut auth.connection)
        .await?
        .delete_demon(&mut auth.connection)
        .await?;

    auth.commit().await?;

    Ok(Status::NoContent)
}
sphericle commented 2 months ago

button now works! i also got the api to delete the associated creators and records to avoid any fkey issues. the only issue now is that the site is trying to run the function that sends a delete request, for every demon.

sphericle commented 2 months ago

probably demonManager.currentObject.id instead of currentObject.id

sphericle commented 2 months ago

also make sure everyone's scores are regenerated after deleting the level

sphericle commented 2 months ago

also we should move all the records on a demon to a new table in the db. shouldn't be too hard

sphericle commented 2 months ago

ok so the record backup thing can be done, but the code sucks lol. i dont really care. the issue with the scores thing is we need to regen the scores for every player with a record on the list, as well as the verifier.

sphericle commented 2 months ago

i can't wait for this to run so slowly LMAO

sphericle commented 2 months ago

but the code sucks lol.

nvm the code that sucked doesnt work lol! oops.

sphericle commented 2 months ago

alr! the issue rn is the code to backup the records to a separate table records_backup. the query theoretically should look like:


sqlx::query!("
            INSERT INTO records_backup (id, progress, video, status_, player, submitter, demon, raw_footage, demon_name) SELECT id, progress, video, status_, player, submitter, demon, raw_footage, $2 FROM records WHERE demon = $1;
            ", demon_id, demon_name // working variables)
            .execute(&mut *connection)
            .await?;

if we swap out the variables used in the query with dummy data (no $1 or $2), it works fine, so the issue is how we're substituting these values with variables. either its the wrong syntax (and rust analyzer doesn't find that for some reason) or something with the database's data types. idk!

sphericle commented 2 months ago

it is probably data types, as inserting the demon name into the demons table explicitly sets the type to text, it's probably $2::text, demon_id, demon_name

sphericle commented 2 months ago

also for the x button running multiple times, copy the code from the delete record note button


closeX.addEventListener("click", () => {
      if (confirm("This action will irrevocably delete this note. Proceed?")) {
        del(
          "/api/v1/records/" +
            recordManager.currentObject.id +
            "/notes/" +
            note.id +
            "/"
        ).then(() => noteDiv.parentElement.removeChild(noteDiv));
      }
    });

^^ closeX is created in scope and not in the webpage code

sphericle commented 2 months ago

it is probably data types, as inserting the demon name into the demons table explicitly sets the type to text, it's probably $2::text, demon_id, demon_name

lmfao its litearlly just because the records table is linked which i guess means the data has to mostly sync up LOL?!

sphericle commented 2 months ago

should probably use transactions for this just incase the records fail to back up. also fix the error message not showing up lol

sphericle commented 2 months ago

auth should also be ok

sphericle commented 2 months ago

copy the code from the delete record note button

yeah this is already how it is, idk man! let's just make it more similar to the delete note / record javascript

sphericle commented 2 months ago

oki the update_score function does not need the specific player passed into it, so we can just run it once. the issue on stream was that we cant access the function, but this is just me being dumb! declare a variable "record" which leads somehow to FullRecord, because we know FullRecord can lead to DatabasePlayer. or just set the variable equal to DatabasePlayer!

sphericle commented 2 months ago

i'm really dumb. i blame rust.

DatabasePlayer::update_score(connection)

sphericle commented 2 months ago

oki the update_score function does not need the specific player passed into it

yes it does. it needs DatabasePlayer to get the id of the player. LOL! shouldn't be a problem though, we just need to run that code for each player with a record on the demon we're deleting. now that i think of it, just copy paste whatever the function that changes the position does lmao.

sphericle commented 2 months ago

never mind! it's recompute_scores()! well that makes my life easier

sphericle commented 2 months ago

we're very close, the main functionality is done but im just gonna do some testing to make sure everything works properly

sphericle commented 2 months ago

hell yeah! and i made the deadline too.