comparison src/mysql.sml @ 1979:81bc76aa4acd

Merge in upstream changes.
author Patrick Hurst <phurst@mit.edu>
date Sat, 18 Jan 2014 18:26:24 -0500
parents ef9fdbb05c73
children 6bea98c7f736
comparison
equal deleted inserted replaced
1978:c5143edaf3c7 1979:81bc76aa4acd
74 | ch => str ch) 74 | ch => str ch)
75 75
76 fun checkRel (table, checkNullable) (s, xts) = 76 fun checkRel (table, checkNullable) (s, xts) =
77 let 77 let
78 val sl = CharVector.map Char.toLower s 78 val sl = CharVector.map Char.toLower s
79 val both = "table_name IN ('" ^ sl ^ "', '" ^ s ^ "')" 79 val sl = if size sl > 1 andalso String.sub (sl, 0) = #"\"" then
80 String.substring (sl, 1, size sl - 2)
81 else
82 sl
83 val both = "LOWER(table_name) = ('" ^ sl ^ "')"
80 84
81 val q = "SELECT COUNT(*) FROM information_schema." ^ table ^ " WHERE " ^ both 85 val q = "SELECT COUNT(*) FROM information_schema." ^ table ^ " WHERE " ^ both
82 86
83 val q' = String.concat ["SELECT COUNT(*) FROM information_schema.columns WHERE ", 87 val q' = String.concat ["SELECT COUNT(*) FROM information_schema.columns WHERE ",
84 both, 88 both,
85 " AND (", 89 " AND (",
86 case String.concatWith " OR " 90 case String.concatWith " OR "
87 (map (fn (x, t) => 91 (map (fn (x, t) =>
88 String.concat ["(column_name IN ('uw_", 92 String.concat ["(LOWER(column_name) = '",
89 CharVector.map 93 Settings.mangleSqlCatalog
90 Char.toLower (ident x), 94 (CharVector.map
91 "', 'uw_", 95 Char.toLower (ident x)),
92 ident x, 96 "' AND data_type ",
93 "') AND data_type = '", 97 case p_sql_type_base t of
94 p_sql_type_base t, 98 "bigint" =>
95 "'", 99 "IN ('bigint', 'int')"
100 | "longtext" =>
101 "IN ('longtext', 'varchar')"
102 | s => "= '" ^ s ^ "'",
96 if checkNullable then 103 if checkNullable then
97 (" AND is_nullable = '" 104 (" AND is_nullable = '"
98 ^ (if isNotNull t then 105 ^ (if isNotNull t then
99 "NO" 106 "NO"
100 else 107 else
107 | s => s, 114 | s => s,
108 ")"] 115 ")"]
109 116
110 val q'' = String.concat ["SELECT COUNT(*) FROM information_schema.columns WHERE ", 117 val q'' = String.concat ["SELECT COUNT(*) FROM information_schema.columns WHERE ",
111 both, 118 both,
112 " AND column_name LIKE 'uw_%'"] 119 " AND LOWER(column_name) LIKE '", Settings.mangleSqlCatalog "%'"]
113 in 120 in
114 box [string "if (mysql_query(conn->conn, \"", 121 box [string "if (mysql_query(conn->conn, \"",
115 string q, 122 string q,
116 string "\")) {", 123 string "\")) {",
117 newline, 124 newline,
172 box [string "mysql_free_result(res);", 179 box [string "mysql_free_result(res);",
173 newline, 180 newline,
174 string "mysql_close(conn->conn);", 181 string "mysql_close(conn->conn);",
175 newline, 182 newline,
176 string "uw_error(ctx, FATAL, \"Table '", 183 string "uw_error(ctx, FATAL, \"Table '",
177 string s, 184 string sl,
178 string "' does not exist.\");", 185 string "' does not exist.\");",
179 newline], 186 newline],
180 string "}", 187 string "}",
181 newline, 188 newline,
182 newline, 189 newline,
247 box [string "mysql_free_result(res);", 254 box [string "mysql_free_result(res);",
248 newline, 255 newline,
249 string "mysql_close(conn->conn);", 256 string "mysql_close(conn->conn);",
250 newline, 257 newline,
251 string "uw_error(ctx, FATAL, \"Table '", 258 string "uw_error(ctx, FATAL, \"Table '",
252 string s, 259 string sl,
253 string "' has the wrong column types.\");", 260 string "' has the wrong column types.\");",
254 newline], 261 newline],
255 string "}", 262 string "}",
256 newline, 263 newline,
257 newline, 264 newline,
322 box [string "mysql_free_result(res);", 329 box [string "mysql_free_result(res);",
323 newline, 330 newline,
324 string "mysql_close(conn->conn);", 331 string "mysql_close(conn->conn);",
325 newline, 332 newline,
326 string "uw_error(ctx, FATAL, \"Table '", 333 string "uw_error(ctx, FATAL, \"Table '",
327 string s, 334 string sl,
328 string "' has extra columns.\");", 335 string "' has extra columns.\");",
329 newline], 336 newline],
330 string "}", 337 string "}",
331 newline, 338 newline,
332 newline, 339 newline,
527 case !port of 534 case !port of
528 NONE => string "0" 535 NONE => string "0"
529 | SOME n => string (Int.toString n), 536 | SOME n => string (Int.toString n),
530 string ", ", 537 string ", ",
531 stringOf unix_socket, 538 stringOf unix_socket,
532 string ", 0) == NULL) {", 539 string ", CLIENT_MULTI_STATEMENTS) == NULL) {",
533 newline, 540 newline,
534 box [string "char msg[1024];", 541 box [string "char msg[1024];",
535 newline, 542 newline,
536 string "strncpy(msg, mysql_error(mysql), 1024);", 543 string "strncpy(msg, mysql_error(mysql), 1024);",
537 newline, 544 newline,
541 newline, 548 newline,
542 string "uw_error(ctx, BOUNDED_RETRY, ", 549 string "uw_error(ctx, BOUNDED_RETRY, ",
543 string "\"Connection to MySQL server failed: %s\", msg);"], 550 string "\"Connection to MySQL server failed: %s\", msg);"],
544 newline, 551 newline,
545 string "}", 552 string "}",
553 newline,
554 newline,
555 string "if (mysql_set_character_set(mysql, \"utf8\")) {",
556 newline,
557 box [string "char msg[1024];",
558 newline,
559 string "strncpy(msg, mysql_error(mysql), 1024);",
560 newline,
561 string "msg[1023] = 0;",
562 newline,
563 string "mysql_close(mysql);",
564 newline,
565 string "uw_error(ctx, FATAL, ",
566 string "\"Error setting UTF-8 character set for MySQL connection: %s\", msg);"],
567 newline,
568 string "}",
569 newline,
546 newline, 570 newline,
547 string "conn = calloc(1, sizeof(uw_conn));", 571 string "conn = calloc(1, sizeof(uw_conn));",
548 newline, 572 newline,
549 string "conn->conn = mysql;", 573 string "conn->conn = mysql;",
550 newline, 574 newline,
575 newline, 599 newline,
576 string "}", 600 string "}",
577 newline, 601 newline,
578 newline, 602 newline,
579 603
580 string "static int uw_db_begin(uw_context ctx) {", 604 string "static int uw_db_begin(uw_context ctx, int could_write) {",
581 newline, 605 newline,
582 string "uw_conn *conn = uw_get_db(ctx);", 606 string "uw_conn *conn = uw_get_db(ctx);",
583 newline, 607 newline,
584 newline, 608 newline,
585 string "return mysql_query(conn->conn, \"SET TRANSACTION ISOLATION LEVEL SERIALIZABLE\")", 609 string "return mysql_query(conn->conn, \"SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; BEGIN\") ? 1 : (mysql_next_result(conn->conn), 0);",
586 newline,
587 string " || mysql_query(conn->conn, \"BEGIN\");",
588 newline, 610 newline,
589 string "}", 611 string "}",
590 newline, 612 newline,
591 newline, 613 newline,
592 614
845 query, 867 query,
846 string ", mysql_error(conn->conn));", 868 string ", mysql_error(conn->conn));",
847 newline, 869 newline,
848 newline, 870 newline,
849 871
850 string "if (mysql_stmt_execute(stmt)) uw_error(ctx, FATAL, \"", 872 string "if (mysql_stmt_execute(stmt)) {",
851 string (ErrorMsg.spanToString loc), 873 newline,
852 string ": Error executing query: %s\\n%s\", ", 874 box [string "if (mysql_errno(conn->conn) == 1213)",
853 query, 875 newline,
854 string ", mysql_error(conn->conn));", 876 box [string "uw_error(ctx, UNLIMITED_RETRY, \"Deadlock detected\");",
877 newline],
878 newline,
879 string "uw_error(ctx, FATAL, \"",
880 string (ErrorMsg.spanToString loc),
881 string ": Error executing query: %s\\n%s\", ",
882 query,
883 string ", mysql_error(conn->conn));",
884 newline],
885 string "}",
855 newline, 886 newline,
856 newline, 887 newline,
857 888
858 string "if (mysql_stmt_bind_result(stmt, out)) uw_error(ctx, FATAL, \"", 889 string "if (mysql_stmt_bind_result(stmt, out)) uw_error(ctx, FATAL, \"",
859 string (ErrorMsg.spanToString loc), 890 string (ErrorMsg.spanToString loc),
1199 newline] 1230 newline]
1200 else 1231 else
1201 box []] 1232 box []]
1202 1233
1203 fun dmlCommon {loc, dml, mode} = 1234 fun dmlCommon {loc, dml, mode} =
1204 box [string "if (mysql_stmt_execute(stmt)) ", 1235 box [string "if (mysql_stmt_execute(stmt)) {",
1205 case mode of 1236 box [string "if (mysql_errno(conn->conn) == 1213)",
1206 Settings.Error => box [string "uw_error(ctx, FATAL, \"", 1237 newline,
1207 string (ErrorMsg.spanToString loc), 1238 box [string "uw_error(ctx, UNLIMITED_RETRY, \"Deadlock detected\");",
1208 string ": Error executing DML: %s\\n%s\", ", 1239 newline],
1209 dml, 1240 newline,
1210 string ", mysql_error(conn->conn));"] 1241 case mode of
1211 | Settings.None => string "uw_set_error_message(ctx, mysql_error(conn->conn));", 1242 Settings.Error => box [string "uw_error(ctx, FATAL, \"",
1212 newline, 1243 string (ErrorMsg.spanToString loc),
1244 string ": Error executing DML: %s\\n%s\", ",
1245 dml,
1246 string ", mysql_error(conn->conn));"]
1247 | Settings.None => string "uw_set_error_message(ctx, mysql_error(conn->conn));",
1248 newline],
1249 string "}",
1213 newline] 1250 newline]
1214 1251
1215 fun dml (loc, mode) = 1252 fun dml (loc, mode) =
1216 box [string "uw_conn *conn = uw_get_db(ctx);", 1253 box [string "uw_conn *conn = uw_get_db(ctx);",
1217 newline, 1254 newline,