Skip to content

Commit

Permalink
Add NOT NULL constraint (#46)
Browse files Browse the repository at this point in the history
* Add not null constraint (#42)

* Fix spacing between AttributeKey and Description
  • Loading branch information
lnschroeder authored Aug 6, 2023
1 parent 65f2af8 commit 4ff9592
Show file tree
Hide file tree
Showing 12 changed files with 47 additions and 31 deletions.
2 changes: 1 addition & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ func init() {
rootCmd.Flags().StringP(config.SchemaKey, "s", "", "schema that should be used")
rootCmd.Flags().StringP(config.OutputFileNameKey, "o", "result.mmd", "output file name")
rootCmd.Flags().String(config.SchemaPrefixSeparator, ".", "the separator that should be used between schema and table name")
rootCmd.Flags().StringSlice(config.ShowDescriptionsKey, []string{""}, "show 'enumValues' and/or 'columnComments' in the description column")
rootCmd.Flags().StringSlice(config.ShowDescriptionsKey, []string{""}, "show 'notNull', 'enumValues' and/or 'columnComments' in the description column")
rootCmd.Flags().StringSlice(config.SelectedTablesKey, []string{""}, "tables to include")

bindFlagToViper(config.ShowAllConstraintsKey)
Expand Down
3 changes: 2 additions & 1 deletion config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ omitAttributeKeys: true
showDescriptions:
- enumValues
- columnComments
- notNull
useAllSchemas: true
showSchemaPrefix: true
schemaPrefixSeparator: "_"
Expand Down Expand Up @@ -58,7 +59,7 @@ connectionStringSuggestions:
assert.True(t, config.Debug())
assert.True(t, config.OmitConstraintLabels())
assert.True(t, config.OmitAttributeKeys())
assert.ElementsMatch(t, []string{"enumValues", "columnComments"}, config.ShowDescriptions())
assert.ElementsMatch(t, []string{"notNull", "enumValues", "columnComments"}, config.ShowDescriptions())
assert.True(t, config.UseAllSchemas())
assert.True(t, config.ShowSchemaPrefix())
assert.Equal(t, "_", config.SchemaPrefixSeparator())
Expand Down
45 changes: 24 additions & 21 deletions database/database_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ import (
)

type columnTestResult struct {
Name string
isPrimary bool
isForeign bool
Name string
isPrimary bool
isForeign bool
isNullable bool
}

type connectionParameter struct {
Expand Down Expand Up @@ -135,33 +136,34 @@ func TestDatabaseIntegrations(t *testing.T) {
expectedColumns []columnTestResult
}{
{tableName: "article", expectedColumns: []columnTestResult{
{Name: "id", isPrimary: true, isForeign: false},
{Name: "title", isPrimary: false, isForeign: false},
{Name: "id", isPrimary: true, isForeign: false, isNullable: false},
{Name: "title", isPrimary: false, isForeign: false, isNullable: false},
{Name: "subtitle", isPrimary: false, isForeign: false, isNullable: true},
}},
{tableName: "article_detail", expectedColumns: []columnTestResult{
{Name: "id", isPrimary: true, isForeign: true},
{Name: "created_at", isPrimary: false, isForeign: false},
{Name: "id", isPrimary: true, isForeign: true, isNullable: false},
{Name: "created_at", isPrimary: false, isForeign: false, isNullable: false},
}},
{tableName: "article_comment", expectedColumns: []columnTestResult{
{Name: "id", isPrimary: true, isForeign: false},
{Name: "article_id", isPrimary: false, isForeign: true},
{Name: "comment", isPrimary: false, isForeign: false},
{Name: "id", isPrimary: true, isForeign: false, isNullable: false},
{Name: "article_id", isPrimary: false, isForeign: true, isNullable: false},
{Name: "comment", isPrimary: false, isForeign: false, isNullable: false},
}},
{tableName: "label", expectedColumns: []columnTestResult{
{Name: "id", isPrimary: true, isForeign: false},
{Name: "label", isPrimary: false, isForeign: false},
{Name: "id", isPrimary: true, isForeign: false, isNullable: false},
{Name: "label", isPrimary: false, isForeign: false, isNullable: false},
}},
{tableName: "article_label", expectedColumns: []columnTestResult{
{Name: "article_id", isPrimary: true, isForeign: true},
{Name: "label_id", isPrimary: true, isForeign: true},
{Name: "article_id", isPrimary: true, isForeign: true, isNullable: false},
{Name: "label_id", isPrimary: true, isForeign: true, isNullable: false},
}},
{tableName: "test_1_a", expectedColumns: []columnTestResult{
{Name: "id", isPrimary: true, isForeign: false},
{Name: "xid", isPrimary: true, isForeign: false},
{Name: "id", isPrimary: true, isForeign: false, isNullable: false},
{Name: "xid", isPrimary: true, isForeign: false, isNullable: false},
}},
{tableName: "test_1_b", expectedColumns: []columnTestResult{
{Name: "aid", isPrimary: true, isForeign: true},
{Name: "bid", isPrimary: true, isForeign: true},
{Name: "aid", isPrimary: true, isForeign: true, isNullable: false},
{Name: "bid", isPrimary: true, isForeign: true, isNullable: false},
}},
}

Expand All @@ -177,9 +179,10 @@ func TestDatabaseIntegrations(t *testing.T) {
// Assert
for _, column := range columns {
columnResult = append(columnResult, columnTestResult{
Name: column.Name,
isPrimary: column.IsPrimary,
isForeign: column.IsForeign,
Name: column.Name,
isPrimary: column.IsPrimary,
isForeign: column.IsForeign,
isNullable: column.IsNullable,
})
}

Expand Down
3 changes: 2 additions & 1 deletion database/mssql.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ func (c *mssqlConnector) GetColumns(tableName TableDetail) ([]ColumnResult, erro
where cu.column_name = c.column_name
and cu.table_name = c.table_name
and tc.constraint_type = 'FOREIGN KEY') as is_foreign,
case when c.is_nullable = 'YES' then 1 else 0 end as is_nullable,
(select ISNULL(ep.value, '') from sys.tables t
inner join sys.columns col on col.object_id = t.object_id and col.name = c.column_name
left join sys.extended_properties ep on ep.major_id = t.object_id and ep.minor_id = col.column_id
Expand All @@ -117,7 +118,7 @@ func (c *mssqlConnector) GetColumns(tableName TableDetail) ([]ColumnResult, erro
var columns []ColumnResult
for rows.Next() {
var column ColumnResult
if err = rows.Scan(&column.Name, &column.DataType, &column.IsPrimary, &column.IsForeign, &column.Comment); err != nil {
if err = rows.Scan(&column.Name, &column.DataType, &column.IsPrimary, &column.IsForeign, &column.IsNullable, &column.Comment); err != nil {
return nil, err
}

Expand Down
3 changes: 2 additions & 1 deletion database/mysql.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ func (c *mySqlConnector) GetColumns(tableName TableDetail) ([]ColumnResult, erro
where cu.column_name = c.column_name
and cu.table_name = c.table_name
and tc.constraint_type = 'FOREIGN KEY') as is_foreign,
IF(c.is_nullable = 'YES', 1, 0) as is_nullable,
case when c.data_type = 'enum' then REPLACE(REPLACE(REPLACE(REPLACE(c.column_type, 'enum', ''), '\'', ''), '(', ''), ')', '') else '' end as enum_values,
c.column_comment as comment
from information_schema.columns c
Expand All @@ -112,7 +113,7 @@ func (c *mySqlConnector) GetColumns(tableName TableDetail) ([]ColumnResult, erro
var columns []ColumnResult
for rows.Next() {
var column ColumnResult
if err = rows.Scan(&column.Name, &column.DataType, &column.IsPrimary, &column.IsForeign, &column.EnumValues, &column.Comment); err != nil {
if err = rows.Scan(&column.Name, &column.DataType, &column.IsPrimary, &column.IsForeign, &column.IsNullable, &column.EnumValues, &column.Comment); err != nil {
return nil, err
}

Expand Down
3 changes: 2 additions & 1 deletion database/postgres.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ func (c *postgresConnector) GetColumns(tableName TableDetail) ([]ColumnResult, e
where cu.column_name = c.column_name
and cu.table_name = c.table_name
and tc.constraint_type = 'FOREIGN KEY') as is_foreign,
bool_or(c.is_nullable = 'YES') as is_not_null,
coalesce(string_agg(enumlabel, ',' order by enumsortorder), '') as enum_values,
coalesce(pd.description, '') as comment
from information_schema.columns c
Expand All @@ -125,7 +126,7 @@ func (c *postgresConnector) GetColumns(tableName TableDetail) ([]ColumnResult, e
var columns []ColumnResult
for rows.Next() {
var column ColumnResult
if err = rows.Scan(&column.Name, &column.DataType, &column.IsPrimary, &column.IsForeign, &column.EnumValues, &column.Comment); err != nil {
if err = rows.Scan(&column.Name, &column.DataType, &column.IsPrimary, &column.IsForeign, &column.IsNullable, &column.EnumValues, &column.Comment); err != nil {
return nil, err
}

Expand Down
1 change: 1 addition & 0 deletions database/result.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ type ColumnResult struct {
DataType string
IsPrimary bool
IsForeign bool
IsNullable bool
EnumValues string
Comment string
}
Expand Down
4 changes: 4 additions & 0 deletions diagram/diagram_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ func getDescription(options []string, column database.ColumnResult) string {
var description []string
for _, option := range options {
switch option {
case "notNull":
if !column.IsNullable {
description = append(description, "{NOT_NULL}")
}
case "enumValues":
if column.EnumValues != "" {
description = append(description, "<"+column.EnumValues+">")
Expand Down
2 changes: 1 addition & 1 deletion diagram/erd_template.gommd
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ erDiagram
{{- range .Tables}}
{{.Name}} {
{{- range .Columns}}
{{.DataType}} {{.Name}} {{.AttributeKey}} {{- if .Description}}"{{.Description}}"{{end -}}
{{.DataType}} {{.Name}} {{- if .AttributeKey}} {{.AttributeKey}}{{end -}} {{- if .Description}} "{{.Description}}"{{end -}}
{{- end}}
}
{{end -}}
Expand Down
1 change: 1 addition & 0 deletions exampleRunConfig.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,6 @@ omitAttributeKeys: false
showDescriptions:
- enumValues
- columnComments
- notNull
showSchemaPrefix: true
schemaPrefixSeparator: "_"
8 changes: 5 additions & 3 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ for your operating system. To be able to use it globally on your system, add the
* Show primary and foreign keys
* Show enum values of enum column
* Show column comments
* Show NOT NULL constraints

## Why would I need it / Why should I care?

Expand Down Expand Up @@ -81,7 +82,7 @@ via `mermerd -h`
--schemaPrefixSeparator string the separator that should be used between schema and table name (default ".")
--selectedTables strings tables to include
--showAllConstraints show all constraints, even though the table of the resulting constraint was not selected
--showDescriptions strings show 'enumValues' and/or 'columnComments' in the description column
--showDescriptions strings show 'notNull', enumValues' and/or 'columnComments' in the description column
--showSchemaPrefix show schema prefix in table name
--useAllSchemas use all available schemas
--useAllTables use all available tables
Expand Down Expand Up @@ -148,6 +149,7 @@ omitAttributeKeys: true
showDescriptions:
- enumValues
- columnComments
- notNull
showSchemaPrefix: true
schemaPrefixSeparator: "_"
```
Expand All @@ -173,8 +175,8 @@ mermerd -c "postgresql://user:password@localhost:5432/yourDb" -s public --useAll
# same as previous one, but use a list of tables without interaction
mermerd -c "postgresql://user:password@localhost:5432/yourDb" -s public --selectedTables article,article_label
# show enum values and column comments in the description column
mermerd -c "postgresql://user:password@localhost:5432/yourDb" -s public --useAllTables --showDescriptions enumValues,columnComments
# show enum values, column comments and notNull in the description column
mermerd -c "postgresql://user:password@localhost:5432/yourDb" -s public --useAllTables --showDescriptions enumValues,columnComments,notNull
```

## Connection strings
Expand Down
3 changes: 2 additions & 1 deletion test/db-table-setup.sql
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
create table article
(
id int not null primary key,
title varchar(255) not null
title varchar(255) not null,
subtitle varchar(255)
);

create table article_detail
Expand Down

0 comments on commit 4ff9592

Please sign in to comment.