mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Merge branch 'xvar/move-waypoint-persistence-to-stats-table' into 'master'
Moved waypoint persistence to new waypoint column on stats table See merge request veloren/veloren!1531
This commit is contained in:
commit
43c81b3dd6
@ -0,0 +1,38 @@
|
||||
-- Put waypoint data back into item table
|
||||
UPDATE item
|
||||
SET position = ( SELECT s.waypoint
|
||||
FROM stats s
|
||||
WHERE s.stats_id = item.item_id
|
||||
AND item.item_definition_id = 'veloren.core.pseudo_containers.character'
|
||||
AND s.waypoint IS NOT NULL)
|
||||
WHERE EXISTS ( SELECT s.waypoint
|
||||
FROM stats s
|
||||
WHERE s.stats_id = item.item_id
|
||||
AND item.item_definition_id = 'veloren.core.pseudo_containers.character'
|
||||
AND s.waypoint IS NOT NULL);
|
||||
|
||||
-- SQLite does not support dropping columns on tables so the entire table must be
|
||||
-- dropped and recreated without the 'waypoint' column
|
||||
CREATE TABLE stats_new
|
||||
(
|
||||
stats_id INT NOT NULL
|
||||
PRIMARY KEY
|
||||
REFERENCES entity,
|
||||
level INT NOT NULL,
|
||||
exp INT NOT NULL,
|
||||
endurance INT NOT NULL,
|
||||
fitness INT NOT NULL,
|
||||
willpower INT NOT NULL
|
||||
);
|
||||
|
||||
INSERT INTO stats_new (stats_id, level, exp, endurance, fitness, willpower)
|
||||
SELECT stats_id,
|
||||
level,
|
||||
exp,
|
||||
endurance,
|
||||
fitness,
|
||||
willpower
|
||||
FROM stats;
|
||||
|
||||
DROP TABLE stats;
|
||||
ALTER TABLE stats_new RENAME TO stats;
|
@ -0,0 +1,21 @@
|
||||
-- Add a 'waypoint' column to the 'stats' table
|
||||
ALTER TABLE stats ADD COLUMN waypoint TEXT NULL;
|
||||
|
||||
-- Move any waypoints persisted into the item.position column into the new stats.waypoint column
|
||||
UPDATE stats
|
||||
SET waypoint = ( SELECT i.position
|
||||
FROM item i
|
||||
WHERE i.item_id = stats.stats_id
|
||||
AND i.position != i.item_id
|
||||
AND i.item_definition_id = 'veloren.core.pseudo_containers.character')
|
||||
WHERE EXISTS ( SELECT i.position
|
||||
FROM item i
|
||||
WHERE i.item_id = stats.stats_id
|
||||
AND i.position != i.item_id
|
||||
AND i.item_definition_id = 'veloren.core.pseudo_containers.character');
|
||||
|
||||
-- Reset the 'item.position' column value for character pseudo-containers to the character id to
|
||||
-- remove old waypoint data that has now been migrated to stats
|
||||
UPDATE item
|
||||
SET position = item_id
|
||||
WHERE item_definition_id = 'veloren.core.pseudo_containers.character';
|
@ -15,23 +15,21 @@ use crate::{
|
||||
convert_character_from_database, convert_inventory_from_database_items,
|
||||
convert_items_to_database_items, convert_loadout_from_database_items,
|
||||
convert_stats_from_database, convert_stats_to_database,
|
||||
convert_waypoint_to_database_json,
|
||||
convert_waypoint_from_database_json,
|
||||
},
|
||||
character_loader::{CharacterCreationResult, CharacterDataResult, CharacterListResult},
|
||||
error::Error::DatabaseError,
|
||||
json_models::CharacterPosition,
|
||||
PersistedComponents,
|
||||
},
|
||||
};
|
||||
use common::{
|
||||
character::{CharacterId, CharacterItem, MAX_CHARACTERS_PER_PLAYER},
|
||||
comp::item::tool::AbilityMap,
|
||||
state::Time,
|
||||
};
|
||||
use core::ops::Range;
|
||||
use diesel::{prelude::*, sql_query, sql_types::BigInt};
|
||||
use std::sync::Arc;
|
||||
use tracing::{error, trace};
|
||||
use tracing::{error, trace, warn};
|
||||
|
||||
/// Private module for very tightly coupled database conversion methods. In
|
||||
/// general, these have many invariants that need to be maintained when they're
|
||||
@ -90,22 +88,27 @@ pub fn load_character_data(
|
||||
.filter(schema::body::dsl::body_id.eq(char_id))
|
||||
.first::<Body>(&*connection)?;
|
||||
|
||||
let waypoint = item
|
||||
.filter(item_id.eq(char_id))
|
||||
.first::<Item>(&*connection)
|
||||
.ok()
|
||||
.and_then(|it: Item| {
|
||||
(serde_json::de::from_str::<CharacterPosition>(it.position.as_str()))
|
||||
.ok()
|
||||
.map(|charpos| comp::Waypoint::new(charpos.waypoint, Time(0.0)))
|
||||
});
|
||||
let char_waypoint =
|
||||
stats_data
|
||||
.waypoint
|
||||
.as_ref()
|
||||
.and_then(|x| match convert_waypoint_from_database_json(&x) {
|
||||
Ok(w) => Some(w),
|
||||
Err(e) => {
|
||||
warn!(
|
||||
"Error reading waypoint from database for character ID {}, error: {}",
|
||||
char_id, e
|
||||
);
|
||||
None
|
||||
},
|
||||
});
|
||||
|
||||
Ok((
|
||||
convert_body_from_database(&char_body)?,
|
||||
convert_stats_from_database(&stats_data, character_data.alias),
|
||||
convert_inventory_from_database_items(&inventory_items)?,
|
||||
convert_loadout_from_database_items(&loadout_items, map)?,
|
||||
waypoint,
|
||||
char_waypoint,
|
||||
))
|
||||
}
|
||||
|
||||
@ -186,17 +189,14 @@ pub fn create_character(
|
||||
let character_id = new_entity_ids.next().unwrap();
|
||||
let inventory_container_id = new_entity_ids.next().unwrap();
|
||||
let loadout_container_id = new_entity_ids.next().unwrap();
|
||||
// by default the character's position is the id in textual form
|
||||
let character_position = waypoint
|
||||
.and_then(|waypoint| serde_json::to_string(&waypoint.get_pos()).ok())
|
||||
.unwrap_or_else(|| character_id.to_string());
|
||||
|
||||
let pseudo_containers = vec![
|
||||
Item {
|
||||
stack_size: 1,
|
||||
item_id: character_id,
|
||||
parent_container_item_id: WORLD_PSEUDO_CONTAINER_ID,
|
||||
item_definition_id: CHARACTER_PSEUDO_CONTAINER_DEF_ID.to_owned(),
|
||||
position: character_position,
|
||||
position: character_id.to_string(),
|
||||
},
|
||||
Item {
|
||||
stack_size: 1,
|
||||
@ -225,7 +225,7 @@ pub fn create_character(
|
||||
}
|
||||
|
||||
// Insert stats record
|
||||
let db_stats = convert_stats_to_database(character_id, &stats);
|
||||
let db_stats = convert_stats_to_database(character_id, &stats, &waypoint)?;
|
||||
let stats_count = diesel::insert_into(stats::table)
|
||||
.values(&db_stats)
|
||||
.execute(&*connection)?;
|
||||
@ -535,7 +535,7 @@ pub fn update(
|
||||
char_stats: comp::Stats,
|
||||
inventory: comp::Inventory,
|
||||
loadout: comp::Loadout,
|
||||
waypoint: Option<comp::Waypoint>,
|
||||
char_waypoint: Option<comp::Waypoint>,
|
||||
connection: VelorenTransaction,
|
||||
) -> Result<Vec<Arc<common::comp::item::ItemId>>, Error> {
|
||||
use super::schema::{item::dsl::*, stats::dsl::*};
|
||||
@ -558,22 +558,6 @@ pub fn update(
|
||||
next_id
|
||||
})?;
|
||||
|
||||
if let Some(waypoint) = waypoint {
|
||||
match convert_waypoint_to_database_json(&waypoint) {
|
||||
Ok(character_position) => {
|
||||
diesel::update(item.filter(item_id.eq(char_id)))
|
||||
.set(position.eq(character_position))
|
||||
.execute(&*connection)?;
|
||||
},
|
||||
Err(err) => {
|
||||
return Err(Error::ConversionError(format!(
|
||||
"Error encoding waypoint: {:?}",
|
||||
err
|
||||
)));
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Next, delete any slots we aren't upserting.
|
||||
trace!("Deleting items for character_id {}", char_id);
|
||||
let existing_items = parent_container_item_id
|
||||
@ -617,7 +601,7 @@ pub fn update(
|
||||
}
|
||||
}
|
||||
|
||||
let db_stats = convert_stats_to_database(char_id, &char_stats);
|
||||
let db_stats = convert_stats_to_database(char_id, &char_stats, &char_waypoint)?;
|
||||
let stats_count = diesel::update(stats.filter(stats_id.eq(char_id)))
|
||||
.set(db_stats)
|
||||
.execute(&*connection)?;
|
||||
|
@ -9,8 +9,9 @@ use crate::persistence::{
|
||||
};
|
||||
use common::{
|
||||
character::CharacterId,
|
||||
comp::{item::tool::AbilityMap, Body as CompBody, *},
|
||||
comp::{item::tool::AbilityMap, Body as CompBody, Waypoint, *},
|
||||
loadout_builder,
|
||||
state::Time,
|
||||
};
|
||||
use core::{convert::TryFrom, num::NonZeroU64};
|
||||
use itertools::{Either, Itertools};
|
||||
@ -168,22 +169,44 @@ pub fn convert_body_to_database_json(body: &CompBody) -> Result<String, Error> {
|
||||
serde_json::to_string(&json_model).map_err(Error::SerializationError)
|
||||
}
|
||||
|
||||
pub fn convert_waypoint_to_database_json(waypoint: &Waypoint) -> Result<String, Error> {
|
||||
fn convert_waypoint_to_database_json(waypoint: &Waypoint) -> Result<String, Error> {
|
||||
let charpos = CharacterPosition {
|
||||
waypoint: waypoint.get_pos(),
|
||||
};
|
||||
serde_json::to_string(&charpos).map_err(Error::SerializationError)
|
||||
serde_json::to_string(&charpos)
|
||||
.map_err(|err| Error::ConversionError(format!("Error encoding waypoint: {:?}", err)))
|
||||
}
|
||||
|
||||
pub fn convert_stats_to_database(character_id: CharacterId, stats: &common::comp::Stats) -> Stats {
|
||||
Stats {
|
||||
pub fn convert_waypoint_from_database_json(position: &str) -> Result<Waypoint, Error> {
|
||||
let character_position =
|
||||
serde_json::de::from_str::<CharacterPosition>(position).map_err(|err| {
|
||||
Error::ConversionError(format!(
|
||||
"Error de-serializing waypoint: {} err: {}",
|
||||
position, err
|
||||
))
|
||||
})?;
|
||||
Ok(Waypoint::new(character_position.waypoint, Time(0.0)))
|
||||
}
|
||||
|
||||
pub fn convert_stats_to_database(
|
||||
character_id: CharacterId,
|
||||
stats: &common::comp::Stats,
|
||||
waypoint: &Option<common::comp::Waypoint>,
|
||||
) -> Result<Stats, Error> {
|
||||
let waypoint = match waypoint {
|
||||
Some(w) => Some(convert_waypoint_to_database_json(&w)?),
|
||||
None => None,
|
||||
};
|
||||
|
||||
Ok(Stats {
|
||||
stats_id: character_id,
|
||||
level: stats.level.level() as i32,
|
||||
exp: stats.exp.current() as i32,
|
||||
endurance: stats.endurance as i32,
|
||||
fitness: stats.fitness as i32,
|
||||
willpower: stats.willpower as i32,
|
||||
}
|
||||
waypoint,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn convert_inventory_from_database_items(database_items: &[Item]) -> Result<Inventory, Error> {
|
||||
|
@ -46,6 +46,7 @@ pub struct Stats {
|
||||
pub endurance: i32,
|
||||
pub fitness: i32,
|
||||
pub willpower: i32,
|
||||
pub waypoint: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Associations, Identifiable, Insertable, Queryable, Debug)]
|
||||
|
@ -38,6 +38,7 @@ table! {
|
||||
endurance -> Integer,
|
||||
fitness -> Integer,
|
||||
willpower -> Integer,
|
||||
waypoint -> Nullable<Text>,
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user