summaryrefslogtreecommitdiff
path: root/src/cjr_print.sml
diff options
context:
space:
mode:
Diffstat (limited to 'src/cjr_print.sml')
-rw-r--r--src/cjr_print.sml195
1 files changed, 118 insertions, 77 deletions
diff --git a/src/cjr_print.sml b/src/cjr_print.sml
index a12e5bc1..938821be 100644
--- a/src/cjr_print.sml
+++ b/src/cjr_print.sml
@@ -321,6 +321,18 @@ fun patConInfo env pc =
"lw_" ^ m ^ "_" ^ con,
"lw_" ^ con)
+fun p_unsql env (tAll as (t, loc)) e =
+ case t of
+ TFfi ("Basis", "int") => box [string "*(lw_Basis_int *)", e]
+ | TFfi ("Basis", "float") => box [string "*(lw_Basis_float *)", e]
+ | TFfi ("Basis", "string") => box [string "lw_Basis_strdup(ctx, ", e, string ")"]
+ | TFfi ("Basis", "bool") => box [string "(*(int *)",
+ e,
+ string " ? lw_Basis_True : lw_Basis_False)"]
+ | _ => (ErrorMsg.errorAt loc "Don't know how to unmarshal type from SQL";
+ Print.eprefaces' [("Type", p_typ env tAll)];
+ string "ERROR")
+
fun p_exp' par env (e, loc) =
case e of
EPrim p => Prim.p_t_GCC p
@@ -549,86 +561,115 @@ fun p_exp' par env (e, loc) =
string "})"]
| EQuery {exps, tables, rnum, state, query, body, initial} =>
- box [string "({",
- newline,
- string "PGconn *conn = lw_get_db(ctx);",
- newline,
- string "char *query = ",
- p_exp env query,
- string ";",
- newline,
- string "int n, i;",
- newline,
- p_typ env state,
- space,
- string "acc",
- space,
- string "=",
- space,
- p_exp env initial,
- string ";",
- newline,
- string "PGresult *res = PQexecParams(conn, query, 0, NULL, NULL, NULL, NULL, 1);",
- newline,
- newline,
+ let
+ val exps = map (fn (x, t) => ("__lwf_" ^ x, t)) exps
+ val tables = ListUtil.mapConcat (fn (x, xts) =>
+ map (fn (x', t) => ("__lwf_" ^ x ^ ".__lwf_" ^ x', t)) xts)
+ tables
+
+ val outputs = exps @ tables
+ in
+ box [string "({",
+ newline,
+ string "PGconn *conn = lw_get_db(ctx);",
+ newline,
+ string "char *query = ",
+ p_exp env query,
+ string ";",
+ newline,
+ string "int n, i;",
+ newline,
+ p_typ env state,
+ space,
+ string "acc",
+ space,
+ string "=",
+ space,
+ p_exp env initial,
+ string ";",
+ newline,
+ string "PGresult *res = PQexecParams(conn, query, 0, NULL, NULL, NULL, NULL, 1);",
+ newline,
+ newline,
- string "if (res == NULL) lw_error(ctx, FATAL, \"Out of memory allocating query result.\");",
- newline,
- newline,
+ string "if (res == NULL) lw_error(ctx, FATAL, \"Out of memory allocating query result.\");",
+ newline,
+ newline,
- string "if (PQresultStatus(res) != PGRES_TUPLES_OK) {",
- newline,
- box [string "PQclear(res);",
- newline,
- string "lw_error(ctx, FATAL, \"",
- string (ErrorMsg.spanToString loc),
- string ": Query failed:\\n%s\\n%s\", query, PQerrorMessage(conn));",
- newline],
- string "}",
- newline,
- newline,
+ string "if (PQresultStatus(res) != PGRES_TUPLES_OK) {",
+ newline,
+ box [string "PQclear(res);",
+ newline,
+ string "lw_error(ctx, FATAL, \"",
+ string (ErrorMsg.spanToString loc),
+ string ": Query failed:\\n%s\\n%s\", query, PQerrorMessage(conn));",
+ newline],
+ string "}",
+ newline,
+ newline,
- string "n = PQntuples(res);",
- newline,
- string "for (i = 0; i < n; ++i) {",
- newline,
- box [string "struct",
- space,
- string "__lws_",
- string (Int.toString rnum),
- space,
- string "__lwr_r_",
- string (Int.toString (E.countERels env)),
- string ";",
- newline,
- p_typ env state,
- space,
- string "__lwr_acc_",
- string (Int.toString (E.countERels env + 1)),
- space,
- string "=",
- space,
- string "acc;",
- newline,
- newline,
- string "acc",
- space,
- string "=",
- space,
- p_exp (E.pushERel
- (E.pushERel env "r" (TRecord rnum, loc))
- "acc" state)
- body,
- string ";",
- newline],
- string "}",
- newline,
- newline,
- string "PQclear(res);",
- newline,
- string "acc;",
- newline,
- string "})"]
+ string "n = PQntuples(res);",
+ newline,
+ string "for (i = 0; i < n; ++i) {",
+ newline,
+ box [string "struct",
+ space,
+ string "__lws_",
+ string (Int.toString rnum),
+ space,
+ string "__lwr_r_",
+ string (Int.toString (E.countERels env)),
+ string ";",
+ newline,
+ p_typ env state,
+ space,
+ string "__lwr_acc_",
+ string (Int.toString (E.countERels env + 1)),
+ space,
+ string "=",
+ space,
+ string "acc;",
+ newline,
+ newline,
+
+ p_list_sepi (box []) (fn i =>
+ fn (proj, t) =>
+ box [string "__lwr_r_",
+ string (Int.toString (E.countERels env)),
+ string ".",
+ string proj,
+ space,
+ string "=",
+ space,
+ p_unsql env t
+ (box [string "PQgetvalue(res, i, ",
+ string (Int.toString i),
+ string ")"]),
+ string ";",
+ newline]) outputs,
+
+ newline,
+ newline,
+
+ string "acc",
+ space,
+ string "=",
+ space,
+ p_exp (E.pushERel
+ (E.pushERel env "r" (TRecord rnum, loc))
+ "acc" state)
+ body,
+ string ";",
+ newline],
+ string "}",
+ newline,
+ newline,
+ string "PQclear(res);",
+ newline,
+ string "acc;",
+ newline,
+ string "})"]
+ end
and p_exp env = p_exp' false env