Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: export presence #328

Merged
merged 7 commits into from
Nov 21, 2024
Merged
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Types of changes
- `Added` possibility to filter columns via `select` property in ingress descriptors
- `Added` commands `set-parent-select` and `set-child-select` to `lino id`
- `Added` `import: no` option for columns in `tables.yaml` configuration
- `Added` `export: presence` option for columns in `tables.yaml` configuration

## [3.0.2]

Expand Down
2 changes: 1 addition & 1 deletion internal/infra/analyse/sql_datasource.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ func (ds *SQLDataSource) Open() error {
// Get WHERE Clause query
sqlWhere, values := commonsql.GetWhereSQLAndValues(map[string]any{}, ds.where, ds.dialect)

sql := ds.dialect.Select(ds.table, ds.schema, sqlWhere, false, ds.column)
sql := ds.dialect.Select(ds.table, ds.schema, sqlWhere, false, commonsql.ColumnExportDefinition{Name: ds.column})

// If log level is more than debug level, this function will log all SQL Query
commonsql.LogSQLQuery(sql, values, ds.dialect)
Expand Down
17 changes: 15 additions & 2 deletions internal/infra/commonsql/dialect.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,19 @@ import (
"github.com/rs/zerolog/log"
)

type ColumnExportDefinition struct {
Name string
OnlyPresence bool
}

func Names(columns []ColumnExportDefinition) []string {
us := make([]string, len(columns))
for i := range columns {
us[i] = columns[i].Name
}
return us
}

type Dialect interface {
// Placeholder format variable in query
Placeholder(int) string
Expand All @@ -35,9 +48,9 @@ type Dialect interface {
// Where clause
Where(string) string
// Select clause
Select(tableName string, schemaName string, where string, distinct bool, columns ...string) string
Select(tableName string, schemaName string, where string, distinct bool, columns ...ColumnExportDefinition) string
// SelectLimit clause
SelectLimit(tableName string, schemaName string, where string, distinct bool, limit uint, columns ...string) string
SelectLimit(tableName string, schemaName string, where string, distinct bool, limit uint, columns ...ColumnExportDefinition) string
// Quote identifier
Quote(id string) string

Expand Down
32 changes: 22 additions & 10 deletions internal/infra/commonsql/dialect_db2.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func (db2 Db2Dialect) Where(where string) string {
}

// Select clause
func (db2 Db2Dialect) Select(tableName string, schemaName string, where string, distinct bool, columns ...string) string {
func (db2 Db2Dialect) Select(tableName string, schemaName string, where string, distinct bool, columns ...ColumnExportDefinition) string {
var query strings.Builder

query.WriteString("SELECT ")
Expand All @@ -62,11 +62,15 @@ func (db2 Db2Dialect) Select(tableName string, schemaName string, where string,
query.WriteString("DISTINCT ")
}

if len(columns) > 0 {
for i := range columns {
columns[i] = db2.Quote(columns[i])
if names := Names(columns); len(names) > 0 {
for i := range names {
if columns[i].OnlyPresence {
names[i] = db2.selectPresence(names[i])
} else {
names[i] = db2.Quote(names[i])
}
}
query.WriteString(strings.Join(columns, ", "))
query.WriteString(strings.Join(names, ", "))
} else {
query.WriteRune('*')
}
Expand All @@ -80,7 +84,7 @@ func (db2 Db2Dialect) Select(tableName string, schemaName string, where string,
}

// SelectLimit clause
func (db2 Db2Dialect) SelectLimit(tableName string, schemaName string, where string, distinct bool, limit uint, columns ...string) string {
func (db2 Db2Dialect) SelectLimit(tableName string, schemaName string, where string, distinct bool, limit uint, columns ...ColumnExportDefinition) string {
var query strings.Builder

query.WriteString("SELECT ")
Expand All @@ -89,11 +93,15 @@ func (db2 Db2Dialect) SelectLimit(tableName string, schemaName string, where str
query.WriteString("DISTINCT ")
}

if len(columns) > 0 {
for i := range columns {
columns[i] = db2.Quote(columns[i])
if names := Names(columns); len(names) > 0 {
for i := range names {
if columns[i].OnlyPresence {
names[i] = db2.selectPresence(names[i])
} else {
names[i] = db2.Quote(names[i])
}
}
query.WriteString(strings.Join(columns, ", "))
query.WriteString(strings.Join(names, ", "))
} else {
query.WriteRune('*')
}
Expand Down Expand Up @@ -123,3 +131,7 @@ func (db2 Db2Dialect) Quote(id string) string {
func (db2 Db2Dialect) CreateSelect(sel string, where string, limit string, columns string, from string) string {
return fmt.Sprintf("%s %s %s %s %s", sel, columns, from, where, limit)
}

func (db2 Db2Dialect) selectPresence(column string) string {
return fmt.Sprintf("CASE WHEN %s IS NOT NULL THEN 1 ELSE NULL END AS %s", db2.Quote(column), db2.Quote(column))
}
32 changes: 22 additions & 10 deletions internal/infra/commonsql/dialect_mariadb.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func (pd MariadbDialect) Where(where string) string {
}

// Select clause
func (pd MariadbDialect) Select(tableName string, schemaName string, where string, distinct bool, columns ...string) string {
func (pd MariadbDialect) Select(tableName string, schemaName string, where string, distinct bool, columns ...ColumnExportDefinition) string {
var query strings.Builder

query.WriteString("SELECT ")
Expand All @@ -62,11 +62,15 @@ func (pd MariadbDialect) Select(tableName string, schemaName string, where strin
query.WriteString("DISTINCT ")
}

if len(columns) > 0 {
for i := range columns {
columns[i] = pd.Quote(columns[i])
if names := Names(columns); len(names) > 0 {
for i := range names {
if columns[i].OnlyPresence {
names[i] = pd.selectPresence(names[i])
} else {
names[i] = pd.Quote(names[i])
}
}
query.WriteString(strings.Join(columns, ", "))
query.WriteString(strings.Join(names, ", "))
} else {
query.WriteRune('*')
}
Expand All @@ -80,7 +84,7 @@ func (pd MariadbDialect) Select(tableName string, schemaName string, where strin
}

// SelectLimit clause
func (pd MariadbDialect) SelectLimit(tableName string, schemaName string, where string, distinct bool, limit uint, columns ...string) string {
func (pd MariadbDialect) SelectLimit(tableName string, schemaName string, where string, distinct bool, limit uint, columns ...ColumnExportDefinition) string {
var query strings.Builder

query.WriteString("SELECT ")
Expand All @@ -89,11 +93,15 @@ func (pd MariadbDialect) SelectLimit(tableName string, schemaName string, where
query.WriteString("DISTINCT ")
}

if len(columns) > 0 {
for i := range columns {
columns[i] = pd.Quote(columns[i])
if names := Names(columns); len(names) > 0 {
for i := range names {
if columns[i].OnlyPresence {
names[i] = pd.selectPresence(names[i])
} else {
names[i] = pd.Quote(names[i])
}
}
query.WriteString(strings.Join(columns, ", "))
query.WriteString(strings.Join(names, ", "))
} else {
query.WriteRune('*')
}
Expand Down Expand Up @@ -123,3 +131,7 @@ func (sd MariadbDialect) Quote(id string) string {
func (sd MariadbDialect) CreateSelect(sel string, where string, limit string, columns string, from string) string {
return fmt.Sprintf("%s %s %s %s %s", sel, columns, from, where, limit)
}

func (sd MariadbDialect) selectPresence(column string) string {
return fmt.Sprintf("CASE WHEN %s IS NOT NULL THEN 'TRUE' ELSE NULL END AS %s", sd.Quote(column), sd.Quote(column))
}
32 changes: 22 additions & 10 deletions internal/infra/commonsql/dialect_oracle.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func (od OracleDialect) Where(where string) string {
}

// Select clause
func (od OracleDialect) Select(tableName string, schemaName string, where string, distinct bool, columns ...string) string {
func (od OracleDialect) Select(tableName string, schemaName string, where string, distinct bool, columns ...ColumnExportDefinition) string {
var query strings.Builder

query.WriteString("SELECT ")
Expand All @@ -62,11 +62,15 @@ func (od OracleDialect) Select(tableName string, schemaName string, where string
query.WriteString("DISTINCT ")
}

if len(columns) > 0 {
for i := range columns {
columns[i] = od.Quote(columns[i])
if names := Names(columns); len(names) > 0 {
for i := range names {
if columns[i].OnlyPresence {
names[i] = od.selectPresence(names[i])
} else {
names[i] = od.Quote(names[i])
}
}
query.WriteString(strings.Join(columns, ", "))
query.WriteString(strings.Join(names, ", "))
} else {
query.WriteRune('*')
}
Expand All @@ -80,7 +84,7 @@ func (od OracleDialect) Select(tableName string, schemaName string, where string
}

// SelectLimit clause
func (od OracleDialect) SelectLimit(tableName string, schemaName string, where string, distinct bool, limit uint, columns ...string) string {
func (od OracleDialect) SelectLimit(tableName string, schemaName string, where string, distinct bool, limit uint, columns ...ColumnExportDefinition) string {
var query strings.Builder

query.WriteString("SELECT ")
Expand All @@ -89,11 +93,15 @@ func (od OracleDialect) SelectLimit(tableName string, schemaName string, where s
query.WriteString("DISTINCT ")
}

if len(columns) > 0 {
for i := range columns {
columns[i] = od.Quote(columns[i])
if names := Names(columns); len(names) > 0 {
for i := range names {
if columns[i].OnlyPresence {
names[i] = od.selectPresence(names[i])
} else {
names[i] = od.Quote(names[i])
}
}
query.WriteString(strings.Join(columns, ", "))
query.WriteString(strings.Join(names, ", "))
} else {
query.WriteRune('*')
}
Expand Down Expand Up @@ -123,3 +131,7 @@ func (od OracleDialect) Quote(id string) string {
func (od OracleDialect) CreateSelect(sel string, where string, limit string, columns string, from string) string {
return fmt.Sprintf("%s %s %s %s %s", sel, columns, from, where, limit)
}

func (od OracleDialect) selectPresence(column string) string {
return fmt.Sprintf("CASE WHEN %s IS NOT NULL THEN 'TRUE' ELSE NULL END AS %s", od.Quote(column), od.Quote(column))
}
30 changes: 21 additions & 9 deletions internal/infra/commonsql/dialect_postgres.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func (pgd PostgresDialect) Where(where string) string {
}

// Select clause
func (pgd PostgresDialect) Select(tableName string, schemaName string, where string, distinct bool, columns ...string) string {
func (pgd PostgresDialect) Select(tableName string, schemaName string, where string, distinct bool, columns ...ColumnExportDefinition) string {
var query strings.Builder

query.WriteString("SELECT ")
Expand All @@ -62,11 +62,15 @@ func (pgd PostgresDialect) Select(tableName string, schemaName string, where str
query.WriteString("DISTINCT ")
}

if len(columns) > 0 {
if names := Names(columns); len(names) > 0 {
for i := range columns {
columns[i] = pgd.Quote(columns[i])
if columns[i].OnlyPresence {
names[i] = pgd.selectPresence(names[i])
} else {
names[i] = pgd.Quote(names[i])
}
}
query.WriteString(strings.Join(columns, ", "))
query.WriteString(strings.Join(names, ", "))
} else {
query.WriteRune('*')
}
Expand All @@ -80,7 +84,7 @@ func (pgd PostgresDialect) Select(tableName string, schemaName string, where str
}

// SelectLimit clause
func (pgd PostgresDialect) SelectLimit(tableName string, schemaName string, where string, distinct bool, limit uint, columns ...string) string {
func (pgd PostgresDialect) SelectLimit(tableName string, schemaName string, where string, distinct bool, limit uint, columns ...ColumnExportDefinition) string {
var query strings.Builder

query.WriteString("SELECT ")
Expand All @@ -89,11 +93,15 @@ func (pgd PostgresDialect) SelectLimit(tableName string, schemaName string, wher
query.WriteString("DISTINCT ")
}

if len(columns) > 0 {
for i := range columns {
columns[i] = pgd.Quote(columns[i])
if names := Names(columns); len(names) > 0 {
for i := range names {
if columns[i].OnlyPresence {
names[i] = pgd.selectPresence(names[i])
} else {
names[i] = pgd.Quote(names[i])
}
}
query.WriteString(strings.Join(columns, ", "))
query.WriteString(strings.Join(names, ", "))
} else {
query.WriteRune('*')
}
Expand Down Expand Up @@ -123,3 +131,7 @@ func (pgd PostgresDialect) Quote(id string) string {
func (pgd PostgresDialect) CreateSelect(sel string, where string, limit string, columns string, from string) string {
return fmt.Sprintf("%s %s %s %s %s", sel, columns, from, where, limit)
}

func (pgd PostgresDialect) selectPresence(column string) string {
return fmt.Sprintf("CASE WHEN (%s IS NOT NULL) THEN TRUE ELSE NULL END AS %s", pgd.Quote(column), pgd.Quote(column))
}
28 changes: 20 additions & 8 deletions internal/infra/commonsql/dialect_sqlserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func (sd SQLServerDialect) Where(where string) string {
}

// Select clause
func (sd SQLServerDialect) Select(tableName string, schemaName string, where string, distinct bool, columns ...string) string {
func (sd SQLServerDialect) Select(tableName string, schemaName string, where string, distinct bool, columns ...ColumnExportDefinition) string {
var query strings.Builder

query.WriteString("SELECT ")
Expand All @@ -63,11 +63,15 @@ func (sd SQLServerDialect) Select(tableName string, schemaName string, where str
query.WriteString("DISTINCT ")
}

if len(columns) > 0 {
if names := Names(columns); len(names) > 0 {
for i := range columns {
columns[i] = sd.Quote(columns[i])
if columns[i].OnlyPresence {
names[i] = sd.selectPresence(names[i])
} else {
names[i] = sd.Quote(names[i])
}
}
query.WriteString(strings.Join(columns, ", "))
query.WriteString(strings.Join(names, ", "))
} else {
query.WriteRune('*')
}
Expand All @@ -81,7 +85,7 @@ func (sd SQLServerDialect) Select(tableName string, schemaName string, where str
}

// SelectLimit clause
func (sd SQLServerDialect) SelectLimit(tableName string, schemaName string, where string, distinct bool, limit uint, columns ...string) string {
func (sd SQLServerDialect) SelectLimit(tableName string, schemaName string, where string, distinct bool, limit uint, columns ...ColumnExportDefinition) string {
var query strings.Builder

query.WriteString("SELECT ")
Expand All @@ -93,11 +97,15 @@ func (sd SQLServerDialect) SelectLimit(tableName string, schemaName string, wher
query.WriteString(sd.Limit(limit))
query.WriteRune(' ')

if len(columns) > 0 {
if names := Names(columns); len(names) > 0 {
for i := range columns {
columns[i] = sd.Quote(columns[i])
if columns[i].OnlyPresence {
names[i] = sd.selectPresence(names[i])
} else {
names[i] = sd.Quote(names[i])
}
}
query.WriteString(strings.Join(columns, ", "))
query.WriteString(strings.Join(names, ", "))
} else {
query.WriteRune('*')
}
Expand Down Expand Up @@ -125,3 +133,7 @@ func (sd SQLServerDialect) Quote(id string) string {
func (sd SQLServerDialect) CreateSelect(sel string, where string, limit string, columns string, from string) string {
return fmt.Sprintf("%s %s %s %s %s", sel, limit, columns, from, where)
}

func (sd SQLServerDialect) selectPresence(column string) string {
return fmt.Sprintf("CASE WHEN %s IS NOT NULL THEN 1 ELSE NULL END AS %s", sd.Quote(column), sd.Quote(column))
}
Loading
Loading