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 |