diff --git a/.gitignore b/.gitignore index e29a8c5b1..08e2afcd5 100644 --- a/.gitignore +++ b/.gitignore @@ -30,6 +30,8 @@ lib/jaybird-full\.jar lib/jaybird-cryptoapi\.jar +lib/fbclient-3\.jar + lib/fbclient-4\.jar lib/fbclient-5\.jar diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f9388d51f..f651d436e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -11,6 +11,7 @@ stages: - test - repackage - deploy + - report variables: RELEASE_HUB_PROJECT: red_expert @@ -56,8 +57,10 @@ prepare: CONTEXT=commit STAGE=snapshot fi + - BUILD=$(awk -F'=' '/^eq.build=/ {print $2}' ./src/org/executequery/eq.system.properties) - m4 -DVERSION=${VERSION} ci/artifacts.m4 > .ci/artifacts - echo VERSION=${VERSION} > vars.env + - echo BUILD=${BUILD} >> vars.env - echo BRANCH=${BRANCH} >> vars.env - echo CONTEXT=${CONTEXT} >> vars.env - echo STAGE=${STAGE} >> vars.env @@ -85,8 +88,6 @@ sources: paths: - dist-src/ - - build_docs: stage: build_docs artifacts: @@ -97,13 +98,15 @@ build_docs: - docker - builder - x86_64 - image: registry.red-soft.biz:5000/docker-images/texlive-alpine/texlive2018-alpine:20190305 + image: registry.red-soft.biz:5000/docker-images/3rdparty/texlive:TL2022-2023-03-12-full before_script: - - tar xf dist-src/RedExpert-$VERSION-src.tar.gz + - apt update && apt install -y python3-venv python3-pip + - mkdir -p dist/guide script: - - cd RedExpert-$VERSION && ./ci/build_docs.sh && cd .. - - mv RedExpert-$VERSION/dist . - + - cd guide_rst + - make bootstrap + - make latexpdf + - cp build/latex/Red_Expert.pdf ../dist/guide/RedExpert_Guide-ru.pdf .build_template: stage: build @@ -150,6 +153,7 @@ build:linux: - mv modules/redexpert/target/lib "${DIST}" - cp -r license/ "${DIST}" - cp -r "${CI_PROJECT_DIR}"/dist/guide/ "${DIST}" + - mv modules/redexpert/target/classes "${DIST}" - mv modules/redexpert/target/LICENSE.txt "${DIST}" - mv modules/redexpert/target/red_expert.ico "${DIST}" - mv modules/redexpert/target/red_expert.png "${DIST}" @@ -210,6 +214,7 @@ build:windows: expire_in: 1 day paths: - test-results/ + - coverage-results/ except: variables: - $SKIP_TESTS == "1" @@ -221,6 +226,7 @@ test:windows: - proxmox - tester variables: + BUILD: ${BUILD} PROXMOX_TEMPLATE: template-testing-re-windows-7 JAVA_HOME: c:\Program Files\Java\jdk8 ErrorActionPreference: STOP @@ -259,6 +265,7 @@ test:windows-robot: - proxmox - tester variables: + BUILD: ${BUILD} PROXMOX_TEMPLATE: template-testing-re-windows-7 ErrorActionPreference: STOP DIST: ${CI_PROJECT_DIR}\dist\windows-${ARCH} @@ -297,6 +304,7 @@ test:linux-robot: - red_expert - tester variables: + BUILD: ${BUILD} PROXMOX_TEMPLATE: template-testing-re-ubuntu-20 ErrorActionPreference: STOP DIST: ${CI_PROJECT_DIR}/dist/linux-${ARCH} @@ -315,6 +323,10 @@ test:linux-robot: - $PYTHON ./ci/download_dbms.py ${DBMS} ${ARCH} linux - chmod +x ./ci/install_dbms.sh - ./ci/install_dbms.sh + - | + if [ $ARCH == "x86_64" ] && [ $DBMS == "rdb50" ]; then + export COVERAGE=true + fi script: - chmod +x ./ci/test_robot.sh - ./ci/test_robot.sh @@ -366,3 +378,38 @@ deploy: only: variables: - "$RELEASE_HUB_KEY" + +report:coverage: + stage: report + tags: ["docker", "x86_64"] + image: registry.red-soft.biz:5000/docker-images/rdbbuildenv:rdb5-8 + before_script: + - test -e ${CI_PROJECT_DIR}/coverage-results || (echo No coverage data found; exit 0) + script: + - echo "Uploading report" + - mc alias set minio ${MINIO_SERVER} ${MINIO_USER} ${MINIO_PASSWORD} + - | + if [ "${CI_COMMIT_TAG}" ]; then + REPORT_NAME=${VERSION} + elif [ "${CI_COMMIT_REF_NAME}" = "$TAG_BRANCH" ]; then + REPORT_NAME=${TAG_BRANCH} + echo "Generating badge" + PCOV=$(grep -oP '.*?' coverage-results/index.html | grep -oP '\K[^<]+' | head -n 1 | tr -d '%') + anybadge -l "coverage ${TAG_BRANCH}" -v "$PCOV" --suffix='%' -o -f coverage-results/badge.svg 70=red 80=orange 90=yellow 100=green + fi + - | + if [ "${REPORT_NAME}" ]; then + mc rm -r --force minio/reports/coverage/red-expert/${REPORT_NAME} + mc cp -r coverage-results/ minio/reports/coverage/red-expert/${REPORT_NAME} + echo Report ${MINIO_SERVER}reports/coverage/red-expert/${REPORT_NAME}/index.html + else + mc cp -r coverage-results/ minio/reports/temp/coverage/red-expert/${VERSION} + echo Report ${MINIO_SERVER}reports/temp/coverage/red-expert/${VERSION}/index.html + fi + # coverage: /^\s*lines:\s*\d+.\d+\%/ + only: + variables: + - $CI_COMMIT_TAG + - $CONTEXT == "weekly" + - $FORCE_COVERAGE == "1" + allow_failure: true diff --git a/ci/test.ps1 b/ci/test.ps1 index 69c759d98..a0d53c0b5 100644 --- a/ci/test.ps1 +++ b/ci/test.ps1 @@ -21,6 +21,9 @@ $DISTRO=$env:DISTRO if (-Not (Test-Path env:\DBMS)) { die("DBMS not defined") } $DBMS=$env:DBMS +if (-Not (Test-Path env:\BUILD)) { die("BUILD not defined") } +$BUILD=$env:BUILD + echo "Downloading tests" git clone -q http://git.red-soft.biz/red-database/re-tests.git -b new_ui git clone -q http://git.red-soft.biz/red-database/python/lackey.git @@ -31,6 +34,12 @@ start-process "${PYTHON}" "-m pip install git+http://git.red-soft.biz/red-databa start-process "${PYTHON}" "-m pip install -e .\lackey" -wait -nonewwindow start-process "${PYTHON}" "-m pip install -e .\re-tests" -wait -nonewwindow +echo "Set .xml" +$BUILD_PATH="$env:USERPROFILE\.redexpert\${BUILD}" +mkdir "${BUILD_PATH}" +copy ".\re-tests\files\xml\savedconnections.xml" "${BUILD_PATH}" +copy ".\re-tests\files\xml\eq.user.properties" "${BUILD_PATH}" + echo "Start testing" cd re-tests start-process "${PYTHON}" "-m pytest -vv --junitxml .\results.xml .\tests" -wait -nonewwindow diff --git a/ci/test_robot.ps1 b/ci/test_robot.ps1 index 886cc9e67..425b4f5e2 100644 --- a/ci/test_robot.ps1 +++ b/ci/test_robot.ps1 @@ -21,6 +21,9 @@ $DISTRO=$env:DISTRO if (-Not (Test-Path env:\DBMS)) { die("DBMS not defined") } $DBMS=$env:DBMS +if (-Not (Test-Path env:\BUILD)) { die("BUILD not defined") } +$BUILD=$env:BUILD + echo "Downloading tests" git clone -q http://git.red-soft.biz/red-database/re-tests-robot @@ -28,6 +31,11 @@ echo "Installing components" start-process "${PYTHON}" "-m pip install git+http://git.red-soft.biz/red-database/python/red-database-python-driver.git" -wait -nonewwindow start-process "${PYTHON}" "-m pip install robotframework" -wait -nonewwindow +echo "Set .xml" +$BUILD_PATH="$env:USERPROFILE\.redexpert\${BUILD}" +mkdir "${BUILD_PATH}" +copy ".\re-tests-robot\files\xml\savedconnections.xml" "${BUILD_PATH}" + echo "Start testing" cd re-tests-robot start-process "${PYTHON}" "-m robot -x results.xml .\tests" -wait -nonewwindow diff --git a/ci/test_robot.sh b/ci/test_robot.sh index 57909af19..c6de63f45 100644 --- a/ci/test_robot.sh +++ b/ci/test_robot.sh @@ -20,6 +20,7 @@ check_variable WORKSPACE check_variable DISTRO check_variable PYTHON check_variable DBMS +check_variable BUILD echo "Downloading tests" git clone -q http://git.red-soft.biz/red-database/re-tests-robot @@ -28,14 +29,27 @@ echo "Installing components" $PYTHON -m pip install git+http://git.red-soft.biz/red-database/python/red-database-python-driver.git $PYTHON -m pip install robotframework +export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/RedDatabase/lib + export PYTHONPATH=$PYTHONPATH:/root/remoteswinglibrary-2.3.3.jar export DISPLAY=:0 su reduser -c 'xhost +' +echo "Set .xml" +BUILD_PATH="/root/.redexpert/${BUILD}" +mkdir "${BUILD_PATH}" +cp "./re-tests-robot/files/xml/savedconnections.xml" "${BUILD_PATH}" + echo "Start testing" cd re-tests-robot $PYTHON -m robot -x results.xml --nostatusrc ./tests +if [ $COVERAGE == true ]; then + echo "Start generate coverage results" + mkdir "${WORKSPACE}/coverage-results/" + java -jar ./lib/jacococli.jar report ./results/jacoco.exec --classfiles "${DIST}/classes" --sourcefiles ../src --html "${WORKSPACE}/coverage-results/" +fi + echo "Copy test results" mkdir "${WORKSPACE}/test-results/" cp results.xml "${WORKSPACE}/test-results/${DISTRO}-${DBMS}-${ARCH}.xml" diff --git a/guide_rst/Makefile b/guide_rst/Makefile new file mode 100644 index 000000000..6a443b039 --- /dev/null +++ b/guide_rst/Makefile @@ -0,0 +1,38 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= $(VENV)/bin/sphinx-build +SOURCEDIR = source +BUILDDIR = build + +PYTHON ?= python3 +ROOT := $(shell pwd) +VENV ?= $(ROOT)/.venv +PIP ?= $(VENV)/bin/pip + +.DEFAULT_GOAL := all + + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile clean distclean bootstrap + +clean: + - rm -rf $(BUILDDIR) + +distclean: clean + - rm -r $(VENV) + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +bootstrap: + $(PYTHON) -m venv .venv + $(PIP) install -r requirements.txt diff --git a/guide_rst/make.bat b/guide_rst/make.bat new file mode 100644 index 000000000..061f32f91 --- /dev/null +++ b/guide_rst/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=source +set BUILDDIR=build + +if "%1" == "" goto help + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.https://www.sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd diff --git a/guide_rst/requirements.txt b/guide_rst/requirements.txt new file mode 100644 index 000000000..195e34158 --- /dev/null +++ b/guide_rst/requirements.txt @@ -0,0 +1,2 @@ +Sphinx==7.2.6 +sphinx_design \ No newline at end of file diff --git a/guide_rst/source/_ext/HideShowIfCertDirective.py b/guide_rst/source/_ext/HideShowIfCertDirective.py new file mode 100644 index 000000000..9deb239d7 --- /dev/null +++ b/guide_rst/source/_ext/HideShowIfCertDirective.py @@ -0,0 +1,42 @@ +from __future__ import annotations + +__docformat__ = 'reStructuredText' + +import os.path + +from docutils import statemachine +from docutils.parsers.rst import Directive, states + +import globalvar + +class BaseInclude(Directive): + has_content = True + required_arguments = 0 + optional_arguments = 0 + final_argument_whitespace = True + option_spec = {} + + def run(self): + tab_width = self.state.document.settings.tab_width + rawtext = '\n'.join(self.content) + include_lines = statemachine.string2lines(rawtext, tab_width, convert_whitespace=1) + self.state_machine.insert_input(include_lines, '') + return [] + +class HideIfCert(BaseInclude): + def run(self): + if not globalvar.IsCertifiedVersion: + return super().run() + else: + return [] + +class ShowIfCert(BaseInclude): + def run(self): + if globalvar.IsCertifiedVersion: + return super().run() + else: + return [] + +def setup(app): + app.add_directive('hideifcert', HideIfCert) + app.add_directive('showifcert', ShowIfCert) diff --git a/guide_rst/source/_ext/HideShowIfCertRole.py b/guide_rst/source/_ext/HideShowIfCertRole.py new file mode 100644 index 000000000..ea641c874 --- /dev/null +++ b/guide_rst/source/_ext/HideShowIfCertRole.py @@ -0,0 +1,44 @@ +from docutils import nodes +from docutils.parsers.rst.states import Struct +import globalvar + +def Hide_ifcert_role(role, rawtext, text, lineno, inliner, options={}, content=[]): + # Prepare context for nested parsing + memo = Struct(document=inliner.document, + reporter=inliner.reporter, + language=inliner.language) + parent = nodes.inline(rawtext, '', **options) + + if not globalvar.IsCertifiedVersion: + # Parse role text for markup and add to parent + processed, messages = inliner.parse(text, lineno, memo, parent) + parent += processed + else: + parent = nodes.Text('') + messages = [] + + return [parent], messages + +def Show_ifcert_role(role, rawtext, text, lineno, inliner, options={}, content=[]): + # Prepare context for nested parsing + memo = Struct(document=inliner.document, + reporter=inliner.reporter, + language=inliner.language) + parent = nodes.inline(rawtext, '', **options) + + if globalvar.IsCertifiedVersion: + # Parse role text for markup and add to parent + processed, messages = inliner.parse(text, lineno, memo, parent) + parent += processed + else: + parent = nodes.Text('') + messages = [] + + return [parent], messages + + +def setup(app): + app.add_role('hideifcert', Hide_ifcert_role) + app.add_role('showifcert', Show_ifcert_role) + + diff --git a/guide_rst/source/_ext/NewCodeBlockDirective.py b/guide_rst/source/_ext/NewCodeBlockDirective.py new file mode 100644 index 000000000..bf6c7b325 --- /dev/null +++ b/guide_rst/source/_ext/NewCodeBlockDirective.py @@ -0,0 +1,108 @@ +from __future__ import annotations + +import sys + +from docutils import nodes +from docutils.parsers.rst import directives + + +from sphinx import addnodes +from sphinx.directives import optional_int +from sphinx.locale import __ +from sphinx.util import logging, parselinenos +from sphinx.util.docutils import SphinxDirective +import re +import globalvar + + +def remove_ifcert(content): + result = [] + pattern = r':hideifcert:\`(.+?)\`' + for line in content: + if ":hideifcert:" not in line: + result.append(line) + else: + if not globalvar.IsCertifiedVersion: # если версия документации обычная + line = re.sub(pattern, r'\1', line) # то вставляем все строки с :hideifcert: + result.append(line) + else: + line = re.sub(pattern, r'', line) # если версия документации сертифицированная, то пропускаем то, что внутри роли :hideifcert: + if not re.match(r'^\s*$', line): + result.append(line) + return result + +class ReCodeBlock(SphinxDirective): + has_content = True + required_arguments = 0 + optional_arguments = 1 + final_argument_whitespace = False + option_spec: OptionSpec = { + 'force': directives.flag, + 'linenos': directives.flag, + 'lineno-start': int, + 'emphasize-lines': directives.unchanged_required, + 'caption': directives.unchanged_required, + 'class': directives.class_option, + 'name': directives.unchanged, + } + + def run(self) -> list[Node]: + document = self.state.document + self.content = remove_ifcert(self.content) + code = '\n'.join(self.content) + location = self.state_machine.get_source_and_line(self.lineno) + + linespec = self.options.get('emphasize-lines') + if linespec: + try: + nlines = len(self.content) + hl_lines = parselinenos(linespec, nlines) + if any(i >= nlines for i in hl_lines): + logger.warning(__('line number spec is out of range(1-%d): %r') % + (nlines, self.options['emphasize-lines']), + location=location) + + hl_lines = [x + 1 for x in hl_lines if x < nlines] + except ValueError as err: + return [document.reporter.warning(err, line=self.lineno)] + else: + hl_lines = None + + literal: Element = nodes.literal_block(code, code) + if 'linenos' in self.options or 'lineno-start' in self.options: + literal['linenos'] = True + literal['classes'] += self.options.get('class', []) + literal['force'] = 'force' in self.options + if self.arguments: + literal['language'] = self.env.temp_data.get('highlight_language', + self.config.highlight_language) + prefix = '\\redexamplestyle' + arg = self.arguments[0] + if arg.lower()=='redstatement': + prefix = '\\redstatementstyle' + elif arg.lower()=='redlisting': + capt = self.options.get('caption', '') + prefix = '\\redlistingtitlestyle{'+ capt +'} ' +' \\vspace{-27pt} ' + elif arg.lower()=='redbordless': + prefix = '\\redbordlessstyle' + elif arg.lower()=='sql': + literal['language'] = arg + else: + prefix = '\\redexamplestyle' + literal['language'] = self.env.temp_data.get('highlight_language', + self.config.highlight_language) + + extra_args = literal['highlight_args'] = {} + if hl_lines is not None: + extra_args['hl_lines'] = hl_lines + if 'lineno-start' in self.options: + extra_args['linenostart'] = self.options['lineno-start'] + self.set_source_info(literal) + self.add_name(literal) + + latex_prefix = nodes.raw('', prefix, format='latex') + return [latex_prefix, literal] + +def setup(app): + app.add_directive('code-block', ReCodeBlock) + diff --git a/guide_rst/source/_ext/UnindentedListDirective.py b/guide_rst/source/_ext/UnindentedListDirective.py new file mode 100644 index 000000000..78167bd02 --- /dev/null +++ b/guide_rst/source/_ext/UnindentedListDirective.py @@ -0,0 +1,39 @@ +from __future__ import annotations + +from docutils import nodes +from sphinx.locale import __ +from sphinx.util import logging +from sphinx.util.docutils import SphinxDirective +from docutils.parsers.rst import Directive +from docutils.parsers.rst.directives.admonitions import Note + +logger = logging.getLogger(__name__) + + +class UnindentedList(SphinxDirective): + has_content = True + required_arguments = 0 + optional_arguments = 0 + final_argument_whitespace = False + option_spec: OptionSpec = {} + + def run(self) -> list[Node]: + node = nodes.paragraph() + node.document = self.state.document + self.state.nested_parse(self.content, self.content_offset, node) + if len(node.children) != 1 or not isinstance(node.children[0], + nodes.bullet_list): + if not isinstance(node.children[0], nodes.enumerated_list): + logger.warning(__('.. list content is not a list'), + location=(self.env.docname, self.lineno)) + return [] + bullet_list = node.children[0] + prefix = '\\begin{listenv}' + suffix = '\end{listenv}' + latex_prefix = nodes.raw('', prefix, format='latex') + latex_suffix = nodes.raw('', suffix, format='latex') + return [latex_prefix, bullet_list, latex_suffix] + + +def setup(app): + app.add_directive('unindened_list', UnindentedList) diff --git a/guide_rst/source/_ext/globalvar.py b/guide_rst/source/_ext/globalvar.py new file mode 100644 index 000000000..66ac685a1 --- /dev/null +++ b/guide_rst/source/_ext/globalvar.py @@ -0,0 +1 @@ +IsCertifiedVersion = False diff --git a/guide_rst/source/app-options.rst b/guide_rst/source/app-options.rst new file mode 100644 index 000000000..67ed6933a --- /dev/null +++ b/guide_rst/source/app-options.rst @@ -0,0 +1,29 @@ +.. _parameter_description: + +Описание параметров +======================= + +Поля для подключения к базе данных +----------------------------------------- + +Расширенные параметры подключения к базе данных +------------------------------------------------------ + +.. _trace_open: + +Параметры для включения аудита +--------------------------------- + +.. _trace_conf: + +Параметры файла конфигурации трейс менеджера +------------------------------------------------- + +.. _driver: + +Параметры для добавления драйвера +-------------------------------------- + + + + diff --git a/guide_rst/source/app-toolbar.rst b/guide_rst/source/app-toolbar.rst new file mode 100644 index 000000000..ba4871827 --- /dev/null +++ b/guide_rst/source/app-toolbar.rst @@ -0,0 +1,9 @@ +.. _toolbar: + +Панель инструментов +---------------------- + +Далее следует описание каждой панели инструментов и связанных с ней кнопок и действий. + + + diff --git a/guide_rst/source/conf.py b/guide_rst/source/conf.py new file mode 100644 index 000000000..e979c3121 --- /dev/null +++ b/guide_rst/source/conf.py @@ -0,0 +1,187 @@ +# Configuration file for the Sphinx documentation builder. +# +# For the full list of built-in configuration values, see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Project information ----------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information + +latex_use_latex_multicolumn = True + +project = 'Red_Expert' +copyright = '2024, Red Soft' +author = 'Red Soft' + +# General configuration + +import re +import os +import sys +sys.path.append(os.path.abspath("./_ext")) +import globalvar + + +# функция подменяет один список слов на другой в rst файлах +# эта функция вспомогательная, она работает, но выполнить ее достаточно один раз для замены необходимых слов +''' +def replace_words_in_files(words_to_replace, new_words): + rst_files = [file for file in os.listdir() if file.endswith(".rst")] + + for file_name in rst_files: + with open(file_name, 'r') as file: + file_content = file.read() + + # Заменяем слова из списка words_to_replace на соответствующие слова из списка new_words + for i in range(len(words_to_replace)): + file_content = file_content.replace(words_to_replace[i], new_words[i]) + + with open(file_name, 'w') as file: + file.write(file_content) + + +# Список слов для замены +words_to_replace = ["security_version", "rdb_version"] +new_words = ["security5.fdb", "5.0"] + +# Вызываем функцию для замены слов +replace_words_in_files(words_to_replace, new_words) +''' + + +# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration + +extensions = ['NewCodeBlockDirective', 'HideShowIfCertDirective', 'HideShowIfCertRole', 'UnindentedListDirective'] + +#f = open('defs.tex.txt', 'r+'); +#PREAMBLE = f.read(); + +smartquotes = False + +templates_path = ['_templates'] +exclude_patterns = [] + +language = 'ru' + +latex_additional_files = ["defs.sty"] + +latex_engine = 'pdflatex' + +latex_toplevel_sectioning = 'section' + +latex_documents = [ + ('index', 'Red_Expert.tex', u'Ред Эксперт', u'YourName', 'article'), +] + +latex_elements = { +'passoptionstopackages' : r''' + \PassOptionsToPackage{pdftex}{graphicx} + \PassOptionsToPackage{numbered}{bookmark} + \PassOptionsToPackage{tikz}{bclogo} + ''', +'fontenc' : r''' + \usepackage[T2A]{fontenc} + ''', +'fontsubstitution' : r'', +'inputenc' : r'\usepackage[utf8]{inputenc}', +'preamble': r""" +\usepackage{defs} +""", +'hyperref' : r''' +\usepackage[colorlinks=true,linkcolor=blue]{hyperref} +''', +'maketitle': r""" +\nonstopmode + +\thispagestyle{empty} +\begin{titlepage} +\renewcommand{\maketitle}{ O{\ } O{\ } m }{ +\fancyhf{} +\thispagestyle{empty} + +\topskip0pt +\vspace*{\fill} + +\begin{flushright} +\Huge {\xhrulefill{red}{2mm}\color{red} Ред} Эксперт\\ +\LARGE Версия 2024.08\\ +\huge Руководство пользователя\\ + +\end{flushright} + +\vspace*{\fill}} +\end{titlepage} +""", +'tableofcontents' : r""" +\addtocounter{page}{1} + +\definecolor{MidnightBlue}{RGB}{25, 25, 112} + +\titleformat{\section}[display] +{\filcenter\Huge\bfseries\color{MidnightBlue}} +{\raggedright\normalfont\Large Глава \thesection}{3pt}{} + +\titleformat{\subsection} +{\filright\LARGE\bfseries\color{MidnightBlue}} +{\thesubsection}{10pt}{} + +\titleformat{\subsubsection} +{\filright\Large\bfseries\color{MidnightBlue}} +{\thesubsubsection}{10pt}{} + +\titleformat{\paragraph} +{\filright\large\bfseries\color{MidnightBlue}} +{\theparagraph}{1em}{} + +\renewcommand{\thetable}{\thesection.\arabic{table}} +\renewcommand{\thefigure}{\thesection.\arabic{figure}} + +\makeatletter +\fancypagestyle{normal}{ +\pagestyle{fancy} +\fancyhf{} +\fancyhead[R]{Руководство пользователя\\\rightmark} +\fancyfoot[C]{\xhrulefill{red}{2mm} Стр. \thepage} +\renewcommand{\headrulewidth}{0.5pt} +} +\makeatother + +\setcounter{tocdepth}{10} +\setlength{\headheight}{24pt} +\renewcommand\contentsname{Содержание} +\tableofcontents +""", +'figure_align': 'H', +} + + +latex_table_style = [] + +numfig = True # чтобы :numref: не игнорировался +highlight_language = 'none' # подсветка синтаксиса в код-блоках по умолчанию выключена + + +#latex_show_urls = 'footnote' +# -- Options for HTML output ------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output + +html_theme = 'alabaster' +html_static_path = ['_static'] +html_css_files = [ + 'css/codeblock_style.css', +] + +# Параметр для директивы и роли hideifcert (showifcert). +# Если версия документации сертифицированная (True), то текст внутри hideifcert (showifcert) скрывается (виден) +globalvar.IsCertifiedVersion = False + + +# Замены для ролей hideifcert и showifcert. +# Роли не умеют парсить моноширинный текст, но могут распарсить замены +rst_prolog = """ +""" + + + + + + diff --git a/guide_rst/source/defs.sty b/guide_rst/source/defs.sty new file mode 100644 index 000000000..6f35aa8a7 --- /dev/null +++ b/guide_rst/source/defs.sty @@ -0,0 +1,286 @@ +\usepackage{hyphsubst} + +\PassOptionsToPackage{english,russian}{babel} + +\usepackage{sphinx} + +% \usepackage[utf8]{inputenc} +% \usepackage[T2A,T1]{fontenc} + +\usepackage{fancyhdr} + +\usepackage{hypcap} % чтобы избежать ошибки при использовании директивы figure + + +\PassOptionsToPackage{pdftex}{graphicx} + +\usepackage{array} +\usepackage{longtable} +\usepackage{hhline} + +\usepackage{amsmath} %математические символы +\usepackage{amssymb} +\usepackage{amsfonts} +\usepackage{textcomp} %шрифты +\usepackage{type1ec} % для четкости шрифта + +\makeatletter +\newcommand\arraybslash{\let\\\@arraycr} +\makeatother + +\setlength\tabcolsep{1mm} +\renewcommand\arraystretch{1.3} +\newcounter{Table}[section] +\renewcommand\theTable{\thesection.\arabic{Table}} + + + +\usepackage{color} +\usepackage{framed} +\usepackage[framemethod=tikz]{mdframed} +\usepackage[tikz]{bclogo} + +\usepackage{titlesec} +\usepackage{xhfill} +\usepackage{booktabs} +\usepackage{listingsutf8} +\usepackage{float} +\usepackage{tablefootnote} +\usepackage{colortbl} +\usepackage{multirow} +\usepackage{tabularx} +\usepackage{comment} +\usepackage{enumitem} +\usepackage{indentfirst} +\usepackage[most]{tcolorbox} +\usepackage{afterpage} +\usepackage{transparent} +\usepackage{xcolor} + + + +\emergencystretch=25pt + +% чтобы разделы в оглавлении были не жирным а обычным шрифтом +\makeatletter +\renewcommand*\l@section[2]{% +\ifnum \c@tocdepth >\z@ +\addpenalty\@secpenalty +\addvspace{1.0em \@plus\p@}% +\setlength\@tempdima{1.5em}% +\begingroup +\parindent \z@ \rightskip \@pnumwidth +\parfillskip -\@pnumwidth +\leavevmode +\advance\leftskip\@tempdima +\hskip -\leftskip +#1\nobreak\hfil \nobreak\hb@xt@\@pnumwidth{\hss #2}\par +\endgroup +\fi} +\makeatother + +\makeatletter +\@addtoreset{figure}{section} % сбросит счетчик рисунков в начале каждого раздела. +\makeatother + +\makeatletter +\@addtoreset{table}{section} % сбросит счетчик таблиц в начале каждого раздела. +\makeatother + +\renewcommand{\labelenumii}{\theenumii.} +\renewcommand{\theenumii}{\arabic{enumii}} + +\newcounter{redlisting}[section] +\renewcommand{\theredlisting}{\thesection.\arabic{redlisting}} +\newcommand{\li}{\refstepcounter{redlisting} Листинг \theredlisting. } +\newcommand{\enli}{\refstepcounter{redlisting} Listing \theredlisting. } + +%оформление таблиц и рисунков по ГОСТ +\PassOptionsToPackage{tableposition=top}{caption} +\usepackage{subcaption} +\DeclareCaptionLabelFormat{gostfigure}{Рисунок #2} +\DeclareCaptionLabelFormat{gosttable}{Таблица #2} +\DeclareCaptionLabelSeparator{gost}{~---~} +\captionsetup{labelsep=gost} +\captionsetup[figure]{labelformat=gostfigure} +\captionsetup[table]{labelformat=gosttable,justification=raggedright,slc=off} + + +%задает пустое пространство до и после таблицы +\setlength{\LTpre}{5pt} +\setlength{\LTpost}{5pt} + +\newcommand{\sectionbreak}{\clearpage} + +%задает цвет гиперссылок +\hypersetup{urlcolor=blue} +\usepackage{xparse} + + +\setlist[enumerate]{leftmargin=42pt, labelsep = 6pt} +\setlist[itemize]{leftmargin=42pt, labelsep = 6pt} +\setlist[description]{labelsep=0pt, partopsep=0pt, itemsep = 2pt, leftmargin = 25pt} + + + +%для отображения нумерованных подпунктов, например, 1.1 +\renewcommand{\labelenumii}{\arabic{enumi}.\arabic{enumii}} +\renewcommand{\labelenumiii}{\arabic{enumi}.\arabic{enumii}.\arabic{enumiii}} +\renewcommand{\labelenumiv}{\arabic{enumi}.\arabic{enumii}.\arabic{enumiii}.\arabic{enumiv}} + +% чтобы заголовки таблиц были жирным обычным шрифтом +\protected\def\sphinxstyletheadfamily {\centering\arraybackslash\normalfont\bfseries } +\protected\def\sphinxtablecontinued#1{\hspace{140mm}\textsf{\footnotesize{(pазрыв таблицы)}}} +\protected\def\sphinxstylecodecontinued#1{\textsf{\footnotesize{(продолжение с предыдущей страницы)}}} +\protected\def\sphinxstylecodecontinues#1{\textsf{\footnotesize{(продолжение на следующей странице)}}} + +\parskip = 3pt +\parindent=25pt + +% настройка для блоков Note и Warning +\sphinxsetup{ + div.note_border-top-width = 0pt, + div.note_border-right-width = 0pt, + div.note_border-bottom-width = 0pt, + div.note_border-left-width = 4pt, + div.note_border-TeXcolor = green!50!black, + div.note_background-TeXcolor = green!8, + div.warning_border-top-width = 0pt, + div.warning_border-right-width = 0pt, + div.warning_border-bottom-width = 0pt, + div.warning_border-left-width = 4pt, + div.warning_border-TeXcolor = red, + div.warning_background-TeXcolor = red!8, + } + + +\renewenvironment{sphinxnote}[1]{\begin{sphinxheavybox}}{\end{sphinxheavybox}} % чтобы не печаталось слово "Примечание:" +\renewenvironment{sphinxwarning}[1]{\begin{sphinxheavybox}}{\end{sphinxheavybox}} % чтобы не печаталось слово "Предупреждение:" + +% команда для настройки Verbatim (код-блоков) +% потребовалось для отступа текста от рамки внутри блока кода +\usepackage{fancyvrb} +\fvset{ + frame=single, + framerule=0mm, + xrightmargin=8pt, + xleftmargin=8pt, + framesep=6pt, +} + +% настройка код-блоков +% директива код-блоков переопределена в файле NewCodeBlockDirective.py +\sphinxsetup{ + verbatimvisiblespace = , % чтобы переносы строк в код-блоке были без + verbatimcontinued = , % красных стрелок и подчеркивания пробела +} + +\newcommand{\redlistingstyle}{ + \sphinxsetup{ + pre_border-width = 0.5pt , + pre_border-top-left-radius = 0pt, + pre_border-top-right-radius = 0pt, + pre_border-bottom-right-radius = 5pt, + pre_border-bottom-left-radius = 5pt, + pre_border-TeXcolor = black!90, + pre_background-TeXcolor = white!98!black, + pre_box-shadow = 2pt 2pt, + pre_box-shadow-TeXcolor=gray!40, + pre_padding-top=0pt, + pre_padding-right = -0.5pt, + pre_padding-bottom = 0pt, + pre_padding-left = -0.5pt, + } +} +\newcommand{\redstatementstyle}{ + \sphinxsetup{ + pre_border-width = 0.5pt , + pre_border-radius=5pt, + pre_border-TeXcolor = black!90, + pre_background-TeXcolor = white!98!black, + pre_box-shadow = 2pt 2pt, + pre_box-shadow-TeXcolor=gray!40, + pre_padding=-0.5pt, + } +} + +\newcommand{\redbordlessstyle}{ + \sphinxsetup{ + pre_border-width = 0pt , + pre_border-radius=0pt, + pre_background-TeXcolor = white, + pre_box-shadow = 0pt 0pt, + } +} + +\newcommand{\redexamplestyle}{ + \sphinxsetup{ + pre_border-radius=0pt, + pre_border-top-width = 0.5pt , + pre_border-bottom-width = 0.5pt , + pre_border-right-width = 0pt, + pre_border-left-width = 0pt, + pre_border-TeXcolor = yellow!70!black, + pre_background-TeXcolor= yellow!10, + pre_box-shadow = 0pt 0pt, + pre_padding=-0.5pt, + } +} + +% Листинг состоит из 2-х разных блоков: +% 1. Заголовок - в окружении tcolorbox +% 2. Тело - стандартный код-блок +\newcommand{\redlistingtitlestyle}[1]{\begin{tcolorbox}[% + enhanced, + colback=white, % цвет фона основого текста + width=\textwidth, + arc=5pt, + coltitle = white, % цвет текста заголовка + fonttitle = \normalfont\bfseries, + title = \li #1, + toptitle = 3pt, % отступ Текста заголовка от рамки сверху + bottomtitle = 2pt, % отступ Текста заголовка от рамки снизу + shadow={2pt}{0pt}{0mm}{gray!43}, + colbacktitle = black!55!white, % цвет фона заголовка + colframe=white, % цвет рамки всего бокса + boxrule = 0.5pt, % толщина рамки + attach boxed title to top, % чтобы рамка была только + boxed title style={colframe=black}, % у заголовка в черном цвете + ]% +\end{tcolorbox}% +\redlistingstyle} + + +\renewenvironment{DUlineblock}[1]{% + \list{}{\setlength{\partopsep}{\parskip}% + \addtolength{\partopsep}{0.3\baselineskip}% + \setlength{\topsep}{0pt}% + \setlength{\itemsep}{0.15\baselineskip}% + \setlength{\parsep}{0pt}% + \setlength{\leftmargin}{#1}}% + \raggedright% +} +{\endlist} + +% окружение для директивы unindened_list (списки с маленьким отступом) +\newenvironment{listenv}{\setlist[itemize]{leftmargin=12pt, labelsep = 6pt}\setlist[enumerate]{leftmargin=17pt, labelsep = 6pt} }{} + + + +% чтобы в оглавлении было не присто А Б, а Приложение А, Приложение Б +\renewcommand\appendixname{Приложение} + +\newcounter{application} +\renewcommand{\theapplication}{\Asbuk{application}} +\newcommand{\appcount}{\refstepcounter{application}} + +\makeatletter +\def\redeflsection{\def\l@section{\@dottedtocline{1}{0em}{8em}}} +\renewcommand\appendix{\par + \setcounter{application}{0}% + \setcounter{subsection}{0}% + \def\@chapapp{\appendixname}% + \addtocontents{toc}{\protect\redeflsection} + \def\thesection{\appendixname\hspace{0.2cm}\Asbuk{application}} + } +\makeatother \ No newline at end of file diff --git a/guide_rst/source/img/add_user.png b/guide_rst/source/img/add_user.png new file mode 100644 index 000000000..9f9380a90 Binary files /dev/null and b/guide_rst/source/img/add_user.png differ diff --git a/guide_rst/source/img/browser.png b/guide_rst/source/img/browser.png new file mode 100644 index 000000000..53e53d791 Binary files /dev/null and b/guide_rst/source/img/browser.png differ diff --git a/guide_rst/source/img/compare_db_module.png b/guide_rst/source/img/compare_db_module.png new file mode 100644 index 000000000..f45de2479 Binary files /dev/null and b/guide_rst/source/img/compare_db_module.png differ diff --git a/guide_rst/source/img/compare_stat_sql.png b/guide_rst/source/img/compare_stat_sql.png new file mode 100644 index 000000000..8fda4970f Binary files /dev/null and b/guide_rst/source/img/compare_stat_sql.png differ diff --git a/guide_rst/source/img/compare_stat_text.png b/guide_rst/source/img/compare_stat_text.png new file mode 100644 index 000000000..b814f4ead Binary files /dev/null and b/guide_rst/source/img/compare_stat_text.png differ diff --git a/guide_rst/source/img/create_db.png b/guide_rst/source/img/create_db.png new file mode 100644 index 000000000..cb65855ed Binary files /dev/null and b/guide_rst/source/img/create_db.png differ diff --git a/guide_rst/source/img/database.png b/guide_rst/source/img/database.png new file mode 100644 index 000000000..913b5e261 Binary files /dev/null and b/guide_rst/source/img/database.png differ diff --git a/guide_rst/source/img/drivers.png b/guide_rst/source/img/drivers.png new file mode 100644 index 000000000..0bb4135a4 Binary files /dev/null and b/guide_rst/source/img/drivers.png differ diff --git a/guide_rst/source/img/erd.png b/guide_rst/source/img/erd.png new file mode 100644 index 000000000..d7e7fa291 Binary files /dev/null and b/guide_rst/source/img/erd.png differ diff --git a/guide_rst/source/img/execute_from_file.png b/guide_rst/source/img/execute_from_file.png new file mode 100644 index 000000000..19d7e31d5 Binary files /dev/null and b/guide_rst/source/img/execute_from_file.png differ diff --git a/guide_rst/source/img/export_connection.png b/guide_rst/source/img/export_connection.png new file mode 100644 index 000000000..f6d755058 Binary files /dev/null and b/guide_rst/source/img/export_connection.png differ diff --git a/guide_rst/source/img/export_metadata_output.png b/guide_rst/source/img/export_metadata_output.png new file mode 100644 index 000000000..5ebcbe55f Binary files /dev/null and b/guide_rst/source/img/export_metadata_output.png differ diff --git a/guide_rst/source/img/export_metadata_sql.png b/guide_rst/source/img/export_metadata_sql.png new file mode 100644 index 000000000..523edbe44 Binary files /dev/null and b/guide_rst/source/img/export_metadata_sql.png differ diff --git a/guide_rst/source/img/export_metadata_view.png b/guide_rst/source/img/export_metadata_view.png new file mode 100644 index 000000000..2d59491a6 Binary files /dev/null and b/guide_rst/source/img/export_metadata_view.png differ diff --git a/guide_rst/source/img/export_metadate.png b/guide_rst/source/img/export_metadate.png new file mode 100644 index 000000000..c9d6fc2df Binary files /dev/null and b/guide_rst/source/img/export_metadate.png differ diff --git a/guide_rst/source/img/import_connection.png b/guide_rst/source/img/import_connection.png new file mode 100644 index 000000000..c25aec024 Binary files /dev/null and b/guide_rst/source/img/import_connection.png differ diff --git a/guide_rst/source/img/import_connection_file.png b/guide_rst/source/img/import_connection_file.png new file mode 100644 index 000000000..606f41825 Binary files /dev/null and b/guide_rst/source/img/import_connection_file.png differ diff --git a/guide_rst/source/img/import_date.png b/guide_rst/source/img/import_date.png new file mode 100644 index 000000000..46087156d Binary files /dev/null and b/guide_rst/source/img/import_date.png differ diff --git a/guide_rst/source/img/import_example.png b/guide_rst/source/img/import_example.png new file mode 100644 index 000000000..a0c2bbec3 Binary files /dev/null and b/guide_rst/source/img/import_example.png differ diff --git a/guide_rst/source/img/instruments.png b/guide_rst/source/img/instruments.png new file mode 100644 index 000000000..48fe9efed Binary files /dev/null and b/guide_rst/source/img/instruments.png differ diff --git a/guide_rst/source/img/interface_overview.png b/guide_rst/source/img/interface_overview.png new file mode 100644 index 000000000..72a6d8e1a Binary files /dev/null and b/guide_rst/source/img/interface_overview.png differ diff --git a/guide_rst/source/img/memory.png b/guide_rst/source/img/memory.png new file mode 100644 index 000000000..a8cb24165 Binary files /dev/null and b/guide_rst/source/img/memory.png differ diff --git a/guide_rst/source/img/named_parameter.png b/guide_rst/source/img/named_parameter.png new file mode 100644 index 000000000..cbe51f2d5 Binary files /dev/null and b/guide_rst/source/img/named_parameter.png differ diff --git a/guide_rst/source/img/new_driver.png b/guide_rst/source/img/new_driver.png new file mode 100644 index 000000000..cabf4739e Binary files /dev/null and b/guide_rst/source/img/new_driver.png differ diff --git a/guide_rst/source/img/overview.png b/guide_rst/source/img/overview.png new file mode 100644 index 000000000..b3bd8f480 Binary files /dev/null and b/guide_rst/source/img/overview.png differ diff --git a/guide_rst/source/img/privilege_manager.png b/guide_rst/source/img/privilege_manager.png new file mode 100644 index 000000000..12d0db531 Binary files /dev/null and b/guide_rst/source/img/privilege_manager.png differ diff --git a/guide_rst/source/img/profiler.png b/guide_rst/source/img/profiler.png new file mode 100644 index 000000000..cf25187da Binary files /dev/null and b/guide_rst/source/img/profiler.png differ diff --git a/guide_rst/source/img/settings.png b/guide_rst/source/img/settings.png new file mode 100644 index 000000000..8d5d4ad05 Binary files /dev/null and b/guide_rst/source/img/settings.png differ diff --git a/guide_rst/source/img/sql_editor.png b/guide_rst/source/img/sql_editor.png new file mode 100644 index 000000000..541380079 Binary files /dev/null and b/guide_rst/source/img/sql_editor.png differ diff --git a/guide_rst/source/img/stat.png b/guide_rst/source/img/stat.png new file mode 100644 index 000000000..d3923a101 Binary files /dev/null and b/guide_rst/source/img/stat.png differ diff --git a/guide_rst/source/img/stat_out.png b/guide_rst/source/img/stat_out.png new file mode 100644 index 000000000..00ae4528d Binary files /dev/null and b/guide_rst/source/img/stat_out.png differ diff --git a/guide_rst/source/img/test_data_generator.png b/guide_rst/source/img/test_data_generator.png new file mode 100644 index 000000000..3ef3d28dd Binary files /dev/null and b/guide_rst/source/img/test_data_generator.png differ diff --git a/guide_rst/source/img/toolbar.png b/guide_rst/source/img/toolbar.png new file mode 100644 index 000000000..3f05b90da Binary files /dev/null and b/guide_rst/source/img/toolbar.png differ diff --git a/guide_rst/source/img/trace_manager.png b/guide_rst/source/img/trace_manager.png new file mode 100644 index 000000000..d9c465549 Binary files /dev/null and b/guide_rst/source/img/trace_manager.png differ diff --git a/guide_rst/source/img/trace_manager_analysis.png b/guide_rst/source/img/trace_manager_analysis.png new file mode 100644 index 000000000..eb42bda66 Binary files /dev/null and b/guide_rst/source/img/trace_manager_analysis.png differ diff --git a/guide_rst/source/img/trace_manager_session.png b/guide_rst/source/img/trace_manager_session.png new file mode 100644 index 000000000..46878a3cb Binary files /dev/null and b/guide_rst/source/img/trace_manager_session.png differ diff --git a/guide_rst/source/img/trace_manager_table.png b/guide_rst/source/img/trace_manager_table.png new file mode 100644 index 000000000..5928edcc5 Binary files /dev/null and b/guide_rst/source/img/trace_manager_table.png differ diff --git a/guide_rst/source/img/tree.png b/guide_rst/source/img/tree.png new file mode 100644 index 000000000..4e67c8f30 Binary files /dev/null and b/guide_rst/source/img/tree.png differ diff --git a/guide_rst/source/img/tree_object.png b/guide_rst/source/img/tree_object.png new file mode 100644 index 000000000..fc1671b23 Binary files /dev/null and b/guide_rst/source/img/tree_object.png differ diff --git a/guide_rst/source/img/tree_options.png b/guide_rst/source/img/tree_options.png new file mode 100644 index 000000000..8e9d0f3fe Binary files /dev/null and b/guide_rst/source/img/tree_options.png differ diff --git a/guide_rst/source/img/unnamed_parameter.png b/guide_rst/source/img/unnamed_parameter.png new file mode 100644 index 000000000..da0ad72dd Binary files /dev/null and b/guide_rst/source/img/unnamed_parameter.png differ diff --git a/guide_rst/source/img/user_manager.png b/guide_rst/source/img/user_manager.png new file mode 100644 index 000000000..1e7c45a97 Binary files /dev/null and b/guide_rst/source/img/user_manager.png differ diff --git a/guide_rst/source/img/validation.png b/guide_rst/source/img/validation.png new file mode 100644 index 000000000..a18a1504c Binary files /dev/null and b/guide_rst/source/img/validation.png differ diff --git a/guide_rst/source/img/workspace.png b/guide_rst/source/img/workspace.png new file mode 100644 index 000000000..4728e36dc Binary files /dev/null and b/guide_rst/source/img/workspace.png differ diff --git a/guide_rst/source/index.rst b/guide_rst/source/index.rst new file mode 100644 index 000000000..2e0f57ead --- /dev/null +++ b/guide_rst/source/index.rst @@ -0,0 +1,34 @@ + +Welcome to Red_Expert's documentation! +============================================= + +.. toctree:: + :maxdepth: 2 + + introduction + sec-install + sec-overview + sec-database + sec-compare_db_module + sec-export_metadate + sec-instruments + sec-sql_editor + sec-erd + sec-stat + sec-trace_manager + sec-user_manager + sec-privilege_manager + sec-profiler + sec-validation + sec-import + sec-test_generator + sec-system + .. app-toolbar + .. app-options + + + + + + + diff --git a/guide_rst/source/introduction.rst b/guide_rst/source/introduction.rst new file mode 100644 index 000000000..fcd07d716 --- /dev/null +++ b/guide_rst/source/introduction.rst @@ -0,0 +1,12 @@ +Введение +========== + +Ред Эксперт - это GUI-оболочка, написанная на ``Java``, предоставляющая интерфейс для работы с базами данных ``Firebird`` и Ред Базой Данных. +Ред Эксперт является программой, независимой от операционной системы, для которой требуется только ``JDK`` не ниже ``1.8``. + +Ред Эксперт обеспечивает лёгкое взаимодействие с базой данных, позволяя выполнять различные действия: писать и профилировать запросы, +создавать и редактировать таблицы, экспортировать и сравнивать метаданные баз, собирать статистику и многое другое. + +Вы можете связаться с нами через форму обратной связи в приложении (Справка :math:`\to` Обратная связь) или отправив письмо по адресу ``rdb.support@red-soft.ru``. +В письме Вы можете оставить отзыв о работе программы, сообщить нам об ошибке или предложить новый функционал. +Мы будем рады Вам помочь! \ No newline at end of file diff --git a/guide_rst/source/sec-compare_db_module.rst b/guide_rst/source/sec-compare_db_module.rst new file mode 100644 index 000000000..dab41e209 --- /dev/null +++ b/guide_rst/source/sec-compare_db_module.rst @@ -0,0 +1,31 @@ +Модуль сравнения баз данных +================================ + +Инструмент сравнивает две базы данных и генерирует SQL-скрипт, позволяющий сделать две базы идентичными. + +.. warning:: + + В результате работы сгенерированного SQL-скрипт у выбранных баз будет идентичная структура, но не данные. + +.. figure:: img/compare_db_module.png + + Модуль сравнения баз данных + +``База-образец`` – база данных, к состоянию которой нужно привести целевую базу. +``Целевая база`` – база данных, к которой будут применяться изменения. + +Блок ``Атрибуты`` представляет собой список элементов базы данных, которые нужно/не нужно учитывать при сравнении. + +Блок ``Параметры`` представляет собой список условий, влияющих на сравнение баз и формирование SQL-скрипта, приводящего структуру целевой базы к состоянию базы-образца: + +* ``Создание/изменение/удаление объектов`` - добавление в SQL-скрипт запросов для создания/изменения/удаления объектов в целевой базе; +* ``Игнорировать комментарии`` - учитывать ли комментарии при сравнении баз; +* ``Игнорировать вычисляемые столбцы`` – учитывать ли вычисляемые столбцы при сравнении баз; +* ``Игнорировать позиции столбцов`` - учитывать ли позиции столбцов при сравнении баз; +* ``Игнорировать PK/FK/UK/CK`` – учитывать ли ограничения при сравнении баз. + +Найденные различия будут записаны во вкладку ``Вывод``. +Во вкладке SQL будет сформирован скрипт, приводящий структуру целевой базы к структуре базы-образца. + + + diff --git a/guide_rst/source/sec-database.rst b/guide_rst/source/sec-database.rst new file mode 100644 index 000000000..aba2a57eb --- /dev/null +++ b/guide_rst/source/sec-database.rst @@ -0,0 +1,104 @@ +База данных +=============== + +Инструменты для создания базы данных, подключения к ней, а также для извлечения и сравнения метаданных находятся во вкладке База Данных. + +.. figure:: img/database.png + + Вкладка ``База Данных`` + +Создание подключения +------------------------ + +Ред Эксперт позволяет одновременно использовать несколько подключений к базе данных. +Информацию о подключении отображает ``«Браузер баз данных»``. + +.. figure:: img/browser.png + + Браузер баз данных + +Для создания подключения выберите соответствующий пункт в меню База данных или нажмите на кнопку ``Создать подключение`` в панели инструментов. +Заполните поля в открывшемся окне и нажмите на кнопку ``Подключиться``. +.. Подробное описание полей см. в разделе :ref:`parameter_description`. + +.. note:: + + При попытке подключения может возникнуть ошибка шифрования сетевого соединения. + Для поддержки шифрования необходима версия ``Java`` не ниже ``1.8.0_161`` или установленное ``JCE`` дополнение. + В противном случае следует изменить значение параметра ``WireCrypt = Disabled``в ``firebird.conf``. + +SSH туннель +~~~~~~~~~~~~~~~~ + +Есть удобная возможность подключиться к базе данных через ``SSH-туннель``. +Как и при любом ``SSH-соединении``, весь трафик между вами и БД будет шифроваться. +Для этого введите параметры подключения на вкладке ``«Базовые»``, переключитесь на вкладку +``«SSH Тоннель»`` и заполните параметры для ``SSH-соединения``. Имя хоста переносится с вкладки ``«Базовые»``. + +Расширенные параметры подключения +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Дополнительные свойства соединения можно ввести, выбрав вкладку ``«Расширенные»``. +На ней можно увидеть таблицу с двумя столбцами. Левый соответствует параметру подключения, а правый его значению. +Обратитесь к документации ``JDBC`` драйвера, чтобы узнать, какие дополнительные параметры подключения к базе данных могут быть установлены. + +Также можно выбрать уровень изоляции транзакций. +Различные уровни изоляции транзакций определяют поведение данного клиентского приложения, +запустившего эту транзакцию, по отношению к другим параллельным процессам, +выполняющимся на любом компьютере локальной сети, +одновременно выполняющих чтение или изменение в той же базе данных, что и текущий процесс. +Для Ред Базы Данных и Firebird по умолчанию используется ``READ_COMMITED``. + +Создание базы данных +----------------------------- + +Для создания подключения выберите соответствующий пункт в меню ``База данных`` +или нажмите на кнопку ``Создать базу данных`` в панели инструментов. +Заполните поля в открывшемся окне и нажмите на кнопку ``Создать``. +.. Подробное описание полей см. в разделе :ref:`parameter_description`. + +.. figure:: img/create_db.png + + Создание базы данных + +.. note:: + + При попытке создания базы данных может возникнуть ошибка шифрования сетевого соединения. + Для поддержки шифрования необходима версия ``Java`` не ниже ``1.8.0_161`` или установленное ``JCE`` дополнение. + В противном случае следует изменить значение параметра ``WireCrypt = Disabled``в ``firebird.conf``. + +Выполнить SQL-скрипт из файла +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Выберите открытое соединение и укажите путь к файлу с SQL-скриптом и нажмите кнопку ``Начать``. +Сделайте ``commit`` или ``rollback`` транзакции, нажав на соответствующие кнопки. + +.. figure:: img/execute_from_file.png + + Выполнить SQL-скрипт из файла + +Импорт подключения +----------------------- + +Для тех, у кого уже есть настроенные в ``IBExpert`` подключения, разработана опция импорта подключений. +Запустите Ред Эксперт и подключитесь к нужной пользовательской базе данных. +Выберите пункт меню База данных :math:`\to` Импортировать подключения :math:`\to` Импортировать из базы данных и выберите нужное подключение в открывшемся окне. + +.. figure:: img/import_connection.png + + Импорт подключения из базы данных + +Также доступен импорт подключения из файла: + +.. figure:: img/import_connection_file.png + + Импорт подключения из файла + +Экспорт подключения +----------------------- + +Для экспорта подключения в файл выберите пункт меню База данных :math:`\to` Экспортировать подключения и выберите нужное подключение в открывшемся окне. + +.. figure:: img/export_connection.png + + Экспорт подключения \ No newline at end of file diff --git a/guide_rst/source/sec-erd.rst b/guide_rst/source/sec-erd.rst new file mode 100644 index 000000000..cc56e298f --- /dev/null +++ b/guide_rst/source/sec-erd.rst @@ -0,0 +1,18 @@ +.. _erd: + +Редактор ER-диаграмм +========================== + +Инструмент предназначен для создания и редактирования ER-диаграмм баз данных. + +.. figure:: img/erd.png + + Редактор ER-диаграмм + +Основные функции: + +* Создание и редактирование ER-диаграммы; +* Генерация SQL-скрипта для создания таблиц, представленных на диаграмме; +* Построение ER-диаграммы существующей базы данных; +* Экспорт диаграммы в различные форматы. + diff --git a/guide_rst/source/sec-export_metadate.rst b/guide_rst/source/sec-export_metadate.rst new file mode 100644 index 000000000..3ec07fa4a --- /dev/null +++ b/guide_rst/source/sec-export_metadate.rst @@ -0,0 +1,39 @@ +Экспорт метаданных +======================== + +Инструмент извлекает метаданные выбранной базы данных в SQL-скрипт, выполнение которого позволяет создать дубликат этой базы. + +.. figure:: img/export_metadate.png + + Экспорт метаданных + +``База-образец`` – база данных, метаданные которой нужно извлечь. + +Блок ``Атрибуты`` представляет собой список элементов базы данных, которые нужно/не нужно учитывать при экспорте. + +Блок ``Параметры`` представляет собой список условий, влияющих на извлечение метаданных и формирование SQL-скрипта, создающего выбранную базу данных: + +* ``Игнорировать комментарии`` - учитывать ли комментарии при экспорте; +* ``Игнорировать вычисляемые столбцы`` – учитывать ли вычисляемые столбцы при экспорте; +* ``Игнорировать PK/FK/UK/CK`` – учитывать ли ограничения при экспорте. + +Посмотреть результаты экспорта метаданных можно во вкладках Вывод, Обзор и SQL. + +Во вкладке Вывод перечислены элементы, метаданные которых были извлечены: + +.. figure:: img/export_metadata_output.png + + Вкладка Вывод + +Во вкладке Обзор отображены извлечённые элементы, которые будут созданы при выполнении сгенерированного скрипта: + +.. figure:: img/export_metadata_view.png + + Вкладка Обзор + +Во вкладке SQL размещён сгенерированный SQL-скрипт: + +.. figure:: img/export_metadata_sql.png + + Вкладка SQL + diff --git a/guide_rst/source/sec-import.rst b/guide_rst/source/sec-import.rst new file mode 100644 index 000000000..b56d88bcd --- /dev/null +++ b/guide_rst/source/sec-import.rst @@ -0,0 +1,31 @@ +.. _import_date: + +Импорт данных +================== + +Инструмент для импорта данных из файла в таблицу. Поддерживается импорт из ``XLSX``, ``XML`` и ``CSV`` файлов. + +.. figure:: img/import_date.png + + Импорт данных + +Парметры импорта данных: + +* ``Импортировать из соединения`` - Позволяет выбрать базу данных в качестве источника. +* ``Файл данных`` - Путь к файлу-источнику данных. Поддерживается импорт из XLSX, XML и CSV файлов. +* ``Файл блобов`` - Путь к файлу-источнику с блобами (с расширением .lob). +* ``Целевая БД`` - База данных, в которую будет производиться импорт. +* ``Целевая таблица`` - Таблица, в которую будет производиться импорт. +* ``Разделитель`` - Тип разделителя данных в CSV файлах. +* ``Номер страницы`` - Для XLSX файлов можно выбрасть страницу excel-файла, из которой нужно импортировать данные. +* ``Первая импортируемая строка`` - Строка, начиная с которой будут импортированы данные. +* ``Последняя импортируемая строка`` - Строка, поcле которой импорт данных будет прекращён. Строки, непопадающие в диапазон между первой и последней импортируемой строкой, будут проигнорированы. +* ``Шаг фиксации`` - Количество записей, после которого будет произведено подтверждение транзакии и сохранение данных в таблице. +* ``Очистить таблицу перед вставкой`` - Следует ли очистить целевую таблицу от данных, которые в ней были до импорта. +* ``Столбец источника`` - Имя столбца, из которого нужно импортировать данные. Кнопка ``Сопоставить`` автоматически распределяет импортируемые столбцы к целевым столбцам по их именам. +* ``Параметры`` - Импортировать ``BLOB`` как файл или как текст. + +.. figure:: img/import_example.png + + Пример заполнения полей + diff --git a/guide_rst/source/sec-install.rst b/guide_rst/source/sec-install.rst new file mode 100644 index 000000000..017f35e14 --- /dev/null +++ b/guide_rst/source/sec-install.rst @@ -0,0 +1,27 @@ +Установка и обновление +============================ + +Установка +~~~~~~~~~~~~~ + +#. Установите ``JDK`` не ниже 1.8. +#. Скачайте дистрибутив Ред Эксперт с официального сайта СУБД Ред Базы Данных - reddatabase.ru. Загрузка доступна только авторизованному пользователю. +#. Запустите установку с помощью файла ``red_expert_installer-<версия>-xxxxxx``. Инсталляция осуществляется с помощью стандартного мастера установки программ. Предусмотрена установка на русском и английском языке. После установки на рабочем столе появится ярлык приложения. +#. Запустите Ред Эксперт. + +.. note:: + + Если при запуске приложению не удастся найти путь установки ``Java``, то пользователю будет предложено выбрать путь вручную, либо запустить автоматическое скачивание ``Java``: + + * На ``Linux`` системах для автоматического скачивания ``Java`` должен быть установлен пакет ``libcurl4``. + * На ``Windows Server`` для автоматического скачивания ``Java`` нужно отключить усиленную безопасность ``InternetExplorer``. + * Если для вашей системы не предусмотрен инсталятор, то можно запустить приложение командой ``"java -jar RedExpert.jar"`` из каталога в котором находится ``RedExpert.jar``. + +Обновление +~~~~~~~~~~~~~~~~ + +#. При выходе новой версии приложения в строке состояния появится сообщение "Доступно обновление". +#. Нажмите на эту панель и начните обновление. +#. По окончании обновления перезапустите Ред Эксперт. + +Проверять наличие обновлений можно также через пункт меню Справка :math:`\to` Проверить обновления. \ No newline at end of file diff --git a/guide_rst/source/sec-instruments.rst b/guide_rst/source/sec-instruments.rst new file mode 100644 index 000000000..05f1d97c4 --- /dev/null +++ b/guide_rst/source/sec-instruments.rst @@ -0,0 +1,21 @@ +Инструменты +============== + +В этой вкладке находятся различные инструменты для работы с базой данных. + +.. figure:: img/instruments.png + + Вкладка ``Инструменты`` + +Доступные инструменты: + +* :ref:`sql_editor` +* :ref:`erd` +* :ref:`stat` +* :ref:`trace` +* :ref:`user_manager` +* :ref:`privilege_manager` +* :ref:`profiler` +* :ref:`validation` +* :ref:`import_date` +* :ref:`generator` \ No newline at end of file diff --git a/guide_rst/source/sec-overview.rst b/guide_rst/source/sec-overview.rst new file mode 100644 index 000000000..26664481d --- /dev/null +++ b/guide_rst/source/sec-overview.rst @@ -0,0 +1,61 @@ +Обзор графического интерфейса +================================= + +Интерфейс приложения разделен на три основные части: панель инструментов, дерево подключений и рабочее пространство. + +.. figure:: img/overview.png + + Интерфейс приложения + +1 - панель инструментов; +2 - дерево подключений; +3 - рабочее пространство. + +Строка состояния в нижней части приложения отображает информацию о количестве подключений, +доступных обновлениях, версии ``JDK`` и состоянии памяти. + +Панель инструментов +--------------------- + +На панели инструментов находятся кнопки, позволяющие выполнять различные действия, например, установка соединения с базой +и отключение от неё, создание новой базы данных или подключения. Также там находятся кнопки для быстрого доступа к инструментам. + +.. figure:: img/toolbar.png + + Панель инструментов + +Набор кнопок на панели инструментов можно редактировать в меню ``Вид`` или в настройках приложения. + +.. Подробное описание кнопок см. в разделе :ref:`toolbar`. + +Дерево подключений +----------------------- + +После подключения к базе данных на панели появляется структура дерева, узлы которого представляют собой объекты базы данных. +В скобках указано количество объектов каждого вида. + +.. figure:: img/tree.png + + Дерево подключений + +Клик правой кнопкой мыши по узлу вызовет всплывающее меню с доступными для данного объекта действиями. + +.. figure:: img/tree_options.png + + Доступные действия с таблицей + +Двойной клик по объекту откроет вкладку с подробной информацией о нём. + +.. figure:: img/tree_object.png + + Информация о таблице + +Рабочее пространство +---------------------- + +В этой области происходит работа с инструментами базы данных и редактирование объектов. + +.. figure:: img/workspace.png + + Рабочее пространство + diff --git a/guide_rst/source/sec-privilege_manager.rst b/guide_rst/source/sec-privilege_manager.rst new file mode 100644 index 000000000..abe35b9b2 --- /dev/null +++ b/guide_rst/source/sec-privilege_manager.rst @@ -0,0 +1,10 @@ +.. _privilege_manager: + +Менеджер привилегий +========================== + +Менеджер привилегий отображает привилегии и позволяет ими управлять. + +.. figure:: img/privilege_manager.png + + Менеджер привилегий \ No newline at end of file diff --git a/guide_rst/source/sec-profiler.rst b/guide_rst/source/sec-profiler.rst new file mode 100644 index 000000000..d02be3048 --- /dev/null +++ b/guide_rst/source/sec-profiler.rst @@ -0,0 +1,36 @@ +.. _profiler: + +Профайлер +=============== + +Инструмент Профайлер позволяет измерять затраты на производительность ``SQL`` и ``PSQL`` кода. + +.. figure:: img/profiler.png + + Профайлер + +Форматы отображения результата: + +* ``Компактное отображение`` – Отображает общую картину выполнения запросов. Повторяющиеся процессы внутри общего родительского будут объединены в один. Является значением по умолчанию. +* ``Расширенное отображение`` – Отображает детализированную картину выполнения запросов. Отоюражается статискика по выполнению каждой строки ``PSQL`` кода, а повторяющиеся операции не объединяются. +* ``Округлять значения`` - Если общее или среднее время больше 1000000ns, то оно будет переводиться в большую единицу измерения, пока значение не станет меньше 1000000. По умолчанию включено. + +В ``компактном отображении`` для каждого не последнего узла (за исключением ``ROOT NODE`` - корневого узла) есть узел ``Собственное время``, +показывающий затраченное время без учета дочерних процессов. + +В результирующей таблице отображается информация, собранная профайлером, а именно: + +* Имя процесса или SQL-код; +* Затраченное на процесс время в наносекундах (с учетом дочерних процессов) и процент времени от родительского процесса; +* Среднее затраченное на процесс время в наносекундах (с учетом дочерних процессов) для повторяющихся процессов, объединенных в один узел; +* Количество вызовов повторяющихся процессов. + +Сессию профайлера можно запустить для одного запроса из редактора запросов кликом по кнопке ``Выполнить в профайлере``. +В этом случае будет выполнено следующее: + +1. Запустится сессия профайлера. +2. Выполнится находящийся в редакторе запрос. +3. Завершится сессия профайлера. +4. Отобразится панель профайлера с собранной информацией. + + diff --git a/guide_rst/source/sec-sql_editor.rst b/guide_rst/source/sec-sql_editor.rst new file mode 100644 index 000000000..dfc3d3e54 --- /dev/null +++ b/guide_rst/source/sec-sql_editor.rst @@ -0,0 +1,68 @@ +.. _sql_editor: + +Редактор запросов +====================== + +Редактор запросов представляет собой настраиваемый инструмент просмотра и выполнения операторов SQL. В любой момент времени может быть открыто любое количество редакторов. + +Редактор поддерживает следующие функции: + +* Настраиваемая подсветка синтаксиса SQL; +* Подсказки ключевых слов и имен объектов базы данных; +* Выполнение нескольких запросов; +* Выполнение и отображение нескольких запросов с множеством результатов (``Result Set``); +* Поддержка параметризованных запросов; +* Полная поддержка печати; +* Управление транзакциями; +* Функции текстового редактора стиля IDE - поиск, замена, вставка и т.д.; +* Экспорт результатов; +* Поддержка нескольких открытых соединений; +* Поисковая исполняемая история SQL-запросов; +* Быстрый переход из редактора к просмотру объекта базы данных двойным кликом или нажатием CTRL + Левая клавиша мыши по имени объекта; +* Выбор уровня изоляции транзакции. + +.. figure:: img/sql_editor.png + + Редактор запросов + +Параметризованные запросы +------------------------------- + +В некоторых случаях нужно создать запрос, который можно использовать многократно, но каждый раз с разными входными значениями. +Например, можно написать несколько запросов, чтобы найти данные о сотруднике с определенной фамилией. А можно написать один запрос, меняя только фамилию сотрудника. + +Чтобы создать запрос, который в разное время может иметь разные входные данные, используются параметры запроса. +Параметры могут быть именованными и неименованными. +Неименованный параметр - это вопросительный знак (``?``), который можно указать в любом месте запроса, вместо литерального значения. Например: + +.. code-block:: + + SELECT * FROM employee WHERE (surname = ?) + +После запуска такого запроса откроется диалоговое окно для ввода значения параметра (фамилии сотрудника): + +.. figure:: img/unnamed_parameter.png + + Неименованный параметр + +Именованные параметры - это комбинация двоеточия и имени параметра (``:``), которую также можно подставлять вместо литерального значения. +Именованные параметры особенно полезны, если в запросе их несколько. Например: + +.. code-block:: + + SELECT * FROM employee WHERE (surname = :surname AND name =:name) + +После запуска такого запроса откроется диалоговое окно для ввода значений параметров (фамилии и имени сотрудника): + +.. figure:: img/named_parameter.png + + Именованные параметры + +История запросов +------------------ + +После успешного выполнения запрос сохраняется в кэше журнала редактора. +Количество хранящихся в истории запросов указывается в настройках редактора. +Сохраненные запросы не теряются после перезапуска приложения или редактора запросов. + + diff --git a/guide_rst/source/sec-stat.rst b/guide_rst/source/sec-stat.rst new file mode 100644 index 000000000..ff4456ce4 --- /dev/null +++ b/guide_rst/source/sec-stat.rst @@ -0,0 +1,46 @@ +.. _stat: + +Статистика БД +=================== + +Инструмент отображает статистику базы данных, а также позволяет сравнить результаты анализа двух баз. + +.. figure:: img/stat.png + + Сбор статистики БД + +Форматы сбора статистики: + +* По умолчанию – анализ всей базы данных, вывод аналогичен выполнению ``gstat`` без опций; +* Таблицы – статистика страниц данных, вывод аналогичен выполнению ``gstat -data``; +* Индексы – анализ индексов, вывод аналогичен ``gstat -index``; +* Версии записей – добавляет статистику о средних длинах записей, количестве версий и информацию о ``BLOB``; +* Системные объекты – анализ системных таблиц и индексов; +* Страница заголовка – статические данные о базе данных, вывод аналогичен ``gstat -header``; +* Только выбранные таблицы – анализ выбранных таблиц, параметр доступен, если установлено соединение с выбранной базой данных. + +Собранная статистика оборажается в отдельной вкладке: + +.. figure:: img/stat_out.png + + Собранная статистика + +Сравнение статистик двух баз +--------------------------------- + +Для сравнения статистик двух баз данных выполните сбор статистики для второй базы и нажмите кнопку ``Сравнить``. + +Во вкладке ``Текст`` будет отображен текстовый вывод статистик: + +.. figure:: img/compare_stat_text.png + + Текстовый вывод статистик + +Во вкладках ``Таблицы``, ``Индексы`` и ``Табличные пространства`` значения столбцов показывают разницу между результатом первой и второй базы. + +.. figure:: img/compare_stat_sql.png + + Результат сравнения статистик + +Зелёным цветом обозначено то, что есть в обеих базах данных. +Красным цветом обозначены таблицы и индексы, которые есть в первой базе, но отсутствуют во второй. \ No newline at end of file diff --git a/guide_rst/source/sec-system.rst b/guide_rst/source/sec-system.rst new file mode 100644 index 000000000..0f80e0674 --- /dev/null +++ b/guide_rst/source/sec-system.rst @@ -0,0 +1,67 @@ +Система +=========== + +Драйверы +------------- + +Панель ``Драйверы`` перечисляет все установленные в настоящее время драйверы ``JDBC``. + +По умолчанию в Ред Эксперт установлены библиотеки ``Jaybird 3 Driver``, ``Jaybird 4 Driver``, ``Jaybird 5 Driver``, +которая позволяет работать с базами данных ``Firebird`` и Ред Базой Данных. + +.. figure:: img/drivers.png + + Драйверы + +Для добавления нового драйвера нажмите на кнопку "Добавить драйвер" и заполните все поля. +.. Подробное описание полей см. :ref:`driver`. + +.. figure:: img/new_driver.png + + Добавление драйвера + +Лог приложения +------------------- + +В журнал записывается вся информация, которая выводится в стандартный поток вывода, ошибки и предупреждения. +В Настройках можно задать уровень вывода для ограничения содержащейся в логе информации. + +Системный журнал вывода хранится в ``$HOME/.redexpert/logs`` +и его можно открыть любым текстовым редактором, но можно посмотреть и с помощью Ред Эксперт. + +Состояние памяти +------------------ + +Ред Эксперт позволяет отслеживать текущее использование памяти и запускать сборку мусора. + +.. figure:: img/memory.png + + Состояние памяти + +Настройки +---------------------- + +Для настройки приложения выберите пункт меню Система :math:`\to` Настройки. + +.. note:: + + Практически все изменения вступают в силу после перезапуска Ред Эксперт. + +.. figure:: img/settings.png + + Настройки + +Портативизация настроек +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Чтобы хранить Ред Эксперт и его настройки в одной папке выполните следующие действия: + +1. Закройте программу; +2. Откройте файл ``...\каталог c Red Expert\config\redexpert_config.ini``; +3. Для параметра ``eq.user.home.dir`` укажите значение ``../.redexpert`` и сохраните изменения; +4. В адресной строке проводника введите путь ``%homepath%``; +5. Переместите папку ``.redexpert`` в корень каталога, в который установлен Ред Эксперт; +6. Запустите Ред Эксперт. + + + diff --git a/guide_rst/source/sec-test_generator.rst b/guide_rst/source/sec-test_generator.rst new file mode 100644 index 000000000..5c6ed8ec1 --- /dev/null +++ b/guide_rst/source/sec-test_generator.rst @@ -0,0 +1,33 @@ +.. _generator: + +Генератор тестовых данных +============================ + +Инструмент ``Генератор тестовых данных`` предназначен для быстрого и удобного заполнения полей таблицы большим объемом данных. + +.. figure:: img/test_data_generator.png + + Генератор тестовых данных + +Выберите таблицу. Поля и их типы вы увидите перед собой. +Напротив поля поставьте галочку, если для него нужно сгенерировать данные. +Иначе это поле будет заполнено значениями ``NULL``. + +Напишите количество записей, которое нужно сгенерировать. +Генерация больших объемов данных может занять некоторое время. + +В поле ``Фиксация после`` введите число строк, после вставки которых будет коммит. + +При генерации могут возникать ошибки. По умолчанию они не пишутся в лог-файл. +Поставьте соответствующую галочку, чтобы все ошибки фиксировались в логе. + +Если в процессе генерации возникают ошибки для некоторых записей (например, из-за ограничений столбца), то по умолчанию генератор продолжает свою работу. +Можно изменить это поведение, поставив галочку для поля ``Остановить при ошибке``. + +Можно выбрать метод генерации отдельно для каждого поля таблицы: + +* ``Случайно`` - В зависимости от типа поля настраиваются различные параметры генерации. +* ``Получить из другой таблицы`` - В этом методе нужно выбрать таблицу, столбец и количество записей. Записи из таблицы выбираются случайно в указанном количестве, далее из этого списка значений заполняется основная таблица. +* ``Получить из списка`` - Значения списка формируют содержимое поля. Список должен состоять из элементов соответствующего типа данных. Разделителем может выступать любой одиночный символ или escape-последовательность, начинающаяся с обратной косой черты ('\'). Сам список можно ввести вручную в предназначенном для этого поле, либо загрузить из файла. +* ``Автоинкремент`` - Для автоинкремента настраивается начальное значение, шаг и направление движения шага (в сторону увеличения или уменьшения). + diff --git a/guide_rst/source/sec-trace_manager.rst b/guide_rst/source/sec-trace_manager.rst new file mode 100644 index 000000000..c4250a9d8 --- /dev/null +++ b/guide_rst/source/sec-trace_manager.rst @@ -0,0 +1,83 @@ +.. _trace: + +Трейс менеджер +===================== + +Трейс менеджер позволяет отслеживать и анализировать все, что происходит в базе данных в режиме реального времени. +Он отслеживает и записывает в лог-файлы такие события, как: соединение и отключение от базы данных, +создание и удаление базы, выполнение ``DML`` и ``DDL``, хранимых процедур и прочее. + +.. figure:: img/trace_manager.png + + Трейс менеджер + +Для включения сервиса аудита необходимо заполнить все поля. +Можно выбрать сохраненное подключение к базе данных и поля параметров +будут заполнены автоматически на основе этого подключения. + +Укажите конфигурационный файл с настройками аудита. +В зависимости от версии сервера параметры настройки аудита несколько отличаются, +поэтому из выпадающего списка выберите сервер, соответствующий базе данных. +Настройте параметры аудита и включите трассировку или сохраните их в файле конфигурации. +.. Описание параметров см. :ref:`trace_conf`. + +Таблица событий +---------------------- + +Таблица событий в Трейс менеджере заполняется либо при включении трассировки, либо при открытии сохраненного лог-файла. +При открытии лог-файла есть возможность выбора кодировки. + +В таблице событий по умолчанию отображаются все возможные столбцы, содержащие информацию о зарегистрированном событии. +По желанию некоторые столбцы можно скрыть. Для этого нажмите на кнопку ``Видимые столбцы`` и внесите необходимые изменения. + +.. figure:: img/trace_manager_table.png + + Таблица событий + +При нажатии Правой кнопки мыши на любую из таблиц, появляется контекстное меню для экспорта таблицы. + +Анализ трейса +--------------- + +Анализ трейса отображает информацию о событиях произошедших в указанный период времени. События добавляются либо при включении трассировки, либо при открытии лог-файла. + +Параметры анализа трейса: + +* ``TIME`` - Информация о времени выполнения запроса; +* ``READ`` - Информация о количестве страниц, считанных с диска; +* ``FETCH`` - Информация о количестве страниц, считанных из страничного кэша; +* ``WRITE`` - Информация о количестве страниц, записанных на диск; +* ``MARK`` - Информация о количестве страниц, изменённых в страничном кэше; +* ``RSORT`` - Информация об объёме ОЗУ, использованном для сортировки; +* ``DSORT`` - Информация о размере временных файлов, использованных в запросе; +* ``Округлить значения`` - Если значение больше 10000, то оно будет переводиться в большую единицу измерения, пока не станет меньше 10000; +* ``Показать план`` - План выполнения выбранного запроса. + +Дополнительные параметры: + +* ``Период`` - Период времени, который нужно проанализировать; после изменения периода нужно нажать кнопку ``Обновить``; +* ``Сравнить по N`` - Считать запросы одинаковыми, если у них совпадают первые ``N`` символов; +* ``Фильтр событий`` - Позволяет выбрать типы событий, которые нужно анализировать. + +.. figure:: img/trace_manager_analysis.png + + Результирующая таблица + +При наведении на ячейку в всплывающей подсказке будет показана сумма значений столбца и среднее значение. +Для просмотра полного текста запроса и его плана нужно выбрать ячейку. +При двойном клике откроется окно с записью события в текстовом формате. + +Менеджер сессий +------------------ + +Менеджер сессий отображает список всех доступных в настоящее время сеансов трассировки. +Вкладка менеджера видна только при запущенной текущей сессии аудита. + +.. figure:: img/trace_manager_session.png + + Менеджер сессиий + +В окне слева можно выбрать имя сессии и посмотреть информацию о ней (``ID``, запустившего пользователя, время запуска), +а также завершить сеанс трассировки. + + diff --git a/guide_rst/source/sec-user_manager.rst b/guide_rst/source/sec-user_manager.rst new file mode 100644 index 000000000..5b1333118 --- /dev/null +++ b/guide_rst/source/sec-user_manager.rst @@ -0,0 +1,16 @@ +.. _user_manager: + +Менеджер пользователей +=========================== + +С помощью Менеджера пользователей можно управлять пользователями базы данных: добавлять, редактировать и удалять. + +.. figure:: img/user_manager.png + + Менеджер пользователей + +Для добавления, изменения и удаления пользователя нужно нажать на соответствующую кнопку и заполнить все поля в открывшемся окне. + +.. figure:: img/add_user.png + + Добавление пользователя \ No newline at end of file diff --git a/guide_rst/source/sec-validation.rst b/guide_rst/source/sec-validation.rst new file mode 100644 index 000000000..293438d2b --- /dev/null +++ b/guide_rst/source/sec-validation.rst @@ -0,0 +1,23 @@ +.. _validation: + +Валидация таблиц +=================== + +Проверка базы данных позволяет выполнять низкоуровневые проверки согласованности данных на диске. + +Онлайн-проверка может делать следующее: + +* проверять некоторые (или все) пользовательские таблицы в базе данных; системные таблицы не проверяются; +* проверять некоторые (или все) индексы; + +.. warning:: + + Другие проверки ODS, такие как страницы заголовка (``Header``), ``PIP``, ``TIP``, страницы генераторов (``Generators pages``) не выполняются. + +.. figure:: img/validation.png + + Валидация таблиц + + + + diff --git a/modules/plugins/fbclient-3/pom.xml b/modules/plugins/fbclient-3/pom.xml new file mode 100644 index 000000000..1ef993487 --- /dev/null +++ b/modules/plugins/fbclient-3/pom.xml @@ -0,0 +1,37 @@ + + + 4.0.0 + + + org.executequery + RedExpert-parent + 2024.09 + ../../../pom.xml + + + fbclient-3 + 3.0.15 + jar + + 2019 + + + mrotteveel + Mark Rotteveel + mark@lawinegevaar.nl + + Administrator + + + + + + Initial Developer's Public License Version 1.0 + https://firebirdsql.org/en/initial-developer-s-public-license-version-1-0/ + repo + + + + \ No newline at end of file diff --git a/modules/plugins/fbclient-3/src/main/resources/linux-x86-64/libfbclient.so b/modules/plugins/fbclient-3/src/main/resources/linux-x86-64/libfbclient.so new file mode 100755 index 000000000..c522191e6 Binary files /dev/null and b/modules/plugins/fbclient-3/src/main/resources/linux-x86-64/libfbclient.so differ diff --git a/modules/plugins/fbclient-3/src/main/resources/win32-x86-64/fbclient.dll b/modules/plugins/fbclient-3/src/main/resources/win32-x86-64/fbclient.dll new file mode 100755 index 000000000..0b93ccab1 Binary files /dev/null and b/modules/plugins/fbclient-3/src/main/resources/win32-x86-64/fbclient.dll differ diff --git a/modules/plugins/fbclient-3/src/main/resources/win32-x86/fbclient.dll b/modules/plugins/fbclient-3/src/main/resources/win32-x86/fbclient.dll new file mode 100755 index 000000000..e49fd9430 Binary files /dev/null and b/modules/plugins/fbclient-3/src/main/resources/win32-x86/fbclient.dll differ diff --git a/modules/plugins/fbclient-4/pom.xml b/modules/plugins/fbclient-4/pom.xml new file mode 100644 index 000000000..b7719d66e --- /dev/null +++ b/modules/plugins/fbclient-4/pom.xml @@ -0,0 +1,37 @@ + + + 4.0.0 + + + org.executequery + RedExpert-parent + 2024.09 + ../../../pom.xml + + + fbclient-4 + 4.0.0 + jar + + 2019 + + + mrotteveel + Mark Rotteveel + mark@lawinegevaar.nl + + Administrator + + + + + + Initial Developer's Public License Version 1.0 + https://firebirdsql.org/en/initial-developer-s-public-license-version-1-0/ + repo + + + + \ No newline at end of file diff --git a/modules/plugins/fbclient-4/src/main/resources/linux-x86-64/libfbclient.so b/modules/plugins/fbclient-4/src/main/resources/linux-x86-64/libfbclient.so new file mode 100644 index 000000000..659d62116 Binary files /dev/null and b/modules/plugins/fbclient-4/src/main/resources/linux-x86-64/libfbclient.so differ diff --git a/modules/plugins/fbclient-4/src/main/resources/win32-x86-64/fbclient.dll b/modules/plugins/fbclient-4/src/main/resources/win32-x86-64/fbclient.dll new file mode 100755 index 000000000..80fc1684e Binary files /dev/null and b/modules/plugins/fbclient-4/src/main/resources/win32-x86-64/fbclient.dll differ diff --git a/modules/plugins/fbclient-5/pom.xml b/modules/plugins/fbclient-5/pom.xml new file mode 100644 index 000000000..443b94027 --- /dev/null +++ b/modules/plugins/fbclient-5/pom.xml @@ -0,0 +1,37 @@ + + + 4.0.0 + + + org.executequery + RedExpert-parent + 2024.09 + ../../../pom.xml + + + fbclient-5 + 5.0.0 + jar + + 2019 + + + mrotteveel + Mark Rotteveel + mark@lawinegevaar.nl + + Administrator + + + + + + Initial Developer's Public License Version 1.0 + https://firebirdsql.org/en/initial-developer-s-public-license-version-1-0/ + repo + + + + \ No newline at end of file diff --git a/modules/plugins/fbclient-5/src/main/resources/linux-x86-64/libfbclient.so b/modules/plugins/fbclient-5/src/main/resources/linux-x86-64/libfbclient.so new file mode 100644 index 000000000..659d62116 Binary files /dev/null and b/modules/plugins/fbclient-5/src/main/resources/linux-x86-64/libfbclient.so differ diff --git a/modules/plugins/fbclient-5/src/main/resources/win32-x86-64/fbclient.dll b/modules/plugins/fbclient-5/src/main/resources/win32-x86-64/fbclient.dll new file mode 100755 index 000000000..80fc1684e Binary files /dev/null and b/modules/plugins/fbclient-5/src/main/resources/win32-x86-64/fbclient.dll differ diff --git a/modules/plugins/fbplugin-impl/pom.xml b/modules/plugins/fbplugin-impl/pom.xml index c6b477820..6c393f489 100644 --- a/modules/plugins/fbplugin-impl/pom.xml +++ b/modules/plugins/fbplugin-impl/pom.xml @@ -9,7 +9,7 @@ org.executequery RedExpert-parent - 2024.07 + 2024.09 ../../../pom.xml @@ -26,31 +26,25 @@ + org.executequery fbplugin 1.0 + ru.red-soft.jdbc jaybird-jdk18 ${jaybird4.version} + ru.red-soft.jdbc jaybird-cryptoapi-jdk18 ${jaybird4.version} - - ru.red-soft.jdbc - fbclient - ${jaybird4.version} - - - log4j - log4j - 1.2.17 - + @@ -119,13 +113,6 @@ ../../../lib jaybird-cryptoapi-4.jar - - ru.red-soft.jdbc - fbclient - jar - ../../../lib - fbclient-4.jar - @@ -166,13 +153,6 @@ ../../redexpert/target/lib jaybird-cryptoapi-4.jar - - ru.red-soft.jdbc - fbclient - jar - ../../redexpert/target/lib - fbclient-4.jar - diff --git a/modules/plugins/fbplugin-impl/src/main/java/biz/redsoft/FBBatchCompletionStateImpl.java b/modules/plugins/fbplugin-impl/src/main/java/biz/redsoft/FBBatchCompletionStateImpl.java index 5495dce9e..77f2e8eb3 100644 --- a/modules/plugins/fbplugin-impl/src/main/java/biz/redsoft/FBBatchCompletionStateImpl.java +++ b/modules/plugins/fbplugin-impl/src/main/java/biz/redsoft/FBBatchCompletionStateImpl.java @@ -4,7 +4,7 @@ import java.sql.SQLException; -public class FBBatchCompletionStateImpl implements IFBBatchCompletionState{ +public class FBBatchCompletionStateImpl implements IFBBatchCompletionState { private final FbBatchCompletionState state; @@ -21,4 +21,15 @@ public int[] getAllStates() throws SQLException { public String printAllStates() throws SQLException { return state.printAllStates(); } + + @Override + public int getState(int i) throws SQLException { + return state.getState(i); + } + + @Override + public String getError(int i) throws SQLException { + return state.getError(i); + } + } diff --git a/modules/plugins/fbplugin-impl5/pom.xml b/modules/plugins/fbplugin-impl5/pom.xml index 68ab520c7..5c6042881 100644 --- a/modules/plugins/fbplugin-impl5/pom.xml +++ b/modules/plugins/fbplugin-impl5/pom.xml @@ -9,7 +9,7 @@ org.executequery RedExpert-parent - 2024.07 + 2024.09 ../../../pom.xml @@ -26,31 +26,25 @@ + org.executequery fbplugin 1.0 + ru.red-soft.jdbc jaybird-jdk18 ${jaybird5.version} + ru.red-soft.jdbc jaybird-cryptoapi-jdk18 ${jaybird5.version} - - ru.red-soft.jdbc - fbclient - ${jaybird4.version} - - - log4j - log4j - 1.2.17 - + @@ -103,13 +97,6 @@ ../../../lib jaybird-cryptoapi-5.jar - - ru.red-soft.jdbc - fbclient - jar - ../../../lib - fbclient-5.jar - @@ -134,13 +121,6 @@ ../../redexpert/target/lib jaybird-cryptoapi-5.jar - - ru.red-soft.jdbc - fbclient - jar - ../../redexpert/target/lib - fbclient-5.jar - diff --git a/modules/plugins/fbplugin-impl5/src/main/java/biz/redsoft/FBBatchCompletionStateImpl.java b/modules/plugins/fbplugin-impl5/src/main/java/biz/redsoft/FBBatchCompletionStateImpl.java index 44753de66..77f2e8eb3 100644 --- a/modules/plugins/fbplugin-impl5/src/main/java/biz/redsoft/FBBatchCompletionStateImpl.java +++ b/modules/plugins/fbplugin-impl5/src/main/java/biz/redsoft/FBBatchCompletionStateImpl.java @@ -21,4 +21,15 @@ public int[] getAllStates() throws SQLException { public String printAllStates() throws SQLException { return state.printAllStates(); } + + @Override + public int getState(int i) throws SQLException { + return state.getState(i); + } + + @Override + public String getError(int i) throws SQLException { + return state.getError(i); + } + } diff --git a/modules/plugins/fbplugin/pom.xml b/modules/plugins/fbplugin/pom.xml index 270246547..491d77f6b 100644 --- a/modules/plugins/fbplugin/pom.xml +++ b/modules/plugins/fbplugin/pom.xml @@ -17,7 +17,7 @@ org.executequery RedExpert-parent - 2024.07 + 2024.09 ../../../pom.xml diff --git a/modules/plugins/fbplugin/src/main/java/biz/redsoft/IFBBatchCompletionState.java b/modules/plugins/fbplugin/src/main/java/biz/redsoft/IFBBatchCompletionState.java index a20948edf..d1b5469ce 100644 --- a/modules/plugins/fbplugin/src/main/java/biz/redsoft/IFBBatchCompletionState.java +++ b/modules/plugins/fbplugin/src/main/java/biz/redsoft/IFBBatchCompletionState.java @@ -7,4 +7,9 @@ public interface IFBBatchCompletionState { int[] getAllStates() throws SQLException; String printAllStates() throws SQLException; + + int getState(int i) throws SQLException; + + String getError(int i) throws SQLException; + } diff --git a/modules/plugins/procedure-parser/pom.xml b/modules/plugins/procedure-parser/pom.xml index ecddb2efa..76e260fd6 100644 --- a/modules/plugins/procedure-parser/pom.xml +++ b/modules/plugins/procedure-parser/pom.xml @@ -15,7 +15,7 @@ org.executequery RedExpert-parent - 2024.07 + 2024.09 ../../../pom.xml diff --git a/modules/plugins/sql-parser/pom.xml b/modules/plugins/sql-parser/pom.xml index 08054a72e..1fc948589 100644 --- a/modules/plugins/sql-parser/pom.xml +++ b/modules/plugins/sql-parser/pom.xml @@ -6,7 +6,7 @@ org.executequery RedExpert-parent - 2024.07 + 2024.09 ../../../pom.xml 1.0 diff --git a/modules/plugins/sqlLexer/pom.xml b/modules/plugins/sqlLexer/pom.xml index 4d0c766c9..f92be755e 100644 --- a/modules/plugins/sqlLexer/pom.xml +++ b/modules/plugins/sqlLexer/pom.xml @@ -15,7 +15,7 @@ org.executequery RedExpert-parent - 2024.07 + 2024.09 ../../../pom.xml diff --git a/modules/plugins/trace-parser/pom.xml b/modules/plugins/trace-parser/pom.xml index 15a4a2562..19670f14d 100644 --- a/modules/plugins/trace-parser/pom.xml +++ b/modules/plugins/trace-parser/pom.xml @@ -15,7 +15,7 @@ org.executequery RedExpert-parent - 2024.07 + 2024.09 ../../../pom.xml diff --git a/modules/redexpert/pom.xml b/modules/redexpert/pom.xml index 6fa19408b..b861a98a0 100644 --- a/modules/redexpert/pom.xml +++ b/modules/redexpert/pom.xml @@ -14,7 +14,7 @@ org.executequery RedExpert-parent ../../pom.xml - 2024.07 + 2024.09 @@ -25,6 +25,24 @@ 1.0 + + org.executequery + fbclient-3 + 3.0.15 + + + + org.executequery + fbclient-4 + 4.0.0 + + + + org.executequery + fbclient-5 + 5.0.0 + + xerces xercesImpl @@ -142,7 +160,7 @@ net.java.dev.jna jna - 5.5.0 + 5.14.0 @@ -154,7 +172,7 @@ net.java.dev.jna jna-platform - 5.5.0 + 5.14.0 @@ -249,28 +267,6 @@ - - com.googlecode.addjars-maven-plugin - addjars-maven-plugin - 1.0.5 - - - - add-jars - - - - - ${pom.basedir}/../../lib - - **/fbclient.jar - - - - - - - maven-resources-plugin 3.0.2 @@ -394,6 +390,19 @@ copy-dependencies + fbclient-3,fbclient-4,fbclient-5 + ${project.build.directory}/lib + + + + copy-fbclient-libs + package + + copy-dependencies + + + true + fbclient-3,fbclient-4,fbclient-5 ${project.build.directory}/lib diff --git a/pom.xml b/pom.xml index 69018c968..22c3b45a0 100644 --- a/pom.xml +++ b/pom.xml @@ -6,15 +6,18 @@ 4.7 3.0.36 - 4.0.28 - 5.0.17 + 4.0.30 + 5.0.18 org.executequery RedExpert-parent pom - 2024.07 + 2024.09 modules/plugins/fbplugin + modules/plugins/fbclient-3 + modules/plugins/fbclient-4 + modules/plugins/fbclient-5 modules/plugins/fbplugin-impl modules/plugins/fbplugin-impl5 modules/plugins/sql-parser diff --git a/src/org/executequery/Application.java b/src/org/executequery/Application.java index 9652c426a..623363236 100644 --- a/src/org/executequery/Application.java +++ b/src/org/executequery/Application.java @@ -51,17 +51,9 @@ public static synchronized Application getInstance() { public void exitProgram() { if (promptToSave() && GUIUtilities.getOpenSaveFunctionCount() > 0) { - - SaveOnExitDialog exitDialog = new SaveOnExitDialog(); - - int result = exitDialog.getResult(); - if (result != SaveFunction.SAVE_COMPLETE || - result != SaveOnExitDialog.DISCARD_OPTION) { - - exitDialog = null; + int result = new SaveOnExitDialog().getResult(); + if (result != SaveFunction.SAVE_COMPLETE && result != SaveFunction.SAVE_CANCELLED) return; - } - } releaseConnections(); diff --git a/src/org/executequery/CheckForUpdateNotifier.java b/src/org/executequery/CheckForUpdateNotifier.java index 5843b3951..d2794abbd 100644 --- a/src/org/executequery/CheckForUpdateNotifier.java +++ b/src/org/executequery/CheckForUpdateNotifier.java @@ -350,9 +350,9 @@ private void startUpdate() { argsList.add("-root=" + updateLoader.getRoot()); argsList.add("-launch=" + restartNow); - File file = new File("RedExpert.jar"); + File file = new File(CheckForUpdateNotifier.class.getProtectionDomain().getCodeSource().getLocation().toURI()); if (!file.exists()) - file = new File("../RedExpert.jar"); + throw new Exception("Couldn't locale application JAR file (RedExpert.jar)"); String javaPath = "java"; if (!System.getProperty("os.name").toLowerCase().contains("win")) diff --git a/src/org/executequery/GUIUtilities.java b/src/org/executequery/GUIUtilities.java index a933e3823..15bbf7bf9 100644 --- a/src/org/executequery/GUIUtilities.java +++ b/src/org/executequery/GUIUtilities.java @@ -1363,6 +1363,10 @@ public static int displayYesNoDialog(Object message, String title) { return GUIUtils.displayYesNoDialog(getInFocusDialogOrWindow(), message, title); } + public static int displayYesNoCancelDialog(Object message, String title) { + return GUIUtils.displayYesNoCancelDialog(getInFocusDialogOrWindow(), message, title); + } + public static int displayConfirmCancelDialog(Object message) { return GUIUtils.displayConfirmCancelDialog(getInFocusDialogOrWindow(), message); } diff --git a/src/org/executequery/actions/databasecommands/ImportConnectionsFromDBCommand.java b/src/org/executequery/actions/databasecommands/ImportConnectionsFromDBCommand.java index 41884b615..c79d6b59f 100644 --- a/src/org/executequery/actions/databasecommands/ImportConnectionsFromDBCommand.java +++ b/src/org/executequery/actions/databasecommands/ImportConnectionsFromDBCommand.java @@ -10,12 +10,14 @@ public class ImportConnectionsFromDBCommand extends OpenFrameCommand implements BaseCommand { + @Override public void execute(ActionEvent e) { - try { - - GUIUtilities.showWaitCursor(); + if (!isConnected()) + return; + GUIUtilities.showWaitCursor(); + try { BaseDialog dialog = new BaseDialog(ImportConnectionsDBPanel.TITLE, true); ImportConnectionsDBPanel panel = new ImportConnectionsDBPanel(dialog); @@ -23,10 +25,8 @@ public void execute(ActionEvent e) { dialog.display(); } finally { - GUIUtilities.showNormalCursor(); } - } -} \ No newline at end of file +} diff --git a/src/org/executequery/actions/filecommands/OpenCommand.java b/src/org/executequery/actions/filecommands/OpenCommand.java index 7c49b1cb8..06c60a80f 100644 --- a/src/org/executequery/actions/filecommands/OpenCommand.java +++ b/src/org/executequery/actions/filecommands/OpenCommand.java @@ -182,7 +182,7 @@ private void openNewQueryEditor(File file, String contents) { GUIUtilities.addCentralPane( QueryEditor.TITLE, QueryEditor.FRAME_ICON, - new QueryEditor(contents, file.getAbsolutePath()), + new QueryEditor(contents, file.getAbsolutePath(), -1), null, true ); diff --git a/src/org/executequery/actions/toolscommands/ConsoleCommand.java b/src/org/executequery/actions/toolscommands/ConsoleCommand.java index 6f057d68f..da0746de7 100644 --- a/src/org/executequery/actions/toolscommands/ConsoleCommand.java +++ b/src/org/executequery/actions/toolscommands/ConsoleCommand.java @@ -34,26 +34,15 @@ */ public class ConsoleCommand implements BaseCommand { + @Override public void execute(ActionEvent e) { - GUIUtilities.addDockedTab(ConsolePanel.TITLE, - new ConsolePanel(), + ConsolePanel consolePanel = new ConsolePanel(); + GUIUtilities.addDockedTab( + consolePanel.getTitle(), + consolePanel, SwingConstants.SOUTH, - true); + true + ); } } - - - - - - - - - - - - - - - diff --git a/src/org/executequery/components/ConnectionsComboBox.java b/src/org/executequery/components/ConnectionsComboBox.java deleted file mode 100644 index 19005f7c7..000000000 --- a/src/org/executequery/components/ConnectionsComboBox.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * ConnectionsComboBox.java - * - * Copyright (C) 2002-2017 Takis Diakoumis - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 3 - * of the License, or any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -package org.executequery.components; - -import org.executequery.databasemediators.DatabaseConnection; -import org.executequery.datasource.ConnectionManager; - -import javax.swing.*; -import java.util.List; - -/** - * Combo box pre-populated with database connection objects. - * - * @author Takis Diakoumis - */ -public class ConnectionsComboBox extends JComboBox { - - /** - * the selection model - */ - private ConnectionSelectionModel model; - - /** - * Creates a new instance of ConnectionsComboBox - */ - public ConnectionsComboBox() { - model = new ConnectionSelectionModel(); - setModel(model); - } - - public DatabaseConnection getSelectedConnection() { - return (DatabaseConnection) model.getSelectedItem(); - } - - private static class ConnectionSelectionModel extends DefaultComboBoxModel { - - /** - * the selected item - */ - private DatabaseConnection selectedItem; - - /** - * the database connections vector - */ - private List connections; - - public ConnectionSelectionModel() { - connections = ConnectionManager.getActiveConnections(); - } - - public void addElement(Object object) { - connections.add((DatabaseConnection) object); - int index = connections.indexOf((DatabaseConnection) object); - fireContentsChanged(this, index, index); - } - - public void setSelectedItem(Object object) { - selectedItem = (DatabaseConnection) object; - } - - public void removeAllElements() { - connections.clear(); - selectedItem = null; - } - - public void removeElement(Object object) { - connections.remove((DatabaseConnection) object); - } - - public Object getSelectedItem() { - return selectedItem; - } - - public int getIndexOf(Object object) { - return connections.indexOf((DatabaseConnection) object); - } - - public int getSize() { - return connections.size(); - } - } - -} - diff --git a/src/org/executequery/components/TableSelectionCombosGroup.java b/src/org/executequery/components/TableSelectionCombosGroup.java deleted file mode 100644 index 97c513a4f..000000000 --- a/src/org/executequery/components/TableSelectionCombosGroup.java +++ /dev/null @@ -1,490 +0,0 @@ -/* - * TableSelectionCombosGroup.java - * - * Copyright (C) 2002-2017 Takis Diakoumis - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 3 - * of the License, or any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -package org.executequery.components; - -import org.executequery.ApplicationException; -import org.executequery.databasemediators.DatabaseConnection; -import org.executequery.databaseobjects.*; -import org.executequery.databaseobjects.impl.DatabaseObjectFactoryImpl; -import org.executequery.datasource.ConnectionManager; -import org.executequery.gui.WidgetFactory; -import org.executequery.localization.Bundles; -import org.executequery.log.Log; -import org.executequery.util.ThreadUtils; -import org.underworldlabs.jdbc.DataSourceException; -import org.underworldlabs.swing.DynamicComboBoxModel; - -import javax.swing.*; -import java.awt.event.ItemEvent; -import java.awt.event.ItemListener; -import java.util.ArrayList; -import java.util.List; -import java.util.Vector; - -/** - * Combo box group controller containing connection -> table - * selection combo boxes. - * - * @author Takis Diakoumis - */ -public class TableSelectionCombosGroup implements ItemListener { - - private final JComboBox connectionsCombo; - - private final JComboBox tablesCombo; - - private final JComboBox columnsCombo; - - private List itemListeners; - - public TableSelectionCombosGroup() { - this(WidgetFactory.createComboBox("connectionsCombo"), WidgetFactory.createComboBox("tableCombo"), null); - } - - public TableSelectionCombosGroup(JComboBox connectionsCombo) { - this(connectionsCombo, null, null); - } - - public TableSelectionCombosGroup(JComboBox connectionsCombo, JComboBox tablesCombo, JComboBox columnsCombo) { - - super(); - - this.connectionsCombo = connectionsCombo; - this.tablesCombo = tablesCombo; - this.columnsCombo = columnsCombo; - - init(); - - connectionSelected(); - } - - private void init() { - - initConnectionsCombo(connectionsCombo); - - if (tablesCombo != null) - initTablesCombo(tablesCombo); - - if (columnsCombo != null) - initTablesCombo(columnsCombo); - } - - public void connectionOpened(DatabaseConnection databaseConnection) { - - DynamicComboBoxModel model = connectionComboModel(); - model.addElement(databaseObjectFactory().createDatabaseHost(databaseConnection)); - } - - public void connectionClosed(DatabaseConnection databaseConnection) { - - DynamicComboBoxModel model = connectionComboModel(); - - DatabaseHost host = null; - DatabaseHost selectedHost = getSelectedHost(); - - if (selectedHost.getDatabaseConnection() == databaseConnection) { - - host = selectedHost; - - } else { - - host = hostForConnection(databaseConnection); - } - - if (host != null) { - - model.removeElement(host); - } - - } - - private DynamicComboBoxModel connectionComboModel() { - - return (DynamicComboBoxModel) connectionsCombo.getModel(); - } - - private DatabaseHost hostForConnection(DatabaseConnection databaseConnection) { - - ComboBoxModel model = connectionComboModel(); - - for (int i = 0, n = model.getSize(); i < n; i++) { - - DatabaseHost host = (DatabaseHost) model.getElementAt(i); - - if (host.getDatabaseConnection() == databaseConnection) { - - return host; - } - - } - - return null; - } - - public void addItemSelectionListener(ItemSelectionListener listener) { - - if (itemListeners == null) { - - itemListeners = new ArrayList(); - } - - itemListeners.add(listener); - } - - public DatabaseHost getSelectedHost() { - - return (DatabaseHost) connectionsCombo.getSelectedItem(); - } - - public void setSelectedDatabaseHost(DatabaseHost databaseHost) { - - if (connectionsCombo.getSelectedItem() == databaseHost) { - - return; - } - - try { - - connectionSelectionPending = true; - - if (comboContains(connectionsCombo, databaseHost)) { - - connectionsCombo.setSelectedItem(databaseHost); - - } else { - - ComboBoxModel model = connectionComboModel(); - - String connectionId = databaseHost.getDatabaseConnection().getId(); - - for (int i = 0, n = model.getSize(); i < n; i++) { - - DatabaseHost host = (DatabaseHost) model.getElementAt(i); - - if (connectionId.equals(host.getDatabaseConnection().getId())) { - - connectionsCombo.setSelectedItem(host); - break; - } - - } - - } - - connectionSelected(); - - } finally { - - connectionSelectionPending = false; - } - - } - - private boolean comboContains(JComboBox comboBox, Object item) { - - return ((DynamicComboBoxModel) comboBox.getModel()).contains(item); - } - - private boolean connectionSelectionPending; - private boolean tableSelectionPending; - - public void setSelectedDatabaseTable(DatabaseTable databaseTable) { - - if (tablesCombo.getSelectedItem() == databaseTable) { - - return; - } - - if (comboContains(tablesCombo, databaseTable)) { - - tablesCombo.setSelectedItem(databaseTable); - - } else { - - setSelectedDatabaseHost(databaseTable.getDatabaseSource().getHost()); - - try { - - tableSelectionPending = true; - - ComboBoxModel model = tablesCombo.getModel(); - - String tableName = databaseTable.getName(); - - for (int i = 0, n = model.getSize(); i < n; i++) { - - DatabaseTable table = (DatabaseTable) model.getElementAt(i); - - if (tableName.equals(table.getName())) { - - tablesCombo.setSelectedItem(table); - break; - } - - } - - } finally { - - tableSelectionPending = false; - } - - } - - } - - public DatabaseTable getSelectedTable() { - - if (tablesCombo.getSelectedItem() != null) { - - return (DatabaseTable) tablesCombo.getSelectedItem(); - } - - return null; - } - - public DatabaseColumn getSelectedColumn() { - - if (columnsCombo.getSelectedItem() != null) { - - return (DatabaseColumn) columnsCombo.getSelectedItem(); - } - - return null; - } - - public void itemStateChanged(final ItemEvent e) { - - if (selectionPending() || (e.getStateChange() == ItemEvent.DESELECTED)) { - - return; - } - - final Object source = e.getSource(); - - ThreadUtils.startWorker(new Runnable() { - public void run() { - - try { - - fireItemStateChanging(e); - - if (source == connectionsCombo) { - - connectionSelected(); - - } else if (source == tablesCombo) { - - tableSelected(); - } - - } finally { - - fireItemStateChanged(e); - } - - } - }); - - } - - private boolean selectionPending() { - return connectionSelectionPending || tableSelectionPending; - } - - private synchronized void fireItemStateChanged(ItemEvent e) { - - if (hasItemListeners()) { - - for (ItemSelectionListener listener : itemListeners) { - - listener.itemStateChanged(e); - } - - } - - } - - private synchronized void fireItemStateChanging(ItemEvent e) { - - if (hasItemListeners()) { - - for (ItemSelectionListener listener : itemListeners) { - - listener.itemStateChanging(e); - } - - } - - } - - private boolean hasItemListeners() { - - return (itemListeners != null && !itemListeners.isEmpty()); - } - - private void connectionSelected() { - clearCombos(); - } - - private void tableSelected() { - - if (columnsCombo != null) { - - try { - - DatabaseTable table = getSelectedTable(); - - if (table != null) { - - List columns = table.getColumns(); - - populateModelForCombo(columnsCombo, columns); - - } else { - - populateModelForCombo(columnsCombo, null); - } - - } catch (DataSourceException e) { - - handleDataSourceException(e); - } - - } - - } - - private void populateModelForCombo(JComboBox comboBox, List list) { - - if (comboBox == null) { - - return; - } - - DynamicComboBoxModel model = (DynamicComboBoxModel) comboBox.getModel(); - - if (list != null && !list.isEmpty()) { - - try { - - comboBox.removeItemListener(this); - model.setElements(list); - - } finally { - - comboBox.addItemListener(this); - } - - comboBox.setEnabled(true); - - } else { - - try { - - comboBox.removeItemListener(this); - model.removeAllElements(); - - } finally { - - comboBox.addItemListener(this); - } - - comboBox.setEnabled(false); - } - - } - - private void clearCombos() { - if (tablesCombo != null) - populateModelForCombo(tablesCombo, null); - } - - private void initTablesCombo(JComboBox comboBox) { - - comboBox.setModel(new DynamicComboBoxModel()); - initComboBox(comboBox); - } - - private void initConnectionsCombo(JComboBox comboBox) { - - DatabaseObjectFactory factory = databaseObjectFactory(); - - Vector hosts = new Vector(); - - for (DatabaseConnection connection : activeConnections()) { - - hosts.add(factory.createDatabaseHost(connection)); - } - - ComboBoxModel model = new DynamicComboBoxModel(hosts); - - comboBox.setModel(model); - initComboBox(comboBox); - comboBox.setEnabled(true); - } - - private void initComboBox(JComboBox comboBox) { - - comboBox.addItemListener(this); - comboBox.setEnabled(false); - } - - private DatabaseObjectFactory databaseObjectFactory() { - - return new DatabaseObjectFactoryImpl(); - } - - private Vector activeConnections() { - - return ConnectionManager.getActiveConnections(); - } - - private void handleDataSourceException(DataSourceException e) { - - Log.error(bundleString("error.selection-object"), e); - - throw new ApplicationException(e); - } - - public void close() { - - ComboBoxModel model = connectionComboModel(); - - for (int i = 0, n = model.getSize(); i < n; i++) { - - DatabaseHost host = (DatabaseHost) model.getElementAt(i); - host.close(); - } - } - - public JComboBox getConnectionsCombo() { - return connectionsCombo; - } - - public JComboBox getTablesCombo() { - return tablesCombo; - } - - public String bundleString(String key) { - return Bundles.get(getClass(), key); - } - -} diff --git a/src/org/executequery/connection-folders-default.xml b/src/org/executequery/connection-folders-default.xml index 06904e3f9..61de7bb22 100644 --- a/src/org/executequery/connection-folders-default.xml +++ b/src/org/executequery/connection-folders-default.xml @@ -13,10 +13,4 @@ - - 61a05e8a-df1c-44fd-b8b7-8684691ee6ca - Favourites - - - diff --git a/src/org/executequery/databaseobjects/DatabaseTable.java b/src/org/executequery/databaseobjects/DatabaseTable.java index 84040fc0d..14c7cb1e5 100644 --- a/src/org/executequery/databaseobjects/DatabaseTable.java +++ b/src/org/executequery/databaseobjects/DatabaseTable.java @@ -192,8 +192,14 @@ public interface DatabaseTable extends DatabaseTableObject { String prepareStatementWithPK(List columns); + String prepareStatementInMonTable(List columns); + String prepareStatementDeletingWithPK(); + String[] getMonField(); + + String prepareStatementDeletingFromMonTable(); + List getPrimaryKeyColumnNames(); boolean hasForeignKey(); diff --git a/src/org/executequery/databaseobjects/TableDataChangeWorker.java b/src/org/executequery/databaseobjects/TableDataChangeWorker.java index c09a59633..610d5089d 100644 --- a/src/org/executequery/databaseobjects/TableDataChangeWorker.java +++ b/src/org/executequery/databaseobjects/TableDataChangeWorker.java @@ -67,6 +67,8 @@ public boolean apply(List rows) { if (row.get(0).isDeleted()) { if (table != null && table.hasPrimaryKey()) result += executeDeletingWithPK(connection, table, row); + else if (table != null && table.getMonField() != null) + result += executeDeletingFromMonTable(connection, table, row); else result += executedDeleting(connection, tableObject, row); @@ -76,6 +78,9 @@ public boolean apply(List rows) { } else if (table != null && table.hasPrimaryKey()) { result += executeWithPK(connection, table, row); + } else if (table != null && table.getMonField() != null) { + result += executeInMonTable(connection, table, row); + } else result += executeChange(connection, tableObject, row); } @@ -172,6 +177,70 @@ private int executeWithPK(Connection connection, DatabaseTable table, List values) { + + List columns = new ArrayList(); + List changes = new ArrayList(); + for (RecordDataItem item : values) { + + if (item.isChanged()) { + + changes.add(item); + columns.add(item.getName()); + } + + } + + if (changes.isEmpty()) { + + return 0; + } + + try { + + int n = changes.size(); + String sql = table.prepareStatementInMonTable(columns); + + Log.info("Executing data change using statement - [ " + sql + " ]"); + + statement = connection.prepareStatement(sql); + for (int i = 0; i < n; i++) { + + RecordDataItem recordDataItem = changes.get(i); + if (!recordDataItem.isNewValueNull()) { + + statement.setObject((i + 1), recordDataItem.getNewValue(), recordDataItem.getDataType()); + + } else { + + statement.setNull((i + 1), Types.NULL); + } + + } + n++; + statement.setObject(n, valueForKey(table.getMonField()[1], values)); + return statement.executeUpdate(); + + } catch (Exception e) { + + rollback(); + throw handleException(e); + + } finally { + + if (statement != null) { + + try { + statement.close(); + } catch (SQLException e) { + } + statement = null; + } + + } + + } + private int executeDeletingWithPK(Connection connection, DatabaseTable table, List values) { List columns = new ArrayList(); @@ -229,6 +298,56 @@ private int executeDeletingWithPK(Connection connection, DatabaseTable table, Li } + private int executeDeletingFromMonTable(Connection connection, DatabaseTable table, List values) { + + List columns = new ArrayList(); + List changes = new ArrayList(); + for (RecordDataItem item : values) { + + if (item.isDeleted()) { + + changes.add(item); + columns.add(item.getName()); + } + + } + + if (changes.isEmpty()) { + + return 0; + } + + try { + String sql = table.prepareStatementDeletingFromMonTable(); + + Log.info("Executing data change using statement - [ " + sql + " ]"); + + statement = connection.prepareStatement(sql); + statement.setObject(1, valueForKey(table.getMonField()[1], values)); + + + return statement.executeUpdate(); + + } catch (Exception e) { + + rollback(); + throw handleException(e); + + } finally { + + if (statement != null) { + + try { + statement.close(); + } catch (SQLException e) { + } + statement = null; + } + + } + + } + private int executeAdding(Connection connection, DatabaseTableObject table, List values) { List columns = new ArrayList(); List changes = new ArrayList(); diff --git a/src/org/executequery/databaseobjects/impl/DefaultDatabaseCollation.java b/src/org/executequery/databaseobjects/impl/DefaultDatabaseCollation.java index 997ca5613..ef24525b5 100644 --- a/src/org/executequery/databaseobjects/impl/DefaultDatabaseCollation.java +++ b/src/org/executequery/databaseobjects/impl/DefaultDatabaseCollation.java @@ -80,7 +80,8 @@ protected SelectBuilder builderCommonQuery() { SelectBuilder sb = new SelectBuilder(getHost().getDatabaseConnection()); Table collates = getMainTable(); Table charsets = Table.createTable("RDB$CHARACTER_SETS", "CH"); - sb.appendFields(collates, getFieldName(), BASE_COLLATE, ATTRIBUTES, DESCRIPTION, COLLATION_ATTRIBUTES); + sb.appendField(Field.createField(collates, getFieldName()).setCast("VARCHAR(1024)")); + sb.appendFields(collates, BASE_COLLATE, ATTRIBUTES, DESCRIPTION, COLLATION_ATTRIBUTES); sb.appendFields(charsets, CHARACTER_SET_NAME); sb.appendJoin(Join.createLeftJoin().appendFields(Field.createField(collates, CHARACTER_SET_ID), Field.createField(charsets, CHARACTER_SET_ID))); sb.setOrdering(getObjectField().getFieldTable()); @@ -225,7 +226,7 @@ public String getDropSQL() throws DataSourceException { public String getCompareAlterSQL(AbstractDatabaseObject databaseObject) throws DataSourceException { String comparingSqlQuery = databaseObject.getCompareCreateSQL(); return !Objects.equals(this.getCompareCreateSQL(), comparingSqlQuery) ? - getDropSQL() + comparingSqlQuery : "/* there are no changes */\n"; + getDropSQL() + comparingSqlQuery : SQLUtils.THERE_ARE_NO_CHANGES; } } diff --git a/src/org/executequery/databaseobjects/impl/DefaultDatabaseDomain.java b/src/org/executequery/databaseobjects/impl/DefaultDatabaseDomain.java index d3429c6db..241e6b6c3 100644 --- a/src/org/executequery/databaseobjects/impl/DefaultDatabaseDomain.java +++ b/src/org/executequery/databaseobjects/impl/DefaultDatabaseDomain.java @@ -73,8 +73,9 @@ protected SelectBuilder builderCommonQuery() { Table collations = Table.createTable("RDB$COLLATIONS", "CO"); Table dimensions = Table.createTable("RDB$FIELD_DIMENSIONS", "FD"); + sb.appendField(Field.createField(fields, getFieldName()).setCast("VARCHAR(1024)")); sb.appendFields(fields, - FIELD_NAME, TYPE, SUB_TYPE, FIELD_PRECISION, SCALE, FIELD_LENGTH, NULL_FLAG, + TYPE, SUB_TYPE, FIELD_PRECISION, SCALE, FIELD_LENGTH, NULL_FLAG, COMPUTED_BY, VALIDATION_SOURCE, DEFAULT_SOURCE, COMPUTED_SOURCE, SEGMENT_LENGTH, DESCRIPTION ); sb.appendField(Field.createField(fields, "CHARACTER_LENGTH").setAlias(CHAR_LENGTH)); diff --git a/src/org/executequery/databaseobjects/impl/DefaultDatabaseException.java b/src/org/executequery/databaseobjects/impl/DefaultDatabaseException.java index 0472f95aa..e1a9faa0f 100644 --- a/src/org/executequery/databaseobjects/impl/DefaultDatabaseException.java +++ b/src/org/executequery/databaseobjects/impl/DefaultDatabaseException.java @@ -2,6 +2,7 @@ import org.executequery.databaseobjects.DatabaseMetaTag; import org.executequery.gui.browser.comparer.Comparer; +import org.executequery.sql.sqlbuilder.Field; import org.executequery.sql.sqlbuilder.SelectBuilder; import org.executequery.sql.sqlbuilder.Table; import org.underworldlabs.jdbc.DataSourceException; @@ -96,7 +97,8 @@ protected Table getMainTable() { protected SelectBuilder builderCommonQuery() { SelectBuilder sb = new SelectBuilder(getHost().getDatabaseConnection()); Table mainTable = getMainTable(); - sb.appendFields(mainTable, getFieldName(), ID, EXCEPTION_TEXT, DESCRIPTION); + sb.appendField(Field.createField(mainTable, getFieldName()).setCast("VARCHAR(1024)")); + sb.appendFields(mainTable, ID, EXCEPTION_TEXT, DESCRIPTION); sb.appendTable(mainTable); sb.setOrdering(getObjectField().getFieldTable()); return sb; diff --git a/src/org/executequery/databaseobjects/impl/DefaultDatabaseFunction.java b/src/org/executequery/databaseobjects/impl/DefaultDatabaseFunction.java index d2a846fe3..b27ce94ce 100644 --- a/src/org/executequery/databaseobjects/impl/DefaultDatabaseFunction.java +++ b/src/org/executequery/databaseobjects/impl/DefaultDatabaseFunction.java @@ -168,7 +168,7 @@ public String getDropSQL() throws DataSourceException { @Override public String getCompareAlterSQL(AbstractDatabaseObject databaseObject) throws DataSourceException { return (!this.getCompareCreateSQL().equals(databaseObject.getCompareCreateSQL())) ? - databaseObject.getCompareCreateSQL() : "/* there are no changes */"; + databaseObject.getCompareCreateSQL() : SQLUtils.THERE_ARE_NO_CHANGES; } protected static final String FA = "FA_"; @@ -207,7 +207,8 @@ protected SelectBuilder builderCommonQuery() { Table charsets = Table.createTable("RDB$CHARACTER_SETS", "CR"); Table collations1 = Table.createTable("RDB$COLLATIONS", "CO1"); Table collations2 = Table.createTable("RDB$COLLATIONS", "CO2"); - sb.appendFields(functions, getFieldName(), PROCEDURE_SOURCE, DESCRIPTION, DETERMINISTIC_FLAG, RETURN_ARGUMENT, VALID_BLR); + sb.appendField(Field.createField(functions, getFieldName()).setCast("VARCHAR(1024)")); + sb.appendFields(functions, PROCEDURE_SOURCE, DESCRIPTION, DETERMINISTIC_FLAG, RETURN_ARGUMENT, VALID_BLR); sb.appendFields(functions, !externalCheck(), ENGINE_NAME, ENTRYPOINT); sb.appendField(buildSqlSecurityField(functions)); sb.appendFields(FA, arguments, PARAMETER_NAME, PARAMETER_NUMBER, FIELD_SOURCE, DESCRIPTION, PARAMETER_MECHANISM, DEFAULT_SOURCE, RELATION_NAME, FIELD_NAME, NULL_FLAG); diff --git a/src/org/executequery/databaseobjects/impl/DefaultDatabaseIndex.java b/src/org/executequery/databaseobjects/impl/DefaultDatabaseIndex.java index 41c6d3777..bf755d503 100644 --- a/src/org/executequery/databaseobjects/impl/DefaultDatabaseIndex.java +++ b/src/org/executequery/databaseobjects/impl/DefaultDatabaseIndex.java @@ -298,10 +298,11 @@ public String getExpression() { } public void setExpression(String expression) { - if (MiscUtils.isNull(expression)) - return; - expression = expression.trim().substring(1, expression.trim().length() - 1); this.expression = expression; + if (!MiscUtils.isNull(expression)) { + expression = expression.trim().substring(1, expression.trim().length() - 1); + this.expression = expression; + } } @Override @@ -321,7 +322,7 @@ protected SelectBuilder builderCommonQuery() { Table constraints = Table.createTable("RDB$RELATION_CONSTRAINTS", "RC"); Table indexSegments = Table.createTable("RDB$INDEX_SEGMENTS", "ISGMT"); - sb.appendField(Field.createField(indicies, getFieldName())); + sb.appendField(Field.createField(indicies, getFieldName()).setCast("VARCHAR(1024)")); sb.appendField(Field.createField(indicies, RELATION_NAME)); sb.appendField(Field.createField(indicies, INDEX_TYPE)); sb.appendField(Field.createField(indicies, UNIQUE_FLAG)); diff --git a/src/org/executequery/databaseobjects/impl/DefaultDatabaseJob.java b/src/org/executequery/databaseobjects/impl/DefaultDatabaseJob.java index 35b27dbba..c019b9f19 100644 --- a/src/org/executequery/databaseobjects/impl/DefaultDatabaseJob.java +++ b/src/org/executequery/databaseobjects/impl/DefaultDatabaseJob.java @@ -3,6 +3,7 @@ import org.executequery.databasemediators.spi.DefaultStatementExecutor; import org.executequery.databaseobjects.DatabaseMetaTag; import org.executequery.databaseobjects.NamedObject; +import org.executequery.sql.sqlbuilder.Field; import org.executequery.sql.sqlbuilder.SelectBuilder; import org.executequery.sql.sqlbuilder.Table; import org.underworldlabs.jdbc.DataSourceException; @@ -17,14 +18,15 @@ public class DefaultDatabaseJob extends AbstractDatabaseObject { public static final int PSQL_TYPE = 0; public static final int BASH_TYPE = 1; + private String id; private String source; - private boolean active; - private int jobType; + private Boolean active; + private Integer jobType; + private String database; private String cronSchedule; private LocalDateTime startDate; private LocalDateTime endDate; - private String database; public DefaultDatabaseJob(DatabaseMetaTag metaTagParent, String name) { super(metaTagParent, name); @@ -62,7 +64,7 @@ protected SelectBuilder builderCommonQuery() { SelectBuilder sb = new SelectBuilder(getHost().getDatabaseConnection()); Table jobs = getMainTable(); sb.appendTable(jobs); - + sb.appendField(Field.createField(jobs, getFieldName()).setCast("VARCHAR(1024)")); sb.appendFields(jobs, JOB_ID, SOURCE, ACTIVE, JOB_TYPE, SCHEDULE, START_DATE, END_DATE, DATABASE, DESCRIPTION); sb.setOrdering(getObjectField().getFieldTable()); return sb; @@ -155,6 +157,8 @@ public String getCompareAlterSQL(AbstractDatabaseObject databaseObject) throws D } public String getId() { + if (id == null || isMarkedForReload()) + getObjectInfo(); return id; } @@ -164,9 +168,8 @@ public void setId(String id) { @Override public String getSource() { - if (source == null || isMarkedForReload()) { + if (source == null || isMarkedForReload()) getObjectInfo(); - } return source; } @@ -176,6 +179,8 @@ public void setSource(String source) { } public boolean isActive() { + if (active == null || isMarkedForReload()) + getObjectInfo(); return active; } @@ -184,6 +189,8 @@ public void setActive(boolean active) { } public int getJobType() { + if (jobType == null || isMarkedForReload()) + getObjectInfo(); return jobType; } @@ -192,9 +199,8 @@ public void setJobType(int jobType) { } public String getCronSchedule() { - if (cronSchedule == null || isMarkedForReload()) { + if (cronSchedule == null || isMarkedForReload()) getObjectInfo(); - } return cronSchedule; } @@ -203,6 +209,8 @@ public void setCronSchedule(String cronSchedule) { } public LocalDateTime getStartDate() { + if (startDate == null || isMarkedForReload()) + getObjectInfo(); return startDate; } @@ -211,6 +219,8 @@ public void setStartDate(LocalDateTime startDate) { } public LocalDateTime getEndDate() { + if (endDate == null || isMarkedForReload()) + getObjectInfo(); return endDate; } @@ -219,13 +229,13 @@ public void setEndDate(LocalDateTime endDate) { } public String getDatabase() { - if (database == null || isMarkedForReload()) { + if (database == null || isMarkedForReload()) getObjectInfo(); - } return database; } public void setDatabase(String database) { this.database = database; } + } diff --git a/src/org/executequery/databaseobjects/impl/DefaultDatabaseMetaTag.java b/src/org/executequery/databaseobjects/impl/DefaultDatabaseMetaTag.java index b9e7dc9d2..fe93f8030 100644 --- a/src/org/executequery/databaseobjects/impl/DefaultDatabaseMetaTag.java +++ b/src/org/executequery/databaseobjects/impl/DefaultDatabaseMetaTag.java @@ -22,7 +22,10 @@ import biz.redsoft.IFBDatabaseConnection; import org.executequery.databasemediators.spi.DefaultStatementExecutor; -import org.executequery.databaseobjects.*; +import org.executequery.databaseobjects.DatabaseHost; +import org.executequery.databaseobjects.DatabaseMetaTag; +import org.executequery.databaseobjects.DatabaseObject; +import org.executequery.databaseobjects.NamedObject; import org.executequery.datasource.PooledConnection; import org.executequery.datasource.PooledResultSet; import org.executequery.gui.browser.ComparerDBPanel; @@ -601,6 +604,7 @@ private AbstractDatabaseObject getTable(ResultSet rs, String metaDataKey, int ty switch (type) { case TABLE: + case SYSTEM_TABLE: return new DefaultDatabaseTable(object); case VIEW: return new DefaultDatabaseView(object); @@ -804,10 +808,11 @@ private ResultSet getProceduresResultSet() throws SQLException { e.printStackTrace(System.out); } - String sql = "SELECT CAST (RDB$PROCEDURE_NAME as VARCHAR(1024)) AS PROCEDURE_NAME\n" + + String sql = "SELECT\n" + + "CAST (RDB$PROCEDURE_NAME as VARCHAR(1024)) AS PROCEDURE_NAME\n" + "FROM RDB$PROCEDURES\n" + ((majorVersion > 2) ? "WHERE RDB$PACKAGE_NAME IS NULL\n" : "") + - "ORDER BY PROCEDURE_NAME"; + "ORDER BY RDB$PROCEDURE_NAME"; if (typeTree == TreePanel.DEPENDED_ON) sql = getDependOnQuery(5); @@ -882,7 +887,8 @@ else if (typeTree == TreePanel.DEPENDENT) private ResultSet getSequencesResultSet() throws SQLException { - String query = "SELECT CAST (RDB$GENERATOR_NAME as VARCHAR(1024))\n" + + String query = "SELECT\n" + + "CAST (RDB$GENERATOR_NAME as VARCHAR(1024))\n" + "FROM RDB$GENERATORS\n" + "WHERE ((RDB$SYSTEM_FLAG IS NULL) OR (RDB$SYSTEM_FLAG = 0))\n" + "ORDER BY RDB$GENERATOR_NAME"; @@ -897,10 +903,11 @@ else if (typeTree == TreePanel.DEPENDENT) private ResultSet getSystemSequencesResultSet() throws SQLException { - String query = "SELECT CAST (RDB$GENERATOR_NAME as VARCHAR(1024))\n" + + String query = "SELECT\n" + + "CAST (RDB$GENERATOR_NAME as VARCHAR(1024))\n" + "FROM RDB$GENERATORS\n" + "WHERE ((RDB$SYSTEM_FLAG IS NOT NULL) AND (RDB$SYSTEM_FLAG != 0))\n" + - "ORDER BY RDB$GENERATOR_NAME"; + "ORDER BY RDB$GENERATOR_NAME"; if (typeTree == TreePanel.DEPENDED_ON) query = getDependOnQuery(14); @@ -912,7 +919,8 @@ else if (typeTree == TreePanel.DEPENDENT) private ResultSet getDomainsResultSet() throws SQLException { - String query = "SELECT CAST (RDB$FIELD_NAME as VARCHAR(1024))\n" + + String query = "SELECT\n" + + "CAST (RDB$FIELD_NAME as VARCHAR(1024))\n" + "FROM RDB$FIELDS\n" + "WHERE (NOT (RDB$FIELD_NAME STARTING WITH 'RDB$')) AND (RDB$SYSTEM_FLAG = 0 OR RDB$SYSTEM_FLAG IS NULL)\n" + "ORDER BY RDB$FIELD_NAME"; @@ -927,7 +935,8 @@ else if (typeTree == TreePanel.DEPENDENT) private ResultSet getSystemDomainResultSet() throws SQLException { - String query = "SELECT CAST (RDB$FIELD_NAME as VARCHAR(1024))\n" + + String query = "SELECT\n" + + "CAST (RDB$FIELD_NAME as VARCHAR(1024))\n" + "FROM RDB$FIELDS\n" + "WHERE (RDB$FIELD_NAME STARTING WITH 'RDB$') OR (RDB$SYSTEM_FLAG <> 0 AND RDB$SYSTEM_FLAG IS NOT NULL)\n" + "ORDER BY RDB$FIELD_NAME"; @@ -942,17 +951,18 @@ private ResultSet getSystemRolesResultSet() throws SQLException { "RDB$OWNER_NAME AS OWNER_NAME\n" + "FROM RDB$ROLES\n" + "WHERE RDB$SYSTEM_FLAG != 0 AND RDB$SYSTEM_FLAG IS NOT NULL\n" + - "ORDER BY 1"; + "ORDER BY RDB$ROLE_NAME"; return getResultSetFromQuery(query); } private ResultSet getSystemPackagesResultSet() throws SQLException { - String query = "SELECT CAST (RDB$PACKAGE_NAME as VARCHAR(1024))\n" + + String query = "SELECT\n" + + "CAST (RDB$PACKAGE_NAME as VARCHAR(1024))\n" + "FROM RDB$PACKAGES\n" + "WHERE RDB$SYSTEM_FLAG != 0 AND RDB$SYSTEM_FLAG IS NOT NULL\n" + - "ORDER BY 1"; + "ORDER BY RDB$PACKAGE_NAME"; return getResultSetFromQuery(query); } @@ -963,7 +973,7 @@ private ResultSet getUsersResultSet() throws SQLException { "CAST (SEC$USER_NAME as VARCHAR(1024)),\n" + "SEC$PLUGIN\n" + "FROM SEC$USERS\n" + - "ORDER BY 1,2"; + "ORDER BY SEC$USER_NAME, SEC$PLUGIN"; if (typeTree == TreePanel.DEPENDED_ON) query = getDependOnQuery(8); @@ -980,36 +990,47 @@ private ResultSet getRolesResultSet() throws SQLException { "RDB$OWNER_NAME AS OWNER_NAME\n" + "FROM RDB$ROLES\n" + "WHERE RDB$SYSTEM_FLAG = 0 OR RDB$SYSTEM_FLAG IS NULL\n" + - "ORDER BY 1"; + "ORDER BY RDB$ROLE_NAME"; return getResultSetFromQuery(query); } private ResultSet getTablespacesResultSet() throws SQLException { - String query = "SELECT CAST (RDB$TABLESPACE_NAME as VARCHAR(1024)) FROM RDB$TABLESPACES ORDER BY 1"; + String query = "SELECT\n" + + "CAST (RDB$TABLESPACE_NAME as VARCHAR(1024))\n" + + "FROM RDB$TABLESPACES\n" + + "ORDER BY RDB$TABLESPACE_NAME"; + return getResultSetFromQuery(query); } private ResultSet getJobsResultSet() throws SQLException { - String query = "SELECT CAST (RDB$JOB_NAME as VARCHAR(1024)) FROM RDB$JOBS ORDER BY 1"; + String query = "SELECT\n" + + "CAST (RDB$JOB_NAME as VARCHAR(1024))\n" + + "FROM RDB$JOBS\n" + + "ORDER BY RDB$JOB_NAME"; + return getResultSetFromQuery(query); } private ResultSet getCollationsResultSet() throws SQLException { - String query = "SELECT CAST (RDB$COLLATION_NAME as VARCHAR(1024))\n" + + String query = "SELECT\n" + + "CAST (RDB$COLLATION_NAME as VARCHAR(1024))\n" + "FROM RDB$COLLATIONS\n" + "WHERE RDB$SYSTEM_FLAG = 0 OR RDB$SYSTEM_FLAG IS NULL\n" + - "ORDER BY 1"; + "ORDER BY RDB$COLLATION_NAME"; return getResultSetFromQuery(query); } private ResultSet getExceptionResultSet() throws SQLException { - String query = "SELECT CAST (RDB$EXCEPTION_NAME as VARCHAR(1024)), RDB$DESCRIPTION\n" + + String query = "SELECT\n" + + "CAST (RDB$EXCEPTION_NAME as VARCHAR(1024)),\n" + + "RDB$DESCRIPTION\n" + "FROM RDB$EXCEPTIONS\n" + "ORDER BY RDB$EXCEPTION_NAME"; @@ -1095,7 +1116,8 @@ private ResultSet getPackagesResultSet() throws SQLException { String query = "SELECT CAST (P.RDB$PACKAGE_NAME as VARCHAR(1024))\n" + "FROM RDB$PACKAGES P\n" + - "WHERE RDB$SYSTEM_FLAG = 0 OR RDB$SYSTEM_FLAG IS NULL ORDER BY 1"; + "WHERE RDB$SYSTEM_FLAG = 0 OR RDB$SYSTEM_FLAG IS NULL\n" + + "ORDER BY P.RDB$PACKAGE_NAME"; if (typeTree == TreePanel.DEPENDED_ON) query = getDependOnQuery(19); @@ -1173,7 +1195,7 @@ private ResultSet getFunctionsResultSet() throws SQLException { "RDB$DESCRIPTION AS REMARKS\n" + "FROM RDB$FUNCTIONS\n" + "WHERE (RDB$MODULE_NAME IS NULL) AND (RDB$PACKAGE_NAME IS NULL)\n" + - "ORDER BY FUNCTION_NAME "; + "ORDER BY RDB$FUNCTION_NAME"; try { diff --git a/src/org/executequery/databaseobjects/impl/DefaultDatabaseObject.java b/src/org/executequery/databaseobjects/impl/DefaultDatabaseObject.java index 649aa091b..7d1d02976 100644 --- a/src/org/executequery/databaseobjects/impl/DefaultDatabaseObject.java +++ b/src/org/executequery/databaseobjects/impl/DefaultDatabaseObject.java @@ -22,6 +22,7 @@ import org.executequery.databaseobjects.*; import org.executequery.gui.browser.tree.TreePanel; +import org.executequery.sql.sqlbuilder.Field; import org.executequery.sql.sqlbuilder.SelectBuilder; import org.executequery.sql.sqlbuilder.Table; import org.underworldlabs.jdbc.DataSourceException; @@ -148,7 +149,8 @@ protected Table getMainTable() { protected SelectBuilder builderCommonQuery() { SelectBuilder sb = new SelectBuilder(getHost().getDatabaseConnection()); Table table = getMainTable(); - sb.appendFields(table, getFieldName(), DESCRIPTION); + sb.appendField(Field.createField(table, getFieldName()).setCast("VARCHAR(1024)")); + sb.appendFields(table, DESCRIPTION); sb.appendTable(table); sb.setOrdering(getObjectField().getFieldTable()); return sb; diff --git a/src/org/executequery/databaseobjects/impl/DefaultDatabasePackage.java b/src/org/executequery/databaseobjects/impl/DefaultDatabasePackage.java index 7b438de00..6151d0b57 100644 --- a/src/org/executequery/databaseobjects/impl/DefaultDatabasePackage.java +++ b/src/org/executequery/databaseobjects/impl/DefaultDatabasePackage.java @@ -3,6 +3,7 @@ import org.executequery.databaseobjects.DatabaseMetaTag; import org.executequery.databaseobjects.DatabaseProcedure; import org.executequery.databaseobjects.NamedObject; +import org.executequery.sql.sqlbuilder.Field; import org.executequery.sql.sqlbuilder.SelectBuilder; import org.executequery.sql.sqlbuilder.Table; import org.underworldlabs.jdbc.DataSourceException; @@ -56,8 +57,7 @@ public String getHeaderSource() { if (isMarkedForReload()) getObjectInfo(); - return "CREATE OR ALTER PACKAGE " + getName() + - "\nAS\n" + this.headerSource; + return this.headerSource; } public void setHeaderSource(String headerSource) { @@ -65,9 +65,11 @@ public void setHeaderSource(String headerSource) { } public String getBodySource() { + return this.bodySource; + } - return "RECREATE PACKAGE BODY " + getName() + - "\nAS\n" + this.bodySource; + public String getOriginalBodySource() { + return this.bodySource; } public void setBodySource(String bodySource) { @@ -129,7 +131,7 @@ public String getDropSQL() throws DataSourceException { @Override public String getCompareAlterSQL(AbstractDatabaseObject databaseObject) throws DataSourceException { return (!this.getCompareCreateSQL().equals(databaseObject.getCompareCreateSQL())) ? - databaseObject.getCompareCreateSQL() : "/* there are no changes */"; + databaseObject.getCompareCreateSQL() : SQLUtils.THERE_ARE_NO_CHANGES; } protected final static String PACKAGE_HEADER_SOURCE = "PACKAGE_HEADER_SOURCE"; protected final static String PACKAGE_BODY_SOURCE = "PACKAGE_BODY_SOURCE"; @@ -152,7 +154,8 @@ protected Table getMainTable() { protected SelectBuilder builderCommonQuery() { SelectBuilder sb = new SelectBuilder(getHost().getDatabaseConnection()); Table packages = getMainTable(); - sb.appendFields(packages, getFieldName(), PACKAGE_HEADER_SOURCE, PACKAGE_BODY_SOURCE, VALID_BODY_FLAG, + sb.appendField(Field.createField(packages, getFieldName()).setCast("VARCHAR(1024)")); + sb.appendFields(packages, PACKAGE_HEADER_SOURCE, PACKAGE_BODY_SOURCE, VALID_BODY_FLAG, SECURITY_CLASS, OWNER_NAME, SYSTEM_FLAG, DESCRIPTION); sb.appendField(buildSqlSecurityField(packages)); sb.appendTable(packages); diff --git a/src/org/executequery/databaseobjects/impl/DefaultDatabaseProcedure.java b/src/org/executequery/databaseobjects/impl/DefaultDatabaseProcedure.java index 44c1c2686..ad0984ddb 100644 --- a/src/org/executequery/databaseobjects/impl/DefaultDatabaseProcedure.java +++ b/src/org/executequery/databaseobjects/impl/DefaultDatabaseProcedure.java @@ -142,7 +142,7 @@ public String getDropSQL() throws DataSourceException { @Override public String getCompareAlterSQL(AbstractDatabaseObject databaseObject) throws DataSourceException { return (!this.getCompareCreateSQL().equals(databaseObject.getCompareCreateSQL())) ? - databaseObject.getCompareCreateSQL() : "/* there are no changes */"; + databaseObject.getCompareCreateSQL() : SQLUtils.THERE_ARE_NO_CHANGES; } protected static final String PP = "PP_"; @@ -176,7 +176,8 @@ protected SelectBuilder builderCommonQuery() { Table charsets = Table.createTable("RDB$CHARACTER_SETS", "CR"); Table collations1 = Table.createTable("RDB$COLLATIONS", "CO1"); Table collations2 = Table.createTable("RDB$COLLATIONS", "CO2"); - sb.appendFields(procedures, getFieldName(), PROCEDURE_SOURCE, PROCEDURE_TYPE, DESCRIPTION, VALID_BLR); + sb.appendField(Field.createField(procedures, getFieldName()).setCast("VARCHAR(1024)")); + sb.appendFields(procedures, PROCEDURE_SOURCE, PROCEDURE_TYPE, DESCRIPTION, VALID_BLR); sb.appendFields(procedures, !externalCheck(), ENGINE_NAME, ENTRYPOINT); sb.appendField(buildSqlSecurityField(procedures)); Field authid = Field.createField(procedures, PROCEDURE_CONTEXT); diff --git a/src/org/executequery/databaseobjects/impl/DefaultDatabaseRole.java b/src/org/executequery/databaseobjects/impl/DefaultDatabaseRole.java index d8582c921..c573e36f3 100644 --- a/src/org/executequery/databaseobjects/impl/DefaultDatabaseRole.java +++ b/src/org/executequery/databaseobjects/impl/DefaultDatabaseRole.java @@ -2,7 +2,7 @@ import org.executequery.databaseobjects.DatabaseMetaTag; import org.executequery.databaseobjects.NamedObject; -import org.executequery.gui.browser.comparer.Comparer; +import org.executequery.sql.sqlbuilder.Field; import org.executequery.sql.sqlbuilder.SelectBuilder; import org.executequery.sql.sqlbuilder.Table; import org.underworldlabs.jdbc.DataSourceException; @@ -44,7 +44,7 @@ public String getDropSQL() throws DataSourceException { @Override public String getCompareAlterSQL(AbstractDatabaseObject databaseObject) throws DataSourceException { - return "/* there are no changes */\n"; + return SQLUtils.THERE_ARE_NO_CHANGES; } @Override @@ -61,7 +61,8 @@ protected Table getMainTable() { protected SelectBuilder builderCommonQuery() { SelectBuilder sb = new SelectBuilder(getHost().getDatabaseConnection()); Table table = getMainTable(); - sb.appendFields(table, getFieldName(), DESCRIPTION, OWNER_NAME); + sb.appendField(Field.createField(table, getFieldName()).setCast("VARCHAR(1024)")); + sb.appendFields(table, DESCRIPTION, OWNER_NAME); sb.appendTable(table); sb.setOrdering(getObjectField().getFieldTable()); return sb; diff --git a/src/org/executequery/databaseobjects/impl/DefaultDatabaseSequence.java b/src/org/executequery/databaseobjects/impl/DefaultDatabaseSequence.java index 8a46a522a..38a1f88ae 100644 --- a/src/org/executequery/databaseobjects/impl/DefaultDatabaseSequence.java +++ b/src/org/executequery/databaseobjects/impl/DefaultDatabaseSequence.java @@ -178,7 +178,7 @@ protected SelectBuilder builderCommonQuery() { SelectBuilder sb = SelectBuilder.createSelectBuilder(getHost().getDatabaseConnection()); Table gens = getMainTable(); sb.appendTable(gens); - sb.appendField(getObjectField()); + sb.appendField(Field.createField(gens, getFieldName()).setCast("VARCHAR(1024)")); sb.appendField(Field.createField(gens, INITIAL_VALUE).setNull(getDatabaseMajorVersion() < 3)); sb.appendField(Field.createField(gens, GENERATOR_INCREMENT).setNull(getDatabaseMajorVersion() < 3)); sb.appendField(Field.createField(gens, DESCRIPTION)); diff --git a/src/org/executequery/databaseobjects/impl/DefaultDatabaseTable.java b/src/org/executequery/databaseobjects/impl/DefaultDatabaseTable.java index d36fcd28e..ca309fa97 100644 --- a/src/org/executequery/databaseobjects/impl/DefaultDatabaseTable.java +++ b/src/org/executequery/databaseobjects/impl/DefaultDatabaseTable.java @@ -333,7 +333,7 @@ public List getIndexes() throws DataSourceException { DefaultDatabaseIndex index1 = metaTag.getIndexFromName(index.getName()); index1.getObjectInfo(); indexes.add(index1); - if (index1.getExpression() != null) { + if (!MiscUtils.isNull(index1.getExpression())) { index.setIndexedColumns(null); index.setExpression(index1.getExpression()); } @@ -803,6 +803,28 @@ public boolean hasPrimaryKey() { return keys != null && !keys.isEmpty(); } + String[][] monTables = new String[][] + { + {"MON$ATTACHMENTS", "MON$ATTACHMENT_ID"}, + {"MON$TRANSACTIONS", "MON$TRANSACTION_ID"}, + {"MON$STATEMENTS", "MON$STATEMENT_ID"}, + {"MON$CALL_STACK", "MON$CALL_ID"}, + {"MON$COMPILED_STATEMENTS", "MON$COMPILED_STATEMENT_ID"}, + {"MON$TEMP_SPACES", "MON$TEMP_SPACE_ID"} + }; + + public String[] getMonField() { + for (int i = 0; i < monTables.length; i++) + if (monTables[i][0].contentEquals(getName())) + return monTables[i]; + return null; + } + + public boolean isMonTable() { + return getMonField() != null; + } + + @Override public List getPrimaryKeys() { @@ -1104,6 +1126,19 @@ public String prepareStatementWithPK(List columns) { return sb.toString(); } + @Override + public String prepareStatementInMonTable(List columns) { + + StringBuilder sb = new StringBuilder(); + sb.append("UPDATE ").append(getNameWithPrefixForQuery()).append(" SET "); + for (String column : columns) + sb.append(MiscUtils.getFormattedObject(column, getHost().getDatabaseConnection())).append(" = ?,"); + sb.deleteCharAt(sb.length() - 1); + sb.append(" WHERE "); + sb.append(getMonField()[1]).append(" = ?"); + return sb.toString(); + } + @Override public String prepareStatementDeletingWithPK() { @@ -1124,6 +1159,14 @@ public String prepareStatementDeletingWithPK() { return sb.toString(); } + @Override + public String prepareStatementDeletingFromMonTable() { + String sb = "DELETE FROM " + getNameWithPrefixForQuery() + + " WHERE " + + getMonField()[1] + " = ?"; + return sb; + } + @Override public List getPrimaryKeyColumnNames() { return namesFromColumns(getPrimaryKeysColumns()); @@ -1213,7 +1256,7 @@ protected SelectBuilder builderCommonQuery() { .appendArgument(conType.getFieldTable() + " <> 'CHECK'") .appendArgument("NULL") .appendArgument(conName.getFieldTable()); - sb.appendField(getObjectField()); + sb.appendField(Field.createField(getMainTable(), getFieldName()).setCast("VARCHAR(1024)")); sb.appendField(Field.createField().setStatement(compareCheck.getStatement()).setAlias(conName.getAlias())); compareCheck.setArgument(2, conType.getFieldTable()); sb.appendField(Field.createField().setStatement(compareCheck.getStatement()).setAlias(conType.getAlias())); @@ -1233,7 +1276,7 @@ protected SelectBuilder builderCommonQuery() { .appendCondition(Condition.createCondition(Field.createField(triggers, "TRIGGER_TYPE"), "=", "1")) .appendCondition(Condition.createCondition(Field.createField(triggers, "TRIGGER_TYPE"), "IS", "NULL")) .setLogicOperator("OR")); - sb.setOrdering("1"); + sb.setOrdering(getObjectField().getFieldTable()); return sb; } diff --git a/src/org/executequery/databaseobjects/impl/DefaultDatabaseTablespace.java b/src/org/executequery/databaseobjects/impl/DefaultDatabaseTablespace.java index a15eee9c3..3510729bf 100644 --- a/src/org/executequery/databaseobjects/impl/DefaultDatabaseTablespace.java +++ b/src/org/executequery/databaseobjects/impl/DefaultDatabaseTablespace.java @@ -3,6 +3,8 @@ import org.executequery.databasemediators.spi.DefaultStatementExecutor; import org.executequery.databaseobjects.DatabaseMetaTag; import org.executequery.databaseobjects.NamedObject; +import org.executequery.gui.browser.comparer.Comparer; +import org.executequery.sql.sqlbuilder.Field; import org.executequery.sql.sqlbuilder.SelectBuilder; import org.executequery.sql.sqlbuilder.Table; import org.underworldlabs.jdbc.DataSourceException; @@ -95,7 +97,8 @@ protected Table getMainTable() { protected SelectBuilder builderCommonQuery() { SelectBuilder sb = new SelectBuilder(getHost().getDatabaseConnection()); Table table = getMainTable(); - sb.appendFields(table, getFieldName(), ID, SYSTEM, DESCRIPTION, OWNER, FILE_NAME, READ_ONLY, OFFLINE); + sb.appendField(Field.createField(table, getFieldName()).setCast("VARCHAR(1024)")); + sb.appendFields(table, ID, SYSTEM, DESCRIPTION, OWNER, FILE_NAME, READ_ONLY, OFFLINE); sb.appendTable(table); sb.setOrdering(getObjectField().getFieldTable()); return sb; @@ -176,15 +179,14 @@ public void setTables(List tables) { @Override public String getCreateSQLText() throws DataSourceException { - return SQLUtils.generateCreateTablespace(getName(), getFileName(), getHost().getDatabaseConnection()); + return SQLUtils.generateCreateTablespace(getName(), getFileName(), getRemarks(), true, getHost().getDatabaseConnection()); } @Override public String getCreateSQLTextWithoutComment() throws DataSourceException { - return getCreateSQLText(); + return SQLUtils.generateCreateTablespace(getName(), getFileName(), null, false, getHost().getDatabaseConnection()); } - @Override public String getDropSQL() throws DataSourceException { return SQLUtils.generateDefaultDropQuery("TABLESPACE", getName(), getHost().getDatabaseConnection()); @@ -193,8 +195,7 @@ public String getDropSQL() throws DataSourceException { @Override public String getCompareAlterSQL(AbstractDatabaseObject databaseObject) throws DataSourceException { DefaultDatabaseTablespace comparingTablespace = (DefaultDatabaseTablespace) databaseObject; - return SQLUtils.generateAlterTablespace(this, comparingTablespace); + return SQLUtils.generateAlterTablespace(this, comparingTablespace, Comparer.isCommentsNeed()); } } - diff --git a/src/org/executequery/databaseobjects/impl/DefaultDatabaseTrigger.java b/src/org/executequery/databaseobjects/impl/DefaultDatabaseTrigger.java index 088fb502a..ca649c440 100644 --- a/src/org/executequery/databaseobjects/impl/DefaultDatabaseTrigger.java +++ b/src/org/executequery/databaseobjects/impl/DefaultDatabaseTrigger.java @@ -421,7 +421,7 @@ public String getDropSQL() throws DataSourceException { @Override public String getCompareAlterSQL(AbstractDatabaseObject databaseObject) throws DataSourceException { return (!this.getCompareCreateSQL().equals(databaseObject.getCompareCreateSQL())) ? - databaseObject.getCompareCreateSQL() : "/* there are no changes */"; + databaseObject.getCompareCreateSQL() : SQLUtils.THERE_ARE_NO_CHANGES; } protected static final String TRIGGER_SOURCE = "TRIGGER_SOURCE"; @@ -467,7 +467,8 @@ protected SelectBuilder builderCommonQuery() { SelectBuilder sb = SelectBuilder.createSelectBuilder(getHost().getDatabaseConnection()); Table triggers = getMainTable(); sb.appendTable(triggers); - sb.appendFields(triggers, getFieldName(), TRIGGER_SOURCE, RELATION_NAME, TRIGGER_SEQUENCE, TRIGGER_TYPE, TRIGGER_INACTIVE, DESCRIPTION, VALID_BLR); + sb.appendField(Field.createField(triggers, getFieldName()).setCast("VARCHAR(1024)")); + sb.appendFields(triggers, TRIGGER_SOURCE, RELATION_NAME, TRIGGER_SEQUENCE, TRIGGER_TYPE, TRIGGER_INACTIVE, DESCRIPTION, VALID_BLR); sb.appendFields(triggers, !externalCheck(), ENGINE_NAME, ENTRYPOINT); sb.appendField(buildSqlSecurityField(triggers)); sb.setOrdering(getObjectField().getFieldTable()); diff --git a/src/org/executequery/databaseobjects/impl/DefaultDatabaseUDF.java b/src/org/executequery/databaseobjects/impl/DefaultDatabaseUDF.java index bb69bce5d..88d9ca83b 100644 --- a/src/org/executequery/databaseobjects/impl/DefaultDatabaseUDF.java +++ b/src/org/executequery/databaseobjects/impl/DefaultDatabaseUDF.java @@ -101,7 +101,7 @@ public String getCompareCreateSQL() throws DataSourceException { @Override public String getDropSQL() throws DataSourceException { - return SQLUtils.generateDefaultDropQuery("UDF", getName(), getHost().getDatabaseConnection()); + return SQLUtils.generateDefaultDropQuery("EXTERNAL FUNCTION", getName(), getHost().getDatabaseConnection()); } @Override @@ -120,7 +120,8 @@ protected SelectBuilder builderCommonQuery() { Table collations1 = Table.createTable("RDB$COLLATIONS", "CO1"); Table collations2 = Table.createTable("RDB$COLLATIONS", "CO2"); - sb.appendFields(functions, getFieldName(), DESCRIPTION, RETURN_ARGUMENT, MODULE_NAME, ENTRYPOINT); + sb.appendField(Field.createField(functions, getFieldName()).setCast("VARCHAR(1024)")); + sb.appendFields(functions, DESCRIPTION, RETURN_ARGUMENT, MODULE_NAME, ENTRYPOINT); sb.appendField(buildSqlSecurityField(functions)); sb.appendFields(FA, arguments, getDatabaseMajorVersion() < 3 && !isRDB(), PARAMETER_NAME, DESCRIPTION, PARAMETER_MECHANISM, mechanismLabel(), DEFAULT_SOURCE, RELATION_NAME, FIELD_NAME); sb.appendFields(FA, arguments, PARAMETER_NUMBER); diff --git a/src/org/executequery/databaseobjects/impl/DefaultDatabaseView.java b/src/org/executequery/databaseobjects/impl/DefaultDatabaseView.java index cef2aa3b9..9cdff8c5a 100644 --- a/src/org/executequery/databaseobjects/impl/DefaultDatabaseView.java +++ b/src/org/executequery/databaseobjects/impl/DefaultDatabaseView.java @@ -22,7 +22,6 @@ import org.executequery.databasemediators.spi.DefaultStatementExecutor; import org.executequery.databaseobjects.*; -import org.executequery.gui.browser.comparer.Comparer; import org.executequery.log.Log; import org.executequery.sql.TokenizingFormatter; import org.executequery.sql.sqlbuilder.*; @@ -67,7 +66,8 @@ protected SelectBuilder builderCommonQuery() { SelectBuilder sb = new SelectBuilder(getHost().getDatabaseConnection()); Table rels = getMainTable(); Table rf = Table.createTable("RDB$RELATION_FIELDS", "RF"); - sb.appendFields(rels, getFieldName(), SOURCE, DESCRIPTION); + sb.appendField(Field.createField(rels, getFieldName()).setCast("VARCHAR(1024)")); + sb.appendFields(rels, SOURCE, DESCRIPTION); sb.appendFields(rf, FIELD_NAME); sb.appendJoin(Join.createLeftJoin().appendFields(getObjectField(), Field.createField(rf, getFieldName()))); sb.setOrdering(getObjectField().getFieldTable() + ", " + Field.createField(rf, FIELD_POSITION).getFieldTable()); @@ -144,7 +144,7 @@ public String getDropSQL() throws DataSourceException { @Override public String getCompareAlterSQL(AbstractDatabaseObject databaseObject) throws DataSourceException { return (!this.getCompareCreateSQL().equals(databaseObject.getCompareCreateSQL())) ? - databaseObject.getCompareCreateSQL() : "/* there are no changes */"; + databaseObject.getCompareCreateSQL() : SQLUtils.THERE_ARE_NO_CHANGES; } @Override diff --git a/src/org/executequery/databases.xml b/src/org/executequery/databases.xml index 119e9cd5a..4b0dff661 100644 --- a/src/org/executequery/databases.xml +++ b/src/org/executequery/databases.xml @@ -12,92 +12,15 @@ 1 - Oracle + Red Database - jdbc:oracle:thin:@[host]:[source] - jdbc:oracle:thin:@[host]:[port]:[source] - jdbc:oracle:oci:@[host]:[source] - jdbc:oracle:oci:@[host]:[port]:[source] + jdbc:firebirdsql://[host]:[port]/[source] + jdbc:firebirdsql:[source] 2 - SyBase - - jdbc:sybase:Tds:[host]:[port] - jdbc:sybase:Tds:[host]:[port]/[source] - - - - - 3 - DB2 - - jdbc:db2://[host]:[port]/[source] - - - - - 4 - MS SQL Server - - jdbc:sqlserver://[host];databaseName=[source]; - jdbc:sqlserver://[host]:[port];databaseName=[source]; - jdbc:sqlserver://[host]:[port];instanceName=[source] - jdbc:microsoft:sqlserver://[host]:[port] - jdbc:microsoft:sqlserver://[host]:[port];DatabaseName=[source] - - - - - 5 - MySQL - - jdbc:mysql://[host]/[source] - jdbc:mysql://[host]:[port]/[source] - - - - - 6 - PostgreSQL - - jdbc:postgresql://[host]/[source] - jdbc:postgresql://[host]:[port]/[source] - - - - - 7 - Informix - - jdbc:informix-sqli://[host]:[port]:informixserver=[source] - - - - - 10 - HSQL DB - - jdbc:hsqldb:. - jdbc:hsqldb:[source] - jdbc:hsqldb:hsql://[host]:[port] - - - - - 15 - MaxDB - - jdbc:sapdb://[host]:[port]/[source] - jdbc:sapdb://[host]/[source] - jdbc:sapdb:[source] - - - - - 16 Firebird jdbc:firebirdsql://[host]:[port]/[source] @@ -106,83 +29,7 @@ - 11 - MS Access - - - - - 12 - Pointbase - - jdbc:pointbase:server://[host]:[port]/[source] - jdbc:pointbase:embedded:[source] - - - - - 13 - H2 Database Engine - - jdbc:h2:[source] - - - - - 14 - Apache Derby - - jdbc:derby://[host]/[source] - jdbc:derby://[host]:[port]/[source] - - - - - 17 - FrontBase - - jdbc:FrontBase://[host]/[source] - - - - - 18 - jTDS - - jdbc:jtds:sqlserver://[host]/[source] - jdbc:jtds:sqlserver://[host]:[port]/[source] - jdbc:jtds:sybase://[host]/[source] - jdbc:jtds:sybase://[host]:[port]/[source] - - - - - 19 - MckoiDDB - - jdbc:mckoi://[host]/[source]/ - jdbc:mckoi://[host]:[port][/[source]/ - - - - - 20 - ThinkSQL - - jdbc:thinksql://[host]:[port] - - - - - 21 - SQLite - - jdbc:sqlite:[source] - - - - - 9 + -1 Other diff --git a/src/org/executequery/datasource/ConnectionManager.java b/src/org/executequery/datasource/ConnectionManager.java index 2a07d2796..34d682e43 100644 --- a/src/org/executequery/datasource/ConnectionManager.java +++ b/src/org/executequery/datasource/ConnectionManager.java @@ -30,7 +30,9 @@ import org.executequery.gui.browser.ConnectionsTreePanel; import org.executequery.gui.browser.nodes.DatabaseObjectNode; import org.executequery.log.Log; +import org.executequery.repository.DatabaseConnectionRepository; import org.executequery.repository.DatabaseDriverRepository; +import org.executequery.repository.Repository; import org.executequery.repository.RepositoryCache; import org.underworldlabs.jdbc.DataSourceException; import org.underworldlabs.util.SystemProperties; @@ -346,15 +348,29 @@ public static void setTransactionIsolationLevel(DatabaseConnection databaseConne * @return a collection of active connections */ public static Vector getActiveConnections() { - if (connectionPools == null || connectionPools.isEmpty()) { - return new Vector(0); - } - Vector connections = - new Vector(connectionPools.size()); - for (Iterator i = - connectionPools.keySet().iterator(); i.hasNext(); ) { - connections.add(i.next()); - } + + if (connectionPools.isEmpty()) + return new Vector<>(0); + + Vector connections = new Vector<>(connectionPools.size()); + connections.addAll(connectionPools.keySet()); + + return connections; + } + + /** + * Returns a collection of database connection property + * objects that are active (connected). + * + * @return a collection of active connections + */ + public static Vector getAllConnections() { + + Vector connections = new Vector<>(); + Repository repository = RepositoryCache.load(DatabaseConnectionRepository.REPOSITORY_ID); + if (repository instanceof DatabaseConnectionRepository) + connections.addAll(((DatabaseConnectionRepository) repository).findAll()); + return connections; } diff --git a/src/org/executequery/datasource/PooledConnection.java b/src/org/executequery/datasource/PooledConnection.java index 91380f378..3fda2429b 100644 --- a/src/org/executequery/datasource/PooledConnection.java +++ b/src/org/executequery/datasource/PooledConnection.java @@ -25,6 +25,7 @@ import org.executequery.databasemediators.ConnectionMediator; import org.executequery.databasemediators.DatabaseConnection; import org.executequery.localization.Bundles; +import org.executequery.log.Log; import org.underworldlabs.util.DynamicLibraryLoader; import org.underworldlabs.util.SystemProperties; @@ -263,47 +264,49 @@ protected void handleException(SQLException e) throws SQLException { throw e; } - public void checkConnectionToServer() - { + public void checkConnectionToServer() { + + TimerTask task = new TimerTask() { + @Override + public void run() { + if (databaseConnection.isConnected()) + askAndCloseConnection(); + timerDelay.cancel(); + } + }; + try { - IFBDatabasePerformance db = (IFBDatabasePerformance) DynamicLibraryLoader.loadingObjectFromClassLoader(databaseConnection.getDriverMajorVersion(), realConnection, "FBDatabasePerformanceImpl"); + int driverVersion = databaseConnection.getDriverMajorVersion(); + Object loadedObject = DynamicLibraryLoader.loadingObjectFromClassLoader(driverVersion, realConnection, "FBDatabasePerformanceImpl"); + + IFBDatabasePerformance db = (IFBDatabasePerformance) loadedObject; db.setConnection(realConnection); - TimerTask task = new TimerTask() { - @Override - public void run() { - if (databaseConnection.isConnected()) { - if (GUIUtilities.displayConfirmDialog("The server is not responding. Do you want to close the connection?") == JOptionPane.OK_OPTION) { - closeDatabaseConnection(); - timerDelay.cancel(); - } - } else - timerDelay.cancel(); - } - }; - timerDelay = new Timer("check "+databaseConnection.getName()+ "conToServer"); - /*StackTraceElement[] stack = Thread.currentThread().getStackTrace(); - Log.info("---------------------------------Start check----------------------------------\n\n\n"); - for (int i = 0; i < stack.length - 2; i++) - Log.info(stack[stack.length - 1 - i]);*/ + + timerDelay = new Timer("check " + databaseConnection.getName() + "connection to the server"); timerDelay.schedule(task, timeoutShutdown); - db.getPerformanceInfo(databaseConnection.getDriverMajorVersion()); - timerDelay.cancel(); - //Log.info("---------------------------------Finish check.----------------------------------\n\n\n"); - } catch (SQLException e) - { + db.getPerformanceInfo(driverVersion); //todo check (with using OO API throws exceptions from handleException method) + + } catch (SQLException e) { + Log.error(e.getMessage(), e); if (databaseConnection.isConnected()) closeDatabaseConnection(); - timerDelay.cancel(); + } catch (ClassNotFoundException e) { - if (databaseConnection.isConnected()) { - if (GUIUtilities.displayConfirmDialog("The server is not responding. Do you want to close the connection?") == JOptionPane.OK_OPTION) { - closeDatabaseConnection(); - } - } + Log.error(e.getMessage(), e); + if (databaseConnection.isConnected()) + askAndCloseConnection(); + + } finally { timerDelay.cancel(); } } + private void askAndCloseConnection() { + int result = GUIUtilities.displayConfirmDialog(Bundles.get("common.serverNotResponding.closeConnection.ask")); + if (result == JOptionPane.OK_OPTION) + closeDatabaseConnection(); + } + public Statement createStatement() throws SQLException { checkOpen(); Statement statement = null; diff --git a/src/org/executequery/datasource/SimpleDataSource.java b/src/org/executequery/datasource/SimpleDataSource.java index 8e3ae221a..6ba08550a 100644 --- a/src/org/executequery/datasource/SimpleDataSource.java +++ b/src/org/executequery/datasource/SimpleDataSource.java @@ -158,42 +158,45 @@ public Connection getConnection(String username, String password, ITPB tpb) thro // Checking for original jaybird or rdb jaybird... try { - Class aClass = driver.getClass().getClassLoader().loadClass("org.firebirdsql.jca.FBSADataSource"); + driver.getClass().getClassLoader().loadClass("org.firebirdsql.jca.FBSADataSource"); } catch (ClassNotFoundException e) { - Class aClass = driver.getClass().getClassLoader().loadClass("org.firebirdsql.jaybird.xca.FBSADataSource"); + driver.getClass().getClassLoader().loadClass("org.firebirdsql.jaybird.xca.FBSADataSource"); } + String jarPath = databaseConnection.getJDBCDriver().getPath(); + jarPath = jarPath.replace("../", "./") + ";" + jarPath.replace("./", "../"); + jarPath = jarPath.replace(".../", "../"); + jarPath += ";" + DynamicLibraryLoader.getFbPluginImplPath(driver.getMajorVersion()); - // ...rdb jaybird - // in multifactor authentication case, need to initialize crypto plugin, - // otherwise get a message, that multifactor authentication will be unavailable if (cryptoPlugin == null) { try { - String path = databaseConnection.getJDBCDriver().getPath(); - path = path.replace("../", "./") + ";" + path.replace("./", "../"); - path = path.replace(".../", "../"); - path += ";" + DynamicLibraryLoader.getFbPluginImplPath(driver.getMajorVersion()); - Object odb = DynamicLibraryLoader.loadingObjectFromClassLoader(driver, + Object odb = DynamicLibraryLoader.loadingObjectFromClassLoader( + driver, "biz.redsoft.FBCryptoPluginInitImpl", - path); + jarPath + ); + cryptoPlugin = (IFBCryptoPluginInit) odb; - // try to initialize crypto plugin cryptoPlugin.init(); - } catch (Throwable e) { Log.warning("Unable to initialize cryptographic plugin. " + "Authentication using cryptographic mechanisms will not be available. " + - "Please install the crypto pro library to enable cryptographic modules."); + "Please install the crypto pro library to enable cryptographic modules." + ); advancedProperties.put("excludeCryptoPlugins", "Multifactor,GostPassword,Certificate"); } } if (databaseConnection.useNewAPI()) { try { - dataSource = (IFBDataSource) DynamicLibraryLoader.loadingObjectFromClassLoaderWithParams(driver.getMajorVersion(), driver, - "FBDataSourceImpl", - new DynamicLibraryLoader.Parameter(String.class, "FBOONATIVE")); + dataSource = (IFBDataSource) DynamicLibraryLoader.loadingObjectFromClassLoaderWithParams( + driver, + "biz.redsoft.FBDataSourceImpl", + jarPath, + new DynamicLibraryLoader.Parameter(String.class, "FBOONATIVE") + ); + } catch (ClassNotFoundException e) { dataSource = (IFBDataSource) DynamicLibraryLoader.loadingObjectFromClassLoader(driver.getMajorVersion(), driver, "FBDataSourceImpl"); diff --git a/src/org/executequery/eq.default.properties b/src/org/executequery/eq.default.properties index 44d380696..fe3bede89 100644 --- a/src/org/executequery/eq.default.properties +++ b/src/org/executequery/eq.default.properties @@ -10,7 +10,6 @@ # --------------------------- startup.window.maximized=false; startup.display.splash=true -startup.display.openwindow=1 startup.display.lookandfeel=DEFAULT_LIGHT startup.connection.name=noconn startup.default.connection.username=SYSDBA @@ -144,7 +143,7 @@ results.table.double-click.record.dialog=true results.table.use.form.adding.deleting=false results.table.use.other.color.null=false results.table.row.select=true -results.table.row.numbers=false +results.table.row.numbers=true results.table.single.row.transpose=false results.table.align.numeric=right results.table.align.text=left @@ -183,18 +182,10 @@ browser.show.connection.properties.advanced=false # ------------------------------ connection.usepool=0 connection.initialcount=1 -connection.scheme=0 -connection.reuse.count=20 -connection.reuse=true startup.connection.connect=false -connection.login.timeout=15 connection.shutdown.timeout=10000 connection.connect.timeout=5 # -------------------- -# Locale Options -# -------------------- -# startup.display.language=en -# -------------------- # Internet proxy # -------------------- internet.proxy.set=false diff --git a/src/org/executequery/eq.system.properties b/src/org/executequery/eq.system.properties index 7317c2a09..60adbab31 100644 --- a/src/org/executequery/eq.system.properties +++ b/src/org/executequery/eq.system.properties @@ -18,7 +18,7 @@ eq.import.log=import.log # version info eq.minor.version=4.4.2 eq.major.version=4.4 -eq.build=202406 +eq.build=202408 help.version=3.2.0 check.version.url=https://api.github.com/repos/redsoftbiz/executequery/releases/latest check.version.notes.url=https://api.github.com/repos/redsoftbiz/executequery/releases/latest diff --git a/src/org/executequery/gui/ActionContainer.java b/src/org/executequery/gui/ActionContainer.java index 8145a1659..9016369b3 100644 --- a/src/org/executequery/gui/ActionContainer.java +++ b/src/org/executequery/gui/ActionContainer.java @@ -53,6 +53,11 @@ public interface ActionContainer { */ public void finished(); + /** + * Sets whether this dialog is resizable by the user + */ + void setResizable(boolean resize); + } diff --git a/src/org/executequery/gui/BaseDialog.java b/src/org/executequery/gui/BaseDialog.java index ceae9080d..47084c85f 100644 --- a/src/org/executequery/gui/BaseDialog.java +++ b/src/org/executequery/gui/BaseDialog.java @@ -247,6 +247,11 @@ public void display() { toFront(); } + @Override + public void setResizable(boolean resize) { + super.setResizable(resize); + } + } diff --git a/src/org/executequery/gui/ExecuteSqlScriptPanel.java b/src/org/executequery/gui/ExecuteSqlScriptPanel.java index f2a0df2dc..8b84b2969 100644 --- a/src/org/executequery/gui/ExecuteSqlScriptPanel.java +++ b/src/org/executequery/gui/ExecuteSqlScriptPanel.java @@ -28,21 +28,14 @@ import org.executequery.components.SplitPaneFactory; import org.executequery.databasemediators.ConnectionMediator; import org.executequery.databasemediators.DatabaseConnection; -import org.executequery.datasource.ConnectionManager; import org.executequery.gui.text.SimpleSqlTextPanel; import org.executequery.gui.text.TextFileWriter; import org.executequery.localization.Bundles; -import org.executequery.repository.DatabaseConnectionRepository; -import org.executequery.repository.Repository; -import org.executequery.repository.RepositoryCache; import org.executequery.sql.ExecutionController; import org.executequery.sql.SqlScriptRunner; import org.executequery.sql.SqlStatementResult; import org.executequery.util.ThreadUtils; -import org.underworldlabs.swing.AbstractStatusBarPanel; -import org.underworldlabs.swing.GUIUtils; -import org.underworldlabs.swing.ProgressBar; -import org.underworldlabs.swing.ProgressBarFactory; +import org.underworldlabs.swing.*; import org.underworldlabs.swing.layouts.GridBagHelper; import org.underworldlabs.swing.plaf.UIUtils; import org.underworldlabs.swing.util.SwingWorker; @@ -55,8 +48,6 @@ import java.io.File; import java.io.IOException; import java.sql.SQLException; -import java.util.HashMap; -import java.util.Map; /** * @author Takis Diakoumis @@ -76,7 +67,7 @@ public class ExecuteSqlScriptPanel extends DefaultTabViewActionPanel // --- GUI components --- - private JComboBox connectionsCombo; + private ConnectionsComboBox connectionsCombo; private JCheckBox useConnectionCheck; private JCheckBox stopOnErrorCheck; @@ -105,27 +96,18 @@ public class ExecuteSqlScriptPanel extends DefaultTabViewActionPanel private SwingWorker swingWorker; private SqlScriptRunner sqlScriptRunner; - private final Map connections; public ExecuteSqlScriptPanel() { super(new BorderLayout()); - - this.connections = new HashMap<>(); - init(); arrange(); } private void init() { - Repository repository = RepositoryCache.load(DatabaseConnectionRepository.REPOSITORY_ID); - if (repository != null) - for (DatabaseConnection dc : ((DatabaseConnectionRepository) repository).findAll()) - connections.put(dc.getName(), dc); - // --- comboBoxes --- - connectionsCombo = WidgetFactory.createComboBox("connectionsCombo", connections.keySet().toArray()); + connectionsCombo = WidgetFactory.createConnectionComboBox("connectionsCombo", false); connectionsCombo.setEnabled(false); // --- checkBoxes --- @@ -430,8 +412,7 @@ private SqlStatementResult execute() { } private DatabaseConnection getSelectedConnection() { - Object selectedValue = connectionsCombo.getSelectedItem(); - return selectedValue != null ? connections.get(selectedValue.toString()) : null; + return connectionsCombo.getSelectedConnection(); } private boolean fieldsValid() { diff --git a/src/org/executequery/gui/GenerateErdPanel.java b/src/org/executequery/gui/GenerateErdPanel.java index fca4f600b..128086964 100644 --- a/src/org/executequery/gui/GenerateErdPanel.java +++ b/src/org/executequery/gui/GenerateErdPanel.java @@ -21,7 +21,6 @@ package org.executequery.gui; import org.executequery.GUIUtilities; -import org.executequery.databasemediators.DatabaseConnection; import org.executequery.gui.erd.ErdGenerateProgressDialog; import org.executequery.gui.erd.ErdViewerPanel; import org.executequery.gui.erd.ErdSelectionPanel; @@ -42,17 +41,15 @@ public class GenerateErdPanel extends JPanel { private JButton generateButton; private JButton cancelButton; - private final DatabaseConnection connection; private final ErdViewerPanel erdPanel; private final ActionContainer parent; public GenerateErdPanel(ActionContainer parent) { - this(null, parent, null); + this(null, parent); } - public GenerateErdPanel(ErdViewerPanel erdPanel, ActionContainer parent, DatabaseConnection connection) { + public GenerateErdPanel(ErdViewerPanel erdPanel, ActionContainer parent) { super(new BorderLayout()); - this.connection = connection; this.erdPanel = erdPanel; this.parent = parent; @@ -61,7 +58,7 @@ public GenerateErdPanel(ErdViewerPanel erdPanel, ActionContainer parent, Databas } private void init() { - selectionPanel = new ErdSelectionPanel(connection, erdPanel); + selectionPanel = new ErdSelectionPanel(erdPanel); generateButton = WidgetFactory.createButton( "generateButton", diff --git a/src/org/executequery/gui/SaveOnExitDialog.java b/src/org/executequery/gui/SaveOnExitDialog.java index 99a36ad59..22a40130e 100644 --- a/src/org/executequery/gui/SaveOnExitDialog.java +++ b/src/org/executequery/gui/SaveOnExitDialog.java @@ -23,11 +23,10 @@ import org.executequery.GUIUtilities; import org.executequery.localization.Bundles; import org.underworldlabs.swing.AbstractBaseDialog; +import org.underworldlabs.swing.layouts.GridBagHelper; import javax.swing.*; import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.util.List; @@ -35,135 +34,92 @@ /** * @author Takis Diakoumis */ -public class SaveOnExitDialog extends AbstractBaseDialog - implements ActionListener { +public class SaveOnExitDialog extends AbstractBaseDialog { + public static final String TITLE = bundleString("title"); - public static final int DISCARD_OPTION = 0; - - /** - * The frames list - */ - private JList list; - - /** - * The button choice result - */ private int result; + private JList list; - public SaveOnExitDialog() { - - super(GUIUtilities.getParentFrame(), "Save Changes", true); - - result = SaveFunction.SAVE_CANCELLED; + private JButton saveButton; + private JButton discardButton; - try { + public SaveOnExitDialog() { + super(GUIUtilities.getParentFrame(), TITLE, true); - init(); + init(); + arrange(); + } - } catch (Exception e) { + private void init() { + List panels = GUIUtilities.getOpenSaveFunctionPanels(); - e.printStackTrace(); - } + saveButton = WidgetFactory.createButton("saveButton", Bundles.get("common.save.button"), e -> save()); + discardButton = WidgetFactory.createButton("discardButton", bundleString("discardButton"), e -> discardSaving()); - pack(); - setLocation(GUIUtilities.getLocationForDialog(getSize())); - setVisible(true); + list = new DefaultList(panels.toArray()); + list.setSelectionInterval(0, panels.size() - 1); } - private void init() throws Exception { + private void arrange() { + GridBagHelper gbh; - JButton saveButton = new JButton("Save Selected"); - JButton cancelButton = new JButton(Bundles.get("common.cancel.button")); - JButton discardButton = new JButton("Discard All"); + // --- button panel --- - Insets buttonInsets = new Insets(0, 0, 0, 0); - saveButton.setMargin(buttonInsets); - cancelButton.setMargin(buttonInsets); - discardButton.setMargin(buttonInsets); + JPanel buttonPanel = new JPanel(new GridBagLayout()); - Dimension buttonSize = new Dimension(130, 25); - saveButton.setPreferredSize(buttonSize); - cancelButton.setPreferredSize(buttonSize); - discardButton.setPreferredSize(buttonSize); + gbh = new GridBagHelper().fillHorizontally(); + buttonPanel.add(new JPanel(), gbh.setMaxWeightX().get()); + buttonPanel.add(saveButton, gbh.nextCol().setMinWeightX().fillNone().get()); + buttonPanel.add(discardButton, gbh.nextCol().leftGap(5).get()); - saveButton.addActionListener(this); - cancelButton.addActionListener(this); - discardButton.addActionListener(this); + // --- main panel --- - List panels = GUIUtilities.getOpenSaveFunctionPanels(); + JPanel mainPanel = new JPanel(new GridBagLayout()); - list = new DefaultList(panels.toArray()); - list.setSelectionInterval(0, panels.size() - 1); + gbh = new GridBagHelper().anchorNorthWest().fillHorizontally(); + mainPanel.add(new JLabel(bundleString("label")), gbh.spanX().get()); + mainPanel.add(new JScrollPane(list), gbh.nextRow().topGap(5).setMaxWeightY().fillBoth().get()); + mainPanel.add(buttonPanel, gbh.nextRow().setMinWeightY().get()); - JPanel base = new JPanel(new GridBagLayout()); - GridBagConstraints gbc = new GridBagConstraints(); - gbc.insets = new Insets(5, 5, 5, 5); - gbc.anchor = GridBagConstraints.NORTHWEST; - gbc.gridwidth = 3; - base.add(new JLabel("The following open frames have unsaved changes"), gbc); - gbc.gridy = 1; - gbc.fill = GridBagConstraints.BOTH; - gbc.weightx = 1.0; - gbc.weighty = 1.0; - gbc.insets.top = 0; - base.add(new JScrollPane(list), gbc); - gbc.fill = GridBagConstraints.HORIZONTAL; - gbc.weighty = 0; - gbc.gridwidth = 1; - gbc.gridy = 2; - base.add(saveButton, gbc); - gbc.insets.left = 0; - gbc.gridx = 1; - base.add(discardButton, gbc); - gbc.gridx = 2; - base.add(cancelButton, gbc); - - Container c = this.getContentPane(); - c.setLayout(new BorderLayout()); - c.add(base, BorderLayout.CENTER); + // --- base --- + + setLayout(new GridBagLayout()); + gbh = new GridBagHelper().setInsets(5, 5, 5, 5).fillBoth().spanX().spanY(); + add(mainPanel, gbh.get()); setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE); addWindowListener(new WindowAdapter() { + @Override public void windowClosing(WindowEvent e) { - result = SaveFunction.SAVE_CANCELLED; - dispose(); + discardSaving(); } }); + pack(); + setLocation(GUIUtilities.getLocationForDialog(getSize())); + setResizable(false); + setVisible(true); } - public int saveChanges() { - - int result = -1; - - Object[] selectedFrames = list.getSelectedValues(); - - for (int i = 0; i < selectedFrames.length; i++) { + private void save() { + result = SaveFunction.SAVE_CANCELLED; - SaveFunction saveFunction = (SaveFunction) selectedFrames[i]; - result = saveFunction.save(false); + for (Object selectedFrame : list.getSelectedValuesList()) { + if (selectedFrame instanceof SaveFunction) { - if (result != SaveFunction.SAVE_COMPLETE) { + SaveFunction saveFunction = (SaveFunction) selectedFrame; + result = saveFunction.save(false); - break; + if (result != SaveFunction.SAVE_COMPLETE) + break; } - } - return result; + dispose(); } - public void actionPerformed(ActionEvent e) { - String command = e.getActionCommand(); - - if (command.equals("Cancel")) { - result = SaveFunction.SAVE_CANCELLED; - } else if (command.equals("Discard All")) { - result = DISCARD_OPTION; - } else if (command.equals("Save Selected")) { - result = saveChanges(); - } - + private void discardSaving() { + result = SaveFunction.SAVE_CANCELLED; dispose(); } @@ -171,15 +127,8 @@ public int getResult() { return result; } -} - - - - - - - - - - + private static String bundleString(String key, Object... args) { + return Bundles.get(SaveOnExitDialog.class, key, args); + } +} diff --git a/src/org/executequery/gui/WidgetFactory.java b/src/org/executequery/gui/WidgetFactory.java index de9c0e8f4..c492883d4 100644 --- a/src/org/executequery/gui/WidgetFactory.java +++ b/src/org/executequery/gui/WidgetFactory.java @@ -21,7 +21,6 @@ package org.executequery.gui; import org.executequery.Constants; -import org.executequery.GUIUtilities; import org.executequery.gui.browser.DefaultInlineFieldButton; import org.underworldlabs.swing.*; @@ -249,6 +248,20 @@ public static JTextField createTextField(String name) { return textField; } + /** + * Create named JTextField class instance + * + * @param name the component's name + * @param editable the boolean to be set + */ + public static JTextField createTextField(String name, boolean editable) { + + JTextField textField = createTextField(name); + textField.setEditable(editable); + + return textField; + } + /** * Create named JTextField class instance * @@ -438,7 +451,7 @@ public static JTabbedPane createTabbedPane(String name) { */ public static JPanel createPanel(String name) { - JPanel panel = new JPanel(); + JPanel panel = new JPanel(new GridBagLayout()); panel.setName(name); return panel; @@ -490,6 +503,21 @@ public static JLabel createLabel(String text, int fontSize) { // --- Custom Components --- // ------------------------- + /** + * Create named ConnectionsComboBox class instance, + * that extended from JComboBox with the DatabaseConnection items + * with the automatically updated active connections list + * + * @param name the component's name + * @param showOnlyActiveConnections whether comboBox will contain only active connections + */ + public static ConnectionsComboBox createConnectionComboBox(String name, boolean showOnlyActiveConnections) { + + ConnectionsComboBox connectionsCombo = new ConnectionsComboBox(showOnlyActiveConnections); + connectionsCombo.setName(name); + + return connectionsCombo; + } /** * Create named DefaultInlineFieldButton class instance @@ -755,7 +783,10 @@ public static LinkLabel createLinkLabel(String name, String text, String link, i // ----------------------- private static Dimension getPreferredSize(JComponent component) { - return new Dimension((int) component.getPreferredSize().getWidth(), DEFAULT_HEIGHT); + return new Dimension( + (int) component.getPreferredSize().getWidth(), + (int) Math.max(DEFAULT_HEIGHT, component.getPreferredSize().getHeight()) + ); } public static int defaultHeight() { diff --git a/src/org/executequery/gui/browser/BrowserController.java b/src/org/executequery/gui/browser/BrowserController.java index ceb860326..037870ed0 100644 --- a/src/org/executequery/gui/browser/BrowserController.java +++ b/src/org/executequery/gui/browser/BrowserController.java @@ -26,8 +26,8 @@ import org.executequery.databaseobjects.DatabaseHost; import org.executequery.databaseobjects.DatabaseTable; import org.executequery.databaseobjects.NamedObject; -import org.executequery.databaseobjects.impl.*; import org.executequery.databaseobjects.impl.ColumnConstraint; +import org.executequery.databaseobjects.impl.*; import org.executequery.gui.BaseDialog; import org.executequery.gui.browser.nodes.DatabaseObjectNode; import org.executequery.gui.databaseobjects.AbstractCreateObjectPanel; @@ -170,11 +170,21 @@ protected void nodeNameValueChanged(DatabaseHost host) { * This void has been moved in BrowserTreePopupMenuActionListener */ public void valueChanged(DatabaseObjectNode node, DatabaseConnection connection) { + valueChanged(node, connection, true); + } + + /** + * This void has been moved in BrowserTreePopupMenuActionListener + */ + public void valueChanged(DatabaseObjectNode node, DatabaseConnection connection, boolean updatePropertiesPanel) { + + if (!isNodeObjectEditable(node)) + return; treePanel.setInProcess(true); try { - FormObjectView panel = buildPanelView(node); + FormObjectView panel = buildPanelView(node, updatePropertiesPanel); if (panel == null) return; @@ -182,9 +192,6 @@ public void valueChanged(DatabaseObjectNode node, DatabaseConnection connection) String type = ""; int nodeType = node.getType(); - if (NamedObject.isTableFolder(nodeType)) - return; - if (nodeType < NamedObject.META_TYPES.length) type = NamedObject.META_TYPES[node.getType()]; @@ -225,7 +232,7 @@ public void valueChanged(DatabaseObjectNode node, DatabaseConnection connection) * @param node the selected node */ @SuppressWarnings("DataFlowIssue") - private FormObjectView buildPanelView(DatabaseObjectNode node) { + private FormObjectView buildPanelView(DatabaseObjectNode node, boolean updatePropertiesPanel) { try { NamedObject databaseObject = node.getDatabaseObject(); @@ -247,7 +254,7 @@ private FormObjectView buildPanelView(DatabaseObjectNode node) { viewPanel = new BrowserViewPanel(this); HostPanel hostPanel = hostPanel(); - hostPanel.setValues((DatabaseHost) databaseObject); + hostPanel.setValues((DatabaseHost) databaseObject, updatePropertiesPanel); return hostPanel; } @@ -285,6 +292,7 @@ private FormObjectView buildPanelView(DatabaseObjectNode node) { case NamedObject.ROLE: case NamedObject.SYSTEM_DOMAIN: case NamedObject.SYSTEM_ROLE: + case NamedObject.SYSTEM_PACKAGE: case NamedObject.SYSTEM_FUNCTION: { AbstractCreateObjectPanel objectPanel = AbstractCreateObjectPanel @@ -313,20 +321,6 @@ private FormObjectView buildPanelView(DatabaseObjectNode node) { return triggerPanel; } - case NamedObject.SYSTEM_PACKAGE: { - - BrowserPackagePanel packagePanel; - if (!viewPanel.containsPanel(BrowserPackagePanel.NAME)) { - packagePanel = new BrowserPackagePanel(this); - viewPanel.addToLayout(packagePanel); - - } else - packagePanel = (BrowserPackagePanel) viewPanel.getFormObjectView(BrowserPackagePanel.NAME); - - packagePanel.setValues((DefaultDatabasePackage) databaseObject); - return packagePanel; - } - case NamedObject.SYSTEM_SEQUENCE: { BrowserSequencePanel sequencePanel; @@ -341,13 +335,12 @@ private FormObjectView buildPanelView(DatabaseObjectNode node) { return sequencePanel; } - case NamedObject.TABLE_INDEX: - case NamedObject.INDEX: { + case NamedObject.SYSTEM_INDEX: { try { GUIUtilities.showWaitCursor(); BaseDialog dialog = new BaseDialog(CreateIndexPanel.ALTER_TITLE, true); - CreateIndexPanel createObjectPanel = new CreateIndexPanel(connection, dialog, (DefaultDatabaseIndex) databaseObject); + CreateIndexPanel createObjectPanel = new CreateIndexPanel(connection, dialog, (DefaultDatabaseIndex) databaseObject, true); showDialogCreateObject(createObjectPanel, dialog); } finally { @@ -356,22 +349,24 @@ private FormObjectView buildPanelView(DatabaseObjectNode node) { return null; } - case NamedObject.SYSTEM_INDEX: { - - BrowserIndexPanel browserIndexPanel; - if (!viewPanel.containsPanel(BrowserIndexPanel.NAME)) { - browserIndexPanel = new BrowserIndexPanel(this); - viewPanel.addToLayout(browserIndexPanel); + case NamedObject.TABLE_INDEX: + case NamedObject.INDEX: { + try { - } else - browserIndexPanel = (BrowserIndexPanel) viewPanel.getFormObjectView(BrowserIndexPanel.NAME); + GUIUtilities.showWaitCursor(); + BaseDialog dialog = new BaseDialog(CreateIndexPanel.ALTER_TITLE, true); + CreateIndexPanel createObjectPanel = new CreateIndexPanel(connection, dialog, (DefaultDatabaseIndex) databaseObject); + showDialogCreateObject(createObjectPanel, dialog); - browserIndexPanel.setValues((DefaultDatabaseIndex) databaseObject); - return browserIndexPanel; + } finally { + GUIUtilities.showNormalCursor(); + } + return null; } case NamedObject.TABLE: - case NamedObject.GLOBAL_TEMPORARY: { + case NamedObject.GLOBAL_TEMPORARY: + case NamedObject.SYSTEM_TABLE: { BrowserTableEditingPanel editingPanel = viewPanel.getEditingPanel(); editingPanel.setValues((DatabaseTable) databaseObject); return editingPanel; @@ -463,6 +458,20 @@ private HostPanel hostPanel() { return hostPanel; } + private static boolean isNodeObjectEditable(DatabaseObjectNode node) { + + int nodeType = node.getType(); + if (NamedObject.isTableFolder(nodeType)) + return false; + + if (nodeType == NamedObject.TABLE_COLUMN) { + int parentType = ((DatabaseObjectNode) node.getParent()).getType(); + return parentType != NamedObject.VIEW; + } + + return true; + } + /** * Selects the node that matches the specified prefix forward * from the currently selected node. diff --git a/src/org/executequery/gui/browser/BrowserIndexPanel.java b/src/org/executequery/gui/browser/BrowserIndexPanel.java deleted file mode 100644 index d90d7f770..000000000 --- a/src/org/executequery/gui/browser/BrowserIndexPanel.java +++ /dev/null @@ -1,222 +0,0 @@ -package org.executequery.gui.browser; - -import org.executequery.GUIUtilities; -import org.executequery.databaseobjects.DatabaseObject; -import org.executequery.databaseobjects.NamedObject; -import org.executequery.databaseobjects.impl.DefaultDatabaseIndex; -import org.executequery.databaseobjects.impl.DefaultDatabaseMetaTag; -import org.executequery.gui.IconManager; -import org.executequery.gui.forms.AbstractFormObjectViewPanel; -import org.executequery.gui.text.SimpleSqlTextPanel; -import org.executequery.localization.Bundles; -import org.underworldlabs.jdbc.DataSourceException; -import org.underworldlabs.swing.DefaultComboBox; -import org.underworldlabs.swing.DisabledField; -import org.underworldlabs.swing.StyledLogPane; -import org.underworldlabs.swing.layouts.GridBagHelper; - -import javax.swing.*; -import java.awt.*; -import java.awt.print.Printable; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Created by vasiliy on 15.02.17. - */ -public class BrowserIndexPanel extends AbstractFormObjectViewPanel { - - public static final String NAME = "BrowserIndexPanel"; - - private DependenciesPanel dependenciesPanel; - - private DisabledField indexNameField; - - private JLabel objectNameLabel; - - /** - * the current database object in view - */ - private DatabaseObject currentObjectView; - - /** - * The tabbed description pane - */ - private JTabbedPane tabPane; - - private JTextPane descriptionPane; - - private Map cache; - - List columns = new ArrayList(); - - private JTable table; - - private DefaultDatabaseIndex.IndexColumnsModel model; - - private JCheckBox uniqueCheckBox; - private JTextField tableField; - private JComboBox sortingComboBox; - private JCheckBox activeCheckBox; - private SimpleSqlTextPanel expressionText; - - /** - * the browser's control object - */ - private final BrowserController controller; - - public BrowserIndexPanel(BrowserController controller) { - super(); - this.controller = controller; - - try { - init(); - } catch (Exception e) { - e.printStackTrace(); - } - - } - - private void init() { - JPanel fieldsPanel = new JPanel(new GridBagLayout()); - dependenciesPanel = new DependenciesPanel(); - model = new DefaultDatabaseIndex.IndexColumnsModel(columns); - table = new JTable(model); - GridBagConstraints gbc_def = new GridBagConstraints(); - gbc_def.fill = GridBagConstraints.HORIZONTAL; - gbc_def.anchor = GridBagConstraints.NORTHWEST; - gbc_def.insets = new Insets(10, 10, 10, 10); - gbc_def.gridy = -1; - gbc_def.gridx = 0; - GridBagHelper gbh = new GridBagHelper(); - gbh.setDefaults(gbc_def).defaults(); - fieldsPanel.add( - new JScrollPane(table), gbh.nextRowFirstCol().fillBoth().spanX().spanY().get()); - tabPane = new JTabbedPane(JTabbedPane.TOP); - tabPane.add(bundleString("IncludedFields"), fieldsPanel); - JPanel descriptionPanel = new JPanel(new BorderLayout()); - - descriptionPanel.setBorder(BorderFactory.createEtchedBorder()); - - descriptionPane = new StyledLogPane(); - - descriptionPanel.add(descriptionPane, BorderLayout.CENTER); - - tabPane.add(Bundles.getCommon("description"), descriptionPanel); - tabPane.add(Bundles.getCommon("dependencies"), dependenciesPanel); - - objectNameLabel = new JLabel(); - indexNameField = new DisabledField(); - - tableField = new DisabledField(); - uniqueCheckBox = new JCheckBox(bundleString("Unique")); - uniqueCheckBox.setEnabled(false); - uniqueCheckBox.setSelected(false); - activeCheckBox = new JCheckBox(bundleString("Active")); - activeCheckBox.setSelected(false); - activeCheckBox.setEnabled(false); - sortingComboBox = new DefaultComboBox(); - List sorting = new ArrayList<>(); - sorting.add(bundleString("Ascending")); - sorting.add(bundleString("Descending")); - sortingComboBox.setModel(new DefaultComboBoxModel(sorting.toArray())); - - JPanel base = new JPanel(new GridBagLayout()); - gbh.defaults(); - base.add(editButton, gbh.get()); - gbh.nextRowFirstCol(); - gbh.addLabelFieldPair(base, objectNameLabel, indexNameField, null); - gbh.addLabelFieldPair(base, bundleString("TableName"), tableField, null); - gbh.addLabelFieldPair(base, bundleString("Sorting"), sortingComboBox, null); - base.add(activeCheckBox, gbh.nextRowFirstCol().setLabelDefault().get()); - base.add(uniqueCheckBox, gbh.nextCol().get()); - base.add(tabPane, gbh.nextRowFirstCol().fillBoth().spanX().spanY().get()); - - - setHeaderText("Database UDF"); - setHeaderIcon(IconManager.getIcon(BrowserConstants.INDEXES_IMAGE)); - setContentPanel(base); - cache = new HashMap(); - - } - - public String getLayoutName() { - return NAME; - } - - @Override - public void cleanup() { - super.cleanup(); - } - - @Override - public Printable getPrintable() { - return null; - } - - public void setValues(DefaultDatabaseIndex index) { - dependenciesPanel.setDatabaseObject(index); - if (index.getParent().getMetaDataKey() != NamedObject.META_TYPES[NamedObject.SYSTEM_INDEX]) { - DefaultDatabaseMetaTag metaTag = (DefaultDatabaseMetaTag) index.getParent(); - currentObjectView = metaTag.getIndexFromName(index.getName()); - index = (DefaultDatabaseIndex) currentObjectView; - } else { - currentObjectView = index; - } - - columns.clear(); - for (DefaultDatabaseIndex.DatabaseIndexColumn column : index.getIndexColumns()) - columns.add(column); - - model = new DefaultDatabaseIndex.IndexColumnsModel(columns); - - tableField.setText(index.getTableName()); - sortingComboBox.setSelectedIndex(index.getIndexType()); - uniqueCheckBox.setSelected(index.isUnique()); - activeCheckBox.setSelected(index.isActive()); - descriptionPane.setText(index.getRemarks()); - if (index.getExpression() != null) { - expressionText = new SimpleSqlTextPanel(); - expressionText.setSQLText(index.getExpression()); - tabPane.remove(0); - tabPane.insertTab("Expression", null, expressionText, null, 0); - tabPane.setSelectedIndex(0); - } - - objectNameLabel.setText(bundleString("IndexName")); - setHeaderText(bundleString("DatabaseIndex")); - setHeaderIcon(IconManager.getIcon(BrowserConstants.INDEXES_IMAGE)); - - try { - indexNameField.setText(index.getName()); - descriptionPane.setText(index.getRemarks()); - } catch (DataSourceException e) { - controller.handleException(e); - } - - } - - public void setValues(BaseDatabaseObject metaObject) { - DefaultDatabaseIndex index = (DefaultDatabaseIndex) cache.get(metaObject); - setValues(metaObject, index); - } - - public void setValues(BaseDatabaseObject metaObject, DefaultDatabaseIndex index) { - - objectNameLabel.setText(bundleString("IndexName")); - setHeaderText(bundleString("DatabaseIndex")); - setHeaderIcon(IconManager.getIcon(BrowserConstants.INDEXES_IMAGE)); - - if (index != null) { - indexNameField.setText(index.getName()); - descriptionPane.setText(index.getRemarks()); - - } else { - indexNameField.setText(metaObject.getName()); - } - - } - -} \ No newline at end of file diff --git a/src/org/executequery/gui/browser/BrowserPackagePanel.java b/src/org/executequery/gui/browser/BrowserPackagePanel.java deleted file mode 100644 index 0b2703b5c..000000000 --- a/src/org/executequery/gui/browser/BrowserPackagePanel.java +++ /dev/null @@ -1,203 +0,0 @@ -package org.executequery.gui.browser; - -import org.executequery.databaseobjects.impl.DefaultDatabasePackage; -import org.executequery.gui.IconManager; -import org.executequery.gui.forms.AbstractFormObjectViewPanel; -import org.executequery.gui.text.SQLTextArea; -import org.executequery.localization.Bundles; -import org.underworldlabs.jdbc.DataSourceException; -import org.underworldlabs.swing.DisabledField; -import org.underworldlabs.swing.StyledLogPane; - -import javax.swing.*; -import java.awt.*; -import java.awt.print.Printable; -import java.util.HashMap; -import java.util.Map; - -/** - * Created by vasiliy on 04.05.17. - */ -public class BrowserPackagePanel extends AbstractFormObjectViewPanel { - public static final String NAME = "BrowserPackagePanel"; - - private DependenciesPanel dependenciesPanel; - - private DisabledField packageNameField; - - private JLabel objectNameLabel; - - JTextPane descriptionPane; - SQLTextArea sqlPane; - - private Map cache; - - SQLTextArea headerTextPane; - SQLTextArea bodyTextPane; - - /** - * the browser's control object - */ - private final BrowserController controller; - - public BrowserPackagePanel(BrowserController controller) { - super(); - this.controller = controller; - - try { - init(); - } catch (Exception e) { - e.printStackTrace(); - } - - } - - private void init() throws Exception { - - dependenciesPanel = new DependenciesPanel(); - - JPanel panel = new JPanel(); - - panel.setLayout(new BorderLayout()); - - JPanel headerPanel = new JPanel(new BorderLayout()); - headerTextPane = new SQLTextArea(); - headerTextPane.setEditable(false); - headerPanel.add(new JScrollPane(headerTextPane), BorderLayout.CENTER); - - panel.add(headerPanel, BorderLayout.CENTER); - - JTabbedPane tabs = new JTabbedPane(JTabbedPane.TOP); - tabs.add("Package Header", panel); - - JPanel bodyPanel = new JPanel(new BorderLayout()); - bodyTextPane = new SQLTextArea(); - bodyTextPane.setEditable(false); - bodyPanel.add(new JScrollPane(bodyTextPane), BorderLayout.CENTER); - - panel.add(headerPanel, BorderLayout.CENTER); - - tabs.add("Package Body", bodyPanel); - - JPanel descriptionPanel = new JPanel(new BorderLayout()); - descriptionPanel.setBorder(BorderFactory.createEtchedBorder()); - - descriptionPane = new StyledLogPane(); - - descriptionPanel.add(descriptionPane, BorderLayout.CENTER); - - //addPrivilegesTab(tabs); - - tabs.add("Description", descriptionPanel); - - JPanel sqlPanel = new JPanel(new BorderLayout()); - sqlPanel.setBorder(BorderFactory.createEtchedBorder()); - - sqlPane = new SQLTextArea(); - - sqlPanel.add(sqlPane, BorderLayout.CENTER); - - tabs.add("Sql", sqlPanel); - tabs.add(Bundles.getCommon("dependencies"), dependenciesPanel); - - objectNameLabel = new JLabel(); - packageNameField = new DisabledField(); - - JPanel base = new JPanel(new GridBagLayout()); - GridBagConstraints gbc = new GridBagConstraints(); - Insets insets = new Insets(10, 10, 5, 5); - gbc.anchor = GridBagConstraints.NORTHEAST; - gbc.fill = GridBagConstraints.HORIZONTAL; - gbc.gridx++; - gbc.insets = insets; - gbc.gridy = 0; - base.add(editButton, gbc); - gbc.gridy++; - base.add(objectNameLabel, gbc); - gbc.gridy++; - gbc.insets.top = 0; - gbc.insets.right = 5; - gbc.insets.right = 10; - gbc.gridy++; - gbc.weightx = 1.0; - gbc.weighty = 1.0; - gbc.gridwidth = 2; - gbc.insets.bottom = 10; - gbc.fill = GridBagConstraints.BOTH; - base.add(tabs, gbc); - gbc.fill = GridBagConstraints.HORIZONTAL; - gbc.insets.left = 5; - gbc.insets.top = 10; - gbc.gridwidth = 1; - gbc.weighty = 0; - gbc.gridy = 1; - gbc.gridx = 1; - base.add(packageNameField, gbc); - ++gbc.gridy; - gbc.insets.top = 0; - - setHeaderText("Database Package"); - setHeaderIcon(IconManager.getIcon(BrowserConstants.PACKAGE_IMAGE)); - setContentPanel(base); - cache = new HashMap(); - - } - - public String getLayoutName() { - return NAME; - } - - public Printable getPrintable() { - return null; - } - - public void refresh() { - cache.clear(); - } - - public void cleanup() { - super.cleanup(); - sqlPane.cleanup(); - headerTextPane.cleanup(); - bodyTextPane.cleanup(); - } - - public void setValues(DefaultDatabasePackage databasePackage) { - - dependenciesPanel.setDatabaseObject(databasePackage); - objectNameLabel.setText("Package Name:"); - setHeaderText("Database Package"); - setHeaderIcon(IconManager.getIcon(BrowserConstants.PACKAGE_IMAGE)); - - try { - packageNameField.setText(databasePackage.getName()); - headerTextPane.setText(databasePackage.getHeaderSource()); - bodyTextPane.setText(databasePackage.getBodySource()); - - descriptionPane.setText(databasePackage.getDescription()); - sqlPane.setText(databasePackage.getCreateSQLText()); - } catch (DataSourceException e) { - controller.handleException(e); - } - - } - - public void setValues(BaseDatabaseObject metaObject) { - DefaultDatabasePackage databasePackage = (DefaultDatabasePackage) cache.get(metaObject); - setValues(metaObject, databasePackage); - } - - public void setValues(BaseDatabaseObject metaObject, DefaultDatabasePackage databasePackage) { - - objectNameLabel.setText("Package Name:"); - setHeaderText("Database Package"); - setHeaderIcon(IconManager.getIcon(BrowserConstants.PACKAGE_IMAGE)); - - if (databasePackage != null) { - packageNameField.setText(databasePackage.getName()); - } else { - packageNameField.setText(metaObject.getName()); - } - } - -} diff --git a/src/org/executequery/gui/browser/BrowserSequencePanel.java b/src/org/executequery/gui/browser/BrowserSequencePanel.java index 02c0caf33..a714badb5 100644 --- a/src/org/executequery/gui/browser/BrowserSequencePanel.java +++ b/src/org/executequery/gui/browser/BrowserSequencePanel.java @@ -99,7 +99,7 @@ private void init() { sqlPanel.add(sqlPane, BorderLayout.CENTER); - tabs.add("Sql", sqlPanel); + tabs.add("SQL", sqlPanel); tabs.add(Bundles.getCommon("dependencies"), dependenciesPanel); objectNameLabel = new JLabel(); diff --git a/src/org/executequery/gui/browser/BrowserTableEditingPanel.java b/src/org/executequery/gui/browser/BrowserTableEditingPanel.java index d4436a414..98cda5e8a 100644 --- a/src/org/executequery/gui/browser/BrowserTableEditingPanel.java +++ b/src/org/executequery/gui/browser/BrowserTableEditingPanel.java @@ -594,7 +594,7 @@ private void editDescription(MouseEvent e) { BaseDialog dialog = new BaseDialog(InsertColumnPanel.EDIT_TITLE, true); InsertColumnPanel panel = new InsertColumnPanel(table, dialog, column); - dialog.addDisplayComponent(panel); + dialog.addDisplayComponentWithEmptyBorder(panel); dialog.display(); table.reset(); reloadView(); @@ -1359,6 +1359,7 @@ public void refresh() { private class PropertiesPanel extends JPanel { private static final String NONE = "NONE"; + private static final String PRIMARY = "PRIMARY"; private List oldValues; private DynamicComboBoxModel tablespaceComboModel; @@ -1436,7 +1437,7 @@ private void populateTablespace() { .getDatabaseObjectsForMetaTag(NamedObject.META_TYPES[NamedObject.TABLESPACE]); List tablespaceNameList = new ArrayList<>(); - tablespaceNameList.add(0, NONE); + tablespaceNameList.add(0, PRIMARY); if (tablespaceList != null && !tablespaceList.isEmpty()) tablespaceNameList.addAll(tablespaceList.stream().map(Named::getName).collect(Collectors.toList())); @@ -1457,7 +1458,7 @@ protected void update() { tablespaceComboBox.setEnabled(false); sqlSecurityComboBox.setSelectedItem(Objects.equals(sqlSecurity, "") ? NONE : sqlSecurity); - tablespaceComboBox.setSelectedItem(Objects.equals(tablespace, "") ? NONE : tablespace); + tablespaceComboBox.setSelectedItem(Objects.equals(tablespace, "") ? PRIMARY : tablespace); externalCheckBox.setSelected(externalFile != null && !externalFile.isEmpty()); adapterCheckBox.setSelected(adapter != null && !adapter.isEmpty()); externalFileTextField.setText(externalFile); diff --git a/src/org/executequery/gui/browser/BrowserTreePopupMenu.java b/src/org/executequery/gui/browser/BrowserTreePopupMenu.java index 396a70a0b..e7cbce000 100644 --- a/src/org/executequery/gui/browser/BrowserTreePopupMenu.java +++ b/src/org/executequery/gui/browser/BrowserTreePopupMenu.java @@ -114,8 +114,8 @@ private void buildPopup() { DatabaseObjectNode objectNode = (DatabaseObjectNode) treeNode; int nodeType = objectNode.getType(); - String labelMultiple = Bundles.get(NamedObject.class, getMetaTag(objectNode)).toLowerCase(); - String labelSingle = Bundles.get(BrowserTreePopupMenu.class, getMetaTag(objectNode)).toLowerCase(); + String labelSingle = bundleString(getMetaTag(objectNode)); + String labelMultiple = bundleString(getMetaTag(objectNode) + ".multiple"); // --- system objects popup --- @@ -181,27 +181,32 @@ private void buildPopup() { boolean isTable = nodeType == NamedObject.TABLE; boolean isIndex = nodeType == NamedObject.INDEX; boolean isSeveralSelected = listener.isSelectedSeveralPaths(); + boolean isViewColumn = nodeType == NamedObject.TABLE_COLUMN + && ((DatabaseObjectNode) objectNode.getParent()).getType() == NamedObject.VIEW; // --- - if (!isSeveralSelected) { - createObject.setText(bundleString("create", labelSingle)); - add(createObject); - addSeparator(); - } + if (!isViewColumn) { - reloadObject.setText(bundleString("reload", isSeveralSelected ? labelMultiple : labelSingle)); - add(reloadObject); + if (!isSeveralSelected) { + createObject.setText(bundleString("create", labelSingle)); + add(createObject); + addSeparator(); + } - if (!isSeveralSelected) { - editObject.setText(bundleString("edit", labelSingle)); - add(editObject); - } + reloadObject.setText(bundleString("reload", isSeveralSelected ? labelMultiple : labelSingle)); + add(reloadObject); - if (!isSeveralSelected) { - deleteObject.setText(bundleString("delete", labelSingle)); - add(deleteObject); - addSeparator(); + if (!isSeveralSelected) { + editObject.setText(bundleString("edit", labelSingle)); + add(editObject); + } + + if (!isSeveralSelected) { + deleteObject.setText(bundleString("delete", labelSingle)); + add(deleteObject); + addSeparator(); + } } if (isIndex) diff --git a/src/org/executequery/gui/browser/BrowserTreePopupMenuActionListener.java b/src/org/executequery/gui/browser/BrowserTreePopupMenuActionListener.java index 283d6bbe6..889589957 100644 --- a/src/org/executequery/gui/browser/BrowserTreePopupMenuActionListener.java +++ b/src/org/executequery/gui/browser/BrowserTreePopupMenuActionListener.java @@ -296,15 +296,17 @@ public void showCreateObjectDialog(DatabaseObjectNode node, DatabaseConnection c try { GUIUtilities.showWaitCursor(); - BaseDialog dialog = new BaseDialog("", false); - AbstractCreateObjectPanel panel = editing ? - getEditObjectPanel(node, dialog, connection) : - getCreateObjectPanel(node, dialog, connection); + if (editing) { + treePanel.valueChanged(node, connection); + return; + } + BaseDialog dialog = new BaseDialog("", false); + AbstractCreateObjectPanel panel = getCreateObjectPanel(node, dialog, connection); if (panel == null) return; - String title = editing ? panel.getEditTitle() : panel.getCreateTitle(); + String title = panel.getCreateTitle(); if (GUIUtilities.isDialogOpen(title)) { GUIUtilities.setSelectedDialog(title); return; @@ -442,108 +444,6 @@ private AbstractCreateObjectPanel getCreateObjectPanel(DatabaseObjectNode node, return panel; } - private AbstractCreateObjectPanel getEditObjectPanel(DatabaseObjectNode node, BaseDialog - dialog, DatabaseConnection connection) { - - int type = node.getType(); - if (type == NamedObject.META_TAG) { - for (int i = 0; i < NamedObject.META_TYPES.length; i++) { - if (NamedObject.META_TYPES[i].equals(node.getMetaDataKey())) { - type = i; - break; - } - } - } - - ColumnConstraint constraint; - AbstractCreateObjectPanel panel = null; - switch (type) { - - case NamedObject.TABLE: - case NamedObject.GLOBAL_TEMPORARY: - case NamedObject.ROLE: - treePanel.valueChanged(node, connection); - break; - - case NamedObject.SEQUENCE: - panel = new CreateGeneratorPanel(connection, dialog, (DefaultDatabaseSequence) node.getDatabaseObject()); - break; - - case NamedObject.VIEW: - panel = new CreateViewPanel(connection, dialog, (DefaultDatabaseView) node.getDatabaseObject()); - break; - - case NamedObject.PROCEDURE: - if (node.getDatabaseObject().getParent().getType() == NamedObject.PACKAGE) { - GUIUtilities.displayErrorMessage(bundledString("temporaryInconvenience")); - break; - } - panel = new CreateProcedurePanel(connection, dialog, MiscUtils.trimEnd(node.getName())); - break; - - case NamedObject.DOMAIN: - panel = new CreateDomainPanel(connection, dialog, MiscUtils.trimEnd(node.getName())); - break; - - case NamedObject.TRIGGERS_FOLDER_NODE: - type = NamedObject.TRIGGER; - case NamedObject.TRIGGER: - case NamedObject.DATABASE_TRIGGER: - case NamedObject.DDL_TRIGGER: - panel = new CreateTriggerPanel(connection, dialog, (DefaultDatabaseTrigger) node.getDatabaseObject(), type); - break; - - case NamedObject.EXCEPTION: - panel = new CreateExceptionPanel(connection, dialog, (DefaultDatabaseException) node.getDatabaseObject()); - break; - - case NamedObject.INDEX: - case NamedObject.INDEXES_FOLDER_NODE: - panel = new CreateIndexPanel(connection, dialog, (DefaultDatabaseIndex) node.getDatabaseObject()); - break; - - case NamedObject.FUNCTION: - if (node.getDatabaseObject().getParent().getType() == NamedObject.PACKAGE) { - GUIUtilities.displayErrorMessage(bundledString("temporaryInconvenience")); - break; - } - panel = new CreateFunctionPanel(connection, dialog, MiscUtils.trimEnd(node.getName()), (DefaultDatabaseFunction) node.getDatabaseObject()); - break; - - case NamedObject.UDF: - panel = new CreateUDFPanel(connection, dialog, node.getDatabaseObject()); - break; - - case NamedObject.PACKAGE: - panel = new CreatePackagePanel(connection, dialog, (DefaultDatabasePackage) node.getDatabaseObject()); - break; - - case NamedObject.USER: - panel = new CreateDatabaseUserPanel(connection, dialog, (DefaultDatabaseUser) node.getDatabaseObject()); - break; - - case NamedObject.TABLESPACE: - panel = new CreateTablespacePanel(connection, dialog, node.getDatabaseObject()); - break; - - case NamedObject.TABLE_COLUMN: - panel = new InsertColumnPanel((DatabaseTableColumn) node.getDatabaseObject(), dialog, true); - break; - - case NamedObject.PRIMARY_KEY: - case NamedObject.FOREIGN_KEY: - constraint = (ColumnConstraint) node.getDatabaseObject(); - panel = new EditConstraintPanel(constraint.getTable(), dialog, constraint); - break; - - default: - GUIUtilities.displayErrorMessage(bundledString("temporaryInconvenience")); - break; - } - - return panel; - } - private String getDropQuery(DatabaseObjectNode node, int nodeType) { if (nodeType == NamedObject.TABLE_COLUMN) { diff --git a/src/org/executequery/gui/browser/BrowserTriggerPanel.java b/src/org/executequery/gui/browser/BrowserTriggerPanel.java index 650595570..047b46d4a 100644 --- a/src/org/executequery/gui/browser/BrowserTriggerPanel.java +++ b/src/org/executequery/gui/browser/BrowserTriggerPanel.java @@ -123,7 +123,7 @@ private void init() { sqlPanel.add(new JScrollPane(sqlPane), BorderLayout.CENTER); - tabs.add("Sql", sqlPanel); + tabs.add("SQL", sqlPanel); tabs.add(Bundles.getCommon("dependencies"), dependenciesPanel); objectNameLabel = new JLabel(); diff --git a/src/org/executequery/gui/browser/ComparerDBPanel.java b/src/org/executequery/gui/browser/ComparerDBPanel.java index 008ada572..c6029703a 100644 --- a/src/org/executequery/gui/browser/ComparerDBPanel.java +++ b/src/org/executequery/gui/browser/ComparerDBPanel.java @@ -1,5 +1,6 @@ package org.executequery.gui.browser; +import org.executequery.Constants; import org.executequery.GUIUtilities; import org.executequery.base.TabView; import org.executequery.databasemediators.ConnectionMediator; @@ -11,6 +12,7 @@ import org.executequery.datasource.SimpleDataSource; import org.executequery.gui.IconManager; import org.executequery.gui.LoggingOutputPanel; +import org.executequery.gui.WidgetFactory; import org.executequery.gui.browser.comparer.ComparedObject; import org.executequery.gui.browser.comparer.Comparer; import org.executequery.gui.editor.QueryEditor; @@ -19,10 +21,9 @@ import org.executequery.gui.text.SimpleSqlTextPanel; import org.executequery.localization.Bundles; import org.executequery.log.Log; -import org.executequery.repository.DatabaseConnectionRepository; -import org.executequery.repository.RepositoryCache; import org.underworldlabs.jdbc.DataSourceException; import org.underworldlabs.swing.BackgroundProgressDialog; +import org.underworldlabs.swing.ConnectionsComboBox; import org.underworldlabs.swing.layouts.GridBagHelper; import org.underworldlabs.swing.tree.AbstractTreeCellRenderer; import org.underworldlabs.swing.util.SwingWorker; @@ -72,7 +73,6 @@ public class ComparerDBPanel extends JPanel implements TabView { private Comparer comparer; private List scriptGenerationOrder; private List comparedObjectList; - private List databaseConnectionList; private static final List busyConnectionList = new ArrayList<>(); private boolean isComparing; @@ -82,8 +82,9 @@ public class ComparerDBPanel extends JPanel implements TabView { // --- panel components --- - private JComboBox dbMasterComboBox; - private JComboBox dbTargetComboBox; + private ConnectionsComboBox dbMasterComboBox; + private ConnectionsComboBox dbTargetComboBox; + private JButton compareButton; private JButton saveScriptButton; private JButton executeScriptButton; @@ -92,56 +93,62 @@ public class ComparerDBPanel extends JPanel implements TabView { private JButton switchTargetSourceButton; private JTabbedPane tabPane; - private LoggingOutputPanel loggingOutputPanel; private SimpleSqlTextPanel sqlTextPanel; + private LoggingOutputPanel loggingOutputPanel; private DifferenceSqlTextPanel differenceSqlTextPanel; + private JTree dbComponentsTree; private ComparerTreeNode rootTreeNode; private JProgressBar progressBar; private BackgroundProgressDialog progressDialog; + private List erdTables; private Map attributesCheckBoxMap; private Map propertiesCheckBoxMap; - private List erdTables; private StringBuilder settingScriptProps; // --- public ComparerDBPanel() { + this.isExtractMetadata = false; + this.isErd = false; - isExtractMetadata = false; - isErd = false; init(); + arrange(); } public ComparerDBPanel(List tables, DatabaseConnection databaseConnection) { - isErd = true; - isExtractMetadata = databaseConnection == null; + this.isExtractMetadata = databaseConnection == null; + this.isErd = true; + this.erdTables = new ArrayList<>(); - for (ErdTable erd : tables) { + for (ErdTable erd : tables) erdTables.add(new DefaultDatabaseTable(erd)); - } + init(); + arrange(); if (databaseConnection != null) { - dbTargetComboBox.setSelectedItem(databaseConnection.getName()); - dbMasterComboBox.setSelectedItem(databaseConnection.getName()); + dbTargetComboBox.setSelectedItem(databaseConnection); + dbMasterComboBox.setSelectedItem(databaseConnection); } + if (databaseConnection != null) attributesCheckBoxMap.values().forEach(checkBox -> checkBox.setSelected(true)); } - public ComparerDBPanel(DatabaseConnection dc) { + public ComparerDBPanel(DatabaseConnection databaseConnection) { + this.isExtractMetadata = true; + this.isErd = false; - isExtractMetadata = true; - isErd = false; init(); + arrange(); - if (dc != null) { - dbTargetComboBox.setSelectedItem(dc.getName()); - dbMasterComboBox.setSelectedItem(dc.getName()); + if (databaseConnection != null) { + dbTargetComboBox.setSelectedItem(databaseConnection); + dbMasterComboBox.setSelectedItem(databaseConnection); } attributesCheckBoxMap.values().forEach(checkBox -> checkBox.setSelected(true)); @@ -149,11 +156,9 @@ public ComparerDBPanel(DatabaseConnection dc) { private void init() { - databaseConnectionList = new ArrayList<>(); - comparedObjectList = new ArrayList<>(); - isComparing = false; isReverseOrder = false; + comparedObjectList = new ArrayList<>(); // --- script generation order defining --- @@ -162,30 +167,42 @@ private void init() { // --- buttons defining --- - compareButton = new JButton(); - compareButton.setText(bundleString(isExtractMetadata ? "CompareExportButton" : "CompareButton")); - compareButton.addActionListener(e -> compareDatabase()); + compareButton = WidgetFactory.createButton( + "compareButton", + bundleString(isExtractMetadata ? "CompareExportButton" : "CompareButton"), + e -> compareDatabase() + ); - saveScriptButton = new JButton(); - saveScriptButton.setText(bundleString("SaveScriptButton")); - saveScriptButton.addActionListener(e -> saveScript()); + saveScriptButton = WidgetFactory.createButton( + "saveScriptButton", + bundleString("SaveScriptButton"), + e -> saveScript() + ); - executeScriptButton = new JButton(); - executeScriptButton.setText(bundleString("ExecuteScriptButton")); - executeScriptButton.addActionListener(e -> executeScript()); + executeScriptButton = WidgetFactory.createButton( + "executeScriptButton", + bundleString("ExecuteScriptButton"), + e -> executeScript() + ); - selectAllAttributesButton = new JButton(); - selectAllAttributesButton.setText(bundleString("SelectAllButton")); - selectAllAttributesButton.addActionListener(e -> selectAll("attributes")); + selectAllAttributesButton = WidgetFactory.createButton( + "selectAllAttributesButton", + bundleString("SelectAllButton"), + e -> selectAll("attributes") + ); - selectAllPropertiesButton = new JButton(); - selectAllPropertiesButton.setText(bundleString("SelectAllButton")); - selectAllPropertiesButton.addActionListener(e -> selectAll("properties")); + selectAllPropertiesButton = WidgetFactory.createButton( + "selectAllPropertiesButton", + bundleString("SelectAllButton"), + e -> selectAll("properties") + ); - switchTargetSourceButton = new JButton(); - switchTargetSourceButton.setText("

"); // Unicode Character '⇅' (U+21C5) - switchTargetSourceButton.addActionListener(e -> switchTargetSource()); + switchTargetSourceButton = WidgetFactory.createButton( + "switchTargetSourceButton", + "

", + e -> switchTargetSource()); switchTargetSourceButton.setVisible(!isExtractMetadata); + switchTargetSourceButton.setHorizontalTextPosition(SwingConstants.LEFT); // --- attributes checkBox defining --- @@ -199,23 +216,23 @@ private void init() { if (checkBoxText.isEmpty()) checkBoxText = Bundles.get(NamedObject.class, NamedObject.META_TYPES_FOR_BUNDLE[objectType]); - attributesCheckBoxMap.put(objectType, new JCheckBox(checkBoxText)); + JCheckBox checkBox = WidgetFactory.createCheckBox(NamedObject.META_TYPES_FOR_BUNDLE[objectType] + "_CHECK", checkBoxText); + attributesCheckBoxMap.put(objectType, checkBox); } // --- properties checkBox defining --- propertiesCheckBoxMap = new LinkedHashMap<>(); - propertiesCheckBoxMap.put(CHECK_CREATE, new JCheckBox(bundleString("CheckCreate"))); - propertiesCheckBoxMap.put(CHECK_ALTER, new JCheckBox(bundleString("CheckAlter"))); - propertiesCheckBoxMap.put(CHECK_DROP, new JCheckBox(bundleString("CheckDrop"))); - propertiesCheckBoxMap.put(IGNORE_COMMENTS, new JCheckBox(bundleString(("IgnoreComments")))); - propertiesCheckBoxMap.put(IGNORE_COMPUTED_FIELDS, new JCheckBox(bundleString(("IgnoreComputed")))); - propertiesCheckBoxMap.put(IGNORE_FIELDS_POSITIONS, new JCheckBox(bundleString(("IgnorePositions")))); - propertiesCheckBoxMap.put(IGNORE_PK, new JCheckBox(bundleString("IgnorePK"))); - propertiesCheckBoxMap.put(IGNORE_FK, new JCheckBox(bundleString("IgnoreFK"))); - propertiesCheckBoxMap.put(IGNORE_UK, new JCheckBox(bundleString("IgnoreUK"))); - propertiesCheckBoxMap.put(IGNORE_CK, new JCheckBox(bundleString("IgnoreCK"))); - + propertiesCheckBoxMap.put(CHECK_CREATE, WidgetFactory.createCheckBox("checkCreate", bundleString("CheckCreate"))); + propertiesCheckBoxMap.put(CHECK_ALTER, WidgetFactory.createCheckBox("checkAlter", bundleString("CheckAlter"))); + propertiesCheckBoxMap.put(CHECK_DROP, WidgetFactory.createCheckBox("checkDrop", bundleString("CheckDrop"))); + propertiesCheckBoxMap.put(IGNORE_COMMENTS, WidgetFactory.createCheckBox("ignoreComments", bundleString(("IgnoreComments")))); + propertiesCheckBoxMap.put(IGNORE_COMPUTED_FIELDS, WidgetFactory.createCheckBox("ignoreComputed", bundleString(("IgnoreComputed")))); + propertiesCheckBoxMap.put(IGNORE_FIELDS_POSITIONS, WidgetFactory.createCheckBox("ignorePositions", bundleString(("IgnorePositions")))); + propertiesCheckBoxMap.put(IGNORE_PK, WidgetFactory.createCheckBox("ignorePK", bundleString("IgnorePK"))); + propertiesCheckBoxMap.put(IGNORE_FK, WidgetFactory.createCheckBox("ignoreFK", bundleString("IgnoreFK"))); + propertiesCheckBoxMap.put(IGNORE_UK, WidgetFactory.createCheckBox("ignoreUK", bundleString("IgnoreUK"))); + propertiesCheckBoxMap.put(IGNORE_CK, WidgetFactory.createCheckBox("ignoreCK", bundleString("IgnoreCK"))); if (isExtractMetadata) { propertiesCheckBoxMap.remove(CHECK_CREATE); @@ -231,14 +248,15 @@ private void init() { // --- comboBoxes defining --- - dbTargetComboBox = new JComboBox<>(); - dbMasterComboBox = new JComboBox<>(); + dbTargetComboBox = WidgetFactory.createConnectionComboBox("dbTargetComboBox", false); + dbMasterComboBox = WidgetFactory.createConnectionComboBox("dbMasterComboBox", false); dbMasterComboBox.setVisible(!isExtractMetadata); // --- db components tree view --- rootTreeNode = new ComparerTreeNode(bundleString("DatabaseChanges")); dbComponentsTree = new JTree(new DefaultTreeModel(rootTreeNode)); + dbComponentsTree.setName("dbComponentsTree"); dbComponentsTree.setCellRenderer(new ComparerTreeCellRenderer()); dbComponentsTree.addMouseListener(new MouseAdapter() { @Override @@ -265,6 +283,7 @@ public void mouseClicked(MouseEvent e) { loggingOutputPanel = new LoggingOutputPanel(); loggingOutputPanel.append(bundleString("WelcomeText")); + loggingOutputPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 6, 0)); progressBar = new JProgressBar(); progressBar.setStringPainted(true); @@ -272,55 +291,42 @@ public void mouseClicked(MouseEvent e) { sqlTextPanel = new SimpleSqlTextPanel(); differenceSqlTextPanel = new DifferenceSqlTextPanel(bundleString("SourceLabel"), bundleString("TargetLabel"), !isExtractMetadata); - - // --- - - arrangeComponents(); - getConnections(); } - private void arrangeComponents() { - - GridBagHelper gridBagHelper; + private void arrange() { + GridBagHelper gbh; // --- connections selector panel --- - gridBagHelper = new GridBagHelper(); - gridBagHelper.setInsets(5, 5, 5, 5).anchorNorthWest().fillHorizontally(); - JPanel connectionsSelectorPanel = new JPanel(new GridBagLayout()); - gridBagHelper.addLabelFieldPair(connectionsSelectorPanel, - bundleString("CompareDatabaseLabel"), dbTargetComboBox, null); - if (!isExtractMetadata) - gridBagHelper.addLabelFieldPair(connectionsSelectorPanel, - bundleString("MasterDatabaseLabel"), dbMasterComboBox, null); + gbh = new GridBagHelper().anchorNorthWest().fillHorizontally(); + connectionsSelectorPanel.add(new JLabel(bundleString("CompareDatabaseLabel")), gbh.topGap(3).setMinWeightX().get()); + connectionsSelectorPanel.add(dbTargetComboBox, gbh.nextCol().topGap(0).leftGap(5).setMaxWeightX().get()); + if (!isExtractMetadata) { + connectionsSelectorPanel.add(new JLabel(bundleString("MasterDatabaseLabel")), gbh.nextRowFirstCol().topGap(8).leftGap(0).setMinWeightX().get()); + connectionsSelectorPanel.add(dbMasterComboBox, gbh.nextCol().topGap(5).leftGap(5).setMaxWeightX().get()); + } // --- connections panel --- - gridBagHelper = new GridBagHelper(); - gridBagHelper.setInsets(5, 5, 5, 5).anchorNorthWest().fillHorizontally(); - JPanel connectionsPanel = new JPanel(new GridBagLayout()); connectionsPanel.setBorder(BorderFactory.createTitledBorder(bundleString("ConnectionsLabel"))); - connectionsPanel.add(connectionsSelectorPanel, gridBagHelper.setMaxWeightX().get()); - connectionsPanel.add(switchTargetSourceButton, gridBagHelper.nextCol().setMinWeightX().fillVertical().get()); - connectionsPanel.add(compareButton, gridBagHelper.nextRowFirstCol().setWidth(2).fillHorizontally().get()); + gbh = new GridBagHelper().setInsets(5, 5, 5, 5).anchorNorthWest().fillBoth(); + connectionsPanel.add(connectionsSelectorPanel, gbh.setMaxWeightX().get()); + connectionsPanel.add(switchTargetSourceButton, gbh.nextCol().leftGap(0).setMinWeightX().fillVertical().get()); + connectionsPanel.add(compareButton, gbh.nextRowFirstCol().leftGap(5).topGap(0).fillHorizontally().spanX().get()); // --- attributes panel --- - gridBagHelper = new GridBagHelper(); - gridBagHelper.setLabelDefault().setInsets(5, 5, 5, 5).anchorNorthWest().fillHorizontally(); - JPanel attributesPanel = new JPanel(new GridBagLayout()); - attributesPanel.add(selectAllAttributesButton, gridBagHelper.nextRowFirstCol().setLabelDefault().anchorNorthWest().get()); + gbh = new GridBagHelper().setInsets(5, 5, 5, 0).anchorNorthWest().fillHorizontally(); + attributesPanel.add(selectAllAttributesButton, gbh.get()); for (JCheckBox checkBox : attributesCheckBoxMap.values()) - attributesPanel.add(checkBox, gridBagHelper.nextRowFirstCol().get()); - attributesPanel.add(new JPanel(), gridBagHelper.nextRowFirstCol().setMaxWeightY().spanY().get()); - - attributesPanel.add(new JScrollPane()); + attributesPanel.add(checkBox, gbh.nextRowFirstCol().get()); + attributesPanel.add(new JPanel(), gbh.nextRowFirstCol().bottomGap(5).setMaxWeightY().spanY().get()); JScrollPane attributesPanelWithScrolls = new JScrollPane(attributesPanel, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, @@ -330,15 +336,13 @@ private void arrangeComponents() { // --- properties panel --- - gridBagHelper = new GridBagHelper(); - gridBagHelper.setLabelDefault().setInsets(5, 5, 5, 5).anchorNorthWest().fillHorizontally(); - JPanel propertiesPanel = new JPanel(new GridBagLayout()); - propertiesPanel.add(selectAllPropertiesButton, gridBagHelper.nextRowFirstCol().setLabelDefault().anchorNorthWest().get()); + gbh = new GridBagHelper().setInsets(5, 5, 5, 0).anchorNorthWest().fillHorizontally(); + propertiesPanel.add(selectAllPropertiesButton, gbh.get()); for (JCheckBox checkBox : propertiesCheckBoxMap.values()) - propertiesPanel.add(checkBox, gridBagHelper.nextRowFirstCol().get()); - propertiesPanel.add(new JPanel(), gridBagHelper.nextRowFirstCol().setMaxWeightY().spanY().get()); + propertiesPanel.add(checkBox, gbh.nextRowFirstCol().get()); + propertiesPanel.add(new JPanel(), gbh.nextRowFirstCol().bottomGap(5).setMaxWeightY().spanY().get()); JScrollPane propertiesPanelWithScrolls = new JScrollPane(propertiesPanel, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, @@ -348,21 +352,20 @@ private void arrangeComponents() { // --- SQL panel --- - gridBagHelper = new GridBagHelper(); - gridBagHelper.setLabelDefault().setInsets(5, 5, 5, 5).anchorNorthWest().fillBoth(); - JPanel sqlPanel = new JPanel(new GridBagLayout()); - sqlPanel.add(sqlTextPanel, gridBagHelper.setWidth(3).setMaxWeightY().spanX().get()); - sqlPanel.add(saveScriptButton, gridBagHelper.setLabelDefault().nextRowFirstCol().get()); - sqlPanel.add(executeScriptButton, gridBagHelper.nextCol().get()); - sqlPanel.add(new JPanel(), gridBagHelper.nextCol().get()); + gbh = new GridBagHelper().setInsets(0, 5, 0, 5).anchorNorthWest().fillBoth(); + sqlPanel.add(sqlTextPanel, gbh.setMaxWeightY().spanX().get()); + sqlPanel.add(saveScriptButton, gbh.nextRowFirstCol().setLabelDefault().topGap(0).bottomGap(6).get()); + sqlPanel.add(executeScriptButton, gbh.nextCol().leftGap(5).get()); + sqlPanel.add(new JPanel(), gbh.nextCol().setMaxWeightX().get()); // --- view panel --- JScrollPane dbComponentsTreePanel = new JScrollPane(dbComponentsTree, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); + dbComponentsTreePanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 6, 5)); JSplitPane viewPanel = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT); viewPanel.setResizeWeight(0.25); @@ -372,39 +375,36 @@ private void arrangeComponents() { // --- tabbed pane --- tabPane = new JTabbedPane(); - tabPane.add(bundleString("OutputLabel"), loggingOutputPanel); tabPane.add(bundleString("TreeView"), viewPanel); tabPane.add("SQL", sqlPanel); // --- compare panel --- - gridBagHelper = new GridBagHelper(); - gridBagHelper.setLabelDefault().setInsets(5, 5, 5, 5).anchorNorthWest().fillBoth(); - JPanel comparePanel = new JPanel(new GridBagLayout()); - if (!isErd) { - comparePanel.add(connectionsPanel, gridBagHelper.setWidth(2).get()); + gbh = new GridBagHelper().setInsets(5, 5, 5, 0).anchorNorthWest().fillBoth(); + if (!isErd) { + comparePanel.add(connectionsPanel, gbh.spanX().get()); + comparePanel.add(attributesPanelWithScrolls, gbh.nextRowFirstCol().setMaxWeightY().setWidth(1).spanY().get()); + gbh.nextCol().leftGap(5); - comparePanel.add(attributesPanelWithScrolls, gridBagHelper.nextRowFirstCol().setWidth(1).get()); } else { - comparePanel.add(compareButton, gridBagHelper.setLabelDefault().get()); - gridBagHelper.nextRowFirstCol(); - gridBagHelper.previousCol(); + comparePanel.add(compareButton, gbh.spanX().get()); + gbh.nextRow().setMaxWeightY().spanY(); } - comparePanel.add(propertiesPanelWithScrolls, gridBagHelper.nextCol().spanY().get()); + comparePanel.add(propertiesPanelWithScrolls, gbh.get()); // --- main panel --- - gridBagHelper = new GridBagHelper(); - gridBagHelper.setLabelDefault().setInsets(5, 5, 5, 5).anchorNorthWest().fillBoth(); + gbh = new GridBagHelper(); + gbh.setLabelDefault().setInsets(0, 5, 5, 5).anchorNorthWest().fillBoth(); JPanel mainPanel = new JPanel(new GridBagLayout()); - mainPanel.add(comparePanel, gridBagHelper.setMaxWeightY().get()); - mainPanel.add(tabPane, gridBagHelper.nextCol().spanX().get()); - mainPanel.add(progressBar, gridBagHelper.nextRowFirstCol().setMinWeightY().spanX().get()); + mainPanel.add(comparePanel, gbh.setMaxWeightY().get()); + mainPanel.add(tabPane, gbh.nextCol().bottomGap(1).spanX().get()); + mainPanel.add(progressBar, gbh.nextRowFirstCol().topGap(0).leftGap(5).bottomGap(5).setMinWeightY().spanX().get()); // --- layout configure --- @@ -413,19 +413,6 @@ private void arrangeComponents() { } - private void getConnections() { - - List connections = - ((DatabaseConnectionRepository) Objects.requireNonNull( - RepositoryCache.load(DatabaseConnectionRepository.REPOSITORY_ID))).findAll(); - - for (DatabaseConnection dc : connections) { - databaseConnectionList.add(dc); - dbTargetComboBox.addItem(dc.getName()); - dbMasterComboBox.addItem(dc.getName()); - } - } - private boolean prepareComparer() { if (isErd && isExtractMetadata) { comparer = new Comparer(this, null, new boolean[]{ @@ -439,8 +426,9 @@ private boolean prepareComparer() { !isPropertySelected(IGNORE_FIELDS_POSITIONS)); return true; } - DatabaseConnection masterConnection = databaseConnectionList.get(dbMasterComboBox.getSelectedIndex()); - DatabaseConnection targetConnection = databaseConnectionList.get(dbTargetComboBox.getSelectedIndex()); + + DatabaseConnection masterConnection = dbMasterComboBox.getSelectedConnection(); + DatabaseConnection targetConnection = dbTargetComboBox.getSelectedConnection(); if (busyConnectionList.contains(masterConnection) || busyConnectionList.contains(targetConnection)) { GUIUtilities.displayWarningMessage(isExtractMetadata ? @@ -458,6 +446,7 @@ private boolean prepareComparer() { ConnectionMediator.getInstance().connect(targetConnection, true); } catch (DataSourceException e) { + Log.error(e.getMessage(), e); GUIUtilities.displayWarningMessage(bundleString("UnableCompareNoConnections")); return false; } @@ -498,8 +487,8 @@ private boolean prepareComparer() { try { - DefaultDatabaseHost masterHost = new DefaultDatabaseHost(databaseConnectionList.get(dbMasterComboBox.getSelectedIndex())); - DefaultDatabaseHost slaveHost = new DefaultDatabaseHost(databaseConnectionList.get(dbTargetComboBox.getSelectedIndex())); + DefaultDatabaseHost masterHost = new DefaultDatabaseHost(dbMasterComboBox.getSelectedConnection()); + DefaultDatabaseHost slaveHost = new DefaultDatabaseHost(dbTargetComboBox.getSelectedConnection()); if (!slaveHost.getDatabaseProductName().toLowerCase().contains("reddatabase") || (!isExtractMetadata && !masterHost.getDatabaseProductName().toLowerCase().contains("reddatabase"))) { @@ -511,7 +500,6 @@ private boolean prepareComparer() { if (slaveHost.getDatabaseMajorVersion() < 3 || (!isExtractMetadata && masterHost.getDatabaseMajorVersion() < 3)) { - attributesCheckBoxMap.get(Arrays.asList(NamedObject.META_TYPES_FOR_BUNDLE).indexOf("USER")).setSelected(false); attributesCheckBoxMap.get(Arrays.asList(NamedObject.META_TYPES_FOR_BUNDLE).indexOf("PACKAGE")).setSelected(false); attributesCheckBoxMap.get(Arrays.asList(NamedObject.META_TYPES_FOR_BUNDLE).indexOf("FUNCTION")).setSelected(false); attributesCheckBoxMap.get(Arrays.asList(NamedObject.META_TYPES_FOR_BUNDLE).indexOf("TABLESPACE")).setSelected(false); @@ -527,6 +515,7 @@ private boolean prepareComparer() { } } catch (SQLException | NullPointerException e) { + Log.error(e.getMessage(), e); GUIUtilities.displayWarningMessage(bundleString("UnableCompareNoConnections")); return false; } @@ -568,50 +557,47 @@ private void compare() { } if (isErd && isExtractMetadata) { - ((ComparerTreeNode) rootTreeNode.getChildAt(rootTreeNode.getChildCount() - 1)) - .add(new ComparerTreeNode(ComparerTreeNode.CREATE, NamedObject.TABLE, - Bundles.get(NamedObject.class, NamedObject.META_TYPES_FOR_BUNDLE[NamedObject.TABLE]), ComparerTreeNode.TYPE_FOLDER)); - - loggingOutputPanel.append(MessageFormat.format("\n============= {0} to CREATE =============", - Bundles.getEn(NamedObject.class, NamedObject.META_TYPES_FOR_BUNDLE[NamedObject.TABLE]))); + updateOutputPanels(ComparerTreeNode.CREATE, NamedObject.TABLE); comparer.createErds(erdTables); + if (!isPropertySelected(IGNORE_COMPUTED_FIELDS) && !isCanceled()) { loggingOutputPanel.append("\n============= COMPUTED FIELDS defining ============="); if (!Objects.equals(comparer.getComputedFieldsList(), "") && comparer.getComputedFieldsList() != null) loggingOutputPanel.append(comparer.getComputedFieldsList()); comparer.createComputedFields(); } - } else for (Integer type : scriptGenerationOrder) { - if (isCanceled()) - break; + } else { - if (type == STUBS) { - comparer.createStubs(attributesCheckBoxMap.get(NamedObject.FUNCTION).isSelected(), - attributesCheckBoxMap.get(NamedObject.PROCEDURE).isSelected(), - attributesCheckBoxMap.get(NamedObject.TRIGGER).isSelected(), - attributesCheckBoxMap.get(NamedObject.DDL_TRIGGER).isSelected(), - attributesCheckBoxMap.get(NamedObject.DATABASE_TRIGGER).isSelected()); - - if (!isPropertySelected(IGNORE_COMPUTED_FIELDS) && !isCanceled()) { - loggingOutputPanel.append("\n============= COMPUTED FIELDS defining ============="); - if (!Objects.equals(comparer.getComputedFieldsList(), "") && comparer.getComputedFieldsList() != null) - loggingOutputPanel.append(comparer.getComputedFieldsList()); - comparer.createComputedFields(); + for (Integer type : scriptGenerationOrder) { + + if (isCanceled()) + break; + + if (type == STUBS) { + comparer.setStubsNeed( + true, + attributesCheckBoxMap.get(NamedObject.FUNCTION).isSelected(), + attributesCheckBoxMap.get(NamedObject.PROCEDURE).isSelected(), + attributesCheckBoxMap.get(NamedObject.TRIGGER).isSelected(), + attributesCheckBoxMap.get(NamedObject.DDL_TRIGGER).isSelected(), + attributesCheckBoxMap.get(NamedObject.DATABASE_TRIGGER).isSelected() + ); + + if (!isPropertySelected(IGNORE_COMPUTED_FIELDS) && !isCanceled()) { + loggingOutputPanel.append("\n============= COMPUTED FIELDS defining ============="); + if (!Objects.equals(comparer.getComputedFieldsList(), "") && comparer.getComputedFieldsList() != null) + loggingOutputPanel.append(comparer.getComputedFieldsList()); + comparer.createComputedFields(); + } + + continue; } - continue; - } - - if (attributesCheckBoxMap.get(type).isSelected()) { - - ((ComparerTreeNode) rootTreeNode.getChildAt(rootTreeNode.getChildCount() - 1)) - .add(new ComparerTreeNode(ComparerTreeNode.CREATE, type, - Bundles.get(NamedObject.class, NamedObject.META_TYPES_FOR_BUNDLE[type]), ComparerTreeNode.TYPE_FOLDER)); - - loggingOutputPanel.append(MessageFormat.format("\n============= {0} to CREATE =============", - Bundles.getEn(NamedObject.class, NamedObject.META_TYPES_FOR_BUNDLE[type]))); - comparer.createObjects(type); + if (attributesCheckBoxMap.get(type).isSelected()) { + updateOutputPanels(ComparerTreeNode.CREATE, type); + comparer.createObjects(type); + } } } } @@ -625,6 +611,15 @@ private void compare() { Collections.reverse(scriptGenerationOrder); } + comparer.setStubsNeed( + false, + attributesCheckBoxMap.get(NamedObject.FUNCTION).isSelected(), + attributesCheckBoxMap.get(NamedObject.PROCEDURE).isSelected(), + attributesCheckBoxMap.get(NamedObject.TRIGGER).isSelected(), + attributesCheckBoxMap.get(NamedObject.DDL_TRIGGER).isSelected(), + attributesCheckBoxMap.get(NamedObject.DATABASE_TRIGGER).isSelected() + ); + for (Integer type : scriptGenerationOrder) { if (isCanceled()) @@ -634,16 +629,12 @@ private void compare() { continue; if (attributesCheckBoxMap.get(type).isSelected()) { + updateOutputPanels(ComparerTreeNode.ALTER, type); - ((ComparerTreeNode) rootTreeNode.getChildAt(rootTreeNode.getChildCount() - 1)) - .add(new ComparerTreeNode(ComparerTreeNode.ALTER, type, - Bundles.get(NamedObject.class, NamedObject.META_TYPES_FOR_BUNDLE[type]), ComparerTreeNode.TYPE_FOLDER)); - - loggingOutputPanel.append(MessageFormat.format("\n============= {0} to ALTER =============", - Bundles.getEn(NamedObject.class, NamedObject.META_TYPES_FOR_BUNDLE[type]))); if (isErd) comparer.alterErds(erdTables); - else comparer.alterObjects(type); + else + comparer.alterObjects(type); } } } @@ -666,16 +657,12 @@ private void compare() { continue; if (attributesCheckBoxMap.get(type).isSelected()) { + updateOutputPanels(ComparerTreeNode.DROP, type); - ((ComparerTreeNode) rootTreeNode.getChildAt(rootTreeNode.getChildCount() - 1)) - .add(new ComparerTreeNode(ComparerTreeNode.DROP, type, - Bundles.get(NamedObject.class, NamedObject.META_TYPES_FOR_BUNDLE[type]), ComparerTreeNode.TYPE_FOLDER)); - - loggingOutputPanel.append(MessageFormat.format("\n============= {0} to DROP =============", - Bundles.getEn(NamedObject.class, NamedObject.META_TYPES_FOR_BUNDLE[type]))); if (isErd) comparer.dropErds(erdTables); - else comparer.dropObjects(type); + else + comparer.dropObjects(type); } } } @@ -706,8 +693,7 @@ private void compareDatabase() { if (!isExtractMetadata) { - if (databaseConnectionList.size() < 2 || - dbTargetComboBox.getSelectedIndex() == dbMasterComboBox.getSelectedIndex()) { + if (Objects.equals(dbTargetComboBox.getSelectedConnection(), dbMasterComboBox.getSelectedConnection())) { GUIUtilities.displayWarningMessage(bundleString("UnableCompareSampleConnections")); return; } @@ -842,9 +828,9 @@ private void saveScript() { try (FileOutputStream path = new FileOutputStream(fileSavePath)) { - for (int i = 0; i < comparer.getScript().size(); i++) { - String text = comparer.getScript(i); - byte[] buffer = text.getBytes(); + String[] sqlTextLines = sqlTextPanel.getSQLText().split("\n"); + for (String sqlLine : sqlTextLines) { + byte[] buffer = (sqlLine + "\n").getBytes(); path.write(buffer, 0, buffer.length); } @@ -852,7 +838,7 @@ private void saveScript() { loggingOutputPanel.append(bundleString("SavedTo") + fileSavePath); } catch (IOException e) { - e.printStackTrace(System.out); + Log.error(e.getMessage(), e); } } } @@ -892,7 +878,7 @@ else if (Objects.equals(selectedBox, "properties")) } private void switchTargetSource() { - Object sourceConnection = dbMasterComboBox.getSelectedItem(); + DatabaseConnection sourceConnection = dbMasterComboBox.getSelectedConnection(); dbMasterComboBox.setSelectedItem(dbTargetComboBox.getSelectedItem()); dbTargetComboBox.setSelectedItem(sourceConnection); } @@ -953,6 +939,30 @@ private String getMasterDBDialect() { return dialect; } + private void updateOutputPanels(int treeNodeType, Integer objectType) { + + ComparerTreeNode childNode = (ComparerTreeNode) rootTreeNode.getChildAt(rootTreeNode.getChildCount() - 1); + childNode.add(new ComparerTreeNode( + treeNodeType, + objectType, + Bundles.get(NamedObject.class, NamedObject.META_TYPES_FOR_BUNDLE[objectType]), + ComparerTreeNode.TYPE_FOLDER + )); + + String pattern = Constants.EMPTY; + if (treeNodeType == ComparerTreeNode.CREATE) + pattern = "\n============= {0} to CREATE ============="; + else if (treeNodeType == ComparerTreeNode.ALTER) + pattern = "\n============= {0} to ALTER ============="; + else if (treeNodeType == ComparerTreeNode.DROP) + pattern = "\n============= {0} to DROP ============="; + + loggingOutputPanel.append(MessageFormat.format( + pattern, + Bundles.getEn(NamedObject.class, NamedObject.META_TYPES_FOR_BUNDLE[objectType]) + )); + } + public void recreateProgressBar(String label, String metaTag, int maxValue) { progressBar.setValue(0); progressBar.setMaximum(maxValue); diff --git a/src/org/executequery/gui/browser/ConnectionsTreePanel.java b/src/org/executequery/gui/browser/ConnectionsTreePanel.java index 23cd97297..0c48f07c3 100644 --- a/src/org/executequery/gui/browser/ConnectionsTreePanel.java +++ b/src/org/executequery/gui/browser/ConnectionsTreePanel.java @@ -665,6 +665,15 @@ public void newConnection(String sourceName) { * @param dc the connection the new one is to be based on */ public void newConnection(DatabaseConnection dc) { + newConnection(dc, true); + } + + /** + * Creates a new connection based on the specified connection. + * + * @param dc the connection the new one is to be based on + */ + public void newConnection(DatabaseConnection dc, boolean updatePropertiesPanel) { validateConnectionCopyName(dc); DatabaseHost host = databaseObjectFactory().createDatabaseHost(dc); @@ -687,7 +696,7 @@ public void newConnection(DatabaseConnection dc) { } else { DatabaseHostNode databaseHostNode = new DatabaseHostNode(host, null); tree.addToRoot(databaseHostNode); - valueChanged(databaseHostNode, null); + valueChanged(databaseHostNode, null, updatePropertiesPanel); } connectionAdded(dc); @@ -924,8 +933,12 @@ public synchronized void valueChanged(DatabaseObjectNode node) { controller.valueChanged(node, null); } - public synchronized void valueChanged(DatabaseObjectNode node, DatabaseConnection connection) { - controller.valueChanged(node, connection); + public void valueChanged(DatabaseObjectNode node, DatabaseConnection connection) { + valueChanged(node, connection, true); + } + + public synchronized void valueChanged(DatabaseObjectNode node, DatabaseConnection connection, boolean updatePropertiesPanel) { + controller.valueChanged(node, connection, updatePropertiesPanel); } public void reloadOpenedConnections() { @@ -954,18 +967,11 @@ public void reloadPath(TreePath path, boolean refreshButtons) { GUIUtilities.showWaitCursor(); - boolean expanded = tree.isExpanded(path); - if (expanded) - tree.collapsePath(path); - DatabaseObjectNode node = (DatabaseObjectNode) object; node.reset(); + nodeStructureChanged(node); pathExpanded(path); - - if (expanded) - tree.expandPath(path); - pathChanged(oldSelectionPath, path, refreshButtons); // --- reload panel view --- diff --git a/src/org/executequery/gui/browser/DatabasePropertiesPanel.java b/src/org/executequery/gui/browser/DatabasePropertiesPanel.java index e6132bd5b..47ea79f07 100644 --- a/src/org/executequery/gui/browser/DatabasePropertiesPanel.java +++ b/src/org/executequery/gui/browser/DatabasePropertiesPanel.java @@ -38,8 +38,6 @@ * @author Takis Diakoumis */ public class DatabasePropertiesPanel extends ConnectionPropertiesPanel { - - private PropertyWrapperModel model; private JTable table; public DatabasePropertiesPanel() { @@ -48,10 +46,7 @@ public DatabasePropertiesPanel() { } private void init() { - - model = new PropertyWrapperModel(); - - table = new SortableColumnsTable(model); + table = new SortableColumnsTable(); setTableProperties(table); add(new JScrollPane(table), new GridBagHelper().fillBoth().spanX().spanY().get()); @@ -62,7 +57,7 @@ public void setDatabaseProperties(Map properties) { } public void setDatabaseProperties(Map properties, boolean sort) { - model.setValues(properties, sort); + table.setModel(new PropertyWrapperModel(properties, sort)); } public JTable getTable() { diff --git a/src/org/executequery/gui/browser/DatabaseStatisticPanel.java b/src/org/executequery/gui/browser/DatabaseStatisticPanel.java index 18e39920d..ee660312b 100644 --- a/src/org/executequery/gui/browser/DatabaseStatisticPanel.java +++ b/src/org/executequery/gui/browser/DatabaseStatisticPanel.java @@ -21,6 +21,7 @@ import org.executequery.util.UserProperties; import org.underworldlabs.statParser.*; import org.underworldlabs.swing.*; +import org.underworldlabs.swing.layouts.GridBagHelper; import org.underworldlabs.swing.util.SwingWorker; import org.underworldlabs.util.DynamicLibraryLoader; import org.underworldlabs.util.MiscUtils; @@ -38,6 +39,7 @@ import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; +import java.util.Vector; public class DatabaseStatisticPanel extends AbstractServiceManagerPanel implements TabView { @@ -98,72 +100,7 @@ public void actionPerformed(ActionEvent e) { loadFromFile(fileChooser, fileStatButton); } }); - compareButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - BaseDialog dialog = new BaseDialog(bundleString("selectStatsDialogTitle"), true); - JComboBox comboBox1 = WidgetFactory.createComboBox("combobox1"); - DynamicComboBoxModel model1 = new DynamicComboBoxModel(); - model1.setElements(statDatabaseList); - comboBox1.setModel(model1); - JComboBox comboBox2 = WidgetFactory.createComboBox("combobox2"); - DynamicComboBoxModel model2 = new DynamicComboBoxModel(); - model2.setElements(statDatabaseList); - comboBox2.setModel(model2); - ActionListener actionListener = new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - GUIUtilities.closeSelectedDialog(); - SwingWorker sw = new SwingWorker("compareStatistics") { - @Override - public Object construct() { - StatDatabase compareDB = new StatDatabase(); - StatDatabase db1 = (StatDatabase) comboBox1.getSelectedItem(); - StatDatabase db2 = (StatDatabase) comboBox2.getSelectedItem(); - compareDB = compareDBS(db1, db2); - CompareStatPanel compareStatPanel = new CompareStatPanel(compareDB, db1, db2); - tabPane.addTab(null, null, compareStatPanel, db1 + " vs " + db2); - tabPane.setTabComponentAt(tabPane.indexOfComponent(compareStatPanel), new ClosableTabTitle(bundleString("compare"), null, compareStatPanel)); - tabPane.setSelectedComponent(compareStatPanel); - return null; - } - - @Override - public void finished() { - GUIUtilities.showNormalCursor(); - } - }; - sw.start(); - GUIUtilities.showWaitCursor(); - } - }; - BottomButtonPanel bottomButtonPanel = new BottomButtonPanel(actionListener, "OK", null, true); - bottomButtonPanel.setHelpButtonVisible(false); - AbstractPanel panel = new AbstractPanel() { - @Override - protected void initComponents() { - - } - - @Override - protected void arrangeComponents() { - add(comboBox1, gbh.setInsets(10,10,10,0).fillHorizontally().spanX().get()); - add(comboBox2, gbh.nextRowFirstCol().topGap(5).fillHorizontally().spanX().get()); - add(bottomButtonPanel, gbh.nextRowFirstCol().bottomGap(10).rightGap(5).spanX().get()); - } - - @Override - protected void postInitActions() { - - } - }; - dialog.setContentPane(panel); - dialog.setPreferredSize(new Dimension(300, 120)); - dialog.setResizable(false); - dialog.display(); - - } - }); + compareButton.addActionListener(e -> showCompareDialog()); progressBar = new IndeterminateProgressBar(true); toolBar.add(progressBar); getStatButton = WidgetFactory.createButton("getStatButton", bundleString("Start")); @@ -275,54 +212,74 @@ public Object construct() { } } }); - itemListener = new ItemListener() { - @Override - public void itemStateChanged(ItemEvent e) { + + itemListener = e -> { + + if (e.getSource() == onlySelectTablesBox) { if (e.getStateChange() == ItemEvent.SELECTED) { - if (e.getSource() == defaultStatCheckBox) { - tableStatBox.setSelected(false); - indexStatBox.setSelected(false); - recordVersionsStatBox.setSelected(false); - systemTableStatBox.setSelected(false); - headerPageStatBox.setSelected(false); - onlySelectTablesBox.setSelected(false); - tablesField.setEnabled(false); - } else if (e.getSource() == headerPageStatBox) { - tableStatBox.setSelected(false); - indexStatBox.setSelected(false); - recordVersionsStatBox.setSelected(false); - systemTableStatBox.setSelected(false); - defaultStatCheckBox.setSelected(false); - onlySelectTablesBox.setSelected(false); - tablesField.setEnabled(false); - } else if (e.getSource() == tableStatBox || e.getSource() == indexStatBox || e.getSource() == recordVersionsStatBox || e.getSource() == systemTableStatBox) { - headerPageStatBox.setSelected(false); - onlySelectTablesBox.setSelected(false); - defaultStatCheckBox.setSelected(false); - tablesField.setEnabled(false); - } else if (e.getSource() == onlySelectTablesBox) { - tableStatBox.setSelected(false); - indexStatBox.setSelected(false); - recordVersionsStatBox.setSelected(false); - systemTableStatBox.setSelected(false); - defaultStatCheckBox.setSelected(false); - headerPageStatBox.setSelected(false); - tablesField.setEnabled(true); - SwingWorker sw = new SwingWorker("displayDialog") { - @Override - public Object construct() { - BaseDialog dialog = new BaseDialog(bundleString("selectTableDialogTitle"), true); - dialog.addDisplayComponent(new DialogPanel()); - dialog.setResizable(false); - dialog.display(); - return null; - } - }; - sw.start(); - } + + tableStatBox.setSelected(false); + indexStatBox.setSelected(false); + recordVersionsStatBox.setSelected(false); + systemTableStatBox.setSelected(false); + defaultStatCheckBox.setSelected(false); + headerPageStatBox.setSelected(false); + tablesField.setEnabled(true); + + SwingWorker sw = new SwingWorker("displayDialog") { + @Override + public Object construct() { + BaseDialog dialog = new BaseDialog(bundleString("selectTableDialogTitle"), true); + dialog.addDisplayComponent(new DialogPanel()); + dialog.setResizable(false); + dialog.display(); + return null; + } + }; + sw.start(); + + } else { + tablesStatPanel.removeAllAction(); + tablesField.setEnabled(false); + tablesField.setText(null); } + + return; + } + + if (e.getStateChange() != ItemEvent.SELECTED) + return; + + if (e.getSource() == defaultStatCheckBox) { + tableStatBox.setSelected(false); + indexStatBox.setSelected(false); + recordVersionsStatBox.setSelected(false); + systemTableStatBox.setSelected(false); + headerPageStatBox.setSelected(false); + onlySelectTablesBox.setSelected(false); + tablesField.setEnabled(false); + + } else if (e.getSource() == headerPageStatBox) { + tableStatBox.setSelected(false); + indexStatBox.setSelected(false); + recordVersionsStatBox.setSelected(false); + systemTableStatBox.setSelected(false); + defaultStatCheckBox.setSelected(false); + onlySelectTablesBox.setSelected(false); + tablesField.setEnabled(false); + + } else if (e.getSource() == tableStatBox + || e.getSource() == indexStatBox + || e.getSource() == recordVersionsStatBox + || e.getSource() == systemTableStatBox) { + + headerPageStatBox.setSelected(false); + onlySelectTablesBox.setSelected(false); + defaultStatCheckBox.setSelected(false); + tablesField.setEnabled(false); } }; + defaultStatCheckBox = WidgetFactory.createCheckBox("defaultStatCheckBox", bundleString("default")); defaultStatCheckBox.setSelected(true); defaultStatCheckBox.addItemListener(itemListener); @@ -362,6 +319,72 @@ public void actionPerformed(ActionEvent e) { } + private void showCompareDialog() { + + BaseDialog dialog = new BaseDialog(bundleString("selectStatsDialogTitle"), true); + AbstractPanel panel = new AbstractPanel() { + private JButton okButton; + private JButton cancelButton; + private JComboBox comboBox1; + private JComboBox comboBox2; + + @Override + protected void initComponents() { + comboBox1 = WidgetFactory.createComboBox("comboBox1", new Vector<>(statDatabaseList)); + comboBox2 = WidgetFactory.createComboBox("comboBox2", new Vector<>(statDatabaseList)); + okButton = WidgetFactory.createButton("okButton", Bundles.get("common.ok.button"), e -> doCompare()); + cancelButton = WidgetFactory.createButton("cancelButton", Bundles.get("common.cancel.button"), e -> dialog.dispose()); + } + + @Override + protected void arrangeComponents() { + gbh = new GridBagHelper().setInsets(5, 5, 5, 5).anchorCenter().fillHorizontally(); + add(comboBox1, gbh.spanX().get()); + add(comboBox2, gbh.nextRow().topGap(0).get()); + add(okButton, gbh.nextRow().setWidth(1).topGap(5).get()); + add(cancelButton, gbh.nextCol().leftGap(0).get()); + } + + @Override + protected void postInitActions() { + } + + private void doCompare() { + StatDatabase db1 = (StatDatabase) comboBox1.getSelectedItem(); + StatDatabase db2 = (StatDatabase) comboBox2.getSelectedItem(); + compareStatistics(db1, db2); + } + + }; + + dialog.setContentPane(panel); + dialog.setPreferredSize(new Dimension(300, dialog.getPreferredSize().height)); + dialog.setResizable(false); + dialog.display(); + } + + private void compareStatistics(StatDatabase db1, StatDatabase db2) { + GUIUtilities.closeSelectedDialog(); + SwingWorker sw = new SwingWorker("compareStatistics") { + @Override + public Object construct() { + StatDatabase compareDB = new StatDatabase(); + CompareStatPanel compareStatPanel = new CompareStatPanel(compareDB, db1, db2); + tabPane.addTab(null, null, compareStatPanel, db1 + " vs " + db2); + tabPane.setTabComponentAt(tabPane.indexOfComponent(compareStatPanel), new ClosableTabTitle(bundleString("compare"), null, compareStatPanel)); + tabPane.setSelectedComponent(compareStatPanel); + return null; + } + + @Override + public void finished() { + GUIUtilities.showNormalCursor(); + } + }; + sw.start(); + GUIUtilities.showWaitCursor(); + } + protected void loadFromFile(FileChooserDialog fileChooser, JButton fileStatButton) { int returnVal = fileChooser.showOpenDialog(fileStatButton); if (returnVal == JFileChooser.APPROVE_OPTION) { diff --git a/src/org/executequery/gui/browser/GeneratorTestDataPanel.java b/src/org/executequery/gui/browser/GeneratorTestDataPanel.java index 2b713a1de..e7006228d 100644 --- a/src/org/executequery/gui/browser/GeneratorTestDataPanel.java +++ b/src/org/executequery/gui/browser/GeneratorTestDataPanel.java @@ -3,6 +3,7 @@ import biz.redsoft.IFBBatch; import biz.redsoft.IFBBatchCompletionState; import biz.redsoft.IFBDatabaseConnection; +import org.executequery.Constants; import org.executequery.GUIUtilities; import org.executequery.base.TabView; import org.executequery.databasemediators.DatabaseConnection; @@ -14,487 +15,614 @@ import org.executequery.datasource.ConnectionManager; import org.executequery.datasource.DefaultDriverLoader; import org.executequery.gui.LoggingOutputPanel; +import org.executequery.gui.WidgetFactory; import org.executequery.gui.browser.generatortestdata.FieldGenerator; import org.executequery.gui.browser.generatortestdata.FieldsPanel; -import org.executequery.gui.components.OpenConnectionsComboboxPanel; import org.executequery.localization.Bundles; +import org.executequery.log.Log; import org.executequery.sql.SqlStatementResult; -import org.underworldlabs.jdbc.DataSourceException; +import org.underworldlabs.swing.ConnectionsComboBox; import org.underworldlabs.swing.DynamicComboBoxModel; import org.underworldlabs.swing.NumberTextField; import org.underworldlabs.swing.layouts.GridBagHelper; import org.underworldlabs.swing.util.SwingWorker; import org.underworldlabs.util.DynamicLibraryLoader; +import org.underworldlabs.util.MiscUtils; import javax.swing.*; import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; import java.awt.event.ItemEvent; -import java.awt.event.ItemListener; import java.sql.*; -import java.util.ArrayList; +import java.util.*; import java.util.List; -import java.util.Vector; -public class GeneratorTestDataPanel extends JPanel implements TabView { +public class GeneratorTestDataPanel extends JPanel + implements TabView { - public final static String TITLE = bundles("TITLE"); public static final String FRAME_ICON = "icon_generator"; + public static final String TITLE = bundleString("TITLE"); - private OpenConnectionsComboboxPanel comboboxPanel; + // --- GUI components --- - private JComboBox tableBox; + private JComboBox tablesCombo; + private ConnectionsComboBox connectionsCombo; - private DynamicComboBoxModel tableBoxModel; + private JButton stopButton; + private JButton startButton; - private DefaultStatementExecutor executor; + private NumberTextField batchSizeField; + private NumberTextField commitAfterField; + private NumberTextField recordsCountField; + private JCheckBox useBatchesCheck; + private JCheckBox stopOnErrorCheck; + private JCheckBox loggingEnabledCheck; + + private JLabel batchLabel; + private JTabbedPane tabbedPane; private FieldsPanel fieldsPanel; + private JProgressBar progressBar; + private LoggingOutputPanel logPanel; - private JButton startButton; + // --- - private JButton stopButton; + private boolean stop; + private DynamicComboBoxModel tablesModel; + private DefaultStatementExecutor executor; - private boolean stop = false; + public GeneratorTestDataPanel() { + init(); + arrange(); + checkBatchToolsEnable(); + updateBatchToolsEnable(); + loadTableColumns(); + } - private NumberTextField countRecordsField; + private void init() { - private NumberTextField batchCountField; + fieldsPanel = new FieldsPanel(); + progressBar = new JProgressBar(); + logPanel = new LoggingOutputPanel(); + batchLabel = new JLabel(bundleString("BatchCount")); - private LoggingOutputPanel logPanel; + tabbedPane = new JTabbedPane(); + tabbedPane.add(bundleString("Generator"), fieldsPanel); + tabbedPane.add(bundleString("Output"), logPanel); - private JProgressBar progressBar; + connectionsCombo = WidgetFactory.createConnectionComboBox("connectionsCombo", true); + connectionsCombo.setMinimumSize(new Dimension(400, WidgetFactory.defaultHeight())); + connectionsCombo.addItemListener(this::connectionsComboTriggered); - private JCheckBox logBox; + executor = new DefaultStatementExecutor(); + executor.setDatabaseConnection(getSelectedConnection()); + executor.setCommitMode(false); + executor.setKeepAlive(true); - private JLabel batchLabel; + stopButton = WidgetFactory.createButton("stopButton", bundleString("Stop")); + stopButton.addActionListener(e -> stop = true); + stopButton.setEnabled(false); - private JLabel batchNotAvailable; + startButton = WidgetFactory.createButton("startButton", bundleString("Start")); + startButton.addActionListener(e -> start()); - private JCheckBox useBatchesBox; + recordsCountField = WidgetFactory.createNumberTextField("recordsCountField"); + recordsCountField.setEnableNegativeNumbers(false); + recordsCountField.setText("100"); - private JCheckBox printBatchStateBox; + batchSizeField = WidgetFactory.createNumberTextField("batchSizeField"); + batchSizeField.setEnableNegativeNumbers(false); + batchSizeField.setText("100"); - private JCheckBox stopOnErrorBox; + commitAfterField = WidgetFactory.createNumberTextField("commitAfterField"); + commitAfterField.setEnableNegativeNumbers(false); + commitAfterField.setText("500"); + stopOnErrorCheck = WidgetFactory.createCheckBox("stopOnErrorCheck", bundleString("StopOnError")); - public GeneratorTestDataPanel() { - init(); - } + useBatchesCheck = WidgetFactory.createCheckBox("useBatchesCheck", bundleString("useBatchesBox")); + useBatchesCheck.addActionListener(e -> updateBatchToolsEnable()); - public static String bundles(String key) { - return Bundles.get(GeneratorTestDataPanel.class, key); - } + loggingEnabledCheck = WidgetFactory.createCheckBox("loggingEnabledCheck", bundleString("OutputLog")); + loggingEnabledCheck.setSelected(true); - @Override - public boolean tabViewClosing() { - return true; + tablesModel = new DynamicComboBoxModel(); + tablesModel.setElements(getDatabaseTables()); + tablesCombo = WidgetFactory.createComboBox("tablesCombo", tablesModel); + tablesCombo.addItemListener(this::tablesComboTriggered); } - @Override - public boolean tabViewSelected() { - return true; - } + private void arrange() { + GridBagHelper gbh; - @Override - public boolean tabViewDeselected() { - return true; - } + // --- check panel --- + + JPanel checkBoxesPanel = new JPanel(new GridBagLayout()); + + gbh = new GridBagHelper(); + checkBoxesPanel.add(loggingEnabledCheck, gbh.get()); + checkBoxesPanel.add(stopOnErrorCheck, gbh.nextCol().leftGap(5).get()); + checkBoxesPanel.add(useBatchesCheck, gbh.nextCol().get()); + checkBoxesPanel.add(new JPanel(), gbh.nextCol().spanX().get()); + + // --- buttons panel --- + + JPanel buttonsPanel = new JPanel(new GridBagLayout()); + + gbh = new GridBagHelper().fillHorizontally(); + buttonsPanel.add(checkBoxesPanel, gbh.leftGap(1).setMaxWeightX().get()); + buttonsPanel.add(startButton, gbh.nextCol().setMinWeightX().fillNone().get()); + buttonsPanel.add(stopButton, gbh.nextCol().leftGap(5).get()); + + // --- preferences panel --- + + JPanel preferencesPanel = new JPanel(new GridBagLayout()); + + gbh = new GridBagHelper().anchorNorthWest().leftGap(5).fillHorizontally(); + preferencesPanel.add(new JLabel(Bundles.get("common.connection")), gbh.setMinWeightX().topGap(3).get()); + preferencesPanel.add(connectionsCombo, gbh.nextCol().setMaxWeightX().topGap(0).spanX().get()); + preferencesPanel.add(new JLabel(bundleString("Table")), gbh.setMinWeightX().setWidth(1).nextRowFirstCol().topGap(8).get()); + preferencesPanel.add(tablesCombo, gbh.nextCol().setMaxWeightX().topGap(5).spanX().get()); + preferencesPanel.add(new JLabel(bundleString("CountRecords")), gbh.setMinWeightX().setWidth(1).nextRowFirstCol().topGap(8).get()); + preferencesPanel.add(recordsCountField, gbh.nextCol().setMaxWeightX().topGap(5).spanX().get()); + preferencesPanel.add(new JLabel(bundleString("AfterCommit")), gbh.setMinWeightX().setWidth(1).nextRowFirstCol().topGap(8).get()); + preferencesPanel.add(commitAfterField, gbh.nextCol().setMaxWeightX().topGap(5).spanX().get()); + preferencesPanel.add(batchLabel, gbh.setMinWeightX().setWidth(1).nextRowFirstCol().topGap(8).get()); + preferencesPanel.add(batchSizeField, gbh.nextCol().setMaxWeightX().topGap(5).spanX().get()); + + // --- main panel --- + + JPanel mainPanel = new JPanel(new GridBagLayout()); - public DatabaseConnection getSelectedConnection() { - return comboboxPanel.getSelectedConnection(); + gbh = new GridBagHelper().anchorNorthWest().fillHorizontally(); + mainPanel.add(preferencesPanel, gbh.spanX().get()); + mainPanel.add(buttonsPanel, gbh.nextRow().topGap(5).get()); + mainPanel.add(tabbedPane, gbh.nextRow().setMaxWeightY().fillBoth().get()); + mainPanel.add(progressBar, gbh.nextRow().setMinWeightY().fillHorizontally().get()); + + // --- base --- + + setLayout(new GridBagLayout()); + gbh = new GridBagHelper().fillBoth().setInsets(5, 5, 5, 5).spanY().spanX(); + add(mainPanel, gbh.get()); } - private NumberTextField commitAfterField; + private void start() { + new SwingWorker("TestDataGenerator") { - private Vector fillTables() { - Vector tables = new Vector<>(); - SqlStatementResult result = null; - try { - String query = "select rdb$relation_name\n" + - "from rdb$relations\n" + - "where rdb$view_blr is null \n" + - "and (rdb$system_flag is null or rdb$system_flag = 0) and rdb$relation_type=0 or rdb$relation_type=2\n" + - "order by rdb$relation_name"; - result = executor.getResultSet(query); - ResultSet rs = result.getResultSet(); - while (rs.next()) { - tables.add(rs.getString(1).trim()); + @Override + public Object construct() { + runGeneration(); + return Constants.WORKER_SUCCESS; } - if (tables.size() == 0) { - tables.add(""); - GUIUtilities.displayErrorMessage("there is no table in the database"); + + @Override + public void finished() { + stopButton.setEnabled(false); + startButton.setEnabled(true); + progressBar.setValue(0); } - } catch (SQLException e) { - e.printStackTrace(); - } catch (NullPointerException e) { - e.printStackTrace(); - } finally { - executor.releaseResources(); - } - return tables; + + }.start(); } - private void fillCols() { - if (tableBox.getSelectedItem() != "") { - NamedObject object = ((ConnectionsTreePanel) GUIUtilities.getDockedTabComponent(ConnectionsTreePanel.PROPERTY_KEY)).getHostNode(getSelectedConnection()).getDatabaseObject(); - DatabaseHost host = (DatabaseHost) object; - List cols = host.getColumns( (String) tableBox.getSelectedItem()); - List fieldGenerators = new ArrayList<>(); - for (int i = 0; i < cols.size(); i++) { - fieldGenerators.add(new FieldGenerator(cols.get(i), executor)); + private void runGeneration() { + + int recordsCount = recordsCountField.getValue(); + if (recordsCount <= 0) { + GUIUtilities.displayErrorMessage(bundleString("nothingToGenerate")); + return; + } + + List selectedFields = new ArrayList<>(); + for (FieldGenerator fieldGenerator : fieldsPanel.getFieldGenerators()) { + if (fieldGenerator.isSelectedField()) { + selectedFields.add(fieldGenerator); + fieldGenerator.setFirst(); } - if (fieldsPanel == null) { - fieldsPanel = new FieldsPanel(fieldGenerators); - } else fieldsPanel.setFieldGenerators(fieldGenerators); + } + + if (selectedFields.isEmpty()) { + GUIUtilities.displayErrorMessage(bundleString("noColumnsSelected")); + return; + } + + stopButton.setEnabled(true); + startButton.setEnabled(false); + tabbedPane.setSelectedIndex(1); + + stop = false; + progressBar.setMinimum(0); + progressBar.setMaximum(recordsCount); + + long startTime = System.currentTimeMillis(); + try { + if (useBatchesCheck.isSelected()) + generateUsingBatches(recordsCount, selectedFields); + else + generate(recordsCount, selectedFields); + + } catch (Exception e) { + Log.error(e.getMessage(), e); + GUIUtilities.displayExceptionErrorDialog(e.getMessage(), e, this.getClass()); + + } finally { + logPanel.append("Execution time: " + (System.currentTimeMillis() - startTime) + " ms"); } } - private void init() { - executor = new DefaultStatementExecutor(); - progressBar = new JProgressBar(); - logPanel = new LoggingOutputPanel(); - comboboxPanel = new OpenConnectionsComboboxPanel(); - comboboxPanel.connectionsCombo.addItemListener(new ItemListener() { - @Override - public void itemStateChanged(ItemEvent e) { - if (e.getStateChange() == ItemEvent.SELECTED) { - executor.setDatabaseConnection(getSelectedConnection()); - tableBoxModel.setElements(fillTables()); + private void generate(int recordsCount, List selectedFields) throws SQLException { + + int commitAfter = commitAfterField.getValue(); + boolean isStopOnError = stopOnErrorCheck.isSelected(); + boolean loggingEnabled = loggingEnabledCheck.isSelected(); + + int countError = 0; + int countSuccess = 0; + int lastErrorIndex = -1; + String lastErrorMessage = null; + boolean isGenerationError = false; + + PreparedStatement statement = executor.getPreparedStatement(getInsertQuery(selectedFields)); + for (int recordIndex = 0; recordIndex < recordsCount && !stop; recordIndex++) { + progressBar.setValue(recordIndex); + + if (recordIndex % commitAfter == 0 && recordIndex != 0) + executor.getConnection().commit(); + + // > try to set generate and set values + + try { + for (int fieldIndex = 0; fieldIndex < selectedFields.size(); fieldIndex++) { + Object parameter = selectedFields.get(fieldIndex).getMethodGeneratorPanel().getTestDataObject(); + statement.setObject(fieldIndex + 1, parameter); } - } - }); - executor.setDatabaseConnection(getSelectedConnection()); - tableBoxModel = new DynamicComboBoxModel(); - tableBox = new JComboBox(tableBoxModel); - tableBox.addItemListener(new ItemListener() { - @Override - public void itemStateChanged(ItemEvent e) { - if (e.getStateChange() == ItemEvent.SELECTED) { - fillCols(); + + if (loggingEnabled && isGenerationError && lastErrorIndex > -1) { + if (recordIndex - lastErrorIndex + 1 > 1) + logPanel.appendError("Failed on [" + lastErrorIndex + ", " + (recordIndex - 1) + "] records"); + else + logPanel.appendError("Failed on " + lastErrorIndex + " record"); + + lastErrorIndex = -1; + } + + isGenerationError = false; + + } catch (SQLException e) { + + if (loggingEnabled && lastErrorIndex == -1) { + String errorMessage = e.getMessage(); + if (!Objects.equals(errorMessage, lastErrorMessage)) { + lastErrorIndex = recordIndex; + lastErrorMessage = errorMessage; + logPanel.appendError(errorMessage); + } } + + isGenerationError = true; + continue; // if there is an exception with generating data then go to the next iteration } - }); - stopButton = new JButton(bundles("Stop")); - stopButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - stop = true; + + // > try to insert generated values + + SqlStatementResult result = executor.execute(QueryTypes.INSERT, statement); + if (result.isException()) { + countError++; + + if (loggingEnabled && lastErrorIndex == -1) { + String errorMessage = result.getSqlException().getMessage(); + if (!Objects.equals(errorMessage, lastErrorMessage)) { + lastErrorIndex = recordIndex; + lastErrorMessage = errorMessage; + logPanel.appendError(errorMessage); + } + } + + if (isStopOnError) { + GUIUtilities.displayExceptionErrorDialog( + result.getSqlException().getMessage(), + result.getSqlException(), + this.getClass() + ); + break; + } + + } else { + countSuccess++; + if (loggingEnabled && lastErrorIndex > -1) { + if (recordIndex - lastErrorIndex + 1 > 1) + logPanel.appendError("Failed on [" + lastErrorIndex + ", " + (recordIndex - 1) + "] records"); + else + logPanel.appendError("Failed on " + lastErrorIndex + " record"); + + lastErrorIndex = -1; + } } - }); - stopButton.setEnabled(false); + } - startButton = new JButton(bundles("Start")); - startButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - SwingWorker worker = new SwingWorker("TestDataGenerator") { - @Override - public Object construct() { - stop = false; - int count = countRecordsField.getValue(); - if (count <= 0) - GUIUtilities.displayErrorMessage("the number of records to be added must be greater than zero"); - else { - boolean outlog = logBox.isSelected(); - startButton.setEnabled(false); - stopButton.setEnabled(true); - long startTime = System.currentTimeMillis(); - progressBar.setMinimum(0); - progressBar.setMaximum(count); - int commitAfter = commitAfterField.getValue(); - int countSuccess = 0; - int countError = 0; - List fieldGenerators = fieldsPanel.getFieldGenerators(); - List selectedFields = new ArrayList<>(); - String sql = "INSERT INTO \"" + tableBox.getSelectedItem() + "\" ("; - String values = ""; - boolean first = true; - for (int g = 0; g < fieldGenerators.size(); g++) { - if (fieldGenerators.get(g).isSelectedField()) { - selectedFields.add(fieldGenerators.get(g)); - if (!first) { - sql += ","; - values += ","; - } else first = false; - sql += " \"" + fieldGenerators.get(g).getColumn().getName() + "\"\n"; - values += "? "; - fieldGenerators.get(g).setFirst(); + if (loggingEnabled && lastErrorIndex > -1) { + if (recordsCount - lastErrorIndex + 1 > 1) + logPanel.appendError("Failed on [" + lastErrorIndex + ", " + recordsCount + "] records"); + else + logPanel.appendError("Failed on " + lastErrorIndex + " record"); + } + + executor.getConnection().commit(); + executor.releaseResources(); + + logPanel.appendAction("Added: " + countSuccess + "\nFailed: " + countError); + GUIUtilities.displayInformationMessage(bundleString("generationEndMessage", countSuccess, recordsCount, countError)); + } + + private void generateUsingBatches(int recordsCount, List selectedFields) throws SQLException { + + long countError = 0; + long countSuccess = 0; + + int batchSize = batchSizeField.getValue(); + int commitAfter = commitAfterField.getValue(); + boolean isStopOnError = stopOnErrorCheck.isSelected(); + boolean loggingEnabled = loggingEnabledCheck.isSelected(); + + Connection realConnection = ConnectionManager.getTemporaryConnection(getSelectedConnection()); + Connection fbConnection = realConnection.unwrap(Connection.class); + if (!fbConnection.getClass().getName().contains("FBConnection")) { + GUIUtilities.displayWarningMessage(bundleString("batchesNotSupported")); + return; + } + + IFBBatch batch; + try { + IFBDatabaseConnection db = (IFBDatabaseConnection) DynamicLibraryLoader.loadingObjectFromClassLoader( + getSelectedConnection().getDriverMajorVersion(), + fbConnection, + "FBDatabaseConnectionImpl4" + ); + db.setConnection(fbConnection); + batch = db.createBatch(getInsertQuery(selectedFields)); + + } catch (ClassNotFoundException e) { + Log.error(e.getMessage(), e); + GUIUtilities.displayExceptionErrorDialog(e.getMessage(), e, getClass()); + return; + } + + int recordIndex = 0; + while (recordIndex < recordsCount && !stop) { + try { + + if (recordIndex + batchSize > recordsCount) + batchSize = recordIndex + batchSize - recordsCount; + + for (int batchRecordIndex = 0; batchRecordIndex < batchSize; batchRecordIndex++) { + for (int columnIndex = 0; columnIndex < selectedFields.size(); columnIndex++) { + + String parameterType = selectedFields.get(columnIndex).getColumn().getTypeName(); + Object parameterValue = selectedFields.get(columnIndex).getMethodGeneratorPanel().getTestDataObject(); + + if (parameterType.contains("BLOB")) { + if (((byte[]) parameterValue).length == 0) + parameterValue = new byte[1]; + batch.addBlob(columnIndex + 1, (byte[]) parameterValue); + + } else + batch.setObject(columnIndex + 1, parameterValue); + } + + batch.addBatch(); + } + + IFBBatchCompletionState execute = batch.execute(); + int[] states = execute.getAllStates(); + long batchError = Arrays.stream(states).filter(i -> i < 0).count(); + long batchSuccess = states.length - batchError; + + countError += batchError; + countSuccess += batchSuccess; + + String errorMessage = null; + if (countError > 0 && isStopOnError) { + for (int i = 0; i < states.length; i++) { + if (states[i] < 0) { - } - } - sql += ") VALUES (" + values + ");"; - logPanel.append("execute:\n"); - logPanel.append(sql); try { - if (selectedFields.size() < 1) - throw new DataSourceException("no columns selected for generation"); - executor.setCommitMode(false); - executor.setKeepAlive(true); - if (useBatchesBox.isSelected()) { - - int batchCount = batchCountField.getValue(); - - Connection realConnection = ConnectionManager.getTemporaryConnection(getSelectedConnection()); - if (realConnection.unwrap(Connection.class).getClass().getName().contains("FBConnection")) { // Red Database or FB - Connection fbConn = realConnection.unwrap(Connection.class); - IFBDatabaseConnection db = null; - try { - db = (IFBDatabaseConnection) DynamicLibraryLoader.loadingObjectFromClassLoader(getSelectedConnection().getDriverMajorVersion(), fbConn, "FBDatabaseConnectionImpl4"); - } catch (ClassNotFoundException e) { - e.printStackTrace(); - } - db.setConnection(fbConn); - IFBBatch batch = db.createBatch(sql); - - boolean lastError = false; - String lastMessage = ""; - int i = 0; - while (i < count) { - - if (i + batchCount > count) - batchCount = i + batchCount - count; - - for (int bc = 0; bc < batchCount; bc++) { - for (int g = 0; g < selectedFields.size(); g++) { - Object param = selectedFields.get(g).getMethodGeneratorPanel().getTestDataObject(); - String typeName = selectedFields.get(g).getColumn().getTypeName(); - if (typeName.contains("BLOB")) { - if (((byte[]) param).length == 0) - param = new byte[1]; - batch.addBlob(g + 1, (byte[]) param); - } else { - batch.setObject(g + 1, param); - } - } - batch.addBatch(); - } - - IFBBatchCompletionState execute = batch.execute(); - if (printBatchStateBox.isSelected()) - logPanel.append(execute.printAllStates()); - - if (stop) - break; - if (i % commitAfter == 0 && i != 0) { - batch.commit(); - batch.startTransaction(); - } - i += batchCount; - progressBar.setValue(i); - } - - batch.commit(); - logPanel.append("Execution time: " + (System.currentTimeMillis() - startTime) + " ms"); - GUIUtilities.displayInformationMessage("Batch execution completed. See log panel to details."); - } - } else { - PreparedStatement statement = executor.getPreparedStatement(sql); - boolean lastError = false; - String lastMessage = ""; - int i = 0; - for (; i < count; i++) { - if (stop) - break; - if (i % commitAfter == 0 && i != 0) { - executor.getConnection().commit(); - } - progressBar.setValue(i); - try { - for (int g = 0; g < selectedFields.size(); g++) { - Object param = selectedFields.get(g).getMethodGeneratorPanel().getTestDataObject(); - statement.setObject(g + 1, param); - } - } catch (SQLException e) { - String message = sql; - if (outlog) { - String errorMessage = e.getMessage(); - if (!lastError) { - if (!errorMessage.contentEquals(lastMessage)) { - message += errorMessage; - lastMessage = message; - logPanel.appendError(message); - } - logPanel.appendError("failed from " + i); - lastError = true; - } - } - } - SqlStatementResult result = executor.execute(QueryTypes.INSERT, statement); - String message = sql;// + params; - if (result.isException()) { - if (outlog) { - String errorMessage = result.getSqlException().getMessage(); - if (!lastError) { - if (!errorMessage.contentEquals(lastMessage)) { - message += errorMessage; - lastMessage = message; - logPanel.appendError(message); - } - logPanel.appendError("failed from " + i); - lastError = true; - } - } - countError++; - if (stopOnErrorBox.isSelected()) { - GUIUtilities.displayExceptionErrorDialog(result.getSqlException().getMessage(), result.getSqlException(), this.getClass()); - break; - } - } else { - countSuccess++; - if (outlog && lastError) { - logPanel.appendError("to " + (i - 1)); - lastError = false; - } - } - } - if (outlog && lastError) { - logPanel.appendError("to " + (i - 1)); - } - executor.getConnection().commit(); - logPanel.append("Execution time: " + (System.currentTimeMillis() - startTime) + " ms"); - } + errorMessage = execute.getError(i); + } catch (SQLException ignored) { + } + + if (!MiscUtils.isNull(errorMessage)) + throw new SQLException(errorMessage); + } + } + } + + if (loggingEnabled) { + logPanel.append(String.format("Batch executed. Added: %d. Failed: %d", batchSuccess, batchError)); - if (!useBatchesBox.isSelected()) { - GUIUtilities.displayInformationMessage(countSuccess + " records added successfully\n" + countError + " queries failed"); - logPanel.append(countSuccess + " records added successfully\n" + countError + " queries failed"); + if (countError > 0) { + for (int i = 0; i < states.length; i++) { + if (states[i] < 0) { + try { + errorMessage = execute.getError(i); + if (!MiscUtils.isNull(errorMessage)) + logPanel.appendError(errorMessage); + + } catch (SQLException ignored) { } - } catch (Exception ex) { - ex.printStackTrace(); - GUIUtilities.displayExceptionErrorDialog("generation error: " + ex.getMessage(), ex, this.getClass()); - } finally { - executor.releaseResources(); } - progressBar.setValue(0); } - return null; } + } - @Override - public void finished() { - startButton.setEnabled(true); - stopButton.setEnabled(false); - } - }; - worker.start(); + if (recordIndex % commitAfter == 0 && recordIndex != 0) { + batch.commit(); + batch.startTransaction(); + } + + } catch (SQLException e) { + logPanel.appendError(e.getMessage()); + batch.cancel(); + if (isStopOnError) { + GUIUtilities.displayExceptionErrorDialog(e.getMessage(), e, this.getClass()); + break; + } } - }); - countRecordsField = new NumberTextField(false); - countRecordsField.setText("100"); - batchCountField = new NumberTextField(false); - batchCountField.setText("100"); + recordIndex += batchSize; + progressBar.setValue(recordIndex); + } - commitAfterField = new NumberTextField(false); - commitAfterField.setText("500"); + batch.commit(); + logPanel.appendAction("Added: " + countSuccess + "\nFailed: " + countError); + GUIUtilities.displayInformationMessage(bundleString("generationEndMessage", countSuccess, recordsCount, countError)); + } + private String getInsertQuery(List selectedFields) { + StringBuilder fields = new StringBuilder(); + StringBuilder values = new StringBuilder(); - logBox = new JCheckBox(bundles("OutputLog")); - useBatchesBox = new JCheckBox(bundles("useBatchesBox")); - printBatchStateBox = new JCheckBox(bundles("printBatchStateBox")); - stopOnErrorBox = new JCheckBox(bundles("StopOnError")); + boolean first = true; + for (FieldGenerator fieldGenerator : selectedFields) { + if (!first) { + fields.append(","); + values.append(", "); + } + + fields.append("\n \"").append(fieldGenerator.getColumn().getName()).append("\""); + values.append("?"); - tableBoxModel.setElements(fillTables()); - JPanel topPanel = new JPanel(); - JPanel bottomPanel = new JPanel(); - JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, topPanel, bottomPanel); + first = false; + } + String query = String.format( + "INSERT INTO \"%s\" (%s\n) VALUES (%s);", + tablesCombo.getSelectedItem(), + fields, + values + ); - GridBagHelper gbh = new GridBagHelper(); + logPanel.appendPlain("Prepared query:"); + logPanel.appendAction(query); - //ConnectionCombobox - GridBagConstraints gbc = new GridBagConstraints(0, 0, 1, 1, 0, 0, - GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0, 0); - gbh.setDefaults(gbc); + return query; + } - topPanel.setLayout(new GridBagLayout()); + private Vector getDatabaseTables() { + Vector tables = new Vector<>(); - topPanel.add(comboboxPanel, gbh.defaults().spanX().fillHorizontally().setInsets(0, 0, 0, 0).get()); + String query = "SELECT RDB$RELATION_NAME\n" + + "FROM RDB$RELATIONS\n" + + "WHERE RDB$VIEW_BLR IS NULL \n" + + "AND (RDB$SYSTEM_FLAG IS NULL OR RDB$SYSTEM_FLAG = 0)\n" + + "AND RDB$RELATION_TYPE = 0 OR RDB$RELATION_TYPE = 2\n" + + "ORDER BY RDB$RELATION_NAME"; - JLabel label = new JLabel(bundles("Table")); - topPanel.add(label, gbh.defaults().nextRowFirstCol().setLabelDefault().get()); + try { + ResultSet rs = executor.getResultSet(query).getResultSet(); + while (rs.next()) + tables.add(rs.getString(1).trim()); - topPanel.add(tableBox, gbh.defaults().nextCol().spanX().get()); + if (tables.isEmpty()) { + tables.add(null); + GUIUtilities.displayErrorMessage(bundleString("noTables")); + } - label = new JLabel(bundles("CountRecords")); - topPanel.add(label, gbh.defaults().nextRowFirstCol().setLabelDefault().get()); + } catch (SQLException | NullPointerException e) { + Log.error(e.getMessage(), e); - topPanel.add(countRecordsField, gbh.defaults().nextCol().spanX().get()); + } finally { + executor.releaseResources(); + } - label = new JLabel(bundles("AfterCommit")); - topPanel.add(label, gbh.defaults().nextRowFirstCol().setLabelDefault().get()); + return tables; + } - topPanel.add(commitAfterField, gbh.defaults().nextCol().spanX().get()); + private void loadTableColumns() { - topPanel.add(logBox, gbh.defaults().nextRowFirstCol().setLabelDefault().get()); + String selectedTable = getSelectedTable(); + if (selectedTable == null) + return; - topPanel.add(stopOnErrorBox, gbh.defaults().nextCol().setLabelDefault().get()); + DatabaseHost host = null; + JPanel tabComponent = GUIUtilities.getDockedTabComponent(ConnectionsTreePanel.PROPERTY_KEY); + if (tabComponent instanceof ConnectionsTreePanel) { + ConnectionsTreePanel connectionsTreePanel = (ConnectionsTreePanel) tabComponent; + NamedObject namedObject = connectionsTreePanel.getHostNode(getSelectedConnection()).getDatabaseObject(); + host = (DatabaseHost) namedObject; + } - topPanel.add(useBatchesBox, gbh.defaults().nextCol().setLabelDefault().get()); + if (host == null) + return; - batchLabel = new JLabel(bundles("BatchCount")); + List fieldGenerators = new ArrayList<>(); + for (DatabaseColumn column : host.getColumns(selectedTable)) + fieldGenerators.add(new FieldGenerator(column, executor)); - batchNotAvailable = new JLabel(); - batchNotAvailable.setVisible(false); + fieldsPanel.setFieldGenerators(fieldGenerators); + } - topPanel.add(batchLabel, gbh.defaults().nextCol().setLabelDefault().anchorEast().anchorCenter().get()); + private void checkBatchToolsEnable() { + boolean enable = new DefaultDriverLoader().load(getSelectedConnection().getJDBCDriver()).getMajorVersion() > 3 + && getSelectedConnection().getMajorServerVersion() > 3 + && getSelectedConnection().useNewAPI(); - topPanel.add(batchCountField, gbh.defaults().nextCol().setIpad(40, 0).get()); + useBatchesCheck.setEnabled(enable); + useBatchesCheck.setSelected(false); + updateBatchToolsEnable(); + } - topPanel.add(printBatchStateBox, gbh.defaults().nextCol().spanX().get()); + private void updateBatchToolsEnable() { + boolean enable = useBatchesCheck.isSelected(); + batchLabel.setEnabled(enable); + batchSizeField.setEnabled(enable); + } - // topPanel.add(batchNotAvailable, gbh.defaults().nextRowFirstCol().spanX().get()); + private void tablesComboTriggered(ItemEvent e) { + if (e.getStateChange() == ItemEvent.SELECTED) { + loadTableColumns(); + tabbedPane.setSelectedIndex(0); + } + } - topPanel.add(progressBar, gbh.defaults().nextRowFirstCol().spanX().get()); + private void connectionsComboTriggered(ItemEvent e) { + if (e.getStateChange() != ItemEvent.SELECTED) + return; - topPanel.add(fieldsPanel, gbh.defaults().nextRowFirstCol().spanX().setMaxWeightY().fillBoth().get()); + executor.setDatabaseConnection(getSelectedConnection()); + tablesModel.setElements(getDatabaseTables()); + checkBatchToolsEnable(); + } - topPanel.add(startButton, gbh.defaults().nextRowFirstCol().setLabelDefault().get()); + private String getSelectedTable() { + return (String) tablesCombo.getSelectedItem(); + } - topPanel.add(stopButton, gbh.defaults().nextCol().setLabelDefault().get()); + private DatabaseConnection getSelectedConnection() { + return connectionsCombo.getSelectedConnection(); + } - topPanel.add(new JPanel(), gbh.defaults().nextCol().spanX().get()); + // --- TabView impl --- - bottomPanel.setLayout(new GridBagLayout()); + @Override + public boolean tabViewSelected() { + return true; + } - gbh.setXY(0, 0); + @Override + public boolean tabViewDeselected() { + return true; + } - bottomPanel.add(new JScrollPane(logPanel), gbh.defaults().spanX().spanY().fillBoth().get()); + @Override + public boolean tabViewClosing() { + return true; + } - setLayout(new GridBagLayout()); + // --- - gbh.setXY(0, 0); - - add(splitPane, gbh.defaults().spanX().spanY().fillBoth().get()); - - splitPane.setResizeWeight(0.7); - - Driver driver = new DefaultDriverLoader().load(executor.getDatabaseConnection().getJDBCDriver()); - if (driver.getMajorVersion() < 4 || !executor.getDatabaseConnection().useNewAPI() || - executor.getDatabaseConnection().getMajorServerVersion() < 4) { - useBatchesBox.setEnabled(false); - batchLabel.setEnabled(false); - batchCountField.setEnabled(false); - printBatchStateBox.setEnabled(false); - StringBuilder sb = new StringBuilder(); - if (driver.getMajorVersion() < 4) - sb.append(bundles("UnsupportedDriver")); - if (!executor.getDatabaseConnection().useNewAPI()) { - if (sb.length() > 0) - sb.append(". "); - sb.append(bundles("OOAPINotUsed")); - } - if (executor.getDatabaseConnection().getMajorServerVersion() < 4) { - if (sb.length() > 0) - sb.append(". "); - sb.append(bundles("UnsupportedServer")); - } - batchNotAvailable.setVisible(true); - batchNotAvailable.setForeground(Color.RED); - batchNotAvailable.setText(sb.toString()); - } + private static String bundleString(String key, Object... args) { + return Bundles.get(GeneratorTestDataPanel.class, key, args); } } diff --git a/src/org/executequery/gui/browser/HostPanel.java b/src/org/executequery/gui/browser/HostPanel.java index 25ffae171..65b003d7d 100644 --- a/src/org/executequery/gui/browser/HostPanel.java +++ b/src/org/executequery/gui/browser/HostPanel.java @@ -102,7 +102,7 @@ public boolean tabViewDeselected() { return connectionPanel.tabViewDeselected(); } - public void setValues(DatabaseHost host) { + public void setValues(DatabaseHost host, boolean updatePropertiesPanel) { this.host = host; connectionPanel.setConnectionValue(host); @@ -110,7 +110,7 @@ public void setValues(DatabaseHost host) { DatabaseConnection databaseConnection = host.getDatabaseConnection(); if (databaseConnection.isConnected()) changePanelData(); - else + else if (updatePropertiesPanel) updateDatabaseProperties(true); } diff --git a/src/org/executequery/gui/browser/ObjectDefinitionPanel.java b/src/org/executequery/gui/browser/ObjectDefinitionPanel.java index a10a31624..8020d7490 100644 --- a/src/org/executequery/gui/browser/ObjectDefinitionPanel.java +++ b/src/org/executequery/gui/browser/ObjectDefinitionPanel.java @@ -178,9 +178,9 @@ public void mouseClicked(MouseEvent e) { if (databaseConnection == null) databaseConnection = currentObjectView.getHost().getDatabaseConnection(); - BaseDialog dialog = new BaseDialog("Edit View", true); + BaseDialog dialog = new BaseDialog(CreateViewPanel.EDIT_TITLE, false); CreateViewPanel panel = new CreateViewPanel(databaseConnection, dialog, (DefaultDatabaseView) currentObjectView); - dialog.addDisplayComponent(panel); + dialog.addDisplayComponentWithEmptyBorder(panel); dialog.display(); } } diff --git a/src/org/executequery/gui/browser/TableDataTab.java b/src/org/executequery/gui/browser/TableDataTab.java index d87cb24ea..2ba2bf567 100644 --- a/src/org/executequery/gui/browser/TableDataTab.java +++ b/src/org/executequery/gui/browser/TableDataTab.java @@ -25,6 +25,7 @@ import org.executequery.Constants; import org.executequery.EventMediator; import org.executequery.GUIUtilities; +import org.executequery.UserPreferencesManager; import org.executequery.components.CancelButton; import org.executequery.databasemediators.QueryTypes; import org.executequery.databasemediators.spi.DefaultStatementExecutor; @@ -511,6 +512,7 @@ public boolean canHandleEvent(ApplicationEvent event) { table.setModel(sorter); tableModel.setTable(table); sorter.setTableHeader(table.getTableHeader()); + ((ResultSetTableModel) sorter.getReferencedTableModel()).setCellsEditable(!UserPreferencesManager.doubleClickOpenItemView()); boolean showLineLumbers = SystemProperties.getBooleanProperty("user", "results.table.row.numbers"); if (showLineLumbers) { diff --git a/src/org/executequery/gui/browser/TraceManagerPanel.java b/src/org/executequery/gui/browser/TraceManagerPanel.java index 6145a8f06..3e6e633f6 100644 --- a/src/org/executequery/gui/browser/TraceManagerPanel.java +++ b/src/org/executequery/gui/browser/TraceManagerPanel.java @@ -25,6 +25,7 @@ import org.underworldlabs.util.DynamicLibraryLoader; import org.underworldlabs.util.FileUtils; import org.underworldlabs.util.MiscUtils; +import org.underworldlabs.util.PanelsStateProperties; import javax.swing.*; import java.awt.*; @@ -40,16 +41,15 @@ import java.sql.SQLException; import java.sql.Timestamp; import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.Arrays; +import java.util.*; import java.util.List; -import java.util.Vector; public class TraceManagerPanel extends AbstractServiceManagerPanel implements TabView { public static final String TITLE = Bundles.get(TraceManagerPanel.class, "title"); public static final String FRAME_ICON = "icon_manager_trace"; + private PanelsStateProperties stateProperties; private IFBTraceManager traceManager; private TablePanel loggerPanel; @@ -174,14 +174,23 @@ public boolean tabViewDeselected() { } protected void initOtherComponents() { + stateProperties = new PanelsStateProperties(TraceManagerPanel.class.getName()); + message = Message.LOG_MESSAGE; sessions = new ArrayList<>(); initTraceManager(null); sessionField = new JTextField(); sessionField.setText("Session"); sessionManagerPanel = new SessionManagerPanel(traceManager, sessionField); + columnsCheckPanel = new ListSelectionPanel(new Vector<>(Arrays.asList(LogConstants.COLUMNS))); - columnsCheckPanel.selectAllAction(); + if (stateProperties.isLoaded()) { + for (Object available : LogConstants.COLUMNS) + if (Objects.equals(stateProperties.get(available.toString()), String.valueOf(true))) + columnsCheckPanel.selectOneStringAction(available.toString()); + } else + columnsCheckPanel.selectAllAction(); + loggerPanel = new TablePanel(columnsCheckPanel); analisePanel = new AnalisePanel(loggerPanel.getTableRows()); fileConfButton = new JButton("..."); @@ -211,14 +220,7 @@ public void itemStateChanged(ItemEvent e) { toolBar.add(encodeCombobox, gbhToolBar.nextCol().setLabelDefault().fillHorizontally().setWeightX(0.1).get()); //toolBar.add(new JSeparator(),gbhToolBar.nextCol().setLabelDefault().get()); visibleColumnsButton = WidgetFactory.createRolloverButton("visibleColumnsButton", bundleString("VisibleColumns"), "icon_find_next"); - visibleColumnsButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - BaseDialog dialog = new BaseDialog(bundleString("VisibleColumns"), true); - dialog.addDisplayComponentWithEmptyBorder(columnsCheckPanel); - dialog.display(); - } - }); + visibleColumnsButton.addActionListener(e -> showVisibleColumnsDialog()); toolBar.add(visibleColumnsButton, gbhToolBar.nextCol().setLabelDefault().get()); toolBar.add(new JPanel(), gbhToolBar.nextCol().fillHorizontally().spanX().get()); fileConfField = new JTextField(); @@ -382,6 +384,17 @@ public void actionPerformed(ActionEvent e) { } + private void showVisibleColumnsDialog() { + BaseDialog dialog = new BaseDialog(bundleString("VisibleColumns"), true); + dialog.addDisplayComponentWithEmptyBorder(columnsCheckPanel); + dialog.display(); + + for (Object available : columnsCheckPanel.getAvailableValues()) + stateProperties.put(available.toString(), String.valueOf(false)); + for (Object available : columnsCheckPanel.getSelectedValues()) + stateProperties.put(available.toString(), String.valueOf(true)); + stateProperties.save(); + } protected void loadFromFile(int selectedRow, int selectedCol) { @@ -457,11 +470,9 @@ protected void arrangeComponents() { add(topPanel, gbh.fillBoth().spanX().setMaxWeightY().topGap(5).get()); - - add(startStopSessionButton, gbh.nextRowFirstCol().setLabelDefault().get()); - - add(clearTableButton, gbh.nextCol().setLabelDefault().get()); - + add(new JPanel(), gbh.nextRowFirstCol().setLabelDefault().setMaxWeightX().get()); + add(startStopSessionButton, gbh.nextCol().setMinWeightX().get()); + add(clearTableButton, gbh.nextCol().get()); tabPane.add(bundleString("Connection"), connectionPanel); //tabPane.add(bundleString("BuildConfigurationFile"), new JScrollPane(confPanel)); diff --git a/src/org/executequery/gui/browser/comparer/Comparer.java b/src/org/executequery/gui/browser/comparer/Comparer.java index 5c4c49e07..6d38462eb 100644 --- a/src/org/executequery/gui/browser/comparer/Comparer.java +++ b/src/org/executequery/gui/browser/comparer/Comparer.java @@ -40,6 +40,10 @@ public class Comparer { protected DatabaseConnection masterConnection; protected DatabaseConnection compareConnection; + private int stubsInsertIndex; + private Map> stubsOnAlter; + private Map> stubsOnCreate; + private final int[] counter; private String constraintsList; private String computedFieldsList; @@ -63,6 +67,7 @@ public Comparer( constraintsToDrop = new ArrayList<>(); computedFields = new ArrayList<>(); + stubsInsertIndex = -1; counter = new int[]{0, 0, 0}; this.panel = panel; @@ -215,7 +220,7 @@ public void alterErds(List tables) { AbstractDatabaseObject compareObject = (AbstractDatabaseObject) alterObjects.get(obj); String sqlScript = masterObject.getCompareAlterSQL(compareObject); - if (!sqlScript.contains("there are no changes")) { + if (!sqlScript.contains(SQLUtils.THERE_ARE_NO_CHANGES)) { script.add("\n/* " + obj.getName() + " */\n" + sqlScript); panel.addTreeComponent(ComparerDBPanel.ComparerTreeNode.ALTER, TABLE, obj); panel.addComparedObject(new ComparedObject(TABLE, masterObject, compareObject.getCreateSQLText(), masterObject.getCreateSQLText())); @@ -254,6 +259,9 @@ public void createObjects(int type) { if (createObjects == null || createObjects.isEmpty()) return; + if (stubsOnCreate != null && stubsOnCreate.containsKey(type) && stubsOnCreate.get(type) != null) + stubsOnCreate.get(type).addAll(createObjects); + String header = MessageFormat.format( "\n/* ----- Creating {0} ----- */\n", Bundles.getEn(NamedObject.class, NamedObject.META_TYPES_FOR_BUNDLE[type])); @@ -382,13 +390,23 @@ public void alterObjects(int type) { loadingObjectsHelperCompare.preparingLoadForObjectAndCols(compareObject); String sqlScript = masterObject.getCompareAlterSQL(compareObject); - if (!sqlScript.contains("there are no changes")) { + if (!sqlScript.contains(SQLUtils.THERE_ARE_NO_CHANGES) && !sqlScript.equals(SQLUtils.ALTER_CONSTRAINTS)) { + + if (stubsOnAlter != null && stubsOnAlter.containsKey(type) && stubsOnAlter.get(type) != null) + stubsOnAlter.get(type).add(compareObject); + script.add("\n/* " + obj.getName() + " */\n" + sqlScript); panel.addTreeComponent(ComparerDBPanel.ComparerTreeNode.ALTER, type, obj); panel.addComparedObject(new ComparedObject(type, masterObject, compareObject.getCreateSQLText(), masterObject.getCreateSQLText())); panel.addToLog("\t" + obj.getName()); isHeaderNeeded = true; counter[2]++; + } else if (sqlScript.equals(SQLUtils.ALTER_CONSTRAINTS)) { + panel.addTreeComponent(ComparerDBPanel.ComparerTreeNode.ALTER, type, obj); + panel.addComparedObject(new ComparedObject(type, masterObject, compareObject.getCreateSQLText(), masterObject.getCreateSQLText())); + panel.addToLog("\t" + obj.getName()); + isHeaderNeeded = true; + counter[2]++; } loadingObjectsHelperMaster.postProcessingLoadForObjectAndCols(masterObject); @@ -633,26 +651,31 @@ public void createComputedFields() { } } - public void createStubs( + public void setStubsNeed( + boolean onCreate, boolean functions, boolean procedures, boolean triggers, boolean ddlTriggers, boolean dbTriggers) { - if (functions) - addStubsToScript(FUNCTION); - if (procedures) - addStubsToScript(PROCEDURE); - if (triggers) - addStubsToScript(TRIGGER); - if (ddlTriggers) - addStubsToScript(DDL_TRIGGER); - if (dbTriggers) - addStubsToScript(DATABASE_TRIGGER); + Map> exampleHashMap = new HashMap<>(); + exampleHashMap.put(FUNCTION, functions ? new ArrayList<>() : null); + exampleHashMap.put(PROCEDURE, procedures ? new ArrayList<>() : null); + exampleHashMap.put(TRIGGER, triggers ? new ArrayList<>() : null); + exampleHashMap.put(DDL_TRIGGER, ddlTriggers ? new ArrayList<>() : null); + exampleHashMap.put(DATABASE_TRIGGER, dbTriggers ? new ArrayList<>() : null); + + if (stubsInsertIndex < 0) + stubsInsertIndex = script.size(); + + if (onCreate) + stubsOnCreate = new HashMap<>(exampleHashMap); + else + stubsOnAlter = new HashMap<>(exampleHashMap); } private void addConstraintToScript(org.executequery.gui.browser.ColumnConstraint obj) { script.add("\n/* " + obj.getTable() + "." + obj.getName() + " */"); script.add("\nALTER TABLE " + obj.getTable() + "\n\tADD " + - SQLUtils.generateDefinitionColumnConstraint(obj, true, false, compareConnection, false) + ";\n"); + SQLUtils.generateDefinitionColumnConstraint(obj, true, false, compareConnection, true) + ";\n"); } private void dropConstraintToScript(org.executequery.gui.browser.ColumnConstraint obj) { @@ -847,7 +870,7 @@ private void alterListConstraints(int type) { AbstractDatabaseObject masterAbstractObject = (AbstractDatabaseObject) masterObject; loadingObjectsHelperMaster.preparingLoadForObjectCols(masterAbstractObject); if (Objects.equals(masterObject.getName(), compareObject.getName())) - if (!((AbstractDatabaseObject) masterObject).getCompareAlterSQL((AbstractDatabaseObject) compareObject).contains("there are no changes")) + if (!((AbstractDatabaseObject) masterObject).getCompareAlterSQL((AbstractDatabaseObject) compareObject).contains(SQLUtils.THERE_ARE_NO_CHANGES)) checkConstraintsPair(masterObject, compareObject, droppedConstraints); loadingObjectsHelperMaster.postProcessingLoadForObjectForCols(masterAbstractObject); @@ -915,10 +938,10 @@ private void checkConstraintsPair(NamedObject masterObject, NamedObject compareO if (panel.isCanceled()) break; - if ((masterCC.getType() == PRIMARY_KEY && !TABLE_CONSTRAINTS_NEED[0]) || - (masterCC.getType() == FOREIGN_KEY && !TABLE_CONSTRAINTS_NEED[1]) || - (masterCC.getType() == UNIQUE_KEY && !TABLE_CONSTRAINTS_NEED[2]) || - (masterCC.getType() == CHECK_KEY && !TABLE_CONSTRAINTS_NEED[3])) + if ((masterCC.getType() == PRIMARY_KEY && TABLE_CONSTRAINTS_NEED[0]) || + (masterCC.getType() == FOREIGN_KEY && TABLE_CONSTRAINTS_NEED[1]) || + (masterCC.getType() == UNIQUE_KEY && TABLE_CONSTRAINTS_NEED[2]) || + (masterCC.getType() == CHECK_KEY && TABLE_CONSTRAINTS_NEED[3])) continue; long dropCheck = compareConstraints.stream() @@ -1015,10 +1038,10 @@ private void checkConstraintsPair(NamedObject masterObject, NamedObject compareO if (panel.isCanceled()) break; - if ((comparingCC.getType() == PRIMARY_KEY && !TABLE_CONSTRAINTS_NEED[0]) || - (comparingCC.getType() == FOREIGN_KEY && !TABLE_CONSTRAINTS_NEED[1]) || - (comparingCC.getType() == UNIQUE_KEY && !TABLE_CONSTRAINTS_NEED[2]) || - (comparingCC.getType() == CHECK_KEY && !TABLE_CONSTRAINTS_NEED[3])) + if ((comparingCC.getType() == PRIMARY_KEY && TABLE_CONSTRAINTS_NEED[0]) || + (comparingCC.getType() == FOREIGN_KEY && TABLE_CONSTRAINTS_NEED[1]) || + (comparingCC.getType() == UNIQUE_KEY && TABLE_CONSTRAINTS_NEED[2]) || + (comparingCC.getType() == CHECK_KEY && TABLE_CONSTRAINTS_NEED[3])) continue; long addCheck = masterConstraints.stream() @@ -1114,21 +1137,15 @@ private List sortObjectsByDependency(List objectsList) return objectsList; } - private void addStubsToScript(int type) { + private void addStubsToScript(int type, List stubsList, int insertIndex) { - List stubsList = createListObjects( - panel.isExtractMetadata() ? new ArrayList<>() : getObjects(masterConnection, type), - getObjects(compareConnection, type), - type - ); - - if (stubsList.isEmpty()) + if (stubsList == null || stubsList.isEmpty()) return; String header = MessageFormat.format( "\n/* ----- Creating {0} stubs ----- */\n", Bundles.getEn(NamedObject.class, NamedObject.META_TYPES_FOR_BUNDLE[type])); - script.add(header); + script.add(insertIndex++, header); panel.recreateProgressBar( "CreatingStubs", NamedObject.META_TYPES[type], @@ -1136,8 +1153,8 @@ private void addStubsToScript(int type) { ); for (NamedObject obj : stubsList) { - script.add("\n/* " + obj.getName() + " (STUB) */"); - script.add("\n" + SQLUtils.generateCreateDefaultStub(obj)); + script.add(insertIndex++, "\n/* " + obj.getName() + " (STUB) */"); + script.add(insertIndex++, "\n" + SQLUtils.generateCreateDefaultStub(obj)); panel.incrementProgressBarValue(); } @@ -1160,6 +1177,21 @@ public String getComputedFieldsList() { } public ArrayList getScript() { + + if (stubsInsertIndex > 0 && stubsOnCreate != null) { + for (Integer key : stubsOnCreate.keySet()) + addStubsToScript(key, stubsOnCreate.get(key), stubsInsertIndex); + + stubsOnCreate = null; + } + + if (stubsInsertIndex > 0 && stubsOnAlter != null) { + for (Integer key : stubsOnAlter.keySet()) + addStubsToScript(key, stubsOnAlter.get(key), stubsInsertIndex); + + stubsOnAlter = null; + } + return script; } diff --git a/src/org/executequery/gui/browser/generatortestdata/FieldGenerator.java b/src/org/executequery/gui/browser/generatortestdata/FieldGenerator.java index ec95ce102..1aa46804f 100644 --- a/src/org/executequery/gui/browser/generatortestdata/FieldGenerator.java +++ b/src/org/executequery/gui/browser/generatortestdata/FieldGenerator.java @@ -4,7 +4,8 @@ import org.executequery.databaseobjects.DatabaseColumn; public class FieldGenerator { - MethodGeneratorPanel methodGeneratorPanel; + private final MethodGeneratorPanel methodGeneratorPanel; + private boolean selectedField; private DatabaseColumn column; @@ -37,11 +38,4 @@ public void setFirst() { methodGeneratorPanel.setFirst(); } - public void setMethodGeneratorPanel(MethodGeneratorPanel methodGeneratorPanel) { - this.methodGeneratorPanel = methodGeneratorPanel; - } - - public Object getNextDataTestObject() { - return getMethodGeneratorPanel().getTestDataObject(); - } } diff --git a/src/org/executequery/gui/browser/generatortestdata/FieldsPanel.java b/src/org/executequery/gui/browser/generatortestdata/FieldsPanel.java index d7f791028..9edbf046c 100644 --- a/src/org/executequery/gui/browser/generatortestdata/FieldsPanel.java +++ b/src/org/executequery/gui/browser/generatortestdata/FieldsPanel.java @@ -2,57 +2,70 @@ import org.executequery.gui.browser.GeneratorTestDataPanel; import org.executequery.localization.Bundles; +import org.underworldlabs.swing.layouts.GridBagHelper; import javax.swing.*; -import javax.swing.event.ListSelectionEvent; -import javax.swing.event.ListSelectionListener; import javax.swing.table.AbstractTableModel; import java.awt.*; +import java.util.ArrayList; import java.util.List; public class FieldsPanel extends JPanel { + public final static int SELECTED_FIELD = 0; - public final static int NAME_FIELD = 1; - public final static int TYPE_FIELD = 2; - public final static int REQUIRED_FIELD = 3; + public final static int NAME_FIELD = SELECTED_FIELD + 1; + public final static int TYPE_FIELD = NAME_FIELD + 1; + public final static int REQUIRED_FIELD = TYPE_FIELD + 1; + + private JPanel rightPanel; private JTable tableFields; - private List fieldGenerators; - private final String[] colNames = Bundles.get(GeneratorTestDataPanel.class, - new String[]{"Selected", "Name", "Type", "Required"}); private FieldGeneratorModel model; - private JPanel rightPanel; + private List fieldGenerators; - public FieldsPanel(List fieldGenerators) { - this.fieldGenerators = fieldGenerators; + public FieldsPanel() { + fieldGenerators = new ArrayList<>(); init(); } private void init() { + rightPanel = new JPanel(); - rightPanel.setBorder(BorderFactory.createTitledBorder(bundledString("GeneratorMethod"))); rightPanel.setLayout(new GridBagLayout()); + rightPanel.setBorder(BorderFactory.createTitledBorder(Bundles.get("GeneratorTestDataPanel.GeneratorMethod"))); + model = new FieldGeneratorModel(); tableFields = new JTable(model); - tableFields.getSelectionModel().addListSelectionListener(new ListSelectionListener() { - @Override - public void valueChanged(ListSelectionEvent e) { - rightPanel.removeAll(); - if (tableFields.getSelectedRow() >= 0) - rightPanel.add(fieldGenerators.get(tableFields.getSelectedRow()).getMethodGeneratorPanel(), new GridBagConstraints(0, 0, GridBagConstraints.REMAINDER, GridBagConstraints.REMAINDER, 1, 1, - GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); - rightPanel.updateUI(); - } - }); - JScrollPane scroll = new JScrollPane(tableFields); + tableFields.getSelectionModel().addListSelectionListener(e -> reloadRightPanel()); + + // --- + JScrollPane rightScrollPane = new JScrollPane(rightPanel); + rightScrollPane.setPreferredSize(new Dimension(675, 400)); + rightScrollPane.setMinimumSize(rightScrollPane.getPreferredSize()); + + JScrollPane leftScrollPane = new JScrollPane(tableFields); + leftScrollPane.setPreferredSize(new Dimension(400, 400)); + leftScrollPane.setMinimumSize(leftScrollPane.getPreferredSize()); + + JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT); + splitPane.setTopComponent(leftScrollPane); + splitPane.setBottomComponent(rightScrollPane); + splitPane.setResizeWeight(1); setLayout(new GridBagLayout()); + add(splitPane, new GridBagHelper().fillBoth().spanX().spanY().get()); + } + private void reloadRightPanel() { + rightPanel.removeAll(); + if (tableFields.getSelectedRow() >= 0) { + rightPanel.add( + fieldGenerators.get(tableFields.getSelectedRow()).getMethodGeneratorPanel(), + new GridBagHelper().fillBoth().spanX().spanY().get() + ); + } - JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, scroll, new JScrollPane(rightPanel)); - add(splitPane, new GridBagConstraints(0, 0, GridBagConstraints.REMAINDER, GridBagConstraints.REMAINDER, 1, 1, - GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); - splitPane.setResizeWeight(0.6); + rightPanel.updateUI(); } public List getFieldGenerators() { @@ -61,25 +74,15 @@ public List getFieldGenerators() { public void setFieldGenerators(List fieldGenerators) { this.fieldGenerators = fieldGenerators; - model.fireTableDataChanged(); - } - - private String bundledString(String key) { - return GeneratorTestDataPanel.bundles(key); + this.model.fireTableDataChanged(); } - public class FieldGeneratorModel extends AbstractTableModel { - - - @Override - public int getRowCount() { - return fieldGenerators.size(); - } + private class FieldGeneratorModel extends AbstractTableModel { - @Override - public int getColumnCount() { - return colNames.length; - } + private final String[] COLUMN_NAMES = Bundles.get( + GeneratorTestDataPanel.class, + new String[]{"Selected", "Name", "Type", "Required"} + ); @Override public Object getValueAt(int rowIndex, int columnIndex) { @@ -97,16 +100,16 @@ public Object getValueAt(int rowIndex, int columnIndex) { } } + @Override public void setValueAt(Object aValue, int rowIndex, int columnIndex) { - if (columnIndex == SELECTED_FIELD) { + if (columnIndex == SELECTED_FIELD) fieldGenerators.get(rowIndex).setSelectedField((boolean) aValue); - } } + @Override public Class getColumnClass(int columnIndex) { switch (columnIndex) { case SELECTED_FIELD: - return Boolean.class; case REQUIRED_FIELD: return Boolean.class; default: @@ -114,14 +117,26 @@ public Class getColumnClass(int columnIndex) { } } + @Override public String getColumnName(int column) { - return colNames[column]; + return COLUMN_NAMES[column]; } + @Override public boolean isCellEditable(int rowIndex, int columnIndex) { return columnIndex == SELECTED_FIELD; } + @Override + public int getRowCount() { + return fieldGenerators.size(); + } + + @Override + public int getColumnCount() { + return COLUMN_NAMES.length; + } + + } // FieldGeneratorModel class - } } diff --git a/src/org/executequery/gui/browser/generatortestdata/MethodGeneratorPanel.java b/src/org/executequery/gui/browser/generatortestdata/MethodGeneratorPanel.java index 378891566..7d4c8fad1 100644 --- a/src/org/executequery/gui/browser/generatortestdata/MethodGeneratorPanel.java +++ b/src/org/executequery/gui/browser/generatortestdata/MethodGeneratorPanel.java @@ -4,28 +4,26 @@ import org.executequery.databaseobjects.DatabaseColumn; import org.executequery.gui.browser.GeneratorTestDataPanel; import org.executequery.gui.browser.generatortestdata.methodspanels.*; -import org.executequery.log.Log; +import org.executequery.localization.Bundles; import org.underworldlabs.swing.layouts.GridBagHelper; import javax.swing.*; import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -public class MethodGeneratorPanel extends JPanel implements ActionListener { - - DatabaseColumn column; - AbstractMethodPanel methodPanel; - private ButtonGroup buttonGroup; - public final static int COUNT_METHODS = 4; - private JPanel bottomPanel; - private DefaultStatementExecutor executor; +public class MethodGeneratorPanel extends JPanel { public final static int RANDOM = 0; public final static int FROM_TABLE = 1; public final static int FROM_LIST = 2; public final static int AUTOINCREMENT = 3; - AbstractMethodPanel[] methodPanels; + public final static int COUNT_METHODS = 4; + + private final DatabaseColumn column; + private final DefaultStatementExecutor executor; + + private JPanel mainPanel; private JRadioButton[] radioButtons; + private AbstractMethodPanel methodPanel; + private AbstractMethodPanel[] methodPanels; public MethodGeneratorPanel(DatabaseColumn column, DefaultStatementExecutor executor) { this.column = column; @@ -34,79 +32,81 @@ public MethodGeneratorPanel(DatabaseColumn column, DefaultStatementExecutor exec } private void init() { - methodPanels = new AbstractMethodPanel[COUNT_METHODS]; + radioButtons = new JRadioButton[COUNT_METHODS]; radioButtons[RANDOM] = new JRadioButton(bundledString("Random")); radioButtons[FROM_TABLE] = new JRadioButton(bundledString("getFromOtherTable")); radioButtons[FROM_LIST] = new JRadioButton(bundledString("getFromList")); radioButtons[AUTOINCREMENT] = new JRadioButton(bundledString("Autoincrement")); - buttonGroup = new ButtonGroup(); + + ButtonGroup buttonGroup = new ButtonGroup(); + methodPanels = new AbstractMethodPanel[COUNT_METHODS]; for (int i = 0; i < methodPanels.length; i++) { methodPanels[i] = null; - radioButtons[i].addActionListener(this); + radioButtons[i].addActionListener(e -> refresh()); buttonGroup.add(radioButtons[i]); } - bottomPanel = new JPanel(); - bottomPanel.setLayout(new GridBagLayout()); + + mainPanel = new JPanel(); + mainPanel.setLayout(new GridBagLayout()); setLayout(new GridBagLayout()); - GridBagHelper gbh = new GridBagHelper(); - GridBagConstraints gbc = new GridBagConstraints(0, 0, 1, 1, 0, 0, - GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0, 0); - gbh.setDefaults(gbc); - gbh.setXY(0, -1); + + GridBagHelper gbh = new GridBagHelper().anchorNorthWest().setInsets(5, 5, 5, 5).fillHorizontally().setXY(0, -1); for (int i = 0; i < radioButtons.length; i++) { - if (i != AUTOINCREMENT || (!column.getFormattedDataType().contains("CHAR") && !column.getFormattedDataType().contains("BLOB") && !column.getFormattedDataType().contains("BOOLEAN"))) - add(radioButtons[i], gbh.defaults().nextRowFirstCol().spanX().get()); + if (i != AUTOINCREMENT + || (!column.getFormattedDataType().contains("CHAR") + && !column.getFormattedDataType().contains("BLOB") + && !column.getFormattedDataType().contains("BOOLEAN")) + ) { + add(radioButtons[i], gbh.nextRowFirstCol().spanX().get()); + } } - add(bottomPanel, gbh.defaults().fillBoth().nextRowFirstCol().spanX().spanY().get()); - radioButtons[RANDOM].setSelected(true); - refresh(); - } - @Override - public void actionPerformed(ActionEvent e) { + add(mainPanel, gbh.nextRowFirstCol().setWidth(1).fillBoth().spanX().spanY().get()); + radioButtons[RANDOM].setSelected(true); refresh(); } private void refresh() { - bottomPanel.removeAll(); - GridBagConstraints gbc = new GridBagConstraints(0, 0, GridBagConstraints.REMAINDER, GridBagConstraints.REMAINDER, 1, 1, - GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0); + for (int i = 0; i < radioButtons.length; i++) { - if (radioButtons[i].isSelected()) { - if (methodPanels[i] != null) - methodPanel = methodPanels[i]; - else { - switch (i) { - case RANDOM: - methodPanel = new RandomMethodPanel(column); - break; - case FROM_TABLE: - methodPanel = new GetFromOtherTablePanel(column, executor); - break; - case FROM_LIST: - methodPanel = new GetFromListPanel(column); - break; - case AUTOINCREMENT: - methodPanel = new AutoincrementPanel(column); - break; - } - methodPanels[i] = methodPanel; - } + + if (!radioButtons[i].isSelected()) + continue; + + if (methodPanels[i] != null) { + methodPanel = methodPanels[i]; break; } + + switch (i) { + case RANDOM: + methodPanel = new RandomMethodPanel(column); + break; + case FROM_TABLE: + methodPanel = new GetFromOtherTablePanel(column, executor); + break; + case FROM_LIST: + methodPanel = new GetFromListPanel(column); + break; + case AUTOINCREMENT: + methodPanel = new AutoincrementPanel(column); + break; + } + + methodPanels[i] = methodPanel; + break; } - bottomPanel.add(methodPanel, gbc); + + mainPanel.removeAll(); + mainPanel.add(methodPanel, new GridBagHelper().fillBoth().spanX().spanY().get()); updateUI(); } public void setFirst() { - try { + if (methodPanel != null) methodPanel.setFirst(true); - } catch (NullPointerException e) { - Log.debug("methodPanel not exist"); - } } public Object getTestDataObject() { @@ -114,6 +114,7 @@ public Object getTestDataObject() { } private String bundledString(String key) { - return GeneratorTestDataPanel.bundles(key); + return Bundles.get(GeneratorTestDataPanel.class, key); } + } diff --git a/src/org/executequery/gui/browser/generatortestdata/methodspanels/AbstractMethodPanel.java b/src/org/executequery/gui/browser/generatortestdata/methodspanels/AbstractMethodPanel.java index 604a80413..d889382fd 100644 --- a/src/org/executequery/gui/browser/generatortestdata/methodspanels/AbstractMethodPanel.java +++ b/src/org/executequery/gui/browser/generatortestdata/methodspanels/AbstractMethodPanel.java @@ -1,7 +1,9 @@ package org.executequery.gui.browser.generatortestdata.methodspanels; import org.executequery.databaseobjects.DatabaseColumn; +import org.executequery.databaseobjects.T; import org.executequery.gui.browser.GeneratorTestDataPanel; +import org.executequery.localization.Bundles; import javax.swing.*; @@ -15,11 +17,79 @@ public AbstractMethodPanel(DatabaseColumn col) { public abstract Object getTestDataObject(); + protected static boolean isNumeric(String dataType) { + return dataType.contentEquals(T.BIGINT) + || dataType.contentEquals(T.INT128) + || dataType.contentEquals(T.INTEGER) + || dataType.contentEquals(T.SMALLINT) + || dataType.contentEquals(T.DOUBLE_PRECISION) + || dataType.contentEquals(T.FLOAT) + || dataType.startsWith(T.DECIMAL) + || dataType.startsWith(T.NUMERIC) + || dataType.startsWith(T.DECFLOAT); + } + + protected static boolean isDecimal(String dataType) { + return dataType.contentEquals(T.DOUBLE_PRECISION) + || dataType.contentEquals(T.FLOAT) + || dataType.startsWith(T.DECIMAL) + || dataType.startsWith(T.NUMERIC); + } + + protected static boolean isDecFloat(String dataType) { + return dataType.startsWith(T.DECFLOAT); + } + + protected static boolean isSmallint(String dataType) { + return dataType.contentEquals(T.SMALLINT); + } + + protected static boolean isInteger(String dataType) { + return dataType.contentEquals(T.INTEGER); + } + + protected static boolean isBigint(String dataType) { + return dataType.contentEquals(T.BIGINT) || dataType.contentEquals(T.INT128); + } + + protected static boolean isChar(String dataType) { + return dataType.contains(T.CHAR); + } + + protected static boolean isDate(String dataType) { + return dataType.contentEquals(T.DATE); + } + + protected static boolean isTime(String dataType) { + return dataType.contentEquals(T.TIME); + } + + protected static boolean isTimestamp(String dataType) { + return dataType.contentEquals(T.TIMESTAMP); + } + + protected static boolean isZonedTime(String dataType) { + return dataType.contentEquals(T.TIME_WITH_TIMEZONE); + } + + protected static boolean isZonedTimestamp(String dataType) { + return dataType.contentEquals(T.TIMESTAMP_WITH_TIMEZONE); + } + + protected static boolean isBlob(String dataType) { + return dataType.contains(T.BLOB); + } + + protected static boolean isBoolean(String dataType) { + return dataType.contains(T.BOOLEAN); + } + public void setFirst(boolean first) { this.first = first; } - protected String bundles(String key) { - return GeneratorTestDataPanel.bundles(key); + protected String bundleString(String key) { + return Bundles.get(GeneratorTestDataPanel.class, key); } + } diff --git a/src/org/executequery/gui/browser/generatortestdata/methodspanels/AutoincrementPanel.java b/src/org/executequery/gui/browser/generatortestdata/methodspanels/AutoincrementPanel.java index 5622a3275..41dbaa57a 100644 --- a/src/org/executequery/gui/browser/generatortestdata/methodspanels/AutoincrementPanel.java +++ b/src/org/executequery/gui/browser/generatortestdata/methodspanels/AutoincrementPanel.java @@ -2,8 +2,7 @@ import com.github.lgooddatepicker.components.DatePicker; import org.executequery.databaseobjects.DatabaseColumn; -import org.executequery.databaseobjects.T; -import org.executequery.log.Log; +import org.executequery.gui.WidgetFactory; import org.underworldlabs.swing.*; import org.underworldlabs.swing.celleditor.picker.TimestampPicker; import org.underworldlabs.swing.celleditor.picker.ZonedTimestampPicker; @@ -16,28 +15,31 @@ import java.math.BigInteger; import java.sql.Date; import java.sql.Timestamp; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.LocalTime; -import java.time.OffsetDateTime; +import java.time.*; public class AutoincrementPanel extends AbstractMethodPanel { + private JPanel settingsPanel; private JTextField iterationField; private JTextField startValueField; - private ZonedTimePicker startValueTimezone; - private TimePicker startValueTime; + private JComboBox incrementsCombo; + + private DatePicker startDate; + private TimePicker startTime; + private TimestampPicker startTimestamp; + private ZonedTimePicker startZonedTime; + private ZonedTimestampPicker startZonedTimestamp; + + private NumberTextField iterationYears; + private NumberTextField iterationMouths; + private NumberTextField iterationDays; private TimePicker iterationTime; - private TimestampPicker startValueDateTime; - private ZonedTimestampPicker startValueDateTimezone; - private DateDifferenceSetter iterationDate; - private DatePicker startValueDate; - private JComboBox plusMinusBox; - private long current_value; - private LocalDateTime current_local_date_time; - private OffsetDateTime current_offset_date_time; - private BigInteger cur_bigint; - private double current_double; + + private long currentInteger; + private double currentDouble; + private BigInteger currentBigint; + private LocalDateTime currentLocalDateTime; + private OffsetDateTime currentOffsetDateTime; public AutoincrementPanel(DatabaseColumn col) { super(col); @@ -45,315 +47,405 @@ public AutoincrementPanel(DatabaseColumn col) { } private void init() { - settingsPanel = new JPanel(); - plusMinusBox = new JComboBox(new String[]{ - "+", "-" - }); + settingsPanel = new JPanel(); settingsPanel.setLayout(new GridBagLayout()); - GridBagHelper gbh = new GridBagHelper(); - GridBagConstraints gbc = new GridBagConstraints(0, 0, 1, 1, 0, 0, - GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0, 0); - gbh.setDefaults(gbc); - Log.info("\"" + col.getFormattedDataType() + "\""); - if (col.getFormattedDataType().contentEquals(T.BIGINT) - || col.getFormattedDataType().contentEquals(T.INTEGER) - || col.getFormattedDataType().contentEquals(T.SMALLINT) - || col.getFormattedDataType().contentEquals(T.DOUBLE_PRECISION) - || col.getFormattedDataType().contentEquals(T.FLOAT) - || col.getFormattedDataType().startsWith(T.DECIMAL) - || col.getFormattedDataType().startsWith(T.NUMERIC) - || col.getFormattedDataType().startsWith(T.INT128)) { - - if (col.getFormattedDataType().contentEquals(T.BIGINT) - || col.getFormattedDataType().contentEquals(T.DOUBLE_PRECISION) - || col.getFormattedDataType().contentEquals(T.FLOAT) - || col.getFormattedDataType().startsWith(T.DECIMAL) - || col.getFormattedDataType().startsWith(T.NUMERIC) - || col.getFormattedDataType().startsWith(T.DECFLOAT) - || col.getFormattedDataType().startsWith(T.INT128) - ) { - iterationField = new JTextField(); - startValueField = new JTextField(); - if (col.getFormattedDataType().contentEquals(T.BIGINT)) { - iterationField.setText("1"); - startValueField.setText("-9223372036854775808"); - } else { - iterationField.setText("1"); - startValueField.setText("0"); - } - } else { - iterationField = new NumberTextField(); - startValueField = new NumberTextField(); - if (col.getFormattedDataType().contentEquals(T.INTEGER)) { - iterationField.setText("" + 1); - startValueField.setText("" + Integer.MIN_VALUE); - } else { - iterationField.setText("" + 1); - startValueField.setText("" + (-32768)); - } - } - - gbh.setXY(0, 0); - JLabel label = new JLabel(bundles("StartValue")); - settingsPanel.add(label, gbh.defaults().setLabelDefault().get()); - settingsPanel.add(startValueField, gbh.defaults().nextCol().setMaxWeightX().get()); - label = new JLabel(bundles("Iteration")); - settingsPanel.add(label, gbh.defaults().nextCol().setLabelDefault().get()); - settingsPanel.add(iterationField, gbh.defaults().nextCol().setMaxWeightX().get()); + incrementsCombo = WidgetFactory.createComboBox("incrementsCombo", new String[]{"+", "-"}); - } + // --- init settings panel --- - if (col.getFormattedDataType().contentEquals(T.TIME)) { + String dataType = col.getFormattedDataType(); + if (isNumeric(dataType)) { + initNumericPanel(dataType); - startValueTime = new TimePicker(); - startValueTime.setVisibleNullCheck(false); - startValueTime.setTime(LocalTime.MIN); + } else if (isDate(dataType)) { + initDatePanel(); - iterationTime = new TimePicker(); - iterationTime.setVisibleNullCheck(false); - iterationTime.setTime(LocalTime.of(1, 1, 1)); + } else if (isTime(dataType)) { + initTimePanel(); - gbh.setXY(0, 0); - settingsPanel.add(new JLabel(bundles("StartValue")), gbh.defaults().setLabelDefault().get()); - settingsPanel.add(startValueTime, gbh.defaults().nextCol().setMaxWeightX().get()); - settingsPanel.add(new JLabel(bundles("Iteration")), gbh.defaults().nextCol().setLabelDefault().get()); - settingsPanel.add(iterationTime, gbh.defaults().nextCol().setMaxWeightX().get()); - } + } else if (isTimestamp(dataType)) { + initTimestampPanel(); - if (col.getFormattedDataType().contentEquals(T.TIME_WITH_TIMEZONE)) { + } else if (isZonedTime(dataType)) { + initZonedTimePanel(); - startValueTimezone = new ZonedTimePicker(); - startValueTimezone.setVisibleNullCheck(false); - startValueTimezone.setTime(LocalTime.MIN); + } else if (isZonedTimestamp(dataType)) + initZonedTimestampPanel(); - iterationTime = new TimePicker(); - iterationTime.setVisibleNullCheck(false); - iterationTime.setTime(LocalTime.of(1, 1, 1)); + // --- base --- - gbh.setXY(0, 0); - settingsPanel.add(new JLabel(bundles("StartValue")), gbh.defaults().setLabelDefault().get()); - settingsPanel.add(startValueTimezone, gbh.defaults().nextCol().setMaxWeightX().get()); - settingsPanel.add(new JLabel(bundles("Iteration")), gbh.defaults().nextCol().setLabelDefault().get()); - settingsPanel.add(iterationTime, gbh.defaults().nextCol().setMaxWeightX().get()); - } + setLayout(new GridBagLayout()); - if (col.getFormattedDataType().contentEquals(T.DATE)) { + GridBagHelper gbh = new GridBagHelper().anchorNorthWest().fillHorizontally(); + add(incrementsCombo, gbh.spanX().get()); + add(settingsPanel, gbh.nextRowFirstCol().topGap(5).fillBoth().spanY().get()); + } - startValueDate = new DatePicker(); - startValueDate.setDate(LocalDate.now()); + private void initNumericPanel(String dataType) { + + iterationField = WidgetFactory.createNumberTextField("iterationField"); + iterationField.setText("1"); + + startValueField = WidgetFactory.createNumberTextField("startValueField"); + if (isInteger(dataType)) { + startValueField.setText("" + Integer.MIN_VALUE); + } else if (isSmallint(dataType)) { + startValueField.setText("" + (-32768)); + } else if (isBigint(dataType)) { + startValueField.setText("-9223372036854775808"); + } else + startValueField.setText("0"); + + // --- arrange --- + + GridBagHelper gbh = new GridBagHelper().anchorNorthWest().fillHorizontally(); + settingsPanel.add(new JLabel(bundleString("StartValue")), gbh.leftGap(3).topGap(3).get()); + settingsPanel.add(startValueField, gbh.nextCol().topGap(0).leftGap(5).setMaxWeightX().get()); + settingsPanel.add(new JLabel(bundleString("Iteration")), gbh.nextRowFirstCol().leftGap(3).topGap(8).setMinWeightX().get()); + settingsPanel.add(iterationField, gbh.nextCol().topGap(5).leftGap(5).setMaxWeightX().get()); + settingsPanel.add(new JPanel(), gbh.nextRowFirstCol().fillBoth().spanX().spanY().get()); + } - iterationDate = new DateDifferenceSetter(); + private void initDatePanel() { - settingsPanel.add(new JLabel(bundles("StartValue")), gbh.defaults().setLabelDefault().get()); - settingsPanel.add(startValueDate, gbh.defaults().nextCol().setMaxWeightX().get()); - settingsPanel.add(new JLabel(bundles("Iteration")), gbh.defaults().nextRowFirstCol().setLabelDefault().get()); - settingsPanel.add(iterationDate, gbh.defaults().nextCol().setMaxWeightX().get()); - } + startDate = new DatePicker(); + startDate.setDate(LocalDate.now()); + + iterationYears = WidgetFactory.createNumberTextField("yearsField"); + iterationYears.setValue(0); + + iterationMouths = WidgetFactory.createNumberTextField("mouthsField"); + iterationMouths.setValue(0); + + iterationDays = WidgetFactory.createNumberTextField("daysField"); + iterationDays.setValue(1); + + // --- arrange --- + + GridBagHelper gbh = new GridBagHelper().anchorNorthWest().fillHorizontally(); + settingsPanel.add(new JLabel(bundleString("StartValue")), gbh.leftGap(3).topGap(3).get()); + settingsPanel.add(startDate, gbh.nextCol().topGap(0).leftGap(5).setMaxWeightX().get()); + settingsPanel.add(new JLabel(bundleString("Years")), gbh.nextRowFirstCol().leftGap(3).topGap(8).setMinWeightX().get()); + settingsPanel.add(iterationYears, gbh.nextCol().topGap(5).leftGap(5).setMaxWeightX().get()); + settingsPanel.add(new JLabel(bundleString("Mouths")), gbh.nextRowFirstCol().leftGap(3).topGap(8).setMinWeightX().get()); + settingsPanel.add(iterationMouths, gbh.nextCol().topGap(5).leftGap(5).setMaxWeightX().get()); + settingsPanel.add(new JLabel(bundleString("Days")), gbh.nextRowFirstCol().leftGap(3).topGap(8).setMinWeightX().get()); + settingsPanel.add(iterationDays, gbh.nextCol().topGap(5).leftGap(5).setMaxWeightX().get()); + settingsPanel.add(new JPanel(), gbh.nextRowFirstCol().fillBoth().spanX().spanY().get()); + } + + private void initTimePanel() { + + startTime = new TimePicker(); + startTime.setVisibleNullCheck(false); + startTime.setTime(LocalTime.MIN); + + iterationTime = new TimePicker(); + iterationTime.setVisibleNullCheck(false); + iterationTime.setTime(LocalTime.of(1, 0, 0)); + + // --- arrange --- + + GridBagHelper gbh = new GridBagHelper().anchorNorthWest().fillHorizontally(); + settingsPanel.add(new JLabel(bundleString("StartValue")), gbh.leftGap(3).topGap(3).get()); + settingsPanel.add(startTime, gbh.nextCol().topGap(0).leftGap(5).setMaxWeightX().get()); + settingsPanel.add(new JLabel(bundleString("Iteration")), gbh.nextRowFirstCol().leftGap(3).topGap(8).setMinWeightX().get()); + settingsPanel.add(iterationTime, gbh.nextCol().topGap(5).leftGap(5).setMaxWeightX().get()); + settingsPanel.add(new JPanel(), gbh.nextRowFirstCol().fillBoth().spanX().spanY().get()); + } + + private void initTimestampPanel() { + + startTimestamp = new TimestampPicker(); + startTimestamp.setVisibleNullCheck(false); + startTimestamp.setDateTime(LocalDateTime.now()); + + iterationTime = new TimePicker(); + iterationTime.setVisibleNullCheck(false); + iterationTime.setTime(LocalTime.of(0, 0, 0)); + + iterationYears = WidgetFactory.createNumberTextField("yearsField"); + iterationYears.setValue(0); + + iterationMouths = WidgetFactory.createNumberTextField("mouthsField"); + iterationMouths.setValue(0); + + iterationDays = WidgetFactory.createNumberTextField("daysField"); + iterationDays.setValue(1); + + // --- arrange --- + + GridBagHelper gbh = new GridBagHelper().anchorNorthWest().fillHorizontally(); + settingsPanel.add(new JLabel(bundleString("StartValue")), gbh.leftGap(3).topGap(3).get()); + settingsPanel.add(startTimestamp, gbh.nextCol().topGap(0).leftGap(5).setMaxWeightX().get()); + settingsPanel.add(new JLabel(bundleString("Years")), gbh.nextRowFirstCol().leftGap(3).topGap(8).setMinWeightX().get()); + settingsPanel.add(iterationYears, gbh.nextCol().topGap(5).leftGap(5).setMaxWeightX().get()); + settingsPanel.add(new JLabel(bundleString("Mouths")), gbh.nextRowFirstCol().leftGap(3).topGap(8).setMinWeightX().get()); + settingsPanel.add(iterationMouths, gbh.nextCol().topGap(5).leftGap(5).setMaxWeightX().get()); + settingsPanel.add(new JLabel(bundleString("Days")), gbh.nextRowFirstCol().leftGap(3).topGap(8).setMinWeightX().get()); + settingsPanel.add(iterationDays, gbh.nextCol().topGap(5).leftGap(5).setMaxWeightX().get()); + settingsPanel.add(new JLabel(bundleString("Time")), gbh.nextRowFirstCol().leftGap(3).topGap(8).setMinWeightX().get()); + settingsPanel.add(iterationTime, gbh.nextCol().topGap(5).leftGap(5).setMaxWeightX().get()); + settingsPanel.add(new JPanel(), gbh.nextRowFirstCol().fillBoth().spanX().spanY().get()); + } + + private void initZonedTimePanel() { + + startZonedTime = new ZonedTimePicker(); + startZonedTime.setVisibleNullCheck(false); + startZonedTime.setTime(LocalTime.MIN); + + iterationTime = new TimePicker(); + iterationTime.setVisibleNullCheck(false); + iterationTime.setTime(LocalTime.of(1, 0, 0)); + + // --- arrange --- + + GridBagHelper gbh = new GridBagHelper().anchorNorthWest().fillHorizontally(); + settingsPanel.add(new JLabel(bundleString("StartValue")), gbh.leftGap(3).topGap(3).get()); + settingsPanel.add(startZonedTime, gbh.nextCol().topGap(0).leftGap(5).setMaxWeightX().get()); + settingsPanel.add(new JLabel(bundleString("Iteration")), gbh.nextRowFirstCol().leftGap(3).topGap(8).setMinWeightX().get()); + settingsPanel.add(iterationTime, gbh.nextCol().topGap(5).leftGap(5).setMaxWeightX().get()); + settingsPanel.add(new JPanel(), gbh.nextRowFirstCol().fillBoth().spanX().spanY().get()); + } + + private void initZonedTimestampPanel() { + + startZonedTimestamp = new ZonedTimestampPicker(); + startZonedTimestamp.setVisibleNullCheck(false); + startZonedTimestamp.setDateTime(LocalDateTime.now()); + + iterationTime = new TimePicker(); + iterationTime.setVisibleNullCheck(false); + iterationTime.setTime(LocalTime.of(0, 0, 0)); + + iterationYears = WidgetFactory.createNumberTextField("yearsField"); + iterationYears.setValue(0); + + iterationMouths = WidgetFactory.createNumberTextField("mouthsField"); + iterationMouths.setValue(0); - if (col.getFormattedDataType().contentEquals(T.TIMESTAMP)) { + iterationDays = WidgetFactory.createNumberTextField("daysField"); + iterationDays.setValue(1); - startValueDateTime = new TimestampPicker(); - startValueDateTime.setVisibleNullCheck(false); - startValueDateTime.setDateTime(LocalDateTime.now()); + // --- arrange --- - iterationDate = new DateDifferenceSetter(); + GridBagHelper gbh = new GridBagHelper().anchorNorthWest().fillHorizontally(); + settingsPanel.add(new JLabel(bundleString("StartValue")), gbh.leftGap(3).topGap(3).get()); + settingsPanel.add(startZonedTimestamp, gbh.nextCol().topGap(0).leftGap(5).setMaxWeightX().get()); + settingsPanel.add(new JLabel(bundleString("Years")), gbh.nextRowFirstCol().leftGap(3).topGap(8).setMinWeightX().get()); + settingsPanel.add(iterationYears, gbh.nextCol().topGap(5).leftGap(5).setMaxWeightX().get()); + settingsPanel.add(new JLabel(bundleString("Mouths")), gbh.nextRowFirstCol().leftGap(3).topGap(8).setMinWeightX().get()); + settingsPanel.add(iterationMouths, gbh.nextCol().topGap(5).leftGap(5).setMaxWeightX().get()); + settingsPanel.add(new JLabel(bundleString("Days")), gbh.nextRowFirstCol().leftGap(3).topGap(8).setMinWeightX().get()); + settingsPanel.add(iterationDays, gbh.nextCol().topGap(5).leftGap(5).setMaxWeightX().get()); + settingsPanel.add(new JLabel(bundleString("Time")), gbh.nextRowFirstCol().leftGap(3).topGap(8).setMinWeightX().get()); + settingsPanel.add(iterationTime, gbh.nextCol().topGap(5).leftGap(5).setMaxWeightX().get()); + settingsPanel.add(new JPanel(), gbh.nextRowFirstCol().fillBoth().spanX().spanY().get()); + } + + // --- - iterationTime = new TimePicker(); - iterationTime.setVisibleNullCheck(false); - iterationTime.setTime(LocalTime.of(0, 0, 0)); + private BigInteger getBigintValue(boolean increment) { - gbh.setXY(0, 0); - settingsPanel.add(new JLabel(bundles("StartValue")), gbh.defaults().setLabelDefault().get()); - settingsPanel.add(startValueDateTime, gbh.defaults().nextCol().setMaxWeightX().get()); - settingsPanel.add(new JLabel(bundles("Iteration")), gbh.defaults().nextRowFirstCol().setLabelDefault().get()); - settingsPanel.add(iterationDate, gbh.defaults().nextCol().setMaxWeightX().get()); - settingsPanel.add(iterationTime, gbh.defaults().nextRow().setMaxWeightX().get()); + if (first) { + first = false; + currentBigint = new BigInteger(startValueField.getText()); + return currentBigint; } - if (col.getFormattedDataType().contentEquals(T.TIMESTAMP_WITH_TIMEZONE)) { + BigInteger iterationBig = new BigInteger(iterationField.getText()); + currentBigint = increment ? currentBigint.add(iterationBig) : currentBigint.subtract(iterationBig); + return currentBigint; + } + + private int getIntegerValue(String dataType, boolean increment) { - startValueDateTimezone = new ZonedTimestampPicker(); - startValueDateTimezone.setVisibleNullCheck(false); - startValueDateTimezone.setDateTime(LocalDateTime.now()); + if (first) { + first = false; + currentInteger = Long.parseLong(startValueField.getText()); + return isSmallint(dataType) ? (short) currentInteger : (int) currentInteger; + } - iterationDate = new DateDifferenceSetter(); + currentInteger += Long.parseLong(iterationField.getText()) * (increment ? 1 : -1); + return isSmallint(dataType) ? (short) currentInteger : (int) currentInteger; + } - iterationTime = new TimePicker(); - iterationTime.setVisibleNullCheck(false); - iterationTime.setTime(LocalTime.of(0, 0, 0)); + private double getDecimalValue(boolean increment) { - gbh.setXY(0, 0); - settingsPanel.add(new JLabel(bundles("StartValue")), gbh.defaults().setLabelDefault().get()); - settingsPanel.add(startValueDateTimezone, gbh.defaults().nextCol().setMaxWeightX().get()); - settingsPanel.add(new JLabel(bundles("Iteration")), gbh.defaults().nextRowFirstCol().setLabelDefault().get()); - settingsPanel.add(iterationDate, gbh.defaults().nextCol().setMaxWeightX().get()); - settingsPanel.add(iterationTime, gbh.defaults().nextRow().setMaxWeightX().get()); + if (first) { + first = false; + currentDouble = Double.parseDouble(startValueField.getText()); + return currentDouble; } - setLayout(new GridBagLayout()); - gbh.setXY(0, 0); - add(plusMinusBox, gbh.defaults().spanX().get()); - add(settingsPanel, gbh.defaults().nextRowFirstCol().spanX().fillBoth().get()); - add(new JPanel(), gbh.defaults().nextRowFirstCol().spanX().spanY().fillBoth().get()); + currentDouble += Double.parseDouble(iterationField.getText()) * (increment ? 1 : -1); + return currentDouble; } - public Object getTestDataObject() { - if (col.getFormattedDataType().contentEquals(T.BIGINT) || col.getFormattedDataType().contentEquals(T.INT128)) { - if (first) { - cur_bigint = new BigInteger(startValueField.getText()); - first = false; - return cur_bigint; - } - BigInteger iterationBig = new BigInteger(iterationField.getText()); - if (plusMinusBox.getSelectedIndex() == 0) - cur_bigint = cur_bigint.add(iterationBig); - else cur_bigint = cur_bigint.subtract(iterationBig); - return cur_bigint; + private LocalDate getDateValue(boolean increment) { + + if (first) { + first = false; + currentLocalDateTime = LocalDateTime.of(startDate.getDate(), LocalTime.of(0, 0, 0)); + return currentLocalDateTime.toLocalDate(); } - if (col.getFormattedDataType().contentEquals(T.TIME)) { - if (first) { - current_local_date_time = startValueTime.getLocalTime().atDate(LocalDate.of(1970, 1, 1)); - first = false; - return current_local_date_time.toLocalTime(); - } - LocalTime iteration = iterationTime.getLocalTime(); - if (plusMinusBox.getSelectedIndex() == 0) { - current_local_date_time = current_local_date_time.plusHours(iteration.getHour()); - current_local_date_time = current_local_date_time.plusMinutes(iteration.getMinute()); - current_local_date_time = current_local_date_time.plusSeconds(iteration.getSecond()); - current_local_date_time = current_local_date_time.plusNanos(iteration.getNano()); - } else { - current_local_date_time = current_local_date_time.minusHours(iteration.getHour()); - current_local_date_time = current_local_date_time.minusMinutes(iteration.getMinute()); - current_local_date_time = current_local_date_time.minusSeconds(iteration.getSecond()); - current_local_date_time = current_local_date_time.minusNanos(iteration.getNano()); - } - return current_local_date_time.toLocalTime(); + + if (increment) { + currentLocalDateTime = currentLocalDateTime.plusYears(iterationYears.getValue()); + currentLocalDateTime = currentLocalDateTime.plusMonths(iterationMouths.getValue()); + currentLocalDateTime = currentLocalDateTime.plusDays(iterationDays.getValue()); + } else { + currentLocalDateTime = currentLocalDateTime.minusYears(iterationYears.getValue()); + currentLocalDateTime = currentLocalDateTime.minusMonths(iterationMouths.getValue()); + currentLocalDateTime = currentLocalDateTime.minusDays(iterationDays.getValue()); } - if (col.getFormattedDataType().contentEquals(T.TIME_WITH_TIMEZONE)) { - if (first) { - current_offset_date_time = startValueTimezone.getOffsetTime().atDate(LocalDate.of(1970, 1, 1)); - first = false; - return current_offset_date_time.toOffsetTime(); - } - LocalTime iteration = iterationTime.getLocalTime(); - if (plusMinusBox.getSelectedIndex() == 0) { - current_offset_date_time = current_offset_date_time.plusHours(iteration.getHour()); - current_offset_date_time = current_offset_date_time.plusMinutes(iteration.getMinute()); - current_offset_date_time = current_offset_date_time.plusSeconds(iteration.getSecond()); - current_offset_date_time = current_offset_date_time.plusNanos(iteration.getNano()); - } else { - current_offset_date_time = current_offset_date_time.minusHours(iteration.getHour()); - current_offset_date_time = current_offset_date_time.minusMinutes(iteration.getMinute()); - current_offset_date_time = current_offset_date_time.minusSeconds(iteration.getSecond()); - current_offset_date_time = current_offset_date_time.minusNanos(iteration.getNano()); - } - return current_offset_date_time.toOffsetTime(); + + return new Date(Timestamp.valueOf(currentLocalDateTime).getTime()).toLocalDate(); + } + + private LocalTime getTimeValue(boolean increment) { + + if (first) { + first = false; + currentLocalDateTime = startTime.getLocalTime().atDate(LocalDate.of(1970, 1, 1)); + return currentLocalDateTime.toLocalTime(); } - if (col.getFormattedDataType().contentEquals(T.DATE)) { - if (first) { - current_local_date_time = LocalDateTime.of(startValueDate.getDate(), LocalTime.of(0, 0, 0)); - first = false; - return current_local_date_time.toLocalDate(); - } - if (plusMinusBox.getSelectedIndex() == 0) { - current_local_date_time = current_local_date_time.plusYears(iterationDate.getYears()); - current_local_date_time = current_local_date_time.plusDays(iterationDate.getDays()); - current_local_date_time = current_local_date_time.plusMonths(iterationDate.getMouths()); - } else { - current_local_date_time = current_local_date_time.minusYears(iterationDate.getYears()); - current_local_date_time = current_local_date_time.minusDays(iterationDate.getDays()); - current_local_date_time = current_local_date_time.minusMonths(iterationDate.getMouths()); - } - return new Date(Timestamp.valueOf(current_local_date_time).getTime()); + + LocalTime iteration = iterationTime.getLocalTime(); + if (increment) { + currentLocalDateTime = currentLocalDateTime.plusHours(iteration.getHour()); + currentLocalDateTime = currentLocalDateTime.plusMinutes(iteration.getMinute()); + currentLocalDateTime = currentLocalDateTime.plusSeconds(iteration.getSecond()); + currentLocalDateTime = currentLocalDateTime.plusNanos(iteration.getNano()); + } else { + currentLocalDateTime = currentLocalDateTime.minusHours(iteration.getHour()); + currentLocalDateTime = currentLocalDateTime.minusMinutes(iteration.getMinute()); + currentLocalDateTime = currentLocalDateTime.minusSeconds(iteration.getSecond()); + currentLocalDateTime = currentLocalDateTime.minusNanos(iteration.getNano()); } - if (col.getFormattedDataType().contentEquals(T.TIMESTAMP)) { - if (first) { - current_local_date_time = startValueDateTime.getDateTime(); - first = false; - return current_local_date_time; - } - LocalTime iteration = iterationTime.getLocalTime(); - if (plusMinusBox.getSelectedIndex() == 0) { - current_local_date_time = current_local_date_time.plusYears(iterationDate.getYears()); - current_local_date_time = current_local_date_time.plusDays(iterationDate.getDays()); - current_local_date_time = current_local_date_time.plusMonths(iterationDate.getMouths()); - current_local_date_time = current_local_date_time.plusHours(iteration.getHour()); - current_local_date_time = current_local_date_time.plusMinutes(iteration.getMinute()); - current_local_date_time = current_local_date_time.plusSeconds(iteration.getSecond()); - current_local_date_time = current_local_date_time.plusNanos(iteration.getNano()); - } else { - current_local_date_time = current_local_date_time.minusYears(iterationDate.getYears()); - current_local_date_time = current_local_date_time.minusDays(iterationDate.getDays()); - current_local_date_time = current_local_date_time.minusMonths(iterationDate.getMouths()); - current_local_date_time = current_local_date_time.minusHours(iteration.getHour()); - current_local_date_time = current_local_date_time.minusMinutes(iteration.getMinute()); - current_local_date_time = current_local_date_time.minusSeconds(iteration.getSecond()); - current_local_date_time = current_local_date_time.minusNanos(iteration.getNano()); - } - return current_local_date_time; + return currentLocalDateTime.toLocalTime(); + } + + private LocalDateTime getTimestampValue(boolean increment) { + + if (first) { + first = false; + currentLocalDateTime = startTimestamp.getDateTime(); + return currentLocalDateTime; } - if (col.getFormattedDataType().contentEquals(T.TIMESTAMP_WITH_TIMEZONE)) { - if (first) { - current_offset_date_time = startValueDateTimezone.getOffsetDateTime(); - first = false; - return current_offset_date_time; - } - LocalTime iteration = iterationTime.getLocalTime(); - if (plusMinusBox.getSelectedIndex() == 0) { - current_offset_date_time = current_offset_date_time.plusYears(iterationDate.getYears()); - current_offset_date_time = current_offset_date_time.plusDays(iterationDate.getDays()); - current_offset_date_time = current_offset_date_time.plusMonths(iterationDate.getMouths()); - current_offset_date_time = current_offset_date_time.plusHours(iteration.getHour()); - current_offset_date_time = current_offset_date_time.plusMinutes(iteration.getMinute()); - current_offset_date_time = current_offset_date_time.plusSeconds(iteration.getSecond()); - current_offset_date_time = current_offset_date_time.plusNanos(iteration.getNano()); - } else { - current_offset_date_time = current_offset_date_time.minusYears(iterationDate.getYears()); - current_offset_date_time = current_offset_date_time.minusDays(iterationDate.getDays()); - current_offset_date_time = current_offset_date_time.minusMonths(iterationDate.getMouths()); - current_offset_date_time = current_offset_date_time.minusHours(iteration.getHour()); - current_offset_date_time = current_offset_date_time.minusMinutes(iteration.getMinute()); - current_offset_date_time = current_offset_date_time.minusSeconds(iteration.getSecond()); - current_offset_date_time = current_offset_date_time.minusNanos(iteration.getNano()); - } - return current_offset_date_time; + LocalTime iteration = iterationTime.getLocalTime(); + if (increment) { + currentLocalDateTime = currentLocalDateTime.plusYears(iterationYears.getValue()); + currentLocalDateTime = currentLocalDateTime.plusMonths(iterationMouths.getValue()); + currentLocalDateTime = currentLocalDateTime.plusDays(iterationDays.getValue()); + currentLocalDateTime = currentLocalDateTime.plusHours(iteration.getHour()); + currentLocalDateTime = currentLocalDateTime.plusMinutes(iteration.getMinute()); + currentLocalDateTime = currentLocalDateTime.plusSeconds(iteration.getSecond()); + currentLocalDateTime = currentLocalDateTime.plusNanos(iteration.getNano()); + } else { + currentLocalDateTime = currentLocalDateTime.minusYears(iterationYears.getValue()); + currentLocalDateTime = currentLocalDateTime.minusMonths(iterationMouths.getValue()); + currentLocalDateTime = currentLocalDateTime.minusDays(iterationDays.getValue()); + currentLocalDateTime = currentLocalDateTime.minusHours(iteration.getHour()); + currentLocalDateTime = currentLocalDateTime.minusMinutes(iteration.getMinute()); + currentLocalDateTime = currentLocalDateTime.minusSeconds(iteration.getSecond()); + currentLocalDateTime = currentLocalDateTime.minusNanos(iteration.getNano()); } - if (col.getFormattedDataType().contentEquals(T.INTEGER) || col.getFormattedDataType().contentEquals(T.SMALLINT)) { - if (first) { - current_value = Long.parseLong(startValueField.getText()); - first = false; - if (col.getFormattedDataType().contentEquals(T.SMALLINT)) - return (short) current_value; - return (int) current_value; - } - if (plusMinusBox.getSelectedIndex() == 0) - current_value += Long.parseLong(iterationField.getText()); - else current_value -= Long.parseLong(iterationField.getText()); - if (col.getFormattedDataType().contentEquals(T.SMALLINT)) - return (short) current_value; - return (int) current_value; + + return currentLocalDateTime; + } + + private OffsetTime getZonedTimeValue(boolean increment) { + + if (first) { + first = false; + currentOffsetDateTime = startZonedTime.getOffsetTime().atDate(LocalDate.of(1970, 1, 1)); + return currentOffsetDateTime.toOffsetTime(); } - if (col.getFormattedDataType().contentEquals(T.DOUBLE_PRECISION) - || col.getFormattedDataType().contentEquals(T.FLOAT) - || col.getFormattedDataType().startsWith(T.DECIMAL) - || col.getFormattedDataType().startsWith(T.NUMERIC) - || col.getFormattedDataType().startsWith(T.DECFLOAT) - ) { - if (first) { - current_double = Double.parseDouble(startValueField.getText()); - first = false; - return current_double; - } - if (plusMinusBox.getSelectedIndex() == 0) - current_double += Double.parseDouble(iterationField.getText()); - else current_double -= Double.parseDouble(iterationField.getText()); - return current_double; + + LocalTime iteration = iterationTime.getLocalTime(); + if (increment) { + currentOffsetDateTime = currentOffsetDateTime.plusHours(iteration.getHour()); + currentOffsetDateTime = currentOffsetDateTime.plusMinutes(iteration.getMinute()); + currentOffsetDateTime = currentOffsetDateTime.plusSeconds(iteration.getSecond()); + currentOffsetDateTime = currentOffsetDateTime.plusNanos(iteration.getNano()); + } else { + currentOffsetDateTime = currentOffsetDateTime.minusHours(iteration.getHour()); + currentOffsetDateTime = currentOffsetDateTime.minusMinutes(iteration.getMinute()); + currentOffsetDateTime = currentOffsetDateTime.minusSeconds(iteration.getSecond()); + currentOffsetDateTime = currentOffsetDateTime.minusNanos(iteration.getNano()); } + return currentOffsetDateTime.toOffsetTime(); + } + + private OffsetDateTime getZonedTimestampValue(boolean increment) { + + if (first) { + first = false; + currentOffsetDateTime = startZonedTimestamp.getOffsetDateTime(); + return currentOffsetDateTime; + } + + LocalTime iteration = iterationTime.getLocalTime(); + if (increment) { + currentLocalDateTime = currentLocalDateTime.plusYears(iterationYears.getValue()); + currentLocalDateTime = currentLocalDateTime.plusMonths(iterationMouths.getValue()); + currentLocalDateTime = currentLocalDateTime.plusDays(iterationDays.getValue()); + currentLocalDateTime = currentLocalDateTime.plusHours(iteration.getHour()); + currentLocalDateTime = currentLocalDateTime.plusMinutes(iteration.getMinute()); + currentLocalDateTime = currentLocalDateTime.plusSeconds(iteration.getSecond()); + currentLocalDateTime = currentLocalDateTime.plusNanos(iteration.getNano()); + } else { + currentLocalDateTime = currentLocalDateTime.minusYears(iterationYears.getValue()); + currentLocalDateTime = currentLocalDateTime.minusMonths(iterationMouths.getValue()); + currentLocalDateTime = currentLocalDateTime.minusDays(iterationDays.getValue()); + currentLocalDateTime = currentLocalDateTime.minusHours(iteration.getHour()); + currentLocalDateTime = currentLocalDateTime.minusMinutes(iteration.getMinute()); + currentLocalDateTime = currentLocalDateTime.minusSeconds(iteration.getSecond()); + currentLocalDateTime = currentLocalDateTime.minusNanos(iteration.getNano()); + } + + return currentOffsetDateTime; + } + + // --- AbstractMethodPanel impl --- + + @Override + public Object getTestDataObject() { + + String dataType = col.getFormattedDataType(); + boolean increment = incrementsCombo.getSelectedIndex() == 0; + + if (isBigint(dataType)) { + return getBigintValue(increment); + + } else if (isSmallint(dataType) || isInteger(dataType)) { + return getIntegerValue(dataType, increment); + + } else if (isDecimal(dataType) || isDecFloat(dataType)) { + return getDecimalValue(increment); + + } else if (isDate(dataType)) { + return getDateValue(increment); + + } else if (isTime(dataType)) { + return getTimeValue(increment); + + } else if (isTimestamp(dataType)) { + return getTimestampValue(increment); + + } else if (isZonedTime(dataType)) { + return getZonedTimeValue(increment); + + } else if (isZonedTimestamp(dataType)) + return getZonedTimestampValue(increment); + return null; } + } diff --git a/src/org/executequery/gui/browser/generatortestdata/methodspanels/GetFromListPanel.java b/src/org/executequery/gui/browser/generatortestdata/methodspanels/GetFromListPanel.java index 63ec1e3d1..6c1e2b2d4 100644 --- a/src/org/executequery/gui/browser/generatortestdata/methodspanels/GetFromListPanel.java +++ b/src/org/executequery/gui/browser/generatortestdata/methodspanels/GetFromListPanel.java @@ -1,11 +1,11 @@ package org.executequery.gui.browser.generatortestdata.methodspanels; import org.executequery.databaseobjects.DatabaseColumn; -import org.executequery.databaseobjects.T; +import org.executequery.gui.WidgetFactory; import org.executequery.gui.browser.GeneratorTestDataPanel; import org.executequery.gui.text.SimpleTextArea; import org.executequery.localization.Bundles; -import org.executequery.localization.LocaleManager; +import org.executequery.log.Log; import org.underworldlabs.jdbc.DataSourceException; import org.underworldlabs.swing.layouts.GridBagHelper; @@ -14,10 +14,7 @@ import javax.swing.text.BadLocationException; import javax.swing.text.PlainDocument; import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; import java.awt.event.ItemEvent; -import java.awt.event.ItemListener; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; @@ -35,220 +32,253 @@ import java.util.regex.Pattern; public class GetFromListPanel extends AbstractMethodPanel { - private SimpleTextArea textArea; + + private JTextField fileField; private JTextField delimiterField; - private JComboBox orderBox; - Object[] listObject; - JFileChooser openFileDialog; - private JComboBox sourceBox; + private JLabel labelFile; - String[] list; - private JTextField fileField; - int index; - private JButton fileSelectButton; + private SimpleTextArea textArea; + private JButton browseFileButton; + private JFileChooser openFileDialog; + private JComboBox ordersCombo; + private JComboBox sourcesCombo; + + private int index; + private String[] dataArray; + private Object[] listObject; + private final String dataType; public GetFromListPanel(DatabaseColumn col) { super(col); + this.dataType = col.getFormattedDataType(); + init(); + arrange(); } private void init() { - openFileDialog = new JFileChooser(); + textArea = new SimpleTextArea(); - textArea.getTextAreaComponent().setColumns(20); - delimiterField = new JTextField(); - delimiterField.setDocument(new JTextFieldLimit(1)); + openFileDialog = new JFileChooser(); + + delimiterField = WidgetFactory.createTextField("delimiterField"); + delimiterField.setDocument(new LimitedDocument(1)); delimiterField.setText("\\n"); - orderBox = new JComboBox(Bundles.get(GeneratorTestDataPanel.class, new String[]{ - "InOrder", "Random" - })); - sourceBox = new JComboBox(Bundles.get(GeneratorTestDataPanel.class, new String[]{ - "FromTextArea", "FromFile" - })); - sourceBox.addItemListener(new ItemListener() { - @Override - public void itemStateChanged(ItemEvent e) { - if (e.getStateChange() == ItemEvent.SELECTED) { - boolean visibling = sourceBox.getSelectedIndex() == 0; - labelFile.setVisible(!visibling); - fileField.setVisible(!visibling); - fileSelectButton.setVisible(!visibling); - textArea.setVisible(visibling); - } - } - }); - - fileField = new JTextField(); - fileSelectButton = new JButton("..."); - fileSelectButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - if (col.getFormattedDataType().contains("BLOB")) - openFileDialog.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); - if (openFileDialog.showOpenDialog(fileSelectButton) == JOptionPane.OK_OPTION) - fileField.setText(openFileDialog.getSelectedFile().getAbsolutePath()); - } - }); + ordersCombo = WidgetFactory.createComboBox("ordersCombo", bundleString(new String[]{"InOrder", "Random"})); + sourcesCombo = WidgetFactory.createComboBox("sourcesCombo", bundleString(new String[]{"FromTextArea", "FromFile"})); + sourcesCombo.addItemListener(this::sourcesComboTriggered); + fileField = WidgetFactory.createTextField("fileField"); + labelFile = new JLabel(bundleString(isBlob(dataType) ? "ChooseDirectory" : "ChooseFile")); + browseFileButton = WidgetFactory.createButton("browseFileButton", "...", e -> browseFile()); - setLayout(new GridBagLayout()); - GridBagHelper gbh = new GridBagHelper(); - GridBagConstraints gbc = new GridBagConstraints(0, 0, 1, 1, 0, 0, - GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0, 0); - gbh.setDefaults(gbc); - String labelStr = bundles("ChooseDirectory"); - if (!col.getFormattedDataType().contains("BLOB")) { - JLabel label = new JLabel(bundles("Source")); - add(label, gbh.defaults().setLabelDefault().get()); - add(sourceBox, gbh.defaults().nextCol().spanX().get()); - labelStr = bundles("ChooseFile"); - } - labelFile = new JLabel(labelStr); - if (!col.getFormattedDataType().contains("BLOB")) { + if (!isBlob(dataType)) { labelFile.setVisible(false); fileField.setVisible(false); - fileSelectButton.setVisible(false); - - } - JLabel label = new JLabel(bundles("Method")); - add(label, gbh.defaults().nextRowFirstCol().setLabelDefault().get()); - add(orderBox, gbh.defaults().nextCol().spanX().get()); - if (!col.getFormattedDataType().contains("BLOB")) { - label = new JLabel(bundles("Delimiter")); - add(label, gbh.defaults().nextRowFirstCol().setLabelDefault().get()); - add(delimiterField, gbh.defaults().nextCol().spanX().get()); + browseFileButton.setVisible(false); } - add(labelFile, gbh.defaults().nextRowFirstCol().setLabelDefault().get()); - add(fileField, gbh.defaults().nextCol().setMaxWeightX().setMaxWeightY().get()); - add(fileSelectButton, gbh.defaults().nextCol().setLabelDefault().get()); - if (!col.getFormattedDataType().contains("BLOB")) - add(textArea, gbh.defaults().nextRowFirstCol().fillBoth().spanX().spanY().get()); } - @Override + private void arrange() { + GridBagHelper gbh; - public Object getTestDataObject() { - if (first) { - fillList(); - first = false; - index = 0; + // --- main panel --- + + JPanel mainPanel = new JPanel(new GridBagLayout()); + + gbh = new GridBagHelper().anchorNorthWest().fillHorizontally(); + if (!isBlob(dataType)) { + mainPanel.add(new JLabel(bundleString("Source")), gbh.leftGap(3).topGap(3).bottomGap(5).get()); + mainPanel.add(sourcesCombo, gbh.nextCol().topGap(0).leftGap(5).setMaxWeightX().spanX().get()); + gbh.setWidth(1).setMinWeightX().nextRowFirstCol().bottomGap(0); } - if (index >= list.length) - index = 0; - if (orderBox.getSelectedIndex() == 1) { - index = new Random().nextInt(list.length); + + mainPanel.add(new JLabel(bundleString("Method")), gbh.leftGap(3).topGap(3).get()); + mainPanel.add(ordersCombo, gbh.nextCol().topGap(0).leftGap(5).setMaxWeightX().spanX().get()); + if (!isBlob(dataType)) { + mainPanel.add(new JLabel(bundleString("Delimiter")), gbh.nextRowFirstCol().setWidth(1).leftGap(3).topGap(8).setMinWeightX().get()); + mainPanel.add(delimiterField, gbh.nextCol().topGap(5).leftGap(5).setMaxWeightX().spanX().get()); } - index++; - return listObject[index - 1]; + + mainPanel.add(labelFile, gbh.nextRowFirstCol().setWidth(1).leftGap(3).topGap(8).setMinWeightX().get()); + mainPanel.add(fileField, gbh.nextCol().topGap(5).leftGap(5).setMaxWeightX().get()); + mainPanel.add(browseFileButton, gbh.nextCol().setMinWeightX().get()); + + gbh.nextRowFirstCol().fillBoth().spanX().spanY(); + if (!isBlob(dataType)) + mainPanel.add(textArea, gbh.get()); + mainPanel.add(new JPanel(), gbh.get()); + + // --- base --- + + setLayout(new GridBagLayout()); + gbh = new GridBagHelper().topGap(5).fillBoth().spanX().spanY(); + add(mainPanel, gbh.get()); + } + + private void browseFile() { + openFileDialog.setFileSelectionMode(isBlob(dataType) ? JFileChooser.DIRECTORIES_ONLY : JFileChooser.FILES_ONLY); + if (openFileDialog.showOpenDialog(browseFileButton) == JOptionPane.OK_OPTION) + fileField.setText(openFileDialog.getSelectedFile().getAbsolutePath()); } - private void fillList() { - if (col.getFormattedDataType().contains("BLOB")) { - File directory = new File(fileField.getText()); + private void sourcesComboTriggered(ItemEvent e) { + + if (e.getStateChange() != ItemEvent.SELECTED) + return; + + boolean visible = sourcesCombo.getSelectedIndex() == 0; + browseFileButton.setVisible(!visible); + labelFile.setVisible(!visible); + fileField.setVisible(!visible); + textArea.setVisible(visible); + } + + private void initDataList() { + String fileName = fileField.getText().trim(); + + if (isBlob(dataType)) { + + File directory = new File(fileName); if (!directory.exists()) throw new DataSourceException("The selected directory does not exist."); + File[] files = directory.listFiles(); - list = new String[files.length]; - for (int i = 0; i < list.length; i++) { - list[i] = files[i].getAbsolutePath(); + if (files != null) { + dataArray = new String[files.length]; + for (int i = 0; i < dataArray.length; i++) + dataArray[i] = files[i].getAbsolutePath(); } + } else { + String delimiter = delimiterField.getText(); if (!delimiter.startsWith("\\")) delimiter = Pattern.quote(delimiter); - if (sourceBox.getSelectedIndex() == 0) - list = textArea.getTextAreaComponent().getText().trim().split(delimiter); - else { + + if (sourcesCombo.getSelectedIndex() == 0) { + dataArray = textArea.getTextAreaComponent().getText().trim().split(delimiter); + + } else { + + File file = new File(fileName); + if (!file.exists()) + throw new DataSourceException("The selected file does not exist."); + try { - File file = new File(fileField.getText()); - if (!file.exists()) - throw new DataSourceException("The selected file does not exist."); - String s = new String(Files.readAllBytes(Paths.get(fileField.getText()))); - list = s.trim().split(delimiter); + String fileData = new String(Files.readAllBytes(Paths.get(fileName))); + dataArray = fileData.trim().split(delimiter); + } catch (IOException e) { - e.printStackTrace(); + Log.error(e.getMessage(), e); } } } - listObject = new Object[list.length]; - for (int i = 0; i < list.length; i++) { - listObject[i] = objectFromString(list[i]); - } + + listObject = new Object[dataArray.length]; + for (int i = 0; i < dataArray.length; i++) + listObject[i] = objectFromString(dataArray[i]); } - Object objectFromString(String str) { - if (col.getFormattedDataType().contentEquals("BIGINT") - || col.getFormattedDataType().contentEquals(T.INT128)) { + private Object objectFromString(String str) { + + if (isBigint(dataType)) { return new BigInteger(str); - } - if (col.getFormattedDataType().contentEquals("INTEGER")) { + + } else if (isInteger(dataType)) { return Integer.parseInt(str); - } - if (col.getFormattedDataType().contentEquals("SMALLINT")) { + + } else if (isSmallint(dataType)) { return Short.parseShort(str); - } - if (col.getFormattedDataType().contentEquals("TIME")) { - return Time.valueOf(str); - } - if (col.getFormattedDataType().contentEquals(T.TIME_WITH_TIMEZONE)) { - return OffsetTime.parse(str); - } - if (col.getFormattedDataType().contentEquals("DATE")) { - return Date.valueOf(str); - } - if (col.getFormattedDataType().contentEquals("TIMESTAMP")) { - return Timestamp.valueOf(str); - } - if (col.getFormattedDataType().contentEquals(T.TIMESTAMP_WITH_TIMEZONE)) { - return OffsetDateTime.parse(str); - } - if (col.getFormattedDataType().contentEquals("DOUBLE PRECISION") - || col.getFormattedDataType().contentEquals("FLOAT") - || col.getFormattedDataType().startsWith("DECIMAL") - || col.getFormattedDataType().startsWith("NUMERIC")) { + + } else if (isDecimal(dataType)) { return Double.valueOf(str); - } - if (col.getFormattedDataType().startsWith(T.DECFLOAT)) { + + } else if (isDecFloat(dataType)) { return new BigDecimal(str); - } - if (col.getFormattedDataType().contains("CHAR")) { + + } else if (isChar(dataType)) { return str; - } - if (col.getFormattedDataType().contains("BLOB")) { + + } else if (isDate(dataType)) { + return Date.valueOf(str); + + } else if (isTime(dataType)) { + return Time.valueOf(str); + + } else if (isTimestamp(dataType)) { + return Timestamp.valueOf(str); + + } else if (isZonedTime(dataType)) { + return OffsetTime.parse(str); + + } else if (isZonedTimestamp(dataType)) { + return OffsetDateTime.parse(str); + + } else if (isBlob(dataType)) { try { return new FileInputStream(str); + } catch (FileNotFoundException e) { - e.printStackTrace(); + Log.error(e.getMessage(), e); } - } - if (col.getFormattedDataType().contentEquals("BOOLEAN")) { + + } else if (isBoolean(dataType)) return Boolean.valueOf(str); - } + return null; } - class JTextFieldLimit extends PlainDocument { - private final int limit; + private static String[] bundleString(String[] keys) { + return Bundles.get(GeneratorTestDataPanel.class, keys); + } - JTextFieldLimit(int limit) { - super(); - this.limit = limit; + // --- AbstractMethodPanel impl --- + + @Override + public Object getTestDataObject() { + + if (first) { + initDataList(); + first = false; + index = 0; } - JTextFieldLimit(int limit, boolean upper) { + if (index >= dataArray.length) + index = 0; + + if (ordersCombo.getSelectedIndex() == 1) + index = new Random().nextInt(dataArray.length); + + index++; + return listObject[index - 1]; + } + + // --- + + private static class LimitedDocument extends PlainDocument { + private final int limit; + + public LimitedDocument(int limit) { super(); this.limit = limit; } + @Override public void insertString(int offset, String str, AttributeSet attr) throws BadLocationException { if (str == null) return; - if ((getLength() + str.length()) <= limit || getText(0, 1).startsWith("\\") || getLength() == 0 && str.startsWith("\\")) { + if ((getLength() + str.length()) <= limit + || getText(0, 1).startsWith("\\") + || getLength() == 0 && str.startsWith("\\") + ) { super.insertString(offset, str, attr); } } - } + + } // LimitedDocument class + } diff --git a/src/org/executequery/gui/browser/generatortestdata/methodspanels/GetFromOtherTablePanel.java b/src/org/executequery/gui/browser/generatortestdata/methodspanels/GetFromOtherTablePanel.java index 966ea5f9c..594be5d87 100644 --- a/src/org/executequery/gui/browser/generatortestdata/methodspanels/GetFromOtherTablePanel.java +++ b/src/org/executequery/gui/browser/generatortestdata/methodspanels/GetFromOtherTablePanel.java @@ -4,8 +4,10 @@ import org.executequery.databasemediators.spi.DefaultStatementExecutor; import org.executequery.databaseobjects.DatabaseColumn; import org.executequery.databaseobjects.DatabaseHost; -import org.executequery.databaseobjects.NamedObject; +import org.executequery.gui.WidgetFactory; import org.executequery.gui.browser.ConnectionsTreePanel; +import org.executequery.gui.browser.nodes.DatabaseObjectNode; +import org.executequery.log.Log; import org.executequery.sql.SqlStatementResult; import org.underworldlabs.swing.DynamicComboBoxModel; import org.underworldlabs.swing.NumberTextField; @@ -14,125 +16,156 @@ import javax.swing.*; import java.awt.*; import java.awt.event.ItemEvent; -import java.awt.event.ItemListener; import java.sql.ResultSet; import java.sql.SQLException; -import java.util.ArrayList; +import java.util.*; import java.util.List; -import java.util.Random; -import java.util.Vector; public class GetFromOtherTablePanel extends AbstractMethodPanel { - NumberTextField countRowsField; - DefaultStatementExecutor executor; - private JComboBox tableBox; - private JComboBox colBox; - private DynamicComboBoxModel tableBoxModel; - private DynamicComboBoxModel colBoxModel; - Random random; - private List objList; + + private JComboBox tablesCombo; + private JComboBox columnsCombo; + private NumberTextField recordsCountField; + private JCheckBox useFirstNRecordsCheck; + private DynamicComboBoxModel columnsModel; + + private final Random random; + private final List objList; + private final DefaultStatementExecutor executor; + + public GetFromOtherTablePanel(DatabaseColumn col, DefaultStatementExecutor executor) { + super(col); + this.random = new Random(); + this.objList = new ArrayList<>(); + this.executor = new DefaultStatementExecutor(executor.getDatabaseConnection()); + + init(); + } private void init() { - setLayout(new GridBagLayout()); - tableBoxModel = new DynamicComboBoxModel(); - tableBoxModel.setElements(fillTables()); - colBoxModel = new DynamicComboBoxModel(); - tableBox = new JComboBox(tableBoxModel); - tableBox.addItemListener(new ItemListener() { - @Override - public void itemStateChanged(ItemEvent e) { - if (e.getStateChange() == ItemEvent.SELECTED) { - colBoxModel.setElements(fillCols()); - } - } + + JLabel recordsCountLabel = new JLabel(bundleString("CountRecords")); + recordsCountLabel.setEnabled(false); + + columnsModel = new DynamicComboBoxModel(); + columnsCombo = WidgetFactory.createComboBox("columnsCombo", columnsModel); + tablesCombo = WidgetFactory.createComboBox("tablesCombo", getTablesVector()); + + useFirstNRecordsCheck = WidgetFactory.createCheckBox("useFirstNRecordsCheck", bundleString("useFirstNRecordsCheck")); + useFirstNRecordsCheck.addActionListener(e -> { + boolean enabled = useFirstNRecordsCheck.isSelected(); + recordsCountLabel.setEnabled(enabled); + recordsCountField.setEnabled(enabled); }); - colBox = new JComboBox(colBoxModel); - countRowsField = new NumberTextField(false); - countRowsField.setValue(1); - GridBagHelper gbh = new GridBagHelper(); - GridBagConstraints gbc = new GridBagConstraints(0, 0, 1, 1, 0, 0, - GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0, 0); - gbh.setDefaults(gbc); - JLabel label = new JLabel(bundles("TableView")); + recordsCountField = WidgetFactory.createNumberTextField("recordsCountField", "10"); + recordsCountField.setEnableNegativeNumbers(false); + recordsCountField.setEnabled(false); - add(label, gbh.defaults().setLabelDefault().get()); + // --- arrange --- - add(tableBox, gbh.defaults().nextCol().spanX().get()); + JPanel mainPanel = new JPanel(new GridBagLayout()); - label = new JLabel(bundles("Column")); + GridBagHelper gbh = new GridBagHelper().anchorNorthWest().fillHorizontally(); + mainPanel.add(new JLabel(bundleString("TableView")), gbh.leftGap(3).topGap(3).get()); + mainPanel.add(tablesCombo, gbh.nextCol().topGap(0).leftGap(5).setMaxWeightX().get()); + mainPanel.add(new JLabel(bundleString("Column")), gbh.nextRowFirstCol().leftGap(3).topGap(8).setMinWeightX().get()); + mainPanel.add(columnsCombo, gbh.nextCol().topGap(5).leftGap(5).setMaxWeightX().get()); + mainPanel.add(useFirstNRecordsCheck, gbh.nextRowFirstCol().leftGap(0).spanX().get()); + mainPanel.add(recordsCountLabel, gbh.nextRowFirstCol().setWidth(1).leftGap(3).topGap(8).setMinWeightX().get()); + mainPanel.add(recordsCountField, gbh.nextCol().topGap(5).leftGap(5).setMaxWeightX().get()); + mainPanel.add(new JPanel(), gbh.nextRowFirstCol().fillBoth().spanX().spanY().get()); - add(label, gbh.defaults().nextRowFirstCol().setLabelDefault().get()); + setLayout(new GridBagLayout()); + gbh = new GridBagHelper().setInsets(0, 5, 0, 0).fillBoth().spanX().spanY(); + add(mainPanel, gbh.get()); - add(colBox, gbh.defaults().nextCol().spanX().get()); + // --- - label = new JLabel(bundles("CountRecords")); + tablesCombo.addItemListener(this::tablesComboTriggered); + columnsModel.setElements(getColumnsList()); + } - add(label, gbh.defaults().nextRowFirstCol().setLabelDefault().get()); + private Vector getTablesVector() { + String query = "SELECT RDB$RELATION_NAME\n" + + "FROM RDB$RELATIONS\n" + + "WHERE (RDB$SYSTEM_FLAG IS NULL OR RDB$SYSTEM_FLAG = 0)\n" + + "AND RDB$RELATION_TYPE = 0 OR RDB$RELATION_TYPE = 1 OR RDB$RELATION_TYPE = 2\n" + + "ORDER BY RDB$RELATION_NAME"; - add(countRowsField, gbh.defaults().nextCol().spanX().spanY().get()); + Vector tables = new Vector<>(); + try { + SqlStatementResult result = executor.getResultSet(query); + ResultSet rs = result.getResultSet(); + while (rs.next()) + tables.add(rs.getString(1).trim()); + + } catch (SQLException | NullPointerException e) { + Log.error(e.getMessage(), e); - colBoxModel.setElements(fillCols()); + } finally { + executor.releaseResources(); + } + return tables; } - public GetFromOtherTablePanel(DatabaseColumn col, DefaultStatementExecutor executor) { - super(col); - this.executor = new DefaultStatementExecutor(executor.getDatabaseConnection()); - init(); + private List getColumnsList() { + + JPanel tabComponent = GUIUtilities.getDockedTabComponent(ConnectionsTreePanel.PROPERTY_KEY); + if (tabComponent instanceof ConnectionsTreePanel) { + DatabaseObjectNode objectNode = ((ConnectionsTreePanel) tabComponent).getHostNode(executor.getDatabaseConnection()); + if (objectNode != null) { + DatabaseHost host = (DatabaseHost) objectNode.getDatabaseObject(); + return host.getColumns((String) tablesCombo.getSelectedItem()); + } + } + + return new ArrayList<>(); + } + + private String getQuery() { + Object selectedColumn = columnsCombo.getSelectedItem(); + + String tableName = (String) tablesCombo.getSelectedItem(); + String columnName = selectedColumn instanceof DatabaseColumn ? + ((DatabaseColumn) selectedColumn).getName() : + (String) columnsCombo.getModel().getElementAt(columnsCombo.getSelectedIndex()); + + return useFirstNRecordsCheck.isSelected() ? + String.format("SELECT FIRST %d %s FROM %s", recordsCountField.getValue(), columnName, tableName) : + String.format("SELECT %s FROM %s", columnName, tableName); + } + + private void tablesComboTriggered(ItemEvent e) { + if (e.getStateChange() == ItemEvent.SELECTED) + columnsModel.setElements(getColumnsList()); } + // --- AbstractMethodPanel impl --- + @Override public Object getTestDataObject() { + if (first) { - first = false; - objList = new ArrayList<>(); - String query = "Select first " + countRowsField.getStringValue() + " \n" + ((DatabaseColumn) colBox.getSelectedItem()).getName() + " from " + tableBox.getSelectedItem(); try { + String query = getQuery(); ResultSet rs = executor.getResultSet(query).getResultSet(); - random = new Random(); - int count = countRowsField.getValue(); - for (int i = 0; i < count && rs.next(); i++) { + while (rs.next()) objList.add(rs.getObject(1)); - } + } catch (SQLException e) { - e.printStackTrace(); + Log.error(e.getMessage(), e); return null; + } finally { executor.releaseResources(); } - } - int rand = random.nextInt(objList.size()); - return objList.get(rand); - } - private Vector fillTables() { - Vector tables = new Vector<>(); - SqlStatementResult result = null; - try { - String query = "select rdb$relation_name\n" + - "from rdb$relations\n" + - "where \n" + - "(rdb$system_flag is null or rdb$system_flag = 0) and rdb$relation_type=0 or rdb$relation_type=1 or rdb$relation_type=2\n" + - "order by rdb$relation_name"; - result = executor.getResultSet(query); - ResultSet rs = result.getResultSet(); - while (rs.next()) { - tables.add(rs.getString(1).trim()); - } - } catch (SQLException e) { - e.printStackTrace(); - } catch (NullPointerException e) { - e.printStackTrace(); - } finally { - executor.releaseResources(); + first = false; } - return tables; - } - private List fillCols() { - NamedObject object = ((ConnectionsTreePanel) GUIUtilities.getDockedTabComponent(ConnectionsTreePanel.PROPERTY_KEY)).getHostNode(executor.getDatabaseConnection()).getDatabaseObject(); - DatabaseHost host = (DatabaseHost) object; - return host.getColumns( (String) tableBox.getSelectedItem()); + return objList.get(random.nextInt(objList.size())); } + } diff --git a/src/org/executequery/gui/browser/generatortestdata/methodspanels/RandomMethodPanel.java b/src/org/executequery/gui/browser/generatortestdata/methodspanels/RandomMethodPanel.java index fce6a33b9..0839e5119 100644 --- a/src/org/executequery/gui/browser/generatortestdata/methodspanels/RandomMethodPanel.java +++ b/src/org/executequery/gui/browser/generatortestdata/methodspanels/RandomMethodPanel.java @@ -1,9 +1,12 @@ package org.executequery.gui.browser.generatortestdata.methodspanels; import com.github.lgooddatepicker.components.DatePicker; +import org.apache.commons.lang.RandomStringUtils; import org.executequery.databaseobjects.DatabaseColumn; import org.executequery.databaseobjects.T; +import org.executequery.gui.WidgetFactory; import org.executequery.gui.text.SimpleTextArea; +import org.executequery.log.Log; import org.underworldlabs.jdbc.DataSourceException; import org.underworldlabs.swing.*; import org.underworldlabs.swing.celleditor.picker.TimestampPicker; @@ -11,34 +14,47 @@ import org.underworldlabs.swing.celleditor.picker.TimePicker; import org.underworldlabs.swing.celleditor.picker.ZonedTimePicker; import org.underworldlabs.swing.layouts.GridBagHelper; +import org.underworldlabs.util.FileUtils; +import org.underworldlabs.util.MiscUtils; import javax.swing.*; import java.awt.*; import java.math.BigInteger; +import java.nio.charset.Charset; import java.time.*; -import java.util.Random; +import java.util.*; +import java.util.List; public class RandomMethodPanel extends AbstractMethodPanel { + + private JCheckBox useNullCheck; private JPanel settingsPanel; - private JTextField maxField; - private JTextField minField; + + private NumberTextField maxField; + private NumberTextField minField; + private NumberTextField symbolsAfterComma; + + private DatePicker maxDate; + private DatePicker minDate; + private TimePicker minTime; private TimePicker maxTime; + private ZonedTimePicker minTimezone; private ZonedTimePicker maxTimezone; + private TimestampPicker minDateTime; private TimestampPicker maxDateTime; + private ZonedTimestampPicker minDateTimezone; private ZonedTimestampPicker maxDateTimezone; - private DatePicker maxDate; - private DatePicker minDate; - private NumberTextField countSymbolsAfterComma; - private JCheckBox useOnlyThisSymbolsBox; - private SimpleTextArea useOnlyThisSymbolsField; - //private JScrollPane scrollSymbols; + + private JComboBox charsetCombo; + private JCheckBox useSelectedCharsetCheck; + private SimpleTextArea useSelectedCharsetField; + private JTextField maxByteField; private JTextField minByteField; - private JCheckBox nullBox; public RandomMethodPanel(DatabaseColumn col) { super(col); @@ -46,444 +62,500 @@ public RandomMethodPanel(DatabaseColumn col) { } private void init() { - countSymbolsAfterComma = new NumberTextField(); - countSymbolsAfterComma.setText("1"); - nullBox = new JCheckBox(bundles("UseNull")); + settingsPanel = new JPanel(); settingsPanel.setLayout(new GridBagLayout()); - GridBagHelper gbh = new GridBagHelper(); - GridBagConstraints gbc = new GridBagConstraints(0, 0, 1, 1, 0, 0, - GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0, 0); - gbh.setDefaults(gbc); - - if (col.getFormattedDataType().contentEquals(T.BIGINT) - || col.getFormattedDataType().contentEquals(T.INT128) - || col.getFormattedDataType().contentEquals(T.INTEGER) - || col.getFormattedDataType().contentEquals(T.SMALLINT) - || col.getFormattedDataType().contentEquals(T.DOUBLE_PRECISION) - || col.getFormattedDataType().contentEquals(T.FLOAT) - || col.getFormattedDataType().startsWith(T.DECIMAL) - || col.getFormattedDataType().startsWith(T.NUMERIC) - || col.getFormattedDataType().startsWith(T.DECFLOAT) - ) { - - if (col.getFormattedDataType().contentEquals(T.BIGINT) - || col.getFormattedDataType().contentEquals(T.INT128) - || col.getFormattedDataType().contentEquals(T.DOUBLE_PRECISION) - || col.getFormattedDataType().contentEquals(T.FLOAT) - || col.getFormattedDataType().startsWith(T.DECIMAL) - || col.getFormattedDataType().startsWith(T.NUMERIC) - || col.getFormattedDataType().startsWith(T.DECFLOAT) - ) { - maxField = new JTextField(); - minField = new JTextField(); - if (col.getFormattedDataType().contentEquals("BIGINT")) { - maxField.setText("9223372036854775807"); - minField.setText("-9223372036854775808"); - } else { - maxField.setText("1"); - minField.setText("0"); - } - } else { - maxField = new NumberTextField(); - minField = new NumberTextField(); - if (col.getFormattedDataType().contentEquals(T.INTEGER)) { - maxField.setText("" + Integer.MAX_VALUE); - minField.setText("" + Integer.MIN_VALUE); - } else { - maxField.setText("" + 32767); - minField.setText("" + (-32768)); - } - } + useNullCheck = WidgetFactory.createCheckBox("useNullCheck", bundleString("UseNull")); + // --- init settings panel --- - JLabel label = new JLabel(bundles("Min")); - settingsPanel.add(label, gbh.defaults().setLabelDefault().get()); - settingsPanel.add(minField, gbh.defaults().nextCol().setMaxWeightX().get()); - - label = new JLabel(bundles("Max")); - settingsPanel.add(label, gbh.defaults().nextCol().setLabelDefault().get()); - settingsPanel.add(maxField, gbh.defaults().nextCol().setMaxWeightX().get()); - if (col.getFormattedDataType().contentEquals(T.DOUBLE_PRECISION) - || col.getFormattedDataType().contentEquals(T.FLOAT) - || col.getFormattedDataType().startsWith(T.DECIMAL) - || col.getFormattedDataType().startsWith(T.NUMERIC) - || col.getFormattedDataType().startsWith(T.DECFLOAT) - ) { - label = new JLabel(bundles("CountDigitsAfterComma")); - settingsPanel.add(label, gbh.defaults().nextRowFirstCol().setLabelDefault().get()); - settingsPanel.add(countSymbolsAfterComma, gbh.defaults().nextCol().spanX().get()); - } + String dataType = col.getFormattedDataType(); + if (isNumeric(dataType)) { + initNumericPanel(dataType); - } + } else if (isChar(dataType)) { + initCharPanel(); - if (col.getFormattedDataType().contentEquals(T.TIME)) { + } else if (isDate(dataType)) { + initDatePanel(); - minTime = new TimePicker(); - minTime.setVisibleNullCheck(false); - minTime.setTime(LocalTime.MIN); + } else if (isTime(dataType)) { + initTimePanel(); - maxTime = new TimePicker(); - maxTime.setVisibleNullCheck(false); - maxTime.setTime(LocalTime.MAX); + } else if (isTimestamp(dataType)) { + initTimestampPanel(); - settingsPanel.add(new JLabel(bundles("Min")), gbh.defaults().setLabelDefault().get()); - settingsPanel.add(minTime, gbh.defaults().nextCol().setMaxWeightX().get()); - settingsPanel.add(new JLabel(bundles("Max")), gbh.defaults().nextCol().setLabelDefault().get()); - settingsPanel.add(maxTime, gbh.defaults().nextCol().setMaxWeightX().get()); - } + } else if (isZonedTime(dataType)) { + initZonedTimePanel(); + + } else if (isZonedTimestamp(dataType)) { + initZonedTimestampPanel(); + + } else if (isBlob(dataType)) + initBlobPanel(); - if (col.getFormattedDataType().contentEquals(T.TIME_WITH_TIMEZONE)) { + // --- base --- - minTimezone = new ZonedTimePicker(); - minTimezone.setVisibleNullCheck(false); - minTimezone.setTime(LocalTime.MIN); + setLayout(new GridBagLayout()); + + GridBagHelper gbh = new GridBagHelper().anchorNorthWest().fillHorizontally(); + add(useNullCheck, gbh.spanX().get()); + add(settingsPanel, gbh.nextRowFirstCol().topGap(5).fillBoth().spanY().get()); + } + + private void initNumericPanel(String dataType) { + + maxField = WidgetFactory.createNumberTextField("maxField"); + minField = WidgetFactory.createNumberTextField("minField"); + + if (isInteger(dataType)) { + maxField.setText("" + Integer.MAX_VALUE); + minField.setText("" + Integer.MIN_VALUE); - maxTimezone = new ZonedTimePicker(); - maxTimezone.setVisibleNullCheck(false); - maxTimezone.setTime(LocalTime.MAX); + } else if (isSmallint(dataType)) { + maxField.setText("" + 32767); + minField.setText("" + (-32768)); - settingsPanel.add(new JLabel(bundles("Min")), gbh.defaults().setLabelDefault().get()); - settingsPanel.add(minTimezone, gbh.defaults().nextCol().setMaxWeightX().get()); - settingsPanel.add(new JLabel(bundles("Max")), gbh.defaults().nextCol().setLabelDefault().get()); - settingsPanel.add(maxTimezone, gbh.defaults().nextCol().setMaxWeightX().get()); + } else if (isBigint(dataType)) { + maxField.setText("9223372036854775807"); + minField.setText("-9223372036854775808"); + + } else { + maxField.setText("1"); + minField.setText("0"); } - if (col.getFormattedDataType().contentEquals(T.DATE)) { - minDate = new DatePicker(); - minDate.setDate(LocalDate.of(0, 1, 1)); - maxDate = new DatePicker(); - maxDate.setDate(LocalDate.of(9999, 1, 1)); - JLabel label = new JLabel(bundles("Min")); - settingsPanel.add(label, gbh.defaults().setLabelDefault().get()); - settingsPanel.add(minDate, gbh.defaults().nextCol().setMaxWeightX().get()); - label = new JLabel(bundles("Max")); - settingsPanel.add(label, gbh.defaults().nextCol().setLabelDefault().get()); - settingsPanel.add(maxDate, gbh.defaults().nextCol().setMaxWeightX().get()); + if (isDecimal(dataType) || isDecFloat(dataType)) { + symbolsAfterComma = WidgetFactory.createNumberTextField("symbolsAfterComma"); + symbolsAfterComma.setText("1"); } - if (col.getFormattedDataType().contentEquals(T.TIMESTAMP)) { + // --- arrange --- - minDateTime = new TimestampPicker(); - minDateTime.setVisibleNullCheck(false); - minDateTime.setDateTime(LocalDateTime.of(LocalDate.of(0, 1, 1), LocalTime.of(0, 0, 0))); + GridBagHelper gbh = new GridBagHelper().anchorNorthWest().fillHorizontally(); + settingsPanel.add(new JLabel(bundleString("Min")), gbh.leftGap(3).topGap(3).get()); + settingsPanel.add(minField, gbh.nextCol().topGap(0).leftGap(5).setMaxWeightX().get()); + settingsPanel.add(new JLabel(bundleString("Max")), gbh.nextRowFirstCol().leftGap(3).topGap(8).setMinWeightX().get()); + settingsPanel.add(maxField, gbh.nextCol().topGap(5).leftGap(5).setMaxWeightX().get()); + if (isDecimal(dataType) || isDecFloat(dataType)) { + settingsPanel.add(new JLabel(bundleString("CountDigitsAfterComma")), gbh.nextRowFirstCol().leftGap(3).topGap(8).setMinWeightX().get()); + settingsPanel.add(symbolsAfterComma, gbh.nextCol().topGap(5).leftGap(5).setMaxWeightX().get()); + } + settingsPanel.add(new JPanel(), gbh.nextRowFirstCol().fillBoth().spanX().spanY().get()); + } - maxDateTime = new TimestampPicker(); - maxDateTime.setVisibleNullCheck(false); - maxDateTime.setDateTime(LocalDateTime.of(LocalDate.of(9999, 12, 31), LocalTime.of(23, 59, 59))); + private void initCharPanel() { + + maxField = WidgetFactory.createNumberTextField("maxField"); + maxField.setText("" + col.getColumnSize()); + maxField.setEnableNegativeNumbers(false); + + minField = WidgetFactory.createNumberTextField("minField"); + minField.setEnableNegativeNumbers(false); + minField.setText("0"); + + JLabel charsetLabel = new JLabel(bundleString("Charset")); + charsetCombo = WidgetFactory.createComboBox("charsetCombo", getLoadCharsets().toArray()); + + useSelectedCharsetField = new SimpleTextArea(); + useSelectedCharsetCheck = WidgetFactory.createCheckBox("useSelectedCharsetCheck", bundleString("UseOnlyThisSymbols")); + useSelectedCharsetCheck.addActionListener(e -> { + boolean enabled = !useSelectedCharsetCheck.isSelected(); + charsetLabel.setEnabled(enabled); + charsetCombo.setEnabled(enabled); + }); + + // --- arrange --- + + GridBagHelper gbh = new GridBagHelper().anchorNorthWest().fillHorizontally(); + settingsPanel.add(new JLabel(bundleString("MinLength")), gbh.leftGap(3).topGap(3).get()); + settingsPanel.add(minField, gbh.nextCol().topGap(0).leftGap(5).setMaxWeightX().get()); + settingsPanel.add(new JLabel(bundleString("MaxLength")), gbh.nextRowFirstCol().leftGap(3).topGap(8).setMinWeightX().get()); + settingsPanel.add(maxField, gbh.nextCol().topGap(5).leftGap(5).setMaxWeightX().get()); + settingsPanel.add(charsetLabel, gbh.nextRowFirstCol().leftGap(3).topGap(8).setMinWeightX().get()); + settingsPanel.add(charsetCombo, gbh.nextCol().topGap(5).leftGap(5).setMaxWeightX().get()); + settingsPanel.add(useSelectedCharsetCheck, gbh.nextRowFirstCol().leftGap(0).spanX().get()); + settingsPanel.add(useSelectedCharsetField, gbh.nextRowFirstCol().setMaxWeightY().fillBoth().spanY().get()); + } - settingsPanel.add(new JLabel(bundles("Min")), gbh.defaults().setLabelDefault().get()); - settingsPanel.add(minDateTime, gbh.defaults().nextCol().spanX().get()); - settingsPanel.add(new JLabel(bundles("Max")), gbh.defaults().nextRowFirstCol().setLabelDefault().get()); - settingsPanel.add(maxDateTime, gbh.defaults().nextCol().spanX().get()); - } + private void initDatePanel() { - if (col.getFormattedDataType().contentEquals(T.TIMESTAMP_WITH_TIMEZONE)) { + minDate = new DatePicker(); + minDate.setDate(LocalDate.of(0, 1, 1)); - minDateTimezone = new ZonedTimestampPicker(); - minDateTimezone.setVisibleNullCheck(false); - minDateTimezone.setDateTime(LocalDateTime.of(LocalDate.of(0, 1, 1), LocalTime.of(0, 0, 0))); + maxDate = new DatePicker(); + maxDate.setDate(LocalDate.of(9999, 1, 1)); - maxDateTimezone = new ZonedTimestampPicker(); - maxDateTimezone.setVisibleNullCheck(false); - maxDateTimezone.setDateTime(LocalDateTime.of(LocalDate.of(9999, 12, 31), LocalTime.of(23, 59, 59))); + // --- arrange --- - settingsPanel.add(new JLabel(bundles("Min")), gbh.defaults().setLabelDefault().get()); - settingsPanel.add(minDateTimezone, gbh.defaults().nextCol().spanX().get()); - settingsPanel.add(new JLabel(bundles("Max")), gbh.defaults().nextRowFirstCol().setLabelDefault().get()); - settingsPanel.add(maxDateTimezone, gbh.defaults().nextCol().spanX().get()); - } + GridBagHelper gbh = new GridBagHelper().anchorNorthWest().fillHorizontally(); + settingsPanel.add(new JLabel(bundleString("Min")), gbh.leftGap(3).topGap(3).get()); + settingsPanel.add(minDate, gbh.nextCol().topGap(0).leftGap(5).setMaxWeightX().get()); + settingsPanel.add(new JLabel(bundleString("Max")), gbh.nextRowFirstCol().leftGap(3).topGap(8).setMinWeightX().get()); + settingsPanel.add(maxDate, gbh.nextCol().topGap(5).leftGap(5).setMaxWeightX().get()); + settingsPanel.add(new JPanel(), gbh.nextRowFirstCol().fillBoth().spanX().spanY().get()); + } - if (col.getFormattedDataType().contains(T.CHAR)) { - maxField = new NumberTextField(false); - minField = new NumberTextField(false); - maxField.setText("" + col.getColumnSize()); - minField.setText("0"); - useOnlyThisSymbolsBox = new JCheckBox(bundles("UseOnlyThisSymbols")); - useOnlyThisSymbolsField = new SimpleTextArea(); + private void initTimePanel() { - //scrollSymbols = new JScrollPane(useOnlyThisSymbolsField); - //scrollSymbols.setVerticalScrollBar(scrollSymbols.createVerticalScrollBar()); + minTime = new TimePicker(); + minTime.setTime(LocalTime.MIN); + minTime.setVisibleNullCheck(false); - JLabel label = new JLabel(bundles("MinLength")); + maxTime = new TimePicker(); + maxTime.setTime(LocalTime.MAX); + maxTime.setVisibleNullCheck(false); - settingsPanel.add(label, gbh.defaults().setLabelDefault().get()); - settingsPanel.add(minField, gbh.defaults().nextCol().setMaxWeightX().get()); - label = new JLabel(bundles("MaxLength")); - settingsPanel.add(label, gbh.defaults().nextCol().setLabelDefault().get()); - settingsPanel.add(maxField, gbh.defaults().nextCol().setMaxWeightX().get()); - settingsPanel.add(useOnlyThisSymbolsBox, gbh.defaults().nextRowFirstCol().spanX().get()); - settingsPanel.add(useOnlyThisSymbolsField, gbh.defaults().nextRowFirstCol().fillBoth().spanX().spanY().get()); - } - if (col.getFormattedDataType().contains(T.BLOB)) { - maxField = new NumberTextField(false); - minField = new NumberTextField(false); - maxField.setText("" + col.getColumnSize()); - minField.setText("0"); - maxByteField = new NumberTextField(); - minByteField = new NumberTextField(); - maxByteField.setText("255"); - minByteField.setText("0"); + // --- arrange --- + GridBagHelper gbh = new GridBagHelper().anchorNorthWest().fillHorizontally(); + settingsPanel.add(new JLabel(bundleString("Min")), gbh.leftGap(3).topGap(3).get()); + settingsPanel.add(minTime, gbh.nextCol().topGap(0).leftGap(5).setMaxWeightX().get()); + settingsPanel.add(new JLabel(bundleString("Max")), gbh.nextRowFirstCol().leftGap(3).topGap(8).setMinWeightX().get()); + settingsPanel.add(maxTime, gbh.nextCol().topGap(5).leftGap(5).setMaxWeightX().get()); + settingsPanel.add(new JPanel(), gbh.nextRowFirstCol().fillBoth().spanX().spanY().get()); + } - JLabel label = new JLabel(bundles("MinLength")); + private void initTimestampPanel() { - settingsPanel.add(label, gbh.defaults().setLabelDefault().get()); - settingsPanel.add(minField, gbh.defaults().nextCol().setMaxWeightX().get()); - label = new JLabel(bundles("MaxLength")); - settingsPanel.add(label, gbh.defaults().nextCol().setLabelDefault().get()); - settingsPanel.add(maxField, gbh.defaults().nextCol().setMaxWeightX().get()); - label = new JLabel(bundles("MinByte")); + LocalDateTime minValue = LocalDateTime.of(LocalDate.of(0, 1, 1), LocalTime.of(0, 0, 0)); + LocalDateTime maxValue = LocalDateTime.of(LocalDate.of(9999, 12, 31), LocalTime.of(23, 59, 59)); - settingsPanel.add(label, gbh.defaults().nextRowFirstCol().setLabelDefault().get()); - settingsPanel.add(minByteField, gbh.defaults().nextCol().setMaxWeightX().get()); - label = new JLabel(bundles("MaxByte")); - settingsPanel.add(label, gbh.defaults().nextCol().setLabelDefault().get()); - settingsPanel.add(maxByteField, gbh.defaults().nextCol().setMaxWeightX().get()); + minDateTime = new TimestampPicker(); + minDateTime.setDateTime(minValue); + minDateTime.setVisibleNullCheck(false); + maxDateTime = new TimestampPicker(); + maxDateTime.setDateTime(maxValue); + maxDateTime.setVisibleNullCheck(false); - } - setLayout(new GridBagLayout()); - gbh.setXY(0, 0); - add(nullBox, gbh.defaults().spanX().get()); - if (col.getFormattedDataType().contains(T.CHAR)) { - add(settingsPanel, gbh.defaults().nextRowFirstCol().fillBoth().spanX().spanY().get()); - } else { - add(settingsPanel, gbh.defaults().nextRowFirstCol().spanX().get()); - add(new JPanel(), gbh.defaults().nextRowFirstCol().spanX().spanY().get()); - } + // --- arrange --- + GridBagHelper gbh = new GridBagHelper().anchorNorthWest().fillHorizontally(); + settingsPanel.add(new JLabel(bundleString("Min")), gbh.leftGap(3).topGap(3).get()); + settingsPanel.add(minDateTime, gbh.nextCol().topGap(0).leftGap(5).setMaxWeightX().get()); + settingsPanel.add(new JLabel(bundleString("Max")), gbh.nextRowFirstCol().leftGap(3).topGap(8).setMinWeightX().get()); + settingsPanel.add(maxDateTime, gbh.nextCol().topGap(5).leftGap(5).setMaxWeightX().get()); + settingsPanel.add(new JPanel(), gbh.nextRowFirstCol().fillBoth().spanX().spanY().get()); } - private BigInteger getBigint() { - BigInteger bigint = new BigInteger(62, new Random()); - BigInteger max = new BigInteger(maxField.getText()); - BigInteger min = new BigInteger(minField.getText()); - if (max.compareTo(min) == -1) - throw new DataSourceException("minimum greater than maximum for column \"" + col.getName() + "\""); - BigInteger zero = new BigInteger("0"); + private void initZonedTimePanel() { + + minTimezone = new ZonedTimePicker(); + minTimezone.setTime(LocalTime.MIN); + minTimezone.setVisibleNullCheck(false); + + maxTimezone = new ZonedTimePicker(); + maxTimezone.setTime(LocalTime.MAX); + maxTimezone.setVisibleNullCheck(false); + + // --- arrange --- + + GridBagHelper gbh = new GridBagHelper().anchorNorthWest().fillHorizontally(); + settingsPanel.add(new JLabel(bundleString("Min")), gbh.leftGap(3).topGap(3).get()); + settingsPanel.add(minTimezone, gbh.nextCol().topGap(0).leftGap(5).setMaxWeightX().get()); + settingsPanel.add(new JLabel(bundleString("Max")), gbh.nextRowFirstCol().leftGap(3).topGap(8).setMinWeightX().get()); + settingsPanel.add(maxTimezone, gbh.nextCol().topGap(5).leftGap(5).setMaxWeightX().get()); + settingsPanel.add(new JPanel(), gbh.nextRowFirstCol().fillBoth().spanX().spanY().get()); + } + + private void initZonedTimestampPanel() { + + LocalDateTime minValue = LocalDateTime.of(LocalDate.of(0, 1, 1), LocalTime.of(0, 0, 0)); + LocalDateTime maxValue = LocalDateTime.of(LocalDate.of(9999, 12, 31), LocalTime.of(23, 59, 59)); + + minDateTimezone = new ZonedTimestampPicker(); + minDateTimezone.setVisibleNullCheck(false); + minDateTimezone.setDateTime(minValue); + + maxDateTimezone = new ZonedTimestampPicker(); + maxDateTimezone.setVisibleNullCheck(false); + maxDateTimezone.setDateTime(maxValue); + + // --- arrange --- + + GridBagHelper gbh = new GridBagHelper().anchorNorthWest().fillHorizontally(); + settingsPanel.add(new JLabel(bundleString("Min")), gbh.leftGap(3).topGap(3).get()); + settingsPanel.add(minDateTimezone, gbh.nextCol().topGap(0).leftGap(5).setMaxWeightX().get()); + settingsPanel.add(new JLabel(bundleString("Max")), gbh.nextRowFirstCol().leftGap(3).topGap(8).setMinWeightX().get()); + settingsPanel.add(maxDateTimezone, gbh.nextCol().topGap(5).leftGap(5).setMaxWeightX().get()); + settingsPanel.add(new JPanel(), gbh.nextRowFirstCol().fillBoth().spanX().spanY().get()); + } + + private void initBlobPanel() { + + maxField = WidgetFactory.createNumberTextField("maxField"); + maxField.setText("" + col.getColumnSize()); + maxField.setEnableNegativeNumbers(false); + + minField = WidgetFactory.createNumberTextField("minField"); + minField.setEnableNegativeNumbers(false); + minField.setText("0"); + + maxByteField = WidgetFactory.createNumberTextField("maxByteField"); + maxByteField.setText("255"); + + minByteField = WidgetFactory.createNumberTextField("minByteField"); + minByteField.setText("0"); + + // --- arrange --- + + GridBagHelper gbh = new GridBagHelper().anchorNorthWest().fillHorizontally(); + settingsPanel.add(new JLabel(bundleString("MinLength")), gbh.leftGap(3).topGap(3).get()); + settingsPanel.add(minField, gbh.nextCol().topGap(0).leftGap(5).setMaxWeightX().get()); + settingsPanel.add(new JLabel(bundleString("MaxLength")), gbh.nextRowFirstCol().leftGap(3).topGap(8).setMinWeightX().get()); + settingsPanel.add(maxField, gbh.nextCol().topGap(5).leftGap(5).setMaxWeightX().get()); + settingsPanel.add(new JLabel(bundleString("MinByte")), gbh.nextRowFirstCol().leftGap(3).topGap(8).setMinWeightX().get()); + settingsPanel.add(minByteField, gbh.nextCol().topGap(5).leftGap(5).setMaxWeightX().get()); + settingsPanel.add(new JLabel(bundleString("MaxByte")), gbh.nextRowFirstCol().leftGap(3).topGap(8).setMinWeightX().get()); + settingsPanel.add(maxByteField, gbh.nextCol().topGap(5).leftGap(5).setMaxWeightX().get()); + settingsPanel.add(new JPanel(), gbh.nextRowFirstCol().fillBoth().spanX().spanY().get()); + } + + // --- + + private BigInteger getBigintValue() { BigInteger diapason; + BigInteger zero = new BigInteger("0"); + + BigInteger min = new BigInteger(minField.getText()); + BigInteger max = new BigInteger(maxField.getText()); + checkDiapason(max.compareTo(min) < 0); + + BigInteger value = new BigInteger(62, new Random()); if (min.compareTo(zero) < 0 && max.compareTo(zero) > 0) { - Random random = new Random(); - int x = random.nextInt(); - x = x % 2; + + int x = new Random().nextInt() % 2; if (x == 0) { diapason = min.multiply(new BigInteger("-1")); - bigint = bigint.mod(diapason).multiply(new BigInteger("-1")); + value = value.mod(diapason).multiply(new BigInteger("-1")); } else { diapason = max; - bigint = bigint.mod(diapason); + value = value.mod(diapason); } + } else { diapason = max.subtract(min); - bigint = min.add(bigint.mod(diapason)); + value = min.add(value.mod(diapason)); } - return bigint; + + return value; } + private int getIntegerValue(String dataType) { - public Object getTestDataObject() { - if (nullBox.isSelected()) { - if (new Random().nextInt(10) == 0) - return null; - } - if (col.getFormattedDataType().contentEquals(T.BIGINT) || col.getFormattedDataType().contentEquals(T.INT128)) { - return getBigint(); - } - if (col.getFormattedDataType().contentEquals(T.TIME)) { - long value = new Random().nextLong(); - if (value < 0) - value *= -1; - - long max = maxTime.getLocalTime().atDate(LocalDate.of(1970, 1, 1)) - .toInstant(ZoneId.of(ZoneId.systemDefault().getId()) - .getRules().getOffset(Instant.now())) - .toEpochMilli(); - long min = minTime.getLocalTime().atDate(LocalDate.of(1970, 1, 1)) - .toInstant(ZoneId.of(ZoneId.systemDefault().getId()) - .getRules().getOffset(Instant.now())) - .toEpochMilli(); - - if (min > max) - throw new DataSourceException("minimum greater than maximum for column \"" + col.getName() + "\""); - long diapason = max - min; - if (diapason == 0) { - value = max; - } else - value = (min + (value % diapason)); - LocalDateTime dateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(value), ZoneId.systemDefault()); - return dateTime.toLocalTime(); - } + long max = maxField.getValue(); + long min = minField.getValue(); + checkDiapason(min, max); - if (col.getFormattedDataType().contentEquals(T.TIME_WITH_TIMEZONE)) { - long value = new Random().nextLong(); - if (value < 0) - value *= -1; - - long max = maxTimezone.getOffsetTime().atDate(LocalDate.of(1970, 1, 1)).toInstant().toEpochMilli(); - long min = minTimezone.getOffsetTime().atDate(LocalDate.of(1970, 1, 1)).toInstant().toEpochMilli(); - if (min > max) - throw new DataSourceException("minimum greater than maximum for column \"" + col.getName() + "\""); - long diapason = max - min; - if (diapason == 0) { - value = max; - } else - value = (min + (value % diapason)); - OffsetDateTime dateTime = OffsetDateTime.ofInstant(Instant.ofEpochMilli(value), ZoneId.systemDefault()); - return dateTime.toOffsetTime(); - } + long value = getRandomValue(max, min); + return dataType.contentEquals(T.SMALLINT) ? (short) value : (int) value; + } - if (col.getFormattedDataType().contentEquals(T.DATE)) { - long value = new Random().nextLong(); - if (value < 0) - value *= -1; - long max = maxDate.getDate().toEpochDay(); - long min = minDate.getDate().toEpochDay(); - if (min > max) - throw new DataSourceException("minimum greater than maximum for column \"" + col.getName() + "\""); - long diapason = max - min; - if (diapason == 0) { - value = max; - } else - value = (min + (value % diapason)); - LocalDate temp = LocalDate.ofEpochDay(value); - return temp; - } - if (col.getFormattedDataType().contentEquals(T.TIMESTAMP)) { - long value = new Random().nextLong(); - if (value < 0) - value *= -1; - ZoneId z_id = ZoneId.systemDefault(); - ZoneOffset offset = z_id.getRules().getOffset(Instant.now()); - long max = maxDateTime.getDateTime().toInstant(offset).toEpochMilli(); - long min = minDateTime.getDateTime().toInstant(offset).toEpochMilli(); - if (min > max) - throw new DataSourceException("minimum greater than maximum for column \"" + col.getName() + "\""); - long diapason = max - min; - if (diapason == 0) { - value = max; - } else - value = (min + (value % diapason)); - LocalDateTime dateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(value), ZoneId.systemDefault()); - return dateTime; - } - if (col.getFormattedDataType().contentEquals(T.TIMESTAMP_WITH_TIMEZONE)) { - long value = new Random().nextLong(); - if (value < 0) - value *= -1; - long max = maxDateTimezone.getOffsetDateTime().toInstant().toEpochMilli(); - long min = minDateTimezone.getOffsetDateTime().toInstant().toEpochMilli(); - if (min > max) - throw new DataSourceException("minimum greater than maximum for column \"" + col.getName() + "\""); - long diapason = max - min; - if (diapason == 0) { - value = max; - } else - value = (min + (value % diapason)); - OffsetDateTime dateTime = OffsetDateTime.ofInstant(Instant.ofEpochMilli(value), ZoneId.systemDefault()); - return dateTime; - } - if (col.getFormattedDataType().contentEquals(T.INTEGER) - || col.getFormattedDataType().contentEquals(T.SMALLINT)) { - long value = new Random().nextLong(); - if (value < 0) - value *= -1; - long max = ((NumberTextField) maxField).getValue(); - long min = ((NumberTextField) minField).getValue(); - if (min > max) - throw new DataSourceException("minimum greater than maximum for column \"" + col.getName() + "\""); - long diapason = max - min; - if (diapason == 0) { - value = max; - } else - value = (min + (value % diapason)); - if (col.getFormattedDataType().contentEquals(T.SMALLINT)) - return (short) value; - return (int) value; - } - if (col.getFormattedDataType().contentEquals(T.DOUBLE_PRECISION) - || col.getFormattedDataType().contentEquals(T.FLOAT) - || col.getFormattedDataType().startsWith(T.DECIMAL) - || col.getFormattedDataType().startsWith(T.NUMERIC) - || col.getFormattedDataType().startsWith(T.DECFLOAT) - ) { - long value = new Random().nextLong(); - if (value < 0) - value *= -1; - long power = (long) Math.pow(10, countSymbolsAfterComma.getLongValue()); - long max = Long.parseLong(maxField.getText()) * power; - long min = Long.parseLong(minField.getText()) * power; - if (min > max) - throw new DataSourceException("minimum greater than maximum for column \"" + col.getName() + "\""); - long diapason = max - min; - if (diapason == 0) { - value = max; - } else - value = (min + (value % diapason)); - return ((double) value) / ((double) power); - } - if (col.getFormattedDataType().contains(T.CHAR)) { - long n = new Random().nextLong(); - if (n < 0) - n *= -1; - long max = ((NumberTextField) maxField).getLongValue() + 1; - long min = ((NumberTextField) minField).getLongValue(); - if (min > max) - throw new DataSourceException("minimum greater than maximum for column \"" + col.getName() + "\""); - long diapason = max - min; - if (diapason == 0) { - n = max; - } else - n = (min + (n % diapason)); - StringBuilder result = new StringBuilder(); - if (useOnlyThisSymbolsBox.isSelected()) { - String charset = useOnlyThisSymbolsField.getTextAreaComponent().getText(); - int length = charset.length(); - for (int i = 0; i < n; i++) { - int x = new Random().nextInt(length); - result.append(charset.charAt(x)); - } - } else { - for (int i = 0; i < n; i++) { - int x = new Random().nextInt(127); - result.append((char) x); - } - } - return result.toString(); - } - if (col.getFormattedDataType().contains(T.BLOB)) { - int n = new Random().nextInt(); - if (n < 0) - n *= -1; - int max = ((NumberTextField) maxField).getValue() + 1; - int min = ((NumberTextField) minField).getValue(); - if (min > max) - throw new DataSourceException("minimum greater than maximum for column \"" + col.getName() + "\""); - int diapason = max - min; - if (diapason == 0) { - n = max; - } else - n = (min + (n % diapason)); - max = ((NumberTextField) maxByteField).getValue() + 1; - min = ((NumberTextField) minByteField).getValue(); - if (min > max) - throw new DataSourceException("minimum greater than maximum for column \"" + col.getName() + "\""); - diapason = max - min; - byte[] bytes = new byte[n]; - for (int i = 0; i < n; i++) { - if (diapason == 0) - bytes[i] = (byte) max; - int x = new Random().nextInt(); - if (x < 0) - x *= -1; - x = min + (x % diapason); - bytes[i] = (byte) x; + private Double getDecimalValue() { + long power = (long) Math.pow(10, symbolsAfterComma.getLongValue()); + + long max = Long.parseLong(maxField.getText()) * power; + long min = Long.parseLong(minField.getText()) * power; + checkDiapason(min, max); + + long value = getRandomValue(max, min); + return ((double) value) / ((double) power); + } + + private String getCharValue() { + + long max = maxField.getLongValue() + 1; + long min = minField.getLongValue(); + checkDiapason(min, max); + + StringBuilder value = new StringBuilder(); + long valueLength = getRandomValue(max, min); + String encoding = charsetCombo != null ? (String) charsetCombo.getSelectedItem() : null; + + if (useSelectedCharsetCheck.isSelected()) { + + String charset = useSelectedCharsetField.getTextAreaComponent().getText(); + int length = charset.length(); + + for (int i = 0; i < valueLength; i++) { + int x = new Random().nextInt(length); + value.append(charset.charAt(x)); } - return bytes; + + } else { + + String randomString = RandomStringUtils.random((int) valueLength, true, true); + if (!MiscUtils.isNull(encoding) && !Objects.equals(encoding, "NONE")) + randomString = new String(randomString.getBytes(), Charset.forName(encoding)); + + value.append(randomString); } - if (col.getFormattedDataType().contains(T.BOOLEAN)) { - return new Random().nextInt(2) == 1; + + return value.toString(); + } + + private LocalDate getDateValue() { + + long max = maxDate.getDate().toEpochDay(); + long min = minDate.getDate().toEpochDay(); + checkDiapason(min, max); + + long value = getRandomValue(max, min); + return LocalDate.ofEpochDay(value); + } + + private LocalTime getTimeValue() { + + long max = maxTime.getLocalTime().atDate(LocalDate.of(1970, 1, 1)) + .toInstant(ZoneId.of(ZoneId.systemDefault().getId()).getRules().getOffset(Instant.now())) + .toEpochMilli(); + + long min = minTime.getLocalTime().atDate(LocalDate.of(1970, 1, 1)) + .toInstant(ZoneId.of(ZoneId.systemDefault().getId()).getRules().getOffset(Instant.now())) + .toEpochMilli(); + + checkDiapason(min, max); + + long value = getRandomValue(max, min); + LocalDateTime dateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(value), ZoneId.systemDefault()); + return dateTime.toLocalTime(); + } + + private LocalDateTime getTimestampValue() { + ZoneOffset offset = ZoneId.systemDefault().getRules().getOffset(Instant.now()); + + long max = maxDateTime.getDateTime().toInstant(offset).toEpochMilli(); + long min = minDateTime.getDateTime().toInstant(offset).toEpochMilli(); + checkDiapason(min, max); + + long value = getRandomValue(max, min); + return LocalDateTime.ofInstant(Instant.ofEpochMilli(value), ZoneId.systemDefault()); + } + + private OffsetTime getZonedTimeValue() { + + long max = maxTimezone.getOffsetTime().atDate(LocalDate.of(1970, 1, 1)).toInstant().toEpochMilli(); + long min = minTimezone.getOffsetTime().atDate(LocalDate.of(1970, 1, 1)).toInstant().toEpochMilli(); + checkDiapason(min, max); + + long value = getRandomValue(max, min); + OffsetDateTime dateTime = OffsetDateTime.ofInstant(Instant.ofEpochMilli(value), ZoneId.systemDefault()); + return dateTime.toOffsetTime(); + } + + private OffsetDateTime getZonedTimestamp() { + + long max = maxDateTimezone.getOffsetDateTime().toInstant().toEpochMilli(); + long min = minDateTimezone.getOffsetDateTime().toInstant().toEpochMilli(); + checkDiapason(min, max); + + long value = getRandomValue(max, min); + return OffsetDateTime.ofInstant(Instant.ofEpochMilli(value), ZoneId.systemDefault()); + } + + private byte[] getBlobValue() { + + int maxLength = maxField.getValue() + 1; + int minLength = minField.getValue(); + checkDiapason(minLength, maxLength); + + int max = ((NumberTextField) maxByteField).getValue() + 1; + int min = ((NumberTextField) minByteField).getValue(); + checkDiapason(min, max); + + int valueLength = (int) getRandomValue(maxLength, minLength); + byte[] bytes = new byte[valueLength]; + for (int i = 0; i < valueLength; i++) + bytes[i] = (byte) getRandomValue(max, min); + + return bytes; + } + + private static boolean getBooleanValue() { + return new Random().nextInt(2) == 1; + } + + // --- + + private List getLoadCharsets() { + + List charsets = new LinkedList<>(); + try { + String loadedResource = FileUtils.loadResource("org/executequery/charsets.properties"); + Arrays.stream(loadedResource.split("\n")) + .filter(line -> !line.isEmpty()) + .filter(line -> !line.startsWith("#")) + .sorted().forEach(charsets::add); + + } catch (Exception e) { + Log.error(e.getMessage(), e); } + + charsets.add(0, "NONE"); + return charsets; + } + + private static long getRandomValue(long max, long min) { + + long diapason = max - min; + if (diapason == 0) + return max; + + return min + Math.abs(new Random().nextLong()) % diapason; + } + + private void checkDiapason(long min, long max) throws DataSourceException { + checkDiapason(min > max); + } + + private void checkDiapason(boolean isInvalid) throws DataSourceException { + if (isInvalid) + throw new DataSourceException("minimum greater than maximum for column \"" + col.getName() + "\""); + } + + // --- AbstractMethodPanel impl --- + + @Override + public Object getTestDataObject() { + + if (useNullCheck.isSelected() && new Random().nextInt(10) == 0) + return null; + + String dataType = col.getFormattedDataType(); + if (isBigint(dataType)) { + return getBigintValue(); + + } else if (isSmallint(dataType) || isInteger(dataType)) { + return getIntegerValue(dataType); + + } else if (isDecimal(dataType) || isDecFloat(dataType)) { + return getDecimalValue(); + + } else if (isChar(dataType)) { + return getCharValue(); + + } else if (isDate(dataType)) { + return getDateValue(); + + } else if (isTime(dataType)) { + return getTimeValue(); + + } else if (isTimestamp(dataType)) { + return getTimestampValue(); + + } else if (isZonedTime(dataType)) { + return getZonedTimeValue(); + + } else if (isZonedTimestamp(dataType)) { + return getZonedTimestamp(); + + } else if (isBlob(dataType)) { + return getBlobValue(); + + } else if (isBoolean(dataType)) + return getBooleanValue(); + return null; } diff --git a/src/org/executequery/gui/browser/managment/dbstatistic/DbStatPanel.java b/src/org/executequery/gui/browser/managment/dbstatistic/DbStatPanel.java index 1ae8402bf..836df679c 100644 --- a/src/org/executequery/gui/browser/managment/dbstatistic/DbStatPanel.java +++ b/src/org/executequery/gui/browser/managment/dbstatistic/DbStatPanel.java @@ -26,13 +26,19 @@ public DbStatPanel(StatDatabase db) { @Override protected void initComponents() { + textPanel = new SimpleTextArea(); + textPanel.getTextAreaComponent().setEditable(false); + tablesPanel = new StatisticTablePanel(); tablesPanel.initModel(StatisticTablePanel.TABLE); + indexesPanel = new StatisticTablePanel(); indexesPanel.initModel(StatisticTablePanel.INDEX); + tablespacesPanel = new StatisticTablePanel(); tablespacesPanel.initModel(StatisticTablePanel.TABLESPACE); + tabPane = new JTabbedPane(); tabPane.add(AbstractServiceManagerPanel.bundleString("tabText"), textPanel); tabPane.add(AbstractServiceManagerPanel.bundleString("tables"), tablesPanel); diff --git a/src/org/executequery/gui/browser/managment/dbstatistic/StatisticTablePanel.java b/src/org/executequery/gui/browser/managment/dbstatistic/StatisticTablePanel.java index b9d598c31..f9f10c28a 100644 --- a/src/org/executequery/gui/browser/managment/dbstatistic/StatisticTablePanel.java +++ b/src/org/executequery/gui/browser/managment/dbstatistic/StatisticTablePanel.java @@ -6,14 +6,19 @@ import org.executequery.gui.WidgetFactory; import org.executequery.gui.browser.managment.tracemanager.AnalisePanel; import org.executequery.gui.browser.managment.tracemanager.ServiceManagerPopupMenu; +import org.executequery.localization.Bundles; import org.underworldlabs.statParser.*; import org.underworldlabs.swing.AbstractPanel; +import org.underworldlabs.util.MiscUtils; import javax.swing.*; import javax.swing.event.*; import javax.swing.table.AbstractTableModel; import javax.swing.table.DefaultTableCellRenderer; +import javax.swing.table.JTableHeader; +import javax.swing.table.TableColumnModel; import java.awt.*; +import java.awt.event.MouseEvent; import java.util.List; import java.util.Vector; @@ -25,6 +30,7 @@ public class StatisticTablePanel extends AbstractPanel { JTable table; protected StatisticTableModel model; protected HeaderTableModel headerModel; + protected TableModelObject tableModelObject; protected List rows; protected JTable headerRows; JScrollPane scrollPane; @@ -115,7 +121,6 @@ protected void postInitActions() { } public void initModel(int type) { - TableModelObject tableModelObject; switch (type) { case DATABASE: tableModelObject = new StatDatabase(); @@ -134,6 +139,8 @@ public void initModel(int type) { } model = new StatisticTableModel(tableModelObject); table.setModel(model); + table.setTableHeader(new StatisticTableHeader(table.getColumnModel())); + headerModel = new HeaderTableModel(tableModelObject); headerRows.setModel(headerModel); headerRows.getColumnModel().getColumn(0).setPreferredWidth(200); @@ -318,4 +325,43 @@ private String delimitValue(long value, String result) { } else return value + result; } } + + private class StatisticTableHeader extends JTableHeader { + private List columnToolTips; + + public StatisticTableHeader(TableColumnModel columnModel) { + super(columnModel); + } + + @Override + public String getToolTipText(MouseEvent e) { + loadColumnsToolTips(); + + String tooltip = null; + try { + int index = columnModel.getColumnIndexAtX(e.getPoint().x); + int realIndex = columnModel.getColumn(index).getModelIndex(); + tooltip = columnToolTips.get(realIndex); + + } catch (ArrayIndexOutOfBoundsException ignored) { + } + + return tooltip; + } + + private void loadColumnsToolTips() { + + if (!MiscUtils.isEmpty(columnToolTips)) + return; + + columnToolTips = tableModelObject.getToolTips(); + columnToolTips.add(Bundles.get("TableModelObject.range_20")); + columnToolTips.add(Bundles.get("TableModelObject.range_40")); + columnToolTips.add(Bundles.get("TableModelObject.range_60")); + columnToolTips.add(Bundles.get("TableModelObject.range_80")); + columnToolTips.add(Bundles.get("TableModelObject.range_100")); + } + + } // StatisticTableHeader class + } diff --git a/src/org/executequery/gui/browser/managment/tracemanager/SessionManagerPanel.java b/src/org/executequery/gui/browser/managment/tracemanager/SessionManagerPanel.java index a8623ef13..c5d39d9b8 100644 --- a/src/org/executequery/gui/browser/managment/tracemanager/SessionManagerPanel.java +++ b/src/org/executequery/gui/browser/managment/tracemanager/SessionManagerPanel.java @@ -2,181 +2,153 @@ import biz.redsoft.IFBTraceManager; import org.executequery.GUIUtilities; -import org.executequery.gui.browser.TraceManagerPanel; +import org.executequery.gui.WidgetFactory; import org.executequery.gui.browser.managment.tracemanager.net.SessionInfo; -import org.underworldlabs.swing.DefaultButton; +import org.executequery.localization.Bundles; import org.underworldlabs.swing.DynamicComboBoxModel; +import org.underworldlabs.swing.layouts.GridBagHelper; import javax.swing.*; -import javax.swing.event.ListSelectionEvent; -import javax.swing.event.ListSelectionListener; import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; import java.sql.SQLException; import java.util.List; public class SessionManagerPanel extends JPanel { - private DynamicComboBoxModel sessionBoxModel; - private JList sessionBox; - private JTextField nameField; - private JTextField idField; + + private boolean refreshFlag; + private IFBTraceManager fbTraceManager; + + // --- GUI components --- + + private JList sessionsList; + private DynamicComboBoxModel sessionModel; + + private JTextField sessionIdField; private JTextArea flagsField; + private JTextField nameField; private JTextField userField; - private JTextField datetimeField; + private JTextField timestampField; + private final JTextField sessionField; + private JButton stopButton; private JButton refreshButton; - private boolean refreshFlag; - private IFBTraceManager fbTraceManager; - private JTextField sessionField; + + // --- public SessionManagerPanel(IFBTraceManager fbTraceManager, JTextField sessionField) { this.fbTraceManager = fbTraceManager; this.sessionField = sessionField; + + setRefreshFlag(true); init(); + arrange(); } private void init() { - setLayout(new GridBagLayout()); - setRefreshFlag(true); - sessionBoxModel = new DynamicComboBoxModel(); - sessionBox = new JList(sessionBoxModel); - sessionBox.addListSelectionListener(new ListSelectionListener() { - @Override - public void valueChanged(ListSelectionEvent e) { - if (sessionBox.getSelectedValue() != null) { - SessionInfo sessionInfo = (SessionInfo) sessionBox.getSelectedValue(); - idField.setText(sessionInfo.getId()); - nameField.setText(sessionInfo.getName()); - userField.setText(sessionInfo.getUser()); - datetimeField.setText(sessionInfo.getDatetime()); - flagsField.setText(sessionInfo.getFlags()); - } - } - }); - JScrollPane scrollPane = new JScrollPane(sessionBox); - nameField = new JTextField(); - nameField.setEditable(false); - idField = new JTextField(); - idField.setEditable(false); + + sessionModel = new DynamicComboBoxModel(); + sessionsList = new JList<>(sessionModel); + sessionsList.setBorder(BorderFactory.createTitledBorder(bundleString("Sessions"))); + sessionsList.addListSelectionListener(e -> sessionChanged()); + flagsField = new JTextArea(); + flagsField.setBorder(BorderFactory.createTitledBorder(bundleString("Flags"))); flagsField.setFont(UIManager.getDefaults().getFont("Label.font")); flagsField.setEditable(false); - userField = new JTextField(); - userField.setEditable(false); - datetimeField = new JTextField(); - datetimeField.setEditable(false); - stopButton = new DefaultButton(TraceManagerPanel.bundleString("Stop")); - stopButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - if (sessionBox.getSelectedValue() != null) - try { - SessionInfo sessionInfo = (SessionInfo) sessionBox.getSelectedValue(); - if (sessionField.getText().contentEquals(sessionInfo.getName())) { - int res = GUIUtilities.displayConfirmDialog("this session may be current session.Do you want continue?"); - if (res == JOptionPane.YES_OPTION) { - fbTraceManager.stopTraceSession(Integer.parseInt(sessionInfo.getId())); - refresh(); - } - } else { - fbTraceManager.stopTraceSession(Integer.parseInt(sessionInfo.getId())); - refresh(); - } - } catch (SQLException e1) { - GUIUtilities.displayExceptionErrorDialog("Error stop session", e1, this.getClass()); - } - } - }); - - refreshButton = new DefaultButton(TraceManagerPanel.bundleString("Refresh")); - refreshButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - refresh(); - } - }); - - JLabel label = new JLabel(TraceManagerPanel.bundleString("Sessions")); - add(label, new GridBagConstraints(0, 0, - 1, 1, 0, 0, - GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), - 0, 0)); - add(scrollPane, new GridBagConstraints(0, 1, - 1, 4, 1, 1, - GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), - 0, 0)); - - label = new JLabel(TraceManagerPanel.bundleString("ID")); - add(label, new GridBagConstraints(1, 1, - 1, 1, 0, 0, - GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), - 0, 0)); - - add(idField, new GridBagConstraints(2, 1, - 1, 1, 1, 0, - GridBagConstraints.NORTHEAST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), - 0, 0)); - - label = new JLabel(TraceManagerPanel.bundleString("Name")); - add(label, new GridBagConstraints(3, 1, - 1, 1, 0, 0, - GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), - 0, 0)); - - add(nameField, new GridBagConstraints(4, 1, - 1, 1, 1, 0, - GridBagConstraints.NORTHEAST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), - 0, 0)); - - label = new JLabel(TraceManagerPanel.bundleString("User")); - add(label, new GridBagConstraints(1, 2, - 1, 1, 0, 0, - GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), - 0, 0)); - - add(userField, new GridBagConstraints(2, 2, - 1, 1, 1, 0, - GridBagConstraints.NORTHEAST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), - 0, 0)); - - label = new JLabel(TraceManagerPanel.bundleString("Date")); - add(label, new GridBagConstraints(3, 2, - 1, 1, 0, 0, - GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), - 0, 0)); - - add(datetimeField, new GridBagConstraints(4, 2, - 1, 1, 1, 0, - GridBagConstraints.NORTHEAST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), - 0, 0)); - - label = new JLabel(TraceManagerPanel.bundleString("Flags")); - add(label, new GridBagConstraints(1, 3, - 1, 1, 0, 0, - GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), - 0, 0)); - - add(flagsField, new GridBagConstraints(2, 3, - 3, 1, 1, 1, - GridBagConstraints.NORTHEAST, GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), - 0, 0)); - - add(stopButton, new GridBagConstraints(1, 4, - 1, 1, 0, 0, - GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), - 0, 0)); - - add(refreshButton, new GridBagConstraints(2, 4, - 1, 1, 0, 0, - GridBagConstraints.NORTHEAST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), - 0, 0)); + userField = WidgetFactory.createTextField("userField", false); + nameField = WidgetFactory.createTextField("nameField", false); + sessionIdField = WidgetFactory.createTextField("sessionIdField", false); + timestampField = WidgetFactory.createTextField("timestampField", false); + + stopButton = WidgetFactory.createButton("stopButton", bundleString("Stop"), e -> stop()); + refreshButton = WidgetFactory.createButton("refreshButton", bundleString("Refresh"), e -> refresh()); + } + + private void arrange() { + GridBagHelper gbh; + + // --- buttons panel --- + + JPanel buttonsPanel = WidgetFactory.createPanel("buttonsPanel"); + + gbh = new GridBagHelper().anchorNorthWest().fillHorizontally(); + buttonsPanel.add(refreshButton, gbh.nextCol().get()); + buttonsPanel.add(stopButton, gbh.nextCol().leftGap(5).get()); + + // --- info panel --- + JPanel infoPanel = WidgetFactory.createPanel("infoPanel"); + + gbh = new GridBagHelper().anchorNorthWest().fillHorizontally(); + infoPanel.add(new JLabel(bundleString("SessionId")), gbh.setMinWeightX().topGap(3).get()); + infoPanel.add(sessionIdField, gbh.nextCol().setMaxWeightX().leftGap(5).topGap(0).get()); + infoPanel.add(new JLabel(bundleString("Name")), gbh.nextCol().setMinWeightX().leftGap(10).topGap(3).get()); + infoPanel.add(nameField, gbh.nextCol().setMaxWeightX().leftGap(5).topGap(0).get()); + infoPanel.add(new JLabel(bundleString("User")), gbh.nextRowFirstCol().setMinWeightX().leftGap(0).topGap(8).get()); + infoPanel.add(userField, gbh.nextCol().setMaxWeightX().leftGap(5).topGap(5).get()); + infoPanel.add(new JLabel(bundleString("Date")), gbh.nextCol().setMinWeightX().leftGap(10).topGap(8).get()); + infoPanel.add(timestampField, gbh.nextCol().setMaxWeightX().leftGap(5).topGap(5).get()); + infoPanel.add(flagsField, gbh.nextRowFirstCol().leftGap(0).setMaxWeightY().fillBoth().spanX().spanY().get()); + + // --- main panel --- + + JPanel mainPanel = WidgetFactory.createPanel("mainPanel"); + + gbh = new GridBagHelper().anchorNorthWest().fillBoth(); + mainPanel.add(sessionsList, gbh.setWeightX(0.15).setMaxWeightY().get()); + mainPanel.add(buttonsPanel, gbh.nextRow().setMinWeightY().topGap(5).fillHorizontally().get()); + mainPanel.add(infoPanel, gbh.nextCol().previousRow().leftGap(5).topGap(0).fillBoth().spanY().spanX().get()); + + // --- base --- + + setLayout(new GridBagLayout()); + + gbh = new GridBagHelper().topGap(5).anchorNorthWest().fillBoth(); + add(mainPanel, gbh.spanX().spanY().get()); + } + + private void stop() { + + if (sessionsList.getSelectedValue() == null) + return; + + try { + + SessionInfo sessionInfo = sessionsList.getSelectedValue(); + if (sessionField.getText().contentEquals(sessionInfo.getName())) { + int confirmResult = GUIUtilities.displayConfirmDialog(bundleString("SessionManagerPanel.SessionsEquals")); + if (confirmResult == JOptionPane.YES_OPTION) + stopAndRefresh(sessionInfo); + + } else + stopAndRefresh(sessionInfo); + + } catch (SQLException e) { + GUIUtilities.displayExceptionErrorDialog(bundleString("ErrorStopping", e.getMessage()), e, this.getClass()); + } + } + + private void stopAndRefresh(SessionInfo sessionInfo) throws SQLException { + fbTraceManager.stopTraceSession(Integer.parseInt(sessionInfo.getId())); + refresh(); + } + + private void sessionChanged() { + + if (sessionsList.getSelectedValue() == null) + return; + + SessionInfo sessionInfo = sessionsList.getSelectedValue(); + sessionIdField.setText(sessionInfo.getId()); + nameField.setText(sessionInfo.getName()); + userField.setText(sessionInfo.getUser()); + timestampField.setText(sessionInfo.getDatetime()); + flagsField.setText(sessionInfo.getFlags()); } public void setSessions(List sessions) { - sessionBoxModel.setElements(sessions); + sessionModel.setElements(sessions); } public boolean isRefreshFlag() { @@ -191,8 +163,8 @@ private void refresh() { setRefreshFlag(true); try { fbTraceManager.listTraceSessions(); - } catch (SQLException e1) { - GUIUtilities.displayExceptionErrorDialog("Error refresh", e1, this.getClass()); + } catch (SQLException e) { + GUIUtilities.displayExceptionErrorDialog(e.getMessage(), e, this.getClass()); } } @@ -200,4 +172,8 @@ public void setFbTraceManager(IFBTraceManager fbTraceManager) { this.fbTraceManager = fbTraceManager; } + private static String bundleString(String key, Object... args) { + return Bundles.get(SessionManagerPanel.class, key, args); + } + } diff --git a/src/org/executequery/gui/browser/managment/tracemanager/TablePanel.java b/src/org/executequery/gui/browser/managment/tracemanager/TablePanel.java index 74ae9bee8..bc68933a1 100644 --- a/src/org/executequery/gui/browser/managment/tracemanager/TablePanel.java +++ b/src/org/executequery/gui/browser/managment/tracemanager/TablePanel.java @@ -307,6 +307,7 @@ public void mouseClicked(MouseEvent e) { littleSplit.setTopComponent(logListPanel); txtFieldRawSql = new SimpleSqlTextPanel(); txtFieldRawSql.setBorder(BorderFactory.createTitledBorder(TraceManagerPanel.bundleString("Body"))); + txtFieldRawSql.setFont(new Font("Monospaced", Font.PLAIN, 14)); littleSplit.setBottomComponent(txtFieldRawSql); JSplitPane bigSplit = new JSplitPane(); diff --git a/src/org/executequery/gui/browser/profiler/ProfilerPanel.java b/src/org/executequery/gui/browser/profiler/ProfilerPanel.java index 583d0ce58..7aee17b6e 100644 --- a/src/org/executequery/gui/browser/profiler/ProfilerPanel.java +++ b/src/org/executequery/gui/browser/profiler/ProfilerPanel.java @@ -2,13 +2,12 @@ import org.executequery.GUIUtilities; import org.executequery.base.TabView; -import org.executequery.components.TableSelectionCombosGroup; import org.executequery.databasemediators.DatabaseConnection; import org.executequery.databasemediators.spi.DefaultStatementExecutor; -import org.executequery.datasource.ConnectionManager; import org.executequery.gui.WidgetFactory; import org.executequery.localization.Bundles; import org.executequery.log.Log; +import org.underworldlabs.swing.ConnectionsComboBox; import org.underworldlabs.swing.DynamicComboBoxModel; import org.underworldlabs.swing.layouts.GridBagHelper; import org.underworldlabs.swing.treetable.CCTNode; @@ -42,8 +41,8 @@ public class ProfilerPanel extends JPanel // --- GUI objects --- - private JComboBox connectionsComboBox; private JComboBox attachmentsComboBox; + private ConnectionsComboBox connectionsComboBox; private JCheckBox compactViewCheckBox; private JCheckBox roundValuesCheckBox; @@ -64,9 +63,8 @@ public class ProfilerPanel extends JPanel private int sessionId; private int currentState; private boolean dataCollected; - private DefaultProfilerExecutor profilerExecutor; - private TableSelectionCombosGroup combosGroup; private List oldDataList; + private DefaultProfilerExecutor profilerExecutor; // --- @@ -100,10 +98,8 @@ private void init() { // --- connections comboBox --- - connectionsComboBox = WidgetFactory.createComboBox("connectionsComboBox"); - connectionsComboBox.setModel(new DynamicComboBoxModel(new Vector<>(ConnectionManager.getActiveConnections()))); + connectionsComboBox = WidgetFactory.createConnectionComboBox("connectionsComboBox", true); connectionsComboBox.addActionListener(e -> refreshAttachments()); - combosGroup = new TableSelectionCombosGroup(connectionsComboBox); // --- compactView CheckBox --- @@ -236,7 +232,7 @@ private void startSession() { } profilerExecutor = new DefaultProfilerExecutor( - combosGroup.getSelectedHost().getDatabaseConnection(), + getSelectedConnection(), ((AttachmentData) Objects.requireNonNull(attachmentsComboBox.getSelectedItem())).id ); @@ -595,7 +591,7 @@ private void refreshAttachments() { try { DefaultStatementExecutor executor = new DefaultStatementExecutor(); - executor.setDatabaseConnection(combosGroup.getSelectedHost().getDatabaseConnection()); + executor.setDatabaseConnection(getSelectedConnection()); executor.setKeepAlive(true); executor.setCommitMode(false); @@ -657,7 +653,11 @@ public boolean isDataCollected() { } private boolean isConnected() { - return combosGroup.getSelectedHost().isConnected(); + return getSelectedConnection().isConnected(); + } + + private DatabaseConnection getSelectedConnection() { + return connectionsComboBox.getSelectedConnection(); } @Override diff --git a/src/org/executequery/gui/components/OpenConnectionsComboboxPanel.java b/src/org/executequery/gui/components/OpenConnectionsComboboxPanel.java deleted file mode 100644 index b87e2c788..000000000 --- a/src/org/executequery/gui/components/OpenConnectionsComboboxPanel.java +++ /dev/null @@ -1,50 +0,0 @@ -package org.executequery.gui.components; - -import org.executequery.databasemediators.DatabaseConnection; -import org.executequery.datasource.ConnectionManager; -import org.executequery.gui.WidgetFactory; -import org.executequery.localization.Bundles; -import org.underworldlabs.swing.DynamicComboBoxModel; - -import javax.swing.*; -import java.awt.*; -import java.awt.event.ActionListener; -import java.util.Vector; - -public class OpenConnectionsComboboxPanel extends JPanel { - public JComboBox connectionsCombo; - public DynamicComboBoxModel connectionsModel; - - public OpenConnectionsComboboxPanel() { - init(); - } - - void init() { - Vector connections = ConnectionManager.getActiveConnections(); - connectionsModel = new DynamicComboBoxModel(connections); - connectionsCombo = WidgetFactory.createComboBox("connectionsCombo", connectionsModel); - - setLayout(new GridBagLayout()); - JLabel connLabel = new JLabel(Bundles.getCommon("connection")); - add(connLabel, new GridBagConstraints(0, 0, - 1, 1, 0, 0, - GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), - 0, 0)); - add(connectionsCombo, new GridBagConstraints(1, 0, - 1, 1, 1, 0, - GridBagConstraints.NORTHEAST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), - 0, 0)); - } - - public void addActionListener(ActionListener listener) { - connectionsCombo.addActionListener(listener); - } - - public DatabaseConnection getSelectedConnection() { - return (DatabaseConnection) connectionsCombo.getSelectedItem(); - } - - public void setSelectedConnection(DatabaseConnection connection) { - connectionsCombo.setSelectedItem(connection); - } -} diff --git a/src/org/executequery/gui/connections/ExportConnectionsPanelTwo.java b/src/org/executequery/gui/connections/ExportConnectionsPanelTwo.java index 5e3fc224b..00bf26668 100644 --- a/src/org/executequery/gui/connections/ExportConnectionsPanelTwo.java +++ b/src/org/executequery/gui/connections/ExportConnectionsPanelTwo.java @@ -45,7 +45,7 @@ private void init() { fileNameField = WidgetFactory.createTextField("fileNameField"); - JButton button = WidgetFactory.createInlineFieldButton("browseButton", Bundles.get("CreateTableFunctionPanel.BrowseButtonText")); + JButton button = WidgetFactory.createInlineFieldButton("browseButton", Bundles.get("common.browse.button")); button.setActionCommand("browse"); button.addActionListener(this); button.setMnemonic('r'); diff --git a/src/org/executequery/gui/connections/ImportConnectionsDBPanel.java b/src/org/executequery/gui/connections/ImportConnectionsDBPanel.java index a74a612c5..3f09c56fd 100644 --- a/src/org/executequery/gui/connections/ImportConnectionsDBPanel.java +++ b/src/org/executequery/gui/connections/ImportConnectionsDBPanel.java @@ -1,163 +1,229 @@ package org.executequery.gui.connections; import org.executequery.GUIUtilities; -import org.executequery.components.BottomButtonPanel; import org.executequery.databasemediators.DatabaseConnection; import org.executequery.databasemediators.DatabaseConnectionFactory; import org.executequery.databasemediators.spi.DatabaseConnectionFactoryImpl; import org.executequery.databasemediators.spi.DefaultStatementExecutor; import org.executequery.gui.ActionContainer; +import org.executequery.gui.WidgetFactory; import org.executequery.gui.browser.ConnectionsTreePanel; -import org.executequery.gui.components.OpenConnectionsComboboxPanel; import org.executequery.localization.Bundles; +import org.executequery.log.Log; import org.executequery.repository.DatabaseConnectionRepository; import org.executequery.repository.RepositoryCache; +import org.underworldlabs.swing.ConnectionsComboBox; +import org.underworldlabs.swing.layouts.GridBagHelper; import org.underworldlabs.util.MiscUtils; import javax.swing.*; import java.awt.*; -import java.awt.event.ActionEvent; import java.sql.ResultSet; import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; import java.util.Properties; public class ImportConnectionsDBPanel extends JPanel { - public static final String TITLE = "Import Connections"; + public static final String TITLE = bundleString("title"); - ActionContainer parent; - OpenConnectionsComboboxPanel connectionsComboboxPanel; - DatabaseConnectionFactory databaseConnectionFactory; + private final ActionContainer parent; + private final List loadedConnections; + private final List availableConnections; + private DatabaseConnectionFactory connectionFactory; + private JButton applyButton; + private JButton cancelButton; + private ConnectionsComboBox connectionsCombo; + + public ImportConnectionsDBPanel(ActionContainer parent) { + this.parent = parent; + this.loadedConnections = new ArrayList<>(); + this.availableConnections = new ArrayList<>(); - public ImportConnectionsDBPanel(ActionContainer dialog) { - parent = dialog; init(); + arrange(); } - void init() { - connectionsComboboxPanel = new OpenConnectionsComboboxPanel(); - BottomButtonPanel bottomButtonPanel = new BottomButtonPanel(parent.isDialog()); - bottomButtonPanel.setOkButtonAction(new AbstractAction() { - @Override - public void actionPerformed(ActionEvent e) { - doImport(); - } - }); - bottomButtonPanel.setOkButtonText("OK"); - bottomButtonPanel.setHelpButtonVisible(false); + private void init() { + connectionsCombo = WidgetFactory.createConnectionComboBox("connectionsCombo", true); + applyButton = WidgetFactory.createButton("applyButton", Bundles.get("common.ok.button"), e -> importConnections()); + cancelButton = WidgetFactory.createButton("cancelButton", Bundles.get("common.cancel.button"), e -> finished(false)); + } + + private void arrange() { + GridBagHelper gbh; + + // --- button panel --- + + JPanel buttonPanel = new JPanel(new GridBagLayout()); - setLayout(new BorderLayout()); + gbh = new GridBagHelper().anchorSouthWest(); + buttonPanel.add(new JPanel(), gbh.setMaxWeightX().get()); + buttonPanel.add(applyButton, gbh.nextCol().setMinWeightX().get()); + buttonPanel.add(cancelButton, gbh.nextCol().leftGap(5).get()); - this.add(connectionsComboboxPanel, BorderLayout.NORTH); - this.add(bottomButtonPanel, BorderLayout.SOUTH); + // --- main panel --- + JPanel mainPanel = new JPanel(new GridBagLayout()); + + gbh = new GridBagHelper().anchorNorthWest().fillHorizontally(); + mainPanel.add(new JLabel(Bundles.get("common.connection")), gbh.topGap(3).setMinWeightX().get()); + mainPanel.add(connectionsCombo, gbh.nextCol().topGap(0).leftGap(5).setMaxWeightX().get()); + mainPanel.add(buttonPanel, gbh.nextRowFirstCol().leftGap(0).topGap(10).spanX().spanY().get()); + + // --- base --- + + setLayout(new GridBagLayout()); + + gbh = new GridBagHelper().setInsets(5, 5, 5, 5).fillBoth().spanX().spanY(); + add(mainPanel, gbh.get()); + + setPreferredSize(new Dimension(300, getPreferredSize().height)); + parent.setResizable(false); } - void doImport() { - DatabaseConnection connection = connectionsComboboxPanel.getSelectedConnection(); + private void importConnections() { + + DatabaseConnection connection = getSelectedConnection(); DefaultStatementExecutor sender = new DefaultStatementExecutor(connection, true); - String query = "SELECT PROPS FROM DATABASES"; + + ConnectionsTreePanel treePanel = null; + JPanel tabbedComponent = GUIUtilities.getDockedTabComponent(ConnectionsTreePanel.PROPERTY_KEY); + if (tabbedComponent instanceof ConnectionsTreePanel) + treePanel = (ConnectionsTreePanel) tabbedComponent; + + if (treePanel == null) { + GUIUtilities.displayWarningMessage(bundleString("connectionsTreeUnavailable")); + finished(false); + return; + } + try { + + String query = "SELECT PROPS FROM DATABASES"; ResultSet rs = sender.getResultSet(query).getResultSet(); - if (rs == null) - GUIUtilities.displayErrorMessage("Sorry, this connection does not seem to contain connection settings"); - else - while (rs.next()) { - Properties properties = new Properties(); - String str = rs.getString(1); - String[] strs = str.split("\r\n"); - for (int i = 0; i < strs.length; i++) { - int ind = strs[i].indexOf("="); - String key = strs[i].substring(0, ind); - String prop = strs[i].substring(ind + 1); - properties.setProperty(key, prop); - } - String name = properties.getProperty("Alias"); - if (!MiscUtils.isNull(name)) { - DatabaseConnection databaseConnection = databaseConnectionFactory().create(name); - ConnectionsTreePanel connectionsTreePanel = null; - if (!connectionNameExists(databaseConnection.getName(), databaseConnection)) { - try { - connectionsTreePanel = (ConnectionsTreePanel) GUIUtilities. - getDockedTabComponent(ConnectionsTreePanel.PROPERTY_KEY); - } catch (Exception e) { - e.printStackTrace(); - } - - /***/ - databaseConnection.setUserName(properties.getProperty("UserName")); - databaseConnection.setPasswordStored(true); - databaseConnection.setPassword(properties.getProperty("Password")); - databaseConnection.setRole(properties.getProperty("Role")); - databaseConnection.setCharset(properties.getProperty("Charset")); - String s = properties.getProperty("DBName"); - databaseConnection.setSourceName(s); - String host = properties.getProperty("SrvName"); - if (MiscUtils.isNull(host)) { - databaseConnection.setHost("127.0.0.1"); - databaseConnection.setPort("3050"); - } else { - String server; - String port; - if (host.contains("/")) { - String[] serverport = host.split("/"); - server = serverport[0]; - port = serverport[1]; - } else { - server = host; - port = "3050"; - } - databaseConnection.setHost(server); - databaseConnection.setPort(port); - } - - try { - connectionsTreePanel.newConnection(databaseConnection); - } catch (Exception e) { - e.printStackTrace(); - } - } + if (rs == null) { + GUIUtilities.displayErrorMessage(bundleString("noConnections")); + finished(false); + return; + } + + while (rs.next()) { + + String rsValue = rs.getString(1); + if (MiscUtils.isNull(rsValue)) + continue; + + String[] connectionProperties = rsValue.split("\r\n"); + if (MiscUtils.isEmpty(connectionProperties)) + continue; - /***/ + Properties properties = new Properties(); + for (String propertyString : connectionProperties) { + int splitIndex = propertyString.indexOf("="); + properties.setProperty( + propertyString.substring(0, splitIndex), + propertyString.substring(splitIndex + 1) + ); + } + + String alias = properties.getProperty("Alias"); + if (MiscUtils.isNull(alias)) + continue; + + availableConnections.add(alias); + DatabaseConnection databaseConnection = databaseConnectionFactory().create(alias); + if (!connectionNameExists(databaseConnection.getName(), databaseConnection)) { + + String port = "3050"; + String host = "localhost"; + String serverString = properties.getProperty("SrvName"); + if (!MiscUtils.isNull(serverString)) { + if (serverString.contains("/")) { + String[] serverProperties = serverString.split("/"); + host = serverProperties[0]; + port = serverProperties[1]; + } else { + host = serverString; + port = "3050"; + } } + databaseConnection.setHost(host); + databaseConnection.setPort(port); + databaseConnection.setPasswordStored(true); + databaseConnection.setRole(properties.getProperty("Role")); + databaseConnection.setCharset(properties.getProperty("Charset")); + databaseConnection.setSourceName(properties.getProperty("DBName")); + databaseConnection.setUserName(properties.getProperty("UserName")); + databaseConnection.setPassword(properties.getProperty("Password")); + + try { + treePanel.newConnection(databaseConnection, false); + loadedConnections.add(alias); + + } catch (Exception e) { + Log.error(e.getMessage(), e); + } } - parent.finished(); + } + finished(true); + } catch (SQLException e) { - e.printStackTrace(); + Log.error(e.getMessage(), e); + GUIUtilities.displayExceptionErrorDialog(e.getMessage(), e, getClass()); + } finally { sender.releaseResources(); } + } + + private void finished(boolean showMessage) { + parent.finished(); + + if (!showMessage) + return; + + if (availableConnections.size() == loadedConnections.size()) { + GUIUtilities.displayInformationMessage(bundleString("loadedSuccessfully")); + return; + } + + availableConnections.removeAll(loadedConnections); + GUIUtilities.displayWarningMessage(bundleString( + "loadedWithError", + availableConnections.size(), + String.join("\n", availableConnections) + )); + } + private DatabaseConnection getSelectedConnection() { + return connectionsCombo.getSelectedConnection(); } private boolean connectionNameExists(String name, DatabaseConnection databaseConnection) { if (databaseConnectionRepository().nameExists(databaseConnection, name, databaseConnection.getFolderId())) { - GUIUtilities.displayErrorMessage(String.format(Bundles.get("ConnectionPanel.error.nameExist"), name)); + GUIUtilities.displayErrorMessage(bundleString("nameExist", name)); return true; } return false; } - private DatabaseConnectionFactory databaseConnectionFactory() { - - if (databaseConnectionFactory == null) { - - databaseConnectionFactory = new DatabaseConnectionFactoryImpl(); - } - - return databaseConnectionFactory; + if (connectionFactory == null) + connectionFactory = new DatabaseConnectionFactoryImpl(); + return connectionFactory; } private DatabaseConnectionRepository databaseConnectionRepository() { - - return (DatabaseConnectionRepository) RepositoryCache.load( - DatabaseConnectionRepository.REPOSITORY_ID); + return (DatabaseConnectionRepository) RepositoryCache.load(DatabaseConnectionRepository.REPOSITORY_ID); } + private static String bundleString(String key, Object... args) { + return Bundles.get(ImportConnectionsDBPanel.class, key, args); + } } - diff --git a/src/org/executequery/gui/connections/ImportConnectionsPanelOne.java b/src/org/executequery/gui/connections/ImportConnectionsPanelOne.java index 2e7cc54de..93a43dda3 100644 --- a/src/org/executequery/gui/connections/ImportConnectionsPanelOne.java +++ b/src/org/executequery/gui/connections/ImportConnectionsPanelOne.java @@ -45,7 +45,7 @@ private void init() { fileNameField = WidgetFactory.createTextField("fileNameField"); - JButton button = WidgetFactory.createInlineFieldButton("browseButton", Bundles.get("CreateTableFunctionPanel.BrowseButtonText")); + JButton button = WidgetFactory.createInlineFieldButton("browseButton", Bundles.get("common.browse.button")); button.setActionCommand("browse"); button.addActionListener(this); button.setMnemonic('r'); diff --git a/src/org/executequery/gui/console/Console.java b/src/org/executequery/gui/console/Console.java index dc3f2f23f..41e9ef389 100644 --- a/src/org/executequery/gui/console/Console.java +++ b/src/org/executequery/gui/console/Console.java @@ -54,6 +54,7 @@ public class Console extends JScrollPane { public static final int WINDOWS_OS = 0; public static final int UNIX_OS = 1; public static final int MAC_OS = 2; + private final String title; private int osType; @@ -115,19 +116,20 @@ public class Console extends JScrollPane { * Instanciates a new console without displaying prompt. */ public Console() { - this(true); + this(true, null); } /** * Creates a new console, embedding it in a JScrollPane. - * By default console help is displayed. + * By default, console help is displayed. * * @param display If set on true, prompt is displayed */ - public Console(boolean display) { + public Console(boolean display, String title) { super(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + this.title = title; // check we have the console properties loaded if (SystemProperties.getProperties("console") == null) { @@ -906,6 +908,10 @@ public void execute(String command) { displayPrompt(); } + public String getFrameTitle() { + return title; + } + class StdoutThread extends Thread { StdoutThread() { diff --git a/src/org/executequery/gui/console/ConsolePanel.java b/src/org/executequery/gui/console/ConsolePanel.java index 7ec1b86ca..6f5ed43a1 100644 --- a/src/org/executequery/gui/console/ConsolePanel.java +++ b/src/org/executequery/gui/console/ConsolePanel.java @@ -23,8 +23,11 @@ import org.executequery.ActiveComponent; import org.executequery.base.DefaultTabView; import org.executequery.gui.NamedView; +import org.executequery.localization.Bundles; import java.awt.*; +import java.util.ArrayList; +import java.util.List; /** * The system console base panel. @@ -35,81 +38,63 @@ public class ConsolePanel extends DefaultTabView implements ActiveComponent, NamedView { - public static final String TITLE = "System Console "; public static final String FRAME_ICON = "icon_console_system"; + private static final List instances = new ArrayList<>(); + private String title; private Console console; - /** - * Constructs a new instance. - */ public ConsolePanel() { super(new BorderLayout()); - - try { - jbInit(); - } catch (Exception e) { - e.printStackTrace(); - } - + init(); } - /** - * Initializes the state of this instance. - */ - private void jbInit() throws Exception { - console = new Console(true); + private void init() { + instances.add(buildUniqueTitle()); + console = new Console(true, title); + setPreferredSize(new Dimension(600, 400)); add(console, BorderLayout.CENTER); } - public void cleanup() { - console.cleanup(); + private String buildUniqueTitle() { + final String bundledTitle = Bundles.get(ConsolePanel.class, "title"); + + int maxIndex = instances.stream() + .map(s -> s.replace(bundledTitle, "").trim()) + .map(Integer::parseInt) + .max(Integer::compare).orElse(0); + + title = bundledTitle + " " + (maxIndex + 1); + return title; } - public String toString() { - return TITLE; + public String getTitle() { + return title; } - /** - * the instance counter - */ - private static int count = 1; + // --- ActiveComponent impl --- - /** - * Returns the display name for this view. - * - * @return the display name - */ + @Override + public void cleanup() { + console.cleanup(); + } + + // --- NamedView impl ---- + + @Override public String getDisplayName() { - return TITLE + (count++); + return title; } - // -------------------------------------------- - // DockedTabView implementation - // -------------------------------------------- + // --- DockedTabView impl --- - /** - * Indicates the panel is being removed from the pane - */ + @Override public boolean tabViewClosing() { + instances.remove(title); cleanup(); + return true; } } - - - - - - - - - - - - - - - diff --git a/src/org/executequery/gui/console/commands/ExitCommand.java b/src/org/executequery/gui/console/commands/ExitCommand.java index 97f0926dd..bab3af6e4 100644 --- a/src/org/executequery/gui/console/commands/ExitCommand.java +++ b/src/org/executequery/gui/console/commands/ExitCommand.java @@ -22,7 +22,6 @@ import org.executequery.GUIUtilities; import org.executequery.gui.console.Console; -import org.executequery.gui.console.ConsolePanel; import org.underworldlabs.util.SystemProperties; import javax.swing.*; @@ -36,28 +35,28 @@ /** * This command exits from the console and closes current window. - */ - -/** + * * @author Takis Diakoumis */ public class ExitCommand extends Command { private static final String COMMAND_NAME = "exit"; + @Override public String getCommandName() { return COMMAND_NAME; } + @Override public String getCommandSummary() { return SystemProperties.getProperty("console", "console.exit.command.help"); } + @Override public boolean handleCommand(Console console, String command) { if (command.equals(COMMAND_NAME)) { - GUIUtilities.closeDockedComponent(ConsolePanel.TITLE, SwingConstants.SOUTH); - //GUIUtilities.closeInternalFrame(ConsolePanel.TITLE); + GUIUtilities.closeDockedComponent(console.getFrameTitle(), SwingConstants.SOUTH); return true; } @@ -65,18 +64,3 @@ public boolean handleCommand(Console console, String command) { } } - - - - - - - - - - - - - - - diff --git a/src/org/executequery/gui/databaseobjects/AbstractCreateObjectPanel.java b/src/org/executequery/gui/databaseobjects/AbstractCreateObjectPanel.java index 431bc2909..a5cfcfedb 100644 --- a/src/org/executequery/gui/databaseobjects/AbstractCreateObjectPanel.java +++ b/src/org/executequery/gui/databaseobjects/AbstractCreateObjectPanel.java @@ -8,7 +8,6 @@ import org.executequery.databaseobjects.DatabaseTable; import org.executequery.databaseobjects.NamedObject; import org.executequery.databaseobjects.impl.*; -import org.executequery.datasource.ConnectionManager; import org.executequery.gui.ActionContainer; import org.executequery.gui.BaseDialog; import org.executequery.gui.ExecuteQueryDialog; @@ -24,7 +23,7 @@ import org.executequery.gui.text.SimpleSqlTextPanel; import org.executequery.localization.Bundles; import org.executequery.log.Log; -import org.underworldlabs.swing.DynamicComboBoxModel; +import org.underworldlabs.swing.ConnectionsComboBox; import org.underworldlabs.swing.UpperFilter; import org.underworldlabs.swing.layouts.GridBagHelper; import org.underworldlabs.util.MiscUtils; @@ -39,7 +38,6 @@ import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.print.Printable; -import java.util.Vector; public abstract class AbstractCreateObjectPanel extends AbstractFormObjectViewPanel { @@ -58,7 +56,7 @@ public abstract class AbstractCreateObjectPanel extends AbstractFormObjectViewPa protected JButton submitButton; protected JButton cancelButton; protected JTextField nameField; - protected JComboBox connectionsCombo; + protected ConnectionsComboBox connectionsCombo; protected SimpleCommentPanel simpleCommentPanel; protected boolean edited; @@ -125,13 +123,12 @@ private void initBase() { // --- connections comboBox --- - Vector connections = ConnectionManager.getActiveConnections(); - connectionsCombo = WidgetFactory.createComboBox("connectionsCombo", new DynamicComboBoxModel(connections)); + connectionsCombo = WidgetFactory.createConnectionComboBox("connectionsCombo", true); connectionsCombo.addItemListener(this::connectionChanged); connectionsCombo.setEnabled(parent != null); if (connection == null) - connection = (DatabaseConnection) connectionsCombo.getSelectedItem(); + connection = getSelectedConnection(); else connectionsCombo.setSelectedItem(connection); @@ -264,7 +261,10 @@ public static AbstractCreateObjectPanel getEditPanelFromType(int type, DatabaseC return new CreateGeneratorPanel(dc, null, (DefaultDatabaseSequence) databaseObject); case NamedObject.PACKAGE: - return new CreatePackagePanel(dc, null, (DefaultDatabasePackage) databaseObject); + return new CreatePackagePanel(dc, null, (DefaultDatabasePackage) databaseObject, false); + + case NamedObject.SYSTEM_PACKAGE: + return new CreatePackagePanel(dc, null, (DefaultDatabasePackage) databaseObject, true); case NamedObject.EXCEPTION: return new CreateExceptionPanel(dc, null, (DefaultDatabaseException) databaseObject); @@ -297,7 +297,7 @@ private void connectionChanged(ItemEvent e) { if (e.getStateChange() == ItemEvent.DESELECTED) return; - connection = (DatabaseConnection) connectionsCombo.getSelectedItem(); + connection = getSelectedConnection(); sender.setDatabaseConnection(connection); } @@ -413,6 +413,17 @@ protected static String getEditTitle(int type) { return Bundles.get(BrowserTreePopupMenu.class, "edit", Bundles.get(BrowserTreePopupMenu.class, NamedObject.META_TYPES_FOR_BUNDLE[type])); } + protected void hideButtons() { + editButton.setVisible(false); + actionButton.setVisible(false); + submitButton.setVisible(false); + cancelButton.setVisible(false); + } + + protected DatabaseConnection getSelectedConnection() { + return connectionsCombo.getSelectedConnection(); + } + @Override public void cleanup() { super.cleanup(); diff --git a/src/org/executequery/gui/databaseobjects/CreateFunctionPanel.java b/src/org/executequery/gui/databaseobjects/CreateFunctionPanel.java index ae663675a..6ec2719b1 100644 --- a/src/org/executequery/gui/databaseobjects/CreateFunctionPanel.java +++ b/src/org/executequery/gui/databaseobjects/CreateFunctionPanel.java @@ -21,6 +21,7 @@ import java.sql.DatabaseMetaData; import java.sql.ResultSet; import java.sql.SQLException; +import java.util.Comparator; import java.util.List; import java.util.Objects; import java.util.Vector; @@ -60,7 +61,7 @@ protected void init() { // --- return type components --- deterministicCheck = WidgetFactory.createCheckBox("deterministicCheck", bundleStaticString("deterministic")); - deterministicCheck.addActionListener(e -> generateDdlScript()); + deterministicCheck.addActionListener(e -> generateDdlScript(false)); useDomainTypeCheck = WidgetFactory.createCheckBox("useDomainTypeCheck", bundledString("useDomainTypeCheck")); useDomainTypeCheck.addActionListener(e -> domainCheckTriggered()); @@ -152,6 +153,35 @@ protected String getFullSourceBody() { return result; } + @Override + protected String getUpperScript() { + Vector variables = null; + if (isParseVariables()) { + variables = new Vector<>(); + variables.addAll(variablesPanel.getProcedureParameterModel().getTableVector()); + variables.addAll(cursorsPanel.getCursorsVector()); + variables.addAll(subProgramPanel.getSubProgsVector()); + } + return SQLUtils.generateUpperCreateFunctionScript(nameField.getText(), + externalField.getText(), + engineField.getText(), + inputParamsPanel.getProcedureParameterModel().getTableVector(), + variables, + (String) securityCombo.getSelectedItem(), + returnType, + deterministicCheck != null && deterministicCheck.isSelected(), + connection); + } + + @Override + protected String getDownScript() { + return SQLUtils.generateDownCreateFunctionScript(nameField.getText(), + simpleCommentPanel.getComment(), + inputParamsPanel.getProcedureParameterModel().getTableVector(), + true, + connection); + } + @Override protected void loadParameters() { try { @@ -182,6 +212,13 @@ protected String generateQuery() { Vector variables = new Vector<>(); variables.addAll(variablesPanel.getProcedureParameterModel().getTableVector()); variables.addAll(cursorsPanel.getCursorsVector()); + variables.addAll(subProgramPanel.getSubProgsVector()); + variables.sort(new Comparator() { + @Override + public int compare(ColumnData o1, ColumnData o2) { + return Integer.compare(o1.getColumnPosition(), o2.getColumnPosition()); + } + }); return SQLUtils.generateCreateFunction( nameField.getText(), @@ -276,7 +313,7 @@ private void domainChanged() { returnType.setDomain(selectedDomain.getName()); typePanel.refresh(false); - generateDdlScript(); + generateDdlScript(false); } private List getDomains() { diff --git a/src/org/executequery/gui/databaseobjects/CreateIndexPanel.java b/src/org/executequery/gui/databaseobjects/CreateIndexPanel.java index 28882d8b3..c25d7beb8 100644 --- a/src/org/executequery/gui/databaseobjects/CreateIndexPanel.java +++ b/src/org/executequery/gui/databaseobjects/CreateIndexPanel.java @@ -4,7 +4,6 @@ import org.executequery.databaseobjects.NamedObject; import org.executequery.databaseobjects.Types; import org.executequery.databaseobjects.impl.DefaultDatabaseIndex; -import org.executequery.databaseobjects.impl.DefaultDatabaseMetaTag; import org.executequery.databaseobjects.impl.DefaultDatabaseTablespace; import org.executequery.gui.ActionContainer; import org.executequery.gui.browser.ColumnData; @@ -62,6 +61,12 @@ public CreateIndexPanel(DatabaseConnection dc, ActionContainer dialog, DefaultDa super(dc, dialog, index); } + public CreateIndexPanel(DatabaseConnection dc, ActionContainer dialog, DefaultDatabaseIndex index, boolean isSystem) { + super(dc, dialog, index); + if (isSystem) + hideButtons(); + } + public CreateIndexPanel(DatabaseConnection dc, ActionContainer dialog, DefaultDatabaseIndex index, String tableName) { super(dc, dialog, index, new Object[]{tableName}); } @@ -148,8 +153,6 @@ protected void init() { protected void initEdited() { nameField.setText(databaseIndex.getName().trim()); - DefaultDatabaseMetaTag metaTag = new DefaultDatabaseMetaTag(databaseIndex.getHost(), NamedObject.META_TYPES[NamedObject.INDEX]); - databaseIndex = metaTag.getIndexFromName(databaseIndex.getName()); nameField.setEditable(false); simpleCommentPanel.setDatabaseObject(databaseIndex); @@ -178,7 +181,7 @@ public void changedUpdate(DocumentEvent e) { } } - if (databaseIndex.getExpression() == null) { + if (MiscUtils.isNull(databaseIndex.getExpression())) { for (int i = 0; i < databaseIndex.getIndexColumns().size(); i++) { DefaultDatabaseIndex.DatabaseIndexColumn column = databaseIndex.getIndexColumns().get(i); diff --git a/src/org/executequery/gui/databaseobjects/CreateJobPanel.java b/src/org/executequery/gui/databaseobjects/CreateJobPanel.java index d7df9f8b9..93de4b41c 100644 --- a/src/org/executequery/gui/databaseobjects/CreateJobPanel.java +++ b/src/org/executequery/gui/databaseobjects/CreateJobPanel.java @@ -1,6 +1,5 @@ package org.executequery.gui.databaseobjects; -import org.executequery.Constants; import org.executequery.databasemediators.DatabaseConnection; import org.executequery.databaseobjects.NamedObject; import org.executequery.databaseobjects.impl.DefaultDatabaseJob; @@ -26,7 +25,7 @@ public class CreateJobPanel extends AbstractCreateObjectPanel { private DefaultDatabaseJob job; - // --- GUI ccomponents --- + // --- GUI components --- private TimestampPicker startDatePicker; private TimestampPicker endDatePicker; @@ -81,7 +80,7 @@ protected void init() { tabbedPane.add(bundleString("Task"), taskPanel); tabbedPane.add(bundleString("Schedule"), cronPanel); -// addCommentTab(null); RDB doesn't support adding comments on the JOBs + addCommentTab(null); if (!editing) arrange(); @@ -99,7 +98,7 @@ protected void initEdited() { reset(); arrange(); -// simpleCommentPanel.setDatabaseObject(job); RDB doesn't support adding comments on the JOBs + simpleCommentPanel.setDatabaseObject(job); nameField.setEditable(false); tabbedPane.addTab(bundleString("Log"), new JobsLogPanel(job)); addCreateSqlTab(job); @@ -159,9 +158,8 @@ private void arrange() { topPanel.add(endDatePicker, topGbh.nextCol().setMaxWeightX().topGap(0).rightGap(5).spanX().get()); if (parent != null) { - int height = System.getProperty("os.name").toLowerCase().contains("win") ? 450 : 420; - ((BaseDialog) parent).setPreferredSize(new Dimension(700, height)); - ((BaseDialog) parent).setResizable(false); + ((BaseDialog) parent).setPreferredSize(new Dimension(700, 450)); + parent.setResizable(false); } } @@ -217,7 +215,7 @@ private String getGenerateCreateQuery() { jobTypeCombo.getSelectedIndex() == DefaultDatabaseJob.PSQL_TYPE ? sqlTextPanel.getSQLText() : bashTextPanel.getTextAreaComponent().getText(), - Constants.EMPTY, + simpleCommentPanel.getComment(), false, getDatabaseConnection() ); @@ -239,7 +237,7 @@ private String getGenerateAlterQuery() { jobTypeCombo.getSelectedIndex() == DefaultDatabaseJob.PSQL_TYPE ? sqlTextPanel.getSQLText() : bashTextPanel.getTextAreaComponent().getText(), - Constants.EMPTY, + simpleCommentPanel.getComment(), false ); } diff --git a/src/org/executequery/gui/databaseobjects/CreatePackagePanel.java b/src/org/executequery/gui/databaseobjects/CreatePackagePanel.java index 22002a25f..b511294c8 100644 --- a/src/org/executequery/gui/databaseobjects/CreatePackagePanel.java +++ b/src/org/executequery/gui/databaseobjects/CreatePackagePanel.java @@ -19,11 +19,14 @@ public class CreatePackagePanel extends AbstractCreateObjectPanel { private DefaultDatabasePackage databasePackage; public CreatePackagePanel(DatabaseConnection dc, ActionContainer dialog) { - this(dc, dialog, null); + this(dc, dialog, null, false); } - public CreatePackagePanel(DatabaseConnection dc, ActionContainer dialog, DefaultDatabasePackage databaseObject) { + public CreatePackagePanel(DatabaseConnection dc, ActionContainer dialog, DefaultDatabasePackage databaseObject, boolean isSystem) { super(dc, dialog, databaseObject); + + if (isSystem) + hideButtons(); } @Override @@ -36,11 +39,7 @@ protected void initEdited() { } protected String generateQuery() { - String sb = headerPanel.getSQLText() + "^\n" + - bodyPanel.getSQLText() + "^\n" + - SQLUtils.generateComment(getFormattedName(), "PACKAGE", - simpleCommentPanel.getComment(), "^", true, getDatabaseConnection()); - return sb; + return SQLUtils.generateCreatePackage(nameField.getText(), headerPanel.getSQLText(), bodyPanel.getSQLText(), simpleCommentPanel.getComment(), getDatabaseConnection()); } @Override @@ -53,7 +52,7 @@ protected void reset() { @Override public void createObject() { - displayExecuteQueryDialog(generateQuery(), "^"); + displayExecuteQueryDialog(generateQuery(), ";"); } @Override @@ -92,6 +91,7 @@ public void insertUpdate(DocumentEvent e) { public void removeUpdate(DocumentEvent e) { changeName(); } + @Override public void changedUpdate(DocumentEvent e) { changeName(); @@ -102,24 +102,13 @@ public void changedUpdate(DocumentEvent e) { tabbedPane.add(bundleString("Body"), bodyPanel); addCommentTab(null); - String sqlTemplate = getFormattedName() + "\nAS" + "\nBEGIN" + "\n\nEND"; - headerPanel.setSQLText("CREATE OR ALTER PACKAGE " + sqlTemplate); - bodyPanel.setSQLText("RECREATE PACKAGE BODY " + sqlTemplate); + String sqlTemplate = "BEGIN" + "\n\nEND"; + headerPanel.setSQLText(sqlTemplate); + bodyPanel.setSQLText(sqlTemplate); } private void changeName() { - String sqlText = headerPanel.getSQLText().trim() - .replaceAll("PACKAGE\\s+((\".*\")|(\\w*\\$?\\w*\\b)|)", - "PACKAGE " + getFormattedName().replace("$", "\\$")) - .replace("PACKAGE " + getFormattedName().replace("$", "\\$"), "PACKAGE " + getFormattedName()); - headerPanel.setSQLText(sqlText); - - sqlText = bodyPanel.getSQLText().trim() - .replaceAll("PACKAGE BODY\\s+((\".*\")|(\\w*\\$?\\w*\\b)|)", - "PACKAGE BODY " + getFormattedName().replace("$", "\\$")) - .replace("PACKAGE BODY " + getFormattedName().replace("$", "\\$"), "PACKAGE BODY " + getFormattedName()); - bodyPanel.setSQLText(sqlText); } } diff --git a/src/org/executequery/gui/databaseobjects/CreateProcedurePanel.java b/src/org/executequery/gui/databaseobjects/CreateProcedurePanel.java index a336a5734..5e26ef9c7 100644 --- a/src/org/executequery/gui/databaseobjects/CreateProcedurePanel.java +++ b/src/org/executequery/gui/databaseobjects/CreateProcedurePanel.java @@ -20,6 +20,7 @@ import java.sql.DatabaseMetaData; import java.sql.SQLException; +import java.util.Comparator; import java.util.List; import java.util.Vector; @@ -52,7 +53,7 @@ protected String getFullSourceBody() { String fullProcedureBody = null; try { - DatabaseConnection connection = (DatabaseConnection) connectionsCombo.getSelectedItem(); + DatabaseConnection connection = getSelectedConnection(); host = new DatabaseObjectFactoryImpl().createDatabaseHost(connection); DatabaseMetaData databaseMetadata = ((PooledDatabaseMetaData) host.getDatabaseMetaData()).getInner(); @@ -75,6 +76,36 @@ protected String getFullSourceBody() { return fullProcedureBody; } + @Override + protected String getUpperScript() { + Vector variables = null; + if (isParseVariables()) { + variables = new Vector<>(); + variables.addAll(variablesPanel.getProcedureParameterModel().getTableVector()); + variables.addAll(cursorsPanel.getCursorsVector()); + variables.addAll(subProgramPanel.getSubProgsVector()); + } + return SQLUtils.generateUpperCreateProcedureScript(nameField.getText(), + externalField.getText(), + engineField.getText(), + inputParamsPanel.getProcedureParameterModel().getTableVector(), + outputParamsPanel.getProcedureParameterModel().getTableVector(), + variables, + (String) securityCombo.getSelectedItem(), + (String) authidCombo.getSelectedItem(), + getDatabaseConnection()); + } + + @Override + protected String getDownScript() { + return SQLUtils.generateDownCreateProcedureScript(nameField.getText(), + simpleCommentPanel.getComment(), + inputParamsPanel.getProcedureParameterModel().getTableVector(), + outputParamsPanel.getProcedureParameterModel().getTableVector(), + true, + connection); + } + @Override protected void loadParameters() { inputParamsPanel.clearRows();// remove first empty row @@ -103,6 +134,13 @@ protected String generateQuery() { Vector vars = new Vector<>(); vars.addAll(variablesPanel.getProcedureParameterModel().getTableVector()); vars.addAll(cursorsPanel.getCursorsVector()); + vars.addAll(subProgramPanel.getSubProgsVector()); + vars.sort(new Comparator() { + @Override + public int compare(ColumnData o1, ColumnData o2) { + return Integer.compare(o1.getColumnPosition(), o2.getColumnPosition()); + } + }); return SQLUtils.generateCreateProcedure( nameField.getText(), diff --git a/src/org/executequery/gui/databaseobjects/CreateTablespacePanel.java b/src/org/executequery/gui/databaseobjects/CreateTablespacePanel.java index 09bd8ca54..236608b24 100644 --- a/src/org/executequery/gui/databaseobjects/CreateTablespacePanel.java +++ b/src/org/executequery/gui/databaseobjects/CreateTablespacePanel.java @@ -16,15 +16,18 @@ import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; import java.io.File; public class CreateTablespacePanel extends AbstractCreateObjectPanel { + public static final String CREATE_TITLE = getCreateTitle(NamedObject.TABLESPACE); public static final String EDIT_TITLE = getEditTitle(NamedObject.TABLESPACE); - private JTextField fileField; + + private DefaultDatabaseTablespace tablespace; + private JButton fileButton; + private JTextField fileField; + private FileChooserDialog fileChooser; private SimpleSqlTextPanel sqlTextPanel; public CreateTablespacePanel(DatabaseConnection dc, ActionContainer dialog) { @@ -35,69 +38,21 @@ public CreateTablespacePanel(DatabaseConnection dc, ActionContainer dialog, Obje super(dc, dialog, databaseObject); } - public CreateTablespacePanel(DatabaseConnection dc, ActionContainer dialog, Object databaseObject, Object[] params) { - super(dc, dialog, databaseObject, params); - } - @Override protected void init() { - sqlTextPanel = new SimpleSqlTextPanel(); + fileField = new JTextField(); + fileChooser = new FileChooserDialog(); + sqlTextPanel = new SimpleSqlTextPanel(); + fileButton = new JButton("..."); - fileButton.addActionListener(new ActionListener() { - final FileChooserDialog fileChooser = new FileChooserDialog(); + fileButton.addActionListener(e -> browseFile()); - @Override - public void actionPerformed(ActionEvent e) { - int returnVal = fileChooser.showOpenDialog(fileButton); - if (returnVal == JFileChooser.APPROVE_OPTION) { - File file = fileChooser.getSelectedFile(); - fileField.setText(file.getAbsolutePath()); - } - } - }); - GridBagHelper gbh = new GridBagHelper(); - gbh.setDefaults(new GridBagConstraints( - 0, 0, 1, 1, 0, 0, - GridBagConstraints.NORTHWEST, - GridBagConstraints.HORIZONTAL, - new Insets(5, 5, 5, 5), 0, 0)); - gbh.defaults(); - centralPanel.setLayout(new GridBagLayout()); - centralPanel.add(new JLabel(Bundles.getCommon("file")), gbh.nextRowFirstCol().setLabelDefault().get()); - centralPanel.add(fileField, gbh.nextCol().setMaxWeightX().fillHorizontally().get()); - centralPanel.add(fileButton, gbh.nextCol().setLabelDefault().get()); tabbedPane.add("SQL", sqlTextPanel); + addCommentTab(null); - nameField.getDocument().addDocumentListener(new DocumentListener() { - @Override - public void insertUpdate(DocumentEvent e) { - generateSQL(); - } - @Override - public void removeUpdate(DocumentEvent e) { - generateSQL(); - } - @Override - public void changedUpdate(DocumentEvent e) { - generateSQL(); - } - }); - fileField.getDocument().addDocumentListener(new DocumentListener() { - @Override - public void insertUpdate(DocumentEvent e) { - generateSQL(); - } - @Override - public void removeUpdate(DocumentEvent e) { - generateSQL(); - } - @Override - public void changedUpdate(DocumentEvent e) { - generateSQL(); - } - }); - + arrange(); + addListeners(); generateSQL(); } @@ -105,39 +60,68 @@ public void changedUpdate(DocumentEvent e) { protected void initEdited() { reset(); nameField.setEditable(false); + DependPanel tablesIndexesPanel = new DependPanel(TreePanel.TABLESPACE); tablesIndexesPanel.setDatabaseObject(tablespace); tablesIndexesPanel.setDatabaseConnection(tablespace.getHost().getDatabaseConnection()); + tabbedPane.insertTab(Bundles.getCommon("contents"), null, new JScrollPane(tablesIndexesPanel), null, 0); + addCreateSqlTab(tablespace); tabbedPane.setSelectedIndex(0); + simpleCommentPanel.setDatabaseObject(tablespace); } - protected void reset() { - nameField.setText(tablespace.getName()); - fileField.setText(tablespace.getFileName()); - generateSQL(); + private void arrange() { + + centralPanel.setLayout(new GridBagLayout()); + + GridBagHelper gbh = new GridBagHelper().setInsets(5, 3, 0, 0).anchorNorthWest().fillHorizontally(); + centralPanel.add(new JLabel(Bundles.getCommon("file")), gbh.nextRowFirstCol().get()); + centralPanel.add(fileField, gbh.nextCol().topGap(0).setMaxWeightX().get()); + centralPanel.add(fileButton, gbh.nextCol().rightGap(5).setMinWeightX().get()); } @Override protected String generateQuery() { - return editing ? - SQLUtils.generateAlterTablespace(nameField.getText(), fileField.getText(), getDatabaseConnection()) : - SQLUtils.generateCreateTablespace(nameField.getText(), fileField.getText(), getDatabaseConnection()); + return editing ? getGenerateAlterQuery() : getGenerateCreateQuery(); } - private void generateSQL() { - sqlTextPanel.setSQLText(generateQuery()); + private String getGenerateCreateQuery() { + return SQLUtils.generateCreateTablespace( + nameField.getText(), + fileField.getText(), + simpleCommentPanel.getComment(), + true, + getDatabaseConnection() + ); + } + + private String getGenerateAlterQuery() { + return SQLUtils.generateAlterTablespace( + nameField.getText(), + fileField.getText(), + simpleCommentPanel.getComment(), + true, + getDatabaseConnection() + ); } @Override public void createObject() { - if (tabbedPane.getSelectedComponent() != sqlTextPanel) { + if (tabbedPane.getSelectedComponent() != sqlTextPanel) generateSQL(); - } displayExecuteQueryDialog(sqlTextPanel.getSQLText(), ";"); + } + @Override + protected void reset() { + if (!editing) + return; + nameField.setText(tablespace.getName()); + fileField.setText(tablespace.getFileName()); + generateSQL(); } @Override @@ -155,8 +139,6 @@ public String getTypeObject() { return NamedObject.META_TYPES[NamedObject.TABLESPACE]; } - private DefaultDatabaseTablespace tablespace; - @Override public void setDatabaseObject(Object databaseObject) { tablespace = (DefaultDatabaseTablespace) databaseObject; @@ -164,6 +146,42 @@ public void setDatabaseObject(Object databaseObject) { @Override public void setParameters(Object[] params) { + } + + private void addListeners() { + + DocumentListener documentListener = new DocumentListener() { + + @Override + public void insertUpdate(DocumentEvent e) { + generateSQL(); + } + + @Override + public void removeUpdate(DocumentEvent e) { + generateSQL(); + } + + @Override + public void changedUpdate(DocumentEvent e) { + generateSQL(); + } + }; + nameField.getDocument().addDocumentListener(documentListener); + fileField.getDocument().addDocumentListener(documentListener); + } + + private void browseFile() { + int returnVal = fileChooser.showOpenDialog(fileButton); + if (returnVal == JFileChooser.APPROVE_OPTION) { + File file = fileChooser.getSelectedFile(); + fileField.setText(file.getAbsolutePath()); + } } + + private void generateSQL() { + sqlTextPanel.setSQLText(generateQuery()); + } + } diff --git a/src/org/executequery/gui/databaseobjects/CreateTriggerPanel.java b/src/org/executequery/gui/databaseobjects/CreateTriggerPanel.java index f80749233..9b38baabb 100644 --- a/src/org/executequery/gui/databaseobjects/CreateTriggerPanel.java +++ b/src/org/executequery/gui/databaseobjects/CreateTriggerPanel.java @@ -343,6 +343,9 @@ protected void checkExternal() { @Override protected void reset() { + if (!editing) + return; + nameField.setEditable(false); triggerTypeCombo.setEnabled(false); diff --git a/src/org/executequery/gui/drivers/AbstractDriverPanel.java b/src/org/executequery/gui/drivers/AbstractDriverPanel.java index 0aa4f30f4..f9e7bb0b6 100644 --- a/src/org/executequery/gui/drivers/AbstractDriverPanel.java +++ b/src/org/executequery/gui/drivers/AbstractDriverPanel.java @@ -49,7 +49,6 @@ import java.io.File; import java.io.IOException; import java.net.MalformedURLException; -import java.util.List; import java.util.Vector; public abstract class AbstractDriverPanel extends JPanel @@ -221,30 +220,7 @@ private JTextField textFieldWithKey(String name, String key) { } private Vector createDatabaseComboValues() { - - // retrieve the db name list - List databases = loadDatabaseDefinitions(); - - int count = databases.size() + 1; - Vector databasesVector = new Vector(count); - - // create a new list with a dummy value - for (int i = 1; i < count; i++) { - - databasesVector.add(databases.get(i - 1)); - } - - // add the dummy - databasesVector.add(0, new DatabaseDefinition( - DatabaseDefinition.INVALID_DATABASE_ID, - getString("AbstractDriverPanel.selectWithDots"))); - - return databasesVector; - } - - private List loadDatabaseDefinitions() { - - return DatabaseDefinitionCache.getDatabaseDefinitions(); + return new Vector<>(DatabaseDefinitionCache.getDatabaseDefinitions()); } public void itemStateChanged(ItemEvent e) { diff --git a/src/org/executequery/gui/editor/OpenConnectionsComboBox.java b/src/org/executequery/gui/editor/OpenConnectionsComboBox.java deleted file mode 100644 index 5788a3e79..000000000 --- a/src/org/executequery/gui/editor/OpenConnectionsComboBox.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * OpenConnectionsComboBox.java - * - * Copyright (C) 2002-2017 Takis Diakoumis - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 3 - * of the License, or any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -package org.executequery.gui.editor; - -import org.executequery.databasemediators.DatabaseConnection; -import org.underworldlabs.swing.DynamicComboBoxModel; - -import javax.swing.*; -import java.awt.event.KeyEvent; -import java.util.Vector; - -/** - * @author Takis Diakoumis - */ -final class OpenConnectionsComboBox extends JComboBox { - - private QueryEditor queryEditor; - - private DynamicComboBoxModel connectionsModel; - - OpenConnectionsComboBox(QueryEditor queryEditor, - Vector connections) { - - this.queryEditor = queryEditor; - - connectionsModel = new DynamicComboBoxModel(connections); - setModel(connectionsModel); - - if (connectionsModel.getSize() == 0) { - setEnabled(false); - } - - } - - public boolean contains(DatabaseConnection databaseConnection) { - - return connectionsModel.contains(databaseConnection); - } - - public void processKeyEvent(KeyEvent e) { - - super.processKeyEvent(e); - - if (isKeyForCaretReset(e.getKeyCode())) { - - queryEditor.resetCaretPositionToLast(); - } - } - - private boolean isKeyForCaretReset(int keyCode) { - return keyCode == KeyEvent.VK_ENTER || keyCode == KeyEvent.VK_ESCAPE; - } - - protected void attemptToFocus() { - requestFocus(); - setPopupVisible(true); - } - - protected void removeElement(DatabaseConnection databaseConnection) { - connectionsModel.removeElement(databaseConnection); - if (connectionsModel.getSize() == 0) { - setEnabled(false); - } - } - - protected void addElement(DatabaseConnection databaseConnection) { - connectionsModel.addElement(databaseConnection); - setEnabled(true); - } - -} - - - - - diff --git a/src/org/executequery/gui/editor/QueryEditor.java b/src/org/executequery/gui/editor/QueryEditor.java index 5ff888490..34cd88402 100644 --- a/src/org/executequery/gui/editor/QueryEditor.java +++ b/src/org/executequery/gui/editor/QueryEditor.java @@ -43,6 +43,7 @@ import org.japura.gui.event.ListCheckListener; import org.japura.gui.event.ListEvent; import org.underworldlabs.sqlParser.SqlParser; +import org.underworldlabs.swing.ConnectionsComboBox; import org.underworldlabs.swing.EQCheckCombox; import org.underworldlabs.swing.RolloverButton; import org.underworldlabs.swing.layouts.GridBagHelper; @@ -55,6 +56,8 @@ import java.awt.event.ActionEvent; import java.awt.event.ItemEvent; import java.awt.print.Printable; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; import java.sql.ResultSet; import java.sql.SQLException; import java.util.*; @@ -74,7 +77,8 @@ public class QueryEditor extends DefaultTabView QueryShortcutListener, UserPreferenceListener, TextEditor, - FocusablePanel { + FocusablePanel, + PropertyChangeListener { public static final String TITLE = Bundles.get(QueryEditor.class, "title"); public static final String FRAME_ICON = "icon_query_editor"; @@ -100,8 +104,8 @@ public class QueryEditor extends DefaultTabView private QueryEditorPopupMenu popup; private TransactionParametersPanel transactionParametersPanel; - private OpenConnectionsComboBox connectionsCombo; private EQCheckCombox connectionsCheckCombo; + private ConnectionsComboBox connectionsCombo; private JPanel baseEditorPanel; private JSplitPane splitPane; @@ -133,14 +137,14 @@ public class QueryEditor extends DefaultTabView private boolean executeToFile; public QueryEditor() { - this(null, null); + this(null, null, -1); } public QueryEditor(String text) { - this(text, null); + this(text, null, -1); } - public QueryEditor(String text, String absolutePath) { + public QueryEditor(String text, String absolutePath, int splitDividerLocation) { super(new GridBagLayout()); init(); @@ -162,7 +166,11 @@ public QueryEditor(String text, String absolutePath) { editorPanel.getQueryArea().setDatabaseConnection(getSelectedConnection()); } - QueryEditorHistory.addEditor(connectionID, absolutePath, queryEditorNumber); + if (splitDividerLocation > 0) + splitPane.setDividerLocation(splitDividerLocation); + + QueryEditorHistory.addEditor(connectionID, absolutePath, queryEditorNumber, splitPane.getDividerLocation()); + splitPane.addPropertyChangeListener("dividerLocation", this); isContentChanged = false; if (text != null) @@ -187,7 +195,7 @@ private void init() { // --- connection combos --- - connectionsCombo = new OpenConnectionsComboBox(this, ConnectionManager.getActiveConnections()); + connectionsCombo = WidgetFactory.createConnectionComboBox("connectionsCombo", true); connectionsCombo.setMaximumSize(new Dimension(200, 30)); connectionsCombo.addItemListener(this::connectionChanged); connectionsCombo.setVisible(!useMultipleConnections); @@ -199,7 +207,7 @@ private void init() { oldConnection = useMultipleConnections ? getSelectedConnection() : - (DatabaseConnection) connectionsCombo.getSelectedItem(); + connectionsCombo.getSelectedConnection(); // --- transaction parameters panel --- @@ -571,6 +579,17 @@ public void setLeftStatusText(String text) { statusBar.setStatus(text); } + /** + * Sets the text of the left status label. + * + * @param text the text to be set + * @param toolTip the label toolTip + * @param icon the icon to be set + */ + public void setLeftStatus(String text, String toolTip, Icon icon) { + statusBar.setStatus(text, toolTip, icon); + } + /** * Propagates the call to interrupt an executing process. */ @@ -816,13 +835,21 @@ public boolean tabViewClosing() { return false; } + if (delegate.getIDTransaction() != -1) { - int result = GUIUtilities.displayConfirmCancelDialog(bundleString("requestTransactionMessage")); + + int result = GUIUtilities.displayYesNoCancelDialog( + bundleString("requestTransactionMessage"), + bundleString("requestTransactionTitle") + ); + if (result == JOptionPane.YES_OPTION) delegate.commit(false); else if (result == JOptionPane.NO_OPTION) delegate.rollback(false); - else return false; + else + return false; + return tabViewClosing(); } @@ -846,7 +873,7 @@ else if (result == JOptionPane.NO_OPTION) QueryEditorHistory.removeFile(oldPath); scriptFile.setAbsolutePath(newPath); - QueryEditorHistory.addEditor(connectionID, getAbsolutePath(), -1); + QueryEditorHistory.addEditor(connectionID, getAbsolutePath(), -1, splitPane.getDividerLocation()); } else return false; @@ -861,13 +888,15 @@ else if (result == JOptionPane.NO_OPTION) "\n\nThe system returned:\n" + e.getMessage(), e, this.getClass()); } - String connectionID = (getSelectedConnection() != null) ? - getSelectedConnection().getId() : QueryEditorHistory.NULL_CONNECTION; - try { - QueryEditorHistory.removeEditor(connectionID, scriptFile.getAbsolutePath()); + DatabaseConnection dc = getSelectedConnection(); + if (dc == null || dc.isConnected()) { + String connectionID = dc != null ? dc.getId() : QueryEditorHistory.NULL_CONNECTION; + QueryEditorHistory.removeEditor(connectionID, scriptFile.getAbsolutePath()); + } + } catch (Exception e) { - e.printStackTrace(System.out); + Log.error(e.getMessage(), e); } return true; @@ -925,12 +954,9 @@ public DatabaseConnection getSelectedConnection() { return selectedConnections != null && !selectedConnections.isEmpty() ? (DatabaseConnection) selectedConnections.get(0) : null; - - } else { - return connectionsCombo.getSelectedIndex() != -1 ? - (DatabaseConnection) connectionsCombo.getSelectedItem() : - null; } + + return connectionsCombo.getSelectedConnection(); } public void setSelectedConnection(DatabaseConnection databaseConnection) { @@ -942,8 +968,8 @@ public void setSelectedConnection(DatabaseConnection databaseConnection) { } else if (useMultipleConnections) connectionToSelect = databaseConnection; - if (connectionsCombo.contains(databaseConnection)) { - connectionsCombo.getModel().setSelectedItem(databaseConnection); + if (connectionsCombo.hasConnection(databaseConnection)) { + connectionsCombo.setSelectedItem(databaseConnection); } else if (!useMultipleConnections) connectionToSelect = databaseConnection; @@ -1298,7 +1324,7 @@ public int save(boolean saveAs) { getSelectedConnection().getId() : QueryEditorHistory.NULL_CONNECTION; QueryEditorHistory.PathNumber editor = QueryEditorHistory.getEditor(connectionID, oldAbsolutePath); QueryEditorHistory.removeEditor(connectionID, oldAbsolutePath); - QueryEditorHistory.addEditor(connectionID, getAbsolutePath(), editor.number); + QueryEditorHistory.addEditor(connectionID, getAbsolutePath(), editor.number, splitPane.getDividerLocation()); } return SaveFunction.SAVE_COMPLETE; } @@ -1377,29 +1403,21 @@ public void cleanup() { public void connected(ConnectionEvent connectionEvent) { if (!isQueryEditorClosed) { - -// if (connectionsCombo.getModel().getSize() == 0) -// connectionsCombo.addElement(null); - - connectionsCombo.addElement(connectionEvent.getDatabaseConnection()); connectionsCheckCombo.getModel().addElement(connectionEvent.getDatabaseConnection()); DatabaseConnection databaseConnection = connectionEvent.getDatabaseConnection(); if (databaseConnection == connectionToSelect) { connectionsCheckCombo.getModel().addCheck(databaseConnection); - connectionsCombo.getModel().setSelectedItem(databaseConnection); + connectionsCombo.setSelectedItem(databaseConnection); connectionToSelect = null; } } - } @Override public void disconnected(ConnectionEvent connectionEvent) { - if (!isQueryEditorClosed) { + if (!isQueryEditorClosed) connectionsCheckCombo.getModel().removeElement(connectionEvent.getDatabaseConnection()); - connectionsCombo.removeElement(connectionEvent.getDatabaseConnection()); - } } // --------------------------------------------- @@ -1533,4 +1551,18 @@ private void connectionChanged() { transactionParametersPanel.setDatabaseConnection(getSelectedConnection()); } + // --- PropertyChangeListener impl --- + + @Override + public void propertyChange(PropertyChangeEvent evt) { + + DatabaseConnection dc = getSelectedConnection(); + String oldAbsolutePath = scriptFile.getAbsolutePath(); + String connectionID = dc != null ? dc.getId() : QueryEditorHistory.NULL_CONNECTION; + + QueryEditorHistory.PathNumber editor = QueryEditorHistory.getEditor(connectionID, oldAbsolutePath); + QueryEditorHistory.removeEditor(connectionID, oldAbsolutePath); + QueryEditorHistory.addEditor(connectionID, getAbsolutePath(), editor.number, splitPane.getDividerLocation()); + } + } diff --git a/src/org/executequery/gui/editor/QueryEditorHistory.java b/src/org/executequery/gui/editor/QueryEditorHistory.java index b36fd40fe..bc64c54c6 100644 --- a/src/org/executequery/gui/editor/QueryEditorHistory.java +++ b/src/org/executequery/gui/editor/QueryEditorHistory.java @@ -1,8 +1,10 @@ package org.executequery.gui.editor; +import org.executequery.Constants; import org.executequery.GUIUtilities; import org.executequery.databasemediators.DatabaseConnection; import org.executequery.gui.editor.autocomplete.Parameter; +import org.executequery.log.Log; import org.executequery.util.SystemResources; import org.underworldlabs.util.FileUtils; import org.underworldlabs.util.SystemProperties; @@ -32,9 +34,8 @@ public static Map> getHistoryParameters() { return historyParameters; } - public static void addEditor(String connectionID, String editor, int number) { - addEditor(connectionID, new PathNumber(editor, number)); - + public static void addEditor(String connectionID, String editor, int number, int splitDividerLocation) { + addEditor(connectionID, new PathNumber(editor, number, splitDividerLocation)); } public static void addEditor(String connectionID, PathNumber pathNumber) { @@ -82,11 +83,11 @@ private static int indexOfEditor(String editor, List list) { return -1; } - public static void changedConnectionEditor(String oldConnectionID, String newConnectionID, String editor) { - int number = getEditors(oldConnectionID).get(indexOfEditor(editor, getEditors(oldConnectionID))).number; + PathNumber pathNumber = getEditors(oldConnectionID).get(indexOfEditor(editor, getEditors(oldConnectionID))); + removeEditor(oldConnectionID, editor); - addEditor(newConnectionID, editor, number); + addEditor(newConnectionID, editor, pathNumber.number, pathNumber.splitDividerLocation); } public static List getEditors(DatabaseConnection connection) { @@ -158,10 +159,10 @@ private static void loadEditors() { String[] strings = strLine.split(";"); if (!editors.containsKey(strings[0])) editors.put(strings[0], new ArrayList<>()); - editors.get(strings[0]).add(new PathNumber(strings[1], Integer.parseInt(strings[2]))); + editors.get(strings[0]).add(new PathNumber(strings[1], Integer.parseInt(strings[2]), Integer.parseInt(strings[3]))); } } catch (IOException e) { - e.printStackTrace(); + Log.error(e.getMessage(), e); } } @@ -180,22 +181,27 @@ private static void loadNumbers() { } private static void saveEditors() { - //Log.printStackTrace(); + + String charset = SystemProperties.getProperty("user", "system.file.encoding"); + if (charset == null) + charset = Constants.EMPTY; + try { FileOutputStream fileOutputStream = new FileOutputStream(historyFile(), false); - Writer writer = new OutputStreamWriter(fileOutputStream, SystemProperties.getProperty("user", "system.file.encoding")); - //int g = 0; + Writer writer = new OutputStreamWriter(fileOutputStream, charset); + for (String key : editors().keySet()) { - List list = editors().get(key); - for (int i = 0; i < list.size(); i++) { - //Log.info(g+";"+i+";"+key+";"+list.get(i).path+";"+list.get(i).number); - writer.append(key + ";" + list.get(i).path + ";" + list.get(i).number + "\n"); + for (PathNumber pathNumber : editors().get(key)) { + writer.append(key).append(";") + .append(pathNumber.path).append(";") + .append(String.valueOf(pathNumber.number)).append(";") + .append(String.valueOf(pathNumber.splitDividerLocation)).append("\n"); } - //g++; } writer.flush(); + } catch (IOException e) { - e.printStackTrace(); + Log.error(e.getMessage(), e); } } @@ -271,7 +277,7 @@ public static void restoreTabs(DatabaseConnection connection) { File file = new File(copy.get(i).path); if (file.exists()) { String contents = FileUtils.loadFile(file, encoding); - QueryEditor queryEditor = new QueryEditor(contents, copy.get(i).path); + QueryEditor queryEditor = new QueryEditor(contents, copy.get(i).path, copy.get(i).splitDividerLocation); if (connection != null) queryEditor.setSelectedConnection(connection); GUIUtilities.addCentralPane(QueryEditor.TITLE, @@ -280,7 +286,7 @@ public static void restoreTabs(DatabaseConnection connection) { null, true); } else { - QueryEditor queryEditor = new QueryEditor("", copy.get(i).path); + QueryEditor queryEditor = new QueryEditor("", copy.get(i).path, copy.get(i).splitDividerLocation); if (connection != null) queryEditor.setSelectedConnection(connection); GUIUtilities.addCentralPane(QueryEditor.TITLE, @@ -296,12 +302,16 @@ public static void restoreTabs(DatabaseConnection connection) { } public static class PathNumber { + private final int splitDividerLocation; public String path; public int number; - public PathNumber(String path, int number) { + public PathNumber(String path, int number, int splitDividerLocation) { this.path = path; this.number = number; + this.splitDividerLocation = splitDividerLocation; } - } + + } // PathNumber class + } diff --git a/src/org/executequery/gui/editor/QueryEditorResultsPanel.java b/src/org/executequery/gui/editor/QueryEditorResultsPanel.java index 76c3183b9..16293fe90 100644 --- a/src/org/executequery/gui/editor/QueryEditorResultsPanel.java +++ b/src/org/executequery/gui/editor/QueryEditorResultsPanel.java @@ -37,6 +37,7 @@ import org.underworldlabs.swing.plaf.TabRolloverEvent; import org.underworldlabs.swing.plaf.TabSelectionListener; import org.underworldlabs.util.MiscUtils; +import org.underworldlabs.util.SystemProperties; import javax.swing.*; import javax.swing.event.ChangeEvent; @@ -89,10 +90,13 @@ public class QueryEditorResultsPanel extends SimpleCloseTabbedPane private static final String SUCCESS = bundleString("SUCCESS"); private static final String NO_ROWS = bundleString("NO_ROWS"); private static final String SUCCESS_NO_ROWS = SUCCESS + "\n" + NO_ROWS; - private static final String ZERO_ROWS = bundleString("ZERO_ROWS"); - private static final String SPACE = " "; - private static final String ROW_RETURNED = bundleString("ROW_RETURNED"); - private static final String ROWS_RETURNED = bundleString("ROWS_RETURNED"); + + private static final Icon WARNING_ICON = IconManager.getIcon( + "icon_warning_animated", + "gif", + 20, + IconManager.IconFolder.BASE + ); private ResultSetTableColumnResizingManager resultSetTableColumnResizingManager; @@ -505,23 +509,27 @@ private Icon resulSetTabIcon() { */ private void resetEditorRowCount(int rowCount) { - if (queryEditor != null) { - - if (rowCount > 1) { - - queryEditor.setLeftStatusText(SPACE + rowCount + " " + ROWS_RETURNED); + if (queryEditor == null) + return; - } else if (rowCount == 1) { + String text = bundleString("ZERO_ROWS"); + if (rowCount > 1) { + text = bundleString("ROWS_RETURNED", rowCount); - queryEditor.setLeftStatusText(SPACE + rowCount + " " + ROW_RETURNED); + } else if (rowCount == 1) + text = bundleString("ROW_RETURNED", rowCount); - } else { + boolean isRowsCountLimited = SystemProperties.getBooleanProperty("user", "editor.limit.records.count"); + if (isRowsCountLimited) { - queryEditor.setLeftStatusText(ZERO_ROWS); + int limit = SystemProperties.getIntProperty("user", "editor.max.records.count"); + if (limit <= rowCount) { + queryEditor.setLeftStatus(text, bundleString("LIMIT_ON", limit), WARNING_ICON); + return; } - } + queryEditor.setLeftStatusText(text); } private int getResultSetRowCount(ResultSetTableModel model, boolean showRowNumber) { @@ -896,10 +904,8 @@ public boolean isTransposeAvailable() { return true; } - private static String bundleString(String key) { - return Bundles.get(QueryEditorResultsPanel.class, key); + private static String bundleString(String key, Object... args) { + return Bundles.get(QueryEditorResultsPanel.class, key, args); } } - - diff --git a/src/org/executequery/gui/editor/QueryEditorStatusBar.java b/src/org/executequery/gui/editor/QueryEditorStatusBar.java index d0c8fa879..d4bc43639 100644 --- a/src/org/executequery/gui/editor/QueryEditorStatusBar.java +++ b/src/org/executequery/gui/editor/QueryEditorStatusBar.java @@ -125,7 +125,16 @@ public void setInsertionMode(String text) { * Sets the editor status to the text specified. */ public void setStatus(String text) { + setStatus(text, null, null); + } + + /** + * Sets the editor status to the text specified. + */ + public void setStatus(String text, String toolTip, Icon icon) { + setLabelIcon(0, icon); setLabelText(0, text); + setLabelToolTip(0, toolTip); } /** diff --git a/src/org/executequery/gui/editor/ResultSetTablePopupMenu.java b/src/org/executequery/gui/editor/ResultSetTablePopupMenu.java index a4c43cbed..2b2513d6a 100644 --- a/src/org/executequery/gui/editor/ResultSetTablePopupMenu.java +++ b/src/org/executequery/gui/editor/ResultSetTablePopupMenu.java @@ -102,7 +102,7 @@ public ResultSetTablePopupMenu( // the cell opens checkBox menu-item cellOpensDialog = MenuItemFactory.createCheckBoxMenuItem(reflectiveAction); cellOpensDialog.setText(bundleString("Double-ClickOpensItemView")); - cellOpensDialog.setSelected(doubleClickCellOpensDialog()); + cellOpensDialog.setSelected(doubleClickCellOpensDialog); cellOpensDialog.setActionCommand("cellOpensDialog"); // the auto column width menu-item @@ -422,9 +422,8 @@ public void mousePressed(MouseEvent e) { @Override public void mouseClicked(MouseEvent e) { - if (e.getClickCount() >= 2 && - (doubleClickCellOpensDialog || table.getValueAt(table.getSelectedRow(), table.getSelectedColumn()) instanceof LobRecordDataItem) - ) { + boolean isLob = table.getValueAt(table.getSelectedRow(), table.getSelectedColumn()) instanceof LobRecordDataItem; + if (e.getClickCount() >= 2 && (doubleClickCellOpensDialog || isLob)) { lastPopupPoint = e.getPoint(); openDataItemViewer(); } diff --git a/src/org/executequery/gui/editor/SQLHistoryDialog.java b/src/org/executequery/gui/editor/SQLHistoryDialog.java index e28dddf72..953ee89b5 100644 --- a/src/org/executequery/gui/editor/SQLHistoryDialog.java +++ b/src/org/executequery/gui/editor/SQLHistoryDialog.java @@ -22,8 +22,6 @@ import org.executequery.Constants; import org.executequery.GUIUtilities; -import org.executequery.gui.DefaultList; -import org.executequery.gui.DefaultPanelButton; import org.executequery.gui.WidgetFactory; import org.executequery.gui.text.SQLTextArea; import org.executequery.localization.Bundles; @@ -31,14 +29,11 @@ import org.executequery.repository.SqlCommandHistoryRepository; import org.underworldlabs.swing.AbstractBaseDialog; import org.underworldlabs.swing.FlatSplitPane; +import org.underworldlabs.swing.layouts.GridBagHelper; import org.underworldlabs.util.MiscUtils; import javax.swing.*; -import javax.swing.event.ListSelectionEvent; -import javax.swing.event.ListSelectionListener; import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import java.util.Vector; @@ -58,273 +53,194 @@ * * @author Takis Diakoumis */ -public class SQLHistoryDialog extends AbstractBaseDialog - implements ActionListener, - ListSelectionListener { +public class SQLHistoryDialog extends AbstractBaseDialog { - private JList historyList; + private static final String TITLE = bundleString("title"); - private Vector data; - - private QueryEditor queryEditor; + // --- GUI components --- + private SQLTextArea textPane; private JTextField searchField; + private JCheckBox openNewEditorCheck; + private JList historyList; - private JCheckBox newEditorCheck; + private JButton copyButton; + private JButton clearButton; + private JButton cancelButton; + private JButton selectButton; + private JButton insertButton; + private JButton searchButton; - private SQLTextArea textPane; + // --- + + private Vector data; + private final QueryEditor queryEditor; - /** - * Creates a new object with history data - * to be set within the specified editor. - * - * @param - the statement history Vector - * @param - the editor - */ public SQLHistoryDialog(Vector data, QueryEditor queryEditor) { + super(GUIUtilities.getParentFrame(), TITLE, true); + this.queryEditor = queryEditor; + this.data = data; - super(GUIUtilities.getParentFrame(), "SQL Command History", true); + init(); + arrange(); + } - try { + private void init() { - this.data = data; - this.queryEditor = queryEditor; + // --- buttons --- - initHistoryList(data); + selectButton = WidgetFactory.createButton("selectButton", Bundles.get("common.select.button"), e -> selectQuery()); + selectButton.setToolTipText(bundleString("selectButton.toolTip")); - init(); - pack(); + copyButton = WidgetFactory.createButton("copyButton", Bundles.get("common.copy.button"), e -> copyQuery()); + copyButton.setToolTipText(bundleString("copyButton.toolTip")); - setLocation(GUIUtilities.getLocationForDialog(getSize())); - setVisible(true); + clearButton = WidgetFactory.createButton("clearButton", Bundles.get("common.clear.button"), e -> clearHistory()); + clearButton.setToolTipText(bundleString("clearButton.toolTip")); - } catch (Exception e) { + insertButton = WidgetFactory.createButton("insertButton", bundleString("insertButton"), e -> insertQuery()); + insertButton.setToolTipText(bundleString("insertButton.toolTip")); - e.printStackTrace(); - } + searchButton = WidgetFactory.createButton("searchButton", Bundles.get("common.search.button"), e -> searchForQuery()); + searchButton.setToolTipText(bundleString("searchButton.toolTip")); - } + cancelButton = WidgetFactory.createButton("cancelButton", Bundles.get("common.cancel.button"), e -> dispose()); - /** - *

Initialises the state of this instance - * and positions all components. - * - * @throws Exception - */ - private void init() { - - JButton cancelButton = createButton(Bundles.get("common.cancel.button"), null); - cancelButton.setActionCommand("Cancel"); - JButton selectButton = createButton(Bundles.get("common.select.button"), - "Pastes the selected queries into the Query Editor"); - selectButton.setActionCommand("Select"); - JButton copyButton = createButton(Bundles.get("common.copy.button"), - "Copies the selected queries to the system clipboard"); - copyButton.setActionCommand("Copy"); - JButton insertAtCursorButton = createButton("Insert at Cursor", - "Inserts the selected queries at the cursor position within the Query Editor"); - JButton clearButton = createButton(Bundles.get("common.clear.button"), - "Clears and resets ALL SQL history"); - clearButton.setActionCommand("Clear"); - - newEditorCheck = new JCheckBox("Open in new Query Editor"); - newEditorCheck.setToolTipText("Select to paste the query in a new Query Editor panel"); - - textPane = new SQLTextArea(); - textPane.setEditable(false); - - JSplitPane splitPane = createSplitPane(); - splitPane.setLeftComponent(new JScrollPane(historyList)); - splitPane.setRightComponent(new JScrollPane(textPane)); + // --- history list --- - Container c = getContentPane(); - c.setLayout(new GridBagLayout()); - - searchField = WidgetFactory.createTextField("searchField"); - searchField.addActionListener(this); - JButton searchButton = createButton("Search", null); - - JPanel searchPanel = new JPanel(new GridBagLayout()); - GridBagConstraints gbc = new GridBagConstraints(); - gbc.gridx++; - gbc.insets.right = 5; - searchPanel.add(new JLabel("Find:"), gbc); - gbc.gridx++; - gbc.weightx = 1.0; - gbc.fill = GridBagConstraints.HORIZONTAL; - searchPanel.add(searchField, gbc); - gbc.gridx++; - gbc.weightx = 0; - gbc.insets.right = 0; - searchPanel.add(searchButton, gbc); - - // layout the components - gbc = new GridBagConstraints(); - gbc.gridx = 0; - gbc.gridy = 0; - gbc.insets.top = 5; - gbc.insets.left = 5; - gbc.insets.right = 5; - gbc.gridwidth = GridBagConstraints.REMAINDER; - gbc.insets.bottom = 5; - gbc.weighty = 0; - gbc.fill = GridBagConstraints.HORIZONTAL; - c.add(searchPanel, gbc); - gbc.gridy++; - gbc.weightx = 1.0; - gbc.weighty = 1.0; - gbc.insets.top = 0; - gbc.fill = GridBagConstraints.BOTH; - c.add(splitPane, gbc); - gbc.weightx = 0; - gbc.insets.left = 5; - gbc.insets.bottom = 7; - gbc.gridwidth = 1; - gbc.gridy++; - gbc.gridx = 4; - gbc.weighty = 0; - gbc.fill = GridBagConstraints.NONE; - gbc.anchor = GridBagConstraints.EAST; - c.add(cancelButton, gbc); - gbc.gridx--; - gbc.insets.right = 0; - c.add(clearButton, gbc); - gbc.gridx--; - gbc.insets.right = 0; - c.add(copyButton, gbc); - gbc.gridx--; - c.add(insertAtCursorButton, gbc); - gbc.gridx--; - gbc.weightx = 1.0; - c.add(selectButton, gbc); - gbc.weightx = 0; - gbc.anchor = GridBagConstraints.WEST; - c.add(newEditorCheck, gbc); - - historyList.addListSelectionListener(this); + historyList = new JList<>(data); + historyList.setFixedCellHeight(20); + historyList.addListSelectionListener(e -> updateTextPanel()); historyList.addMouseListener(new java.awt.event.MouseAdapter() { + @Override public void mouseClicked(MouseEvent e) { - historyListMouseClicked(e); + if (e.getClickCount() >= 2) + selectQuery(); } }); historyList.addKeyListener(new java.awt.event.KeyAdapter() { + @Override public void keyPressed(KeyEvent e) { - historyListKeyPressed(e); + if (e.getKeyCode() == KeyEvent.VK_ENTER) + selectQuery(); } }); - c.setPreferredSize(new Dimension(800, 490)); - } - - private void initHistoryList(Vector data) { - - historyList = new DefaultList(data); - } - - private JSplitPane createSplitPane() { - - JSplitPane splitPane = new FlatSplitPane(JSplitPane.VERTICAL_SPLIT); - - splitPane.setDividerSize(4); - splitPane.setResizeWeight(0.5); - splitPane.setDividerLocation(0.7); - - return splitPane; - } + // --- others --- - private JButton createButton(String text, String toolTip) { + openNewEditorCheck = WidgetFactory.createCheckBox("openNewEditorCheck", bundleString("openNewEditorCheck")); + openNewEditorCheck.setToolTipText(bundleString("openNewEditorCheck.toolTip")); - JButton button = new DefaultPanelButton(text); - if (toolTip != null) { - - button.setToolTipText(toolTip); - } + searchField = WidgetFactory.createTextField("searchField"); + searchField.addActionListener(e -> searchForQuery()); - button.addActionListener(this); + textPane = new SQLTextArea(); + textPane.setEditable(false); - return button; } - /** - * Sets the statement history data to the JList. - * - * @param - the statement history Vector - */ - public void setHistoryData(Vector data) { - this.data = data; - historyList.setListData(data); - } + private void arrange() { + GridBagHelper gbh; - /** - *

Initiates the action of the "Select" button adding - * the selected statement to the open Query Editor. - * - * @param - the action event - */ - public void actionPerformed(ActionEvent e) { + // --- split pane --- - String command = e.getActionCommand(); + JSplitPane splitPane = new FlatSplitPane(JSplitPane.VERTICAL_SPLIT); + splitPane.setLeftComponent(new JScrollPane(historyList)); + splitPane.setRightComponent(new JScrollPane(textPane)); + splitPane.setDividerLocation(0.7); + splitPane.setResizeWeight(0.5); + splitPane.setDividerSize(4); - if (command.equals("Select")) { + // --- search panel --- - selectSQLCommand(); + JPanel searchPanel = new JPanel(new GridBagLayout()); - } else if (command.equals("Copy")) { + gbh = new GridBagHelper().anchorNorthWest().fillHorizontally().rightGap(5); + searchPanel.add(new JLabel(Bundles.get("common.search")), gbh.topGap(3).get()); + searchPanel.add(searchField, gbh.nextCol().topGap(0).setMaxWeightX().get()); + searchPanel.add(searchButton, gbh.nextCol().rightGap(0).setMinWeightX().get()); - copySQLCommand(); + // --- button panel --- - } else if (command.equals("Insert at Cursor")) { + JPanel buttonPanel = new JPanel(new GridBagLayout()); - insertAtCursorButton(); + gbh = new GridBagHelper().anchorNorthWest().fillHorizontally(); + buttonPanel.add(openNewEditorCheck, gbh.get()); + buttonPanel.add(new JPanel(), gbh.nextCol().setMaxWeightX().get()); + buttonPanel.add(selectButton, gbh.nextCol().setMinWeightX().rightGap(5).get()); + buttonPanel.add(insertButton, gbh.nextCol().get()); + buttonPanel.add(copyButton, gbh.nextCol().get()); + buttonPanel.add(clearButton, gbh.nextCol().get()); + buttonPanel.add(cancelButton, gbh.nextCol().rightGap(0).get()); - } else if (command.equals("Search") || e.getSource() == searchField) { + // --- main panel --- - String text = searchField.getText(); + JPanel mainPanel = new JPanel(new GridBagLayout()); - if (MiscUtils.isNull(text)) { + gbh = new GridBagHelper().anchorNorthWest().fillBoth().bottomGap(5); + mainPanel.add(searchPanel, gbh.setMinWeightY().spanX().get()); + mainPanel.add(splitPane, gbh.nextRow().setMaxWeightY().get()); + mainPanel.add(buttonPanel, gbh.nextRow().bottomGap(0).setMinWeightY().get()); - return; - } + // --- base --- - int start = historyList.getSelectedIndex(); - if (start == -1 || start == data.size() - 1) { + setLayout(new GridBagLayout()); + setPreferredSize(new Dimension(800, 490)); - start = 0; + gbh = new GridBagHelper().setInsets(5, 5, 5, 5).fillBoth().spanX().spanY(); + add(mainPanel, gbh.get()); - } else { + pack(); + setLocation(GUIUtilities.getLocationForDialog(getSize())); + setVisible(true); + } - start++; - } + private void updateTextPanel() { + textPane.setText(queryForIndex(historyList.getSelectedIndex())); + } - search(text, start); + /** + * Sets the statement history data to the JList. + * + * @param data the statement history Vector + */ + public void setHistoryData(Vector data) { + this.data = data; + historyList.setListData(data); + } - } else if (command.equals("Clear")) { + private void searchForQuery() { - sqlCommandHistoryRepository().clearSqlCommandHistory(queryEditor.getSelectedConnection().getId()); - setHistoryData(new Vector(0)); + String text = searchField.getText(); + if (MiscUtils.isNull(text)) + return; - } else { + int start = historyList.getSelectedIndex(); + if (start == -1 || start == data.size() - 1) + start = 0; + else + start++; - dispose(); - } + search(text, start); + } + private void clearHistory() { + sqlCommandHistoryRepository().clearSqlCommandHistory(queryEditor.getSelectedConnection().getId()); + setHistoryData(new Vector<>(0)); } private SqlCommandHistoryRepository sqlCommandHistoryRepository() { - - return (SqlCommandHistoryRepository) RepositoryCache.load( - SqlCommandHistoryRepository.REPOSITORY_ID); + return (SqlCommandHistoryRepository) RepositoryCache.load(SqlCommandHistoryRepository.REPOSITORY_ID); } private void search(String text, int start) { - Pattern pattern = Pattern.compile("\\b" + text, - Pattern.CASE_INSENSITIVE); + + Pattern pattern = Pattern.compile("\\b" + text, Pattern.CASE_INSENSITIVE); Matcher matcher = pattern.matcher(Constants.EMPTY); for (int i = start, k = data.size(); i < k; i++) { - matcher.reset(data.get(i)); if (matcher.find()) { @@ -334,50 +250,42 @@ private void search(String text, int start) { } } - GUIUtilities.displayInformationMessage("Search string not found"); + GUIUtilities.displayInformationMessage(bundleString("stringNotFound")); } private void scrollToSelection(int i) { - historyList.ensureIndexIsVisible(i); } - private boolean validSelection() { - - if (data.isEmpty()) { + private boolean invalidSelection() { - return false; - } + if (data.isEmpty()) + return true; if (historyList.isSelectionEmpty()) { - - GUIUtilities.displayErrorMessage("No selection made."); - return false; + GUIUtilities.displayErrorMessage(bundleString("noSelection")); + return true; } - return true; + return false; } - private void copySQLCommand() { - - if (validSelection()) { - - String query = queryForIndices(historyList.getSelectedIndices()); - GUIUtilities.copyToClipBoard(query); + private void copyQuery() { - dispose(); - } + if (invalidSelection()) + return; + String query = queryForIndices(historyList.getSelectedIndices()); + GUIUtilities.copyToClipBoard(query); + dispose(); } - private void insertAtCursorButton() { - - if (newEditorCheck.isSelected()) { + private void insertQuery() { - selectSQLCommand(); + if (openNewEditorCheck.isSelected()) { + selectQuery(); } else if (queryEditor != null) { - String query = queryForIndices(historyList.getSelectedIndices()); queryEditor.insertTextAtCaret(query); dispose(); @@ -385,93 +293,45 @@ private void insertAtCursorButton() { } - private void selectSQLCommand() { - - if (validSelection()) { - - String query = queryForIndices(historyList.getSelectedIndices()); - if (newEditorCheck.isSelected()) { + private void selectQuery() { - QueryEditor editor = new QueryEditor(query); - GUIUtilities.addCentralPane(QueryEditor.TITLE, - QueryEditor.FRAME_ICON, - editor, - null, - true); + if (invalidSelection()) + return; - } else if (queryEditor != null) { + String query = queryForIndices(historyList.getSelectedIndices()); + if (openNewEditorCheck.isSelected()) { + GUIUtilities.addCentralPane( + QueryEditor.TITLE, + QueryEditor.FRAME_ICON, + new QueryEditor(query), + null, + true + ); - queryEditor.setEditorText(query); - } + } else if (queryEditor != null) + queryEditor.setEditorText(query); - dispose(); - } + dispose(); } private String queryForIndices(int[] indices) { - if (indices.length > 0) { + if (indices.length < 1) + return Constants.EMPTY; - StringBuilder sb = new StringBuilder(); - for (int index : indices) { - - sb.append(queryForIndex(index).trim()); - sb.append("\n\n"); - } + StringBuilder sb = new StringBuilder(); + for (int index : indices) + sb.append(queryForIndex(index).trim()).append("\n\n"); - return sb.toString().trim(); - } - - return ""; + return sb.toString().trim(); } private String queryForIndex(int index) { - - if (index != -1) { - - return data.get(index); - } - return ""; + return index != -1 ? data.get(index) : Constants.EMPTY; } - /** - *

Initiates the action on the history list after - * double clicking a selected statement and propagates - * the action to the method selectButton_actionPerformed. - * - * @param - the mouse event - */ - private void historyListMouseClicked(MouseEvent e) { - if (e.getClickCount() >= 2) { - - selectSQLCommand(); - } - } - - public void valueChanged(ListSelectionEvent e) { - - textPane.setText(queryForIndex(historyList.getSelectedIndex())); - } - - /** - *

Initiates the action on the history list after - * pressing the ENTER key on a selected statement and propagates - * the action to the method selectButton_actionPerformed. - * - * @param - the key event - */ - private void historyListKeyPressed(KeyEvent e) { - if (e.getKeyCode() == KeyEvent.VK_ENTER) { - selectSQLCommand(); - } + private static String bundleString(String key, Object... args) { + return Bundles.get(SQLHistoryDialog.class, key, args); } } - - - - - - - - diff --git a/src/org/executequery/gui/editor/autocomplete/DefaultAutoCompletePopupProvider.java b/src/org/executequery/gui/editor/autocomplete/DefaultAutoCompletePopupProvider.java index d877dfa33..cd805086b 100644 --- a/src/org/executequery/gui/editor/autocomplete/DefaultAutoCompletePopupProvider.java +++ b/src/org/executequery/gui/editor/autocomplete/DefaultAutoCompletePopupProvider.java @@ -33,8 +33,10 @@ import java.awt.event.FocusEvent; import java.awt.event.FocusListener; import java.awt.event.KeyEvent; +import java.util.ArrayList; +import java.util.Comparator; import java.util.List; -import java.util.*; +import java.util.TreeSet; public class DefaultAutoCompletePopupProvider implements AutoCompletePopupProvider, @@ -712,14 +714,13 @@ public void firePopupTrigger() { QueryEditorAutoCompletePopupPanel popupPanel = popupMenu(); Container parent = textComponent.getParent(); - int popupHeight = popupPanel.getHeight(); + int popupHeight = popupPanel.getPreferredSize().height; if (popupHeight != 0 && caretPosition.y + popupHeight > parent.getHeight()) caretPosition.y = caretPosition.y - popupHeight; else caretPosition.y += heightFont; - - if (caretPosition.x + popupPanel.getWidth() > parent.getWidth()) - caretPosition.x = parent.getWidth() - popupPanel.getWidth(); + if (caretPosition.x + popupPanel.getPreferredSize().width > parent.getWidth()) + caretPosition.x = parent.getWidth() - popupPanel.getPreferredSize().width; if (caretPosition.x < 0) caretPosition.x = 0; diff --git a/src/org/executequery/gui/erd/ErdDeleteRelationshipDialog.java b/src/org/executequery/gui/erd/ErdDeleteRelationshipDialog.java index 2a9fa474d..233f5bbad 100644 --- a/src/org/executequery/gui/erd/ErdDeleteRelationshipDialog.java +++ b/src/org/executequery/gui/erd/ErdDeleteRelationshipDialog.java @@ -20,368 +20,289 @@ package org.executequery.gui.erd; +import org.executequery.Constants; import org.executequery.GUIUtilities; -import org.executequery.gui.DefaultPanelButton; import org.executequery.gui.DefaultTable; +import org.executequery.gui.WidgetFactory; import org.executequery.gui.browser.ColumnConstraint; import org.executequery.gui.browser.ColumnData; import org.executequery.localization.Bundles; +import org.underworldlabs.swing.layouts.GridBagHelper; import javax.swing.*; import javax.swing.table.AbstractTableModel; import javax.swing.table.TableColumnModel; import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; import java.util.Vector; /** * @author Takis Diakoumis */ @SuppressWarnings({"unchecked", "rawtypes"}) -public class ErdDeleteRelationshipDialog extends ErdPrintableDialog - implements ActionListener { +public class ErdDeleteRelationshipDialog extends ErdPrintableDialog { + private static final String TITLE = bundleString("title"); - /** - * The controller for the ERD viewer - */ - private final ErdViewerPanel parent; - /** - * The table listing constraints - */ private JTable table; - /** - * The two related tables - */ - private ErdTable[] erdTables; - /** - * The SQL text string buffer - */ - private StringBuffer sqlBuffer; - /** - * The constraints - */ - private Vector constraints; + private JButton deleteButton; + private JButton cancelButton; - /** - * The literal 'ALTER TABLE ' - */ - private static final String ALTER_TABLE = "ALTER TABLE "; - /** - * The literal ' ADD CONSTRAINT ' - */ - private static final String DROP_CONSTRAINT = " DROP CONSTRAINT "; - /** - * The literal ';' - */ - private static final String CLOSE_END = ";\n"; + private Vector constraints; + private final ErdViewerPanel parent; public ErdDeleteRelationshipDialog(ErdViewerPanel parent, ErdTable[] erdTables) { - super("Delete Table Relationship"); - + super(TITLE); this.parent = parent; - this.erdTables = erdTables; + this.constraints = new Vector(); + + if (!preInit(erdTables)) { + dispose(); + return; + } + + init(); + arrange(); + display(); + } - ColumnData[] cd1 = erdTables[0].getTableColumns(); - ColumnData[] cd2 = erdTables[1].getTableColumns(); + private boolean preInit(ErdTable[] erdTables) { String tableName1 = erdTables[0].getTableName(); String tableName2 = erdTables[1].getTableName(); - ColumnConstraint[] tableConstraints = null; - - constraints = new Vector(); - for (int i = 0; i < cd1.length; i++) { + ColumnData[] columnData1 = erdTables[0].getTableColumns(); + ColumnData[] columnData2 = erdTables[1].getTableColumns(); - if (!cd1[i].isForeignKey()) { + for (ColumnData columnData : columnData1) { + if (!columnData.isForeignKey()) continue; - } - tableConstraints = cd1[i].getColumnConstraintsArray(); - if (tableConstraints == null || tableConstraints.length == 0) { + ColumnConstraint[] tableConstraints = columnData.getColumnConstraintsArray(); + if (tableConstraints == null || tableConstraints.length == 0) break; - } for (int j = 0; j < tableConstraints.length; j++) { - if (tableConstraints[j].isPrimaryKey()) { - continue; - } - - if (tableConstraints[j].getRefTable().equalsIgnoreCase(tableName2)) { - constraints.add(new ColumnConstraintDrop(cd1[i], erdTables[0], j)); - } + ColumnConstraint constraint = tableConstraints[j]; + if (!constraint.isPrimaryKey() && constraint.getRefTable().equalsIgnoreCase(tableName2)) + constraints.add(new ColumnConstraintDrop(columnData, erdTables[0], j)); } - } - for (int i = 0; i < cd2.length; i++) { - - if (!cd2[i].isForeignKey()) { + for (ColumnData columnData : columnData2) { + if (!columnData.isForeignKey()) continue; - } - tableConstraints = cd2[i].getColumnConstraintsArray(); - if (tableConstraints == null || tableConstraints.length == 0) { + ColumnConstraint[] tableConstraints = columnData.getColumnConstraintsArray(); + if (tableConstraints == null || tableConstraints.length == 0) continue; - } for (int j = 0; j < tableConstraints.length; j++) { - if (tableConstraints[j].isPrimaryKey()) { - continue; - } - - if (tableConstraints[j].getRefTable().equalsIgnoreCase(tableName1)) { - constraints.add(new ColumnConstraintDrop(cd2[i], erdTables[1], j)); - } + ColumnConstraint constraint = tableConstraints[j]; + if (!constraint.isPrimaryKey() && constraint.getRefTable().equalsIgnoreCase(tableName1)) + constraints.add(new ColumnConstraintDrop(columnData, erdTables[1], j)); } - } - if (constraints.size() == 0) { - GUIUtilities.displayErrorMessage( - "No relation exists between the selected tables"); - super.dispose(); - return; + if (constraints.isEmpty()) { + GUIUtilities.displayErrorMessage(bundleString("noRelation")); + return false; } - try { - jbInit(); - } catch (Exception e) { - e.printStackTrace(); - } - - display(); - + return true; } - private void jbInit() throws Exception { - JButton deleteButton = new DefaultPanelButton(Bundles.get("common.delete.button"), "Delete"); - JButton cancelButton = new DefaultPanelButton(Bundles.get("common.cancel.button"), "Cancel"); + private void init() { - cancelButton.addActionListener(this); - deleteButton.addActionListener(this); + deleteButton = WidgetFactory.createButton("deleteButton", Bundles.get("common.delete.button"), e -> delete()); + cancelButton = WidgetFactory.createButton("cancelButton", Bundles.get("common.cancel.button"), e -> dispose()); - sqlText.setPreferredSize(new Dimension(480, 90)); + sqlText.setSQLTextEditable(false); + sqlText.setPreferredSize(new Dimension(450, 200)); table = new DefaultTable(new ConstraintTableModel()); - table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); table.getTableHeader().setReorderingAllowed(false); - table.setCellSelectionEnabled(true); table.setColumnSelectionAllowed(false); table.setRowSelectionAllowed(false); + table.setCellSelectionEnabled(true); + table.setFillsViewportHeight(true); TableColumnModel tcm = table.getColumnModel(); tcm.getColumn(0).setPreferredWidth(25); - tcm.getColumn(1).setPreferredWidth(100); - tcm.getColumn(2).setPreferredWidth(125); - tcm.getColumn(3).setPreferredWidth(125); - tcm.getColumn(4).setPreferredWidth(125); - tcm.getColumn(5).setPreferredWidth(125); - - JScrollPane tableScroller = new JScrollPane(table); - tableScroller.setPreferredSize(new Dimension(640, 130)); - - JPanel panel = new JPanel(new GridBagLayout()); - panel.setBorder(BorderFactory.createEtchedBorder()); - - GridBagConstraints gbc = new GridBagConstraints(); - gbc.insets = new Insets(5, 5, 5, 5); - gbc.anchor = GridBagConstraints.NORTHWEST; - panel.add(new JLabel("Select the constraints to be dropped:"), gbc); - gbc.gridy = 1; - gbc.fill = GridBagConstraints.BOTH; - gbc.gridwidth = GridBagConstraints.REMAINDER; - gbc.weightx = 1.0; - gbc.weighty = 0.7; - gbc.insets.top = 0; - panel.add(tableScroller, gbc); - gbc.gridx = 0; - gbc.gridy = 2; - gbc.weighty = 0.3; - panel.add(sqlText, gbc); - gbc.gridy = 3; - gbc.gridx = 1; - gbc.weighty = 0; - gbc.gridwidth = 1; - gbc.fill = GridBagConstraints.VERTICAL; - gbc.anchor = GridBagConstraints.EAST; - panel.add(deleteButton, gbc); - gbc.gridx = 2; - gbc.insets.left = 0; - gbc.weightx = 0; - panel.add(cancelButton, gbc); - - Container c = getContentPane(); - c.setLayout(new GridBagLayout()); - - c.add(panel, new GridBagConstraints(1, 1, 1, 1, 1.0, 1.0, - GridBagConstraints.SOUTHEAST, GridBagConstraints.BOTH, - new Insets(7, 7, 7, 7), 0, 0)); - - sqlBuffer = new StringBuffer(); + tcm.getColumn(0).setMaxWidth(25); + tcm.getColumn(0).setMinWidth(25); + } + + private void arrange() { + GridBagHelper gbh; + + // --- button panel --- + + JPanel buttonPanel = new JPanel(new GridBagLayout()); + + gbh = new GridBagHelper().anchorNorthWest().fillHorizontally(); + buttonPanel.add(new JPanel(), gbh.setMaxWeightX().get()); + buttonPanel.add(deleteButton, gbh.nextCol().setMinWeightX().get()); + buttonPanel.add(cancelButton, gbh.nextCol().leftGap(5).get()); + + // --- main panel --- + + JPanel mainPanel = new JPanel(new GridBagLayout()); + + gbh = new GridBagHelper().anchorNorthWest().fillHorizontally().spanX(); + mainPanel.add(new JLabel(bundleString("selectConstraints")), gbh.get()); + mainPanel.add(new JScrollPane(table), gbh.nextRow().topGap(5).setMaxWeightY().fillBoth().get()); + mainPanel.add(sqlText, gbh.nextRow().get()); + mainPanel.add(buttonPanel, gbh.nextRow().setMinWeightY().get()); + + // --- base --- + + setLayout(new GridBagLayout()); + setPreferredSize(new Dimension(800, 500)); setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); + + gbh = new GridBagHelper().setInsets(5, 5, 5, 5).fillBoth().spanX().spanY(); + add(mainPanel, gbh.get()); } private void setSQLText() { - sqlBuffer.setLength(0); - ColumnConstraintDrop ccd = null; + + StringBuilder sb = new StringBuilder(); for (int i = 0, n = constraints.size(); i < n; i++) { - ccd = (ColumnConstraintDrop) constraints.elementAt(i); - if (ccd.isDropped()) { - sqlBuffer.append(ccd.getSql()); - } + ColumnConstraintDrop constraintToDrop = (ColumnConstraintDrop) constraints.elementAt(i); + if (constraintToDrop.isDropped()) + sb.append(constraintToDrop.getSql()); } - sqlText.setSQLText(sqlBuffer.toString()); + + sqlText.setSQLText(sb.toString()); } private void delete() { - ColumnConstraintDrop ccd = null; + for (int i = 0, n = constraints.size(); i < n; i++) { - ccd = (ColumnConstraintDrop) constraints.elementAt(i); - ccd.dropConstraint(); + ColumnConstraintDrop constraintToDrop = (ColumnConstraintDrop) constraints.elementAt(i); + constraintToDrop.dropConstraint(); } constraints = null; - erdTables = null; table = null; parent.updateTableRelationships(); dispose(); } - public void actionPerformed(ActionEvent e) { - Object button = e.getSource(); - - if (button instanceof JButton) { - String command = e.getActionCommand(); - - if (command.equals("Cancel")) - dispose(); - - else if (command.equals("Delete")) - delete(); - - } - + private static String bundleString(String key, Object... args) { + return Bundles.get(ErdDeleteRelationshipDialog.class, key, args); } private class ConstraintTableModel extends AbstractTableModel { - protected String[] header = {" ", "Name", "Referencing Table", - "Referencing Column", "Referenced Table", - "Referenced Column"}; + private final String[] headers = { + " ", + bundleString("Name"), + bundleString("ReferencingTable"), + bundleString("ReferencingColumn"), + bundleString("ReferencedTable"), + bundleString("ReferencedColumn") + }; + @Override public int getColumnCount() { - return 6; + return headers.length; } + @Override public int getRowCount() { return constraints.size(); } + @Override public Object getValueAt(int row, int col) { - ColumnConstraintDrop ccd = (ColumnConstraintDrop) constraints.elementAt(row); - ColumnConstraint cc = ccd.getColumnConstraint(); + ColumnConstraintDrop constraintToDrop = (ColumnConstraintDrop) constraints.elementAt(row); + ColumnConstraint constraint = constraintToDrop.getColumnConstraint(); switch (col) { - case 0: - return Boolean.valueOf(ccd.isDropped()); - + return constraintToDrop.isDropped(); case 1: - return cc.getName(); - + return constraint.getName(); case 2: - return cc.getTable(); - + return constraint.getTable(); case 3: - return cc.getColumn(); - + return constraint.getColumn(); case 4: - return cc.getRefTable(); - + return constraint.getRefTable(); case 5: - return cc.getRefColumn(); - + return constraint.getRefColumn(); default: return null; - } } + @Override public void setValueAt(Object value, int row, int col) { - ColumnConstraintDrop ccd = (ColumnConstraintDrop) constraints.elementAt(row); - ColumnConstraint cc = ccd.getColumnConstraint(); + ColumnConstraintDrop constraintToDrop = (ColumnConstraintDrop) constraints.elementAt(row); + ColumnConstraint constraint = constraintToDrop.getColumnConstraint(); switch (col) { case 0: - ccd.setDropped(((Boolean) value).booleanValue()); + constraintToDrop.setDropped((Boolean) value); setSQLText(); break; case 1: - cc.setName((String) value); + constraint.setName((String) value); break; case 2: - cc.setTable((String) value); + constraint.setTable((String) value); break; case 3: - cc.setColumn((String) value); + constraint.setColumn((String) value); break; case 4: - cc.setRefTable((String) value); + constraint.setRefTable((String) value); break; case 5: - cc.setRefColumn((String) value); + constraint.setRefColumn((String) value); break; } fireTableRowsUpdated(row, row); } + @Override public boolean isCellEditable(int row, int col) { - return (col == 0); + return col == 0; } + @Override public String getColumnName(int col) { - return header[col]; + return headers[col]; } + @Override public Class getColumnClass(int col) { - if (col == 0) { - return Boolean.class; - } - return String.class; + return col == 0 ? Boolean.class : String.class; } - } // ConstraintTableModel + } // ConstraintTableModel class - - class ColumnConstraintDrop { + private static class ColumnConstraintDrop { private boolean dropped; private final ErdTable erdTable; - private ColumnConstraint columnConstraint; private final ColumnData columnData; + private final ColumnConstraint columnConstraint; - public ColumnConstraintDrop(ColumnData columnData, - ErdTable erdTable, int constraintIndex) { - columnConstraint = columnData.getColumnConstraintsArray()[constraintIndex]; - this.erdTable = erdTable; + public ColumnConstraintDrop(ColumnData columnData, ErdTable erdTable, int constraintIndex) { + this.columnConstraint = columnData.getColumnConstraintsArray()[constraintIndex]; this.columnData = columnData; - dropped = false; + this.erdTable = erdTable; + this.dropped = false; } public void dropConstraint() { - if (dropped) { columnData.removeConstraint(columnConstraint); columnData.setForeignKey(false); erdTable.setDropConstraintsScript(getSql()); } - - } - - public void setColumnConstraint(ColumnConstraint columnConstraint) { - this.columnConstraint = columnConstraint; } public ColumnConstraint getColumnConstraint() { @@ -390,12 +311,15 @@ public ColumnConstraint getColumnConstraint() { public String getSql() { - if (dropped) - return ALTER_TABLE + erdTable.getTableName() + - DROP_CONSTRAINT + columnConstraint.getName() + CLOSE_END; - else - return ""; + if (dropped) { + return String.format( + "ALTER TABLE %s DROP CONSTRAINT %s;\n", + erdTable.getTableName(), + columnConstraint.getName() + ); + } + return Constants.EMPTY; } public boolean isDropped() { @@ -406,18 +330,6 @@ public void setDropped(boolean dropped) { this.dropped = dropped; } - } // ColumnConstraintDrop + } // ColumnConstraintDrop class } - - - - - - - - - - - - diff --git a/src/org/executequery/gui/erd/ErdGenerateProgressDialog.java b/src/org/executequery/gui/erd/ErdGenerateProgressDialog.java index aa6d7b48c..c56569bcb 100644 --- a/src/org/executequery/gui/erd/ErdGenerateProgressDialog.java +++ b/src/org/executequery/gui/erd/ErdGenerateProgressDialog.java @@ -38,7 +38,7 @@ import java.util.List; import java.util.*; -import static org.executequery.databaseobjects.NamedObject.PRIMARY_KEY; +import static org.executequery.databaseobjects.NamedObject.FOREIGN_KEY; /** * @author Takis Diakoumis @@ -65,17 +65,6 @@ public ErdGenerateProgressDialog(Vector selectedTables, DatabaseConnection conne display(); } - public ErdGenerateProgressDialog(Vector selectedTables, ErdViewerPanel parent) { - super(GUIUtilities.getParentFrame(), "Adding Tables", false); - - this.connection = parent.getDatabaseConnection(); - this.selectedTables = selectedTables; - this.parent = parent; - - init(); - display(); - } - public ErdGenerateProgressDialog(Vector selectedTables, ErdViewerPanel parent, DatabaseConnection connection) { super(GUIUtilities.getParentFrame(), "Adding Tables", false); @@ -219,10 +208,6 @@ private void processComplete(Vector tableInfoList) { } GUIUtilities.showWaitCursor(); - - ErdViewerPanel viewerPanel = new ErdViewerPanel(tableInfoList, false); - viewerPanel.setDatabaseConnection(connection); - GUIUtilities.closeDialog(GenerateErdPanel.TITLE); dispose(); GUIUtilities.showNormalCursor(); @@ -277,7 +262,7 @@ public Map> buildTableRelationships(Vector referencedTableCombo; + private JComboBox referencedColumnCombo; + private JComboBox referencingTableCombo; + private JComboBox referencingColumnCombo; + public ErdNewRelationshipDialog(ErdViewerPanel parent) { + super(TITLE); this.parent = parent; - try { - jbInit(); - } catch (Exception e) { - e.printStackTrace(); - } - + init(); + arrange(); display(); - } - private void jbInit() throws Exception { - JButton createButton = new DefaultPanelButton(Bundles.get("common.create.button")); - JButton cancelButton = new DefaultPanelButton(Bundles.get("common.cancel.button")); - createButton.setActionCommand("Create"); - cancelButton.setActionCommand("Cancel"); - - ActionListener btnListener = new ActionListener() { - public void actionPerformed(ActionEvent e) { - buttons_actionPerformed(e); - } - }; + private void init() { + ErdTable[] tables = parent.getAllTablesArray(); - cancelButton.addActionListener(btnListener); - createButton.addActionListener(btnListener); + createButton = WidgetFactory.createButton("createButton", Bundles.get("common.create.button"), e -> create()); + cancelButton = WidgetFactory.createButton("cancelButton", Bundles.get("common.cancel.button"), e -> dispose()); - sqlText.setPreferredSize(new Dimension(420, 120)); + sqlText.setSQLTextEditable(false); + sqlText.setPreferredSize(new Dimension(420, 150)); nameField = WidgetFactory.createTextField("nameField"); nameField.addKeyListener(new KeyAdapter() { + @Override public void keyReleased(KeyEvent e) { setSQLText(); } }); - ErdTable[] tables = parent.getAllTablesArray(); referencingTableCombo = WidgetFactory.createComboBox("referencingTableCombo", tables); + referencingTableCombo.addActionListener(this::tableChanged); + referencedTableCombo = WidgetFactory.createComboBox("referencedTableCombo", tables); + referencedTableCombo.addActionListener(this::tableChanged); referencingColumnCombo = WidgetFactory.createComboBox("referencingColumnCombo"); - referencedColumnCombo = WidgetFactory.createComboBox("referencedColumnCombo"); - - referencingTableCombo.addActionListener(btnListener); - referencedTableCombo.addActionListener(btnListener); - referencingColumnCombo.addActionListener(btnListener); - referencedColumnCombo.addActionListener(btnListener); - - JPanel panel = new JPanel(new GridBagLayout()); - panel.setBorder(BorderFactory.createEtchedBorder()); - - GridBagConstraints gbc = new GridBagConstraints(); - gbc.anchor = GridBagConstraints.NORTHWEST; - gbc.fill = GridBagConstraints.HORIZONTAL; - - gbc.insets = new Insets(10, 10, 0, 10); - gbc.gridy++; - gbc.gridx = 0; - gbc.gridwidth = 1; - gbc.insets.top = 0; - gbc.weightx = 0; - panel.add(new DefaultFieldLabel("Constraint Name:"), gbc); - gbc.gridwidth = GridBagConstraints.REMAINDER; - gbc.gridx = 1; - gbc.insets.left = 5; - gbc.weightx = 1.0; - panel.add(nameField, gbc); - - gbc.insets = new Insets(10, 10, 0, 10); - gbc.gridy++; - gbc.gridx = 0; - gbc.gridwidth = 1; - gbc.weightx = 0; - panel.add(new DefaultFieldLabel("Referencing Table:"), gbc); - gbc.gridwidth = GridBagConstraints.REMAINDER; - gbc.gridx = 1; - gbc.insets.left = 5; - gbc.weightx = 1.0; - panel.add(referencingTableCombo, gbc); - - gbc.insets = new Insets(10, 10, 0, 10); - gbc.gridy++; - gbc.gridx = 0; - gbc.gridwidth = 1; - gbc.weightx = 0; - panel.add(new DefaultFieldLabel("Referencing Column:"), gbc); - gbc.gridwidth = GridBagConstraints.REMAINDER; - gbc.gridx = 1; - gbc.insets.left = 5; - gbc.weightx = 1.0; - panel.add(referencingColumnCombo, gbc); - - gbc.insets = new Insets(10, 10, 0, 10); - gbc.gridy++; - gbc.gridx = 0; - gbc.gridwidth = 1; - gbc.weightx = 0; - panel.add(new DefaultFieldLabel("Referenced Table:"), gbc); - gbc.gridwidth = GridBagConstraints.REMAINDER; - gbc.gridx = 1; - gbc.insets.left = 5; - gbc.weightx = 1.0; - panel.add(referencedTableCombo, gbc); - - gbc.insets = new Insets(10, 10, 0, 10); - gbc.gridy++; - gbc.gridx = 0; - gbc.gridwidth = 1; - gbc.weightx = 0; - panel.add(new DefaultFieldLabel("Referenced Column:"), gbc); - gbc.gridwidth = GridBagConstraints.REMAINDER; - gbc.gridx = 1; - gbc.insets.left = 5; - gbc.weightx = 1.0; - panel.add(referencedColumnCombo, gbc); - - gbc.gridx = 0; - gbc.gridy = 5; - gbc.weighty = 1.0; - gbc.fill = GridBagConstraints.BOTH; - gbc.insets.left = 5; - gbc.insets.bottom = 5; - panel.add(sqlText, gbc); - gbc.gridy = 6; - gbc.gridx = 2; - gbc.weighty = 0; - gbc.weightx = 1.0; - gbc.gridwidth = 1; - gbc.fill = GridBagConstraints.NONE; - gbc.anchor = GridBagConstraints.EAST; - panel.add(createButton, gbc); - gbc.gridx = 3; - gbc.insets.left = 0; - gbc.weightx = 0; - panel.add(cancelButton, gbc); - - Container c = getContentPane(); - c.setLayout(new GridBagLayout()); - - c.add(panel, new GridBagConstraints(1, 1, 1, 1, 1.0, 1.0, - GridBagConstraints.SOUTHEAST, GridBagConstraints.BOTH, - new Insets(7, 7, 7, 7), 0, 0)); - - this.addComponentListener(new ComponentAdapter() { - public void componentResized(ComponentEvent e) { - int width = getWidth(); - int height = getHeight(); - - if (width < DIALOG_WIDTH) - width = DIALOG_WIDTH; - - if (height < DIALOG_HEIGHT) - height = DIALOG_HEIGHT; - - setSize(width, height); - } - }); + referencingColumnCombo.addActionListener(e -> setSQLText()); - sqlBuffer = new StringBuffer(); - - ErdTable table = (ErdTable) referencingTableCombo.getSelectedItem(); - referencingColumnCombo.setModel(new DefaultComboBoxModel( - table.getTableColumns())); - table = (ErdTable) referencedTableCombo.getSelectedItem(); - referencedColumnCombo.setModel(new DefaultComboBoxModel( - table.getTableColumns())); - - this.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); + referencedColumnCombo = WidgetFactory.createComboBox("referencedColumnCombo"); + referencedColumnCombo.addActionListener(e -> setSQLText()); + referencingTableChanged(); + referencedTableChanged(); } - private void setSQLText() { - sqlBuffer.delete(0, sqlBuffer.length()); - - sqlBuffer.append(ALTER_TABLE). - append(referencingTableCombo.getSelectedItem()). - append(ADD_CONSTRAINT). - append(nameField.getText()). - append(FOREIGN_KEY). - append(referencingColumnCombo.getSelectedItem()). - append(REFERENCES). - append(referencedTableCombo.getSelectedItem()). - append(OPEN_B). - append(referencedColumnCombo.getSelectedItem()). - append(CLOSE_END); - - sqlText.setSQLText(sqlBuffer.toString()); + private void arrange() { + GridBagHelper gbh; - } + // --- button panel --- - private void create() { + JPanel buttonPanel = new JPanel(new GridBagLayout()); - ColumnData column = (ColumnData) referencingColumnCombo.getSelectedItem(); + gbh = new GridBagHelper().anchorNorthWest().fillHorizontally(); + buttonPanel.add(new JPanel(), gbh.setMaxWeightX().get()); + buttonPanel.add(createButton, gbh.nextCol().fillNone().setMinWeightX().get()); + buttonPanel.add(cancelButton, gbh.nextCol().leftGap(5).get()); - ColumnConstraint constraint = new ColumnConstraint(); - constraint.setName(nameField.getText()); - constraint.setRefTable(referencedTableCombo.getSelectedItem().toString()); - constraint.setColumn(column.getColumnName()); - constraint.setRefColumn(referencedColumnCombo.getSelectedItem().toString()); - constraint.setType(NamedObject.FOREIGN_KEY); + // --- main panel --- - column.addConstraint(constraint); - column.setForeignKey(true); + JPanel mainPanel = new JPanel(new GridBagLayout()); - ErdTable referencingTable = (ErdTable) referencingTableCombo.getSelectedItem(); - referencingTable.setAddConstraintsScript(sqlText.getSQLText()); + gbh = new GridBagHelper().anchorNorthWest().fillHorizontally(); + mainPanel.add(new JLabel(bundleString("ConstraintName")), gbh.topGap(3).get()); + mainPanel.add(nameField, gbh.nextCol().leftGap(5).topGap(0).get()); + mainPanel.add(new JLabel(bundleString("ReferencingTable")), gbh.nextRowFirstCol().leftGap(0).topGap(8).get()); + mainPanel.add(referencingTableCombo, gbh.nextCol().leftGap(5).topGap(5).get()); + mainPanel.add(new JLabel(bundleString("ReferencingColumn")), gbh.nextRowFirstCol().leftGap(0).topGap(8).get()); + mainPanel.add(referencingColumnCombo, gbh.nextCol().leftGap(5).topGap(5).get()); + mainPanel.add(new JLabel(bundleString("ReferencedTable")), gbh.nextRowFirstCol().leftGap(0).topGap(8).get()); + mainPanel.add(referencedTableCombo, gbh.nextCol().leftGap(5).topGap(5).get()); + mainPanel.add(new JLabel(bundleString("ReferencedColumn")), gbh.nextRowFirstCol().leftGap(0).topGap(8).get()); + mainPanel.add(referencedColumnCombo, gbh.nextCol().leftGap(5).topGap(5).get()); + mainPanel.add(sqlText, gbh.nextRowFirstCol().leftGap(0).setMaxWeightY().fillBoth().spanX().get()); + mainPanel.add(buttonPanel, gbh.nextRowFirstCol().setMinWeightY().get()); - SwingUtilities.invokeLater(new Runnable() { - public void run() { - parent.updateTableRelationships(); - } - }); + // --- base --- - dispose(); + setLayout(new GridBagLayout()); + setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); + setPreferredSize(new Dimension(800, 400)); + setMinimumSize(getPreferredSize()); + gbh = new GridBagHelper().setInsets(5, 5, 5, 5).fillBoth().spanX().spanY(); + add(mainPanel, gbh.get()); } - private void buttons_actionPerformed(ActionEvent e) { - Object button = e.getSource(); - - if (button instanceof JButton) { - String command = e.getActionCommand(); - - if (command.equals("Cancel")) - dispose(); - - else if (command.equals("Create")) - create(); - - } else { - - if (button == referencingTableCombo) { - ErdTable table = (ErdTable) referencingTableCombo.getSelectedItem(); - referencingColumnCombo.setModel(new DefaultComboBoxModel( - table.getTableColumns())); - } else if (button == referencedTableCombo) { - ErdTable table = (ErdTable) referencedTableCombo.getSelectedItem(); - referencedColumnCombo.setModel(new DefaultComboBoxModel( - table.getTableColumns())); - } - - setSQLText(); + private void create() { + Object selectedReferencingColumn = referencingColumnCombo.getSelectedItem(); + if (!(selectedReferencingColumn instanceof ColumnData)) { + GUIUtilities.displayWarningMessage(bundleString("isEmptyOrNull", bundleString("referencingColumn"))); + return; } - } - -} - + Object selectedReferencingTable = referencingTableCombo.getSelectedItem(); + if (!(selectedReferencingTable instanceof ErdTable)) { + GUIUtilities.displayWarningMessage(bundleString("isEmptyOrNull", bundleString("referencingTable"))); + return; + } + Object selectedReferencedColumn = referencedColumnCombo.getSelectedItem(); + if (selectedReferencedColumn == null) { + GUIUtilities.displayWarningMessage(bundleString("isEmptyOrNull", bundleString("referencedColumn"))); + return; + } + Object selectedReferencedTable = referencedTableCombo.getSelectedItem(); + if (selectedReferencedTable == null) { + GUIUtilities.displayWarningMessage(bundleString("isEmptyOrNull", bundleString("referencedTable"))); + return; + } + ErdTable referencingTable = (ErdTable) selectedReferencingTable; + ColumnData referencingColumn = (ColumnData) selectedReferencingColumn; + ColumnConstraint constraint = new ColumnConstraint(); + constraint.setName(nameField.getText()); + constraint.setRefTable(selectedReferencedTable.toString()); + constraint.setColumn(referencingColumn.getColumnName()); + constraint.setRefColumn(selectedReferencedColumn.toString()); + constraint.setType(NamedObject.FOREIGN_KEY); + referencingColumn.addConstraint(constraint); + referencingColumn.setForeignKey(true); + referencingTable.setAddConstraintsScript(sqlText.getSQLText()); + SwingUtilities.invokeLater(parent::updateTableRelationships); + dispose(); + } + private void setSQLText() { + String query = String.format( + "ALTER TABLE %s ADD CONSTRAINT %s FOREIGN KEY(%s) REFERENCES %s (%s);\n", + referencingTableCombo.getSelectedItem(), + nameField.getText(), + referencingColumnCombo.getSelectedItem(), + referencedTableCombo.getSelectedItem(), + referencedColumnCombo.getSelectedItem() + ); + sqlText.setSQLText(query); + } + private void tableChanged(ActionEvent e) { + Object source = e.getSource(); + if (source == referencingTableCombo) + referencingTableChanged(); + if (source == referencedTableCombo) + referencedTableChanged(); + setSQLText(); + } + @SuppressWarnings({"rawtypes", "unchecked"}) + private void referencedTableChanged() { + Object selectedItem = referencedTableCombo.getSelectedItem(); + if (selectedItem instanceof ErdTable) { + ErdTable table = (ErdTable) selectedItem; + referencedColumnCombo.setModel(new DefaultComboBoxModel(table.getTableColumns())); + } + } + @SuppressWarnings({"rawtypes", "unchecked"}) + private void referencingTableChanged() { + Object selectedItem = referencingTableCombo.getSelectedItem(); + if (selectedItem instanceof ErdTable) { + ErdTable table = (ErdTable) selectedItem; + referencingColumnCombo.setModel(new DefaultComboBoxModel(table.getTableColumns())); + } + } + private static String bundleString(String key, Object... args) { + return Bundles.get(ErdNewRelationshipDialog.class, key, args); + } +} diff --git a/src/org/executequery/gui/erd/ErdNewTableDialog.java b/src/org/executequery/gui/erd/ErdNewTableDialog.java index f707353d9..c2f68e919 100644 --- a/src/org/executequery/gui/erd/ErdNewTableDialog.java +++ b/src/org/executequery/gui/erd/ErdNewTableDialog.java @@ -21,7 +21,6 @@ package org.executequery.gui.erd; import org.executequery.GUIUtilities; -import org.executequery.databasemediators.DatabaseConnection; import org.executequery.gui.ActionContainer; import org.executequery.gui.BaseDialog; import org.executequery.gui.WidgetFactory; @@ -68,7 +67,7 @@ public ErdNewTableDialog(ErdViewerPanel parent, ErdTable erdTable) { createPanel.setTableName(erdTable.getTableName()); createPanel.getSimpleCommentPanel().setComment(erdTable.getDescriptionTable()); createPanel.setColumnDataArray(tableColumns); - createPanel.setColumnConstraintVector(getColumnConstraints(tableColumns)); + createPanel.setColumnConstraintVector(erdTable.getColumnConstraints()); createPanel.resetSQLText(); createPanel.setSQLTextCaretPosition(0); } @@ -93,7 +92,7 @@ private void init() { buttonsPanel.add(createButton, gbh.nextCol().setMinWeightX().fillNone().get()); buttonsPanel.add(cancelButton, gbh.nextCol().rightGap(5).get()); - createPanel = new CreateTableERDPanel(erdViewerPanel.getDatabaseConnection(), this); + createPanel = new CreateTableERDPanel(this); createPanel.addButtonsPanel(buttonsPanel); createPanel.setPreferredSize(new Dimension(700, 550)); @@ -148,21 +147,6 @@ public void createTable() { dispose(); } - private static Vector getColumnConstraints(ColumnData[] columnDataArray) { - - if (columnDataArray == null) - return new Vector<>(); - - Vector columnConstraintVector = new Vector<>(); - for (ColumnData columnData : columnDataArray) { - Vector tempConstraintsVector = columnData.getColumnConstraintsVector(); - if (tempConstraintsVector != null) - columnConstraintVector.addAll(tempConstraintsVector); - } - - return columnConstraintVector; - } - // --- ActionContainer impl --- @Override @@ -218,8 +202,8 @@ private static String bundleString(String key) { public class CreateTableERDPanel extends CreateTablePanel { - public CreateTableERDPanel(DatabaseConnection dc, ActionContainer dialog) { - super(dc, dialog); + public CreateTableERDPanel(ActionContainer dialog) { + super(null, dialog); } public void setColumnConstraintVector(Vector ccv) { @@ -235,11 +219,11 @@ public List getErdTables() { } public boolean isShowCommentOnTable() { - return showCommentOnTableBox.isSelected(); + return showTableCommentCheck.isSelected(); } public boolean isShowCommentOnFields() { - return showCommentOnFieldsBox.isSelected(); + return showFieldCommentCheck.isSelected(); } @Override diff --git a/src/org/executequery/gui/erd/ErdSaveDialog.java b/src/org/executequery/gui/erd/ErdSaveDialog.java index 839ada617..8bc2437a0 100644 --- a/src/org/executequery/gui/erd/ErdSaveDialog.java +++ b/src/org/executequery/gui/erd/ErdSaveDialog.java @@ -25,7 +25,6 @@ import org.executequery.components.FileChooserDialog; import org.executequery.event.DefaultFileIOEvent; import org.executequery.event.FileIOEvent; -import org.executequery.gui.DefaultPanelButton; import org.executequery.gui.SaveFunction; import org.executequery.gui.WidgetFactory; import org.executequery.imageio.*; @@ -33,6 +32,7 @@ import org.underworldlabs.swing.AbstractBaseDialog; import org.underworldlabs.swing.FileSelector; import org.underworldlabs.swing.NumberTextField; +import org.underworldlabs.swing.layouts.GridBagHelper; import org.underworldlabs.swing.util.SwingWorker; import org.underworldlabs.util.MiscUtils; @@ -46,8 +46,6 @@ import java.awt.event.KeyListener; import java.awt.image.BufferedImage; import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; /** * @author Takis Diakoumis @@ -57,104 +55,49 @@ public class ErdSaveDialog extends AbstractBaseDialog KeyListener, ChangeListener { - /** - * Indicator for JPEG format - */ - private static final int JPEG_FORMAT = 1; - /** - * Indicator for GIF format - */ - private static final int GIF_FORMAT = 2; - /** - * Indicator for SVG format - */ - private static final int SVG_FORMAT = 4; - /** - * Indicator for SVG format - */ - private static final int PNG_FORMAT = 3; - /** - * Indicator for EQ format - */ - private static final int EQ_FORMAT = 0; - /** - * Indicator for transparent background - */ - private static final int TRANSPARENT_BACKGROUND = 0; - /** - * Indicator for white background - */ - private static final int WHITE_BACKGROUND = 1; - - /** - * The ERD parent panel - */ - private ErdViewerPanel parent; + private static final String TITLE = bundleString("title"); - /** - * The open file's path - if any - */ - private String openPath; + private static final int EQ_FORMAT = 0; + private static final int JPG_FORMAT = EQ_FORMAT + 1; + private static final int GIF_FORMAT = JPG_FORMAT + 1; + private static final int SVG_FORMAT = GIF_FORMAT + 1; + private static final int PNG_FORMAT = SVG_FORMAT + 1; - /** - * Image type combo-box - */ - private JComboBox imageTypeCombo; + private static final int TRANSPARENT_BACKGROUND = 0; + private static final int WHITE_BACKGROUND = TRANSPARENT_BACKGROUND + 1; - /** - * The quality text box - */ - private NumberTextField qualityTextField; + // --- GUI components --- - /** - * The quality combo-box - */ - private JComboBox qualityCombo; + private JComboBox qualityCombo; + private JComboBox imageTypeCombo; + private JComboBox backgroundCombo; - /** - * The quality label - */ private JLabel qualityLabel; - - /** - * The background label - */ private JLabel backgroundLabel; - /** - * The background combo-box - */ - private JComboBox backgroundCombo; + private JButton saveButton; + private JButton browseButton; + private JButton cancelButton; - /** - * The quality slider - */ + private JTextField filePathField; private JSlider qualitySlider; + private JCheckBox renderTextAsImageCheck; + private NumberTextField qualityTextField; - /** - * The path field - */ - private JTextField pathField; - - private JCheckBox svgFontCheckbox; + // --- - /** - * The default file to save to - */ - private File defaultFile; private int savedResult; + private String openPath; + private File defaultFile; + private ErdViewerPanel parent; private ErdSaveDialog() { - super(GUIUtilities.getParentFrame(), "Save ERD", true); - + super(GUIUtilities.getParentFrame(), TITLE, true); savedResult = -1; - try { - jbInit(); - } catch (Exception e) { - e.printStackTrace(); - } - + init(); + arrange(); + enablePanel(0); } public ErdSaveDialog(ErdViewerPanel parent) { @@ -177,318 +120,284 @@ public ErdSaveDialog(ErdViewerPanel parent, String openPath) { display(); } - private void display() { - pack(); - this.setLocation(GUIUtilities.getLocationForDialog(this.getSize())); - setVisible(true); - } + private void init() { - private void jbInit() throws Exception { - qualityLabel = new JLabel("Quality:"); - qualityTextField = new NumberTextField(2); - qualityTextField.setValue(8); - qualityTextField.addKeyListener(this); + String[] backgroundTypesArray = { + bundleString("background.transparent"), + bundleString("background.white") + }; - qualityCombo = WidgetFactory.createComboBox("qualityCombo", new String[]{"Low", "Medium", "High", "Maximum"}); - qualityCombo.setSelectedIndex(2); + String[] qualitiesArray = { + bundleString("quality.low"), + bundleString("quality.medium"), + bundleString("quality.high"), + bundleString("quality.maximum") + }; + + String[] imageTypesArray = { + "Red Expert ERD", + "JPEG", + "GIF", + "PNG", + "SVG" + }; + + // --- - Dimension fieldDim = new Dimension(50, 20); - qualityTextField.setPreferredSize(fieldDim); + qualityLabel = new JLabel(bundleString("quality")); + backgroundLabel = new JLabel(bundleString("background")); - Dimension comboDim = new Dimension(150, 23); - qualityCombo.setPreferredSize(comboDim); + qualityTextField = WidgetFactory.createNumberTextField("qualityTextField", "8"); + qualityTextField.setDigits(2); + + qualityCombo = WidgetFactory.createComboBox("qualityCombo", qualitiesArray); + qualityCombo.setSelectedIndex(2); + + backgroundCombo = WidgetFactory.createComboBox("backgroundCombo", backgroundTypesArray); + backgroundCombo.setSelectedIndex(0); qualitySlider = new JSlider(JSlider.HORIZONTAL, 1, 10, 8); + qualitySlider.putClientProperty("JSlider.isFilled", Boolean.TRUE); qualitySlider.setMajorTickSpacing(5); qualitySlider.setMajorTickSpacing(1); - qualitySlider.putClientProperty("JSlider.isFilled", Boolean.TRUE); - qualitySlider.setPreferredSize(new Dimension(300, 30)); - JPanel qualityPanel = new JPanel(new GridBagLayout()); - GridBagConstraints gbc = new GridBagConstraints(); - gbc.insets = new Insets(8, 5, 5, 5); - gbc.anchor = GridBagConstraints.NORTHWEST; - qualityPanel.add(qualityLabel, gbc); - gbc.gridx = 1; - gbc.insets.left = 0; - gbc.insets.top = 6; - qualityPanel.add(qualityTextField, gbc); - gbc.gridx = 2; - gbc.insets.top = 5; - qualityPanel.add(qualityCombo, gbc); - gbc.insets.left = 5; - gbc.insets.top = 0; - gbc.insets.bottom = 0; - gbc.weighty = 1.0; - gbc.gridx = 0; - gbc.gridy = 1; - gbc.fill = GridBagConstraints.BOTH; - gbc.gridwidth = GridBagConstraints.REMAINDER; - qualityPanel.add(qualitySlider, gbc); - - qualityPanel.setBorder(BorderFactory.createTitledBorder("JPEG Options")); - - backgroundLabel = new JLabel("Background:"); - backgroundCombo = WidgetFactory.createComboBox("backgroundCombo", new String[]{"Transparent", "White"}); - backgroundCombo.setPreferredSize(comboDim); - backgroundCombo.setSelectedIndex(0); + saveButton = WidgetFactory.createButton("saveButton", Bundles.get("common.save.button"), e -> save()); + cancelButton = WidgetFactory.createButton("saveButton", Bundles.get("common.cancel.button"), e -> dispose()); + browseButton = WidgetFactory.createButton("browseButton", Bundles.get("common.browse.button"), e -> browse()); - JPanel gifPanel = new JPanel(new FlowLayout(FlowLayout.LEADING, 20, 3)); - gifPanel.add(backgroundLabel); - gifPanel.add(backgroundCombo); - - gifPanel.setBorder(BorderFactory.createTitledBorder("GIF/PNG Options")); - - svgFontCheckbox = new JCheckBox("Render fonts as images"); - JPanel svgPanel = new JPanel(new FlowLayout(FlowLayout.LEADING, 20, 3)); - svgPanel.add(svgFontCheckbox); - svgPanel.setBorder(BorderFactory.createTitledBorder("SVG Options")); - - imageTypeCombo = WidgetFactory.createComboBox("imageTypeCombo", new String[]{ - "Red Expert ERD", "JPEG", "GIF", "PNG", "SVG"}); - imageTypeCombo.setPreferredSize(comboDim); - - pathField = WidgetFactory.createTextField("pathField"); - pathField.setPreferredSize(fieldDim); - - JButton browseButton = new JButton("Browse"); - - JPanel base = new JPanel(new GridBagLayout()); - gbc.fill = GridBagConstraints.NONE; - gbc.insets.top = 7; - gbc.insets.bottom = 5; - gbc.weightx = 0; - gbc.weighty = 0; - gbc.gridx = 0; - gbc.gridy = 0; - gbc.gridwidth = 1; - base.add(new JLabel("Format:"), gbc); - gbc.insets.top = 5; - gbc.gridx = 1; - base.add(imageTypeCombo, gbc); - gbc.gridx = 0; - gbc.gridy++; - gbc.weightx = 1.0; - gbc.fill = GridBagConstraints.BOTH; - gbc.gridwidth = GridBagConstraints.REMAINDER; - base.add(qualityPanel, gbc); - gbc.insets.top = 0; - gbc.gridy++; - base.add(gifPanel, gbc); - gbc.gridy++; - base.add(svgPanel, gbc); - - gbc.gridy++; - gbc.gridx = 0; - gbc.weightx = 0; - gbc.gridwidth = 1; - gbc.insets.top = 5; - base.add(new JLabel("Path:"), gbc); - gbc.fill = GridBagConstraints.HORIZONTAL; - gbc.insets.left = 0; - gbc.insets.top = 8; - gbc.gridx = 1; - gbc.weightx = 1.0; - base.add(pathField, gbc); - gbc.gridx = 2; - gbc.weightx = 0; - gbc.gridwidth = 1; - gbc.insets.top = 5; - gbc.fill = GridBagConstraints.BOTH; - base.add(browseButton, gbc); - - base.setBorder(BorderFactory.createEtchedBorder()); - base.setPreferredSize(new Dimension(400, 300)); - - JButton saveButton = new DefaultPanelButton(Bundles.get("common.save.button")); - saveButton.setActionCommand("Save"); - JButton cancelButton = new DefaultPanelButton(Bundles.get("common.cancel.button")); - cancelButton.setActionCommand("Cancel"); - - cancelButton.addActionListener(this); - saveButton.addActionListener(this); - browseButton.addActionListener(this); - imageTypeCombo.addActionListener(this); - qualityCombo.addActionListener(this); + filePathField = WidgetFactory.createTextField("filePathField"); + imageTypeCombo = WidgetFactory.createComboBox("imageTypeCombo", imageTypesArray); + renderTextAsImageCheck = WidgetFactory.createCheckBox("renderTextAsImageCheck", bundleString("renderTextAsImageCheck")); + + // --- add listeners + qualityCombo.addActionListener(this); qualitySlider.addChangeListener(this); + qualityTextField.addKeyListener(this); + imageTypeCombo.addActionListener(this); + } - Container c = this.getContentPane(); - c.setLayout(new GridBagLayout()); - - gbc.insets.top = 5; - gbc.insets.left = 5; - gbc.weightx = 1.0; - gbc.weighty = 1.0; - gbc.gridx = 0; - gbc.gridy = 0; - gbc.gridwidth = 2; - c.add(base, gbc); - gbc.gridwidth = 1; - gbc.gridy = 1; - gbc.anchor = GridBagConstraints.EAST; - gbc.fill = GridBagConstraints.NONE; - gbc.weighty = 0; - gbc.insets.top = 0; - c.add(saveButton, gbc); - gbc.gridx = 1; - gbc.weightx = 0; - gbc.insets.left = 0; - c.add(cancelButton, gbc); - - enableOptionsPanels(0); + private void arrange() { + GridBagHelper gbh; - setResizable(false); - this.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); + // --- quality panel --- - } + JPanel qualityPanel = new JPanel(new GridBagLayout()); + qualityPanel.setBorder(BorderFactory.createTitledBorder(bundleString("options.jpeg"))); - /** - *

Displays the file chooser dialog. - */ - private void showFileChooser() { - String fileDescription = null; - String fileExtension = null; + gbh = new GridBagHelper().setInsets(5, 8, 5, 5).anchorNorthWest().fillHorizontally(); + qualityPanel.add(qualityLabel, gbh.setMinWeightX().get()); + qualityPanel.add(qualityTextField, gbh.nextCol().topGap(5).leftGap(0).get()); + qualityPanel.add(qualityCombo, gbh.nextCol().setMaxWeightX().get()); + qualityPanel.add(qualitySlider, gbh.nextRowFirstCol().topGap(0).leftGap(5).spanX().get()); - int imageType = imageTypeCombo.getSelectedIndex(); + // --- png panel --- - if (imageType == EQ_FORMAT) { - fileDescription = "Red Expert ERD Files"; - fileExtension = "eqd"; - } else if (imageType == JPEG_FORMAT) { - fileDescription = "JPEG Files"; - fileExtension = "jpeg"; - } else if (imageType == SVG_FORMAT) { - fileDescription = "SVG Files"; - fileExtension = "svg"; - } else if (imageType == PNG_FORMAT) { - fileDescription = "PNG Files"; - fileExtension = "png"; - } else { - fileDescription = "GIF Files"; - fileExtension = "gif"; - } + JPanel pngPanel = new JPanel(new GridBagLayout()); + pngPanel.setBorder(BorderFactory.createTitledBorder(bundleString("options.png"))); - FileSelector fs = new FileSelector(new String[]{fileExtension}, fileDescription); + gbh = new GridBagHelper().setInsets(5, 8, 5, 5).anchorNorthWest().fillHorizontally(); + pngPanel.add(backgroundLabel, gbh.setMinWeightX().get()); + pngPanel.add(backgroundCombo, gbh.nextCol().setMaxWeightX().topGap(5).leftGap(0).get()); - FileChooserDialog fileChooser = null; + // --- svg panel --- - if (openPath != null) { - fileChooser = new FileChooserDialog(openPath); - } else { - fileChooser = new FileChooserDialog(); - } + JPanel svgPanel = new JPanel(new GridBagLayout()); + svgPanel.setBorder(BorderFactory.createTitledBorder(bundleString("options.svg"))); - if (defaultFile != null && imageType == EQ_FORMAT) { - fileChooser.setSelectedFile(defaultFile); + gbh = new GridBagHelper().setInsets(3, 5, 5, 5).anchorNorthWest().fillHorizontally(); + svgPanel.add(renderTextAsImageCheck, gbh.spanX().get()); + + // --- path panel --- + + JPanel pathPanel = new JPanel(new GridBagLayout()); + + gbh = new GridBagHelper().anchorNorthWest().fillHorizontally(); + pathPanel.add(new JLabel(bundleString("path")), gbh.leftGap(3).topGap(3).setMinWeightX().get()); + pathPanel.add(filePathField, gbh.nextCol().leftGap(5).topGap(0).setMaxWeightX().get()); + pathPanel.add(browseButton, gbh.nextCol().setMinWeightX().rightGap(3).get()); + + // --- button panel --- + + JPanel buttonPanel = new JPanel(new GridBagLayout()); + + gbh = new GridBagHelper().anchorCenter().fillHorizontally(); + buttonPanel.add(saveButton, gbh.get()); + buttonPanel.add(cancelButton, gbh.nextCol().leftGap(5).get()); + + // --- main panel --- + + JPanel mainPanel = new JPanel(new GridBagLayout()); + mainPanel.setPreferredSize(new Dimension(400, 300)); + + gbh = new GridBagHelper().anchorNorthWest().fillHorizontally(); + mainPanel.add(new JLabel(bundleString("format")), gbh.setMinWeightX().leftGap(3).topGap(3).get()); + mainPanel.add(imageTypeCombo, gbh.nextCol().setMaxWeightX().leftGap(5).topGap(0).rightGap(5).get()); + mainPanel.add(qualityPanel, gbh.nextRowFirstCol().setMaxWeightY().leftGap(0).topGap(5).rightGap(3).spanX().get()); + mainPanel.add(pngPanel, gbh.nextRowFirstCol().get()); + mainPanel.add(svgPanel, gbh.nextRowFirstCol().get()); + mainPanel.add(pathPanel, gbh.nextRowFirstCol().setMinWeightY().get()); + + // --- base --- + + setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); + setLayout(new GridBagLayout()); + + gbh = new GridBagHelper().setInsets(5, 5, 5, 5).anchorNorthWest().fillBoth(); + add(mainPanel, gbh.setMaxWeightY().spanX().get()); + add(buttonPanel, gbh.nextRow().topGap(10).setMinWeightY().get()); + } + + private void enablePanel(int index) { + switch (index) { + case 0: + enableJpegPanel(false); + enableGifPanel(false); + enableSvgPanel(false); + break; + case 1: + enableJpegPanel(true); + enableGifPanel(false); + enableSvgPanel(false); + break; + case 2: + case 3: + enableJpegPanel(false); + enableGifPanel(true); + enableSvgPanel(false); + break; + case 4: + enableJpegPanel(false); + enableGifPanel(false); + enableSvgPanel(true); + break; } + } - fileChooser.setDialogTitle("Select File..."); - fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY); - fileChooser.setDialogType(JFileChooser.OPEN_DIALOG); - fileChooser.setFileFilter(fs); - int result = fileChooser.showDialog(GUIUtilities.getParentFrame(), "Select"); + private void enableSvgPanel(boolean enable) { + renderTextAsImageCheck.setEnabled(enable); + } - String filePath = null; + private void enableJpegPanel(boolean enable) { + qualityTextField.setEnabled(enable); + qualitySlider.setEnabled(enable); + qualityLabel.setEnabled(enable); + qualityCombo.setEnabled(enable); + } + + private void enableGifPanel(boolean enable) { + backgroundCombo.setEnabled(enable); + backgroundLabel.setEnabled(enable); + } - if (result == JFileChooser.CANCEL_OPTION) { + private void display() { + pack(); + setResizable(false); + setLocation(GUIUtilities.getLocationForDialog(this.getSize())); + setVisible(true); + } + + // --- + + private void save() { + + final String path = filePathField.getText(); + if (MiscUtils.isNull(path)) { + GUIUtilities.displayErrorMessage(bundleString("noFileName")); return; } - File file = fileChooser.getSelectedFile(); + final int fileFormat = imageTypeCombo.getSelectedIndex(); + if ((fileFormat == EQ_FORMAT && !path.endsWith(".eqd")) + || (fileFormat == JPG_FORMAT && !path.endsWith(".jpeg")) + || (fileFormat == SVG_FORMAT && !path.endsWith(".svg")) + || (fileFormat == PNG_FORMAT && !path.endsWith(".png")) + || (fileFormat == GIF_FORMAT && !path.endsWith(".gif"))) { - if (file != null) { - if (file.exists()) { - int _result = GUIUtilities.displayConfirmCancelDialog( - "Overwrite existing file?"); + GUIUtilities.displayErrorMessage(bundleString("invalidFileExtension")); + return; + } - if (_result == JOptionPane.CANCEL_OPTION) { - return; - } else if (_result == JOptionPane.NO_OPTION) { - showFileChooser(); - } + SwingWorker worker = new SwingWorker("saving ER-diagram") { + @Override + public Object construct() { + try { + setVisible(false); + GUIUtilities.showWaitCursor(); + return saveFile(path, fileFormat); + + } finally { + GUIUtilities.showNormalCursor(); + } } - filePath = fileChooser.getSelectedFile().getAbsolutePath(); - } - fileExtension = "." + fileExtension; - if (!filePath.endsWith(fileExtension)) { - filePath += fileExtension; - } + @Override + public void finished() { + if (savedResult == SaveFunction.SAVE_COMPLETE) + dispose(); + else + setVisible(true); + } + }; - pathField.setText(filePath); + worker.start(); } - /** - *

Saves the image in the specified format. - */ - private String save(String path, int fileFormat) { - File file = new File(path); + private String saveFile(String path, int fileFormat) { - if (fileFormat == EQ_FORMAT) { + File file = new File(path); + if (fileFormat == EQ_FORMAT) return saveApplicationFileFormat(file); - } Dimension extents = parent.getMaxImageExtents(); int width = (int) extents.getWidth(); int height = (int) extents.getHeight(); - int imageType = 0; + int imageType; int bgType = backgroundCombo.getSelectedIndex(); - FileOutputStream fos = null; - - if ((fileFormat == GIF_FORMAT || fileFormat == PNG_FORMAT) - && bgType == TRANSPARENT_BACKGROUND) { + if ((fileFormat == GIF_FORMAT || fileFormat == PNG_FORMAT) && bgType == TRANSPARENT_BACKGROUND) { imageType = BufferedImage.TYPE_INT_ARGB; } else if (fileFormat == SVG_FORMAT) { imageType = BufferedImage.TYPE_INT_ARGB; - } else { + } else imageType = BufferedImage.TYPE_INT_RGB; - } BufferedImage image = new BufferedImage(width, height, imageType); - Graphics2D g2d = image.createGraphics(); - - if (fileFormat == JPEG_FORMAT || bgType == WHITE_BACKGROUND) { - g2d.setColor(Color.WHITE); - g2d.fillRect(0, 0, width, height); + Graphics2D graphics = image.createGraphics(); + if (fileFormat == JPG_FORMAT || bgType == WHITE_BACKGROUND) { + graphics.setColor(Color.WHITE); + graphics.fillRect(0, 0, width, height); } - paintImage(g2d); + paintImage(graphics); try { ImageWriter imageWriter = null; ImageWriterInfo imageWriterInfo = null; - ImageWriterFactory factory = new DefaultImageWriterFactory(); if (fileFormat == PNG_FORMAT) { - imageWriter = factory.createImageWriterForPngImages(); imageWriterInfo = new PngImageWriterInfo(image, file); } else if (fileFormat == SVG_FORMAT) { - imageWriter = factory.createImageWriterForSvgImages(); - imageWriterInfo = new SvgImageWriterInfo(image, file, - svgFontCheckbox.isSelected()); - - } else if (fileFormat == JPEG_FORMAT) { + imageWriterInfo = new SvgImageWriterInfo(image, file, renderTextAsImageCheck.isSelected()); + } else if (fileFormat == JPG_FORMAT) { imageWriter = factory.createImageWriterForJpegImages(); - imageWriterInfo = new JpegImageWriterInfo(image, file, - qualitySlider.getValue()); + imageWriterInfo = new JpegImageWriterInfo(image, file, qualitySlider.getValue()); } else if (fileFormat == GIF_FORMAT) { - imageWriter = factory.createImageWriterForGifImages(); imageWriterInfo = new GifImageWriterInfo(image, file); } - imageWriter.write(imageWriterInfo); + if (imageWriter != null) + imageWriter.write(imageWriterInfo); GUIUtilities.scheduleGC(); @@ -497,215 +406,152 @@ private String save(String path, int fileFormat) { } catch (Exception e) { savedResult = SaveFunction.SAVE_FAILED; - GUIUtilities.displayExceptionErrorDialog("An error occured saving to file:\n" + - e.getMessage(), e, this.getClass()); + GUIUtilities.displayExceptionErrorDialog(e.getMessage(), e, this.getClass()); return "failed"; - } finally { - if (fos != null) { - try { - fos.close(); - } catch (IOException e) { - } - } } - } - private void paintImage(Graphics2D g) { - // set the highest quality rendering - g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, - RenderingHints.VALUE_ANTIALIAS_ON); - g.setRenderingHint(RenderingHints.KEY_RENDERING, - RenderingHints.VALUE_RENDER_QUALITY); - g.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, - RenderingHints.VALUE_FRACTIONALMETRICS_ON); - g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, - RenderingHints.VALUE_INTERPOLATION_BICUBIC); - g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, - RenderingHints.VALUE_TEXT_ANTIALIAS_ON); - g.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, - RenderingHints.VALUE_COLOR_RENDER_QUALITY); - g.setRenderingHint(RenderingHints.KEY_DITHERING, - RenderingHints.VALUE_DITHER_ENABLE); - g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, - RenderingHints.VALUE_STROKE_NORMALIZE); - g.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, - RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY); - parent.getDependenciesPanel().drawDependencies(g); - ErdTable[] tablesArray = parent.getAllTablesArray(); + private void paintImage(Graphics2D graphics) { - for (int i = 0; i < tablesArray.length; i++) { - tablesArray[i].setSelected(false); - tablesArray[i].drawTable(g, tablesArray[i].getX(), tablesArray[i].getY()); + graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + graphics.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); + graphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON); + graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC); + graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); + graphics.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY); + graphics.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE); + graphics.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_NORMALIZE); + graphics.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY); + + parent.getDependenciesPanel().drawDependencies(graphics); + + ErdTable[] tablesArray = parent.getAllTablesArray(); + for (ErdTable erdTable : tablesArray) { + erdTable.setSelected(false); + erdTable.drawTable(graphics, erdTable.getX(), erdTable.getY()); } ErdTitlePanel title = parent.getTitlePanel(); - if (title != null) { title.setSelected(false); - title.drawTitlePanel(g, title.getX(), title.getY()); + title.drawTitlePanel(graphics, title.getX(), title.getY()); } } - public int getSaved() { - return savedResult; - } + private void browse() { - /** - *

Removes the listeners within the JPEG options - * components so changes do not propagate. - */ - private void removeListeners() { - qualityTextField.removeKeyListener(this); - qualityCombo.removeActionListener(this); - qualitySlider.removeChangeListener(this); - } + String fileExtension; + String fileDescription; - /** - *

Adds the listeners within the JPEG options components. - */ - private void addListeners() { - qualityTextField.addKeyListener(this); - qualityCombo.addActionListener(this); - qualitySlider.addChangeListener(this); - } + int imageType = imageTypeCombo.getSelectedIndex(); + if (imageType == EQ_FORMAT) { + fileDescription = bundleString("files", "Red Expert ERD"); + fileExtension = "eqd"; - /** - *

Processes a change in the sliders value. - * - * @param the event object - */ - public void stateChanged(ChangeEvent e) { - removeListeners(); + } else if (imageType == JPG_FORMAT) { + fileDescription = bundleString("files", "JPEG"); + fileExtension = "jpeg"; - int value = qualitySlider.getValue(); - qualityTextField.setText(Integer.toString(value)); + } else if (imageType == SVG_FORMAT) { + fileDescription = bundleString("files", "SVG"); + fileExtension = "svg"; - if (value == 10) - qualityCombo.setSelectedIndex(3); - else if (value >= 8) - qualityCombo.setSelectedIndex(2); - else if (value >= 3) - qualityCombo.setSelectedIndex(1); - else - qualityCombo.setSelectedIndex(0); + } else if (imageType == PNG_FORMAT) { + fileDescription = bundleString("files", "PNG"); + fileExtension = "png"; - addListeners(); + } else { + fileDescription = bundleString("files", "GIF"); + fileExtension = "gif"; + } - } + FileChooserDialog fileChooser = getFileChooserDialog(imageType, fileExtension, fileDescription); + int result = fileChooser.showDialog(GUIUtilities.getParentFrame(), Bundles.get("common.select.button")); + if (result == JFileChooser.CANCEL_OPTION) + return; - public void keyReleased(KeyEvent e) { - removeListeners(); - int value = qualityTextField.getValue(); + String filePath = null; + File file = fileChooser.getSelectedFile(); + if (file != null) { + if (file.exists()) { - if (value > 10) { - value = 10; - } + int overwriteResult = GUIUtilities.displayConfirmCancelDialog(bundleString("overwriteFile")); + if (overwriteResult == JOptionPane.CANCEL_OPTION) + return; - qualitySlider.setValue(value); + if (overwriteResult == JOptionPane.NO_OPTION) { + browse(); + return; + } + } - if (value == 10) - qualityCombo.setSelectedIndex(3); - else if (value >= 8) - qualityCombo.setSelectedIndex(2); - else if (value >= 3) - qualityCombo.setSelectedIndex(1); - else - qualityCombo.setSelectedIndex(0); + filePath = fileChooser.getSelectedFile().getAbsolutePath(); + } - addListeners(); - } + if (filePath != null) { + fileExtension = "." + fileExtension; + if (!filePath.endsWith(fileExtension)) + filePath += fileExtension; + } - public void keyPressed(KeyEvent e) { + filePathField.setText(filePath); } - public void keyTyped(KeyEvent e) { - } + private FileChooserDialog getFileChooserDialog(int imageType, String fileExtension, String fileDescription) { - private void enableOptionsPanels(int index) { + FileChooserDialog fileChooser = openPath != null ? + new FileChooserDialog(openPath) : + new FileChooserDialog(); - switch (index) { - case 0: - enableJpegPanel(false); - enableGifPanel(false); - enableSvgPanel(false); - break; - case 1: - enableJpegPanel(true); - enableGifPanel(false); - enableSvgPanel(false); - break; - case 2: - case 3: - enableJpegPanel(false); - enableGifPanel(true); - enableSvgPanel(false); - break; - case 4: - enableJpegPanel(false); - enableGifPanel(false); - enableSvgPanel(true); - break; - } + if (defaultFile != null && imageType == EQ_FORMAT) + fileChooser.setSelectedFile(defaultFile); - } + fileChooser.setDialogTitle(bundleString("selectFile")); + fileChooser.setDialogType(JFileChooser.OPEN_DIALOG); + fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY); + fileChooser.setFileFilter(new FileSelector(new String[]{fileExtension}, fileDescription)); - private void enableSvgPanel(boolean enable) { - svgFontCheckbox.setEnabled(enable); + return fileChooser; } - private void enableJpegPanel(boolean enable) { - qualityLabel.setEnabled(enable); - qualityTextField.setEnabled(enable); - qualityCombo.setEnabled(enable); - qualitySlider.setEnabled(enable); - } + private String saveApplicationFileFormat(File file) { + savedResult = parent.saveApplicationFileFormat(file); - private void enableGifPanel(boolean enable) { - backgroundCombo.setEnabled(enable); - backgroundLabel.setEnabled(enable); + fireFileOpened(file); + GUIUtilities.scheduleGC(); + + if (savedResult == SaveFunction.SAVE_COMPLETE) + GUIUtilities.setTabTitleForComponent(parent, ErdViewerPanel.TITLE + " - " + file.getName()); + + return "done"; } - /** - *

Performs the respective action upon selection - * of a button within this dialog. - * - * @param the ActionEvent - */ - public void actionPerformed(ActionEvent e) { - String command = e.getActionCommand(); + private void addListeners() { + qualityCombo.addActionListener(this); + qualityTextField.addKeyListener(this); + qualitySlider.addChangeListener(this); + } - if (command.equals("Cancel")) { - dispose(); - } else if (command.equals("Browse")) { - showFileChooser(); - return; - } else if (command.equals("Save")) { - final String path = pathField.getText(); - if (MiscUtils.isNull(path)) { - GUIUtilities.displayErrorMessage("You must enter a file name"); - return; - } + private void removeListeners() { + qualityTextField.removeKeyListener(this); + qualityCombo.removeActionListener(this); + qualitySlider.removeChangeListener(this); + } - final int fileFormat = imageTypeCombo.getSelectedIndex(); - if ((fileFormat == EQ_FORMAT && !path.endsWith(".eqd")) || - (fileFormat == JPEG_FORMAT && !path.endsWith(".jpeg")) || - (fileFormat == SVG_FORMAT && !path.endsWith(".svg")) || - (fileFormat == PNG_FORMAT && !path.endsWith(".png")) || - (fileFormat == GIF_FORMAT && !path.endsWith(".gif"))) { - GUIUtilities.displayErrorMessage("Invalid file extension for selected file type"); - return; - } + public int getSaved() { + return savedResult; + } - doSave(path, fileFormat); - return; - } + // --- ActionListener impl --- + @Override + public void actionPerformed(ActionEvent e) { removeListeners(); - Object object = e.getSource(); + Object object = e.getSource(); if (object == imageTypeCombo) { - enableOptionsPanels(imageTypeCombo.getSelectedIndex()); + enablePanel(imageTypeCombo.getSelectedIndex()); + } else if (object == qualityCombo) { int value = -1; int index = qualityCombo.getSelectedIndex(); @@ -721,70 +567,72 @@ else if (index == 3) qualitySlider.setValue(value); qualityTextField.setText(Integer.toString(value)); - } addListeners(); - } - private void doSave(final String path, final int fileFormat) { - SwingWorker worker = new SwingWorker("saveERD") { - public Object construct() { - try { - setVisible(false); - GUIUtilities.showWaitCursor(); - return save(path, fileFormat); - } finally { - GUIUtilities.showNormalCursor(); - } - } - - public void finished() { - GUIUtilities.showNormalCursor(); - if (savedResult == SaveFunction.SAVE_COMPLETE) { - dispose(); - } else { - setVisible(true); - } - } - }; - worker.start(); - } - - private String saveApplicationFileFormat(File file) { - - savedResult = parent.saveApplicationFileFormat(file); + // --- ChangeListener impl --- - fireFileOpened(file); - - GUIUtilities.scheduleGC(); - - if (savedResult == SaveFunction.SAVE_COMPLETE) { - - GUIUtilities.setTabTitleForComponent(parent, ErdViewerPanel.TITLE + - " - " + file.getName()); - } + @Override + public void stateChanged(ChangeEvent e) { + removeListeners(); - return "done"; - } + int value = qualitySlider.getValue(); + qualityTextField.setText(Integer.toString(value)); - private void fireFileOpened(File file) { + if (value == 10) + qualityCombo.setSelectedIndex(3); + else if (value >= 8) + qualityCombo.setSelectedIndex(2); + else if (value >= 3) + qualityCombo.setSelectedIndex(1); + else + qualityCombo.setSelectedIndex(0); - EventMediator.fireEvent( - new DefaultFileIOEvent(parent, FileIOEvent.OUTPUT_COMPLETE, - file.getAbsolutePath())); + addListeners(); } -} + // --- KeyListener impl --- + @Override + public void keyReleased(KeyEvent e) { + removeListeners(); + int value = qualityTextField.getValue(); + if (value > 10) + value = 10; + qualitySlider.setValue(value); + if (value == 10) + qualityCombo.setSelectedIndex(3); + else if (value >= 8) + qualityCombo.setSelectedIndex(2); + else if (value >= 3) + qualityCombo.setSelectedIndex(1); + else + qualityCombo.setSelectedIndex(0); + addListeners(); + } + @Override + public void keyPressed(KeyEvent e) { + } + @Override + public void keyTyped(KeyEvent e) { + } + // --- + private void fireFileOpened(File file) { + EventMediator.fireEvent(new DefaultFileIOEvent(parent, FileIOEvent.OUTPUT_COMPLETE, file.getAbsolutePath())); + } + private static String bundleString(String key, Object... args) { + return Bundles.get(ErdSaveDialog.class, key, args); + } +} diff --git a/src/org/executequery/gui/erd/ErdSelectionPanel.java b/src/org/executequery/gui/erd/ErdSelectionPanel.java index de2d16d05..25493dc7a 100644 --- a/src/org/executequery/gui/erd/ErdSelectionPanel.java +++ b/src/org/executequery/gui/erd/ErdSelectionPanel.java @@ -23,12 +23,11 @@ import org.executequery.GUIUtilities; import org.executequery.databasemediators.DatabaseConnection; import org.executequery.databaseobjects.NamedObject; -import org.executequery.datasource.ConnectionManager; import org.executequery.gui.WidgetFactory; import org.executequery.gui.browser.ConnectionsTreePanel; import org.executequery.localization.Bundles; import org.underworldlabs.jdbc.DataSourceException; -import org.underworldlabs.swing.DynamicComboBoxModel; +import org.underworldlabs.swing.ConnectionsComboBox; import org.underworldlabs.swing.GUIUtils; import org.underworldlabs.swing.ListSelectionPanel; @@ -49,12 +48,7 @@ public class ErdSelectionPanel extends JPanel /** * The connection combo selection */ - protected JComboBox connectionsCombo; - - /** - * The connections combo box model - */ - protected DynamicComboBoxModel connectionsModel; + protected ConnectionsComboBox connectionsCombo; /** * The add/remove table selections panel @@ -68,12 +62,11 @@ public class ErdSelectionPanel extends JPanel private final ErdViewerPanel erdViewer; public ErdSelectionPanel() { - this(null, null); + this(null); } - public ErdSelectionPanel(DatabaseConnection databaseConnection, ErdViewerPanel erdViewer) { + public ErdSelectionPanel(ErdViewerPanel erdViewer) { super(new GridBagLayout()); - this.databaseConnection = databaseConnection; this.erdViewer = erdViewer; init(); } @@ -82,10 +75,7 @@ private void init() { listPanel = new ListSelectionPanel(bundleString("availableTables"), bundleString("selected Tables")); - // combo boxes - Vector connections = ConnectionManager.getActiveConnections(); - connectionsModel = new DynamicComboBoxModel(connections); - connectionsCombo = WidgetFactory.createComboBox("connectionsCombo", connectionsModel); + connectionsCombo = WidgetFactory.createConnectionComboBox("connectionsCombo", true); connectionsCombo.addItemListener(this); setBorder(BorderFactory.createEtchedBorder()); @@ -112,9 +102,7 @@ private void init() { gbc.fill = GridBagConstraints.BOTH; add(listPanel, gbc); - if (connections.isEmpty()) - connectionsCombo.setEnabled(false); - else + if (connectionsCombo.getItemCount() > 0) connectionChanged(); setPreferredSize(new Dimension(700, 380)); @@ -135,7 +123,7 @@ public void itemStateChanged(ItemEvent event) { } private void connectionChanged() { - databaseConnection = (DatabaseConnection) connectionsCombo.getSelectedItem(); + databaseConnection = getSelectedConnection(); try { List tables = ConnectionsTreePanel.getPanelFromBrowser() @@ -148,12 +136,16 @@ private void connectionChanged() { tables.add(table.getTableName()); } } + populateTableValues(tables); + } catch (DataSourceException e) { GUIUtilities.displayExceptionErrorDialog( - "Error retrieving the tables names for the " + - "current connection.\n\nThe system returned:\n" + - e.getExtendedMessage(), e, this.getClass()); + "Error retrieving the tables names for the current connection." + + "\n\nThe system returned:\n" + e.getExtendedMessage(), + e, + this.getClass() + ); } } @@ -171,10 +163,14 @@ public boolean hasSelections() { public DatabaseConnection getDatabaseConnection() { if (databaseConnection == null) - return (DatabaseConnection) connectionsCombo.getSelectedItem(); + return getSelectedConnection(); return databaseConnection; } + private DatabaseConnection getSelectedConnection() { + return connectionsCombo.getSelectedConnection(); + } + private String bundleString(String key) { return Bundles.get(ErdSelectionPanel.class, key); } diff --git a/src/org/executequery/gui/erd/ErdTable.java b/src/org/executequery/gui/erd/ErdTable.java index 26dd62a42..22aa1acc4 100644 --- a/src/org/executequery/gui/erd/ErdTable.java +++ b/src/org/executequery/gui/erd/ErdTable.java @@ -22,6 +22,7 @@ import org.apache.batik.ext.awt.g2d.DefaultGraphics2D; import org.apache.commons.lang.ArrayUtils; +import org.executequery.gui.browser.ColumnConstraint; import org.executequery.gui.browser.ColumnData; import org.underworldlabs.swing.plaf.UIUtils; import org.underworldlabs.util.MiscUtils; @@ -965,6 +966,21 @@ public void setShowCommentOnFields(boolean showCommentOnFields) { this.showCommentOnFields = showCommentOnFields; } + public Vector getColumnConstraints() { + + if (columns == null) + return new Vector<>(); + + Vector columnConstraintVector = new Vector<>(); + for (ColumnData columnData : columns) { + Vector tempConstraintsVector = columnData.getColumnConstraintsVector(); + if (tempConstraintsVector != null) + columnConstraintVector.addAll(tempConstraintsVector); + } + + return columnConstraintVector; + } + static class ErdTableConnectionPoint { private final int axisType; diff --git a/src/org/executequery/gui/erd/ErdToolBarPalette.java b/src/org/executequery/gui/erd/ErdToolBarPalette.java index eb89ebac0..1dcf7ce97 100644 --- a/src/org/executequery/gui/erd/ErdToolBarPalette.java +++ b/src/org/executequery/gui/erd/ErdToolBarPalette.java @@ -22,16 +22,11 @@ import org.executequery.GUIUtilities; import org.executequery.actions.toolscommands.ComparerDBCommands; -import org.executequery.databasemediators.ConnectionMediator; -import org.executequery.databasemediators.DatabaseConnection; import org.executequery.datasource.ConnectionManager; import org.executequery.gui.BaseDialog; import org.executequery.gui.GenerateErdPanel; import org.executequery.gui.WidgetFactory; import org.executequery.localization.Bundles; -import org.executequery.repository.DatabaseConnectionRepository; -import org.executequery.repository.Repository; -import org.executequery.repository.RepositoryCache; import org.underworldlabs.swing.RolloverButton; import org.underworldlabs.swing.layouts.GridBagHelper; import org.underworldlabs.swing.toolbar.PanelToolBar; @@ -39,7 +34,6 @@ import javax.swing.*; import java.awt.*; import java.util.*; -import java.util.List; /** * @author Takis Diakoumis @@ -65,8 +59,6 @@ public class ErdToolBarPalette extends JPanel { private RolloverButton zoomInButton; private RolloverButton zoomOutButton; - private JComboBox connectionsCombo; - public ErdToolBarPalette(ErdViewerPanel parent) { super(); @@ -80,16 +72,6 @@ public ErdToolBarPalette(ErdViewerPanel parent) { private void init() { - List connections = ConnectionManager.getActiveConnections(); - Repository repo = RepositoryCache.load(DatabaseConnectionRepository.REPOSITORY_ID); - if (repo instanceof DatabaseConnectionRepository) - connections = ((DatabaseConnectionRepository) repo).findAll(); - - connectionsCombo = WidgetFactory.createComboBox( - "connectionsCombo", - connections.toArray() - ); - createTableButton = WidgetFactory.createRolloverButton( "createTableButton", bundleString("createTable"), @@ -187,18 +169,13 @@ private void init() { "icon_zoom_out", e -> parent.zoom(false) ); - - connections.stream() - .filter(DatabaseConnection::isConnected) - .findFirst().ifPresent(dc -> connectionsCombo.setSelectedItem(dc)); } private void arrange() { setLayout(new GridBagLayout()); GridBagHelper gbh = new GridBagHelper().anchorWest().fillHorizontally(); - add(connectionsCombo, gbh.setWeightX(0.2).get()); - add(createTableButton, gbh.nextCol().setMinWeightX().get()); + add(createTableButton, gbh.get()); add(dropTableButton, gbh.nextCol().get()); add(createRelationButton, gbh.nextCol().get()); add(deleteRelationButton, gbh.nextCol().get()); @@ -321,11 +298,17 @@ public void setScale(String scale) { } private void updateFromDatabase() { + + if (!ConnectionManager.hasConnections()) { + GUIUtilities.displayWarningMessage(bundleString("noActiveConnections")); + return; + } + try { GUIUtilities.showWaitCursor(); BaseDialog dialog = new BaseDialog(GenerateErdPanel.TITLE, false); - JPanel panel = new GenerateErdPanel(parent, dialog, getSelectedConnection()); + JPanel panel = new GenerateErdPanel(parent, dialog); dialog.addDisplayComponentWithEmptyBorder(panel); dialog.setResizable(false); @@ -369,25 +352,6 @@ private void updateScale() { parent.setPopupMenuScaleValue(selectedScaleIndex); } - public DatabaseConnection getSelectedConnection() { - - Object selectedItem = connectionsCombo.getSelectedItem(); - if (selectedItem instanceof DatabaseConnection) { - - DatabaseConnection connection = (DatabaseConnection) selectedItem; - if (!connection.isConnected()) - ConnectionMediator.getInstance().connect(connection, true); - - return connection; - } - - return null; - } - - public void setSelectedConnection(DatabaseConnection connection) { - connectionsCombo.setSelectedItem(connection); - } - private static String bundleString(String key) { return Bundles.get(ErdToolBarPalette.class, key); } diff --git a/src/org/executequery/gui/erd/ErdViewerPanel.java b/src/org/executequery/gui/erd/ErdViewerPanel.java index dcc65dd47..813c50a27 100644 --- a/src/org/executequery/gui/erd/ErdViewerPanel.java +++ b/src/org/executequery/gui/erd/ErdViewerPanel.java @@ -24,7 +24,6 @@ import org.executequery.Constants; import org.executequery.GUIUtilities; import org.executequery.base.DefaultTabView; -import org.executequery.databasemediators.DatabaseConnection; import org.executequery.gui.SaveFunction; import org.executequery.gui.browser.ColumnConstraint; import org.executequery.gui.browser.ColumnData; @@ -49,7 +48,7 @@ import java.util.Stack; import java.util.Vector; -import static org.executequery.databaseobjects.NamedObject.PRIMARY_KEY; +import static org.executequery.databaseobjects.NamedObject.FOREIGN_KEY; /** * @author Takis Diakoumis @@ -545,10 +544,12 @@ public Vector buildTableRelationships() { for (ColumnConstraint columnConstraint : cca) { - if (columnConstraint.getType() == PRIMARY_KEY) + if (columnConstraint.getType() != FOREIGN_KEY) continue; referencedTable = columnConstraint.getRefTable(); + if (referencedTable == null) + continue; for (int j = 0; j < m; j++) { @@ -1253,19 +1254,6 @@ public int getTextBlockFontStyle() { return textBlockFontStyle; } - public String getAllSQLText() { - - char newLine = '\n'; - ErdTable[] allTables = getAllTablesArray(); - - StringBuilder sb = new StringBuilder(); - for (ErdTable allTable : allTables) - if (allTable.hasSQLScripts()) - sb.append(allTable.getAllSQLScripts()).append(newLine); - - return sb.toString(); - } - public String getErdFileName() { return fileName; } @@ -1280,14 +1268,6 @@ public String toString() { return TITLE + " - " + fileName; } - public DatabaseConnection getDatabaseConnection() { - return tools.getSelectedConnection(); - } - - public void setDatabaseConnection(DatabaseConnection databaseConnection) { - tools.setSelectedConnection(databaseConnection); - } - // -------------------------------------------- // TabView implementation // -------------------------------------------- diff --git a/src/org/executequery/gui/exportData/AbstractExportHelper.java b/src/org/executequery/gui/exportData/AbstractExportHelper.java index 1c42eda45..4640c596f 100644 --- a/src/org/executequery/gui/exportData/AbstractExportHelper.java +++ b/src/org/executequery/gui/exportData/AbstractExportHelper.java @@ -208,11 +208,11 @@ private String saveBlobToFile(byte[] lobData, String lobType, String fileName, b // --- protected final void displayErrorMessage(Throwable e) { - GUIUtilities.displayExceptionErrorDialog(bundleString("ErrorWritingToFile") + e.getMessage(), e, this.getClass()); + GUIUtilities.displayExceptionErrorDialog(bundleString("ErrorWritingToFile", e.getMessage()), e, this.getClass()); } - protected final String bundleString(String key) { - return Bundles.get(ExportDataPanel.class, key); + protected final String bundleString(String key, Object... args) { + return Bundles.get(ExportDataPanel.class, key, args); } } diff --git a/src/org/executequery/gui/exportData/ExportDataPanel.java b/src/org/executequery/gui/exportData/ExportDataPanel.java index 0bbac8de2..f21c6422f 100644 --- a/src/org/executequery/gui/exportData/ExportDataPanel.java +++ b/src/org/executequery/gui/exportData/ExportDataPanel.java @@ -20,7 +20,7 @@ package org.executequery.gui.exportData; -import org.executequery.ApplicationContext; +import org.executequery.Constants; import org.executequery.GUIUtilities; import org.executequery.components.FileChooserDialog; import org.executequery.databaseobjects.DatabaseColumn; @@ -32,6 +32,7 @@ import org.underworldlabs.swing.layouts.GridBagHelper; import org.underworldlabs.util.FileUtils; import org.underworldlabs.util.MiscUtils; +import org.underworldlabs.util.PanelsStateProperties; import org.underworldlabs.util.SystemProperties; import javax.swing.*; @@ -43,7 +44,6 @@ import java.awt.event.MouseEvent; import java.io.*; import java.nio.charset.StandardCharsets; -import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Paths; import java.sql.ResultSet; @@ -101,6 +101,7 @@ public class ExportDataPanel extends AbstractBaseDialog { private final Object exportData; private final String tableNameForExport; + private final ParametersSaver parametersSaver; private final List databaseColumns; private Map components; @@ -116,6 +117,7 @@ public ExportDataPanel(Object exportData, String tableNameForExport, List 0) { @@ -626,14 +640,6 @@ private ExportHelper getExportHelper() { // --- getters --- - public static String getParametersSaverFilePath() { - return new ParametersSaver().getFileName(); - } - - public static String getParametersSaverDelimiter() { - return new ParametersSaver().getDelimiter(); - } - protected List getDatabaseColumns() { return databaseColumns; } @@ -685,89 +691,66 @@ protected boolean isOpenQueryEditor() { // --- inner classes --- private static class ParametersSaver { + private final PanelsStateProperties stateProperties; - private final String FILE_NAME = - ApplicationContext.getInstance().getUserSettingsHome() + FileSystems.getDefault().getSeparator() + "resultsExporter.save"; - private final String DELIMITER = "==="; + public ParametersSaver() { + stateProperties = new PanelsStateProperties(ExportDataPanel.class.getName()); + } void save(Map components) { - // clear old values - try (PrintWriter writer = new PrintWriter(new FileWriter(FILE_NAME, false))) { - writer.print(""); - - } catch (IOException e) { - Log.error("Error saving ExportDataPanel values", e); - } - - // save new values - try (PrintWriter writer = new PrintWriter(new FileWriter(FILE_NAME, true))) { + for (String key : components.keySet()) { + Object value = null; - for (String key : components.keySet()) { + Component component = components.get(key); + if (component instanceof JCheckBox) { + value = ((JCheckBox) component).isSelected(); - writer.print(key + DELIMITER); + } else if (component instanceof JTextField) { + value = ((JTextField) component).getText().trim(); - Component component = components.get(key); - if (component instanceof JCheckBox) { - writer.println(((JCheckBox) component).isSelected()); + } else if (component instanceof JComboBox) { - } else if (component instanceof JTextField) { - writer.println(((JTextField) component).getText().trim()); - - } else if (component instanceof JComboBox) { - - if (component.getName().equals(columnDelimiterComboName)) - writer.println(((JComboBox) component).getSelectedItem()); - else - writer.println(((JComboBox) component).getSelectedIndex()); - } + if (component.getName().equals(columnDelimiterComboName)) + value = ((JComboBox) component).getSelectedItem(); + else + value = ((JComboBox) component).getSelectedIndex(); } - } catch (IOException e) { - Log.error("Error saving ExportDataPanel values", e); + if (value == null) + value = Constants.EMPTY; + + stateProperties.put(key, value.toString()); } + + stateProperties.save(); } void restore(Map components) { - try (BufferedReader reader = new BufferedReader(new FileReader(FILE_NAME))) { - - String line; - while ((line = reader.readLine()) != null) { - String[] data = line.split(DELIMITER); - - Component component = components.get(data[0]); - String value = data.length > 1 ? data[1] : ""; + for (String key : components.keySet()) { + Component component = components.get(key); - if (component instanceof JCheckBox) { - ((JCheckBox) component).setSelected(value.equalsIgnoreCase("true")); + String value = stateProperties.get(key); + if (value == null) + continue; - } else if (component instanceof JTextField) { - ((JTextField) component).setText(value); + if (component instanceof JCheckBox) { + ((JCheckBox) component).setSelected(value.equalsIgnoreCase("true")); - } else if (component instanceof JComboBox) { + } else if (component instanceof JTextField) { + ((JTextField) component).setText(value); - if (component.getName().equals(columnDelimiterComboName)) - ((JComboBox) component).setSelectedItem(value); - else - ((JComboBox) component).setSelectedIndex(Integer.parseInt(value)); + } else if (component instanceof JComboBox) { - } + if (component.getName().equals(columnDelimiterComboName)) + ((JComboBox) component).setSelectedItem(value); + else + ((JComboBox) component).setSelectedIndex(Integer.parseInt(value)); } - - } catch (IOException e) { - Log.error("Error restoring ExportDataPanel values", e); } } - String getFileName() { - return FILE_NAME; - } - - String getDelimiter() { - return DELIMITER; - } - } // class ParameterSaver private static class ColumnTableModel implements TableModel { @@ -903,12 +886,12 @@ public String getType() { @Override public void dispose() { - new ParametersSaver().save(components); + parametersSaver.save(components); super.dispose(); } - private static String bundleString(String key) { - return Bundles.get(ExportDataPanel.class, key); + private static String bundleString(String key, Object... args) { + return Bundles.get(ExportDataPanel.class, key, args); } } diff --git a/src/org/executequery/gui/importData/ImportDataPanel.java b/src/org/executequery/gui/importData/ImportDataPanel.java index 5e3f44a4c..0cb114e74 100644 --- a/src/org/executequery/gui/importData/ImportDataPanel.java +++ b/src/org/executequery/gui/importData/ImportDataPanel.java @@ -25,6 +25,7 @@ import org.underworldlabs.swing.table.TableSorter; import org.underworldlabs.swing.util.SwingWorker; import org.underworldlabs.util.MiscUtils; +import org.underworldlabs.util.PanelsStateProperties; import javax.swing.*; import javax.swing.filechooser.FileNameExtensionFilter; @@ -131,7 +132,9 @@ private void init() { delimiterCombo = WidgetFactory.createComboBox("delimiterCombo", delimiters); delimiterCombo.setEditable(true); - setDelimiterComboSelectedValue("columnDelimiterCombo", delimiterCombo); + String selectedValue = getDelimiterComboSelectedValue(); + if (selectedValue != null) + delimiterCombo.setSelectedItem(selectedValue); delimiterCombo.addActionListener(e -> previewSourceFile(false)); targetTableCombo = WidgetFactory.createComboBox("targetTableCombo"); @@ -859,23 +862,9 @@ private void updateSourcePropertiesFields() { previewSourceFile(false); } - private void setDelimiterComboSelectedValue(@SuppressWarnings("SameParameterValue") String key, JComboBox combo) { - - try (BufferedReader reader = new BufferedReader(new FileReader(ExportDataPanel.getParametersSaverFilePath()))) { - - String line; - while ((line = reader.readLine()) != null) { - - String[] data = line.split(ExportDataPanel.getParametersSaverDelimiter()); - if (data[0].equals(key)) { - if (data.length > 1) - combo.setSelectedItem(data[1]); - break; - } - } - - } catch (IOException ignored) { - } + private String getDelimiterComboSelectedValue() { + PanelsStateProperties stateProperties = new PanelsStateProperties(ExportDataPanel.class.getName()); + return stateProperties.get("columnDelimiterCombo"); } private boolean targetNotSelected(boolean displayWarnings) { diff --git a/src/org/executequery/gui/prefs/PropertiesPanel.java b/src/org/executequery/gui/prefs/PropertiesPanel.java index c3b5b034e..2e18ad500 100644 --- a/src/org/executequery/gui/prefs/PropertiesPanel.java +++ b/src/org/executequery/gui/prefs/PropertiesPanel.java @@ -21,15 +21,16 @@ package org.executequery.gui.prefs; import org.executequery.*; -import org.executequery.components.BottomButtonPanel; import org.executequery.components.SplitPaneFactory; import org.executequery.components.table.PropertiesTreeCellRenderer; import org.executequery.event.DefaultUserPreferenceEvent; import org.executequery.event.UserPreferenceEvent; import org.executequery.gui.ActionContainer; +import org.executequery.gui.WidgetFactory; import org.executequery.localization.Bundles; import org.executequery.toolbars.ToolBarManager; import org.executequery.util.ThreadUtils; +import org.underworldlabs.swing.layouts.GridBagHelper; import org.underworldlabs.swing.tree.DynamicTree; import javax.swing.*; @@ -72,6 +73,8 @@ public class PropertiesPanel extends JPanel "startup.display.lookandfeel", "startup.display.language", "display.aa.fonts", + // -- PropertiesConnections -- + "treeconnection.row.height", // -- PropertiesEditorGeneral -- "editor.tabs.tospaces", "editor.tab.spaces" @@ -86,6 +89,7 @@ public class PropertiesPanel extends JPanel private final ActionContainer parent; private final Map preferenceChangeEvents; + private static boolean hasChanges; private static boolean updateEnvNeed; private static Integer lastSelectedRow; private static List> classesNeedRestart; @@ -192,14 +196,21 @@ private void init() { leftPanel.add(js, BorderLayout.CENTER); splitPane.setLeftComponent(leftPanel); + // --- buttons panel --- + + JButton saveButton = WidgetFactory.createButton("saveButton", Bundles.get("common.ok.button"), e -> save(false)); + JButton cancelButton = WidgetFactory.createButton("cancelButton", Bundles.get("common.cancel.button"), e -> cancel()); + JPanel buttonPanel = new JPanel(new GridBagLayout()); + + GridBagHelper gbh = new GridBagHelper().leftGap(5).topGap(5).fillHorizontally(); + buttonPanel.add(new JPanel(), gbh.setMaxWeightX().get()); + buttonPanel.add(saveButton, gbh.nextCol().setMinWeightX().fillNone().get()); + buttonPanel.add(cancelButton, gbh.nextCol().get()); + + // --- + mainPanel.add(splitPane, BorderLayout.CENTER); - mainPanel.add(new BottomButtonPanel( - e -> save(false), - null, - "prefs", - parent.isDialog() - ), BorderLayout.SOUTH - ); + mainPanel.add(buttonPanel, BorderLayout.SOUTH); add(mainPanel, BorderLayout.CENTER); panelMap = new HashMap<>(); @@ -347,8 +358,10 @@ public void save(boolean isApplyAction) { if (GUIUtilities.displayConfirmDialog(bundledString("restart-message")) == JOptionPane.YES_OPTION) ExecuteQuery.restart(ApplicationContext.getInstance().getRepo(), updateEnvNeed); - } else + } else if (isHasChanges()) { GUIUtilities.displayInformationMessage(bundledString("setting-applied")); + setHasChanges(false); + } } finally { GUIUtilities.showNormalCursor(); @@ -358,10 +371,23 @@ public void save(boolean isApplyAction) { parent.finished(); } + private void cancel() { + setHasChanges(false); + parent.finished(); + } + private UserPreferenceEvent createUserPreferenceEvent() { return new DefaultUserPreferenceEvent(this, null, UserPreferenceEvent.ALL); } + public static void setHasChanges(boolean hasChanges) { + PropertiesPanel.hasChanges = hasChanges; + } + + public static boolean isHasChanges() { + return hasChanges; + } + private boolean isRestartNeed() { return !classesNeedRestart.isEmpty(); } diff --git a/src/org/executequery/gui/prefs/UserPreference.java b/src/org/executequery/gui/prefs/UserPreference.java index c191cde95..b1139a77e 100644 --- a/src/org/executequery/gui/prefs/UserPreference.java +++ b/src/org/executequery/gui/prefs/UserPreference.java @@ -180,6 +180,7 @@ public void reset(Object value) { } public void setValue(Object value) { + PropertiesPanel.setHasChanges(true); this.value = value; } diff --git a/src/org/executequery/gui/procedure/CreateProcedureFunctionPanel.java b/src/org/executequery/gui/procedure/CreateProcedureFunctionPanel.java index 278398c4c..bac699f5b 100644 --- a/src/org/executequery/gui/procedure/CreateProcedureFunctionPanel.java +++ b/src/org/executequery/gui/procedure/CreateProcedureFunctionPanel.java @@ -33,6 +33,7 @@ import org.underworldlabs.swing.GUIUtils; import org.underworldlabs.swing.layouts.GridBagHelper; import org.underworldlabs.util.MiscUtils; +import org.underworldlabs.util.PanelsStateProperties; import org.underworldlabs.util.SystemProperties; import javax.swing.*; @@ -61,14 +62,19 @@ public abstract class CreateProcedureFunctionPanel extends AbstractCreateExterna protected KeyListener changeKeyListener; protected ActionListener changeActionListener; + private PanelsStateProperties stateProperties; // --- GUI components --- + private JSplitPane splitPane; + private JCheckBox showHelpersCheck; + protected ProcedureDefinitionPanel outputParamsPanel; protected ProcedureDefinitionPanel inputParamsPanel; protected ProcedureDefinitionPanel variablesPanel; protected SimpleSqlTextPanel ddlTextPanel; protected CursorsPanel cursorsPanel; + protected SubProgramPanel subProgramPanel; // --- @@ -89,12 +95,13 @@ public CreateProcedureFunctionPanel(DatabaseConnection dc, ActionContainer dialo @Override protected void init() { + stateProperties = new PanelsStateProperties(CreateProcedureFunctionPanel.class.getName()); - changeActionListener = e -> generateDdlScript(); + changeActionListener = e -> generateDdlScript(false); changeKeyListener = new KeyListener() { @Override public void keyReleased(KeyEvent e) { - generateDdlScript(); + generateDdlScript(false); } @Override @@ -110,56 +117,62 @@ public void keyPressed(KeyEvent e) { initExternal(); - engineField.addKeyListener(changeKeyListener); - externalField.addKeyListener(changeKeyListener); - authidCombo.addActionListener(changeActionListener); - securityCombo.addActionListener(changeActionListener); - useExternalCheck.addActionListener(changeActionListener); - // --- cursorsPanel = new CursorsPanel(); - cursorsPanel.addChangesListener(changeActionListener); + subProgramPanel = new SubProgramPanel(); inputParamsPanel = new ProcedureDefinitionPanel(ColumnData.INPUT_PARAMETER); inputParamsPanel.setDataTypes(connection.getDataTypesArray(), connection.getIntDataTypesArray()); inputParamsPanel.setDomains(getDomains()); inputParamsPanel.setDatabaseConnection(connection); - inputParamsPanel.addChangesListener(changeActionListener); outputParamsPanel = new ProcedureDefinitionPanel(ColumnData.OUTPUT_PARAMETER); outputParamsPanel.setDataTypes(connection.getDataTypesArray(), connection.getIntDataTypesArray()); outputParamsPanel.setDomains(getDomains()); outputParamsPanel.setDatabaseConnection(connection); - outputParamsPanel.addChangesListener(changeActionListener); variablesPanel = new ProcedureDefinitionPanel(ColumnData.VARIABLE); variablesPanel.setDataTypes(connection.getDataTypesArray(), connection.getIntDataTypesArray()); variablesPanel.setDomains(getDomains()); variablesPanel.setDatabaseConnection(connection); - variablesPanel.addChangesListener(changeActionListener); ddlTextPanel = new SimpleSqlTextPanel(false, true, "DDL"); + ddlTextPanel.setMinimumSize(new Dimension(500, ddlTextPanel.getPreferredSize().height)); ddlTextPanel.getTextPane().setDatabaseConnection(connection); + ddlTextPanel.getTextPane().addKeyListener(new KeyAdapter() { + @Override + public void keyReleased(KeyEvent e) { + procedureBody = extractProcedureBody(ddlTextPanel.getSQLText()); + } + }); tabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT); tabbedPane.add(bundleString("InputParameters"), inputParamsPanel); tabbedPane.add(bundleString("OutputParameters"), outputParamsPanel); tabbedPane.add(bundleString("Variables"), variablesPanel); tabbedPane.add(bundleString("Cursors"), cursorsPanel); + tabbedPane.add(bundleString("Subprograms"), subProgramPanel); addCommentTab(null); - nameField.addKeyListener(changeKeyListener); - simpleCommentPanel.getCommentField().getTextAreaComponent().addKeyListener(changeKeyListener); + showHelpersCheck = WidgetFactory.createCheckBox("showHelpersCheck", bundleString("showHelpersCheck")); arrange(); checkExternal(); fillSqlBody(); + String value = stateProperties.get(showHelpersCheck.getName()); + showHelpersCheck.setSelected(value == null || Boolean.parseBoolean(value)); + if (!showHelpersCheck.isSelected()) + showHelpersCheckTriggered(); + try { - generateDdlScript(); + generateDdlScript(false); } catch (Exception ignored) { } + + if (!editing) + addListeners(); } protected void initEditing() { @@ -191,7 +204,8 @@ protected void initEditing() { addDependenciesTab((DatabaseObject) namedObject); reset(); - generateDdlScript(); + addListeners(); + generateDdlScript(false); } private void arrange() { @@ -199,18 +213,19 @@ private void arrange() { // --- split pane --- - JSplitPane splitPane = new JSplitPane(); + splitPane = new JSplitPane(); splitPane.setLeftComponent(tabbedPane); splitPane.setRightComponent(ddlTextPanel); splitPane.setOneTouchExpandable(true); - splitPane.setDividerLocation(0.5); + splitPane.setResizeWeight(1.0); // --- button panel --- JPanel buttonPanel = new JPanel(new GridBagLayout()); gbh = new GridBagHelper().leftGap(5).topGap(5).fillHorizontally().anchorNorthEast(); - buttonPanel.add(new JPanel(), gbh.setMaxWeightX().get()); + buttonPanel.add(showHelpersCheck, gbh.get()); + buttonPanel.add(new JPanel(), gbh.nextCol().setMaxWeightX().get()); buttonPanel.add(actionButton, gbh.nextCol().setMinWeightX().fillNone().get()); buttonPanel.add(submitButton, gbh.nextCol().get()); buttonPanel.add(cancelButton, gbh.nextCol().get()); @@ -222,7 +237,7 @@ private void arrange() { gbh = new GridBagHelper().setInsets(5, 5, 5, 0).anchorNorthWest().fillBoth(); mainPanel.add(topPanel, gbh.setMinWeightY().spanX().get()); mainPanel.add(splitPane, gbh.nextRow().setMaxWeightY().setMaxWeightY().get()); - mainPanel.add(buttonPanel, gbh.nextRow().fillNone().anchorNorthEast().setMinWeightY().bottomGap(5).get()); + mainPanel.add(buttonPanel, gbh.nextRow().fillHorizontally().anchorNorthEast().setMinWeightY().bottomGap(5).get()); // --- base --- @@ -235,42 +250,85 @@ private void arrange() { setPreferredSize(new Dimension(1200, 600)); } + private void addListeners() { + nameField.addKeyListener(changeKeyListener); + engineField.addKeyListener(changeKeyListener); + externalField.addKeyListener(changeKeyListener); + authidCombo.addActionListener(changeActionListener); + cursorsPanel.addChangesListener(changeActionListener); + subProgramPanel.addChangesListener(changeActionListener); + securityCombo.addActionListener(changeActionListener); + variablesPanel.addChangesListener(changeActionListener); + useExternalCheck.addActionListener(changeActionListener); + inputParamsPanel.addChangesListener(changeActionListener); + outputParamsPanel.addChangesListener(changeActionListener); + showHelpersCheck.addActionListener(e -> showHelpersCheckTriggered()); + simpleCommentPanel.getCommentField().getTextAreaComponent().addKeyListener(changeKeyListener); + } + + private void showHelpersCheckTriggered() { + boolean selected = showHelpersCheck.isSelected(); + tabbedPane.setVisible(selected); + splitPane.setDividerLocation(splitPane.getMaximumDividerLocation()); + splitPane.updateUI(); + + stateProperties.put(showHelpersCheck.getName(), String.valueOf(selected)); + stateProperties.save(); + } + @SuppressWarnings("DataFlowIssue") - protected void generateDdlScript() { + protected void generateDdlScript(boolean extractBody) { - TreeSet variables = new TreeSet<>(); - variables = fillTreeSetFromTableVector(variables, variablesPanel.tableVector); - variables = fillTreeSetFromTableVector(variables, cursorsPanel.getCursorsVector()); + if (isParseVariables()) { + TreeSet variables = new TreeSet<>(); + variables = fillTreeSetFromTableVector(variables, variablesPanel.tableVector); + variables = fillTreeSetFromTableVector(variables, cursorsPanel.getCursorsVector()); + variables = fillTreeSetFromTableVector(variables, subProgramPanel.getSubProgsVector()); + ddlTextPanel.getTextPane().setVariables(variables); + } TreeSet parameters = new TreeSet<>(); parameters = fillTreeSetFromTableVector(parameters, inputParamsPanel.tableVector); parameters = fillTreeSetFromTableVector(parameters, outputParamsPanel.tableVector); - ddlTextPanel.getTextPane().setVariables(variables); + ddlTextPanel.getTextPane().setParameters(parameters); - procedureBody = extractProcedureBody(ddlTextPanel.getSQLText()); + if (extractBody) + procedureBody = extractProcedureBody(ddlTextPanel.getSQLText()); ddlTextPanel.setSQLText(generateQuery()); } - private String extractProcedureBody(String sqlText) { + protected abstract String getUpperScript(); - if (MiscUtils.isNull(sqlText)) - return procedureBody; + protected abstract String getDownScript(); - sqlText = sqlText.trim(); - int beginIndex = sqlText.toUpperCase().indexOf("BEGIN"); - int endIndex = sqlText.toUpperCase().lastIndexOf("END") + 3; - procedureBody = sqlText.substring(beginIndex, endIndex); + private String extractProcedureBody(String sqlText) { + if (MiscUtils.isNull(sqlText)) + return procedureBody; + String upScript = getUpperScript(); + String[] upLines = upScript.split("\n"); + String downScript = getDownScript(); + String[] downLines = downScript.split("\n"); + String[] allLines = sqlText.split("\n"); + if (allLines.length > upLines.length + downLines.length) { + procedureBody = ""; + int n = allLines.length - downLines.length + 1; + for (int i = upLines.length; i < n; i++) { + procedureBody += allLines[i]; + if (i < n - 1) + procedureBody += "\n"; + } + } return procedureBody; } - private void loadVariables() { // remove first empty row variablesPanel.clearRows(); cursorsPanel.clearRows(); + subProgramPanel.clearRows(); String fullProcedureBody = getFullSourceBody(); if (fullProcedureBody != null && !fullProcedureBody.isEmpty()) { @@ -295,140 +353,178 @@ public void enterDeclare_block_without_params(ProcedureParserParser.Declare_bloc ProcedureParserParser.Full_bodyContext bodyContext = ctx.full_body(); procedureBody = bodyContext.getText(); - List vars = ctx.local_variable(); + List vars = ctx.declare_stmt(); if (!vars.isEmpty()) { boolean firstVar = true; boolean firstCursor = true; + boolean firstProc = true; + int order = 0; + + for (ProcedureParserParser.Declare_stmtContext dstmt : vars) { + if (dstmt.local_variable() != null) { + ProcedureParserParser.Local_variableContext var = dstmt.local_variable(); + if (var.cursor() == null) { + + ProcedureParameter variable = new ProcedureParameter( + var.variable_name().getText(), + DatabaseMetaData.procedureColumnUnknown, + 0, + "", + 0, + 0 + ); + variable.setPosition(order); + + ProcedureParserParser.DatatypeContext type = var.datatype(); + if (type != null && !type.isEmpty()) { + + if (type.domain_name() != null && !type.domain_name().isEmpty()) { + + String domain = type.domain_name().getText(); + if (!domain.startsWith("\"")) + domain = domain.toUpperCase(); + + variable.setDomain(domain); + } - for (ProcedureParserParser.Local_variableContext var : vars) { - if (var.cursor() == null) { + if (type.datatypeSQL() != null && !type.datatypeSQL().isEmpty()) { - ProcedureParameter variable = new ProcedureParameter( - var.variable_name().getText(), - DatabaseMetaData.procedureColumnUnknown, - 0, - "", - 0, - 0 - ); + List children = type.datatypeSQL().children; + variable.setSqlType(children.get(0).getText()); - ProcedureParserParser.DatatypeContext type = var.datatype(); - if (type != null && !type.isEmpty()) { + if (type.datatypeSQL().type_size() != null && !type.datatypeSQL().type_size().isEmpty()) + variable.setSize(Integer.parseInt(type.datatypeSQL().type_size().getText().trim())); - if (type.domain_name() != null && !type.domain_name().isEmpty()) { + if (type.datatypeSQL().scale() != null && !type.datatypeSQL().scale().isEmpty()) + variable.setScale(Integer.parseInt(type.datatypeSQL().scale().getText().trim())); - String domain = type.domain_name().getText(); - if (!domain.startsWith("\"")) - domain = domain.toUpperCase(); + if (type.datatypeSQL().subtype() != null && !type.datatypeSQL().subtype().isEmpty()) { - variable.setDomain(domain); - } + if (type.datatypeSQL().subtype().any_name() != null && !type.datatypeSQL().subtype().any_name().isEmpty()) + variable.setSubType(1); - if (type.datatypeSQL() != null && !type.datatypeSQL().isEmpty()) { + if (type.datatypeSQL().subtype().int_number() != null && !type.datatypeSQL().subtype().int_number().isEmpty()) + variable.setSubType(Integer.parseInt(type.datatypeSQL().subtype().int_number().getText().trim())); + } - List children = type.datatypeSQL().children; - variable.setSqlType(children.get(0).getText()); + if (type.datatypeSQL().charset_name() != null && !type.datatypeSQL().charset_name().isEmpty()) + variable.setEncoding(type.datatypeSQL().charset_name().getText()); + } - if (type.datatypeSQL().type_size() != null && !type.datatypeSQL().type_size().isEmpty()) - variable.setSize(Integer.parseInt(type.datatypeSQL().type_size().getText().trim())); + if (type.type_of() != null && !type.type_of().isEmpty()) { - if (type.datatypeSQL().scale() != null && !type.datatypeSQL().scale().isEmpty()) - variable.setScale(Integer.parseInt(type.datatypeSQL().scale().getText().trim())); + if (type.type_of().domain_name() != null && !type.type_of().domain_name().isEmpty()) { + variable.setDomain(type.type_of().domain_name().getText()); + variable.setTypeOfFrom(ColumnData.TYPE_OF_FROM_DOMAIN); + } - if (type.datatypeSQL().subtype() != null && !type.datatypeSQL().subtype().isEmpty()) { + if (type.type_of().column_name() != null && !type.type_of().column_name().isEmpty()) { + variable.setRelationName(type.type_of().table_name().getText()); + variable.setFieldName(type.type_of().column_name().getText()); + variable.setTypeOfFrom(ColumnData.TYPE_OF_FROM_COLUMN); + } + } + } - if (type.datatypeSQL().subtype().any_name() != null && !type.datatypeSQL().subtype().any_name().isEmpty()) - variable.setSubType(1); + if (var.notnull() != null && !var.notnull().isEmpty()) + variable.setNullable(0); + else + variable.setNullable(1); - if (type.datatypeSQL().subtype().int_number() != null && !type.datatypeSQL().subtype().int_number().isEmpty()) - variable.setSubType(Integer.parseInt(type.datatypeSQL().subtype().int_number().getText().trim())); - } + if (var.default_statement() != null) + variable.setDefaultValue(var.default_statement().getText()); - if (type.datatypeSQL().charset_name() != null && !type.datatypeSQL().charset_name().isEmpty()) - variable.setEncoding(type.datatypeSQL().charset_name().getText()); - } + if (var.comment() != null) { - if (type.type_of() != null && !type.type_of().isEmpty()) { + String description = var.comment().getText(); + if (description.startsWith("--")) { + description = description.substring(2); + variable.setDescriptionAsSingleComment(true); - if (type.type_of().domain_name() != null && !type.type_of().domain_name().isEmpty()) { - variable.setDomain(type.type_of().domain_name().getText()); - variable.setTypeOfFrom(ColumnData.TYPE_OF_FROM_DOMAIN); - } + } else if (description.startsWith("/*")) + description = description.substring(2, description.length() - 2); - if (type.type_of().column_name() != null && !type.type_of().column_name().isEmpty()) { - variable.setRelationName(type.type_of().table_name().getText()); - variable.setFieldName(type.type_of().column_name().getText()); - variable.setTypeOfFrom(ColumnData.TYPE_OF_FROM_COLUMN); - } + variable.setDescription(description); } - } - if (var.notnull() != null && !var.notnull().isEmpty()) - variable.setNullable(0); - else - variable.setNullable(1); + if (firstVar) + variablesPanel.deleteEmptyRow(); - if (var.default_statement() != null) - variable.setDefaultValue(var.default_statement().getText()); + firstVar = false; + variablesPanel.addRow(variable); - if (var.comment() != null) { + } else { - String description = var.comment().getText(); - if (description.startsWith("--")) { - description = description.substring(2); - variable.setDescriptionAsSingleComment(true); + ColumnData cursor = new ColumnData(connection); + cursor.setColumnPosition(order); + cursor.setCursor(true); - } else if (description.startsWith("/*")) - description = description.substring(2, description.length() - 2); + if (var.variable_name() != null) + cursor.setColumnName(var.variable_name().getText()); - variable.setDescription(description); - } + if (var.cursor().scroll() != null) + cursor.setScroll(var.cursor().scroll().getText().contentEquals("SCROLL")); + else + cursor.setScroll(false); - if (firstVar) - variablesPanel.deleteEmptyRow(); + if (var.cursor().operator_select() != null) + cursor.setSelectOperator(var.cursor().operator_select().operator_select_in().getText()); - firstVar = false; - variablesPanel.addRow(variable); + if (var.comment() != null) { - } else { + String description = var.comment().getText(); + if (description.startsWith("--")) { + description = description.substring(2); + cursor.setRemarkAsSingleComment(true); - ColumnData cursor = new ColumnData(connection); - cursor.setCursor(true); + } else if (description.startsWith("/*")) + description = description.substring(2, description.length() - 2); - if (var.variable_name() != null) - cursor.setColumnName(var.variable_name().getText()); + cursor.setRemarks(description); + } - if (var.cursor().scroll() != null) - cursor.setScroll(var.cursor().scroll().getText().contentEquals("SCROLL")); - else - cursor.setScroll(false); + if (firstCursor) + cursorsPanel.deleteEmptyRow(); - if (var.cursor().operator_select() != null) - cursor.setSelectOperator(var.cursor().operator_select().operator_select_in().getText()); + firstCursor = false; + cursorsPanel.addRow(cursor); + } + } else if (dstmt.declare_procedure_stmt() != null) { + ProcedureParserParser.Declare_procedure_stmtContext var = dstmt.declare_procedure_stmt(); + ColumnData cursor = new ColumnData(connection); + cursor.setColumnPosition(order); + cursor.setTypeName("PROCEDURE"); - if (var.comment() != null) { + if (var.procedure_name() != null) + cursor.setColumnName(var.procedure_name().getText()); + cursor.setSelectOperator(var.getText()); + if (firstProc) + subProgramPanel.deleteEmptyRow(); - String description = var.comment().getText(); - if (description.startsWith("--")) { - description = description.substring(2); - cursor.setRemarkAsSingleComment(true); + firstProc = false; + subProgramPanel.addRow(cursor); - } else if (description.startsWith("/*")) - description = description.substring(2, description.length() - 2); + } else if (dstmt.declare_function_stmt() != null) { + ProcedureParserParser.Declare_function_stmtContext var = dstmt.declare_function_stmt(); + ColumnData cursor = new ColumnData(connection); + cursor.setColumnPosition(order); + cursor.setTypeName("FUNCTION"); - cursor.setRemarks(description); - } + if (var.procedure_name() != null) + cursor.setColumnName(var.procedure_name().getText()); + cursor.setSelectOperator(var.getText()); - if (firstCursor) - cursorsPanel.deleteEmptyRow(); + if (firstProc) + subProgramPanel.deleteEmptyRow(); - firstCursor = false; - cursorsPanel.addRow(cursor); + firstProc = false; + subProgramPanel.addRow(cursor); } + order++; } - } + } } }, tree); } @@ -452,6 +548,7 @@ protected void checkExternal() { if (tabbedPane.indexOfComponent(variablesPanel) > 0) { tabbedPane.remove(variablesPanel); tabbedPane.remove(cursorsPanel); + tabbedPane.remove(subProgramPanel); } } else { @@ -529,7 +626,7 @@ private void columnChangeConnection(DatabaseConnection dc) { } private void connectionChanged() { - DatabaseConnection connection = (DatabaseConnection) connectionsCombo.getSelectedItem(); + DatabaseConnection connection = getSelectedConnection(); // reset meta data inputParamsPanel.setDatabaseConnection(connection); @@ -607,8 +704,9 @@ protected void fillSqlBody() { if (isParseVariables()) { if (tabbedPane.indexOfComponent(variablesPanel) < 0) { - tabbedPane.insertTab(bundleString("Variables"), null, variablesPanel, null, 3); - tabbedPane.insertTab(bundleString("Cursors"), null, cursorsPanel, null, 4); + tabbedPane.insertTab(bundleString("Variables"), null, variablesPanel, null, 2); + tabbedPane.insertTab(bundleString("Cursors"), null, cursorsPanel, null, 3); + tabbedPane.insertTab(bundleString("Subprograms"), null, subProgramPanel, null, 4); } loadVariables(); @@ -617,6 +715,7 @@ protected void fillSqlBody() { if (tabbedPane.indexOfComponent(variablesPanel) > 0) { tabbedPane.remove(variablesPanel); tabbedPane.remove(cursorsPanel); + tabbedPane.remove(subProgramPanel); } if (procedureName != null) diff --git a/src/org/executequery/gui/procedure/SubProgramPanel.java b/src/org/executequery/gui/procedure/SubProgramPanel.java new file mode 100644 index 000000000..a2620f190 --- /dev/null +++ b/src/org/executequery/gui/procedure/SubProgramPanel.java @@ -0,0 +1,415 @@ +package org.executequery.gui.procedure; + +import org.executequery.Constants; +import org.executequery.databasemediators.DatabaseConnection; +import org.executequery.gui.DefaultTable; +import org.executequery.gui.browser.ColumnData; +import org.executequery.gui.table.CreateTableToolBar; +import org.executequery.gui.table.TableDefinitionPanel; +import org.executequery.gui.text.SimpleSqlTextPanel; +import org.executequery.localization.Bundles; +import org.underworldlabs.swing.layouts.GridBagHelper; +import org.underworldlabs.swing.print.AbstractPrintableTableModel; + +import javax.swing.*; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import javax.swing.table.TableCellEditor; +import javax.swing.table.TableColumnModel; +import javax.swing.table.TableModel; +import java.awt.*; +import java.awt.event.ActionListener; +import java.util.Vector; + +public class SubProgramPanel extends JPanel implements DefinitionPanel { + private final boolean editing; + private static final int NAME_COLUMN = 0; + private static final int TYPE_COLUMN = 1; + private CreateTableToolBar toolBar; + private SimpleSqlTextPanel sqlTextPanel; + private ProcedureParameterModel parameterModel; + private int selectedRow; + private DatabaseConnection connection; + private Vector subProgsVector; + private DatabaseTable cursorsTable; + + public SubProgramPanel() { + this(true); + } + + public SubProgramPanel(boolean editing) { + super(new GridBagLayout()); + this.editing = editing; + this.selectedRow = -1; + + init(); + arrange(); + } + + private void init() { + toolBar = new CreateTableToolBar(this); + + // --- table --- + + parameterModel = new ProcedureParameterModel(); + + cursorsTable = new DatabaseTable(parameterModel); + cursorsTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); + cursorsTable.getSelectionModel().addListSelectionListener(e -> selectionChanged()); + + TableColumnModel tcm = cursorsTable.getColumnModel(); + tcm.getColumn(NAME_COLUMN).setPreferredWidth(200); + tcm.getColumn(TYPE_COLUMN).setPreferredWidth(120); + + // --- sql text panel --- + + sqlTextPanel = new SimpleSqlTextPanel(); + sqlTextPanel.setMinimumSize(new Dimension(100, 200)); + sqlTextPanel.getTextPane().getSQLSyntaxDocument().addDocumentListener(new DocumentListener() { + + @Override + public void changedUpdate(DocumentEvent e) { + if (selectedRow >= 0) { + subProgsVector.get(selectedRow).setSelectOperator(sqlTextPanel.getSQLText()); + parameterModel.fireTableRowsUpdated(selectedRow, selectedRow); + } + } + + @Override + public void insertUpdate(DocumentEvent e) { + } + + @Override + public void removeUpdate(DocumentEvent e) { + } + + }); + + // --- cell editors --- + + if (!editing) { + } + } + + private void arrange() { + GridBagHelper gbh; + + // --- table panel --- + + JPanel tablePanel = new JPanel(new GridBagLayout()); + + gbh = new GridBagHelper().anchorNorthWest().fillVertical(); + tablePanel.add(toolBar, gbh.setMinWeightX().rightGap(2).spanY().get()); + tablePanel.add(new JScrollPane(cursorsTable), gbh.nextCol().bottomGap(10).setMaxWeightX().fillBoth().spanX().get()); + + // --- split pane --- + + JSplitPane splitPane = new JSplitPane(); + splitPane.setTopComponent(tablePanel); + splitPane.setBottomComponent(sqlTextPanel); + splitPane.setDividerLocation(0.5); + splitPane.setOrientation(JSplitPane.VERTICAL_SPLIT); + + // --- base --- + + setLayout(new GridBagLayout()); + setPreferredSize(new Dimension(300, 200)); + setMinimumSize(getPreferredSize()); + + gbh = new GridBagHelper().setInsets(0, 0, 0, 0).fillBoth().spanX().spanY(); + add(splitPane, gbh.get()); + } + + public void addRow(ColumnData cd) { + cd.setCursor(true); + subProgsVector.add(cd); + } + + private void selectionChanged() { + if (cursorsTable.getSelectedRow() >= 0) { + selectedRow = cursorsTable.getSelectedRow(); + sqlTextPanel.setSQLText(subProgsVector.get(selectedRow).getSelectOperator()); + } + } + + public void setDatabaseConnection(DatabaseConnection databaseConnection) { + connection = databaseConnection; + subProgsVector.forEach(columnData -> columnData.setConnection(connection)); + } + + public int getSelectedRow() { + return cursorsTable.getSelectedRow(); + } + + public boolean isEditing() { + return cursorsTable.isEditing(); + } + + public void insertRow(ColumnData cd, int position) { + subProgsVector.insertElementAt(cd, position); + } + + public void removeRow(int position) { + subProgsVector.remove(position); + } + + public void clearRows() { + subProgsVector.clear(); + } + + public void fireEditingStopped() { + cursorsTable.editingStopped(null); + if (cursorsTable.isEditing()) + cursorsTable.removeEditor(); + } + + public void deleteEmptyRow() { + + cursorsTable.editingStopped(null); + if (cursorsTable.isEditing()) + cursorsTable.removeEditor(); + + if (subProgsVector.isEmpty()) + return; + + removeRow(0); + parameterModel.fireTableRowsDeleted(0, 0); + } + + public void setRowSelectionInterval(int row) { + cursorsTable.setRowSelectionInterval(row, row); + } + + public String getSQLText() { + return sqlTextPanel.getSQLText(); + } + + public Vector getSubProgsVector() { + return subProgsVector; + } + + public ProcedureParameterModel getProcedureParameterModel() { + return parameterModel; + } + + // --- DefinitionPanel impl --- + + /** + *

Inserts a new column after the selected + * column moving the selected column up one row. + */ + @Override + public void addRow() { + fireEditingStopped(); + + int lastRow = subProgsVector.size() - 1; + int newRow = lastRow + 1; + + ColumnData columnData = new ColumnData(connection); + columnData.setCursor(true); + addRow(columnData); + + parameterModel.fireTableRowsInserted(lastRow, newRow); + cursorsTable.setRowSelectionInterval(newRow, newRow); + cursorsTable.setColumnSelectionInterval(1, 1); + + cursorsTable.setEditingRow(newRow); + cursorsTable.setEditingColumn(NAME_COLUMN); + ((DefaultCellEditor) cursorsTable.getCellEditor(newRow, NAME_COLUMN)).getComponent().requestFocus(); + } + + /** + *

Deletes the selected row from the table. + * This will also modify the SQL generated text. + */ + @Override + public void deleteRow() { + + cursorsTable.editingStopped(null); + if (cursorsTable.isEditing()) + cursorsTable.removeEditor(); + + int selection = cursorsTable.getSelectedRow(); + if (selection == -1 || subProgsVector.isEmpty()) + return; + + removeRow(selection); + parameterModel.fireTableRowsDeleted(selection, selection); + + if (subProgsVector.isEmpty()) { + addRow(new ColumnData(true, connection)); + parameterModel.fireTableRowsInserted(0, 0); + } + } + + /** + *

Moves the selected column up one row within + * the table moving the column above the selection + * below the selection. + */ + @Override + public void moveRowUp() { + + int selection = cursorsTable.getSelectedRow(); + if (selection == -1 || selection == 0) + return; + + cursorsTable.editingStopped(null); + if (cursorsTable.isEditing()) + cursorsTable.removeEditor(); + + int newPosition = selection - 1; + ColumnData columnDataToMove = subProgsVector.elementAt(selection); + + removeRow(selection); + insertRow(columnDataToMove, newPosition); + cursorsTable.setRowSelectionInterval(newPosition, newPosition); + parameterModel.fireTableRowsUpdated(newPosition, selection); + } + + /** + *

Moves the selected column down one row within + * the table moving the column below the selection + * above the selection. + */ + @Override + public void moveRowDown() { + + int selectedRow = cursorsTable.getSelectedRow(); + if (selectedRow == -1 || selectedRow == subProgsVector.size() - 1) + return; + + cursorsTable.editingStopped(null); + if (cursorsTable.isEditing()) + cursorsTable.removeEditor(); + + int newPosition = selectedRow + 1; + ColumnData columnDataToMove = subProgsVector.elementAt(selectedRow); + + removeRow(selectedRow); + insertRow(columnDataToMove, newPosition); + cursorsTable.setRowSelectionInterval(newPosition, newPosition); + parameterModel.fireTableRowsUpdated(selectedRow, newPosition); + } + + public void addChangesListener(ActionListener listener) { + parameterModel.addTableModelListener(e -> listener.actionPerformed(null)); + } + + private static class DatabaseTable extends DefaultTable { + + public DatabaseTable(TableModel _model) { + super(_model); + getTableHeader().setReorderingAllowed(false); + setCellSelectionEnabled(true); + setColumnSelectionAllowed(false); + setRowSelectionAllowed(false); + setSurrendersFocusOnKeystroke(true); + } + + @Override + public TableCellEditor getCellEditor(int row, int col) { + return super.getCellEditor(row, col); + } + + } + + private class ProcedureParameterModel extends AbstractPrintableTableModel { + + protected String[] header = Bundles.get(TableDefinitionPanel.class, new String[]{ + "Name", "Datatype" + }); + + public ProcedureParameterModel() { + subProgsVector = new Vector<>(); + ColumnData cd = new ColumnData(connection); + cd.setCursor(true); + addRow(cd); + } + + @Override + public int getColumnCount() { + return header.length; + } + + @Override + public int getRowCount() { + return subProgsVector.size(); + } + + /** + * Returns the printable value at the specified row and column. + * + * @param row the row index + * @param col the column index + * @return the value to print + */ + @Override + public String getPrintValueAt(int row, int col) { + + if (col < 0) + return Constants.EMPTY; + + Object value = getValueAt(row, col); + if (value != null) + return value.toString(); + + return Constants.EMPTY; + } + + @Override + public Object getValueAt(int row, int col) { + + if (row >= subProgsVector.size()) + return null; + + ColumnData cd = subProgsVector.elementAt(row); + switch (col) { + + case NAME_COLUMN: + return cd.getColumnName(); + + case TYPE_COLUMN: + return cd.getTypeName(); + + default: + return null; + } + } + + @Override + public void setValueAt(Object value, int row, int col) { + + ColumnData cd = subProgsVector.elementAt(row); + switch (col) { + + case NAME_COLUMN: + cd.setColumnName((String) value); + break; + + case TYPE_COLUMN: + cd.setTypeName((String) value); + break; + } + + fireTableRowsUpdated(row, row); + } + + @Override + public boolean isCellEditable(int row, int col) { + return false; + } + + @Override + public String getColumnName(int col) { + return header[col]; + } + + @Override + public Class getColumnClass(int col) { + return String.class; + } + + } // CreateTableModel class + +} diff --git a/src/org/executequery/gui/resultset/ResultSetTableCellRenderer.java b/src/org/executequery/gui/resultset/ResultSetTableCellRenderer.java index ed4363630..a22bc2f5c 100644 --- a/src/org/executequery/gui/resultset/ResultSetTableCellRenderer.java +++ b/src/org/executequery/gui/resultset/ResultSetTableCellRenderer.java @@ -22,7 +22,6 @@ import org.executequery.Constants; import org.executequery.databaseobjects.Types; -import org.executequery.localization.Bundles; import org.underworldlabs.util.MiscUtils; import org.underworldlabs.util.SystemProperties; @@ -448,6 +447,7 @@ public Component getTableCellRendererComponent( setBackground(selectionBackground); } else if (row == table.getSelectedRow()) { + setForeground(tableForeground); setBackground(focusRowBackground); } else { diff --git a/src/org/executequery/gui/table/ColumnKeyRenderer.java b/src/org/executequery/gui/table/ColumnKeyRenderer.java index d1c11063a..2a9d90c6d 100644 --- a/src/org/executequery/gui/table/ColumnKeyRenderer.java +++ b/src/org/executequery/gui/table/ColumnKeyRenderer.java @@ -22,7 +22,6 @@ import org.executequery.databaseobjects.DatabaseColumn; import org.executequery.databaseobjects.impl.DatabaseTableColumn; -import org.executequery.gui.IconManager; import javax.swing.*; import javax.swing.table.DefaultTableCellRenderer; @@ -31,95 +30,54 @@ /** * @author takisd */ -public class ColumnKeyRenderer extends DefaultTableCellRenderer { - - /** - * foreign key image icon - */ - private ImageIcon fkImage; - - /** - * primary key image icon - */ - private ImageIcon pkImage; - - /** - * primary/foreign key image icon - */ - private ImageIcon pkfkImage; - - /** - * deleted flag icon - */ - private ImageIcon deleteImage; - - /** - * new column flag icon - */ - private ImageIcon newImage; - - public ColumnKeyRenderer() { - deleteImage = IconManager.getIcon("icon_mark_delete"); - newImage = IconManager.getIcon("icon_mark_new"); - fkImage = IconManager.getIcon("icon_key_foreign"); - pkImage = IconManager.getIcon("icon_key_primary"); - pkfkImage = IconManager.getIcon("icon_key_mixed"); - } +public class ColumnKeyRenderer extends DefaultTableCellRenderer + implements ColumnKeyStates { - public Component getTableCellRendererComponent(JTable table, - Object value, - boolean isSelected, - boolean hasFocus, - int row, int col) { + @Override + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) { - if (col > 0) { - return super.getTableCellRendererComponent( - table, value, isSelected, hasFocus, row, col); - } + if (col > 0) + return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col); + + Icon icon = null; + String tooltip = null; + + if (value instanceof DatabaseColumn) { + DatabaseColumn databaseColumn = (DatabaseColumn) value; + + if (databaseColumn.isPrimaryKey()) { + if (databaseColumn.isForeignKey()) { + tooltip = primaryForeignTooltip; + icon = primaryForeignImage; - if (value != null) { - DatabaseColumn column = (DatabaseColumn) value; - if (column.isPrimaryKey()) { - if (column.isForeignKey()) { - setIcon(pkfkImage); - setToolTipText("Primary Key/Foreign Key"); } else { - setIcon(pkImage); - setToolTipText("Primary Key"); + tooltip = primaryTooltip; + icon = primaryImage; } - } else if (column.isForeignKey()) { - setIcon(fkImage); - setToolTipText("Foreign Key"); - } else { - setIcon(null); - setToolTipText(null); + + } else if (databaseColumn.isForeignKey()) { + tooltip = foreignTooltip; + icon = foreignImage; } - // if its an editable column - check its state - // and reset icons and tooltips accordingly - if (column instanceof DatabaseTableColumn) { - DatabaseTableColumn _column = (DatabaseTableColumn) column; - if (_column.isMarkedDeleted()) { - setIcon(deleteImage); - setToolTipText("This column marked to be dropped"); - } else if (_column.isNewColumn()) { - setIcon(newImage); - setToolTipText("This column marked new"); + if (databaseColumn instanceof DatabaseTableColumn) { + DatabaseTableColumn databaseTableColumn = (DatabaseTableColumn) databaseColumn; + + if (databaseTableColumn.isMarkedDeleted()) { + tooltip = deleteTooltip; + icon = deleteImage; + + } else if (databaseTableColumn.isNewColumn()) { + tooltip = newTooltip; + icon = newImage; } } - } + setIcon(icon); + setToolTipText(tooltip); setHorizontalAlignment(JLabel.CENTER); - return this; } } - - - - - - - diff --git a/src/org/executequery/gui/table/ColumnKeyStates.java b/src/org/executequery/gui/table/ColumnKeyStates.java new file mode 100644 index 000000000..6f67533fc --- /dev/null +++ b/src/org/executequery/gui/table/ColumnKeyStates.java @@ -0,0 +1,22 @@ +package org.executequery.gui.table; + +import org.executequery.gui.IconManager; +import org.executequery.localization.Bundles; + +import javax.swing.*; + +public interface ColumnKeyStates { + + ImageIcon newImage = IconManager.getIcon("icon_mark_new"); + ImageIcon deleteImage = IconManager.getIcon("icon_mark_delete"); + ImageIcon primaryImage = IconManager.getIcon("icon_key_primary"); + ImageIcon foreignImage = IconManager.getIcon("icon_key_foreign"); + ImageIcon primaryForeignImage = IconManager.getIcon("icon_key_mixed"); + + String newTooltip = Bundles.get(ColumnKeyStates.class, "newTooltip"); + String deleteTooltip = Bundles.get(ColumnKeyStates.class, "deleteTooltip"); + String primaryTooltip = Bundles.get(ColumnKeyStates.class, "primaryTooltip"); + String foreignTooltip = Bundles.get(ColumnKeyStates.class, "foreignTooltip"); + String primaryForeignTooltip = Bundles.get(ColumnKeyStates.class, "primaryForeignTooltip"); + +} diff --git a/src/org/executequery/gui/table/CreateTablePanel.java b/src/org/executequery/gui/table/CreateTablePanel.java index ad3717f29..087d9fda9 100644 --- a/src/org/executequery/gui/table/CreateTablePanel.java +++ b/src/org/executequery/gui/table/CreateTablePanel.java @@ -26,6 +26,7 @@ import org.executequery.databaseobjects.DatabaseTypeConverter; import org.executequery.databaseobjects.NamedObject; import org.executequery.databaseobjects.T; +import org.executequery.databaseobjects.impl.DefaultDatabaseHost; import org.executequery.gui.ActionContainer; import org.executequery.gui.FocusComponentPanel; import org.executequery.gui.WidgetFactory; @@ -54,9 +55,12 @@ import javax.swing.event.DocumentListener; import javax.swing.filechooser.FileNameExtensionFilter; import java.awt.*; -import java.awt.event.*; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; import java.io.File; -import java.util.Collections; +import java.util.LinkedList; import java.util.List; import java.util.Objects; import java.util.Vector; @@ -75,128 +79,71 @@ public class CreateTablePanel extends AbstractSQLSecurityObjectPanel TableConstraintFunction, TextEditorContainer { - public static final String TITLE = Bundles.get(CreateTablePanel.class, "title"); - + public static final String TITLE = bundledString("title"); public static final String FRAME_ICON = "icon_table_add"; - protected JComboBox tablespacesCombo; + // --- GUI components --- - protected DynamicComboBoxModel tablespaceComboModel; + private JComboBox tablespacesCombo; + private JComboBox temporaryTypeCombo; - /** - * The components for creating EXTERNAL table - */ - protected JCheckBox isExternalTable; //checking for creating EXTERNAL table - protected JPanel externalTablePropsPanel; //panel with components for creating EXTERNAL table - protected JTextField externalTableFilePathField; //path to table data file - protected JButton browseExternalTableFileButton; //button for open selectFileDialog - protected JCheckBox isAdapterNeeded; //checking for using ADAPTER table + private JCheckBox isExternalCheck; + private JCheckBox isAdapterNeededCheck; + protected JCheckBox showTableCommentCheck; + protected JCheckBox showFieldCommentCheck; - /** - * The table column definition panel - */ - protected NewTablePanel tablePanel; + private DynamicComboBoxModel tablespaceComboModel; - /** - * The table constraints panel - */ - protected NewTableConstraintsPanel consPanel; + private JButton browseExternalFileButton; + private JTextField externalFileField; - /** - * The text pane showing SQL generated - */ - protected SimpleSqlTextPanel sqlText; - /** - * The buffer off all SQL generated - */ - protected StringBuffer sqlBuffer; + private JPanel externalPanel; + private NewTablePanel tablePanel; + private SimpleSqlTextPanel sqlText; + private NewTableConstraintsPanel consPanel; - /** - * The toolbar - */ - private CreateTableToolBar colTools; - private CreateTableToolBar conTools; - - /** - * The base panel - */ - protected JPanel mainPanel; - private JComboBox typeTemporaryBox; + private CreateTableToolBar columnsToolBar; + private CreateTableToolBar constraintsToolBar; - protected JCheckBox showCommentOnTableBox; - protected JCheckBox showCommentOnFieldsBox; + // --- - /** - *

Constructs a new instance. - */ public CreateTablePanel(DatabaseConnection dc, ActionContainer dialog) { super(dc, dialog, null, null); } - @Override - protected void reset() { - - } + // --- AbstractCreateObjectPanel impl --- + @Override protected void init() { - initSQLSecurity(); - securityCombo.addActionListener(actionEvent -> setSQLText()); + securityCombo.addActionListener(e -> setSQLText()); connectionsCombo.addItemListener(this); - colTools = new CreateTableToolBar(this); - conTools = new CreateTableToolBar(this); + + columnsToolBar = new CreateTableToolBar(this); + constraintsToolBar = new CreateTableToolBar(this); + tablespaceComboModel = new DynamicComboBoxModel(new Vector<>()); tablespacesCombo = WidgetFactory.createComboBox("tablespaceCombo", tablespaceComboModel); tablespacesCombo.addItemListener(this); - JPanel columnsPanel = new JPanel(new GridBagLayout()); + + sqlText = new SimpleSqlTextPanel(); tablePanel = new NewTablePanel(this); - GridBagHelper gbh = new GridBagHelper(); - gbh.setDefaultsStatic(); - columnsPanel.add(colTools, gbh.setLabelDefault().fillVertical().spanY().get()); - columnsPanel.add(tablePanel, gbh.nextCol().fillBoth().spanX().spanY().get()); - tabbedPane.add(bundledString("Columns"), columnsPanel); - // create the constraints table and model - JPanel constraintsPanel = new JPanel(new GridBagLayout()); consPanel = new NewTableConstraintsPanel(this); - consPanel.setData(new Vector(0), true); - typeTemporaryBox = new JComboBox(new DefaultComboBoxModel(new String[]{"DELETE ROWS", "PRESERVE ROWS"})); - typeTemporaryBox.addActionListener(actionEvent -> setSQLText()); - gbh.setDefaultsStatic(); - constraintsPanel.add(conTools, gbh.setLabelDefault().fillVertical().spanY().get()); - constraintsPanel.add(consPanel, gbh.nextCol().fillBoth().spanX().spanY().get()); + consPanel.setData(new Vector<>(0), true); - tabbedPane.add(bundledString("Constraints"), constraintsPanel); + temporaryTypeCombo = WidgetFactory.createComboBox("temporaryTypeCombo", new String[]{"DELETE ROWS", "PRESERVE ROWS"}); + temporaryTypeCombo.addActionListener(e -> setSQLText()); - addCommentTab(null); - simpleCommentPanel.getCommentField().getTextAreaComponent().addKeyListener(new KeyListener() { - @Override - public void keyTyped(KeyEvent e) { - setSQLText(); - } - @Override - public void keyPressed(KeyEvent e) { - setSQLText(); - } - @Override - public void keyReleased(KeyEvent e) { - setSQLText(); - } - }); - - sqlText = new SimpleSqlTextPanel(); + isExternalCheck = WidgetFactory.createCheckBox("isExternalCheck", bundledString("IsExternalTableText")); + isExternalCheck.addActionListener(e -> externalTablePropsChanged()); - // ----- components for creating EXTERNAL table ----- + showTableCommentCheck = WidgetFactory.createCheckBox("showTableCommentCheck", Bundles.get(ErdPopupMenu.class, "DisplayCommentOnTable")); + showFieldCommentCheck = WidgetFactory.createCheckBox("showFieldCommentCheck", Bundles.get(ErdPopupMenu.class, "DisplayCommentsOnFields")); - isExternalTable = new JCheckBox(bundledString("IsExternalTableText")); - isExternalTable.addActionListener(e -> externalTablePropsChanged()); - - showCommentOnTableBox = new JCheckBox(Bundles.get(ErdPopupMenu.class, "DisplayCommentOnTable")); - showCommentOnFieldsBox = new JCheckBox(Bundles.get(ErdPopupMenu.class, "DisplayCommentsOnFields")); - - externalTableFilePathField = WidgetFactory.createTextField("externalTableFilePathField"); - externalTableFilePathField.getDocument().addDocumentListener(new DocumentListener() { + externalFileField = WidgetFactory.createTextField("externalFileField"); + externalFileField.getDocument().addDocumentListener(new DocumentListener() { @Override public void insertUpdate(DocumentEvent e) { @@ -215,95 +162,81 @@ public void changedUpdate(DocumentEvent e) { }); - browseExternalTableFileButton = WidgetFactory.createInlineFieldButton("browseExternalTableFileButton", bundledString("BrowseButtonText")); - browseExternalTableFileButton.addActionListener(e -> browseExternalTableFile()); + browseExternalFileButton = WidgetFactory.createButton("browseExternalTableFileButton", Bundles.get("common.browse.button")); + browseExternalFileButton.addActionListener(e -> browseExternalTableFile()); - isAdapterNeeded = new JCheckBox(bundledString("IsAdapterNeededText")); - isAdapterNeeded.addActionListener(e -> externalTablePropsChanged()); + isAdapterNeededCheck = WidgetFactory.createCheckBox("isAdapterNeededCheck", bundledString("IsAdapterNeededText")); + isAdapterNeededCheck.addActionListener(e -> externalTablePropsChanged()); - // ------ components arranging ----- - if (!(this instanceof CreateGlobalTemporaryTable)) - topGbh.addLabelFieldPair(topPanel, bundledString("Tablespace"), tablespacesCombo, null, false); - tablespacesCombo.setToolTipText(Bundles.get(TableDefinitionPanel.class, "Tablespace")); - tablespacesCombo.addActionListener(actionEvent -> setSQLText()); - if (this instanceof CreateGlobalTemporaryTable) { - topGbh.addLabelFieldPair(topPanel, bundledString("TypeTemporaryTable"), typeTemporaryBox, null, false); - } - if (connection != null) { - if (getDatabaseVersion() >= 3 && !(this instanceof CreateGlobalTemporaryTable)) { + arrange(); + addListeners(); - topPanel.add(isExternalTable, topGbh.nextRowFirstCol().setLabelDefault().get()); - - topPanel.add(isAdapterNeeded, topGbh.nextCol().get()); - } - } - if (this instanceof ErdNewTableDialog.CreateTableERDPanel) { - if (connection == null) - topGbh.nextRowFirstCol().previousCol(); - topPanel.add(showCommentOnTableBox, topGbh.nextCol().setLabelDefault().get()); - topPanel.add(showCommentOnFieldsBox, topGbh.nextCol().setLabelDefault().get()); - } - - // ----- external panel ----- - GridBagHelper gridBagHelper = new GridBagHelper(); - gridBagHelper.setDefaultsStatic(); - externalTablePropsPanel = new JPanel(new GridBagLayout()); - - gridBagHelper.addLabelFieldPair(externalTablePropsPanel, - bundledString("ExternalTableDataFileLabel"), externalTableFilePathField, - null, true, false); - - externalTablePropsPanel.add(browseExternalTableFileButton, - gridBagHelper.nextCol().setLabelDefault().get()); - - // ----- - - topPanel.add(externalTablePropsPanel, topGbh.nextRowFirstCol().spanX().spanY().fillHorizontally().get()); - tabbedPane.addTab("SQL", sqlText); - - // ------ - - setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4)); - //add(mainPanel, BorderLayout.CENTER); - - tabbedPane.addChangeListener(this); - nameField.addKeyListener(new java.awt.event.KeyAdapter() { - public void keyReleased(KeyEvent e) { - setSQLText(); - } - }); - - sqlBuffer = new StringBuffer(CreateTableSQLSyntax.CREATE_TABLE); - - // check initial values for possible value inits if (connection != null) { tablePanel.setDataTypes(connection.getDataTypesArray(), connection.getIntDataTypesArray()); tablePanel.setDomains(getDomains()); tablePanel.setGenerators(getGenerators()); - } else { + } else tablePanel.setDataTypes(T.DEFAULT_TYPES, DatabaseTypeConverter.getSQLDataTypesFromNames(T.DEFAULT_TYPES)); - } + tablePanel.setDatabaseConnection(connection); if (connection != null) populateTablespaces(connection); externalTablePropsChanged(); - conTools.enableButtons(false); - colTools.enableButtons(true); + constraintsToolBar.enableButtons(true); + columnsToolBar.enableButtons(true); centralPanel.setVisible(false); } @Override - protected void initEdited() { + @SuppressWarnings("unchecked") + protected String generateQuery() { + + String tablespace = (String) tablespacesCombo.getSelectedItem(); + if (Objects.equals(tablespace, PRIMARY.trim())) + tablespace = null; + + String adapter = null; + String externalFile = null; + if (isExternalCheck.isSelected()) { + externalFile = externalFileField.getText(); + if (isAdapterNeededCheck.isSelected()) + adapter = "CSV"; + } + + String comment = null; + if (!Objects.equals(simpleCommentPanel.getComment(), "")) + comment = simpleCommentPanel.getComment().trim(); + + return SQLUtils.generateCreateTable( + nameField.getText(), + tablePanel.getTableColumnDataVector(), + consPanel.getKeys(), + false, + this instanceof CreateGlobalTemporaryTable, + true, + true, + true, + "ON COMMIT " + temporaryTypeCombo.getSelectedItem(), + externalFile, + adapter, + (String) securityCombo.getSelectedItem(), + tablespace, + comment, + "^" + ); } @Override public void createObject() { - if (!checkFullType()) - return; - String queries = getSQLText(); - displayExecuteQueryDialog(queries, "^"); + if (checkFullType()) + displayExecuteQueryDialog(getSQLText(), "^"); + } + + @Override + public String getTypeObject() { + return NamedObject.META_TYPES[NamedObject.TABLE]; } @Override @@ -317,204 +250,205 @@ public String getEditTitle() { } @Override - public String getTypeObject() { - return NamedObject.META_TYPES[NamedObject.TABLE]; + protected void initEdited() { } @Override - public void setDatabaseObject(Object databaseObject) { + protected void reset() { } @Override - public void setParameters(Object[] params) { + public void setDatabaseObject(Object databaseObject) { } @Override - protected String generateQuery() { + public void setParameters(Object[] params) { + } - String tablespace = null; - if (tablespacesCombo.getSelectedItem() != null) - tablespace = ((NamedObject) tablespacesCombo.getSelectedItem()).getName(); + // --- - String externalFile = null; - String adapter = null; - if (isExternalTable.isSelected()) { - externalFile = externalTableFilePathField.getText(); + private void arrange() { + GridBagHelper gbh; - if (isAdapterNeeded.isSelected()) - adapter = "CSV"; - } + // --- columns panel --- - String comment = null; - if (!Objects.equals(simpleCommentPanel.getComment(), "")) - comment = simpleCommentPanel.getComment().trim(); + JPanel columnsPanel = new JPanel(new GridBagLayout()); - return SQLUtils.generateCreateTable( - nameField.getText(), tablePanel.getTableColumnDataVector(), consPanel.getKeys(), - false, this instanceof CreateGlobalTemporaryTable, true, true, true, - "ON COMMIT " + typeTemporaryBox.getSelectedItem(), - externalFile, adapter, (String) securityCombo.getSelectedItem(), tablespace, comment, "^"); - } + gbh = new GridBagHelper().setDefaultsStatic(); + columnsPanel.add(columnsToolBar, gbh.setLabelDefault().fillVertical().spanY().get()); + columnsPanel.add(tablePanel, gbh.nextCol().fillBoth().spanX().spanY().get()); - private void externalTablePropsChanged() { + // --- constraints panel --- - if (isExternalTable.isSelected()) { + JPanel constraintsPanel = new JPanel(new GridBagLayout()); - externalTablePropsPanel.setVisible(true); - isAdapterNeeded.setVisible(true); - setSQLText(); + gbh = new GridBagHelper().setDefaultsStatic(); + constraintsPanel.add(constraintsToolBar, gbh.setLabelDefault().fillVertical().spanY().get()); + constraintsPanel.add(consPanel, gbh.nextCol().fillBoth().spanX().spanY().get()); - } else { + // --- erd panel --- - externalTablePropsPanel.setVisible(false); - isAdapterNeeded.setVisible(false); - setSQLText(); - } + JPanel erdPanel = new JPanel(new GridBagLayout()); - } + gbh = new GridBagHelper().rightGap(5).fillHorizontally(); + erdPanel.add(showTableCommentCheck, gbh.get()); + erdPanel.add(showFieldCommentCheck, gbh.nextCol().rightGap(0).get()); + erdPanel.add(new JPanel(), gbh.nextCol().setMaxWeightX().get()); - public void sqlSecurityChanged(ActionEvent e) { - setSQLText(); - } + // --- external panel --- + externalPanel = new JPanel(new GridBagLayout()); - public void browseExternalTableFile() { + gbh = new GridBagHelper().rightGap(5).leftGap(2).fillHorizontally(); + externalPanel.add(new JLabel(bundledString("ExternalTableDataFileLabel")), gbh.setMinWeightX().get()); + externalPanel.add(externalFileField, gbh.nextCol().leftGap(0).setMaxWeightX().get()); + externalPanel.add(browseExternalFileButton, gbh.nextCol().setMinWeightX().rightGap(0).get()); - FileChooserDialog fileChooser = new FileChooserDialog(); - fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY); - fileChooser.setFileFilter( - new FileNameExtensionFilter("CSV Files", "csv")); - fileChooser.setMultiSelectionEnabled(false); + // --- top panel --- - fileChooser.setDialogTitle(bundledString("OpenFileDialogText")); - fileChooser.setDialogType(JFileChooser.OPEN_DIALOG); + if (!(this instanceof CreateGlobalTemporaryTable)) { + topPanel.add(new JLabel(bundledString("Tablespace")), topGbh.nextCol().topGap(3).setMinWeightX().get()); + topPanel.add(tablespacesCombo, topGbh.nextCol().topGap(0).setMaxWeightX().get()); - int result = fileChooser.showDialog( - GUIUtilities.getInFocusDialogOrWindow(), bundledString("OpenFileDialogButton")); - if (result == JFileChooser.CANCEL_OPTION) { + if (connection != null && getDatabaseVersion() >= 3) { + topPanel.add(isExternalCheck, topGbh.nextRowFirstCol().leftGap(2).setMinWeightX().setWidth(1).get()); + topPanel.add(isAdapterNeededCheck, topGbh.nextCol().get()); + topPanel.add(externalPanel, topGbh.nextRowFirstCol().fillHorizontally().spanX().get()); + } + } - return; + if (this instanceof CreateGlobalTemporaryTable) { + topPanel.add(new JLabel(bundledString("TypeTemporaryTable")), topGbh.nextCol().topGap(3).setMinWeightX().get()); + topPanel.add(temporaryTypeCombo, topGbh.nextCol().topGap(0).setMaxWeightX().get()); } - File file = fileChooser.getSelectedFile(); + if (this instanceof ErdNewTableDialog.CreateTableERDPanel) + topPanel.add(erdPanel, topGbh.nextRowFirstCol().fillHorizontally().spanX().get()); - if (!file.exists()) { + // --- tabbed pane filling --- - GUIUtilities.displayWarningMessage( - bundledString("FileDoesNotExistMessage")); - return; - } + tabbedPane.add(bundledString("Columns"), columnsPanel); + tabbedPane.add(bundledString("Constraints"), constraintsPanel); + addCommentTab(null); + tabbedPane.addTab("SQL", sqlText); + tabbedPane.addChangeListener(this); - externalTableFilePathField.setText(file.getAbsolutePath()); - externalTablePropsChanged(); + // --- base --- + setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4)); } - String[] getDomains() { - java.util.List domains = ConnectionsTreePanel.getPanelFromBrowser().getDefaultDatabaseHostFromConnection(getSelectedConnection()).getDatabaseObjectNamesForMetaTag(NamedObject.META_TYPES[NamedObject.DOMAIN]); - return domains.toArray(new String[domains.size()]); - } + private void addListeners() { + + KeyAdapter keyAdapter = new KeyAdapter() { + @Override + public void keyReleased(KeyEvent e) { + setSQLText(); + } + }; - String[] getGenerators() { - java.util.List generators = ConnectionsTreePanel.getPanelFromBrowser().getDefaultDatabaseHostFromConnection(getSelectedConnection()).getDatabaseObjectNamesForMetaTag(NamedObject.META_TYPES[NamedObject.SEQUENCE]); - return generators.toArray(new String[generators.size()]); + nameField.addKeyListener(keyAdapter); + simpleCommentPanel.getCommentField().getTextAreaComponent().addKeyListener(keyAdapter); } - /** - * Returns the selected connection from the panel's - * connections combo selection box. - * - * @return the selected connection properties object - */ - public DatabaseConnection getSelectedConnection() { - return (DatabaseConnection) connectionsCombo.getSelectedItem(); + protected void addButtonsPanel(JPanel buttonsPanel) { + add(buttonsPanel, BorderLayout.SOUTH); } - /** - * Returns the table name field. - */ - public Component getDefaultFocusComponent() { - return nameField; + private void externalTablePropsChanged() { + boolean isExternal = isExternalCheck.isSelected(); + externalPanel.setVisible(isExternal); + isAdapterNeededCheck.setVisible(isExternal); + + setSQLText(); } - /** - * Invoked when an item has been selected or deselected by the user. - * The code written for this method performs the operations - * that need to occur when an item is selected (or deselected). - */ - public void itemStateChanged(ItemEvent event) { - // interested in selections only - if (event.getStateChange() == ItemEvent.DESELECTED) { + public void browseExternalTableFile() { + + FileChooserDialog fileChooser = new FileChooserDialog(); + fileChooser.setFileFilter(new FileNameExtensionFilter("CSV Files", "csv")); + fileChooser.setDialogTitle(bundledString("OpenFileDialogText")); + fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY); + fileChooser.setDialogType(JFileChooser.OPEN_DIALOG); + fileChooser.setMultiSelectionEnabled(false); + + int result = fileChooser.showDialog(GUIUtilities.getInFocusDialogOrWindow(), Bundles.get("common.select.button")); + if (result == JFileChooser.CANCEL_OPTION) + return; + + File file = fileChooser.getSelectedFile(); + if (!file.exists()) { + GUIUtilities.displayWarningMessage(bundledString("FileDoesNotExistMessage")); return; } - final Object source = event.getSource(); - if (event.getSource() == tablespacesCombo) { - setSQLText(); + externalFileField.setText(file.getAbsolutePath()); + externalTablePropsChanged(); + } - } else - GUIUtils.startWorker(() -> { - try { - setInProcess(true); - if (source == connectionsCombo) - connectionChanged(); + private String[] getDomains() { + List domains = getDatabaseObjectNames(getSelectedConnection(), NamedObject.DOMAIN); + return domains.toArray(new String[0]); + } - } finally { - setInProcess(false); - } - }); + private String[] getGenerators() { + List generators = getDatabaseObjectNames(getSelectedConnection(), NamedObject.SEQUENCE); + return generators.toArray(new String[0]); } private void columnChangeConnection(DatabaseConnection dc) { - Vector cd = getTableColumnDataVector(); - for (ColumnData c : cd) { - c.setConnection(dc); - } + for (Object object : getTableColumnDataVector()) + if (object instanceof ColumnData) + ((ColumnData) object).setConnection(dc); } private void connectionChanged() { - // retrieve connection selection - DatabaseConnection connection = - (DatabaseConnection) connectionsCombo.getSelectedItem(); - // reset meta data - tablePanel.setDatabaseConnection(connection); - columnChangeConnection(connection); + DatabaseConnection selectedConnection = getSelectedConnection(); + tablePanel.setDatabaseConnection(selectedConnection); + columnChangeConnection(selectedConnection); - // reset data types try { - populateDataTypes(getDatabaseConnection().getDataTypesArray(), getDatabaseConnection().getIntDataTypesArray()); + DatabaseConnection databaseConnection = getDatabaseConnection(); + populateDataTypes(databaseConnection.getDataTypesArray(), databaseConnection.getIntDataTypesArray()); + } catch (DataSourceException e) { GUIUtilities.displayExceptionErrorDialog( - bundledString("error.retrieving", bundledString("data-types"), bundledString("selected-connection"), e.getExtendedMessage()), - e, this.getClass()); + bundledString("error.retrieving", + bundledString("data-types"), + bundledString("selected-connection"), + e.getExtendedMessage()), + e, + this.getClass() + ); + populateDataTypes(new String[0], new int[0]); } - populateTablespaces(connection); - + populateTablespaces(selectedConnection); } private void populateTablespaces(DatabaseConnection connection) { - List tss = ConnectionsTreePanel.getPanelFromBrowser().getDefaultDatabaseHostFromConnection(connection) - .getDatabaseObjectsForMetaTag(NamedObject.META_TYPES[NamedObject.TABLESPACE]); - if (tss == null) + + List tablespacesList = getDatabaseObjects(connection, NamedObject.TABLESPACE); + if (tablespacesList == null) { tablespacesCombo.setEnabled(false); - else { - Vector vector = new Vector<>(); - vector.add(null); - vector.addAll(tss); - tablespaceComboModel.setElements(vector); + return; } + + List tablespacesNames = new LinkedList<>(); + tablespacesNames.add(PRIMARY.trim()); + for (NamedObject namedObject : tablespacesList) + tablespacesNames.add(namedObject.getName()); + + tablespaceComboModel.setElements(tablespacesNames); } private void populateDataTypes(final String[] dataTypes, final int[] intDataTypes) { - GUIUtils.invokeAndWait(new Runnable() { - public void run() { - tablePanel.setDataTypes(dataTypes, intDataTypes); - tablePanel.setDomains(getDomains()); - tablePanel.setGenerators(getGenerators()); - } + GUIUtils.invokeAndWait(() -> { + tablePanel.setDataTypes(dataTypes, intDataTypes); + tablePanel.setDomains(getDomains()); + tablePanel.setGenerators(getGenerators()); }); } @@ -527,37 +461,17 @@ public void setSQLTextCaretPosition(int position) { sqlText.setCaretPosition(position); } - protected void addButtonsPanel(JPanel buttonsPanel) { - add(buttonsPanel, BorderLayout.SOUTH); - } - public void fireEditingStopped() { tablePanel.fireEditingStopped(); consPanel.fireEditingStopped(); } - public void setColumnDataArray(ColumnData[] cda) { - tablePanel.setColumnDataArray(cda); - } - - public void setColumnConstraintVector(Vector ccv, boolean fillCombos) { - consPanel.setData(ccv, fillCombos); + public void setColumnDataArray(ColumnData[] columnData) { + tablePanel.setColumnDataArray(columnData); } - public void setColumnConstraintsArray(ColumnConstraint[] cca, boolean fillCombos) { - Vector ccv = new Vector(cca.length); - Collections.addAll(ccv, cca); - consPanel.setData(ccv, fillCombos); - } - - /** - * Indicates that a [long-running] process has begun or ended - * as specified. This may trigger the glass pane on or off - * or set the cursor appropriately. - * - * @param inProcess - true | false - */ - public void setInProcess(boolean inProcess) { + public void setColumnConstraintVector(Vector constraintsVector, boolean fillCombos) { + consPanel.setData(constraintsVector, fillCombos); } public void resetSQLText() { @@ -565,11 +479,6 @@ public void resetSQLText() { consPanel.resetSQLText(); } - @Override - public void setSQLText() { - setSQLText(generateQuery()); - } - private void setSQLText(final String text) { GUIUtils.invokeLater(() -> sqlText.setSQLText(text)); } @@ -578,203 +487,205 @@ public String getSQLText() { return sqlText.getSQLText(); } - @Override - public String getTableName() { - return nameField.getText(); + private boolean checkFullType() { + + for (ColumnData columnData : getTableColumnData()) { + if (columnData.getTypeName() == null) { + GUIUtilities.displayErrorMessage(bundledString("error.select-type")); + tabbedPane.setSelectedIndex(0); + return false; + } + } + + return true; } - // ----------------------------------------------- + public ColumnData[] getTableColumnDataAndConstraints() { + ColumnData[] tableColumnData = tablePanel.getTableColumnData(); + ColumnConstraint[] constraintsArray = consPanel.getColumnConstraintArray(); - // constraints panel only - public void updateCellEditor(int col, int row, String value) { - } + for (ColumnData columnData : tableColumnData) { + columnData.setForeignKey(false); + columnData.resetConstraints(); + if (columnData.isPrimaryKey()) { + ColumnConstraint primaryConstraint = new ColumnConstraint(); + primaryConstraint.setName("PK_" + columnData.getTableName()); + primaryConstraint.setType(NamedObject.PRIMARY_KEY); + primaryConstraint.setColumn(columnData.getColumnName()); + columnData.addConstraint(primaryConstraint); + } - public void columnValuesChanging(int col, int row, String value) { - } + String tableName = columnData.getTableName(); + String columnName = columnData.getColumnName(); - public Vector getTableColumnDataVector() { - return tablePanel.getTableColumnDataVector(); - } + for (ColumnConstraint constraint : constraintsArray) { - public void stateChanged(ChangeEvent e) { - if (tabbedPane.getSelectedIndex() == 1) { - checkFullType(); - } - if (e.getSource() == sqlText) - setSQLText(); - } + String constraintColumn = constraint.getColumn(); + if (constraintColumn == null || !constraintColumn.equalsIgnoreCase(columnName)) + continue; - protected boolean checkFullType() { - for (int i = 0; i < getTableColumnData().length; i++) { - if (getTableColumnData()[i].getTypeName() == null) { - GUIUtilities.displayErrorMessage(bundledString("error.select-type")); - tabbedPane.setSelectedIndex(0); - return false; + columnData.setPrimaryKey(constraint.isPrimaryKey()); + columnData.setForeignKey(constraint.isForeignKey()); + columnData.setUniqueKey(constraint.isUniqueKey()); + + constraint.setTable(tableName); + constraint.setNewConstraint(true); + columnData.addConstraint(constraint); } } - return true; + + return tableColumnData; } - /* - private void tableTabs_changed() { - - if (tableTabs.getSelectedIndex() == 1) { - tools.enableButtons(false); - - // if (table.isEditing()) - // table.removeEditor(); - - } - else { - tools.enableButtons(true); - } - + private static DefaultDatabaseHost getDefaultDatabaseHost(DatabaseConnection connection) { + return ConnectionsTreePanel.getPanelFromBrowser().getDefaultDatabaseHostFromConnection(connection); } - */ - public ColumnData[] getTableColumnDataAndConstraints() { - String tableName; - ColumnData[] cda = tablePanel.getTableColumnData(); - ColumnConstraint[] cca = consPanel.getColumnConstraintArray(); + @SuppressWarnings("SameParameterValue") + private static List getDatabaseObjects(DatabaseConnection connection, int metaTag) { + return getDefaultDatabaseHost(connection).getDatabaseObjectsForMetaTag(NamedObject.META_TYPES[metaTag]); + } - for (ColumnData columnData : cda) { + private static List getDatabaseObjectNames(DatabaseConnection connection, int metaTag) { + return getDefaultDatabaseHost(connection).getDatabaseObjectNamesForMetaTag(NamedObject.META_TYPES[metaTag]); + } - // reset the keys - //columnData.setPrimaryKey(false); - columnData.setForeignKey(false); - columnData.resetConstraints(); + // --- ItemListener impl --- - tableName = columnData.getTableName(); + /** + * Invoked when an item has been selected or deselected by the user. + * The code written for this method performs the operations + * that need to occur when an item is selected (or deselected). + */ + @Override + public void itemStateChanged(ItemEvent event) { - String columnName = columnData.getColumnName(); + if (event.getStateChange() == ItemEvent.DESELECTED) + return; - for (ColumnConstraint columnConstraint : cca) { + final Object source = event.getSource(); + if (event.getSource() == tablespacesCombo) { + setSQLText(); + return; + } - String constraintColumn = columnConstraint.getColumn(); + GUIUtils.startWorker(() -> { + if (source == connectionsCombo) + connectionChanged(); + }); + } - if (constraintColumn != null - && constraintColumn.equalsIgnoreCase(columnName)) { + // --- TableModifier impl --- - if (columnConstraint.isPrimaryKey()) { - columnData.setPrimaryKey(true); - } else if (columnConstraint.isForeignKey()) { - columnData.setForeignKey(true); - } else if (columnConstraint.isUniqueKey()) { - columnData.setUniqueKey(true); - } + @Override + public void setSQLText() { + setSQLText(generateQuery()); + } - columnConstraint.setTable(tableName); - columnConstraint.setNewConstraint(true); - columnData.addConstraint(columnConstraint); - } + @Override + public String getTableName() { + return nameField.getText(); + } - } + // --- ChangeListener impl --- - } + @Override + public void stateChanged(ChangeEvent e) { - return cda; + if (tabbedPane.getSelectedIndex() == 1) + checkFullType(); + if (e.getSource() == sqlText) + setSQLText(); } - public void columnValuesChanging() { + // --- TableConstraintFunction impl --- + + @Override + public DatabaseConnection getSelectedConnection() { + return super.getSelectedConnection(); } @Override public List getTables() { - return ConnectionsTreePanel.getPanelFromBrowser().getDefaultDatabaseHostFromConnection(connection).getTableNames(); + return getDefaultDatabaseHost(connection).getTableNames(); } @Override public List getColumns(String table) { - return ConnectionsTreePanel.getPanelFromBrowser().getDefaultDatabaseHostFromConnection(connection).getColumnNames(table); + return getDefaultDatabaseHost(connection).getColumnNames(table); } + @Override public ColumnData[] getTableColumnData() { return tablePanel.getTableColumnData(); } - // ----------------------------------------------- - // -------- TableFunction implementations -------- - // ----------------------------------------------- + @Override + public Vector getTableColumnDataVector() { + return tablePanel.getTableColumnDataVector(); + } + + // --- DefinitionPanel impl --- @Override public void moveRowUp() { - int index = tabbedPane.getSelectedIndex(); - if (index == 0) { + if (tabbedPane.getSelectedIndex() == 0) tablePanel.moveColumnUp(); - } } @Override public void moveRowDown() { - int index = tabbedPane.getSelectedIndex(); - if (index == 0) { + if (tabbedPane.getSelectedIndex() == 0) tablePanel.moveColumnDown(); - } } @Override public void deleteRow() { - if (tabbedPane.getSelectedIndex() == 0) { + int selectedIndex = tabbedPane.getSelectedIndex(); + + if (selectedIndex == 0) tablePanel.deleteRow(); - } else if (tabbedPane.getSelectedIndex() == 1) { + else if (selectedIndex == 1) consPanel.deleteSelectedRow(); - } } @Override public void addRow() { - if (tabbedPane.getSelectedIndex() == 0) { + int selectedIndex = tabbedPane.getSelectedIndex(); + + if (selectedIndex == 0) tablePanel.insertAfter(); - } else if (tabbedPane.getSelectedIndex() == 1) { + else if (selectedIndex == 1) consPanel.insertRowAfter(); - } - } - - // ----------------------------------------------- - - public String getDisplayName() { - return ""; } - // ------------------------------------------------ - // ----- TextEditorContainer implementations ------ - // ------------------------------------------------ + // --- TextEditorContainer impl --- /** * Returns the SQL text pane as the TextEditor component * that this container holds. */ + @Override public TextEditor getTextEditor() { return sqlText; } - protected String bundleString(String key, Object... args) { - return Bundles.get(getClass(), key, args); - } + // --- FocusComponentPanel impl --- - private String bundledString(String key) { - return Bundles.get("CreateTableFunctionPanel." + key); + /** + * Returns the table name field. + */ + @Override + public Component getDefaultFocusComponent() { + return nameField; } - private String bundledString(String key, Object... args) { - return Bundles.get("CreateTableFunctionPanel." + key, args); + // --- + + private static String bundledString(String key, Object... args) { + return Bundles.get(CreateTablePanel.class, key, args); } } - - - - - - - - - - - - - - - diff --git a/src/org/executequery/gui/table/KeyCellRenderer.java b/src/org/executequery/gui/table/KeyCellRenderer.java index be360081b..0c850d141 100644 --- a/src/org/executequery/gui/table/KeyCellRenderer.java +++ b/src/org/executequery/gui/table/KeyCellRenderer.java @@ -20,8 +20,8 @@ package org.executequery.gui.table; -import org.executequery.gui.IconManager; import org.executequery.gui.browser.ColumnData; +import org.executequery.localization.Bundles; import javax.swing.*; import javax.swing.table.TableCellRenderer; @@ -31,96 +31,62 @@ * @author Takis Diakoumis */ public class KeyCellRenderer extends JLabel - implements TableCellRenderer { - - private static ImageIcon fkImage; - private static ImageIcon pkImage; - private static ImageIcon pkfkImage; - private static ImageIcon deleteImage; - private static ImageIcon newImage; - -// private static final String PRIMARY = "PK"; -// private static final String FOREIGN = "FK"; -// private static final String PRIMARY_AND_FOREIGN = "PKFK"; - - static { - deleteImage = IconManager.getIcon("icon_mark_delete"); - newImage = IconManager.getIcon("icon_mark_new"); - fkImage = IconManager.getIcon("icon_key_foreign"); - pkImage = IconManager.getIcon("icon_key_primary"); - pkfkImage = IconManager.getIcon("icon_key_mixed"); - } + implements TableCellRenderer, + ColumnKeyStates { - public KeyCellRenderer() { - } + @Override + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { - public Component getTableCellRendererComponent(JTable table, - Object value, boolean isSelected, boolean hasFocus, - int row, int column) { - - if (value != null) { - if (value instanceof ColumnData) { - ColumnData columnData = (ColumnData) value; - if (columnData.isMarkedDeleted()) { - setIcon(deleteImage); - setToolTipText("This column marked to be dropped"); - } else if (columnData.isNewColumn()) { - setIcon(newImage); - setToolTipText("This column marked new"); - } else if (columnData.isPrimaryKey()) { - - if (columnData.isForeignKey()) { - setIcon(pkfkImage); - setToolTipText("Primary Key/Foreign Key"); - } else { - setIcon(pkImage); - setToolTipText("Primary Key"); - } - - } else if (columnData.isForeignKey()) { - setIcon(fkImage); - setToolTipText("Foreign Key"); - } else { - setIcon(null); - } - } else if (value instanceof String) { - String svalue = (String) value; - if (svalue.trim().equals("PRIMARY KEY")) { - setIcon(pkImage); - setToolTipText("Primary Key"); - } else if (svalue.trim().equals("FOREIGN KEY")) { - setIcon(fkImage); - setToolTipText("Foreign Key"); - } else { - setIcon(null); - } - } - }else setIcon(null); + Icon icon = null; + String tooltip = null; - setHorizontalAlignment(JLabel.CENTER); - - /* - if (keyValue.equals(PRIMARY_AND_FOREIGN)) { - setIcon(pkfkImage); - } - else if (keyValue.equals(FOREIGN)) { - setIcon(fkImage); - } - else if (keyValue.equals(PRIMARY)) { - setIcon(pkImage); - } - else { - setIcon(null); - } - */ - return this; - } + if (value instanceof ColumnData) { + ColumnData formattedValue = (ColumnData) value; -} + if (formattedValue.isMarkedDeleted()) { + tooltip = deleteTooltip; + icon = deleteImage; + + } else if (formattedValue.isNewColumn()) { + tooltip = newTooltip; + icon = newImage; + } else if (formattedValue.isPrimaryKey()) { + if (formattedValue.isForeignKey()) { + tooltip = primaryForeignTooltip; + icon = primaryForeignImage; + + } else { + tooltip = primaryTooltip; + icon = primaryImage; + } + + } else if (formattedValue.isForeignKey()) { + tooltip = foreignTooltip; + icon = foreignImage; + } + } else if (value instanceof String) { + String formattedValue = (String) value; + if (formattedValue.trim().equals("PRIMARY KEY")) { + tooltip = primaryTooltip; + icon = primaryImage; + } else if (formattedValue.trim().equals("FOREIGN KEY")) { + tooltip = foreignTooltip; + icon = foreignImage; + } + } + setIcon(icon); + setToolTipText(tooltip); + setHorizontalAlignment(JLabel.CENTER); + return this; + } + public static String bundleString(String key, Object... args) { + return Bundles.get(KeyCellRenderer.class, key, args); + } +} diff --git a/src/org/executequery/gui/text/SimpleCommentPanel.java b/src/org/executequery/gui/text/SimpleCommentPanel.java index c9df3d575..5630f36fb 100644 --- a/src/org/executequery/gui/text/SimpleCommentPanel.java +++ b/src/org/executequery/gui/text/SimpleCommentPanel.java @@ -67,7 +67,7 @@ private void init() { updateCommentButton.setEnabled(currentDatabaseObject != null); rollbackCommentButton = WidgetFactory.createRolloverButton( - "updateCommentButton", + "rollbackCommentButton", Bundles.get("common.rollback.button"), "icon_rollback", e -> resetComment() diff --git a/src/org/executequery/gui/text/SimpleSqlTextPanel.java b/src/org/executequery/gui/text/SimpleSqlTextPanel.java index c4e83463b..b2ea602d8 100644 --- a/src/org/executequery/gui/text/SimpleSqlTextPanel.java +++ b/src/org/executequery/gui/text/SimpleSqlTextPanel.java @@ -206,4 +206,12 @@ public boolean contentCanBeSaved() { return true; } + @Override + public void setFont(Font font) { + super.setFont(font); + + if (textComponent != null) + textComponent.setFont(font); + } + } diff --git a/src/org/executequery/icons/base/icon_warning_animated.gif b/src/org/executequery/icons/base/icon_warning_animated.gif new file mode 100644 index 000000000..c783d32ea Binary files /dev/null and b/src/org/executequery/icons/base/icon_warning_animated.gif differ diff --git a/src/org/executequery/jdbcdrivers-default.xml b/src/org/executequery/jdbcdrivers-default.xml index bc2729554..9ee1a5261 100644 --- a/src/org/executequery/jdbcdrivers-default.xml +++ b/src/org/executequery/jdbcdrivers-default.xml @@ -9,34 +9,35 @@ --> + + + 5555555 + Jaybird 5 Driver + Jaybird 5 Driver + 1 + ./lib/jaybird-5.jar;../lib/jaybird-5.jar;./lib/jaybird-cryptoapi-5.jar;../lib/jaybird-cryptoapi-5.jar;./lib/fbclient-5.jar;../lib/fbclient-5.jar + org.firebirdsql.jdbc.FBDriver + jdbc:firebirdsql://[host]:[port]/[source] + + 2222222 Jaybird 4 Driver Jaybird 4 Driver - 16 - ./lib/jaybird-4.jar;./lib/jaybird-cryptoapi-4.jar;./lib/fbclient-4.jar;../lib/jaybird-4.jar;../lib/jaybird-cryptoapi-4.jar;../lib/fbclient-4.jar - + 1 + ./lib/jaybird-4.jar;./lib/jaybird-cryptoapi-4.jar;./lib/fbclient-4.jar;../lib/jaybird-4.jar;../lib/jaybird-cryptoapi-4.jar;../lib/fbclient-4.jar org.firebirdsql.jdbc.FBDriver jdbc:firebirdsql://[host]:[port]/[source] + 1111111 Jaybird 3 Driver Jaybird 3 Driver - 16 - ./lib/jaybird-3.jar;../lib/jaybird-3.jar;./lib/jaybird-cryptoapi-3.jar;../lib/jaybird-cryptoapi-3.jar - - org.firebirdsql.jdbc.FBDriver - jdbc:firebirdsql://[host]:[port]/[source] - - - 5555555 - Jaybird 5 Driver - Jaybird 5 Driver - 16 - ./lib/jaybird-5.jar;../lib/jaybird-5.jar;./lib/jaybird-cryptoapi-5.jar;../lib/jaybird-cryptoapi-5.jar - + 1 + ./lib/jaybird-3.jar;../lib/jaybird-3.jar;./lib/jaybird-cryptoapi-3.jar;../lib/jaybird-cryptoapi-3.jar org.firebirdsql.jdbc.FBDriver jdbc:firebirdsql://[host]:[port]/[source] + diff --git a/src/org/executequery/listeners/OpenEditorConnectionListener.java b/src/org/executequery/listeners/OpenEditorConnectionListener.java index 60f4db9da..2f3eb5dd2 100644 --- a/src/org/executequery/listeners/OpenEditorConnectionListener.java +++ b/src/org/executequery/listeners/OpenEditorConnectionListener.java @@ -28,12 +28,8 @@ import org.executequery.gui.ComponentPanel; import org.executequery.gui.editor.QueryEditor; import org.executequery.gui.editor.QueryEditorHistory; -import org.executequery.log.Log; -import org.underworldlabs.util.FileUtils; import org.underworldlabs.util.SystemProperties; -import java.io.File; -import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Vector; @@ -62,19 +58,6 @@ public void connected(ConnectionEvent connectionEvent) { null, true ); - - File file = new File(queryEditor.getAbsolutePath()); - if (file.exists()) { - try { - queryEditor.setEditorText(FileUtils.loadFile( - file, - SystemProperties.getProperty("user", "system.file.encoding") - )); - - } catch (IOException e) { - Log.error(e.getMessage(), e); - } - } } queryEditor.setSelectedConnection(connection); diff --git a/src/org/executequery/localization/resources.properties b/src/org/executequery/localization/resources.properties index bbacf94a3..70cdcf110 100644 --- a/src/org/executequery/localization/resources.properties +++ b/src/org/executequery/localization/resources.properties @@ -97,6 +97,7 @@ common.save.button=Save common.save-changes.message=Do you wish to save changes to {0}? common.scale=Scale common.search=Search: +common.search.button=Search common.select.button=Select common.select=Select common.send.button=Send @@ -112,6 +113,7 @@ common.triggers=Triggers common.value=Value common.warning=Warning common.yes.button=Yes +common.serverNotResponding.closeConnection.ask=The server is not responding.\nDo you want to close the connection? # ------------------------------------------------------------- # actions # ------------------------------------------------------------- @@ -700,15 +702,6 @@ BrowserExceptionPanel.ExceptionName=Exception Name: BrowserFunctionPanel.Source=Source BrowserFunctionPanel.function-name=Function Name: BrowserFunctionPanel.function=Database Function -BrowserIndexPanel.Active=Is Active -BrowserIndexPanel.Ascending=Ascending -BrowserIndexPanel.DatabaseIndex=Database Index -BrowserIndexPanel.Descending=Descending -BrowserIndexPanel.IncludedFields=Included Fields -BrowserIndexPanel.IndexName=Index Name: -BrowserIndexPanel.Sorting=Sorting: -BrowserIndexPanel.TableName=Table Name: -BrowserIndexPanel.Unique=Is Unique BrowserNodeBasePanel.object-count=Object count: BrowserProcedurePanel.function-name=Function Name: BrowserProcedurePanel.function=Database Function @@ -836,6 +829,40 @@ BrowserTreePopupMenu.TABLE_COLUMN=table column BrowserTreePopupMenu.TRIGGER=table trigger BrowserTreePopupMenu.USER=user BrowserTreePopupMenu.VIEW=view +BrowserTreePopupMenu.CONSTRAINT.multiple=constraints +BrowserTreePopupMenu.DATABASE_TRIGGER.multiple=DB triggers +BrowserTreePopupMenu.DDL_TRIGGER.multiple=DDL triggers +BrowserTreePopupMenu.DOMAIN.multiple=domains +BrowserTreePopupMenu.EXCEPTION.multiple=exceptions +BrowserTreePopupMenu.EXTERNAL_FUNCTION.multiple=UDFs +BrowserTreePopupMenu.FUNCTION.multiple=functions +BrowserTreePopupMenu.GLOBAL_TEMPORARY.multiple=global temporary tables +BrowserTreePopupMenu.INDEX.multiple=indices +BrowserTreePopupMenu.JOB.multiple=jobs +BrowserTreePopupMenu.PACKAGE.multiple=packages +BrowserTreePopupMenu.PRIMARY_KEY.multiple=primary keys +BrowserTreePopupMenu.FOREIGN_KEY.multiple=foreign keys +BrowserTreePopupMenu.PROCEDURE.multiple=procedures +BrowserTreePopupMenu.ROLE.multiple=roles +BrowserTreePopupMenu.SEQUENCE.multiple=sequences +BrowserTreePopupMenu.SYSTEM_DATE_TIME_FUNCTIONS.multiple=system date time functions +BrowserTreePopupMenu.SYSTEM_DOMAIN.multiple=system domains +BrowserTreePopupMenu.SYSTEM_FUNCTIONS.multiple=system functions +BrowserTreePopupMenu.SYSTEM_INDEX.multiple=system indices +BrowserTreePopupMenu.SYSTEM_NUMERIC_FUNCTIONS.multiple=system numeric functions +BrowserTreePopupMenu.SYSTEM_PACKAGE.multiple=system packages +BrowserTreePopupMenu.SYSTEM_ROLE.multiple=system roles +BrowserTreePopupMenu.SYSTEM_SEQUENCE.multiple=system sequences +BrowserTreePopupMenu.SYSTEM_STRING_FUNCTIONS.multiple=system string functions +BrowserTreePopupMenu.SYSTEM_TABLE.multiple=system tables +BrowserTreePopupMenu.SYSTEM_TRIGGER.multiple=system triggers +BrowserTreePopupMenu.SYSTEM_VIEW.multiple=system views +BrowserTreePopupMenu.TABLE.multiple=tables +BrowserTreePopupMenu.TABLESPACE.multiple=tablespaces +BrowserTreePopupMenu.TABLE_COLUMN.multiple=table columns +BrowserTreePopupMenu.TRIGGER.multiple=table triggers +BrowserTreePopupMenu.USER.multiple=users +BrowserTreePopupMenu.VIEW.multiple=views BrowserTreePopupMenu.active=Enable BrowserTreePopupMenu.copyName=Copy Name BrowserTreePopupMenu.create=Create {0} @@ -911,6 +938,11 @@ ColumnConstraintTableModel.UpdateRule=Update Rule ColumnIndexTableModel.IndexName=Index Name ColumnIndexTableModel.IndexedColumn=Indexed Column ColumnIndexTableModel.Non-Unique=Non-Unique +ColumnKeyStates.newTooltip=This column marked new +ColumnKeyStates.deleteTooltip=This column marked to be dropped +ColumnKeyStates.primaryTooltip=Primary Key +ColumnKeyStates.foreignTooltip=Foreign Key +ColumnKeyStates.primaryForeignTooltip=Primary/Foreign Key ComparerDBPanel.AlterObjects=Objects To Alter ComparerDBPanel.AttributesLabel=Attributes ComparerDBPanel.Canceling=Canceling @@ -1116,34 +1148,32 @@ CreatePackagePanel.Header=Header CreateProcedureFunctionPanel.executeProcedure=Execute Procedure CreateProcedureFunctionPanel.executeFunction=Execute Function CreateProcedureFunctionPanel.Cursors=Cursors +CreateProcedureFunctionPanel.Subprograms=Subprograms CreateProcedureFunctionPanel.DDL=DDL CreateProcedureFunctionPanel.Description=Comment CreateProcedureFunctionPanel.ErrorRetrievingDataTypes=Error retrieving the data types for the selected connection.\nThe system returned:\n CreateProcedureFunctionPanel.FUNCTION=Function +CreateProcedureFunctionPanel.showHelpersCheck=Show helper tools CreateProcedureFunctionPanel.InputParameters=Input Parameters CreateProcedureFunctionPanel.OutputParameters=Output Parameters CreateProcedureFunctionPanel.PROCEDURE=Procedure CreateProcedureFunctionPanel.Variables=Variables CreateProcedureFunctionPanel.confirmTabChange=When you exit this tab, all changes you have made will be lost.\nAre you sure you want to switch tab? -CreateTableFunctionPanel.BrowseButtonText=Browse -CreateTableFunctionPanel.Columns=Columns -CreateTableFunctionPanel.Connection=Connection: -CreateTableFunctionPanel.Constraints=Constraints -CreateTableFunctionPanel.ExternalTableDataFileLabel=Data File: -CreateTableFunctionPanel.FileDoesNotExistMessage=The selected file does not exist -CreateTableFunctionPanel.IsAdapterNeededText=ADAPTER 'CSV' -CreateTableFunctionPanel.IsExternalTableText=EXTERNAL -CreateTableFunctionPanel.OpenFileDialogButton=Select -CreateTableFunctionPanel.OpenFileDialogText=Select Data File -CreateTableFunctionPanel.TableCommentLabel=Comment -CreateTableFunctionPanel.TableName=Table Name: -CreateTableFunctionPanel.Tablespace=Tablespace -CreateTableFunctionPanel.TypeTemporaryTable=Type Temporary Table: -CreateTableFunctionPanel.UseSQLSecurity=Use SQL Security? -CreateTableFunctionPanel.data-types=data types -CreateTableFunctionPanel.error.retrieving=Error retrieving the {0} list for the {1}.\n\nThe system returned:\n{2} -CreateTableFunctionPanel.error.select-type=Select type for all columns -CreateTableFunctionPanel.selected-connection=selected connection +CreateTablePanel.Columns=Columns +CreateTablePanel.Connection=Connection: +CreateTablePanel.Constraints=Constraints +CreateTablePanel.ExternalTableDataFileLabel=Data File: +CreateTablePanel.FileDoesNotExistMessage=The selected file does not exist +CreateTablePanel.IsAdapterNeededText=ADAPTER 'CSV' +CreateTablePanel.IsExternalTableText=EXTERNAL +CreateTablePanel.OpenFileDialogText=Select Data File +CreateTablePanel.TableCommentLabel=Comment +CreateTablePanel.TableName=Table Name: +CreateTablePanel.Tablespace=Tablespace +CreateTablePanel.TypeTemporaryTable=Type Temporary Table +CreateTablePanel.UseSQLSecurity=Use SQL Security? +CreateTablePanel.data-types=data types +CreateTablePanel.error.select-type=Select type for all columns CreateTablePanel.Create=Create CreateTablePanel.column-names=column names CreateTablePanel.error.retrieving=Error retrieving the {0} list for the {1}.\n\nThe system returned:\n{2} @@ -1308,6 +1338,14 @@ EditConstraintPanel.Sorting=Sorting EditConstraintPanel.Table=Table: EditConstraintPanel.Type=Type: EditConstraintPanel.UpdateRule=Update rule +ErdDeleteRelationshipDialog.title=Delete Table Relationship +ErdDeleteRelationshipDialog.Name=Name +ErdDeleteRelationshipDialog.ReferencingTable=Referencing Table +ErdDeleteRelationshipDialog.ReferencingColumn=Referencing Column +ErdDeleteRelationshipDialog.ReferencedTable=Referenced Table +ErdDeleteRelationshipDialog.ReferencedColumn=Referenced Column +ErdDeleteRelationshipDialog.noRelation=No relation exists between the selected tables +ErdDeleteRelationshipDialog.selectConstraints=Select the constraints to be dropped ErdFontStyleDialog.Bold-Italic=Bold/Italic ErdFontStyleDialog.Bold=Bold ErdFontStyleDialog.ColumnNameStyleLabel=Column Name Style: @@ -1328,6 +1366,17 @@ ErdLineStyleDialog.LineStyleLabel=Line Style: ErdLineStyleDialog.LineWeightLabel=Line Weight: ErdLineStyleDialog.BendLineLabel=Line Bend: ErdLineStyleDialog.title=Line Style +ErdNewRelationshipDialog.title=New Table Relationship +ErdNewRelationshipDialog.ConstraintName=Constraint Name: +ErdNewRelationshipDialog.ReferencingTable=Referencing Table: +ErdNewRelationshipDialog.ReferencingColumn=Referencing Column: +ErdNewRelationshipDialog.ReferencedTable=Referenced Table: +ErdNewRelationshipDialog.ReferencedColumn=Referenced Column: +ErdNewRelationshipDialog.isEmptyOrNull={0} is empty or null +ErdNewRelationshipDialog.referencingColumn=Referencing column +ErdNewRelationshipDialog.referencingTable=Referencing table +ErdNewRelationshipDialog.referencedColumn=Referenced column +ErdNewRelationshipDialog.referencedTable=Referenced table ErdNewTableDialog.TableExistsError=This table name already exists ErdNewTableDialog.TableNameEmptyError=Table name can not be empty ErdNewTableDialog.editableTitle=Table: @@ -1364,6 +1413,7 @@ ErdTitlePanelDialog.textBlock=Text Block ErdToolBarPalette.NoSchemaChangesRecordedError=No schema changes have been recorded ErdToolBarPalette.NoTablesError=No tables in ERD ErdToolBarPalette.SelectOnlyTwoTablesError=Please select only 2 related tables +ErdToolBarPalette.noActiveConnections=There are no active connections ErdToolBarPalette.canvasBg=Canvas background colour ErdToolBarPalette.canvasFg=Table background colour for selected or all tables ErdToolBarPalette.createTable=Create new table @@ -1381,6 +1431,26 @@ ErdToolBarPalette.updateFromDatabase=Reverse engineering ErdViewerPanel.errorFileSaving=An error occurred saving to file:\n ErdViewerPanel.setSavedErd=Do you want to save your changes? ErdViewerPanel.title=Entity Relationship Diagram +ErdSaveDialog.title=Save ER-diagram +ErdSaveDialog.background=Background +ErdSaveDialog.background.transparent=Transparent +ErdSaveDialog.background.white=White +ErdSaveDialog.quality=Quality +ErdSaveDialog.quality.low=Low +ErdSaveDialog.quality.medium=Medium +ErdSaveDialog.quality.high=High +ErdSaveDialog.quality.maximum=Maximum +ErdSaveDialog.renderTextAsImageCheck=Render fonts as images +ErdSaveDialog.options.jpeg=JPEG Options +ErdSaveDialog.options.png=GIF/PNG Options +ErdSaveDialog.options.svg=SVG Options +ErdSaveDialog.path=Path +ErdSaveDialog.format=Format +ErdSaveDialog.noFileName=You must enter a file name +ErdSaveDialog.invalidFileExtension=Invalid file extension for selected file type +ErdSaveDialog.files={0} files +ErdSaveDialog.overwriteFile=Overwrite existing file? +ErdSaveDialog.selectFile=Select File ExceptionErrorDialog.HideStackTrace=Hide Stack Trace ExceptionErrorDialog.NextException=Next Exception ExceptionErrorDialog.PreviousException=Previous Exception @@ -1447,7 +1517,8 @@ ExportDataPanel.CanNotWrite=Not enough permissions to write to the directory: ExportDataPanel.ColumnNameHeader=Column Name ExportDataPanel.ColumnTypeHeader=Column Type ExportDataPanel.ColumnsTab=Columns -ExportDataPanel.ErrorWritingToFile=Error writing to file:\n\n +ExportDataPanel.ErrorWritingToFile=Error writing to file.\n{0} +ExportDataPanel.FileNotWritable=File not writable ({0}) ExportDataPanel.FileFormat=File Format: ExportDataPanel.FilePath=File Path: ExportDataPanel.FolderPath=BLOBs Folder: @@ -1503,11 +1574,12 @@ GenerateErdPanel.title=Generate ERD GeneratorTestDataPanel.AfterCommit=Commit after GeneratorTestDataPanel.Autoincrement=Autoincrement GeneratorTestDataPanel.BatchCount=Batch Size -GeneratorTestDataPanel.ChooseDirectory=Choose Directory -GeneratorTestDataPanel.ChooseFile=Choose File +GeneratorTestDataPanel.ChooseDirectory=Directory +GeneratorTestDataPanel.ChooseFile=File GeneratorTestDataPanel.Column=Column -GeneratorTestDataPanel.CountDigitsAfterComma=Count Digits After Comma -GeneratorTestDataPanel.CountRecords=Count Records +GeneratorTestDataPanel.CountDigitsAfterComma=Digits After Comma +GeneratorTestDataPanel.useFirstNRecordsCheck=Use first N records +GeneratorTestDataPanel.CountRecords=Records GeneratorTestDataPanel.Delimiter=Delimiter GeneratorTestDataPanel.FromFile=From File GeneratorTestDataPanel.FromTextArea=From Text Area @@ -1517,33 +1589,41 @@ GeneratorTestDataPanel.Iteration=Iteration GeneratorTestDataPanel.Max=Max GeneratorTestDataPanel.MaxByte=Max Byte GeneratorTestDataPanel.MaxLength=Max Length +GeneratorTestDataPanel.Charset=Charset GeneratorTestDataPanel.Method=Method GeneratorTestDataPanel.Min=Min GeneratorTestDataPanel.MinByte=Min Byte GeneratorTestDataPanel.MinLength=Max Length GeneratorTestDataPanel.Name=Name -GeneratorTestDataPanel.OOAPINotUsed=The connection does not use the OO API. Use it when connecting -GeneratorTestDataPanel.OutputLog=Output to the errors log +GeneratorTestDataPanel.OutputLog=Enable execution logging GeneratorTestDataPanel.Random=Random GeneratorTestDataPanel.Required=Required GeneratorTestDataPanel.Selected=Selected/Deselected GeneratorTestDataPanel.Source=Source GeneratorTestDataPanel.Start=Start GeneratorTestDataPanel.StartValue=Start value +GeneratorTestDataPanel.Years=Years increment +GeneratorTestDataPanel.Mouths=Mouths increment +GeneratorTestDataPanel.Days=Days increment +GeneratorTestDataPanel.Time=Time increment GeneratorTestDataPanel.Stop=Stop GeneratorTestDataPanel.StopOnError=Stop on error GeneratorTestDataPanel.TITLE=Test Data Generator GeneratorTestDataPanel.Table=Table -GeneratorTestDataPanel.TableView=Table/View +GeneratorTestDataPanel.TableView=Table GeneratorTestDataPanel.Type=Type -GeneratorTestDataPanel.UnsupportedDriver=This driver does not support batch operations. Use Jaybird 4 or newer -GeneratorTestDataPanel.UnsupportedServer=This server does not support batch operations. Batch operations are available in FB 4/RDB 4 or newer GeneratorTestDataPanel.UseNull=Use NULL GeneratorTestDataPanel.UseOnlyThisSymbols=Use Only This Symbols GeneratorTestDataPanel.getFromList=Get from list GeneratorTestDataPanel.getFromOtherTable=Get from other table -GeneratorTestDataPanel.printBatchStateBox=Print states for batch execution GeneratorTestDataPanel.useBatchesBox=Use batches to insert data +GeneratorTestDataPanel.noTables=There are no tables for the selected connection +GeneratorTestDataPanel.noColumnsSelected=You must select at least one column for generate data +GeneratorTestDataPanel.nothingToGenerate=Records count couldn't be less than 1 +GeneratorTestDataPanel.batchesNotSupported=Selected connection doesn't support batch operations +GeneratorTestDataPanel.generationEndMessage=Test data generation ends\nRecords added: {0} from total {1}\nRecords failed: {2} +GeneratorTestDataPanel.Generator=Generator +GeneratorTestDataPanel.Output=Output GotoCommand.goTo=Go To GotoCommand.lineNumber=Line Number: GrantManagerPanel.AllObjects=All Objects @@ -1607,6 +1687,12 @@ HostPanel.DataTypes=Data Types HostPanel.DatabaseConnection=Database Connection HostPanel.DatabaseProperties=Database Properties HostPanel.SQLKeywords=SQL Keywords +ImportConnectionsDBPanel.title=Import Connection +ImportConnectionsDBPanel.nameExist=The name [{0}] is already exists +ImportConnectionsDBPanel.connectionsTreeUnavailable=Couldn't import connections.\nConnections tree panel unavailable +ImportConnectionsDBPanel.noConnections=This connection does not contain any connections properties +ImportConnectionsDBPanel.loadedSuccessfully=All connections loaded successfully +ImportConnectionsDBPanel.loadedWithError={0} connections loaded successfully\nSome connections couldn't be loaded:\n{1} ImportConnectionPanel.ExceptionErrorMessage=Error reading connections from file.\n\nThe system returned:\n{0} ImportConnectionPanel.FinishedImportingConnectionsFromFile=Finished importing connections from file. ImportConnectionPanel.ImportConnections=Import Connections @@ -1622,7 +1708,7 @@ ImportConnectionPanelOne.ImportFile=Import File: ImportConnectionPanelOne.SelectImportFilePath=Select Import File Path ImportConnectionPanelOne.SelectTheFileToImportFoldersAndConnectionsFrom=Select the file to import folders and connections from. ImportConnectionsPanelOne.MessageOne=This allows you to import connections from a file - usually generated from the export on another instance of this application.
  -ImportConnectionsPanelOne.MessageTwo=Note: Any folders with existing names will be merged with those in the file.
Any connections with existing names will be added with the suffix '_1'.
Driver libraries are not part of the import process and will need to be added separately.
  +ImportConnectionsPanelOne.MessageTwo=Note: The contents of folders with the same name will be merged during import.
Driver libraries are not imported and must be added separately.
The name of the connection to be imported will be suffixed with _1 if a connection with this name already exists.
  ImportConnectionsPanelTwo.Importing=Importing ... ImportConnectionsPanelTwo.ImportingSelections=Importing selections... ImportDataPanel.BrowseButtonText=Browse @@ -1937,14 +2023,16 @@ QueryEditor.ShowTPP=Show TPP QueryEditor.TransactionIsolationLevel=Transaction isolation level: QueryEditor.autocommitEnable=Auto-commit is enabled QueryEditor.autocommitDisable=Auto-commit is disabled -QueryEditor.requestTransactionMessage=There is active transaction.You must commit or rollback it before closing form.\nFor commit click "yes", for rollback - "no". +QueryEditor.requestTransactionTitle=There is an active transaction +QueryEditor.requestTransactionMessage=Commit the active transaction before closing? QueryEditor.script=script QueryEditor.title=Query Editor -QueryEditor.FileSavedTo= File saved to {0} +QueryEditor.FileSavedTo=File saved to {0} QueryEditorResultsPanel.DatabaseOutput=Database output QueryEditorResultsPanel.NO_ROWS=No rows selected -QueryEditorResultsPanel.ROWS_RETURNED=rows returned -QueryEditorResultsPanel.ROW_RETURNED=row returned +QueryEditorResultsPanel.ROWS_RETURNED={0} rows returned +QueryEditorResultsPanel.ROW_RETURNED={0} row returned +QueryEditorResultsPanel.LIMIT_ON=Rows count limit enabled for {0} records QueryEditorResultsPanel.ResultSetTitle=Result Set QueryEditorResultsPanel.ResultSetTitleFiltered=- Filtered QueryEditorResultsPanel.SUCCESS=Statement executed successfully @@ -2012,6 +2100,9 @@ ResultSetTablePopupMenu.TransposeRow=Transpose Row ResultSetTablePopupMenu.View=View RootDatabaseObjectNode.error.add=Node must be of type DatabaseHostNode ConnectionTree.error.exportAsDrag=Node selection pending before drag +SaveOnExitDialog.title=Saving Changes +SaveOnExitDialog.label=The following open frames have unsaved changes +SaveOnExitDialog.discardButton=Don't save ScrollingTabPane.menuItem.close=Close ScrollingTabPane.menuItem.closeAll=Close All ScrollingTabPane.menuItem.closeOther=Close Others @@ -2046,6 +2137,17 @@ SimpleDataItemViewerPanel.Text=Text SimpleTextComponentPopUpMenu.Copy=Copy SimpleTextComponentPopUpMenu.Cut=Cut SimpleTextComponentPopUpMenu.Paste=Paste +SQLHistoryDialog.title=SQL Command History +SQLHistoryDialog.selectButton.toolTip=Pastes the selected queries into the Query Editor +SQLHistoryDialog.copyButton.toolTip=Copies the selected queries to the system clipboard +SQLHistoryDialog.insertButton=Insert at Cursor +SQLHistoryDialog.insertButton.toolTip=Inserts the selected queries at the cursor position within the Query Editor +SQLHistoryDialog.clearButton.toolTip=Clears and resets ALL SQL history +SQLHistoryDialog.searchButton.toolTip=Search for query in the SQL history +SQLHistoryDialog.openNewEditorCheck=Open in new Query Editor +SQLHistoryDialog.openNewEditorCheck.toolTip=Select to paste the query in a new Query Editor panel +SQLHistoryDialog.stringNotFound=Search string not found +SQLHistoryDialog.noSelection=No selection made SystemLogsViewer.LogFileNotFound=Selected log file not found SystemLogsViewer.outOfMemory=Out of Memory.\nThe file is too large to open for viewing. SystemLogsViewer.reload=Reload this log file @@ -2106,6 +2208,65 @@ TableDefinitionPanel.Subtype=Subtype TableDefinitionPanel.Table=Table TableDefinitionPanel.Tablespace=Tablespace TableDefinitionPanel.TypeOf=Type of +TableModelObject.tablespace_name=Tablespace +TableModelObject.primary_pointer_page=First page of indirect pointers to pages storing table data +TableModelObject.index_root_page=First page of pointers to table indexes +TableModelObject.pointer_pages=Number of pages of indirect pointers to pages storing table data +TableModelObject.data_pages=Number of pages that store table data +TableModelObject.data_page_slots=Number of pointers to database pages contained in pointer pages +TableModelObject.primary_pages=Number of pages on which primary versions of records are stored +TableModelObject.secondary_pages=Number of pages that do not store primary versions of records +TableModelObject.swept_pages=Number of pages that have only primary versions of records. +TableModelObject.empty_pages=Number of pages that have no entries +TableModelObject.full_pages=Number of fully filled pages +TableModelObject.big_record_pages=Number of pages that are completely filled with only one record. +TableModelObject.blob_pages=Number of pages with blobs +TableModelObject.avg_record_length=Average compressed record size in bytes +TableModelObject.total_records=Total number of rows in the table +TableModelObject.avg_version_length=Average length of old versions in bytes +TableModelObject.total_versions=Total number of old versions in the table +TableModelObject.max_versions=Maximum chain of old versions for the record +TableModelObject.avg_fill=Memory usage allocation for all pages allocated in the table +TableModelObject.total_formats=Total number of formats in table RDB$FORMATS +TableModelObject.used_formats=Number of used formats +TableModelObject.avg_fragment_length=Average fragment size in bytes +TableModelObject.total_fragments=Number of all fragments in all records +TableModelObject.max_fragments=Maximum number of fragments in one record +TableModelObject.avg_unpacked_length=Average record size in bytes +TableModelObject.compression_ratio=Ratio of uncompressed to compressed data +TableModelObject.blobs=Number of all blobs +TableModelObject.blobs_total_length=Size occupied by blobs, in bytes +TableModelObject.level_0=Number of blobs of level 0 +TableModelObject.level_1=Number of blobs of level 1 +TableModelObject.level_2=Number of blocks of level 2 +TableModelObject.table_size=Size without blobs in bytes +TableModelObject.size_with_blobs=Size including blobs in bytes +TableModelObject.size_with_blob_pages=Size including blobs per page in bytes +TableModelObject.size_with_indices=Size including blobs and indexes in bytes +TableModelObject.real_selectivity=Real index selectivity +TableModelObject.avg_data_length=Average length of each key in bytes +TableModelObject.total_dup=Total number of duplicate index rows +TableModelObject.max_dup=Number of duplicate nodes in the “chain” with the highest number of duplicates +TableModelObject.root_page=Root page number of the index +TableModelObject.depth=Number of levels in the index tree page. +TableModelObject.leaf_buckets=Number of pages of the lowest level (leaf) in the index tree +TableModelObject.nodes=Total number of records indexed in the tree +TableModelObject.avg_node_length=Average node size in bytes +TableModelObject.avg_key_length=Average key size in bytes including compression +TableModelObject.compression_ratio.index=Average key and prefix length in bytes +TableModelObject.avg_prefix_length=Average size occupied by node prefixes in bytes +TableModelObject.clustering_factor=Degree of rows ordering in the table by index values +TableModelObject.ratio=Ratio of the degree of row ordering to the total number of nodes in the index. +TableModelObject.leaf_full_size=Size of the lowest level pages (leaf pages) in the index tree +TableModelObject.estimated_full_size=Estimated size of all pages in the index tree +TableModelObject.full_path=Absolute path to the tablespace file +TableModelObject.table_count=Number of tables in the tablespace +TableModelObject.index_count=Number of indexes in the tablespace +TableModelObject.range_20=Number of pages whose average occupancy corresponds to the range [0-19] percent +TableModelObject.range_40=Number of pages whose average occupancy corresponds to the range [20-39] percent +TableModelObject.range_60=Number of pages whose average fill rate matches the range [40-59] percent +TableModelObject.range_80=Number of pages whose average fill rate matches the range [60-79] percent +TableModelObject.range_100=Number of pages whose average fill rate matches the [80-99] percent range. TableSelectionCombosGroup.error.selection-object=Error during database object selection TableTriggersTableModel.Active=Active TableTriggersTableModel.Description=Comment @@ -2213,4 +2374,15 @@ WizardProcessPanel.Back=Back WizardProcessPanel.Cancel=Cancel WizardProcessPanel.Help=Help WizardProcessPanel.Next=Next -WizardProcessPanel.Steps=Steps \ No newline at end of file +WizardProcessPanel.Steps=Steps +ConsolePanel.title=System Console +SessionManagerPanel.Flags=Flags +SessionManagerPanel.Stop=Stop session +SessionManagerPanel.Refresh=Refresh list +SessionManagerPanel.Sessions=Sessions +SessionManagerPanel.SessionId=Session ID +SessionManagerPanel.Name=Name +SessionManagerPanel.User=User +SessionManagerPanel.Date=Date +SessionManagerPanel.SessionsEquals=This session may be current one. Do you want to continue? +SessionManagerPanel.ErrorStopping=Error occurred while stopping session\nSystem returned: {0} \ No newline at end of file diff --git a/src/org/executequery/localization/resources_ru.properties b/src/org/executequery/localization/resources_ru.properties index ed0d098f9..bc117ce7c 100644 --- a/src/org/executequery/localization/resources_ru.properties +++ b/src/org/executequery/localization/resources_ru.properties @@ -97,6 +97,7 @@ common.save.button=Сохранить common.save-changes.message=Сохранить изменения {0}? common.scale=Масштаб common.search=Поиск: +common.search.button=Поиск common.select.button=Выбрать common.select=Выбрать common.send.button=Отправить @@ -112,6 +113,7 @@ common.triggers=Триггеры common.value=Значение common.warning=Предупреждение common.yes.button=Да +common.serverNotResponding.closeConnection.ask=Сервер не отвечает.\nОтключиться от БД? # ------------------------------------------------------------- # actions # ------------------------------------------------------------- @@ -700,15 +702,6 @@ BrowserExceptionPanel.ExceptionName=Имя исключения: BrowserFunctionPanel.Source=Исходный код BrowserFunctionPanel.function-name=Имя функции: BrowserFunctionPanel.function=Функция -BrowserIndexPanel.Active=Активный -BrowserIndexPanel.Ascending=По возрастанию -BrowserIndexPanel.DatabaseIndex=Индекс -BrowserIndexPanel.Descending=По убыванию -BrowserIndexPanel.IncludedFields=Поля Индекса -BrowserIndexPanel.IndexName=Имя Индекса: -BrowserIndexPanel.Sorting=Сортировка -BrowserIndexPanel.TableName=Имя таблицы: -BrowserIndexPanel.Unique=Уникальный BrowserNodeBasePanel.object-count=Количество объектов: BrowserProcedurePanel.function-name=Имя функции: BrowserProcedurePanel.function=Функция базы данных @@ -808,7 +801,7 @@ BrowserTreePopupMenu.DOMAIN=домен BrowserTreePopupMenu.EXCEPTION=исключение BrowserTreePopupMenu.EXTERNAL_FUNCTION=внешнюю функцию BrowserTreePopupMenu.FUNCTION=функцию -BrowserTreePopupMenu.GLOBAL_TEMPORARY=глобальную временную таблицу +BrowserTreePopupMenu.GLOBAL_TEMPORARY=временную таблицу BrowserTreePopupMenu.INDEX=индекс BrowserTreePopupMenu.JOB=задачу BrowserTreePopupMenu.PACKAGE=пакет @@ -836,6 +829,40 @@ BrowserTreePopupMenu.TABLE_COLUMN=столбец BrowserTreePopupMenu.TRIGGER=табличный триггер BrowserTreePopupMenu.USER=пользователя BrowserTreePopupMenu.VIEW=представление +BrowserTreePopupMenu.CONSTRAINT.multiple=ограничения +BrowserTreePopupMenu.DATABASE_TRIGGER.multiple=триггеры БД +BrowserTreePopupMenu.DDL_TRIGGER.multiple=DDL триггеры +BrowserTreePopupMenu.DOMAIN.multiple=домены +BrowserTreePopupMenu.EXCEPTION.multiple=исключения +BrowserTreePopupMenu.EXTERNAL_FUNCTION.multiple=внешние функции +BrowserTreePopupMenu.FUNCTION.multiple=функции +BrowserTreePopupMenu.GLOBAL_TEMPORARY.multiple=временные таблицы +BrowserTreePopupMenu.INDEX.multiple=индексы +BrowserTreePopupMenu.JOB.multiple=задачи +BrowserTreePopupMenu.PACKAGE.multiple=пакеты +BrowserTreePopupMenu.PRIMARY_KEY.multiple=первичные ключи +BrowserTreePopupMenu.FOREIGN_KEY.multiple=внешние ключи +BrowserTreePopupMenu.PROCEDURE.multiple=процедуры +BrowserTreePopupMenu.ROLE.multiple=роли +BrowserTreePopupMenu.SEQUENCE.multiple=генераторы +BrowserTreePopupMenu.SYSTEM_DATE_TIME_FUNCTIONS.multiple=системные временные функции +BrowserTreePopupMenu.SYSTEM_DOMAIN.multiple=системные домены +BrowserTreePopupMenu.SYSTEM_FUNCTIONS.multiple=системные функции +BrowserTreePopupMenu.SYSTEM_INDEX.multiple=системные индексы +BrowserTreePopupMenu.SYSTEM_NUMERIC_FUNCTIONS.multiple=системные числовые функции +BrowserTreePopupMenu.SYSTEM_PACKAGE.multiple=системные пакеты +BrowserTreePopupMenu.SYSTEM_ROLE.multiple=системные роли +BrowserTreePopupMenu.SYSTEM_SEQUENCE.multiple=системные генераторы +BrowserTreePopupMenu.SYSTEM_STRING_FUNCTIONS.multiple=системные строковые функции +BrowserTreePopupMenu.SYSTEM_TABLE.multiple=системные таблицы +BrowserTreePopupMenu.SYSTEM_TRIGGER.multiple=системные триггеры +BrowserTreePopupMenu.SYSTEM_VIEW.multiple=системные представления +BrowserTreePopupMenu.TABLE.multiple=таблицы +BrowserTreePopupMenu.TABLESPACE.multiple=табличные пространства +BrowserTreePopupMenu.TABLE_COLUMN.multiple=столбцы +BrowserTreePopupMenu.TRIGGER.multiple=табличные триггеры +BrowserTreePopupMenu.USER.multiple=пользователей +BrowserTreePopupMenu.VIEW.multiple=представления BrowserTreePopupMenu.active=Включить BrowserTreePopupMenu.copyName=Копировать название BrowserTreePopupMenu.create=Создать {0} @@ -891,7 +918,7 @@ CheckForUpdateNotifier.RedExpertUpToDate=Вы используете актуа CheckForUpdateNotifier.downloadVersionMessage=Новая версия {0} доступна для скачивания с {1}.\n\nСкачать новую версию? CheckForUpdateNotifier.latestVersionInfoTitle=Информация о последней версии CheckForUpdateNotifier.newVersionAvailableText=Доступна новая версия {0}. -CheckForUpdateNotifier.newVersionMessage=Новая версия {0} доступна для скачивания c {1}.\nКликните Здесь чтобы перейти на страницу загрузки.\n\nВы хотите просмотреть примечания к версии для этого выпуска? +CheckForUpdateNotifier.newVersionMessage=Новая версия {0} доступна для скачивания c {1}.\nПерейдите на страницу загрузки.\n\nВы хотите просмотреть примечания к версии для этого выпуска? CheckForUpdateNotifier.noInternetMessage=Отсутствует подключение к интернету. Обновитесь позже. CheckForUpdateNotifier.progressDialogForReleaseNotesLabel=Получение примечаний к выпуску новой версии CheckForUpdateNotifier.restart.message.postpone=Приложение будет обновлено после его закрытия. @@ -911,6 +938,11 @@ ColumnConstraintTableModel.UpdateRule=Правило обновления ColumnIndexTableModel.IndexName=Имя индекса ColumnIndexTableModel.IndexedColumn=Индексируемый столбец ColumnIndexTableModel.Non-Unique=Неуникальность +ColumnKeyStates.newTooltip=Этот столбец помечен как новый +ColumnKeyStates.deleteTooltip=Этот столбец помечен как подлежащий удалению +ColumnKeyStates.primaryTooltip=Первичный ключ +ColumnKeyStates.foreignTooltip=Внешний ключ +ColumnKeyStates.primaryForeignTooltip=Первичный/Внешний ключ ComparerDBPanel.AlterObjects=Элементы для изменения ComparerDBPanel.AttributesLabel=Аттрибуты ComparerDBPanel.Canceling=Остановка процесса сравнения @@ -1116,34 +1148,32 @@ CreatePackagePanel.Header=Заголовок CreateProcedureFunctionPanel.executeProcedure=Выполнить процедуру CreateProcedureFunctionPanel.executeFunction=Выполнить функцию CreateProcedureFunctionPanel.Cursors=Курсоры +CreateProcedureFunctionPanel.Subprograms=Подпрограммы CreateProcedureFunctionPanel.DDL=DDL CreateProcedureFunctionPanel.Description=Комментарий CreateProcedureFunctionPanel.ErrorRetrievingDataTypes=Ошибка при получении типов данных для выбранного соединения.\nСистема вернула:\n CreateProcedureFunctionPanel.FUNCTION=функции +CreateProcedureFunctionPanel.showHelpersCheck=Показать вспомогательные инструменты CreateProcedureFunctionPanel.InputParameters=Входные параметры CreateProcedureFunctionPanel.OutputParameters=Выходные параметры CreateProcedureFunctionPanel.PROCEDURE=процедуры CreateProcedureFunctionPanel.Variables=Переменные CreateProcedureFunctionPanel.confirmTabChange=При выходе с этой вкладки все внесенные изменения будут потеряны.\nВы действительно хотите перейти на другую вкладку? -CreateTableFunctionPanel.BrowseButtonText=Открыть Файл -CreateTableFunctionPanel.Columns=Столбцы -CreateTableFunctionPanel.Connection=Подключение: -CreateTableFunctionPanel.Constraints=Ограничения -CreateTableFunctionPanel.ExternalTableDataFileLabel=Файл данных: -CreateTableFunctionPanel.FileDoesNotExistMessage=Выбранный файл не существует -CreateTableFunctionPanel.IsAdapterNeededText=ADAPTER 'CSV' -CreateTableFunctionPanel.IsExternalTableText=Внешняя -CreateTableFunctionPanel.OpenFileDialogButton=Выбрать -CreateTableFunctionPanel.OpenFileDialogText=Выберите Файл Данных -CreateTableFunctionPanel.TableCommentLabel=Комментарий -CreateTableFunctionPanel.TableName=Имя таблицы: -CreateTableFunctionPanel.Tablespace=Табличное пространство -CreateTableFunctionPanel.TypeTemporaryTable=Тип временной таблицы: -CreateTableFunctionPanel.UseSQLSecurity=Использовать SQL Security? -CreateTableFunctionPanel.data-types=типов данных -CreateTableFunctionPanel.error.retrieving=Ошибка построения списка {0} для {1}.\n\nСистема вернула:\n{2} -CreateTableFunctionPanel.error.select-type=Выберите тип данных для всех столбцов -CreateTableFunctionPanel.selected-connection=выбранного подключения +CreateTablePanel.Columns=Столбцы +CreateTablePanel.Connection=Подключение: +CreateTablePanel.Constraints=Ограничения +CreateTablePanel.ExternalTableDataFileLabel=Файл данных: +CreateTablePanel.FileDoesNotExistMessage=Выбранный файл не существует +CreateTablePanel.IsAdapterNeededText=ADAPTER 'CSV' +CreateTablePanel.IsExternalTableText=Внешняя +CreateTablePanel.OpenFileDialogText=Выберите Файл Данных +CreateTablePanel.TableCommentLabel=Комментарий +CreateTablePanel.TableName=Имя таблицы: +CreateTablePanel.Tablespace=Табличное пространство +CreateTablePanel.TypeTemporaryTable=Тип временной таблицы +CreateTablePanel.UseSQLSecurity=Использовать SQL Security? +CreateTablePanel.data-types=типов данных +CreateTablePanel.error.select-type=Выберите тип данных для всех столбцов CreateTablePanel.Create=Создать CreateTablePanel.column-names=столбцов CreateTablePanel.error.retrieving=Ошибка построения списка {0} для {1}.\n\nСистема вернула:\n{2} @@ -1308,6 +1338,14 @@ EditConstraintPanel.Sorting=Сортировка EditConstraintPanel.Table=Таблица: EditConstraintPanel.Type=Тип: EditConstraintPanel.UpdateRule=Правило обновления +ErdDeleteRelationshipDialog.title=Удаление ограничений +ErdDeleteRelationshipDialog.Name=Имя +ErdDeleteRelationshipDialog.ReferencingTable=Таблица +ErdDeleteRelationshipDialog.ReferencingColumn=Столбец +ErdDeleteRelationshipDialog.ReferencedTable=Связанная таблица +ErdDeleteRelationshipDialog.ReferencedColumn=Связанный столбец +ErdDeleteRelationshipDialog.noRelation=Между выбранными таблицами нет связи +ErdDeleteRelationshipDialog.selectConstraints=Выберите ограничения, которые нужно удалить ErdFontStyleDialog.Bold-Italic=Жирный/Курсив ErdFontStyleDialog.Bold=Жирный ErdFontStyleDialog.ColumnNameStyleLabel=Стиль имени столбца: @@ -1328,6 +1366,17 @@ ErdLineStyleDialog.LineStyleLabel=Стиль линий: ErdLineStyleDialog.LineWeightLabel=Ширина линий: ErdLineStyleDialog.BendLineLabel=Изгиб линий: ErdLineStyleDialog.title=Стиль линий +ErdNewRelationshipDialog.title=Добавление ограничения +ErdNewRelationshipDialog.ConstraintName=Имя ограничения: +ErdNewRelationshipDialog.ReferencingTable=Таблица: +ErdNewRelationshipDialog.ReferencingColumn=Столбец: +ErdNewRelationshipDialog.ReferencedTable=Связанная таблица: +ErdNewRelationshipDialog.ReferencedColumn=Связанный столбец: +ErdNewRelationshipDialog.isEmptyOrNull={0} не заполнено +ErdNewRelationshipDialog.referencingColumn=Имя столбца +ErdNewRelationshipDialog.referencingTable=Имя таблицы +ErdNewRelationshipDialog.referencedColumn=Имя связанного столбца +ErdNewRelationshipDialog.referencedTable=Имя связанной таблицы ErdNewTableDialog.TableExistsError=Эта таблица уже существует ErdNewTableDialog.TableNameEmptyError=Имя таблицы не может быть пустым ErdNewTableDialog.editableTitle=Таблица: @@ -1364,6 +1413,7 @@ ErdTitlePanelDialog.textBlock=Текстовый блок ErdToolBarPalette.NoSchemaChangesRecordedError=Никаких изменений схемы не зафиксировано. ErdToolBarPalette.NoTablesError=Нет таблиц в ER-диаграмме ErdToolBarPalette.SelectOnlyTwoTablesError=Пожалуйста, выберите только 2 таблицы +ErdToolBarPalette.noActiveConnections=Нет ни одного активного соединения ErdToolBarPalette.canvasBg=Цвет фона холста ErdToolBarPalette.canvasFg=Цвет фона объекта ErdToolBarPalette.createTable=Создать новую таблицу @@ -1381,6 +1431,26 @@ ErdToolBarPalette.updateFromDatabase=Реверс-инжиниринг ErdViewerPanel.errorFileSaving=Произошла ошибка при сохранении файла:\n ErdViewerPanel.setSavedErd=Хотите сохранить изменения? ErdViewerPanel.title=ER-диаграмма +ErdSaveDialog.title=Сохранить ER-диаграмму +ErdSaveDialog.background=Фон +ErdSaveDialog.background.transparent=Прозрачный +ErdSaveDialog.background.white=Белый +ErdSaveDialog.quality=Качество +ErdSaveDialog.quality.low=Низкое +ErdSaveDialog.quality.medium=Среднее +ErdSaveDialog.quality.high=Высокое +ErdSaveDialog.quality.maximum=Максимальное +ErdSaveDialog.renderTextAsImageCheck=Рендеринг шрифтов как изображений +ErdSaveDialog.options.jpeg=Опции JPEG +ErdSaveDialog.options.png=Опции GIF/PNG +ErdSaveDialog.options.svg=Опции SVG +ErdSaveDialog.path=Файл +ErdSaveDialog.format=Формат +ErdSaveDialog.noFileName=Вы должны ввести имя файла +ErdSaveDialog.invalidFileExtension=Неправильное расширение файла +ErdSaveDialog.files={0} файлы +ErdSaveDialog.overwriteFile=Перезаписать существующий файл? +ErdSaveDialog.selectFile=Выбрать файл ExceptionErrorDialog.HideStackTrace=Скрыть трассировку стека ExceptionErrorDialog.NextException=Следующее исключение ExceptionErrorDialog.PreviousException=Предыдущее исключение @@ -1447,7 +1517,8 @@ ExportDataPanel.CanNotWrite=Недостаточно прав для запис ExportDataPanel.ColumnNameHeader=Имя поля ExportDataPanel.ColumnTypeHeader=Тип поля ExportDataPanel.ColumnsTab=Поля -ExportDataPanel.ErrorWritingToFile=Ошибка записи в файл:\n\n +ExportDataPanel.ErrorWritingToFile=Ошибка записи в файл:\n{0} +ExportDataPanel.FileNotWritable=Файл недоступен для записи ({0}) ExportDataPanel.FileFormat=Формат файла: ExportDataPanel.FilePath=Путь к файлу: ExportDataPanel.FolderPath=Путь к BLOB файлам: @@ -1503,11 +1574,12 @@ GenerateErdPanel.title=Построить диаграмму БД GeneratorTestDataPanel.AfterCommit=Фиксация после GeneratorTestDataPanel.Autoincrement=Автоинкремент GeneratorTestDataPanel.BatchCount=Кол-во записей в пакете -GeneratorTestDataPanel.ChooseDirectory=Выбрать папку -GeneratorTestDataPanel.ChooseFile=Выбрать файл +GeneratorTestDataPanel.ChooseDirectory=Папка +GeneratorTestDataPanel.ChooseFile=Файл GeneratorTestDataPanel.Column=Столбец -GeneratorTestDataPanel.CountDigitsAfterComma=Число цифр после запятой -GeneratorTestDataPanel.CountRecords=Количество записей +GeneratorTestDataPanel.CountDigitsAfterComma=Цифр после запятой +GeneratorTestDataPanel.useFirstNRecordsCheck=Использовать N первых записей +GeneratorTestDataPanel.CountRecords=Количество GeneratorTestDataPanel.Delimiter=Разделитель GeneratorTestDataPanel.FromFile=Из файла GeneratorTestDataPanel.FromTextArea=Из текстового поля @@ -1517,33 +1589,41 @@ GeneratorTestDataPanel.Iteration=Шаг инкремента GeneratorTestDataPanel.Max=Максимум GeneratorTestDataPanel.MaxByte=Максимальный байт GeneratorTestDataPanel.MaxLength=Максимальная длина +GeneratorTestDataPanel.Charset=Кодировка GeneratorTestDataPanel.Method=Метод GeneratorTestDataPanel.Min=Минимум GeneratorTestDataPanel.MinByte=Минимальный байт GeneratorTestDataPanel.MinLength=Минимальная длина GeneratorTestDataPanel.Name=Имя -GeneratorTestDataPanel.OOAPINotUsed=Соединение не использует OO API. Используйте его при подключении к БД -GeneratorTestDataPanel.OutputLog=Вывод ошибок в лог +GeneratorTestDataPanel.OutputLog=Логирование операций GeneratorTestDataPanel.Random=Случайно GeneratorTestDataPanel.Required=Обязательное GeneratorTestDataPanel.Selected=Выбрать GeneratorTestDataPanel.Source=Источник GeneratorTestDataPanel.Start=Начать генерацию GeneratorTestDataPanel.StartValue=Начальное значение +GeneratorTestDataPanel.Years=Инкремент по годам +GeneratorTestDataPanel.Mouths=Инкремент по месяцам +GeneratorTestDataPanel.Days=Инкремент по дням +GeneratorTestDataPanel.Time=Инкремент по времени GeneratorTestDataPanel.Stop=Остановить GeneratorTestDataPanel.StopOnError=Остановить при ошибке GeneratorTestDataPanel.TITLE=Генератор тестовых данных GeneratorTestDataPanel.Table=Таблица -GeneratorTestDataPanel.TableView=Таблица/Представление +GeneratorTestDataPanel.TableView=Таблица GeneratorTestDataPanel.Type=Тип -GeneratorTestDataPanel.UnsupportedDriver=Используемый драйвер не поддерживает пакетные операции. Используйте Jaybird 4 или более новый -GeneratorTestDataPanel.UnsupportedServer=Используемый сервер не поддерживает пакетные операции. Пакетные операции доступны в FB 4/RDB 4 или новее GeneratorTestDataPanel.UseNull=Использовать NULL GeneratorTestDataPanel.UseOnlyThisSymbols=Использовать только эти символы GeneratorTestDataPanel.getFromList=Получить из списка GeneratorTestDataPanel.getFromOtherTable=Получить из другой таблицы -GeneratorTestDataPanel.printBatchStateBox=Выводить результат выполнения пакетной операции GeneratorTestDataPanel.useBatchesBox=Использовать пакетную загрузку данных +GeneratorTestDataPanel.noTables=В выбранной базе данных нет таблиц +GeneratorTestDataPanel.noColumnsSelected=Вы должны выбрать хотя бы один столбец для генерации данных +GeneratorTestDataPanel.nothingToGenerate=Количество записей не может быть меньше 1 +GeneratorTestDataPanel.batchesNotSupported=Выбранное соединение не поддерживает пакетные операции +GeneratorTestDataPanel.generationEndMessage=Генерация тестовых данных завершена\nЗаписей добавлено: {0} из {1}\nЗаписей проигнорировано: {2} +GeneratorTestDataPanel.Generator=Генератор +GeneratorTestDataPanel.Output=Вывод GotoCommand.goTo=Перейти к GotoCommand.lineNumber=Номер строки: GrantManagerPanel.AllObjects=Все объекты @@ -1607,9 +1687,15 @@ HostPanel.DataTypes=Типы Данных HostPanel.DatabaseConnection=Подключение к базе данных HostPanel.DatabaseProperties=Свойства базы данных HostPanel.SQLKeywords=Ключевые слова SQL +ImportConnectionsDBPanel.title=Импорт подключения +ImportConnectionsDBPanel.nameExist=Имя [{0}] уже занято +ImportConnectionsDBPanel.connectionsTreeUnavailable=Не удалось импортировать подключения.\nНе удалось получить дерево подключений +ImportConnectionsDBPanel.noConnections=Это подключение не содержит данных о доступных соединениях +ImportConnectionsDBPanel.loadedSuccessfully=Все подключения импортированы успешно +ImportConnectionsDBPanel.loadedWithError={0} подключений импортировано успешно\nНекоторые подключения не удалось импортировать:\n{1} ImportConnectionPanel.ExceptionErrorMessage=Ошибка чтения подключений из файла.\n\nСистема вернула:\n{0} ImportConnectionPanel.FinishedImportingConnectionsFromFile=Завершен импорт соединений из файла. -ImportConnectionPanel.ImportConnections=Импорт Соединений +ImportConnectionPanel.ImportConnections=Импорт соединений ImportConnectionPanel.ImportingConnectionsFromFile=Импорт соединений из файла... ImportConnectionPanel.ProcessedFoldersAndConnections=\nОбработано папок - {0} и соединений - {1} ImportConnectionPanel.StepsOne=Выберите файл импорта @@ -1621,8 +1707,8 @@ ImportConnectionPanelOne.ErrorMessageOne=Вы должны указать пол ImportConnectionPanelOne.ImportFile=Импорт файла: ImportConnectionPanelOne.SelectImportFilePath=Выберите файл для импорта ImportConnectionPanelOne.SelectTheFileToImportFoldersAndConnectionsFrom=Выберите файл для импорта папок и подключений. -ImportConnectionsPanelOne.MessageOne=Импорт файлов позволяет вам импортировать соединения из файла, обычно создаваемого в результате экспорта в другом экземпляре этого приложения.
  -ImportConnectionsPanelOne.MessageTwo=Примечание: Все папки с существующими именами будут объединены с папками, содержащимися в файле.
Любые соединения с существующими именами будут добавлены с помощью суффикса '_1'.
Библиотеки драйверов не являются частью процесса импорта и должны быть добавлены отдельно.
  +ImportConnectionsPanelOne.MessageOne=Импорт файлов позволяет вам импортировать соединения из файла, созданного в результате экспорта в другом экземпляре этого приложения.
  +ImportConnectionsPanelOne.MessageTwo=Примечание: Cодержание папок с одинаковыми именами при импорте будет объединено.
Библиотеки драйверов не импортируются и должны быть добавлены отдельно.
К имени импортируемого соединения будет дописан суффикс _1, если подключение с таким именем уже существует.
  ImportConnectionsPanelTwo.Importing=Импорт ... ImportConnectionsPanelTwo.ImportingSelections=Импорт соединений... ImportDataPanel.BrowseButtonText=Выбрать @@ -1937,14 +2023,16 @@ QueryEditor.ShowTPP=Показать параметры транзакции QueryEditor.TransactionIsolationLevel=Уровень изоляции транзакций: QueryEditor.autocommitEnable=Автофиксация включена QueryEditor.autocommitDisable=Автофиксация выключена -QueryEditor.requestTransactionMessage=Перед закрытием формы необходимо подтвердить или откатить активную транзакцию.\nДля подтверждения нажмите "да", для отката - "нет". +QueryEditor.requestTransactionTitle=Есть неподтвежденная транзакция +QueryEditor.requestTransactionMessage=Подтвердить активную транзакцию перед закрытием? QueryEditor.script=скрипт QueryEditor.title=Редактор запросов QueryEditor.FileSavedTo= Файл сохранен в {0} QueryEditorResultsPanel.DatabaseOutput=Вывод БД QueryEditorResultsPanel.NO_ROWS=Не выбрано ни одной строки -QueryEditorResultsPanel.ROWS_RETURNED=строк возвращено -QueryEditorResultsPanel.ROW_RETURNED=строка возвращена +QueryEditorResultsPanel.ROWS_RETURNED= {0} строк возвращено +QueryEditorResultsPanel.ROW_RETURNED= {0} строка возвращена +QueryEditorResultsPanel.LIMIT_ON=Включено ограничение количества строк на {0} записей QueryEditorResultsPanel.ResultSetTitle=Набор Результатов QueryEditorResultsPanel.ResultSetTitleFiltered=- Отфильтровано QueryEditorResultsPanel.SUCCESS=Запрос выполнен успешно @@ -2012,6 +2100,9 @@ ResultSetTablePopupMenu.TransposeRow=Транспонировать строку ResultSetTablePopupMenu.View=Просмотреть содержимое RootDatabaseObjectNode.error.add=Узел должен быть типа DatabaseHostNode ConnectionTree.error.exportAsDrag=Выбор узла до перетаскивания +SaveOnExitDialog.title=Сохранение изменений +SaveOnExitDialog.label=У Вас есть следующие несохраненные изменения +SaveOnExitDialog.discardButton=Не сохранять ScrollingTabPane.menuItem.close=Закрыть ScrollingTabPane.menuItem.closeAll=Закрыть все ScrollingTabPane.menuItem.closeOther=Закрыть другие @@ -2046,6 +2137,17 @@ SimpleDataItemViewerPanel.Text=Текст SimpleTextComponentPopUpMenu.Copy=Копировать SimpleTextComponentPopUpMenu.Cut=Вырезать SimpleTextComponentPopUpMenu.Paste=Вставить +SQLHistoryDialog.title=История SQL запросов +SQLHistoryDialog.selectButton.toolTip=Вставить выбранные запросы в редактор +SQLHistoryDialog.copyButton.toolTip=Скопировать выбранные запросы в буфер обмена +SQLHistoryDialog.insertButton=Вставить +SQLHistoryDialog.insertButton.toolTip=Добавить выбранные запросы в редактор после курсора +SQLHistoryDialog.clearButton.toolTip=Очистить всю историю запросов +SQLHistoryDialog.searchButton.toolTip=Найти запрос в истории +SQLHistoryDialog.openNewEditorCheck=Открыть в новом редакторе запросов +SQLHistoryDialog.openNewEditorCheck.toolTip=Выберите, чтобы открыть запрос в новом редакторе +SQLHistoryDialog.stringNotFound=Ничего не найдено +SQLHistoryDialog.noSelection=Ничего не выбрано SystemLogsViewer.LogFileNotFound=Выбранный файл журнала не найден SystemLogsViewer.outOfMemory=Недостаточно памяти.\nФайл слишком велик, чтобы его можно было открыть для просмотра. SystemLogsViewer.reload=Перезагрузить этот файл журнала @@ -2106,6 +2208,65 @@ TableDefinitionPanel.Subtype=Подтип TableDefinitionPanel.Table=Таблица TableDefinitionPanel.Tablespace=Табличное пространство TableDefinitionPanel.TypeOf=TYPE OF +TableModelObject.tablespace_name=Табличное пространство +TableModelObject.primary_pointer_page=Первая страница косвенных указателей на страницы, хранящие данные таблицы +TableModelObject.index_root_page=Первая страница указателей на индексы таблицы +TableModelObject.pointer_pages=Количество страниц косвенных указателей на страницы, хранящие данные таблицы +TableModelObject.data_pages=Количество страниц, в которых хранятся данные таблицы +TableModelObject.data_page_slots=Количество указателей на страницы базы данных, содержащихся на страницах указателей +TableModelObject.primary_pages=Количество страниц, на которых хранятся первичные версии записей +TableModelObject.secondary_pages=Количество страниц, на которых не хранятся первичные версии записей +TableModelObject.swept_pages=Количество страниц, которые имеют только первичные версии записей +TableModelObject.empty_pages=Количество страниц, на которых нет записей +TableModelObject.full_pages=Количество полностью заполненных страниц +TableModelObject.big_record_pages=Количество страниц, которые полностью заняты только одной записью +TableModelObject.blob_pages=Количество страниц с блобами +TableModelObject.avg_record_length=Средний размер сжатой записи в байтах +TableModelObject.total_records=Общее количество строк в таблице +TableModelObject.avg_version_length=Среднее значение длины старых версий в байтах +TableModelObject.total_versions=Общее количество старых версий в таблице +TableModelObject.max_versions=Максимальная цепочка старых версий для записи +TableModelObject.avg_fill=Распределение использования памяти для всех страниц, выделенных в таблице +TableModelObject.total_formats=Общее количество форматов в таблице RDB$FORMATS +TableModelObject.used_formats=Количество используемых форматов +TableModelObject.avg_fragment_length=Средний размер фрагмента в байтах +TableModelObject.total_fragments=Количество всех фрагментов во всех записях +TableModelObject.max_fragments=Максимальное количество фрагментов в одной записи +TableModelObject.avg_unpacked_length=Средний размер записи в байтах +TableModelObject.compression_ratio=Отношение несжатых данных к сжатым +TableModelObject.blobs=Количество всех блобов +TableModelObject.blobs_total_length=Размер, занимаемый блобами, в байтах +TableModelObject.level_0=Количество блобов уровня 0 +TableModelObject.level_1=Количество блобов уровня 1 +TableModelObject.level_2=Количество блобов уровня 2 +TableModelObject.table_size=Размер без учета блобов в байтах +TableModelObject.size_with_blobs=Размер с учетом блобов в байтах +TableModelObject.size_with_blob_pages=Размер с учетом блобов по страницам в байтах +TableModelObject.size_with_indices=Размер с учетом блобов и индексов в байтах +TableModelObject.real_selectivity=Реальная селективность индекса +TableModelObject.avg_data_length=Средняя длина каждого ключа в байтах +TableModelObject.total_dup=Общее количество строк дубликатов индекса +TableModelObject.max_dup=Количество дублирующих узлов в "цепочке", имеющих наибольшее количество дубликатов +TableModelObject.root_page=Номер корневой страницы индекса +TableModelObject.depth=Количество уровней в странице индексного дерева +TableModelObject.leaf_buckets=Количество страниц самого низкого уровня (листовых) в дереве индекса +TableModelObject.nodes=Общее количество записей, индексированных в дереве +TableModelObject.avg_node_length=Средний размер узлов в байтах +TableModelObject.avg_key_length=Средний размер ключа в байтах с учетом сжатия +TableModelObject.compression_ratio.index=Средняя длина ключа и префикса в байтах +TableModelObject.avg_prefix_length=Средний размер, занимаемый префиксами узлов, в байтах +TableModelObject.clustering_factor=Степень упорядоченности строк в таблице по значениям индекса +TableModelObject.ratio=Отношение степени упорядоченности строк к общему количеству узлов в индексе +TableModelObject.leaf_full_size=Размер страниц самого низкого уровня (листовых) в дереве индекса +TableModelObject.estimated_full_size=Оценка размера всех страниц в дереве индекса +TableModelObject.full_path=Абсолютный путь к файлу табличного пространства +TableModelObject.table_count=Количество таблиц в табличном пространстве +TableModelObject.index_count=Количество индексов в табличном пространстве +TableModelObject.range_20=Количество страниц, чье среднее заполнение соответствует диапазону [0-19] процентов +TableModelObject.range_40=Количество страниц, чье среднее заполнение соответствует диапазону [20-39] процентов +TableModelObject.range_60=Количество страниц, чье среднее заполнение соответствует диапазону [40-59] процентов +TableModelObject.range_80=Количество страниц, чье среднее заполнение соответствует диапазону [60-79] процентов +TableModelObject.range_100=Количество страниц, чье среднее заполнение соответствует диапазону [80-99] процентов TableSelectionCombosGroup.error.selection-object=Ошибка при выборе объекта базы данных TableTriggersTableModel.Active=Активность TableTriggersTableModel.Description=Комментарий @@ -2213,4 +2374,15 @@ WizardProcessPanel.Back=Назад WizardProcessPanel.Cancel=Отменить WizardProcessPanel.Help=Помощь WizardProcessPanel.Next=Дальше -WizardProcessPanel.Steps=Шаги \ No newline at end of file +WizardProcessPanel.Steps=Шаги +ConsolePanel.title=Системная консоль +SessionManagerPanel.Flags=Флаги +SessionManagerPanel.Stop=Остановить сессию +SessionManagerPanel.Refresh=Обновить список +SessionManagerPanel.Sessions=Сессии +SessionManagerPanel.SessionId=ID сессии +SessionManagerPanel.Name=Имя +SessionManagerPanel.User=Пользователь +SessionManagerPanel.Date=Дата +SessionManagerPanel.SessionsEquals=Возможно, вы выбрали текущую сессию. Вы хотите продолжить? +SessionManagerPanel.ErrorStopping=При остановке сеанса произошла ошибка\nСистема вернула: {0} diff --git a/src/org/executequery/release_notes_en.html b/src/org/executequery/release_notes_en.html index 8b29d0397..e08d439aa 100644 --- a/src/org/executequery/release_notes_en.html +++ b/src/org/executequery/release_notes_en.html @@ -1,5 +1,69 @@

RedExpert Changelog

+

Major changes - v2024.09

+

Added:

+
    +
  1. fbclient libraries for RDB 3, 4 and 5 version
  2. +
  3. Notification when records count limit is enabled
  4. +
  5. Check for valid exported file path before export table data
  6. +
  7. Ability to delete data from the monitoring tables (MON$...)
  8. +
  9. Indicators of the connected databases in the select connection fields
  10. +
  11. Comment tabs for "Edit Job" and "Edit Tablespace" panels
  12. +
  13. Ability to hide helper tools in the "Edit Procedure" and "Edit Function" panels
  14. +
  15. Displaying Result Set table row numbers by default
  16. +
  17. Tooltips for the table columns in the DB statistics panel
  18. +
  19. Clearing selected tables if the "Only select tables" check disabled in the DB statistics panel
  20. +
+

Improved:

+
    +
  1. ER-diagram editor toolbar
  2. +
  3. "Test Data Generator" tool
  4. +
  5. "Import connections from DB" tool
  6. +
  7. "Add table" dialog in the ERD Editor
  8. +
  9. "Add relationship" dialog in the ERD Editor
  10. +
  11. "Remove relationship" dialog in the ERD Editor
  12. +
  13. Exception message formatting in the error dialog
  14. +
  15. Update databases list for JDBC drivers
  16. +
  17. Update Jaybird drivers to 4.0.30 and 5.0.18
  18. +
  19. Update Java Native Access and Java Native Access Platform package versions
  20. +
  21. Remove showing "setting applied" message when there are no preferences changed
  22. +
  23. Set Monospaced font for the "Trace Manager" SQL panel
  24. +
  25. Set PRIMARY tablespace as default instead of NONE when creating table
  26. +
+

Fixed:

+
    +
  1. ER-diagram generation
  2. +
  3. Loading ER-diagram from the file
  4. +
  5. Primary key generation for ER-diagram
  6. +
  7. Editing table constraints in the ER-diagram editor
  8. +
  9. Saving visible columns in the "Trace Manager" tool
  10. +
  11. Editing JOB type displaying
  12. +
  13. Result Set table cell rendering
  14. +
  15. Enabling toolbar for table constraints
  16. +
  17. Freezing when displaying the autocomplete popup
  18. +
  19. Connections tree updating
  20. +
  21. Popup actions for the VIEW columns into the connections tree
  22. +
  23. NPE when open "Edit Function" panel
  24. +
  25. Executing SQL scripts with parameters
  26. +
  27. Executing SQL scripts without "SET TERM" statement
  28. +
  29. OO API tools enabling in the "Test Data Generator" panel
  30. +
  31. Default TRIGGER name generation when create new one
  32. +
  33. Generating SQL drop query for UDFs
  34. +
  35. Generating SQL script for PROCEDUREs and FUNCTIONs
  36. +
  37. Generating SQL script for JOBs and TABLESPACEs with comment
  38. +
  39. Generating SQL script for PACKAGEs without body
  40. +
  41. Generating SQL script for TRIGGERs on the Firebird with version less than 3
  42. +
  43. Generating SQL script for existing FUNCTIONs with the deterministic return type
  44. +
  45. Generating SQL script for table constraints during comparing
  46. +
  47. Loading information for TABLEs, INDEXes and FUNCTIONs during DB comparing
  48. +
  49. Loading information for JOBs while editing them
  50. +
  51. Starting DB compare with version less than 3
  52. +
  53. Saving SQL script after DB comparing with the user changes
  54. +
  55. Generating SQL stubs for PROCEDUREs during DB comparing
  56. +
  57. Generating titles for new "System Console" tool instances
  58. +
  59. Saving Query Editor instances history
  60. +
  61. Data view dialog opening for the first time
  62. +

Major changes - v2024.07

Improved:

    @@ -89,7 +153,7 @@

    Major changes - v2024.05

  1. Export UDF from Firebird 3 using UTF-8 encoding
  2. Display related foreign key columns
  3. Deadlock on editing table records
  4. -
  5. Red Expert hangs when opening the “Memory Usage” tool
  6. +
  7. Red Expert hangs when opening the "Memory Usage" tool
  8. Adding variables when generating SQL script for creating procedures
  9. Adding comments to database table fields
  10. Creating a connection folder with an empty name
  11. @@ -206,13 +270,13 @@

    Major changes - v2024.01

  12. Transaction confirmation window when closing the Query Editor and the "Data" tab of tables and views
  13. Displaying connection and database properties (such as server, page size, database file size, etc.)
  14. Ability to copy column names from a Result Set
  15. -
  16. “Triggers” tab for views
  17. +
  18. "Triggers" tab for views
  19. Ability to configure database connection timeout
  20. Updated data import and export panels

Fixed:

    -
  1. Display tables with “NONE” encoding
  2. +
  3. Display tables with "NONE" encoding
  4. Recognizing VARCHAR and CHAR types other than undefined subtype and with fixed binary data
  5. Reloading of views after making changes
  6. Auto-completion: by occurrence, not by string start
  7. @@ -220,7 +284,7 @@

    Major changes - v2024.01

  8. Editing foreign keys
  9. Copying connection with encoding
  10. Editing data in columns with names containing spaces
  11. -
  12. Disappearance of the edited procedure text on the “DDL” tab when switching tabs
  13. +
  14. Disappearance of the edited procedure text on the "DDL" tab when switching tabs
  15. Searching for database objects in the connection tree with names containing '$'
  16. GUI defects when double-clicking on a table name in the Query Editor
  17. Limitations on the number of characters and maximum value when editing field value with INT128 type
  18. @@ -235,7 +299,7 @@

    Major changes - v2024.01

    Major changes - v2023.10.1

    Added:

      -
    1. “Properties” tab on the database table editing panel.
    2. +
    3. "Properties" tab on the database table editing panel.
    4. Configuring SQL templates from the Menu -> Tools.
    5. Checkbox "Automatic text wrapping" in the text browser of data with the BLOB type.
    6. Ability to specify a relative path to the log file in the settings.
    7. @@ -259,8 +323,8 @@

      Major changes - v2023.10.1

      application over the old one.
    8. Action taken when clicking the Select Displayed Dataset Columns button when the Results Pane is closed.
    9. -
    10. Selecting table rows to be deleted after closing the “Data” tab and canceling the deletion.
    11. -
    12. An error when the “Close all tabs” button did not close all tabs.
    13. +
    14. Selecting table rows to be deleted after closing the "Data" tab and canceling the deletion.
    15. +
    16. An error when the "Close all tabs" button did not close all tabs.
    17. Incorrect error handling during update.
    18. Syntax highlighting for multi-line identifiers.
    19. Application crash if user settings are broken.
    20. @@ -282,9 +346,9 @@

      Major changes - v2023.08

    21. Ability to enable line wrapping mode in the Query Editor.
    22. Support of the PSQL-profiler.
    23. Tree view display with a panel of differences for each object as a DB comparer result.
    24. -
    25. New Foreign Key selection panel on the “Data” tab when working with DB tables.
    26. +
    27. New Foreign Key selection panel on the "Data" tab when working with DB tables.
    28. Ability to reset color to default by RMB click in the color settings.
    29. -
    30. Ability to filter columns by their names in the “Result Column Visibility” window for a Result Set.
    31. +
    32. Ability to filter columns by their names in the "Result Column Visibility" window for a Result Set.
    33. Audit analysis.
    34. Auto-complete for packages (procedures and functions are suggested after a dot).
    35. Date display in the application log.
    36. @@ -296,13 +360,13 @@

      Major changes - v2023.08

      Fixed:

      1. Inability to add a comment for a table field when editing it.
      2. -
      3. An error due to which the content of the “SQL” tab during table creation was not updated when changing the - “Comment” tab content. +
      4. An error due to which the content of the "SQL" tab during table creation was not updated when changing the + "Comment" tab content.
      5. -
      6. Option “Show Grid” in the “Links” tab when working with a DB table.
      7. -
      8. Displaying the username in the “Select Result” tab when editing a user is confirmed.
      9. +
      10. Option "Show Grid" in the "Links" tab when working with a DB table.
      11. +
      12. Displaying the username in the "Select Result" tab when editing a user is confirmed.
      13. Generation of the SQL scripts for packages, views, tables and jobs.
      14. -
      15. “Description” tabs renamed to “Comment”.
      16. +
      17. "Description" tabs renamed to "Comment".
      18. Incorrect application of theme and style for the Query Editor.
      19. Wrong SQL script formatting in the Query Editor.
      20. NPE when navigating through folders in the connection tree.
      21. @@ -385,7 +449,7 @@

        Major changes - v2023.01

      22. "Switch data display" button and key combination [ALT + NUM_ADD] in data tab
      23. Exit confirmation dialog
      24. Specifies explicitly how a table field is sorted (COLLATE) when creating a table
      25. -
      26. “DDL to create” tab in "Edit constraint" panel
      27. +
      28. "DDL to create" tab in "Edit constraint" panel
      29. Ability to view password during user creation and authorization at reddatabase.ru
      30. Ability to replace "\n" with another symbol when exporting to file with separators
      31. Ability to work with functions and packages in privilege manager
      32. @@ -403,8 +467,8 @@

        Major changes - v2023.01

      33. Error when generating SQL script for adding table constraints when only one constraint was inserted into script instead of multiple ones
      34. -
      35. Red Expert hangs after a data access error in the “Data” tab of the “Table” menu.
      36. -
      37. Adding comments to database elements like “User” or “Domain” while editing them
      38. +
      39. Red Expert hangs after a data access error in the "Data" tab of the "Table" menu.
      40. +
      41. Adding comments to database elements like "User" or "Domain" while editing them
      42. Generating SQL script when adding a new column to a table
      43. Export to a spreadsheet. Now export to Excel 2007 is possible
      44. Automatic generation of table name on creation
      45. @@ -418,7 +482,7 @@

        Major changes - v2023.01

      46. Updated keyword list for syntax highlighting
      47. Creating a database with default charset
      48. Flickering interface in privilege manager
      49. -
      50. Invalid representation of “DATE” type when exporting to SQL
      51. +
      52. Invalid representation of "DATE" type when exporting to SQL
      53. Undo/redo (Ctrl+Z/Ctrl+Y) in the query editor
      54. Nonoptimal space usage by result set in query editor
      55. Application hangs when opening objects
      56. @@ -446,7 +510,7 @@

        Major changes - v2022.09

      57. Rollback transaction on closing request dialog
      58. Error in generating date and time values in the test data generator
      59. Wrong message about successful creation of external procedures and functions in request editor
      60. -
      61. Incorrect generation of “create generator” query
      62. +
      63. Incorrect generation of "create generator" query
      64. Errors of trace parsing
      65. Autocomplete columns to alias escaped table
      @@ -497,7 +561,7 @@

      Major changes - v2022.02

    37. Error adding a record with IDENTITY field
    38. Autocomplete errors in queries with aliases
    39. Tab-indexing order on connection page
    40. -
    41. Wrong error “TABLE is in use” on attempt to remove table
    42. +
    43. Wrong error "TABLE is in use" on attempt to remove table
    44. Error opening browser in Linux
    45. Index is active by default when created
    46. Modified the update dialogs
    47. @@ -715,7 +779,7 @@

      Major changes - v1.0.4

    48. Changed display of connection windows in the user manager (removed unnecessary windows when there are no connections)
    49. -
    50. On the Membership tab, the option “User → Role” is enabled by default. The remaining options are deactivated. +
    51. On the Membership tab, the option "User → Role" is enabled by default. The remaining options are deactivated.
    52. Before sorting the data in the table, a full fetch is done.
    53. Added the distinction between the display of the total and the loaded (recorded) number of records in the table. @@ -734,13 +798,13 @@

      Major changes - v1.0.4

    54. Fixed table editing mode. When you click "Apply" did not exit the edit mode, as a result, changes in the editable field were not displayed.
    55. -
    56. Fixed procedure call using “execute procedure” in query editor
    57. +
    58. Fixed procedure call using "execute procedure" in query editor
    59. Fixed reconnection (Recycle) to the database (not performed at all)
    60. Fixed closing cursors when closing a table
    61. Fixed deletion of objects (if the object is open, it cannot be deleted)
    62. Fixed the location of menu objects (removed inaccessible and under development)
    63. Fixed display of the "Database Tools" menu (hiding, although it was active)
    64. -
    65. Hidden schemes (in the “Firebird” and “Red Database” they are missing)
    66. +
    67. Hidden schemes (in the "Firebird" and "Red Database" they are missing)
    68. Fixed display of errors in dialog boxes (structured output)
    69. Fixed working with tables if OpenJDK is used as Java (NPE when clicking on a table cell)
    70. Fixed bug where after adding a role it is impossible to create (change and delete) a user
    71. @@ -754,7 +818,7 @@

      Major changes - v1.0.4

      on the connection button
    72. Fixed display of the search window when you press ALT in Windows (when clicked, the window disappeared)
    73. -
    74. Fixed bug with double-clicking on “Favorite” connections
    75. +
    76. Fixed bug with double-clicking on "Favorite" connections
    77. Fixed definition of hot keys in the application settings
    78. Fixed display of columns in the table when fetching data
    79. Optimized loading of the Membership tab in the user manager
    80. diff --git a/src/org/executequery/release_notes_ru.html b/src/org/executequery/release_notes_ru.html index 4f7ecde4f..994fd5966 100644 --- a/src/org/executequery/release_notes_ru.html +++ b/src/org/executequery/release_notes_ru.html @@ -1,5 +1,71 @@

      Лог изменений RedExpert

      +

      Основные изменения - v2024.09

      +

      Добавлено:

      +
        +
      1. Библиотеки fbclient для RedDatabase с версиями 3, 4 и 5
      2. +
      3. Уведомление об ограничении количества возвращаемых записей
      4. +
      5. Проверка корректности пути к файлу перед экспортом данных таблицы
      6. +
      7. Возможность удаления данных из таблиц мониторинга (MON$...)
      8. +
      9. Индикаторы подключенных баз данных в поле выбора соединения
      10. +
      11. Вкладки комментария для панелей "Редактирование задачи" и "Редактирование табличного пространства"
      12. +
      13. Возможность скрыть вспомогательные инструменты на панелях "Редактирование процедуры" и "Редактирование + функции" +
      14. +
      15. Отображение номеров строк по умолчанию в таблице набора результатов
      16. +
      17. Всплывающие подсказки для столбцов таблицы в инструменте "Статистика БД"
      18. +
      19. Очистка выбранных таблиц при выключенной опции "Только выбранные таблицы" в инструменте "Статистика БД"
      20. +
      +

      Улучшено:

      +
        +
      1. Панель инструментов редактора ER-диаграмм
      2. +
      3. Инструмент "Генератор тестовых данных"
      4. +
      5. Инструмент "Импорт соединений из БД"
      6. +
      7. Диалоговое окно "Добавить таблицу" в редакторе ER-диаграмм
      8. +
      9. Диалоговое окно "Добавить связь" в редакторе ER-диаграмм
      10. +
      11. Диалоговое окно "Удалить связь" в редакторе ER-диаграмм
      12. +
      13. Форматирование сообщений об исключениях в диалоговом окне ошибки
      14. +
      15. Обновлен список баз данных для драйверов JDBC
      16. +
      17. Обновлены драйверы Jaybird до версий 4.0.30 и 5.0.18
      18. +
      19. Обновлены версии пакетов Java Native Access и Java Native Access Platform
      20. +
      21. Скрыто отображение сообщения "Настройки применены", если нет изменений
      22. +
      23. Установлен шрифт "Monospaced" для SQL-панели "Трейс Менеджер"
      24. +
      25. Табличное пространство по умолчанию при создании таблицы изменено на PRIMARY вместо NONE
      26. +
      +

      Исправлено:

      +
        +
      1. Генерация ER-диаграмм
      2. +
      3. Загрузка ER-диаграммы из файла
      4. +
      5. Генерация первичных ключей для ER-диаграммы
      6. +
      7. Редактирование ограничений таблицы в редакторе ER-диаграммы
      8. +
      9. Сохранение видимых столбцов в инструменте "Трейс Менеджер"
      10. +
      11. Отображение типа задачи при ее редактировании
      12. +
      13. Отрисовка ячеек таблицы набора результатов
      14. +
      15. Активность панели инструментов для табличных ограничений
      16. +
      17. Зависания при отображении панели автодополнения
      18. +
      19. Обновление дерева подключений
      20. +
      21. Действия во всплывающем окне для столбцов представлений в дереве соединений
      22. +
      23. NPE при открытии панели "Редактирование функции"
      24. +
      25. Выполнение SQL-скриптов с параметрами
      26. +
      27. Выполнение SQL-скриптов без оператора "SET TERM"
      28. +
      29. Активность инструментов OO API в инструменте "Генератор тестовых данных"
      30. +
      31. Генерация имени для новых триггеров по умолчанию
      32. +
      33. Генерация SQL-запросов для удаления UDF
      34. +
      35. Генерация SQL-запросов для процедур и функций
      36. +
      37. Генерация SQL-запросов для задач и табличных пространств с комментариями
      38. +
      39. Генерация SQL-запросов для пакетов без тела
      40. +
      41. Генерация SQL-запросов для триггеров на СУБД Firebird с версией ниже 3
      42. +
      43. Генерация SQL-запросов для функций с детерминированным возвращаемым типом
      44. +
      45. Генерация SQL-запросов для ограничений таблицы во время сравнения БД
      46. +
      47. Загрузка информации для таблиц, индексов и функций во время сравнения БД
      48. +
      49. Загрузка информации для задач во время их редактирования
      50. +
      51. Запуск сравнения БД с версией СУБД ниже 3
      52. +
      53. Сохранение SQL-скрипта после сравнения БД с изменениями пользователя
      54. +
      55. Генерация SQL-заглушек для процедур во время сравнения БД
      56. +
      57. Генерация заголовков для новых экземпляров панели "Системная консоль"
      58. +
      59. Сохранение истории экземпляров панели "Редактор Запросов"
      60. +
      61. Открытие диалогового окна для просмотра данных таблицы в первый раз
      62. +

      Основные изменения - v2024.07

      Улучшено:

        @@ -12,7 +78,7 @@

        Основные изменения - v2024.07

      1. Контекстное меню редактора запросов
      2. Дерево подключений
      3. Панель настроек
      4. -
      5. Панель “О программе”
      6. +
      7. Панель "О программе"
      8. Панель редактирования процедур, функций и задач
      9. Панель лога изменений (примечания к выпуску)
      10. Панель работы с драйверами
      11. @@ -36,7 +102,7 @@

        Основные изменения - v2024.07

      12. Возможность выбора типа линий
      13. -
      14. Кнопка “Выполнить” в редакторе запросов теперь может +
      15. Кнопка "Выполнить" в редакторе запросов теперь может
        • Выполнять только выделенный скрипт
        • Выполнять все, если ничего не выделено
        • @@ -203,7 +269,7 @@

          Основные изменения - v2024.01

        • Выполнение SQL-запросов в файл напрямую
        • Поддержка параметров транзакции в Редакторе Запросов
        • Выполнение запроса в нескольких подключениях одновременно
        • -
        • Окно подтверждения транзакции при закрытии Редактора Запросов и вкладки “Данные” у таблиц и представлений
        • +
        • Окно подтверждения транзакции при закрытии Редактора Запросов и вкладки "Данные" у таблиц и представлений
        • Отображение свойств подключения и базы данных (таких, как сервер, размер страницы, размер файла БД и т.д.)
        • Возможность копирования названий столбцов у набора данных
        • Вкладка "Триггеры" для представлений
        • @@ -221,14 +287,14 @@

          Основные изменения - v2024.01

        • Редактирование внешних ключей
        • Копирование подключения вместе с кодировкой
        • Редактирование данных в столбцах, имена которых содержат пробелы
        • -
        • Исчезновение текста редактируемой процедуры на вкладке “DDL” при переключении вкладок
        • +
        • Исчезновение текста редактируемой процедуры на вкладке "DDL" при переключении вкладок
        • Поиск объектов БД в дереве подключений, имена которых содержат символ '$'
        • Графические дефекты при двойном клике на имя таблицы в Редакторе Запросов
        • Ограничения на количество символов и максимальное значение при вводе данных в поле с типом INT128
        • Генерация SQL-кода для внешних UDR-функций, индексов и ограничений
        • Валидация таблиц с большим количеством полей и индексов
        • Доступность кнопок профайлера при переключении между вкладками приложения
        • -
        • Отображение роли PUBLIC в группе “Пользователи” в Менеджере Привилегий
        • +
        • Отображение роли PUBLIC в группе "Пользователи" в Менеджере Привилегий
        • Смещение фокуса при изменении поля фильтра в Менеджере Привилегий
        • Обновление списка триггеров у таблиц и представлений при добавлении нового триггера
        • Обновление списка полей таблиц при их изменении
        • @@ -236,7 +302,7 @@

          Основные изменения - v2024.01

          Основные изменения - v2023.10.1

          Добавлено:

            -
          1. Вкладка “Свойства” на панели редактирования таблиц БД.
          2. +
          3. Вкладка "Свойства" на панели редактирования таблиц БД.
          4. Настройка шаблонов SQL из Меню -> Инструменты.
          5. Галочка "Автоматический перенос текста" в текстовом обозревателе данных с типом BLOB.
          6. Возможность указать в настройках относительный путь до файла с логом.
          7. @@ -261,8 +327,8 @@

            Основные изменения - v2023.10.1
          8. Действие при нажатии на кнопку "Выбрать отображаемые столбцы набора данных", когда панель результатов закрыта.
          9. -
          10. Выделение удаляемых строк таблицы после закрытия вкладки “Данные” с отменой удаления.
          11. -
          12. Действие кнопки “Закрыть все вкладки”.
          13. +
          14. Выделение удаляемых строк таблицы после закрытия вкладки "Данные" с отменой удаления.
          15. +
          16. Действие кнопки "Закрыть все вкладки".
          17. Некорректная обработка ошибок при обновлении.
          18. Подсветка синтаксиса для многострочных идентификаторов.
          19. Некорректная работа приложения, если была нарушена структура пользовательских настроек.
          20. @@ -285,7 +351,7 @@

            Основные изменения - v2023.08

          21. Возможность включения режима переноса строк в редакторе запросов.
          22. Поддержка PSQL-профайлера.
          23. Древовидное отображение результата работы модуля сравнения БД с панелью различий для каждого объекта.
          24. -
          25. Новая панель выбора внешнего ключа на вкладке “Данные” при работе с таблицами БД.
          26. +
          27. Новая панель выбора внешнего ключа на вкладке "Данные" при работе с таблицами БД.
          28. Возможность сбросить цвет на значение по умолчанию, щелкнув правой кнопкой мыши в настройках цвета.
          29. Возможность фильтрации столбцов по их именам в окне "Видимость столбцов результата" для набора результатов.
          30. Анализ лога трейса.
          31. @@ -299,14 +365,14 @@

            Основные изменения - v2023.08

            Исправлено:

            1. Невозможность добавить комментарий для поля таблицы при его редактировании.
            2. -
            3. Ошибка, из-за которой содержимое вкладки “SQL” во время создания таблицы не обновлялось при изменениях во - вкладке “Комментарий”. +
            4. Ошибка, из-за которой содержимое вкладки "SQL" во время создания таблицы не обновлялось при изменениях во + вкладке "Комментарий".
            5. -
            6. Работа опции “Показать сетку” во вкладке “Ссылки” при работе с таблицей БД.
            7. -
            8. Отображение имени пользователя на вкладке “Результат выделения” при подтверждении редактирования пользователя. +
            9. Работа опции "Показать сетку" во вкладке "Ссылки" при работе с таблицей БД.
            10. +
            11. Отображение имени пользователя на вкладке "Результат выделения" при подтверждении редактирования пользователя.
            12. Генерация SQL-скриптов для пакетов, представлений, таблиц, задач.
            13. -
            14. Вкладки “Описание” переименованы в “Комментарий”.
            15. +
            16. Вкладки "Описание" переименованы в "Комментарий".
            17. Неверное применение темы и стиля в редакторе запросов.
            18. Плохое форматирование SQL-скрипта в редакторе запросов.
            19. NPE при навигации по папкам дерева подключений.
            20. @@ -364,8 +430,8 @@

              Основные изменения - v2023.05

            21. Чувствительность к регистру у параметров в редакторе запросов
            22. Работа с привилегиями объектов
            23. Проблема перезапуска РедЭксперта после установки обновления в Linux-системах
            24. -
            25. Неверное отображение (написание) ключевого слова “TIME ZONE”
            26. -
            27. Поведение кнопки “Выполнить” в редакторе запросов (Теперь при нажатии на нее скрипт выполняется как единый блок, +
            28. Неверное отображение (написание) ключевого слова "TIME ZONE"
            29. +
            30. Поведение кнопки "Выполнить" в редакторе запросов (Теперь при нажатии на нее скрипт выполняется как единый блок, а не делится на несколько в соответствии с разделителями. Для выполнения SQL-скрипта из нескольких запросов необходимо воспользоваться кнопкой «Выполнить SQL-скрипт»)
            31. @@ -378,7 +444,7 @@

              Основные изменения - v2023.02

              Исправлено:

              1. Ошибка модуля обратной связи с разработчиками (запрос новых функций, сообщения об ошибках, комментарии)
              2. -
              3. Очистка списка триггеров на вкладке “Триггеры” в таблице после открытия одного из них
              4. +
              5. Очистка списка триггеров на вкладке "Триггеры" в таблице после открытия одного из них
              6. Возврат к настройкам по умолчанию для цветов редактора запросов

              Основные изменения - v2023.01

              @@ -396,7 +462,7 @@

              Основные изменения - v2023.01

            32. Явное указание способа сортировки поля таблицы (COLLATE) при создании таблицы
            33. Вкладка «DDL для создания» в панели «Редактировать ограничение»
            34. Возможность посмотреть пароль при создании пользователя и авторизации на сайте reddatabase.ru
            35. -
            36. Возможность заменять “\n” на другой символ при экспорте в файл с разделителями
            37. +
            38. Возможность заменять "\n" на другой символ при экспорте в файл с разделителями
            39. Возможность работы с функциями и пакетами в менеджере привилегий
            40. Поддержка триггеров на представления
            @@ -412,9 +478,9 @@

            Основные изменения - v2023.01

          32. Ошибка генерации SQL-скрипта добавления ограничений таблицы, когда вместо нескольких ограничений в скрипт подставлялось только одно
          33. -
          34. Зависания Ред Эксперта после ошибки доступа к данным таблицы на вкладке “Данные” в меню “Таблица”.
          35. +
          36. Зависания Ред Эксперта после ошибки доступа к данным таблицы на вкладке "Данные" в меню "Таблица".
          37. Ошибка при добавлении комментариев к элементам БД во время их редактирования, в частности для таких объектов как - “Пользователь” и “Домен” + "Пользователь" и "Домен"
          38. Генерация SQL-скрипта при добавлении нового столбца в таблицу
          39. Экспорт в электронную таблицу. Теперь экспорт производится в Excel 2007
          40. diff --git a/src/org/executequery/repository/DatabaseDefinitionCache.java b/src/org/executequery/repository/DatabaseDefinitionCache.java index 1a8350a89..eb9e85a3b 100644 --- a/src/org/executequery/repository/DatabaseDefinitionCache.java +++ b/src/org/executequery/repository/DatabaseDefinitionCache.java @@ -22,6 +22,7 @@ import org.executequery.ExecuteQuerySystemError; import org.executequery.datasource.DatabaseDefinition; +import org.executequery.log.Log; import org.underworldlabs.swing.actions.ActionBuilder; import org.xml.sax.Attributes; import org.xml.sax.SAXException; @@ -31,7 +32,6 @@ import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import java.io.CharArrayWriter; -import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; @@ -42,54 +42,29 @@ * @author Takis Diakoumis */ public class DatabaseDefinitionCache { - - /** - * database definition cache - */ private static List databaseDefinitions; - private static final DatabaseDefinition nullDatabaseDefinition = - new DatabaseDefinition(DatabaseDefinition.INVALID_DATABASE_ID, ""); - - private DatabaseDefinitionCache() { - } - public static DatabaseDefinition getDatabaseDefinition(int id) { - if (databaseDefinitions == null) { + if (id == -1) + return new DatabaseDefinition(DatabaseDefinition.INVALID_DATABASE_ID, ""); + if (databaseDefinitions == null) load(); - } - if (id == -1) { - - return nullDatabaseDefinition; - } + for (DatabaseDefinition databaseDefinition : databaseDefinitions) + if (databaseDefinition.getId() == id) + return databaseDefinition; - for (int i = 0, n = databaseDefinitions.size(); i < n; i++) { - DatabaseDefinition dd = databaseDefinitions.get(i); - if (dd.getId() == id) { - return dd; - } - } - - return null; - } - - public static DatabaseDefinition getDatabaseDefinitionAt(int index) { - if (databaseDefinitions == null) { - load(); - } - return databaseDefinitions.get(index); + return new DatabaseDefinition(DatabaseDefinition.INVALID_DATABASE_ID, ""); } /** * Returns the database definitions within a collection. */ public static List getDatabaseDefinitions() { - if (databaseDefinitions == null) { + if (databaseDefinitions == null) load(); - } return databaseDefinitions; } @@ -97,85 +72,73 @@ public static List getDatabaseDefinitions() { * Loads the definitions from file. */ public static synchronized void load() { - InputStream input = null; - ClassLoader cl = ActionBuilder.class.getClassLoader(); + databaseDefinitions = new ArrayList<>(); String path = "org/executequery/databases.xml"; - if (cl != null) { - input = cl.getResourceAsStream(path); - } else { - input = ClassLoader.getSystemResourceAsStream(path); - } + ClassLoader classLoader = ActionBuilder.class.getClassLoader(); + + try (InputStream input = classLoader != null ? + classLoader.getResourceAsStream(path) : + ClassLoader.getSystemResourceAsStream(path)) { - databaseDefinitions = new ArrayList(); - try { SAXParserFactory factory = SAXParserFactory.newInstance(); factory.setNamespaceAware(true); SAXParser parser = factory.newSAXParser(); DatabaseHandler handler = new DatabaseHandler(); parser.parse(input, handler); + } catch (Exception e) { - e.printStackTrace(); - throw new ExecuteQuerySystemError(); - } finally { - if (input != null) { - try { - input.close(); - } catch (IOException e) { - } - } + Log.error(e.getMessage(), e); + throw new ExecuteQuerySystemError(e); } - } - static class DatabaseHandler extends DefaultHandler { + private static class DatabaseHandler extends DefaultHandler { private DatabaseDefinition database = new DatabaseDefinition(); - private CharArrayWriter contents = new CharArrayWriter(); - - public DatabaseHandler() { - } + private final CharArrayWriter contents = new CharArrayWriter(); - public void startElement(String nameSpaceURI, String localName, - String qName, Attributes attrs) { + @Override + public void startElement(String nameSpaceURI, String localName, String qName, Attributes attrs) { contents.reset(); - if (localName.equals("database")) { + if (localName.equals("database")) database = new DatabaseDefinition(); - } } - public void endElement(String nameSpaceURI, String localName, - String qName) { - if (localName.equals("id")) { - database.setId(Integer.parseInt(contents.toString())); - } else if (localName.equals("name")) { - database.setName(contents.toString()); - } else if (localName.equals("url")) { - database.addUrlPattern(contents.toString()); - } else if (localName.equals("database")) { - databaseDefinitions.add(database); + @Override + public void endElement(String nameSpaceURI, String localName, String qName) { + switch (localName) { + case "id": + database.setId(Integer.parseInt(contents.toString())); + break; + case "name": + database.setName(contents.toString()); + break; + case "url": + database.addUrlPattern(contents.toString()); + break; + case "database": + databaseDefinitions.add(database); + break; } } + @Override public void characters(char[] data, int start, int length) { contents.write(data, start, length); } + @Override public void ignorableWhitespace(char[] data, int start, int length) { characters(data, start, length); } + @Override public void error(SAXParseException spe) throws SAXException { throw new SAXException(spe.getMessage()); } - } // DatabaseHandler - -} - - - - - + } // DatabaseHandler class +} diff --git a/src/org/executequery/sql/QueryDispatcher.java b/src/org/executequery/sql/QueryDispatcher.java index 881c265dc..71e4d5015 100644 --- a/src/org/executequery/sql/QueryDispatcher.java +++ b/src/org/executequery/sql/QueryDispatcher.java @@ -1059,41 +1059,36 @@ private Object executeScript(String script, boolean anyConnections) { continue; } + if (isBeginEndQuery(query)) { + executeCreateOrAlterObject(queryToExecute, query, anyConnections); + continue; + } + int type = query.getQueryType(); if (type != QueryTypes.COMMIT && type != QueryTypes.ROLLBACK) { - logExecution(queryToExecute, anyConnections); } else { - - if (type == QueryTypes.COMMIT) { - - setOutputMessage(querySender.getDatabaseConnection(), - SqlMessages.ACTION_MESSAGE, - COMMITTING_LAST, anyConnections); - - } else if (type == QueryTypes.ROLLBACK) { - - setOutputMessage(querySender.getDatabaseConnection(), - SqlMessages.ACTION_MESSAGE, - ROLLING_BACK_LAST, anyConnections); - } - + setOutputMessage( + querySender.getDatabaseConnection(), + SqlMessages.ACTION_MESSAGE, + type == QueryTypes.COMMIT ? COMMITTING_LAST : ROLLING_BACK_LAST, + anyConnections + ); } - PreparedStatement statement; - if (queryToExecute.toUpperCase().contains("SET BLOBFILE ")) { blobFilePath = "blobfile=" + queryToExecute.substring(queryToExecute.indexOf("SET BLOBFILE ") + 14, queryToExecute.length() - 1); continue; } + PreparedStatement statement; if (query.getQueryType() == QueryTypes.SET_AUTODDL_ON || query.getQueryType() == QueryTypes.SET_AUTODDL_OFF) statement = null; else if (query.getQueryType() == QueryTypes.INSERT) statement = prepareStatementWithParameters(queryToExecute, blobFilePath); else - statement = prepareStatementWithParameters(queryToExecute, ""); + statement = prepareStatementWithParameters(queryToExecute, getVariables(queryToExecute)); SqlStatementResult result = querySender.execute(type, statement); diff --git a/src/org/executequery/sql/QueryTokenizer.java b/src/org/executequery/sql/QueryTokenizer.java index e1a29bc69..7f01c6435 100644 --- a/src/org/executequery/sql/QueryTokenizer.java +++ b/src/org/executequery/sql/QueryTokenizer.java @@ -273,6 +273,10 @@ public void extractNotDelimiterTokens(String query) { declareBlockTokens.add(new Token(TokenTypes.DECLARE_BLOCK, startIndex, antlrToken.getStopIndex())); state = AS; } + if (antlrToken.getType() == SqlLexer.KEYWORD && antlrToken.getText().equalsIgnoreCase("as")) { + declareBlockTokens.add(new Token(TokenTypes.DECLARE_BLOCK, startIndex, antlrToken.getStopIndex())); + state = AS; + } } else if (state == BEGIN_END) { if (antlrToken.getType() == SqlLexer.KEYWORD) { if (antlrToken.getText().equalsIgnoreCase("begin")) { @@ -281,7 +285,7 @@ public void extractNotDelimiterTokens(String query) { beginCount--; if (beginCount <= 0) { beginEndBlockTokens.add(new Token(TokenTypes.BEGIN_END_BLOCK, startIndex, antlrToken.getStopIndex())); - state = NORMAL; + state = AS; } } } diff --git a/src/org/executequery/sql/sqlbuilder/Field.java b/src/org/executequery/sql/sqlbuilder/Field.java index 941842459..9e04db4ed 100644 --- a/src/org/executequery/sql/sqlbuilder/Field.java +++ b/src/org/executequery/sql/sqlbuilder/Field.java @@ -6,6 +6,7 @@ public class Field { String alias; boolean isNull = false; String statement; + String castType; public static Field createField() { return new Field(); @@ -66,17 +67,31 @@ public Field setNull(boolean aNull) { return this; } + public Field setCast(String castType) { + this.castType = castType; + return this; + } + + public String getCastType() { + return castType; + } + public String getFieldTable() { return table.getAlias() + "." + name; } public String getFieldForQuery() { StringBuilder sb = new StringBuilder(); + if (isNull) sb.append("NULL"); else if (statement != null) sb.append(statement); - else sb.append(getFieldTable()); + else if (castType != null) + sb.append("CAST (").append(getFieldTable()).append(" AS ").append(castType).append(")"); + else + sb.append(getFieldTable()); + sb.append(" AS ").append(alias); return sb.toString(); } diff --git a/src/org/underworldlabs/procedureParser/ProcedureParser.g4 b/src/org/underworldlabs/procedureParser/ProcedureParser.g4 index 5ce300e1e..e8138aa12 100644 --- a/src/org/underworldlabs/procedureParser/ProcedureParser.g4 +++ b/src/org/underworldlabs/procedureParser/ProcedureParser.g4 @@ -20,13 +20,25 @@ grammar ProcedureParser; ; create_or_alter_procedure_stmt - :K_CREATE spases_or_comment K_OR spases_or_comment K_ALTER K_PROCEDURE procedure_name + :K_CREATE spases_or_comment K_OR spases_or_comment K_ALTER spases_or_comment K_PROCEDURE spases_or_comment procedure_name (K_AUTHID (K_OWNER|K_CALLER))? declare_block |recreate_procedure_stmt |alter_procedure_stmt |create_procedure_stmt ; + + declare_procedure_stmt + :K_DECLARE spases_or_comment K_PROCEDURE spases_or_comment procedure_name + (K_AUTHID (K_OWNER|K_CALLER))? + declare_block + ; + +declare_function_stmt +:K_DECLARE spases_or_comment K_FUNCTION spases_or_comment procedure_name +declare_function_block +; + recreate_procedure_stmt :K_RECREATE K_PROCEDURE procedure_name (K_AUTHID (K_OWNER|K_CALLER))? @@ -44,18 +56,36 @@ grammar ProcedureParser; declare_block ; + declare_function_block + : ('(' input_parameter (',' input_parameter)*')')? + K_RETURNS output_parameter + spases_or_comment? K_AS spases_or_comment + declare_stmt* + K_BEGIN + body + K_END +; + declare_block : ('(' input_parameter (',' input_parameter)*')')? - (K_RETURNS '(' output_parameter (',' output_parameter)*')')? - K_AS - local_variable* + (spases_or_comment? K_RETURNS '(' output_parameter (',' output_parameter)*')')? + spases_or_comment? K_AS spases_or_comment + declare_stmt* K_BEGIN body K_END + spases_or_comment? ; +declare_stmt +:local_variable + |declare_procedure_stmt + |declare_function_stmt + ; + declare_block_without_params -:spases_or_comment? local_variable* +:spases_or_comment? +declare_stmt* full_body ; @@ -65,7 +95,7 @@ full_body body: ~(K_END)* - | ~(K_BEGIN)* K_BEGIN body K_END ~(K_END)* + | ~(K_BEGIN|K_END)* K_BEGIN body K_END ~(K_END)* ; local_variable @@ -114,7 +144,8 @@ body: variable_name - :any_name + : IDENTIFIER + | STRING_LITERAL ; input_parameter @@ -1108,6 +1139,7 @@ K_FORTRAN : F O R T R A N ; K_FOUND : F O U N D ; K_FROM : F R O M ; K_FULL : F U L L ; +K_FUNCTION : F U N C T I O N; K_GENERATED : G E N E R A T E D ; K_GEN_UUID : G E N '_' U U I D ; K_GET : G E T ; diff --git a/src/org/underworldlabs/statParser/StatDatabase.java b/src/org/underworldlabs/statParser/StatDatabase.java index 9272771b9..5a37e4602 100644 --- a/src/org/underworldlabs/statParser/StatDatabase.java +++ b/src/org/underworldlabs/statParser/StatDatabase.java @@ -8,30 +8,31 @@ public class StatDatabase extends TableModelObject { public String fullPath; public static final String[][] ITEMS_HDR = { - {"Flags", "i", null}, - {"Checksum", "i", null}, - {"Generation", "i", null}, - {"System Change Number", "i", "system_change_number"}, - {"Page size", "i", null}, - {"Server", "s", null}, - {"ODS version", "s", "ods_version"}, - {"Oldest transaction", "i", "oit"}, - {"Oldest active", "i", "oat"}, - {"Oldest snapshot", "i", "ost"}, - {"Next transaction", "i", null}, - {"Bumped transaction", "i", null}, - {"Autosweep gap", "i", null}, - {"Sequence number", "i", null}, - {"Next attachment ID", "i", "next_attachment_id"}, - {"Implementation ID", "i", "implementation_id"}, - {"Implementation", "s", null}, - {"Shadow count", "i", null}, - {"Page buffers", "i", null}, - {"Next header page", "i", null}, - {"Database dialect", "i", null}, - {"Creation date", "d", null}, - {"Attributes", "l", null} + {"Flags", "i", null, null}, + {"Checksum", "i", null, null}, + {"Generation", "i", null, null}, + {"System Change Number", "i", "system_change_number", null}, + {"Page size", "i", null, null}, + {"Server", "s", null, null}, + {"ODS version", "s", "ods_version", null}, + {"Oldest transaction", "i", "oit", null}, + {"Oldest active", "i", "oat", null}, + {"Oldest snapshot", "i", "ost", null}, + {"Next transaction", "i", null, null}, + {"Bumped transaction", "i", null, null}, + {"Autosweep gap", "i", null, null}, + {"Sequence number", "i", null, null}, + {"Next attachment ID", "i", "next_attachment_id", null}, + {"Implementation ID", "i", "implementation_id", null}, + {"Implementation", "s", null, null}, + {"Shadow count", "i", null, null}, + {"Page buffers", "i", null, null}, + {"Next header page", "i", null, null}, + {"Database dialect", "i", null, null}, + {"Creation date", "d", null, null}, + {"Attributes", "l", null, null}, }; + public long gstat_version; public long system_change_number; diff --git a/src/org/underworldlabs/statParser/StatIndex.java b/src/org/underworldlabs/statParser/StatIndex.java index 9887be624..b9c7aae45 100644 --- a/src/org/underworldlabs/statParser/StatIndex.java +++ b/src/org/underworldlabs/statParser/StatIndex.java @@ -4,29 +4,29 @@ import java.util.ArrayList; public class StatIndex extends StatTableIndex { - public static final String[][] ITEMS_IDX = { - {"Index name:", "s", "name"}, - {"Table name:", "s", "table_name"}, - {"Tablespace:", "s", "tablespaceName"}, - {"Real selectivity:", "f+", "real_selectivity"}, - {"Average data length:", "f", "avg_data_length"}, - {"total dup:", "i", null}, - {"max dup:", "i", null}, - {"Root page:", "i", null}, - {"Depth:", "i", null}, - {"leaf buckets:", "i", null}, - {"nodes:", "i", null}, - {"Average node length:", "f", "avg_node_length"}, - {"Average key length:", "f", "avg_key_length"}, - {"compression ratio:", "f", null}, - {"Average prefix length:", "f", "avg_prefix_length"}, - {"average data length:", "f", "avg_data_length"}, - {"Clustering factor:", "f", null}, - {"ratio:", "f", null}, - {"leaf full size:", "i", null}, - {"estimated full size:", "i", null}, + public static final String[][] ITEMS_IDX = { + {"Index name:", "s", "name", null}, + {"Table name:", "s", "table_name", null}, + {"Tablespace:", "s", "tablespaceName", bundleString("tablespace_name")}, + {"Real selectivity:", "f+", "real_selectivity", bundleString("real_selectivity")}, + {"Average data length:", "f", "avg_data_length", bundleString("avg_data_length")}, + {"total dup:", "i", null, bundleString("total_dup")}, + {"max dup:", "i", null, bundleString("max_dup")}, + {"Root page:", "i", null, bundleString("root_page")}, + {"Depth:", "i", null, bundleString("depth")}, + {"leaf buckets:", "i", null, bundleString("leaf_buckets")}, + {"nodes:", "i", null, bundleString("nodes")}, + {"Average node length:", "f", "avg_node_length", bundleString("avg_node_length")}, + {"Average key length:", "f", "avg_key_length", bundleString("avg_key_length")}, + {"compression ratio:", "f", null, bundleString("compression_ratio.index")}, + {"Average prefix length:", "f", "avg_prefix_length", bundleString("avg_prefix_length")}, + {"Clustering factor:", "f", null, bundleString("clustering_factor")}, + {"ratio:", "f", null, bundleString("ratio")}, + {"leaf full size:", "i", null, bundleString("leaf_full_size")}, + {"estimated full size:", "i", null, bundleString("estimated_full_size")}, }; + public StatTable table; public String table_name; public double real_selectivity; diff --git a/src/org/underworldlabs/statParser/StatTable.java b/src/org/underworldlabs/statParser/StatTable.java index 7455ee70e..cdd1d83bd 100644 --- a/src/org/underworldlabs/statParser/StatTable.java +++ b/src/org/underworldlabs/statParser/StatTable.java @@ -3,45 +3,46 @@ import java.util.List; public class StatTable extends StatTableIndex { + public static final String[][] ITEMS_TBL = { - {"Table name:", "s", "name"}, - {"Tablespace:", "s", "tablespaceName"}, - {"Primary pointer page:", "i", null}, - {"Index root page:", "i", null}, - {"Pointer pages:", "i", "pointer_pages"}, - {"Data pages:", "i", null}, - {"data page slots:", "i", null}, - {"Primary pages:", "i", null}, - {"secondary pages:", "i", null}, - {"swept pages:", "i", null}, - {"Empty pages:", "i", null}, - {"full pages:", "i", null}, - {"Big record pages:", "i", null}, - {"blob pages:", "i", null}, - {"Average record length:", "f", "avg_record_length"}, - {"total records:", "i", null}, - {"Average version length:", "f", "avg_version_length"}, - {"total versions:", "i", null}, - {"max versions:", "i", null}, - {"average fill:", "p", "avg_fill"}, - {"Total formats:", "i", null}, - {"used formats:", "i", null}, - {"Average fragment length:", "f", "avg_fragment_length"}, - {"total fragments:", "i", null}, - {"max fragments:", "i", null}, - {"Average unpacked length:", "f", "avg_unpacked_length"}, - {"compression ratio:", "f", null}, - {"Blobs:", "i", null}, - {"total length:", "i+", "blobs_total_length"}, - {"Level 0:", "i", null}, - {"Level 1:", "i", null}, - {"Level 2:", "i", null}, - {"table size(without blobs):", "i", "table_size"}, - {"size with blobs:", "i", "size_with_blobs"}, - {"size with blob_pages:", "i", "size_with_blob_pages"}, - {"full size with indices:", "i", "size_with_indices"} - + {"Table name:", "s", "name", null}, + {"Tablespace:", "s", "tablespaceName", bundleString("tablespace_name")}, + {"Primary pointer page:", "i", null, bundleString("primary_pointer_page")}, + {"Index root page:", "i", null, bundleString("index_root_page")}, + {"Pointer pages:", "i", "pointer_pages", bundleString("pointer_pages")}, + {"Data pages:", "i", null, bundleString("data_pages")}, + {"data page slots:", "i", null, bundleString("data_page_slots")}, + {"Primary pages:", "i", null, bundleString("primary_pages")}, + {"secondary pages:", "i", null, bundleString("secondary_pages")}, + {"swept pages:", "i", null, bundleString("swept_pages")}, + {"Empty pages:", "i", null, bundleString("empty_pages")}, + {"full pages:", "i", null, bundleString("full_pages")}, + {"Big record pages:", "i", null, bundleString("big_record_pages")}, + {"blob pages:", "i", null, bundleString("blob_pages")}, + {"Average record length:", "f", "avg_record_length", bundleString("avg_record_length")}, + {"total records:", "i", null, bundleString("total_records")}, + {"Average version length:", "f", "avg_version_length", bundleString("avg_version_length")}, + {"total versions:", "i", null, bundleString("total_versions")}, + {"max versions:", "i", null, bundleString("max_versions")}, + {"average fill:", "p", "avg_fill", bundleString("avg_fill")}, + {"Total formats:", "i", null, bundleString("total_formats")}, + {"used formats:", "i", null, bundleString("used_formats")}, + {"Average fragment length:", "f", "avg_fragment_length", bundleString("avg_fragment_length")}, + {"total fragments:", "i", null, bundleString("total_fragments")}, + {"max fragments:", "i", null, bundleString("max_fragments")}, + {"Average unpacked length:", "f", "avg_unpacked_length", bundleString("avg_unpacked_length")}, + {"compression ratio:", "f", null, bundleString("compression_ratio")}, + {"Blobs:", "i", null, bundleString("blobs")}, + {"total length:", "i+", "blobs_total_length", bundleString("blobs_total_length")}, + {"Level 0:", "i", null, bundleString("level_0")}, + {"Level 1:", "i", null, bundleString("level_1")}, + {"Level 2:", "i", null, bundleString("level_2")}, + {"table size(without blobs):", "i", "table_size", bundleString("table_size")}, + {"size with blobs:", "i", "size_with_blobs", bundleString("size_with_blobs")}, + {"size with blob_pages:", "i", "size_with_blob_pages", bundleString("size_with_blob_pages")}, + {"full size with indices:", "i", "size_with_indices", bundleString("size_with_indices")}, }; + public long table_id; public long primary_pointer_page; public long index_root_page; diff --git a/src/org/underworldlabs/statParser/StatTablespace.java b/src/org/underworldlabs/statParser/StatTablespace.java index 082e950ab..7954dbd1f 100644 --- a/src/org/underworldlabs/statParser/StatTablespace.java +++ b/src/org/underworldlabs/statParser/StatTablespace.java @@ -4,14 +4,14 @@ import java.util.List; public class StatTablespace extends TableModelObject { + public static final String[][] ITEMS_TBS = { - {"Name:", "s", "name"}, - {"Full path:", "s", null}, - {"Table count:", "i", null}, - {"Index count:", "i", null} - /* {"TableName count:", "i", null}, - {"IndexName count:", "i", null},*/ + {"Name:", "s", "name", null}, + {"Full path:", "s", null, bundleString("full_path")}, + {"Table count:", "i", null, bundleString("table_count")}, + {"Index count:", "i", null, bundleString("index_count")}, }; + public String full_path; public List tableNames; public List indexNames; diff --git a/src/org/underworldlabs/statParser/TableModelObject.java b/src/org/underworldlabs/statParser/TableModelObject.java index c4c9eab40..21fe9f819 100644 --- a/src/org/underworldlabs/statParser/TableModelObject.java +++ b/src/org/underworldlabs/statParser/TableModelObject.java @@ -1,8 +1,12 @@ package org.underworldlabs.statParser; +import org.executequery.localization.Bundles; + import java.time.LocalDateTime; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import java.util.stream.Collectors; public abstract class TableModelObject implements Comparable { @@ -30,6 +34,9 @@ public List getColumns() { return columns; } + public List getToolTips() { + return Arrays.stream(getItems()).map(item -> item[3]).collect(Collectors.toList()); + } public String getColumnName(int column) { return getColumns().get(column).toLowerCase(); @@ -110,4 +117,9 @@ public String getName() { public void setName(String name) { this.name = name; } + + protected static String bundleString(String key, Object... args) { + return Bundles.get(TableModelObject.class, key, args); + } + } diff --git a/src/org/underworldlabs/swing/AbstractStatusBarPanel.java b/src/org/underworldlabs/swing/AbstractStatusBarPanel.java index 6ccc460c7..417bf268e 100644 --- a/src/org/underworldlabs/swing/AbstractStatusBarPanel.java +++ b/src/org/underworldlabs/swing/AbstractStatusBarPanel.java @@ -117,6 +117,28 @@ protected void setLabelText(int index, final String text) { } + protected void setLabelToolTip(int index, final String toolTip) { + + Object object = components.get(index); + if (object instanceof JLabel) { + + final JLabel label = (JLabel) object; + label.setToolTipText(toolTip); + } + } + + protected void setLabelIcon(int index, final Icon icon) { + + Object object = components.get(index); + if (object instanceof JLabel) { + + final JLabel label = (JLabel) object; + label.setIcon(icon); + + scheduleLabelRepaint(label); + } + } + private void scheduleLabelRepaint(final JLabel label) { Runnable update = new Runnable() { diff --git a/src/org/underworldlabs/swing/ConnectionsComboBox.java b/src/org/underworldlabs/swing/ConnectionsComboBox.java new file mode 100644 index 000000000..42e617f21 --- /dev/null +++ b/src/org/underworldlabs/swing/ConnectionsComboBox.java @@ -0,0 +1,139 @@ +package org.underworldlabs.swing; + +import org.executequery.EventMediator; +import org.executequery.databasemediators.DatabaseConnection; +import org.executequery.datasource.ConnectionManager; +import org.executequery.event.ApplicationEvent; +import org.executequery.event.ConnectionEvent; +import org.executequery.event.ConnectionListener; +import org.executequery.gui.IconManager; + +import javax.swing.*; +import java.awt.*; +import java.util.Objects; + +import static org.executequery.gui.browser.BrowserConstants.*; + +public class ConnectionsComboBox extends JComboBox + implements ConnectionListener { + + public ConnectionsComboBox(boolean showOnlyActiveConnections) { + super(); + + setModel(new DefaultComboBoxModel<>(showOnlyActiveConnections ? + ConnectionManager.getActiveConnections() : + ConnectionManager.getAllConnections() + )); + + if (showOnlyActiveConnections) { + EventMediator.registerListener(this); + + } else { + setRenderer(new ConnectionsComboRenderer()); + selectFirstActiveConnection(); + } + } + + public DatabaseConnection getSelectedConnection() { + return (DatabaseConnection) getSelectedItem(); + } + + public boolean hasConnection(DatabaseConnection connection) { + + for (int i = 0; i < getItemCount(); i++) + if (Objects.equals(getItemAt(i), connection)) + return true; + + return false; + } + + private void selectFirstActiveConnection() { + for (int i = 0; i < getItemCount(); i++) { + DatabaseConnection dc = getItemAt(i); + if (dc.isConnected()) { + setSelectedItem(dc); + return; + } + } + } + + private void updateEnable() { + setEnabled(getItemCount() > 0); + } + + // --- ConnectionListener impl --- + + @Override + public void connected(ConnectionEvent connectionEvent) { + super.addItem(connectionEvent.getDatabaseConnection()); + updateEnable(); + } + + @Override + public void disconnected(ConnectionEvent connectionEvent) { + super.removeItem(connectionEvent.getDatabaseConnection()); + updateEnable(); + } + + @Override + public boolean canHandleEvent(ApplicationEvent event) { + return event instanceof ConnectionEvent; + } + + // --- JComboBox impl --- + + @Override + public void setModel(ComboBoxModel aModel) { + super.setModel(aModel); + updateEnable(); + } + + @Override + public void addItem(DatabaseConnection item) { + super.addItem(item); + updateEnable(); + } + + @Override + public void insertItemAt(DatabaseConnection item, int index) { + super.insertItemAt(item, index); + updateEnable(); + } + + @Override + public void removeItem(Object anObject) { + super.removeItem(anObject); + updateEnable(); + } + + @Override + public void removeItemAt(int anIndex) { + super.removeItemAt(anIndex); + updateEnable(); + } + + @Override + public void removeAllItems() { + super.removeAllItems(); + updateEnable(); + } + + // --- + + private static class ConnectionsComboRenderer extends DefaultListCellRenderer { + + private static final Icon CONNECTED_ICON = IconManager.getIcon(GRANT_IMAGE, "svg", 10, IconManager.IconFolder.BASE); + private static final Icon NOT_CONNECTED_ICON = IconManager.getIcon(FIELD_GRANT_IMAGE, "svg", 10, IconManager.IconFolder.BASE); + + @Override + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { + + JLabel component = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + component.setIcon(((DatabaseConnection) value).isConnected() ? CONNECTED_ICON : NOT_CONNECTED_ICON); + + return component; + } + + } // ConnectionsComboRenderer class + +} diff --git a/src/org/underworldlabs/swing/DateDifferenceSetter.java b/src/org/underworldlabs/swing/DateDifferenceSetter.java deleted file mode 100644 index 68af09d10..000000000 --- a/src/org/underworldlabs/swing/DateDifferenceSetter.java +++ /dev/null @@ -1,57 +0,0 @@ -package org.underworldlabs.swing; - -import javax.swing.*; -import java.awt.*; - -public class DateDifferenceSetter extends JPanel { - NumberTextField yearsField; - NumberTextField mouthsField; - NumberTextField daysField; - - public DateDifferenceSetter() { - init(); - } - - private void init() { - yearsField = new NumberTextField(); - yearsField.setValue(0); - - mouthsField = new NumberTextField(); - mouthsField.setValue(0); - - daysField = new NumberTextField(); - daysField.setValue(0); - - setLayout(new GridBagLayout()); - JLabel label = new JLabel("Years"); - add(label, new GridBagConstraints(0, 0, 1, 1, 0, 0, - GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0, 0)); - add(yearsField, new GridBagConstraints(1, 0, 1, 1, 1, 0, - GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0, 0)); - - label = new JLabel("Mouths"); - add(label, new GridBagConstraints(0, 1, 1, 1, 0, 0, - GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0, 0)); - add(mouthsField, new GridBagConstraints(1, 1, 1, 1, 1, 0, - GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0, 0)); - - label = new JLabel("Days"); - add(label, new GridBagConstraints(0, 2, 1, 1, 0, 0, - GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0, 0)); - add(daysField, new GridBagConstraints(1, 2, 1, 1, 1, 0, - GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0, 0)); - } - - public int getYears() { - return yearsField.getValue(); - } - - public int getMouths() { - return mouthsField.getValue(); - } - - public int getDays() { - return daysField.getValue(); - } - -} diff --git a/src/org/underworldlabs/swing/ExceptionErrorDialog.java b/src/org/underworldlabs/swing/ExceptionErrorDialog.java index c3112b13b..6b33af4be 100644 --- a/src/org/underworldlabs/swing/ExceptionErrorDialog.java +++ b/src/org/underworldlabs/swing/ExceptionErrorDialog.java @@ -24,15 +24,21 @@ import org.executequery.gui.WidgetFactory; import org.executequery.localization.Bundles; import org.underworldlabs.swing.layouts.GridBagHelper; +import org.underworldlabs.util.MiscUtils; import javax.swing.*; import java.awt.*; import java.awt.datatransfer.StringSelection; +import java.awt.event.ComponentEvent; +import java.awt.event.ComponentListener; import java.io.PrintWriter; import java.io.StringWriter; import java.sql.SQLException; +import java.util.LinkedList; +import java.util.List; import java.util.StringTokenizer; import java.util.Vector; +import java.util.stream.Collectors; /** * Generic error dialog box displaying the stack trace. @@ -42,7 +48,10 @@ public class ExceptionErrorDialog extends AbstractBaseDialog { private static final int STACK_HEIGHT = 220; - private static final int DEFAULT_WIDTH = 600; + private static final int DEFAULT_WIDTH = 700; + + private static final String HTML_ROW = "%s\n"; + private static final String HTML_MESSAGE = "%s
            "; private final String message; private final Class sourceClass; @@ -145,7 +154,7 @@ private void arrange() { gbh = new GridBagHelper().setInsets(5, 5, 20, 0); mainPanel.add(new JLabel(errorIcon), gbh.get()); - mainPanel.add(new JLabel(getExceptionMessage()), gbh.nextCol().rightGap(5).leftGap(0).setMaxWeightX().fillHorizontally().spanX().get()); + mainPanel.add(new ExceptionMessageLabel(message), gbh.nextCol().rightGap(5).leftGap(0).setMaxWeightX().fillHorizontally().spanX().get()); mainPanel.add(buttonPanel, gbh.anchorEast().fillNone().leftGap(5).bottomGap(5).nextRowFirstCol().spanX().get()); mainPanel.add(stackTracePanel, gbh.nextRowFirstCol().topGap(0).setMaxWeightY().fillBoth().get()); @@ -155,7 +164,8 @@ private void arrange() { pack(); defaultHeight = getHeight(); - setMinimumSize(new Dimension(Math.max(DEFAULT_WIDTH, getWidth()), defaultHeight)); + int defaultWidth = Math.max(Math.min(getPreferredSize().width, Toolkit.getDefaultToolkit().getScreenSize().width / 2), DEFAULT_WIDTH); + setMinimumSize(new Dimension(defaultWidth, defaultHeight)); setSize(getMinimumSize()); Point location = GUIUtils.getPointToCenter(getOwner(), getSize()); @@ -195,35 +205,6 @@ private void buildStackTracePanel() { } } - private String getExceptionMessage() { - - StringBuilder sb = new StringBuilder(); - sb.append(""); - - String lineBreak = "\n"; - boolean hasLineBreak = true; - - StringTokenizer tokenizer = new StringTokenizer(message, lineBreak, true); - while (tokenizer.hasMoreTokens()) { - String token = tokenizer.nextToken(); - - if (lineBreak.equals(token)) { - if (hasLineBreak) - sb.append(""); - - hasLineBreak = true; - continue; - } - - sb.append(""); - hasLineBreak = false; - } - - sb.append("
            ").append(token).append("
            "); - - return sb.toString(); - } - /** * Prints the specified exception's stack trace * to the text pane. @@ -300,4 +281,125 @@ private String bundleString(String key) { return Bundles.get(ExceptionErrorDialog.class, key); } + // --- + + private class ExceptionMessageLabel extends JLabel implements ComponentListener { + private final List messages; + + public ExceptionMessageLabel(String originalMessage) { + super(); + this.messages = parseMessage(originalMessage); + addComponentListener(this); + update(); + } + + public List parseMessage(String originalMessage) { + + String lineBreak = "\n"; + boolean hasLineBreak = true; + List parsedMessage = new LinkedList<>(); + + StringTokenizer tokenizer = new StringTokenizer(originalMessage, lineBreak, true); + while (tokenizer.hasMoreTokens()) { + String token = tokenizer.nextToken(); + + if (lineBreak.equals(token)) { + if (hasLineBreak) + parsedMessage.add(new ExceptionMessage()); + + hasLineBreak = true; + continue; + } + + parsedMessage.add(new ExceptionMessage(token.trim())); + hasLineBreak = false; + } + + return parsedMessage; + } + + private void update() { + ExceptionMessage.setProperties( + getFontMetrics(getFont()), + ExceptionErrorDialog.this.getWidth() - 100, + getInsets().left + getInsets().right + ); + + String preparedMessage = messages.stream() + .map(ExceptionMessage::getPrepareMessage) + .collect(Collectors.joining()); + + setText(String.format(HTML_MESSAGE, preparedMessage)); + } + + // --- ComponentListener impl --- + + @Override + public void componentResized(ComponentEvent e) { + update(); + } + + @Override + public void componentMoved(ComponentEvent e) { + } + + @Override + public void componentShown(ComponentEvent e) { + } + + @Override + public void componentHidden(ComponentEvent e) { + } + + } // ExceptionMessageLabel class + + private static class ExceptionMessage { + private static final String ELLIPSIS = "..."; + + private static FontMetrics fontMetrics; + private static int availableWidth; + private final String message; + + public ExceptionMessage() { + this(null); + } + + public ExceptionMessage(String message) { + this.message = message; + } + + public static void setProperties(FontMetrics fontMetrics, int availableWidth, int insets) { + ExceptionMessage.fontMetrics = fontMetrics; + ExceptionMessage.availableWidth = availableWidth - insets; + } + + public String getPrepareMessage() { + + if (MiscUtils.isNull(message)) + return String.format(HTML_ROW, ""); + + String preparedMessage = message; + int textWidth = fontMetrics.stringWidth(message); + + if (textWidth > availableWidth) { + int ellipsisWidth = fontMetrics.stringWidth(ELLIPSIS); + + do { + preparedMessage = clipText(preparedMessage); + textWidth = fontMetrics.stringWidth(preparedMessage) + ellipsisWidth; + + } while (!preparedMessage.isEmpty() && textWidth >= availableWidth); + + preparedMessage += ELLIPSIS; + } + + return String.format(HTML_ROW, preparedMessage); + } + + private String clipText(String text) { + return text.substring(0, text.length() - 1); + } + + } // ExceptionMessage class + } diff --git a/src/org/underworldlabs/swing/GUIUtils.java b/src/org/underworldlabs/swing/GUIUtils.java index c38578d5d..09d0c9422 100644 --- a/src/org/underworldlabs/swing/GUIUtils.java +++ b/src/org/underworldlabs/swing/GUIUtils.java @@ -507,6 +507,23 @@ public static final int displayYesNoDialog(Component parent, Object message, Str message, new Object[]{Bundles.getCommon("yes.button"), Bundles.getCommon("no.button")})); } + public static int displayYesNoCancelDialog(Component parent, Object message, String title) { + return formatDialogReturnValue(displayDialog( + parent, + JOptionPane.YES_NO_CANCEL_OPTION, + JOptionPane.QUESTION_MESSAGE, + false, + "OptionPane.questionIcon", + title, + message, + new Object[]{ + Bundles.getCommon("yes.button"), + Bundles.getCommon("no.button"), + Bundles.getCommon("cancel.button") + } + )); + } + public static final int displayConfirmCancelDialog(Component parent, Object message) { return formatDialogReturnValue(displayDialog(parent, JOptionPane.YES_NO_CANCEL_OPTION, diff --git a/src/org/underworldlabs/swing/table/PropertyWrapperModel.java b/src/org/underworldlabs/swing/table/PropertyWrapperModel.java index 496e9031b..c24f40c0a 100644 --- a/src/org/underworldlabs/swing/table/PropertyWrapperModel.java +++ b/src/org/underworldlabs/swing/table/PropertyWrapperModel.java @@ -47,6 +47,10 @@ public PropertyWrapperModel(Properties values) { setValues(values.entrySet(), values.size()); } + public PropertyWrapperModel(Map properties, boolean sort) { + setValues(properties, sort); + } + public void setValues(Map values, boolean sort) { setValues(values.entrySet(), values.size()); if (sort) diff --git a/src/org/underworldlabs/util/DynamicLibraryLoader.java b/src/org/underworldlabs/util/DynamicLibraryLoader.java index 6b1724a07..ef17e1636 100644 --- a/src/org/underworldlabs/util/DynamicLibraryLoader.java +++ b/src/org/underworldlabs/util/DynamicLibraryLoader.java @@ -133,12 +133,6 @@ public static Object loadingObjectFromClassLoaderWithCS(ClassLoader classLoader, return odb; } - public static Object loadingObjectFromClassLoaderWithParams(int jaybirdVersion, Object unwrapObject, String shortClassName, Parameter... params) - throws ClassNotFoundException { - return loadingObjectFromClassLoaderWithParams(unwrapObject, "biz.redsoft." - + shortClassName, getFbPluginImplPath(jaybirdVersion), params); - } - public static String getFbPluginImplPath(int jaybirdVersion) { String jarPath = "./lib/fbplugin-impl.jar;../lib/fbplugin-impl.jar"; if (jaybirdVersion >= 5) diff --git a/src/org/underworldlabs/util/PanelsStateProperties.java b/src/org/underworldlabs/util/PanelsStateProperties.java new file mode 100644 index 000000000..66fcfbc94 --- /dev/null +++ b/src/org/underworldlabs/util/PanelsStateProperties.java @@ -0,0 +1,87 @@ +package org.underworldlabs.util; + +import org.executequery.log.Log; +import org.executequery.util.UserSettingsProperties; + +import java.io.*; +import java.util.HashMap; +import java.util.Map; + +public final class PanelsStateProperties { + private static final String DELIMITER = "="; + private static final String FILE_NAME = "re.user.panels.state"; + + private final String className; + private static String filePath; + private static final Map stateMap; + + static { + stateMap = new HashMap<>(); + readFile(); + } + + public PanelsStateProperties(String className) { + this.className = className; + } + + public void put(String key, String value) { + stateMap.put(buildKey(key), value); + } + + public String get(String key) { + return stateMap.get(buildKey(key)); + } + + public void save() { + + StringBuilder sb = new StringBuilder(); + for (String key : stateMap.keySet()) + sb.append(key).append(DELIMITER).append(stateMap.get(key)).append("\n"); + + writeFile(sb); + } + + public boolean isLoaded() { + return !stateMap.isEmpty(); + } + + private static void readFile() { + try (BufferedReader reader = new BufferedReader(new FileReader(getFilePath()))) { + + String line; + while ((line = reader.readLine()) != null) { + int delimiterIndex = line.indexOf(DELIMITER); + + String key = line.substring(0, delimiterIndex); + String value = line.substring(delimiterIndex + DELIMITER.length()); + stateMap.put(key, value); + } + + } catch (FileNotFoundException e) { + Log.warning(String.format("File %s not found", FILE_NAME)); + + } catch (IOException e) { + Log.error(String.format("Error reading %s file", FILE_NAME), e); + } + } + + private void writeFile(StringBuilder sb) { + try (PrintWriter writer = new PrintWriter(new FileWriter(getFilePath(), false))) { + writer.print(sb); + + } catch (IOException e) { + Log.error(String.format("Error writing %s file", FILE_NAME), e); + } + } + + private static String getFilePath() { + if (filePath == null) + filePath = new UserSettingsProperties().getUserSettingsDirectory() + FILE_NAME; + return filePath; + } + + private String buildKey(String key) { + return className + "." + key; + } + +} diff --git a/src/org/underworldlabs/util/SQLUtils.java b/src/org/underworldlabs/util/SQLUtils.java index c35206922..e25aea02e 100644 --- a/src/org/underworldlabs/util/SQLUtils.java +++ b/src/org/underworldlabs/util/SQLUtils.java @@ -24,6 +24,8 @@ import static org.executequery.gui.table.CreateTableSQLSyntax.*; public final class SQLUtils { + public static final String THERE_ARE_NO_CHANGES = "/* there are no changes */\n"; + public static final String ALTER_CONSTRAINTS = "/* ALTER CONSTRAINTS */\n"; public static String generateCreateTable( String name, List columnDataList, List columnConstraintList, @@ -360,6 +362,83 @@ public static String generateCreateProcedure( return sb.toString(); } + public static String generateDownCreateProcedureScript(String name, String comment, Vector inputParameters, + Vector outputParameters, boolean setComment, DatabaseConnection dc) { + StringBuilder sb = new StringBuilder(); + sb.append("\n^\n"); + + if (setComment) { + sb.append(generateComment(name, NamedObject.META_TYPES[PROCEDURE], comment, "^", false, dc)); + sb.append(generateCommentForColumns(name, inputParameters, "PARAMETER", "^")); + sb.append(generateCommentForColumns(name, outputParameters, "PARAMETER", "^")); + } + return sb.toString(); + } + + public static String generateDownCreateFunctionScript(String name, String comment, Vector inputArguments, boolean setComment, DatabaseConnection dc) { + StringBuilder sb = new StringBuilder(); + sb.append("\n^\n"); + + if (setComment) { + sb.append(generateComment(name, NamedObject.META_TYPES[FUNCTION], comment, "^", false, dc)); + sb.append(generateCommentForColumns(name, inputArguments, "PARAMETER", "^")); + } + + + return sb.toString(); + } + + public static String generateUpperCreateProcedureScript( + String name, String entryPoint, String engine, Vector inputParameters, + Vector outputParameters, Vector variables, String sqlSecurity, String authid, DatabaseConnection dc) { + + StringBuilder sb = new StringBuilder(); + String body = null; + if (variables != null) + body = formattedParameters(variables, true); + sb.append(generateCreateProcedureOrFunctionHeader(name, inputParameters, NamedObject.META_TYPES[PROCEDURE], authid, dc)); + + String output = formattedParameters(outputParameters, false); + if (!MiscUtils.isNull(output.trim())) + sb.append("\nRETURNS (\n").append(output).append(")"); + + if (!MiscUtils.isNull(entryPoint)) { + sb.append("\nEXTERNAL NAME '").append(entryPoint).append("'"); + sb.append(" ENGINE ").append(engine); + + } else if (!MiscUtils.isNull(sqlSecurity)) + sb.append("\n" + SQL_SECURITY).append(sqlSecurity); + sb.append("\nAS\n"); + if (body != null && !body.isEmpty()) + sb.append(body); + + return sb.toString(); + } + + public static String generateUpperCreateFunctionScript( + String name, String entryPoint, String engine, Vector inputParameters, Vector variables, String sqlSecurity, ColumnData returnType, boolean deterministic, DatabaseConnection dc) { + + StringBuilder sb = new StringBuilder(); + String body = null; + if (variables != null) + body = formattedParameters(variables, true); + + sb.append(generateCreateProcedureOrFunctionHeader(name, inputParameters, NamedObject.META_TYPES[FUNCTION], null, dc)); + sb.append("\nRETURNS ").append(formattedReturnType(returnType, deterministic)); + + if (!MiscUtils.isNull(entryPoint)) { + sb.append("\nEXTERNAL NAME '").append(entryPoint).append("'"); + sb.append(" ENGINE ").append(engine); + + } else if (!MiscUtils.isNull(sqlSecurity)) + sb.append("\n" + SQL_SECURITY).append(sqlSecurity); + sb.append("\nAS\n"); + if (body != null && !body.isEmpty()) + sb.append(body); + + return sb.toString(); + } + public static String generateCommentForColumns( String relationName, List cols, String metaTag, String delimiter) { @@ -673,7 +752,10 @@ public static String formattedParameters(Vector tableVector, boolean for (int i = 0, k = tableVector.size(); i < k; i++) { ColumnData cd = tableVector.elementAt(i); - + if (cd.getTypeName() == "PROCEDURE" || cd.getTypeName() == "FUNCTION") { + sb.append(cd.getSelectOperator()); + continue; + } if (!MiscUtils.isNull(cd.getColumnName())) { if (variable) @@ -784,6 +866,7 @@ public static ColumnData columnDataFromProcedureParameter(Parameter parameter, D cd.setColumnTable(parameter.getFieldName()); cd.setDefaultValue(parameter.getDefaultValue(), true, parameter.isDefaultValueFromDomain()); cd.setRemarkAsSingleComment(parameter.isDescriptionAsSingleComment()); + cd.setColumnPosition(parameter.getPosition()); String[] dataTypes = dc.getDataTypesArray(); int[] intDataTypes = dc.getIntDataTypesArray(); for (int i = 0; i < dataTypes.length; i++) { @@ -794,26 +877,45 @@ public static ColumnData columnDataFromProcedureParameter(Parameter parameter, D } public static String generateNameForDBObject(String type, DatabaseConnection databaseConnection) { - String name = "NEW_" + type + "_"; - int int_number = 0; - String number; - List keys = ConnectionsTreePanel.getPanelFromBrowser().getDefaultDatabaseHostFromConnection(databaseConnection).getDatabaseObjectsForMetaTag(type); - if (keys != null) - for (NamedObject key : keys) { - if (!MiscUtils.isNull(key.getName())) - if (key.getName().contains(name)) { - number = key.getName().replace(name, ""); - try { - if (Integer.parseInt(number) > int_number) - int_number = Integer.parseInt(number); - } catch (NumberFormatException e) { - Log.debug(e.getMessage()); - } - } + String newObjectName = "NEW_" + type + "_"; + String stringNumber; + int newNumber = 0; + + DefaultDatabaseHost databaseHost = ConnectionsTreePanel.getPanelFromBrowser().getDefaultDatabaseHostFromConnection(databaseConnection); + List databaseObjects = databaseHost.getDatabaseObjectsForMetaTag(type); + if (Objects.equals(type, META_TYPES[TRIGGER])) { + List dbo = databaseHost.getDatabaseObjectsForMetaTag(META_TYPES[DATABASE_TRIGGER]); + if (dbo != null) + databaseObjects.addAll(dbo); + dbo = databaseHost.getDatabaseObjectsForMetaTag(META_TYPES[DDL_TRIGGER]); + if (dbo != null) + databaseObjects.addAll(dbo); + } + + if (databaseObjects == null) + return newObjectName + "1"; + + for (NamedObject object : databaseObjects) { + + if (MiscUtils.isNull(object.getName())) + continue; + + if (object.getName().contains(newObjectName)) { + stringNumber = object.getName().replace(newObjectName, ""); + + try { + if (Integer.parseInt(stringNumber) > newNumber) + newNumber = Integer.parseInt(stringNumber); + + } catch (NumberFormatException e) { + Log.debug(e.getMessage()); + } } - number = String.valueOf(int_number + 1); - return name + number; + } + + stringNumber = String.valueOf(newNumber + 1); + return newObjectName + stringNumber; } private static String generateNameForConstraint(String type, List keys) { @@ -1021,7 +1123,7 @@ public static String generateAlterDomain(ColumnData thisDomainData, ColumnData d sb.append("NULL"); } - return !sb.toString().isEmpty() ? sb.toString() : "/* there are no changes */\n"; + return !sb.toString().isEmpty() ? sb.toString() : THERE_ARE_NO_CHANGES; } public static String generateAlterDomain(ColumnData columnData, String domainName) { @@ -1064,7 +1166,8 @@ public static String generateAlterDomain(ColumnData columnData, String domainNam sb.append("NULL"); } - return !sb.toString().isEmpty() ? sb.toString() : "/* there are no changes */\n"; + return !sb.toString().isEmpty() ? sb.toString() : THERE_ARE_NO_CHANGES; + } @@ -1074,6 +1177,7 @@ public static String generateAlterTable( StringBuilder sb = new StringBuilder(); StringBuilder columnComments = new StringBuilder(); + boolean alterConstraints = false; if (temporary) sb.append("ALTER GLOBAL TEMPORARY TABLE "); @@ -1151,18 +1255,49 @@ public static String generateAlterTable( } } - if (!Arrays.equals(constraints, new boolean[]{false, false, false, false})) { + if (!Arrays.equals(constraints, new boolean[]{true, true, true, true})) { List thisConstraints = thisTable.getConstraints(); List comparingConstraints = comparingTable.getConstraints(); + //check for ALTER CONSTRAINT + for (org.executequery.databaseobjects.impl.ColumnConstraint thisConstraint : thisConstraints) { + + if ((thisConstraint.getType() == PRIMARY_KEY && constraints[0]) || + (thisConstraint.getType() == FOREIGN_KEY && constraints[1]) || + (thisConstraint.getType() == UNIQUE_KEY && constraints[2]) || + (thisConstraint.getType() == CHECK_KEY && constraints[3])) + continue; + + + for (org.executequery.databaseobjects.impl.ColumnConstraint comparingConstraint : comparingConstraints) + if (Objects.equals(thisConstraint.getName(), comparingConstraint.getName())) { + boolean[] flags = new boolean[8]; + flags[0] = thisConstraint.getType() != comparingConstraint.getType(); + flags[1] = !Objects.equals(thisConstraint.getColumnName(), comparingConstraint.getColumnName()); + flags[2] = !Objects.equals(thisConstraint.getCheck(), comparingConstraint.getCheck()); + flags[3] = !Objects.equals(thisConstraint.getReferencedTable(), comparingConstraint.getReferencedTable()); + flags[4] = !Objects.equals(thisConstraint.getColumnDisplayList(), comparingConstraint.getColumnDisplayList()); + flags[5] = !Objects.equals(thisConstraint.getReferenceColumnDisplayList(), comparingConstraint.getReferenceColumnDisplayList()); + flags[6] = !Objects.equals(thisConstraint.getUpdateRule(), comparingConstraint.getUpdateRule()); + flags[7] = !Objects.equals(thisConstraint.getDeleteRule(), comparingConstraint.getDeleteRule()); + boolean notEquals = false; + for (boolean flag : flags) { + notEquals = notEquals || flag; + } + if (notEquals) { + alterConstraints = true; + break; + } + } + } //check for DROP CONSTRAINT for (org.executequery.databaseobjects.impl.ColumnConstraint thisConstraint : thisConstraints) { - if ((thisConstraint.getType() == PRIMARY_KEY && !constraints[0]) || - (thisConstraint.getType() == FOREIGN_KEY && !constraints[1]) || - (thisConstraint.getType() == UNIQUE_KEY && !constraints[2]) || - (thisConstraint.getType() == CHECK_KEY && !constraints[3])) + if ((thisConstraint.getType() == PRIMARY_KEY && constraints[0]) || + (thisConstraint.getType() == FOREIGN_KEY && constraints[1]) || + (thisConstraint.getType() == UNIQUE_KEY && constraints[2]) || + (thisConstraint.getType() == CHECK_KEY && constraints[3])) continue; int dropCheck = 0; @@ -1178,10 +1313,10 @@ public static String generateAlterTable( //check for ADD CONSTRAINT for (org.executequery.databaseobjects.impl.ColumnConstraint comparingConstraint : comparingConstraints) { - if ((comparingConstraint.getType() == PRIMARY_KEY && !constraints[0]) || - (comparingConstraint.getType() == FOREIGN_KEY && !constraints[1]) || - (comparingConstraint.getType() == UNIQUE_KEY && !constraints[2]) || - (comparingConstraint.getType() == CHECK_KEY && !constraints[3])) + if ((comparingConstraint.getType() == PRIMARY_KEY && constraints[0]) || + (comparingConstraint.getType() == FOREIGN_KEY && constraints[1]) || + (comparingConstraint.getType() == UNIQUE_KEY && constraints[2]) || + (comparingConstraint.getType() == CHECK_KEY && constraints[3])) continue; int addCheck = 0; @@ -1220,7 +1355,10 @@ public static String generateAlterTable( } if (sb.toString().isEmpty()) - return "/* there are no changes */\n"; + if (alterConstraints) + return ALTER_CONSTRAINTS; + else + return THERE_ARE_NO_CHANGES; return sb.toString(); } @@ -1244,7 +1382,7 @@ public static String generateAlterException( } } - return sb.toString().trim().isEmpty() ? "/* there are no changes */\n" : sb.toString(); + return sb.toString().trim().isEmpty() ? THERE_ARE_NO_CHANGES : sb.toString(); } public static String generateAlterSequence( @@ -1262,7 +1400,7 @@ public static String generateAlterSequence( } if (noChangesCheckString.contentEquals(sb)) - return "/* there are no changes */\n"; + return THERE_ARE_NO_CHANGES; return sb.append(";\n").toString(); } @@ -1296,7 +1434,7 @@ public static String generateAlterUDF( } } - return sb.toString().isEmpty() ? "/* there are no changes */\n" : sb.toString(); + return sb.toString().isEmpty() ? THERE_ARE_NO_CHANGES : sb.toString(); } public static String generateAlterIndex( @@ -1343,7 +1481,7 @@ public static String generateAlterIndex( } } - return sb.toString().isEmpty() ? "/* there are no changes */\n" : sb.toString(); + return sb.toString().isEmpty() ? THERE_ARE_NO_CHANGES : sb.toString(); } public static String generateAlterUser(DefaultDatabaseUser thisUser, DefaultDatabaseUser compareUser, boolean setComment) { @@ -1399,30 +1537,66 @@ public static String generateAlterUser(DefaultDatabaseUser thisUser, DefaultData sb.append(generateComment(thisUser.getName(), "USER", compareUser.getRemarks(), thisUser.getPlugin(), ";", false, thisUser.getHost().getDatabaseConnection())); } - return !sb.toString().isEmpty() ? sb.toString() : "/* there are no changes */\n"; + return !sb.toString().isEmpty() ? sb.toString() : THERE_ARE_NO_CHANGES; } - public static String generateAlterTablespace( - DefaultDatabaseTablespace thisTablespace, DefaultDatabaseTablespace comparingTablespace) { + public static String generateAlterTablespace(DefaultDatabaseTablespace thisTablespace, + DefaultDatabaseTablespace comparingTablespace, + boolean commentsNeed) { + + StringBuilder sb = new StringBuilder(); String comparingFileName = comparingTablespace.getFileName(); + if (!Objects.equals(thisTablespace.getFileName(), comparingFileName)) { + sb.append(generateAlterTablespace( + thisTablespace.getName(), + comparingFileName, + null, + false, + thisTablespace.getHost().getDatabaseConnection() + )); + } + + String comparingComment = comparingTablespace.getRemarks(); + if (commentsNeed && !Objects.equals(thisTablespace.getRemarks(), comparingComment)) { + sb.append(generateComment( + thisTablespace.getName(), + "TABLESPACE", + comparingComment, + ";", + false, + thisTablespace.getHost().getDatabaseConnection() + )); + } - return !Objects.equals(thisTablespace.getFileName(), comparingFileName) ? - "/* there are no changes */\n" : - generateAlterTablespace(thisTablespace.getName(), comparingFileName, thisTablespace.getHost().getDatabaseConnection()); + return sb.toString().isEmpty() ? THERE_ARE_NO_CHANGES : sb.toString(); } - public static String generateAlterTablespace(String name, String file, DatabaseConnection dc) { - String sb = "ALTER TABLESPACE " + format(name, dc) + - " SET FILE '" + file + "';\n"; - return sb; + public static String generateAlterTablespace(String name, String file, String comment, boolean commentNeed, DatabaseConnection dc) { + StringBuilder sb = new StringBuilder(); + String formattedName = format(name, dc); + + sb.append("ALTER TABLESPACE ").append(formattedName); + sb.append(" SET FILE '").append(file).append("';\n"); + + if (commentNeed && !MiscUtils.isNull(comment)) + sb.append(generateComment(formattedName, "TABLESPACE", comment, ";")); + + return sb.toString(); } - public static String generateCreateTablespace(String name, String file, DatabaseConnection dc) { - String sb = "CREATE TABLESPACE " + format(name, dc) + - " FILE '" + file + "';\n"; - return sb; + public static String generateCreateTablespace(String name, String file, String comment, boolean commentNeed, DatabaseConnection dc) { + StringBuilder sb = new StringBuilder(); + String formattedName = format(name, dc); + + sb.append("CREATE TABLESPACE ").append(formattedName); + sb.append(" FILE '").append(file).append("';\n"); + + if (commentNeed && !MiscUtils.isNull(comment)) + sb.append(generateComment(formattedName, "TABLESPACE", comment, ";")); + + return sb.toString(); } public static String generateCreateSequence( @@ -1557,8 +1731,9 @@ public static String generateCreatePackage( StringBuilder sb = new StringBuilder(); sb.append("SET TERM ^ ;"); - sb.append("\n").append(headerSource); - sb.append("^\n").append(bodySource); + sb.append("\n").append("CREATE OR ALTER PACKAGE ").append(name).append("\nAS\n").append(headerSource); + if (!MiscUtils.isNull(bodySource)) + sb.append("^\n").append("RECREATE PACKAGE BODY ").append(name).append("\nAS\n").append(bodySource); sb.append("^\n").append("SET TERM ; ^").append("\n"); if (description != null && !description.isEmpty()) @@ -1806,7 +1981,11 @@ public static String generateCreateProcedureStub(DefaultDatabaseProcedure obj) { if (!MiscUtils.isNull(formattedOutputParams.trim())) sb.append(String.format("\nRETURNS (\n%s)", formattedOutputParams)); - return sb.append("\nAS BEGIN END^\n").toString(); + sb.append("\nAS BEGIN "); + if (!outputParams.isEmpty()) + sb.append("\n\tSUSPEND;\n"); + + return sb.append("END^").toString(); } public static String generateCreateTriggerStub(DefaultDatabaseTrigger obj) { @@ -1973,7 +2152,7 @@ public static String generateAlterJob(DefaultDatabaseJob thisJob, DefaultDatabas sb.append("^").append(generateComment(thisJob.getName(), "JOB", compareJob.getRemarks(), "", false, thisJob.getHost().getDatabaseConnection())); if (noChangesCheckString.contentEquals(sb)) - return "/* there are no changes */\n"; + return THERE_ARE_NO_CHANGES; return sb.append("^\nSET TERM ;^\n").toString(); }