# HG changeset patch # User Adam Chlipala # Date 1220814352 14400 # Node ID 52d4c60518d46ff9acee92ca55d3b15c7c4b9e85 # Parent 99e4f39e820dc4df57aa375942bbe5802d7c7aaf First INSERT works diff -r 99e4f39e820d -r 52d4c60518d4 src/cjr.sml --- a/src/cjr.sml Sun Sep 07 14:38:14 2008 -0400 +++ b/src/cjr.sml Sun Sep 07 15:05:52 2008 -0400 @@ -85,6 +85,8 @@ body : exp, initial : exp, prepared : int option } + | EDml of { dml : exp, + prepared : int option } withtype exp = exp' located diff -r 99e4f39e820d -r 52d4c60518d4 src/cjr_print.sml --- a/src/cjr_print.sml Sun Sep 07 14:38:14 2008 -0400 +++ b/src/cjr_print.sml Sun Sep 07 15:05:52 2008 -0400 @@ -857,6 +857,83 @@ string "})"] end + | EDml {dml, prepared} => + box [string "({", + newline, + string "PGconn *conn = lw_get_db(ctx);", + newline, + case prepared of + NONE => box [string "char *dml = ", + p_exp env dml, + string ";", + newline] + | SOME _ => + let + val ets = getPargs dml + in + box [p_list_sepi newline + (fn i => fn (e, t) => + box [p_sql_type t, + space, + string "arg", + string (Int.toString (i + 1)), + space, + string "=", + space, + p_exp env e, + string ";"]) + ets, + newline, + newline, + + string "const char *paramValues[] = { ", + p_list_sepi (box [string ",", space]) + (fn i => fn (_, t) => p_ensql t (box [string "arg", + string (Int.toString (i + 1))])) + ets, + string " };", + newline, + newline] + end, + newline, + newline, + string "PGresult *res = ", + case prepared of + NONE => string "PQexecParams(conn, dml, 0, NULL, NULL, NULL, NULL, 0);" + | SOME n => box [string "PQexecPrepared(conn, \"lw", + string (Int.toString n), + string "\", ", + string (Int.toString (length (getPargs dml))), + string ", paramValues, NULL, NULL, 0);"], + newline, + newline, + + string "if (res == NULL) lw_error(ctx, FATAL, \"Out of memory allocating DML result.\");", + newline, + newline, + + string "if (PQresultStatus(res) != PGRES_COMMAND_OK) {", + newline, + box [string "PQclear(res);", + newline, + string "lw_error(ctx, FATAL, \"", + string (ErrorMsg.spanToString loc), + string ": DML failed:\\n%s\\n%s\", ", + case prepared of + NONE => string "dml" + | SOME _ => p_exp env dml, + string ", PQerrorMessage(conn));", + newline], + string "}", + newline, + newline, + + string "PQclear(res);", + newline, + string "lw_unit_v;", + newline, + string "})"] + and p_exp env = p_exp' false env fun p_fun env (fx, n, args, ran, e) = diff -r 99e4f39e820d -r 52d4c60518d4 src/cjrize.sml --- a/src/cjrize.sml Sun Sep 07 14:38:14 2008 -0400 +++ b/src/cjrize.sml Sun Sep 07 15:05:52 2008 -0400 @@ -374,6 +374,13 @@ query = query, body = body, initial = initial, prepared = NONE}, loc), sm) end + | L.EDml e => + let + val (e, sm) = cifyExp (e, sm) + in + ((L'.EDml {dml = e, prepared = NONE}, loc), sm) + end + fun cifyDecl ((d, loc), sm) = case d of diff -r 99e4f39e820d -r 52d4c60518d4 src/mono.sml --- a/src/mono.sml Sun Sep 07 14:38:14 2008 -0400 +++ b/src/mono.sml Sun Sep 07 15:05:52 2008 -0400 @@ -88,6 +88,7 @@ query : exp, body : exp, initial : exp } + | EDml of exp withtype exp = exp' located diff -r 99e4f39e820d -r 52d4c60518d4 src/mono_print.sml --- a/src/mono_print.sml Sun Sep 07 14:38:14 2008 -0400 +++ b/src/mono_print.sml Sun Sep 07 15:05:52 2008 -0400 @@ -257,6 +257,9 @@ string "in", space, p_exp (E.pushERel (E.pushERel env "r" dummyt NONE) "acc" dummyt NONE) body] + | EDml e => box [string "dml(", + p_exp env e, + string ")"] and p_exp env = p_exp' false env diff -r 99e4f39e820d -r 52d4c60518d4 src/mono_reduce.sml --- a/src/mono_reduce.sml Sun Sep 07 14:38:14 2008 -0400 +++ b/src/mono_reduce.sml Sun Sep 07 15:05:52 2008 -0400 @@ -39,6 +39,7 @@ case e of EWrite _ => true | EQuery _ => true + | EDml _ => true | EAbs _ => false | EPrim _ => false diff -r 99e4f39e820d -r 52d4c60518d4 src/mono_util.sml --- a/src/mono_util.sml Sun Sep 07 14:38:14 2008 -0400 +++ b/src/mono_util.sml Sun Sep 07 15:05:52 2008 -0400 @@ -285,6 +285,11 @@ body = body', initial = initial'}, loc))))))) + + | EDml e => + S.map2 (mfe ctx e, + fn e' => + (EDml e', loc)) in mfe end diff -r 99e4f39e820d -r 52d4c60518d4 src/monoize.sml --- a/src/monoize.sml Sun Sep 07 14:38:14 2008 -0400 +++ b/src/monoize.sml Sun Sep 07 15:05:52 2008 -0400 @@ -591,6 +591,39 @@ fm) end + | L.EFfiApp ("Basis", "dml", [e]) => + let + val (e, fm) = monoExp (env, st, fm) e + val un = (L'.TRecord [], loc) + in + ((L'.EAbs ("_", un, un, + (L'.EDml (liftExpInExp 0 e), loc)), loc), + fm) + end + | L.ECApp ((L.EFfi ("Basis", "insert"), _), fields) => + (case monoType env (L.TRecord fields, loc) of + (L'.TRecord fields, _) => + let + val s = (L'.TFfi ("Basis", "string"), loc) + val fields = map (fn (x, _) => (x, s)) fields + val rt = (L'.TRecord fields, loc) + fun sc s = (L'.EPrim (Prim.String s), loc) + in + ((L'.EAbs ("tab", s, (L'.TFun (rt, s), loc), + (L'.EAbs ("fs", rt, s, + strcat loc [sc "INSERT INTO ", + (L'.ERel 1, loc), + sc " (", + strcatComma loc (map (fn (x, _) => sc ("lw_" ^ x)) fields), + sc ") VALUES (", + strcatComma loc (map (fn (x, _) => + (L'.EField ((L'.ERel 0, loc), + x), loc)) fields), + sc ")"]), loc)), loc), + fm) + end + | _ => poly ()) + | L.ECApp ( (L.ECApp ( (L.ECApp ((L.EFfi ("Basis", "query"), _), (L.CRecord (_, tables), _)), _), diff -r 99e4f39e820d -r 52d4c60518d4 src/prepare.sml --- a/src/prepare.sml Sun Sep 07 14:38:14 2008 -0400 +++ b/src/prepare.sml Sun Sep 07 15:05:52 2008 -0400 @@ -150,6 +150,13 @@ initial = initial, prepared = SOME (#2 sns)}, loc), ((String.concat (rev ss), n) :: #1 sns, #2 sns + 1))) + | EDml {dml, ...} => + (case prepString (dml, [], 0) of + NONE => (e, sns) + | SOME (ss, n) => + ((EDml {dml = dml, prepared = SOME (#2 sns)}, loc), + ((String.concat (rev ss), n) :: #1 sns, #2 sns + 1))) + fun prepDecl (d as (_, loc), sns) = case #1 d of DStruct _ => (d, sns)