jet/generator/postgres-metadata/column_info.go

123 lines
2.8 KiB
Go
Raw Normal View History

2019-05-24 13:13:13 +02:00
package postgres_metadata
import (
"database/sql"
"fmt"
"github.com/serenize/snaker"
"strings"
)
type ColumnInfo struct {
Name string
IsNullable bool
DataType string
2019-04-03 19:21:46 +02:00
EnumName string
}
func (c ColumnInfo) SqlBuilderColumnType() string {
switch c.DataType {
case "boolean":
2019-06-08 16:34:15 +02:00
return "Bool"
case "smallint", "integer", "bigint":
2019-06-08 16:34:15 +02:00
return "Integer"
case "date":
2019-06-08 16:34:15 +02:00
return "Date"
case "timestamp without time zone":
2019-06-08 16:34:15 +02:00
return "Timestamp"
case "timestamp with time zone":
2019-06-08 16:34:15 +02:00
return "Timestampz"
case "time without time zone":
2019-06-08 16:34:15 +02:00
return "Time"
case "time with time zone":
2019-06-08 16:34:15 +02:00
return "Timez"
case "USER-DEFINED", "text", "character", "character varying", "bytea", "uuid",
"tsvector", "bit", "bit varying", "money", "json", "jsonb", "xml", "point", "interval", "line", "ARRAY":
2019-06-08 16:34:15 +02:00
return "String"
case "real", "numeric", "decimal", "double precision":
2019-06-08 16:34:15 +02:00
return "Float"
default:
fmt.Println("Unknown sql type: " + c.DataType + ", using string column instead for sql builder.")
2019-06-08 16:34:15 +02:00
return "String"
}
}
func (c ColumnInfo) GoBaseType() string {
2019-05-20 17:37:55 +02:00
switch c.DataType {
case "USER-DEFINED":
return snaker.SnakeToCamel(c.EnumName)
case "boolean":
return "bool"
case "smallint":
return "int16"
case "integer":
return "int32"
case "bigint":
return "int64"
case "date", "timestamp without time zone", "timestamp with time zone", "time with time zone", "time without time zone":
2019-05-20 17:37:55 +02:00
return "time.Time"
case "bytea":
return "[]byte"
case "text", "character", "character varying", "tsvector", "bit", "bit varying", "money", "json", "jsonb",
"xml", "point", "interval", "line", "ARRAY":
2019-05-20 17:37:55 +02:00
return "string"
case "real":
return "float32"
case "numeric", "decimal", "double precision":
2019-05-20 17:37:55 +02:00
return "float64"
case "uuid":
return "uuid.UUID"
default:
fmt.Println("Unknown sql type: " + c.DataType + ", " + c.EnumName + ", using string instead for model type.")
2019-05-20 17:37:55 +02:00
return "string"
}
}
func (c ColumnInfo) GoModelType() string {
2019-05-24 13:13:13 +02:00
typeStr := c.GoBaseType()
if c.IsNullable && !strings.HasPrefix(typeStr, "[]") {
2019-05-24 13:13:13 +02:00
return "*" + typeStr
}
2019-05-20 17:37:55 +02:00
2019-05-24 13:13:13 +02:00
return typeStr
}
2019-05-24 13:13:13 +02:00
func getColumnInfos(db *sql.DB, dbName, schemaName, tableName string) ([]ColumnInfo, error) {
query := `
2019-04-03 19:21:46 +02:00
SELECT column_name, is_nullable, data_type, udt_name
FROM information_schema.columns
2019-05-24 13:13:13 +02:00
where table_catalog = $1 and table_schema = $2 and table_name = $3
order by ordinal_position;`
2019-05-24 13:13:13 +02:00
rows, err := db.Query(query, dbName, schemaName, tableName)
if err != nil {
return nil, err
}
defer rows.Close()
ret := []ColumnInfo{}
for rows.Next() {
columnInfo := ColumnInfo{}
var isNullable string
2019-04-03 19:21:46 +02:00
err := rows.Scan(&columnInfo.Name, &isNullable, &columnInfo.DataType, &columnInfo.EnumName)
columnInfo.IsNullable = isNullable == "YES"
if err != nil {
return nil, err
}
ret = append(ret, columnInfo)
}
err = rows.Err()
if err != nil {
return nil, err
}
return ret, nil
}