diff --git a/src/entity/gateway/postgres/migrations/V0001__initial.sql b/src/entity/gateway/postgres/migrations/V0001__initial.sql index c5805f1..1e5a925 100644 --- a/src/entity/gateway/postgres/migrations/V0001__initial.sql +++ b/src/entity/gateway/postgres/migrations/V0001__initial.sql @@ -79,9 +79,9 @@ create table item_location ( created_at timestamptz default current_timestamp not null ); -create table inventory_slots ( - pchar integer references player_character not null, - items integer[30] /* references item (id) */ +create table inventory_slot ( + item integer references item not null unique, + slot integer not null ); create table weapon_modifier ( diff --git a/src/entity/gateway/postgres/postgres.rs b/src/entity/gateway/postgres/postgres.rs index ffa11cd..965bcf4 100644 --- a/src/entity/gateway/postgres/postgres.rs +++ b/src/entity/gateway/postgres/postgres.rs @@ -172,7 +172,6 @@ impl EntityGateway for PostgresGateway { ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26, $27, $28, $29, $30, $31) returning *;"#; let character = sqlx::query_as::<_, PgCharacter>(q) - //sqlx::query(q) .bind(char.user_id.0) .bind(char.slot as i16) .bind(char.name) @@ -206,9 +205,6 @@ impl EntityGateway for PostgresGateway { .bind(char.option_flags as i32) .fetch_one(&self.pool).await?; - sqlx::query("insert into inventory_slots (pchar) values ($1)") - .bind(character.id) - .execute(&self.pool).await?; Ok(character.into()) } @@ -280,23 +276,22 @@ impl EntityGateway for PostgresGateway { let new_item = sqlx::query_as::<_, PgItem>("insert into item (item) values ($1) returning *;") .bind(sqlx::types::Json(PgItemDetail::from(item.item))) .fetch_one(&mut tx).await?; - let location = if let ItemLocation::Inventory{character_id, slot, ..} = &item.location { + let location = if let ItemLocation::Inventory{slot, ..} = &item.location { sqlx::query("insert into item_location (item, location) values ($1, $2)") .bind(new_item.id) .bind(sqlx::types::Json(PgItemLocationDetail::from(item.location.clone()))) .execute(&mut tx).await?; - sqlx::query("update inventory_slots set items[$2] = $1 where pchar = $3") + sqlx::query("insert into inventory_slot (item, slot) values ($1, $2)") .bind(new_item.id) .bind(*slot as i32) - .bind(character_id.0 as i32) .execute(&mut tx).await?; sqlx::query_as::<_, PgItemLocation>(r#"select item_location.item, - jsonb_set(item_location.location, '{Inventory,slot}', (array_position(inventory_slots.items, item.id))::text::jsonb) as location, + jsonb_set(item_location.location, '{Inventory,slot}', inventory_slot.slot::text::jsonb) as location, item_location.created_at from item_location join item on item.id = item_location.item - join inventory_slots on inventory_slots.pchar = cast (item_location.location -> 'Inventory' ->> 'character_id' as integer) + join inventory_slot on inventory_slot.item = item.id where item.id = $1 order by item_location.created_at limit 1"#) @@ -319,15 +314,13 @@ impl EntityGateway for PostgresGateway { async fn change_item_location(&mut self, item_id: &ItemEntityId, item_location: ItemLocation) -> Result<(), GatewayError> { let mut tx = self.pool.begin().await?; - if let ItemLocation::Inventory{character_id, slot, ..} = &item_location { - sqlx::query("update inventory_slots set items[array_position(items, $1)] = null where pchar = $2 and items[array_position(items, $1)] is not null") + if let ItemLocation::Inventory{slot, ..} = &item_location { + sqlx::query("delete from inventory_slot where item = $1") .bind(item_id.0 as i32) - .bind(character_id.0 as i32) .execute(&mut tx).await?; - sqlx::query("update inventory_slots set items[$2] = $1 where pchar = $3") - .bind(item_id.0 as i32) + sqlx::query("insert into inventory_slot (item, slot) values ($1, $2)") + .bind(item_id.0) .bind(*slot as i32) - .bind(character_id.0 as i32) .execute(&mut tx).await?; sqlx::query(r#"insert into item_location (item, location) select $1, $2 @@ -377,14 +370,14 @@ impl EntityGateway for PostgresGateway { item.id, case when item_location.location -> 'Inventory' is not null then - jsonb_set(item_location.location, '{Inventory,slot}', (array_position(inventory_slots.items, item.id))::text::jsonb) + jsonb_set(item_location.location, '{Inventory,slot}', inventory_slot.slot::text::jsonb) else item_location.location end, item.item from item_location join item on item.id = item_location.item - join inventory_slots on inventory_slots.pchar = $1 + join inventory_slot on inventory_slot.item = item.id order by item_location.item, item_location.created_at desc ) as i where cast (location -> 'Inventory' ->> 'character_id' as integer) = $1