Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion stdlib/examples/produce-exchange/serverActor.as
Original file line number Diff line number Diff line change
Expand Up @@ -625,7 +625,24 @@ actor server = {
cost: Price,
ttid: TruckTypeId
) : async ?RouteId {
getModel().transporterAddRoute(trans, rstart, rend, start, end, cost, ttid)
getModel().transporterAddRoute(null, trans, rstart, rend, start, end, cost, ttid)
};

/**
`transporterUpdateRoute`
---------------------------
*/
transporterUpdateRoute(
route: RouteId,
trans: TransporterId,
rstart: RegionId,
rend: RegionId,
start: Date,
end: Date,
cost: Price,
ttid: TruckTypeId
) : async ?() {
getModel().transporterUpdateRoute(route, trans, rstart, rend, start, end, cost, ttid)
};

/**
Expand Down
143 changes: 122 additions & 21 deletions stdlib/examples/produce-exchange/serverModel.as
Original file line number Diff line number Diff line change
Expand Up @@ -910,6 +910,8 @@ than the MVP goals, however.
case (?x) { x };
};

/// xxx: access control: Check that the current user is the owner of this inventory

/// xxx an abstraction to hide these type arguments?
let (updatedInventory, _) =
Trie.remove<InventoryId, InventoryDoc>(
Expand Down Expand Up @@ -979,6 +981,7 @@ than the MVP goals, however.
---------------------------
*/
transporterAddRoute(
rid_: ?RouteId,
id_: TransporterId,
start_region_id: RegionId,
end_region_id: RegionId,
Expand All @@ -993,27 +996,31 @@ than the MVP goals, however.
let otransporter : ?TransporterDoc = transporterTable.getDoc(id_);
let orstart : ?RegionDoc = regionTable.getDoc(start_region_id);
let orend : ?RegionDoc = regionTable.getDoc(end_region_id);
let otrucktype : ?TruckTypeDoc = truckTypeTable.getDoc(trucktype_id);
let otrucktype : ?TruckTypeInfo = truckTypeTable.getInfo(trucktype_id);
let (transporter, start_region_, end_region_, truck_type_) = {
switch (otransporter, orstart, orend, otrucktype) {
case (?x1, ?x2, ?x3, ?x4) (x1, x2, x3, x4);
case _ { return null };
}};

/**- Create the route item document: */
let (_, route) = routeTable.addDoc(
func(routeId:RouteId):RouteDoc{
new {
id= routeId;
transporter=id_;
truck_type=truck_type_;
start_date=start_date_;
end_date=end_date_;
start_region=start_region_;
end_region=end_region_;
cost=cost_;
let route : RouteDoc = {
switch (routeTable.addInfoAs(rid_, func(routeId:RouteId):RouteInfo{
shared {
id= routeId;
transporter=id_;
truck_type=truck_type_;
start_date=start_date_;
end_date=end_date_;
start_region=start_region_id;
end_region=end_region_id;
cost=cost_;
};
});
})) {
case (?(_, route)) { route };
case null { unreachable() };
}
};

/**- Update the transporter's routes collection to hold the new route document: */
let updatedRoutes =
Expand Down Expand Up @@ -1049,20 +1056,114 @@ than the MVP goals, however.
};

/**
`transporterRemRoute`
`transporterUpdateRoute`
---------------------------
Update the given route with the given field values.
*/
transporterUpdateRoute(
rid_ : RouteId,
id_ : TransporterId,
start_region_id : RegionId,
end_region_id : RegionId,
start_date_ : Date,
end_date_ : Date,
cost_ : Price,
trucktype_id : TruckTypeId
) : ?() {
/** The model updates routes and maintains secondary indicies as follows: */

/**- Validate these ids; fail fast if not defined: */
let oroute : ?RouteDoc = routeTable.getDoc(rid_);
let otransporter : ?TransporterDoc = transporterTable.getDoc(id_);
let orstart : ?RegionDoc = regionTable.getDoc(start_region_id);
let orend : ?RegionDoc = regionTable.getDoc(end_region_id);
let otrucktype : ?TruckTypeDoc = truckTypeTable.getDoc(trucktype_id);
let (route, transporter, start_region_, end_region_, truck_type_) = {
switch (oroute, otransporter, orstart, orend, otrucktype) {
case (?route, ?transporter, ?x2, ?x3, ?x4) {
// it's an error if the transporter is not fixed across the
// update. i.e., transporter A cannot update the routes
// of transporter B, only her own.
if ( route.transporter == transporter.id ) {
(route, transporter, x2, x3, x4);
} else {
return null
}
};
case _ { return null };
}};

/**- remove the route; given the validation above, this cannot fail. */
assertSome<()>( transporterRemRoute(rid_) );

/**- add the (updated) route; given the validation above, this cannot fail. */
assertSome<RouteId>(
transporterAddRoute(
?rid_, id_,
start_region_id,
end_region_id,
start_date_,
end_date_,
cost_,
trucktype_id
)
);

**Implementation summary:**
/**- Success! */
?()
};

- remove from the inventory in inventory table; use `Trie.removeThen`
- if successful, look up the producer ID; should not fail; `Trie.find`
- update the transporter, removing this inventory; use `Trie.{replace,remove}`
- finally, use route info to update the routesByRegion table,
removing this inventory item; use `Trie.remove2D`.
/**
`transporterRemRoute`
---------------------------
Remove the given route from the exchange.
*/
transporterRemRoute(id:RouteId) : ?() {
nyi()

let doc = switch (routeTable.getDoc(id)) {
case null { return null };
case (?doc) { doc };
};

assertSome<RouteDoc>(
routeTable.rem( id )
);

let transporter = switch (transporterTable.getDoc(doc.transporter)) {
case null { unreachable() };
case (?x) { x };
};

/// xxx: access control: Check that the current user is the owner of this route

let (updatedRoutes, _) =
Trie.remove<RouteId, RouteDoc>(
transporter.routes, keyOf(id), idIsEq);

let updatedTransporter = new {
id = transporter.id ;
short_name = transporter.short_name ;
description = transporter.description ;
routes = updatedRoutes ;
reserved = transporter.reserved ;
};

assertSome<TransporterDoc>(
transporterTable.updateDoc( transporter.id, updatedTransporter )
);

routesByDstSrcRegions := {
let (t, d) = Trie.remove3D<RegionId, RegionId, RouteId, RouteDoc>(
routesByDstSrcRegions,
keyOf(doc.end_region.id), idIsEq,
keyOf(doc.start_region.id), idIsEq,
keyOf(doc.id), idIsEq
);
assertSome<RouteDoc>(d);
t
};

?()
};

/**
Expand Down
20 changes: 20 additions & 0 deletions stdlib/examples/produce-exchange/test/simpleSetupAndQuery.as
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,26 @@ actor class Test() = this {

printEntityCount("Route", (await s.getCounts()).route_count);

////////////////////////////////////////////////////////////////////////////////////

/**- remove some of the routes added above */

{ let x = await s.transporterRemRoute(unwrap<RouteId>(rtc_b_c_tta));
assertSome<()>(x); };

// a double-remove should return null
assertNull<()>(await s.transporterRemRoute(unwrap<RouteId>(rtc_b_c_tta)));

printEntityCount("Route@time2", (await s.getCounts()).route_count);

{ let x = await s.transporterRemRoute(unwrap<RouteId>(rtc_c_e_tta));
assertSome<()>(x); };

// a double-remove should return null
assertNull<()>(await s.transporterRemRoute(unwrap<RouteId>(rtc_c_e_tta)));

printEntityCount("Route@time2", (await s.getCounts()).route_count);

//////////////////////////////////////////////////////////////////

print "\nExchange setup: Done.\n====================================\n";
Expand Down