Mercurial > urweb
comparison src/cjr_print.sml @ 870:7fa9a37a34b3
Move all DBMS initialization to #init
author | Adam Chlipala <adamc@hcoop.net> |
---|---|
date | Tue, 30 Jun 2009 15:45:10 -0400 |
parents | 64ba57fa20bf |
children | 9654bce27cff |
comparison
equal
deleted
inserted
replaced
869:64ba57fa20bf | 870:7fa9a37a34b3 |
---|---|
1835 string ");"], | 1835 string ");"], |
1836 newline, | 1836 newline, |
1837 string "}"] | 1837 string "}"] |
1838 end | 1838 end |
1839 | 1839 |
1840 val prepped = ref ([] : (string * int) list) | |
1841 | |
1842 fun p_decl env (dAll as (d, _) : decl) = | 1840 fun p_decl env (dAll as (d, _) : decl) = |
1843 case d of | 1841 case d of |
1844 DStruct (n, xts) => | 1842 DStruct (n, xts) => |
1845 let | 1843 let |
1846 val env = E.declBinds env dAll | 1844 val env = E.declBinds env dAll |
1988 space, | 1986 space, |
1989 string s, | 1987 string s, |
1990 space, | 1988 space, |
1991 string " */", | 1989 string " */", |
1992 newline] | 1990 newline] |
1993 | DDatabase {name, expunge, initialize} => | 1991 | DDatabase _ => box [] |
1994 box [string "static void uw_db_validate(uw_context);", | 1992 | DPreparedStatements _ => box [] |
1995 newline, | |
1996 string "static void uw_db_prepare(uw_context);", | |
1997 newline, | |
1998 newline, | |
1999 | |
2000 #init (Settings.currentDbms ()) (name, !prepped), | |
2001 | |
2002 string "void uw_expunger(uw_context ctx, uw_Basis_client cli) {", | |
2003 newline, | |
2004 box [p_enamed env expunge, | |
2005 string "(ctx, cli);", | |
2006 newline], | |
2007 string "}", | |
2008 newline, | |
2009 newline, | |
2010 | |
2011 string "void uw_initializer(uw_context ctx) {", | |
2012 newline, | |
2013 box [p_enamed env initialize, | |
2014 string "(ctx, uw_unit_v);", | |
2015 newline], | |
2016 string "}", | |
2017 newline] | |
2018 | |
2019 | DPreparedStatements ss => | |
2020 (prepped := ss; | |
2021 box []) | |
2022 | 1993 |
2023 | DJavaScript s => box [string "static char jslib[] = \"", | 1994 | DJavaScript s => box [string "static char jslib[] = \"", |
2024 string (String.toString s), | 1995 string (String.toString s), |
2025 string "\";"] | 1996 string "\";"] |
2026 | DCookie s => box [string "/*", | 1997 | DCookie s => box [string "/*", |
2603 ] | 2574 ] |
2604 end | 2575 end |
2605 | 2576 |
2606 val pds' = map p_page ps | 2577 val pds' = map p_page ps |
2607 | 2578 |
2608 val tables = List.mapPartial (fn (DTable (s, xts, _, _), _) => SOME (s, xts) | 2579 val hasDb = ref false |
2609 | _ => NONE) ds | 2580 val tables = ref [] |
2610 val sequences = List.mapPartial (fn (DSequence s, _) => SOME s | 2581 val sequences = ref [] |
2611 | _ => NONE) ds | 2582 val dbstring = ref "" |
2612 | 2583 val expunge = ref 0 |
2613 val validate = | 2584 val initialize = ref 0 |
2614 if #persistent (Settings.currentProtocol ()) then | 2585 val prepped = ref [] |
2615 box [string "static void uw_db_validate(uw_context ctx) {", | 2586 |
2616 newline, | 2587 val () = app (fn d => |
2617 string "PGconn *conn = uw_get_db(ctx);", | 2588 case #1 d of |
2618 newline, | 2589 DDatabase {name = x, expunge = y, initialize = z} => (hasDb := true; |
2619 string "PGresult *res;", | 2590 dbstring := x; |
2620 newline, | 2591 expunge := y; |
2621 newline, | 2592 initialize := z) |
2622 p_list_sep newline | 2593 | DTable (s, xts, _, _) => tables := (s, map (fn (x, t) => |
2623 (fn (s, xts) => | 2594 (x, sql_type_in env t)) xts) :: !tables |
2624 let | 2595 | DSequence s => sequences := s :: !sequences |
2625 val sl = CharVector.map Char.toLower s | 2596 | DPreparedStatements ss => prepped := ss |
2626 | 2597 | _ => ()) ds |
2627 val q = "SELECT COUNT(*) FROM pg_class WHERE relname = '" | 2598 |
2628 ^ sl ^ "'" | 2599 val hasDb = !hasDb |
2629 | |
2630 val q' = String.concat ["SELECT COUNT(*) FROM pg_attribute WHERE attrelid = (SELECT oid FROM pg_class WHERE relname = '", | |
2631 sl, | |
2632 "') AND (", | |
2633 String.concatWith " OR " | |
2634 (map (fn (x, t) => | |
2635 String.concat ["(attname = 'uw_", | |
2636 CharVector.map | |
2637 Char.toLower (ident x), | |
2638 "' AND atttypid = (SELECT oid FROM pg_type", | |
2639 " WHERE typname = '", | |
2640 p_sqltype_base' env t, | |
2641 "') AND attnotnull = ", | |
2642 if is_not_null t then | |
2643 "TRUE" | |
2644 else | |
2645 "FALSE", | |
2646 ")"]) xts), | |
2647 ")"] | |
2648 | |
2649 val q'' = String.concat ["SELECT COUNT(*) FROM pg_attribute WHERE attrelid = (SELECT oid FROM pg_class WHERE relname = '", | |
2650 sl, | |
2651 "') AND attname LIKE 'uw_%'"] | |
2652 in | |
2653 box [string "res = PQexec(conn, \"", | |
2654 string q, | |
2655 string "\");", | |
2656 newline, | |
2657 newline, | |
2658 string "if (res == NULL) {", | |
2659 newline, | |
2660 box [string "PQfinish(conn);", | |
2661 newline, | |
2662 string "uw_error(ctx, FATAL, \"Out of memory allocating query result.\");", | |
2663 newline], | |
2664 string "}", | |
2665 newline, | |
2666 newline, | |
2667 string "if (PQresultStatus(res) != PGRES_TUPLES_OK) {", | |
2668 newline, | |
2669 box [string "char msg[1024];", | |
2670 newline, | |
2671 string "strncpy(msg, PQerrorMessage(conn), 1024);", | |
2672 newline, | |
2673 string "msg[1023] = 0;", | |
2674 newline, | |
2675 string "PQclear(res);", | |
2676 newline, | |
2677 string "PQfinish(conn);", | |
2678 newline, | |
2679 string "uw_error(ctx, FATAL, \"Query failed:\\n", | |
2680 string q, | |
2681 string "\\n%s\", msg);", | |
2682 newline], | |
2683 string "}", | |
2684 newline, | |
2685 newline, | |
2686 string "if (strcmp(PQgetvalue(res, 0, 0), \"1\")) {", | |
2687 newline, | |
2688 box [string "PQclear(res);", | |
2689 newline, | |
2690 string "PQfinish(conn);", | |
2691 newline, | |
2692 string "uw_error(ctx, FATAL, \"Table '", | |
2693 string s, | |
2694 string "' does not exist.\");", | |
2695 newline], | |
2696 string "}", | |
2697 newline, | |
2698 newline, | |
2699 string "PQclear(res);", | |
2700 newline, | |
2701 | |
2702 string "res = PQexec(conn, \"", | |
2703 string q', | |
2704 string "\");", | |
2705 newline, | |
2706 newline, | |
2707 string "if (res == NULL) {", | |
2708 newline, | |
2709 box [string "PQfinish(conn);", | |
2710 newline, | |
2711 string "uw_error(ctx, FATAL, \"Out of memory allocating query result.\");", | |
2712 newline], | |
2713 string "}", | |
2714 newline, | |
2715 newline, | |
2716 string "if (PQresultStatus(res) != PGRES_TUPLES_OK) {", | |
2717 newline, | |
2718 box [string "char msg[1024];", | |
2719 newline, | |
2720 string "strncpy(msg, PQerrorMessage(conn), 1024);", | |
2721 newline, | |
2722 string "msg[1023] = 0;", | |
2723 newline, | |
2724 string "PQclear(res);", | |
2725 newline, | |
2726 string "PQfinish(conn);", | |
2727 newline, | |
2728 string "uw_error(ctx, FATAL, \"Query failed:\\n", | |
2729 string q', | |
2730 string "\\n%s\", msg);", | |
2731 newline], | |
2732 string "}", | |
2733 newline, | |
2734 newline, | |
2735 string "if (strcmp(PQgetvalue(res, 0, 0), \"", | |
2736 string (Int.toString (length xts)), | |
2737 string "\")) {", | |
2738 newline, | |
2739 box [string "PQclear(res);", | |
2740 newline, | |
2741 string "PQfinish(conn);", | |
2742 newline, | |
2743 string "uw_error(ctx, FATAL, \"Table '", | |
2744 string s, | |
2745 string "' has the wrong column types.\");", | |
2746 newline], | |
2747 string "}", | |
2748 newline, | |
2749 newline, | |
2750 string "PQclear(res);", | |
2751 newline, | |
2752 newline, | |
2753 | |
2754 string "res = PQexec(conn, \"", | |
2755 string q'', | |
2756 string "\");", | |
2757 newline, | |
2758 newline, | |
2759 string "if (res == NULL) {", | |
2760 newline, | |
2761 box [string "PQfinish(conn);", | |
2762 newline, | |
2763 string "uw_error(ctx, FATAL, \"Out of memory allocating query result.\");", | |
2764 newline], | |
2765 string "}", | |
2766 newline, | |
2767 newline, | |
2768 string "if (PQresultStatus(res) != PGRES_TUPLES_OK) {", | |
2769 newline, | |
2770 box [string "char msg[1024];", | |
2771 newline, | |
2772 string "strncpy(msg, PQerrorMessage(conn), 1024);", | |
2773 newline, | |
2774 string "msg[1023] = 0;", | |
2775 newline, | |
2776 string "PQclear(res);", | |
2777 newline, | |
2778 string "PQfinish(conn);", | |
2779 newline, | |
2780 string "uw_error(ctx, FATAL, \"Query failed:\\n", | |
2781 string q'', | |
2782 string "\\n%s\", msg);", | |
2783 newline], | |
2784 string "}", | |
2785 newline, | |
2786 newline, | |
2787 string "if (strcmp(PQgetvalue(res, 0, 0), \"", | |
2788 string (Int.toString (length xts)), | |
2789 string "\")) {", | |
2790 newline, | |
2791 box [string "PQclear(res);", | |
2792 newline, | |
2793 string "PQfinish(conn);", | |
2794 newline, | |
2795 string "uw_error(ctx, FATAL, \"Table '", | |
2796 string s, | |
2797 string "' has extra columns.\");", | |
2798 newline], | |
2799 string "}", | |
2800 newline, | |
2801 newline, | |
2802 string "PQclear(res);", | |
2803 newline] | |
2804 end) tables, | |
2805 | |
2806 p_list_sep newline | |
2807 (fn s => | |
2808 let | |
2809 val sl = CharVector.map Char.toLower s | |
2810 | |
2811 val q = "SELECT COUNT(*) FROM pg_class WHERE relname = '" | |
2812 ^ sl ^ "' AND relkind = 'S'" | |
2813 in | |
2814 box [string "res = PQexec(conn, \"", | |
2815 string q, | |
2816 string "\");", | |
2817 newline, | |
2818 newline, | |
2819 string "if (res == NULL) {", | |
2820 newline, | |
2821 box [string "PQfinish(conn);", | |
2822 newline, | |
2823 string "uw_error(ctx, FATAL, \"Out of memory allocating query result.\");", | |
2824 newline], | |
2825 string "}", | |
2826 newline, | |
2827 newline, | |
2828 string "if (PQresultStatus(res) != PGRES_TUPLES_OK) {", | |
2829 newline, | |
2830 box [string "char msg[1024];", | |
2831 newline, | |
2832 string "strncpy(msg, PQerrorMessage(conn), 1024);", | |
2833 newline, | |
2834 string "msg[1023] = 0;", | |
2835 newline, | |
2836 string "PQclear(res);", | |
2837 newline, | |
2838 string "PQfinish(conn);", | |
2839 newline, | |
2840 string "uw_error(ctx, FATAL, \"Query failed:\\n", | |
2841 string q, | |
2842 string "\\n%s\", msg);", | |
2843 newline], | |
2844 string "}", | |
2845 newline, | |
2846 newline, | |
2847 string "if (strcmp(PQgetvalue(res, 0, 0), \"1\")) {", | |
2848 newline, | |
2849 box [string "PQclear(res);", | |
2850 newline, | |
2851 string "PQfinish(conn);", | |
2852 newline, | |
2853 string "uw_error(ctx, FATAL, \"Sequence '", | |
2854 string s, | |
2855 string "' does not exist.\");", | |
2856 newline], | |
2857 string "}", | |
2858 newline, | |
2859 newline, | |
2860 string "PQclear(res);", | |
2861 newline] | |
2862 end) sequences, | |
2863 | |
2864 string "}"] | |
2865 else | |
2866 string "static void uw_db_validate(uw_context ctx) { }" | |
2867 | |
2868 val hasDb = List.exists (fn (DDatabase _, _) => true | _ => false) ds | |
2869 | 2600 |
2870 val cookies = List.mapPartial (fn (DCookie s, _) => SOME s | _ => NONE) ds | 2601 val cookies = List.mapPartial (fn (DCookie s, _) => SOME s | _ => NONE) ds |
2871 | 2602 |
2872 val cookieCode = foldl (fn (cookie, acc) => | 2603 val cookieCode = foldl (fn (cookie, acc) => |
2873 SOME (case acc of | 2604 SOME (case acc of |
2918 if hasDb then | 2649 if hasDb then |
2919 box [string ("#include <" ^ #header (Settings.currentDbms ()) ^ ">"), | 2650 box [string ("#include <" ^ #header (Settings.currentDbms ()) ^ ">"), |
2920 newline] | 2651 newline] |
2921 else | 2652 else |
2922 box [], | 2653 box [], |
2923 newline, | |
2924 p_list_sep (box []) (fn s => box [string "#include \"", | 2654 p_list_sep (box []) (fn s => box [string "#include \"", |
2925 string s, | 2655 string s, |
2926 string "\"", | 2656 string "\"", |
2927 newline]) (Settings.getHeaders ()), | 2657 newline]) (Settings.getHeaders ()), |
2928 string "#include \"", | 2658 string "#include \"", |
2929 string (OS.Path.joinDirFile {dir = Config.includ, | 2659 string (OS.Path.joinDirFile {dir = Config.includ, |
2930 file = "urweb.h"}), | 2660 file = "urweb.h"}), |
2931 string "\"", | 2661 string "\"", |
2662 newline, | |
2663 newline, | |
2664 | |
2665 if hasDb then | |
2666 #init (Settings.currentDbms ()) {dbstring = !dbstring, | |
2667 prepared = !prepped, | |
2668 tables = !tables, | |
2669 sequences = !sequences} | |
2670 else | |
2671 box [string "void uw_db_init(uw_context ctx) { };", | |
2672 newline, | |
2673 string "int uw_db_begin(uw_context ctx) { return 0; };", | |
2674 newline, | |
2675 string "int uw_db_commit(uw_context ctx) { return 0; };", | |
2676 newline, | |
2677 string "int uw_db_rollback(uw_context ctx) { return 0; };"], | |
2932 newline, | 2678 newline, |
2933 newline, | 2679 newline, |
2934 | 2680 |
2935 string "const char *uw_url_prefix = \"", | 2681 string "const char *uw_url_prefix = \"", |
2936 string (Settings.getUrlPrefix ()), | 2682 string (Settings.getUrlPrefix ()), |
3006 string "uw_error(ctx, FATAL, \"Unknown page\");", | 2752 string "uw_error(ctx, FATAL, \"Unknown page\");", |
3007 newline, | 2753 newline, |
3008 string "}", | 2754 string "}", |
3009 newline, | 2755 newline, |
3010 newline, | 2756 newline, |
2757 | |
3011 if hasDb then | 2758 if hasDb then |
3012 validate | 2759 box [string "void uw_expunger(uw_context ctx, uw_Basis_client cli) {", |
2760 newline, | |
2761 box [p_enamed env (!expunge), | |
2762 string "(ctx, cli);", | |
2763 newline], | |
2764 string "}", | |
2765 newline, | |
2766 newline, | |
2767 | |
2768 string "void uw_initializer(uw_context ctx) {", | |
2769 newline, | |
2770 box [p_enamed env (!initialize), | |
2771 string "(ctx, uw_unit_v);", | |
2772 newline], | |
2773 string "}", | |
2774 newline] | |
3013 else | 2775 else |
3014 box [], | 2776 box [string "void uw_expunger(uw_context ctx, uw_Basis_client cli) { };", |
3015 newline, | |
3016 if List.exists (fn (DDatabase _, _) => true | _ => false) ds then | |
3017 box [] | |
3018 else | |
3019 box [newline, | |
3020 string "void uw_db_init(uw_context ctx) { };", | |
3021 newline, | |
3022 string "int uw_db_begin(uw_context ctx) { return 0; };", | |
3023 newline, | |
3024 string "int uw_db_commit(uw_context ctx) { return 0; };", | |
3025 newline, | |
3026 string "int uw_db_rollback(uw_context ctx) { return 0; };", | |
3027 newline, | |
3028 string "void uw_expunger(uw_context ctx, uw_Basis_client cli) { };", | |
3029 newline, | 2777 newline, |
3030 string "void uw_initializer(uw_context ctx) { };", | 2778 string "void uw_initializer(uw_context ctx) { };", |
3031 newline]] | 2779 newline]] |
3032 end | 2780 end |
3033 | 2781 |