/
bp2col.go
142 lines (116 loc) · 3.04 KB
/
bp2col.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
138
139
140
141
142
// Extract column metadata for one or more tables from an unzipped bacpac file
package main
import (
"bytes"
"flag"
"fmt"
"io/ioutil"
"log"
"os"
"runtime/pprof"
"sort"
"strings"
//
bp "github.com/gsiems/bac-tract/bactract"
)
type params struct {
baseDir string
tableName string
tablesFile string
cpuprofile string
memprofile string
debug bool
}
func main() {
var v params
flag.StringVar(&v.baseDir, "b", "", "The directory containing the unzipped bacpac file.")
flag.StringVar(&v.tableName, "t", "", "The table to extract column meta-data from. When not specified then extract column meta-data from all tables")
flag.StringVar(&v.tablesFile, "f", "", "The file to read the list of tables to extract column meta-data from, one table per line")
flag.StringVar(&v.cpuprofile, "cpuprofile", "", "The filename to write cpu profile information to")
//flag.StringVar(&v.memprofile, "memprofile", "", The filename to write memory profile information to")
flag.Parse()
if v.cpuprofile != "" {
f, err := os.Create(v.cpuprofile)
if err != nil {
log.Fatal(err)
}
err = pprof.StartCPUProfile(f)
if err != nil {
log.Fatal(err)
}
defer pprof.StopCPUProfile()
}
doDump(v)
}
func doDump(v params) {
p, _ := bp.New(v.baseDir)
model, err := p.GetModel("")
dieOnErrf("GetModel failed: %q", err)
var tables []string
if v.tableName != "" {
tables = append(tables, v.tableName)
} else if v.tablesFile != "" {
content, err := ioutil.ReadFile(v.tablesFile)
dieOnErrf("File read failed: %q", err)
x := bytes.Split(content, []byte("\n"))
for _, z := range x {
tables = append(tables, string(z))
}
} else {
for t, _ := range model.Tables {
tables = append(tables, t)
}
sort.Strings(tables)
}
fmt.Println(strings.Join([]string{"table_schema",
"table_name", "column_name", "ordinal_position", "is_nullable",
"data_type", "character_maximum_length", "numeric_precision",
"numeric_scale"}, "\t"))
for _, table := range tables {
t, ok := model.Tables[table]
if ok {
for i, c := range t.Columns {
var attr []string
attr = append(attr, t.Schema)
attr = append(attr, t.TabName)
attr = append(attr, c.ColName)
attr = append(attr, fmt.Sprintf("%d", i))
if c.IsNullable {
attr = append(attr, "YES")
} else {
attr = append(attr, "NO")
}
attr = append(attr, c.DtStr)
if isChar(c.DtStr) {
attr = append(attr, fmt.Sprintf("%d", c.Length))
} else if isBinary(c.DtStr) {
attr = append(attr, fmt.Sprintf("%d", c.Length))
} else {
attr = append(attr, "")
}
attr = append(attr, fmt.Sprintf("%d", c.Precision))
attr = append(attr, fmt.Sprintf("%d", c.Scale))
fmt.Println(strings.Join(attr, "\t"))
}
}
}
}
func isChar(dt string) (b bool) {
switch dt {
case "char", "varchar", "text", "nchar", "nvarchar", "ntext":
return true
}
return false
}
func isBinary(dt string) (b bool) {
switch dt {
case "binary", "varbinary":
return true
}
return false
}
func dieOnErrf(s string, err error) {
if err != nil {
log.Fatalf(s, err)
}
}