diff --git a/.gitmodules b/.gitmodules
index ed6a3d93..29ce44a6 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +1,3 @@
-[submodule "docs/themes/hugo-coder"]
- path = docs/themes/hugo-coder
- url = https://github.com/luizdepra/hugo-coder.git
+[submodule "docs/themes/hugo-whisper-theme"]
+ path = docs/themes/hugo-whisper-theme
+ url = https://github.com/jugglerx/hugo-whisper-theme.git
diff --git a/Makefile b/Makefile
index 35027cb6..517e982c 100644
--- a/Makefile
+++ b/Makefile
@@ -21,6 +21,14 @@ lint: bin/golangci-lint
@echo
bin/golangci-lint run ./...
+.PHONY: docs
+docs:
+ @echo
+ @echo " (x x) < memefish: docs"
+ @echo " /|||\\"
+ @echo
+ cd docs && hugo
+
.PHONY: ci
ci: lint test
diff --git a/README.md b/README.md
index 6206c5df..b0e8464f 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,9 @@
+---
+title: README
+---
+
-
+
# méméfish
@@ -18,134 +22,6 @@
- Generate Spanner SQL from AST (unparse)
- Check expression type and semantics in SQL statement
-Try it!
-
-```console
-$ go run ./tools/analyze -param ./tools/param.yml 'select 1 + @foo'
-+-------+
-| FOO |
-+-------+
-| INT64 |
-+-------+
-
-$ go run ./tools/analyze -param ./tools/param.yml 'select @bar + 1 as bar'
-analyze error::1:8: operator + requires two INT64/FLOAT64, but: STRUCT, INT64
-
- 1: select @bar + 1 as bar
- ^~~~~~~~
-
-exit status 1
-```
-
-## Example
-
-### Parse + Unparse
-
-```go
-package main
-
-import (
- "fmt"
- "log"
-
- "github.com/MakeNowJust/memefish/pkg/parser"
- "github.com/MakeNowJust/memefish/pkg/token"
- "github.com/k0kubun/pp"
-)
-
-func main() {
- // Create a new Parser instance.
- file := &token.File{
- Buffer: "SELECT * FROM customers",
- }
- p := &parser.Parser{
- Lexer: &parser.Lexer{File: file},
- }
-
- // Do parsing!
- stmt, err := p.ParseQuery()
- if err != nil {
- log.Fatal(err)
- }
-
- // Show AST.
- log.Print("AST")
- _, _ = pp.Println(stmt)
-
- // Unparse AST to SQL source string.
- log.Print("Unparse")
- fmt.Println(stmt.SQL())
-}
-```
-
-### Analyze
-
-```go
-package main
-
-import (
- "fmt"
- "log"
-
- "github.com/MakeNowJust/memefish/pkg/analyzer"
- "github.com/MakeNowJust/memefish/pkg/parser"
- "github.com/MakeNowJust/memefish/pkg/token"
-)
-
-func main() {
- // Create a new Parser instance.
- file := &token.File{
- Buffer: "SELECT * FROM singers",
- }
- p := &parser.Parser{
- Lexer: &parser.Lexer{File: file},
- }
-
- // Do parsing!
- stmt, err := p.ParseQuery()
- if err != nil {
- log.Fatal(err)
- }
-
- // Create table catalog.
- catalog := &analyzer.Catalog{
- Tables: map[string]*analyzer.TableSchema{
- "SINGERS": {
- Name: "Singers",
- Columns: []*analyzer.ColumnSchema{
- {Name: "SingerId", Type: analyzer.Int64Type},
- {Name: "FirstName", Type: analyzer.StringType},
- {Name: "LastName", Type: analyzer.StringType},
- },
- },
- },
- }
-
- // Create a new Analyzer instance.
- a := &analyzer.Analyzer{
- File: file,
- Catalog: catalog,
- }
-
- // Analyze!
- err = a.AnalyzeQueryStatement(stmt)
- if err != nil {
- log.Fatal(err)
- }
-
- // Get first column information.
- columns := a.NameLists[stmt.Query]
- fmt.Printf("1st column name : %s\n", columns[0].Text)
- fmt.Printf("1st column type : %s\n", columns[0].Type)
- fmt.Printf("1st column schema: %#v\n", columns[0].Deref().ColumnSchema) // == catalog.Tables["SINGERS"].Columns[0]
-}
-```
-
-## TODO
-
-- Make more compatibility
-- Build Spanner emulator on memefish
-
## Notice
This project is originally developed under "Expert team Go Engineer (Backend)" of [Mercari Summer Internship for Engineer 2019](https://mercan.mercari.com/articles/13497/).
@@ -154,7 +30,5 @@ This project is originally developed under "Expert team Go Engineer (Backend)" o
This project is licensed under MIT license.
-2019 (C) TSUYUSATO "MakeNowJust" Kitsune
-
[godoc-badge]: https://img.shields.io/badge/godoc-reference-black.svg?style=for-the-badge&colorA=%235272B4&logo=go&logoColor=white
[codecov-badge]: https://img.shields.io/codecov/c/github/MakeNowJust/memefish/master.svg?style=for-the-badge&colorA=FF005E&logo=codecov&logoColor=white
diff --git a/docs/.gitignore b/docs/.gitignore
new file mode 100644
index 00000000..e54c19ca
--- /dev/null
+++ b/docs/.gitignore
@@ -0,0 +1,2 @@
+resources/
+public/
\ No newline at end of file
diff --git a/docs/archetypes/default.md b/docs/archetypes/default.md
deleted file mode 100644
index 00e77bd7..00000000
--- a/docs/archetypes/default.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: "{{ replace .Name "-" " " | title }}"
-date: {{ .Date }}
-draft: true
----
-
diff --git a/docs/config.toml b/docs/config.toml
index e4b74182..f54e7c85 100644
--- a/docs/config.toml
+++ b/docs/config.toml
@@ -1,3 +1,41 @@
-baseURL = "http://example.org/"
-languageCode = "en-us"
-title = "My New Hugo Site"
+baseurl = "https://makenowjust.github.io/memefish"
+title = "méméfish"
+theme = "hugo-whisper-theme"
+languagecode = "en"
+defaultcontentlanguage = "en"
+
+paginate = 20
+canonifyurls = true
+
+pygmentsstyle = "bw"
+pygmentscodefences = true
+pygmentscodefencesguesssyntax = true
+
+summaryLength = 30
+
+[params]
+ homepage_button_link = "/docs"
+ homepage_button_text = "Read The Docs"
+ homepage_intro = "the foundation to analyze Spanner SQL"
+ homepage_image = "/images/terminal.svg"
+
+ [params.logo]
+ mobile = "/images/memefish.svg"
+ standard = "/images/memefish.svg"
+
+[[menu.main]]
+ name = "Docs"
+ weight = 1
+ url = "/docs/"
+[[menu.main]]
+ name = "Demo"
+ weight = 2
+ url = "/demo/"
+[[menu.main]]
+ name = "GoDoc"
+ weight = 3
+ url = "https://godoc.org/github.com/MakeNowJust/memefish/pkg"
+[[menu.main]]
+ name = "GitHub"
+ weight = 3
+ url = "https://github.com/MakeNowJust/memefish"
\ No newline at end of file
diff --git a/docs/content/docs/_index.md b/docs/content/docs/_index.md
new file mode 120000
index 00000000..8a33348c
--- /dev/null
+++ b/docs/content/docs/_index.md
@@ -0,0 +1 @@
+../../../README.md
\ No newline at end of file
diff --git a/docs/content/docs/example-analyze/index.md b/docs/content/docs/example-analyze/index.md
new file mode 100644
index 00000000..830100ab
--- /dev/null
+++ b/docs/content/docs/example-analyze/index.md
@@ -0,0 +1,76 @@
+---
+date: 2020-02-03 00:00:00 +0900
+title: "Example: analyze"
+weight: 2
+---
+
+This example shows how to analyze a Spanner SQL after parsing.
+
+
+
+## Code
+
+```go
+package main
+
+import (
+ "fmt"
+ "log"
+
+ "github.com/MakeNowJust/memefish/pkg/analyzer"
+ "github.com/MakeNowJust/memefish/pkg/parser"
+ "github.com/MakeNowJust/memefish/pkg/token"
+)
+
+func main() {
+ // Create a new Parser instance.
+ file := &token.File{
+ Buffer: "SELECT * FROM singers",
+ }
+ p := &parser.Parser{
+ Lexer: &parser.Lexer{File: file},
+ }
+
+ // Do parsing!
+ stmt, err := p.ParseQuery()
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ // Create table catalog.
+ catalog := &analyzer.Catalog{
+ Tables: map[string]*analyzer.TableSchema{
+ "SINGERS": {
+ Name: "Singers",
+ Columns: []*analyzer.ColumnSchema{
+ {Name: "SingerId", Type: analyzer.Int64Type},
+ {Name: "FirstName", Type: analyzer.StringType},
+ {Name: "LastName", Type: analyzer.StringType},
+ },
+ },
+ },
+ }
+
+ // Create a new Analyzer instance.
+ a := &analyzer.Analyzer{
+ File: file,
+ Catalog: catalog,
+ }
+
+ // Analyze!
+ err = a.AnalyzeQueryStatement(stmt)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ // Get first column information.
+ columns := a.NameLists[stmt.Query]
+ fmt.Printf("1st column name : %s\n", columns[0].Text)
+ fmt.Printf("1st column type : %s\n", columns[0].Type)
+ fmt.Printf("1st column schema: %#v\n", columns[0].Deref().ColumnSchema) // == catalog.Tables["SINGERS"].Columns[0]
+}
+```
+
+## Links
+
+- [analyzer - GoDoc](https://godoc.org/github.com/MakeNowJust/memefish/pkg/analyzer)
\ No newline at end of file
diff --git a/docs/content/docs/example-parse/index.md b/docs/content/docs/example-parse/index.md
new file mode 100644
index 00000000..08eca419
--- /dev/null
+++ b/docs/content/docs/example-parse/index.md
@@ -0,0 +1,54 @@
+---
+date: 2020-02-03 00:00:00 +0900
+title: "Example: parse and unparse"
+weight: 1
+---
+
+This example shows how to parse a Spanner SQL and unparse it.
+
+
+
+ ## Code
+
+```go
+package main
+
+import (
+ "fmt"
+ "log"
+
+ "github.com/MakeNowJust/memefish/pkg/parser"
+ "github.com/MakeNowJust/memefish/pkg/token"
+ "github.com/k0kubun/pp"
+)
+
+func main() {
+ // Create a new Parser instance.
+ file := &token.File{
+ Buffer: "SELECT * FROM customers",
+ }
+ p := &parser.Parser{
+ Lexer: &parser.Lexer{File: file},
+ }
+
+ // Do parsing!
+ stmt, err := p.ParseQuery()
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ // Show AST.
+ log.Print("AST")
+ _, _ = pp.Println(stmt)
+
+ // Unparse AST to SQL source string.
+ log.Print("Unparse")
+ fmt.Println(stmt.SQL())
+}
+```
+
+## Links
+
+- [ast - GoDoc](https://godoc.org/github.com/MakeNowJust/memefish/pkg/ast)
+- [parser - GoDoc](https://godoc.org/github.com/MakeNowJust/memefish/pkg/parser)
+- [Query Syntax | Cloud Spanner | Google Cloud](https://cloud.google.com/spanner/docs/query-syntax)
\ No newline at end of file
diff --git a/docs/layouts/_default/list.html b/docs/layouts/_default/list.html
new file mode 100644
index 00000000..b23d3759
--- /dev/null
+++ b/docs/layouts/_default/list.html
@@ -0,0 +1,12 @@
+{{ define "header_css" }}{{ end }}
+{{ define "body_classes" }}page-default-list{{ end }}
+{{ define "header_classes" }}{{ end }}
+
+{{ define "main" }}
+
+{{ .Title }}
+
+ {{ .Content }}
+
+
+{{ end }}
diff --git a/docs/layouts/partials/sub-footer.html b/docs/layouts/partials/sub-footer.html
new file mode 100644
index 00000000..cd7b499c
--- /dev/null
+++ b/docs/layouts/partials/sub-footer.html
@@ -0,0 +1,16 @@
+
+
\ No newline at end of file
diff --git a/docs/static/images/memefish.svg b/docs/static/images/memefish.svg
new file mode 120000
index 00000000..9ac175a8
--- /dev/null
+++ b/docs/static/images/memefish.svg
@@ -0,0 +1 @@
+../../../images/memefish.svg
\ No newline at end of file
diff --git a/docs/static/images/terminal.svg b/docs/static/images/terminal.svg
new file mode 120000
index 00000000..ae07bd85
--- /dev/null
+++ b/docs/static/images/terminal.svg
@@ -0,0 +1 @@
+../../../images/terminal.svg
\ No newline at end of file
diff --git a/docs/themes/hugo-whisper-theme b/docs/themes/hugo-whisper-theme
new file mode 160000
index 00000000..60c6443b
--- /dev/null
+++ b/docs/themes/hugo-whisper-theme
@@ -0,0 +1 @@
+Subproject commit 60c6443b36efd49071f2ee70e7289ce9348ceb1c
diff --git a/icon/memefish.png b/images/memefish.png
similarity index 100%
rename from icon/memefish.png
rename to images/memefish.png
diff --git a/icon/memefish.svg b/images/memefish.svg
similarity index 100%
rename from icon/memefish.svg
rename to images/memefish.svg
diff --git a/images/terminal.svg b/images/terminal.svg
new file mode 100644
index 00000000..68d79620
--- /dev/null
+++ b/images/terminal.svg
@@ -0,0 +1,305 @@
+
\ No newline at end of file
diff --git a/tools/analyze/main.go b/tools/analyze/main.go
index 69f792d1..6cf9377a 100644
--- a/tools/analyze/main.go
+++ b/tools/analyze/main.go
@@ -2,6 +2,7 @@ package main
import (
"flag"
+ "fmt"
"io/ioutil"
"log"
"os"
@@ -15,9 +16,10 @@ import (
"gopkg.in/yaml.v2"
)
-var param = flag.String("param", "", "param file")
-var schema = flag.String("schema", "", "schema file")
+var param = flag.String("param", "./tools/param.yml", "param file")
+var schema = flag.String("schema", "./tools/schema.yml", "schema file")
var debug = flag.Bool("debug", false, "enable debug")
+var logging = flag.Bool("logging", false, "enable log")
func init() {
flag.Parse()
@@ -25,14 +27,14 @@ func init() {
func main() {
if flag.NArg() < 1 {
- log.Fatal("usage: ./analyze [SQL query]")
+ log.Fatal("usage: ./analyze [-param FILE] [-schema FILE] [-debug] [-logging] ")
}
query := flag.Arg(0)
var params map[string]interface{}
if *param != "" {
- log.Printf("load param file: %s", *param)
+ logf("load param file: %s", *param)
var err error
params, err = loadParamFile(*param)
if err != nil {
@@ -42,7 +44,7 @@ func main() {
var catalog map[string]*analyzer.TableSchema
if *schema != "" {
- log.Printf("load schema file: %s", *schema)
+ logf("load schema file: %s", *schema)
var err error
catalog, err = loadSchemaFile(*schema)
if err != nil {
@@ -50,7 +52,7 @@ func main() {
}
}
- log.Printf("query: %q", query)
+ logf("query: %q", query)
p := &parser.Parser{
Lexer: &parser.Lexer{
@@ -58,14 +60,15 @@ func main() {
},
}
- log.Printf("start parsing")
+ logf("start parsing")
stmt, err := p.ParseQuery()
if err != nil {
- log.Fatal(err)
+ fmt.Fprintf(os.Stderr, "%v", err)
+ os.Exit(1)
}
- log.Printf("finish parsing successfully")
+ logf("finish parsing successfully")
- log.Printf("start analyzing")
+ logf("start analyzing")
a := &analyzer.Analyzer{
File: p.File,
Params: params,
@@ -73,9 +76,10 @@ func main() {
}
err = a.AnalyzeQueryStatement(stmt)
if err != nil {
- log.Fatal(err)
+ fmt.Fprintf(os.Stderr, "%v", err)
+ os.Exit(1)
}
- log.Printf("finish analyzing")
+ logf("finish analyzing")
list := a.NameLists[stmt.Query]
if list == nil {
@@ -203,3 +207,9 @@ func decodeTableSchema(t *TableSchema) *analyzer.TableSchema {
Columns: columns,
}
}
+
+func logf(msg string, params ...interface{}) {
+ if *logging {
+ log.Printf(msg, params...)
+ }
+}
diff --git a/tools/parse/main.go b/tools/parse/main.go
index 2b8acdb9..6757654d 100644
--- a/tools/parse/main.go
+++ b/tools/parse/main.go
@@ -12,6 +12,7 @@ import (
)
var mode = flag.String("mode", "statement", "parsing mode")
+var logging = flag.Bool("logging", false, "enable log")
func init() {
flag.Parse()
@@ -19,12 +20,12 @@ func init() {
func main() {
if flag.NArg() < 1 {
- log.Fatal("usage: ./parse [-mode statement|query|expr|ddl|dml] [SQL query]")
+ log.Fatal("usage: ./parse [-mode statement|query|expr|ddl|dml] [-logging] ")
}
query := flag.Arg(0)
- log.Printf("query: %q", query)
+ logf("query: %q", query)
p := &parser.Parser{
Lexer: &parser.Lexer{
@@ -32,7 +33,7 @@ func main() {
},
}
- log.Printf("start parsing")
+ logf("start parsing")
var node ast.Node
var err error
switch *mode {
@@ -50,7 +51,7 @@ func main() {
if err != nil {
log.Fatal(err)
}
- log.Printf("finish parsing successfully")
+ logf("finish parsing successfully")
fmt.Println("--- AST")
_, _ = pp.Println(node)
@@ -58,3 +59,9 @@ func main() {
fmt.Println("--- SQL")
fmt.Println(node.SQL())
}
+
+func logf(msg string, params ...interface{}) {
+ if *logging {
+ log.Printf(msg, params...)
+ }
+}