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
32 changes: 0 additions & 32 deletions Changelog.md

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,4 @@ class DatabaseReaderChanger {
}
return databaseReader;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,11 @@ import br.com.bluesoft.bee.model.IndexColumn
import br.com.bluesoft.bee.model.Procedure
import br.com.bluesoft.bee.model.Schema
import br.com.bluesoft.bee.model.Sequence
import br.com.bluesoft.bee.model.Table
import br.com.bluesoft.bee.model.TableColumn
import br.com.bluesoft.bee.model.Trigger
import br.com.bluesoft.bee.model.View
import br.com.bluesoft.bee.model.postgres.PostgresPolicy
import br.com.bluesoft.bee.model.postgres.PostgresTable
import br.com.bluesoft.bee.util.VersionHelper

class PostgresDatabaseReader implements DatabaseReader {
Expand Down Expand Up @@ -80,18 +81,21 @@ class PostgresDatabaseReader implements DatabaseReader {
fillIndexes(tables, objectName, databaseVersion)
fillCostraints(tables, objectName)
fillCostraintsColumns(tables, objectName)
fillPolicies(tables, objectName)
return tables
}

static final def TABLES_QUERY = '''
select t.table_name, 'N'as temporary
select t.table_name, pt.rowsecurity
from information_schema.tables t
inner join pg_catalog.pg_tables pt on t.table_name = pt.tablename
where t.table_type = 'BASE TABLE' and table_schema not in ('pg_catalog', 'information_schema')
order by table_name
'''
static final def TABLES_QUERY_BY_NAME = '''
select t.table_name, 'N'as temporary
select t.table_name, pt.rowsecurity
from information_schema.tables t
inner join pg_catalog.pg_tables pt on t.table_name = pt.tablename
where t.table_type = 'BASE TABLE' and table_schema not in ('pg_catalog', 'information_schema')
and t.table_name = ?
order by table_name
Expand All @@ -107,14 +111,12 @@ class PostgresDatabaseReader implements DatabaseReader {
}
rows.each({
def name = it.table_name.toLowerCase()
def temporary = it.temporary == 'Y' ? true : false
def comment = ''
tables[name] = new Table(name: name, temporary: temporary, comment: comment)
def rowSecurity = it.rowsecurity
tables[name] = new PostgresTable(name: name, rowSecurity: rowSecurity, temporary: false, comment: '')
})
return tables
}


static final def TABLES_COLUMNS_QUERY = '''
select ic.table_name, ic.column_name, ic.data_type, ic.is_nullable as nullable,
case
Expand Down Expand Up @@ -417,6 +419,39 @@ class PostgresDatabaseReader implements DatabaseReader {
})
}

private def fillPolicies(tables, objectName) {
def rows

if (objectName) {
rows = sql.rows("""
select p.tablename, p.policyname, p.permissive, p.cmd, p.qual, p.with_check, p.roles::varchar
from pg_catalog.pg_policies p
where objectname = ?
""", objectName)
} else {
rows = sql.rows("""
select p.tablename, p.policyname, p.permissive, p.cmd, p.qual, p.with_check, p.roles::varchar
from pg_catalog.pg_policies p
""")
}

rows.each({
def tableName = it.tablename.toLowerCase()
def policyName = it.policyname
def table = tables[tableName]

def policy = new PostgresPolicy()
policy.name = it.policyname
policy.permissive = it.permissive == 'PERMISSIVE'
policy.cmd = it.cmd
policy.usingExpression = it.qual
policy.checkExpression = it.with_check
policy.roles = it.roles.substring(1, it.roles.size() - 1).tokenize(',')

table.policies[policyName] = policy
})
}

final static def SEQUENCES_QUERY = '''
select c.relname as sequence_name, '1' as min_value
from pg_class c
Expand Down
21 changes: 18 additions & 3 deletions src/main/groovy/br/com/bluesoft/bee/importer/JsonImporter.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ import br.com.bluesoft.bee.model.Table
import br.com.bluesoft.bee.model.Trigger
import br.com.bluesoft.bee.model.UserType
import br.com.bluesoft.bee.model.View
import br.com.bluesoft.bee.model.postgres.PostgresTable
import br.com.bluesoft.bee.util.JsonUtil
import br.com.bluesoft.bee.util.RDBMS
import org.codehaus.jackson.map.ObjectMapper

class JsonImporter implements Importer {
Expand Down Expand Up @@ -75,8 +77,21 @@ class JsonImporter implements Importer {
}

Schema importMetaData() {
importMetaData(Table.class)
}

Schema importMetaData(RDBMS rdbms) {
switch (rdbms) {
case RDBMS.POSTGRES:
return importMetaData(PostgresTable.class)
default:
return importMetaData()
}
}

Schema importMetaData(Class<? extends Table> tableClass) {
Schema schema = new Schema()
schema.tables = importTables()
schema.tables = importTables(tableClass)
schema.views = importViews()
schema.sequences = importSequences()
schema.procedures = importProcedures()
Expand All @@ -86,12 +101,12 @@ class JsonImporter implements Importer {
return schema
}

private def importTables() {
private def importTables(Class<? extends Table> tableClass) {
checkIfFolderExists(tablesFolder)
def tables = [:]
tablesFolder.eachFile {
if (it.name.endsWith(".bee")) {
def table = mapper.readValue(it, Table.class)
def table = mapper.readValue(it, tableClass)
tables[table.name] = table
}
}
Expand Down
12 changes: 11 additions & 1 deletion src/main/groovy/br/com/bluesoft/bee/model/ObjectType.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,17 @@ package br.com.bluesoft.bee.model;

public enum ObjectType {

TABLE("table"), VIEW("view"), SEQUENCE("sequence"), TABLE_COLUMN("table column"), INDEX('index'), CONSTRAINT('constraint'), PROCEDURE('procedure'), PACKAGE('package'), TRIGGER('trigger'), USER_TYPE('user type')
TABLE("table"),
VIEW("view"),
SEQUENCE("sequence"),
TABLE_COLUMN("table column"),
INDEX('index'),
CONSTRAINT('constraint'),
PROCEDURE('procedure'),
PACKAGE('package'),
TRIGGER('trigger'),
USER_TYPE('user type'),
POLICY('policy')

def description

Expand Down
7 changes: 3 additions & 4 deletions src/main/groovy/br/com/bluesoft/bee/model/Schema.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ class Schema {
boolean filtered

def validateWithMetadata(Schema metadataSchema) {

def databaseObjects = this.getAllObjects()
def metadataObjects = metadataSchema.getAllObjects()

Expand All @@ -60,9 +59,9 @@ class Schema {
databaseObjects.each { objName, obj ->
if (obj instanceof Validator) {
def target = metadataSchema.getAllObjects()[objName]
if (target) {
messages.addAll obj.validateWithMetadata(target)
}
if (target) {
messages.addAll obj.validateWithMetadata(target)
}
}
}

Expand Down
9 changes: 5 additions & 4 deletions src/main/groovy/br/com/bluesoft/bee/model/Table.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,12 @@ class Table implements Validator {
}

List validateWithMetadata(metadataTable) {
if (!metadataTable instanceof Table) {
return []
}
if (!metadataTable instanceof Table) {
return []
}

def messages = []

if (metadataTable) {
messages.addAll validatePresenceOfColumns(metadataTable)
messages.addAll validatePresenceOfIndexes(metadataTable)
Expand Down Expand Up @@ -145,7 +146,7 @@ class Table implements Validator {
return validateElements('constraints', metadataTable)
}

private def validateElements(elements, metadataTable) {
protected def validateElements(elements, Table metadataTable) {
def messages = []
def metadataElementsMap = metadataTable[elements]
def databaseElementsMap = this[elements]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package br.com.bluesoft.bee.model.postgres

import br.com.bluesoft.bee.model.ObjectType
import br.com.bluesoft.bee.model.Table
import br.com.bluesoft.bee.model.message.Message
import br.com.bluesoft.bee.model.message.MessageLevel
import br.com.bluesoft.bee.model.message.MessageType

class PostgresPolicy {

String name
String cmd
String usingExpression
String checkExpression
String[] roles
boolean permissive

def validateWithMetadata(Table table, PostgresPolicy metadataPolicy) {
def messages = []

if (metadataPolicy.cmd != this.cmd) {
def messageText = "The cmd of the policy ${this.name} of the table ${table.name} should be ${metadataPolicy.cmd} but it is ${this.cmd}"
messages << new Message(objectName: this.name, level: MessageLevel.ERROR, objectType: ObjectType.POLICY, messageType: MessageType.DATA_MISMATCH, message: messageText)
}

if (metadataPolicy.usingExpression != this.usingExpression) {
def messageText = "The using expression of the policy ${this.name} of the table ${table.name} should be ${metadataPolicy.usingExpression} but it is ${this.usingExpression}"
messages << new Message(objectName: this.name, level: MessageLevel.ERROR, objectType: ObjectType.POLICY, messageType: MessageType.DATA_MISMATCH, message: messageText)
}

if (metadataPolicy.checkExpression != this.checkExpression) {
def messageText = "The check expression of the policy ${this.name} of the table ${table.name} should be ${metadataPolicy.checkExpression} but it is ${this.checkExpression}"
messages << new Message(objectName: this.name, level: MessageLevel.ERROR, objectType: ObjectType.POLICY, messageType: MessageType.DATA_MISMATCH, message: messageText)
}

if (metadataPolicy.permissive != this.permissive) {
def messageText = "The policy ${this.name} of the table ${table.name} should ${metadataPolicy.permissive ? 'be' : 'not be'} permissive"
messages << new Message(objectName: this.name, level: MessageLevel.ERROR, objectType: ObjectType.POLICY, messageType: MessageType.DATA_MISMATCH, message: messageText)
}

messages.addAll validatePresenceOfRoles(table, metadataPolicy)

return messages
}

private def validatePresenceOfRoles(Table table, PostgresPolicy metadataPolicy) {
def messages = []

def missingRoles = metadataPolicy.roles - this.roles
def aditionalRoles = this.roles - metadataPolicy.roles

missingRoles.each {
def messageText = "The policy ${name} of the table ${table.name} is missing the role ${it}.";
def message = new Message(objectName: "${table.name}.${name}", level: MessageLevel.ERROR, objectType: ObjectType.POLICY, messageType: MessageType.PRESENCE, message: messageText)
messages << message
}

aditionalRoles.each {
def messageText = "The policy ${name} of the table ${table.name} has the additional role ${it}.";
def message = new Message(objectName: "${table.name}.${name}", level: MessageLevel.ERROR, objectType: ObjectType.POLICY, messageType: MessageType.PRESENCE, message: messageText)
messages << message
}

return messages
}

// forcing getter to avoid the creation of conflicting getters (is + get)
boolean isPermissive() {
return permissive
}
}
Loading