open Meta functor Make(M : sig con paper :: {(Type * Type)} constraint [Id, Title] ~ paper val paper : $(map meta paper) con review :: {(Type * Type)} constraint [Paper, User] ~ review val review : $(map meta review) val submissionDeadline : time end) = struct table user : {Id : int, Nam : string, Password : string, Chair : bool, OnPc : bool} PRIMARY KEY Id, CONSTRAINT Nam UNIQUE Nam sequence userId con paper = [Id = int, Title = string] ++ map fst M.paper table paper : paper PRIMARY KEY Id sequence paperId con review = [Paper = int, User = int] ++ map fst M.review table review : review PRIMARY KEY (Paper, User), CONSTRAINT Paper FOREIGN KEY Paper REFERENCES paper(Id), CONSTRAINT User FOREIGN KEY User REFERENCES user(Id) sequence reviewId cookie login : {Id : int, Password : string} val checkLogin = r <- getCookie login; case r of None => return None | Some r => oneOrNoRows1 (SELECT user.Id, user.Nam, user.Chair, user.OnPc FROM user WHERE user.Id = {[r.Id]} AND user.Password = {[r.Password]}) structure Users = BulkEdit.Make(struct con keyName = #Id val visible = {Nam = string "Name", Chair = bool "Chair?", OnPc = bool "On PC?"} val title = "Users" val isAllowed = me <- checkLogin; return (Option.isSome me) val t = user end) fun doRegister r = n <- oneRowE1 (SELECT COUNT( * ) AS N FROM user WHERE user.Nam = {[r.Nam]}); if n > 0 then register (Some "Sorry; that username is taken.") else id <- nextval userId; dml (INSERT INTO user (Id, Nam, Password, Chair, OnPc) VALUES ({[id]}, {[r.Nam]}, {[r.Password]}, FALSE, FALSE)); setCookie login {Id = id, Password = r.Password}; main () and register msg = return

Registering a New Account

{case msg of None => | Some msg =>
{[msg]}
}
Username:
Password:
and signin r = ro <- oneOrNoRowsE1 (SELECT user.Id AS N FROM user WHERE user.Nam = {[r.Nam]} AND user.Password = {[r.Password]}); (case ro of None => return () | Some id => setCookie login {Id = id, Password = r.Password}); m <- main' (); return {case ro of None =>
Invalid username or password.
| _ => } {m} and main' () = me <- checkLogin; now <- now; return
    {case me of None =>
  • Register for access
  • Log in:
    Username:
    Password:
  • | Some me =>
    Welcome, {[me.Nam]}!
    {if me.Chair then
  • Manage users
  • else } {if now < M.submissionDeadline then
  • Submit
  • else } }
and main () = m <- main' (); return {m} end