comparison src/cjr_print.sml @ 858:346cf1908a17

Avoid using prepared statements for non-persistent protocols
author Adam Chlipala <adamc@hcoop.net>
date Sat, 27 Jun 2009 10:50:45 -0400
parents 2fbd1ac2f04b
children 305bc0a431de
comparison
equal deleted inserted replaced
857:3d2f6cb6d54a 858:346cf1908a17
1639 end, 1639 end,
1640 1640
1641 string "PGresult *res = ", 1641 string "PGresult *res = ",
1642 case prepared of 1642 case prepared of
1643 NONE => string "PQexecParams(conn, query, 0, NULL, NULL, NULL, NULL, 0);" 1643 NONE => string "PQexecParams(conn, query, 0, NULL, NULL, NULL, NULL, 0);"
1644 | SOME n => box [string "PQexecPrepared(conn, \"uw", 1644 | SOME (n, s) =>
1645 string (Int.toString n), 1645 if #persistent (Settings.currentProtocol ()) then
1646 string "\", ", 1646 box [string "PQexecPrepared(conn, \"uw",
1647 string (Int.toString (length (getPargs query))), 1647 string (Int.toString n),
1648 string ", paramValues, paramLengths, paramFormats, 0);"], 1648 string "\", ",
1649 string (Int.toString (length (getPargs query))),
1650 string ", paramValues, paramLengths, paramFormats, 0);"]
1651 else
1652 box [string "PQexecParams(conn, \"",
1653 string (String.toString s),
1654 string "\", ",
1655 string (Int.toString (length (getPargs query))),
1656 string ", NULL, paramValues, paramLengths, paramFormats, 0);"],
1649 newline, 1657 newline,
1650 newline, 1658 newline,
1651 1659
1652 string "if (res == NULL) uw_error(ctx, FATAL, \"Out of memory allocating query result.\");", 1660 string "if (res == NULL) uw_error(ctx, FATAL, \"Out of memory allocating query result.\");",
1653 newline, 1661 newline,
1818 newline, 1826 newline,
1819 newline, 1827 newline,
1820 string "PGresult *res = ", 1828 string "PGresult *res = ",
1821 case prepared of 1829 case prepared of
1822 NONE => string "PQexecParams(conn, dml, 0, NULL, NULL, NULL, NULL, 0);" 1830 NONE => string "PQexecParams(conn, dml, 0, NULL, NULL, NULL, NULL, 0);"
1823 | SOME n => box [string "PQexecPrepared(conn, \"uw", 1831 | SOME (n, s) =>
1824 string (Int.toString n), 1832 if #persistent (Settings.currentProtocol ()) then
1825 string "\", ", 1833 box [string "PQexecPrepared(conn, \"uw",
1826 string (Int.toString (length (getPargs dml))), 1834 string (Int.toString n),
1827 string ", paramValues, paramLengths, paramFormats, 0);"], 1835 string "\", ",
1836 string (Int.toString (length (getPargs dml))),
1837 string ", paramValues, paramLengths, paramFormats, 0);"]
1838 else
1839 box [string "PQexecParams(conn, \"",
1840 string (String.toString s),
1841 string "\", ",
1842 string (Int.toString (length (getPargs dml))),
1843 string ", NULL, paramValues, paramLengths, paramFormats, 0);"],
1828 newline, 1844 newline,
1829 newline, 1845 newline,
1830 1846
1831 string "if (res == NULL) uw_error(ctx, FATAL, \"Out of memory allocating DML result.\");", 1847 string "if (res == NULL) uw_error(ctx, FATAL, \"Out of memory allocating DML result.\");",
1832 newline, 1848 newline,
1890 box [], 1906 box [],
1891 newline, 1907 newline,
1892 string "PGresult *res = ", 1908 string "PGresult *res = ",
1893 case prepared of 1909 case prepared of
1894 NONE => string "PQexecParams(conn, query, 0, NULL, NULL, NULL, NULL, 0);" 1910 NONE => string "PQexecParams(conn, query, 0, NULL, NULL, NULL, NULL, 0);"
1895 | SOME n => box [string "PQexecPrepared(conn, \"uw", 1911 | SOME (n, s) =>
1896 string (Int.toString n), 1912 if #persistent (Settings.currentProtocol ()) then
1897 string "\", 0, NULL, NULL, NULL, 0);"], 1913 box [string "PQexecPrepared(conn, \"uw",
1914 string (Int.toString n),
1915 string "\", 0, NULL, NULL, NULL, 0);"]
1916 else
1917 box [string "PQexecParams(conn, \"uw",
1918 string (Int.toString n),
1919 string "\", 0, NULL, NULL, NULL, NULL, 0);"],
1898 newline, 1920 newline,
1899 string "uw_Basis_int n;", 1921 string "uw_Basis_int n;",
1900 newline, 1922 newline,
1901 newline, 1923 newline,
1902 1924
2304 | DPreparedStatements [] => 2326 | DPreparedStatements [] =>
2305 box [string "static void uw_db_prepare(uw_context ctx) {", 2327 box [string "static void uw_db_prepare(uw_context ctx) {",
2306 newline, 2328 newline,
2307 string "}"] 2329 string "}"]
2308 | DPreparedStatements ss => 2330 | DPreparedStatements ss =>
2309 box [string "static void uw_db_prepare(uw_context ctx) {", 2331 if #persistent (Settings.currentProtocol ()) then
2310 newline, 2332 box [string "static void uw_db_prepare(uw_context ctx) {",
2311 string "PGconn *conn = uw_get_db(ctx);", 2333 newline,
2312 newline, 2334 string "PGconn *conn = uw_get_db(ctx);",
2313 string "PGresult *res;", 2335 newline,
2314 newline, 2336 string "PGresult *res;",
2315 newline, 2337 newline,
2316 2338 newline,
2317 p_list_sepi newline (fn i => fn (s, n) => 2339
2318 box [string "res = PQprepare(conn, \"uw", 2340 p_list_sepi newline (fn i => fn (s, n) =>
2319 string (Int.toString i), 2341 box [string "res = PQprepare(conn, \"uw",
2320 string "\", \"", 2342 string (Int.toString i),
2321 string (String.toString s), 2343 string "\", \"",
2322 string "\", ", 2344 string (String.toString s),
2323 string (Int.toString n), 2345 string "\", ",
2324 string ", NULL);", 2346 string (Int.toString n),
2325 newline, 2347 string ", NULL);",
2326 string "if (PQresultStatus(res) != PGRES_COMMAND_OK) {", 2348 newline,
2327 newline, 2349 string "if (PQresultStatus(res) != PGRES_COMMAND_OK) {",
2328 box [string "char msg[1024];", 2350 newline,
2329 newline, 2351 box [string "char msg[1024];",
2330 string "strncpy(msg, PQerrorMessage(conn), 1024);", 2352 newline,
2331 newline, 2353 string "strncpy(msg, PQerrorMessage(conn), 1024);",
2332 string "msg[1023] = 0;", 2354 newline,
2333 newline, 2355 string "msg[1023] = 0;",
2334 string "PQclear(res);", 2356 newline,
2335 newline, 2357 string "PQclear(res);",
2336 string "PQfinish(conn);", 2358 newline,
2337 newline, 2359 string "PQfinish(conn);",
2338 string "uw_error(ctx, FATAL, \"Unable to create prepared statement:\\n", 2360 newline,
2339 string (String.toString s), 2361 string "uw_error(ctx, FATAL, \"Unable to create prepared statement:\\n",
2340 string "\\n%s\", msg);", 2362 string (String.toString s),
2341 newline], 2363 string "\\n%s\", msg);",
2342 string "}", 2364 newline],
2343 newline, 2365 string "}",
2344 string "PQclear(res);", 2366 newline,
2345 newline]) 2367 string "PQclear(res);",
2346 ss, 2368 newline])
2347 2369 ss,
2348 string "}"] 2370
2371 string "}"]
2372 else
2373 string "static void uw_db_prepare(uw_context ctx) { }"
2349 2374
2350 | DJavaScript s => box [string "static char jslib[] = \"", 2375 | DJavaScript s => box [string "static char jslib[] = \"",
2351 string (String.toString s), 2376 string (String.toString s),
2352 string "\";"] 2377 string "\";"]
2353 | DCookie s => box [string "/*", 2378 | DCookie s => box [string "/*",
2926 | _ => NONE) ds 2951 | _ => NONE) ds
2927 val sequences = List.mapPartial (fn (DSequence s, _) => SOME s 2952 val sequences = List.mapPartial (fn (DSequence s, _) => SOME s
2928 | _ => NONE) ds 2953 | _ => NONE) ds
2929 2954
2930 val validate = 2955 val validate =
2931 box [string "static void uw_db_validate(uw_context ctx) {", 2956 if #persistent (Settings.currentProtocol ()) then
2932 newline, 2957 box [string "static void uw_db_validate(uw_context ctx) {",
2933 string "PGconn *conn = uw_get_db(ctx);", 2958 newline,
2934 newline, 2959 string "PGconn *conn = uw_get_db(ctx);",
2935 string "PGresult *res;", 2960 newline,
2936 newline, 2961 string "PGresult *res;",
2937 newline, 2962 newline,
2938 p_list_sep newline 2963 newline,
2939 (fn (s, xts) => 2964 p_list_sep newline
2940 let 2965 (fn (s, xts) =>
2941 val sl = CharVector.map Char.toLower s 2966 let
2942 2967 val sl = CharVector.map Char.toLower s
2943 val q = "SELECT COUNT(*) FROM pg_class WHERE relname = '" 2968
2944 ^ sl ^ "'" 2969 val q = "SELECT COUNT(*) FROM pg_class WHERE relname = '"
2945 2970 ^ sl ^ "'"
2946 val q' = String.concat ["SELECT COUNT(*) FROM pg_attribute WHERE attrelid = (SELECT oid FROM pg_class WHERE relname = '", 2971
2947 sl, 2972 val q' = String.concat ["SELECT COUNT(*) FROM pg_attribute WHERE attrelid = (SELECT oid FROM pg_class WHERE relname = '",
2948 "') AND (", 2973 sl,
2949 String.concatWith " OR " 2974 "') AND (",
2950 (map (fn (x, t) => 2975 String.concatWith " OR "
2951 String.concat ["(attname = 'uw_", 2976 (map (fn (x, t) =>
2952 CharVector.map 2977 String.concat ["(attname = 'uw_",
2953 Char.toLower (ident x), 2978 CharVector.map
2954 "' AND atttypid = (SELECT oid FROM pg_type", 2979 Char.toLower (ident x),
2955 " WHERE typname = '", 2980 "' AND atttypid = (SELECT oid FROM pg_type",
2956 p_sqltype_base' env t, 2981 " WHERE typname = '",
2957 "') AND attnotnull = ", 2982 p_sqltype_base' env t,
2958 if is_not_null t then 2983 "') AND attnotnull = ",
2959 "TRUE" 2984 if is_not_null t then
2960 else 2985 "TRUE"
2961 "FALSE", 2986 else
2962 ")"]) xts), 2987 "FALSE",
2963 ")"] 2988 ")"]) xts),
2964 2989 ")"]
2965 val q'' = String.concat ["SELECT COUNT(*) FROM pg_attribute WHERE attrelid = (SELECT oid FROM pg_class WHERE relname = '", 2990
2966 sl, 2991 val q'' = String.concat ["SELECT COUNT(*) FROM pg_attribute WHERE attrelid = (SELECT oid FROM pg_class WHERE relname = '",
2967 "') AND attname LIKE 'uw_%'"] 2992 sl,
2968 in 2993 "') AND attname LIKE 'uw_%'"]
2969 box [string "res = PQexec(conn, \"", 2994 in
2970 string q, 2995 box [string "res = PQexec(conn, \"",
2971 string "\");", 2996 string q,
2972 newline, 2997 string "\");",
2973 newline, 2998 newline,
2974 string "if (res == NULL) {", 2999 newline,
2975 newline, 3000 string "if (res == NULL) {",
2976 box [string "PQfinish(conn);", 3001 newline,
2977 newline, 3002 box [string "PQfinish(conn);",
2978 string "uw_error(ctx, FATAL, \"Out of memory allocating query result.\");", 3003 newline,
2979 newline], 3004 string "uw_error(ctx, FATAL, \"Out of memory allocating query result.\");",
2980 string "}", 3005 newline],
2981 newline, 3006 string "}",
2982 newline, 3007 newline,
2983 string "if (PQresultStatus(res) != PGRES_TUPLES_OK) {", 3008 newline,
2984 newline, 3009 string "if (PQresultStatus(res) != PGRES_TUPLES_OK) {",
2985 box [string "char msg[1024];", 3010 newline,
2986 newline, 3011 box [string "char msg[1024];",
2987 string "strncpy(msg, PQerrorMessage(conn), 1024);", 3012 newline,
2988 newline, 3013 string "strncpy(msg, PQerrorMessage(conn), 1024);",
2989 string "msg[1023] = 0;", 3014 newline,
2990 newline, 3015 string "msg[1023] = 0;",
2991 string "PQclear(res);", 3016 newline,
2992 newline, 3017 string "PQclear(res);",
2993 string "PQfinish(conn);", 3018 newline,
2994 newline, 3019 string "PQfinish(conn);",
2995 string "uw_error(ctx, FATAL, \"Query failed:\\n", 3020 newline,
2996 string q, 3021 string "uw_error(ctx, FATAL, \"Query failed:\\n",
2997 string "\\n%s\", msg);", 3022 string q,
2998 newline], 3023 string "\\n%s\", msg);",
2999 string "}", 3024 newline],
3000 newline, 3025 string "}",
3001 newline, 3026 newline,
3002 string "if (strcmp(PQgetvalue(res, 0, 0), \"1\")) {", 3027 newline,
3003 newline, 3028 string "if (strcmp(PQgetvalue(res, 0, 0), \"1\")) {",
3004 box [string "PQclear(res);", 3029 newline,
3005 newline, 3030 box [string "PQclear(res);",
3006 string "PQfinish(conn);", 3031 newline,
3007 newline, 3032 string "PQfinish(conn);",
3008 string "uw_error(ctx, FATAL, \"Table '", 3033 newline,
3009 string s, 3034 string "uw_error(ctx, FATAL, \"Table '",
3010 string "' does not exist.\");", 3035 string s,
3011 newline], 3036 string "' does not exist.\");",
3012 string "}", 3037 newline],
3013 newline, 3038 string "}",
3014 newline, 3039 newline,
3015 string "PQclear(res);", 3040 newline,
3016 newline, 3041 string "PQclear(res);",
3017 3042 newline,
3018 string "res = PQexec(conn, \"", 3043
3019 string q', 3044 string "res = PQexec(conn, \"",
3020 string "\");", 3045 string q',
3021 newline, 3046 string "\");",
3022 newline, 3047 newline,
3023 string "if (res == NULL) {", 3048 newline,
3024 newline, 3049 string "if (res == NULL) {",
3025 box [string "PQfinish(conn);", 3050 newline,
3026 newline, 3051 box [string "PQfinish(conn);",
3027 string "uw_error(ctx, FATAL, \"Out of memory allocating query result.\");", 3052 newline,
3028 newline], 3053 string "uw_error(ctx, FATAL, \"Out of memory allocating query result.\");",
3029 string "}", 3054 newline],
3030 newline, 3055 string "}",
3031 newline, 3056 newline,
3032 string "if (PQresultStatus(res) != PGRES_TUPLES_OK) {", 3057 newline,
3033 newline, 3058 string "if (PQresultStatus(res) != PGRES_TUPLES_OK) {",
3034 box [string "char msg[1024];", 3059 newline,
3035 newline, 3060 box [string "char msg[1024];",
3036 string "strncpy(msg, PQerrorMessage(conn), 1024);", 3061 newline,
3037 newline, 3062 string "strncpy(msg, PQerrorMessage(conn), 1024);",
3038 string "msg[1023] = 0;", 3063 newline,
3039 newline, 3064 string "msg[1023] = 0;",
3040 string "PQclear(res);", 3065 newline,
3041 newline, 3066 string "PQclear(res);",
3042 string "PQfinish(conn);", 3067 newline,
3043 newline, 3068 string "PQfinish(conn);",
3044 string "uw_error(ctx, FATAL, \"Query failed:\\n", 3069 newline,
3045 string q', 3070 string "uw_error(ctx, FATAL, \"Query failed:\\n",
3046 string "\\n%s\", msg);", 3071 string q',
3047 newline], 3072 string "\\n%s\", msg);",
3048 string "}", 3073 newline],
3049 newline, 3074 string "}",
3050 newline, 3075 newline,
3051 string "if (strcmp(PQgetvalue(res, 0, 0), \"", 3076 newline,
3052 string (Int.toString (length xts)), 3077 string "if (strcmp(PQgetvalue(res, 0, 0), \"",
3053 string "\")) {", 3078 string (Int.toString (length xts)),
3054 newline, 3079 string "\")) {",
3055 box [string "PQclear(res);", 3080 newline,
3056 newline, 3081 box [string "PQclear(res);",
3057 string "PQfinish(conn);", 3082 newline,
3058 newline, 3083 string "PQfinish(conn);",
3059 string "uw_error(ctx, FATAL, \"Table '", 3084 newline,
3060 string s, 3085 string "uw_error(ctx, FATAL, \"Table '",
3061 string "' has the wrong column types.\");", 3086 string s,
3062 newline], 3087 string "' has the wrong column types.\");",
3063 string "}", 3088 newline],
3064 newline, 3089 string "}",
3065 newline, 3090 newline,
3066 string "PQclear(res);", 3091 newline,
3067 newline, 3092 string "PQclear(res);",
3068 newline, 3093 newline,
3069 3094 newline,
3070 string "res = PQexec(conn, \"", 3095
3071 string q'', 3096 string "res = PQexec(conn, \"",
3072 string "\");", 3097 string q'',
3073 newline, 3098 string "\");",
3074 newline, 3099 newline,
3075 string "if (res == NULL) {", 3100 newline,
3076 newline, 3101 string "if (res == NULL) {",
3077 box [string "PQfinish(conn);", 3102 newline,
3078 newline, 3103 box [string "PQfinish(conn);",
3079 string "uw_error(ctx, FATAL, \"Out of memory allocating query result.\");", 3104 newline,
3080 newline], 3105 string "uw_error(ctx, FATAL, \"Out of memory allocating query result.\");",
3081 string "}", 3106 newline],
3082 newline, 3107 string "}",
3083 newline, 3108 newline,
3084 string "if (PQresultStatus(res) != PGRES_TUPLES_OK) {", 3109 newline,
3085 newline, 3110 string "if (PQresultStatus(res) != PGRES_TUPLES_OK) {",
3086 box [string "char msg[1024];", 3111 newline,
3087 newline, 3112 box [string "char msg[1024];",
3088 string "strncpy(msg, PQerrorMessage(conn), 1024);", 3113 newline,
3089 newline, 3114 string "strncpy(msg, PQerrorMessage(conn), 1024);",
3090 string "msg[1023] = 0;", 3115 newline,
3091 newline, 3116 string "msg[1023] = 0;",
3092 string "PQclear(res);", 3117 newline,
3093 newline, 3118 string "PQclear(res);",
3094 string "PQfinish(conn);", 3119 newline,
3095 newline, 3120 string "PQfinish(conn);",
3096 string "uw_error(ctx, FATAL, \"Query failed:\\n", 3121 newline,
3097 string q'', 3122 string "uw_error(ctx, FATAL, \"Query failed:\\n",
3098 string "\\n%s\", msg);", 3123 string q'',
3099 newline], 3124 string "\\n%s\", msg);",
3100 string "}", 3125 newline],
3101 newline, 3126 string "}",
3102 newline, 3127 newline,
3103 string "if (strcmp(PQgetvalue(res, 0, 0), \"", 3128 newline,
3104 string (Int.toString (length xts)), 3129 string "if (strcmp(PQgetvalue(res, 0, 0), \"",
3105 string "\")) {", 3130 string (Int.toString (length xts)),
3106 newline, 3131 string "\")) {",
3107 box [string "PQclear(res);", 3132 newline,
3108 newline, 3133 box [string "PQclear(res);",
3109 string "PQfinish(conn);", 3134 newline,
3110 newline, 3135 string "PQfinish(conn);",
3111 string "uw_error(ctx, FATAL, \"Table '", 3136 newline,
3112 string s, 3137 string "uw_error(ctx, FATAL, \"Table '",
3113 string "' has extra columns.\");", 3138 string s,
3114 newline], 3139 string "' has extra columns.\");",
3115 string "}", 3140 newline],
3116 newline, 3141 string "}",
3117 newline, 3142 newline,
3118 string "PQclear(res);", 3143 newline,
3119 newline] 3144 string "PQclear(res);",
3120 end) tables, 3145 newline]
3121 3146 end) tables,
3122 p_list_sep newline 3147
3123 (fn s => 3148 p_list_sep newline
3124 let 3149 (fn s =>
3125 val sl = CharVector.map Char.toLower s 3150 let
3126 3151 val sl = CharVector.map Char.toLower s
3127 val q = "SELECT COUNT(*) FROM pg_class WHERE relname = '" 3152
3128 ^ sl ^ "' AND relkind = 'S'" 3153 val q = "SELECT COUNT(*) FROM pg_class WHERE relname = '"
3129 in 3154 ^ sl ^ "' AND relkind = 'S'"
3130 box [string "res = PQexec(conn, \"", 3155 in
3131 string q, 3156 box [string "res = PQexec(conn, \"",
3132 string "\");", 3157 string q,
3133 newline, 3158 string "\");",
3134 newline, 3159 newline,
3135 string "if (res == NULL) {", 3160 newline,
3136 newline, 3161 string "if (res == NULL) {",
3137 box [string "PQfinish(conn);", 3162 newline,
3138 newline, 3163 box [string "PQfinish(conn);",
3139 string "uw_error(ctx, FATAL, \"Out of memory allocating query result.\");", 3164 newline,
3140 newline], 3165 string "uw_error(ctx, FATAL, \"Out of memory allocating query result.\");",
3141 string "}", 3166 newline],
3142 newline, 3167 string "}",
3143 newline, 3168 newline,
3144 string "if (PQresultStatus(res) != PGRES_TUPLES_OK) {", 3169 newline,
3145 newline, 3170 string "if (PQresultStatus(res) != PGRES_TUPLES_OK) {",
3146 box [string "char msg[1024];", 3171 newline,
3147 newline, 3172 box [string "char msg[1024];",
3148 string "strncpy(msg, PQerrorMessage(conn), 1024);", 3173 newline,
3149 newline, 3174 string "strncpy(msg, PQerrorMessage(conn), 1024);",
3150 string "msg[1023] = 0;", 3175 newline,
3151 newline, 3176 string "msg[1023] = 0;",
3152 string "PQclear(res);", 3177 newline,
3153 newline, 3178 string "PQclear(res);",
3154 string "PQfinish(conn);", 3179 newline,
3155 newline, 3180 string "PQfinish(conn);",
3156 string "uw_error(ctx, FATAL, \"Query failed:\\n", 3181 newline,
3157 string q, 3182 string "uw_error(ctx, FATAL, \"Query failed:\\n",
3158 string "\\n%s\", msg);", 3183 string q,
3159 newline], 3184 string "\\n%s\", msg);",
3160 string "}", 3185 newline],
3161 newline, 3186 string "}",
3162 newline, 3187 newline,
3163 string "if (strcmp(PQgetvalue(res, 0, 0), \"1\")) {", 3188 newline,
3164 newline, 3189 string "if (strcmp(PQgetvalue(res, 0, 0), \"1\")) {",
3165 box [string "PQclear(res);", 3190 newline,
3166 newline, 3191 box [string "PQclear(res);",
3167 string "PQfinish(conn);", 3192 newline,
3168 newline, 3193 string "PQfinish(conn);",
3169 string "uw_error(ctx, FATAL, \"Sequence '", 3194 newline,
3170 string s, 3195 string "uw_error(ctx, FATAL, \"Sequence '",
3171 string "' does not exist.\");", 3196 string s,
3172 newline], 3197 string "' does not exist.\");",
3173 string "}", 3198 newline],
3174 newline, 3199 string "}",
3175 newline, 3200 newline,
3176 string "PQclear(res);", 3201 newline,
3177 newline] 3202 string "PQclear(res);",
3178 end) sequences, 3203 newline]
3179 3204 end) sequences,
3180 string "}"] 3205
3206 string "}"]
3207 else
3208 string "static void uw_db_validate(uw_context ctx) { }"
3181 3209
3182 val hasDb = List.exists (fn (DDatabase _, _) => true | _ => false) ds 3210 val hasDb = List.exists (fn (DDatabase _, _) => true | _ => false) ds
3183 3211
3184 val cookies = List.mapPartial (fn (DCookie s, _) => SOME s | _ => NONE) ds 3212 val cookies = List.mapPartial (fn (DCookie s, _) => SOME s | _ => NONE) ds
3185 3213