diff --git a/Changelog.md b/Changelog.md deleted file mode 100644 index 7111828..0000000 --- a/Changelog.md +++ /dev/null @@ -1,32 +0,0 @@ -## 2011-07-01 Daniel Carneiro - -* Initial Release - -1.32 -Added new function markAll to mark all archives. Good when you re-create a database with all changes applied to schema. -1.33 -Added new function to create dbseeds (like ruby migrations). -Updated funtion schema:recreate_oracle and schema:recreate_mysql, now creating insert DDL for core data. -1.34 -bug fix encoding problems -bug fix metadata files generation -1.35 -Added new function to validate if a constraint is enabled or not (Works only in Oracle) -1.36 -bug fix schema:recreate_mysql duplicating primary key statement -1.37 -bug fix dbchange:markall in mysql -1.40 -bug fix - Single quotes duplicated in insert into query -bug-fix - String fields not encapsulated with single quotes when value is number -1.41 -bug fix - schema:recreate_mysql not escaping strings in defaultValue -1.42 -bug fix - dbchange:down executing empty down statements -Added support for postgres (version >= 8.4) -1.43 -bug fixes in postgres support -1.58 -bug fix in oracle indexes read -1.59 -transforming warnings in errors \ No newline at end of file diff --git a/src/main/groovy/br/com/bluesoft/bee/database/reader/DatabaseReaderChanger.groovy b/src/main/groovy/br/com/bluesoft/bee/database/reader/DatabaseReaderChanger.groovy index 6bfe736..f357709 100644 --- a/src/main/groovy/br/com/bluesoft/bee/database/reader/DatabaseReaderChanger.groovy +++ b/src/main/groovy/br/com/bluesoft/bee/database/reader/DatabaseReaderChanger.groovy @@ -27,5 +27,4 @@ class DatabaseReaderChanger { } return databaseReader; } - } diff --git a/src/main/groovy/br/com/bluesoft/bee/database/reader/PostgresDatabaseReader.groovy b/src/main/groovy/br/com/bluesoft/bee/database/reader/PostgresDatabaseReader.groovy index 456f562..093b754 100644 --- a/src/main/groovy/br/com/bluesoft/bee/database/reader/PostgresDatabaseReader.groovy +++ b/src/main/groovy/br/com/bluesoft/bee/database/reader/PostgresDatabaseReader.groovy @@ -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 { @@ -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 @@ -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 @@ -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 diff --git a/src/main/groovy/br/com/bluesoft/bee/importer/JsonImporter.groovy b/src/main/groovy/br/com/bluesoft/bee/importer/JsonImporter.groovy index 7a5c781..fea7263 100644 --- a/src/main/groovy/br/com/bluesoft/bee/importer/JsonImporter.groovy +++ b/src/main/groovy/br/com/bluesoft/bee/importer/JsonImporter.groovy @@ -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 { @@ -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 tableClass) { Schema schema = new Schema() - schema.tables = importTables() + schema.tables = importTables(tableClass) schema.views = importViews() schema.sequences = importSequences() schema.procedures = importProcedures() @@ -86,12 +101,12 @@ class JsonImporter implements Importer { return schema } - private def importTables() { + private def importTables(Class 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 } } diff --git a/src/main/groovy/br/com/bluesoft/bee/model/ObjectType.groovy b/src/main/groovy/br/com/bluesoft/bee/model/ObjectType.groovy index 6208e23..12c898f 100644 --- a/src/main/groovy/br/com/bluesoft/bee/model/ObjectType.groovy +++ b/src/main/groovy/br/com/bluesoft/bee/model/ObjectType.groovy @@ -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 diff --git a/src/main/groovy/br/com/bluesoft/bee/model/Schema.groovy b/src/main/groovy/br/com/bluesoft/bee/model/Schema.groovy index f671c3f..f45127e 100644 --- a/src/main/groovy/br/com/bluesoft/bee/model/Schema.groovy +++ b/src/main/groovy/br/com/bluesoft/bee/model/Schema.groovy @@ -49,7 +49,6 @@ class Schema { boolean filtered def validateWithMetadata(Schema metadataSchema) { - def databaseObjects = this.getAllObjects() def metadataObjects = metadataSchema.getAllObjects() @@ -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) + } } } diff --git a/src/main/groovy/br/com/bluesoft/bee/model/Table.groovy b/src/main/groovy/br/com/bluesoft/bee/model/Table.groovy index b966e8a..10725b2 100644 --- a/src/main/groovy/br/com/bluesoft/bee/model/Table.groovy +++ b/src/main/groovy/br/com/bluesoft/bee/model/Table.groovy @@ -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) @@ -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] diff --git a/src/main/groovy/br/com/bluesoft/bee/model/postgres/PostgresPolicy.groovy b/src/main/groovy/br/com/bluesoft/bee/model/postgres/PostgresPolicy.groovy new file mode 100644 index 0000000..6530711 --- /dev/null +++ b/src/main/groovy/br/com/bluesoft/bee/model/postgres/PostgresPolicy.groovy @@ -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 + } +} diff --git a/src/main/groovy/br/com/bluesoft/bee/model/postgres/PostgresTable.groovy b/src/main/groovy/br/com/bluesoft/bee/model/postgres/PostgresTable.groovy new file mode 100644 index 0000000..7cdb468 --- /dev/null +++ b/src/main/groovy/br/com/bluesoft/bee/model/postgres/PostgresTable.groovy @@ -0,0 +1,82 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Bluesoft Consultoria em Informatica Ltda. + * Portions created by the Initial Developer are Copyright (C) 2011 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + */ +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 PostgresTable extends Table { + + Boolean rowSecurity + Map policies = [:] + + List validateWithMetadata(metadataTable) { + def messages = super.validateWithMetadata(metadataTable) + + if (metadataTable instanceof PostgresTable) { + if (metadataTable.rowSecurity != this.rowSecurity) { + def messageText = "The row security of the table ${metadataTable.name} should be ${metadataTable.rowSecurity} but it is ${this.rowSecurity}" + messages << new Message(objectName: this.name, level: MessageLevel.ERROR, objectType: ObjectType.TABLE, messageType: MessageType.PRESENCE, message: messageText) + } + + messages.addAll validatePresenceOfPolicies(metadataTable) + messages.addAll validateElements('policies', metadataTable) + } + + return messages + } + + private def validatePresenceOfPolicies(PostgresTable metadataTable) { + def messages = [] + + def missingPolicies = metadataTable.policies.keySet() - this.policies.keySet() + def additionalPolicies = this.policies.keySet() - metadataTable.policies.keySet() + + missingPolicies.each { + def messageText = "The table ${name} is missing the policy ${it}."; + def message = new Message(objectName: "${name}.${it}", level: MessageLevel.ERROR, objectType: ObjectType.TABLE_COLUMN, messageType: MessageType.PRESENCE, message: messageText) + messages << message + } + + additionalPolicies.each { + def messageText = "The table ${name} has the additional policy ${it}."; + def message = new Message(objectName: "${name}.${it}", level: MessageLevel.ERROR, objectType: ObjectType.TABLE_COLUMN, messageType: MessageType.PRESENCE, message: messageText) + messages << message + } + + return messages + } +} diff --git a/src/main/groovy/br/com/bluesoft/bee/schema/BeePostgresSchemaCreator.groovy b/src/main/groovy/br/com/bluesoft/bee/schema/BeePostgresSchemaCreator.groovy index 0607a46..ee34f68 100644 --- a/src/main/groovy/br/com/bluesoft/bee/schema/BeePostgresSchemaCreator.groovy +++ b/src/main/groovy/br/com/bluesoft/bee/schema/BeePostgresSchemaCreator.groovy @@ -72,7 +72,6 @@ class BeePostgresSchemaCreator extends BeeSchemaCreator { file << "\n" } - void createProcedures(def file, def schema) { schema.procedures*.value.sort().each { def procedure = "${it.text};\n\n" @@ -86,4 +85,39 @@ class BeePostgresSchemaCreator extends BeeSchemaCreator { file.append(trigger.toString(), 'utf-8') } } + + void createTables(def file, def schema) { + def tables = schema.tables.sort() + tables.each({ + file << createTable(it.value) + file << createRowSecurity(it.value) + file << createPolicies(it.value) + file << "\n" + }) + } + + def createRowSecurity(def table) { + return table.rowSecurity ? "alter table ${table.name} enable row level security;\n" : "" + } + + def createPolicies(def table) { + def result = "" + table.policies.each({ + result += createPolicy(table, it.value) + }) + return result; + } + + def createPolicy(def table, def policy) { + def result = "create policy ${policy.name} on ${table.name}" + result += " as ${policy.permissive ? 'permissive' : 'restrictive'}" + result += " for ${policy.cmd}" + result += " to ${policy.roles.join(", ")}" + result += " using (${policy.usingExpression})" + if (policy.checkExpression) { + result += " with check (${policy.checkExpression})" + } + result += ";\n" + return result + } } diff --git a/src/main/groovy/br/com/bluesoft/bee/schema/BeePostgresSchemaCreatorAction.groovy b/src/main/groovy/br/com/bluesoft/bee/schema/BeePostgresSchemaCreatorAction.groovy index 05bf205..9b778b6 100644 --- a/src/main/groovy/br/com/bluesoft/bee/schema/BeePostgresSchemaCreatorAction.groovy +++ b/src/main/groovy/br/com/bluesoft/bee/schema/BeePostgresSchemaCreatorAction.groovy @@ -2,6 +2,7 @@ package br.com.bluesoft.bee.schema import br.com.bluesoft.bee.importer.JsonImporter import br.com.bluesoft.bee.model.Options +import br.com.bluesoft.bee.model.postgres.PostgresTable import br.com.bluesoft.bee.runner.ActionRunner import br.com.bluesoft.bee.service.BeeWriter @@ -20,11 +21,11 @@ public class BeePostgresSchemaCreatorAction implements ActionRunner { } public boolean run() { - def objectName = options.arguments[0] out.log('importing schema metadata from the reference files') - def schema = getImporter().importMetaData() + + def schema = getImporter().importMetaData(PostgresTable.class) if (objectName) { schema = schema.filter(objectName) diff --git a/src/main/groovy/br/com/bluesoft/bee/schema/BeeSchemaCreator.groovy b/src/main/groovy/br/com/bluesoft/bee/schema/BeeSchemaCreator.groovy index 3527ade..5a28f50 100644 --- a/src/main/groovy/br/com/bluesoft/bee/schema/BeeSchemaCreator.groovy +++ b/src/main/groovy/br/com/bluesoft/bee/schema/BeeSchemaCreator.groovy @@ -15,29 +15,30 @@ abstract class BeeSchemaCreator { println 'BeeSchemaCreator' def result = " ${column.name} ${column.type}" - if (column.type in ['char', 'varchar']) { - if (column.sizeType != null) { - result += "(${column.size} ${column.sizeType})" - } else { - result += "(${column.size})" - } - } - - if (column.type == 'number') { - if (column.scale > 0) { - result += "(${column.size}, ${column.scale})" - } else { - result += "(${column.size})" - } - } - - if (column.defaultValue) { - result += " default ${column.defaultValue}" - } - - if (!column.nullable) { - result += ' not null' - } + if (column.type in ['char', 'varchar']) { + if (column.sizeType != null) { + result += "(${column.size} ${column.sizeType})" + } else { + result += "(${column.size})" + } + } + + if (column.type == 'number') { + if (column.scale > 0) { + result += "(${column.size}, ${column.scale})" + } else { + result += "(${column.size})" + } + } + + if (column.defaultValue) { + result += " default ${column.defaultValue}" + } + + if (!column.nullable) { + result += ' not null' + } + return result } @@ -47,20 +48,23 @@ abstract class BeeSchemaCreator { columns << createColumn(it.value) }) def temp = table.temporary ? " global temporary" : "" - def result = "create${temp} table ${table.name} (\n" + columns.join(",\n") + "\n);\n\n" + return "create${temp} table ${table.name} (\n" + columns.join(",\n") + "\n);\n" } void createTables(def file, def schema) { def tables = schema.tables.sort() - tables.each({ file << createTable(it.value) }) + tables.each({ + file << createTable(it.value) + file << "\n" + }) } def createPrimaryKey(table) { def constraint = table.constraints.find({ it.value.type == 'P' }) - if (constraint == null) { - return "" - } + if (constraint == null) { + return "" + } constraint = constraint.value @@ -143,12 +147,12 @@ abstract class BeeSchemaCreator { def createIndex(tableName, index) { def result = "create" - if (index.type == 'b') { - result += ' bitmap' - } - if (index.unique) { - result += ' unique' - } + if (index.type == 'b') { + result += ' bitmap' + } + if (index.unique) { + result += ' unique' + } result += " index ${index.name} on ${tableName}(" + index.columns.join(',') + ");\n" return result diff --git a/src/main/groovy/br/com/bluesoft/bee/schema/BeeSchemaGeneratorAction.groovy b/src/main/groovy/br/com/bluesoft/bee/schema/BeeSchemaGeneratorAction.groovy index 1cb6844..f36dd5d 100644 --- a/src/main/groovy/br/com/bluesoft/bee/schema/BeeSchemaGeneratorAction.groovy +++ b/src/main/groovy/br/com/bluesoft/bee/schema/BeeSchemaGeneratorAction.groovy @@ -40,6 +40,7 @@ import br.com.bluesoft.bee.model.Options import br.com.bluesoft.bee.model.Schema import br.com.bluesoft.bee.runner.ActionRunner import br.com.bluesoft.bee.service.BeeWriter +import br.com.bluesoft.bee.util.RDBMSUtil import groovy.sql.Sql class BeeSchemaGeneratorAction implements ActionRunner { @@ -68,16 +69,19 @@ class BeeSchemaGeneratorAction implements ActionRunner { try { out.log "Extracting the metadata..." + + def rdbms = RDBMSUtil.getRDBMS(options) def databaseReader = DatabaseReaderChanger.getDatabaseReader(options, sql) + Schema schemaNew = databaseReader.getSchema(objectName) - if (objectName) { - schemaNew = schemaNew.filter(objectName) - } + if (objectName) { + schemaNew = schemaNew.filter(objectName) + } - Schema schemaOld = getImporter().importMetaData() - if (objectName) { - schemaOld = schemaOld.filter(objectName) - } + Schema schemaOld = getImporter().importMetaData(rdbms) + if (objectName) { + schemaOld = schemaOld.filter(objectName) + } applyIgnore(schemaOld, schemaNew) @@ -111,9 +115,9 @@ class BeeSchemaGeneratorAction implements ActionRunner { } private def getImporter() { - if (importer == null) { - return new JsonImporter(options.dataDir.canonicalPath) - } + if (importer == null) { + return new JsonImporter(options.dataDir.canonicalPath) + } return importer } } diff --git a/src/main/groovy/br/com/bluesoft/bee/schema/BeeSchemaValidatorAction.groovy b/src/main/groovy/br/com/bluesoft/bee/schema/BeeSchemaValidatorAction.groovy index a1e75c2..09afc18 100644 --- a/src/main/groovy/br/com/bluesoft/bee/schema/BeeSchemaValidatorAction.groovy +++ b/src/main/groovy/br/com/bluesoft/bee/schema/BeeSchemaValidatorAction.groovy @@ -41,6 +41,7 @@ import br.com.bluesoft.bee.model.message.MessageLevel import br.com.bluesoft.bee.runner.ActionRunner import br.com.bluesoft.bee.service.BeeWriter import br.com.bluesoft.bee.service.MessagePrinter +import br.com.bluesoft.bee.util.RDBMSUtil class BeeSchemaValidatorAction implements ActionRunner { @@ -66,18 +67,18 @@ class BeeSchemaValidatorAction implements ActionRunner { def databaseReader = DatabaseReaderChanger.getDatabaseReader(options, sql) out.log('importing schema metadata from the reference files') - Schema metadataSchema = importer.importMetaData() + Schema metadataSchema = importer.importMetaData(RDBMSUtil.getRDBMS(options)) - if (objectName) { - metadataSchema = metadataSchema.filter(objectName) - } + if (objectName) { + metadataSchema = metadataSchema.filter(objectName) + } out.log('importing schema metadata from the database') Schema databaseSchema = databaseReader.getSchema(objectName) - if (objectName) { - databaseSchema = databaseSchema.filter(objectName) - } + if (objectName) { + databaseSchema = databaseSchema.filter(objectName) + } out.log('validating') def messages = databaseSchema.validateWithMetadata(metadataSchema) @@ -94,13 +95,12 @@ class BeeSchemaValidatorAction implements ActionRunner { } private def getImporter() { - if (importer == null) { - return new JsonImporter(options.dataDir.canonicalPath) - } + if (importer == null) { + return new JsonImporter(options.dataDir.canonicalPath) + } return importer } - def getDatabaseConnection(clientName) { if (sql != null) { return sql diff --git a/src/main/groovy/br/com/bluesoft/bee/util/VersionHelper.groovy b/src/main/groovy/br/com/bluesoft/bee/util/VersionHelper.groovy index 4251fa0..1181b07 100644 --- a/src/main/groovy/br/com/bluesoft/bee/util/VersionHelper.groovy +++ b/src/main/groovy/br/com/bluesoft/bee/util/VersionHelper.groovy @@ -4,8 +4,10 @@ public class VersionHelper { def static isNewerThan9_6(String version) { def is_newer = false + def major_version = version.tokenize('.')[0].toInteger() - def minor_version = version.tokenize('.')[1].toInteger() + def minor_version = version.tokenize('.')[1].tokenize(' ')[0].toInteger() + if (major_version == 9 && minor_version >= 6) { is_newer = true } else if (major_version > 9) { @@ -13,5 +15,4 @@ public class VersionHelper { } return is_newer } - } diff --git a/src/test/groovy/br/com/bluesoft/bee/util/VersionHelperTest.groovy b/src/test/groovy/br/com/bluesoft/bee/util/VersionHelperTest.groovy index 4d33c29..ad2c909 100644 --- a/src/test/groovy/br/com/bluesoft/bee/util/VersionHelperTest.groovy +++ b/src/test/groovy/br/com/bluesoft/bee/util/VersionHelperTest.groovy @@ -6,26 +6,36 @@ class VersionHelperTest { @Test void 'versao 8_5 deve retornar false'() { - assert VersionHelper.isNewerThan9_6('8.5') == false + assert !VersionHelper.isNewerThan9_6('8.5') } @Test void 'versao 9_5 deve retornar false'() { - assert VersionHelper.isNewerThan9_6('9.5') == false + assert !VersionHelper.isNewerThan9_6('9.5') } @Test void 'versao 9_6 deve retornar true'() { - assert VersionHelper.isNewerThan9_6('9.6') == true + assert VersionHelper.isNewerThan9_6('9.6') } @Test void 'versao 9_7 deve retornar true'() { - assert VersionHelper.isNewerThan9_6('9.7') == true + assert VersionHelper.isNewerThan9_6('9.7') } @Test void 'versao 10_3 deve retornar true'() { - assert VersionHelper.isNewerThan9_6('10.3') == true + assert VersionHelper.isNewerThan9_6('10.3') + } + + @Test + void 'versao 9_5 com string do SO deve retornar false'() { + assert !VersionHelper.isNewerThan9_6('9.5 (Debian 12.2-2.pgdg100+1)') + } + + @Test + void 'versao 9_6 com string do SO deve retornar true'() { + assert VersionHelper.isNewerThan9_6('9.6 (Debian 12.2-2.pgdg100+1)') } }