Skip to content

Commit 5f219ac

Browse files
authored
Merge pull request #18 from Virtual-Repetitions/improve-ownership
ownership tracking
2 parents bc8a727 + 67ee522 commit 5f219ac

1 file changed

Lines changed: 75 additions & 2 deletions

File tree

crates/postgres-subsystem/postgres-graphql-resolver/src/create_data_param_mapper.rs

Lines changed: 75 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@ async fn map_single<'a>(
109109
subsystem: &'a PostgresGraphQLSubsystem,
110110
request_context: &'a RequestContext<'a>,
111111
) -> Result<(InsertionRow, Vec<AbstractPredicate>), PostgresExecutionError> {
112+
let enriched_argument = enrich_argument_for_access(data_type, argument, subsystem);
113+
let access_input_value = enriched_argument.as_ref().unwrap_or(argument);
112114
let AccessCheckOutcome {
113115
precheck_predicate, ..
114116
} = check_access(
@@ -118,9 +120,9 @@ async fn map_single<'a>(
118120
subsystem,
119121
request_context,
120122
Some(&AccessInput {
121-
value: argument,
123+
value: access_input_value,
122124
ignore_missing_value: true,
123-
aliases: HashMap::new(),
125+
aliases: Default::default(),
124126
}),
125127
)
126128
.await?;
@@ -201,6 +203,77 @@ async fn map_single<'a>(
201203
Ok((InsertionRow { elems: row? }, vec![precheck_predicate]))
202204
}
203205

206+
fn enrich_argument_for_access(
207+
data_type: &MutationType,
208+
argument: &Val,
209+
subsystem: &PostgresGraphQLSubsystem,
210+
) -> Option<Val> {
211+
let argument_object = match argument {
212+
Val::Object(map) => map,
213+
_ => return None,
214+
};
215+
216+
let mut column_to_field: HashMap<ColumnId, &str> = HashMap::new();
217+
for field in &data_type.fields {
218+
if let PostgresRelation::Scalar { column_id, .. } = &field.relation {
219+
column_to_field.insert(*column_id, field.name.as_str());
220+
}
221+
}
222+
223+
let mut enriched = argument_object.clone();
224+
let mut modified = false;
225+
226+
for field in &data_type.fields {
227+
if enriched.contains_key(&field.name) {
228+
continue;
229+
}
230+
231+
if let PostgresRelation::ManyToOne { relation, .. } = &field.relation {
232+
let relation_details = relation
233+
.relation_id
234+
.deref(&subsystem.core_subsystem.database);
235+
236+
let mut related_fields: HashMap<String, Val> = HashMap::new();
237+
238+
for (pair, pk_field_id) in relation_details
239+
.column_pairs
240+
.iter()
241+
.zip(relation.foreign_pk_field_ids.iter())
242+
{
243+
let fk_field_name = match column_to_field.get(&pair.self_column_id) {
244+
Some(name) => *name,
245+
None => {
246+
related_fields.clear();
247+
break;
248+
}
249+
};
250+
251+
let fk_value = match argument_object.get(fk_field_name) {
252+
Some(value) => value.clone(),
253+
None => {
254+
related_fields.clear();
255+
break;
256+
}
257+
};
258+
259+
let pk_field = pk_field_id.resolve(&subsystem.core_subsystem.entity_types);
260+
related_fields.insert(pk_field.name.clone(), fk_value);
261+
}
262+
263+
if !related_fields.is_empty() {
264+
enriched.insert(field.name.clone(), Val::Object(related_fields));
265+
modified = true;
266+
}
267+
}
268+
}
269+
270+
if modified {
271+
Some(Val::Object(enriched))
272+
} else {
273+
None
274+
}
275+
}
276+
204277
async fn map_self_column<'a>(
205278
key_column_id: ColumnId,
206279
field: &'a PostgresField<MutationType>,

0 commit comments

Comments
 (0)