diff --git a/sqldev/pom.xml b/sqldev/pom.xml
index 4be8a609..41261000 100644
--- a/sqldev/pom.xml
+++ b/sqldev/pom.xml
@@ -5,7 +5,7 @@
org.utplsql
org.utplsql.sqldev
- 0.7.0-SNAPSHOT
+ 0.7.0
bundle
UTF-8
diff --git a/sqldev/src/main/java/org/utplsql/sqldev/dal/UtplsqlDao.xtend b/sqldev/src/main/java/org/utplsql/sqldev/dal/UtplsqlDao.xtend
index 87e7c5e6..e7a12a50 100644
--- a/sqldev/src/main/java/org/utplsql/sqldev/dal/UtplsqlDao.xtend
+++ b/sqldev/src/main/java/org/utplsql/sqldev/dal/UtplsqlDao.xtend
@@ -20,6 +20,7 @@ import java.sql.Connection
import java.sql.SQLException
import java.sql.Types
import java.util.List
+import java.util.regex.Pattern
import org.oddgen.sqldev.generators.model.Node
import org.springframework.dao.DataAccessException
import org.springframework.dao.EmptyResultDataAccessException
@@ -31,19 +32,81 @@ import org.utplsql.sqldev.model.ut.Annotation
import org.utplsql.sqldev.model.ut.OutputLines
class UtplsqlDao {
- public static val UTPLSQL_PACKAGE_NAME = "UT"
+ public static val UTPLSQL_PACKAGE_NAME = "UT"
+ public static val FIRST_VERSION_WITH_INTERNAL_ANNOTATION_API = 3000004
+ public static val FIRST_VERSION_WITH_ANNOTATION_API = 3001003
var Connection conn
var JdbcTemplate jdbcTemplate
// cache fields
Boolean cachedDbaViewAccessible
String cachedUtplsqlSchema
- Boolean cachedUtAnnotationManagerInstalled
+ String cachedUtPlsqlVersion
new(Connection connection) {
conn = connection
jdbcTemplate = new JdbcTemplate(new SingleConnectionDataSource(conn, true))
}
+ /**
+ * used for testing purposes only
+ */
+ def setUtPlsqlVersion(String utPlsqlVersion) {
+ cachedUtPlsqlVersion = utPlsqlVersion
+ }
+
+ /**
+ * returns a normalized utPLSQL version in format 9.9.9
+ */
+ def String normalizedUtPlsqlVersion() {
+ val p = Pattern.compile("(\\d+\\.\\d+\\.\\d+)")
+ val version = getUtPlsqlVersion()
+ val m = p.matcher(version)
+ if (m.find) {
+ return m.group(0)
+ } else {
+ return "0.0.0"
+ }
+ }
+
+ /**
+ * get version as number, e.g. 3001004
+ */
+ def int normalizedUtPlsqlVersionNumber() {
+ val p = Pattern.compile("(\\d+)")
+ val version = normalizedUtPlsqlVersion()
+ val m = p.matcher(version)
+ m.find
+ val major = m.group
+ m.find
+ val minor = m.group
+ m.find
+ val bugfix = m.group
+ val versionNumber = Integer.valueOf(major)*1000000 + Integer.valueOf(minor)*1000 + Integer.valueOf(bugfix)
+ return versionNumber
+ }
+
+ /**
+ * gets version of installed utPLSQL
+ */
+ def String getUtPlsqlVersion() {
+ if (cachedUtPlsqlVersion === null) {
+ val sql = '''
+ BEGIN
+ ? := ut.version;
+ END;
+ '''
+ cachedUtPlsqlVersion = jdbcTemplate.execute(sql, new CallableStatementCallback() {
+ override String doInCallableStatement(CallableStatement cs) throws SQLException, DataAccessException {
+ cs.registerOutParameter(1, Types.VARCHAR);
+ cs.execute
+ val version = cs.getString(1)
+ return version
+ }
+ })
+ }
+ return cachedUtPlsqlVersion
+ }
+
def boolean isDbaViewAccessible() {
if (cachedDbaViewAccessible === null) {
try {
@@ -96,21 +159,7 @@ class UtplsqlDao {
* @throws DataAccessException if there is a problem
*/
def boolean isUtAnnotationManagerInstalled() {
- if (cachedUtAnnotationManagerInstalled === null) {
- cachedUtAnnotationManagerInstalled = false
- if (utplsqlSchema !== null) {
- val sql = '''
- SELECT count(*)
- FROM «IF dbaViewAccessible»dba«ELSE»all«ENDIF»_objects
- WHERE owner = '«utplsqlSchema»'
- AND object_type = 'PACKAGE'
- AND object_name = 'UT_ANNOTATION_MANAGER'
- '''
- val found = jdbcTemplate.queryForObject(sql, Integer)
- cachedUtAnnotationManagerInstalled = found == 1
- }
- }
- return cachedUtAnnotationManagerInstalled
+ return normalizedUtPlsqlVersionNumber >= FIRST_VERSION_WITH_INTERNAL_ANNOTATION_API
}
/**
@@ -124,31 +173,44 @@ class UtplsqlDao {
*/
def boolean containsUtplsqlTest(String owner, String objectName, String subobjectName) {
try {
- val sql = '''
- SELECT count(
- CASE
- WHEN a.name = 'test'
- AND (upper(a.subobject_name) = upper(?) OR ? IS NULL)
- THEN
- 1
- ELSE
- NULL
- END
- )
- FROM TABLE(«utplsqlSchema».ut_annotation_manager.get_annotated_objects(upper(?), 'PACKAGE')) o
- CROSS JOIN TABLE(o.annotations) a
- WHERE (o.object_name = upper(?) OR ? IS NULL)
- AND a.name IN ('test', 'suite')
- HAVING count(
- CASE
- WHEN a.name = 'suite' THEN
- 1
- ELSE
- NULL
- END
- ) > 0
- '''
- val found = jdbcTemplate.queryForObject(sql, Integer, #[subobjectName, subobjectName, owner, objectName, objectName])
+ var Integer found
+ if (normalizedUtPlsqlVersionNumber >= FIRST_VERSION_WITH_ANNOTATION_API) {
+ // using API available since 3.1.3
+ val sql = '''
+ SELECT count(*)
+ FROM TABLE(ut_runner.get_suites_info(upper(?), upper(?)))
+ WHERE item_type = 'UT_TEST'
+ AND (item_name = upper(?) or ? IS NULL)
+ '''
+ found = jdbcTemplate.queryForObject(sql, Integer, #[owner, objectName, subobjectName, subobjectName])
+ } else {
+ // using internal API (deprecated)
+ val sql = '''
+ SELECT count(
+ CASE
+ WHEN a.name = 'test'
+ AND (upper(a.subobject_name) = upper(?) OR ? IS NULL)
+ THEN
+ 1
+ ELSE
+ NULL
+ END
+ )
+ FROM TABLE(«utplsqlSchema».ut_annotation_manager.get_annotated_objects(upper(?), 'PACKAGE')) o
+ CROSS JOIN TABLE(o.annotations) a
+ WHERE (o.object_name = upper(?) OR ? IS NULL)
+ AND a.name IN ('test', 'suite')
+ HAVING count(
+ CASE
+ WHEN a.name = 'suite' THEN
+ 1
+ ELSE
+ NULL
+ END
+ ) > 0
+ '''
+ found = jdbcTemplate.queryForObject(sql, Integer, #[subobjectName, subobjectName, owner, objectName, objectName])
+ }
return found > 0
} catch (EmptyResultDataAccessException e) {
return false
@@ -172,12 +234,30 @@ class UtplsqlDao {
* @throws DataAccessException if a utPLSQL version less than 3.0.4 is installed or if there are other problems
*/
def List annotations(String owner, String objectName) {
- val sql = '''
- SELECT o.object_owner, o.object_type, o.object_name, a.name, a.text, a.subobject_name
- FROM TABLE(«utplsqlSchema».ut_annotation_manager.get_annotated_objects(upper(?), 'PACKAGE')) o
- CROSS JOIN TABLE(o.annotations) a
- WHERE o.object_name = upper(?)
- '''
+ var String sql
+ if (normalizedUtPlsqlVersionNumber >= FIRST_VERSION_WITH_ANNOTATION_API) {
+ // using API available since 3.1.3
+ sql = '''
+ SELECT object_owner,
+ object_name,
+ lower(substr(item_type, 4)) AS name,
+ item_name as subobject_name
+ FROM TABLE(ut_runner.get_suites_info(upper(?), upper(?)))
+ '''
+
+ } else {
+ // using internal API (deprecated)
+ sql = '''
+ SELECT o.object_owner,
+ o.object_name,
+ a.name,
+ a.text,
+ coalesce(upper(a.subobject_name), o.object_name) AS subobject_name
+ FROM TABLE(«utplsqlSchema».ut_annotation_manager.get_annotated_objects(upper(?), 'PACKAGE')) o
+ CROSS JOIN TABLE(o.annotations) a
+ WHERE o.object_name = upper(?)
+ '''
+ }
val result = jdbcTemplate.query(sql, new BeanPropertyRowMapper(Annotation), #[owner, objectName])
return result
}
@@ -222,21 +302,42 @@ class UtplsqlDao {
def List testables(String objectType) {
var String sql;
if (objectType == "PACKAGE") {
- sql = '''
- SELECT DISTINCT
- object_type || '.' || object_name AS id,
- object_type AS parent_id,
- 1 AS leaf,
- 1 AS generatable,
- 1 AS multiselectable
- FROM user_procedures
- WHERE object_type = ?
- AND procedure_name IS NOT NULL
- AND object_name NOT IN (
- SELECT object_name
- FROM TABLE(«utplsqlSchema».ut_annotation_manager.get_annotated_objects(USER, 'PACKAGE'))
- )
- '''
+ if (normalizedUtPlsqlVersionNumber >= FIRST_VERSION_WITH_ANNOTATION_API) {
+ // using API available since 3.1.3
+ sql = '''
+ SELECT DISTINCT
+ object_type || '.' || object_name AS id,
+ object_type AS parent_id,
+ 1 AS leaf,
+ 1 AS generatable,
+ 1 AS multiselectable
+ FROM user_procedures
+ WHERE object_type = ?
+ AND procedure_name IS NOT NULL
+ AND object_name NOT IN (
+ SELECT object_name
+ FROM TABLE(ut_runner.get_suites_info(USER))
+ WHERE item_type = 'UT_SUITE'
+ )
+ '''
+ } else {
+ // using internal API (deprecated)
+ sql = '''
+ SELECT DISTINCT
+ object_type || '.' || object_name AS id,
+ object_type AS parent_id,
+ 1 AS leaf,
+ 1 AS generatable,
+ 1 AS multiselectable
+ FROM user_procedures
+ WHERE object_type = ?
+ AND procedure_name IS NOT NULL
+ AND object_name NOT IN (
+ SELECT object_name
+ FROM TABLE(«utplsqlSchema».ut_annotation_manager.get_annotated_objects(USER, 'PACKAGE'))
+ )
+ '''
+ }
}
else if (objectType == "TYPE") {
sql = '''
@@ -278,202 +379,306 @@ class UtplsqlDao {
* @throws DataAccessException if there is a problem
*/
def List runnables() {
- var sql = '''
- WITH
- base AS (
- SELECT rownum AS an_id,
- o.object_owner,
- o.object_type,
- o.object_name,
- lower(a.name) AS name,
- a.text,
- a.subobject_name
- FROM table(«utplsqlSchema».ut_annotation_manager.get_annotated_objects(user, 'PACKAGE')) o
- CROSS JOIN table(o.annotations) a
- WHERE lower(a.name) in ('suite', 'suitepath', 'endcontext', 'test')
- OR lower(a.name) = 'context' AND regexp_like(text, '(\w+)(\.\w+)*')
- ),
- suite AS (
- SELECT object_owner, object_type, object_name, text AS suite_description
- FROM base
- WHERE name = 'suite'
- ),
- suitepath as (
- SELECT object_owner, object_type, object_name, lower(text) AS suitepath
- FROM base
- WHERE name = 'suitepath'
- ),
- context_base AS (
- SELECT an_id,
- lead(an_id) over (partition by object_owner, object_type, object_name order by an_id) AS an_id_end,
- object_owner,
- object_type,
- object_name,
- name,
- lead(name) over (partition by object_owner, object_type, object_name order by an_id) AS name_end,
- text as context
- FROM base
- WHERE name IN ('context', 'endcontext')
- ),
- context as (
- SELECT an_id, an_id_end, object_owner, object_type, object_name, context
- FROM context_base
- WHERE name = 'context'
- AND name_end = 'endcontext'
- ),
- test AS (
- SELECT b.an_id,
- b.object_owner,
- b.object_type,
- b.object_name,
- p.suitepath,
- c.context,
- b.subobject_name,
- b.text AS test_description
- FROM base b
- LEFT JOIN suitepath p
- ON p.object_owner = b.object_owner
- AND p.object_type = b.object_type
- AND p.object_name = b.object_name
- LEFT JOIN context c
- ON c.object_owner = b.object_owner
- AND c.object_type = b.object_type
- AND c.object_name = b.object_name
- AND b.an_id BETWEEN c.an_id AND c.an_id_end
- WHERE name = 'test'
- AND (b.object_owner, b.object_type, b.object_name) IN (
- SELECT object_owner, object_type, object_name
- FROM suite
- )
- ),
- suite_tree AS (
- SELECT null AS parent_id,
- 'SUITE' AS id,
- 'All Suites' AS name,
- 'All utPLSQL test suites' AS description,
- 'PACKAGE_FOLDER_ICON' AS iconName,
- 'No' AS leaf,
- 'Yes' AS generatable,
- 'Yes' AS multiselectable,
- 'Yes' AS relevant
- FROM dual
- UNION ALL
- SELECT DISTINCT
- 'SUITE' AS parent_id,
- object_owner || '.' || object_name AS id,
- object_name AS name,
- null AS description,
- 'PACKAGE_ICON' AS iconName,
- 'No' AS leaf,
- 'Yes' AS generatable,
- 'Yes' AS multiselectable,
- 'Yes' AS relevant
- FROM test
- UNION ALL
- SELECT object_owner || '.' || object_name AS parent_id,
- object_owner || '.' || object_name || '.' || subobject_name AS id,
- subobject_name AS name,
- null AS description,
- 'PROCEDURE_ICON' AS iconName,
- 'Yes' AS leaf,
- 'Yes' AS generatable,
- 'Yes' AS multiselectable,
- 'Yes' AS relevant
- FROM test
- ),
- suitepath_base AS (
- SELECT DISTINCT
- suitepath
- FROM suitepath
- ),
- gen AS (
- SELECT rownum AS pos
- FROM xmltable('1 to 100')
- ),
- suitepath_part AS (
- SELECT DISTINCT
- substr(suitepath, 1, instr(suitepath || '.', '.', 1, g.pos) -1) AS suitepath
- FROM suitepath_base b
- JOIN gen g
- ON g.pos <= regexp_count(suitepath, '\w+')
- ),
- suitepath_tree AS (
- SELECT NULL AS parent_id,
- 'SUITEPATH' AS id,
- 'All Suitepaths' AS name,
- 'All utPLSQL test suitepathes' AS description,
- 'FOLDER_ICON' AS iconName,
- 'No' AS leaf,
- 'Yes' AS generatable,
- 'Yes' AS multiselectable,
- 'Yes' AS relevant
- FROM dual
- UNION ALL
- SELECT CASE
- WHEN regexp_replace(suitepath,'\.?\w+$','') IS NULL THEN
- 'SUITEPATH'
- ELSE
- USER || ':' || regexp_replace(suitepath,'\.?\w+$','')
- END AS parent_id,
- USER || ':' || suitepath AS id,
- regexp_substr(suitepath, '\.?(\w+$)', 1, 1, NULL, 1) AS name,
- null AS description,
- 'FOLDER_ICON' AS iconName,
- 'No' AS leaf,
- 'Yes' AS generatable,
- 'Yes' AS multiselectable,
- 'Yes' AS relevant
- FROM suitepath_part
- UNION ALL
- SELECT DISTINCT
- object_owner || ':' || suitepath AS parent_id,
- object_owner || ':' || suitepath || '.' || object_name AS id,
- object_name AS name,
- null AS description,
- 'PACKAGE_ICON' AS iconName,
- 'No' AS leaf,
- 'Yes' AS generatable,
- 'Yes' AS multiselectable,
- 'Yes' AS relevant
- FROM test
- WHERE suitepath IS NOT NULL
- UNION ALL
- SELECT DISTINCT
- object_owner || ':' || suitepath || '.' || object_name AS parent_id,
- object_owner || ':' || suitepath || '.' || object_name || '.' || context AS id,
- context AS name,
- null AS description,
- 'FOLDER_ICON' AS iconName,
- 'No' AS leaf,
- 'Yes' AS generatable,
- 'Yes' AS multiselectable,
- 'Yes' AS relevant
- FROM test
- WHERE suitepath IS NOT NULL
- AND context IS NOT NULL
- UNION ALL
- SELECT object_owner || ':' || suitepath || '.' || object_name || CASE WHEN context IS NOT NULL THEN '.' || context END AS parent_id,
- object_owner || ':' || suitepath || '.' || object_name || CASE WHEN context IS NOT NULL THEN '.' || context END || '.' || subobject_name AS id,
- subobject_name AS name,
- null AS description,
- 'PROCEDURE_ICON' AS iconName,
- 'Yes' AS leaf,
- 'Yes' AS generatable,
- 'Yes' AS multiselectable,
- 'Yes' AS relevant
- FROM test
- WHERE suitepath IS NOT NULL
- ),
- tree AS (
- SELECT parent_id, id, name, description, iconName, leaf, generatable, multiselectable, relevant
- FROM suite_tree
- UNION ALL
- SELECT parent_id, id, name, description, iconName, leaf, generatable, multiselectable, relevant
- FROM suitepath_tree
- )
- SELECT parent_id, id, name, description, iconName, leaf, generatable, multiselectable, relevant
- FROM tree
- '''
+ var String sql
+ if (normalizedUtPlsqlVersionNumber >= FIRST_VERSION_WITH_ANNOTATION_API) {
+ // using API available since 3.1.3
+ sql = '''
+ WITH
+ test AS (
+ SELECT object_owner,
+ object_name,
+ path AS suitepath,
+ item_type,
+ item_name,
+ item_description
+ FROM TABLE(ut_runner.get_suites_info(user))
+ ),
+ suite_tree AS (
+ SELECT null AS parent_id,
+ 'SUITE' AS id,
+ 'All Suites' AS name,
+ 'All utPLSQL test suites' AS description,
+ 'PACKAGE_FOLDER_ICON' AS iconName,
+ 'No' AS leaf,
+ 'Yes' AS generatable,
+ 'Yes' AS multiselectable,
+ 'Yes' AS relevant
+ FROM dual
+ UNION ALL
+ SELECT DISTINCT
+ 'SUITE' AS parent_id,
+ object_owner || '.' || object_name AS id,
+ object_name AS name,
+ null AS description,
+ 'PACKAGE_ICON' AS iconName,
+ 'No' AS leaf,
+ 'Yes' AS generatable,
+ 'Yes' AS multiselectable,
+ 'Yes' AS relevant
+ FROM test
+ WHERE item_type = 'UT_TEST'
+ UNION ALL
+ SELECT object_owner || '.' || object_name AS parent_id,
+ object_owner || '.' || object_name || '.' || item_name AS id,
+ item_name AS name,
+ item_description AS description,
+ 'PROCEDURE_ICON' AS iconName,
+ 'Yes' AS leaf,
+ 'Yes' AS generatable,
+ 'Yes' AS multiselectable,
+ 'Yes' AS relevant
+ FROM test
+ WHERE item_type = 'UT_TEST'
+ ),
+ suitepath_tree AS (
+ SELECT NULL AS parent_id,
+ 'SUITEPATH' AS id,
+ 'All Suitepaths' AS name,
+ 'All utPLSQL test suitepathes' AS description,
+ 'FOLDER_ICON' AS iconName,
+ 'No' AS leaf,
+ 'Yes' AS generatable,
+ 'Yes' AS multiselectable,
+ 'Yes' AS relevant
+ FROM dual
+ UNION ALL
+ SELECT CASE
+ WHEN regexp_replace(suitepath,'\.?\w+$','') IS NULL THEN
+ 'SUITEPATH'
+ ELSE
+ object_owner || ':' || regexp_replace(suitepath,'\.?\w+$','')
+ END AS parent_id,
+ object_owner || ':' || suitepath AS id,
+ item_name AS name,
+ item_description AS description,
+ CASE item_type
+ WHEN 'UT_SUITE' THEN
+ 'PACKAGE_ICON'
+ WHEN 'UT_TEST' THEN
+ 'PROCEDURE_ICON'
+ ELSE
+ 'FOLDER_ICON'
+ END AS iconName,
+ CASE item_type
+ WHEN 'UT_TEST' THEN
+ 'Yes'
+ ELSE
+ 'No'
+ END AS leaf,
+ 'Yes' AS generatable,
+ 'Yes' AS multiselectable,
+ 'Yes' AS relevant
+ FROM test
+ ),
+ tree AS (
+ SELECT parent_id, id, name, description, iconName, leaf, generatable, multiselectable, relevant
+ FROM suite_tree
+ UNION ALL
+ SELECT parent_id, id, name, description, iconName, leaf, generatable, multiselectable, relevant
+ FROM suitepath_tree
+ )
+ SELECT parent_id, id, initcap(name) AS name, description, iconName, leaf, generatable, multiselectable, relevant
+ FROM tree
+ '''
+ } else {
+ // using internal API (deprecated)
+ sql = '''
+ WITH
+ base AS (
+ SELECT rownum AS an_id,
+ o.object_owner,
+ o.object_type,
+ o.object_name,
+ lower(a.name) AS name,
+ a.text,
+ a.subobject_name
+ FROM table(ut3.ut_annotation_manager.get_annotated_objects(user, 'PACKAGE')) o
+ CROSS JOIN table(o.annotations) a
+ WHERE lower(a.name) in ('suite', 'suitepath', 'endcontext', 'test')
+ OR lower(a.name) = 'context' AND regexp_like(text, '(\w+)(\.\w+)*')
+ ),
+ suite AS (
+ SELECT object_owner, object_type, object_name, text AS suite_description
+ FROM base
+ WHERE name = 'suite'
+ ),
+ suitepath as (
+ SELECT object_owner, object_type, object_name, lower(text) AS suitepath
+ FROM base
+ WHERE name = 'suitepath'
+ ),
+ context_base AS (
+ SELECT an_id,
+ lead(an_id) over (partition by object_owner, object_type, object_name order by an_id) AS an_id_end,
+ object_owner,
+ object_type,
+ object_name,
+ name,
+ lead(name) over (partition by object_owner, object_type, object_name order by an_id) AS name_end,
+ text as context
+ FROM base
+ WHERE name IN ('context', 'endcontext')
+ ),
+ context as (
+ SELECT an_id, an_id_end, object_owner, object_type, object_name, context
+ FROM context_base
+ WHERE name = 'context'
+ AND name_end = 'endcontext'
+ ),
+ test AS (
+ SELECT b.an_id,
+ b.object_owner,
+ b.object_type,
+ b.object_name,
+ p.suitepath,
+ c.context,
+ b.subobject_name,
+ b.text AS test_description
+ FROM base b
+ LEFT JOIN suitepath p
+ ON p.object_owner = b.object_owner
+ AND p.object_type = b.object_type
+ AND p.object_name = b.object_name
+ LEFT JOIN context c
+ ON c.object_owner = b.object_owner
+ AND c.object_type = b.object_type
+ AND c.object_name = b.object_name
+ AND b.an_id BETWEEN c.an_id AND c.an_id_end
+ WHERE name = 'test'
+ AND (b.object_owner, b.object_type, b.object_name) IN (
+ SELECT object_owner, object_type, object_name
+ FROM suite
+ )
+ ),
+ suite_tree AS (
+ SELECT null AS parent_id,
+ 'SUITE' AS id,
+ 'All Suites' AS name,
+ 'All utPLSQL test suites' AS description,
+ 'PACKAGE_FOLDER_ICON' AS iconName,
+ 'No' AS leaf,
+ 'Yes' AS generatable,
+ 'Yes' AS multiselectable,
+ 'Yes' AS relevant
+ FROM dual
+ UNION ALL
+ SELECT DISTINCT
+ 'SUITE' AS parent_id,
+ object_owner || '.' || object_name AS id,
+ object_name AS name,
+ null AS description,
+ 'PACKAGE_ICON' AS iconName,
+ 'No' AS leaf,
+ 'Yes' AS generatable,
+ 'Yes' AS multiselectable,
+ 'Yes' AS relevant
+ FROM test
+ UNION ALL
+ SELECT object_owner || '.' || object_name AS parent_id,
+ object_owner || '.' || object_name || '.' || upper(subobject_name) AS id,
+ subobject_name AS name,
+ null AS description,
+ 'PROCEDURE_ICON' AS iconName,
+ 'Yes' AS leaf,
+ 'Yes' AS generatable,
+ 'Yes' AS multiselectable,
+ 'Yes' AS relevant
+ FROM test
+ ),
+ suitepath_base AS (
+ SELECT DISTINCT
+ suitepath
+ FROM suitepath
+ ),
+ gen AS (
+ SELECT rownum AS pos
+ FROM xmltable('1 to 100')
+ ),
+ suitepath_part AS (
+ SELECT DISTINCT
+ lower(substr(suitepath, 1, instr(suitepath || '.', '.', 1, g.pos) -1)) AS suitepath
+ FROM suitepath_base b
+ JOIN gen g
+ ON g.pos <= regexp_count(suitepath, '\w+')
+ ),
+ suitepath_tree AS (
+ SELECT NULL AS parent_id,
+ 'SUITEPATH' AS id,
+ 'All Suitepaths' AS name,
+ 'All utPLSQL test suitepathes' AS description,
+ 'FOLDER_ICON' AS iconName,
+ 'No' AS leaf,
+ 'Yes' AS generatable,
+ 'Yes' AS multiselectable,
+ 'Yes' AS relevant
+ FROM dual
+ UNION ALL
+ SELECT CASE
+ WHEN regexp_replace(suitepath,'\.?\w+$','') IS NULL THEN
+ 'SUITEPATH'
+ ELSE
+ USER || ':' || regexp_replace(suitepath,'\.?\w+$','')
+ END AS parent_id,
+ USER || ':' || suitepath AS id,
+ regexp_substr(suitepath, '\.?(\w+$)', 1, 1, NULL, 1) AS name,
+ null AS description,
+ 'FOLDER_ICON' AS iconName,
+ 'No' AS leaf,
+ 'Yes' AS generatable,
+ 'Yes' AS multiselectable,
+ 'Yes' AS relevant
+ FROM suitepath_part
+ UNION ALL
+ SELECT DISTINCT
+ object_owner || ':' || suitepath AS parent_id,
+ object_owner || ':' || suitepath || '.' || lower(object_name) AS id,
+ object_name AS name,
+ null AS description,
+ 'PACKAGE_ICON' AS iconName,
+ 'No' AS leaf,
+ 'Yes' AS generatable,
+ 'Yes' AS multiselectable,
+ 'Yes' AS relevant
+ FROM test
+ WHERE suitepath IS NOT NULL
+ UNION ALL
+ SELECT DISTINCT
+ object_owner || ':' || suitepath || '.' || lower(object_name) AS parent_id,
+ object_owner || ':' || suitepath || '.' || lower(object_name) || '.' || context AS id,
+ context AS name,
+ null AS description,
+ 'FOLDER_ICON' AS iconName,
+ 'No' AS leaf,
+ 'Yes' AS generatable,
+ 'Yes' AS multiselectable,
+ 'Yes' AS relevant
+ FROM test
+ WHERE suitepath IS NOT NULL
+ AND context IS NOT NULL
+ UNION ALL
+ SELECT object_owner || ':' || suitepath || '.' || lower(object_name) || CASE WHEN context IS NOT NULL THEN '.' || context END AS parent_id,
+ object_owner || ':' || suitepath || '.' || lower(object_name) || CASE WHEN context IS NOT NULL THEN '.' || context END || '.' || lower(subobject_name) AS id,
+ subobject_name AS name,
+ null AS description,
+ 'PROCEDURE_ICON' AS iconName,
+ 'Yes' AS leaf,
+ 'Yes' AS generatable,
+ 'Yes' AS multiselectable,
+ 'Yes' AS relevant
+ FROM test
+ WHERE suitepath IS NOT NULL
+ ),
+ tree AS (
+ SELECT parent_id, id, name, description, iconName, leaf, generatable, multiselectable, relevant
+ FROM suite_tree
+ UNION ALL
+ SELECT parent_id, id, name, description, iconName, leaf, generatable, multiselectable, relevant
+ FROM suitepath_tree
+ )
+ SELECT parent_id, id, initcap(name) AS name, description, iconName, leaf, generatable, multiselectable, relevant
+ FROM tree
+ '''
+ }
val jdbcTemplate = new JdbcTemplate(new SingleConnectionDataSource(conn, true))
val nodes = jdbcTemplate.query(sql, new BeanPropertyRowMapper(Node))
return nodes
@@ -638,8 +843,9 @@ class UtplsqlDao {
'MDSYS', 'OLAPSYS', 'ORDDATA', 'XDB', 'WMSYS', 'ORDSYS', 'GSMCATUSER',
'MDDATA', 'REMOTE_SCHEDULER_AGENT', 'SYSBACKUP', 'GSMUSER', 'APEX_PUBLIC_USER',
'SYSRAC', 'AUDSYS', 'DIP', 'SYSKM', 'ORACLE_OCM', 'APEX_INSTANCE_ADMIN_USER',
- 'SYSDG', 'FLOWS_FILES', 'ORDS_METADATA', 'ORDS_PUBLIC_USER', 'APEX_180100'
+ 'SYSDG', 'FLOWS_FILES', 'ORDS_METADATA', 'ORDS_PUBLIC_USER'
)
+ AND referenced_owner NOT LIKE 'APEX\_______'
AND referenced_type IN ('PACKAGE', 'TYPE', 'PROCEDURE', 'FUNCTION', 'TRIGGER')
'''
val jdbcTemplate = new JdbcTemplate(new SingleConnectionDataSource(conn, true))
diff --git a/sqldev/src/main/java/org/utplsql/sqldev/model/ut/Annotation.xtend b/sqldev/src/main/java/org/utplsql/sqldev/model/ut/Annotation.xtend
index 087f2330..ee658e91 100644
--- a/sqldev/src/main/java/org/utplsql/sqldev/model/ut/Annotation.xtend
+++ b/sqldev/src/main/java/org/utplsql/sqldev/model/ut/Annotation.xtend
@@ -21,7 +21,6 @@ import org.utplsql.sqldev.model.AbstractModel
@Accessors
class Annotation extends AbstractModel {
String objectOwner
- String objectType
String objectName
String name
String text
diff --git a/sqldev/src/test/java/org/utplsql/sqldev/tests/DalTest.xtend b/sqldev/src/test/java/org/utplsql/sqldev/tests/DalTest.xtend
index 6ceb7544..9dbad90b 100644
--- a/sqldev/src/test/java/org/utplsql/sqldev/tests/DalTest.xtend
+++ b/sqldev/src/test/java/org/utplsql/sqldev/tests/DalTest.xtend
@@ -86,9 +86,9 @@ class DalTest extends AbstractJdbcTest {
Assert.assertTrue(dao.utAnnotationManagerInstalled)
}
- @Test
- def void containsUtplsqlTest() {
+ def void containsUtplsqlTest(String utPlsqlVersion) {
val dao = new UtplsqlDao(dataSource.connection)
+ dao.utPlsqlVersion = utPlsqlVersion
jdbcTemplate.execute('''
CREATE OR REPLACE PACKAGE junit_utplsql_test_pkg IS
-- %suite
@@ -125,10 +125,20 @@ class DalTest extends AbstractJdbcTest {
Assert.assertFalse(dao.containsUtplsqlTest("scott", "junit_utplsql_test_pkg", "t3"))
jdbcTemplate.execute("DROP PACKAGE junit_utplsql_test_pkg")
}
-
+
+ @Test
+ def void containsUtplsqlTest304() {
+ containsUtplsqlTest("3.0.4")
+ }
+
@Test
- def void annotations() {
+ def void containsUtplsqlTest313() {
+ containsUtplsqlTest("3.1.3")
+ }
+
+ def void annotations(String utPlsqlVersion) {
val dao = new UtplsqlDao(dataSource.connection)
+ dao.utPlsqlVersion = utPlsqlVersion
jdbcTemplate.execute('''
CREATE OR REPLACE PACKAGE junit_utplsql_test_pkg IS
-- %suite
@@ -146,31 +156,39 @@ class DalTest extends AbstractJdbcTest {
val expected = new ArrayList
val suite = new Annotation
suite.objectOwner = "SCOTT"
- suite.objectType = "PACKAGE"
suite.objectName = "JUNIT_UTPLSQL_TEST_PKG"
suite.name = 'suite'
+ suite.subobjectName = suite.objectName
expected.add(suite)
val t1 = new Annotation
t1.objectOwner = "SCOTT"
- t1.objectType = "PACKAGE"
t1.objectName = "JUNIT_UTPLSQL_TEST_PKG"
t1.name = 'test'
- t1.subobjectName = 't1'
+ t1.subobjectName = 'T1'
expected.add(t1)
val t2 = new Annotation
t2.objectOwner = "SCOTT"
- t2.objectType = "PACKAGE"
t2.objectName = "JUNIT_UTPLSQL_TEST_PKG"
t2.name = 'test'
- t2.subobjectName = 't2'
+ t2.subobjectName = 'T2'
expected.add(t2)
Assert.assertEquals(expected.toString, actual.toString)
jdbcTemplate.execute("DROP PACKAGE junit_utplsql_test_pkg")
}
-
+
+ @Test
+ def void annotations304() {
+ annotations("3.0.4")
+ }
+
@Test
- def void testablesPackages() {
+ def void annotations313() {
+ annotations("3.1.3")
+ }
+
+ def void testablesPackages(String utPlsqlVersion) {
val dao = new UtplsqlDao(dataSource.connection)
+ dao.utPlsqlVersion = utPlsqlVersion
jdbcTemplate.execute('''
CREATE OR REPLACE PACKAGE junit_utplsql_test_pkg IS
-- %suite
@@ -197,8 +215,18 @@ class DalTest extends AbstractJdbcTest {
}
@Test
- def void testablesTypes() {
+ def void testablesPackages304() {
+ testablesPackages("3.0.4")
+ }
+
+ @Test
+ def void testablesPackages313() {
+ testablesPackages("3.1.3")
+ }
+
+ def void testablesTypes(String utPlsqlVersion) {
val dao = new UtplsqlDao(dataSource.connection)
+ dao.utPlsqlVersion = utPlsqlVersion
jdbcTemplate.execute('''
CREATE OR REPLACE TYPE junit_tab1_ot IS object (a integer, b integer);
''')
@@ -218,8 +246,18 @@ class DalTest extends AbstractJdbcTest {
}
@Test
- def void testablesFunctions() {
+ def void testablesTypes304() {
+ testablesTypes("3.0.4")
+ }
+
+ @Test
+ def void testablesTypes313() {
+ testablesTypes("3.1.3")
+ }
+
+ def void testablesFunctions(String utPlsqlVersion) {
val dao = new UtplsqlDao(dataSource.connection)
+ dao.utPlsqlVersion = utPlsqlVersion
jdbcTemplate.execute('''
CREATE OR REPLACE FUNCTION junit_f RETURN INTEGER IS
BEGIN
@@ -232,8 +270,18 @@ class DalTest extends AbstractJdbcTest {
}
@Test
- def void testablesProcedures() {
+ def void testablesFunctions304() {
+ testablesFunctions("3.0.4")
+ }
+
+ @Test
+ def void testablesFunctions313() {
+ testablesFunctions("3.1.3")
+ }
+
+ def void testablesProcedures(String utPlsqlVersion) {
val dao = new UtplsqlDao(dataSource.connection)
+ dao.utPlsqlVersion = utPlsqlVersion
jdbcTemplate.execute('''
CREATE OR REPLACE PROCEDURE junit_p RETURN INTEGER IS
BEGIN
@@ -246,22 +294,32 @@ class DalTest extends AbstractJdbcTest {
}
@Test
- def void runnables() {
+ def void testablesProcedures304() {
+ testablesProcedures("3.0.4")
+ }
+
+ @Test
+ def void testablesProcedures313() {
+ testablesProcedures("3.1.3")
+ }
+
+ def void runnables(String utPlsqlVersion) {
val dao = new UtplsqlDao(dataSource.connection)
+ dao.utPlsqlVersion = utPlsqlVersion
jdbcTemplate.execute('''
CREATE OR REPLACE PACKAGE junit_utplsql_test_pkg IS
-- %suite
-- %suitepath(a.B.c)
-- %test
- PROCEDURE t0;
+ PROCEDURE T0;
- -- %context(mycontext)
+ -- %context(myContext)
- -- %test
+ -- %test(t1: test One)
PROCEDURE t1;
- -- %test
+ -- %test(t2: test Two)
PROCEDURE t2;
-- %endcontext
@@ -278,20 +336,30 @@ class DalTest extends AbstractJdbcTest {
}
Assert.assertEquals(null, actual.get("SUITE"))
Assert.assertEquals("SUITE", actual.get("SCOTT.JUNIT_UTPLSQL_TEST_PKG"))
- Assert.assertEquals("SCOTT.JUNIT_UTPLSQL_TEST_PKG", actual.get("SCOTT.JUNIT_UTPLSQL_TEST_PKG.t0"))
- Assert.assertEquals("SCOTT.JUNIT_UTPLSQL_TEST_PKG", actual.get("SCOTT.JUNIT_UTPLSQL_TEST_PKG.t1"))
- Assert.assertEquals("SCOTT.JUNIT_UTPLSQL_TEST_PKG", actual.get("SCOTT.JUNIT_UTPLSQL_TEST_PKG.t2"))
- Assert.assertEquals("SCOTT.JUNIT_UTPLSQL_TEST_PKG", actual.get("SCOTT.JUNIT_UTPLSQL_TEST_PKG.t3"))
+ Assert.assertEquals("SCOTT.JUNIT_UTPLSQL_TEST_PKG", actual.get("SCOTT.JUNIT_UTPLSQL_TEST_PKG.T0"))
+ Assert.assertEquals("SCOTT.JUNIT_UTPLSQL_TEST_PKG", actual.get("SCOTT.JUNIT_UTPLSQL_TEST_PKG.T1"))
+ Assert.assertEquals("SCOTT.JUNIT_UTPLSQL_TEST_PKG", actual.get("SCOTT.JUNIT_UTPLSQL_TEST_PKG.T2"))
+ Assert.assertEquals("SCOTT.JUNIT_UTPLSQL_TEST_PKG", actual.get("SCOTT.JUNIT_UTPLSQL_TEST_PKG.T3"))
Assert.assertEquals(null, actual.get("SUITEPATH"))
Assert.assertEquals("SUITEPATH", actual.get("SCOTT:a"))
Assert.assertEquals("SCOTT:a", actual.get("SCOTT:a.b"))
Assert.assertEquals("SCOTT:a.b", actual.get("SCOTT:a.b.c"))
- Assert.assertEquals("SCOTT:a.b.c", actual.get("SCOTT:a.b.c.JUNIT_UTPLSQL_TEST_PKG"))
- Assert.assertEquals("SCOTT:a.b.c.JUNIT_UTPLSQL_TEST_PKG", actual.get("SCOTT:a.b.c.JUNIT_UTPLSQL_TEST_PKG.mycontext"))
- Assert.assertEquals("SCOTT:a.b.c.JUNIT_UTPLSQL_TEST_PKG", actual.get("SCOTT:a.b.c.JUNIT_UTPLSQL_TEST_PKG.t0"))
- Assert.assertEquals("SCOTT:a.b.c.JUNIT_UTPLSQL_TEST_PKG", actual.get("SCOTT:a.b.c.JUNIT_UTPLSQL_TEST_PKG.t3"))
- Assert.assertEquals("SCOTT:a.b.c.JUNIT_UTPLSQL_TEST_PKG.mycontext", actual.get("SCOTT:a.b.c.JUNIT_UTPLSQL_TEST_PKG.mycontext.t1"))
- Assert.assertEquals("SCOTT:a.b.c.JUNIT_UTPLSQL_TEST_PKG.mycontext", actual.get("SCOTT:a.b.c.JUNIT_UTPLSQL_TEST_PKG.mycontext.t2"))
+ Assert.assertEquals("SCOTT:a.b.c", actual.get("SCOTT:a.b.c.junit_utplsql_test_pkg"))
+ Assert.assertEquals("SCOTT:a.b.c.junit_utplsql_test_pkg", actual.get("SCOTT:a.b.c.junit_utplsql_test_pkg.myContext"))
+ Assert.assertEquals("SCOTT:a.b.c.junit_utplsql_test_pkg", actual.get("SCOTT:a.b.c.junit_utplsql_test_pkg.t0"))
+ Assert.assertEquals("SCOTT:a.b.c.junit_utplsql_test_pkg", actual.get("SCOTT:a.b.c.junit_utplsql_test_pkg.t3"))
+ Assert.assertEquals("SCOTT:a.b.c.junit_utplsql_test_pkg.myContext", actual.get("SCOTT:a.b.c.junit_utplsql_test_pkg.myContext.t1"))
+ Assert.assertEquals("SCOTT:a.b.c.junit_utplsql_test_pkg.myContext", actual.get("SCOTT:a.b.c.junit_utplsql_test_pkg.myContext.t2"))
+ }
+
+ @Test
+ def void runnables304() {
+ runnables("3.0.4")
+ }
+
+ @Test
+ def void runnables313() {
+ runnables("3.1.3")
}
@Test
@@ -361,5 +429,47 @@ class DalTest extends AbstractJdbcTest {
val actual = dao.includes('junit_utplsql_test_pkg')
Assert.assertEquals(#['JUNIT_UTPLSQL_TEST_PKG','JUNIT_F','UT_EXPECTATION'].sort, actual.sort)
}
+
+ @Test
+ def void normalizedPlsqlVersionOkRelease() {
+ val dao = new UtplsqlDao(dataSource.connection)
+ dao.utPlsqlVersion = "v3.1.10.1234"
+ val actual = dao.normalizedUtPlsqlVersion()
+ Assert.assertEquals("3.1.10", actual)
+ }
+
+ @Test
+ def void normalizedPlsqlVersionOkDevelop() {
+ val dao = new UtplsqlDao(dataSource.connection)
+ dao.utPlsqlVersion = "v3.1.10.1234-develop"
+ val actual = dao.normalizedUtPlsqlVersion()
+ Assert.assertEquals("3.1.10", actual)
+ }
+
+ @Test
+ def void normalizedPlsqlVersionNok() {
+ val dao = new UtplsqlDao(dataSource.connection)
+ dao.utPlsqlVersion = "bla bla 1.2"
+ val actual = dao.normalizedUtPlsqlVersion()
+ Assert.assertEquals("0.0.0", actual)
+ }
+
+ @Test
+ def void normaliedPlsqlVersionNumber() {
+ val dao = new UtplsqlDao(dataSource.connection)
+ dao.utPlsqlVersion = "3.14.37"
+ val actual = dao.normalizedUtPlsqlVersionNumber()
+ Assert.assertEquals(3014037, actual)
+ }
+
+ @Test
+ def void utPlsqlVersion() {
+ val dao = new UtplsqlDao(dataSource.connection)
+ val actual = dao.utPlsqlVersion
+ val sql = "SELECT ut.version FROM DUAL"
+ val expected = jdbcTemplate.queryForObject(sql, String)
+ Assert.assertEquals(expected, actual)
+
+ }
}
\ No newline at end of file
diff --git a/sqldev/src/test/java/org/utplsql/sqldev/tests/UtplsqlParserTest.xtend b/sqldev/src/test/java/org/utplsql/sqldev/tests/UtplsqlParserTest.xtend
index 131a9d4e..93be55f4 100644
--- a/sqldev/src/test/java/org/utplsql/sqldev/tests/UtplsqlParserTest.xtend
+++ b/sqldev/src/test/java/org/utplsql/sqldev/tests/UtplsqlParserTest.xtend
@@ -35,6 +35,7 @@ class UtplsqlParserTest extends AbstractJdbcTest {
CREATE OR REPLACE PACKAGE pkg IS
-- %suite
-- %rollback(manual)
+
-- %test
PROCEDURE p (in_p1 INTEGER);
FUNCTION f (in_p1 INTEGER) RETURN INTEGER;
@@ -90,7 +91,7 @@ class UtplsqlParserTest extends AbstractJdbcTest {
Assert.assertEquals("pkg", parser.getPathAt(parser.toPosition(4,1)))
Assert.assertEquals("pkg.p", parser.getPathAt(parser.toPosition(10,33)))
Assert.assertEquals("pkg.p", parser.getPathAt(parser.toPosition(13,1)))
- Assert.assertEquals("SCOTT.PKG.P", parser.getPathAt(parser.toPosition(19,1)))
+ Assert.assertEquals("SCOTT.PKG.p", parser.getPathAt(parser.toPosition(19,1)))
Assert.assertEquals("SCOTT.PKG.P", parser.getPathAt(parser.toPosition(22,9)))
Assert.assertEquals("SCOTT.PKG.P", parser.getPathAt(parser.toPosition(22,10)))
Assert.assertEquals("SCOTT.PKG.P", parser.getPathAt(parser.toPosition(29,1)))
@@ -125,7 +126,7 @@ class UtplsqlParserTest extends AbstractJdbcTest {
Assert.assertEquals(2, parser.getObjects.size)
Assert.assertEquals(2, parser.getUnits.size)
Assert.assertEquals("pkg.p", parser.getPathAt(parser.toPosition(13,1)))
- Assert.assertEquals("SCOTT.PKG.P", parser.getPathAt(parser.toPosition(19,1)))
+ Assert.assertEquals("SCOTT.PKG.p", parser.getPathAt(parser.toPosition(19,1)))
setupAndTeardown
}