init
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Available context bindings:
|
||||
* COLUMNS List<DataColumn>
|
||||
* ROWS Iterable<DataRow>
|
||||
* OUT { append() }
|
||||
* FORMATTER { format(row, col); formatValue(Object, col); getTypeName(Object, col); isStringLiteral(Object, col); }
|
||||
* TRANSPOSED Boolean
|
||||
* plus ALL_COLUMNS, TABLE, DIALECT
|
||||
*
|
||||
* where:
|
||||
* DataRow { rowNumber(); first(); last(); data(): List<Object>; value(column): Object }
|
||||
* DataColumn { columnNumber(), name() }
|
||||
*/
|
||||
|
||||
import static java.math.MathContext.DECIMAL128
|
||||
|
||||
BigDecimal RES = 0
|
||||
int i = 0
|
||||
ROWS.each { row ->
|
||||
COLUMNS.each { column ->
|
||||
def value = row.value(column)
|
||||
if (value instanceof Number) {
|
||||
RES = RES.add(value, DECIMAL128)
|
||||
i++
|
||||
}
|
||||
else if (value.toString().isBigDecimal()) {
|
||||
RES = RES.add(value.toString().toBigDecimal(), DECIMAL128)
|
||||
i++
|
||||
}
|
||||
}
|
||||
}
|
||||
if (i > 0) {
|
||||
RES = RES.divide(i, DECIMAL128)
|
||||
OUT.append(RES.toString())
|
||||
}
|
||||
else {
|
||||
OUT.append("Not enough values")
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Available context bindings:
|
||||
* COLUMNS List<DataColumn>
|
||||
* ROWS Iterable<DataRow>
|
||||
* OUT { append() }
|
||||
* FORMATTER { format(row, col); formatValue(Object, col); getTypeName(Object, col); isStringLiteral(Object, col); }
|
||||
* TRANSPOSED Boolean
|
||||
* plus ALL_COLUMNS, TABLE, DIALECT
|
||||
*
|
||||
* where:
|
||||
* DataRow { rowNumber(); first(); last(); data(): List<Object>; value(column): Object }
|
||||
* DataColumn { columnNumber(), name() }
|
||||
*/
|
||||
|
||||
import static java.math.MathContext.DECIMAL128
|
||||
|
||||
def toBigDecimal = { value ->
|
||||
value instanceof Number ? value as BigDecimal :
|
||||
value.toString().isBigDecimal() ? value.toString() as BigDecimal :
|
||||
null
|
||||
}
|
||||
|
||||
def values = []
|
||||
|
||||
ROWS.each { row ->
|
||||
COLUMNS.each { column ->
|
||||
def bigDecimal = toBigDecimal(row.value(column))
|
||||
if (bigDecimal != null) {
|
||||
values.add(bigDecimal)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (values.isEmpty()) {
|
||||
OUT.append("Not enough values")
|
||||
return
|
||||
}
|
||||
|
||||
def sum = BigDecimal.ZERO
|
||||
values.forEach { value ->
|
||||
sum = sum.add(value, DECIMAL128)
|
||||
}
|
||||
def avg = sum.divide(values.size(), DECIMAL128)
|
||||
def sumSquaredDiff = BigDecimal.ZERO
|
||||
values.each { value ->
|
||||
BigDecimal diff = value.subtract(avg, DECIMAL128)
|
||||
sumSquaredDiff = sumSquaredDiff.add(diff.multiply(diff, DECIMAL128), DECIMAL128)
|
||||
}
|
||||
|
||||
def variance = sumSquaredDiff.divide(values.size(), DECIMAL128)
|
||||
def standardDeviation = variance.sqrt(DECIMAL128)
|
||||
def cv = standardDeviation.divide(avg, DECIMAL128)
|
||||
OUT.append((cv * 100).round(2) + "%")
|
||||
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
* Available context bindings:
|
||||
* COLUMNS List<DataColumn>
|
||||
* ROWS Iterable<DataRow>
|
||||
* OUT { append() }
|
||||
* FORMATTER { format(row, col); formatValue(Object, col); getTypeName(Object, col); isStringLiteral(Object, col); }
|
||||
* TRANSPOSED Boolean
|
||||
* plus ALL_COLUMNS, TABLE, DIALECT
|
||||
*
|
||||
* where:
|
||||
* DataRow { rowNumber(); first(); last(); data(): List<Object>; value(column): Object }
|
||||
* DataColumn { columnNumber(), name() }
|
||||
*/
|
||||
|
||||
OUT.append(COLUMNS.size().toString())
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Available context bindings:
|
||||
* COLUMNS List<DataColumn>
|
||||
* ROWS Iterable<DataRow>
|
||||
* OUT { append() }
|
||||
* FORMATTER { format(row, col); formatValue(Object, col); getTypeName(Object, col); isStringLiteral(Object, col); }
|
||||
* TRANSPOSED Boolean
|
||||
* plus ALL_COLUMNS, TABLE, DIALECT
|
||||
*
|
||||
* where:
|
||||
* DataRow { rowNumber(); first(); last(); data(): List<Object>; value(column): Object }
|
||||
* DataColumn { columnNumber(), name() }
|
||||
*/
|
||||
|
||||
def RES = 0G
|
||||
ROWS.each { row ->
|
||||
COLUMNS.each { column ->
|
||||
RES += 1
|
||||
}
|
||||
}
|
||||
OUT.append(RES.toString())
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Available context bindings:
|
||||
* COLUMNS List<DataColumn>
|
||||
* ROWS Iterable<DataRow>
|
||||
* OUT { append() }
|
||||
* FORMATTER { format(row, col); formatValue(Object, col); getTypeName(Object, col); isStringLiteral(Object, col); }
|
||||
* TRANSPOSED Boolean
|
||||
* plus ALL_COLUMNS, TABLE, DIALECT
|
||||
*
|
||||
* where:
|
||||
* DataRow { rowNumber(); first(); last(); data(): List<Object>; value(column): Object }
|
||||
* DataColumn { columnNumber(), name() }
|
||||
*/
|
||||
|
||||
def RES = 0G
|
||||
ROWS.each { row ->
|
||||
COLUMNS.each { column ->
|
||||
def value = row.value(column)
|
||||
if (value instanceof Number) {
|
||||
RES += 1
|
||||
}
|
||||
else if (value.toString().isBigDecimal()) {
|
||||
RES += 1
|
||||
}
|
||||
}
|
||||
}
|
||||
OUT.append(RES.toString())
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Available context bindings:
|
||||
* COLUMNS List<DataColumn>
|
||||
* ROWS Iterable<DataRow>
|
||||
* OUT { append() }
|
||||
* FORMATTER { format(row, col); formatValue(Object, col); getTypeName(Object, col); isStringLiteral(Object, col); }
|
||||
* TRANSPOSED Boolean
|
||||
* plus ALL_COLUMNS, TABLE, DIALECT
|
||||
*
|
||||
* where:
|
||||
* DataRow { rowNumber(); first(); last(); data(): List<Object>; value(column): Object }
|
||||
* DataColumn { columnNumber(), name() }
|
||||
*/
|
||||
|
||||
|
||||
values = new ArrayList<BigDecimal>()
|
||||
ROWS.each { row ->
|
||||
COLUMNS.each { column ->
|
||||
def value = row.value(column)
|
||||
if (value instanceof Number) {
|
||||
values.add(value as BigDecimal)
|
||||
}
|
||||
else if (value.toString().isBigDecimal()) {
|
||||
values.add(value.toString() as BigDecimal)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (values.size() == 0) {
|
||||
OUT.append("Not enough values")
|
||||
return
|
||||
}
|
||||
OUT.append(Collections.max(values).toString())
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Available context bindings:
|
||||
* COLUMNS List<DataColumn>
|
||||
* ROWS Iterable<DataRow>
|
||||
* OUT { append() }
|
||||
* FORMATTER { format(row, col); formatValue(Object, col); getTypeName(Object, col); isStringLiteral(Object, col); }
|
||||
* TRANSPOSED Boolean
|
||||
* plus ALL_COLUMNS, TABLE, DIALECT
|
||||
*
|
||||
* where:
|
||||
* DataRow { rowNumber(); first(); last(); data(): List<Object>; value(column): Object }
|
||||
* DataColumn { columnNumber(), name() }
|
||||
*/
|
||||
|
||||
import static java.math.MathContext.DECIMAL128
|
||||
|
||||
def toBigDecimal = { value ->
|
||||
value instanceof Number ? value as BigDecimal :
|
||||
value.toString().isBigDecimal() ? value.toString() as BigDecimal :
|
||||
null
|
||||
}
|
||||
|
||||
def values = []
|
||||
|
||||
ROWS.each { row ->
|
||||
COLUMNS.each { column ->
|
||||
def bigDecimal = toBigDecimal(row.value(column))
|
||||
if (bigDecimal != null) {
|
||||
values.add(bigDecimal)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (values.isEmpty()) {
|
||||
OUT.append("Not enough values")
|
||||
return
|
||||
}
|
||||
elementsNumber = values.size()
|
||||
Collections.sort(values)
|
||||
mid = (int)elementsNumber / 2
|
||||
RES = elementsNumber % 2 != 0 ? values[mid] : values[mid].add(values[mid - 1], DECIMAL128).divide(2, DECIMAL128)
|
||||
OUT.append(RES.toString())
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Available context bindings:
|
||||
* COLUMNS List<DataColumn>
|
||||
* ROWS Iterable<DataRow>
|
||||
* OUT { append() }
|
||||
* FORMATTER { format(row, col); formatValue(Object, col); getTypeName(Object, col); isStringLiteral(Object, col); }
|
||||
* TRANSPOSED Boolean
|
||||
* plus ALL_COLUMNS, TABLE, DIALECT
|
||||
*
|
||||
* where:
|
||||
* DataRow { rowNumber(); first(); last(); data(): List<Object>; value(column): Object }
|
||||
* DataColumn { columnNumber(), name() }
|
||||
*/
|
||||
|
||||
values = new ArrayList<BigDecimal>()
|
||||
ROWS.each { row ->
|
||||
COLUMNS.each { column ->
|
||||
def value = row.value(column)
|
||||
if (value instanceof Number) {
|
||||
values.add(value as BigDecimal)
|
||||
}
|
||||
else if (value.toString().isBigDecimal()) {
|
||||
values.add(value.toString() as BigDecimal)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (values.size() == 0) {
|
||||
OUT.append("Not enough values")
|
||||
return
|
||||
}
|
||||
OUT.append(Collections.min(values).toString())
|
||||
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
* Available context bindings:
|
||||
* COLUMNS List<DataColumn>
|
||||
* ROWS Iterable<DataRow>
|
||||
* OUT { append() }
|
||||
* FORMATTER { format(row, col); formatValue(Object, col); getTypeName(Object, col); isStringLiteral(Object, col); }
|
||||
* TRANSPOSED Boolean
|
||||
* plus ALL_COLUMNS, TABLE, DIALECT
|
||||
*
|
||||
* where:
|
||||
* DataRow { rowNumber(); first(); last(); data(): List<Object>; value(column): Object }
|
||||
* DataColumn { columnNumber(), name() }
|
||||
*/
|
||||
|
||||
OUT.append(ROWS.size().toString())
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Available context bindings:
|
||||
* COLUMNS List<DataColumn>
|
||||
* ROWS Iterable<DataRow>
|
||||
* OUT { append() }
|
||||
* FORMATTER { format(row, col); formatValue(Object, col); getTypeName(Object, col); isStringLiteral(Object, col); }
|
||||
* TRANSPOSED Boolean
|
||||
* plus ALL_COLUMNS, TABLE, DIALECT
|
||||
*
|
||||
* where:
|
||||
* DataRow { rowNumber(); first(); last(); data(): List<Object>; value(column): Object }
|
||||
* DataColumn { columnNumber(), name() }
|
||||
*/
|
||||
|
||||
import static java.math.MathContext.DECIMAL128
|
||||
|
||||
BigDecimal RES = 0
|
||||
ROWS.each { row ->
|
||||
COLUMNS.each { column ->
|
||||
def value = row.value(column)
|
||||
if (value instanceof Number) {
|
||||
RES = RES.add(value, DECIMAL128)
|
||||
}
|
||||
else if (value.toString().isBigDecimal()) {
|
||||
RES = RES.add(value.toString().toBigDecimal(), DECIMAL128)
|
||||
}
|
||||
}
|
||||
}
|
||||
OUT.append(RES.toString())
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Available context bindings:
|
||||
* COLUMNS List<DataColumn>
|
||||
* ROWS Iterable<DataRow>
|
||||
* OUT { append() }
|
||||
* FORMATTER { format(row, col); formatValue(Object, col); getTypeName(Object, col); isStringLiteral(Object, col); }
|
||||
* TRANSPOSED Boolean
|
||||
* plus ALL_COLUMNS, TABLE, DIALECT
|
||||
*
|
||||
* where:
|
||||
* DataRow { rowNumber(); first(); last(); data(): List<Object>; value(column): Object }
|
||||
* DataColumn { columnNumber(), name() }
|
||||
*/
|
||||
|
||||
SEPARATOR = ","
|
||||
QUOTE = "\""
|
||||
NEWLINE = System.getProperty("line.separator")
|
||||
|
||||
def printRow = { values, valueToString ->
|
||||
values.eachWithIndex { value, idx ->
|
||||
def str = valueToString(value)
|
||||
def q = str.contains(SEPARATOR) || str.contains(QUOTE) || str.contains(NEWLINE)
|
||||
OUT.append(q ? QUOTE : "")
|
||||
.append(str.replace(QUOTE, QUOTE + QUOTE))
|
||||
.append(q ? QUOTE : "")
|
||||
.append(idx != values.size() - 1 ? SEPARATOR : NEWLINE)
|
||||
}
|
||||
}
|
||||
|
||||
if (!TRANSPOSED) {
|
||||
ROWS.each { row -> printRow(COLUMNS, { FORMATTER.format(row, it) }) }
|
||||
}
|
||||
else {
|
||||
def values = COLUMNS.collect { new ArrayList<String>() }
|
||||
ROWS.each { row -> COLUMNS.eachWithIndex { col, i -> values[i].add(FORMATTER.format(row, col)) } }
|
||||
values.each { printRow(it, { it }) }
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Available context bindings:
|
||||
* COLUMNS List<DataColumn>
|
||||
* ROWS Iterable<DataRow>
|
||||
* OUT { append() }
|
||||
* FORMATTER { format(row, col); formatValue(Object, col); getTypeName(Object, col); isStringLiteral(Object, col); }
|
||||
* TRANSPOSED Boolean
|
||||
* plus ALL_COLUMNS, TABLE, DIALECT
|
||||
*
|
||||
* where:
|
||||
* DataRow { rowNumber(); first(); last(); data(): List<Object>; value(column): Object }
|
||||
* DataColumn { columnNumber(), name() }
|
||||
*/
|
||||
|
||||
import static com.intellij.openapi.util.text.StringUtil.escapeXmlEntities
|
||||
|
||||
NEWLINE = System.getProperty("line.separator")
|
||||
|
||||
def HTML_PATTERN = ~"<.+>"
|
||||
|
||||
def printRow = { values, tag, valueToString ->
|
||||
OUT.append("$NEWLINE<tr>$NEWLINE")
|
||||
values.each {
|
||||
def str = valueToString(it)
|
||||
def escaped = str ==~ HTML_PATTERN
|
||||
? str
|
||||
: escapeXmlEntities((str as String).replaceAll("\\t|\\b|\\f", "")).replaceAll("\\r|\\n|\\r\\n", "<br/>")
|
||||
OUT.append(" <$tag>$escaped</$tag>$NEWLINE")
|
||||
}
|
||||
OUT.append("</tr>")
|
||||
}
|
||||
|
||||
OUT.append(
|
||||
"""<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title></title>
|
||||
<meta charset="UTF-8">
|
||||
</head>
|
||||
<body>
|
||||
<table border="1" style="border-collapse:collapse">""")
|
||||
|
||||
if (!TRANSPOSED) {
|
||||
printRow(COLUMNS, "th") { it.name() }
|
||||
ROWS.each { row -> printRow(COLUMNS, "td") { FORMATTER.format(row, it) } }
|
||||
}
|
||||
else {
|
||||
def values = COLUMNS.collect { new ArrayList<String>( [it.name()] ) }
|
||||
ROWS.each { row -> COLUMNS.eachWithIndex { col, i -> values[i].add(FORMATTER.format(row, col)) } }
|
||||
values.each { printRow(it, "td", { it }) }
|
||||
}
|
||||
|
||||
OUT.append("""
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
""")
|
||||
@@ -0,0 +1,49 @@
|
||||
function eachWithIdx(iterable, f) { var i = iterable.iterator(); var idx = 0; while (i.hasNext()) f(i.next(), idx++); }
|
||||
function mapEach(iterable, f) { var vs = []; eachWithIdx(iterable, function (i) { vs.push(f(i));}); return vs; }
|
||||
function escape(str) {
|
||||
str = str.replace(/\t|\b|\f/g, "");
|
||||
str = com.intellij.openapi.util.text.StringUtil.escapeXml(str);
|
||||
str = str.replace(/\r|\n|\r\n/g, "<br/>");
|
||||
return str;
|
||||
}
|
||||
var isHTML = RegExp.prototype.test.bind(/^<.+>$/);
|
||||
|
||||
var NEWLINE = "\n";
|
||||
|
||||
function output() { for (var i = 0; i < arguments.length; i++) { OUT.append(arguments[i]); } }
|
||||
function outputRow(items, tag) {
|
||||
output("<tr>");
|
||||
for (var i = 0; i < items.length; i++)
|
||||
output("<", tag, ">", isHTML(items[i]) ? items[i] : escape(items[i]), "</", tag, ">");
|
||||
output("</tr>", NEWLINE);
|
||||
}
|
||||
|
||||
|
||||
output("<!DOCTYPE html>", NEWLINE,
|
||||
"<html>", NEWLINE,
|
||||
"<head>", NEWLINE,
|
||||
"<title></title>", NEWLINE,
|
||||
"<meta charset=\"UTF-8\">", NEWLINE,
|
||||
"</head>", NEWLINE,
|
||||
"<body>", NEWLINE,
|
||||
"<table border=\"1\" style=\"border-collapse:collapse\">", NEWLINE);
|
||||
|
||||
if (TRANSPOSED) {
|
||||
var values = mapEach(COLUMNS, function(col) { return [col.name()]; });
|
||||
eachWithIdx(ROWS, function (row) {
|
||||
eachWithIdx(COLUMNS, function (col, i) {
|
||||
values[i].push(FORMATTER.format(row, col));
|
||||
});
|
||||
});
|
||||
eachWithIdx(COLUMNS, function (_, i) { outputRow(values[i], "td"); });
|
||||
}
|
||||
else {
|
||||
outputRow(mapEach(COLUMNS, function (col) { return col.name(); }), "th");
|
||||
eachWithIdx(ROWS, function (row) {
|
||||
outputRow(mapEach(COLUMNS, function (col) { return FORMATTER.format(row, col); }), "td")
|
||||
});
|
||||
}
|
||||
|
||||
output("</table>", NEWLINE,
|
||||
"</body>", NEWLINE,
|
||||
"</html>", NEWLINE);
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Available context bindings:
|
||||
* COLUMNS List<DataColumn>
|
||||
* ROWS Iterable<DataRow>
|
||||
* OUT { append() }
|
||||
* FORMATTER { format(row, col); formatValue(Object, col); getTypeName(Object, col); isStringLiteral(Object, col); }
|
||||
* TRANSPOSED Boolean
|
||||
* plus ALL_COLUMNS, TABLE, DIALECT
|
||||
*
|
||||
* where:
|
||||
* DataRow { rowNumber(); first(); last(); data(): List<Object>; value(column): Object }
|
||||
* DataColumn { columnNumber(), name() }
|
||||
*/
|
||||
|
||||
|
||||
import static com.intellij.openapi.util.text.StringUtil.escapeStringCharacters as escapeStr
|
||||
|
||||
NEWLINE = System.getProperty("line.separator")
|
||||
INDENT = " "
|
||||
|
||||
def printJSON(level, col, o) {
|
||||
switch (o) {
|
||||
case null: OUT.append("null"); break
|
||||
case Tuple: printJSON(level, o[0], o[1]); break
|
||||
case Map:
|
||||
OUT.append("{")
|
||||
o.entrySet().eachWithIndex { entry, i ->
|
||||
OUT.append("${i > 0 ? "," : ""}$NEWLINE${INDENT * (level + 1)}")
|
||||
OUT.append("\"${escapeStr(entry.getKey().toString())}\"")
|
||||
OUT.append(": ")
|
||||
printJSON(level + 1, col, entry.getValue())
|
||||
}
|
||||
OUT.append("$NEWLINE${INDENT * level}}")
|
||||
break
|
||||
case Object[]:
|
||||
case Iterable:
|
||||
OUT.append("[")
|
||||
def plain = true
|
||||
o.eachWithIndex { item, i ->
|
||||
plain = item == null || item instanceof Number || item instanceof Boolean || item instanceof String
|
||||
if (plain) {
|
||||
OUT.append(i > 0 ? ", " : "")
|
||||
}
|
||||
else {
|
||||
OUT.append("${i > 0 ? "," : ""}$NEWLINE${INDENT * (level + 1)}")
|
||||
}
|
||||
printJSON(level + 1, col, item)
|
||||
}
|
||||
if (plain) OUT.append("]") else OUT.append("$NEWLINE${INDENT * level}]")
|
||||
break
|
||||
case Boolean: OUT.append("$o"); break
|
||||
default:
|
||||
def str = FORMATTER.formatValue(o, col)
|
||||
def typeName = FORMATTER.getTypeName(o, col)
|
||||
def shouldQuote = FORMATTER.isStringLiteral(o, col) && !(typeName.equalsIgnoreCase("json") || typeName.equalsIgnoreCase("jsonb"))
|
||||
OUT.append(shouldQuote ? "\"${escapeStr(str)}\"" : str);
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
printJSON(0, null, ROWS.transform { row ->
|
||||
def map = new LinkedHashMap<String, Object>()
|
||||
COLUMNS.each { col ->
|
||||
if (row.hasValue(col)) {
|
||||
def val = row.value(col)
|
||||
map.put(col.name(), new Tuple(col, val))
|
||||
}
|
||||
}
|
||||
map
|
||||
})
|
||||
@@ -0,0 +1,65 @@
|
||||
package extensions.data.extractors
|
||||
|
||||
NEWLINE = System.getProperty("line.separator")
|
||||
SEPARATOR = "|"
|
||||
BACKSLASH = "\\"
|
||||
BACKQUOTE = "`"
|
||||
LTAG = "<"
|
||||
RTAG = ">"
|
||||
ASTERISK = "*"
|
||||
UNDERSCORE = "_"
|
||||
LPARENTH = "("
|
||||
RPARENTH = ")"
|
||||
LBRACKET = "["
|
||||
RBRACKET = "]"
|
||||
TILDE = "~"
|
||||
|
||||
def printRow = { values, firstBold = false, valueToString ->
|
||||
values.eachWithIndex { value, idx ->
|
||||
def str = valueToString(value)
|
||||
.replace(BACKSLASH, BACKSLASH + BACKSLASH)
|
||||
.replace(SEPARATOR, BACKSLASH + SEPARATOR)
|
||||
.replace(BACKQUOTE, BACKSLASH + BACKQUOTE)
|
||||
.replace(ASTERISK, BACKSLASH + ASTERISK)
|
||||
.replace(UNDERSCORE, BACKSLASH + UNDERSCORE)
|
||||
.replace(LPARENTH, BACKSLASH + LPARENTH)
|
||||
.replace(RPARENTH, BACKSLASH + RPARENTH)
|
||||
.replace(LBRACKET, BACKSLASH + LBRACKET)
|
||||
.replace(RBRACKET, BACKSLASH + RBRACKET)
|
||||
.replace(TILDE, BACKSLASH + TILDE)
|
||||
.replace(LTAG, "<")
|
||||
.replace(RTAG, ">")
|
||||
.replaceAll("\r\n|\r|\n", "<br/>")
|
||||
.replaceAll("\t|\b|\f", "")
|
||||
|
||||
OUT.append("| ")
|
||||
.append(firstBold && idx == 0 ? "**" : "")
|
||||
.append(str)
|
||||
.append(firstBold && idx == 0 ? "**" : "")
|
||||
.append(idx != values.size() - 1 ? " " : " |" + NEWLINE)
|
||||
}
|
||||
}
|
||||
|
||||
if (TRANSPOSED) {
|
||||
def values = COLUMNS.collect { new ArrayList<String>([it.name()]) }
|
||||
def rowCount = 0
|
||||
ROWS.forEach { row ->
|
||||
COLUMNS.eachWithIndex { col, i -> values[i].add(FORMATTER.format(row, col)) }
|
||||
rowCount++
|
||||
}
|
||||
for (int i = 0; i <= rowCount; i++) {
|
||||
OUT.append("| ")
|
||||
}
|
||||
OUT.append("|" + NEWLINE)
|
||||
for (int i = 0; i <= rowCount; i++) {
|
||||
OUT.append("| :- ")
|
||||
}
|
||||
OUT.append("|" + NEWLINE)
|
||||
values.each { printRow(it, true) { it } }
|
||||
}
|
||||
else {
|
||||
printRow(COLUMNS) { it.name() }
|
||||
COLUMNS.each { OUT.append("| :--- ") }
|
||||
OUT.append("|" + NEWLINE)
|
||||
ROWS.each { row -> printRow(COLUMNS) { FORMATTER.format(row, it) } }
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Available context bindings:
|
||||
* COLUMNS List<DataColumn>
|
||||
* ROWS Iterable<DataRow>
|
||||
* OUT { append() }
|
||||
* FORMATTER { format(row, col); formatValue(Object, col); getTypeName(Object, col); isStringLiteral(Object, col); }
|
||||
* TRANSPOSED Boolean
|
||||
* plus ALL_COLUMNS, TABLE, DIALECT
|
||||
*
|
||||
* where:
|
||||
* DataRow { rowNumber(); first(); last(); data(): List<Object>; value(column): Object }
|
||||
* DataColumn { columnNumber(), name() }
|
||||
*/
|
||||
|
||||
SEPARATOR = ", "
|
||||
QUOTE = "'"
|
||||
STRING_PREFIX = DIALECT.getDbms().isMicrosoft() ? "N" : ""
|
||||
KEYWORDS_LOWERCASE = com.intellij.database.util.DbSqlUtil.areKeywordsLowerCase(PROJECT)
|
||||
KW_NULL = KEYWORDS_LOWERCASE ? "null" : "NULL"
|
||||
|
||||
first = true
|
||||
ROWS.each { row ->
|
||||
COLUMNS.each { column ->
|
||||
def value = row.value(column)
|
||||
def stringValue = value == null ? KW_NULL : FORMATTER.formatValue(value, column)
|
||||
def isStringLiteral = value != null && FORMATTER.isStringLiteral(value, column)
|
||||
if (isStringLiteral && DIALECT.getDbms().isMysql()) stringValue = stringValue.replace("\\", "\\\\")
|
||||
OUT.append(first ? "" : SEPARATOR)
|
||||
.append(isStringLiteral ? (STRING_PREFIX + QUOTE) : "")
|
||||
.append(stringValue ? stringValue.replace(QUOTE, QUOTE + QUOTE) : stringValue)
|
||||
.append(isStringLiteral ? QUOTE : "")
|
||||
first = false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
|
||||
/*
|
||||
* Available context bindings:
|
||||
* COLUMNS List<DataColumn>
|
||||
* ROWS Iterable<DataRow>
|
||||
* OUT { append() }
|
||||
* FORMATTER { format(row, col); formatValue(Object, col); getTypeName(Object, col); isStringLiteral(Object, col); }
|
||||
* TRANSPOSED Boolean
|
||||
* plus ALL_COLUMNS, TABLE, DIALECT
|
||||
*
|
||||
* where:
|
||||
* DataRow { rowNumber(); first(); last(); data(): List<Object>; value(column): Object }
|
||||
* DataColumn { columnNumber(), name() }
|
||||
*/
|
||||
|
||||
|
||||
WIDTH_BASED_ON_CONTENT = -1
|
||||
|
||||
PIPE = "|"
|
||||
SPACE = " "
|
||||
CROSS = "+"
|
||||
MINUS = "-"
|
||||
ROW_SEPARATORS = false
|
||||
COLUMN_WIDTH = WIDTH_BASED_ON_CONTENT
|
||||
NEWLINE = System.getProperty("line.separator")
|
||||
|
||||
static def splitByLines(values, size) {
|
||||
def splitValues = new ArrayList<>()
|
||||
def maxLines = 0
|
||||
for (int i = 0; i < size; i++) {
|
||||
def splitValue = StringUtil.splitByLines(values(i))
|
||||
splitValues.add(splitValue)
|
||||
maxLines = Math.max(maxLines, splitValue.size())
|
||||
}
|
||||
|
||||
def byLines = new ArrayList<>(maxLines)
|
||||
for (int i = 0; i < maxLines; i++) {
|
||||
def lineValues = new ArrayList<>()
|
||||
byLines.add(lineValues)
|
||||
for (int j = 0; j < splitValues.size(); j++) {
|
||||
def splitValue = splitValues[j]
|
||||
lineValues.add(splitValue.size() <= i ? null : splitValue[i])
|
||||
}
|
||||
}
|
||||
return byLines
|
||||
}
|
||||
|
||||
def printRow(values, size, width = { COLUMN_WIDTH }, padding = SPACE, separator = { PIPE }) {
|
||||
def byLines = splitByLines(values, size)
|
||||
byLines.each { line ->
|
||||
def lineSize = line.size()
|
||||
if (lineSize > 0) OUT.append(separator(-1))
|
||||
for (int i = 0; i < lineSize; i++) {
|
||||
def value = line[i] == null ? "" : line.get(i)
|
||||
def curWidth = width(i)
|
||||
OUT.append(value.padRight(curWidth, padding))
|
||||
OUT.append(separator(i))
|
||||
}
|
||||
OUT.append(NEWLINE)
|
||||
}
|
||||
}
|
||||
|
||||
def printRows() {
|
||||
def colNames = COLUMNS.collect { it.name() }
|
||||
def calcWidth = COLUMN_WIDTH == WIDTH_BASED_ON_CONTENT
|
||||
def rows
|
||||
def width
|
||||
def rowFormatter
|
||||
if (calcWidth) {
|
||||
rows = new ArrayList<>()
|
||||
def widths = new int[COLUMNS.size()]
|
||||
COLUMNS.eachWithIndex { column, idx -> widths[idx] = column.name().length() }
|
||||
ROWS.each { row ->
|
||||
def rowValues = COLUMNS.withIndex().collect { col, idx ->
|
||||
def value = FORMATTER.format(row, col)
|
||||
widths[idx] = Math.max(widths[idx], value.length())
|
||||
value
|
||||
}
|
||||
rows.add(rowValues)
|
||||
}
|
||||
width = { widths[it] }
|
||||
rowFormatter = { it }
|
||||
}
|
||||
else {
|
||||
rows = ROWS
|
||||
width = { COLUMN_WIDTH }
|
||||
rowFormatter = { COLUMNS.collect { col -> FORMATTER.format(it, col) } }
|
||||
}
|
||||
|
||||
printRow({""}, COLUMNS.size(), { width(it) }, MINUS) { CROSS }
|
||||
printRow( { colNames[it] }, COLUMNS.size()) { width(it) }
|
||||
|
||||
def first = true
|
||||
rows.each { row ->
|
||||
def rowValues = rowFormatter(row)
|
||||
if (first || ROW_SEPARATORS) printRow({""}, COLUMNS.size(), { width(it) }, MINUS) { first ? CROSS : MINUS }
|
||||
printRow({ rowValues[it] }, rowValues.size()) { width(it) }
|
||||
first = false
|
||||
}
|
||||
printRow({""}, COLUMNS.size(), { width(it) }, MINUS) { CROSS }
|
||||
}
|
||||
|
||||
def printRowsTransposed() {
|
||||
def calcWidth = COLUMN_WIDTH == WIDTH_BASED_ON_CONTENT
|
||||
if (calcWidth) {
|
||||
COLUMN_WIDTHS = new ArrayList<Integer>()
|
||||
COLUMN_WIDTHS.add(0)
|
||||
}
|
||||
def valuesByRow = COLUMNS.collect { col ->
|
||||
if (calcWidth) COLUMN_WIDTHS.set(0, Math.max(COLUMN_WIDTHS[0], col.name().length()))
|
||||
new ArrayList<String>([col.name()])
|
||||
}
|
||||
def rowCount = 1
|
||||
ROWS.each { row ->
|
||||
rowCount++
|
||||
COLUMNS.eachWithIndex { col, i ->
|
||||
def formattedValue = FORMATTER.format(row, col)
|
||||
valuesByRow[i].add(formattedValue)
|
||||
def widthIdx = rowCount - 1
|
||||
def length = formattedValue.length()
|
||||
if (calcWidth) {
|
||||
if (COLUMN_WIDTHS.size() == widthIdx) COLUMN_WIDTHS.add(length)
|
||||
COLUMN_WIDTHS.set(widthIdx, Math.max(COLUMN_WIDTHS[widthIdx], length))
|
||||
}
|
||||
}
|
||||
}
|
||||
valuesByRow.each { row ->
|
||||
printRow({ "" }, rowCount, { calcWidth ? COLUMN_WIDTHS[it] : COLUMN_WIDTH }, MINUS) {
|
||||
it <= 0 ? CROSS : it == rowCount - 1 ? CROSS : MINUS
|
||||
}
|
||||
printRow({ row[it] }, row.size()) { calcWidth ? COLUMN_WIDTHS[it] : COLUMN_WIDTH }
|
||||
}
|
||||
printRow({ "" }, rowCount, { calcWidth ? COLUMN_WIDTHS[it] : COLUMN_WIDTH }, MINUS) {
|
||||
it <= 0 ? CROSS : it == rowCount - 1 ? CROSS : MINUS
|
||||
}
|
||||
}
|
||||
|
||||
if (TRANSPOSED) {
|
||||
printRowsTransposed()
|
||||
}
|
||||
else {
|
||||
printRows()
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Available context bindings:
|
||||
* COLUMNS List<DataColumn>
|
||||
* ROWS Iterable<DataRow>
|
||||
* OUT { append() }
|
||||
* FORMATTER { format(row, col); formatValue(Object, col); getTypeName(Object, col); isStringLiteral(Object, col); }
|
||||
* TRANSPOSED Boolean
|
||||
* plus ALL_COLUMNS, TABLE, DIALECT
|
||||
*
|
||||
* where:
|
||||
* DataRow { rowNumber(); first(); last(); data(): List<Object>; value(column): Object }
|
||||
* DataColumn { columnNumber(), name() }
|
||||
*/
|
||||
|
||||
SEP = ", "
|
||||
QUOTE = "\'"
|
||||
STRING_PREFIX = DIALECT.getDbms().isMicrosoft() ? "N" : ""
|
||||
NEWLINE = System.getProperty("line.separator")
|
||||
|
||||
KEYWORDS_LOWERCASE = com.intellij.database.util.DbSqlUtil.areKeywordsLowerCase(PROJECT)
|
||||
KW_INSERT_INTO = KEYWORDS_LOWERCASE ? "insert into " : "INSERT INTO "
|
||||
KW_VALUES = KEYWORDS_LOWERCASE ? "values" : "VALUES"
|
||||
KW_NULL = KEYWORDS_LOWERCASE ? "null" : "NULL"
|
||||
|
||||
begin = true
|
||||
|
||||
def record(columns, dataRow) {
|
||||
|
||||
if (begin) {
|
||||
OUT.append(KW_INSERT_INTO)
|
||||
if (TABLE == null) OUT.append("MY_TABLE")
|
||||
else OUT.append(TABLE.getParent().getName()).append(".").append(TABLE.getName())
|
||||
OUT.append(" (")
|
||||
|
||||
columns.eachWithIndex { column, idx ->
|
||||
OUT.append(column.name()).append(idx != columns.size() - 1 ? SEP : "")
|
||||
}
|
||||
|
||||
OUT.append(")").append(NEWLINE)
|
||||
OUT.append(KW_VALUES).append(" (")
|
||||
begin = false
|
||||
}
|
||||
else {
|
||||
OUT.append(",").append(NEWLINE)
|
||||
OUT.append(" (")
|
||||
}
|
||||
|
||||
columns.eachWithIndex { column, idx ->
|
||||
def value = dataRow.value(column)
|
||||
def stringValue = value == null ? KW_NULL : FORMATTER.formatValue(value, column)
|
||||
def isStringLiteral = value != null && FORMATTER.isStringLiteral(value, column)
|
||||
if (isStringLiteral && DIALECT.getDbms().isMysql()) stringValue = stringValue.replace("\\", "\\\\")
|
||||
OUT.append(isStringLiteral ? (STRING_PREFIX + QUOTE) : "")
|
||||
.append(stringValue ? stringValue.replace(QUOTE, QUOTE + QUOTE) : stringValue)
|
||||
.append(isStringLiteral ? QUOTE : "")
|
||||
.append(idx != columns.size() - 1 ? SEP : "")
|
||||
}
|
||||
OUT.append(")")
|
||||
}
|
||||
|
||||
ROWS.each { row -> record(COLUMNS, row) }
|
||||
OUT.append(";")
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Available context bindings:
|
||||
* COLUMNS List<DataColumn>
|
||||
* ROWS Iterable<DataRow>
|
||||
* OUT { append() }
|
||||
* FORMATTER { format(row, col); formatValue(Object, col); getTypeName(Object, col); isStringLiteral(Object, col); }
|
||||
* TRANSPOSED Boolean
|
||||
* plus ALL_COLUMNS, TABLE, DIALECT
|
||||
*
|
||||
* where:
|
||||
* DataRow { rowNumber(); first(); last(); data(): List<Object>; value(column): Object }
|
||||
* DataColumn { columnNumber(), name() }
|
||||
*/
|
||||
|
||||
SEP = ", "
|
||||
QUOTE = "\'"
|
||||
STRING_PREFIX = DIALECT.getDbms().isMicrosoft() ? "N" : ""
|
||||
NEWLINE = System.getProperty("line.separator")
|
||||
|
||||
KEYWORDS_LOWERCASE = com.intellij.database.util.DbSqlUtil.areKeywordsLowerCase(PROJECT)
|
||||
KW_INSERT_INTO = KEYWORDS_LOWERCASE ? "insert into " : "INSERT INTO "
|
||||
KW_VALUES = KEYWORDS_LOWERCASE ? ") values (" : ") VALUES ("
|
||||
KW_NULL = KEYWORDS_LOWERCASE ? "null" : "NULL"
|
||||
|
||||
def record(columns, dataRow) {
|
||||
OUT.append(KW_INSERT_INTO)
|
||||
if (TABLE == null) OUT.append("MY_TABLE")
|
||||
else OUT.append(TABLE.getParent().getName()).append(".").append(TABLE.getName())
|
||||
OUT.append(" (")
|
||||
|
||||
columns.eachWithIndex { column, idx ->
|
||||
OUT.append(column.name()).append(idx != columns.size() - 1 ? SEP : "")
|
||||
}
|
||||
|
||||
OUT.append(KW_VALUES)
|
||||
columns.eachWithIndex { column, idx ->
|
||||
def value = dataRow.value(column)
|
||||
def stringValue = value == null ? KW_NULL : FORMATTER.formatValue(value, column)
|
||||
def isStringLiteral = value != null && FORMATTER.isStringLiteral(value, column)
|
||||
if (isStringLiteral && DIALECT.getDbms().isMysql()) stringValue = stringValue.replace("\\", "\\\\")
|
||||
OUT.append(isStringLiteral ? (STRING_PREFIX + QUOTE) : "")
|
||||
.append(isStringLiteral ? stringValue.replace(QUOTE, QUOTE + QUOTE) : stringValue)
|
||||
.append(isStringLiteral ? QUOTE : "")
|
||||
.append(idx != columns.size() - 1 ? SEP : "")
|
||||
}
|
||||
OUT.append(");").append(NEWLINE)
|
||||
}
|
||||
|
||||
ROWS.each { row -> record(COLUMNS, row) }
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Available context bindings:
|
||||
* COLUMNS List<DataColumn>
|
||||
* ROWS Iterable<DataRow>
|
||||
* OUT { append() }
|
||||
* FORMATTER { format(row, col); formatValue(Object, col); getTypeName(Object, col); isStringLiteral(Object, col); }
|
||||
* TRANSPOSED Boolean
|
||||
* plus ALL_COLUMNS, TABLE, DIALECT
|
||||
*
|
||||
* where:
|
||||
* DataRow { rowNumber(); first(); last(); data(): List<Object>; value(column): Object }
|
||||
* DataColumn { columnNumber(), name() }
|
||||
*/
|
||||
|
||||
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
|
||||
import java.util.regex.Pattern
|
||||
|
||||
NEWLINE = System.getProperty("line.separator")
|
||||
|
||||
pattern = Pattern.compile("[^\\w\\d]")
|
||||
def escapeTag(name) {
|
||||
name = pattern.matcher(name).replaceAll("_")
|
||||
return name.isEmpty() || !Character.isLetter(name.charAt(0)) ? "_$name" : name
|
||||
}
|
||||
def printRow(level, rowTag, values) {
|
||||
def prefix = "$NEWLINE${StringUtil.repeat(" ", level)}"
|
||||
OUT.append("$prefix<$rowTag>")
|
||||
values.each { name, col, valuesName, value ->
|
||||
switch (value) {
|
||||
case Map:
|
||||
def mapValues = new ArrayList<Tuple>()
|
||||
value.each { key, v -> mapValues.add(new Tuple(escapeTag(key.toString()), col, key.toString(), v)) }
|
||||
printRow(level + 1, name, mapValues)
|
||||
break
|
||||
case Object[]:
|
||||
case Iterable:
|
||||
def listItems = new ArrayList<Tuple>()
|
||||
def itemName = valuesName != null ? escapeTag(StringUtil.unpluralize(valuesName) ?: "item") : "item"
|
||||
value.collect { v -> listItems.add(new Tuple(itemName, col, null, v)) }
|
||||
printRow(level + 1, name, listItems)
|
||||
break
|
||||
default:
|
||||
OUT.append("$prefix <$name>")
|
||||
if (value == null) OUT.append("null")
|
||||
else {
|
||||
def formattedValue = FORMATTER.formatValue(value, col)
|
||||
if (isXmlString(formattedValue)) OUT.append(formattedValue)
|
||||
else OUT.append(StringUtil.escapeXmlEntities(formattedValue))
|
||||
}
|
||||
OUT.append("</$name>")
|
||||
}
|
||||
}
|
||||
OUT.append("$prefix</$rowTag>")
|
||||
}
|
||||
|
||||
def isXmlString(string) {
|
||||
return string.startsWith("<") && string.endsWith(">") && (string.contains("</") || string.contains("/>"))
|
||||
}
|
||||
|
||||
OUT.append(
|
||||
"""<?xml version="1.0" encoding="UTF-8"?>
|
||||
<data>""")
|
||||
|
||||
if (!TRANSPOSED) {
|
||||
ROWS.each { row ->
|
||||
def values = COLUMNS
|
||||
.findAll { col -> row.hasValue(col) }
|
||||
.collect { col ->
|
||||
new Tuple(escapeTag(col.name()), col, col.name(), row.value(col))
|
||||
}
|
||||
printRow(0, "row", values)
|
||||
}
|
||||
}
|
||||
else {
|
||||
def values = COLUMNS.collect { new ArrayList<Tuple>() }
|
||||
ROWS.eachWithIndex { row, rowIdx ->
|
||||
COLUMNS.eachWithIndex { col, colIdx ->
|
||||
if (row.hasValue(col)) {
|
||||
def value = row.value(col)
|
||||
values[colIdx].add(new Tuple("row${rowIdx + 1}", col, col.name(), value))
|
||||
}
|
||||
}
|
||||
}
|
||||
values.eachWithIndex { it, index ->
|
||||
printRow(0, escapeTag(COLUMNS[index].name()), it)
|
||||
}
|
||||
}
|
||||
|
||||
OUT.append("""
|
||||
</data>
|
||||
""")
|
||||
@@ -0,0 +1,53 @@
|
||||
import com.intellij.database.model.DasObjectWithSource
|
||||
import com.intellij.database.model.DasSchemaChild
|
||||
import com.intellij.database.model.ObjectKind
|
||||
import com.intellij.database.util.DasUtil
|
||||
import com.intellij.database.util.ObjectPath
|
||||
|
||||
LAYOUT.ignoreDependencies = true
|
||||
LAYOUT.baseName { ctx -> baseName(ctx.object) }
|
||||
LAYOUT.fileScope { path -> fileScope(path) }
|
||||
|
||||
|
||||
def baseName(obj) {
|
||||
def db = DasUtil.getCatalog(obj)
|
||||
def schema = DasUtil.getSchema(obj)
|
||||
def file = fileName(obj)
|
||||
if (db.isEmpty()) {
|
||||
if (!schema.isEmpty()) return "anonymous/" + sanitize(schema) + "/" + file
|
||||
return file
|
||||
}
|
||||
else if (schema.isEmpty()) {
|
||||
return sanitize(db) + "/" + file
|
||||
}
|
||||
else {
|
||||
return sanitize(db) + "/" + sanitize(schema) + "/" + file
|
||||
}
|
||||
}
|
||||
|
||||
def fileName(obj) {
|
||||
for (def cur = obj; cur != null; cur = cur.dasParent) {
|
||||
if (storeSeparately(cur)) return sanitize(cur.name)
|
||||
}
|
||||
return sanitize(obj.name)
|
||||
}
|
||||
|
||||
def fileScope(path) {
|
||||
def root = path.getName(0).toString()
|
||||
if (root.endsWith(".sql")) return null
|
||||
def next = path.getName(1).toString()
|
||||
if (next.endsWith(".sql")) {
|
||||
if (root == "anonymous") return null
|
||||
return ObjectPath.create(root, ObjectKind.DATABASE)
|
||||
}
|
||||
if (root == "anonymous") return ObjectPath.create(next, ObjectKind.SCHEMA)
|
||||
return ObjectPath.create(root, ObjectKind.DATABASE).append(next, ObjectKind.SCHEMA)
|
||||
}
|
||||
|
||||
def storeSeparately(obj) {
|
||||
return obj instanceof DasObjectWithSource || obj instanceof DasSchemaChild
|
||||
}
|
||||
|
||||
def sanitize(name) {
|
||||
return name.replace('/', 'slash')
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
import com.intellij.database.model.DasObjectWithSource
|
||||
import com.intellij.database.model.DasSchemaChild
|
||||
import com.intellij.database.model.ObjectKind
|
||||
import com.intellij.database.util.DasUtil
|
||||
import com.intellij.database.util.ObjectPath
|
||||
|
||||
LAYOUT.ignoreDependencies = true
|
||||
LAYOUT.baseName { ctx -> baseName(ctx.object) }
|
||||
LAYOUT.fileScope { path -> fileScope(path) }
|
||||
|
||||
|
||||
def baseName(obj) {
|
||||
def schema = DasUtil.getSchema(obj)
|
||||
def file = fileName(obj)
|
||||
if (schema.isEmpty()) {
|
||||
return file
|
||||
}
|
||||
else {
|
||||
return sanitize(schema) + "/" + obj.kind.code() + "/" + file
|
||||
}
|
||||
}
|
||||
|
||||
def fileName(obj) {
|
||||
for (def cur = obj; cur != null; cur = cur.dasParent) {
|
||||
if (storeSeparately(cur)) return sanitize(cur.name)
|
||||
}
|
||||
return sanitize(obj.name)
|
||||
}
|
||||
|
||||
def fileScope(path) {
|
||||
def root = path.getName(0).toString()
|
||||
if (root.endsWith(".sql")) return null
|
||||
return ObjectPath.create(root, ObjectKind.SCHEMA)
|
||||
}
|
||||
|
||||
def storeSeparately(obj) {
|
||||
return obj instanceof DasObjectWithSource || obj instanceof DasSchemaChild
|
||||
}
|
||||
|
||||
def sanitize(name) {
|
||||
return name.replace('/', 'slash')
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
import com.intellij.database.model.DasObjectWithSource
|
||||
import com.intellij.database.model.DasSchemaChild
|
||||
import com.intellij.database.model.ObjectKind
|
||||
import com.intellij.database.util.DasUtil
|
||||
import com.intellij.database.util.ObjectPath
|
||||
|
||||
LAYOUT.ignoreDependencies = true
|
||||
LAYOUT.baseName { ctx -> baseName(ctx.object) }
|
||||
LAYOUT.fileScope { path -> fileScope(path) }
|
||||
|
||||
|
||||
def baseName(obj) {
|
||||
def schema = DasUtil.getSchema(obj)
|
||||
def file = fileName(obj)
|
||||
if (schema.isEmpty()) {
|
||||
return file
|
||||
}
|
||||
else {
|
||||
return sanitize(schema) + "/" + file
|
||||
}
|
||||
}
|
||||
|
||||
def fileName(obj) {
|
||||
for (def cur = obj; cur != null; cur = cur.dasParent) {
|
||||
if (storeSeparately(cur)) return sanitize(cur.name)
|
||||
}
|
||||
return sanitize(obj.name)
|
||||
}
|
||||
|
||||
def fileScope(path) {
|
||||
def root = path.getName(0).toString()
|
||||
if (root.endsWith(".sql")) return null
|
||||
return ObjectPath.create(root, ObjectKind.SCHEMA)
|
||||
}
|
||||
|
||||
def storeSeparately(obj) {
|
||||
return obj instanceof DasObjectWithSource || obj instanceof DasSchemaChild
|
||||
}
|
||||
|
||||
def sanitize(name) {
|
||||
return name.replace('/', 'slash')
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import com.intellij.database.model.DasObjectWithSource
|
||||
import com.intellij.database.model.DasSchemaChild
|
||||
|
||||
LAYOUT.baseName { ctx -> baseName(ctx.object) }
|
||||
LAYOUT.fileName { ctx -> String.format("%03d-%s.sql", ctx.count, ctx.baseName) }
|
||||
|
||||
|
||||
def baseName(obj) {
|
||||
for (def cur = obj; cur != null; cur = cur.dasParent) {
|
||||
if (storeSeparately(cur)) return sanitize(cur.name)
|
||||
}
|
||||
return sanitize(obj.name)
|
||||
}
|
||||
|
||||
def storeSeparately(obj) {
|
||||
return obj instanceof DasObjectWithSource || obj instanceof DasSchemaChild
|
||||
}
|
||||
|
||||
def sanitize(name) {
|
||||
return name.replace('/', 'slash')
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import com.intellij.database.model.DasObjectWithSource
|
||||
import com.intellij.database.model.DasSchemaChild
|
||||
|
||||
LAYOUT.ignoreDependencies = true
|
||||
LAYOUT.baseName { ctx -> baseName(ctx.object) }
|
||||
|
||||
|
||||
def baseName(obj) {
|
||||
for (def cur = obj; cur != null; cur = cur.dasParent) {
|
||||
if (storeSeparately(cur)) return sanitize(cur.name)
|
||||
}
|
||||
return sanitize(obj.name)
|
||||
}
|
||||
|
||||
def storeSeparately(obj) {
|
||||
return obj instanceof DasObjectWithSource || obj instanceof DasSchemaChild
|
||||
}
|
||||
|
||||
def sanitize(name) {
|
||||
return name.replace('/', 'slash')
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
import com.intellij.database.model.DasTable
|
||||
import com.intellij.database.util.Case
|
||||
import com.intellij.database.util.DasUtil
|
||||
|
||||
/*
|
||||
* Available context bindings:
|
||||
* SELECTION Iterable<DasObject>
|
||||
* PROJECT project
|
||||
* FILES files helper
|
||||
*/
|
||||
|
||||
packageName = "com.sample;"
|
||||
typeMapping = [
|
||||
(~/(?i)int/) : "long",
|
||||
(~/(?i)float|double|decimal|real/): "double",
|
||||
(~/(?i)datetime|timestamp/) : "java.sql.Timestamp",
|
||||
(~/(?i)date/) : "java.sql.Date",
|
||||
(~/(?i)time/) : "java.sql.Time",
|
||||
(~/(?i)/) : "String"
|
||||
]
|
||||
|
||||
FILES.chooseDirectoryAndSave("Choose directory", "Choose where to store generated files") { dir ->
|
||||
SELECTION.filter { it instanceof DasTable }.each { generate(it, dir) }
|
||||
}
|
||||
|
||||
def generate(table, dir) {
|
||||
def className = javaName(table.getName(), true)
|
||||
def fields = calcFields(table)
|
||||
new File(dir, className + ".java").withPrintWriter { out -> generate(out, className, fields) }
|
||||
}
|
||||
|
||||
def generate(out, className, fields) {
|
||||
out.println "package $packageName"
|
||||
out.println ""
|
||||
out.println ""
|
||||
out.println "public class $className {"
|
||||
out.println ""
|
||||
fields.each() {
|
||||
if (it.annos != "") out.println " ${it.annos}"
|
||||
out.println " private ${it.type} ${it.name};"
|
||||
}
|
||||
out.println ""
|
||||
fields.each() {
|
||||
out.println ""
|
||||
out.println " public ${it.type} get${it.name.capitalize()}() {"
|
||||
out.println " return ${it.name};"
|
||||
out.println " }"
|
||||
out.println ""
|
||||
out.println " public void set${it.name.capitalize()}(${it.type} ${it.name}) {"
|
||||
out.println " this.${it.name} = ${it.name};"
|
||||
out.println " }"
|
||||
out.println ""
|
||||
}
|
||||
out.println "}"
|
||||
}
|
||||
|
||||
def calcFields(table) {
|
||||
DasUtil.getColumns(table).reduce([]) { fields, col ->
|
||||
def spec = Case.LOWER.apply(col.getDasType().getSpecification())
|
||||
def typeStr = typeMapping.find { p, t -> p.matcher(spec).find() }.value
|
||||
fields += [[
|
||||
name : javaName(col.getName(), false),
|
||||
type : typeStr,
|
||||
annos: ""]]
|
||||
}
|
||||
}
|
||||
|
||||
def javaName(str, capitalize) {
|
||||
def s = com.intellij.psi.codeStyle.NameUtil.splitNameIntoWords(str)
|
||||
.collect { Case.LOWER.apply(it).capitalize() }
|
||||
.join("")
|
||||
.replaceAll(/[^\p{javaJavaIdentifierPart}[_]]/, "_")
|
||||
capitalize || s.length() == 1? s : Case.LOWER.apply(s[0]) + s[1..-1]
|
||||
}
|
||||
Reference in New Issue
Block a user