Attribute Extraction
Dears,
I want to extract a attribute from a XML file. Can anyone
please help me in this regard.
Regards,
Ram
Sample XML file: ( Here i want to extract the attribute:
valueClass)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE jasperPrint PUBLIC "-//JasperReports//DTD
JasperPrint//EN" "
http://jasperreports.sourceforge.net/dtds/jasperprint.dtd">
<jasperPrint name="Buzz_Trend" pageWidth="595"
pageHeight="842" locale="en_US" timezone="Asia/Calcutta">
<property
name="net.sf.jasperreports.export.xml.page.count" value="1"/>
<origin band="background"/>
<origin band="title"/>
<origin band="pageHeader"/>
<origin band="columnHeader"/>
<origin band="detail"/>
<origin band="columnFooter"/>
<origin band="pageFooter"/>
<page>
<text textHeight="12.578125"
lineSpacingFactor="1.2578125" leadingOffset="-2.1972656"
hyperlinkType="None" valueClass="java.math.BigDecimal"
pattern="#0.00">
<reportElement key="textField" x="337" y="29" width="100"
height="18" origin="4"/>
<textContent><![CDATA[86.00]]></textContent>
</text>
<text textHeight="12.578125"
lineSpacingFactor="1.2578125" leadingOffset="-2.1972656"
hyperlinkType="None" valueClass="java.sql.Timestamp"
pattern="M/d/yy h:mm a">
<reportElement key="textField" x="158" y="29" width="100"
height="18" origin="4"/>
<textContent><![CDATA[9/26/08 12:00
AM]]></textContent>
</text>
<text textHeight="12.578125"
lineSpacingFactor="1.2578125" leadingOffset="-2.1972656"
hyperlinkType="None" valueClass="java.math.BigDecimal"
pattern="#0.00">
<reportElement key="textField" x="337" y="79" width="100"
height="18" origin="4"/>
<textContent><![CDATA[78.00]]></textContent>
</text>
<text textHeight="12.578125"
lineSpacingFactor="1.2578125" leadingOffset="-2.1972656"
hyperlinkType="None" valueClass="java.sql.Timestamp"
pattern="M/d/yy h:mm a">
<reportElement key="textField" x="158" y="79" width="100"
height="18" origin="4"/>
<textContent><![CDATA[9/27/08 12:00
AM]]></textContent>
</text>
<text textHeight="12.578125"
lineSpacingFactor="1.2578125" leadingOffset="-2.1972656"
hyperlinkType="None" valueClass="java.math.BigDecimal"
pattern="#0.00">
<reportElement key="textField" x="337" y="129"
width="100" height="18" origin="4"/>
<textContent><![CDATA[56.00]]></textContent>
</text>
<text textHeight="12.578125"
lineSpacingFactor="1.2578125" leadingOffset="-2.1972656"
hyperlinkType="None" valueClass="java.sql.Timestamp"
pattern="M/d/yy h:mm a">
<reportElement key="textField" x="158" y="129"
width="100" height="18" origin="4"/>
<textContent><![CDATA[9/28/08 12:00
AM]]></textContent>
</text>
<text textHeight="12.578125"
lineSpacingFactor="1.2578125" leadingOffset="-2.1972656"
hyperlinkType="None" valueClass="java.math.BigDecimal"
pattern="#0.00">
<reportElement key="textField" x="337" y="179"
width="100" height="18" origin="4"/>
<textContent><![CDATA[89.00]]></textContent>
</text>
<text textHeight="12.578125"
lineSpacingFactor="1.2578125" leadingOffset="-2.1972656"
hyperlinkType="None" valueClass="java.sql.Timestamp"
pattern="M/d/yy h:mm a">
<reportElement key="textField" x="158" y="179"
width="100" height="18" origin="4"/>
<textContent><![CDATA[9/29/08 12:00
AM]]></textContent>
</text>
</page>
</jasperPrint>
See FB3 help sys on e4x syntax. It has good support for
accessing xml attributes.
Similar Messages
-
Cost Order Attribute Extraction (0COORDER_ATTR) - ABAP Dump
I am having trouble with this Cost Order Attribute Extraction (0COORDER_ATTR). It happened on the R3 side, and it is ABAP dump.
The message:
The following syntax error occurred in program "SAPLROMA" in include "LROMAU01" in Line 341: "The data object "L_S_BIW_COOR" does not have a component called "CCKEY".
This error happened after installing the enchantment pack. Also, I did look at the OSS notes, and nothing found.
Any idea on how to fix this problem.Hello,
Have you checked the structure L_S_BIW_COOR if it has the field CCKEY ?
When it happens the dump? when you do a Check extractor in RSA3 t-code?
Have you done any enhacement to the datasource? adding extra fields and filling them in the EXIT...
Regards, Federico -
TREX python extension for HTML attribute extraction
How is the TREX python extension for HTML attribute extraction supposed to work?
I activated this extension and indexed an HTML document containing:
<HTML>
<HEAD>
<META content="debian, GNU, linux, unix" name=Keywords>
<HEAD>
<HTML>
Why when submitting the query "unix" this document is not found by the system?
(TREX version 6.1.11.02)
DavideThe trick doesn't work on my system (TREX v. 6.1.11.02).
1) This is the edited line in getDCAttributes.py:
knownAttributes = ['description','Keywords']
2) Only the HTML Attribute Extractor extension is activated in extensions.py. In particular, the Dublin Core extension is deactivated.
3) This is the pythonextension section of TREXPreprocessor.ini:
extensiontype= beforeHTTP
4) This is the parametrization of the newly created property in CM:
<i>Unique ID: html_keywords
Description: not set
Property ID: Keywords
Namespace Alias: trilog
Type: String
Group: html
Mandatory: not checked
Multi-Valued: not checked
Read Only: not checked
Maintainable: not checked
Indexable: checked
Default Value: not set
Allowed Values: not set
Key for Label: not set
Meta Data Extension: not set
Folder Validity Patterns: /
Document Validity Patterns: /
Resource Types: not set
Mime Types: not set
Default Sorting Ascending: not set
Label Icon: not set
Hidden: not checked
Dependencies: not checked
Additional Metadata: not set
Property Renderer: not set
Virtual: not checked
Composed of: not set
Comparator Class: not set</i>
5) I've added this property in the parameters <i>Allowed Predefined Properties</i> and <i>Predefined Properties</i> under <i>Content Management -> User Interface -> Search</i>
6) Now it's possible to filter by the <b>Keywords</b> predefined property in the Search UI, but no matches are ever found.
7) No significant message is found in PythonExtension.log:
# running global extensions.py at Tue Jul 12 11:13:03 2005
### import getHtmlAttributes
# running global extensions.py at Tue Jul 12 11:13:04 2005
### import getHtmlAttributes
8) I've run another test <b>activating the Dublin Core extension</b> in extensions.py as well, and setting extensiontype to beforeLEXICON in TREXPreprocessor.ini. Nevertheless it didn't work.
9) Here's some DC extension's output:
### Parse document with key: '/davide_test/attributi/GNU_Emacs.htm'
### extracted attributes: []
This is the GNU_Emacs.htm's <head>:
<META content=emacs name=keywords>
Cheers, Davide -
Effect of Full Attribute Extract on Aggregate Attribute Change Run
Because we extract data that does not trigger the change pointer on 0CUST_SALES we do a FULL extract of this data daily instead of a DELTA. We recently created an aggregate which contains navigational attributes of 0CUST_SALES (namely Sales Office & Sales Group).
My question is does the system look to see if any information has changed between the new and old values or does it assume since there is a new version for every entry that 100% of the values have changed?
The reason I'm asking is BW appears to be rebuilding this aggregate from scratch each day instead of changing the aggregate for the few entries that actually changed.I did a FULL extract for 0CUST_SALES in our QA system. It transferred 28617 records. When I look into the monitor > processing > data package 1 > update I see the following:
3 data records in table /BI0/XCUST_SALES marked for deletion
3 data records inserted in table /BI0/XCUST_SALES
3 data records n table /BI0/PCUST_SALES marked for deletion
3 data records inserted in table /BI0/PCUST_SALES
Different database operations were executed
When I run the attribute change I see the following messages:
The Change Run is executing
Attribute 0CUST_SALES__ZZROUTE for basic characteristic 0CUST_SALES: 2 changes
Attribute 0CUST_SALES__0BILLTOPRTY for basic characteristic 0CUST_SALES: 2 changes
Attribute 0CUST_SALES__0PAYER for basic characteristic 0CUST_SALES: 2 changes
Attribute 0CUST_SALES__ZZACGRP for basic characteristic 0CUST_SALES: 2 changes
0001 ZSD_C02 100016 Aggregates Will Be Adjusted by:Reconstruction
0002 ZSD_C02 100019 Aggregates Will Be Adjusted by:Reconstruction
After seeing this i revisited the documentation for threshold value in RSCUSTV8. Ours is BLANK! So according to the documents when it is blank the aggregate is reconstructed generally. Not what we want!!
I will change the setting to the suggested 20% to start and we'll work from there.
Thanks for your help Oliver. -
Essbase Metadata ATTRIBUTE Extraction
Hi Everyone,
Anyone have any luck exporting Essbase (BSO) hierarchy attribute information? I have the Essbase Dimension extraction working, but getting an error on the Attribute process.
Appreciate your thoughts -- let me know if anyone has had any success with this.
-ChrisHmm... I was just able to Export my Essbase Attribute Dimension Hierarchy with Star Analytics Integration Services (SIS) in about 5 minutes. So I know the extraction of Attribute hierarchies is possible. The cool thing was SIS created its own table to do this and it was user friendly. Very cool extraction utility -- far superior than the OLAP Extraction tool.
Has anyone had success using ODI to extract Attribute Dimension Hierarchies? I hope so because I'd like to use ODI to do this step. Was hoping to see a John Goodwin blog on this or something by Cameron Lackpour.
We're also installing Patch 12529600: ORACLE DATA INTEGRATOR 10.1.3.6.8 CUMULATIVE PATCH this weekend and maybe that might help get beyond the erorr we're hitting.
-Chris Rothermel
P.S. My Attribute Dimension Extract is failing with the following message
org.apache.bsf.BSFException: exception from Jython:
Traceback (most recent call last):
File "<string>", line 89, in <module>
at com.hyperion.odi.essbase.ODIEssbaseMetaReader.validateSourceMetadata(Unknown Source)
at com.hyperion.odi.essbase.ODIEssbaseMetaReader.validateExtractOptions(Unknown Source)
at com.hyperion.odi.essbase.AbstractEssbaseReader.beginExtract(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
java.lang.NullPointerException: java.lang.NullPointerException
--- -
Wanted: only attributes .extract() - function returns the complete node
Hi I have xml documents stored as XMLType, I would like to extract only the attributes of a node which I point to using a xPath expression. As a matter of fact the funcion .extract( some XPath) returns the corresponding node inclusive all children. This is very costly since I have large XML documents having a deep structure.
ThanksYour XPATH is incorrect
The XPATH you provided identifies the node with the attribute name = blah
The XPATH you want would end with /@*
See
http://www.w3c.org/TR/xpath#section-Location-Steps
eg
SQL> select extract(xml,'/Root/Element[@A1="FOO"]/@*')
2 from
3 (select xmltype(
4 '
5 <Root>
6 <Element A1="FOO" A2="BAA"/>
7 <Element A1="BAA" A2="FOO"/>
8 </Root>
9 ') xml
10 from dual
11 );
EXTRACT(XML,'/ROOT/ELEMENT[@A1="FOO"]/@*')
FOOBAA
Unfortunately, extract will return a concatenation of the value of the selected attributes -
UWL refresh problem for ABAP BOR custom attributes
Hi all,
we are facing an issue with an UWL iView. We wanted to display custom attributes from an ABAP Business Object (ABAP_BOR).
The feature is working but when an end-user receives a new task in his UWL view, he needs to click on the refresh button in order to have all the custom attributes correctly displayed.
We have only the problem with custom attributes, for the columns containing standard workflow decision task attributes, the data are displayed directly without the need to push the refresh button.
We are on EP 7 SPS11 and the back-end is an ECC6 version.
We have followed the methodology described in the How to configure and customize the Universal Worklist pdf document:
ABAP BOR
<CustomAttributeSource id="ABAP_BOR"
objectIdHolder="externalObjectId"
objectType="FORMABSENC"
cacheValidity="final">
<Attribute name="COSTCENTER" type="string"
displayName="Cost Center"></Attribute>
<Attribute name="FIRSTDAYOFABSENCE" type="date"
displayName="First day of absence"></Attribute>
<Attribute name="LASTDAYOFABSENCE" type="date"
displayName="Last day of absence"></Attribute>
</CustomAttributeSource>
Do you have an idea where this problem come from and how it could be solved?
Thanks in advance and regards,
Sébastien BODSONHi Chintan,
This parameter has no impact on the problem we face. I found an exact description of our problem on SAP Help portal, in the UWL pages:
CustomAttributes, CustomAttributeSource and Attribute
Extract from SAP Help portal:
Every item type can have custom attributes defined, which can be filled from Business Object or Provider Data Containers like the Business Workflow Container or the Alert Container. These attribute sources are defined within the CustomAttributeSourcetag, which contains information on which attribute connector brings the custom attributes, how to identify these custom attributes in the provider system and how long the cache is valid.
Note that once an item arrives, these custom attributes are retrieved in additional calls to the backend. For performance reasons, in order to minimize responses times to the end user, this may happen while the item is displayed to the end user - causing such attributes to be empty initially and only to appear in subsequent requests.
The display names of the attributes for column headers and labels are defined in the display attributes of the default view of the item type.
Does anyone know a workaround in order to have directly the complete information displayed?
Sébastien BODSON -
Using HAL to extract and then load metadata
hi!
We are designing a process in which HAL is used to extract a dimension from Essbase and then loaded to another application using a load rule.
We are struggling with our attributes extraction, we have multiple attributes to an entity and when we extract it from Essbase it creates a string with a comma delimiter. Example
- Entity1, Store, +, "Attribute1,Attribute2,Attribute3",UDA1
Any ideas of how to remove the "? I have tried using formulas like Mid(String,1,Len(String)-1) - but it ignores the "
ThanksYou could run a macro in Excel's VBA editor that would extract each member of the dim and put each one in a column in a spreadsheet. The macro is ->
Sub mainSub()
x = EssVConnect("Sheet1", "admin", "password", "server", "appname", "dbname")
Set rng = Range("A1")
vt = EssVGetMemberInfo("Sheet1", "dimName", 2, False)
If IsArray(vt) Then
cbItems = UBound(vt) + 1
For i = 0 To UBound(vt)
rng.Value = vt(i)
Set rng = rng.Offset(1, 0)
Next
End If
End Sub
Of course you would need to have the EssVGetMemberInfo function declared, but it is a nice neet way to extract the members into separate cells in an Excel worksheet. And then it could be imported to a db cube. -
Outline Extractor - Attributes - Implied Shared members
I am attempting to extract the attributes from one cube to load into another cube. Some of our attributes are at the level 0 and others are at level 1. We have many parents that have one child, essentially an implied share.
When I run the outline extractor, the implied shared parent attributes are assigned to the child. When you have a implied share scenario, is there a way to get the attributes extracted to the proper level?
Forgot to mention... We are 9.3.1.
Thanks.
Edited by: GlennH on Jan 31, 2011 8:40 AMHi Glenn,
Send email to [email protected] and my OlapUnderground support guys can take a look at it..
Tim Tow
Applied OLAP, Inc -
ORA 01792 maximum number of columns in a table or view is 1000
Hello every1, I wish to register a large xmlschema doc, I am using the command
begin
dbms_xmlschema.registerschema(
schemaurl=>'xxxx',
schemadoc=>bfilename('XMLDIR','xxxxxx.xsd'),
csid=>nls_charset_id('AL32UTF8'));
end;
But the schema file exists 1000 col and it gives me the error msg of
ORA-01792: maximum number of columns in a table or view is 1000
is there anyway to solve the problems without edit the original schema document?
Thanks for your helpFirst create this package
create or replace package XDB_ANALYZE_XMLSCHEMA_10200
authid CURRENT_USER
as
function analyzeStorageModel(P_COMPLEX_TYPE_NAME VARCHAR2) return XMLTYPE;
function analyzeComplexType(COMPLEX_TYPE VARCHAR2) return XMLTYPE;
procedure renameCollectionTable (XMLTABLE varchar2, XPATH varchar2, COLLECTION_TABLE_PREFIX varchar2);
function printNestedTables(XML_TABLE varchar2) return XMLType;
function getComplexTypeElementList(P_SQLTYPE VARCHAR2, P_SQLSCHEMA VARCHAR2) return XDB.XDB$XMLTYPE_REF_LIST_T;
procedure scopeXMLReferences;
procedure indexXMLReferences(INDEX_NAME VARCHAR2);
function generateSchemaFromTable(P_TABLE_NAME varchar2, P_OWNER varchar2 default USER) return XMLTYPE;
function showSQLTypes(schemaFolder varchar2) return XMLType;
function generateCreateTableStatement(XML_TABLE_NAME varchar2, NEW_TABLE_NAME varchar2) return CLOB;
end XDB_ANALYZE_XMLSCHEMA_10200;
show errors
create or replace package body XDB_ANALYZE_XMLSCHEMA_10200
as
G_DEPTH_COUNT NUMBER(2) := 0;
TYPE BASETYPE_T is RECORD
SUBTYPE varchar2(128),
SUBTYPE_OWNER varchar2(32),
BASETYPE varchar2(128),
BASETYPE_OWNER varchar2(32)
TYPE BASETYPE_LIST_T IS TABLE OF BASETYPE_T;
BASETYPE_LIST BASETYPE_LIST_T := BASETYPE_LIST_T();
function findStorageModel(P_TYPE_NAME VARCHAR2, P_TYPE_OWNER VARCHAR2, P_INCLUDE_SUBTYPES VARCHAR2 DEFAULT 'YES') return XMLType;
function getLocalAttributes(P_TYPE_NAME varchar2, P_TYPE_OWNER VARCHAR2) return XMLType;
function makeElement(P_NAME varchar2)
return xmltype
as
V_NAME varchar2(4000) := P_NAME;
begin
-- -- dbms_output.put_line('Processing : ' || P_NAME);
if (P_NAME LIKE '%$') then
V_NAME := SUBSTR(V_NAME,1,LENGTH(V_NAME) - 1);
end if;
if (P_NAME LIKE '%$%') then
V_NAME := REPLACE(V_NAME,'$','_0x22_');
end if;
return XMLTYPE( '<' || V_NAME || '/>');
end;
function getPathToRoot(SUBTYPE VARCHAR2, SUBTYPE_OWNER VARCHAR2)
return varchar2
as
TYPE_HIERARCHY varchar2(4000);
begin
SELECT sys_connect_by_path( OWNER || '.' || TYPE_NAME , '/')
INTO TYPE_HIERARCHY
FROM ALL_TYPES
WHERE TYPE_NAME = SUBTYPE
AND OWNER = SUBTYPE_OWNER
CONNECT BY SUPERTYPE_NAME = PRIOR TYPE_NAME
AND SUPERTYPE_OWNER = PRIOR OWNER
START WITH SUPERTYPE_NAME IS NULL
AND SUPERTYPE_OWNER IS NULL;
return TYPE_HIERARCHY;
end;
function expandSQLType(ATTR_NAME VARCHAR2, SUBTYPE VARCHAR2, SUBTYPE_OWNER VARCHAR2)
return XMLType
as
STORAGE_MODEL XMLTYPE;
ATTRIBUTES XMLTYPE;
EXTENDED_TYPE XMLTYPE;
ATTR_COUNT NUMBER := 0;
CURSOR FIND_EXTENDED_TYPES
is
select TYPE_NAME, OWNER
from ALL_TYPES
where SUPERTYPE_NAME = SUBTYPE
and SUPERTYPE_OWNER = SUBTYPE_OWNER;
begin
-- dbms_output.put_line('Processing SQLType : "' || SUBTYPE_OWNER || '.' || SUBTYPE || '".' );
STORAGE_MODEL := makeElement(ATTR_NAME);
select insertChildXML(STORAGE_MODEL,'/' || STORAGE_MODEL.getRootElement(),'@type',SUBTYPE)
into STORAGE_MODEL
from dual;
select insertChildXML(STORAGE_MODEL,'/' || STORAGE_MODEL.getRootElement(),'@typeOwner',SUBTYPE_OWNER)
into STORAGE_MODEL
from dual;
ATTRIBUTES := getLocalAttributes(SUBTYPE, SUBTYPE_OWNER);
ATTR_COUNT := ATTR_COUNT + ATTRIBUTES.extract('/' || ATTRIBUTES.getRootElement() || '/@columns').getNumberVal();
select appendChildXML(STORAGE_MODEL,'/' || STORAGE_MODEL.getRootElement(),ATTRIBUTES)
into STORAGE_MODEL
from DUAL;
for t in FIND_EXTENDED_TYPES loop
EXTENDED_TYPE := expandSQLType('ExtendedType',T.TYPE_NAME,T.OWNER);
ATTR_COUNT := ATTR_COUNT + EXTENDED_TYPE.extract('/' || EXTENDED_TYPE.getRootElement() || '/@columns').getNumberVal();
select appendChildXML(STORAGE_MODEL,'/' || STORAGE_MODEL.getRootElement(),EXTENDED_TYPE)
into STORAGE_MODEL
from DUAL;
end loop;
select insertChildXML(STORAGE_MODEL,'/' || STORAGE_MODEL.getRootElement(),'@columns',ATTR_COUNT)
into STORAGE_MODEL
from dual;
return STORAGE_MODEL;
end;
function getLocalAttributes(P_TYPE_NAME varchar2, P_TYPE_OWNER VARCHAR2)
return XMLType
as
V_ATTRIBUTE_COUNT NUMBER := 0;
V_TOTAL_ATTRIBUTES NUMBER := 0;
V_TEMP_RESULT NUMBER;
V_COLLECTION_TYPE varchar2(32);
V_COLLECTION_OWNER varchar2(32);
CURSOR FIND_CHILD_ATTRS
is
select ATTR_NAME, ATTR_TYPE_OWNER, ATTR_TYPE_NAME, INHERITED
from ALL_TYPE_ATTRS
where TYPE_NAME = P_TYPE_NAME
and OWNER = P_TYPE_OWNER
and INHERITED = 'NO'
order by ATTR_NO;
V_ATTR DBMS_XMLDOM.DOMATTR;
V_ATTRIBUTE_LIST XMLTYPE;
V_ATTRIBUTE_LIST_DOCUMENT DBMS_XMLDOM.DOMDOCUMENT;
V_ATTRIBUTE_LIST_ROOT DBMS_XMLDOM.DOMELEMENT;
V_ATTRIBUTE XMLTYPE;
V_ATTRIBUTE_DOCUMENT DBMS_XMLDOM.DOMDOCUMENT;
V_ATTRIBUTE_ROOT DBMS_XMLDOM.DOMELEMENT;
V_TYPE_DEFINITION XMLTYPE;
V_TYPE_DEFINITION_DOCUMENT DBMS_XMLDOM.DOMDOCUMENT;
V_TYPE_DEFINITION_ROOT DBMS_XMLDOM.DOMELEMENT;
begin
V_ATTRIBUTE_LIST := makeElement('Attributes');
V_ATTRIBUTE_LIST_DOCUMENT := DBMS_XMLDOM.NEWDOMDOCUMENT(V_ATTRIBUTE_LIST);
V_ATTRIBUTE_LIST_ROOT := DBMS_XMLDOM.GETDOCUMENTELEMENT(V_ATTRIBUTE_LIST_DOCUMENT);
for ATTR in FIND_CHILD_ATTRS loop
-- Finding Element / Attribute Name could be tricky. Use SQLName
V_ATTRIBUTE := makeElement(ATTR.ATTR_NAME);
V_ATTRIBUTE_DOCUMENT := DBMS_XMLDOM.NEWDOMDOCUMENT(V_ATTRIBUTE);
V_ATTRIBUTE_ROOT := DBMS_XMLDOM.GETDOCUMENTELEMENT(V_ATTRIBUTE_DOCUMENT);
begin
-- Check for Attributes based on collection types, With Nested Table storage each Collection will cost 2 columns.
select ELEM_TYPE_NAME, ELEM_TYPE_OWNER
into V_COLLECTION_TYPE, V_COLLECTION_OWNER
from ALL_COLL_TYPES
where TYPE_NAME = ATTR.ATTR_TYPE_NAME
and OWNER = ATTR.ATTR_TYPE_OWNER;
-- -- dbms_output.put_line('Adding "' || ATTR.ATTR_NAME || '". Collection of "' || ATTR.ATTR_TYPE_OWNER || '"."' || ATTR.ATTR_TYPE_NAME || '".');
-- Attribute is a Collection Type.
-- Collection will be managed as a NESTED TABLE
-- Each Collection cost 2 columns.
-- May want to count the number of columns in the NESTED_TABLE at a later date.
V_ATTR := DBMS_XMLDOM.CREATEATTRIBUTE(V_ATTRIBUTE_DOCUMENT,'SQLCollType');
DBMS_XMLDOM.SETVALUE(V_ATTR,ATTR.ATTR_TYPE_NAME);
V_ATTR := DBMS_XMLDOM.SETATTRIBUTENODE(V_ATTRIBUTE_ROOT,V_ATTR);
V_ATTR := DBMS_XMLDOM.CREATEATTRIBUTE(V_ATTRIBUTE_DOCUMENT,'SQLCollTypeOwner');
DBMS_XMLDOM.SETVALUE(V_ATTR,ATTR.ATTR_TYPE_OWNER);
V_ATTR := DBMS_XMLDOM.SETATTRIBUTENODE(V_ATTRIBUTE_ROOT,V_ATTR);
V_ATTR := DBMS_XMLDOM.CREATEATTRIBUTE(V_ATTRIBUTE_DOCUMENT,'SQLType');
DBMS_XMLDOM.SETVALUE(V_ATTR,V_COLLECTION_TYPE);
V_ATTR := DBMS_XMLDOM.SETATTRIBUTENODE(V_ATTRIBUTE_ROOT,V_ATTR);
V_ATTR := DBMS_XMLDOM.CREATEATTRIBUTE(V_ATTRIBUTE_DOCUMENT,'SQLTypeOwner');
DBMS_XMLDOM.SETVALUE(V_ATTR,V_COLLECTION_OWNER);
V_ATTR := DBMS_XMLDOM.SETATTRIBUTENODE(V_ATTRIBUTE_ROOT,V_ATTR);
V_ATTR := DBMS_XMLDOM.CREATEATTRIBUTE(V_ATTRIBUTE_DOCUMENT,'columns');
DBMS_XMLDOM.SETVALUE(V_ATTR,2);
V_ATTR := DBMS_XMLDOM.SETATTRIBUTENODE(V_ATTRIBUTE_ROOT,V_ATTR);
exception
when no_data_found then
-- Attribute is not a collection type.
begin
-- Check for Attributes based on non-scalar types.
select 1
into V_TEMP_RESULT
from ALL_TYPES
where TYPE_NAME = ATTR.ATTR_TYPE_NAME
and OWNER = ATTR.ATTR_TYPE_OWNER;
-- Attribute is based on a non-scalar type. Find the Storage Model for this type.
V_ATTR := DBMS_XMLDOM.CREATEATTRIBUTE(V_ATTRIBUTE_DOCUMENT,'SQLType');
DBMS_XMLDOM.SETVALUE(V_ATTR,ATTR.ATTR_TYPE_NAME);
V_ATTR := DBMS_XMLDOM.SETATTRIBUTENODE(V_ATTRIBUTE_ROOT,V_ATTR);
V_ATTR := DBMS_XMLDOM.CREATEATTRIBUTE(V_ATTRIBUTE_DOCUMENT,'SQLTypeOwner');
DBMS_XMLDOM.SETVALUE(V_ATTR,ATTR.ATTR_TYPE_OWNER);
V_ATTR := DBMS_XMLDOM.SETATTRIBUTENODE(V_ATTRIBUTE_ROOT,V_ATTR);
V_TYPE_DEFINITION := findStorageModel(ATTR.ATTR_TYPE_NAME, ATTR.ATTR_TYPE_OWNER, 'YES');
V_TYPE_DEFINITION_DOCUMENT := DBMS_XMLDOM.NEWDOMDOCUMENT(V_TYPE_DEFINITION);
V_TYPE_DEFINITION_ROOT := DBMS_XMLDOM.GETDOCUMENTELEMENT(V_TYPE_DEFINITION_DOCUMENT);
V_ATTRIBUTE_COUNT := DBMS_XMLDOM.GETATTRIBUTE(V_TYPE_DEFINITION_ROOT,'columns');
V_TYPE_DEFINITION_ROOT := DBMS_XMLDOM.MAKEELEMENT(DBMS_XMLDOM.IMPORTNODE(V_ATTRIBUTE_DOCUMENT,DBMS_XMLDOM.MAKENODE(V_TYPE_DEFINITION_ROOT),TRUE));
V_TYPE_DEFINITION_ROOT := DBMS_XMLDOM.MAKEELEMENT(DBMS_XMLDOM.APPENDCHILD(DBMS_XMLDOM.MAKENODE(V_ATTRIBUTE_ROOT),DBMS_XMLDOM.MAKENODE(V_TYPE_DEFINITION_ROOT)));
DBMS_XMLDOM.FREEDOCUMENT(V_TYPE_DEFINITION_DOCUMENT);
if (ATTR.ATTR_TYPE_NAME = 'XDB$ENUM_T' and ATTR.ATTR_TYPE_OWNER = 'XDB') then
-- The cost of a XDB$ENUM_T is 2 columns
V_ATTR := DBMS_XMLDOM.CREATEATTRIBUTE(V_ATTRIBUTE_DOCUMENT,'columns');
DBMS_XMLDOM.SETVALUE(V_ATTR,2);
V_ATTR := DBMS_XMLDOM.SETATTRIBUTENODE(V_ATTRIBUTE_ROOT,V_ATTR);
else
-- The cost of a non scalar Type is the number of attributes plus one for Type and one for the TYPEID.
V_ATTR := DBMS_XMLDOM.CREATEATTRIBUTE(V_ATTRIBUTE_DOCUMENT,'columns');
DBMS_XMLDOM.SETVALUE(V_ATTR,V_ATTRIBUTE_COUNT + 2);
V_ATTR := DBMS_XMLDOM.SETATTRIBUTENODE(V_ATTRIBUTE_ROOT,V_ATTR);
end if;
exception
when no_data_found then
-- Attribute is based on a scalar type
V_ATTR := DBMS_XMLDOM.CREATEATTRIBUTE(V_ATTRIBUTE_DOCUMENT,'SQLType');
DBMS_XMLDOM.SETVALUE(V_ATTR,ATTR.ATTR_TYPE_NAME);
V_ATTR := DBMS_XMLDOM.SETATTRIBUTENODE(V_ATTRIBUTE_ROOT,V_ATTR);
V_ATTR := DBMS_XMLDOM.CREATEATTRIBUTE(V_ATTRIBUTE_DOCUMENT,'columns');
DBMS_XMLDOM.SETVALUE(V_ATTR,1);
V_ATTR := DBMS_XMLDOM.SETATTRIBUTENODE(V_ATTRIBUTE_ROOT,V_ATTR);
end;
end;
V_TOTAL_ATTRIBUTES := V_TOTAL_ATTRIBUTES + DBMS_XMLDOM.GETATTRIBUTE(V_ATTRIBUTE_ROOT,'columns');
V_ATTRIBUTE_ROOT := DBMS_XMLDOM.MAKEELEMENT(DBMS_XMLDOM.IMPORTNODE(V_ATTRIBUTE_LIST_DOCUMENT,DBMS_XMLDOM.MAKENODE(V_ATTRIBUTE_ROOT),TRUE));
V_ATTRIBUTE_ROOT := DBMS_XMLDOM.MAKEELEMENT(DBMS_XMLDOM.APPENDCHILD(DBMS_XMLDOM.MAKENODE(V_ATTRIBUTE_LIST_ROOT),DBMS_XMLDOM.MAKENODE(V_ATTRIBUTE_ROOT)));
DBMS_XMLDOM.FREEDOCUMENT(V_ATTRIBUTE_DOCUMENT);
if (V_TOTAL_ATTRIBUTES > 25000) then
exit;
end if;
end loop;
V_ATTR := DBMS_XMLDOM.CREATEATTRIBUTE(V_ATTRIBUTE_LIST_DOCUMENT,'columns');
DBMS_XMLDOM.SETVALUE(V_ATTR,V_TOTAL_ATTRIBUTES);
V_ATTR := DBMS_XMLDOM.SETATTRIBUTENODE(V_ATTRIBUTE_LIST_ROOT,V_ATTR);
return V_ATTRIBUTE_LIST;
end;
function getSubTypes(P_TYPE_NAME VARCHAR2, P_TYPE_OWNER VARCHAR2)
return XMLType
as
CURSOR FIND_SUBTYPES
is
select TYPE_NAME, OWNER
from ALL_TYPES
where SUPERTYPE_NAME = P_TYPE_NAME
and SUPERTYPE_OWNER = P_TYPE_OWNER;
CURSOR FIND_SUBTYPE_HEIRARCHY
is
select LEVEL, TYPE_NAME, OWNER
from ALL_TYPES
where TYPE_NAME <> P_TYPE_NAME
and OWNER <> P_TYPE_OWNER
connect by SUPERTYPE_NAME = PRIOR TYPE_NAME
and SUPERTYPE_OWNER = PRIOR OWNER
start with TYPE_NAME = P_TYPE_NAME
and OWNER = P_TYPE_OWNER;
V_SUBTYPE_LIST XMLType;
V_SUBTYPE_LIST_DOCUMENT DBMS_XMLDOM.DOMDOCUMENT;
V_SUBTYPE_LIST_ROOT DBMS_XMLDOM.DOMELEMENT;
V_TYPE_DEFINITION XMLType;
V_TYPE_DEFINITION_DOCUMENT DBMS_XMLDOM.DOMDOCUMENT;
V_TYPE_DEFINITION_ROOT DBMS_XMLDOM.DOMELEMENT;
V_SUBTYPE_DEFINITIONS XMLType;
V_SUBTYPE_DEFINITIONS_DOCUMENT DBMS_XMLDOM.DOMDOCUMENT;
V_SUBTYPE_DEFINITIONS_ROOT DBMS_XMLDOM.DOMELEMENT;
V_ATTRIBUTE_LIST XMLType;
V_ATTRIBUTE_LIST_DOCUMENT DBMS_XMLDOM.DOMDOCUMENT;
V_ATTRIBUTE_LIST_ROOT DBMS_XMLDOM.DOMELEMENT;
V_SUBTYPES_EXIST BOOLEAN := FALSE;
V_TOTAL_columns number;
V_ATTRIBUTE_COUNT number;
V_ATTR DBMS_XMLDOM.DOMATTR;
V_COMPLEX_TYPE VARCHAR2(256);
begin
V_SUBTYPE_LIST := makeElement('SubTypeDefinitions');
V_SUBTYPE_LIST_DOCUMENT := DBMS_XMLDOM.NEWDOMDOCUMENT(V_SUBTYPE_LIST);
V_SUBTYPE_LIST_ROOT := DBMS_XMLDOM.GETDOCUMENTELEMENT(V_SUBTYPE_LIST_DOCUMENT);
V_TOTAL_columns := 0;
for t in FIND_SUBTYPES() loop
V_SUBTYPES_EXIST := TRUE;
V_TYPE_DEFINITION := makeElement(t.TYPE_NAME);
V_TYPE_DEFINITION_DOCUMENT := DBMS_XMLDOM.NEWDOMDOCUMENT(V_TYPE_DEFINITION);
V_TYPE_DEFINITION_ROOT := DBMS_XMLDOM.GETDOCUMENTELEMENT(V_TYPE_DEFINITION_DOCUMENT);
V_ATTR := DBMS_XMLDOM.CREATEATTRIBUTE(V_TYPE_DEFINITION_DOCUMENT,'SQLTypeOwner');
DBMS_XMLDOM.SETVALUE(V_ATTR,t.OWNER);
V_ATTR := DBMS_XMLDOM.SETATTRIBUTENODE(V_TYPE_DEFINITION_ROOT,V_ATTR);
begin
select x.XMLDATA.NAME
into V_COMPLEX_TYPE
from XDB.XDB$COMPLEX_TYPE x
where x.XMLDATA.SQLTYPE = t.TYPE_NAME
and x.XMLDATA.SQLSCHEMA = t.OWNER;
V_ATTR := DBMS_XMLDOM.CREATEATTRIBUTE(V_TYPE_DEFINITION_DOCUMENT,'type');
DBMS_XMLDOM.SETVALUE(V_ATTR,V_COMPLEX_TYPE);
V_ATTR := DBMS_XMLDOM.SETATTRIBUTENODE(V_TYPE_DEFINITION_ROOT,V_ATTR);
-- Consider adding Schema URL Attribute
exception
when no_data_found then
null;
when others then
raise;
end;
V_ATTRIBUTE_LIST := getLocalAttributes(t.TYPE_NAME, t.OWNER);
V_ATTRIBUTE_LIST_DOCUMENT := DBMS_XMLDOM.NEWDOMDOCUMENT(V_ATTRIBUTE_LIST);
V_ATTRIBUTE_LIST_ROOT := DBMS_XMLDOM.GETDOCUMENTELEMENT(V_ATTRIBUTE_LIST_DOCUMENT);
V_ATTRIBUTE_COUNT := DBMS_XMLDOM.GETATTRIBUTE(V_ATTRIBUTE_LIST_ROOT,'columns');
V_ATTRIBUTE_LIST_ROOT := DBMS_XMLDOM.MAKEELEMENT(DBMS_XMLDOM.IMPORTNODE(V_TYPE_DEFINITION_DOCUMENT,DBMS_XMLDOM.MAKENODE(V_ATTRIBUTE_LIST_ROOT),TRUE));
V_ATTRIBUTE_LIST_ROOT := DBMS_XMLDOM.MAKEELEMENT(DBMS_XMLDOM.APPENDCHILD(DBMS_XMLDOM.MAKENODE(V_TYPE_DEFINITION_ROOT),DBMS_XMLDOM.MAKENODE(V_ATTRIBUTE_LIST_ROOT)));
DBMS_XMLDOM.FREEDOCUMENT(V_ATTRIBUTE_LIST_DOCUMENT);
V_SUBTYPE_DEFINITIONS := getSubTypes(t.TYPE_NAME,t.OWNER);
if (V_SUBTYPE_DEFINITIONS is not NULL) then
V_SUBTYPE_DEFINITIONS_DOCUMENT := DBMS_XMLDOM.NEWDOMDOCUMENT(V_SUBTYPE_DEFINITIONS);
V_SUBTYPE_DEFINITIONS_ROOT := DBMS_XMLDOM.GETDOCUMENTELEMENT(V_SUBTYPE_DEFINITIONS_DOCUMENT);
V_ATTRIBUTE_COUNT := V_ATTRIBUTE_COUNT + DBMS_XMLDOM.GETATTRIBUTE(V_SUBTYPE_DEFINITIONS_ROOT,'columns');
V_SUBTYPE_DEFINITIONS_ROOT := DBMS_XMLDOM.MAKEELEMENT(DBMS_XMLDOM.IMPORTNODE(V_TYPE_DEFINITION_DOCUMENT,DBMS_XMLDOM.MAKENODE(V_SUBTYPE_DEFINITIONS_ROOT),TRUE));
V_SUBTYPE_DEFINITIONS_ROOT := DBMS_XMLDOM.MAKEELEMENT(DBMS_XMLDOM.APPENDCHILD(DBMS_XMLDOM.MAKENODE(V_TYPE_DEFINITION_ROOT),DBMS_XMLDOM.MAKENODE(V_SUBTYPE_DEFINITIONS_ROOT)));
end if;
V_ATTR := DBMS_XMLDOM.CREATEATTRIBUTE(V_TYPE_DEFINITION_DOCUMENT,'columns');
DBMS_XMLDOM.SETVALUE(V_ATTR,V_ATTRIBUTE_COUNT);
V_ATTR := DBMS_XMLDOM.SETATTRIBUTENODE(V_TYPE_DEFINITION_ROOT,V_ATTR);
V_TYPE_DEFINITION_ROOT := DBMS_XMLDOM.MAKEELEMENT(DBMS_XMLDOM.IMPORTNODE(V_SUBTYPE_LIST_DOCUMENT,DBMS_XMLDOM.MAKENODE(V_TYPE_DEFINITION_ROOT),TRUE));
V_TYPE_DEFINITION_ROOT := DBMS_XMLDOM.MAKEELEMENT(DBMS_XMLDOM.APPENDCHILD(DBMS_XMLDOM.MAKENODE(V_SUBTYPE_LIST_ROOT),DBMS_XMLDOM.MAKENODE(V_TYPE_DEFINITION_ROOT)));
V_TOTAL_columns := V_TOTAL_columns + V_ATTRIBUTE_COUNT;
end loop;
if (V_SUBTYPES_EXIST) then
V_ATTR := DBMS_XMLDOM.CREATEATTRIBUTE(V_SUBTYPE_LIST_DOCUMENT,'columns');
DBMS_XMLDOM.SETVALUE(V_ATTR,V_TOTAL_columns);
V_ATTR := DBMS_XMLDOM.SETATTRIBUTENODE(V_SUBTYPE_LIST_ROOT,V_ATTR);
return V_SUBTYPE_LIST;
else
return NULL;
end if;
end;
function findSuperTypeModel(P_TYPE_NAME VARCHAR2, P_TYPE_OWNER VARCHAR2)
return XMLType
as
begin
-- dbms_output.put_line('Processing Super Type : "' || P_TYPE_OWNER || '"."' || P_TYPE_NAME || '"');
return findStorageModel(P_TYPE_NAME, P_TYPE_OWNER,'NO');
end;
function getStorageModel(P_TYPE_NAME VARCHAR2, P_TYPE_OWNER VARCHAR2, P_INCLUDE_SUBTYPES VARCHAR2 DEFAULT 'YES')
return XMLType
as
V_TYPE_DEFINITION XMLTYPE;
V_ATTRIBUTE_COUNT NUMBER := 0;
SUBTYPE_STORAGE_MODEL XMLTYPE;
V_SUPERTYPE_DEFINITION XMLTYPE;
V_SUPERTYPE_DOCUMENT DBMS_XMLDOM.DOMDOCUMENT;
V_SUPERTYPE_ROOT DBMS_XMLDOM.DOMELEMENT;
V_SUBTYPE_DEFINITION XMLTYPE;
V_SUBTYPE_DOCUMENT DBMS_XMLDOM.DOMDOCUMENT;
V_SUBTYPE_ROOT DBMS_XMLDOM.DOMELEMENT;
V_ATTRIBUTE_LIST XMLTYPE;
V_ATTRIBUTE_LIST_DOCUMENT DBMS_XMLDOM.DOMDOCUMENT;
V_ATTRIBUTE_LIST_ROOT DBMS_XMLDOM.DOMELEMENT;
cursor FIND_SUPERTYPE_HEIRARCHY
is
select TYPE_NAME, OWNER
from ALL_TYPES
where TYPE_NAME <> P_TYPE_NAME
and OWNER <> P_TYPE_OWNER
connect by TYPE_NAME = PRIOR SUPERTYPE_NAME
and OWNER = PRIOR SUPERTYPE_OWNER
start with TYPE_NAME = P_TYPE_NAME
and OWNER = P_TYPE_OWNER
order by LEVEL;
V_COMPLEX_TYPE varchar2(256);
V_SUPERTYPE_NAME varchar2(256);
v_SUPERTYPE_OWNER varchar2(256);
V_DOCUMENT DBMS_XMLDOM.DOMDOCUMENT;
V_ROOT DBMS_XMLDOM.DOMELEMENT;
V_ATTR DBMS_XMLDOM.DOMATTR;
begin
-- dbms_output.put_line('Generating Storage Model for : "' || P_TYPE_OWNER || '"."' || P_TYPE_NAME || '"');
V_TYPE_DEFINITION := makeElement(P_TYPE_NAME);
V_DOCUMENT := DBMS_XMLDOM.NEWDOMDOCUMENT(V_TYPE_DEFINITION);
V_ROOT := DBMS_XMLDOM.GETDOCUMENTELEMENT(V_DOCUMENT);
V_ATTR := DBMS_XMLDOM.CREATEATTRIBUTE(V_DOCUMENT,'SQLTypeOwner');
DBMS_XMLDOM.SETVALUE(V_ATTR,P_TYPE_OWNER);
V_ATTR := DBMS_XMLDOM.SETATTRIBUTENODE(V_ROOT,V_ATTR);
begin
select x.XMLDATA.NAME
into V_COMPLEX_TYPE
from XDB.XDB$COMPLEX_TYPE x
where x.XMLDATA.SQLTYPE = P_TYPE_NAME
and x.XMLDATA.SQLSCHEMA = P_TYPE_OWNER;
V_ATTR := DBMS_XMLDOM.CREATEATTRIBUTE(V_DOCUMENT,'type');
DBMS_XMLDOM.SETVALUE(V_ATTR,V_COMPLEX_TYPE);
V_ATTR := DBMS_XMLDOM.SETATTRIBUTENODE(V_ROOT,V_ATTR);
-- Consider adding Schema URL Attribute
exception
when no_data_found then
null;
when others then
raise;
end;
select SUPERTYPE_NAME, SUPERTYPE_OWNER
into V_SUPERTYPE_NAME, V_SUPERTYPE_OWNER
from ALL_TYPES
where TYPE_NAME = P_TYPE_NAME
and OWNER = P_TYPE_OWNER;
-- Process SuperType.
if (V_SUPERTYPE_NAME is not null) then
V_ATTR := DBMS_XMLDOM.CREATEATTRIBUTE(V_DOCUMENT,'SQLParentType');
DBMS_XMLDOM.SETVALUE(V_ATTR,V_SUPERTYPE_NAME);
V_ATTR := DBMS_XMLDOM.SETATTRIBUTENODE(V_ROOT,V_ATTR);
V_ATTR := DBMS_XMLDOM.CREATEATTRIBUTE(V_DOCUMENT,'SQLParentTypeOwner');
DBMS_XMLDOM.SETVALUE(V_ATTR,V_SUPERTYPE_OWNER);
V_ATTR := DBMS_XMLDOM.SETATTRIBUTENODE(V_ROOT,V_ATTR);
-- Find the Definition for the super type. Do not include the definition of it's subtypes.
V_SUPERTYPE_DEFINITION := findSuperTypeModel(V_SUPERTYPE_NAME, V_SUPERTYPE_OWNER);
-- -- dbms_output.put_line(dbms_lob.substr(V_SUPERTYPE_DEFINITION.getClobVal(),1000,1));
V_SUPERTYPE_DOCUMENT := DBMS_XMLDOM.NEWDOMDOCUMENT(V_SUPERTYPE_DEFINITION);
V_SUPERTYPE_ROOT := DBMS_XMLDOM.GETDOCUMENTELEMENT(V_SUPERTYPE_DOCUMENT);
V_ATTRIBUTE_COUNT := V_ATTRIBUTE_COUNT + DBMS_XMLDOM.GETATTRIBUTE(V_SUPERTYPE_ROOT,'columns');
V_SUPERTYPE_ROOT := DBMS_XMLDOM.MAKEELEMENT(DBMS_XMLDOM.IMPORTNODE(V_DOCUMENT,DBMS_XMLDOM.MAKENODE(V_SUPERTYPE_ROOT),TRUE));
V_SUPERTYPE_ROOT := DBMS_XMLDOM.MAKEELEMENT(DBMS_XMLDOM.APPENDCHILD(DBMS_XMLDOM.MAKENODE(V_ROOT),DBMS_XMLDOM.MAKENODE(V_SUPERTYPE_ROOT)));
DBMS_XMLDOM.FREEDOCUMENT(V_SUPERTYPE_DOCUMENT);
end if;
-- Process Attributes defined directly by the Type.
V_ATTRIBUTE_LIST := getLocalAttributes(P_TYPE_NAME, P_TYPE_OWNER);
V_ATTRIBUTE_LIST_DOCUMENT := DBMS_XMLDOM.NEWDOMDOCUMENT(V_ATTRIBUTE_LIST);
V_ATTRIBUTE_LIST_ROOT := DBMS_XMLDOM.GETDOCUMENTELEMENT(V_ATTRIBUTE_LIST_DOCUMENT);
V_ATTRIBUTE_COUNT := V_ATTRIBUTE_COUNT + DBMS_XMLDOM.GETATTRIBUTE(V_ATTRIBUTE_LIST_ROOT,'columns');
V_ATTRIBUTE_LIST_ROOT := DBMS_XMLDOM.MAKEELEMENT(DBMS_XMLDOM.IMPORTNODE(V_DOCUMENT,DBMS_XMLDOM.MAKENODE(V_ATTRIBUTE_LIST_ROOT),TRUE));
V_ATTRIBUTE_LIST_ROOT := DBMS_XMLDOM.MAKEELEMENT(DBMS_XMLDOM.APPENDCHILD(DBMS_XMLDOM.MAKENODE(V_ROOT),DBMS_XMLDOM.MAKENODE(V_ATTRIBUTE_LIST_ROOT)));
DBMS_XMLDOM.FREEDOCUMENT(V_ATTRIBUTE_LIST_DOCUMENT);
if (P_INCLUDE_SUBTYPES = 'YES') then
-- Process any Sub-Types...
V_SUBTYPE_DEFINITION := getSubTypes(P_TYPE_NAME, P_TYPE_OWNER);
if (V_SUBTYPE_DEFINITION is not null) then
V_SUBTYPE_DOCUMENT := DBMS_XMLDOM.NEWDOMDOCUMENT(V_SUBTYPE_DEFINITION);
V_SUBTYPE_ROOT := DBMS_XMLDOM.GETDOCUMENTELEMENT(V_SUBTYPE_DOCUMENT);
V_ATTRIBUTE_COUNT := V_ATTRIBUTE_COUNT + DBMS_XMLDOM.GETATTRIBUTE(V_SUBTYPE_ROOT,'columns');
V_SUBTYPE_ROOT := DBMS_XMLDOM.MAKEELEMENT(DBMS_XMLDOM.IMPORTNODE(V_DOCUMENT,DBMS_XMLDOM.MAKENODE(V_SUBTYPE_ROOT),TRUE));
V_SUBTYPE_ROOT := DBMS_XMLDOM.MAKEELEMENT(DBMS_XMLDOM.APPENDCHILD(DBMS_XMLDOM.MAKENODE(V_ROOT),DBMS_XMLDOM.MAKENODE(V_SUBTYPE_ROOT)));
DBMS_XMLDOM.FREEDOCUMENT(V_SUBTYPE_DOCUMENT);
end if;
end if;
V_ATTR := DBMS_XMLDOM.CREATEATTRIBUTE(V_DOCUMENT,'columns');
DBMS_XMLDOM.SETVALUE(V_ATTR,V_ATTRIBUTE_COUNT);
V_ATTR := DBMS_XMLDOM.SETATTRIBUTENODE(V_ROOT,V_ATTR);
-- Cache the type definition.
-- dbms_output.put_line('Cached Storage Model for "' || P_TYPE_OWNER || '.' || P_TYPE_NAME || '".');
insert into XDBPM.XDBPM_STORAGE_MODEL_CACHE (TYPE_NAME, TYPE_OWNER, EXTENDED_DEFINITION, STORAGE_MODEL) VALUES (P_TYPE_NAME, P_TYPE_OWNER, P_INCLUDE_SUBTYPES, V_TYPE_DEFINITION);
return V_TYPE_DEFINITION;
end;
function findStorageModel(P_TYPE_NAME VARCHAR2, P_TYPE_OWNER VARCHAR2, P_INCLUDE_SUBTYPES VARCHAR2 DEFAULT 'YES')
-- Find the Storage Model for the Base Type.
-- If the type is derived from another type we need the storage model of the Base Type
-- As storage models are calculated they are cached in the global temporary table XDBPM_STORAGE_MODEL_CACHE. This makes
-- the process much more efficient. A global temporary table is used to minimize memory usage.
return XMLType
as
V_STORAGE_MODEL XMLType;
V_STORAGE_MODEL_DOCUMENT DBMS_XMLDOM.DOMDOCUMENT;
V_STORAGE_MODEL_ROOT DBMS_XMLDOM.DOMELEMENT;
V_ATTRIBUTE_COUNT VARCHAR2(10);
begin
dbms_output.put_line('findStorageModel(' || G_DEPTH_COUNT || ') : Processing "' || P_TYPE_OWNER || '"."' || P_TYPE_NAME || '".' );
begin
SELECT STORAGE_MODEL
into V_STORAGE_MODEL
from XDBPM.XDBPM_STORAGE_MODEL_CACHE
where TYPE_NAME = P_TYPE_NAME
and TYPE_OWNER = P_TYPE_OWNER
and EXTENDED_DEFINITION = P_INCLUDE_SUBTYPES;
-- dbms_output.put_line('Resolved Storage Model from cache.');
exception
when no_data_found then
G_DEPTH_COUNT := G_DEPTH_COUNT + 1;
V_STORAGE_MODEL := getStorageModel(P_TYPE_NAME,P_TYPE_OWNER, P_INCLUDE_SUBTYPES);
G_DEPTH_COUNT := G_DEPTH_COUNT - 1;
when others then
raise;
end;
V_STORAGE_MODEL_DOCUMENT := DBMS_XMLDOM.NEWDOMDOCUMENT(V_STORAGE_MODEL);
V_STORAGE_MODEL_ROOT := DBMS_XMLDOM.GETDOCUMENTELEMENT(V_STORAGE_MODEL_DOCUMENT);
V_ATTRIBUTE_COUNT := DBMS_XMLDOM.GETATTRIBUTE(V_STORAGE_MODEL_ROOT,'columns');
dbms_output.put_line('findStorageModel : Attribute Count for "' || P_TYPE_OWNER || '"."' || P_TYPE_NAME || '" = ' || V_ATTRIBUTE_COUNT || '.' );
return V_STORAGE_MODEL;
end;
function analyzeStorageModel(P_COMPLEX_TYPE_NAME VARCHAR2, P_TYPE_NAME VARCHAR2, P_TYPE_OWNER VARCHAR2)
-- Generate a map showing the number of columns required to persist an instance of the SQL type.
return XMLType
as
V_STORAGE_MODEL XMLTYPE;
V_COUNT NUMBER := 0;
V_DOCUMENT DBMS_XMLDOM.DOMDOCUMENT;
V_ROOT DBMS_XMLDOM.DOMELEMENT;
V_ATTR DBMS_XMLDOM.DOMATTR;
V_MODEL DBMS_XMLDOM.DOMELEMENT;
V_TYPE_DEFINITION DBMS_XMLDOM.DOMELEMENT;
begin
V_STORAGE_MODEL := makeElement(P_COMPLEX_TYPE_NAME);
V_DOCUMENT := DBMS_XMLDOM.NEWDOMDOCUMENT(V_STORAGE_MODEL);
V_ROOT := DBMS_XMLDOM.GETDOCUMENTELEMENT(V_DOCUMENT);
V_ATTR := DBMS_XMLDOM.CREATEATTRIBUTE(V_DOCUMENT,'SQLType');
DBMS_XMLDOM.SETVALUE(V_ATTR,P_TYPE_NAME);
V_ATTR := DBMS_XMLDOM.SETATTRIBUTENODE(V_ROOT,V_ATTR);
V_ATTR := DBMS_XMLDOM.CREATEATTRIBUTE(V_DOCUMENT,'SQLTypeOwner');
DBMS_XMLDOM.SETVALUE(V_ATTR,P_TYPE_OWNER);
V_ATTR := DBMS_XMLDOM.SETATTRIBUTENODE(V_ROOT,V_ATTR);
V_TYPE_DEFINITION := DBMS_XMLDOM.GETDOCUMENTELEMENT(DBMS_XMLDOM.NEWDOMDOCUMENT(findStorageModel(P_TYPE_NAME, P_TYPE_OWNER, 'YES')));
V_TYPE_DEFINITION := DBMS_XMLDOM.MAKEELEMENT(DBMS_XMLDOM.IMPORTNODE(V_DOCUMENT,DBMS_XMLDOM.MAKENODE(V_TYPE_DEFINITION),TRUE));
V_TYPE_DEFINITION := DBMS_XMLDOM.MAKEELEMENT(DBMS_XMLDOM.APPENDCHILD(DBMS_XMLDOM.MAKENODE(V_ROOT),DBMS_XMLDOM.MAKENODE(V_TYPE_DEFINITION)));
V_ATTR := DBMS_XMLDOM.CREATEATTRIBUTE(V_DOCUMENT,'columns');
DBMS_XMLDOM.SETVALUE(V_ATTR,DBMS_XMLDOM.GETATTRIBUTE(V_TYPE_DEFINITION,'columns'));
V_ATTR := DBMS_XMLDOM.SETATTRIBUTENODE(V_ROOT,V_ATTR);
return V_STORAGE_MODEL;
end;
function analyzeStorageModel(P_COMPLEX_TYPE_NAME VARCHAR2)
return XMLTYPE
-- Generate a map showing the number of columns required to persist an instance of the complex type.
as
pragma autonomous_transaction;
V_SQLTYPE VARCHAR2(128);
V_SQLSCHEMA VARCHAR2(32);
V_RESULT XMLType;
begin
G_DEPTH_COUNT := 0;
select ct.XMLDATA.SQLTYPE, ct.XMLDATA.SQLSCHEMA
into V_SQLTYPE, V_SQLSCHEMA
from XDB.XDB$COMPLEX_TYPE ct, XDB.XDB$SCHEMA s
where ct.XMLDATA.NAME = P_COMPLEX_TYPE_NAME
and ref(s) = ct.XMLDATA.PARENT_SCHEMA
and s.XMLDATA.SCHEMA_OWNER = USER;
delete from XDBPM.XDBPM_STORAGE_MODEL_CACHE;
-- delete from XDBPM.XDBPM_STORAGE_MODEL;
V_RESULT := analyzeStorageModel(P_COMPLEX_TYPE_NAME,V_SQLTYPE,V_SQLSCHEMA);
COMMIT;
return V_RESULT;
exception
when no_data_found then
-- dbms_output.put_line('Unable to find SQLType mapping for complexType : "' || USER || '"."' || P_COMPLEX_TYPE_NAME || '".' );
return null;
when others then
raise;
end;
function analyzeSQLType(ATTR_NAME VARCHAR2, TARGET_TYPE_NAME VARCHAR2, TARGET_TYPE_OWNER VARCHAR2)
return XMLType
as
ROOT_NODE_NAME VARCHAR2(128);
ATTR_DETAIL XMLTYPE;
XPATH_EXPRESSION VARCHAR2(129);
CURSOR FIND_CHILD_ATTRS is
select ATTR_NAME, ATTR_TYPE_OWNER, ATTR_TYPE_NAME, INHERITED
from ALL_TYPE_ATTRS
where OWNER = TARGET_TYPE_OWNER
and TYPE_NAME = TARGET_TYPE_NAME
order by ATTR_NO;
CHILD_ATTR XMLTYPE;
ATTR_COUNT NUMBER := 0;
TEMP number;
COLLECTION_TYPE_NAME varchar2(256);
COLLECTION_TYPE_OWNER varchar2(256);
begin
-- -- dbms_output.put_line('Processing Attribute ' || ATTR_NAME || ' of ' || TARGET_TYPE_OWNER || '.' || TARGET_TYPE_NAME );
ATTR_DETAIL := makeElement(ATTR_NAME);
XPATH_EXPRESSION := '/' || ATTR_DETAIL.GETROOTELEMENT();
for ATTR in FIND_CHILD_ATTRS loop
begin
select ELEM_TYPE_NAME, ELEM_TYPE_OWNER
into COLLECTION_TYPE_NAME, COLLECTION_TYPE_OWNER
from ALL_COLL_TYPES
where TYPE_NAME = ATTR.ATTR_TYPE_NAME
and OWNER = ATTR.ATTR_TYPE_OWNER;
CHILD_ATTR := analyzeSQLType(ATTR.ATTR_NAME, COLLECTION_TYPE_NAME, COLLECTION_TYPE_OWNER );
ATTR_COUNT := ATTR_COUNT + CHILD_ATTR.extract('/' || CHILD_ATTR.GETROOTELEMENT() || '/@sqlAttrs').getNumberVal();
select appendChildXML(ATTR_DETAIL,XPATH_EXPRESSION,CHILD_ATTR)
into ATTR_DETAIL
from DUAL;
exception
when no_data_found then
begin
select 1
into TEMP
from ALL_TYPES
where TYPE_NAME = ATTR.ATTR_TYPE_NAME
and OWNER = ATTR.ATTR_TYPE_OWNER;
CHILD_ATTR := analyzeSQLType(ATTR.ATTR_NAME, ATTR.ATTR_TYPE_NAME, ATTR.ATTR_TYPE_OWNER );
ATTR_COUNT := ATTR_COUNT + CHILD_ATTR.extract('/' || CHILD_ATTR.GETROOTELEMENT() || '/@sqlAttrs').getNumberVal();
select appendChildXML(ATTR_DETAIL,XPATH_EXPRESSION,CHILD_ATTR)
into ATTR_DETAIL
from DUAL;
exception
when no_data_found then
ATTR_COUNT := ATTR_COUNT + 1;
end;
end;
end loop;
select insertChildXML(ATTR_DETAIL,XPATH_EXPRESSION,'@sqlAttrs',ATTR_COUNT)
into ATTR_DETAIL
from dual;
return ATTR_DETAIL;
end;
function analyzeComplexType(COMPLEX_TYPE VARCHAR2)
return XMLType
as
RESULT xmltype;
SQLTYPE varchar2(128);
SQLTYPE_OWNER varchar2(32);
begin
select SQLTYPE, SQLTYPE_OWNER
into SQLTYPE, SQLTYPE_OWNER
from USER_XML_SCHEMAS,
xmlTable
xmlnamespaces
'http://www.w3.org/2001/XMLSchema' as "xsd",
'http://xmlns.oracle.com/xdb' as "xdb"
'/xsd:schema/xsd:complexType'
passing Schema
columns
COMPLEX_TYPE_NAME varchar2(4000) path '@name',
SQLTYPE varchar2(128) path '@xdb:SQLType',
SQLTYPE_OWNER varchar2(32) path '@xdb:SQLSchema'
where COMPLEX_TYPE_NAME = COMPLEX_TYPE;
result := analyzeSQLType(COMPLEX_TYPE,SQLTYPE,SQLTYPE_OWNER);
select insertChildXML(RESULT,'/' || COMPLEX_TYPE,'@SQLType',SQLTYPE)
into result
from dual;
return result;
end;
function showSQLTypes(schemaFolder varchar2) return XMLType
is
xmlSchema XMLTYPE;
begin
select xmlElement
"TypeList",
xmlAgg
xmlElement
"Schema",
xmlElement
"ResourceName",
extractValue(res,'/Resource/DisplayName')
xmlElement
"complexTypes",
select xmlAgg
xmlElement
"complexType",
xmlElement
"name",
extractValue(value(XML),'/xsd:complexType/@name',XDB_NAMESPACES.XDBSCHEMA_PREFIXES)
xmlElement
"SQLType",
extractValue(value(XML),'/xsd:complexType/@xdb:SQLType',XDB_NAMESPACES.XDBSCHEMA_PREFIXES)
from table
xmlsequence
extract
xdburitype(p.path).getXML(),
'/xsd:schema/xsd:complexType',
XDB_NAMESPACES.XDBSCHEMA_PREFIXES
) xml
-- order by extractValue(value(XML),'/xsd:complexType/@name',XDB_NAMESPACES.XDBSCHEMA_PREFIXES)
).extract('/*')
into xmlSchema
from path_view p
where under_path(res,schemaFolder) = 1
order by extractValue(res,'/Resource/DisplayName');
return xmlSchema;
end;
procedure renameCollectionTable (XMLTABLE varchar2, XPATH varchar2, COLLECTION_TABLE_PREFIX varchar2)
as
SYSTEM_GENERATED_NAME varchar2(256);
COLLECTION_TABLE_NAME varchar2(256);
CLUSTERED_INDEX_NAME varchar2(256);
PARENT_INDEX_NAME varchar2(256);
RENAME_STATEMENT varchar2(4000);
begin
COLLECTION_TABLE_NAME := COLLECTION_TABLE_PREFIX || '_TABLE';
CLUSTERED_INDEX_NAME := COLLECTION_TABLE_PREFIX || '_DATA';
PARENT_INDEX_NAME := COLLECTION_TABLE_PREFIX || '_LIST';
select TABLE_NAME
into SYSTEM_GENERATED_NAME
from ALL_NESTED_TABLES
where PARENT_TABLE_NAME = XMLTABLE
and PARENT_TABLE_COLUMN = XPATH
and OWNER = USER;
RENAME_STATEMENT := 'alter table ' || USER || '."' || SYSTEM_GENERATED_NAME || '" rename to "' ||COLLECTION_TABLE_NAME || '"';
-- -- dbms_output.put_line(RENAME_STATEMENT);
execute immediate RENAME_STATEMENT;
begin
select INDEX_NAME
into SYSTEM_GENERATED_NAME
from ALL_INDEXES
where TABLE_NAME = COLLECTION_TABLE_NAME
and INDEX_TYPE = 'IOT - TOP'
and OWNER = USER;
RENAME_STATEMENT := 'alter index ' || USER || '."' || SYSTEM_GENERATED_NAME || '" rename to "' || CLUSTERED_INDEX_NAME || '"';
-- -- dbms_output.put_line(RENAME_STATEMENT);
execute immediate RENAME_STATEMENT;
exception
when NO_DATA_FOUND then
null;
end;
begin
select INDEX_NAME
into SYSTEM_GENERATED_NAME
from ALL_IND_columns
where COLUMN_NAME = XPATH
and TABLE_NAME = XMLTABLE
and TABLE_OWNER = USER;
RENAME_STATEMENT := 'alter index ' || USER || '."' || SYSTEM_GENERATED_NAME || '" rename to "' || PARENT_INDEX_NAME || '"';
-- -- dbms_output.put_line(RENAME_STATEMENT);
execute immediate RENAME_STATEMENT;
exception
when NO_DATA_FOUND then
null;
end;
end;
function processNestedTable(currentLevel in out number, currentNode in out XMLType, query SYS_REFCURSOR)
return XMLType
is
thisLevel number;
thisNode xmlType;
result xmlType;
begin
thisLevel := currentLevel;
thisNode := currentNode;
fetch query into currentLevel, currentNode;
if (query%NOTFOUND) then
currentLevel := -1;
end if;
while (currentLevel >= thisLevel) loop
-- Next Node is a decendant of sibling of this Node.
if (currentLevel > thisLevel) then
-- Next Node is a decendant of this Node.
result := processNestedTable(currentLevel, currentNode, query);
select xmlElement
"Collection",
extract(thisNode,'/Collection/*'),
xmlElement
"NestedCollections",
result
into thisNode
from dual;
else
-- Next node is a sibling of this Node.
result := processNestedTable(currentLevel, currentNode, query);
select xmlconcat(thisNode,result) into thisNode from dual;
end if;
end loop;
-- Next Node is a sibling of some ancestor of this node.
return thisNode;
end;
function printNestedTables(XML_TABLE varchar2)
return XMLType
is
query SYS_REFCURSOR;
result XMLType;
rootLevel number := 0;
rootNode xmlType;
begin
open query for
select level, xmlElement
"Collection",
xmlElement
"CollectionId",
PARENT_TABLE_COLUMN
) as XML
from USER_NESTED_TABLES
connect by PRIOR TABLE_NAME = PARENT_TABLE_NAME
start with PARENT_TABLE_NAME = XML_TABLE;
fetch query into rootLevel, rootNode;
result := processNestedTable(rootLevel, rootNode, query);
select xmlElement
"NestedTableStructure",
result
into result
from dual;
return result;
end;
function generateSchemaFromTable(P_TABLE_NAME varchar2, P_OWNER varchar2 default USER)
return XMLTYPE
as
xmlSchema XMLTYPE;
begin
select xmlElement
"xsd:schema",
xmlAttributes
'http://www.w3.org/2001/XMLSchema' as "xmlns:xsd",
'http://xmlns.oracle.com/xdb' as "xmlns:xdb"
xmlElement
"xsd:element",
xmlAttributes
'ROWSET' as "name",
'rowset' as "type"
xmlElement
"xsd:complexType",
xmlAttributes
'rowset' as "name"
xmlElement
"xsd:sequence",
xmlElement
"xsd:element",
xmlAttributes
'ROW' as "name",
table_name || '_T' as "type",
'unbounded' as "maxOccurs"
xmlElement
"xsd:complexType",
xmlAttributes
table_name || '_T' as "name"
xmlElement
"xsd:sequence",
xmlAgg(ELEMENT order by INTERNAL_COLUMN_ID)
into xmlSchema
from (select TABLE_NAME, INTERNAL_COLUMN_ID,
case
when DATA_TYPE in ('VARCHAR2','CHAR') then
xmlElement
"xsd:element",
xmlattributes
column_name as "name",
decode(NULLABLE, 'Y', 0, 1) as "minOccurs",
column_name as "xdb:SQLName",
DATA_TYPE as "xdb:SQLType"
xmlElement
"xsd:simpleType",
xmlElement
"xsd:restriction",
xmlAttributes
'xsd:string' as "base"
xmlElement
"xsd:maxLength",
xmlAttributes
DATA_LENGTH as "value"
when DATA_TYPE = 'NUMBER' then
xmlElement
"xsd:element",
xmlattributes
column_name as "name",
decode(NULLABLE, 'Y', 0, 1) as "minOccurs",
column_name as "xdb:SQLName",
DATA_TYPE as "xdb:SQLType"
xmlElement
"xsd:simpleType",
xmlElement
"xsd:restriction",
xmlAttributes
decode(DATA_SCALE, 0, 'xsd:integer', 'xsd:double') as "base"
xmlElement
"xsd:totalDigits",
xmlAttributes
DATA_PRECISION as "value"
when DATA_TYPE = 'DATE' then
xmlElement
"xsd:element",
xmlattributes
column_name as "name",
decode(NULLABLE, 'Y', 0, 1) as "minOccurs",
'xsd:date' as "type",
column_name as "xdb:SQLName",
DATA_TYPE as "xdb:SQLType"
when DATA_TYPE like 'TIMESTAMP%WITH TIME ZONE' then
xmlElement
"xsd:element",
xmlattributes
column_name as "name",
decode(NULLABLE, 'Y', 0, 1) as "minOccurs",
'xsd:dateTime' as "type",
column_name as "xdb:SQLName",
DATA_TYPE as "xdb:SQLType"
else
xmlElement
"xsd:element",
xmlattributes
column_name as "name",
decode(NULLABLE, 'Y', 0, 1) as "minOccurs",
'xsd:anySimpleType' as "type",
column_name as "xdb:SQLName",
DATA_TYPE as "xdb:SQLType"
end ELEMENT
from all_tab_cols c
where c.TABLE_NAME = P_TABLE_NAME
and c.OWNER = P_OWNER
group by TABLE_NAME;
return xmlSchema;
end;
function appendElementList(V_ELEMENT_LIST IN OUT XDB.XDB$XMLTYPE_REF_LIST_T, V_CHILD_ELEMENT_LIST XDB.XDB$XMLTYPE_REF_LIST_T) return XDB.XDB$XMLTYPE_REF_LIST_T;
function expandModel(P_MODEL XDB.XDB$MODEL_T) return XDB.XDB$XMLTYPE_REF_LIST_T;
function expandChoiceList(P_CHOICE_LIST XDB.XDB$XMLTYPE_REF_LIST_T) return XDB.XDB$XMLTYPE_REF_LIST_T;
function expandSequenceList(P_SEQUENCE_LIST XDB.XDB$XMLTYPE_REF_LIST_T) return XDB.XDB$XMLTYPE_REF_LIST_T;
function expandGroupList(P_GROUP_LIST XDB.XDB$XMLTYPE_REF_LIST_T) return XDB.XDB$XMLTYPE_REF_LIST_T;
function appendElementList(V_ELEMENT_LIST IN OUT XDB.XDB$XMLTYPE_REF_LIST_T, V_CHILD_ELEMENT_LIST XDB.XDB$XMLTYPE_REF_LIST_T)
return XDB.XDB$XMLTYPE_REF_LIST_T
as
begin
SELECT CAST
SET
CAST(V_ELEMENT_LIST as XDBPM.XMLTYPE_REF_TABLE_T)
MULTISET UNION
CAST(V_CHILD_ELEMENT_LIST as XDBPM.XMLTYPE_REF_TABLE_T)
as XDB.XDB$XMLTYPE_REF_LIST_T
into V_ELEMENT_LIST
from DUAL;
return V_ELEMENT_LIST;
end;
function expandModel(P_MODEL XDB.XDB$MODEL_T)
return XDB.XDB$XMLTYPE_REF_LIST_T
as
V_ELEMENT_LIST XDB.XDB$XMLTYPE_REF_LIST_T;
V_CHILD_ELEMENT_LIST XDB.XDB$XMLTYPE_REF_LIST_T;
begin
V_ELEMENT_LIST := XDB.XDB$XMLTYPE_REF_LIST_T();
if P_MODEL.ELEMENTS is not null then
V_ELEMENT_LIST := P_MODEL.ELEMENTS;
end if;
if (P_MODEL.CHOICE_KIDS is not NULL) then
V_CHILD_ELEMENT_LIST := expandChoiceList(P_MODEL.CHOICE_KIDS);
V_ELEMENT_LIST := appendElementList(V_ELEMENT_LIST,V_CHILD_ELEMENT_LIST);
end if;
if (P_MODEL.SEQUENCE_KIDS is not NULL) then
V_CHILD_ELEMENT_LIST := expandSequenceList(P_MODEL.SEQUENCE_KIDS);
V_ELEMENT_LIST := appendElementList(V_ELEMENT_LIST,V_CHILD_ELEMENT_LIST);
end if;
-- Process ANYS
if (P_MODEL.GROUPS is not NULL) then
V_CHILD_ELEMENT_LIST := expandGroupList(P_MODEL.GROUPS);
V_ELEMENT_LIST := appendElementList(V_ELEMENT_LIST,V_CHILD_ELEMENT_LIST);
end if;
return V_ELEMENT_LIST;
end;
function expandChoiceList(P_CHOICE_LIST XDB.XDB$XMLTYPE_REF_LIST_T)
return XDB.XDB$XMLTYPE_REF_LIST_T
as
V_ELEMENT_LIST XDB.XDB$XMLTYPE_REF_LIST_T;
V_CHILD_ELEMENT_LIST XDB.XDB$XMLTYPE_REF_LIST_T;
cursor getChoices is
select c.XMLDATA MODEL
from XDB.XDB$CHOICE_MODEL c, TABLE(P_CHOICE_LIST) cl
where ref(c) = value(cl);
begin
V_ELEMENT_LIST := XDB.XDB$XMLTYPE_REF_LIST_T();
for c in getChoices loop
V_CHILD_ELEMENT_LIST := expandModel(c.MODEL);
V_ELEMENT_LIST := appendElementList(V_ELEMENT_LIST,V_CHILD_ELEMENT_LIST);
end loop;
return V_ELEMENT_LIST;
end;
function expandSequenceList(P_SEQUENCE_LIST XDB.XDB$XMLTYPE_REF_LIST_T)
return XDB.XDB$XMLTYPE_REF_LIST_T
as
V_ELEMENT_LIST XDB.XDB$XMLTYPE_REF_LIST_T;
V_CHILD_ELEMENT_LIST XDB.XDB$XMLTYPE_REF_LIST_T;
cursor getSequences is
select s.XMLDATA MODEL
from XDB.XDB$SEQUENCE_MODEL s, TABLE(P_SEQUENCE_LIST) sl
where ref(s) = value(sl);
begin
V_ELEMENT_LIST := XDB.XDB$XMLTYPE_REF_LIST_T();
for s in getSequences loop
V_CHILD_ELEMENT_LIST := expandModel(s.MODEL);
V_ELEMENT_LIST := appendElementList(V_ELEMENT_LIST,V_CHILD_ELEMENT_LIST);
end loop;
return V_ELEMENT_LIST;
end;
function expandGroupList(P_GROUP_LIST XDB.XDB$XMLTYPE_REF_LIST_T)
return XDB.XDB$XMLTYPE_REF_LIST_T
as
V_ELEMENT_LIST XDB.XDB$XMLTYPE_REF_LIST_T;
V_CHILD_ELEMENT_LIST XDB.XDB$XMLTYPE_REF_LIST_T; V_MODEL XDB.XDB$MODEL_T;
cursor getGroups is
SELECT CASE
-- Return The MODEL Definition for the CHOICE, ALL or SEQUENCE
WHEN gd.XMLDATA.ALL_KID is not NULL
THEN ( SELECT a.XMLDATA from XDB.XDB$ALL_MODEL a where ref(a) = gd.XMLDATA.ALL_KID)
WHEN gd.XMLDATA.SEQUENCE_KID is not NULL
THEN ( SELECT s.XMLDATA from XDB.XDB$SEQUENCE_MODEL s where ref(s) = gd.XMLDATA.SEQUENCE_KID)
WHEN gd.XMLDATA.CHOICE_KID is not NULL
THEN ( SELECT c.XMLDATA from XDB.XDB$CHOICE_MODEL c where ref(c) = gd.XMLDATA.CHOICE_KID)
END MODEL
FROM XDB.XDB$GROUP_DEF gd, XDB.XDB$GROUP_REF gr, TABLE(P_GROUP_LIST) gl
WHERE ref(gd) = gr.XMLDATA.GROUPREF_REF
and ref(gr) = value(gl);
begin
V_ELEMENT_LIST := XDB.XDB$XMLTYPE_REF_LIST_T();
for g in getGroups loop
V_CHILD_ELEMENT_LIST := expandModel(g.MODEL);
V_ELEMENT_LIST := appendElementList(V_ELEMENT_LIST,V_CHILD_ELEMENT_LIST);
end loop;
return V_ELEMENT_LIST;
end;
function getComplexTypeElementList(P_COMPLEX_TYPE_REF REF XMLTYPE)
return XDB.XDB$XMLTYPE_REF_LIST_T
as
V_MODEL XDB.XDB$MODEL_T;
V_BASE_TYPE REF XMLTYPE;
V_ELEMENT_LIST XDB.XDB$XMLTYPE_REF_LIST_T := XDB.XDB$XMLTYPE_REF_LIST_T();
begin
SELECT ct.XMLDATA.BASE_TYPE,
CASE
-- Return The MODEL Definition for the CHOICE, ALL or SEQUENCE
WHEN ct.XMLDATA.ALL_KID is not NULL
THEN ( SELECT a.XMLDATA from XDB.XDB$ALL_MODEL a where ref(a) = ct.XMLDATA.ALL_KID)
WHEN ct.XMLDATA.SEQUENCE_KID is not NULL
THEN ( SELECT s.XMLDATA from XDB.XDB$SEQUENCE_MODEL s where ref(s) = ct.XMLDATA.SEQUENCE_KID)
WHEN ct.XMLDATA.CHOICE_KID is not NULL
THEN ( SELECT c.XMLDATA from XDB.XDB$CHOICE_MODEL c where ref(c) = ct.XMLDATA.CHOICE_KID)
WHEN ct.XMLDATA.GROUP_KID is not NULL
-- COMPLEXTYPE is based on a GROUP.
THEN (
-- RETURN The CHOICE, ALL or SEQUENCE for GROUP
SELECT CASE
WHEN gd.XMLDATA.ALL_KID is not NULL
THEN ( SELECT a.XMLDATA from XDB.XDB$ALL_MODEL a where ref(a) = gd.XMLDATA.ALL_KID)
WHEN gd.XMLDATA.SEQUENCE_KID is not NULL
THEN ( SELECT s.XMLDATA from XDB.XDB$SEQUENCE_MODEL s where ref(s) = gd.XMLDATA.SEQUENCE_KID)
WHEN gd.XMLDATA.CHOICE_KID is not NULL
THEN ( SELECT c.XMLDATA from XDB.XDB$CHOICE_MODEL c where ref(c) = gd.XMLDATA.CHOICE_KID)
END
FROM XDB.XDB$GROUP_DEF gd, xdb.xdb$GROUP_REF gr
WHERE ref(gd) = gr.XMLDATA.GROUPREF_REF
and ref(gr) = ct.XMLDATA.GROUP_KID
-- WHEN ct.XMLDATA.COMPLEXCONTENT.RESTRICTION.ALL_KID is not NULL
-- THEN ( SELECT a.XMLDATA from XDB.XDB$ALL_MODEL a where ref(a) = ct.XMLDATA.COMPLEXCONTENT.RESTRICTION.ALL_KID)
-- WHEN ct.XMLDATA.COMPLEXCONTENT.RESTRICTION.SEQUENCE_KID is not NULL
-- THEN ( SELECT s.XMLDATA from XDB.XDB$SEQUENCE_MODEL s where ref(s) = ct.XMLDATA.COMPLEXCONTENT.RESTRICTION.SEQUENCE_KID)
-- WHEN ct.XMLDATA.COMPLEXCONTENT.RESTRICTION.CHOICE_KID is not NULL
-- THEN ( SELECT c.XMLDATA from XDB.XDB$CHOICE_MODEL c where ref(c) = ct.XMLDATA.COMPLEXCONTENT.RESTRICTION.CHOICE_KID)
-- WHEN ct.XMLDATA.COMPLEXCONTENT.RESTRICTION.GROUP_KID is not NULL
-- -- COMPLEXTYPE is based on a GROUP.
-- THEN (
-- -- RETURN The CHOICE, ALL or SEQUENCE for GROUP
-- SELECT CASE
-- WHEN gd.XMLDATA.ALL_KID is not NULL
-- THEN ( SELECT a.XMLDATA from XDB.XDB$ALL_MODEL a where ref(a) = gd.XMLDATA.ALL_KID)
-- WHEN gd.XMLDATA.SEQUENCE_KID is not NULL
-- THEN ( SELECT s.XMLDATA from XDB.XDB$SEQUENCE_MODEL s where ref(s) = gd.XMLDATA.SEQUENCE_KID)
-- WHEN gd.XMLDATA.CHOICE_KID is not NULL
-- THEN ( SELECT c.XMLDATA from XDB.XDB$CHOICE_MODEL c where ref(c) = gd.XMLDATA.CHOICE_KID)
-- END
-- FROM XDB.XDB$GROUP_DEF gd, xdb.xdb$GROUP_REF gr
-- WHERE ref(gd) = gr.XMLDATA.GROUPREF_REF
-- and ref(gr) = ct.XMLDATA.COMPLEXCONTENT.RESTRICTION.GROUP_KID
WHEN ct.XMLDATA.COMPLEXCONTENT.EXTENSION.ALL_KID is not NULL
THEN ( SELECT a.XMLDATA from XDB.XDB$ALL_MODEL a where ref(a) = ct.XMLDATA.COMPLEXCONTENT.EXTENSION.ALL_KID)
WHEN ct.XMLDATA.COMPLEXCONTENT.EXTENSION.SEQUENCE_KID is not NULL
THEN ( SELECT s.XMLDATA from XDB.XDB$SEQUENCE_MODEL s where ref(s) = ct.XMLDATA.COMPLEXCONTENT.EXTENSION.SEQUENCE_KID)
WHEN ct.XMLDATA.COMPLEXCONTENT.EXTENSION.CHOICE_KID is not NULL
THEN ( SELECT c.XMLDATA from XDB.XDB$CHOICE_MODEL c where ref(c) = ct.XMLDATA.COMPLEXCONTENT.EXTENSION.CHOICE_KID)
WHEN ct.XMLDATA.COMPLEXCONTENT.EXTENSION.GROUP_KID is not NULL
-- COMPLEXTYPE is based on a GROUP.
THEN (
-- RETURN The CHOICE, ALL or SEQUENCE for GROUP
SELECT CASE
WHEN gd.XMLDATA.ALL_KID is not NULL
THEN ( SELECT a.XMLDATA from XDB.XDB$ALL_MODEL a where ref(a) = gd.XMLDATA.ALL_KID)
-
Hi all,
i am trying to make my own rtf editor , I've read the most of the toppics in this forum on this issue,
but I'm stucked on inserting the hex Data into the document.
Do I actually need to override ImageView?
I found a method in RTFReader (instantiated from read(InputStream in,...)) handleBinaryBlob(byte[] data).
RTFReader is private, so I cannot override this method. Should I override the read method in
RTFEditorKit and then call the read method in DefaultEditorKit, or I could just use the doc.insertString(...) with the binary data inside of the overriden RTFEditorKit read method? I will lose the functionallity of the RTFParser this way.
I know I should override read and write methods but how?
So could somebody help me on this?
The code for creating the binary data from buffered image and creating the Icon from StanislavL follows:
ImageIcon icon=(ImageIcon)StyleConstants.getIcon(attr);
if (icon!=null) {
int w=StyleConstants.getIcon(attr).getIconWidth();
int h=StyleConstants.getIcon(attr).getIconHeight();
ByteArrayOutputStream os=new ByteArrayOutputStream();
PNGCodec p=new PNGCodec();
ImageEncoder pe=p.createImageEncoder("PNG",os,null);
BufferedImage bi=new BufferedImage(w,h,BufferedImage.TYPE_INT_RGB);
bi.getGraphics().drawImage(icon.getImage(),0,0,null);
pe.encode(bi);
byte[] ba=os.toByteArray();
int len=ba.length,i;
StringBuffer sb=new StringBuffer(len*2);
for (i=0;i<len;i++) {
String sByte=Integer.toHexString((int)ba & 0xFF);
if (sByte.length()<2)
sb.append('0'+sByte);
else
sb.append(sByte);
String s=sb.toString();
out.write("{\\pict\\pngblip ");
out.write(s);
out.write("}");
extracting image
String content; //<- image representation
int len=content.length();
//converts to binary representation
byte[] buf=new byte[len/2];
for (int j=0; j<len/2 ;j++) {
String c1=content.substring(j*2,j*2+1);
String c2=content.substring(j*2+1,j*2+2);
byte b1=Byte.parseByte(c1,16);
byte b2=Byte.parseByte(c2,16);
buf[j]=(byte)(b1*16+b2);
//creates image from binary
Image img = Toolkit.getDefaultToolkit().createImage(buf);
ImageIcon icon=new ImageIcon();
icon.setImage(img);
if ((icon.getIconHeight()<0) || (icon.getIconWidth()<0))
return;
MutableAttributeSet attr=new SimpleAttributeSet();
StyleConstants.setIcon(attr,icon);
//inserts image in the document
document.insertString(currentOffset," ",attr);
currentOffset++;
I guess these two functions must be implied into the overriden EditKit write and read methods.
Could somebody give me a start idea?
regards
rumpiThanks for reply.
It did't helped me a lot or I'dont really understand your idea.
What you say in your postings is build my own reader and writer.
For example to open a rtf file in my jeditorpane I must read from
the input stream each byte and reimplementing AbstractFilter, RTFParser and RTFReader
I could get all headers like \par or \pic and then rtfDoc.insertString(pos, "the label content", attr) with the attributes extracted from header.
When that is the only way I am asking myself what are the swing people for?!?!
I'll try to do that myself, so I'm not asking for code but I would appreciate
some detailed info about it. For example when I dont use RTFReader anymore
I loose everything what I've got untill now. So I should read every byte opening a file
and check like in RTFParser if the first character is "\", then the next couple of bytes
untill I get the header. Then I should check which labels(text) is this header for(until the next header), so
I could insert a string with the according attribute set? For Icon when I get the
\pic header I read the byte sequence and build the picture just like you wrote.
My Editor is an applet so I've hoped I wouldn't send too much code to the client
so reimplementing RTFParser, Reader... would slow it down, but whatever.
Thats really a lot of work only because the given classes are not extendable, grrrr.
Viravan, thanks for the fast reply , but like I said , I 've already read all relevant
postings in this forum and didnt found something really helpful. I already read all
tutorials and articles from sun about this issue and I still have the feeling I'm a freshman
in this area.
I'm still angry with the swing team about it, this bug is noted since 2001 I think. grrr
regards
rumpi -
Xpath performance and xsi namespace
In my xpath, I need to use the "xsi" namespace to specify the xpath condition. It seems to be the performance of the xpath that uses the "xsi" namespace is extremly slow, compared with a similar xpath that does not use the name space, although the number of retrieved objects are the same in my test case.
What causes such a big difference in speed? Is that possible when I use the "xsi" namespace in the xpath, the xpath is not get rewritten? How can I improve the performance when using "xsi" namespace.
1)xpath not use the namespace
select extract(object_value, '/Test/Group/Object[uniqueName="a1"]') from Test where existsNode(object_value, '/Test/Group[uniqueName="N10001"])=1;
2)xpath use the "xsi" namespace
select extract(object_value, '/Test/Group/Object[uniqueName="a1" and @xsi:type="Architecture"]', 'xmlns="http://www.myspace.com/testXML" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"') from Test where existsNode(object_value, '/Test/Group[uniqueName="N10001"])=1;Yes, you'll need to workout where to split the document.. Good, and typical points to break up the entity are if you have a choice of one or more complex structures.
The following code may help with looking at this..
You'll need to register the XML Schema with gentables="false" so that all the types get generated.. You can then look at the types and see how many columns each type will generate if you build a table on it...
create or replace package XDB_ANALYZE_XMLSCHEMA_11100
authid CURRENT_USER
as
function analyzeStorageModel(COMPLEX_TYPE VARCHAR2) return XMLTYPE;
function analyzeStorageModel(ATTR_NAME VARCHAR2, SUBTYPE VARCHAR2, SUBTYPE_OWNER VARCHAR2) return XMLType;
function analyzeComplexType(COMPLEX_TYPE VARCHAR2) return XMLTYPE;
procedure renameCollectionTable (XMLTABLE varchar2, XPATH varchar2, COLLECTION_TABLE_PREFIX varchar2);
function printNestedTables(XML_TABLE varchar2) return XMLType;
function generateSchemaFromTable(P_TABLE_NAME varchar2, P_OWNER varchar2 default USER) return XMLTYPE;
function showSQLTypes(schemaFolder varchar2) return XMLType;
NAMESPACES varchar2(1024) := xdb_namespaces.XMLSCHEMA_PREFIX_XSD || ' ' || xdb_namespaces.XDBSCHEMA_PREFIX_XDB;
end XDB_ANALYZE_XMLSCHEMA_11100;
show errors
create or replace package body XDB_ANALYZE_XMLSCHEMA_11100
as
TYPE STORAGE_MODEL_T is RECORD
TYPE_NAME varchar2(128),
TYPE_OWNER varchar2(32),
STORAGE_MODEL XMLType
TYPE STORAGE_MODEL_LIST_T is TABLE OF STORAGE_MODEL_T;
TYPE BASETYPE_T is RECORD
SUBTYPE varchar2(128),
SUBTYPE_OWNER varchar2(32),
BASETYPE varchar2(128),
BASETYPE_OWNER varchar2(32)
TYPE BASETYPE_LIST_T IS TABLE OF BASETYPE_T;
DEPTH_COUNT NUMBER(2) := 0;
STORAGE_MODEL_LIST STORAGE_MODEL_LIST_T := STORAGE_MODEL_LIST_T();
BASETYPE_LIST BASETYPE_LIST_T := BASETYPE_LIST_T();
function getLocalAttributes(SQLTYPE varchar2, SQLTYPE_OWNER VARCHAR2) return XMLType;
function makeElement(ATTR_NAME varchar2)
return xmltype
as
VALID_NAME varchar2(4000) := ATTR_NAME;
begin
-- dbms_output.put_line('Processing : ' || ATTR_NAME);
if (ATTR_NAME LIKE '%$') THEN
VALID_NAME := SUBSTR(VALID_NAME,1,LENGTH(VALID_NAME) - 1);
end if;
return XMLTYPE( '<' || VALID_NAME || '/>');
end;
function getPathToRoot(SUBTYPE VARCHAR2, SUBTYPE_OWNER VARCHAR2)
return varchar2
as
TYPE_HIERARCHY varchar2(4000);
begin
SELECT sys_connect_by_path( OWNER || '.' || TYPE_NAME , '/')
INTO TYPE_HIERARCHY
FROM ALL_TYPES
WHERE TYPE_NAME = SUBTYPE
AND OWNER = SUBTYPE_OWNER
CONNECT BY SUPERTYPE_NAME = PRIOR TYPE_NAME
AND SUPERTYPE_OWNER = PRIOR OWNER
START WITH SUPERTYPE_NAME IS NULL
AND SUPERTYPE_OWNER IS NULL;
return TYPE_HIERARCHY;
end;
function expandSQLType(ATTR_NAME VARCHAR2, SUBTYPE VARCHAR2, SUBTYPE_OWNER VARCHAR2)
return XMLType
as
STORAGE_MODEL XMLTYPE;
ATTRIBUTES XMLTYPE;
EXTENDED_TYPE XMLTYPE;
ATTR_COUNT NUMBER := 0;
CURSOR FIND_EXTENDED_TYPES
is
select TYPE_NAME, OWNER
from ALL_TYPES
where SUPERTYPE_NAME = SUBTYPE
and SUPERTYPE_OWNER = SUBTYPE_OWNER;
begin
dbms_output.put_line('Processing SQLType : "' || SUBTYPE_OWNER || '.' || SUBTYPE || '".' );
STORAGE_MODEL := makeElement(ATTR_NAME);
select insertChildXML(STORAGE_MODEL,'/' || STORAGE_MODEL.getRootElement(),'@type',SUBTYPE)
into STORAGE_MODEL
from dual;
select insertChildXML(STORAGE_MODEL,'/' || STORAGE_MODEL.getRootElement(),'@typeOwner',SUBTYPE_OWNER)
into STORAGE_MODEL
from dual;
ATTRIBUTES := getLocalAttributes(SUBTYPE, SUBTYPE_OWNER);
ATTR_COUNT := ATTR_COUNT + ATTRIBUTES.extract('/' || ATTRIBUTES.getRootElement() || '/@columns').getNumberVal();
select appendChildXML(STORAGE_MODEL,'/' || STORAGE_MODEL.getRootElement(),ATTRIBUTES)
into STORAGE_MODEL
from DUAL;
for t in FIND_EXTENDED_TYPES loop
EXTENDED_TYPE := expandSQLType('ExtendedType',T.TYPE_NAME,T.OWNER);
ATTR_COUNT := ATTR_COUNT + EXTENDED_TYPE.extract('/' || EXTENDED_TYPE.getRootElement() || '/@columns').getNumberVal();
select appendChildXML(STORAGE_MODEL,'/' || STORAGE_MODEL.getRootElement(),EXTENDED_TYPE)
into STORAGE_MODEL
from DUAL;
end loop;
select insertChildXML(STORAGE_MODEL,'/' || STORAGE_MODEL.getRootElement(),'@columns',ATTR_COUNT)
into STORAGE_MODEL
from dual;
return STORAGE_MODEL;
end;
function getTypeHierarchy(ELEMENT_NAME varchar2, TYPE_HIERARCHY varchar2)
return XMLType
as
SUBTYPE_HIERARCHY varchar2(4000);
ATTRIBUTES XMLTYPE;
SUBTYPE_STORAGE_MODEL XMLTYPE;
STORAGE_MODEL XMLTYPE;
ATTR_COUNT NUMBER := 0;
V_TYPE_OWNER varchar2(32);
V_TYPE_NAME varchar2(128);
CURSOR FIND_EXTENDED_TYPES
is
select TYPE_NAME, OWNER
from ALL_TYPES
where SUPERTYPE_NAME = V_TYPE_NAME
and SUPERTYPE_OWNER = V_TYPE_OWNER;
begin
dbms_output.put_line('Type Hierarchy : ' || TYPE_HIERARCHY );
if DEPTH_COUNT > 25 then
return null;
end if;
DEPTH_COUNT := DEPTH_COUNT + 1;
SUBTYPE_HIERARCHY := substr(TYPE_HIERARCHY,instr(TYPE_HIERARCHY,'/',2));
V_TYPE_OWNER := substr(TYPE_HIERARCHY,2,instr(TYPE_HIERARCHY,'.',2) - 2);
if (instr(TYPE_HIERARCHY,'/',-1) > 1) then
V_TYPE_NAME := substr(TYPE_HIERARCHY,instr(TYPE_HIERARCHY,'.',2) + 1,instr(TYPE_HIERARCHY,'/',2) - instr(TYPE_HIERARCHY,'.',2) -1);
else
V_TYPE_NAME := substr(TYPE_HIERARCHY,instr(TYPE_HIERARCHY,'.') + 1);
SUBTYPE_HIERARCHY := null;
end if;
dbms_output.put_line('Processing : "' || V_TYPE_OWNER || '"."' || V_TYPE_NAME || '"');
STORAGE_MODEL := makeElement(ELEMENT_NAME);
select insertChildXML(STORAGE_MODEL,'/' || STORAGE_MODEL.getRootElement(),'@type',V_TYPE_NAME)
into STORAGE_MODEL
from dual;
select insertChildXML(STORAGE_MODEL,'/' || STORAGE_MODEL.getRootElement(),'@typeOwner',V_TYPE_OWNER)
into STORAGE_MODEL
from dual;
ATTRIBUTES := getLocalAttributes(V_TYPE_NAME, V_TYPE_OWNER);
ATTR_COUNT := ATTR_COUNT + ATTRIBUTES.extract('/' || ATTRIBUTES.getRootElement() || '/@columns').getNumberVal();
select appendChildXML(STORAGE_MODEL,'/' || STORAGE_MODEL.getRootElement(),ATTRIBUTES)
into STORAGE_MODEL
from DUAL;
if (SUBTYPE_HIERARCHY is not null) then
SUBTYPE_STORAGE_MODEL := getTypeHierarchy('subType',SUBTYPE_HIERARCHY);
ATTR_COUNT := ATTR_COUNT + SUBTYPE_STORAGE_MODEL.extract('/' || SUBTYPE_STORAGE_MODEL.getRootElement() || '/@columns').getNumberVal();
select appendChildXML(STORAGE_MODEL,'/' || STORAGE_MODEL.getRootElement(),SUBTYPE_STORAGE_MODEL)
into STORAGE_MODEL
from DUAL;
else
dbms_output.put_line('Processing All known SubTypes of : "' || V_TYPE_OWNER || '"."' || V_TYPE_NAME || '"');
for t in FIND_EXTENDED_TYPES loop
SUBTYPE_STORAGE_MODEL := expandSQLType('ExtendedType',T.TYPE_NAME,T.OWNER);
ATTR_COUNT := ATTR_COUNT + SUBTYPE_STORAGE_MODEL.extract('/' || SUBTYPE_STORAGE_MODEL.getRootElement() || '/@columns').getNumberVal();
select appendChildXML(STORAGE_MODEL,'/' || STORAGE_MODEL.getRootElement(),SUBTYPE_STORAGE_MODEL)
into STORAGE_MODEL
from DUAL;
end loop;
end if;
select insertChildXML(STORAGE_MODEL,'/' || STORAGE_MODEL.getRootElement(),'@columns',ATTR_COUNT)
into STORAGE_MODEL
from dual;
DEPTH_COUNT := DEPTH_COUNT - 1;
return STORAGE_MODEL;
end;
function getStorageModel(TYPE_NAME VARCHAR2, TYPE_OWNER VARCHAR2)
return XMLType
as
BASETYPE varchar2(128);
BASETYPE_OWNER varchar2(32);
STORAGE_MODEL STORAGE_MODEL_T;
begin
dbms_output.put_line('Depth : ' || DEPTH_COUNT || '. Getting Storage Model for "' || TYPE_OWNER || '.' || TYPE_NAME || '".' );
if DEPTH_COUNT > 25 then
return null;
end if;
DEPTH_COUNT := DEPTH_COUNT + 1;
for i in 1..STORAGE_MODEL_LIST.count loop
STORAGE_MODEL := STORAGE_MODEL_LIST(i);
if (STORAGE_MODEL.TYPE_NAME = TYPE_NAME and STORAGE_MODEL.TYPE_OWNER = TYPE_OWNER) then
DEPTH_COUNT := DEPTH_COUNT - 1;
return STORAGE_MODEL.STORAGE_MODEL;
end if;
end loop;
STORAGE_MODEL.TYPE_NAME := TYPE_NAME;
STORAGE_MODEL.TYPE_OWNER := TYPE_OWNER;
STORAGE_MODEL.STORAGE_MODEL := getTypeHierarchy('RootType',getPathToRoot(TYPE_NAME,TYPE_OWNER));
STORAGE_MODEL_LIST.extend(1);
STORAGE_MODEL_LIST(STORAGE_MODEL_LIST.count) := STORAGE_MODEL;
DEPTH_COUNT := DEPTH_COUNT - 1;
return STORAGE_MODEL.STORAGE_MODEL;
end;
function getLocalAttributes(SQLTYPE varchar2, SQLTYPE_OWNER VARCHAR2)
return XMLType
as
CHILD_ATTR XMLTYPE;
ATTR_COUNT NUMBER := 0;
COLLECTION_TYPE varchar2(128);
COLLECTION_OWNER varchar2(32);
SUPERTYPE varchar2(128);
STORAGE_MODEL xmlType;
SQL_ATTRIBUTES XMLTYPE := xmlType('<SQLAttributes/>');
CURSOR FIND_CHILD_ATTRS
is
select ATTR_NAME, ATTR_TYPE_OWNER, ATTR_TYPE_NAME, INHERITED
from ALL_TYPE_ATTRS
where TYPE_NAME = SQLTYPE
and OWNER = SQLTYPE_OWNER
and INHERITED = 'NO'
order by ATTR_NO;
begin
for ATTR in FIND_CHILD_ATTRS loop
CHILD_ATTR := makeElement(ATTR.ATTR_NAME);
begin
-- Check for Attributes based on collection types, With Nested Table storage each Collection will cost 2 columns.
select ELEM_TYPE_NAME, ELEM_TYPE_OWNER
into COLLECTION_TYPE, COLLECTION_OWNER
from ALL_COLL_TYPES
where TYPE_NAME = ATTR.ATTR_TYPE_NAME
and OWNER = ATTR.ATTR_TYPE_OWNER;
-- Attribute is a Collection Type. Each Collection requires 2 columns.
select insertChildXML(CHILD_ATTR,'/' || CHILD_ATTR.getRootElement(),'@collectionType',COLLECTION_TYPE)
into CHILD_ATTR
from dual;
select insertChildXML(CHILD_ATTR,'/' || CHILD_ATTR.getRootElement(),'@collectionOwner',COLLECTION_OWNER)
into CHILD_ATTR
from dual;
select insertChildXML(CHILD_ATTR,'/' || CHILD_ATTR.getRootElement(),'@columns',2)
into CHILD_ATTR
from dual;
exception
when no_data_found then
-- Attribute is not a collection type.
begin
-- Check for Attributes based on non-scalar types.
select SUPERTYPE_NAME
into SUPERTYPE
from ALL_TYPES
where TYPE_NAME = ATTR.ATTR_TYPE_NAME
and OWNER = ATTR.ATTR_TYPE_OWNER;
-- Attribute is based on a non-scalar type. Find the Storage Model for this type.
select insertChildXML(CHILD_ATTR,'/' || CHILD_ATTR.getRootElement(),'@type',ATTR.ATTR_TYPE_NAME)
into CHILD_ATTR
from dual;
select insertChildXML(CHILD_ATTR,'/' || CHILD_ATTR.getRootElement(),'@owner',ATTR.ATTR_TYPE_OWNER)
into CHILD_ATTR
from dual;
STORAGE_MODEL := getStorageModel(ATTR.ATTR_TYPE_NAME, ATTR.ATTR_TYPE_OWNER);
select appendChildXML(CHILD_ATTR,'/' || ATTR.ATTR_NAME,STORAGE_MODEL)
into CHILD_ATTR
from DUAL;
-- The cost of a non scalar Type is the number of attributes plus one for Type and one for the TYPEID.
select insertChildXML(CHILD_ATTR,'/' || ATTR.ATTR_NAME,'@columns',STORAGE_MODEL.extract(STORAGE_MODEL.GETROOTELEMENT() || '/@columns').getNumberVal() + 2)
into CHILD_ATTR
from dual;
exception
when no_data_found then
-- Attribute is based on a scalar type
select insertChildXML(CHILD_ATTR,'/' || CHILD_ATTR.getRootElement(),'@type',ATTR.ATTR_TYPE_NAME)
into CHILD_ATTR
from dual;
select insertChildXML(CHILD_ATTR,'/' || CHILD_ATTR.getRootElement(),'@columns',1)
into CHILD_ATTR
from dual;
end;
end;
select appendChildXML(SQL_ATTRIBUTES,'/' || SQL_ATTRIBUTES.getRootElement(),CHILD_ATTR)
into SQL_ATTRIBUTES
from DUAL;
ATTR_COUNT := ATTR_COUNT + CHILD_ATTR.extract('/' || CHILD_ATTR.getRootElement() || '/@columns').getNumberVal();
end loop;
select insertChildXML(SQL_ATTRIBUTES,'/' || SQL_ATTRIBUTES.getRootElement(),'@columns',ATTR_COUNT)
into SQL_ATTRIBUTES
from dual;
return SQL_ATTRIBUTES;
end;
function analyzeStorageModel(ATTR_NAME VARCHAR2, SUBTYPE VARCHAR2, SUBTYPE_OWNER VARCHAR2)
return XMLType
as
ROOT_NODE_NAME VARCHAR2(128);
TYPE_DEFINITION XMLTYPE;
STORAGE_MODEL XMLTYPE;
ATTR_COUNT NUMBER := 0;
begin
dbms_output.put_line('Processing Attribute : "' || ATTR_NAME || '". SQLType="' || SUBTYPE_OWNER || '.' || SUBTYPE || '".' );
TYPE_DEFINITION := makeElement(ATTR_NAME);
select insertChildXML(TYPE_DEFINITION,'/' || TYPE_DEFINITION.getRootElement(),'@type',SUBTYPE)
into TYPE_DEFINITION
from dual;
select insertChildXML(TYPE_DEFINITION,'/' || TYPE_DEFINITION.getRootElement(),'@owner',SUBTYPE_OWNER)
into TYPE_DEFINITION
from dual;
STORAGE_MODEL := getStorageModel(SUBTYPE, SUBTYPE_OWNER);
ATTR_COUNT := ATTR_COUNT + STORAGE_MODEL.extract('/' || STORAGE_MODEL.getRootElement() || '/@columns').getNumberVal();
select insertChildXML(TYPE_DEFINITION,'/' || TYPE_DEFINITION.getRootElement(),'@columns',ATTR_COUNT)
into TYPE_DEFINITION
from dual;
select appendChildXML
TYPE_DEFINITION,
'/' || TYPE_DEFINITION.getRootElement(),
STORAGE_MODEL
into TYPE_DEFINITION
from DUAL;
return TYPE_DEFINITION;
end;
function analyzeStorageModel(COMPLEX_TYPE VARCHAR2)
return XMLTYPE
as
SQLTYPE VARCHAR2(128);
SQLTYPE_OWNER VARCHAR2(32);
RESULT XMLTYPE;
begin
STORAGE_MODEL_LIST := STORAGE_MODEL_LIST_T();
select SQLTYPE, SQLTYPE_OWNER
into SQLTYPE, SQLTYPE_OWNER
from USER_XML_SCHEMAS,
xmlTable
xmlnamespaces
'http://www.w3.org/2001/XMLSchema' as "xsd",
'http://xmlns.oracle.com/xdb' as "xdb"
'/xsd:schema/xsd:complexType'
passing Schema
columns
COMPLEX_TYPE_NAME varchar2(4000) path '@name',
SQLTYPE varchar2(128) path '@xdb:SQLType',
SQLTYPE_OWNER varchar2(32) path '@xdb:SQLSchema'
where COMPLEX_TYPE_NAME = COMPLEX_TYPE;
-- dbms_output.put_line('Processing SQLType : "' || SQLTYPE_OWNER || '.' || SQLTYPE || '".' );
return analyzeStorageModel(COMPLEX_TYPE,SQLTYPE,SQLTYPE_OWNER);
exception
when no_data_found then
dbms_output.put_line('Unable to find SQLType mapping for complexType : "' || COMPLEX_TYPE || '".' );
return null;
end;
function analyzeSQLType(ATTR_NAME VARCHAR2, TARGET_TYPE_NAME VARCHAR2, TARGET_TYPE_OWNER VARCHAR2)
return XMLType
as
ROOT_NODE_NAME VARCHAR2(128);
ATTR_DETAIL XMLTYPE;
XPATH_EXPRESSION VARCHAR2(129);
CURSOR FIND_CHILD_ATTRS is
select ATTR_NAME, ATTR_TYPE_OWNER, ATTR_TYPE_NAME, INHERITED
from ALL_TYPE_ATTRS
where OWNER = TARGET_TYPE_OWNER
and TYPE_NAME = TARGET_TYPE_NAME
order by ATTR_NO;
CHILD_ATTR XMLTYPE;
ATTR_COUNT NUMBER := 0;
TEMP number;
COLLECTION_TYPE_NAME varchar2(256);
COLLECTION_TYPE_OWNER varchar2(256);
begin
-- dbms_output.put_line('Processing Attribute ' || ATTR_NAME || ' of ' || TARGET_TYPE_OWNER || '.' || TARGET_TYPE_NAME );
ATTR_DETAIL := makeElement(ATTR_NAME);
XPATH_EXPRESSION := '/' || ATTR_DETAIL.GETROOTELEMENT();
for ATTR in FIND_CHILD_ATTRS loop
begin
select ELEM_TYPE_NAME, ELEM_TYPE_OWNER
into COLLECTION_TYPE_NAME, COLLECTION_TYPE_OWNER
from ALL_COLL_TYPES
where TYPE_NAME = ATTR.ATTR_TYPE_NAME
and OWNER = ATTR.ATTR_TYPE_OWNER;
CHILD_ATTR := analyzeSQLType(ATTR.ATTR_NAME, COLLECTION_TYPE_NAME, COLLECTION_TYPE_OWNER );
ATTR_COUNT := ATTR_COUNT + CHILD_ATTR.extract('/' || CHILD_ATTR.GETROOTELEMENT() || '/@columns').getNumberVal();
select appendChildXML(ATTR_DETAIL,XPATH_EXPRESSION,CHILD_ATTR)
into ATTR_DETAIL
from DUAL;
exception
when no_data_found then
begin
select 1
into TEMP
from ALL_TYPES
where TYPE_NAME = ATTR.ATTR_TYPE_NAME
and OWNER = ATTR.ATTR_TYPE_OWNER;
CHILD_ATTR := analyzeSQLType(ATTR.ATTR_NAME, ATTR.ATTR_TYPE_NAME, ATTR.ATTR_TYPE_OWNER );
ATTR_COUNT := ATTR_COUNT + CHILD_ATTR.extract('/' || CHILD_ATTR.GETROOTELEMENT() || '/@columns').getNumberVal();
select appendChildXML(ATTR_DETAIL,XPATH_EXPRESSION,CHILD_ATTR)
into ATTR_DETAIL
from DUAL;
exception
when no_data_found then
ATTR_COUNT := ATTR_COUNT + 1;
end;
end;
end loop;
select insertChildXML(ATTR_DETAIL,XPATH_EXPRESSION,'@columns',ATTR_COUNT)
into ATTR_DETAIL
from dual;
return ATTR_DETAIL;
end;
function analyzeComplexType(COMPLEX_TYPE VARCHAR2)
return XMLType
as
RESULT xmltype;
SQLTYPE varchar2(128);
SQLTYPE_OWNER varchar2(32);
begin
select SQLTYPE, SQLTYPE_OWNER
into SQLTYPE, SQLTYPE_OWNER
from USER_XML_SCHEMAS,
xmlTable
xmlnamespaces
'http://www.w3.org/2001/XMLSchema' as "xsd",
'http://xmlns.oracle.com/xdb' as "xdb"
'/xsd:schema/xsd:complexType'
passing Schema
columns
COMPLEX_TYPE_NAME varchar2(4000) path '@name',
SQLTYPE varchar2(128) path '@xdb:SQLType',
SQLTYPE_OWNER varchar2(32) path '@xdb:SQLSchema'
where COMPLEX_TYPE_NAME = COMPLEX_TYPE;
result := analyzeSQLType(COMPLEX_TYPE,SQLTYPE,SQLTYPE_OWNER);
select insertChildXML(RESULT,'/' || COMPLEX_TYPE,'@SQLType',SQLTYPE)
into result
from dual;
return result;
end;
function showSQLTypes(schemaFolder varchar2) return XMLType
is
xmlSchema XMLTYPE;
begin
select xmlElement
"TypeList",
xmlAgg
xmlElement
"Schema",
xmlElement
"ResourceName",
extractValue(res,'/Resource/DisplayName')
xmlElement
"complexTypes",
select xmlAgg
xmlElement
"complexType",
xmlElement
"name",
extractValue(value(XML),'/xsd:complexType/@name',NAMESPACES)
xmlElement
"SQLType",
extractValue(value(XML),'/xsd:complexType/@xdb:SQLType',NAMESPACES)
from table
xmlsequence
extract
xdburitype(p.path).getXML(),
'/xsd:schema/xsd:complexType',
NAMESPACES
) xml
-- order by extractValue(value(XML),'/xsd:complexType/@name',NAMESPACES)
).extract('/*')
into xmlSchema
from path_view p
where under_path(res,schemaFolder) = 1
order by extractValue(res,'/Resource/DisplayName');
return xmlSchema;
end;
procedure renameCollectionTable (XMLTABLE varchar2, XPATH varchar2, COLLECTION_TABLE_PREFIX varchar2)
as
SYSTEM_GENERATED_NAME varchar2(256);
COLLECTION_TABLE_NAME varchar2(256);
CLUSTERED_INDEX_NAME varchar2(256);
PARENT_INDEX_NAME varchar2(256);
RENAME_STATEMENT varchar2(4000);
begin
COLLECTION_TABLE_NAME := COLLECTION_TABLE_PREFIX || '_TABLE';
CLUSTERED_INDEX_NAME := COLLECTION_TABLE_PREFIX || '_DATA';
PARENT_INDEX_NAME := COLLECTION_TABLE_PREFIX || '_LIST';
select TABLE_NAME
into SYSTEM_GENERATED_NAME
from ALL_NESTED_TABLES
where PARENT_TABLE_NAME = XMLTABLE
and PARENT_TABLE_COLUMN = XPATH
and OWNER = USER;
RENAME_STATEMENT := 'alter table ' || USER || '."' || SYSTEM_GENERATED_NAME || '" rename to "' ||COLLECTION_TABLE_NAME || '"';
-- dbms_output.put_line(RENAME_STATEMENT);
execute immediate RENAME_STATEMENT;
begin
select INDEX_NAME
into SYSTEM_GENERATED_NAME
from ALL_INDEXES
where TABLE_NAME = COLLECTION_TABLE_NAME
and INDEX_TYPE = 'IOT - TOP'
and OWNER = USER;
RENAME_STATEMENT := 'alter index ' || USER || '."' || SYSTEM_GENERATED_NAME || '" rename to "' || CLUSTERED_INDEX_NAME || '"';
-- dbms_output.put_line(RENAME_STATEMENT);
execute immediate RENAME_STATEMENT;
exception
when NO_DATA_FOUND then
null;
end;
begin
select INDEX_NAME
into SYSTEM_GENERATED_NAME
from ALL_IND_COLUMNS
where COLUMN_NAME = XPATH
and TABLE_NAME = XMLTABLE
and TABLE_OWNER = USER;
RENAME_STATEMENT := 'alter index ' || USER || '."' || SYSTEM_GENERATED_NAME || '" rename to "' || PARENT_INDEX_NAME || '"';
-- dbms_output.put_line(RENAME_STATEMENT);
execute immediate RENAME_STATEMENT;
exception
when NO_DATA_FOUND then
null;
end;
end;
function processNestedTable(currentLevel in out number, currentNode in out XMLType, query SYS_REFCURSOR)
return XMLType
is
thisLevel number;
thisNode xmlType;
result xmlType;
begin
thisLevel := currentLevel;
thisNode := currentNode;
fetch query into currentLevel, currentNode;
if (query%NOTFOUND) then
currentLevel := -1;
end if;
while (currentLevel >= thisLevel) loop
-- Next Node is a decendant of sibling of this Node.
if (currentLevel > thisLevel) then
-- Next Node is a decendant of this Node.
result := processNestedTable(currentLevel, currentNode, query);
select xmlElement
"Collection",
extract(thisNode,'/Collection/*'),
xmlElement
"NestedCollections",
result
into thisNode
from dual;
else
-- Next node is a sibling of this Node.
result := processNestedTable(currentLevel, currentNode, query);
select xmlconcat(thisNode,result) into thisNode from dual;
end if;
end loop;
-- Next Node is a sibling of some ancestor of this node.
return thisNode;
end;
function printNestedTables(XML_TABLE varchar2)
return XMLType
is
query SYS_REFCURSOR;
result XMLType;
rootLevel number := 0;
rootNode xmlType;
begin
open query for
select level, xmlElement
"Collection",
xmlElement
"CollectionId",
PARENT_TABLE_COLUMN
) as XML
from USER_NESTED_TABLES
connect by PRIOR TABLE_NAME = PARENT_TABLE_NAME
start with PARENT_TABLE_NAME = XML_TABLE;
fetch query into rootLevel, rootNode;
result := processNestedTable(rootLevel, rootNode, query);
select xmlElement
"NestedTableStructure",
result
into result
from dual;
return result;
end;
function generateSchemaFromTable(P_TABLE_NAME varchar2, P_OWNER varchar2 default USER)
return XMLTYPE
as
xmlSchema XMLTYPE;
begin
select xmlElement
"xsd:schema",
xmlAttributes
'http://www.w3.org/2001/XMLSchema' as "xmlns:xsd",
'http://xmlns.oracle.com/xdb' as "xmlns:xdb"
xmlElement
"xsd:element",
xmlAttributes
'ROWSET' as "name",
'rowset' as "type"
xmlElement
"xsd:complexType",
xmlAttributes
'rowset' as "name"
xmlElement
"xsd:sequence",
xmlElement
"xsd:element",
xmlAttributes
'ROW' as "name",
table_name || '_T' as "type",
'unbounded' as "maxOccurs"
xmlElement
"xsd:complexType",
xmlAttributes
table_name || '_T' as "name"
xmlElement
"xsd:sequence",
xmlAgg(ELEMENT order by INTERNAL_COLUMN_ID)
into xmlSchema
from (select TABLE_NAME, INTERNAL_COLUMN_ID,
case
when DATA_TYPE = 'VARCHAR2' then
xmlElement
"xsd:element",
xmlattributes
column_name as "name",
column_name as "xdb:SQLName",
DATA_TYPE as "xdb:SQLTYPE"
xmlElement
"xsd:simpleType",
xmlElement
"xsd:restriction",
xmlAttributes
'xsd:string' as "base"
xmlElement
"xsd:maxLength",
xmlAttributes
DATA_LENGTH as "value"
when DATA_TYPE = 'DATE' then
xmlElement
"xsd:element",
xmlattributes
column_name as "name",
'xsd:dateTime' as "type",
column_name as "xdb:SQLName",
DATA_TYPE as "xdb:SQLTYPE"
else
xmlElement
"xsd:element",
xmlattributes
column_name as "name",
'xsd:anySimpleType' as "type",
column_name as "xdb:SQLName",
DATA_TYPE as "xdb:SQLTYPE"
end ELEMENT
from all_tab_cols c
where c.TABLE_NAME = P_TABLE_NAME
and c.OWNER = P_OWNER
group by TABLE_NAME;
return xmlSchema;
end;
end XDB_ANALYZE_XMLSCHEMA_11100;
show errors
--You can use this as follows...
SQL> set long 100000
SQL> select xdb_analyze_xmlschema.analyzeStorageModel('ComponentA') from dual;
<ComponentA type="COMPONENTA_T" owner="XDBTEST" columns="50">
<RootType type="COMPONENTA_T" typeOwner="XDBTEST" columns="50">
<SQLAttributes columns="14">
<SYS_XDBPD collectionType="RAW" collectionOwner="" columns="2"/>
<COMPONENTA_UNIQUENAME type="COMPONENTA_UNIQUENAME_T" owner="XDBTEST" columns="6">
<RootType type="COMPONENTA_UNIQUENAME_T" typeOwner="XDBTEST" columns="4">
<SQLAttributes columns="4">
<SYS_XDBPD collectionType="RAW" collectionOwner="" columns="2"/>
<SYS_XDBBODY type="VARCHAR2" columns="1"/>
<DISPLAYNAME type="VARCHAR2" columns="1"/>
</SQLAttributes>
</RootType>
</COMPONENTA_UNIQUENAME>
<COMPONENTA_DESCRIPTION type="COMPONENTA_DESCRIPTION_T" owner="XDBTEST" columns="6">
<RootType type="COMPONENTA_DESCRIPTION_T" typeOwner="XDBTEST" columns="4">
<SQLAttributes columns="4">
<SYS_XDBPD collectionType="RAW" collectionOwner="" columns="2"/>
<SYS_XDBBODY type="VARCHAR2" columns="1"/>
<DISPLAYNAME type="VARCHAR2" columns="1"/>
</SQLAttributes>
</RootType>
</COMPONENTA_DESCRIPTION>
</SQLAttributes>
<ExtendedType type="COMPONENTB_T" typeOwner="XDBTEST" columns="30">
<SQLAttributes columns="12">
<COMPONENTB_CONTROLNUMBER type="COMPONENTB_CONTROLNUMBER_T" owner="XDBTEST" columns="6">
<RootType type="COMPONENTB_CONTROLNUMBER_T" typeOwner="XDBTEST" columns="4">
<SQLAttributes columns="4">
<SYS_XDBPD collectionType="RAW" collectionOwner="" columns="2"/>
<SYS_XDBBODY type="VARCHAR2" columns="1"/>
<DISPLAYNAME type="VARCHAR2" columns="1"/>
</SQLAttributes>
</RootType>
</COMPONENTB_CONTROLNUMBER>
<COMPONENTB_COREFOLDER type="COMPONENTB_COREFOLDER_T" owner="XDBTEST" columns="6">
<RootType type="COMPONENTB_COREFOLDER_T" typeOwner="XDBTEST" columns="4">
<SQLAttributes columns="4">
<SYS_XDBPD collectionType="RAW" collectionOwner="" columns="2"/>
<SYS_XDBBODY type="VARCHAR2" columns="1"/>
<DISPLAYNAME type="VARCHAR2" columns="1"/>
</SQLAttributes>
</RootType>
</COMPONENTB_COREFOLDER>
</SQLAttributes>
<ExtendedType type="COMPONENTD_T" typeOwner="XDBTEST" columns="18">
<SQLAttributes columns="18">
<COMPONENTD_FINDINGTYPE type="COMPONENTD_FINDINGTYPE_T" owner="XDBTEST" columns="6">
<RootType type="COMPONENTD_FINDINGTYPE_T" typeOwner="XDBTEST" columns="4">
<SQLAttributes columns="4">
<SYS_XDBPD collectionType="RAW" collectionOwner="" columns="2"/>
<SYS_XDBBODY type="VARCHAR2" columns="1"/>
<DISPLAYNAME type="VARCHAR2" columns="1"/>
</SQLAttributes>
</RootType>
</COMPONENTD_FINDINGTYPE>
<COMPONENTD_PRIORITY type="COMPONENTD_PRIORITY_T" owner="XDBTEST" columns="6">
<RootType type="COMPONENTD_PRIORITY_T" typeOwner="XDBTEST" columns="4">
<SQLAttributes columns="4">
<SYS_XDBPD collectionType="RAW" collectionOwner="" columns="2"/>
<SYS_XDBBODY type="VARCHAR2" columns="1"/>
<DISPLAYNAME type="VARCHAR2" columns="1"/>
</SQLAttributes>
</RootType>
</COMPONENTD_PRIORITY>
<COMPONENTD_SUMMARY type="COMPONENTD_SUMMARY_T" owner="XDBTEST" columns="6">
<RootType type="COMPONENTD_SUMMARY_T" typeOwner="XDBTEST" columns="4">
<SQLAttributes columns="4">
<SYS_XDBPD collectionType="RAW" collectionOwner="" columns="2"/>
<SYS_XDBBODY type="VARCHAR2" columns="1"/>
<DISPLAYNAME type="VARCHAR2" columns="1"/>
</SQLAttributes>
</RootType>
</COMPONENTD_SUMMARY>
</SQLAttributes>
</ExtendedType>
</ExtendedType>
<ExtendedType type="COMPONENTC_T" typeOwner="XDBTEST" columns="6">
<SQLAttributes columns="6">
<COMPONENTC_CONTROLNUMBER type="COMPONENTC_CONTROLNUMBER_T" owner="XDBTEST" columns="6">
<RootType type="COMPONENTC_CONTROLNUMBER_T" typeOwner="XDBTEST" columns="4">
<SQLAttributes columns="4">
<SYS_XDBPD collectionType="RAW" collectionOwner="" columns="2"/>
<SYS_XDBBODY type="VARCHAR2" columns="1"/>
<DISPLAYNAME type="VARCHAR2" columns="1"/>
</SQLAttributes>
</RootType>
</COMPONENTC_CONTROLNUMBER>
</SQLAttributes>
</ExtendedType>
</RootType>
</ComponentA>THis will tell you that a table based xml element of the complexType 'componentA' will have approx 50 columns.. -
Suggested feature - wire-format aware binary extractor
I would like to suggest another feature, which might or might not improve performance of querying unindexed attributes (possibly at the cost of some more bytes in the wire-format).
We found that in case of querying caches with many keys, but no indexes on the queried attribute, the performance of the cache is quite worse than querying Oracle, for instance.
The foremost reason of that, I believe, is that for this scenario, the primary node has to deserialize all the entries in the cache to extract a single attribute from it, compared to a database which knows the exact position and representation of that value in the database storage.
If the cached entry did not have to be deserialized, but we knew how to pointedly extract only the particular attribute from the wire format, it could be way faster, and even some object allocations may be avoided compared to the current situation.
I think, that providing a new extraction method could speed up this scenario, all it requires is that the extractor be faster than the deserializing the entire object. This can for example be provided by having the attributes extracted this way put to a place where it is much faster to be found, probably to a fixed position in the wire format.
As the entries (key and value) are stored in wire-format in the backing map, the wire-format can be passed without a byte array copy to the filter or to the extractor.
I suggest the following interfaces could be used for such an extractor and a custom filter using similar techniques:
public interface WireFormatAwareBinaryExtractor {
Object extractFromBinary(byte[] wireFormat, int wireFormatStartsAt, int wireFormatLength);
public interface WireFormatAwareBinaryFilter {
boolean evaluateBinaryValue(byte[] valueWireFormat, int valueStartsAt, int valueLength);
public interface WireFormatAwareBinaryEntryFilter {
boolean isKeyRequiredAsBinary();
boolean evaluateKeyAndBinaryValue(
Object key,
byte[] valueWireFormat, int valueStartsAt, int valueLength);
boolean evaluateBinaryKeyAndValue(
byte[] keyWireFormat, int keyStartsAt, int keyLength,
byte[] valueWireFormat, int valueStartsAt, int valueLength);
The two int attributes are necessary only if the byte[] contains more than the binary representation of the value or the key, but other bytes as well (e.g. the key and the value in the same array, in which case one of the array parameters can actually go; or it might contain class name or class name cache index, you know it, this is an internal detail).
In case of the entry filter, depending on the return value of the isKeyRequiredAsBinary() method, one or the other evaluate method would be invoked.
After this, the developer is free to choose how he modifies the wire format of his cached classes, to suit this as much as possible, if he wants to use this feature.
I don't know how much this may or may not help with the performance of queries, but I think it can help in some cases, for example when the index cost of a cache would be too prohibitive, compared to the wins it can provide (e.g. all queries to that attribute can be prefiltered to a number of candidate keys which is way less than the entire key set size, and the values in the attribute are so diverse that the index would consume almost as much space as (or even more than) the values themselves).
Also it is a feature which is not too complex to implement, I believe.
Also, it would be useful to have utility methods equivalent to the read methods on the ExternalizableHelper class to be provided but with a byte[] and int (start index) instead of a DataInput in the signature.
Or otherwise the byte[] parameters in the methods might be replaced with a seekable DataInput wrapper containing the byte[] (in which the wrapped byte[] can be changed by the loop evaluating the entries).
Best regards,
Robert Varga
Message was edited by:
robvargaWe found that in case of querying caches with many > keys, but no indexes on the queried
> > attribute, the performance of the cache is quite
> worse than querying Oracle, for instance.
>
> That is to be expected.
>
> Please also note that Oracle (and other SQL
> databases) are very refined and optimized
> implementations of relational query engines, so it
> should not be surprising when results are in their
> favor for relational-style queries.
>
> > The foremost reason of that, I believe, is that for
> this scenario, the primary node has to
> > deserialize all the entries in the cache to extract
> a single attribute from it, compared to a
> > database which knows the exact position and
> representation of that value in the database
> > storage.
>
> Yes, deserialization can be quite expensive.
>
Yes, I am aware of it, and accept them as a trade-off for getting objects in the cache. And I was not even speaking about the relational part of RDBMS-es, only about the partially reproducable advantage of the known storage structure of a single table.
And it was mostly just the preface text. :-)
> > I think, that providing a new extraction method
> could speed up this scenario, all it
> > requires is that the extractor be faster than the
> deserializing the entire object. This can
> > for example be provided by having the attributes
> extracted this way put to a place
> > where it is much faster to be found, probably to a
> fixed position in the wire format.
>
> We considered fixed-position techniques, but decided
> against them for a number of reasons, although for
> the use case you describe it would likely work well.
> Our decision was based on the following:
>
> 1) The fixed length fields would all have to be
> placed first into the binary structure in order for
> those data to have fixed offsets, and
> 2) Only the fixed length fields of the outermost
> object would be directly extractable.
>
Yes, but if the developer has the freedom to choose such an extractor, it cannot hurt to provide the feature as an alternative to ReflectionExtractor and extracted value-using filters, if it is sort of straightforward to implement.
And I believe, actually not only the first fixed length fields would be extractable, but you could also get the same sort of speed advantage, as you have when using a SAX parser instead of a DOM builder, because you don't need to instantiate objects which you do not even need, and you can skip (or at least search for the end of it) stuff which you do not need without actually instantiating it.
> In your example, you suggested:
>
> Object extractFromBinary(byte[] wireFormat, int
> wireFormatStartsAt, int wireFormatLength); >
> A couple things to keep in mind:
>
> 1) The data stored in a backing map is a Binary
> object (com.tangosol.util.Binary)
> 2) A Binary object can provide a Binary object within
> it without copying:
>
> Binary binSub =
> bin.toBinary(wireFormatStartsAt,
> wireFormatLength); >
> 3) A Binary object can provide a BufferInput, which
> is a combination of an Input Stream, a Data Input
> implementation, etc.:
>
> ReadBuffer.BufferInput in =
> bin.toBinary(wireFormatStartsAt,
> wireFormatLength).getBufferInput(); >
> .. or simply:
>
> ReadBuffer.BufferInput in =
> bin.getBufferInput(wireFormatStartsAt,
> wireFormatLength); >
> (See the JavaDoc documentation in com.tangosol.io
> package.)
>
> 4) To extract an "int" value from offset 13, it's as
> easy as:
>
> int n = bin.getBufferInput(13,
> 4).readInt(); >
> .. but since it's a known offset, you can simply do
> this:
>
> int n =
> bin.getBufferInput().setOffset(13).readInt(); >
> > Also, it would be useful to have utility methods
> equivalent to the read methods on the
> > ExternalizableHelper class to be provided but with
> a byte[] and int (start index) instead
> > of a DataInput in the signature.
>
> BufferInput does that already, for the most part.
>
> > Or otherwise the byte[] parameters in the methods
> might be replaced with a seekable
> > DataInput wrapper containing the byte[] (in which
> the wrapped byte[] can be changed
> > by the loop evaluating the entries).
>
> That's exactly what BufferInput is.
>
> Check it out and tell me if we're talking about the
> same thing.
>
I think we are. :-)
>
> In 3.2, an improved type of serialization will be
> provided as well (as discussed previously on some of
> the XmlBean threads), which may address this
> question.
>
Can't wait to see it. When will it be released? In some post it was mentioned that 3.2 GA is tentatively scheduled for this July. Is there some update to that? :-)
> Peace,
>
> Cameron.
Thanks and best regards,
Robert -
Can interMedia store CMYK colorspace images and images containing IPTC metadata?
<BLOCKQUOTE><font size="1" face="Verdana, Arial">quote:</font><HR>Originally posted by Susan Mavris:
Can interMedia store CMYK colorspace images and images containing IPTC metadata?<HR></BLOCKQUOTE>
Any image, regardless of format and/or color space, can be stored in the interMedia ORDImage object type. Similarly, any audio or video can be stored in the ORDAudio or
ORDVideo object type.
If the format of the media being stored is natively understood by interMedia, we offer additional capability, namely attribute extraction and image processing.
The ORDImage import method automatically calls the setProperties method to extract image attributes. This is a problem for formats that are not natively understood by interMedia. If the format stored in the format attribute of the ORDImage object begins with "OTHER", the import method will not automatically call setProperties after importing the image into the BLOB. This
is how to avoid problems with importing CMYK and IPTC images using the ORDImage import method.
Please take a look at the interMedia Annotator Utility. This utility, available on OTN, is capable of parsing IPTC metadata
and uploading the metadata and the image into the database. Depending on what formats you're using, it may also be able to parse your CMYK color space images. -
XMLType extract method does not work if namespace attribute values are included
In the example below, only the second row returns an ID from the extract function. The presence of an xmlns attribute appears to be the cause.
SQL> drop table configs;
Table dropped.
Elapsed: 00:00:03.06
SQL>
SQL> create table configs (xml_data sys.xmltype);
Table created.
Elapsed: 00:00:00.02
SQL>
SQL> create index configs on configs (xml_data) indextype is ctxsys.context;
Index created.
Elapsed: 00:00:02.01
SQL>
SQL> insert into configs values(sys.xmltype.createxml('<config
2 xmlns="http://www.ourcompanykscl.com/configuration">
3 <dataformat
4 name="F1" description="format spec" id="14082" version="2"
5 status="started" deployed="true" lastModifiedBy="bloggsj" lastModifiedDate="2002-05-10T09:44:45">
6 <F11Format>
7 <SpecificationFilename>c:/formats/F1.txt</SpecificationFilename>
8 </F11Format>
9 </dataformat></config>'
10 ))
11 /
1 row created.
Elapsed: 00:00:01.02
SQL>
SQL> insert into configs values(sys.xmltype.createxml('<config>
2 <dataformat
3 name="F1" description="format spec" id="14082" version="2"
4 status="started" deployed="true" lastModifiedBy="bloggsj" lastModifiedDate="2002-05-10T09:44:45">
5 <F11Format>
6 <SpecificationFilename>c:/formats/F1.txt</SpecificationFilename>
7 </F11Format>
8 </dataformat>
9 </config>'
10 ))
11 /
1 row created.
Elapsed: 00:00:00.00
SQL>
SQL> BEGIN
2 ctx_ddl.sync_index('configs');
3 END;
4 /
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.02
SQL>
SQL> SELECT c.xml_data.extract('//dataformat/@id').getstringval(), c.xml_data.getstringval()
2 FROM configs c
3 WHERE CONTAINS(c.xml_data, '14082 INPATH (//dataformat/@id)') > 0
4 /
C.XML_DATA.EXTRACT('//DATAFORMAT/@ID').GETSTRINGVAL()
C.XML_DATA.GETSTRINGVAL()
<config
xmlns="http://www.ourcompanykscl.com/configuration">
<dataformat
name="F1" description="format spec" id="14082" version="2"
status="started" deployed="true" lastModifiedBy="bloggsj" lastModifiedDa
te="2002-05-10T09:44:45">
<F11Format>
<SpecificationFilename>c:/formats/F1.txt</SpecificationFilename>
</F11Format>
</dataformat></config>
14082
<config>
<dataformat
name="F1" description="format spec" id="14082" version="2"
status="started" deployed="true" lastModifiedBy="bloggsj" lastModifiedDa
te="2002-05-10T09:44:45">
<F11Format>
<SpecificationFilename>c:/formats/F1.txt</SpecificationFilename>
</F11Format>
</dataformat>
</config>
Elapsed: 00:00:00.03Hi Amarnath,
Thanks for looking into my issue.
When I started writing the dynamic custom approver group, I did not use FND_NUMBER and it didnt work. After that I checked it in the AME Implementation Guide which says
"Queries for number and currency attributes must select the number or currency
amount converted to a varchar2 by:
fnd_number.number_to_canonical"
So that should not be a problem.
Please correct me if I am wrong but Now I see two different possibilities :
1. The seeded variable :transactionId which is being passed to the query is not able to get the value. In other words, the transactionId is not being passed.
2. I am using wrong Attributes to identify the transaction which is being used in the Condition and that condition is used in a Rule. In this case, I am trying to identify that the Basic Person details are changed and I am using seeded attribute HR_IS_PERSON_BASIC_DETAILS_CHANGE_SS in condition.
Any feedback?
Appreciate all replies.
Thanks,
CAH
Maybe you are looking for
-
XI Installation: Adapters do not work.
Hello, All. I can not get any adapters after Installation of SAP XI. JPR adapter is only available in "RWB\Component monitoring\Adapter monitoring" (and it is at red state). After clicking at JPR I can see extended information: SLD access is in red s
-
Problem to display japanese/multi-byte character on weblogic server 9.1
Hi experts We are running weblogic 9.1 on linux box [REHL v4] and trying to display Japanese characters embedded in some of html files, but Japanese characters are converted into a question mark [?]. The html files that contain Japanese characters ar
-
How do I get the the indicator light to work with Voice Mail
I recently switched to Digital Voice. I have a Panasonic Phone that has a light that indicates when I have Voice mail. The light is NOT working when I get voice mail, however I get the stutter dial tone when I have voice mails. Is there something
-
Installing grub2 fails due to labels conflicts?
I had a working arch setup on /dev/sda with the following setup: /dev/sda1 /boot /dev/sda4 / Then I bought a new disk and installed a new archlinux onto LUKS from the previous working system. The new setup is the following: /dev/sdb1 /boot /dev/sdb2
-
Webservice Execution based on a condition
Hi , I have implemented a serch form using webservice. Now my web service is getting called on page load. its rather getting called for every other method call. how to stop the execution conditionally Regards, Naveen