From 4265bd48f2c75ba48cc2cfde9514009a6fa0756a Mon Sep 17 00:00:00 2001 From: Raphael 'kena' Poss Date: Fri, 12 Apr 2019 19:06:10 +0200 Subject: [PATCH] Remove some configuration options This PR removes the ability to customize keyword casing, simplify expressions and change the alignment mode. Instead it proposes just two modes: - the default "compact" mode uses "full" alignment and simplificaiton - the optional "expanded" mode uses no alignment and does not simplify expressions Example, "compact": ``` SELECT count(*) AS count, winner, counter * 60 * 5 AS counter FROM ( SELECT winner, round(length / (60 * 5)) AS counter FROM players WHERE build = $1 AND (hero = $2 OR region = $3) ) GROUP BY winner, counter; ``` Example, "expanded": ``` SELECT count(*) AS count, winner, counter * (60 * 5) AS counter FROM ( SELECT winner, round(length / (60 * 5)) AS counter FROM players WHERE build = $1 AND (hero = $2 OR region = $3) ) GROUP BY winner, counter; ``` --- main.go | 146 ++++++++++++++++---------------------------------------- 1 file changed, 40 insertions(+), 106 deletions(-) diff --git a/main.go b/main.go index 0b674a05..573c9355 100644 --- a/main.go +++ b/main.go @@ -7,7 +7,6 @@ import ( "html/template" "io/ioutil" "log" - "math/rand" "net/http" "os" "os/signal" @@ -36,11 +35,10 @@ type Specification struct { var ( prettyCfg = tree.DefaultPrettyCfg() + flagExpanded = flag.Bool("expanded", false, "use a verbose, expansive format") flagPrintWidth = flag.Int("print-width", 60, "line length where sqlfmt will try to wrap") flagUseSpaces = flag.Bool("use-spaces", false, "indent with spaces instead of tabs") flagTabWidth = flag.Int("tab-width", 4, "number of spaces per indentation level") - flagNoSimplify = flag.Bool("no-simplify", false, "don't simplify the output") - flagAlign = flag.Bool("align", false, "right-align keywords") flagStmts = flag.StringArray("stmt", nil, "instead of reading from stdin, specify statements as arguments") flagHelp = flag.BoolP("help", "h", false, "display help") flagVersion = flag.BoolP("version", "v", false, "display version") @@ -113,9 +111,11 @@ func runCmd() error { cfg.UseTabs = !*flagUseSpaces cfg.LineWidth = *flagPrintWidth cfg.TabWidth = *flagTabWidth - cfg.Simplify = !*flagNoSimplify - cfg.Align = tree.PrettyNoAlign - if *flagAlign { + if *flagExpanded { + cfg.Simplify = false + cfg.Align = tree.PrettyNoAlign + } else { + cfg.Simplify = false cfg.Align = tree.PrettyAlignAndDeindent } @@ -323,15 +323,10 @@ func fmtSQLRequest(r *http.Request) (string, error) { if err != nil { return "", err } - simplify, err := parseBool(r.FormValue("simplify")) + expanded, err := parseBool(r.FormValue("expanded")) if err != nil { return "", err } - align, err := strconv.Atoi(r.FormValue("align")) - if err != nil { - return "", err - } - casemode := caseModes[r.FormValue("case")] spaces, err := parseBool(r.FormValue("spaces")) if err != nil { return "", err @@ -341,31 +336,16 @@ func fmtSQLRequest(r *http.Request) (string, error) { pcfg.LineWidth = n pcfg.UseTabs = !spaces pcfg.TabWidth = tabWidth - pcfg.Simplify = simplify - pcfg.Align = tree.PrettyAlignMode(align) - pcfg.Case = casemode - - return fmtsql(pcfg, []string{sql}) -} - -var caseModes = map[string]func(string) string{ - "upper": strings.ToUpper, - "lower": strings.ToLower, - "title": titleCase, - "spongebob": spongeBobCase, -} - -func titleCase(s string) string { - return strings.Title(strings.ToLower(s)) -} + pcfg.Case = strings.ToUpper -func spongeBobCase(s string) string { - var b strings.Builder - b.Grow(len(s)) - for _, c := range s { - b.WriteRune(unicode.To(rand.Intn(2), c)) + if expanded { + pcfg.Simplify = false + pcfg.Align = tree.PrettyNoAlign + } else { + pcfg.Simplify = true + pcfg.Align = tree.PrettyAlignAndDeindent } - return b.String() + return fmtsql(pcfg, []string{sql}) } const ( @@ -435,32 +415,12 @@ Its purpose is to beautifully format SQL statements.

Usage

-

There is a box in which to paste or type SQL statements. Multiple statements are supported by separating them with a semicolon (;). The slider below the box controls the desired maximum line width in characters. Various options on the side control tab/indentation width, the use of spaces or tabs, simplification, and alignment modes. Simplification causes the formatter to remove unneeded parentheses and words when the meaning will be the same without them.

- -

There are four alignment modes. The default, no, uses left alignment. partial right aligns keywords at the width of the longest keyword at the beginning of all lines immediately below. full is the same as partial but the keywords AND and OR are deindented, in a style similar to the sqlite tests. other is like partial but instead of deindenting AND and OR, their arguments are instead indented.

- -

no:

-
-SELECT
-    a
-FROM
-    t
-WHERE
-    c
-    AND b
-    OR d
-
+

There is a box in which to paste or type SQL statements. Multiple statements are supported by separating them with a semicolon (;). The slider below the box controls the desired maximum line width in characters. Various options on the side control tab/indentation width, and the use of spaces or tabs.

-

partial:

-
-SELECT a
-  FROM t
- WHERE c
-       AND b
-       OR d
-
+

There are two formatting modes. The default "compact" format, simplifies expressions and collapses clauses using alignment to clarify between clauses. +The "expanded" format avoids simplifying expressions and reveals the full structure of SQL queries.

-

full:

+

compact:

 SELECT a
   FROM t
@@ -469,14 +429,16 @@ SELECT a
     OR d
 
-

other:

+

expanded:

-SELECT a
-  FROM t
- WHERE    c
-          AND
-            b
-       OR d
+SELECT
+    a
+FROM
+    t
+WHERE
+    c
+    AND b
+    OR d
 

Background

@@ -504,18 +466,8 @@ sqlfmt was inspired by prettier. It is based

options:

-

-
alignment mode: -
- -
- -
case: -
- -
- +



@@ -540,9 +492,7 @@ const actualWidth = document.getElementById('actual_width'); const actualBytes = document.getElementById('actual_bytes'); const n = document.getElementById('n'); const iw = document.getElementById('indent'); -const simplify = document.getElementById('simplify'); -const align = document.theform.align; -const casemode = document.theform.casemode; +const expanded = document.getElementById('expanded'); const spaces = document.getElementById('spaces'); const fmt = document.getElementById('fmt'); const sqlEl = document.getElementById('sql'); @@ -623,20 +573,16 @@ function range() { const viw = iw.value; const sql = sqlEl.value; const spVal = spaces.checked ? 1 : 0; - const simVal = simplify.checked ? 1 : 0; - const alVal = align.value; - const caseVal = casemode.value; + const expVal = expanded.checked ? 1 : 0; localStorage.setItem('sql', sql); localStorage.setItem('n', v); localStorage.setItem('iw', viw); - localStorage.setItem('simplify', simVal); - localStorage.setItem('align', alVal); - localStorage.setItem('case', caseVal); + localStorage.setItem('expanded', expVal); localStorage.setItem('spaces', spVal); fmt.style["tab-size"] = viw; fmt.style["-moz-tab-size"] = viw; - share.href = '/?n=' + v + '&indent=' + viw + '&spaces=' + spVal + '&simplify=' + simVal + '&align=' + alVal + '&case=' + caseVal + '&sql=' + encodeURIComponent(b64EncodeUnicode(sql)); - fetch('/fmt?json=1&n=' + v + '&indent=' + viw + '&spaces=' + spVal + '&simplify=' + simVal + '&align=' + alVal + '&case=' + caseVal + '&sql=' + encodeURIComponent(sql)).then( + share.href = '/?n=' + v + '&indent=' + viw + '&spaces=' + spVal + '&expanded=' + expVal + '&sql=' + encodeURIComponent(b64EncodeUnicode(sql)); + fetch('/fmt?json=1&n=' + v + '&indent=' + viw + '&spaces=' + spVal + '&expanded=' + expVal + '&sql=' + encodeURIComponent(sql)).then( resp => { working = false; resp.json().then(data => { @@ -699,9 +645,7 @@ function reloadVals() { let sql = localStorage.getItem('sql'); let nVal = localStorage.getItem('n'); let iwVal = localStorage.getItem('iw'); - let simVal = localStorage.getItem('simplify'); - let alVal = localStorage.getItem('align'); - let caseVal = localStorage.getItem('case'); + let expVal = localStorage.getItem('expanded'); let spVal = localStorage.getItem('spaces'); // Load predefined defaults, for each value that didn't have a default in storage. @@ -713,9 +657,7 @@ function reloadVals() { } if (nVal === null) { nVal = 60; } if (iwVal === null) { iwVal = 4; } - if (simVal === null) { simVal = 1; } - if (alVal === null) { alVal = 0; } - if (caseVal === null) { caseVal = 'upper'; } + if (expVal === null) { expVal = 1; } if (spVal === null) { spVal = 0; } // Override any value from the URL. @@ -724,9 +666,7 @@ function reloadVals() { if (search.has('sql')) { sql = b64DecodeUnicode(search.get('sql')); } if (search.has('n')) { nVal = search.get('n'); } if (search.has('indent')) { iwVal = search.get('indent'); } - if (search.has('align')) { alVal = search.get('align'); } - if (search.has('case')) { caseVal = search.get('case'); } - if (search.has('simplify')) { simVal = search.get('simplify'); } + if (search.has('expanded')) { simVal = search.get('expanded'); } if (search.has('spaces')) { spVal = search.get('spaces'); } } @@ -734,9 +674,7 @@ function reloadVals() { sqlEl.value = sql; n.value = nVal; iw.value = iwVal; - simplify.checked = !!simVal; - align.value = alVal; - casemode.value = caseVal; + expanded.checked = !!expVal; spaces.checked = !!spVal; } @@ -762,9 +700,7 @@ autoPaste(); sqlEl.onkeydown = null; n.oninput = n.onchange = range; iw.oninput = iw.onchange = range; - simplify.oninput = simplify.onchange = range; - align.oninput = simplify.oninput = range; - casemode.oninput = simplify.onchange = range; + expanded.oninput = expanded.onchange = range; spaces.oninput = spaces.oninput = range; reset.onclick = resetVals; }; @@ -774,9 +710,7 @@ autoPaste(); range(); }; iw.oninput = iw.onchange = n.oninput; - simplify.oninput = simplify.onchange = n.oninput; - align.oninput = simplify.oninput = n.oninput; - casemode.oninput = simplify.oninput = n.oninput; + expanded.oninput = expanded.onchange = n.oninput; spaces.oninput = spaces.oninput = n.oninput; reset.onclick = () => { clearSearch();