Initial
This commit is contained in:
parent
eba568be76
commit
d261820c98
3
.idea/.gitignore
vendored
Normal file
3
.idea/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
409
.idea/dbnavigator.xml
Normal file
409
.idea/dbnavigator.xml
Normal file
@ -0,0 +1,409 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="DBNavigator.Project.DatabaseBrowserManager">
|
||||||
|
<autoscroll-to-editor value="false" />
|
||||||
|
<autoscroll-from-editor value="true" />
|
||||||
|
<show-object-properties value="true" />
|
||||||
|
<loaded-nodes />
|
||||||
|
</component>
|
||||||
|
<component name="DBNavigator.Project.DatabaseFileManager">
|
||||||
|
<open-files />
|
||||||
|
</component>
|
||||||
|
<component name="DBNavigator.Project.Settings">
|
||||||
|
<connections />
|
||||||
|
<browser-settings>
|
||||||
|
<general>
|
||||||
|
<display-mode value="TABBED" />
|
||||||
|
<navigation-history-size value="100" />
|
||||||
|
<show-object-details value="false" />
|
||||||
|
<enable-sticky-paths value="true" />
|
||||||
|
</general>
|
||||||
|
<filters>
|
||||||
|
<object-type-filter>
|
||||||
|
<object-type name="SCHEMA" enabled="true" />
|
||||||
|
<object-type name="USER" enabled="true" />
|
||||||
|
<object-type name="ROLE" enabled="true" />
|
||||||
|
<object-type name="PRIVILEGE" enabled="true" />
|
||||||
|
<object-type name="CHARSET" enabled="true" />
|
||||||
|
<object-type name="TABLE" enabled="true" />
|
||||||
|
<object-type name="VIEW" enabled="true" />
|
||||||
|
<object-type name="MATERIALIZED_VIEW" enabled="true" />
|
||||||
|
<object-type name="NESTED_TABLE" enabled="true" />
|
||||||
|
<object-type name="COLUMN" enabled="true" />
|
||||||
|
<object-type name="INDEX" enabled="true" />
|
||||||
|
<object-type name="CONSTRAINT" enabled="true" />
|
||||||
|
<object-type name="DATASET_TRIGGER" enabled="true" />
|
||||||
|
<object-type name="DATABASE_TRIGGER" enabled="true" />
|
||||||
|
<object-type name="SYNONYM" enabled="true" />
|
||||||
|
<object-type name="SEQUENCE" enabled="true" />
|
||||||
|
<object-type name="PROCEDURE" enabled="true" />
|
||||||
|
<object-type name="FUNCTION" enabled="true" />
|
||||||
|
<object-type name="PACKAGE" enabled="true" />
|
||||||
|
<object-type name="TYPE" enabled="true" />
|
||||||
|
<object-type name="TYPE_ATTRIBUTE" enabled="true" />
|
||||||
|
<object-type name="ARGUMENT" enabled="true" />
|
||||||
|
<object-type name="DIMENSION" enabled="true" />
|
||||||
|
<object-type name="CLUSTER" enabled="true" />
|
||||||
|
<object-type name="DBLINK" enabled="true" />
|
||||||
|
</object-type-filter>
|
||||||
|
</filters>
|
||||||
|
<sorting>
|
||||||
|
<object-type name="COLUMN" sorting-type="NAME" />
|
||||||
|
<object-type name="FUNCTION" sorting-type="NAME" />
|
||||||
|
<object-type name="PROCEDURE" sorting-type="NAME" />
|
||||||
|
<object-type name="ARGUMENT" sorting-type="POSITION" />
|
||||||
|
<object-type name="TYPE ATTRIBUTE" sorting-type="POSITION" />
|
||||||
|
</sorting>
|
||||||
|
<default-editors>
|
||||||
|
<object-type name="VIEW" editor-type="SELECTION" />
|
||||||
|
<object-type name="PACKAGE" editor-type="SELECTION" />
|
||||||
|
<object-type name="TYPE" editor-type="SELECTION" />
|
||||||
|
</default-editors>
|
||||||
|
</browser-settings>
|
||||||
|
<navigation-settings>
|
||||||
|
<lookup-filters>
|
||||||
|
<lookup-objects>
|
||||||
|
<object-type name="SCHEMA" enabled="true" />
|
||||||
|
<object-type name="USER" enabled="false" />
|
||||||
|
<object-type name="ROLE" enabled="false" />
|
||||||
|
<object-type name="PRIVILEGE" enabled="false" />
|
||||||
|
<object-type name="CHARSET" enabled="false" />
|
||||||
|
<object-type name="TABLE" enabled="true" />
|
||||||
|
<object-type name="VIEW" enabled="true" />
|
||||||
|
<object-type name="MATERIALIZED VIEW" enabled="true" />
|
||||||
|
<object-type name="INDEX" enabled="true" />
|
||||||
|
<object-type name="CONSTRAINT" enabled="true" />
|
||||||
|
<object-type name="DATASET TRIGGER" enabled="true" />
|
||||||
|
<object-type name="DATABASE TRIGGER" enabled="true" />
|
||||||
|
<object-type name="SYNONYM" enabled="false" />
|
||||||
|
<object-type name="SEQUENCE" enabled="true" />
|
||||||
|
<object-type name="PROCEDURE" enabled="true" />
|
||||||
|
<object-type name="FUNCTION" enabled="true" />
|
||||||
|
<object-type name="PACKAGE" enabled="true" />
|
||||||
|
<object-type name="TYPE" enabled="true" />
|
||||||
|
<object-type name="DIMENSION" enabled="false" />
|
||||||
|
<object-type name="CLUSTER" enabled="false" />
|
||||||
|
<object-type name="DBLINK" enabled="true" />
|
||||||
|
</lookup-objects>
|
||||||
|
<force-database-load value="false" />
|
||||||
|
<prompt-connection-selection value="true" />
|
||||||
|
<prompt-schema-selection value="true" />
|
||||||
|
</lookup-filters>
|
||||||
|
</navigation-settings>
|
||||||
|
<dataset-grid-settings>
|
||||||
|
<general>
|
||||||
|
<enable-zooming value="true" />
|
||||||
|
<enable-column-tooltip value="true" />
|
||||||
|
</general>
|
||||||
|
<sorting>
|
||||||
|
<nulls-first value="true" />
|
||||||
|
<max-sorting-columns value="4" />
|
||||||
|
</sorting>
|
||||||
|
<audit-columns>
|
||||||
|
<column-names value="" />
|
||||||
|
<visible value="true" />
|
||||||
|
<editable value="false" />
|
||||||
|
</audit-columns>
|
||||||
|
</dataset-grid-settings>
|
||||||
|
<dataset-editor-settings>
|
||||||
|
<text-editor-popup>
|
||||||
|
<active value="false" />
|
||||||
|
<active-if-empty value="false" />
|
||||||
|
<data-length-threshold value="100" />
|
||||||
|
<popup-delay value="1000" />
|
||||||
|
</text-editor-popup>
|
||||||
|
<values-actions-popup>
|
||||||
|
<show-popup-button value="true" />
|
||||||
|
<element-count-threshold value="1000" />
|
||||||
|
<data-length-threshold value="250" />
|
||||||
|
</values-actions-popup>
|
||||||
|
<general>
|
||||||
|
<fetch-block-size value="100" />
|
||||||
|
<fetch-timeout value="30" />
|
||||||
|
<trim-whitespaces value="true" />
|
||||||
|
<convert-empty-strings-to-null value="true" />
|
||||||
|
<select-content-on-cell-edit value="true" />
|
||||||
|
<large-value-preview-active value="true" />
|
||||||
|
</general>
|
||||||
|
<filters>
|
||||||
|
<prompt-filter-dialog value="true" />
|
||||||
|
<default-filter-type value="BASIC" />
|
||||||
|
</filters>
|
||||||
|
<qualified-text-editor text-length-threshold="300">
|
||||||
|
<content-types>
|
||||||
|
<content-type name="Text" enabled="true" />
|
||||||
|
<content-type name="Properties" enabled="true" />
|
||||||
|
<content-type name="XML" enabled="true" />
|
||||||
|
<content-type name="DTD" enabled="true" />
|
||||||
|
<content-type name="HTML" enabled="true" />
|
||||||
|
<content-type name="XHTML" enabled="true" />
|
||||||
|
<content-type name="Java" enabled="true" />
|
||||||
|
<content-type name="SQL" enabled="true" />
|
||||||
|
<content-type name="PL/SQL" enabled="true" />
|
||||||
|
<content-type name="JSON" enabled="true" />
|
||||||
|
<content-type name="JSON5" enabled="true" />
|
||||||
|
<content-type name="Groovy" enabled="true" />
|
||||||
|
<content-type name="YAML" enabled="true" />
|
||||||
|
<content-type name="Manifest" enabled="true" />
|
||||||
|
</content-types>
|
||||||
|
</qualified-text-editor>
|
||||||
|
<record-navigation>
|
||||||
|
<navigation-target value="VIEWER" />
|
||||||
|
</record-navigation>
|
||||||
|
</dataset-editor-settings>
|
||||||
|
<code-editor-settings>
|
||||||
|
<general>
|
||||||
|
<show-object-navigation-gutter value="false" />
|
||||||
|
<show-spec-declaration-navigation-gutter value="true" />
|
||||||
|
<enable-spellchecking value="true" />
|
||||||
|
<enable-reference-spellchecking value="false" />
|
||||||
|
</general>
|
||||||
|
<confirmations>
|
||||||
|
<save-changes value="false" />
|
||||||
|
<revert-changes value="true" />
|
||||||
|
<exit-on-changes value="ASK" />
|
||||||
|
</confirmations>
|
||||||
|
</code-editor-settings>
|
||||||
|
<code-completion-settings>
|
||||||
|
<filters>
|
||||||
|
<basic-filter>
|
||||||
|
<filter-element type="RESERVED_WORD" id="keyword" selected="true" />
|
||||||
|
<filter-element type="RESERVED_WORD" id="function" selected="true" />
|
||||||
|
<filter-element type="RESERVED_WORD" id="parameter" selected="true" />
|
||||||
|
<filter-element type="RESERVED_WORD" id="datatype" selected="true" />
|
||||||
|
<filter-element type="RESERVED_WORD" id="exception" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="schema" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="role" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="user" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="privilege" selected="true" />
|
||||||
|
<user-schema>
|
||||||
|
<filter-element type="OBJECT" id="table" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="view" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="materialized view" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="index" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="constraint" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="trigger" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="synonym" selected="false" />
|
||||||
|
<filter-element type="OBJECT" id="sequence" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="procedure" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="function" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="package" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="type" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="dimension" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="cluster" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="dblink" selected="true" />
|
||||||
|
</user-schema>
|
||||||
|
<public-schema>
|
||||||
|
<filter-element type="OBJECT" id="table" selected="false" />
|
||||||
|
<filter-element type="OBJECT" id="view" selected="false" />
|
||||||
|
<filter-element type="OBJECT" id="materialized view" selected="false" />
|
||||||
|
<filter-element type="OBJECT" id="index" selected="false" />
|
||||||
|
<filter-element type="OBJECT" id="constraint" selected="false" />
|
||||||
|
<filter-element type="OBJECT" id="trigger" selected="false" />
|
||||||
|
<filter-element type="OBJECT" id="synonym" selected="false" />
|
||||||
|
<filter-element type="OBJECT" id="sequence" selected="false" />
|
||||||
|
<filter-element type="OBJECT" id="procedure" selected="false" />
|
||||||
|
<filter-element type="OBJECT" id="function" selected="false" />
|
||||||
|
<filter-element type="OBJECT" id="package" selected="false" />
|
||||||
|
<filter-element type="OBJECT" id="type" selected="false" />
|
||||||
|
<filter-element type="OBJECT" id="dimension" selected="false" />
|
||||||
|
<filter-element type="OBJECT" id="cluster" selected="false" />
|
||||||
|
<filter-element type="OBJECT" id="dblink" selected="false" />
|
||||||
|
</public-schema>
|
||||||
|
<any-schema>
|
||||||
|
<filter-element type="OBJECT" id="table" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="view" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="materialized view" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="index" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="constraint" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="trigger" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="synonym" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="sequence" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="procedure" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="function" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="package" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="type" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="dimension" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="cluster" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="dblink" selected="true" />
|
||||||
|
</any-schema>
|
||||||
|
</basic-filter>
|
||||||
|
<extended-filter>
|
||||||
|
<filter-element type="RESERVED_WORD" id="keyword" selected="true" />
|
||||||
|
<filter-element type="RESERVED_WORD" id="function" selected="true" />
|
||||||
|
<filter-element type="RESERVED_WORD" id="parameter" selected="true" />
|
||||||
|
<filter-element type="RESERVED_WORD" id="datatype" selected="true" />
|
||||||
|
<filter-element type="RESERVED_WORD" id="exception" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="schema" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="user" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="role" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="privilege" selected="true" />
|
||||||
|
<user-schema>
|
||||||
|
<filter-element type="OBJECT" id="table" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="view" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="materialized view" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="index" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="constraint" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="trigger" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="synonym" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="sequence" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="procedure" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="function" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="package" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="type" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="dimension" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="cluster" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="dblink" selected="true" />
|
||||||
|
</user-schema>
|
||||||
|
<public-schema>
|
||||||
|
<filter-element type="OBJECT" id="table" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="view" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="materialized view" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="index" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="constraint" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="trigger" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="synonym" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="sequence" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="procedure" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="function" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="package" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="type" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="dimension" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="cluster" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="dblink" selected="true" />
|
||||||
|
</public-schema>
|
||||||
|
<any-schema>
|
||||||
|
<filter-element type="OBJECT" id="table" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="view" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="materialized view" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="index" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="constraint" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="trigger" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="synonym" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="sequence" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="procedure" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="function" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="package" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="type" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="dimension" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="cluster" selected="true" />
|
||||||
|
<filter-element type="OBJECT" id="dblink" selected="true" />
|
||||||
|
</any-schema>
|
||||||
|
</extended-filter>
|
||||||
|
</filters>
|
||||||
|
<sorting enabled="true">
|
||||||
|
<sorting-element type="RESERVED_WORD" id="keyword" />
|
||||||
|
<sorting-element type="RESERVED_WORD" id="datatype" />
|
||||||
|
<sorting-element type="OBJECT" id="column" />
|
||||||
|
<sorting-element type="OBJECT" id="table" />
|
||||||
|
<sorting-element type="OBJECT" id="view" />
|
||||||
|
<sorting-element type="OBJECT" id="materialized view" />
|
||||||
|
<sorting-element type="OBJECT" id="index" />
|
||||||
|
<sorting-element type="OBJECT" id="constraint" />
|
||||||
|
<sorting-element type="OBJECT" id="trigger" />
|
||||||
|
<sorting-element type="OBJECT" id="synonym" />
|
||||||
|
<sorting-element type="OBJECT" id="sequence" />
|
||||||
|
<sorting-element type="OBJECT" id="procedure" />
|
||||||
|
<sorting-element type="OBJECT" id="function" />
|
||||||
|
<sorting-element type="OBJECT" id="package" />
|
||||||
|
<sorting-element type="OBJECT" id="type" />
|
||||||
|
<sorting-element type="OBJECT" id="dimension" />
|
||||||
|
<sorting-element type="OBJECT" id="cluster" />
|
||||||
|
<sorting-element type="OBJECT" id="dblink" />
|
||||||
|
<sorting-element type="OBJECT" id="schema" />
|
||||||
|
<sorting-element type="OBJECT" id="role" />
|
||||||
|
<sorting-element type="OBJECT" id="user" />
|
||||||
|
<sorting-element type="RESERVED_WORD" id="function" />
|
||||||
|
<sorting-element type="RESERVED_WORD" id="parameter" />
|
||||||
|
</sorting>
|
||||||
|
<format>
|
||||||
|
<enforce-code-style-case value="true" />
|
||||||
|
</format>
|
||||||
|
</code-completion-settings>
|
||||||
|
<execution-engine-settings>
|
||||||
|
<statement-execution>
|
||||||
|
<fetch-block-size value="100" />
|
||||||
|
<execution-timeout value="20" />
|
||||||
|
<debug-execution-timeout value="600" />
|
||||||
|
<focus-result value="false" />
|
||||||
|
<prompt-execution value="false" />
|
||||||
|
</statement-execution>
|
||||||
|
<script-execution>
|
||||||
|
<command-line-interfaces />
|
||||||
|
<execution-timeout value="300" />
|
||||||
|
</script-execution>
|
||||||
|
<method-execution>
|
||||||
|
<execution-timeout value="30" />
|
||||||
|
<debug-execution-timeout value="600" />
|
||||||
|
<parameter-history-size value="10" />
|
||||||
|
</method-execution>
|
||||||
|
</execution-engine-settings>
|
||||||
|
<operation-settings>
|
||||||
|
<transactions>
|
||||||
|
<uncommitted-changes>
|
||||||
|
<on-project-close value="ASK" />
|
||||||
|
<on-disconnect value="ASK" />
|
||||||
|
<on-autocommit-toggle value="ASK" />
|
||||||
|
</uncommitted-changes>
|
||||||
|
<multiple-uncommitted-changes>
|
||||||
|
<on-commit value="ASK" />
|
||||||
|
<on-rollback value="ASK" />
|
||||||
|
</multiple-uncommitted-changes>
|
||||||
|
</transactions>
|
||||||
|
<session-browser>
|
||||||
|
<disconnect-session value="ASK" />
|
||||||
|
<kill-session value="ASK" />
|
||||||
|
<reload-on-filter-change value="false" />
|
||||||
|
</session-browser>
|
||||||
|
<compiler>
|
||||||
|
<compile-type value="KEEP" />
|
||||||
|
<compile-dependencies value="ASK" />
|
||||||
|
<always-show-controls value="false" />
|
||||||
|
</compiler>
|
||||||
|
</operation-settings>
|
||||||
|
<ddl-file-settings>
|
||||||
|
<extensions>
|
||||||
|
<mapping file-type-id="VIEW" extensions="vw" />
|
||||||
|
<mapping file-type-id="TRIGGER" extensions="trg" />
|
||||||
|
<mapping file-type-id="PROCEDURE" extensions="prc" />
|
||||||
|
<mapping file-type-id="FUNCTION" extensions="fnc" />
|
||||||
|
<mapping file-type-id="PACKAGE" extensions="pkg" />
|
||||||
|
<mapping file-type-id="PACKAGE_SPEC" extensions="pks" />
|
||||||
|
<mapping file-type-id="PACKAGE_BODY" extensions="pkb" />
|
||||||
|
<mapping file-type-id="TYPE" extensions="tpe" />
|
||||||
|
<mapping file-type-id="TYPE_SPEC" extensions="tps" />
|
||||||
|
<mapping file-type-id="TYPE_BODY" extensions="tpb" />
|
||||||
|
</extensions>
|
||||||
|
<general>
|
||||||
|
<lookup-ddl-files value="true" />
|
||||||
|
<create-ddl-files value="false" />
|
||||||
|
<synchronize-ddl-files value="true" />
|
||||||
|
<use-qualified-names value="false" />
|
||||||
|
<make-scripts-rerunnable value="true" />
|
||||||
|
</general>
|
||||||
|
</ddl-file-settings>
|
||||||
|
<general-settings>
|
||||||
|
<regional-settings>
|
||||||
|
<date-format value="MEDIUM" />
|
||||||
|
<number-format value="UNGROUPED" />
|
||||||
|
<locale value="SYSTEM_DEFAULT" />
|
||||||
|
<use-custom-formats value="false" />
|
||||||
|
</regional-settings>
|
||||||
|
<environment>
|
||||||
|
<environment-types>
|
||||||
|
<environment-type id="development" name="Development" description="Development environment" color="-2430209/-12296320" readonly-code="false" readonly-data="false" />
|
||||||
|
<environment-type id="integration" name="Integration" description="Integration environment" color="-2621494/-12163514" readonly-code="true" readonly-data="false" />
|
||||||
|
<environment-type id="production" name="Production" description="Productive environment" color="-11574/-10271420" readonly-code="true" readonly-data="true" />
|
||||||
|
<environment-type id="other" name="Other" description="" color="-1576/-10724543" readonly-code="false" readonly-data="false" />
|
||||||
|
</environment-types>
|
||||||
|
<visibility-settings>
|
||||||
|
<connection-tabs value="true" />
|
||||||
|
<dialog-headers value="true" />
|
||||||
|
<object-editor-tabs value="true" />
|
||||||
|
<script-editor-tabs value="false" />
|
||||||
|
<execution-result-tabs value="true" />
|
||||||
|
</visibility-settings>
|
||||||
|
</environment>
|
||||||
|
</general-settings>
|
||||||
|
</component>
|
||||||
|
</project>
|
16
.idea/gradle.xml
Normal file
16
.idea/gradle.xml
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="GradleMigrationSettings" migrationVersion="1" />
|
||||||
|
<component name="GradleSettings">
|
||||||
|
<option name="linkedExternalProjectsSettings">
|
||||||
|
<GradleProjectSettings>
|
||||||
|
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||||
|
<option name="modules">
|
||||||
|
<set>
|
||||||
|
<option value="$PROJECT_DIR$" />
|
||||||
|
</set>
|
||||||
|
</option>
|
||||||
|
</GradleProjectSettings>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
</project>
|
6
.idea/misc.xml
Normal file
6
.idea/misc.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="openjdk-17" project-jdk-type="JavaSDK">
|
||||||
|
<output url="file://$PROJECT_DIR$/out" />
|
||||||
|
</component>
|
||||||
|
</project>
|
124
.idea/uiDesigner.xml
Normal file
124
.idea/uiDesigner.xml
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="Palette2">
|
||||||
|
<group name="Swing">
|
||||||
|
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
|
||||||
|
</item>
|
||||||
|
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.svg" removable="false" auto-create-binding="false" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
|
||||||
|
<initial-values>
|
||||||
|
<property name="text" value="Button" />
|
||||||
|
</initial-values>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
||||||
|
<initial-values>
|
||||||
|
<property name="text" value="RadioButton" />
|
||||||
|
</initial-values>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
||||||
|
<initial-values>
|
||||||
|
<property name="text" value="CheckBox" />
|
||||||
|
</initial-values>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
|
||||||
|
<initial-values>
|
||||||
|
<property name="text" value="Label" />
|
||||||
|
</initial-values>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||||
|
<preferred-size width="150" height="-1" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||||
|
<preferred-size width="150" height="-1" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||||
|
<preferred-size width="150" height="-1" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||||
|
<preferred-size width="150" height="50" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||||
|
<preferred-size width="150" height="50" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||||
|
<preferred-size width="150" height="50" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||||
|
<preferred-size width="150" height="50" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
|
||||||
|
<preferred-size width="150" height="50" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||||
|
<preferred-size width="150" height="50" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
||||||
|
<preferred-size width="200" height="200" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
||||||
|
<preferred-size width="200" height="200" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
|
||||||
|
<preferred-size width="-1" height="20" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
|
||||||
|
</item>
|
||||||
|
</group>
|
||||||
|
</component>
|
||||||
|
</project>
|
6
.idea/vcs.xml
Normal file
6
.idea/vcs.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
7
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
7
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
distributionBase=GRADLE_USER_HOME
|
||||||
|
distributionPath=wrapper/dists
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
|
||||||
|
networkTimeout=10000
|
||||||
|
validateDistributionUrl=true
|
||||||
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
zipStorePath=wrapper/dists
|
@ -1,16 +1,13 @@
|
|||||||
package fr.doap.jdb;
|
package fr.doap.jdb;
|
||||||
|
|
||||||
|
import fr.doap.jdb.utils.*;
|
||||||
import fr.doap.slog.*;
|
import fr.doap.slog.*;
|
||||||
|
|
||||||
import javax.sql.rowset.serial.*;
|
|
||||||
import javax.swing.plaf.*;
|
|
||||||
import java.lang.reflect.*;
|
import java.lang.reflect.*;
|
||||||
import java.sql.*;
|
import java.sql.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
|
|
||||||
import static fr.doap.jdb.Utils.*;
|
|
||||||
|
|
||||||
public class JDB {
|
public class JDB {
|
||||||
/* public static */
|
/* public static */
|
||||||
static public void init(String aConn, String aUser, String aPass) {
|
static public void init(String aConn, String aUser, String aPass) {
|
||||||
@ -32,12 +29,16 @@ public class JDB {
|
|||||||
|
|
||||||
Optional<Map<String, Object>> lOpt = mDBWrap.query("SELECT MAX("+DBWrap.sJID+")+1 AS NEXTID FROM OBJECTS").findFirst();
|
Optional<Map<String, Object>> lOpt = mDBWrap.query("SELECT MAX("+DBWrap.sJID+")+1 AS NEXTID FROM OBJECTS").findFirst();
|
||||||
Object lNID = lOpt.get().get("NEXTID");
|
Object lNID = lOpt.get().get("NEXTID");
|
||||||
if (lNID != null) mNextID = (int)lNID;
|
if (lNID != null) mDBWOC.setNextID((int)lNID);
|
||||||
else mNextID = 1;
|
else mDBWOC.setNextID(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void _save(Object aObject) {
|
protected void _save(Object aObject) {
|
||||||
new ObjectMapBuilder(aObject);
|
Objects2Maps lO2M = new Objects2Maps(mDBWOC);
|
||||||
|
lO2M.add(aObject);
|
||||||
|
mSQLTypes.putAll(lO2M.getColumnSQLTypes());
|
||||||
|
lO2M.getInserts().values().forEach(aProps -> mDBWrap.insert(aProps));
|
||||||
|
lO2M.getUpdates().values().forEach(aProps -> mDBWrap.update(aProps));
|
||||||
}
|
}
|
||||||
|
|
||||||
// aConds = String: le SQL et ensuite les paramètres
|
// aConds = String: le SQL et ensuite les paramètres
|
||||||
@ -63,7 +64,7 @@ public class JDB {
|
|||||||
mRS.next();
|
mRS.next();
|
||||||
int lID = mRS.getInt(mDBWrap.sJID);
|
int lID = mRS.getInt(mDBWrap.sJID);
|
||||||
L.i("ID: {}", lID);
|
L.i("ID: {}", lID);
|
||||||
Object lCached = mWeakObjectCache.getObject(lID);
|
Object lCached = mDBWOC.getObject(lID);
|
||||||
if (lCached != null) return (T)lCached;
|
if (lCached != null) return (T)lCached;
|
||||||
L.i("NOT CACHED ! Loading...");
|
L.i("NOT CACHED ! Loading...");
|
||||||
|
|
||||||
@ -85,7 +86,7 @@ L.i("Props: {}", lMap);
|
|||||||
byte[] lBA = mRS.getBytes("_SUBS_");
|
byte[] lBA = mRS.getBytes("_SUBS_");
|
||||||
if (lBA != null) {
|
if (lBA != null) {
|
||||||
int[] lIDs = (int[]) Utils.fromByteArray(lBA);
|
int[] lIDs = (int[]) Utils.fromByteArray(lBA);
|
||||||
for (int i=0; i<lIDs.length; i++) if (mWeakObjectCache.getObject(lIDs[i]) == null) lLoadList.add(lIDs[i]);
|
for (int i=0; i<lIDs.length; i++) if (mDBWOC.getObject(lIDs[i]) == null) lLoadList.add(lIDs[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultSet lLoadRS = mDBWrap._query("SELECT * FROM OBJECTS WHERE \""+DBWrap.sJID+"\" IN ("+String.join(",", lLoadList.stream().map(aID -> aID.toString()).toList())+")").get();
|
ResultSet lLoadRS = mDBWrap._query("SELECT * FROM OBJECTS WHERE \""+DBWrap.sJID+"\" IN ("+String.join(",", lLoadList.stream().map(aID -> aID.toString()).toList())+")").get();
|
||||||
@ -103,10 +104,10 @@ L.i(" --> Props: {}", lMap);
|
|||||||
|
|
||||||
Class<?> lClass = Class.forName(lLoadRS.getString("_CLASS_"));
|
Class<?> lClass = Class.forName(lLoadRS.getString("_CLASS_"));
|
||||||
Object lO = lClass.getDeclaredConstructor().newInstance();
|
Object lO = lClass.getDeclaredConstructor().newInstance();
|
||||||
mWeakObjectCache.put(lSID, lO);
|
mDBWOC.put(lSID, lO);
|
||||||
}
|
}
|
||||||
lProps.forEach((aID, aProps) -> {
|
lProps.forEach((aID, aProps) -> {
|
||||||
Object lO = mWeakObjectCache.getId(aID);
|
Object lO = mDBWOC.getId(aID);
|
||||||
if ((lO instanceof Collection)&&(lO.getClass().getCanonicalName().startsWith("java."))) {
|
if ((lO instanceof Collection)&&(lO.getClass().getCanonicalName().startsWith("java."))) {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -122,7 +123,7 @@ L.i(" --> Props: {}", lMap);
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return (T)mWeakObjectCache.getObject(lID);
|
return (T) mDBWOC.getObject(lID);
|
||||||
} catch (Exception aE) { L.w(aE); }
|
} catch (Exception aE) { L.w(aE); }
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -142,146 +143,7 @@ L.i(" --> Props: {}", lMap);
|
|||||||
return mDBWrap._query(lSQL, lParams);
|
return mDBWrap._query(lSQL, lParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
static final Map<Class<?>, String> sTypeMap = Utils.HashMapOf(
|
|
||||||
Boolean.class, "BOOLEAN",
|
|
||||||
Integer.class, "INTEGER",
|
|
||||||
Long.class, "BIGINT",
|
|
||||||
byte[].class, "VARBINARY",
|
|
||||||
Blob.class, "BLOB",
|
|
||||||
String.class, "VARCHAR");
|
|
||||||
|
|
||||||
class ObjectMapBuilder {
|
|
||||||
ObjectMapBuilder(Object aObject) {
|
|
||||||
Map<Object, Set<Object>> lReach=new HashMap<>();
|
|
||||||
Map<Object, Map<String, Object>> lInserts=new HashMap<>();
|
|
||||||
Map<Object, Map<String, Object>> lUpdates=new HashMap<>();
|
|
||||||
|
|
||||||
add(aObject);
|
|
||||||
|
|
||||||
while (mPos < mProcessingList.size()) {
|
|
||||||
Object lO = mProcessingList.get(mPos);
|
|
||||||
try {
|
|
||||||
Constructor lCons = lO.getClass().getDeclaredConstructor(); // ensure at least a default constructor...
|
|
||||||
} catch (Exception aE) {
|
|
||||||
throw new RuntimeException("No constructor for class "+lO.getClass().getCanonicalName());
|
|
||||||
}
|
|
||||||
|
|
||||||
Set<Object> lObjects = new HashSet<>();
|
|
||||||
lReach.put(lO, lObjects);
|
|
||||||
|
|
||||||
Map<String, Object> lProps = getProperties(lO);
|
|
||||||
for (Map.Entry<String, Object> iME: lProps.entrySet()) {
|
|
||||||
Object lV = iME.getValue();
|
|
||||||
if (!sTypeMap.containsKey(lV.getClass())) {
|
|
||||||
add(lV);
|
|
||||||
iME.setValue(mWeakObjectCache.getId(lV));
|
|
||||||
mSQLTypes.put(iME.getKey(), "INTEGER");
|
|
||||||
lObjects.add(lV);
|
|
||||||
} else mSQLTypes.put(iME.getKey(), sTypeMap.get(lV.getClass()));
|
|
||||||
}
|
|
||||||
|
|
||||||
lProps.put(DBWrap.sJID, mWeakObjectCache.getId(lO));
|
|
||||||
lProps.put("_CLASS_", lO.getClass().getCanonicalName());
|
|
||||||
|
|
||||||
if (mInserts.contains(lO)) lInserts.put(lO, lProps);
|
|
||||||
else lUpdates.put(lO, lProps);
|
|
||||||
|
|
||||||
mPos++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// saturate
|
|
||||||
Set<Object> lReachComplete = new HashSet<>();
|
|
||||||
lReachComplete.add(this);
|
|
||||||
while (!lReachComplete.isEmpty()) {
|
|
||||||
lReachComplete.clear();
|
|
||||||
lReach.values().forEach(aSet -> {
|
|
||||||
Set<Object> lNew = new HashSet<>(aSet);
|
|
||||||
aSet.forEach(aE -> {
|
|
||||||
if (lNew.addAll(lReach.get(aE))) lReachComplete.add(aE);
|
|
||||||
});
|
|
||||||
aSet.clear();
|
|
||||||
aSet.addAll(lNew);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
lReach.forEach((aO, aSet) -> {
|
|
||||||
if (aSet.size() > 0) {
|
|
||||||
Object[] lObs = aSet.toArray();
|
|
||||||
int lNew[] = new int[lObs.length];
|
|
||||||
for (int i = 0; i < lNew.length; i++) lNew[i] = mWeakObjectCache.getId(lObs[i]);
|
|
||||||
L.i("Reach {} -> {}", aSet, lNew);
|
|
||||||
if (lInserts.containsKey(aO)) lInserts.get(aO).put("_SUBS_", Utils.toByteArray(lNew));
|
|
||||||
else lUpdates.get(aO).put("_SUBS_", Utils.toByteArray(lNew));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
L.i("Reach: {}", lReach);
|
|
||||||
lInserts.values().forEach(aProps -> mDBWrap.insert(aProps));
|
|
||||||
lUpdates.values().forEach(aProps -> mDBWrap.update(aProps));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void add(Object aObject) {
|
|
||||||
if (!mProcessingList.contains(aObject)) {
|
|
||||||
mProcessingList.add(aObject);
|
|
||||||
if (mWeakObjectCache.getId(aObject) == -1) {
|
|
||||||
mWeakObjectCache.put(mNextID, aObject);
|
|
||||||
mNextID++;
|
|
||||||
mInserts.add(aObject);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Map<String, Object> getProperties(Object aObject) {
|
|
||||||
Map<String, Object> lProps = new HashMap<>();
|
|
||||||
boolean isCollection = aObject instanceof Collection;
|
|
||||||
Class<?> lC = aObject.getClass();
|
|
||||||
while (lC != Object.class) {
|
|
||||||
lProps.put(getShortClassname(lC), true);
|
|
||||||
if (isCollection && lC.getCanonicalName().startsWith("java.")) {
|
|
||||||
Collection lColl = (Collection) aObject;
|
|
||||||
Object[] lObjects = new Object[2*lColl.size()];
|
|
||||||
Iterator iIt = lColl.iterator();
|
|
||||||
for (int i=0; i<lColl.size(); i++) {
|
|
||||||
Object lV = iIt.next();
|
|
||||||
if (!sTypeMap.containsKey(lV.getClass())) {
|
|
||||||
add(lV);
|
|
||||||
lObjects[2*i] = null;
|
|
||||||
lObjects[2*i+1] = mWeakObjectCache.getId(lV);
|
|
||||||
} else {
|
|
||||||
lObjects[2*i] = lV.getClass().getCanonicalName();
|
|
||||||
lObjects[2*i+1] = lV;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
L.i("Coded collection is {}", Arrays.asList(lObjects));
|
|
||||||
lProps.put("_CONTENT_", Utils.toByteArray(lObjects));
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
Field[] lFields = lC.getDeclaredFields();
|
|
||||||
for (Field iF : lFields) {
|
|
||||||
int lModif = iF.getModifiers();
|
|
||||||
if (((lModif & Modifier.FINAL) | (lModif & Modifier.TRANSIENT) | (lModif & Modifier.VOLATILE)) == 0) {
|
|
||||||
if (iF.trySetAccessible()) {
|
|
||||||
try {
|
|
||||||
lProps.put(getShortClassname(lC) + "#" + iF.getName(), iF.get(aObject));
|
|
||||||
} catch (Exception aE) {
|
|
||||||
L.t(aE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lC = lC.getSuperclass();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return lProps;
|
|
||||||
}
|
|
||||||
|
|
||||||
int mPos = 0;
|
|
||||||
List<Object> mProcessingList = new ArrayList<>();
|
|
||||||
Set<Object> mInserts = new HashSet<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected DBWrap mDBWrap;
|
protected DBWrap mDBWrap;
|
||||||
protected WeakObjectCache mWeakObjectCache = new WeakObjectCache();
|
protected DBWOC mDBWOC = new DBWOC();
|
||||||
protected int mNextID;
|
|
||||||
protected Map<String, String> mSQLTypes = new HashMap<>();
|
protected Map<String, String> mSQLTypes = new HashMap<>();
|
||||||
}
|
}
|
152
src/main/java/fr/doap/jdb/Objects2Maps.java
Normal file
152
src/main/java/fr/doap/jdb/Objects2Maps.java
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
package fr.doap.jdb;
|
||||||
|
|
||||||
|
import fr.doap.jdb.impl.*;
|
||||||
|
import fr.doap.jdb.utils.*;
|
||||||
|
import fr.doap.slog.*;
|
||||||
|
|
||||||
|
import java.lang.reflect.*;
|
||||||
|
import java.sql.*;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import static fr.doap.jdb.utils.Utils.*;
|
||||||
|
|
||||||
|
public class Objects2Maps extends ObjectVisitor {
|
||||||
|
|
||||||
|
public Objects2Maps(DBWOC aWOC) { mDBWOC =aWOC; }
|
||||||
|
|
||||||
|
public Map<Object, Map<String, Object>> getInserts() { return mInserts; }
|
||||||
|
public Map<Object, Map<String, Object>> getUpdates() { return mUpdates; }
|
||||||
|
public Map<String, String> getColumnSQLTypes() { return mColumnSQLType; }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onObjectAdded(Object aObject, int aPos) {
|
||||||
|
if (mDBWOC.getId(aObject) == -1) {
|
||||||
|
mDBWOC.addNew(aObject);
|
||||||
|
mNewObjects.add(aObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onProcessingObject(Object aObject, int aPos) {
|
||||||
|
Class<?> lClass = aObject.getClass();
|
||||||
|
try {
|
||||||
|
Constructor lCons = lClass.getDeclaredConstructor(); // ensure at least a default constructor...
|
||||||
|
} catch (Exception aE) {
|
||||||
|
throw new RuntimeException("No constructor for class "+lClass.getCanonicalName());
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<Object> lReachableObjects = new HashSet<>();
|
||||||
|
mReach.put(aObject, lReachableObjects);
|
||||||
|
|
||||||
|
Map<String, Object> lProps = getProperties(aObject);
|
||||||
|
|
||||||
|
for (Map.Entry<String, Object> iME: lProps.entrySet()) {
|
||||||
|
Object lV = iME.getValue();
|
||||||
|
if (!sTypeMap.containsKey(lV.getClass())) {
|
||||||
|
add(lV); // process object if necessary
|
||||||
|
iME.setValue(mDBWOC.getId(lV)); // replace object by ID
|
||||||
|
mColumnSQLType.put(iME.getKey(), "INTEGER"); // column type
|
||||||
|
lReachableObjects.add(lV); // add object to reachable list
|
||||||
|
} else mColumnSQLType.put(iME.getKey(), sTypeMap.get(lV.getClass()));
|
||||||
|
}
|
||||||
|
|
||||||
|
lProps.put(DBWrap.sJID, mDBWOC.getId(aObject));
|
||||||
|
lProps.put("_CLASS_", lClass.getCanonicalName());
|
||||||
|
|
||||||
|
if (mNewObjects.contains(aObject)) mInserts.put(aObject, lProps);
|
||||||
|
else mUpdates.put(aObject, lProps);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onEndingRun(int aStart, int aPos) {
|
||||||
|
// saturate
|
||||||
|
Set<Object> lReachChanged = new HashSet<>(mReach.keySet());
|
||||||
|
while (lReachChanged.size() > 0) {
|
||||||
|
Set<Object> lNewReachChanged = new HashSet<>();
|
||||||
|
for (Object iKey : lReachChanged) {
|
||||||
|
Set<Object> lSet = mReach.get(iKey);
|
||||||
|
boolean lSetUpdated = false;
|
||||||
|
Set<Object> lNew = new HashSet<>(lSet);
|
||||||
|
for (Object iO : lSet) if (lNew.addAll(mReach.get(iO))) lSetUpdated = true;
|
||||||
|
if (lSetUpdated) {
|
||||||
|
lSet.clear();
|
||||||
|
lSet.addAll(lNew);
|
||||||
|
lNewReachChanged.add(iKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lReachChanged = lNewReachChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
mReach.forEach((aO, aSet) -> {
|
||||||
|
if (aSet.size() > 0) {
|
||||||
|
Object[] lObs = aSet.toArray();
|
||||||
|
int lNew[] = new int[lObs.length];
|
||||||
|
for (int i = 0; i < lNew.length; i++) lNew[i] = mDBWOC.getId(lObs[i]);
|
||||||
|
L.i("Reach {} -> {}", aSet, lNew);
|
||||||
|
if (mInserts.containsKey(aO)) mInserts.get(aO).put("_SUBS_", Utils.toByteArray(lNew));
|
||||||
|
else mUpdates.get(aO).put("_SUBS_", Utils.toByteArray(lNew));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
L.i("Reach: {}", mReach);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Map<String, Object> getProperties(Object aObject) {
|
||||||
|
Map<String, Object> lProps = new HashMap<>();
|
||||||
|
Class<?> lC = aObject.getClass();
|
||||||
|
while (lC != Object.class) {
|
||||||
|
lProps.put(getShortClassname(lC), true);
|
||||||
|
if (aObject instanceof Collection && lC.getCanonicalName().startsWith("java.")) {
|
||||||
|
Collection lColl = (Collection) aObject;
|
||||||
|
Object[] lObjects = new Object[2*lColl.size()];
|
||||||
|
Iterator iIt = lColl.iterator();
|
||||||
|
for (int i=0; i<lColl.size(); i++) {
|
||||||
|
Object lV = iIt.next();
|
||||||
|
if (!sTypeMap.containsKey(lV.getClass())) {
|
||||||
|
add(lV);
|
||||||
|
lObjects[2*i] = null;
|
||||||
|
lObjects[2*i+1] = mDBWOC.getId(lV);
|
||||||
|
} else {
|
||||||
|
lObjects[2*i] = lV.getClass().getCanonicalName();
|
||||||
|
lObjects[2*i+1] = lV;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
L.i("Coded collection is {}", Arrays.asList(lObjects));
|
||||||
|
lProps.put("_CONTENT_", Utils.toByteArray(lObjects));
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
Field[] lFields = lC.getDeclaredFields();
|
||||||
|
for (Field iF : lFields) {
|
||||||
|
int lModif = iF.getModifiers();
|
||||||
|
if (((lModif & Modifier.FINAL) | (lModif & Modifier.TRANSIENT) | (lModif & Modifier.VOLATILE)) == 0) {
|
||||||
|
if (iF.trySetAccessible()) {
|
||||||
|
try {
|
||||||
|
lProps.put(getShortClassname(lC) + "#" + iF.getName(), iF.get(aObject));
|
||||||
|
} catch (Exception aE) {
|
||||||
|
L.t(aE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lC = lC.getSuperclass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return lProps;
|
||||||
|
}
|
||||||
|
|
||||||
|
DBWOC mDBWOC;
|
||||||
|
|
||||||
|
Set<Object> mNewObjects = new HashSet<>();
|
||||||
|
Map<Object, Set<Object>> mReach =new HashMap<>();
|
||||||
|
Map<Object, Map<String, Object>> mInserts =new HashMap<>();
|
||||||
|
Map<Object, Map<String, Object>> mUpdates =new HashMap<>();
|
||||||
|
Map<String, String> mColumnSQLType =new HashMap<>();
|
||||||
|
|
||||||
|
static final Map<Class<?>, String> sTypeMap = Utils.HashMapOf(
|
||||||
|
Boolean.class, "BOOLEAN",
|
||||||
|
Integer.class, "INTEGER",
|
||||||
|
Long.class, "BIGINT",
|
||||||
|
byte[].class, "VARBINARY",
|
||||||
|
Blob.class, "BLOB",
|
||||||
|
String.class, "VARCHAR" );
|
||||||
|
}
|
@ -1,5 +0,0 @@
|
|||||||
package fr.doap.jdb;
|
|
||||||
|
|
||||||
public class TestSupport {
|
|
||||||
|
|
||||||
}
|
|
@ -8,31 +8,39 @@ import java.util.*;
|
|||||||
abstract
|
abstract
|
||||||
public class ClassAnalyzer {
|
public class ClassAnalyzer {
|
||||||
|
|
||||||
abstract public Map<String, PropGetterSetter> analyze(Class<?> aClass);
|
|
||||||
|
|
||||||
public boolean isApplicable(Class<?> aClass) { return true; }
|
public boolean isApplicable(Class<?> aClass) { return true; }
|
||||||
|
public boolean processSuperclass(Class<?> aClass) { return true; }
|
||||||
|
|
||||||
|
abstract public void analyze(Class<?> aClass, Map<String, PropGetterSetter> aMap);
|
||||||
|
|
||||||
|
|
||||||
static public class FieldCA extends ClassAnalyzer {
|
static public class FieldCA extends ClassAnalyzer {
|
||||||
@Override
|
@Override
|
||||||
public Map<String, PropGetterSetter> analyze(Class<?> aClass) {
|
public void analyze(Class<?> aClass, Map<String, PropGetterSetter> aMap) {
|
||||||
Map<String, PropGetterSetter> lMap = new HashMap<>();
|
|
||||||
try {
|
try {
|
||||||
Field[] lFields = aClass.getDeclaredFields();
|
Field[] lFields = aClass.getDeclaredFields();
|
||||||
for (Field iF: lFields) lMap.put(iF.getName(),new PropGetterSetter.FieldGS(iF));
|
for (Field iF: lFields) {
|
||||||
|
if (iF.trySetAccessible()) {
|
||||||
|
PropGetterSetter lPGS = new PropGetterSetter.FieldGS(iF);
|
||||||
|
if (lPGS != null) aMap.put(iF.getName(), lPGS);
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (Exception aE) { L.t(aE); }
|
} catch (Exception aE) { L.t(aE); }
|
||||||
return lMap;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static public class CollectionCA extends ClassAnalyzer {
|
static public class CollectionCA extends ClassAnalyzer {
|
||||||
@Override
|
|
||||||
public Map<String, PropGetterSetter> analyze(Class<?> aClass) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isApplicable(Class<?> aClass) {
|
public boolean isApplicable(Class<?> aClass) {
|
||||||
return Collection.class.isAssignableFrom(aClass);
|
return (Collection.class.isAssignableFrom(aClass) && aClass.getCanonicalName().startsWith("java."));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean processSuperclass(Class<?> aClass) { return false; }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void analyze(Class<?> aClass, Map<String, PropGetterSetter> aMap) {
|
||||||
|
aMap.put("_CONTENT_", new PropGetterSetter.CollectionGS());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,21 +9,19 @@ public class ClassInfos {
|
|||||||
static public Map<String, Object> getProps(Object aObject) {
|
static public Map<String, Object> getProps(Object aObject) {
|
||||||
Map<String, Object> lMap = new HashMap<>();
|
Map<String, Object> lMap = new HashMap<>();
|
||||||
ClassInfos lCI = get(aObject.getClass());
|
ClassInfos lCI = get(aObject.getClass());
|
||||||
if (lCI != null) {
|
if (lCI != null) lCI.mPropsGetterSetter.forEach((aKey, aGS) -> lMap.put(aKey, aGS.get(aObject)));
|
||||||
lCI.mPropsGetterSetter.forEach((aKey, aGS) -> {
|
|
||||||
lMap.put(aKey, aGS.get(aObject))
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return lMap;
|
return lMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static public void setProps(Map<String, Object> aMap, Object aObject) {
|
||||||
|
ClassInfos lCI = get(aObject.getClass());
|
||||||
|
if (lCI != null) lCI.mPropsGetterSetter.forEach((aKey, aGS) -> aGS.set(aObject, aMap.get(aKey)));
|
||||||
|
}
|
||||||
|
|
||||||
static public ClassInfos get(Class<?> aClass) {
|
static public ClassInfos get(Class<?> aClass) {
|
||||||
if ((aClass != null)&&(aClass != Object.class)) {
|
if ((aClass != null)&&(aClass != Object.class)) {
|
||||||
ClassInfos lCI = sInfosMap.get(aClass);
|
ClassInfos lCI = sInfosMap.get(aClass);
|
||||||
if (lCI == null) {
|
if (lCI == null) lCI = new ClassInfos(aClass);
|
||||||
lCI = new ClassInfos(aClass);
|
|
||||||
sInfosMap.put(aClass, lCI);
|
|
||||||
}
|
|
||||||
return lCI;
|
return lCI;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@ -32,24 +30,30 @@ public class ClassInfos {
|
|||||||
ClassInfos(Class<?> aClass) {
|
ClassInfos(Class<?> aClass) {
|
||||||
try {
|
try {
|
||||||
sInfosMap.put(aClass, this);
|
sInfosMap.put(aClass, this);
|
||||||
Class<?> lSuper = aClass.getSuperclass();
|
ClassAnalyzer lCA = null;
|
||||||
if (lSuper != Object.class) {
|
|
||||||
ClassInfos lCI = get(lSuper);
|
|
||||||
mPropsGetterSetter.putAll(lCI.mPropsGetterSetter);
|
|
||||||
}
|
|
||||||
for (ClassAnalyzer iCA: sClassAnalyzers) {
|
for (ClassAnalyzer iCA: sClassAnalyzers) {
|
||||||
if (iCA.isApplicable(aClass)) {
|
if (iCA.isApplicable(aClass)) {
|
||||||
mPropsGetterSetter.putAll(iCA.analyze(aClass));
|
lCA = iCA;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (lCA != null) {
|
||||||
|
if (lCA.processSuperclass(aClass)) {
|
||||||
|
Class<?> lSuper = aClass.getSuperclass();
|
||||||
|
if ((lSuper != null)&&(lSuper != Object.class)) {
|
||||||
|
ClassInfos lCI = get(lSuper);
|
||||||
|
mPropsGetterSetter.putAll(lCI.mPropsGetterSetter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lCA.analyze(aClass, mPropsGetterSetter);
|
||||||
|
}
|
||||||
} catch (Exception aE) { L.t(aE); }
|
} catch (Exception aE) { L.t(aE); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Map<String, PropGetterSetter> getGS() { return mPropsGetterSetter; }
|
||||||
|
|
||||||
|
private Map<String, PropGetterSetter> mPropsGetterSetter = new HashMap<>();
|
||||||
|
|
||||||
private Map<String, PropGetterSetter> mPropsGetterSetter = new HashMap<>();
|
static Map<Class<?>, ClassInfos> sInfosMap = new HashMap<>();
|
||||||
|
static List<ClassAnalyzer> sClassAnalyzers = new ArrayList<>(List.of(new ClassAnalyzer.CollectionCA(), new ClassAnalyzer.FieldCA()));
|
||||||
static Map<Class<?>, ClassInfos> sInfosMap = new HashMap<>();
|
|
||||||
static List<ClassAnalyzer> sClassAnalyzers = new ArrayList<>(List.of(new ClassAnalyzer.Collection(), new ClassAnalyzer.Field()));
|
|
||||||
}
|
}
|
||||||
|
@ -1,25 +1,46 @@
|
|||||||
package fr.doap.jdb.impl;
|
package fr.doap.jdb.impl;
|
||||||
|
|
||||||
|
import fr.doap.jdb.utils.*;
|
||||||
import fr.doap.slog.*;
|
import fr.doap.slog.*;
|
||||||
|
|
||||||
import java.lang.reflect.*;
|
import java.lang.reflect.*;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
interface PropGetterSetter {
|
abstract
|
||||||
|
public class PropGetterSetter {
|
||||||
|
|
||||||
Class<?> getType();
|
abstract public Class<?> getType();
|
||||||
|
|
||||||
Object get(Object aObject);
|
abstract public Object get(Object aObject);
|
||||||
void set(Object aObject, Object aValue);
|
|
||||||
|
|
||||||
|
abstract public void set(Object aObject, Object aValue);
|
||||||
|
|
||||||
static public class FieldGS implements PropGetterSetter {
|
static public class FieldGS extends PropGetterSetter {
|
||||||
FieldGS(Field aF) { mField=aF; }
|
|
||||||
|
public FieldGS(Field aF) { mField=aF; }
|
||||||
|
|
||||||
public Class<?> getType() { return mField.getType(); }
|
public Class<?> getType() { return mField.getType(); }
|
||||||
|
|
||||||
public Object get(Object aObject) { try { return mField.get(aObject); } catch (Exception aE) { L.t(aE); } return null; }
|
public Object get(Object aObject) { try { return mField.get(aObject); } catch (Exception aE) { L.t(aE); } return null; }
|
||||||
|
|
||||||
public void set(Object aObject, Object aValue) { try { mField.set(aObject, aValue); } catch (Exception aE) { L.t(aE); }}
|
public void set(Object aObject, Object aValue) { try { mField.set(aObject, aValue); } catch (Exception aE) { L.t(aE); }}
|
||||||
|
|
||||||
Field mField;
|
Field mField;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
static public class CollectionGS extends PropGetterSetter {
|
||||||
|
|
||||||
|
public Class<?> getType() { return byte[].class; }
|
||||||
|
|
||||||
|
public Object get(Object aObject) {
|
||||||
|
Iterator<Object> lIt = ((Collection<Object>)aObject).iterator();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void set(Object aObject, Object aValue) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package fr.doap.jdb;
|
package fr.doap.jdb.tests;
|
||||||
|
|
||||||
public class TestC {
|
public class TestC {
|
||||||
int mInt = 3;
|
int mInt = 3;
|
@ -1,4 +1,4 @@
|
|||||||
package fr.doap.jdb;
|
package fr.doap.jdb.tests;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package fr.doap.jdb;
|
package fr.doap.jdb.tests;
|
||||||
|
|
||||||
public class TestD {
|
public class TestD {
|
||||||
String mS = "mon test D";
|
String mS = "mon test D";
|
24
src/main/java/fr/doap/jdb/utils/DBWOC.java
Normal file
24
src/main/java/fr/doap/jdb/utils/DBWOC.java
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
package fr.doap.jdb.utils;
|
||||||
|
|
||||||
|
public class DBWOC extends WeakObjectCache {
|
||||||
|
|
||||||
|
public DBWOC setNextID(int aNextID) {
|
||||||
|
mNextID =aNextID;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int nextID() { return mNextID; }
|
||||||
|
|
||||||
|
public int addNew(Object aObject) {
|
||||||
|
int lID = getId(aObject);
|
||||||
|
if (lID == -1) {
|
||||||
|
lID = mNextID;
|
||||||
|
put(lID, aObject);
|
||||||
|
mNextID++;
|
||||||
|
}
|
||||||
|
return lID;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected int mNextID;
|
||||||
|
}
|
79
src/main/java/fr/doap/jdb/utils/ObjectVisitor.java
Normal file
79
src/main/java/fr/doap/jdb/utils/ObjectVisitor.java
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
package fr.doap.jdb.utils;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.function.*;
|
||||||
|
|
||||||
|
public class ObjectVisitor {
|
||||||
|
|
||||||
|
protected boolean onCheckObjectBeforeAdding(Object aObject, int aPos) { return true; }
|
||||||
|
protected void onObjectAdded(Object aObject, int aPos) {}
|
||||||
|
|
||||||
|
protected void onStartingRun(int aPos) {}
|
||||||
|
protected void onProcessingObject(Object aObject, int aPos) {}
|
||||||
|
protected void onEndingRun(int aStart, int aPos) {}
|
||||||
|
|
||||||
|
public void add(Consumer<Object> aCallback, Object ... aObjects) {
|
||||||
|
boolean lNeedRun = false;
|
||||||
|
if (aObjects != null) {
|
||||||
|
for (Object iO : aObjects) {
|
||||||
|
if (iO != null) {
|
||||||
|
if (!mProcessingList.contains(iO)) {
|
||||||
|
if (onCheckObjectBeforeAdding(iO, mProcessingList.size())) {
|
||||||
|
lNeedRun = true;
|
||||||
|
mProcessingList.add(iO);
|
||||||
|
onObjectAdded(iO, mProcessingList.size()-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Set<Consumer<Object>> lCallbacks = mPostProcessCallback.get(iO);
|
||||||
|
if (lCallbacks == null) {
|
||||||
|
lCallbacks = new HashSet<>();
|
||||||
|
mPostProcessCallback.put(iO, lCallbacks);
|
||||||
|
}
|
||||||
|
lCallbacks.add(aCallback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (lNeedRun) run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(Object ... aObjects) {
|
||||||
|
boolean lNeedRun = false;
|
||||||
|
if (aObjects != null) {
|
||||||
|
for (Object iO : aObjects) {
|
||||||
|
if (iO != null) {
|
||||||
|
if (!mProcessingList.contains(iO)) {
|
||||||
|
if (onCheckObjectBeforeAdding(iO, mProcessingList.size())) {
|
||||||
|
lNeedRun = true;
|
||||||
|
mProcessingList.add(iO);
|
||||||
|
onObjectAdded(iO, mProcessingList.size()-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (lNeedRun && !mRunning) run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void run() {
|
||||||
|
mRunning = true;
|
||||||
|
int lStartPos = mPos;
|
||||||
|
onStartingRun(mPos);
|
||||||
|
while (mPos < mProcessingList.size()) {
|
||||||
|
Object lO = mProcessingList.get(mPos);
|
||||||
|
onProcessingObject(lO, mPos);
|
||||||
|
mPos++;
|
||||||
|
}
|
||||||
|
for (int iP=mPos-1; iP>=lStartPos; iP--) {
|
||||||
|
Object lO = mProcessingList.get(iP);
|
||||||
|
Set<Consumer<Object>> lCallbacks = mPostProcessCallback.get(lO);
|
||||||
|
if (lCallbacks != null) lCallbacks.forEach(aCallback -> aCallback.accept(lO));
|
||||||
|
}
|
||||||
|
onEndingRun(lStartPos, mPos);
|
||||||
|
mRunning = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean mRunning = false;
|
||||||
|
protected int mPos = 0;
|
||||||
|
protected List<Object> mProcessingList = new ArrayList<>();
|
||||||
|
protected Map<Object, Set<Consumer<Object>>> mPostProcessCallback = new HashMap<>();
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package fr.doap.jdb;
|
package fr.doap.jdb.utils;
|
||||||
|
|
||||||
import fr.doap.slog.*;
|
import fr.doap.slog.*;
|
||||||
|
|
||||||
@ -22,7 +22,7 @@ public class Utils {
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
static byte[] toByteArray(final Object obj) {
|
static public byte[] toByteArray(final Object obj) {
|
||||||
ByteArrayOutputStream lBAOS = new ByteArrayOutputStream();
|
ByteArrayOutputStream lBAOS = new ByteArrayOutputStream();
|
||||||
try (ObjectOutputStream lOOS = new ObjectOutputStream(lBAOS)) {
|
try (ObjectOutputStream lOOS = new ObjectOutputStream(lBAOS)) {
|
||||||
lOOS.writeObject(obj);
|
lOOS.writeObject(obj);
|
||||||
@ -32,7 +32,7 @@ public class Utils {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Object fromByteArray(byte[] bytes) {
|
static public Object fromByteArray(byte[] bytes) {
|
||||||
ByteArrayInputStream lBAIS = new ByteArrayInputStream(bytes);
|
ByteArrayInputStream lBAIS = new ByteArrayInputStream(bytes);
|
||||||
try (ObjectInput lOI = new ObjectInputStream(lBAIS)) {
|
try (ObjectInput lOI = new ObjectInputStream(lBAIS)) {
|
||||||
return lOI.readObject();
|
return lOI.readObject();
|
@ -1,4 +1,4 @@
|
|||||||
package fr.doap.jdb;
|
package fr.doap.jdb.utils;
|
||||||
|
|
||||||
import java.lang.ref.*;
|
import java.lang.ref.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@ -29,6 +29,6 @@ public class WeakObjectCache {
|
|||||||
mObjectCache.clear();
|
mObjectCache.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<Object, Integer> mIDs = new WeakHashMap<>();
|
Map<Object, Integer> mIDs = new WeakHashMap<>();
|
||||||
Map<Integer, WeakReference<Object>> mObjectCache = new TreeMap<>();
|
Map<Integer, WeakReference<Object>> mObjectCache = new TreeMap<>();
|
||||||
}
|
}
|
27
src/main/java/fr/doap/jdb/utils/proxies/ListProxy.java
Normal file
27
src/main/java/fr/doap/jdb/utils/proxies/ListProxy.java
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
package fr.doap.jdb.utils.proxies;
|
||||||
|
|
||||||
|
import fr.doap.slog.*;
|
||||||
|
|
||||||
|
import java.lang.reflect.*;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class ListProxy implements InvocationHandler {
|
||||||
|
|
||||||
|
static public <T extends List> T getProxy(T aObject) {
|
||||||
|
return (T) Proxy.newProxyInstance(aObject.getClass().getClassLoader(), new Class<?>[]{ List.class }, new ListProxy(aObject));
|
||||||
|
}
|
||||||
|
|
||||||
|
private ListProxy(List aList) { mList=aList; }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||||
|
if (!mLoaded) {
|
||||||
|
mLoaded = true;
|
||||||
|
L.i("Loading list values... DONE !");
|
||||||
|
} else L.t("Values already loaded");
|
||||||
|
return method.invoke(mList, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean mLoaded = false;
|
||||||
|
private List mList;
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
package fr.doap.trash;
|
package fr.doap.trash;
|
||||||
|
|
||||||
import fr.doap.jdb.*;
|
import fr.doap.jdb.utils.*;
|
||||||
import fr.doap.slog.*;
|
import fr.doap.slog.*;
|
||||||
|
|
||||||
import java.sql.*;
|
import java.sql.*;
|
||||||
@ -50,7 +50,7 @@ public class DBWrapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected Connection mConnection;
|
protected Connection mConnection;
|
||||||
protected WeakObjectCache mWeakObjectCache = new WeakObjectCache();
|
protected WeakObjectCache mWeakObjectCache = new WeakObjectCache();
|
||||||
protected ProcessingQueue<SQLAbstractCommand> mSQLQueue;
|
protected ProcessingQueue<SQLAbstractCommand> mSQLQueue;
|
||||||
|
|
||||||
interface SQLAbstractCommand {
|
interface SQLAbstractCommand {
|
||||||
|
@ -8,4 +8,6 @@ module fr.doap.jdb {
|
|||||||
exports fr.doap.jdb;
|
exports fr.doap.jdb;
|
||||||
exports fr.doap.trash;
|
exports fr.doap.trash;
|
||||||
exports fr.doap.jdb.impl;
|
exports fr.doap.jdb.impl;
|
||||||
|
exports fr.doap.jdb.tests;
|
||||||
|
exports fr.doap.jdb.utils;
|
||||||
}
|
}
|
20
src/test/java/fr/doap/jdb/ClassStructTest.java
Normal file
20
src/test/java/fr/doap/jdb/ClassStructTest.java
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
package fr.doap.jdb;
|
||||||
|
|
||||||
|
import fr.doap.jdb.tests.*;
|
||||||
|
import fr.doap.jdb.utils.*;
|
||||||
|
import fr.doap.slog.*;
|
||||||
|
import org.junit.jupiter.api.*;
|
||||||
|
|
||||||
|
@TestMethodOrder(MethodOrderer.MethodName.class)
|
||||||
|
public class ClassStructTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test1() {
|
||||||
|
TestC lTC2 = new TestC2();
|
||||||
|
Objects2Maps lO2M = new Objects2Maps(new DBWOC());
|
||||||
|
lO2M.add(lTC2);
|
||||||
|
L.i("SQL Types: {}", lO2M.getColumnSQLTypes());
|
||||||
|
L.i("Inserts: {}", lO2M.getInserts());
|
||||||
|
L.i("Updates: {}", lO2M.getUpdates());
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
package fr.doap.jdb;
|
package fr.doap.jdb;
|
||||||
|
|
||||||
|
import fr.doap.jdb.tests.*;
|
||||||
import fr.doap.slog.*;
|
import fr.doap.slog.*;
|
||||||
import org.junit.jupiter.api.*;
|
import org.junit.jupiter.api.*;
|
||||||
|
|
||||||
@ -19,7 +20,7 @@ public class JDBTest {
|
|||||||
JDB.save(new TestC());
|
JDB.save(new TestC());
|
||||||
JDB.save(new TestD());
|
JDB.save(new TestD());
|
||||||
|
|
||||||
JDB.sJDB.mWeakObjectCache.clear();
|
JDB.sJDB.mDBWOC.clear();
|
||||||
|
|
||||||
JDB.sJDB.mDBWrap.query("SELECT * FROM OBJECTS").forEach(aMap -> L.i(aMap.toString()));
|
JDB.sJDB.mDBWrap.query("SELECT * FROM OBJECTS").forEach(aMap -> L.i(aMap.toString()));
|
||||||
|
|
||||||
|
22
src/test/java/fr/doap/jdb/ProxyTest.java
Normal file
22
src/test/java/fr/doap/jdb/ProxyTest.java
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
package fr.doap.jdb;
|
||||||
|
|
||||||
|
import fr.doap.jdb.utils.proxies.*;
|
||||||
|
import fr.doap.slog.*;
|
||||||
|
import org.junit.jupiter.api.*;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class ProxyTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test1() {
|
||||||
|
List<String> lS = new ArrayList<>(List.of("test 1", "test 2", "test 3"));
|
||||||
|
List<String> lProx = ListProxy.getProxy(lS);
|
||||||
|
List<String> lProx2 = ListProxy.getProxy(lS);
|
||||||
|
L.i("Original #1: {}", lS.get(1));
|
||||||
|
L.i("Proxy1 empty: {}", lProx.isEmpty());
|
||||||
|
L.i("Proxy1 #1: {}", lProx.get(1));
|
||||||
|
L.i("Proxy2 size: {}", lProx2.size());
|
||||||
|
L.i("Proxy2 #2: {}", lProx2.get(2));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user