Passed
Pull Request — master (#17)
by Frank
06:11 queued 03:57
created

database.*Postgresql.IsTemporal   A

Complexity

Conditions 1

Size

Total Lines 2
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nop 1
dl 0
loc 2
rs 10
c 0
b 0
f 0
1
package database
2
3
import (
4
	"fmt"
5
	"strings"
6
7
	"github.com/fraenky8/tables-to-go/pkg/settings"
8
9
	// postgres database driver
10
	_ "github.com/lib/pq"
11
)
12
13
// Postgresql implemenmts the Database interface with help of generalDatabase
14
type Postgresql struct {
15
	*GeneralDatabase
16
}
17
18
// NewPostgresql creates a new Postgresql database
19
func NewPostgresql(s *settings.Settings) *Postgresql {
20
	return &Postgresql{
21
		GeneralDatabase: &GeneralDatabase{
22
			Settings: s,
23
			driver:   dbTypeToDriverMap[settings.DbType(s.DbType)],
24
		},
25
	}
26
}
27
28
// Connect connects to the database by the given data source name (dsn) of the concrete database
29
func (pg *Postgresql) Connect() error {
30
	return pg.GeneralDatabase.Connect(pg.DSN(pg.Settings))
31
}
32
33
// DSN creates the DSN String to connect to this database
34
func (pg *Postgresql) DSN(settings *settings.Settings) string {
35
	return fmt.Sprintf("host=%v port=%v user=%v dbname=%v password=%v sslmode=disable",
36
		settings.Host, settings.Port, settings.User, settings.DbName, settings.Pswd)
37
}
38
39
// GetDriverImportLibrary returns the golang sql driver specific fot the MySQL database
40
func (pg *Postgresql) GetDriverImportLibrary() string {
41
	return "pg \"github.com/lib/pq\""
42
}
43
44
// GetTables gets all tables for a given schema by name
45
func (pg *Postgresql) GetTables() (tables []*Table, err error) {
46
47
	err = pg.Select(&tables, `
48
		SELECT table_name
49
		FROM information_schema.tables
50
		WHERE table_type = 'BASE TABLE'
51
		AND table_schema = $1
52
		ORDER BY table_name
53
	`, pg.Schema)
54
55
	if pg.Verbose {
56
		if err != nil {
57
			fmt.Println("> Error at GetTables()")
58
			fmt.Printf("> schema: %q\r\n", pg.Schema)
59
		}
60
	}
61
62
	return tables, err
63
}
64
65
// PrepareGetColumnsOfTableStmt prepares the statement for retrieving the columns of a specific table for a given database
66
func (pg *Postgresql) PrepareGetColumnsOfTableStmt() (err error) {
67
68
	pg.GetColumnsOfTableStmt, err = pg.Preparex(`
69
		SELECT
70
			ic.ordinal_position,
71
			ic.column_name,
72
			ic.data_type,
73
			ic.column_default,
74
			ic.is_nullable,
75
			ic.character_maximum_length,
76
			ic.numeric_precision,
77
			itc.constraint_name,
78
			itc.constraint_type
79
		FROM information_schema.columns AS ic
80
			LEFT JOIN information_schema.key_column_usage AS ikcu ON ic.table_name = ikcu.table_name
81
			AND ic.table_schema = ikcu.table_schema
82
			AND ic.column_name = ikcu.column_name
83
			LEFT JOIN information_schema.table_constraints AS itc ON ic.table_name = itc.table_name
84
			AND ic.table_schema = itc.table_schema
85
			AND ikcu.constraint_name = itc.constraint_name
86
		WHERE ic.table_name = $1
87
		AND ic.table_schema = $2
88
		ORDER BY ic.ordinal_position
89
	`)
90
91
	return err
92
}
93
94
// GetColumnsOfTable executes the statement for retrieving the columns of a specific table in a given schema
95
func (pg *Postgresql) GetColumnsOfTable(table *Table) (err error) {
96
97
	err = pg.GetColumnsOfTableStmt.Select(&table.Columns, table.Name, pg.Schema)
98
99
	if pg.Verbose {
100
		if err != nil {
101
			fmt.Printf("> Error at GetColumnsOfTable(%v)\r\n", table.Name)
102
			fmt.Printf("> schema: %q\r\n", pg.Schema)
103
		}
104
	}
105
106
	return err
107
}
108
109
// IsPrimaryKey checks if column belongs to primary key
110
func (pg *Postgresql) IsPrimaryKey(column Column) bool {
111
	return strings.Contains(column.ConstraintType.String, "PRIMARY KEY")
112
}
113
114
// IsAutoIncrement checks if column is a serial column
115
func (pg *Postgresql) IsAutoIncrement(column Column) bool {
116
	return strings.Contains(column.DefaultValue.String, "nextval")
117
}
118
119
// GetStringDatatypes returns the string datatypes for the postgre database
120
func (pg *Postgresql) GetStringDatatypes() []string {
121
	return []string{
122
		"character varying",
123
		"varchar",
124
		"character",
125
		"char",
126
	}
127
}
128
129
// IsString returns true if colum is of type string for the postgre database
130
func (pg *Postgresql) IsString(column Column) bool {
131
	return pg.IsStringInSlice(column.DataType, pg.GetStringDatatypes())
132
}
133
134
// GetTextDatatypes returns the text datatypes for the postgre database
135
func (pg *Postgresql) GetTextDatatypes() []string {
136
	return []string{
137
		"text",
138
	}
139
}
140
141
// IsText returns true if colum is of type text for the postgre database
142
func (pg *Postgresql) IsText(column Column) bool {
143
	return pg.IsStringInSlice(column.DataType, pg.GetTextDatatypes())
144
}
145
146
// GetIntegerDatatypes returns the integer datatypes for the postgre database
147
func (pg *Postgresql) GetIntegerDatatypes() []string {
148
	return []string{
149
		"smallint",
150
		"integer",
151
		"bigint",
152
		"smallserial",
153
		"serial",
154
		"bigserial",
155
	}
156
}
157
158
// IsInteger returns true if colum is of type integer for the postgre database
159
func (pg *Postgresql) IsInteger(column Column) bool {
160
	return pg.IsStringInSlice(column.DataType, pg.GetIntegerDatatypes())
161
}
162
163
// GetFloatDatatypes returns the float datatypes for the postgre database
164
func (pg *Postgresql) GetFloatDatatypes() []string {
165
	return []string{
166
		"numeric",
167
		"decimal",
168
		"real",
169
		"double precision",
170
	}
171
}
172
173
// IsFloat returns true if colum is of type float for the postgre database
174
func (pg *Postgresql) IsFloat(column Column) bool {
175
	return pg.IsStringInSlice(column.DataType, pg.GetFloatDatatypes())
176
}
177
178
// GetTemporalDatatypes returns the temporal datatypes for the postgre database
179
func (pg *Postgresql) GetTemporalDatatypes() []string {
180
	return []string{
181
		"time",
182
		"timestamp",
183
		"time with time zone",
184
		"timestamp with time zone",
185
		"time without time zone",
186
		"timestamp without time zone",
187
		"date",
188
	}
189
}
190
191
// IsTemporal returns true if colum is of type temporal for the postgre database
192
func (pg *Postgresql) IsTemporal(column Column) bool {
193
	return pg.IsStringInSlice(column.DataType, pg.GetTemporalDatatypes())
194
}
195
196
// GetTemporalDriverDataType returns the time data type specific for the postgre database
197
func (pg *Postgresql) GetTemporalDriverDataType() string {
198
	return "pg.NullTime"
199
}
200