This repository has been archived by the owner on Jan 28, 2021. It is now read-only.
/
show_create_table.go
137 lines (108 loc) · 3.46 KB
/
show_create_table.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
package plan
import (
"fmt"
"io"
"strings"
"gopkg.in/src-d/go-errors.v1"
"gopkg.in/src-d/go-mysql-server.v0/sql"
)
// ErrTableNotFound is returned when the table could not be found.
var ErrTableNotFound = errors.NewKind("Table `%s` not found")
// ShowCreateTable is a node that shows the CREATE TABLE statement for a table.
type ShowCreateTable struct {
Catalog *sql.Catalog
CurrentDatabase string
Table string
}
// Schema implements the Node interface.
func (n *ShowCreateTable) Schema() sql.Schema {
return sql.Schema{
&sql.Column{Name: "Table", Type: sql.Text, Nullable: false},
&sql.Column{Name: "Create Table", Type: sql.Text, Nullable: false},
}
}
// TransformExpressionsUp implements the Transformable interface.
func (n *ShowCreateTable) TransformExpressionsUp(f sql.TransformExprFunc) (sql.Node, error) {
return n, nil
}
// TransformUp implements the Transformable interface.
func (n *ShowCreateTable) TransformUp(f sql.TransformNodeFunc) (sql.Node, error) {
return f(NewShowCreateTable(n.CurrentDatabase, n.Catalog, n.Table))
}
// RowIter implements the Node interface
func (n *ShowCreateTable) RowIter(*sql.Context) (sql.RowIter, error) {
db, err := n.Catalog.Database(n.CurrentDatabase)
if err != nil {
return nil, sql.ErrDatabaseNotFound.New(n.CurrentDatabase)
}
return &showCreateTablesIter{
db: db,
table: n.Table,
}, nil
}
// String implements the Stringer interface.
func (n *ShowCreateTable) String() string {
return fmt.Sprintf("SHOW CREATE TABLE %s", n.Table)
}
type showCreateTablesIter struct {
db sql.Database
table string
didIteration bool
}
func (i *showCreateTablesIter) Next() (sql.Row, error) {
if i.didIteration {
return nil, io.EOF
}
i.didIteration = true
table, found := i.db.Tables()[i.table]
if !found {
return nil, ErrTableNotFound.New(i.table)
}
composedCreateTableStatement := produceCreateStatement(table)
return sql.NewRow(
i.table, // "Table" string
composedCreateTableStatement, // "Create Table" string
), nil
}
func produceCreateStatement(table sql.Table) string {
schema := table.Schema()
colCreateStatements := make([]string, len(schema))
// Statement creation parts for each column
for indx, col := range schema {
createStmtPart := fmt.Sprintf(" `%s` %s", col.Name, col.Type.Type())
if !col.Nullable {
createStmtPart = fmt.Sprintf("%s NOT NULL", createStmtPart)
}
switch def := col.Default.(type) {
case string:
if def != "" {
createStmtPart = fmt.Sprintf("%s DEFAULT %s", createStmtPart, def)
}
default:
if def != nil {
createStmtPart = fmt.Sprintf("%s DEFAULT %v", createStmtPart, col.Default)
}
}
colCreateStatements[indx] = createStmtPart
}
prettyColCreateStmts := strings.Join(colCreateStatements, ",\n")
composedCreateTableStatement :=
fmt.Sprintf("CREATE TABLE `%s` (\n%s\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", table.Name(), prettyColCreateStmts)
return composedCreateTableStatement
}
func (i *showCreateTablesIter) Close() error {
return nil
}
// NewShowCreateTable creates a new ShowCreateTable node.
func NewShowCreateTable(db string, ctl *sql.Catalog, table string) sql.Node {
return &ShowCreateTable{
CurrentDatabase: db,
Table: table,
Catalog: ctl}
}
// Resolved implements the Resolvable interface.
func (n *ShowCreateTable) Resolved() bool {
return true
}
// Children implements the Node interface.
func (n *ShowCreateTable) Children() []sql.Node { return nil }