Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@ require (

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you run go mod tidy and go mod vendor to include the vendor changes?

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/denisenkom/go-mssqldb v0.12.3 // indirect
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe // indirect
github.com/golang-sql/sqlexp v0.1.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/stretchr/objx v0.4.0 // indirect
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
32 changes: 32 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
github.com/Azure/azure-sdk-for-go/sdk/azcore v0.19.0/go.mod h1:h6H6c8enJmmocHUbLiiGY6sx7f9i+X3m1CHdd5c6Rdw=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v0.11.0/go.mod h1:HcM1YX14R7CJcghJGOYCgdezslRSVzqwLf/q+4Y2r/0=
github.com/Azure/azure-sdk-for-go/sdk/internal v0.7.0/go.mod h1:yqy467j36fJxcRV2TzfVZ1pCb5vxm4BtZPUdYWe/Xo8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/denisenkom/go-mssqldb v0.12.3 h1:pBSGx9Tq67pBOTLmxNuirNTeB8Vjmf886Kx+8Y+8shw=
github.com/denisenkom/go-mssqldb v0.12.3/go.mod h1:k0mtMFOnU+AihqFxPMiF05rtiDrorD1Vrm1KEz5hxDo=
github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ=
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY=
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A=
github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI=
github.com/iancoleman/strcase v0.2.0 h1:05I4QRnGpI0m37iZQRuskXh+w77mr6Z41lwQzuHLwW0=
github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g=
Expand All @@ -13,18 +23,40 @@ github.com/lib/pq v1.10.6/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/mattn/go-sqlite3 v1.14.14 h1:qZgc/Rwetq+MtyE18WhzjokPD93dNqLGNT3QJuLvBGw=
github.com/mattn/go-sqlite3 v1.14.14/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8=
github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d h1:sK3txAijHtOK88l68nt020reeT1ZdKLIYetKl95FzVY=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
3 changes: 3 additions & 0 deletions pkg/database/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ var (
settings.DBTypePostgresql: "postgres",
settings.DBTypeMySQL: "mysql",
settings.DBTypeSQLite: "sqlite3",
settings.DBTypeSQLServer: "sqlserver",
}
)

Expand Down Expand Up @@ -91,6 +92,8 @@ func New(s *settings.Settings) Database {
db = NewSQLite(s)
case settings.DBTypeMySQL:
db = NewMySQL(s)
case settings.DBTypeSQLServer:
db = NewSqlserver(s)
case settings.DBTypePostgresql:
fallthrough
default:
Expand Down
208 changes: 208 additions & 0 deletions pkg/database/sqlserver.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
package database

import (
"fmt"
"strings"

"github.com/fraenky8/tables-to-go/pkg/settings"

// sqlserver database driver
_ "github.com/denisenkom/go-mssqldb"
)

// Sqlserver implements the Database interface with help of GeneralDatabase.
type Sqlserver struct {
Comment on lines +13 to +14

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

*GeneralDatabase

defaultUserName string
}

// NewSqlserver creates a new Sqlserver database.
func NewSqlserver(s *settings.Settings) *Sqlserver {
return &Sqlserver{
GeneralDatabase: &GeneralDatabase{
Settings: s,
driver: dbTypeToDriverMap[s.DbType],
},
defaultUserName: "sa",
}
}

// Connect connects to the database by the given data source name (dsn) of the
// concrete database.
func (ss *Sqlserver) Connect() error {
return ss.GeneralDatabase.Connect(ss.DSN())
}

// DSN creates the DSN String to connect to this database.
func (ss *Sqlserver) DSN() string {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets add a unit test for that? I see the other database implementation have one, just for the sake of consistency?

user := ss.defaultUserName
if ss.Settings.User != "" {
user = ss.Settings.User
}
return fmt.Sprintf("server=%s;port=%s;user=%s;database=%s;password=%s",

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a way to connect via a socket to SQLServer? I see MySQL and PG have this option. Can you check and add it here as well?

ss.Settings.Host, ss.Settings.Port, user, ss.Settings.DbName, ss.Settings.Pswd)
}

// GetTables gets all tables for a given schema by name.
func (ss *Sqlserver) GetTables() (tables []*Table, err error) {

err = ss.Select(&tables, `
SELECT
table_name
FROM
INFORMATION_SCHEMA.TABLES
WHERE
TABLE_SCHEMA = @p1
ORDER BY TABLE_NAME
`, ss.Schema)

if ss.Verbose {
if err != nil {
fmt.Println("> Error at GetTables()")
fmt.Printf("> schema: %q\r\n", ss.Schema)
}
}

return tables, err
}

// PrepareGetColumnsOfTableStmt prepares the statement for retrieving the
// columns of a specific table for a given database.
func (ss *Sqlserver) PrepareGetColumnsOfTableStmt() (err error) {

ss.GetColumnsOfTableStmt, err = ss.Preparex(`

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to be double sure, since I don't have any experience with SQLServer - this statement is the same as for PG except the placeholder format?

SELECT
ic.ordinal_position,
ic.column_name,
ic.data_type,
ic.column_default,
ic.is_nullable,
ic.character_maximum_length,
ic.numeric_precision,
itc.constraint_name,
itc.constraint_type
FROM information_schema.columns AS ic
LEFT JOIN information_schema.key_column_usage AS ikcu ON ic.table_name = ikcu.table_name
AND ic.table_schema = ikcu.table_schema
AND ic.column_name = ikcu.column_name
LEFT JOIN information_schema.table_constraints AS itc ON ic.table_name = itc.table_name
AND ic.table_schema = itc.table_schema
AND ikcu.constraint_name = itc.constraint_name
WHERE ic.table_name = @p1
AND ic.table_schema = @p2
ORDER BY ic.ordinal_position
`)

return err
}

// GetColumnsOfTable executes the statement for retrieving the columns of a
// specific table in a given schema.
func (ss *Sqlserver) GetColumnsOfTable(table *Table) (err error) {

err = ss.GetColumnsOfTableStmt.Select(&table.Columns, table.Name, ss.Schema)

if ss.Verbose {
if err != nil {
fmt.Printf("> Error at GetColumnsOfTable(%v)\r\n", table.Name)
fmt.Printf("> schema: %q\r\n", ss.Schema)
}
}

return err
}

// IsPrimaryKey checks if the column belongs to the primary key.
func (ss *Sqlserver) IsPrimaryKey(column Column) bool {
return strings.Contains(column.ConstraintType.String, "PRIMARY KEY")
}

// IsAutoIncrement checks if the column is an auto_increment column.
func (ss *Sqlserver) IsAutoIncrement(column Column) bool {
return strings.Contains(column.DefaultValue.String, "IDENTITY")
}

// GetStringDatatypes returns the string datatypes for the Sqlserver database.
// https://learn.microsoft.com/en-us/sql/t-sql/data-types/data-types-transact-sql?view=sql-server-ver16#character-strings
func (ss *Sqlserver) GetStringDatatypes() []string {
return []string{
"char",
"varchar",
"nchar",
"nvarchar",
}
}

// IsString returns true if colum is of type string for the Sqlserver database.
func (ss *Sqlserver) IsString(column Column) bool {
return isStringInSlice(column.DataType, ss.GetStringDatatypes())
}

// GetTextDatatypes returns the text datatypes for the Sqlserver database.
// https://learn.microsoft.com/en-us/sql/t-sql/data-types/data-types-transact-sql?view=sql-server-ver16#character-strings
func (ss *Sqlserver) GetTextDatatypes() []string {
return []string{
"text",
"ntext",
"binary",
"varbinary",
"image",
}
}

// IsText returns true if colum is of type text for the Sqlserver database.
func (ss *Sqlserver) IsText(column Column) bool {
return isStringInSlice(column.DataType, ss.GetTextDatatypes())
}

// GetIntegerDatatypes returns the integer datatypes for the Sqlserver database.
// https://learn.microsoft.com/en-us/sql/t-sql/data-types/data-types-transact-sql?view=sql-server-ver16#exact-numerics
func (ss *Sqlserver) GetIntegerDatatypes() []string {
return []string{
"bigint",
"bit",
"smallint",
"int",
"tinyint",
}
}

// IsInteger returns true if colum is of type integer for the Sqlserver database.
func (ss *Sqlserver) IsInteger(column Column) bool {
return isStringInSlice(column.DataType, ss.GetIntegerDatatypes())
}

// GetFloatDatatypes returns the float datatypes for the Sqlserver database.
// https://learn.microsoft.com/en-us/sql/t-sql/data-types/data-types-transact-sql?view=sql-server-ver16#exact-numerics
func (ss *Sqlserver) GetFloatDatatypes() []string {
return []string{
"numeric",
"decimal",
"float",
"real",
}
}

// IsFloat returns true if colum is of type float for the Sqlserver database.
func (ss *Sqlserver) IsFloat(column Column) bool {
return isStringInSlice(column.DataType, ss.GetFloatDatatypes())
}

// GetTemporalDatatypes returns the temporal datatypes for the Sqlserver database.
// https://learn.microsoft.com/en-us/sql/t-sql/data-types/data-types-transact-sql?view=sql-server-ver16#date-and-time
func (ss *Sqlserver) GetTemporalDatatypes() []string {
return []string{
"date",
"datetimeoffset",
"datetime2",
"smalldatetime",
"datetime",
"time",
}
}

// IsTemporal returns true if colum is of type temporal for the Sqlserver database.
func (ss *Sqlserver) IsTemporal(column Column) bool {
return isStringInSlice(column.DataType, ss.GetTemporalDatatypes())
}
3 changes: 3 additions & 0 deletions pkg/settings/settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const (
DBTypePostgresql DBType = "pg"
DBTypeMySQL DBType = "mysql"
DBTypeSQLite DBType = "sqlite3"
DBTypeSQLServer DBType = "sqlserver"
)

// Set sets the datatype for the custom type for the flag package.
Expand Down Expand Up @@ -122,6 +123,7 @@ var (
DBTypePostgresql: true,
DBTypeMySQL: true,
DBTypeSQLite: true,
DBTypeSQLServer: true,
}

// supportedOutputFormats represents the supported output formats
Expand All @@ -135,6 +137,7 @@ var (
DBTypePostgresql: "5432",
DBTypeMySQL: "3306",
DBTypeSQLite: "",
DBTypeSQLServer: "1433",
}

// supportedNullTypes represents the supported types of NULL types
Expand Down
16 changes: 16 additions & 0 deletions vendor/modules.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,22 @@
# github.com/davecgh/go-spew v1.1.1
## explicit
github.com/davecgh/go-spew/spew
# github.com/denisenkom/go-mssqldb v0.12.3
## explicit; go 1.13
github.com/denisenkom/go-mssqldb
github.com/denisenkom/go-mssqldb/internal/cp
github.com/denisenkom/go-mssqldb/internal/decimal
github.com/denisenkom/go-mssqldb/internal/querytext
github.com/denisenkom/go-mssqldb/msdsn
# github.com/go-sql-driver/mysql v1.6.0
## explicit; go 1.10
github.com/go-sql-driver/mysql
# github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe
## explicit
github.com/golang-sql/civil
# github.com/golang-sql/sqlexp v0.1.0
## explicit; go 1.16
github.com/golang-sql/sqlexp
# github.com/iancoleman/strcase v0.2.0
## explicit; go 1.16
github.com/iancoleman/strcase
Expand All @@ -29,6 +42,9 @@ github.com/stretchr/objx
## explicit; go 1.13
github.com/stretchr/testify/assert
github.com/stretchr/testify/mock
# golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d
## explicit; go 1.17
golang.org/x/crypto/md4
# golang.org/x/text v0.3.7
## explicit; go 1.17
golang.org/x/text/cases
Expand Down