Mercurial > urweb
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, |