Passed
Pull Request — master (#17)
by Frank
10:41 queued 58s
created

config.*OutputFormat.Set   A

Complexity

Conditions 3

Size

Total Lines 9
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 7
nop 1
dl 0
loc 9
rs 10
c 0
b 0
f 0
1
package config
2
3
import (
4
	"fmt"
5
	"os"
6
	"path/filepath"
7
)
8
9
// DbType represents a type of a database.
10
type DbType string
11
12
// String is the implementation of the Stringer interface needed for flag.Value interface.
13
func (db DbType) String() string {
14
	return string(db)
15
}
16
17
// Set sets the datatype for the custom type for the flag package.
18
func (db *DbType) Set(s string) error {
19
	*db = DbType(s)
20
	if *db == "" {
21
		*db = DbTypePostgresql
22
	}
23
	if !SupportedDbTypes[*db] {
24
		return fmt.Errorf("type of database %q not supported! supported: %v", *db, SprintfSupportedDbTypes())
25
	}
26
	return nil
27
}
28
29
// These database types are supported.
30
const (
31
	DbTypePostgresql DbType = "pg"
32
	DbTypeMySQL      DbType = "mysql"
33
)
34
35
// NullType represents a null type.
36
type NullType string
37
38
// String is the implementation of the Stringer interface needed for flag.Value interface.
39
func (t NullType) String() string {
40
	return string(t)
41
}
42
43
// Set sets the datatype for the custom type for the flag package.
44
func (t *NullType) Set(s string) error {
45
	*t = NullType(s)
46
	if *t == "" {
47
		*t = NullTypeSQL
48
	}
49
	if !supportedNullTypes[*t] {
50
		return fmt.Errorf("null type %q not supported! supported: %v", *t, SupportedNullTypes())
51
	}
52
	return nil
53
}
54
55
// These null types are supported. The types native and primitive map to the same
56
// underlying builtin golang type.
57
const (
58
	NullTypeSQL       NullType = "sql"
59
	NullTypeNative    NullType = "native"
60
	NullTypePrimitive NullType = "primitive"
61
)
62
63
// OutputFormat represents a output format option.
64
type OutputFormat string
65
66
// String is the implementation of the Stringer interface needed for flag.Value interface.
67
func (of OutputFormat) String() string {
68
	return string(of)
69
}
70
71
// Set sets the datatype for the custom type for the flag package.
72
func (of *OutputFormat) Set(s string) error {
73
	*of = OutputFormat(s)
74
	if *of == "" {
75
		*of = OutputFormatCamelCase
76
	}
77
	if !supportedOutputFormats[*of] {
78
		return fmt.Errorf("output format %q not supported", *of)
79
	}
80
	return nil
81
}
82
83
// These are the output format command line parameter.
84
const (
85
	OutputFormatCamelCase OutputFormat = "c"
86
	OutputFormatOriginal  OutputFormat = "o"
87
)
88
89
var (
90
	// SupportedDbTypes represents the supported databases
91
	SupportedDbTypes = map[DbType]bool{
92
		DbTypePostgresql: true,
93
		DbTypeMySQL:      true,
94
	}
95
96
	// supportedOutputFormats represents the supported output formats
97
	supportedOutputFormats = map[OutputFormat]bool{
98
		OutputFormatCamelCase: true,
99
		OutputFormatOriginal:  true,
100
	}
101
102
	// dbDefaultPorts maps the database type to the default ports
103
	dbDefaultPorts = map[DbType]string{
104
		DbTypePostgresql: "5432",
105
		DbTypeMySQL:      "3306",
106
	}
107
108
	// supportedNullTypes represents the supported types of NULL types
109
	supportedNullTypes = map[NullType]bool{
110
		NullTypeSQL:       true,
111
		NullTypeNative:    true,
112
		NullTypePrimitive: true,
113
	}
114
)
115
116
// Settings stores the supported settings / command line arguments
117
type Settings struct {
118
	Verbose  bool
119
	VVerbose bool
120
121
	DbType DbType
122
123
	User   string
124
	Pswd   string
125
	DbName string
126
	Schema string
127
	Host   string
128
	Port   string
129
130
	OutputFilePath string
131
	OutputFormat   OutputFormat
132
133
	PackageName string
134
	Prefix      string
135
	Suffix      string
136
	Null        NullType
137
138
	NoInitialism bool
139
140
	TagsNoDb bool
141
142
	TagsMastermindStructable       bool
143
	TagsMastermindStructableOnly   bool
144
	IsMastermindStructableRecorder bool
145
146
	// TODO not implemented yet
147
	TagsGorm bool
148
149
	// experimental
150
	TagsSQL     bool
151
	TagsSQLOnly bool
152
}
153
154
// NewSettings constructs settings with default values
155
func NewSettings() *Settings {
156
157
	dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
158
	if err != nil {
159
		dir = "."
160
	}
161
162
	return &Settings{
163
		Verbose:  false,
164
		VVerbose: false,
165
166
		DbType:         DbTypePostgresql,
167
		User:           "postgres",
168
		Pswd:           "",
169
		DbName:         "postgres",
170
		Schema:         "public",
171
		Host:           "127.0.0.1",
172
		Port:           "", // left blank -> is automatically determined if not set
173
		OutputFilePath: dir,
174
		OutputFormat:   OutputFormatCamelCase,
175
		PackageName:    "dto",
176
		Prefix:         "",
177
		Suffix:         "",
178
		Null:           NullTypeSQL,
179
180
		NoInitialism: false,
181
182
		TagsNoDb: false,
183
184
		TagsMastermindStructable:       false,
185
		TagsMastermindStructableOnly:   false,
186
		IsMastermindStructableRecorder: false,
187
188
		TagsGorm: false,
189
190
		TagsSQL:     false,
191
		TagsSQLOnly: false,
192
	}
193
}
194
195
// Verify verifies the settings and checks the given output paths
196
func (settings *Settings) Verify() (err error) {
197
198
	if err = settings.verifyOutputPath(); err != nil {
199
		return err
200
	}
201
202
	if settings.OutputFilePath, err = settings.prepareOutputPath(); err != nil {
203
		return err
204
	}
205
206
	if settings.Port == "" {
207
		settings.Port = dbDefaultPorts[settings.DbType]
208
	}
209
210
	if settings.PackageName == "" {
211
		return fmt.Errorf("name of package can not be empty")
212
	}
213
214
	if settings.VVerbose {
215
		settings.Verbose = true
216
	}
217
218
	return err
219
}
220
221
func (settings *Settings) verifyOutputPath() (err error) {
222
223
	info, err := os.Stat(settings.OutputFilePath)
224
225
	if os.IsNotExist(err) {
226
		return fmt.Errorf("output file path %q does not exists", settings.OutputFilePath)
227
	}
228
229
	if !info.Mode().IsDir() {
230
		return fmt.Errorf("output file path %q is not a directory", settings.OutputFilePath)
231
	}
232
233
	return err
234
}
235
236
func (settings *Settings) prepareOutputPath() (outputFilePath string, err error) {
237
	outputFilePath, err = filepath.Abs(settings.OutputFilePath)
238
	outputFilePath += string(filepath.Separator)
239
	return outputFilePath, err
240
}
241
242
// SprintfSupportedDbTypes returns a slice of strings as names of the supported database types
243
func SprintfSupportedDbTypes() string {
244
	names := make([]string, 0, len(SupportedDbTypes))
245
	for name := range SupportedDbTypes {
246
		names = append(names, string(name))
247
	}
248
	return fmt.Sprintf("%v", names)
249
}
250
251
// SupportedNullTypes returns a slice of strings as names of the supported null types
252
func SupportedNullTypes() string {
253
	names := make([]string, 0, len(supportedNullTypes))
254
	for name := range supportedNullTypes {
255
		names = append(names, string(name))
256
	}
257
	return fmt.Sprintf("%v", names)
258
}
259
260
// IsNullTypeSQL returns true if the type given by the command line args is of null type SQL
261
func (settings *Settings) IsNullTypeSQL() bool {
262
	return settings.Null == NullTypeSQL
263
}
264
265
// ShouldInitialism returns wheather or not if column names should be converted
266
// to initialisms.
267
func (settings *Settings) ShouldInitialism() bool {
268
	return !settings.NoInitialism
269
}
270
271
// IsOutputFormatCamelCase returns if the type given by command line args is of camel-case format.
272
func (settings *Settings) IsOutputFormatCamelCase() bool {
273
	return settings.OutputFormat == OutputFormatCamelCase
274
}
275