comparison src/monoize.sml @ 687:a3ddf05fb3e3

On start-up, delete/nullify rows mentioning clients or channels
author Adam Chlipala <adamc@hcoop.net>
date Thu, 02 Apr 2009 11:42:26 -0400
parents f0224c7f12bb
children 7ea0df9e56b6
comparison
equal deleted inserted replaced
686:3b46548f701b 687:a3ddf05fb3e3
2472 () 2472 ()
2473 2473
2474 val loc = E.dummySpan 2474 val loc = E.dummySpan
2475 val client = (L'.TFfi ("Basis", "client"), loc) 2475 val client = (L'.TFfi ("Basis", "client"), loc)
2476 val unit = (L'.TRecord [], loc) 2476 val unit = (L'.TRecord [], loc)
2477
2478 fun calcClientish xts =
2479 foldl (fn ((x : L.con, t : L.con), st as (nullable, notNullable)) =>
2480 case #1 x of
2481 L.CName x =>
2482 (case #1 t of
2483 L.CFfi ("Basis", "client") =>
2484 (nullable, (x, Client) :: notNullable)
2485 | L.CApp ((L.CFfi ("Basis", "option"), _),
2486 (L.CFfi ("Basis", "client"), _)) =>
2487 ((x, Client) :: nullable, notNullable)
2488 | L.CApp ((L.CFfi ("Basis", "channel"), _), _) =>
2489 (nullable, (x, Channel) :: notNullable)
2490 | L.CApp ((L.CFfi ("Basis", "option"), _),
2491 (L.CApp ((L.CFfi ("Basis", "channel"), _), _), _)) =>
2492 ((x, Channel) :: nullable, notNullable)
2493 | _ => st)
2494 | _ => st) ([], []) xts
2495
2477 fun expunger () = 2496 fun expunger () =
2478 let 2497 let
2479 val target = (L'.EFfiApp ("Basis", "sqlifyClient", [(L'.ERel 0, loc)]), loc) 2498 val target = (L'.EFfiApp ("Basis", "sqlifyClient", [(L'.ERel 0, loc)]), loc)
2480 2499
2481 fun doTable (tab, xts, e) = 2500 fun doTable (tab, xts, e) =
2482 case xts of 2501 case xts of
2483 L.CRecord (_, xts) => 2502 L.CRecord (_, xts) =>
2484 let 2503 let
2485 val (nullable, notNullable) = 2504 val (nullable, notNullable) = calcClientish xts
2486 foldl (fn ((x, t), st as (nullable, notNullable)) =>
2487 case #1 x of
2488 L.CName x =>
2489 (case #1 t of
2490 L.CFfi ("Basis", "client") =>
2491 (nullable, (x, Client) :: notNullable)
2492 | L.CApp ((L.CFfi ("Basis", "option"), _),
2493 (L.CFfi ("Basis", "client"), _)) =>
2494 ((x, Client) :: nullable, notNullable)
2495 | L.CApp ((L.CFfi ("Basis", "channel"), _), _) =>
2496 (nullable, (x, Channel) :: notNullable)
2497 | L.CApp ((L.CFfi ("Basis", "option"), _),
2498 (L.CApp ((L.CFfi ("Basis", "channel"), _), _), _)) =>
2499 ((x, Channel) :: nullable, notNullable)
2500 | _ => st)
2501 | _ => st) ([], []) xts
2502 2505
2503 fun cond (x, v) = 2506 fun cond (x, v) =
2504 (L'.EStrcat ((L'.EPrim (Prim.String ("uw_" ^ x 2507 (L'.EStrcat ((L'.EPrim (Prim.String ("uw_" ^ x
2505 ^ (case v of 2508 ^ (case v of
2506 Client => "" 2509 Client => ""
2527 | eb :: ebs => 2530 | eb :: ebs =>
2528 (L'.ESeq ( 2531 (L'.ESeq (
2529 (L'.EDml (foldl 2532 (L'.EDml (foldl
2530 (fn (eb, s) => 2533 (fn (eb, s) =>
2531 (L'.EStrcat (s, 2534 (L'.EStrcat (s,
2532 (L'.EStrcat ((L'.EPrim (Prim.String " AND "), 2535 (L'.EStrcat ((L'.EPrim (Prim.String " OR "),
2533 loc), 2536 loc),
2534 cond eb), loc)), loc)) 2537 cond eb), loc)), loc))
2535 (L'.EStrcat ((L'.EPrim (Prim.String ("DELETE FROM uw_" 2538 (L'.EStrcat ((L'.EPrim (Prim.String ("DELETE FROM uw_"
2536 ^ tab 2539 ^ tab
2537 ^ " WHERE ")), loc), 2540 ^ " WHERE ")), loc),
2549 case d of 2552 case d of
2550 L.DTable (_, _, xts, tab) => doTable (tab, #1 xts, e) 2553 L.DTable (_, _, xts, tab) => doTable (tab, #1 xts, e)
2551 | _ => e) e file 2554 | _ => e) e file
2552 end 2555 end
2553 2556
2557 fun initializer () =
2558 let
2559 fun doTable (tab, xts, e) =
2560 case xts of
2561 L.CRecord (_, xts) =>
2562 let
2563 val (nullable, notNullable) = calcClientish xts
2564
2565 val e =
2566 case nullable of
2567 [] => e
2568 | (x, _) :: ebs =>
2569 (L'.ESeq (
2570 (L'.EDml (L'.EPrim (Prim.String
2571 (foldl (fn ((x, _), s) =>
2572 s ^ ", uw_" ^ x ^ " = NULL")
2573 ("UPDATE uw_"
2574 ^ tab
2575 ^ " SET uw_"
2576 ^ x
2577 ^ " = NULL")
2578 ebs)), loc), loc),
2579 e), loc)
2580
2581 val e =
2582 case notNullable of
2583 [] => e
2584 | eb :: ebs =>
2585 (L'.ESeq (
2586 (L'.EDml (L'.EPrim (Prim.String ("DELETE FROM uw_"
2587 ^ tab)), loc), loc),
2588 e), loc)
2589 in
2590 e
2591 end
2592 | _ => e
2593
2594 val e = (L'.ERecord [], loc)
2595 in
2596 foldl (fn ((d, _), e) =>
2597 case d of
2598 L.DTable (_, _, xts, tab) => doTable (tab, #1 xts, e)
2599 | _ => e) e file
2600 end
2601
2554 val (_, _, ds) = List.foldl (fn (d, (env, fm, ds)) => 2602 val (_, _, ds) = List.foldl (fn (d, (env, fm, ds)) =>
2555 case #1 d of 2603 case #1 d of
2556 L.DDatabase s => 2604 L.DDatabase s =>
2557 let 2605 let
2558 val (n, fm) = Fm.freshName fm 2606 val (nExp, fm) = Fm.freshName fm
2559 2607 val (nIni, fm) = Fm.freshName fm
2560 2608
2561 val d = L'.DVal ("expunger", 2609 val dExp = L'.DVal ("expunger",
2562 n, 2610 nExp,
2563 (L'.TFun (client, unit), loc), 2611 (L'.TFun (client, unit), loc),
2564 (L'.EAbs ("cli", client, unit, expunger ()), loc), 2612 (L'.EAbs ("cli", client, unit, expunger ()), loc),
2565 "expunger") 2613 "expunger")
2614 val dIni = L'.DVal ("initializer",
2615 nIni,
2616 (L'.TFun (unit, unit), loc),
2617 (L'.EAbs ("_", unit, unit, initializer ()), loc),
2618 "initializer")
2566 in 2619 in
2567 (env, Fm.enter fm, (L'.DDatabase (s, n), loc) 2620 (env, Fm.enter fm, (L'.DDatabase {name = s,
2568 :: (d, loc) 2621 expunge = nExp,
2622 initialize = nIni}, loc)
2623 :: (dExp, loc)
2624 :: (dIni, loc)
2569 :: ds) 2625 :: ds)
2570 end 2626 end
2571 | _ => 2627 | _ =>
2572 case monoDecl (env, fm) d of 2628 case monoDecl (env, fm) d of
2573 NONE => (env, fm, ds) 2629 NONE => (env, fm, ds)