Skip to content
Closed
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
17 changes: 17 additions & 0 deletions stdlib/docTable.as
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,23 @@ class DocTable<Id,Doc,Info>(
}
};

/**
`upsertInfo`
---------

Updates the document with the given id, or inserts a new document if nothing exists. Returns the old document if it was replaced.

*/
upsertInfo(id:Id, info:Info) : ?Doc {
let doc = docOfInfo(info);
switch doc {
case null { null };
case (?doc) {
updateDoc(id, doc)
}
}
};

/**
`rem`
---------
Expand Down
118 changes: 63 additions & 55 deletions stdlib/examples/produce-exchange/serverActor.as
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ actor server = {
*/

registrarAddUser(
userId: UserId,
short_name_: Text,
description_: Text,
region_: RegionId,
Expand All @@ -63,51 +64,56 @@ actor server = {
isTransporter: Bool
) : async ?UserId {

let prId = if isProducer { getModel().producerTable.addInfoGetId(
func(id_:ProducerId):ProducerInfo {
let producer_ = if isProducer {
getModel().producerTable.upsertInfo(userId,
shared {
id=id_:ProducerId;
id=userId:ProducerId;
short_name=short_name_;
description=description_;
region=region_;
inventory=[];
reserved=[];
}
}) } else null;
)
} else null;

let trId = if isTransporter { getModel().transporterTable.addInfoGetId(
func(id_:TransporterId):TransporterInfo {
let transporter_ = if isTransporter {
getModel().transporterTable.upsertInfo(userId,
shared {
id=id_:TransporterId;
id=userId:TransporterId;
short_name=short_name_;
description=description_;
routes=[];
reserved=[];
}
}) } else null;
)
} else null;

let rrId = if isRetailer { getModel().retailerTable.addInfoGetId(
func(id_:RetailerId):RetailerInfo {
let retailer_ = if isRetailer {
getModel().retailerTable.upsertInfo(userId,
shared {
id=id_;
id=userId;
short_name=short_name_;
description=description_;
region=region_:RegionId
}
}) } else null;
)
} else null;

getModel().userTable.addInfoGetId(
func (id_: UserId) : UserInfo =
shared {
id = id_;
short_name = short_name_;
description = description_;
region = region_;
producerId = prId;
transporterId = trId;
retailerId = rrId;
isDeveloper = isDeveloper_;
})
let user_ = getModel().userTable.upsertInfo(userId,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What should happen in the case that registrarAddUser is called twice with the same userId?

Shouldn't that be an error?

Here, it will overwrite the old data with new data. I'm not sure that's what we want, is it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe that's what we want, right? A user/producer/retailer can update their info

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure, updating information should be permitted, but that's a different operation than addUser, is it not?

shared {
id = userId;
short_name = short_name_;
description = description_;
region = region_;
producerId = ?userId;
transporterId = ?userId;
retailerId = ?userId;
isDeveloper = isDeveloper_;
}
);

?userId
};

/**
Expand Down Expand Up @@ -338,21 +344,22 @@ actor server = {
*/

registrarAddProducer(
producerId: ProducerId,
short_name_: Text,
description_: Text,
region_: RegionId,
) : async ?ProducerId {
getModel().producerTable.addInfoGetId(
func(id_:ProducerId):ProducerInfo {
shared {
id=id_:ProducerId;
short_name=short_name_:Text;
description=description_:Text;
region=region_:RegionId;
inventory=[];
reserved=[];
}
})
let producer_ = getModel().producerTable.upsertInfo(producerId,
shared {
id=producerId:ProducerId;
short_name=short_name_;
description=description_;
region=region_;
inventory=[];
reserved=[];
});

?producerId
};

/**
Expand Down Expand Up @@ -405,19 +412,20 @@ actor server = {
*/

registrarAddRetailer(
retailerId: RetailerId,
short_name_: Text,
description_: Text,
region_: RegionId,
) : async ?RetailerId {
getModel().retailerTable.addInfoGetId(
func(id_:RetailerId):RetailerInfo {
shared {
id=id_:RetailerId;
short_name=short_name_:Text;
description=description_:Text;
region=region_:RegionId
}
})
let retailer_ = getModel().retailerTable.upsertInfo(retailerId,
shared {
id=retailerId:RetailerId;
short_name=short_name_:Text;
description=description_:Text;
region=region_:RegionId
});

?retailerId
};

/**
Expand Down Expand Up @@ -466,20 +474,20 @@ actor server = {

*/
registrarAddTransporter(
transporterId: TransporterId,
short_name_: Text,
description_: Text,
) : async ?TransporterId {
getModel().transporterTable.addInfoGetId(
func(id_:TransporterId):TransporterInfo {
shared {
id=id_:TransporterId;
short_name=short_name_:Text;
description=description_:Text;
routes=[];
reserved=[];
}
})

let transporter_ = getModel().transporterTable.upsertInfo(transporterId,
shared {
id=transporterId:TransporterId;
short_name=short_name_:Text;
description=description_:Text;
routes=[];
reserved=[];
});

?transporterId
};

/**
Expand Down
42 changes: 25 additions & 17 deletions stdlib/examples/produce-exchange/serverModel.as
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,24 @@ class Model() {

private idIsEq(x:Nat,y:Nat):Bool { x == y };

private userIdIsEq(x:UserId,y:UserId):Bool { x == y };

private idPairIsEq(x:(Nat,Nat),y:(Nat,Nat)):Bool { x.0 == y.0 and x.1 == y.1 };

private idHash(x:Nat):Hash { Hash.hashOfInt(x) };

private userIdHash(x:UserId):Hash { Hash.hashOfText(x) };

private idPairHash(x:(Nat,Nat)):Hash { Hash.hashOfIntAcc(Hash.hashOfInt(x.0), x.1) };

private keyOf(x:Nat):Key<Nat> {
new { key = x ; hash = idHash(x) }
};

private keyOfUserId(x:UserId):Key<UserId> {
new { key = x ; hash = userIdHash(x) }
};

private keyOfIdPair(x:Nat, y:Nat):Key<(Nat,Nat)> {
new { key = (x,y) ; hash = idPairHash(x,y) }
};
Expand Down Expand Up @@ -118,10 +126,10 @@ secondary maps.

var userTable : UserTable =
DocTable<UserId, UserDoc, UserInfo>(
0,
func(x:UserId):UserId{x+1},
"",
func(x:UserId):UserId{x},
func(x:UserId,y:UserId):Bool{x==y},
idHash,
userIdHash,
func(doc:UserDoc):UserInfo = shared {
id=doc.id;
short_name=doc.short_name;
Expand Down Expand Up @@ -229,10 +237,10 @@ secondary maps.

var producerTable : ProducerTable =
DocTable<ProducerId, ProducerDoc, ProducerInfo>(
0,
func(x:ProducerId):ProducerId{x+1},
"",
func(x:ProducerId):ProducerId{x},
func(x:ProducerId,y:ProducerId):Bool{x==y},
idHash,
userIdHash,
func(doc:ProducerDoc):ProducerInfo = shared {
id=doc.id;
short_name=doc.short_name;
Expand Down Expand Up @@ -313,10 +321,10 @@ secondary maps.

var transporterTable : TransporterTable =
DocTable<TransporterId, TransporterDoc, TransporterInfo> (
0,
func(x:TransporterId):TransporterId{x+1},
"",
func(x:TransporterId):TransporterId{x},
func(x:TransporterId,y:TransporterId):Bool{x==y},
idHash,
userIdHash,
func(doc:TransporterDoc):TransporterInfo = shared {
id=doc.id;
short_name=doc.short_name;
Expand All @@ -341,10 +349,10 @@ secondary maps.

var retailerTable : RetailerTable =
DocTable<RetailerId, RetailerDoc, RetailerInfo>(
0,
func(x:RetailerId):RetailerId{x+1},
"",
func(x:RetailerId):RetailerId{x},
func(x:RetailerId,y:RetailerId):Bool{x==y},
idHash,
userIdHash,
func(doc:RetailerDoc):RetailerInfo = shared {
id=doc.id;
short_name=doc.short_name;
Expand Down Expand Up @@ -706,7 +714,7 @@ than the MVP goals, however.
Map.insert2D<RegionId, ProducerId, InventoryMap>(
inventoryByRegion,
keyOf(producer_.region.id), idIsEq,
keyOf(producer_.id), idIsEq,
keyOfUserId(producer_.id), userIdIsEq,
updatedInventory,
);

Expand Down Expand Up @@ -817,7 +825,7 @@ than the MVP goals, however.
let (t, d) = Trie.remove3D<RegionId, ProducerId, InventoryId, InventoryDoc>(
inventoryByRegion,
keyOf(producer.region.id), idIsEq,
keyOf(producer.id), idIsEq,
keyOfUserId(producer.id), userIdIsEq,
keyOf(id), idIsEq
);
assertSome<InventoryDoc>(d);
Expand Down Expand Up @@ -951,7 +959,7 @@ than the MVP goals, however.
`transporterAllRouteInfo`
---------------------------
*/
transporterAllRouteInfo(id:RouteId) : ?[RouteInfo] {
transporterAllRouteInfo(id:TransporterId) : ?[RouteInfo] {
let doc = switch (transporterTable.getDoc(id)) {
case null { return null };
case (?doc) { doc };
Expand Down Expand Up @@ -1087,7 +1095,7 @@ than the MVP goals, however.
retailerQueryCount += 1;

debug "\nRetailer ";
debugInt id;
debug id;
debug " sends `retailerQueryAll`\n";
debug "------------------------------------\n";

Expand Down Expand Up @@ -1136,7 +1144,7 @@ than the MVP goals, however.
routes,
/** - (To perform this Cartesian product, use a 1D inventory map:) */
Trie.mergeDisjoint2D<ProducerId, InventoryId, InventoryDoc>(
inventory, idIsEq, idIsEq),
inventory, userIdIsEq, idIsEq),

func (route_id:RouteId,
route :RouteDoc,
Expand Down
9 changes: 5 additions & 4 deletions stdlib/examples/produce-exchange/serverTypes.as
Original file line number Diff line number Diff line change
Expand Up @@ -49,17 +49,18 @@ Externally, these Ids give a unique identifier that is unique to its type, but n
Internally, each type of Id serves as a "row key" for a table (or two).

*/
type UserId = Nat;
type Id = Text;
type UserId = Id;

type RegionId = Nat;
type TruckTypeId = Nat;
type ProduceId = Nat;

type ProducerId = Nat;
type ProducerId = Id;
type InventoryId = Nat;
type ReservedInventoryId = Nat;
type RetailerId = Nat;
type TransporterId = Nat;
type RetailerId = Id;
type TransporterId = Id;
type RouteId = Nat;
type ReservedRouteId = Nat;

Expand Down
Loading