Skip to content

Commit

Permalink
Update local command (#121)
Browse files Browse the repository at this point in the history
* update local command

* update readme
  • Loading branch information
jievince authored Aug 18, 2021
1 parent a673b17 commit 2c58080
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 131 deletions.
56 changes: 14 additions & 42 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,27 +105,25 @@ docker> nebula-console -u <user> -p <password> --address=<graphd> --port=9669
```
## Export mode for Nebula Graph Console
When the export mode is enabled, Nebula Graph Console exports all the query results into a CSV file. When the export mode is disabled, the export stops. The syntax is as follows.
## Console side commands:
> **NOTE**: The following commands are case insensitive.
* Enable nebula-console export mode:
* Export the result of the following statement to a csv file:
```nGQL
nebula> :set CSV <your_file.csv>
nebula> :csv a.csv
```
* Disable nebula-console export mode:
* Export the execution plan in graphviz format to a dot file when profiling a statement with format "dot" or "dot:struct":
```nGQL
nebula> :unset CSV
nebula> :dot a.dot
nebula> PROFILE FORMAT="dot" GO FROM "Tony Parker" OVER like;
```
You can paste the content in the dot file to `https://dreampuf.github.io/GraphvizOnline/` to show the execution plan.
## Load nba dataset
To load the demonstration nba dataset, make sure that Console is connected to Nebula Graph.
* Load the demonstration nba dataset:
```ngql
nebula> :play nba
Expand All @@ -134,45 +132,19 @@ Start loading dataset nba...
Load dataset succeeded!
```
## Wait for heartbeat
```nGQL
nebula> :sleep 3
```
e.g.
```nGQL
cat >> nba.ngql << EOF
CREATE SPACE nba(VID_TYPE=FIXED_STRING(32));
:sleep 3
USE nba;
CREATE TAG IF NOT EXISTS player(name string, age int);
:sleep 3
INSERT VERTEX player(name, age) VALUES "Amar'e Stoudemire": ("Amar'e Stoudemire", 36)
EOF
nebula-console -addr 127.0.0.1 -port 9669 -u root -p nebula -f nba.ngql
```
## Export .dot file
To export the graviz text to a `.dot` format, run the following command:
* Repeat to execute a statement n times, the average execution time will also be printed:
```ngql
nebula> :set dot <filename>
nebula> :repeat 3
```
For example:
* Sleep for some seconds, it's just used in `:play nba`:

```ngql
nebula> TODO
```nGQL
nebula> :sleep 3
```

## Disconnect Nebula Graph Console from Nebula Graph
* Exit the console

You can use `:EXIT` or `:QUIT` to disconnect from Nebula Graph. For convenience, nebula-console supports using these commands in lower case without the colon (":"), such as `quit`.

Expand Down
93 changes: 38 additions & 55 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,13 @@ import (

// Console side commands
const (
Unknown = -1
Quit = 0
SetCsv = 1
UnsetCsv = 2
PlayData = 3
Sleep = 4
SetDot = 5
UnsetDot = 6
Repeat = 7
Unknown = -1
Quit = 0
PlayData = 1
Sleep = 2
ExportCsv = 3
ExportDot = 4
Repeat = 5
)

var dataSetPrinter = printer.NewDataSetPrinter()
Expand All @@ -45,8 +43,6 @@ in order to get the total and avearge execution time of the statement") */
var g_repeats = 1

func welcome(interactive bool) {
defer dataSetPrinter.UnsetOutCsv()
defer planDescPrinter.UnsetOutDot()
if !interactive {
return
}
Expand Down Expand Up @@ -99,6 +95,8 @@ func playData(data string) (string, error) {

// Console side cmd will not be sent to server
func isConsoleCmd(cmd string) (isLocal bool, localCmd int, args []string) {
isLocal = false
localCmd = Unknown
// Currently, command "exit" and "quit" can also exit the console
if cmd == "exit" || cmd == "quit" {
isLocal = true
Expand All @@ -112,63 +110,56 @@ func isConsoleCmd(cmd string) (isLocal bool, localCmd int, args []string) {
}

isLocal = true
localCmd = Unknown
if plain[len(plain)-1] == ';' {
plain = plain[:len(plain)-1]
}
words := strings.Fields(plain[1:])
switch len(words) {
case 1:
if words[0] == "exit" || words[0] == "quit" {
localCmd = Quit
}
case 2:
if words[0] == "unset" && words[1] == "csv" {
localCmd = UnsetCsv
} else if words[0] == "unset" && words[1] == "dot" {
localCmd = UnsetDot
} else if words[0] == "sleep" {
localCmdName := words[0]
switch localCmdName {
case "exit", "quit":
localCmd = Quit
case "sleep":
{
localCmd = Sleep
args = []string{words[1]}
} else if words[0] == "play" {
}
case "play":
{
localCmd = PlayData
args = []string{words[1]}
} else if words[0] == "repeat" {
}
case "repeat":
{
localCmd = Repeat
args = []string{words[1]}
}
case 3:
if words[0] == "set" && words[1] == "csv" {
localCmd = SetCsv
args = []string{words[2]}
} else if words[0] == "set" && words[1] == "dot" {
localCmd = SetDot
args = []string{words[2]}
case "csv":
{
localCmd = ExportCsv
args = []string{words[1]}
}
case "dot":
{
localCmd = ExportDot
args = []string{words[1]}
}
default:
localCmd = Unknown
}

return
}

func executeConsoleCmd(cmd int, args []string) (newSpace string) {
func executeConsoleCmd(c cli.Cli, cmd int, args []string) {
switch cmd {
case SetCsv:
dataSetPrinter.SetOutCsv(args[0])
case UnsetCsv:
dataSetPrinter.UnsetOutCsv()
case SetDot:
planDescPrinter.SetOutDot(args[0])
case UnsetDot:
planDescPrinter.UnsetOutDot()
case ExportCsv:
dataSetPrinter.ExportCsv(args[0])
case ExportDot:
planDescPrinter.ExportDot(args[0])
case PlayData:
var err error
newSpace, err = playData(args[0])
newSpace, err := playData(args[0])
if err != nil {
printConsoleResp("Error: load dataset failed, " + err.Error())
} else {
printConsoleResp("Load dataset succeeded!")
c.SetSpace(newSpace)
}
case Sleep:
i, err := strconv.Atoi(args[0])
Expand All @@ -187,7 +178,6 @@ func executeConsoleCmd(cmd int, args []string) (newSpace string) {
default:
printConsoleResp("Error: this local command not exists!")
}
return newSpace
}

func printResultSet(res *nebula.ResultSet, startTime time.Time) (duration time.Duration) {
Expand Down Expand Up @@ -254,14 +244,7 @@ func loop(c cli.Cli) error {
if cmd == Quit {
return nil
}
newSpace := executeConsoleCmd(cmd, args)
if newSpace != "" {
c.SetSpace(newSpace)
session.Execute(fmt.Sprintf("USE %s", newSpace))
if err != nil {
return err
}
}
executeConsoleCmd(c, cmd, args)
continue
}
// Server side command
Expand Down
24 changes: 7 additions & 17 deletions printer/dataset_printer.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,7 @@ func NewDataSetPrinter() DataSetPrinter {
}
}

func (p *DataSetPrinter) SetOutCsv(filename string) {
if p.fd != nil {
p.UnsetOutCsv()
}
func (p *DataSetPrinter) ExportCsv(filename string) {
fd, err := os.OpenFile(filename, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0600)
if err != nil {
fmt.Printf("Open or Create file %s failed, %s", filename, err.Error())
Expand All @@ -42,17 +39,6 @@ func (p *DataSetPrinter) SetOutCsv(filename string) {
p.filename = filename
}

func (p *DataSetPrinter) UnsetOutCsv() {
if p.fd == nil {
return
}
if err := p.fd.Close(); err != nil {
fmt.Printf("Close file %s failed, %s", p.filename, err.Error())
}
p.fd = nil
p.filename = ""
}

func (p *DataSetPrinter) PrintDataSet(res *nebula.ResultSet) {
if res.GetColSize() == 0 {
return
Expand Down Expand Up @@ -86,10 +72,14 @@ func (p *DataSetPrinter) PrintDataSet(res *nebula.ResultSet) {
fmt.Println(p.writer.Render())
if p.fd != nil {
go func() {
p.fd.Truncate(0)
p.fd.Seek(0, 0)
s := strings.Replace(p.writer.RenderCSV(), "\\\"", "", -1)
fmt.Fprintln(p.fd, s)

if err := p.fd.Close(); err != nil {
fmt.Printf("Close file %s failed, %s", p.filename, err.Error())
}
p.fd = nil
p.filename = ""
}()
}
}
24 changes: 7 additions & 17 deletions printer/plan_desc_printer.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,7 @@ func NewPlanDescPrinter() PlanDescPrinter {
}
}

func (p *PlanDescPrinter) SetOutDot(filename string) {
if p.fd != nil {
p.UnsetOutDot()
}
func (p *PlanDescPrinter) ExportDot(filename string) {
fd, err := os.OpenFile(filename, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0600)
if err != nil {
fmt.Printf("Open or Create file %s failed, %s", filename, err.Error())
Expand All @@ -51,17 +48,6 @@ func (p *PlanDescPrinter) SetOutDot(filename string) {
p.filename = filename
}

func (p *PlanDescPrinter) UnsetOutDot() {
if p.fd == nil {
return
}
if err := p.fd.Close(); err != nil {
fmt.Printf("Close file %s failed, %s", p.filename, err.Error())
}
p.fd = nil
p.filename = ""
}

func (p PlanDescPrinter) configWriterDotRenderStyle(renderByDot bool) {
if renderByDot {
p.writer.Style().Box.Left = " "
Expand Down Expand Up @@ -132,9 +118,13 @@ func (p *PlanDescPrinter) PrintPlanDesc(res *nebula.ResultSet) {

if p.fd != nil {
go func() {
p.fd.Truncate(0)
p.fd.Seek(0, 0)
fmt.Fprintln(p.fd, s)

if err := p.fd.Close(); err != nil {
fmt.Printf("Close file %s failed, %s", p.filename, err.Error())
}
p.fd = nil
p.filename = ""
}()
}
}

0 comments on commit 2c58080

Please sign in to comment.