diff options
author | jakefeasel <jfeasel@gmail.com> | 2014-09-01 21:23:30 -0700 |
---|---|---|
committer | jakefeasel <jfeasel@gmail.com> | 2014-09-01 21:23:30 -0700 |
commit | 2f98b46a765e966e7031236b05e9d2720c0ffa37 (patch) | |
tree | 38983db6e377d6f1abc8581e8ebfd4c843555bed /src | |
parent | 5fc08f6919e749d0ff103dae88b3f6ed2a93ccfe (diff) | |
download | sqlfiddle2-2f98b46a765e966e7031236b05e9d2720c0ffa37.zip sqlfiddle2-2f98b46a765e966e7031236b05e9d2720c0ffa37.tar.gz sqlfiddle2-2f98b46a765e966e7031236b05e9d2720c0ffa37.tar.bz2 |
Upgrading to Scripted SQL 1.4 for both connectors
Diffstat (limited to 'src')
-rw-r--r-- | src/main/assembly/zip.xml | 14 | ||||
-rw-r--r-- | src/main/resources/conf/provisioner.openicf-fiddles.json | 90 | ||||
-rw-r--r-- | src/main/resources/conf/provisioner.openicf-hosts.json | 27 | ||||
-rw-r--r-- | src/main/resources/script/executeQuery.groovy | 9 | ||||
-rw-r--r-- | src/main/resources/tools/fiddles/CreateScript.groovy | 64 | ||||
-rw-r--r-- | src/main/resources/tools/fiddles/DeleteScript.groovy | 14 | ||||
-rw-r--r-- | src/main/resources/tools/fiddles/SearchScript.groovy | 216 | ||||
-rw-r--r-- | src/main/resources/tools/fiddles/SyncScript.groovy | 30 | ||||
-rw-r--r-- | src/main/resources/tools/fiddles/TestScript.groovy | 2 | ||||
-rw-r--r-- | src/main/resources/tools/fiddles/UpdateScript.groovy | 65 | ||||
-rw-r--r-- | src/main/resources/tools/hosts/CreateScript.groovy | 45 | ||||
-rw-r--r-- | src/main/resources/tools/hosts/DeleteScript.groovy | 7 | ||||
-rw-r--r-- | src/main/resources/tools/hosts/SearchScript.groovy | 61 | ||||
-rw-r--r-- | src/main/resources/tools/hosts/SyncScript.groovy | 87 | ||||
-rw-r--r-- | src/main/resources/tools/hosts/TestScript.groovy | 27 | ||||
-rw-r--r-- | src/main/resources/tools/hosts/UpdateScript.groovy | 75 |
16 files changed, 356 insertions, 477 deletions
diff --git a/src/main/assembly/zip.xml b/src/main/assembly/zip.xml index 4b36c65..747d74c 100644 --- a/src/main/assembly/zip.xml +++ b/src/main/assembly/zip.xml @@ -56,8 +56,9 @@ <useTransitiveDependencies>false</useTransitiveDependencies> <!--<useTransitiveFiltering>true</useTransitiveFiltering>--> <excludes> - <exclude>org.forgerock.openidm:openidm-zip</exclude> <exclude>org.forgerock.openicf.connectors*</exclude> + <exclude>org.apache.tomcat:tomcat-jdbc</exclude> + <exclude>org.apache.geronimo.ext.tomcat:juli</exclude> </excludes> </dependencySet> <dependencySet> @@ -69,5 +70,16 @@ <include>org.forgerock.openicf.connectors*</include> </includes> </dependencySet> + + <dependencySet> + <useProjectArtifact>false</useProjectArtifact> + <outputDirectory>/lib</outputDirectory> + <includes> + <include>org.apache.tomcat:tomcat-jdbc</include> + <include>org.apache.geronimo.ext.tomcat:juli</include> + <include>mysql:mysql-connector-java</include> + <include>org.postgresql:postgresql-fr-osgi</include> + </includes> + </dependencySet> </dependencySets> </assembly> diff --git a/src/main/resources/conf/provisioner.openicf-fiddles.json b/src/main/resources/conf/provisioner.openicf-fiddles.json index 07ac036..24a00ae 100644 --- a/src/main/resources/conf/provisioner.openicf-fiddles.json +++ b/src/main/resources/conf/provisioner.openicf-fiddles.json @@ -1,8 +1,8 @@ { "name" : "fiddles", "connectorRef" : { - "bundleName" : "org.forgerock.openicf.connectors.scriptedsql-connector", - "bundleVersion" : "1.1.1.0", + "bundleName" : "org.forgerock.openicf.connectors.groovy-connector", + "bundleVersion" : "1.4.0.0", "connectorName" : "org.forgerock.openicf.connectors.scriptedsql.ScriptedSQLConnector" }, "producerBufferSize" : 100, @@ -29,22 +29,19 @@ "SCHEMA" : -1 }, "configurationProperties" : { - "host" : "SQLFIDDLE_HOST", - "port" : "5432", - "user" : "postgres", + "username" : "postgres", "password" : "password", - "database" : "sqlfiddle", + "driverClassName" : "org.postgresql.Driver", + "url" : "jdbc:postgresql://SQLFIDDLE_HOST:5432/sqlfiddle", "autoCommit" : true, "reloadScriptOnExecution" : true, - "jdbcDriver" : "org.postgresql.Driver", - "jdbcConnectionUrl" : "jdbc:postgresql://SQLFIDDLE_HOST:5432/sqlfiddle", - "jdbcUrlTemplate" : "jdbc:postgresql://%h:%p/%d", - "createScriptFileName" : "&{launcher.project.location}/tools/fiddles/CreateScript.groovy", - "testScriptFileName" : "&{launcher.project.location}/tools/fiddles/TestScript.groovy", - "searchScriptFileName" : "&{launcher.project.location}/tools/fiddles/SearchScript.groovy", - "deleteScriptFileName" : "&{launcher.project.location}/tools/fiddles/DeleteScript.groovy", - "updateScriptFileName" : "&{launcher.project.location}/tools/fiddles/UpdateScript.groovy", - "syncScriptFileName" : "&{launcher.project.location}/tools/fiddles/SyncScript.groovy" + "createScriptFileName" : "CreateScript.groovy", + "testScriptFileName" : "TestScript.groovy", + "searchScriptFileName" : "SearchScript.groovy", + "updateScriptFileName" : "UpdateScript.groovy", + "classpath" : [ + "&{launcher.project.location}/tools/fiddles" + ] }, "syncFailureHandler" : { "maxRetries" : 5, @@ -303,6 +300,69 @@ "nativeType" : "integer" } } + }, + "query_sets": { + "$schema" : "http://json-schema.org/draft-03/schema", + "id" : "query_sets", + "type" : "object", + "nativeType" : "query_sets", + "properties" : { + "_id" : { + "type" : "integer", + "nativeName" : "__UID__", + "nativeType" : "integer" + }, + "query_set_id" : { + "type" : "integer", + "nativeName" : "id", + "nativeType" : "integer" + }, + "query_id" : { + "type" : "integer", + "nativeName" : "query_id", + "nativeType" : "integer" + }, + "schema_def_id" : { + "type" : "integer", + "nativeName" : "schema_def_id", + "nativeType" : "integer" + }, + "row_count" : { + "type" : "integer", + "nativeName" : "row_count", + "nativeType" : "integer" + }, + "execution_time" : { + "type" : "string", + "nativeName" : "execution_time", + "nativeType" : "string" + }, + "execution_plan" : { + "type" : "string", + "nativeName" : "execution_plan", + "nativeType" : "string" + }, + "succeeded" : { + "type" : "string", + "nativeName" : "succeeded", + "nativeType" : "string" + }, + "error_message" : { + "type" : "string", + "nativeName" : "error_message", + "nativeType" : "string" + }, + "sql" : { + "type" : "string", + "nativeName" : "sql", + "nativeType" : "string" + }, + "columns_list" : { + "type" : "string", + "nativeName" : "columns_list", + "nativeType" : "string" + } + } } }, "operationOptions" : { } diff --git a/src/main/resources/conf/provisioner.openicf-hosts.json b/src/main/resources/conf/provisioner.openicf-hosts.json index dd11d53..91f6184 100644 --- a/src/main/resources/conf/provisioner.openicf-hosts.json +++ b/src/main/resources/conf/provisioner.openicf-hosts.json @@ -1,8 +1,8 @@ { "name" : "hosts", "connectorRef" : { - "bundleName" : "org.forgerock.openicf.connectors.scriptedsql-connector", - "bundleVersion" : "1.1.1.0", + "bundleName" : "org.forgerock.openicf.connectors.groovy-connector", + "bundleVersion" : "1.4.0.0", "connectorName" : "org.forgerock.openicf.connectors.scriptedsql.ScriptedSQLConnector" }, "producerBufferSize" : 100, @@ -29,22 +29,19 @@ "SCHEMA" : -1 }, "configurationProperties" : { - "host" : "SQLFIDDLE_HOST", - "port" : "5432", - "user" : "postgres", + "username" : "postgres", "password" : "password", - "database" : "sqlfiddle", + "driverClassName" : "org.postgresql.Driver", + "url" : "jdbc:postgresql://SQLFIDDLE_HOST:5432/sqlfiddle", "autoCommit" : true, "reloadScriptOnExecution" : true, - "jdbcDriver" : "org.postgresql.Driver", - "jdbcConnectionUrl" : "jdbc:postgresql://SQLFIDDLE_HOST:5432/sqlfiddle", - "jdbcUrlTemplate" : "jdbc:postgresql://%h:%p/%d", - "createScriptFileName" : "&{launcher.project.location}/tools/hosts/CreateScript.groovy", - "testScriptFileName" : "&{launcher.project.location}/tools/hosts/TestScript.groovy", - "searchScriptFileName" : "&{launcher.project.location}/tools/hosts/SearchScript.groovy", - "deleteScriptFileName" : "&{launcher.project.location}/tools/hosts/DeleteScript.groovy", - "updateScriptFileName" : "&{launcher.project.location}/tools/hosts/UpdateScript.groovy", - "syncScriptFileName" : "&{launcher.project.location}/tools/hosts/SyncScript.groovy" + "createScriptFileName" : "CreateScript.groovy", + "testScriptFileName" : "TestScript.groovy", + "searchScriptFileName" : "SearchScript.groovy", + "deleteScriptFileName" : "DeleteScript.groovy", + "classpath" : [ + "&{launcher.project.location}/tools/hosts" + ] }, "syncFailureHandler" : { "maxRetries" : 5, diff --git a/src/main/resources/script/executeQuery.groovy b/src/main/resources/script/executeQuery.groovy index 7cec713..58c6c61 100644 --- a/src/main/resources/script/executeQuery.groovy +++ b/src/main/resources/script/executeQuery.groovy @@ -16,7 +16,6 @@ assert content.schema_short_code assert content.sql.size() <= 8000 - def execQueryStatement(connection, statement, rethrow) { def set = [ RESULTS: [ COLUMNS: [], DATA: [] ], SUCCEEDED: true, STATEMENT: statement ] @@ -71,7 +70,10 @@ def execQueryStatement(connection, statement, rethrow) { } else if ( ((Boolean) errorMessage =~ /insert or update on table "deferred_.*" violates foreign key constraint "deferred_.*_ref"/)) { set.ERRORMESSAGE = "Explicit commits are not allowed within the query panel." set.SUCCEEDED = false - } else if ( ((Boolean) errorMessage =~ /Cannot execute statement in a READ ONLY transaction./)) { + } else if ( + ((Boolean) errorMessage =~ /Cannot execute statement in a READ ONLY transaction./) || + ((Boolean) errorMessage =~ /Can not issue data manipulation statements with executeQuery/) + ) { set.ERRORMESSAGE = "DDL and DML statements are not allowed in the query panel for MySQL; only SELECT statements are allowed. Put DDL and DML in the schema panel." set.SUCCEEDED = false } else { @@ -102,11 +104,14 @@ def m = openidm.create("system/fiddles/queries", ] )._id =~ /^\d+_\w+_(\d+)*$/ + + int queryId = m[0][1].toInteger() def response = [ID: queryId] if (schema_def.context == "host") { + // Use the presence of a link between fiddle and host db to determine if we need to provision a running instance of this db def hostLink = openidm.query("repo/link", [ "_queryId": "links-for-firstId", diff --git a/src/main/resources/tools/fiddles/CreateScript.groovy b/src/main/resources/tools/fiddles/CreateScript.groovy index 445fa30..6b9495b 100644 --- a/src/main/resources/tools/fiddles/CreateScript.groovy +++ b/src/main/resources/tools/fiddles/CreateScript.groovy @@ -24,29 +24,20 @@ * $Id$ */ -import groovy.sql.Sql; -import groovy.sql.DataSet; +import groovy.sql.Sql +import groovy.sql.DataSet import java.security.MessageDigest +import org.identityconnectors.framework.common.objects.AttributesAccessor +import org.identityconnectors.framework.common.objects.Uid -def digest = MessageDigest.getInstance("MD5") - -// Parameters: -// The connector sends us the following: -// connection : SQL connection -// action: String correponding to the action ("CREATE" here) -// log: a handler to the Log facility -// objectClass: a String describing the Object class (__ACCOUNT__ / __GROUP__ / other) -// id: The entry identifier (OpenICF "Name" atribute. (most often matches the uid) -// attributes: an Attribute Map, containg the <String> attribute name as a key -// and the <List> attribute value(s) as value. -// password: password string, clear text -// options: a handler to the OperationOptions Map +def createAttributes = new AttributesAccessor(attributes as Set<Attribute>) -def sql = new Sql(connection); +def digest = MessageDigest.getInstance("MD5") +def sql = new Sql(connection) //Create must return UID. -switch ( objectClass ) { +switch ( objectClass.objectClassValue ) { case "schema_defs": @@ -64,14 +55,14 @@ switch ( objectClass ) { VALUES (?,?,?,?,?,current_timestamp) """, [ - attributes.get("db_type_id").get(0).toInteger(), - attributes.get("short_code").get(0), - attributes.get("ddl").get(0), + createAttributes.findInteger("db_type_id"), + createAttributes.findString("short_code"), + createAttributes.findString("ddl"), id, - attributes.get("statement_separator").get(0) + createAttributes.findString("statement_separator") ]) - return attributes.get("db_type_id").get(0).toInteger() + "_" + attributes.get("short_code").get(0) + return new Uid(createAttributes.findInteger("db_type_id").toString() + "_" + createAttributes.findString("short_code") as String) break @@ -79,9 +70,9 @@ switch ( objectClass ) { // queries will return an existing ID if provided with duplicate sql case "queries": - def statement_separator = attributes.get("statement_separator").get(0) - def sql_query = attributes.get("sql").get(0) - def schema_def_id = attributes.get("schema_def_id").get(0).toInteger() + def statement_separator = createAttributes.findString("statement_separator") + def sql_query = createAttributes.findString("sql") + def schema_def_id = createAttributes.findInteger("schema_def_id") def md5hash @@ -97,19 +88,14 @@ switch ( objectClass ) { def existing_query = sql.firstRow(""" SELECT - ( - SELECT - q.id - FROM - queries q - WHERE - q.schema_def_id = s.id AND - q.md5 = ? - ) as queryId, + q.id as queryId, s.db_type_id, s.short_code FROM schema_defs s + LEFT OUTER JOIN queries q ON + s.id = q.schema_def_id AND + q.md5 = ? WHERE s.id = ? """, [md5hash, schema_def_id]) @@ -158,15 +144,13 @@ switch ( objectClass ) { ] ) } - return existing_query.db_type_id + "_" + existing_query.short_code + "_" + new_query.queryId + return new Uid((existing_query.db_type_id + "_" + existing_query.short_code + "_" + new_query.queryId) as String) } else { - return existing_query.db_type_id + "_" + existing_query.short_code + "_" + existing_query.queryId + return new Uid((existing_query.db_type_id + "_" + existing_query.short_code + "_" + existing_query.queryId) as String) } break - - default: - id; } -return id; +throw new UnsupportedOperationException(operation.name() + " operation of type:" + + objectClass.objectClassValue + " is not supported.") diff --git a/src/main/resources/tools/fiddles/DeleteScript.groovy b/src/main/resources/tools/fiddles/DeleteScript.groovy index 069fc62..e7987bc 100644 --- a/src/main/resources/tools/fiddles/DeleteScript.groovy +++ b/src/main/resources/tools/fiddles/DeleteScript.groovy @@ -23,28 +23,26 @@ * * $Id$ */ -import groovy.sql.Sql; -import groovy.sql.DataSet; +import groovy.sql.Sql +import groovy.sql.DataSet // Parameters: // The connector sends the following: // connection: handler to the SQL connection -// action: a string describing the action ("DELETE" here) // log: a handler to the Log facility // objectClass: a String describing the Object class (__ACCOUNT__ / __GROUP__ / other) // options: a handler to the OperationOptions Map // uid: String for the unique id that specifies the object to delete -log.info("Entering "+action+" Script"); -def sql = new Sql(connection); +def sql = new Sql(connection) assert uid != null -switch ( objectClass ) { +switch ( objectClass.objectClassValue ) { case "schema_defs": - sql.execute("DELETE FROM schema_defs s where (s.db_type_id || '_' || s.short_code) = ?",[uid]) + sql.execute("DELETE FROM schema_defs s where (s.db_type_id || '_' || s.short_code) = ?",[uid.uidValue]) break default: - uid; + uid }
\ No newline at end of file diff --git a/src/main/resources/tools/fiddles/SearchScript.groovy b/src/main/resources/tools/fiddles/SearchScript.groovy index 4a1a9cf..82d58c9 100644 --- a/src/main/resources/tools/fiddles/SearchScript.groovy +++ b/src/main/resources/tools/fiddles/SearchScript.groovy @@ -23,37 +23,10 @@ * * $Id$ */ -import groovy.sql.Sql; -import groovy.sql.DataSet; - -// Parameters: -// The connector sends the following: -// connection: handler to the SQL connection -// objectClass: a String describing the Object class (__ACCOUNT__ / __GROUP__ / other) -// action: a string describing the action ("SEARCH" here) -// log: a handler to the Log facility -// options: a handler to the OperationOptions Map -// query: a handler to the Query Map -// -// The Query map describes the filter used. -// -// query = [ operation: "CONTAINS", left: attribute, right: "value", not: true/false ] -// query = [ operation: "ENDSWITH", left: attribute, right: "value", not: true/false ] -// query = [ operation: "STARTSWITH", left: attribute, right: "value", not: true/false ] -// query = [ operation: "EQUALS", left: attribute, right: "value", not: true/false ] -// query = [ operation: "GREATERTHAN", left: attribute, right: "value", not: true/false ] -// query = [ operation: "GREATERTHANOREQUAL", left: attribute, right: "value", not: true/false ] -// query = [ operation: "LESSTHAN", left: attribute, right: "value", not: true/false ] -// query = [ operation: "LESSTHANOREQUAL", left: attribute, right: "value", not: true/false ] -// query = null : then we assume we fetch everything -// -// AND and OR filter just embed a left/right couple of queries. -// query = [ operation: "AND", left: query1, right: query2 ] -// query = [ operation: "OR", left: query1, right: query2 ] -// -// Returns: A list of Maps. Each map describing one row. -// !!!! Each Map must contain a '__UID__' and '__NAME__' attribute. -// This is required to build a ConnectorObject. +import groovy.sql.Sql +import groovy.sql.DataSet +import org.identityconnectors.framework.common.objects.filter.Filter +import org.forgerock.openicf.misc.scriptedcommon.MapFilterVisitor //Need to handle the __UID__ and __NAME__ in queries def fieldMap = [ @@ -63,7 +36,7 @@ def fieldMap = [ ], "schema_defs": [ "__NAME__": "s.md5", - "__UID__": "(s.db_type_id || '_' || s.short_code)", + "__UID__": "s.db_type_id = ? AND s.short_code = ?", "schema_def_id": "s.id", "last_used": "to_char(s.last_used, 'YYYY-MM-DD HH24:MI:SS.MS')", "minutes_since_last_used": "floor(EXTRACT(EPOCH FROM age(current_timestamp, last_used))/60)" @@ -71,7 +44,7 @@ def fieldMap = [ "queries": [ "__NAME__": "q.md5", "query_id": "q.id", - "__UID__": "(s.db_type_id || '_' || s.short_code || '_' || q.id)" + "__UID__": "s.db_type_id = ? AND s.short_code = ? AND q.id = ?" ] ] @@ -95,47 +68,78 @@ queryParser = { queryObj -> return "(" + queryParser(queryObj.right) + " " + queryObj.operation + " " + queryParser(queryObj.left) + ")" } else { - if (queryObj.get("operation") == "CONTAINS") { - whereParams.push("%" + queryObj.get("right") + "%") - } else if (queryObj.get("operation") == "ENDSWITH") { - whereParams.push("%" + queryObj.get("right")) - } else if (queryObj.get("operation") == "STARTSWITH") { - whereParams.push(queryObj.get("right") + "%") - } else if (queryObj.get("left") == "minutes_since_last_used" || - queryObj.get("left") == "schema_def_id" || - queryObj.get("left") == "db_type_id" || - (objectClass == "db_types" && queryObj.get("left") == "__UID__")) { - whereParams.push(queryObj.get("right").toInteger()) + + // special cases for concatenated-keys + if (objectClass.objectClassValue == "schema_defs" && queryObj.get("left") == "__UID__") { + def fragment_parts = queryObj.get("right").split("_") + assert fragment_parts.size() == 2 + + whereParams.push(fragment_parts[0].toInteger()) + whereParams.push(fragment_parts[1]) + + return fieldMap[objectClass.objectClassValue][queryObj.get("left")] + + } else if (objectClass.objectClassValue == "queries" && queryObj.get("left") == "__UID__") { + def fragment_parts = queryObj.get("right").split("_") + assert fragment_parts.size() == 3 + + whereParams.push(fragment_parts[0].toInteger()) + whereParams.push(fragment_parts[1]) + whereParams.push(fragment_parts[2].toInteger()) + + return fieldMap[objectClass.objectClassValue][queryObj.get("left")] } else { - whereParams.push(queryObj.get("right")) - } - if (fieldMap[objectClass] && fieldMap[objectClass][queryObj.get("left")]) { - queryObj.put("left",fieldMap[objectClass][queryObj.get("left")]) - } + if (queryObj.get("operation") == "CONTAINS") { + whereParams.push("%" + queryObj.get("right") + "%") + } else if (queryObj.get("operation") == "ENDSWITH") { + whereParams.push("%" + queryObj.get("right")) + } else if (queryObj.get("operation") == "STARTSWITH") { + whereParams.push(queryObj.get("right") + "%") + + // integer parameters + } else if (queryObj.get("left") == "minutes_since_last_used" || + queryObj.get("left") == "schema_def_id" || + queryObj.get("left") == "db_type_id" || + (objectClass.objectClassValue == "db_types" && queryObj.get("left") == "__UID__")) { + whereParams.push(queryObj.get("right").toInteger()) + + } else { + whereParams.push(queryObj.get("right")) + } + + if (fieldMap[objectClass.objectClassValue] && fieldMap[objectClass.objectClassValue][queryObj.get("left")]) { + queryObj.put("left",fieldMap[objectClass.objectClassValue][queryObj.get("left")]) + } - def engine = new groovy.text.SimpleTemplateEngine() - def wt = whereTemplates.get(queryObj.get("operation")) - def binding = [left:queryObj.get("left"),not:queryObj.get("not")] - def template = engine.createTemplate(wt).make(binding) + def engine = new groovy.text.SimpleTemplateEngine() + def wt = whereTemplates.get(queryObj.get("operation")) + def binding = [left:queryObj.get("left"),not:queryObj.get("not")] + def template = engine.createTemplate(wt).make(binding) - return template.toString() + return template.toString() + + } } } -log.info("Entering "+action+" Script") - def sql = new Sql(connection) -def result = [] +def filter = filter as Filter + def where = "" -if (query != null) { - // We can use Groovy template engine to generate our custom SQL queries - where = "WHERE " + queryParser(query) - //println("Search WHERE clause is: ${where} + ${whereParams}") +if (filter != null) { + + def query = filter.accept(MapFilterVisitor.INSTANCE, null) + + if (query != null) { + // We can use Groovy template engine to generate our custom SQL queries + where = "WHERE " + queryParser(query) + //println("Search WHERE clause is: ${where} + ${whereParams}") + } } -switch ( objectClass ) { +switch ( objectClass.objectClassValue ) { case "schema_defs": sql.eachRow(""" @@ -159,27 +163,27 @@ switch ( objectClass ) { schema_defs s INNER JOIN db_types d ON s.db_type_id = d.id - """ + where, whereParams) { - - result.add([ - __NAME__:it.md5, - __UID__: it.db_type_id + '_' + it.short_code, - schema_def_id:it.id.toInteger(), - db_type_id:it.db_type_id.toInteger(), - context: it.context, - fragment: it.db_type_id + '_' + it.short_code, - ddl: it.ddl, - last_used:it.last_used, - minutes_since_last_used:it.minutes_since_last_used != null ? it.minutes_since_last_used.toInteger(): null, - short_code:it.short_code, - statement_separator:it.statement_separator, - simple_name:it.simple_name, - full_name:it.full_name, - execution_plan_prefix:it.execution_plan_prefix, - execution_plan_suffix:it.execution_plan_suffix, - execution_plan_xslt:it.execution_plan_xslt, - batch_separator:it.batch_separator - ]) + """ + where, whereParams) { row -> + + handler { + id row.md5 + uid row.db_type_id + '_' + row.short_code as String + attribute 'schema_def_id', row.id.toInteger() + attribute 'db_type_id', row.db_type_id.toInteger() + attribute 'context', row.context + attribute 'fragment', row.db_type_id + '_' + row.short_code + attribute 'ddl', row.ddl + attribute 'last_used', row.last_used + attribute 'minutes_since_last_used', (row.minutes_since_last_used != null ? row.minutes_since_last_used.toInteger(): null) + attribute 'short_code', row.short_code + attribute 'statement_separator', row.statement_separator + attribute 'simple_name', row.simple_name + attribute 'full_name', row.full_name + attribute 'execution_plan_prefix', row.execution_plan_prefix + attribute 'execution_plan_suffix', row.execution_plan_suffix + attribute 'execution_plan_xslt', row.execution_plan_xslt + attribute 'batch_separator', row.batch_separator + } } break @@ -198,18 +202,17 @@ switch ( objectClass ) { schema_defs s INNER JOIN queries q ON q.schema_def_id = s.id - """ + where, whereParams) { - - result.add([ - __NAME__:it.md5, - __UID__: it.db_type_id + '_' + it.short_code + '_' + it.id, - fragment: it.db_type_id + '_' + it.short_code + '_' + it.id, - md5: it.md5, - query_id:it.id.toInteger(), - schema_def_id:it.schema_def_id.toInteger(), - sql: it.sql, - statement_separator:it.statement_separator - ]) + """ + where, whereParams) { row -> + handler { + id row.md5 + uid (row.db_type_id + '_' + row.short_code + '_' + row.id) as String + attribute 'fragment', row.db_type_id + '_' + row.short_code + '_' + row.id + attribute 'md5', row.md5 + attribute 'query_id', row.id.toInteger() + attribute 'schema_def_id', row.schema_def_id.toInteger() + attribute 'sql', row.sql + attribute 'statement_separator', row.statement_separator + } } break @@ -229,20 +232,19 @@ switch ( objectClass ) { ${where} ORDER BY d.full_name - """, whereParams) { - - result.add([ - __NAME__:it.full_name, - __UID__: it.id.toInteger(), - context:it.context, - simple_name:it.simple_name, - className:it.jdbc_class_name, - sample_fragment: it.sample_fragment, - batch_separator:it.batch_separator - ]) + """, whereParams) { row -> + handler { + id row.full_name + uid row.id as String + attribute 'context', row.context + attribute 'simple_name', row.simple_name + attribute 'className', row.jdbc_class_name + attribute 'sample_fragment', row.sample_fragment + attribute 'batch_separator', row.batch_separator + } } break } -return result;
\ No newline at end of file +return new SearchResult() diff --git a/src/main/resources/tools/fiddles/SyncScript.groovy b/src/main/resources/tools/fiddles/SyncScript.groovy index 6e14700..b8091d2 100644 --- a/src/main/resources/tools/fiddles/SyncScript.groovy +++ b/src/main/resources/tools/fiddles/SyncScript.groovy @@ -23,24 +23,24 @@ * * $Id$ */ -import groovy.sql.Sql; -import groovy.sql.DataSet; +import groovy.sql.Sql +import groovy.sql.DataSet +import org.forgerock.openicf.misc.scriptedcommon.OperationType // Parameters: // The connector sends the following: // connection: handler to the SQL connection // objectClass: a String describing the Object class (__ACCOUNT__ / __GROUP__ / other) -// action: a string describing the action ("SYNC" or "GET_LATEST_SYNC_TOKEN" here) // log: a handler to the Log facility -// options: a handler to the OperationOptions Map (null if action = "GET_LATEST_SYNC_TOKEN") -// token: a handler to an Object representing the sync token (null if action = "GET_LATEST_SYNC_TOKEN") +// options: a handler to the OperationOptions Map (null if operation = "GET_LATEST_SYNC_TOKEN") +// token: a handler to an Object representing the sync token (null if operation = "GET_LATEST_SYNC_TOKEN") // // // Returns: -// if action = "GET_LATEST_SYNC_TOKEN", it must return an object representing the last known +// if operation = "GET_LATEST_SYNC_TOKEN", it must return an object representing the last known // sync token for the corresponding ObjectClass // -// if action = "SYNC": +// if operation = "SYNC": // A list of Maps . Each map describing one update: // Map should look like the following: // @@ -53,13 +53,13 @@ import groovy.sql.DataSet; // "attributes":Map<String,List> of attributes name/values // ] -log.info("Entering "+action+" Script"); -def sql = new Sql(connection); +def sql = new Sql(connection) +def operation = operation as OperationType switch ( objectClass ) { case "schema_defs": - if (action.equalsIgnoreCase("GET_LATEST_SYNC_TOKEN")) { + if (operation.equalsIgnoreCase(OperationType.GET_LATEST_SYNC_TOKEN)) { row = sql.firstRow(""" SELECT @@ -67,10 +67,10 @@ switch ( objectClass ) { FROM schema_defs """) - println ("Sync token found: " + row["latest_used"]) + //println ("Sync token found: " + row["latest_used"]) return row["latest_used"] - } else if (action.equalsIgnoreCase("SYNC")) { + } else if (operation.equalsIgnoreCase(OperationType.SYNC)) { def result = [] sql.eachRow(""" @@ -88,7 +88,7 @@ switch ( objectClass ) { last_used > ? """, [Date.parse("yyyy-MM-dd HH:mm:ss.S", token).toTimestamp()]) { - println ("Found record: " + it.db_type_id + '_' + it.short_code) + //println ("Found record: " + it.db_type_id + '_' + it.short_code) result.add([ operation: "CREATE_OR_UPDATE", @@ -109,8 +109,8 @@ switch ( objectClass ) { println result return result - } else { // action not implemented - log.error("Sync script: action '"+action+"' is not implemented in this script") + } else { // operation not implemented + log.error("Sync script: operation '"+operation+"' is not implemented in this script") return null; } diff --git a/src/main/resources/tools/fiddles/TestScript.groovy b/src/main/resources/tools/fiddles/TestScript.groovy index b5c711a..2caf204 100644 --- a/src/main/resources/tools/fiddles/TestScript.groovy +++ b/src/main/resources/tools/fiddles/TestScript.groovy @@ -29,10 +29,8 @@ import groovy.sql.DataSet; // Parameters: // The connector sends the following: // connection: handler to the SQL connection -// action: a string describing the action ("TEST" here) // log: a handler to the Log facility -log.info("Entering "+action+" Script"); def sql = new Sql(connection); sql.eachRow("select count(id) as numTypes from db_types", { println it.numTypes} ); diff --git a/src/main/resources/tools/fiddles/UpdateScript.groovy b/src/main/resources/tools/fiddles/UpdateScript.groovy index a754c61..45654b8 100644 --- a/src/main/resources/tools/fiddles/UpdateScript.groovy +++ b/src/main/resources/tools/fiddles/UpdateScript.groovy @@ -23,40 +23,22 @@ * * $Id$ */ -import groovy.sql.Sql; -import groovy.sql.DataSet; +import groovy.sql.Sql +import groovy.sql.DataSet +import org.forgerock.openicf.misc.scriptedcommon.OperationType +import org.identityconnectors.framework.common.exceptions.ConnectorException +import org.identityconnectors.framework.common.objects.AttributesAccessor -// Parameters: -// The connector sends us the following: -// connection : SQL connection -// -// action: String correponding to the action (UPDATE/ADD_ATTRIBUTE_VALUES/REMOVE_ATTRIBUTE_VALUES) -// - UPDATE : For each input attribute, replace all of the current values of that attribute -// in the target object with the values of that attribute. -// - ADD_ATTRIBUTE_VALUES: For each attribute that the input set contains, add to the current values -// of that attribute in the target object all of the values of that attribute in the input set. -// - REMOVE_ATTRIBUTE_VALUES: For each attribute that the input set contains, remove from the current values -// of that attribute in the target object any value that matches one of the values of the attribute from the input set. +def operation = operation as OperationType +def sql = new Sql(connection) +def fragment_parts = uid.uidValue.split("_") +def updateAttributes = new AttributesAccessor(attributes as Set<Attribute>) -// log: a handler to the Log facility -// -// objectClass: a String describing the Object class (__ACCOUNT__ / __GROUP__ / other) -// -// uid: a String representing the entry uid -// -// attributes: an Attribute Map, containg the <String> attribute name as a key -// and the <List> attribute value(s) as value. -// -// password: password string, clear text (only for UPDATE) -// -// options: a handler to the OperationOptions Map +assert fragment_parts.size() == 2 -log.info("Entering "+action+" Script"); -def sql = new Sql(connection); - -switch ( action ) { - case "UPDATE": - switch ( objectClass ) { +switch ( operation ) { + case OperationType.UPDATE: + switch ( objectClass.objectClassValue ) { case "schema_defs": sql.executeUpdate(""" @@ -65,22 +47,27 @@ switch ( action ) { SET last_used = ? WHERE - (s.db_type_id || '_' || s.short_code) = ? + s.db_type_id = ? AND + s.short_code = ? """, [ - Date.parse("yyyy-MM-dd HH:mm:ss.S", attributes.last_used[0]).toTimestamp(), - uid + Date.parse("yyyy-MM-dd HH:mm:ss.S", updateAttributes.findString("last_used")).toTimestamp(), + fragment_parts[0].toInteger(), + fragment_parts[1] ] ); break - - default: - uid; } break + case OperationType.ADD_ATTRIBUTE_VALUES: + throw new UnsupportedOperationException(operation.name() + " operation of type:" + + objectClass.objectClassValue + " is not supported.") + case OperationType.REMOVE_ATTRIBUTE_VALUES: + throw new UnsupportedOperationException(operation.name() + " operation of type:" + + objectClass.objectClassValue + " is not supported.") default: - uid + throw new ConnectorException("UpdateScript can not handle operation:" + operation.name()) } -return uid;
\ No newline at end of file +return uid
\ No newline at end of file diff --git a/src/main/resources/tools/hosts/CreateScript.groovy b/src/main/resources/tools/hosts/CreateScript.groovy index 8e3078a..0f902bd 100644 --- a/src/main/resources/tools/hosts/CreateScript.groovy +++ b/src/main/resources/tools/hosts/CreateScript.groovy @@ -24,24 +24,15 @@ * $Id$ */ -import groovy.sql.Sql; -import groovy.sql.DataSet; -import java.util.regex.Pattern; - -import org.identityconnectors.framework.common.exceptions.ConnectorException; -// Parameters: -// The connector sends us the following: -// connection : SQL connection -// action: String correponding to the action ("CREATE" here) -// log: a handler to the Log facility -// objectClass: a String describing the Object class (__ACCOUNT__ / __GROUP__ / other) -// id: The entry identifier (OpenICF "Name" atribute. (most often matches the uid) -// attributes: an Attribute Map, containg the <String> attribute name as a key -// and the <List> attribute value(s) as value. -// password: password string, clear text -// options: a handler to the OperationOptions Map - -log.info("Entering "+action+" Script"); +import groovy.sql.Sql +import groovy.sql.DataSet +import java.util.regex.Pattern +import org.identityconnectors.framework.common.objects.AttributesAccessor +import org.identityconnectors.framework.common.exceptions.ConnectorException +import org.identityconnectors.framework.common.objects.Uid + + +def createAttributes = new AttributesAccessor(attributes as Set<Attribute>) def sql = new Sql(connection) @@ -71,15 +62,13 @@ def findAvailableHost = { db_type_id -> return row.id } -//Create must return UID. Let's return the name for now. - -switch ( objectClass ) { +switch ( objectClass.objectClassValue ) { case "databases": String delimiter = (char) 7; char newline = 10; char carrageReturn = 13; - def host_id = findAvailableHost(attributes.db_type_id.get(0)) + def host_id = findAvailableHost(createAttributes.findInteger("db_type_id")) sql.eachRow("""\ SELECT @@ -122,18 +111,18 @@ switch ( objectClass ) { } populatedUrl = it.jdbc_url_template.replaceAll("#databaseName#", id) - hostConnection = Sql.newInstance(populatedUrl, attributes.username.get(0), attributes.pw.get(0), it.jdbc_class_name) + hostConnection = Sql.newInstance(populatedUrl, createAttributes.findString("username"), createAttributes.findString("pw"), it.jdbc_class_name) hostConnection.withStatement { it.queryTimeout = 10 } def ddl = "" - if (attributes.ddl) { - ddl = attributes.ddl.get(0) + if (createAttributes.findString("ddl")) { + ddl = createAttributes.findString("ddl") } def statement_separator = ";" - if (attributes.statement_separator) { - statement_separator = attributes.statement_separator.get(0) + if (createAttributes.findString("statement_separator")) { + statement_separator = createAttributes.findString("statement_separator") } if (batch_separator && batch_separator.size()) { @@ -163,4 +152,4 @@ switch ( objectClass ) { break } -return id; +return new Uid(id as String) diff --git a/src/main/resources/tools/hosts/DeleteScript.groovy b/src/main/resources/tools/hosts/DeleteScript.groovy index 322a63a..18dfb4b 100644 --- a/src/main/resources/tools/hosts/DeleteScript.groovy +++ b/src/main/resources/tools/hosts/DeleteScript.groovy @@ -31,7 +31,6 @@ import groovy.sql.DataSet; // Parameters: // The connector sends the following: // connection: handler to the SQL connection -// action: a string describing the action ("DELETE" here) // log: a handler to the Log facility // objectClass: a String describing the Object class (__ACCOUNT__ / __GROUP__ / other) // options: a handler to the OperationOptions Map @@ -41,13 +40,13 @@ def sql = new Sql(connection) def result = [] assert uid != null -switch ( objectClass ) { +switch ( objectClass.objectClassValue ) { case "databases": String delimiter = (char) 7; char newline = 10; char carrageReturn = 13; - def dbTypeMatcher = uid =~ /^db_(\d+)_.*$/; + def dbTypeMatcher = uid.uidValue =~ /^db_(\d+)_.*$/; def db_type_id = dbTypeMatcher[0][1].toInteger(); sql.eachRow("""\ @@ -73,7 +72,7 @@ switch ( objectClass ) { def host_id = it.host_id def hostConnection = Sql.newInstance(populatedUrl, it.admin_username, it.admin_password, it.jdbc_class_name); - def drop_script = it.drop_script_template.replaceAll('#databaseName#', uid.replaceFirst("db_", "")) + def drop_script = it.drop_script_template.replaceAll('#databaseName#', uid.uidValue.replaceFirst("db_", "")) if (it.batch_separator && it.batch_separator.size()) { drop_script = drop_script.replaceAll(Pattern.compile(newline + it.batch_separator + carrageReturn + "?(" + newline + "|\$)", Pattern.CASE_INSENSITIVE), delimiter) diff --git a/src/main/resources/tools/hosts/SearchScript.groovy b/src/main/resources/tools/hosts/SearchScript.groovy index 7a04044..ba58c9b 100644 --- a/src/main/resources/tools/hosts/SearchScript.groovy +++ b/src/main/resources/tools/hosts/SearchScript.groovy @@ -1,5 +1,7 @@ -import groovy.sql.Sql; -import groovy.sql.DataSet; +import groovy.sql.Sql +import groovy.sql.DataSet +import org.identityconnectors.framework.common.objects.filter.Filter +import org.forgerock.openicf.misc.scriptedcommon.MapFilterVisitor def findDatabase = { schema_name, connection -> @@ -67,50 +69,51 @@ import groovy.sql.DataSet; } def hostConnection = Sql.newInstance(populatedUrl, it.admin_username, it.admin_password, it.jdbc_class_name) - hostConnection.eachRow(it.list_database_script + schemaNameWhere, schemaNameWhereParams) { - def name = it.getAt(0) + hostConnection.eachRow(it.list_database_script + schemaNameWhere, schemaNameWhereParams) { row -> + + def name = row.getAt(0) def short_code_matcher = name =~ /^db_\d+_(.*)$/ def short_code = short_code_matcher[0][1] populatedUrl = jdbc_url_template.replace("#databaseName#", name) - result.add([ - __UID__:name, - __NAME__:name, - db_type_id: db_type_id, - jdbc_class_name: jdbc_class_name, - simple_name: simple_name, - full_name: full_name, - jdbc_url: populatedUrl, - username: "user_" + db_type_id + "_" + short_code, - pw: db_type_id + "_" + short_code - ]) + handler { + uid name as String + id name + attribute 'db_type_id', db_type_id + attribute 'jdbc_class_name', jdbc_class_name + attribute 'simple_name', simple_name + attribute 'full_name', full_name + attribute 'jdbc_url', populatedUrl + attribute 'username', "user_" + db_type_id + "_" + short_code + attribute 'pw', db_type_id + "_" + short_code + } } hostConnection.close() } sql.close() - return result - } +def schema_name = null +def filter = filter as Filter -def result = [] -def schema_name = null +if (filter != null) { -// The only query we support is on the schema_name -if (query != null && (query.get("left") instanceof String) && (query.get("left") == "__UID__" || query.get("left") == "__NAME__")) { - schema_name = query.get("right") -} + def query = filter.accept(MapFilterVisitor.INSTANCE, null) -switch ( objectClass ) { + // The only query we support is on the schema_name + if (query != null && (query.get("left") instanceof String) && (query.get("left") == "__UID__" || query.get("left") == "__NAME__")) { + schema_name = query.get("right") + } + +} +switch ( objectClass.objectClassValue ) { case "databases": - result = findDatabase(schema_name, connection) + findDatabase(schema_name, connection) break - - default: - result } -return result
\ No newline at end of file + +return new SearchResult()
\ No newline at end of file diff --git a/src/main/resources/tools/hosts/SyncScript.groovy b/src/main/resources/tools/hosts/SyncScript.groovy deleted file mode 100644 index 2eff9f9..0000000 --- a/src/main/resources/tools/hosts/SyncScript.groovy +++ /dev/null @@ -1,87 +0,0 @@ -/* - * - * Copyright (c) 2010 ForgeRock Inc. All Rights Reserved - * - * The contents of this file are subject to the terms - * of the Common Development and Distribution License - * (the License). You may not use this file except in - * compliance with the License. - * - * You can obtain a copy of the License at - * http://www.opensource.org/licenses/cddl1.php or - * OpenIDM/legal/CDDLv1.0.txt - * See the License for the specific language governing - * permission and limitations under the License. - * - * When distributing Covered Code, include this CDDL - * Header Notice in each file and include the License file - * at OpenIDM/legal/CDDLv1.0.txt. - * If applicable, add the following below the CDDL Header, - * with the fields enclosed by brackets [] replaced by - * your own identifying information: - * "Portions Copyrighted 2010 [name of copyright owner]" - * - * $Id$ - */ -import groovy.sql.Sql; -import groovy.sql.DataSet; - -// Parameters: -// The connector sends the following: -// connection: handler to the SQL connection -// objectClass: a String describing the Object class (__ACCOUNT__ / __GROUP__ / other) -// action: a string describing the action ("SYNC" or "GET_LATEST_SYNC_TOKEN" here) -// log: a handler to the Log facility -// options: a handler to the OperationOptions Map (null if action = "GET_LATEST_SYNC_TOKEN") -// token: a handler to an Object representing the sync token (null if action = "GET_LATEST_SYNC_TOKEN") -// -// -// Returns: -// if action = "GET_LATEST_SYNC_TOKEN", it must return an object representing the last known -// sync token for the corresponding ObjectClass -// -// if action = "SYNC": -// A list of Maps . Each map describing one update: -// Map should look like the following: -// -// [ -// "token": <Object> token object (could be Integer, Date, String) , [!! could be null] -// "operation":<String> ("CREATE_OR_UPDATE"|"DELETE"), -// "uid":<String> uid (uid of the entry) , -// "previousUid":<String> prevuid (This is for rename ops) , -// "password":<String> password (optional... allows to pass clear text password if needed), -// "attributes":Map<String,List> of attributes name/values -// ] - -log.info("Entering "+action+" Script"); -def sql = new Sql(connection); - -if (action.equalsIgnoreCase("GET_LATEST_SYNC_TOKEN")) { - row = sql.firstRow("select timestamp from Users order by timestamp desc") - log.ok("Get Latest Sync Token script: last token is: "+row["timestamp"]) - // We don't wanna return the java.sql.Timestamp, it is not a supported data type - // Get the 'long' version - return row["timestamp"].getTime(); -} - -else if (action.equalsIgnoreCase("SYNC")) { - def result = [] - def tstamp = null - if (token != null){ - tstamp = new java.sql.Timestamp(token) - } - else{ - def today= new Date() - tstamp = new java.sql.Timestamp(today.time) - } - - sql.eachRow("select * from Users where timestamp > ${tstamp}", - {result.add([operation:"CREATE_OR_UPDATE", uid:it.uid, token:it.timestamp.getTime(), attributes:[firstname:it.firstname, lastname:it.lastname, email:it.email]])} - ) - log.ok("Sync script: found "+result.size()+" events to sync") - return result; - } -else { // action not implemented - log.error("Sync script: action '"+action+"' is not implemented in this script") - return null; -}
\ No newline at end of file diff --git a/src/main/resources/tools/hosts/TestScript.groovy b/src/main/resources/tools/hosts/TestScript.groovy index f188448..37ef011 100644 --- a/src/main/resources/tools/hosts/TestScript.groovy +++ b/src/main/resources/tools/hosts/TestScript.groovy @@ -23,23 +23,30 @@ * * $Id$ */ -import groovy.sql.Sql; -import groovy.sql.DataSet; +import groovy.sql.Sql +import groovy.sql.DataSet // Parameters: // The connector sends the following: // connection: handler to the SQL connection -// action: a string describing the action ("TEST" here) // log: a handler to the Log facility -log.info("Entering "+action+" Script"); -def sql = new Sql(connection); - -sql.eachRow("select hosts.jdbc_url_template from db_types inner join hosts on db_types.id = hosts.db_type_id WHERE db_types.full_name = 'PostgreSQL 9.1.4'") { - - def testUrl = it.jdbc_url_template.replaceAll("#databaseName#", "postgres"); - Sql.newInstance(testUrl, "postgres", "password", "org.postgresql.Driver") +def sql = new Sql(connection) +sql.eachRow(""" + SELECT + hosts.jdbc_url_template, + hosts.default_database, + hosts.admin_username, + hosts.admin_password, + db_types.jdbc_class_name + FROM + db_types + INNER JOIN hosts ON + db_types.id = hosts.db_type_id +""") { + def testUrl = it.jdbc_url_template.replaceAll("#databaseName#", it.default_database) + def testConnection = Sql.newInstance(testUrl, it.admin_username, it.admin_password, it.jdbc_class_name) } diff --git a/src/main/resources/tools/hosts/UpdateScript.groovy b/src/main/resources/tools/hosts/UpdateScript.groovy deleted file mode 100644 index 9d17f13..0000000 --- a/src/main/resources/tools/hosts/UpdateScript.groovy +++ /dev/null @@ -1,75 +0,0 @@ -/* - * - * Copyright (c) 2010 ForgeRock Inc. All Rights Reserved - * - * The contents of this file are subject to the terms - * of the Common Development and Distribution License - * (the License). You may not use this file except in - * compliance with the License. - * - * You can obtain a copy of the License at - * http://www.opensource.org/licenses/cddl1.php or - * OpenIDM/legal/CDDLv1.0.txt - * See the License for the specific language governing - * permission and limitations under the License. - * - * When distributing Covered Code, include this CDDL - * Header Notice in each file and include the License file - * at OpenIDM/legal/CDDLv1.0.txt. - * If applicable, add the following below the CDDL Header, - * with the fields enclosed by brackets [] replaced by - * your own identifying information: - * "Portions Copyrighted 2010 [name of copyright owner]" - * - * $Id$ - */ -import groovy.sql.Sql; -import groovy.sql.DataSet; - -// Parameters: -// The connector sends us the following: -// connection : SQL connection -// -// action: String correponding to the action (UPDATE/ADD_ATTRIBUTE_VALUES/REMOVE_ATTRIBUTE_VALUES) -// - UPDATE : For each input attribute, replace all of the current values of that attribute -// in the target object with the values of that attribute. -// - ADD_ATTRIBUTE_VALUES: For each attribute that the input set contains, add to the current values -// of that attribute in the target object all of the values of that attribute in the input set. -// - REMOVE_ATTRIBUTE_VALUES: For each attribute that the input set contains, remove from the current values -// of that attribute in the target object any value that matches one of the values of the attribute from the input set. - -// log: a handler to the Log facility -// -// objectClass: a String describing the Object class (__ACCOUNT__ / __GROUP__ / other) -// -// uid: a String representing the entry uid -// -// attributes: an Attribute Map, containg the <String> attribute name as a key -// and the <List> attribute value(s) as value. -// -// password: password string, clear text (only for UPDATE) -// -// options: a handler to the OperationOptions Map - -log.info("Entering "+action+" Script"); -def sql = new Sql(connection); - - -switch ( action ) { - case "UPDATE": - switch ( objectClass ) { - - case "schema_defs": - sql.executeUpdate("UPDATE schema_defs set last_used = ? where (s.db_type_id || '_' || s.short_code) = ?", [attributes.get("last_used").get(0), uid]); - break - - default: - uid; - } - break - - default: - uid -} - -return uid;
\ No newline at end of file |