📄 database.java
字号:
result.p("\n)"); return result.extract(); } private void appendForeignKeys(StringBuilder result, Relation[] possibleSubSets, Relation superSet, int idx) throws Exception { for (int i=0; i<possibleSubSets.length && possibleSubSets[i] != superSet; ++i) if (ArraysExt.isSubSuperSet(possibleSubSets[i].keys, superSet.keys, Relations.ATTR_KEY_CMP)) appendForeignKeys(result, possibleSubSets[i], superSet, idx); } private void appendForeignKeys(StringBuilder result, Relation subSet, Relation superSet, int idx) throws Exception { int[][] mappings = ArraysExt.mapSubToAllSuperSets(subSet.keys, superSet.keys, Relations.ATTR_KEY_CMP); for (int i=0; i<mappings.length; ++i) { result.p("\n, FOREIGN KEY ("); appendWithSep(result, "", ", ", ArraysExt.pick(mappings[i], superSet.keys), FORMAT_UNTYPED_ATTR); result.p(") REFERENCES ").p(withBasenameAndIdx(subSet, idx)).p(" ("); appendWithSep(result, "", ", ", subSet.keys, FORMAT_UNTYPED_ATTR); result.p(")"); } } private static final ObjectToObject FORMAT_TYPED_ATTR = new ObjectToObject() { public Object with(Object attrO) { Attr attr = (Attr)attrO; return attr.name + " " + ("shared_str".equals(attr.type) ? "int" : attr.type); }}; private static final ObjectToObject FORMAT_UNTYPED_ATTR = new ObjectToObject() { public Object with(Object attr) { return ((Attr)attr).name; }}; private static void appendWithSep(StringBuilder result, String firstSep, String restSep, Object[] elems, ObjectToObject formatter) throws Exception { for (int i=0; i<elems.length; ++i) result.p(0 == i ? firstSep : restSep).p(formatter.with(elems[i])); } private String[] findTableNames(String pattern) throws Exception { ArrayList result = new ArrayList(); for (ResultSet rs = getMetaData().getTables(null, "", pattern, null); rs.next();) result.add(rs.getString(3)); return (String[])result.toArray(new String[result.size()]); } private Env createEnv(final StringBuffer result, int selectedIndex, int[] selectedIndices) throws Exception { Env env = Lisp.createEnv(); // Provide default indices (if there is anything to select from) if ((-1 == selectedIndex || 0 == selectedIndices.length) && 0 < historyList.getSize()) { selectedIndex = 0; selectedIndices = new int[]{selectedIndex}; } env.add(Symbol.create("selected-index"), indexToInteger(selectedIndex)); Object[] indices = new Object[selectedIndices.length]; for (int i=0; i<indices.length; ++i) indices[i] = indexToInteger(selectedIndices[i]); env.add(Symbol.create("selected-indices"), indices); env.add(Symbol.create("emit"), new Lisp.Function() { public Object with(Object arg, Env env) throws Exception { Pair.map(arg, new minijlisp.util.ObjectToObject() { public Object with(Object o) { return result.append(o); } }); return null; }}); env.add(Symbol.create("failwith"), new Lisp.Function() { public Object with(Object arg, Env env) throws Exception { final StringBuffer message = new StringBuffer(); Pair.map(arg, new minijlisp.util.ObjectToObject() { public Object with(Object o) { return message.append(o); } }); throw new ActionCancelledException(message.toString(), "Query failed!", JOptionPane.ERROR_MESSAGE); }}); env.add(Symbol.create("shared-tbl-name"), new Lisp.Function() { public Object with(Object rest, Env env) throws Exception { return withBasename(Pair.firstAt(rest,0).toString()); } }); env.add(Symbol.create("snapshot-tbl-name"), new Lisp.Function() { public Object with(Object rest, Env env) throws Exception { return withBasenameAndIdx(Pair.firstAt(rest,0).toString(), ((Integer)Pair.firstAt(rest,1)).intValue()); } }); return env; } private Integer indexToInteger(int index) { return new Integer(0 <= index && index < historyList.getSize() ? ((HistoryList.Entry)historyList.getElementAt(index)).idx : -1); } private String markup(final String code, final String markupOpen, final String markupClose) throws Exception { final StringBuffer result = new StringBuffer(); new VoidToVoid() { int directBegin = 0; int offset = 0; public void with() { while (more()) { copyUntil(markupOpen); endDirect(); if (!more()) break; copyUntil(markupClose); beginDirect(); } } boolean more() { return offset < code.length(); } void copyUntil(String marker) { while (!matches(marker) && more()) copy(); } boolean matches(String prefix) { return code.regionMatches(offset, prefix, 0, prefix.length()); } void copy() { if (directBegin == offset) result.append("(emit \""); result.append(code.charAt(offset)); offset += 1; } void beginDirect() { offset += markupClose.length(); directBegin = offset; } void endDirect() { if (more() && !matches(markupOpen)) throw new RuntimeException("Error: `" + markupOpen + "' was not matched by an `" + markupClose + "'."); if (directBegin < offset) result.append("\")"); offset += markupOpen.length(); } }.with(); return result.toString(); } private class StrTable { StrTable() throws Exception { for (ResultSet rs = query("SELECT * FROM " + withBasename(STR_RELATION)); rs.next();) strToId.put(rs.getString(2), new Integer(rs.getInt(1))); } int put(String str) throws Exception { Object result = strToId.get(str); if (null != result) { return ((Integer)result).intValue(); } else { int next = strToId.size(); update("INSERT INTO " + withBasename(STR_RELATION) + " VALUES (" + next + ", '" + str + "')"); strToId.put(str, new Integer(next)); return next; } } private HashMap strToId = new HashMap(); } private String withBasename(Relation relation) { return withBasename(relation.name); } private String withBasenameAndIdx(Relation relation, int idx) { return withBasenameAndIdx(relation.name, idx); } private String withBasename(String name) { return basename + "_" + name; } private String withBasenameAndIdx(String name, int idx) { return withBasename(name) + (-1 == idx ? "" : "_" + idx); } private static final Attr ID_ATTR = new Attr("id", "int"), STR_ATTR = new Attr("str", "varchar(511) UNIQUE NOT NULL"), IDX_ATTR = new Attr("idx", "int"), TS_ATTR = new Attr("ts", "timestamp UNIQUE NOT NULL"), NAME_ATTR = new Attr("name", "varchar(80)"); private static final Relation STR_RELATION = new Relation("str", new Attr[]{ID_ATTR}, new Attr[]{STR_ATTR}), HISTORY_RELATION = new Relation("history", new Attr[]{IDX_ATTR}, new Attr[]{TS_ATTR, NAME_ATTR}); private static final Relation[] RELATIONS = { STR_RELATION, HISTORY_RELATION}; public final HistoryList historyList = new HistoryList(); public final String basename;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -